From d150b82511b946ae326616216b8f13e73cfae20b Mon Sep 17 00:00:00 2001 From: Mel Padden Date: Tue, 24 Sep 2024 14:42:10 +0200 Subject: [PATCH] Updates --- 1.5.X/concepts/accounts-and-keys/index.html | 112 ++ 1.5.X/concepts/callstack/index.html | 33 + .../concepts/design/casper-design/index.html | 237 +++ 1.5.X/concepts/design/highway/index.html | 58 + .../design/networking-protocol/index.html | 209 ++ 1.5.X/concepts/design/p2p/index.html | 53 + .../index.html | 36 + 1.5.X/concepts/dictionaries/index.html | 84 + 1.5.X/concepts/economics/concepts/index.html | 31 + 1.5.X/concepts/economics/consensus/index.html | 78 + .../concepts/economics/delegation/index.html | 42 + .../economics/gas-concepts/index.html | 54 + 1.5.X/concepts/global-state/index.html | 42 + 1.5.X/concepts/glossary/A/index.html | 35 + 1.5.X/concepts/glossary/B/index.html | 63 + 1.5.X/concepts/glossary/C/index.html | 46 + 1.5.X/concepts/glossary/D/index.html | 36 + 1.5.X/concepts/glossary/E/index.html | 34 + 1.5.X/concepts/glossary/F/index.html | 27 + 1.5.X/concepts/glossary/G/index.html | 39 + 1.5.X/concepts/glossary/H/index.html | 27 + 1.5.X/concepts/glossary/I/index.html | 23 + 1.5.X/concepts/glossary/J/index.html | 25 + 1.5.X/concepts/glossary/K/index.html | 25 + 1.5.X/concepts/glossary/L/index.html | 26 + 1.5.X/concepts/glossary/M/index.html | 31 + 1.5.X/concepts/glossary/N/index.html | 41 + 1.5.X/concepts/glossary/O/index.html | 28 + 1.5.X/concepts/glossary/P/index.html | 50 + 1.5.X/concepts/glossary/Q/index.html | 23 + 1.5.X/concepts/glossary/R/index.html | 31 + 1.5.X/concepts/glossary/S/index.html | 51 + 1.5.X/concepts/glossary/T/index.html | 30 + 1.5.X/concepts/glossary/U/index.html | 29 + 1.5.X/concepts/glossary/V/index.html | 32 + 1.5.X/concepts/glossary/W/index.html | 27 + 1.5.X/concepts/glossary/X/index.html | 23 + 1.5.X/concepts/glossary/Y/index.html | 23 + 1.5.X/concepts/glossary/Z/index.html | 23 + 1.5.X/concepts/hash-types/index.html | 133 ++ 1.5.X/concepts/index.html | 95 + 1.5.X/concepts/intro-to-dapps/index.html | 42 + 1.5.X/concepts/list-auth-keys/index.html | 40 + .../serialization-standard/index.html | 32 +- 1.5.X/concepts/smart-contracts/index.html | 35 + 1.5.X/counter-testnet/index.html | 42 + 1.5.X/counter/index.html | 33 + 1.5.X/deploy-and-deploy-lifecycle/index.html | 75 + 1.5.X/design/index.html | 20 + .../cli/calling-contracts/index.html | 41 +- .../developers/cli/delegate/index.html | 26 +- .../cli/execution-error-codes/index.html | 28 + 1.5.X/developers/cli/index.html | 63 + .../cli/installing-contracts/index.html | 118 ++ 1.5.X/developers/cli/opcode-costs/index.html | 648 ++++++ .../cli/querying-global-state/index.html | 90 + .../developers/cli/redelegate/index.html | 28 +- .../cli/sending-deploys/index.html | 38 +- .../direct-token-transfer/index.html | 100 + 1.5.X/developers/cli/transfers/index.html | 27 + .../multisig-deploy-transfer/index.html | 155 ++ .../cli/transfers/verify-transfer/index.html | 131 ++ .../developers/cli/undelegate/index.html | 24 +- 1.5.X/developers/dapps/dapp/index.html | 33 + 1.5.X/developers/dapps/index.html | 67 + .../monitor-and-consume-events/index.html | 187 ++ 1.5.X/developers/dapps/nctl-test/index.html | 107 + .../developers/dapps/prerequisites/index.html | 51 + .../dapps/sdk/client-library-usage/index.html | 172 ++ .../dapps/sdk/csharp-sdk/index.html | 39 + 1.5.X/developers/dapps/sdk/go-sdk/index.html | 33 + .../dapps/sdk/python-sdk/index.html | 85 + .../dapps/sdk/script-sdk/index.html | 12 +- 1.5.X/developers/dapps/setup-nctl/index.html | 114 ++ .../dapps/signing-a-deploy/index.html | 35 + .../dapps/speculative-exec/index.html | 28 + .../dapps/technology-stack/index.html | 60 + .../dapps/template-frontend/index.html | 95 + .../developers/dapps/uref-security/index.html | 100 + 1.5.X/developers/essential-crates/index.html | 77 + 1.5.X/developers/index.html | 57 + 1.5.X/developers/json-rpc/errors/index.html | 126 ++ 1.5.X/developers/json-rpc/guidance/index.html | 29 + 1.5.X/developers/json-rpc/index.html | 65 + .../json-rpc-informational/index.html | 687 +++++++ .../json-rpc/json-rpc-pos/index.html | 182 ++ .../json-rpc-transactional/index.html | 133 ++ .../json-rpc/minimal-compliance/index.html | 49 + .../json-rpc/types_chain/index.html | 1142 +++++++++++ 1.5.X/developers/json-rpc/types_cl/index.html | 58 + 1.5.X/developers/prerequisites/index.html | 151 ++ .../assembly-script/index.html | 14 +- .../best-practices/index.html | 81 + .../calling-contracts/index.html | 44 + .../contract-hash-vs-package-hash/index.html | 141 ++ .../contract-vs-session/index.html | 62 + .../getting-started/index.html | 77 + .../simple-contract/index.html | 214 ++ .../testing-contracts/index.html | 93 + .../testing-session-code/index.html | 93 + .../upgrading-contracts/index.html | 42 + .../writing-session-code/index.html | 92 + {next => 1.5.X}/disclaimer/index.html | 12 +- 1.5.X/economics/index.html | 46 + 1.5.X/glossary/index.html | 24 + 1.5.X/index.html | 29 + .../becoming-a-validator/bonding/index.html | 91 + .../inactive-vs-faulty/index.html | 35 + .../operators/becoming-a-validator/index.html | 47 + .../recovering/index.html | 102 + .../becoming-a-validator/unbonding/index.html | 14 +- 1.5.X/operators/index.html | 51 + .../archiving-and-restoring/index.html | 12 +- 1.5.X/operators/maintenance/index.html | 39 + .../maintenance/moving-node/index.html | 12 +- .../setup-network/chain-spec/index.html | 709 +++++++ .../setup-network/create-private/index.html | 240 +++ .../setup-network/genesis/index.html | 32 + 1.5.X/operators/setup-network/index.html | 47 + .../staging-files-for-new-network/index.html | 14 +- .../setup/basic-node-configuration/index.html | 160 ++ 1.5.X/operators/setup/fast-sync/index.html | 26 + 1.5.X/operators/setup/hardware/index.html | 40 + 1.5.X/operators/setup/index.html | 63 + .../operators/setup/install-node/index.html | 20 +- .../operators/setup/joining/index.html | 28 +- .../operators/setup/node-endpoints/index.html | 46 +- .../operators/setup/non-root-user/index.html | 57 + .../operators/setup/open-files/index.html | 12 +- 1.5.X/operators/setup/upgrade/index.html | 40 + .../list-auth-keys-tutorial/index.html | 28 +- 1.5.X/resources/advanced/multi-sig/index.html | 22 + .../multi-sig/multi-sig-workflow/index.html | 330 ++++ .../multi-sig/other-scenarios/index.html | 12 +- .../counter-testnet/commands/index.html | 14 +- .../counter-testnet/overview/index.html | 23 + .../counter-testnet/walkthrough/index.html | 126 ++ .../beginner/counter/commands/index.html | 14 +- .../beginner/counter/overview/index.html | 23 + .../beginner/counter/walkthrough/index.html | 141 ++ .../casper-open-source-software/index.html | 531 +++++ .../build-on-casper/introduction/index.html | 78 + .../condor-for-exchanges/index.html | 8 +- 1.5.X/resources/index.html | 89 + .../resources/moving-to-casper/index.html | 29 +- 1.5.X/resources/quick-start/index.html | 122 ++ .../tokens/cep18/full-tutorial/index.html | 193 ++ 1.5.X/resources/tokens/cep18/query/index.html | 59 + .../tokens/cep18/quickstart-guide/index.html | 63 + 1.5.X/resources/tokens/cep18/tests/index.html | 80 + .../tokens/cep18/transfer/index.html | 18 +- .../tokens/cep78/introduction/index.html | 782 ++++++++ .../tokens/cep78/js-tutorial/index.html | 143 ++ .../tokens/cep78/modalities/index.html | 522 +++++ .../tokens/cep78/reverse-lookup/index.html | 52 + .../full-installation-tutorial/index.html | 36 +- .../interacting-with-NFTs/index.html | 18 +- .../querying-NFTs/index.html | 14 +- .../quickstart-guide/index.html | 47 + .../testing-NFTs/index.html | 33 + 1.5.X/resources/tokens/index.html | 82 + .../advanced/cross-contract/index.html | 160 ++ 1.5.X/resources/tutorials/advanced/index.html | 58 + .../tutorials/advanced/list-cspr/index.html | 40 +- .../return-values-tutorial/index.html | 16 +- .../advanced/storage-workflow/index.html | 47 + .../transfer-token-to-contract/index.html | 14 +- .../advanced/two-party-multi-sig/index.html | 26 +- .../tutorials/beginner/aws-node/index.html | 12 +- .../tutorials/beginner/cep18/index.html | 149 ++ .../getting-started-tutorial/index.html | 24 + 1.5.X/resources/tutorials/beginner/index.html | 78 + .../beginner/querying-network/index.html | 18 +- .../beginner/upgrade-contract/index.html | 142 ++ 1.5.X/runtime/index.html | 39 + 1.5.X/sdk/index.html | 74 + 1.5.X/staking/index.html | 52 + 1.5.X/users/block-explorer/index.html | 40 + 1.5.X/users/csprlive/index.html | 46 + 1.5.X/users/delegate-ui/index.html | 83 + 1.5.X/users/funding-from-exchanges/index.html | 58 + 1.5.X/users/index.html | 88 + 1.5.X/users/ledger/index.html | 46 + .../users/ledger/ledger-cspr-live/index.html | 142 ++ 1.5.X/users/ledger/ledger-live/index.html | 247 +++ 1.5.X/users/staking-ledger/index.html | 128 ++ 1.5.X/users/testnet-faucet/index.html | 40 + 1.5.X/users/token-transfer/index.html | 57 + 1.5.X/users/undelegate-ui/index.html | 61 + 1.5.X/workflow/ledger-setup/index.html | 85 + 1.5.X/writing-contracts/index.html | 150 ++ 2.0.0/concepts/about/index.html | 29 + .../concepts/accounts-and-keys/index.html | 18 +- 2.0.0/concepts/addressable-entity/index.html | 40 + 2.0.0/concepts/callstack/index.html | 33 + .../concepts/design/casper-design/index.html | 38 +- 2.0.0/concepts/design/consensus/index.html | 68 + 2.0.0/concepts/design/highway/index.html | 45 + .../design/networking-protocol/index.html | 16 +- 2.0.0/concepts/design/p2p/index.html | 53 + .../index.html | 36 + .../concepts/design/rewards/index.html | 14 +- .../concepts/design/zug/index.html | 12 +- .../concepts/dictionaries/index.html | 18 +- 2.0.0/concepts/economics/consensus/index.html | 79 + .../economics/dynamic-gas-pricing/index.html | 37 + .../economics/fee-elimination/index.html | 40 + .../economics/gas-concepts/index.html | 40 + 2.0.0/concepts/economics/staking/index.html | 33 + 2.0.0/concepts/global-state/index.html | 42 + 2.0.0/concepts/glossary/A/index.html | 37 + 2.0.0/concepts/glossary/B/index.html | 63 + 2.0.0/concepts/glossary/C/index.html | 45 + 2.0.0/concepts/glossary/D/index.html | 39 + 2.0.0/concepts/glossary/E/index.html | 36 + 2.0.0/concepts/glossary/F/index.html | 27 + 2.0.0/concepts/glossary/G/index.html | 43 + 2.0.0/concepts/glossary/H/index.html | 27 + 2.0.0/concepts/glossary/I/index.html | 23 + 2.0.0/concepts/glossary/J/index.html | 25 + 2.0.0/concepts/glossary/K/index.html | 25 + 2.0.0/concepts/glossary/L/index.html | 26 + 2.0.0/concepts/glossary/M/index.html | 31 + 2.0.0/concepts/glossary/N/index.html | 41 + 2.0.0/concepts/glossary/O/index.html | 28 + 2.0.0/concepts/glossary/P/index.html | 48 + 2.0.0/concepts/glossary/Q/index.html | 23 + 2.0.0/concepts/glossary/R/index.html | 31 + 2.0.0/concepts/glossary/S/index.html | 51 + 2.0.0/concepts/glossary/T/index.html | 30 + 2.0.0/concepts/glossary/U/index.html | 29 + 2.0.0/concepts/glossary/V/index.html | 32 + 2.0.0/concepts/glossary/W/index.html | 27 + 2.0.0/concepts/glossary/X/index.html | 23 + 2.0.0/concepts/glossary/Y/index.html | 23 + 2.0.0/concepts/glossary/Z/index.html | 25 + 2.0.0/concepts/index.html | 99 + 2.0.0/concepts/intro-to-dapps/index.html | 42 + 2.0.0/concepts/key-types/index.html | 485 +++++ 2.0.0/concepts/list-auth-keys/index.html | 39 + 2.0.0/concepts/serialization/index.html | 44 + .../serialization/primitives/index.html | 256 +++ .../serialization/structures/index.html | 138 +- 2.0.0/concepts/serialization/types/index.html | 1251 ++++++++++++ 2.0.0/concepts/smart-contracts/index.html | 38 + 2.0.0/counter-testnet/index.html | 42 + 2.0.0/counter/index.html | 33 + 2.0.0/design/index.html | 20 + .../cli/calling-contracts/index.html | 176 ++ 2.0.0/developers/cli/delegate/index.html | 123 ++ .../cli/execution-error-codes/index.html | 28 + 2.0.0/developers/cli/index.html | 67 + .../cli/installing-contracts/index.html | 32 +- .../developers/cli/opcode-costs/index.html | 14 +- .../cli/querying-global-state/index.html | 16 +- 2.0.0/developers/cli/redelegate/index.html | 86 + .../cli/sending-transactions/index.html | 128 ++ .../direct-token-transfer/index.html | 20 +- 2.0.0/developers/cli/transfers/index.html | 27 + .../multisig-deploy-transfer/index.html | 26 +- .../cli/transfers/verify-transfer/index.html | 14 +- 2.0.0/developers/cli/undelegate/index.html | 95 + .../cli/verifying-contracts/index.html | 46 + 2.0.0/developers/dapps/dapp/index.html | 33 + 2.0.0/developers/dapps/index.html | 67 + .../monitor-and-consume-events/index.html | 18 +- .../developers/dapps/nctl-test/index.html | 26 +- .../developers/dapps/prerequisites/index.html | 51 + .../dapps/sdk/client-library-usage/index.html | 14 +- .../dapps/sdk/csharp-sdk/index.html | 39 + .../developers/dapps/sdk/go-sdk/index.html | 12 +- .../dapps/sdk/python-sdk/index.html | 12 +- .../dapps/sdk/script-sdk/index.html | 57 + .../developers/dapps/setup-nctl/index.html | 14 +- .../dapps/signing-a-transaction/index.html | 35 + .../dapps/speculative-exec/index.html | 28 + .../dapps/technology-stack/index.html | 60 + .../dapps/template-frontend/index.html | 14 +- .../developers/dapps/uref-security/index.html | 14 +- 2.0.0/developers/essential-crates/index.html | 77 + 2.0.0/developers/index.html | 57 + 2.0.0/developers/json-rpc/errors/index.html | 126 ++ 2.0.0/developers/json-rpc/guidance/index.html | 29 + 2.0.0/developers/json-rpc/index.html | 65 + .../json-rpc-informational/index.html | 86 +- .../json-rpc/json-rpc-pos/index.html | 24 +- .../json-rpc-transactional/index.html | 36 +- .../json-rpc/minimal-compliance/index.html | 49 + .../json-rpc/types_chain/index.html | 28 +- 2.0.0/developers/json-rpc/types_cl/index.html | 56 + .../developers/prerequisites/index.html | 22 +- .../assembly-script/index.html | 54 + .../best-practices/index.html | 24 +- .../calling-contracts/index.html | 44 + .../contract-hash-vs-package-hash/index.html | 22 +- .../contract-vs-session/index.html | 62 + .../emitting-contract-events/index.html | 151 ++ .../factory-pattern/index.html | 67 + .../getting-started/index.html | 16 +- .../simple-contract/index.html | 32 +- .../testing-contracts/index.html | 26 +- .../testing-session-code/index.html | 16 +- .../upgrading-contracts/index.html | 41 + .../writing-session-code/index.html | 28 +- 2.0.0/disclaimer/index.html | 77 + 2.0.0/economics/index.html | 51 + 2.0.0/glossary/index.html | 24 + 2.0.0/index.html | 27 + .../becoming-a-validator/bonding/index.html | 18 +- .../change-bid-public-key/index.html | 80 + .../inactive-vs-faulty/index.html | 34 + .../operators/becoming-a-validator/index.html | 51 + .../recovering/index.html | 24 +- .../becoming-a-validator/unbonding/index.html | 75 + 2.0.0/operators/index.html | 51 + .../archiving-and-restoring/index.html | 102 + 2.0.0/operators/maintenance/index.html | 39 + .../maintenance/moving-node/index.html | 76 + .../setup-network/chain-spec/index.html | 16 +- .../setup-network/create-private/index.html | 42 +- .../setup-network/genesis/index.html | 32 + 2.0.0/operators/setup-network/index.html | 47 + .../staging-files-for-new-network/index.html | 105 + .../setup/basic-node-configuration/index.html | 20 +- .../operators/setup/casper-sidecar/index.html | 75 + 2.0.0/operators/setup/fast-sync/index.html | 26 + 2.0.0/operators/setup/hardware/index.html | 40 + 2.0.0/operators/setup/index.html | 71 + 2.0.0/operators/setup/install-node/index.html | 109 + 2.0.0/operators/setup/joining/index.html | 78 + .../operators/setup/node-endpoints/index.html | 109 + 2.0.0/operators/setup/node-events/index.html | 35 + .../operators/setup/non-root-user/index.html | 57 + 2.0.0/operators/setup/open-files/index.html | 57 + 2.0.0/operators/setup/upgrade/index.html | 40 + .../list-auth-keys-tutorial/index.html | 238 +++ 2.0.0/resources/advanced/multi-sig/index.html | 22 + .../multi-sig/multi-sig-workflow/index.html | 20 +- .../multi-sig/other-scenarios/index.html | 41 + .../counter-testnet/commands/index.html | 51 + .../counter-testnet/overview/index.html | 23 + .../counter-testnet/walkthrough/index.html | 12 +- .../beginner/counter/commands/index.html | 51 + .../beginner/counter/overview/index.html | 23 + .../beginner/counter/walkthrough/index.html | 14 +- .../casper-open-source-software/index.html | 12 +- .../build-on-casper/introduction/index.html | 77 + 2.0.0/resources/changelog/index.html | 35 + 2.0.0/resources/index.html | 89 + 2.0.0/resources/moving-to-casper/index.html | 182 ++ .../resources/quick-start/index.html | 20 +- .../tokens/cep18/full-tutorial/index.html | 30 +- .../resources/tokens/cep18/query/index.html | 14 +- .../tokens/cep18/quickstart-guide/index.html | 63 + .../resources/tokens/cep18/tests/index.html | 16 +- .../tokens/cep18/transfer/index.html | 135 ++ .../tokens/cep78/introduction/index.html | 40 +- .../tokens/cep78/js-tutorial/index.html | 22 +- .../tokens/cep78/modalities/index.html | 18 +- .../tokens/cep78/reverse-lookup/index.html | 52 + 2.0.0/resources/tokens/index.html | 82 + .../tokens/using-casper-client/index.html | 165 ++ .../advanced/cross-contract/index.html | 28 +- 2.0.0/resources/tutorials/advanced/index.html | 58 + .../tutorials/advanced/list-cspr/index.html | 152 ++ .../return-values-tutorial/index.html | 35 + .../advanced/storage-workflow/index.html | 18 +- .../transfer-token-to-contract/index.html | 39 + .../advanced/two-party-multi-sig/index.html | 78 + .../tutorials/beginner/aws-node/index.html | 72 + .../tutorials/beginner/cep18/index.html | 20 +- .../getting-started-tutorial/index.html | 24 + 2.0.0/resources/tutorials/beginner/index.html | 78 + .../beginner/querying-network/index.html | 120 ++ .../beginner/upgrade-contract/index.html | 22 +- 2.0.0/runtime/index.html | 63 + 2.0.0/sdk/index.html | 74 + .../index.html | 72 + 2.0.0/transactions/index.html | 90 + 2.0.0/users/block-explorer/index.html | 40 + 2.0.0/users/csprlive/index.html | 46 + 2.0.0/users/delegate-ui/index.html | 83 + 2.0.0/users/delegating/index.html | 59 + 2.0.0/users/funding-from-exchanges/index.html | 58 + 2.0.0/users/index.html | 91 + 2.0.0/users/ledger/index.html | 46 + .../users/ledger/ledger-cspr-live/index.html | 12 +- .../users/ledger/ledger-live/index.html | 14 +- .../users/staking-ledger/index.html | 16 +- 2.0.0/users/testnet-faucet/index.html | 34 + 2.0.0/users/token-transfer/index.html | 56 + 2.0.0/users/undelegate-ui/index.html | 61 + 2.0.0/workflow/ledger-setup/index.html | 70 + 2.0.0/writing-contracts/index.html | 158 ++ 404.html | 10 +- CNAME | 1 - assets/js/00935d0c.4467c113.js | 1 + assets/js/017e616b.8ebc0779.js | 1 + assets/js/01be152e.b1fca991.js | 1 + assets/js/01db17fe.4fe78b51.js | 1 + assets/js/02627fb8.7d16ba66.js | 1 + assets/js/028247bf.b7389543.js | 1 + assets/js/028247bf.e22beb61.js | 1 - assets/js/03aa8e23.0a426846.js | 1 - assets/js/03aa8e23.2c61f65f.js | 1 + assets/js/03acd2fb.9a8b2e6c.js | 1 + assets/js/03acd2fb.d5a0a15f.js | 1 - assets/js/03c6d9c7.4f0c8d42.js | 1 + assets/js/03c6d9c7.c792cbe5.js | 1 - assets/js/044f7961.5f1b0a68.js | 1 - assets/js/044f7961.a5cca8cf.js | 1 + assets/js/04a0dcd6.f1fd239f.js | 1 + assets/js/04f8200d.35a20847.js | 1 - assets/js/04f8200d.5228b822.js | 1 + assets/js/051b98e7.8a9171cd.js | 1 + assets/js/053d5d89.4f1b46a0.js | 1 - assets/js/053d5d89.4f2907f5.js | 1 + assets/js/056155c0.abd058a6.js | 1 + assets/js/05a3aa78.7bddfc8e.js | 1 + assets/js/05a3aa78.baa762b5.js | 1 - assets/js/06c1e821.b8aa7d80.js | 1 + assets/js/06c1e821.b9348323.js | 1 - assets/js/074e7bdc.1512fa35.js | 1 + assets/js/074e7bdc.4eb0678a.js | 1 - assets/js/0753c93f.38bf38b5.js | 1 - assets/js/0753c93f.c3fc9760.js | 1 + assets/js/0791978c.6cb20991.js | 1 - assets/js/0791978c.8b8ea331.js | 1 + assets/js/08996e66.378c3d02.js | 1 - assets/js/08996e66.45d2a303.js | 1 + assets/js/08af526d.864924c4.js | 1 + assets/js/08af526d.cefb371d.js | 1 - assets/js/0904ce24.59e4ae24.js | 1 - assets/js/0904ce24.a293aebe.js | 1 + assets/js/09278318.4b956a66.js | 1 + assets/js/094b4aff.6cc550cf.js | 1 + assets/js/0ac4e675.ee46eb79.js | 1 - assets/js/0ac4e675.f7475e94.js | 1 + assets/js/0ae07240.2f1af85d.js | 1 + assets/js/0b20c33e.4baa51ac.js | 1 + assets/js/0b3fc8e9.ce7a5cab.js | 1 + assets/js/0b8cc739.11d60f3d.js | 1 + assets/js/0b8cc739.79de13f9.js | 1 - assets/js/0bb2dbe9.0880aaaf.js | 1 - assets/js/0bb2dbe9.25561148.js | 1 + assets/js/0bd3b317.a7a76776.js | 1 + assets/js/0bd3b317.d740e1e1.js | 1 - assets/js/0c098c15.5f193e57.js | 1 - assets/js/0c098c15.9fdd6a6d.js | 1 + assets/js/0cde4ba3.766b9399.js | 1 + assets/js/0cde4ba3.db3b01f2.js | 1 - assets/js/0dea8207.469d8eba.js | 1 + assets/js/0dea8207.4f27fd0b.js | 1 - assets/js/0fa7e001.d0182770.js | 1 + assets/js/106a38e1.01a8cfcd.js | 1 - assets/js/106a38e1.08a834c1.js | 1 + assets/js/106b67a5.5be98423.js | 1 + assets/js/106b67a5.9d743cdc.js | 1 - assets/js/10ab4195.ee7630a9.js | 1 + assets/js/10dd5949.d7da3af3.js | 1 + assets/js/116fa82a.4ab1633b.js | 1 + assets/js/116fa82a.7fdfa28d.js | 1 - assets/js/124873a8.3f86c852.js | 1 - assets/js/124873a8.ea47be98.js | 1 + assets/js/12984b65.704e4746.js | 1 + assets/js/12e95288.283682c6.js | 1 + assets/js/12e95288.dcfe96df.js | 1 - assets/js/130631d9.473508f7.js | 1 - assets/js/130631d9.5fa36173.js | 1 + assets/js/134a9ec2.0ccdf24e.js | 1 + assets/js/134a9ec2.a9986cfa.js | 1 - assets/js/13f7cbc7.8e07b7af.js | 1 + assets/js/14620e15.210101ba.js | 1 - assets/js/14620e15.e55ff3e7.js | 1 + assets/js/1494.44935779.js | 1 - assets/js/157e4bc2.7b9ed566.js | 1 + assets/js/157e4bc2.eba0692b.js | 1 - assets/js/158765df.0818e83f.js | 1 + assets/js/15ce11b3.3da7da11.js | 1 + assets/js/15ce11b3.dca58b4c.js | 1 - assets/js/168da062.e84c3ca9.js | 1 + assets/js/168da062.f79ac659.js | 1 - assets/js/175e85c1.ae48dd54.js | 1 + assets/js/17896441.a80fb57c.js | 1 + assets/js/17896441.e301f0ef.js | 1 - assets/js/1871ac35.4fb85a4c.js | 1 + assets/js/1871ac35.c8a05ff4.js | 1 - assets/js/18b84202.39914aaa.js | 1 + assets/js/1966dde1.2677b260.js | 1 + assets/js/197196c4.10c851c2.js | 1 + assets/js/197196c4.af135d1b.js | 1 - assets/js/19770ceb.8387e9e3.js | 1 - assets/js/19770ceb.85de565a.js | 1 + ...76c6c.fdefcb5a.js => 19b85f8d.9543118f.js} | 2 +- assets/js/1a4e3797.87166043.js | 2 + ...E.txt => 1a4e3797.87166043.js.LICENSE.txt} | 0 assets/js/1a4e3797.db7f4d3c.js | 2 - assets/js/1b0eecbc.03a68f28.js | 1 + assets/js/1b0eecbc.35fe077e.js | 1 - assets/js/1b2f0a70.1f2d7217.js | 1 + assets/js/1b2f0a70.d99e2656.js | 1 - assets/js/1b312e15.3da2e07f.js | 1 + assets/js/1c694ffb.e2c21c8e.js | 1 + assets/js/1c694ffb.eb41d9b2.js | 1 - assets/js/1cd8ca26.cbdbeb37.js | 1 + assets/js/1e144f6d.3fce115e.js | 1 + assets/js/1e144f6d.846df292.js | 1 - assets/js/1e2c8091.780b66ed.js | 1 + assets/js/202767e6.650f5669.js | 1 + assets/js/202767e6.662bbd94.js | 1 - assets/js/2063472f.3db4a69b.js | 1 + assets/js/2063472f.f81204a0.js | 1 - assets/js/20e65df1.58813634.js | 1 + assets/js/20f436ec.0bdc9c76.js | 1 - assets/js/20f436ec.d9cf2a40.js | 1 + assets/js/212aab5d.1a701a70.js | 1 - assets/js/212aab5d.5eef133e.js | 1 + assets/js/21ae0e7e.0ab591f6.js | 1 - assets/js/21ae0e7e.b7e7da29.js | 1 + assets/js/21d2c26c.34fe9668.js | 1 + assets/js/2237.2be052d4.js | 1 - assets/js/22dd74f7.d59e4fd6.js | 1 - assets/js/22dd74f7.e428a829.js | 1 + assets/js/236eb0f0.5852e7f6.js | 1 + assets/js/236eb0f0.ea22eadd.js | 1 - assets/js/23e022aa.6c773674.js | 1 - assets/js/23e022aa.9f08479d.js | 1 + assets/js/241648bf.39c48090.js | 1 + assets/js/241648bf.5946a39a.js | 1 - assets/js/241f36ed.20e39934.js | 1 + assets/js/24433f15.4be389a9.js | 1 + assets/js/25f19435.e9c61eb7.js | 1 - assets/js/25f19435.f0517f89.js | 1 + assets/js/261dbd4a.690860d0.js | 1 - assets/js/261dbd4a.98bcfe9f.js | 1 + assets/js/2668f34f.81895d61.js | 1 - assets/js/2668f34f.8cbf8a64.js | 1 + assets/js/26a33332.6303f856.js | 1 + assets/js/26a33332.9159dc58.js | 1 - assets/js/26ab9a7a.06a0c1d8.js | 1 + assets/js/26f7e8fd.759ba063.js | 1 - assets/js/26f7e8fd.9da42033.js | 1 + assets/js/277b6be0.0f968348.js | 1 + assets/js/277b6be0.6924c872.js | 1 - assets/js/280f0f40.42bc3e47.js | 1 + assets/js/285c66e7.2cc1f187.js | 1 + ...5b925.0168630d.js => 28b5b925.0cbd1f9b.js} | 2 +- assets/js/28bc9864.246d5f11.js | 1 + assets/js/28bc9864.9af5621d.js | 1 - assets/js/2a21571b.eb912000.js | 1 + assets/js/2ac03470.9c632600.js | 1 + assets/js/2b8e251b.baf2f328.js | 1 + assets/js/2b8e251b.f0bf2b40.js | 1 - assets/js/2bd0ed90.2b52c78d.js | 1 + assets/js/2bd0ed90.42d1714b.js | 1 - assets/js/2c04116d.a32622f9.js | 1 + assets/js/2c04116d.e52985c2.js | 1 - assets/js/2c27a7b4.6fa37b9d.js | 1 - assets/js/2c27a7b4.dfdad9af.js | 1 + assets/js/2cb8ed3d.81fd42ba.js | 1 - assets/js/2cb8ed3d.cd46c6fa.js | 1 + assets/js/2cc4f81c.309d1501.js | 1 + assets/js/2cc4f81c.f99f6439.js | 1 - assets/js/2d971abe.1121b1e3.js | 1 + assets/js/2d971abe.26e71149.js | 1 - assets/js/2e4bdb60.94cd32d7.js | 1 + assets/js/2e4bdb60.fa0d0d8f.js | 1 - assets/js/2fb5589e.18083c1f.js | 1 - assets/js/2fb5589e.7b8c9375.js | 1 + assets/js/2fe2b30f.134c1dc9.js | 1 + assets/js/2ffce966.32a561e7.js | 1 + assets/js/2ffce966.af34eb97.js | 1 - assets/js/31722bc4.8b17745a.js | 1 + assets/js/31722bc4.9f4ab15b.js | 1 - assets/js/31dbaea7.4f18e31a.js | 1 + assets/js/31dbaea7.cb2ad24d.js | 1 - assets/js/31e8518f.78747659.js | 1 + assets/js/32dd135c.20dd4de8.js | 1 - assets/js/32dd135c.45237611.js | 1 + assets/js/331badc5.26951b81.js | 1 + assets/js/331badc5.a0e388dd.js | 1 - assets/js/3362155c.196ff25b.js | 1 - assets/js/3362155c.2951497f.js | 1 + assets/js/33a9c3bd.2116c2c6.js | 1 + assets/js/33a9c3bd.3a1f4799.js | 1 - assets/js/33fc5bb8.1380a971.js | 1 + assets/js/33fc5bb8.4b577c2a.js | 1 - assets/js/340c2365.a24dd798.js | 1 - assets/js/340c2365.f9fb5495.js | 1 + assets/js/34b086e1.d56022ae.js | 1 + assets/js/34b086e1.d5c23182.js | 1 - assets/js/35808b61.27d7ec33.js | 1 - assets/js/35808b61.5e787011.js | 1 + assets/js/358cf6da.1b3e0934.js | 1 - assets/js/358cf6da.50a774a3.js | 1 + assets/js/35a4f7b3.e6576d4a.js | 1 - assets/js/35a4f7b3.f6ca0fad.js | 1 + assets/js/3619739c.59a850b5.js | 1 + assets/js/3619739c.88978e27.js | 1 - assets/js/362368d5.3185e36c.js | 1 - assets/js/362368d5.b933ef02.js | 1 + assets/js/3669623c.858e4657.js | 1 - assets/js/3669623c.b2f466b1.js | 1 + assets/js/36994c47.31271808.js | 1 - assets/js/36994c47.ce48ef1d.js | 1 + assets/js/3724f9ed.5eafca9c.js | 1 + assets/js/3724f9ed.c1aaf3d4.js | 1 - assets/js/372c0574.041c94fa.js | 1 + assets/js/381391cb.1c3e00bf.js | 1 - assets/js/381391cb.289be185.js | 1 + assets/js/38296185.1abf2f2d.js | 1 - assets/js/38296185.4a41b532.js | 1 + assets/js/387aabc2.5dc9fb8c.js | 1 + assets/js/38b4dbd3.7e645026.js | 1 + assets/js/38b4dbd3.bdc4f617.js | 1 - assets/js/38ff73e5.a2c2ca1e.js | 1 + assets/js/396a697c.6fa30002.js | 1 + assets/js/398cf21c.1c69896e.js | 1 + assets/js/398cf21c.db34c60d.js | 1 - assets/js/39ac5a41.0cb58650.js | 1 + assets/js/39ac5a41.6476776a.js | 1 - assets/js/3a19cb34.19cbf1ee.js | 1 + assets/js/3a5d5492.554dd0cb.js | 1 - assets/js/3a5d5492.d650666a.js | 1 + assets/js/3a98aaad.38c11bd1.js | 1 + assets/js/3a9d2720.81ccdd66.js | 1 + assets/js/3a9d2720.e34e9dc9.js | 1 - assets/js/3aa29420.3264772a.js | 1 + assets/js/3aa29420.a18fd86b.js | 1 - assets/js/3aaf2bfb.7183a894.js | 1 - assets/js/3aaf2bfb.b2e73a42.js | 1 + assets/js/3ac85609.12ab7143.js | 1 + assets/js/3ac85609.db0b618c.js | 1 - assets/js/3b749ca6.12e4a5ed.js | 1 + assets/js/3b749ca6.2b2c6cde.js | 1 - assets/js/3b86d751.8b6804b4.js | 1 - assets/js/3b86d751.aaac82d9.js | 1 + assets/js/3bf1ce3c.4be36f8e.js | 1 - assets/js/3bf1ce3c.e158e2c3.js | 1 + assets/js/3c9a8a22.cbde2a2a.js | 1 + assets/js/3ce1a06b.08bdbb80.js | 1 + assets/js/3ce1a06b.211c5901.js | 1 - assets/js/3d262e04.8ce8efde.js | 1 + assets/js/3d90f760.85ca88d2.js | 1 + assets/js/3d90f760.a5aed92d.js | 1 - assets/js/3d9ade7d.23253525.js | 1 + assets/js/3db2ed27.9501e9bc.js | 1 + assets/js/3e796ac9.77cf76db.js | 1 + assets/js/3e796ac9.d85b7445.js | 1 - assets/js/3efe71e8.3d46f3c7.js | 1 + assets/js/3efe71e8.65395bbf.js | 1 - assets/js/3fe76c6c.09dd3645.js | 1 + assets/js/40078125.92fe6e66.js | 1 + assets/js/40078125.bd3a3d60.js | 1 - assets/js/40c07125.9be41738.js | 1 - assets/js/40c07125.b0d71ef3.js | 1 + assets/js/411a45a4.bfced875.js | 1 + assets/js/41905acb.2fa671b8.js | 1 + assets/js/41905acb.9b219f55.js | 1 - assets/js/41e7d56e.2064be67.js | 1 - assets/js/41e7d56e.3c81128b.js | 1 + assets/js/41eb5a6a.25e46683.js | 1 + assets/js/41eb5a6a.432785b3.js | 1 - assets/js/42744730.53821c1f.js | 1 + assets/js/433fdaab.7d8c5d7c.js | 1 + assets/js/43a834ef.022fd866.js | 1 - assets/js/43a834ef.36ed403d.js | 1 + assets/js/43fd3112.179a51de.js | 1 - assets/js/43fd3112.e7439ebf.js | 1 + assets/js/4423d65b.01606f7a.js | 1 - assets/js/4423d65b.43623fa8.js | 1 + assets/js/449bc0d9.5dd63daf.js | 1 - assets/js/449bc0d9.ed4526e9.js | 1 + assets/js/452e65d7.1de256df.js | 1 + assets/js/452e65d7.cb4a29c5.js | 1 - assets/js/4545390c.0ca5f8dc.js | 1 - assets/js/4545390c.1d3a08c0.js | 1 + assets/js/459c4db6.2d3b0e56.js | 1 - assets/js/459c4db6.5ba5952e.js | 1 + assets/js/46206018.718b2b19.js | 1 + assets/js/46c04ff3.0ad52045.js | 1 - assets/js/46c04ff3.202aa580.js | 1 + assets/js/46e94768.dab245b0.js | 1 + assets/js/46e94768.e7996bf8.js | 1 - assets/js/471ca6e4.a462efc0.js | 1 - assets/js/471ca6e4.fc8efafc.js | 1 + assets/js/4732c0e2.3853b69c.js | 1 + assets/js/473a077c.eb7aa5a0.js | 1 + assets/js/4804492c.1872c747.js | 1 - assets/js/4804492c.9bff2638.js | 1 + assets/js/480fa8f7.75e26ad2.js | 1 + assets/js/480fa8f7.d7f8bb82.js | 1 - assets/js/481163ce.aa41f256.js | 1 - assets/js/481163ce.cef26660.js | 1 + assets/js/4832c6fe.1c554d77.js | 1 - assets/js/4832c6fe.829d1c30.js | 1 + assets/js/4a522ab0.74a2f484.js | 1 + assets/js/4ab63648.4c995b82.js | 1 + assets/js/4ab63648.80eee16a.js | 1 - assets/js/4ba3ceff.081c4b34.js | 1 + assets/js/4ba3ceff.df7f2c6a.js | 1 - assets/js/4bf77031.6626d6ed.js | 1 + assets/js/4c91363f.93a6ede3.js | 1 + assets/js/4c91363f.d784b1bc.js | 1 - assets/js/4cc44e19.7d979e88.js | 1 + assets/js/4cc75cd6.34166208.js | 1 - assets/js/4cc75cd6.c5db8ce8.js | 1 + assets/js/4d118a4e.26672722.js | 1 + assets/js/4d118a4e.fd0876b0.js | 1 - assets/js/4d355c12.2357dd50.js | 1 + assets/js/4d4c05c4.06123333.js | 1 + assets/js/4db682c6.25cb8a9e.js | 1 + assets/js/4db682c6.c730ac08.js | 1 - assets/js/4e015808.64ad3dfe.js | 1 + assets/js/4e015808.a485ffdf.js | 1 - assets/js/4e4df367.6b2bf3f2.js | 1 + assets/js/4e4df367.d91fcd1d.js | 1 - assets/js/4e8b7bcc.034fae29.js | 1 - assets/js/4e8b7bcc.d320f421.js | 1 + assets/js/4ed7ac06.e7cc3604.js | 1 + assets/js/4fdb6df3.2cd2adde.js | 1 - assets/js/4fdb6df3.3ae7fba2.js | 1 + assets/js/5052751d.2ecba4e7.js | 1 + assets/js/5052751d.e6a325fc.js | 1 - assets/js/50c21d96.c39e8686.js | 1 + assets/js/5109d3ad.4be6508a.js | 1 + assets/js/5109d3ad.b642a8c5.js | 1 - assets/js/5168ee15.9f3c0d6d.js | 1 + assets/js/51719dea.6107622a.js | 1 - assets/js/51719dea.65346675.js | 1 + assets/js/51ce653c.21c89cba.js | 1 - assets/js/51ce653c.dc35e1ca.js | 1 + assets/js/521a6610.546443b5.js | 1 + assets/js/521a6610.95717138.js | 1 - assets/js/52927c97.de1bbc11.js | 1 + assets/js/52ab49a5.7e1e13d0.js | 1 + assets/js/52fa5650.b182f278.js | 1 - assets/js/52fa5650.deb039aa.js | 1 + assets/js/533ebf6b.62b843d3.js | 1 - assets/js/533ebf6b.d593cda4.js | 1 + assets/js/5364a150.134445fe.js | 1 + assets/js/5364a150.155bae67.js | 1 - assets/js/53d095ec.27dbcfb8.js | 1 + assets/js/53d095ec.d55cf378.js | 1 - assets/js/53dc618d.924994dd.js | 1 + assets/js/546b5549.3f31a8ae.js | 1 + assets/js/546b5549.588a9376.js | 1 - assets/js/5496fb16.e37b2d67.js | 1 + assets/js/5497691c.3c574e7f.js | 1 - assets/js/5497691c.7a0da876.js | 1 + assets/js/54fcde43.7c8f527d.js | 1 + assets/js/55568807.2e91d1c2.js | 1 - assets/js/55568807.da999a9a.js | 1 + assets/js/555a4473.0aea839c.js | 1 - assets/js/555a4473.fbed11b1.js | 1 + assets/js/559dc838.8f1fde69.js | 1 + assets/js/560adf9d.033a09e9.js | 1 - assets/js/560adf9d.05f652ff.js | 1 + assets/js/5611a8f0.95614330.js | 1 + assets/js/56746dcb.51ad8181.js | 1 + assets/js/56746dcb.f4900217.js | 1 - assets/js/56aa8058.bdb374f9.js | 1 + assets/js/56ad65de.d53d5c28.js | 1 - assets/js/56ad65de.fcda7351.js | 1 + assets/js/56fae639.036d3ba6.js | 1 + assets/js/56ffdb25.995afe37.js | 1 + assets/js/576e11bb.b19d9462.js | 1 + assets/js/57d593f0.9081b32b.js | 1 + assets/js/57f923a9.ad12da5f.js | 1 - assets/js/57f923a9.f57d37c0.js | 1 + assets/js/58092c27.8c31d248.js | 1 + assets/js/58092c27.b116ed08.js | 1 - assets/js/58718032.25ddfdd1.js | 1 - assets/js/58718032.68396545.js | 1 + .../js/{416.c7de0599.js => 58913.6eee2a6e.js} | 2 +- assets/js/5979a0ec.621162c0.js | 1 + assets/js/5979a0ec.ef4511ba.js | 1 - assets/js/59b77803.fd87f57e.js | 1 + assets/js/5a22b142.b646e6c0.js | 1 + assets/js/5a22b142.d6483baa.js | 1 - assets/js/5a3b84ba.63717aa0.js | 1 + assets/js/5a3b84ba.73c72eda.js | 1 - assets/js/5a6ba1cd.fa112277.js | 1 + assets/js/5b38c543.7266d270.js | 1 + assets/js/5b827590.803d7896.js | 1 - assets/js/5b827590.e6f4f0a7.js | 1 + assets/js/5c07109c.72972707.js | 1 - assets/js/5c07109c.9dc5bbd3.js | 1 + assets/js/5c08a95a.26a3ecb2.js | 1 + assets/js/5c3f78ae.1c8dc26f.js | 1 + assets/js/5c3f78ae.c5d549a0.js | 1 - assets/js/5ce0f216.2ca1cbe8.js | 1 - assets/js/5ce0f216.5f134790.js | 1 + assets/js/5cf40dea.940a452c.js | 1 + assets/js/5cf40dea.eeda9684.js | 1 - assets/js/5d4e9672.00906f33.js | 1 - assets/js/5d4e9672.604f7974.js | 1 + assets/js/5db8b942.1835e546.js | 1 + assets/js/5e5b712e.6e7d89b9.js | 1 + assets/js/5e9306ee.35f8dd24.js | 1 - assets/js/5e9306ee.39afcc18.js | 1 + assets/js/5eb62c95.f9ba076c.js | 1 + assets/js/5ed91ab5.744eaccf.js | 1 + assets/js/5ed91ab5.d74e522c.js | 1 - assets/js/5f02ec4e.25f504ac.js | 1 + assets/js/5f02ec4e.e8115c1a.js | 1 - assets/js/5f241059.4b623e89.js | 1 + assets/js/603aca9e.56ef5275.js | 1 - assets/js/603aca9e.d3942f34.js | 1 + assets/js/6043c3f4.024a7c77.js | 1 - assets/js/6043c3f4.9b2ce9e7.js | 1 + assets/js/60d3a705.8959a6ed.js | 1 + assets/js/60d3a705.cec61f0b.js | 1 - assets/js/60fa9972.532892dc.js | 1 + assets/js/60fa9972.b69bb4a6.js | 1 - assets/js/61415b83.6de3dfdc.js | 1 + assets/js/6193b30e.8d7754ae.js | 1 + assets/js/6193b30e.8f5c08a1.js | 1 - assets/js/621db11d.72d8a767.js | 1 + assets/js/621db11d.81ae89ad.js | 1 - assets/js/6245c126.30b30088.js | 1 - assets/js/6245c126.8cf7cbff.js | 1 + assets/js/62569fa7.4c155b8f.js | 1 + assets/js/6318ac72.262b8dce.js | 1 + assets/js/6318ac72.49f55d51.js | 1 - assets/js/631bdc93.abd03f43.js | 1 + assets/js/63925da8.5e258b77.js | 1 + assets/js/63925da8.a65c70bf.js | 1 - assets/js/63d4ce07.2ce275cd.js | 1 + assets/js/63d4ce07.8dccf7cc.js | 1 - assets/js/64733a41.aa5d15dd.js | 1 + assets/js/6474e148.836b5554.js | 1 - assets/js/6474e148.f34dd9c3.js | 1 + assets/js/64899cf9.892e78a4.js | 1 + assets/js/64899cf9.d83e08cf.js | 1 - assets/js/64959b1e.2d006066.js | 1 + assets/js/64959b1e.487a4de3.js | 1 - assets/js/64bdcaf3.e264dcdb.js | 1 + assets/js/64c09e2e.d5d788c7.js | 1 - assets/js/64c09e2e.fa6ac55d.js | 1 + assets/js/650a8fc0.6c05b66c.js | 1 - assets/js/650a8fc0.fcb9962e.js | 1 + assets/js/6520db96.0f7b780d.js | 1 + assets/js/6520db96.17ace29b.js | 1 - assets/js/65961da4.2834b925.js | 1 + assets/js/65961da4.60f93cb9.js | 1 - assets/js/65a9ed9e.3fe3d223.js | 1 + assets/js/65a9ed9e.f11f4e01.js | 1 - assets/js/65cd111b.64289a65.js | 1 - assets/js/65cd111b.9f4c0cef.js | 1 + assets/js/680b7fa9.7fd0fcdc.js | 1 - assets/js/680b7fa9.83815de4.js | 1 + assets/js/68730730.64e6198a.js | 1 + assets/js/6875c492.b515c771.js | 1 - assets/js/6875c492.b5181e60.js | 1 + assets/js/68ccb7f6.108271e9.js | 1 - assets/js/68ccb7f6.22bc5312.js | 1 + assets/js/6a307077.51e38375.js | 1 - assets/js/6a307077.880239fa.js | 1 + assets/js/6bed00f2.4b14e37a.js | 1 + assets/js/6c606038.42035320.js | 1 - assets/js/6c606038.a21110c8.js | 1 + assets/js/6ceb2263.4869c915.js | 1 + assets/js/6dcb5e16.631ecf42.js | 1 + assets/js/6dcb5e16.e806e70a.js | 1 - assets/js/6e2737c0.94881826.js | 1 - assets/js/6e2737c0.fc64a7ef.js | 1 + assets/js/6e34a484.5e7fcec6.js | 1 - assets/js/6e34a484.df202898.js | 1 + assets/js/6fe126b9.1e04b30e.js | 1 - assets/js/6fe126b9.e52a98b9.js | 1 + assets/js/705e93ef.1d983d05.js | 1 - assets/js/705e93ef.e6ce9050.js | 1 + assets/js/709dfa47.62b3e248.js | 1 - assets/js/709dfa47.969b3e76.js | 1 + assets/js/72106d8f.bdea1c52.js | 1 + assets/js/727f767d.5bc07a55.js | 1 + assets/js/727f767d.bf85bdde.js | 1 - assets/js/72a89de8.820a02b4.js | 1 - assets/js/72a89de8.adc4dd3e.js | 1 + assets/js/72b43be8.3923b0c1.js | 1 + assets/js/72b43be8.5416988c.js | 1 - assets/js/72c6e609.3cf437f8.js | 1 + assets/js/72c6e609.8779ead0.js | 1 - assets/js/72cc2261.0d29617c.js | 1 + assets/js/72cc2261.d789919f.js | 1 - assets/js/7366a28d.4e7c9bfa.js | 1 + assets/js/738a6ad4.cf62d230.js | 1 - assets/js/738a6ad4.df968aee.js | 1 + assets/js/74d57d33.872e0d5f.js | 1 + assets/js/74d57d33.882cb0d6.js | 1 - assets/js/753d7b98.669096ae.js | 1 + assets/js/753d7b98.aa766a46.js | 1 - assets/js/75de5623.40d8f83e.js | 1 - assets/js/75de5623.515b1f12.js | 1 + assets/js/7607f1d5.09164840.js | 1 - assets/js/7607f1d5.d4ae0eb6.js | 1 + assets/js/76839fc0.2942aa34.js | 1 + assets/js/76a75fbd.8393010c.js | 1 + assets/js/76a75fbd.cb2ccf80.js | 1 - assets/js/76ea157b.4cf4a84d.js | 1 + assets/js/7708241d.76dde882.js | 1 - assets/js/7708241d.c2fc2488.js | 1 + assets/js/772d3db3.5265c340.js | 1 + assets/js/772d3db3.b3494ddc.js | 1 - assets/js/77395f9a.d869d436.js | 1 + assets/js/77981a3a.5c6f062e.js | 1 + assets/js/77981a3a.abfda3cf.js | 1 - assets/js/77c92c8c.228a09d7.js | 1 + assets/js/7850177d.e012839f.js | 1 + assets/js/78c66fad.28feae2f.js | 1 + assets/js/78c66fad.6c958184.js | 1 - assets/js/79113.6a88e948.js | 1 + assets/js/79474bae.a5a4db28.js | 1 + assets/js/79474bae.b05288fa.js | 1 - assets/js/79d896a3.09570395.js | 1 + assets/js/79d896a3.a26aa031.js | 1 - assets/js/7ade0b2a.77621e50.js | 1 - assets/js/7ade0b2a.9718930e.js | 1 + assets/js/7b1c3c68.2f0f9401.js | 1 + assets/js/7b1c3c68.e8be7755.js | 1 - assets/js/7b8da7d8.8db3e644.js | 1 + assets/js/7b8da7d8.eab766d1.js | 1 - assets/js/7bf3b0fc.dec4d3c2.js | 1 + assets/js/7c67ea25.976f293e.js | 1 + assets/js/7c67ea25.dbf66f2d.js | 1 - assets/js/7c798d59.93f88623.js | 1 - assets/js/7c798d59.a338572d.js | 1 + assets/js/7ce4a62a.76742a6b.js | 1 + assets/js/7ce4a62a.8943f664.js | 1 - assets/js/7ce91694.521657b2.js | 1 + assets/js/7cf62e8d.1ebdf3ec.js | 1 + assets/js/7cf62e8d.f6f618ae.js | 1 - assets/js/7cff47a5.24df3477.js | 1 + assets/js/7cff47a5.af4053dd.js | 1 - assets/js/7e55f6e6.22836de1.js | 1 - assets/js/7e55f6e6.80a4eced.js | 1 + assets/js/7effaf45.395677e0.js | 1 - assets/js/7effaf45.b7576d51.js | 1 + assets/js/7f115b1f.08f8427a.js | 1 + assets/js/7f115b1f.4ae39270.js | 1 - assets/js/7feecbc1.0bd89ed5.js | 1 + assets/js/80510dbd.8f6dc460.js | 1 + assets/js/80e6044e.713e25c1.js | 1 - assets/js/80e6044e.be8973b1.js | 1 + assets/js/814e64cc.3ab7cd73.js | 1 + assets/js/814f3328.42442acd.js | 1 + assets/js/814f3328.f0c18ae2.js | 1 - assets/js/8154f86c.6126d122.js | 1 + assets/js/821dc1e3.07ce4564.js | 1 + assets/js/821dc1e3.484815c2.js | 1 - assets/js/82237.082e051d.js | 1 + assets/js/830e9e14.801017c6.js | 1 + assets/js/830e9e14.b215aae2.js | 1 - assets/js/8323e0f5.5f3557eb.js | 1 - assets/js/8323e0f5.8ddff4c3.js | 1 + assets/js/85b8bb26.306e91f8.js | 1 + assets/js/85b8bb26.da81382e.js | 1 - assets/js/861e5e13.2a7daafb.js | 1 - assets/js/861e5e13.e59049a7.js | 1 + assets/js/862f9df3.ca8d966e.js | 1 + assets/js/8675f5af.bfe5a528.js | 1 + assets/js/86ae953a.101fb2af.js | 1 + assets/js/86b0038a.ae57b7f1.js | 1 + assets/js/870de909.24484384.js | 1 + assets/js/870de909.59012146.js | 1 - assets/js/871da383.0bff42d1.js | 1 + assets/js/8768801e.c7c6d258.js | 1 + assets/js/87867a42.4e487d7d.js | 1 + assets/js/87f5bee7.11d7c141.js | 1 + assets/js/87f5bee7.c06abb9f.js | 1 - assets/js/883310e5.f489e4cb.js | 1 + assets/js/883310e5.f84c5342.js | 1 - assets/js/8833ab21.2f4414a2.js | 1 + assets/js/8833ab21.8e10ccb3.js | 1 - assets/js/8941358f.b44c7608.js | 1 - assets/js/8941358f.e38b3228.js | 1 + assets/js/897e9cb3.4f6ab0e4.js | 1 + assets/js/897e9cb3.7555ccf7.js | 1 - assets/js/89c22482.8436b3a0.js | 1 - assets/js/89c22482.b950b66f.js | 1 + assets/js/89d896be.164f310b.js | 1 + assets/js/89d896be.f7cb4e66.js | 1 - assets/js/8c0ead1f.9f40d963.js | 1 - assets/js/8c0ead1f.ef689526.js | 1 + assets/js/8d265689.94e8c769.js | 1 - assets/js/8d265689.b6706ec9.js | 1 + assets/js/8d81394c.8dfe83fc.js | 1 + assets/js/8d81394c.b71ef1fd.js | 1 - assets/js/8d90c7e3.28b4caa2.js | 1 + assets/js/8dd9adb4.f35c58e4.js | 1 + assets/js/8de9f24f.046ff0c7.js | 1 + assets/js/8de9f24f.27e228f9.js | 1 - assets/js/8e1fd569.89ba8087.js | 1 + assets/js/8e1fd569.c1e0d801.js | 1 - assets/js/8f27be43.9c50069b.js | 1 - assets/js/8f27be43.ca74fdf7.js | 1 + assets/js/8fcee16d.27cfe3cc.js | 1 + assets/js/8ff31131.13194bde.js | 1 + assets/js/8ff31131.5c0f2d85.js | 1 - .../{8913.b6442bb9.js => 90416.140f33a2.js} | 2 +- assets/js/905c7445.20605116.js | 1 + assets/js/90efbb16.0264317d.js | 1 - assets/js/90efbb16.eca6bbe3.js | 1 + assets/js/90f2be13.1d93cdbb.js | 1 + assets/js/9116852a.695b9cf3.js | 1 + assets/js/9116852a.95b23be5.js | 1 - assets/js/915d90e1.21e8e7ff.js | 1 - assets/js/915d90e1.6837c1e2.js | 1 + assets/js/931ecaed.0c0278da.js | 1 - assets/js/931ecaed.28170080.js | 1 + assets/js/947e950c.16603b98.js | 1 + assets/js/94f643bb.0ffdacc0.js | 1 + assets/js/94f643bb.31c536d4.js | 1 - assets/js/95c53987.293de8d0.js | 1 + assets/js/962c96ee.fd744aa5.js | 1 + assets/js/96fcb421.99cb328e.js | 1 + assets/js/977c8faa.143671f7.js | 1 + assets/js/977c8faa.34237830.js | 1 - assets/js/98d1a471.222d0cf9.js | 1 + assets/js/98df448b.23f7a8f8.js | 1 - assets/js/98df448b.4dbc3804.js | 1 + assets/js/99a13742.82691f99.js | 1 + assets/js/99a13742.d3215e16.js | 1 - assets/js/9a38f23f.5bb7b4cd.js | 1 + assets/js/9a508619.234da57e.js | 1 + assets/js/9acc619b.a5bfebce.js | 1 - assets/js/9acc619b.fdbf2c17.js | 1 + assets/js/9afe1d3d.115a3c11.js | 1 + assets/js/9afe1d3d.e763479c.js | 1 - assets/js/9b0d9b67.bbbfb3bf.js | 1 - assets/js/9b0d9b67.d0cc04c6.js | 1 + assets/js/9b70ce79.bc96c9f0.js | 1 + assets/js/9c5b6467.3d86687a.js | 1 + assets/js/9c5b6467.3db5c71f.js | 1 - assets/js/9c6aa8d2.87f1ae35.js | 1 - assets/js/9c6aa8d2.a5007e66.js | 1 + assets/js/9c780b1a.134169a6.js | 1 - assets/js/9c780b1a.7540caa7.js | 1 + assets/js/9cb749bd.a84526b3.js | 1 + assets/js/9cd0819b.14619139.js | 1 - assets/js/9cd0819b.647896eb.js | 1 + assets/js/9d275d72.0b08718a.js | 1 + assets/js/9d275d72.668b0bc7.js | 1 - assets/js/9dd9d4ea.3a5f592e.js | 1 + assets/js/9e4087bc.426382ea.js | 1 + assets/js/9e4087bc.c84286d7.js | 1 - assets/js/9ec4e3de.88035139.js | 1 + assets/js/9ed00072.851b8b22.js | 1 + assets/js/9ed00072.861eaae3.js | 1 - assets/js/9ee7887a.3c988df8.js | 1 + assets/js/9ee7887a.a80b72fc.js | 1 - assets/js/a024ab51.21c9b95c.js | 1 + assets/js/a03c4947.715ecbfc.js | 1 - assets/js/a03c4947.b024c0ac.js | 1 + assets/js/a0ccdbb2.9cb4eb73.js | 1 + assets/js/a0ccdbb2.cf1b6b50.js | 1 - assets/js/a1868598.bd404523.js | 1 - assets/js/a1868598.e4c98816.js | 1 + assets/js/a2874f18.02b183f5.js | 1 + assets/js/a2874f18.d9627a72.js | 1 - assets/js/a2ea0fe7.f73f7874.js | 1 + assets/js/a30e2bb0.89267903.js | 1 - assets/js/a30e2bb0.db4101ac.js | 1 + assets/js/a35afcc3.76af9ebf.js | 1 + assets/js/a35afcc3.c8f608cb.js | 1 - assets/js/a36dca7d.ea67c2e6.js | 1 + assets/js/a3c7ece8.5621f945.js | 1 + assets/js/a3dc4ae2.0aa14bc4.js | 1 - assets/js/a3dc4ae2.ee951085.js | 1 + assets/js/a3e473b3.b3680e8e.js | 1 + assets/js/a4046515.82e9c056.js | 1 - assets/js/a4046515.c01a629a.js | 1 + assets/js/a40a2cf8.5c89beea.js | 1 - assets/js/a40a2cf8.a2747ba0.js | 1 + assets/js/a434b528.63eb51ca.js | 1 - assets/js/a434b528.8590c09f.js | 1 + assets/js/a4ae8417.5511ae65.js | 1 + assets/js/a4ae8417.97847ea7.js | 1 - assets/js/a4b0daeb.2b9391ae.js | 1 + assets/js/a4b0daeb.ca90cf11.js | 1 - assets/js/a4cd78b5.cbc7d4a6.js | 1 - assets/js/a4cd78b5.e215ea72.js | 1 + assets/js/a4f8fe7e.83f1a268.js | 1 + assets/js/a4f8fe7e.b982673b.js | 1 - assets/js/a53bd891.07818a14.js | 1 + assets/js/a53bd891.34baf369.js | 1 - assets/js/a55b9639.792f74b1.js | 1 - assets/js/a55b9639.bcfdb692.js | 1 + assets/js/a6957975.4b06c94e.js | 1 + assets/js/a6aa9e1f.43025aa7.js | 1 - assets/js/a6aa9e1f.4977cbdf.js | 1 + assets/js/a6c56441.56418c50.js | 1 + assets/js/a6efe0e1.17fb2b9f.js | 1 - assets/js/a6efe0e1.f66fc475.js | 1 + assets/js/a72bcf22.d7ffd90c.js | 1 - assets/js/a72bcf22.e9c31f44.js | 1 + assets/js/a7bd4aaa.951f72a9.js | 1 - assets/js/a7bd4aaa.f6bd7d37.js | 1 + assets/js/a7e0ea76.d1f0fa4d.js | 1 + assets/js/a80f26d4.7206c3fd.js | 1 - assets/js/a80f26d4.8ef94877.js | 1 + assets/js/a811e42c.6d7c6526.js | 1 + assets/js/a811e42c.b14b4cad.js | 1 - assets/js/a81b7004.614649de.js | 1 + assets/js/a81b7004.8421c8ce.js | 1 - assets/js/a833d846.fbb45413.js | 1 + assets/js/a94703ab.1cba57a1.js | 1 - assets/js/a94703ab.6d07f677.js | 1 + assets/js/a9707311.4c91be6f.js | 1 + assets/js/a9deb425.39296314.js | 1 - assets/js/a9deb425.4b3ac4cb.js | 1 + assets/js/a9f5564d.2e90b9b1.js | 1 - assets/js/a9f5564d.7ae89e3b.js | 1 + assets/js/aa162190.1c22b5a0.js | 1 - assets/js/aa162190.42fe6ae5.js | 1 + assets/js/aafbba97.658201c7.js | 1 - assets/js/aafbba97.d6419f85.js | 1 + assets/js/ab246697.680665e7.js | 1 - assets/js/ab246697.e9ff96c3.js | 1 + assets/js/ab991e0e.54fa42af.js | 1 - assets/js/ab991e0e.afb1898b.js | 1 + assets/js/aba21aa0.1ae003ba.js | 1 + assets/js/aba21aa0.9fadd1f0.js | 1 - assets/js/abd56c27.10b1808e.js | 1 + assets/js/abd56c27.bf3ed5c3.js | 1 - assets/js/ac16ac20.7b905f4c.js | 1 + assets/js/ac361b55.023b05ee.js | 1 + assets/js/ac361b55.a49eb8bd.js | 1 - assets/js/ac9a16c0.8245bc52.js | 1 + assets/js/acecf23e.1d924b0f.js | 1 + assets/js/acecf23e.77fdf311.js | 1 - assets/js/acee0a96.3b8121a3.js | 1 + assets/js/ad0b296a.459bbd0d.js | 1 + assets/js/ad0b296a.ec564b7f.js | 1 - assets/js/ad15c07f.89ebc550.js | 1 + assets/js/ad15c07f.9bfac3bd.js | 1 - assets/js/ad591877.cf7047e7.js | 1 + assets/js/ad727d36.001c91d8.js | 1 + assets/js/ad727d36.f0083a21.js | 1 - assets/js/ad7eda35.6b9ae2e7.js | 1 + assets/js/ad7eda35.de731ba0.js | 1 - assets/js/ae470ddc.47363dbf.js | 1 + assets/js/ae470ddc.f89950ff.js | 1 - assets/js/ae5d26cf.38358f39.js | 1 + assets/js/aee0fe92.50fa9bd5.js | 1 + assets/js/aee0fe92.cc892c71.js | 1 - assets/js/aefd42fa.03d773c1.js | 1 - assets/js/aefd42fa.55d4578e.js | 1 + assets/js/af050a36.9b90e62b.js | 1 - assets/js/af050a36.f22df805.js | 1 + assets/js/af1112c6.45aa0929.js | 1 + assets/js/af1112c6.4e044cf1.js | 1 - assets/js/afa6d836.e95ff699.js | 1 + assets/js/afa6d836.ec61673a.js | 1 - assets/js/b0b03333.557020ef.js | 1 + assets/js/b0e8b9d5.48be246d.js | 1 + assets/js/b114f501.3335785a.js | 1 + assets/js/b15d29cb.755d6cd9.js | 1 + assets/js/b15d29cb.801818ce.js | 1 - assets/js/b192e983.9d48f4fd.js | 1 + assets/js/b1eae65b.5f062bf3.js | 1 - assets/js/b1eae65b.e24179ba.js | 1 + assets/js/b36f50d3.b825a751.js | 1 - assets/js/b36f50d3.ce29c971.js | 1 + assets/js/b3a49b92.abfa439b.js | 1 - assets/js/b3a49b92.cbe25f10.js | 1 + assets/js/b3b8c5cb.66ba977e.js | 1 + assets/js/b3b8c5cb.d5f88718.js | 1 - assets/js/b415f00a.bd7e11c9.js | 1 + assets/js/b46ec474.0abc05a8.js | 1 - assets/js/b46ec474.8b17c0c3.js | 1 + assets/js/b67f60dc.7656748c.js | 1 - assets/js/b67f60dc.9c1e5109.js | 1 + assets/js/b687a817.0ec13cad.js | 1 - assets/js/b687a817.353ec7bd.js | 1 + assets/js/b70225e0.6b9ec728.js | 1 + assets/js/b70624a2.df42b3c0.js | 1 + assets/js/b71ecf14.1d11eac0.js | 1 + assets/js/b71ecf14.1f26aa20.js | 1 - assets/js/b7708f1e.2b3f2d3b.js | 1 + assets/js/b7708f1e.99acd00d.js | 1 - assets/js/b7a2b993.47bcf617.js | 1 + assets/js/b7cc26e1.2bfdb498.js | 1 + assets/js/b8c8445c.2da23794.js | 1 + assets/js/b8c8445c.ff0cc91b.js | 1 - assets/js/b8ef17b7.802d36c5.js | 1 + assets/js/b8f04a6b.619e6ba5.js | 1 + assets/js/b9ffcd07.a7d11053.js | 1 + assets/js/ba0fa3fe.2c38bb2c.js | 1 - assets/js/ba0fa3fe.45f877c7.js | 1 + assets/js/baabe181.1d890051.js | 1 + assets/js/baabe181.5c403d89.js | 1 - assets/js/baf71301.8c98a771.js | 1 - assets/js/baf71301.b7c5f244.js | 1 + assets/js/bafead24.1578a574.js | 1 - assets/js/bafead24.e60d55cc.js | 1 + assets/js/bb037852.08cf4bca.js | 1 + assets/js/bb037852.a0493efc.js | 1 - assets/js/bb9db0dd.0b2c5312.js | 1 - assets/js/bb9db0dd.83c0a3cb.js | 1 + assets/js/bc4bfdf0.65012c91.js | 1 - assets/js/bc4bfdf0.6b70cee0.js | 1 + assets/js/bcd2587d.f268cb4c.js | 1 + assets/js/bd7d26b2.4f702e53.js | 1 + assets/js/bd7d26b2.6860a437.js | 1 - assets/js/be0df356.4be5fb84.js | 1 + assets/js/be0df356.811aeaeb.js | 1 - assets/js/be5e85f4.e6fa4137.js | 1 + assets/js/be5e85f4.f95550ce.js | 1 - assets/js/befad559.50157083.js | 1 + assets/js/befad559.b54dfbe5.js | 1 - assets/js/bf5bbaf8.13f23cdc.js | 1 + assets/js/bf5bbaf8.79578d9c.js | 1 - assets/js/bfb3244a.0a60faf8.js | 1 + assets/js/bfb3244a.40640614.js | 1 - assets/js/c00ffc57.c6e16365.js | 1 + assets/js/c0299000.60ccb8d1.js | 1 + assets/js/c0299000.a0ce979e.js | 1 - assets/js/c0def98a.5774eed0.js | 1 + assets/js/c10b8a9f.7b6997c1.js | 1 - assets/js/c10b8a9f.f9001f93.js | 1 + assets/js/c10cfbfe.2a9f53c2.js | 1 + assets/js/c10cfbfe.9a85001f.js | 1 - assets/js/c141421f.4ae5844e.js | 1 + assets/js/c141421f.80b09241.js | 1 - assets/js/c19e69a7.2fc7560a.js | 1 - assets/js/c19e69a7.9d2442b7.js | 1 + assets/js/c2728190.0a5a894f.js | 1 - assets/js/c2728190.c9436c76.js | 1 + assets/js/c2a48fdb.aa595378.js | 1 + assets/js/c2a48fdb.c860eb25.js | 1 - assets/js/c3308ba6.425334c7.js | 1 + assets/js/c3308ba6.dabf8cd8.js | 1 - assets/js/c34be5c7.a0d52e84.js | 1 + assets/js/c377a04b.d0facf52.js | 1 + assets/js/c377dc4a.607514a8.js | 1 + assets/js/c377dc4a.bac70803.js | 1 - assets/js/c37f176d.38ea646e.js | 1 + assets/js/c37f176d.df6ecd7f.js | 1 - assets/js/c380abc4.9161c3a0.js | 1 + assets/js/c380abc4.bac3fe3d.js | 1 - assets/js/c4561df8.dd6655af.js | 1 - assets/js/c4561df8.e426f1f3.js | 1 + assets/js/c45e62e7.265d09b1.js | 1 + assets/js/c474c2b1.b1dce14d.js | 1 + assets/js/c52eaa26.32d71864.js | 1 - assets/js/c52eaa26.dc4744b9.js | 1 + assets/js/c5f06d44.f6b77b6b.js | 1 + assets/js/c691959f.300edfdd.js | 1 + assets/js/c691959f.8bec913d.js | 1 - assets/js/c74094f8.7db305e4.js | 1 - assets/js/c74094f8.c3dcc644.js | 1 + assets/js/c7d46fe1.340d8422.js | 1 - assets/js/c7d46fe1.c6ccb6de.js | 1 + assets/js/c8e4da00.1ce531b1.js | 1 - assets/js/c8e4da00.377067a0.js | 1 + assets/js/c8eb2c38.d5c12a00.js | 1 + assets/js/c95e6d8d.9669f9e6.js | 1 + assets/js/c9d52fc5.95b1b5e6.js | 1 + assets/js/c9d52fc5.a4eef94e.js | 1 - assets/js/c9db186d.08192e85.js | 1 - assets/js/c9db186d.fb5fa52a.js | 1 + assets/js/c9f0fdac.1f67a1b8.js | 1 - assets/js/c9f0fdac.8d113f91.js | 1 + assets/js/ca0e408e.aa3ff09a.js | 1 - assets/js/ca7245df.76e3b27d.js | 1 + assets/js/ca7245df.9c1a68a4.js | 1 - assets/js/ca962d2e.fb46012c.js | 1 + assets/js/cacd3f19.fb6d7d41.js | 1 + assets/js/cad9fd36.a362a2cd.js | 1 + assets/js/cb447cb9.2ecfdbd1.js | 1 + assets/js/cb63487a.169a1a3c.js | 1 - assets/js/cb63487a.7cab35d9.js | 1 + assets/js/cbe09f13.99a63f42.js | 1 - assets/js/cbe09f13.b56f8a87.js | 1 + assets/js/cbe8101d.1206d77a.js | 1 - assets/js/cbe8101d.7596f688.js | 1 + assets/js/cc2e94c0.ab50e15c.js | 1 - assets/js/cc2e94c0.b91d5649.js | 1 + assets/js/cc84b9e4.a97ce4c6.js | 1 + assets/js/ccc49370.78b27ccb.js | 1 + assets/js/ccc49370.be9d46ff.js | 1 - assets/js/cd8c5c3b.2df6b353.js | 1 + assets/js/cd948886.281c855f.js | 1 - assets/js/cd948886.5aed8c76.js | 1 + assets/js/cdd6a56c.a344a0d7.js | 1 + assets/js/ce0e1dbb.a2815888.js | 1 + assets/js/ce0e1dbb.b2988b7b.js | 1 - assets/js/ce3d5a4b.69e5cefd.js | 1 + assets/js/ce3d5a4b.b4b03daf.js | 1 - assets/js/ce6605d8.702f3687.js | 1 + assets/js/ce6605d8.ba4d38f5.js | 1 - assets/js/ce6fe363.8c36f3f4.js | 1 + assets/js/cf3029ea.f454004c.js | 1 + assets/js/cf35294f.5c7a277d.js | 1 + assets/js/cf35294f.bb066321.js | 1 - assets/js/cfcbd284.63fc464b.js | 1 + assets/js/d02d0f51.fff99507.js | 1 + assets/js/d050b476.240ce090.js | 1 + assets/js/d050b476.71af1ad0.js | 1 - assets/js/d0616161.a6c02aa2.js | 1 + assets/js/d06ee05c.4fae27bd.js | 1 + assets/js/d06ee05c.b42299f4.js | 1 - assets/js/d0a8493b.0a50edbb.js | 1 - assets/js/d0a8493b.8611e4aa.js | 1 + assets/js/d0c6c99a.e6fa3b5a.js | 1 + assets/js/d13dc577.5be46c79.js | 1 + assets/js/d13dc577.6fe89c7c.js | 1 - assets/js/d2039ef8.5609990b.js | 1 - assets/js/d2039ef8.e3054ff4.js | 1 + assets/js/d220dcab.b0fd0ac0.js | 1 - assets/js/d220dcab.d1c22622.js | 1 + assets/js/d279fdce.312ed6b1.js | 1 + assets/js/d279fdce.7ef66588.js | 1 - assets/js/d3ef4614.1ecc7dd0.js | 1 + assets/js/d3ef4614.82ba742b.js | 1 - assets/js/d477c291.57fee1c9.js | 1 - assets/js/d477c291.e950cbd2.js | 1 + ...4e3de.eaa96579.js => d48191b6.092d048f.js} | 2 +- assets/js/d48191b6.9a8c43c0.js | 1 - assets/js/d49dddd4.766c61f5.js | 1 + assets/js/d49dddd4.ceb8eee3.js | 1 - assets/js/d4c529d3.c6f1d5fa.js | 1 - assets/js/d4c529d3.d2c5e7bd.js | 1 + assets/js/d629d828.9452bae9.js | 1 + assets/js/d638c601.15664957.js | 1 + assets/js/d638c601.58b730d1.js | 1 - assets/js/d7289626.35d9a384.js | 1 + assets/js/d7289626.6cdeaeb0.js | 1 - assets/js/d7f9f727.75d78148.js | 1 - assets/js/d7f9f727.baf34cdc.js | 1 + assets/js/d7fae98e.1349e043.js | 1 + assets/js/d7fae98e.1faab744.js | 1 - assets/js/d80df429.67028afb.js | 1 - assets/js/d80df429.d3c78300.js | 1 + assets/js/d81ba6be.98f8f400.js | 1 + assets/js/d8ae3676.ed256976.js | 1 + assets/js/d8c709f8.5f79bc8f.js | 1 + assets/js/d92b4d08.2f4390d9.js | 1 - assets/js/d92b4d08.d98a3927.js | 1 + assets/js/d94d6bbe.5f51f6b7.js | 1 + assets/js/d94d6bbe.f9bfb75e.js | 1 - assets/js/db24aef0.5b7d27fc.js | 1 - assets/js/db24aef0.7be66191.js | 1 + assets/js/dbfc4782.400f41c7.js | 1 + assets/js/dbfc4782.468a1d4c.js | 1 - assets/js/dc1c4417.1f2e5fdc.js | 1 - assets/js/dc1c4417.31cadd38.js | 1 + assets/js/dc5e10d3.7935911a.js | 1 + assets/js/dc5e10d3.854abbc3.js | 1 - assets/js/dcb4c613.333717ee.js | 1 + assets/js/dcb4c613.9305969c.js | 1 - assets/js/dd04b75e.3463f4df.js | 1 + assets/js/dd04b75e.7f740bf3.js | 1 - assets/js/dd908370.a9598e25.js | 1 - assets/js/dd908370.b6499474.js | 1 + assets/js/dd93ee27.c6c59160.js | 1 + assets/js/de33ad21.8fafd612.js | 1 + assets/js/df5bc763.577a5deb.js | 1 + assets/js/df5bc763.837d978f.js | 1 - assets/js/dfbc8a55.1e3a65ca.js | 1 - assets/js/dfbc8a55.270b4583.js | 1 + assets/js/dfcc4619.0ab89293.js | 1 - assets/js/dfcc4619.c764dc8b.js | 1 + assets/js/e068c333.4084d666.js | 1 + assets/js/e08eef46.56de3c31.js | 1 - assets/js/e08eef46.c3b1a795.js | 1 + assets/js/e10cd13d.5aff8aea.js | 1 + assets/js/e15566cb.26ef38f0.js | 1 + assets/js/e15566cb.87dbe301.js | 1 - assets/js/e1e5af17.a55d48e0.js | 1 + assets/js/e1e5af17.e2008a93.js | 1 - assets/js/e238c115.03c04108.js | 1 + assets/js/e238c115.2aaf7fc9.js | 1 - assets/js/e2509bb6.6b2e5db8.js | 1 + assets/js/e2799c63.caf45662.js | 1 + assets/js/e2799c63.d128e43e.js | 1 - assets/js/e289ead3.1f169ca7.js | 1 - assets/js/e289ead3.b2eba89f.js | 1 + assets/js/e2975a84.51a6b884.js | 1 + assets/js/e2975a84.5efeb63f.js | 1 - assets/js/e2f5312b.06dbe2a4.js | 1 - assets/js/e2f5312b.d4f136f1.js | 1 + assets/js/e3f9a068.2511d6f6.js | 1 - assets/js/e3f9a068.ee51fe72.js | 1 + assets/js/e45056bc.816736bc.js | 1 + assets/js/e45056bc.9693a59b.js | 1 - assets/js/e4d870e1.abd2b6f0.js | 1 + assets/js/e4d870e1.f85bd94e.js | 1 - assets/js/e5493a21.b67e196f.js | 1 + assets/js/e5493a21.e2c9467a.js | 1 - assets/js/e5afa1a3.435be811.js | 1 + assets/js/e605c6b3.e7d9d88b.js | 1 + assets/js/e7589c2a.a8005701.js | 1 + assets/js/e8b40bee.16146a5b.js | 1 + assets/js/e8b40bee.291c4a8c.js | 1 - assets/js/e939f825.436c9fa9.js | 1 + assets/js/ea0474c4.2a0d441d.js | 1 - assets/js/ea0474c4.f097486d.js | 1 + assets/js/ea921b39.308e6c57.js | 1 + assets/js/eaba5dd2.013bab1c.js | 1 - assets/js/eaba5dd2.a045f2ae.js | 1 + assets/js/eacea541.713b9738.js | 1 + assets/js/eacea541.eb56de71.js | 1 - assets/js/eb0d94ae.4b8f7e24.js | 1 + assets/js/eb0d94ae.58bdbefc.js | 1 - assets/js/eb1cd7f2.1282bdde.js | 1 + assets/js/eb1cd7f2.4d0cd80d.js | 1 - assets/js/eb5a6cc0.5fb4114d.js | 1 + assets/js/eb5a6cc0.bb4e4618.js | 1 - assets/js/ebb9a3ce.877a950d.js | 1 - assets/js/ebb9a3ce.bdc45b5b.js | 1 + assets/js/ed267fba.167c6c60.js | 1 - assets/js/ed267fba.6c0f909a.js | 1 + assets/js/ed3af4a0.611178a8.js | 1 + assets/js/ed772d97.ff32e5f5.js | 1 + assets/js/ee7c1cc7.acd77737.js | 1 + assets/js/ee7c1cc7.f382d244.js | 1 - assets/js/ee94176e.42f353c4.js | 1 + assets/js/ee94176e.948fb7cb.js | 1 - assets/js/eeb3740b.7aca9b4d.js | 1 + assets/js/ef2abd7e.4f00923b.js | 1 + assets/js/ef2abd7e.e1b228a5.js | 1 - assets/js/ef646837.20fafc7e.js | 1 + assets/js/ef726b40.2fca8d33.js | 1 + assets/js/ef7672e3.34f0b8af.js | 1 + assets/js/ef7672e3.d080a329.js | 1 - assets/js/efd01d75.02a4a077.js | 1 + assets/js/eff21157.bd65bcae.js | 1 - assets/js/eff21157.d54a2b5c.js | 1 + assets/js/f0563fee.0da4678b.js | 1 - assets/js/f0563fee.df8d1b93.js | 1 + assets/js/f070a991.8a1ac562.js | 1 - assets/js/f070a991.984951c4.js | 1 + assets/js/f1245771.23f1d291.js | 1 - assets/js/f1245771.8a14c444.js | 1 + assets/js/f1a6c2e6.30426d72.js | 1 + assets/js/f1c6b7a3.50559f74.js | 1 - assets/js/f1c6b7a3.dd24385f.js | 1 + assets/js/f1f89c2e.04046fd4.js | 1 - assets/js/f1f89c2e.2e307f65.js | 1 + assets/js/f203f57a.c10ab2eb.js | 1 + assets/js/f224ad82.becdd6c1.js | 1 + assets/js/f2779c45.1985fa4b.js | 1 + assets/js/f2779c45.270e5772.js | 1 - assets/js/f2a77c75.4e76bee9.js | 1 + assets/js/f2e157d0.d49d6620.js | 1 + assets/js/f3bf6984.253d30ee.js | 1 - assets/js/f3bf6984.d6d4b2c7.js | 1 + assets/js/f46d6e59.b998f248.js | 1 + assets/js/f46d6e59.d7f83469.js | 1 - assets/js/f5c04343.715b43d2.js | 1 + assets/js/f6320c57.a7d30f9d.js | 1 + assets/js/f69b951d.a8eed262.js | 1 + assets/js/f71fe95d.9ad08d80.js | 1 + assets/js/f71fe95d.fa1be639.js | 1 - assets/js/f74078f7.5b44140b.js | 1 + assets/js/f776c06c.59c0b752.js | 1 - assets/js/f776c06c.6260625f.js | 1 + assets/js/f8743170.a30916fe.js | 1 + assets/js/f88cb658.93e9da43.js | 1 + assets/js/f88cb658.de8becbc.js | 1 - assets/js/f95b1f88.2c0ea01f.js | 1 + assets/js/f95b1f88.7cc6f7b3.js | 1 - assets/js/faf2a93e.41ab65a9.js | 1 - assets/js/faf2a93e.5f4fcdac.js | 1 + assets/js/fb804d1c.8135cc99.js | 1 + assets/js/fb804d1c.9658edac.js | 1 - assets/js/fb904585.9a2467f1.js | 1 + assets/js/fd661beb.9306c892.js | 1 + assets/js/fd661beb.dd72aba0.js | 1 - assets/js/fd967833.84a1d37c.js | 1 + assets/js/fe0242b1.4ee542a5.js | 1 + assets/js/fe0242b1.da99f6c2.js | 1 - assets/js/fef6ab33.16f28ded.js | 1 - assets/js/fef6ab33.746d8b52.js | 1 + assets/js/main.8959bba6.js | 2 - assets/js/main.d3917998.js | 2 + ...CENSE.txt => main.d3917998.js.LICENSE.txt} | 0 assets/js/runtime~main.d0ca807f.js | 1 - assets/js/runtime~main.f9ac0d96.js | 1 + blog/addressable-entity/index.html | 8 +- blog/archive/index.html | 8 +- blog/atom.xml | 108 +- blog/authors/alexanderlimonov/index.html | 8 +- blog/authors/dylanireland/index.html | 8 +- blog/authors/index.html | 8 +- blog/authors/melpadden/index.html | 8 +- blog/authors/sczembor/index.html | 10 +- blog/condor-fee-elimination/index.html | 8 +- blog/condor-local-setup/index.html | 10 +- blog/condor-validator-rewards/index.html | 10 +- blog/index.html | 10 +- blog/rss.xml | 104 +- blog/tags/condor/index.html | 10 +- blog/tags/docs-redux/index.html | 8 +- blog/tags/features/index.html | 8 +- blog/tags/hello/index.html | 8 +- blog/tags/index.html | 8 +- blog/tags/new-docs/index.html | 8 +- blog/tags/setup/index.html | 8 +- blog/tags/tokenomics/index.html | 8 +- blog/tags/validators/index.html | 8 +- blog/welcome-docs-redux/index.html | 8 +- concepts/about/index.html | 29 + concepts/accounts-and-keys/index.html | 27 +- concepts/addressable-entity/index.html | 40 + concepts/callstack/index.html | 20 +- concepts/design/casper-design/index.html | 57 +- concepts/design/consensus/index.html | 68 + concepts/design/highway/index.html | 67 +- .../design/networking-protocol/index.html | 16 +- concepts/design/p2p/index.html | 18 +- .../index.html | 16 +- concepts/design/rewards/index.html | 67 + concepts/design/zug/index.html | 86 + concepts/dictionaries/index.html | 28 +- concepts/economics/concepts/index.html | 31 - concepts/economics/consensus/index.html | 61 +- concepts/economics/delegation/index.html | 42 - .../economics/dynamic-gas-pricing/index.html | 12 +- concepts/economics/fee-elimination/index.html | 40 + concepts/economics/gas-concepts/index.html | 40 +- concepts/economics/staking/index.html | 33 + concepts/global-state/index.html | 16 +- concepts/glossary/A/index.html | 16 +- concepts/glossary/B/index.html | 24 +- concepts/glossary/C/index.html | 15 +- concepts/glossary/D/index.html | 17 +- concepts/glossary/E/index.html | 18 +- concepts/glossary/F/index.html | 12 +- concepts/glossary/G/index.html | 18 +- concepts/glossary/H/index.html | 12 +- concepts/glossary/I/index.html | 12 +- concepts/glossary/J/index.html | 12 +- concepts/glossary/K/index.html | 12 +- concepts/glossary/L/index.html | 12 +- concepts/glossary/M/index.html | 12 +- concepts/glossary/N/index.html | 12 +- concepts/glossary/O/index.html | 12 +- concepts/glossary/P/index.html | 16 +- concepts/glossary/Q/index.html | 12 +- concepts/glossary/R/index.html | 12 +- concepts/glossary/S/index.html | 20 +- concepts/glossary/T/index.html | 14 +- concepts/glossary/U/index.html | 12 +- concepts/glossary/V/index.html | 12 +- concepts/glossary/W/index.html | 12 +- concepts/glossary/X/index.html | 12 +- concepts/glossary/Y/index.html | 12 +- concepts/glossary/Z/index.html | 14 +- concepts/hash-types/index.html | 133 -- concepts/index.html | 18 +- concepts/intro-to-dapps/index.html | 28 +- .../key-types/index.html | 14 +- concepts/list-auth-keys/index.html | 29 +- concepts/serialization/index.html | 44 + .../serialization/primitives/index.html | 14 +- concepts/serialization/structures/index.html | 509 +++++ .../serialization/types/index.html | 264 +-- concepts/smart-contracts/index.html | 19 +- counter-testnet/index.html | 18 +- counter/index.html | 16 +- deploy-and-deploy-lifecycle/index.html | 75 - design/index.html | 10 +- developers/cli/calling-contracts/index.html | 15 +- developers/cli/delegate/index.html | 16 +- .../cli/execution-error-codes/index.html | 12 +- developers/cli/index.html | 16 +- .../cli/installing-contracts/index.html | 123 +- developers/cli/opcode-costs/index.html | 45 +- .../cli/querying-global-state/index.html | 194 +- developers/cli/redelegate/index.html | 12 +- .../cli/sending-transactions/index.html | 42 +- .../direct-token-transfer/index.html | 22 +- developers/cli/transfers/index.html | 18 +- .../multisig-deploy-transfer/index.html | 16 +- .../cli/transfers/verify-transfer/index.html | 16 +- developers/cli/undelegate/index.html | 12 +- developers/cli/verifying-contracts/index.html | 46 + developers/dapps/dapp/index.html | 22 +- developers/dapps/index.html | 12 +- .../monitor-and-consume-events/index.html | 203 +- developers/dapps/nctl-test/index.html | 99 +- developers/dapps/prerequisites/index.html | 12 +- .../dapps/sdk/client-library-usage/index.html | 12 +- developers/dapps/sdk/csharp-sdk/index.html | 12 +- developers/dapps/sdk/go-sdk/index.html | 14 +- developers/dapps/sdk/python-sdk/index.html | 89 +- developers/dapps/sdk/script-sdk/index.html | 12 +- developers/dapps/setup-nctl/index.html | 105 +- developers/dapps/signing-a-deploy/index.html | 35 - .../dapps/signing-a-transaction/index.html | 35 + developers/dapps/speculative-exec/index.html | 14 +- developers/dapps/technology-stack/index.html | 22 +- developers/dapps/template-frontend/index.html | 12 +- developers/dapps/uref-security/index.html | 18 +- developers/essential-crates/index.html | 12 +- developers/index.html | 12 +- developers/json-rpc/errors/index.html | 14 +- developers/json-rpc/guidance/index.html | 14 +- developers/json-rpc/index.html | 22 +- .../json-rpc-informational/index.html | 377 +++- developers/json-rpc/json-rpc-pos/index.html | 34 +- .../json-rpc-transactional/index.html | 135 +- .../json-rpc/minimal-compliance/index.html | 30 +- developers/json-rpc/types_chain/index.html | 1749 +++++++++++++---- developers/json-rpc/types_cl/index.html | 64 +- developers/prerequisites/index.html | 39 +- .../assembly-script/index.html | 14 +- .../best-practices/index.html | 30 +- .../calling-contracts/index.html | 20 +- .../contract-hash-vs-package-hash/index.html | 15 +- .../contract-vs-session/index.html | 14 +- .../emitting-contract-events/index.html | 16 +- .../factory-pattern/index.html | 20 +- .../getting-started/index.html | 17 +- .../simple-contract/index.html | 33 +- .../testing-contracts/index.html | 33 +- .../testing-session-code/index.html | 12 +- .../upgrading-contracts/index.html | 15 +- .../writing-session-code/index.html | 12 +- disclaimer/index.html | 12 +- economics/index.html | 49 +- glossary/index.html | 12 +- index.html | 24 +- next/concepts/addressable-entity/index.html | 40 - next/concepts/callstack/index.html | 33 - next/concepts/design/consensus/index.html | 68 - next/concepts/design/highway/index.html | 45 - next/concepts/design/p2p/index.html | 53 - .../index.html | 36 - next/concepts/economics/consensus/index.html | 79 - .../economics/fee-elimination/index.html | 40 - .../economics/gas-concepts/index.html | 40 - next/concepts/economics/staking/index.html | 33 - next/concepts/global-state/index.html | 42 - next/concepts/glossary/A/index.html | 37 - next/concepts/glossary/B/index.html | 63 - next/concepts/glossary/C/index.html | 45 - next/concepts/glossary/D/index.html | 39 - next/concepts/glossary/E/index.html | 36 - next/concepts/glossary/F/index.html | 27 - next/concepts/glossary/G/index.html | 43 - next/concepts/glossary/H/index.html | 27 - next/concepts/glossary/I/index.html | 23 - next/concepts/glossary/J/index.html | 25 - next/concepts/glossary/K/index.html | 25 - next/concepts/glossary/L/index.html | 26 - next/concepts/glossary/M/index.html | 31 - next/concepts/glossary/N/index.html | 41 - next/concepts/glossary/O/index.html | 28 - next/concepts/glossary/P/index.html | 48 - next/concepts/glossary/Q/index.html | 23 - next/concepts/glossary/R/index.html | 31 - next/concepts/glossary/S/index.html | 51 - next/concepts/glossary/T/index.html | 30 - next/concepts/glossary/U/index.html | 29 - next/concepts/glossary/V/index.html | 32 - next/concepts/glossary/W/index.html | 27 - next/concepts/glossary/X/index.html | 23 - next/concepts/glossary/Y/index.html | 23 - next/concepts/glossary/Z/index.html | 25 - next/concepts/index.html | 99 - next/concepts/intro-to-dapps/index.html | 42 - next/concepts/list-auth-keys/index.html | 39 - next/concepts/serialization/index.html | 44 - next/concepts/smart-contracts/index.html | 38 - next/counter-testnet/index.html | 42 - next/counter/index.html | 33 - next/design/index.html | 20 - .../cli/execution-error-codes/index.html | 28 - next/developers/cli/index.html | 67 - next/developers/cli/transfers/index.html | 27 - .../cli/verifying-contracts/index.html | 46 - next/developers/dapps/dapp/index.html | 33 - next/developers/dapps/index.html | 67 - .../developers/dapps/prerequisites/index.html | 51 - .../dapps/sdk/csharp-sdk/index.html | 39 - .../dapps/signing-a-transaction/index.html | 35 - .../dapps/speculative-exec/index.html | 28 - .../dapps/technology-stack/index.html | 60 - next/developers/essential-crates/index.html | 77 - next/developers/index.html | 57 - next/developers/json-rpc/errors/index.html | 126 -- next/developers/json-rpc/guidance/index.html | 29 - next/developers/json-rpc/index.html | 65 - .../json-rpc/minimal-compliance/index.html | 49 - next/developers/json-rpc/types_cl/index.html | 56 - .../calling-contracts/index.html | 44 - .../contract-vs-session/index.html | 62 - .../upgrading-contracts/index.html | 41 - next/economics/index.html | 51 - next/glossary/index.html | 24 - next/index.html | 29 - .../inactive-vs-faulty/index.html | 34 - .../operators/becoming-a-validator/index.html | 51 - next/operators/index.html | 51 - next/operators/maintenance/index.html | 39 - .../setup-network/genesis/index.html | 32 - next/operators/setup-network/index.html | 47 - next/operators/setup/fast-sync/index.html | 26 - next/operators/setup/hardware/index.html | 40 - next/operators/setup/index.html | 71 - next/operators/setup/node-events/index.html | 35 - next/operators/setup/non-root-user/index.html | 57 - next/operators/setup/upgrade/index.html | 40 - next/resources/advanced/multi-sig/index.html | 22 - .../counter-testnet/overview/index.html | 23 - .../beginner/counter/overview/index.html | 23 - .../build-on-casper/introduction/index.html | 77 - next/resources/changelog/index.html | 35 - next/resources/index.html | 89 - .../tokens/cep18/quickstart-guide/index.html | 63 - .../tokens/cep78/reverse-lookup/index.html | 52 - next/resources/tokens/index.html | 82 - next/resources/tutorials/advanced/index.html | 58 - .../getting-started-tutorial/index.html | 24 - next/resources/tutorials/beginner/index.html | 78 - next/runtime/index.html | 63 - next/sdk/index.html | 74 - next/users/block-explorer/index.html | 40 - next/users/csprlive/index.html | 46 - next/users/delegate-ui/index.html | 83 - next/users/funding-from-exchanges/index.html | 58 - next/users/index.html | 91 - next/users/ledger/index.html | 46 - next/users/testnet-faucet/index.html | 34 - next/users/token-transfer/index.html | 56 - next/users/undelegate-ui/index.html | 61 - next/workflow/ledger-setup/index.html | 70 - next/writing-contracts/index.html | 158 -- opensearch.xml | 8 +- .../becoming-a-validator/bonding/index.html | 24 +- .../change-bid-public-key/index.html | 10 +- .../inactive-vs-faulty/index.html | 13 +- operators/becoming-a-validator/index.html | 16 +- .../recovering/index.html | 17 +- .../becoming-a-validator/unbonding/index.html | 12 +- operators/index.html | 12 +- .../archiving-and-restoring/index.html | 12 +- operators/maintenance/index.html | 12 +- operators/maintenance/moving-node/index.html | 12 +- operators/setup-network/chain-spec/index.html | 414 +++- .../setup-network/create-private/index.html | 27 +- operators/setup-network/genesis/index.html | 12 +- operators/setup-network/index.html | 12 +- .../staging-files-for-new-network/index.html | 12 +- .../setup/basic-node-configuration/index.html | 18 +- .../setup/casper-sidecar/index.html | 10 +- operators/setup/fast-sync/index.html | 16 +- operators/setup/hardware/index.html | 12 +- operators/setup/index.html | 20 +- operators/setup/install-node/index.html | 12 +- operators/setup/joining/index.html | 16 +- operators/setup/node-endpoints/index.html | 16 +- operators/setup/node-events/index.html | 35 + operators/setup/non-root-user/index.html | 12 +- operators/setup/open-files/index.html | 12 +- operators/setup/upgrade/index.html | 12 +- .../list-auth-keys-tutorial/index.html | 26 +- resources/advanced/multi-sig/index.html | 12 +- .../multi-sig/multi-sig-workflow/index.html | 12 +- .../multi-sig/other-scenarios/index.html | 12 +- .../counter-testnet/commands/index.html | 12 +- .../counter-testnet/overview/index.html | 12 +- .../counter-testnet/walkthrough/index.html | 24 +- .../beginner/counter/commands/index.html | 12 +- .../beginner/counter/overview/index.html | 12 +- .../beginner/counter/walkthrough/index.html | 52 +- .../casper-open-source-software/index.html | 12 +- .../build-on-casper/introduction/index.html | 17 +- resources/changelog/index.html | 35 + resources/index.html | 12 +- resources/moving-to-casper/index.html | 15 +- resources/quick-start/index.html | 15 +- .../tokens/cep18/full-tutorial/index.html | 27 +- resources/tokens/cep18/query/index.html | 16 +- .../tokens/cep18/quickstart-guide/index.html | 14 +- resources/tokens/cep18/tests/index.html | 14 +- resources/tokens/cep18/transfer/index.html | 12 +- .../tokens/cep78/introduction/index.html | 23 +- resources/tokens/cep78/js-tutorial/index.html | 14 +- resources/tokens/cep78/modalities/index.html | 12 +- .../tokens/cep78/reverse-lookup/index.html | 12 +- .../quickstart-guide/index.html | 47 - .../testing-NFTs/index.html | 33 - resources/tokens/index.html | 12 +- .../tokens/using-casper-client/index.html | 18 +- .../advanced/cross-contract/index.html | 54 +- resources/tutorials/advanced/index.html | 12 +- .../tutorials/advanced/list-cspr/index.html | 18 +- .../return-values-tutorial/index.html | 12 +- .../advanced/storage-workflow/index.html | 14 +- .../transfer-token-to-contract/index.html | 12 +- .../advanced/two-party-multi-sig/index.html | 18 +- .../tutorials/beginner/aws-node/index.html | 12 +- resources/tutorials/beginner/cep18/index.html | 13 +- .../getting-started-tutorial/index.html | 12 +- resources/tutorials/beginner/index.html | 12 +- .../beginner/querying-network/index.html | 12 +- .../beginner/upgrade-contract/index.html | 42 +- runtime/index.html | 70 +- sdk/index.html | 14 +- search/index.html | 8 +- sitemap.xml | 2 +- staking/index.html | 52 - .../index.html | 20 +- .../transactions => transactions}/index.html | 22 +- users/block-explorer/index.html | 14 +- users/csprlive/index.html | 12 +- users/delegate-ui/index.html | 36 +- {next/users => users}/delegating/index.html | 20 +- users/funding-from-exchanges/index.html | 28 +- users/index.html | 19 +- users/ledger/index.html | 12 +- users/ledger/ledger-cspr-live/index.html | 67 +- users/ledger/ledger-live/index.html | 167 +- users/staking-ledger/index.html | 117 +- users/testnet-faucet/index.html | 26 +- users/token-transfer/index.html | 23 +- users/undelegate-ui/index.html | 28 +- workflow/ledger-setup/index.html | 41 +- writing-contracts/index.html | 22 +- 1825 files changed, 34118 insertions(+), 9993 deletions(-) create mode 100644 1.5.X/concepts/accounts-and-keys/index.html create mode 100644 1.5.X/concepts/callstack/index.html create mode 100644 1.5.X/concepts/design/casper-design/index.html create mode 100644 1.5.X/concepts/design/highway/index.html create mode 100644 1.5.X/concepts/design/networking-protocol/index.html create mode 100644 1.5.X/concepts/design/p2p/index.html create mode 100644 1.5.X/concepts/design/reading-and-writing-to-the-blockchain/index.html create mode 100644 1.5.X/concepts/dictionaries/index.html create mode 100644 1.5.X/concepts/economics/concepts/index.html create mode 100644 1.5.X/concepts/economics/consensus/index.html create mode 100644 1.5.X/concepts/economics/delegation/index.html create mode 100644 1.5.X/concepts/economics/gas-concepts/index.html create mode 100644 1.5.X/concepts/global-state/index.html create mode 100644 1.5.X/concepts/glossary/A/index.html create mode 100644 1.5.X/concepts/glossary/B/index.html create mode 100644 1.5.X/concepts/glossary/C/index.html create mode 100644 1.5.X/concepts/glossary/D/index.html create mode 100644 1.5.X/concepts/glossary/E/index.html create mode 100644 1.5.X/concepts/glossary/F/index.html create mode 100644 1.5.X/concepts/glossary/G/index.html create mode 100644 1.5.X/concepts/glossary/H/index.html create mode 100644 1.5.X/concepts/glossary/I/index.html create mode 100644 1.5.X/concepts/glossary/J/index.html create mode 100644 1.5.X/concepts/glossary/K/index.html create mode 100644 1.5.X/concepts/glossary/L/index.html create mode 100644 1.5.X/concepts/glossary/M/index.html create mode 100644 1.5.X/concepts/glossary/N/index.html create mode 100644 1.5.X/concepts/glossary/O/index.html create mode 100644 1.5.X/concepts/glossary/P/index.html create mode 100644 1.5.X/concepts/glossary/Q/index.html create mode 100644 1.5.X/concepts/glossary/R/index.html create mode 100644 1.5.X/concepts/glossary/S/index.html create mode 100644 1.5.X/concepts/glossary/T/index.html create mode 100644 1.5.X/concepts/glossary/U/index.html create mode 100644 1.5.X/concepts/glossary/V/index.html create mode 100644 1.5.X/concepts/glossary/W/index.html create mode 100644 1.5.X/concepts/glossary/X/index.html create mode 100644 1.5.X/concepts/glossary/Y/index.html create mode 100644 1.5.X/concepts/glossary/Z/index.html create mode 100644 1.5.X/concepts/hash-types/index.html create mode 100644 1.5.X/concepts/index.html create mode 100644 1.5.X/concepts/intro-to-dapps/index.html create mode 100644 1.5.X/concepts/list-auth-keys/index.html rename {concepts => 1.5.X/concepts}/serialization-standard/index.html (81%) create mode 100644 1.5.X/concepts/smart-contracts/index.html create mode 100644 1.5.X/counter-testnet/index.html create mode 100644 1.5.X/counter/index.html create mode 100644 1.5.X/deploy-and-deploy-lifecycle/index.html create mode 100644 1.5.X/design/index.html rename {next => 1.5.X}/developers/cli/calling-contracts/index.html (83%) rename {next => 1.5.X}/developers/cli/delegate/index.html (70%) create mode 100644 1.5.X/developers/cli/execution-error-codes/index.html create mode 100644 1.5.X/developers/cli/index.html create mode 100644 1.5.X/developers/cli/installing-contracts/index.html create mode 100644 1.5.X/developers/cli/opcode-costs/index.html create mode 100644 1.5.X/developers/cli/querying-global-state/index.html rename {next => 1.5.X}/developers/cli/redelegate/index.html (55%) rename {developers => 1.5.X/developers}/cli/sending-deploys/index.html (75%) create mode 100644 1.5.X/developers/cli/transfers/direct-token-transfer/index.html create mode 100644 1.5.X/developers/cli/transfers/index.html create mode 100644 1.5.X/developers/cli/transfers/multisig-deploy-transfer/index.html create mode 100644 1.5.X/developers/cli/transfers/verify-transfer/index.html rename {next => 1.5.X}/developers/cli/undelegate/index.html (57%) create mode 100644 1.5.X/developers/dapps/dapp/index.html create mode 100644 1.5.X/developers/dapps/index.html create mode 100644 1.5.X/developers/dapps/monitor-and-consume-events/index.html create mode 100644 1.5.X/developers/dapps/nctl-test/index.html create mode 100644 1.5.X/developers/dapps/prerequisites/index.html create mode 100644 1.5.X/developers/dapps/sdk/client-library-usage/index.html create mode 100644 1.5.X/developers/dapps/sdk/csharp-sdk/index.html create mode 100644 1.5.X/developers/dapps/sdk/go-sdk/index.html create mode 100644 1.5.X/developers/dapps/sdk/python-sdk/index.html rename {next => 1.5.X}/developers/dapps/sdk/script-sdk/index.html (78%) create mode 100644 1.5.X/developers/dapps/setup-nctl/index.html create mode 100644 1.5.X/developers/dapps/signing-a-deploy/index.html create mode 100644 1.5.X/developers/dapps/speculative-exec/index.html create mode 100644 1.5.X/developers/dapps/technology-stack/index.html create mode 100644 1.5.X/developers/dapps/template-frontend/index.html create mode 100644 1.5.X/developers/dapps/uref-security/index.html create mode 100644 1.5.X/developers/essential-crates/index.html create mode 100644 1.5.X/developers/index.html create mode 100644 1.5.X/developers/json-rpc/errors/index.html create mode 100644 1.5.X/developers/json-rpc/guidance/index.html create mode 100644 1.5.X/developers/json-rpc/index.html create mode 100644 1.5.X/developers/json-rpc/json-rpc-informational/index.html create mode 100644 1.5.X/developers/json-rpc/json-rpc-pos/index.html create mode 100644 1.5.X/developers/json-rpc/json-rpc-transactional/index.html create mode 100644 1.5.X/developers/json-rpc/minimal-compliance/index.html create mode 100644 1.5.X/developers/json-rpc/types_chain/index.html create mode 100644 1.5.X/developers/json-rpc/types_cl/index.html create mode 100644 1.5.X/developers/prerequisites/index.html rename {next => 1.5.X}/developers/writing-onchain-code/assembly-script/index.html (65%) create mode 100644 1.5.X/developers/writing-onchain-code/best-practices/index.html create mode 100644 1.5.X/developers/writing-onchain-code/calling-contracts/index.html create mode 100644 1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html create mode 100644 1.5.X/developers/writing-onchain-code/contract-vs-session/index.html create mode 100644 1.5.X/developers/writing-onchain-code/getting-started/index.html create mode 100644 1.5.X/developers/writing-onchain-code/simple-contract/index.html create mode 100644 1.5.X/developers/writing-onchain-code/testing-contracts/index.html create mode 100644 1.5.X/developers/writing-onchain-code/testing-session-code/index.html create mode 100644 1.5.X/developers/writing-onchain-code/upgrading-contracts/index.html create mode 100644 1.5.X/developers/writing-onchain-code/writing-session-code/index.html rename {next => 1.5.X}/disclaimer/index.html (70%) create mode 100644 1.5.X/economics/index.html create mode 100644 1.5.X/glossary/index.html create mode 100644 1.5.X/index.html create mode 100644 1.5.X/operators/becoming-a-validator/bonding/index.html create mode 100644 1.5.X/operators/becoming-a-validator/inactive-vs-faulty/index.html create mode 100644 1.5.X/operators/becoming-a-validator/index.html create mode 100644 1.5.X/operators/becoming-a-validator/recovering/index.html rename {next => 1.5.X}/operators/becoming-a-validator/unbonding/index.html (61%) create mode 100644 1.5.X/operators/index.html rename {next => 1.5.X}/operators/maintenance/archiving-and-restoring/index.html (65%) create mode 100644 1.5.X/operators/maintenance/index.html rename {next => 1.5.X}/operators/maintenance/moving-node/index.html (59%) create mode 100644 1.5.X/operators/setup-network/chain-spec/index.html create mode 100644 1.5.X/operators/setup-network/create-private/index.html create mode 100644 1.5.X/operators/setup-network/genesis/index.html create mode 100644 1.5.X/operators/setup-network/index.html rename {next => 1.5.X}/operators/setup-network/staging-files-for-new-network/index.html (64%) create mode 100644 1.5.X/operators/setup/basic-node-configuration/index.html create mode 100644 1.5.X/operators/setup/fast-sync/index.html create mode 100644 1.5.X/operators/setup/hardware/index.html create mode 100644 1.5.X/operators/setup/index.html rename {next => 1.5.X}/operators/setup/install-node/index.html (69%) rename {next => 1.5.X}/operators/setup/joining/index.html (52%) rename {next => 1.5.X}/operators/setup/node-endpoints/index.html (63%) create mode 100644 1.5.X/operators/setup/non-root-user/index.html rename {next => 1.5.X}/operators/setup/open-files/index.html (58%) create mode 100644 1.5.X/operators/setup/upgrade/index.html rename {next => 1.5.X}/resources/advanced/list-auth-keys-tutorial/index.html (91%) create mode 100644 1.5.X/resources/advanced/multi-sig/index.html create mode 100644 1.5.X/resources/advanced/multi-sig/multi-sig-workflow/index.html rename {next => 1.5.X}/resources/advanced/multi-sig/other-scenarios/index.html (62%) rename {next => 1.5.X}/resources/beginner/counter-testnet/commands/index.html (62%) create mode 100644 1.5.X/resources/beginner/counter-testnet/overview/index.html create mode 100644 1.5.X/resources/beginner/counter-testnet/walkthrough/index.html rename {next => 1.5.X}/resources/beginner/counter/commands/index.html (63%) create mode 100644 1.5.X/resources/beginner/counter/overview/index.html create mode 100644 1.5.X/resources/beginner/counter/walkthrough/index.html create mode 100644 1.5.X/resources/build-on-casper/casper-open-source-software/index.html create mode 100644 1.5.X/resources/build-on-casper/introduction/index.html rename {resources => 1.5.X/resources}/condor-for-exchanges/index.html (70%) create mode 100644 1.5.X/resources/index.html rename {next => 1.5.X}/resources/moving-to-casper/index.html (75%) create mode 100644 1.5.X/resources/quick-start/index.html create mode 100644 1.5.X/resources/tokens/cep18/full-tutorial/index.html create mode 100644 1.5.X/resources/tokens/cep18/query/index.html create mode 100644 1.5.X/resources/tokens/cep18/quickstart-guide/index.html create mode 100644 1.5.X/resources/tokens/cep18/tests/index.html rename {next => 1.5.X}/resources/tokens/cep18/transfer/index.html (81%) create mode 100644 1.5.X/resources/tokens/cep78/introduction/index.html create mode 100644 1.5.X/resources/tokens/cep78/js-tutorial/index.html create mode 100644 1.5.X/resources/tokens/cep78/modalities/index.html create mode 100644 1.5.X/resources/tokens/cep78/reverse-lookup/index.html rename {resources => 1.5.X/resources}/tokens/cep78/using-casper-client/full-installation-tutorial/index.html (90%) rename {resources => 1.5.X/resources}/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html (69%) rename {resources => 1.5.X/resources}/tokens/cep78/using-casper-client/querying-NFTs/index.html (80%) create mode 100644 1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html create mode 100644 1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html create mode 100644 1.5.X/resources/tokens/index.html create mode 100644 1.5.X/resources/tutorials/advanced/cross-contract/index.html create mode 100644 1.5.X/resources/tutorials/advanced/index.html rename {next => 1.5.X}/resources/tutorials/advanced/list-cspr/index.html (83%) rename {next => 1.5.X}/resources/tutorials/advanced/return-values-tutorial/index.html (65%) create mode 100644 1.5.X/resources/tutorials/advanced/storage-workflow/index.html rename {next => 1.5.X}/resources/tutorials/advanced/transfer-token-to-contract/index.html (71%) rename {next => 1.5.X}/resources/tutorials/advanced/two-party-multi-sig/index.html (57%) rename {next => 1.5.X}/resources/tutorials/beginner/aws-node/index.html (60%) create mode 100644 1.5.X/resources/tutorials/beginner/cep18/index.html create mode 100644 1.5.X/resources/tutorials/beginner/getting-started-tutorial/index.html create mode 100644 1.5.X/resources/tutorials/beginner/index.html rename {next => 1.5.X}/resources/tutorials/beginner/querying-network/index.html (77%) create mode 100644 1.5.X/resources/tutorials/beginner/upgrade-contract/index.html create mode 100644 1.5.X/runtime/index.html create mode 100644 1.5.X/sdk/index.html create mode 100644 1.5.X/staking/index.html create mode 100644 1.5.X/users/block-explorer/index.html create mode 100644 1.5.X/users/csprlive/index.html create mode 100644 1.5.X/users/delegate-ui/index.html create mode 100644 1.5.X/users/funding-from-exchanges/index.html create mode 100644 1.5.X/users/index.html create mode 100644 1.5.X/users/ledger/index.html create mode 100644 1.5.X/users/ledger/ledger-cspr-live/index.html create mode 100644 1.5.X/users/ledger/ledger-live/index.html create mode 100644 1.5.X/users/staking-ledger/index.html create mode 100644 1.5.X/users/testnet-faucet/index.html create mode 100644 1.5.X/users/token-transfer/index.html create mode 100644 1.5.X/users/undelegate-ui/index.html create mode 100644 1.5.X/workflow/ledger-setup/index.html create mode 100644 1.5.X/writing-contracts/index.html create mode 100644 2.0.0/concepts/about/index.html rename {next => 2.0.0}/concepts/accounts-and-keys/index.html (75%) create mode 100644 2.0.0/concepts/addressable-entity/index.html create mode 100644 2.0.0/concepts/callstack/index.html rename {next => 2.0.0}/concepts/design/casper-design/index.html (60%) create mode 100644 2.0.0/concepts/design/consensus/index.html create mode 100644 2.0.0/concepts/design/highway/index.html rename {next => 2.0.0}/concepts/design/networking-protocol/index.html (93%) create mode 100644 2.0.0/concepts/design/p2p/index.html create mode 100644 2.0.0/concepts/design/reading-and-writing-to-the-blockchain/index.html rename {next => 2.0.0}/concepts/design/rewards/index.html (53%) rename {next => 2.0.0}/concepts/design/zug/index.html (58%) rename {next => 2.0.0}/concepts/dictionaries/index.html (70%) create mode 100644 2.0.0/concepts/economics/consensus/index.html create mode 100644 2.0.0/concepts/economics/dynamic-gas-pricing/index.html create mode 100644 2.0.0/concepts/economics/fee-elimination/index.html create mode 100644 2.0.0/concepts/economics/gas-concepts/index.html create mode 100644 2.0.0/concepts/economics/staking/index.html create mode 100644 2.0.0/concepts/global-state/index.html create mode 100644 2.0.0/concepts/glossary/A/index.html create mode 100644 2.0.0/concepts/glossary/B/index.html create mode 100644 2.0.0/concepts/glossary/C/index.html create mode 100644 2.0.0/concepts/glossary/D/index.html create mode 100644 2.0.0/concepts/glossary/E/index.html create mode 100644 2.0.0/concepts/glossary/F/index.html create mode 100644 2.0.0/concepts/glossary/G/index.html create mode 100644 2.0.0/concepts/glossary/H/index.html create mode 100644 2.0.0/concepts/glossary/I/index.html create mode 100644 2.0.0/concepts/glossary/J/index.html create mode 100644 2.0.0/concepts/glossary/K/index.html create mode 100644 2.0.0/concepts/glossary/L/index.html create mode 100644 2.0.0/concepts/glossary/M/index.html create mode 100644 2.0.0/concepts/glossary/N/index.html create mode 100644 2.0.0/concepts/glossary/O/index.html create mode 100644 2.0.0/concepts/glossary/P/index.html create mode 100644 2.0.0/concepts/glossary/Q/index.html create mode 100644 2.0.0/concepts/glossary/R/index.html create mode 100644 2.0.0/concepts/glossary/S/index.html create mode 100644 2.0.0/concepts/glossary/T/index.html create mode 100644 2.0.0/concepts/glossary/U/index.html create mode 100644 2.0.0/concepts/glossary/V/index.html create mode 100644 2.0.0/concepts/glossary/W/index.html create mode 100644 2.0.0/concepts/glossary/X/index.html create mode 100644 2.0.0/concepts/glossary/Y/index.html create mode 100644 2.0.0/concepts/glossary/Z/index.html create mode 100644 2.0.0/concepts/index.html create mode 100644 2.0.0/concepts/intro-to-dapps/index.html create mode 100644 2.0.0/concepts/key-types/index.html create mode 100644 2.0.0/concepts/list-auth-keys/index.html create mode 100644 2.0.0/concepts/serialization/index.html create mode 100644 2.0.0/concepts/serialization/primitives/index.html rename {next => 2.0.0}/concepts/serialization/structures/index.html (57%) create mode 100644 2.0.0/concepts/serialization/types/index.html create mode 100644 2.0.0/concepts/smart-contracts/index.html create mode 100644 2.0.0/counter-testnet/index.html create mode 100644 2.0.0/counter/index.html create mode 100644 2.0.0/design/index.html create mode 100644 2.0.0/developers/cli/calling-contracts/index.html create mode 100644 2.0.0/developers/cli/delegate/index.html create mode 100644 2.0.0/developers/cli/execution-error-codes/index.html create mode 100644 2.0.0/developers/cli/index.html rename {next => 2.0.0}/developers/cli/installing-contracts/index.html (79%) rename {next => 2.0.0}/developers/cli/opcode-costs/index.html (52%) rename {next => 2.0.0}/developers/cli/querying-global-state/index.html (81%) create mode 100644 2.0.0/developers/cli/redelegate/index.html create mode 100644 2.0.0/developers/cli/sending-transactions/index.html rename {next => 2.0.0}/developers/cli/transfers/direct-token-transfer/index.html (81%) create mode 100644 2.0.0/developers/cli/transfers/index.html rename {next => 2.0.0}/developers/cli/transfers/multisig-deploy-transfer/index.html (69%) rename {next => 2.0.0}/developers/cli/transfers/verify-transfer/index.html (79%) create mode 100644 2.0.0/developers/cli/undelegate/index.html create mode 100644 2.0.0/developers/cli/verifying-contracts/index.html create mode 100644 2.0.0/developers/dapps/dapp/index.html create mode 100644 2.0.0/developers/dapps/index.html rename {next => 2.0.0}/developers/dapps/monitor-and-consume-events/index.html (68%) rename {next => 2.0.0}/developers/dapps/nctl-test/index.html (61%) create mode 100644 2.0.0/developers/dapps/prerequisites/index.html rename {next => 2.0.0}/developers/dapps/sdk/client-library-usage/index.html (92%) create mode 100644 2.0.0/developers/dapps/sdk/csharp-sdk/index.html rename {next => 2.0.0}/developers/dapps/sdk/go-sdk/index.html (72%) rename {next => 2.0.0}/developers/dapps/sdk/python-sdk/index.html (81%) create mode 100644 2.0.0/developers/dapps/sdk/script-sdk/index.html rename {next => 2.0.0}/developers/dapps/setup-nctl/index.html (71%) create mode 100644 2.0.0/developers/dapps/signing-a-transaction/index.html create mode 100644 2.0.0/developers/dapps/speculative-exec/index.html create mode 100644 2.0.0/developers/dapps/technology-stack/index.html rename {next => 2.0.0}/developers/dapps/template-frontend/index.html (90%) rename {next => 2.0.0}/developers/dapps/uref-security/index.html (56%) create mode 100644 2.0.0/developers/essential-crates/index.html create mode 100644 2.0.0/developers/index.html create mode 100644 2.0.0/developers/json-rpc/errors/index.html create mode 100644 2.0.0/developers/json-rpc/guidance/index.html create mode 100644 2.0.0/developers/json-rpc/index.html rename {next => 2.0.0}/developers/json-rpc/json-rpc-informational/index.html (85%) rename {next => 2.0.0}/developers/json-rpc/json-rpc-pos/index.html (66%) rename {next => 2.0.0}/developers/json-rpc/json-rpc-transactional/index.html (91%) create mode 100644 2.0.0/developers/json-rpc/minimal-compliance/index.html rename {next => 2.0.0}/developers/json-rpc/types_chain/index.html (76%) create mode 100644 2.0.0/developers/json-rpc/types_cl/index.html rename {next => 2.0.0}/developers/prerequisites/index.html (74%) create mode 100644 2.0.0/developers/writing-onchain-code/assembly-script/index.html rename {next => 2.0.0}/developers/writing-onchain-code/best-practices/index.html (56%) create mode 100644 2.0.0/developers/writing-onchain-code/calling-contracts/index.html rename {next => 2.0.0}/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html (50%) create mode 100644 2.0.0/developers/writing-onchain-code/contract-vs-session/index.html create mode 100644 2.0.0/developers/writing-onchain-code/emitting-contract-events/index.html create mode 100644 2.0.0/developers/writing-onchain-code/factory-pattern/index.html rename {next => 2.0.0}/developers/writing-onchain-code/getting-started/index.html (57%) rename {next => 2.0.0}/developers/writing-onchain-code/simple-contract/index.html (85%) rename {next => 2.0.0}/developers/writing-onchain-code/testing-contracts/index.html (79%) rename {next => 2.0.0}/developers/writing-onchain-code/testing-session-code/index.html (75%) create mode 100644 2.0.0/developers/writing-onchain-code/upgrading-contracts/index.html rename {next => 2.0.0}/developers/writing-onchain-code/writing-session-code/index.html (71%) create mode 100644 2.0.0/disclaimer/index.html create mode 100644 2.0.0/economics/index.html create mode 100644 2.0.0/glossary/index.html create mode 100644 2.0.0/index.html rename {next => 2.0.0}/operators/becoming-a-validator/bonding/index.html (75%) create mode 100644 2.0.0/operators/becoming-a-validator/change-bid-public-key/index.html create mode 100644 2.0.0/operators/becoming-a-validator/inactive-vs-faulty/index.html create mode 100644 2.0.0/operators/becoming-a-validator/index.html rename {next => 2.0.0}/operators/becoming-a-validator/recovering/index.html (63%) create mode 100644 2.0.0/operators/becoming-a-validator/unbonding/index.html create mode 100644 2.0.0/operators/index.html create mode 100644 2.0.0/operators/maintenance/archiving-and-restoring/index.html create mode 100644 2.0.0/operators/maintenance/index.html create mode 100644 2.0.0/operators/maintenance/moving-node/index.html rename {next => 2.0.0}/operators/setup-network/chain-spec/index.html (68%) rename {next => 2.0.0}/operators/setup-network/create-private/index.html (78%) create mode 100644 2.0.0/operators/setup-network/genesis/index.html create mode 100644 2.0.0/operators/setup-network/index.html create mode 100644 2.0.0/operators/setup-network/staging-files-for-new-network/index.html rename {next => 2.0.0}/operators/setup/basic-node-configuration/index.html (67%) create mode 100644 2.0.0/operators/setup/casper-sidecar/index.html create mode 100644 2.0.0/operators/setup/fast-sync/index.html create mode 100644 2.0.0/operators/setup/hardware/index.html create mode 100644 2.0.0/operators/setup/index.html create mode 100644 2.0.0/operators/setup/install-node/index.html create mode 100644 2.0.0/operators/setup/joining/index.html create mode 100644 2.0.0/operators/setup/node-endpoints/index.html create mode 100644 2.0.0/operators/setup/node-events/index.html create mode 100644 2.0.0/operators/setup/non-root-user/index.html create mode 100644 2.0.0/operators/setup/open-files/index.html create mode 100644 2.0.0/operators/setup/upgrade/index.html create mode 100644 2.0.0/resources/advanced/list-auth-keys-tutorial/index.html create mode 100644 2.0.0/resources/advanced/multi-sig/index.html rename {next => 2.0.0}/resources/advanced/multi-sig/multi-sig-workflow/index.html (82%) create mode 100644 2.0.0/resources/advanced/multi-sig/other-scenarios/index.html create mode 100644 2.0.0/resources/beginner/counter-testnet/commands/index.html create mode 100644 2.0.0/resources/beginner/counter-testnet/overview/index.html rename {next => 2.0.0}/resources/beginner/counter-testnet/walkthrough/index.html (71%) create mode 100644 2.0.0/resources/beginner/counter/commands/index.html create mode 100644 2.0.0/resources/beginner/counter/overview/index.html rename {next => 2.0.0}/resources/beginner/counter/walkthrough/index.html (71%) rename {next => 2.0.0}/resources/build-on-casper/casper-open-source-software/index.html (64%) create mode 100644 2.0.0/resources/build-on-casper/introduction/index.html create mode 100644 2.0.0/resources/changelog/index.html create mode 100644 2.0.0/resources/index.html create mode 100644 2.0.0/resources/moving-to-casper/index.html rename {next => 2.0.0}/resources/quick-start/index.html (72%) rename {next => 2.0.0}/resources/tokens/cep18/full-tutorial/index.html (86%) rename {next => 2.0.0}/resources/tokens/cep18/query/index.html (62%) create mode 100644 2.0.0/resources/tokens/cep18/quickstart-guide/index.html rename {next => 2.0.0}/resources/tokens/cep18/tests/index.html (89%) create mode 100644 2.0.0/resources/tokens/cep18/transfer/index.html rename {next => 2.0.0}/resources/tokens/cep78/introduction/index.html (56%) rename {next => 2.0.0}/resources/tokens/cep78/js-tutorial/index.html (77%) rename {next => 2.0.0}/resources/tokens/cep78/modalities/index.html (68%) create mode 100644 2.0.0/resources/tokens/cep78/reverse-lookup/index.html create mode 100644 2.0.0/resources/tokens/index.html create mode 100644 2.0.0/resources/tokens/using-casper-client/index.html rename {next => 2.0.0}/resources/tutorials/advanced/cross-contract/index.html (90%) create mode 100644 2.0.0/resources/tutorials/advanced/index.html create mode 100644 2.0.0/resources/tutorials/advanced/list-cspr/index.html create mode 100644 2.0.0/resources/tutorials/advanced/return-values-tutorial/index.html rename {next => 2.0.0}/resources/tutorials/advanced/storage-workflow/index.html (64%) create mode 100644 2.0.0/resources/tutorials/advanced/transfer-token-to-contract/index.html create mode 100644 2.0.0/resources/tutorials/advanced/two-party-multi-sig/index.html create mode 100644 2.0.0/resources/tutorials/beginner/aws-node/index.html rename {next => 2.0.0}/resources/tutorials/beginner/cep18/index.html (72%) create mode 100644 2.0.0/resources/tutorials/beginner/getting-started-tutorial/index.html create mode 100644 2.0.0/resources/tutorials/beginner/index.html create mode 100644 2.0.0/resources/tutorials/beginner/querying-network/index.html rename {next => 2.0.0}/resources/tutorials/beginner/upgrade-contract/index.html (84%) create mode 100644 2.0.0/runtime/index.html create mode 100644 2.0.0/sdk/index.html create mode 100644 2.0.0/transactions-and-transaction-lifecycle/index.html create mode 100644 2.0.0/transactions/index.html create mode 100644 2.0.0/users/block-explorer/index.html create mode 100644 2.0.0/users/csprlive/index.html create mode 100644 2.0.0/users/delegate-ui/index.html create mode 100644 2.0.0/users/delegating/index.html create mode 100644 2.0.0/users/funding-from-exchanges/index.html create mode 100644 2.0.0/users/index.html create mode 100644 2.0.0/users/ledger/index.html rename {next => 2.0.0}/users/ledger/ledger-cspr-live/index.html (51%) rename {next => 2.0.0}/users/ledger/ledger-live/index.html (57%) rename {next => 2.0.0}/users/staking-ledger/index.html (51%) create mode 100644 2.0.0/users/testnet-faucet/index.html create mode 100644 2.0.0/users/token-transfer/index.html create mode 100644 2.0.0/users/undelegate-ui/index.html create mode 100644 2.0.0/workflow/ledger-setup/index.html create mode 100644 2.0.0/writing-contracts/index.html delete mode 100644 CNAME create mode 100644 assets/js/00935d0c.4467c113.js create mode 100644 assets/js/017e616b.8ebc0779.js create mode 100644 assets/js/01be152e.b1fca991.js create mode 100644 assets/js/01db17fe.4fe78b51.js create mode 100644 assets/js/02627fb8.7d16ba66.js create mode 100644 assets/js/028247bf.b7389543.js delete mode 100644 assets/js/028247bf.e22beb61.js delete mode 100644 assets/js/03aa8e23.0a426846.js create mode 100644 assets/js/03aa8e23.2c61f65f.js create mode 100644 assets/js/03acd2fb.9a8b2e6c.js delete mode 100644 assets/js/03acd2fb.d5a0a15f.js create mode 100644 assets/js/03c6d9c7.4f0c8d42.js delete mode 100644 assets/js/03c6d9c7.c792cbe5.js delete mode 100644 assets/js/044f7961.5f1b0a68.js create mode 100644 assets/js/044f7961.a5cca8cf.js create mode 100644 assets/js/04a0dcd6.f1fd239f.js delete mode 100644 assets/js/04f8200d.35a20847.js create mode 100644 assets/js/04f8200d.5228b822.js create mode 100644 assets/js/051b98e7.8a9171cd.js delete mode 100644 assets/js/053d5d89.4f1b46a0.js create mode 100644 assets/js/053d5d89.4f2907f5.js create mode 100644 assets/js/056155c0.abd058a6.js create mode 100644 assets/js/05a3aa78.7bddfc8e.js delete mode 100644 assets/js/05a3aa78.baa762b5.js create mode 100644 assets/js/06c1e821.b8aa7d80.js delete mode 100644 assets/js/06c1e821.b9348323.js create mode 100644 assets/js/074e7bdc.1512fa35.js delete mode 100644 assets/js/074e7bdc.4eb0678a.js delete mode 100644 assets/js/0753c93f.38bf38b5.js create mode 100644 assets/js/0753c93f.c3fc9760.js delete mode 100644 assets/js/0791978c.6cb20991.js create mode 100644 assets/js/0791978c.8b8ea331.js delete mode 100644 assets/js/08996e66.378c3d02.js create mode 100644 assets/js/08996e66.45d2a303.js create mode 100644 assets/js/08af526d.864924c4.js delete mode 100644 assets/js/08af526d.cefb371d.js delete mode 100644 assets/js/0904ce24.59e4ae24.js create mode 100644 assets/js/0904ce24.a293aebe.js create mode 100644 assets/js/09278318.4b956a66.js create mode 100644 assets/js/094b4aff.6cc550cf.js delete mode 100644 assets/js/0ac4e675.ee46eb79.js create mode 100644 assets/js/0ac4e675.f7475e94.js create mode 100644 assets/js/0ae07240.2f1af85d.js create mode 100644 assets/js/0b20c33e.4baa51ac.js create mode 100644 assets/js/0b3fc8e9.ce7a5cab.js create mode 100644 assets/js/0b8cc739.11d60f3d.js delete mode 100644 assets/js/0b8cc739.79de13f9.js delete mode 100644 assets/js/0bb2dbe9.0880aaaf.js create mode 100644 assets/js/0bb2dbe9.25561148.js create mode 100644 assets/js/0bd3b317.a7a76776.js delete mode 100644 assets/js/0bd3b317.d740e1e1.js delete mode 100644 assets/js/0c098c15.5f193e57.js create mode 100644 assets/js/0c098c15.9fdd6a6d.js create mode 100644 assets/js/0cde4ba3.766b9399.js delete mode 100644 assets/js/0cde4ba3.db3b01f2.js create mode 100644 assets/js/0dea8207.469d8eba.js delete mode 100644 assets/js/0dea8207.4f27fd0b.js create mode 100644 assets/js/0fa7e001.d0182770.js delete mode 100644 assets/js/106a38e1.01a8cfcd.js create mode 100644 assets/js/106a38e1.08a834c1.js create mode 100644 assets/js/106b67a5.5be98423.js delete mode 100644 assets/js/106b67a5.9d743cdc.js create mode 100644 assets/js/10ab4195.ee7630a9.js create mode 100644 assets/js/10dd5949.d7da3af3.js create mode 100644 assets/js/116fa82a.4ab1633b.js delete mode 100644 assets/js/116fa82a.7fdfa28d.js delete mode 100644 assets/js/124873a8.3f86c852.js create mode 100644 assets/js/124873a8.ea47be98.js create mode 100644 assets/js/12984b65.704e4746.js create mode 100644 assets/js/12e95288.283682c6.js delete mode 100644 assets/js/12e95288.dcfe96df.js delete mode 100644 assets/js/130631d9.473508f7.js create mode 100644 assets/js/130631d9.5fa36173.js create mode 100644 assets/js/134a9ec2.0ccdf24e.js delete mode 100644 assets/js/134a9ec2.a9986cfa.js create mode 100644 assets/js/13f7cbc7.8e07b7af.js delete mode 100644 assets/js/14620e15.210101ba.js create mode 100644 assets/js/14620e15.e55ff3e7.js delete mode 100644 assets/js/1494.44935779.js create mode 100644 assets/js/157e4bc2.7b9ed566.js delete mode 100644 assets/js/157e4bc2.eba0692b.js create mode 100644 assets/js/158765df.0818e83f.js create mode 100644 assets/js/15ce11b3.3da7da11.js delete mode 100644 assets/js/15ce11b3.dca58b4c.js create mode 100644 assets/js/168da062.e84c3ca9.js delete mode 100644 assets/js/168da062.f79ac659.js create mode 100644 assets/js/175e85c1.ae48dd54.js create mode 100644 assets/js/17896441.a80fb57c.js delete mode 100644 assets/js/17896441.e301f0ef.js create mode 100644 assets/js/1871ac35.4fb85a4c.js delete mode 100644 assets/js/1871ac35.c8a05ff4.js create mode 100644 assets/js/18b84202.39914aaa.js create mode 100644 assets/js/1966dde1.2677b260.js create mode 100644 assets/js/197196c4.10c851c2.js delete mode 100644 assets/js/197196c4.af135d1b.js delete mode 100644 assets/js/19770ceb.8387e9e3.js create mode 100644 assets/js/19770ceb.85de565a.js rename assets/js/{3fe76c6c.fdefcb5a.js => 19b85f8d.9543118f.js} (67%) create mode 100644 assets/js/1a4e3797.87166043.js rename assets/js/{1a4e3797.db7f4d3c.js.LICENSE.txt => 1a4e3797.87166043.js.LICENSE.txt} (100%) delete mode 100644 assets/js/1a4e3797.db7f4d3c.js create mode 100644 assets/js/1b0eecbc.03a68f28.js delete mode 100644 assets/js/1b0eecbc.35fe077e.js create mode 100644 assets/js/1b2f0a70.1f2d7217.js delete mode 100644 assets/js/1b2f0a70.d99e2656.js create mode 100644 assets/js/1b312e15.3da2e07f.js create mode 100644 assets/js/1c694ffb.e2c21c8e.js delete mode 100644 assets/js/1c694ffb.eb41d9b2.js create mode 100644 assets/js/1cd8ca26.cbdbeb37.js create mode 100644 assets/js/1e144f6d.3fce115e.js delete mode 100644 assets/js/1e144f6d.846df292.js create mode 100644 assets/js/1e2c8091.780b66ed.js create mode 100644 assets/js/202767e6.650f5669.js delete mode 100644 assets/js/202767e6.662bbd94.js create mode 100644 assets/js/2063472f.3db4a69b.js delete mode 100644 assets/js/2063472f.f81204a0.js create mode 100644 assets/js/20e65df1.58813634.js delete mode 100644 assets/js/20f436ec.0bdc9c76.js create mode 100644 assets/js/20f436ec.d9cf2a40.js delete mode 100644 assets/js/212aab5d.1a701a70.js create mode 100644 assets/js/212aab5d.5eef133e.js delete mode 100644 assets/js/21ae0e7e.0ab591f6.js create mode 100644 assets/js/21ae0e7e.b7e7da29.js create mode 100644 assets/js/21d2c26c.34fe9668.js delete mode 100644 assets/js/2237.2be052d4.js delete mode 100644 assets/js/22dd74f7.d59e4fd6.js create mode 100644 assets/js/22dd74f7.e428a829.js create mode 100644 assets/js/236eb0f0.5852e7f6.js delete mode 100644 assets/js/236eb0f0.ea22eadd.js delete mode 100644 assets/js/23e022aa.6c773674.js create mode 100644 assets/js/23e022aa.9f08479d.js create mode 100644 assets/js/241648bf.39c48090.js delete mode 100644 assets/js/241648bf.5946a39a.js create mode 100644 assets/js/241f36ed.20e39934.js create mode 100644 assets/js/24433f15.4be389a9.js delete mode 100644 assets/js/25f19435.e9c61eb7.js create mode 100644 assets/js/25f19435.f0517f89.js delete mode 100644 assets/js/261dbd4a.690860d0.js create mode 100644 assets/js/261dbd4a.98bcfe9f.js delete mode 100644 assets/js/2668f34f.81895d61.js create mode 100644 assets/js/2668f34f.8cbf8a64.js create mode 100644 assets/js/26a33332.6303f856.js delete mode 100644 assets/js/26a33332.9159dc58.js create mode 100644 assets/js/26ab9a7a.06a0c1d8.js delete mode 100644 assets/js/26f7e8fd.759ba063.js create mode 100644 assets/js/26f7e8fd.9da42033.js create mode 100644 assets/js/277b6be0.0f968348.js delete mode 100644 assets/js/277b6be0.6924c872.js create mode 100644 assets/js/280f0f40.42bc3e47.js create mode 100644 assets/js/285c66e7.2cc1f187.js rename assets/js/{28b5b925.0168630d.js => 28b5b925.0cbd1f9b.js} (57%) create mode 100644 assets/js/28bc9864.246d5f11.js delete mode 100644 assets/js/28bc9864.9af5621d.js create mode 100644 assets/js/2a21571b.eb912000.js create mode 100644 assets/js/2ac03470.9c632600.js create mode 100644 assets/js/2b8e251b.baf2f328.js delete mode 100644 assets/js/2b8e251b.f0bf2b40.js create mode 100644 assets/js/2bd0ed90.2b52c78d.js delete mode 100644 assets/js/2bd0ed90.42d1714b.js create mode 100644 assets/js/2c04116d.a32622f9.js delete mode 100644 assets/js/2c04116d.e52985c2.js delete mode 100644 assets/js/2c27a7b4.6fa37b9d.js create mode 100644 assets/js/2c27a7b4.dfdad9af.js delete mode 100644 assets/js/2cb8ed3d.81fd42ba.js create mode 100644 assets/js/2cb8ed3d.cd46c6fa.js create mode 100644 assets/js/2cc4f81c.309d1501.js delete mode 100644 assets/js/2cc4f81c.f99f6439.js create mode 100644 assets/js/2d971abe.1121b1e3.js delete mode 100644 assets/js/2d971abe.26e71149.js create mode 100644 assets/js/2e4bdb60.94cd32d7.js delete mode 100644 assets/js/2e4bdb60.fa0d0d8f.js delete mode 100644 assets/js/2fb5589e.18083c1f.js create mode 100644 assets/js/2fb5589e.7b8c9375.js create mode 100644 assets/js/2fe2b30f.134c1dc9.js create mode 100644 assets/js/2ffce966.32a561e7.js delete mode 100644 assets/js/2ffce966.af34eb97.js create mode 100644 assets/js/31722bc4.8b17745a.js delete mode 100644 assets/js/31722bc4.9f4ab15b.js create mode 100644 assets/js/31dbaea7.4f18e31a.js delete mode 100644 assets/js/31dbaea7.cb2ad24d.js create mode 100644 assets/js/31e8518f.78747659.js delete mode 100644 assets/js/32dd135c.20dd4de8.js create mode 100644 assets/js/32dd135c.45237611.js create mode 100644 assets/js/331badc5.26951b81.js delete mode 100644 assets/js/331badc5.a0e388dd.js delete mode 100644 assets/js/3362155c.196ff25b.js create mode 100644 assets/js/3362155c.2951497f.js create mode 100644 assets/js/33a9c3bd.2116c2c6.js delete mode 100644 assets/js/33a9c3bd.3a1f4799.js create mode 100644 assets/js/33fc5bb8.1380a971.js delete mode 100644 assets/js/33fc5bb8.4b577c2a.js delete mode 100644 assets/js/340c2365.a24dd798.js create mode 100644 assets/js/340c2365.f9fb5495.js create mode 100644 assets/js/34b086e1.d56022ae.js delete mode 100644 assets/js/34b086e1.d5c23182.js delete mode 100644 assets/js/35808b61.27d7ec33.js create mode 100644 assets/js/35808b61.5e787011.js delete mode 100644 assets/js/358cf6da.1b3e0934.js create mode 100644 assets/js/358cf6da.50a774a3.js delete mode 100644 assets/js/35a4f7b3.e6576d4a.js create mode 100644 assets/js/35a4f7b3.f6ca0fad.js create mode 100644 assets/js/3619739c.59a850b5.js delete mode 100644 assets/js/3619739c.88978e27.js delete mode 100644 assets/js/362368d5.3185e36c.js create mode 100644 assets/js/362368d5.b933ef02.js delete mode 100644 assets/js/3669623c.858e4657.js create mode 100644 assets/js/3669623c.b2f466b1.js delete mode 100644 assets/js/36994c47.31271808.js create mode 100644 assets/js/36994c47.ce48ef1d.js create mode 100644 assets/js/3724f9ed.5eafca9c.js delete mode 100644 assets/js/3724f9ed.c1aaf3d4.js create mode 100644 assets/js/372c0574.041c94fa.js delete mode 100644 assets/js/381391cb.1c3e00bf.js create mode 100644 assets/js/381391cb.289be185.js delete mode 100644 assets/js/38296185.1abf2f2d.js create mode 100644 assets/js/38296185.4a41b532.js create mode 100644 assets/js/387aabc2.5dc9fb8c.js create mode 100644 assets/js/38b4dbd3.7e645026.js delete mode 100644 assets/js/38b4dbd3.bdc4f617.js create mode 100644 assets/js/38ff73e5.a2c2ca1e.js create mode 100644 assets/js/396a697c.6fa30002.js create mode 100644 assets/js/398cf21c.1c69896e.js delete mode 100644 assets/js/398cf21c.db34c60d.js create mode 100644 assets/js/39ac5a41.0cb58650.js delete mode 100644 assets/js/39ac5a41.6476776a.js create mode 100644 assets/js/3a19cb34.19cbf1ee.js delete mode 100644 assets/js/3a5d5492.554dd0cb.js create mode 100644 assets/js/3a5d5492.d650666a.js create mode 100644 assets/js/3a98aaad.38c11bd1.js create mode 100644 assets/js/3a9d2720.81ccdd66.js delete mode 100644 assets/js/3a9d2720.e34e9dc9.js create mode 100644 assets/js/3aa29420.3264772a.js delete mode 100644 assets/js/3aa29420.a18fd86b.js delete mode 100644 assets/js/3aaf2bfb.7183a894.js create mode 100644 assets/js/3aaf2bfb.b2e73a42.js create mode 100644 assets/js/3ac85609.12ab7143.js delete mode 100644 assets/js/3ac85609.db0b618c.js create mode 100644 assets/js/3b749ca6.12e4a5ed.js delete mode 100644 assets/js/3b749ca6.2b2c6cde.js delete mode 100644 assets/js/3b86d751.8b6804b4.js create mode 100644 assets/js/3b86d751.aaac82d9.js delete mode 100644 assets/js/3bf1ce3c.4be36f8e.js create mode 100644 assets/js/3bf1ce3c.e158e2c3.js create mode 100644 assets/js/3c9a8a22.cbde2a2a.js create mode 100644 assets/js/3ce1a06b.08bdbb80.js delete mode 100644 assets/js/3ce1a06b.211c5901.js create mode 100644 assets/js/3d262e04.8ce8efde.js create mode 100644 assets/js/3d90f760.85ca88d2.js delete mode 100644 assets/js/3d90f760.a5aed92d.js create mode 100644 assets/js/3d9ade7d.23253525.js create mode 100644 assets/js/3db2ed27.9501e9bc.js create mode 100644 assets/js/3e796ac9.77cf76db.js delete mode 100644 assets/js/3e796ac9.d85b7445.js create mode 100644 assets/js/3efe71e8.3d46f3c7.js delete mode 100644 assets/js/3efe71e8.65395bbf.js create mode 100644 assets/js/3fe76c6c.09dd3645.js create mode 100644 assets/js/40078125.92fe6e66.js delete mode 100644 assets/js/40078125.bd3a3d60.js delete mode 100644 assets/js/40c07125.9be41738.js create mode 100644 assets/js/40c07125.b0d71ef3.js create mode 100644 assets/js/411a45a4.bfced875.js create mode 100644 assets/js/41905acb.2fa671b8.js delete mode 100644 assets/js/41905acb.9b219f55.js delete mode 100644 assets/js/41e7d56e.2064be67.js create mode 100644 assets/js/41e7d56e.3c81128b.js create mode 100644 assets/js/41eb5a6a.25e46683.js delete mode 100644 assets/js/41eb5a6a.432785b3.js create mode 100644 assets/js/42744730.53821c1f.js create mode 100644 assets/js/433fdaab.7d8c5d7c.js delete mode 100644 assets/js/43a834ef.022fd866.js create mode 100644 assets/js/43a834ef.36ed403d.js delete mode 100644 assets/js/43fd3112.179a51de.js create mode 100644 assets/js/43fd3112.e7439ebf.js delete mode 100644 assets/js/4423d65b.01606f7a.js create mode 100644 assets/js/4423d65b.43623fa8.js delete mode 100644 assets/js/449bc0d9.5dd63daf.js create mode 100644 assets/js/449bc0d9.ed4526e9.js create mode 100644 assets/js/452e65d7.1de256df.js delete mode 100644 assets/js/452e65d7.cb4a29c5.js delete mode 100644 assets/js/4545390c.0ca5f8dc.js create mode 100644 assets/js/4545390c.1d3a08c0.js delete mode 100644 assets/js/459c4db6.2d3b0e56.js create mode 100644 assets/js/459c4db6.5ba5952e.js create mode 100644 assets/js/46206018.718b2b19.js delete mode 100644 assets/js/46c04ff3.0ad52045.js create mode 100644 assets/js/46c04ff3.202aa580.js create mode 100644 assets/js/46e94768.dab245b0.js delete mode 100644 assets/js/46e94768.e7996bf8.js delete mode 100644 assets/js/471ca6e4.a462efc0.js create mode 100644 assets/js/471ca6e4.fc8efafc.js create mode 100644 assets/js/4732c0e2.3853b69c.js create mode 100644 assets/js/473a077c.eb7aa5a0.js delete mode 100644 assets/js/4804492c.1872c747.js create mode 100644 assets/js/4804492c.9bff2638.js create mode 100644 assets/js/480fa8f7.75e26ad2.js delete mode 100644 assets/js/480fa8f7.d7f8bb82.js delete mode 100644 assets/js/481163ce.aa41f256.js create mode 100644 assets/js/481163ce.cef26660.js delete mode 100644 assets/js/4832c6fe.1c554d77.js create mode 100644 assets/js/4832c6fe.829d1c30.js create mode 100644 assets/js/4a522ab0.74a2f484.js create mode 100644 assets/js/4ab63648.4c995b82.js delete mode 100644 assets/js/4ab63648.80eee16a.js create mode 100644 assets/js/4ba3ceff.081c4b34.js delete mode 100644 assets/js/4ba3ceff.df7f2c6a.js create mode 100644 assets/js/4bf77031.6626d6ed.js create mode 100644 assets/js/4c91363f.93a6ede3.js delete mode 100644 assets/js/4c91363f.d784b1bc.js create mode 100644 assets/js/4cc44e19.7d979e88.js delete mode 100644 assets/js/4cc75cd6.34166208.js create mode 100644 assets/js/4cc75cd6.c5db8ce8.js create mode 100644 assets/js/4d118a4e.26672722.js delete mode 100644 assets/js/4d118a4e.fd0876b0.js create mode 100644 assets/js/4d355c12.2357dd50.js create mode 100644 assets/js/4d4c05c4.06123333.js create mode 100644 assets/js/4db682c6.25cb8a9e.js delete mode 100644 assets/js/4db682c6.c730ac08.js create mode 100644 assets/js/4e015808.64ad3dfe.js delete mode 100644 assets/js/4e015808.a485ffdf.js create mode 100644 assets/js/4e4df367.6b2bf3f2.js delete mode 100644 assets/js/4e4df367.d91fcd1d.js delete mode 100644 assets/js/4e8b7bcc.034fae29.js create mode 100644 assets/js/4e8b7bcc.d320f421.js create mode 100644 assets/js/4ed7ac06.e7cc3604.js delete mode 100644 assets/js/4fdb6df3.2cd2adde.js create mode 100644 assets/js/4fdb6df3.3ae7fba2.js create mode 100644 assets/js/5052751d.2ecba4e7.js delete mode 100644 assets/js/5052751d.e6a325fc.js create mode 100644 assets/js/50c21d96.c39e8686.js create mode 100644 assets/js/5109d3ad.4be6508a.js delete mode 100644 assets/js/5109d3ad.b642a8c5.js create mode 100644 assets/js/5168ee15.9f3c0d6d.js delete mode 100644 assets/js/51719dea.6107622a.js create mode 100644 assets/js/51719dea.65346675.js delete mode 100644 assets/js/51ce653c.21c89cba.js create mode 100644 assets/js/51ce653c.dc35e1ca.js create mode 100644 assets/js/521a6610.546443b5.js delete mode 100644 assets/js/521a6610.95717138.js create mode 100644 assets/js/52927c97.de1bbc11.js create mode 100644 assets/js/52ab49a5.7e1e13d0.js delete mode 100644 assets/js/52fa5650.b182f278.js create mode 100644 assets/js/52fa5650.deb039aa.js delete mode 100644 assets/js/533ebf6b.62b843d3.js create mode 100644 assets/js/533ebf6b.d593cda4.js create mode 100644 assets/js/5364a150.134445fe.js delete mode 100644 assets/js/5364a150.155bae67.js create mode 100644 assets/js/53d095ec.27dbcfb8.js delete mode 100644 assets/js/53d095ec.d55cf378.js create mode 100644 assets/js/53dc618d.924994dd.js create mode 100644 assets/js/546b5549.3f31a8ae.js delete mode 100644 assets/js/546b5549.588a9376.js create mode 100644 assets/js/5496fb16.e37b2d67.js delete mode 100644 assets/js/5497691c.3c574e7f.js create mode 100644 assets/js/5497691c.7a0da876.js create mode 100644 assets/js/54fcde43.7c8f527d.js delete mode 100644 assets/js/55568807.2e91d1c2.js create mode 100644 assets/js/55568807.da999a9a.js delete mode 100644 assets/js/555a4473.0aea839c.js create mode 100644 assets/js/555a4473.fbed11b1.js create mode 100644 assets/js/559dc838.8f1fde69.js delete mode 100644 assets/js/560adf9d.033a09e9.js create mode 100644 assets/js/560adf9d.05f652ff.js create mode 100644 assets/js/5611a8f0.95614330.js create mode 100644 assets/js/56746dcb.51ad8181.js delete mode 100644 assets/js/56746dcb.f4900217.js create mode 100644 assets/js/56aa8058.bdb374f9.js delete mode 100644 assets/js/56ad65de.d53d5c28.js create mode 100644 assets/js/56ad65de.fcda7351.js create mode 100644 assets/js/56fae639.036d3ba6.js create mode 100644 assets/js/56ffdb25.995afe37.js create mode 100644 assets/js/576e11bb.b19d9462.js create mode 100644 assets/js/57d593f0.9081b32b.js delete mode 100644 assets/js/57f923a9.ad12da5f.js create mode 100644 assets/js/57f923a9.f57d37c0.js create mode 100644 assets/js/58092c27.8c31d248.js delete mode 100644 assets/js/58092c27.b116ed08.js delete mode 100644 assets/js/58718032.25ddfdd1.js create mode 100644 assets/js/58718032.68396545.js rename assets/js/{416.c7de0599.js => 58913.6eee2a6e.js} (55%) create mode 100644 assets/js/5979a0ec.621162c0.js delete mode 100644 assets/js/5979a0ec.ef4511ba.js create mode 100644 assets/js/59b77803.fd87f57e.js create mode 100644 assets/js/5a22b142.b646e6c0.js delete mode 100644 assets/js/5a22b142.d6483baa.js create mode 100644 assets/js/5a3b84ba.63717aa0.js delete mode 100644 assets/js/5a3b84ba.73c72eda.js create mode 100644 assets/js/5a6ba1cd.fa112277.js create mode 100644 assets/js/5b38c543.7266d270.js delete mode 100644 assets/js/5b827590.803d7896.js create mode 100644 assets/js/5b827590.e6f4f0a7.js delete mode 100644 assets/js/5c07109c.72972707.js create mode 100644 assets/js/5c07109c.9dc5bbd3.js create mode 100644 assets/js/5c08a95a.26a3ecb2.js create mode 100644 assets/js/5c3f78ae.1c8dc26f.js delete mode 100644 assets/js/5c3f78ae.c5d549a0.js delete mode 100644 assets/js/5ce0f216.2ca1cbe8.js create mode 100644 assets/js/5ce0f216.5f134790.js create mode 100644 assets/js/5cf40dea.940a452c.js delete mode 100644 assets/js/5cf40dea.eeda9684.js delete mode 100644 assets/js/5d4e9672.00906f33.js create mode 100644 assets/js/5d4e9672.604f7974.js create mode 100644 assets/js/5db8b942.1835e546.js create mode 100644 assets/js/5e5b712e.6e7d89b9.js delete mode 100644 assets/js/5e9306ee.35f8dd24.js create mode 100644 assets/js/5e9306ee.39afcc18.js create mode 100644 assets/js/5eb62c95.f9ba076c.js create mode 100644 assets/js/5ed91ab5.744eaccf.js delete mode 100644 assets/js/5ed91ab5.d74e522c.js create mode 100644 assets/js/5f02ec4e.25f504ac.js delete mode 100644 assets/js/5f02ec4e.e8115c1a.js create mode 100644 assets/js/5f241059.4b623e89.js delete mode 100644 assets/js/603aca9e.56ef5275.js create mode 100644 assets/js/603aca9e.d3942f34.js delete mode 100644 assets/js/6043c3f4.024a7c77.js create mode 100644 assets/js/6043c3f4.9b2ce9e7.js create mode 100644 assets/js/60d3a705.8959a6ed.js delete mode 100644 assets/js/60d3a705.cec61f0b.js create mode 100644 assets/js/60fa9972.532892dc.js delete mode 100644 assets/js/60fa9972.b69bb4a6.js create mode 100644 assets/js/61415b83.6de3dfdc.js create mode 100644 assets/js/6193b30e.8d7754ae.js delete mode 100644 assets/js/6193b30e.8f5c08a1.js create mode 100644 assets/js/621db11d.72d8a767.js delete mode 100644 assets/js/621db11d.81ae89ad.js delete mode 100644 assets/js/6245c126.30b30088.js create mode 100644 assets/js/6245c126.8cf7cbff.js create mode 100644 assets/js/62569fa7.4c155b8f.js create mode 100644 assets/js/6318ac72.262b8dce.js delete mode 100644 assets/js/6318ac72.49f55d51.js create mode 100644 assets/js/631bdc93.abd03f43.js create mode 100644 assets/js/63925da8.5e258b77.js delete mode 100644 assets/js/63925da8.a65c70bf.js create mode 100644 assets/js/63d4ce07.2ce275cd.js delete mode 100644 assets/js/63d4ce07.8dccf7cc.js create mode 100644 assets/js/64733a41.aa5d15dd.js delete mode 100644 assets/js/6474e148.836b5554.js create mode 100644 assets/js/6474e148.f34dd9c3.js create mode 100644 assets/js/64899cf9.892e78a4.js delete mode 100644 assets/js/64899cf9.d83e08cf.js create mode 100644 assets/js/64959b1e.2d006066.js delete mode 100644 assets/js/64959b1e.487a4de3.js create mode 100644 assets/js/64bdcaf3.e264dcdb.js delete mode 100644 assets/js/64c09e2e.d5d788c7.js create mode 100644 assets/js/64c09e2e.fa6ac55d.js delete mode 100644 assets/js/650a8fc0.6c05b66c.js create mode 100644 assets/js/650a8fc0.fcb9962e.js create mode 100644 assets/js/6520db96.0f7b780d.js delete mode 100644 assets/js/6520db96.17ace29b.js create mode 100644 assets/js/65961da4.2834b925.js delete mode 100644 assets/js/65961da4.60f93cb9.js create mode 100644 assets/js/65a9ed9e.3fe3d223.js delete mode 100644 assets/js/65a9ed9e.f11f4e01.js delete mode 100644 assets/js/65cd111b.64289a65.js create mode 100644 assets/js/65cd111b.9f4c0cef.js delete mode 100644 assets/js/680b7fa9.7fd0fcdc.js create mode 100644 assets/js/680b7fa9.83815de4.js create mode 100644 assets/js/68730730.64e6198a.js delete mode 100644 assets/js/6875c492.b515c771.js create mode 100644 assets/js/6875c492.b5181e60.js delete mode 100644 assets/js/68ccb7f6.108271e9.js create mode 100644 assets/js/68ccb7f6.22bc5312.js delete mode 100644 assets/js/6a307077.51e38375.js create mode 100644 assets/js/6a307077.880239fa.js create mode 100644 assets/js/6bed00f2.4b14e37a.js delete mode 100644 assets/js/6c606038.42035320.js create mode 100644 assets/js/6c606038.a21110c8.js create mode 100644 assets/js/6ceb2263.4869c915.js create mode 100644 assets/js/6dcb5e16.631ecf42.js delete mode 100644 assets/js/6dcb5e16.e806e70a.js delete mode 100644 assets/js/6e2737c0.94881826.js create mode 100644 assets/js/6e2737c0.fc64a7ef.js delete mode 100644 assets/js/6e34a484.5e7fcec6.js create mode 100644 assets/js/6e34a484.df202898.js delete mode 100644 assets/js/6fe126b9.1e04b30e.js create mode 100644 assets/js/6fe126b9.e52a98b9.js delete mode 100644 assets/js/705e93ef.1d983d05.js create mode 100644 assets/js/705e93ef.e6ce9050.js delete mode 100644 assets/js/709dfa47.62b3e248.js create mode 100644 assets/js/709dfa47.969b3e76.js create mode 100644 assets/js/72106d8f.bdea1c52.js create mode 100644 assets/js/727f767d.5bc07a55.js delete mode 100644 assets/js/727f767d.bf85bdde.js delete mode 100644 assets/js/72a89de8.820a02b4.js create mode 100644 assets/js/72a89de8.adc4dd3e.js create mode 100644 assets/js/72b43be8.3923b0c1.js delete mode 100644 assets/js/72b43be8.5416988c.js create mode 100644 assets/js/72c6e609.3cf437f8.js delete mode 100644 assets/js/72c6e609.8779ead0.js create mode 100644 assets/js/72cc2261.0d29617c.js delete mode 100644 assets/js/72cc2261.d789919f.js create mode 100644 assets/js/7366a28d.4e7c9bfa.js delete mode 100644 assets/js/738a6ad4.cf62d230.js create mode 100644 assets/js/738a6ad4.df968aee.js create mode 100644 assets/js/74d57d33.872e0d5f.js delete mode 100644 assets/js/74d57d33.882cb0d6.js create mode 100644 assets/js/753d7b98.669096ae.js delete mode 100644 assets/js/753d7b98.aa766a46.js delete mode 100644 assets/js/75de5623.40d8f83e.js create mode 100644 assets/js/75de5623.515b1f12.js delete mode 100644 assets/js/7607f1d5.09164840.js create mode 100644 assets/js/7607f1d5.d4ae0eb6.js create mode 100644 assets/js/76839fc0.2942aa34.js create mode 100644 assets/js/76a75fbd.8393010c.js delete mode 100644 assets/js/76a75fbd.cb2ccf80.js create mode 100644 assets/js/76ea157b.4cf4a84d.js delete mode 100644 assets/js/7708241d.76dde882.js create mode 100644 assets/js/7708241d.c2fc2488.js create mode 100644 assets/js/772d3db3.5265c340.js delete mode 100644 assets/js/772d3db3.b3494ddc.js create mode 100644 assets/js/77395f9a.d869d436.js create mode 100644 assets/js/77981a3a.5c6f062e.js delete mode 100644 assets/js/77981a3a.abfda3cf.js create mode 100644 assets/js/77c92c8c.228a09d7.js create mode 100644 assets/js/7850177d.e012839f.js create mode 100644 assets/js/78c66fad.28feae2f.js delete mode 100644 assets/js/78c66fad.6c958184.js create mode 100644 assets/js/79113.6a88e948.js create mode 100644 assets/js/79474bae.a5a4db28.js delete mode 100644 assets/js/79474bae.b05288fa.js create mode 100644 assets/js/79d896a3.09570395.js delete mode 100644 assets/js/79d896a3.a26aa031.js delete mode 100644 assets/js/7ade0b2a.77621e50.js create mode 100644 assets/js/7ade0b2a.9718930e.js create mode 100644 assets/js/7b1c3c68.2f0f9401.js delete mode 100644 assets/js/7b1c3c68.e8be7755.js create mode 100644 assets/js/7b8da7d8.8db3e644.js delete mode 100644 assets/js/7b8da7d8.eab766d1.js create mode 100644 assets/js/7bf3b0fc.dec4d3c2.js create mode 100644 assets/js/7c67ea25.976f293e.js delete mode 100644 assets/js/7c67ea25.dbf66f2d.js delete mode 100644 assets/js/7c798d59.93f88623.js create mode 100644 assets/js/7c798d59.a338572d.js create mode 100644 assets/js/7ce4a62a.76742a6b.js delete mode 100644 assets/js/7ce4a62a.8943f664.js create mode 100644 assets/js/7ce91694.521657b2.js create mode 100644 assets/js/7cf62e8d.1ebdf3ec.js delete mode 100644 assets/js/7cf62e8d.f6f618ae.js create mode 100644 assets/js/7cff47a5.24df3477.js delete mode 100644 assets/js/7cff47a5.af4053dd.js delete mode 100644 assets/js/7e55f6e6.22836de1.js create mode 100644 assets/js/7e55f6e6.80a4eced.js delete mode 100644 assets/js/7effaf45.395677e0.js create mode 100644 assets/js/7effaf45.b7576d51.js create mode 100644 assets/js/7f115b1f.08f8427a.js delete mode 100644 assets/js/7f115b1f.4ae39270.js create mode 100644 assets/js/7feecbc1.0bd89ed5.js create mode 100644 assets/js/80510dbd.8f6dc460.js delete mode 100644 assets/js/80e6044e.713e25c1.js create mode 100644 assets/js/80e6044e.be8973b1.js create mode 100644 assets/js/814e64cc.3ab7cd73.js create mode 100644 assets/js/814f3328.42442acd.js delete mode 100644 assets/js/814f3328.f0c18ae2.js create mode 100644 assets/js/8154f86c.6126d122.js create mode 100644 assets/js/821dc1e3.07ce4564.js delete mode 100644 assets/js/821dc1e3.484815c2.js create mode 100644 assets/js/82237.082e051d.js create mode 100644 assets/js/830e9e14.801017c6.js delete mode 100644 assets/js/830e9e14.b215aae2.js delete mode 100644 assets/js/8323e0f5.5f3557eb.js create mode 100644 assets/js/8323e0f5.8ddff4c3.js create mode 100644 assets/js/85b8bb26.306e91f8.js delete mode 100644 assets/js/85b8bb26.da81382e.js delete mode 100644 assets/js/861e5e13.2a7daafb.js create mode 100644 assets/js/861e5e13.e59049a7.js create mode 100644 assets/js/862f9df3.ca8d966e.js create mode 100644 assets/js/8675f5af.bfe5a528.js create mode 100644 assets/js/86ae953a.101fb2af.js create mode 100644 assets/js/86b0038a.ae57b7f1.js create mode 100644 assets/js/870de909.24484384.js delete mode 100644 assets/js/870de909.59012146.js create mode 100644 assets/js/871da383.0bff42d1.js create mode 100644 assets/js/8768801e.c7c6d258.js create mode 100644 assets/js/87867a42.4e487d7d.js create mode 100644 assets/js/87f5bee7.11d7c141.js delete mode 100644 assets/js/87f5bee7.c06abb9f.js create mode 100644 assets/js/883310e5.f489e4cb.js delete mode 100644 assets/js/883310e5.f84c5342.js create mode 100644 assets/js/8833ab21.2f4414a2.js delete mode 100644 assets/js/8833ab21.8e10ccb3.js delete mode 100644 assets/js/8941358f.b44c7608.js create mode 100644 assets/js/8941358f.e38b3228.js create mode 100644 assets/js/897e9cb3.4f6ab0e4.js delete mode 100644 assets/js/897e9cb3.7555ccf7.js delete mode 100644 assets/js/89c22482.8436b3a0.js create mode 100644 assets/js/89c22482.b950b66f.js create mode 100644 assets/js/89d896be.164f310b.js delete mode 100644 assets/js/89d896be.f7cb4e66.js delete mode 100644 assets/js/8c0ead1f.9f40d963.js create mode 100644 assets/js/8c0ead1f.ef689526.js delete mode 100644 assets/js/8d265689.94e8c769.js create mode 100644 assets/js/8d265689.b6706ec9.js create mode 100644 assets/js/8d81394c.8dfe83fc.js delete mode 100644 assets/js/8d81394c.b71ef1fd.js create mode 100644 assets/js/8d90c7e3.28b4caa2.js create mode 100644 assets/js/8dd9adb4.f35c58e4.js create mode 100644 assets/js/8de9f24f.046ff0c7.js delete mode 100644 assets/js/8de9f24f.27e228f9.js create mode 100644 assets/js/8e1fd569.89ba8087.js delete mode 100644 assets/js/8e1fd569.c1e0d801.js delete mode 100644 assets/js/8f27be43.9c50069b.js create mode 100644 assets/js/8f27be43.ca74fdf7.js create mode 100644 assets/js/8fcee16d.27cfe3cc.js create mode 100644 assets/js/8ff31131.13194bde.js delete mode 100644 assets/js/8ff31131.5c0f2d85.js rename assets/js/{8913.b6442bb9.js => 90416.140f33a2.js} (55%) create mode 100644 assets/js/905c7445.20605116.js delete mode 100644 assets/js/90efbb16.0264317d.js create mode 100644 assets/js/90efbb16.eca6bbe3.js create mode 100644 assets/js/90f2be13.1d93cdbb.js create mode 100644 assets/js/9116852a.695b9cf3.js delete mode 100644 assets/js/9116852a.95b23be5.js delete mode 100644 assets/js/915d90e1.21e8e7ff.js create mode 100644 assets/js/915d90e1.6837c1e2.js delete mode 100644 assets/js/931ecaed.0c0278da.js create mode 100644 assets/js/931ecaed.28170080.js create mode 100644 assets/js/947e950c.16603b98.js create mode 100644 assets/js/94f643bb.0ffdacc0.js delete mode 100644 assets/js/94f643bb.31c536d4.js create mode 100644 assets/js/95c53987.293de8d0.js create mode 100644 assets/js/962c96ee.fd744aa5.js create mode 100644 assets/js/96fcb421.99cb328e.js create mode 100644 assets/js/977c8faa.143671f7.js delete mode 100644 assets/js/977c8faa.34237830.js create mode 100644 assets/js/98d1a471.222d0cf9.js delete mode 100644 assets/js/98df448b.23f7a8f8.js create mode 100644 assets/js/98df448b.4dbc3804.js create mode 100644 assets/js/99a13742.82691f99.js delete mode 100644 assets/js/99a13742.d3215e16.js create mode 100644 assets/js/9a38f23f.5bb7b4cd.js create mode 100644 assets/js/9a508619.234da57e.js delete mode 100644 assets/js/9acc619b.a5bfebce.js create mode 100644 assets/js/9acc619b.fdbf2c17.js create mode 100644 assets/js/9afe1d3d.115a3c11.js delete mode 100644 assets/js/9afe1d3d.e763479c.js delete mode 100644 assets/js/9b0d9b67.bbbfb3bf.js create mode 100644 assets/js/9b0d9b67.d0cc04c6.js create mode 100644 assets/js/9b70ce79.bc96c9f0.js create mode 100644 assets/js/9c5b6467.3d86687a.js delete mode 100644 assets/js/9c5b6467.3db5c71f.js delete mode 100644 assets/js/9c6aa8d2.87f1ae35.js create mode 100644 assets/js/9c6aa8d2.a5007e66.js delete mode 100644 assets/js/9c780b1a.134169a6.js create mode 100644 assets/js/9c780b1a.7540caa7.js create mode 100644 assets/js/9cb749bd.a84526b3.js delete mode 100644 assets/js/9cd0819b.14619139.js create mode 100644 assets/js/9cd0819b.647896eb.js create mode 100644 assets/js/9d275d72.0b08718a.js delete mode 100644 assets/js/9d275d72.668b0bc7.js create mode 100644 assets/js/9dd9d4ea.3a5f592e.js create mode 100644 assets/js/9e4087bc.426382ea.js delete mode 100644 assets/js/9e4087bc.c84286d7.js create mode 100644 assets/js/9ec4e3de.88035139.js create mode 100644 assets/js/9ed00072.851b8b22.js delete mode 100644 assets/js/9ed00072.861eaae3.js create mode 100644 assets/js/9ee7887a.3c988df8.js delete mode 100644 assets/js/9ee7887a.a80b72fc.js create mode 100644 assets/js/a024ab51.21c9b95c.js delete mode 100644 assets/js/a03c4947.715ecbfc.js create mode 100644 assets/js/a03c4947.b024c0ac.js create mode 100644 assets/js/a0ccdbb2.9cb4eb73.js delete mode 100644 assets/js/a0ccdbb2.cf1b6b50.js delete mode 100644 assets/js/a1868598.bd404523.js create mode 100644 assets/js/a1868598.e4c98816.js create mode 100644 assets/js/a2874f18.02b183f5.js delete mode 100644 assets/js/a2874f18.d9627a72.js create mode 100644 assets/js/a2ea0fe7.f73f7874.js delete mode 100644 assets/js/a30e2bb0.89267903.js create mode 100644 assets/js/a30e2bb0.db4101ac.js create mode 100644 assets/js/a35afcc3.76af9ebf.js delete mode 100644 assets/js/a35afcc3.c8f608cb.js create mode 100644 assets/js/a36dca7d.ea67c2e6.js create mode 100644 assets/js/a3c7ece8.5621f945.js delete mode 100644 assets/js/a3dc4ae2.0aa14bc4.js create mode 100644 assets/js/a3dc4ae2.ee951085.js create mode 100644 assets/js/a3e473b3.b3680e8e.js delete mode 100644 assets/js/a4046515.82e9c056.js create mode 100644 assets/js/a4046515.c01a629a.js delete mode 100644 assets/js/a40a2cf8.5c89beea.js create mode 100644 assets/js/a40a2cf8.a2747ba0.js delete mode 100644 assets/js/a434b528.63eb51ca.js create mode 100644 assets/js/a434b528.8590c09f.js create mode 100644 assets/js/a4ae8417.5511ae65.js delete mode 100644 assets/js/a4ae8417.97847ea7.js create mode 100644 assets/js/a4b0daeb.2b9391ae.js delete mode 100644 assets/js/a4b0daeb.ca90cf11.js delete mode 100644 assets/js/a4cd78b5.cbc7d4a6.js create mode 100644 assets/js/a4cd78b5.e215ea72.js create mode 100644 assets/js/a4f8fe7e.83f1a268.js delete mode 100644 assets/js/a4f8fe7e.b982673b.js create mode 100644 assets/js/a53bd891.07818a14.js delete mode 100644 assets/js/a53bd891.34baf369.js delete mode 100644 assets/js/a55b9639.792f74b1.js create mode 100644 assets/js/a55b9639.bcfdb692.js create mode 100644 assets/js/a6957975.4b06c94e.js delete mode 100644 assets/js/a6aa9e1f.43025aa7.js create mode 100644 assets/js/a6aa9e1f.4977cbdf.js create mode 100644 assets/js/a6c56441.56418c50.js delete mode 100644 assets/js/a6efe0e1.17fb2b9f.js create mode 100644 assets/js/a6efe0e1.f66fc475.js delete mode 100644 assets/js/a72bcf22.d7ffd90c.js create mode 100644 assets/js/a72bcf22.e9c31f44.js delete mode 100644 assets/js/a7bd4aaa.951f72a9.js create mode 100644 assets/js/a7bd4aaa.f6bd7d37.js create mode 100644 assets/js/a7e0ea76.d1f0fa4d.js delete mode 100644 assets/js/a80f26d4.7206c3fd.js create mode 100644 assets/js/a80f26d4.8ef94877.js create mode 100644 assets/js/a811e42c.6d7c6526.js delete mode 100644 assets/js/a811e42c.b14b4cad.js create mode 100644 assets/js/a81b7004.614649de.js delete mode 100644 assets/js/a81b7004.8421c8ce.js create mode 100644 assets/js/a833d846.fbb45413.js delete mode 100644 assets/js/a94703ab.1cba57a1.js create mode 100644 assets/js/a94703ab.6d07f677.js create mode 100644 assets/js/a9707311.4c91be6f.js delete mode 100644 assets/js/a9deb425.39296314.js create mode 100644 assets/js/a9deb425.4b3ac4cb.js delete mode 100644 assets/js/a9f5564d.2e90b9b1.js create mode 100644 assets/js/a9f5564d.7ae89e3b.js delete mode 100644 assets/js/aa162190.1c22b5a0.js create mode 100644 assets/js/aa162190.42fe6ae5.js delete mode 100644 assets/js/aafbba97.658201c7.js create mode 100644 assets/js/aafbba97.d6419f85.js delete mode 100644 assets/js/ab246697.680665e7.js create mode 100644 assets/js/ab246697.e9ff96c3.js delete mode 100644 assets/js/ab991e0e.54fa42af.js create mode 100644 assets/js/ab991e0e.afb1898b.js create mode 100644 assets/js/aba21aa0.1ae003ba.js delete mode 100644 assets/js/aba21aa0.9fadd1f0.js create mode 100644 assets/js/abd56c27.10b1808e.js delete mode 100644 assets/js/abd56c27.bf3ed5c3.js create mode 100644 assets/js/ac16ac20.7b905f4c.js create mode 100644 assets/js/ac361b55.023b05ee.js delete mode 100644 assets/js/ac361b55.a49eb8bd.js create mode 100644 assets/js/ac9a16c0.8245bc52.js create mode 100644 assets/js/acecf23e.1d924b0f.js delete mode 100644 assets/js/acecf23e.77fdf311.js create mode 100644 assets/js/acee0a96.3b8121a3.js create mode 100644 assets/js/ad0b296a.459bbd0d.js delete mode 100644 assets/js/ad0b296a.ec564b7f.js create mode 100644 assets/js/ad15c07f.89ebc550.js delete mode 100644 assets/js/ad15c07f.9bfac3bd.js create mode 100644 assets/js/ad591877.cf7047e7.js create mode 100644 assets/js/ad727d36.001c91d8.js delete mode 100644 assets/js/ad727d36.f0083a21.js create mode 100644 assets/js/ad7eda35.6b9ae2e7.js delete mode 100644 assets/js/ad7eda35.de731ba0.js create mode 100644 assets/js/ae470ddc.47363dbf.js delete mode 100644 assets/js/ae470ddc.f89950ff.js create mode 100644 assets/js/ae5d26cf.38358f39.js create mode 100644 assets/js/aee0fe92.50fa9bd5.js delete mode 100644 assets/js/aee0fe92.cc892c71.js delete mode 100644 assets/js/aefd42fa.03d773c1.js create mode 100644 assets/js/aefd42fa.55d4578e.js delete mode 100644 assets/js/af050a36.9b90e62b.js create mode 100644 assets/js/af050a36.f22df805.js create mode 100644 assets/js/af1112c6.45aa0929.js delete mode 100644 assets/js/af1112c6.4e044cf1.js create mode 100644 assets/js/afa6d836.e95ff699.js delete mode 100644 assets/js/afa6d836.ec61673a.js create mode 100644 assets/js/b0b03333.557020ef.js create mode 100644 assets/js/b0e8b9d5.48be246d.js create mode 100644 assets/js/b114f501.3335785a.js create mode 100644 assets/js/b15d29cb.755d6cd9.js delete mode 100644 assets/js/b15d29cb.801818ce.js create mode 100644 assets/js/b192e983.9d48f4fd.js delete mode 100644 assets/js/b1eae65b.5f062bf3.js create mode 100644 assets/js/b1eae65b.e24179ba.js delete mode 100644 assets/js/b36f50d3.b825a751.js create mode 100644 assets/js/b36f50d3.ce29c971.js delete mode 100644 assets/js/b3a49b92.abfa439b.js create mode 100644 assets/js/b3a49b92.cbe25f10.js create mode 100644 assets/js/b3b8c5cb.66ba977e.js delete mode 100644 assets/js/b3b8c5cb.d5f88718.js create mode 100644 assets/js/b415f00a.bd7e11c9.js delete mode 100644 assets/js/b46ec474.0abc05a8.js create mode 100644 assets/js/b46ec474.8b17c0c3.js delete mode 100644 assets/js/b67f60dc.7656748c.js create mode 100644 assets/js/b67f60dc.9c1e5109.js delete mode 100644 assets/js/b687a817.0ec13cad.js create mode 100644 assets/js/b687a817.353ec7bd.js create mode 100644 assets/js/b70225e0.6b9ec728.js create mode 100644 assets/js/b70624a2.df42b3c0.js create mode 100644 assets/js/b71ecf14.1d11eac0.js delete mode 100644 assets/js/b71ecf14.1f26aa20.js create mode 100644 assets/js/b7708f1e.2b3f2d3b.js delete mode 100644 assets/js/b7708f1e.99acd00d.js create mode 100644 assets/js/b7a2b993.47bcf617.js create mode 100644 assets/js/b7cc26e1.2bfdb498.js create mode 100644 assets/js/b8c8445c.2da23794.js delete mode 100644 assets/js/b8c8445c.ff0cc91b.js create mode 100644 assets/js/b8ef17b7.802d36c5.js create mode 100644 assets/js/b8f04a6b.619e6ba5.js create mode 100644 assets/js/b9ffcd07.a7d11053.js delete mode 100644 assets/js/ba0fa3fe.2c38bb2c.js create mode 100644 assets/js/ba0fa3fe.45f877c7.js create mode 100644 assets/js/baabe181.1d890051.js delete mode 100644 assets/js/baabe181.5c403d89.js delete mode 100644 assets/js/baf71301.8c98a771.js create mode 100644 assets/js/baf71301.b7c5f244.js delete mode 100644 assets/js/bafead24.1578a574.js create mode 100644 assets/js/bafead24.e60d55cc.js create mode 100644 assets/js/bb037852.08cf4bca.js delete mode 100644 assets/js/bb037852.a0493efc.js delete mode 100644 assets/js/bb9db0dd.0b2c5312.js create mode 100644 assets/js/bb9db0dd.83c0a3cb.js delete mode 100644 assets/js/bc4bfdf0.65012c91.js create mode 100644 assets/js/bc4bfdf0.6b70cee0.js create mode 100644 assets/js/bcd2587d.f268cb4c.js create mode 100644 assets/js/bd7d26b2.4f702e53.js delete mode 100644 assets/js/bd7d26b2.6860a437.js create mode 100644 assets/js/be0df356.4be5fb84.js delete mode 100644 assets/js/be0df356.811aeaeb.js create mode 100644 assets/js/be5e85f4.e6fa4137.js delete mode 100644 assets/js/be5e85f4.f95550ce.js create mode 100644 assets/js/befad559.50157083.js delete mode 100644 assets/js/befad559.b54dfbe5.js create mode 100644 assets/js/bf5bbaf8.13f23cdc.js delete mode 100644 assets/js/bf5bbaf8.79578d9c.js create mode 100644 assets/js/bfb3244a.0a60faf8.js delete mode 100644 assets/js/bfb3244a.40640614.js create mode 100644 assets/js/c00ffc57.c6e16365.js create mode 100644 assets/js/c0299000.60ccb8d1.js delete mode 100644 assets/js/c0299000.a0ce979e.js create mode 100644 assets/js/c0def98a.5774eed0.js delete mode 100644 assets/js/c10b8a9f.7b6997c1.js create mode 100644 assets/js/c10b8a9f.f9001f93.js create mode 100644 assets/js/c10cfbfe.2a9f53c2.js delete mode 100644 assets/js/c10cfbfe.9a85001f.js create mode 100644 assets/js/c141421f.4ae5844e.js delete mode 100644 assets/js/c141421f.80b09241.js delete mode 100644 assets/js/c19e69a7.2fc7560a.js create mode 100644 assets/js/c19e69a7.9d2442b7.js delete mode 100644 assets/js/c2728190.0a5a894f.js create mode 100644 assets/js/c2728190.c9436c76.js create mode 100644 assets/js/c2a48fdb.aa595378.js delete mode 100644 assets/js/c2a48fdb.c860eb25.js create mode 100644 assets/js/c3308ba6.425334c7.js delete mode 100644 assets/js/c3308ba6.dabf8cd8.js create mode 100644 assets/js/c34be5c7.a0d52e84.js create mode 100644 assets/js/c377a04b.d0facf52.js create mode 100644 assets/js/c377dc4a.607514a8.js delete mode 100644 assets/js/c377dc4a.bac70803.js create mode 100644 assets/js/c37f176d.38ea646e.js delete mode 100644 assets/js/c37f176d.df6ecd7f.js create mode 100644 assets/js/c380abc4.9161c3a0.js delete mode 100644 assets/js/c380abc4.bac3fe3d.js delete mode 100644 assets/js/c4561df8.dd6655af.js create mode 100644 assets/js/c4561df8.e426f1f3.js create mode 100644 assets/js/c45e62e7.265d09b1.js create mode 100644 assets/js/c474c2b1.b1dce14d.js delete mode 100644 assets/js/c52eaa26.32d71864.js create mode 100644 assets/js/c52eaa26.dc4744b9.js create mode 100644 assets/js/c5f06d44.f6b77b6b.js create mode 100644 assets/js/c691959f.300edfdd.js delete mode 100644 assets/js/c691959f.8bec913d.js delete mode 100644 assets/js/c74094f8.7db305e4.js create mode 100644 assets/js/c74094f8.c3dcc644.js delete mode 100644 assets/js/c7d46fe1.340d8422.js create mode 100644 assets/js/c7d46fe1.c6ccb6de.js delete mode 100644 assets/js/c8e4da00.1ce531b1.js create mode 100644 assets/js/c8e4da00.377067a0.js create mode 100644 assets/js/c8eb2c38.d5c12a00.js create mode 100644 assets/js/c95e6d8d.9669f9e6.js create mode 100644 assets/js/c9d52fc5.95b1b5e6.js delete mode 100644 assets/js/c9d52fc5.a4eef94e.js delete mode 100644 assets/js/c9db186d.08192e85.js create mode 100644 assets/js/c9db186d.fb5fa52a.js delete mode 100644 assets/js/c9f0fdac.1f67a1b8.js create mode 100644 assets/js/c9f0fdac.8d113f91.js delete mode 100644 assets/js/ca0e408e.aa3ff09a.js create mode 100644 assets/js/ca7245df.76e3b27d.js delete mode 100644 assets/js/ca7245df.9c1a68a4.js create mode 100644 assets/js/ca962d2e.fb46012c.js create mode 100644 assets/js/cacd3f19.fb6d7d41.js create mode 100644 assets/js/cad9fd36.a362a2cd.js create mode 100644 assets/js/cb447cb9.2ecfdbd1.js delete mode 100644 assets/js/cb63487a.169a1a3c.js create mode 100644 assets/js/cb63487a.7cab35d9.js delete mode 100644 assets/js/cbe09f13.99a63f42.js create mode 100644 assets/js/cbe09f13.b56f8a87.js delete mode 100644 assets/js/cbe8101d.1206d77a.js create mode 100644 assets/js/cbe8101d.7596f688.js delete mode 100644 assets/js/cc2e94c0.ab50e15c.js create mode 100644 assets/js/cc2e94c0.b91d5649.js create mode 100644 assets/js/cc84b9e4.a97ce4c6.js create mode 100644 assets/js/ccc49370.78b27ccb.js delete mode 100644 assets/js/ccc49370.be9d46ff.js create mode 100644 assets/js/cd8c5c3b.2df6b353.js delete mode 100644 assets/js/cd948886.281c855f.js create mode 100644 assets/js/cd948886.5aed8c76.js create mode 100644 assets/js/cdd6a56c.a344a0d7.js create mode 100644 assets/js/ce0e1dbb.a2815888.js delete mode 100644 assets/js/ce0e1dbb.b2988b7b.js create mode 100644 assets/js/ce3d5a4b.69e5cefd.js delete mode 100644 assets/js/ce3d5a4b.b4b03daf.js create mode 100644 assets/js/ce6605d8.702f3687.js delete mode 100644 assets/js/ce6605d8.ba4d38f5.js create mode 100644 assets/js/ce6fe363.8c36f3f4.js create mode 100644 assets/js/cf3029ea.f454004c.js create mode 100644 assets/js/cf35294f.5c7a277d.js delete mode 100644 assets/js/cf35294f.bb066321.js create mode 100644 assets/js/cfcbd284.63fc464b.js create mode 100644 assets/js/d02d0f51.fff99507.js create mode 100644 assets/js/d050b476.240ce090.js delete mode 100644 assets/js/d050b476.71af1ad0.js create mode 100644 assets/js/d0616161.a6c02aa2.js create mode 100644 assets/js/d06ee05c.4fae27bd.js delete mode 100644 assets/js/d06ee05c.b42299f4.js delete mode 100644 assets/js/d0a8493b.0a50edbb.js create mode 100644 assets/js/d0a8493b.8611e4aa.js create mode 100644 assets/js/d0c6c99a.e6fa3b5a.js create mode 100644 assets/js/d13dc577.5be46c79.js delete mode 100644 assets/js/d13dc577.6fe89c7c.js delete mode 100644 assets/js/d2039ef8.5609990b.js create mode 100644 assets/js/d2039ef8.e3054ff4.js delete mode 100644 assets/js/d220dcab.b0fd0ac0.js create mode 100644 assets/js/d220dcab.d1c22622.js create mode 100644 assets/js/d279fdce.312ed6b1.js delete mode 100644 assets/js/d279fdce.7ef66588.js create mode 100644 assets/js/d3ef4614.1ecc7dd0.js delete mode 100644 assets/js/d3ef4614.82ba742b.js delete mode 100644 assets/js/d477c291.57fee1c9.js create mode 100644 assets/js/d477c291.e950cbd2.js rename assets/js/{9ec4e3de.eaa96579.js => d48191b6.092d048f.js} (60%) delete mode 100644 assets/js/d48191b6.9a8c43c0.js create mode 100644 assets/js/d49dddd4.766c61f5.js delete mode 100644 assets/js/d49dddd4.ceb8eee3.js delete mode 100644 assets/js/d4c529d3.c6f1d5fa.js create mode 100644 assets/js/d4c529d3.d2c5e7bd.js create mode 100644 assets/js/d629d828.9452bae9.js create mode 100644 assets/js/d638c601.15664957.js delete mode 100644 assets/js/d638c601.58b730d1.js create mode 100644 assets/js/d7289626.35d9a384.js delete mode 100644 assets/js/d7289626.6cdeaeb0.js delete mode 100644 assets/js/d7f9f727.75d78148.js create mode 100644 assets/js/d7f9f727.baf34cdc.js create mode 100644 assets/js/d7fae98e.1349e043.js delete mode 100644 assets/js/d7fae98e.1faab744.js delete mode 100644 assets/js/d80df429.67028afb.js create mode 100644 assets/js/d80df429.d3c78300.js create mode 100644 assets/js/d81ba6be.98f8f400.js create mode 100644 assets/js/d8ae3676.ed256976.js create mode 100644 assets/js/d8c709f8.5f79bc8f.js delete mode 100644 assets/js/d92b4d08.2f4390d9.js create mode 100644 assets/js/d92b4d08.d98a3927.js create mode 100644 assets/js/d94d6bbe.5f51f6b7.js delete mode 100644 assets/js/d94d6bbe.f9bfb75e.js delete mode 100644 assets/js/db24aef0.5b7d27fc.js create mode 100644 assets/js/db24aef0.7be66191.js create mode 100644 assets/js/dbfc4782.400f41c7.js delete mode 100644 assets/js/dbfc4782.468a1d4c.js delete mode 100644 assets/js/dc1c4417.1f2e5fdc.js create mode 100644 assets/js/dc1c4417.31cadd38.js create mode 100644 assets/js/dc5e10d3.7935911a.js delete mode 100644 assets/js/dc5e10d3.854abbc3.js create mode 100644 assets/js/dcb4c613.333717ee.js delete mode 100644 assets/js/dcb4c613.9305969c.js create mode 100644 assets/js/dd04b75e.3463f4df.js delete mode 100644 assets/js/dd04b75e.7f740bf3.js delete mode 100644 assets/js/dd908370.a9598e25.js create mode 100644 assets/js/dd908370.b6499474.js create mode 100644 assets/js/dd93ee27.c6c59160.js create mode 100644 assets/js/de33ad21.8fafd612.js create mode 100644 assets/js/df5bc763.577a5deb.js delete mode 100644 assets/js/df5bc763.837d978f.js delete mode 100644 assets/js/dfbc8a55.1e3a65ca.js create mode 100644 assets/js/dfbc8a55.270b4583.js delete mode 100644 assets/js/dfcc4619.0ab89293.js create mode 100644 assets/js/dfcc4619.c764dc8b.js create mode 100644 assets/js/e068c333.4084d666.js delete mode 100644 assets/js/e08eef46.56de3c31.js create mode 100644 assets/js/e08eef46.c3b1a795.js create mode 100644 assets/js/e10cd13d.5aff8aea.js create mode 100644 assets/js/e15566cb.26ef38f0.js delete mode 100644 assets/js/e15566cb.87dbe301.js create mode 100644 assets/js/e1e5af17.a55d48e0.js delete mode 100644 assets/js/e1e5af17.e2008a93.js create mode 100644 assets/js/e238c115.03c04108.js delete mode 100644 assets/js/e238c115.2aaf7fc9.js create mode 100644 assets/js/e2509bb6.6b2e5db8.js create mode 100644 assets/js/e2799c63.caf45662.js delete mode 100644 assets/js/e2799c63.d128e43e.js delete mode 100644 assets/js/e289ead3.1f169ca7.js create mode 100644 assets/js/e289ead3.b2eba89f.js create mode 100644 assets/js/e2975a84.51a6b884.js delete mode 100644 assets/js/e2975a84.5efeb63f.js delete mode 100644 assets/js/e2f5312b.06dbe2a4.js create mode 100644 assets/js/e2f5312b.d4f136f1.js delete mode 100644 assets/js/e3f9a068.2511d6f6.js create mode 100644 assets/js/e3f9a068.ee51fe72.js create mode 100644 assets/js/e45056bc.816736bc.js delete mode 100644 assets/js/e45056bc.9693a59b.js create mode 100644 assets/js/e4d870e1.abd2b6f0.js delete mode 100644 assets/js/e4d870e1.f85bd94e.js create mode 100644 assets/js/e5493a21.b67e196f.js delete mode 100644 assets/js/e5493a21.e2c9467a.js create mode 100644 assets/js/e5afa1a3.435be811.js create mode 100644 assets/js/e605c6b3.e7d9d88b.js create mode 100644 assets/js/e7589c2a.a8005701.js create mode 100644 assets/js/e8b40bee.16146a5b.js delete mode 100644 assets/js/e8b40bee.291c4a8c.js create mode 100644 assets/js/e939f825.436c9fa9.js delete mode 100644 assets/js/ea0474c4.2a0d441d.js create mode 100644 assets/js/ea0474c4.f097486d.js create mode 100644 assets/js/ea921b39.308e6c57.js delete mode 100644 assets/js/eaba5dd2.013bab1c.js create mode 100644 assets/js/eaba5dd2.a045f2ae.js create mode 100644 assets/js/eacea541.713b9738.js delete mode 100644 assets/js/eacea541.eb56de71.js create mode 100644 assets/js/eb0d94ae.4b8f7e24.js delete mode 100644 assets/js/eb0d94ae.58bdbefc.js create mode 100644 assets/js/eb1cd7f2.1282bdde.js delete mode 100644 assets/js/eb1cd7f2.4d0cd80d.js create mode 100644 assets/js/eb5a6cc0.5fb4114d.js delete mode 100644 assets/js/eb5a6cc0.bb4e4618.js delete mode 100644 assets/js/ebb9a3ce.877a950d.js create mode 100644 assets/js/ebb9a3ce.bdc45b5b.js delete mode 100644 assets/js/ed267fba.167c6c60.js create mode 100644 assets/js/ed267fba.6c0f909a.js create mode 100644 assets/js/ed3af4a0.611178a8.js create mode 100644 assets/js/ed772d97.ff32e5f5.js create mode 100644 assets/js/ee7c1cc7.acd77737.js delete mode 100644 assets/js/ee7c1cc7.f382d244.js create mode 100644 assets/js/ee94176e.42f353c4.js delete mode 100644 assets/js/ee94176e.948fb7cb.js create mode 100644 assets/js/eeb3740b.7aca9b4d.js create mode 100644 assets/js/ef2abd7e.4f00923b.js delete mode 100644 assets/js/ef2abd7e.e1b228a5.js create mode 100644 assets/js/ef646837.20fafc7e.js create mode 100644 assets/js/ef726b40.2fca8d33.js create mode 100644 assets/js/ef7672e3.34f0b8af.js delete mode 100644 assets/js/ef7672e3.d080a329.js create mode 100644 assets/js/efd01d75.02a4a077.js delete mode 100644 assets/js/eff21157.bd65bcae.js create mode 100644 assets/js/eff21157.d54a2b5c.js delete mode 100644 assets/js/f0563fee.0da4678b.js create mode 100644 assets/js/f0563fee.df8d1b93.js delete mode 100644 assets/js/f070a991.8a1ac562.js create mode 100644 assets/js/f070a991.984951c4.js delete mode 100644 assets/js/f1245771.23f1d291.js create mode 100644 assets/js/f1245771.8a14c444.js create mode 100644 assets/js/f1a6c2e6.30426d72.js delete mode 100644 assets/js/f1c6b7a3.50559f74.js create mode 100644 assets/js/f1c6b7a3.dd24385f.js delete mode 100644 assets/js/f1f89c2e.04046fd4.js create mode 100644 assets/js/f1f89c2e.2e307f65.js create mode 100644 assets/js/f203f57a.c10ab2eb.js create mode 100644 assets/js/f224ad82.becdd6c1.js create mode 100644 assets/js/f2779c45.1985fa4b.js delete mode 100644 assets/js/f2779c45.270e5772.js create mode 100644 assets/js/f2a77c75.4e76bee9.js create mode 100644 assets/js/f2e157d0.d49d6620.js delete mode 100644 assets/js/f3bf6984.253d30ee.js create mode 100644 assets/js/f3bf6984.d6d4b2c7.js create mode 100644 assets/js/f46d6e59.b998f248.js delete mode 100644 assets/js/f46d6e59.d7f83469.js create mode 100644 assets/js/f5c04343.715b43d2.js create mode 100644 assets/js/f6320c57.a7d30f9d.js create mode 100644 assets/js/f69b951d.a8eed262.js create mode 100644 assets/js/f71fe95d.9ad08d80.js delete mode 100644 assets/js/f71fe95d.fa1be639.js create mode 100644 assets/js/f74078f7.5b44140b.js delete mode 100644 assets/js/f776c06c.59c0b752.js create mode 100644 assets/js/f776c06c.6260625f.js create mode 100644 assets/js/f8743170.a30916fe.js create mode 100644 assets/js/f88cb658.93e9da43.js delete mode 100644 assets/js/f88cb658.de8becbc.js create mode 100644 assets/js/f95b1f88.2c0ea01f.js delete mode 100644 assets/js/f95b1f88.7cc6f7b3.js delete mode 100644 assets/js/faf2a93e.41ab65a9.js create mode 100644 assets/js/faf2a93e.5f4fcdac.js create mode 100644 assets/js/fb804d1c.8135cc99.js delete mode 100644 assets/js/fb804d1c.9658edac.js create mode 100644 assets/js/fb904585.9a2467f1.js create mode 100644 assets/js/fd661beb.9306c892.js delete mode 100644 assets/js/fd661beb.dd72aba0.js create mode 100644 assets/js/fd967833.84a1d37c.js create mode 100644 assets/js/fe0242b1.4ee542a5.js delete mode 100644 assets/js/fe0242b1.da99f6c2.js delete mode 100644 assets/js/fef6ab33.16f28ded.js create mode 100644 assets/js/fef6ab33.746d8b52.js delete mode 100644 assets/js/main.8959bba6.js create mode 100644 assets/js/main.d3917998.js rename assets/js/{main.8959bba6.js.LICENSE.txt => main.d3917998.js.LICENSE.txt} (100%) delete mode 100644 assets/js/runtime~main.d0ca807f.js create mode 100644 assets/js/runtime~main.f9ac0d96.js create mode 100644 concepts/about/index.html create mode 100644 concepts/addressable-entity/index.html create mode 100644 concepts/design/consensus/index.html create mode 100644 concepts/design/rewards/index.html create mode 100644 concepts/design/zug/index.html delete mode 100644 concepts/economics/concepts/index.html delete mode 100644 concepts/economics/delegation/index.html rename {next/concepts => concepts}/economics/dynamic-gas-pricing/index.html (57%) create mode 100644 concepts/economics/fee-elimination/index.html create mode 100644 concepts/economics/staking/index.html delete mode 100644 concepts/hash-types/index.html rename {next/concepts => concepts}/key-types/index.html (55%) create mode 100644 concepts/serialization/index.html rename {next/concepts => concepts}/serialization/primitives/index.html (67%) create mode 100644 concepts/serialization/structures/index.html rename {next/concepts => concepts}/serialization/types/index.html (60%) delete mode 100644 deploy-and-deploy-lifecycle/index.html rename {next/developers => developers}/cli/sending-transactions/index.html (91%) create mode 100644 developers/cli/verifying-contracts/index.html delete mode 100644 developers/dapps/signing-a-deploy/index.html create mode 100644 developers/dapps/signing-a-transaction/index.html rename {next/developers => developers}/writing-onchain-code/emitting-contract-events/index.html (91%) rename {next/developers => developers}/writing-onchain-code/factory-pattern/index.html (79%) delete mode 100644 next/concepts/addressable-entity/index.html delete mode 100644 next/concepts/callstack/index.html delete mode 100644 next/concepts/design/consensus/index.html delete mode 100644 next/concepts/design/highway/index.html delete mode 100644 next/concepts/design/p2p/index.html delete mode 100644 next/concepts/design/reading-and-writing-to-the-blockchain/index.html delete mode 100644 next/concepts/economics/consensus/index.html delete mode 100644 next/concepts/economics/fee-elimination/index.html delete mode 100644 next/concepts/economics/gas-concepts/index.html delete mode 100644 next/concepts/economics/staking/index.html delete mode 100644 next/concepts/global-state/index.html delete mode 100644 next/concepts/glossary/A/index.html delete mode 100644 next/concepts/glossary/B/index.html delete mode 100644 next/concepts/glossary/C/index.html delete mode 100644 next/concepts/glossary/D/index.html delete mode 100644 next/concepts/glossary/E/index.html delete mode 100644 next/concepts/glossary/F/index.html delete mode 100644 next/concepts/glossary/G/index.html delete mode 100644 next/concepts/glossary/H/index.html delete mode 100644 next/concepts/glossary/I/index.html delete mode 100644 next/concepts/glossary/J/index.html delete mode 100644 next/concepts/glossary/K/index.html delete mode 100644 next/concepts/glossary/L/index.html delete mode 100644 next/concepts/glossary/M/index.html delete mode 100644 next/concepts/glossary/N/index.html delete mode 100644 next/concepts/glossary/O/index.html delete mode 100644 next/concepts/glossary/P/index.html delete mode 100644 next/concepts/glossary/Q/index.html delete mode 100644 next/concepts/glossary/R/index.html delete mode 100644 next/concepts/glossary/S/index.html delete mode 100644 next/concepts/glossary/T/index.html delete mode 100644 next/concepts/glossary/U/index.html delete mode 100644 next/concepts/glossary/V/index.html delete mode 100644 next/concepts/glossary/W/index.html delete mode 100644 next/concepts/glossary/X/index.html delete mode 100644 next/concepts/glossary/Y/index.html delete mode 100644 next/concepts/glossary/Z/index.html delete mode 100644 next/concepts/index.html delete mode 100644 next/concepts/intro-to-dapps/index.html delete mode 100644 next/concepts/list-auth-keys/index.html delete mode 100644 next/concepts/serialization/index.html delete mode 100644 next/concepts/smart-contracts/index.html delete mode 100644 next/counter-testnet/index.html delete mode 100644 next/counter/index.html delete mode 100644 next/design/index.html delete mode 100644 next/developers/cli/execution-error-codes/index.html delete mode 100644 next/developers/cli/index.html delete mode 100644 next/developers/cli/transfers/index.html delete mode 100644 next/developers/cli/verifying-contracts/index.html delete mode 100644 next/developers/dapps/dapp/index.html delete mode 100644 next/developers/dapps/index.html delete mode 100644 next/developers/dapps/prerequisites/index.html delete mode 100644 next/developers/dapps/sdk/csharp-sdk/index.html delete mode 100644 next/developers/dapps/signing-a-transaction/index.html delete mode 100644 next/developers/dapps/speculative-exec/index.html delete mode 100644 next/developers/dapps/technology-stack/index.html delete mode 100644 next/developers/essential-crates/index.html delete mode 100644 next/developers/index.html delete mode 100644 next/developers/json-rpc/errors/index.html delete mode 100644 next/developers/json-rpc/guidance/index.html delete mode 100644 next/developers/json-rpc/index.html delete mode 100644 next/developers/json-rpc/minimal-compliance/index.html delete mode 100644 next/developers/json-rpc/types_cl/index.html delete mode 100644 next/developers/writing-onchain-code/calling-contracts/index.html delete mode 100644 next/developers/writing-onchain-code/contract-vs-session/index.html delete mode 100644 next/developers/writing-onchain-code/upgrading-contracts/index.html delete mode 100644 next/economics/index.html delete mode 100644 next/glossary/index.html delete mode 100644 next/index.html delete mode 100644 next/operators/becoming-a-validator/inactive-vs-faulty/index.html delete mode 100644 next/operators/becoming-a-validator/index.html delete mode 100644 next/operators/index.html delete mode 100644 next/operators/maintenance/index.html delete mode 100644 next/operators/setup-network/genesis/index.html delete mode 100644 next/operators/setup-network/index.html delete mode 100644 next/operators/setup/fast-sync/index.html delete mode 100644 next/operators/setup/hardware/index.html delete mode 100644 next/operators/setup/index.html delete mode 100644 next/operators/setup/node-events/index.html delete mode 100644 next/operators/setup/non-root-user/index.html delete mode 100644 next/operators/setup/upgrade/index.html delete mode 100644 next/resources/advanced/multi-sig/index.html delete mode 100644 next/resources/beginner/counter-testnet/overview/index.html delete mode 100644 next/resources/beginner/counter/overview/index.html delete mode 100644 next/resources/build-on-casper/introduction/index.html delete mode 100644 next/resources/changelog/index.html delete mode 100644 next/resources/index.html delete mode 100644 next/resources/tokens/cep18/quickstart-guide/index.html delete mode 100644 next/resources/tokens/cep78/reverse-lookup/index.html delete mode 100644 next/resources/tokens/index.html delete mode 100644 next/resources/tutorials/advanced/index.html delete mode 100644 next/resources/tutorials/beginner/getting-started-tutorial/index.html delete mode 100644 next/resources/tutorials/beginner/index.html delete mode 100644 next/runtime/index.html delete mode 100644 next/sdk/index.html delete mode 100644 next/users/block-explorer/index.html delete mode 100644 next/users/csprlive/index.html delete mode 100644 next/users/delegate-ui/index.html delete mode 100644 next/users/funding-from-exchanges/index.html delete mode 100644 next/users/index.html delete mode 100644 next/users/ledger/index.html delete mode 100644 next/users/testnet-faucet/index.html delete mode 100644 next/users/token-transfer/index.html delete mode 100644 next/users/undelegate-ui/index.html delete mode 100644 next/workflow/ledger-setup/index.html delete mode 100644 next/writing-contracts/index.html rename {next/operators => operators}/becoming-a-validator/change-bid-public-key/index.html (70%) rename {next/operators => operators}/setup/casper-sidecar/index.html (61%) create mode 100644 operators/setup/node-events/index.html create mode 100644 resources/changelog/index.html delete mode 100644 resources/tokens/cep78/using-casper-client/quickstart-guide/index.html delete mode 100644 resources/tokens/cep78/using-casper-client/testing-NFTs/index.html rename {next/resources => resources}/tokens/using-casper-client/index.html (64%) delete mode 100644 staking/index.html rename {next/transactions-and-transaction-lifecycle => transactions-and-transaction-lifecycle}/index.html (56%) rename {next/transactions => transactions}/index.html (80%) rename {next/users => users}/delegating/index.html (54%) diff --git a/1.5.X/concepts/accounts-and-keys/index.html b/1.5.X/concepts/accounts-and-keys/index.html new file mode 100644 index 000000000..fa7dcbc88 --- /dev/null +++ b/1.5.X/concepts/accounts-and-keys/index.html @@ -0,0 +1,112 @@ + + + + + +Accounts and Keys | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

import useBaseUrl from '@docusaurus/useBaseUrl';

+

Accounts and Cryptographic Keys

+

The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.

+

By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

+

The Casper platform supports two types of keys for creating accounts and signing transactions:

+
    +
  • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
  • +
  • Secp256k1 keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain
  • +
+

You can generate keys using both formats, and it is also possible to work with existing Ethereum keys.

+

You can also generate an account hash from a public key with the Casper command-line client.

+

Creating Accounts and Keys

+

When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the Casper command-line client or a block explorer. Developers must use the Casper command-line client as described below. Otherwise, they won't have access to the secret key file needed during development.

+
note

SAVE your keys to a safe place, preferably offline.

+

Option 1: Generating keys using the Casper Client

+

This option describes how you can use the Casper command-line client to set up an account using either key type.

+

EdDSA Keys

+

The command-line client generates EdDSA keys by default. Use the command below to create the account.

+
mkdir ed25519-keys
casper-client keygen ed25519-keys/
tree ed25519-keys/
+

Sample output of the tree command shows the contents of the ed25519-keys folder:

+
ed25519-keys/
├── public_key.pem
├── public_key_hex
└── secret_key.pem

0 directories, 3 files
+

Here are some details about the files generated:

+
    +
  1. public_key.pem is a PEM-encoded public key
  2. +
  3. public_key_hex is a hexadecimal-encoded string of the public key
  4. +
  5. secret_key.pem is the PEM-encoded secret key
  6. +
+

The public-key-hex for Ed25519 keys starts with 01 and is 66 bytes long:

+
cat ed25519-keys/public_key_hex
011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd
+

ECDSA Keys

+

To create Secp256k1 keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:

+
mkdir secp256k1-keys
casper-client keygen -a secp256k1 secp256k1-keys/
tree secp256k1-keys/
+

Sample output of the tree command shows the contents of the secp256k1-keys folder:

+
secp256k1-keys/
├── public_key.pem
├── public_key_hex
└── secret_key.pem

0 directories, 3 files
+

The public-key-hex for Secp256k1 keys starts with 02 and is 68 bytes long:

+
cat secp256k1-keys/public_key_hex
020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d
+
note

After generating keys for the account, you may add funds to the account's purse to finish the account creation process.

+

Option 2: Generating keys using a block explorer

+

This option is available on networks that have a block explorer.

+

For instance, on the official Testnet, the CSPR.live block explorer is available, and the following instructions assume you are using it.

+

Start by creating an account using the Casper Wallet, Ledger, or Torus Wallet.

+
caution

Developers must generate keys using the Casper command-line client to access the secret_key.pem file.

The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined here.

+

Funding your Account

+

Once you create your account, you can fund the account's main purse to finish the process of setting it up.

+
note

Until you fund your account's main purse, it does not exist on the blockchain.

+

Working with Existing Ethereum Keys

+

You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:

+
Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F
Public key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66
Private key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086
+

To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a Secp256k1 type. To achieve this, we will prefix the public key hex with 02, as shown in the example below.

+

The Casper command-line client provides an example of how this works.

+

Example:

+

The following transaction sends 10 CSPR.

+
casper-client transfer \
--transfer-id 1234567 \
--node-address http://localhost:7777 \
--chain-name casper \
--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \
--amount 10000000000 \
--secret-key <path-to-secret_key.pem> \
--payment-amount 100000000
+
tip

The payment amount varies based on each deploy and network chainspec.

+

The Casper command-line client requires the secret key in PEM format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to PEM format is needed.

+

The following example is a JS script that generates a PEM file, using a key encoder and Node.js. To install these components, do the following:

+
sudo apt install nodejs
npm install key-encoder
+

Then create the JS script convert-to-pem.js using vi or nano, and include this content:

+
var KeyEncoder = require("key-encoder"),
keyEncoder = new KeyEncoder.default("secp256k1");
let priv_hex = "THE SECRET KEY TO ENCODE";
let priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");
console.log(priv_pem);
+

Then run the script using Node.js and name the secret key.

+
node convert-to-pem.js > eth-secret.pem
+

To view the secret key, use cat <filename>:

+
cat eth-secret.pem
+

Below is the sample output showing the contents of the secret key.

+
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK
oUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF
tlKF2V5RFQn4rzkwipSYnrqaPf1pTA==
-----END EC PRIVATE KEY-----
+

Option 3: Generating keys using OpenSSL

+

You can generate keys without the Casper client using the openssl cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system.

+

Generating the secret_key.pem file

+
openssl genpkey -algorithm ed25519 -out secret_key.pem
+

Generating public keys from the secret_key.pem file

+

For default Ed25519 keys, you can generate the public_key.pem and public_key_hex using these commands:

+
openssl pkey -in secret_key.pem -pubout -out public_key.pem

{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve '/1 "%02x" ' | tr -d "/n"; } > public_key_hex
+

Generating an Account Hash

+

To generate the account hash for a public key, use the account-address option of the Casper client. The argument for the public-key must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the keygen command: public_key_hex or public_key.pem.

+
casper-client account-address --public-key <FORMATTED STRING or PATH>
+

Finding the Main Purse URef

+

You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse.

+

Using the Casper CLI client

+

With the casper-client, use the get-account-info subcommand.

+
casper-client get-account-info \
--node-address <HOST:PORT> \
--public-key <FORMATTED STRING or PATH>
+
    +
  1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
  2. +
  3. public-key - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the keygen subcommand; "public_key_hex" or "public_key.pem"
  4. +
+
Sample command and output
+ +
casper-client get-account-info --node-address http://65.21.75.254:7777  --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db
{
"id": -2018234245556346849,
"jsonrpc": "2.0",
"result": {
"account": {
"account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",
"action_thresholds": {
"deployment": 1,
"key_management": 1
},
"associated_keys": [
{
"account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",
"weight": 1
}
],
"main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",
"named_keys": []
},
"api_version": "1.4.15",
"merkle_proof": "[29712 hex chars]"
}
}

+
+

Run the following help command for more details:

+
casper-client get-account-info --help
+

Using a block explorer

+

Using the block explorer for Mainnet or Testnet, open the Account in question, and expand the Raw Data section. Look for the main_purse field and find the corresponding URef. If you do not see data in the Raw Data section, then the account has not been funded yet.

+

Image showing an account&#39;s main purse

+ + \ No newline at end of file diff --git a/1.5.X/concepts/callstack/index.html b/1.5.X/concepts/callstack/index.html new file mode 100644 index 000000000..b1a903b7c --- /dev/null +++ b/1.5.X/concepts/callstack/index.html @@ -0,0 +1,33 @@ + + + + + +Call Stacks | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Understanding Call Stacks

+

Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.

+

When the session code within a Deploy interacts with one or more contracts, this is the beginning of a Call Stack. A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code.

+

The Caller

+

In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the zeroth entity in each call stack. The account that initiated the deploy can be retrieved with the contract_api::runtime::get_caller function.

+

The Call Stack

+

Developers can access the call stack with the contract_api::runtime::get_call_stack function.

+

If session code calls a contract, which in turn calls another contract, then the session code would represent the zeroth entity in the stack, the contract called by the initiating session code would be the first and the contract called by the first contract would be the second.

+

In this example, the first contract would be the immediate caller of the second contract, meaning it interacted directly with it. The session code would remain the caller.

+

+

Limitations

+

Casper networks place a limitation on the maximum height of a call stack. This value can be set within the chainspec for the network in question. For the Casper Mainnet, this limit is set at 10 contracts. This does not include the initiating session code, which would still count as the zeroth instance within the stack.

+

As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation.

+
note

Contract code cannot call session code, only other contract code.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/design/casper-design/index.html b/1.5.X/concepts/design/casper-design/index.html new file mode 100644 index 000000000..b582f9b21 --- /dev/null +++ b/1.5.X/concepts/design/casper-design/index.html @@ -0,0 +1,237 @@ + + + + + +Network Design | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

import useBaseUrl from '@docusaurus/useBaseUrl';

+

Casper Network Design

+

Introduction

+

Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a Deploy. Deploys contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

+

A deploy executes in the context of the user's Account but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an Unforgeable Reference or URef. After a node accepts a deploy as valid, it places the deploy in a proposed Block and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy.

+
    +
  1. +

    Execution Semantics

    +
  2. +
  3. +

    Accounts

    +
  4. +
  5. +

    Unforgeable Reference (URef)

    +
  6. +
  7. +

    Block Structure

    +
  8. +
  9. +

    Tokens

    +
  10. +
+

Execution Semantics

+

A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model.

+

Measuring Computational Work

+

Computation is done in a WebAssembly (Wasm) interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses Gas to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a Gas cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter.

+

Costs for opcode instructions on the Casper Mainnet network can be found here.

+

All executions are finite because each has a finite gas limit that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy.

+

Although the network measures costs in Gas, payment for computation occurs in motes. Therefore, there is a conversion rate between Gas and motes.

+
note

Please note that Casper will not refund any amount of unused gas.

This decision is taken to incentivize the Casper Runtime Economics by efficiently allocating the computational resources. The consensus-before-execution model implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys.

+

The Casper Network Runtime

+

A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state.

+

Casper Network Runtime

+

All these features are accessible via functions in the Casper External FFI.

+

Generating URefs

+

URefs are generated using a cryptographically secure random number generator using the ChaCha algorithm. The random number generator is seeded by taking the blake2b256 hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same deploy).

+

Generating URefs

+

Accounts

+

The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The global state trie store requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants.

+

The Casper platform supports two types of keys for creating accounts and signing transactions:

+
    +
  • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
  • +
  • Secp256k1 keys, commonly known as Ethereum keys, which are 68 bytes long
  • +
+

By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see Tokens for more information).

+

This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts.

+

Creating an account

+

Account creation automatically happens upon transferring tokens to a yet unused PublicKey. On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the PublicKey used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse.

+

Account Data Structure

+

An Account contains the following data:

+
    +
  • A URef representing the account's "main purse"
  • +
  • A collection of named keys (playing the same role as the named keys in a stored contract)
  • +
  • A collection of "associated keys" (see below for more information)
  • +
  • "Action thresholds" (see below for more information)
  • +
+

Permissions Model

+

Actions and Thresholds

+

An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place.

+

The ActionThresholds contained in the Account data structure set a Weight, which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold.

+

Associated Keys and Weights

+

Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's associated keys are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.

+
note

Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.

+

Key Management Actions

+

A key management action is a change to the account permissions, including:

+
    +
  • Adding or removing an associated key
  • +
  • Changing the weight of an associated key
  • +
  • Changing the threshold of any action
  • +
+

Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys.

+

Account security and recovery using key management

+

This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone.

+
note

It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").

+

The Account Context

+

A deploy is a user request to perform some execution on the blockchain (see Execution Semantics for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account's context.

+
note

In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account.

+

Unforgeable Reference (URef)

+

This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

+

Permissions for URefs

+

In the runtime, a URef carries its permissions called AccessRights. Additionally, the runtime tracks what AccessRights would be valid for each URef in each context. The system assumes that a sent URef is invalid, regardless of declared AccessRights, and will check it against the executing context to determine validity on each usage. Only the host logic can add a URef, in the following ways:

+
    +
  • It can exist in a set of "known" URefs
  • +
  • It can be freshly created by the runtime via the new_uref function
  • +
  • For called contracts, the caller can pass it in via the arguments to call_contract
  • +
  • It can be returned to the caller from call_contract via the ret function
  • +
+

Note that only valid URefs may be added to the known URefs or cross-call boundaries; this means the system cannot be tricked into accepting a forged URef by getting it through a contract or stashing it in the known URefs.

+

The ability to pass URefs between contexts via call_contract / ret, allows them to share state among a fixed number of parties while keeping it private from all others.

+

URefs and Purses

+

Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual accounts do not own ‘URef’s. As described above, accounts and contracts possess certain Access Rights, allowing them to interact with the given URef. While an account will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

+

Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required.

+

Block Structure

+

A block is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure.

+

Data Fields

+

A block consists of the following:

+
    +
  • A block_hash
  • +
  • A header
  • +
  • A body
  • +
+

Each of these fields is detailed in the subsequent sections.

+

block_hash

+

The block_hash is the blake2b256 hash of the block header.

+ +

The block header contains the following fields:

+
    +
  • +

    parent_hash

    +

    A list of block_hashes giving the parents of the block.

    +
  • +
  • +

    state_root_hash

    +

    The global state root hash produced by executing this block's body.

    +
  • +
  • +

    body_hash

    +

    The hash of the block body.

    +
  • +
  • +

    random_bit

    +

    A boolean needed for initializing a future era.

    +
  • +
  • +

    accumulated_seed

    +

    A seed needed for initializing a future era.

    +
  • +
  • +

    era_end

    +

    Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field.

    +
  • +
  • +

    timestamp

    +

    The timestamp from when the block was proposed.

    +
  • +
  • +

    era_id

    +

    Era ID in which this block was created.

    +
  • +
  • +

    height

    +

    The height of this block, i.e., the number of ancestors.

    +
  • +
  • +

    protocol_version

    +

    The version of the Casper network when this block was proposed.

    +
  • +
+

Body

+

The block body contains an ordered list of DeployHashes which refer to deploys, and an ordered list of DeployHashes for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no deploys and / or native transfers.

+

The block body also contains the public key of the validator that proposed the block.

+

Refer to the Serialization Standard for additional information on how blocks and deploy are serialized.

+

Tokens

+

Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called Highway. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

+

This chapter describes tokens and how one can use them on the Casper platform.

+

Token Generation and Distribution

+

A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available here. In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage.

+

The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis.

+

Token Lifecycle

+

Divisibility of Tokens

+

Typically, a token is divisible into some number of parts. We call the indivisible units which make up the CSPR token motes. Each CSPR is divisible into 109 motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 1018 parts called Wei.

+

The concept of CSPR is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with motes.

+

Purses and Accounts

+

All accounts on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the source and the main purse of the account at the provided key as the target.

+

The Casper Mint Contract

+

The Casper mint is a system contract that manages the balance of motes within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's main purse. Each balance is associated with a URef, which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as purses and conceptually represent a container for motes. The URef is how a purse is referenced externally, outside the mint.

+

The AccessRights of the URefs permissions model determines what actions can be performed when using a URef associated with a purse.

+

As all URefs 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:

+ + + + + + + + + + + + + + + + + + + + + +
Global StateAction Monetary Action
AddDeposit (i.e. transfer to)
WriteWithdraw (i.e. transfer from)
ReadBalance check
+

The mint Contract Interface

+

The mint system contract exposes the following methods:

+
    +
  • transfer(source: URef, target: URef, amount: Motes) -> TransferResult +
      +
    • source must have at least Write access rights, target must have at least Add access rights
    • +
    • TransferResult may be a success acknowledgment or an error in the case of invalid source or target or insufficient balance in the source purse
    • +
    +
  • +
  • mint(amount: Motes) -> MintResult +
      +
    • MintResult either gives the created URef (with full access rights), which now has a balance equal to the given amount; or an error due to the minting of new motes not being allowed
    • +
    • In the Casper mint, only the system account can call mint, and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account
    • +
    +
  • +
  • create() -> URef +
      +
    • a convenience function for mint(0) which cannot fail because it is always allowed to create an empty purse
    • +
    +
  • +
  • balance(purse: URef) -> Option<Motes> +
      +
    • purse must have at least Read access rights
    • +
    • BalanceResult either returns the number of motes held by the purse, or nothing if the URef is not valid
    • +
    +
  • +
+ + \ No newline at end of file diff --git a/1.5.X/concepts/design/highway/index.html b/1.5.X/concepts/design/highway/index.html new file mode 100644 index 000000000..5aa3df042 --- /dev/null +++ b/1.5.X/concepts/design/highway/index.html @@ -0,0 +1,58 @@ + + + + + +Highway Consensus | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

The Highway Consensus Protocol

+

What is Consensus?

+

Consensus is the backbone of any distributed network. The decentralized nature of a blockchain requires a method through which disparate entities can agree on one immutable truth. This involves determining the validity of transactions, resolving conflicts, and finalizing blocks to be added to the chain by the network. A consensus protocol is a set of mechanisms and rules within the distributed network with which all actors must comply.

+

These rules outline the type of messages sent over the network, when they are sent and how to process them. Within the context of a blockchain, the consensus protocol decides which blocks are added to the chain by the network and the order in which they are added. This determines the state of the distributed ledger and ensures that all nodes agree on that state.

+

The consensus mechanism will determine how a blockchain meets the following requirements:

+
    +
  • +

    Safety - All honest nodes eventually agree on the final value. The system is setup in a way where no two honest nodes will report two different blocks at the same height of the blockchain.

    +
  • +
  • +

    Liveness - The system continues running and adds new blocks to the chain indefinitely.

    +
  • +
+

What is Highway Consensus?

+

Casper networks use a consensus protocol called Highway, ensuring the Safety and Liveness requirements of these networks. Highway is a Byzantine Fault Tolerant protocol requiring a partially synchronous network.

+

How does the Casper Mainnet use Highway?

+

The Casper Mainnet is a Proof-of-Stake network in which the on-chain auction contract determines validators participating in Highway. The protocol uses a decentralized network of nodes, either bonded or unbonded. Nodes actively participating in the consensus process must stake CSPR tokens and are known as Validator Nodes. The top 100 bidders are selected through the auction contract every era to act as validators in the era after the next (Current Era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus. Highway does not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model.

+

These validators run a Casper network that will continue to function so long as the amount of faulty or dishonest nodes does not exceed one-third of the total number of nodes in the network. Nodes that are not faulty are honest nodes. In most cases, the system can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly. A block's fault tolerance increases beyond one-third as the protocol continues. If all validators are honest, it approaches 100%.

+

Dynamic Round Length

+

Within the Highway protocol, the length of a round is determined dynamically to ensure a suitable amount of time for nodes to gossip all messages through several round trips with honest validators. This ensures that the system maintains liveness by ensuring that all messages are properly gossiped while maintaining a timely addition of blocks to the chain.

+

Eras

+

The concept of eras allows Highway to reduce the overall operational storage requirements of participating nodes while also rotating validators. A new instance of Highway runs every two hours or approximately 220 blocks, depending on current network metrics. This allows for two benefits:

+
    +
  • +

    Data Reduction - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.

    +
  • +
  • +

    Banning Equivocators - Dishonest nodes caught equivocating in a previous era are banned from participating in new eras. This allows honest nodes to begin a new era in the relaxed mode, no longer needing to send endorsements due to past equivocations.

    +
  • +
  • +

    Rotating Validators - Bonded nodes bid on validator spots each era, with the top 100 highest bidders becoming validators for the era after next (N+2).

    +
  • +
+

In any given era, node operators will bid to become validators that will participate in the consensus mechanism for the era after next (N+2). Each time slot within the era will also determine a lead validator. The lead validator proposes new blocks to be added to the chain, which are then gossiped among the network's nodes. These messages show an implicit preference for the lead validator's block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. Once this process reaches critical mass, with a sufficient interconnected pattern of messages, it becomes impossible to switch to another block. The selected block is then considered finalized and added to the chain.

+

The final block of an era is a switch block and forms the initial state of the next era. A new Highway instance begins with the new era, using information contained within the switch block and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the Consensus Economics page.

+

Finality

+

Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require greater than 1/3 of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart.

+

On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously.

+

Highway's criterion for detecting finality is the presence of a pattern of messages called a Summit. It is an improvement over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect. Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/design/networking-protocol/index.html b/1.5.X/concepts/design/networking-protocol/index.html new file mode 100644 index 000000000..21cb4f863 --- /dev/null +++ b/1.5.X/concepts/design/networking-protocol/index.html @@ -0,0 +1,209 @@ + + + + + +Casper Node Networking Protocol | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Casper Node Networking Protocol

+

Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)

+

This is a description of the casper-node's networking protocol. This document follows the conventions laid out in RFC2119.

+

Connection Level

+

Any casper-node taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate.

+

Reciprocity, retries and data direction

+

A connection that was initiated by a node is considered an outgoing connection by the node itself, but an incoming connection by all other peers.

+

A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time.

+

A node that receives an incoming connection MUST eventually establish an outgoing connection to the node.

+

A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second.

+

Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes.

+

TLS parameters

+

Any node creating a connection to a node MUST present a client certificate with the following properties:

+
    +
  • Signature algorithm: ECDSA_WITH_SHA512
  • +
  • Subject name: Same as issuer name (self-signed certificate!)
  • +
  • Serial number: 1
  • +
  • Expiration ("not before"): Must be earlier than current time.
  • +
  • Expiration ("not after"): Must be later than current time.
  • +
  • Signature: Must be using SECP521R1 with SHA512 and valid.
  • +
+

The SHA512 fingerprint of the public key is considered the NodeID of the node.

+

Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node.

+

An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done.

+

Discovery

+

A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication.

+

Every node SHOULD have one or more so-called known node addresses of other nodes configured.

+

On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address.

+

Every node MUST periodically gossip its own node address to the network (see gossiping below).

+

A node learns new node addresses through receiving a gossiped node address, or being told of an address through the handshake.

+

Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it.

+

After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called forgetting a node. An address that has been forgotten will be considered new the next time it is learned.

+

A node MUST NOT forget the known addresses it was configured with initially.

+

Framing

+

To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first.

+

A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection.

+

Encoding

+

The node uses three encoding schemes: Handshakes (see below) are encoded using MessagePack, while regular messages are encoded using bincode. Many (but not all) data objects use bytesrepr for serialization.

+

The node uses the rmp-serde crate, version 0.14.4, which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node.

+

All nodes MUST use the following settings for bincode encoding of network messages:

+
    +
  • Byte limit: Unlimited
  • +
  • Endianness: Little Endian
  • +
  • Integer Encoding: Varint
  • +
  • Trailing Bytes: Not allowed
  • +
+

Any other use of bincode encoding (e.g. for GetRequest payloads, see below) MUST use the following bincode encoding settings:

+
    +
  • Byte limit: Unlimited
  • +
  • Endianness: Little Endian
  • +
  • Integer Encoding: Fixint
  • +
  • Trailing Bytes: Allowed
  • +
+

Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard serde-derived encoding. For bytesrepr serialization refer to the specific implementations in the bytesrepr crate.

+

Any data types given from here on out are described using simplified Rust structure definitions.

+

The Message Type

+

The following data types make up the networking protocol:

+
enum Message {
Handshake {
network_name: String,
public_addr: SocketAddr,
// default: 1.0
protocol_version: ProtocolVersion,
// default: `None`
consensus_certificate: Option<ConsensusCertificate>,
// default: false
is_syncing: bool,
// default: `None`
chainspec_hash: Option<Digest>,
},
Payload(Payload),
}

struct ConsensusCertificate {
public_key: PublicKey,
signature: Signature,
}

struct Digest([u8; 32]);
+

For String, SocketAddr, ProtocolVersion, Option, PublicKey, Signature see the respective docs and details below.

+

Handshake Behavior

+

A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections).

+

A handshake MUST be encoded using the Message::Handshake structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (protocol_version, consensus_certificate, is_syncing, chainspec_hash). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults.

+

After receiving a handshake, a node MUST compare the network_name, protocol_version and chainspec_hash fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it.

+

A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of is_syncing set to true as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.

+

A node MAY compare peers that provide a consensus_certificate to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited.

+

Upon handshake completion, the node SHOULD learn the provided public_addr.

+

Blocking Nodes

+

If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake.

+

A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour.

+

After a block on a node is expired, the node SHOULD forget the nodes IP address, allowing a later learning of said address again.

+

The Payload Type

+

The Payload (found in the node sources as Message in payload.rs) contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in bincode encoding, this should have no effect on implementations.

+
enum Payload {
Consensus(ConsensusMessage),
DeployGossiper(DeployGossiperMessage),
AddressGossiper(AddressGossiperMessage),
GetRequest {
tag: Tag,
serialized_id: Vec<u8>,
},
GetResponse {
tag: Tag,
serialized_item: Vec<[u8]>,
},
FinalitySignature(FinalitySignature),
}

enum DeployGossiperMessage {
Gossip(DeployHash),
GossipResponse {
item_id: DeployHash,
is_already_held: bool,
},
}

enum AddressGossiperMessage {
Gossip(GossippedAddress),
GossipResponse {
item_id: GossippedAddress,
is_already_held: bool,
},
}

struct DeployHash(Digest);
struct GossipedAddress(SocketAddr);
+

Consensus

+

A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the consensus::Message type or an appropriate description of the underlying protocol for details.

+

Gossiping

+

Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address.

+

A node must support a gossiper for deploys and one for GossippedAddress, which is an alias for the regular Rust standard library's SocketAddr.

+

A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an AddressGossiperMessage::Gossip message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details.

+

Unsafe-for-syncing

+

A node that is syncing MUST indicate this by setting is_syncing to true.

+

A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of TrieNodes that can cause issues with peers that are also sending GetRequests.

+

A node that succeeds in a handshake with a peer that has set is_syncing MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for TrieNodes.

+

Gossiping

+

Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed.

+

Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself.

+

Gossiper messages have the following structure:

+
enum GossiperMessage {
Gossip(Id),
GossipResponse {
item_id: Id,
is_already_held: bool,
},
}
+

To gossip, a node MAY send a GossiperMessage::Gossip message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a GossiperMessage:GossipResponse, citing the given id and using is_already_held to indicate whether it already possessed the given item.

+

The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers.

+

The node that initiated the gossip MUST keep track of which peer replied with a positive (is_already_held being true) response and MUST NOT send another Gossip message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again.

+

If a node receives a negative GossiperMessage::GossipResponse (i.e. is_already_held being false), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a GetRequest for the item (see GetRequests section below).

+

GetRequests

+

The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.

+

A peer MAY send a GetRequest (see Payload::GetRequest) with a Tag and serialized_id payload. Both serialized_id and serialized_item MUST be encoded using bincode (see "Encoding" section for details).

+
pub enum Tag {
Deploy,
FinalizedApprovals,
Block,
GossipedAddress,
BlockAndMetadataByHeight,
BlockHeaderByHash,
BlockHeaderAndFinalitySignaturesByHeight,
TrieOrChunk,
BlockAndDeploysByHash,
BlockHeaderBatch,
FinalitySignaturesByHash,
}
+

The tag dictates which item is being retrieved, and which key (ID type) is being used.

+

A node that receives a GetRequest from a peer SHOULD return a GetResponse (see Payload::GetResponse). The GetResponse MUST use the same Tag.

+
pub enum FetchedOrNotFound<T, Id> {
Fetched(T),
NotFound(Id),
}
+

If the item was found, serialized_item MUST contain a serialized FetchedOrNotFound::Fetched instance, with the inner value T being the item.

+

If the item was not found, serialized_item MUST contain a FetchedOrNotFound::NotFound instance, with the inner value Id being the ID found in the originating GetRequest.

+

A node MUST not send any items to a peer that it itself has not verified.

+

The following table shows which tag corresponds to which ID and item type. Type definitions for DeployHash and GossippedAddress can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the Serialization Standard, but be aware that those docs describe serializing using bytesrepr rather than bincode.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TagID typePayload (item) type
DeployDeployHashDeploy
FinalizedApprovalsDeployHashFinalizedApprovalsWithId
BlockBlockHashBlock
GossipedAddressGossipedAddressGossipedAddress
BlockAndMetadataByHeightu64BlockWithMetadata
BlockHeaderByHashBlockHashBlockHeader
BlockHeaderAndFinalitySignaturesByHeightu64BlockHeaderWithMetadata
TrieOrChunkTrieOrChunkIdTrieOrChunk
BlockAndDeploysByHashBlockHashBlockAndDeploys
BlockHeaderBatchBlockHeadersBatchIdBlockHeadersBatch
FinalitySignaturesByHashBlockHashBlockSignatures
+
pub struct Deploy {
hash: DeployHash,
header: DeployHeader,
payment: ExecutableDeployItem,
session: ExecutableDeployItem,
approvals: BTreeSet<Approval>,
}

struct DeployHeader {
account: PublicKey,
timestamp: u64,
ttl: u64,
gas_price: u64,
body_hash: Digest,
dependencies: Vec<DeployHash>,
chain_name: String,
}

enum PublicKey {
System,
Ed25519(Vec<u8>),
Secp256k1(Vec<u8>),
}

enum ExecutableDeployItem {
ModuleBytes {
module_bytes: Vec<u8>,
args: RuntimeArgs,
},
StoredContractByHash {
hash: [u8; 32],
entry_point: String,
args: RuntimeArgs,
},
StoredContractByName {
name: String,
entry_point: String,
args: RuntimeArgs,
},
StoredVersionedContractByHash {
hash: [u8; 32],
version: Option<u32>,
entry_point: String,
args: RuntimeArgs,
},
StoredVersionedContractByName {
name: String,
version: Option<u32>,
entry_point: String,
args: RuntimeArgs,
},
Transfer { args: RuntimeArgs },
}

struct RuntimeArgs(Vec<NamedArg>);

struct NamedArg(String, CLValue);

struct CLValue(CLType, Vec<u8>);

enum CLType {
Bool,
I32,
I64,
U8,
U32,
U64,
U128,
U256,
U512,
Unit,
String,
Key,
URef,
PublicKey,
Option(Box<CLType>),
List(Box<CLType>),
ByteArray(u32),
Result { ok: Box<CLType>, err: Box<CLType> },
Map { key: Box<CLType>, value: Box<CLType> },
Tuple1([Box<CLType>; 1]),
Tuple2([Box<CLType>; 2]),
Tuple3([Box<CLType>; 3]),
Any,
}

struct Approval {
signer: PublicKey,
signature: Signature,
}

enum Signature {
System,
Ed25519(Vec<u8>),
Secp256k1(Vec<u8>),
}

struct FinalizedApprovalsWithId {
id: DeployHash,
approvals: FinalizedApprovals,
}

struct FinalizedApprovals(BTreeSet<Approval>);

struct Block {
hash: BlockHash,
header: BlockHeader,
body: BlockBody,
}

struct BlockHash(Digest);

struct BlockHeader {
parent_hash: BlockHash,
state_root_hash: Digest,
body_hash: Digest,
random_bit: bool,
accumulated_seed: Digest,
era_end: Option<EraEnd>,
timestamp: u64,
era_id: u64,
height: u64,
protocol_version: ProtocolVersion,
}

struct EraEnd {
era_report: EraReport,
next_era_validator_weights: BTreeMap<PublicKey, U512>,
}

struct EraReport<VID> {
equivocators: Vec<PublicKey>,
rewards: BTreeMap<PublicKey, u64>,
inactive_validators: Vec<PublicKey>,
}

struct ProtocolVersion {
major: u32,
minor: u32,
patch: u32,
}

struct BlockBody {
proposer: PublicKey,
deploy_hashes: Vec<DeployHash>,
transfer_hashes: Vec<DeployHash>,
}
+

Custom variable length encoding is used when serializing U512, U256 and U128 types. They are encoded in a way equivalent to encoding the following pseudo struct:

+
struct Bigint {
serialized_length: u8,
little_endian_unpadded_bytes: [u8, serialized_length - 1],
}
+

In other words, the following steps are taken:

+
    +
  • convert the bigint to an array of bytes in little-endian form
  • +
  • strip the contiguous range of irrelevant padding 0 bytes from the right hand end, if any
  • +
  • prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself
  • +
+

For a description explaining the use of TrieOrChunk and related types, see the "Trie chunking" section. The relevant types are:

+
struct TrieOrChunkId(u64, Digest);

enum TrieOrChunk {
Trie(Bytes),
ChunkWithProof(ChunkWithProof),
}

struct ChunkWithProof {
proof: IndexedMerkleProof,
chunk: Bytes,
}

struct IndexedMerkleProof {
index: u64,
count: u64,
merkle_proof: Vec<Digest>,
}
+

BlockHeadersBatchId is used to request multiple BlockHeaders with a single request.

+
struct BlockHeadersBatchId {
highest: u64,
lowest: u64,
}

struct BlockWithMetadata {
block: Block,
finality_signatures: BlockSignatures,
}

struct BlockHeaderWithMetadata {
block_header: BlockHeader,
block_signatures: BlockSignatures,
}

struct BlockSignatures {
block_hash: BlockHash,
era_id: u64,
proofs: BTreeMap<PublicKey, Signature>,
}

struct BlockAndDeploys {
block: Block,
deploys: Vec<Deploy>,
}

struct BlockHeadersBatch(Vec<BlockHeader>);
+

Finality Signatures

+

The Payload::FinalitySignature variant is used when broadcasting finality signatures.

+

A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates.

+

Trie Chunking

+

Large trie nodes are split when transferred across the network, according to CHUNK_SIZE_BYTES, which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a TrieOrChunk::Trie instance.

+

Should a trie node be larger than this, a Merkle tree is constructed with CHUNK_SIZE_BYTES sized chunks and is identified by the root hash of the resulting tree instead.

+

Peers MUST only request chunks. The TrieOrChunkId type allows for requesting the n-th chunk of a given trie node. See the casper-hashing crate for details.

+

A node receiving a TrieOrChunk item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/design/p2p/index.html b/1.5.X/concepts/design/p2p/index.html new file mode 100644 index 000000000..8fad15997 --- /dev/null +++ b/1.5.X/concepts/design/p2p/index.html @@ -0,0 +1,53 @@ + + + + + +Network Communication | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Network Communication

+

Identity

+

Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID.

+

Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint.

+

Inter-node connections

+

Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the client and the remote node the server for this connection.

+

During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks.

+

Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected.

+

Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see Node Discovery on how the server finds endpoints).

+

Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it.

+

Network

+

As soon as a node has connected to one node in the network, it partakes in Node Discovery. In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network.

+

Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below.

+

In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped.

+

Gossiping

+

Multiple types of objects are gossipped, the most prominent ones being blocks, deploys, and endpoints (see Identity). Each of these objects is immutable and can be identified by a unique hash.

+

Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed.

+

The process can be summarized as follows:

+

Given a message M to gossip, the desired saturation S, and an infection limit L:

+
    +
  1. Pick a subset T of K nodes from all currently connected nodes.
  2. +
  3. Send M to each node in T, noting which nodes were already infected (a node is considered infected if it already had received or known M).
  4. +
  5. For every node shown as already infected, add another random node outside to T and send it M, again noting the response.
  6. +
  7. End when we confirm infection of L new nodes or encountered S already infected nodes.
  8. +
+

Through this process, a message will spread to almost all nodes over time.

+

Requesting missing data

+

While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing deploy from a block.

+

Validation

+

Objects have a concept of dependencies. For example, a block depends on all the deploys whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node.

+

Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved.

+

Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so.

+

Node Discovery

+

Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/index.html b/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/index.html new file mode 100644 index 000000000..11d7f068d --- /dev/null +++ b/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/index.html @@ -0,0 +1,36 @@ + + + + + +Reading and Writing Data | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Reading and Writing Data to Global State

+

Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.

+
note

Due to the nature of Casper's serialization standard, NamedKeys should be used sparingly and only for small data sets. Developers should use dictionaries for larger mapped structures.

+

Using the Casper JSON-RPC

+

The query_global_state method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the Querying a Casper Network tutorial.

+

Using the Casper Rust API

+

The Casper API includes the following functions for reading and writing to global state:

+
    +
  • put_key - Stores the given Key under the given name in the current context's named keys
  • +
  • get_key - Returns the requested NamedKey from the current context
  • +
  • storage::new_uref - Creates a new URef in the current context
  • +
  • storage::write - Writes a given value under a previously created URef
  • +
  • storage::read - Reads the value from a URef in global state
  • +
  • dictionary_put - Writes the given value under the given dictionary_item_key
  • +
  • dictionary_get - Retrieves the value stored under a dictionary_item_key
  • +
+

For more details, see the Reading and Writing to Global State using Rust tutorial.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/dictionaries/index.html b/1.5.X/concepts/dictionaries/index.html new file mode 100644 index 000000000..8090f9a81 --- /dev/null +++ b/1.5.X/concepts/dictionaries/index.html @@ -0,0 +1,84 @@ + + + + + +Dictionaries | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Understanding Dictionaries

+

In a Casper network, you can now store sets of data under Keys. Previously, URefs were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an Account or Contract context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated NamedKeys structures.

+

Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs.

+

As a solution to this problem, the Casper platform provides the Dictionary feature, which allows users a more efficient and scalable means to aggregate data over time.

+

In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost.

+

Seed URefs

+

Items within a dictionary exist as individual records stored underneath their unique dictionary address in global state. In other words, items associated with a specific dictionary share the same seed URef but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key.

+

As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef.

+

Using Dictionaries

+

Dictionaries are ideal for storing larger volumes of data for which NamedKeys would be less suitable.

+

Creating a new dictionary is fairly simple and done within the context of a Deploy sent to a Casper network. The associated code is included within the casper_contract crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context.

+

Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract.

+

While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional Deploy removing those access rights, but it is better to create the dictionary within the context of the Contract.

+

Dictionaries allow a contract to store additional data without drastically expanding the size of the NamedKeys within their context. If a contract's NamedKeys expand too far, they may run into system limitations that would unintentionally disable the contract's functionality.

+

A dictionary item key can be no longer than 64 bytes in length.

+

Practical Dictionary Examples

+

The Casper CEP-78 Enhanced NFT Standard includes several practical applications of dictionaries.

+

Simple examples for dictionary use within CEP-78 include the approve dictionary.

+

More advanced dictionary functionality can be found in the CEP-78 Page System, which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract.

+

Creating Dictionaries in a Contract's Context

+

The following code snippet shows the most basic example of creating a dictionary.

+

casper_contract::contract_api::storage::new_dictionary(dict_name)

+

The following example includes the creation of a dictionary "ledger" within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the init entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point.

+

#[no_mangle]
pub extern "C" fn init() {
let fundraising_purse = system::create_purse();
runtime::put_key("fundraising_purse", fundraising_purse.into());
// Create a dictionary to track the mapping of account hashes to number of donations made.
storage::new_dictionary("ledger").unwrap_or_revert();
}

+

Writing Entries into a Dictionary

+

After the creation of a dictionary, you may then add entries through the use of the following code:

+

storage::dictionary_put(dictionary_uref, &dictionary_item_key, value);

+

The dictionary_uref refers to the seed URef established during the dictionary creation process. The key is the unique identifier for this dictionary item, and the value is the data to be stored within the dictionary.

+

As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first.

+

The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item.

+

The first section acquiring the LEDGER seed URef to assign the new dictionary item to the proper dictionary.

+

fn update_ledger_record(dictionary_item_key: String) {
// Acquiring the LEDGER seed URef to properly assign the dictionary item.
let ledger_seed_uref = *runtime::get_key("ledger")
.unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)
.as_uref()
.unwrap_or_revert();

+

The second section uses dictionary_get to read an entry within the LEDGER dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a dictionary_put operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost.

+

// This identifies an item within the dictionary and either creates or updates the associated value.
match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()
{
None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),
Some(current_number_of_donations) => storage::dictionary_put(
ledger_seed_uref,
&dictionary_item_key,
current_number_of_donations + 1u64,
),
}
}

+

Reading Items from a Dictionary using the JSON-RPC

+

The Casper platform provides several means of looking up a dictionary item. These means are explained within the DictionaryIdentifier JSON-RPC type. The following explains how to query the dictionary items using the Casper client.

+

ContractNamedKey lookup via a Contract's named keys.

+

Reading a dictionary item using the Contract's NamedKeys requires the following parameters:

+
    +
  • +

    Node Address - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network.

    +
  • +
  • +

    State Root Hash - The current state root hash of a Casper network hosting the dictionary item you are attempting to read.

    +
  • +
  • +

    Contract Hash - The hash of the contract that references the dictionary in its NamedKeys.

    +
  • +
  • +

    Dictionary Name - The name of the dictionary as a String stored in the Contract's NamedKeys.

    +
  • +
  • +

    Dictionary Item Key - The specific dictionary item key to be read, as a String.

    +
  • +
+

casper-client get-dictionary-item \
--node-address http://localhost:11101 \
--state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
--contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \
--dictionary-name <String> \
--dictionary-item-key <String>

+

URef lookup via the dictionary's seed URef.

+

Reading a dictionary item using the dictionary's seed URef requires the Node Address, State Root Hash and Dictionary Item Key as above. However, it does not require the Contract Hash or Dictionary Name. Instead, it requires:

+
    +
  • Seed URef - The Seed URef of the dictionary to reference.
  • +
+

casper-client get-dictionary-item \
--node-address http://localhost:11101 \
--state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
--dictionary-item-key <String> \
--seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007

+

Dictionary lookup via the unique dictionary item key.

+

In the event that you know the dictionary address of the dictionary item key you need to read, you can read it directly using the following Casper client command.

+

casper-client get-dictionary-item \
--node-address http://localhost:11101 \
--state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
--dictionary-address dictionary-<string>

+ + \ No newline at end of file diff --git a/1.5.X/concepts/economics/concepts/index.html b/1.5.X/concepts/economics/concepts/index.html new file mode 100644 index 000000000..9e86df264 --- /dev/null +++ b/1.5.X/concepts/economics/concepts/index.html @@ -0,0 +1,31 @@ + + + + + +Staking Concepts | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Staking Concepts

+

The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.

+

Consensus mechanism: Casper operates using a Proof-of-Stake consensus mechanism per the Highway Protocol, a specification of Correct-by-Construction Casper (CBC Casper).

+

Number of validators: The Casper Mainnet supports up to 100 validators on the network. This number is chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through a process of permission-less bonding by participating in an auction for the validator slot.

+

Permission-less bonding: For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permission-less, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens.

+

Unbonding: To detach from a Casper network, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards during the seven eras required for unbonding, as they are not actively contributing to the network's security during that time.

+

Eras and block times: An era on Casper is roughly 2 hours long. Casper's Highway protocol allows validators to propose blocks as quickly as network conditions allow, subject to a platform-wide limit that may be adjusted with upgrades. We anticipate block times to last between thirty seconds and eight minutes.

+

Block rewards: Block time is orthogonal to rewards, so there is no precise reward per block. Instead, the number of rewards is split proportionally among stakes and reduced for failure to participate in the protocol promptly.

+

Reward cycle: Rewards are distributed to validators and delegators once per era.

+

Token supply and inflation: Mainnet launched with ten billion CSPR at the time of genesis. The target annual supply growth rate is 8%.

+

Annual reward percentage: Validators on the Casper Mainnet earn between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes is dependent on total active stake, as only a fixed number of tokens is created per era.

+

Please visit the Staking Guide for further details on the staking mechanism.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/economics/consensus/index.html b/1.5.X/concepts/economics/consensus/index.html new file mode 100644 index 000000000..5c4af75f1 --- /dev/null +++ b/1.5.X/concepts/economics/consensus/index.html @@ -0,0 +1,78 @@ + + + + + +Consensus | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Consensus Economics

+

Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.

+

Entry

+

After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a chainspec configuration file specifies a few key parameters:

+
    +
  • The auction_delay specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the auction_delay is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era.
  • +
  • The validator_slots parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids.
  • +
+

Bids

+

Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the unbonding_delay chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners.

+

Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document.

+

Delegation

+

Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate.

+

Currently, delegation is unrestricted. Please visit Delegation details page to check more about delegation cost and related details.

+

Incentives

+

Correct operation of the Highway protocol requires the economics of the platform to discourage equivocation for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals.

+

Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future.

+

The network incentivizes participation by scaling rewards for on-time proposals and responses, taking into account the speed of finalizing blocks. All rewards are added directly to the corresponding bids and delegations.

+

Participation

+

Issuance of new tokens and their distribution to validators incentivizes work even under low transaction load.

+

CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:

+
    +
  • The growth of CSPR supply is exponential
  • +
  • Issuance takes into account slashed CSPR
  • +
+

With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:

+
    +
  • i - the era's index as a positive integer [0, 1, 2, ..., n]
  • +
  • initial_supply - the number of CSPR at genesis
  • +
  • issuance_rate - the annual rate at which new CSPR tokens are minted
  • +
  • ticks_per_year - the number of milliseconds in a year equal to 31,536,000,000
  • +
+
supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)
+

We introduce the round issuance rate (corresponding to the chainspec parameter round_seigniorage_rate) with this formula:

+
round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1
+

The round issuance rate is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter minimum_round_exponent. For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds.

+

Finally, the base round reward is computed as:

+
base_round_reward(i) = round_issuance_rate * supply(i)
+

This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block.

+

Distribution

+

Validators receive tokens for proposing and finalizing blocks according to their performance. The concept of weight is crucial for understanding this distribution scheme:

+
    +
  • Weight: A validator's bonded stake, used in consensus
  • +
  • Assigned weight of a block/round: The total stake of validators scheduled to participate in a block
  • +
  • Participated weight of a block/round: The total stake of validators that end up participating or sending messages to finalize a block before the end of their respective round
  • +
+

To determine eligibility, we look at on-time finalization (OTF). Validators should finalize blocks on time by sending required messages before the end of their respective round.

+

Switch blocks are not visible to the issuance calculation (as this calculation is performed in the switch block itself for each era), and, consequently, no tokens are issued for switch blocks.

+
Participation schedule
+

The participation schedule is segmented into rounds, which are allocated dynamically according to the validators' exponents and a deterministic (randomized at era start) assignment of validators to milliseconds of an era. Thus, a validator with the round exponent n must participate in rounds that repeat every 2^n ticks.

+

Each validator is assessed according to its round exponent. All assigned validators become eligible to receive tokens as long as the block gets finalized with messages sent within each validator's round.

+
Eligibility
+

Once a block has been proposed and enough time has passed, the history of protocol messages can be examined to detect whether the block was finalized on time, according to the conditions given above. If the block was not finalized on time, validators receive a fraction of the expected tokens, governed by the reduced_reward_multiplier chainspec parameter. If the block was finalized on time, assigned validators share the reward proportionally to their stake, regardless of whether they have sent messages or not.

+

Inactivity

+

Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special deploy that reactivates their bid.

+

Slashing

+

Please review our Equivocator Policy. We are currently conducting research into the utility of slashing as an incentive mechanism.

+

Founding validators

+

Founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days, then releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/economics/delegation/index.html b/1.5.X/concepts/economics/delegation/index.html new file mode 100644 index 000000000..cd2a92b6b --- /dev/null +++ b/1.5.X/concepts/economics/delegation/index.html @@ -0,0 +1,42 @@ + + + + + +Delegation Details | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Delegation Details

+

This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.

+

Delegation Cost

+

The delegation cost is defined in the chainspec.toml file for each Casper network. In this example chainspec, the delegation is set to cost 2.5 CSPR. However, when you perform the delegation, you see that it costs a little more than what is specified in the chainspec. Let’s discuss why this happens.

+

When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is addition to the delegation cost defined in the chainspec file.

+

For example, the chainspec file in release 1.3.2 will contain the following information. This is how the delegation cost is defined in the chainspec.toml file of a Casper network.

+

Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network

+

Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network
+

+

Delegation fees may change over time, so, it is essential to stay up to date. To do so, select the latest release in Github, and navigate to the chainspec.toml file.

+

If you are unsure about anything, please join the Discord channel to ask us questions.

+

First-time Delegation

+

If you perform the delegation for the first time, the system charges some gas to create a purse to hold the delegated tokens.

+

Example: The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on Mainnet

+

It is essential to have enough funds in your account's main purse when you set up a delegation transaction. Otherwise, the transaction will fail, and you will lose the transfer cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer.

+

As a result, when performing a delegation using the command line, we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure.

+

Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR +Delegation Details

+
+

NOTE:

+

Transaction costs depend on each Casper network and the cost tables defined in the chainspec. The examples you will find in the documentation are general.

+
+

Lastly, we recommend that you try out delegations on the Casper Testnet before making actual transactions on the Casper Mainnet. This way, you will understand the costs involved in delegating tokens.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/economics/gas-concepts/index.html b/1.5.X/concepts/economics/gas-concepts/index.html new file mode 100644 index 000000000..eaa9bfd3d --- /dev/null +++ b/1.5.X/concepts/economics/gas-concepts/index.html @@ -0,0 +1,54 @@ + + + + + +Gas Cost | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Gas and Resources

+

What is gas?

+

Gas is a conceptual measure of resources utilized when executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide in order to execute a transaction.

+

Gas fees are consumed on the network irrespective of whether your transaction was successful or not. Even when a transaction fails, you have to pay the transaction fee because your deploy consumed resources and space on the block as the validator attempted to execute it on your behalf.

+

How is gas cost determined?

+

The amount of gas required for a transaction is determined by how much code is executed on the blockchain. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. The gas charged for a transaction on the blockchain is paid to the network's validators.

+

Why do we need gas cost?

+

Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:

+
    +
  • Rate-limiting is used to ensure a secure and live network: +
      +
    • It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting is used to control the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves in a similar fashion, because each block permits only a fixed amount of transactions (gas) to be included in the era.
    • +
    • It explicitly quantifies the system load. The gas cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators.
    • +
    +
  • +
  • Pricing leads to more meaningful transactions: +
      +
    • Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each deploy.
    • +
    +
  • +
+

Why do I see an ‘Out of gas error’?

+

You might encounter an ‘Out of gas error’ when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.

+

Here is an example of a transaction resulting in an ‘Out of gas error’ on the Mainnet.

+

Figure 1: In the Deploys tab of an account on cspr.live, a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an 'Out of gas error'.

+

+

Figure 2: Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully.

+

+

Figure 3: Click the Show raw data button, to see more details about the deploy. Towards the end of the raw data, you can see the error message.

+

+

How do I determine the gas cost for a transaction?

+

Currently, we are hard at work to create tools to help you estimate gas costs. Meanwhile, we recommend using the NCTL tool on your local machine or the Testnet to deploy your contracts in a test environment. You can check a deploy status and roughly see how much it would actually cost when deployed. You can estimate the costs in this way and then add a small buffer if the network state has changed. Note that when estimating gas cost locally or on the Testnet, the blockchain specification needs to match the specification of the Mainnet, where you will need to pay for the transaction with actual Casper (CSPR) tokens.

+

Why do I see a gas limit error?

+

You may sometimes see an error such as ‘payment: 2.5, cost: 2.5, Error::GasLimit’, This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error. Let’s explore this error message a little further.

+

When a smart contract hits its gas limit (the payment amount), execution stops. If your limit is 2.5 CSPR, execution stops and that is the computation cost even if the smart contract did not run to completion. So, the error message tries to communicate to you that execution stopped at 2.5 CSPR. The computation resulted in an error because there were not enough funds to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution there and charged you that much, even though it was a failed transaction. The execution engine does not actually know how much it would have cost if allowed to run to completion, because it did not allow the contract to finish since the contract would have run over its gas limit.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/global-state/index.html b/1.5.X/concepts/global-state/index.html new file mode 100644 index 000000000..3b4276a3a --- /dev/null +++ b/1.5.X/concepts/global-state/index.html @@ -0,0 +1,42 @@ + + + + + +Global State | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Global State

+

Introduction

+

The storage layer for the Casper blockchain is called global state and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly.

+
note

Refer to Keys and Permissions for further information on keys.

+

Each finalized block causes changes to the network's global state because of the execution of the deploys it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a Merkle trie.

+

Merkle Trie Structure

+

Global State

+

At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes.

+

Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value.

+

Formally, a trie node is one of the following:

+
    +
  • a leaf, which includes a key and a value
  • +
  • a branch, which has up to 256 blake2b256 hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)
  • +
  • an extension node, which includes a byte array (called the affix) and a blake2b256 hash pointing to another node in the trie
  • +
+

The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node.

+

The Rust implementation of Casper's trie can be found on GitHub:

+ +
note

Conceptually, each block has its trie because the state changes based on the deploys it contains. For this reason, Casper's implementation has a notion of a TrieStore, which allows us to look up the root node for each trie.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/A/index.html b/1.5.X/concepts/glossary/A/index.html new file mode 100644 index 000000000..ee41bd3ec --- /dev/null +++ b/1.5.X/concepts/glossary/A/index.html @@ -0,0 +1,35 @@ + + + + + +A | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

A

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Account

+

An Account is a structure that represents a user on a Casper network. Information on creating an account can be found here.

+

Account Hash

+

The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found here.

+

AssemblyScript

+

AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using asc, the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community.

+

Auction

+

The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.

+

Auction contract

+

The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction.

+

Auction delay

+

The number of full eras that pass between the booking block and the era whose validator set it defines. The auction delay is configurable and can be several eras long.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/B/index.html b/1.5.X/concepts/glossary/B/index.html new file mode 100644 index 000000000..942e7629d --- /dev/null +++ b/1.5.X/concepts/glossary/B/index.html @@ -0,0 +1,63 @@ + + + + + +B | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

B

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Blake2b

+

A function used within the Casper platform to create cryptographic hashes. More information can be found here.

+

Block

+

Used in two contexts:

+
    +
  1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain.
  2. +
  3. A message that is exchanged between nodes containing the data structure as explained in (1).
  4. +
+

Each block has a globally unique ID, achieved by hashing the contents of the block.

+

Each block points to its parent. An exception is the first block, which has no parent.

+

Block creation

+

Block creation means computing the deployment results and collecting the results that belong together into a block. We follow a process called execution after consensus.

+

The block proposal happens first, and the proposed proto block contains a set of deploys that have not been executed yet.

+

Only after consensus on a proto block has been reached, the deploys are executed. The resulting new global state root hash is put into an actual block, together with the executed deploys.

+

Note that only validators can create valid blocks.

+

Block finality

+

A block is "finalized" if the validators agree on adding it to the blockchain.

+

There are different levels of finality in the Highway protocol. A finalized block has a fault-tolerance F, expressed as a fraction of the total stake. For an observer to see a conflicting block as finalized, several validators whose total stake exceeds F would have to collude and show different information in a way that would ultimately be detected and punished (see slashing).

+

Block gossiping

+

Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms block gossiping and block passing are interchangeable.

+

Block height

+

Block height is an identifier for a given block based on the number of blocks completed prior to that block.

+

Block passing

+

See block gossiping.

+

Block processing

+

Block processing consists of running the deploys in a block received from another node to determine updates to the global state. Note that this is an essential part of validating blocks.

+

Block proposal

+

Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only.

+

Block validation

+

The process of determining the validity of a block obtained from another node on the network.

+

Blockchain

+

Blockchain is a P2P network where the collection of nodes (validators) concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of transactions. For performance reasons, transactions are bundled in blocks. According to a particular cooperation protocol (consensus protocol), the collection of nodes connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the global state and has a sizeable map-like collection.

+

Block store

+

The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash.

+

Bond

+

The amount of money (in crypto-currency) that is allocated by a node in order to participate in consensus (and to be a validator).

+

Bonding

+

Depositing money in the auction contract and try to become a staker. The bonding request is a transaction that transfers tokens to the auction contract. In the next booking block, a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block.

+

Booking block

+

The booking block for an era is the block that determines the era's validator set. In it, the auction contract selects the highest bidders to be the future era's validators. There is a configurable delay, the auction_delay, which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era N + auction_delay + 1 is the last block of era N.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/C/index.html b/1.5.X/concepts/glossary/C/index.html new file mode 100644 index 000000000..4f72bad80 --- /dev/null +++ b/1.5.X/concepts/glossary/C/index.html @@ -0,0 +1,46 @@ + + + + + +C | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

C

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Cargo

+

Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies.

+

Casper network

+

Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found here.

+

CBC

+

Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:

+
    +
  • All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval.
  • +
  • The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted.
  • +
+

Chainspec

+

A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. Here is an example chainspec, which will change with newer releases.

+

Consensus

+

An algorithm used to mandate agreement on the blockchain between all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not.

+

Casper uses the Highway algorithm in the CBC Casper family of consensus algorithms. The algorithm for securing an agreement is what is known as consensus. The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer.

+

Contract runtime

+

Enables developers to use a seamless workflow for authoring and testing their smart contracts. This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices.

+

Correct by construction

+

See CBC.

+

Crate

+

A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, rustc, the compiler for the Rust programming language, will produce a binary from a crate.

+

CSPR

+

CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for staking (securing the network).

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/D/index.html b/1.5.X/concepts/glossary/D/index.html new file mode 100644 index 000000000..27f5d7f0a --- /dev/null +++ b/1.5.X/concepts/glossary/D/index.html @@ -0,0 +1,36 @@ + + + + + +D | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

D

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

dApp

+

A decentralized application (dApp) employs smart contracts installed on a decentralized peer-to-peer network such as a blockchain.

+

Delegation rate

+

Node operators (validators) define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services.

+

Delegator

+

Delegators are users who participate in the platform's security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

+

Deploy

+

Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network.

+

All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the global state.

+

Review the deploy data structure and the deploy implementation for more details.

+

Dictionary

+

A Dictionary is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to NamedKeys.

+

More information can be found in the Reading and Writing to Dictionaries document.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/E/index.html b/1.5.X/concepts/glossary/E/index.html new file mode 100644 index 000000000..bd18e91f6 --- /dev/null +++ b/1.5.X/concepts/glossary/E/index.html @@ -0,0 +1,34 @@ + + + + + +E | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

E

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Ecosystem

+

The ecosystem layer in Casper encompasses dApp design and operation.

+

Entry point

+

See EntryPoint and Defining the Contract Entry Points.

+

Era

+

A period of time during which the validator set does not change.

+

In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an auction. At the beginning of the era, the validators create a new instance of the Highway protocol and run this consensus protocol until they finalize the era's last block (see booking block).

+

Eviction

+

Validators that fail to participate in era will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the auction contract.

+

External client

+

Any hardware/software connecting to a Node for the purpose of sending deploys or querying the state of the blockchain.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/F/index.html b/1.5.X/concepts/glossary/F/index.html new file mode 100644 index 000000000..70f164707 --- /dev/null +++ b/1.5.X/concepts/glossary/F/index.html @@ -0,0 +1,27 @@ + + + + + +F | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

F

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Finality

+

See block finality.

+

Fungible

+

A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a non-fungible token, where each token is unique and not interchangeable.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/G/index.html b/1.5.X/concepts/glossary/G/index.html new file mode 100644 index 000000000..afb7d2e9f --- /dev/null +++ b/1.5.X/concepts/glossary/G/index.html @@ -0,0 +1,39 @@ + + + + + +G | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

G

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Gas

+

Gas is the virtual currency for calculating the cost of transaction execution. The transaction cost is expressed as a given amount of gas consumed and can be seen intuitively as some cycles of the virtual processor that has to be used to run the computation defined as the transaction's code.

+

Genesis

+

The state of the virtual machine at the beginning of the blockchain.

+

Groups

+

The user groups feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:

+
    +
  • User groups associate a set of URefs with a label.
  • +
  • The entry points on a contract can accept a list of labels
  • +
  • The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution.
  • +
+

Global state

+

When thinking of a blockchain as a decentralized computer, the global state is its memory state.

+

When thinking of a blockchain as a shared database, the global state is the snapshot of the database's data.

+

Technically, a global state is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs).

+

For every block B in the blockchain, one can compute the global state achieved by executing all transactions in this block and its ancestors. The root hash identifying this state is stored in every executed block.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/H/index.html b/1.5.X/concepts/glossary/H/index.html new file mode 100644 index 000000000..29dcc1c26 --- /dev/null +++ b/1.5.X/concepts/glossary/H/index.html @@ -0,0 +1,27 @@ + + + + + +H | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

H

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Hash

+

A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the blake2b function.

+

Highway

+

A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is finalized. The full paper is found in GitHub: https://github.com/casper-network/highway.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/I/index.html b/1.5.X/concepts/glossary/I/index.html new file mode 100644 index 000000000..48c49ab17 --- /dev/null +++ b/1.5.X/concepts/glossary/I/index.html @@ -0,0 +1,23 @@ + + + + + +I | Casper Docs - Redux + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/J/index.html b/1.5.X/concepts/glossary/J/index.html new file mode 100644 index 000000000..53f57eabb --- /dev/null +++ b/1.5.X/concepts/glossary/J/index.html @@ -0,0 +1,25 @@ + + + + + +J | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

J

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

JSON

+

JSON (JavaScript Object Notation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found here.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/K/index.html b/1.5.X/concepts/glossary/K/index.html new file mode 100644 index 000000000..ab1479b63 --- /dev/null +++ b/1.5.X/concepts/glossary/K/index.html @@ -0,0 +1,25 @@ + + + + + +K | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

K

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Key

+

Keys are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found here.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/L/index.html b/1.5.X/concepts/glossary/L/index.html new file mode 100644 index 000000000..fc9c36c9f --- /dev/null +++ b/1.5.X/concepts/glossary/L/index.html @@ -0,0 +1,26 @@ + + + + + +L | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

L

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Liveness

+

A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions).

+

If the protocol is not live, the blockchain does not grow anymore, and the network stalls.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/M/index.html b/1.5.X/concepts/glossary/M/index.html new file mode 100644 index 000000000..b4d77e5d7 --- /dev/null +++ b/1.5.X/concepts/glossary/M/index.html @@ -0,0 +1,31 @@ + + + + + +M | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

M

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Mainnet

+

The live, decentralized, and public Casper platform, with version 1.0.

+

Merkle tree

+

A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes.

+

Motes

+

A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the CSPR token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes.

+

Multi-Sig

+

Short for Multi-Signature. Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for deploys. More information on the use of Multi-Sig can be found here.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/N/index.html b/1.5.X/concepts/glossary/N/index.html new file mode 100644 index 000000000..b1bace23a --- /dev/null +++ b/1.5.X/concepts/glossary/N/index.html @@ -0,0 +1,41 @@ + + + + + +N | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

N

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

NamedKeys

+

NamedKeys +are a collection of String-Key pairs used to easily identify some data on the network.

+
    +
  • The String is the name given to identify the data
  • +
  • The Key is the data to be referenced
  • +
+

Node

+

A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data.

+

You will encounter different types of nodes on the network:

+
    +
  • Bonded node: a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era.
  • +
  • Unbonded node: a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization).
  • +
+

Node operator

+

See operator.

+

Non-Fungible Token (NFT)

+

Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/O/index.html b/1.5.X/concepts/glossary/O/index.html new file mode 100644 index 000000000..4dd2209b1 --- /dev/null +++ b/1.5.X/concepts/glossary/O/index.html @@ -0,0 +1,28 @@ + + + + + +O | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

O

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Operator

+

Anyone running a node is an operator.

+

An operator that has staked a bid but does not currently have a validator slot is a *staked operator*.

+

An operator whose bid has won a validator slot in the auction for a specific era is a validator in that era.

+

It is common for a staked operator to win an auction slot for many eras in a row and thus be a validator for a range of eras.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/P/index.html b/1.5.X/concepts/glossary/P/index.html new file mode 100644 index 000000000..9678674de --- /dev/null +++ b/1.5.X/concepts/glossary/P/index.html @@ -0,0 +1,50 @@ + + + + + +P | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

P

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Partial synchrony

+

Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see CBC.

+

Participate in consensus

+

The process of following the consensus algorithm. The primary participants are validators, bonded with their stake and part of the validator set for that particular era. Delegators participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network.

+

Payment code

+

The payment code is the Wasm program that pays the transaction execution fee.

+

Peer node

+

A node on a peer-to-peer (P2P) network.

+

Permissionless

+

A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants.

+

Primary token

+

See CSPR.

+

Private key

+

See secret key.

+

Proof-of-Stake

+

Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain.

+

Proof-of-Work

+

A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed.

+

Proof-of-Stake contract

+

The Proof-of-Stake (PoS) contract holds on to transaction fees for the time while the state transition is happening (contracts are being executed). The PoS contract remits the transaction fees to the block proposer.

+

Proposer

+

The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain.

+

Proto block

+

The block proposed by the leader, which the consensus processes (in highway). Only after consensus is complete, the proto block is executed, and the global state is updated.

+

A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era.

+

Purse

+

A purse is a unique type of URef representing a token balance. An account's main purse represents the balance of CSPR tokens (in motes) the account has access to on a Casper network. An account may have more than one purse in some instances. More information on purses can be found here.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/Q/index.html b/1.5.X/concepts/glossary/Q/index.html new file mode 100644 index 000000000..9498acb74 --- /dev/null +++ b/1.5.X/concepts/glossary/Q/index.html @@ -0,0 +1,23 @@ + + + + + +Q | Casper Docs - Redux + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/R/index.html b/1.5.X/concepts/glossary/R/index.html new file mode 100644 index 000000000..00457399d --- /dev/null +++ b/1.5.X/concepts/glossary/R/index.html @@ -0,0 +1,31 @@ + + + + + +R | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

R

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Reward

+

Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's delegation rate. Rewards are distributed at the end of each era.

+

Root hash

+

The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to Merkle tree if you wish to learn more.

+

Rust

+

A programming language similar to C++, designed for performance and safety, especially safe concurrency.

+

Rustdocs

+

As part of the Rust development environment, the Rustdocs describe the Casper contracts library, the Casper types library, and the Casper test support library.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/S/index.html b/1.5.X/concepts/glossary/S/index.html new file mode 100644 index 000000000..d31e66818 --- /dev/null +++ b/1.5.X/concepts/glossary/S/index.html @@ -0,0 +1,51 @@ + + + + + +S | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

S

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Safe

+

When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see CBC.

+

Secret key

+

A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations).

+

Seigniorage

+

The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators.

+

Session code

+

Session code is Wasm executed in the context of an account through sending a Deploy. The session code contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state.

+

Slashing

+

In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets slashed, i.e., a part of it is removed.

+

Smart contract

+

Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party.

+

On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the global state. The execution of a smart contract causes changes to the global state.

+

A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values.

+

Smart-contract platform

+

A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts.

+

Staker

+

A person that deposits tokens in the proof-of-stake contract. A staker is either a validator or a delegator. Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their tokens by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is slashed, the staker will lose their tokens.

+

Staking

+

A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The Staking Guide highlights the steps required to stake CSPR tokens on the Casper Mainnet.

+

State root hash

+

The state root hash is an identifier of the network's global state at a moment in time. The state root hash changes with each block executed, containing deploys. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras.

+

Stateful

+

Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions.

+

Stateless

+

Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time.

+

Switch Block

+

A Switch Block is the final block in an era, which contains the era_summary. See also booking block.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/T/index.html b/1.5.X/concepts/glossary/T/index.html new file mode 100644 index 000000000..82c9b59be --- /dev/null +++ b/1.5.X/concepts/glossary/T/index.html @@ -0,0 +1,30 @@ + + + + + +T | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

T

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Token

+

A type of cryptocurrency that represents an asset. See CSPR.

+

Transaction

+

See deploy.

+

Turing-complete blockchain

+

Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets.

+

For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/U/index.html b/1.5.X/concepts/glossary/U/index.html new file mode 100644 index 000000000..33e741f9f --- /dev/null +++ b/1.5.X/concepts/glossary/U/index.html @@ -0,0 +1,29 @@ + + + + + +U | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

U

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Unbonding

+

Withdrawing money from the auction contract with withdraw bid and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed.

+

URef

+

An Unforgeable Reference, used by a Casper network to store any value other than Account. More information can be found here.

+

Users

+

Users execute session and contract code using the platform's computational resources.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/V/index.html b/1.5.X/concepts/glossary/V/index.html new file mode 100644 index 000000000..e94b7742b --- /dev/null +++ b/1.5.X/concepts/glossary/V/index.html @@ -0,0 +1,32 @@ + + + + + +V | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

V

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Validator

+

Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain's security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.

+

The responsibilities of a validator include:

+ +

Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending deploys). Validators and stakers can lose their bond (be slashed) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/W/index.html b/1.5.X/concepts/glossary/W/index.html new file mode 100644 index 000000000..6eb5acc4e --- /dev/null +++ b/1.5.X/concepts/glossary/W/index.html @@ -0,0 +1,27 @@ + + + + + +W | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

W

+
+

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

+
+

Web3

+

An advanced version of the internet based on decentralization and trustless interactions.

+

WebAssembly

+

WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/X/index.html b/1.5.X/concepts/glossary/X/index.html new file mode 100644 index 000000000..91d4e139b --- /dev/null +++ b/1.5.X/concepts/glossary/X/index.html @@ -0,0 +1,23 @@ + + + + + +X | Casper Docs - Redux + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/Y/index.html b/1.5.X/concepts/glossary/Y/index.html new file mode 100644 index 000000000..b3ee2ca8e --- /dev/null +++ b/1.5.X/concepts/glossary/Y/index.html @@ -0,0 +1,23 @@ + + + + + +Y | Casper Docs - Redux + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/1.5.X/concepts/glossary/Z/index.html b/1.5.X/concepts/glossary/Z/index.html new file mode 100644 index 000000000..ba05fa099 --- /dev/null +++ b/1.5.X/concepts/glossary/Z/index.html @@ -0,0 +1,23 @@ + + + + + +Z | Casper Docs - Redux + + + + + + + + + +
Skip to main content
+ + \ No newline at end of file diff --git a/1.5.X/concepts/hash-types/index.html b/1.5.X/concepts/hash-types/index.html new file mode 100644 index 000000000..f0a59d6c3 --- /dev/null +++ b/1.5.X/concepts/hash-types/index.html @@ -0,0 +1,133 @@ + + + + + +Hash Types | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Understanding Hash Types

+

For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.

+

Table of Associated Hash Types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TypePrefixExample
PublicKey018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c
AccountHashaccount-hash-account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
ContractHashcontract-contract-0101010101010101010101010101010101010101010101010101010101010101
ContractPackageHashcontract-package-contract-package-0101010101010101010101010101010101010101010101010101010101010101
Key::Accountaccount-hash-account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
Key::Hashhash-hash-0101010101010101010101010101010101010101010101010101010101010101
Key::URefuref-uref-0101010101010101010101010101010101010101010101010101010101010101-001
Key::Transfertransfer-transfer-0101010101010101010101010101010101010101010101010101010101010101
Key::DeployInfodeploy-deploy-0101010101010101010101010101010101010101010101010101010101010101
Key::EraInfoera-era-1
Key::Balancebalance-balance-0101010101010101010101010101010101010101010101010101010101010101
Key::Bidbid-bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
Key::Withdrawwithdraw-withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
Key::Dictionarydictionary-dictionary-0101010101010101010101010101010101010101010101010101010101010101
Key::SystemContractRegistrysystem-contract-registry-system-contract-registry-00000000000000000000000000000000
Key::EraSummaryera-summary-era-summary-00000000000000000000000000000000
+

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 the system and it is a single 00.

+

AccountHash is a 32 byte hash of the PublicKey serving to identify user accounts.

+

ContractHash is the 32 byte hash of specific smart contract versions. You can use this to call specific contract versions.

+

ContractPackageHash is a 32 byte hash of the smart contract package. This hash directs you to the contract package. The function call_versioned_contract uses ContractPackageHash and allows you to call the latest version of the contract (by default). It also allows you to call any version stored previously to the package.

+

Key is a wrapper type that may contain one of several possible sets of data.

+
    +
  • Key::Account contains an AccountHash.
  • +
  • Key::Hash contains a byte array with a length of 32, and as such can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for implementation of any checks necessary on the receiving side.
  • +
  • Key::URef contains an URef suffixed by access rights.
  • +
  • Key::Transfer should contain the address hash for a transfer.
  • +
  • Key::DeployInfo retains the address hash of deploy information.
  • +
  • Key::EraInfo is the integer number of the associated era.
  • +
  • Key::Balance is the balance of a purse.
  • +
  • Key::Bid is used to keep track of bids for the auction contract. It is not generally used by users.
  • +
  • Key::Withdraw is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context.
  • +
  • Key::Dictionary is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary.
  • +
  • Key::SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts, including Mint, Auction, HandlePayment and StandardPayment, is stored.
  • +
  • Key::EraSummary is a Key under which we store current era info.
  • +
+ + \ No newline at end of file diff --git a/1.5.X/concepts/index.html b/1.5.X/concepts/index.html new file mode 100644 index 000000000..69e747c98 --- /dev/null +++ b/1.5.X/concepts/index.html @@ -0,0 +1,95 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Concepts Overview

+

The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.

+

Concepts

+

This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TopicDescription
Introduction to the Casper BlockchainHigh-level details about the Casper blockchain
Introduction to dAppsDeveloping distributed applications on the Casper blockchain
Accounts and Cryptographic KeysThe Casper programming model is account-based. Learn how Casper accounts work and how they are secured
Hash TypesHashes are used throughout the Casper ecosystem for keys, addresses, packaging data, and more
Global StateLearn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state
Call StacksLearn how Casper manages the calling of a contract
Deploys and the Deploy LifecycleDeploys are a concept fundamental to the Casper blockchain. Learn about deploys, what they are for, how to create and send them
Smart ContractsLearn how to develop smart contracts on Casper
DictionariesLearn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform
SerializationLearn about serializing data types and the Casper Serialization Standard
DesignThe high-level design of a Casper network
EconomicsLearn about the Casper on-chain economics
GlossaryA compendium of all the terms used in Casper, in alphabetical order
+

Next Steps

+

After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories.

+

Developers

+

The Developers area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs.

+

Operators

+

The Operators section caters to those who want to run and administrate a Casper node or network.

+

Users

+

The Users section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device.

+

Resources

+

Navigate to Resources to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the beginner tutorials. Afterward, continue with more advanced tutorials to explore the multi-signature feature, runtime return values, and other essential features.

+ + \ No newline at end of file diff --git a/1.5.X/concepts/intro-to-dapps/index.html b/1.5.X/concepts/intro-to-dapps/index.html new file mode 100644 index 000000000..b71ba5623 --- /dev/null +++ b/1.5.X/concepts/intro-to-dapps/index.html @@ -0,0 +1,42 @@ + + + + + +dApps | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

Introduction to dApps

+

What is a dApp?

+

DApp stands for Decentralized Application. Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface.

+

A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

+

A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of nodes does the processing of smart contracts instead of a single central server.

+

Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

+

Interacting with a Casper Decentralized Network

+

For a dApp to integrate with a Casper network, it must be able to send Deploys via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. Sending a Deploy to a node will result in that node gossiping that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution.

+

A Deploy contains session code in the form of Wasm to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. +A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy.

+

Updating data in a Casper dApp

+

Sending a Deploy is the only means by which a dApp can change global state. All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

+

Post-Consensus Execution in a Casper network

+

Unlike other blockchain networks, a Casper network performs execution after consensus. This means that observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy.

+

Deploy lifecycle

+

There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The Deploy Lifecycle results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase.

+ +
+ + \ No newline at end of file diff --git a/1.5.X/concepts/list-auth-keys/index.html b/1.5.X/concepts/list-auth-keys/index.html new file mode 100644 index 000000000..fde18aeb9 --- /dev/null +++ b/1.5.X/concepts/list-auth-keys/index.html @@ -0,0 +1,40 @@ + + + + + +Authorization Keys | Casper Docs - Redux + + + + + + + + + +
Skip to main content
Version: 1.5.X

import useBaseUrl from '@docusaurus/useBaseUrl';

+

Authorization Keys

+

This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.

+

Associated Keys vs. Authorization Keys

+

Let's review the difference between associated keys to an Account and authorization keys for a Deploy.

+
    +
  • Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about associated keys and weights and try the Two-Party Multi-Signature tutorial.
  • +
  • Authorization keys are public keys used to sign a deploy and are listed in the Deploy's approvals. Authorization keys are a subset of the associated keys of the account under which the deploy is executed.
  • +
  • When a node receives a deploy, it checks that the deploy has the required authorization keys under approvals before including it in a block.
  • +
  • Different deploys executing the same smart contract can have different authorization keys.
  • +
+

Image showing associated keys and authorization keys

+

Here is a sample JSON representation of an Account's associated keys:

+
"associated_keys": [
{
"account_hash": "account-hash-1ab…11",
"weight": 1
},
{
"account_hash": "account-hash-2cd…22",
"weight": 1
},
{
"account_hash": "account-hash-3de…33",
"weight": 1
},
{
"account_hash": "account-hash-4fg…44",
"weight": 1
}
], ...
+

Here is a sample JSON representation of a Deploy's authorization keys:

+
"approvals": [
{
"signer": " 2cd...22",
"signature": "02df8c...f481"
},
{
"signer": "4fg...44",
"signature": "02ef21...756a"
}
]
+

Accessing Authorization Keys from a Smart Contract

+

Contract code can retrieve the set of authorization keys for a given deploy by calling the contract_api::runtime::list_authorization_keys function, which returns the set of account hashes representing the keys used to sign the deploy.

+

When to Use Authorization Keys

+

Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations.

+

Try the Working with Authorization Keys tutorial to view an example workflow.

+ + \ No newline at end of file diff --git a/concepts/serialization-standard/index.html b/1.5.X/concepts/serialization-standard/index.html similarity index 81% rename from concepts/serialization-standard/index.html rename to 1.5.X/concepts/serialization-standard/index.html index 610a6cf88..17e123384 100644 --- a/concepts/serialization-standard/index.html +++ b/1.5.X/concepts/serialization-standard/index.html @@ -3,19 +3,19 @@ -Serialization Standard | Casper Docs - Redux +Serialization Standard | Casper Docs - Redux - - + +
Skip to main content
Version: 1.5.X

Serialization Standard

+ submit an issue on Github
Version: 1.5.X

Serialization Standard

We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This document details how this custom serialization is implemented, allowing developers to build a library that implements the custom serialization.

In your smart contracts, you can implement serialization using cltype-any.

Account

@@ -281,7 +281,7 @@

Deploy-Header<
  • chain_name: Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below.
  • Payment & Session

    -

    Payment and Session are both defined as ExecutableDeployItems. More information on ExecutableDeployItems can be found here

    +

    Payment and Session are both defined as ExecutableDeployItems. More information on ExecutableDeployItems can be found here

    • Module Bytes are serialized such that the first byte within the serialized buffer is 0 with the rest of the buffer containing the bytes present.

      @@ -429,7 +429,7 @@

      GroupsURefs held within. The remainder consists of a repeating pattern of serialized user groups and BTreeSets of the length dictated by the first four bytes.

      Keys

      In this chapter, we describe what constitutes a "key", the permissions model for the keys, and how they are serialized.

      -

      A key in Global State is one of the following data types:

      +

      A key in Global State is one of the following data types:

      • 32-byte account identifier (called an "account identity key")
      • 32-byte immutable contract identifier (called a "hash key")
      • @@ -446,19 +446,19 @@

        EraInfo, which actually serializes as a u64 value with an additional byte for the tag.

        Account identity key

        -

        This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        +

        This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        Hash key

        -

        This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the blake2b256 hash of the deploy hash (see block-structure-head for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key.

        +

        This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the blake2b256 hash of the deploy hash (see block-structure-head for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key.

        Unforgeable Reference (URef)

        -

        URef broadly speaking can be used to store values and manage permissions to interact with the value stored under the URef. URef is a tuple which contains the address under which the values are stored and the Access rights to the URef. Refer to the Unforgeable Reference section for details on how URefs are managed.

        +

        URef broadly speaking can be used to store values and manage permissions to interact with the value stored under the URef. URef is a tuple which contains the address under which the values are stored and the Access rights to the URef. Refer to the Unforgeable Reference section for details on how URefs are managed.

        Transfer Key

        This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the transfer address associated with the given transfer

        DeployInfo Key

        This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the deploy itself.

        EraInfo Key

        This key type is used specifically for storing information related to the Auction metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive u64 data type and co-relates to the era number when the auction information was stored.

        -

        This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        -

        This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        +

        This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        +

        This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

        Serialization for Key

        Given the different variants for the over-arching Key data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant.

        @@ -602,7 +602,7 @@

        URef permissions on how permissions are handled in the case of URefs.

        +

        Refer to URef permissions on how permissions are handled in the case of URefs.

        NamedArg

        Named arguments to a contract. It is serialized by the combination of a String followed by the associated CLValue.

        NamedKey

        @@ -808,7 +808,7 @@

        accounts-head.

        +

        We discuss CLValue and contract in more detail below. Details about accounts can be found in accounts-head.

        Each StoredValue is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of StoredValue it is, followed by the serialization of that variant. The tag for each variant is as follows:

    - +
    warning

    When passing a URef to another entity on chain, you must ensure that the AccessRights are set correctly. If the URef represents a purse, AccessRights impact who can deposit and withdraw CSPR.

    If a passed URef contains ADD permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. WRITE permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove WRITE permissions. In this event, READ and ADD permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with WRITE permissions unintentionally.

    PublicKey

    PublicKey serializes as a single byte tag representing the algorithm followed by 32 bytes of the PublicKey itself:

    @@ -1054,7 +1054,7 @@

    Contr
  • a collection of named keys
  • a protocol version
  • -

    The wasm module must contain a function named call, which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the Casper runtime.

    +

    The wasm module must contain a function named call, which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the Casper runtime.

    Note: though the call function signature has no arguments and no return value, within the call function body, the get_named_arg runtime function can be used to accept arguments (by ordinal), and the ret runtime function can be used to return a single CLValue to the caller.

    The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the URefs, which are known to the contract (see the section on Permissions for details).

    Each contract specifies the Casper protocol version that was active when the contract was written to the global state.

    @@ -1076,6 +1076,6 @@

    WithdrawPurse<
  • amount The unbonding amount, serialized as a U512 value.

  • -

    +
    \ No newline at end of file diff --git a/1.5.X/concepts/smart-contracts/index.html b/1.5.X/concepts/smart-contracts/index.html new file mode 100644 index 000000000..7afc4583f --- /dev/null +++ b/1.5.X/concepts/smart-contracts/index.html @@ -0,0 +1,35 @@ + + + + + +Smart Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Smart Contracts

    +

    Smart Contracts in General

    +

    A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism.

    +

    Casper Smart Contracts

    +

    Casper smart contracts can be implemented in any programming language that compiles to Wasm, which can be installed and executed on-chain using Deploys. Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust here.

    +

    Session Code

    +

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either session code or another smart contract may call these entry points. Understand when you would use session code over contract code here.

    +

    Further Reading

    +
    + + \ No newline at end of file diff --git a/1.5.X/counter-testnet/index.html b/1.5.X/counter-testnet/index.html new file mode 100644 index 000000000..ab5c5967d --- /dev/null +++ b/1.5.X/counter-testnet/index.html @@ -0,0 +1,42 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    A Counter on the Testnet

    +

    This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    +

    Here is how the tutorial is structured:

    + +

    Prerequisites

    +
      +
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. +
    3. You have installed the Casper client to send deploys to the chain.
    4. +
    5. You were able to set up and fund an account on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial: +
        +
      • The location of your account’s secret_key.pem file
      • +
      • Your account hash identifier
      • +
      +
    6. +
    7. You selected a node whose RPC port will be receiving the deploys coming from your account.
    8. +
    +

    Video Tutorial

    +

    If you prefer a video walkthrough of this guide, you can check out this video.

    +
    + + \ No newline at end of file diff --git a/1.5.X/counter/index.html b/1.5.X/counter/index.html new file mode 100644 index 000000000..9db26721b --- /dev/null +++ b/1.5.X/counter/index.html @@ -0,0 +1,33 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    A Counter on an NCTL Network

    +

    This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    +

    Here is how the tutorial is structured:

    + +

    Prerequisites

    +
      +
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. +
    3. You have completed the NCTL tutorial, which introduces you to the CLI tool to set up and control local Casper networks for development.
    4. +
    5. You have installed the Casper client to send deploys to the chain.
    6. +
    + + \ No newline at end of file diff --git a/1.5.X/deploy-and-deploy-lifecycle/index.html b/1.5.X/deploy-and-deploy-lifecycle/index.html new file mode 100644 index 000000000..27e3eb0cd --- /dev/null +++ b/1.5.X/deploy-and-deploy-lifecycle/index.html @@ -0,0 +1,75 @@ + + + + + +Deploy Lifecycle | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Deploys and the Deploy Lifecycle

    +

    Deploys

    +

    A Deploy is a data structure containing Wasm and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy’s structure is as follows:

    +

    Structure of a Deploy

    +
      +
    • Body: Containing payment code and session code (more details on these below)
    • +
    • Header: containing +
        +
      • The Public Key of the account in whose context the deploy will run
      • +
      • The timestamp of the deploy’s creation
      • +
      • A time-to-live, after which the deploy expires and cannot be included in a block
      • +
      • the blake2b256 hash of the body
      • +
      +
    • +
    • Deploy hash: the blake2b hash of the Header
    • +
    • Approvals: the set of signatures which have signed the deploy hash; these are used in the account permissions model
    • +
    +

    The Deploy Lifecycle

    +

    A deploy goes through the following phases on Casper:

    +
      +
    1. Deploy Received
    2. +
    3. Deploy Gossiped
    4. +
    5. Block Proposed
    6. +
    7. Block Gossiped
    8. +
    9. Consensus Reached
    10. +
    11. Deploy Executed
    12. +
    +

    Deploy Received

    +

    A client sending the deploy will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given deploy matches configuration settings outlined in the network's chainspec. Deploy configuration for the Casper Mainnet can be found here. Once accepted, the system returns the deploy hash to the client to indicate it has been enqueued for execution. The deploy could expire while waiting to be gossiped; whenever this happens, a DeployExpired event is emitted by the event stream servers of all nodes which have the expired deploy.

    +

    Deploy Gossiped

    +

    After a node accepts a new deploy, it will gossip to all other nodes. A validator node will put the deploy into the block proposer buffer. The validator leader will pick the deploy from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given deploy. Each node that accepts a gossiped deploy also emits a DeployAccepted event on its event stream server. The deploy may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a DeployExpired event.

    +

    Block Proposed

    +

    The validator leader for this round will propose a block that includes as many deploys from the block proposer buffer as can fit in a block.

    +

    Block Gossiped

    +

    The proposed block propagates to all other nodes.

    +

    Consensus Reached

    +

    Once the other validators reach consensus that the proposed block is valid, all deploys in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a BlockAdded. FinalitySignature events emit shortly after that. Finality signatures for the new block arrive from the validators.

    +

    Deploy Executed

    +

    A deploy executes in distinct phases to accommodate flexibly paying for computation. The phases of a deploy are payment, session, and finalization. Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the deploy is executed, a DeployProcessed event is emitted by the event stream server.

    +

    In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty deploys.

    +

    Payment code

    +

    Payment code determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a deploy. For example, the simplest payment code could use the account's main purse. In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only accounts with a balance in their main purse greater than or equal to MAX_PAYMENT_COST may execute deploys. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than MAX_PAYMENT_COST motes (a constant of the system.) +If the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending account's main purse.

    +

    Session code

    +

    Session code provides the main logic for the deploy. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself).

    +

    Specifying payment code and session code

    +

    The user-defined logic of a deploy can be specified in a number of ways:

    +
      +
    • a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the account the deploy is running in.)
    • +
    • a 32-byte identifier representing the hash where a contract is already stored in the global state
    • +
    • a name corresponding to a named key in the account, where a contract is stored under the key
    • +
    +

    Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module).

    +

    Summary

    +

    The following diagram summarizes the deploy lifecycle.

    +

    Image showing the deploy lifecycle

    + + \ No newline at end of file diff --git a/1.5.X/design/index.html b/1.5.X/design/index.html new file mode 100644 index 000000000..77cd30ec5 --- /dev/null +++ b/1.5.X/design/index.html @@ -0,0 +1,20 @@ + + + + + +Design Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/next/developers/cli/calling-contracts/index.html b/1.5.X/developers/cli/calling-contracts/index.html similarity index 83% rename from next/developers/cli/calling-contracts/index.html rename to 1.5.X/developers/cli/calling-contracts/index.html index 7b99b90dc..551fbca19 100644 --- a/next/developers/cli/calling-contracts/index.html +++ b/1.5.X/developers/cli/calling-contracts/index.html @@ -1,36 +1,37 @@ - + -Calling Contracts | Casper Docs - Redux +Calling Contracts | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Calling Smart Contracts with the Rust Client

    -

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.

    + submit an issue on Github
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Calling Smart Contracts with the Rust Client

    +

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.

    The following examples use two contracts on Testnet:

    Prerequisites

    Calling Contracts by Contract Hash

    -

    After installing a contract in global state, you can use the contract's hash to call one of its entry points. The following usage of put-deploy allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully.

    +

    After installing a contract in global state, you can use the contract's hash to call one of its entry points. The following usage of put-deploy allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully.

    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-hash [HEX_STRING] \
    --session-entry-point [ENTRY_POINT_FUNCTION]

    The arguments used above are:

      @@ -44,9 +45,9 @@

      Ca

      Example - Calling the Counter contract by hash:

      In this example, the --session-hash option identifies a stored contract with an entry-point called "counter-inc".

      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 100000000 \
      --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \
      --session-entry-point "counter-inc"
      -

      This put-deploy command is nearly identical to the command used to install the contract. Here, instead of session-path pointing to the Wasm binary, we have session-hash and session-entry-point identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn’t return a value. If an entry point returns a value, use code to interact with runtime return values.

      -
      tip

      The payment amount varies based on each deploy and network chainspec.

      -

      The following sample response contains a deploy_hash, needed to verify the changes in global state, as described here.

      +

      This put-deploy command is nearly identical to the command used to install the contract. Here, instead of session-path pointing to the Wasm binary, we have session-hash and session-entry-point identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn’t return a value. If an entry point returns a value, use code to interact with runtime return values.

      +
      tip

      The payment amount varies based on each deploy and network chainspec.

      +

      The following sample response contains a deploy_hash, needed to verify the changes in global state, as described here.

      Sample response
      {
      "id": 1197172763279676268,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.4.5",
      "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"
      }
      }
      @@ -81,7 +82,7 @@

      Calling Contracts by Package Hash

      -

      You can also call an entry point in a contract that is part of a contract package (see contract upgrades). Call put-deploy using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified.

      +

      You can also call an entry point in a contract that is part of a contract package (see contract upgrades). Call put-deploy using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified.

      casper-client put-deploy \
      --node-address [NODE_SERVER_ADDRESS] \
      --chain-name [CHAIN_NAME] \
      --secret-key [KEY_PATH]/secret_key.pem \
      --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
      --session-package-hash [HEX_STRING] \
      --session-entry-point [ENTRY_POINT_FUNCTION] \
      --session-version [INTEGER]

      The arguments of interest are:

        @@ -116,7 +117,7 @@

        Ca
        runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());

        The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.

        casper-client put-deploy \
        --node-address http://65.21.235.219:7777 \
        --chain-name casper-test \
        --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
        --payment-amount 100000000 \
        --session-name "counter" \
        --session-entry-point "counter_inc"
        -

        The sample response will contain a deploy_hash, which you need to use as described here to verify the changes in global state.

        +

        The sample response will contain a deploy_hash, which you need to use as described here to verify the changes in global state.

        Example 2 - Calling the Auction contract using a named key:

        This example uses the system Auction contract stored in global state under the "auction" key and its delegate entry point.

        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-name "auction" \
        --session-entry-point "delegate" \
        --session-arg "validator:public_key='0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f'" \
        --session-arg "amount:u512='500000000000'" \
        --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'"
        @@ -157,20 +158,20 @@

        Counter Contract Tutorial shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm).

        +

        The Counter Contract Tutorial shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm).


        casper-client put-deploy \
        --node-address http://65.21.235.219:7777 \
        --chain-name casper-test \
        --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
        --payment-amount 25000000000 \
        --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm

        Video - Calling a contract using Wasm:

        Calling Contracts that Return a Value

        -

        Visit the Interacting with Runtime Return Values tutorial to learn how to call a contract that returns a value using session code or contract code.

        +

        Visit the Interacting with Runtime Return Values tutorial to learn how to call a contract that returns a value using session code or contract code.

        What's Next?

    +
    \ No newline at end of file diff --git a/next/developers/cli/delegate/index.html b/1.5.X/developers/cli/delegate/index.html similarity index 70% rename from next/developers/cli/delegate/index.html rename to 1.5.X/developers/cli/delegate/index.html index 797764efa..ccf038827 100644 --- a/next/developers/cli/delegate/index.html +++ b/1.5.X/developers/cli/delegate/index.html @@ -1,30 +1,30 @@ - + -Delegating Tokens | Casper Docs - Redux +Delegating Tokens | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Delegating with the Casper Client

    This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.

    Prerequisites

      -
    1. You meet all prerequisites listed here, including having a valid node-address and the Casper command-line client
    2. -
    3. You have previously installed a smart contract to a Casper network
    4. +
    5. You meet all prerequisites listed here, including having a valid node-address and the Casper command-line client
    6. +
    7. You have previously installed a smart contract to a Casper network
    8. Acquiring a Validator's Public Key

    Acquiring a Validator's Public Key

    -

    This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the delegation request.

    +

    This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the delegation request.

    Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process.

    The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set.

    Sending the Delegation Request

    @@ -54,7 +54,7 @@

    Me
  • amount: The number of tokens to be delegated
  • delegator: The hexadecimal public key of the account delegating tokens to a validator. This key must match the secret key that signs the delegation
  • -

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    note

    Calling the delegate entry point on the auction contract has a fixed cost of 2.5 CSPR.

    Example:

    This example shows an account delegating 500 CSPR:

    @@ -85,13 +85,13 @@

    Deploy Status section for more details.

    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    Example:

    -

    This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the delegate entry point.

    +

    This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the delegate entry point.

    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ~/delegate.wasm \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"

    Next, confirm the delegation.

    Confirming the Delegation

    -

    A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:

    +

    A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:

    1. Your delegation is part of the bid to the auction
    2. The validator is part of the active validator set
    3. @@ -118,6 +118,6 @@

      Ch
      1. Testnet explorer
      2. Mainnet explorer
      3. -

    +
    \ No newline at end of file diff --git a/1.5.X/developers/cli/execution-error-codes/index.html b/1.5.X/developers/cli/execution-error-codes/index.html new file mode 100644 index 000000000..c8668a2db --- /dev/null +++ b/1.5.X/developers/cli/execution-error-codes/index.html @@ -0,0 +1,28 @@ + + + + + +Execution Error Codes | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Execution Error Codes

    +

    This section covers smart contract execution error codes.

    +

    As mentioned in Writing Rust Contracts, smart contracts can exit with an error code defined by an ApiError. Descriptions of each variant are found here and include the following sub-types:

    + +

    An ApiError of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ApiError::User(2) maps to an exit code of 65538 (i.e. 65536 + 2). You can find a mapping from contract exit codes to ApiError variants here.

    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/index.html b/1.5.X/developers/cli/index.html new file mode 100644 index 000000000..a38e36eb5 --- /dev/null +++ b/1.5.X/developers/cli/index.html @@ -0,0 +1,63 @@ + + + + + +Interacting with the Blockchain | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Using the Casper CLI Client

    +

    This section explains how to interact with a Casper network using the Casper command-line client written in Rust.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Transferring TokensTransferring tokens from one account to another using the Casper command-line client
    Delegating tokensDelegating tokens to a validator on a Casper network
    Undelegating Tokens with the Casper ClientUndelegating tokens from a validator on a Casper network
    Sending Deploys to a NetworkSending Deploys to a Casper network using the Rust CLI Client
    Installing Smart ContractsSteps to install a contract on a Casper network
    Querying Global StateHow to query global state after contract installation
    Calling Smart Contracts with the Rust ClientVarious ways to call a contract's entry-points
    Execution Error CodesError codes for smart contract execution
    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/installing-contracts/index.html b/1.5.X/developers/cli/installing-contracts/index.html new file mode 100644 index 000000000..67bbc6a22 --- /dev/null +++ b/1.5.X/developers/cli/installing-contracts/index.html @@ -0,0 +1,118 @@ + + + + + +Installing Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Installing Smart Contracts

    +

    This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.

    +

    Prerequisites

    +
      +
    • You have a compiled contract (.wasm file) to send to a Casper network
    • +
    • You have installed the Casper CLI client to interact with the network
    • +
    • You have a Casper Account with a public and secret key pair to initiate the deploy
    • +
    • You have enough CSPR tokens in your account's main purse to pay for deploys. If you plan to use the Casper Testnet, learn about the faucet to fund your testing account's main purse
    • +
    +

    Installing a Contract in Global State

    +

    To install a contract in global state, you need to send a deploy to the network with the contract Wasm. You can do so by using the put-deploy command.

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [CONTRACT_PATH]/[CONTRACT_NAME].wasm
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • +
    • chain-name - The chain name to the network where you wish to send the deploy. For Mainnet, use casper. For Testnet, use casper-test
    • +
    • secret-key - The file name containing the secret key of the account paying for the deploy
    • +
    • payment-amount - The payment for the deploy in motes
    • +
    • session-path - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer
    • +
    +

    Once you call this command, it will return a deploy hash. You can use this hash to verify successful execution of the deploy.

    +

    Example - Install the contract:

    +

    Here we send a counter-v1.wasm to a local NCTL network.

    +
    casper-client put-deploy \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount 5000000000000 \
    --session-path ./counter/target/wasm32-unknown-unknown/release/counter-v1.wasm
    +
    tip

    The payment amount varies based on each contract and network chainspec.

    +

    To verify the deploy, call get-deploy and provide the deploy hash you received from put-deploy.

    +
    casper-client get-deploy \
    --node-address http://localhost:11101 [DEPLOY_HASH]
    +

    Video - Contract Installation Walkthrough

    +

    This video demonstrates the commands described above for installing a contract on-chain.

    +

    + +

    +

    Querying Global State

    +

    Here we look at how to query global state to see details about a successfully installed contract.

    +

    Get the state root hash

    +

    The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time.

    +
    note

    After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state.

    +

    To get the state root hash, use the get-state-root-hash command:

    +
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    +

    Query global state

    +

    Next, query the state of a Casper network at a given time, specified by the state-root-hash described above. You can dive into the data stored in global state using the optional query path argument -q.

    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [HASH_STRING] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • +
    • state-root-hash - Hex-encoded hash of the state root
    • +
    • key - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash
    • +
    • q - An optional query path argument that allows you to drill into the specifics of a query with respect to the key
    • +
    +

    Example - Query the account:

    +

    To find your account details, query global state using your account hash.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d
    +

    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
    + +
    {
    "id": -6831525034388467034,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[27614 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "weight": 1
    }
    ],
    "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",
    "named_keys": [
    {
    "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "name": "counter"
    },
    {
    "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "name": "counter_access_uref"
    },
    {
    "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "name": "counter_package_name"
    },
    {
    "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",
    "name": "version"
    }
    ]
    }
    }
    }
    }
    +
    +

    +
    tip

    If you don't know your account hash, you can run this command:

    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    +

    Example - Query the contract:

    +

    This example shows how to query global state given a contract hash. We use the contract hash from the sample response above.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e
    +

    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
    + +
    {
    "id": -4657473054587773855,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[21330 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",
    "entry_points": [
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_get",
    "ret": "I32"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_inc",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",
    "name": "count"
    }
    ],
    "protocol_version": "1.4.5"
    }
    }
    }
    }

    +
    +

    +

    Example - Query a value using its key and the contract hash:

    +

    Next, you can query a named key associated with the contract using the -q option. This example comes from the Counter Contract Tutorial, where a "count" variable is incremented and stored under a named key.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_HASH] \
    -q "count"
    +
    Sample stored value
    + +
    {
    "id": -2540117660598287261,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[56562 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "00000000",
    "cl_type": "I32",
    "parsed": 0
    }
    }
    }
    }
    +
    +

    +

    Example - Query a value using the account hash and named keys:

    +

    It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \
    -q "counter/count"
    +

    The response should be the same as in Example 3, above.

    +

    Example - Query contract package state:

    +

    You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \
    --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966
    +

    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 in the next section. You would also see the access_key for the ContractPackage and the current contract_version.

    +
    Sample contract package state
    + +
    {
    "id": -6225901853092301031,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[20964 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }
    +
    +

    +

    Video - Querying Walkthrough

    +

    This video shows you what to expect when querying the network.

    +

    + +

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/opcode-costs/index.html b/1.5.X/developers/cli/opcode-costs/index.html new file mode 100644 index 000000000..38543775a --- /dev/null +++ b/1.5.X/developers/cli/opcode-costs/index.html @@ -0,0 +1,648 @@ + + + + + +OpCode Costs Tables | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    OpCode Costs Tables

    +

    The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.

    +

    More information on chainspecs for private networks can be found here

    +
    note

    All costs in this table are in motes, not CSPR, and the corresponding chainspec is here.

    +

    Storage Costs

    + + + + + + + + + + + + + + + +
    AttributeDescriptionCost
    gas_per_byteGas charged per byte stored in global state.630,000
    +

    OpCode Costs

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionCost
    bitBit operations multiplier.300
    addArithmetic add operations multiplier.210
    mulMul operations multiplier.240
    divDiv operations multiplier.320
    loadMemory load operation multiplier.2_500
    storeMemory store operation multiplier.4,700
    constConst store operation multiplier.110
    localLocal operations multiplier.390
    globalGlobal operations multiplier.390
    integer_comparisonInteger operations multiplier.250
    conversionConversion operations multiplier.420
    unreachableUnreachable operation multiplier.270
    nopNop operation multiplier.200
    current_memoryGet the current memory operation multiplier.290
    grow_memoryGrow memory cost per page (64 kB).240,000
    +

    Control Flow Operation Costs

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionCost
    blockCost for block opcode.440
    loopCost for loop opcode.440
    ifCost for if opcode.440
    elseCost for else opcode.440
    endCost for end opcode.440
    brCost for br opcode.35_000
    br_ifCost for br_if opcode.35,000
    returnCost for return opcode.440
    selectCost for select opcode.440
    callCost for call opcode.68_000
    call_indirectCost for call_indirect opcode.68,000
    dropCost for drop opcode.440
    +

    Br_Table OpCode Costs

    + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionCost
    costFixed cost per br_table opcode.35,000
    size_multiplierSize of target labels in the br_table opcode will be multiplied by size_multiplier.100
    +

    External Function Costs

    +

    The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found here.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Host-Side FunctionCostArguments
    add5,800[0, 0, 0, 0]
    add_associated_key9,000[0, 0, 0]
    add_contract_version200[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    blake2b200[0, 0, 0, 0]
    call_contract4,500[0, 0, 0, 0, 0, 420, 0]
    call_versioned_contract4,500[0, 0, 0, 0, 0, 0, 0, 420, 0]
    create_contract_package_at_hash200[0, 0]
    create_contract_user_group200[0, 0, 0, 0, 0, 0, 0, 0]
    create_purse2,500,000,000[0, 0]
    disable_contract_version200[0, 0, 0, 0]
    get_balance3,800[0, 0, 0]
    get_blocktime330[0]
    get_caller380[0]
    get_key2,000[0, 440, 0, 0, 0]
    get_main_purse1,300[0]
    get_named_arg200[0, 0, 0, 0]
    get_named_arg_size200[0, 0, 0]
    get_phase710[0]
    get_system_contract1,100[0, 0, 0]
    has_key1,500[0, 840]
    is_valid_uref760[0, 0]
    load_named_keys42,000[0, 0]
    new_uref17,000[0, 0, 590]
    random_bytes200[0, 0]
    print20,000[0, 4,600]
    provision_contract_user_group_uref200[0, 0, 0, 0, 0]
    put_key38,000[0, 1,100, 0, 0]
    read_host_buffer3,500[0, 310, 0]
    read_value6,000[0, 0, 0]
    read_value_local5,500[0, 590, 0]
    remove_associated_key4,200[0, 0]
    remove_contract_user_group200[0, 0, 0, 0]
    remove_contract_user_group_urefs200[0, 0, 0, 0, 0, 0]
    remove_key61,000[0, 3,200]
    ret23,000[0, 420,000]
    revert500[0]
    set_action_threshold74,000[0, 0]
    transfer_from_purse_to_account2,500,000,000[0, 0, 0, 0, 0, 0, 0, 0, 0]
    transfer_from_purse_to_purse82,000[0, 0, 0, 0, 0, 0, 0, 0]
    transfer_to_account2,500,000,000[0, 0, 0, 0, 0, 0, 0]
    update_associated_key4,200[0, 0, 0]
    write14,000[0, 0, 0, 980]
    write_local9,500[0, 1,800, 0, 520]
    +

    Protocol Operating Costs

    + + + + + + + + + + + + + + + +
    AttributeDescriptionCost
    wasmless_transfer_costDefault gas cost for a wasmless transfer.100,000,000
    +

    Auction System Contract Costs

    +

    These are the costs of calling auction system contract entrypoints.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EntrypointDescriptionCost
    get_era_validatorsCost of calling the get_era_validators entrypoint.10,000
    read_seigniorage_recipientsCost of calling the read_seigniorage_recipients entrypoint.10,000
    add_bidCost of calling the add_bid entrypoint.2,500,000,000
    withdraw_bidCost of calling the withdraw_bid entrypoint.2,500,000,000
    delegateCost of calling the delegate entrypoint.2,500,000,000
    undelegateCost of calling the undelegate entrypoint.2,500,000,000
    run_auctionCost of calling the run_auction entrypoint.10,000
    slashCost of calling the slash entrypoint.10,000
    distributeCost of calling the distribute entrypoint.10,000
    withdraw_delegator_rewardCost of calling the withdraw_delegator_reward entrypoint.10,000
    withdraw_validator_rewardCost of calling the withdraw_validator_reward entrypoint.10,000
    read_era_idCost of calling the read_era_id entrypoint.10,000
    activate_bidCost of calling the activate_bid entrypoint.10,000
    redelegateCost of calling the redelegate entrypoint.2,500,000,000
    +

    Mint System Contract Costs

    +

    These are the costs of calling mint system contract entrypoints.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EntrypointDescriptionCost
    mintCost of calling the mint entrypoint.2,500,000,000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10,000
    createCost of calling the create entrypoint.2,500,000,000
    balanceCost of calling the balance entrypoint.10,000
    transferCost of calling the transfer entrypoint.10,000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10,000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2,500,000,000
    +

    Handle_Payment System Contract Costs

    +

    These are the costs of calling entrypoints on the handle_payment system contract.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    EntrypointDescriptionCost
    get_payment_purseCost of calling the get_payment_purse entrypoint.10,000
    set_refund_purseCost of calling the set_refund_purse entrypoint.10,000
    get_refund_purseCost of calling the get_refund_purse entrypoint.10,000
    finalize_paymentCost of calling the finalize_payment entrypoint.10,000
    +

    Standard_Payment System Contract Costs

    +

    These settings manage the costs of calling entrypoints on the standard_payment system contract.

    + + + + + + + + + + + + + + + +
    EntrypointDescriptionCost
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10,000
    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/querying-global-state/index.html b/1.5.X/developers/cli/querying-global-state/index.html new file mode 100644 index 000000000..c1d27aef6 --- /dev/null +++ b/1.5.X/developers/cli/querying-global-state/index.html @@ -0,0 +1,90 @@ + + + + + +Querying Global State | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Querying Global State

    +

    This page explains how to query global state after contract installation.

    +

    Prerequisites

    + +

    Getting the State Root Hash

    +

    The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time.

    +
    note

    After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state.

    +

    To get the state root hash, use the get-state-root-hash command:

    +
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    +

    Sending the Query

    +

    Next, query the state of a Casper network at a given time, specified by the state-root-hash described above. You can dive into the data stored in global state using the optional query path argument -q.

    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [HASH_STRING] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • +
    • state-root-hash - Hex-encoded hash of the state root
    • +
    • key - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash
    • +
    • q - An optional query path argument that allows you to drill into the specifics of a query with respect to the key
    • +
    +

    Query the account

    +

    To find your account details, query global state using your account hash.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d
    +

    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
    + +
    {
    "id": -6831525034388467034,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[27614 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "weight": 1
    }
    ],
    "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",
    "named_keys": [
    {
    "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "name": "counter"
    },
    {
    "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "name": "counter_access_uref"
    },
    {
    "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "name": "counter_package_name"
    },
    {
    "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",
    "name": "version"
    }
    ]
    }
    }
    }
    }
    +
    +

    +
    tip

    If you don't know your account hash, you can run this command:

    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    +

    Query the contract

    +

    This example shows how to query global state given a contract hash. We use the contract hash from the sample response above.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e
    +

    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
    + +
    {
    "id": -4657473054587773855,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[21330 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",
    "entry_points": [
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_get",
    "ret": "I32"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_inc",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",
    "name": "count"
    }
    ],
    "protocol_version": "1.4.5"
    }
    }
    }
    }

    +
    +

    +

    Query a value using its key and the contract hash

    +

    Next, you can query a named key associated with the contract using the -q option. This example comes from the Counter Contract Tutorial, where a "count" variable is incremented and stored under a named key.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_HASH] \
    -q "count"
    +
    Sample stored value
    + +
    {
    "id": -2540117660598287261,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[56562 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "00000000",
    "cl_type": "I32",
    "parsed": 0
    }
    }
    }
    }
    +
    +

    +

    Query a value using the account hash and named keys

    +

    It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \
    -q "counter/count"
    +

    The response should be the same as in Example 3, above.

    +

    Query contract package state

    +

    You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \
    --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966
    +

    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 in the next section. You would also see the access_key for the ContractPackage and the current contract_version.

    +
    Sample contract package state
    + +
    {
    "id": -6225901853092301031,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[20964 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }
    +
    +

    +

    Video Walkthrough

    +

    This video shows you what to expect when querying the network.

    +

    + +

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/next/developers/cli/redelegate/index.html b/1.5.X/developers/cli/redelegate/index.html similarity index 55% rename from next/developers/cli/redelegate/index.html rename to 1.5.X/developers/cli/redelegate/index.html index 979e77293..808e66230 100644 --- a/next/developers/cli/redelegate/index.html +++ b/1.5.X/developers/cli/redelegate/index.html @@ -1,27 +1,27 @@ - + -Redelegating Tokens with the Casper Client | Casper Docs - Redux +Redelegating Tokens with the Casper Client | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Redelegating Tokens with the Casper Client

    -

    This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.

    + submit an issue on Github
    Version: 1.5.X

    Redelegating Tokens with the Casper Client

    +

    This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.

    Prerequisites

      -
    1. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    2. -
    3. You have delegated tokens to a validator on a Casper network, and you have the validator's public key
    4. -
    5. You have the public key of the new validator to whom you wish to redelegate tokens. See Acquiring a Validator's Public Key for more details
    6. +
    7. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    8. +
    9. You have delegated tokens to a validator on a Casper network, and you have the validator's public key
    10. +
    11. You have the public key of the new validator to whom you wish to redelegate tokens. See Acquiring a Validator's Public Key for more details

    Method 1: Redelegating with the System Auction Contract

    This method calls the existing redelegate entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity.

    @@ -50,11 +50,11 @@

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    note

    Calling the redelegate entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations.

    Example:

    -

    This example uses a private network running casper-node version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +

    This example uses a private network running casper-node version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    casper-client put-deploy \
    --node-address http://3.143.158.19:7777 \
    --chain-name integration-test \
    --secret-key ~/KEYS/integration/Test_secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \
    --session-entry-point redelegate \
    --session-arg "validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'" \
    --session-arg "new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'"

    Next, verify the redelegation.

    Method 2: Redelegating with Compiled Wasm

    -

    Another way to send a redelegation is to compile the redelegate.wasm and send it to the network via a deploy. To compile the Wasm yourself, build the casper-node contracts that will include the redelegation Wasm.

    +

    Another way to send a redelegation is to compile the redelegate.wasm and send it to the network via a deploy. To compile the Wasm yourself, build the casper-node contracts that will include the redelegation Wasm.

    Sending the redelegation request

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    This example uses the Casper client to send a deploy containing the redelegate.wasm to the network to initiate the redelegation process.

    @@ -73,14 +73,14 @@

    query information about the redelegation Deploy.

    +

    Save the returned deploy_hash from the output to query information about the redelegation Deploy.

    note

    Running the redelegate.wasm is a more expensive operation than calling the redelegate entrypoint from the system auction contract.

    Example:

    -

    This example uses a private network running casper-node version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +

    This example uses a private network running casper-node version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    casper-client put-deploy \
    --node-address http://3.143.158.19:7777 \
    --chain-name integration-test \
    --secret-key ~/KEYS/integration/Test_secret_key.pem \
    --payment-amount 8000000000 \
    --session-path ~/redelegate.wasm \
    --session-arg "validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'" \
    --session-arg "new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'"

    Verifying the Redelegation

    The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy.

    Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator.

    -

    Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as verifying a delegation request using the casper-client get-auction-info command.

    +

    Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as verifying a delegation request using the casper-client get-auction-info command.

    \ No newline at end of file diff --git a/developers/cli/sending-deploys/index.html b/1.5.X/developers/cli/sending-deploys/index.html similarity index 75% rename from developers/cli/sending-deploys/index.html rename to 1.5.X/developers/cli/sending-deploys/index.html index d735c9234..cf8ddd3d9 100644 --- a/developers/cli/sending-deploys/index.html +++ b/1.5.X/developers/cli/sending-deploys/index.html @@ -3,38 +3,38 @@ -Sending Deploys | Casper Docs - Redux +Sending Deploys | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Sending Deploys using the Casper Client

    -

    To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:

    + submit an issue on Github
    Version: 1.5.X

    Sending Deploys using the Casper Client

    +

    To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:

      -
    • You will need a client to interact with the network, such as the default Casper client
    • -
    • Ensure you have an Account and its associated keys This account will pay for the Deploy, and its secret key will sign the Deploy
    • +
    • You will need a client to interact with the network, such as the default Casper client
    • +
    • Ensure you have an Account and its associated keys This account will pay for the Deploy, and its secret key will sign the Deploy
    • Ensure this account has enough CSPR tokens to pay for the Deploy

    Paying for Deploys

    CSPR tokens are used to pay for deploys on the Casper Mainnet and Testnet. There are several ways to fund your account:

    Monitoring the Event Stream for Deploys

    -

    If you want to follow the lifecycle of the Deploy, you can start monitoring a node's event stream. This section will focus only on DeployAccepted events, but there are other event types described here. You need the following information to proceed:

    +

    If you want to follow the lifecycle of the Deploy, you can start monitoring a node's event stream. This section will focus only on DeployAccepted events, but there are other event types described here. You need the following information to proceed:

      -
    • The IP address of a peer on the network
    • +
    • The IP address of a peer on the network
    • The port specified as the event_stream_server.address in the node's config.toml, which is by default 9999 on Mainnet and Testnet
    • The URL for DeployAccepted events, which is HOST:PORT/events/deploys
    @@ -90,7 +90,7 @@

    The session Wasm (or payment Wasm if you choose to not use the standard payment) of a Deploy often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the --session-arg or --payment-arg options, once for each arg required. The Casper client provides some examples of how to do this:

    casper-client put-deploy --show-arg-examples

    Advanced Features

    -

    Casper networks support complex deploys using multiple signatures. Casper Accounts use a powerful permissions model that enables a multi-signature scheme for deploys.

    +

    Casper networks support complex deploys using multiple signatures. Casper Accounts use a powerful permissions model that enables a multi-signature scheme for deploys.

    The put-deploy command performs multiple actions under the hood, optimizing the typical use case. It creates a deploy, signs it, and sends the Deploy to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:

    • make-deploy - Creates a Deploy and outputs it to a file or stdout. As a file, the deploy can subsequently be signed by other parties using the sign-deploy subcommand and then sent to the network for execution using the send-deploy subcommand
    • @@ -98,13 +98,13 @@

      Advanced F
    • send-deploy - Reads a previously-saved Deploy from a file and sends it to the network for execution

    To sign a Deploy with multiple keys, create the Deploy with the make-deploy command. The generated deploy file can be sent to the other signers, who then sign it with their keys by calling the sign-deploy for each key. Signatures need to be gathered on the Deploy one after another until all required parties have signed the Deploy. Finally, the signed Deploy is sent to the network with the send-deploy command for processing.

    -

    For a step-by-step workflow, visit the Two-Party Multi-Signature Deploy guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network.

    +

    For a step-by-step workflow, visit the Two-Party Multi-Signature Deploy guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network.

    A Note about Gas Price

    A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"

    We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the deploy. If you plan on sending a deploy to Mainnet, you can use the Testnet to estimate the payment amount needed for the deploy.

    -

    If your test configuration matches your production chainspec, you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the runtime economics section for more details about gas usage and fees.

    +

    If your test configuration matches your production chainspec, you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the runtime economics section for more details about gas usage and fees.

    Please be aware that sending a deploy always requires payment. This is true regardless of the validity of included Wasm.

    -

    If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the failed execution.

    -

    However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse.

    +

    If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the failed execution.

    +

    However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse.

    \ No newline at end of file diff --git a/1.5.X/developers/cli/transfers/direct-token-transfer/index.html b/1.5.X/developers/cli/transfers/direct-token-transfer/index.html new file mode 100644 index 000000000..e993028f8 --- /dev/null +++ b/1.5.X/developers/cli/transfers/direct-token-transfer/index.html @@ -0,0 +1,100 @@ + + + + + +Direct Token Transfer | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Direct Token Transfer

    +

    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 general development prerequisites
    2. +
    3. You are using the Casper command-line client
    4. +
    5. You have a target public key
    6. +
    7. You have a valid node address
    8. +
    9. You must be able to sign a deploy for the source account using the source secret key
    10. +
    +

    Direct Transfer Example

    +

    The following transfer command allows you to move CSPR from one account's purse to another as denominated in Motes. 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.

    +
    casper-client transfer \
    --id <ID> \
    --transfer-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 [TARGET_PUBLIC_KEY_HEX] \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES]
    +

    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:<http://localhost:7777\>\]

      +
    • +
    • +

      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. For Testnet node version 1.5.1, you can specify 10^8 motes

      +
    • +
    +

    Important response fields:

    +
      +
    • "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.

    +

    Example Transfer:

    +
    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.
    + +

    JSON-RPC Request:

    +
    {
    "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"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "014767a90000000000",
    "parsed": 11102023
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"
    }
    ]
    }
    },
    "id": 3
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "id": 3,
    "result": {
    "api_version": "1.5.3",
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"
    }
    }
    +
    +

    Verifying the Deploy

    +

    A transfer on a Casper network is only executed after it has been included in a finalized block.

    +
    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.

    +

    Example Query:

    +
    casper-client get-deploy 
    --node-address https://rpc.testnet.casperlabs.io
    1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c
    +
    Explore the JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "info_get_deploy",
    "params": {
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "finalized_approvals": false
    },
    "id": -3447643973713335073
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.3",
    "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"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "014767a90000000000",
    "parsed": 11102023
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"
    }
    ]
    },
    "execution_results": [
    {
    "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",
    "result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06621c3e660301",
    "parsed": "1114111876194"
    }
    }
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06621c3e660301",
    "parsed": "1114111876194"
    }
    }
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06622a383c0201",
    "parsed": "1109111876194"
    }
    }
    },
    {
    "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",
    "transform": {
    "AddUInt512": "5000000000"
    }
    },
    {
    "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",
    "transform": {
    "WriteTransfer": {
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",
    "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",
    "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",
    "amount": "5000000000",
    "gas": "0",
    "id": 11102023
    }
    }
    },
    {
    "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "transfers": [
    "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"
    ],
    "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",
    "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",
    "gas": "100000000"
    }
    }
    },
    {
    "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"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",
    "transform": {
    "AddUInt512": "100000000"
    }
    }
    ]
    },
    "transfers": [
    "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"
    ],
    "cost": "100000000"
    }
    }
    }
    ]
    },
    "id": -3447643973713335073
    }
    +
    +

    Refer to the Section on querying deploys for more information.

    +

    Verifying the Transfer

    +

    In addition to verifying the deploy, you also need to verify the transfer details. 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 diff --git a/1.5.X/developers/cli/transfers/index.html b/1.5.X/developers/cli/transfers/index.html new file mode 100644 index 000000000..c9af10392 --- /dev/null +++ b/1.5.X/developers/cli/transfers/index.html @@ -0,0 +1,27 @@ + + + + + +Transferring Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Transferring Tokens with the Casper CLI Client

    +

    The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.

    +

    Transferring tokens using a direct transfer

    +

    Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see Transferring Tokens Using Direct Transfer.

    +

    Transferring tokens using a multi-sig deploy

    +

    Multi-sig deploy transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the deploy. To set up the account's associated keys, see the Two-Party Multi-Signature Deploys workflow. To use a multi-sig deploy transfer, see Transferring Tokens Using a Multi-sig Account.

    +

    Verifying a transfer using the command-line client

    +

    To verify the status of a transfer, see Verifying a Transfer.

    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/transfers/multisig-deploy-transfer/index.html b/1.5.X/developers/cli/transfers/multisig-deploy-transfer/index.html new file mode 100644 index 000000000..1131b80fa --- /dev/null +++ b/1.5.X/developers/cli/transfers/multisig-deploy-transfer/index.html @@ -0,0 +1,155 @@ + + + + + +Transferring Tokens using a Multi-Sig Deploy | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Transferring Tokens using a Multi-Sig Deploy

    +

    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

    +

    You must ensure the following prerequisites are met.

    +
      +
    1. Set up all the prerequisites listed here, including: + +
    2. +
    3. Set up the source account for multi-signature deploys, as outlined in the Two-Party Multi-Signature Deploys workflow
    4. +
    5. Get the path of the source account's secret key file
    6. +
    7. Get the target account's public key in hex format
    8. +
    +

    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. +
    3. The sign-deploy command adds additional signatures for a multi-signature transfer
    4. +
    5. The send-deploy command sends the deploy containing the transfer to the network
    6. +
    +

    +

    Creating the transfer

    +

    This section explains the make-transfer command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the secret_key.pem file) to a target account. To use this example on the Mainnet, the chain-name would be casper instead of casper-test. Note that we are saving the output of the make-transfer command in a transfer.deploy file.

    +
    casper-client make-transfer --amount 2500000000 \
    --secret-key [PATH]/secret_key.pem \
    --chain-name casper-test \
    --target-account [PUBLIC_KEY_HEX] \
    --transfer-id [ID] \
    --payment-amount 100000000 \
    --output transfer.deploy
    +

    The following table explains the parameters used in the make-transfer command.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterDescription
    amountThe number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)
    secret-keyThe path of the secret key file for the source account
    chain-nameThe name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain
    • For Testnet use casper-test
    • For Mainnet use casper
    target-accountHex-encoded public key of the target account from which the main purse will be used
    transfer-idA user-defined identifier permanently associated with the transfer
    payment-amountThe payment for the transfer in motes. The payment amount varies based on the deploy and network chainspec. For Testnet node version 1.5.1, 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.

    +

    Example:

    +
    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
    + +
    {
    "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",
    "header": {
    "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "timestamp": "2023-10-12T19:14:22.080Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",
    "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": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010100000000000000",
    "parsed": 1
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"
    }
    ]
    }
    +
    +

    Signing the transfer

    +

    Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a transfer2.deploy file.

    +
    casper-client sign-deploy \
    --input transfer.deploy \
    --secret-key [PATH]/another_secret_key.pem \
    --output transfer2.deploy
    + + + + + + + + + + + + + + + + + + + + + +
    ParameterDescription
    inputThe path of the deploy file, which needs to be signed
    secret-keyThe path of the secret key file used to sign the deploy
    outputThe path of the output file used to save the deploy with multiple signatures
    +

    Example:

    +
    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.

    +
    Sample output saved in the transfer2.deploy file
    + +
    {
    "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",
    "header": {
    "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "timestamp": "2023-10-12T19:14:22.080Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",
    "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": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010100000000000000",
    "parsed": 1
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"
    },
    {
    "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",
    "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"
    }
    ]
    }
    +
    +

    Sending the deploy

    +

    The next step is to send the deploy for processing on the network. As described in the 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.

    +
    casper-client send-deploy \
    --input transfer2.deploy \
    --node-address https://rpc.testnet.casperlabs.io/
    + + + + + + + + + + + + + + + + + +
    ParameterDescription
    inputThe path of the deploy file, which is used as the input
    node-addressThe Hostname or IP and port of the node
    +

    Make a note of the deploy_hash from the send-deploy command output to verify the status of the deploy.

    +
    Successful output of the send-deploy command
    + +
    {
    "jsonrpc": "2.0",
    "id": -818883417884028030,
    "result": {
    "api_version": "1.5.3",
    "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"
    }
    }
    +
    +
    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 workflow is an example of how to accomplish this.

    +
    Example of an account authorization error
    + +
    {
    "code": -32008,
    "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"
    }
    +
    +

    Verifying the transfer

    +

    To verify the transfer status, see Verifying a Transfer.

    +
    tip

    You can also verify if the transfer was successful by checking your account balance using a block explorer.

    + + \ No newline at end of file diff --git a/1.5.X/developers/cli/transfers/verify-transfer/index.html b/1.5.X/developers/cli/transfers/verify-transfer/index.html new file mode 100644 index 000000000..b2e7d8c5f --- /dev/null +++ b/1.5.X/developers/cli/transfers/verify-transfer/index.html @@ -0,0 +1,131 @@ + + + + + +Verifying a Transfer | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Verifying a Transfer

    +

    Prerequisites

    +

    Before verifying a transfer, make sure you have:

    +
      +
    1. Initiated a Direct Transfer or Multi-sig Deploy Transfer
    2. +
    3. The deploy_hash of the transfer you want to verify
    4. +
    5. The public key of the source and target accounts
    6. +
    +

    Query 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 sending a deploy.

    +
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    +

    Example Query:

    +
    casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io 
    +
    Sample output of the get-state-root-hash command
    + +
    {
    "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

    +

    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.

    +

    +

    First, use the get-deploy command and the deploy_hash to identify the corresponding transfer:

    +
    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    +

    Important response fields:

    +
      +
    • "result"."execution_results"."result"."Success"."transfers" - List of transfers contained in a successful deploy
    • +
    +

    After obtaining the transfer identifier, query the transfer details.

    +
    casper-client query-global-state \
    --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 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:

    +
    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.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",
    "path": []
    },
    "id": 3
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "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
    }
    +
    +

    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 the Account State

    +

    Next, query for information about the Source account, using the state-root-hash of the block containing the transfer:

    +
    casper-client query-global-state \
    --id [ID] \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [SOURCE_PUBLIC_KEY]
    +

    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 - 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
    • +
    +

    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 Account Query:

    +
    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.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",
    "path": []
    },
    "id": 4
    }
    +

    JSON-RPC Response:

    +
    {
    "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
    }
    +
    +

    Target Account Query:

    +

    Repeat the same step to query information about the Target account:

    +
    casper-client query-global-state -v \
    --id 5 \
    --node-address https://rpc.testnet.casperlabs.io/ \
    --state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \
    --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986
    +
    Explore the JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "path": []
    },
    "id": 5
    }
    +

    JSON-RPC Response:

    +
    {
    "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 the Purse Balance

    +

    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:

    +
    casper-client query-balance --help
    +

    Verify the source purse balance using the query-balance command:

    +
    casper-client query-balance \
    --id 6 \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HAHS] \
    --purse-identifier [SOURCE_PUBLIC_KEY_HEX]
    +

    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 - 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
    • +
    +

    Query Source Account Example:

    +
    casper-client query-balance -v --id 6 \
    --node-address https://rpc.testnet.casperlabs.io/ \
    --state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \
    --purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655
    +
    Explore the sample JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "purse_identifier": {
    "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"
    }
    },
    "id": 6
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.3",
    "balance": "1109111876194"
    },
    "id": 6
    }
    +
    +

    Similarly, query the balance of the target purse.

    +
    casper-client get-balance \
    --id 7 \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HAHS] \
    --purse-identifier [TARGET_PUBLIC_KEY_HEX]
    +

    Target Account Example:

    +
    casper-client query-balance -v --id 7 \
    --node-address https://rpc.testnet.casperlabs.io/ \
    --state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \
    --purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7
    +
    Explore the sample JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "purse_identifier": {
    "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"
    }
    },
    "id": 7
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.3",
    "balance": "46200000000"
    },
    "id": 7
    }
    +
    + + \ No newline at end of file diff --git a/next/developers/cli/undelegate/index.html b/1.5.X/developers/cli/undelegate/index.html similarity index 57% rename from next/developers/cli/undelegate/index.html rename to 1.5.X/developers/cli/undelegate/index.html index 7374bea6c..1d51a6756 100644 --- a/next/developers/cli/undelegate/index.html +++ b/1.5.X/developers/cli/undelegate/index.html @@ -1,26 +1,26 @@ - + -Undelegating Tokens | Casper Docs - Redux +Undelegating Tokens | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Undelegating Tokens with the Casper Client

    This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.

    Prerequisites

      -
    1. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    2. -
    3. You have delegated tokens to a validator on a Casper network and you have the validator's public key
    4. +
    5. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    6. +
    7. You have delegated tokens to a validator on a Casper network and you have the validator's public key

    Sending the Undelegation Request

    There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the undelegate entry point from the system auction contract. The second method involves building the undelegate.wasm from the casper-node repository and installing it on the network.

    @@ -48,14 +48,14 @@

  • amount: The number of tokens to be undelegated
  • delegator: The hexadecimal public key of the account undelegating tokens from a validator. This key must match the secret key that signs the delegation
  • -

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    note

    Calling the undelegate entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call.

    Example:

    This example shows an account delegating 100 CSPR:

    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point undelegate \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='100000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"

    Next, confirm the undelegation.

    Method 2: Undelegating with Compiled Wasm

    -

    As part of this process, you need to build the casper-node contracts that produce the undelegation Wasm.

    +

    As part of this process, you need to build the casper-node contracts that produce the undelegation Wasm.

    Next, use the Casper CLI client to send a deploy containing the undelegate.wasm to the network to initiate the undelegation process.

    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-path <PATH_TO_WASM>/undelegate.wasm \
    --session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
    --session-arg "amount:u512='<AMOUNT_TO_UNDELEGATE>'" \
    --session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
      @@ -71,9 +71,9 @@

      M
    1. amount: The number of tokens to be undelegated
    2. delegator: The hexadecimal public key of the account undelegating tokens from a validator. This key must match the secret key that signs the delegation
    -

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    Example:

    -

    This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the undelegate entry point.

    +

    This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the undelegate entry point.

    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 6000000000 \
    --session-path ~/undelegate.wasm \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='100000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"

    Next, confirm the undelegation.

    Verifying the Undelegation

    @@ -90,6 +90,6 @@

    V
  • Testnet explorer
  • Mainnet explorer
  • -

    Important Note: After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator.

    +

    Important Note: After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator.

    \ No newline at end of file diff --git a/1.5.X/developers/dapps/dapp/index.html b/1.5.X/developers/dapps/dapp/index.html new file mode 100644 index 000000000..39f88d382 --- /dev/null +++ b/1.5.X/developers/dapps/dapp/index.html @@ -0,0 +1,33 @@ + + + + + +What is a dApp? | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    What is a dApp?

    +

    A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.

    +

    The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself.

    +

    How are Decentralized Applications Different?

    +

    A decentralized system consists of a group of interchangeable machines that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    +

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    +

    Routine operations in a decentralized network may result in nodes coming on or offline. This node churn can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node.

    +

    Interacting with a Decentralized Network

    +

    For a dApp to integrate with a Casper network, it must be able to send Deploys via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. Sending a Deploy to a node will result in that node gossiping that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution.

    +

    A Deploy contains session code in the form of Wasm to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later.

    +

    Sending a Deploy is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy.

    +

    All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    +

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy.

    +

    There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The Deploy Lifecycle results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/index.html b/1.5.X/developers/dapps/index.html new file mode 100644 index 000000000..05a81d4b4 --- /dev/null +++ b/1.5.X/developers/dapps/index.html @@ -0,0 +1,67 @@ + + + + + +Overview of Casper dApps | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Overview of Casper dApps

    +

    The following topics are essential for developers building decentralized applications on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Introducing dAppsIntroducing dApps on a Casper network
    Prerequisites for Building dAppsRecommended setup for building dApps on Casper
    SDK Client LibrariesClient-side libraries providing ways to interact with a Casper network
    dApp Technology StackBuilding the front-end, backend, and on-chain logic of a dApp
    Front-end Template with ReactUse the Casper JS SDK with React to build a dApp fron-tend
    Signing DeploysDetails about the signatures required for deploys
    Setting up a Local Network with NCTLLearn to set up a local test network
    Testing Smart Contracts with NCTLTest deploys locally before sending them to a Casper network
    Monitoring and Consuming EventsHow dApps can listen for emitted events and perform actions based on event data
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/monitor-and-consume-events/index.html b/1.5.X/developers/dapps/monitor-and-consume-events/index.html new file mode 100644 index 000000000..fec4cf1f5 --- /dev/null +++ b/1.5.X/developers/dapps/monitor-and-consume-events/index.html @@ -0,0 +1,187 @@ + + + + + +Monitoring and Consuming Events | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    +

    Monitoring and Consuming Events

    +

    The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.

    +

    Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the event_stream_server.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.

    +

    Events are divided into three categories and streamed on their respective endpoints:

    +
      +
    • Deploy events - Associated with Deploys on a node. Currently, only a DeployAccepted event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is http://<HOST>:9999/events/deploys/.
    • +
    • Finality Signature events - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is http://<HOST>:9999/events/sigs/.
    • +
    • Main events - All other events fall under this type, including: BlockAdded, DeployProcessed, DeployExpired, Fault, Step, and Shutdown events. The URL to consume these events on Mainnet and Testnet is http://<HOST>:9999/events/main/.
    • +
    +
    note

    An ApiVersion event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version.

    +

    Listening to the Event Stream

    +

    Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:

    + + +
    const { EventStream, EventName } = require("casper-js-sdk")

    const es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL)
    es.start()
    es.subscribe(EventName.EVENT_NAME, eventHandler)

    const eventHandler = (event) => {
    console.log(event)
    }
    +
    + +
    from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType

    def eventHandler(event):
    print(event)

    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    client.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)
    +
    + +
    curl -s http://NODE_ADDRESS:9999/events/CHANNEL
    +
    +
    +

    You can find node addresses of active online peers to replace NODE_ADDRESS, by navigating to cspr.live for Mainnet and testnet.cspr.live for Testnet.

    +

    Replace EVENT_NAME with one of the event types listed below.

    +

    Replace CHANNEL with one of the following event streams:

    +
      +
    • main for ApiVersion, BlockAdded, DeployExpired, DeployProcessed, Fault, or Step events.
    • +
    • deploys for DeployAccepted events.
    • +
    • sigs for FinalitySignature events.
    • +
    +

    Event Types

    +

    ApiVersion

    +

    The ApiVersion event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ApiVersion event structure.

    +
    data:{"ApiVersion":"1.0.0"}
    +

    BlockAdded

    +

    A BlockAdded event is emitted when a new block is added to the blockchain and stored locally in the node.

    +
    Expand to view output
    + +
    {
    "BlockAdded": {
    "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",
    "block": {
    "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",
    "header": {
    "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",
    "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",
    "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",
    "random_bit": true,
    "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",
    "era_end": null,
    "timestamp": "2023-01-01T09:55:25.312Z",
    "era_id": 8426,
    "height": 1566677,
    "protocol_version": "1.4.13"
    },
    "body": {
    "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",
    "deploy_hashes": [],
    "transfer_hashes": []
    },
    "proofs": []
    }
    }
    }
    +
      +
    • block_hash - The cryptographic hash that identifies a block.
    • +
    • block - The JSON representation of the block.
    • +
    • proposer - The validator selected to propose the block.
    • +
    +
    +

    DeployAccepted

    +

    DeployAccepted events are emitted when a node on the network receives a deploy.

    +
    Expand to view output
    + +
    {
    "DeployAccepted": {
    "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",
    "header": {
    "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",
    "timestamp": "2023-01-01T20:22:45.383Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",
    "dependencies": [],
    "chain_name": "casper-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "040008af2f",
    "parsed": "800000000"
    }
    ]
    ]
    }
    },
    "session": {
    "StoredContractByHash": {
    "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",
    "entry_point": "test_entry_point",
    "args": [
    [
    "cost",
    {
    "cl_type": "U512",
    "bytes": "0500c817a804",
    "parsed": "20000000000"
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",
    "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"
    }
    ]
    }
    }
    +
      +
    • hash - The blake2b hash of the Deploy.
    • +
    • account - The hexadecimal-encoded public key of the account submitting the Deploy.
    • +
    • body_hash - The blake2b hash of the Deploy body.
    • +
    • payment - Gas payment information.
    • +
    • session - The session logic defining the Deploy's functionality.
    • +
    • approvals - The signer's hexadecimal-encoded public key and signature.
    • +
    +
    +

    For details on custom serializations, check the Serialization Standard. Also, the Types page defines the terms used in the event stream output.

    +

    DeployProcessed

    +

    A DeployProcessed event is emitted when a given Deploy has been executed.

    +
    Expand to view output
    + +
    {
    "DeployProcessed": {
    "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",
    "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",
    "timestamp": "2023-01-01T10:07:00.401Z",
    "ttl": "30m",
    "dependencies": [],
    "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",
    "execution_result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",
    "transform": "Identity"
    },
    ]
    },
    "transfers": [
    "transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"
    ],
    "cost": "100000000"
    }
    }
    }
    }
    +
      +
    • deploy_hash - The cryptographic hash of a Deploy.
    • +
    • account - The hexadecimal-encoded public key of the account submitting the Deploy.
    • +
    • timestamp - A timestamp type representing a concrete moment in time.
    • +
    • dependencies - A list of Deploy hashes.
    • +
    • block_hash - A cryptographic hash identifying a Block.
    • +
    • execution_result - The execution status of the Deploy, which is either Success or Failure.
    • +
    +
    +

    DeployExpired

    +

    A DeployExpired event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired.

    +
    Expand to view output
    + +
    {
    "DeployExpired": {
    "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"
    }
    }
    + +
    +

    Fault

    +

    The Fault event is emitted if there is a validator error.

    +
    Expand the below section to view the Fault event details:
    + +
    {
    "Fault": {
    "era_id": 4591448806312642600,
    "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",
    "timestamp": "2023-01-01T01:26:58.364Z"
    }
    }
    +
      +
    • era_id - A period of time during which the validator set does not change.
    • +
    • public_key - The hexadecimal-encoded public key of the validator that caused the fault.
    • +
    • timestamp - A timestamp representing the moment the validator faulted.
    • +
    +
    +

    FinalitySignature

    +

    This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the consensus reached and block finality sections to learn more about finality signatures.

    +
    Expand to view output
    + +
    {
    "FinalitySignature": {
    "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",
    "era_id": 8419,
    "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",
    "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"
    }
    }
    +
      +
    • block_hash - A cryptographic hash identifying a Block.
    • +
    • era_id - A period of time during which the validator set does not change.
    • +
    • signature - Serialized bytes representing the validator's signature.
    • +
    • public_key - The hexadecimal-encoded public key of the validator.
    • +
    +
    +

    Step

    +

    The Step event is emitted at the end of every era and contains the execution effects produced by running the auction contract's step function.

    +
    Expand to view output:
    + +
    {
    "Step": {
    "era_id": 1,
    "execution_effect": {
    "operations": [],
    "transforms": [
    {
    "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",
    "transform": "Identity"
    },
    {
    "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",
    "transform": "Identity"
    },
    {
    "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",
    "transform": "Identity"
    },
    {
    "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",
    "transform": {
    "WriteBid": {
    "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",
    "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",
    "staked_amount": "1000000000000005",
    "delegation_rate": 5,
    "vesting_schedule": {
    "initial_release_timestamp_millis": 1664475057182,
    "locked_amounts": null
    },
    "delegators": {
    "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {
    "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",
    "staked_amount": "51312014671568117976319379",
    "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",
    "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",
    "vesting_schedule": {
    "initial_release_timestamp_millis": 1664475057182,
    "locked_amounts": null
    }
    }
    },
    "inactive": false
    }
    }
    }
    ]
    }
    }
    }
    +
      +
    • era_id - A period of time during which the validator set does not change.
    • +
    • execution_effect - The journal of execution transforms from a single Deploy.
    • +
    • operations - Operations performed while executing a Deploy.
    • +
    • transform - The actual transformation performed while executing a Deploy.
    • +
    +
    +

    Shutdown

    +

    The Shutdown event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream.

    +
    Expand the below section to view the Shutdown event details:
    + +
    "Shutdown"
    +
      +
    • Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.
    • +
    +
    +

    Reacting to Events

    +

    An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, DeployAccepted events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react.

    + + +
    const eventHandler = (event) => {
    if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {
    // Perform an action
    }
    }
    +
    + +
    def eventHandler(event):
    if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":
    # Perform an action
    +
    +
    +

    Unsubscribing from Events

    +

    In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the unsubscribe function:

    + + +
    es.unsubscribe(EventName.EVENT_NAME)
    +
    +
    +
      +
    • EVENT_NAME - One of the different event types emitted by a Casper node.
    • +
    +

    Stopping the Event Stream

    +

    A dApp may cease listening to all events using the stop function:

    + + +
    es.stop()
    +
    +
    +

    Replaying the Event Stream

    +

    This command will replay the event stream from an old event onward. Replace the NODE_ADDRESS, CHANNEL, and ID fields with the values of your scenario.

    + + +
    curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID
    +

    Example:

    +
    curl -sN http://65.21.235.219:9999/events/main?start_from=29267508
    +
    +
    +

    Each URL can have a query string added to the form ?start_from=ID, where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events.

    +
    note

    The server keeps only a limited number of events cached to allow replaying the stream to clients using the ?start_from= query string. The cache size can be set differently on each node using the event_stream_buffer_length value in the config.toml. By default, it is only 5000. +The intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/nctl-test/index.html b/1.5.X/developers/dapps/nctl-test/index.html new file mode 100644 index 000000000..d129e99cb --- /dev/null +++ b/1.5.X/developers/dapps/nctl-test/index.html @@ -0,0 +1,107 @@ + + + + + +Local Network Testing | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Testing Smart Contracts with NCTL

    +

    NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.

    +

    Testing Deploys prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.

    +

    Getting Started with NCTL

    +

    Prior to testing a Deploy through NCTL, you should have the following steps accomplished:

    +
      +
    1. +

      Completed writing a Deploy

      +
    2. +
    3. +

      Tested the Deploy using the Casper testing framework

      +
    4. +
    5. +

      Setup NCTL on your system

      +
    6. +
    +

    NCTL Verification Prior to Testing

    +

    Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:

    +
    nctl-status
    +

    You should see five nodes RUNNING and five STOPPED. Further, verify that the node and user information propagated within the casper-node/utils/assets directory. Each node and user should have the associated Keys necessary to interact with the network. Run the following command to view first user details:

    +
    nctl-view-user-account user=1
    +

    Installing the Smart Contract

    +

    This document assumes that you setup your NCTL network using the standard settings in a directory called /casper/.

    +

    You will need the following information to use the put-deploy command:

    +
      +
    • +

      The chain name, in this case casper-net-1. This will appear in our example put-deploy as --chain-name "casper-net-1"

      +
    • +
    • +

      The secret key of the account sending the Deploy. For this example, we are using node-1 as the sender. The secret key file can be found at casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. In our example put-deploy, this will appear as --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. If your Deploy is more complex and requires multiple accounts, NCTL also establishes multiple users for testing.

      +
    • +
    • +

      The payment amount in motes, which should be sufficient to avoid an 'Out of Gas' error. The payment amount will appear in our example put-deploy as --payment-amount 2500000000. NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our note about gas prices.

      +
    • +
    • +

      The path to your Deploy that you wish to send to the NCTL network. This will appear in our example put-deploy as --session-path <PATH> and will require you to define the path to your specific Deploy Wasm.

      +
    • +
    • +

      The node address for a node on your NCTL network. In this example, we are using the node at http://localhost:11101. On the Casper Mainnet or Testnet, nodes will use port 7777. This will appear in our example put-deploy as --node-address http://<HOST>:7777.

      +
    • +
    +

    The command to send your Deploy should look similar to the following code snippet:

    +
    note

    Use of the $(get_path_to_client) command assumes that you are operating in an activated NCTL envrionment.

    +
    $(get_path_to_client) put-deploy \
    --chain-name "casper-net-1" \
    --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --payment-amount 2500000000 \
    --session-path <PATH> \
    --node-address http://localhost:11101
    +

    The response will return something similar to the following information. Note the deploy_hash:

    +
    {
    "id": 4824893960188648146,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"
    }
    }
    +

    Verifying Deploy Execution

    +

    The previous command sent the Deploy to the NCTL network, but we recommend verifying deploy execution before continuing. The deploy_hash received in the response allows you to query the Deploy's status.

    +

    To query the Deploy's status, you will pass both the deploy_hash and the same node-address from above using the following command. This will return either an error message in the event of failure or the Deploy details if it succeeds.

    +
    $(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101
    +

    Interacting with the Installed Contract

    +

    Once your NCTL network executes your Deploy, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ContractHash itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to send the Deploy, we can retrieve the ContractHash from the node-1 account information. To do so, we will use the following command with a node address and the PublicKey of the node in question.

    +
    $(get_path_to_client) get-account-info \
    --node-address http://localhost:11101 \
    --public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem
    +

    This command will return information pertaining to the account, including the NamedKeys. The ContractHash of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a Deploy. In this instance, you will need the following information:

    +
      +
    • +

      The node address, entered in this instance using --node-address http://localhost:11101

      +
    • +
    • +

      The chain name, entered in this instance using --chain-name "casper-net-1"

      +
    • +
    • +

      The payment amount for this Deploy in motes, which may need to be adjusted depending on cost and network chainspec. In this instance, we will use --payment-amount 500000000

      +
    • +
    • +

      The session path, defining the location of the Wasm bearing file for the Deploy. It appears in our example as --session-path <PATH> but you must define the path to your specific file.

      +
    • +
    • +

      Any session arguments specific to the contract that you are testing. Multiple instances of --session-arg may be used as necessary to provide values to the contract, including the ContractHash you acquired above. In the example below, you will see a demonstration of the ContractHash as a session argument as --session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"

      +
    • +
    +
    $(get_path_to_client) put-deploy \
    --node-address http://localhost:11101 \
    --chain-name "casper-net-1" \
    --payment-amount 500000000 \
    --session-path <PATH> \
    --session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"
    +

    Verifying Correct Contract Behavior

    +

    After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the basic smart contract tutorial, the NCTL process would have the following flow:

    +
      +
    1. +

      Send a Deploy to install the "Donation" smart contract.

      +
    2. +
    3. +

      Verify the execution of the Deploy.

      +
    4. +
    5. +

      Interact with the installed contract using an additional Deploy that calls one or several of the entry points. For example, calling the donate entry point to donate an amount to the fundraising purse.

      +
    6. +
    7. +

      Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse.

      +
    8. +
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/prerequisites/index.html b/1.5.X/developers/dapps/prerequisites/index.html new file mode 100644 index 000000000..f6d0bc54d --- /dev/null +++ b/1.5.X/developers/dapps/prerequisites/index.html @@ -0,0 +1,51 @@ + + + + + +Prerequisites | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Prerequisites

    +

    Before trying your hand at dApp development on a Casper network, there are a few things you should do first:

    +
      +
    1. +

      Set up your development environment.

      +
    2. +
    3. +

      Be sure you understand the language(s) you are developing in.

      +

      Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you.

      +

      The preferred stack for building on Casper is JavaScript using the Casper JS SDK, however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the Introduction to SDKs.

      +
    4. +
    5. +

      Familiarize yourself with the fundamentals of Casper networks.

      +

      Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the design section.

      +
    6. +
    7. +

      Read the documentation or source code of your chosen SDK.

      +

      Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see Client Library Usage.

      +
    8. +
    +

    Development Considerations

    +

    When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value.

    +

    To ensure the highest level of security, consider the following practices:

    +
      +
    1. Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code.
    2. +
    3. Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors.
    4. +
    5. Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet.
    6. +
    7. Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes.
    8. +
    9. Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities.
    10. +
    11. Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively.
    12. +
    +

    By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/sdk/client-library-usage/index.html b/1.5.X/developers/dapps/sdk/client-library-usage/index.html new file mode 100644 index 000000000..1af202c2d --- /dev/null +++ b/1.5.X/developers/dapps/sdk/client-library-usage/index.html @@ -0,0 +1,172 @@ + + + + + +SDK Client Library Usage | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem';

    +

    SDK Client Library Usage

    +

    Installing the SDKs

    + + +

    Use npm or yarn to install the casper-js-sdk package:

    +
    npm install casper-js-sdk
    +
    yarn install casper-js-sdk
    +
    + +

    Use pip to install the pycspr package:

    +
    pip install pycspr
    +
    + +

    Include the casper-client dependency to your Cargo.toml:

    +
    [dependencies]
    casper-client="1.5.1"
    +

    and add it to your main.rs:

    +
    extern crate casper_client;
    +

    Use types and methods from casper_client:

    +
    use casper_client::transfer;
    use casper_client::put_deploy;
    //...
    +

    as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:

    +
    [dependencies]
    tokio = { version = "^1.27.0", features = ["full"] }
    +
    +
    +
    +

    Creating Accounts

    +

    You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the Accounts and Cryptographic Keys page for more details.

    +

    Creating new account keys

    + + +
    const { Keys } = require("casper-js-sdk");
    const keypair = Keys.Ed25519.new();
    const { publicKey, privateKey } = keypair;
    +

    Replace Ed25519 with Secp256K1 if you wish.

    +
    + +
    from pycspr.crypto import KeyAlgorithm, get_key_pair
    keypair = get_key_pair(KeyAlgorithm.ED25519)
    +

    Replace ED25519 with SECP256K1 if you wish.

    +
    + +

    Create a keypair and write the files to a specified PATH:

    +
        casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();
    +

    Replace ED25519 with SECP256K1 if you wish.

    +
    +
    +

    Exporting the public key and account hash

    +

    The keypair variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash.

    + + +
    // Create a hexadecimal representation of the public key and account hash.
    const publicKeyHex = publicKey.toHex();
    const accountHashHex = publicKey.toAccountHashStr();
    +

    Note that accountHashHex will be prefixed with the text "account-hash-".

    +
    + +
    import pycspr.crypto

    publicKeyBytes = keypair.account_key
    publicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)
    accountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)
    accountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)
    +
    +
    +

    Uploading the secret key from a file

    +

    To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below.

    + + +
    const { Keys } = require("casper-js-sdk");
    const keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");
    +

    Replace Ed25519 with Secp256K1 if you wish.

    +
    + +
    import pycspr
    keypair = pycspr.parse_private_key(
    "./secret_key.pem",
    pycspr.crypto.KeyAlgorithm.ED25519
    )
    +

    Replace ED25519 with SECP256K1 if you wish.

    +
    + +

    In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:

    +
    let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{
    secret_key:"./secret_key.pem",
    timestamp:"",
    ...
    };
    +
    +
    +
    +

    Transferring CSPR

    +

    Using the keypair created above, you can sign a deploy that transfers CSPR.

    +

    Replace the NODE_ADDRESS and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on cspr.live and for Testnet on testnet.cspr.live. The RPC port is usually 7777, but it depends on the network's configuration settings.

    + + +
    const { CasperClient, DeployUtil } = require("casper-js-sdk");

    const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");
    const receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"

    const amount = 2.5e9 // Minimum transfer: 2.5 CSPR
    let deployParams = new DeployUtil.DeployParams(
    keypair.publicKey,
    "casper" // or "casper-test" for Testnet
    );

    const session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(
    amount,
    recipientPublicKeyHex
    );

    const payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR
    const deploy = DeployUtil.makeDeploy(deployParams, session, payment);
    const signedDeploy = DeployUtil.signDeploy(deploy, keypair);

    console.log(await casperClient.putDeploy(signedDeploy));
    +
    + +
    import pycspr

    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    recipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"
    recipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)

    deployParams = pycspr.create_deploy_parameters(
    account = keypair,
    chain_name = "casper" # or "casper-test" for Testnet
    )

    deploy = pycspr.create_transfer(
    params = deployParams,
    amount = int(2.5e9), # Minimum transfer: 2.5 CSPR
    target = recipientPublicKeyBytes
    )

    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())
    +
    + +
    extern crate casper_client;
    async fn send_transfer(){
    let maybe_rpc_id: &str = "";
    let node_address: &str = "http://135.181.216.142:7777";
    let verbosity_level: u64 = 1;
    let amount: &str = "2500000000";
    let target_account: &str = recipient;
    let transfer_id: &str = "1";
    let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{
    secret_key:"./sk_testnet.pem",
    timestamp:"",
    ttl:"50s",
    gas_price:"1000000000",
    chain_name:"casper", // or "casper-test" for testnet
    dependencies: Vec::new(),
    session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"

    };
    let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";
    let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);
    let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();
    println!("Deploy response: {:?}", result);
    }

    #[tokio::main]
    async fn main(){
    send_transfer().await;
    }
    +
    +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    +
    +

    Installing Contracts

    +

    To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm.

    +

    Replace the NODE_ADDRESS and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on cspr.live and for Testnet on testnet.cspr.live. The RPC port is usually 7777, but it depends on the network's configuration settings.

    + + +
    const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")
    const fs = require("fs")

    const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")
    const contract = new Contracts.Contract(casperClient)

    const contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)

    const runtimeArguments = RuntimeArgs.fromMap({
    "argument": CLValueBuilder.string("Hello world!")
    })

    const deploy = contract.install(
    contractWasm,
    runtimeArguments,
    "10000000000", // Gas payment (10 CSPR)
    keypair.publicKey,
    "casper", // or "casper-test" for Testnet
    [keypair]
    )

    console.log(await casperClient.putDeploy(deploy))
    +
    + +
    import pycspr
    from pycspr.types import ModuleBytes, CL_String

    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))

    deployParams = pycspr.create_deploy_parameters(
    account = keypair,
    chain_name = "casper" # or "casper-test" for Testnet
    )
    payment = pycspr.create_standard_payment(10000000000) # 10 CSPR
    session = ModuleBytes(
    module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),
    args = {
    "message": CL_String("Hello world!"),
    }
    )

    deploy = pycspr.create_deploy(deployParams, payment, session)

    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())
    +
    + +
    extern crate casper_client;
    async fn put_deploy(){
    let maybe_rpc: &str = "";
    let verbosity: u64 = 1;
    let node_address: &str = "http://135.181.216.142:7777";
    let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{
    secret_key:"./sk_testnet.pem",
    timestamp:"",
    ttl:"50s",
    gas_price:"1000000000",
    chain_name:"casper", // or "casper-test"
    dependencies: Vec::new(),
    session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"

    };
    // Without session args:
    // let session_args: Vec<&str> = Vec::new();
    // With session args:
    let mut session_args: Vec<&str> = Vec::new();
    session_args.push("argument:String='hello world'");
    let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");
    let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");
    let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();
    println!("Deploy response: {:?}", result);
    }

    #[tokio::main]
    async fn main(){
    send_transfer().await;
    }
    +
    +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    +

    Staking

    +

    Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network.

    +

    The delegation functionality is available as a smart contract, which can be found in the casper-node repository. To delegate tokens, first clone the repository:

    +
    git clone https://github.com/casper-network/casper-node.git
    cd casper-node/
    +

    Then compile the delegate contract:

    +
    make setup-rs
    make build-contract-rs/delegate
    +

    Now, assuming that you cloned casper-node from your project's root directory, cd back into it:

    +
    cd ../
    +

    Now in your dApp's backend (or standalone script), load the delegate.wasm file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.

    + + +
    const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");
    const fs = require("fs");

    const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")
    const contract = new Contracts.Contract(casperClient)

    const contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);

    const runtimeArguments = RuntimeArgs.fromMap({
    "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR
    "delegator": keypair.publicKey,
    "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")
    });

    const deploy = contract.install(
    contractWasm,
    runtimeArguments,
    "5000000000", // Gas payment (5 CSPR)
    keypair.publicKey,
    "casper", // or "casper-test" for testnet
    [keypair]
    );

    (async () => {
    console.log(await casperClient.putDeploy(deploy));
    })();
    +
    + +
    import pycspr

    validator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(
    bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")
    )

    deploy_params = pycspr.create_deploy_parameters(
    account = keypair, # Only the public key is used, see `create_deploy_parameters`
    chain_name = "casper" # or "casper-test" for testnet
    )

    deploy = pycspr.create_validator_delegation(
    params = deploy_params,
    amount = int(500e9), # Minimum delegation amount: 500 CSPR
    public_key_of_delegator = keypair,
    public_key_of_validator = validator_public_key,
    path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"
    )

    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())
    +
    + +
    extern crate casper_client;
    async fn put_deploy(){
    let maybe_rpc: &str = "";
    let verbosity: u64 = 1;
    let node_address: &str = "http://135.181.216.142:7777";
    let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{
    secret_key:"./sk_testnet.pem",
    timestamp:"",
    ttl:"50s",
    gas_price:"1000000000",
    chain_name:"casper", // or "casper-test" for testnet
    dependencies: Vec::new(),
    session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"

    };
    let mut session_args: Vec<&str> = Vec::new();
    session_args.push("amount:U512='500000000000'");

    session_args.push("delegator:public_key='01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a'");
    session_args.push("validator:public_key='validator_public_key'");

    let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");
    let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");
    let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();
    println!("Deploy result: {:?}", result);
    }

    #[tokio::main]
    async fn main(){
    put_deploy().await;
    }
    +
    +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    +
    +

    Calling Contracts

    +

    Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:

    + + +
    const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");
    const contract = new Contracts.Contract(casperClient);
    contract.setContractHash(
    "hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"
    );
    const runtimeArguments = RuntimeArgs.fromMap({
    "message": CLValueBuilder.string("Hello world!")
    })
    const deploy = contract.callEntrypoint(
    "update_msg",
    runtimeArguments,
    keypair.publicKey,
    "casper", // or "casper-test" for Testnet
    "1000000000", // 1 CSPR (10^9 Motes)
    [keypair]
    );
    (async () => {
    console.log(await casperClient.putDeploy(deploy))
    })();
    +
    + +
    import pycspr
    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    deployParams = pycspr.create_deploy_parameters(
    account = keypair,
    chain_name = "casper-test"
    )
    payment = pycspr.create_standard_payment(10_000_000_000)
    session = pycspr.types.StoredContractByHash(
    entry_point = "update_msg",
    hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),
    args = {
    "message": pycspr.types.CL_String("Hello world!"),
    }
    )
    deploy = pycspr.create_deploy(deployParams, payment, session)
    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())
    +
    +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    +
    +

    Staking

    +

    Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network.

    +

    The delegation functionality is available as a smart contract, which can be found in the casper-node repository. To delegate tokens, first clone the repository:

    +
    git clone https://github.com/casper-network/casper-node.git
    cd casper-node/
    +

    Then compile the delegate contract:

    +
    make setup-rs
    make build-contract-rs/delegate
    +

    Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the delegate.wasm file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.

    + + +
    const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");
    const fs = require("fs");

    const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")
    const contract = new Contracts.Contract(casperClient)

    const contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);

    const runtimeArguments = RuntimeArgs.fromMap({
    "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR
    "delegator": keypair.publicKey,
    "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")
    });

    const deploy = contract.install(
    contractWasm,
    runtimeArguments,
    "5000000000", // Gas payment (5 CSPR)
    keypair.publicKey,
    "casper", // or "casper-test" for testnet
    [keypair]
    );

    (async () => {
    console.log(await casperClient.putDeploy(deploy));
    })();
    +
    + +
    import pycspr

    validator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(
    bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")
    )

    deploy_params = pycspr.create_deploy_parameters(
    account = keypair, # Only the public key is used, see `create_deploy_parameters`
    chain_name = "casper" # or "casper-test" for testnet
    )

    deploy = pycspr.create_validator_delegation(
    params = deploy_params,
    amount = int(500e9), # Minimum delegation amount: 500 CSPR
    public_key_of_delegator = keypair,
    public_key_of_validator = validator_public_key,
    path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"
    )

    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())
    +
    +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/sdk/csharp-sdk/index.html b/1.5.X/developers/dapps/sdk/csharp-sdk/index.html new file mode 100644 index 000000000..691044b92 --- /dev/null +++ b/1.5.X/developers/dapps/sdk/csharp-sdk/index.html @@ -0,0 +1,39 @@ + + + + + +.NET SDK | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    .NET SDK

    +

    The C# .NET SDK allows developers to interact with a Casper network using C#.

    +

    Documentation

    +

    Visit https://make-software.github.io/casper-net-sdk/ to find the SDK documentation, examples, and tutorials.

    +

    Get started

    +

    This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing.

    +

    Open a terminal window and create a new console app:

    +
    dotnet new console -o GetAccountBalance
    cd GetAccountBalance
    +

    The Casper.Network.SDK for .NET is published on nuget.org as a NuGet package.

    +

    To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the dotnet CLI tool.

    +

    Package Manager (Windows)

    +
    Install-Package Casper.Network.SDK
    +

    dotnet CLI Tool (Windows, Mac, and Linux)

    +
    dotnet add package Casper.Network.SDK
    +

    Now, replace the default code in Program.cs with this main program:

    +
    using System;
    using System.Threading.Tasks;
    using Casper.Network.SDK;
    using Casper.Network.SDK.JsonRpc;
    using Casper.Network.SDK.Types;

    namespace Casper.NET.SDK.Examples
    {
    public class GetAccountBalance
    {
    public static async Task Main(string[] args)
    {
    string nodeAddress = "http://testnet-node.make.services:7777";

    var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";
    var publicKey = PublicKey.FromHexString(hex);

    try
    {
    var casperSdk = new NetCasperClient(nodeAddress);

    // Get the balance using the account public key
    //
    var rpcResponse = await casperSdk.GetAccountBalance(publicKey);
    Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);
    }
    catch (RpcClientException e)
    {
    Console.WriteLine("ERROR:\n" + e.RpcError.Message);
    }
    catch (Exception e)
    {
    Console.WriteLine(e);
    }
    }
    }
    }
    +

    Finally, run the example with:

    +
    dotnet run
    +

    The program will print the account's main purse balance retrieved from the testnet.

    +

    Visit https://make-software.github.io/casper-net-sdk/ to find other examples, tutorials, and complete documentation for this SDK.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/sdk/go-sdk/index.html b/1.5.X/developers/dapps/sdk/go-sdk/index.html new file mode 100644 index 000000000..72d21e903 --- /dev/null +++ b/1.5.X/developers/dapps/sdk/go-sdk/index.html @@ -0,0 +1,33 @@ + + + + + +Go SDK | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Go SDK

    +

    Usage Examples

    +

    This section includes some examples of how to use Go SDK:

    + +

    Get a Deploy from the Network

    +
    package main

    import (
    "context"
    "fmt"
    "net/http"

    "github.com/make-software/casper-go-sdk/casper"
    )

    func main() {
    handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)
    client := casper.NewRPCClient(handler)
    deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"
    deploy, err := client.GetDeploy(context.Background(), deployHash)
    if err != nil {
    return
    }
    fmt.Println(deploy.Deploy.Hash)
    }
    +

    Handle the Deploy Processed Event

    +
    package main

    import (
    "context"
    "log"

    "github.com/make-software/casper-go-sdk/sse"
    )

    func main() {
    client := sse.NewClient("https://<Node Address and Port>/events/main")
    defer client.Stop()
    client.RegisterHandler(
    sse.DeployProcessedEventType,
    func(ctx context.Context, rawEvent sse.RawEvent) error {
    deploy, err := rawEvent.ParseAsDeployProcessedEvent()
    if err != nil {
    return err
    }
    log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)
    return nil
    })
    lastEventID := 1234
    client.Start(context.TODO(), lastEventID)
    }
    +

    Sending a Transfer

    +
    package main

    import (
    "context"
    "encoding/hex"
    "log"
    "math/big"
    "net/http"

    "github.com/make-software/casper-go-sdk/casper"
    "github.com/make-software/casper-go-sdk/types/clvalue"
    )

    func main() {
    accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")
    if err != nil { return }
    amount := big.NewInt(100000000)
    session := casper.ExecutableDeployItem{
    ModuleBytes: &casper.ModuleBytes{
    ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),
    Args: (&casper.Args{}).
    AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).
    AddArgument("amount", *clvalue.NewCLUInt512(amount)),
    },
    }

    payment := casper.StandardPayment(amount)

    deployHeader := casper.DefaultHeader()
    deployHeader.Account = accountPublicKey
    deployHeader.ChainName = "casper-test"

    newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)

    handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)
    client := casper.NewRPCClient(handler)
    result, err := client.PutDeploy(context.Background(), *newDeploy)

    log.Println(result.DeployHash)
    }
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/sdk/python-sdk/index.html b/1.5.X/developers/dapps/sdk/python-sdk/index.html new file mode 100644 index 000000000..cf6a35268 --- /dev/null +++ b/1.5.X/developers/dapps/sdk/python-sdk/index.html @@ -0,0 +1,85 @@ + + + + + +Python SDK | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Python SDK

    +

    The Python SDK allows developers to interact with the Casper platform using Python 3.12+.

    +

    Installation

    +
    pip3 install pycspr
    +

    How To's

    +

    The following set of How To's cover the full SDK feature set and are designed to be run against a CCTL network.

    +

    Cryptography

    + +

    Deploys

    + +

    Smart Contracts

    + +

    Node APIs

    +
    + + \ No newline at end of file diff --git a/next/developers/dapps/sdk/script-sdk/index.html b/1.5.X/developers/dapps/sdk/script-sdk/index.html similarity index 78% rename from next/developers/dapps/sdk/script-sdk/index.html rename to 1.5.X/developers/dapps/sdk/script-sdk/index.html index 7c1e09026..90d2477da 100644 --- a/next/developers/dapps/sdk/script-sdk/index.html +++ b/1.5.X/developers/dapps/sdk/script-sdk/index.html @@ -1,21 +1,21 @@ - + -JavaScript/TypeScript SDK | Casper Docs - Redux +JavaScript/TypeScript SDK | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    JavaScript/TypeScript SDK

    This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.

    Usage of JavaScript Clients

    The Casper team has implemented specific JS clients to support interaction with the Casper contracts.

    @@ -52,6 +52,6 @@

    Sending a

    Here is the code you can use to serialize the deploy:

    const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);

    Then, you can reconstruct the deploy object using this function:

    -
    const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);

    +
    const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);
    \ No newline at end of file diff --git a/1.5.X/developers/dapps/setup-nctl/index.html b/1.5.X/developers/dapps/setup-nctl/index.html new file mode 100644 index 000000000..8cc82b7e9 --- /dev/null +++ b/1.5.X/developers/dapps/setup-nctl/index.html @@ -0,0 +1,114 @@ + + + + + +Local Network Setup | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Setting up a Local Network with NCTL

    +

    NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.

    +

    Prerequisites

    +
      +
    1. You have completed the Getting Started section, which shows you how to install your development environment, including tools like CMake (version 3.1.4+), Cargo, and Rust.
    2. +
    3. Make sure you have Python 3 installed if your operating system does not include Python.
    4. +
    5. To run NCTL, you will also need the bash shell.
    6. +
    +

    Video Tutorial

    +

    If you prefer a video walkthrough of this guide, you can check out this video.

    + +

    Installing a Virtual Environment

    +

    We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing.

    +

    First, you will need to install a set of tools required for running NCTL.

    +

    Step 1. The first tool you will need is pip, a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or the full installation instructions.

    +

    Instructions for MacOS:

    +
    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    python3 get-pip.py
    +

    Instructions for Linux:

    +
    sudo apt install python3-pip
    +

    Step 2. Install pkg-config, a program used to compile and link against one or more libraries.

    +

    Instructions for MacOS:

    +
    brew install pkg-config
    +

    Instructions for Linux:

    +
    sudo apt install pkg-config
    +

    Step 3. Install either libssl-dev (Linux) or openssl (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries.

    +

    Instructions for MacOS:

    +
    brew install openssl
    +

    Instructions for Linux:

    +
    sudo apt install libssl-dev
    +

    Step 4. You will also need the gcc and g++ compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing).

    +

    Instructions for MacOS:

    +
    xcode-select --install
    gcc --version
    g++ --version
    +

    Instructions for Linux:

    +
    sudo apt install build-essential
    gcc --version
    g++ --version
    +

    Important Note:

    +

    The following commands need to be executed within the Bash shell. While MacOS and some Linux distributions use Zsh by default, they also include Bash. To ensure proper execution of the subsequent commands, switching to Bash is recommended. If the command does not work, please refer to the Bash documentation on how to install it on your system.

    +

    Step 5. Switching to Bash Shell:

    +

    Type the following command in your terminal:

    +

    Instructions for MacOS and Linux:

    +
    bash
    +

    This will launch a new Bash shell session. You can then proceed with the tutorial.

    +

    Step 6. Create and activate a new virtual environment. Commands applicable to the virtual environment will be prefixed with (env). Run the following commands to set it up.

    +

    Instructions for MacOS and Linux:

    +
    python3 -m venv env
    source env/bin/activate
    +

    Once you have activated the virtual environment, your terminal prompt will change to indicate you're working within it. It will usually look something like this:

    +
    (env) $  // This line is for visual representation only, not to be copied
    +

    Step 7. Inside the virtual environment, upgrade pip to the latest version.

    +

    Instructions for MacOS and Linux:

    +
    pip install --upgrade pip
    +

    Step 8. Install jq, a command-line JSON processor.

    +

    Instructions for MacOS and Linux:

    +
    pip install jq
    +

    Step 9. Install supervisor, a cross-platform process manager.

    +

    Instructions for MacOS and Linux:

    +
    pip install supervisor
    +

    Step 10. Install toml, a configuration file parser.

    +

    Instructions for MacOS and Linux:

    +
    pip install toml
    +

    Setting up the Network

    +

    You are now ready to set up and run your local network of Casper nodes.

    +

    Step 11. Clone the casper-node-launcher software in your working directory, which we will call WORKING_DIRECTORY. Very Important!!! Choose a short path for your working directory; otherwise, the NCTL tool will report that the path is too long.

    +

    Instructions for MacOS and Linux:

    +
    cd <WORKING_DIRECTORY>
    git clone https://github.com/casper-network/casper-node-launcher
    +
    note

    Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the deploy_delay in your local config.toml before running nctl-assets-setup.

    +

    Step 12. Next, clone the casper-node software, also in your working directory.

    +

    Instructions for MacOS and Linux:

    +
    git clone https://github.com/casper-network/casper-node
    +

    Step 13. Finally, clone the casper-client-rs software in your working directory.

    +

    Instructions for MacOS and Linux:

    +
    git clone https://github.com/casper-ecosystem/casper-client-rs
    +

    Step 14. Activate the NCTL environment with the following command.

    +

    Instructions for MacOS and Linux:

    +
    source casper-node/utils/nctl/activate
    +

    Step 15. Compile the NCTL binary scripts. The following command compiles both the casper-node and the casper-client in release mode.

    +

    Instructions for MacOS and Linux:

    +
    nctl-compile
    +
    note

    The compilation takes some time, so it might be a perfect moment to get some coffee.

    +

    Step 16. Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes.

    +

    Instructions for MacOS and Linux:

    +
    nctl-assets-setup && nctl-start
    +

    Once a network is up and running, you can control each node within the network and add new nodes to the network.

    +

    Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by nctl- and allow you to perform various tasks.

    +

    You should see the new directory utils/nctl/assets, with the following structure.

    +

    +

    Here is the command line output you would expect.

    +

    +

    Stopping the Network

    +

    Step 17. Although not necessary, you can stop and clean the NCTL setup with the following commands.

    +

    Instructions for MacOS and Linux:

    +
    nctl-stop
    nctl-clean
    +

    Next Steps

    +
      +
    1. Explore the various NCTL commands.
    2. +
    3. Explore the NCTL usage guide.
    4. +
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/signing-a-deploy/index.html b/1.5.X/developers/dapps/signing-a-deploy/index.html new file mode 100644 index 000000000..d6e0be2e8 --- /dev/null +++ b/1.5.X/developers/dapps/signing-a-deploy/index.html @@ -0,0 +1,35 @@ + + + + + +Signing Deploys | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Signing Deploys

    +

    When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.

    +

    When a signature is attached to a deploy, it is paired with the public key of the signer, and referred to as an Approval. Every valid deploy has at least one approval.

    +

    The signature creation process begins with the hashing of the payment and session of the deploy to create the BodyHash. The BodyHash becomes a component of the DeployHeader as outlined in the serialization standard. From there, the DeployHeader can be hashed to create the DeployHash. As outlined above, the DeployHash is then combined with the account's key-pair to create the deploy's signature.

    +

    As the DeployHash contains a hash of the deploy's body within, any variation to any aspect of the deploy or sending account's keys would render the DeployHash invalid.

    +

    Public Key Cryptography

    +

    Casper networks are compatible with both Ed25519 and Secp256k1 public key cryptography. When serialized, public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with 1, whereas Secp256k1 are prefixed with 2.

    +

    Casper uses blake2b hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:

    +
      +
    • +

      Ed25519 signs over a SHA-512 digest.

      +
    • +
    • +

      Secp256k1 signs over a SHA-256 digest.

      +
    • +
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/speculative-exec/index.html b/1.5.X/developers/dapps/speculative-exec/index.html new file mode 100644 index 000000000..f7cb2bf83 --- /dev/null +++ b/1.5.X/developers/dapps/speculative-exec/index.html @@ -0,0 +1,28 @@ + + + + + +Estimating Gas Costs with Speculative Execution | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Estimating Gas Costs with Speculative Execution

    +

    Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculative_exec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.

    +

    In addition to the Deploy in question, speculative_exec also accepts a [block_identifier] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block.

    +

    Sending a Speculative Execution Deploy using the Rust CLI Casper Client

    +

    The Rust CLI Casper client includes a speculative-exec option that will flag a normal put-deploy for execution but not commitment to global state. The following command shows an example:

    +

    casper client put-deploy /
    --node-address <HOST:PORT> /
    --chain-name <CHAIN_NAME> /
    --secret-key <PATH> /
    --session-path <PATH> /
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES>
    --speculative-exec <BLOCK HEIGHT OR HASH>

    +

    You should receive execution_results that show a cost.

    +

    {
    "jsonrpc": "2.0",
    "id": -4571113357017152230,
    "result": {
    "api_version": "1.0.0",
    "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",
    "execution_result": {
    "Success": {
    "effect": {
    <Deploy effects removed for conciseness.>
    },
    "transfers": [],
    "cost": "87300473670"
    }
    }
    }
    }

    +
    note

    Cost estimates acquired through speculative_exec may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/technology-stack/index.html b/1.5.X/developers/dapps/technology-stack/index.html new file mode 100644 index 000000000..b22986c88 --- /dev/null +++ b/1.5.X/developers/dapps/technology-stack/index.html @@ -0,0 +1,60 @@ + + + + + +dApp Technology Stack | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem';

    +

    dApp Technology Stack

    +

    There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.

    +

    Front-End

    +

    The front-end, or client-side of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried.

    +

    You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill CORS requirements.

    +

    Signing Transactions

    +

    The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:

    +
      +
    1. +

      The Casper Wallet

      +

      Use the Casper Wallet to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node.

      +
      caution

      The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

      +
    2. +
    3. +

      Third-party signers

      +

      Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object.

      +
    4. +
    +

    Querying Global State

    +

    To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query.

    +

    Backend

    +

    The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect CORS headers from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain.

    +

    As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to.

    + + +
    const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");
    +
    + +
    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    +
    +
    +
    tip

    You can find online peers for Mainnet at cspr.live or testnet at testnet.cspr.live

    +

    There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end.

    +

    Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end.

    +

    In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along.

    +

    Blockchain

    +

    The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open transactional, informational, and Proof-of-Stake endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods.

    +

    More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as WebAssembly binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in Rust for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust.

    +

    To learn how to write smart contracts for your dApp, read the smart contract documentation.

    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/template-frontend/index.html b/1.5.X/developers/dapps/template-frontend/index.html new file mode 100644 index 000000000..9426153d2 --- /dev/null +++ b/1.5.X/developers/dapps/template-frontend/index.html @@ -0,0 +1,95 @@ + + + + + +Front-end in React | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    +

    Front-end Template with React

    +

    For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.

    +

    This guide will walk you through setting up and developing a React application with Vite that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by reading the React documentation.

    +

    Get Started

    +

    Begin by opening a terminal and running:

    +
    node -v
    +

    To get your Node.js version.

    +

    To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the Node Version Manager or another tool if you are running an earlier version.

    +

    Using npm, create a new Vite project by running:

    +
    npm install -g vite
    npm create vite@latest
    +

    Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.

    +

    Head into your new project directory, replacing vite-project with your project name:

    +
    cd vite-project/
    +

    Run the following command to test the server:

    +
    npm install
    vite dev
    +

    Quit the server by pressing q. Install the Casper JS SDK by running the following:

    +
    npm install casper-js-sdk
    +

    This guide will use axios to communicate with the backend; install it by running:

    +
    npm install axios
    +

    Casper Wallet Integration

    +

    The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with window.CasperWalletProvider and window.CasperWalletEventTypes. If the value of these variables is undefined the Casper Wallet is not installed.

    +

    Start with a helper for getting the provider instance:

    +
    touch src/casper-wallet.js
    +

    Fill the file with the following content:

    +
    // Timeout (in ms) for requests to the extension [DEFAULT: 30 min]
    const REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;

    export const getProvider = () => {
    let providerConstructor = window.CasperWalletProvider;
    if (providerConstructor === undefined) {
    alert("Casper Wallet extension is not installed!");
    return;
    }
    let provider = providerConstructor({
    timeout: REQUESTS_TIMEOUT_MS
    });
    return provider;
    }

    +
    tip

    For complete integration details, refer to README of Casper Wallet SDK.

    +

    To ensure that a user's public key will be available to all necessary components, create a React state variable in src/App.jsx or another parent component that encapsulates the components that should have access to this public key:

    +
    import React from "react";
    import Connect from "./Connect";
    import './App.css'

    function App() {
    const [publicKey, setPublicKey] = React.useState(null);
    return (
    <>
    <Connect setPublicKey={ setPublicKey } />
    <div>
    {publicKey !== null && (<>
    Wallet connected: {publicKey}<br/>
    </>)}
    </div>
    </>
    );
    }

    export default App;
    +

    This is an example of src/App.jsx that imports and displays the Connect component that is described next. The setPublicKey function is passed to the Connect component as a prop so that it may set the public key and make it available to all of src/App.jsx. This way, when more components are added to src/App.jsx, they may utilize the publicKey variable.

    +

    To connect to the Casper Wallet within your React app, create the Connect component and import the getProvider helper.

    +
    touch src/Connect.jsx
    +

    Open the file and write:

    +
    import { getProvider } from "./casper-wallet";

    const provider = getProvider();

    const Connect = (props) => {
    return (
    <>
    <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>
    {/* Place for disconnect button */}
    </>
    );
    }

    export default Connect;
    +

    Notice that Connect accepts props, and forwards them to the connectToWallet function described below. This function is called when the button is clicked, allowing it to set the public key within src/App.jsx using props.setPublicKey().

    +

    Write the connectToWallet function under the Connect function component:

    +
    const connectToWallet = (props) => {
    provider.requestConnection().then(connected => {
    if (!connected) {
    alert("Couldn't connect to wallet");
    } else {
    provider.getActivePublicKey().then(publicKey => {
    props.setPublicKey(publicKey);
    }).catch(error => {
    alert(error.message);
    });
    }
    })
    .catch(error => {
    alert(error.message);
    });
    }
    +

    The connectToWallet() function calls provider.isConnected() to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. provider.isConnected() will throw an error if the Wallet is not installed as an extension or if it is locked.

    +

    Disconnect the Casper Wallet

    +

    To request that the Casper Wallet disconnect from a website, add the following function call to src/Connect.jsx:

    +
    const disconnect = (props) => {
    provider.disconnectFromSite().then(disconnected => {
    if (disconnected) {
    props.setPublicKey(null);
    alert("Disconnected");
    }
    }).catch(error => {
    alert(error.message);
    });
    }
    +

    Then connect it to a button:

    +
    const Connect = (props) => {
    return (
    <>
    <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>
    // highlight-next-line-green
    <button onClick={ () => disconnect(props) }>Disconnect</button>
    </>
    );
    }
    +

    Call a Smart Contract

    +

    For this example, we'll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We'll call the "update_message" entrypoint with text entered by the user in an HTML input field.

    +

    When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like input, then grab the value within the smart-contract-calling function.

    +

    Create a new component:

    +
    touch src/UpdateMessage.jsx
    +

    Open the file and write:

    +
    import { useState } from 'react';
    import { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";
    import axios from "axios";
    import { getProvider } from "./casper-wallet";

    const provider = getProvider();

    const UpdateMessage = (props) => {
    const [message, setMessage] = useState("");

    return (
    <>
    <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />
    <button onClick={ () => updateMessage(props, message) }>Update Message</button>
    </>
    );
    }

    export default UpdateMessage;
    +

    On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint "update_message" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the publicKey variable passed in as a prop from src/App.jsx. Write this function under your UpdateMessage component function.

    +
    const NODE_URL = "http://65.108.127.242:7777/rpc";
    const NETWORK_NAME = "casper-test"; // "casper" for mainnet
    const CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";

    const updateMessage = (props, message) => {
    const casperClient = new CasperClient(NODE_URL);
    const contract = new Contracts.Contract(casperClient);
    contract.setContractHash(CONTRACT_HASH);
    const runtimeArguments = RuntimeArgs.fromMap({
    "message": CLValueBuilder.string(message)
    });
    const deploy = contract.callEntrypoint(
    "update_message",
    runtimeArguments,
    CLPublicKey.fromHex(props.publicKey),
    NETWORK_NAME,
    "1000000000", // 1 CSPR (10^9 Motes)
    );
    const deployJSON = DeployUtil.deployToJson(deploy);
    provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request
    axios.post("/sendDeploy", signedDeploy, {
    headers: {
    'Content-Type': 'application/json'
    }
    }).then((response) => {
    alert(response.data);
    }).catch((error) => {
    console.error(error.message);
    });
    }).catch((error) => {
    console.error(error.message);
    });
    }
    +

    In this example, updateMessage builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, signedDeploy is forwarded to the backend at the /sendDeploy endpoint using axios.post before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to stderr. In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript alert; however, you may do with the response data as you wish.

    +
    info

    The backend endpoint /sendDeploy should handle signed deployment by simply passing it to a Casper node.

    In Casper node v1.5.0, which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node.

    +

    Now that this component is created, render it to the user interface in src/App.jsx, passing along the publicKey as a prop:

    +
    import React from "react";
    import Connect from "./Connect";
    // highlight-next-line-green
    import UpdateMessage from "./UpdateMessage";
    import './App.css'

    function App() {
    const [publicKey, setPublicKey] = React.useState(null);
    return (
    <>
    <Connect setPublicKey={ setPublicKey } />
    <div>
    {publicKey !== null && (<>
    Wallet connected: {publicKey}<br/>
    // highlight-next-line-green
    <UpdateMessage publicKey={ publicKey } />
    </>)}
    </div>
    </>
    );
    }
    +

    Query a Smart Contract

    +

    Consider that the message written to the chain during the update_message entrypoint invocation is stored in the dictionary messages in the contract. Further consider that each account may write its own message and that the messages are stored under the account's account hash as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end.

    +

    Create a new component:

    +
    touch src/Query.jsx
    +

    Open the file and write:

    +
    import axios from "axios";
    import { CLPublicKey } from "casper-js-sdk";

    const Query = (props) => {
    return <button onClick={ () => query(props) }>Query</button>;
    }

    const query = (props) => {
    const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);
    axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {
    alert(response.data)
    }).catch((error) => {
    console.error(error.message);
    });
    }

    export default Query;
    +

    All this component does is render an HTML button element that, when pressed, performs a GET request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user.

    +
    tip

    The toAccountHashStr method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the substring(13) method.

    +
    info

    This functionality relies on the /queryMessage endpoint, which should be implemented in your backend.

    +

    Now add this component to src/App.jsx, making available the publicKey state variable via a prop:

    +
    import React from "react";
    import Connect from "./Connect";
    import UpdateMessage from "./UpdateMessage";
    // highlight-next-line-green
    import Query from "./Query";
    import './App.css'

    function App() {
    const [publicKey, setPublicKey] = React.useState(null);
    return (
    <>
    <Connect setPublicKey={ setPublicKey } />
    <div>
    {publicKey !== null && (<>
    Wallet connected: {publicKey}<br/>
    <UpdateMessage publicKey={ publicKey } />
    // highlight-next-line-green
    <Query publicKey={ publicKey } />
    </>)}
    </div>
    </>
    );
    }
    +

    Test Application

    +

    Test your application by running the following:

    +
    vite dev
    +

    Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press h, then o to open the app in a browser.

    +

    Build for Production

    +

    When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:

    +
    vite build
    +

    Once this is complete, you can preview your production build by running:

    +
    vite preview
    + + \ No newline at end of file diff --git a/1.5.X/developers/dapps/uref-security/index.html b/1.5.X/developers/dapps/uref-security/index.html new file mode 100644 index 000000000..616084461 --- /dev/null +++ b/1.5.X/developers/dapps/uref-security/index.html @@ -0,0 +1,100 @@ + + + + + +URef Access Rights | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    URef Access Rights and Security Considerations

    +

    Understanding Access Rights

    +

    An Unforgeable Reference or URef is a key type used for storage on a Casper network. They can store any value other than Account and exist as a top-level entity. As such, no individual account may own a URef, they can only hold the necessary AccessRights to interact with a given URef.

    +

    AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

    +
    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000
    +

    And this is the same URef with READ and ADD access rights.

    +
    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005
    +

    The following table outlines all possible AccessRights settings:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Access RightsSerialization
    NONE0
    READ1
    WRITE2
    READ_WRITE3
    ADD4
    READ_ADD5
    ADD_WRITE6
    READ_ADD_WRITE7
    +
    warning

    Any access rights granted alongside a passed URef are irrevocable.

    +

    AccessRights and Purses

    +

    A Purse is a unique type of URef representing a token balance. Each Account will have an associated URef that represents its main purse. Accounts and contracts may have additional purses.

    +

    For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:

    + + + + + + + + + + + + + + + + + + + + + +
    Global StateAction Monetary Action
    AddDeposit (i.e. transfer to)
    WriteWithdraw (i.e. transfer from)
    ReadBalance check
    +

    Security Considerations for dApp Developers

    +

    When developing a dApp that interacts with tokens in any way, it will be necessary to work with various URef AccessRights for associated purse URefs.

    +

    This tutorial outlines our recommendations when transferring tokens to a contract.

    +

    When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate AccessRights. The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the new_uref should be passed to another entity.

    +
    // This example will create a version of the original URef with access rights stripped entirely.
    let new_uref = uref.with_access_rights(AccessRights::NONE);
    // This example will create a version of the original URef with only READ access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ);
    // This example will create a version of the original URef with only WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::WRITE);
    // This example will create a version of the original URef with both READ and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
    // This example will create a version of the original URef with only ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD);
    // This example will create a version of the original URef with both READ and ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
    // This example will create a version of the original URef with both ADD and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
    // This example will create a version of the original URef with full access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);
    + + \ No newline at end of file diff --git a/1.5.X/developers/essential-crates/index.html b/1.5.X/developers/essential-crates/index.html new file mode 100644 index 000000000..2d45d9ad5 --- /dev/null +++ b/1.5.X/developers/essential-crates/index.html @@ -0,0 +1,77 @@ + + + + + +Essential Rust Crates | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Essential Rust Crates

    +

    Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.

    +

    casper-types

    +

    Types shared by many Casper crates:

    + +

    casper-contract

    +

    A library for developing Casper smart contracts:

    + +

    casper-engine-test-support

    +

    The Casper test support library:

    + +

    casper-node

    +

    The component for running a node on a Casper network:

    + +

    casper-client

    +

    A client library for interacting with a Casper network:

    + +

    casper-event-standard

    +

    A Rust library that provides a simple and standardized way for Casper contracts to emit events:

    + +

    casper-hashing

    +

    A library providing hashing functionality including Merkle Proof utilities:

    + +

    casper-wasm-utils

    +

    Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:

    + +

    cargo-casper

    +

    A command line tool for creating a Wasm smart contract and tests:

    + +

    Other Libraries

    +

    The Open-Source Software page provides other community-curated tools and libraries.

    + + \ No newline at end of file diff --git a/1.5.X/developers/index.html b/1.5.X/developers/index.html new file mode 100644 index 000000000..bf315079e --- /dev/null +++ b/1.5.X/developers/index.html @@ -0,0 +1,57 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Developers Overview

    +

    This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Development PrerequisitesSetup needed for various workflows
    Essential Casper CratesAvailable Casper crates and the corresponding documentation
    Writing On-Chain CodeWriting contracts in Rust and Wasm for a Casper network
    Casper JSON-RPC APIEndpoints for developers wishing to interact directly with a Casper node's JSON-RPC API
    Building dAppsUseful information for dApp developers
    Interacting with the Blockchain Using CLIUsing a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens.
    +

    The Ecosystem Open-Source Software may provide other helpful examples.

    +

    The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together.

    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/errors/index.html b/1.5.X/developers/json-rpc/errors/index.html new file mode 100644 index 000000000..08fcda7f8 --- /dev/null +++ b/1.5.X/developers/json-rpc/errors/index.html @@ -0,0 +1,126 @@ + + + + + +Casper JSON-RPC Error Codes | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Casper JSON-RPC Error Codes

    +

    The following document expands on custom error codes provided by casper-json-rpc crate.

    +

    Error Codes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeErrorDescription
    -1NoSuchDeployThe requested Deploy was not found.
    -2NoSuchBlockThe requested Block was not found.
    -3FailedToParseQueryKeyParsing the Key from a query failed.
    -4QueryFailedThe query failed to find a result.
    -5QueryFailedToExecuteExecuting the query failed.
    -6FailedToParseGetBalanceURefParsing the URef while getting a balance failed.
    -7FailedToGetBalanceFailed to get the requested balance.
    -8GetBalanceFailedToExecuteExecuting the query to retrieve the balance failed.
    -9InvalidDeployThe given Deploy cannot be executed as it is invalid.
    -10NoSuchAccountThe given account was not found.
    -11FailedToGetDictionaryURefFailed to get the requested dictionary URef.
    -12FailedToGetTrieFailed to get the requested dictionary trie.
    -13NoSuchStateRootThe requested state root hash was not found.
    -32600InvalidRequestThe JSON sent is not a valid Request object.
    -32601MethodNotFoundThe method does not exist or is not available.
    -32602InvalidParamsInvalid method parameter(s)
    -32603InternalErrorInternal JSON-RPC error.
    -32700ParseErrorInvalid JSON was received by the server.
    +

    Invalid Params

    +

    The casper-json-rpc no longer ignores invalid params fields. Params fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent.

    +

    Failing to adhere to this will result in an InvalidParams error.

    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/guidance/index.html b/1.5.X/developers/json-rpc/guidance/index.html new file mode 100644 index 000000000..485e590e1 --- /dev/null +++ b/1.5.X/developers/json-rpc/guidance/index.html @@ -0,0 +1,29 @@ + + + + + +Guidance for JSON-RPC SDK Compliance | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Guidance for JSON-RPC SDK Compliance

    +

    A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.

    +

    A Casper JSON-RPC SDK claiming to be complete is expected to implement all endpoints and all types defined in the serialization standard.

    +

    Consistency

    +

    A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and Deploy, not similar terms such as wallet or transaction.

    +

    Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK.

    +

    Advanced Functionality

    +

    SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations.

    +

    However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience.

    +

    For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform.

    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/index.html b/1.5.X/developers/json-rpc/index.html new file mode 100644 index 000000000..5ffad6d93 --- /dev/null +++ b/1.5.X/developers/json-rpc/index.html @@ -0,0 +1,65 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Interacting with the Casper JSON-RPC API

    +

    Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.

    +

    Casper nodes provide the RPC schema on port 8888, followed by rpc-schema:

    +
    <HOST:8888>/rpc-schema 
    +

    To see an example, navigate to a node's RPC schema using a browser.

    +

    The Casper client subcommand list-rpcs provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:

    +
    casper-client list-rpcs --node-address <HOST:PORT>
    +

    Table of Contents

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PageDescription
    Guidance for JSON-RPC SDK ComplianceRequirements for a compliant Casper SDK
    Required JSON-RPC Methods for Minimal ComplianceMethods required for a minimally compliant Casper SDK
    Transactional JSON-RPC MethodMethods allowing interaction with a Casper network
    Informational JSON-RPC MethodsMethods returning information about the network from a Casper node
    Proof-of-Stake JSON-RPC MethodsMethods pertaining to Proof-of-Stake functionality on a Casper network
    TypesInformation on types used within JSON-RPC methods
    CL TypesInformation related to CL Types
    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/json-rpc-informational/index.html b/1.5.X/developers/json-rpc/json-rpc-informational/index.html new file mode 100644 index 000000000..e98b92aaa --- /dev/null +++ b/1.5.X/developers/json-rpc/json-rpc-informational/index.html @@ -0,0 +1,687 @@ + + + + + +Informational JSON-RPC Methods | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Informational JSON-RPC Methods

    +

    The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.

    +
    +

    chain_get_block

    +

    This method returns the JSON representation of a Block from the network.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block hash or the Block height.
    +
    Example chain_get_block request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +
    +

    chain_get_block_result

    +

    The result from chain_get_block depends on block availability from a given node. If chain_get_block returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    blockObjectThe Block, if found. (Not required)
    +
    Example chain_get_block result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block": {
    "body": {
    "deploy_hashes": [],
    "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "transfer_hashes": [
    "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    ]
    },
    "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "header": {
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",
    "era_end": {
    "era_report": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "rewards": [
    {
    "amount": 1000,
    "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"
    }
    ]
    },
    "next_era_validator_weights": [
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    },
    {
    "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "weight": "123"
    }
    ]
    },
    "era_id": 1,
    "height": 10,
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "protocol_version": "1.0.0",
    "random_bit": true,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "timestamp": "2020-11-17T00:39:24.072Z"
    },
    "proofs": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"
    }
    ]
    }
    }
    }

    +
    +

    chain_get_block_transfers

    +

    This method returns all successful native transfers within a given Block from a network.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block hash.
    +
    Example chain_get_block_transfers request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block_transfers",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +
    +

    chain_get_block_transfers_result

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_hashObjectThe Block hash, if found.
    transfersArrayThe Block's successful transfers, if found.
    +
    Example chain_get_block_transfers result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "transfers": [
    {
    "amount": "0",
    "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",
    "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",
    "gas": "0",
    "id": null,
    "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",
    "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",
    "to": null
    }
    ]
    }
    }

    +
    +

    chain_get_era_summary

    +

    This method returns the era summary at a given Block. If you do not specify a block_identifier, you will receive the era summary at the highest state root hash.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    +
    Example chain_get_era_summary request
    + +

    {
    "id": 1,
    "jsonrpc":"2.0",
    "method":"chain_get_era_summary",
    "params": [
    {
    "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"
    }
    ]
    }

    +
    +

    chain_get_era_summary_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary (if found).
    +
    Example chain_get_era_summary result
    + +

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "api_version": "1.0.0",
    "era_summary": {
    "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",
    "era_id": 1,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",
    "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",
    "amount": "53472520551166781393617756"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",
    "amount": "54552773491594393138943367"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",
    "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",
    "amount": "51312014670568117976319374"
    }
    },
    {
    "Validator": {
    "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",
    "amount": "56713279372733183026458256"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",
    "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",
    "amount": "51852141140784624481333262"
    }
    },
    {
    "Validator": {
    "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",
    "amount": "56173152902516676521444368"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",
    "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",
    "amount": "52392267611001130986347150"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",
    "amount": "55633026432300170016430480"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",
    "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",
    "amount": "52932394080952975520954950"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",
    "amount": "55092899961808199011606173"
    }
    }
    ]
    }
    },
    "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",
    "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"
    }
    }
    }

    +
    +

    chain_get_state_root_hash

    +

    This method returns a state root hash at a given Block. If you do not specify a block_identifier, you will receive the highest state root hash.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    +
    Example chain_get_state_root_hash request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_state_root_hash",
    "params": [
    {
    "Height": 10
    }
    ]
    }

    +
    +

    chain_get_state_root_hash_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    state_root_hashStringHex-encoded hash of the state root.
    +
    Example chain_get_state_root_hash result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"
    }
    }

    +
    +

    info_get_chainspec

    +

    This method returns raw bytes for chainspec files.

    +
    Example info_get_chainspec request
    + +

    {
    "jsonrpc": "2.0",
    "method": "info_get_chainspec",
    "id": 5510244237763930243
    }

    +
    +

    info_get_chainspec_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    chainspec_bytesObjectThe raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.
    +
    Example info_get_chainspec result
    + +

    Please note that adding a --vv flag will return the full chainspec bytes.

    +

    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.0",
    "chainspec_bytes": {
    "chainspec_bytes": "[22040 hex chars]",
    "maybe_genesis_accounts_bytes": null,
    "maybe_global_state_bytes": null
    }
    },
    "id": 5510244237763930243
    }

    +
    +

    info_get_deploy

    +

    This method retrieves a Deploy from a network. It requires a deploy_hash to query the Deploy.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    deploy_hashStringThe Deploy hash.
    finalized_approvalsBooleanDetermines whether to return the Deploy with the finalized approvals substituted. (Optional)
    +
    Example info_get_deploy request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_deploy",
    "params": [
    "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    true
    ]
    }

    +
    +

    info_get_deploy_result

    +

    The response contains the Deploy and the results of executing the Deploy.

    +

    If the execution_results field is empty, it means that the network processed the Deploy, but has yet to execute it. If the network executed the Deploy, it will return the results of the execution. The execution results contain the Block hash which contains the Deploy.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    deployObjectThe Deploy.
    execution_resultsArrayAn array of execution results with Block hashes.
    +
    Example info_get_deploy result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy": {
    "approvals": [
    {
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    ],
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "chain_name": "casper-example",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "gas_price": 1,
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h"
    },
    "payment": {
    "StoredContractByName": {
    "args": [
    [
    "amount",
    {
    "bytes": "e8030000",
    "cl_type": "I32",
    "parsed": 1000
    }
    ]
    ],
    "entry_point": "example-entry-point",
    "name": "casper-example"
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "bytes": "e8030000",
    "cl_type": "I32",
    "parsed": 1000
    }
    ]
    ]
    }
    }
    },
    "execution_results": [
    {
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "result": {
    "Success": {
    "cost": "123456",
    "effect": {
    "operations": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": "Write"
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Read"
    }
    ],
    "transforms": [
    {
    "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",
    "transform": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "transform": "Identity"
    }
    ]
    },
    "transfers": [
    "transfer-5959595959595959595959595959595959595959595959595959595959595959",
    "transfer-8282828282828282828282828282828282828282828282828282828282828282"
    ]
    }
    }
    }
    ]
    }
    }

    +
    +

    query_balance

    +

    This method allows you to query for the balance of a purse using a PurseIdentifier and StateIdentifier.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used.
    +
    Example query_balance request
    + +
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    +
    +

    query_balance_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    balanceObjectThe balance represented in motes.
    +
    Example query_balance result
    + +

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "api_version": "1.0.0",
    "balance": "1000000000000000000000000000000000"
    }
    }

    +
    +

    query_global_state

    +

    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 or state root hash.

    +
      +
    • Note: Querying a purse's balance requires the use of query_balance, rather than any iteration of query_global_state.
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    state_identifierObjectThe identifier used for the query.
    keyStringcasper_types::Key as a formatted string.
    pathArrayThe path components starting from the key as base.
    +
    Example query_global_state request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": [
    "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    [],
    {
    "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +
    +

    query_global_state_result

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_headerObjectThe Block header if a Block hash was provided. (Not required)
    stored_valueObjectThe stored value.
    merkle_proofStringThe merkle proof.
    +
    Example query_global_state result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": {
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",
    "era_end": {
    "era_report": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "rewards": [
    {
    "amount": 1000,
    "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"
    }
    ]
    },
    "next_era_validator_weights": [
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    },
    {
    "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "weight": "123"
    }
    ]
    },
    "era_id": 1,
    "height": 10,
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "protocol_version": "1.0.0",
    "random_bit": true,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "timestamp": "2020-11-17T00:39:24.072Z"
    },
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "weight": 1
    }
    ],
    "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "named_keys": []
    }
    }
    }
    }

    +
    +

    state_get_account_info

    +

    This method returns a JSON representation of an Account from the network. The block_identifier must refer to a Block after the Account's creation, or the method will return an empty response.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    public_keyStringThe public key of the Account.
    block_identifierObjectThe Block identifier.
    +
    Example state_get_account_info request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_account_info",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    },
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ]
    }

    +
    +

    state_get_account_info_result

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    accountObjectA JSON representation of the Account structure.
    merkle_proofStringThe merkle proof.
    +
    Example state_get_account_info result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "account": {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "weight": 1
    }
    ],
    "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "named_keys": []
    },
    "api_version": "1.4.13",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }

    +
    +

    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.

    +

    You may query a stored value directly using the dictionary address.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    state_root_hashStringHash of the state root.
    dictionary_identifierObjectThe Dictionary query identifier.
    +
    Example state_get_dictionary_item request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_dictionary_item",
    "params": [
    {
    "URef": {
    "dictionary_item_key": "a_unique_entry_identifier",
    "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
    }
    },
    "0808080808080808080808080808080808080808080808080808080808080808"
    ]
    }

    +
    +

    state_get_dictionary_item_result

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    dictionary_keyStringThe key under which the value is stored.
    stored_valueObjectThe stored value.
    merkle_proofStringThe merkle proof.
    +
    Example state_get_dictionary_item result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "stored_value": {
    "CLValue": {
    "bytes": "0100000000000000",
    "cl_type": "U64",
    "parsed": 1
    }
    }
    }
    }

    +
    +
    +

    Node Informational JSON-RPC Methods

    +

    The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary.

    +
    +

    info_get_peers

    +

    This method returns a list of peers connected to the node.

    +
    Example info_get_peers request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_peers",
    "params": []
    }

    +
    +

    info_get_peers_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    peersArrayThe node ID and network address of each connected peer.
    +
    Example info_get_peers result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "peers": [
    {
    "address": "127.0.0.1:54321",
    "node_id": "tls:0101..0101"
    }
    ]
    }
    }

    +
    +

    info_get_status

    +

    This method returns the current status of a node.

    +
    Example info_get_status request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_status",
    "params": []
    }

    +
    +

    info_get_status_result

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    available_block_rangeObjectThe available block range in storage.
    block_syncObjectThe status of the block synchronizer builders.
    build_versionStringThe compiled node version.
    chainspec_nameStringThe chainspec name, used to identify the currently connected network.
    last_added_block_infoObjectThe minimal info of the last Block from the linear chain.
    last_progressStringTimestamp of the last recorded progress in the reactor.
    next_upgradeObjectInformation about the next scheduled upgrade.
    our_public_signing_keyStringOur public signing key.
    peersArrayThe node ID and network address of each connected peer.
    reactor_stateStringThe current state of the node reactor.
    round_lengthIntegerThe next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block.
    starting_state_root_hashStringThe state root hash used at the start of the current session.
    uptimeIntegerTime that passed since the node has started.
    +
    Example info_get_status result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_status_result",
    "value": {
    "peers": [
    {
    "node_id": "tls:0101..0101",
    "address": "127.0.0.1:54321"
    }
    ],
    "api_version": "1.4.8",
    "build_version": "1.0.0-xxxxxxxxx@DEBUG",
    "chainspec_name": "casper-example",
    "starting_state_root_hash": null,
    "last_added_block_info": {
    "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "round_length": "1m 5s 536ms",
    "next_upgrade": {
    "activation_point": 42,
    "protocol_version": "2.0.1"
    },
    "uptime": "13s",
    "reactor_state": "Initialize",
    "last_progress": "1970-01-01T00:00:00.000Z",
    "available_block_range": {
    "low": 0,
    "high": 0
    },
    "block_sync": {
    "historical": {
    "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",
    "block_height": 40,
    "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"
    },
    "forward": {
    "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",
    "block_height": 6701,
    "acquisition_state": "have block body(6701) for: block hash 5990..4983"
    }
    }
    }
    }

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/json-rpc-pos/index.html b/1.5.X/developers/json-rpc/json-rpc-pos/index.html new file mode 100644 index 000000000..02f06b00c --- /dev/null +++ b/1.5.X/developers/json-rpc/json-rpc-pos/index.html @@ -0,0 +1,182 @@ + + + + + +Proof-of-Stake JSON-RPC Methods | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Proof-of-Stake JSON-RPC Methods

    +

    The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.

    +
    +

    state_get_auction_info

    +

    This method returns the bids and validators as of either a specific Block (by height or hash). If you do not provide a block_identifier, state_get_auction_info will return information from the most recent Block.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block identifier.
    +
    Example state_get_auction_info request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_auction_info",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +
    +

    state_get_auction_info_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    auction_stateObjectThe auction state.
    +
    Example state_get_auction_info result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "auction_state": {
    "bids": [
    {
    "bid": {
    "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",
    "delegation_rate": 0,
    "delegators": [],
    "inactive": false,
    "staked_amount": "10"
    },
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"
    }
    ],
    "block_height": 10,
    "era_validators": [
    {
    "era_id": 10,
    "validator_weights": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "weight": "10"
    }
    ]
    }
    ],
    "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
    }
    }
    }

    +
    +

    info_get_validator_changes

    +

    This method returns status changes of active validators. Listed changes occurred during the EraId contained within the response itself. A validator may show more than one change in a single era.

    +

    Potential change types:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Change TypeDescription
    AddedThe validator has been added to the set.
    RemovedThe validator has been removed from the set.
    BannedThe validator has been banned in the current era.
    CannotProposeThe validator cannot propose a Block.
    SeenAsFaultyThe validator has performed questionable activity.
    +
    Example info_get_validator_changes request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_validator_changes",
    "params": []
    }

    +
    +

    info_get_validator_changes_result

    +

    If no changes occurred in the current era, info_get_validator_changes will return empty.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    changesObjectThe validators' status changes.
    +
    Example info_get_validator_changes result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "changes": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "status_changes": [
    {
    "era_id": 1,
    "validator_change": "Added"
    }
    ]
    }
    ]
    }
    }

    +
    +

    chain_get_era_info_by_switch_block

    +

    This method returns an EraInfo from the network. Only the last Block in an era, known as a switch block, will contain an era_summary.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe Block identifier. If you do not supply a block_identifier, the returned information will be the most recent Block. (Optional)
    +
    Example chain_get_era_info_by_switch_block request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_era_info_by_switch_block",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +
    +

    chain_get_era_info_by_switch_block_result

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary (If found).
    +
    Example chain_get_era_info_by_switch_block
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "era_summary": {
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "era_id": 42,
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "amount": "1000",
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"
    }
    },
    {
    "Validator": {
    "amount": "2000",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"
    }
    }
    ]
    }
    }
    }
    }
    }

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/json-rpc-transactional/index.html b/1.5.X/developers/json-rpc/json-rpc-transactional/index.html new file mode 100644 index 000000000..bcc2e59d5 --- /dev/null +++ b/1.5.X/developers/json-rpc/json-rpc-transactional/index.html @@ -0,0 +1,133 @@ + + + + + +Transactional JSON-RPC Methods | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Transactional JSON-RPC Methods

    +
    +

    account_put_deploy

    +

    This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the Deploy as a parameter, prior to sending it to a node on a network for execution.

    + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    +
    +

    Note: You can find a list of trusted peers in the network's configuration file, config.toml. Here is an example config.toml. You may send deploys to one of the trusted nodes or use them to query other online nodes.

    +
    +
    Example account_put_deploy request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": [
    {
    "approvals": [
    {
    "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",
    "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"
    }
    ],
    "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",
    "header": {
    "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",
    "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",
    "chain_name": "casper-net-1",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "gas_price": 1,
    "timestamp": "2023-09-26T14:07:10.024Z",
    "ttl": "1h"
    },
    "payment": {
    "StoredContractByName": {
    "args": [
    [
    "amount",
    {
    "bytes": "0400f90295",
    "cl_type": "U512"
    }
    ]
    ],
    "entry_point": "example-entry-point",
    "name": "casper-example"
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"
    }
    ]
    ]
    }
    }
    }
    ]
    }

    +
    +

    account_put_deploy_result

    +

    The result contains the deploy_hash, which is the primary identifier of a Deploy within a Casper network.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    deploy_hashStringA hex-encoded hash of the Deploy as sent.
    +
    Example account_put_deploy result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    }
    }

    +
    +

    speculative_exec

    +

    The speculative_exec endpoint provides a method to execute a Deploy without committing its execution effects to global state. By default, speculative_exec is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, speculative_exec operates on a separate port from the primary JSON-RPC, using 7778.

    +

    speculative_exec executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    block_identifierObjectThe block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used.
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    +
    Example speculative_exec request
    + +

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec",
    "params": {
    "block_identifier": null,
    "deploy": {
    "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",
    "header": {
    "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "timestamp": "2023-05-23T13:32:45.554Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",
    "dependencies": [],
    "chain_name": "integration-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400e1f505",
    "parsed": "100000000"
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",
    "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010000000000000000",
    "parsed": 0
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"
    }
    ]
    }
    },
    "id": 6889533540839698701
    }

    +
    +

    speculative_exec_result

    +

    The result contains the hash of the targeted block and the results of the execution.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_hashObjectThe Block hash on top of which the deploy was executed.
    execution_resultsObjectThe map of Block hash to execution result.
    +
    Example speculative_exec result
    + +

    {
    "jsonrpc": "2.0",
    "id": -8801853076373554652,
    "result": {
    "api_version": "1.5.0",
    "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",
    "execution_result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0e630ed87",
    "parsed": "583799990000"
    }
    }
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0e630ed87",
    "parsed": "583799990000"
    }
    }
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0ed2d5887",
    "parsed": "581299990000"
    }
    }
    },
    {
    "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",
    "transform": {
    "AddUInt512": "2500000000"
    }
    },
    {
    "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",
    "transform": {
    "WriteTransfer": {
    "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",
    "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",
    "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",
    "amount": "2500000000",
    "gas": "0",
    "id": 0
    }
    }
    },
    {
    "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "transfers": [
    "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"
    ],
    "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",
    "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",
    "gas": "100000000"
    }
    }
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",
    "transform": {
    "AddUInt512": "100000000"
    }
    }
    ]
    },
    "transfers": [
    "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"
    ],
    "cost": "100000000"
    }
    }
    }
    }

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/minimal-compliance/index.html b/1.5.X/developers/json-rpc/minimal-compliance/index.html new file mode 100644 index 000000000..7f11a9d49 --- /dev/null +++ b/1.5.X/developers/json-rpc/minimal-compliance/index.html @@ -0,0 +1,49 @@ + + + + + +Required Methods for Minimal Compliance | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Required Methods for Minimal Compliance

    +

    The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.

    +
      +
    • +

      chain_get_block - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers.

      +
    • +
    • +

      info_get_deploy - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy.

      +
    • +
    • +

      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 - The state root hash is one of the several global state identifiers used to query the network state after sending deploys.

      +
    • +
    • +

      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 - 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 - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state.

      +
    • +
    • +

      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 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.

    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/types_chain/index.html b/1.5.X/developers/json-rpc/types_chain/index.html new file mode 100644 index 000000000..289bf59d5 --- /dev/null +++ b/1.5.X/developers/json-rpc/types_chain/index.html @@ -0,0 +1,1142 @@ + + + + + +Types | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Types

    +

    The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.

    +

    Account

    +

    Structure representing a user's Account, stored in global state.

    +

    Required Parameters:

    + +

    AccountHash

    +

    The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length.

    +

    ActionThresholds

    +

    Thresholds that have to be met when executing an action of a certain type.

    +

    Required Parameters:

    +
      +
    • +

      deployment

      +
    • +
    • +

      key_management

      +
    • +
    +

    ActivationPoint

    +

    The first era to which the associated protocol version applies.

    + +

    Approval

    +

    A struct containing a signature and the public key of the signer.

    +

    Required Parameters:

    + +

    AssociatedKey

    +

    A key granted limited permissions to an Account, for purposes such as multisig.

    +

    Required Parameters:

    + +

    AuctionState

    +

    Data structure summarizing auction contract data.

    +

    Required Parameters:

    + +

    AvailableBlockRange

    +
      +
    • +

      low The inclusive lower bound of the range.

      +
    • +
    • +

      high The inclusive upper bound of the range.

      +
    • +
    +

    Bid

    +

    An entry in the validator map.

    +

    Required Parameters:

    +
      +
    • +

      bonding_purse The purse that was used for bonding.

      +
    • +
    • +

      delegation_rate The delegation rate.

      +
    • +
    • +

      delegators The validator's delegators, indexed by their public keys.

      +
    • +
    • +

      inactive true if validator has been "evicted".

      +
    • +
    • +

      staked_amount The amount of tokens staked by a validator (not including delegators).

      +
    • +
    • +

      validator_public_key Validator's public key.

      +
    • +
    +

    Additional Parameters:

    +
      +
    • vesting_schedule Vesting schedule for a genesis validator. None if non-genesis validator.
    • +
    +

    BlockHash

    +

    A cryptographic hash identifying a Block.

    +

    BlockIdentifier

    +

    Identifier for possible ways to retrieve a Block.

    +
      +
    • +

      Hash Identify and retrieve the Block with its hash.

      +
    • +
    • +

      Height Identify and retrieve the Block with its height.

      +
    • +
    +

    BlockSynchronizerStatus

    +

    The status of the block synchronizer.

    +
      +
    • +

      Historical The status of syncing a historical block, if any.

      +
        +
      • +

        block_hash The block hash.

        +
      • +
      • +

        block_height The height of the block, if known.

        +
      • +
      • +

        acquisition_state The state of acquisition of the data associated with the block.

        +
      • +
      +
    • +
    • +

      Forward The status of syncing a forward block, if any.

      +
        +
      • +

        block_hash The block hash.

        +
      • +
      • +

        block_height The height of the block, if known.

        +
      • +
      • +

        acquisition_state The state of acquisition of the data associated with the block.

        +
      • +
      +
    • +
    +

    ChainspecRawBytes

    +

    The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.

    +
      +
    • +

      chainspec_bytes Hex-encoded raw bytes of the current chainspec.toml file.

      +
    • +
    • +

      maybe_genesis_accounts_bytes Hex-encoded raw bytes of the current genesis accounts.toml file.

      +
    • +
    • +

      maybe_global_state_bytes Hex-encoded raw bytes of the current global_state.toml file.

      +
    • +
    +

    Contract

    +

    A contract struct that can be serialized as a JSON object.

    +

    Required Parameters:

    +

    contract_package_hash

    +

    contract_wasm_hash

    +

    entry_points

    +

    named_keys

    +

    protocol_version

    +

    ContractHash

    +

    The hash address of the contract.

    +

    ContractPackage

    +

    Contract definition, metadata and security container.

    +

    Required Parameters:

    + +

    ContractPackageHash

    +

    The hash address of the contract package.

    +

    ContractVersion

    +

    The version of the contract.

    +

    Required Parameters:

    +
      +
    • +

      contract_hash

      +
    • +
    • +

      contract_version

      +
    • +
    • +

      protocol_version_major

      +
    • +
    +

    ContractWasmHash

    +

    The hash address of the contract Wasm.

    +

    Delegator

    +

    Represents a party delegating their stake to a validator (or "delegatee").

    +

    Required Parameters:

    + +

    Additional Parameters:

    + +

    Deploy

    +

    A Deploy; an item containing a smart contract along with the requester's signature(s).

    +

    Required properties:

    + +

    DeployHash

    +

    Hex-encoded Deploy hash.

    +

    DeployHeader

    +

    The header portion of a Deploy.

    +

    Required Parameters:

    + +

    DeployInfo

    +

    Information relating to the given Deploy.

    +

    Required Parameters:

    +
      +
    • +

      deploy_hash The relevant Deploy.

      +
    • +
    • +

      from Account identifier of the creator of the Deploy.

      +
    • +
    • +

      gas Gas cost of executing the Deploy.

      +
    • +
    • +

      source Source purse used for payment of the Deploy.

      +
    • +
    • +

      transfers Transfers performed by the Deploy.

      +
    • +
    +

    DictionaryIdentifier

    +

    Options for dictionary item lookups.

    +
      +
    • +

      AccountNamedKey Lookup a dictionary item via an Account's named keys.

      +

      Required Parameters:

      +

      key The Account key as a formatted string whose named keys contain dictionary_name.

      +

      dictionary_name The named key under which the dictionary seed URef is stored.

      +

      dictionary_item_key The dictionary item key formatted as a string.

      +
    • +
    • +

      ContractNamedKey Lookup a dictionary item via a Contract's named keys.

      +

      key The contract key as a formatted string whose named keys contains dictionary_name.

      +

      dictionary_name The named key under which the dictionary seed URef is stored.

      +

      dictionary_item_key The dictionary item key formatted as a string.

      +
    • +
    • +

      URef Lookup a dictionary item via its seed URef.

      +

      seed_uref The dictionary's seed URef.

      +

      dictionary_item_key The dictionary item key formatted as a string.

      +
    • +
    • +

      Dictionary Lookup a dictionary item via its unique key.

      +
    • +
    +

    Digest

    +

    Hex-encoded hash digest.

    +

    DisabledVersions

    +

    Required Parameters:

    +
      +
    • +

      contract_version

      +
    • +
    • +

      protocol_version_major

      +
    • +
    +

    EntryPoint

    +

    Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters.

    +

    Required Parameters:

    + +

    EntryPointAccess

    +

    Enum describing the possible access control options for a contract entry point.

    +
      +
    • +

      Public A public entry point is callable by any caller.

      +
    • +
    • +

      Groups Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract.

      +
    • +
    +

    EntryPointType

    +

    Context of an entry point execution.

    +
      +
    • +

      session Executes in the caller's context.

      +
    • +
    • +

      contract Executes in the callee's context.

      +
    • +
    +

    EraID

    +

    Era ID newtype.

    +

    EraInfo

    +

    Auction metadata. Intended to be recorded at each era.

    +

    Required Parameters:

    + +

    EraSummary

    +

    The summary of an era.

    +

    Required Parameters:

    + +

    ExecutableDeployItem

    +

    Represents possible variants of an executable Deploy.

    +

    ModuleBytes

    +

    Executable specified as raw bytes that represent Wasm code and an instance of RuntimeArgs.

    +

    Required Parameters:

    +
      +
    • module_bytes Hex-encoded raw Wasm bytes. There are some special cases around passing module_bytes for payment code.
    • +
    +

    Additional Parameters:

    +
      +
    • args Runtime arguments.
    • +
    +

    StoredContractByHash

    +

    Stored contract referenced by its ContractHash, entry point and an instance of RuntimeArgs.

    +

    Required Parameters:

    +
      +
    • +

      args Runtime arguments.

      +
    • +
    • +

      entry_point The name of an entry point.

      +
    • +
    • +

      hash A hex-encoded hash.

      +
    • +
    +

    StoredContractByName

    +

    Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of RuntimeArgs.

    +

    Required Parameters:

    +
      +
    • +

      args Runtime arguments.

      +
    • +
    • +

      entry_point The name of an entry point.

      +
    • +
    • +

      name A named key.

      +
    • +
    +

    StoredVersionContractByHash

    +

    Stored versioned contract referenced by its ContractPackageHash, entry point and an instance of RuntimeArgs.

    +

    Required Parameters:

    +
      +
    • +

      args Runtime arguments.

      +
    • +
    • +

      entry_point The name of an entry point.

      +
    • +
    • +

      hash A hex-encoded hash.

      +
    • +
    +

    Additional Parameters:

    +
      +
    • version An optional version of the contract to call. It will default to the highest enabled version if no value is specified.
    • +
    +

    StoredVersionContractByName

    +

    Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of RuntimeArgs.

    +

    Required Parameters:

    +
      +
    • +

      args Runtime arguments.

      +
    • +
    • +

      entry_point The name of an entry point.

      +
    • +
    • +

      name A named key.

      +
    • +
    +

    Additional Parameters:

    +
      +
    • version An optional version of the contract to call. It will default to the highest enabled version if no value is specified.
    • +
    +

    Transfer

    +

    A native transfer which does not contain or reference a Wasm code.

    +

    Required Parameters:

    + +

    ExecutionEffect

    +

    The journal of execution transforms from a single Deploy.

    +

    Required Parameters:

    + +

    ExecutionResult

    +

    The result of executing a single Deploy.

    +
      +
    • +

      Failure The result of a failed execution`

      +

      Required Parameters:

      +

      effect

      +

      transfers

      +

      cost

      +

      error_message The error message associated with executing the Deploy.

      +
    • +
    • +

      Success The result of a successful execution.

      +

      Required Parameters:

      +

      effect

      +

      transfers

      +

      cost

      +
    • +
    +

    FinalizedApprovals

    +

    A boolean value that determines whether to return the deploy with the finalized approvals substituted. If false or omitted, returns the deploy with the approvals that were originally received by the node.

    +

    GlobalStateIdentifier

    +

    Identifier for possible ways to query global state.

    + +

    Group

    +

    A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.

    +

    Groups

    +

    Required Parameters:

    +
      +
    • +

      group

      +
    • +
    • +

      keys

      +
    • +
    +

    JsonBid

    +

    An entry in a founding validator map representing a bid.

    +

    Required Parameters:

    +
      +
    • +

      bonding_purse The purse that was used for bonding.

      +
    • +
    • +

      delegation_rate The delegation rate.

      +
    • +
    • +

      delegators The delegators.

      +
    • +
    • +

      inactive Is this an inactive validator.

      +
    • +
    • +

      staked_amount The amount of tokens staked by a validator (not including delegators).

      +
    • +
    +

    JsonBids

    +

    A Json representation of a single bid.

    +

    Required Parameters:

    + +

    JsonBlock

    +

    A JSON-friendly representation of Block.

    +

    Required Parameters:

    +
      +
    • +

      body JSON-friendly Block body.

      +
    • +
    • +

      hash BlockHash.

      +
    • +
    • +

      header JSON-friendly Block header.

      +
    • +
    • +

      proofs JSON-friendly list of proofs for this Block.

      +
    • +
    +

    JsonBlockBody

    +

    A JSON-friendly representation of Body.

    +

    Required Parameters:

    + +

    JsonBlockHeader

    +

    JSON representation of a Block header.

    + +

    Additional Parameters:

    + +

    JsonDelegator

    +

    A delegator associated with the given validator.

    +

    Required Parameters:

    + +

    JsonEraEnd

    +

    Required Parameters:

    + +

    JsonEraReport

    +

    Equivocation and reward information to be included in the terminal Block.

    +

    Required Parameters:

    + +

    JsonEraValidators

    +

    The validators for the given era.

    +

    Required Parameters:

    + +

    JsonExecutionResult

    +

    The execution result of a single Deploy.

    + +

    JsonProof

    +

    A JSON-friendly representation of a proof, i.e. a Block's finality signature.

    +

    Required Parameters:

    + +

    JsonValidatorChanges

    +

    The changes in a validator's status.

    +

    Required Parameters:

    + +

    JsonValidatorStatusChange

    +

    A single change to a validator's status in the given era.

    +

    Required Parameters:

    + +

    JsonValidatorsWeights

    +

    A validator's weight.

    +

    Required Parameters:

    + +

    Merkle_Proof

    +

    A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes.

    +

    MinimalBlockInfo

    +

    Minimal info of a Block.

    +

    Required Parameters:

    + +

    NamedArg

    +

    Named arguments to a contract.

    +

    NamedKey

    +

    A named key.

    +

    Required Parameters:

    +
      +
    • +

      key The value of the entry: a casper Key type.

      +
    • +
    • +

      name The name of the entry.

      +
    • +
    +

    NextUpgrade

    +

    Information about the next protocol upgrade.

    +

    Required Parameters:

    + +

    NewValidator

    +

    The public key for the new validator in a redelegation using UnbondingPurse.

    +

    Operation

    +

    An operation performed while executing a Deploy.

    +

    Required Parameters:

    +
      +
    • +

      key The formatted string of the Key.

      +
    • +
    • +

      kind

      +
    • +
    +

    OpKind

    +

    The type of operation performed while executing a Deploy.

    +

    Parameter

    +

    Parameter to an entry point.

    +

    Required Parameters:

    + +

    PeerEntry

    +

    Required Parameters:

    +
      +
    • +

      address

      +
    • +
    • +

      node_id

      +
    • +
    +

    PeersMap

    +

    Map of peer IDs to network addresses.

    +

    ProtocolVersion

    +

    Casper Platform protocol version.

    +

    PublicKey

    +

    Hex-encoded cryptographic public key, including the algorithm tag prefix.

    +

    PurseIdentifier

    +

    The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:

    +
      +
    • +

      main_purse_under_public_key The main purse under a provided PublicKey.

      +
    • +
    • +

      main_purse_under_account_hash The main purse under a provided AccountHash.

      +
    • +
    • +

      purse_uref A specific purse identified by the associated URef.

      +
    • +
    +

    ReactorState

    +

    The state of the reactor, which will return one of the following:

    +
      +
    • +

      Initialize Get all components and reactor state set up on start.

      +
    • +
    • +

      CatchUp Orient to the network and attempt to catch up to tip.

      +
    • +
    • +

      Upgrading Running commit upgrade and creating immediate switch block.

      +
    • +
    • +

      KeepUp Stay caught up with tip.

      +
    • +
    • +

      Validate Node is currently caught up and is an active validator.

      +
    • +
    • +

      ShutdownForUpgrade Node should be shut down for upgrade.

      +
    • +
    +

    Reward

    +

    Required Parameters:

    + +

    RuntimeArgs

    +

    Represents a collection of arguments passed to a smart contract.

    +

    SeigniorageAllocation

    +

    Information about a seigniorage allocation.

    +
      +
    • +

      Validator Info about a seigniorage allocation for a validator.

      +

      Required Parameters:

      +

      amount Allocated amount.

      +

      validator_public_key Validator's public key.

      +
    • +
    • +

      Delegator Info about a seigniorage allocation for a delegator.

      +

      Require Parameters:

      +

      amount Allocated amount.

      +

      delegator_public_key Delegator's public key.

      +

      validator_public_key Validator's public key.

      +
    • +
    +

    Signature

    +

    Hex-encoded cryptographic signature, including the algorithm tag prefix.

    +

    StoredValue

    +

    Representation of a value stored in global state. Account, Contract and ContractPackage have their own json_compatibility representation (see their docs for further info).

    +
      +
    • +

      CLValue A Casper-specific value.

      +
    • +
    • +

      Account An Account.

      +
    • +
    • +

      ContractWasm A contract's Wasm.

      +
    • +
    • +

      Contract Entry points supported by a contract.

      +
    • +
    • +

      ContractPackage A contract definition, metadata, and security container.

      +
    • +
    • +

      Transfer A record of a transfer.

      +
    • +
    • +

      DeployInfo A record of a Deploy.

      +
    • +
    • +

      EraInfo Auction metadata.

      +
    • +
    • +

      Bid A bid.

      +
    • +
    • +

      Withdraw A withdraw.

      +
    • +
    +

    TimeDiff

    +

    Human-readable duration.

    +

    Timestamp

    +

    Timestamp formatted as per RFC 3339.

    +

    Transfer

    +

    Represents a transfer from one purse to another.

    +

    Required Parameters:

    +
      +
    • +

      amount Transfer amount.

      +
    • +
    • +

      deploy_hash Deploy that created the transfer.

      +
    • +
    • +

      from Account from which transfer was executed.

      +
    • +
    • +

      gas

      +
    • +
    • +

      source Source purse.

      +
    • +
    • +

      target Target purse.

      +
    • +
    +

    Additional Parameters:

    +
      +
    • +

      id User-defined ID.

      +
    • +
    • +

      to Account to which funds are transferred.

      +
    • +
    +

    TransferAddr

    +

    Hex-encoded transfer address.

    +

    Transform

    +

    The actual transformation performed while executing a Deploy.

    +
      +
    • +

      WriteCLValue Write the given CLValue to global state.

      +
    • +
    • +

      WriteAccount Writes the given Account to global state.

      +
    • +
    • +

      WriteDeployInfo Writes the given DeployInfo to global state.

      +
    • +
    • +

      WriteEraInfo Writes the given EraInfo to global state.

      +
    • +
    • +

      WriteTransfer Writes the given Transfer to global state.

      +
    • +
    • +

      WriteBid Writes the given Bid to global state.

      +
    • +
    • +

      WriteWithdraw Writes the given Withdraw to global state.

      +
    • +
    • +

      AddInt32 Adds the given i32.

      +
    • +
    • +

      AddUInt64 Adds the given u64.

      +
    • +
    • +

      AddUInt128 Adds the given U128.

      +
    • +
    • +

      AddUInt256 Adds the given U256.

      +
    • +
    • +

      AddUInt512 Adds the given U512.

      +
    • +
    • +

      AddKeys Adds the given collection of named keys.

      +
    • +
    • +

      Failure A failed transformation, containing an error message.

      +
    • +
    +

    TransformEntry

    +

    A transformation performed while executing a Deploy.

    +

    Required Parameters:

    +
      +
    • +

      key The formatted string of the Key.

      +
    • +
    • +

      transforms The transformation.

      +
    • +
    +

    U128

    +

    Decimal representation of a 128-bit integer.

    +

    U256

    +

    Decimal representation of a 256-bit integer.

    +

    U512

    +

    Decimal representation of a 512-bit integer.

    +

    UnbondingPurse

    +

    Unbonding purse.

    +

    Required Parameters:

    + +

    URef

    +

    Hex-encoded, formatted URef.

    +

    ValidatorChange

    +

    A change to a validator's status between two eras.

    +
      +
    • +

      Added

      +
    • +
    • +

      Removed

      +
    • +
    • +

      Banned

      +
    • +
    • +

      CannotPropose

      +
    • +
    • +

      SeenAsFaulty

      +
    • +
    +

    ValidatorWeight

    +

    Required Parameters:

    + +

    VestingSchedule

    +

    Vesting schedule for a genesis validator.

    +

    WithdrawPurse

    +

    Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data.

    +

    Required Parameters:

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/json-rpc/types_cl/index.html b/1.5.X/developers/json-rpc/types_cl/index.html new file mode 100644 index 000000000..7fc2604cf --- /dev/null +++ b/1.5.X/developers/json-rpc/types_cl/index.html @@ -0,0 +1,58 @@ + + + + + +CLType | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    CLType

    +

    Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.

    +
        `Bool`
    `I32`
    `I64`
    `U8`
    `U32`
    `U64`
    `U128`
    `U256`
    `U512`
    `Unit`
    `String`
    `Key`
    `URef`
    `PublicKey`
    `Any`
    +
      +
    • +

      Option Option of a CLType.

      +
    • +
    • +

      List Variable-length list of a single CLType (comparable to a Vec).

      +
    • +
    • +

      ByteArray Fixed-length list of a single CLType (comparable to a Rust array).

      +
    • +
    • +

      Result Result with Ok and Err variants of CLType's.

      +
    • +
    • +

      Map Map with keys of a single CLType and values of a single CLType.

      +
    • +
    • +

      Tuple1 1-ary tuple of a CLType.

      +
    • +
    • +

      Tuple2 2-ary tuple of CLTypes.

      +
    • +
    • +

      Tuple3 3-ary tuple of CLTypes.

      +
    • +
    +

    CLValue

    +

    A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized Vec<u8> and also holds the CLType of the underlying data as a separate member. The parsed field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred.

    +
      +
    • +

      bytes A Casper serialized representation of the underlying value. For more information, reference the Serialization Standard.

      +
    • +
    • +

      cl_type

      +
    • +
    + + \ No newline at end of file diff --git a/1.5.X/developers/prerequisites/index.html b/1.5.X/developers/prerequisites/index.html new file mode 100644 index 000000000..e5ada4ffd --- /dev/null +++ b/1.5.X/developers/prerequisites/index.html @@ -0,0 +1,151 @@ + + + + + +Development Prerequisites | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl'; +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem';

    +

    Development Prerequisites

    +

    This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.

    +

    Preparing your Development Environment

    + + +

    Installing curl

    +
    sudo apt install curl
    +

    Installing essential Linux packages

    +
    sudo apt install build-essential
    +

    Installing packages required for Casper tools

    +
    sudo apt-get install pkg-config
    sudo apt-get install openssl
    sudo apt-get install libssl-dev
    +

    Installing cargo on Linux

    +
    sudo apt install cargo
    +
    + +

    Installing Xcode developer tools for macOS

    +
    xcode-select --install
    +

    Verify the installation:

    +
    xcode-select -p
    +

    Installing brew

    +
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    +

    Installing packages required for Casper tools

    +
    brew install pkg-config
    brew install openssl
    +
    +
    +

    Installing Rust

    +

    Install the Rust programming language if you don't already have it on your computer.

    +

    The official Rust guide recommends installing Rust by using curl:

    +
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    +

    After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH.

    +
    source $HOME/.cargo/env
    +

    Verify the installation:

    +
    rustup --version
    +

    Note: You can also use brew on MacOS or apt on Linux to install Rust.

    +

    Installing the Casper Crates

    +

    The best and fastest way to set up a Casper Rust project is to use cargo casper, which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. Cargo is a build system and package manager for Rust (much like pip if you are familiar with Python, or npm and yarn for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline.

    +
    cargo install cargo-casper
    +

    If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:

    +
    rustup update
    +

    Verify the installation:

    +
    cargo-casper --version
    +
    note

    Familiarize yourself with the essential Casper crates described here.

    +

    Installing the Casper Client

    +

    The default Casper client is on crates.io. This client can transmit your deploys to a Casper network.

    +
    cargo install casper-client
    +

    Verify the installation:

    +
    casper-client --version
    +

    The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:

    +
    casper-client --help
    +

    You can use help for each command to get the most up-to-date arguments and descriptions.

    +
    casper-client <command> --help
    +

    Accessing the Casper client source code

    +

    You can access the Casper client source code here. The lib directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app casper-client uses this library to implement its functionality.

    +

    If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:

    +
    rustup toolchain install nightly
    +

    Then, compile the source code:

    +
    cargo build --release
    +

    You will find the casper-client executable in the target/release directory.

    +

    Installing CMake

    +

    If you plan to compile contracts from the source code, including those provided in the casper-node repository, install CMake with the commands below.

    +

    CMake is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the CMake website. Once installed, check your version as shown below.

    + + +
    sudo apt-get -y install cmake
    +
    + +
    brew install cmake
    +
    +
    +

    Check your version:

    +
    cmake --version
    +

    Sample output:

    +
    cmake version 3.20.0 (or above)

    CMake suite maintained and supported by Kitware (kitware.com/cmake).
    +

    Installing an IDE

    +

    We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:

    + +

    You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development.

    +

    If you are using VSC, you might find the following extensions useful:

    +
      +
    • CodeLLDB – An important extension for debugging Rust code
    • +
    • rust-analyzer – The official Rust language extension
    • +
    • Better TOML – Support for formatting TOML files
    • +
    • crates – An extension to help manage crates
    • +
    • Error Lens – Enhances the programming experience by highlighting syntax errors
    • +
    +

    Setting up a Casper Account

    +

    The Account creation process consists of two steps:

    +
      +
    1. Creating an Account
    2. +
    3. Funding the Account
    4. +
    +

    The following video complements the instructions below, showing you the expected output.

    +

    + +

    +

    Creating an account

    +

    The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey.

    +

    By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

    +

    Developers must create accounts using the Casper command-line client to access the secret_key.pem file needed during development.

    +

    Some Casper networks, such as the official Testnet and Mainnet, provide wallets that allow account creation as outlined here. However, these wallets do not give developers access to the secret key file.

    +

    Generating the account hash

    +

    As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain AccountHashes instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the account-address option of the Casper CLI client:

    +
    casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>
    +

    Funding an Account

    +

    After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain.

    +

    On Testnet, you can fund an account by requesting test tokens according to this guide. You can request test tokens only once for each account.

    +

    On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet.

    +

    Acquiring a Node Address from the Network

    +

    Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, http://<node-address>:7777 by default.

    +

    The node address is the IP address or URL of a peer node.

    +

    Casper Labs provides public Casper node JSON-RPC endpoints for each network:

    + +

    Additionally, both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks.

    +

    You can get the node-ip-address of a node on the network by visiting the following block explorers:

    + +

    You will see a list of peers, and you can select the IP of any peer on the list.

    +

    Note: If the selected peer is unresponsive, pick a different peer and try again.

    + + \ No newline at end of file diff --git a/next/developers/writing-onchain-code/assembly-script/index.html b/1.5.X/developers/writing-onchain-code/assembly-script/index.html similarity index 65% rename from next/developers/writing-onchain-code/assembly-script/index.html rename to 1.5.X/developers/writing-onchain-code/assembly-script/index.html index b918a9903..c58aea64c 100644 --- a/next/developers/writing-onchain-code/assembly-script/index.html +++ b/1.5.X/developers/writing-onchain-code/assembly-script/index.html @@ -1,21 +1,21 @@ - + -Getting Started with AssemblyScript | Casper Docs - Redux +Getting Started with AssemblyScript | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Getting Started with AssemblyScript

    + submit an issue on Github
    Version: 1.5.X

    Getting Started with AssemblyScript

    Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.

    Prerequisites

    Installing AssemblyScript

    @@ -27,7 +27,7 @@

    Installing the Casper Package

    The casper-contract package can be installed using the following command:

    npm i casper-contract
    -

    The Assemblyscript contract API documentation can be found at https://www.npmjs.com/package/casper-contract.

    +

    The AssemblyScript contract API documentation can be found at https://www.npmjs.com/package/casper-contract.

    Creating a Project

    For each smart contract, it is necessary to create a project directory and initialize it.

    The npm init process prompts for various details about the project. Answer as you see fit, but you may safely default everything except name, which needs to be specified. In this guide, we will refer to the contract name as your-contract-name.

    @@ -49,6 +49,6 @@

    Sample

    Compile to Wasm

    To compile the contract to Wasm, use npm to run the asbuild script from the project root:

    npm run asbuild
    -

    If the build is successful, there will be a dist folder in the root folder and in it should be your-contract-name.wasm.

    +

    If the build is successful, there will be a dist folder in the root folder and in it should be your-contract-name.wasm.

    \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/best-practices/index.html b/1.5.X/developers/writing-onchain-code/best-practices/index.html new file mode 100644 index 000000000..2f4c800ca --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/best-practices/index.html @@ -0,0 +1,81 @@ + + + + + +Best Practices for Casper Smart Contract Authors | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Best Practices for Casper Smart Contract Authors

    +

    At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.

    +

    Data Efficiency

    +

    When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary Deploys will drastically decrease the overall cost.

    +

    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
    + +

    // This entry point initializes the donation system, setting up the fundraising purse
    // and creating a dictionary to track the account hashes and the number of donations
    // made.
    #[no_mangle]
    pub extern "C" fn init() {
    let fundraising_purse = system::create_purse();
    runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());
    // Create a dictionary to track the mapping of account hashes to number of donations made.
    storage::new_dictionary(LEDGER).unwrap_or_revert();
    }

    +
    +

    Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial deployment.

    +

    Costs

    +

    Computations occurring on-chain come with associated gas costs. Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a Deploy is critical.

    +

    Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the reuse of purses should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author.

    +

    Tips to reduce WASM size

    +

    Deploys have a maxim size specified in each network chainspec as max_deploy_size. For example, networks running node version 1.5.1, have the following maximum deploy size in bytes:

    +
    max_deploy_size = 1_048_576
    +

    Here are a few tips to reduce the size of Wasm included in a deploy:

    +
      +
    1. +

      Build the smart contract in release mode. You will find an example here

      +
      cargo build --release --target wasm32-unknown-unknown
      +
    2. +
    3. +

      Run wasm-strip on the compiled code (see WABT). You will find an example here

      +
      wasm-strip target/wasm32-unknown-unknown/release/contract.wasm
      +
    4. +
    5. +

      Don't enable the std feature when linking to the casper-contract or casper-types crates using the #![no_std] attribute, which tells the program not to import the standard libraries. You will find an example here and further details here

      +
      #![no_std]
      +
    6. +
    7. +

      Build the contract with codegen-units set to 1 by adding codegen-units = 1 to the Cargo.toml under [profile.release]). You will find an example here

      +
    8. +
    9. +

      Build the contract with link-time optimizations enabled by adding lto = true to the Cargo.toml under [profile.release]. You will find an example here

      +
    10. +
    +

    Inlining

    +

    As often as practicable, developers should inline functions by including the body of the function within their code rather than making call or call_indirect to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances.

    +

    Testing

    +

    Testing all Deploys prior to committing them to Mainnet can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending Deploys to Testnet.

    +

    Information on these processes can be found at the following locations:

    + +

    Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/calling-contracts/index.html b/1.5.X/developers/writing-onchain-code/calling-contracts/index.html new file mode 100644 index 000000000..87d8e8dd7 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/calling-contracts/index.html @@ -0,0 +1,44 @@ + + + + + +Calling Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Calling Contracts

    +

    Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.

    +

    Using Deploy Variants

    +

    ModuleBytes

    +

    ModuleBytes is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm.

    +

    However, you can also use ModuleBytes to deploy session code that calls a contract.

    +

    Further information on the structure of ModuleBytes can be found in here.

    +

    StoredContractByHash

    +

    StoredContractByHash is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question.

    +

    While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract.

    +

    Further information on the structure of StoredContractByHash can be found here.

    +

    StoredContractByName

    +

    StoredContractByName is similar to StoredContractByHash, with the main difference being the reference used to invoke on-chain Wasm. Where StoredContractByHash requires the contract hash, StoredContractByName uses a string stored as a NamedKey in the caller's account.

    +

    This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's NamedKeys.

    +

    StoredVersionedContractByHash

    +

    StoredVersionedContractByHash is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package.

    +

    This makes StoredVersionedContractByHash more stable than StoredContractByHash, as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version.

    +

    DApp developers that use contracts developed by other parties can use StoredVersionedContractByHash to avoid interruptions from contract version changes.

    +

    Further information on the structure of StoredVersionedContractByHash can be found here.

    +

    StoredVersionedContractByName

    +

    StoredVersionedContractByName combines the functionality of StoredContractByName and StoredVersionedContractByHash. It allows a developer to store a reference string as a NamedKey within their account context that references a contract by its contract package hash.

    +

    Further information on the structure of StoredVersionedContractByName can be found here.

    +

    Transfer

    +

    Native Transfers are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network.

    +

    Further information on the structure of a native Transfer can be found here.

    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html b/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html new file mode 100644 index 000000000..93e2143b1 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html @@ -0,0 +1,141 @@ + + + + + +Contract Hash vs. Package Hash | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Using the Contract Hash vs. the Package Hash

    +

    This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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. 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
    • +
    • 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 callers at the package level but track by both package and contract hash?
    • +
    • Will the contract allow other combinations of these basic concepts?
    • +
    +

    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, 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, which provides a stack of one or more entries of this kind:

    +
    /// 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.

    +

    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 and how Casper manages the calling of a contract.

    +

    Recommendations

    +

    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?

      + + + + + + + + + + + + + + + + + + + + + +
      AnswerRecommendation
      Specific accountsUse the account hash to identify and track each account.
      Exactly one specific accountUse the account hash of a specific account to identify it.
      Any accountsThere is no need to track the accounts by account hash.
      +
    2. +
    3. +

      Will you allow only contracts to use it? If so, what kind of contracts?

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      AnswerRecommendation
      Specific contract versionsUse the contract hash to identify each contract version.
      Specific contract versions of specific packagesUse the contract hash and the package hash to identify each contract version.
      Any contract versions of specific packagesUse only the package hash to identify each contract package.
      Any contract version of any contractThere is no need to track by contract or package hash.
      +
    4. +
    5. +

      Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      AnswerRecommendation
      Specific accounts and contract versionsUse the account hash to track each account and the contract hash to identify each contract version.
      Specific accounts and specific versions of specific packagesUse 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 packagesUse the account hash to identify each account and the package hash to identify each contract package.
      Any accounts and contractsThere is no need to track by account hash or contract hash.
      +
    6. +
    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/contract-vs-session/index.html b/1.5.X/developers/writing-onchain-code/contract-vs-session/index.html new file mode 100644 index 000000000..30aed6a14 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/contract-vs-session/index.html @@ -0,0 +1,62 @@ + + + + + +Contracts and Session Code | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Contracts and Session Code

    +

    What is Session Code?

    +

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the call function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse.

    +

    The best use of session code is when the situation calls for stateless execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary.

    +

    Comparing Session and Contract Code

    +

    The following table summarizes the key differences between session code and contract code on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Session CodeContract Code
    Session code always executes in the context of the account that signed the deploy containing the session code.A smart contract, which is stored on-chain logic, executes within its own context.
    Session code has only one entry point, call, which can be used to interact with the session code.A smart contract can have multiple entry points that can be invoked.
    The call entry point initiates any action the session code takes.Any action undertaken by a contract must initiate through an outside call, usually via session code.
    When a put_key call is made within the body of the session code, the key is added to the account's named keys.When a put_key call is made within the smart contract's context, the contract's record is modified to have a new named_key entry.
    For more information on how to write session code, see Writing Session Code.For more information on writing contracts, see Writing a Basic Smart Contract in Rust.
    +

    The following image depicts the comparison presented in the table.

    +

    Comparing Session and Contract Code

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/getting-started/index.html b/1.5.X/developers/writing-onchain-code/getting-started/index.html new file mode 100644 index 000000000..1f8082800 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/getting-started/index.html @@ -0,0 +1,77 @@ + + + + + +Getting Started with Rust | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Getting Started with Rust Casper Contracts

    +

    This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.

    +

    Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described here.

    +

    Creating a Project

    +

    You can create a new sample project very easily with the cargo casper crate. For example, let's say that I want to create a project named my-project for this tutorial (you can choose a different name if you wish), then I can simply run the command:

    +
    cargo casper my-project
    +

    If you look inside the newly-created my-project folder, you will find two crates: contract and tests. This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The tests crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test.

    +

    Using the nightly toolchain

    +

    Navigate to the my-project folder and open the rust-toolchain file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:

    +
    nightly-2022-08-03
    +

    Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the Rust Documentation on Channels and the Rust Documentation on Toolchains for further information.

    +

    As shown in this example, we recommend setting up the rust-toolchain file in your project's top-level directory.

    +

    You can also install the nightly Rust toolchain with this command:

    +
    rustup toolchain install nightly
    +

    Available Casper Rust crates

    +

    To support smart contract development with Rust, the following crates are published:

    +
      +
    • casper-contract - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts.
    • +
    • casper-engine-test-support - a virtual machine against which you can test your smart contracts.
    • +
    • casper-types - a library with types we use across the Rust ecosystem.
    • +
    +

    A crate is a compilation unit that can be compiled into a binary or a library.

    +
    note

    For a comprehensive list of crates, visit the Essential Casper Crates page.

    +

    Available API documentation

    +

    Each of the Casper crates comes with API documentation and examples for each function, located at https://docs.rs. The latest contract API documentation can be found here.

    +

    Compiling to Wasm

    +

    The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts.

    +
      +
    • Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG.
    • +
    +

    To compile the smart contract into Wasm, go into the my-project folder, and run the following commands:

    +
    cd my-project
    make prepare
    make build-contract
    +

    You can find the compiled contract on this path: my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm.

    +

    Linting

    +

    Casper contracts support Rust tooling such as clippy for linting contracts. Feel free to use them! You can also use the make check-lint command for linting your contract. Run this command inside the my-project folder:

    +
    make check-lint
    +

    Testing the Contract

    +

    In addition to creating the contract, the Casper crate also automatically created sample tests in the my-project/tests folder.

    +

    The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named build.rs if you are interested in looking more into it.

    +
    note

    Since the test script automatically builds the contract, during development you only need to run the command make test without the need for make build-contract.

    +

    A successful test run indicates that your smart contract environment is set up correctly.

    +
    make test
    +

    After the compilation finishes, the test should run and you should see output similar to this message in your terminal:

    +
    running 2 tests
    test tests::should_error_on_missing_runtime_arg ... ok
    test tests::should_store_hello_world ... ok

    test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    +

    As a brief example, open up my-project/contract/src/main.rs in your editor, modify the KEY_NAME value in the contract, and then rerun the make test command. You should observe that the smart contract recompiles and the test fails now.

    +

    Video Walkthrough

    +

    The following video tutorial complements this guide.

    +

    + +

    +

    Rust Resources

    +

    These Rust resources are excellent and we highly recommend them:

    +
      +
    1. https://doc.rust-lang.org/book/foreword.html
    2. +
    3. https://rustwasm.github.io/docs/book/
    4. +
    5. https://doc.rust-lang.org/stable/rust-by-example
    6. +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/simple-contract/index.html b/1.5.X/developers/writing-onchain-code/simple-contract/index.html new file mode 100644 index 000000000..7ac62e437 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/simple-contract/index.html @@ -0,0 +1,214 @@ + + + + + +Writing a Basic Smart Contract in Rust | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Writing a Basic Smart Contract in Rust

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    What is a Smart Contract?

    +

    A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a Deploy. Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic.

    +

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended.

    +

    Key Features of Casper Contracts

    +

    On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be sent to a node on a Casper network using a Deploy. Nodes within the network then gossip deploys, include them within a block, and finalize them. After finalizing, the network executes the deploys within the block.

    +

    Further, the Casper platform allows for upgradable contracts. A ContractPackage is created through the new_contract or new_locked_contract methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ContractPackageHash. The new contract is added to this package with a ContractHash key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable.

    +

    The new_contract and new_locked_contract methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract.

    +

    The contract contains required metadata, and it is primarily identified by its ContractHash. While the contract hash identifies a specific ContractVersion, the ContractPackageHash serves as an identifier for the most recent contract version in the contract package.

    +

    Creating the Directory Structure

    +

    To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below.

    +
    project-directory/

    └── contract/
    ├── src/
    └── main.rs
    └── Cargo.toml

    └── Makefile
    └── rust-toolchain

    └── tests/
    ├── src/
    └── integration-tests.rs
    └── Cargo.toml
    +

    The project structure would be different in a dApp with full-stack architecture.

    +

    Automatically using cargo casper

    +

    The cargo casper command can automatically set up the project structure. This is the recommended way of setting up a new Casper project.

    +
    cargo casper my-project
    +

    The cargo casper command will generate an example contract in the contract directory and an example tests crate with logic defined in the integration-tests.rs file. The Makefile includes commands to prepare and build the contract, and the rust-toolchain file specifies the target build version of Rust.

    +

    Semi-automatically using plain cargo

    +
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended and the command creates everything you need to start coding.

    +
      +
    1. +

      Create a top-level project directory for the contract code and its corresponding tests.

      +
    2. +
    3. +

      Inside the project directory, run the following command to create a new binary package called contract. Use a different name instead of contract if you wish.

      +
      cargo new contract
      +

      The command creates a contract folder with a /src/main.rs file and a Cargo.toml file:

      +
        +
      • main.rs - This file would contain the contract code.
      • +
      • Cargo.toml - This file would contain crate dependencies and other configurations.
      • +
      +

      The following sections explain how to update these files using example code.

      +
    4. +
    5. +

      Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of tests if you wish.

      +
      cargo new tests
      +

      The command creates a tests folder with a /src/main.rs file and a Cargo.toml file:

      +
        +
      • main.rs - This file would store the unit test code required to test the contract. You can rename the file to integration-tests.rs as shown in the example structure.
      • +
      • Cargo.toml - This is the file with test configurations.
      • +
      +

      The Testing Smart Contracts guide explains how to update the tests using example code.

      +
    6. +
    7. +

      Unlike cargo casper, cargo does not create a Makefile and rust-toolchain configuration file. Therefore, you must manually add these files to the project's root folder.

      +
    8. +
    +
    Example Makefile
    + +
    prepare:
    rustup target add wasm32-unknown-unknown

    build-contract:
    cd contract && cargo build --release --target wasm32-unknown-unknown
    wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true

    test: build-contract
    mkdir -p tests/wasm
    cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm
    cd tests && cargo test

    clippy:
    cd contract && cargo clippy --all-targets -- -D warnings
    cd tests && cargo clippy --all-targets -- -D warnings

    check-lint: clippy
    cd contract && cargo fmt -- --check
    cd tests && cargo fmt -- --check

    lint: clippy
    cd contract && cargo fmt
    cd tests && cargo fmt
    +
    +
    Example rust-toolchain file
    + +
    nightly-2022-08-03
    +
    +

    Manually

    +
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended, and the command creates everything you need to start coding.

    +
      +
    1. +

      Create a top-level project directory to store the contract code and corresponding tests.

      +
    2. +
    3. +

      Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder contract. You can use a different folder name if you wish.

      +
        +
      • In the contract folder, add a source folder called src and a Cargo.toml file, which specifies the contract's dependencies.
      • +
      • Add a Rust file with the contract code in the src folder. In this example, we have the main.rs file.
      • +
      +
    4. +
    5. +

      Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder tests.

      +
        +
      • In the tests folder, add a source folder called src and a Cargo.toml file, which specifies the required dependencies to run the tests.
      • +
      • In the src folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the integration-tests.rs file.
      • +
      +
    6. +
    7. +

      Manually create Makefile and rust-toolchain as per Semi-automatic setup (4.)

      +
    8. +
    +

    Dependencies

    +

    The Cargo.toml file in the contract folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the casper-contract and casper-types crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements.

    +

    If you followed the automatic setup, the dependencies should be in the Cargo.toml file. For the semi-automatic setup and manual setup, however, you'll need to manually add the dependencies to the crate's Cargo.toml file:

    +
    [dependencies]
    # A library for developing Casper network smart contracts.
    casper-contract = "1.4.4"
    # Types shared by many Casper crates for use on a Casper network.
    casper-types = "1.5.0"
    +
      +
    • casper-contract = "1.4.4" - Provides the SDK for the execution engine (EE). The latest version of the crate is published here.
    • +
    • casper-types = "1.5.0" - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published here.
    • +
    +

    Writing a Basic Smart Contract

    +

    At this point, you either have the default example contract defined in contract/src/main.rs (automatic setup using cargo-casper), an empty contract/src/main.rs file (manual project setup), or a Rust "hello world" program defined in the contract/src/main.rs (semi-automatic setup).

    +

    This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the contract/main.rs file if there are any.

    +

    The example code comes from the counter contract. This simple contract allows callers to increment and retrieve an integer. Casper provides a contract API within the casper_contract crate.

    +
    info

    Important syntax elements used frequently in Rust:

    To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples.

    +

    Updating the main.rs File

    +

    To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated main.rs file, remove the auto-generated main function.

    +
    #![no_std]
    #![no_main]
    +
      +
    • #![no_main] - This attribute tells the program not to use the standard main function as its entry point.
    • +
    • #![no_std] - This attribute tells the program not to import the standard libraries.
    • +
    +

    Defining required dependencies

    +

    Add the required imports and dependencies. The example code for the counter contract declares the following dependencies.

    +
    // This code imports necessary aspects of external crates that we will use in our contract code.
    extern crate alloc;

    // Importing Rust types.
    use alloc::{
    string::{String, ToString},
    vec::Vec,
    };
    // Importing aspects of the Casper platform.
    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };
    // Importing specific Casper types.
    use casper_types::{
    api_error::ApiError,
    contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},
    CLType, CLValue, URef,
    };
    +

    Defining the global constants

    +

    After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract.

    +
    // Creating constants for values within the contract package.
    const CONTRACT_PACKAGE_NAME: &str = "counter_package_name";
    const CONTRACT_ACCESS_UREF: &str = "counter_access_uref";

    // Creating constants for the various contract entry points.
    const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";
    const ENTRY_POINT_COUNTER_GET: &str = "counter_get";

    // Creating constants for values within the contract.
    const CONTRACT_VERSION_KEY: &str = "version";
    const CONTRACT_KEY: &str = "counter";
    const COUNT_KEY: &str = "count";
    +

    Defining the contract entry points

    +

    Entry points provide access to contract code installed in global state. Either session code or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program.

    +

    Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points.

    +

    If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded.

    +

    When defining entry points, begin with a #[no_mangle] line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable.

    +

    The following entry point is an example from the counter contract. To see all the available entry points, review the contract in GitHub.

    +
    #[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.
    }
    +

    Defining the call function

    +

    The call function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the call function. Review the call function in the counter contract.

    +
      +
    1. Define the runtime arguments.
    2. +
    +

    At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition.

    +

    Look at the CEP-78 contract to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple.

    +
      +
    1. Add the entry points into the call function.
    2. +
    +

    The call function replaces a traditional main function and executes automatically when a caller interacts with the contract. Within the call function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist.

    +

    Each entry point should have these arguments:

    +
      +
    • name - The entry point's name, which should be the same as the initial definition.
    • +
    • arguments - A list of runtime arguments declared as part of the definition of the entry point.
    • +
    • return type - The CLType returned by the entry point. Use the type Unit for empty return types.
    • +
    • access level - Access permissions of the entry point.
    • +
    • entry point type - This can be contract or session code.
    • +
    +

    This step adds the individual entry points to a counter_entry_points object using the add_entry_point method. This object will later be passed to the new_contract method.

    +
    #[no_mangle]
    pub extern "C" fn call() {
    // Initialize the count to 0 locally
    let count_start = storage::new_uref(0_i32);
    // Create the entry points for this contract
    let mut counter_entry_points = EntryPoints::new();

    counter_entry_points.add_entry_point(EntryPoint::new(
    ENTRY_POINT_COUNTER_GET,
    Vec::new(),
    CLType::I32,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    ));

    counter_entry_points.add_entry_point(EntryPoint::new(
    ENTRY_POINT_COUNTER_INC,
    Vec::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    ));
    }
    +

    In the following, we will add more content to this call function.

    +
      +
    1. Create the contract's named keys.
    2. +
    +

    NamedKeys are a collection of String-Key pairs used to identify some network data quickly.

    +
      +
    • The String is the name given to identify the data
    • +
    • The Key is the data to be referenced
    • +
    +

    You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found here.

    +

    For the counter, we store the integer that we increment into a named key.

    +
        // In the named keys of the counter contract, add a key for the count.
    let mut counter_named_keys = NamedKeys::new();
    let key_name = String::from(COUNT_KEY);
    counter_named_keys.insert(key_name, count_start.into());
    +
      +
    1. Create the contract.
    2. +
    +

    Use the new_contract method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a contractPackageHash. Then, it adds the contract to the package with a contractHash.

    +
        // Create a new contract package that can be upgraded.
    let (stored_contract_hash, contract_version) = storage::new_contract(
    counter_entry_points,
    Some(counter_named_keys),
    Some(CONTRACT_PACKAGE_NAME.to_string()),
    Some(CONTRACT_ACCESS_UREF.to_string()),
    );
    +

    Usually, these contracts are upgradeable with the ability to add new versions. You must have the access URef to the contract package to add a new contract version. This can be accomplished by passing the Some(CONTRACT_ACCESS_UREF.to_string()) argument to the new_contract method. To prevent any upgrades to a contract, use the new_locked_contract method described below.

    +
      +
    1. Create additional named keys.
    2. +
    +

    Generally, the Contract_Hash and Contract_Version are saved as NamedKeys in the account's context for later use.

    +
        // Store the contract version in the context's named keys.
    let version_uref = storage::new_uref(contract_version);
    runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());

    // Create a named key for the contract hash.
    runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());
    +

    The complete call function should look like this:

    +
    #[no_mangle]
    pub extern "C" fn call() {
    // Initialize the count to 0 locally
    let count_start = storage::new_uref(0_i32);
    // Create the entry points for this contract
    let mut counter_entry_points = EntryPoints::new();

    counter_entry_points.add_entry_point(EntryPoint::new(
    ENTRY_POINT_COUNTER_GET,
    Vec::new(),
    CLType::I32,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    ));

    counter_entry_points.add_entry_point(EntryPoint::new(
    ENTRY_POINT_COUNTER_INC,
    Vec::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    ));

    // In the named keys of the counter contract, add a key for the count.
    let mut counter_named_keys = NamedKeys::new();
    let key_name = String::from(COUNT_KEY);
    counter_named_keys.insert(key_name, count_start.into());

    // Create a new contract package that can be upgraded.
    let (stored_contract_hash, contract_version) = storage::new_contract(
    counter_entry_points,
    Some(counter_named_keys),
    Some(CONTRACT_PACKAGE_NAME.to_string()),
    Some(CONTRACT_ACCESS_UREF.to_string()),
    );

    /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned
    let (stored_contract_hash, _) =
    storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */

    // Store the contract version in the context's named keys.
    let version_uref = storage::new_uref(contract_version);
    runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());

    // Create a named key for the contract hash.
    runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());
    }
    +

    Locked Contracts

    +

    Locked contracts cannot contain other contract versions in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract.

    +
    pub fn new_locked_contract(
    entry_points: EntryPoints,
    named_keys: Option<NamedKeys>,
    hash_name: Option<String>,
    uref_name: Option<String>,
    ) -> (ContractHash, ContractVersion) {
    create_contract(entry_points, named_keys, hash_name, uref_name, true)
    }
    +
      +
    • entry_points - The set of entry points defined inside the smart contract.
    • +
    • named_keys - Any named-key pairs for the contract.
    • +
    • hash_name - Contract hash value. Puts contractHash in the current context's named keys under hash_name.
    • +
    • uref_name - Access URef value. Puts access_uref in the current context's named keys under uref_name.
    • +
    +

    Note: The current context is the context of the person who initiated the call function, usually an account.

    +

    The counter contract in our example would be locked if we created it this way:

    +
    let (stored_contract_hash, _) =
    storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);
    +

    Compiling Contract Code

    +

    To compile the smart contract, run the following commands in the contract folder in your project's directory, where the Cargo.toml file and src folder are hosted.

    +
    rustup target add wasm32-unknown-unknown
    cargo build --release --target wasm32-unknown-unknown
    +

    For the counter example, in the project directory where the Makefile is, run the following commands:

    +
    make prepare
    make build-contract
    +

    Executing Contract Code

    +

    Contract execution must be initiated through an outside call, usually via session code or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section.

    +

    Video Walkthrough

    +

    The following brief video accompanies this guide.

    +

    + +

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/testing-contracts/index.html b/1.5.X/developers/writing-onchain-code/testing-contracts/index.html new file mode 100644 index 000000000..b3728910d --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/testing-contracts/index.html @@ -0,0 +1,93 @@ + + + + + +Testing Smart Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Testing Smart Contracts

    +

    Introduction

    +

    As part of the Casper development environment, we provide a testing framework to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated.

    +
    note

    The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework.

    +

    Defining Dependencies in Cargo.toml

    +

    This guide uses the project structure, and example contract outlined here for creating tests.

    +

    To begin, outline the required test dependencies in the /tests/Cargo.toml file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:

    +
    [dependencies]
    casper-execution-engine = "5.0.0"
    casper-engine-test-support = { version = "5.0.0", features = ["test-support"] }
    casper-types = "3.0.0"
    +
      +
    • casper-execution-engine - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior.
    • +
    • casper-engine-test-support - A helper crate that provides the interface to write tests and interact with an instance of the execution engine.
    • +
    • casper-types - Types shared by many Casper crates for use on a Casper network.
    • +
    +

    Writing the Tests

    +

    The tests for the contract usually reside in the tests directory. Tests for the counter contract reside in the tests/src/integration-tests.rs file. Notice that this file contains an empty main method to initialize the test program. Alternatively, we could use the #![no_main] annotation at the top of the file, as we did here.

    +
    fn main() {
    panic!("Execute \"cargo test\" to test the contract, not \"cargo run\".");
    }
    +

    The #[cfg(test)] attribute tells the Rust compiler to compile and run the tests only when invoking cargo test, not while debugging or releasing. All testing functions reside within the grouping mechanism mod tests.

    +
    #[cfg(test)]
    mod tests {
    // The entire test program resides here
    }
    +

    Importing Builders and Constants

    +

    Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any CLTypes used within the contract code to be tested.

    +
        // Outlining aspects of the Casper test support crate to include.
    use casper_engine_test_support::{
    ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
    PRODUCTION_RUN_GENESIS_REQUEST,
    };
    // Custom Casper types that will be used within this test.
    use casper_types::{runtime_args, ContractHash, RuntimeArgs};
    +

    Next, you need to define any global variables or constants for the test.

    +
        // Contract Wasm File Paths (Constants)
    const COUNTER_V1_WASM: &str = "counter-v1.wasm";
    const COUNTER_V2_WASM: &str = "counter-v2.wasm";
    const COUNTER_V3_WASM: &str = "counter-v3.wasm";
    const COUNTER_CALL_WASM: &str = "counter-call.wasm";

    // Contract Storage Keys (Constants)
    const CONTRACT_KEY: &str = "counter";
    const COUNT_KEY: &str = "count";
    const LAST_UPDATED_KEY: &str = "last_updated";
    const CONTRACT_VERSION_KEY: &str = "version";

    // Contract Entry Points (Constants)
    const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement";
    const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";
    const ENTRY_POINT_COUNTER_LAST_UPDATED_AT: &str = "counter_last_updated_at";
    +

    Creating a Test Function

    +

    Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the InMemoryWasmTestBuilder to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain.

    +

    As part of this process, we use the PRODUCTION_RUN_GENESIS_REQUEST to install the system contracts necessary for the tests, including the Mint, Auction, and HandlePaymentcontracts, as well as establishing a default account and funding the associated purse.

    +
        #[test]
    /// Install version 1 of the counter contract and check its available entry points. ...
    fn install_version1_and_check_entry_points() {
    let mut builder = InMemoryWasmTestBuilder::default();
    builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST).commit();

    // See the repository for the full function.
    }
    +

    Installing the Contract

    +

    Test functions use the ExecuteRequestBuilder to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the DEFAULT_ACCOUNT_ADDR established by our genesis builder as the account sending the Deploy.

    +

    After building the ExecuteRequestBuilder (in this example, contract_installation_request), we process the request through builder.exec and then add and process other requests as necessary.

    +
        // Install the contract.
    let contract_v1_installation_request = ExecuteRequestBuilder::standard(
    *DEFAULT_ACCOUNT_ADDR,
    COUNTER_V1_WASM,
    runtime_args! {},
    )
    .build();

    builder
    .exec(contract_v1_installation_request)
    .expect_success()
    .commit();
    +

    Calling the Contract by Hash

    +

    To verify the installed contract, we need its contract hash. The test will then call its entry points using the contract_call_by_hash function. The following code retrieves the contract hash from the named keys of the DEFAULT_ACCOUNT_ADDR that sent the installation Deploy.

    +
        // Check the contract hash.
    let contract_v1_hash = builder
    .get_expected_account(*DEFAULT_ACCOUNT_ADDR)
    .named_keys()
    .get(CONTRACT_KEY)
    .expect("must have contract hash key as part of contract creation")
    .into_hash()
    .map(ContractHash::new)
    .expect("must get contract hash");
    +

    Next, we test an entry point that should not exist in the first version of the contract.

    +
        // Call the decrement entry point, which should not be in version 1 before the upgrade.
    let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(
    *DEFAULT_ACCOUNT_ADDR,
    contract_v1_hash,
    ENTRY_POINT_COUNTER_DECREMENT,
    runtime_args! {},
    )
    .build();

    // Try executing the decrement entry point and expect an error.
    builder
    .exec(contract_decrement_request)
    .expect_failure()
    .commit();
    +

    Calling the Contract using Session Code

    +

    In the counter example, we use the session code included in the counter-call.wasm file. For more details on what session code is and how it differs from contract code, see the next section.

    +

    The following session code uses the contract hash to identify the contract, the account for sending the deploy (DEFAULT_ACCOUNT_ADDR), the deploy to be sent (COUNTER_CALL_WASM), and the runtime arguments required. Once again, the ExecuteRequestBuilder simulates the execution of session code and calls the counter-inc entry point.

    +
        // Use session code to increment the counter.
    let session_code_request = ExecuteRequestBuilder::standard(
    *DEFAULT_ACCOUNT_ADDR,
    COUNTER_CALL_WASM,
    runtime_args! {
    CONTRACT_KEY => contract_v1_hash
    },
    )
    .build();

    builder.exec(session_code_request)
    .expect_success()
    .commit();
    +
    tip

    Testing Time-Sensitive Functions

    Normally, smart contracts operate on a blockchain where time advances in blocks. Testing functions that rely on time can be tricky.

    Simulating Time with with_block_time

    When building a request to call a contract function (using ExecuteRequestBuilder), you can set a custom block time with .with_block_time(desired_time). This pretends the function is called at that specific time.

    Example:

        let session_code_request = ExecuteRequestBuilder::standard(
    *DEFAULT_ACCOUNT_ADDR,
    COUNTER_CALL_WASM,
    runtime_args! {
    CONTRACT_KEY => contract_v1_hash
    },
    .with_block_time(5000)
    .build();

    This lets you test how your contract behaves at different points in time, all within your unit test.

    +

    Evaluating and Comparing Results

    +

    After calling the contract, we should verify the results received to ensure the contract operated as intended. The builder method retrieves the required information and converts it to the value type required. Then, assert_eq!() compares the result against the expected value.

    +
        // Verify the value of count is now 1.
    let incremented_count = builder
    .query(None, count_key, &[])
    .expect("should be stored value.")
    .as_cl_value()
    .expect("should be cl value.")
    .clone()
    .into_t::<i32>()
    .expect("should be i32.");

    assert_eq!(incremented_count, 1);
    +

    For more test examples, visit the casper-node GitHub repository.

    +

    Testing Contracts that Call Contracts

    +

    If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the DEFAULT_RUN_GENESIS_REQUEST. The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include.

    +

    Each contract installation will require an additional Wasm file installed through a Deploy using ExecuteRequestBuilder. Depending on your requirements as a smart contract author, you may need to use return values to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously.

    +

    The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ExecuteRequestBuilder. Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:

    +
      +
    • contract_call_by_hash - Calling a contract by its ContractHash.
    • +
    • contract_call_by_name - Calling a contract referenced by a named key in the signer's Account context.
    • +
    • versioned_contract_call_by_hash - Calling a specific contract version using its ContractHash.
    • +
    • versioned_contract_call_by_name - Calling a specific version of a contract referenced by a named key in the signer's Account context.
    • +
    +

    The calling contract must also provide an entry point and any necessary runtime arguments in all cases.

    +

    Running the Tests

    +

    To run the tests, the counter example uses a Makefile.

    +
    make test
    +

    Under the hood, the Makefile generates a tests/wasm folder, copies the Wasm files to the folder, and runs the tests using cargo test.

    +
    test: build-contract
    mkdir -p tests/wasm
    cp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm
    cp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm
    cp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm
    cd tests && cargo test
    +

    Video Walkthrough

    +

    The following brief video describes testing sample contract code.

    +

    + +

    +

    Further Testing

    +

    Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform local network testing using NCTL. This allows you to set up and control multiple local Casper nodes to perform testing in an other simulated network environment.

    +

    You may also wish to test your contracts on the Casper Testnet.

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/testing-session-code/index.html b/1.5.X/developers/writing-onchain-code/testing-session-code/index.html new file mode 100644 index 000000000..3ce40dec4 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/testing-session-code/index.html @@ -0,0 +1,93 @@ + + + + + +Testing Session Code | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Testing Session Code

    +

    This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.

    +

    Specifying Dependencies in Cargo.toml

    +

    The Cargo.toml sample file in the tests directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:

    +
    [dev-dependencies]
    casper-engine-test-support = { version = "2.2.0", features = ["test-support"] }
    casper-execution-engine = "2.0.0"
    casper-types = "1.5.0"
    +
      +
    • casper-execution-engine - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior.
    • +
    • casper-engine-test-support - A helper crate that provides the interface to write tests and interact with an instance of the execution engine.
    • +
    • casper-types - Types shared by many Casper crates for use on a Casper network.
    • +
    +

    Writing the Tests

    +

    Tests for this example session code reside in the tests/src/integration-tests.rs file.

    +

    Notice that this file contains an empty main method to initialize the test program. Alternatively, we could use the #![no_main] annotation at the top of the file, as we did here.

    +
    fn main() {
    panic!("Execute \"cargo test\" to test the contract, not \"cargo run\".");
    }
    +

    The #[cfg(test)] attribute tells the Rust compiler to compile and run the tests only when invoking cargo test, not while debugging or releasing. All testing functions reside within the grouping mechanism mod tests.

    +
    #[cfg(test)]
    mod tests {
    // The entire test program resides here
    }
    +

    Importing Required Packages

    +

    Next, import the packages required for the tests to run. The example tests use these packages:

    +
        use casper_engine_test_support::{
    ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
    DEFAULT_RUN_GENESIS_REQUEST,
    };
    use casper_types::account::AccountHash;
    use casper_types::{runtime_args, RuntimeArgs};
    +

    Defining The Constants

    +

    The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point.

    +
    const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account
    const ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument
    const CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE
    +

    Creating a Test Function

    +

    In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the #[test] attribute.

    +
    #[test]
    fn <unit-test-name>{
    // Test function implementation
    }
    +

    This unit test is a good example of testing session code. At a high level, the test follows this process:

    +
      +
    1. Initialize an instance of the execution engine and the InMemoryWasmTestBuilder.
    2. +
    +
        let mut builder = InMemoryWasmTestBuilder::default();
    +
      +
    1. Execute the genesis process.
    2. +
    +
        builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();
    +
      +
    1. +

      Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit GitHub.

      +
    2. +
    3. +

      Retrieve runtime arguments, which should be the same as defined in the contract.

      +
    4. +
    5. +

      Create the execution request that sets up the session code to be processed. In this example, the CONTRACT_WASM is the session code.

      +
    6. +
    +
        let execute_request =
    ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)
    .build();
    +
      +
    1. Invoke the execution engine to process the session code.
    2. +
    +
        builder.exec(execute_request).expect_success().commit();
    +
      +
    1. Verify that the results match the expected output. This example checks the associated keys.
    2. +
    +
        assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));
    +

    Running the Test

    +

    This example uses a Makefile to run the tests.

    +
    make test
    +

    Under the hood, the Makefile generates a tests/wasm folder, copies the Wasm to the folder, and runs the tests with cargo test.

    +
    mkdir -p tests/wasm
    cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm
    cd tests && cargo test
    +

    Other Examples

    +

    In the counter unit tests, we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code.

    +
        // Use session code to increment the counter.
    let session_code_request = ExecuteRequestBuilder::standard(
    *DEFAULT_ACCOUNT_ADDR,
    COUNTER_CALL_WASM,
    runtime_args! {
    CONTRACT_KEY => contract_v1_hash
    },
    )
    .build();

    builder.exec(session_code_request)
    .expect_success()
    .commit();
    +

    The verification step looks like this:

    +

    let incremented_count = builder
    .query(None, count_key, &[])
    .expect("should be stored value.")
    .as_cl_value()
    .expect("should be cl value.")
    .clone()
    .into_t::<i32>()
    .expect("should be i32.");

    assert_eq!(incremented_count, 1);
    +

    For many more examples, visit the casper-node GitHub repository.

    +

    Video Walkthrough

    +

    The following brief video describes testing the sample session code for configuring an account.

    +

    + +

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/upgrading-contracts/index.html b/1.5.X/developers/writing-onchain-code/upgrading-contracts/index.html new file mode 100644 index 000000000..d73c1e5cf --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/upgrading-contracts/index.html @@ -0,0 +1,42 @@ + + + + + +Upgrading and Maintaining Smart Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Upgrading and Maintaining Smart Contracts

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Our smart contract packaging tools enable you to:

    +
      +
    • Upgrade your contracts and specify how the state of the contract is managed
    • +
    • Specify whether a contract is upgradable or immutable
    • +
    • 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. If you find that you need to use a disabled contract version, you may also re-enable it.

    +

    +

    The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain.

    +

    Videos and Tutorials

    +

    To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the Writing On-Chain Code documentation.

    +

    + +

    +

    Or, for a different perspective, consult the Smart Contract Upgrade Tutorial.

    +

    Maintaining a Contract

    +

    The contract maintenance process is generally covered through the contract upgrade process.

    +

    Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance.

    +

    On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process.

    + + \ No newline at end of file diff --git a/1.5.X/developers/writing-onchain-code/writing-session-code/index.html b/1.5.X/developers/writing-onchain-code/writing-session-code/index.html new file mode 100644 index 000000000..5222544a4 --- /dev/null +++ b/1.5.X/developers/writing-onchain-code/writing-session-code/index.html @@ -0,0 +1,92 @@ + + + + + +Writing Session Code | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Writing Session Code

    +

    This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.

    +

    Creating the Directory Structure

    +

    For writing session code, we use the same project structure used for writing contracts, described here.

    +

    Example 1: Writing Session Code

    +

    The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: https://github.com/casper-ecosystem/two-party-multi-sig/. The sample code adds an associated key to the account and updates the action thresholds. Remember that an Account on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository.

    +
    git clone https://github.com/casper-ecosystem/two-party-multi-sig/
    +
    note

    Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious.

    +

    Dependencies in Cargo.toml

    +

    The Cargo.toml file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the casper-contract and casper-types crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements.

    +
      +
    • casper-contract = "1.4.4" - Provides the SDK for the execution engine (EE). The latest version of the crate is published here.
    • +
    • casper-types = "1.5.0" - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published here.
    • +
    +

    Updating the main.rs File

    +

    Open the contract/src/main.rs file that contains the sample session code. Notice these directives at the top of the file:

    +
      +
    • #![no_std] - Specifies not to import the standard library.
    • +
    • #![no_main] - Indicates the main function is not required since the session code has only one entry point as the call function.
    • +
    +

    Next, review the imported crates and other required libraries.

    +
    #![no_std]
    #![no_main]

    use casper_contract::contract_api::{account, runtime};
    use casper_contract::unwrap_or_revert::UnwrapOrRevert;
    use casper_types::account::{AccountHash, ActionType, Weight};
    +

    After the imported libraries, we usually find the constants.

    +
    const ASSOCIATED_ACCOUNT: &str = "deployment-account";
    +

    Next, we see the call function, the only entry point in this example session code. The #[no_mangle] flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the call string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project.

    +
    #[no_mangle]
    pub extern "C" fn call() {
    // Open the repository for details
    }
    +

    When compiled, the call function could be used from another library. For example, a C library could link to the resulting Wasm.

    +

    Example 2: Calling a Contract with Session Code

    +

    Another example of session code is the counter-call/src/main.rs file, in the counter repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository.

    +
    git clone https://github.com/casper-ecosystem/counter/
    +

    Observe how the project is set up and review the dependencies in the counter/counter-call/Cargo.toml file. Then, open the counter/counter-call/src/main.rs file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants.

    +

    The call function interacts with the contract's counter_inc and counter_get entry points. This is how the session's call entry point triggers the logic stored inside the counter contract.

    +
        // Call the counter to get the current value.
    let current_counter_value: u32 =
    runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());

    // Call the counter to increment the value.
    let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());
    +

    Example 3: Transfers using Session Code

    +

    In this example, we use session code to perform a transfer using the transfer_from_purse_to_purse system function. The entire session code is available in GitHub, but this is the call function:

    +
    #[no_mangle]
    pub extern "C" fn call() {
    let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);
    let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);

    let source_purse = account::get_main_purse();

    system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)
    .unwrap_or_revert();
    }
    +

    Another system function is transfer_to_public_key. The full session code example is on GitHub.

    +
    #[no_mangle]
    pub extern "C" fn call() {
    let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);
    let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);
    system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();
    }
    +

    Other transfer functions are available here:

    + +

    Compiling Session Code

    +

    Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the Cargo.toml file and src folder.

    +
    cargo build --release --target wasm32-unknown-unknown
    +

    For the examples above, you may use the Makefiles provided:

    +
    make build-contract
    +

    Executing Session Code

    +

    Before running session code on a live Casper network, test it as described here. You can also set up a local network using NCTL for additional tests.

    +

    Session code can execute on a Casper network via a Deploy. All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state.

    +

    The Casper command-line client and its put-deploy command provide one way to execute session code.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --chain-name <NETWORK-NAME> \
    --secret-key <PATH> \
    --payment-amount <PAYMENT-AMOUNT> \
    --session-path <SESSION-PATH> \
    --session-arg <"NAME:TYPE='VALUE'" OR "NAME:TYPE=null">
    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777.
    • +
    • secret-key - The file name containing the secret key of the account paying for the deploy.
    • +
    • chain-name - The network where the deploy should be sent. For Mainnet, use casper. For Testnet, use casper-test.
    • +
    • payment-amount - Payment for the deploy in motes. The payment amount varies based on the deploy and network chainspec.
    • +
    • session-path - Path to the contract Wasm, pointing to the compiled contract.
    • +
    • session-arg - A named and typed argument passed to the Wasm code.
    • +
    +

    Use the --help option to view an updated list of supported arguments.

    +
    casper-client put-deploy --help
    +

    Video Walkthrough

    +

    The following brief video describes sample session code for configuring an account.

    +

    + +

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/next/disclaimer/index.html b/1.5.X/disclaimer/index.html similarity index 70% rename from next/disclaimer/index.html rename to 1.5.X/disclaimer/index.html index 4df56a251..4257ba267 100644 --- a/next/disclaimer/index.html +++ b/1.5.X/disclaimer/index.html @@ -1,21 +1,21 @@ - + -Disclaimer | Casper Docs - Redux +Disclaimer | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Disclaimer

    + submit an issue on Github
    Version: 1.5.X

    Disclaimer

    By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.

    Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR”). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.

    This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO”) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA”) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA”) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.

    @@ -72,6 +72,6 @@

    Risk Factors

    Risks associated with forking: the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient’s CSPR (if and when created and/or issued).

    -

    +
    \ No newline at end of file diff --git a/1.5.X/economics/index.html b/1.5.X/economics/index.html new file mode 100644 index 000000000..2f9349960 --- /dev/null +++ b/1.5.X/economics/index.html @@ -0,0 +1,46 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Overview of Casper Economics

    +

    Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value.

    +

    We cannot yet provide formal game-theoretic results for our incentive mechanisms, but interested readers can follow our progress with the Economics of the Casper Blockchain paper, which will be periodically updated to summarize ongoing research.

    +

    This section of our online documentation is intended only to familiarize the user with our core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active.

    +

    Consensus

    +

    The consensus layer of our platform runs on the Highway flavor of CBC-Casper. The distinguishing characteristics of this protocol are its safety and liveness guarantees. Specifically, under the assumptions made in the Highway protocol paper, blocks in the canonical history cannot be reverted, and new blocks continue to be added to this history indefinitely. The assumptions, however, require that a large portion of validators remain online and honest; this assumed behavior must be incentivized for the platform to remain secure and live.

    +

    When discussing consensus, we default to considering it "one era at a time," unless expressly stated otherwise, in keeping with the Highway paper. Recall that each era is, effectively, a separate instance of the protocol.

    +

    Agents (consensus layer)

    +

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain's security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.

    +

    Delegators are users who participate in the platform's security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    +

    Incentives (consensus layer)

    +

    The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.

    +

    Rewards (per era) are issued to validators who perform, at their nominal pace, in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator.

    +

    Evictions deactivate validators who fail to participate in an era, disabling their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract.

    +

    Runtime

    +

    The runtime layer encompasses the deployment and execution of smart contracts, session code, and other activity that performs computation on the global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to metering computing time, measured as gas. Gas can be conceptualized as relative time use of different Wasm operations and host-side functions. Use of storage is also presently assigned a gas cost. We do not currently have a pricing mechanism for metered gas, although an outstanding Casper Enhancement Proposal (CEP #22) suggests the implementation of a first-price gas auction similar to Ethereum's. The initial Mainnet deploy selection mechanism is based on FIFO.

    +

    We expect to continue work on runtime resource markets, particularly gas futures (CEP #17).

    +

    Agents (consensus layer)

    +

    Validators again play a vital role in this layer since protocol operation includes construction and validation of new blocks, consisting of deploys that change the global state, which the validators also maintain.

    +

    Users execute session and contract code using the platform's computational resources

    +

    Incentives (consensus layer)

    +

    Transaction fees, or charges for gas use, ensure that the users compensate validators for performing their computations. Transaction fees are awarded to the block creator. Because we expect to launch with FIFO ordering of deploys, it can be assumed that one unit of gas will be priced at one mote until future changes to deploy orders are implemented.

    +

    Ecosystem

    +

    The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps.

    +

    Macroeconomy

    +

    Casper's macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics are different from those of "digital gold" tokens like Bitcoin, designed to be scarce. Our tokens are minted from a fixed starting basis, which is accounted for by tokens distributed to genesis validators, employees, community members and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate from this basis.

    +

    The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, a behavior we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity on the platform and discourage hoarding tokens in expectation of speculative gain.

    + + \ No newline at end of file diff --git a/1.5.X/glossary/index.html b/1.5.X/glossary/index.html new file mode 100644 index 000000000..8e8e3045c --- /dev/null +++ b/1.5.X/glossary/index.html @@ -0,0 +1,24 @@ + + + + + +Glossary | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Glossary

    +

    These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    + + \ No newline at end of file diff --git a/1.5.X/index.html b/1.5.X/index.html new file mode 100644 index 000000000..00eacb888 --- /dev/null +++ b/1.5.X/index.html @@ -0,0 +1,29 @@ + + + + + +What is Casper? | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    What is Casper?

    What is Casper?

    +

    Casper is a new Turing-complete smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    +

    The network's consensus protocol is called Highway, and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Highway allows networks to reach higher thresholds of finality, meaning that more blocks are finalized, and validators agree to add them to the blockchain. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the correct-by-construction (CBC) Casper research.

    +

    Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's core features and strengths enable developers and enterprises to reap the benefits of blockchain technology.

    +

    Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises.

    +

    How does Casper work?

    +

    Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network.

    +

    To understand the design further, read this article.

    +

    Disclaimer

    +

    Read the Legal Disclaimer regarding this CasperLabs Tech Spec (this "Whitepaper").

    + + \ No newline at end of file diff --git a/1.5.X/operators/becoming-a-validator/bonding/index.html b/1.5.X/operators/becoming-a-validator/bonding/index.html new file mode 100644 index 000000000..94da3db95 --- /dev/null +++ b/1.5.X/operators/becoming-a-validator/bonding/index.html @@ -0,0 +1,91 @@ + + + + + +Bonding | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Bonding as a Validator

    +

    It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.

    +

    In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, the time for bid submission to inclusion in the validator set is a minimum of six hours. Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship.

    +

    Method 1: Bonding with the System Auction Contract

    +

    This method submits a bid using the system auction contract. Call the existing add_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point add_bid \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<BID_AMOUNT>'" \
    --session-arg="delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entrypoint that will be used when calling the contract
    2. +
    +

    The add_bid entry point expects three arguments:

    +
      +
    1. public key: The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid
    2. +
    3. amount: The bidding amount
    4. +
    5. delegation_rate: Percentage of the rewards that the node operator retains for their services
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    Calling the add_bid entry point on the auction contract has a fixed cost of 2.5 CSPR.

    +

    Example:

    +

    This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point add_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg="delegation_rate:u8='10'"
    +

    Next, check the status of the auction to see if you have won a validator slot.

    +

    Method 2: Bonding with Compiled Wasm

    +

    Another way to send a bonding transaction to the network is via a deploy containing the compiled add_bid.wasm. For details, refer to Building the Required Contracts.

    +

    The following deploy is a template for sending a bonding request:

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<BID-AMOUNT>'" \
    --session-arg="delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes
    8. +
    9. session-path - The path to the compiled Wasm on your computer
    10. +
    +

    The add_bid.wasm expects three arguments:

    +
      +
    1. public_key: The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid
    2. +
    3. amount: The bidding amount
    4. +
    5. delegation_rate: Percentage of the rewards that the node operator retains for their services
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    This method is more expensive than calling the add_bid entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.

    +

    Example:

    +

    Here is an example request to bond using the add_bid.wasm. The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.235.219:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 3000000000 \
    --session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg="delegation_rate:u8='10'"
    +

    Next, check the bid status to see if you have won a validator slot.

    +

    Checking the Bid Status

    +

    Since the bid was submitted using a deploy like any other, perform get-deploy using the casper-client, to see the execution status.

    +
    casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>
    +

    If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:

    +
    casper-client get-auction-info --node-address http://<HOST:PORT>
    +
    Example auction info response
    + +
    {
    "jsonrpc": "2.0",
    "result": {
    "bids": [
    {
    "bid": {
    "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",
    "delegation_rate": 0,
    "delegators": [],
    "release_era": null,
    "reward": "93328432442428418861229954179737",
    "staked_amount": "10000000000000000"
    },
    "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"
    },
    {
    "bid": {
    "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",
    "delegation_rate": 10,
    "delegators": [],
    "release_era": null,
    "reward": "0",
    "staked_amount": "9000000000000000"
    },
    "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"
    },
    {
    "bid": {
    "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",
    "delegation_rate": 10,
    "delegators": [],
    "release_era": null,
    "reward": "266185120443441810685787",
    "staked_amount": "100000000"
    },
    "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"
    },
    {
    "bid": {
    "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",
    "delegation_rate": 10,
    "delegators": [],
    "release_era": null,
    "reward": "0",
    "staked_amount": "9000000000000000"
    },
    "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"
    },
    {
    "bid": {
    "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",
    "delegation_rate": 0,
    "delegators": [],
    "release_era": null,
    "reward": "93328432442428418861229954179737",
    "staked_amount": "10000000000000000"
    },
    "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"
    }
    ],
    "block_height": 318,
    "era_validators": [
    {
    "era_id": 20,
    "validator_weights": [
    {
    "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
    "weight": "10000000000000000"
    },
    {
    "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
    "weight": "100000000"
    },
    {
    "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
    "weight": "10000000000000000"
    }
    ]
    },
    {
    "era_id": 21,
    "validator_weights": [
    {
    "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
    "weight": "10000000000000000"
    },
    {
    "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
    "weight": "100000000"
    },
    {
    "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
    "weight": "10000000000000000"
    }
    ]
    },
    {
    "era_id": 22,
    "validator_weights": [
    {
    "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
    "weight": "10000000000000000"
    },
    {
    "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
    "weight": "100000000"
    },
    {
    "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
    "weight": "10000000000000000"
    }
    ]
    },
    {
    "era_id": 23,
    "validator_weights": [
    {
    "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",
    "weight": "10000000000000000"
    },
    {
    "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",
    "weight": "100000000"
    },
    {
    "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",
    "weight": "9000000000000000"
    },
    {
    "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",
    "weight": "10000000000000000"
    }
    ]
    }
    ],
    "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"
    },
    "id": -3624528661787095850
    }
    +
    +

    +

    Note the era_id and the validator_weights in the response above. The current era is the one with the lowest ID in the era_validators array. For a given era_id, a set of validators is defined. If the public key associated with a bid appears in the validator_weights structure for an era, then the account is bonded in that era.

    +

    A Losing Bid

    +

    If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding.

    +

    Avoiding Ejection

    +

    To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details here.

    +

    Withdrawing a Bid

    +

    Follow the steps in Unbonding to withdraw a bid.

    + + \ No newline at end of file diff --git a/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/index.html b/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/index.html new file mode 100644 index 000000000..a71b583bb --- /dev/null +++ b/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/index.html @@ -0,0 +1,35 @@ + + + + + +Inactive and Faulty Nodes | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Inactive vs. Faulty Validator Nodes

    +

    This page describes the differences between a validator node being considered inactive or faulty.

    +

    In the last block of each era N, the consensus algorithm checks whether there are any messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as inactive in that block.

    +

    Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as faulty in that block. Usually, that means:

    +
      +
    • If you got marked as inactive, your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed.
    • +
    • If you got marked as faulty, you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file.
    • +
    +

    The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era N. The auction determines the validator set for the era after the next (because auction_delay is set to 1 on mainnet), i.e., for era N + 2. That means you will still be a validator (with a weight proportional to your stake) in the next era, N + 1, but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder.

    +

    And even in the next era, N + 1:

    +
      +
    • If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era N + 1, it will get evicted for being offline in era N.
    • +
    • If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards.
    • +
    +

    In both cases, you remain evicted until you reactivate your bid, as described here.

    + + \ No newline at end of file diff --git a/1.5.X/operators/becoming-a-validator/index.html b/1.5.X/operators/becoming-a-validator/index.html new file mode 100644 index 000000000..eb92b4dc3 --- /dev/null +++ b/1.5.X/operators/becoming-a-validator/index.html @@ -0,0 +1,47 @@ + + + + + +Becoming a Validator | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Becoming a Validator

    +

    After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Bonding as a ValidatorA guide about the bonding process and submitting a bid
    Unbonding as a ValidatorThe process to withdraw a bid and unbonding
    Recovering from Validator EvictionSteps a validator needs to take if it is evicted from the validator set
    Inactive vs. Faulty NodesThe differences between inactive and faulty nodes
    + + \ No newline at end of file diff --git a/1.5.X/operators/becoming-a-validator/recovering/index.html b/1.5.X/operators/becoming-a-validator/recovering/index.html new file mode 100644 index 000000000..bcd4a2857 --- /dev/null +++ b/1.5.X/operators/becoming-a-validator/recovering/index.html @@ -0,0 +1,102 @@ + + + + + +Recovery | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Recovering from Validator Eviction

    +

    This topic discusses the steps a validator needs to take if it is evicted from the validator set:

    +
      +
    1. Detecting the eviction
    2. +
    3. Correcting any underlying node issues
    4. +
    5. Re-building the contracts for bonding
    6. +
    7. Activating the bid
    8. +
    9. Checking the bid
    10. +
    +

    The Inactive vs. Faulty Validator Nodes topic explains why a node would be evicted.

    +

    Detecting the Eviction

    +

    The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era.

    +

    For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era.

    +

    Detection using CSPR.live

    +

    If you were a previous validator and still exist on the Validators Auction tab but not in Validators, you may have been evicted or outbid.

    +

    Detection using the Casper Client

    +

    All auction information is returned with the casper-client get-auction-info command. It would help if you filtered this down to your public key.

    +

    You can replace the public_key with your public key manually and run this command:

    +
    casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == "<public_key>")'
    +

    Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:

    +
    casper-client get-auction-info | jq --arg pk "$(cat /etc/casper/validator_keys/public_key_hex)" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'
    +

    You know you were evicted if the get-auction-info command returned your bid showing an inactive field. See the Inactive vs. Faulty Validator Nodes page for more information.

    +

    If you receive a parse error: Invalid numeric literal at, this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:

    +
    casper-client get-auction-info
    +

    Correcting any Underlying Node Issues

    +

    Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync.

    +

    To check if your node is in sync, compare the current block height at https://cspr.live/ with the height from your node with:

    +
    curl -s localhost:8888/status | jq .last_added_block_info
    +

    If you cannot figure out the issue, ask for help in the node-tech-support channel on Discord.

    +

    Activating the Bid

    +

    Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the activate_bid entry point from the system auction contract. The second method involves building the activate_bid.wasm contract as explained in Building the Required Contracts.

    +

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    +

    Method 1: Activating the Bid with the System Auction Contract

    +

    This method calls the existing activate_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point activate_bid \
    --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version 1.5.1
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entry point that will be used when calling the system auction contract. In this case, it is activate_bid
    2. +
    +

    The activate_bid entry point expects one argument:

    +
      +
    1. validator_public_key: The hexadecimal public key of the validator reactivating its bid. This key must match the secret key that signs the bid activation request
    2. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +
    tip

    Calling the activate_bid entry point on the auction contract has a fixed cost of 10,000 motes.

    +

    Example:

    +

    This example uses the Casper Testnet to reactivate a bid:

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 10000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point activate_bid \
    --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"
    +

    Next, check the bid activation status.

    +

    Method 2: Activating the Bid with Compiled Wasm

    +

    The second method to rejoin the network is to reactivate your bid using the activate_bid.wasm.

    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \
    --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes
    8. +
    9. session-path - The path to the compiled Wasm on your computer
    10. +
    +

    The activate_bid.wasm expects one argument:

    +
      +
    1. validator_public_key: The hexadecimal public key of the validator reactivating its bid. This key must match the secret key that signs the bid activation request
    2. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    As described above, this method is much more expensive than calling the activate_bid entry point.

    +

    Example:

    +

    Here is an example that reactivates a bid using the activate_bid.wasm. You must modify the payment and other values in the deploy based on your environment and the network's chainspec.toml. For example, if you use the activate_bid.wasm on a network with node version 1.4.9, you will require a balance of at least 5 CSPR for this contract.

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 5000000000 \
    --session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \
    --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"
    +

    Check that the deploy was successful with the casper-client get-deploy <deploy_hash> or by searching for the deploy hash on https://cspr.live/. Also, check the bid activation status as shown below.

    +

    Checking the Bid Activation

    +

    Once your deploy processes, you can check your bid again. You should now see "inactive": false in the output.

    +

    If you wait until the next Era starts, you should also see your public key as a future validator on the Validators tab.

    + + \ No newline at end of file diff --git a/next/operators/becoming-a-validator/unbonding/index.html b/1.5.X/operators/becoming-a-validator/unbonding/index.html similarity index 61% rename from next/operators/becoming-a-validator/unbonding/index.html rename to 1.5.X/operators/becoming-a-validator/unbonding/index.html index 92b78a0f8..63a1cffee 100644 --- a/next/operators/becoming-a-validator/unbonding/index.html +++ b/1.5.X/operators/becoming-a-validator/unbonding/index.html @@ -1,21 +1,21 @@ - + -Unbonding | Casper Docs - Redux +Unbonding | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Unbonding as a Validator

    + submit an issue on Github
    Version: 1.5.X

    Unbonding as a Validator

    Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.

    Method 1: Unbonding with the System Auction Contract

    This method withdraws a bid using the system auction contract. Call the existing withdraw_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    @@ -64,12 +64,12 @@

    Metho

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    note

    This method is more expensive than calling the withdraw_bid entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.

    Example:

    -

    Here is an example request to unbond stake using the withdraw_bid.wasm. The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +

    Here is an example request to unbond stake using the withdraw_bid.wasm. The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \
    --payment-amount 4000000000 \
    --session-arg="public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg="amount:u512='1000000000000'"

    Check the Auction Contract

    Check the auction contract for updates to the bid amounts.

    casper-client get-auction-info --node-address http://<HOST:PORT>

    Unbonding Wait Period

    -

    To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours.

    +

    To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours.

    \ No newline at end of file diff --git a/1.5.X/operators/index.html b/1.5.X/operators/index.html new file mode 100644 index 000000000..d92a17781 --- /dev/null +++ b/1.5.X/operators/index.html @@ -0,0 +1,51 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Operators Overview

    +

    Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.

    +

    Prior knowledge of Unix-based operating systems and proficiency with systemd and bash scripting are recommended. If you are unfamiliar with systemd, the Arch Linux page on systemd is a good introduction.

    +

    Operators should know the hardware requirements before running a node.

    +

    Also, the network requirements specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes.

    +

    Review the node's configuration first. Then, you can follow the node installation instructions.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Node SetupHow to set up a Casper node
    Becoming a ValidatorHow to join a network and become a validator
    Private Network SetupHow to set up a private Casper network
    MaintenanceTopics related to node maintenance
    + + \ No newline at end of file diff --git a/next/operators/maintenance/archiving-and-restoring/index.html b/1.5.X/operators/maintenance/archiving-and-restoring/index.html similarity index 65% rename from next/operators/maintenance/archiving-and-restoring/index.html rename to 1.5.X/operators/maintenance/archiving-and-restoring/index.html index 56e8a9baa..6d183ca64 100644 --- a/next/operators/maintenance/archiving-and-restoring/index.html +++ b/1.5.X/operators/maintenance/archiving-and-restoring/index.html @@ -1,21 +1,21 @@ - + -Archive and Restore a DB | Casper Docs - Redux +Archive and Restore a DB | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Archiving and Restoring a Database

    + submit an issue on Github
    Version: 1.5.X

    Archiving and Restoring a Database

    This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.

    Zstandard is the best method for compression speed and space for the current LMDB-based database system that the casper-node uses.

    note

    The values presented in this document assume that the trie-compact tool was run on a Mainnet database for compression. Contact the support team if you have questions.

    @@ -97,6 +97,6 @@

    Strea

    Starting a New Node with a Decompressed DB

    If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the node_util.py script included in the casper-node-launcher installation.

    For example, if you are using a DB archive from node version 1.4.5, you would run this command:

    -
    sudo /etc/casper/node_util.py force_run_version 1_4_5
    +
    sudo /etc/casper/node_util.py force_run_version 1_4_5
    \ No newline at end of file diff --git a/1.5.X/operators/maintenance/index.html b/1.5.X/operators/maintenance/index.html new file mode 100644 index 000000000..75c18c1db --- /dev/null +++ b/1.5.X/operators/maintenance/index.html @@ -0,0 +1,39 @@ + + + + + +Node Maintenance | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Node Maintenance

    +

    This section covers maintenance actions such as moving a node to a different location and restoring a database.

    + + + + + + + + + + + + + + + + + +
    TitleDescription
    Archiving and Restoring a DatabaseUsing zstd for the compression and decompression of a Casper node database and streaming from a backup location
    Moving a Validating NodeWays to move a validator node to another machine
    + + \ No newline at end of file diff --git a/next/operators/maintenance/moving-node/index.html b/1.5.X/operators/maintenance/moving-node/index.html similarity index 59% rename from next/operators/maintenance/moving-node/index.html rename to 1.5.X/operators/maintenance/moving-node/index.html index 38d8b08a9..190a2e931 100644 --- a/next/operators/maintenance/moving-node/index.html +++ b/1.5.X/operators/maintenance/moving-node/index.html @@ -1,21 +1,21 @@ - + -Move a Node | Casper Docs - Redux +Move a Node | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Moving a Validating Node

    + submit an issue on Github
    Version: 1.5.X

    Moving a Validating 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

    @@ -71,6 +71,6 @@

    After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era.

    tip

    You could time the swap right before the era ends to minimize reward losses.

    Checking file permissions

    -

    After the swap, check and fix file permissions by running the /etc/casper/node_util.py utility.

    +

    After the swap, check and fix file permissions by running the /etc/casper/node_util.py utility.

    \ No newline at end of file diff --git a/1.5.X/operators/setup-network/chain-spec/index.html b/1.5.X/operators/setup-network/chain-spec/index.html new file mode 100644 index 000000000..afebf5993 --- /dev/null +++ b/1.5.X/operators/setup-network/chain-spec/index.html @@ -0,0 +1,709 @@ + + + + + +The Chainspec | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    The Blockchain Specification

    +

    The blockchain specification, or chainspec, is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 1.5.2 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring.

    +

    protocol

    +

    These settings describe the active protocol version.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    versionThe Casper node protocol version.'1.5.2'
    hard_resetWhen set to true, clear blocks and deploys back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true.true
    activation_pointThe protocol version that should become active.

    If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 — see the finality_threshold_fraction below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash.

    If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era.
    9100
    +

    network

    +

    The following settings configure the networking layer.

    + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    nameHuman readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash.'casper'
    maximum_net_message_sizeThe maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level.25_165_824
    +

    core

    +

    These settings manage the core protocol behavior.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    era_durationEra duration.'120min'
    minimum_era_heightMinimum number of blocks per era. An era will take longer than era_duration if that is necessary to reach the minimum height.20
    minimum_block_timeMinimum difference between a block's and its child's timestamp.'16384ms'
    validator_slotsNumber of slots available in the validator auction.100
    finality_threshold_fractionA number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.
    It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.
    Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly.
    [1, 3]
    start_protocol_version_with_strict
    _finality_signatures_required
    Protocol version from which nodes are required to hold strict finality signatures.'1.5.0'
    legacy_required_finalityThe finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'.
    Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures.
    'Strict'
    auction_delayNumber of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1.1
    locked_funds_periodThe period after genesis during which a genesis validator's bid is locked.'90days'
    vesting_schedule_periodThe period in which the genesis validator's bid is released over time after it is unlocked.'13 weeks'
    unbonding_delayDefault number of eras that need to pass to be able to withdraw unbonded funds.7
    round_seigniorage_rateRound seigniorage rate represented as a fraction of the total supply.
    - Annual issuance: 8%.
    - Minimum block time: 2^15 milliseconds.
    - Ticks per year: 31536000000.

    (1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:
    Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)
    [7, 87535408]
    max_associated_keysMaximum number of associated keys for a single account.100
    max_runtime_call_stack_heightMaximum height of the contract runtime call stack.12
    minimum_delegation_amountMinimum allowed delegation amount in motes.500_000_000_000
    prune_batch_sizeGlobal state prune batch size for tip pruning in version 1.4.15. Possible values:
    - 0 when the feature is OFF
    - Integer if the feature is ON, representing the number of eras to process per block.
    0
    strict_argument_checkingEnables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct CLType.false
    simultaneous_peer_requestsNumber of simultaneous peer requests.5
    consensus_protocolThe consensus protocol to use. Options are 'Zug' or 'Highway'.'Highway'
    max_delegators_per_validatorThe maximum amount of delegators per validator. If the value is 0, there is no maximum capacity.1200
    +

    highway

    +

    These settings configure the Highway Consensus protocol.

    + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    maximum_round_lengthHighway dynamically chooses its round length between minimum_block_time and maximum_round_length.'132seconds'
    reduced_reward_multiplierThe factor by which rewards for a round are multiplied if the greatest summit has ≤50% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet).[1, 5]
    +

    deploys

    +

    These settings manage deploys and their lifecycle.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    max_payment_costThe maximum number of motes allowed to be spent during payment. 0 means unlimited.'0'
    max_ttlThe duration after the deploy timestamp during which the deploy can be included in a block.'18hours'
    max_dependenciesThe maximum number of other deploys a deploy can depend on (requiring them to have been executed before it can execute).10
    max_block_sizeMaximum block size in bytes, including deploys contained by the block. 0 means unlimited.10_485_760
    max_deploy_sizeMaximum deploy size in bytes. Size is of the deploy when serialized via ToBytes.1_048_576
    block_max_deploy_countThe maximum number of non-transfer deploys permitted in a single block.50
    block_max_transfer_countThe maximum number of Wasm-less transfer deploys permitted in a single block.1250
    block_max_approval_countThe maximum number of approvals permitted in a single block.2600
    block_gas_limitThe upper limit of the total gas of all deploys in a block.4_000_000_000_000
    payment_args_max_lengthThe limit of length of serialized payment code arguments.1024
    session_args_max_lengthThe limit of length of serialized session code arguments.1024
    native_transfer_minimum_motesThe minimum amount in motes for a valid native transfer.2_500_000_000
    +

    wasm

    +

    The following are Wasm-related settings.

    + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    max_memoryAmount of free memory (in 64 kB pages) each contract can use for its stack.64
    max_stack_heightMax stack height (native WebAssembly stack limiter).500
    +

    wasm.storage_costs

    +

    These settings manage Wasm storage costs.

    + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    gas_per_byteGas charged per byte stored in global state.630_000
    +

    wasm.opcode_costs

    +

    The following settings manage the cost table for Wasm opcodes.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    bitBit operations multiplier.300
    addArithmetic add operations multiplier.210
    mulMul operations multiplier.240
    divDiv operations multiplier.320
    loadMemory load operation multiplier.2_500
    storeMemory store operation multiplier.4_700
    constConst store operation multiplier.110
    localLocal operations multiplier.390
    globalGlobal operations multiplier.390
    integer_comparisonInteger operations multiplier.250
    conversionConversion operations multiplier.420
    unreachableUnreachable operation multiplier.270
    nopNop operation multiplier.200
    current_memoryGet the current memory operation multiplier.290
    grow_memoryGrow memory cost per page (64 kB).240_000
    +

    wasm.opcode_costs.control_flow

    +

    These settings manage costs for control flow operations.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    blockCost for block opcode.440
    loopCost for loop opcode.440
    ifCost for if opcode.440
    elseCost for else opcode.440
    endCost for end opcode.440
    brCost for br opcode.35_000
    br_ifCost for br_if opcode.35_000
    returnCost for return opcode.440
    selectCost for select opcode.440
    callCost for call opcode.68_000
    call_indirectCost for call_indirect opcode.68_000
    dropCost for drop opcode.440
    +

    wasm.opcode_costs.control_flow.br_table

    +

    The following settings manage br_table Wasm opcodes.

    + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    costFixed cost per br_table opcode.35_000
    size_multiplierSize of target labels in the br_table opcode will be multiplied by size_multiplier.100
    +

    wasm.host_function_costs

    +

    The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in smart_contracts/contract/src/ext_ffi.rs.

    +
    - add = { cost = 5_800, arguments = [0, 0, 0, 0] }
    - add_associated_key = { cost = 9_000, arguments = [0, 0, 0] }
    - add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
    - blake2b = { cost = 200, arguments = [0, 0, 0, 0] }
    - call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] }
    - call_versioned_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 0, 0, 420, 0] }
    - create_contract_package_at_hash = { cost = 200, arguments = [0, 0] }
    - create_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }
    - create_purse = { cost = 2_500_000_000, arguments = [0, 0] }
    - disable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] }
    - get_balance = { cost = 3_800, arguments = [0, 0, 0] }
    - get_blocktime = { cost = 330, arguments = [0] }
    - get_caller = { cost = 380, arguments = [0] }
    - get_key = { cost = 2_000, arguments = [0, 440, 0, 0, 0] }
    - get_main_purse = { cost = 1_300, arguments = [0] }
    - get_named_arg = { cost = 200, arguments = [0, 0, 0, 0] }
    - get_named_arg_size = { cost = 200, arguments = [0, 0, 0] }
    - get_phase = { cost = 710, arguments = [0] }
    - get_system_contract = { cost = 1_100, arguments = [0, 0, 0] }
    - has_key = { cost = 1_500, arguments = [0, 840] }
    - is_valid_uref = { cost = 760, arguments = [0, 0] }
    - load_named_keys = { cost = 42_000, arguments = [0, 0] }
    - new_uref = { cost = 17_000, arguments = [0, 0, 590] }
    - random_bytes = { cost = 200, arguments = [0, 0] }
    - print = { cost = 20_000, arguments = [0, 4_600] }
    - provision_contract_user_group_uref = { cost = 200, arguments = [0, 0, 0, 0, 0] }
    - put_key = { cost = 38_000, arguments = [0, 1_100, 0, 0] }
    - read_host_buffer = { cost = 3_500, arguments = [0, 310, 0] }
    - read_value = { cost = 6_000, arguments = [0, 0, 0] }
    - read_value_local = { cost = 5_500, arguments = [0, 590, 0] }
    - remove_associated_key = { cost = 4_200, arguments = [0, 0] }
    - remove_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0] }
    - remove_contract_user_group_urefs = { cost = 200, arguments = [0, 0, 0, 0, 0, 0] }
    - remove_key = { cost = 61_000, arguments = [0, 3_200] }
    - ret = { cost = 23_000, arguments = [0, 420_000] }
    - revert = { cost = 500, arguments = [0] }
    - set_action_threshold = { cost = 74_000, arguments = [0, 0] }
    - transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] }
    - transfer_from_purse_to_purse = { cost = 82_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }
    - transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] }
    - update_associated_key = { cost = 4_200, arguments = [0, 0, 0] }
    - write = { cost = 14_000, arguments = [0, 0, 0, 980] }
    - write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] }
    +

    system_costs

    +

    The following settings manage protocol operating costs.

    + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    wasmless_transfer_costDefault gas cost for a wasmless transfer.100_000_000
    +

    system_costs.auction_costs

    +

    These settings manage the costs of calling the auction system contract entrypoints.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    get_era_validatorsCost of calling the get_era_validators entrypoint.10_000
    read_seigniorage_recipientsCost of calling the read_seigniorage_recipients entrypoint.10_000
    add_bidCost of calling the add_bid entrypoint.2_500_000_000
    withdraw_bidCost of calling the withdraw_bid entrypoint.2_500_000_000
    delegateCost of calling the delegate entrypoint.2_500_000_000
    undelegateCost of calling the undelegate entrypoint.2_500_000_000
    run_auctionCost of calling the run_auction entrypoint.10_000
    slashCost of calling the slash entrypoint.10_000
    distributeCost of calling the distribute entrypoint.10_000
    withdraw_delegator_rewardCost of calling the withdraw_delegator_reward entrypoint.10_000
    withdraw_validator_rewardCost of calling the withdraw_validator_reward entrypoint.10_000
    read_era_idCost of calling the read_era_id entrypoint.10_000
    activate_bidCost of calling the activate_bid entrypoint.10_000
    redelegateCost of calling the redelegate entrypoint.2_500_000_000
    +

    system_costs.mint_costs

    +

    These settings manage the costs of calling the mint system contract entrypoints.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    mintCost of calling the mint entrypoint.2_500_000_000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10_000
    createCost of calling the create entrypoint.2_500_000_000
    balanceCost of calling the balance entrypoint.10_000
    transferCost of calling the transfer entrypoint.10_000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10_000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2_500_000_000
    +

    system_costs.handle_payment_costs

    +

    These settings manage the costs of calling entrypoints on the handle_payment system contract.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    get_payment_purseCost of calling the get_payment_purse entrypoint.10_000
    set_refund_purseCost of calling the set_refund_purse entrypoint.10_000
    get_refund_purseCost of calling the get_refund_purse entrypoint.10_000
    finalize_paymentCost of calling the finalize_payment entrypoint.10_000
    +

    system_costs.standard_payment_costs

    +

    These settings manage the costs of calling entrypoints on the standard_payment system contract.

    + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10_000
    + + \ No newline at end of file diff --git a/1.5.X/operators/setup-network/create-private/index.html b/1.5.X/operators/setup-network/create-private/index.html new file mode 100644 index 000000000..6f2621595 --- /dev/null +++ b/1.5.X/operators/setup-network/create-private/index.html @@ -0,0 +1,240 @@ + + + + + +Private Network Setup | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Setting Up a Private Casper Network

    +

    Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.

    +

    Contents

    +
      +
    1. +

      Prerequisites

      +
    2. +
    3. +

      Setting up a Validator Node

      +
    4. +
    5. +

      Setting up the Directory

      +
    6. +
    7. +

      Configuring the Genesis Block

      +
    8. +
    9. +

      Configuring the Administrator Accounts

      +
    10. +
    11. +

      Starting the Casper Node

      +
    12. +
    13. +

      Testing the Private Network

      +
    14. +
    15. +

      Setting up a Block Explorer

      +
    16. +
    +

    Prerequisites

    +

    Follow these guides to set up the required environment and user accounts.

    + +

    Step 1. Setting up a Validator Node

    +

    A Casper node is a physical or virtual device participating in a Casper network. You need to set up several validator nodes on your private network. An operator who has won an auction bid will be a validator for the private network.

    +

    Use the below guides to set up and manage validator nodes.

    +
      +
    • Casper node setup - GitHub guide: A guide to configuring a system with the new Rust node to operate within a network.
    • +
    • Basic node setup tutorial: A guide on using the casper-node-launcher, generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes.
    • +
    • Set up Mainnet and Testnet validator nodes: A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes.
    • +
    +

    Use these FAQ collections for tips and details for validators.

    + +

    Step 2. Setting up the Directory

    +

    Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes.

    +
      +
    • Go through the file location section to understand how directories are created and managed in a Casper private network.
    • +
    • Refer to the setting up a new network guide to identify the required configuration files to set up a genesis block.
    • +
    +

    Step 3. Configuring the Genesis Block

    +

    A Casper private network contains a different set of configurations when compared to the public network. The chainspec.toml file contains the required configurations for the genesis process in a private network.

    +

    You should add the configuration options below to the chainspec.toml file inside the private network directory.

    +

    Unrestricted transfers configuration

    +

    This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators.

    +
    [core]
    allow_unrestricted_transfers = false
    +

    In contrast, users in the public network can freely transfer funds to different accounts.

    +
    note

    A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:

    [core]
    allow_unrestricted_transfers = false
    compute_rewards = false
    allow_auction_bids = false
    refund_handling = { type = "refund", refund_ratio = [1, 1] }
    fee_handling = { type = "accumulate" }
    administrators = ["ADMIN_PUBLIC_KEY"]
    +

    Refund handling configuration

    +

    This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user.

    +

    A refund_ratio is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the refund_ratio is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user.

    +
    [core]
    refund_handling = { type = "refund", refund_ratio = [1, 1] }
    +

    After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.

    +

    The default configuration for a public chain, including the Casper Mainet, looks like this:

    +
    [core]
    refund_handling = { type = "refund", refund_ratio = [0, 100] }
    +

    The refund variant with refund_ratio of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return.

    +

    Fee handling configuration

    +

    This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed.

    +

    Set up the configuration as below:

    +
    [core]
    fee_handling = { type = "pay_to_proposer" }
    +

    The fee_handling configuration has three variations:

    +
      +
    • pay_to_proposer: The rest of the payment amount after deducing the gas fee from a refund is paid to the block's proposer.
    • +
    • burn: The tokens paid are burned, and the total supply is reduced.
    • +
    • accumulate: The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled.
    • +
    +

    Auction behavior configuration

    +

    A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set.

    +

    Use the configuration below to limit the auction validators:

    +
    [core]
    allow_auction_bids = false
    +

    Other configurations related to the auction:

    +
      +
    • allow_auction_bids - if this option is set to false then add_bid and delegate options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an AuctionBidsDisabled error.
    • +
    • core.compute_rewards - if this option is set to false, then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids.
    • +
    +

    In a public network, allow_auction_bid is set to true, which allows bidding for new entries and validator nodes.

    +

    Step 4. Configuring the Administrator Accounts

    +

    An administrator is mandatory for a private network since it manages all the other validator accounts. There should be at least one administrator account configured within a network to operate it as a private network. You can create new administrators and rotate the validator set in a single configuration update. The operator must first ensure the global_state.toml file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances.

    +

    Configuring administrator accounts

    +

    Use this configuration option in the chainspec.toml to add administrator accounts to the private network:

    +
    [core]
    administrators = ["NEW_ACCOUNT_PUBLIC_KEY"]
    +

    Note: Regular accounts are not allowed to manage their associated keys on a private network.

    +

    Generating new administrator accounts

    +

    Use the command below to generate new administrator accounts in your private network. This generates the contents of a global_state.toml with the entries required to create new administrator accounts at the upgrade point.

    +
    global-state-update-gen \
    generate-admins --data-dir $DATA_DIR/global_state \
    --state-hash $STATE_ROOT_HASH \
    --admin $PUBLIC_KEY_HEX, $BALANCE
    +
      +
    • NEW_PUBLIC_KEY - Public key of the administrator in a hex format.
    • +
    • NEW_BALANCE - Balance for the administrator’s main purse.
    • +
    • DATA_DIR - Path to the global state directory.
    • +
    • STATE_ROOT_HASH - State root hash, taken from the latest block before an upgrade.
    • +
    +

    Managing accounts and smart contracts

    +

    Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in Casper node's private chain control management file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key.

    +

    Use this command to generate these contracts:

    +
    make build-contracts-rs
    +

    Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:

    +
      +
    • To disable a contract: Execute the disable_contract.wasm with contract_hashand contract_package_hash as parameters.
    • +
    • To enable a contract: Execute the enable_contract.wasm with contract_hashand contract_package_hash as parameters.
    • +
    • To disable an account: Execute set_action_thresholds.wasm with argument deploy_threshold:u8='255' and key_management_threshold:u8='255'.
    • +
    • To enable an account: Execute set_action_thresholds.wasm with deploy_threshold:u8='1' set to 1 and key_management_threshold:u8='0'.
    • +
    +

    Step 5. Starting the Casper Node

    +

    After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:

    +
    sudo systemctl start casper-node-launcher
    +

    Refer to the Casper node setup GitHub guide to know more details about configuring a new node to operate within a network.

    +

    Additionally, refer to the casper-node-launcher to check whether the installed node binaries match the installed configurations by comparing the version numbers.

    +

    Step 6. Rotating the Validator Accounts

    +

    You need to go through setting up a validator node guide before starting this section.

    +

    To rotate the validators set, you must perform a network upgrade using a global_state.toml with new entries generated by the global-state-update-gen command.

    +

    When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block.

    +

    After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new global_state.toml.

    +

    global-state-update-gen validators \
    --data-dir $DATA_DIR/global_state \
    --state-hash $STATE_ROOT_HASH \
    –-validator $PUBLIC_KEY_HEX,$STAKE \
    –-validator $PUBLIC_KEY_HEX,$STAKE

    +

    Each use of the --validator parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter.

    +

    After designating the next era's validators, you must set the chainspec activation point and last_emergency_restart to X, where X is equal to the new era after the switch block from above. Finally, set hard_reset = true. This makes the network revert to the end of the previous era when restarted with the upgrade.

    +

    For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run global-state-update-gen, set the activaction point and last_emergency_restart to 10 and hard_reset to true.

    +

    You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators.

    +
    note

    Please make sure you are running this tool as the same user that owns $DATA_DIR. Otherwise, you may receive a permission denied error.

    +

    You can find more details on enabling new validators in the joining a running network guide. The guide explains how to join the network and provide additional security to the system.

    +

    Step 7. Testing the Private Network

    +

    We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer.

    +

    Sample configuration files

    +

    Here are sample configurations that can be adapted for testing:

    + +

    Specifying IP addresses

    +

    Here is an example set of IP addresses in use:

    +
    http://18.224.190.213:7777
    http://18.188.11.97:7777
    http://18.188.206.170:7777
    http://18.116.201.114:7777
    +

    Setting up the node

    +

    Set up the node address, chain name, and the administrator's secret key.

    +
    export NODE_ADDR=http://18.224.190.213:7777
    export CHAIN_NAME="private-test"
    +

    This testing example will also use an alice/secret_key.pem file, a secret key generated through the keys generation process. Alice is a regular user in this testing example.

    +

    Network access control

    +

    With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed.

    +

    To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA).

    +
    [network.identity]
    tls_certificate = "local_node_cert.pem"
    secret_key = "local_node.pem"
    ca_certificate = "ca_cert.pem"
    +
      +
    • tls_certificate is the certificate signed by a ca_cert.pem.
    • +
    • secret_key refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key.
    • +
    • ca_certificate is the network CA that should be the same on each of the nodes.
    • +
    +

    To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:

    +
    # Recommended EC curve algorithm to use
    export CURVE="secp521r1"

    # Generate secret key for CA and save it to ca_key.pem
    openssl ecparam -out ca_key.pem -name $CURVE -genkey
    # Create ca_cert.pem signed by ca_key.pem
    openssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem

    # Generate secret key for a node and a certificate signed by the CA
    openssl ecparam -out node_1.pem -name $CURVE -genkey
    openssl req -new -key node_1.pem -out node_1.csr -sha256
    openssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem
    +

    And then configure the node with the following settings:

    +
    [network.identity]
    tls_certificate = "node_1_cert.pem"
    secret_key = "node_1.pem"
    ca_certificate = "ca_cert.pem"
    +

    Every node in the private chain network has to be configured with the same CA certificate, and each tls_certificate and secret_key pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:

    +
    2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority
    +

    Keep in mind that for security reasons ca_key.pem should be stored securely and never present on each of participating machines.

    +

    Funding Alice's account

    +

    The following command transfers tokens to Alice's main purse.

    +
    casper-client \
    transfer \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key admin/secret_key.pem \
    --session-account=$(<admin/public_key_hex) \
    --target-account=$(<alice/public_key_hex) \
    --amount=100000000000 \
    --payment-amount=3000000000 \
    --transfer-id=123
    +

    To check the account information, use this command:

    +
    casper-client get-account-info -n $NODE_ADDR
    --public-key alice/public_key.pem
    +

    Adding a bid as Alice

    +

    The following command attempts to add an auction bid on the network. It should return ApiError::AuctionError(AuctionBidsDisabled) [64559].

    +
    tip

    All payment amounts in these examples must be adjusted based on the network chainspec.

    +
    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key alice/secret_key.pem \
    --session-path add_bid.wasm \
    --payment-amount 5000000000 \
    --session-arg "public_key:public_key='$(<alice/public_key_hex)'" \
    --session-arg "amount:u512='10000'" \
    --session-arg "delegation_rate:u8='5'"

    # Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"
    +

    We should get a similar error for the delegate entry point.

    +

    Disabling Alice's account

    +

    The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful.

    +
    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key admin/secret_key.pem \
    --session-account=alice/public_key_hex
    --session-path set_action_thresholds.wasm \
    --payment-amount=2500000000 \
    --session-arg "key_management_threshold:u8='255'" \
    --session-arg "deploy_threshold:u8='255'"
    +

    Enabling Alice's account

    +

    The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful.

    +
    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key admin/secret_key.pem \
    --session-account=alice/public_key_hex
    --session-path set_action_thresholds.wasm \
    --payment-amount=2500000000 \
    --session-arg "key_management_threshold:u8='0'" \
    --session-arg "deploy_threshold:u8='1'"
    +

    Enabling a contract

    +

    The following command enables a contract using its hash.

    +
    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key admin/secret_key.pem \
    --session-account=$(<alice/public_key_hex) \
    --session-path enable_contract.wasm \
    --payment-amount 3000000000 \
    --session-arg "contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'" \
    --session-arg "contract_hash:account_hash='account-hash-$CONTRACT_HASH'"
    +

    Disabling a contract

    +

    The following command disables a contract using its hash. Executing this contract using CONTRACT_HASH again should fail.

    +
    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key admin/secret_key.pem \
    --session-account=$(<alice/public_key_hex) \
    --session-path disable_contract.wasm \
    --payment-amount 3000000000 \
    --session-arg "contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'" \
    --session-arg "contract_hash:account_hash='account-hash-$CONTRACT_HASH'"
    +

    Alice needs a container access key for the contract package in her named keys.

    +

    Verifying seigniorage allocations

    +

    Seigniorage allocations should be zero at each switch block. This is the related configuration:

    +
    [core]
    compute_rewards = false
    +

    Validator stakes should not increase on each switch block. Run this command to verify this:

    +
    casper-client get-era-info -n $NODE_ADDR -b 153
    +

    The total supply shouldn't increase, and the validator's stakes should remain the same.

    +

    Operating guide

    +

    Some configuration options such as allow_auction_bids require a private chain operator to perform specific tasks manually through a network upgrade with chainspec and contents of global_state.toml file generated by a provided tool global-state-update-gen.

    +

    You can find this tool by either downloading a package or by installing it manually from the sources:

    +
    $ cargo install --git https://github.com/casper-network/casper-node/ --tag private-1.4.6 global-state-update-gen
    $ global-state-update-gen --help
    Global State Update Generator 0.2.0
    Generates a global state update file based on the supplied parameters

    USAGE:
    global-state-update-gen [SUBCOMMAND]

    FLAGS:
    -h, --help Prints help information
    -V, --version Prints version information

    SUBCOMMANDS:
    balances Generates an update changing account balances
    generate-admins Generates entries to create new admin accounts on a private chain
    help Prints this message or the help of the given subcommand(s)
    system-contract-registry Generates an update creating the system contract registry
    validators Generates an update changing the validators set
    +

    The standard output of running commands listed above is the content of a global_state.toml file, which contains a list of direct global state modifications.

    +

    Example output of running a generate-admins subcommand:

    +
    [[entries]]
    key = "balance-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13"
    value = "AAIAAAABCgg="

    [[entries]]
    key = "uref-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13-007"
    value = "AAAAAAAJ"

    [[entries]]
    key = "account-hash-ac2f4caa3e3ce1cd1dfb3d089854020b18a50cac49977d0a4c873c4d3d5a2409"
    value = "AawvTKo+POHNHfs9CJhUAgsYpQysSZd9CkyHPE09WiQJAAAAAJe7zCQls+2lFJqJPGGAti8UctUUO7FFDQHI4elr4J8TBwEAAACsL0yqPjzhzR37PQiYVAILGKUMrEmXfQpMhzxNPVokCQEBAQ=="

    # total supply increases from 200000000000000000 to 200000000000000010
    [[entries]]
    key = "uref-f8475fd4125484be39a0793530f09a29d220ffda8e48387b3d2194ddfc22894e-007"
    value = "AAkAAAAICgAUu/CKxgII"
    +

    Currently, this tool outputs contents into standard output. You should redirect standard output to a file named global_state.toml and place this file in the same directory as chainspec.toml before performing a network upgrade.

    +
    $ global-state-update-gen generate-admins --data-dir $DATA_DIR --state-hash $STATE_HASH --admin NEW_PUBLIC_KEY,BALANCE >> global_state.toml
    +

    By using >> shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade.

    +

    Common options:

    +
      +
    • --data-dir path to a global state directory where data.lmdb can be found
    • +
    • --state-hash is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the global_state.toml.
    • +
    +

    Rotating validators

    +

    The following command rotates the validator set. Perform a network upgrade with a global_state.toml with the new entries generated by the global-state-update-gen command.

    +
    global-state-update-gen validators \
    --data-dir $DATA_DIR \
    --state-hash $STATE_ROOT_HASH \
    --validator NEW_PUBLIC_KEY,NEW_STAKE \
    --validator NEW_PUBLIC_KEY2,NEW_STAKE2
    +

    Adding new administrators

    +

    The following command produces the administrator content in the global_state.toml file.

    +
    global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH
    +

    Remember that new administrators can be created, and the validator set can also be rotated in a single update.

    +

    The chainspec.toml file should contain the following entries that include new administrators as well as existing ones for an upgrade:

    +
    [core]
    administrators = ["NEW_PUBLIC_KEY"]
    +

    After this step, the private network would be ready for use.

    +

    Setting up a Block Explorer

    +

    Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer here.

    + + \ No newline at end of file diff --git a/1.5.X/operators/setup-network/genesis/index.html b/1.5.X/operators/setup-network/genesis/index.html new file mode 100644 index 000000000..54ffcb65f --- /dev/null +++ b/1.5.X/operators/setup-network/genesis/index.html @@ -0,0 +1,32 @@ + + + + + +Genesis | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    The Genesis Block

    +

    The Casper node software creates a genesis block from the following input files:

    +
      +
    • chainspec.toml
    • +
    • accounts.toml
    • +
    +

    chainspec.toml

    +

    A version of the chainspec is downloaded by the pull_casper_node_version.sh script installed with the casper-node-launcher debian package. This script pulls the chainspec.toml file from the appropriate path defined in the network config file used (casper.conf for MainNet and casper-test.conf for TestNet).

    +

    The production version of the file from which this is based on can be found at casper-node/resources/production/chainspec.toml in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to this page for detailed documentation on each of the variables in the file.

    +

    accounts.toml

    +

    This file contains the genesis validator set information, starting accounts and associated balances and bond amounts.

    +

    If an account is not bonded at genesis, specify a 0 for the bond amount.

    +

    Similar to the chainspec.toml, this is pulled from the appropriate path defined in the network config file used.

    + + \ No newline at end of file diff --git a/1.5.X/operators/setup-network/index.html b/1.5.X/operators/setup-network/index.html new file mode 100644 index 000000000..ce2c73b93 --- /dev/null +++ b/1.5.X/operators/setup-network/index.html @@ -0,0 +1,47 @@ + + + + + +Setting up Private Networks | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Setting up Private Networks

    +

    Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    The Genesis BlockFiles needed to create a genesis block
    The Chain SpecificationConfiguration settings describing the network state
    Setting up a Private Casper NetworkA step-by-step guide to establishing and configuring a private Casper network
    Staging Files for a New NetworkA guide to hosting protocol files for a new Casper network
    + + \ No newline at end of file diff --git a/next/operators/setup-network/staging-files-for-new-network/index.html b/1.5.X/operators/setup-network/staging-files-for-new-network/index.html similarity index 64% rename from next/operators/setup-network/staging-files-for-new-network/index.html rename to 1.5.X/operators/setup-network/staging-files-for-new-network/index.html index d361a964b..7f4dba633 100644 --- a/next/operators/setup-network/staging-files-for-new-network/index.html +++ b/1.5.X/operators/setup-network/staging-files-for-new-network/index.html @@ -1,21 +1,21 @@ - + -Staging Files | Casper Docs - Redux +Staging Files | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Staging Files for a New Network

    + submit an issue on Github
    Version: 1.5.X

    Staging Files for a New Network

    important

    Staging files is not needed for already established running networks.

    Only use these instructions if you are creating a new Casper network and hosting protocol files for this network.

    Hosting Server

    Files for staging protocol versions are hosted on a typical HTTP(S) server.

    @@ -76,7 +76,7 @@

    N

    Setup Configuration Files

    For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time.

    chainspec.toml

    -

    The chainspec.toml file is configuration for the network and must be exactly the same on all nodes.

    +

    The chainspec.toml file is configuration for the network and must be exactly the same on all nodes.

    The name for a network is specified network.name.

    Each protocol will have a version and activation_point. At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the era_id for activation of the upgrade.

    [protocol]
    version = '1.0.0'
    activation_point = '2022-08-01T10:00:00Z'

    [network]
    name = 'mynetwork'
    @@ -100,6 +100,6 @@

    S

    We will copy bin.tar.gz and config.tar.gz into 1_1_0. Once this is done, we are safe to update protocol_versions by appending 1_1_0 to the end of the file and uploading it into the root of the network directory.

    Any node that runs the following command will get this new upgrade:

    -
    sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>
    \ No newline at end of file diff --git a/1.5.X/operators/setup/basic-node-configuration/index.html b/1.5.X/operators/setup/basic-node-configuration/index.html new file mode 100644 index 000000000..61f84b263 --- /dev/null +++ b/1.5.X/operators/setup/basic-node-configuration/index.html @@ -0,0 +1,160 @@ + + + + + +Configuration | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Basic Node Configuration

    +

    This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.

    +

    The Casper Node Launcher

    +

    A node is usually run by executing the casper-node-launcher, which executes the casper-node as a child process and also handles upgrades to bring the node to the latest version released.

    +

    The casper-node-launcher can be installed via a Debian package, which also creates the casper user and directory structures and sets up a systemd unit and logging.

    +

    The casper-node-launcher Debian package can be obtained from https://repo.casperlabs.io. You only need to run the steps detailed there once.

    +

    Then, proceed to install the casper-node-launcher by running these commands:

    +
    sudo apt update
    sudo apt install casper-node-launcher
    +

    You can also build from source. However, all the setup and pull of casper-node releases will be manual.

    +

    File Locations

    +

    The casper-node-launcher Debian installation creates the directories and files needed to run casper-node versions and perform upgrades. A casper user and casper group are created during installation and used to run the software. Two main folders are relevant for our software: /etc/casper and /var/lib/casper.

    +

    The casper-node install version

    +

    Each version of the casper-node install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named 1_0_3. This convention applies to both binary and configuration file locations. Versioning with [m_n_p] represents the major, minor, and patch of a semantic version.

    +
    note

    Multiple versioned folders will exist on a system when upgrades are set up.

    +

    The following is the filesystem's state after installing the casper-client and casper-node-launcher Debian packages, and after running the command sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf (Use casper-test.conf if on Testnet).

    +

    /usr/bin/

    +

    The default location for executables from the Debian package install is /usr/bin.

    +
      +
    • casper-client - A client for interacting with a Casper network
    • +
    • casper-node-launcher - The launcher application which starts the casper-node as a child process
    • +
    +

    /etc/casper/

    +

    This is the default location for configuration files. It can be overwritten with the CASPER_CONFIG_DIR environment variable. The paths in this document assume the default configuration file location of /etc/casper. The data is organized as follows:

    +
      +
    • delete_local_db.sh - Removes *.lmdb* files from /var/lib/casper/casper-node
    • +
    • pull_casper_node_version.sh - Pulls bin.tar.gz and config.tar.gz from genesis.casperlabs.io for a specified protocol version and extracts them into /var/lib/bin/<protocol_version> and /etc/casper/<protocol_version>
    • +
    • config_from_example.sh - Gets external IP to replace and create the config.toml from config-example.toml
    • +
    • node_util.py - A script that will be replacing other scripts and is the preferred method of performing the actions of pull_casper_node_version.sh, config_from_example.sh, and delete_local_db.sh. Other scripts will be deprecated in future releases of casper-node-launcher.
    • +
    • casper-node-launcher-state.toml - The local state for the casper-node-launcher which is created during the first run
    • +
    • validator_keys/ - The default folder for node keys, containing: +
        +
      • README.md - Instructions on how to create validator keys using the casper-client
      • +
      • secret_key.pem - Secret key used by the validator node to sign blocks and peer-to-peer messages
      • +
      • public_key.pem - Public key associated with the secret key above, stored in PEM format
      • +
      • public_key_hex - Public key associated with the secret key above, stored in hex format
      • +
      +
    • +
    • 1_0_0/ - Folder for genesis configuration files, containing: +
        +
      • accounts.toml - Contains the genesis validators and delegators
      • +
      • chainspec.toml - Contains invariant network settings, with the activation_point (network start time) as a timestamp
      • +
      • config-example.toml - Example for creating a config.toml file
      • +
      • config.toml - Contains variable node configuration settings, created by a node operator manually or by running config_from_example.sh 1_0_0
      • +
      +
    • +
    • m_n_p/ - Folder for each installed upgrade package's configuration files, containing: +
        +
      • chainspec.toml - Contains invariant network settings, with the activation_point as an era ID (the era at which this protocol version of the node became or will become active)
      • +
      • config-example.toml - As per 1_0_0/config-example.toml, but compatible with the m.n.p version of the node
      • +
      • config.toml - As per 1_0_0/config.toml, but compatible with the m.n.p version of the node
      • +
      +
    • +
    +

    /var/lib/casper/

    +

    This is the location for larger and variable data for the casper-node, organized in the following folders and files:

    +
      +
    • +

      bin/ - The parent folder storing the versions of casper-node executables. This location can be overwritten with the CASPER_BIN_DIR environment variable. The paths in this document assume the default of /var/lib/casper/bin/.

      +
        +
      • 1_0_0/ - Folder for genesis binary files, containing: +
          +
        • casper-node - The node executable - defaults to the Ubuntu 20.04 compatible binary
        • +
        • README.md - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms
        • +
        +
      • +
      • m_n_p/ - Folder for each installed upgrade package, containing: +
          +
        • casper-node - As per 1_0_0/casper-node, but the m.n.p version of the node
        • +
        • README.md - As per 1_0_0/README.md, but compatible with the m.n.p version of the node
        • +
        +
      • +
      +
    • +
    • +

      casper-node/<NETWORK NAME> - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is casper and for Testnet it is casper-test.

      +
        +
      • data.lmdb - Persistent global state store of the network
      • +
      • data.lmbd-lock - Lockfile for the data.lmdb database
      • +
      • storage.lmdb - Persistent store of all other network data, primarily Blocks and Deploys
      • +
      • storage.lmdb-lock - Lockfile for the storage.lmdb database
      • +
      • unit_files/ - Folder containing transient caches of consensus information
      • +
      +
    • +
    +

    Node Version Installation

    +

    Included with the casper-node-launcher is node_util.py for installing casper-node versions. This command will stage all current casper-node versions:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>
    +

    For <NETWORK_CONFIG>, we use casper.conf for Mainnet and casper-test.conf for Testnet. This will install all currently released protocols in one step.

    +

    This command will do the following:

    +
      +
    • Create /var/lib/casper/bin/1_0_2/ and expand the bin.tar.gz containing at a minimum casper-node
    • +
    • Create /etc/casper/1_0_2/ and expand the config.tar.gz containing chainspec.toml, config-example.toml, and possibly accounts.csv and other files
    • +
    • Remove the archive files and run /etc/casper/config_from_example.sh 1_0_2 to create a config.toml from the config-example.toml
    • +
    +

    Release versions are invoked using the underscore format, such as:

    +
    sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2
    +

    The Node Configuration File

    +

    One config.toml file exists for each casper-node version installed. It is located in the /etc/casper/[m_n_p]/ directory, where m_n_p is the current semantic version. This can be created from the config-example.toml by using /etc/casper/config_from_example.sh [m_n_p] where [m_n_p] is replaced with the current version, using underscores.

    +

    Below are some fields in the config.toml that you may need to adjust.

    +

    The Trusted Hash for Synchronizing

    +

    Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator.

    +

    When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:

    +
      +
    • Find a list of trusted validators
    • +
    • Query the status endpoint of a trusted validator (http://<NODE_IP_ADDRESS>:8888/status)
    • +
    • Obtain the hash of a block from the status endpoint
    • +
    • Update the config.toml for the node to include the trusted hash. There is a field dedicated to this near the top of the file
    • +
    +

    Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network.

    +
    sudo sed -i "/trusted_hash =/c\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\n')'" /etc/casper/1_0_0/config.toml
    +

    Known Addresses

    +

    For the node to connect to a network, the node needs a set of trusted peers for that network. For Mainnet, these are listed in the config.toml as known_addresses. For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an example configuration. The casper-protocol-release repository stores configurations for various environments, which you can also use as examples.

    +

    Updating the config.toml file

    +

    At the top of a config.toml file as shown here, enter the trusted block hash to replace the 'HEX-FORMATTED BLOCK HASH' and uncomment the line by deleting the leading '#'. See the Configuration File for more details.

    +
    # ================================
    # Configuration options for a node
    # ================================
    [node]

    # If set, use this hash as a trust anchor when joining an existing network.
    #trusted_hash = 'HEX-FORMATTED BLOCK HASH'
    +

    Secret Keys

    +

    Provide the path to the secret keys for the node. This path is set to etc/casper/validator_keys/ by default. See Creating Keys and Funding Accounts for more details.

    +

    Networking and Gossiping

    +

    The node requires a publicly accessible IP address. The config_from_example.sh and node_util.py both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the config_from_example.sh external services are called to find your IP and this is inserted into the config.toml created.

    +

    The following default values are specified in the file if you want to change them:

    +
      +
    • The port that will be used for status and deploys
    • +
    • The port used for networking
    • +
    • Known_addresses - these are the bootstrap nodes (there is no need to change these)
    • +
    +

    Enabling Speculative Execution

    +

    The speculative_exec endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, speculative_exec is disabled on a node.

    +

    speculative_exec can be enabled within config.toml by changing enable_server to true under the configuration options for the speculative execution JSON-RPC HTTP server.

    +

    Node operators may also change the incoming request port for speculative execution, which defaults to 7778. Further, you can choose to alter the qps_limit and max_body_bytes, which limit the amount and size of requests to the speculative execution server.

    +

    Example Config.toml configuration with speculative execution enabled

    +
    # ========================================================================
    # Configuration options for the speculative execution JSON-RPC HTTP server
    # ========================================================================
    [speculative_exec_server]

    # Flag which enables the speculative execution JSON-RPC HTTP server.
    enable_server = true

    # Listening address for speculative execution JSON-RPC HTTP server. If the port
    # is set to 0, a random port will be used.
    #
    # If the specified port cannot be bound to, a random port will be tried instead.
    # If binding fails, the speculative execution JSON-RPC HTTP server will not run,
    # but the node will be otherwise unaffected.
    #
    # The actual bound address will be reported via a log line if logging is enabled.
    address = '0.0.0.0:7778'

    # The global max rate of requests (per second) before they are limited.
    # Request will be delayed to the next 1 second bucket once limited.
    qps_limit = 1

    # Maximum number of bytes to accept in a single request body.
    max_body_bytes = 2_621_440

    # Specifies which origin will be reported as allowed by speculative execution server.
    #
    # If left empty, CORS will be disabled.
    # If set to '*', any origin is allowed.
    # Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).
    cors_origin = ''

    +

    Rust Client Installation

    +

    The Prerequisites page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network.

    +

    Creating Keys and Funding Accounts

    +

    The following command will create keys in the /etc/casper/validator_keys folder.

    +
    sudo -u casper casper-client keygen /etc/casper/validator_keys
    +

    To learn about other options for generating keys, see Accounts and Cryptographic Keys or run the Rust client keygen command with the --help option.

    +
    sudo -u casper casper-client keygen --help
    +

    More about keys and key generation can also be found in /etc/casper/validator_keys/README.md if the casper-node-launcher was installed from the Debian package.

    +
    note

    Save your keys in a secure location, preferably offline.

    +

    To submit a bonding request, you will need to fund your account as well.

    + + \ No newline at end of file diff --git a/1.5.X/operators/setup/fast-sync/index.html b/1.5.X/operators/setup/fast-sync/index.html new file mode 100644 index 000000000..7e0fa29c1 --- /dev/null +++ b/1.5.X/operators/setup/fast-sync/index.html @@ -0,0 +1,26 @@ + + + + + +Fast Sync | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Introducing Fast Sync

    +

    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.

    +

    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 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, 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.

    + + \ No newline at end of file diff --git a/1.5.X/operators/setup/hardware/index.html b/1.5.X/operators/setup/hardware/index.html new file mode 100644 index 000000000..cfd7e33ef --- /dev/null +++ b/1.5.X/operators/setup/hardware/index.html @@ -0,0 +1,40 @@ + + + + + +Hardware | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Recommended Hardware Specifications

    +

    System Requirements

    +

    The following hardware specifications are recommended for the Casper Mainnet and Testnet:

    +
      +
    • 4 Cores
    • +
    • 32 GB Ram
    • +
    • 2 TB SSD or network SSD backed disk
    • +
    • Linux machine running Ubuntu 20.04
    • +
    +
    Notes
      +
    • +

      SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network.

      +
    • +
    • +

      For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this.

      +
    • +
    +

    CPU Requirements

    +

    Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions.

    +

    To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture.

    +
    note

    This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question.

    + + \ No newline at end of file diff --git a/1.5.X/operators/setup/index.html b/1.5.X/operators/setup/index.html new file mode 100644 index 000000000..a12c0f7bb --- /dev/null +++ b/1.5.X/operators/setup/index.html @@ -0,0 +1,63 @@ + + + + + +Setting up a Node | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Setting up a Node

    +

    The prerequisite for becoming a validator is to set up a node and join a network as described here.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Recommended Hardware SpecificationsSystem requirements for the Casper Mainnet and Testnet
    Basic Node ConfigurationProcesses and files involved in setting up a Casper node
    Node EndpointsPorts for communicating with other nodes and dApps
    Installing a NodeStep-by-step instructions to install a Casper node
    Setting the Open Files LimitRequired setting for the Casper node to run correctly
    Upgrading the NodeBefore joining the network, the node needs to be upgraded
    Joining a Running NetworkSteps to join an existing Casper network
    Setting up a Non-Root UserLogging into the node remotely using a key
    + + \ No newline at end of file diff --git a/next/operators/setup/install-node/index.html b/1.5.X/operators/setup/install-node/index.html similarity index 69% rename from next/operators/setup/install-node/index.html rename to 1.5.X/operators/setup/install-node/index.html index 5ed93bced..d0687e8d1 100644 --- a/next/operators/setup/install-node/index.html +++ b/1.5.X/operators/setup/install-node/index.html @@ -1,21 +1,21 @@ - + -Installation | Casper Docs - Redux +Installation | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Installing a Node

    + submit an issue on Github
    Version: 1.5.X

    Installing a Node

    Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.

    Network Requirements

    The following ports are used by the node:

    @@ -25,7 +25,7 @@

    Network
  • 8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)
  • 9999 SSE endpoint for event stream
  • -

    Of these 35000 is the only port required to be open for your node to function, however, opening 8888 will allow others to know general network health. For more details, see the additional information on Node Endpoints.

    +

    Of these 35000 is the only port required to be open for your node to function, however, opening 8888 will allow others to know general network health. For more details, see the additional information on Node Endpoints.

    Operating System Requirements

    The recommended OS version is Ubuntu 20.04.

    Using Ubuntu 22.04

    @@ -35,7 +35,7 @@

    Using Ubun

    This message is due to the default openssl moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:

    curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb
    sudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb

    Required Number of Open Files

    -

    Before beginning, update the maximum open files limit for your system. Specifically, update the node's /etc/security/limits.conf file as described here, to ensure proper node operation.

    +

    Before beginning, update the maximum open files limit for your system. Specifically, update the node's /etc/security/limits.conf file as described here, to ensure proper node operation.

    Required Clean Up

    If you were running a previous node on this box, this will clean up state. If packages are not installed, the apt remove may give errors, but this is not a problem.

    sudo systemctl stop casper-node-launcher.service
    sudo apt remove -y casper-client
    sudo apt remove -y casper-node
    sudo apt remove -y casper-node-launcher
    sudo rm /etc/casper/casper-node-launcher-state.toml
    sudo rm -rf /etc/casper/1_*
    sudo rm -rf /var/lib/casper/*
    @@ -59,9 +59,9 @@

    Ins

    Validator Keys

    If you do not have keys yet, you can create them using the following command:

    sudo -u casper casper-client keygen /etc/casper/validator_keys
    -

    For more details, see the Node Setup page.

    +

    For more details, see the Node Setup page.

    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. Find out more about Fast Sync.

    +

    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.

    Node Address

    NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes

    You can find active peers at https://cspr.live/tools/peers or use the following Casper Labs public nodes:

    @@ -104,6 +104,6 @@

    A Note on Speculative Execution

    The speculative_exec_server defaults to off and can be enabled in your Config.toml file.

    -

    While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You should not use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic.

    +

    While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You should not use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic.

    \ No newline at end of file diff --git a/next/operators/setup/joining/index.html b/1.5.X/operators/setup/joining/index.html similarity index 52% rename from next/operators/setup/joining/index.html rename to 1.5.X/operators/setup/joining/index.html index 94417a6a0..bfffa37e4 100644 --- a/next/operators/setup/joining/index.html +++ b/1.5.X/operators/setup/joining/index.html @@ -1,26 +1,26 @@ - + -Join a Network | Casper Docs - Redux +Join a Network | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Joining a Running Network

    + submit an issue on Github
    Version: 1.5.X

    Joining a Running Network

    Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.

    Step 1: Provisioning Hardware

    -

    Visit the Hardware Specifications section and provision your node hardware.

    +

    Visit the Hardware Specifications section and provision your node hardware.

    Step 2: Setting Up the Node

    -

    Follow the instructions on the Node Setup page.

    +

    Follow the instructions on the Node Setup page.

    Step 3: Building the Required Contracts

    Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding.

      @@ -31,7 +31,7 @@

      Step
    1. Install these prerequisites, which are also listed here.
      -
    • Rust
    • +
    • Rust
    • CMake
    • pkg-config - On Ubuntu, use sudo apt-get install pkg-config
    • openssl - On Ubuntu, use sudo apt-get install openssl
    • @@ -39,10 +39,10 @@

      Step

    1. -

      Install the Rust casper-client and fund the keys you will use for bonding.

      +

      Install the Rust casper-client and fund the keys you will use for bonding.

    2. -

      Use the following commands to build the contracts in release mode. Make sure you have installed Rust.

      +

      Use the following commands to build the contracts in release mode. Make sure you have installed Rust.

    cd casper-node
    make setup-rs
    make build-client-contracts
    @@ -55,10 +55,10 @@

    Step
  • withdraw_bid.wasm - Enables unbonding for validator stake
  • Step 4: Creating and Fund Keys for Bonding

    -

    See the Node Setup instructions if you have not generated and funded your validator keys.

    +

    See the Node Setup instructions if you have not generated and funded your validator keys.

    Step 5: Updating the Trusted Hash

    The node's config.toml needs to be updated with a recent trusted hash.

    -

    See the Trusted Hash for Synchronizing instructions if you have not set up a trusted hash during node installation.

    +

    See the Trusted Hash for Synchronizing instructions if you have not set up a trusted hash during node installation.

    Step 6: Starting the Node

    Start the node with the casper-node-launcher:

    sudo systemctl start casper-node-launcher
    @@ -72,7 +72,7 @@

    {
    "api_version": "1.4.3",
    "chainspec_name": "casper-test",
    "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",
    "peers": [
    {
    "node_id": "tls:0097..b253",
    "address": "18.163.249.168:35000"
    },
    ...
    ...
    ...
    {
    "node_id": "tls:ff95..c014",
    "address": "93.186.201.14:35000"
    }
    ],
    "last_added_block_info": {
    "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",
    "timestamp": "2022-01-04T15:33:08.224Z",
    "era_id": 3240,
    "height": 430162,
    "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",
    "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"
    },
    "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",
    "round_length": null,
    "next_upgrade": null,
    "build_version": "1.4.3-a44bed1fd-casper-mainnet",
    "uptime": "25days 1h 48m 22s 47ms"
    }

    Step 8: Sending the Bonding Request

    -

    You can submit a bonding request to change your synchronized node to a validating node.

    -

    The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures.

    +

    You can submit a bonding request to change your synchronized node to a validating node.

    +

    The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures.

    \ No newline at end of file diff --git a/next/operators/setup/node-endpoints/index.html b/1.5.X/operators/setup/node-endpoints/index.html similarity index 63% rename from next/operators/setup/node-endpoints/index.html rename to 1.5.X/operators/setup/node-endpoints/index.html index a95c55e33..811d03255 100644 --- a/next/operators/setup/node-endpoints/index.html +++ b/1.5.X/operators/setup/node-endpoints/index.html @@ -1,22 +1,22 @@ - + -Endpoints | Casper Docs - Redux +Endpoints | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Node Endpoints

    -

    As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.

    + submit an issue on Github
    Version: 1.5.X

    Node Endpoints

    +

    As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.

    This document describes in more detail a Casper node's default endpoints:

    -

    Node operators can modify a node's configuration options, including the port settings, by updating the node's config.toml file. An example configuration file can be found here.

    +

    Node operators can modify a node's configuration options, including the port settings, by updating the node's config.toml file. An example configuration file can be found here.

    The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up.

    Default Networking Port: 35000

    The configuration options for networking are under the network section of the config.toml file. The bind_address using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the config.toml file, the setting is:

    @@ -33,12 +33,12 @@

    Default Networking Por

    Default JSON-RPC HTTP Server Port: 7777

    The configuration options for the JSON-RPC HTTP server are under the rpc_server section in the config.toml file. The address using port 7777 is the listening address for JSON-RPC HTTP server.

    address = '0.0.0.0:7777'
    -

    DApps would use this address to interact with the Casper JSON-RPC API. Users would use this address to interact with the network using CLI. Validators would use this address to bond or unbond. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected.

    +

    DApps would use this address to interact with the Casper JSON-RPC API. Users would use this address to interact with the network using CLI. Validators would use this address to bond or unbond. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected.

    Default REST HTTP Server Port: 8888

    The configuration options for the JSON-RPC HTTP server are under the rest_server section in the config.toml file. The address listing port 8888 is the listening address for the REST HTTP server.

    address = '0.0.0.0:8888'

    Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected.

    -

    One may use this port to get a trusted hash, verify successful staging during an upgrade, or to confirm that the node is synchronized.

    +

    One may use this port to get a trusted hash, verify successful staging during an upgrade, or to confirm that the node is synchronized.

    Example usage

    For general health metrics, use this command:

    curl -s http://<node_address>:8888/metrics
    @@ -80,30 +80,30 @@

    Example usage<

    Default SSE HTTP Event Stream Server Port: 9999

    The configuration options for the SSE HTTP event stream server are listed under the event_stream_server section of the config.toml file. The address listing port 9999 is the listening address for the SSE HTTP event stream server.

    address = '0.0.0.0:9999'
    -

    If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see Monitoring and Consuming Events.

    +

    If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see Monitoring and Consuming Events.

    Setting up Firewall Rules

    To limit inbound traffic to the node’s endpoints, you can set firewall rules similar to the ufw commands below:

    sudo apt install ufw -y
    sudo ufw disable
    sudo ufw reset
    sudo ufw default allow outgoing
    sudo ufw default deny incoming
    sudo ufw limit ssh
    sudo ufw limit 7777/tcp
    sudo ufw limit 8888/tcp
    sudo ufw limit 35000/tcp
    sudo ufw enable

    These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication.

    If you have any concerns, questions, or issues, please submit a request to the Casper support team.

    Restricting Access for Private Networks

    -

    Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described here.

    +

    Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described here.

    Here is a summary of the links mentioned on this page:

    +
    \ No newline at end of file diff --git a/1.5.X/operators/setup/non-root-user/index.html b/1.5.X/operators/setup/non-root-user/index.html new file mode 100644 index 000000000..c5274ae07 --- /dev/null +++ b/1.5.X/operators/setup/non-root-user/index.html @@ -0,0 +1,57 @@ + + + + + +Non-Root Users | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Setting up a Non-Root User

    +

    Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace <username> in the instructions below with your username.

    +
      +
    1. +

      Use ssh-keygen to generate a new SSH key.

      +
    2. +
    3. +

      Create the user with no password, as the key is your password.

      +
    4. +
    +
    sudo adduser <username> --disabled-password
    +
      +
    1. Create authorized_keys with your key to log in.
    2. +
    +
    sudo su - <username>
    mkdir .ssh
    chmod 700 .ssh
    touch .ssh/authorized_keys
    +
      +
    1. +

      Use the editor of your choice and paste your .ssh public key i the .ssh/authorized_keys file.

      +
    2. +
    3. +

      Exit out of the <username> account and log into the root or previous sudo-er account.

      +
    4. +
    +
    exit
    +
      +
    1. Add your user to sudo-ers under the root account or your previous sudo-er account.
    2. +
    +
    sudo visudo
    +
      +
    1. Type <username> ALL=(ALL:ALL) NOPASSWD:ALL below the row containing root ALL=(ALL:ALL) ALL.
    2. +
    +
    # User privilege specification
    root ALL=(ALL:ALL) ALL
    <username> ALL=(ALL:ALL) NOPASSWD:ALL
    +
      +
    1. You should be able to log in with the key and not use the root user.
    2. +
    +
    ssh -i <your ssh private key> <username>@<server ip>
    +

    Here is an example command:

    +
    ssh -i ~/.ssh/id_rsa casper@10.21.10.200
    + + \ No newline at end of file diff --git a/next/operators/setup/open-files/index.html b/1.5.X/operators/setup/open-files/index.html similarity index 58% rename from next/operators/setup/open-files/index.html rename to 1.5.X/operators/setup/open-files/index.html index 7aec22f7f..8510ca389 100644 --- a/next/operators/setup/open-files/index.html +++ b/1.5.X/operators/setup/open-files/index.html @@ -1,21 +1,21 @@ - + -Open Files Limit | Casper Docs - Redux +Open Files Limit | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Setting the Open Files Limit

    + submit an issue on Github
    Version: 1.5.X

    Setting the Open Files Limit

    When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.

    The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default nofile limit needs to be increased.

    With the casper-node-launcher running, you can see what the system allocated by finding the process ID (PID) for the casper-node with the following command.

    @@ -52,6 +52,6 @@

    Updatin

    It is possible to persist the nofile limit across server reboots, casper-node-launcher restarts, and protocol upgrades, by adding the nofile setting for the casper user in /etc/security/limits.conf.

    Add the following row to the bottom of the /etc/security/limits.conf file:

    casper          hard    nofile          64000
    -

    Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct nofile setting.

    +

    Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct nofile setting.

    \ No newline at end of file diff --git a/1.5.X/operators/setup/upgrade/index.html b/1.5.X/operators/setup/upgrade/index.html new file mode 100644 index 000000000..87d07bf71 --- /dev/null +++ b/1.5.X/operators/setup/upgrade/index.html @@ -0,0 +1,40 @@ + + + + + +Upgrades | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Upgrading the Node

    +

    The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.

    +
    [protocol]
    # This protocol version becomes active at the start of this era.
    activation_point = 100
    +

    At every block finalization, the casper-node looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the chainspec.toml file. This will be the era before where the current casper-node will cleanly shut down.

    +

    The casper-node-launcher will detect a clean exit 0 condition and start the next version of the casper-node.

    +

    Upgrading Protocol Versions

    +

    All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of casper-node immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point.

    +

    Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point.

    +

    Upgrade Staging Instructions

    +

    The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf
    +

    On Testnet, use casper-test.conf:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf
    +

    Note: To only view the list of staged and unstaged protocols, use this command: sudo -u casper /etc/casper/node_util.py check_protocols casper.conf

    +

    Verifying Successful Staging

    +

    After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:

    +
    curl -s http://127.0.0.1:8888/status | jq .next_upgrade
    +

    You should expect this output if properly staged, prior to upgrading:

    +
    $ curl -s localhost:8888/status | jq .next_upgrade
    {
    "activation_point": 4968,
    "protocol_version": "1.4.6"
    }
    +

    If you see null after waiting for a few minutes, then your upgrade staging was not executed successfully.

    +

    Note: The protocol version will change as per the next upgrade available.

    + + \ No newline at end of file diff --git a/next/resources/advanced/list-auth-keys-tutorial/index.html b/1.5.X/resources/advanced/list-auth-keys-tutorial/index.html similarity index 91% rename from next/resources/advanced/list-auth-keys-tutorial/index.html rename to 1.5.X/resources/advanced/list-auth-keys-tutorial/index.html index 1d59603a2..0a297b87e 100644 --- a/next/resources/advanced/list-auth-keys-tutorial/index.html +++ b/1.5.X/resources/advanced/list-auth-keys-tutorial/index.html @@ -1,37 +1,37 @@ - + -Authorization Keys | Casper Docs - Redux +Authorization Keys | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Working with Authorization Keys

    + submit an issue on Github
    Version: 1.5.X

    Working with Authorization Keys

    caution

    These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.

    This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the list_authorization_keys function.

    let authorization_keys = runtime::list_authorization_keys();
    -

    Remember that authorization keys are listed under a Deploy's approvals section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:

    +

    Remember that authorization keys are listed under a Deploy's approvals section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:

    "approvals": [
    {
    "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",
    "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"
    }
    ]

    The contract code in this example retrieves the set of authorization keys for a given deploy by calling the runtime::list_authorization_keys function. In other words, list_authorization_keys returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection.

    Prerequisites

    @@ -57,7 +57,7 @@

    The exa
    let authorization_keys_caller: Vec<AccountHash> =
    runtime::list_authorization_keys().iter().cloned().collect();

    Client Wasm files

    add_keys.wasm

    -

    This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the Two-Party Multi-Signature tutorial.

    +

    This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the Two-Party Multi-Signature tutorial.

    contract_call.wasm

    This session code calls the contract's entry point, which returns the intersection between two sets of keys:

      @@ -233,6 +233,6 @@

      final test in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (account_addr_1, account_addr_2) and the installer deploy's authorization keys (DEFAULT_ACCOUNT_ADDR), the entry point returns an error.

      -
       let session_code = PathBuf::from(CONTRACT_CALL_WASM);

      let session_args = runtime_args! {
      ARG_CONTRACT_HASH => Key::from(contract_hash),
      ARG_KEY_NAME => INTERSECTION_RECEIPT
      };

      // account_addr_2 as an associated key is not among the default account's associated keys
      // The deploy will therefore revert with PermissionDenied
      let entry_point_deploy_item = DeployItemBuilder::new()
      .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
      .with_authorization_keys(&[account_addr_1, account_addr_2])
      .with_address(account_addr_1)
      .with_session_code(session_code, session_args)
      .build();

      let entry_point_request =
      ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

      builder.exec(entry_point_request).commit().expect_failure();

      let error = builder.get_error().expect("must have User error: 0");
      assert_expected_error(
      error,
      0,
      "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",
      );

    +
     let session_code = PathBuf::from(CONTRACT_CALL_WASM);

    let session_args = runtime_args! {
    ARG_CONTRACT_HASH => Key::from(contract_hash),
    ARG_KEY_NAME => INTERSECTION_RECEIPT
    };

    // account_addr_2 as an associated key is not among the default account's associated keys
    // The deploy will therefore revert with PermissionDenied
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1, account_addr_2])
    .with_address(account_addr_1)
    .with_session_code(session_code, session_args)
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).commit().expect_failure();

    let error = builder.get_error().expect("must have User error: 0");
    assert_expected_error(
    error,
    0,
    "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",
    );
    \ No newline at end of file diff --git a/1.5.X/resources/advanced/multi-sig/index.html b/1.5.X/resources/advanced/multi-sig/index.html new file mode 100644 index 000000000..4ac4580b0 --- /dev/null +++ b/1.5.X/resources/advanced/multi-sig/index.html @@ -0,0 +1,22 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    The Native Multi-Signature Feature

    +

    In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.

    +

    The additional examples present use cases where Casper's multi-signature feature would be helpful.

    + + \ No newline at end of file diff --git a/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/index.html b/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/index.html new file mode 100644 index 000000000..0e18d65cc --- /dev/null +++ b/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/index.html @@ -0,0 +1,330 @@ + + + + + +Multi-Sig Workflow | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Multi-Signature Workflow

    +

    The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.

    +
    warning

    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.

    +

    Prerequisites

    +

    The following prerequisites are required for this workflow:

    +
      +
    1. Set up all the development environment prerequisites, including a funded account and the Casper CLI client
    2. +
    3. Complete the Two-Party Multi-Signature Deploys workflow and set up the source account for multi-signature deploys
    4. +
    5. Understand the Casper account-based model before proceeding
    6. +
    +

    Session Code Required for Key Management

    +

    To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case.

    +
    caution

    Do not run these examples on Mainnet. Update each command for your environment.

    +

    Tutorial Workflow

    +

    Step 1: Clone the example Wasm for this workflow

    +

    The multi-sig GitHub repository contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder.

    +
    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:

    +
    rustup update
    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.

    +

    Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client.

    +
    casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>
    +

    Update the weight of the primary key to 3 by calling the update_associated_keys.wasm.

    +
    casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \
    --chain-name "casper-test" \
    --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-<ACCOUNT_HASH>'" \
    --session-arg "new_weight:u8='3'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    The primary key in this account should now have weight 3.

    +
    Account details
    + +
    "Account": {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "weight": 3
    }
    ],
    "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",
    "named_keys": []
    }
    +
    +

    The table below summarizes the updates.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Threshold / KeyPrevious weightCurrent weight
    deployment11
    key_management11
    Primary key (1ed5...)13
    +

    Step 4: Update the account's action thresholds

    +

    Set up a multi-signature scheme for the account by updating the deployment and key_management thresholds. The update_thresholds.wasm will take two arguments and set the deployment threshold to 2 and the key_management threshold to 3.

    +
    casper-client put-deploy \
    --node-address https://rpc.testnet.casperlabs.io \
    --chain-name casper-test \
    --payment-amount 500000000 \
    --secret-key $PATH/secret_key.pem \
    --session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \
    --session-arg "deployment_threshold:u8='2'" \
    --session-arg "key_management_threshold:u8='3'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    The account's action thresholds should look like this:

    +
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    +

    This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management.

    +
    Account details
    + +
    "Account": {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "weight": 3
    }
    ],
    "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",
    "named_keys": []
    }
    +
    +

    The table below summarizes the updates.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    +

    Step 5: Add associated keys to the primary account

    +

    To add an associated key to the primary account, use the add_account.wasm provided. This example adds two keys to the primary account (account-hash-d89c*): user_1 with account-hash-e2d0*, and user_2 with account-hash-04a9*.

    +
    casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \
    --chain-name "casper-test" \
    --payment-amount 500000000 \
    --secret-key $PATH/secret_key.pem \
    --session-path target/wasm32-unknown-unknown/release/add_account.wasm \
    --session-arg "new_key:key='account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \
    --session-arg "weight:u8='1'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +
    casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \
    --chain-name "casper-test" \
    --payment-amount 500000000 \
    --secret-key $PATH/secret_key.pem \
    --session-path target/wasm32-unknown-unknown/release/add_account.wasm \
    --session-arg "new_key:key='account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \
    --session-arg "weight:u8='1'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1.

    +
    Account details
    + +
    "Account": {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",
    "weight": 1
    },
    {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "weight": 3
    },
    {
    "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",
    "weight": 1
    }
    ],
    "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",
    "named_keys": []
    }
    +
    +
    note
      +
    1. All associated keys should be kept incredibly secure to ensure the security and integrity of the account.
    2. +
    3. After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up.
    4. +
    +

    The table below summarizes the updates.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    Associated key (04a9...)N/A1
    Associated key (e2d0...)N/A1
    +

    Step 6: Send a deploy from the primary account

    +

    This step sends a deploy containing Wasm (contract.wasm), which adds a named key to the account. The source code for the Wasm comes from the hello-world repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold.

    +
    casper-client put-deploy --chain-name casper-test \
    --payment-amount 3000000000 \
    --session-path tests/wasm/contract.wasm \
    --secret-key $PATH/secret_key.pem \
    --session-arg "my-key-name:string='primary_account_key'" \
    --session-arg "message:string='Hello, World'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    The hello_world.wasm should have run and added a named key to the account.

    +
    "named_keys": [
    {
    "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",
    "name": "my-key-name"
    }
    ]
    +

    Step 7: Send a multi-signature deploy from an associated key

    +

    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:

    +
      +
    • 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.

    +

    When using the --session-account argument, specify the hex-encoded public key of the primary account context under which the session code will be executed.

    +

    One associated key creates and signs the deploy with the make-deploy command, indicating the account context under which the session code will be executed.

    +
    casper-client make-deploy --chain-name casper-test \
    --payment-amount 300000000 \
    --session-path tests/wasm/contract.wasm \
    --secret-key $PATH/user_1_secret_key.pem \
    --session-arg "my-key-name:string='user_1_key'" \
    --session-arg "message:string='Hello, World'" \
    --session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \
    --output hello_world_one_signature
    +

    The second associated key signs the deploy with sign-deploy to meet the deployment threshold for the account.

    +
    casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem  -o hello_world_two_signatures
    +

    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
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    The hello_world.wasm should have run and added a named key to the account.

    +

    Removing a Compromised Key

    +

    This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the remove_account.wasm session code.

    +
    caution

    Remove keys with caution! Do not run this example on Mainnet.

    Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution.

    +

    Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key.

    +
    casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \
    --chain-name "casper-test" \
    --payment-amount 500000000 \
    --secret-key $PATH/secret_key.pem \
    --session-path target/wasm32-unknown-unknown/release/add_account.wasm \
    --session-arg "new_key:key='account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \
    --session-arg "weight:u8='1'"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +
    Account details
    + +
    "Account": {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",
    "weight": 1
    },
    {
    "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",
    "weight": 1
    },
    {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "weight": 3
    },
    {
    "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",
    "weight": 1
    }
    ],
    "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",
    "named_keys": []
    }
    +
    +

    The table below summarizes the updates after calling the add_account.wasm.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    Associated key (04a9...)11
    Associated key (e2d0...)11
    Associated key (1fed...)N/A1
    +

    The remove_account.wasm will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised.

    +
    casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \
    --chain-name "casper-test" \
    --payment-amount 500000000 \
    --secret-key $PATH/secret_key.pem \
    --session-path target/wasm32-unknown-unknown/release/remove_account.wasm \
    --session-arg "remove_key:key='account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"
    +

    Verify that the deploy ran successfully.

    +
    casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>
    +

    Retrieve the latest state root hash and check the primary account details.

    +
    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 <STATE_ROOT_HASH> \
    --key account-hash-<PRIMARY_ACCOUNT_HASH>
    +

    The resulting account should not contain the associated key that was just removed.

    +
    Account details
    + +
    "Account": {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",
    "weight": 1
    },
    {
    "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "weight": 3
    },
    {
    "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",
    "weight": 1
    }
    ],
    "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",
    "named_keys": []
    }
    +
    +

    The table below summarizes the updates after calling the remove_account.wasm.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    Associated key (04a9...)11
    Associated key (e2d0...)11
    Associated key (1fed...)1N/A (Removed)
    +

    Next Steps

    +

    The next section contains additional examples where Casper's multi-signature feature would be helpful.

    + + \ No newline at end of file diff --git a/next/resources/advanced/multi-sig/other-scenarios/index.html b/1.5.X/resources/advanced/multi-sig/other-scenarios/index.html similarity index 62% rename from next/resources/advanced/multi-sig/other-scenarios/index.html rename to 1.5.X/resources/advanced/multi-sig/other-scenarios/index.html index 224727c1f..3477473bd 100644 --- a/next/resources/advanced/multi-sig/other-scenarios/index.html +++ b/1.5.X/resources/advanced/multi-sig/other-scenarios/index.html @@ -1,21 +1,21 @@ - + -Additional Examples | Casper Docs - Redux +Additional Examples | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Additional Examples

    + submit an issue on Github
    Version: 1.5.X

    Additional Examples

    This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.

    Example 1: An account with a single (primary) key

    In this example, only one key (account-hash-a1…) can sign transactions in the name of this account. This key is the primary key of the account and has a weight equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions.

    @@ -36,6 +36,6 @@

    Example 5: Recovering a lost primary key

    This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account.

    Account details in example 5:

    -
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-d4…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-d4…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    \ No newline at end of file diff --git a/next/resources/beginner/counter-testnet/commands/index.html b/1.5.X/resources/beginner/counter-testnet/commands/index.html similarity index 62% rename from next/resources/beginner/counter-testnet/commands/index.html rename to 1.5.X/resources/beginner/counter-testnet/commands/index.html index c863b33cb..e302e0913 100644 --- a/next/resources/beginner/counter-testnet/commands/index.html +++ b/1.5.X/resources/beginner/counter-testnet/commands/index.html @@ -1,21 +1,21 @@ - + -Casper-Client Commands | Casper Docs - Redux +Casper-Client Commands | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Casper-Client Commands

    State Root Hash

    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]

    Example:

    @@ -43,9 +43,9 @@

    Deploy via a named key already on the blockchain

    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-test \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"

    This second usage of put-deploy does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts.

    -

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    +

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    Get Deploys (from the Chain)

    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    -

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    \ No newline at end of file diff --git a/1.5.X/resources/beginner/counter-testnet/overview/index.html b/1.5.X/resources/beginner/counter-testnet/overview/index.html new file mode 100644 index 000000000..cd8f5da63 --- /dev/null +++ b/1.5.X/resources/beginner/counter-testnet/overview/index.html @@ -0,0 +1,23 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Overview

    +

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    +

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    +

    image

    + + \ No newline at end of file diff --git a/1.5.X/resources/beginner/counter-testnet/walkthrough/index.html b/1.5.X/resources/beginner/counter-testnet/walkthrough/index.html new file mode 100644 index 000000000..7278eec8e --- /dev/null +++ b/1.5.X/resources/beginner/counter-testnet/walkthrough/index.html @@ -0,0 +1,126 @@ + + + + + +Tutorial Walkthrough | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Tutorial Walkthrough

    +

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    +

    Clone the Repository

    +

    First, you will need to clone the counter contract repository on our local machine.

    +
    git clone https://github.com/casper-ecosystem/counter
    +

    If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:

    +
      +
    • +

      contract-v1

      +
        +
      • This is the first version of the counter contract.
      • +
      • Defines two named keys: counter to reference the contract and an associated variable count to store a value.
      • +
      • Provides a function to get the current count (count_get).
      • +
      • Provides a function to increment the current count (counter_inc).
      • +
      +
    • +
    • +

      contract-v2

      +
        +
      • This is a second version of the counter contract, which will not be used in this tutorial.
      • +
      • This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial.
      • +
      +
    • +
    • +

      counter-call

      +
    • +
    • +

      This is session code that retrieves the contract-v1 contract, gets the current count value, increments it, and ensures the count was incremented by 1.

      +
    • +
    +

    View the Network State

    +

    With a network up and running, you can use the casper-client query-global-state command to check the status of the network. However, you first need an account hash and the state-root-hash so that you can get the current snapshot. Once you have that information, you can check the status of the network.

    +

    You will need to use the following three commands:

    +
      +
    1. casper-client account-address --public-key [PATH_TO_PUBLIC_KEY] - Get the account-hash
    2. +
    3. casper-client get-state-root-hash - Get the state-root-hash
    4. +
    5. casper-client query-state - Query the network state
    6. +
    +

    Run through these commands in order.

    +
    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    +

    You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first.

    +

    Next, get the state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777
    +

    You need to use the IP address of one of the connected peers on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state.

    +

    Please be mindful of the node address format when using the casper-client get-state-root-hash command.

    +

    While browsing the connected peers list, you might encounter entries similar to 44.222.236.237:35000. These entries only provide the IP address and port used for peer-to-peer communication within the network.

    +

    For the casper-client get-state-root-hash command, you need to modify the address slightly:

    +
      +
    1. Add the http:// prefix: This indicates that you're communicating with the node using the HTTP protocol.
    2. +
    3. Replace the port: While the peers list might show a different port (e.g., 35000), the Casper node uses port 7777 for state queries.
    4. +
    +

    Following these steps, the correct command format for your example address would be:

    +
    casper-client get-state-root-hash --node-address http://44.222.236.237:7777
    +

    Remember to apply this modification to any node address you use with the get-state-root-hash command.

    +

    Finally, query the actual state:

    +
    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet.

    +

    Install the Contract

    +

    Before installing the contract on the chain, you will need to compile it to Wasm.

    +

    The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. make prepare sets the Wasm target and make test builds the contracts and verifies them.

    +
    cd counter
    make prepare
    make test
    +

    With the compiled contract, you can call the casper-client put-deploy command to install the contract on the chain.

    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm
    +
      +
    • Replace the [PATH_TO_YOUR_KEY] field with the actual path of where your secret key is stored.
    • +
    • The session-path argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory.
    • +
    +

    Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place.

    +
    casper-client get-deploy \
    --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]
    +

    View the Updated Network State

    +

    Hopefully, the deploy was successful. Call the casper-client query-global-state command to check if the named key is visible on the chain.

    +
    note

    You must get the new state root hash since you just wrote a deploy to the chain.

    +

    If you run these two commands, there will be a new counter named key on the chain.

    +

    Get the NEW state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777
    +

    Get the network state:

    +
    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail.

    +

    Retrieve the specific counter contract details:

    +
    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter"
    +

    Retrieve the specific count value:

    +
    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    Retrieve the specific deploy details:

    +
    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]
    +

    The first two commands access the counter and count named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of put-deploy) to query the state of that specific deploy only.

    +

    Increment the Counter

    +

    You now have a counter on the chain, and you can increment it by calling the entry-point counter_inc, the function defined in the contract. You can call an entry-point in an installed contract by using the put-deploy command as illustrated here:

    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +

    Notice that this command is nearly identical to the command used to deploy the contract. However, instead of session-path pointing to the Wasm binary, you have session-name and session-entry-point identifying the on-chain contract and its associated entry-point to execute.

    +

    View the Updated Network State Again

    +

    After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument.

    +

    Get the NEW state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777
    +

    Get the network state, specifically for the count variable this time:

    +
    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    You should be able to see the count value and observe that it has increased.

    +

    Increment the Counter Again

    +

    If you recall, in the repository there is session code called counter-call. Try to increment the count using that session code instead of the session entry-point used above.

    +

    Keep in mind, this is another put-deploy call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract.

    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm
    +

    View the Final Network State

    +

    To make sure that the session code ran successfully, get the new state root hash and query the network.

    +
    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777
    +

    Get the network state, specifically for the count variable this time:

    +
    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    If all went according to plan, your count value should be 2 at this point.

    +

    Congratulations on building, installing, and using a smart contract on the Testnet!

    + + \ No newline at end of file diff --git a/next/resources/beginner/counter/commands/index.html b/1.5.X/resources/beginner/counter/commands/index.html similarity index 63% rename from next/resources/beginner/counter/commands/index.html rename to 1.5.X/resources/beginner/counter/commands/index.html index 84288b15b..c511c10f6 100644 --- a/next/resources/beginner/counter/commands/index.html +++ b/1.5.X/resources/beginner/counter/commands/index.html @@ -1,21 +1,21 @@ - + -Casper-Client Commands | Casper Docs - Redux +Casper-Client Commands | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Casper-Client Commands

    Faucet Account Information

    nctl-view-faucet-account

    This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's secret key location and the account hash, which are used to sign deploys and query the network state, respectively.

    @@ -43,9 +43,9 @@

    Deploy via a named key already on the blockchain

    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-net-1 \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"

    This second usage of put-deploy does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts.

    -

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    +

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    Get Deploys (from the Chain)

    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    -

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    \ No newline at end of file diff --git a/1.5.X/resources/beginner/counter/overview/index.html b/1.5.X/resources/beginner/counter/overview/index.html new file mode 100644 index 000000000..2d6642c54 --- /dev/null +++ b/1.5.X/resources/beginner/counter/overview/index.html @@ -0,0 +1,23 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Overview

    +

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    +

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    +

    image

    + + \ No newline at end of file diff --git a/1.5.X/resources/beginner/counter/walkthrough/index.html b/1.5.X/resources/beginner/counter/walkthrough/index.html new file mode 100644 index 000000000..2f2439b76 --- /dev/null +++ b/1.5.X/resources/beginner/counter/walkthrough/index.html @@ -0,0 +1,141 @@ + + + + + +Tutorial Walkthrough | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Tutorial Walkthrough

    +

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    +

    Clone the Repository

    +

    First, you will need to clone the counter contract repository on our local machine.

    +
    git clone https://github.com/casper-ecosystem/counter
    +

    If you explore the source code, you will see that there are three versions of the counter contract and one file with session code that calls the contract's entry-points:

    +
      +
    • +

      contract-v1

      +
        +
      • This is the first version of the counter contract.
      • +
      • It defines two named keys: +
          +
        • counter: References the contract itself.
        • +
        • count: Stores the current counter value.
        • +
        +
      • +
      • It provides functions for: +
          +
        • get_count: Retrieves the current counter value.
        • +
        • counter_inc: Increments the counter value by 1.
        • +
        +
      • +
      +
    • +
    • +

      contract-v2 (Not Used in This Tutorial)

      +
        +
      • An extension of contract-v1. It demonstrates decrementing the counter and contract upgrades.
      • +
      +
    • +
    • +

      **contract-v3 ** (Not Used in This Tutorial)

      +
        +
      • This version showcases how to add new functionalities during smart contract upgrades. It extends contract-v1 and contract-v2 by introducing: +
          +
        • A new named key: last_updated_at - Tracks the timestamp of the last counter update.
        • +
        • A new entry point: get_last_updated_at - Retrieves the last_updated_at timestamp.
        • +
        +
      • +
      • It focuses on the process of adding new fields like last_updated_at to existing contracts.
      • +
      +
    • +
    • +

      counter-call

      +
        +
      • Session code that retrieves the specific contract version (e.g., contract-v1), interacts with its functions (e.g., get_count, counter_inc), and verifies the expected behavior.
      • +
      +
    • +
    +

    Create a Local Network

    +

    After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network.

    +

    If you run the following line in your terminal, you should be able to spin up a network effortlessly.

    +
    nctl-assets-setup && nctl-start
    +
    note

    If it fails for any reason, please refer the NCTL tutorial and make sure that all your packages are up to date.

    +

    View the Network State

    +

    With a network up and running, you can use the casper-client query-global-state command to check the status of the network. However, you first need an AccountHash and the state-root-hash so that you can get the current snapshot. Once you have that information, check the status of the network.

    +

    You will need to use the following three commands:

    +
      +
    1. nctl-view-faucet-account - Get the faucet's account hash
    2. +
    3. casper-client get-state-root-hash - Get the state root hash
    4. +
    5. casper-client query-global-state - Get the network state
    6. +
    +

    Run through these commands in order.

    +
    nctl-view-faucet-account
    +

    If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the account-hash field and the secret_key.pem path because you will often use both.

    +

    Get the state root hash:

    +
    casper-client get-state-root-hash --node-address http://localhost:11101
    +

    You are using localhost as the node server since the network is running on our local machine. Make a note of the state-root-hash that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state.

    +

    Finally, query the actual state:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet.

    +

    Install the Contract

    +

    Before installing the contract on the chain, you will need to compile it to Wasm.

    +

    The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. make prepare sets the Wasm target and make test builds the contracts and verifies them.

    +
    cd counter
    make prepare
    make test
    +

    With the compiled contract, you can call the casper-client put-deploy command to install the contract on the chain.

    +
    casper-client put-deploy \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm
    +
      +
    • Replace the [PATH_TO_YOUR_KEY] field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call nctl-view-faucet-account.
    • +
    • The session-path argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory.
    • +
    +

    Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place.

    +
    casper-client get-deploy \
    --node-address http://localhost:11101 [DEPLOY_HASH]
    +

    View the Updated Network State

    +

    Hopefully, the deploy was successful. Call the casper-client query-global-state command to check if the named key is visible on the chain.

    +
    note

    You must get the new state root hash since you just wrote a deploy to the chain.

    +

    If you run these two commands, there will be a new counter named key on the chain.

    +

    Get the NEW state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://localhost:11101
    +

    Get the network state:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail.

    +

    Retrieve the specific counter contract details:

    +
    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter"
    +

    Retrieve the specific count value:

    +
    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    Retrieve the specific deploy details:

    +
    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]
    +

    The first two commands access the counter and count named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of put-deploy) to query the state of that specific deploy only.

    +

    Increment the Counter

    +

    You now have a counter on the chain, and you can increment it by calling the entry-point counter_inc, the function defined in the contract. You can call an entry-point in an installed contract by using the put-deploy command as illustrated here:

    +
    casper-client put-deploy \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +

    Notice that this command is nearly identical to the command used to install the contract. However, instead of session-path pointing to the Wasm binary, you have session-name and session-entry-point identifying the on-chain contract and its associated entry-point to execute.

    +

    View the Updated Network State Again

    +

    After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument.

    +

    Get the NEW state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://localhost:11101
    +

    Get the network state, specifically for the count variable this time:

    +
    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    You should be able to see the count value and observe that it has increased.

    +

    Increment the Counter Again

    +

    If you recall, in the repository there is session code called counter-call. Try to increment the count using that session code instead of the session entry-point used above.

    +

    Keep in mind, this is another put-deploy call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract.

    +
    casper-client put-deploy \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm
    +

    View the Final Network State

    +

    To make sure that the session code ran successfully, get the new state root hash and query the network.

    +
    casper-client get-state-root-hash --node-address http://localhost:11101
    +

    Get the network state, specifically for the count variable this time:

    +
    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"
    +

    If all went according to plan, your count value should be 2 at this point.

    +

    Congratulations on building, installing, and using a smart contract on your local network!

    + + \ No newline at end of file diff --git a/1.5.X/resources/build-on-casper/casper-open-source-software/index.html b/1.5.X/resources/build-on-casper/casper-open-source-software/index.html new file mode 100644 index 000000000..c4df2353f --- /dev/null +++ b/1.5.X/resources/build-on-casper/casper-open-source-software/index.html @@ -0,0 +1,531 @@ + + + + + +Open-Source Software | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Ecosystem Open-Source Software

    +

    This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescriptionAuthorLanguageLicenseLast Update DateType
    Basic Yield FarmStaking RewardsRengo LabsRustApache-2.0 license2022-06-24Staking
    Blockcerts on CasperIssues Blockcerts using the Bitcoin, Ethereum, or Casper blockchainamazanzanPythonMIT license2022-07-22Tokens
    BlockMatcher Frontend BackendPrivate Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches.LedgerLeapJavaScript-PHPMIT license2022-01-15Exchange
    Camel CasperApache Camel connector for the Casper BlockchainM.AbahmaneJavaMIT license2022-03-26Tools
    Casper .NET SDKCasper .NET Client SDK to interact with Casper network nodes via RPC.MAKE Software.NETApache-2.0 license2022-04-19Client SDK
    Casper Analytics AppCasper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod Appcaspercommunity.ioPHPMIT license2022-01-20Tools
    Casper C++ SDKC++ library to interact with Casper network nodes via RPCYusuf KetenC++Apache-2.0 license2022-09-13Client SDK
    Casper CalculatorCasper Earnings Calculator and Node MonitorCharles NguyenJavaScriptMIT license2021-09-26Tools
    Casper Contract UpgradeExample contract to demonstrate the general way of upgrading a contract and the necessary stepsCasper LabsRustApache-2.0 license2022-06-21Example Contracts
    Casper Dart SDKCasper Dart SDK is for interacting with the Casper Blockchain using RPC.TemiltasDartApache-2.0 license2022-06-26Client SDK
    Friendly Market's Casper variant of ERC20Implementation of the ERC20 standard for Casper networksFriendly MarketRustApache-2.0 license2022-08-10Tokens
    Casper Go SDKCasper Go SDKMAKE SoftwareGoApache-2.0 license2023-06-01Client SDK
    Casper Hello World ContractThis example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKeyCasper LabsRustNA2022-07-13Example contracts
    Casper JavaScript SDKCasper Client JavaScript SDKCasper LabsTypeScript-JavaScriptApache-2.0 license2022-09-13Client SDK
    Casper Kotlin SDKCasper Kotlin Client SDK to interact with a Casper network.tqhuy2018KotlinMIT license2022-07-21Client SDK
    Casper MetricsCasper Metrics - fast blockchain crawler, API, and analysis toolA3MCTypeScriptMIT license2022-09-09Tools
    Casper NCTL DockerA Docker container that runs Casper NCTL as a serviceMAKE SoftwareShellApache-2.0 license2022-03-17Tools
    Casper Node-REDNodes to communicate with the Casper's Blockchain using node-redcaspercommunity.ioJavaScriptMIT license2022-02-08Tools
    Casper Objective-C SDKCasper Objective-C SDK is for interacting with the Casper Blockchain using RPC.hienbui9999Objective-CMIT license2022-06-18Client SDK
    Casper PHP SDKPHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHPMAKE SoftwarePHPApache-2.0 license2022-06-29Client SDK
    Casper Ruby Client SDKRuby SDK to interact with Casper network nodes via RPC.Sait GulmezRubyApache-2.0 license2022-03-08Client SDK
    Casper Scala SDKCasper Scala client SDK to interact with the Casper Network nodes via RPCM.AbahmaneScalaMIT license2022-03-23Client SDK
    Casper WalletA browser wallet for the Casper NetworkMAKE SoftwareTypeScript-JavaScriptApache-2.0 license2023-04-12Wallet
    Casper SSI Web AppCasper SSI Framework in the form of a demo web application.Credentia NetworkTypeScriptMIT license2022-06-29Tools
    Casper StorageCasper storage - HD walletsCasperDashTypeScriptApache-2.0 license2022-09-14Wallet
    Casper Swift SDKCasper Client SDK. Casper SDK methods implementation in Swift.hienbui9999SwiftMIT license2022-06-08Client SDK
    Casper Two-Party MultiSig ContractThis example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys.Casper LabsRustNA2022-04-26Example contracts
    Casper WorldCasper network status and decentralization map web applicationNodes GuruTypeScriptMIT license2022-01-26Blockchain Explorer
    CasperDash WalletA non-custodial wallet for the Casper blockchainCasperDashJavaScriptMIT license2022-09-14Wallet
    CasperFYRE APIDispensory API interface for Casper MainnetLedgerLeapJavaScript-PHPApache-2.0 license2022-09-06Tools
    CasperHoldersFirst 3rd party UI to interact with Casper BlockchainCasperHoldersJavaScriptApache-2.0 license2022-08-23Blockchain Explorer
    CasperSignThe First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper BlockchainChronoLogic and Digital StrategiesTypeScriptNA2022-08-31dApp
    CEP-78 Enhanced NFT StandardStandard Contract Generator for NFTsCasper LabsRustApache-2.0 license2022-08-23NFT
    CES Rust Event EmitterRust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)MAKE SoftwareRustApache-2.0 license2023-05-11dApp library
    CES JS ParserJS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareJavaScriptApache-2.0 license2023-03-27dApp library
    CES Go ParserGo library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareGoApache-2.0 license2023-06-02dApp library
    Clearest StakeStaking Asset Manager for Node operators and groupsLedgerLeapPHPApache-2.0 license2022-04-02DeFi
    DAO ContractsSmart Contracts for the MVPR On-Chain Governance System on CasperMAKE SoftwareRustApache-2.0 license2022-07-17DAO
    DHF PAYThe crypto currency payment gateway on the CSPR blockchainDHFinanceTypeScriptApache-2.0 license2022-08-28Payments
    DLN DAODLN DAOAlphaFinTypeScriptMIT license2022-09-10DAO
    DotOracleRealtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains.DotOracle NetworkTypeScriptNA2022-09-26Bridge
    Dragon’s Lair Style StakingLair Style StakingRengo LabsRustApache-2.0 license2022-06-24Staking
    Subscription BillingERC-1337 subscription billingRengo LabsRustMIT license2022-04-07Tokens
    Casper Fungible TokenImplementation of Fungible Tokens for Casper networksCasper LabsRustApache-2.0 license2022-09-01Tokens
    Advanced Fungible TokenERC-777 + 1820 Advanced Fungible Token with Callbacks & Self IdentificationRengo LabsRustApache-2.0 license2022-08-16Tokens
    Helper BotHelper bot for improving DevDao VAs productivityA3MCTypeScriptMIT license2022-08-19Tools
    Java SDKCasper Client Java SDKSyntiFiJavaApache-2.0 license2021-04-20Client SDK
    KYC Proxy ContactThis is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)Casper LabsRustNA2022-07-01Example contracts
    LiquidNFTNFT Collateralized LoansRengo LabsJavaScriptGNU General Public License v3.02022-09-15NFT
    Payment Example ContractThis example demonstrates the usage of purses to transfer motes inside a contractCasper LabsRustNA2022-06-22Example contracts
    ServicesDAOThe ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR.Ekon YazilimHTML-CSS-C#MIT license2022-09-13DAO
    Uniswap DemoAppUniswap UI + ContractsRengo LabsJavaScriptGPL-3.0 license2022-09-15DeFi
    Verified Impact NFTAn NFT platform dedicated to impact causes with verification of the beneficiariesAlphaFinJavaScript-RustMIT license2022-07-08NFT
    UseWalletuseWallet is a collection of React Hooks containing everything you need to start working with a Casper networkCasperDashTypescript-ReactMIT license2023-09-19dApp library
    Testnet FaucetA faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for freeCasperDashTypescript-ReactMIT license2023-09-19Tools
    + + \ No newline at end of file diff --git a/1.5.X/resources/build-on-casper/introduction/index.html b/1.5.X/resources/build-on-casper/introduction/index.html new file mode 100644 index 000000000..fe93ba3e3 --- /dev/null +++ b/1.5.X/resources/build-on-casper/introduction/index.html @@ -0,0 +1,78 @@ + + + + + +Build on Casper | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Building on Casper

    +

    This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.

    + +

    Thriving Ecosystem

    +

    The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use.

    +

    Wallets

    + +

    Block Explorers

    + +

    Developer Tools

    + +

    Open Source Software

    + +

    Developer-Friendly Language

    +

    Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet.

    +

    Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an open standard for performance and portability of modern web applications.

    +
    note

    Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available.

    +

    Powerful Accounts

    +

    Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the Casper Permissions Model for more details.

    +

    Contract Upgrades

    +

    Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts.

    +

    Development Tools

    +

    IDE Integration

    +

    The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started.

    +

    CI/CD

    +

    Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline.

    +

    Local Network Testing

    +

    We also offer a tool to run a local Casper Network Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface.

    +

    Public Mainnet and Testnet

    +

    The Casper Mainnet is a public, open-source, community-driven ecosystem. You can also explore the Testnet to test drive your applications and estimate gas costs.

    +

    AWS

    +

    We also offer several tools to run AWS instances of Casper nodes.

    +

    SDK Client Libraries

    +

    In addition to the default command-line Rust client, the Casper community is building other clients in JavaScript, Java, Golang, Python, C#, and other languages.

    +

    Low Gas Fees

    +

    Casper seeks to eliminate volatility and improve developer and enterprise experiences by establishing transparent, consistent, and low gas prices. This feature seeks to promote active and diverse network behaviour and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows.

    + + \ No newline at end of file diff --git a/resources/condor-for-exchanges/index.html b/1.5.X/resources/condor-for-exchanges/index.html similarity index 70% rename from resources/condor-for-exchanges/index.html rename to 1.5.X/resources/condor-for-exchanges/index.html index 4ba1bdf87..22cfb65cd 100644 --- a/resources/condor-for-exchanges/index.html +++ b/1.5.X/resources/condor-for-exchanges/index.html @@ -3,19 +3,19 @@ -Condor Release Notes for Exchanges | Casper Docs - Redux +Condor Release Notes for Exchanges | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Condor Release Notes for Exchanges

    + submit an issue on Github
    Version: 1.5.X

    Condor Release Notes for Exchanges

    Account/Contract Merge

    • diff --git a/1.5.X/resources/index.html b/1.5.X/resources/index.html new file mode 100644 index 000000000..ad3bf4043 --- /dev/null +++ b/1.5.X/resources/index.html @@ -0,0 +1,89 @@ + + + + + +Resources Overview | Casper Docs - Redux + + + + + + + + + +
      Version: 1.5.X

      Resources Overview

      +

      Building on Casper

      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      TopicDescription
      Wallets and Block ExplorersWallets that support the native Casper token $CSPR
      WebAssemblyLearn why WebAssembly is an advantage in contract development
      AccountsThe Casper account-model allowing for multi-signature deploys
      Developer toolsAvailable development tools
      Ecosystem ProjectsExplore some open-source code available in the Casper ecosystem
      +

      Move to Casper

      + + + + + + + + + + + + + +
      TopicDescription
      Move to CasperLearn how to start working with Casper, having previous knowledge of other blockchains
      +

      Tutorials

      + + + + + + + + + + + + + + + + + + + + + +
      TopicDescription
      QuickstartInstall Rust and setup a Casper environment
      BeginnerLearn the basics, such as installing and upgrading contracts
      AdvancedLearn about multi-sig, authorization keys, exchange integration, and storage
      + + \ No newline at end of file diff --git a/next/resources/moving-to-casper/index.html b/1.5.X/resources/moving-to-casper/index.html similarity index 75% rename from next/resources/moving-to-casper/index.html rename to 1.5.X/resources/moving-to-casper/index.html index 81339f8a1..3c6ac0890 100644 --- a/next/resources/moving-to-casper/index.html +++ b/1.5.X/resources/moving-to-casper/index.html @@ -1,21 +1,22 @@ - + -Move to Casper | Casper Docs - Redux +Move to Casper | Casper Docs - Redux - - + +
      Version: Next

      import Tabs from '@theme/Tabs'; + submit an issue on Github

      Version: 1.5.X

      import useBaseUrl from '@docusaurus/useBaseUrl'; +import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

      Moving to Casper from another Blockchain

      This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:

      @@ -31,9 +32,9 @@

      Smart Cont

      Casper smart contracts are written in Rust.

      -

      Variables defined within the smart contract can be stored as either Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

      -

      The call function serves as the main entry point of the smart contract. 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.

      +

      Variables defined within the smart contract can be stored as either Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

      +

      The call function serves as the main entry point of the smart contract. 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.

      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.

      @@ -64,7 +65,7 @@

      Smart Cont

      Variable Storage and State Management

      -

      Variables can be stored as Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

      +

      Variables can be stored as Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

      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.

      @@ -92,9 +93,9 @@

      Contract

      For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:

      #[no_mangle]
      pub extern "C" fn counter_inc() {

      // Entry point body
      }

      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 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 syntax described in the Interacting with Runtime Return Values tutorial.

      +

      If a return value is needed, it should be declared using the syntax described in the Interacting with Runtime Return Values tutorial.

      runtime::ret(value);
      -

      Each call to an entry point is treated as a Deploy to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).

      +

      Each call to an entry point is treated as a Deploy to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).

      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.

      @@ -137,11 +138,11 @@

      Passing Ar

      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:

      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'"
      -

      To understand the context of this example, refer to: Delegating with the Casper Client.

      +

      To understand the context of this example, refer to: Delegating with the Casper Client.

      In the contract, you can access the session arguments as follows:

      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.

      +

      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.

      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.

      @@ -177,6 +178,6 @@

      Ad

    • 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.

    +

    The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects.

    \ No newline at end of file diff --git a/1.5.X/resources/quick-start/index.html b/1.5.X/resources/quick-start/index.html new file mode 100644 index 000000000..6d40be9e0 --- /dev/null +++ b/1.5.X/resources/quick-start/index.html @@ -0,0 +1,122 @@ + + + + + +Quickstart | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Quickstart

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.

    +

    Prerequisites

    +
      +
    1. You have installed Rust. Verify the installation with this command: rustup --version. Restart the shell if needed.
    2. +
    3. You have installed cmake. Verify the installation with this command: cmake --version. +
        +
      • On Ubuntu, you can follow this guide.
      • +
      • On MacOS, use this command: brew install cmake.
      • +
      +
    4. +
    5. You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install cargo-casper.
    6. +
    7. You have download Git.
    8. +
    +

    Steps

    +
      +
    1. +

      Install Cargo Casper with this command:

      +

      cargo install cargo-casper

      +
    2. +
    3. +

      Install the Casper client:

      +

      cargo install casper-client

      +

      If you have issues installing the casper-client, you may need additional libraries.

      +
        +
      • +

        On MacOS:

        +
        brew install pkg-config
        brew install openssl
        +
      • +
      • +

        On Ubuntu:

        +
        sudo apt-get install pkg-config
        sudo apt-get install openssl
        sudo apt-get install libssl-dev
        +
      • +
      +

      Note: Make sure you also have the development packages of openssl installed. For example, libssl-dev on Ubuntu or openssl-devel on Fedora.

      +
    4. +
    5. +

      Test the casper-client by querying a node on the network and getting the latest state root hash.

      +
      casper-client get-state-root-hash --node-address http://65.21.235.219:7777
      +
    6. +
    7. +

      Set up a Casper Account.

      +
    8. +
    9. +

      Clone a simple counter contract or download it from GitHub:

      +

      git clone https://github.com/casper-ecosystem/counter

      +
    10. +
    11. +

      Navigate to the folder and prepare the dependencies to build the contract:

      +
    12. +
    +
    cd counter
    make prepare
    +
      +
    1. Build the contract and tests:
    2. +
    +

    make test

    +
      +
    1. Install the contract on Testnet using the casper-client's put-deploy command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet chainspec.
    2. +
    +
    casper-client put-deploy \
    --node-address [NODE_ADDRESS] \
    --chain-name casper-test \
    --secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \
    --payment-amount 30000000000 \
    --session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm
    +
      +
    1. Check the deploy status given the deploy hash from the previous command:
    2. +
    +
    casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]
    +
      +
    1. Get the latest state root hash:
    2. +
    +
    casper-client get-state-root-hash --node-address [NODE_ADDRESS]
    +
      +
    1. Open the deploy tab of the account on the Testnet to see the deploy details.
    2. +
    +
      +
    • As an alternative to step 15, check your account using the command line:
    • +
    +
    casper-client query-global-state \
    --node-address [NODE_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [PATH_TO_PUBLIC_KEY]
    +
      +
    • As another alternative, use the account hash for the --key argument. To get the account hash, look at the account details on the block explorer, or run this command:
    • +
    +
    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    +

    Then, query the blockchain using the account hash:

    +
    casper-client query-global-state \
    --node-address [NODE_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +
      +
    1. Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let's make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.
    2. +
    +
    casper-client query-global-state \
    --node-address [NODE_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "counter/count"
    +

    Example output:

    +
    {
    "id": 8523290678829319485,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.6",
    "block_header": null,
    "merkle_proof": "[85716 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "01000000",
    "cl_type": "I32",
    "parsed": 0
    }
    }
    }
    }
    +
      +
    1. Now increment the count value by calling the entry point counter_inc.
    2. +
    +
    casper-client put-deploy \
    --node-address [NODE_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY] \
    --payment-amount 100000000 \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +
      +
    1. Get the NEW state root hash, to get the latest snapshot of the blockchain state – this is EXTREMELY IMPORTANT!
    2. +
    +
    casper-client get-state-root-hash --node-address [NODE_ADDRESS]
    +
      +
    1. Query the state of the network.
    2. +
    +
    casper-client query-state \
    --node-address [NODE_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "counter/count"
    +

    If everything went according to plan, the value should be 1. Look at the "parsed" value below.

    +
    {
    "id": 8523290678829319485,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.6",
    "block_header": null,
    "merkle_proof": "[85716 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "01000000",
    "cl_type": "I32",
    "parsed": 1
    }
    }
    }
    }
    +

    You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts.

    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep18/full-tutorial/index.html b/1.5.X/resources/tokens/cep18/full-tutorial/index.html new file mode 100644 index 000000000..d68f61b80 --- /dev/null +++ b/1.5.X/resources/tokens/cep18/full-tutorial/index.html @@ -0,0 +1,193 @@ + + + + + +Fungible Token Workflow | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Casper Fungible Token Tutorial

    +

    This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.

    +

    The Ethereum Request for Comment (ERC-20) standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded.

    +

    The Casper Fungible Token standard is the Casper Platform's ER-C20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed.

    +

    The following functions implement the rules defined by Casper Fungible Tokens: totalSupply, transfer, transferFrom, approve, balanceOf, and allowance. A portion of this tutorial reviews the contract and the casper_fungible_token library.

    +

    The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read first.

    +

    Preparation

    +

    First clone the contract from GitHub:

    +
    git clone https://github.com/casper-ecosystem/cep18 && cd cep18
    +

    Prepare your environment with the following command:

    +
    make prepare
    +

    If your environment is set up correctly, you will see this output:

    +
    rustup target add wasm32-unknown-unknown
    info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date
    +

    If you do not see this message, check the Getting Started Guide.

    +

    Next, compile your contract and run the contract unit tests.

    +
    make build-contract
    make test
    +

    Contract Implementation

    +

    In GitHub, you will find a library and an example implementation of the Fungible Token for Casper networks. This section explains the example contract in more detail.

    +

    There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:

    +
      +
    1. Fork the code from the example repository listed above.
    2. +
    3. Perform any customization changes necessary on your personal fork of the example contract.
    4. +
    5. Compile the customized code to Wasm.
    6. +
    7. Send the customized Wasm as a deploy to a Casper network.
    8. +
    +

    Installing Required Crates

    +

    This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:

    +
      +
    • casper_contract - A Rust library for writing smart contracts on Casper networks
    • +
    • casper_types - Types used to allow creation of Wasm contracts and tests for use on Casper networks
    • +
    • casper_erc20 - A library for developing Fungible Tokens for Casper networks
    • +
    +

    Here is the code snippet which imports those crates:

    +

    use casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};

    use casper_types::{CLValue, U256};

    +

    Note: In Rust, the keyword use is like an include statement in C/C++.

    +

    Initializing the Contract

    +

    Initializing the contract happens through the call() function inside the contract file. When you deploy the contract, you need to initialize it with a call() function and define name, symbol, decimals, and total_supply.

    +

    The code snippet for initializing the contract should look like this:

    +

    #[no_mangle]
    fn call() {
    let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);
    let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);
    let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);
    let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);

    let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();
    }

    +

    Contract Methods

    +

    This section briefly explains the contract methods used in the Casper Fungible Token contract.

    +

    To see the full implementation of the below contract methods, refer to the contract file in Github. If you have any questions, review the casper_erc20 library and the EIP-20 standard.

    +

    Also, for further unresolved issues please contact the Casper support team via the Discord channel.

    +

    Contract methods are:

    +
      +
    • allowance - Returns the amount of owner’s tokens allowed to be spent by the spender
    • +
    • approve - Allows a spender to transfer up to an amount of the direct caller’s tokens
    • +
    • balance_of - Returns the token balance of the owner
    • +
    • burn - Burns tokens, reducing the total supply.
    • +
    • change_security - An administrator-level entry point to manipulate security access granted to users
    • +
    • decimals - Returns the decimals of the token
    • +
    • decrease_allowance - Decrease the allotted allowance for an account approved to spend from an owner's token balance
    • +
    • increase_allowance - Increases the allotted allowance for an account approved to spend from an owner's token balance
    • +
    • mint - Mints additional tokens, increasing the total supply
    • +
    • name- Returns the name of the token
    • +
    • symbol - Returns the symbol of the token
    • +
    • total_supply - Returns the total supply of the token
    • +
    • transfer - Transfers an amount of tokens from the direct caller to a recipient
    • +
    • transfer_from - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner
    • +
    +

    Installing the Contract

    +

    After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the Sending Deploys to a Casper network using the Rust Client section to learn more about install contracts.

    +

    Deploy Prerequisites

    + +

    Basic Flow

    +

    Here are the basic steps to install the Casper Fungible Token contract on a Casper Network.

    + +

    Cloning the Token Contract

    +

    This step includes cloning and preparing the token contract for the deployment.

    +
      +
    1. Clone the Fungible Token contract from the repository.
    2. +
    +

    git clone https://github.com/casper-ecosystem/cep18.git

    +
      +
    1. +

      Make any necessary changes to the code for your customization requirements.

      +
    2. +
    3. +

      Compile the contract to create the target .wasm file and build the Wasm.

      +
    4. +
    +

    cd cep18
    make prepare
    make build-contracts

    +
      +
    1. Build and verify the compiled contract.
    2. +
    +

    make test

    +

    Getting an IP Address from a Testnet Peer

    +

    We will use a Testnet peer to send the deploy. Read the guide to acquiring a node address if needed.

    +

    Viewing the Network Status

    +

    This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query.

    +

    Getting the state root hash

    +

    Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the Node IP address taken from a Testnet peer.

    +
    casper-client get-state-root-hash --node-address http://<HOST:PORT>
    +

    Getting the account hash

    +

    Run the following command and supply the path to your public key in hexadecimal format to get the account hash.

    +
    casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"
    +

    Querying global state

    +

    Use the command template below to query the network status with regard to your account.

    +
    casper-client query-global-state \
    --node-address http://<HOST:PORT> \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    Installing the Contract

    +

    Now you can install the contract to the network and check how it behaves.

    +

    If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the note about gas price to understand more about payment amounts and gas price adjustments.

    +

    The Casper platform currently does not refund any tokens as part of sending a deploy. For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the Gas and the Casper Blockchain documentation for further details.

    +

    Use the following command template to deploy the contract:

    +
    casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --chain-name [NETWORK_NAME]] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [AMOUNT] \
    --session-path [WASM_FILE_PATH]/[File_Name].wasm
    --session-arg <"NAME:TYPE='VALUE'" OR "NAME:TYPE=null">
    +
      +
    • NETWORK_NAME: Use the relevant network name. Here we use 'casper-test'
    • +
    • PATH_TO_YOUR_KEY: Replace this with the actual path of your secret key
    • +
    • PAYMENT_AMOUNT: Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error
    • +
    • WASM FILE PATH: The session-path argument should point to the location of your compiled Fungible Token Wasm file
    • +
    +

    Here is a sample put-deploy command:

    +
    casper-client put-deploy \
    --node-address http://95.216.24.237:7777 \
    --chain-name casper-test \
    --secret-key "/home/ubuntu/secret_key.pem" \
    --payment-amount 1000000 \
    --session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"
    --session-arg "name='Token test', symbol='TEST', decimals:u8=10, total_supply:u256=1000"
    +

    Querying the Network Status

    +

    You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the viewing the network state section to execute this step with the new state root hash.

    +

    Verifying the Deploy

    +

    Now you can verify the sent deploy using the get-deploy command. This will output the details of the sent deploy.

    +
    casper-client get-deploy \
    --node-address http://<HOST:PORT> [DEPLOY_HASH]
    +

    Querying with Arguments

    +

    This step will narrow down the context and check the status of a specific entry point. You will use the details inside the Fungible Token contract to derive arguments.

    +

    Use the command template below to query the network state with arguments:

    +
    casper-client query-global-state \
    --node-address http://<HOST:PORT> \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "[CONTRACT_NAME/ARGUMENT]"
    +

    Example Deploy on Testnet

    +

    The following steps will guide you through the process with sample values and results.

    +

    Cloning the Fungible Token Contract

    +
    git clone https://github.com/casper-ecosystem/cep18.git
    +

    Getting an IP Address from a Testnet Peer

    +

    Use peers to get the node IP address.

    +

    Viewing the Network Status

    +

    Here is the command to query the state of the network:

    +
    casper-client query-global-state \
    --key account-hash-<account-address> \
    --node-address http://<HOST:PORT> \
    --state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f
    +

    Result:

    +

    This result contains the network state before the deploy. You can see the named-key field is empty since we haven't sent the deploy to the network yet.

    +
    Result from querying the network status
    + +
    {
    "id": 401803927542812599,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "merkle_proof": "[25564 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-<account-address> ",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-<account-address> ",
    "weight": 1
    }
    ],
    "main_purse": "uref-<hash>",
    "named_keys": []
    }
    }
    }
    }
    +
    +

    +

    Sending the Deploy

    +

    Send the Deploy containing your contract with this command:

    +
    casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --chain-name casper-test \
    --secret-key "/home/ubuntu/secret_key.pem" \
    --payment-amount 1000000 \
    --session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"
    --session-arg "name='Token test', symbol='TEST', decimals:u8=10, total_supply:u256=1000"
    +

    Result:

    +

    This command execution will output the deploy_hash of the applied deploy. We can use the deploy_hash to get the details of the deploy.

    +
    {
    "id": 931694842944790108,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "deploy_hash": "b00E59f8aBA5c7aB9...."
    }
    }
    +

    Viewing the Deploy Details

    +

    You can view the details of the sent deploy using the command below:

    +
    casper-client get-deploy \
    --node-address http://<HOST:PORT> \
    b00E59f8aBA5c7aB9.....
    +

    Result:

    +

    This contains the header, payment, and session details along with the execution results.

    +
      +
    • If the execution result field appears as "execution_results":[], it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network.
    • +
    +
    Result from querying the deploy
    + +
    {
    {
    "id": -870982079597140956,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "deploy": {
    "approvals": [
    {
    "signature": "[130 hex chars]",
    "signer": "017B8CE645c728......................."
    }
    ],
    "hash": "F9D4C649Fa78Da07E.......................",
    "header": {
    "account": "017B8CE645c7285.......................",
    "body_hash": "8eAEd6B7bCBB493d75d.......................",
    "chain_name": "casper-test",
    "dependencies": [],
    "gas_price": 1,
    "timestamp": "2022-01-04T15:14:29.203Z",
    "ttl": "30m"
    },
    "payment": {
    "ModuleBytes": {
    "args": [
    [
    "amount",
    {
    "bytes": "0500e8764817",
    "cl_type": "U512",
    "parsed": "100000000000"
    }
    ]
    ],
    "module_bytes": ""
    }
    },
    "session": {
    "ModuleBytes": {
    "args": [],
    "module_bytes": "[417800 hex chars]"
    }
    }
    },
    "execution_results": [
    {
    "block_hash": "d3644f0306F20fa6.......................",
    "result": {
    "Success": {
    "cost": "45040980830",
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-8cf5E4aCF51f54Eb5.......................",
    "transform": "Identity"
    },
    {
    "key": "hash-624dBE2395b9D9503FB.......................",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3Fe81B7b862E50C77.......................",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dC3A5c44A20b.......................",
    "transform": "Identity"
    },
    {
    "key": "balance-C051e7EC16e08De.......................",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324F865243.......................",
    "transform": "Identity"
    },
    {
    "key": "balance-C051e7EC16e08Def8b556",
    "transform": {
    "WriteCLValue": {
    "bytes": "06E07f3abEa001",
    "cl_type": "U512",
    "parsed": "1789897900000"
    }
    }
    },
    {
    "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",
    "transform": {
    "AddUInt512": "100000000000"
    }
    },
    {
    "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "",
    "cl_type": "Unit",
    "parsed": null
    }
    }
    },
    {
    "key": "account-hash-7f4bf39A3...................................................",
    "transform": {
    "AddKeys": [
    {
    "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",
    "name": "balances"
    }
    ]
    }
    },
    {
    "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "",
    "cl_type": "Unit",
    "parsed": null
    }
    }
    },
    {
    "key": "account-hash-7f4bf39A311...................................................",
    "transform": {
    "AddKeys": [
    {
    "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",
    "name": "allowances"
    }
    ]
    }
    },
    {
    "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "0400ca9A3B",
    "cl_type": "U256",
    "parsed": "1000000000"
    }
    }
    },
    {
    "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    },
    {
    "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "050000004353505254",
    "cl_type": "String",
    "parsed": "CSPRT"
    }
    }
    },
    {
    "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "08",
    "cl_type": "U8",
    "parsed": 8
    }
    }
    },
    {
    "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",
    "transform": {
    "WriteCLValue": {
    "bytes": "[188 hex chars]",
    "cl_type": "Any",
    "parsed": null
    }
    }
    },
    {
    "key": "account-hash-7f4bf39A311a7538d8C...................................................",
    "transform": "Identity"
    },
    {
    "key": "account-hash-7f4bf39A311a75...................................................",
    "transform": {
    "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"
    }
    },
    {
    "key": "account-hash-7f4bf39A311a7538...................................................",
    "transform": "Identity"
    },
    {
    "key": "account-hash-7f4bf39A311a7538d8C...................................................",
    "transform": {
    "WriteAccount": "account-hash-7f4bf39A311a75..................................................."
    }
    },
    {
    "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "",
    "cl_type": "Unit",
    "parsed": null
    }
    }
    },
    {
    "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",
    "transform": "WriteContractPackage"
    },
    {
    "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",
    "transform": "Identity"
    },
    {
    "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",
    "transform": "WriteContractWasm"
    },
    {
    "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",
    "transform": "WriteContract"
    },
    {
    "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",
    "transform": "WriteContractPackage"
    },
    {
    "key": "account-hash-7f4bf39A311a7538d8...................................................",
    "transform": {
    "AddKeys": [
    {
    "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",
    "name": "test_contract"
    }
    ]
    }
    },
    {
    "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",
    "transform": "Identity"
    },
    {
    "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",
    "transform": {
    "WriteCLValue": {
    "bytes": "[186 hex chars]",
    "cl_type": "Any",
    "parsed": null
    }
    }
    },
    {
    "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "04400cAa3b",
    "cl_type": "U256",
    "parsed": "1001000000"
    }
    }
    },
    {
    "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",
    "transform": "Identity"
    },
    {
    "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",
    "transform": {
    "WriteCLValue": {
    "bytes": "[186 hex chars]",
    "cl_type": "Any",
    "parsed": null
    }
    }
    },
    {
    "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "04C090c83b",
    "cl_type": "U256",
    "parsed": "1003000000"
    }
    }
    },
    {
    "key": "deploy-F9D4C649Fa78Da...................................................",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",
    "from": "account-hash-7f4bf39A311a...................................................",
    "gas": "45040980830",
    "source": "uref-C051e7EC16e08Def8b556F9...................................................",
    "transfers": []
    }
    }
    },
    {
    "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",
    "transform": "Identity"
    },
    {
    "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",
    "transform": {
    "WriteCLValue": {
    "bytes": "00",
    "cl_type": "U512",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",
    "transform": {
    "AddUInt512": "100000000000"
    }
    }
    ]
    },
    "transfers": []
    }
    }
    }
    ]
    }
    }
    +
    +

    +

    Querying Contract Entry Points

    +

    We will query the argument 'name' in this example.

    +
    casper-client query-global-state --node-address http://95.216.24.237:7777 \
    --state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \
    --key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \
    -q "test_contract/name"
    +

    Result:

    +

    You can see that the name is CasperTest in this example.

    +
    {
    "id": -3650676146668320186,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "block_header": null,
    "merkle_proof": "[80252 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    }
    }

    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep18/query/index.html b/1.5.X/resources/tokens/cep18/query/index.html new file mode 100644 index 000000000..9b4743a3d --- /dev/null +++ b/1.5.X/resources/tokens/cep18/query/index.html @@ -0,0 +1,59 @@ + + + + + +CEP-18 Contract Details | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Exploring the CEP-18 Contracts

    +

    This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:

    +
      +
    • +

      The Casper fungible token contract

      +
    • +
    • +

      The CEP-18 utility contract, which should appear in the NamedKeys of the account that sent the Deploy as cep18_test_contract

      +
    • +
    +

    Querying the Contract Package

    +

    We will need the contract package's contract_hash to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's NamedKeys, under the name given during the installation process.

    +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    // This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.
    --key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \
    // This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +
    Casper client command without comments
    + +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    --key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +
    +

    This will return the Contract Package object:

    +
    {
    "id": -1489823435760214673,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block_header": null,
    "merkle_proof": "[2048 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }
    +
      +
    • Note - In the contract_hash field, the hash value represents the stored contract which we will invoke later.
    • +
    +

    Querying the Utility Contract

    +

    In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called result. You can find this URef in the NamedKeys of the utility contract.

    +

    First, you will need to query the cep18_test_contract hash found within the installing account's NamedKeys:

    +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    // This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`
    --key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +
    Casper client command without comments
    + +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    --key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +
    +

    Which should return information similar to the following:

    +

    {
    "id": 5359405942597097786,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block_header": null,
    "merkle_proof": "[2048 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }

    +

    You will need to take the contract_hash value and replace contract with hash to run another `query-global-state:

    +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    --key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +

    Which will return the full cep18_test_contract information. The following snippet is condensed to show only the NamedKeys, but you should also see the entry_points when you run the command. You should see the URef result, which will be used to view the results of any checks run through the utility contract.

    +
    {
    "id": -1426549275795832481,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block_header": null,
    "merkle_proof": "[3370 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",
    "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",
    "named_keys": [
    {
    "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",
    "name": "result"
    }
    ],
    "protocol_version": "1.0.0"
    }
    }
    }
    }

    +

    Next Steps

    +
    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep18/quickstart-guide/index.html b/1.5.X/resources/tokens/cep18/quickstart-guide/index.html new file mode 100644 index 000000000..e7141dde8 --- /dev/null +++ b/1.5.X/resources/tokens/cep18/quickstart-guide/index.html @@ -0,0 +1,63 @@ + + + + + +On-chain Installation | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Installing and Interacting with a CEP-18 Contract

    +

    This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.

    +

    The Ethereum Request for Comment (ERC-20) standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded.

    +

    To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions.

    +

    For greater detail into the creation and mechanics of the Casper fungible token contract, see the full Casper Fungible Token Tutorial.

    +

    Prerequisites

    +

    Before using this guide, ensure you meet the following requirements:

    +
      +
    • Set up your machine as per the prerequisites
    • +
    • Use the [Casper command-line client]
    • +
    • Get a valid node-address
    • +
    • Know how to deploy a smart contract to a Casper network
    • +
    • Hold enough CSPR tokens to pay for transactions
    • +
    +

    Setup

    +

    Clone the fungible token (CEP-18) contract repository and run the make build-contract command. This will create the cep18.wasm and the cep18_test_contract.wasm. The token Wasm is the main contract. We will use the cep18_test_contract Wasm to query the balances and allowances of the fungible token balances throughout this workflow.

    +

    Install the Main Fungible Token Contract

    +

    The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:

    +
      +
    • Name - The name of your CEP-18 token
    • +
    • Symbol - The symbol used to refer to your CEP-18 token
    • +
    • Total_supply - The total supply of the CEP-18 token to be minted
    • +
    • Decimals - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a decimals setting of 3 would be 1,000.000 tokens)
    • +
    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18.wasm \
    --session-arg "name:string='CEP18'" \
    --session-arg "symbol:string='gris'" \
    --session-arg "total_supply:u256='100'" \
    --session-arg "decimals:u8='1'" \
    --payment-amount 150000000000
    +

    Install the cep18_test_contract Contract Package

    +

    The following command will install the CEP-18 helper contract that allows you to check balances and access approval features.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18_test_contract.wasm \
    --payment-amount 50000000000
    +

    At this point, the account that installed both the main contract and the helper contract will look like this.

    +
    {
    "src": {
    "Account": {
    "_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "namedKeys": [
    {
    "name": "cep18_test_contract",
    "key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"
    },
    {
    "name": "cep18_token_contract",
    "key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"
    },
    ],
    "mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",
    "associatedKeys": [
    {
    "accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "weight": 1
    }
    ],
    "actionThresholds": {
    "deployment": 1,
    "keyManagement": 1
    }
    }
    }
    }
    +

    Note:

    +
    +
      +
    1. cep18_token_contract is the main contract, and is a stored contract, record its hash
    2. +
    3. cep18_test_call is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state.
    4. +
    +
    +

    Next Steps

    +

    In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals.

    +
    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep18/tests/index.html b/1.5.X/resources/tokens/cep18/tests/index.html new file mode 100644 index 000000000..540fcee05 --- /dev/null +++ b/1.5.X/resources/tokens/cep18/tests/index.html @@ -0,0 +1,80 @@ + + + + + +Testing Guide | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Testing Framework for CEP-18

    +

    The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.

    +

    The following section reviews the GitHub testing folder, which creates a testing framework for the Casper Fungible Token project. You can find more details about testing Casper contracts here.

    +

    The following is an example of a complete test expecting a failed transfer:

    +
    #[should_panic(expected = "ApiError::User(65534) [131070]")]
    #[test]
    fn should_not_transfer_with_insufficient_balance() {
    let mut fixture = TestFixture::install_contract();

    let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();
    assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);

    fixture.transfer(
    Key::from(fixture.bob),
    initial_ali_balance + U256::one(),
    fixture.ali,
    );
    }
    +

    To build and run the tests, issue the following command in the project folder, cep18:

    +
    make test
    +

    The project contains a Makefile, which is a custom build script that compiles the contract before running tests in release mode. Then, the script copies the contract.wasm file to the tests/wasm directory. In practice, you only need to run the make test command during development.

    +

    Configuring the Test Package

    +

    In this project, we define a tests package using the tests/Cargo.toml file.

    +
    [package]
    name = "tests"
    version = "1.0.0"
    ...

    [dependencies]
    casper-types = "2.0.0"
    casper-engine-test-support = "4.0.0"
    casper-execution-engine = "4.0.0"
    once_cell = "1.16.0"

    [lib]
    name = "tests"
    ...
    +

    Testing Logic

    +

    In Github, you will find an example containing a Casper Fungible Token contract implementation with the corresponding tests. The tests follow this sequence:

    +
      +
    • Step 1 - Specify the starting state of the blockchain.
    • +
    • Step 2 - Deploy the compiled contract to the blockchain and query it.
    • +
    • Step 3 - Create additional deploys for calling each of the entrypoints in the contract.
    • +
    +

    The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints.

    +

    Setting up the Testing Context

    +

    The code in the utility directory initializes the blockchain's global state with all the data and entrypoints the smart contract needs.

    +

    Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the constants.rs file within the utility directory. For the most up-to-date version of the code, visit GitHub.

    +
    Example of required constants
    + +
    // File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs

    use casper_engine_test_support::{
    ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
    MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,
    };
    use casper_execution_engine::core::engine_state::ExecuteRequest;
    use casper_types::{
    account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,
    };

    use crate::utility::constants::{
    ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,
    };

    use super::constants::{
    ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,
    };
    +
    +

    Installing the Contract

    +

    The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a TestContext of its own. The contract_hash and the session_code won’t change after the contract is deployed, so it is good to keep them handy.

    +

    This code snippet builds the context and includes the compiled contract .wasm binary being tested. The TestContext struct creates a new instance of the cep18_token with several test accounts.

    +

    Note: These accounts have a positive initial balance.

    +

    The full and most recent code implementation is available on GitHub.

    +
    Example of a CEP-18 token in a test
    + +
    // File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs

    // Creating the `TestContext` struct.

    pub(crate) struct TestContext {
    pub(crate) cep18_token: ContractHash,
    pub(crate) cep18_test_contract_package: ContractPackageHash,
    }

    // Setting up the test instance of CEP-18.

    pub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {
    setup_with_args(runtime_args! {
    ARG_NAME => TOKEN_NAME,
    ARG_SYMBOL => TOKEN_SYMBOL,
    ARG_DECIMALS => TOKEN_DECIMALS,
    ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),
    })
    }

    // Establishing test accounts.

    pub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {
    let mut builder = InMemoryWasmTestBuilder::default();
    builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);

    let id: Option<u64> = None;
    let transfer_1_args = runtime_args! {
    mint::ARG_TARGET => *ACCOUNT_1_ADDR,
    mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,
    mint::ARG_ID => id,
    };
    let transfer_2_args = runtime_args! {
    mint::ARG_TARGET => *ACCOUNT_2_ADDR,
    mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,
    mint::ARG_ID => id,
    };

    let transfer_request_1 =
    ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();
    let transfer_request_2 =
    ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();

    // Installing the test version of CEP-18 with the default account.

    let install_request_1 =
    ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)
    .build();

    let install_request_2 = ExecuteRequestBuilder::standard(
    *DEFAULT_ACCOUNT_ADDR,
    CEP18_TEST_CONTRACT_WASM,
    RuntimeArgs::default(),
    )
    .build();

    builder.exec(transfer_request_1).expect_success().commit();
    builder.exec(transfer_request_2).expect_success().commit();
    builder.exec(install_request_1).expect_success().commit();
    builder.exec(install_request_2).expect_success().commit();

    let account = builder
    .get_account(*DEFAULT_ACCOUNT_ADDR)
    .expect("should have account");

    let cep18_token = account
    .named_keys()
    .get(CEP18_TOKEN_CONTRACT_KEY)
    .and_then(|key| key.into_hash())
    .map(ContractHash::new)
    .expect("should have contract hash");

    let cep18_test_contract_package = account
    .named_keys()
    .get(CEP18_TEST_CONTRACT_KEY)
    .and_then(|key| key.into_hash())
    .map(ContractPackageHash::new)
    .expect("should have contract package hash");

    let test_context = TestContext {
    cep18_token,
    cep18_test_contract_package,
    };

    (builder, test_context)
    }
    +
    +

    Creating Helper Functions

    +

    The previous step has simulated sending a real deploy on the network. The next code snippet in installer_request_builders.rs defines helper functions that will be used throughout the testing framework:

    +
      +
    • cep18_check_total_supply - A function for testing the total supply of the CEP-18 contract instance.
    • +
    • cep18_check_balance_of - A function for checking an account's balance of CEP-18 tokens.
    • +
    • cep18_check_allowance_of - A function for checking an account's spending allowance from another account's balance.
    • +
    +

    These are followed by functions that check specific aspects of the CEP-18 contract. These include test_cep18_transfer, make_cep18_approve_request and test_approve_for.

    +

    The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in contract installation:

    +
    Example helper function
    + +
    // File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs

    pub(crate) fn test_cep18_transfer(
    builder: &mut InMemoryWasmTestBuilder,
    test_context: &TestContext,
    sender1: Key,
    recipient1: Key,
    sender2: Key,
    recipient2: Key) {
    let TestContext { cep18_token, .. } = test_context;

    // Defining the amount to be transferred to each account.

    let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);
    let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);

    // Checking the pre-existing balances of the default address and the two receiving addresses.

    let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);
    assert_ne!(sender_balance_before, U256::zero());

    let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);
    assert_eq!(account_1_balance_before, U256::zero());

    let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);
    assert_eq!(account_2_balance_before, U256::zero());

    // Creating the first transfer request.

    let token_transfer_request_1 =
    make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);

    builder
    .exec(token_transfer_request_1)
    .expect_success()
    .commit();

    // Checking the prior balance against the new balance to ensure the transfer occurred correctly.

    let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);
    assert_eq!(account_1_balance_after, transfer_amount_1);
    let account_1_balance_before = account_1_balance_after;

    let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);
    assert_eq!(
    sender_balance_after,
    sender_balance_before - transfer_amount_1
    );
    let sender_balance_before = sender_balance_after;

    // Creating the second transfer request.

    let token_transfer_request_2 =
    make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);

    builder
    .exec(token_transfer_request_2)
    .expect_success()
    .commit();

    // Checking prior balances against new balances.

    let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);
    assert_eq!(sender_balance_after, sender_balance_before);

    let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);
    assert!(account_1_balance_after < account_1_balance_before);
    assert_eq!(
    account_1_balance_after,
    transfer_amount_1 - transfer_amount_2
    );

    let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);
    assert_eq!(account_2_balance_after, transfer_amount_2);
    }
    +
    +

    Creating Unit Tests

    +

    Within this testing context, the tests directory includes a variety of unit tests, which verify the contract code by invoking the functions defined in the installer_request_builders.rs file.

    +

    The example below shows one of the tests. Visit GitHub to find all the available tests.

    +
    Example test querying token properties
    + +
    // File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs

    use casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;
    use casper_types::{Key, U256};

    use crate::utility::{
    constants::{
    ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,
    TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,
    },
    installer_request_builders::{
    cep18_check_balance_of, invert_cep18_address, setup, TestContext,
    },
    };

    #[test]
    fn should_have_queryable_properties() {
    let (mut builder, TestContext { cep18_token, .. }) = setup();

    let name: String = builder.get_value(cep18_token, NAME_KEY);
    assert_eq!(name, TOKEN_NAME);

    let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);
    assert_eq!(symbol, TOKEN_SYMBOL);

    let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);
    assert_eq!(decimals, TOKEN_DECIMALS);

    let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);
    assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));

    let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);

    let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);
    assert_eq!(owner_balance, total_supply);

    let contract_balance =
    cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));
    assert_eq!(contract_balance, U256::zero());

    // Ensures that Account and Contract ownership is respected and we're not keying ownership under
    // the raw bytes regardless of variant.
    let inverted_owner_key = invert_cep18_address(owner_key);
    let inverted_owner_balance =
    cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);
    assert_eq!(inverted_owner_balance, U256::zero());
    }
    +
    +

    Running the Tests

    +

    The lib.rs file is configured to run the example integration tests via the make test command:

    +
    #[cfg(test)]
    mod allowance;
    #[cfg(test)]
    mod install;
    #[cfg(test)]
    mod mint_and_burn;
    #[cfg(test)]
    mod transfer;
    #[cfg(test)]
    mod utility;
    +

    To run the tests, navigate to the parent cep18 directory and run the command:

    +
    make test
    +

    This example uses bash. If you are using a Rust IDE, you need to configure it to run the tests.

    + + \ No newline at end of file diff --git a/next/resources/tokens/cep18/transfer/index.html b/1.5.X/resources/tokens/cep18/transfer/index.html similarity index 81% rename from next/resources/tokens/cep18/transfer/index.html rename to 1.5.X/resources/tokens/cep18/transfer/index.html index de4e77a48..528752112 100644 --- a/next/resources/tokens/cep18/transfer/index.html +++ b/1.5.X/resources/tokens/cep18/transfer/index.html @@ -1,22 +1,22 @@ - + -CEP-18 Transfers | Casper Docs - Redux +CEP-18 Transfers | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    CEP-18 Token Transfers and Allowances

    -

    This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.

    + submit an issue on Github
    Version: 1.5.X

    CEP-18 Token Transfers and Allowances

    +

    This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.

    Transferring CEP-18 Tokens to Another Account

    The following command will invoke the transfer entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account.

    casper-client put-deploy -n http://<node IP>:<PORT> \
    // The chain name of the Casper network on which your CEP-18 instance was installed.
    --chain-name <CHAIN NAME>\
    // The local path to your account's secret key.
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    // The contract hash of your CEP-18 contract instance.
    --session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \
    // The name of the entry point you are invoking.
    --session-entry-point "transfer" \
    // The account hash of the account that you are sending CEP-18 tokens to.
    --session-arg "recipient:key='account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \
    // The amount of CEP-18 tokens you are sending to the receiving account.
    --session-arg "amount:u256='10'" \
    // The gas payment you are allotting, in motes.
    --payment-amount "10000000000"
    @@ -32,7 +32,7 @@

    casper-client put-deploy -n http://<node IP>:<PORT>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_test_contract" \
    --session-entry-point "check_balance_of" \
    --session-arg "token_contract:account_hash='account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180'" \
    --session-arg "address:key='account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000

    -

    After sending this command, you will need to query the results URef within the NamedKeys of your cep18_test_contract utility contract instance. More information on finding this URef can be found in the Exploring the CEP18 Contracts document.

    +

    After sending this command, you will need to query the results URef within the NamedKeys of your cep18_test_contract utility contract instance. More information on finding this URef can be found in the Exploring the CEP18 Contracts document.

    You can use the following command to query global state for the results URef.

    casper-client query-global-state -n http://<NODE IP>:<PORT> \
    // This is the `results` URef location from your `cep18_test_contract` `NamedKeys`
    --key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \
    --state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7
    Casper client command without comments
    @@ -129,7 +129,7 @@

    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "change_security" \
    /// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.
    --session-arg "none_list:string:'<List of account hashes>'" \
    --session-arg "admin_list:string:'<List of account hashes>'" \
    --session-arg "mint_and_burn_list:string:'<List of account hashes>'" \
    --session-arg "burner_list:string:'<List of account hashes>'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000

    Next Steps

    +
  • Testing Framework for CEP-18
  • +
    \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/introduction/index.html b/1.5.X/resources/tokens/cep78/introduction/index.html new file mode 100644 index 000000000..86c4b11c6 --- /dev/null +++ b/1.5.X/resources/tokens/cep78/introduction/index.html @@ -0,0 +1,782 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    CEP-78 Enhanced NFT Standard Introduction

    +

    Usage

    +

    Building the Contract

    +

    The main.rs file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the make build-contract command from the Makefile provided.

    +

    The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the make build-contract command provided in the Makefile. Please note, however, that you must install wasm-strip to build the contract.

    +

    The call method will install the contract with the necessary entrypoints and call the init() entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation.

    +

    The Full Installation Tutorial provides a step-by-step workflow.

    +

    Required Runtime Arguments

    +

    The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the Modalities documentation.

    +
      +
    • "collection_name": The name of the NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
    • +
    • "collection_symbol": The symbol representing a given NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
    • +
    • "total_token_supply": The total number of NFTs that a specific instance of a contract will mint passed in as a U64 value. This parameter is required.
    • +
    • "ownership_mode": The OwnershipMode modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "nft_kind": The NFTKind modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "json_schema": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a String. This parameter is required if the metadata kind is set to CustomValidated(3) and cannot be changed post installation.
    • +
    • "nft_metadata_kind": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "identifier_mode": The NFTIdentifierMode modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "metadata_mutability": The MetadataMutability modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    +

    The following are the optional parameters that can be passed in at the time of installation.

    +
      +
    • +

      "minting_mode": The MintingMode modality that dictates the access to the mint() entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      "allow_minting": The "allow_minting" flag allows the installer of the contract to pause the minting of new NFTs. The allow_minting is a boolean toggle that allows minting when true. If not provided at install the toggle will default to true. This value can be changed by the installer by calling the set_variables() entrypoint.

      +
    • +
    • +

      "whitelist_mode": The WhitelistMode modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      "holder_mode": The NFTHolderMode modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either Accounts or Contracts to hold NFTs. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      "contract_whitelist": The contract whitelist is a list of contract hashes that specifies which contracts can call the mint() entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the set_variables post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail.

      +
    • +
    • +

      "burn_mode": The BurnMode modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      "events_mode": The EventsMode modality selects the event schema used to record any changes that occur to tokens issued by the contract instance.

      +
    • +
    • +

      "additional_required_metdata": An additional metadata schema that must be included. This argument is passed in as a u8 value.

      +
    • +
    • +

      "optional_metdata": An optional metadata schema that may be included. This argument is passed in as a u8 value.

      +
    • +
    +

    Example deploy

    +

    The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

    +
    casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='enhanced-nft-1'" \
    --session-arg "collection_symbol:string='ENFT-1'" \
    --session-arg "total_token_supply:u64='10'" \
    --session-arg "ownership_mode:u8='0'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "allow_minting:bool='true'" \
    --session-arg "owner_reverse_lookup_mode:u8='0'" \
    --session-arg "nft_metadata_kind:u8='2'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='1'"
    +

    Utility Session Code

    +

    Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary. +In order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that +users and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the client +folder within the project folder.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Entrypoint nameSession code
    "mint"client/mint_session
    "balance_of"client/balance_of_session
    "get_approvedclient/get_approved_session
    "owner_of"client/owner_of_session
    "transfer"client/transfer_session
    +

    Checking Token Ownership

    +

    Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

    +

    Upgrading to Version 1.1.1

    +

    Upgrade to v1.1.1 using a Standard NamedKey Convention or a Custom NamedKey Convention.

    +

    Installing and Interacting with the Contract using the Rust Casper Client

    +

    You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

    +

    Test Suite and Specification

    +

    The expected behavior of the NFT contract implementation is asserted by its test suite found in the tests folder. +The test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors +of the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite +ensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced. +The test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run +by using the provided Makefile and running the make test command.

    +

    Error Codes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeError
    1InvalidAccount
    2MissingInstaller
    3InvalidInstaller
    4UnexpectedKeyVariant
    5MissingTokenOwner
    6InvalidTokenOwner
    7FailedToGetArgBytes
    8FailedToCreateDictionary
    9MissingStorageUref
    10InvalidStorageUref
    11MissingOwnerUref
    12InvalidOwnersUref
    13FailedToAccessStorageDictionary
    14FailedToAccessOwnershipDictionary
    15DuplicateMinted
    16FailedToConvertCLValue
    17MissingCollectionName
    18InvalidCollectionName
    19FailedToSerializeMetaData
    20MissingAccount
    21MissingMintingStatus
    22InvalidMintingStatus
    23MissingCollectionSymbol
    24InvalidCollectionSymbol
    25MissingTotalTokenSupply
    26InvalidTotalTokenSupply
    27MissingTokenID
    28InvalidTokenIdentifier
    29MissingTokenOwners
    30MissingAccountHash
    31InvalidAccountHash
    32TokenSupplyDepleted
    33MissingOwnedTokensDictionary
    34TokenAlreadyBelongsToMinterFatal
    35FatalTokenIdDuplication
    36InvalidMinter
    37MissingMintingMode
    38InvalidMintingMode
    39MissingInstallerKey
    40FailedToConvertToAccountHash
    41InvalidBurner
    42PreviouslyBurntToken
    43MissingAllowMinting
    44InvalidAllowMinting
    45MissingNumberOfMintedTokens
    46InvalidNumberOfMintedTokens
    47MissingTokenMetaData
    48InvalidTokenMetaData
    49MissingApprovedAccountHash
    50InvalidApprovedAccountHash
    51MissingApprovedTokensDictionary
    52TokenAlreadyApproved
    53MissingApproveAll
    54InvalidApproveAll
    55MissingOperator
    56InvalidOperator
    57Phantom
    58ContractAlreadyInitialized
    59MintingIsPaused
    60FailureToParseAccountHash
    61VacantValueInDictionary
    62MissingOwnershipMode
    63InvalidOwnershipMode
    64InvalidTokenMinter
    65MissingOwnedTokens
    66InvalidAccountKeyInDictionary
    67MissingJsonSchema
    68InvalidJsonSchema
    69InvalidKey
    70InvalidOwnedTokens
    71MissingTokenURI
    72InvalidTokenURI
    73MissingNftKind
    74InvalidNftKind
    75MissingHolderMode
    76InvalidHolderMode
    77MissingWhitelistMode
    78InvalidWhitelistMode
    79MissingContractWhiteList
    80InvalidContractWhitelist
    81UnlistedContractHash
    82InvalidContract
    83EmptyContractWhitelist
    84MissingReceiptName
    85InvalidReceiptName
    86InvalidJsonMetadata
    87InvalidJsonFormat
    88FailedToParseCep78Metadata
    89FailedToParse721Metadata
    90FailedToParseCustomMetadata
    91InvalidCEP78Metadata
    92FailedToJsonifyCEP78Metadata
    93InvalidNFT721Metadata
    94FailedToJsonifyNFT721Metadata
    95InvalidCustomMetadata
    96MissingNFTMetadataKind
    97InvalidNFTMetadataKind
    98MissingIdentifierMode
    99InvalidIdentifierMode
    100FailedToParseTokenId
    101MissingMetadataMutability
    102InvalidMetadataMutability
    103FailedToJsonifyCustomMetadata
    104ForbiddenMetadataUpdate
    105MissingBurnMode
    106InvalidBurnMode
    107MissingHashByIndex
    108InvalidHashByIndex
    109MissingIndexByHash
    110InvalidIndexByHash
    111MissingPageTableURef
    112InvalidPageTableURef
    113MissingPageLimit
    114InvalidPageLimit
    115InvalidPageNumber
    116InvalidPageIndex
    117MissingUnmatchedHashCount
    118InvalidUnmatchedHashCount
    119MissingPackageHashForUpgrade
    120MissingPageUref
    121InvalidPageUref
    122CannotUpgradeWithZeroSupply
    123CannotInstallWithZeroSupply
    124MissingMigrationFlag
    125InvalidMigrationFlag
    126ContractAlreadyMigrated
    127UnregisteredOwnerInMint
    128UnregisteredOwnerInTransfer
    129MissingReportingMode
    130InvalidReportingMode
    131MissingPage
    132UnregisteredOwnerFromMigration
    133ExceededMaxTotalSupply
    134MissingCep78PackageHash
    135InvalidCep78InvalidHash
    136InvalidPackageHashName
    137InvalidAccessKeyName
    138InvalidCheckForUpgrade
    139InvalidNamedKeyConvention
    140OwnerReverseLookupModeNotTransferable
    141InvalidAdditionalRequiredMetadata
    142InvalidOptionalMetadata
    143MissingOptionalNFTMetadataKind
    144InvalidOptionalNFTMetadataKind
    145MissingAdditionalNFTMetadataKind
    146InvalidAdditionalNFTMetadataKind
    147InvalidRequirement
    148MissingEventsMode
    149InvalidEventsMode
    150CannotUpgradeToMoreSupply
    151MissingOperatorDict
    152MissingApprovedDict
    153MissingSpenderAccountHash
    154InvalidSpenderAccountHash
    155MissingOwnerTokenIdentifierKey
    156InvalidTransferFilterContract
    157MissingTransferFilterContract
    158TransferFilterContractNeedsTransferableMode
    159TransferFilterContractDenied
    160MissingACLWhiteList
    161InvalidACLWhitelist
    162EmptyACLWhitelist
    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/js-tutorial/index.html b/1.5.X/resources/tokens/cep78/js-tutorial/index.html new file mode 100644 index 000000000..a33b3cef0 --- /dev/null +++ b/1.5.X/resources/tokens/cep78/js-tutorial/index.html @@ -0,0 +1,143 @@ + + + + + +CEP-78 JavaScript Client | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    CEP-78 JavaScript Client Tutorial

    +

    This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.

    +

    Further information on the CEP-78 Enhanced NFT Standard can be found here.

    +

    The client is available in npm as casper-cep78-js-client.

    +

    Client Installation

    +

    The client can be installed in a project you have built using TypeScript / Javascript.

    +

    To install run:

    +
    npm install casper-cep78-js-client
    +

    Installing a CEP-78 Contract using the JavaScript Client

    +

    The install method crafts a Deploy using InstallArgs. +As with every deploy created by the SDK, you can send it using the .send(rpcUrl) method providing the RPC URL that you want to use. It will return deployHash.

    +

    const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);

    const installDeploy = await cc.install(
    {
    collectionName: "my-collection",
    collectionSymbol: "MY-NFTS",
    totalTokenSupply: "1000",
    ownershipMode: NFTOwnershipMode.Transferable,
    nftKind: NFTKind.Physical,
    jsonSchema: {
    properties: {
    color: { name: "color", description: "", required: true },
    size: { name: "size", description: "", required: true },
    material: { name: "material", description: "", required: true },
    condition: { name: "condition", description: "", required: false },
    },
    },
    nftMetadataKind: NFTMetadataKind.CustomValidated,
    identifierMode: NFTIdentifierMode.Ordinal,
    metadataMutability: MetadataMutability.Immutable,
    mintingMode: MintingMode.Installer,
    ownerReverseLookupMode: OwnerReverseLookupMode.Complete
    },
    "250000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);

    +

    InstallArgs are specified as follows:

    +
      +
    • +

      collectionName - The name of the NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.

      +
    • +
    • +

      collectionSymbol - The symbol representing a given NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.

      +
    • +
    • +

      totalTokenSupply - The total number of NFTs that a specific contract instance will mint passed in as a U64 value. This parameter is required and cannot be changed post installation.

      +
    • +
    • +

      ownershipMode - The OwnershipMode modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.

      +
    • +
    • +

      nftKind - The NFTKind modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a u8 value and is required at the time of installation.

      +
    • +
    • +

      jsonSchema - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a String. More information on NFTMetadataKind can be found here. This parameter may be left empty if metadata kind is set to Raw(3). If the metadata kind is set to CustomValidated(4), it will require a specifically formatted custom schema. This parameter cannot be changed post installation.

      +
    • +
    • +

      nftMetadataKind - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.

      +
    • +
    • +

      identifierMode - The NFTIdentifierMode modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a u8 value and is required at the time of installation.

      +
    • +
    • +

      metadataMutability - The MetadataMutability modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a u8 value and is required at the time of installation.

      +
    • +
    • +

      mintingmode - The MintingMode modality dictates the access to the mint() entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      holdermode - The NFTHolderMode modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either Accounts or Contracts to hold NFTs. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      burnMode - The BurnMode modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.

      +
    • +
    • +

      ownerReverseLookupMode - The OwnerReverseLookupMode dictates whether the contract will index ownership of tokens as outlined here to allow lookup of owned tokens by account. This parameter cannot be changed once the contract has been installed.

      +
    • +
    +

    Further information on CEP-78 modality options can be found here.

    +

    Minting a Token

    +

    The CEP-78 JS Client includes code to construct a deploy that will Mint a token, as follows:

    +

    const mintDeploy = cc.mint(
    {
    owner: FAUCET_KEYS.publicKey,
    meta: {
    color: "Blue",
    size: "Medium",
    material: "Aluminum",
    condition: "Used",
    },
    },
    { useSessionCode: true },
    "2000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");

    +

    The arguments adhere to those provided in the original installation, with the .send() pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL.

    +

    In this example, the useSessionCode variable decides if the user will call mint using session code, or not. It will be set to true if the OwnerReverseLookupMode is set to Complete. It then registers the recipient with the contract and mints the token.

    +

    If OwnerReverseLookupMode is set to NoLookup, useSessionCode will be set to false and it will simply mint the token as it does not need to register the recipient.

    +

    Register Recipient

    +

    As we used ownerReverseLookupMode: OwnerReverseLookupMode.Complete in this contract installation, we must register the recipient. To do this, we construct a register deploy:

    +

    const registerDeploy = cc.register(
    {
    tokenOwner: USER1_KEYS.publicKey,
    },
    "1000000000",
    USER1_KEYS.publicKey,
    [USER1_KEYS]
    );

    const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");

    +

    Transferring a Token

    +

    After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:

    +

    const transferDeploy = cc.transfer(
    {
    tokenId: "0",
    source: FAUCET_KEYS.publicKey,
    target: USER1_KEYS.publicKey,
    },
    { useSessionCode: true },
    "13000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");

    +

    Transferring accepts the following arguments:

    +
      +
    • +

      tokenId - The sequential ID assigned to a token in mint order.

      +
    • +
    • +

      source - The account sending the token in question.

      +
    • +
    • +

      target - The account receiving the transferred token.

      +
    • +
    +

    As above, the useSessionCode variable determines if the user will call transfer using session code based on the setting of OwnerReverseLookupMode.

    +

    Burning a Token

    +

    The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the tokenId argument:

    +

    const burnDeploy = await contractClient.burn(
    { tokenId: "0" },
    "13000000000",
    USER1_KEYS.publicKey,
    [USER1_KEYS]
    );

    const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");

    +

    Example Usages

    +

    Running an Install Example

    +

    This repository includes an example script for installing a CEP-78 contract instance.

    +

    You will need to define the following variables in the .env file:

    +
      +
    • +

      NODE_URL - The address of a node. If you are testing using NCTL, this will be http://localhost:11101/rpc.

      +
    • +
    • +

      NETWORK_NAME - The name of the Casper network you are operating on, casper-net-1 when testing using a local network with NCTL.

      +
    • +
    • +

      MASTER_KEY_PAIR_PATH - The path to the key pair of the minting account.

      +
    • +
    • +

      USER1_KEY_PAIR_PATH - The path to an additional account's key pair for use in testing transfer features.

      +
    • +
    +

    You may also need to install associated dependencies using:

    +
    npm i
    +

    This example can be run using the following command:

    +
    npm run example:install
    +

    The example will then return the installation's deployHash, and inform you when the installation is successful.

    +

    The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash.

    +

    Running a Usage Example

    +

    A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation.

    +

    The usage example can be run using the following command:

    +
    npm run example:usage
    +

    This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:

    +
      +
    • +

      Mint - The example will attempt to mint an NFT using the installation account.

      +
    • +
    • +

      Transfer - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)

      +
    • +
    • +

      Burn - The example will burn the minted NFT.

      +
    • +
    +

    The associated code for these deploys may be found in the client-js/examples directory.

    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/modalities/index.html b/1.5.X/resources/tokens/cep78/modalities/index.html new file mode 100644 index 000000000..a32fb5793 --- /dev/null +++ b/1.5.X/resources/tokens/cep78/modalities/index.html @@ -0,0 +1,522 @@ + + + + + +CEP-78 Modalities | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    CEP-78 Modalities

    +

    The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.

    +

    Ownership

    +

    This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:

    +
      +
    1. Minter: Minter mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the Minter mode the owner of the NFT will not change and thus cannot be transferred to another entity.
    2. +
    3. Assigned: Assigned mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the Minter mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another.
    4. +
    5. Transferable: In the Transferable mode the owner of the newly minted NFT must be specified by the minter. However, in the Transferable mode, NFTs can be transferred from the owner to another entity.
    6. +
    +

    In all the three mentioned modes, the owner entity is currently restricted to Accounts on the Casper network.

    +

    Note: In the Transferable mode, it is possible to transfer the NFT to an Account that does not exist.

    +

    This Ownership mode is a required installation parameter and cannot be changed once the contract has been installed. +The mode is passed in as u8 value to the "ownership_mode" runtime argument.

    + + + + + + + + + + + + + + + + + + + + + +
    Ownershipu8
    Minter0
    Assigned1
    Transferable2
    +

    The ownership mode of a contract can be determined by querying the ownership_mode entry within the contract's NamedKeys.

    +

    NFTKind

    +

    The NFTKind modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the NFTKind modality does not alter or govern the behavior of the contract itself +and only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the NFTKind mode.

    +
      +
    1. Physical: The NFT represents a real-world physical item e.g., a house.
    2. +
    3. Digital: The NFT represents a digital item, e.g., a unique JPEG or digital art.
    4. +
    5. Virtual: The NFT is the virtual representation of a physical notion, e.g., a patent or copyright.
    6. +
    +

    The NFTKind mode is a required installation parameter and cannot be changed once the contract has been installed. +The mode is passed in as a u8 value to nft_kind runtime argument.

    + + + + + + + + + + + + + + + + + + + + + +
    NFTKindu8
    Physical0
    Digital1
    Virtual2
    +

    NFTHolderMode

    +

    The NFTHolderMode dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:

    +
      +
    1. Accounts: In this mode, only Accounts can own and mint NFTs.
    2. +
    3. Contracts: In this mode, only Contracts can own and mint NFTs.
    4. +
    5. Mixed: In this mode both Accounts and Contracts can own and mint NFTs.
    6. +
    +

    If the NFTHolderMode is set to Contracts a ContractHash whitelist must be provided. This whitelist dictates which +Contracts are allowed to mint NFTs in the restricted Installer minting mode.

    + + + + + + + + + + + + + + + + + + + + + +
    NFTHolderModeu8
    Accounts0
    Contracts1
    Mixed2
    +

    This modality is an optional installation parameter and will default to the Mixed mode if not provided. However, this +mode cannot be changed once the contract has been installed. +The mode is passed in as a u8 value to nft_holder_mode runtime argument.

    +

    WhitelistMode

    +

    The WhitelistMode dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:

    +
      +
    1. Unlocked: The ACL whitelist is unlocked and can be updated via the set variables endpoint.
    2. +
    3. Locked: The ACL whitelist is locked and cannot be updated further.
    4. +
    +

    If the WhitelistMode is set to Locked an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ACL minting mode. These entities include Accounts and/or Contracts.

    +

    This WhitelistMode is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a u8 value to whitelist_mode runtime argument.

    + + + + + + + + + + + + + + + + + +
    WhitelistModeu8
    Unlocked0
    Locked1
    +

    Minting

    +

    The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:

    +
      +
    1. Installer: This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract.
    2. +
    3. Public: This mode allows any account to mint NFT tokens.
    4. +
    5. ACL: This mode allows whitelisted accounts or contracts to mint NFT tokens.
    6. +
    +

    This modality is an optional installation parameter and will default to the Installer mode if not provided. However, this +mode cannot be changed once the contract has been installed. The mode is set by passing a u8 value to the minting_mode runtime argument.

    + + + + + + + + + + + + + + + + + + + + + +
    MintingModeu8
    Installer0
    Public1
    ACL2
    +

    NFTMetadataKind

    +

    This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:

    +
      +
    1. CEP78: This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema.
    2. +
    3. NFT721: This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema.
    4. +
    5. Raw: This mode specifies that metadata validation will not occur and raw strings can be passed to token_metadata runtime argument as part of the call to mint entrypoint.
    6. +
    7. CustomValidated: This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to mint entrypoint.
    8. +
    +

    During installation, one NFTMetadataKind must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the additional_required_metadata or optional_metadata arguments.

    +

    CEP-78 metadata example

    +
    {
    "name": "John Doe",
    "token_uri": "https://www.barfoo.com",
    "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"
    }
    +

    NFT-721 metadata example

    +
    {
    "name": "John Doe",
    "symbol": "abc",
    "token_uri": "https://www.barfoo.com"
    }
    +

    Custom Validated

    +

    The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation. +The schema is passed as a String value to json_schema runtime argument at the time of installation. Once provided, the schema +for a given instance of the contract cannot be changed.

    +

    The custom JSON schema must contain a top-level properties field. An example of a valid JSON schema is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata. +If the metadata kind is not set to custom validated, then the value passed to the json_schema runtime argument will be ignored.

    +

    Example Custom Validated schema

    +
    {
    "properties": {
    "deity_name": {
    "name": "deity_name",
    "description": "The name of deity from a particular pantheon.",
    "required": true
    },
    "mythology": {
    "name": "mythology",
    "description": "The mythology the deity belongs to.",
    "required": true
    }
    }
    }
    +

    Example Custom Metadata

    +
    {
    "deity_name": "Baldur",
    "mythology": "Nordic"
    }
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    NFTMetadataKindu8
    CEP780
    NFT7211
    Raw2
    CustomValidated3
    +

    NFTIdentifierMode

    +

    The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:

    +
      +
    1. Ordinal: NFTs minted in this modality are identified by a u64 value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted.
    2. +
    3. Hash: NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint.
    4. +
    +

    Since the primary identifier in the Hash mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint.

    +

    Attempting to install the contract with the MetadataMutability modality set to Mutable in the Hash identifier mode will raise an error.

    +

    This modality is a required installation parameter and cannot be changed once the contract has been installed.

    +

    It is passed in as a u8 value to the identifier_mode runtime argument.

    + + + + + + + + + + + + + + + + + +
    NFTIdentifierModeu8
    Ordinal0
    Hash1
    +

    Metadata Mutability

    +

    The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:

    +
      +
    1. Immutable: Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted.
    2. +
    3. Mutable: Metadata for NFTs minted in this mode can update the metadata via the set_token_metadata entrypoint.
    4. +
    +

    The Mutable option cannot be used in conjunction with the Hash modality for the NFT identifier; attempting to install the contract with this configuration raises InvalidMetadataMutability error. +This modality is a required installation parameter and cannot be changed once the contract has been installed. +It is passed in as a u8 value to the metadata_mutability runtime argument.

    + + + + + + + + + + + + + + + + + +
    MetadataMutabilityu8
    Immutable0
    Mutable1
    +

    BurnMode

    +

    The BurnMode modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality +provides two options:

    +
      +
    1. Burnable: Minted tokens can be burnt.
    2. +
    3. NonBurnable: Minted tokens cannot be burnt.
    4. +
    + + + + + + + + + + + + + + + + + +
    BurnModeu8
    Burnable0
    NonBurnable1
    +

    This modality is an optional installation parameter and will default to the Burnable mode if not provided. However, this +mode cannot be changed once the contract has been installed. The mode is set by passing a u8 value to the burn_mode runtime argument.

    +

    OwnerReverseLookupMode

    +

    The OwnerReverseLookupMode modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID.

    +

    This modality provides the following options:

    +
      +
    1. NoLookup: The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling.
    2. +
    3. Complete: The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described here.
    4. +
    5. TransfersOnly: The reporting and receipt functionality is supported like Complete. However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described here.
    6. +
    +

    Additionally, when set to Complete, causes a receipt to be returned by the mint or transfer entrypoints, which the caller can store in their account or contract context for later reference.

    +

    Further, two special entrypoints are enabled in Complete mode. First, register_owner which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, updated_receipts, which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own.

    + + + + + + + + + + + + + + + + + + + + + +
    OwnerReverseLookupModeu8
    NoLookup0
    Complete1
    TransfersOnly2
    +

    This modality is an optional installation parameter and will default to the NoLookup mode if not provided. The mode is set by passing a u8 value to the owner_reverse_lookup_mode runtime argument. This mode cannot be changed once the contract has been installed.

    +

    Note : if ownership_mode is set to Minter and the minting_mode is set to Installer only, OwnerReverseLookupMode will be set to NoLookup. This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances.

    +

    Note : if OwnerReverseLookupMode is set to TransfersOnly then ownership_mode has to be set to Transferable only. This is because other ownership modes do not allow transfer.

    +

    If you are upgrading a contract from CEP-78 version 1.0 to 1.1, OwnerReverseLookupMode will be set to Complete, as this was the standard behavior of CEP-78 1.0. In addition to being set to Complete, existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration.

    +

    If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option.

    +

    NamedKeyConventionMode

    +

    The NamedKeyConvention modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1.

    +

    This modality provides three options:

    +
      +
    1. DerivedFromCollectionName: This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's NamedKeys as cep78_contract_package_<collection_name> and cep78_contract_package_access_<collection_name>.
    2. +
    3. V_1_0_standard: This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the NamedKey entries originally created during the 1.0 installation.
    4. +
    5. V_1_0_custom: This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the NamedKey entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments access_key_name and hash_key_name for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in.
    6. +
    + + + + + + + + + + + + + + + + + + + + + +
    NamedKeyConventionu8
    DerivedFromCollectionName0
    V_1_0_standard1
    V_1_0_custom2
    +

    EventsMode

    +

    The EventsMode modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract.

    +

    The modality provides three options:

    +
      +
    1. NoEvents: This modality will signal the contract to not record events at all. This is the default mode.
    2. +
    3. CEP47: This modality will signal the contract to record events using the CEP47 event schema. Further information can be found below.
    4. +
    5. CES: This modality will signal the contract to record events using the Casper Event Standard.
    6. +
    + + + + + + + + + + + + + + + + + + + + + +
    EventsModeu8
    NoEvents0
    CEP471
    CES2
    +

    Transfer Filter Hook

    +

    The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the transfer method is invoked on the contract. CEP-78 will call the can_transfer +method on the specified callback contract, which is expected to return a value of TransferFilterContractResult, represented as a u8.

    +
      +
    • TransferFilterContractResult::DenyTransfer will block the transfer regardless of the outcome of other checks
    • +
    • TransferFilterContractResult::ProceedTransfer will allow the transfer to proceed if other checks also pass
    • +
    +

    The transfer filter can be enabled by passing a ARG_TRANSFER_FILTER_CONTRACT argument to the install method, with a value of type Option<Key>

    +

    CEP47 Mode

    +

    The CEP47 EventsMode modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a BTreeMap within a dictionary (EVENTS) in the contract's context. Entries consist of the PREFIX_HASH_KEY_NAME, followed by the EVENT_TYPE and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available here.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Event nameIncluded values and type
    Mintrecipient (Key), token_id (String)
    Transferowner (Key), operator (Option<Key>), recipient (Key), token_id (String)
    Burnowner (Key), token_id (String)
    ApprovalGrantedowner (Key), spender (Key), token_id (String)
    ApprovalRevokedowner (Key), token_id (String)
    ApprovalForAllowner (Key), operator (Key)
    RevokedForAllowner (Key), operator (Key)
    MetadataUpdatetoken_id (String)
    Migration-
    VariablesSet-
    +

    Casper Event Standard

    +

    CES is an option within the EventsMode modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the __events dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface.

    +

    The emitted events are encoded according to the Casper Event Standard, and the schema is visible to an observer reading the __events_schema contract named key.

    +

    For this CEP-78 reference implementation, the events schema is as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Event nameIncluded values and type
    Mintrecipient (Key), token_id (String), data (String)
    Transferowner (Key), operator (Option<Key>), recipient (Key), token_id (String)
    Burnowner (Key), token_id (String)
    Approvalowner (Key), spender (Key), token_id (String)
    ApprovalRevokedowner (Key), token_id (String)
    ApprovalForAllowner (Key), operator (Key)
    RevokedForAllowner (Key), operator (Key)
    MetadataUpdatedtoken_id (String), data (String)
    Migration-
    VariablesSet-
    +

    Modality Conflicts

    +

    The MetadataMutability option set to Mutable cannot be used in conjunction with the NFTIdentifierMode modality set to Hash.

    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/reverse-lookup/index.html b/1.5.X/resources/tokens/cep78/reverse-lookup/index.html new file mode 100644 index 000000000..ef623c918 --- /dev/null +++ b/1.5.X/resources/tokens/cep78/reverse-lookup/index.html @@ -0,0 +1,52 @@ + + + + + +Ownership Lookup | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Owner Reverse Lookup Functionality

    +

    In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.

    +

    In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract.

    +

    This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page.

    +

    The CEP-78 Page System

    +

    Ownership of NFTs within a CEP-78 contract is now tracked with a series of pages, with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs.

    +

    A page_table tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the register_owner entrypoint.

    +

    After registering as an owner, the contract creates an entry within the page_table dictionary for the minting account or contract. This dictionary entry consists of a series of boolean values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false.

    +

    Upon minting the token, the user will pay for a page allocation. This adds them to the page dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the page dictionary will consist of 1,000 page_address bits set to False upon allocation, and the minting of any given token in that page will set the page_address bit to True.

    +

    In addition, that account or contract's page_table will be updated by marking the corresponding page number's bit as True.

    +

    As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:

    +
      +
    1. +

      The contract registers their account as an owner.

      +
    2. +
    3. +

      The contract creates a page_table dictionary for that account, with 10 boolean values. As the numbering system begins with 0, the third boolean value corresponding with page 2 is set to True.

      +
    4. +
    5. +

      The account pays for allocation of page 2, creating an entry in the Page 2 dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding page_address boolean for 350 as True.

      +
    6. +
    7. +

      Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for page 5 to be allocated to them. They would then be added to the page 5 dictionary with the page_address boolean for 125 set as True.

      +
    8. +
    +

    This system binds the data writing costs to a maximum size of any given page dictionary.

    +

    Updated Receipts

    +

    If the contract enables OwnerReverseLookupMode, calling the updated_receipts entrypoint will return a list of receipt names alongside the dictionary for the relevant pages.

    +

    Updated receipts come in the format of "{<collection name>}\_m{modulo}\_p{<page number>}". Once again using the 2,350th token as an example, the receipt would read:

    +
    cep78_collection_m_350_p_2
    +

    You can determine the token number by multiplying the page_number by the page_size(1,000) and adding the modulo.

    +

    If the NFTIdentifierMode is set to Ordinal, this number corresponds directly to the token ID.

    +

    If it is set to Hash, you will need to reference the HASH_BY_INDEX dictionary to determine the mapping of token numbers to token hashes.

    + + \ No newline at end of file diff --git a/resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html b/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html similarity index 90% rename from resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html rename to 1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html index 0dcc8b8d8..113938712 100644 --- a/resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html +++ b/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/index.html @@ -3,21 +3,21 @@ -Installation Workflow | Casper Docs - Redux +Installation Workflow | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Installing an NFT Contract using the Rust Casper Client

    This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of 1.63.0. The code for this tutorial is available in GitHub. A portion of this tutorial reviews the contract.

    -

    Information on the modalities used throughout this installation process can be found in the modalities documentation.

    +

    Information on the modalities used throughout this installation process can be found in the modalities documentation.

    Table of Contents

    1. Environment Setup @@ -46,12 +46,12 @@

      Environmen

      Prerequisites

      Before using this guide, ensure you meet the following requirements:

      -

      The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read as a prerequisite.

      +

      The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read as a prerequisite.

      Building the Contract and Tests

      First, clone the contract from GitHub:

      git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft
      @@ -59,7 +59,7 @@

      make prepare

    If your environment is set up correctly, you will see this output:

    rustup target add wasm32-unknown-unknown
    info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date
    -

    If you do not see this message, check the Getting Started Guide.

    +

    If you do not see this message, check the Getting Started Guide.

    The contract code can be compiled to Wasm by running the make build-contract command provided in the Makefile at the top level. The Wasm will be found in the contract/target/wasm32-unknown-unknown/release directory as contract.wasm.

    You can also compile your contract and run the contract unit tests with this command:

    make test
    @@ -88,7 +88,7 @@

  • utils - Utility and helper functions to run the contract code
  • Initialization Flow

    -

    Initializing the contract happens through the call() -> install_contract() -> init() functions inside the main.rs contract file. The init() function reads the runtime arguments and defines parameters such as collection_name, collection_symbol, and total_token_supply, among the other required and optional arguments described here.

    +

    Initializing the contract happens through the call() -> install_contract() -> init() functions inside the main.rs contract file. The init() function reads the runtime arguments and defines parameters such as collection_name, collection_symbol, and total_token_supply, among the other required and optional arguments described here.

    Contract Entrypoints

    This section briefly explains the essential entrypoints used in the Casper NFT contract. To see their full implementation, refer to the main.rs contract file. For further questions, contact the Casper support team via the Discord channel.

      @@ -119,9 +119,9 @@

      Contrac
    • metadata

    Installing the Contract

    -

    Installing the enhanced NFT contract to global state requires using a Deploy. But before proceeding with the installation, verify the network state and the status of the account that will send the installation deploy.

    +

    Installing the enhanced NFT contract to global state requires using a Deploy. But before proceeding with the installation, verify the network state and the status of the account that will send the installation deploy.

    Querying Global State

    -

    This step queries information about the network state given the latest state root hash. You will also need the IP address from a Testnet peer node.

    +

    This step queries information about the network state given the latest state root hash. You will also need the IP address from a Testnet peer node.

    casper-client get-state-root-hash --node-address http://localhost:11101/rpc/

    Querying the Account State

    Run the following command and supply the path to your public key in hexadecimal format to get the account hash if you don't have it already.

    @@ -135,7 +135,7 @@

    Q

    Sending the Installation Deploy

    Below is an example of a casper-client command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state.

    -

    Use the Testnet to understand the exact gas amount required for installation. Refer to the note about gas prices to understand payment amounts and gas price adjustments.

    +

    Use the Testnet to understand the exact gas amount required for installation. Refer to the note about gas prices to understand payment amounts and gas price adjustments.

    • casper-client put-deploy -n http://localhost:11101/rpc/ --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm
    @@ -177,7 +177,7 @@

    modalities.

    +

    The session arguments match the available modalities.

    Expand for a sample query and response
    casper-client put-deploy --node-address http://localhost:11101/rpc/ \
    --chain-name "casper-net-1" \
    --payment-amount 500000000000 \
    --secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='CEP-78-collection'" \
    --session-arg "collection_symbol:string='CEP78'" \
    --session-arg "total_token_supply:u64='100'" \
    --session-arg "ownership_mode:u8='2'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "nft_metadata_kind:u8='0'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='0'"
    @@ -193,8 +193,8 @@

    V

    Next Steps

    +
  • Learn to Query the NFT contract
  • +
  • Learn to Mint, Transfer, and Burn NFT tokens
  • +
    \ No newline at end of file diff --git a/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html b/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html similarity index 69% rename from resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html rename to 1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html index 2acd93b8e..a3ea31bf4 100644 --- a/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html +++ b/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/index.html @@ -3,24 +3,24 @@ -Interaction Workflow | Casper Docs - Redux +Interaction Workflow | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Interacting with the NFT Contract using the Rust Casper Client

    This document describes interacting with NFTs on a Casper network using the Rust command-line client.

    Prerequisites

    Table of Contents

      @@ -60,7 +60,7 @@

      casper-client put-deploy --node-address http://localhost:11101/rpc/ \
      --chain-name "casper-net-1” \
      --payment-amount 5000000000 \
      --secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
      --session-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \
      --session-entry-point "transfer" \
      --session-arg "source_key:key='account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'" \
      --session-arg "target_key:key='account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34'" \
      --session-arg "token_id:u64='0'"

    Minting NFTs

    -

    Below is an example of a casper-client command that uses the mint entrypoint of the contract to mint an NFT for the user associated with node-1 in an NCTL environment.

    +

    Below is an example of a casper-client command that uses the mint entrypoint of the contract to mint an NFT for the user associated with node-1 in an NCTL environment.

    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "mint"
    @@ -248,7 +248,7 @@

    Burning NFTs

    Next Steps

    +
  • Testing Framework for CEP-78
  • +
    \ No newline at end of file diff --git a/resources/tokens/cep78/using-casper-client/querying-NFTs/index.html b/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/index.html similarity index 80% rename from resources/tokens/cep78/using-casper-client/querying-NFTs/index.html rename to 1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/index.html index f00acebab..8fc5e3fa6 100644 --- a/resources/tokens/cep78/using-casper-client/querying-NFTs/index.html +++ b/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/index.html @@ -3,24 +3,24 @@ -CEP-78 Contract Details | Casper Docs - Redux +CEP-78 Contract Details | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    Querying NFT Contracts

    This document covers different commands to query and interact with an NFT (CEP-78) contract instance.

    Prerequisites

    Querying the Contract

    First, identify the contract hash by looking at the account that installed the contract. Under the account's named keys, you will see a named key for the contract hash, representing the stored contract. Copy this value and save it for future queries.

    @@ -46,7 +46,7 @@

    Queryi

    Next Steps

    +
  • Learn to Mint, Transfer, and Burn NFT tokens
  • +
    \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html b/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html new file mode 100644 index 000000000..897e1a6a4 --- /dev/null +++ b/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html @@ -0,0 +1,47 @@ + + + + + +Quick Installation | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Casper NFT Quick Installation Guide

    +

    This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.

    +

    To execute transactions on a Casper network involving NFTs, you will need some CSPR tokens to pay for the transactions. The Testnet provides test tokens using a faucet.

    +

    Prerequisites

    +

    Before using this guide, ensure you meet the following requirements:

    + +

    Setup

    +

    Clone the Casper NFT (CEP-78) contract repository.

    +
    git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft
    +

    Run the following commands to build the contract.wasm in the contract/target/wasm32-unknown-unknown/release directory and run the tests.

    +
    make prepare
    make test
    +

    The output of the command would end with the following message:

    +
    test result: ok. 159 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.33s
    +

    Installing the NFT Contract

    +

    The following command will install a sample NFT contract on the Testnet:

    +
    casper-client put-deploy --node-address http://localhost:11101/rpc/ \
    --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    --secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='CEP-78-collection'" \
    --session-arg "collection_symbol:string='CEP78'" \
    --session-arg "total_token_supply:u64='100'" \
    --session-arg "ownership_mode:u8='2'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "nft_metadata_kind:u8='0'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='0'"
    +

    Next Steps

    +

    Learn to query the contract, perform token transfers, set up approvals, and understand the testing framework.

    +
    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html b/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html new file mode 100644 index 000000000..d4585526c --- /dev/null +++ b/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html @@ -0,0 +1,33 @@ + + + + + +Testing NFTs | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Testing NFT Contracts

    +

    Prerequisites

    + +

    Framework Description

    +

    The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.

    +

    The tests source folder contains over 150 tests covering a variety of scenarios, including contract installation, minting and burning tokens, sending transfers, upgrading the contract, and listening to events.

    +

    For more details about the test framework and how each test is set up, visit the Testing Smart Contracts documentation page.

    +

    Running the Tests

    +

    To build and run the tests, issue the following command in the project folder:

    +
    make test
    +

    The project contains a Makefile, which is a custom build script that compiles the contract before running tests in release mode. Then, the script copies the contract.wasm file to the corresponding version folder in a tests/wasm directory. In practice, you only need to run the make test command during development without building the contract separately.

    +

    This example uses bash. If you use a Rust IDE, you must configure it to run the tests.

    + + \ No newline at end of file diff --git a/1.5.X/resources/tokens/index.html b/1.5.X/resources/tokens/index.html new file mode 100644 index 000000000..2491196a3 --- /dev/null +++ b/1.5.X/resources/tokens/index.html @@ -0,0 +1,82 @@ + + + + + +Casper Token Standards | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Casper Token Standards

    +

    CEP-18 Casper Fungible Token Standard

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    A Casper Fungible Token TutorialA full tutorial for use of the CEP-18 Casper Fungible Token Standard.
    Installing and Interacting with a CEP-18 ContractA quickstart guide for installing a CEP-18 contract with the Rust Casper Client.
    Exploring the CEP-18 ContractsA guide to interacting with installed CEP-18 contracts.
    CEP-18 Token Transfers and AllowancesA guide for transferring Casper Fungible Tokens.
    Testing Framework for CEP-18A CEP-18 testing framework using the Casper engine test support crate.
    +

    CEP-78 Enhanced NFT Standard

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    CEP-78 Enhanced NFT Standard IntroductionAn introduction to the CEP-78 Enhanced NFT Standard.
    CEP-78 ModalitiesInformation on the features available when installing a CEP-78 contract instance.
    Installing and Interacting with a CEP-78 ContractAn introduction to features present in the CEP-78 Enhanced NFT Standard.
    Owner Reverse Lookup FunctionalityInformation on the Onwer Reverse Lookup feature of CEP-78 contracts.
    A CEP-78 JavaScript Client TutorialA tutorial for using the JavaScript CEP-78 client.
    + + \ No newline at end of file diff --git a/1.5.X/resources/tutorials/advanced/cross-contract/index.html b/1.5.X/resources/tutorials/advanced/cross-contract/index.html new file mode 100644 index 000000000..49c07e14b --- /dev/null +++ b/1.5.X/resources/tutorials/advanced/cross-contract/index.html @@ -0,0 +1,160 @@ + + + + + +Cross-Contract Communication | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Cross-Contract Communication

    +

    This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:

    + +

    Tutorial Outline

    +

    This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol.

    +

    Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose. The contracts are as follows:

    +
      +
    • Factory
    • +
    • Pair
    • +
    • Pair (ERC20)
    • +
    • Library
    • +
    • Router01
    • +
    • Router02
    • +
    +

    The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash. The Pair smart contract is used to perform operations like mint or burn on a created pair of tokens.

    +

    Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called.

    +

    Creating the Project

    +

    In the appropriate folder, create the project for the contract using the following command:

    +
    cargo casper cross-contract
    +

    This will create the following directory structure within your smart contract folder.

    +
    cross-contract
    ├──contract
    │ ├── Cargo.toml
    │   ├── rust-toolchain
    │   ├── src
    │   │   └── main.rs
    │   └── target
    ├──tests
    │ ├── Cargo.toml
    │ ├── src
    │ │   └── integration_tests.rs
    │ └── target
    └── Makefile
    +

    After creating the project directory structure, use the following commands to go into the project folder and compile the files:

    +
    cd cross-contract
    make prepare
    make build-contract
    +

    This will produce the .wasm file of our contract. It can be found in contract/target/wasm32-unknown-unknown/release/contract.wasm. Additionally you can check if the tests can be performed using the following command:

    +
    make test
    +

    This should produce the following outcome:

    +
    running 2 tests
    test tests::should_error_on_missing_runtime_arg ... ok
    test tests::should_store_hello_world ... ok

    test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    +
    tip

    When you try to run the tests, you might encounter errors if the project's dependencies are outdated. If you see an error message similar to the following:

    warning: `tests` (bin "integration-tests" test) generated 2 warnings
    error: could not compile `tests` due to 3 previous errors; 2 warnings emitted
    make: *** [test] Error 101

    This indicates potential issues with outdated dependencies. Use the cargo update command to check for and install any available updates for your project's dependencies or do it manually through Cargo.toml file.

    If you are using cargo extensions in your editor you will see a warning next to the outdated dependencies.

    +

    Changing the Standard Contract

    +

    The standard Casper contract from cargo-casper contains some methods that we will reuse. However, we will remove most of the automatically generated code.

    +

    We will be changing the main.rs file. Your code should look exactly as below:

    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    }
    +

    This will serve as a base for introducing the elements needed for cross-contract communication.

    +

    In a contract, you should first define the call entry point. It should be understood as a constructor for the contract. Everything included in the call entry point will be visible as metadata on a Casper network, in the contract's context. You should already be familiar with the call entry point from the Writing a Basic Smart Contract in Rust document. If this is not the case, be sure to familiarize yourself with it now.

    +

    The contract code, with changes to the call entry point, should look as shown below:

    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    // Get the value of the runtime argument named "message"
    let value: String = runtime::get_named_arg("message");

    // The value will be written under a URef
    let value_ref = storage::new_uref(value);

    // Creating the new set of named keys
    // The keys are a Map of String/casper_types::Key
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();

    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key
    // Create a new vector
    let mut params = Vec::new();
    vec.push(Parameter::new("message", CLType::String));

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Describing the metadata for the entry point
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg", // the name of the entry point
    vec, // the arguments which can be passed into the entry point
    CLType::Unit, // return type of the entry point
    EntryPointAccess::Public, // access permissions - public can be accessed always
    EntryPointType::Contract // in most cases it will be contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access the contract hash from the accounts named keys
    runtime::put_key("hello_world_contract", stored_contract_hash.into());

    }
    +
    tip

    runtime and storage appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the Contract API Modules.

    +

    The metadata for each of the contract's entry points is defined in the call entry point. When installing the contract, the Casper Node will search for the entry point based on the name specified in its metadata. Therefore, each of the entry points defined in the code must share the same name as the String value passed when defining the metadata for the entry point.

    +

    The #[no_mangle] attribute guarantees that the compiler won't alter the entry point's name. It doesn't mandate that the name matches its metadata definition, so developers need to be cautious when specifying entry points.

    +

    In our case, we will define the entry point update_msg in the contract code just before call.

    +

    Your complete contract should match the following:

    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };

    #[no_mangle]
    pub extern "C" fn update_msg() {

    let value: String = runtime::get_named_arg("message");
    // Get the uref of the message stored in global state
    let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();
    // Write the message to global state
    storage::write(uref, String::from(value));
    }


    #[no_mangle]
    pub extern "C" fn call() {
    // Get the value of a passed parameter with the key "message"
    let value: String = runtime::get_named_arg("message");
    // The value will be wraped in a URef
    let value_ref = storage::new_uref(value);
    // Creating the new set of named keys
    // The keys are a Map of Key/Value
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();
    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key
    // Create a new vector
    let mut vec = Vec::new();
    vec.push(Parameter::new("message", CLType::String));
    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Define the metadata for the entry point `update_msg`
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points metadata
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("hello_world_contract", stored_contract_hash.into());
    }
    +
    info

    There is a distinction between storing data in a contract’s NamedKeys and using a dictionary. Dictionaries can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.

    +

    Deploying the Contract

    +

    There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand put_deploy.

    +

    Be sure to go through the prerequisites from the Installing Smart Contracts and Querying Global State documentation.

    +

    Make sure that after doing this you have:

    +
      +
    1. A valid private key for your account.
    2. +
    3. Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract.
    4. +
    +

    Create the keys folder in the main folder of your project and make sure that the private key which you put into the folder is called secret_key.pem.

    +

    Compile the contract in the contract directory so you obtain the contracts .wasm:

    +
    cd cross-contract
    make prepare
    make build-contract
    +

    This should produce the following outcome:

    +
    cd contract && cargo build --release --target wasm32-unknown-unknown
    Finished release [optimized] target(s) in 0.13s
    wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true
    +

    With this step everything is in place to deploy the contract.

    +
    tip

    When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands.

    +

    Since we are using a default contract structure, the command called from the cross-contract folder should be the following:

    +
    casper-client put-deploy \
    --node-address http://136.243.187.84:7777 \
    --chain-name casper-test \
    --secret-key ./keys/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "message:string='hello world'"
    +
    tip

    The parameters used in this command need to be adjusted based on your use case. For details, see querying a node and installing contracts. The payment amount may also need to be adjusted based on the latest Testnet chainspec.

    +

    The output of this command is:

    +
    {
    "id": -9119604526598719721,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"
    }
    }
    +

    To verify that the contract was successfully deployed, use the get-deploy subcommand, providing as a parameter the deploy_hash received from the put-deploy above.

    +
    casper-client get-deploy \
    --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832
    +

    This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the verbose flag with the put-deploy subcommand. Take time to familiarize yourself with the structure of the output.

    +

    We can use the supplied deploy hash, af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832 to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as Success.

    +

    From your cspr.live account, you will find a tab called NamedKeys. This tab includes a list of all contracts deployed using the private key connected to your account.

    +

    By clicking the contract hash, you can see all entry points included in the contract, as well as the NamedKeys under which your contract’s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations.

    +

    An additional tab, Deploys, that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea.

    +

    Create Another Contract for the Cross-Contract Call

    +

    This section describes the process of writing an additional contract, which will use an entry point titled call_contract_2 to invoke the update_msg entry point on the previous contract.

    +

    In this tutorial we will be passing the contract hash, as an argument, into the call entry point and use this to perform the calls to the destination contract.

    +

    Prepare the call entry point as described below:

    +

    #[no_mangle]
    pub extern "C" fn call() {

    // Create the list of required runtime arguments for the given entry point.
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let mut named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point metadata definition.
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());
    }

    +

    This would be the easiest implementation of the call entry point. There is only one entry point which accepts the key contract2 of type String and the key hello_world_contract of the type Key. There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys.

    +

    Now that we have defined the metadata for the call_contract_2 entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point update_msg. It will then pass a message to the second contract as a parameter, which will be stored in that contract’s context.

    +
    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.
    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    // Get the value of the message from the second parameter
    let new_value: String = runtime::get_named_arg("new_message");

    // Call the update_msg entry point on the other contract with the parameter values
    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    "message" => new_value,
    },
    );

    }
    +

    Your complete contract implementation should look as follows:

    +

    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use crate::alloc::string::ToString;
    use crate::runtime_args::RuntimeArgs;

    // Casper crates
    use casper_types::{
    api_error::ApiError,
    contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    unwrap_or_revert::UnwrapOrRevert,
    contract_api::{runtime, storage},
    };

    // The contract key in the account named keys
    const CONTRACT_HASH: &str = "hello_world_contract";

    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    let new_value: String = runtime::get_named_arg("new_message");

    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    // key => value
    "message" => new_value,
    },
    );

    }

    #[no_mangle]
    pub extern "C" fn call() {

    // Create a new vector - this will be the signature of the entrypoint
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point to the entry points object
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());

    }
    +

    After you run make build-contract in your second contract's directory, you should obtain the outcome:

    +
    cd contract && cargo build --release --target wasm32-unknown-unknown
    Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)
    Finished release [optimized] target(s) in 0.69s
    wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true
    +

    Create the keys subfolder and copy the keys from the keys subfolder in the first contract into this subfolder. The call from the terminal will look as follows:

    +
    casper-client put-deploy \
    --node-address http://136.243.187.84:7777 \
    --chain-name casper-test \
    --secret-key ./keys/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm
    +
    tip

    You may have noticed that the contract.wasm is always output to the same filename for each new cargo casper project. You can change this by editing the Makefile in the main directory. You can then observe the result by recompiling your contract with these commands;

    make prepare
    make build-contract
    +

    After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points.

    +

    The result of invoking the put-deploy subcommand is:

    +
    {
    "id": -7557689417621513622,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"
    }
    }
    +
    tip

    If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys.

    +

    Observing the deploy, we can see that it succeeded:

    +
    casper-client get-deploy \
    --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832
    +

    In the execution_results JSON element we should see "Success".

    +

    "execution_results": [
    {
    "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",
    "result": {
    "Success": {
    "cost": "16580565260",
    "effect": { ...

    }
    }
    }
    }
    ]

    +

    Get the state root hash of the current network state:

    +
    casper-client get-state-root-hash --node-address http://136.243.187.84:7777
    +

    The result of invoking theget-state-root-hash command is:

    +
    {
    "id": -3631326529646611302,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"
    }
    }
    +

    Query the state of Casper network using the account hash:

    +
      casper-client query-global-state \
    --node-address http://136.243.187.84:7777 \
    --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \
    --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9
    +

    If we check the account's named keys, we can see all of the account's deployed contracts:

    +
    Account's named keys
    + +
    {
    "id": -6842818667609668962,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[30424 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",
    "weight": 1
    }
    ],
    "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",
    "named_keys": [
    {
    "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",
    "name": "Hello_world_access_uref"
    },
    {
    "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",
    "name": "Hello_world_package_name"
    },
    {
    "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",
    "name": "contract2_access_uref"
    },
    {
    "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",
    "name": "contract2_package_name"
    },
    {
    "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",
    "name": "cross_contract_2"
    },
    {
    "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",
    "name": "hello_world_contract"
    }
    ]
    }
    }
    }
    }
    +
    +

    +

    As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function.

    +

    The Uref of the message variable is stored under the Named Keys in the contract.

    +
    casper-client query-global-state \
    --node-address http://136.243.187.84:7777 \
    --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \
    --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea
    +
    {
    "id": 2434670480361972874,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[25224 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",
    "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",
    "entry_points": [
    {
    "access": "Public",
    "args": [
    {
    "cl_type": "String",
    "name": "message"
    }
    ],
    "entry_point_type": "Contract",
    "name": "update_msg",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",
    "name": "message"
    }
    ],
    "protocol_version": "1.4.13"
    }
    }
    }
    }
    +

    Checking the state of the message in the first contract, we observe the following:

    +
    casper-client query-global-state \
    --node-address http://136.243.187.84:7777 \
    --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \
    --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"
    +

    This is a simple hello world string. After invoking the entry point using the command below this value should change.

    +
    info

    --session-hash - is the contract hash, which is returned from the put-deploy.

    --session-arg "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.

    +
    casper-client put-deploy \
    --node-address http://136.243.187.84:7777 \
    --chain-name casper-test \
    --secret-key ./keys/secret_key.pem \
    --payment-amount 20000000000 \
    --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \
    --session-entry-point "call_contract_2" \
    --session-arg "new_message:string='Hello new message!'" \
    --session-arg "hello_world_contract:Key='hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea'"
    +
    tip

    The contract hash has to be of type ContractHash in the contract itself. We can pass the hash as a Key argument and change it to ContractHash in the smart contract.

    +

    The output of the above command is:

    +
    {
    "id": -6419793201665396463,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"
    }
    }
    +

    Check the deploy with:

    +
    casper-client get-deploy \
    --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537
    +

    After the deploy finishes successfully, you should see a similar outcome to the following:

    +
    Deploy details
    + +
    {
    "id": 3968762702269106998,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy": {
    "approvals": [
    {
    "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",
    "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"
    }
    ],
    "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",
    "header": {
    "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",
    "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",
    "chain_name": "casper-test",
    "dependencies": [],
    "gas_price": 1,
    "timestamp": "2023-03-09T14:39:24.974Z",
    "ttl": "30m"
    },
    "payment": {
    "ModuleBytes": {
    "args": [
    [
    "amount",
    {
    "bytes": "0500c817a804",
    "cl_type": "U512",
    "parsed": "20000000000"
    }
    ]
    ],
    "module_bytes": ""
    }
    },
    "session": {
    "StoredContractByHash": {
    "args": [
    [
    "new_message",
    {
    "bytes": "1200000048656c6c6f206e6577206d65737361676521",
    "cl_type": "String",
    "parsed": "Hello new message!"
    }
    ],
    [
    "hello_world_contract",
    {
    "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",
    "cl_type": "Key",
    "parsed": {
    "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"
    }
    }
    ]
    ],
    "entry_point": "call_contract_2",
    "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"
    }
    }
    },
    "execution_results": [
    {
    "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",
    "result": {
    "Success": {
    "cost": "462273650",
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",
    "transform": {
    "WriteCLValue": {
    "bytes": "0600876bf27301",
    "cl_type": "U512",
    "parsed": "1597500000000"
    }
    }
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "AddUInt512": "20000000000"
    }
    },
    {
    "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",
    "transform": "Identity"
    },
    {
    "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",
    "transform": "Identity"
    },
    {
    "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",
    "transform": "Identity"
    },
    {
    "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",
    "transform": "Identity"
    },
    {
    "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",
    "transform": "Identity"
    },
    {
    "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",
    "transform": "Identity"
    },
    {
    "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",
    "transform": {
    "WriteCLValue": {
    "bytes": "1200000048656c6c6f206e6577206d65737361676521",
    "cl_type": "String",
    "parsed": "Hello new message!"
    }
    }
    },
    {
    "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",
    "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",
    "gas": "462273650",
    "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",
    "transfers": []
    }
    }
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "WriteCLValue": {
    "bytes": "00",
    "cl_type": "U512",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",
    "transform": {
    "AddUInt512": "20000000000"
    }
    }
    ]
    },
    "transfers": []
    }
    }
    }
    ]
    }
    }
    +
    +

    +

    We would expect that the value of the message reference in the other contract would have changed, which we can check:

    +
    casper-client query-global-state \
    --node-address http://136.243.187.84:7777 \
    --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \
    --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"
    +

    The output of the above command is:

    +
    {
    "id": -5477027327608594231,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[61444 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "1200000048656c6c6f206e6577206d65737361676521",
    "cl_type": "String",
    "parsed": "Hello new message!"
    }
    }
    }
    }
    +

    With this we have succeeded in cross-contract communication between two contracts.

    +

    Summary

    +

    In this tutorial, we:

    +
      +
    • Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract
    • +
    • Called an entry point on one contract from the other contract, passing a value as an argument to this entry point.
    • +
    + + \ No newline at end of file diff --git a/1.5.X/resources/tutorials/advanced/index.html b/1.5.X/resources/tutorials/advanced/index.html new file mode 100644 index 000000000..e6daf7c1e --- /dev/null +++ b/1.5.X/resources/tutorials/advanced/index.html @@ -0,0 +1,58 @@ + + + + + +Advanced Tutorials | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Advanced Tutorials

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Two-Party Multi-Signature DeploysA trivial two-party multi-signature scheme for signing and sending deploys
    Multi-Sig ManagementIntegrate key management on Casper accounts and sign deploys with multiple keys
    Interacting with Runtime Return ValuesContract code returning a value to the immediate caller via runtime::ret()
    Safely Transfer Tokens to a ContractTwo methods to handle tokens via a contract
    Reading and Writing to Global State using RustMethods to read and write data to global state on a Casper network using Rust
    Cross Contract CommunicationVariations of cross-contract communication for more complex scenarios
    Working with Authorization KeysRetrieve and use the authorization keys associated with a deploy
    + + \ No newline at end of file diff --git a/next/resources/tutorials/advanced/list-cspr/index.html b/1.5.X/resources/tutorials/advanced/list-cspr/index.html similarity index 83% rename from next/resources/tutorials/advanced/list-cspr/index.html rename to 1.5.X/resources/tutorials/advanced/list-cspr/index.html index c8960d20a..5de7c74e2 100644 --- a/next/resources/tutorials/advanced/list-cspr/index.html +++ b/1.5.X/resources/tutorials/advanced/list-cspr/index.html @@ -1,28 +1,28 @@ - + -Listing CSPR | Casper Docs - Redux +Listing CSPR | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Listing CSPR on an Exchange

    + submit an issue on Github
    Version: 1.5.X

    Listing CSPR on an Exchange

    This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.

    caution

    The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

    Setting up a Node

    -

    While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see Basic Node Setup.

    +

    While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see Basic Node Setup.

    This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions.

    Casper Account

    -

    You will need a Casper Account to handle the transactions on an exchange. Casper has an Account model and instructions on how to create an Account.

    +

    You will need a Casper Account to handle the transactions on an exchange. Casper has an Account model and instructions on how to create an Account.

    For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users.

    Understanding Basic Transactions

    We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice.

    @@ -33,9 +33,9 @@

    Native trans

    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": {
    "deploy": {
    "approvals": [
    {
    "signature": "130 chars",
    "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"
    }
    ],
    "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
    }
    ]
    ]
    }
    }
    }
    }
    }

    -

    Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see Direct Token Transfer. The following command transfers 10 CSPR from account A's main purse to account B's main purse.

    +

    Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see Direct Token Transfer. The following command transfers 10 CSPR from account A's main purse to account B's main purse.

    casper-client transfer \
    --id 1 \
    --transfer-id 123456 \
    --node-address http://<node-ip-address>:7777 \
    --amount 10000000000 \
    --secret-key <accountA-secret-key>.pem \
    --chain-name casper \
    --target-account <accountB-hex-encoded-public-key> \
    --payment-amount <payment-in-motes>
    -

    The payment amount varies based on the deploy and network chainspec. For node version 1.5.1, wasmless transfers cost 10^8 motes.

    +

    The payment amount varies based on the deploy and network chainspec. For node version 1.5.1, wasmless transfers cost 10^8 motes.

    Bulk or batched Wasm transfer

    Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the Rust contract API, which can be used in session code to achieve batched Wasm transfer:

      @@ -45,30 +45,30 @@

      Writing Session Code. There are equivalent assembly script methods available. Alternatively, you can program directly against the ext-FFI methods.

      +

      For more information on how to write session code, see Writing Session Code. There are equivalent assembly script methods available. Alternatively, you can program directly against the ext-FFI methods.

      Integrating CSPR

      -

      You can integrate with the JSON-RPC API of a node on the Casper Mainnet. -You can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see SDK Libraries. -Casper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see Monitoring and Consuming Events.

      +

      You can integrate with the JSON-RPC API of a node on the Casper Mainnet. +You can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see SDK Libraries. +Casper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see Monitoring and Consuming Events.

      Testing the Integration

      Our recommended testing mechanism is to have a test environment that points at the official Casper Testnet. Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the Mainnet, then you can do so with your own test accounts.

      If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public.

      The Casper Protocol

      • Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already.
      • -
      • Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle’d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see Execution Semantics.
      • -
      • Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see Monitoring and Consuming Events.
      • +
      • Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle’d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see Execution Semantics.
      • +
      • Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see Monitoring and Consuming Events.

      Staking Integration for Exchanges

      -

      Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the JavaScript SDK to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found here.

      +

      Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the JavaScript SDK to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found here.

      Deploy Structures and Parameters

      Staking operations consists of two parts:

      1. -

        Creating a deploy object

        +

        Creating a deploy object

      2. -

        Signing the deploy

        +

        Signing the deploy

      The staking deploy requires the following information:

      @@ -139,7 +139,7 @@

      2b

      We can then send it to a network.

      casperService.deploy(signedDeploy)

      Costs and Minimums

      -

      The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network chainspec.

      +

      The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network chainspec.

      Transfer Cost: 100,000,000 motes or 0.1 CSPR

      Delegation Cost: 2,500,000,000 motes or 2.5 CSPR

      Minimum transfer amount: 2,500,000,000 motes, or 2.5 CSPR

      @@ -147,6 +147,6 @@

      Costs and

      The Delegation Cap

      Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at 953. This is a temporary solution to prevent complications with Casper’s fast sync mechanism - in which high bond counts could break fast sync.

      Validators with a delegator count at or above 953 at the time of the 1.4.5 upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below 953.

      -

      Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their CSPR to that validator. However, no new delegators may join the validator until it drops below the 953 limit.

    +

    Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their CSPR to that validator. However, no new delegators may join the validator until it drops below the 953 limit.

    \ No newline at end of file diff --git a/next/resources/tutorials/advanced/return-values-tutorial/index.html b/1.5.X/resources/tutorials/advanced/return-values-tutorial/index.html similarity index 65% rename from next/resources/tutorials/advanced/return-values-tutorial/index.html rename to 1.5.X/resources/tutorials/advanced/return-values-tutorial/index.html index 629a7a85f..b6f29a6ff 100644 --- a/next/resources/tutorials/advanced/return-values-tutorial/index.html +++ b/1.5.X/resources/tutorials/advanced/return-values-tutorial/index.html @@ -1,21 +1,21 @@ - + -Runtime Return Values | Casper Docs - Redux +Runtime Return Values | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Interacting with Runtime Return Values

    + submit an issue on Github
    Version: 1.5.X

    Interacting with Runtime Return Values

    Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.

    Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers.

    Contract code can optionally return a value to their immediate caller via runtime::ret(), whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance.

    @@ -28,8 +28,8 @@

    Contrac

    Session Code

    The following is an example of session code calling the specified entry point. Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code.


    #[no_mangle]
    pub extern "C" fn call() {
    let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);
    let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);
    let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);

    let donating_purse_uref: URef = runtime::call_contract(
    fundraiser_contract_hash,
    ENTRY_POINT_DONATE,
    runtime_args! {
    DONATING_ACCOUNT_KEY => donating_account_key
    },
    );
    system::transfer_from_purse_to_purse(
    account::get_main_purse(),
    donating_purse_uref,
    donation_amount,
    None
    )
    .unwrap_or_revert()
    }

    -

    This session code calls into a contract's entry point by using runtime::call_contract, supplying the contract_hash to identify the contract to be called, and the name of the entry point to be invoked, in this case donate. It supplies the donating_account_key, which in this case is the account key of the caller. The contract will then provide a return value, in this case donating_purse_uref. To call an entry point, you will need to know the CLType of the return value and identify it within the code.

    -

    You can determine the type of the return value by querying the contract object in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash.

    -

    This example code takes that returned value and transfers a donation_amount from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer.

    +

    This session code calls into a contract's entry point by using runtime::call_contract, supplying the contract_hash to identify the contract to be called, and the name of the entry point to be invoked, in this case donate. It supplies the donating_account_key, which in this case is the account key of the caller. The contract will then provide a return value, in this case donating_purse_uref. To call an entry point, you will need to know the CLType of the return value and identify it within the code.

    +

    You can determine the type of the return value by querying the contract object in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash.

    +

    This example code takes that returned value and transfers a donation_amount from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer.

    \ No newline at end of file diff --git a/1.5.X/resources/tutorials/advanced/storage-workflow/index.html b/1.5.X/resources/tutorials/advanced/storage-workflow/index.html new file mode 100644 index 000000000..71589a5aa --- /dev/null +++ b/1.5.X/resources/tutorials/advanced/storage-workflow/index.html @@ -0,0 +1,47 @@ + + + + + +Storage Workflow | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Reading and Writing to Global State using Rust

    +

    The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.

    +

    Essentially, there are three means of storage within the Casper ecosystem. These consist of runtime::put_key, storage::write(alongside storage::new_uref as explained below) and storage::dictionary_put. These stored values can be read using runtime::get_key, storage::read and storage::dictionary_get, respectively. Each method stores data in a specific way, and it's important to understand the differences.

    +

    Description of Functions

    +

    runtime::put_key / runtime::get_key

    +

    Both the put_key and get_key functions refer to Casper Key types as outlined in both the Understanding Hash Types and Serialization Standard. These keys are stored within a URef as a Key type.

    +

    storage::write / storage::read

    +

    storage::write writes a given value to a previously established URef (created using storage::new_uref). Unlike put_key, this value is not one of the Key types listed above, but rather any of the potential CLTypes as outlined. storage::read provides a method to retrieve these values from the associated URef.

    +

    storage:dictionary_put / storage::dictionary_get

    +

    For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than NamedKeys. Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes.

    +

    More information on dictionaries can be found on the Reading and Writing to Dictionaries page.

    +

    Example Code

    +

    Example of put_key and storage::write

    +

    This sample code creates a new contract and stores the contract hash in global state using the runtime::put_key function.

    +

    Once the stored value has been initialized, the storage::write function overwrites the existing value with true. The URef is then stored in the current context as a NamedKey titled MY_STORED_VALUE_UREF.

    +

    // Store contract hash under a Named key CONTRACT_HASH
    runtime::put_key(CONTRACT_HASH, contract_hash.into());

    // Store !MY_STORED_VALUE (false) as init value/type into a new URef
    let my_value_uref = storage::new_uref(!MY_STORED_VALUE);

    // Store MY_STORED_VALUE (true) under the URef value
    storage::write(my_value_uref, MY_STORED_VALUE);

    // Store the Uref under a Named key MY_STORED_VALUE_UREF
    let my_value_key: Key = my_value_uref.into();
    runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);
    }

    +

    Example of get_key and storage::read

    +

    This example compliments the code sample above by retrieving the CONTRACT_HASH using the get_key function, before comparing a provided runtime argument ARG_MY_STORED_VALUE against the previously stored MY_STORED_VALUE_UREF using storage::read.

    +

    let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)
    .unwrap_or_revert()
    .into_uref()
    .map(|uref| URef::new(uref.addr(), AccessRights::default()))
    .unwrap_or_revert()
    .into_read();

    let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();

    // Compare my stored value with runtime arg
    let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);
    if my_actual_stored_value != my_expected_stored_value {
    // We revert if my stored value is not what is expected from caller argument
    runtime::revert(UserError::StoredValueError);
    }

    runtime::print(&my_actual_stored_value.to_string());
    }

    +

    Example of dictionary_put and dictionary_get

    +

    Examples of dictionary usage for storage can be found in the Writing Entries into a Dictionary section of Reading and Writing to Dictionaries.

    +

    Additional Functions for Named Keys

    +

    The following functions might also be of interest for working with named keys:

    +
      +
    • list_named_keys - Returns the named keys of the current context
    • +
    • has_key - Returns true if the key exists in the current context’s named keys
    • +
    • remove_key - Removes the requested NamedKey from the current context
    • +
    + + \ No newline at end of file diff --git a/next/resources/tutorials/advanced/transfer-token-to-contract/index.html b/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/index.html similarity index 71% rename from next/resources/tutorials/advanced/transfer-token-to-contract/index.html rename to 1.5.X/resources/tutorials/advanced/transfer-token-to-contract/index.html index b8608ca88..09e0e8363 100644 --- a/next/resources/tutorials/advanced/transfer-token-to-contract/index.html +++ b/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/index.html @@ -1,23 +1,23 @@ - + -Token Transfers | Casper Docs - Redux +Token Transfers | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Safely Transfer Tokens to a Contract

    + submit an issue on Github
    Version: 1.5.X

    Safely Transfer Tokens to a Contract

    This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.

    -

    For increased security, token transfers from a main purse must be handled via session code (WASM), as shown here. Therefore, transfer-* methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context.

    +

    For increased security, token transfers from a main purse must be handled via session code (WASM), as shown here. Therefore, transfer-* methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context.

    Scenario 1 - Creating a Throw-Away Purse

    The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee.

    In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues.

    @@ -34,6 +34,6 @@

    Scenario 2 - Maint
    // Scenario 2: with this style, the contract being called has some internal accounting
    // to keep track of a reusable purse associated to the calling account; this avoids
    // wasteful creation of one time purses but requires the smart contract being called
    // to have more sophisticated internal logic.
    #[no_mangle]
    pub extern "C" fn call() {
    let amount: U512 = runtime::get_named_arg("amount");

    // This is demonstrating the most direct case, wherein you pass in the contract_hash and
    // the entry_point_names of the target contract as args.
    // With prior setup having been done, this can also be simplified.
    let contract_hash = runtime::get_named_arg("contract_hash");
    // the name of the entry point on the contract that returns a purse uref to receive token at
    // the actual name of the entry point is up to the smart contract authors
    let deposit_point_name = runtime::get_named_arg("deposit_point_name");
    // whatever entry point on the smart contract does the actual work if token has been transferred
    // the actual name of which is up to the smart contract authors.
    let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");

    // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)
    // for the caller to transfer to.
    let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});

    // transfer from the caller's purse to the purse provided by the contract; the transfer is handled
    // safely by the host and the caller's purse is never exposed to the called smart contract.
    system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)
    .unwrap_or_revert();

    // The contract being interacted with looks up the associated purse, checks its balance, etc.
    // within its logic. That side of it is entirely up to the smart contract authors to code; the caller
    // merely calls the logic. Also, the entry point might require one or more runtime arguments.
    // In all cases some discovery of the API of the contract you are calling is necessary.
    runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});
    }

    Scenario 2 - Advanced Variation

    In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract.

    -

    This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup.

    +

    This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup.

    \ No newline at end of file diff --git a/next/resources/tutorials/advanced/two-party-multi-sig/index.html b/1.5.X/resources/tutorials/advanced/two-party-multi-sig/index.html similarity index 57% rename from next/resources/tutorials/advanced/two-party-multi-sig/index.html rename to 1.5.X/resources/tutorials/advanced/two-party-multi-sig/index.html index 53047dd7b..55cefbc05 100644 --- a/next/resources/tutorials/advanced/two-party-multi-sig/index.html +++ b/1.5.X/resources/tutorials/advanced/two-party-multi-sig/index.html @@ -1,27 +1,27 @@ - + -Two-Party Multi-Sig | Casper Docs - Redux +Two-Party Multi-Sig | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Two-Party Multi-Signature Deploys

    -

    Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.

    + submit an issue on Github
    Version: 1.5.X

    Two-Party Multi-Signature Deploys

    +

    Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.

    This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:

      -
    1. You meet the prerequisites, including having the Casper command-line client and a valid node address
    2. +
    3. You meet the prerequisites, including having the Casper command-line client and a valid node address
    4. You have the main account's PublicKey hex (MA) and another PublicKey hex to associate (AA)
    5. -
    6. You have previously sent deploys to a Casper network
    7. +
    8. You have previously sent deploys to a Casper network

    Configuring the Main Account

    caution

    Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet.

    @@ -51,7 +51,7 @@

    chainspec. +
  • payment-amount - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network chainspec.
  • session-path - The path to the contract Wasm
  • session-arg - The contract takes the account hash of the associated account as an argument labeled deployment-account. You can pass this argument using the --session-arg flag in the command line client
  • @@ -61,11 +61,11 @@

    Confirming Processing and Account Status

    -

    Account configuration on a Casper blockchain is stored in a Merkle Tree and is a snapshot of the blockchain's Global State. The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the state-root-hash and is stored in every executed block.

    +

    Account configuration on a Casper blockchain is stored in a Merkle Tree and is a snapshot of the blockchain's Global State. The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the state-root-hash and is stored in every executed block.

    To check that the account was configured correctly, you need the state-root-hash corresponding to the block that contains your deploy. To obtain the state-root-hash, you need to:

      -
    1. Confirm the execution status of the deploy and obtain the hash of the block containing it
    2. -
    3. Query the block containing the deploy to obtain the corresponding state_root_hash
    4. +
    5. Confirm the execution status of the deploy and obtain the hash of the block containing it
    6. +
    7. Query the block containing the deploy to obtain the corresponding state_root_hash

    Using the state_root_hash and the hex-encoded-public-key of the main account, query the network and check the account's configuration.

    casper-client query-global-state \
    --node-address http://<peer-ip-address>:7777 \
    --state-root-hash <state-root-hash-from-block> \
    --key <hex-encoded-public-key-MA>
    @@ -73,6 +73,6 @@

    {
    "id": 1126043166167626077,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "merkle_proof": "2226 chars",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 2
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",
    "weight": 1
    },
    {
    "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
    "weight": 1
    }
    ],
    "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",
    "named_keys": []
    }
    }
    }
    }

    -

    In the example output, you can see the account hashes listed within the associated_keys section. Each key has weight 1; since the action threshold for deployment is 2, neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold.

    +

    In the example output, you can see the account hashes listed within the associated_keys section. Each key has weight 1; since the action threshold for deployment is 2, neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold.

    \ No newline at end of file diff --git a/next/resources/tutorials/beginner/aws-node/index.html b/1.5.X/resources/tutorials/beginner/aws-node/index.html similarity index 60% rename from next/resources/tutorials/beginner/aws-node/index.html rename to 1.5.X/resources/tutorials/beginner/aws-node/index.html index 25e3e6ad9..70ddcd251 100644 --- a/next/resources/tutorials/beginner/aws-node/index.html +++ b/1.5.X/resources/tutorials/beginner/aws-node/index.html @@ -1,21 +1,21 @@ - + -AWS Casper Nodes | Casper Docs - Redux +AWS Casper Nodes | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Launching a Casper Node with AWS Marketplace

    + submit an issue on Github
    Version: 1.5.X

    Launching a Casper Node with AWS Marketplace

    The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.

    Step 1 - Subscribing

    You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription.

    @@ -67,6 +67,6 @@

    EC2 Ke

    Step 12

    Launching Your Node

    If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange Launch button to launch your AWS-hosted Casper node.

    -

    Step 13

    +

    Step 13

    \ No newline at end of file diff --git a/1.5.X/resources/tutorials/beginner/cep18/index.html b/1.5.X/resources/tutorials/beginner/cep18/index.html new file mode 100644 index 000000000..bbe4c153b --- /dev/null +++ b/1.5.X/resources/tutorials/beginner/cep18/index.html @@ -0,0 +1,149 @@ + + + + + +Fungible Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Fungible Tokens (CEP-18) Implementation and Usage

    +

    This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:

    + +

    Outline of the Tutorial

    +

    This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol.

    +

    ERC-20 Standard

    +

    The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain.

    +

    It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana. +Some key points of the ERC-20 standard include:

    +
      +
    • +

      A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address.

      +
    • +
    • +

      Optional metadata functions like name(), symbol(), and decimals(), which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes.

      +
    • +
    • +

      A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets. +By adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens.

      +
    • +
    +

    Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols.

    +

    Interaction of ERC-20 Based Tokens with the Uniswap Standard

    +

    By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2.

    +

    Uniswap V2 uses ERC-20 tokens in the following scenarios:

    +
      +
    • Listing Tokens – Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard.
    • +
    • Liquidity Pools – any two pairs of ERC-20 tokens can be used to create a liquidity pool.
    • +
    • Uniswap V2 uses the ERC-20 standard transfer() function to allow an exchange of tokens within the liquidity pools.
    • +
    +

    ERC-20 Implementations on Casper and Implications for Decentralized Exchanges

    +

    There exist at least two different implementations of the ERC-20 Standard on Casper networks.

    + +

    While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks.

    +

    The following considerations should be applied when trying to create an ERC-20 Token:

    +
      +
    • +

      Interoperability – Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets.

      +
    • +
    • +

      Project Security Audits – Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities.

      +
    • +
    • +

      Ecosystem – The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration.

      +
    • +
    +

    The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities.

    +

    The Casper CEP-18 Standard

    +

    The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:

    +
      +
    • allowance - Returns the amount of owner’s tokens allowed to be spent by the spender
    • +
    • approve - Allows a spender to transfer up to an amount of the direct caller’s tokens
    • +
    • balance_of - Returns the token balance of the owner
    • +
    • decimals - Returns the decimal places applied to the balance of the token
    • +
    • name - Returns the name of the token
    • +
    • symbol - Returns the symbol of the token
    • +
    • total_supply - Returns the total supply of the token
    • +
    • transfer - Transfers an amount of tokens from the direct caller to a recipient
    • +
    • transfer_from - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner
    • +
    +

    For more detail on these methods, there is a reference implementation available on GitHub.

    +

    Creating a CEP-18 Token on the Testnet

    +

    Clone and Compile the CEP-18 Contract

    +

    Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state.

    +

    If you are unsure how to interact with Casper Contracts please refer to the following tutorial: Writing a Basic Smart Contract in Rust.

    +

    We will clone the token repository and prepare the token contract for sending in a Deploy.

    +
      +
    1. Clone the Fungible Token contract from the repository.
    2. +
    +
    	git clone https://github.com/casper-ecosystem/cep18.git
    +
      +
    1. +

      Make any necessary changes to the code for your customization requirements.

      +
    2. +
    3. +

      Compile the contract to create the target .wasm file and build the Wasm.

      +
    4. +
    +
        cd cep18
    make prepare
    make build-contract
    +
    tip

    If the build-contract finishes with an error wasm-strip: command not found, make sure you install an additional package on MacOS:

        brew install wabt
    +
      +
    1. Build and verify the compiled contract.
    2. +
    +
    	make test
    +

    Install the CEP-18 Contract

    +

    As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet.

    +

    Use the following template to install the contract on the Testnet:

    +

    casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --chain-name [NETWORK_NAME]] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [AMOUNT] \
    --session-path [WASM_FILE_PATH]/[File_Name].wasm
    --session-arg <"NAME:TYPE='VALUE'" OR "NAME:TYPE=null">

    +

    Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:

    +

    casper-client get-state-root-hash --node-address http://78.46.32.13:7777

    +

    You should obtain a response similar to:

    +
    {
    "id": 3323991011802671610,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.15",
    "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"
    }
    }
    +

    An exemplary deploy to the Casper Testnet is as follows:

    +

    casper-client put-deploy \
    --node-address http://78.46.32.13:7777 \
    --chain-name casper-test \
    --secret-key "./keys/secret_key.pem" \
    --payment-amount 150000000000 \
    --session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \
    --session-arg "name:string='CHF Coin'" \
    --session-arg "symbol:string='CHFC'" \
    --session-arg "decimals:u8='10'" \
    --session-arg "total_supply:u256='1000'"

    +
    info

    Always be mindful of the --secret-key and --session-path arguments. +Path provided to the arguments should always be with regard to the current folder, where the command is executed.

    The keys folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored.

    +

    The response from the put-deploy command should look like this:

    +

    {
    "id": 5066914343373494745,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.15",
    "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"
    }
    }

    +

    Using the deploy_hash the state of the deploy can be checked:

    +

    casper-client get-deploy \
    --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6

    +

    In the execution results we can see, that the deploy was successful:

    +

    ...
    "execution_results": [
    {
    "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",
    "result": {
    "Success": {
    "cost": "140416131900",
    "effect": {
    "operations": [],
    ...

    +

    Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with Out of gas error.

    +

    Query the Entry Points in the CEP-18 contract

    +

    Get the state root hash from the network:

    +
    casper-client get-state-root-hash --node-address http://78.46.32.13:7777
    +

    Your response should look similar to:

    +
    {
    "id": 2950480729544096556,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.15",
    "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"
    }
    }
    +

    With the state root hash and the account hash which performed the deploy, you can query the contract arguments.

    +
    casper-client query-global-state --node-address http://78.46.32.13:7777 \
    --state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \
    --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \
    -q "cep18_contract_hash_CHF Coin/name"
    +

    The above command will query the contract for the name. The template for the query is contract_name/named_key.

    +

    You will obtain the following response:

    +
    {
    "id": -7058786841478812744,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.15",
    "block_header": null,
    "merkle_proof": "[94526 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0800000043484620436f696e",
    "cl_type": "String",
    "parsed": "CHF Coin"
    }
    }
    }
    }
    +

    Try to query the contract for other Named Keys and check how the contract behaves.

    +

    Summary

    +

    In this tutorial, we:

    +
      +
    • Explained the ERC20 standard and what the implications are for not using the standard implementations.
    • +
    • Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy.
    • +
    • Installed the contract on the Testnet
    • +
    • Called an entry point on the contract to get the value of the Named Key name.
    • +
    + + \ No newline at end of file diff --git a/1.5.X/resources/tutorials/beginner/getting-started-tutorial/index.html b/1.5.X/resources/tutorials/beginner/getting-started-tutorial/index.html new file mode 100644 index 000000000..8cfe465f5 --- /dev/null +++ b/1.5.X/resources/tutorials/beginner/getting-started-tutorial/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Getting Started Video

    +

    This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.

    +

    + +

    + + \ No newline at end of file diff --git a/1.5.X/resources/tutorials/beginner/index.html b/1.5.X/resources/tutorials/beginner/index.html new file mode 100644 index 000000000..9e7ea5188 --- /dev/null +++ b/1.5.X/resources/tutorials/beginner/index.html @@ -0,0 +1,78 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Overview

    +

    Beginner Tutorials

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on an NCTL NetworkAn example contract that maintains a counter variable on a local Casper Network with NCTL
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Querying a Casper NetworkQueries for users and developers to obtain information stored on the blockchain
    Smart Contract UpgradesLearn how to upgrade smart contracts
    The Casper Fungible Token Standard (CEP-18)Fungible Token Standard (CEP-18) Implementation and Usage
    Launching a Casper Node with AWS MarketplaceLearn how to launch a Casper Node through the AWS Marketplace
    +

    GitHub Tutorials

    + + + + + + + + + + + + + + + + + +
    TitleDescription
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    + + \ No newline at end of file diff --git a/next/resources/tutorials/beginner/querying-network/index.html b/1.5.X/resources/tutorials/beginner/querying-network/index.html similarity index 77% rename from next/resources/tutorials/beginner/querying-network/index.html rename to 1.5.X/resources/tutorials/beginner/querying-network/index.html index 674ca4c50..51759a046 100644 --- a/next/resources/tutorials/beginner/querying-network/index.html +++ b/1.5.X/resources/tutorials/beginner/querying-network/index.html @@ -1,26 +1,26 @@ - + -Querying a Node | Casper Docs - Redux +Querying a Node | Casper Docs - Redux - - + +
    Skip to main content
    Version: 1.5.X

    Querying a Casper Node

    The Casper node supports queries for users and developers to obtain information stored on the blockchain.

    This document assumes:

      -
    1. You have met the prerequisites
    2. -
    3. You are familiar with the structure of the Global State and the Blockchain Design to query data from the network
    4. +
    5. You have met the prerequisites
    6. +
    7. You are familiar with the structure of the Global State and the Blockchain Design to query data from the network

    When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:

      @@ -45,7 +45,7 @@

      {
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.0.0",
      "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"
      },
      "id": 1
      }

    Querying an Account

    -

    Accounts are stored in the global state and can be queried using the query-global-state command:

    +

    Accounts are stored in the global state and can be queried using the query-global-state command:

    casper-client query-global-state \
    --id 4 \
    --node-address http://<node-ip-address>:7777 \
    --state-root-hash <state-root-hash> \
    --key <hex-encoded-source-account-public-key>

    Request fields:

      @@ -115,6 +115,6 @@

      Querying De
    • id - 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
    • deploy-hash - Hex-encoded hash of the deploy
    • -

    +
    \ No newline at end of file diff --git a/1.5.X/resources/tutorials/beginner/upgrade-contract/index.html b/1.5.X/resources/tutorials/beginner/upgrade-contract/index.html new file mode 100644 index 000000000..2fbaa16fe --- /dev/null +++ b/1.5.X/resources/tutorials/beginner/upgrade-contract/index.html @@ -0,0 +1,142 @@ + + + + + +Contract Upgrades | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Upgrading a Contract

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the add_contract_version API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.

    +

    Video Tutorial

    +

    Here is a video walkthrough of this tutorial.

    + +

    Prerequisites

    + +
    note

    Installing the first version of the contract (contract-v1.wasm) as shown in the counter tutorial is a prerequisite before installing the second version of the contract (contract-v2.wasm).

    +

    If you explore the code, you will observe the different versions of the contract:

    +
      +
    • contract-v1 is the counter contract you can see in the A Counter on the Testnet tutorial.
    • +
    • contract-v2 is the contract with the new counter_decrement entry point.
    • +
    • contract-v3 is the contract with the new get_last_updated_at entry point and last_updated_at named key.
    • +
    +

    Contract Versioning Flow

    +

    The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash.

    +
      +
    1. Create a contract in the most common way, using new_contract.
    2. +
    3. Add a new version of the contract using add_contract_version.
    4. +
    5. Build the new contract and generate the corresponding .wasm file.
    6. +
    7. Install the contract on the network via a deploy.
    8. +
    9. Verify that your new contract version works as desired.
    10. +
    +

    In this tutorial, you will use the second version of the counter contract to perform the upgrade.

    +

    Step 1. Create a new unlocked contract

    +

    Create a new contract using the new_contract function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned.

    +

    When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key.

    +
        // Create a new contract and specify a package name and access URef for further modifications
    let (stored_contract_hash, contract_version) = storage::new_contract(
    contract_entry_points,
    Some(contract_named_keys),
    Some("contract_package_name".to_string()),
    Some("contract_access_uref".to_string()),
    );

    // The hash of the installed contract will be reachable through a named key
    runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());

    // The current version of the contract will be reachable through a named key
    let version_uref = storage::new_uref(contract_version);
    runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());
    +

    The first version of the counter shows you a contract package that can be versioned. This step is covered in the tutorial for A Counter on the Testnet.

    +

    Additional details:

    +
      +
    1. We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used.
    2. +
    3. The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions.
    4. +
    +

    Step 2. Add a new contract to the package

    +

    There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract.

    +

    To add a new contract version in the package, invoke the add_contract_version function and pass in the ContractPackageHash, EntryPoints, and NamedKeys. In the counter example, you will find the add_contract_version call here.

    +
        let (contract_hash, contract_version) =
    storage::add_contract_version(contract_package_hash,
    entry_points,
    named_keys);
    +

    Explanation of arguments:

    +
      +
    • contract_package_hash - This hash directs you to the contract package. See Hash and Key Explanations.
    • +
    • entry_points - Entry points of the contract, which can be modified or newly added.
    • +
    • named_keys - Named key pairs of the contract.
    • +
    +

    The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract.

    +

    You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:

    +
      +
    1. Pin your client contract to the contract hash of a specific version.
    2. +
    3. Use call_versioned_contract with a version number to pin your client contract to that version.
    4. +
    5. Call a contract using call_versioned_contract and version "None", which uses the newest version of the contract.
    6. +
    +

    Step 3. Build the contract Wasm

    +

    Use these commands to prepare and build the newly added contract:

    +
    make prepare

    make build-contract
    +

    Step 4. Install the contract

    +

    Install the contract on the network via a deploy and verify the deploy status. You can also monitor the event stream to see when your deploy is accepted.

    +

    To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the counter_decrement entry point.

    +
    note

    Installing the first version of the contract, as shown in the Counter tutorial, is a prerequisite before installing the second version.

    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm
    +

    Step 5. Verify your changes

    +

    You can write unit tests to verify the behavior of the new contract version with call_contract or call_versioned_contract. When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version.

    +

    For the simple example counter above, here are the corresponding tests. Notice how the tests store and verify the contract's version and entry points.

    +

    You could store the latest version of the contract package under a NamedKey, as shown here. Then, you can query the NamedKey to check the latest version of the contract package.

    +
    Example test function
    + +
        // Verify the contract version is now 2.
    let account = builder
    .get_account(*DEFAULT_ACCOUNT_ADDR)
    .expect("should have account");

    let version_key = *account
    .named_keys()
    .get(CONTRACT_VERSION_KEY)
    .expect("version uref should exist");

    let version = builder
    .query(None, version_key, &[])
    .expect("should be stored value.")
    .as_cl_value()
    .expect("should be cl value.")
    .clone()
    .into_t::<u32>()
    .expect("should be u32.");

    assert_eq!(version, 2);
    +
    +

    You can also test the new entry point by using the Rust command-line client.

    +

    Get the NEW state-root-hash:

    +
    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777
    +

    Check the new contract entry points. You should see the counter_decrement entry point now.

    +
    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter"
    +
    Example output
    + +
     {
    "id": 5602352547578277096,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[54054 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",
    "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",
    "entry_points": [
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_decrement",
    "ret": "Unit"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_get",
    "ret": "I32"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_inc",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",
    "name": "count"
    }
    ],
    "protocol_version": "1.4.13"
    }
    }
    }
    }
    +
    +

    Check the version and package details with the latest state root hash:

    +
    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "version"
    +
    Example output
    + +
    {
    "id": 9084525900533244372,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[64874 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "02000000",
    "cl_type": "U32",
    "parsed": 2
    }
    }
    }

    +
    +
    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] -q "counter_package_name"
    +
    Example output
    + +
    {
    "id": 6933525663267881367,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_header": null,
    "merkle_proof": "[52174 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",
    "contract_version": 1,
    "protocol_version_major": 1
    },
    {
    "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",
    "contract_version": 2,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }


    +
    +

    Call the new entry point, counter_decrement, using the package name and check the results.

    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-package-name "counter_package_name" \
    --session-entry-point "counter_decrement"
    +
    note

    There are two ways to call versioned contracts:

      +
    1. Calling Contracts by Package Hash
    2. +
    3. Calling Contracts by Package Name
    4. +
    +

    After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash.

    +

    Disabling and Enabling Contract Versions

    +

    You can disable a contract version within a contract package by using the disable_contract_version function.

    +

    Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract.

    +

    Enable_contract_version allows you to re-enable a previously disabled contract version.

    +
    note

    Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so.

    +

    Creating a Locked Contract Package

    +

    You can create a locked contract package with the new_locked_contract function. This contract can never be upgraded.

    +
    let (stored_contract_hash, _) = storage::new_locked_contract(
    contract_entry_points,
    Some(contract_named_keys),
    Some("contract_package_name".to_string()),
    Some("contract_access_uref".to_string()),
    );
    +

    Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1.

    +
    note

    Creating a locked contract package is an irreversible decision. To upgrade a contract, use new_contract as Step 1 explains.

    +

    Adding New Fields During Upgrades

    +

    contract-v3 demonstrates adding new data storage to your contract. It introduces a new field for the last update timestamp.

    +

    Key Steps:

    +
      +
    1. +

      Define a Named Key: A key (LAST_UPDATED_KEY) references the new field.

      +
    2. +
    3. +

      Initialize the Field: A URef is created using storage::new_uref to point to the storage location. It's then added to NamedKeys along with the key.

      +
    4. +
    +

    Code Breakdown:

    +
    // Create NamedKeys and initialize the new field (last_updated) with default value (0).
    let mut named_keys = NamedKeys::new();
    let last_updated = storage::new_uref(0_u64);
    named_keys.insert(String::from(LAST_UPDATED_KEY), last_updated.into());
    +

    For a deeper dive into the implementation details, explore the contract-v3 code itself. This hands-on exploration will further solidify your understanding of adding new fields during contract upgrades.

    + + \ No newline at end of file diff --git a/1.5.X/runtime/index.html b/1.5.X/runtime/index.html new file mode 100644 index 000000000..19a5f52f4 --- /dev/null +++ b/1.5.X/runtime/index.html @@ -0,0 +1,39 @@ + + + + + +Runtime | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Runtime Economics

    +

    The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.

    +

    Gas allocation

    +

    Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas. We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant CEPs. In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme.

    +

    Consensus before execution & basics of payment

    +

    The Highway protocol in its Mainnet implementation reaches consensus on a block before the block is executed, introducing a subtle difference from platforms like Ethereum. In addition, deploys sent to a Casper network can only be selected based on claimed, rather than used, gas. Consequently, to incentivize user-side optimization and prevent block space exhaustion by poorly optimized deploys, the platform provides no refunds for unused gas.

    +

    Additionally, a minimal amount of CSPR must be present in the user account's main purse to ensure that the payment computation is covered. The community may introduce additional balance checks in the future.

    +

    Costs and limits

    +

    Gas cost is a measure of relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific more complex host-side functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the chainspec and may vary according to arguments.

    +

    We expect to refine the current gas cost table to reflect time use more closely, with updates introduced in future upgrades. We also anticipate that, with the introduction of state pruning, storage costs will be calculated separately from computing time.

    +

    Lanes

    +

    The block gas limit is split into two lanes, one for native transfers and one for general deploys. The number of transfers, which cost a fixed amount of gas, is governed directly by the block_max_transfer_count chainspec parameter, set to 2500 when Mainnet launched.

    +

    Gas fees

    +

    Currently, the price of gas is fixed at 1 mote per 1 unit of gas.

    +

    Fee allocation

    +

    All fees from a particular block accrue to its proposer, incentivizing non-empty block production and allowing major dApps to execute deploys for free, provided they operate a validator node and are comfortable with the latency introduced by validator scheduling.

    +

    Spot pricing

    +

    Please see CEP #22 for one potential design of a gas spot market.

    +

    Futures pricing

    +

    Please see CEP #17 for our draft proposal of a gas futures market.

    + + \ No newline at end of file diff --git a/1.5.X/sdk/index.html b/1.5.X/sdk/index.html new file mode 100644 index 000000000..d2c234944 --- /dev/null +++ b/1.5.X/sdk/index.html @@ -0,0 +1,74 @@ + + + + + +SDK Client Libraries | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    SDK Client Libraries

    +

    This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.

    +

    Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories.

    +

    Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories.

    +

    Serialization Standard

    +

    The Casper platform uses a custom serialization format. To this end, we've established a Serialization Standard, which must be followed when building a Casper SDK.

    +

    JSON-RPC API

    +

    Developers can interact directly with the Casper JSON-RPC API instead of using an SDK.

    +

    Table of Contents

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SDK DocumentationGitHub LocationOrganization
    JavaScript/TypeScriptcasper-js-sdkCasper Ecosystem
    Java SDKcasper-java-sdkCasper Association
    C# SDKcasper-net-sdkMAKE
    Go SDKcasper-go-sdkMAKE
    Python SDKcasper-python-sdkCasper Association
    PHP SDKcasper-php-sdkMAKE
    Scala SDKcasper-scala-sdkM. Abahmane
    + + \ No newline at end of file diff --git a/1.5.X/staking/index.html b/1.5.X/staking/index.html new file mode 100644 index 000000000..150ae44f5 --- /dev/null +++ b/1.5.X/staking/index.html @@ -0,0 +1,52 @@ + + + + + +Staking vs. Delegating | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Staking vs. Delegating

    +

    A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as staking or delegation. They can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.

    +

    Here are a few common topics related to staking, but we also encourage you to do your own research.

    +

    Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network.

    +

    Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate.

    +

    Casper does not treat validator stake differently than delegator stake for security reasons.

    +

    Slashing

    +

    Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated.

    +

    Delegation Rate

    +

    Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services.

    +

    Delegation Fees

    +

    It is important to know that the cost of the delegation process is approximately 3 CSPR. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse.

    +

    Rewards

    +

    Validators receive rewards proportional to their stake for securing the network and participating in consensus (by voting and finalizing blocks). Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot vote on many blocks.

    +

    There is no precise reward per block. Rewards are split proportionally among stakes within an era and are distributed at the end of each era.

    +

    Selecting a Node for Delegating

    +

    As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as cspr.live provide validator performance statistics, including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator.

    +

    +

    Monitoring Rewards

    +

    It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations.

    +

    Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours.

    +

    Unbonding Period

    +

    For security purposes, whenever tokens are un-delegated, the protocol will continue to keep the token locked for 14 hours.

    +

    Tutorials

    +

    Navigate to these pages for step-by-step tutorials on creating an account and delegating and undelegating tokens.

    +
    + + \ No newline at end of file diff --git a/1.5.X/users/block-explorer/index.html b/1.5.X/users/block-explorer/index.html new file mode 100644 index 000000000..1d25b6f6b --- /dev/null +++ b/1.5.X/users/block-explorer/index.html @@ -0,0 +1,40 @@ + + + + + +Block Explorers | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Block Explorers

    +

    The Casper blockchain is available as the Mainnet and Testnet. +The Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR). +The Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet.

    +

    You can use block explorers to explore the Casper blockchain such as :

    + +

    What is a Block Explorer

    +

    A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history.

    +

    Using a Block Explorer

    +

    You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of deploys, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator.

    +

    The following topics link you to detailed instructions on using the cspr.live block explorer to access and work with your CSPR tokens.

    + +
    note

    To perform actions using the cspr.live block explorer, you must sign in to your Casper account using one of the wallets provided.

    + + \ No newline at end of file diff --git a/1.5.X/users/csprlive/index.html b/1.5.X/users/csprlive/index.html new file mode 100644 index 000000000..687c10c82 --- /dev/null +++ b/1.5.X/users/csprlive/index.html @@ -0,0 +1,46 @@ + + + + + +Using CSPR.live | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Using the CSPR.live block explorer

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Funding Testnet AccountsFund a Testnet account for testing
    Transferring TokensTransfer tokens using the CSPR.live block explorer
    Delegating TokensDelegate tokens to a validator
    Undelegating TokensUndelegate tokens from a validator
    + + \ No newline at end of file diff --git a/1.5.X/users/delegate-ui/index.html b/1.5.X/users/delegate-ui/index.html new file mode 100644 index 000000000..0cc6d4dec --- /dev/null +++ b/1.5.X/users/delegate-ui/index.html @@ -0,0 +1,83 @@ + + + + + +Delegate Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Delegating Tokens with a Block Explorer

    +

    Introduction

    +

    This tutorial covers how to delegate Casper tokens to a validator on the network.

    +

    Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called delegation or staking. We will use these terms interchangeably in this guide. See the Staking Key Concepts page for more details about the differences.

    +

    Prerequisites

    +
      +
    1. To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the Casper Wallet by following the Getting Started user guide.
    2. +
    3. You need to fund the account's main purse to delegate tokens.
    4. +
    5. Connect to a block explorer to set up the delegation. This guide uses cspr.live and the Casper Wallet.
    6. +
    7. Review your account before starting the process.
    8. +
    9. Review the current delegation fees and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail.
    10. +
    +

    Reviewing your Account

    +

    Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:

    +
      +
    • The Liquid Account Balance, representing the tokens you have for immediate use
    • +
    • The Delegated Account Balance, representing the delegated tokens already staked with validators on the network
    • +
    • The Delegations tab, listing the validators to whom you have delegated tokens
    • +
    +

    +
      +
    • The Staking Rewards tab, showing the rewards received in each era
    • +
    +

    +

    Accessing the Delegation Feature

    +

    You can access the delegation functionality in two ways.

    +

    Option 1: Click Wallet from the top navigation menu and then click Delegate. In the next screen, you will need to specify the validator's public key or search for a validator.

    +

    +

    Option 2: Click Validators from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the Delegate button. The next screen will have the validator's public key pre-populated.

    +

    +

    Stepping through the Delegation Process

    +

    The following instructions will take you through the delegation process, starting with the "Delegation details" screen.

    +

    Step 1 - Delegation details

    +
      +
    1. Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field.
    2. +
    3. Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee.
    4. +
    5. Click Next.
    6. +
    +

    +

    Step 2 - Confirm the delegation

    +
      +
    1. Review the delegation details.
    2. +
    3. If everything is correct, click Confirm and delegate stake. If you wish to make changes, return to the previous screen.
    4. +
    +

    +

    Step 3 - Sign the delegation

    +
      +
    1. Sign the delegation by clicking Sign with Casper Wallet.
    2. +
    +

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.
    2. +
    +

    +
      +
    1. Click Sign in the Signature Request window to finalize the delegation.
    2. +
    +

    +

    The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the Deploy Details highlighted above.

    +

    Remember to Monitor your Stake. Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the Rewards tab on your account page on cspr.live.

    +

    If you want to undelegate your tokens, you can do so at any time. See the Undelegation Guide for details.

    +

    Video Tutorial

    +

    This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step.

    +
    + + \ No newline at end of file diff --git a/1.5.X/users/funding-from-exchanges/index.html b/1.5.X/users/funding-from-exchanges/index.html new file mode 100644 index 000000000..8e9878ae3 --- /dev/null +++ b/1.5.X/users/funding-from-exchanges/index.html @@ -0,0 +1,58 @@ + + + + + +Funding Mainnet Accounts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Funding Mainnet Accounts from an Exchange

    +

    To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.

    +

    This guide demonstrates a withdrawal from Coinlist to the Casper Mainnet using the cspr.live block explorer. You need to contact the exchange for instructions if you are working with a different exchange.

    +

    Prerequisites

    +

    Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on cspr.live and the field you need to specify in the withdrawal request from Coinlist.

    +

    +

    Transfers from Coinlist to Casper Mainnet

    +

    Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts.

    +
      +
    1. Log into your https://coinlist.co/ account.
    2. +
    3. Go to the "Wallet" tab.
    4. +
    +

    +
      +
    1. Click on the "CSPR" section.
    2. +
    +

    +
      +
    1. Click on the "Withdraw" button.
    2. +
    +

    +
      +
    1. Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.
    2. +
    +

    +
      +
    1. +

      Enter 0 in the "Transfer ID" field or another value that is meaningful to you. You MUST enter a value, or the transfer will fail!

      +
    2. +
    3. +

      Enter the CSPR amount you wish to transfer.

      +
    4. +
    5. +

      Click "Review".

      +
    6. +
    7. +

      Submit the transfer request. Wait approximately 5 minutes, and then go to the cspr.live site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.

      +
    8. +
    + + \ No newline at end of file diff --git a/1.5.X/users/index.html b/1.5.X/users/index.html new file mode 100644 index 000000000..eaa175d3f --- /dev/null +++ b/1.5.X/users/index.html @@ -0,0 +1,88 @@ + + + + + +Users Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Users Overview

    +

    General Topics

    + + + + + + + + + + + + + + + + + +
    TopicDescription
    Block ExplorersA guide to understanding block explorers
    Funding Mainnet AccountsFunding Mainnet accounts from an exchange
    +

    Using CSPR.live

    +

    Interact with the Casper blockchain using the cspr.live block explorer.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Funding Testnet AccountsFunding your Testnet account using the Faucet
    Delegating TokensStaking your Casper tokens with cspr.live
    Undelegating TokensUn-staking your Casper tokens
    Transferring TokensTransferring your Casper tokens using cspr.live
    +

    Using Ledger Devices

    +

    Interact with the Casper blockchain using a Ledger device.

    + + + + + + + + + + + + + + + + + +
    TopicDescription
    Ledger SetupA guide to setting up your Ledger device
    Delegating with Ledger DevicesDelegating tokens using your Ledger device
    + + \ No newline at end of file diff --git a/1.5.X/users/ledger/index.html b/1.5.X/users/ledger/index.html new file mode 100644 index 000000000..f9afc2d31 --- /dev/null +++ b/1.5.X/users/ledger/index.html @@ -0,0 +1,46 @@ + + + + + +Casper on Ledger | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/1.5.X/users/ledger/ledger-cspr-live/index.html b/1.5.X/users/ledger/ledger-cspr-live/index.html new file mode 100644 index 000000000..72d9907a3 --- /dev/null +++ b/1.5.X/users/ledger/ledger-cspr-live/index.html @@ -0,0 +1,142 @@ + + + + + +Ledger and CSPR.live | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Using Ledger and CSPR.live

    +

    This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.

    +

    Prerequisites

    +
      +
    1. Install a Chromium-based browser, such as Chrome or Brave, for use with cspr.live for the Casper Mainnet.
    2. +
    +

    Signing In

    +

    To use the Ledger device with the cspr.live block explorer, follow these steps:

    +
      +
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    2. +
    3. Open the Casper app on the Ledger device as shown above.
    4. +
    5. While keeping the Casper app open, navigate to cspr.live/sign-in.
    6. +
    +

    +
      +
    1. Click on the Connect button in the Ledger section.
    2. +
    +

    +
      +
    1. Click the Connect to Ledger wallet button next.
    2. +
    +

    +
      +
    1. Select an account you want to use.
    2. +
    +

    +
      +
    1. Your Ledger device is now connected to the block explorer, displaying your account details.
    2. +
    +

    +

    Viewing Account Details

    +
      +
    1. Open cspr.live.
    2. +
    3. Click on the account in the upper-right corner of the page.
    4. +
    +

    +
      +
    1. Click on the View Account button.
    2. +
    +

    +
      +
    1. You are presented with a page displaying details about your account. Check your account's main purse balance in the Liquid row under Total Balance.
    2. +
    +

    +

    Receiving Tokens

    +

    To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:

    +
      +
    1. Open the account details page as described here and copy the public key in the Public Key row.
    2. +
    3. Alternatively, click on the drop-down menu on your account address.
    4. +
    +

    +
      +
    1. Click on the Copy Public Key button and share it with the sender.
    2. +
    +

    +

    Sending Tokens

    +
      +
    1. Open cspr.live.
    2. +
    3. Sign in with your Ledger device.
    4. +
    5. Click on Wallet and then Transfer CSPR.
    6. +
    +

    +
      +
    1. Fill in the details for the transfer.
    2. +
    +

    +
      +
    1. Click on the Next button.
    2. +
    3. On the next page, click Confirm and transfer.
    4. +
    +

    +
      +
    1. On the Sign transaction page, click on the Sign with Ledger button.
    2. +
    +

    +
      +
    1. Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source account, fee, target, and amount). Meanwhile, the block explorer will show this message:
    2. +
    +

    +

    Verify the transaction on your Ledger device

    +

    Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see "Approve".

    +
      +
    1. Verify the Txn hash - ensure it matches the value displayed on cspr.live.
    2. +
    +

    +

    The Txn hash value continues on a second screen.

    +

    +
      +
    1. The next page displays transaction Type - for CSPR transfers, that will be Token transfer.
    2. +
    +

    +
      +
    1. Verify the Chain ID, which identifies the network to which you want to send the transaction.
    2. +
    +

    +
      +
    1. Verify the Account, the account's public key initiating the transaction.
    2. +
    +

    +

    The Account value continues on a second screen.

    +

    +
      +
    1. Verify the Fee. For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR.
    2. +
    +

    +
      +
    1. Verify the Target, the recipient's public key. Compare this value with the one in the block explorer.
    2. +
    +

    +

    The Target value continues on a second screen.

    +

    +
      +
    1. Verify the Amount you want to transfer.
    2. +
    +

    +
      +
    1. If you want to approve the transaction, click both buttons on the Ledger device while on the APPROVE screen.
    2. +
    +

    +

    After approving the transaction with your Ledger hardware wallet, the cspr.live block explorer will display a "Transfer completed" page.

    +

    +

    You can now check your account to see a list of all the completed transfers.

    + + \ No newline at end of file diff --git a/1.5.X/users/ledger/ledger-live/index.html b/1.5.X/users/ledger/ledger-live/index.html new file mode 100644 index 000000000..2d8f2f45e --- /dev/null +++ b/1.5.X/users/ledger/ledger-live/index.html @@ -0,0 +1,247 @@ + + + + + +Ledger and Ledger Live | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    Using Ledger and Ledger Live

    +

    This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.

    +
    important

    From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live.

    +

    Prerequisites

    +
      +
    1. Configure your Ledger and the Ledger Live application as described in the Getting Started with Ledger Live article.
    2. +
    3. Install the Casper app as described here.
    4. +
    +

    Connecting to Ledger Live

    +

    This section describes using the Ledger device with the Ledger Live application and your Casper accounts.

    +
      +
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    2. +
    +

    +Connect the Ledger to your computer +

    +
      +
    1. Allow Ledger Manager to connect by clicking the two buttons on the Ledger device.
    2. +
    +

    +Unlock the Ledger +

    +
      +
    1. Ledger Live will verify your Ledger device and display the following confirmation:
    2. +
    +

    +Confirmation that the Ledger is genuine +

    +
      +
    1. Click My Ledger in the left-side navigation bar, and search for Casper or CSPR in the App catalog.
    2. +
    +

    +Confirmation that the Ledger is genuine +

    +
      +
    1. To import a Casper account from the Ledger device into the Ledger Live application, click on the Add account link.
    2. +
    +

    +Click the Add account link +

    +
      +
    1. Open the Casper app on your Ledger device.
    2. +
    +

    +Open the Casper app +

    +
      +
    1. Ledger Live will import the first account listed on your Ledger device. Choose a name for the account.
    2. +
    +

    +Name the account +

    +
      +
    1. After synchronizing the account, Ledger Live will confirm that the account was successfully added.
    2. +
    +

    +Synchronizing the account +

    +

    +Confirmation that the account was added +

    +
      +
    1. Click on the account summary, to view more details.
    2. +
    +

    +Account summary +

    +

    +Account details +

    +
      +
    1. To add another account, open the Account option in the left-side navigation bar. Then, click on the Add account button.
    2. +
    +

    +Add a second account +

    +

    Receiving Tokens

    +

    To receive tokens, you need to provide the sender with your account's public key.

    +
    caution

    Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds.

    +
      +
    1. Click on the Receive option in the left-side navigation bar.
    2. +
    +

    +Click on Receive +

    +
      +
    1. Choose an account from the drop-down list.
    2. +
    +

    +Choose an account +

    +
      +
    1. Copy the address displayed, or use the corresponding QR code.
    2. +
    +

    +Choose an account +

    +
      +
    1. Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click APPROVE.
    2. +
    +

    +Verify address part 1 +

    +

    +Verify address part 2 +

    +

    +Click APPROVE +

    +

    +Confirmation displayed +

    +

    Sending Tokens

    +

    Ledger Live supports sending CSPR tokens from one Casper account to another.

    +
      +
    1. Start by clicking on the Send option in the left-side navigation bar. Choose the account to debit:
    2. +
    +

    +Choose the account to debit +

    +
      +
    1. Enter the recipient's address and click Continue.
    2. +
    +

    +Enter recipient +

    +
      +
    1. Enter the amount and an optional transfer ID. Click Continue.
    2. +
    +

    +Enter amount and transfer ID +

    +
      +
    1. Review the summary, and if everything is correct, click Continue. Otherwise, click the Back link in the top-left corner.
    2. +
    +

    +Review the transfer +

    +
      +
    1. Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source account, fee, target, and amount. Meanwhile, Ledger Live will display this message:
    2. +
    +

    +Review the transaction in the Ledger +

    +

    Verify the transaction on your Ledger device

    +

    Press the right button on your Ledger Device to review the transaction details until you see "APPROVE".

    +
      +
    1. Review the Txn hash.
    2. +
    +

    +3-txn-1 +

    +

    The Txn hash value continues on a second screen.

    +

    +4-txn-2 +

    +
      +
    1. The next screen displays the transaction Type, which will be Token transfer.
    2. +
    +

    +5-type +

    +
      +
    1. Verify the chain ID, which for Mainnet should be casper.
    2. +
    +

    +7-chain +

    +
      +
    1. Verify the Account initiating the token transfer.
    2. +
    +

    +8-account-1 +

    +

    The Account value continues on a second screen.

    +

    +9-account-2 +

    +
      +
    1. Verify the Fee. For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR.
    2. +
    +

    +10-fee +

    +
      +
    1. Verify the Target, which is the recipient's public key.
    2. +
    +

    +11-target-1 +

    +

    The Target value continues on a second screen.

    +

    +12-target-2 +

    +
      +
    1. Verify the Amount you want to transfer.
    2. +
    +

    +13-amount +

    +
      +
    1. If you want to approve the transaction, click both buttons on the Ledger device while on the APPROVE screen.
    2. +
    +

    +15-approve +

    +
      +
    1. After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:
    2. +
    +

    +Broadcasting transaction +

    +

    +Transaction sent +

    +
      +
    1. To view the transaction details, click on the View details button. The following screen will appear:
    2. +
    +

    +Transaction details +

    +
      +
    1. You can view the transaction in the CSPR.live block explorer by clicking on the View in explorer link.
    2. +
    +

    +Explorer showing transaction +

    + + \ No newline at end of file diff --git a/1.5.X/users/staking-ledger/index.html b/1.5.X/users/staking-ledger/index.html new file mode 100644 index 000000000..d7b7280ac --- /dev/null +++ b/1.5.X/users/staking-ledger/index.html @@ -0,0 +1,128 @@ + + + + + +Delegate with Ledger | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Delegating with Ledger Devices

    +

    Ledger Initialization

    +

    Before getting started, you need to complete two prerequisite steps:

    +
      +
    1. Set up your Ledger device using the official documentation.
    2. +
    3. Connect the Ledger to your cspr.live account by following the Ledger Setup guide.
    4. +
    +

    Important Notes

    +
      +
    1. <span style={{color:"#ee5945"}}>CRITICAL: Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key.
    2. +
    3. When logging in to cspr.live, the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (more info here). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in.
    4. +
    +

    Staking with a Validator

    +

    Connect and Login with Ledger

    +
      +
    1. +

      Connect your Ledger to your computer via USB and enter your PIN to unlock it.

      +
    2. +
    3. +

      Open the Casper app on the Ledger (you will see the message "Casper Ready").

      +

      +
    4. +
    5. +

      Sign in to cspr.live with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.

      +

      +
    6. +
    7. +

      Select the public key connected to your Ledger account.

      +

      +
    8. +
    9. +

      View your account by clicking on your public key at the top right corner.

      +

      +
    10. +
    +

    Receive Tokens from an External Source

    +

    This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the documentation.

    +

    Staking Tokens

    +

    Once you have tokens in your account, staking (delegating) with a validator is easy.

    +
      +
    1. +

      Go back to your account, but this time open the "delegate" tab located at: https://cspr.live/delegate-stake (alternatively, click on Wallet ⇒ Delegate Stake to go there).

      +
    2. +
    3. +

      From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you.

      +
    4. +
    5. +

      Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:

      +
        +
      1. Remember that the total delegation amount to one validator cannot be less than 500 CSPR.
      2. +
      3. Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later.
      4. +
      +
    6. +
    7. +

      Click "Next" to continue, as shown below.

      +

      +
    8. +
    9. +

      The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.

      +
    10. +
    11. +

      You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.

      +

      Note: If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.

      +

      +
    12. +
    13. +

      On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on cspr.live.

      +

      +
    14. +
    15. +

      Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.

      +

      +

      +
    16. +
    17. +

      At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.

      +

      Note: If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens.

      +

      +
    18. +
    +

    Unstaking with a Validator

    +

    Initiate the Undelegation

    +

    Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account's profile page, click "Undelegate" to get started.

    +

    +

    The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.

    +

    +

    You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.

    +

    Sign the Undelegation

    +

    You will have to sign the transaction to verify your account is initiating this action.

    +
      +
    1. +

      Connect your Ledger device to your computer.

      +
    2. +
    3. +

      Unlock your Ledger by entering your PIN.

      +
    4. +
    5. +

      Open the "Casper" app and ensure you see "Casper Ready".

      +
    6. +
    7. +

      Then back on cspr.live click the "Sign with Ledger" button shown below.

      +

      +
    8. +
    +

    On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.

    +

    +

    Note: There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.

    +

    +

    After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish.

    + + \ No newline at end of file diff --git a/1.5.X/users/testnet-faucet/index.html b/1.5.X/users/testnet-faucet/index.html new file mode 100644 index 000000000..978c74f3a --- /dev/null +++ b/1.5.X/users/testnet-faucet/index.html @@ -0,0 +1,40 @@ + + + + + +Testnet Funding | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Funding Testnet Accounts

    +

    The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.

    +

    Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below.

    +

    Requesting Testnet Tokens

    +

    To request test tokens, follow these steps:

    +
      +
    1. +

      Log into the Casper Testnet with the Casper Wallet. See the Getting Started user guide for detailed instructions.

      +
    2. +
    3. +

      Click Tools on the top menu bar and select Faucet from the drop-down menu. Or, navigate to the Faucet using this link: https://testnet.cspr.live/tools/faucet.

      +
    4. +
    5. +

      Click Request tokens on the Faucet page:

      +

      +
    6. +
    +
    caution

    Tokens can be requested only once per account. Otherwise, the deploy will fail with status User error: 1.

    If you have already exhausted your test funds, you can always create a new account.

    +
      +
    1. The Testnet will credit your account with test tokens.
    2. +
    + + \ No newline at end of file diff --git a/1.5.X/users/token-transfer/index.html b/1.5.X/users/token-transfer/index.html new file mode 100644 index 000000000..3c0fe4b62 --- /dev/null +++ b/1.5.X/users/token-transfer/index.html @@ -0,0 +1,57 @@ + + + + + +Transfer Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Transferring Tokens

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.

    +

    Transferring Tokens

    +

    To transfer tokens, follow these steps:

    +
      +
    1. Sign in to your account with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    2. +
    3. Click Wallet on the top menu bar and select Transfer CSPR from the drop-down menu.
    4. +
    5. Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one.
    6. +
    7. Click Next to proceed.
    8. +
    +

    +
      +
    1. A confirmation window appears to verify the details entered. Click Confirm and transfer to proceed to the next step.
    2. +
    +

    +
      +
    1. Review the following important fields:
    2. +
    +
      +
    • The Deploy hash, which uniquely identifies your transfer
    • +
    • The Recipient public key of the person receiving your transfer
    • +
    • The Recipient account hash used by the system to track the transaction
    • +
    • The Transfer Amount containing the value of the transfer
    • +
    +

    Sign the transaction by selecting the Sign with Casper Wallet button to proceed to the next step.

    +

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click Sign in the Signature Request window to complete the transaction.
    2. +
    +

    +
      +
    1. You completed the transaction and successfully transferred tokens.
    2. +
    +

    +
      +
    1. View the updated CSPR balance in the account's main purse next.
    2. +
    + + \ No newline at end of file diff --git a/1.5.X/users/undelegate-ui/index.html b/1.5.X/users/undelegate-ui/index.html new file mode 100644 index 000000000..aec527ebf --- /dev/null +++ b/1.5.X/users/undelegate-ui/index.html @@ -0,0 +1,61 @@ + + + + + +Undelegate Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Undelegating Tokens

    +

    If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.

    +

    Prerequisites

    +

    This guide assumes that you have previously delegated tokens to a validator using a block explorer or the Casper client.

    +

    Accessing the Undelegation Feature

    +

    You can access the undelegation functionality in three ways.

    +

    Option 1: Click Wallet from the top navigation menu and then click Undelegate Stake.

    +

    +

    Option 2: Click Validators from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the Undelegate Stake button.

    +

    +

    Option 3: Open your account details and select the Delegations tab. Click the Undelegate button next to the validator from whom you wish to undelegate.

    +

    +

    Stepping through the Undelegation Process

    +

    The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.

    +

    Step 1 - Undelegation details

    +
      +
    1. Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field.
    2. +
    3. Enter the amount of Casper tokens you want to undelegate.
    4. +
    5. Click Next.
    6. +
    +

    +

    Step 2 - Confirm the undelegation

    +
      +
    1. Review the undelegation details.
    2. +
    3. If everything looks correct, click Confirm and undelegate stake. If you wish to make changes, return to the previous screen.
    4. +
    +

    +

    Step 3 - Sign the undelegation

    +
      +
    1. Click Sign with Casper Wallet to sign the undelegation.
    2. +
    +

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.
    2. +
    +

    +
      +
    1. Click Sign in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:
    2. +
    +

    +

    It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.

    +

    Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours.

    + + \ No newline at end of file diff --git a/1.5.X/workflow/ledger-setup/index.html b/1.5.X/workflow/ledger-setup/index.html new file mode 100644 index 000000000..8010facbc --- /dev/null +++ b/1.5.X/workflow/ledger-setup/index.html @@ -0,0 +1,85 @@ + + + + + +Set up Ledger | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Ledger Setup with Casper

    +

    import useBaseUrl from '@docusaurus/useBaseUrl';

    +

    A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.

    +

    Prerequisites

    +
      +
    1. Configure your Ledger and the Ledger Live application as described in the Getting Started with Ledger Live article.
    2. +
    3. <span style={{color:"#ee5945"}}>CRITICAL: Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key.
    4. +
    5. Make sure the Ledger Live application version is at least at 2.73.1, which is the version that includes Casper accounts.
    6. +
    +
    note

    If you need help, contact us on Twitter, Discord, or Telegram.

    +

    Installing the Casper App on a Ledger Device

    +

    Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official Ledger support site.

    +
      +
    1. In Ledger Live, open My Ledger at the bottom of the left-hand menu.
    2. +
    +

    +Open My Ledger +

    +
      +
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    2. +
    +

    +Unlock your Ledger device +

    +
      +
    1. If asked, allow Ledger manager on your device.
    2. +
    +

    +Allow Ledger +

    +
      +
    1. Find Casper in the app catalog.
    2. +
    +

    +Find the Casper app +

    +
    important

    Having trouble finding the Casper app? +Please search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.

    +
      +
    1. Click the Install button of the app.
    2. +
    +
      +
    • An installation window appears.
    • +
    • Your device will display "Processing..."
    • +
    • The app installation is confirmed.
    • +
    +

    +Casper installation confirmed +

    +
      +
    1. Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps.
    2. +
    +

    +Select Casper on Ledger +

    +

    +Casper app is ready +

    +

    Sending and Receiving Tokens

    +

    To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:

    +
      +
    1. Manage Casper Accounts using Ledger and Ledger Live
    2. +
    3. Manage Casper Accounts using Ledger and CSPR.live
    4. +
    +

    To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in Delegating with Ledger Devices.

    +

    Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange.

    + + \ No newline at end of file diff --git a/1.5.X/writing-contracts/index.html b/1.5.X/writing-contracts/index.html new file mode 100644 index 000000000..86f61270f --- /dev/null +++ b/1.5.X/writing-contracts/index.html @@ -0,0 +1,150 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 1.5.X

    Writing On-Chain Code

    +

    This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.

    +

    + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started with RustAn introduction to using Rust with the Casper Platform
    Getting Started with AssemblyScriptAn introduction to using AssemblyScript with the Casper Platform
    Writing a Basic Smart Contract in RustAn example of a smart contract built in Rust
    Unit Testing Smart ContractsSteps to test contract code using the unit testing framework
    Upgrading and Maintaining Smart ContractsAn introduction to versioning smart contracts
    Calling Contracts
    Smart Contracts and Session CodeUnderstand what session code is and when you would use it over contract code
    Writing Session CodeAn introduction to writing session code
    Unit Testing Session CodeSteps to test session code using the unit testing framework
    Using Contract Hash vs. Package HashAdvantages and disadvantages of using contract_hash vs. contract_package_hash when calling a contract
    Best Practices for Casper Smart Contract AuthorsAn 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 covers installing and calling contracts using the Casper command-line client written in Rust.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Installing Smart Contracts and Querying Global StateA guide on installing smart contracts and querying global state
    Calling Smart Contracts with the Rust ClientSteps to call a smart contract with the Rust command-line client
    Reading and Writing to DictionariesInformation on Dictionaries and how to read and write to them on the Casper Platform.
    Execution Error CodesPossible error codes when writing smart contracts.
    +

    Tutorials

    +

    The following tutorials outline some aspects of writing smart contracts on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Smart Contract UpgradesLearn how to upgrade smart contracts
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    Interacting with Runtime Return ValuesLearning how to return a value using contract code
    Working with Authorization KeysRetrieving and using the authorization keys associated with a deploy
    Safely Transfer Tokens to a ContractHow to handle tokens via a contract
    + + \ No newline at end of file diff --git a/2.0.0/concepts/about/index.html b/2.0.0/concepts/about/index.html new file mode 100644 index 000000000..0ae560917 --- /dev/null +++ b/2.0.0/concepts/about/index.html @@ -0,0 +1,29 @@ + + + + + +What is Casper? | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    What is Casper?

    What is Casper?

    +

    Casper is a Turing-complete smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    +

    The network's consensus protocol is called Zug, and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of finality, meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

    +

    Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's core features and strengths enable developers and enterprises to reap the benefits of blockchain technology.

    +

    Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises.

    +

    How does Casper work?

    +

    Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network.

    +

    To understand the design further, read this article.

    +

    Disclaimer

    +

    Read the Legal Disclaimer regarding this CasperLabs Tech Spec (this "Whitepaper").

    + + \ No newline at end of file diff --git a/next/concepts/accounts-and-keys/index.html b/2.0.0/concepts/accounts-and-keys/index.html similarity index 75% rename from next/concepts/accounts-and-keys/index.html rename to 2.0.0/concepts/accounts-and-keys/index.html index 7c35b0214..dfee1440d 100644 --- a/next/concepts/accounts-and-keys/index.html +++ b/2.0.0/concepts/accounts-and-keys/index.html @@ -1,22 +1,22 @@ - + -Accounts and Keys | Casper Docs - Redux +Accounts and Keys | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Accounts and Cryptographic Keys

    -

    The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.

    + submit an issue on Github
    Version: 2.0.0

    Accounts and Cryptographic Keys

    +

    The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.

    By default, a transactional interaction with the blockchain takes the form of a Transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

    The Casper platform supports two types of keys for creating accounts and signing transactions:

      @@ -57,7 +57,7 @@

      Casper Wallet, Ledger, or Torus Wallet.

      caution

      The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined here.

      Funding your Account

      -

      Once you create your account, you can fund the account's main purse to finish the process of setting it up.

      +

      Once you create your account, you can fund the account's main purse to finish the process of setting it up.

      note

      Until you fund your account's main purse, it does not exist on the blockchain.

      Working with Existing Ethereum Keys

      You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:

      @@ -67,7 +67,7 @@

      casper-client transfer \
      --transfer-id 1234567 \
      --node-address http://localhost:7777 \
      --chain-name casper \
      --target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \
      --amount 10000000000 \
      --secret-key <path-to-secret_key.pem> \
      --payment-amount 100000000

    -
    tip

    The payment amount varies based on each transaction and network chainspec.

    +
    tip

    The payment amount varies based on each transaction and network chainspec.

    The Casper command-line client requires the secret key in PEM format to send a transaction from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to PEM format is needed.

    The following example is a JS script that generates a PEM file, using a key encoder and Node.js. To install these components, do the following:

    sudo apt install nodejs
    npm install key-encoder
    @@ -106,6 +106,6 @@

    casper-client get-account-info --help

    Using a block explorer

    Using the block explorer for Mainnet or Testnet, open the Account in question, and expand the Raw Data section. Look for the main_purse field and find the corresponding URef. If you do not see data in the Raw Data section, then the account has not been funded yet.

    -

    Main purse

    +

    Main purse

    \ No newline at end of file diff --git a/2.0.0/concepts/addressable-entity/index.html b/2.0.0/concepts/addressable-entity/index.html new file mode 100644 index 000000000..ef2c02435 --- /dev/null +++ b/2.0.0/concepts/addressable-entity/index.html @@ -0,0 +1,40 @@ + + + + + +Addressable Entities | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Addressable Entities

    +

    What is an Addressable Entity?

    +

    The AddressableEntity data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system. +Casper 2.0 introduces the concept of an AddressableEntity which replaces the existing Account and Contract types.

    +

    The merger of the Account and Contract concepts allows for some new possibilities.

    +

    For any given AddressableEntity, the EntityType will identify if it is an Account, a user-deployed SmartContract, or a System contract such as Mint or HandlePayment.

    +

    This EntityType will dictate what the addressable entity can and cannot do.

    +

    Account

    +

    An addressable entity marked as an Account will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a PublicKey and a secret key, and an AccountHash derived from the public key. There is also an associated main purse.

    +

    A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same.

    +

    SmartContract

    +

    An addressable entity marked as a SmartContract will have the same functionality as a legacy contract, but with several new features. The SmartContract now possesses a main purse, and may have associated keys and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found here.

    +

    System

    +

    As part of the migration to Casper 2.0, system contracts (Mint, Auction and HandlePayment) will migrate to a special type of addressable entity with the EntityType of System. The StandardPayment system contract will be pruned away.

    +

    Further Reading

    +
    + + \ No newline at end of file diff --git a/2.0.0/concepts/callstack/index.html b/2.0.0/concepts/callstack/index.html new file mode 100644 index 000000000..4477fa9d9 --- /dev/null +++ b/2.0.0/concepts/callstack/index.html @@ -0,0 +1,33 @@ + + + + + +Call Stacks | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Understanding Call Stacks

    +

    Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.

    +

    When the session code within a transaction interacts with one or more contracts, this is the beginning of a Call Stack. A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code.

    +

    The Caller

    +

    In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the zeroth entity in each call stack. The account that initiated the transaction can be retrieved with the contract_api::runtime::get_caller function.

    +

    The Call Stack

    +

    Developers can access the call stack with the contract_api::runtime::get_call_stack function.

    +

    If session code calls a contract, which in turn calls another contract, then the session code would represent the zeroth entity in the stack, the contract called by the initiating session code would be the first and the contract called by the first contract would be the second.

    +

    In this example, the first contract would be the immediate caller of the second contract, meaning it interacted directly with it. The session code would remain the caller.

    +

    Call Stack

    +

    Limitations

    +

    Casper networks place a limitation on the maximum height of a call stack. This value can be set within the chainspec for the network in question. For the Casper Mainnet, this limit is set at 10 contracts. This does not include the initiating session code, which would still count as the zeroth instance within the stack.

    +

    As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation.

    +
    note

    Contract code cannot call session code, only other contract code.

    + + \ No newline at end of file diff --git a/next/concepts/design/casper-design/index.html b/2.0.0/concepts/design/casper-design/index.html similarity index 60% rename from next/concepts/design/casper-design/index.html rename to 2.0.0/concepts/design/casper-design/index.html index 273852286..ecd644dd4 100644 --- a/next/concepts/design/casper-design/index.html +++ b/2.0.0/concepts/design/casper-design/index.html @@ -1,23 +1,23 @@ - + -Network Design | Casper Docs - Redux +Network Design | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Casper Network Design

    + submit an issue on Github
    Version: 2.0.0

    Casper Network Design

    Introduction

    -

    Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a transaction. Transactions may contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

    +

    Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a transaction. Transactions may contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

    A transaction executes in the context of the user's Account but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an Unforgeable Reference or URef. After a node accepts a transaction as valid, it places the transaction in a proposed Block and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction.

    1. @@ -39,11 +39,11 @@

      IntroductionExecution Semantics

      A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model.

      Measuring Computational Work

      -

      Computation is done in a WebAssembly (Wasm) interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses Gas to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a Gas cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter.

      +

      Computation is done in a WebAssembly (Wasm) interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses Gas to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a Gas cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter.

      Costs for opcode instructions on the Casper Mainnet network can be found here.

      All executions are finite because each has a finite gas limit that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction.

      Although the network measures costs in Gas, payment for computation occurs in motes. Therefore, there is a conversion rate between Gas and motes.

      -
      note

      Casper networks support configurable fee, refund, and pricing strategies to incentivize the Casper Runtime Economics by efficiently allocating computational resources. The consensus-before-execution model implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions.

      +
      note

      Casper networks support configurable fee, refund, and pricing strategies to incentivize the Casper Runtime Economics by efficiently allocating computational resources. The consensus-before-execution model implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions.

      The Casper Network Runtime

      A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state.

      Casper Network Runtime

      @@ -52,11 +52,11 @@

      Ge

      URefs are generated using a cryptographically secure random number generator using the ChaCha algorithm. The random number generator is seeded by taking the blake2b256 hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same transaction).

      Generating URefs

      Accounts

      -

      The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The global state trie store requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants.

      +

      The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The global state trie store requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants.

      The Casper platform supports two types of keys for creating accounts and signing transactions:

        -
      • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
      • -
      • Secp256k1 keys, commonly known as Ethereum keys, which are 68 bytes long
      • +
      • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
      • +
      • Secp256k1 keys, commonly known as Ethereum keys, which are 68 bytes long

      By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see Tokens for more information).

      This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts.

      @@ -92,7 +92,7 @@

      The Account

      A transaction is a user request to perform some execution on the blockchain (see Execution Semantics for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity's context.

      note

      In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity.

      Unforgeable Reference (URef)

      -

      This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

      +

      This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

      Permissions for URefs

      In the runtime, a URef carries its permissions called AccessRights. Additionally, the runtime tracks what AccessRights would be valid for each URef in each context. The system assumes that a sent URef is invalid, regardless of declared AccessRights, and will check it against the executing context to determine validity on each usage. Only the host logic can add a URef, in the following ways:

        @@ -104,7 +104,7 @@

        Permissions

        Note that only valid URefs may be added to the known URefs or cross-call boundaries; this means the system cannot be tricked into accepting a forged URef by getting it through a contract or stashing it in the known URefs.

        The ability to pass URefs between contexts via call_contract / ret, allows them to share state among a fixed number of parties while keeping it private from all others.

        URefs and Purses

        -

        Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual entities do not own ‘URef’s. As described above, entities possess certain Access Rights, allowing them to interact with the given URef. While an account entity will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

        +

        Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual entities do not own ‘URef’s. As described above, entities possess certain Access Rights, allowing them to interact with the given URef. While an account entity will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

        Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required.

        Block Structure

        A block is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure.

        @@ -119,7 +119,7 @@

        Data Fi

        block_hash

        The block_hash is the blake2b256 hash of the block header.

        -

        The block header contains the following fields:

        +

        The block header contains the following fields:

        • parent_hash

          @@ -163,11 +163,11 @@ -

          The block body contains an ordered list of transaction hashes. All transactions, including mint, auction, install_upgrade and standard transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no transactions.

          +

          The block body contains an ordered list of transaction hashes. All transactions, including mint, auction, install_upgrade and standard transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no transactions.

          The block body also contains the public key of the validator that proposed the block.

          -

          Refer to the Serialization Standard for additional information on how blocks and transactions are serialized.

          +

          Refer to the Serialization Standard for additional information on how blocks and transactions are serialized.

          Tokens

          -

          Casper is a decentralized Proof-of-Stake blockchain platform that may use either the Highway or Zug consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

          +

          Casper is a decentralized Proof-of-Stake blockchain platform that may use either the Highway or Zug consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

          This chapter describes tokens and how one can use them on the Casper platform.

          Token Generation and Distribution

          A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available here. In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage.

          @@ -177,7 +177,7 @@

          Divisibi

          Typically, a token is divisible into some number of parts. We call the indivisible units which make up the CSPR token motes. Each CSPR is divisible into 109 motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 1018 parts called Wei.

          The concept of CSPR is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with motes.

          Purses and Addressable Entities

          -

          All entities on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the source and the main purse of the account entity at the provided key as the target.

          +

          All entities on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the source and the main purse of the account entity at the provided key as the target.

          The Casper Mint Contract

          The Casper mint is a system contract that manages the balance of motes within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's main purse. Each balance is associated with a URef, which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as purses and conceptually represent a container for motes. The URef is how a purse is referenced externally, outside the mint.

          The AccessRights of the URefs permissions model determines what actions can be performed when using a URef associated with a purse.

          @@ -231,6 +231,6 @@

          The mi
        • BalanceResult either returns the number of motes held by the purse, or nothing if the URef is not valid
        -
    +
    \ No newline at end of file diff --git a/2.0.0/concepts/design/consensus/index.html b/2.0.0/concepts/design/consensus/index.html new file mode 100644 index 000000000..8118c04cb --- /dev/null +++ b/2.0.0/concepts/design/consensus/index.html @@ -0,0 +1,68 @@ + + + + + +Consensus in a Casper Network | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Consensus in a Casper Network

    +

    The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.

    +

    Safety, Liveness, and Byzantine Fault Tolerance

    +

    In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The Transaction Lifecycle describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called safety.

    +

    The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called liveness.

    +

    Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a Byzantine fault and thus secure against malicious activity.

    +

    To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:

    +
      +
    • +

      Safety: All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain.

      +
    • +
    • +

      Liveness: The network runs indefinitely and adds new blocks to the chain.

      +
    • +
    • +

      Byzantine Fault Tolerance (BFT): All honest nodes eventually agree on the final value, even if some are faulty.

      +
    • +
    +

    Casper Consensus Protocols

    +

    Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are Zug and Highway. Highway served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast, which describes how Zug meets the safety, liveness, and resiliency requirements.

    +

    Consensus in the Casper Mainnet

    +

    The Casper Mainnet is a Proof-of-Stake network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of nodes, which participate in the consensus process by staking CSPR tokens. These active nodes are known as validators. The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus.

    +

    The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are honest nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly.

    +
    note

    The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model.

    +

    Dynamic Round Length

    +

    Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner.

    +

    Eras

    +

    The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:

    +
      +
    • +

      Data Reduction - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.

      +
    • +
    • +

      Banning Equivocators - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras.

      +
    • +
    +
      +
    • Rotating Validators - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (current era+ 2).
    • +
    +

    In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (current era + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain.

    +

    The final block of an era is a switch block and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the switch block and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the Consensus Economics page.

    +

    Finality

    +

    Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart.

    +

    On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously.

    + +
      +
    • Zug Consensus - An overview of the Zug consensus used in Mainnet and Testnet
    • +
    • Highway Consensus - Brief overview of the Highway consensus available as an alternative to Zug
    • +
    + + \ No newline at end of file diff --git a/2.0.0/concepts/design/highway/index.html b/2.0.0/concepts/design/highway/index.html new file mode 100644 index 000000000..7d064b4bd --- /dev/null +++ b/2.0.0/concepts/design/highway/index.html @@ -0,0 +1,45 @@ + + + + + +Highway Consensus | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    The Highway Consensus Protocol

    +

    The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.

    +

    Unit Broadcasting

    +

    In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:

    +
      +
    • Citations of other units (at most one per node), subject to validity conditions
    • +
    • An optional proposed list of transactions to be included in a block. Note that the list can be empty
    • +
    • The unit's creator and its digital signature
    • +
    • Additional metadata, including a timestamp, sequence number, round length, etc.
    • +
    +

    An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn't clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.

    +

    Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges.

    +

    DAG

    +

    Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator.

    +

    The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era.

    +

    Block Finalization

    +

    In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum q, a percentage of the participating validator weight, and a level k. Level k represents the depth in the graph. For a given fault tolerance threshold t (FTT), finality is defined as:

    +

    Finality Equation

    +

    If q is close to n, meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT).

    +

    The existence of such a summit means that a weight of more than t would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block.

    +

    In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network.

    + +
      +
    • Highway Whitepaper - Describes the protocol, and the liveness and safety proofs in detail
    • +
    • Zug Consensus - The protocol currently used in Mainnet and Testnet
    • +
    + + \ No newline at end of file diff --git a/next/concepts/design/networking-protocol/index.html b/2.0.0/concepts/design/networking-protocol/index.html similarity index 93% rename from next/concepts/design/networking-protocol/index.html rename to 2.0.0/concepts/design/networking-protocol/index.html index 0348e3f60..e9d48600c 100644 --- a/next/concepts/design/networking-protocol/index.html +++ b/2.0.0/concepts/design/networking-protocol/index.html @@ -1,21 +1,21 @@ - + -Casper Node Networking Protocol | Casper Docs - Redux +Casper Node Networking Protocol | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Casper Node Networking Protocol

    + submit an issue on Github
    Version: 2.0.0

    Casper Node Networking Protocol

    Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)

    This is a description of the casper-node's networking protocol. This document follows the conventions laid out in RFC2119.

    Connection Level

    @@ -89,7 +89,7 @@

    The P

    The Payload (found in the node sources as Message in payload.rs) contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in bincode encoding, this should have no effect on implementations.

    enum Payload {
    Consensus(ConsensusMessage),
    DeployGossiper(DeployGossiperMessage),
    AddressGossiper(AddressGossiperMessage),
    GetRequest {
    tag: Tag,
    serialized_id: Vec<u8>,
    },
    GetResponse {
    tag: Tag,
    serialized_item: Vec<[u8]>,
    },
    FinalitySignature(FinalitySignature),
    }

    enum DeployGossiperMessage {
    Gossip(DeployHash),
    GossipResponse {
    item_id: DeployHash,
    is_already_held: bool,
    },
    }

    enum AddressGossiperMessage {
    Gossip(GossippedAddress),
    GossipResponse {
    item_id: GossippedAddress,
    is_already_held: bool,
    },
    }

    struct DeployHash(Digest);
    struct GossipedAddress(SocketAddr);

    Consensus

    -

    A consensus message is sent exclusively between instances of the consensus component, from one peer to another.

    +

    A consensus message is sent exclusively between instances of the consensus component, from one peer to another.

    Gossiping

    Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address.

    A node must support a gossiper for deploys and one for GossippedAddress, which is an alias for the regular Rust standard library's SocketAddr.

    @@ -117,7 +117,7 @@

    GetRequestsIf the item was found, serialized_item MUST contain a serialized FetchedOrNotFound::Fetched instance, with the inner value T being the item.

    If the item was not found, serialized_item MUST contain a FetchedOrNotFound::NotFound instance, with the inner value Id being the ID found in the originating GetRequest.

    A node MUST not send any items to a peer that it itself has not verified.

    -

    The following table shows which tag corresponds to which ID and item type. Type definitions for DeployHash and GossippedAddress can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the Serialization Standard, but be aware that those docs describe serializing using bytesrepr rather than bincode.

    +

    The following table shows which tag corresponds to which ID and item type. Type definitions for DeployHash and GossippedAddress can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the Serialization Standard, but be aware that those docs describe serializing using bytesrepr rather than bincode.

    @@ -204,6 +204,6 @@

    Trie Chunking<

    Large trie nodes are split when transferred across the network, according to CHUNK_SIZE_BYTES, which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a TrieOrChunk::Trie instance.

    Should a trie node be larger than this, a Merkle tree is constructed with CHUNK_SIZE_BYTES sized chunks and is identified by the root hash of the resulting tree instead.

    Peers MUST only request chunks. The TrieOrChunkId type allows for requesting the n-th chunk of a given trie node. See the casper-hashing crate for details.

    -

    A node receiving a TrieOrChunk item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it.

    +

    A node receiving a TrieOrChunk item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it.

    \ No newline at end of file diff --git a/2.0.0/concepts/design/p2p/index.html b/2.0.0/concepts/design/p2p/index.html new file mode 100644 index 000000000..d8bd9468a --- /dev/null +++ b/2.0.0/concepts/design/p2p/index.html @@ -0,0 +1,53 @@ + + + + + +Network Communication | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Network Communication

    +

    Identity

    +

    Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID.

    +

    Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint.

    +

    Inter-node connections

    +

    Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the client and the remote node the server for this connection.

    +

    During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks.

    +

    Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected.

    +

    Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see Node Discovery on how the server finds endpoints).

    +

    Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it.

    +

    Network

    +

    As soon as a node has connected to one node in the network, it partakes in Node Discovery. In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network.

    +

    Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below.

    +

    In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped.

    +

    Gossiping

    +

    Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see Identity). Each of these objects is immutable and can be identified by a unique hash.

    +

    Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed.

    +

    The process can be summarized as follows:

    +

    Given a message M to gossip, the desired saturation S, and an infection limit L:

    +
      +
    1. Pick a subset T of K nodes from all currently connected nodes.
    2. +
    3. Send M to each node in T, noting which nodes were already infected (a node is considered infected if it already had received or known M).
    4. +
    5. For every node shown as already infected, add another random node outside to T and send it M, again noting the response.
    6. +
    7. End when we confirm infection of L new nodes or encountered S already infected nodes.
    8. +
    +

    Through this process, a message will spread to almost all nodes over time.

    +

    Requesting missing data

    +

    While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block.

    +

    Validation

    +

    Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node.

    +

    Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved.

    +

    Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so.

    +

    Node Discovery

    +

    Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/index.html b/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/index.html new file mode 100644 index 000000000..436e1f24a --- /dev/null +++ b/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/index.html @@ -0,0 +1,36 @@ + + + + + +Reading and Writing Data | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Reading and Writing Data to Global State

    +

    Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.

    +
    note

    Casper's Condor release shifts NamedKeys to a top-level key type, making them more viable for larger data sets.

    +

    Using the Casper JSON-RPC

    +

    The query_global_state method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the Querying a Casper Network tutorial.

    +

    Using the Casper Rust API

    +

    The Casper API includes the following functions for reading and writing to global state:

    +
      +
    • put_key - Stores the given Key under the given name in the current context's named keys
    • +
    • get_key - Returns the requested NamedKey from the current context
    • +
    • storage::new_uref - Creates a new URef in the current context
    • +
    • storage::write - Writes a given value under a previously created URef
    • +
    • storage::read - Reads the value from a URef in global state
    • +
    • dictionary_put - Writes the given value under the given dictionary_item_key
    • +
    • dictionary_get - Retrieves the value stored under a dictionary_item_key
    • +
    +

    For more details, see the Reading and Writing to Global State using Rust tutorial.

    + + \ No newline at end of file diff --git a/next/concepts/design/rewards/index.html b/2.0.0/concepts/design/rewards/index.html similarity index 53% rename from next/concepts/design/rewards/index.html rename to 2.0.0/concepts/design/rewards/index.html index a9b09c82d..801bb837a 100644 --- a/next/concepts/design/rewards/index.html +++ b/2.0.0/concepts/design/rewards/index.html @@ -1,24 +1,24 @@ - + -Rewards Design | Casper Docs - Redux +Rewards Design | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Network Participation Rewards

    + submit an issue on Github
    Version: 2.0.0

    Network Participation Rewards

    Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.

    Like other Proof-of-Stake chains, a Casper network rewards validators for participating in building a linear chain of blocks, each containing ordered state changes and ensuring that the entire ecosystem of validators, builders, and users eventually achieve common knowledge of the chain's history. External, non-validator participants in the ecosystem can thus have a high degree of confidence on the canonical history of the blockchain's state, thus making the blockchain economically useful.

    -

    The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both Zug and Highway. The current reward scheme has the following properties:

    +

    The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both Zug and Highway. The current reward scheme has the following properties:

    • Rewards are proportional to a validator's weight on average.
    • The reward scheme incentivizes cooperation.
    • @@ -62,6 +62,6 @@

      The block proposer gets a portion corresponding to the finders_fee chainspec parameter, scaled by the total collected signature creator weight divided by the total weight in the relevant era.

    Rewards Pot

    -

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the signature_rewards_max_delay parameter, to compensate for the delay in creating and distributing finality signatures.

    +

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the signature_rewards_max_delay parameter, to compensate for the delay in creating and distributing finality signatures.

    \ No newline at end of file diff --git a/next/concepts/design/zug/index.html b/2.0.0/concepts/design/zug/index.html similarity index 58% rename from next/concepts/design/zug/index.html rename to 2.0.0/concepts/design/zug/index.html index b9f1d2965..64482ecfe 100644 --- a/next/concepts/design/zug/index.html +++ b/2.0.0/concepts/design/zug/index.html @@ -1,21 +1,21 @@ - + -Zug Consensus | Casper Docs - Redux +Zug Consensus | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Simple and Fast Consensus with Zug

    + submit an issue on Github
    Version: 2.0.0

    Simple and Fast Consensus with Zug

    The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.

    The Zug protocol requires that at most one-third of the validator weight could be attributed to faulty validators. It also assumes that there exists an upper bound for the network delay, which is the duration for a correct validator to deliver a message. The value of the upper bound may be unknown, but it exists. Under these conditions, all correct nodes will reach agreement on a chain of finalized blocks.

    Of course, all nodes in a network have to run the same protocol to work together, but when starting a new network or upgrading an existing one, either Highway or Zug can now be selected as the consensus_protocol in the chainspec file. The Casper Mainnet will switch to Zug.

    @@ -81,6 +81,6 @@

    Block Rewards<

    Casper 2.0.0 will distribute a configurable fraction of the seigniorage as a reward for finality signatures and the rest as a simple reward for each block, both proportionally to the validators' stakes.

    This new reward system is simpler, fairer, predictable, and transparent. It will give equal weight to all blocks (including at the end of an era), but it will not take into account every single consensus message.

    Read the Paper

    -

    Here, we describe Zug, an implementation of the ideas from our paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast. The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the echo messages are used by our Reliable Broadcast implementation, and the vote messages are used by our Weakly-terminating Binary Agreement implementation.

    +

    Here, we describe Zug, an implementation of the ideas from our paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast. The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the echo messages are used by our Reliable Broadcast implementation, and the vote messages are used by our Weakly-terminating Binary Agreement implementation.

    \ No newline at end of file diff --git a/next/concepts/dictionaries/index.html b/2.0.0/concepts/dictionaries/index.html similarity index 70% rename from next/concepts/dictionaries/index.html rename to 2.0.0/concepts/dictionaries/index.html index f7a6ffc8f..aea3259cd 100644 --- a/next/concepts/dictionaries/index.html +++ b/2.0.0/concepts/dictionaries/index.html @@ -1,27 +1,27 @@ - + -Dictionaries | Casper Docs - Redux +Dictionaries | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Understanding Dictionaries

    -

    In a Casper network, you can now store sets of data under Keys. Previously, URefs were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an addressable entity's context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated NamedKeys structures.

    + submit an issue on Github
    Version: 2.0.0

    Understanding Dictionaries

    +

    In a Casper network, you can now store sets of data under Keys. Previously, URefs were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an addressable entity's context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated NamedKeys structures.

    Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs.

    As a solution to this problem, the Casper platform provides the Dictionary feature, which allows users a more efficient and scalable means to aggregate data over time.

    Casper's Condor release shifts NamedKeys to a top-level key, removing this restriction and making them viable for data storage.

    Seed URefs

    -

    Items within a dictionary exist as individual records stored underneath their unique dictionary address in global state. In other words, items associated with a specific dictionary share the same seed URef but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key.

    +

    Items within a dictionary exist as individual records stored underneath their unique dictionary address in global state. In other words, items associated with a specific dictionary share the same seed URef but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key.

    As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef.

    Using Dictionaries

    Creating a new dictionary is fairly simple and done within the context of a transaction sent to a Casper network. The associated code is included within the casper_contract crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context.

    @@ -48,7 +48,7 @@

    dictionary_get to read an entry within the LEDGER dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a dictionary_put operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost.


    // This identifies an item within the dictionary and either creates or updates the associated value.
    match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()
    {
    None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),
    Some(current_number_of_donations) => storage::dictionary_put(
    ledger_seed_uref,
    &dictionary_item_key,
    current_number_of_donations + 1u64,
    ),
    }
    }

    Reading Items from a Dictionary using the JSON-RPC

    -

    The Casper platform provides several means of looking up a dictionary item. These means are explained within the DictionaryIdentifier JSON-RPC type. The following explains how to query the dictionary items using the Casper client.

    +

    The Casper platform provides several means of looking up a dictionary item. These means are explained within the DictionaryIdentifier JSON-RPC type. The following explains how to query the dictionary items using the Casper client.

    ContractNamedKey lookup via a Contract's named keys.

    Reading a dictionary item using the Contract's NamedKeys requires the following parameters:

      @@ -77,6 +77,6 @@


      casper-client get-dictionary-item \
      --node-address http://localhost:11101 \
      --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
      --dictionary-item-key <String> \
      --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007

    Dictionary lookup via the unique dictionary item key.

    In the event that you know the dictionary address of the dictionary item key you need to read, you can read it directly using the following Casper client command.

    -

    casper-client get-dictionary-item \
    --node-address http://localhost:11101 \
    --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
    --dictionary-address dictionary-<string>

    +

    casper-client get-dictionary-item \
    --node-address http://localhost:11101 \
    --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
    --dictionary-address dictionary-<string>

    \ No newline at end of file diff --git a/2.0.0/concepts/economics/consensus/index.html b/2.0.0/concepts/economics/consensus/index.html new file mode 100644 index 000000000..502323533 --- /dev/null +++ b/2.0.0/concepts/economics/consensus/index.html @@ -0,0 +1,79 @@ + + + + + +Consensus | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Consensus Economics

    +

    Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.

    +

    Validator Selection

    +

    After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a chainspec configuration file specifies a few key parameters:

    +
      +
    • The auction_delay specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the auction_delay is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era.
    • +
    • The validator_slots parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids.
    • +
    +

    Bids

    +

    Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the unbonding_delay chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners.

    +

    Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document.

    +

    Delegation

    +

    Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate.

    +

    Currently, there are delegation limits in the chainspec. Visit the Delegating Tokens page for more details.

    +

    Incentives

    +

    The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals.

    +

    Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future.

    +

    The network incentivizes participation by issuing rewards to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by staking with a validator. All rewards are added directly to the corresponding bids and delegations.

    +

    Validator Participation

    +

    The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load.

    +

    CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:

    +
      +
    • The growth of CSPR supply is exponential
    • +
    • Issuance takes into account slashed CSPR
    • +
    +

    With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:

    +
      +
    • i - the era's index as a positive integer [0, 1, 2, ..., n]
    • +
    • initial_supply - the number of CSPR at genesis
    • +
    • issuance_rate - the annual rate at which new CSPR tokens are minted
    • +
    • ticks_per_year - the number of milliseconds in a year equal to 31,536,000,000
    • +
    +
    supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)
    +

    We introduce the round issuance rate (corresponding to the chainspec parameter round_seigniorage_rate) with this formula:

    +
    round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1
    +

    The round issuance rate is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter minimum_round_exponent. For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds.

    +

    Finally, the base round reward is computed as:

    +
    base_round_reward(i) = round_issuance_rate * supply(i)
    +

    This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block.

    +

    Rewards Distribution

    +

    Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals.

    +

    The concept of validator weight is crucial in understanding the distribution scheme:

    +
      +
    • Weight: A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average
    • +
    • Assigned weight of a round: The total weight of validators scheduled to participate in a round
    • +
    • Participated weight of a round: The total weight of validators that participated or sent messages before the end of the round
    • +
    • Relative weight: A validator's weight relative to the total validator weight that participated in a round
    • +
    +

    The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:

    +
      +
    • For each finalized block, there is a fraction of rewards due for signature creation and collection
    • +
    • Signature rewards are split between the finder (block proposer) and the signature creators
    • +
    • The signature creators get a part of the signature reward pot due for the block: (1 - finder's fee) * relative weight
    • +
    • The finder gets a small reward as well to incentivize collecting and reporting all the signatures: finder's fee * total relative weight of signatures collected
    • +
    +

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the Rewards Design page for more details.

    +

    Validator Inactivity

    +

    Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid.

    +

    Founding Validators

    +

    When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/economics/dynamic-gas-pricing/index.html b/2.0.0/concepts/economics/dynamic-gas-pricing/index.html new file mode 100644 index 000000000..7371eacf6 --- /dev/null +++ b/2.0.0/concepts/economics/dynamic-gas-pricing/index.html @@ -0,0 +1,37 @@ + + + + + +Dynamic Gas Pricing | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Dynamic Gas Pricing on Mainnet

    +

    The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.

    +

    When dynamic gas pricing is enabled, a calculation runs at the end of each era to average block usage within that era. This calculation determines the gas price the network will use for the next era. If overall consumption rises above a threshold, the gas price increases by 1. If consumption falls below a threshold, the gas price decreases by 1. The gas price remains the same if overall consumption remains within those thresholds. The gas price will not go up or down by more than 1 in a given era and will not go above the maximum or below the minimum threshold.

    +

    The gas price is recorded in the block header and is easily discoverable for current and historical purposes. The current gas price is a multiplier that determines the actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1 but would cost 2 CSPR if the current gas price is 2. As blocks become congested, the amount of CSPR required to obtain a slot for executing transactions will increase by a multiple. The following configuration settings control this behavior:

    +
      +
    • upper_threshold - The threshold to decrease gas price
    • +
    • lower_threshold - The threshold to increase gas price
    • +
    • max_gas_price - The maximum gas price
    • +
    • min_gas_price - The minimum gas price
    • +
    +

    Mainnet Condor Configurations

    +

    These are the block vacancy (dynamic gas pricing) settings for the Condor release on Mainnet. Before Condor, the gas price was 1, meaning 1 unit of gas cost 1 mote. With Condor, the multiple is configured to adjust between 1 and 3.

    +
    [vacancy]
    # The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network.
    #
    # The network starts with a current_gas_price of min_gas_price.
    #
    # Each block has multiple limits (bytes, transactions, transfers, gas, etc.)
    # The utilization for a block is determined by the highest percentage utilization of each these limits.
    #
    # Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here)
    # 19 transactons -> 19/20 or 95%
    # 600 transfers -> 600/650 or 92.3%
    # resulting block utilization is 95
    #
    # The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is
    # adjusted with the following:
    #
    # If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price.
    # If utilization falls between the thresholds, current_gas_price is not changed.
    # If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price.
    #
    # The cost charged for the transaction is simply the gas_used * current_gas_price.
    upper_threshold = 90
    lower_threshold = 50
    max_gas_price = 3
    min_gas_price = 1
    +

    Fixed Transaction Costs vs. Dynamic Gas Prices

    +

    The current gas price and the slot’s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it’s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost here. Also, the pricing_handling = { type = 'fixed' } setting is described here.

    +

    Gas Tolerance

    +
    caution

    The cost of interacting with the blockchain increases during high network usage. Plan accordingly for any transactions and use the gas_tolerance field described below.

    +

    Transactions have a gas_tolerance field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with gas_tolerance = 2 and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/economics/fee-elimination/index.html b/2.0.0/concepts/economics/fee-elimination/index.html new file mode 100644 index 000000000..ff6a2c96a --- /dev/null +++ b/2.0.0/concepts/economics/fee-elimination/index.html @@ -0,0 +1,40 @@ + + + + + +Fee Elimination | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Fee Elimination on Mainnet

    +

    Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user's purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.

    +

    Instead of paying for gas to execute transactions, the no_fee chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: fee_handling = { type = 'no_fee'}. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable gas_hold_interval determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The query_balance_details RPC endpoint provides details on available balances and hold records.

    +
    note

    A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer.

    +

    Chainspec Configurations

    +

    The following chainspec configurations manage this feature:

    +
      +
    • fee_handling - Defines how fees are handled. To enable the "no fee" mode, set it to { type = 'no_fee'}.
    • +
    • refund_handling Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to { type = 'no_refund'}. If no fees are transferred from the paying purse, no refunds need to be paid out.
    • +
    • pricing_handling - Defines how pricing is handled. For this setting to work with the no_fee mode, set it to { type = 'fixed'}, which means that costs are fixed per the cost table, and senders do not specify how much they pay.
    • +
    • validator_credit_cap - The validator credit cannot exceed this percentage of their total stake.
    • +
    • `gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry).
    • +
    • gas_hold_interval - Defines how long gas holds last.
    • +
    +

    Mainnet Condor Configurations

    +

    These are the fee elimination settings for the Condor release on Mainnet:

    +
    # Defines how refunds of the unused portion of payment amounts are calculated and handled.
    #
    # Valid options are:
    # 'refund': a ratio of the unspent token is returned to the spender.
    # 'burn': a ratio of the unspent token is burned.
    # 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.
    # This causes excess payment amounts to be sent to either a
    # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount
    # minus the execution costs.
    refund_handling = { type = 'no_refund' }
    # Defines how fees are handled.
    #
    # Valid options are:
    # 'no_fee': fees are eliminated.
    # 'pay_to_proposer': fees are paid to the block proposer
    # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all
    # administrator accounts
    # 'burn': fees are burned
    fee_handling = { type = 'no_fee' }
    # If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.
    validator_credit_cap = [1, 5]
    # Defines how pricing is handled.
    #
    # Valid options are:
    # 'classic': senders of transaction self-specify how much they pay.
    # 'fixed': costs are fixed, per the cost table
    # 'reserved': prepaid transaction (currently not supported)
    pricing_handling = { type = 'fixed' }

    # Defines how gas holds affect available balance calculations.
    #
    # Valid options are:
    # 'accrued': sum of full value of all non-expired holds.
    # 'amortized': sum of each hold is amortized over the time remaining until expiry.
    #
    # For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,
    # with accrued, the full hold amount would be applied
    # with amortized, half the hold amount would be applied
    gas_hold_balance_handling = { type = 'accrued' }
    # Defines how long gas holds last.
    #
    # If fee_handling is set to 'no_fee', the system places a balance hold on the payer
    # equal to the value the fee would have been. Such balance holds expire after a time
    # interval has elapsed. This setting controls how long that interval is. The available
    # balance of a purse equals its total balance minus the held amount(s) of non-expired
    # holds (see gas_hold_balance_handling setting for details of how that is calculated).
    #
    # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,
    # a hold for 100 is placed on that purse and is considered when calculating total balance
    # for 24 hours starting from the block_time when the hold was placed.
    gas_hold_interval = '24 hours'
    +

    Computational and Storage Costs

    +

    Despite the introduction of fee elimination, the network continues to track computational cost based on opcodes as defined in the chainspec, thus retaining the gas pricing mechanism. Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines.

    +

    Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state.

    +

    This feature complements the dynamic gas pricing model introduced and configured to scale gas costs based on network utilization.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/economics/gas-concepts/index.html b/2.0.0/concepts/economics/gas-concepts/index.html new file mode 100644 index 000000000..bd4711266 --- /dev/null +++ b/2.0.0/concepts/economics/gas-concepts/index.html @@ -0,0 +1,40 @@ + + + + + +Gas Cost | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Gas and Resources

    +

    What is gas?

    +

    Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction.

    +

    Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures computational work as gas because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    +

    How is gas cost determined?

    +

    The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's current_gas_price multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the current_gas_price multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to dynamic pricing can be configured in a Casper network's chainspec.

    +

    Why do we need to charge a cost?

    +

    Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:

    +
      +
    • Rate-limiting is used to ensure a secure and live network: +
        +
      • It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era.
      • +
      • It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators.
      • +
      +
    • +
    • Pricing leads to more meaningful transactions: +
        +
      • Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction.
      • +
      +
    • +
    + + \ No newline at end of file diff --git a/2.0.0/concepts/economics/staking/index.html b/2.0.0/concepts/economics/staking/index.html new file mode 100644 index 000000000..0adc0a55d --- /dev/null +++ b/2.0.0/concepts/economics/staking/index.html @@ -0,0 +1,33 @@ + + + + + +Staking | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Staking

    +

    The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.

    +

    Consensus mechanism: The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called Zug. Another Casper network can choose between Zug and Highway using the network's chainspec.

    +

    Number of validators: The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot.

    +

    Permission-less bonding: For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens.

    +

    Unbonding: To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution here. The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings.

    +

    Eras and block times: An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute.

    +

    Block rewards: Validators receive rewards proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate.

    +

    Reward calculations: Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation.

    +

    Reward cycle: Rewards are calculated and distributed to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures.

    +

    Token supply and inflation: Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%.

    +

    Annual reward percentage: Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era.

    +

    Slashing: Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated.

    +

    Delegation rate: Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/global-state/index.html b/2.0.0/concepts/global-state/index.html new file mode 100644 index 000000000..5acaf2c27 --- /dev/null +++ b/2.0.0/concepts/global-state/index.html @@ -0,0 +1,42 @@ + + + + + +Global State | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Global State

    +

    Introduction

    +

    The storage layer for the Casper blockchain is called global state and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly.

    +
    note

    Refer to Keys and Permissions for further information on keys.

    +

    Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a Merkle trie.

    +

    Merkle Trie Structure

    +

    Global State

    +

    At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes.

    +

    Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value.

    +

    Formally, a trie node is one of the following:

    +
      +
    • a leaf, which includes a key and a value
    • +
    • a branch, which has up to 256 blake2b256 hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)
    • +
    • an extension node, which includes a byte array (called the affix) and a blake2b256 hash pointing to another node in the trie
    • +
    +

    The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node.

    +

    The Rust implementation of Casper's trie can be found on GitHub:

    + +
    note

    Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a TrieStore, which allows us to look up the root node for each trie.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/A/index.html b/2.0.0/concepts/glossary/A/index.html new file mode 100644 index 000000000..8c836d30e --- /dev/null +++ b/2.0.0/concepts/glossary/A/index.html @@ -0,0 +1,37 @@ + + + + + +A | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    A

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Account

    +

    An Account is a structure that represents a user on a Casper network. Information on creating an account can be found here. Casper's Condor release introduces the concept of an addressable entity, which contains an account entity type that supersedes legacy accounts.

    +

    Account Hash

    +

    The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found here.

    +

    Addressable Entity

    +

    An addressable entity is a post-2.0 type that merges the concept of an Account and a Contract, bringing in features from both. More information can be found here.

    +

    AssemblyScript

    +

    AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using asc, the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community.

    +

    Auction

    +

    The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.

    +

    Auction contract

    +

    The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction.

    +

    Auction delay

    +

    The number of full eras that pass between the booking block and the era whose validator set it defines. The auction delay is configurable and can be several eras long.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/B/index.html b/2.0.0/concepts/glossary/B/index.html new file mode 100644 index 000000000..5850c27ed --- /dev/null +++ b/2.0.0/concepts/glossary/B/index.html @@ -0,0 +1,63 @@ + + + + + +B | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    B

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Blake2b

    +

    A function used within the Casper platform to create cryptographic hashes. More information can be found here.

    +

    Block

    +

    Used in two contexts:

    +
      +
    1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain.
    2. +
    3. A message that is exchanged between nodes containing the data structure as explained in (1).
    4. +
    +

    Each block has a globally unique ID, achieved by hashing the contents of the block.

    +

    Each block points to its parent. An exception is the first block, which has no parent.

    +

    Block creation

    +

    Block creation means computing the transaction results and collecting the results into a block. We follow a process called execution after consensus.

    +

    The block proposal happens first, and the proposed proto block contains a set of transactions that have not been executed yet.

    +

    Only after consensus on a proto block has been reached, the transactions are executed. The resulting new global state root hash is put into an actual block, together with the executed transactions.

    +

    Note that only validators can create valid blocks.

    +

    Block finality

    +

    A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.

    +

    For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see eviction).

    +

    Block gossiping

    +

    Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms block gossiping and block passing are interchangeable.

    +

    Block height

    +

    Block height is an identifier for a given block based on the number of blocks completed prior to that block.

    +

    Block passing

    +

    See block gossiping.

    +

    Block processing

    +

    Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of validating blocks.

    +

    Block proposal

    +

    Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only.

    +

    Block validation

    +

    The process of determining the validity of a block obtained from another node on the network.

    +

    Blockchain

    +

    Blockchain is a P2P network where the collection of nodes (validators) concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of transactions. For performance reasons, transactions are bundled in blocks. According to a particular cooperation protocol (consensus protocol), the collection of nodes connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the global state and has a sizeable map-like collection.

    +

    Block store

    +

    The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash.

    +

    Bond

    +

    The amount of money (in crypto-currency) that is allocated by a node in order to participate in consensus (and to be a validator).

    +

    Bonding

    +

    Depositing money in the auction contract and try to become a staker. The bonding request is a transaction that transfers tokens to the auction contract. In the next booking block, a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block.

    +

    Booking block

    +

    The booking block for an era is the block that determines the era's validator set. In it, the auction contract selects the highest bidders to be the future era's validators. There is a configurable delay, the auction_delay, which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era N + auction_delay + 1 is the last block of era N.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/C/index.html b/2.0.0/concepts/glossary/C/index.html new file mode 100644 index 000000000..629e6e8e1 --- /dev/null +++ b/2.0.0/concepts/glossary/C/index.html @@ -0,0 +1,45 @@ + + + + + +C | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    C

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Cargo

    +

    Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies.

    +

    Casper network

    +

    Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found here.

    +

    CBC

    +

    Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:

    +
      +
    • All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval.
    • +
    • The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted.
    • +
    +

    Chainspec

    +

    A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. Here is an example chainspec, which will change with newer releases.

    +

    Consensus

    +

    Consensus is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as consensus. The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer.

    +

    Contract runtime

    +

    Enables developers to use a seamless workflow for authoring and testing their smart contracts. This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices.

    +

    Correct by construction

    +

    See CBC.

    +

    Crate

    +

    A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, rustc, the compiler for the Rust programming language, will produce a binary from a crate.

    +

    CSPR

    +

    CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for staking (securing the network).

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/D/index.html b/2.0.0/concepts/glossary/D/index.html new file mode 100644 index 000000000..f9ffa40e6 --- /dev/null +++ b/2.0.0/concepts/glossary/D/index.html @@ -0,0 +1,39 @@ + + + + + +D | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    D

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    dApp

    +

    A decentralized application (dApp) employs smart contracts installed on a decentralized peer-to-peer network such as a blockchain.

    +

    Delegation rate

    +

    Node operators (validators) define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services.

    +

    Delegator

    +

    Delegators are users who participate in the platform's security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    +

    Deploy

    +

    Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network.

    +

    Casper's Condor release introduces the Transaction. Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected.

    +

    All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the global state.

    +

    Review the deploy data structure and the deploy implementation for more details.

    +

    Dictionary

    +

    A Dictionary is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to NamedKeys.

    +

    More information can be found in the Reading and Writing to Dictionaries document.

    +

    Dynamic gas pricing

    +

    Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details here.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/E/index.html b/2.0.0/concepts/glossary/E/index.html new file mode 100644 index 000000000..9b572d24a --- /dev/null +++ b/2.0.0/concepts/glossary/E/index.html @@ -0,0 +1,36 @@ + + + + + +E | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    E

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Ecosystem

    +

    The ecosystem layer in Casper encompasses dApp design and operation.

    +

    Entry point

    +

    See EntryPoint and Defining the Contract Entry Points.

    +

    Equivocation

    +

    A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive.

    +

    Era

    +

    A period of time during which the validator set does not change.

    +

    In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an auction. At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see booking block).

    +

    Eviction

    +

    Validators that fail to participate in era will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the auction contract.

    +

    External client

    +

    Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/F/index.html b/2.0.0/concepts/glossary/F/index.html new file mode 100644 index 000000000..9df790bea --- /dev/null +++ b/2.0.0/concepts/glossary/F/index.html @@ -0,0 +1,27 @@ + + + + + +F | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    F

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Finality

    +

    See block finality.

    +

    Fungible

    +

    A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a non-fungible token, where each token is unique and not interchangeable.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/G/index.html b/2.0.0/concepts/glossary/G/index.html new file mode 100644 index 000000000..156af1a17 --- /dev/null +++ b/2.0.0/concepts/glossary/G/index.html @@ -0,0 +1,43 @@ + + + + + +G | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    G

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Gas

    +

    Gas is a conceptual measure of resources used when executing transactions on the blockchain.

    +

    Gas cost

    +

    Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction.

    +

    Gas price

    +

    Multiplier applied to gas cost. See dynamic gas pricing.

    +

    Genesis

    +

    The state of the virtual machine at the beginning of the blockchain.

    +

    Groups

    +

    The user groups feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:

    +
      +
    • User groups associate a set of URefs with a label.
    • +
    • The entry points on a contract can accept a list of labels
    • +
    • The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution.
    • +
    +

    Global state

    +

    When thinking of a blockchain as a decentralized computer, the global state is its memory state.

    +

    When thinking of a blockchain as a shared database, the global state is the snapshot of the database's data.

    +

    Technically, a global state is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs).

    +

    For every block B in the blockchain, one can compute the global state achieved by executing all transactions in this block and its ancestors. The root hash identifying this state is stored in every executed block.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/H/index.html b/2.0.0/concepts/glossary/H/index.html new file mode 100644 index 000000000..03b5dda41 --- /dev/null +++ b/2.0.0/concepts/glossary/H/index.html @@ -0,0 +1,27 @@ + + + + + +H | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    H

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Hash

    +

    A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the blake2b function.

    +

    Highway

    +

    A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is finalized. The full paper is found in GitHub: https://github.com/casper-network/highway.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/I/index.html b/2.0.0/concepts/glossary/I/index.html new file mode 100644 index 000000000..f4f608f22 --- /dev/null +++ b/2.0.0/concepts/glossary/I/index.html @@ -0,0 +1,23 @@ + + + + + +I | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/J/index.html b/2.0.0/concepts/glossary/J/index.html new file mode 100644 index 000000000..85eb9d609 --- /dev/null +++ b/2.0.0/concepts/glossary/J/index.html @@ -0,0 +1,25 @@ + + + + + +J | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    J

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    JSON

    +

    JSON (JavaScript Object Notation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found here.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/K/index.html b/2.0.0/concepts/glossary/K/index.html new file mode 100644 index 000000000..bb19b42eb --- /dev/null +++ b/2.0.0/concepts/glossary/K/index.html @@ -0,0 +1,25 @@ + + + + + +K | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    K

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Key

    +

    Keys are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found here.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/L/index.html b/2.0.0/concepts/glossary/L/index.html new file mode 100644 index 000000000..89a9d965b --- /dev/null +++ b/2.0.0/concepts/glossary/L/index.html @@ -0,0 +1,26 @@ + + + + + +L | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    L

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Liveness

    +

    A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions).

    +

    If the protocol is not live, the blockchain does not grow anymore, and the network stalls.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/M/index.html b/2.0.0/concepts/glossary/M/index.html new file mode 100644 index 000000000..048354f73 --- /dev/null +++ b/2.0.0/concepts/glossary/M/index.html @@ -0,0 +1,31 @@ + + + + + +M | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    M

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Mainnet

    +

    The live, decentralized, and public Casper platform, with version 1.0.

    +

    Merkle tree

    +

    A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes.

    +

    Motes

    +

    A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the CSPR token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes.

    +

    Multi-Sig

    +

    Short for Multi-Signature. Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found here.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/N/index.html b/2.0.0/concepts/glossary/N/index.html new file mode 100644 index 000000000..57db4dd76 --- /dev/null +++ b/2.0.0/concepts/glossary/N/index.html @@ -0,0 +1,41 @@ + + + + + +N | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    N

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    NamedKeys

    +

    NamedKeys +are a collection of String-Key pairs used to easily identify some data on the network.

    +
      +
    • The String is the name given to identify the data
    • +
    • The Key is the data to be referenced
    • +
    +

    Node

    +

    A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data.

    +

    You will encounter different types of nodes on the network:

    +
      +
    • Bonded node: a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era.
    • +
    • Unbonded node: a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization).
    • +
    +

    Node operator

    +

    See operator.

    +

    Non-Fungible Token (NFT)

    +

    Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/O/index.html b/2.0.0/concepts/glossary/O/index.html new file mode 100644 index 000000000..c6cf7017b --- /dev/null +++ b/2.0.0/concepts/glossary/O/index.html @@ -0,0 +1,28 @@ + + + + + +O | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    O

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Operator

    +

    Anyone running a node is an operator.

    +

    An operator that has staked a bid but does not currently have a validator slot is a *staked operator*.

    +

    An operator whose bid has won a validator slot in the auction for a specific era is a validator in that era.

    +

    It is common for a staked operator to win an auction slot for many eras in a row and thus be a validator for a range of eras.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/P/index.html b/2.0.0/concepts/glossary/P/index.html new file mode 100644 index 000000000..9e8bc4f2d --- /dev/null +++ b/2.0.0/concepts/glossary/P/index.html @@ -0,0 +1,48 @@ + + + + + +P | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    P

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Partial synchrony

    +

    Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see CBC.

    +

    Participate in consensus

    +

    The process of following the consensus algorithm. The primary participants are validators, bonded with their stake and part of the validator set for that particular era. Delegators participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network.

    +

    Payment code

    +

    The payment code is the Wasm program that pays the transaction execution fee.

    +

    Peer node

    +

    A node on a peer-to-peer (P2P) network.

    +

    Permissionless

    +

    A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants.

    +

    Primary token

    +

    See CSPR.

    +

    Private key

    +

    See secret key.

    +

    Proof-of-Stake

    +

    Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain.

    +

    Proof-of-Work

    +

    A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed.

    +

    Proposer

    +

    The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain.

    +

    Proto block

    +

    The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated.

    +

    A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era.

    +

    Purse

    +

    A purse is a unique type of URef representing a token balance. An entity's main purse represents the balance of CSPR tokens (in motes) the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found here.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/Q/index.html b/2.0.0/concepts/glossary/Q/index.html new file mode 100644 index 000000000..e5d933cba --- /dev/null +++ b/2.0.0/concepts/glossary/Q/index.html @@ -0,0 +1,23 @@ + + + + + +Q | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/R/index.html b/2.0.0/concepts/glossary/R/index.html new file mode 100644 index 000000000..262023f32 --- /dev/null +++ b/2.0.0/concepts/glossary/R/index.html @@ -0,0 +1,31 @@ + + + + + +R | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    R

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Reward

    +

    Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's delegation rate. Rewards are distributed at the end of each era.

    +

    Root hash

    +

    The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to Merkle tree if you wish to learn more.

    +

    Rust

    +

    A programming language similar to C++, designed for performance and safety, especially safe concurrency.

    +

    Rustdocs

    +

    As part of the Rust development environment, the Rustdocs describe the Casper contracts library, the Casper types library, and the Casper test support library.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/S/index.html b/2.0.0/concepts/glossary/S/index.html new file mode 100644 index 000000000..2f4113b7c --- /dev/null +++ b/2.0.0/concepts/glossary/S/index.html @@ -0,0 +1,51 @@ + + + + + +S | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    S

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Safe

    +

    When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see CBC.

    +

    Secret key

    +

    A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations).

    +

    Seigniorage

    +

    The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators.

    +

    Session code

    +

    Session code is Wasm executed in the context of an account entity through sending a transaction. The session code contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state.

    +

    Slashing

    +

    In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets slashed, i.e., a part of it is removed.

    +

    Smart contract

    +

    Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party.

    +

    On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the global state. The execution of a smart contract causes changes to the global state.

    +

    A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values.

    +

    Smart-contract platform

    +

    A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts.

    +

    Staker

    +

    A staker is either a validator or a delegator. Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their tokens by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is slashed, the staker will lose their tokens.

    +

    Staking

    +

    A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The Staking Guide highlights the steps required to stake CSPR tokens on the Casper Mainnet.

    +

    State root hash

    +

    The state root hash is an identifier of the network's global state at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras.

    +

    Stateful

    +

    Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions.

    +

    Stateless

    +

    Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time.

    +

    Switch Block

    +

    A Switch Block is the final block in an era, which contains the era_summary. See also booking block.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/T/index.html b/2.0.0/concepts/glossary/T/index.html new file mode 100644 index 000000000..a86a64d5e --- /dev/null +++ b/2.0.0/concepts/glossary/T/index.html @@ -0,0 +1,30 @@ + + + + + +T | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    T

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Token

    +

    A type of cryptocurrency that represents an asset. See CSPR.

    +

    Transaction

    +

    Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a Deploy. Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found here.

    +

    Turing-complete blockchain

    +

    Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets.

    +

    For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/U/index.html b/2.0.0/concepts/glossary/U/index.html new file mode 100644 index 000000000..f904bb72c --- /dev/null +++ b/2.0.0/concepts/glossary/U/index.html @@ -0,0 +1,29 @@ + + + + + +U | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    U

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Unbonding

    +

    Withdrawing money from the auction contract with withdraw bid and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed.

    +

    URef

    +

    An Unforgeable Reference, used by a Casper network to store any value other than Account. More information can be found here.

    +

    Users

    +

    Users execute session and contract code using the platform's computational resources.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/V/index.html b/2.0.0/concepts/glossary/V/index.html new file mode 100644 index 000000000..59f5f8fce --- /dev/null +++ b/2.0.0/concepts/glossary/V/index.html @@ -0,0 +1,32 @@ + + + + + +V | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    V

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Validator

    +

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain's security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.

    +

    The responsibilities of a validator include:

    + +

    Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and stakers can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/W/index.html b/2.0.0/concepts/glossary/W/index.html new file mode 100644 index 000000000..cba84c38c --- /dev/null +++ b/2.0.0/concepts/glossary/W/index.html @@ -0,0 +1,27 @@ + + + + + +W | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    W

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    +

    Web3

    +

    An advanced version of the internet based on decentralization and trustless interactions.

    +

    WebAssembly

    +

    WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/X/index.html b/2.0.0/concepts/glossary/X/index.html new file mode 100644 index 000000000..78068630d --- /dev/null +++ b/2.0.0/concepts/glossary/X/index.html @@ -0,0 +1,23 @@ + + + + + +X | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/Y/index.html b/2.0.0/concepts/glossary/Y/index.html new file mode 100644 index 000000000..b55072980 --- /dev/null +++ b/2.0.0/concepts/glossary/Y/index.html @@ -0,0 +1,23 @@ + + + + + +Y | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/2.0.0/concepts/glossary/Z/index.html b/2.0.0/concepts/glossary/Z/index.html new file mode 100644 index 000000000..5bda74819 --- /dev/null +++ b/2.0.0/concepts/glossary/Z/index.html @@ -0,0 +1,25 @@ + + + + + +Z | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    + + \ No newline at end of file diff --git a/2.0.0/concepts/index.html b/2.0.0/concepts/index.html new file mode 100644 index 000000000..f1f8009eb --- /dev/null +++ b/2.0.0/concepts/index.html @@ -0,0 +1,99 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Concepts Overview

    +

    The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.

    +

    Concepts

    +

    This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Introduction to the Casper BlockchainHigh-level details about the Casper blockchain
    Introduction to dAppsDeveloping distributed applications on the Casper blockchain
    Addressable EntitiesLearn about addressable entities and how they relate to accounts and smart contracts.
    Accounts and Cryptographic KeysThe Casper programming model is account-based. Learn how Casper accounts work and how they are secured
    Key TypesHashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more
    Global StateLearn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state
    Call StacksLearn how Casper manages the calling of a contract
    Transactions and the Transaction LifecycleTransactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them
    Smart ContractsLearn how to develop smart contracts on Casper
    DictionariesLearn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform
    SerializationLearn about serializing data types and the Casper Serialization Standard
    DesignThe high-level design of a Casper network
    EconomicsLearn about the Casper on-chain economics
    GlossaryA compendium of all the terms used in Casper, in alphabetical order
    +

    Next Steps

    +

    After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories.

    +

    Developers

    +

    The Developers area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs.

    +

    Operators

    +

    The Operators section caters to those who want to run and administrate a Casper node or network.

    +

    Users

    +

    The Users section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device.

    +

    Resources

    +

    Navigate to Resources to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the beginner tutorials. Afterward, continue with more advanced tutorials to explore the multi-signature feature, runtime return values, and other essential features.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/intro-to-dapps/index.html b/2.0.0/concepts/intro-to-dapps/index.html new file mode 100644 index 000000000..21aa2597b --- /dev/null +++ b/2.0.0/concepts/intro-to-dapps/index.html @@ -0,0 +1,42 @@ + + + + + +dApps | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Introduction to dApps

    +

    What is a dApp?

    +

    DApp stands for Decentralized Application. Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface.

    +

    A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    +

    A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of nodes does the processing of smart contracts instead of a single central server.

    +

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    +

    Interacting with a Casper Decentralized Network

    +

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    +

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. +A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    +

    Updating data in a Casper dApp

    +

    Sending a transaction is the only means by which a dApp can change global state. All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    +

    Post-Consensus Execution in a Casper network

    +

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means that observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    +

    Transaction lifecycle

    +

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    + +
    + + \ No newline at end of file diff --git a/2.0.0/concepts/key-types/index.html b/2.0.0/concepts/key-types/index.html new file mode 100644 index 000000000..a38d568db --- /dev/null +++ b/2.0.0/concepts/key-types/index.html @@ -0,0 +1,485 @@ + + + + + +Key Types | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Understanding Key Types

    +

    For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.

    +

    Key Explanations

    +

    Key is a wrapper type that may contain one of several possible sets of data.

    +

    Account

    +

    Key::Account contains an AccountHash.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Accountaccount-hash-account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    +

    Hash

    +

    Key::Hash contains a byte array with a length of 32, which can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for the implementation of any checks necessary on the receiving side.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Hashhash-hash-0101010101010101010101010101010101010101010101010101010101010101
    +

    URef

    +

    Key::URef contains an URef suffixed by access rights.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::URefuref-uref-0101010101010101010101010101010101010101010101010101010101010101-001
    +

    Transfer

    +

    Key::Transfer should contain the address hash for a transfer.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Transfertransfer-transfer-0101010101010101010101010101010101010101010101010101010101010101
    +

    DeployInfo

    +

    Key::DeployInfo retains the address hash of deploy information.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::DeployInfodeploy-deploy-0101010101010101010101010101010101010101010101010101010101010101
    +

    EraInfo

    +

    Key::EraInfo is the integer number of the associated era.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::EraInfoera-era-1
    +

    Balance

    +

    Key::Balance is the balance of a purse.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Balancebalance-balance-0101010101010101010101010101010101010101010101010101010101010101
    +

    BalanceHold

    +

    Key::BalanceHold is a Key under which a hold on a purse balance is stored.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::BalanceHoldbalance-hold-balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a6400000000000000
    +

    Bid

    +

    Key::Bid is used to keep track of bids for the auction contract. It is not generally used by users.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Bidbid-bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    +

    Withdraw

    +

    Key::Withdraw is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Withdrawwithdraw-withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    +

    Dictionary

    +

    Key::Dictionary is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Dictionarydictionary-dictionary-0101010101010101010101010101010101010101010101010101010101010101
    +

    SystemContractRegistry

    +

    Key::SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts, including Mint, Auction, HandlePayment and StandardPayment, is stored.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::SystemContractRegistrysystem-entity-registry-system-entity-registry-0000000000000000000000000000000000000000000000000000000000000000
    +

    EraSummary

    +

    Key::EraSummary is a Key under which we store current era info.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::EraSummaryera-summary-era-summary-00000000000000000000000000000000
    +

    Unbond

    +

    Key::Unbond is a variant of the key type that tracks unbonding purses.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Unbondunbond-unbond-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    +

    ChainspecRegistry

    +

    Key::ChainspecRegistry is a unique Key which contains a mapping of file names to the hash of the file itself. These files include Chainspec.toml and may also include Accounts.toml and GlobalState.toml.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::ChainspecRegistrychainspec-registry-chainspec-registry-11111111111111111111111111111111
    +

    ChecksumRegistry

    +

    Key::ChecksumRegistry is a unique key variant under which we write a registry of checksums for a given block. There are two checksums in the registry, one for the execution results and the other for the approvals of all transactions in the block.

    +

    |Key::ChecksumRegistry | checksum-registry- | checksum-registry-00000000000000000000000000000000 |

    +

    BidAddr

    +

    Key::BidAddr manages data associated with bids for the Auction contract. It may be any one of three variants: unified, validator, or delegator.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    Unifiedbid-addr-00bid-addr-00ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    Validatorbid-addr-01bid-addr-01ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    Delegatorbid-addr-02bid-addr-02ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    +

    Package

    +

    Key::Package is a Key under which package information is stored.

    + + + + + + + + + + + + + + + +
    TypePrefixExample
    Key::Packagepackage-package-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    +

    AddressableEntity

    +

    Key::AddressableEntity is a Key under which an AddressableEntity is stored. It may be one of three variants: Account, System or SmartContract.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    Accountaddressable-entity-account-addressable-entity-account-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    Systemaddressable-entity-system-addressable-entity-system-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    SmartContractaddressable-entity-contract-addressable-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    +

    ByteCode

    +

    Key::ByteCode is a Key under which a byte code record is stored. It may be one of two variants: v1-wasm or empty.

    + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    v1-wasmbyte-code-v1-wasm-byte-code-v1-wasm-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    emptybyte-code-empty-byte-code-empty-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    +

    Message

    +

    Key::Message is a Key under which a message is stored.

    + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    Message Topicmessage-topic-entity-contract-message-topic-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a
    Messagemessage-entity-contract-message-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-0202020202020202020202020202020202020202020202020202020202020202-f
    +

    NamedKey

    +

    Key::NamedKey is a Key under which a single named key entry is stored.

    + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    Account Named Keynamed-key-entity-account-named-key-entity-account-928d914bdcad3ca269e750f63ed3615c5d3f615cf97dba87006fd9f979dacb3c-dde6f264c89fe385a5b07c26d77284d6fddabe79653c5ca25cec39a6363e6ec7
    Contract Named Keynamed-key-entity-contract-named-key-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b
    +

    BlockGlobal

    +

    Key::BlockGlobal is a Key under which per-block details are stored to global state.

    + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    Block Timeblock-time-block-time-00000000000000000000000000000000000000000000000000000000000000
    Block Message Countblock-message-count-block-message-count-00000000000000000000000000000000000000000000000000000000000000
    +

    EntryPoint

    +

    Key::EntryPoint is a Key under which an entrypoint record is written.

    + + + + + + + + + + + + + + + + + + + + +
    TypePrefixExample
    V1 Entry Pointentry-point-v1-entity-contract-entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481
    V2 Entry Pointentry-point-v2-entity-contract-entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1
    + + \ No newline at end of file diff --git a/2.0.0/concepts/list-auth-keys/index.html b/2.0.0/concepts/list-auth-keys/index.html new file mode 100644 index 000000000..b986a132d --- /dev/null +++ b/2.0.0/concepts/list-auth-keys/index.html @@ -0,0 +1,39 @@ + + + + + +Authorization Keys | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Authorization Keys

    +

    This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.

    +

    Associated Keys vs. Authorization Keys

    +

    Let's review the difference between associated keys to an Account and authorization keys for a transaction.

    +
      +
    • Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about associated keys and weights and try the Two-Party Multi-Signature tutorial.
    • +
    • Authorization keys are public keys used to sign a transaction and are listed in the transaction's approvals. Authorization keys are a subset of the associated keys of the account under which the transaction is executed.
    • +
    • When a node receives a transaction, it checks that the transaction has the required authorization keys under approvals before including it in a block.
    • +
    • Different transactions executing the same smart contract can have different authorization keys.
    • +
    +

    Auth Keys

    +

    Here is a sample JSON representation of an Account's associated keys:

    +
    "associated_keys": [
    {
    "account_hash": "account-hash-1ab…11",
    "weight": 1
    },
    {
    "account_hash": "account-hash-2cd…22",
    "weight": 1
    },
    {
    "account_hash": "account-hash-3de…33",
    "weight": 1
    },
    {
    "account_hash": "account-hash-4fg…44",
    "weight": 1
    }
    ], ...
    +

    Here is a sample JSON representation of a transaction's authorization keys:

    +
    "approvals": [
    {
    "signer": " 2cd...22",
    "signature": "02df8c...f481"
    },
    {
    "signer": "4fg...44",
    "signature": "02ef21...756a"
    }
    ]
    +

    Accessing Authorization Keys from a Smart Contract

    +

    Contract code can retrieve the set of authorization keys for a given transaction by calling the contract_api::runtime::list_authorization_keys function, which returns the set of account hashes representing the keys used to sign the transaction.

    +

    When to Use Authorization Keys

    +

    Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations.

    +

    Try the Working with Authorization Keys tutorial to view an example workflow.

    + + \ No newline at end of file diff --git a/2.0.0/concepts/serialization/index.html b/2.0.0/concepts/serialization/index.html new file mode 100644 index 000000000..5c09c612e --- /dev/null +++ b/2.0.0/concepts/serialization/index.html @@ -0,0 +1,44 @@ + + + + + +Binary Serialization Standard | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Binary Serialization Standard

    +

    We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization.

    +

    The Casper Binary Serialization Standard uses a default u8 byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories.

    + + + + + + + + + + + + + + + + + + + + + +
    PageDescription
    PrimitivesBase-level types used to create more complex structures.
    StructuresMajor structures used through Casper systems, as well as their included sub-types.
    TypesMinor types not covered Primitives or Structures.
    + + \ No newline at end of file diff --git a/2.0.0/concepts/serialization/primitives/index.html b/2.0.0/concepts/serialization/primitives/index.html new file mode 100644 index 000000000..b2ebfca9d --- /dev/null +++ b/2.0.0/concepts/serialization/primitives/index.html @@ -0,0 +1,256 @@ + + + + + +Primitives and Basic Serialization Rules | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Primitives and Basic Serialization Rules

    +

    CLValue

    +

    CLValue describes data that is used by smart contracts. This could be a local state variable, input argument, or return value. A CLValue consists of two parts: a CLType describing the type of the value and an array of bytes representing the data in our serialization format.

    +

    CLType is described by the following recursive data type:

    +
    enum CLType {
    Bool, // boolean primitive
    I32, // signed 32-bit integer primitive
    I64, // signed 64-bit integer primitive
    U8, // unsigned 8-bit integer primitive
    U32, // unsigned 32-bit integer primitive
    U64, // unsigned 64-bit integer primitive
    U128, // unsigned 128-bit integer primitive
    U256, // unsigned 256-bit integer primitive
    U512, // unsigned 512-bit integer primitive
    Unit, // singleton value without additional semantics
    String, // e.g. "Hello, World!"
    URef, // unforgeable reference (see above)
    Key, // global state key (see above)
    PublicKey // A Casper system PublicKey type
    Option(CLType), // optional value of the given type
    List(CLType), // list of values of the given type (e.g. Vec in rust)
    ByteArray(CLType, u32), // same as `List` above, but number of elements
    // is statically known (e.g. arrays in rust)
    Result(CLType, CLType), // co-product of the given types;
    // one variant meaning success, the other failure
    Map(CLType, CLType), // key-value association where keys and values have the given types
    Tuple1(CLType), // single value of the given type
    Tuple2(CLType, CLType), // pair consisting of elements of the given types
    Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types
    Any // Indicates the type is not known
    }
    +

    All data that can be assigned a (non-Any) CLType can be serialized according to the following rules, which define the Casper serialization format:

    +

    Boolean

    +

    Boolean values serialize as a single byte; true maps to 1, while false maps to 0.

    +

    Numeric

    +

    Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width.

    +
      +
    • +

      E.g. 7u8 serializes as 0x07

      +
    • +
    • +

      E.g. 7u32 serializes as 0x07000000

      +
    • +
    • +

      E.g. 1024u32 serializes as 0x00040000

      +
    • +
    • +

      Wider numeric values (i.e. U128, U256, U512) serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This reduces the serialization size when small numbers are represented within a wide data type.

      +
    • +
    • +

      E.g. U512::from(7) serializes as 0x0107

      +
    • +
    • +

      E.g. U512::from(1024) serializes as 0x020004

      +
    • +
    • +

      E.g. U512::from("123456789101112131415") serializes as 0x0957ff1ada959f4eb106

      +
    • +
    +

    Unit

    +

    Unit serializes to an empty byte array.

    +

    String

    +

    Strings serialize as a 32-bit integer representing the length in bytes (that might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string.

    +
      +
    • E.g. "Hello, World!" serializes as 0x0d00000048656c6c6f2c20576f726c6421
    • +
    +

    Option

    +

    Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to 0 if the value is missing, and 1 if it is present.

    +
      +
    • E.g. None serializes as 0x00
    • +
    • E.g. Some(10u32) serializes as 0x010a000000
    • +
    +

    List

    +

    A list of values serializes as a 32-bit integer representing the number of elements in the list (differing from strings where it gives the number of bytes), followed by the concatenation of each serialized element.

    +
      +
    • E.g. List() serializes as 0x00000000
    • +
    • E.g. List(1u32, 2u32, 3u32) serializes as 0x03000000010000000200000003000000
    • +
    +

    ByteArray

    +

    A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value.

    +
      +
    • E.g. [1u32, 2u32, 3u32] serializes as 0x010000000200000003000000
    • +
    +

    Result

    +

    A Result serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to 1 for the success variant and 0 for the error variant.

    +
    -   E.g. `Ok(314u64)` serializes as `0x013a01000000000000`
    - E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`
    +

    Tuple

    +

    Tuples serialize as the concatenation of their serialized elements. Similar to ByteArray the number of elements is not included in the serialization because it is statically known in the type.

    +
    -   E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`
    +

    Map

    +

    A Map serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as Map data structures can be unordered.

    +

    URef

    +

    URef values serialize as the concatenation of their address (a fixed-length list of u8) and a single byte tag representing access rights, which are converted as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Access RightsSerialization
    NONE0
    READ1
    WRITE2
    READ_WRITE3
    ADD4
    READ_ADD5
    ADD_WRITE6
    READ_ADD_WRITE7
    +
    warning

    When passing a URef to another entity on chain, you must ensure that the AccessRights are set correctly. If the URef represents a purse, AccessRights impact who can deposit and withdraw CSPR.

    +

    If a passed URef contains ADD permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. WRITE permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove WRITE permissions. In this event, READ and ADD permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with WRITE permissions unintentionally.

    +

    PublicKey

    +

    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.
    • +
    +

    Key

    +

    Key values serialize as a single byte tag representing the variant, followed by the serialization of the data that the variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is Key::URef, which contains a URef; so its data serializes per the description above. The tags are as follows: Key::Account serializes as 0, Key::Hash as 1, Key::URef as 2.

    +

    CLType

    +

    CLType itself also has rules for serialization. A CLType serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ByteArray is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CLTypeSerialization Tag
    Bool0
    I321
    I642
    U83
    U324
    U645
    U1286
    U2567
    U5128
    Unit9
    String10
    Key11
    URef12
    Option13
    List14
    ByteArray15
    Result16
    Map17
    Tuple118
    Tuple219
    Tuple320
    Any21
    PublicKey22
    +

    CLValue

    +

    A complete CLValue, including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type.

    +

    Contracts

    +

    Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A contract contains the following data:

    +
      +
    • a wasm module
    • +
    • a collection of named keys
    • +
    • a protocol version
    • +
    +

    The wasm module must contain a function named call, which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the Casper runtime.

    +

    Note: though the call function signature has no arguments and no return value, within the call function body, the get_named_arg runtime function can be used to accept arguments (by ordinal), and the ret runtime function can be used to return a single CLValue to the caller.

    +

    The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the URefs, which are known to the contract (see the section on Permissions for details).

    +

    Each contract specifies the Casper protocol version that was active when the contract was written to the global state.

    + + \ No newline at end of file diff --git a/next/concepts/serialization/structures/index.html b/2.0.0/concepts/serialization/structures/index.html similarity index 57% rename from next/concepts/serialization/structures/index.html rename to 2.0.0/concepts/serialization/structures/index.html index dd874dbfe..3b4bd8e75 100644 --- a/next/concepts/serialization/structures/index.html +++ b/2.0.0/concepts/serialization/structures/index.html @@ -1,69 +1,69 @@ - + -Major Structures | Casper Docs - Redux +Major Structures | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Major Structures

    Account

    An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, Accounts were replaced with AddressableEntities of the type Account. The account structure consists of the following fields:

    AddressableEntity

    An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields:

    Block

    @@ -155,7 +155,7 @@

    Bloc

    transactions: Is a BTreeMap of transaction hashes and their given categories. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of values held within. The remainder consists of a repeating pattern of transaction categories as a u8 value and then the associated TransactionHash the category tag describes.

  • -

    rewarded_signatures: A list of identifiers for finality signatures for a particular past block. It serializes as a vector of SingleBlockRewardedSignatures which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

    +

    rewarded_signatures: A list of identifiers for finality signatures for a particular past block. It serializes as a vector of SingleBlockRewardedSignatures which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

  • Contract

    @@ -168,13 +168,13 @@

    Contractcontract_wasm_hash

  • -

    named_keys

    +

    named_keys

  • -

    entry_points

    +

    entry_points

  • -

    protocol_version

    +

    protocol_version

  • ContractPackageHash

    @@ -184,7 +184,7 @@

    ContractWas

    ContractHash

    A blake2b hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash.

    ContractPackageStatus

    -

    The lock status of the contract package, serialized as a boolean where true indicates a locked contract and false indicates an unlocked contract package.

    +

    The lock status of the contract package, serialized as a boolean where true indicates a locked contract and false indicates an unlocked contract package.

    ContractVersion

    The version of the contract.

      @@ -192,55 +192,55 @@

      ContractVers

      contract_hash: The contract hash of the contract.

    • -

      contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

      +

      contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

    • -

      protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

      +

      protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

    ContractVersionKey

    -

    The major element of ProtocolVersion combined with Contract Version serialized as two u32 values.

    +

    The major element of ProtocolVersion combined with Contract Version serialized as two u32 values.

    ContractWasm

    A container for a contract's Wasm bytes, serialized as the byte representation of itself.

    Message

    A message emitted by an addressable entity during execution. The message struct contains the following fields:

    • -

      entity_hash: The identity of the entity that produced the message, serialized as an EntityAddr.

      +

      entity_hash: The identity of the entity that produced the message, serialized as an EntityAddr.

    • message: The payload of the message, serialized as a MessagePayload.

    • -

      topic_name: The name of the topic on which the message was emitted, serialized as a String.

      +

      topic_name: The name of the topic on which the message was emitted, serialized as a String.

    • topic_name_hash: The hash of the topic name, serialized as a TopicNameHash.

    • -

      topic_index: The message index in the topic, serialized as a u32 value.

      +

      topic_index: The message index in the topic, serialized as a u32 value.

    • -

      block_index: The message index in the block, serialized as a u64 value.

      +

      block_index: The message index in the block, serialized as a u64 value.

    MessageAddr

    A message topic address, a structure which consists of the following fields:

    • -

      entity_addr: The entity address, serialized as an EntityAddr.

      +

      entity_addr: The entity address, serialized as an EntityAddr.

    • topic_name_hash: The hash of the topic name, serialized as a TopicNameHash.

    • -

      message_index: The message index, serialized as an Option of u32.

      +

      message_index: The message index, serialized as an Option of u32.

    MessageChecksum

    -

    A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a CLType u8 tag followed by a ByteArray.

    +

    A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a CLType u8 tag followed by a ByteArray.

    MessageLimits

    -

    Configuration for message lists, serialized as three u32 values:

    +

    Configuration for message lists, serialized as three u32 values:

    • max_topic_name_size: Maximum size in bytes of a topic name string.

      @@ -253,11 +253,11 @@

      MessageLimits

    MessagePayload

    -

    The payload of a message emitted by an addressable entity during execution. It serializes as either a u8 tag of 0 followed by a a serialized version of a human-readable String, or as a u8 tag of 1 followed by serialized raw Bytes.

    +

    The payload of a message emitted by an addressable entity during execution. It serializes as either a u8 tag of 0 followed by a a serialized version of a human-readable String, or as a u8 tag of 1 followed by serialized raw Bytes.

    MessageTopicOperation

    -

    Operations that can be performed on message topics. Currently, serializes as a u8 of 0 representing the Add function.

    +

    Operations that can be performed on message topics. Currently, serializes as a u8 of 0 representing the Add function.

    TopicNameHash

    -

    The hash of the name of a message topic, serialized as a u8 describing the length of the string and the 32-byte serialized representation of the string itself.

    +

    The hash of the name of a message topic, serialized as a u8 describing the length of the string and the 32-byte serialized representation of the string itself.

    Transaction

    A versioned wrapper for a transaction or deploy. It serializes as a u8 tag of 0 followed by a Deploy or a u8 tag of 1 followed by a TransactionV1.

    Deploy

    @@ -288,7 +288,7 @@

    ApprovalApprovalsHash

    -

    The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a digest.

    +

    The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a digest.

    DeployInfo

    Information relating to a given deploy. The structure consists of the following fields:

    DeployConfig

    A struct containing configuration values associated with deploys. The structure contains the following fields:

    • -

      max_payment_cost: The maximum amount any deploy can pay, serialized in Motes.

      +

      max_payment_cost: The maximum amount any deploy can pay, serialized in Motes.

    • -

      max_dependencies: The maximum time to live any deploy can specify, serialized as a u8.

      +

      max_dependencies: The maximum time to live any deploy can specify, serialized as a u8.

    • -

      payment_args_max_length: The maximum length in bytes of payment args per deploy, serialized as a u32

      +

      payment_args_max_length: The maximum length in bytes of payment args per deploy, serialized as a u32

    • -

      session_args_max_length: The maximum length in bytes of session args per deploy, serialized as a u32

      +

      session_args_max_length: The maximum length in bytes of session args per deploy, serialized as a u32

    TransactionV1

    @@ -345,25 +345,25 @@

    Transactio

    TransactionV1Header

    The header portion of a transaction, structurally, is defined as follows:

      -
    • chain_name: Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String.
    • +
    • chain_name: Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String.
    • timestamp: A timestamp is a struct that is a unary tuple containing a u64 value. This value is a count of the milliseconds since the UNIX epoch. Thus the value 1603994401469 serializes as 0xbd3a847575010000.
    • ttl: The Time to live is defined as the amount of time for which the transaction is considered valid. The ttl serializes in the same manner as the timestamp.
    • body_hash: Body hash is a hash over the contents of the transaction body. It serializes as the byte representation of the hash itself.
    • -
    • pricing_mode
    • -
    • initator_addr
    • +
    • pricing_mode
    • +
    • initator_addr

    TransactionV1Body

    The body of a TransactionV1, consisting of the following:

    TransactionRuntime

    -

    The runtime used to execute a transaction, serialized as a u8. Currently, only the VmCasperV1 is available, which serializes as a 0.

    +

    The runtime used to execute a transaction, serialized as a u8. Currently, only the VmCasperV1 is available, which serializes as a 0.

    TransactionEntryPoint

    -

    An entry point of a transaction, serialized as a u8 value based on the type of entry point. The following table outlines the available types:

    +

    An entry point of a transaction, serialized as a u8 value based on the type of entry point. The following table outlines the available types:

    @@ -418,19 +418,19 @@

    Transactio

    A struct containing configuration values associated with Transactions. The structure contains the following fields:

    • -

      max_ttl: The maximum time to live any transaction can specify, serialized as a TimeDiff.

      +

      max_ttl: The maximum time to live any transaction can specify, serialized as a TimeDiff.

    • -

      block_max_approval_count: The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a u32.

      +

      block_max_approval_count: The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a u32.

    • -

      max_block_size: The maximum possible size in bytes of a block, serialized as a u32.

      +

      max_block_size: The maximum possible size in bytes of a block, serialized as a u32.

    • -

      block_gas_limit: The maximum sum of payment across al transactions included in a block, serialized as a u64.

      +

      block_gas_limit: The maximum sum of payment across al transactions included in a block, serialized as a u64.

    • -

      native_transfer_minimum_motes: The minimum token amount for a native transfer deploy or transaction, serialized as a u64.

      +

      native_transfer_minimum_motes: The minimum token amount for a native transfer deploy or transaction, serialized as a u64.

    • max_timestamp_leeway: The maximum value to which a transaction_acceptor.timestamp_leeway can be set in the config.toml file.

      @@ -446,13 +446,13 @@

      Transact

      A struct containing configuration values associated with TransactionV1s. The structure contains the following fields:

      • -

        native_mint_lane: The lane configuration for the native mint interaction, serializing as a vector of u64 values.

        +

        native_mint_lane: The lane configuration for the native mint interaction, serializing as a vector of u64 values.

      • -

        native_auction_lane: The lane configuration for the native auction interaction, serializing as a vector of u64 values.

        +

        native_auction_lane: The lane configuration for the native auction interaction, serializing as a vector of u64 values.

      • -

        wasm_lanes: The lane configuration for the Wasm-based lanes, serializing as a nested vector of u64 values.

        +

        wasm_lanes: The lane configuration for the Wasm-based lanes, serializing as a nested vector of u64 values.

      TransactionHash

      @@ -462,16 +462,16 @@

      Transactio

      TransactionId

      The unique identifier of a Transaction, serialized as its TransactionHash and ApprovalsHash.

      TransactionScheduling

      -

      The scheduling mode of a transaction, serialized as a u8 tag identifying the type:

      +

      The scheduling mode of a transaction, serialized as a u8 tag identifying the type:

      • Standard serializes as a 0.

      • -

        FutureEra serializes as a 1 followed by a future era_id.

        +

        FutureEra serializes as a 1 followed by a future era_id.

      • -

        FutureTimestamp serializes as a 2 followed by a future timestamp.

        +

        FutureTimestamp serializes as a 2 followed by a future timestamp.

      TransactionInvocationTarget

      @@ -481,17 +481,17 @@

      InvocableEntity serializes as a u8 tag of 0 followed by the hex-encoded entity address serialized as the byte representation of itself.

    • -

      InvocableEntityAlias serializes as a u8 tag of 1 followed by the alias serialized as a string.

      +

      InvocableEntityAlias serializes as a u8 tag of 1 followed by the alias serialized as a string.

    • -

      Package serializes as a u8 tag of 2 followed by the package hash and optionally the entity_version.

      +

      Package serializes as a u8 tag of 2 followed by the package hash and optionally the entity_version.

    • -

      PackageAlias serializes as a u8 tag of 3 followed by the alias serialized as a string and optionally the entity_version.

      +

      PackageAlias serializes as a u8 tag of 3 followed by the alias serialized as a string and optionally the entity_version.

    TransactionTarget

    -

    The execution target of a transaction, serializing as a u8 that identifies the type, followed by any additional data.

    +

    The execution target of a transaction, serializing as a u8 that identifies the type, followed by any additional data.

    • native serializes as a 0.

      @@ -504,6 +504,6 @@

      Transactio

    TransactionWithExecutionInfo

    -

    A struct containing aTransaction with execution info. It serializes as a Transaction followed by an Option of ExecutionInfo.

    +

    A struct containing aTransaction with execution info. It serializes as a Transaction followed by an Option of ExecutionInfo.

    \ No newline at end of file diff --git a/2.0.0/concepts/serialization/types/index.html b/2.0.0/concepts/serialization/types/index.html new file mode 100644 index 000000000..fcaf5f0e3 --- /dev/null +++ b/2.0.0/concepts/serialization/types/index.html @@ -0,0 +1,1251 @@ + + + + + +Type Serialization | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Type Serialization

    +

    Account Action Thresholds

    +

    The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

    +
      +
    • +

      deployment: The minimum weight threshold required to perform deployment actions as a u8 value.

      +
    • +
    • +

      key_management: The minimum weight threshold required to perform key management actions as a u8 value.

      +
    • +
    +

    Account Config

    +

    Configuration of an individual account in accounts.toml, containing the account's public key, main purse balance and validator config.

    +
      +
    • +

      public_key The public key of the account, serialized as the byte representation of itself.

      +
    • +
    • +

      balance The balance of the account's main purse, serialized as a U512 value.

      +
    • +
    • +

      validator The validator configuration for the account, serialized as an Option.

      +
    • +
    +

    Account Hash

    +

    A blake2b hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash.

    +

    Account Identifier

    +

    Identifier for possible ways to retrieve an Account. It can consist of any of the following in most situations:

    +
      +
    • +

      PublicKey: The account's public key.

      +
    • +
    • +

      AccountHash: The blake2b hash of the account's public key.

      +
    • +
    +

    Activation Point

    +

    The first era to which the associated protocol version applies. It serializes as a single u8 tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a timestamp. If not, the bytes represent an era_id.

    +
      +
    • +

      era_id: An Era ID newtype identifying the era when the protocol version will activate.

      +
    • +
    • +

      timestamp: A timestamp if the activation point is of the Genesis variant.

      +
    • +
    +

    AddressableEntityHash

    +

    The hex-encoded address of an addressable entity, which serializes as the byte representation of itself.

    +

    Approval

    +

    A struct containing a signature and the public key of the signer.

    +
      +
    • +

      signature: The approval signature, which serializes as the byte representation of the Signature. The first byte within the signature is 1 in the case of an Ed25519 signature or 2 in the case of Secp256k1.

      +
    • +
    • +

      signer: The public key of the approvals signer. It serializes to the byte representation of the PublicKey. If the PublicKey is an Ed25519 key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of Secp256k1, the first byte is 2.

      +
    • +
    +

    ApprovalsHash

    +

    The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a digest.

    +

    AssociatedKey

    +

    A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes.

    +
      +
    • +

      account_hash: The account hash of the associated key.

      +
    • +
    • +

      weight: The weight of an associated key. The weight serializes as a u8 value.

      +
    • +
    +

    AvailableBlockRange

    +

    An unbroken, inclusive range of blocks. It serializes as two consecutive u64 values containing the following two fields:

    +
      +
    • +

      low: The inclusive lower bound of the range.

      +
    • +
    • +

      high: - The inclusive upper bound of the range.

      +
    • +
    +

    BalanceHoldAddr

    +

    A balance hold address. It serializes as a BalanceHoldAddrTag describing the type of balance hold address as follows:

    +
      +
    • +

      Gas serializes as a BalanceHoldAddrTag of 0 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

      +
    • +
    • +

      Processing serializes as a BalanceHoldAddrTag of 1 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

      +
    • +
    +

    BalanceHoldAddrTag

    +

    A tag describing the type of BalanceHoldAddr, serializing as a single u8 value.

    +

    BalanceResponse

    +

    BalanceResponse is a struct that provides the response to a balance query. It consists of the following fields:

    +
      +
    • +

      total_balance: The purse's total balance, not considering holds. It serializes as a U512 value.

      +
    • +
    • +

      available_balance: The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a U512 value.

      +
    • +
    • +

      total_balance_proof: A proof that the given value is present in the Merkle trie. It serializes as a TrieMerkleProof, consisting of a key, a value and a proof_step.

      +
    • +
    • +

      balance_holds: Any time-relevant active holds on the balance. It serializes as a BTreeMap where the first 4 bytes represent a u32 value describing the number of BlockTime and BalanceHoldsWithProof held within. The remainder consists of a repeating pattern of serialized BlockTimes and BalanceHoldsWithProofs of the length dictated by the first four bytes.

      +
    • +
    +

    Bid

    +

    An entry in the validator map. The structure consists of the following fields:

    +
      +
    • +

      validator_public_key: The validator's public key. It serializes as a PublicKey.

      +
    • +
    • +

      bonding_purse: The purse used for bonding. It serializes as a Uref.

      +
    • +
    • +

      staked_amount: The amount of tokens staked by a validator (not including delegators). It serializes as a U512 value.

      +
    • +
    • +

      delegation_rate: The delegation rate of the bid. It serializes as an i32 signed 32-bit integer primitive.

      +
    • +
    • +

      vesting_schedule: The vesting schedule for a genesis validator. None if it is a non-genesis validator. It serializes as an Option.

      +
    • +
    • +

      delegators: The validator's delegators, indexed by their public keys. They are serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of PublicKeys and delegators held within. The remainder consists of a repeating pattern of serialized PublicKeys and then delegators of the length dictated by the first four bytes.

      +
    • +
    • +

      inactive: If the validator has been evicted. A boolean value that serializes as a single byte; true maps to 1, while false maps to 0.

      +
    • +
    +

    BidAddr

    +

    BidAddr manages data associated with bids for the Auction system contract. It serializes as a single u8 tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:

    +
      +
    • +

      Unified A BidAddr for legacy unified bids. It serializes as a u8 of 0 followed by the account_hash identifying the legacy bid.

      +
    • +
    • +

      Validator A validator bid. It serializes as a u8 of 1 followed by the account_hash of the validator.

      +
    • +
    • +

      Delegator A delegator bid. It serializes as a u8 of 2 followed by the account_hash of the associated validator and then the account_hash of the delegator.

      +
    • +
    • +

      Credit A BidAddr representing an auction credit. It serializes as a u8 of 4 followed by the account_hash of the validator and the EraId for the applicable credit.

      +
    • +
    +

    BidKind

    +

    Auction bid variants. It serializes as a single u8 value indicating the type of bid kind as per the following table:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    BidKindu8Description
    Unified0Legacy data that contains all delegators for a given validator.
    Validator1A bid record containing only validator data.
    Delegator2A bid record containing only delegator data.
    +

    BlockGlobalAddr

    +

    An address for singleton values associated to a specific block. These are values which are calculated or set during the execution of a block such as the block timestamp, or the total count of messages emitted during the execution of the block.

    +

    It serializes as two u8 values, the first of which describes the category, followed by the underlying value as follows:

    +
      +
    • +

      BlockTime begins with a u8 of 0, followed by the u8 of the block time.

      +
    • +
    • +

      MessageCount begins with a u8 of 1, followed by message count as a u8.

      +
    • +
    +

    BlockIdentifier

    +

    Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:

    +
      +
    • +

      hash: Identify and retrieve a Block with its hash. The BlockHash serializes as the byte representation of the hash itself.

      +
    • +
    • +

      height: Identify and retrieve the Block with its height. Height serializes as a single u64 value.

      +
    • +
    • +

      state_root_hash: Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the state root hash. The serialized buffer of the state_root_hash is 32 bytes long.

      +
    • +
    +

    BlockSignatures

    +

    A collection of signatures for a single block, along with the associated block's hash and era ID.

    +

    There are two possible versions for BlockSignatures, with a prefixed u8 tag describing which version it is.

    + +

    BlockSignaturesV1

    +

    BlockSignaturesV1 is a legacy version of BlockSignatures that applies to blocks created before the Condor release. The structure is as follows:

    +
      +
    • +

      block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

      +
    • +
    • +

      era_id: The era ID in which this block was created. It serializes as a single u64 value.

      +
    • +
    • +

      proofs: The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a BTreeMap where the first 4 bytes represent a u32 value describing the number of PublicKeys and signatures held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes.

      +
    • +
    +

    BlockSignaturesV2

    +

    BlockSignaturesV2 is the current version of BlockSignatures that applies to blocks created after the Condor release. The structure is as follows:

    +
      +
    • +

      block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

      +
    • +
    • +

      block_height: The block height. It serializes as a single u64 value.

      +
    • +
    • +

      era_id: The era ID in which this block was created. It serializes as a single u64 value.

      +
    • +
    • +

      chain_name_hash: The hash of the chain name of the associated block. It serializes as the byte representation of the hash itself.

      +
    • +
    • +

      proofs: The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a BTreeMap where the first 4 bytes represent a u32 value describing the number of PublicKeys and signatures held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes.

      +
    • +
    +

    BlockSyncStatus

    +

    The status of syncing an individual block. It serializes as the byte representation of the block hash of the block in question, followed by an option representing a u64 of the block height and the remainder is the byte representation of the acquisition_state as a string.

    +

    BlockTime

    +

    The block time serialized as a single u64 value.

    +

    BTreeMap

    +

    A BTreeMap is a method of mapping keys to values within a Casper network. They serialize with the first 4 bytes representing a u32 value describing the number of keys and values held within. The remainder consists of a repeating pattern of serialized keys and then values of the length dictated by the first four bytes.

    +

    BTreeSet

    +

    A BTreeSet is a method of storing a set of values within a Casper network. They serialize with the first 4 bytes representing a u32 value describing the number of values held within. The remainder consists of a repeating series of values of the length dictated by the first four bytes.

    +

    ByteCode

    +

    A container for a contract's Wasm bytes. It serializes as the single u8 BidKind, followed by a u32 value describing the size of the remaining Bytes and then the bytes as described.

    +

    Bytes

    +

    Hex-encoded bytes serialized as a u32 value describing the length of the bytes, followed by the bytes themselves.

    +

    ByteCodeKind

    +

    The type of byte code, serialized as a single u8 value. A 0 indicates empty byte code, while a 1 indicates a V1CasperWasm to be executed with the first version of the Casper execution engine.

    +

    Caller

    +

    Caller is the identity of a calling entity. It serializes as one of two variants, described below:

    +
      +
    • +

      Initiator is the overall calling account and serializes as a u8 tag of 0 followed by the account_hash of the calling account.

      +
    • +
    • +

      Entity is a calling entity, such as a smart contract or a system contract. It serializes as a u8 tag of 1 followed by the package_hash and entity_hash.

      +
    • +
    +

    CallStackElement

    +

    CallStackElement is a legacy enum created pre-Condor release that represents the origin of a sub-call in a call stack. It begins with a u8 tag that describes the type of caller as follows:

    + +

    ChainNameDigest

    +

    The cryptographic hash of a chain name, serialized as the byte representation of the hash itself.

    +

    ChainspecRegistry

    +

    ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes Chainspec.toml and may include Accounts.toml and GlobalState.toml. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names as strings and digests held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:

    +
      +
    • +

      chainspec_raw_hash will always be included.

      +
    • +
    • +

      genesis_accounts_raw_hash may be included in specific circumstances.

      +
    • +
    • +

      global_state_raw_hash may be included in specific circumstances.

      +
    • +
    +

    ChecksumRegistry

    +

    The checksum registry. It serializes as a BTreeMap where the first 4 bytes represent a u32 value describing the number of checksum names as strings and digests held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes.

    +

    Delegator

    +

    Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:

    +
      +
    • +

      delegator_public_key: The public key of the delegator, serialized as a PublicKey.

      +
    • +
    • +

      staked_amount: The amount staked by the delegator, serialized as a U512 value.

      +
    • +
    • +

      bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

      +
    • +
    • +

      validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

      +
    • +
    • +

      vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

      +
    • +
    +

    Digest

    +

    A blake2b hash digest. The digest serializes as a byte representation of the hash itself.

    +

    DisabledVersions

    +

    Disabled contract versions, containing the following:

    +
      +
    • +

      contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

      +
    • +
    • +

      protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

      +
    • +
    +

    Effects

    +

    A log of all transforms produced during execution, serialized as a vector of transforms.

    +

    Entity Action Thresholds

    +

    The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

    +
      +
    • +

      deployment: The minimum weight threshold required to perform deployment actions as a u8 value.

      +
    • +
    • +

      upgrade_management: The minimum weight threshold required to perform upgrade management actions as a u8 value.

      +
    • +
    • +

      key_management: The minimum weight threshold required to perform key management actions as a u8 value.

      +
    • +
    +

    EntityAddr

    +

    The address for an AddressableEntity. It serializes as a u8 EntityKindTag followed by the 32-byte buffer containing the bytes of the hash_addr as follows:

    +
      +
    • +

      System: A package associated with a native contract implementation, serialized as a u8 of 0, followed by the hash_addr.

      +
    • +
    • +

      Account: A package associated with an Account hash, serialized as u8 of 1 followed by the hash_addr.

      +
    • +
    • +

      SmartContract: A package associated with Wasm stored on chain, serialized as a u8 of 2 followed by the hash_addr

      +
    • +
    +

    EntityKind

    +

    The type of Package, serialized as a u8 EntityKindTag describing the type followed by further data as follows:

    +
      +
    • +

      System: A package associated with a native contract implementation. It serializes as a u8 of 0 followed by a SystemEntityType.

      +
    • +
    • +

      Account: A package associated with an Account hash, serialized as a u8 of 1 followed by an account_hash.

      +
    • +
    • +

      SmartContract: A package associated with Wasm stored on chain, serialized as a u8 of 2 followed by a transaction_runtime.

      +
    • +
    +

    EntityKindTag

    +

    A tag for the variants of EntityKind, serialized as a single u8 tag of 0 for System, 1 for Account and 2 for SmartContract.

    +

    EntityVersionKey

    +

    The major element of ProtocolVersion combined with EntityVersion serialized as two u32 values.

    +

    EntityVersions

    +

    A collection of entity versions, serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of EntityVersionKeys mapped to AddressableEntityHashes within. The remainder consists of a repeating pattern of serialized EntityVersionKeys and AddressableEntityHashes of the length dictated by the first four bytes.

    +

    EntryPoint (Contract)

    +

    A type of signature method. Order of arguments matters, since this can be referenced by index as well as name.

    +
      +
    • +

      name: The name of the entry point, serialized as a String.

      +
    • +
    • +

      args: Arguments for this method. They serialize as a list of the Parameters, where each parameter represents an argument passed to the entrypoint.

      +
    • +
    • +

      ret: The return type of the method, serialized as a Unit.

      +
    • +
    • +

      access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

      +
    • +
    • +

      entry_point_type: Identifies the type of entry point. It serializes as a 0 for Session and a 1 for Contract.

      +
    • +
    +

    EntryPoint (Entity)

    +

    The type signature of a method. This structure consists of the following fields:

    +
      +
    • +

      name: The name of the entry point, serialized as a String.

      +
    • +
    • +

      args: Arguments for this method. They serialize as a list of the Parameters, where each parameter represents an argument passed to the entrypoint.

      +
    • +
    • +

      ret: The return type of the method, serialized as a Unit.

      +
    • +
    • +

      access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

      +
    • +
    • +

      entry_point_type

      +
    • +
    • +

      entry_point_payment

      +
    • +
    +

    EntryPointAddr

    +

    An entry point's address. It serializes as one of the two following variants:

    +
      +
    • +

      VmCasperV1: A V1 entry point. It serializes as a u8 of 0 followed by an EntityAddr and name_bytes, which is the 32-byte hash of the name of the entry point.

      +
    • +
    • +

      VmCasperV2: A V2 entry point. It serializes as a u8 of 1 followed by an EntityAddr followed by a u32 Selector.

      +
    • +
    +

    EntrypointPayment

    +

    An enum specifying who pays for the invocation and execution of an entry point. It serializes as a single u8 byte tag as follows:

    +
      +
    • +

      Caller: Serializes as a 0 and indicates that the caller must cover the cost.

      +
    • +
    • +

      SelfOnly: Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts.

      +
    • +
    • +

      SelfOnward: Serializes as a 2 and indicates that the contract will pay for executing itself and any subsequent invocations.

      +
    • +
    +

    EntrypointType

    +

    The context of method execution. It serializes as one of the following:

    +
      +
    • +

      Caller: Serializes as a single u8, 0b00000000

      +
    • +
    • +

      Called: Serializes as a single u8, 0b00000001

      +
    • +
    • +

      Factory: Serializes as a single u8, 0b10000000

      +
    • +
    +

    EntrypointV2

    +

    The entry point for the V2 Casper VM. It serializes as a u32 representing the Selector followed by a u32 representing the Flags.

    +

    EntryPoints

    +

    Entry points for a given entity, serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of String to EntryPoints held within. The remainder consists of a repeating pattern of serialized Strings and then EntryPoints of the length dictated by the first four bytes.

    +

    EraID

    +

    An Era ID newtype. It serializes as a single u64 value.

    +

    EraInfo

    +

    Auction metadata, intended to be recorded each era. It serializes as a List of seigniorage allocations.

    +

    ExecutableDeployItem

    +

    The executable component of a Deploy, serialized as a u8 identifying tag followed by additional bytes as follows:

    +
      +
    • +

      ModuleBytes: Serializes as a u8 tag of 0 followed by bytes and runtimeargs.

      +
    • +
    • +

      StoredContractByHash: Serializes as a u8 tag of 1 followed by the contract hash as an AddressableEntityHash, the name of an entry point as a String and runtimeargs.

      +
    • +
    • +

      StoredContractByName: Serializes as a u8 tag of 2 followed by the named key as a String, the name of an entry point as a String and runtimeargs.

      +
    • +
    • +

      StoredVersionedContractByHash: Serializes as a u8 tag of 3 followed by the PackageHash, the version as an Option, an entry point as a String and runtimeargs.

      +
    • +
    • +

      StoredVersionedContractByName: Serializes as a u8 tag of 4 followed by the named key as a String, the version as an Option, the name of an entry point as a String and runtimeargs.

      +
    • +
    • +

      Transfer: Serializes as a u8 tag of 5 followed by runtimeargs.

      +
    • +
    +

    ExecutionEffect

    +

    The journal of execution transforms from a single deploy.

    +
      +
    • +

      operations: The resulting operations, serialized as a List of operations.

      +
    • +
    • +

      transforms: The actual transformation performed while executing a deploy.

      +
    • +
    +

    ExecutionResultV1

    +

    The result of a single deploy. It serializes as a u8 tag indicating either Failure as a 0 or Success as a 1. This is followed by the appropriate structure below:

    +

    Failure

    +

    The result of a failed execution.

    +
      +
    • +

      effect: The effect of executing the deploy.

      +
    • +
    • +

      transfers: A record of transfers performed while executing the deploy, serialized as a List.

      +
    • +
    • +

      cost: The cost of executing the deploy, serializes as a U512 value.

      +
    • +
    • +

      error_message: The error message associated with executing the deploy, serialized as a String.

      +
    • +
    +

    Success

    +

    The result of a successful execution.

    +
      +
    • +

      effect: The effect of executing the deploy.

      +
    • +
    • +

      transfers: A record of transfers performed while executing the deploy, serialized as a List.

      +
    • +
    • +

      cost: The cost of executing the deploy, serializes as a U512 value.

      +
    • +
    +

    ExecutionResultV2

    +

    The result of a single transaction. It serializes as a u8 tag indicating either Failure as a 0 or Success as a 1. This is followed by the appropriate structure below:

    +

    Failure

    +

    The result of a failed execution.

    +
      +
    • +

      effects: The effect of executing the transaction.

      +
    • +
    • +

      transfers: A record of transfers performed while executing the transaction, serialized as a List.

      +
    • +
    • +

      cost: The cost of executing the transaction, serializes as a U512 value.

      +
    • +
    • +

      error_message: The error message associated with executing the transaction, serialized as a String.

      +
    • +
    +

    Success

    +

    The result of a successful execution.

    +
      +
    • +

      effects: The effects of executing the transaction.

      +
    • +
    • +

      transfers: A record of transfers performed while executing the transaction, serialized as a List.

      +
    • +
    • +

      cost: The cost of executing the transaction, serializes as a U512 value.

      +
    • +
    +

    Gas

    +

    The Gas structure serializes as a U512 amount of gas.

    +

    Group

    +

    A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a String.

    +

    Groups

    +

    They are serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of user groups and BTreeSets of URefs held within. The remainder consists of a repeating pattern of serialized user groups and BTreeSets of the length dictated by the first four bytes.

    +

    InitiatorAddr

    +

    The address of the initiator of a TransactionV1, which serializes as a u8 of 0 followed by a PublicKey or a 1 followed by an AccountHash.

    +

    Keys

    +

    A key in Global State is one of the following data types:

    +
      +
    • 32-byte account identifier (called an "account identity key")
    • +
    • 32-byte immutable contract identifier (called a "hash key")
    • +
    • 32-byte reference identifier (called an "unforgeable reference")
    • +
    • 32-byte transfer identifier
    • +
    • 32-byte deploy information identifier
    • +
    • 32-byte purse balance identifier
    • +
    • 32-byte Auction bid identifier
    • +
    • 32-byte Auction withdrawal identifier
    • +
    • 32-byte Dictionary identifier
    • +
    • 32-byte System Contract Registry
    • +
    • 32-byte Auction unbond identifier
    • +
    • 32-byte Chainspec Registry
    • +
    +

    The one exception to note here is the identifier for EraInfo, which actually serializes as a u64 value with an additional byte for the tag.

    +

    Account Identity Key

    +

    This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

    +

    Hash Key

    +

    This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the blake2b256 hash of the deploy hash (see block-structure-head for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key.

    +

    Unforgeable Reference (URef)

    +

    URef broadly speaking can be used to store values and manage permissions to interact with the value stored under the URef. URef is a tuple which contains the address under which the values are stored and the Access rights to the URef. Refer to the Unforgeable Reference section for details on how URefs are managed.

    +

    Transfer Key

    +

    This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier representing this key is derived from the blake2b256 hash of the transfer address associated with the given transfer.

    +

    DeployInfo Key

    +

    This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the deploy itself.

    +

    EraInfo Key

    +

    This key type is used specifically for storing information related to the Auction metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive u64 data type and co-relates to the era number when the auction information was stored.

    +

    This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

    +

    This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

    +

    Serialization for Key

    +

    Given the different variants for the over-arching Key data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    KeySerialization Tag
    Account0
    Hash1
    URef2
    Transfer3
    DeployInfo4
    EraInfo5
    Balance6
    Bid7
    Withdraw8
    Dictionary9
    SystemContractRegistry10
    EraSummary11
    Unbond12
    ChainspecRegistry13
    ChecksumRegistry14
    BidAddr15
    +

    | Package | 16 | +| AddressableEntity | 17 | +| ByteCode | 18 | +| Message | 19 |

    +
      +
    • Account serializes as a 32 byte long buffer containing the byte representation of the underlying AccountHash.
    • +
    • Hash serializes as a 32 byte long buffer containing the byte representation of the underlying Hash itself.
    • +
    • URef is a tuple that contains the address of the URef and the access rights to that URef. The serialized representation of the URef is 33 bytes long. The first 32 bytes are the byte representation of the URef address, and the last byte contains the bits corresponding to the access rights of the URef. Refer to the CLValue section of this chapter for details on how AccessRights are serialized.
    • +
    • Transfer serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer.
    • +
    • DeployInfo serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized.
    • +
    • EraInfo serializes a u64 primitive type containing the little-endian byte representation of u64.
    • +
    • Balance serializes as 32 byte long buffer containing the byte representation of the URef address.
    • +
    • Bid and Withdraw both contain the AccountHash as their identifier; therefore, they serialize in the same manner as the Account variant.
    • +
    • Dictionary serializes as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item.
    • +
    • SystemContractRegistry serializes as a 32 byte long buffer of zeros.
    • +
    • EraSummary serializes as a 32 byte long buffer of zeros.
    • +
    • Unbond contains the AccountHash as its identifier; therefore, it serialize in the same manner as the Account variant.
    • +
    • ChainspecRegistry serializes as a 32 byte long buffer of ones.
    • +
    • ChecksumRegistry serializes as a 32 byte long buffer of zeros.
    • +
    • BidAddr may be one of three types: +
        +
      • Unified serializes as the tag 0 followed by a 32 byte long buffer containing the byte representation of a legacy bid.
      • +
      • Validator serializes as the tag 1 followed by a 32 byte long buffer containing the byte representation of a validator's hash.
      • +
      • Delegator serializes as the tag 2 followed by a 32 byte long buffer containing the byte representation of the associated validator's hash, appended with a 32 byte long buffer containing the byte representation of the given delegator's hash.
      • +
      +
    • +
    +

    Permissions

    +

    There are three types of actions that can be done on a value: read, write, add. The reason for add to be called out separately from write is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    KeyType Available Actions
    AccountRead + Add (via API)
    HashRead
    URefRead + Write and/or Add
    TransferSystem
    DeploySystem
    EraInfoSystem
    BalanceRead (via API)
    BidSystem
    WithdrawSystem
    DictionaryRead (via API)
    SystemContractRegistryRead (via API)
    UnbondSystem
    ChainspecRegistryRead (via API)
    +
    +

    Refer to URef permissions on how permissions are handled in the case of URefs.

    +

    MessageTopics

    +

    A topic for contract-level messages. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of topic_name strings and topic_name_hash held within. The remainder consists of a repeating pattern of serialized topic_name and topic_name_hash of the length dictated by the first four bytes.

    +

    MessageTopicSummary

    +

    A summary of a message topic that will be stored in global state. It serializes as a u32 value for the message_count followed by the BlockTime

    +

    Motes

    +

    A struct representing a number of Motes serialized as a U512 value.

    +

    NamedArg

    +

    Named arguments to a contract. It is serialized by the combination of a String followed by the associated CLValue.

    +

    NamedKey

    +

    A mapping of string identifiers to a Casper Key type. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes.

    +
      +
    • +

      name: The name of the entry. It serializes as a string.

      +
    • +
    • +

      key: The value of the entry, which is a Casper Key type.

      +
    • +
    +

    The named keys portion of the account structure serializes as a mapping of a string to Casper Key values as described here.

    +

    NamedKeyAddr

    +

    A NamedKey address, serialized as an EntityAddr followed by a u8 describing the length of a string and the 32-byte representation of the string itself.

    +

    NamedKeyValue

    +

    A NamedKey value, serialized as the named_key serialized as a CLValue followed by the name of the key also serialized as a CLValue.

    +

    NamedKeys

    +

    A collection of named keys. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names and keys held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes.

    +

    Operation

    +

    An operation performed while executing a deploy. It contains:

    +
      +
    • +

      key: The formatted string of the key, serialized as a String.

      +
    • +
    • +

      kind: OpKind, The type of operation performed. It serializes as a single byte based on the following table:

      +
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    OpKindSerialization
    Read0
    Write1
    Add2
    NoOp3
    +

    Package

    +

    A structure defining an entity, metadata and security container. The structure consists of the following fields:

    + +

    PackageHash

    +

    The hex-encoded address of a package associated with an AddressableEntity, serialized as the byte representation of itself.

    +

    PackageStatus

    +

    The lock status of the package, serialized as a boolean where true indicates a locked package and false indicates an unlocked package.

    +

    Parameter

    +

    Parameter to a method, structured as a name followed by a CLType. It is serialized as a String followed by a CLType.

    +

    PricingMode

    +

    The pricing mode of a transaction, with two possible variants. It serializes as a u8 tag followed by additional data based on the following table:

    + + + + + + + + + + + + + + + + + + + + +
    TagPricingModeDescription
    0ClassicThe original payment model, in which the creator of a transaction specifies how much they will pay and at which gas price.
    1FixedThe cost of the transaction is determined by the cost table, per the transaction kind.
    +

    Classic

    +

    After the 0 tag, a Classic PricingMode serializes as the u64 payment_amount followed by the u64 value of the gas_price.

    +

    Fixed

    +

    After the 1 tag, a Fixed PricingMode serializes as the u64 gas_price_tolerance.

    +

    ProtocolVersion

    +

    A newtype indicating the Casper Platform protocol version. It is serialized as three u32 values indicating major, minor and patch versions in that order.

    +

    PublicKey

    +

    Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under PublicKey.

    +

    RewardedSignatures

    +

    A list of identifiers for finality signatures for a particular past block. It serializes as a vector of SingleBlockRewardedSignatures which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

    +

    RuntimeArgs

    +

    Represents a collection of arguments passed to a smart contract. They serialize as a List comprised of Tuples.

    +

    SeigniorageAllocation

    +

    Information about seigniorage allocation.

    +

    If the seigniorage allocation in question is for a validator, it serializes as the validator's PublicKey followed by the U512 amount.

    +

    If it is a delegator, it serializes as the delegator's PublicKey, followed by the validator's PublicKey and finally the U512 amount.

    +

    SemVer

    +

    A struct for semantic versioning, it serializes as three u32 that describe the major version, minor version and patch version.

    +

    Signature

    +

    The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an Ed25519 signature or 2 in the case of Secp256k1.

    +

    Stored Values

    +

    A value stored in the global state is a StoredValue. A StoredValue is one of three possible variants:

    +
      +
    • A CLValue
    • +
    • A contract
    • +
    • An account
    • +
    +

    We discuss CLValue and contract in more detail below. Details about accounts can be found in accounts-head.

    +

    Each StoredValue is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of StoredValue it is, followed by the serialization of that variant. The tag for each variant is as follows:

    +
      +
    • CLValue is 0
    • +
    • Account is 1
    • +
    • Contract is 2
    • +
    +

    The details of CLType serialization are in the following section. Using the serialization format for CLValue as a basis, we can succinctly write the serialization rules for contracts and accounts:

    +
      +
    • contracts serialize in the same way as data with CLType equal to Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32));
    • +
    • accounts serialize in the same way as data with CLType equal to Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8)).
    • +
    +

    Note: Tuple5 is not a presently supported CLType. However, it is clear how to generalize the rules for Tuple1, Tuple2, Tuple3 to any size tuple.

    +

    SystemContractRegistry

    +

    SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts. This includes Mint, Auction, HandlePayment and StandardPayment. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names as strings and ContractHashes held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes.

    +

    SystemEntityType

    +

    Entity types for system contracts, serialized as a single u8 tag identifying the contract as per the following table:

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TagSystem Contract
    0Mint
    1Auction
    2StandardPayment
    3HandlePayment
    +

    TimeDiff

    +

    A human-readable duration between two timestamps. It serializes as a single u64 value.

    +

    Timestamp

    +

    A timestamp formatted as per RFC 3339 and serialized as a single u64 value.

    +

    TopicNameHash

    +

    A blake2b hash of a topic name. The topic name hash serializes as a 32-byte buffer containing the bytes of the topic name hash.

    +

    TransferAddr

    +

    Hex-encoded transfer address, which serializes as a byte representation of itself.

    +

    TransformKindV1

    +

    The actual transformation performed while executing a deploy. It serializes as a single u8 value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Transform TypeSerializationDescription
    Identity0A transform having no effect.
    Write_CLValue1Writes the given CLValue to global state.
    Write_Account2Writes the given Account to global state.
    Write_Contract_WASM3Writes a smart contract as Wasm to global state.
    Write_Contract4Writes a smart contract to global state.
    Write_Contract_Package5Writes a smart contract package to global state.
    Write_Deploy_Info6Writes the given DeployInfo to global state.
    Write_Transfer7Writes the given Transfer to global state.
    Write_Era_Info8Writes the given EraInfo to global state.
    Write_Bid9Writes the given Bid to global state.
    Write_Withdraw10Writes the given Withdraw to global state.
    Add_INT3211Adds the given i32.
    Add_UINT6412Adds the given u64.
    Add_UINT12813Adds the given U128.
    Add_UINT25614Adds the given U256.
    Add_UINT51215Adds the given U512.
    Add_Keys16Adds the given collection of named keys.
    Failure17A failed transformation, containing an error message.
    +

    TransformKindV2

    +

    The actual transformation performed while executing a deploy. It serializes as a single u8 value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Transform TypeSerializationDescription
    Identity0A transform having no effect, created as a result of reading from the global state.
    Write1Writes a new value in the global state.
    AddInt322Adds the given i32.
    AddUInt643Adds the given u64.
    AddUInt1284Adds the given U128.
    AddUInt2565Adds the given U256.
    AddUInt5126Adds the given U512.
    AddKeys7Adds the given collection of named keys.
    Failure8A failed transformation, containing an error message.
    Prune9Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states.
    +

    TransformEntry

    +

    A transformation performed while executing a deploy.

    +

    TransformV1

    +

    A legacy transform struct serialized as a String of the key followed by the transformkindv1.

    +

    Transformv2

    +

    A struct representing an executed transformation serialized as a String of the key followed by the transformkindv2.

    +

    UnbondingPurse

    +

    A purse used for unbonding. The structure consists of the following:

    +
      +
    • +

      bonding_purse: The bonding purse, serialized as a URef.

      +
    • +
    • +

      validator_public_key: The public key of the validator, serialized as a PublicKey.

      +
    • +
    • +

      unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

      +
    • +
    • +

      era_of_creation: Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

      +
    • +
    • +

      amount: The unbonding amount, serialized as a U512 value.

      +
    • +
    • +

      new_validator: The validator public key to redelegate to, serialized as an Option containing the public key.

      +
    • +
    +

    ValidatorBid

    +

    An entry in the validator map. The structure consists of the following fields:

    +
      +
    • +

      validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

      +
    • +
    • +

      bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

      +
    • +
    • +

      staked_amount: The amount staked by the delegator, serialized as a U512 value.

      +
    • +
    • +

      delegation_rate: The delegation rate serialized as a u8 value.

      +
    • +
    • +

      vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

      +
    • +
    • +

      inactive: The validator's inactivity status, serialized as a boolean.

      +
    • +
    +

    ValidatorChange

    +

    A change to a validator's status between two eras, serialized as a u8 tag as follows:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TagChange
    0Added
    1Removed
    2Banned
    3Cannot Propose
    4Seen as Faulty
    +

    ValidatorConfig

    +

    A validator account configuration, serialized as a bonded_amount followed by the delegation_rate as a u8.

    +

    ValidatorCredit

    +

    A struct representing the record of a validator credit, with fields as follows:

    + +

    WithdrawPurse

    +

    A purse used for unbonding, replaced in 1.5 by UnbondingPurse. WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data.

    +
      +
    • +

      bonding_purse: The bonding purse, serialized as a URef.

      +
    • +
    • +

      validator_public_key: The public key of the validator, serialized as a PublicKey.

      +
    • +
    • +

      unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

      +
    • +
    • +

      era_of_creation Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

      +
    • +
    • +

      amount The unbonding amount, serialized as a U512 value.

      +
    • +
    + + \ No newline at end of file diff --git a/2.0.0/concepts/smart-contracts/index.html b/2.0.0/concepts/smart-contracts/index.html new file mode 100644 index 000000000..78dd816cf --- /dev/null +++ b/2.0.0/concepts/smart-contracts/index.html @@ -0,0 +1,38 @@ + + + + + +Smart Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Smart Contracts

    +

    Smart Contracts in General

    +

    A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism.

    +

    Casper Smart Contracts

    +

    Casper smart contracts can be implemented in any programming language that compiles to Wasm, which can be installed and executed on-chain using transactions. Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust here.

    +

    Session Code

    +

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either session code or another smart contract may call these entry points. Understand when you would use session code over contract code here.

    +

    Factory Pattern

    +

    From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding Casper Enhancement Proposal provides additional details. Also, you can learn to write a simple contract with factory entry points by following the The Factory Pattern developer guide.

    +

    Further Reading

    +
    + + \ No newline at end of file diff --git a/2.0.0/counter-testnet/index.html b/2.0.0/counter-testnet/index.html new file mode 100644 index 000000000..91fff581c --- /dev/null +++ b/2.0.0/counter-testnet/index.html @@ -0,0 +1,42 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    A Counter on the Testnet

    +

    This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    +

    Here is how the tutorial is structured:

    + +

    Prerequisites

    +
      +
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. +
    3. You have installed the Casper client to send transactions to the chain.
    4. +
    5. You were able to set up and fund an account on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial: +
        +
      • The location of your account’s secret_key.pem file
      • +
      • Your account hash identifier
      • +
      +
    6. +
    7. You selected a node whose RPC port will be receiving the transactions coming from your account.
    8. +
    +

    Video Tutorial

    +

    If you prefer a video walkthrough of this guide, you can check out this video.

    +
    + + \ No newline at end of file diff --git a/2.0.0/counter/index.html b/2.0.0/counter/index.html new file mode 100644 index 000000000..07d332d9b --- /dev/null +++ b/2.0.0/counter/index.html @@ -0,0 +1,33 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    A Counter on an NCTL Network

    +

    This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    +

    Here is how the tutorial is structured:

    + +

    Prerequisites

    +
      +
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. +
    3. You have completed the NCTL tutorial, which introduces you to the CLI tool to set up and control local Casper networks for development.
    4. +
    5. You have installed the Casper client to send transactions to the chain.
    6. +
    + + \ No newline at end of file diff --git a/2.0.0/design/index.html b/2.0.0/design/index.html new file mode 100644 index 000000000..3eb8569a1 --- /dev/null +++ b/2.0.0/design/index.html @@ -0,0 +1,20 @@ + + + + + +Design Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Design Overview

    TopicDescription
    Network DesignOverview of execution semantics, account permissions, URefs, block structure, tokens, and more
    Network CommunicationPeer-to-peer communication for Casper nodes
    Consensus in CasperIntroduction to Consensus in a Casper network
    Zug ConsensusAn overview of the Zug consensus used in Mainnet and Testnet
    Highway ConsensusBrief overview of the Highway consensus available as an alternative to Zug
    Validator RewardsOverview of how rewards are calculated and distributed
    Reading and Writing Data to Global StateStoring and reading data from the blockchain
    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/calling-contracts/index.html b/2.0.0/developers/cli/calling-contracts/index.html new file mode 100644 index 000000000..73927131a --- /dev/null +++ b/2.0.0/developers/cli/calling-contracts/index.html @@ -0,0 +1,176 @@ + + + + + +Calling Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Calling Smart Contracts with the Rust Client

    +

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.

    +

    The following examples use two contracts on Testnet:

    + +

    Prerequisites

    + +

    Calling Contracts by Contract Hash

    +

    After installing a contract in global state, you can use the contract's hash to call one of its entry points. The following usage of put-deploy allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully.

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-hash [HEX_STRING] \
    --session-entry-point [ENTRY_POINT_FUNCTION]
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • +
    • chain-name - The chain name of the network where you wish to send the deploy. For Mainnet, use casper. For Testnet, use casper-test
    • +
    • secret-key - The file name containing the secret key of the account paying for the deploy
    • +
    • payment-amount - The payment for the deploy in motes
    • +
    • session-hash - Hex-encoded hash of the stored contract to be called as the session
    • +
    • session-entry-point - Name of the method that will be used when calling the session contract
    • +
    +

    Example - Calling the Counter contract by hash:

    +

    In this example, the --session-hash option identifies a stored contract with an entry-point called "counter-inc".

    +
    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 100000000 \
    --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \
    --session-entry-point "counter-inc"
    +

    This put-deploy command is nearly identical to the command used to install the contract. Here, instead of session-path pointing to the Wasm binary, we have session-hash and session-entry-point identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn’t return a value. If an entry point returns a value, use code to interact with runtime return values.

    +
    tip

    The payment amount varies based on each deploy and network chainspec.

    +

    The following sample response contains a deploy_hash, needed to verify the changes in global state, as described here.

    +
    Sample response
    + +
    {
    "id": 1197172763279676268,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"
    }
    }
    +
    +

    +

    Video - Calling a contract by hash:

    +

    This video shows how to query a previously installed Counter contract by hash.

    +

    + +

    +

    Calling Contracts with Session Arguments

    +

    When calling contract entry points, you may need to pass in information using session arguments. The put-deploy command allows you to do this with the --session-arg option:

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-hash [HEX_STRING] \
    --session-entry-point [ENTRY_POINT_FUNCTION] \
    --session-arg ["NAME:TYPE='VALUE'" OR "NAME:TYPE=null"]...
    +

    The arguments of interest are:

    +
      +
    • session-hash - Hex-encoded hash of the stored contract to be called as the session
    • +
    • session-entry-point - Name of the method that will be used when calling the session contract
    • +
    • session-arg - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'
    • +
    +

    Example - Calling the Auction contract using session arguments:

    +

    This example demonstrates how to call the Auction contract's entry point delegate with three arguments:

    +
      +
    • The argument validator is the public key of the validator to whom the tokens will be delegated
    • +
    • The argument amount is the number of tokens to be delegated
    • +
    • The argument delegator is the public key of the account delegating tokens to a validator
    • +
    +

    To make the call, we use the contract hash, hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2, and the --session-hash option.

    +
    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'"
    +

    Video - Calling a contract with session arguments:

    +

    This video shows how to call a modified Counter contract using session arguments.

    +

    + +

    +

    Calling Contracts by Package Hash

    +

    You can also call an entry point in a contract that is part of a contract package (see contract upgrades). Call put-deploy using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified.

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-package-hash [HEX_STRING] \
    --session-entry-point [ENTRY_POINT_FUNCTION] \
    --session-version [INTEGER]
    +

    The arguments of interest are:

    +
      +
    • session-package-hash - Hex-encoded hash of the stored package to be called as the session
    • +
    • session-entry-point - Name of the method that will be used when calling the session contract
    • +
    • session-version - Version of the called session contract. The latest will be used by default
    • +
    +

    Example 1 - Calling the Counter using the package hash and version:

    +

    In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".

    +
    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 100000000 \
    --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \
    --session-entry-point "counter-inc" \
    --session-version 1
    +

    To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:

    +
    {
    "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "name": "counter_package_name"
    }
    +

    Example 2 - Calling the Auction using the package hash and version:

    +

    This example demonstrates how to call the Auction contract's delegate entry point by specifying the package hash using the --session-package-hash option. The call defaults to the highest enabled version since no version was specified with the --session-version option.

    +
    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-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \
    --session-entry-point "delegate" \
    --session-arg "validator:public_key='0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'"
    +

    Video - Calling a contract using the package hash:

    +

    The video shows how to query the previously installed Counter contract package.

    +

    + +

    +

    Calling Contracts by Contract Name

    +

    We can also reference a contract using a key as the contract name. When you write the contract, use the put_key function to add the ContractHash under the contract's NamedKeys.

    +

    Having a key enables you to call a contract's entry-point in global state by using the put-deploy command as illustrated here:

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \
    --session-entry-point [ENTRY_POINT_FUNCTION]
    +

    The arguments of interest are:

    +
      +
    • session-name - Name of the stored contract (associated with the executing account) to be called as the session
    • +
    • session-entry-point - Name of the method that will be used when calling the session contract
    • +
    +

    Example 1 - Calling the Counter contract using a named key:

    +

    This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on GitHub.

    +
    runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());
    +

    The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.

    +
    casper-client put-deploy \
    --node-address http://65.21.235.219:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount 100000000 \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +

    The sample response will contain a deploy_hash, which you need to use as described here to verify the changes in global state.

    +

    Example 2 - Calling the Auction contract using a named key:

    +

    This example uses the system Auction contract stored in global state under the "auction" key and its delegate entry point.

    +
    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-name "auction" \
    --session-entry-point "delegate" \
    --session-arg "validator:public_key='0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf'"
    +

    Video - Calling a contract using a named key:

    +

    This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract.

    +

    + +

    +

    Calling Contracts by Package Name

    +

    To call an entry point in a contract by referencing the contract package name, you can use the session-package-name, session-entry-point, and session-version arguments. This will enable you to access the entry point in global state by using the put-deploy command as illustrated here:

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-package-name [NAMED_KEY_FOR_PACKAGE] \
    --session-entry-point [ENTRY_POINT_FUNCTION] \
    --session-version [INTEGER]
    +

    The arguments of interest are:

    +
      +
    • session-package-name - Name of the stored package to be called as the session
    • +
    • session-entry-point - Name of the method that will be used when calling the session contract
    • +
    • session-version - Version of the called session contract. The latest will be used by default
    • +
    +

    Example 1 - Specifying the package name and version number:

    +

    This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.

    +

    You should have previously created the contract by using new_contract, and provided the contract package name as the hash_name argument of new_contract.

    +

    This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.

    +
        let (stored_contract_hash, contract_version) =
    storage::new_contract(counter_entry_points,
    Some(counter_named_keys),
    Some("counter_package_name".to_string()),
    Some("counter_access_uref".to_string())
    );
    +

    Here is the command to call the contract using the package name:

    +
    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 100000000 \
    --session-package-name "counter_package_name" \
    --session-entry-point "counter-inc" \
    --session-version 1
    +

    Example 2 - Calling the package without specifying the version:

    +

    This example demonstrates how to call a contract that is part of the erc20_test_call package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.

    +
        casper-client put-deploy \
    --node-address http://3.143.158.19:7777 \
    --chain-name integration-test \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --payment-amount 1000000000 \
    --session-package-name "erc20_test_call" \
    --session-entry-point "check_balance_of" \
    --session-arg "token_contract:account_hash='account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180'" \
    --session-arg "address:key='account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd'"
    +

    Video - Calling a contract using the package name:

    +

    This video demonstrates how to call versioned contracts by package name.

    +

    + +

    +

    Calling a Contract using Wasm

    +

    Session code or contract code (compiled to Wasm) can act on a contract and change its state. The put-deploy command supports this mechanism as well:

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [PATH]/[FILE_NAME].wasm
    +

    The argument of interest is:

    +
      +
    • session-path - The path to the compiled Wasm on your computer
    • +
    +

    Example - Session code acting on a contract:

    +

    The Counter Contract Tutorial shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm).

    +

    casper-client put-deploy \
    --node-address http://65.21.235.219:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount 25000000000 \
    --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm

    +

    Video - Calling a contract using Wasm:

    +

    + +

    +

    Calling Contracts that Return a Value

    +

    Visit the Interacting with Runtime Return Values tutorial to learn how to call a contract that returns a value using session code or contract code.

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/delegate/index.html b/2.0.0/developers/cli/delegate/index.html new file mode 100644 index 000000000..0b0075c64 --- /dev/null +++ b/2.0.0/developers/cli/delegate/index.html @@ -0,0 +1,123 @@ + + + + + +Delegating Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Delegating with the Casper Client

    +

    This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.

    +

    Prerequisites

    +
      +
    1. You meet all prerequisites listed here, including having a valid node-address and the Casper command-line client
    2. +
    3. You have previously installed a smart contract to a Casper network
    4. +
    5. Acquiring a Validator's Public Key
    6. +
    +

    Acquiring a Validator's Public Key

    +

    This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the delegation request.

    +

    Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process.

    +

    The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set.

    +

    Sending the Delegation Request

    +

    There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the delegate entry point from the system auction contract. The second method involves building the delegate.wasm from the casper-node repository and installing it on the network.

    +

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    +
    note

    The minimum amount to delegate is 500 CSPR (500,000,000,000 motes).

    +

    Method 1: Delegating with the System Auction Contract

    +

    This method calls the existing delegate entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point delegate \
    --session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
    --session-arg "amount:u512='<AMOUNT_TO_DELEGATE>'" \
    --session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entry point that will be used when calling the contract
    2. +
    +

    The delegate entry point expects three arguments:

    +
      +
    1. validator: The hexadecimal public key of the validator receiving the delegated tokens
    2. +
    3. amount: The number of tokens to be delegated
    4. +
    5. delegator: The hexadecimal public key of the account delegating tokens to a validator. This key must match the secret key that signs the delegation
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +
    note

    Calling the delegate entry point on the auction contract has a fixed cost of 2.5 CSPR.

    +

    Example:

    +

    This example shows an account delegating 500 CSPR:

    +
    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point delegate \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
    +

    Next, confirm the delegation.

    +

    Method 2: Delegating with Compiled Wasm

    +

    Another way to send a delegation is to compile the delegate.wasm and send it to the network via a deploy. Here are the steps to compile the contract yourself.

    +

    Building the delegation Wasm

    +

    Obtain the delegate.wasm by cloning the casper-node repository.

    +
    git clone https://github.com/casper-network/casper-node
    +

    Prepare the Rust environment and then build the contracts using the Makefile provided in the repository.

    +
    cd casper-node
    make setup-rs
    make build-contracts-rs
    +

    Once you build the contracts, you can use the delegate.wasm to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: target/wasm32-unknown-unknown/release/.

    +
    ls target/wasm32-unknown-unknown/release/delegate.wasm
    +

    Sending the delegation request

    +

    In this example, we use the Casper client to send a deploy containing the delegate.wasm to the network to initiate the delegation process.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-path <PATH_TO_WASM>/delegate.wasm \
    --session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
    --session-arg "amount:u512='<AMOUNT_TO_DELEGATE>'" \
    --session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-path - The path to where the delegate.wasm is located
    10. +
    +

    The delegate entry point expects three arguments:

    +
      +
    1. validator: The hexadecimal public key of the validator receiving the delegated tokens
    2. +
    3. amount: The number of tokens to be delegated
    4. +
    5. delegator: The hexadecimal public key of the account delegating tokens to a validator. This key must match the secret key that signs the delegation
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    Example:

    +

    This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the delegate entry point.

    +
    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ~/delegate.wasm \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
    +

    Next, confirm the delegation.

    +

    Confirming the Delegation

    +

    A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:

    +
      +
    1. Your delegation is part of the bid to the auction
    2. +
    3. The validator is part of the active validator set
    4. +
    +

    Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:

    +
    casper-client get-auction-info \
    --node-address http://<peer-ip-address>:7777
    +

    Request fields:

    +
      +
    • node-address - An IP address of a node on the network
    • +
    +

    The get-auction-info call will return all the bids currently in the auction contract and the list of active validators for 4 future eras from the present era.

    +

    Below is a sample of the bids structure:

    +
    "bids": [
    {
    "bid": {
    "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",
    "delegation_rate": 1,
    "delegators": [
    {
    "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",
    "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
    "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",
    "staked_amount": "1"
    },
    {
    "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",
    "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
    "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",
    "staked_amount": "478473232415318176495746923"
    }
    ],
    "inactive": false,
    "staked_amount": "493754513995516852173468935"
    },
    "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"
    },
    +

    The delegation request has been processed successfully if your public key and associated amount appear in the bid data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the era_validators structure.

    +

    Checking Validator Status

    +

    The auction maintains a field called era_validators, which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the PublicKeys of the active validators for that era, along with their stake in the network.

    +

    If a validator is part of the set, its public key will be in the era_validators field as part of the Auction data structure returned by casper-client get-auction-info.

    +

    In the response, check the "auction_state"."era_validators" structure, which should contain the public key of the selected validator for the era in which the validator will be active.

    +

    Below is an example of the era_validators structure:

    +
    "block_height":105,
    "era_validators":[
    {
    "era_id":9,
    "validator_weights":[
    {
    "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",
    "weight":"648151805935226166098427654"
    },
    {
    "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",
    "weight":"648151805938466925128109996"
    },
    {
    "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",
    "weight":"648151805935226166098427656"
    },
    {
    "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",
    "weight":"648151805938466925128109998"
    },
    {
    "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",
    "weight":"648151805938466925128110000"
    }
    ]
    },
    +

    In the above example, we see the public keys of the active validators in Era 9.

    +

    Note: Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request.

    +

    If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:

    +
      +
    1. Testnet explorer
    2. +
    3. Mainnet explorer
    4. +
    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/execution-error-codes/index.html b/2.0.0/developers/cli/execution-error-codes/index.html new file mode 100644 index 000000000..b577af323 --- /dev/null +++ b/2.0.0/developers/cli/execution-error-codes/index.html @@ -0,0 +1,28 @@ + + + + + +Execution Error Codes | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Execution Error Codes

    +

    This section covers smart contract execution error codes.

    +

    As mentioned in Writing Rust Contracts, smart contracts can exit with an error code defined by an ApiError. Descriptions of each variant are found here and include the following sub-types:

    + +

    An ApiError of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ApiError::User(2) maps to an exit code of 65538 (i.e. 65536 + 2). You can find a mapping from contract exit codes to ApiError variants here.

    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/index.html b/2.0.0/developers/cli/index.html new file mode 100644 index 000000000..6ab784ac8 --- /dev/null +++ b/2.0.0/developers/cli/index.html @@ -0,0 +1,67 @@ + + + + + +Interacting with the Blockchain | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Using the Casper CLI Client

    +

    This section explains how to interact with a Casper network using the Casper command-line client written in Rust.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Transferring TokensTransferring tokens from one account to another using the Casper command-line client
    Delegating tokensDelegating tokens to a validator on a Casper network
    Undelegating Tokens with the Casper ClientUndelegating tokens from a validator on a Casper network
    Sending Deploys to a NetworkSending Deploys to a Casper network using the Rust CLI Client
    Installing Smart ContractsSteps to install a contract on a Casper network
    Verifying contracts using the Casper ClientHow to use Smart Contract Verification Service
    Querying Global StateHow to query global state after contract installation
    Calling Smart Contracts with the Rust ClientVarious ways to call a contract's entry-points
    Execution Error CodesError codes for smart contract execution
    + + \ No newline at end of file diff --git a/next/developers/cli/installing-contracts/index.html b/2.0.0/developers/cli/installing-contracts/index.html similarity index 79% rename from next/developers/cli/installing-contracts/index.html rename to 2.0.0/developers/cli/installing-contracts/index.html index 0a1a47bff..e2d0fe7cd 100644 --- a/next/developers/cli/installing-contracts/index.html +++ b/2.0.0/developers/cli/installing-contracts/index.html @@ -1,31 +1,31 @@ - + -Installing Contracts | Casper Docs - Redux +Installing Contracts | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Installing Smart Contracts

    +

    This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.

    Prerequisites

    • You have a compiled contract Wasm to send to a Casper network.
    • -
    • You have installed the Casper CLI client to interact with the network.
    • -
    • You have a Casper Account with a public and secret key pair to initiate the transaction.
    • -
    • You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the faucet to fund your testing account's main purse.
    • +
    • You have installed the Casper CLI client to interact with the network.
    • +
    • You have a Casper Account with a public and secret key pair to initiate the transaction.
    • +
    • You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the faucet to fund your testing account's main purse.

    Installing a Contract in Global State

    -

    To install a contract in global state, you need to send a transaction to the network with the contract Wasm. You can do so by using the put-transaction session command, or the equivalent put-txn session command.

    +

    To install a contract in global state, you need to send a transaction to the network with the contract Wasm. You can do so by using the put-transaction session command, or the equivalent put-txn session command.

    casper-client put-transaction session \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --gas-price-tolerance [MAX_GAS_AMOUNT] \
    --pricing-mode fixed \
    --transaction-path <PATH> \
    --session-entry-point call \
    --category 'install-upgrade'

    The arguments used above are:

      @@ -38,8 +38,8 @@

      Ins
    • session-entry-point - Name of the entrypoint that will be used when installing the contract, which is usually call
    • category - The transaction type, based on Wasm size, with install-upgrade being the largest
    -

    Once you call this command, it will return a transaction hash. You can use this hash to verify successful execution of the transaction.

    -
    tip

    The pricing mode varies based on each network chainspec. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.

    +

    Once you call this command, it will return a transaction hash. You can use this hash to verify successful execution of the transaction.

    +
    tip

    The pricing mode varies based on each network chainspec. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.

    Example - Contract Installation

    Here we send a counter-installer.wasm to a local NCTL network:

    casper-client put-transaction session \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key ~/casper/casper-nctl/assets/net-1/users/user-1/secret_key.pem \
    --gas-price-tolerance 10 \
    --pricing-mode fixed \
    --transaction-path ~/test_contracts/counter_installer.wasm \
    --session-entry-point call \
    --category 'install-upgrade'
    @@ -51,11 +51,11 @@

    Ins
    {
    "jsonrpc": "2.0",
    "id": 5297043714444661948,
    "result": {
    "api_version": "2.0.0",
    "transaction": {
    "Version1": {
    "hash": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2",
    "header": {
    "chain_name": "casper-net-1",
    "timestamp": "2024-08-21T11:21:36.201Z",
    "ttl": "30m",
    "body_hash": "543df05d05c456e9b6b5d657029e9ad20c674c6e6b56f498af0052ec87ee9f80",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 10
    }
    },
    "initiator_addr": {
    "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"
    }
    },
    "body": {
    "args": [],
    "target": {
    "Session": {
    "module_bytes": "[105936 hex chars]",
    "runtime": "VmCasperV1"
    }
    },
    "entry_point": "Call",
    "transaction_category": 2,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d",
    "signature": "01537684dd531ce6a4c9383ba7ea565e9408ed2c5dd8bb12787f131e1148fd0f057f45dbaa7bbc0230743cc5740c67db64f66bab1df57547722899f7d7289c1f0c"
    }
    ]
    }
    },
    "execution_info": {
    "block_hash": "24ead40278a71966e16823150b06c06675a216dbef761c1d6ad1439da4147f4a",
    "block_height": 8463,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"
    },
    "error_message": null,
    "limit": "1000000000000",
    "consumed": "46747144601",
    "cost": "1000000000000",
    "payment": [],
    "transfers": [],
    "size_estimate": 53215,
    "effects": [
    {
    "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "I32",
    "bytes": "00000000",
    "parsed": 0
    }
    }
    }
    },
    {
    "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-05c3e063406ddde43671e0d47c45e31a10e9204137171f96ce818bdc725a4e1b",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1050d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "parsed": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"
    },
    "name": {
    "cl_type": "String",
    "bytes": "14000000636f756e7465725f7061636b6167655f6e616d65",
    "parsed": "counter_package_name"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-6409273bf327d5a6a39a29dbd07c5cd2f48ee4f227fd443d025adc51e1bd5103",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0229feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a07",
    "parsed": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000636f756e7465725f6163636573735f75726566",
    "parsed": "counter_access_uref"
    }
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",
    "kind": "Identity"
    },
    {
    "key": "package-f1c97c9b6228be3f316753e4e1289d910071fb880dddccce18881abfb9f53526",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "[82290 hex chars]"
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-5fed34ec1b2c38445b984eee743ce17fb1e5e89a8cb910cc2f9f12b005360eef",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab0363140707",
    "parsed": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "05000000636f756e74",
    "parsed": "count"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-399a84b0da15b34ecd774b1c4ad47c72a9e1298df057d83bee93d22ac4972aa5",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "counter_get",
    "args": [],
    "ret": "I32",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "counter_inc",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-174ccaaa723ba74cee869017501fab28512b6ef9296d48a38daff7d0da13d1a1",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "027bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf07",
    "parsed": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0700000076657273696f6e",
    "parsed": "version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-83b1cde13136393741a1e906a892ccdd289e7827cc9ef84a98cc96e86464bde0",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",
    "parsed": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    },
    "name": {
    "cl_type": "String",
    "bytes": "07000000636f756e746572",
    "parsed": "counter"
    }
    }
    }
    }
    },
    {
    "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Prune": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000"
    }
    },
    {
    "key": "balance-hold-0021dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "entity-system-b76adcf84d4900edec0af9001e727bcc3d4920a40afaa6a0e43137bacf62b91e",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1d29f1bd6ba7016f430498de2d0fe7c9d2c14c200d79be33e0ad240bc2a0d229",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-01f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-04f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d0903000000000000",
    "kind": {
    "Write": {
    "BidKind": {
    "Credit": {
    "validator_public_key": "01e4bb993269e0fe33d6e575ab6a642fdcaf692449a1529c4f73e636dfff9d3e61",
    "era_id": 777,
    "amount": "1000000000000"
    }
    }
    }
    }
    }
    ]
    }
    }
    }
    }
    }

    -

    Note the contract entity address in the above sample output. You will need this to query the contract installed. In this example, the address is entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68.

    -

    Next, query global state to see more details about the successfully installed contract.

    +

    Note the contract entity address in the above sample output. You will need this to query the contract installed. In this example, the address is entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68.

    +

    Next, query global state to see more details about the successfully installed contract.

    What's Next?

    +
  • Learn to query global state using the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/next/developers/cli/opcode-costs/index.html b/2.0.0/developers/cli/opcode-costs/index.html similarity index 52% rename from next/developers/cli/opcode-costs/index.html rename to 2.0.0/developers/cli/opcode-costs/index.html index 47cf651f0..bc7a931c2 100644 --- a/next/developers/cli/opcode-costs/index.html +++ b/2.0.0/developers/cli/opcode-costs/index.html @@ -1,23 +1,23 @@ - + -OpCode Costs Tables | Casper Docs - Redux +OpCode Costs Tables | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    OpCode Costs Tables

    The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.

    -

    More information on chainspecs for private networks can be found here

    +

    More information on chainspecs for private networks can be found here

    note

    All costs in this table are in motes, not CSPR, and the corresponding chainspec is here.

    Storage Costs

    @@ -656,6 +656,6 @@

    +
    EntrypointDescriptionCost
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10_000
    \ No newline at end of file diff --git a/next/developers/cli/querying-global-state/index.html b/2.0.0/developers/cli/querying-global-state/index.html similarity index 81% rename from next/developers/cli/querying-global-state/index.html rename to 2.0.0/developers/cli/querying-global-state/index.html index b53cfcdba..1301ca267 100644 --- a/next/developers/cli/querying-global-state/index.html +++ b/2.0.0/developers/cli/querying-global-state/index.html @@ -1,25 +1,25 @@ - + -Querying Global State | Casper Docs - Redux +Querying Global State | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Querying Global State

    This page explains how to query global state to find account, contract, and package details.

    Prerequisites

    Getting the State Root Hash

    The first step in querying global state is obtaining the state root hash, which acts as an identifier for the current state of the network. It is like a Git commit ID for commit history, providing a snapshot of the blockchain state at a specific time.

    @@ -164,7 +164,7 @@

    {
    "jsonrpc": "2.0",
    "id": -8997536139716357387,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "CLValue": {
    "cl_type": "I32",
    "bytes": "00000000",
    "parsed": 0
    }
    },
    "merkle_proof": "[14486 hex chars]"
    }
    }

    What's Next?

    +
  • Learn different ways to call contracts using the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/2.0.0/developers/cli/redelegate/index.html b/2.0.0/developers/cli/redelegate/index.html new file mode 100644 index 000000000..4660f4c78 --- /dev/null +++ b/2.0.0/developers/cli/redelegate/index.html @@ -0,0 +1,86 @@ + + + + + +Redelegating Tokens with the Casper Client | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Redelegating Tokens with the Casper Client

    +

    This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.

    +

    Prerequisites

    +
      +
    1. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    2. +
    3. You have delegated tokens to a validator on a Casper network, and you have the validator's public key
    4. +
    5. You have the public key of the new validator to whom you wish to redelegate tokens. See Acquiring a Validator's Public Key for more details
    6. +
    +

    Method 1: Redelegating with the System Auction Contract

    +

    This method calls the existing redelegate entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \
    --chain-name <CHAIN_NAME> \
    --payment-amount 2500000000 \
    --session-hash <SESSION_HASH> \
    --session-entry-point redelegate \
    --session-arg "delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'" \
    --session-arg "validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'" \
    --session-arg "amount:u512='<DELEGATION_AMOUNT>'" \
    --session-arg "new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entrypoint that will be used when calling the contract
    2. +
    +

    The redelegate entry point expects four arguments:

    +
      +
    1. delegator:public_key: The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy
    2. +
    3. validator:public_key: The hexadecimal public key of the validator from whom the tokens will be undelegated
    4. +
    5. amount: The amount to be redelegated to the new validator
    6. +
    7. new_validator:public_key: The hexadecimal public key of the validator to whom the tokens will be delegated
    8. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    Calling the redelegate entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations.

    +

    Example:

    +

    This example uses a private network running casper-node version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +
    casper-client put-deploy \
    --node-address http://3.143.158.19:7777 \
    --chain-name integration-test \
    --secret-key ~/KEYS/integration/Test_secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \
    --session-entry-point redelegate \
    --session-arg "validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'" \
    --session-arg "new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'"
    +

    Next, verify the redelegation.

    +

    Method 2: Redelegating with Compiled Wasm

    +

    Another way to send a redelegation is to compile the redelegate.wasm and send it to the network via a deploy. To compile the Wasm yourself, build the casper-node contracts that will include the redelegation Wasm.

    +

    Sending the redelegation request

    +

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    +

    This example uses the Casper client to send a deploy containing the redelegate.wasm to the network to initiate the redelegation process.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path <PATH_TO_WASM>/redelegate.wasm \
    --session-arg "delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'" \
    --session-arg "validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'" \
    --session-arg "amount:u512='<DELEGATION_AMOUNT>'" \
    --session-arg "new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR
    8. +
    9. session-path - The path to the redelegate.wasm on your computer
    10. +
    +

    The redelegate.wasm expects four arguments:

    +
      +
    1. delegator:public_key: The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy
    2. +
    3. validator:public_key: The hexadecimal public key of the validator from whom the tokens will be undelegated
    4. +
    5. amount: The amount to be redelegated to the new validator
    6. +
    7. new_validator:public_key: The hexadecimal public key of the validator to whom the tokens will be delegated
    8. +
    +

    Save the returned deploy_hash from the output to query information about the redelegation Deploy.

    +
    note

    Running the redelegate.wasm is a more expensive operation than calling the redelegate entrypoint from the system auction contract.

    +

    Example:

    +

    This example uses a private network running casper-node version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +
    casper-client put-deploy \
    --node-address http://3.143.158.19:7777 \
    --chain-name integration-test \
    --secret-key ~/KEYS/integration/Test_secret_key.pem \
    --payment-amount 8000000000 \
    --session-path ~/redelegate.wasm \
    --session-arg "validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'" \
    --session-arg "new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'"
    +

    Verifying the Redelegation

    +

    The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy.

    +

    Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator.

    +

    Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as verifying a delegation request using the casper-client get-auction-info command.

    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/sending-transactions/index.html b/2.0.0/developers/cli/sending-transactions/index.html new file mode 100644 index 000000000..a6f3b39a5 --- /dev/null +++ b/2.0.0/developers/cli/sending-transactions/index.html @@ -0,0 +1,128 @@ + + + + + +Sending Transactions | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Sending Transactions using the Casper Client

    +

    To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:

    +
      +
    • You will need a client to interact with the network, such as the default Casper client
    • +
    • Ensure you have an Account and its associated keys This account will pay for the Transaction, and its secret key will sign the Transaction
    • +
    • Ensure this account has enough CSPR tokens to pay for the Transaction
    • +
    +

    Paying for Transactions

    +

    CSPR tokens are used to pay for transactions on the Casper Mainnet and Testnet. There are several ways to fund your account:

    + +

    Monitoring the Event Stream for Transactions

    +

    If you want to follow the lifecycle of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described here. You need the following information to proceed:

    +
      +
    • The IP address of a peer on the network
    • +
    • The port specified as the event_stream_server.address in the node's config.toml, which is by default 9999 on Mainnet and Testnet
    • +
    • The URL for streamed events, which is HOST:PORT/events
    • +
    +

    With the following command, you can start watching the event stream. Note the event ID recorded when you send the Transaction in the next section.

    +
    curl -s http://65.21.235.219:9999/events
    +

    Sending a Transaction to the Network

    +

    You can call the Casper client's put-txn command to put the compiled contract on the chain. In this example, the Transaction will execute in the account's context. See the advanced features section for key delegation.

    +
    casper-client put-txn session\
    --node-address <HOST:PORT> \
    --chain-name casper-net-1 \
    --transaction-path <transaction-PATH> \
    --session-entry-point <NAME> \
    --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \
    --gas-price-tolerance <INTEGER> \
    --pricing-mode fixed \
    --secret-key <PATH> | --initiator-address <HEX STRING>
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of the sidecar's JSON-RPC server on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, config.toml. Here is an example. You may send transactions to one of the trusted nodes or use them to query other online nodes.
    2. +
    3. chain-name - The chain-name to the network where you wish to send the Transaction. For Mainnet, use casper. For Testnet, use casper-test. As you can see, this example uses the Testnet.
    4. +
    5. transaction-path - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer.
    6. +
    7. session-entry-point - Name of the method that will be used when calling the session contract.
    8. +
    9. category - The transaction category, based on size of the Wasm included. install-upgrade being the largest, descending in size through large, medium and small
    10. +
    11. gas-price-tolerance - The maximum gas price that the user is willing to pay for this transaction.
    12. +
    13. pricing-mode - The pricing mode used for this transaction, in this case fixed.
    14. +
    15. secret-key or initiator-address - The file name containing the secret key of the account paying for the Transaction, or the address of the account initiating the transaction. initiator-address can be a public key, account hash or an entity address.
    16. +
    +

    The command will return a transaction hash, which is needed to verify the transaction's execution results. Sending the transaction and receiving the transaction hash does not mean the transaction was processed successfully. Therefore, you must check the transaction execution using the transaction hash. See the transaction lifecycle for more details.

    +

    Note: Each Transaction gets a unique hash, which is part of the cryptographic security of blockchain technology. No two transactions will ever return the same hash.

    +
    Sample put-txn result
    + +
    {
    "jsonrpc": "2.0",
    "id": 1294011212530641270,
    "result": {
    "api_version": "2.0.0",
    "transaction_hash": {
    "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"
    }
    }
    }
    +
    +

    Verify the transaction details with the get-txn command and the transaction_hash received above.

    +
    casper-client get-txn \
    --node-address <HOST:PORT> <TRANSACTION-HASH>
    +

    If the Transaction succeeded, the get-txn command would return a JSON object with the full transaction details.

    +
    Sample get-transaction result
    + +

    {
    "jsonrpc": "2.0",
    "id": -3929997047953574815,
    "result": {
    "api_version": "2.0.0",
    "transaction": {
    "Version1": {
    "hash": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e",
    "header": {
    "chain_name": "casper-net-1",
    "timestamp": "2024-07-17T16:45:43.821Z",
    "ttl": "30m",
    "body_hash": "c5c4f7ae2fecb68937c19a1439eefddd8d4c32de779fe3ffee292977f161b234",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 10
    }
    },
    "initiator_addr": {
    "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"
    }
    },
    "body": {
    "args": [
    [
    "name",
    {
    "cl_type": "String",
    "bytes": "050000004345503138",
    "parsed": "CEP18"
    }
    ],
    [
    "symbol",
    {
    "cl_type": "String",
    "bytes": "0400000067726973",
    "parsed": "gris"
    }
    ],
    [
    "total_supply",
    {
    "cl_type": "U256",
    "bytes": "0164",
    "parsed": "100"
    }
    ],
    [
    "decimals",
    {
    "cl_type": "U8",
    "bytes": "01",
    "parsed": 1
    }
    ]
    ],
    "target": {
    "Session": {
    "module_bytes": "[655810 hex chars]",
    "runtime": "VmCasperV1"
    }
    },
    "entry_point": "Call",
    "transaction_category": 2,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65",
    "signature": "012ac4fc94d4ba269eb94aad1b9e90d1f701ed0e660995c1a15afc69010b74b51dd1334f9a59a9587aaf6aa6ab5ad35a7e86a9dcba39c2d21843e56d5d4014f00f"
    }
    ]
    }
    },
    "execution_info": {
    "block_hash": "23f21d3af261dd830790926b240dbded4362bb3c1183d9ee4ec1aea132bfa5e0",
    "block_height": 624,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"
    },
    "error_message": null,
    "limit": "1000000000000",
    "consumed": "371736413663",
    "cost": "1000000000000",
    "payment": [],
    "transfers": [],
    "size_estimate": 328238,
    "effects": [
    {
    "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "String",
    "bytes": "050000004345503138",
    "parsed": "CEP18"
    }
    }
    }
    },
    {
    "key": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "String",
    "bytes": "0400000067726973",
    "parsed": "gris"
    }
    }
    }
    },
    {
    "key": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U8",
    "bytes": "01",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U256",
    "bytes": "0164",
    "parsed": "100"
    }
    }
    }
    },
    {
    "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U8",
    "bytes": "00",
    "parsed": 0
    }
    }
    }
    },
    {
    "key": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U8",
    "bytes": "00",
    "parsed": 0
    }
    }
    }
    },
    {
    "key": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-987369d1ce9ffff037841f4a221d7fc63924d565196de9e67ea8bdb897bc22e7",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"
    },
    "name": {
    "cl_type": "String",
    "bytes": "1c00000063657031385f636f6e74726163745f7061636b6167655f4345503138",
    "parsed": "cep18_contract_package_CEP18"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-eb635428d8eb01ac5683a333755ba85f6299df45cab9048c18d84fbc5367e932",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b507",
    "parsed": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "2300000063657031385f636f6e74726163745f7061636b6167655f6163636573735f4345503138",
    "parsed": "cep18_contract_package_access_CEP18"
    }
    }
    }
    }
    },
    {
    "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "kind": "Identity"
    },
    {
    "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",
    "kind": "Identity"
    },
    {
    "key": "package-1b937640b847113bb5adeccdd1aae96a913c340c1911949f90c90a0dd025d9a4",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "[659014 hex chars]"
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f07",
    "parsed": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "08000000646563696d616c73",
    "parsed": "decimals"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f26520fac960fb1abac44a358923ab6a064baffb1707c885886d157f66c55209",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce07",
    "parsed": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "10000000656e61626c655f6d696e745f6275726e",
    "parsed": "enable_mint_burn"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-7114a751e72d65a0290c975396374e0120ac8f3ddbb6e4e21e3c6810135b40d0",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0216baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e0307",
    "parsed": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0b0000006576656e74735f6d6f6465",
    "parsed": "events_mode"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "024bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d07",
    "parsed": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "040000006e616d65",
    "parsed": "name"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0221a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a07",
    "parsed": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0600000073796d626f6c",
    "parsed": "symbol"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad107",
    "parsed": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0c000000746f74616c5f737570706c79",
    "parsed": "total_supply"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e3c8f46f39b1ee1cbadb774ffaf842226b7cbf1fef3bbc04abfa80b86daca11",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "allowance",
    "args": [
    {
    "name": "owner",
    "cl_type": "Key"
    },
    {
    "name": "spender",
    "cl_type": "Key"
    }
    ],
    "ret": "U256",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44528c1898e30df62037a76e0c45123f4f4437336ca63236b10ebfc16a5edb78",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "approve",
    "args": [
    {
    "name": "spender",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fcc296caa05679d0d11121e7629b29f222a857018f50985046b73a56e9a10701",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "balance_of",
    "args": [
    {
    "name": "address",
    "cl_type": "Key"
    }
    ],
    "ret": "U256",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-768c370eb010604bd19029a409dca8b5fbf9af9bc14a36c2b294a2a7a922161e",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "burn",
    "args": [
    {
    "name": "owner",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bab8615f758ed79acb7dd7577b1a6c12d625d1a19592a2b1ded0dc352407e4d5",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "change_events_mode",
    "args": [
    {
    "name": "events_mode",
    "cl_type": "U8"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-82a811993cf9ccb5e46c9608c69d86e3c9b7b499520fd48cdca1424f2a08efdc",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "change_security",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "condor",
    "args": [],
    "ret": "String",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "decimals",
    "args": [],
    "ret": "U8",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-ac07c23dc90a33282d553af890e30e62335c5ae986629d643778e2d4516f26ad",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "decrease_allowance",
    "args": [
    {
    "name": "spender",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-a7e05838c728d16c4ba3e1980b6729c857ef4c21d1b0c34e6eefbb486cdc2b89",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "increase_allowance",
    "args": [
    {
    "name": "spender",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "init",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fc79236fd0e4521c8feddcc2094c6a0ea04fcaafb17fef63ef060744a6bab401",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "migrate_sec_keys",
    "args": [
    {
    "name": "events",
    "cl_type": "Bool"
    },
    {
    "name": "revert",
    "cl_type": "Bool"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-18bff854e9d908cf20fb1db53a47ab69968917b53b8c71371e7dd0f88b363e60",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "migrate_user_allowance_keys",
    "args": [
    {
    "name": "events",
    "cl_type": "Bool"
    },
    {
    "name": "revert",
    "cl_type": "Bool"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e7babf918642bd9636d3c121691bd85534b41084a5c22fe1e2bf196224dade6",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "migrate_user_balance_keys",
    "args": [
    {
    "name": "events",
    "cl_type": "Bool"
    },
    {
    "name": "revert",
    "cl_type": "Bool"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-233964bb1dc667b37a8abbb938d7647b2c4ab41f0c26dbbcd26c62e7870f72ba",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "mint",
    "args": [
    {
    "name": "owner",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "name",
    "args": [],
    "ret": "String",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "symbol",
    "args": [],
    "ret": "String",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "total_supply",
    "args": [],
    "ret": "U256",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-3820ce25e54df0470fb738e3e0f63ee50b2719cf2680da2bdb579e21aebc8f63",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "transfer",
    "args": [
    {
    "name": "recipient",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44208043191e40d3417df6878e1a23894172cf37cf2e4444384ada99e25430e7",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "transfer_from",
    "args": [
    {
    "name": "owner",
    "cl_type": "Key"
    },
    {
    "name": "recipient",
    "cl_type": "Key"
    },
    {
    "name": "amount",
    "cl_type": "U256"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "byte_code_hash": "byte-code-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",
    "main_purse": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-dc1e638c71901f1e8fd375ce7a9c6eb2f240241b4ca9cbb7abd65ce16f879a22",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": [
    {
    "topic_name": "errors",
    "topic_name_hash": "b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc"
    }
    ]
    }
    }
    }
    },
    {
    "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "message-topic-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc",
    "kind": {
    "Write": {
    "MessageTopic": {
    "message_count": 0,
    "blocktime": 1721234748003
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-0268d6df10a5edcebe0d3790d2eba676dba455e46a2c880085fdbeca4ab762fb",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",
    "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"
    },
    "name": {
    "cl_type": "String",
    "bytes": "1900000063657031385f636f6e74726163745f686173685f4345503138",
    "parsed": "cep18_contract_hash_CEP18"
    }
    }
    }
    }
    },
    {
    "key": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-da1fb8c629dc3b127c4cc7e8b09431872aa846af6777bb15b280126ca65663cd",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "021075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a07",
    "parsed": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "1c00000063657031385f636f6e74726163745f76657273696f6e5f4345503138",
    "parsed": "cep18_contract_version_CEP18"
    }
    }
    }
    }
    },
    {
    "key": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "String",
    "bytes": "06000000636f6e646f72",
    "parsed": "condor"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "024bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a7807607",
    "parsed": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "06000000636f6e646f72",
    "parsed": "condor"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",
    "kind": "Identity"
    },
    {
    "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",
    "kind": "Identity"
    },
    {
    "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",
    "kind": "Identity"
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-c45567f4859db5b100d4c45a9638973ccdf0a7068a2a50f7a1c8709d5e84fbd2",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",
    "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0c0000007061636b6167655f68617368",
    "parsed": "package_hash"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-d447c1e29c0d374421e2c3f290c580a73aa748eba54e1b6bb3da0acdd4cdcee5",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",
    "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0d000000636f6e74726163745f68617368",
    "parsed": "contract_hash"
    }
    }
    }
    }
    },
    {
    "key": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bce0df2b23ec57062235795dd9b7a1a6dc07885918c6cee5c5859a9df3d498e0",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e21422207",
    "parsed": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0a000000616c6c6f77616e636573",
    "parsed": "allowances"
    }
    }
    }
    }
    },
    {
    "key": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-058ed80a0c85bcf8470ac5b8ca4c14f1086c3cd5ae00f1f0592fee3addf4073c",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "027e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d1707",
    "parsed": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0800000062616c616e636573",
    "parsed": "balances"
    }
    }
    }
    }
    },
    {
    "key": "dictionary-52d71098e9663be90740263d98e5596d99a9c854beada13b2fa1be0e5ab1dd4b",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "[190 hex chars]",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-5f4fd818ad44d4ae056e151759a8585de97a1c7c4d53ceecac6631f9fbb39ab6",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "02a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf07",
    "parsed": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0f00000073656375726974795f626164676573",
    "parsed": "security_badges"
    }
    }
    }
    }
    },
    {
    "key": "dictionary-4e62a209ec9eda0bdfffd2039d231751690eb4594bab0744d59ae01f3b44b875",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "[188 hex chars]",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",
    "kind": "Identity"
    },
    {
    "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",
    "kind": {
    "Prune": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000"
    }
    },
    {
    "key": "balance-hold-004c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "entity-system-11a9f79f8943382d3bff560b55d3153bf33f7a883b0da8da4ad879c5648a4d5b",
    "kind": "Identity"
    },
    {
    "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",
    "kind": "Identity"
    },
    {
    "key": "entity-system-b317612414e2c1f864730f98386c906db6ea330555f57ba2e5c50daca8eec817",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-01d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c1100300",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-04d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c11003003900000000000000",
    "kind": {
    "Write": {
    "BidKind": {
    "Credit": {
    "validator_public_key": "01e9f55f093d23c687d249f63e7ffaa567560500e794751c0ca897af06af3e5102",
    "era_id": 57,
    "amount": "1000000000000"
    }
    }
    }
    }
    }
    ]
    }
    }
    }
    }
    }

    +
    +

    We want to draw your attention to a few properties in the example output:

    +
      +
    • Execution consumed 371736413663 motes, which is less than our gas price tolerance of 1000000000000. Read about gas cost for transactions
    • +
    • The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the --gas-price-tolerance arg
    • +
    • The time-to-live was 30 minutes
    • +
    +

    It is also possible to get a summary of the transaction's information by performing a query-global-state command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed.

    +
    casper-client get-state-root-hash --node-address <HOST:PORT>

    casper-client query-global-state --node-address <HOST:PORT> \
    --key transaction-<TRANSACTION-HASH-HEX-STRING> \
    --state-root-hash <STATE-ROOT-HASH-HEX-STRING>
    +
    casper-client query-global-state --node-address <HOST:PORT> \
    --key transaction-<TRANSACTION-HASH-HEX STRING>
    --block-hash <BLOCK-HASH-HEX-STRING>
    +

    Run the help command for query-global-state to see its usage.

    +
    casper-client query-global-state --help
    +

    Time-to-live

    +

    Time-to-live is the parameter that determines how long a transaction will wait for execution. The acceptable maximum ttl is configurable by chain, with the Casper Mainnet maximum set to 18hours. If you are sending a transaction to a different network, you will need to check chainspec.toml for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid transaction.

    +

    In the event of a network outage or other event that prevents execution within the ttl, the solution is to resend the transaction in question.

    +

    Should the transaction's ttl exceed the allowable limit, or if the transaction expires, the network's transaction acceptor will find the transaction invalid and return a warning.

    +

    Legacy Deploy Payments

    +

    Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution. All legacy deploys will go through the session subcommand for put-txn.

    +

    The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an empty ModuleBytes as your payment code. However, you must specify the amount within a runtime argument. ModuleBytes can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost.

    +

    You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:

    +

    StoredContractByHash

    +

    StoredContractByName

    +

    StoredVersionContractByHash

    +

    StoredVersionContractByName

    +

    Using Arguments with Transactions

    +

    The session Wasm (or payment Wasm if you choose to not use the standard payment) of a Transaction often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the --session-arg or --payment-arg options, once for each arg required. The Casper client provides some examples of how to do this:

    +
    casper-client put-txn session --help
    +

    Advanced Features

    +

    Casper networks support complex transactions using multiple signatures. Casper Accounts use a powerful permissions model that enables a multi-signature scheme for transactions.

    +

    The put-transaction command performs multiple actions under the hood, optimizing the typical use case. It creates a transaction, signs it, and sends the Transaction to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:

    +
      +
    • make-transaction - Creates a Transaction and outputs it to a file or stdout. As a file, the transaction can subsequently be signed by other parties using the sign-transaction subcommand and then sent to the network for execution using the send-transaction subcommand
    • +
    • sign-transaction - Reads a previously-saved Transaction from a file, cryptographically signs it, and outputs it to a file or stdout
    • +
    • send-transaction - Reads a previously-saved Transaction from a file and sends it to the network for execution
    • +
    +

    To sign a Transaction with multiple keys, create the Transaction with the make-transaction command. The generated transaction file can be sent to the other signers, who then sign it with their keys by calling the sign-transaction for each key. Signatures need to be gathered on the Transaction one after another until all required parties have signed the Transaction. Finally, the signed Transaction is sent to the network with the send-transaction command for processing.

    +

    For a step-by-step workflow, visit the Two-Party Multi-Signature Transaction guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network.

    +

    Gas Cost for Transactions

    +

    A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"

    +

    We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the transaction. If you plan on sending a transaction to Mainnet, you can use the Testnet to estimate the payment amount needed for the transaction.

    +
    note

    Casper's "Condor" release introduces a new payment system that includes the concept of fee elimination.

    +

    If your test configuration matches your production chainspec, you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the runtime economics section for more details about gas usage and fees.

    +

    Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    +

    If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the failed execution.

    +

    However, if the failure occurs prior to session execution, the penalty payment will not appear in the transaction's gas cost. Depending on the network configuration, the system will deduct the processing fee from the sending account's main purse or place a processing hold on the purse.

    + +

    Out of gas error

    +

    You might encounter an "Out of gas error" when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.

    +

    Here is an example of a transaction that resulted in an "Out of gas error" on the Mainnet.

    +

    Figure 1: In the Deploys tab of an account on cspr.live, a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an "Out of gas error".

    +

    Out of gas error

    +

    Figure 2: Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully.

    +

    Gas error in account

    +

    Figure 3: Click the Show raw data button, to see more details about the deploy. Towards the end of the raw data, you can see the error message.

    +

    Gas error in raw data

    +

    Gas limit error

    +

    You may sometimes see an error such as "payment: 2.5, cost: 2.5, Error::GasLimit". This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error.

    +

    This error message tries to communicate that execution stopped at 2.5 CSPR, and the transaction did not run to completion. In other words, the computation resulted in an error because there were insufficient funds for the transaction to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution and charged that much, resulting in a failed transaction. The execution engine does not know how much it would have cost if allowed to run to completion because it did not allow the transaction to finish since it would have run over its gas limit.

    +

    In summary, when a transaction hits its gas limit (the payment amount), execution stops.

    + + \ No newline at end of file diff --git a/next/developers/cli/transfers/direct-token-transfer/index.html b/2.0.0/developers/cli/transfers/direct-token-transfer/index.html similarity index 81% rename from next/developers/cli/transfers/direct-token-transfer/index.html rename to 2.0.0/developers/cli/transfers/direct-token-transfer/index.html index 40c6ef6b1..6fb5c5d2a 100644 --- a/next/developers/cli/transfers/direct-token-transfer/index.html +++ b/2.0.0/developers/cli/transfers/direct-token-transfer/index.html @@ -1,33 +1,33 @@ - + -Direct Token Transfer | Casper Docs - Redux +Direct Token Transfer | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Direct Token Transfer

    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 general development prerequisites
    2. +
    3. You meet the general development prerequisites
    4. You are using the Casper command-line client
    5. You have a target public key
    6. You have a valid node address
    7. You must be able to sign a deploy for the source account using the source secret key

    Direct Transfer Example

    -

    The following transfer command allows you to move CSPR from one account's purse to another as denominated in Motes. 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. 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.

    casper-client transfer \
    --id <ID> \
    --transfer-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 [TARGET_PUBLIC_KEY_HEX] \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES]

    Request fields:

    @@ -58,7 +58,7 @@

    Direct Transfer Exa

    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. For Testnet node version 1.5.1, you can specify 10^8 motes

    +

    payment-amount - The payment for the transfer in motes. The payment amount varies based on each deploy and network chainspec. For Testnet node version 1.5.1, you can specify 10^8 motes

  • Important response fields:

    @@ -93,8 +93,8 @@

    Verifying the

    JSON-RPC Response:

    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.3",
    "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"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "014767a90000000000",
    "parsed": 11102023
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"
    }
    ]
    },
    "execution_results": [
    {
    "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",
    "result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06621c3e660301",
    "parsed": "1114111876194"
    }
    }
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",
    "transform": "Identity"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06621c3e660301",
    "parsed": "1114111876194"
    }
    }
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": "Identity"
    },
    {
    "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",
    "transform": "Identity"
    },
    {
    "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "06622a383c0201",
    "parsed": "1109111876194"
    }
    }
    },
    {
    "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",
    "transform": {
    "AddUInt512": "5000000000"
    }
    },
    {
    "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",
    "transform": {
    "WriteTransfer": {
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",
    "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",
    "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",
    "amount": "5000000000",
    "gas": "0",
    "id": 11102023
    }
    }
    },
    {
    "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",
    "transfers": [
    "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"
    ],
    "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",
    "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",
    "gas": "100000000"
    }
    }
    },
    {
    "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"
    },
    {
    "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",
    "transform": "Identity"
    },
    {
    "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": "Identity"
    },
    {
    "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",
    "transform": "Identity"
    },
    {
    "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",
    "transform": {
    "AddUInt512": "100000000"
    }
    }
    ]
    },
    "transfers": [
    "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"
    ],
    "cost": "100000000"
    }
    }
    }
    ]
    },
    "id": -3447643973713335073
    }

    -

    Refer to the Section on querying deploys for more information.

    +

    Refer to the Section on querying deploys for more information.

    Verifying the Transfer

    -

    In addition to verifying the deploy, you also need to verify the transfer details. The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly.

    +

    In addition to verifying the deploy, you also need to verify the transfer details. 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 diff --git a/2.0.0/developers/cli/transfers/index.html b/2.0.0/developers/cli/transfers/index.html new file mode 100644 index 000000000..8934e8d16 --- /dev/null +++ b/2.0.0/developers/cli/transfers/index.html @@ -0,0 +1,27 @@ + + + + + +Transferring Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Transferring Tokens with the Casper CLI Client

    +

    The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.

    +

    Transferring tokens using a direct transfer

    +

    Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see Transferring Tokens Using Direct Transfer.

    +

    Transferring tokens using a multi-sig tranasction

    +

    Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the Two-Party Multi-Signature transactions workflow. To use a multi-sig transaction transfer, see Transferring Tokens Using a Multi-sig Account.

    +

    Verifying a transfer using the command-line client

    +

    To verify the status of a transfer, see Verifying a Transfer.

    + + \ No newline at end of file diff --git a/next/developers/cli/transfers/multisig-deploy-transfer/index.html b/2.0.0/developers/cli/transfers/multisig-deploy-transfer/index.html similarity index 69% rename from next/developers/cli/transfers/multisig-deploy-transfer/index.html rename to 2.0.0/developers/cli/transfers/multisig-deploy-transfer/index.html index 5daed034a..fbea5e5d9 100644 --- a/next/developers/cli/transfers/multisig-deploy-transfer/index.html +++ b/2.0.0/developers/cli/transfers/multisig-deploy-transfer/index.html @@ -1,34 +1,34 @@ - + -Transferring Tokens using a Multi-Sig Deploy | Casper Docs - Redux +Transferring Tokens using a Multi-Sig Deploy | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Transferring Tokens using a Multi-Sig Deploy

    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

    You must ensure the following prerequisites are met.

      -
    1. Set up all the prerequisites listed here, including: +
    2. Set up all the prerequisites listed here, including:
    3. -
    4. Set up the source account for multi-signature deploys, as outlined in the Two-Party Multi-Signature Deploys workflow
    5. +
    6. Set up the source account for multi-signature deploys, as outlined in the Two-Party Multi-Signature Deploys workflow
    7. Get the path of the source account's secret key file
    8. Get the target account's public key in hex format
    @@ -77,7 +77,7 @@

    Creati -
    ParameterDescription
    amountThe number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)
    secret-keyThe path of the secret key file for the source account
    chain-nameThe name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain
    • For Testnet use casper-test
    • For Mainnet use casper
    target-accountHex-encoded public key of the target account from which the main purse will be used
    transfer-idA user-defined identifier permanently associated with the transfer
    payment-amountThe payment for the transfer in motes. The payment amount varies based on the deploy and network chainspec. For Testnet node version 1.5.1, wasmless transfers cost 10^8 motes
    +
    ParameterDescription
    amountThe number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)
    secret-keyThe path of the secret key file for the source account
    chain-nameThe name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain
    • For Testnet use casper-test
    • For Mainnet use casper
    target-accountHex-encoded public key of the target account from which the main purse will be used
    transfer-idA user-defined identifier permanently associated with the transfer
    payment-amountThe payment for the transfer in motes. The payment amount varies based on the deploy and network chainspec. For Testnet node version 1.5.1, 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.

    Example:

    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
    @@ -143,13 +143,13 @@

    Send
    {
    "jsonrpc": "2.0",
    "id": -818883417884028030,
    "result": {
    "api_version": "1.5.3",
    "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"
    }
    }

    -
    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 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 workflow is an example of how to accomplish this.

    Example of an account authorization error
    {
    "code": -32008,
    "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"
    }

    Verifying the transfer

    -

    To verify the transfer status, see Verifying a Transfer.

    -
    tip

    You can also verify if the transfer was successful by checking your account balance using a block explorer.

    +

    To verify the transfer status, see Verifying a Transfer.

    +
    tip

    You can also verify if the transfer was successful by checking your account balance using a block explorer.

    \ No newline at end of file diff --git a/next/developers/cli/transfers/verify-transfer/index.html b/2.0.0/developers/cli/transfers/verify-transfer/index.html similarity index 79% rename from next/developers/cli/transfers/verify-transfer/index.html rename to 2.0.0/developers/cli/transfers/verify-transfer/index.html index 40ed5314d..663bf608e 100644 --- a/next/developers/cli/transfers/verify-transfer/index.html +++ b/2.0.0/developers/cli/transfers/verify-transfer/index.html @@ -1,25 +1,25 @@ - + -Verifying a Transfer | Casper Docs - Redux +Verifying a Transfer | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Verifying a Transfer

    Prerequisites

    Before verifying a transfer, make sure you have:

      -
    1. Initiated a Direct Transfer or Multi-sig Deploy Transfer
    2. +
    3. Initiated a Direct Transfer or Multi-sig Deploy Transfer
    4. The deploy_hash of the transfer you want to verify
    5. The public key of the source and target accounts
    @@ -126,6 +126,6 @@

    Query the
    {
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": {
    "state_identifier": {
    "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
    },
    "purse_identifier": {
    "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"
    }
    },
    "id": 7
    }

    JSON-RPC Response:

    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.3",
    "balance": "46200000000"
    },
    "id": 7
    }
    -

    +
    \ No newline at end of file diff --git a/2.0.0/developers/cli/undelegate/index.html b/2.0.0/developers/cli/undelegate/index.html new file mode 100644 index 000000000..766e41239 --- /dev/null +++ b/2.0.0/developers/cli/undelegate/index.html @@ -0,0 +1,95 @@ + + + + + +Undelegating Tokens | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Undelegating Tokens with the Casper Client

    +

    This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.

    +

    Prerequisites

    +
      +
    1. You meet all prerequisites, including having a valid node-address and the Casper command-line client
    2. +
    3. You have delegated tokens to a validator on a Casper network and you have the validator's public key
    4. +
    +

    Sending the Undelegation Request

    +

    There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the undelegate entry point from the system auction contract. The second method involves building the undelegate.wasm from the casper-node repository and installing it on the network.

    +

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    +

    Method 1: Undelegating with the System Auction Contract

    +

    This method calls the existing undelegate entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point undelegate \
    --session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
    --session-arg "amount:u512='<AMOUNT_TO_UNDELEGATE>'" \
    --session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entry point that will be used when calling the contract
    2. +
    +

    The undelegate entry point expects three arguments:

    +
      +
    1. validator: The hexadecimal public key of the validator from whom the tokens will be undelegated
    2. +
    3. amount: The number of tokens to be undelegated
    4. +
    5. delegator: The hexadecimal public key of the account undelegating tokens from a validator. This key must match the secret key that signs the delegation
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +
    note

    Calling the undelegate entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call.

    +

    Example:

    +

    This example shows an account delegating 100 CSPR:

    +
    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point undelegate \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='100000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
    +

    Next, confirm the undelegation.

    +

    Method 2: Undelegating with Compiled Wasm

    +

    As part of this process, you need to build the casper-node contracts that produce the undelegation Wasm.

    +

    Next, use the Casper CLI client to send a deploy containing the undelegate.wasm to the network to initiate the undelegation process.

    +
    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-path <PATH_TO_WASM>/undelegate.wasm \
    --session-arg "validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'" \
    --session-arg "amount:u512='<AMOUNT_TO_UNDELEGATE>'" \
    --session-arg "delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-path - The path to where the delegate.wasm is located
    10. +
    +

    The undelegate entry point expects three arguments:

    +
      +
    1. validator: The hexadecimal public key of the validator from whom the tokens will be undelegated
    2. +
    3. amount: The number of tokens to be undelegated
    4. +
    5. delegator: The hexadecimal public key of the account undelegating tokens from a validator. This key must match the secret key that signs the delegation
    6. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    Example:

    +

    This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network chainspec. However, notice that this method is more expensive than the previous one that calls the undelegate entry point.

    +
    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 6000000000 \
    --session-path ~/undelegate.wasm \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='100000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"
    +

    Next, confirm the undelegation.

    +

    Verifying the Undelegation

    +

    To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed.

    +

    Here is how you can check the status of the auction to confirm that your bid was withdrawn:

    +
    casper-client get-auction-info \
    --node-address http://<peer-ip-address>:7777
    +

    Request fields:

    +
      +
    • node-address - An IP address of a node on the network
    • +
    +

    If the public key and the amount are absent from the bids structure, we can safely conclude that we have indeed undelegated from the validator.

    +

    If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:

    +
      +
    1. Testnet explorer
    2. +
    3. Mainnet explorer
    4. +
    +

    Important Note: After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator.

    + + \ No newline at end of file diff --git a/2.0.0/developers/cli/verifying-contracts/index.html b/2.0.0/developers/cli/verifying-contracts/index.html new file mode 100644 index 000000000..c92eaf016 --- /dev/null +++ b/2.0.0/developers/cli/verifying-contracts/index.html @@ -0,0 +1,46 @@ + + + + + +Verifying Contracts | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Verifying Smart Contracts

    +

    This document describes actions needed for smart contract verification using the Casper CLI client.

    +

    Prerequisites

    +
      +
    • You have built and installed a contract
    • +
    +

    Verifying contracts using the Casper Client

    +

    You can use the Casper client's verify-contract command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success.

    +
    casper-client verify-contract --verification-url-basepath <HOST:PORT> <TRANSACTION-HASH> <PATH>
    +
      +
    1. verification-url-basepath - The address of the verification service that will perform the operation; the current two options are https://staging.codeverifier.casper.network for Testnet and https://codeverifier.casper.network for Mainnet.
    2. +
    3. <TRANSACTION-HASH> - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success.
    4. +
    5. <PATH> - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used.
    6. +
    +

    The prerequisites for the source code are the same as when installing it on the blockchain:

    +
      +
    • +

      The source code must be a Rust project as described in The Cargo Book.

      +
    • +
    • +

      There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book.

      +
    • +
    • +

      The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.

      +
    • +
    +

    If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on https://staging.casperecosystem.io/check-verification-status/ for Testnet transactions and https://casperecosystem.io/check-verification-status/ for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust.

    + + \ No newline at end of file diff --git a/2.0.0/developers/dapps/dapp/index.html b/2.0.0/developers/dapps/dapp/index.html new file mode 100644 index 000000000..76e3f0d21 --- /dev/null +++ b/2.0.0/developers/dapps/dapp/index.html @@ -0,0 +1,33 @@ + + + + + +What is a dApp? | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    What is a dApp?

    +

    A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.

    +

    The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself.

    +

    How are Decentralized Applications Different?

    +

    A decentralized system consists of a group of interchangeable machines that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    +

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    +

    Routine operations in a decentralized network may result in nodes coming on or offline. This node churn can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node.

    +

    Interacting with a Decentralized Network

    +

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    +

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later.

    +

    Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    +

    All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    +

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    +

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    + + \ No newline at end of file diff --git a/2.0.0/developers/dapps/index.html b/2.0.0/developers/dapps/index.html new file mode 100644 index 000000000..63b2d88aa --- /dev/null +++ b/2.0.0/developers/dapps/index.html @@ -0,0 +1,67 @@ + + + + + +Overview of Casper dApps | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Overview of Casper dApps

    +

    The following topics are essential for developers building decentralized applications on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Introducing dAppsIntroducing dApps on a Casper network
    Prerequisites for Building dAppsRecommended setup for building dApps on Casper
    SDK Client LibrariesClient-side libraries providing ways to interact with a Casper network
    dApp Technology StackBuilding the front-end, backend, and on-chain logic of a dApp
    Front-end Template with ReactUse the Casper JS SDK with React to build a dApp frontend
    Signing TransactionsDetails about the signatures required for transactions
    Setting up a Local Network with NCTLLearn to set up a local test network
    Testing Smart Contracts with NCTLTest transactions locally before sending them to a Casper network
    Monitoring and Consuming EventsHow dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data
    + + \ No newline at end of file diff --git a/next/developers/dapps/monitor-and-consume-events/index.html b/2.0.0/developers/dapps/monitor-and-consume-events/index.html similarity index 68% rename from next/developers/dapps/monitor-and-consume-events/index.html rename to 2.0.0/developers/dapps/monitor-and-consume-events/index.html index 3ba6f977f..42b1dcca5 100644 --- a/next/developers/dapps/monitor-and-consume-events/index.html +++ b/2.0.0/developers/dapps/monitor-and-consume-events/index.html @@ -1,24 +1,24 @@ - + -Monitoring Events with the Casper Sidecar | Casper Docs - Redux +Monitoring Events with the Casper Sidecar | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    + submit an issue on Github
    Version: 2.0.0

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Monitoring and Consuming Events

    -

    The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.

    -

    Smart contracts can also emit contract-level events, as explained here. DApps can consume these events by listening to the event stream, detecting TransactionProcessed events, and parsing the messages array storing String-representations of the emitted events.

    +

    The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.

    +

    Smart contracts can also emit contract-level events, as explained here. DApps can consume these events by listening to the event stream, detecting TransactionProcessed events, and parsing the messages array storing String-representations of the emitted events.

    The Casper Sidecar

    The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar supports the following functionalities:

      @@ -68,7 +68,7 @@

      Detecting Contract-Level Events

      -

      The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the TransactionProcessed event after the corresponding block is processed and added to the blockchain. For more details, see Verifying a Topic and Verifying a Message.

      +

      The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the TransactionProcessed event after the corresponding block is processed and added to the blockchain. For more details, see Verifying a Topic and Verifying a Message.

      Reacting to Events

      An application may parse each event needed for its use case and respond accordingly. Each event type contains additional data that might help decide whether to take action. For example, TransactionAccepted events contain the account's public key that submitted the transaction, the contract address, and more. This information can help determine how to proceed.

      @@ -115,6 +115,6 @@

      The REST APISidecar components and architecture diagram 1

      Sidecar components and architecture diagram 2

      Troubleshooting Tips

      -

      For troubleshooting tips, visit Github.

    +

    For troubleshooting tips, visit Github.

    \ No newline at end of file diff --git a/next/developers/dapps/nctl-test/index.html b/2.0.0/developers/dapps/nctl-test/index.html similarity index 61% rename from next/developers/dapps/nctl-test/index.html rename to 2.0.0/developers/dapps/nctl-test/index.html index 34b33b8ac..a34162f59 100644 --- a/next/developers/dapps/nctl-test/index.html +++ b/2.0.0/developers/dapps/nctl-test/index.html @@ -1,34 +1,34 @@ - + -Local Network Testing | Casper Docs - Redux +Local Network Testing | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Testing Smart Contracts with NCTL

    + submit an issue on Github
    Version: 2.0.0

    Testing Smart Contracts with NCTL

    NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.

    -

    Testing Transactions prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.

    +

    Testing Transactions prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.

    Getting Started with NCTL

    Prior to testing a Transaction through NCTL, you should have the following steps accomplished:

    1. -

      Completed writing a Transaction

      +

      Completed writing a Transaction

    2. -

      Tested the Transaction using the Casper testing framework

      +

      Tested the Transaction using the Casper testing framework

    3. -

      Setup NCTL on your system

      +

      Setup NCTL on your system

    NCTL Verification Prior to Testing

    @@ -50,7 +50,7 @@

    note about gas prices.

    +

    The gas price tolerance in CSPR, which is the maximum amount of gas you are willing to pay for execution. This will appear in our example put-transaction as --gas-price-tolerance 10. NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our note about gas prices.

  • The path to your Transaction that you wish to send to the NCTL network. This will appear in our example put-transaction as --transaction-path <PATH> and will require you to define the path to your specific Transaction Wasm.

    @@ -75,7 +75,7 @@

    $(get_path_to_client) get-transaction efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e -n http://localhost:11101

  • Interacting with the Installed Contract

    -

    Once your NCTL network executes your Transaction, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the PackageHash itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to send the Transaction, we can retrieve the PackageHash from the node-1 account information. To do so, we will use the following NCTL command:

    +

    Once your NCTL network executes your Transaction, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the PackageHash itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to send the Transaction, we can retrieve the PackageHash from the node-1 account information. To do so, we will use the following NCTL command:

    nctl-view-faucet-account

    This will return the NCTL faucet account's PublicKey and AccountHash. We can then query the PublicKey using the following command:

    $(get_path_to_client) query-global-state \
    --node-address http://localhost:11101 \
    --key <PUBLIC KEY> \
    --state-root-hash <STATE ROOT HASH>
    @@ -105,7 +105,7 @@

    $(get_path_to_client) put-transaction package \
    --node-address http://localhost:11101 \
    --chain-name "casper-net-1" \
    --package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4 \
    --gas-price-tolerance 10 \
    --pricing-mode fixed \
    --session-arg "amount:u256='100'"

    Verifying Correct Contract Behavior

    -

    After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the basic counter contract tutorial, the NCTL process would have the following flow:

    +

    After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the basic counter contract tutorial, the NCTL process would have the following flow:

    1. Send a Transaction to install the "Counter" smart contract.

      @@ -119,6 +119,6 @@

    +
    \ No newline at end of file diff --git a/2.0.0/developers/dapps/prerequisites/index.html b/2.0.0/developers/dapps/prerequisites/index.html new file mode 100644 index 000000000..a2cb1cc8c --- /dev/null +++ b/2.0.0/developers/dapps/prerequisites/index.html @@ -0,0 +1,51 @@ + + + + + +Prerequisites | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Prerequisites

    +

    Before trying your hand at dApp development on a Casper network, there are a few things you should do first:

    +
      +
    1. +

      Set up your development environment.

      +
    2. +
    3. +

      Be sure you understand the language(s) you are developing in.

      +

      Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you.

      +

      The preferred stack for building on Casper is JavaScript using the Casper JS SDK, however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the Introduction to SDKs.

      +
    4. +
    5. +

      Familiarize yourself with the fundamentals of Casper networks.

      +

      Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the design section.

      +
    6. +
    7. +

      Read the documentation or source code of your chosen SDK.

      +

      Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see Client Library Usage.

      +
    8. +
    +

    Development Considerations

    +

    When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value.

    +

    To ensure the highest level of security, consider the following practices:

    +
      +
    1. Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code.
    2. +
    3. Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors.
    4. +
    5. Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet.
    6. +
    7. Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes.
    8. +
    9. Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities.
    10. +
    11. Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively.
    12. +
    +

    By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network.

    + + \ No newline at end of file diff --git a/next/developers/dapps/sdk/client-library-usage/index.html b/2.0.0/developers/dapps/sdk/client-library-usage/index.html similarity index 92% rename from next/developers/dapps/sdk/client-library-usage/index.html rename to 2.0.0/developers/dapps/sdk/client-library-usage/index.html index 7ef2fa528..52c584182 100644 --- a/next/developers/dapps/sdk/client-library-usage/index.html +++ b/2.0.0/developers/dapps/sdk/client-library-usage/index.html @@ -1,21 +1,21 @@ - + -SDK Client Library Usage | Casper Docs - Redux +SDK Client Library Usage | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    SDK Client Library Usage

    Installing the SDKs

    @@ -42,7 +42,7 @@

    Installi

    Creating Accounts

    -

    You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the Accounts and Cryptographic Keys page for more details.

    +

    You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the Accounts and Cryptographic Keys page for more details.

    Creating new account keys

    @@ -167,6 +167,6 @@

    Staking
    import pycspr

    validator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(
    bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")
    )

    deploy_params = pycspr.create_deploy_parameters(
    account = keypair, # Only the public key is used, see `create_deploy_parameters`
    chain_name = "casper" # or "casper-test" for testnet
    )

    deploy = pycspr.create_validator_delegation(
    params = deploy_params,
    amount = int(500e9), # Minimum delegation amount: 500 CSPR
    public_key_of_delegator = keypair,
    public_key_of_validator = validator_public_key,
    path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"
    )

    deploy.approve(keypair)
    client.send_deploy(deploy)
    print(deploy.hash.hex())

    -

    Once submitted, the above snippet will print the deploy hash in the console.

    +

    Once submitted, the above snippet will print the deploy hash in the console.

    \ No newline at end of file diff --git a/2.0.0/developers/dapps/sdk/csharp-sdk/index.html b/2.0.0/developers/dapps/sdk/csharp-sdk/index.html new file mode 100644 index 000000000..fd97732de --- /dev/null +++ b/2.0.0/developers/dapps/sdk/csharp-sdk/index.html @@ -0,0 +1,39 @@ + + + + + +.NET SDK | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    .NET SDK

    +

    The C# .NET SDK allows developers to interact with a Casper network using C#.

    +

    Documentation

    +

    Visit https://make-software.github.io/casper-net-sdk/ to find the SDK documentation, examples, and tutorials.

    +

    Get started

    +

    This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing.

    +

    Open a terminal window and create a new console app:

    +
    dotnet new console -o GetAccountBalance
    cd GetAccountBalance
    +

    The Casper.Network.SDK for .NET is published on nuget.org as a NuGet package.

    +

    To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the dotnet CLI tool.

    +

    Package Manager (Windows)

    +
    Install-Package Casper.Network.SDK
    +

    dotnet CLI Tool (Windows, Mac, and Linux)

    +
    dotnet add package Casper.Network.SDK
    +

    Now, replace the default code in Program.cs with this main program:

    +
    using System;
    using System.Threading.Tasks;
    using Casper.Network.SDK;
    using Casper.Network.SDK.JsonRpc;
    using Casper.Network.SDK.Types;

    namespace Casper.NET.SDK.Examples
    {
    public class GetAccountBalance
    {
    public static async Task Main(string[] args)
    {
    string nodeAddress = "http://testnet-node.make.services:7777";

    var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";
    var publicKey = PublicKey.FromHexString(hex);

    try
    {
    var casperSdk = new NetCasperClient(nodeAddress);

    // Get the balance using the account public key
    //
    var rpcResponse = await casperSdk.GetAccountBalance(publicKey);
    Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);
    }
    catch (RpcClientException e)
    {
    Console.WriteLine("ERROR:\n" + e.RpcError.Message);
    }
    catch (Exception e)
    {
    Console.WriteLine(e);
    }
    }
    }
    }
    +

    Finally, run the example with:

    +
    dotnet run
    +

    The program will print the account's main purse balance retrieved from the testnet.

    +

    Visit https://make-software.github.io/casper-net-sdk/ to find other examples, tutorials, and complete documentation for this SDK.

    + + \ No newline at end of file diff --git a/next/developers/dapps/sdk/go-sdk/index.html b/2.0.0/developers/dapps/sdk/go-sdk/index.html similarity index 72% rename from next/developers/dapps/sdk/go-sdk/index.html rename to 2.0.0/developers/dapps/sdk/go-sdk/index.html index 0a0ec9cb8..21f6aad54 100644 --- a/next/developers/dapps/sdk/go-sdk/index.html +++ b/2.0.0/developers/dapps/sdk/go-sdk/index.html @@ -1,21 +1,21 @@ - + -Go SDK | Casper Docs - Redux +Go SDK | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Go SDK

    Usage Examples

    This section includes some examples of how to use Go SDK:

      @@ -28,6 +28,6 @@

      Handle the Deploy Processed Event

      package main

      import (
      "context"
      "log"

      "github.com/make-software/casper-go-sdk/sse"
      )

      func main() {
      client := sse.NewClient("https://<Node Address and Port>/events")
      defer client.Stop()
      client.RegisterHandler(
      sse.DeployProcessedEventType,
      func(ctx context.Context, rawEvent sse.RawEvent) error {
      deploy, err := rawEvent.ParseAsDeployProcessedEvent()
      if err != nil {
      return err
      }
      log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)
      return nil
      })
      lastEventID := 1234
      client.Start(context.TODO(), lastEventID)
      }

      Sending a Transfer

      -
      package main

      import (
      "context"
      "encoding/hex"
      "log"
      "math/big"
      "net/http"

      "github.com/make-software/casper-go-sdk/casper"
      "github.com/make-software/casper-go-sdk/types/clvalue"
      )

      func main() {
      accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")
      if err != nil { return }
      amount := big.NewInt(100000000)
      session := casper.ExecutableDeployItem{
      ModuleBytes: &casper.ModuleBytes{
      ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),
      Args: (&casper.Args{}).
      AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).
      AddArgument("amount", *clvalue.NewCLUInt512(amount)),
      },
      }

      payment := casper.StandardPayment(amount)

      deployHeader := casper.DefaultHeader()
      deployHeader.Account = accountPublicKey
      deployHeader.ChainName = "casper-test"

      newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)

      handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)
      client := casper.NewRPCClient(handler)
      result, err := client.PutDeploy(context.Background(), *newDeploy)

      log.Println(result.DeployHash)
      }
    +
    package main

    import (
    "context"
    "encoding/hex"
    "log"
    "math/big"
    "net/http"

    "github.com/make-software/casper-go-sdk/casper"
    "github.com/make-software/casper-go-sdk/types/clvalue"
    )

    func main() {
    accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")
    if err != nil { return }
    amount := big.NewInt(100000000)
    session := casper.ExecutableDeployItem{
    ModuleBytes: &casper.ModuleBytes{
    ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),
    Args: (&casper.Args{}).
    AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).
    AddArgument("amount", *clvalue.NewCLUInt512(amount)),
    },
    }

    payment := casper.StandardPayment(amount)

    deployHeader := casper.DefaultHeader()
    deployHeader.Account = accountPublicKey
    deployHeader.ChainName = "casper-test"

    newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)

    handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)
    client := casper.NewRPCClient(handler)
    result, err := client.PutDeploy(context.Background(), *newDeploy)

    log.Println(result.DeployHash)
    }
    \ No newline at end of file diff --git a/next/developers/dapps/sdk/python-sdk/index.html b/2.0.0/developers/dapps/sdk/python-sdk/index.html similarity index 81% rename from next/developers/dapps/sdk/python-sdk/index.html rename to 2.0.0/developers/dapps/sdk/python-sdk/index.html index a02d20bc7..1e4471a09 100644 --- a/next/developers/dapps/sdk/python-sdk/index.html +++ b/2.0.0/developers/dapps/sdk/python-sdk/index.html @@ -1,21 +1,21 @@ - + -Python SDK | Casper Docs - Redux +Python SDK | Casper Docs - Redux - - + +
    Skip to main content
    Version: 2.0.0

    Python SDK

    The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.

    Installation

    To install the library, run:

    @@ -35,6 +35,6 @@

    Sending a
        import os
    import pathlib
    import random
    import typing

    import pycspr
    from pycspr.client import NodeClient
    from pycspr.client import NodeConnectionInfo
    from pycspr.crypto import KeyAlgorithm
    from pycspr.types import PrivateKey
    from pycspr.types import Deploy
    from pycspr.types import PublicKey

    # path to cp1 secret key - defaults to NCTL user 1.
    path_to_cp1_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"

    # type of cp1 secret key - defaults to ED25519.
    type_of_cp1_secret_key = KeyAlgorithm.ED25519.name,

    # path to cp2 account key - defaults to NCTL user 2.
    path_to_cp2_account_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-2" / "public_key_hex"

    # name of target chain - defaults to NCTL chain.
    chain_name = "casper-net-1"

    # host address of target node - defaults to NCTL node 1.
    node_host = "localhost"

    # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.
    node_port_rpc = 11101

    def _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key, chain_name):
    """Main entry point.
    :param args: Parsed command line arguments.
    """
    # Set node client.
    client = _get_client(node_host, node_port_rpc)

    # Set counter-parties.
    cp1, cp2 = _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key)

    # Set deploy.
    deploy: Deploy = _get_deploy(chain_name, cp1, cp2)

    # Approve deploy.
    deploy.approve(cp1)

    # Dispatch deploy to a node.
    client.deploys.send(deploy)

    #If deploy is successful send the indication
    print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")


    def _get_client(node_host, node_port_rpc) -> NodeClient:
    """Returns a pycspr client instance.
    """
    return NodeClient(NodeConnectionInfo(
    host=node_host,
    port_rpc=node_port_rpc,
    ))


    def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:
    """Returns the 2 counter-parties participating in the transfer.
    """
    cp1 = pycspr.parse_private_key(
    path_to_cp1_secret_key,
    type_of_cp1_secret_key,
    )
    cp2 = pycspr.parse_public_key(
    path_to_cp2_account_key
    )

    return cp1, cp2


    def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:
    """Returns transfer deploy to be dispatched to a node.
    """
    # Set standard deploy parameters.
    deploy_params = pycspr.create_deploy_parameters(
    account = cp1,
    chain_name = chain_name
    )

    # Set deploy.
    deploy = pycspr.create_native_transfer(
    params = deploy_params,
    amount = int(2.5e9),
    target = cp2.account_hash,
    correlation_id = random.randint(1, 1e6)
    )

    return deploy


    # Entry point.
    if __name__ == '__main__':
    _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)

    Staking

    This example shows you how to define and stake funds with a validator.

    -

    import os
    import pathlib

    import pycspr
    from pycspr.client import NodeClient
    from pycspr.client import NodeConnectionInfo
    from pycspr.crypto import KeyAlgorithm
    from pycspr.types import Deploy
    from pycspr.types import PrivateKey

    # path to cp1 secret key - defaults to NCTL user 1.
    path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"

    # type of cp1 secret key - defaults to ED25519.
    type_of_validator_secret_key = KeyAlgorithm.ED25519.name

    # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.
    path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"

    # amount to stake, i.e. bond, into the network.
    amount = int(2.5e9)

    # amount to charge delegators for service provision.
    delegation_rate = 2

    # name of target chain - defaults to NCTL chain.
    chain_name = "casper-net-1"

    # host address of target node - defaults to NCTL node 1.
    node_host = "localhost"

    # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.
    node_port_rpc = 11101

    def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):
    """Main entry point.
    :param args: Parsed command line arguments.
    """
    # Set node client.
    client: NodeClient = _get_client(node_host, node_port_rpc)

    # Set validator key.
    validator: PrivateKey = pycspr.parse_private_key(
    path_to_validator_secret_key,
    type_of_validator_secret_key,
    )

    # Set deploy.
    deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)

    # Approve deploy.
    deploy.approve(validator)

    # Dispatch deploy to a node.
    client.deploys.send(deploy)

    print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")


    def _get_client(node_host, node_port_rpc) -> NodeClient:
    """Returns a pycspr client instance.
    """
    return NodeClient(NodeConnectionInfo(
    host = node_host,
    port_rpc = node_port_rpc,
    ))


    def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:
    """Returns delegation deploy to be dispatched to a node.
    """
    # Set standard deploy parameters.
    deploy_params = pycspr.create_deploy_parameters(
    account = validator,
    chain_name = chain_name
    )

    # Set deploy.
    deploy = pycspr.create_validator_auction_bid(
    params = deploy_params,
    amount = amount,
    delegation_rate = delegation_rate,
    public_key = validator.as_public_key(),
    path_to_wasm = path_to_wasm
    )

    return deploy


    # Entry point.
    if __name__ == '__main__':
    _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)
    +

    import os
    import pathlib

    import pycspr
    from pycspr.client import NodeClient
    from pycspr.client import NodeConnectionInfo
    from pycspr.crypto import KeyAlgorithm
    from pycspr.types import Deploy
    from pycspr.types import PrivateKey

    # path to cp1 secret key - defaults to NCTL user 1.
    path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"

    # type of cp1 secret key - defaults to ED25519.
    type_of_validator_secret_key = KeyAlgorithm.ED25519.name

    # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.
    path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"

    # amount to stake, i.e. bond, into the network.
    amount = int(2.5e9)

    # amount to charge delegators for service provision.
    delegation_rate = 2

    # name of target chain - defaults to NCTL chain.
    chain_name = "casper-net-1"

    # host address of target node - defaults to NCTL node 1.
    node_host = "localhost"

    # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.
    node_port_rpc = 11101

    def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):
    """Main entry point.
    :param args: Parsed command line arguments.
    """
    # Set node client.
    client: NodeClient = _get_client(node_host, node_port_rpc)

    # Set validator key.
    validator: PrivateKey = pycspr.parse_private_key(
    path_to_validator_secret_key,
    type_of_validator_secret_key,
    )

    # Set deploy.
    deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)

    # Approve deploy.
    deploy.approve(validator)

    # Dispatch deploy to a node.
    client.deploys.send(deploy)

    print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")


    def _get_client(node_host, node_port_rpc) -> NodeClient:
    """Returns a pycspr client instance.
    """
    return NodeClient(NodeConnectionInfo(
    host = node_host,
    port_rpc = node_port_rpc,
    ))


    def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:
    """Returns delegation deploy to be dispatched to a node.
    """
    # Set standard deploy parameters.
    deploy_params = pycspr.create_deploy_parameters(
    account = validator,
    chain_name = chain_name
    )

    # Set deploy.
    deploy = pycspr.create_validator_auction_bid(
    params = deploy_params,
    amount = amount,
    delegation_rate = delegation_rate,
    public_key = validator.as_public_key(),
    path_to_wasm = path_to_wasm
    )

    return deploy


    # Entry point.
    if __name__ == '__main__':
    _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)
    \ No newline at end of file diff --git a/2.0.0/developers/dapps/sdk/script-sdk/index.html b/2.0.0/developers/dapps/sdk/script-sdk/index.html new file mode 100644 index 000000000..d6b21c944 --- /dev/null +++ b/2.0.0/developers/dapps/sdk/script-sdk/index.html @@ -0,0 +1,57 @@ + + + + + +JavaScript/TypeScript SDK | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    JavaScript/TypeScript SDK

    +

    This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.

    +

    Usage of JavaScript Clients

    +

    The Casper team has implemented specific JS clients to support interaction with the Casper contracts.

    +

    Repository & Client Packages

    +

    We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:

    + +

    These packages give you an easy way to install and interact with the corresponding Casper contract.

    +

    Casper SDK for JavaScript

    +

    The TypeScript/JavaScript SDK allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK.

    +

    Installation

    +

    To install this library using Node.js, run the following command:

    +
    npm install casper-js-sdk@next --save
    +

    Tests

    +

    You can find basic examples for how to use this library in the test directory. To run the tests, use this command:

    +
    npm run test
    +

    Usage Examples

    +

    In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:

    +
      +
    • Generating account keys
    • +
    • Sending a transfer
    • +
    +

    Generating Account Keys

    +

    This example shows you how to use the SDK to generate account keys to sign your deploy.

    +
    const fs = require("fs");
    const path = require("path");
    const { Keys } = require("casper-js-sdk");

    const createAccountKeys = () => {
    // Generating keys
    const edKeyPair = Keys.Ed25519.new();
    const { publicKey, privateKey } = edKeyPair;

    // Create a hexadecimal representation of the public key
    const accountAddress = publicKey.toHex();

    // Get the account hash (Uint8Array) from the public key
    const accountHash = publicKey.toAccountHash();

    // Store keys as PEM files
    const publicKeyInPem = edKeyPair.exportPublicKeyInPem();
    const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();

    const folder = path.join("./", "casper_keys");

    if (!fs.existsSync(folder)) {
    const tempDir = fs.mkdirSync(folder);
    }

    fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);
    fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);

    return accountAddress;
    };

    const newAccountAddress = createAccountKeys();
    +

    After generating the keys with this code, you can add them to the Casper Wallet Chrome extension and use them to sign your transactions.

    +

    Sending a Transfer

    +

    This code block shows you how to define and send a transfer on a Casper network. Replace the sender-public-key and recipient-public-key in the code below.

    +

    The sendTransfer function below will return a transfer-hash which you can check on https://testnet.cspr.live/.

    +
    const fs = require("fs");
    const path = require("path");
    const axios = require("axios");
    const casperClientSDK = require("casper-js-sdk");

    const { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");

    const RPC_API = "http://159.65.203.12:7777/rpc";
    const STATUS_API = "http://159.65.203.12:8888";

    const sendTransfer = async ({ from, to, amount }) => {
    const casperClient = new CasperClient(RPC_API);

    const folder = path.join("./", "casper_keys");

    // Read keys from the structure created in #Generating keys
    const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");

    // networkName can be taken from the status api
    const response = await axios.get(STATUS_API + "/status");

    let networkName = null;

    if (response.status == 200) {
    networkName = response.data.chainspec_name;
    }

    // For native-transfers the payment price is fixed
    const paymentAmount = 100000000;

    // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage
    const id = 187821;

    // gasPrice for native transfers can be set to 1
    const gasPrice = 1;

    // Time that the deploy will remain valid for, in milliseconds
    // The default value is 1800000 ms (30 minutes)
    const ttl = 1800000;

    let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);

    // We create a hex representation of the public key with an added prefix
    const toPublicKey = CLPublicKey.fromHex(to);

    const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);

    const payment = DeployUtil.standardPayment(paymentAmount);
    const deploy = DeployUtil.makeDeploy(deployParams, session, payment);
    const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);

    // Here we are sending the signed deploy
    return await casperClient.putDeploy(signedDeploy);
    };

    sendTransfer({
    // Put here the public key of the sender's main purse. Note that it needs to have a balance greater than 2.5 CSPR
    from: "<sender-public-key>",

    // Put here the public key of the recipient's main purse. This account doesn't need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent
    to: "<recipient-public-key>",

    // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)
    amount: 25000000000,
    });
    +

    Note: At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.).

    +

    Here is the code you can use to serialize the deploy:

    +
    const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);
    +

    Then, you can reconstruct the deploy object using this function:

    +
    const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);
    + + \ No newline at end of file diff --git a/next/developers/dapps/setup-nctl/index.html b/2.0.0/developers/dapps/setup-nctl/index.html similarity index 71% rename from next/developers/dapps/setup-nctl/index.html rename to 2.0.0/developers/dapps/setup-nctl/index.html index a1a00bad6..6f2de7388 100644 --- a/next/developers/dapps/setup-nctl/index.html +++ b/2.0.0/developers/dapps/setup-nctl/index.html @@ -1,25 +1,25 @@ - + -Local Network Setup | Casper Docs - Redux +Local Network Setup | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Setting up a Local Network with NCTL

    + submit an issue on Github
    Version: 2.0.0

    Setting up a Local Network with NCTL

    NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.

    Prerequisites

      -
    1. You have completed the Getting Started section, which shows you how to install your development environment, including tools like CMake (version 3.1.4+), Cargo, and Rust.
    2. +
    3. You have completed the Getting Started section, which shows you how to install your development environment, including tools like CMake (version 3.1.4+), Cargo, and Rust.
    4. Make sure you have Python 3 installed if your operating system does not include Python.
    5. To run NCTL, you will also need the bash shell.
    @@ -108,6 +108,6 @@

    Next Steps
  • Explore the various NCTL commands.
  • Explore the NCTL usage guide.
  • -

    +
    \ No newline at end of file diff --git a/2.0.0/developers/dapps/signing-a-transaction/index.html b/2.0.0/developers/dapps/signing-a-transaction/index.html new file mode 100644 index 000000000..d84c4b784 --- /dev/null +++ b/2.0.0/developers/dapps/signing-a-transaction/index.html @@ -0,0 +1,35 @@ + + + + + +Signing Transactions | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Signing Transactions

    +

    When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.

    +

    When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an Approval. Every valid transaction has at least one approval.

    +

    The signature creation process begins with the hashing of the payment and session of the transaction to create the BodyHash. The BodyHash becomes a component of the TransactionV1Header as outlined in the serialization standard. From there, the TransactionV1Header can be hashed to create the TransactionV1Hash. As outlined above, the TransactionV1Hash is then combined with the account's key-pair to create the transaction's signature.

    +

    As the TransactionV1Hash contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the TransactionV1Hash invalid.

    +

    Public Key Cryptography

    +

    Casper networks are compatible with both Ed25519 and Secp256k1 public key cryptography. When serialized, public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with 1, whereas Secp256k1 are prefixed with 2.

    +

    Casper uses blake2b hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:

    +
      +
    • +

      Ed25519 signs over a SHA-512 digest.

      +
    • +
    • +

      Secp256k1 signs over a SHA-256 digest.

      +
    • +
    + + \ No newline at end of file diff --git a/2.0.0/developers/dapps/speculative-exec/index.html b/2.0.0/developers/dapps/speculative-exec/index.html new file mode 100644 index 000000000..4ab18d76e --- /dev/null +++ b/2.0.0/developers/dapps/speculative-exec/index.html @@ -0,0 +1,28 @@ + + + + + +Estimating Gas Costs with Speculative Execution | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Estimating Gas Costs with Speculative Execution

    +

    Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculative_exec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.

    +

    In addition to the Deploy in question, speculative_exec also accepts a [block_identifier] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block.

    +

    Sending a Speculative Execution Deploy using the Rust CLI Casper Client

    +

    The Rust CLI Casper client includes a speculative-exec option that will flag a normal put-deploy for execution but not commitment to global state. The following command shows an example:

    +

    casper client put-deploy /
    --node-address <HOST:PORT> /
    --chain-name <CHAIN_NAME> /
    --secret-key <PATH> /
    --session-path <PATH> /
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES>
    --speculative-exec <BLOCK HEIGHT OR HASH>

    +

    You should receive execution_results that show a cost.

    +

    {
    "jsonrpc": "2.0",
    "id": -4571113357017152230,
    "result": {
    "api_version": "1.0.0",
    "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",
    "execution_result": {
    "Success": {
    "effect": {
    <Deploy effects removed for conciseness.>
    },
    "transfers": [],
    "cost": "87300473670"
    }
    }
    }
    }

    +
    note

    Cost estimates acquired through speculative_exec may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.

    + + \ No newline at end of file diff --git a/2.0.0/developers/dapps/technology-stack/index.html b/2.0.0/developers/dapps/technology-stack/index.html new file mode 100644 index 000000000..8cd833713 --- /dev/null +++ b/2.0.0/developers/dapps/technology-stack/index.html @@ -0,0 +1,60 @@ + + + + + +dApp Technology Stack | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem';

    +

    dApp Technology Stack

    +

    There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.

    +

    Front-End

    +

    The front-end, or client-side of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried.

    +

    You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill CORS requirements.

    +

    Signing Transactions

    +

    The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:

    +
      +
    1. +

      The Casper Wallet

      +

      Use the Casper Wallet to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node.

      +
      caution

      The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

      +
    2. +
    3. +

      Third-party signers

      +

      Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object.

      +
    4. +
    +

    Querying Global State

    +

    To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query.

    +

    Backend

    +

    The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect CORS headers from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain.

    +

    As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to.

    + + +
    const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");
    +
    + +
    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    +
    +
    +
    tip

    You can find online peers for Mainnet at cspr.live or testnet at testnet.cspr.live

    +

    There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end.

    +

    Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end.

    +

    In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along.

    +

    Blockchain

    +

    The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open transactional, informational, and Proof-of-Stake endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods.

    +

    More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as WebAssembly binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in Rust for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust.

    +

    To learn how to write smart contracts for your dApp, read the smart contract documentation.

    + + \ No newline at end of file diff --git a/next/developers/dapps/template-frontend/index.html b/2.0.0/developers/dapps/template-frontend/index.html similarity index 90% rename from next/developers/dapps/template-frontend/index.html rename to 2.0.0/developers/dapps/template-frontend/index.html index 2426a1824..9fcd116e0 100644 --- a/next/developers/dapps/template-frontend/index.html +++ b/2.0.0/developers/dapps/template-frontend/index.html @@ -1,21 +1,21 @@ - + -Front-end in React | Casper Docs - Redux +Front-end in React | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    + submit an issue on Github
    Version: 2.0.0

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Front-end Template with React

    For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.

    This guide will walk you through setting up and developing a React application with Vite that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by reading the React documentation.

    @@ -72,7 +72,7 @@

    Call a

    Now that this component is created, render it to the user interface in src/App.jsx, passing along the publicKey as a prop:

    import React from "react";
    import Connect from "./Connect";
    // highlight-next-line-green
    import UpdateMessage from "./UpdateMessage";
    import './App.css'

    function App() {
    const [publicKey, setPublicKey] = React.useState(null);
    return (
    <>
    <Connect setPublicKey={ setPublicKey } />
    <div>
    {publicKey !== null && (<>
    Wallet connected: {publicKey}<br/>
    // highlight-next-line-green
    <UpdateMessage publicKey={ publicKey } />
    </>)}
    </div>
    </>
    );
    }

    Query a Smart Contract

    -

    Consider that the message written to the chain during the update_message entrypoint invocation is stored in the dictionary messages in the contract. Further consider that each account may write its own message and that the messages are stored under the account's account hash as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end.

    +

    Consider that the message written to the chain during the update_message entrypoint invocation is stored in the dictionary messages in the contract. Further consider that each account may write its own message and that the messages are stored under the account's account hash as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end.

    Create a new component:

    touch src/Query.jsx

    Open the file and write:

    @@ -90,6 +90,6 @@

    Build f

    When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:

    vite build

    Once this is complete, you can preview your production build by running:

    -
    vite preview

    +
    vite preview
    \ No newline at end of file diff --git a/next/developers/dapps/uref-security/index.html b/2.0.0/developers/dapps/uref-security/index.html similarity index 56% rename from next/developers/dapps/uref-security/index.html rename to 2.0.0/developers/dapps/uref-security/index.html index 081de0411..4078e3d5b 100644 --- a/next/developers/dapps/uref-security/index.html +++ b/2.0.0/developers/dapps/uref-security/index.html @@ -1,24 +1,24 @@ - + -URef Access Rights | Casper Docs - Redux +URef Access Rights | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    URef Access Rights and Security Considerations

    + submit an issue on Github
    Version: 2.0.0

    URef Access Rights and Security Considerations

    Understanding Access Rights

    An Unforgeable Reference or URef is a key type used for storage on a Casper network. They can store any value other than Account and exist as a top-level entity. As such, no individual entity may own a URef, they can only hold the necessary AccessRights to interact with a given URef.

    -

    AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

    +

    AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000

    And this is the same URef with READ and ADD access rights.

    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005
    @@ -95,6 +95,6 @@

    dApp that interacts with tokens in any way, it will be necessary to work with various URef AccessRights for associated purse URefs.

    This tutorial outlines our recommendations when transferring tokens to a contract.

    When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate AccessRights. The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the new_uref should be passed to another entity.

    -
    // This example will create a version of the original URef with access rights stripped entirely.
    let new_uref = uref.with_access_rights(AccessRights::NONE);
    // This example will create a version of the original URef with only READ access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ);
    // This example will create a version of the original URef with only WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::WRITE);
    // This example will create a version of the original URef with both READ and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
    // This example will create a version of the original URef with only ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD);
    // This example will create a version of the original URef with both READ and ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
    // This example will create a version of the original URef with both ADD and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
    // This example will create a version of the original URef with full access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);

    +
    // This example will create a version of the original URef with access rights stripped entirely.
    let new_uref = uref.with_access_rights(AccessRights::NONE);
    // This example will create a version of the original URef with only READ access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ);
    // This example will create a version of the original URef with only WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::WRITE);
    // This example will create a version of the original URef with both READ and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
    // This example will create a version of the original URef with only ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD);
    // This example will create a version of the original URef with both READ and ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
    // This example will create a version of the original URef with both ADD and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
    // This example will create a version of the original URef with full access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);
    \ No newline at end of file diff --git a/2.0.0/developers/essential-crates/index.html b/2.0.0/developers/essential-crates/index.html new file mode 100644 index 000000000..7b17ccd4f --- /dev/null +++ b/2.0.0/developers/essential-crates/index.html @@ -0,0 +1,77 @@ + + + + + +Essential Rust Crates | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Essential Rust Crates

    +

    Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.

    +

    casper-types

    +

    Types shared by many Casper crates:

    + +

    casper-contract

    +

    A library for developing Casper smart contracts:

    + +

    casper-engine-test-support

    +

    The Casper test support library:

    + +

    casper-node

    +

    The component for running a node on a Casper network:

    + +

    casper-client

    +

    A client library for interacting with a Casper network:

    + +

    casper-event-standard

    +

    A Rust library that provides a simple and standardized way for Casper contracts to emit events:

    + +

    casper-hashing

    +

    A library providing hashing functionality including Merkle Proof utilities:

    + +

    casper-wasm-utils

    +

    Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:

    + +

    cargo-casper

    +

    A command line tool for creating a Wasm smart contract and tests:

    + +

    Other Libraries

    +

    The Open-Source Software page provides other community-curated tools and libraries.

    + + \ No newline at end of file diff --git a/2.0.0/developers/index.html b/2.0.0/developers/index.html new file mode 100644 index 000000000..380c197dd --- /dev/null +++ b/2.0.0/developers/index.html @@ -0,0 +1,57 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Developers Overview

    +

    This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Development PrerequisitesSetup needed for various workflows
    Essential Casper CratesAvailable Casper crates and the corresponding documentation
    Writing On-Chain CodeWriting contracts in Rust and Wasm for a Casper network
    Casper JSON-RPC APIEndpoints for developers wishing to interact directly with a Casper node's JSON-RPC API
    Building dAppsUseful information for dApp developers
    Interacting with the Blockchain Using CLIUsing a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens.
    +

    The Ecosystem Open-Source Software may provide other helpful examples.

    +

    The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together.

    + + \ No newline at end of file diff --git a/2.0.0/developers/json-rpc/errors/index.html b/2.0.0/developers/json-rpc/errors/index.html new file mode 100644 index 000000000..0045479ac --- /dev/null +++ b/2.0.0/developers/json-rpc/errors/index.html @@ -0,0 +1,126 @@ + + + + + +Casper JSON-RPC Error Codes | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Casper JSON-RPC Error Codes

    +

    The following document expands on custom error codes provided by casper-json-rpc crate.

    +

    Error Codes

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    CodeErrorDescription
    -1NoSuchDeployThe requested Deploy was not found.
    -2NoSuchBlockThe requested Block was not found.
    -3FailedToParseQueryKeyParsing the Key from a query failed.
    -4QueryFailedThe query failed to find a result.
    -5QueryFailedToExecuteExecuting the query failed.
    -6FailedToParseGetBalanceURefParsing the URef while getting a balance failed.
    -7FailedToGetBalanceFailed to get the requested balance.
    -8GetBalanceFailedToExecuteExecuting the query to retrieve the balance failed.
    -9InvalidDeployThe given Deploy cannot be executed as it is invalid.
    -10NoSuchAccountThe given account was not found.
    -11FailedToGetDictionaryURefFailed to get the requested dictionary URef.
    -12FailedToGetTrieFailed to get the requested dictionary trie.
    -13NoSuchStateRootThe requested state root hash was not found.
    -32600InvalidRequestThe JSON sent is not a valid Request object.
    -32601MethodNotFoundThe method does not exist or is not available.
    -32602InvalidParamsInvalid method parameter(s)
    -32603InternalErrorInternal JSON-RPC error.
    -32700ParseErrorInvalid JSON was received by the server.
    +

    Invalid Params

    +

    The casper-json-rpc no longer ignores invalid params fields. Params fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent.

    +

    Failing to adhere to this will result in an InvalidParams error.

    + + \ No newline at end of file diff --git a/2.0.0/developers/json-rpc/guidance/index.html b/2.0.0/developers/json-rpc/guidance/index.html new file mode 100644 index 000000000..08edab267 --- /dev/null +++ b/2.0.0/developers/json-rpc/guidance/index.html @@ -0,0 +1,29 @@ + + + + + +Guidance for JSON-RPC SDK Compliance | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Guidance for JSON-RPC SDK Compliance

    +

    A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.

    +

    A Casper JSON-RPC SDK claiming to be complete is expected to implement all endpoints and all types defined in the serialization standard.

    +

    Consistency

    +

    A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet.

    +

    Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK.

    +

    Advanced Functionality

    +

    SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations.

    +

    However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience.

    +

    For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform.

    + + \ No newline at end of file diff --git a/2.0.0/developers/json-rpc/index.html b/2.0.0/developers/json-rpc/index.html new file mode 100644 index 000000000..c3a39c767 --- /dev/null +++ b/2.0.0/developers/json-rpc/index.html @@ -0,0 +1,65 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Skip to main content
    Version: 2.0.0

    Interacting with the Casper JSON-RPC API

    +

    Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.

    +

    The Casper Sidecar service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the JSON-RPC README in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar.

    +

    You can find the latest RPC schema in the Sidecar's GitHub repository.

    +

    The Casper client subcommand list-rpcs also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:

    +
    casper-client list-rpcs --node-address <HOST:PORT>
    +

    You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.

    +

    Table of Contents

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PageDescription
    Guidance for JSON-RPC SDK ComplianceRequirements for a compliant Casper SDK
    Required JSON-RPC Methods for Minimal ComplianceMethods required for a minimally compliant Casper SDK
    Transactional JSON-RPC MethodMethods allowing interaction with a Casper network
    Informational JSON-RPC MethodsMethods returning information about the network from a Casper node
    Proof-of-Stake JSON-RPC MethodsMethods pertaining to Proof-of-Stake functionality on a Casper network
    TypesInformation on types used within JSON-RPC methods
    CL TypesInformation related to CL Types
    + + \ No newline at end of file diff --git a/next/developers/json-rpc/json-rpc-informational/index.html b/2.0.0/developers/json-rpc/json-rpc-informational/index.html similarity index 85% rename from next/developers/json-rpc/json-rpc-informational/index.html rename to 2.0.0/developers/json-rpc/json-rpc-informational/index.html index b3fb822bf..c5b7af31b 100644 --- a/next/developers/json-rpc/json-rpc-informational/index.html +++ b/2.0.0/developers/json-rpc/json-rpc-informational/index.html @@ -1,25 +1,25 @@ - + -Informational JSON-RPC Methods | Casper Docs - Redux +Informational JSON-RPC Methods | Casper Docs - Redux - - + +
    Skip to main content
    Version: Next

    Informational JSON-RPC Methods

    + submit an issue on Github
    Version: 2.0.0

    Informational JSON-RPC Methods

    The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.


    chain_get_block

    -

    This method returns the JSON representation of a Block from the network. If you do not specify a block_identifier, you will receive the most recent block.

    +

    This method returns the JSON representation of a Block from the network. If you do not specify a block_identifier, you will receive the most recent block.

    @@ -35,7 +35,7 @@

    chain_get_bl -
    ParameterTypeDescription
    block_identifierObjectThe Block hash or the Block height. (Optional)
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash or the Block height. (Optional)
    Example chain_get_block request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    @@ -62,13 +62,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.blockObjectThe Block, if found. (Optional) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    blockObjectThe Block, if found. (Optional)
    Example chain_get_block result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_block_result",
    "value": {
    "api_version": "2.0.0",
    "block_with_signatures": {
    "block": {
    "Version2": {
    "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "header": {
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "body_hash": "48859fb4865d8637d6a35cb224e222cd0e1b1c2dd72928932c1e35ac0550818b",
    "random_bit": true,
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "era_end": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "next_era_validator_weights": [
    {
    "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
    "weight": "123"
    },
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    }
    ],
    "rewards": {},
    "next_era_gas_price": 1
    },
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "protocol_version": "1.0.0",
    "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "current_gas_price": 1,
    "last_switch_block_hash": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a"
    },
    "body": {
    "transactions": {
    "0": [
    {
    "Version1": "1414141414141414141414141414141414141414141414141414141414141414"
    }
    ],
    "1": [
    {
    "Version1": "1515151515151515151515151515151515151515151515151515151515151515"
    }
    ],
    "2": [
    {
    "Version1": "1616161616161616161616161616161616161616161616161616161616161616"
    }
    ],
    "3": [
    {
    "Version1": "1717171717171717171717171717171717171717171717171717171717171717"
    }
    ]
    },
    "rewarded_signatures": []
    }
    }
    },
    "proofs": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "01e18ca03d2ef0238a6a2460a222e0b818406bda99d4c05502c80232013559b926d1c8bca6bf65386f54a847d7850cb76c0c5fd5e633c34c749b8b9958a638d806"
    }
    ]
    }
    }
    }
    }

    chain_get_block_transfers

    -

    This method returns all successful native transfers within a given Block from a network. If you do not specify a block_identifier, you will receive the transfers from the most recent block.

    +

    This method returns all successful native transfers within a given Block from a network. If you do not specify a block_identifier, you will receive the transfers from the most recent block.

    @@ -84,7 +84,7 @@

    ch -
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_block_transfers request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block_transfers",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    @@ -115,13 +115,13 @@

    block_hashObjectThe Block hash, if found. (Optional)transfersArrayThe Block's successful transfers, if found. (Optional) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_hashObjectThe Block hash, if found. (Optional)
    transfersArrayThe Block's successful transfers, if found. (Optional)
    Example chain_get_block_transfers result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_block_transfers_result",
    "value": {
    "api_version": "2.0.0",
    "block_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ]
    }
    }
    }

    chain_get_era_summary

    -

    This method returns the era summary at a given Block. If you do not specify a block_identifier, you will receive the era summary at the highest state root hash.

    +

    This method returns the era summary at a given Block. If you do not specify a block_identifier, you will receive the era summary at the highest state root hash.

    @@ -137,7 +137,7 @@

    chain_ -
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_era_summary request

    {
    "id": 1,
    "jsonrpc":"2.0",
    "method":"chain_get_era_summary",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    @@ -163,13 +163,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.era_summaryObjectThe era summary, if found. (Optional) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary, if found. (Optional)
    Example chain_get_era_summary result

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "chain_get_era_summary_result",
    "value": {
    "api_version": "2.0.0",
    "era_summary": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "era_id": 42,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "1000"
    }
    },
    {
    "Validator": {
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "2000"
    }
    }
    ]
    }
    },
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }
    }

    chain_get_state_root_hash

    -

    This method returns a state root hash at a given Block. If you do not specify a block_identifier, you will receive the highest state root hash.

    +

    This method returns a state root hash at a given Block. If you do not specify a block_identifier, you will receive the highest state root hash.

    @@ -185,7 +185,7 @@

    ch -
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_state_root_hash request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_state_root_hash",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Height": 10
    }
    }
    ]
    }

    @@ -211,7 +211,7 @@

    state_root_hashStringHex-encoded hash of the state root. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    state_root_hashStringHex-encoded hash of the state root.
    Example chain_get_state_root_hash result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_state_root_hash_result",
    "value": {
    "api_version": "2.0.0",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"
    }
    }
    }

    @@ -243,7 +243,7 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.chainspec_bytesObjectThe raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    chainspec_bytesObjectThe raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.
    Example info_get_chainspec result

    Please note that adding a --vv flag will return the full chainspec bytes.

    @@ -251,7 +251,7 @@

    info_get_deploy

    caution

    DEPRECATED: Use info_get_transaction instead.

    -

    This method retrieves a Deploy from a network. It requires a deploy_hash to query the Deploy.

    +

    This method retrieves a Deploy from a network. It requires a deploy_hash to query the Deploy.

    @@ -272,7 +272,7 @@

    info_get_dep -
    ParameterTypeDescription
    deploy_hashStringThe Deploy hash.
    finalized_approvalsBooleanDetermines whether to return the Deploy with the finalized approvals substituted. (Optional)
    +
    ParameterTypeDescription
    deploy_hashStringThe Deploy hash.
    finalized_approvalsBooleanDetermines whether to return the Deploy with the finalized approvals substituted. (Optional)
    Example info_get_deploy request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_deploy",
    "params": [
    {
    "name": "deploy_hash",
    "value": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    },
    {
    "name": "finalized_approvals",
    "value": true
    }
    ]
    }

    @@ -305,7 +305,7 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.deployObjectThe Deploy.execution_infoArrayAn array of execution results with Block hashes, if found. (Optional) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    deployObjectThe Deploy.
    execution_infoArrayAn array of execution results with Block hashes, if found. (Optional)
    Example info_get_deploy result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_deploy_result",
    "value": {
    "api_version": "2.0.0",
    "deploy": {
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "gas_price": 1,
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "chain_name": "casper-example"
    },
    "payment": {
    "StoredContractByName": {
    "name": "casper-example",
    "entry_point": "example-entry-point",
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"
    }
    ]
    },
    "execution_info": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "block_height": 10,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "error_message": null,
    "limit": "123456",
    "consumed": "100000",
    "cost": "246912",
    "payment": [
    {
    "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"
    }
    ],
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ],
    "size_estimate": 186,
    "effects": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Identity"
    }
    ]
    }
    }
    }
    }
    }
    }

    @@ -337,7 +337,7 @@

    info_get_rew -
    ParameterTypeDescription
    validatorStringThe public key of the validator.
    era_identifierObjectThe era identifier. If None, the last finalized era is used. (Optional)
    delegatorStringThe public key of the delegator. If Some, the rewards for the delegator are returned. If None, the rewards for the validator are returned. (Optional)
    +
    ParameterTypeDescription
    validatorStringThe public key of the validator.
    era_identifierObjectThe era identifier. If None, the last finalized era is used. (Optional)
    delegatorStringThe public key of the delegator. If Some, the rewards for the delegator are returned. If None, the rewards for the validator are returned. (Optional)
    Example info_get_reward request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_reward",
    "params": [
    {
    "name": "era_identifier",
    "value": {
    "Era": 1
    }
    },
    {
    "name": "validator",
    "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    {
    "name": "delegator",
    "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    ],
    }

    @@ -368,7 +368,7 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.era_idIntegerThe era for which the reward was calculated.reward_amountIntegerThe total reward amount in the requested era. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_idIntegerThe era for which the reward was calculated.
    reward_amountIntegerThe total reward amount in the requested era.
    Example info_get_reward result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_reward_result",
    "value": {
    "api_version": "2.0.0",
    "reward_amount": "42",
    "era_id": 1
    }
    }

    @@ -395,7 +395,7 @@

    info_ge -
    ParameterTypeDescription
    transaction_hashStringThe transaction hash.
    finalized_approvalsBooleanDetermines whether to return the transaction with the finalized approvals substituted. (Optional)
    +
    ParameterTypeDescription
    transaction_hashStringThe transaction hash.
    finalized_approvalsBooleanDetermines whether to return the transaction with the finalized approvals substituted. (Optional)
    Example info_get_transaction request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_transaction",
    "params": [
    {
    "name": "transaction_hash",
    "value": {
    "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"
    }
    },
    {
    "name": "finalized_approvals",
    "value": true
    }
    ],
    }

    @@ -428,7 +428,7 @@

    -
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    transactionObjectThe transaction.
    execution_infoArrayAn array of execution results with Block hashes, if found. (Optional)
    +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    transactionObjectThe transaction.
    execution_infoArrayAn array of execution results with Block hashes, if found. (Optional)
    Example info_get_transaction result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_transaction_result",
    "value": {
    "api_version": "2.0.0",
    "transaction": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    },
    "execution_info": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "block_height": 10,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "error_message": null,
    "limit": "123456",
    "consumed": "100000",
    "cost": "246912",
    "payment": [
    {
    "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"
    }
    ],
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ],
    "size_estimate": 186,
    "effects": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Identity"
    }
    ]
    }
    }
    }
    }
    }
    }

    @@ -455,7 +455,7 @@

    query_balance< -
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    +
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    Example query_balance request
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    @@ -481,7 +481,7 @@

    q -
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    balanceObjectThe balance represented in motes.
    +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    balanceObjectThe balance represented in motes.
    Example query_balance result

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "name": "query_balance_result",
    "value": {
    "api_version": "2.0.0",
    "balance": "123456"
    }
    }
    }

    @@ -508,7 +508,7 @@

    query_ -
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    +
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    Example query_balance_details request
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance_details",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    @@ -549,13 +549,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.available_balanceObjectThe available balance in motes (total balance - sum of all active holds).holdsArrayThe holds active at the requested point in time.total_balanceObjectThe purses total balance, not considering holds.`total_balance_proofStringA proof that the given value is present in the Merkle trie. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    available_balanceObjectThe available balance in motes (total balance - sum of all active holds).
    holdsArrayThe holds active at the requested point in time.
    total_balanceObjectThe purses total balance, not considering holds.
    `total_balance_proofStringA proof that the given value is present in the Merkle trie.
    Example query_balance_details result

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "name": "query_balance_details_result",
    "value": {
    "api_version": "2.0.0",
    "total_balance": "123456",
    "available_balance": "123456",
    "total_balance_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "holds": [
    {
    "time": 0,
    "amount": "123456",
    "proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    ]
    }
    }
    }

    query_global_state

    -

    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 or state root hash.

    +

    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 or state root hash.

    • Note: Querying a purse's balance requires the use of query_balance, rather than any iteration of query_global_state.
    @@ -584,7 +584,7 @@

    query_glo -
    ParameterTypeDescription
    keyStringThe key as a formatted string, under which data can be stored in global state.
    state_identifierObjectThe identifier used for the query. If not provided, the tip of the chain will be used. (Optional)
    pathArrayThe path components starting from the key as base. (Optional)
    +
    ParameterTypeDescription
    keyStringThe key as a formatted string, under which data can be stored in global state.
    state_identifierObjectThe identifier used for the query. If not provided, the tip of the chain will be used. (Optional)
    pathArrayThe path components starting from the key as base. (Optional)
    Example query_global_state request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    },
    {
    "name": "key",
    "value": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"
    },
    {
    "name": "path",
    "value": []
    }
    ]
    }

    @@ -620,13 +620,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.block_headerObjectThe Block header if a Block hash was provided. (Optional)stored_valueObjectThe stored value.merkle_proofStringThe merkle proof. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_headerObjectThe Block header if a Block hash was provided. (Optional)
    stored_valueObjectThe stored value.
    merkle_proofStringThe merkle proof.
    Example query_global_state result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "2.0.0",
    "block_header": {
    "Version2": {
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "body_hash": "0505050505050505050505050505050505050505050505050505050505050505",
    "random_bit": true,
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "era_end": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "next_era_validator_weights": [
    {
    "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
    "weight": "123"
    },
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    }
    ],
    "rewards": {},
    "next_era_gas_price": 1
    },
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "protocol_version": "1.0.0",
    "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "current_gas_price": 1,
    "last_switch_block_hash": "0909090909090909090909090909090909090909090909090909090909090909"
    }
    },
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "named_keys": [
    {
    "name": "main_purse",
    "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
    }
    ],
    "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    }
    }
    },
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }

    state_get_account_info

    -

    This method returns a JSON representation of an Account from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the account at the highest state root hash. The block_identifier must refer to a Block after the Account's creation, or the method will return an empty response.

    +

    This method returns a JSON representation of an Account from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the account at the highest state root hash. The block_identifier must refer to a Block after the Account's creation, or the method will return an empty response.

    @@ -647,7 +647,7 @@

    state -
    ParameterTypeDescription
    account_identifierStringThe public key or account hash of the Account.
    block_identifierObjectThe Block hash. (Optional)
    +
    ParameterTypeDescription
    account_identifierStringThe public key or account hash of the Account.
    block_identifierObjectThe Block hash. (Optional)
    Example state_get_account_info request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_account_info",
    "params": [
    {
    "name": "account_identifier",
    "value": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    },
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    @@ -678,7 +678,7 @@

    accountObjectA JSON representation of the Account structure.merkle_proofStringThe merkle proof. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    accountObjectA JSON representation of the Account structure.
    merkle_proofStringThe merkle proof.
    Example state_get_account_info result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "state_get_account_info_result",
    "value": {
    "api_version": "2.0.0",
    "account": {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "named_keys": [
    {
    "name": "main_purse",
    "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
    }
    ],
    "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    }
    },
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }

    @@ -706,7 +706,7 @@

    st -
    ParameterTypeDescription
    state_root_hashStringHash of the state root.
    dictionary_identifierObjectThe Dictionary query identifier.
    +
    ParameterTypeDescription
    state_root_hashStringHash of the state root.
    dictionary_identifierObjectThe Dictionary query identifier.
    Example state_get_dictionary_item request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_dictionary_item",
    "params": [
    {
    "name": "state_root_hash",
    "value": "0808080808080808080808080808080808080808080808080808080808080808"
    },
    {
    "name": "dictionary_identifier",
    "value": {
    "URef": {
    "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "dictionary_item_key": "a_unique_entry_identifier"
    }
    }
    }
    ]
    }

    @@ -742,13 +742,13 @@

    stored_valueObjectThe stored value.merkle_proofStringThe merkle proof. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    dictionary_keyStringThe key under which the value is stored.
    stored_valueObjectThe stored value.
    merkle_proofStringThe merkle proof.
    Example state_get_dictionary_item result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "state_get_dictionary_item_result",
    "value": {
    "api_version": "2.0.0",
    "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",
    "stored_value": {
    "CLValue": {
    "cl_type": "U64",
    "bytes": "0100000000000000",
    "parsed": 1
    }
    },
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }

    state_get_entity

    -

    This method returns a JSON representation of an AddressableEntity from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the entity at the highest state root hash. The block_identifier must refer to a Block after the entity's creation, or the method will return an empty response.

    +

    This method returns a JSON representation of an AddressableEntity from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the entity at the highest state root hash. The block_identifier must refer to a Block after the entity's creation, or the method will return an empty response.

    @@ -769,7 +769,7 @@

    state_get_e -
    ParameterTypeDescription
    entity_identifierStringIdentifier of an addressable entity.
    block_identifierObjectThe Block hash. (Optional)
    +
    ParameterTypeDescription
    entity_identifierStringIdentifier of an addressable entity.
    block_identifierObjectThe Block hash. (Optional)
    Example state_get_entity request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_entity",
    "params": [
    {
    "name": "entity_identifier",
    "value": {
    "EntityAddr": "entity-account-0000000000000000000000000000000000000000000000000000000000000000"
    }
    },
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    @@ -800,7 +800,7 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.entityObjectA JSON representation of the AddressableEntity.merkle_proofStringThe merkle proof. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    entityObjectA JSON representation of the AddressableEntity.
    merkle_proofStringThe merkle proof.
    Example state_get_entity result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "state_get_entity_result",
    "value": {
    "api_version": "2.0.0",
    "entity": {
    "AddressableEntity": {
    "entity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "Account": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c"
    },
    "package_hash": "package-0000000000000000000000000000000000000000000000000000000000000000",
    "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",
    "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": [
    {
    "topic_name": "topic",
    "topic_name_hash": "0000000000000000000000000000000000000000000000000000000000000000"
    }
    ]
    },
    "named_keys": [
    {
    "name": "key",
    "key": "hash-0000000000000000000000000000000000000000000000000000000000000000"
    }
    ],
    "entry_points": [
    {
    "V1CasperVm": {
    "name": "entry_point",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Caller",
    "entry_point_payment": "Caller"
    }
    }
    ]
    }
    },
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }

    @@ -836,7 +836,7 @@

    -
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    peersArrayThe node ID and network address of each connected peer.
    +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    peersArrayThe node ID and network address of each connected peer.
    Example info_get_peers result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_peers_result",
    "value": {
    "api_version": "2.0.0",
    "peers": [
    {
    "node_id": "tls:0101..0101",
    "address": "127.0.0.1:54321"
    }
    ]
    }
    }
    }

    @@ -933,10 +933,10 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.available_block_rangeObjectThe available block range in storage.block_syncObjectThe status of the block synchronizer builders.build_versionStringThe compiled node version.chainspec_nameStringThe chainspec name, used to identify the currently connected network.last_added_block_infoObjectThe minimal info of the last Block from the linear chain. (Optional)last_progressStringTimestamp of the last recorded progress in the reactor.latest_switch_block_hashObjectThe hash of the latest switch block. (Optional)next_upgradeObjectInformation about the next scheduled upgrade. (Optional)our_public_signing_keyStringOur public signing key. (Optional)peersArrayThe node ID and network address of each connected peer.reactor_stateStringThe current state of the node reactor.round_lengthIntegerThe next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)starting_state_root_hashStringThe state root hash used at the start of the current session.uptimeIntegerTime that passed since the node has started. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    available_block_rangeObjectThe available block range in storage.
    block_syncObjectThe status of the block synchronizer builders.
    build_versionStringThe compiled node version.
    chainspec_nameStringThe chainspec name, used to identify the currently connected network.
    last_added_block_infoObjectThe minimal info of the last Block from the linear chain. (Optional)
    last_progressStringTimestamp of the last recorded progress in the reactor.
    latest_switch_block_hashObjectThe hash of the latest switch block. (Optional)
    next_upgradeObjectInformation about the next scheduled upgrade. (Optional)
    our_public_signing_keyStringOur public signing key. (Optional)
    peersArrayThe node ID and network address of each connected peer.
    reactor_stateStringThe current state of the node reactor.
    round_lengthIntegerThe next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)
    starting_state_root_hashStringThe state root hash used at the start of the current session.
    uptimeIntegerTime that passed since the node has started.
    Example info_get_status result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_status_result",
    "value": {
    "api_version": "2.0.0",
    "peers": [
    {
    "node_id": "tls:0101..0101",
    "address": "127.0.0.1:54321"
    }
    ],
    "build_version": "1.0.0-xxxxxxxxx@DEBUG",
    "chainspec_name": "casper-example",
    "starting_state_root_hash": "0000000000000000000000000000000000000000000000000000000000000000",
    "last_added_block_info": {
    "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "round_length": "1m 5s 536ms",
    "next_upgrade": {
    "activation_point": 42,
    "protocol_version": "2.0.1"
    },
    "uptime": "13s",
    "reactor_state": "Initialize",
    "last_progress": "1970-01-01T00:00:00.000Z",
    "available_block_range": {
    "low": 0,
    "high": 0
    },
    "block_sync": {
    "historical": {
    "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",
    "block_height": 40,
    "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"
    },
    "forward": {
    "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",
    "block_height": 6701,
    "acquisition_state": "have block body(6701) for: block hash 5990..4983"
    }
    },
    "latest_switch_block_hash": "0000000000000000000000000000000000000000000000000000000000000000"
    }
    }
    }
    }

    -

    +
    \ No newline at end of file diff --git a/next/developers/json-rpc/json-rpc-pos/index.html b/2.0.0/developers/json-rpc/json-rpc-pos/index.html similarity index 66% rename from next/developers/json-rpc/json-rpc-pos/index.html rename to 2.0.0/developers/json-rpc/json-rpc-pos/index.html index 88c461747..285a9ac24 100644 --- a/next/developers/json-rpc/json-rpc-pos/index.html +++ b/2.0.0/developers/json-rpc/json-rpc-pos/index.html @@ -1,25 +1,25 @@ - + -Proof-of-Stake JSON-RPC Methods | Casper Docs - Redux +Proof-of-Stake JSON-RPC Methods | Casper Docs - Redux - - + +
    Version: Next

    Proof-of-Stake JSON-RPC Methods

    + submit an issue on Github
    Version: 2.0.0

    Proof-of-Stake JSON-RPC Methods

    The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.


    state_get_auction_info

    -

    This method returns the bids and validators from a specific Block (by height or hash). If you do not provide a block_identifier, state_get_auction_info will return information from the most recent Block.

    +

    This method returns the bids and validators from a specific Block (by height or hash). If you do not provide a block_identifier, state_get_auction_info will return information from the most recent Block.

    @@ -35,7 +35,7 @@

    state -
    ParameterTypeDescription
    block_identifierObjectThe Block identifier. (Optional)
    +
    ParameterTypeDescription
    block_identifierObjectThe Block identifier. (Optional)
    Example state_get_auction_info request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_auction_info",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    @@ -61,7 +61,7 @@

    auction_stateObjectThe auction state. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    auction_stateObjectThe auction state.
    Example state_get_auction_info result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "state_get_auction_info_result",
    "value": {
    "api_version": "2.0.0",
    "auction_state": {
    "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
    "block_height": 10,
    "era_validators": [
    {
    "era_id": 10,
    "validator_weights": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "weight": "10"
    }
    ]
    }
    ],
    "bids": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "bid": {
    "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",
    "staked_amount": "20",
    "delegation_rate": 0,
    "vesting_schedule": null,
    "delegators": [
    {
    "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",
    "delegator": {
    "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",
    "staked_amount": "10",
    "bonding_purse": "uref-fbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb-007",
    "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "vesting_schedule": null
    }
    }
    ],
    "inactive": false
    }
    }
    ]
    }
    }
    }
    }

    @@ -125,7 +125,7 @@

    changesObjectThe validators' status changes. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    changesObjectThe validators' status changes.
    Example info_get_validator_changes result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_validator_changes_result",
    "value": {
    "api_version": "2.0.0",
    "changes": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "status_changes": [
    {
    "era_id": 1,
    "validator_change": "Added"
    }
    ]
    }
    ]
    }
    }
    }

    @@ -147,7 +147,7 @@

    block_identifierObjectThe Block identifier. If you do not supply a block_identifier, the returned information will be the most recent Block. (Optional) +
    ParameterTypeDescription
    block_identifierObjectThe Block identifier. If you do not supply a block_identifier, the returned information will be the most recent Block. (Optional)
    Example chain_get_era_info_by_switch_block request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_era_info_by_switch_block",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    @@ -173,10 +173,10 @@

    era_summaryObjectThe era summary, if found. (Optional) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary, if found. (Optional)
    Example chain_get_era_info_by_switch_block

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_era_info_by_switch_block_result",
    "value": {
    "api_version": "2.0.0",
    "era_summary": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "era_id": 42,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "1000"
    }
    },
    {
    "Validator": {
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "2000"
    }
    }
    ]
    }
    },
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }
    }

    -

    +
    \ No newline at end of file diff --git a/next/developers/json-rpc/json-rpc-transactional/index.html b/2.0.0/developers/json-rpc/json-rpc-transactional/index.html similarity index 91% rename from next/developers/json-rpc/json-rpc-transactional/index.html rename to 2.0.0/developers/json-rpc/json-rpc-transactional/index.html index 657dda65f..396cd186f 100644 --- a/next/developers/json-rpc/json-rpc-transactional/index.html +++ b/2.0.0/developers/json-rpc/json-rpc-transactional/index.html @@ -1,21 +1,21 @@ - + -Transactional JSON-RPC Methods | Casper Docs - Redux +Transactional JSON-RPC Methods | Casper Docs - Redux - - + +
    Version: Next

    Transactional JSON-RPC Methods

    + submit an issue on Github
    Version: 2.0.0

    Transactional JSON-RPC Methods


    account_put_deploy

    caution

    DEPRECATED: Use account_put_transaction instead.

    @@ -35,13 +35,13 @@

    account_p -
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    +
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    Example account_put_deploy request

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": [
    {
    "name": "deploy",
    "value": {
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "gas_price": 1,
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "chain_name": "casper-example"
    },
    "payment": {
    "StoredContractByName": {
    "name": "casper-example",
    "entry_point": "example-entry-point",
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"
    }
    ]
    }
    }
    ]
    }

    account_put_deploy_result

    -

    The result contains the RPC API version and a deploy_hash, which is the primary identifier of a Deploy within a Casper network.

    +

    The result contains the RPC API version and a deploy_hash, which is the primary identifier of a Deploy within a Casper network.

    @@ -62,13 +62,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.deploy_hashStringA hex-encoded hash of the Deploy as sent. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    deploy_hashStringA hex-encoded hash of the Deploy as sent.
    Example account_put_deploy result

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "account_put_deploy_result",
    "value": {
    "api_version": "2.0.0",
    "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    }
    }
    }

    account_put_transaction

    -

    This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the transaction as a parameter, prior to sending it to a node on a network for execution.

    +

    This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the transaction as a parameter, prior to sending it to a node on a network for execution.

    @@ -84,16 +84,16 @@

    acco -
    ParameterTypeDescription
    transactionObjectA transaction consists of an item containing a Deploy and a Transaction along with the requester's signature(s).
    +
    ParameterTypeDescription
    transactionObjectA transaction consists of an item containing a Deploy and a Transaction along with the requester's signature(s).
    -

    Note: You can find a list of trusted peers in the network's configuration file, config.toml. Here is an example config.toml. You may send transactions to one of the trusted nodes or use them to query other online nodes.

    +

    Note: You can find a list of trusted peers in the network's configuration file, config.toml. Here is an example config.toml. You may send transactions to one of the trusted nodes or use them to query other online nodes.

    Example account_put_transaction request
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_transaction",
    "params": [
    {
    "name": "transaction",
    "value": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    }
    }
    ],
    }

    account_put_transaction_result

    -

    The result contains the RPC API version and the transaction_hash, which is the primary identifier of a transaction within a Casper network.

    +

    The result contains the RPC API version and the transaction_hash, which is the primary identifier of a transaction within a Casper network.

    @@ -114,7 +114,7 @@

    transaction_hashStringA hex-encoded hash of the transaction as sent. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    transaction_hashStringA hex-encoded hash of the transaction as sent.
    Example account_put_transaction result
    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "account_put_transaction_result",
    "value": {
    "api_version": "2.0.0",
    "transaction_hash": {
    "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"
    }
    }
    }
    }

    @@ -137,7 +137,7 @@

    speculative -
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    +
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    Example speculative_exec request

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec",
    "params": {
    "deploy": {
    "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",
    "header": {
    "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "timestamp": "2023-05-23T13:32:45.554Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",
    "dependencies": [],
    "chain_name": "integration-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400e1f505",
    "parsed": "100000000"
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",
    "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010000000000000000",
    "parsed": 0
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"
    }
    ]
    }
    },
    "id": 6889533540839698701
    }

    @@ -164,7 +164,7 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.execution_resultsObjectThe map of Block hash to execution result. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    execution_resultsObjectThe map of Block hash to execution result.
    Example speculative_exec result

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "speculative_exec_result",
    "value": {
    "api_version": "2.0.0",
    "execution_result": {
    "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",
    "transfers": [],
    "limit": "100000000000",
    "consumed": "23289743502",
    "effects": [
    {
    "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"
    },
    "name": {
    "cl_type": "String",
    "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",
    "parsed": "test_payment_package_hash"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",
    "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000746573745f7061796d656e745f616363657373",
    "parsed": "test_payment_access"
    }
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": "Identity"
    },
    {
    "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",
    "kind": "Identity"
    },
    {
    "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "pay",
    "args": [
    {
    "name": "amount",
    "cl_type": "U512"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",
    "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "10000000636f6e74726163745f76657273696f6e",
    "parsed": "contract_version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    },
    "name": {
    "cl_type": "String",
    "bytes": "11000000746573745f7061796d656e745f68617368",
    "parsed": "test_payment_hash"
    }
    }
    }
    }
    }
    ],
    "messages": [],
    "error": null
    }
    }
    }
    }

    @@ -186,7 +186,7 @@

    specula -
    ParameterTypeDescription
    transactionObjectA Transaction is a versioned wrapper for a transaction or deploy.
    +
    ParameterTypeDescription
    transactionObjectA Transaction is a versioned wrapper for a transaction or deploy.
    Example speculative_exec_txn request

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec_txn",
    "params": {
    "transaction": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    }
    },
    "id": 6889533540839698701
    }

    @@ -213,10 +213,10 @@

    -
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    execution_resultObjectResult of the speculative execution.
    +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    execution_resultObjectResult of the speculative execution.
    Example speculative_exec_txn result

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "speculative_exec_txn_result",
    "value": {
    "api_version": "2.0.0",
    "execution_result": {
    "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",
    "transfers": [],
    "limit": "100000000000",
    "consumed": "23289743502",
    "effects": [
    {
    "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"
    },
    "name": {
    "cl_type": "String",
    "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",
    "parsed": "test_payment_package_hash"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",
    "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000746573745f7061796d656e745f616363657373",
    "parsed": "test_payment_access"
    }
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": "Identity"
    },
    {
    "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",
    "kind": "Identity"
    },
    {
    "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "pay",
    "args": [
    {
    "name": "amount",
    "cl_type": "U512"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",
    "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "10000000636f6e74726163745f76657273696f6e",
    "parsed": "contract_version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    },
    "name": {
    "cl_type": "String",
    "bytes": "11000000746573745f7061796d656e745f68617368",
    "parsed": "test_payment_hash"
    }
    }
    }
    }
    }
    ],
    "messages": [],
    "error": null
    }
    }
    }
    }

    -

    +
    \ No newline at end of file diff --git a/2.0.0/developers/json-rpc/minimal-compliance/index.html b/2.0.0/developers/json-rpc/minimal-compliance/index.html new file mode 100644 index 000000000..a8f725569 --- /dev/null +++ b/2.0.0/developers/json-rpc/minimal-compliance/index.html @@ -0,0 +1,49 @@ + + + + + +Required Methods for Minimal Compliance | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Required Methods for Minimal Compliance

    +

    The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.

    +
      +
    • +

      chain_get_block - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers.

      +
    • +
    • +

      info_get_deploy - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy.

      +
    • +
    • +

      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 - The state root hash is one of the several global state identifiers used to query the network state after sending deploys.

      +
    • +
    • +

      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 - 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 - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state.

      +
    • +
    • +

      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 methods state_get_balance and state_get_item should not be used.

    +

    In addition to these methods, a minimally compliant Casper SDK must account for the types 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.

    + + \ No newline at end of file diff --git a/next/developers/json-rpc/types_chain/index.html b/2.0.0/developers/json-rpc/types_chain/index.html similarity index 76% rename from next/developers/json-rpc/types_chain/index.html rename to 2.0.0/developers/json-rpc/types_chain/index.html index fec146096..9d84e5ab6 100644 --- a/next/developers/json-rpc/types_chain/index.html +++ b/2.0.0/developers/json-rpc/types_chain/index.html @@ -1,21 +1,21 @@ - + -Types | Casper Docs - Redux +Types | Casper Docs - Redux - - + +
    Version: 2.0.0

    Types

    The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.

    Account

    Structure representing a user's Account, stored in global state.

    @@ -577,7 +577,7 @@

    Contra

    Unlocked The package is unlocked and can be versioned.

    -

    ContractVersion

    +

    ContractVersion

    The version of the contract.

    Required Parameters:

    EntryPoint2

    @@ -891,7 +891,7 @@

    EntryPoint2name The string name of the entrypoint.

  • -

    ret

    +

    ret

  • EntryPointAccess

    @@ -1147,7 +1147,7 @@

    ExecutionR

    Gas

    The Gas struct represents a U512 amount of gas.

    -

    GlobalStateIdentifier

    +

    GlobalStateIdentifier

    Identifier for possible ways to query global state.

    • @@ -1389,7 +1389,7 @@

      Parametercl_type

      +

      cl_type

    • name

      @@ -1472,16 +1472,16 @@

      PurseIdentif

      One of:

      • -

        main_purse_under_public_key The main purse under a provided PublicKey.

        +

        main_purse_under_public_key The main purse under a provided PublicKey.

      • -

        main_purse_under_account_hash The main purse under a provided AccountHash.

        +

        main_purse_under_account_hash The main purse under a provided AccountHash.

      • main_purse_under_entity_addr The main purse of the account identified by this EntityAddr.

      • -

        purse_uref A specific purse identified by the associated URef.

        +

        purse_uref A specific purse identified by the associated URef.

      ReservationKind

      @@ -2188,6 +2188,6 @@

      WithdrawPurse<
    • validator_public_key The original validator's public key.

    • -

    +
    \ No newline at end of file diff --git a/2.0.0/developers/json-rpc/types_cl/index.html b/2.0.0/developers/json-rpc/types_cl/index.html new file mode 100644 index 000000000..e0c1da0b5 --- /dev/null +++ b/2.0.0/developers/json-rpc/types_cl/index.html @@ -0,0 +1,56 @@ + + + + + +CLType | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    CLType

    +

    Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.

    +
      +
    • Bool Primitive
    • +
    • I32 Primitive
    • +
    • I64 Primitive
    • +
    • U8 Primitive
    • +
    • U32 Primitive
    • +
    • U64 Primitive
    • +
    • U128 Large unsigned integer type
    • +
    • U256 Large unsigned integer type
    • +
    • U512 Large unsigned integer type
    • +
    • Unit Primitive
    • +
    • String Primitive
    • +
    • Key System type
    • +
    • URef System type
    • +
    • PublicKey System type
    • +
    • Option Option of a CLType
    • +
    • List Variable-length list of a single CLType (comparable to a Vec)
    • +
    • ByteArray Fixed-length list of a single CLType (comparable to a Rust array)
    • +
    • Result Result with Ok and Err variants of CLType's
    • +
    • Map Map with keys of a single CLType and values of a single CLType
    • +
    • Tuple1 1-ary tuple of a CLType
    • +
    • Tuple2 2-ary tuple of CLTypes
    • +
    • Tuple3 3-ary tuple of CLTypes
    • +
    • Any Unspecified type
    • +
    +

    CLValue

    +

    A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized Vec<u8> and also holds the CLType of the underlying data as a separate member. The parsed field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred.

    +
      +
    • +

      bytes A Casper serialized representation of the underlying value. For more information, reference the Serialization Standard.

      +
    • +
    • +

      cl_type

      +
    • +
    + + \ No newline at end of file diff --git a/next/developers/prerequisites/index.html b/2.0.0/developers/prerequisites/index.html similarity index 74% rename from next/developers/prerequisites/index.html rename to 2.0.0/developers/prerequisites/index.html index b62a14d6e..aae48584e 100644 --- a/next/developers/prerequisites/index.html +++ b/2.0.0/developers/prerequisites/index.html @@ -1,21 +1,21 @@ - + -Development Prerequisites | Casper Docs - Redux +Development Prerequisites | Casper Docs - Redux - - + +
    Version: Next

    import Tabs from '@theme/Tabs'; + submit an issue on Github

    Version: 2.0.0

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Development Prerequisites

    This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.

    @@ -59,7 +59,7 @@

    rustup update

    Verify the installation:

    cargo-casper --version
    -
    note

    Familiarize yourself with the essential Casper crates described here.

    +
    note

    Familiarize yourself with the essential Casper crates described here.

    Installing the Casper Client

    The default Casper client is on crates.io. This client can transmit your transactions to a Casper network.

    cargo install casper-client
    @@ -109,7 +109,7 @@

    Installing
  • Error Lens – Enhances the programming experience by highlighting syntax errors
  • Setting up a Casper Account

    -

    The Account creation process consists of two steps:

    +

    The Account creation process consists of two steps:

    1. Creating an Account
    2. Funding the Account
    3. @@ -121,15 +121,15 @@

      Settin

      Creating an account

      The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey.

      By default, a transactional interaction with the blockchain takes the form of a Transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

      -

      Users can create accounts using the Casper command-line client.

      -

      Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined here.

      +

      Users can create accounts using the Casper command-line client.

      +

      Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined here.

      Use either method to generate an account and its corresponding cryptographic key-pair.

      Generating the account hash

      As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain AccountHashes instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the account-address option of the Casper CLI client:

      casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>

      Funding an Account

      After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain.

      -

      On Testnet, you can fund an account by requesting test tokens according to this guide. You can request test tokens only once for each account.

      +

      On Testnet, you can fund an account by requesting test tokens according to this guide. You can request test tokens only once for each account.

      On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet.

      Acquiring a Node Address from the Network

      Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, http://<node-ip-address>:7777 by default.

      @@ -141,6 +141,6 @@

      Peers on Mainnet

      You will see a list of peers, and you can select the IP of any peer on the list.

      -

      Note: If the selected peer is unresponsive, pick a different peer and try again.

    +

    Note: If the selected peer is unresponsive, pick a different peer and try again.

    \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/assembly-script/index.html b/2.0.0/developers/writing-onchain-code/assembly-script/index.html new file mode 100644 index 000000000..1b18d1a0a --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/assembly-script/index.html @@ -0,0 +1,54 @@ + + + + + +Getting Started with AssemblyScript | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Getting Started with AssemblyScript

    +

    Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.

    +

    Prerequisites

    +

    Installing AssemblyScript

    +

    Installation of AssemblyScript requires Node.js.

    +

    After installation of Node.js, the following command will install AssemblyScript:

    +
    npm i assemblyscript
    +

    Full instructions and details for installing AssemblyScript can be found here.

    +

    Development Environment Setup

    +

    Installing the Casper Package

    +

    The casper-contract package can be installed using the following command:

    +
    npm i casper-contract
    +

    The Assemblyscript contract API documentation can be found at https://www.npmjs.com/package/casper-contract.

    +

    Creating a Project

    +

    For each smart contract, it is necessary to create a project directory and initialize it.

    +

    The npm init process prompts for various details about the project. Answer as you see fit, but you may safely default everything except name, which needs to be specified. In this guide, we will refer to the contract name as your-contract-name.

    +
    mkdir project
    cd project
    npm init
    +

    Then install AssemblyScript and this package in the project directory.

    +
    npm install --save-dev assemblyscript@0.9.1
    npm install --save casper-contract
    +

    Script Entries

    +

    Add script entries for AssemblyScript to your project's package.json. Note that your contract name is used for the name of the Wasm file. Replace your-contract-name with the name of your contract.

    +
    {
    "name": "your-contract-name",
    ...
    "scripts": {
    "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",
    "asbuild": "npm run asbuild:optimized",
    ...
    },
    ...
    }
    +

    In the project root, create an index.js file with the following contents. Replace your-contract-name with the name of your contract.

    +
    const fs = require("fs");

    const compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));

    const imports = {
    env: {
    abort(_msg, _file, line, column) {
    console.error("abort called at index.ts:" + line + ":" + column);
    },
    },
    };

    Object.defineProperty(module, "exports", {
    get: () => new WebAssembly.Instance(compiled, imports).exports,
    });
    +

    Next, create a directory called assembly, and in that directory, create a file called tsconfig.json in the following way:

    +
    {
    "extends": "../node_modules/assemblyscript/std/assembly.json",
    "include": ["./**/*.ts"]
    }
    +

    Sample Smart Contract

    +

    In the assembly directory, also create an index.ts file, where the code for the contract needs to go.

    +

    You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network.

    +
    //@ts-nocheck
    import { Error, ErrorCode } from "casper-contract/error";

    // simplest possible feedback loop
    export function call(): void {
    Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1
    }
    +

    If you prefer a more complicated first contract, you can look at example contracts on the Casper Ecosystem GitHub repository for inspiration.

    +

    Compile to Wasm

    +

    To compile the contract to Wasm, use npm to run the asbuild script from the project root:

    +
    npm run asbuild
    +

    If the build is successful, there will be a dist folder in the root folder and in it should be your-contract-name.wasm.

    + + \ No newline at end of file diff --git a/next/developers/writing-onchain-code/best-practices/index.html b/2.0.0/developers/writing-onchain-code/best-practices/index.html similarity index 56% rename from next/developers/writing-onchain-code/best-practices/index.html rename to 2.0.0/developers/writing-onchain-code/best-practices/index.html index fe9c79cb8..7abce2555 100644 --- a/next/developers/writing-onchain-code/best-practices/index.html +++ b/2.0.0/developers/writing-onchain-code/best-practices/index.html @@ -1,24 +1,24 @@ - + -Best Practices for Casper Smart Contract Authors | Casper Docs - Redux +Best Practices for Casper Smart Contract Authors | Casper Docs - Redux - - + +
    Version: Next

    Best Practices for Casper Smart Contract Authors

    + submit an issue on Github
    Version: 2.0.0

    Best Practices for Casper Smart Contract Authors

    At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.

    Data Efficiency

    -

    When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary transactions will drastically decrease the overall cost.

    +

    When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary transactions will drastically decrease the overall cost.

    When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent transaction of session code. This entry point creates the internal structure of the contract and cannot be called after the initial transaction. Below is an example of a self-initalizing entry point that can be used within the call function.

    Example Self-initialization Entry Point
    @@ -26,8 +26,8 @@

    Data Efficie

    Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial transaction.

    Costs

    -

    Computations occurring on-chain come with associated gas costs. Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical.

    -

    Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the reuse of purses should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author.

    +

    Computations occurring on-chain come with associated gas costs. Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical.

    +

    Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the reuse of purses should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author.

    Tips to reduce WASM size

    Transactions have a maxim size specified in each network chainspec as max_transaction_size = 1_048_576. For example, networks running node version 2.0, have the following maximum transaction size in bytes:

    max_transaction_size = 1_048_576
    @@ -59,13 +59,13 @@

    TestingUnit Testing Session Code

    +

    Unit Testing Session Code

  • -

    Testing Smart Contracts

    +

    Testing Smart Contracts

  • -

    Testing Smart Contracts with NCTL

    +

    Testing Smart Contracts with NCTL

  • Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:

    @@ -76,6 +76,6 @@

    TestingA Counter On The Testnet

    -

    +
    \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/calling-contracts/index.html b/2.0.0/developers/writing-onchain-code/calling-contracts/index.html new file mode 100644 index 000000000..f5922ac94 --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/calling-contracts/index.html @@ -0,0 +1,44 @@ + + + + + +Calling Contracts | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Calling Contracts

    +

    Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.

    +

    Using Legacy Deploy Variants

    +

    ModuleBytes

    +

    ModuleBytes is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm.

    +

    However, you can also use ModuleBytes to deploy session code that calls a contract.

    +

    Further information on the structure of ModuleBytes can be found in here.

    +

    StoredContractByHash

    +

    StoredContractByHash is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question.

    +

    While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract.

    +

    Further information on the structure of StoredContractByHash can be found here.

    +

    StoredContractByName

    +

    StoredContractByName is similar to StoredContractByHash, with the main difference being the reference used to invoke on-chain Wasm. Where StoredContractByHash requires the contract hash, StoredContractByName uses a string stored as a NamedKey in the caller's account.

    +

    This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's NamedKeys.

    +

    StoredVersionedContractByHash

    +

    StoredVersionedContractByHash is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package.

    +

    This makes StoredVersionedContractByHash more stable than StoredContractByHash, as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version.

    +

    DApp developers that use contracts developed by other parties can use StoredVersionedContractByHash to avoid interruptions from contract version changes.

    +

    Further information on the structure of StoredVersionedContractByHash can be found here.

    +

    StoredVersionedContractByName

    +

    StoredVersionedContractByName combines the functionality of StoredContractByName and StoredVersionedContractByHash. It allows a developer to store a reference string as a NamedKey within their account context that references a contract by its contract package hash.

    +

    Further information on the structure of StoredVersionedContractByName can be found here.

    +

    Transfer

    +

    Native Transfers are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network.

    +

    Further information on the structure of a native Transfer can be found here.

    + + \ No newline at end of file diff --git a/next/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html b/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html similarity index 50% rename from next/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html rename to 2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html index 850762061..760630151 100644 --- a/next/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html +++ b/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html @@ -1,22 +1,22 @@ - + -Contract Hash vs. Package Hash | Casper Docs - Redux +Contract Hash vs. Package Hash | Casper Docs - Redux - - + +
    Version: Next

    Using the Contract Hash vs. the Package Hash

    -

    This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.

    + submit an issue on Github
    Version: 2.0.0

    Using the Contract Hash vs. the Package Hash

    +

    This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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. This behavior depends on what the contract needs to do, so a given contract might:

      @@ -42,7 +42,7 @@

      The Ca
      /// 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.

      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 and how Casper manages the calling of a contract.

      +

      Learn more about Call Stacks and how Casper manages the calling of a contract.

      Recommendations

      Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash.

        @@ -132,9 +132,9 @@

        Recommendati

      What's Next?

    +
  • Best Practices for Casper Smart Contract Authors - An outline of best practices when developing smart contracts on a Casper network
  • +
  • Cross-Contract Communication - Variations of cross-contract communication for more complex scenarios
  • +
  • Interacting with Runtime Return Values - Contract code returning a value to the immediate caller via runtime::ret()
  • +
    \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/contract-vs-session/index.html b/2.0.0/developers/writing-onchain-code/contract-vs-session/index.html new file mode 100644 index 000000000..3a36952f3 --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/contract-vs-session/index.html @@ -0,0 +1,62 @@ + + + + + +Contracts and Session Code | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Contracts and Session Code

    +

    What is Session Code?

    +

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the call function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse.

    +

    The best use of session code is when the situation calls for stateless execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary.

    +

    Comparing Session and Contract Code

    +

    The following table summarizes the key differences between session code and contract code on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Session CodeContract Code
    Session code always executes in the context of the account that signed the transaction containing the session code.A smart contract, which is stored on-chain logic, executes within its own context.
    Session code has only one entry point, call, which can be used to interact with the session code.A smart contract can have multiple entry points that can be invoked.
    The call entry point initiates any action the session code takes.Any action undertaken by a contract must initiate through an outside call, usually via session code.
    When a put_key call is made within the body of the session code, the key is added to the account's named keys.When a put_key call is made within the smart contract's context, the contract's record is modified to have a new named_key entry.
    For more information on how to write session code, see Writing Session Code.For more information on writing contracts, see Writing a Basic Smart Contract in Rust.
    +

    The following image depicts the comparison presented in the table.

    +

    Comparing Session and Contract Code

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/emitting-contract-events/index.html b/2.0.0/developers/writing-onchain-code/emitting-contract-events/index.html new file mode 100644 index 000000000..0cd734a25 --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/emitting-contract-events/index.html @@ -0,0 +1,151 @@ + + + + + +Contract-Level Events | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Enabling Contracts to Emit Events

    +

    Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.

    +

    Messages produced by smart contracts are visible on a node's SSE event stream in human-readable format, and they contain the following information:

    +
      +
    • The address of the entity that produced the message, i.e., the contract hash
    • +
    • The message topic used to categorize the message
    • +
    • The human-readable message string
    • +
    • The index identifying the message in a message array
    • +
    +

    A checksum of the message is permanently stored in global state to protect against message spoofing and repudiation. For more details regarding the design and implementation of this feature, read the corresponding CEP-88 documentation.

    +

    The Casper External FFI provides the following two runtime functions to manage and emit messages:

    +
      +
    • manage_message_topic - Creates a topic to help categorize messages. When used for the first time, this function registers the contract's intent to emit messages. The maximum number of topics is specified in the chainspec.
    • +
    • emit_message - Emits a human-readable string message under a pre-registered topic.
    • +
    +

    The following sections contain more details about using these functions.

    +

    Creating a Topic

    +

    To create a new topic, call the manage_message_topic runtime function.

    +

    This sample code adds a new message topic called EVENTS_TOPIC, on which the contract can emit messages:

    +
    runtime::manage_message_topic(EVENTS_TOPIC, MessageTopicOperation::Add).unwrap_or_revert();
    +

    Verifying a Topic

    +

    No SSE event is emitted when a contract creates a new message topic. However, some applications need to determine which message topics are available to listen to messages on those topics. In global state, each contract entity contains a field called message_topics, which stores a map of registered topic names by topic name hash:

    +
    "message_topics": [
    {
    "topic_name": "events",
    "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"
    }
    ]
    +

    You can view the contract using the Casper CLI client and the query-global-state command using the block identifier or the state root hash:

    +
    casper-client query-global-state \
    --node-address <HOST:PORT> \
    --key [HASH_STRING] \
    --block-identifier <BLOCK_HASH> \
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777.
    • +
    • key - The identifier for the query. Use the key that identifies the contract, e.g., addressable-entity-contract-HASH.
    • +
    • block-identifier - Hex-encoded block hash or height of the block.
    • +
    +

    Here is a sample query to view the contract:

    +
    casper-client query-global-state \
    --node-address http://127.0.0.1:11101 \
    --key "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5" \
    --block-identifier 58d26bf0eeeefb698d76b319014efd2eaa2198ad754a489a23131948ef41fdd2
    +
    Expand to view the sample contract
    + +
    {
    "jsonrpc": "2.0",
    "id": -4994937296370433409,
    "result": {
    "api_version": "1.0.0",
    "block_header": {
    "Version2": {
    "parent_hash": "deafd8e5c1aff47ae8528fa2d343b711c2f5cb18ee29527961b37d4d173ad42a",
    "state_root_hash": "96d8962c03899277f9a4bd667c0510c0eab490dd6253ae0b8cee4ebfbcd52be6",
    "body_hash": "28812ec460ab82f94f3c658e946bb4779c6b76dea9c55d18beaf1e47fe8dd9c9",
    "random_bit": false,
    "accumulated_seed": "96a09ea136bb7e4e99b039ee0f1f6d9dd88d663927faffc7eb5c60804056354c",
    "era_end": null,
    "timestamp": "2023-11-28T23:59:53.856Z",
    "era_id": 112,
    "height": 1066,
    "protocol_version": "1.0.0"
    }
    },
    "stored_value": {
    "AddressableEntity": {
    "package_hash": "contract-package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",
    "byte_code_hash": "contract-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",
    "named_keys": [
    {
    "name": "acl_package_mode",
    "key": "uref-2a088bc6c30d1499cd9348d388a03c8162ab26d09b0484f634e6f4022581fe99-007"
    },
    {
    "name": "acl_whitelist",
    "key": "uref-d17ecf3fe6e46f9a6063cfb31cdb03cdd6b99d095b71d2247319c293f864c4d1-007"
    },
    {
    "name": "allow_minting",
    "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-007"
    },
    {
    "name": "approved",
    "key": "uref-87a0de173fd6a56fb867bab46d8a508a43259a244ffdd8b0d98e5c286261f9af-007"
    },
    {
    "name": "balances",
    "key": "uref-0c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f-007"
    },
    {
    "name": "burn_mode",
    "key": "uref-e507551382a6217b9165dd222854e6c877d33eab9845c4b7e8444559303e5b8a-007"
    },
    {
    "name": "burnt_tokens",
    "key": "uref-4711c3ee36ac9639af509f45164fdb5a88692b109c3b2360e57d09fcdd702f63-007"
    },
    {
    "name": "cep78_CEP-78",
    "key": "uref-a02fc32366a7187448afb8263a8f3716e933d28d84db6c6403893d94917cf98d-007"
    },
    {
    "name": "collection_name",
    "key": "uref-89e904724d79a9f6d41958a3621b437c9e220ad081805f39040ff51c79a8d67c-007"
    },
    {
    "name": "collection_symbol",
    "key": "uref-d41a40789a84cc8e0314135695acc279875d6c7455daafe517cc4ae5329d95de-007"
    },
    {
    "name": "events_mode",
    "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-007"
    },
    {
    "name": "hash_by_index",
    "key": "uref-7c9751097762ad778a6a11151780d377cbc57e0807e289d278831ca9263aa844-007"
    },
    {
    "name": "holder_mode",
    "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-007"
    },
    {
    "name": "identifier_mode",
    "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-007"
    },
    {
    "name": "index_by_hash",
    "key": "uref-e67fecb85654def8b1440907728491f4f1ae125a97f3fed93872c075e6fb4ad5-007"
    },
    {
    "name": "installer",
    "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c"
    },
    {
    "name": "json_schema",
    "key": "uref-f8b2f63a4c69a84c795908e9abd0f66b857790b8df627a21336d6d1e07bf7103-007"
    },
    {
    "name": "metadata_cep78",
    "key": "uref-5cf8084639c2b7b8f54ab78700e0a82107c0bb28966cdc3ffdd4bd0877a47f64-007"
    },
    {
    "name": "metadata_custom_validated",
    "key": "uref-f5ce01c02a1942a4833159d72414c014b0838b607b4f419af9e19cd2fb123658-007"
    },
    {
    "name": "metadata_mutability",
    "key": "uref-c11c8e99c52477efaae636890a49625f54e32b832e23e288e00952c8bf34610a-007"
    },
    {
    "name": "metadata_nft721",
    "key": "uref-d39ee0c77f9864b05297ac504ee5919d60dddb6c8c0d6ccce8225801885f8972-007"
    },
    {
    "name": "metadata_raw",
    "key": "uref-dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a-007"
    },
    {
    "name": "minting_mode",
    "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-007"
    },
    {
    "name": "nft_kind",
    "key": "uref-001ffa305e021b5d411a3e04707b3c17f0d31ee400e6c5faa9b8f66e0ebfdc99-007"
    },
    {
    "name": "nft_metadata_kind",
    "key": "uref-8dfb98ccdd030aae1e0dcda03dc728dd4332eb18c945fd25a55b43f9e487141e-007"
    },
    {
    "name": "nft_metadata_kinds",
    "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-007"
    },
    {
    "name": "number_of_minted_tokens",
    "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-007"
    },
    {
    "name": "operator_burn_mode",
    "key": "uref-40977d32bbfb85454c9e7b5ca03192efcd406f228d5c2e593210b3960e05604e-007"
    },
    {
    "name": "operators",
    "key": "uref-cbcb06403fbd8cb9f397029718f1f7e66bf5ec4e33aa58315dd3d5ecf5d078a7-007"
    },
    {
    "name": "ownership_mode",
    "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-007"
    },
    {
    "name": "package_operator_mode",
    "key": "uref-c05e3e87f5a64fbc20615afffaa6e4c81d98431b698f681322f5d8730ff40590-007"
    },
    {
    "name": "page_table",
    "key": "uref-4c545e6e4860629fd138fcb91f24d21498e69b076d472660ff769dfc2a994301-007"
    },
    {
    "name": "receipt_name",
    "key": "uref-6ddba59f56a5d52df5b8f85d03d19003feec3307a9d9ac6b420486d1a440a586-007"
    },
    {
    "name": "reporting_mode",
    "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-007"
    },
    {
    "name": "rlo_mflag",
    "key": "uref-d520d8cbca2b28a42f0db9493e94bdbb93f74702e20eac1a77b48dda39367afe-007"
    },
    {
    "name": "token_issuers",
    "key": "uref-c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a-007"
    },
    {
    "name": "token_owners",
    "key": "uref-1cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d-007"
    },
    {
    "name": "total_token_supply",
    "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-007"
    },
    {
    "name": "whitelist_mode",
    "key": "uref-af7ba884bbddf91530279c0ea005c56a4951f5330ebe5395528471302b791b3e-007"
    }
    ],
    "entry_points": [
    {
    "name": "approve",
    "entry_point": {
    "name": "approve",
    "args": [
    {
    "name": "spender",
    "cl_type": "Key"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "balance_of",
    "entry_point": {
    "name": "balance_of",
    "args": [
    {
    "name": "token_owner",
    "cl_type": "Key"
    }
    ],
    "ret": "U64",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "burn",
    "entry_point": {
    "name": "burn",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "get_approved",
    "entry_point": {
    "name": "get_approved",
    "args": [],
    "ret": {
    "Option": "Key"
    },
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "init",
    "entry_point": {
    "name": "init",
    "args": [
    {
    "name": "collection_name",
    "cl_type": "String"
    },
    {
    "name": "collection_symbol",
    "cl_type": "String"
    },
    {
    "name": "total_token_supply",
    "cl_type": "U64"
    },
    {
    "name": "allow_minting",
    "cl_type": "Bool"
    },
    {
    "name": "minting_mode",
    "cl_type": "U8"
    },
    {
    "name": "ownership_mode",
    "cl_type": "U8"
    },
    {
    "name": "nft_kind",
    "cl_type": "U8"
    },
    {
    "name": "holder_mode",
    "cl_type": "U8"
    },
    {
    "name": "whitelist_mode",
    "cl_type": "U8"
    },
    {
    "name": "acl_whitelist",
    "cl_type": {
    "List": "Key"
    }
    },
    {
    "name": "acl_package_mode",
    "cl_type": "Bool"
    },
    {
    "name": "package_operator_mode",
    "cl_type": "Bool"
    },
    {
    "name": "json_schema",
    "cl_type": "String"
    },
    {
    "name": "receipt_name",
    "cl_type": "String"
    },
    {
    "name": "identifier_mode",
    "cl_type": "U8"
    },
    {
    "name": "burn_mode",
    "cl_type": "U8"
    },
    {
    "name": "operator_burn_mode",
    "cl_type": "Bool"
    },
    {
    "name": "nft_metadata_kind",
    "cl_type": "U8"
    },
    {
    "name": "metadata_mutability",
    "cl_type": "U8"
    },
    {
    "name": "owner_reverse_lookup_mode",
    "cl_type": "U8"
    },
    {
    "name": "events_mode",
    "cl_type": "U8"
    },
    {
    "name": "transfer_filter_contract",
    "cl_type": {
    "Option": "Key"
    }
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "is_approved_for_all",
    "entry_point": {
    "name": "is_approved_for_all",
    "args": [
    {
    "name": "token_owner",
    "cl_type": "Key"
    },
    {
    "name": "operator",
    "cl_type": "Key"
    }
    ],
    "ret": "Bool",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "metadata",
    "entry_point": {
    "name": "metadata",
    "args": [],
    "ret": "String",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "migrate",
    "entry_point": {
    "name": "migrate",
    "args": [
    {
    "name": "cep78_package_key",
    "cl_type": "Any"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "mint",
    "entry_point": {
    "name": "mint",
    "args": [
    {
    "name": "token_owner",
    "cl_type": "Key"
    },
    {
    "name": "token_meta_data",
    "cl_type": "String"
    }
    ],
    "ret": {
    "Tuple3": [
    "String",
    "Key",
    "String"
    ]
    },
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "owner_of",
    "entry_point": {
    "name": "owner_of",
    "args": [],
    "ret": "Key",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "register_owner",
    "entry_point": {
    "name": "register_owner",
    "args": [],
    "ret": {
    "Tuple2": [
    "String",
    "URef"
    ]
    },
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "revoke",
    "entry_point": {
    "name": "revoke",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "set_approval_for_all",
    "entry_point": {
    "name": "set_approval_for_all",
    "args": [
    {
    "name": "approve_all",
    "cl_type": "Bool"
    },
    {
    "name": "operator",
    "cl_type": "Key"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "set_token_metadata",
    "entry_point": {
    "name": "set_token_metadata",
    "args": [
    {
    "name": "token_meta_data",
    "cl_type": "String"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "set_variables",
    "entry_point": {
    "name": "set_variables",
    "args": [
    {
    "name": "allow_minting",
    "cl_type": "Bool"
    },
    {
    "name": "contract_whitelist",
    "cl_type": {
    "List": {
    "ByteArray": 32
    }
    }
    },
    {
    "name": "acl_whitelist",
    "cl_type": {
    "List": "Key"
    }
    },
    {
    "name": "acl_package_mode",
    "cl_type": "Bool"
    },
    {
    "name": "package_operator_mode",
    "cl_type": "Bool"
    },
    {
    "name": "operator_burn_mode",
    "cl_type": "Bool"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "transfer",
    "entry_point": {
    "name": "transfer",
    "args": [
    {
    "name": "source_key",
    "cl_type": "Key"
    },
    {
    "name": "target_key",
    "cl_type": "Key"
    }
    ],
    "ret": {
    "Tuple2": [
    "String",
    "Key"
    ]
    },
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    },
    {
    "name": "updated_receipts",
    "entry_point": {
    "name": "updated_receipts",
    "args": [],
    "ret": {
    "List": {
    "Tuple2": [
    "String",
    "Key"
    ]
    }
    },
    "access": "Public",
    "entry_point_type": "AddressableEntity"
    }
    }
    ],
    "protocol_version": "1.0.0",
    "main_purse": "uref-596d134ad1078315a5e0cd2f40802b65cf53b6c789f0a38ba04157d04e15ab2b-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": [
    {
    "topic_name": "events",
    "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"
    }
    ]
    }
    },
    "merkle_proof": "[8288 hex chars]"
    }
    }
    +
    +

    +

    Under message_topics, you will find the control record for that topic, which has a composite key derived from the caller's entity address and the hash of the topic name:

    +
    "message_topics": [
    {
    "topic_name": "events",
    "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"
    }
    ]
    +

    Emitting a Message

    +

    To emit a message on a previously-created topic, call the emit_message runtime function.

    +

    This sample code sends a new message on the topic EVENTS_TOPIC.

    +
    runtime::emit_message(EVENTS_TOPIC, &message.try_into().unwrap()).unwrap_or_revert();
    +

    Verifying a Message

    +

    To verify a message, check a node's SSE endpoint, which streams messages in a human-readable format. Messages are visible as part of the TransactionProcessed event after the corresponding block is processed and added to the blockchain. The messages sent out on the event stream contain the following:

    +
      +
    • The identity of the entity that produced the message
    • +
    • The payload of the message
    • +
    • The name of the topic on which the message was emitted
    • +
    • The blake2b hash of the topic name
    • +
    • The message index in the topic
    • +
    +

    The following is a sample message logged inside a TransactionProcessed event:

    +
    "messages": [
    {
    "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",
    "message": {
    "String": "{\"Mint\":{\"recipient\":\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\",\"token_id\":{\"Index\":0}}}"
    },
    "topic_name": "events",
    "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",
    "index": 0
    }
    ]
    +
    Expand to view the full TransactionProcessed message
    + +
    data: {
    "TransactionProcessed": {
    "transaction_hash": {
    "Deploy": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26"
    },
    "account": "0130a16c8b0918cbfa8da00b6c0910ae0f2799dfd5ef7f092d0c4c1688031d60ac",
    "timestamp": "2023-11-29T01:35:41.522Z",
    "ttl": "30m",
    "block_hash": "b90c61cd1e3bc3be36110f04a7aec97b22bcfe9f36291cb011a14c4a663753bd",
    "execution_result": {
    "Version2": {
    "Success": {
    "effects": [
    {
    "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",
    "kind": "Identity"
    },
    {
    "key": "package-c092060112b445d1706f6962d7ad2da72a2e8312000e99d2b58f6a3e1624649a",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": "Identity"
    },
    {
    "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "0e9a6a8aff995ac138938d44c64d31",
    "parsed": "999999999999999999999518955956890"
    }
    }
    }
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": {
    "AddUInt512": "7500000000"
    }
    },
    {
    "key": "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",
    "kind": "Identity"
    },
    {
    "key": "package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",
    "kind": "Identity"
    },
    {
    "key": "byte-code-v1-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",
    "kind": "Identity"
    },
    {
    "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-000",
    "kind": "Identity"
    },
    {
    "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-000",
    "kind": "Identity"
    },
    {
    "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",
    "kind": "Identity"
    },
    {
    "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-000",
    "kind": "Identity"
    },
    {
    "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-000",
    "kind": "Identity"
    },
    {
    "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-000",
    "kind": "Identity"
    },
    {
    "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-000",
    "kind": "Identity"
    },
    {
    "key": "dictionary-79bb2f90d7ab9cef266efe53e70722dc6e4fa56372ce8cd859b89cec3ff05307",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "8f0000008b0000007b226e616d65223a20224a6f686e20446f65222c22746f6b656e5f757269223a202268747470733a5c2f5c2f7777772e626172666f6f2e636f6d222c22636865636b73756d223a202239343062666662336632626261333566383433313361613236646130396563653361643437303435633661313239326332626264326466346162316135356662227d0a20000000dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a0100000030",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-000",
    "kind": "Identity"
    },
    {
    "key": "dictionary-203953bdea81a8373a987786d74eb94d8626c401a28625bb66c006079fd2bde7",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b200000001cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d0100000030",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "dictionary-453603548bb0d677edaa9bbc014bff6e30801a8d86eb85f884ad08e874fdc0f1",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b20000000c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a0100000030",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "dictionary-3344eae47d44ef595de8219a32c69e9ac51ee14f020bd5da24f899fd49d12abf",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Any",
    "bytes": "08000000010000000000000005200000000c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f4000000032313266666464303430623635343935343139663430353763383339323933306534313066376266323462616565633864653539613631313762363365343563",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U64",
    "bytes": "0100000000000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-000",
    "kind": "Identity"
    },
    {
    "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",
    "kind": "Identity"
    },
    {
    "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",
    "kind": {
    "Write": {
    "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"
    }
    }
    },
    {
    "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",
    "kind": {
    "Write": {
    "MessageTopic": {
    "message_count": 1,
    "blocktime": 1701221761024
    }
    }
    }
    },
    {
    "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-000",
    "kind": "Identity"
    },
    {
    "key": "deploy-09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",
    "kind": {
    "Write": {
    "DeployInfo": {
    "deploy_hash": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",
    "transfers": [],
    "from": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",
    "source": "uref-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861-007",
    "gas": "610139570"
    }
    }
    }
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",
    "kind": "Identity"
    },
    {
    "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-account-a4cb74407b8da22b5dbf8cec4b2280fd2f2276bfeaa34ec64753071adf8960f5",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": "Identity"
    },
    {
    "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "04df4c7928",
    "parsed": "679038175"
    }
    }
    }
    },
    {
    "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",
    "kind": {
    "AddUInt512": "6820961825"
    }
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",
    "kind": "Identity"
    },
    {
    "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": "Identity"
    },
    {
    "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",
    "kind": "Identity"
    },
    {
    "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",
    "kind": {
    "AddUInt512": "679038175"
    }
    }
    ],
    "transfers": [],
    "cost": "610139570"
    }
    }
    },
    "messages": [
    {
    "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",
    "message": {
    "String": "{\"Mint\":{\"recipient\":\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\",\"token_id\":{\"Index\":0}}}"
    },
    "topic_name": "events",
    "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",
    "index": 0
    }
    ]
    }
    }
    +
    +

    +

    Querying global state

    +

    Emitted messages are not stored in global state. However, global state stores a checksum of each message, allowing users to verify the origin and integrity of the message. The checksums in global state are unique and can be identified by the hash of the entity that emitted the message, the hash of the topic name, and the index of the message.

    +

    You will find two types of stored values in global state:

    +
      +
    • The checksum of the message payload, as a 32-byte BLAKE2b hash of the serialized MessagePayload
    • +
    • The topic control record containing the number of messages sent on the topic and the timestamp of the block in which the messages were emitted
    • +
    +

    Message key structure

    +
    Expand to view the sample keys
    + +
    {
    "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",
    "kind": {
    "Write": {
    "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"
    }
    }
    },
    {
    "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",
    "kind": {
    "Write": {
    "MessageTopic": {
    "message_count": 1,
    "blocktime": 1701221761024
    }
    }
    }
    },
    +
    +

    +

    Here is how you can query global state to get the message checksum, given the block identifier and the composite key of the message. The message key includes the message hash, the topic name hash, and the message index.

    +
    casper-client query-global-state \
    --node-address <HOST:PORT> \
    --key [HASH_STRING] \
    --block-identifier <BLOCK_HASH> \
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777.
    • +
    • key - The identifier for the query. Use the composite key that identifies the message, i.e., message-CONTRACT_HASH-topic-name-TOPIC_HASH-MESSAGE_INDEX.
    • +
    • block-identifier - Hex-encoded block hash or height of the block.
    • +
    +

    Here is a sample query to view the message checksum:

    +
    casper-client query-global-state --node-address http://127.0.0.1:11101 \
    --key "message-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0" \
    --block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c
    +
    Expand to view the sample response
    + +
    {
    "jsonrpc": "2.0",
    "id": 3085511981091403408,
    "result": {
    "api_version": "1.0.0",
    "block_header": {
    "Version2": {
    "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",
    "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",
    "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",
    "random_bit": false,
    "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",
    "era_end": null,
    "timestamp": "2023-12-02T01:19:12.384Z",
    "era_id": 84,
    "height": 890,
    "protocol_version": "1.0.0"
    }
    },
    "stored_value": {
    "Message": "message-checksum-56098444c4f0dff8f321cfa3769d400f4b5bfa9e01e6ad6b147d81b87130bfb9"
    },
    "merkle_proof": "[1336 hex chars]"
    }
    }
    +
    +

    +

    Emitted messages are temporary by design. Sometimes, message checksums are pruned from global state to manage storage. Pruning of old message records for a particular contract only happens if the contract emits messages again in a new block. Otherwise, the last entries from the time the contract was last executed are still retained in global state. Applications can query old checksums using the state root hash of the block that contains them.

    +
    Expand to view an example
    + +
      +
    • Let's assume we have a contract that executes in a block with block time 1 and emits 100 messages.
    • +
    • If we query the global state at the root hash of the block with block time 1, then we will see a control struct for the topic indicating message count 100 and block time 1.
    • +
    • Let's assume the contract executes in another block with block time 2 and emits 50 messages.
    • +
    • Then, if we query the global state at the root hash of the block at block time 2, we will see message count 50 and block time 2.
    • +
    • Let's assume 3 blocks go by, and the contract doesn't execute in those blocks (block time 3, 4, 5).
    • +
    • If we query the global state at the root hash of the block at block time 5, we will see message count 50 and block time 2.
    • +
    +
    +

    Here is how you can determine the number of messages emitted in a particular block:

    +
    casper-client query-global-state \
    --node-address <HOST:PORT> \
    --key [HASH_STRING] \
    --block-identifier <BLOCK_HASH> \
    +

    The arguments used above are:

    +
      +
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777.
    • +
    • key - The identifier for the query. Use the composite key that identifies the message topic, e.g., message-topic-CONTRACT_HASH-topic-name-TOPIC_HASH.
    • +
    • block-identifier - Hex-encoded block hash or height of the block.
    • +
    +

    Here is a sample query to view the message topic:

    +
    casper-client query-global-state --node-address http://127.0.0.1:11101 \
    --key "message-topic-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1" \
    --block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c
    +
    Expand to view the sample response
    + +
    {
    "jsonrpc": "2.0",
    "id": 1227453659579324378,
    "result": {
    "api_version": "1.0.0",
    "block_header": {
    "Version2": {
    "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",
    "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",
    "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",
    "random_bit": false,
    "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",
    "era_end": null,
    "timestamp": "2023-12-02T01:19:12.384Z",
    "era_id": 84,
    "height": 890,
    "protocol_version": "1.0.0"
    }
    },
    "stored_value": {
    "MessageTopic": {
    "message_count": 1,
    "blocktime": 1701479952384
    }
    },
    "merkle_proof": "[1288 hex chars]"
    }
    }
    +
    +

    +
    note

    The message payload cannot be reconstructed by reading the entry from global state since that entry contains only the checksum of the messages sent.

    +

    Costs and Chainspec Settings

    +

    The following chainspec settings manage the cost of contract-level messages. These limits are bundled into the Wasm configuration settings under the wasm.messages_limits. Consult the chainspec of the network you are working with, as the following are only examples.

    +
    [wasm.messages_limits]
    # Maximum size of the topic name.
    max_topic_name_size = 256
    # Maximum number of topics that can be added for each contract.
    max_topics_per_contract = 128
    # Maximum size in bytes of the serialized message payload.
    max_message_size = 1_024
    +

    Since contract-level messages are handled through FFIs, the gas cost related to using the new interface is captured in the wasm.host_function_costs chainspec settings:

    +
    [wasm.host_function_costs]
    manage_message_topic = { cost = 200, arguments = [0, 0, 0, 0] }
    emit_message = { cost = 200, arguments = [0, 0, 0, 0] }
    cost_increase_per_message = 50
    +

    The cost_increase_per_message setting increases the gas cost for each subsequent message when emitting multiple messages within a single execution. In the example above, within a single execution, the first message will cost 200 motes, the second will cost 250 motes, and so on. Each subsequent call will increase the gas cost by the value specified under the cost_increase_per_message setting. The subsequent execution will start from the base cost specified in the emit_message setting; in this case, the following execution will start at 200 motes.

    +

    Storage is charged based on the wasm.storage_costs.gas_per_byte chainspec parameter. +When a new topic is added, two records are written in global state: the topic control record and the addressable entity record extended with the new topic name and topic name hash. Because the topic name is variable, the cost depends on the length of the topic name. +When a message is emitted, two records are written in global state: the topic control record and the message checksum. Writing these records incurs a fixed cost based on gas_per_byte.

    +

    Topic Management during Contract Upgrades

    +

    When a new contract version is added to the contract package, the message topics registered from the previous version are automatically carried over to the new contract. A new control record will be written for each topic for the new contract version.

    +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/factory-pattern/index.html b/2.0.0/developers/writing-onchain-code/factory-pattern/index.html new file mode 100644 index 000000000..8797d5fcc --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/factory-pattern/index.html @@ -0,0 +1,67 @@ + + + + + +Factory Contracts | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Writing Contracts using the Factory Pattern

    +

    This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.

    +

    The factory pattern is a widely recognized software design concept used in various programming contexts. DApp developers may use factory implementations to create smart contracts from a given source (or factory), such as a factory method or entry point. A factory pattern ensures that the contracts produced maintain a specified behavior, such as specific entry points and arguments. In general, factories produce other smart contracts according to a template.

    +

    Casper factories are created using the entry point type called EntryPointType::Install, which marks an entry point as a factory method responsible for creating and installing contracts on the chain. An installer entry point will derive new Wasm based on the original session Wasm and create a new contract with different sets of entry points as required. In other words, these installer entry points marked with EntryPointType::Install are the contract factories. When referring to the factory contract on this page, we mean the contract containing the factory entry points.

    +

    The EntryPointAccess::Template marks an entry point that exists in the bytecode but is not callable. Thus, regular entry points can be referenced from within installer entry points marked with EntryPointType::Install. In object-oriented terms, entry points marked with EntryPointAccess::Template act as virtual abstract methods and cannot be called from session code.

    +
    note

    This factory pattern poses a known drawback when using Wasm. All the smart contracts created with the factory pattern share the same Wasm installed on the chain. Thus, developers cannot modify the Wasm once installed and create modified contracts using the factory pattern. Developers must specify all the possible entry points in the parent contract and tag them with the EntryPointAccess::Template marker.

    +

    The Counter Factory Example

    +

    This section dives into a simple counter that uses factory methods to describe how to implement the factory pattern on a Casper network. The Counter on the Testnet Tutorial demonstrates the non-factory version of the counter contract.

    +

    Let's start by exploring the session code, where the contract entry points are defined.

    +

    Two installer entry points are marked with EntryPointType::Install, meaning these entry points will produce new counter contracts once this Wasm is installed in global state. They are also marked with EntryPointAccess::Public so that they can be called from the session code.

    +
    let entry_point: EntryPoint = EntryPoint::new(
    CONTRACT_FACTORY_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Install,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    CONTRACT_FACTORY_DEFAULT_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Install,
    );
    +

    These two installers show how to declare multiple factory entry points and use them to initialize the Wasm they produce with different values. On line 61, the contract_factory entry point creates a counter contract with a given name and initial value.

    +
    #[no_mangle]
    pub extern "C" fn contract_factory() {
    let name: String = runtime::get_named_arg(ARG_NAME);
    let initial_value: U512 = runtime::get_named_arg(ARG_INITIAL_VALUE);
    installer(name, initial_value);
    }
    +

    On line 68, the contract_factory_default entry point creates a counter contract with a given name and a zero initial value.

    +
    #[no_mangle]
    pub extern "C" fn contract_factory_default() {
    let name: String = runtime::get_named_arg(ARG_NAME);
    installer(name, U512::zero());
    }
    +
    note

    The factory pattern can produce contracts with different entry points. Suppose the session code defines entry points A, B, C, and D as templates. One installer factory entry point could use entry points A and B to create a contract, and the other installer entry point might use entry points C and D. Such support at the API level enables the implementation of more complex use cases.

    +

    The installer function creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's decrement and increment functionality. These entry points are defined just like in any other smart contract, with EntryPointAccess::Public and EntryPointType::Contract, and they are callable for all the counters created. To learn how to call the increment and decrement functions, see the Counter on the Testnet Tutorial, which is the non-factory version of the counter contract.

    +
    Sample installer code for a counter factory
    + +
    fn installer(name: String, initial_value: U512) {
    let named_keys = {
    let new_uref = storage::new_uref(initial_value);
    let mut named_keys = NamedKeys::new();
    named_keys.insert(CURRENT_VALUE_KEY.to_string(), new_uref.into());
    named_keys
    };

    let entry_points = {
    let mut entry_points = EntryPoints::new();
    let entry_point: EntryPoint = EntryPoint::new(
    INCREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    DECREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);

    entry_points
    };

    let (contract_hash, contract_version) = storage::new_contract(
    entry_points,
    Some(named_keys),
    Some(PACKAGE_HASH_KEY_NAME.to_string()),
    Some(ACCESS_KEY_NAME.to_string()),
    );

    runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());
    runtime::put_key(&name, contract_hash.into());
    }
    +
    +

    It is important to note that the installer logic saves the newly created contract version and contract hash under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the comparison between session and contract context.

    +
    runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());
    runtime::put_key(&name, contract_hash.into());
    +

    For example, if you install the factory counter contract, you will see only one named key for this contract in your account, with the two installer entry points contract_factory and contract_factory_default. See lines 155-163.

    +

    If you call the installer three times to create 3 different counters, you will see 3 named keys for each counter in the factory contract's named keys. The counter contracts produced will have the increment and decrement entry points.

    +

    As explained above, developers must define all the possible non-installer entry points in the factory contract and tag them with the EntryPointAccess::Template and EntryPointType::Contract markers. See lines 135-139:

    +
    let entry_point: EntryPoint = EntryPoint::new(
    INCREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Template,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    DECREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Template,
    EntryPointType::Contract,
    );
    +
    warning

    Suppose developers forget to declare an entry point in the outermost session logic (the call function) and mark it with EntryPointAccess::Template; that Wasm export will be removed when the factory contract is installed in global state. Creating the entry point in the installer logic is not sufficient.

    +

    Unit tests

    +

    Developers can test contracts that follow the factory pattern using the Casper testing framework described under Unit Testing Smart Contracts. The testing process is the same, but this section highlights a particular test called should_install_and_use_factory_pattern found in the unit test suite of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior.

    +

    On line 120, the test starts building a request to call the contract_factory entry point with counter name new-counter-1 and value 1. On line 134, the test calls another factory entry point called contract_factory_default with counter name new-counter-2. The default counter value is 0.

    +

    Once the requests are processed, the test checks the contract hashes of the contracts created:

    + +

    The test proceeds to get the contract Wasm for each counter produced and test the Wasm exports, which are the increment and decrement entry points in each counter contract.

    +

    The setup function on line 209 is a helper function for installing the factory contract on the chain and getting the contract factory hash.

    +

    The other tests in this file are also interesting:

    + +

    What's Next?

    +
    + + \ No newline at end of file diff --git a/next/developers/writing-onchain-code/getting-started/index.html b/2.0.0/developers/writing-onchain-code/getting-started/index.html similarity index 57% rename from next/developers/writing-onchain-code/getting-started/index.html rename to 2.0.0/developers/writing-onchain-code/getting-started/index.html index 640caeb6a..2ff6bf241 100644 --- a/next/developers/writing-onchain-code/getting-started/index.html +++ b/2.0.0/developers/writing-onchain-code/getting-started/index.html @@ -1,23 +1,23 @@ - + -Getting Started with Rust | Casper Docs - Redux +Getting Started with Rust | Casper Docs - Redux - - + +
    Version: Next

    Getting Started with Rust Casper Contracts

    + submit an issue on Github
    Version: 2.0.0

    Getting Started with Rust Casper Contracts

    This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.

    -

    Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described here.

    +

    Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described here.

    Creating a Project

    You can create a new sample project very easily with the cargo casper crate. For example, let's say that I want to create a project named my-project for this tutorial (you can choose a different name if you wish), then I can simply run the command:

    cargo casper my-project
    @@ -41,7 +41,7 @@

    casper-types - a library with types we use across the Rust ecosystem.

    A crate is a compilation unit that can be compiled into a binary or a library.

    -
    note

    For a comprehensive list of crates, visit the Essential Casper Crates page.

    +
    note

    For a comprehensive list of crates, visit the Essential Casper Crates page.

    Available API documentation

    Each of the Casper crates comes with API documentation and examples for each function, located at https://docs.rs. The latest contract API documentation can be found here.

    Compiling to Wasm

    @@ -75,6 +75,6 @@

    Rust Resource
  • https://doc.rust-lang.org/book/foreword.html
  • https://rustwasm.github.io/docs/book/
  • https://doc.rust-lang.org/stable/rust-by-example
  • -

    +
    \ No newline at end of file diff --git a/next/developers/writing-onchain-code/simple-contract/index.html b/2.0.0/developers/writing-onchain-code/simple-contract/index.html similarity index 85% rename from next/developers/writing-onchain-code/simple-contract/index.html rename to 2.0.0/developers/writing-onchain-code/simple-contract/index.html index 9fdbfdc0b..bb470c961 100644 --- a/next/developers/writing-onchain-code/simple-contract/index.html +++ b/2.0.0/developers/writing-onchain-code/simple-contract/index.html @@ -1,27 +1,27 @@ - + -Writing a Basic Smart Contract in Rust | Casper Docs - Redux +Writing a Basic Smart Contract in Rust | Casper Docs - Redux - - + +
    Version: Next

    Writing a Basic Smart Contract in Rust

    + submit an issue on Github
    Version: 2.0.0

    Writing a Basic Smart Contract in Rust

    What is a Smart Contract?

    -

    A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a transaction. Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic.

    +

    A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a transaction. Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic.

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended.

    Key Features of Casper Contracts

    -

    On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be sent to a node on a Casper network using a transaction. Nodes within the network then gossip transactions, include them within a block, and finalize them. After finalizing, the network executes the transactions within the block.

    -

    Further, the Casper platform allows for upgradable contracts. A ContractPackage is created through the new_contract or new_locked_contract methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ContractPackageHash. The new contract is added to this package with a ContractHash key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable.

    +

    On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be sent to a node on a Casper network using a transaction. Nodes within the network then gossip transactions, include them within a block, and finalize them. After finalizing, the network executes the transactions within the block.

    +

    Further, the Casper platform allows for upgradable contracts. A ContractPackage is created through the new_contract or new_locked_contract methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ContractPackageHash. The new contract is added to this package with a ContractHash key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable.

    The new_contract and new_locked_contract methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract.

    The contract contains required metadata, and it is primarily identified by its ContractHash. While the contract hash identifies a specific ContractVersion, the ContractPackageHash serves as an identifier for the most recent contract version in the contract package.

    Creating the Directory Structure

    @@ -29,7 +29,7 @@

    Creating
    project-directory/

    └── contract/
    ├── src/
    └── main.rs
    └── Cargo.toml

    └── Makefile
    └── rust-toolchain

    └── tests/
    ├── src/
    └── integration-tests.rs
    └── Cargo.toml

    The project structure would be different in a dApp with full-stack architecture.

    Automatically using cargo casper

    -

    The cargo casper command can automatically set up the project structure. This is the recommended way of setting up a new Casper project.

    +

    The cargo casper command can automatically set up the project structure. This is the recommended way of setting up a new Casper project.

    cargo casper my-project

    The cargo casper command will generate an example contract in the contract directory and an example tests crate with logic defined in the integration-tests.rs file. The Makefile includes commands to prepare and build the contract, and the rust-toolchain file specifies the target build version of Rust.

    Semi-automatically using plain cargo

    @@ -56,7 +56,7 @@

    main.rs - This file would store the unit test code required to test the contract. You can rename the file to integration-tests.rs as shown in the example structure.
  • Cargo.toml - This is the file with test configurations.
  • -

    The Testing Smart Contracts guide explains how to update the tests using example code.

    +

    The Testing Smart Contracts guide explains how to update the tests using example code.

  • Unlike cargo casper, cargo does not create a Makefile and rust-toolchain configuration file. Therefore, you must manually add these files to the project's root folder.

    @@ -127,7 +127,7 @@

    // Creating constants for values within the contract package.
    const CONTRACT_PACKAGE_NAME: &str = "counter_package_name";
    const CONTRACT_ACCESS_UREF: &str = "counter_access_uref";

    // Creating constants for the various contract entry points.
    const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";
    const ENTRY_POINT_COUNTER_GET: &str = "counter_get";

    // Creating constants for values within the contract.
    const CONTRACT_VERSION_KEY: &str = "version";
    const CONTRACT_KEY: &str = "counter";
    const COUNT_KEY: &str = "count";

  • Defining the contract entry points

    -

    Entry points provide access to contract code installed in global state. Either session code or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program.

    +

    Entry points provide access to contract code installed in global state. Either session code or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program.

    Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the transaction. Note that another smart contract may access any of these entry points.

    If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded.

    When defining entry points, begin with a #[no_mangle] line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable.

    @@ -197,7 +197,7 @@

    Comp

    For the counter example, in the project directory where the Makefile is, run the following commands:

    make prepare
    make build-contract

    Executing Contract Code

    -

    Contract execution must be initiated through an outside call, usually via session code or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section.

    +

    Contract execution must be initiated through an outside call, usually via session code or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section.

    Video Walkthrough

    The following brief video accompanies this guide.

    @@ -205,9 +205,9 @@

    Video Walk

    What's Next?

    +
  • Learn to test your contract.
  • +
  • Understand session code and how it triggers a smart contract.
  • +
  • Learn to install a contract and query global state with the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/next/developers/writing-onchain-code/testing-contracts/index.html b/2.0.0/developers/writing-onchain-code/testing-contracts/index.html similarity index 79% rename from next/developers/writing-onchain-code/testing-contracts/index.html rename to 2.0.0/developers/writing-onchain-code/testing-contracts/index.html index a74c6dced..114f134e1 100644 --- a/next/developers/writing-onchain-code/testing-contracts/index.html +++ b/2.0.0/developers/writing-onchain-code/testing-contracts/index.html @@ -1,26 +1,26 @@ - + -Testing Smart Contracts | Casper Docs - Redux +Testing Smart Contracts | Casper Docs - Redux - - + +
    Version: 2.0.0

    Testing Smart Contracts

    Introduction

    As part of the Casper development environment, we provide a testing framework to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful transactions and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated.

    note

    The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework.

    Defining Dependencies in Cargo.toml

    -

    This guide uses the project structure, and example contract outlined here for creating tests.

    +

    This guide uses the project structure, and example contract outlined here for creating tests.

    To begin, outline the required test dependencies in the /tests/Cargo.toml file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:

    [dependencies]
    casper-execution-engine = "2.0.1"
    casper-engine-test-support = { version = "2.2.0", features = ["test-support"] }
    casper-types = "1.5.0"
      @@ -34,7 +34,7 @@

      Writing th

      The #[cfg(test)] attribute tells the Rust compiler to compile and run the tests only when invoking cargo test, not while debugging or releasing. All testing functions reside within the grouping mechanism mod tests.

      #[cfg(test)]
      mod tests {
      // The entire test program resides here
      }

      Importing Builders and Constants

      -

      Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any CLTypes used within the contract code to be tested.

      +

      Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any CLTypes used within the contract code to be tested.

          // Outlining aspects of the Casper test support crate to include.
      use casper_engine_test_support::{
      ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
      DEFAULT_RUN_GENESIS_REQUEST,
      };
      // Custom Casper types that will be used within this test.
      use casper_types::{runtime_args, ContractHash, RuntimeArgs};

      Next, you need to define any global variables or constants for the test.

          const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract
      const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract
      const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract

      const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract
      const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement
      const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package

      const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value
      const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value
      @@ -52,7 +52,7 @@

      Next, we test an entry point that should not exist in the first version of the contract.

          // Call the decrement entry point, which should not be in version 1 before the upgrade.
      let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(
      *DEFAULT_ACCOUNT_ADDR,
      contract_v1_hash,
      ENTRY_POINT_COUNTER_DECREMENT,
      runtime_args! {},
      )
      .build();

      // Try executing the decrement entry point and expect an error.
      builder
      .exec(contract_decrement_request)
      .expect_failure()
      .commit();

      Calling the Contract using Session Code

      -

      In the counter example, we use the session code included in the counter-call.wasm file. For more details on what session code is and how it differs from contract code, see the next section.

      +

      In the counter example, we use the session code included in the counter-call.wasm file. For more details on what session code is and how it differs from contract code, see the next section.

      The following session code uses the contract hash to identify the contract, the account for sending the transaction (DEFAULT_ACCOUNT_ADDR), the transaction to be sent (COUNTER_CALL_WASM), and the runtime arguments required. Once again, the ExecuteRequestBuilder simulates the execution of session code and calls the counter-inc entry point.

          // Use session code to increment the counter.
      let session_code_request = ExecuteRequestBuilder::standard(
      *DEFAULT_ACCOUNT_ADDR,
      COUNTER_CALL_WASM,
      runtime_args! {
      CONTRACT_KEY => contract_v1_hash
      },
      )
      .build();

      builder.exec(session_code_request)
      .expect_success()
      .commit();

      Evaluating and Comparing Results

      @@ -61,7 +61,7 @@

      casper-node GitHub repository.

      Testing Contracts that Call Contracts

      If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the DEFAULT_RUN_GENESIS_REQUEST. The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include.

      -

      Each contract installation will require an additional Wasm file installed through a Transaction using ExecuteRequestBuilder. Depending on your requirements as a smart contract author, you may need to use return values to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously.

      +

      Each contract installation will require an additional Wasm file installed through a Transaction using ExecuteRequestBuilder. Depending on your requirements as a smart contract author, you may need to use return values to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously.

      The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ExecuteRequestBuilder. Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:

    +
  • Understand session code and how it triggers a smart contract.
  • +
  • Learn to install a contract and query global state with the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/next/developers/writing-onchain-code/testing-session-code/index.html b/2.0.0/developers/writing-onchain-code/testing-session-code/index.html similarity index 75% rename from next/developers/writing-onchain-code/testing-session-code/index.html rename to 2.0.0/developers/writing-onchain-code/testing-session-code/index.html index 511819f87..a4c67cff1 100644 --- a/next/developers/writing-onchain-code/testing-session-code/index.html +++ b/2.0.0/developers/writing-onchain-code/testing-session-code/index.html @@ -1,22 +1,22 @@ - + -Testing Session Code | Casper Docs - Redux +Testing Session Code | Casper Docs - Redux - - + +
    Version: Next

    Testing Session Code

    -

    This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.

    + submit an issue on Github
    Version: 2.0.0

    Testing Session Code

    +

    This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.

    Specifying Dependencies in Cargo.toml

    The Cargo.toml sample file in the tests directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:

    [dev-dependencies]
    casper-engine-test-support = { version = "2.2.0", features = ["test-support"] }
    casper-execution-engine = "2.0.0"
    casper-types = "1.5.0"
    @@ -87,7 +87,7 @@

    Video Walk

    What's Next?

    +
  • Learn to install a contract and query global state.
  • +
    \ No newline at end of file diff --git a/2.0.0/developers/writing-onchain-code/upgrading-contracts/index.html b/2.0.0/developers/writing-onchain-code/upgrading-contracts/index.html new file mode 100644 index 000000000..3c0bd7f6e --- /dev/null +++ b/2.0.0/developers/writing-onchain-code/upgrading-contracts/index.html @@ -0,0 +1,41 @@ + + + + + +Upgrading and Maintaining Smart Contracts | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Upgrading and Maintaining Smart Contracts

    +

    Our smart contract packaging tools enable you to:

    +
      +
    • Upgrade your contracts and specify how the state of the contract is managed
    • +
    • Specify whether a contract is upgradable or immutable
    • +
    • 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. If you find that you need to use a disabled contract version, you may also re-enable it.

    +

    Package Representation

    +

    The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain.

    +

    Videos and Tutorials

    +

    To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the Writing On-Chain Code documentation.

    +

    + +

    +

    Or, for a different perspective, consult the Smart Contract Upgrade Tutorial.

    +

    Maintaining a Contract

    +

    The contract maintenance process is generally covered through the contract upgrade process.

    +

    Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance.

    +

    On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process.

    + + \ No newline at end of file diff --git a/next/developers/writing-onchain-code/writing-session-code/index.html b/2.0.0/developers/writing-onchain-code/writing-session-code/index.html similarity index 71% rename from next/developers/writing-onchain-code/writing-session-code/index.html rename to 2.0.0/developers/writing-onchain-code/writing-session-code/index.html index 96883bf33..f4ca7c6c8 100644 --- a/next/developers/writing-onchain-code/writing-session-code/index.html +++ b/2.0.0/developers/writing-onchain-code/writing-session-code/index.html @@ -1,26 +1,26 @@ - + -Writing Session Code | Casper Docs - Redux +Writing Session Code | Casper Docs - Redux - - + +
    Version: Next

    Writing Session Code

    -

    This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.

    + submit an issue on Github
    Version: 2.0.0

    Writing Session Code

    +

    This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.

    Creating the Directory Structure

    -

    For writing session code, we use the same project structure used for writing contracts, described here.

    +

    For writing session code, we use the same project structure used for writing contracts, described here.

    Example 1: Writing Session Code

    -

    The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: https://github.com/casper-ecosystem/two-party-multi-sig/. The sample code adds an associated key to the account and updates the action thresholds. Remember that an Account on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository.

    +

    The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: https://github.com/casper-ecosystem/two-party-multi-sig/. The sample code adds an associated key to the account and updates the action thresholds. Remember that an Account on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository.

    git clone https://github.com/casper-ecosystem/two-party-multi-sig/
    note

    Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious.

    Dependencies in Cargo.toml

    @@ -65,15 +65,15 @@

    Compi

    For the examples above, you may use the Makefiles provided:

    make build-contract

    Executing Session Code

    -

    Before running session code on a live Casper network, test it as described here. You can also set up a local network using NCTL for additional tests.

    -

    Session code can execute on a Casper network via a Deploy. All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state.

    -

    The Casper command-line client and its put-deploy command provide one way to execute session code.

    +

    Before running session code on a live Casper network, test it as described here. You can also set up a local network using NCTL for additional tests.

    +

    Session code can execute on a Casper network via a Deploy. All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state.

    +

    The Casper command-line client and its put-deploy command provide one way to execute session code.

    casper-client put-deploy \
    --node-address <HOST:PORT> \
    --chain-name <NETWORK-NAME> \
    --secret-key <PATH> \
    --payment-amount <PAYMENT-AMOUNT> \
    --session-path <SESSION-PATH> \
    --session-arg <"NAME:TYPE='VALUE'" OR "NAME:TYPE=null">
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777.
    • secret-key - The file name containing the secret key of the account paying for the deploy.
    • chain-name - The network where the deploy should be sent. For Mainnet, use casper. For Testnet, use casper-test.
    • -
    • payment-amount - Payment for the deploy in motes. The payment amount varies based on the deploy and network chainspec.
    • +
    • payment-amount - Payment for the deploy in motes. The payment amount varies based on the deploy and network chainspec.
    • session-path - Path to the contract Wasm, pointing to the compiled contract.
    • session-arg - A named and typed argument passed to the Wasm code.
    @@ -86,7 +86,7 @@

    Video Walk

    What's Next?

    +
  • Learn to test session code using the Casper testing framework.
  • +
    \ No newline at end of file diff --git a/2.0.0/disclaimer/index.html b/2.0.0/disclaimer/index.html new file mode 100644 index 000000000..323e24cf9 --- /dev/null +++ b/2.0.0/disclaimer/index.html @@ -0,0 +1,77 @@ + + + + + +Disclaimer | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Disclaimer

    +

    By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.

    +

    Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR”). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.

    +

    This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO”) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA”) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA”) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.

    +

    The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC”). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.

    +

    The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required.

    +

    No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient’s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature.

    +

    Preliminary Nature of this Whitepaper

    +

    This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA”). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.

    +

    Forward-Looking Statements

    +

    This Whitepaper includes "forward-looking statements”, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe”, "anticipate”, "expect”, "project”, "estimate”, "predict”, "intend”, "target”, "assume”, "may”, "might”, "could”, "should”, "will” and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG’s and/or any of its affiliates’ present and future expectations regarding the development of the Casper blockchain and the associated software.

    +

    These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG’s and/or any of its affiliates’ expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based.

    +

    Risk Factors

    +

    Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient”) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.

    +
      +
    • +

      Risks associated with CasperLabs Networks AG’s experience: the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain.

      +
    • +
    • +

      Risks associated with CSPR relative value: the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available).

      +
    • +
    • +

      Risks associated with (intellectual) property rights: the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR.

      +
    • +
    • +

      Risks associated with blockchain: the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events.

      +
    • +
    • +

      Risk of weaknesses in the field of cryptography: the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued).

      +
    • +
    • +

      Regulatory risks: the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient.

      +
    • +
    • +

      Risks associated with abandonment / lack of success: the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued).

      +
    • +
    • +

      Risks associated with a loss of private key: the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient’s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient’s account (address) will be unrecoverable and will be permanently lost.

      +
    • +
    • +

      Risks associated with wallets: the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider.

      +
    • +
    • +

      Risks associated with theft/hacks: the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain.

      +
    • +
    • +

      Risks associated with mining attacks: the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations.

      +
    • +
    • +

      Risks associated with a lack of consensus: the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value.

      +
    • +
    • +

      Risks associated with liquidity of CSPR: the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient.

      +
    • +
    • +

      Risks associated with forking: the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient’s CSPR (if and when created and/or issued).

      +
    • +
    + + \ No newline at end of file diff --git a/2.0.0/economics/index.html b/2.0.0/economics/index.html new file mode 100644 index 000000000..3f3b6a413 --- /dev/null +++ b/2.0.0/economics/index.html @@ -0,0 +1,51 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Overview of Casper Economics

    +

    Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.

    +

    This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active.

    +

    Consensus

    +

    The consensus layer of the Casper Mainnet runs the Zug consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

    +

    When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.

    +

    Agents (consensus layer)

    +

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain's security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.

    +

    Delegators are users who participate in the platform's security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    +

    Incentives (consensus layer)

    +

    The auction determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.

    +

    Rewards (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator.

    +

    Evictions deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract.

    +

    Runtime

    +

    The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to metering computing time, measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost.

    +

    The Mainnet transaction selection mechanism is based on FIFO.

    +

    We expect to continue to work on runtime resource markets.

    +

    Agents (runtime layer)

    +

    Validators again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain.

    +

    Users execute session and contract code using the platform's computational resources

    +

    Incentives (runtime layer)

    +

    The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a fee elimination model by default, setting the no_fee,no_refund, and fixed pricing configurations in the network's chainspec.

    +

    The no_fee mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.

    +

    The no_refund mode means no refund is handled when fees are eliminated.

    +

    Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes here.

    +

    When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations.

    +

    The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, private networks can set their fee, refund, and pricing strategies.

    +

    Ecosystem

    +

    The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps.

    +

    Macroeconomy

    +

    Casper's macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.

    +

    The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain.

    + + \ No newline at end of file diff --git a/2.0.0/glossary/index.html b/2.0.0/glossary/index.html new file mode 100644 index 000000000..f7ea717e3 --- /dev/null +++ b/2.0.0/glossary/index.html @@ -0,0 +1,24 @@ + + + + + +Glossary | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Glossary

    +

    These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.

    +
    +

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    +
    + + \ No newline at end of file diff --git a/2.0.0/index.html b/2.0.0/index.html new file mode 100644 index 000000000..7493a9005 --- /dev/null +++ b/2.0.0/index.html @@ -0,0 +1,27 @@ + + + + + +Welcome to the official Casper documentation | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Welcome to the official Casper documentation

    What is Casper?

    +

    Casper is a smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    +

    How to use this documentation portal

    + + +

    The Nav bar is arranged along the top of your browser window, and may be broken down into left and right. On the left hand side, you will see 5 links, each of which corresponds to a sidebar. There are 5 Sidebars, each of which contains links to content broken down by subject area within the documentation.

    +

    Disclaimer

    +

    Legal Disclaimer.

    + + \ No newline at end of file diff --git a/next/operators/becoming-a-validator/bonding/index.html b/2.0.0/operators/becoming-a-validator/bonding/index.html similarity index 75% rename from next/operators/becoming-a-validator/bonding/index.html rename to 2.0.0/operators/becoming-a-validator/bonding/index.html index c9537da23..8cee7e2da 100644 --- a/next/operators/becoming-a-validator/bonding/index.html +++ b/2.0.0/operators/becoming-a-validator/bonding/index.html @@ -1,21 +1,21 @@ - + -Bonding | Casper Docs - Redux +Bonding | Casper Docs - Redux - - + +
    Version: Next

    Bonding as a Validator

    + submit an issue on Github
    Version: 2.0.0

    Bonding as a Validator

    It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.

    In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, the time for bid submission to inclusion in the validator set is a minimum of six hours. Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship.

    Method 1: Bonding with the System Auction Contract

    @@ -50,7 +50,7 @@

    Metho
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point add_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg "delegation_rate:u8='10'"

    Next, check the status of the auction to see if you have won a validator slot.

    Method 2: Bonding with Compiled Wasm

    -

    Another way to send a bonding transaction to the network is via a deploy containing the compiled add_bid.wasm. For details, refer to Building the Required Contracts.

    +

    Another way to send a bonding transaction to the network is via a deploy containing the compiled add_bid.wasm. For details, refer to Building the Required Contracts.

    The following deploy is a template for sending a bonding request:

    sudo -u casper casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg "public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg "amount:u512='<BID-AMOUNT>'" \
    --session-arg "delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    --session-arg "minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'"
    --session-arg "maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'"
      @@ -71,7 +71,7 @@

      Method

      The command will return a deploy hash, which is needed to verify the deploy's processing results.

      note

      This method is more expensive than calling the add_bid entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.

      Example:

      -

      Here is an example request to bond using the add_bid.wasm. The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

      +

      Here is an example request to bond using the add_bid.wasm. The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

      sudo -u casper casper-client put-deploy \
      --node-address http://65.21.235.219:7777 \
      --secret-key /etc/casper/validator_keys/secret_key.pem \
      --chain-name casper-test \
      --payment-amount 3000000000 \
      --session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
      --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
      --session-arg "amount:U512='$[10000 * 1000000000]'" \
      --session-arg "delegation_rate:u8='10'"

      Next, check the bid status to see if you have won a validator slot.

      Checking the Bid Status

      @@ -88,8 +88,8 @@

      A Losing Bid

      If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding.

      Avoiding Ejection

      -

      To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details here.

      +

      To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details here.

      Withdrawing a Bid

      -

      Follow the steps in Unbonding to withdraw a bid.

    +

    Follow the steps in Unbonding to withdraw a bid.

    \ No newline at end of file diff --git a/2.0.0/operators/becoming-a-validator/change-bid-public-key/index.html b/2.0.0/operators/becoming-a-validator/change-bid-public-key/index.html new file mode 100644 index 000000000..43d8261c6 --- /dev/null +++ b/2.0.0/operators/becoming-a-validator/change-bid-public-key/index.html @@ -0,0 +1,80 @@ + + + + + +Change bid public key | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Changing the Public Key Associated with a Validator Bid

    +

    The public key associated with a given validator bid can be changed through the auction contract's change_bid_public_key entry point.

    +

    An example of this functionality would be to transfer ownership of a validator "slot" to a different party or to migrate a node to a backup server. By leveraging the system contract we can perform those operations more securely by making sure that no private key files need to be copied or transmitted between servers.

    +

    When the public key is changed all relevant delegations are also changed to be associated with the updated validator bid.

    +

    Prerequisites

    +

    For a public key change to be performed successfully there must not exist a validator bid associated with the target public key.

    +

    Method 1: Calling the system auction contract's change_bid_public_key entry point

    +

    The public key associated with a given bid can be changed by calling the change_bid_public_key entry point of the system auction contract. Using this method, you do not need to build any contracts, which reduces costs and complexity.

    +
    sudo -u casper casper-client put-txn \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point change_bid_public_key \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="new_public_key:public_key='<PUBLIC_KEY_HEX>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777.
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Transaction.
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Transaction. For Mainnet, use casper. For Testnet, use casper-test.
    6. +
    7. payment-amount - The payment for the Transaction in motes. This entry point call needs 5 CSPR.
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entrypoint that will be used when calling the contract.
    2. +
    +

    The change_bid_public_key entry point expects two arguments:

    +
      +
    1. public key: The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction.
    2. +
    3. new_public key: The hexadecimal public key intended to replace the original key associated with the bid.
    4. +
    +

    The command will return a transaction hash, which is needed to verify the transaction's processing results.

    +
    note

    Calling the change_bid_public_key entry point on the auction contract has a fixed cost of 5 CSPR.

    +

    Method 2: Using compiled WASM

    +

    You may also change the public key associated with a bid via a transaction containing the compiled change_bid_public_key.wasm binary. For details, refer to Building the Required Contracts.

    +

    The following transaction is a template for sending a request:

    +
    sudo -u casper casper-client put-txn session \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \
    --pricing-mode fixed \
    --gas-price-tolerance <GAS_PRICE_TOLERANCE> \
    --transaction-path $HOME/casper-node/target/wasm32-unknown-unknown/release/change_bid_public_key.wasm \
    --session-entry-point call \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="new_public_key:public_key='<PUBLIC_KEY_HEX>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777.
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Transaction.
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Transaction. For Mainnet, use casper. For Testnet, use casper-test.
    6. +
    7. gas-price-tolerance - Maximum payment for the Transaction in motes.
    8. +
    9. transaction-path - The path to the compiled Wasm on your computer.
    10. +
    +

    The change_bid_public_key.wasm expects two arguments:

    +
      +
    1. public key: The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction.
    2. +
    3. new_public key: The hexadecimal public key intended to replace the original key associated with the bid.
    4. +
    +

    The command will return a transaction hash, which is needed to verify the transaction's processing results.

    +
    note

    This method is more expensive than calling the change_bid_public_key entrypoint in the system auction contract, which has a fixed cost of 5 CSPR.

    +

    Bridge records

    +

    In order to continue handling pending unbonds and rewards distribution even if the public key associated with a validator bid has changed, we use dedicated Bridge records. These records connect the original public key to the new public key. By following those records we are able to find the current bid even if the public key was changed multiple times.

    +

    Limitations

    +

    Due to the way the Bridge record mechanism works there are some limitations regarding changing public keys to keep in mind:

    +
      +
    • Because the Bridge record replaces the original bid, it's not possible to then change the public key back to the original value, since it would create a loop
    • +
    • To avoid unbounded computation we also limit the number of Bridge records that can be processed in sequence to 20, which means that: +
        +
      • For unbonding or redelegation requests, if a validator bid public key is changed more than 20 times between the time a request is created and processed, the funds will be returned to a delegator's main purse
      • +
      • For rewards distribution if the public key changes more than 20 times between the point a validator was elected for a given era and when the rewards are distributed, those rewards will be skipped and not distributed
      • +
      +
    • +
    + + \ No newline at end of file diff --git a/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/index.html b/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/index.html new file mode 100644 index 000000000..07e135ae6 --- /dev/null +++ b/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/index.html @@ -0,0 +1,34 @@ + + + + + +Inactive and Faulty Nodes | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Inactive vs. Faulty Validator Nodes

    +

    This page describes the differences between a validator node being considered inactive or faulty.

    +

    In the last block of each era N, the consensus algorithm checks whether there are any messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as inactive in that block.

    +

    Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as faulty in that block. Usually, that means:

    +
      +
    • If you got marked as inactive, your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed.
    • +
    • If you got marked as faulty, you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file.
    • +
    +

    The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era N. The auction determines the validator set for the era after the next (because auction_delay is set to 1 on mainnet), i.e., for era N + 2. That means you will still be a validator (with a weight proportional to your stake) in the next era, N + 1, but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder.

    +

    And even in the next era, N + 1:

    +
      +
    • If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era N + 1, it will get evicted for being offline in era N.
    • +
    • If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards.
    • +
    +

    In both cases, you remain evicted until you reactivate your bid, as described here.

    + + \ No newline at end of file diff --git a/2.0.0/operators/becoming-a-validator/index.html b/2.0.0/operators/becoming-a-validator/index.html new file mode 100644 index 000000000..c4035faf0 --- /dev/null +++ b/2.0.0/operators/becoming-a-validator/index.html @@ -0,0 +1,51 @@ + + + + + +Becoming a Validator | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Becoming a Validator

    +

    After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Bonding as a ValidatorA guide about the bonding process and submitting a bid
    Unbonding as a ValidatorThe process to withdraw a bid and unbonding
    Recovering from Validator EvictionSteps a validator needs to take if it is evicted from the validator set
    Inactive vs. Faulty NodesThe differences between inactive and faulty nodes
    Change bid public keyThe differences between inactive and faulty nodes
    + + \ No newline at end of file diff --git a/next/operators/becoming-a-validator/recovering/index.html b/2.0.0/operators/becoming-a-validator/recovering/index.html similarity index 63% rename from next/operators/becoming-a-validator/recovering/index.html rename to 2.0.0/operators/becoming-a-validator/recovering/index.html index f126c986c..605e0b03a 100644 --- a/next/operators/becoming-a-validator/recovering/index.html +++ b/2.0.0/operators/becoming-a-validator/recovering/index.html @@ -1,21 +1,21 @@ - + -Recovery | Casper Docs - Redux +Recovery | Casper Docs - Redux - - + +
    Version: Next

    Recovering from Validator Eviction

    + submit an issue on Github
    Version: 2.0.0

    Recovering from Validator Eviction

    This topic discusses the steps a validator needs to take if it is evicted from the validator set:

    1. Detecting the eviction
    2. @@ -24,7 +24,7 @@
    3. Activating the bid
    4. Checking the bid
    -

    The Inactive vs. Faulty Validator Nodes topic explains why a node would be evicted.

    +

    The Inactive vs. Faulty Validator Nodes topic explains why a node would be evicted.

    Detecting the Eviction

    The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era.

    For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era.

    @@ -36,7 +36,7 @@

    casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == "<public_key>")'

    Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:

    casper-client get-auction-info | jq --arg pk "$(cat /etc/casper/validator_keys/public_key_hex)" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'
    -

    You know you were evicted if the get-auction-info command returned your bid showing an inactive field. See the Inactive vs. Faulty Validator Nodes page for more information.

    +

    You know you were evicted if the get-auction-info command returned your bid showing an inactive field. See the Inactive vs. Faulty Validator Nodes page for more information.

    If you receive a parse error: Invalid numeric literal at, this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:

    casper-client get-auction-info

    Correcting any Underlying Node Issues

    @@ -45,7 +45,7 @@

    curl -s localhost:8888/status | jq .last_added_block_info

    If you cannot figure out the issue, ask for help in the node-tech-support channel on Discord.

    Activating the Bid

    -

    Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the activate_bid entry point from the system auction contract. The second method involves building the activate_bid.wasm contract as explained in Building the Required Contracts.

    +

    Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the activate_bid entry point from the system auction contract. The second method involves building the activate_bid.wasm contract as explained in Building the Required Contracts.

    We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet.

    Method 1: Activating the Bid with the System Auction Contract

    This method calls the existing activate_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    @@ -68,7 +68,7 @@

    Me
    1. validator_public_key: The hexadecimal public key of the validator reactivating its bid. This key must match the secret key that signs the bid activation request
    -

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the Deploy Status section for more details.

    tip

    Calling the activate_bid entry point on the auction contract has a fixed cost of 10,000 motes.

    Example:

    This example uses the Casper Testnet to reactivate a bid:

    @@ -91,11 +91,11 @@

    Met

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    note

    As described above, this method is much more expensive than calling the activate_bid entry point.

    Example:

    -

    Here is an example that reactivates a bid using the activate_bid.wasm. You must modify the payment and other values in the deploy based on your environment and the network's chainspec.toml. For example, if you use the activate_bid.wasm on a network with node version 1.4.9, you will require a balance of at least 5 CSPR for this contract.

    +

    Here is an example that reactivates a bid using the activate_bid.wasm. You must modify the payment and other values in the deploy based on your environment and the network's chainspec.toml. For example, if you use the activate_bid.wasm on a network with node version 1.4.9, you will require a balance of at least 5 CSPR for this contract.

    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 5000000000 \
    --session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \
    --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"

    Check that the deploy was successful with the casper-client get-deploy <deploy_hash> or by searching for the deploy hash on https://cspr.live/. Also, check the bid activation status as shown below.

    Checking the Bid Activation

    -

    Once your deploy processes, you can check your bid again. You should now see "inactive": false in the output.

    -

    If you wait until the next Era starts, you should also see your public key as a future validator on the Validators tab.

    +

    Once your deploy processes, you can check your bid again. You should now see "inactive": false in the output.

    +

    If you wait until the next Era starts, you should also see your public key as a future validator on the Validators tab.

    \ No newline at end of file diff --git a/2.0.0/operators/becoming-a-validator/unbonding/index.html b/2.0.0/operators/becoming-a-validator/unbonding/index.html new file mode 100644 index 000000000..26fd0ac8f --- /dev/null +++ b/2.0.0/operators/becoming-a-validator/unbonding/index.html @@ -0,0 +1,75 @@ + + + + + +Unbonding | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Unbonding as a Validator

    +

    Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.

    +

    Method 1: Unbonding with the System Auction Contract

    +

    This method withdraws a bid using the system auction contract. Call the existing withdraw_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point withdraw_bid \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<AMOUNT_TO_WITHDRAW>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version 1.5.1
    8. +
    9. session-hash - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:
    10. +
    +
      +
    • Testnet: hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2
    • +
    • Mainnet: hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea
    • +
    +
      +
    1. session-entry-point - Name of the entrypoint that will be used when calling the contract
    2. +
    +

    The withdraw_bid entry point expects two arguments, while the third one is optional:

    +
      +
    1. public key: The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract
    2. +
    3. amount: The amount being withdrawn
    4. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    Calling the withdraw_bid entry point on the auction contract has a fixed cost of 2.5 CSPR.

    +

    Example:

    +

    This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point withdraw_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[5 * 1000000000]'"
    +

    Below is the same command with the optional purse set to a different purse where the amount will be returned. Adjust all the values to your use case.

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point withdraw_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[5 * 1000000000]'"
    +

    Method 2: Unbonding with Compiled Wasm

    +

    There is a second way to withdraw a bid, using the compiled Wasm withdraw_bid.wasm. The process is the same as bonding but uses a different contract.

    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<AMOUNT_TO_WITHDRAW>'"
    +
      +
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. +
    3. secret-key - The file name containing the secret key of the account paying for the Deploy
    4. +
    5. chain-name - The chain-name to the network where you wish to send the Deploy. For Mainnet, use casper. For Testnet, use casper-test
    6. +
    7. payment-amount - The payment for the Deploy in motes estimated
    8. +
    9. session-path - The path to the compiled Wasm on your computer
    10. +
    +

    The withdraw_bid.wasm expects two arguments, while the third one is optional:

    +
      +
    1. public key: The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract
    2. +
    3. amount: The amount being withdrawn
    4. +
    +

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    +
    note

    This method is more expensive than calling the withdraw_bid entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.

    +

    Example:

    +

    Here is an example request to unbond stake using the withdraw_bid.wasm. The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \
    --payment-amount 4000000000 \
    --session-arg="public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg="amount:u512='1000000000000'"
    +

    Check the Auction Contract

    +

    Check the auction contract for updates to the bid amounts.

    +
    casper-client get-auction-info --node-address http://<HOST:PORT>
    +

    Unbonding Wait Period

    +

    To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours.

    + + \ No newline at end of file diff --git a/2.0.0/operators/index.html b/2.0.0/operators/index.html new file mode 100644 index 000000000..3f4957ee4 --- /dev/null +++ b/2.0.0/operators/index.html @@ -0,0 +1,51 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Operators Overview

    +

    Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.

    +

    Prior knowledge of Unix-based operating systems and proficiency with systemd and bash scripting are recommended. If you are unfamiliar with systemd, the Arch Linux page on systemd is a good introduction.

    +

    Operators should know the hardware requirements before running a node.

    +

    Also, the network requirements specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes.

    +

    Review the node's configuration first. Then, you can follow the node installation instructions.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Node SetupHow to set up a Casper node
    Becoming a ValidatorHow to join a network and become a validator
    Private Network SetupHow to set up a private Casper network
    MaintenanceTopics related to node maintenance
    + + \ No newline at end of file diff --git a/2.0.0/operators/maintenance/archiving-and-restoring/index.html b/2.0.0/operators/maintenance/archiving-and-restoring/index.html new file mode 100644 index 000000000..320afab25 --- /dev/null +++ b/2.0.0/operators/maintenance/archiving-and-restoring/index.html @@ -0,0 +1,102 @@ + + + + + +Archive and Restore a DB | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Archiving and Restoring a Database

    +

    This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.

    +

    Zstandard is the best method for compression speed and space for the current LMDB-based database system that the casper-node uses.

    +
    note

    The values presented in this document assume that the trie-compact tool was run on a Mainnet database for compression. Contact the support team if you have questions.

    +

    Zstandard Limitations

    +

    The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use tar as a pre-filter for stripping sparse data, as shown here, thus eliminating the need to read the full DB size and improving processing.

    +

    Zstandard Installation

    +

    To install Zstandard, run the following command:

    +
    sudo apt install zstd
    +

    Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation.

    +

    Initial Warnings

    +

    You need to stop the casper-node-launcher process of the node (and, therefore, the casper-node process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur.

    +

    Compression

    +

    Run the following basic tar command from the DB directory. For Mainnet, the directory would be /var/lib/casper/casper-node/casper, and for Testnet it would be /var/lib/casper/casper-node/casper-test.

    +
    tar -cv --sparse .
    +

    On some systems, you may get better performance if you specify the block number as an argument:

    +
    tar -b 4096 -cv --sparse .
    +

    You can then stream the result into zstd. The sections below discuss the level, thread count, and long arguments.

    +
    tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst
    +

    Compression level

    +

    The -[level] argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful.

    +

    Here are some examples of a Mainnet DB compression at block 741160:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    LevelTime (min:sec)Size
    1229:2015.8 GB
    1546:1513.0 GB
    1787:4213.0 GB
    19197:0812.9 GB
    +

    For local backups, using 1-5 is a great compression speed-to-size trade-off.

    +

    Thread count

    +

    The -T[thread count] is the number of threads that zstd should use for compression. If running a script or command on varying machines, use T0 to allow zstd to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use -T0.

    +

    Long-distance matching

    +

    The --long=31 argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB.

    +

    At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at --long=31.

    +

    An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide.

    +

    Summary of commands

    +

    The general command for compression is:

    +
    tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst
    +

    For local backups, use a lower compression level:

    +
    tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst
    +

    Decompression

    +

    zstd -d is the command for decompression; however, the same --long value used for compression must be specified. For all casper-node DB-related decompression, you will likely use this command:

    +
    zstd -cd --long=31 <.tar.zst file>
    +

    If --long=31 is omitted, you might see an error such as this, which also gives you the solution:

    +
    ./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding 
    ./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728
    ./casper.tar.zst : Use --long=31 or --memory=2048MB
    +

    You can then use the zstd result to populate a tar -xv command. Also, create the decompressed files using sudo -u casper, because the files will be used by the casper-node. Run the following command inside an empty DB location:

    +
    zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv
    +

    To fix ownership, use this command:

    +
    sudo /etc/casper/node_util.py fix_permissions
    +

    Streamed Decompression

    +

    If a .tar.zst archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using curl, which can output to stdout with --output and stream binary to your terminal.

    +
    curl -s --output - <URL for tar.zstd file>
    +

    If you use the output along with the previous process, you can decompress the files from curl directly into a local directory:

    +
    curl -s --output - <tar.zst URL> | zstd -d --long=31 | sudo -u casper tar -xv
    +

    Starting a New Node with a Decompressed DB

    +

    If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the node_util.py script included in the casper-node-launcher installation.

    +

    For example, if you are using a DB archive from node version 1.4.5, you would run this command:

    +
    sudo /etc/casper/node_util.py force_run_version 1_4_5
    + + \ No newline at end of file diff --git a/2.0.0/operators/maintenance/index.html b/2.0.0/operators/maintenance/index.html new file mode 100644 index 000000000..a14dee39e --- /dev/null +++ b/2.0.0/operators/maintenance/index.html @@ -0,0 +1,39 @@ + + + + + +Node Maintenance | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Node Maintenance

    +

    This section covers maintenance actions such as moving a node to a different location and restoring a database.

    + + + + + + + + + + + + + + + + + +
    TitleDescription
    Archiving and Restoring a DatabaseUsing zstd for the compression and decompression of a Casper node database and streaming from a backup location
    Moving a Validating NodeWays to move a validator node to another machine
    + + \ No newline at end of file diff --git a/2.0.0/operators/maintenance/moving-node/index.html b/2.0.0/operators/maintenance/moving-node/index.html new file mode 100644 index 000000000..1840a8292 --- /dev/null +++ b/2.0.0/operators/maintenance/moving-node/index.html @@ -0,0 +1,76 @@ + + + + + +Move a Node | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Moving a Validating 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. +
    3. When the backup_node is up to date, stop the current_node.
    4. +
    5. Move the unit files at the DB level using rsync. This step allows moving the node with nearly zero rewards loss.
    6. +
    7. Stop the backup_node.
    8. +
    9. Swap keys on the backup_node, now the new validator.
    10. +
    11. Restart the backup_node.
    12. +
    13. Swap keys on the current_node, now the new backup.
    14. +
    15. Restart the current_node.
    16. +
    +

    Preparation for swapping

    +
      +
    1. +

      Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset.

      +
    2. +
    3. +

      Prepare to swap keys by following these steps:

      +
        +
      • 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.
      • +
      +
    4. +
    +
        /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

    +
      +
    1. +

      When the backup_node is up to date, stop the current_node.

      +
    2. +
    3. +

      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.

      +
    4. +
    5. +

      On the backup_node, run these commands to stop the node, swap keys, and restart the node:

      +
      sudo systemctl stop casper-node-launcher
      cd /etc/casper/validator_keys/current_node
      sudo -u casper cp * ../
      sudo systemctl start casper-node-launcher
      +
    6. +
    7. +

      On the current_node, run these commands to stop the node and swap keys:

      +
      sudo systemctl stop casper-node-launcher
      cd /etc/casper/validator_keys/backup_node
      sudo -u casper cp * ../
      +
    8. +
    9. +

      Restart the original validator node (current_node), which is now the new backup:

      +
      sudo systemctl start casper-node-launcher 
      +
    10. +
    +

    Understanding rewards impact

    +

    After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era.

    +
    tip

    You could time the swap right before the era ends to minimize reward losses.

    +

    Checking file permissions

    +

    After the swap, check and fix file permissions by running the /etc/casper/node_util.py utility.

    + + \ No newline at end of file diff --git a/next/operators/setup-network/chain-spec/index.html b/2.0.0/operators/setup-network/chain-spec/index.html similarity index 68% rename from next/operators/setup-network/chain-spec/index.html rename to 2.0.0/operators/setup-network/chain-spec/index.html index bb952b271..42ad1e1e9 100644 --- a/next/operators/setup-network/chain-spec/index.html +++ b/2.0.0/operators/setup-network/chain-spec/index.html @@ -1,21 +1,21 @@ - + -The Chainspec | Casper Docs - Redux +The Chainspec | Casper Docs - Redux - - + +
    Version: Next

    The Blockchain Specification

    + submit an issue on Github
    Version: 2.0.0

    The Blockchain Specification

    The blockchain specification, or chainspec, is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 2.0.0 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring.

    protocol

    These settings describe the active protocol version.

    @@ -266,7 +266,7 @@

    coreAttributeDescriptionMainnet Settingera_durationEra duration.'120 minutes'minimum_era_heightMinimum number of blocks per era. An era will take longer than era_duration if that is necessary to reach the minimum height.20minimum_block_timeMinimum difference between a block's and its child's timestamp.'16384 ms'validator_slotsNumber of slots available in the validator auction.100finality_threshold_fractionA number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.
    It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.
    Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly.[1, 3]start_protocol_version_with_strict
    _finality_signatures_requiredProtocol version from which nodes are required to hold strict finality signatures.'1.5.0'legacy_required_finalityThe finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'.
    Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures.'Strict'migrate_legacy_accountsIf true, the protocol upgrade will migrate ALL user accounts to addressable entity. If false, user accounts will be left as they are and will be lazily migrated on a per-account basis if / when that account is used during transaction execution.truemigrate_legacy_contractsIf true, the protocol upgrade will migrate ALL user contracts to addressable entity. If false, user contracts will be left as they are and will be lazily migrated on a per-contract basis if / when that contract is used during transaction execution.trueauction_delayNumber of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1.1locked_funds_periodThe period after genesis during which a genesis validator's bid is locked.'0 days'vesting_schedule_periodThe period in which the genesis validator's bid is released over time after it is unlocked.'0 weeks'unbonding_delayDefault number of eras that need to pass to be able to withdraw unbonded funds.7round_seigniorage_rateRound seigniorage rate represented as a fraction of the total supply.
    - Annual issuance: 8%.
    - Minimum block time: 2^15 milliseconds.
    - Ticks per year: 31536000000.

    (1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:
    Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)[7, 175070816]max_associated_keysMaximum number of associated keys for a single account.100max_runtime_call_stack_heightMaximum height of the contract runtime call stack.12minimum_delegation_amountMinimum allowed delegation amount in motes.500_000_000_000maximum_delegation_amountMaximum allowed delegation amount in motes.1_000_000_000_000_000_000prune_batch_sizeGlobal state prune batch size for tip pruning. Possible values:
    - 0 when the feature is OFF
    - Integer if the feature is ON, representing the number of eras to process per block.0strict_argument_checkingEnables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct CLType.falsesimultaneous_peer_requestsNumber of simultaneous peer requests.5consensus_protocolThe consensus protocol to use. Options are 'Zug' or 'Highway'.'Zug'max_delegators_per_validatorThe maximum amount of delegators per validator. If the value is 0, there is no maximum capacity.1200finders_feeThe split in finality signature rewards between block producer and participating signers.[1, 5]finality_signature_proportionThe proportion of baseline rewards going to reward finality signatures specifically.[1, 2]signature_rewards_max_delayLookback interval indicating how many past blocks we are looking at to reward.3allow_unrestricted_transfersAllows peer to peer transfers between users. Setting this to false makes sense only for private chains.trueallow_auction_bidsEnables the auction entry points 'delegate' and 'add_bid'. Setting this to false makes sense only for private chains that don't need to auction new validator slots. These auction entry points will return an error if called, when this option is set to false.truecompute_rewardsIf set to false, then consensus doesn't compute rewards and always uses 0.truerefund_handlingDefines how refunds of the unused portion of payment amounts are calculated and handled. Valid options are: refund (a ratio of the unspent token is returned to the spender); burn (a ratio of the unspent token is burned); no_refund (no refunds are paid out){ type = 'no_refund' }fee_handlingDefines how fees are handled. Valid options are: no_fee (fees are eliminated); pay_to_proposer (fees are paid to the block proposer); accumulate (fees are accumulated in a special purse and distributed at the end of each era evenly among all administrator accounts); burn (fees are burned){ type = 'no_fee' }validator_credit_capIf a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.[1, 5]pricing_handlingDefines how pricing is handled. Valid options are: classic (senders of transaction self-specify how much they pay); fixed (costs are fixed, per the cost table); reserved (prepaid transaction, currently not supported){ type = 'fixed' }allow_reservationsDoes the network allow pre-payment / reservations for future execution? Currently not supported.falsegas_hold_balance_handlingDefines how gas holds affect available balance calculations. Valid options are: accrued (sum of full value of all non-expired holds) and amortized (sum of each hold is amortized over the time remaining until expiry).{ type = 'accrued' }gas_hold_intervalDefines how long gas holds last.'24 hours'administratorsList of public keys of administrator accounts. Setting this option makes only on private chains which require administrator accounts for regulatory reasons.[] -

    See the Fee Elimination page for more details regarding refund_handling, fee_handling, validator_credit_cap, pricing_handling, gas_hold_balance_handling, and gas_hold_interval.

    +

    See the Fee Elimination page for more details regarding refund_handling, fee_handling, validator_credit_cap, pricing_handling, gas_hold_balance_handling, and gas_hold_interval.

    highway

    These settings configure the Highway Consensus protocol.

    @@ -329,7 +329,7 @@

    transactionsAttributeDescriptionMainnet Settingmax_ttlThe duration after the transaction timestamp during which the transaction can be included in a block.'2 hours'block_max_approval_countThe maximum number of approvals permitted in a single block.2600max_block_sizeMaximum block size in bytes, including transactions contained by the block. 0 means unlimited.5_242_880block_gas_limitThe upper limit of the total gas of all transactions in a block.3_300_000_000_000native_transfer_minimum_motesThe minimum amount in motes for a valid native transfer.2_500_000_000max_timestamp_leewayThe maximum value to which transaction_acceptor.timestamp_leeway can be set in the config.toml file.'5 seconds'

    transactions.v1

    -

    These settings manage the transaction lanes including both native and Wasm based interactions. See Lanes and gas costs for details.

    +

    These settings manage the transaction lanes including both native and Wasm based interactions. See Lanes and gas costs for details.

    @@ -1078,6 +1078,6 @@

    +
    AttributeDescriptionMainnet Setting
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10_000
    \ No newline at end of file diff --git a/next/operators/setup-network/create-private/index.html b/2.0.0/operators/setup-network/create-private/index.html similarity index 78% rename from next/operators/setup-network/create-private/index.html rename to 2.0.0/operators/setup-network/create-private/index.html index cd3ffdb8f..a3b4d1b71 100644 --- a/next/operators/setup-network/create-private/index.html +++ b/2.0.0/operators/setup-network/create-private/index.html @@ -1,21 +1,21 @@ - + -Private Network Setup | Casper Docs - Redux +Private Network Setup | Casper Docs - Redux - - + +
    Version: Next

    Setting Up a Private Casper Network

    + submit an issue on Github
    Version: 2.0.0

    Setting Up a Private Casper Network

    Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.

    Contents

      @@ -47,16 +47,16 @@

      ContentsPrerequisites

      Follow these guides to set up the required environment and user accounts.

      Step 1. Setting up a Validator Node

      -

      A Casper node is a physical or virtual device participating in a Casper network. You need to set up several validator nodes on your private network. An operator who has won an auction bid will be a validator for the private network.

      +

      A Casper node is a physical or virtual device participating in a Casper network. You need to set up several validator nodes on your private network. An operator who has won an auction bid will be a validator for the private network.

      Use the below guides to set up and manage validator nodes.

      • Casper node setup - GitHub guide: A guide to configuring a system with the new Rust node to operate within a network.
      • -
      • Basic node setup tutorial: A guide on using the casper-node-launcher, generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes.
      • +
      • Basic node setup tutorial: A guide on using the casper-node-launcher, generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes.
      • Set up Mainnet and Testnet validator nodes: A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes.

      Use these FAQ collections for tips and details for validators.

      @@ -67,23 +67,23 @@

      Step 2. Setting up the Directory

      Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes.

        -
      • Go through the file location section to understand how directories are created and managed in a Casper private network.
      • -
      • Refer to the setting up a new network guide to identify the required configuration files to set up a genesis block.
      • +
      • Go through the file location section to understand how directories are created and managed in a Casper private network.
      • +
      • Refer to the setting up a new network guide to identify the required configuration files to set up a genesis block.

      Step 3. Configuring the Genesis Block

      -

      A Casper private network contains a different set of configurations when compared to the public network. The chainspec.toml file contains the required configurations for the genesis process in a private network.

      -

      You should add the configuration options below to the chainspec.toml file inside the private network directory.

      +

      A Casper private network contains a different set of configurations when compared to the public network. The chainspec.toml file contains the required configurations for the genesis process in a private network.

      +

      You should add the configuration options below to the chainspec.toml file inside the private network directory.

      Unrestricted transfers configuration

      This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators.

      [core]
      allow_unrestricted_transfers = false

      In contrast, users in the public network can freely transfer funds to different accounts.

      -
      note

      A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:

      [core]
      allow_unrestricted_transfers = false
      compute_rewards = false
      allow_auction_bids = false
      refund_handling = { type = "refund", refund_ratio = [1, 1] }
      fee_handling = { type = "accumulate" }
      administrators = ["ADMIN_PUBLIC_KEY"]

      The Casper Mainnet has different refund and fee handling configurations explained in more detail here.

      [core]
      allow_unrestricted_transfers = true
      compute_rewards = true
      allow_auction_bids = true
      refund_handling = { type = 'no_refund' }
      fee_handling = { type = 'no_fee' }
      administrators = []
      +
      note

      A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:

      [core]
      allow_unrestricted_transfers = false
      compute_rewards = false
      allow_auction_bids = false
      refund_handling = { type = "refund", refund_ratio = [1, 1] }
      fee_handling = { type = "accumulate" }
      administrators = ["ADMIN_PUBLIC_KEY"]

      The Casper Mainnet has different refund and fee handling configurations explained in more detail here.

      [core]
      allow_unrestricted_transfers = true
      compute_rewards = true
      allow_auction_bids = true
      refund_handling = { type = 'no_refund' }
      fee_handling = { type = 'no_fee' }
      administrators = []

      Refund handling configuration

      This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user.

      A refund_ratio is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the refund_ratio is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user.

      [core]
      refund_handling = { type = "refund", refund_ratio = [1, 1] }

      Another example: a refund variant with refund_ratio of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return.

      -

      After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.

      +

      After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.

      Starting with the Condor release, a Casper private network can eliminate fees and, thus, not require refunds, similar to the Casper Mainnet:

      refund_handling = { type = 'no_refund' }
      fee_handling = { type = 'no_fee' }

      Fee handling configuration

      @@ -93,7 +93,7 @@

      F

      The fee_handling configuration has four variations:

      • no_fee: Fees are eliminated. No refunds are necessary.
      • -
      • pay_to_proposer: The rest of the payment amount after deducing the gas fee from a refund is paid to the block's proposer.
      • +
      • pay_to_proposer: The rest of the payment amount after deducing the gas fee from a refund is paid to the block's proposer.
      • burn: The tokens paid are burned, and the total supply is reduced.
      • accumulate: The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled.
      @@ -108,7 +108,7 @@

      Step 4. Configuring the Administrator Accounts

      -

      An administrator is mandatory for a private network since it manages all the other validator accounts. There should be at least one administrator account configured within a network to operate it as a private network. You can create new administrators and rotate the validator set in a single configuration update. The operator must first ensure the global_state.toml file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances.

      +

      An administrator is mandatory for a private network since it manages all the other validator accounts. There should be at least one administrator account configured within a network to operate it as a private network. You can create new administrators and rotate the validator set in a single configuration update. The operator must first ensure the global_state.toml file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances.

      Configuring administrator accounts

      Use this configuration option in the chainspec.toml to add administrator accounts to the private network:

      [core]
      administrators = ["NEW_ACCOUNT_PUBLIC_KEY"]
      @@ -149,7 +149,7 @@

      note

      Please make sure you are running this tool as the same user that owns $DATA_DIR. Otherwise, you may receive a permission denied error.

    -

    You can find more details on enabling new validators in the joining a running network guide. The guide explains how to join the network and provide additional security to the system.

    +

    You can find more details on enabling new validators in the joining a running network guide. The guide explains how to join the network and provide additional security to the system.

    Step 7. Testing the Private Network

    We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer.

    Sample configuration files

    @@ -164,7 +164,7 @@

    Spec

    Setting up the node

    Set up the node address, chain name, and the administrator's secret key.

    export NODE_ADDR=http://18.224.190.213:7777
    export CHAIN_NAME="private-test"
    -

    This testing example will also use an alice/secret_key.pem file, a secret key generated through the keys generation process. Alice is a regular user in this testing example.

    +

    This testing example will also use an alice/secret_key.pem file, a secret key generated through the keys generation process. Alice is a regular user in this testing example.

    Network access control

    With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed.

    To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA).

    @@ -188,7 +188,7 @@

    Fundi
    casper-client get-account-info -n $NODE_ADDR
    --public-key alice/public_key.pem

    Adding a bid as Alice

    The following command attempts to add an auction bid on the network. It should return ApiError::AuctionError(AuctionBidsDisabled) [64559].

    -
    tip

    All payment amounts in these examples must be adjusted based on the network chainspec.

    +
    tip

    All payment amounts in these examples must be adjusted based on the network chainspec.

    casper-client \
    put-deploy \
    -n $NODE_ADDR \
    --chain-name $CHAIN_NAME \
    --secret-key alice/secret_key.pem \
    --session-path add_bid.wasm \
    --payment-amount 5000000000 \
    --session-arg "public_key:public_key='$(<alice/public_key_hex)'" \
    --session-arg "amount:u512='10000'" \
    --session-arg "delegation_rate:u8='5'"

    # Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"

    We should get a similar error for the delegate entry point.

    Disabling Alice's account

    @@ -236,6 +236,6 @@

    Ad
    [core]
    administrators = ["NEW_PUBLIC_KEY"]

    After this step, the private network would be ready for use.

    Setting up a Block Explorer

    -

    Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer here.

    +

    Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer here.

    \ No newline at end of file diff --git a/2.0.0/operators/setup-network/genesis/index.html b/2.0.0/operators/setup-network/genesis/index.html new file mode 100644 index 000000000..1c8a692d7 --- /dev/null +++ b/2.0.0/operators/setup-network/genesis/index.html @@ -0,0 +1,32 @@ + + + + + +Genesis | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    The Genesis Block

    +

    The Casper node software creates a genesis block from the following input files:

    +
      +
    • chainspec.toml
    • +
    • accounts.toml
    • +
    +

    chainspec.toml

    +

    A version of the chainspec is downloaded by the pull_casper_node_version.sh script installed with the casper-node-launcher debian package. This script pulls the chainspec.toml file from the appropriate path defined in the network config file used (casper.conf for MainNet and casper-test.conf for TestNet).

    +

    The production version of the file from which this is based on can be found at casper-node/resources/production/chainspec.toml in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to this page for detailed documentation on each of the variables in the file.

    +

    accounts.toml

    +

    This file contains the genesis validator set information, starting accounts and associated balances and bond amounts.

    +

    If an account is not bonded at genesis, specify a 0 for the bond amount.

    +

    Similar to the chainspec.toml, this is pulled from the appropriate path defined in the network config file used.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup-network/index.html b/2.0.0/operators/setup-network/index.html new file mode 100644 index 000000000..f460f8636 --- /dev/null +++ b/2.0.0/operators/setup-network/index.html @@ -0,0 +1,47 @@ + + + + + +Setting up Private Networks | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Setting up Private Networks

    +

    Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    The Genesis BlockFiles needed to create a genesis block
    The Chain SpecificationConfiguration settings describing the network state
    Setting up a Private Casper NetworkA step-by-step guide to establishing and configuring a private Casper network
    Staging Files for a New NetworkA guide to hosting protocol files for a new Casper network
    + + \ No newline at end of file diff --git a/2.0.0/operators/setup-network/staging-files-for-new-network/index.html b/2.0.0/operators/setup-network/staging-files-for-new-network/index.html new file mode 100644 index 000000000..a45d62978 --- /dev/null +++ b/2.0.0/operators/setup-network/staging-files-for-new-network/index.html @@ -0,0 +1,105 @@ + + + + + +Staging Files | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Staging Files for a New Network

    +
    important

    Staging files is not needed for already established running networks.

    Only use these instructions if you are creating a new Casper network and hosting protocol files for this network.

    +

    Hosting Server

    +

    Files for staging protocol versions are hosted on a typical HTTP(S) server.

    +

    Scripts included with the casper-node-launcher have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name.

    +

    Since a given server can be used for multiple networks, a network named directory is used to +hold files for that network.

    +

    This is a description of Mainnet protocol version hosting (with network name: casper).

    +

    genesis.casperlab.io is the web server URL with the following directory structure:

    +
      +
    • casper +
        +
      • protocol_versions - File listing active protocol versions so scripts know what directories to use
      • +
      • 1_0_0 - Genesis protocol version +
          +
        • config.tar.gz - Configuration files to be expanded into /etc/casper/1_0_0
        • +
        • bin.tar.gz - Binary files to be expanded into /var/lib/casper/bin/1_0_0
        • +
        +
      • +
      • 1_1_0 - First upgrade +
          +
        • config.tar.gz - Configuration files to be expanded into /etc/casper/1_1_0
        • +
        • bin.tar.gz - Binary files to be expanded into /var/lib/casper/bin/1_1_0
        • +
        +
      • +
      • ... (skipping many other protocol versions)
      • +
      • 1_4_6 - A later upgrade +
          +
        • config.tar.gz - Configuration files to be expanded into /etc/casper/1_4_6
        • +
        • bin.tar.gz - Binary files to be expanded into /var/lib/casper/bin/1_4_6
        • +
        +
      • +
      +
    • +
    +

    More on protocol_versions

    +

    At the root of the hosting server directory for a given network, a protocol_versions file exists. This holds the valid protocol versions for a network.

    +

    We can look at this manually on Mainnet using curl. As of writing this, 1.4.6 is the latest version and the contents of this file will change.

    +

    $ curl -s genesis.casperlabs.io/casper/protocol_versions
    1_0_0
    1_1_0
    1_1_2
    1_2_0
    1_2_1
    1_3_2
    1_3_4
    1_4_1
    1_4_3
    1_4_4
    1_4_5
    1_4_6

    +

    We should find bin.tar.gz and config.tar.gz in those directories under casper.

    +

    Protocol Version

    +

    The protocol version of a network is not related to the casper-node version. In Mainnet, these have often been the same. However, with a new network, you would use the latest casper-node version for your +1.0.0 protocol.

    +

    Network Configuration File

    +

    When the casper-node-launcher package is installed, both casper.conf and casper-test.conf are installed +in /etc/casper/network_configs. Once a valid config file for a new network is copied to this location, +all commands with node_util.py will work as they do on existing networks.

    +

    By convention, we name the config file the same as the network. So Mainnet has a network name of casper and we use +casper.conf for the config file.

    +

    For a new network using server casper.mydomain.com to host files for our-network network, we would have a +our-network.conf file that looks like this:

    +
    SOURCE_URL=casper.mydomain.com
    NETWORK_NAME=our-network
    +

    Host this our-network.conf in the root of casper.mydomain.com/our-network at the same level as protocol_versions.

    +

    This allows any node which wants to use the new network to run the following to install this configuration:

    +
    cd /etc/casper/network_configs
    sudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf
    +

    Any command needing a network config from node_util.py can use our-network.conf.

    +

    Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf
    +

    Setup Configuration Files

    +

    For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time.

    +

    chainspec.toml

    +

    The chainspec.toml file is configuration for the network and must be exactly the same on all nodes.

    +

    The name for a network is specified network.name.

    +

    Each protocol will have a version and activation_point. At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the era_id for activation of the upgrade.

    +
    [protocol]
    version = '1.0.0'
    activation_point = '2022-08-01T10:00:00Z'

    [network]
    name = 'mynetwork'
    +

    config-example.toml

    +

    The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The public_address is auto-detected with node_util.py stage_protocols. If using a NAT environment, the public IP can be specified with the --ip argument.

    +

    This file should have known_addresses added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:

    +
    [network]
    known_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']
    +

    The config.toml can be setup to customized fields for a given node. config-example.toml is a default configuration.

    +

    Staging a Protocol Version

    +

    For the initial genesis protocol version or future upgrade protocol versions, you will typically use +prebuilt and tested bin.tar.gz that have been tested and staged for existing networks. The config.tar.gz +file must be customized for the specific network with a network name, protocol version and activation point at the very least.

    +

    These archives should be created with no directory information stored. This is done by using tar in the same directory as the files.

    +
    mkdir config
    cd config
    mv [source of chainspec.toml] ./chainspec.toml
    mv [source of config-example.toml] ./config-example.toml
    tar -czvf ../config.tar.gz .
    +

    You can test what was compressed with untar'ing the file.

    +
    mkdir conftest
    cd conftest
    tar -xzvf ../config.tar.gz .
    +

    This will expand files for verification.

    +

    For custom casper-node builds, the minimum contents of bin.tar.gz is the casper-node executable.

    +
    mkdir bin
    cd bin
    cp [source of casper-node] ./casper-node
    tar -czvf ../bin.tar.gz .
    +

    A directory for the protocol_version will be created on the server. For example: 1_1_0.

    +

    We will copy bin.tar.gz and config.tar.gz into 1_1_0. Once this is done, we are safe to update +protocol_versions by appending 1_1_0 to the end of the file and uploading it into the root of the network directory.

    +

    Any node that runs the following command will get this new upgrade:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>
    + + \ No newline at end of file diff --git a/next/operators/setup/basic-node-configuration/index.html b/2.0.0/operators/setup/basic-node-configuration/index.html similarity index 67% rename from next/operators/setup/basic-node-configuration/index.html rename to 2.0.0/operators/setup/basic-node-configuration/index.html index 449b4eb6c..49cb5880e 100644 --- a/next/operators/setup/basic-node-configuration/index.html +++ b/2.0.0/operators/setup/basic-node-configuration/index.html @@ -1,22 +1,22 @@ - + -Configuration | Casper Docs - Redux +Configuration | Casper Docs - Redux - - + +
    Version: Next

    Basic Node Configuration

    -

    This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.

    + submit an issue on Github
    Version: 2.0.0

    Basic Node Configuration

    +

    This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.

    The Casper Node Launcher

    A node is usually run by executing the casper-node-launcher, which executes the casper-node as a child process and also handles upgrades to bring the node to the latest version released.

    The casper-node-launcher can be installed via a Debian package, which also creates the casper user and directory structures and sets up a systemd unit and logging.

    @@ -128,7 +128,7 @@

    Known Addresses

    For the node to connect to a network, the node needs a set of trusted peers for that network. For Mainnet, these are listed in the config.toml as known_addresses. For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an example configuration. The casper-protocol-release repository stores configurations for various environments, which you can also use as examples.

    Updating the config.toml file

    -

    At the top of a config.toml file as shown here, enter the trusted block hash to replace the 'HEX-FORMATTED BLOCK HASH' and uncomment the line by deleting the leading '#'. See the Configuration File for more details.

    +

    At the top of a config.toml file as shown here, enter the trusted block hash to replace the 'HEX-FORMATTED BLOCK HASH' and uncomment the line by deleting the leading '#'. See the Configuration File for more details.

    # ================================
    # Configuration options for a node
    # ================================
    [node]

    # If set, use this hash as a trust anchor when joining an existing network.
    #trusted_hash = 'HEX-FORMATTED BLOCK HASH'

    Secret Keys

    Provide the path to the secret keys for the node. This path is set to etc/casper/validator_keys/ by default. See Creating Keys and Funding Accounts for more details.

    @@ -147,14 +147,14 @@

    Example Config.toml configuration with speculative execution enabled

    # ========================================================================
    # Configuration options for the speculative execution JSON-RPC HTTP server
    # ========================================================================
    [speculative_exec_server]

    # Flag which enables the speculative execution JSON-RPC HTTP server.
    enable_server = true

    # Listening address for speculative execution JSON-RPC HTTP server. If the port
    # is set to 0, a random port will be used.
    #
    # If the specified port cannot be bound to, a random port will be tried instead.
    # If binding fails, the speculative execution JSON-RPC HTTP server will not run,
    # but the node will be otherwise unaffected.
    #
    # The actual bound address will be reported via a log line if logging is enabled.
    address = '0.0.0.0:7778'

    # The global max rate of requests (per second) before they are limited.
    # Request will be delayed to the next 1 second bucket once limited.
    qps_limit = 1

    # Maximum number of bytes to accept in a single request body.
    max_body_bytes = 2_621_440

    # Specifies which origin will be reported as allowed by speculative execution server.
    #
    # If left empty, CORS will be disabled.
    # If set to '*', any origin is allowed.
    # Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).
    cors_origin = ''

    Rust Client Installation

    -

    The Prerequisites page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network.

    +

    The Prerequisites page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network.

    Creating Keys and Funding Accounts

    The following command will create keys in the /etc/casper/validator_keys folder.

    sudo -u casper casper-client keygen /etc/casper/validator_keys
    -

    To learn about other options for generating keys, see Accounts and Cryptographic Keys or run the Rust client keygen command with the --help option.

    +

    To learn about other options for generating keys, see Accounts and Cryptographic Keys or run the Rust client keygen command with the --help option.

    sudo -u casper casper-client keygen --help

    More about keys and key generation can also be found in /etc/casper/validator_keys/README.md if the casper-node-launcher was installed from the Debian package.

    note

    Save your keys in a secure location, preferably offline.

    -

    To submit a bonding request, you will need to fund your account as well.

    +

    To submit a bonding request, you will need to fund your account as well.

    \ No newline at end of file diff --git a/2.0.0/operators/setup/casper-sidecar/index.html b/2.0.0/operators/setup/casper-sidecar/index.html new file mode 100644 index 000000000..6f530f15a --- /dev/null +++ b/2.0.0/operators/setup/casper-sidecar/index.html @@ -0,0 +1,75 @@ + + + + + +Sidecar Setup | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    The Casper Sidecar

    +

    The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:

    + +

    Visit GitHub for the latest source code and information on system architecture, configurations, testing and troubleshooting.

    +

    Sidecar components and architecture diagram

    +

    Configuring the Sidecar Service

    +

    Operators need to update the Sidecar configuration file according to their needs. Detailed configuration instructions are available in GitHub. Further details regarding each configuration option are available in GitHub.

    +

    Installing the Sidecar

    +

    The following command will install the Debian package for the Casper Sidecar service on various Linux flavors.

    +
    sudo apt install ./casper-sidecar_0.1.0-0_amd64.deb
    +
    Sample output
    + +
    Reading package lists... Done
    Building dependency tree
    Reading state information... Done
    Note, selecting 'casper-sidecar' instead of './casper-sidecar_0.1.0-0_amd64.deb'
    The following NEW packages will be installed:
    casper-sidecar
    0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.
    Need to get 0 B/4162 kB of archives.
    After this operation, 20.2 MB of additional disk space will be used.
    Get:1 /home/ubuntu/casper-sidecar_0.1.0-0_amd64.deb casper-sidecar amd64 0.1.0-0 [4162 kB]
    Selecting previously unselected package casper-sidecar.
    (Reading database ... 102241 files and directories currently installed.)
    Preparing to unpack .../casper-sidecar_0.1.0-0_amd64.deb ...
    Unpacking casper-sidecar (0.1.0-0) ...
    Setting up casper-sidecar (0.1.0-0) ...
    Adding system user `csidecar' (UID 114) ...
    Adding new group `csidecar' (GID 120) ...
    Adding new user `csidecar' (UID 114) with group `csidecar' ...
    Not creating home directory `/home/csidecar'.
    Created symlink /etc/systemd/system/multi-user.target.wants/casper-sidecar.service → /lib/systemd/system/casper-sidecar.service.
    +
    +



    +

    Monitoring the Installation

    +

    Check the service status:

    +
    systemctl status casper-sidecar
    +
    Sample output
    + +
    casper-sidecar.service - Casper Event Sidecar
    Loaded: loaded (/lib/systemd/system/casper-sidecar.service; enabled; vendor preset: enabled)
    Active: active (running) since Wed 2022-12-07 20:33:29 UTC; 1min 3s ago
    Docs: https://docs.casperlabs.io
    Main PID: 16707 (casper-si)
    Tasks: 5 (limit: 9401)
    Memory: 7.1M
    CGroup: /system.slice/casper-sidecar.service
    └─16707 /usr/bin/casper-sidecar /etc/casper-sidecar/config.toml

    Dec 07 20:33:29 user systemd[1]: Started Casper Event Sidecar.
    +
    +



    +

    Check the logs and make sure the service is running as expected.

    +
    journalctl --no-pager -u casper-sidecar
    +
    Sample output
    + +
    Dec 05 17:24:53 user systemd[1]: Started Casper Event Sidecar.
    +
    +



    +

    If you see any errors, you may need to update the configuration and restart the service with the commands below.

    +

    Stopping the service:

    +
    sudo systemctl stop casper-sidecar.service
    +

    Starting the service:

    +
    sudo systemctl start casper-sidecar.service
    +

    The Admin Server

    +

    If enabled, the Sidecar's administrative API can be accessed using the following command. The PORT is usually 18887, depending on how the Sidecar was configured.

    +
    http://localhost:PORT/metrics/
    +

    Swagger Documentation

    +

    You can access the Swagger documentation at http://localhost:PORT/swagger-ui/. The PORT is usually 18888, depending on how the Sidecar was configured.

    +

    OpenAPI Specification

    +

    An OpenAPI schema is available at http://localhost:PORT/api-doc.json/. The PORT is usually 18888, depending on how the Sidecar was configured.

    +

    Using the Sidecar

    +

    The Casper Sidecar Usage Guide describes how to consume events and perform queries using the Sidecar, covering the following topics:

    +
      +
    • Node-generated events emitted by the node(s) to which the Sidecar connects
    • +
    • Sidecar-generated events originating solely from the Sidecar service and not from a node
    • +
    • The RESTful endpoint for performing useful queries about the state of the network
    • +
    +

    Troubleshooting Tips

    +

    For troubleshooting tips, visit Github.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/fast-sync/index.html b/2.0.0/operators/setup/fast-sync/index.html new file mode 100644 index 000000000..85e40d2e2 --- /dev/null +++ b/2.0.0/operators/setup/fast-sync/index.html @@ -0,0 +1,26 @@ + + + + + +Fast Sync | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Introducing Fast Sync

    +

    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 transaction 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.

    +

    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 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

    +

    Fast-sync process

    +

    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.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/hardware/index.html b/2.0.0/operators/setup/hardware/index.html new file mode 100644 index 000000000..c3aaef76a --- /dev/null +++ b/2.0.0/operators/setup/hardware/index.html @@ -0,0 +1,40 @@ + + + + + +Hardware | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Recommended Hardware Specifications

    +

    System Requirements

    +

    The following hardware specifications are recommended for the Casper Mainnet and Testnet:

    +
      +
    • 4 Cores
    • +
    • 32 GB Ram
    • +
    • 2 TB SSD or network SSD backed disk
    • +
    • Linux machine running Ubuntu 20.04
    • +
    +
    Notes
      +
    • +

      SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network.

      +
    • +
    • +

      For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this.

      +
    • +
    +

    CPU Requirements

    +

    Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions.

    +

    To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture.

    +
    note

    This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/index.html b/2.0.0/operators/setup/index.html new file mode 100644 index 000000000..c22a51e17 --- /dev/null +++ b/2.0.0/operators/setup/index.html @@ -0,0 +1,71 @@ + + + + + +Setting up a Node | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Setting up a Node

    +

    The prerequisite for becoming a validator is to set up a node and join a network as described here.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Recommended Hardware SpecificationsSystem requirements for the Casper Mainnet and Testnet
    Basic Node ConfigurationProcesses and files involved in setting up a Casper node
    Node EndpointsPorts for communicating with other nodes and dApps
    Installing a NodeStep-by-step instructions to install a Casper node
    Setting the Open Files LimitRequired setting for the Casper node to run correctly
    Upgrading the NodeBefore joining the network, the node needs to be upgraded
    Joining a Running NetworkSteps to join an existing Casper network
    Setting up a Non-Root UserLogging into the node remotely using a key
    Node EventsInformation on a node's events stream
    Sidecar SetupAn application allowing subscribers to monitor a node's event stream, query stored events, and query a node’s JSON-RPC API
    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/install-node/index.html b/2.0.0/operators/setup/install-node/index.html new file mode 100644 index 000000000..24c043f66 --- /dev/null +++ b/2.0.0/operators/setup/install-node/index.html @@ -0,0 +1,109 @@ + + + + + +Installation | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Installing a Node

    +

    Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.

    +

    Network Requirements

    +

    The following ports are used by the node:

    +
      +
    • 35000 (required to be externally visible)
    • +
    • 7777 RPC endpoint for interaction with JSON-RPC API
    • +
    • 8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)
    • +
    • 9999 SSE endpoint for event stream
    • +
    +

    Of these 35000 is the only port required to be open for your node to function, however, opening 8888 will allow others to know general network health. For more details, see the additional information on Node Endpoints.

    +

    Operating System Requirements

    +

    The recommended OS version is Ubuntu 20.04.

    +

    Using Ubuntu 22.04

    +

    Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:

    +

    If you try to install packages, you will receive:

    +
    casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable
    +

    This message is due to the default openssl moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:

    +
    curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb
    sudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb
    +

    Required Number of Open Files

    +

    Before beginning, update the maximum open files limit for your system. Specifically, update the node's /etc/security/limits.conf file as described here, to ensure proper node operation.

    +

    Required Clean Up

    +

    If you were running a previous node on this box, this will clean up state. If packages are not installed, the apt remove may give errors, but this is not a problem.

    +
    sudo systemctl stop casper-node-launcher.service
    sudo apt remove -y casper-client
    sudo apt remove -y casper-node
    sudo apt remove -y casper-node-launcher
    sudo rm /etc/casper/casper-node-launcher-state.toml
    sudo rm -rf /etc/casper/1_*
    sudo rm -rf /var/lib/casper/*
    +

    Required Packages

    +

    The following commands will set up the Casper Labs repository for packages:

    +
    echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list
    curl -O https://repo.casperlabs.io/casper-repo-pubkey.asc
    sudo apt-key add casper-repo-pubkey.asc
    sudo apt update
    +

    Required Tools

    +
    sudo apt install -y casper-client casper-node-launcher jq
    +

    Enable Bash Auto-Completion for casper-client (Optional)

    +
    sudo casper-client generate-completion
    +

    It defaults to bash but can be changed with the --shell argument:

    +
    --shell <STRING>    The type of shell to generate the completion script for [default: bash]  [possible values:
    zsh, bash, fish, powershell, elvish]

    sudo casper-client generate-completion --shell powershell
    +

    You need to source the new auto completion script or log out and log in again to activate it for the current shell:

    +
    source /usr/share/bash-completion/completions/casper-client
    +

    Now you can use casper-client and press the tab key to get auto completion for your commands.

    +

    Installing All Protocols

    +

    On Mainnet, run:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf
    +

    On Testnet, run:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf
    +

    Validator Keys

    +

    If you do not have keys yet, you can create them using the following command:

    +
    sudo -u casper casper-client keygen /etc/casper/validator_keys
    +

    For more details, see the Node Setup page.

    +

    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. Find out more about Fast Sync.

    +

    Node Address

    +

    NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes

    +

    You can find active peers at https://cspr.live/tools/peers or use the following Casper Labs public nodes:

    + +

    Protocol Version

    +

    Protocol version should be set to the largest available protocol version you see in ls /etc/casper. As of writing this, it was 1_5_2:

    +
    PROTOCOL=1_5_2
    +

    Load trusted_hash in Config.toml of the Protocol Version

    +

    The following command uses the previously established NODE_ADDR and PROTOCOL to load the trusted_hash:

    +
    NODE_ADDR=https://rpc.mainnet.casperlabs.io
    PROTOCOL=1_5_2
    sudo sed -i "/trusted_hash =/c\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\n')'" /etc/casper/$PROTOCOL/config.toml
    +

    Syncing to Genesis

    +

    In the latest protocol version's Config.toml, you will find the option sync_to_genesis. By default, this value will be set to true.

    +

    If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:

    +
    sync_to_genesis = false
    +

    If you are using the node for historical data and want to query back to genesis, you can leave the default value in place.

    +

    Starting the Node

    +

    Start the node using the following commands:

    +
    sudo /etc/casper/node_util.py rotate_logs
    sudo /etc/casper/node_util.py start
    +

    Monitoring the Synchronization Process

    +

    The following command will display the node synchronization details:

    +
    /etc/casper/node_util.py watch
    +

    When you first run the watch command, you may see the message RPC: Not Ready. Once the node is synchronized, the status will change to RPC: Ready and a similar output:

    +
    Last Block: 630151 (Era: 4153)
    Peer Count: 297
    Uptime: 4days 6h 40m 18s 553ms
    Build: 1.4.5-a7f6a648d-casper-mainnet
    Key: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158
    Next Upgrade: None

    RPC: Ready

    ● casper-node-launcher.service - Casper Node Launcher
    Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)
    Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago
    Docs: https://docs.casper.network
    Main PID: 2934 (casper-node-lau)
    Tasks: 12 (limit: 4915)
    CGroup: /system.slice/casper-node-launcher.service
    ├─ 2934 /usr/bin/casper-node-launcher
    └─16842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml
    +

    The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left sync_to_genesis as true, it will begin syncing back history at this time.

    +

    Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:

    +
    $ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk
    # HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made
    # TYPE trie_or_chunk_fetch_total counter
    trie_or_chunk_fetch_total 102647
    # HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage
    # TYPE trie_or_chunk_found_in_storage counter
    trie_or_chunk_found_in_storage 0
    # HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer
    # TYPE trie_or_chunk_found_on_peer counter
    trie_or_chunk_found_on_peer 102263
    # HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out
    # TYPE trie_or_chunk_timeouts counter
    trie_or_chunk_timeouts 0
    +

    If the node is not showing active (running) status, it is either stopped or in the process of restarting.

    +

    Monitoring the Running Node

    +

    The community has created a few tools to monitor your node once it is running, such as:

    + +

    A Note on Speculative Execution

    +

    The speculative_exec_server defaults to off and can be enabled in your Config.toml file.

    +

    While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You should not use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/joining/index.html b/2.0.0/operators/setup/joining/index.html new file mode 100644 index 000000000..a120d6d53 --- /dev/null +++ b/2.0.0/operators/setup/joining/index.html @@ -0,0 +1,78 @@ + + + + + +Join a Network | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Joining a Running Network

    +

    Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.

    +

    Step 1: Provisioning Hardware

    +

    Visit the Hardware Specifications section and provision your node hardware.

    +

    Step 2: Setting Up the Node

    +

    Follow the instructions on the Node Setup page.

    +

    Step 3: Building the Required Contracts

    +

    Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding.

    +
      +
    1. Clone the casper-node repository.
    2. +
    +
    git clone https://github.com/casper-network/casper-node
    +
      +
    1. Install these prerequisites, which are also listed here.
    2. +
    +
      +
    • Rust
    • +
    • CMake
    • +
    • pkg-config - On Ubuntu, use sudo apt-get install pkg-config
    • +
    • openssl - On Ubuntu, use sudo apt-get install openssl
    • +
    • libssl-dev - On Ubuntu, use sudo apt-get install libssl-dev
    • +
    +
      +
    1. +

      Install the Rust casper-client and fund the keys you will use for bonding.

      +
    2. +
    3. +

      Use the following commands to build the contracts in release mode. Make sure you have installed Rust.

      +
    4. +
    +
    cd casper-node
    make setup-rs
    make build-client-contracts
    +

    These commands will build all the necessary Wasm contracts for operating as a validator:

    +
      +
    • activate_bid.wasm - Reactivates an ejected validator
    • +
    • add_bid.wasm - Enables bonding for validator stake
    • +
    • delegate.wasm - Delegates stake
    • +
    • undelegate.wasm - Undelegates stake
    • +
    • withdraw_bid.wasm - Enables unbonding for validator stake
    • +
    +

    Step 4: Creating and Fund Keys for Bonding

    +

    See the Node Setup instructions if you have not generated and funded your validator keys.

    +

    Step 5: Updating the Trusted Hash

    +

    The node's config.toml needs to be updated with a recent trusted hash.

    +

    See the Trusted Hash for Synchronizing instructions if you have not set up a trusted hash during node installation.

    +

    Step 6: Starting the Node

    +

    Start the node with the casper-node-launcher:

    +
    sudo systemctl start casper-node-launcher
    +

    The above Debian package installs a casper-node service for systemd.

    +

    For more information, visit GitHub.

    +

    Step 7: Confirming the Node is Synchronized

    +

    While the node is synchronizing, the /status endpoint is available. You will be able to compare this to another node's status endpoint era_id and height to determine if you are caught up. You will not be able to perform any casper-client calls to your 7777 RPC port until your node is fully caught up.

    +

    Towards the end of the following output, notice the era_id and height that you can use to determine if your node has completed synchronizing.

    +
    Sample output of the /status endpoint
    + +
    {
    "api_version": "1.4.3",
    "chainspec_name": "casper-test",
    "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",
    "peers": [
    {
    "node_id": "tls:0097..b253",
    "address": "18.163.249.168:35000"
    },
    ...
    ...
    ...
    {
    "node_id": "tls:ff95..c014",
    "address": "93.186.201.14:35000"
    }
    ],
    "last_added_block_info": {
    "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",
    "timestamp": "2022-01-04T15:33:08.224Z",
    "era_id": 3240,
    "height": 430162,
    "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",
    "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"
    },
    "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",
    "round_length": null,
    "next_upgrade": null,
    "build_version": "1.4.3-a44bed1fd-casper-mainnet",
    "uptime": "25days 1h 48m 22s 47ms"
    }
    +
    +

    Step 8: Sending the Bonding Request

    +

    You can submit a bonding request to change your synchronized node to a validating node.

    +

    The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/node-endpoints/index.html b/2.0.0/operators/setup/node-endpoints/index.html new file mode 100644 index 000000000..b3902ae52 --- /dev/null +++ b/2.0.0/operators/setup/node-endpoints/index.html @@ -0,0 +1,109 @@ + + + + + +Endpoints | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Node Endpoints

    +

    As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.

    +

    This document describes in more detail a Casper node's default endpoints:

    + +

    Node operators can modify a node's configuration options, including the port settings, by updating the node's config.toml file. An example configuration file can be found here.

    +

    The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up.

    +

    Default Networking Port: 35000

    +

    The configuration options for networking are under the network section of the config.toml file. The bind_address using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the config.toml file, the setting is:

    +
    bind_address = '0.0.0.0:35000'
    +

    If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline.

    +

    Default JSON-RPC HTTP Server Port: 7777

    +

    The configuration options for the JSON-RPC HTTP server are under the rpc_server section in the config.toml file. The address using port 7777 is the listening address for JSON-RPC HTTP server.

    +
    address = '0.0.0.0:7777'
    +

    DApps would use this address to interact with the Casper JSON-RPC API. Users would use this address to interact with the network using CLI. Validators would use this address to bond or unbond. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected.

    +

    Default REST HTTP Server Port: 8888

    +

    The configuration options for the JSON-RPC HTTP server are under the rest_server section in the config.toml file. The address listing port 8888 is the listening address for the REST HTTP server.

    +
    address = '0.0.0.0:8888'
    +

    Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected.

    +

    One may use this port to get a trusted hash, verify successful staging during an upgrade, or to confirm that the node is synchronized.

    +

    Example usage

    +

    For general health metrics, use this command:

    +
    curl -s http://<node_address>:8888/metrics
    +

    You can check the node's status using this command:

    +
    curl -s http://<node_address>:8888/status
    +

    The status endpoint provides a JSON response that can be parsed with jq.

    +
    curl -s http://<node_address>:8888/status | jq
    +
    Sample response
    + +
    {
    "api_version": "1.4.15",
    "chainspec_name": "casper-test",
    "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",
    "peers": [
    {
    "node_id": "tls:007e..e14b",
    "address": "89.58.52.245:35000"
    },
    {
    "node_id": "tls:00eb..ac11",
    "address": "65.109.17.120:35000"
    },
    ...
    {
    "node_id": "tls:ffc0..555b",
    "address": "95.217.228.224:35000"
    }
    ],
    "last_added_block_info": {
    "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",
    "timestamp": "2023-05-10T09:20:10.752Z",
    "era_id": 9085,
    "height": 1711254,
    "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",
    "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"
    },
    "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",
    "round_length": "32s 768ms",
    "next_upgrade": null,
    "build_version": "1.4.15-039d438f2-casper-mainnet",
    "uptime": "5days 13h 46m 54s 520ms"
    }
    +
    +

    You can filter the result with dot notation, specifying one of the following parameters:

    +
      +
    • api_version - The RPC API version
    • +
    • chainspec_name - The chainspec name, used to identify the currently connected network
    • +
    • starting_state_root_hash - The state root hash used at the start of the current session
    • +
    • peers - The node ID and network address of each connected peer
    • +
    • last_added_block_info - The minimal info of the last Block from the linear chain
    • +
    • our_public_signing_key - Our public signing key
    • +
    • round_length - The next round length if this node is a validator.
    • +
    • next_upgrade - Information about the next scheduled upgrade
    • +
    • build_version - The compiled node version
    • +
    • uptime - Time that has passed since the node has started.
    • +
    +

    Here is an example command for retrieving general network information:

    +
    curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'
    +
    Sample response
    + +
    "1.4.15"
    {
    "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",
    "timestamp": "2023-05-10T09:26:43.968Z",
    "era_id": 9085,
    "height": 1711266,
    "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",
    "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"
    }
    "1.4.15-039d438f2-casper-mainnet"
    "5days 13h 53m 10s 763ms"
    +
    +

    To get information about the next upgrade, use:

    +
    curl -s http://<node_address>:8888/status | jq .next_upgrade
    +

    To get information about the last added block, use:

    +
    curl -s http://<node_address>:8888/status | jq .last_added_block_info
    +

    To monitor the downloading of blocks to your node:

    +
    watch -n 15 'curl -s http://<node_address>:8888/status | jq ".peers | length"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'
    +

    To monitor local block height as well as RPC port status:

    +
    watch -n 15 'curl -s http://<node_address>:8888/status | jq ".peers | length"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'
    +

    Default SSE HTTP Event Stream Server Port: 9999

    +

    The configuration options for the SSE HTTP event stream server are listed under the event_stream_server section of the config.toml file. The address listing port 9999 is the listening address for the SSE HTTP event stream server.

    +
    address = '0.0.0.0:9999'
    +

    If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see Monitoring and Consuming Events.

    +

    Setting up Firewall Rules

    +

    To limit inbound traffic to the node’s endpoints, you can set firewall rules similar to the ufw commands below:

    +
    sudo apt install ufw -y
    sudo ufw disable
    sudo ufw reset
    sudo ufw default allow outgoing
    sudo ufw default deny incoming
    sudo ufw limit ssh
    sudo ufw limit 7777/tcp
    sudo ufw limit 8888/tcp
    sudo ufw limit 35000/tcp
    sudo ufw enable
    +

    These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication.

    +

    If you have any concerns, questions, or issues, please submit a request to the Casper support team.

    +

    Restricting Access for Private Networks

    +

    Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described here.

    + +

    Here is a summary of the links mentioned on this page:

    +
    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/node-events/index.html b/2.0.0/operators/setup/node-events/index.html new file mode 100644 index 000000000..50429b7ff --- /dev/null +++ b/2.0.0/operators/setup/node-events/index.html @@ -0,0 +1,35 @@ + + + + + +Node Events | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    The Node's Event Stream

    +

    Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the event_stream_server.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.

    +

    Monitoring a Node's Event Stream

    +

    As an operator, you can use cURL to monitor the event stream on a node.

    +
    curl -s http://HOST:PORT/events/
    +
      +
    • HOST - The IP address of a node on the network.
    • +
    • PORT - The port specified as the event_stream_server.address in the node's config.toml.
    • +
    +

    Another helpful tool is the Casper Sidecar, which provides the recommended way to monitor events on a node. Visit the Casper Sidecar Usage Guide for a detailed list of events and REST queries you can use to monitor the node and the state of the network.

    +

    Replaying the Event Stream

    +

    This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the HOST, PORT, and ID fields with the needed values.

    +
    curl -sN http://HOST:PORT/events?start_from=ID
    +

    Example:

    +
    curl -sN http://65.21.235.219:9999/events?start_from=29267508
    +
    note

    The node stores only a limited number of events in its cache, which can be configured using the event_stream_buffer_length in the config.toml. The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected.

    The Casper Sidecar may store additional events depending on how it was configured.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/non-root-user/index.html b/2.0.0/operators/setup/non-root-user/index.html new file mode 100644 index 000000000..7ea923cd5 --- /dev/null +++ b/2.0.0/operators/setup/non-root-user/index.html @@ -0,0 +1,57 @@ + + + + + +Non-Root Users | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Setting up a Non-Root User

    +

    Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace <username> in the instructions below with your username.

    +
      +
    1. +

      Use ssh-keygen to generate a new SSH key.

      +
    2. +
    3. +

      Create the user with no password, as the key is your password.

      +
    4. +
    +
    sudo adduser <username> --disabled-password
    +
      +
    1. Create authorized_keys with your key to log in.
    2. +
    +
    sudo su - <username>
    mkdir .ssh
    chmod 700 .ssh
    touch .ssh/authorized_keys
    +
      +
    1. +

      Use the editor of your choice and paste your .ssh public key i the .ssh/authorized_keys file.

      +
    2. +
    3. +

      Exit out of the <username> account and log into the root or previous sudo-er account.

      +
    4. +
    +
    exit
    +
      +
    1. Add your user to sudo-ers under the root account or your previous sudo-er account.
    2. +
    +
    sudo visudo
    +
      +
    1. Type <username> ALL=(ALL:ALL) NOPASSWD:ALL below the row containing root ALL=(ALL:ALL) ALL.
    2. +
    +
    # User privilege specification
    root ALL=(ALL:ALL) ALL
    <username> ALL=(ALL:ALL) NOPASSWD:ALL
    +
      +
    1. You should be able to log in with the key and not use the root user.
    2. +
    +
    ssh -i <your ssh private key> <username>@<server ip>
    +

    Here is an example command:

    +
    ssh -i ~/.ssh/id_rsa casper@10.21.10.200
    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/open-files/index.html b/2.0.0/operators/setup/open-files/index.html new file mode 100644 index 000000000..f25361d0b --- /dev/null +++ b/2.0.0/operators/setup/open-files/index.html @@ -0,0 +1,57 @@ + + + + + +Open Files Limit | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Setting the Open Files Limit

    +

    When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.

    +

    The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default nofile limit needs to be increased.

    +

    With the casper-node-launcher running, you can see what the system allocated by finding the process ID (PID) for the casper-node with the following command.

    +
    pgrep "casper-node$"
    +
    Sample output
    + +
    $ pgrep "casper-node$"
    275928
    +
    note

    This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be 275928 each time.

    +
    +

    If you do not get a value in return, you do not have the casper-node-launcher running correctly.

    +

    To find the current nofile (number of open files) hard limit, run prlimit with the PID from the previous command:

    +
    sudo prlimit -n -p <PID>
    +
    Sample output
    + +
    $ sudo prlimit -n -p 275928
    RESOURCE DESCRIPTION SOFT HARD UNITS
    NOFILE max number of open files 1024 4096 files
    +
    +

    You can also embed both commands as shown here:

    +
    sudo prlimit -n -p $(pgrep "casper-node$")
    +
    Sample output
    + +
    $ sudo prlimit -n -p $(pgrep "casper-node$")
    RESOURCE DESCRIPTION SOFT HARD UNITS
    NOFILE max number of open files 1024 4096 files
    +
    +

    If you receive prlimit: option requires an argument -- 'p', then pgrep "casper-node$" is not returning anything because the casper-node-launcher is no longer running.

    +

    Setting the Limit Manually

    +

    Run the command below to set the nofile limit for an active process without restarting the casper-node-launcher and casper-node processes. Note that this setting is active only while the casper-node process runs. To make this setting permanent, update the limits.conf file instead.

    +
    sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`
    +

    Next, check that the prlimit has changed:

    +
    sudo prlimit -n -p $(pgrep "casper-node$")
    +
    Sample output
    + +
    $ sudo prlimit -n -p $(pgrep "casper-node$")
    RESOURCE DESCRIPTION SOFT HARD UNITS
    NOFILE max number of open files 64000 64000 files
    +
    +

    Updating the limits.conf File

    +

    It is possible to persist the nofile limit across server reboots, casper-node-launcher restarts, and protocol upgrades, by adding the nofile setting for the casper user in /etc/security/limits.conf.

    +

    Add the following row to the bottom of the /etc/security/limits.conf file:

    +
    casper          hard    nofile          64000
    +

    Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct nofile setting.

    + + \ No newline at end of file diff --git a/2.0.0/operators/setup/upgrade/index.html b/2.0.0/operators/setup/upgrade/index.html new file mode 100644 index 000000000..17dd7f9e5 --- /dev/null +++ b/2.0.0/operators/setup/upgrade/index.html @@ -0,0 +1,40 @@ + + + + + +Upgrades | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Upgrading the Node

    +

    The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.

    +
    [protocol]
    # This protocol version becomes active at the start of this era.
    activation_point = 100
    +

    At every block finalization, the casper-node looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the chainspec.toml file. This will be the era before where the current casper-node will cleanly shut down.

    +

    The casper-node-launcher will detect a clean exit 0 condition and start the next version of the casper-node.

    +

    Upgrading Protocol Versions

    +

    All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of casper-node immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point.

    +

    Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point.

    +

    Upgrade Staging Instructions

    +

    The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf
    +

    On Testnet, use casper-test.conf:

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf
    +

    Note: To only view the list of staged and unstaged protocols, use this command: sudo -u casper /etc/casper/node_util.py check_protocols casper.conf

    +

    Verifying Successful Staging

    +

    After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:

    +
    curl -s http://127.0.0.1:8888/status | jq .next_upgrade
    +

    You should expect this output if properly staged, prior to upgrading:

    +
    $ curl -s localhost:8888/status | jq .next_upgrade
    {
    "activation_point": 4968,
    "protocol_version": "1.4.6"
    }
    +

    If you see null after waiting for a few minutes, then your upgrade staging was not executed successfully.

    +

    Note: The protocol version will change as per the next upgrade available.

    + + \ No newline at end of file diff --git a/2.0.0/resources/advanced/list-auth-keys-tutorial/index.html b/2.0.0/resources/advanced/list-auth-keys-tutorial/index.html new file mode 100644 index 000000000..311d23f2c --- /dev/null +++ b/2.0.0/resources/advanced/list-auth-keys-tutorial/index.html @@ -0,0 +1,238 @@ + + + + + +Authorization Keys | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Working with Authorization Keys

    +
    caution

    These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.

    +

    This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the list_authorization_keys function.

    +
    let authorization_keys = runtime::list_authorization_keys();
    +

    Remember that authorization keys are listed under a Deploy's approvals section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:

    +
    "approvals": [
    {
    "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",
    "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"
    }
    ]
    +

    The contract code in this example retrieves the set of authorization keys for a given deploy by calling the runtime::list_authorization_keys function. In other words, list_authorization_keys returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection.

    +

    Prerequisites

    + +

    Workflow

    +

    To start, clone the tutorials-example-wasm repository. Then, open the authorization-keys-example directory, prepare your Rust environment, and build the tests with the following commands.

    +
    git clone https://github.com/casper-ecosystem/tutorials-example-wasm
    cd tutorials-example-wasm/authorization-keys-example
    make prepare
    make test
    +

    Review the repository's structure:

    +
      +
    • client - A client folder containing two Wasm files +
        +
      • add_keys.wasm - Session code that adds an associated key to the calling account
      • +
      • contract_call.wasm - Session code that calls the contract's entry point and stores the result into a named key
      • +
      +
    • +
    • contract - A simple contract that demonstrates the usage of authorization keys and compiles into a contract.wasm file
    • +
    • tests - Tests and supporting utilities to verify and demonstrate the contract's expected behavior
    • +
    +
    note

    This tutorial highlights certain lines of code found in GitHub.

    +

    The example contract

    +

    Upon installation, the contract in this example stores the authorization keys that signed the installer deploy into a named key.

    +
    #[no_mangle]
    pub extern "C" fn init() {
    if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {
    let authorization_keys: Vec<AccountHash> =
    runtime::list_authorization_keys().iter().cloned().collect();

    let authorization_keys: Key = storage::new_uref(authorization_keys).into();
    runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);
    }
    }
    +

    The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following usage of runtime::list_authorization_keys retrieves the set of account hashes representing the keys signing the caller deploy.

    +
    let authorization_keys_caller: Vec<AccountHash> =
    runtime::list_authorization_keys().iter().cloned().collect();
    +

    Client Wasm files

    +

    add_keys.wasm

    +

    This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the Two-Party Multi-Signature tutorial.

    +

    contract_call.wasm

    +

    This session code calls the contract's entry point, which returns the intersection between two sets of keys:

    +
      +
    • The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)
    • +
    • The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy).
    • +
    +

    The intersection result is a list stored under a named key of the account calling the contract_call.wasm.

    +
    let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);
    let intersection =
    runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});
    runtime::put_key(&key_name, storage::new_uref(intersection).into());
    }
    +

    Testing this example

    +

    This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:

    +
      +
    • Testing the contract installation
    • +
    • Testing the contract's unique entry point
    • +
    • Testing the entry point using a client contract call
    • +
    +

    These tests focus on testing the contract installation.

    +

    Test 1: should_allow_install_contract_with_default_account

    + + + + + + + + + + + + + +
    Installer deploy authorization keysExpected outcome
    DEFAULT_ACCOUNT_ADDRSuccessful contract installation
    +

    This test signs the installer deploy with an authorization key DEFAULT_ACCOUNT_ADDR that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, DEFAULT_ACCOUNT_ADDR can be used to sign the deploy.

    +
    let session_code = PathBuf::from(CONTRACT_WASM);
    let session_args = RuntimeArgs::new();

    let deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, session_args)
    .build();

    +

    Test 2: should_disallow_install_with_non_added_authorization_key

    + + + + + + + + + + + + + +
    Installer deploy authorization keysExpected outcome
    DEFAULT_ACCOUNT_ADDR, account_addr_1Failed contract installation
    +

    This test tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected.

    +
    let session_code = PathBuf::from(CONTRACT_WASM);
    let session_args = RuntimeArgs::new();

    let deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, session_args)
    .build();

    let execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();
    builder.exec(execute_request).commit().expect_failure();
    let error = builder.get_error().expect("must have error");
    assert_eq!(error.to_string(), "Authorization failure: not authorized.");
    +

    Test 3: should_allow_install_with_added_authorization_key

    + + + + + + + + + + + + + +
    Installer deploy authorization keysExpected outcome
    DEFAULT_ACCOUNT_ADDR, account_addr_1Successful contract installation
    +

    This test demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account account_addr_1 to the default account's associated keys.

    +
    // Add account_addr_1 to the default account's associated keys
    let session_code = PathBuf::from(ADD_KEYS_WASM);
    let session_args = runtime_args! {
    ASSOCIATED_ACCOUNT => account_addr_1
    };

    let add_keys_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, session_args)
    .build();

    let add_keys_execute_request =
    ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();

    builder
    .exec(add_keys_execute_request)
    .commit()
    .expect_success();
    +

    Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with account_addr_1. See GitHub.

    +
    let session_code = PathBuf::from(CONTRACT_WASM);

    let deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, session_args)
    .build();

    let execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();
    builder.exec(execute_request).commit().expect_success();
    +

    The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys.

    +

    Test 4: should_allow_entry_point_with_installer_authorization_key

    + + + + + + + + + + + + + + + +
    Installer deploy authorization keysCaller deploy authorization keysIntersection returned by the entry point
    DEFAULT_ACCOUNT_ADDRaccount_addr_1, DEFAULT_ACCOUNT_ADDRaccount_addr_1
    +

    This test builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ACCOUNT_USER_1 signed only with account_addr_1. This is possible because the deploy action threshold for ACCOUNT_USER_1 is 1 as you can see here.

    +
    let contract_hash = builder
    .get_expected_account(*DEFAULT_ACCOUNT_ADDR)
    .named_keys()
    .get(CONTRACT_HASH)
    .expect("must have this entry in named keys")
    .into_hash()
    .map(ContractHash::new)
    .unwrap();

    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1])
    .with_address(account_addr_1)
    .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).expect_success().commit();
    +

    The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key account_addr_1. Thus, the caller deploy is expected to succeed and return a result.

    +

    Test 5: should_allow_entry_point_with_account_authorization_key

    + + + + + + + + + + + + + + + +
    Installer deploy authorization keysCaller deploy authorization keysIntersection returned by the entry point
    DEFAULT_ACCOUNT_ADDRaccount_addr_1, DEFAULT_ACCOUNT_ADDRDEFAULT_ACCOUNT_ADDR
    +

    This is the main test in this example repository. After installing the contract using the default account, the test adds the default account hash to ACCOUNT_USER_1 as an associated key.

    +
    let session_code = PathBuf::from(ADD_KEYS_WASM);
    let session_args = runtime_args! {
    ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR
    };

    let add_keys_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1])
    .with_address(account_addr_1)
    .with_session_code(session_code, session_args)
    .build();
    +

    Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ACCOUNT_USER_1 and has two authorization keys, account_addr_1 and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash.

    +
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])
    .with_address(account_addr_1)
    .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).expect_success().commit();
    +

    Test 6: should_disallow_entry_point_without_authorization_key

    + + + + + + + + + + + + + + + +
    Installer deploy authorization keysCaller deploy authorization keysIntersection returned by the entry point
    DEFAULT_ACCOUNT_ADDRaccount_addr_2None
    +

    This test verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys.

    +

    The default account hash is used to sign the installer deploy.

    +
    let session_code = PathBuf::from(CONTRACT_WASM);

    let deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, runtime_args! {})
    .build();
    +

    In the test, a new account, ACCOUNT_USER_2, creates a deploy invoking the contract's entry point and signs the deploy with account_addr_2. When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common.

    +
        // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys
    // The deploy will therefore revert with PermissionDenied
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_2])
    .with_address(account_addr_2)
    .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).commit().expect_failure();
    let error = builder.get_error().expect("must have User error: 0");
    assert_expected_error(
    error,
    0,
    "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",
    );
    +

    The following tests exercise the entry point using a contract call and verifying the result returned.

    +

    Test 7: should_allow_entry_point_through_contract_call_with_authorization_key

    + + + + + + + + + + + + + + + +
    Installer deploy authorization keysCaller deploy authorization keysIntersection returned by the entry point
    DEFAULT_ACCOUNT_ADDRaccount_addr_1, DEFAULT_ACCOUNT_ADDRDEFAULT_ACCOUNT_ADDR
    +

    This test validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys.

    +
    let session_code = PathBuf::from(CONTRACT_WASM);

    let deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])
    .with_address(*DEFAULT_ACCOUNT_ADDR)
    .with_session_code(session_code, runtime_args! {})
    .build();
    +

    The caller deploy is signed by account_addr_1 and DEFAULT_ACCOUNT_ADDR:

    +
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])
    .with_address(account_addr_1)
    .with_session_code(session_code, session_args)
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();
    builder.exec(entry_point_request).expect_success().commit();
    +

    The test then verifies that the result returned was saved in the named keys for ACCOUNT_USER_1, containing the default account hash.

    +
    let intersection_receipt: Key = *builder
    .get_expected_account(account_addr_1)
    .named_keys()
    .get(INTERSECTION_RECEIPT)
    .expect("must have this entry in named keys");

    let actual_intersection = builder
    .query(None, intersection_receipt, &[])
    .expect("must have stored_value")
    .as_cl_value()
    .map(|intersection_cl_value| {
    CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())
    })
    .unwrap()
    .unwrap();

    let expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];

    assert_eq!(actual_intersection, expected_intersection);
    +

    Test 8: should_disallow_entry_point_through_contract_call_without_authorization_key

    + + + + + + + + + + + + + + + +
    Installer deploy authorization keysCaller deploy authorization keysIntersection returned by the entry point
    DEFAULT_ACCOUNT_ADDRaccount_addr_1, account_addr_2None
    +

    The final test in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (account_addr_1, account_addr_2) and the installer deploy's authorization keys (DEFAULT_ACCOUNT_ADDR), the entry point returns an error.

    +
     let session_code = PathBuf::from(CONTRACT_CALL_WASM);

    let session_args = runtime_args! {
    ARG_CONTRACT_HASH => Key::from(contract_hash),
    ARG_KEY_NAME => INTERSECTION_RECEIPT
    };

    // account_addr_2 as an associated key is not among the default account's associated keys
    // The deploy will therefore revert with PermissionDenied
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1, account_addr_2])
    .with_address(account_addr_1)
    .with_session_code(session_code, session_args)
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).commit().expect_failure();

    let error = builder.get_error().expect("must have User error: 0");
    assert_expected_error(
    error,
    0,
    "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",
    );
    + + \ No newline at end of file diff --git a/2.0.0/resources/advanced/multi-sig/index.html b/2.0.0/resources/advanced/multi-sig/index.html new file mode 100644 index 000000000..8d41759d0 --- /dev/null +++ b/2.0.0/resources/advanced/multi-sig/index.html @@ -0,0 +1,22 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    The Native Multi-Signature Feature

    +

    In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.

    +

    The additional examples present use cases where Casper's multi-signature feature would be helpful.

    + + \ No newline at end of file diff --git a/next/resources/advanced/multi-sig/multi-sig-workflow/index.html b/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/index.html similarity index 82% rename from next/resources/advanced/multi-sig/multi-sig-workflow/index.html rename to 2.0.0/resources/advanced/multi-sig/multi-sig-workflow/index.html index c938c17d0..b93c9e843 100644 --- a/next/resources/advanced/multi-sig/multi-sig-workflow/index.html +++ b/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/index.html @@ -1,29 +1,29 @@ - + -Multi-Sig Workflow | Casper Docs - Redux +Multi-Sig Workflow | Casper Docs - Redux - - + +
    Version: Next

    Multi-Signature Workflow

    -

    The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.

    + submit an issue on Github
    Version: 2.0.0

    Multi-Signature Workflow

    +

    The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.

    warning

    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.

    Prerequisites

    The following prerequisites are required for this workflow:

      -
    1. Set up all the development environment prerequisites, including a funded account and the Casper CLI client
    2. -
    3. Complete the Two-Party Multi-Signature Deploys workflow and set up the source account for multi-signature deploys
    4. -
    5. Understand the Casper account-based model before proceeding
    6. +
    7. Set up all the development environment prerequisites, including a funded account and the Casper CLI client
    8. +
    9. Complete the Two-Party Multi-Signature Deploys workflow and set up the source account for multi-signature deploys
    10. +
    11. Understand the Casper account-based model before proceeding

    Session Code Required for Key Management

    To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case.

    @@ -325,6 +325,6 @@

    R
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    Associated key (04a9...)11
    Associated key (e2d0...)11
    Associated key (1fed...)1N/A (Removed)

    Next Steps

    -

    The next section contains additional examples where Casper's multi-signature feature would be helpful.

    +

    The next section contains additional examples where Casper's multi-signature feature would be helpful.

    \ No newline at end of file diff --git a/2.0.0/resources/advanced/multi-sig/other-scenarios/index.html b/2.0.0/resources/advanced/multi-sig/other-scenarios/index.html new file mode 100644 index 000000000..e17329d94 --- /dev/null +++ b/2.0.0/resources/advanced/multi-sig/other-scenarios/index.html @@ -0,0 +1,41 @@ + + + + + +Additional Examples | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Additional Examples

    +

    This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.

    +

    Example 1: An account with a single (primary) key

    +

    In this example, only one key (account-hash-a1…) can sign transactions in the name of this account. This key is the primary key of the account and has a weight equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions.

    +

    Account details in example 1:

    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +

    Example 2: An account with primary and associated keys

    +

    In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys.

    +

    Account details in example 2:

    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 2
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key for key management
    "weight": 2
    },
    {
    "account_address": "account-hash-b2…", // associated key used for deploys
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +

    Example 3: Multi-sig setup for deploys and account updates

    +

    The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates.

    +

    Account details in example 3:

    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 2
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 2
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +

    Example 4: Signing deploys but restricting account updates

    +

    This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key.

    +

    Account details in example 4:

    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +

    Example 5: Recovering a lost primary key

    +

    This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account.

    +

    Account details in example 5:

    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-d4…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    + + \ No newline at end of file diff --git a/2.0.0/resources/beginner/counter-testnet/commands/index.html b/2.0.0/resources/beginner/counter-testnet/commands/index.html new file mode 100644 index 000000000..8748460dd --- /dev/null +++ b/2.0.0/resources/beginner/counter-testnet/commands/index.html @@ -0,0 +1,51 @@ + + + + + +Casper-Client Commands | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Casper-Client Commands

    +

    State Root Hash

    +
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    +

    Example:

    +
    casper-client get-state-root-hash --node-address http://[IP]:7777
    +

    You can find a list of Testnet IP addresses at CSPR live.

    +

    The first command to cover is the get-state-root-hash command from the casper-client tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys.

    +
    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.

    +

    Querying Network State

    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)
    +

    This command allows you to query the state of a Casper network at a given moment in time, which is specified by the state-root-hash described above.

    +
      +
    • The node-address is the server on the network.
    • +
    • The key is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types.
    • +
    • The optional query path argument (q) allows you to drill into the specifics of a query concerning the key.
    • +
    +

    Put Deploys (onto the Chain)

    +

    Deploy via a compiled Wasm binary

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-test \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [CONTRACT_PATH]/counter-v1.wasm
    +

    This command creates a deploy and sends it to the network for execution. In this first usage of the command,

    +
      +
    • The session-path points to a compiled Wasm contract.
    • +
    • This contract is then installed on the network specified by the chain-name. The Testnet is "casper-test" but this is configurable.
    • +
    • The payment-amount is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds.
    • +
    +

    Deploy via a named key already on the blockchain

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-test \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +

    This second usage of put-deploy does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts.

    +

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    +

    Get Deploys (from the Chain)

    +
    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    + + \ No newline at end of file diff --git a/2.0.0/resources/beginner/counter-testnet/overview/index.html b/2.0.0/resources/beginner/counter-testnet/overview/index.html new file mode 100644 index 000000000..9cfa6523d --- /dev/null +++ b/2.0.0/resources/beginner/counter-testnet/overview/index.html @@ -0,0 +1,23 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Overview

    +

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    +

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    +

    image

    + + \ No newline at end of file diff --git a/next/resources/beginner/counter-testnet/walkthrough/index.html b/2.0.0/resources/beginner/counter-testnet/walkthrough/index.html similarity index 71% rename from next/resources/beginner/counter-testnet/walkthrough/index.html rename to 2.0.0/resources/beginner/counter-testnet/walkthrough/index.html index 35b8c1d09..a1ff757d2 100644 --- a/next/resources/beginner/counter-testnet/walkthrough/index.html +++ b/2.0.0/resources/beginner/counter-testnet/walkthrough/index.html @@ -1,21 +1,21 @@ - + -Tutorial Walkthrough | Casper Docs - Redux +Tutorial Walkthrough | Casper Docs - Redux - - + +
    Version: 2.0.0

    Tutorial Walkthrough

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    Clone the Repository

    First, you will need to clone the counter contract repository on our local machine.

    @@ -111,6 +111,6 @@

    Get the network state, specifically for the count variable this time:

    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"

    If all went according to plan, your count value should be 2 at this point.

    -

    Congratulations on building, installing, and using a smart contract on the Testnet!

    +

    Congratulations on building, installing, and using a smart contract on the Testnet!

    \ No newline at end of file diff --git a/2.0.0/resources/beginner/counter/commands/index.html b/2.0.0/resources/beginner/counter/commands/index.html new file mode 100644 index 000000000..604f73da7 --- /dev/null +++ b/2.0.0/resources/beginner/counter/commands/index.html @@ -0,0 +1,51 @@ + + + + + +Casper-Client Commands | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Casper-Client Commands

    +

    Faucet Account Information

    +
    nctl-view-faucet-account
    +

    This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's secret key location and the account hash, which are used to sign deploys and query the network state, respectively.

    +

    State Root Hash

    +
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    +

    The first command to cover is the get-state-root-hash command from the casper-client tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys.

    +
    note

    After sending 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.

    +

    Querying Network State

    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)
    +

    This command allows you to query the state of a Casper network at a given moment in time, which is specified by the state-root-hash described above.

    +
      +
    • The node-address is the location of the RPC endpoint, which is typically represented in the form http://IP:PORT. In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is http://localhost:11101.
    • +
    • The key is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types.
    • +
    • The optional query path argument (q) allows you to drill into the specifics of a query concerning the key.
    • +
    +

    Put Deploys (onto the Chain)

    +

    Deploy via a compiled Wasm binary

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-net-1 \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [CONTRACT_PATH]/counter-v1.wasm
    +

    This command creates a deploy and sends it to the network for execution. In this first usage of the command,

    +
      +
    • The session-path points to a compiled Wasm contract.
    • +
    • This contract is then installed on the network specified by the chain-name. By default, NCTL names the chain "casper-net-1" but this is configurable.
    • +
    • The payment-amount is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds.
    • +
    +

    Deploy via a named key already on the blockchain

    +
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name casper-net-1 \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-name "counter" \
    --session-entry-point "counter_inc"
    +

    This second usage of put-deploy does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts.

    +

    This examples uses "counter" and "counter_inc" from the tutorial walkthrough. However, these will be different when you write your contracts.

    +

    Get Deploys (from the Chain)

    +
    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    + + \ No newline at end of file diff --git a/2.0.0/resources/beginner/counter/overview/index.html b/2.0.0/resources/beginner/counter/overview/index.html new file mode 100644 index 000000000..2ef19b3eb --- /dev/null +++ b/2.0.0/resources/beginner/counter/overview/index.html @@ -0,0 +1,23 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Overview

    +

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    +

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    +

    image

    + + \ No newline at end of file diff --git a/next/resources/beginner/counter/walkthrough/index.html b/2.0.0/resources/beginner/counter/walkthrough/index.html similarity index 71% rename from next/resources/beginner/counter/walkthrough/index.html rename to 2.0.0/resources/beginner/counter/walkthrough/index.html index a8c3590d7..1f2172b26 100644 --- a/next/resources/beginner/counter/walkthrough/index.html +++ b/2.0.0/resources/beginner/counter/walkthrough/index.html @@ -1,21 +1,21 @@ - + -Tutorial Walkthrough | Casper Docs - Redux +Tutorial Walkthrough | Casper Docs - Redux - - + +
    Version: 2.0.0

    Tutorial Walkthrough

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    Clone the Repository

    First, you will need to clone the counter contract repository on our local machine.

    @@ -49,7 +49,7 @@

    Creat

    After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network.

    If you run the following line in your terminal, you should be able to spin up a network effortlessly.

    nctl-assets-setup && nctl-start
    -
    note

    If it fails for any reason, please refer the NCTL tutorial and make sure that all your packages are up to date.

    +
    note

    If it fails for any reason, please refer the NCTL tutorial and make sure that all your packages are up to date.

    View the Network State

    With a network up and running, you can use the casper-client query-global-state command to check the status of the network. However, you first need an AccountHash and the state-root-hash so that you can get the current snapshot. Once you have that information, check the status of the network.

    You will need to use the following three commands:

    @@ -116,6 +116,6 @@

    Get the network state, specifically for the count variable this time:

    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"

    If all went according to plan, your count value should be 2 at this point.

    -

    Congratulations on building, installing, and using a smart contract on your local network!

    +

    Congratulations on building, installing, and using a smart contract on your local network!

    \ No newline at end of file diff --git a/next/resources/build-on-casper/casper-open-source-software/index.html b/2.0.0/resources/build-on-casper/casper-open-source-software/index.html similarity index 64% rename from next/resources/build-on-casper/casper-open-source-software/index.html rename to 2.0.0/resources/build-on-casper/casper-open-source-software/index.html index 5a40aad75..c59c4bd5b 100644 --- a/next/resources/build-on-casper/casper-open-source-software/index.html +++ b/2.0.0/resources/build-on-casper/casper-open-source-software/index.html @@ -1,21 +1,21 @@ - + -Open-Source Software | Casper Docs - Redux +Open-Source Software | Casper Docs - Redux - - + +
    Version: Next

    Ecosystem Open-Source Software

    + submit an issue on Github
    Version: 2.0.0

    Ecosystem Open-Source Software

    This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.

    @@ -526,6 +526,6 @@ -
    NameDescriptionAuthorLanguageLicenseLast Update DateType
    Basic Yield FarmStaking RewardsRengo LabsRustApache-2.0 license2022-06-24Staking
    Blockcerts on CasperIssues Blockcerts using the Bitcoin, Ethereum, or Casper blockchainamazanzanPythonMIT license2022-07-22Tokens
    BlockMatcher Frontend BackendPrivate Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches.LedgerLeapJavaScript-PHPMIT license2022-01-15Exchange
    Camel CasperApache Camel connector for the Casper BlockchainM.AbahmaneJavaMIT license2022-03-26Tools
    Casper .NET SDKCasper .NET Client SDK to interact with Casper network nodes via RPC.MAKE Software.NETApache-2.0 license2022-04-19Client SDK
    Casper Analytics AppCasper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod Appcaspercommunity.ioPHPMIT license2022-01-20Tools
    Casper C++ SDKC++ library to interact with Casper network nodes via RPCYusuf KetenC++Apache-2.0 license2022-09-13Client SDK
    Casper CalculatorCasper Earnings Calculator and Node MonitorCharles NguyenJavaScriptMIT license2021-09-26Tools
    Casper Contract UpgradeExample contract to demonstrate the general way of upgrading a contract and the necessary stepsCasper LabsRustApache-2.0 license2022-06-21Example Contracts
    Casper Dart SDKCasper Dart SDK is for interacting with the Casper Blockchain using RPC.TemiltasDartApache-2.0 license2022-06-26Client SDK
    Friendly Market's Casper variant of ERC20Implementation of the ERC20 standard for Casper networksFriendly MarketRustApache-2.0 license2022-08-10Tokens
    Casper Go SDKCasper Go SDKMAKE SoftwareGoApache-2.0 license2023-06-01Client SDK
    Casper Hello World ContractThis example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKeyCasper LabsRustNA2022-07-13Example contracts
    Casper JavaScript SDKCasper Client JavaScript SDKCasper LabsTypeScript-JavaScriptApache-2.0 license2022-09-13Client SDK
    Casper Kotlin SDKCasper Kotlin Client SDK to interact with a Casper network.tqhuy2018KotlinMIT license2022-07-21Client SDK
    Casper MetricsCasper Metrics - fast blockchain crawler, API, and analysis toolA3MCTypeScriptMIT license2022-09-09Tools
    Casper NCTL DockerA Docker container that runs Casper NCTL as a serviceMAKE SoftwareShellApache-2.0 license2022-03-17Tools
    Casper Node-REDNodes to communicate with the Casper's Blockchain using node-redcaspercommunity.ioJavaScriptMIT license2022-02-08Tools
    Casper Objective-C SDKCasper Objective-C SDK is for interacting with the Casper Blockchain using RPC.hienbui9999Objective-CMIT license2022-06-18Client SDK
    Casper PHP SDKPHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHPMAKE SoftwarePHPApache-2.0 license2022-06-29Client SDK
    Casper Ruby Client SDKRuby SDK to interact with Casper network nodes via RPC.Sait GulmezRubyApache-2.0 license2022-03-08Client SDK
    Casper Scala SDKCasper Scala client SDK to interact with the Casper Network nodes via RPCM.AbahmaneScalaMIT license2022-03-23Client SDK
    Casper WalletA browser wallet for the Casper NetworkMAKE SoftwareTypeScript-JavaScriptApache-2.0 license2023-04-12Wallet
    Casper SSI Web AppCasper SSI Framework in the form of a demo web application.Credentia NetworkTypeScriptMIT license2022-06-29Tools
    Casper StorageCasper storage - HD walletsCasperDashTypeScriptApache-2.0 license2022-09-14Wallet
    Casper Swift SDKCasper Client SDK. Casper SDK methods implementation in Swift.hienbui9999SwiftMIT license2022-06-08Client SDK
    Casper Two-Party MultiSig ContractThis example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys.Casper LabsRustNA2022-04-26Example contracts
    Casper WorldCasper network status and decentralization map web applicationNodes GuruTypeScriptMIT license2022-01-26Blockchain Explorer
    CasperDash WalletA non-custodial wallet for the Casper blockchainCasperDashJavaScriptMIT license2022-09-14Wallet
    CasperFYRE APIDispensory API interface for Casper MainnetLedgerLeapJavaScript-PHPApache-2.0 license2022-09-06Tools
    CasperHoldersFirst 3rd party UI to interact with Casper BlockchainCasperHoldersJavaScriptApache-2.0 license2022-08-23Blockchain Explorer
    CasperSignThe First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper BlockchainChronoLogic and Digital StrategiesTypeScriptNA2022-08-31dApp
    CEP-78 Enhanced NFT StandardStandard Contract Generator for NFTsCasper LabsRustApache-2.0 license2022-08-23NFT
    CES Rust Event EmitterRust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)MAKE SoftwareRustApache-2.0 license2023-05-11dApp library
    CES JS ParserJS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareJavaScriptApache-2.0 license2023-03-27dApp library
    CES Go ParserGo library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareGoApache-2.0 license2023-06-02dApp library
    Clearest StakeStaking Asset Manager for Node operators and groupsLedgerLeapPHPApache-2.0 license2022-04-02DeFi
    DAO ContractsSmart Contracts for the MVPR On-Chain Governance System on CasperMAKE SoftwareRustApache-2.0 license2022-07-17DAO
    DHF PAYThe crypto currency payment gateway on the CSPR blockchainDHFinanceTypeScriptApache-2.0 license2022-08-28Payments
    DLN DAODLN DAOAlphaFinTypeScriptMIT license2022-09-10DAO
    DotOracleRealtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains.DotOracle NetworkTypeScriptNA2022-09-26Bridge
    Dragon’s Lair Style StakingLair Style StakingRengo LabsRustApache-2.0 license2022-06-24Staking
    Subscription BillingERC-1337 subscription billingRengo LabsRustMIT license2022-04-07Tokens
    Casper Fungible TokenImplementation of Fungible Tokens for Casper networksCasper LabsRustApache-2.0 license2022-09-01Tokens
    Advanced Fungible TokenERC-777 + 1820 Advanced Fungible Token with Callbacks & Self IdentificationRengo LabsRustApache-2.0 license2022-08-16Tokens
    Helper BotHelper bot for improving DevDao VAs productivityA3MCTypeScriptMIT license2022-08-19Tools
    Java SDKCasper Client Java SDKSyntiFiJavaApache-2.0 license2021-04-20Client SDK
    KYC Proxy ContactThis is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)Casper LabsRustNA2022-07-01Example contracts
    LiquidNFTNFT Collateralized LoansRengo LabsJavaScriptGNU General Public License v3.02022-09-15NFT
    Payment Example ContractThis example demonstrates the usage of purses to transfer motes inside a contractCasper LabsRustNA2022-06-22Example contracts
    ServicesDAOThe ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR.Ekon YazilimHTML-CSS-C#MIT license2022-09-13DAO
    Uniswap DemoAppUniswap UI + ContractsRengo LabsJavaScriptGPL-3.0 license2022-09-15DeFi
    Verified Impact NFTAn NFT platform dedicated to impact causes with verification of the beneficiariesAlphaFinJavaScript-RustMIT license2022-07-08NFT
    UseWalletuseWallet is a collection of React Hooks containing everything you need to start working with a Casper networkCasperDashTypescript-ReactMIT license2023-09-19dApp library
    Testnet FaucetA faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for freeCasperDashTypescript-ReactMIT license2023-09-19Tools
    +
    NameDescriptionAuthorLanguageLicenseLast Update DateType
    Basic Yield FarmStaking RewardsRengo LabsRustApache-2.0 license2022-06-24Staking
    Blockcerts on CasperIssues Blockcerts using the Bitcoin, Ethereum, or Casper blockchainamazanzanPythonMIT license2022-07-22Tokens
    BlockMatcher Frontend BackendPrivate Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches.LedgerLeapJavaScript-PHPMIT license2022-01-15Exchange
    Camel CasperApache Camel connector for the Casper BlockchainM.AbahmaneJavaMIT license2022-03-26Tools
    Casper .NET SDKCasper .NET Client SDK to interact with Casper network nodes via RPC.MAKE Software.NETApache-2.0 license2022-04-19Client SDK
    Casper Analytics AppCasper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod Appcaspercommunity.ioPHPMIT license2022-01-20Tools
    Casper C++ SDKC++ library to interact with Casper network nodes via RPCYusuf KetenC++Apache-2.0 license2022-09-13Client SDK
    Casper CalculatorCasper Earnings Calculator and Node MonitorCharles NguyenJavaScriptMIT license2021-09-26Tools
    Casper Contract UpgradeExample contract to demonstrate the general way of upgrading a contract and the necessary stepsCasper LabsRustApache-2.0 license2022-06-21Example Contracts
    Casper Dart SDKCasper Dart SDK is for interacting with the Casper Blockchain using RPC.TemiltasDartApache-2.0 license2022-06-26Client SDK
    Friendly Market's Casper variant of ERC20Implementation of the ERC20 standard for Casper networksFriendly MarketRustApache-2.0 license2022-08-10Tokens
    Casper Go SDKCasper Go SDKMAKE SoftwareGoApache-2.0 license2023-06-01Client SDK
    Casper Hello World ContractThis example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKeyCasper LabsRustNA2022-07-13Example contracts
    Casper JavaScript SDKCasper Client JavaScript SDKCasper LabsTypeScript-JavaScriptApache-2.0 license2022-09-13Client SDK
    Casper Kotlin SDKCasper Kotlin Client SDK to interact with a Casper network.tqhuy2018KotlinMIT license2022-07-21Client SDK
    Casper MetricsCasper Metrics - fast blockchain crawler, API, and analysis toolA3MCTypeScriptMIT license2022-09-09Tools
    Casper NCTL DockerA Docker container that runs Casper NCTL as a serviceMAKE SoftwareShellApache-2.0 license2022-03-17Tools
    Casper Node-REDNodes to communicate with the Casper's Blockchain using node-redcaspercommunity.ioJavaScriptMIT license2022-02-08Tools
    Casper Objective-C SDKCasper Objective-C SDK is for interacting with the Casper Blockchain using RPC.hienbui9999Objective-CMIT license2022-06-18Client SDK
    Casper PHP SDKPHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHPMAKE SoftwarePHPApache-2.0 license2022-06-29Client SDK
    Casper Ruby Client SDKRuby SDK to interact with Casper network nodes via RPC.Sait GulmezRubyApache-2.0 license2022-03-08Client SDK
    Casper Scala SDKCasper Scala client SDK to interact with the Casper Network nodes via RPCM.AbahmaneScalaMIT license2022-03-23Client SDK
    Casper WalletA browser wallet for the Casper NetworkMAKE SoftwareTypeScript-JavaScriptApache-2.0 license2023-04-12Wallet
    Casper SSI Web AppCasper SSI Framework in the form of a demo web application.Credentia NetworkTypeScriptMIT license2022-06-29Tools
    Casper StorageCasper storage - HD walletsCasperDashTypeScriptApache-2.0 license2022-09-14Wallet
    Casper Swift SDKCasper Client SDK. Casper SDK methods implementation in Swift.hienbui9999SwiftMIT license2022-06-08Client SDK
    Casper Two-Party MultiSig ContractThis example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys.Casper LabsRustNA2022-04-26Example contracts
    Casper WorldCasper network status and decentralization map web applicationNodes GuruTypeScriptMIT license2022-01-26Blockchain Explorer
    CasperDash WalletA non-custodial wallet for the Casper blockchainCasperDashJavaScriptMIT license2022-09-14Wallet
    CasperFYRE APIDispensory API interface for Casper MainnetLedgerLeapJavaScript-PHPApache-2.0 license2022-09-06Tools
    CasperHoldersFirst 3rd party UI to interact with Casper BlockchainCasperHoldersJavaScriptApache-2.0 license2022-08-23Blockchain Explorer
    CasperSignThe First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper BlockchainChronoLogic and Digital StrategiesTypeScriptNA2022-08-31dApp
    CEP-78 Enhanced NFT StandardStandard Contract Generator for NFTsCasper LabsRustApache-2.0 license2022-08-23NFT
    CES Rust Event EmitterRust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)MAKE SoftwareRustApache-2.0 license2023-05-11dApp library
    CES JS ParserJS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareJavaScriptApache-2.0 license2023-03-27dApp library
    CES Go ParserGo library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareGoApache-2.0 license2023-06-02dApp library
    Clearest StakeStaking Asset Manager for Node operators and groupsLedgerLeapPHPApache-2.0 license2022-04-02DeFi
    DAO ContractsSmart Contracts for the MVPR On-Chain Governance System on CasperMAKE SoftwareRustApache-2.0 license2022-07-17DAO
    DHF PAYThe crypto currency payment gateway on the CSPR blockchainDHFinanceTypeScriptApache-2.0 license2022-08-28Payments
    DLN DAODLN DAOAlphaFinTypeScriptMIT license2022-09-10DAO
    DotOracleRealtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains.DotOracle NetworkTypeScriptNA2022-09-26Bridge
    Dragon’s Lair Style StakingLair Style StakingRengo LabsRustApache-2.0 license2022-06-24Staking
    Subscription BillingERC-1337 subscription billingRengo LabsRustMIT license2022-04-07Tokens
    Casper Fungible TokenImplementation of Fungible Tokens for Casper networksCasper LabsRustApache-2.0 license2022-09-01Tokens
    Advanced Fungible TokenERC-777 + 1820 Advanced Fungible Token with Callbacks & Self IdentificationRengo LabsRustApache-2.0 license2022-08-16Tokens
    Helper BotHelper bot for improving DevDao VAs productivityA3MCTypeScriptMIT license2022-08-19Tools
    Java SDKCasper Client Java SDKSyntiFiJavaApache-2.0 license2021-04-20Client SDK
    KYC Proxy ContactThis is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)Casper LabsRustNA2022-07-01Example contracts
    LiquidNFTNFT Collateralized LoansRengo LabsJavaScriptGNU General Public License v3.02022-09-15NFT
    Payment Example ContractThis example demonstrates the usage of purses to transfer motes inside a contractCasper LabsRustNA2022-06-22Example contracts
    ServicesDAOThe ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR.Ekon YazilimHTML-CSS-C#MIT license2022-09-13DAO
    Uniswap DemoAppUniswap UI + ContractsRengo LabsJavaScriptGPL-3.0 license2022-09-15DeFi
    Verified Impact NFTAn NFT platform dedicated to impact causes with verification of the beneficiariesAlphaFinJavaScript-RustMIT license2022-07-08NFT
    UseWalletuseWallet is a collection of React Hooks containing everything you need to start working with a Casper networkCasperDashTypescript-ReactMIT license2023-09-19dApp library
    Testnet FaucetA faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for freeCasperDashTypescript-ReactMIT license2023-09-19Tools
    \ No newline at end of file diff --git a/2.0.0/resources/build-on-casper/introduction/index.html b/2.0.0/resources/build-on-casper/introduction/index.html new file mode 100644 index 000000000..61a4f7af5 --- /dev/null +++ b/2.0.0/resources/build-on-casper/introduction/index.html @@ -0,0 +1,77 @@ + + + + + +Build on Casper | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Building on Casper

    +

    This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.

    + +

    Thriving Ecosystem

    +

    The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use.

    +

    Wallets

    + +

    Block Explorers

    + +

    Developer Tools

    + +

    Open Source Software

    + +

    Developer-Friendly Language

    +

    Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet.

    +

    Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an open standard for performance and portability of modern web applications.

    +
    note

    Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available.

    +

    Powerful Accounts

    +

    Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the Casper Permissions Model for more details.

    +

    Contract Upgrades

    +

    Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts.

    +

    Development Tools

    +

    IDE Integration

    +

    The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started.

    +

    CI/CD

    +

    Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline.

    +

    Local Network Testing

    +

    We also offer a tool to run a local Casper Network Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface.

    +

    Public Mainnet and Testnet

    +

    The Casper Mainnet is a public, open-source, community-driven ecosystem. You can also explore the Testnet to test drive your applications and estimate gas costs.

    +

    AWS

    +

    We also offer several tools to run AWS instances of Casper nodes.

    +

    SDK Client Libraries

    +

    In addition to the default command-line Rust client, the Casper community is building other clients in JavaScript, Java, Golang, Python, C#, and other languages.

    +

    No Gas Fees

    +

    Casper seeks to eliminate volatility and improve developer and enterprise experiences by eliminating transaction fees on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows.

    + + \ No newline at end of file diff --git a/2.0.0/resources/changelog/index.html b/2.0.0/resources/changelog/index.html new file mode 100644 index 000000000..b615e0742 --- /dev/null +++ b/2.0.0/resources/changelog/index.html @@ -0,0 +1,35 @@ + + + + + +Documentation Updates by Protocol Release | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Documentation Updates by Protocol Release

    +

    Condor (2.0)

    +

    Concepts

    +

    The following are changes introduced alongside release of the Condor network upgrade.

    +

    Understanding Key Types - Additional Key Types and document restructuring.

    +

    Serialization Standard - Serialization information for new types.

    +

    Smart Contracts - Information on the new factory pattern feature for smart contracts.

    +

    Developers

    +

    Building dApps -> Monitoring and Consuming Events - Information related to contract-level events.

    +

    Casper JSON-RPC API -> Informational JSON-RPC Methods - New RPC methods.

    +

    Casper JSON-RPC API -> Transactional JSON-RPC Methods - New RPC methods.

    +

    Casper JSON-RPC API -> Types - New parameters used by the JSON-RPC API.

    +

    Writing On-Chain Code -> Contract-Level Events - Guide to the new contract-level events feature.

    +

    Writing On-Chain Code -> Factory Contracts - Guide to the new factory pattern for smart contracts.

    +

    Operators

    +

    Private Network -> The Chainspec - Updates to the chainpsec relating to contract-level events.

    + + \ No newline at end of file diff --git a/2.0.0/resources/index.html b/2.0.0/resources/index.html new file mode 100644 index 000000000..c0558b934 --- /dev/null +++ b/2.0.0/resources/index.html @@ -0,0 +1,89 @@ + + + + + +Resources Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Resources Overview

    +

    Building on Casper

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Wallets and Block ExplorersWallets that support the native Casper token $CSPR
    WebAssemblyLearn why WebAssembly is an advantage in contract development
    AccountsThe Casper account-model allowing for multi-signature deploys
    Developer toolsAvailable development tools
    Ecosystem ProjectsExplore some open-source code available in the Casper ecosystem
    +

    Move to Casper

    + + + + + + + + + + + + + +
    TopicDescription
    Move to CasperLearn how to start working with Casper, having previous knowledge of other blockchains
    +

    Tutorials

    + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    QuickstartInstall Rust and setup a Casper environment
    BeginnerLearn the basics, such as installing and upgrading contracts
    AdvancedLearn about multi-sig, authorization keys, exchange integration, and storage
    + + \ No newline at end of file diff --git a/2.0.0/resources/moving-to-casper/index.html b/2.0.0/resources/moving-to-casper/index.html new file mode 100644 index 000000000..2eb5b5c2e --- /dev/null +++ b/2.0.0/resources/moving-to-casper/index.html @@ -0,0 +1,182 @@ + + + + + +Move to Casper | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem';

    +

    Moving to Casper from another Blockchain

    +

    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
    2. +
    3. Variable Storage and State Management
    4. +
    5. Contract Functions
    6. +
    7. Passing Arguments
    8. +
    +

    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.

    +

    Smart Contract Platform

    + + +

    Casper smart contracts are written in Rust.

    +

    Variables defined within the smart contract can be stored as either Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

    +

    The call function serves as the main entry point of the smart contract. 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.

    +
    + +

    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 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, 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.

    +
    + +

    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.

    +

    All public methods defined within the contract serve as its interface, exposing its functionality.

    +

    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.

    +
    + +

    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.

    +

    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 Module's public methods are its interface and can be invoked from code outside the blockchain.

    +

    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.

    +
    + +

    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.

    +

    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.

    +
    +
    +

    Variable Storage and State Management

    + + +

    Variables can be stored as Named Keys or Dictionaries as described in Reading and Writing Data to the Blockchain.

    +

    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.

    +
    + +

    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.

    +
    + +

    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.

    +

    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.

    +

    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.

    +

    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.

    +
    + +

    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.

    +

    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.

    +
    +
    +

    Contract Functions

    + + +

    For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:

    +
    #[no_mangle]
    pub extern "C" fn counter_inc() {

    // Entry point body
    }
    +

    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 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 syntax described in the Interacting with Runtime Return Values tutorial.

    +
    runtime::ret(value);
    +

    Each call to an entry point is treated as a Deploy to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).

    +
    + +

    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:

    +
    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:

    +
    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:

    +
    pub fn add_message(&mut self, ...) { }
    +

    For public methods that return variables, the definition would be:

    +
    pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }
    +

    The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements.

    +
    + +

    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:

    +
    public fun start_collection(account: &signer) {}
    +

    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 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:

    +
    entrypoint!(process_instruction);
    +

    The implementation of the entry point may resemble the following:

    +
    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

    + + +

    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:

    +
    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'"
    +

    To understand the context of this example, refer to: Delegating with the Casper Client.

    +

    In the contract, you can access the session arguments as follows:

    +
    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.

    +
    + +

    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 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.

    +
    + +

    Like Near, Aptos 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.

    +
    +
    +

    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).

    +
      +
    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.

      +
    2. +
    3. +

      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.

      +
    4. +
    5. +

      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.

      +
    6. +
    7. +

      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.

      +
    8. +
    9. +

      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.

      +
    10. +
    +

    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 diff --git a/next/resources/quick-start/index.html b/2.0.0/resources/quick-start/index.html similarity index 72% rename from next/resources/quick-start/index.html rename to 2.0.0/resources/quick-start/index.html index 79032ed9e..303aedcdb 100644 --- a/next/resources/quick-start/index.html +++ b/2.0.0/resources/quick-start/index.html @@ -1,21 +1,21 @@ - + -Quickstart | Casper Docs - Redux +Quickstart | Casper Docs - Redux - - + +
    Version: Next

    Quickstart

    + submit an issue on Github
    Version: 2.0.0

    Quickstart

    Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.

    Prerequisites

      @@ -36,7 +36,7 @@

      Stepscargo install cargo-casper

    1. -

      Install the Casper client:

      +

      Install the Casper client:

      cargo install casper-client

      If you have issues installing the casper-client, you may need additional libraries.

    If everything went according to plan, the value should be 1. Look at the "parsed" value below.

    {
    "id": 8523290678829319485,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.6",
    "block_header": null,
    "merkle_proof": "[85716 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "01000000",
    "cl_type": "I32",
    "parsed": 1
    }
    }
    }
    }
    -

    You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts.

    +

    You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts.

    \ No newline at end of file diff --git a/next/resources/tokens/cep18/full-tutorial/index.html b/2.0.0/resources/tokens/cep18/full-tutorial/index.html similarity index 86% rename from next/resources/tokens/cep18/full-tutorial/index.html rename to 2.0.0/resources/tokens/cep18/full-tutorial/index.html index cb9a3bc42..6584572cd 100644 --- a/next/resources/tokens/cep18/full-tutorial/index.html +++ b/2.0.0/resources/tokens/cep18/full-tutorial/index.html @@ -1,26 +1,26 @@ - + -Fungible Token Workflow | Casper Docs - Redux +Fungible Token Workflow | Casper Docs - Redux - - + +
    Version: 2.0.0

    Casper Fungible Token Tutorial

    This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.

    The Ethereum Request for Comment (ERC-20) standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded.

    The Casper Fungible Token standard is the Casper Platform's ERC-20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed.

    The following functions implement the rules defined by Casper Fungible Tokens: totalSupply, transfer, transferFrom, approve, balanceOf, and allowance. A portion of this tutorial reviews the contract and the casper_fungible_token library.

    -

    The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read first.

    +

    The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read first.

    Preparation

    First clone the contract from GitHub:

    git clone https://github.com/casper-ecosystem/cep18 && cd cep18
    @@ -28,7 +28,7 @@

    Preparation
    make prepare

    If your environment is set up correctly, you will see this output:

    rustup target add wasm32-unknown-unknown
    info: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date
    -

    If you do not see this message, check the Getting Started Guide.

    +

    If you do not see this message, check the Getting Started Guide.

    Next, compile your contract and run the contract unit tests.

    make build-contract
    make test

    Contract Implementation

    @@ -76,13 +76,13 @@

    Contract Me
  • transfer_from - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner
  • Installing the Contract

    -

    After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the Sending Deploys to a Casper network using the Rust Client section to learn more about install contracts.

    +

    After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the Sending Deploys to a Casper network using the Rust Client section to learn more about install contracts.

    Deploy Prerequisites

    Basic Flow

    Here are the basic steps to install the Casper Fungible Token contract on a Casper Network.

    @@ -113,11 +113,11 @@

    C

    make test

    Getting an IP Address from a Testnet Peer

    -

    We will use a Testnet peer to send the deploy. Read the guide to acquiring a node address if needed.

    +

    We will use a Testnet peer to send the deploy. Read the guide to acquiring a node address if needed.

    Viewing the Network Status

    This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query.

    Getting the state root hash

    -

    Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the Node IP address taken from a Testnet peer.

    +

    Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the Node IP address taken from a Testnet peer.

    casper-client get-state-root-hash --node-address http://<HOST:PORT>

    Getting the account hash

    Run the following command and supply the path to your public key in hexadecimal format to get the account hash.

    @@ -187,6 +187,6 @@

    casper-client query-global-state --node-address http://95.216.24.237:7777 \
    --state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \
    --key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \
    -q "test_contract/name"

    Result:

    You can see that the name is CasperTest in this example.

    -
    {
    "id": -3650676146668320186,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "block_header": null,
    "merkle_proof": "[80252 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    }
    }

    +
    {
    "id": -3650676146668320186,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "block_header": null,
    "merkle_proof": "[80252 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    }
    }

    \ No newline at end of file diff --git a/next/resources/tokens/cep18/query/index.html b/2.0.0/resources/tokens/cep18/query/index.html similarity index 62% rename from next/resources/tokens/cep18/query/index.html rename to 2.0.0/resources/tokens/cep18/query/index.html index c33556618..ee2d59e81 100644 --- a/next/resources/tokens/cep18/query/index.html +++ b/2.0.0/resources/tokens/cep18/query/index.html @@ -1,21 +1,21 @@ - + -CEP-18 Contract Details | Casper Docs - Redux +CEP-18 Contract Details | Casper Docs - Redux - - + +
    Version: 2.0.0

    Exploring the CEP-18 Contracts

    This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:

    • @@ -53,7 +53,7 @@

      {
      "id": -1426549275795832481,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.0.0",
      "block_header": null,
      "merkle_proof": "[3370 hex chars]",
      "stored_value": {
      "Contract": {
      "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",
      "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",
      "named_keys": [
      {
      "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",
      "name": "result"
      }
      ],
      "protocol_version": "1.0.0"
      }
      }
      }
      }

    Next Steps

    +
  • CEP-18 Token Transfers and Allowances
  • +
    \ No newline at end of file diff --git a/2.0.0/resources/tokens/cep18/quickstart-guide/index.html b/2.0.0/resources/tokens/cep18/quickstart-guide/index.html new file mode 100644 index 000000000..d07f3d218 --- /dev/null +++ b/2.0.0/resources/tokens/cep18/quickstart-guide/index.html @@ -0,0 +1,63 @@ + + + + + +On-chain Installation | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Installing and Interacting with a CEP-18 Contract

    +

    This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.

    +

    The Ethereum Request for Comment (ERC-20) standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded.

    +

    To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions.

    +

    For greater detail into the creation and mechanics of the Casper fungible token contract, see the full Casper Fungible Token Tutorial.

    +

    Prerequisites

    +

    Before using this guide, ensure you meet the following requirements:

    +
      +
    • Set up your machine as per the prerequisites
    • +
    • Use the [Casper command-line client]
    • +
    • Get a valid node-address
    • +
    • Know how to deploy a smart contract to a Casper network
    • +
    • Hold enough CSPR tokens to pay for transactions
    • +
    +

    Setup

    +

    Clone the fungible token (CEP-18) contract repository and run the make build-contract command. This will create the cep18.wasm and the cep18_test_contract.wasm. The token Wasm is the main contract. We will use the cep18_test_contract Wasm to query the balances and allowances of the fungible token balances throughout this workflow.

    +

    Install the Main Fungible Token Contract

    +

    The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:

    +
      +
    • Name - The name of your CEP-18 token
    • +
    • Symbol - The symbol used to refer to your CEP-18 token
    • +
    • Total_supply - The total supply of the CEP-18 token to be minted
    • +
    • Decimals - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a decimals setting of 3 would be 1,000.000 tokens)
    • +
    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18.wasm \
    --session-arg "name:string='CEP18'" \
    --session-arg "symbol:string='gris'" \
    --session-arg "total_supply:u256='100'" \
    --session-arg "decimals:u8='1'" \
    --payment-amount 150000000000
    +

    Install the cep18_test_contract Contract Package

    +

    The following command will install the CEP-18 helper contract that allows you to check balances and access approval features.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18_test_contract.wasm \
    --payment-amount 50000000000
    +

    At this point, the account that installed both the main contract and the helper contract will look like this.

    +
    {
    "src": {
    "Account": {
    "_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "namedKeys": [
    {
    "name": "cep18_test_contract",
    "key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"
    },
    {
    "name": "cep18_token_contract",
    "key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"
    },
    ],
    "mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",
    "associatedKeys": [
    {
    "accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "weight": 1
    }
    ],
    "actionThresholds": {
    "deployment": 1,
    "keyManagement": 1
    }
    }
    }
    }
    +

    Note:

    +
    +
      +
    1. cep18_token_contract is the main contract, and is a stored contract, record its hash
    2. +
    3. cep18_test_call is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state.
    4. +
    +
    +

    Next Steps

    +

    In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals.

    +
    + + \ No newline at end of file diff --git a/next/resources/tokens/cep18/tests/index.html b/2.0.0/resources/tokens/cep18/tests/index.html similarity index 89% rename from next/resources/tokens/cep18/tests/index.html rename to 2.0.0/resources/tokens/cep18/tests/index.html index 7ee86fde5..ad6ba694f 100644 --- a/next/resources/tokens/cep18/tests/index.html +++ b/2.0.0/resources/tokens/cep18/tests/index.html @@ -1,23 +1,23 @@ - + -Testing Guide | Casper Docs - Redux +Testing Guide | Casper Docs - Redux - - + +
    Version: 2.0.0

    Testing Framework for CEP-18

    The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.

    -

    The following section reviews the GitHub testing folder, which creates a testing framework for the Casper Fungible Token project. You can find more details about testing Casper contracts here.

    +

    The following section reviews the GitHub testing folder, which creates a testing framework for the Casper Fungible Token project. You can find more details about testing Casper contracts here.

    The following is an example of a complete test expecting a failed transfer:

    #[should_panic(expected = "ApiError::User(65534) [131070]")]
    #[test]
    fn should_not_transfer_with_insufficient_balance() {
    let mut fixture = TestFixture::install_contract();

    let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();
    assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);

    fixture.transfer(
    Key::from(fixture.bob),
    initial_ali_balance + U256::one(),
    fixture.ali,
    );
    }

    To build and run the tests, issue the following command in the project folder, cep18:

    @@ -35,7 +35,7 @@

    Testing Logic<

    The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints.

    Setting up the Testing Context

    -

    The code in the utility directory initializes the blockchain's global state with all the data and entrypoints the smart contract needs.

    +

    The code in the utility directory initializes the blockchain's global state with all the data and entrypoints the smart contract needs.

    Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the constants.rs file within the utility directory. For the most up-to-date version of the code, visit GitHub.

    Example of required constants
    @@ -75,6 +75,6 @@

    Running th
    #[cfg(test)]
    mod allowance;
    #[cfg(test)]
    mod install;
    #[cfg(test)]
    mod mint_and_burn;
    #[cfg(test)]
    mod transfer;
    #[cfg(test)]
    mod utility;

    To run the tests, navigate to the parent cep18 directory and run the command:

    make test
    -

    This example uses bash. If you are using a Rust IDE, you need to configure it to run the tests.

    +

    This example uses bash. If you are using a Rust IDE, you need to configure it to run the tests.

    \ No newline at end of file diff --git a/2.0.0/resources/tokens/cep18/transfer/index.html b/2.0.0/resources/tokens/cep18/transfer/index.html new file mode 100644 index 000000000..912aba4cf --- /dev/null +++ b/2.0.0/resources/tokens/cep18/transfer/index.html @@ -0,0 +1,135 @@ + + + + + +CEP-18 Transfers | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    CEP-18 Token Transfers and Allowances

    +

    This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.

    +

    Transferring CEP-18 Tokens to Another Account

    +

    The following command will invoke the transfer entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account.

    +
    casper-client put-deploy -n http://<node IP>:<PORT> \
    // The chain name of the Casper network on which your CEP-18 instance was installed.
    --chain-name <CHAIN NAME>\
    // The local path to your account's secret key.
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    // The contract hash of your CEP-18 contract instance.
    --session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \
    // The name of the entry point you are invoking.
    --session-entry-point "transfer" \
    // The account hash of the account that you are sending CEP-18 tokens to.
    --session-arg "recipient:key='account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \
    // The amount of CEP-18 tokens you are sending to the receiving account.
    --session-arg "amount:u256='10'" \
    // The gas payment you are allotting, in motes.
    --payment-amount "10000000000"
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<node IP>:<PORT> \
    --chain-name <CHAIN NAME>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \
    --session-entry-point "transfer" \
    --session-arg "recipient:key='account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \
    --session-arg "amount:u256='50'" \
    --payment-amount "10000000000"
    +
    +

    This command will return a deploy hash that you can query using casper-client get-deploy. Querying the Deploy allows you to verify execution success, but you will need to use the check_balance_of entry point on the utility contract to verify the account's balance.

    +

    Invoking the check_balance_of Entry Point

    +

    The following Casper client command invokes the check_balance_of entry point on the cep18_test_contract.

    +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_test_contract" \
    --session-entry-point "check_balance_of" \
    // This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.
    --session-arg "token_contract:account_hash='account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180'" \
    // This is the account hash of the account you are checking the balance of.
    --session-arg "address:key='account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_test_contract" \
    --session-entry-point "check_balance_of" \
    --session-arg "token_contract:account_hash='account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180'" \
    --session-arg "address:key='account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    +

    After sending this command, you will need to query the results URef within the NamedKeys of your cep18_test_contract utility contract instance. More information on finding this URef can be found in the Exploring the CEP18 Contracts document.

    +

    You can use the following command to query global state for the results URef.

    +
    casper-client query-global-state -n http://<NODE IP>:<PORT> \
    // This is the `results` URef location from your `cep18_test_contract` `NamedKeys`
    --key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \
    --state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7
    +
    Casper client command without comments
    + +
    casper-client query-global-state -n http://<NODE IP>:<PORT> \
    --key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \
    --state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7
    +
    +

    This command should show something similar to the following in response, with parsed being the amount of CEP-18 tokens that the account holds.

    +
    {
    "id": -8841145064950441692,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block_header": null,
    "merkle_proof": "[3796 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "010a",
    "cl_type": "U256",
    "parsed": "10"
    }
    }
    }
    }
    +

    Approving an Allowance for Another Account

    +

    The Casper fungible token contract features an allowance entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance.

    +

    Approving an Account to Spend Tokens on Another Account's Behalf

    +

    The following command approves a third-party account to spend an allowance of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance.

    +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    // This is the contract hash of the CEP-18 token contract.
    --session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \
    --session-entry-point "approve" \
    // This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.
    --session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    // This is the number of CEP-18 tokens included in the allowance.
    --session-arg "amount:u256='15'" \
    --payment-amount "10000000000"
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \
    --session-entry-point "approve" \
    --session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    --session-arg "amount:u256='15'" \
    --payment-amount "10000000000"
    +
    +

    Verifying a Previously Issued Allowance

    +

    After approving an account to spend an allowance of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the allowance of the spender's account to the result URef of in the utility contract's NamedKeys:

    +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_test_contract" \
    --session-entry-point "check_allowance_of" \
    // This is the contract hash for the CEP-18 token.
    --session-arg "token_contract:account_hash='account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e'" \
    // This is the account hash for the account that owns the CEP-18 tokens.
    --session-arg "owner:key='account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2'" \
    // This is the account hash for the account previously authorized to spend an allowance of the owning account's CEP-18 tokens.
    --session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 10000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<node IP>:<PORT>\
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_test_contract" \
    --session-entry-point "check_allowance_of" \
    --session-arg "token_contract:account_hash='account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e'" \
    --session-arg "owner:key='account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2'" \
    --session-arg "spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 10000000000
    +
    +

    The following command queries global state to return the value stored under the result URef:

    +
    casper-client query-global-state -n http://<node IP>:<PORT> \
    // This is the previously identified `result` URef from the utility contract's `NamedKeys`
    --key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \
    --state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1
    +
    Casper client command without comments
    + +
    casper-client query-global-state -n http://<node IP>:<PORT> \
    --key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \
    --state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1
    +
    +

    You should get a response similar to the following:

    +
    {
    "id": -9142472925449984061,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block_header": null,
    "merkle_proof": "[3796 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "010f",
    "cl_type": "U256",
    "parsed": "15"
    }
    }
    }
    }
    +

    Transferring Tokens from an Allowance

    +

    The following command allows an account to transfer CEP-18 tokens held by another account up to their approved allowance.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    // This is the secret key for the account that is spending their `allowance` from another account's balance.
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    // This is the CEP-18 token contract.
    --session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \
    --session-entry-point "transfer_from" \
    // This is the account hash of the account that holds the CEP-18 in their balance.
    --session-arg "owner:key='account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2'" \
    // This is the account hash of the account that will receive the transferred CEP-18 tokens.
    --session-arg "recipient:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    // This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.
    --session-arg "amount:u256='10'" \
    --payment-amount "10000000000"
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \
    --session-entry-point "transfer_from" \
    --session-arg "owner:key='account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2'" \
    --session-arg "recipient:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'" \
    --session-arg "amount:u256='10'" \
    --payment-amount "10000000000"
    +
    +

    Increasing and Decreasing an Allowance

    +

    Increasing an Allowance

    +

    The following command increases the designated allowance for the provided account.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "increase_allowance" \
    // This is the account hash of the previously authorized allowance account.
    --session-arg "spender:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    // This is the additional number of CEP-18 tokens that the authorized account may spend.
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "increase_allowance" \
    --session-arg "spender:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    +

    Decreasing an Allowance

    +

    The following command decreases the designated allowance for the provided account.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "decrease_allowance" \
    // This is the account hash of the previously authorized allowance account.
    --session-arg "spender:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    // This is the additional number of CEP-18 tokens that the authorized account may spend.
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "decrease_allowance" \
    --session-arg "spender:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    +

    Minting and Burning Additional CEP-18 Tokens

    +

    Minting Additional Tokens

    +

    If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "mint" \
    // This is the account that will receive the newly minted CEP-18 tokens.
    --session-arg "owner:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    // This is the number of additional CEP-18 tokens to add to the total supply.
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "mint" \
    --session-arg "owner:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    +

    Burning Tokens

    +

    If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question.

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "burn" \
    // This is the account that the tokens will be burned from.
    --session-arg "owner:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    // This is the number of CEP-18 tokens to remove from the total supply.
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "burn" \
    // This is the account that the tokens will be burned from.
    --session-arg "owner:key='account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd'" \
    // This is the number of CEP-18 tokens to remove from the total supply.
    --session-arg "amount:U256='10'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +
    +

    Changing Account Security Permissions

    +

    The change_security entrypoint can be used by an account with admin access to alter the security level of other accounts.

    +

    There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:

    +
      +
    1. +

      None - None overrides other security levels and removes all admin, minting and burning access of an account.

      +
    2. +
    3. +

      Admin - Allows the account full access and control over the CEP-18 contract.

      +
    4. +
    5. +

      MintAndBurn - Allows the account to mint new tokens and burn existing tokens.

      +
    6. +
    7. +

      Burner - The account can burn tokens.

      +
    8. +
    9. +

      Minter - The account can mint new tokens.

      +
    10. +
    +

    Here is an example of a session-arg that provides a list of account hashes to be included on the mint_and_burn_list:

    +
    --session-arg "mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'"
    +

    Be aware that removing all admin accounts will lock out all admin functionality.

    +

    The following command can be supplied with any of the optional arguments above:

    +
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-package-name "cep18_contract_package_CEP18" \
    --session-entry-point "change_security" \
    /// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.
    --session-arg "none_list:string:'<List of account hashes>'" \
    --session-arg "admin_list:string:'<List of account hashes>'" \
    --session-arg "mint_and_burn_list:string:'<List of account hashes>'" \
    --session-arg "burner_list:string:'<List of account hashes>'" \
    --chain-name <CHAIN NAME> \
    --payment-amount 1000000000
    +

    Next Steps

    +
    + + \ No newline at end of file diff --git a/next/resources/tokens/cep78/introduction/index.html b/2.0.0/resources/tokens/cep78/introduction/index.html similarity index 56% rename from next/resources/tokens/cep78/introduction/index.html rename to 2.0.0/resources/tokens/cep78/introduction/index.html index 63b813718..5f0721861 100644 --- a/next/resources/tokens/cep78/introduction/index.html +++ b/2.0.0/resources/tokens/cep78/introduction/index.html @@ -1,64 +1,64 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: Next

    CEP-78 Enhanced NFT Standard Introduction

    + submit an issue on Github
    Version: 2.0.0

    CEP-78 Enhanced NFT Standard Introduction

    Usage

    Building the Contract

    The main.rs file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the make build-contract command from the Makefile provided.

    The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the make build-contract command provided in the Makefile. Please note, however, that you must install wasm-strip to build the contract.

    The call method will install the contract with the necessary entrypoints and call the init() entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation.

    Required Runtime Arguments

    -

    The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the Modalities documentation.

    +

    The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the Modalities documentation.

    • "collection_name": The name of the NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
    • "collection_symbol": The symbol representing a given NFT collection, passed in as a String. This parameter is required and cannot be changed post installation.
    • "total_token_supply": The total number of NFTs that a specific instance of a contract will mint passed in as a U64 value. This parameter is required.
    • -
    • "ownership_mode": The OwnershipMode modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
    • -
    • "nft_kind": The NFTKind modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "ownership_mode": The OwnershipMode modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "nft_kind": The NFTKind modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a u8 value and is required at the time of installation.
    • "json_schema": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a String. This parameter is required if the metadata kind is set to CustomValidated(3) and cannot be changed post installation.
    • "nft_metadata_kind": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.
    • -
    • "identifier_mode": The NFTIdentifierMode modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a u8 value and is required at the time of installation.
    • -
    • "metadata_mutability": The MetadataMutability modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "identifier_mode": The NFTIdentifierMode modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a u8 value and is required at the time of installation.
    • +
    • "metadata_mutability": The MetadataMutability modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a u8 value and is required at the time of installation.

    The following are the optional parameters that can be passed in at the time of installation.

    • -

      "minting_mode": The MintingMode modality that dictates the access to the mint() entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed.

      +

      "minting_mode": The MintingMode modality that dictates the access to the mint() entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed.

    • "allow_minting": The "allow_minting" flag allows the installer of the contract to pause the minting of new NFTs. The allow_minting is a boolean toggle that allows minting when true. If not provided at install the toggle will default to true. This value can be changed by the installer by calling the set_variables() entrypoint.

    • -

      "whitelist_mode": The WhitelistMode modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed.

      +

      "whitelist_mode": The WhitelistMode modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed.

    • -

      "holder_mode": The NFTHolderMode modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either Accounts or Contracts to hold NFTs. This parameter cannot be changed once the contract has been installed.

      +

      "holder_mode": The NFTHolderMode modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either Accounts or Contracts to hold NFTs. This parameter cannot be changed once the contract has been installed.

    • "contract_whitelist": The contract whitelist is a list of contract hashes that specifies which contracts can call the mint() entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the set_variables post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail.

    • -

      "burn_mode": The BurnMode modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.

      +

      "burn_mode": The BurnMode modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.

    • -

      "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.

      +

      "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.

    • -

      "events_mode": The EventsMode modality selects the event schema used to record any changes that occur to tokens issued by the contract instance.

      +

      "events_mode": The EventsMode modality selects the event schema used to record any changes that occur to tokens issued by the contract instance.

    • "additional_required_metdata": An additional metadata schema that must be included. This argument is passed in as a u8 value.

      @@ -68,7 +68,7 @@

      R

    Example deploy

    -

    The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

    +

    The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

    casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='enhanced-nft-1'" \
    --session-arg "collection_symbol:string='ENFT-1'" \
    --session-arg "total_token_supply:u64='10'" \
    --session-arg "ownership_mode:u8='0'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "allow_minting:bool='true'" \
    --session-arg "owner_reverse_lookup_mode:u8='0'" \
    --session-arg "nft_metadata_kind:u8='2'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='1'"

    Utility Session Code

    Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary. @@ -106,11 +106,11 @@

    Utility
    Entrypoint nameSession code
    "mint"client/mint_session
    "balance_of"client/balance_of_session
    "get_approvedclient/get_approved_session
    "owner_of"client/owner_of_session
    "transfer"client/transfer_session

    Checking Token Ownership

    -

    Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

    +

    Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

    Upgrading to Version 1.1.1

    Upgrade to v1.1.1 using a Standard NamedKey Convention or a Custom NamedKey Convention.

    Installing and Interacting with the Contract using the Rust Casper Client

    -

    You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

    +

    You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

    Test Suite and Specification

    The expected behavior of the NFT contract implementation is asserted by its test suite found in the tests folder. The test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors @@ -776,6 +776,6 @@

    Error CodesCodeError1InvalidAccount2MissingInstaller3InvalidInstaller4UnexpectedKeyVariant5MissingTokenOwner6InvalidTokenOwner7FailedToGetArgBytes8FailedToCreateDictionary9MissingStorageUref10InvalidStorageUref11MissingOwnerUref12InvalidOwnersUref13FailedToAccessStorageDictionary14FailedToAccessOwnershipDictionary15DuplicateMinted16FailedToConvertCLValue17MissingCollectionName18InvalidCollectionName19FailedToSerializeMetaData20MissingAccount21MissingMintingStatus22InvalidMintingStatus23MissingCollectionSymbol24InvalidCollectionSymbol25MissingTotalTokenSupply26InvalidTotalTokenSupply27MissingTokenID28InvalidTokenIdentifier29MissingTokenOwners30MissingAccountHash31InvalidAccountHash32TokenSupplyDepleted33MissingOwnedTokensDictionary34TokenAlreadyBelongsToMinterFatal35FatalTokenIdDuplication36InvalidMinter37MissingMintingMode38InvalidMintingMode39MissingInstallerKey40FailedToConvertToAccountHash41InvalidBurner42PreviouslyBurntToken43MissingAllowMinting44InvalidAllowMinting45MissingNumberOfMintedTokens46InvalidNumberOfMintedTokens47MissingTokenMetaData48InvalidTokenMetaData49MissingApprovedAccountHash50InvalidApprovedAccountHash51MissingApprovedTokensDictionary52TokenAlreadyApproved53MissingApproveAll54InvalidApproveAll55MissingOperator56InvalidOperator57Phantom58ContractAlreadyInitialized59MintingIsPaused60FailureToParseAccountHash61VacantValueInDictionary62MissingOwnershipMode63InvalidOwnershipMode64InvalidTokenMinter65MissingOwnedTokens66InvalidAccountKeyInDictionary67MissingJsonSchema68InvalidJsonSchema69InvalidKey70InvalidOwnedTokens71MissingTokenURI72InvalidTokenURI73MissingNftKind74InvalidNftKind75MissingHolderMode76InvalidHolderMode77MissingWhitelistMode78InvalidWhitelistMode79MissingContractWhiteList80InvalidContractWhitelist81UnlistedContractHash82InvalidContract83EmptyContractWhitelist84MissingReceiptName85InvalidReceiptName86InvalidJsonMetadata87InvalidJsonFormat88FailedToParseCep78Metadata89FailedToParse721Metadata90FailedToParseCustomMetadata91InvalidCEP78Metadata92FailedToJsonifyCEP78Metadata93InvalidNFT721Metadata94FailedToJsonifyNFT721Metadata95InvalidCustomMetadata96MissingNFTMetadataKind97InvalidNFTMetadataKind98MissingIdentifierMode99InvalidIdentifierMode100FailedToParseTokenId101MissingMetadataMutability102InvalidMetadataMutability103FailedToJsonifyCustomMetadata104ForbiddenMetadataUpdate105MissingBurnMode106InvalidBurnMode107MissingHashByIndex108InvalidHashByIndex109MissingIndexByHash110InvalidIndexByHash111MissingPageTableURef112InvalidPageTableURef113MissingPageLimit114InvalidPageLimit115InvalidPageNumber116InvalidPageIndex117MissingUnmatchedHashCount118InvalidUnmatchedHashCount119MissingPackageHashForUpgrade120MissingPageUref121InvalidPageUref122CannotUpgradeWithZeroSupply123CannotInstallWithZeroSupply124MissingMigrationFlag125InvalidMigrationFlag126ContractAlreadyMigrated127UnregisteredOwnerInMint128UnregisteredOwnerInTransfer129MissingReportingMode130InvalidReportingMode131MissingPage132UnregisteredOwnerFromMigration133ExceededMaxTotalSupply134MissingCep78PackageHash135InvalidCep78InvalidHash136InvalidPackageHashName137InvalidAccessKeyName138InvalidCheckForUpgrade139InvalidNamedKeyConvention140OwnerReverseLookupModeNotTransferable141InvalidAdditionalRequiredMetadata142InvalidOptionalMetadata143MissingOptionalNFTMetadataKind144InvalidOptionalNFTMetadataKind145MissingAdditionalNFTMetadataKind146InvalidAdditionalNFTMetadataKind147InvalidRequirement148MissingEventsMode149InvalidEventsMode150CannotUpgradeToMoreSupply151MissingOperatorDict152MissingApprovedDict153MissingSpenderAccountHash154InvalidSpenderAccountHash155MissingOwnerTokenIdentifierKey156InvalidTransferFilterContract157MissingTransferFilterContract158TransferFilterContractNeedsTransferableMode159TransferFilterContractDenied160MissingACLWhiteList161InvalidACLWhitelist162EmptyACLWhitelist

    +
    CodeError
    1InvalidAccount
    2MissingInstaller
    3InvalidInstaller
    4UnexpectedKeyVariant
    5MissingTokenOwner
    6InvalidTokenOwner
    7FailedToGetArgBytes
    8FailedToCreateDictionary
    9MissingStorageUref
    10InvalidStorageUref
    11MissingOwnerUref
    12InvalidOwnersUref
    13FailedToAccessStorageDictionary
    14FailedToAccessOwnershipDictionary
    15DuplicateMinted
    16FailedToConvertCLValue
    17MissingCollectionName
    18InvalidCollectionName
    19FailedToSerializeMetaData
    20MissingAccount
    21MissingMintingStatus
    22InvalidMintingStatus
    23MissingCollectionSymbol
    24InvalidCollectionSymbol
    25MissingTotalTokenSupply
    26InvalidTotalTokenSupply
    27MissingTokenID
    28InvalidTokenIdentifier
    29MissingTokenOwners
    30MissingAccountHash
    31InvalidAccountHash
    32TokenSupplyDepleted
    33MissingOwnedTokensDictionary
    34TokenAlreadyBelongsToMinterFatal
    35FatalTokenIdDuplication
    36InvalidMinter
    37MissingMintingMode
    38InvalidMintingMode
    39MissingInstallerKey
    40FailedToConvertToAccountHash
    41InvalidBurner
    42PreviouslyBurntToken
    43MissingAllowMinting
    44InvalidAllowMinting
    45MissingNumberOfMintedTokens
    46InvalidNumberOfMintedTokens
    47MissingTokenMetaData
    48InvalidTokenMetaData
    49MissingApprovedAccountHash
    50InvalidApprovedAccountHash
    51MissingApprovedTokensDictionary
    52TokenAlreadyApproved
    53MissingApproveAll
    54InvalidApproveAll
    55MissingOperator
    56InvalidOperator
    57Phantom
    58ContractAlreadyInitialized
    59MintingIsPaused
    60FailureToParseAccountHash
    61VacantValueInDictionary
    62MissingOwnershipMode
    63InvalidOwnershipMode
    64InvalidTokenMinter
    65MissingOwnedTokens
    66InvalidAccountKeyInDictionary
    67MissingJsonSchema
    68InvalidJsonSchema
    69InvalidKey
    70InvalidOwnedTokens
    71MissingTokenURI
    72InvalidTokenURI
    73MissingNftKind
    74InvalidNftKind
    75MissingHolderMode
    76InvalidHolderMode
    77MissingWhitelistMode
    78InvalidWhitelistMode
    79MissingContractWhiteList
    80InvalidContractWhitelist
    81UnlistedContractHash
    82InvalidContract
    83EmptyContractWhitelist
    84MissingReceiptName
    85InvalidReceiptName
    86InvalidJsonMetadata
    87InvalidJsonFormat
    88FailedToParseCep78Metadata
    89FailedToParse721Metadata
    90FailedToParseCustomMetadata
    91InvalidCEP78Metadata
    92FailedToJsonifyCEP78Metadata
    93InvalidNFT721Metadata
    94FailedToJsonifyNFT721Metadata
    95InvalidCustomMetadata
    96MissingNFTMetadataKind
    97InvalidNFTMetadataKind
    98MissingIdentifierMode
    99InvalidIdentifierMode
    100FailedToParseTokenId
    101MissingMetadataMutability
    102InvalidMetadataMutability
    103FailedToJsonifyCustomMetadata
    104ForbiddenMetadataUpdate
    105MissingBurnMode
    106InvalidBurnMode
    107MissingHashByIndex
    108InvalidHashByIndex
    109MissingIndexByHash
    110InvalidIndexByHash
    111MissingPageTableURef
    112InvalidPageTableURef
    113MissingPageLimit
    114InvalidPageLimit
    115InvalidPageNumber
    116InvalidPageIndex
    117MissingUnmatchedHashCount
    118InvalidUnmatchedHashCount
    119MissingPackageHashForUpgrade
    120MissingPageUref
    121InvalidPageUref
    122CannotUpgradeWithZeroSupply
    123CannotInstallWithZeroSupply
    124MissingMigrationFlag
    125InvalidMigrationFlag
    126ContractAlreadyMigrated
    127UnregisteredOwnerInMint
    128UnregisteredOwnerInTransfer
    129MissingReportingMode
    130InvalidReportingMode
    131MissingPage
    132UnregisteredOwnerFromMigration
    133ExceededMaxTotalSupply
    134MissingCep78PackageHash
    135InvalidCep78InvalidHash
    136InvalidPackageHashName
    137InvalidAccessKeyName
    138InvalidCheckForUpgrade
    139InvalidNamedKeyConvention
    140OwnerReverseLookupModeNotTransferable
    141InvalidAdditionalRequiredMetadata
    142InvalidOptionalMetadata
    143MissingOptionalNFTMetadataKind
    144InvalidOptionalNFTMetadataKind
    145MissingAdditionalNFTMetadataKind
    146InvalidAdditionalNFTMetadataKind
    147InvalidRequirement
    148MissingEventsMode
    149InvalidEventsMode
    150CannotUpgradeToMoreSupply
    151MissingOperatorDict
    152MissingApprovedDict
    153MissingSpenderAccountHash
    154InvalidSpenderAccountHash
    155MissingOwnerTokenIdentifierKey
    156InvalidTransferFilterContract
    157MissingTransferFilterContract
    158TransferFilterContractNeedsTransferableMode
    159TransferFilterContractDenied
    160MissingACLWhiteList
    161InvalidACLWhitelist
    162EmptyACLWhitelist
    \ No newline at end of file diff --git a/next/resources/tokens/cep78/js-tutorial/index.html b/2.0.0/resources/tokens/cep78/js-tutorial/index.html similarity index 77% rename from next/resources/tokens/cep78/js-tutorial/index.html rename to 2.0.0/resources/tokens/cep78/js-tutorial/index.html index 80267e85a..d7c58bf2f 100644 --- a/next/resources/tokens/cep78/js-tutorial/index.html +++ b/2.0.0/resources/tokens/cep78/js-tutorial/index.html @@ -1,21 +1,21 @@ - + -CEP-78 JavaScript Client | Casper Docs - Redux +CEP-78 JavaScript Client | Casper Docs - Redux - - + +
    Version: 2.0.0

    CEP-78 JavaScript Client Tutorial

    This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.

    Further information on the CEP-78 Enhanced NFT Standard can be found here.

    The client is available in npm as casper-cep78-js-client.

    @@ -24,7 +24,7 @@

    Client I

    To install run:

    npm install casper-cep78-js-client

    Installing a CEP-78 Contract using the JavaScript Client

    -

    The install method crafts a Deploy using InstallArgs. +

    The install method crafts a Deploy using InstallArgs. As with every deploy created by the SDK, you can send it using the .send(rpcUrl) method providing the RPC URL that you want to use. It will return deployHash.


    const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);

    const installDeploy = await cc.install(
    {
    collectionName: "my-collection",
    collectionSymbol: "MY-NFTS",
    totalTokenSupply: "1000",
    ownershipMode: NFTOwnershipMode.Transferable,
    nftKind: NFTKind.Physical,
    jsonSchema: {
    properties: {
    color: { name: "color", description: "", required: true },
    size: { name: "size", description: "", required: true },
    material: { name: "material", description: "", required: true },
    condition: { name: "condition", description: "", required: false },
    },
    },
    nftMetadataKind: NFTMetadataKind.CustomValidated,
    identifierMode: NFTIdentifierMode.Ordinal,
    metadataMutability: MetadataMutability.Immutable,
    mintingMode: MintingMode.Installer,
    ownerReverseLookupMode: OwnerReverseLookupMode.Complete
    },
    "250000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);

    InstallArgs are specified as follows:

    @@ -45,7 +45,7 @@

    here. This parameter may be left empty if metadata kind is set to Raw(3). If the metadata kind is set to CustomValidated(4), it will require a specifically formatted custom schema. This parameter cannot be changed post installation.

    +

    jsonSchema - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a String. More information on NFTMetadataKind can be found here. This parameter may be left empty if metadata kind is set to Raw(3). If the metadata kind is set to CustomValidated(4), it will require a specifically formatted custom schema. This parameter cannot be changed post installation.

  • nftMetadataKind - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a u8 value and is required at the time of installation.

    @@ -66,10 +66,10 @@

    here to allow lookup of owned tokens by account. This parameter cannot be changed once the contract has been installed.

    +

    ownerReverseLookupMode - The OwnerReverseLookupMode dictates whether the contract will index ownership of tokens as outlined here to allow lookup of owned tokens by account. This parameter cannot be changed once the contract has been installed.

  • -

    Further information on CEP-78 modality options can be found here.

    +

    Further information on CEP-78 modality options can be found here.

    Minting a Token

    The CEP-78 JS Client includes code to construct a deploy that will Mint a token, as follows:


    const mintDeploy = cc.mint(
    {
    owner: FAUCET_KEYS.publicKey,
    meta: {
    color: "Blue",
    size: "Medium",
    material: "Aluminum",
    condition: "Used",
    },
    },
    { useSessionCode: true },
    "2000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");

    @@ -104,7 +104,7 @@

    R

    You will need to define the following variables in the .env file:

    • -

      NODE_URL - The address of a node. If you are testing using NCTL, this will be http://localhost:11101/rpc.

      +

      NODE_URL - The address of a node. If you are testing using NCTL, this will be http://localhost:11101/rpc.

    • NETWORK_NAME - The name of the Casper network you are operating on, casper-net-1 when testing using a local network with NCTL.

      @@ -138,6 +138,6 @@

      Runn

      Burn - The example will burn the minted NFT.

    -

    The associated code for these deploys may be found in the client-js/examples directory.

    +

    The associated code for these deploys may be found in the client-js/examples directory.

    \ No newline at end of file diff --git a/next/resources/tokens/cep78/modalities/index.html b/2.0.0/resources/tokens/cep78/modalities/index.html similarity index 68% rename from next/resources/tokens/cep78/modalities/index.html rename to 2.0.0/resources/tokens/cep78/modalities/index.html index 322ab0e76..4ca282364 100644 --- a/next/resources/tokens/cep78/modalities/index.html +++ b/2.0.0/resources/tokens/cep78/modalities/index.html @@ -1,21 +1,21 @@ - + -CEP-78 Modalities | Casper Docs - Redux +CEP-78 Modalities | Casper Docs - Redux - - + +
    Version: 2.0.0

    CEP-78 Modalities

    The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.

    Ownership

    This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:

    @@ -310,8 +310,8 @@

    Owner

    This modality provides the following options:

    1. NoLookup: The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling.
    2. -
    3. Complete: The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described here.
    4. -
    5. TransfersOnly: The reporting and receipt functionality is supported like Complete. However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described here.
    6. +
    7. Complete: The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described here.
    8. +
    9. TransfersOnly: The reporting and receipt functionality is supported like Complete. However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described here.

    Additionally, when set to Complete, causes a receipt to be returned by the mint or transfer entrypoints, which the caller can store in their account or contract context for later reference.

    Further, two special entrypoints are enabled in Complete mode. First, register_owner which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, updated_receipts, which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own.

    @@ -411,7 +411,7 @@

    Transfe

    The transfer filter can be enabled by passing a ARG_TRANSFER_FILTER_CONTRACT argument to the install method, with a value of type Option<Key>

    CEP47 Mode

    -

    The CEP47 EventsMode modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a BTreeMap within a dictionary (EVENTS) in the contract's context. Entries consist of the PREFIX_HASH_KEY_NAME, followed by the EVENT_TYPE and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available here.

    +

    The CEP47 EventsMode modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a BTreeMap within a dictionary (EVENTS) in the contract's context. Entries consist of the PREFIX_HASH_KEY_NAME, followed by the EVENT_TYPE and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available here.

    @@ -517,6 +517,6 @@

    Casper
    Event nameIncluded values and type
    Mintrecipient (Key), token_id (String), data (String)
    Transferowner (Key), operator (Option<Key>), recipient (Key), token_id (String)
    Burnowner (Key), token_id (String)
    Approvalowner (Key), spender (Key), token_id (String)
    ApprovalRevokedowner (Key), token_id (String)
    ApprovalForAllowner (Key), operator (Key)
    RevokedForAllowner (Key), operator (Key)
    MetadataUpdatedtoken_id (String), data (String)
    Migration-
    VariablesSet-

    Modality Conflicts

    -

    The MetadataMutability option set to Mutable cannot be used in conjunction with the NFTIdentifierMode modality set to Hash.

    +

    The MetadataMutability option set to Mutable cannot be used in conjunction with the NFTIdentifierMode modality set to Hash.

    \ No newline at end of file diff --git a/2.0.0/resources/tokens/cep78/reverse-lookup/index.html b/2.0.0/resources/tokens/cep78/reverse-lookup/index.html new file mode 100644 index 000000000..b1c51a55e --- /dev/null +++ b/2.0.0/resources/tokens/cep78/reverse-lookup/index.html @@ -0,0 +1,52 @@ + + + + + +Ownership Lookup | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Owner Reverse Lookup Functionality

    +

    In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.

    +

    In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract.

    +

    This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page.

    +

    The CEP-78 Page System

    +

    Ownership of NFTs within a CEP-78 contract is now tracked with a series of pages, with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs.

    +

    A page_table tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the register_owner entrypoint.

    +

    After registering as an owner, the contract creates an entry within the page_table dictionary for the minting account or contract. This dictionary entry consists of a series of boolean values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false.

    +

    Upon minting the token, the user will pay for a page allocation. This adds them to the page dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the page dictionary will consist of 1,000 page_address bits set to False upon allocation, and the minting of any given token in that page will set the page_address bit to True.

    +

    In addition, that account or contract's page_table will be updated by marking the corresponding page number's bit as True.

    +

    As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:

    +
      +
    1. +

      The contract registers their account as an owner.

      +
    2. +
    3. +

      The contract creates a page_table dictionary for that account, with 10 boolean values. As the numbering system begins with 0, the third boolean value corresponding with page 2 is set to True.

      +
    4. +
    5. +

      The account pays for allocation of page 2, creating an entry in the Page 2 dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding page_address boolean for 350 as True.

      +
    6. +
    7. +

      Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for page 5 to be allocated to them. They would then be added to the page 5 dictionary with the page_address boolean for 125 set as True.

      +
    8. +
    +

    This system binds the data writing costs to a maximum size of any given page dictionary.

    +

    Updated Receipts

    +

    If the contract enables OwnerReverseLookupMode, calling the updated_receipts entrypoint will return a list of receipt names alongside the dictionary for the relevant pages.

    +

    Updated receipts come in the format of "{<collection name>}\_m{modulo}\_p{<page number>}". Once again using the 2,350th token as an example, the receipt would read:

    +
    cep78_collection_m_350_p_2
    +

    You can determine the token number by multiplying the page_number by the page_size(1,000) and adding the modulo.

    +

    If the NFTIdentifierMode is set to Ordinal, this number corresponds directly to the token ID.

    +

    If it is set to Hash, you will need to reference the HASH_BY_INDEX dictionary to determine the mapping of token numbers to token hashes.

    + + \ No newline at end of file diff --git a/2.0.0/resources/tokens/index.html b/2.0.0/resources/tokens/index.html new file mode 100644 index 000000000..79546a347 --- /dev/null +++ b/2.0.0/resources/tokens/index.html @@ -0,0 +1,82 @@ + + + + + +Casper Token Standards | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Casper Token Standards

    +

    CEP-18 Casper Fungible Token Standard

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    A Casper Fungible Token TutorialA full tutorial for use of the CEP-18 Casper Fungible Token Standard.
    Installing and Interacting with a CEP-18 ContractA quickstart guide for installing a CEP-18 contract with the Rust Casper Client.
    Exploring the CEP-18 ContractsA guide to interacting with installed CEP-18 contracts.
    CEP-18 Token Transfers and AllowancesA guide for transferring Casper Fungible Tokens.
    Testing Framework for CEP-18A CEP-18 testing framework using the Casper engine test support crate.
    +

    CEP-78 Enhanced NFT Standard

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    CEP-78 Enhanced NFT Standard IntroductionAn introduction to the CEP-78 Enhanced NFT Standard.
    CEP-78 ModalitiesInformation on the features available when installing a CEP-78 contract instance.
    Installing and Interacting with a CEP-78 ContractAn introduction to features present in the CEP-78 Enhanced NFT Standard.
    Owner Reverse Lookup FunctionalityInformation on the Onwer Reverse Lookup feature of CEP-78 contracts.
    A CEP-78 JavaScript Client TutorialA tutorial for using the JavaScript CEP-78 client.
    + + \ No newline at end of file diff --git a/2.0.0/resources/tokens/using-casper-client/index.html b/2.0.0/resources/tokens/using-casper-client/index.html new file mode 100644 index 000000000..be48c4406 --- /dev/null +++ b/2.0.0/resources/tokens/using-casper-client/index.html @@ -0,0 +1,165 @@ + + + + + +On-chain Installation | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Installing and Interacting with a CEP-78 Contract using the Rust Casper Client

    +

    This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.

    +

    Information on the modalities used throughout this installation process can be found in the modalities documentation.

    +

    Installing the Contract

    +

    Installing the enhanced NFT contract to global state requires the use of a Deploy. In this case, the session code can be compiled to Wasm by running the make build-contract command provided in the Makefile at the top level. The Wasm will be found in the contract/target/wasm32-unknown-unknown/release directory as contract.wasm.

    +

    Below is an example of a casper-client command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state.

    +
      +
    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm
    • +
    +
      +
    1. +

      --session-arg "collection_name:string='CEP-78-collection'"

      +

      The name of the NFT collection as a string. In this instance, "CEP-78-collection".

      +
    2. +
    3. +

      --session-arg "collection_symbol:string='CEP78'"

      +

      The symbol representing the NFT collection as a string. In this instance, "CEP78".

      +
    4. +
    5. +

      --session-arg "total_token_supply:u64='100'"

      +

      The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution.

      +
    6. +
    7. +

      --session-arg "ownership_mode:u8='2'"

      +

      The ownership mode for this contract. In this instance the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.

      +
    8. +
    9. +

      --session-arg "nft_kind:u8='1'"

      +

      The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection.

      +
    10. +
    11. +

      --session-arg "nft_metadata_kind:u8='0'"

      +

      The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata.

      +
    12. +
    13. +

      --session-arg "json_schema:string=''"

      +

      An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom validated modality would require passing through a valid JSON schema for your custom metadata.

      +
    14. +
    15. +

      --session-arg "identifier_mode:u8='0'"

      +

      The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash.

      +
    16. +
    17. +

      --session-arg "metadata_mutability:u8='0'"

      +

      A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata.

      +
    18. +
    +

    The session arguments match the available modalities as listed here.

    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='CEP-78-collection'" \
    --session-arg "collection_symbol:string='CEP78'" \
    --session-arg "total_token_supply:u64='100'" \
    --session-arg "ownership_mode:u8='2'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "nft_metadata_kind:u8='0'" \
    --session-arg "json_schema:string=''" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='0'"
    +
    +

    Directly Invoking Entrypoints

    +

    With the release of CEP-78 version 1.1, users that are interacting with a CEP-78 contract that does not use ReverseLookupMode should opt out of using the client Wasms provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost compared against using the provided client Wasm to invoke the entrypoint.

    +

    You may invoke the mint, transfer or burn entrypoints directly through either the contract package hash or the contract hash directly.

    +

    Specifically in the case of mint, there are fewer runtime arguments that must be provided, thereby reducing the total gas cost of minting an NFT.

    +
    Example Mint using StoredVersionByHash
    + +

    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ --payment-amount 7500000000 \ -k ~/secret_key.pem \
    --session-package-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \
    --session-entry-point "mint" \
    --session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \
    --session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"

    +
    +
    Example Transfer using StoredContractByHash
    + +

    Based on the identifier mode for the given contract instance, either the token_id runtime argument must be passed in or in the case of the hash identifier mode, the token_hash runtime argument.

    +

    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ --payment-amount 7500000000 \ -k ~/secret_key.pem \
    --session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \
    --session-entry-point "transfer" \
    --session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \
    --session-arg "target_key:key='account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \
    --session-arg "token_id:u64='0'"

    +
    +

    Minting an NFT

    +

    Below is an example of a casper-client command that uses the mint function of the contract to mint an NFT for the user associated with node-1 in an NCTL environment.

    +
      +
    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm
    • +
    +
      +
    1. +

      --session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'"

      +

      The contract hash of the previously installed CEP-78 NFT contract from which we will be minting.

      +
    2. +
    3. +

      --session-arg "collection_name:string='cep78_<collection_name>'"

      +

      The collection name of the previously installed CEP-78 NFT contract from which we will be minting.

      +
    4. +
    5. +

      --session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"

      +

      The collection name of the NFT to be minted.

      +
    6. +
    7. +

      --session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"

      +

      Metadata describing the NFT to be minted, passed in as a string.

      +
    8. +
    +
    Casper client command without comments
    + +

    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \
    --session-arg "nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'" \
    --session-arg "collection_name:string='cep78_<collection_name>'"` \
    --session-arg "token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \
    --session-arg "token_meta_data:string='{\"name\": \"John Doe\",\"token_uri\": \"https:\/\/www.barfoo.com\",\"checksum\": \"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\"}'"

    +
    +

    Transferring NFTs Between Users

    +

    Below is an example of a casper-client command that uses the transfer function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with node-2 to the user associated with node-3.

    +
      +
    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm
    • +
    +
      +
    1. +

      --session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'"

      +

      The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred.

      +
    2. +
    3. +

      --session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'"

      +

      The account hash of the user that currently owns the NFT and wishes to transfer it.

      +
    4. +
    5. +

      --session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'"

      +

      The account hash of the user that will receive the NFT.

      +
    6. +
    7. +

      --session-arg "is_hash_identifier_mode:bool='false'"

      +

      Argument that the hash identifier mode is ordinal, thereby requiring a token_id rather than a token_hash.

      +
    8. +
    9. +

      --session-arg "token_id:u64='0'"

      +

      The token_id of the NFT to be transferred.

      +
    10. +
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \
    --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \
    --session-arg "nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'" \
    --session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \
    --session-arg "target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \
    --session-arg "is_hash_identifier_mode:bool='false'" \
    --session-arg "token_id:u64='0'"
    +
    +

    Burning an NFT

    +

    Below is an example of a casper-client command that uses the burn function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone.

    +
      +
    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem
    • +
    +
      +
    1. +

      --session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5

      +

      The session hash corresponding to the NFT's contract hash.

      +
    2. +
    3. +

      --session-entry-point "burn"

      +

      The entrypoint corresponding to the burn function.

      +
    4. +
    5. +

      --session-arg "token_id:u64='1'"

      +

      The token ID for the NFT to be burned. If the identifier_mode is not set to Ordinal, you must provide the token_hash instead.

      +
    6. +
    +
    Casper client command without comments
    + +
    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \
    --session-entry-point "burn" \
    --session-arg "token_id:u64='1'"
    +
    + + \ No newline at end of file diff --git a/next/resources/tutorials/advanced/cross-contract/index.html b/2.0.0/resources/tutorials/advanced/cross-contract/index.html similarity index 90% rename from next/resources/tutorials/advanced/cross-contract/index.html rename to 2.0.0/resources/tutorials/advanced/cross-contract/index.html index 841d21b10..151ed2e8a 100644 --- a/next/resources/tutorials/advanced/cross-contract/index.html +++ b/2.0.0/resources/tutorials/advanced/cross-contract/index.html @@ -1,26 +1,26 @@ - + -Cross-Contract Communication | Casper Docs - Redux +Cross-Contract Communication | Casper Docs - Redux - - + +
    Version: Next

    Cross-Contract Communication

    + submit an issue on Github
    Version: 2.0.0

    Cross-Contract Communication

    This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:

    Tutorial Outline

    This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol.

    @@ -56,7 +56,7 @@

    Changing t
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    }

    This will serve as a base for introducing the elements needed for cross-contract communication.

    In a contract, you should first define the call entry point. It should be understood as a constructor for the contract. Everything included in the call entry point will be visible as metadata on a Casper network, in the contract's context. -You should already be familiar with the call entry point from the Writing a Basic Smart Contract in Rust document. If this is not the case, be sure to familiarize yourself with it now.

    +You should already be familiar with the call entry point from the Writing a Basic Smart Contract in Rust document. If this is not the case, be sure to familiarize yourself with it now.

    The contract code, with changes to the call entry point, should look as shown below:

    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    // Get the value of the runtime argument named "message"
    let value: String = runtime::get_named_arg("message");

    // The value will be written under a URef
    let value_ref = storage::new_uref(value);

    // Creating the new set of named keys
    // The keys are a Map of String/casper_types::Key
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();

    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key
    // Create a new vector
    let mut params = Vec::new();
    vec.push(Parameter::new("message", CLType::String));

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Describing the metadata for the entry point
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg", // the name of the entry point
    vec, // the arguments which can be passed into the entry point
    CLType::Unit, // return type of the entry point
    EntryPointAccess::Public, // access permissions - public can be accessed always
    EntryPointType::Contract // in most cases it will be contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access the contract hash from the accounts named keys
    runtime::put_key("hello_world_contract", stored_contract_hash.into());

    }
    tip

    runtime and storage appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the Contract API Modules.

    @@ -65,10 +65,10 @@

    Changing t

    In our case, we will define the entry point update_msg in the contract code just before call.

    Your complete contract should match the following:

    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };

    #[no_mangle]
    pub extern "C" fn update_msg() {

    let value: String = runtime::get_named_arg("message");
    // Get the uref of the message stored in global state
    let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();
    // Write the message to global state
    storage::write(uref, String::from(value));
    }


    #[no_mangle]
    pub extern "C" fn call() {
    // Get the value of a passed parameter with the key "message"
    let value: String = runtime::get_named_arg("message");
    // The value will be wraped in a URef
    let value_ref = storage::new_uref(value);
    // Creating the new set of named keys
    // The keys are a Map of Key/Value
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();
    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key
    // Create a new vector
    let mut vec = Vec::new();
    vec.push(Parameter::new("message", CLType::String));
    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Define the metadata for the entry point `update_msg`
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points metadata
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("hello_world_contract", stored_contract_hash.into());
    }
    -
    info

    There is a distinction between storing data in a contract’s NamedKeys and using a dictionary. Dictionaries can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.

    +
    info

    There is a distinction between storing data in a contract’s NamedKeys and using a dictionary. Dictionaries can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.

    Deploying the Contract

    -

    There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand put_deploy.

    -

    Be sure to go through the prerequisites from the Installing Smart Contracts and Querying Global State documentation.

    +

    There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand put_deploy.

    +

    Be sure to go through the prerequisites from the Installing Smart Contracts and Querying Global State documentation.

    Make sure that after doing this you have:

    1. A valid private key for your account.
    2. @@ -83,7 +83,7 @@

      Deploying
      tip

      When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands.

      Since we are using a default contract structure, the command called from the cross-contract folder should be the following:

      casper-client put-deploy \
      --node-address http://136.243.187.84:7777 \
      --chain-name casper-test \
      --secret-key ./keys/secret_key.pem \
      --payment-amount 20000000000 \
      --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \
      --session-arg "message:string='hello world'"
      -
      tip

      The parameters used in this command need to be adjusted based on your use case. For details, see querying a node and installing contracts. The payment amount may also need to be adjusted based on the latest Testnet chainspec.

      +
      tip

      The parameters used in this command need to be adjusted based on your use case. For details, see querying a node and installing contracts. The payment amount may also need to be adjusted based on the latest Testnet chainspec.

      The output of this command is:

      {
      "id": -9119604526598719721,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.4.13",
      "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"
      }
      }

      To verify that the contract was successfully deployed, use the get-deploy subcommand, providing as a parameter the deploy_hash received from the put-deploy above.

      @@ -159,6 +159,6 @@

      Summary

    +
    \ No newline at end of file diff --git a/2.0.0/resources/tutorials/advanced/index.html b/2.0.0/resources/tutorials/advanced/index.html new file mode 100644 index 000000000..8d40629a5 --- /dev/null +++ b/2.0.0/resources/tutorials/advanced/index.html @@ -0,0 +1,58 @@ + + + + + +Advanced Tutorials | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Advanced Tutorials

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Two-Party Multi-Signature TransactionsA trivial two-party multi-signature scheme for signing and sending transactions
    Multi-Sig ManagementIntegrate key management on Casper accounts and sign transactions with multiple keys
    Interacting with Runtime Return ValuesContract code returning a value to the immediate caller via runtime::ret()
    Safely Transfer Tokens to a ContractTwo methods to handle tokens via a contract
    Reading and Writing to Global State using RustMethods to read and write data to global state on a Casper network using Rust
    Cross Contract CommunicationVariations of cross-contract communication for more complex scenarios
    Working with Authorization KeysRetrieve and use the authorization keys associated with a transaction
    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/advanced/list-cspr/index.html b/2.0.0/resources/tutorials/advanced/list-cspr/index.html new file mode 100644 index 000000000..c9ee1fe7a --- /dev/null +++ b/2.0.0/resources/tutorials/advanced/list-cspr/index.html @@ -0,0 +1,152 @@ + + + + + +Listing CSPR | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Listing CSPR on an Exchange

    +

    This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.

    +
    caution

    The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

    +

    Setting up a Node

    +

    While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see Basic Node Setup.

    +

    This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions.

    +

    Casper Account

    +

    You will need a Casper Account to handle the transactions on an exchange. Casper has an Account model and instructions on how to create an Account.

    +

    For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users.

    +

    Understanding Basic Transactions

    +

    We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice.

    +

    Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others.

    +

    Native transfer

    +

    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
    + +

    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": {
    "deploy": {
    "approvals": [
    {
    "signature": "130 chars",
    "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"
    }
    ],
    "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
    }
    ]
    ]
    }
    }
    }
    }
    }

    +
    +

    Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see Direct Token Transfer. The following command transfers 10 CSPR from account A's main purse to account B's main purse.

    +
    casper-client transfer \
    --id 1 \
    --transfer-id 123456 \
    --node-address http://<node-ip-address>:7777 \
    --amount 10000000000 \
    --secret-key <accountA-secret-key>.pem \
    --chain-name casper \
    --target-account <accountB-hex-encoded-public-key> \
    --payment-amount <payment-in-motes>
    +

    The payment amount varies based on the deploy and network chainspec. For node version 1.5.1, wasmless transfers cost 10^8 motes.

    +

    Bulk or batched Wasm transfer

    +

    Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the Rust contract API, which can be used in session code to achieve batched Wasm transfer:

    +
      +
    • transfer_to_account: Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse.
    • +
    • transfer_to_public_key: Transfers amount of motes from the main purse of the caller’s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse.
    • +
    • transfer_from_purse_to_purse: Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails.
    • +
    • transfer_from_purse_to_public_key: Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it.
    • +
    • transfer_from_purse_to_account: Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account.
    • +
    +

    For more information on how to write session code, see Writing Session Code. There are equivalent assembly script methods available. Alternatively, you can program directly against the ext-FFI methods.

    +

    Integrating CSPR

    +

    You can integrate with the JSON-RPC API of a node on the Casper Mainnet. +You can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see SDK Libraries. +Casper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see Monitoring and Consuming Events.

    +

    Testing the Integration

    +

    Our recommended testing mechanism is to have a test environment that points at the official Casper Testnet. Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the Mainnet, then you can do so with your own test accounts.

    +

    If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public.

    +

    The Casper Protocol

    +
      +
    • Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already.
    • +
    • Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle’d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see Execution Semantics.
    • +
    • Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see Monitoring and Consuming Events.
    • +
    +

    Staking Integration for Exchanges

    +

    Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the JavaScript SDK to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found here.

    +

    Deploy Structures and Parameters

    +

    Staking operations consists of two parts:

    +
      +
    1. +

      Creating a deploy object

      +
    2. +
    3. +

      Signing the deploy

      +
    4. +
    +

    The staking deploy requires the following information:

    +
      +
    • The delegator's public key
    • +
    • The validator's public key
    • +
    • The new validator's public key (For redelegation only)
    • +
    • The amount to be delegated
    • +
    • The gas cost
    • +
    • The auction manager contract's hash
    • +
    • The appropriate entry point
    • +
    +

    Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our casper-node repository, in the following locations:

    + +

    1. Creating a deploy object

    +

    To create a deploy using the JavaScript SDK, we will need deployParams, session and a payment.

    +

    Deploy params is a DeployUtil.DeployParams object created from the delegator's publicKey and the network name as shown in the following:

    +
    import { DeployUtil, CLPublicKey } from 'casper-js-sdk';

    const deployParams = new DeployUtil.DeployParams(
    CLPublicKey.fromHex(publicKeyHex),
    network_name // 'testnet' | 'mainnet'
    );
    +

    For creating a session object, which is DeployUtil.ExecutableDeployItem, we need

    +
      +
    • The delegator and validator's public keys
    • +
    • The amount of tokens to delegate/undelegate/redelgate
    • +
    • The auction manager contract's hash
    • +
    • The entry point
    • +
    +

    First, create a variable RuntimeArgs from the public keys and the amount. We will need to use it below in session:

    +
    import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';

    const args = RuntimeArgs.fromMap({
    delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),
    validator: CLPublicKey.fromHex(validatorPublicKeyHex),
    amount: CLValueBuilder.u512(amountMotes) // in motes
    });
    +

    Second, create a session parameter. It is a Uint8Array consisting of the auction manager contract's hash, the entry points and runtime arguments, which we previously created.

    +

    The auction manager contract's hash will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:

    +
      +
    • +

      Mainnet

      +

      ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea

      +
    • +
    • +

      Testnet

      +

      93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2

      +
    • +
    +

    Your entry point will depend on which action you are performing, with the following three available:

    +
      +
    • delegate - Initial delegation to a validator
    • +
    • undelegate - Undelegating tokens from a validator back to the delegator
    • +
    • redelegate - Redelegating tokens to a new validator
    • +
    +
    import { decodeBase16, DeployUtil } from 'casper-js-sdk';

    const session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(
    decodeBase16(auction_manager_contract_hash), // auction manager contract hash
    contractEntryPoint, // auction manager entry point
    args
    );
    +

    To create the payment parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the chainspec for version 1.4.8. You will need the chainspec for the network version you are using.

    +

    Use the DeployUtil.standardPayment method for creating payment.

    +
    import { DeployUtil } from 'casper-js-sdk';

    const payment = DeployUtil.standardPayment(deployCost);
    +

    The last operation is creating the deploy:

    +
    import { DeployUtil } from 'casper-js-sdk';

    DeployUtil.makeDeploy(deployParams, session, payment);
    +

    Redelegation, occurs the same way as delegation, but with the introduction of a third public_key.

    +
    import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';

    const args = RuntimeArgs.fromMap({
    delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),
    validator: CLPublicKey.fromHex(validatorPublicKeyHex),
    new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),
    amount: CLValueBuilder.u512(amountMotes)
    })
    +

    2a. Sign the deploy (Casper Signer)

    +

    To get the signature, you will need to use Signer.sign from the JavaScript SDK. It will return Promise<{ deploy }>, which is the signed object.

    +

    Use DeployUtil.deployFromJson to convert the result and sent it to network with:

    +
    import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';

    const casperService = new CasperServiceByJsonRPC(GRPC_URL);
    const deployJson = DeployUtil.deployToJson(deploy);
    Signer.sign(
    deployJson,
    accountPublicKey,
    recipientPublicKey
    ).then((signedDeployJson) => {
    const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);
    if (signedDeploy.ok) {
    casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy
    }
    }
    +

    2b. Sign the deploy (Ledger)

    +

    You will need to connect with your Ledger first to get the signature.

    +
    import TransportWebUSB from '@ledgerhq/hw-transport-webusb';
    import LedgerApp, { ResponseBase } from '@zondax/ledger-casper';
    import { DeployUtil } from 'casper-js-sdk';

    const getBipPath = (index: number) => {
    const idx = index.toString();
    return `m/44'/506'/0'/0/${idx}`;
    };

    const deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;
    const transport = await TransportWebUSB.create();
    const ledgerApp = new LedgerApp(transport);
    const res = await ledgerApp.sign(
    getBipPath(selectedAccountIndex),
    deployBytes
    );
    +

    The Signature will be in a property called res.signatureRS.

    +

    After that, we can create a signed deploy,

    +
    import { DeployUtil, CLPublicKey } from 'casper-js-sdk';

    const signedDeploy = DeployUtil.setSignature(
    deploy,
    signatureRS,
    CLPublicKey.fromHex(accountPublicKey)
    );
    +

    We can then send it to a network.

    +
    casperService.deploy(signedDeploy)
    +

    Costs and Minimums

    +

    The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network chainspec.

    +

    Transfer Cost: 100,000,000 motes or 0.1 CSPR

    +

    Delegation Cost: 2,500,000,000 motes or 2.5 CSPR

    +

    Minimum transfer amount: 2,500,000,000 motes, or 2.5 CSPR

    +

    Minimum amount required for delegation: 500,000,000,000 motes, or 500 CSPR.

    +

    The Delegation Cap

    +

    Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at 953. This is a temporary solution to prevent complications with Casper’s fast sync mechanism - in which high bond counts could break fast sync.

    +

    Validators with a delegator count at or above 953 at the time of the 1.4.5 upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below 953.

    +

    Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their CSPR to that validator. However, no new delegators may join the validator until it drops below the 953 limit.

    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/advanced/return-values-tutorial/index.html b/2.0.0/resources/tutorials/advanced/return-values-tutorial/index.html new file mode 100644 index 000000000..27a68a1f6 --- /dev/null +++ b/2.0.0/resources/tutorials/advanced/return-values-tutorial/index.html @@ -0,0 +1,35 @@ + + + + + +Runtime Return Values | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Interacting with Runtime Return Values

    +

    Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.

    +

    Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers.

    +

    Contract code can optionally return a value to their immediate caller via runtime::ret(), whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance.

    +

    Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything.

    +

    Contract Code

    +

    For example, if we create a contract to accept and keep a record of donations, we would use runtime::ret() to define the results that should be passed to the caller as per the following:

    +

    #[no_mangle]
    pub extern "C" fn donate() {
    let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);
    if let Key::Account(donating_account_hash) = donating_account_key {
    update_ledger_record(donating_account_hash.to_string())
    } else {
    runtime::revert(FundRaisingError::InvalidKeyVariant)
    }
    let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)
    .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)
    .as_uref()
    .unwrap_or_revert();
    let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();
    runtime::ret(value)
    }

    +

    In this example, the return value is the URef corresponding to the purse used to raise funds, with add permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the donate entry point.

    +

    Without the addition of the runtime::ret, the purse would not be returned to the caller.

    +

    Session Code

    +

    The following is an example of session code calling the specified entry point. Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code.

    +

    #[no_mangle]
    pub extern "C" fn call() {
    let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);
    let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);
    let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);

    let donating_purse_uref: URef = runtime::call_contract(
    fundraiser_contract_hash,
    ENTRY_POINT_DONATE,
    runtime_args! {
    DONATING_ACCOUNT_KEY => donating_account_key
    },
    );
    system::transfer_from_purse_to_purse(
    account::get_main_purse(),
    donating_purse_uref,
    donation_amount,
    None
    )
    .unwrap_or_revert()
    }

    +

    This session code calls into a contract's entry point by using runtime::call_contract, supplying the contract_hash to identify the contract to be called, and the name of the entry point to be invoked, in this case donate. It supplies the donating_account_key, which in this case is the account key of the caller. The contract will then provide a return value, in this case donating_purse_uref. To call an entry point, you will need to know the CLType of the return value and identify it within the code.

    +

    You can determine the type of the return value by querying the contract object in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash.

    +

    This example code takes that returned value and transfers a donation_amount from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer.

    + + \ No newline at end of file diff --git a/next/resources/tutorials/advanced/storage-workflow/index.html b/2.0.0/resources/tutorials/advanced/storage-workflow/index.html similarity index 64% rename from next/resources/tutorials/advanced/storage-workflow/index.html rename to 2.0.0/resources/tutorials/advanced/storage-workflow/index.html index 3b01ec9c7..83e702b7e 100644 --- a/next/resources/tutorials/advanced/storage-workflow/index.html +++ b/2.0.0/resources/tutorials/advanced/storage-workflow/index.html @@ -1,31 +1,31 @@ - + -Storage Workflow | Casper Docs - Redux +Storage Workflow | Casper Docs - Redux - - + +
    Version: Next

    Reading and Writing to Global State using Rust

    + submit an issue on Github
    Version: 2.0.0

    Reading and Writing to Global State using Rust

    The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.

    Essentially, there are three means of storage within the Casper ecosystem. These consist of runtime::put_key, storage::write(alongside storage::new_uref as explained below) and storage::dictionary_put. These stored values can be read using runtime::get_key, storage::read and storage::dictionary_get, respectively. Each method stores data in a specific way, and it's important to understand the differences.

    Description of Functions

    runtime::put_key / runtime::get_key

    -

    Both the put_key and get_key functions refer to Casper Key types as outlined in both the Understanding Hash Types and Serialization Standard. These keys are stored within a URef as a Key type.

    +

    Both the put_key and get_key functions refer to Casper Key types as outlined in both the Understanding Hash Types and Serialization Standard. These keys are stored within a URef as a Key type.

    storage::write / storage::read

    storage::write writes a given value to a previously established URef (created using storage::new_uref). Unlike put_key, this value is not one of the Key types listed above, but rather any of the potential CLTypes as outlined. storage::read provides a method to retrieve these values from the associated URef.

    storage:dictionary_put / storage::dictionary_get

    For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than NamedKeys. Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes.

    -

    More information on dictionaries can be found on the Reading and Writing to Dictionaries page.

    +

    More information on dictionaries can be found on the Reading and Writing to Dictionaries page.

    Example Code

    Example of put_key and storage::write

    This sample code creates a new contract and stores the contract hash in global state using the runtime::put_key function.

    @@ -35,13 +35,13 @@


    let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)
    .unwrap_or_revert()
    .into_uref()
    .map(|uref| URef::new(uref.addr(), AccessRights::default()))
    .unwrap_or_revert()
    .into_read();

    let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();

    // Compare my stored value with runtime arg
    let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);
    if my_actual_stored_value != my_expected_stored_value {
    // We revert if my stored value is not what is expected from caller argument
    runtime::revert(UserError::StoredValueError);
    }

    runtime::print(&my_actual_stored_value.to_string());
    }

    Example of dictionary_put and dictionary_get

    -

    Examples of dictionary usage for storage can be found in the Writing Entries into a Dictionary section of Reading and Writing to Dictionaries.

    +

    Examples of dictionary usage for storage can be found in the Writing Entries into a Dictionary section of Reading and Writing to Dictionaries.

    Additional Functions for Named Keys

    The following functions might also be of interest for working with named keys:

    • list_named_keys - Returns the named keys of the current context
    • has_key - Returns true if the key exists in the current context’s named keys
    • remove_key - Removes the requested NamedKey from the current context
    • -
    +
    \ No newline at end of file diff --git a/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/index.html b/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/index.html new file mode 100644 index 000000000..0bcf0b153 --- /dev/null +++ b/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/index.html @@ -0,0 +1,39 @@ + + + + + +Token Transfers | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Safely Transfer Tokens to a Contract

    +

    This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.

    +

    For increased security, token transfers from a main purse must be handled via session code (WASM), as shown here. Therefore, transfer-* methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context.

    +

    Scenario 1 - Creating a Throw-Away Purse

    +

    The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee.

    +

    In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues.

    +

    This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation.

    +

    Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet.

    +
    #[no_mangle]
    pub extern "C" fn call() {
    let amount: U512 = runtime::get_named_arg("amount");
    // This is demonstrating the most direct case, wherein you pass in the contract_hash and
    // the entry_point_name of the target contract as args.
    // With prior setup having been done, this can also be simplified.
    let contract_hash = runtime::get_named_arg("contract_hash");
    let entry_point_name = runtime::get_named_arg("entry_point_name");

    // This creates a new empty purse that the caller will use just this one time.
    let new_purse = system::create_purse();

    // Transfer from the caller's main purse to the new purse that was just created.
    // Note that transfer is done safely by the host logic.
    system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)
    .unwrap_or_revert();

    // Pass the newly created purse to the smart contract with full access rights;
    // the called contract should receive the new purse, extract the token from it, and then do
    // whatever else it is meant to do if a valid amount was transferred to it. Note that the
    // caller's main purse is never exposed to the called contract; the newly created purse
    // is provided instead.
    runtime::call_contract(contract_hash, entry_point_name, runtime_args! {
    // The arg names are defined by the contract that you are calling,
    // there is no canonical name. The contract you are calling may have other
    // runtime args that it requires.
    "????" => new_purse
    });
    }

    +

    Scenario 1 - Advanced Variation

    +

    Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly.

    +

    This example provides a framework for the idea, but will require modification to suit developer needs.

    +

    Scenario 2 - Maintaining a Reusable Purse within Contract Logic

    +

    The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping.

    +

    In Scenario 1, the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from Scenario 1's Advanced Variation in that the purse in question is under the control of the contract rather than the caller.

    +

    Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly.

    +
    // Scenario 2: with this style, the contract being called has some internal accounting
    // to keep track of a reusable purse associated to the calling account; this avoids
    // wasteful creation of one time purses but requires the smart contract being called
    // to have more sophisticated internal logic.
    #[no_mangle]
    pub extern "C" fn call() {
    let amount: U512 = runtime::get_named_arg("amount");

    // This is demonstrating the most direct case, wherein you pass in the contract_hash and
    // the entry_point_names of the target contract as args.
    // With prior setup having been done, this can also be simplified.
    let contract_hash = runtime::get_named_arg("contract_hash");
    // the name of the entry point on the contract that returns a purse uref to receive token at
    // the actual name of the entry point is up to the smart contract authors
    let deposit_point_name = runtime::get_named_arg("deposit_point_name");
    // whatever entry point on the smart contract does the actual work if token has been transferred
    // the actual name of which is up to the smart contract authors.
    let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");

    // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)
    // for the caller to transfer to.
    let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});

    // transfer from the caller's purse to the purse provided by the contract; the transfer is handled
    // safely by the host and the caller's purse is never exposed to the called smart contract.
    system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)
    .unwrap_or_revert();

    // The contract being interacted with looks up the associated purse, checks its balance, etc.
    // within its logic. That side of it is entirely up to the smart contract authors to code; the caller
    // merely calls the logic. Also, the entry point might require one or more runtime arguments.
    // In all cases some discovery of the API of the contract you are calling is necessary.
    runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});
    }

    +

    Scenario 2 - Advanced Variation

    +

    In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract.

    +

    This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup.

    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/advanced/two-party-multi-sig/index.html b/2.0.0/resources/tutorials/advanced/two-party-multi-sig/index.html new file mode 100644 index 000000000..dfc164e1c --- /dev/null +++ b/2.0.0/resources/tutorials/advanced/two-party-multi-sig/index.html @@ -0,0 +1,78 @@ + + + + + +Two-Party Multi-Sig | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Two-Party Multi-Signature Deploys

    +

    Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.

    +

    This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:

    +
      +
    1. You meet the prerequisites, including having the Casper command-line client and a valid node address
    2. +
    3. You have the main account's PublicKey hex (MA) and another PublicKey hex to associate (AA)
    4. +
    5. You have previously sent deploys to a Casper network
    6. +
    +

    Configuring the Main Account

    +
    caution

    Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet.

    +

    Each Account has an associated_keys field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the associated_keys field.

    +

    An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the action_thresholds for the account.

    +

    Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:

    +
      +
    1. Send a deploy to the network; determined by the deployment threshold
    2. +
    3. Edit the associated keys and the action_thresholds; determined by the key_management threshold
    4. +
    +

    To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the main key and associated key's combined weight must be greater than or equal to the deployment threshold. This can be achieved by having each key's weight equal to half of the deployment threshold.

    +

    Running session code to set up associated keys

    +

    To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on GitHub. Note that this session code is not a general-purpose program and needs to be modified for each use case.

    +
    git clone https://github.com/casper-ecosystem/two-party-multi-sig
    +

    The session code executes 3 crucial steps to enforce the multi-sig scheme for the main account:

    +
      +
    1. Adds an associated key to the account; we will refer to this key as AA
    2. +
    3. Raises the action threshold to 2, because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to 1
    4. +
    5. Raises the deployment threshold to 2, such that the weight required to send a deploy is split equally between the keys associated with the account
    6. +
    +

    The repository contains a Makefile with the build commands necessary to compile the contract and generate the necessary Wasm.

    +
    cd two-party-multi-sig
    make build-contract
    +

    The compiled Wasm will be saved on this path: contract/target/wasm32-unknown-unknown/release/contract.wasm.

    +

    The Casper command-line client can be used to send the compiled Wasm to the network for execution.

    +
    casper-client put-deploy \
    --node-address http://<peer-ip-address>:7777 \
    --secret-key <secret-key-MA>.pem \
    --chain-name casper-test \
    --payment-amount 2500000000 \
    --session-path <path-to-contract-wasm> \
    --session-arg "deployment-account:account_hash='account-hash-<hash-AA>'"
    +
      +
    1. node-address - An IP address of a node on the network
    2. +
    3. secret-key - The file name containing the secret key of the main account
    4. +
    5. chain-name - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)
    6. +
    7. payment-amount - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network chainspec.
    8. +
    9. session-path - The path to the contract Wasm
    10. +
    11. session-arg - The contract takes the account hash of the associated account as an argument labeled deployment-account. You can pass this argument using the --session-arg flag in the command line client
    12. +
    +

    Important response fields:

    +
      +
    • "result"."deploy_hash" - the address of the executed deploy, needed to look up additional information about the transfer
    • +
    +

    Note: Save the returned deploy_hash from the output to query information about execution status.

    +

    Confirming Processing and Account Status

    +

    Account configuration on a Casper blockchain is stored in a Merkle Tree and is a snapshot of the blockchain's Global State. The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the state-root-hash and is stored in every executed block.

    +

    To check that the account was configured correctly, you need the state-root-hash corresponding to the block that contains your deploy. To obtain the state-root-hash, you need to:

    +
      +
    1. Confirm the execution status of the deploy and obtain the hash of the block containing it
    2. +
    3. Query the block containing the deploy to obtain the corresponding state_root_hash
    4. +
    +

    Using the state_root_hash and the hex-encoded-public-key of the main account, query the network and check the account's configuration.

    +
    casper-client query-global-state \
    --node-address http://<peer-ip-address>:7777 \
    --state-root-hash <state-root-hash-from-block> \
    --key <hex-encoded-public-key-MA>
    +
    Example output
    + +
    {
    "id": 1126043166167626077,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "merkle_proof": "2226 chars",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 2
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",
    "weight": 1
    },
    {
    "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
    "weight": 1
    }
    ],
    "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",
    "named_keys": []
    }
    }
    }
    }
    +
    +

    In the example output, you can see the account hashes listed within the associated_keys section. Each key has weight 1; since the action threshold for deployment is 2, neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold.

    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/beginner/aws-node/index.html b/2.0.0/resources/tutorials/beginner/aws-node/index.html new file mode 100644 index 000000000..673236a7a --- /dev/null +++ b/2.0.0/resources/tutorials/beginner/aws-node/index.html @@ -0,0 +1,72 @@ + + + + + +AWS Casper Nodes | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Launching a Casper Node with AWS Marketplace

    +

    The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.

    +

    Step 1 - Subscribing

    +

    You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription.

    +

    Step 01

    +

    If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe.

    +

    You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different Amazon EC2 (Amazon Elastic Compute Cloud) instance type if you prefer.

    +

    After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the Continue to Configuration button grayed out, as shown below:

    +

    Step 04

    +

    Once the system processes your request, the button will light orange, and you may continue to the configuration options.

    +

    Step 05

    +

    Step 2 - Initial Configuration

    +

    The Configuration page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release.

    +

    The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose.

    +

    Step 06

    +

    Step 3 - Launch Configuration

    +

    The Launch page will show your previously selected configuration details and a Usage instructions button that leads to the most recent instructions based on your chosen software version.

    +

    Below this, you will see a drop-down menu with the title "Choose Action":

    +

    Step 08

    +

    This drop-down menu includes the following options:

    +
      +
    • +

      Launch through EC2 - This option launches your configuration through the Amazon EC2 Console

      +
    • +
    • +

      Launch from Website - This option will launch directly from the current page, using further configuration options outlined below.

      +
    • +
    • +

      Copy to Service Catalog - Copy your configuration of the software to the Service Catalog console, where you can manage your company's cloud resources.

      +
    • +
    +

    Additional drop-down menus include:

    +
      +
    • +

      EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software.

      +
    • +
    • +

      VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box.

      +
    • +
    • +

      Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet.

      +
    • +
    • +

      Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.

      +
    • +
    +

    EC2 Key Pair Settings

    +

    Step 11

    +

    You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.

    +

    Step 12

    +

    Launching Your Node

    +

    If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange Launch button to launch your AWS-hosted Casper node.

    +

    Step 13

    + + \ No newline at end of file diff --git a/next/resources/tutorials/beginner/cep18/index.html b/2.0.0/resources/tutorials/beginner/cep18/index.html similarity index 72% rename from next/resources/tutorials/beginner/cep18/index.html rename to 2.0.0/resources/tutorials/beginner/cep18/index.html index 823cd9e57..059f2c571 100644 --- a/next/resources/tutorials/beginner/cep18/index.html +++ b/2.0.0/resources/tutorials/beginner/cep18/index.html @@ -1,26 +1,26 @@ - + -Fungible Tokens | Casper Docs - Redux +Fungible Tokens | Casper Docs - Redux - - + +
    Version: Next

    Fungible Tokens (CEP-18) Implementation and Usage

    + submit an issue on Github
    Version: 2.0.0

    Fungible Tokens (CEP-18) Implementation and Usage

    This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:

    Outline of the Tutorial

    This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol.

    @@ -86,7 +86,7 @@

    The Casper CE

    Creating a CEP-18 Token on the Testnet

    Clone and Compile the CEP-18 Contract

    Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state.

    -

    If you are unsure how to interact with Casper Contracts please refer to the following tutorial: Writing a Basic Smart Contract in Rust.

    +

    If you are unsure how to interact with Casper Contracts please refer to the following tutorial: Writing a Basic Smart Contract in Rust.

    We will clone the token repository and prepare the token contract for sending in a Deploy.

    1. Clone the Fungible Token contract from the repository.
    2. @@ -143,6 +143,6 @@

      Summary

    +
    \ No newline at end of file diff --git a/2.0.0/resources/tutorials/beginner/getting-started-tutorial/index.html b/2.0.0/resources/tutorials/beginner/getting-started-tutorial/index.html new file mode 100644 index 000000000..27be4169a --- /dev/null +++ b/2.0.0/resources/tutorials/beginner/getting-started-tutorial/index.html @@ -0,0 +1,24 @@ + + + + + +Getting Started | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Getting Started Video

    +

    This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.

    +

    + +

    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/beginner/index.html b/2.0.0/resources/tutorials/beginner/index.html new file mode 100644 index 000000000..f81b5a611 --- /dev/null +++ b/2.0.0/resources/tutorials/beginner/index.html @@ -0,0 +1,78 @@ + + + + + +Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Overview

    +

    Beginner Tutorials

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on an NCTL NetworkAn example contract that maintains a counter variable on a local Casper Network with NCTL
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Querying a Casper NetworkQueries for users and developers to obtain information stored on the blockchain
    Smart Contract UpgradesLearn how to upgrade smart contracts
    The Casper Fungible Token Standard (CEP-18)Fungible Token Standard (CEP-18) Implementation and Usage
    Launching a Casper Node with AWS MarketplaceLearn how to launch a Casper Node through the AWS Marketplace
    +

    GitHub Tutorials

    + + + + + + + + + + + + + + + + + +
    TitleDescription
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    + + \ No newline at end of file diff --git a/2.0.0/resources/tutorials/beginner/querying-network/index.html b/2.0.0/resources/tutorials/beginner/querying-network/index.html new file mode 100644 index 000000000..e240f8ae8 --- /dev/null +++ b/2.0.0/resources/tutorials/beginner/querying-network/index.html @@ -0,0 +1,120 @@ + + + + + +Querying a Node | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Querying a Casper Node

    +

    The Casper node supports queries for users and developers to obtain information stored on the blockchain.

    +

    This document assumes:

    +
      +
    1. You have met the prerequisites
    2. +
    3. You are familiar with the structure of the Global State and the Blockchain Design to query data from the network
    4. +
    +

    When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:

    +
      +
    • Account details
    • +
    • Block information
    • +
    • Deploy information
    • +
    +

    Obtaining the Global State Root Hash

    +

    Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node.

    +

    All queries made to global state require the state-root-hash, which you can obtain with this command:

    +
    casper-client get-state-root-hash \
    --id 1 \
    --node-address http://<node-ip-address>:7777
    +

    Request fields:

    +
      +
    • id - (STRING OR INTEGER) 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
    • +
    +
    Explore the JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "chain_get_state_root_hash",
    "params": null,
    "id": 1
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"
    },
    "id": 1
    }
    +
    +

    Querying an Account

    +

    Accounts are stored in the global state and can be queried using the query-global-state command:

    +
    casper-client query-global-state \
    --id 4 \
    --node-address http://<node-ip-address>:7777 \
    --state-root-hash <state-root-hash> \
    --key <hex-encoded-source-account-public-key>
    +

    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 - Hex-encoded hash of the state root
    • +
    • 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. This purse is the source of the tokens transferred in this example
    • +
    +

    Example Account Query with Verbose Output:

    +
    casper-client query-global-state -v \
    --id 4 \
    --node-address https://rpc.testnet.casperlabs.io/ \
    --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \
    --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986
    +
    Explore the sample JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_global_state",
    "params": {
    "state_identifier": {
    "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"
    },
    "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",
    "path": []
    },
    "id": 4
    }
    +

    JSON-RPC Response:

    +
    {
    "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]"
    }
    }
    +
    +

    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:

    +
    casper-client query-balance --help
    +
    casper-client query-balance \
    --id 6 \
    --node-address http://<node-ip-address>:7777 \
    --state-root-hash <state-root-hash> \
    --purse-identifier <account>
    +

    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 - 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.

    +

    Example Balance Query with Verbose Output:

    +
    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.
    + +

    JSON-RPC Request:

    +
    {
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": {
    "state_identifier": {
    "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"
    },
    "purse_identifier": {
    "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"
    }
    },
    "id": 6
    }
    +

    JSON-RPC Response:

    +
    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.2",
    "balance": "164000000000"
    },
    "id": 6
    }
    +
    +

    Querying Blocks

    +

    It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:

    +
    casper-client get-block \
    --id 3 \
    --node-address http://<node-ip-address>:7777 \
    --block-identifier <block-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
    • +
    • block-identifier - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used
    • +
    +

    Important response fields:

    +
      +
    • "result"."block"."header"."state_root_hash" - contains the state-root-hash for this block
    • +
    +
    Explore the JSON-RPC request and response generated.
    + +

    JSON-RPC Request:

    +
    {
    "id": 3,
    "jsonrpc": "2.0",
    "method": "chain_get_block",
    "params": {
    "block_identifier": {
    "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"
    }
    }
    }
    +

    JSON-RPC Response:

    +
    {
    "id": 3,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.0.0",
    "block": {
    "body": {
    "deploy_hashes": [],
    "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",
    "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]
    },
    "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",
    "header": {
    "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",
    "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",
    "era_end": null,
    "era_id": 0,
    "height": 8,
    "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",
    "protocol_version": "1.0.0",
    "random_bit": true,
    "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",
    "timestamp": "2021-04-20T18:04:42.368Z"
    },
    "proofs": [
    {
    "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",
    "signature": "130 chars"
    },
    {
    "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",
    "signature": "130 chars"
    },
    {
    "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",
    "signature": "130 chars"
    },
    {
    "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",
    "signature": "130 chars"
    },
    {
    "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",
    "signature": "130 chars"
    }
    ]
    }
    }
    }
    +
    +

    Querying Deploys

    +

    Once you submit a deploy to the network, you can check its execution status using get-deploy. If the execution_results in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution.

    +
    casper-client get-deploy \
    --id 2 \
    --node-address http://<node-ip-address>:7777 \
    <deploy-hash>
    +

    Request fields:

    +
      +
    • id - 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
    • +
    • deploy-hash - Hex-encoded hash of the deploy
    • +
    + + \ No newline at end of file diff --git a/next/resources/tutorials/beginner/upgrade-contract/index.html b/2.0.0/resources/tutorials/beginner/upgrade-contract/index.html similarity index 84% rename from next/resources/tutorials/beginner/upgrade-contract/index.html rename to 2.0.0/resources/tutorials/beginner/upgrade-contract/index.html index b325f35df..faa8ef8f6 100644 --- a/next/resources/tutorials/beginner/upgrade-contract/index.html +++ b/2.0.0/resources/tutorials/beginner/upgrade-contract/index.html @@ -1,21 +1,21 @@ - + -Contract Upgrades | Casper Docs - Redux +Contract Upgrades | Casper Docs - Redux - - + +
    Version: 2.0.0

    Upgrading a Contract

    This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the add_contract_version API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.

    Video Tutorial

    Here is a video walkthrough of this tutorial.

    @@ -23,7 +23,7 @@

    Video Tutoria

    Prerequisites

    note

    Installing the first version of the contract (contract-v1.wasm) as shown in the counter tutorial is a prerequisite before installing the second version of the contract (contract-v2.wasm).

    @@ -58,7 +58,7 @@

        let (contract_hash, contract_version) = 
    storage::add_contract_version(contract_package_hash,
    entry_points,
    named_keys);

    Explanation of arguments:

      -
    • contract_package_hash - This hash directs you to the contract package. See Hash and Key Explanations.
    • +
    • contract_package_hash - This hash directs you to the contract package. See Hash and Key Explanations.
    • entry_points - Entry points of the contract, which can be modified or newly added.
    • named_keys - Named key pairs of the contract.
    @@ -73,7 +73,7 @@

    make prepare

    make build-contract

    Step 4. Install the contract

    -

    Install the contract on the network via a deploy and verify the deploy status. You can also monitor the event stream to see when your deploy is accepted.

    +

    Install the contract on the network via a deploy and verify the deploy status. You can also monitor the event stream to see when your deploy is accepted.

    To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the counter_decrement entry point.

    note

    Installing the first version of the contract, as shown in the Counter tutorial, is a prerequisite before installing the second version.

    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm
    @@ -108,8 +108,8 @@

    S

    Call the new entry point, counter_decrement, using the package name and check the results.

    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-package-name "counter_package_name" \
    --session-entry-point "counter_decrement"

    After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash.

    Disabling and Enabling Contract Versions

    @@ -121,6 +121,6 @@

    Crea

    You can create a locked contract package with the new_locked_contract function. This contract can never be upgraded.

    let (stored_contract_hash, _) = storage::new_locked_contract(
    contract_entry_points,
    Some(contract_named_keys),
    Some("contract_package_name".to_string()),
    Some("contract_access_uref".to_string()),
    );

    Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1.

    -
    note

    Creating a locked contract package is an irreversible decision. To upgrade a contract, use new_contract as Step 1 explains.

    +
    note

    Creating a locked contract package is an irreversible decision. To upgrade a contract, use new_contract as Step 1 explains.

    \ No newline at end of file diff --git a/2.0.0/runtime/index.html b/2.0.0/runtime/index.html new file mode 100644 index 000000000..05dd6aa84 --- /dev/null +++ b/2.0.0/runtime/index.html @@ -0,0 +1,63 @@ + + + + + +Runtime | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Runtime Economics

    +

    The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:

    +
      +
    • A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See Fee Elimination for more details.
    • +
    • A form of dynamic pricing that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era.
    • +
    • Blocks are structured into lanes that can only hold a particular number of transactions of specified types.
    • +
    +

    These economic features are configurable using chainspec parameters.

    +

    Gas Allocation

    +

    Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas.

    +

    We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant CEPs. In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model.

    +

    Consensus before execution & basics of payment

    +

    The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas.

    +

    Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future.

    +

    Costs and limits

    +

    Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex host-side functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the chainspec and may vary according to arguments. Read more about how Casper measures computational work here.

    +

    We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades.

    +

    Lanes and gas costs

    +

    There are several platform parameters that delineate the sets of transactions that may be included in a valid block:

    +
      +
    • Number of lanes and lane types +
        +
      • System interaction lanes for Mint (transfers) and Auction transactions.
      • +
      • WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction.
      • +
      • All lanes can contain some finite number of transactions, set separately for each lane.
      • +
      • For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time.
      • +
      +
    • +
    • Block gas and size limits +
        +
      • The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots.
      • +
      • The block size limit imposes an absolute ceiling on the total byte size of included transactions.
      • +
      • Individual transaction size limits are also enforced.
      • +
      +
    • +
    +

    These are the lane configuration settings for the Condor release on Mainnet:

    +
    [transactions.v1]
    # The configuration settings for the lanes of transactions including both native and Wasm based interactions.
    # Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1
    # respectively
    # The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction
    # within a given lane.
    # The maximum length in bytes of runtime args per V1 transaction.
    # [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)
    # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and
    # the lane must be present and defined.
    # Different casper networks may not impose such a restriction.
    # [1] -> Max transaction size in bytes for a given transaction in a certain lane
    # [2] -> Max args length size in bytes for a given transaction in a certain lane
    # [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane
    # [4] -> The maximum number of transactions the lane can contain
    native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]
    native_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]
    wasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]
    +

    These are the block gas and size limits for the Condor release on Mainnet:

    +
    [transactions]
    ...
    # Maximum block size in bytes including transactions contained by the block. 0 means unlimited.
    max_block_size = 5_242_880
    # The upper limit of total gas of all transactions in a block.
    block_gas_limit = 3_300_000_000_000
    +

    Dynamic Gas Pricing

    +

    A dynamic gas pricing system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack.

    +

    Eliminating Gas Fees

    +

    See Gas and Fee Elimination for more details.

    + + \ No newline at end of file diff --git a/2.0.0/sdk/index.html b/2.0.0/sdk/index.html new file mode 100644 index 000000000..15b196665 --- /dev/null +++ b/2.0.0/sdk/index.html @@ -0,0 +1,74 @@ + + + + + +SDK Client Libraries | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    SDK Client Libraries

    +

    This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.

    +

    Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories.

    +

    Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories.

    +

    Serialization Standard

    +

    The Casper platform uses a custom serialization format. To this end, we've established a Serialization Standard, which must be followed when building a Casper SDK.

    +

    JSON-RPC API

    +

    Developers can interact directly with the Casper JSON-RPC API instead of using an SDK.

    +

    Table of Contents

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    SDK DocumentationGitHub LocationOrganization
    JavaScript/TypeScriptcasper-js-sdkCasper Ecosystem
    Java SDKcasper-java-sdkCasper Association
    C# SDKcasper-net-sdkMAKE
    Go SDKcasper-go-sdkMAKE
    Python SDKcasper-python-sdkCasper Association
    PHP SDKcasper-php-sdkMAKE
    Scala SDKcasper-scala-sdkM. Abahmane
    + + \ No newline at end of file diff --git a/2.0.0/transactions-and-transaction-lifecycle/index.html b/2.0.0/transactions-and-transaction-lifecycle/index.html new file mode 100644 index 000000000..477c9e8d9 --- /dev/null +++ b/2.0.0/transactions-and-transaction-lifecycle/index.html @@ -0,0 +1,72 @@ + + + + + +Transaction Lifecycle | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Transactions and the Transaction Lifecycle

    +

    Transactions

    +

    A transaction is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions’s structure is as follows:

    +

    Transaction Data Structure

    +
      +
    • Body: Containing payment code and session code (more details on these below)
    • +
    • Header: containing +
        +
      • The Public Key of the account in whose context the transaction will run
      • +
      • The timestamp of the transaction’s creation
      • +
      • A time-to-live, after which the transaction expires and cannot be included in a block
      • +
      • the blake2b256 hash of the body
      • +
      +
    • +
    • Transaction hash: the blake2b hash of the Header
    • +
    • Approvals: the set of signatures which have signed the transaction hash; these are used in the account permissions model
    • +
    +

    The Transaction Lifecycle

    +

    A transaction goes through the following phases on Casper:

    +
      +
    1. Transaction Received
    2. +
    3. Transaction Gossiped
    4. +
    5. Block Proposed
    6. +
    7. Block Gossiped
    8. +
    9. Consensus Reached
    10. +
    11. Transaction Executed
    12. +
    +

    Transaction Received

    +

    A client sending the transaction will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given transaction matches configuration settings outlined in the network's chainspec. Transaction configuration for the Casper Mainnet can be found here. Once accepted, the system returns the transaction hash to the client to indicate it has been enqueued for execution. The transaction could expire while waiting to be gossiped; whenever this happens, a TransactionExpired event is emitted by the event stream servers of all nodes which have the expired transaction.

    +

    Transaction Gossiped

    +

    After a node accepts a new transaction, it will gossip to all other nodes. A validator node will put the transaction into the block proposer buffer. The validator leader will pick the transaction from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given transaction. Each node that accepts a gossiped transaction also emits a TransactionAccepted event on its event stream server. The transaction may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a TransactionExpired event.

    +

    Block Proposed

    +

    The validator leader for this round will propose a block that includes as many transactions from the block proposer buffer as can fit in a block.

    +

    Block Gossiped

    +

    The proposed block propagates to all other nodes.

    +

    Consensus Reached

    +

    Once the other validators reach consensus that the proposed block is valid, all transactions in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a BlockAdded. FinalitySignature events emit shortly after that. Finality signatures for the new block arrive from the validators.

    +

    Transaction Executed

    +

    A transaction executes in distinct phases to accommodate flexibly paying for computation. The phases of a transaction are payment, session, and finalization. Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the transaction is executed, a TransactionProcessed event is emitted by the event stream server.

    +

    In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty transactions.

    +

    Payment code

    +

    Payment code determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's main purse. In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to MAX_PAYMENT_COST may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than MAX_PAYMENT_COST motes (a constant of the system.) +If the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending entity's main purse.

    +

    Session code

    +

    Session code provides the main logic for the transaction. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself).

    +

    Specifying payment code and session code

    +

    The user-defined logic of a transaction can be specified in a number of ways:

    +
      +
    • a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account entity or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the entity the transaction is running in.)
    • +
    • a 32-byte identifier representing the hash where a contract is already stored in the global state
    • +
    • a name corresponding to a named key, where a contract is stored under the key
    • +
    +

    Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module).

    + + \ No newline at end of file diff --git a/2.0.0/transactions/index.html b/2.0.0/transactions/index.html new file mode 100644 index 000000000..39fbdd9c9 --- /dev/null +++ b/2.0.0/transactions/index.html @@ -0,0 +1,90 @@ + + + + + +Transactions | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Transactions

    +

    Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.

    +

    The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute.

    +

    Transaction Types

    +

    The following is a list of Transaction types included within the CLI Casper client put-transaction or put-txn command.

    +

    Withdraw Bid

    +

    withdraw-bid allows validators to withdraw their auction bid.

    +
    Casper Client Command
    + +

    casper-client put-txn withdraw-bid
    /// The public key of the bidder.
    --public-key <FORMATTED STRING or PATH>
    /// The amount in motes to be withdrawn.
    --transaction-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Add Bid

    +

    add-bid allows validators to place an auction bid.

    +
    Casper Client Command
    + +

    casper-client put-txn add-bid
    /// The [delegation rate](../concepts/economics/staking.md#delegation-rate) for delegators staking on to this validator.
    --delegation-rate <INTEGER>
    /// The public key of the bidder.
    --public-key <FORMATTED STRING or PATH>
    /// The amount in motes to be bid.
    --transaction-amount <INTEGER>
    /// The minimum amount of motes that a delegator can stake to this validator.
    --minimum-delegation-amount <INTEGER>
    /// The maximum amount of motes that a delegator can stake to this validator.
    --maximum-delegation-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Delegate

    +

    delegate allows a user to delegate a stake of CSPR to a validator.

    +
    Casper Client Command
    + +

    casper-client put-txn delegate
    /// The delegator's public key.
    --delegator <STRING>
    /// The validator's public key.
    --validator <STRING>
    /// The amount in motes to stake with this validator.
    --transaction-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Undelegate

    +

    undelegate allows a user to undelegate their previously staked CSPR from a validator.

    +
    Casper Client Command
    + +

    casper-client put-txn undelegate
    /// The delegator's public key.
    --delegator <STRING>
    /// The validator's public key.
    --validator <STRING>
    /// The amount in motes to undelegate from this validator.
    --transaction-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Redelegate

    +

    redelegate allows a user to redelegate their previously staked CSPR to a new validator.

    +
    Casper Client Command
    + +

    casper-client put-txn redelegate
    /// The delegator's public key.
    --delegator <STRING>
    /// The old validator's public key.
    --validator <STRING>
    /// The new validator's public key.
    --new-validator <STRING>
    /// The amount in motes to redelegate from the old validator to the new validator.
    --transaction-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Invocable Entity

    +

    invocable-entity allows a user to invoke an entry point on the given AddressableEntity directly using an Entity Address.

    +
    Casper Client Command
    + +

    casper-client put-txn invocable-entity
    /// The [`entity-hash`](../developers/json-rpc/types_chain.md#addressableentityhash) of the entity to invoke.
    --entity-address <FORMATTED STRING or PATH>
    /// The entry point on the invocable entity.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Invocable Entity Alias

    +

    invocable-entity-alias allows a user to invoke an entry point on the given AddressableEntity directly using an alias stored in their named keys.

    +
    Casper Client Command
    + +

    casper-client put-txn invocable-entity-alias
    /// The entity alias stored in the calling entity's named keys.
    --entity-alias <STRING>
    /// The entry point on the invocable entity.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Package

    +

    package allows a user to invoke an entry point on the given contract package using the associated package-address.

    +
    Casper Client Command
    + +

    casper-client put-txn package
    /// The address of the contract package.
    --package-address <FORMATTED STRING or PATH>
    /// The entry point to invoke on the package.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Package Name

    +

    package-name allows a user to invoke an entry point on the given contract package using an alias stored in their named keys.

    +
    Casper Client Command
    + +

    casper-client put-txn package-name
    /// The package alias stored in the calling entity's named keys.
    --package-alias <STRING>
    /// The entry point to invoke on the package.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Session

    +

    session allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial Sending Transactions covers this in depth.

    +
    Casper Client Command
    + +

    casper-client put-txn session
    /// The local path pointing to Wasm that will be sent to global state.
    --transaction-path <PATH>
    /// An entry point on a previously installed contract, if applicable.
    --session-entry-point <NAME>
    /// The category of the Transaction, in decreasing size order.
    --category <install-upgrade|large|medium|small>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    +

    Transfer

    +

    transfer allows a user to transfer the designated number of motes to a target address.

    +
    Casper Client Command
    + +

    casper-client put-txn transfer
    /// The recipient of the transfer.
    --target <FORMATTED STRING>
    /// The amount in motes to be transferred.
    --transfer-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    +
    + + \ No newline at end of file diff --git a/2.0.0/users/block-explorer/index.html b/2.0.0/users/block-explorer/index.html new file mode 100644 index 000000000..b7ceb2d2c --- /dev/null +++ b/2.0.0/users/block-explorer/index.html @@ -0,0 +1,40 @@ + + + + + +Block Explorers | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Block Explorers

    +

    The Casper blockchain is available as the Mainnet and Testnet. +The Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR). +The Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet.

    +

    You can use block explorers to explore the Casper blockchain such as :

    + +

    What is a Block Explorer

    +

    A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history.

    +

    Using a Block Explorer

    +

    You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator.

    +

    The following topics link you to detailed instructions on using the cspr.live block explorer to access and work with your CSPR tokens.

    + +
    note

    To perform actions using the cspr.live block explorer, you must sign in to your Casper account using one of the wallets provided.

    + + \ No newline at end of file diff --git a/2.0.0/users/csprlive/index.html b/2.0.0/users/csprlive/index.html new file mode 100644 index 000000000..5074a9b58 --- /dev/null +++ b/2.0.0/users/csprlive/index.html @@ -0,0 +1,46 @@ + + + + + +Using CSPR.live | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Using the CSPR.live block explorer

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Funding Testnet AccountsFund a Testnet account for testing
    Transferring TokensTransfer tokens using the CSPR.live block explorer
    Delegating TokensDelegate tokens to a validator
    Undelegating TokensUndelegate tokens from a validator
    + + \ No newline at end of file diff --git a/2.0.0/users/delegate-ui/index.html b/2.0.0/users/delegate-ui/index.html new file mode 100644 index 000000000..4638ea7d2 --- /dev/null +++ b/2.0.0/users/delegate-ui/index.html @@ -0,0 +1,83 @@ + + + + + +Delegate Tokens | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Delegating Tokens with a Block Explorer

    +

    Introduction

    +

    This tutorial covers how to delegate Casper tokens to a validator on the network.

    +

    Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called delegation or staking. We will use these terms interchangeably in this guide. See the Staking Key Concepts page for more details about the differences.

    +

    Prerequisites

    +
      +
    1. To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the Casper Wallet by following the Getting Started user guide.
    2. +
    3. You need to fund the account's main purse to delegate tokens.
    4. +
    5. Connect to a block explorer to set up the delegation. This guide uses cspr.live and the Casper Wallet.
    6. +
    7. Review your account before starting the process.
    8. +
    9. Review the current delegation cost and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail.
    10. +
    +

    Reviewing your Account

    +

    Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:

    +
      +
    • The Liquid Account Balance, representing the tokens you have for immediate use
    • +
    • The Delegated Account Balance, representing the delegated tokens already staked with validators on the network
    • +
    • The Delegations tab, listing the validators to whom you have delegated tokens
    • +
    +

    Account and delegations details

    +
      +
    • The Staking Rewards tab, showing the rewards received in each era
    • +
    +

    Account and rewards

    +

    Accessing the Delegation Feature

    +

    You can access the delegation functionality in two ways.

    +

    Option 1: Click Wallet from the top navigation menu and then click Delegate. In the next screen, you will need to specify the validator's public key or search for a validator.

    +

    Delegate from the Wallet

    +

    Option 2: Click Validators from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the Delegate button. The next screen will have the validator's public key pre-populated.

    +

    Delegate from a Validator

    +

    Stepping through the Delegation Process

    +

    The following instructions will take you through the delegation process, starting with the "Delegation details" screen.

    +

    Step 1 - Delegation details

    +
      +
    1. Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field.
    2. +
    3. Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee.
    4. +
    5. Click Next.
    6. +
    +

    Delegation details

    +

    Step 2 - Confirm the delegation

    +
      +
    1. Review the delegation details.
    2. +
    3. If everything is correct, click Confirm and delegate stake. If you wish to make changes, return to the previous screen.
    4. +
    +

    Confirm delegation details

    +

    Step 3 - Sign the delegation

    +
      +
    1. Sign the delegation by clicking Sign with Casper Wallet.
    2. +
    +

    Sign delegation

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.
    2. +
    +

    Signature Request window

    +
      +
    1. Click Sign in the Signature Request window to finalize the delegation.
    2. +
    +

    Completed delegation

    +

    The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the Deploy Details highlighted above.

    +

    Remember to Monitor your Stake. Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the Rewards tab on your account page on https://cspr.live/.

    +

    If you want to undelegate your tokens, you can do so at any time. See the Undelegation Guide for details.

    +

    Video Tutorial

    +

    This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step.

    +
    + + \ No newline at end of file diff --git a/2.0.0/users/delegating/index.html b/2.0.0/users/delegating/index.html new file mode 100644 index 000000000..eafdc5f37 --- /dev/null +++ b/2.0.0/users/delegating/index.html @@ -0,0 +1,59 @@ + + + + + +Delegating Tokens | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Delegating Tokens

    +

    A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.

    +

    Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network.

    +

    Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate.

    +

    Casper does not treat validator stake differently than delegator stake for security reasons.

    +

    Delegation Cost

    +

    This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates to delegations, and where to find more details. Please note that the cost amounts are likely to change over time, and you may have to check the latest release details to get the most up-to-date and accurate delegation cost.

    +

    The delegation cost is defined in the chainspec.toml file of a Casper network. In this example chainspec, the delegation is set to cost 2.5 CSPR. However, when you perform the delegation, you see that it costs a little more than what is specified in the chainspec. Let's discuss why this happens.

    +

    When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is added to the delegation cost defined in the chainspec file. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse.

    +

    For example, the chainspec file in release 2.0.0 contains the following information. Notice the delegation cost specified with delegate.

    +
    [system_costs.auction_costs]
    ...
    delegate = 2_500_000_000
    undelegate = 2_500_000_000
    ...
    +

    Delegation fees may change over time, so it is essential to stay current. To do so, select the latest release in Github and navigate to the resources/production/chainspec.toml file.

    +

    For further questions, please join the Discord channel.

    +

    Delegation Limits

    +

    The chainspec specifies delegation limits, such as the minimum and maximum amount allowed to be delegated. Also, each validator can have a maximum number of delegators.

    +
    # Minimum allowed delegation amount in motes
    minimum_delegation_amount = 500_000_000_000
    # Maximum allowed delegation amount in motes
    maximum_delegation_amount = 1_000_000_000_000_000_000
    # The maximum amount of delegators per validator.
    max_delegators_per_validator = 1200
    +

    Selecting a Node for Delegating

    +

    As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as cspr.live provide validator performance statistics, including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator.

    +

    Validators

    +

    First-time Delegation

    +

    If you perform a delegation for the first time, the system charges some motes to create a purse to hold the delegated tokens. We recommend that you try out delegations on the Casper Testnet before making transactions on the Casper Mainnet. This will help you understand the costs involved in delegating tokens.

    +

    Example: The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on Mainnet.

    +

    When you set up a delegation transaction, it is essential to have enough funds in your account's main purse. Otherwise, the transaction will fail, and you will lose the delegation cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer.

    +

    As a result, when performing a delegation using the command line, we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure.

    +

    Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.

    +

    +**Figure 2** : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR. +

    +
    note

    Transaction costs depend on each Casper network and the cost tables defined in the chainspec. Most of these examples are from the Casper Mainnet or Testnet.

    +

    Monitoring Rewards

    +

    It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations.

    +

    Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours.

    +

    Tutorials

    +

    Navigate to these pages for step-by-step tutorials on delegating and undelegating tokens.

    +
    + + \ No newline at end of file diff --git a/2.0.0/users/funding-from-exchanges/index.html b/2.0.0/users/funding-from-exchanges/index.html new file mode 100644 index 000000000..f5d96baf0 --- /dev/null +++ b/2.0.0/users/funding-from-exchanges/index.html @@ -0,0 +1,58 @@ + + + + + +Funding Mainnet Accounts | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Funding Mainnet Accounts from an Exchange

    +

    To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.

    +

    This guide demonstrates a withdrawal from Coinlist to the Casper Mainnet using the cspr.live block explorer. You need to contact the exchange for instructions if you are working with a different exchange.

    +

    Prerequisites

    +

    Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on https://cspr.live/ and the field you need to specify in the withdrawal request from Coinlist.

    +

    Account public key from CSPR.Live

    +

    Transfers from Coinlist to Casper Mainnet

    +

    Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts.

    +
      +
    1. Log into your https://coinlist.co account.
    2. +
    3. Go to the "Wallet" tab.
    4. +
    +

    Coinlist Wallet tab

    +
      +
    1. Click on the "CSPR" section.
    2. +
    +

    CSPR on Coinlist

    +
      +
    1. Click on the "Withdraw" button.
    2. +
    +

    Withdraw on Coinlist

    +
      +
    1. Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.
    2. +
    +

    Withdrawal fields on Coinlist

    +
      +
    1. +

      Enter 0 in the "Transfer ID" field or another value that is meaningful to you. You MUST enter a value, or the transfer will fail!

      +
    2. +
    3. +

      Enter the CSPR amount you wish to transfer.

      +
    4. +
    5. +

      Click "Review".

      +
    6. +
    7. +

      Submit the transfer request. Wait approximately 5 minutes, and then go to the https://cspr.live/ site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.

      +
    8. +
    + + \ No newline at end of file diff --git a/2.0.0/users/index.html b/2.0.0/users/index.html new file mode 100644 index 000000000..68ed7f19d --- /dev/null +++ b/2.0.0/users/index.html @@ -0,0 +1,91 @@ + + + + + +Users Overview | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Users Overview

    +

    General Topics

    + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Block ExplorersA guide to understanding block explorers
    Funding Mainnet AccountsFunding Mainnet accounts from an exchange
    Delegating TokensDelegating tokens to a validator (a.k.a. staking with a validator)
    +

    Using CSPR.live

    +

    Interact with the Casper blockchain using the cspr.live block explorer.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TopicDescription
    Funding Testnet AccountsFunding your Testnet account using the Faucet
    Delegating TokensStaking your Casper tokens with cspr.live
    Undelegating TokensUn-staking your Casper tokens
    Transferring TokensTransferring your Casper tokens using cspr.live
    +

    Using Ledger Devices

    +

    Interact with the Casper blockchain using a Ledger device.

    + + + + + + + + + + + + + + + + + +
    TopicDescription
    Ledger SetupA guide to setting up your Ledger device
    Delegating with Ledger DevicesDelegating tokens using your Ledger device
    + + \ No newline at end of file diff --git a/2.0.0/users/ledger/index.html b/2.0.0/users/ledger/index.html new file mode 100644 index 000000000..3ac286994 --- /dev/null +++ b/2.0.0/users/ledger/index.html @@ -0,0 +1,46 @@ + + + + + +Casper on Ledger | Casper Docs - Redux + + + + + + + + + +
    + + \ No newline at end of file diff --git a/next/users/ledger/ledger-cspr-live/index.html b/2.0.0/users/ledger/ledger-cspr-live/index.html similarity index 51% rename from next/users/ledger/ledger-cspr-live/index.html rename to 2.0.0/users/ledger/ledger-cspr-live/index.html index 9d9ee29a4..49c9fb672 100644 --- a/next/users/ledger/ledger-cspr-live/index.html +++ b/2.0.0/users/ledger/ledger-cspr-live/index.html @@ -1,21 +1,21 @@ - + -Ledger and CSPR.live | Casper Docs - Redux +Ledger and CSPR.live | Casper Docs - Redux - - + +
    Version: Next

    Using Ledger and CSPR.live

    + submit an issue on Github
    Version: 2.0.0

    Using Ledger and CSPR.live

    This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.

    Prerequisites

      @@ -136,6 +136,6 @@

      Sending Tokens15-approve

      After approving the transaction with your Ledger hardware wallet, the cspr.live block explorer will display a "Transfer completed" page.

      4-transfer-completed

      -

      You can now check your account to see a list of all the completed transfers.

    +

    You can now check your account to see a list of all the completed transfers.

    \ No newline at end of file diff --git a/next/users/ledger/ledger-live/index.html b/2.0.0/users/ledger/ledger-live/index.html similarity index 57% rename from next/users/ledger/ledger-live/index.html rename to 2.0.0/users/ledger/ledger-live/index.html index 6bed109e0..c20046d24 100644 --- a/next/users/ledger/ledger-live/index.html +++ b/2.0.0/users/ledger/ledger-live/index.html @@ -1,27 +1,27 @@ - + -Ledger and Ledger Live | Casper Docs - Redux +Ledger and Ledger Live | Casper Docs - Redux - - + +
    Version: Next

    Using Ledger and Ledger Live

    + submit an issue on Github
    Version: 2.0.0

    Using Ledger and Ledger Live

    This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.

    important

    From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live.

    Prerequisites

    1. Configure your Ledger and the Ledger Live application as described in the Getting Started with Ledger Live article.
    2. -
    3. Install the Casper app as described here.
    4. +
    5. Install the Casper app as described here.

    Connecting to Ledger Live

    This section describes using the Ledger device with the Ledger Live application and your Casper accounts.

    @@ -163,6 +163,6 @@

    Sending Tokens
  • You can view the transaction in the CSPR.live block explorer by clicking on the View in explorer link.
  • -

    Explorer chowing transaction

    +

    Explorer chowing transaction

    \ No newline at end of file diff --git a/next/users/staking-ledger/index.html b/2.0.0/users/staking-ledger/index.html similarity index 51% rename from next/users/staking-ledger/index.html rename to 2.0.0/users/staking-ledger/index.html index fec62eee6..54490e836 100644 --- a/next/users/staking-ledger/index.html +++ b/2.0.0/users/staking-ledger/index.html @@ -1,26 +1,26 @@ - + -Delegate with Ledger | Casper Docs - Redux +Delegate with Ledger | Casper Docs - Redux - - + +
    Version: Next

    Delegating with Ledger Devices

    + submit an issue on Github
    Version: 2.0.0

    Delegating with Ledger Devices

    Ledger Initialization

    Before getting started, you need to complete two prerequisite steps:

    1. Set up your Ledger device using the official documentation.
    2. -
    3. Connect the Ledger to your cspr.live account by following the Ledger Setup guide.
    4. +
    5. Connect the Ledger to your cspr.live account by following the Ledger Setup guide.

    Important Notes

      @@ -47,7 +47,7 @@

      Receive Tokens from an External Source

      -

      This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the documentation.

      +

      This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the documentation.

      Staking Tokens

      Once you have tokens in your account, staking (delegating) with a validator is easy.

        @@ -108,6 +108,6 @@

        Sign t

        Casper Ready 14

        Note: There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.

        Casper Ready 15

        -

        After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish.

    +

    After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish.

    \ No newline at end of file diff --git a/2.0.0/users/testnet-faucet/index.html b/2.0.0/users/testnet-faucet/index.html new file mode 100644 index 000000000..aeb3cfb7d --- /dev/null +++ b/2.0.0/users/testnet-faucet/index.html @@ -0,0 +1,34 @@ + + + + + +Testnet Funding | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Funding Testnet Accounts

    +

    The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.

    +

    Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below.

    +

    Requesting Testnet Tokens

    +

    To request test tokens, follow these steps:

    +
      +
    1. Log into the Casper Testnet with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    2. +
    3. Click Tools on the top menu bar and select Faucet from the drop-down menu. Or, navigate to the Faucet using this link: https://testnet.cspr.live/tools/faucet.
    4. +
    5. Click Request tokens on the Faucet page:
    6. +
    +

    Faucet

    +
    caution

    Tokens can be requested only once per account. Otherwise, the deploy will fail with status User error: 1.

    If you have already exhausted your test funds, you can always create a new account.

    +
      +
    1. The Testnet will credit your account with test tokens.
    2. +
    + + \ No newline at end of file diff --git a/2.0.0/users/token-transfer/index.html b/2.0.0/users/token-transfer/index.html new file mode 100644 index 000000000..aba5037e5 --- /dev/null +++ b/2.0.0/users/token-transfer/index.html @@ -0,0 +1,56 @@ + + + + + +Transfer Tokens | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Transferring Tokens

    +

    You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.

    +

    Transferring Tokens

    +

    To transfer tokens, follow these steps:

    +
      +
    1. Sign in to your account with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    2. +
    3. Click Wallet on the top menu bar and select Transfer CSPR from the drop-down menu.
    4. +
    5. Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one.
    6. +
    7. Click Next to proceed.
    8. +
    +

    Transfer details

    +
      +
    1. A confirmation window appears to verify the details entered. Click Confirm and transfer to proceed to the next step.
    2. +
    +

    Confirm transfer

    +
      +
    1. Review the following important fields:
    2. +
    +
      +
    • The Deploy hash, which uniquely identifies your transfer
    • +
    • The Recipient public key of the person receiving your transfer
    • +
    • The Recipient account hash used by the system to track the transaction
    • +
    • The Transfer Amount containing the value of the transfer
    • +
    +

    Sign the transaction by selecting the Sign with Casper Wallet button to proceed to the next step.

    +

    Sign the transfer

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click Sign in the Signature Request window to complete the transaction.
    2. +
    +

    Review the transaction

    +
      +
    1. You completed the transaction and successfully transferred tokens.
    2. +
    +

    Transfer completed window

    +
      +
    1. View the updated CSPR balance in the account's main purse next.
    2. +
    + + \ No newline at end of file diff --git a/2.0.0/users/undelegate-ui/index.html b/2.0.0/users/undelegate-ui/index.html new file mode 100644 index 000000000..6a7762cb6 --- /dev/null +++ b/2.0.0/users/undelegate-ui/index.html @@ -0,0 +1,61 @@ + + + + + +Undelegate Tokens | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Undelegating Tokens

    +

    If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.

    +

    Prerequisites

    +

    This guide assumes that you have previously delegated tokens to a validator using a block explorer or the Casper client.

    +

    Accessing the Undelegation Feature

    +

    You can access the undelegation functionality in three ways.

    +

    Option 1: Click Wallet from the top navigation menu and then click Undelegate Stake.

    +

    Undelegate from Wallet

    +

    Option 2: Click Validators from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the Undelegate Stake button.

    +

    Undelegate from Validator

    +

    Option 3: Open your account details and select the Delegations tab. Click the Undelegate button next to the validator from whom you wish to undelegate.

    +

    Undelegate from Account

    +

    Stepping through the Undelegation Process

    +

    The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.

    +

    Step 1 - Undelegation details

    +
      +
    1. Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field.
    2. +
    3. Enter the amount of Casper tokens you want to undelegate.
    4. +
    5. Click Next.
    6. +
    +

    Undelegation details

    +

    Step 2 - Confirm the undelegation

    +
      +
    1. Review the undelegation details.
    2. +
    3. If everything looks correct, click Confirm and undelegate stake. If you wish to make changes, return to the previous screen.
    4. +
    +

    Confirm undelegation

    +

    Step 3 - Sign the undelegation

    +
      +
    1. Click Sign with Casper Wallet to sign the undelegation.
    2. +
    +

    Sign the undelegation

    +
      +
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.
    2. +
    +

    Confirm deploy hash

    +
      +
    1. Click Sign in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:
    2. +
    +

    Undelegation confirmed

    +

    It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.

    +

    Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours.

    + + \ No newline at end of file diff --git a/2.0.0/workflow/ledger-setup/index.html b/2.0.0/workflow/ledger-setup/index.html new file mode 100644 index 000000000..f9412db52 --- /dev/null +++ b/2.0.0/workflow/ledger-setup/index.html @@ -0,0 +1,70 @@ + + + + + +Set up Ledger | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Ledger Setup with Casper

    +

    A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.

    +

    Prerequisites

    +
      +
    1. Configure your Ledger and the Ledger Live application as described in the Getting Started with Ledger Live article.
    2. +
    3. <span style={{color:"#ee5945"}}>CRITICAL: Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key.
    4. +
    5. Make sure the Ledger Live application version is at least at 2.73.1, which is the version that includes Casper accounts.
    6. +
    +
    note

    If you need help, contact us on Twitter, Discord, or Telegram.

    +

    Installing the Casper App on a Ledger Device

    +

    Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official Ledger support site.

    +
      +
    1. In Ledger Live, open My Ledger at the bottom of the left-hand menu.
    2. +
    +

    Open My Ledger

    +
      +
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    2. +
    +

    Unlock your Ledger device

    +
      +
    1. If asked, allow Ledger manager on your device.
    2. +
    +

    Allow Ledger

    +
      +
    1. Find Casper in the app catalog.
    2. +
    +

    Find the Casper app

    +
    important

    Having trouble finding the Casper app? +Please search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.

    +
      +
    1. Click the Install button of the app.
    2. +
    +
      +
    • An installation window appears.
    • +
    • Your device will display "Processing..."
    • +
    • The app installation is confirmed.
    • +
    +

    Casper installation confirmed

    +
      +
    1. Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps.
    2. +
    +

    Select Casper on Ledger

    +

    Casper app is ready

    +

    Sending and Receiving Tokens

    +

    To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:

    +
      +
    1. Manage Casper Accounts using Ledger and Ledger Live
    2. +
    3. Manage Casper Accounts using Ledger and CSPR.live
    4. +
    +

    To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in Delegating with Ledger Devices.

    +

    Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange.

    + + \ No newline at end of file diff --git a/2.0.0/writing-contracts/index.html b/2.0.0/writing-contracts/index.html new file mode 100644 index 000000000..a1dc3bbaa --- /dev/null +++ b/2.0.0/writing-contracts/index.html @@ -0,0 +1,158 @@ + + + + + +Introduction | Casper Docs - Redux + + + + + + + + + +
    Version: 2.0.0

    Writing On-Chain Code

    +

    This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.

    +

    + +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started with RustAn introduction to using Rust with the Casper Platform
    Getting Started with AssemblyScriptAn introduction to using AssemblyScript with the Casper Platform
    Writing a Basic Smart Contract in RustAn example of a smart contract built in Rust
    Unit Testing Smart ContractsSteps to test contract code using the unit testing framework
    Upgrading and Maintaining Smart ContractsAn introduction to versioning smart contracts
    Calling Contracts
    Smart Contracts and Session CodeUnderstand what session code is and when you would use it over contract code
    Writing Session CodeAn introduction to writing session code
    Unit Testing Session CodeSteps to test session code using the unit testing framework
    Contract-Level EventsEnabling smart contracts to emit messages while executing on the blockchain
    Using Contract Hash vs. Package HashAdvantages and disadvantages of using contract_hash vs. contract_package_hash when calling a contract
    The Factory Pattern for Smart ContractsLearn to implement the contract factory pattern on a Casper network
    Best Practices for Casper Smart Contract AuthorsAn 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 covers installing and calling contracts using the Casper command-line client written in Rust.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Installing Smart Contracts and Querying Global StateA guide on installing smart contracts and querying global state
    Calling Smart Contracts with the Rust ClientSteps to call a smart contract with the Rust command-line client
    Reading and Writing to DictionariesInformation on Dictionaries and how to read and write to them on the Casper Platform.
    Execution Error CodesPossible error codes when writing smart contracts.
    +

    Tutorials

    +

    The following tutorials outline some aspects of writing smart contracts on a Casper network.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Smart Contract UpgradesLearn how to upgrade smart contracts
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    Interacting with Runtime Return ValuesLearning how to return a value using contract code
    Working with Authorization KeysRetrieving and using the authorization keys associated with a transaction
    Safely Transfer Tokens to a ContractHow to handle tokens via a contract
    + + \ No newline at end of file diff --git a/404.html b/404.html index 3df226a87..e27aaf964 100644 --- a/404.html +++ b/404.html @@ -1,20 +1,20 @@ - + -Casper Docs - Redux +Casper Docs - Redux - - + +

    Page Not Found

    We could not find what you were looking for.

    Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

    + submit an issue on Github

    Page Not Found

    We could not find what you were looking for.

    Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

    \ No newline at end of file diff --git a/CNAME b/CNAME deleted file mode 100644 index a88c1b47a..000000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -casperdocs.paddentech.com \ No newline at end of file diff --git a/assets/js/00935d0c.4467c113.js b/assets/js/00935d0c.4467c113.js new file mode 100644 index 000000000..49f64d086 --- /dev/null +++ b/assets/js/00935d0c.4467c113.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82487],{42254:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Undelegate Tokens",slug:"/users/undelegate-ui"},o="Undelegating Tokens",l={id:"users/csprlive/undelegate-ui",title:"Undelegate Tokens",description:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.",source:"@site/versioned_docs/version-2.0.0/users/csprlive/undelegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/undelegate-ui",permalink:"/2.0.0/users/undelegate-ui",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Undelegate Tokens",slug:"/users/undelegate-ui"},sidebar:"users",previous:{title:"Delegate Tokens",permalink:"/2.0.0/users/delegate-ui"},next:{title:"Transfer Tokens",permalink:"/2.0.0/users/token-transfer"}},r={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Accessing the Undelegation Feature",id:"accessing-the-undelegation-feature",level:2},{value:"Stepping through the Undelegation Process",id:"stepping-through-the-undelegation-process",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens",children:"Undelegating Tokens"})}),"\n",(0,s.jsx)(n.p,{children:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["This guide assumes that you have previously delegated tokens to a validator using a ",(0,s.jsx)(n.a,{href:"/2.0.0/users/delegate-ui",children:"block explorer"})," or the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"Casper client"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"accessing-the-undelegation-feature",children:"Accessing the Undelegation Feature"}),"\n",(0,s.jsx)(n.p,{children:"You can access the undelegation functionality in three ways."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 1:"})," Click ",(0,s.jsx)(n.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Undelegate from Wallet",src:t(88446).A+"",width:"243",height:"325"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 2:"})," Click ",(0,s.jsx)(n.strong,{children:"Validators"})," from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"})," button."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Undelegate from Validator",src:t(65770).A+"",width:"2222",height:"992"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 3:"})," Open your account details and select the ",(0,s.jsx)(n.strong,{children:"Delegations"})," tab. Click the ",(0,s.jsx)(n.strong,{children:"Undelegate"})," button next to the validator from whom you wish to undelegate."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Undelegate from Account",src:t(70392).A+"",width:"2482",height:"524"})}),"\n",(0,s.jsx)(n.h2,{id:"stepping-through-the-undelegation-process",children:"Stepping through the Undelegation Process"}),"\n",(0,s.jsx)(n.p,{children:'The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.'}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 1 - Undelegation details"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,s.jsx)(n.li,{children:"Enter the amount of Casper tokens you want to undelegate."}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Undelegation details",src:t(96714).A+"",width:"1136",height:"1442"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 2 - Confirm the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Review the undelegation details."}),"\n",(0,s.jsxs)(n.li,{children:["If everything looks correct, click ",(0,s.jsx)(n.strong,{children:"Confirm and undelegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Confirm undelegation",src:t(48126).A+"",width:"1156",height:"1480"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 3 - Sign the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign with Casper Wallet"})," to sign the undelegation."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sign the undelegation",src:t(99486).A+"",width:"1126",height:"1706"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Confirm deploy hash",src:t(89023).A+"",width:"1974",height:"1728"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Undelegation confirmed",src:t(62504).A+"",width:"1114",height:"1336"})}),"\n",(0,s.jsx)(n.p,{children:'It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.'}),"\n",(0,s.jsx)(n.p,{children:"Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours."})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},88446:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.wallet-undelegate-9d248f8c648da6a81f11519504d7812b.png"},65770:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.validator-undelegate-5b02fc97aa94336f98b91ed2414630aa.png"},70392:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.account-undelegate-115ac530fff9a47a18e6e9faa1dd418b.png"},96714:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.undelegate-details-bc50ff78eb29ada22fab3ed956a833be.png"},48126:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.confirm-undelegation-ab54ef5443b66d944efc83b7d9623af7.png"},99486:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/6.sign-undelegation-0e412d3726ca39417062e53ae0e6fcca.png"},89023:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/7.confirm-hash-466847a8e9502b69d17c46350f4bcab2.png"},62504:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/8.undelegation-confirmed-a77491f86b955fe091fe6ebf6e685f91.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>l});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/017e616b.8ebc0779.js b/assets/js/017e616b.8ebc0779.js new file mode 100644 index 000000000..dce068f64 --- /dev/null +++ b/assets/js/017e616b.8ebc0779.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93253],{37388:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"Private Network Setup"},r="Setting Up a Private Casper Network",o={id:"operators/setup-network/create-private",title:"Private Network Setup",description:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.",source:"@site/versioned_docs/version-2.0.0/operators/setup-network/create-private.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/create-private",permalink:"/2.0.0/operators/setup-network/create-private",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Private Network Setup"},sidebar:"operators",previous:{title:"The Chainspec",permalink:"/2.0.0/operators/setup-network/chain-spec"},next:{title:"Staging Files",permalink:"/2.0.0/operators/setup-network/staging-files-for-new-network"}},c={},d=[{value:"Contents",id:"contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1. Setting up a Validator Node",id:"step-1-setting-up-a-validator-node",level:2},{value:"Step 2. Setting up the Directory",id:"step-2-setting-up-the-directory",level:2},{value:"Step 3. Configuring the Genesis Block",id:"step-3-configuring-the-genesis-block",level:2},{value:"Unrestricted transfers configuration",id:"unrestricted-transfers-configuration",level:3},{value:"Refund handling configuration",id:"refund-handling-configuration",level:3},{value:"Fee handling configuration",id:"fee-handling-configuration",level:3},{value:"Auction behavior configuration",id:"auction-behavior-configuration",level:3},{value:"Step 4. Configuring the Administrator Accounts",id:"step-4-configuring-the-administrator-accounts",level:2},{value:"Configuring administrator accounts",id:"configuring-administrator-accounts",level:3},{value:"Generating new administrator accounts",id:"generating-new-administrator-accounts",level:3},{value:"Managing accounts and smart contracts",id:"managing-accounts-and-smart-contracts",level:3},{value:"Step 5. Starting the Casper Node",id:"step-5-starting-the-casper-node",level:2},{value:"Step 6. Rotating the Validator Accounts",id:"step-6-rotating-the-validator-accounts",level:2},{value:"Step 7. Testing the Private Network",id:"step-7-testing-the-private-network",level:2},{value:"Sample configuration files",id:"sample-configuration-files",level:3},{value:"Specifying IP addresses",id:"specifying-ip-addresses",level:3},{value:"Setting up the node",id:"setting-up-the-node",level:3},{value:"Network access control",id:"network-access-control",level:3},{value:"Funding Alice's account",id:"funding-alices-account",level:3},{value:"Adding a bid as Alice",id:"adding-a-bid-as-alice",level:3},{value:"Disabling Alice's account",id:"disabling-alices-account",level:3},{value:"Enabling Alice's account",id:"enabling-alices-account",level:3},{value:"Enabling a contract",id:"enabling-a-contract",level:3},{value:"Disabling a contract",id:"disabling-a-contract",level:3},{value:"Verifying seigniorage allocations",id:"verifying-seigniorage-allocations",level:3},{value:"Operating guide",id:"operating-guide",level:3},{value:"Rotating validators",id:"rotating-validators",level:3},{value:"Adding new administrators",id:"adding-new-administrators",level:3},{value:"Setting up a Block Explorer",id:"setting-up-a-block-explorer",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"setting-up-a-private-casper-network",children:"Setting Up a Private Casper Network"})}),"\n",(0,a.jsx)(n.p,{children:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network."}),"\n",(0,a.jsx)(n.h2,{id:"contents",children:"Contents"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"Setting up a Validator Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-2-setting-up-the-directory",children:"Setting up the Directory"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-3-configuring-the-genesis-block",children:"Configuring the Genesis Block"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-4-configuring-the-administrator-accounts",children:"Configuring the Administrator Accounts"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-5-starting-the-casper-node",children:"Starting the Casper Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-7-testing-the-private-network",children:"Testing the Private Network"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#setting-up-a-block-explorer",children:"Setting up a Block Explorer"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Follow these guides to set up the required environment and user accounts."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Setting up the Casper client"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/blob/dev/README.md#casper-client",children:"Setting up the client for interacting with the network"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"Setting up an Account"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-1-setting-up-a-validator-node",children:"Step 1. Setting up a Validator Node"}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#node",children:"Casper node"})," is a physical or virtual device participating in a Casper network. You need to set up several ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validator"})," nodes on your private network. An ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/O#operator",children:"operator"})," who has won an ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A#auction",children:"auction"})," bid will be a validator for the private network."]}),"\n",(0,a.jsx)(n.p,{children:"Use the below guides to set up and manage validator nodes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup - GitHub guide"}),": A guide to configuring a system with the new Rust node to operate within a network."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration",children:"Basic node setup tutorial"}),": A guide on using the ",(0,a.jsx)(n.code,{children:"casper-node-launcher"}),", generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://docs.cspr.community/",children:"Set up Mainnet and Testnet validator nodes"}),": A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use these FAQ collections for tips and details for validators."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-2-setting-up-the-directory",children:"Step 2. Setting up the Directory"}),"\n",(0,a.jsx)(n.p,{children:"Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Go through the ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#file-locations",children:"file location"})," section to understand how directories are created and managed in a Casper private network."]}),"\n",(0,a.jsxs)(n.li,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"setting up a new network"})," guide to identify the required configuration files to set up a genesis block."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-3-configuring-the-genesis-block",children:"Step 3. Configuring the Genesis Block"}),"\n",(0,a.jsxs)(n.p,{children:["A Casper private network contains a different set of configurations when compared to the public network. The ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:(0,a.jsx)(n.code,{children:"chainspec.toml"})})," file contains the required configurations for the genesis process in a private network."]}),"\n",(0,a.jsxs)(n.p,{children:["You should add the configuration options below to the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file inside the ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup-network/create-private#step-2-setting-up-the-directory",children:"private network directory"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"unrestricted-transfers-configuration",children:"Unrestricted transfers configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"In contrast, users in the public network can freely transfer funds to different accounts."}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nallow_unrestricted_transfers = false\ncompute_rewards = false\nallow_auction_bids = false\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\nfee_handling = { type = "accumulate" }\nadministrators = ["ADMIN_PUBLIC_KEY"]\n'})}),(0,a.jsxs)(n.p,{children:["The Casper Mainnet has different refund and fee handling configurations explained in more detail ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"here"}),"."]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = true\ncompute_rewards = true\nallow_auction_bids = true\nrefund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\nadministrators = []\n"})})]}),"\n",(0,a.jsx)(n.h3,{id:"refund-handling-configuration",children:"Refund handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user."}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Another example: a refund variant with ",(0,a.jsx)(n.code,{children:"refund_ratio"})," of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return."]}),"\n",(0,a.jsxs)(n.p,{children:["After deducting the gas fee, the distribution of the remaining payment amount is handled based on the ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup-network/create-private#fee-handling-config",children:"fee_handling"})," configuration."]}),"\n",(0,a.jsx)(n.p,{children:"Starting with the Condor release, a Casper private network can eliminate fees and, thus, not require refunds, similar to the Casper Mainnet:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"refund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\n"})}),"\n",(0,a.jsx)(n.h3,{id:"fee-handling-configuration",children:"Fee handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed."}),"\n",(0,a.jsx)(n.p,{children:"Set up the configuration as below:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nfee_handling = { type = "pay_to_proposer" }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"fee_handling"})," configuration has four variations:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"no_fee"}),": Fees are eliminated. No refunds are necessary."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"pay_to_proposer"}),": The rest of the payment amount after deducing the gas fee from a refund is paid to the block's ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/P#proposer",children:"proposer"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"burn"}),": The tokens paid are burned, and the total supply is reduced."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"accumulate"}),": The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"auction-behavior-configuration",children:"Auction behavior configuration"}),"\n",(0,a.jsx)(n.p,{children:"A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set."}),"\n",(0,a.jsx)(n.p,{children:"Use the configuration below to limit the auction validators:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_auction_bids = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Other configurations related to the auction:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"allow_auction_bids"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"})," then ",(0,a.jsx)(n.code,{children:"add_bid"})," and ",(0,a.jsx)(n.code,{children:"delegate"})," options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an ",(0,a.jsx)(n.code,{children:"AuctionBidsDisabled"})," error."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"core.compute_rewards"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"}),", then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In a public network, ",(0,a.jsx)(n.code,{children:"allow_auction_bid"})," is set to ",(0,a.jsx)(n.em,{children:"true"}),", which allows bidding for new entries and validator nodes."]}),"\n",(0,a.jsx)(n.h2,{id:"step-4-configuring-the-administrator-accounts",children:"Step 4. Configuring the Administrator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["An administrator is mandatory for a private network since it manages all the other ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validator"})," accounts. There should be at least one administrator account configured within a network to operate it as a ",(0,a.jsx)(n.code,{children:"private network"}),". You can create new administrators and ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup-network/create-private#step-6-rotating-the-validator-accounts",children:"rotate the validator set"})," in a single configuration update. The operator must first ensure the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances."]}),"\n",(0,a.jsx)(n.h3,{id:"configuring-administrator-accounts",children:"Configuring administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use this configuration option in the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," to add administrator accounts to the private network:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_ACCOUNT_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note"}),": Regular accounts are not allowed to manage their associated keys on a private network."]}),"\n",(0,a.jsx)(n.h3,{id:"generating-new-administrator-accounts",children:"Generating new administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use the command below to generate new administrator accounts in your private network. This generates the contents of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the entries required to create new administrator accounts at the upgrade point."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen \\\n generate-admins --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n --admin $PUBLIC_KEY_HEX, $BALANCE\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_PUBLIC_KEY"})," - Public key of the administrator in a hex format."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_BALANCE"})," - Balance for the administrator\u2019s main purse."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"DATA_DIR"})," - Path to the global state directory."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"STATE_ROOT_HASH"})," - State root hash, taken from the latest block before an upgrade."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"managing-accounts-and-smart-contracts",children:"Managing accounts and smart contracts"}),"\n",(0,a.jsxs)(n.p,{children:["Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/c8023736786b2c2b0fd17250fcfd50502ff4151f/smart_contracts/contracts/private_chain/control-management/src/main.rs",children:"Casper node's private chain control management"})," file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key."]}),"\n",(0,a.jsx)(n.p,{children:"Use this command to generate these contracts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"make build-contracts-rs\n"})}),"\n",(0,a.jsx)(n.p,{children:"Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"disable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"enable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with argument ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='255'"})," and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='255'"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='1'"})," set to 1 and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='0'"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-5-starting-the-casper-node",children:"Step 5. Starting the Casper Node"}),"\n",(0,a.jsx)(n.p,{children:"After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup GitHub"})," guide to know more details about configuring a new node to operate within a network."]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally, refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"casper-node-launcher"})," to check whether the installed node binaries match the installed configurations by comparing the version numbers."]}),"\n",(0,a.jsx)(n.h2,{id:"step-6-rotating-the-validator-accounts",children:"Step 6. Rotating the Validator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["You need to go through ",(0,a.jsx)(n.a,{href:"#step-1-setting-up-the-validator-nodes",children:"setting up a validator node "})," guide before starting this section."]}),"\n",(0,a.jsxs)(n.p,{children:["To rotate the validators set, you must perform a network upgrade using a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.p,{children:"When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block."}),"\n",(0,a.jsxs)(n.p,{children:["After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"\nglobal-state-update-gen validators \\\n --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE\n\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Each use of the ",(0,a.jsx)(n.code,{children:"--validator"})," parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter."]}),"\n",(0,a.jsxs)(n.p,{children:["After designating the next era's validators, you must set the chainspec activation point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to ",(0,a.jsx)(n.code,{children:"X"}),", where ",(0,a.jsx)(n.code,{children:"X"})," is equal to the new era after the switch block from above. Finally, set ",(0,a.jsx)(n.code,{children:"hard_reset = true"}),". This makes the network revert to the end of the previous era when restarted with the upgrade."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),", set the activaction point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to 10 and ",(0,a.jsx)(n.code,{children:"hard_reset"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Please make sure you are running this tool as the same user that owns ",(0,a.jsx)(n.code,{children:"$DATA_DIR"}),". Otherwise, you may receive a permission denied error."]})}),"\n",(0,a.jsxs)(n.p,{children:["You can find more details on enabling new validators in the ",(0,a.jsx)(n.a,{href:"/2.0.0/operators/setup/joining",children:"joining a running network"})," guide. The guide explains how to join the network and provide additional security to the system."]}),"\n",(0,a.jsx)(n.h2,{id:"step-7-testing-the-private-network",children:"Step 7. Testing the Private Network"}),"\n",(0,a.jsx)(n.p,{children:"We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer."}),"\n",(0,a.jsx)(n.h3,{id:"sample-configuration-files",children:"Sample configuration files"}),"\n",(0,a.jsx)(n.p,{children:"Here are sample configurations that can be adapted for testing:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["A ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/chainspec.toml.in",children:"chainspec template"})," that is specific to the customer's private chain."]}),"\n",(0,a.jsxs)(n.li,{children:["An ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/accounts.toml.in",children:"accounts template"})," with one administrator in the ",(0,a.jsx)(n.code,{children:"administrators"})," settings."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"specifying-ip-addresses",children:"Specifying IP addresses"}),"\n",(0,a.jsx)(n.p,{children:"Here is an example set of IP addresses in use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"http://18.224.190.213:7777\nhttp://18.188.11.97:7777\nhttp://18.188.206.170:7777\nhttp://18.116.201.114:7777\n"})}),"\n",(0,a.jsx)(n.h3,{id:"setting-up-the-node",children:"Setting up the node"}),"\n",(0,a.jsx)(n.p,{children:"Set up the node address, chain name, and the administrator's secret key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'export NODE_ADDR=http://18.224.190.213:7777\nexport CHAIN_NAME="private-test"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This testing example will also use an ",(0,a.jsx)(n.code,{children:"alice/secret_key.pem"})," file, a secret key generated through the ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#creating-accounts-and-keys",children:"keys generation process"}),". Alice is a regular user in this testing example."]}),"\n",(0,a.jsx)(n.h3,{id:"network-access-control",children:"Network access control"}),"\n",(0,a.jsx)(n.p,{children:"With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed."}),"\n",(0,a.jsx)(n.p,{children:"To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "local_node_cert.pem"\nsecret_key = "local_node.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"tls_certificate"})," is the certificate signed by a ",(0,a.jsx)(n.code,{children:"ca_cert.pem"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secret_key"})," refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ca_certificate"})," is the network CA that should be the same on each of the nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'# Recommended EC curve algorithm to use\nexport CURVE="secp521r1"\n\n# Generate secret key for CA and save it to ca_key.pem\nopenssl ecparam -out ca_key.pem -name $CURVE -genkey\n# Create ca_cert.pem signed by ca_key.pem\nopenssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem\n\n# Generate secret key for a node and a certificate signed by the CA\nopenssl ecparam -out node_1.pem -name $CURVE -genkey\nopenssl req -new -key node_1.pem -out node_1.csr -sha256\nopenssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem\n'})}),"\n",(0,a.jsx)(n.p,{children:"And then configure the node with the following settings:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "node_1_cert.pem"\nsecret_key = "node_1.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Every node in the private chain network has to be configured with the same CA certificate, and each ",(0,a.jsx)(n.code,{children:"tls_certificate"})," and ",(0,a.jsx)(n.code,{children:"secret_key"})," pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Keep in mind that for security reasons ",(0,a.jsx)(n.code,{children:"ca_key.pem"})," should be stored securely and never present on each of participating machines."]}),"\n",(0,a.jsx)(n.h3,{id:"funding-alices-account",children:"Funding Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command transfers tokens to Alice's main purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n transfer \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(> global_state.toml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By using ",(0,a.jsx)(n.code,{children:">>"})," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."]}),"\n",(0,a.jsx)(n.p,{children:"Common options:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--data-dir"})," path to a global state directory where ",(0,a.jsx)(n.code,{children:"data.lmdb"})," can be found"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--state-hash"})," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"rotating-validators",children:"Rotating validators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command rotates the validator set. Perform a network upgrade with a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-new-administrators",children:"Adding new administrators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command produces the administrator content in the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n"})}),"\n",(0,a.jsx)(n.p,{children:"Remember that new administrators can be created, and the validator set can also be rotated in a single update."}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"After this step, the private network would be ready for use."}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-a-block-explorer",children:"Setting up a Block Explorer"}),"\n",(0,a.jsxs)(n.p,{children:["Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-blockexplorer-frontend",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/01be152e.b1fca991.js b/assets/js/01be152e.b1fca991.js new file mode 100644 index 000000000..c5cac05a7 --- /dev/null +++ b/assets/js/01be152e.b1fca991.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94912],{27586:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var c=s(74848),i=s(28453);const t={title:"Accounts and Keys"},a="Accounts and Cryptographic Keys",r={id:"concepts/accounts-and-keys",title:"Accounts and Keys",description:"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.",source:"@site/versioned_docs/version-2.0.0/concepts/accounts-and-keys.md",sourceDirName:"concepts",slug:"/concepts/accounts-and-keys",permalink:"/2.0.0/concepts/accounts-and-keys",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Accounts and Keys"},sidebar:"concepts",previous:{title:"Addressable Entities",permalink:"/2.0.0/concepts/addressable-entity"},next:{title:"Key Types",permalink:"/2.0.0/concepts/key-types"}},o={},d=[{value:"Creating Accounts and Keys",id:"creating-accounts-and-keys",level:2},{value:"Option 1: Generating keys using the Casper Client",id:"option-1-key-generation-using-the-casper-client",level:3},{value:"EdDSA Keys",id:"eddsa-keys",level:4},{value:"ECDSA Keys",id:"ecdsa-keys",level:4},{value:"Option 2: Generating keys using a block explorer",id:"option-2-key-generation-using-a-block-explorer",level:3},{value:"Funding your Account",id:"funding-your-account",level:2},{value:"Working with Existing Ethereum Keys",id:"working-with-existing-ethereum-keys",level:2},{value:"Option 3: Generating keys using OpenSSL",id:"option-3-generating-keys-using-openssl",level:3},{value:"Generating the secret_key.pem file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the secret_key.pem file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"accounts-and-cryptographic-keys",children:"Accounts and Cryptographic Keys"})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain ",(0,c.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"account-based model"}),", uniquely identified by an ",(0,c.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,c.jsx)(n.code,{children:"PublicKey"}),". The ",(0,c.jsx)(n.code,{children:"AccountHash"})," is a 32-byte hash derived from any of the supported ",(0,c.jsx)(n.code,{children:"PublicKey"})," variants below to standardize keys that can vary in length."]}),"\n",(0,c.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,c.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,c.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#ecdsa-keys",children:"Secp256k1"})," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys using both formats, and it is also possible to ",(0,c.jsx)(n.a,{href:"#working-with-existing-ethereum-keys",children:"work with existing Ethereum keys"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["You can also ",(0,c.jsx)(n.a,{href:"#generating-an-account-hash",children:"generate an account hash"})," from a public key with the Casper command-line client."]}),"\n",(0,c.jsx)(n.h2,{id:"creating-accounts-and-keys",children:"Creating Accounts and Keys"}),"\n",(0,c.jsxs)(n.p,{children:["When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," or a block explorer."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"SAVE your keys to a safe place, preferably offline."})}),"\n",(0,c.jsx)(n.h3,{id:"option-1-key-generation-using-the-casper-client",children:"Option 1: Generating keys using the Casper Client"}),"\n",(0,c.jsx)(n.p,{children:"This option describes how you can use the Casper command-line client to set up an account using either key type."}),"\n",(0,c.jsx)(n.h4,{id:"eddsa-keys",children:"EdDSA Keys"}),"\n",(0,c.jsx)(n.p,{children:"The command-line client generates EdDSA keys by default. Use the command below to create the account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"ed25519-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsx)(n.p,{children:"Here are some details about the files generated:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key.pem"})," is a ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key_hex"})," is a hexadecimal-encoded string of the public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"secret_key.pem"})," is the ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded secret key"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Ed25519"})," keys starts with 01 and is 66 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n"})}),"\n",(0,c.jsx)(n.h4,{id:"ecdsa-keys",children:"ECDSA Keys"}),"\n",(0,c.jsxs)(n.p,{children:["To create ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"secp256k1-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys starts with 02 and is 68 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"After generating keys for the account, you may add funds to the account's purse to finish the account creation process."})}),"\n",(0,c.jsx)(n.h3,{id:"option-2-key-generation-using-a-block-explorer",children:"Option 2: Generating keys using a block explorer"}),"\n",(0,c.jsx)(n.p,{children:"This option is available on networks that have a block explorer."}),"\n",(0,c.jsxs)(n.p,{children:["For instance, on the official Testnet, the ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"CSPR.live"})," block explorer is available, and the following instructions assume you are using it."]}),"\n",(0,c.jsxs)(n.p,{children:["Start by creating an account using the ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),", ",(0,c.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true",children:"Ledger"}),", or ",(0,c.jsx)(n.a,{href:"https://casper.tor.us/",children:"Torus Wallet"}),"."]}),"\n",(0,c.jsx)(n.admonition,{type:"caution",children:(0,c.jsxs)(n.p,{children:["The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/signer-user-start-here",children:"here"}),"."]})}),"\n",(0,c.jsx)(n.h2,{id:"funding-your-account",children:"Funding your Account"}),"\n",(0,c.jsxs)(n.p,{children:["Once you create your account, you can ",(0,c.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#fund-your-account",children:"fund the account's main purse"})," to finish the process of setting it up."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"Until you fund your account's main purse, it does not exist on the blockchain."})}),"\n",(0,c.jsx)(n.h2,{id:"working-with-existing-ethereum-keys",children:"Working with Existing Ethereum Keys"}),"\n",(0,c.jsx)(n.p,{children:"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,c.jsx)(n.code,{children:"Secp256k1"})," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper command-line client provides an example of how this works."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,c.jsx)(n.p,{children:"The following transaction sends 10 CSPR."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"tip",children:(0,c.jsxs)(n.p,{children:["The payment amount varies based on each transaction and network ",(0,c.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper command-line client requires the secret key in ",(0,c.jsx)(n.em,{children:"PEM"})," format to send a transaction from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,c.jsx)(n.em,{children:"PEM"})," format is needed."]}),"\n",(0,c.jsxs)(n.p,{children:["The following example is a JS script that generates a ",(0,c.jsx)(n.em,{children:"PEM"})," file, using a ",(0,c.jsx)(n.a,{href:"https://github.com/stacks-network/key-encoder-js",children:"key encoder"})," and Node.js. To install these components, do the following:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"sudo apt install nodejs\nnpm install key-encoder\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Then create the JS script ",(0,c.jsx)(n.em,{children:"convert-to-pem.js"})," using ",(0,c.jsx)(n.em,{children:"vi"})," or ",(0,c.jsx)(n.em,{children:"nano"}),", and include this content:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:'var KeyEncoder = require(\'key-encoder\'),\nkeyEncoder = new KeyEncoder.default(\'secp256k1\');\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n'})}),"\n",(0,c.jsx)(n.p,{children:"Then run the script using Node.js and name the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"node convert-to-pem.js > eth-secret.pem\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To view the secret key, use ",(0,c.jsx)(n.code,{children:"cat "}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat eth-secret.pem\n"})}),"\n",(0,c.jsx)(n.p,{children:"Below is the sample output showing the contents of the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n"})}),"\n",(0,c.jsx)(n.h3,{id:"option-3-generating-keys-using-openssl",children:"Option 3: Generating keys using OpenSSL"}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys without the Casper client using the ",(0,c.jsx)(n.a,{href:"https://www.openssl.org/",children:"openssl"})," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."]}),"\n",(0,c.jsxs)(n.h4,{id:"generating-the-secret_keypem-file",children:["Generating the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"openssl genpkey -algorithm ed25519 -out secret_key.pem\n"})}),"\n",(0,c.jsxs)(n.h4,{id:"generating-public-keys-from-the-secret_keypem-file",children:["Generating public keys from the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsxs)(n.p,{children:["For default Ed25519 keys, you can generate the ",(0,c.jsx)(n.code,{children:"public_key.pem"})," and ",(0,c.jsx)(n.code,{children:"public_key_hex"})," using these commands:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n'})}),"\n",(0,c.jsx)(n.h2,{id:"generating-an-account-hash",children:"Generating an Account Hash"}),"\n",(0,c.jsxs)(n.p,{children:["To generate the account hash for a public key, use the ",(0,c.jsx)(n.em,{children:"account-address"})," option of the Casper client. The argument for the ",(0,c.jsx)(n.em,{children:"public-key"})," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,c.jsx)(n.em,{children:"keygen"})," command: ",(0,c.jsx)(n.em,{children:"public_key_hex"})," or ",(0,c.jsx)(n.em,{children:"public_key.pem"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key \n"})}),"\n",(0,c.jsx)(n.h2,{id:"purse-uref",children:"Finding the Main Purse URef"}),"\n",(0,c.jsx)(n.p,{children:"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."}),"\n",(0,c.jsx)(n.h3,{id:"using-the-casper-cli-client",children:"Using the Casper CLI client"}),"\n",(0,c.jsxs)(n.p,{children:["With the ",(0,c.jsx)(n.code,{children:"casper-client"}),", use the ",(0,c.jsx)(n.code,{children:"get-account-info"})," subcommand."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info \\\n--node-address \\\n--public-key \n"})}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public-key"})," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,c.jsx)(n.code,{children:"keygen"}),' subcommand; "public_key_hex" or "public_key.pem"']}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Sample command and output"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Run the following help command for more details:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info --help\n"})}),"\n",(0,c.jsx)(n.h3,{id:"using-a-block-explorer",children:"Using a block explorer"}),"\n",(0,c.jsxs)(n.p,{children:["Using the block explorer for ",(0,c.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," or ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),", open the Account in question, and expand the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section. Look for the ",(0,c.jsx)(n.code,{children:"main_purse"})," field and find the corresponding URef. If you do not see data in the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section, then the account has not been funded yet."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Main purse",src:s(16399).A+"",width:"1576",height:"1494"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},16399:(e,n,s)=>{s.d(n,{A:()=>c});const c=s.p+"assets/images/main_purse_uref-96cffa61cd6ab63f2fb996efe8fc4197.png"},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var c=s(96540);const i={},t=c.createContext(i);function a(e){const n=c.useContext(t);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),c.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/01db17fe.4fe78b51.js b/assets/js/01db17fe.4fe78b51.js new file mode 100644 index 000000000..f12e7f778 --- /dev/null +++ b/assets/js/01db17fe.4fe78b51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9867],{69676:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(74848),t=n(28453);const o={},a="N",c={id:"concepts/glossary/N",title:"N",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/N.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/N",permalink:"/2.0.0/concepts/glossary/N",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"M",permalink:"/2.0.0/concepts/glossary/M"},next:{title:"O",permalink:"/2.0.0/concepts/glossary/O"}},i={},l=[{value:"NamedKeys",id:"named-keys",level:2},{value:"Node",id:"node",level:2},{value:"Node operator",id:"node-operator",level:2},{value:"Non-Fungible Token (NFT)",id:"non-fungible-token",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"n",children:"N"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),"\nare a collection of String-Key pairs used to easily identify some data on the network."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node",children:"Node"}),"\n",(0,r.jsx)(s.p,{children:"A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data."}),"\n",(0,r.jsx)(s.p,{children:"You will encounter different types of nodes on the network:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Bonded node"}),": a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Unbonded node"}),": a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization)."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node-operator",children:"Node operator"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O#operator",children:"operator"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"non-fungible-token",children:"Non-Fungible Token (NFT)"}),"\n",(0,r.jsx)(s.p,{children:"Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const t={},o=r.createContext(t);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/02627fb8.7d16ba66.js b/assets/js/02627fb8.7d16ba66.js new file mode 100644 index 000000000..7206a76a6 --- /dev/null +++ b/assets/js/02627fb8.7d16ba66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49900],{43934:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>h});var r=n(74848),s=n(28453);const c={title:"Factory Contracts"},a="Writing Contracts using the Factory Pattern",o={id:"developers/writing-onchain-code/factory-pattern",title:"Factory Contracts",description:"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/factory-pattern.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/factory-pattern",permalink:"/2.0.0/developers/writing-onchain-code/factory-pattern",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Factory Contracts"},sidebar:"developers",previous:{title:"Contract Hash vs. Package Hash",permalink:"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash"},next:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/2.0.0/developers/writing-onchain-code/best-practices"}},i={},h=[{value:"The Counter Factory Example",id:"the-counter-factory-example",level:2},{value:"Unit tests",id:"unit-tests",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-contracts-using-the-factory-pattern",children:"Writing Contracts using the Factory Pattern"})}),"\n",(0,r.jsxs)(t.p,{children:["This guide presents a ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"factory pattern"})," for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"The factory pattern is a widely recognized software design concept used in various programming contexts. DApp developers may use factory implementations to create smart contracts from a given source (or factory), such as a factory method or entry point. A factory pattern ensures that the contracts produced maintain a specified behavior, such as specific entry points and arguments. In general, factories produce other smart contracts according to a template."}),"\n",(0,r.jsxs)(t.p,{children:["Casper factories are created using the entry point type called ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", which marks an entry point as a factory method responsible for creating and installing contracts on the chain. An installer entry point will derive new Wasm based on the original session Wasm and create a new contract with different sets of entry points as required. In other words, these installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"})," are the contract factories. When referring to the factory contract on this page, we mean the contract containing the factory entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marks an entry point that exists in the bytecode but is not callable. Thus, regular entry points can be referenced from within installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),". In object-oriented terms, entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," act as virtual abstract methods and cannot be called from session code."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["This factory pattern poses a known drawback when using Wasm. All the smart contracts created with the factory pattern share the same Wasm installed on the chain. Thus, developers cannot modify the Wasm once installed and create modified contracts using the factory pattern. Developers must specify all the possible entry points in the parent contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marker."]})}),"\n",(0,r.jsx)(t.h2,{id:"the-counter-factory-example",children:"The Counter Factory Example"}),"\n",(0,r.jsxs)(t.p,{children:["This section dives into a ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"simple counter that uses factory methods"})," to describe how to implement the factory pattern on a Casper network. The ",(0,r.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"})," demonstrates the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Let's start by exploring the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L115",children:"session code"}),", where the contract entry points are defined."]}),"\n",(0,r.jsxs)(t.p,{children:["Two installer entry points are marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", meaning these entry points will produce new counter contracts once this Wasm is installed in global state. They are also marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," so that they can be called from the session code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_DEFAULT_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\n"})}),"\n",(0,r.jsxs)(t.p,{children:["These two installers show how to declare multiple factory entry points and use them to initialize the Wasm they produce with different values. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L61C19-L61C35",children:"line 61"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point creates a counter contract with a given name and initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n let initial_value: U512 = runtime::get_named_arg(ARG_INITIAL_VALUE);\n installer(name, initial_value);\n}\n'})}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L68",children:"line 68"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," entry point creates a counter contract with a given name and a zero initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory_default() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n installer(name, U512::zero());\n}\n'})}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsx)(t.p,{children:"The factory pattern can produce contracts with different entry points. Suppose the session code defines entry points A, B, C, and D as templates. One installer factory entry point could use entry points A and B to create a contract, and the other installer entry point might use entry points C and D. Such support at the API level enables the implementation of more complex use cases."})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L73",children:"installer function"})," creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's ",(0,r.jsx)(t.code,{children:"decrement"})," and ",(0,r.jsx)(t.code,{children:"increment"})," functionality. These entry points are defined just like in any other smart contract, with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"}),", and they are callable for all the counters created. To learn how to call the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," functions, see the ",(0,r.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"}),", which is the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Sample installer code for a counter factory"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"fn installer(name: String, initial_value: U512) {\n let named_keys = {\n let new_uref = storage::new_uref(initial_value);\n let mut named_keys = NamedKeys::new();\n named_keys.insert(CURRENT_VALUE_KEY.to_string(), new_uref.into());\n named_keys\n };\n\n let entry_points = {\n let mut entry_points = EntryPoints::new();\n let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n let entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n\n entry_points\n };\n\n let (contract_hash, contract_version) = storage::new_contract(\n entry_points,\n Some(named_keys),\n Some(PACKAGE_HASH_KEY_NAME.to_string()),\n Some(ACCESS_KEY_NAME.to_string()),\n );\n\n runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\n runtime::put_key(&name, contract_hash.into());\n}\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["It is important to note that the installer logic ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L110-L111",children:"saves the newly created contract version and contract hash"})," under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#comparing-session-and-contract",children:"comparison between session and contract context"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\nruntime::put_key(&name, contract_hash.into());\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For example, if you install the factory counter contract, you will see only one named key for this contract in your account, with the two installer entry points ",(0,r.jsx)(t.code,{children:"contract_factory"})," and ",(0,r.jsx)(t.code,{children:"contract_factory_default"}),". See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L155C1-L163",children:"lines 155-163"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["If you call the installer three times to create 3 different counters, you will see 3 named keys for each counter in the factory contract's named keys. The counter contracts produced will have the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["As explained above, developers must define all the possible non-installer entry points in the factory contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"})," markers. See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L135C9-L149C11",children:"lines 135-139"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\n"})}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsxs)(t.p,{children:["Suppose developers forget to declare an entry point in the outermost session logic (the ",(0,r.jsx)(t.code,{children:"call"})," function) and mark it with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"}),"; that Wasm export will be removed when the factory contract is installed in global state. Creating the entry point in the installer logic is not sufficient."]})}),"\n",(0,r.jsx)(t.h3,{id:"unit-tests",children:"Unit tests"}),"\n",(0,r.jsxs)(t.p,{children:["Developers can test contracts that follow the factory pattern using the Casper testing framework described under ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"}),". The testing process is the same, but this section highlights a particular test called ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L116C4-L116C42",children:"should_install_and_use_factory_pattern"})," found in the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/execution_engine_testing/tests/src/test/counter_factory.rs",children:"unit test suite"})," of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior."]}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L120",children:"line 120"}),", the test starts building a request to call the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point with counter name ",(0,r.jsx)(t.code,{children:"new-counter-1"})," and value 1. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L134",children:"line 134"}),", the test calls another factory entry point called ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," with counter name ",(0,r.jsx)(t.code,{children:"new-counter-2"}),". The default counter value is 0."]}),"\n",(0,r.jsx)(t.p,{children:"Once the requests are processed, the test checks the contract hashes of the contracts created:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The factory contract on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L146",children:"line 146"})]}),"\n",(0,r.jsxs)(t.li,{children:["The first counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L157",children:"line 157"})]}),"\n",(0,r.jsxs)(t.li,{children:["The second counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L168",children:"line 168"})]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The test proceeds to get the contract Wasm for each counter produced and test the Wasm exports, which are the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points in each counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"setup"})," function on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L209",children:"line 209"})," is a helper function for installing the factory contract on the chain and getting the contract factory hash."]}),"\n",(0,r.jsx)(t.p,{children:"The other tests in this file are also interesting:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L25",children:"should_not_call_undefined_entrypoints_on_factory"})," - This test verifies that entry points marked as a template cannot be called directly from the factory contract"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L87C4-L87C54",children:"contract_factory_wasm_should_have_expected_exports"})," - This test checks the entry points declared in the contract factory"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/028247bf.b7389543.js b/assets/js/028247bf.b7389543.js new file mode 100644 index 000000000..470f53155 --- /dev/null +++ b/assets/js/028247bf.b7389543.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53540],{71648:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var r=o(74848),n=o(28453);const t={},a="P",c={id:"concepts/glossary/P",title:"P",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/P.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/P",permalink:"/1.5.X/concepts/glossary/P",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"O",permalink:"/1.5.X/concepts/glossary/O"},next:{title:"Q",permalink:"/1.5.X/concepts/glossary/Q"}},i={},l=[{value:"Partial synchrony",id:"partial-synchrony",level:2},{value:"Participate in consensus",id:"participate-in-consensus",level:2},{value:"Payment code",id:"payment-code",level:2},{value:"Peer node",id:"peer-node",level:2},{value:"Permissionless",id:"permissionless",level:2},{value:"Primary token",id:"primary-token",level:2},{value:"Private key",id:"private-key",level:2},{value:"Proof-of-Stake",id:"proof-of-stake",level:2},{value:"Proof-of-Work",id:"proof-of-work",level:2},{value:"Proof-of-Stake contract",id:"proof-of-stake-contract",level:2},{value:"Proposer",id:"proposer",level:2},{value:"Proto block",id:"proto-block",level:2},{value:"Purse",id:"purse",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"p",children:"P"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"partial-synchrony",children:"Partial synchrony"}),"\n",(0,r.jsxs)(s.p,{children:["Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"participate-in-consensus",children:"Participate in consensus"}),"\n",(0,r.jsxs)(s.p,{children:["The process of following the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#consensus",children:"consensus"})," algorithm. The primary participants are ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validators"}),", bonded with their stake and part of the validator set for that particular era. ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D#delegator",children:"Delegators"})," participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network."]}),"\n",(0,r.jsx)(s.h2,{id:"payment-code",children:"Payment code"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.em,{children:"payment code"})," is the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W#webassembly",children:"Wasm"})," program that pays the transaction execution fee."]}),"\n",(0,r.jsx)(s.h2,{id:"peer-node",children:"Peer node"}),"\n",(0,r.jsx)(s.p,{children:"A node on a peer-to-peer (P2P) network."}),"\n",(0,r.jsx)(s.h2,{id:"permissionless",children:"Permissionless"}),"\n",(0,r.jsx)(s.p,{children:"A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants."}),"\n",(0,r.jsx)(s.h2,{id:"primary-token",children:"Primary token"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"private-key",children:"Private key"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S#secret-key",children:"secret key"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake",children:"Proof-of-Stake"}),"\n",(0,r.jsx)(s.p,{children:"Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-work",children:"Proof-of-Work"}),"\n",(0,r.jsx)(s.p,{children:"A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake-contract",children:"Proof-of-Stake contract"}),"\n",(0,r.jsx)(s.p,{children:"The Proof-of-Stake (PoS) contract holds on to transaction fees for the time while the state transition is happening (contracts are being executed). The PoS contract remits the transaction fees to the block proposer."}),"\n",(0,r.jsx)(s.h2,{id:"proposer",children:"Proposer"}),"\n",(0,r.jsx)(s.p,{children:"The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proto-block",children:"Proto block"}),"\n",(0,r.jsxs)(s.p,{children:["The block proposed by the leader, which the consensus processes (in ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H#highway",children:"highway"}),"). Only after consensus is complete, the proto block is executed, and the global state is updated."]}),"\n",(0,r.jsx)(s.p,{children:"A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era."}),"\n",(0,r.jsx)(s.h2,{id:"purse",children:"Purse"}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.code,{children:"purse"})," is a unique type of ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U#uref",children:"URef"})," representing a token balance. An account's ",(0,r.jsx)(s.em,{children:"main purse"})," represents the balance of CSPR tokens (in ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M#motes",children:"motes"}),") the account has access to on a Casper network. An account may have more than one purse in some instances. More information on purses can be found ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/design/casper-design#urefs-and-purses",children:"here"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,o)=>{o.d(s,{R:()=>a,x:()=>c});var r=o(96540);const n={},t=r.createContext(n);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/028247bf.e22beb61.js b/assets/js/028247bf.e22beb61.js deleted file mode 100644 index 23ae29976..000000000 --- a/assets/js/028247bf.e22beb61.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3540],{71648:(e,s,o)=>{o.r(s),o.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var r=o(74848),n=o(28453);const t={},a="P",c={id:"concepts/glossary/P",title:"P",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/P.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/P",permalink:"/concepts/glossary/P",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"O",permalink:"/concepts/glossary/O"},next:{title:"Q",permalink:"/concepts/glossary/Q"}},i={},l=[{value:"Partial synchrony",id:"partial-synchrony",level:2},{value:"Participate in consensus",id:"participate-in-consensus",level:2},{value:"Payment code",id:"payment-code",level:2},{value:"Peer node",id:"peer-node",level:2},{value:"Permissionless",id:"permissionless",level:2},{value:"Primary token",id:"primary-token",level:2},{value:"Private key",id:"private-key",level:2},{value:"Proof-of-Stake",id:"proof-of-stake",level:2},{value:"Proof-of-Work",id:"proof-of-work",level:2},{value:"Proof-of-Stake contract",id:"proof-of-stake-contract",level:2},{value:"Proposer",id:"proposer",level:2},{value:"Proto block",id:"proto-block",level:2},{value:"Purse",id:"purse",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"p",children:"P"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"partial-synchrony",children:"Partial synchrony"}),"\n",(0,r.jsxs)(s.p,{children:["Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"participate-in-consensus",children:"Participate in consensus"}),"\n",(0,r.jsxs)(s.p,{children:["The process of following the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#consensus",children:"consensus"})," algorithm. The primary participants are ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V#validator",children:"validators"}),", bonded with their stake and part of the validator set for that particular era. ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D#delegator",children:"Delegators"})," participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network."]}),"\n",(0,r.jsx)(s.h2,{id:"payment-code",children:"Payment code"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.em,{children:"payment code"})," is the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," program that pays the transaction execution fee."]}),"\n",(0,r.jsx)(s.h2,{id:"peer-node",children:"Peer node"}),"\n",(0,r.jsx)(s.p,{children:"A node on a peer-to-peer (P2P) network."}),"\n",(0,r.jsx)(s.h2,{id:"permissionless",children:"Permissionless"}),"\n",(0,r.jsx)(s.p,{children:"A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants."}),"\n",(0,r.jsx)(s.h2,{id:"primary-token",children:"Primary token"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"private-key",children:"Private key"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S#secret-key",children:"secret key"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake",children:"Proof-of-Stake"}),"\n",(0,r.jsx)(s.p,{children:"Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-work",children:"Proof-of-Work"}),"\n",(0,r.jsx)(s.p,{children:"A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake-contract",children:"Proof-of-Stake contract"}),"\n",(0,r.jsx)(s.p,{children:"The Proof-of-Stake (PoS) contract holds on to transaction fees for the time while the state transition is happening (contracts are being executed). The PoS contract remits the transaction fees to the block proposer."}),"\n",(0,r.jsx)(s.h2,{id:"proposer",children:"Proposer"}),"\n",(0,r.jsx)(s.p,{children:"The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proto-block",children:"Proto block"}),"\n",(0,r.jsxs)(s.p,{children:["The block proposed by the leader, which the consensus processes (in ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H#highway",children:"highway"}),"). Only after consensus is complete, the proto block is executed, and the global state is updated."]}),"\n",(0,r.jsx)(s.p,{children:"A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era."}),"\n",(0,r.jsx)(s.h2,{id:"purse",children:"Purse"}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.code,{children:"purse"})," is a unique type of ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U#uref",children:"URef"})," representing a token balance. An account's ",(0,r.jsx)(s.em,{children:"main purse"})," represents the balance of CSPR tokens (in ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M#motes",children:"motes"}),") the account has access to on a Casper network. An account may have more than one purse in some instances. More information on purses can be found ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design#urefs-and-purses",children:"here"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,o)=>{o.d(s,{R:()=>a,x:()=>c});var r=o(96540);const n={},t=r.createContext(n);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03aa8e23.0a426846.js b/assets/js/03aa8e23.0a426846.js deleted file mode 100644 index 0ae57c6da..000000000 --- a/assets/js/03aa8e23.0a426846.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3586],{94073:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>h});var i=n(74848),s=n(28453);const o={title:"Highway Consensus"},a="The Highway Consensus Protocol",r={id:"concepts/design/highway",title:"Highway Consensus",description:"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.",source:"@site/docs/concepts/design/highway.md",sourceDirName:"concepts/design",slug:"/concepts/design/highway",permalink:"/next/concepts/design/highway",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{title:"Highway Consensus"},sidebar:"concepts",previous:{title:"Zug Consensus",permalink:"/next/concepts/design/zug"},next:{title:"Rewards Design",permalink:"/next/concepts/design/rewards"}},c={},h=[{value:"Unit Broadcasting",id:"unit-broadcasting",level:2},{value:"Block Finalization",id:"block-finalization",level:2},{value:"Important Links",id:"important-links",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"the-highway-consensus-protocol",children:"The Highway Consensus Protocol"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"})," consensus protocol was used on the Casper Mainnet until the ",(0,i.jsx)(t.a,{href:"/next/concepts/design/zug",children:"Zug"})," consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail ",(0,i.jsx)(t.a,{href:"/next/concepts/design/consensus",children:"here"}),". This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs."]}),"\n",(0,i.jsx)(t.h2,{id:"unit-broadcasting",children:"Unit Broadcasting"}),"\n",(0,i.jsx)(t.p,{children:"In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Citations of other units (at most one per node), subject to validity conditions"}),"\n",(0,i.jsx)(t.li,{children:"An optional proposed list of transactions to be included in a block. Note that the list can be empty"}),"\n",(0,i.jsx)(t.li,{children:"The unit's creator and its digital signature"}),"\n",(0,i.jsx)(t.li,{children:"Additional metadata, including a timestamp, sequence number, round length, etc."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:'An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn\'t clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.'}),"\n",(0,i.jsx)(t.p,{children:"Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"DAG",src:n(80120).A+"",width:"787",height:"479"})}),"\n",(0,i.jsx)(t.p,{children:"Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator."}),"\n",(0,i.jsx)(t.p,{children:"The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era."}),"\n",(0,i.jsx)(t.h2,{id:"block-finalization",children:"Block Finalization"}),"\n",(0,i.jsxs)(t.p,{children:["In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum ",(0,i.jsx)(t.em,{children:"q"}),", a percentage of the participating validator weight, and a level ",(0,i.jsx)(t.em,{children:"k"}),". Level ",(0,i.jsx)(t.em,{children:"k"})," represents the depth in the graph. For a given fault tolerance threshold ",(0,i.jsx)(t.em,{children:"t"})," (FTT), finality is defined as:"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Finality Equation",src:n(8438).A+"",width:"474",height:"62"})}),"\n",(0,i.jsxs)(t.p,{children:["If ",(0,i.jsx)(t.em,{children:"q"})," is close to ",(0,i.jsx)(t.em,{children:"n"}),", meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT)."]}),"\n",(0,i.jsxs)(t.p,{children:["The existence of such a summit means that a weight of more than ",(0,i.jsx)(t.em,{children:"t"})," would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block."]}),"\n",(0,i.jsx)(t.p,{children:"In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network."}),"\n",(0,i.jsx)(t.h2,{id:"important-links",children:"Important Links"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway Whitepaper"})," - Describes the protocol, and the liveness and safety proofs in detail"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"/next/concepts/design/zug",children:"Zug Consensus"})," - The protocol currently used in Mainnet and Testnet"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},80120:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-dag-cd0520491022e0a3dfdab640eadc36eb.png"},8438:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-finality-3085c2c54335e90870c04d973492a99d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const s={},o=i.createContext(s);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03aa8e23.2c61f65f.js b/assets/js/03aa8e23.2c61f65f.js new file mode 100644 index 000000000..cc09f9827 --- /dev/null +++ b/assets/js/03aa8e23.2c61f65f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93586],{94073:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>h});var i=n(74848),s=n(28453);const o={title:"Highway Consensus"},a="The Highway Consensus Protocol",r={id:"concepts/design/highway",title:"Highway Consensus",description:"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.",source:"@site/docs/concepts/design/highway.md",sourceDirName:"concepts/design",slug:"/concepts/design/highway",permalink:"/concepts/design/highway",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726242038e3,frontMatter:{title:"Highway Consensus"},sidebar:"concepts",previous:{title:"Zug Consensus",permalink:"/concepts/design/zug"},next:{title:"Rewards Design",permalink:"/concepts/design/rewards"}},c={},h=[{value:"Unit Broadcasting",id:"unit-broadcasting",level:2},{value:"Block Finalization",id:"block-finalization",level:2},{value:"Important Links",id:"important-links",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"the-highway-consensus-protocol",children:"The Highway Consensus Protocol"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159",children:"Highway"})," consensus protocol was used on the Casper Mainnet until the ",(0,i.jsx)(t.a,{href:"/concepts/design/zug",children:"Zug"})," consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail ",(0,i.jsx)(t.a,{href:"/concepts/design/consensus",children:"here"}),". This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs."]}),"\n",(0,i.jsx)(t.h2,{id:"unit-broadcasting",children:"Unit Broadcasting"}),"\n",(0,i.jsx)(t.p,{children:"In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Citations of other units (at most one per node), subject to validity conditions"}),"\n",(0,i.jsx)(t.li,{children:"An optional proposed list of transactions to be included in a block. Note that the list can be empty"}),"\n",(0,i.jsx)(t.li,{children:"The unit's creator and its digital signature"}),"\n",(0,i.jsx)(t.li,{children:"Additional metadata, including a timestamp, sequence number, round length, etc."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:'An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn\'t clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.'}),"\n",(0,i.jsx)(t.p,{children:"Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"DAG",src:n(29138).A+"",width:"787",height:"479"})}),"\n",(0,i.jsx)(t.p,{children:"Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator."}),"\n",(0,i.jsx)(t.p,{children:"The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era."}),"\n",(0,i.jsx)(t.h2,{id:"block-finalization",children:"Block Finalization"}),"\n",(0,i.jsxs)(t.p,{children:["In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum ",(0,i.jsx)(t.em,{children:"q"}),", a percentage of the participating validator weight, and a level ",(0,i.jsx)(t.em,{children:"k"}),". Level ",(0,i.jsx)(t.em,{children:"k"})," represents the depth in the graph. For a given fault tolerance threshold ",(0,i.jsx)(t.em,{children:"t"})," (FTT), finality is defined as:"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Finality Equation",src:n(6840).A+"",width:"474",height:"62"})}),"\n",(0,i.jsxs)(t.p,{children:["If ",(0,i.jsx)(t.em,{children:"q"})," is close to ",(0,i.jsx)(t.em,{children:"n"}),", meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT)."]}),"\n",(0,i.jsxs)(t.p,{children:["The existence of such a summit means that a weight of more than ",(0,i.jsx)(t.em,{children:"t"})," would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block."]}),"\n",(0,i.jsx)(t.p,{children:"In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network."}),"\n",(0,i.jsx)(t.h2,{id:"important-links",children:"Important Links"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway Whitepaper"})," - Describes the protocol, and the liveness and safety proofs in detail"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"/concepts/design/zug",children:"Zug Consensus"})," - The protocol currently used in Mainnet and Testnet"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},29138:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-dag-cd0520491022e0a3dfdab640eadc36eb.png"},6840:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-finality-3085c2c54335e90870c04d973492a99d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const s={},o=i.createContext(s);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03acd2fb.9a8b2e6c.js b/assets/js/03acd2fb.9a8b2e6c.js new file mode 100644 index 000000000..677bbada5 --- /dev/null +++ b/assets/js/03acd2fb.9a8b2e6c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79378],{94903:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={title:"Installation"},i="Installing a Node",a={id:"operators/setup/install-node",title:"Installation",description:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.",source:"@site/docs/operators/setup/install-node.md",sourceDirName:"operators/setup",slug:"/operators/setup/install-node",permalink:"/operators/setup/install-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Installation"},sidebar:"operators",previous:{title:"Endpoints",permalink:"/operators/setup/node-endpoints"},next:{title:"Fast Sync",permalink:"/operators/setup/fast-sync"}},l={},c=[{value:"Network Requirements",id:"network-requirements",level:2},{value:"Operating System Requirements",id:"operating-system-requirements",level:2},{value:"Using Ubuntu 22.04",id:"using-ubuntu-2204",level:3},{value:"Required Number of Open Files",id:"required-number-of-open-files",level:2},{value:"Required Clean Up",id:"required-clean-up",level:2},{value:"Required Packages",id:"required-packages",level:2},{value:"Required Tools",id:"required-tools",level:2},{value:"Enable Bash Auto-Completion for casper-client (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load trusted_hash in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-a-node",children:"Installing a Node"})}),"\n",(0,t.jsx)(n.p,{children:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."}),"\n",(0,t.jsx)(n.h2,{id:"network-requirements",children:"Network Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The following ports are used by the node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"35000 (required to be externally visible)"}),"\n",(0,t.jsx)(n.li,{children:"7777 RPC endpoint for interaction with JSON-RPC API"}),"\n",(0,t.jsx)(n.li,{children:"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"}),"\n",(0,t.jsx)(n.li,{children:"9999 SSE endpoint for event stream"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Of these ",(0,t.jsx)(n.code,{children:"35000"})," is the only port required to be open for your node to function, however, opening ",(0,t.jsx)(n.code,{children:"8888"})," will allow others to know general network health. For more details, see the additional information on ",(0,t.jsx)(n.a,{href:"/operators/setup/node-endpoints",children:"Node Endpoints"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"operating-system-requirements",children:"Operating System Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The recommended OS version is Ubuntu 20.04."}),"\n",(0,t.jsx)(n.h3,{id:"using-ubuntu-2204",children:"Using Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"}),"\n",(0,t.jsx)(n.p,{children:"If you try to install packages, you will receive:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This message is due to the default ",(0,t.jsx)(n.code,{children:"openssl"})," moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-number-of-open-files",children:"Required Number of Open Files"}),"\n",(0,t.jsxs)(n.p,{children:["Before beginning, ",(0,t.jsx)(n.a,{href:"/operators/setup/open-files",children:"update the maximum open files limit"})," for your system. Specifically, update the node's ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file as described ",(0,t.jsx)(n.a,{href:"/operators/setup/open-files#updating-limits-conf",children:"here"}),", to ensure proper node operation."]}),"\n",(0,t.jsx)(n.h2,{id:"required-clean-up",children:"Required Clean Up"}),"\n",(0,t.jsxs)(n.p,{children:["If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,t.jsx)(n.code,{children:"apt remove"})," may give errors, but this is not a problem."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-packages",children:"Required Packages"}),"\n",(0,t.jsx)(n.p,{children:"The following commands will set up the Casper Labs repository for packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n'})}),"\n",(0,t.jsx)(n.h2,{id:"required-tools",children:"Required Tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install -y casper-client casper-node-launcher jq\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"enable-bash-auto-completion-for-casper-client-optional",children:["Enable Bash Auto-Completion for ",(0,t.jsx)(n.code,{children:"casper-client"})," (Optional)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo casper-client generate-completion\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It defaults to ",(0,t.jsx)(n.code,{children:"bash"})," but can be changed with the ",(0,t.jsx)(n.code,{children:"--shell"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"--shell The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n"})}),"\n",(0,t.jsx)(n.p,{children:"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source /usr/share/bash-completion/completions/casper-client\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now you can use ",(0,t.jsx)(n.code,{children:"casper-client"})," and press the ",(0,t.jsx)(n.code,{children:"tab"})," key to get auto completion for your commands."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-all-protocols",children:"Installing All Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Mainnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Testnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,t.jsx)(n.h2,{id:"validator-keys",children:"Validator Keys"}),"\n",(0,t.jsx)(n.p,{children:"If you do not have keys yet, you can create them using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-a-trusted-hash",children:"Getting a Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["In the past, we have used a lower ",(0,t.jsx)(n.code,{children:"trusted_hash"}),". Connecting at the tip, we now use as high of a ",(0,t.jsx)(n.code,{children:"trusted_hash"})," as possible. Find out more about ",(0,t.jsx)(n.a,{href:"/operators/setup/fast-sync",children:"Fast Sync"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"node-address",children:"Node Address"}),"\n",(0,t.jsx)(n.p,{children:"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"}),"\n",(0,t.jsxs)(n.p,{children:["You can find active peers at ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"https://cspr.live/tools/peers"})," or use the following Casper Labs public nodes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Testnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io",children:"https://rpc.testnet.casperlabs.io"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Mainnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io",children:"https://rpc.mainnet.casperlabs.io"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,t.jsxs)(n.p,{children:["Protocol version should be set to the largest available protocol version you see in ",(0,t.jsx)(n.code,{children:"ls /etc/casper"}),". As of writing this, it was 1_5_2:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"PROTOCOL=1_5_2\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"load-trusted_hash-in-configtoml-of-the-protocol-version",children:["Load ",(0,t.jsx)(n.code,{children:"trusted_hash"})," in Config.toml of the Protocol Version"]}),"\n",(0,t.jsxs)(n.p,{children:["The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,t.jsx)(n.code,{children:"trusted_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"syncing-to-genesis",children:"Syncing to Genesis"}),"\n",(0,t.jsxs)(n.p,{children:["In the latest protocol version's ",(0,t.jsx)(n.em,{children:"Config.toml"}),", you will find the option ",(0,t.jsx)(n.code,{children:"sync_to_genesis"}),". By default, this value will be set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sync_to_genesis = false\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."}),"\n",(0,t.jsx)(n.h2,{id:"starting-the-node",children:"Starting the Node"}),"\n",(0,t.jsx)(n.p,{children:"Start the node using the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n"})}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-synchronization-process",children:"Monitoring the Synchronization Process"}),"\n",(0,t.jsx)(n.p,{children:"The following command will display the node synchronization details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"/etc/casper/node_util.py watch\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When you first run the watch command, you may see the message ",(0,t.jsx)(n.code,{children:"RPC: Not Ready"}),". Once the node is synchronized, the status will change to ",(0,t.jsx)(n.code,{children:"RPC: Ready"})," and a similar output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,t.jsx)(n.code,{children:"sync_to_genesis"})," as ",(0,t.jsx)(n.code,{children:"true"}),", it will begin syncing back history at this time."]}),"\n",(0,t.jsx)(n.p,{children:"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the node is not showing active (running) status, it is either stopped or in the process of restarting."}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-running-node",children:"Monitoring the Running Node"}),"\n",(0,t.jsx)(n.p,{children:"The community has created a few tools to monitor your node once it is running, such as:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Status.py: ",(0,t.jsx)(n.a,{href:"https://github.com/RapidMark/casper-tools",children:"https://github.com/RapidMark/casper-tools"})]}),"\n",(0,t.jsxs)(n.li,{children:["Grafana: ",(0,t.jsx)(n.a,{href:"https://github.com/matsuro-hadouken/casper-tools",children:"https://github.com/matsuro-hadouken/casper-tools"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"a-note-on-speculative-execution",children:"A Note on Speculative Execution"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"speculative_exec_server"})," defaults to off and can be enabled in your ",(0,t.jsx)(n.em,{children:"Config.toml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"should not"})})," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03acd2fb.d5a0a15f.js b/assets/js/03acd2fb.d5a0a15f.js deleted file mode 100644 index b52e2aa36..000000000 --- a/assets/js/03acd2fb.d5a0a15f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9378],{94903:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={title:"Installation"},i="Installing a Node",a={id:"operators/setup/install-node",title:"Installation",description:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.",source:"@site/docs/operators/setup/install-node.md",sourceDirName:"operators/setup",slug:"/operators/setup/install-node",permalink:"/next/operators/setup/install-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Installation"},sidebar:"operators",previous:{title:"Endpoints",permalink:"/next/operators/setup/node-endpoints"},next:{title:"Fast Sync",permalink:"/next/operators/setup/fast-sync"}},l={},c=[{value:"Network Requirements",id:"network-requirements",level:2},{value:"Operating System Requirements",id:"operating-system-requirements",level:2},{value:"Using Ubuntu 22.04",id:"using-ubuntu-2204",level:3},{value:"Required Number of Open Files",id:"required-number-of-open-files",level:2},{value:"Required Clean Up",id:"required-clean-up",level:2},{value:"Required Packages",id:"required-packages",level:2},{value:"Required Tools",id:"required-tools",level:2},{value:"Enable Bash Auto-Completion for casper-client (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load trusted_hash in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-a-node",children:"Installing a Node"})}),"\n",(0,t.jsx)(n.p,{children:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."}),"\n",(0,t.jsx)(n.h2,{id:"network-requirements",children:"Network Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The following ports are used by the node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"35000 (required to be externally visible)"}),"\n",(0,t.jsx)(n.li,{children:"7777 RPC endpoint for interaction with JSON-RPC API"}),"\n",(0,t.jsx)(n.li,{children:"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"}),"\n",(0,t.jsx)(n.li,{children:"9999 SSE endpoint for event stream"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Of these ",(0,t.jsx)(n.code,{children:"35000"})," is the only port required to be open for your node to function, however, opening ",(0,t.jsx)(n.code,{children:"8888"})," will allow others to know general network health. For more details, see the additional information on ",(0,t.jsx)(n.a,{href:"/next/operators/setup/node-endpoints",children:"Node Endpoints"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"operating-system-requirements",children:"Operating System Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The recommended OS version is Ubuntu 20.04."}),"\n",(0,t.jsx)(n.h3,{id:"using-ubuntu-2204",children:"Using Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"}),"\n",(0,t.jsx)(n.p,{children:"If you try to install packages, you will receive:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This message is due to the default ",(0,t.jsx)(n.code,{children:"openssl"})," moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-number-of-open-files",children:"Required Number of Open Files"}),"\n",(0,t.jsxs)(n.p,{children:["Before beginning, ",(0,t.jsx)(n.a,{href:"/next/operators/setup/open-files",children:"update the maximum open files limit"})," for your system. Specifically, update the node's ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file as described ",(0,t.jsx)(n.a,{href:"/next/operators/setup/open-files#updating-limits-conf",children:"here"}),", to ensure proper node operation."]}),"\n",(0,t.jsx)(n.h2,{id:"required-clean-up",children:"Required Clean Up"}),"\n",(0,t.jsxs)(n.p,{children:["If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,t.jsx)(n.code,{children:"apt remove"})," may give errors, but this is not a problem."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-packages",children:"Required Packages"}),"\n",(0,t.jsx)(n.p,{children:"The following commands will set up the Casper Labs repository for packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n'})}),"\n",(0,t.jsx)(n.h2,{id:"required-tools",children:"Required Tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install -y casper-client casper-node-launcher jq\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"enable-bash-auto-completion-for-casper-client-optional",children:["Enable Bash Auto-Completion for ",(0,t.jsx)(n.code,{children:"casper-client"})," (Optional)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo casper-client generate-completion\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It defaults to ",(0,t.jsx)(n.code,{children:"bash"})," but can be changed with the ",(0,t.jsx)(n.code,{children:"--shell"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"--shell The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n"})}),"\n",(0,t.jsx)(n.p,{children:"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source /usr/share/bash-completion/completions/casper-client\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now you can use ",(0,t.jsx)(n.code,{children:"casper-client"})," and press the ",(0,t.jsx)(n.code,{children:"tab"})," key to get auto completion for your commands."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-all-protocols",children:"Installing All Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Mainnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Testnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,t.jsx)(n.h2,{id:"validator-keys",children:"Validator Keys"}),"\n",(0,t.jsx)(n.p,{children:"If you do not have keys yet, you can create them using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-a-trusted-hash",children:"Getting a Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["In the past, we have used a lower ",(0,t.jsx)(n.code,{children:"trusted_hash"}),". Connecting at the tip, we now use as high of a ",(0,t.jsx)(n.code,{children:"trusted_hash"})," as possible. Find out more about ",(0,t.jsx)(n.a,{href:"/next/operators/setup/fast-sync",children:"Fast Sync"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"node-address",children:"Node Address"}),"\n",(0,t.jsx)(n.p,{children:"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"}),"\n",(0,t.jsxs)(n.p,{children:["You can find active peers at ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"https://cspr.live/tools/peers"})," or use the following Casper Labs public nodes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Testnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io",children:"https://rpc.testnet.casperlabs.io"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Mainnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io",children:"https://rpc.mainnet.casperlabs.io"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,t.jsxs)(n.p,{children:["Protocol version should be set to the largest available protocol version you see in ",(0,t.jsx)(n.code,{children:"ls /etc/casper"}),". As of writing this, it was 1_5_2:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"PROTOCOL=1_5_2\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"load-trusted_hash-in-configtoml-of-the-protocol-version",children:["Load ",(0,t.jsx)(n.code,{children:"trusted_hash"})," in Config.toml of the Protocol Version"]}),"\n",(0,t.jsxs)(n.p,{children:["The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,t.jsx)(n.code,{children:"trusted_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"syncing-to-genesis",children:"Syncing to Genesis"}),"\n",(0,t.jsxs)(n.p,{children:["In the latest protocol version's ",(0,t.jsx)(n.em,{children:"Config.toml"}),", you will find the option ",(0,t.jsx)(n.code,{children:"sync_to_genesis"}),". By default, this value will be set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sync_to_genesis = false\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."}),"\n",(0,t.jsx)(n.h2,{id:"starting-the-node",children:"Starting the Node"}),"\n",(0,t.jsx)(n.p,{children:"Start the node using the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n"})}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-synchronization-process",children:"Monitoring the Synchronization Process"}),"\n",(0,t.jsx)(n.p,{children:"The following command will display the node synchronization details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"/etc/casper/node_util.py watch\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When you first run the watch command, you may see the message ",(0,t.jsx)(n.code,{children:"RPC: Not Ready"}),". Once the node is synchronized, the status will change to ",(0,t.jsx)(n.code,{children:"RPC: Ready"})," and a similar output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,t.jsx)(n.code,{children:"sync_to_genesis"})," as ",(0,t.jsx)(n.code,{children:"true"}),", it will begin syncing back history at this time."]}),"\n",(0,t.jsx)(n.p,{children:"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the node is not showing active (running) status, it is either stopped or in the process of restarting."}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-running-node",children:"Monitoring the Running Node"}),"\n",(0,t.jsx)(n.p,{children:"The community has created a few tools to monitor your node once it is running, such as:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Status.py: ",(0,t.jsx)(n.a,{href:"https://github.com/RapidMark/casper-tools",children:"https://github.com/RapidMark/casper-tools"})]}),"\n",(0,t.jsxs)(n.li,{children:["Grafana: ",(0,t.jsx)(n.a,{href:"https://github.com/matsuro-hadouken/casper-tools",children:"https://github.com/matsuro-hadouken/casper-tools"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"a-note-on-speculative-execution",children:"A Note on Speculative Execution"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"speculative_exec_server"})," defaults to off and can be enabled in your ",(0,t.jsx)(n.em,{children:"Config.toml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"should not"})})," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03c6d9c7.4f0c8d42.js b/assets/js/03c6d9c7.4f0c8d42.js new file mode 100644 index 000000000..65c2fc1d1 --- /dev/null +++ b/assets/js/03c6d9c7.4f0c8d42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34684],{33603:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var s=a(74848),t=a(28453);const r={},c="Proof-of-Stake JSON-RPC Methods {#proof-of-stake}",d={id:"developers/json-rpc/json-rpc-pos",title:"Proof-of-Stake JSON-RPC Methods",description:"proof-of-stake}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-pos.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-pos",permalink:"/1.5.X/developers/json-rpc/json-rpc-pos",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Informational JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-informational"},next:{title:"Types",permalink:"/1.5.X/developers/json-rpc/types_chain"}},i={},o=[{value:"state_get_auction_info",id:"state-get-auction-info",level:2},{value:"state_get_auction_info_result",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info-get-validator-changes",level:2},{value:"info_get_validator_changes_result",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"chain_get_era_info_by_switch_block_result",id:"chain_get_era_info_by_switch_block_result",level:3}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"proof-of-stake",children:"Proof-of-Stake JSON-RPC Methods"})}),"\n",(0,s.jsx)(n.p,{children:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"state-get-auction-info",children:"state_get_auction_info"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/economics/consensus#bids",children:"bids"})," and ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validators"})," as of either a specific Block (by height or hash). If you do not provide a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", ",(0,s.jsx)(n.code,{children:"state_get_auction_info"})," will return information from the most recent Block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block identifier."})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_auction_info request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_auction_info_result",children:(0,s.jsx)(n.code,{children:"state_get_auction_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#auctionstate",children:"auction_state"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The auction state."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_auction_info result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "auction_state": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "delegation_rate": 0,\n "delegators": [],\n "inactive": false,\n "staked_amount": "10"\n },\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"\n }\n ],\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info-get-validator-changes",children:"info_get_validator_changes"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns status changes of active validators. Listed changes occurred during the ",(0,s.jsx)(n.code,{children:"EraId"})," contained within the response itself. A validator may show more than one change in a single era."]}),"\n",(0,s.jsx)(n.p,{children:"Potential change types:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Change Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Added"}),(0,s.jsx)(n.td,{children:"The validator has been added to the set."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Removed"}),(0,s.jsx)(n.td,{children:"The validator has been removed from the set."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Banned"}),(0,s.jsx)(n.td,{children:"The validator has been banned in the current era."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CannotPropose"}),(0,s.jsx)(n.td,{children:"The validator cannot propose a Block."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SeenAsFaulty"}),(0,s.jsx)(n.td,{children:"The validator has performed questionable activity."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_validator_changes request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_validator_changes_result",children:(0,s.jsx)(n.code,{children:"info_get_validator_changes_result"})}),"\n",(0,s.jsxs)(n.p,{children:["If no changes occurred in the current era, ",(0,s.jsx)(n.code,{children:"info_get_validator_changes"})," will return empty."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#jsonvalidatorchanges",children:"changes"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The validators' status changes."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_validator_changes result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_era_info_by_switch_block",children:"chain_get_era_info_by_switch_block"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns an EraInfo from the network. Only the last Block in an ",(0,s.jsx)(n.code,{children:"era"}),", known as a switch block, will contain an ",(0,s.jsx)(n.code,{children:"era_summary"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsxs)(n.td,{children:["The Block identifier. If you do not supply a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", the returned information will be the most recent Block. (Optional)"]})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_era_info_by_switch_block_result",children:(0,s.jsx)(n.code,{children:"chain_get_era_info_by_switch_block_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The era summary (If found)."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "era_summary": {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "era_id": 42,\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "amount": "1000",\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n },\n {\n "Validator": {\n "amount": "2000",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>d});var s=a(96540);const t={},r=s.createContext(t);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/03c6d9c7.c792cbe5.js b/assets/js/03c6d9c7.c792cbe5.js deleted file mode 100644 index 3ebcaa2ba..000000000 --- a/assets/js/03c6d9c7.c792cbe5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4684],{33603:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var s=a(74848),t=a(28453);const r={},c="Proof-of-Stake JSON-RPC Methods {#proof-of-stake}",d={id:"developers/json-rpc/json-rpc-pos",title:"Proof-of-Stake JSON-RPC Methods",description:"proof-of-stake}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-pos.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-pos",permalink:"/developers/json-rpc/json-rpc-pos",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Informational JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-informational"},next:{title:"Types",permalink:"/developers/json-rpc/types_chain"}},i={},o=[{value:"state_get_auction_info",id:"state-get-auction-info",level:2},{value:"state_get_auction_info_result",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info-get-validator-changes",level:2},{value:"info_get_validator_changes_result",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"chain_get_era_info_by_switch_block_result",id:"chain_get_era_info_by_switch_block_result",level:3}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"proof-of-stake",children:"Proof-of-Stake JSON-RPC Methods"})}),"\n",(0,s.jsx)(n.p,{children:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"state-get-auction-info",children:"state_get_auction_info"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the ",(0,s.jsx)(n.a,{href:"/concepts/economics/consensus#bids",children:"bids"})," and ",(0,s.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validators"})," as of either a specific Block (by height or hash). If you do not provide a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", ",(0,s.jsx)(n.code,{children:"state_get_auction_info"})," will return information from the most recent Block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block identifier."})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_auction_info request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_auction_info_result",children:(0,s.jsx)(n.code,{children:"state_get_auction_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#auctionstate",children:"auction_state"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The auction state."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_auction_info result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "auction_state": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "delegation_rate": 0,\n "delegators": [],\n "inactive": false,\n "staked_amount": "10"\n },\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"\n }\n ],\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info-get-validator-changes",children:"info_get_validator_changes"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns status changes of active validators. Listed changes occurred during the ",(0,s.jsx)(n.code,{children:"EraId"})," contained within the response itself. A validator may show more than one change in a single era."]}),"\n",(0,s.jsx)(n.p,{children:"Potential change types:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Change Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Added"}),(0,s.jsx)(n.td,{children:"The validator has been added to the set."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Removed"}),(0,s.jsx)(n.td,{children:"The validator has been removed from the set."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Banned"}),(0,s.jsx)(n.td,{children:"The validator has been banned in the current era."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"CannotPropose"}),(0,s.jsx)(n.td,{children:"The validator cannot propose a Block."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SeenAsFaulty"}),(0,s.jsx)(n.td,{children:"The validator has performed questionable activity."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_validator_changes request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_validator_changes_result",children:(0,s.jsx)(n.code,{children:"info_get_validator_changes_result"})}),"\n",(0,s.jsxs)(n.p,{children:["If no changes occurred in the current era, ",(0,s.jsx)(n.code,{children:"info_get_validator_changes"})," will return empty."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonvalidatorchanges",children:"changes"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The validators' status changes."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_validator_changes result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_era_info_by_switch_block",children:"chain_get_era_info_by_switch_block"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns an EraInfo from the network. Only the last Block in an ",(0,s.jsx)(n.code,{children:"era"}),", known as a switch block, will contain an ",(0,s.jsx)(n.code,{children:"era_summary"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsxs)(n.td,{children:["The Block identifier. If you do not supply a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", the returned information will be the most recent Block. (Optional)"]})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_era_info_by_switch_block_result",children:(0,s.jsx)(n.code,{children:"chain_get_era_info_by_switch_block_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The era summary (If found)."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "era_summary": {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "era_id": 42,\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "amount": "1000",\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n },\n {\n "Validator": {\n "amount": "2000",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>d});var s=a(96540);const t={},r=s.createContext(t);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/044f7961.5f1b0a68.js b/assets/js/044f7961.5f1b0a68.js deleted file mode 100644 index 0cb339b08..000000000 --- a/assets/js/044f7961.5f1b0a68.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8114],{88914:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>h});var s=t(74848),a=t(28453);const i={},r="Signing Transactions",o={id:"developers/dapps/signing-a-transaction",title:"Signing Transactions",description:"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.",source:"@site/docs/developers/dapps/signing-a-transaction.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/signing-a-transaction",permalink:"/next/developers/dapps/signing-a-transaction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"URef Access Rights",permalink:"/next/developers/dapps/uref-security"},next:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/next/developers/dapps/speculative-exec"}},c={},h=[{value:"Public Key Cryptography",id:"public-key-cryptography",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"signing-transactions",children:"Signing Transactions"})}),"\n",(0,s.jsxs)(n.p,{children:["When creating a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:(0,s.jsx)(n.code,{children:"Transaction"})})," to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed."]}),"\n",(0,s.jsxs)(n.p,{children:["When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#approval",children:(0,s.jsx)(n.code,{children:"Approval"})}),". Every valid transaction has at least one approval."]}),"\n",(0,s.jsxs)(n.p,{children:["The signature creation process begins with the hashing of the payment and session of the transaction to create the ",(0,s.jsx)(n.code,{children:"BodyHash"}),". The ",(0,s.jsx)(n.code,{children:"BodyHash"})," becomes a component of the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," as outlined in the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/",children:"serialization standard"}),". From there, the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," can be hashed to create the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"}),". As outlined above, the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," is then combined with the account's key-pair to create the transaction's signature."]}),"\n",(0,s.jsxs)(n.p,{children:["As the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," invalid."]}),"\n",(0,s.jsx)(n.h2,{id:"public-key-cryptography",children:"Public Key Cryptography"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks are compatible with both ",(0,s.jsx)(n.code,{children:"Ed25519"})," and ",(0,s.jsx)(n.code,{children:"Secp256k1"})," public key cryptography. When ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/",children:"serialized"}),", public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with ",(0,s.jsx)(n.code,{children:"1"}),", whereas Secp256k1 are prefixed with ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses ",(0,s.jsx)(n.code,{children:"blake2b"})," hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ed25519 signs over a SHA-512 digest."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Secp256k1 signs over a SHA-256 digest."}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const a={},i=s.createContext(a);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/044f7961.a5cca8cf.js b/assets/js/044f7961.a5cca8cf.js new file mode 100644 index 000000000..10bce0a99 --- /dev/null +++ b/assets/js/044f7961.a5cca8cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[78114],{88914:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>h});var s=t(74848),a=t(28453);const i={},r="Signing Transactions",o={id:"developers/dapps/signing-a-transaction",title:"Signing Transactions",description:"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.",source:"@site/docs/developers/dapps/signing-a-transaction.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/signing-a-transaction",permalink:"/developers/dapps/signing-a-transaction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"},next:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/developers/dapps/speculative-exec"}},c={},h=[{value:"Public Key Cryptography",id:"public-key-cryptography",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"signing-transactions",children:"Signing Transactions"})}),"\n",(0,s.jsxs)(n.p,{children:["When creating a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/T#transaction",children:(0,s.jsx)(n.code,{children:"Transaction"})})," to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed."]}),"\n",(0,s.jsxs)(n.p,{children:["When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an ",(0,s.jsx)(n.a,{href:"/concepts/serialization/types#approval",children:(0,s.jsx)(n.code,{children:"Approval"})}),". Every valid transaction has at least one approval."]}),"\n",(0,s.jsxs)(n.p,{children:["The signature creation process begins with the hashing of the payment and session of the transaction to create the ",(0,s.jsx)(n.code,{children:"BodyHash"}),". The ",(0,s.jsx)(n.code,{children:"BodyHash"})," becomes a component of the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," as outlined in the ",(0,s.jsx)(n.a,{href:"/concepts/serialization/",children:"serialization standard"}),". From there, the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," can be hashed to create the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"}),". As outlined above, the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," is then combined with the account's key-pair to create the transaction's signature."]}),"\n",(0,s.jsxs)(n.p,{children:["As the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," invalid."]}),"\n",(0,s.jsx)(n.h2,{id:"public-key-cryptography",children:"Public Key Cryptography"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks are compatible with both ",(0,s.jsx)(n.code,{children:"Ed25519"})," and ",(0,s.jsx)(n.code,{children:"Secp256k1"})," public key cryptography. When ",(0,s.jsx)(n.a,{href:"/concepts/serialization/",children:"serialized"}),", public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with ",(0,s.jsx)(n.code,{children:"1"}),", whereas Secp256k1 are prefixed with ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses ",(0,s.jsx)(n.code,{children:"blake2b"})," hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ed25519 signs over a SHA-512 digest."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Secp256k1 signs over a SHA-256 digest."}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const a={},i=s.createContext(a);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04a0dcd6.f1fd239f.js b/assets/js/04a0dcd6.f1fd239f.js new file mode 100644 index 000000000..fd890a1c2 --- /dev/null +++ b/assets/js/04a0dcd6.f1fd239f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11573],{94512:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>o});var t=s(74848),i=s(28453);const a={},l="Development Prerequisites",r={id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.",source:"@site/versioned_docs/version-2.0.0/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/2.0.0/developers/prerequisites",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/2.0.0/developers"},next:{title:"Essential Rust Crates",permalink:"/2.0.0/developers/essential-crates"}},c={},o=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing curl",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing cargo on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing brew",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"development-prerequisites",children:"Development Prerequisites"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,t.jsx)(n.code,{children:"Linux Ubuntu 20.04"})," or ",(0,t.jsx)(n.code,{children:"macOS"}),". Developing on Windows is not advised."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["Casper does not officially support ",(0,t.jsx)(n.code,{children:"macOS"}),". If you encounter any problems, reach out to the community on ",(0,t.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"})," or ",(0,t.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"preparing-your-development-environment",children:"Preparing your Development Environment"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsxs)(n.h3,{id:"install-curl",children:["Installing ",(0,t.jsx)(n.code,{children:"curl"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install curl\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-essential",children:"Installing essential Linux packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-linux-cargo",children:["Installing ",(0,t.jsx)(n.code,{children:"cargo"})," on Linux"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install cargo\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.h3,{id:"install-xcode",children:"Installing Xcode developer tools for macOS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select -p\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-brew",children:["Installing ",(0,t.jsx)(n.code,{children:"brew"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds-macos",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-rust",children:"Installing Rust"}),"\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust programming language"})," if you don't already have it on your computer."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"official Rust guide"})," recommends installing Rust by using ",(0,t.jsx)(n.code,{children:"curl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.p,{children:"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source $HOME/.cargo/env\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: You can also use ",(0,t.jsx)(n.code,{children:"brew"})," on MacOS or ",(0,t.jsx)(n.code,{children:"apt"})," on Linux to install Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-casper-crates",children:"Installing the Casper Crates"}),"\n",(0,t.jsxs)(n.p,{children:["The best and fastest way to set up a Casper Rust project is to use ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/cargo-casper",children:"cargo casper"}),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,t.jsx)(n.em,{children:"Cargo"})," is a build system and package manager for Rust (much like ",(0,t.jsx)(n.em,{children:"pip"})," if you are familiar with Python, or ",(0,t.jsx)(n.em,{children:"npm"})," and ",(0,t.jsx)(n.em,{children:"yarn"})," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install cargo-casper\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo-casper --version\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Familiarize yourself with the essential Casper crates described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/essential-crates",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"install-casper-client",children:"Installing the Casper Client"}),"\n",(0,t.jsxs)(n.p,{children:["The default Casper client is on ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-client",children:"crates.io"}),". This client can transmit your transactions to a Casper network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install casper-client\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"help"})," for each command to get the most up-to-date arguments and descriptions."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"building-client-from-source",children:"Accessing the Casper client source code"}),"\n",(0,t.jsxs)(n.p,{children:["You can access the Casper client source code ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs",children:"here"}),". The ",(0,t.jsx)(n.code,{children:"lib"})," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,t.jsx)(n.code,{children:"casper-client"})," uses this library to implement its functionality."]}),"\n",(0,t.jsx)(n.p,{children:"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, compile the source code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You will find the ",(0,t.jsx)(n.code,{children:"casper-client"})," executable in the ",(0,t.jsx)(n.code,{children:"target/release"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"install-cmake",children:"Installing CMake"}),"\n",(0,t.jsxs)(n.p,{children:["If you plan to compile contracts from the source code, including those provided in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, install ",(0,t.jsx)(n.code,{children:"CMake"})," with the commands below."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://cmake.org/",children:"CMake"})," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"CMake website"}),". Once installed, check your version as shown below."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get -y install cmake\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install cmake\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sample output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-an-ide",children:"Installing an IDE"}),"\n",(0,t.jsx)(n.p,{children:"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://code.visualstudio.com",children:"Visual Studio Code"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/clion/",children:"CLion"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/idea/",children:"IntelliJ Idea"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.vim.org/",children:"Vim"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."}),"\n",(0,t.jsx)(n.p,{children:"If you are using VSC, you might find the following extensions useful:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"CodeLLDB"})," \u2013 An important extension for debugging Rust code"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rust-analyzer"})," \u2013 The official Rust language extension"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Better TOML"})," \u2013 Support for formatting TOML files"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"crates"})," \u2013 An extension to help manage crates"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Error Lens"})," \u2013 Enhances the programming experience by highlighting syntax errors"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-an-account",children:"Setting up a Casper Account"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Account"})," creation process consists of two steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Creating an Account"}),"\n",(0,t.jsx)(n.li,{children:"Funding the Account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following video complements the instructions below, showing you the expected output."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"creating-an-account",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,t.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,t.jsxs)(n.p,{children:["Users can create accounts using the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#option-2-key-generation-using-a-block-explorer",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Use either method to generate an account and its corresponding cryptographic key-pair."}),"\n",(0,t.jsx)(n.h3,{id:"generating-the-account-hash",children:"Generating the account hash"}),"\n",(0,t.jsxs)(n.p,{children:["As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,t.jsx)(n.code,{children:"AccountHashes"})," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,t.jsx)(n.code,{children:"account-address"})," option of the Casper CLI client:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key \n"})}),"\n",(0,t.jsx)(n.h2,{id:"fund-your-account",children:"Funding an Account"}),"\n",(0,t.jsx)(n.p,{children:"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."}),"\n",(0,t.jsxs)(n.p,{children:["On Testnet, you can fund an account by requesting test tokens according to ",(0,t.jsx)(n.a,{href:"/2.0.0/users/testnet-faucet",children:"this guide"}),". You can request test tokens ",(0,t.jsx)(n.strong,{children:"only once"})," for each account."]}),"\n",(0,t.jsx)(n.p,{children:"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."}),"\n",(0,t.jsx)(n.h2,{id:"acquire-node-address-from-network-peers",children:"Acquiring a Node Address from the Network"}),"\n",(0,t.jsxs)(n.p,{children:["Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,t.jsx)(n.code,{children:"http://:7777"})," by default."]}),"\n",(0,t.jsx)(n.p,{children:"The node address is the IP of a peer node."}),"\n",(0,t.jsx)(n.p,{children:"Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."}),"\n",(0,t.jsxs)(n.p,{children:["You can get the ",(0,t.jsx)(n.code,{children:"node-ip-address"})," of a node on the network by visiting the following block explorers:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Peers"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Peers"})," on Mainnet"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You will see a list of peers, and you can select the IP of any peer on the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": If the selected peer is unresponsive, pick a different peer and try again."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const i={},a=t.createContext(i);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04f8200d.35a20847.js b/assets/js/04f8200d.35a20847.js deleted file mode 100644 index 6bfd6dde0..000000000 --- a/assets/js/04f8200d.35a20847.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[635],{48232:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Undelegate Tokens",slug:"/users/undelegate-ui"},o="Undelegating Tokens",r={id:"users/csprlive/undelegate-ui",title:"Undelegate Tokens",description:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/undelegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/undelegate-ui",permalink:"/users/undelegate-ui",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Undelegate Tokens",slug:"/users/undelegate-ui"},sidebar:"users",previous:{title:"Delegate Tokens",permalink:"/users/delegate-ui"},next:{title:"Transfer Tokens",permalink:"/users/token-transfer"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Accessing the Undelegation Feature",id:"accessing-the-undelegation-feature",level:2},{value:"Stepping through the Undelegation Process",id:"stepping-through-the-undelegation-process",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens",children:"Undelegating Tokens"})}),"\n",(0,s.jsx)(n.p,{children:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["This guide assumes that you have previously delegated tokens to a validator using a ",(0,s.jsx)(n.a,{href:"/users/delegate-ui",children:"block explorer"})," or the ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"Casper client"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"accessing-the-undelegation-feature",children:"Accessing the Undelegation Feature"}),"\n",(0,s.jsx)(n.p,{children:"You can access the undelegation functionality in three ways."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 1:"})," Click ",(0,s.jsx)(n.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(89990).A+"",width:"243",height:"325"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 2:"})," Click ",(0,s.jsx)(n.strong,{children:"Validators"})," from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"})," button."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(83346).A+"",width:"2222",height:"992"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 3:"})," Open your account details and select the ",(0,s.jsx)(n.strong,{children:"Delegations"})," tab. Click the ",(0,s.jsx)(n.strong,{children:"Undelegate"})," button next to the validator from whom you wish to undelegate."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(53584).A+"",width:"2482",height:"524"})}),"\n",(0,s.jsx)(n.h2,{id:"stepping-through-the-undelegation-process",children:"Stepping through the Undelegation Process"}),"\n",(0,s.jsx)(n.p,{children:'The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.'}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 1 - Undelegation details"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,s.jsx)(n.li,{children:"Enter the amount of Casper tokens you want to undelegate."}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(70370).A+"",width:"1136",height:"1442"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 2 - Confirm the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Review the undelegation details."}),"\n",(0,s.jsxs)(n.li,{children:["If everything looks correct, click ",(0,s.jsx)(n.strong,{children:"Confirm and undelegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(34246).A+"",width:"1156",height:"1480"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 3 - Sign the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign with Casper Wallet"})," to sign the undelegation."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(23926).A+"",width:"1126",height:"1706"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(25463).A+"",width:"1974",height:"1728"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(61312).A+"",width:"1114",height:"1336"})}),"\n",(0,s.jsx)(n.p,{children:'It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.'}),"\n",(0,s.jsx)(n.p,{children:"Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours."})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},89990:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.wallet-undelegate-9d248f8c648da6a81f11519504d7812b.png"},83346:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.validator-undelegate-5b02fc97aa94336f98b91ed2414630aa.png"},53584:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.account-undelegate-115ac530fff9a47a18e6e9faa1dd418b.png"},70370:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.undelegate-details-bc50ff78eb29ada22fab3ed956a833be.png"},34246:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.confirm-undelegation-ab54ef5443b66d944efc83b7d9623af7.png"},23926:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/6.sign-undelegation-0e412d3726ca39417062e53ae0e6fcca.png"},25463:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/7.confirm-hash-466847a8e9502b69d17c46350f4bcab2.png"},61312:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/8.undelegation-confirmed-a77491f86b955fe091fe6ebf6e685f91.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/04f8200d.5228b822.js b/assets/js/04f8200d.5228b822.js new file mode 100644 index 000000000..90581e54f --- /dev/null +++ b/assets/js/04f8200d.5228b822.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30635],{48232:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Undelegate Tokens",slug:"/users/undelegate-ui"},o="Undelegating Tokens",r={id:"users/csprlive/undelegate-ui",title:"Undelegate Tokens",description:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/undelegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/undelegate-ui",permalink:"/1.5.X/users/undelegate-ui",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Undelegate Tokens",slug:"/users/undelegate-ui"},sidebar:"users",previous:{title:"Delegate Tokens",permalink:"/1.5.X/users/delegate-ui"},next:{title:"Transfer Tokens",permalink:"/1.5.X/users/token-transfer"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Accessing the Undelegation Feature",id:"accessing-the-undelegation-feature",level:2},{value:"Stepping through the Undelegation Process",id:"stepping-through-the-undelegation-process",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens",children:"Undelegating Tokens"})}),"\n",(0,s.jsx)(n.p,{children:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["This guide assumes that you have previously delegated tokens to a validator using a ",(0,s.jsx)(n.a,{href:"/1.5.X/users/delegate-ui",children:"block explorer"})," or the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"Casper client"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"accessing-the-undelegation-feature",children:"Accessing the Undelegation Feature"}),"\n",(0,s.jsx)(n.p,{children:"You can access the undelegation functionality in three ways."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 1:"})," Click ",(0,s.jsx)(n.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"}),"."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(46612).A+"",width:"243",height:"325"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 2:"})," Click ",(0,s.jsx)(n.strong,{children:"Validators"})," from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the ",(0,s.jsx)(n.strong,{children:"Undelegate Stake"})," button."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(52488).A+"",width:"2222",height:"992"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Option 3:"})," Open your account details and select the ",(0,s.jsx)(n.strong,{children:"Delegations"})," tab. Click the ",(0,s.jsx)(n.strong,{children:"Undelegate"})," button next to the validator from whom you wish to undelegate."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(35018).A+"",width:"2482",height:"524"})}),"\n",(0,s.jsx)(n.h2,{id:"stepping-through-the-undelegation-process",children:"Stepping through the Undelegation Process"}),"\n",(0,s.jsx)(n.p,{children:'The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.'}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 1 - Undelegation details"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,s.jsx)(n.li,{children:"Enter the amount of Casper tokens you want to undelegate."}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(83420).A+"",width:"1136",height:"1442"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 2 - Confirm the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Review the undelegation details."}),"\n",(0,s.jsxs)(n.li,{children:["If everything looks correct, click ",(0,s.jsx)(n.strong,{children:"Confirm and undelegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(93360).A+"",width:"1156",height:"1480"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Step 3 - Sign the undelegation"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign with Casper Wallet"})," to sign the undelegation."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(43624).A+"",width:"1126",height:"1706"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.']}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(43689).A+"",width:"1974",height:"1728"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(84042).A+"",width:"1114",height:"1336"})}),"\n",(0,s.jsx)(n.p,{children:'It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.'}),"\n",(0,s.jsx)(n.p,{children:"Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours."})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},46612:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.wallet-undelegate-9d248f8c648da6a81f11519504d7812b.png"},52488:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.validator-undelegate-5b02fc97aa94336f98b91ed2414630aa.png"},35018:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.account-undelegate-115ac530fff9a47a18e6e9faa1dd418b.png"},83420:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.undelegate-details-bc50ff78eb29ada22fab3ed956a833be.png"},93360:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.confirm-undelegation-ab54ef5443b66d944efc83b7d9623af7.png"},43624:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/6.sign-undelegation-0e412d3726ca39417062e53ae0e6fcca.png"},43689:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/7.confirm-hash-466847a8e9502b69d17c46350f4bcab2.png"},84042:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/8.undelegation-confirmed-a77491f86b955fe091fe6ebf6e685f91.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/051b98e7.8a9171cd.js b/assets/js/051b98e7.8a9171cd.js new file mode 100644 index 000000000..c227396bf --- /dev/null +++ b/assets/js/051b98e7.8a9171cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[47740],{32563:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=s(74848),c=s(28453);const t={title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},o="CEP-18 Token Transfers and Allowances",r={id:"resources/tokens/cep18/transfer",title:"CEP-18 Transfers",description:"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/transfer.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/transfer",permalink:"/2.0.0/resources/tokens/cep18/transfer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},sidebar:"resources",previous:{title:"CEP-18 Contract Details",permalink:"/2.0.0/resources/tokens/cep18/query"},next:{title:"Testing Guide",permalink:"/2.0.0/resources/tokens/cep18/tests"}},i={},d=[{value:"Transferring CEP-18 Tokens to Another Account",id:"transferring-cep-18-tokens-to-another-account",level:2},{value:"Invoking the check_balance_of Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}];function h(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cep-18-token-transfers-and-allowances",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,a.jsxs)(n.p,{children:["This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,a.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."]}),"\n",(0,a.jsx)(n.h2,{id:"transferring-cep-18-tokens-to-another-account",children:"Transferring CEP-18 Tokens to Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The following command will invoke the ",(0,a.jsx)(n.code,{children:"transfer"})," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://: \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name \\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,a.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the utility contract to verify the account's balance."]}),"\n",(0,a.jsxs)(n.h3,{id:"invoking-the-check_balance_of-entry-point",children:["Invoking the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," Entry Point"]}),"\n",(0,a.jsxs)(n.p,{children:["The following Casper client command invokes the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the ",(0,a.jsx)(n.code,{children:"cep18_test_contract"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["After sending this command, you will need to query the ",(0,a.jsx)(n.code,{children:"results"})," URef within the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," of your ",(0,a.jsx)(n.code,{children:"cep18_test_contract"})," utility contract instance. More information on finding this URef can be found in the ",(0,a.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/query#querying-the-utility-contract",children:"Exploring the CEP18 Contracts"})," document."]}),"\n",(0,a.jsxs)(n.p,{children:["You can use the following command to query global state for the ",(0,a.jsx)(n.code,{children:"results"})," URef."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://: \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command should show something similar to the following in response, with ",(0,a.jsx)(n.code,{children:"parsed"})," being the amount of CEP-18 tokens that the account holds."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approving-an-allowance-for-another-account",children:"Approving an Allowance for Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The Casper fungible token contract features an ",(0,a.jsx)(n.code,{children:"allowance"})," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."]}),"\n",(0,a.jsx)(n.h3,{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",children:"Approving an Account to Spend Tokens on Another Account's Behalf"}),"\n",(0,a.jsxs)(n.p,{children:["The following command approves a third-party account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://:\\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"verifying-a-previously-issued-allowance",children:"Verifying a Previously Issued Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["After approving an account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,a.jsx)(n.code,{children:"allowance"})," of the spender's account to the ",(0,a.jsx)(n.code,{children:"result"})," URef of in the utility contract's ",(0,a.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://:\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name \\\n--payment-amount 10000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following command queries global state to return the value stored under the ",(0,a.jsx)(n.code,{children:"result"})," URef:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://: \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://: \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You should get a response similar to the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"transferring-tokens-from-an-allowance",children:"Transferring Tokens from an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,a.jsx)(n.code,{children:"allowance"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://: \\\n--chain-name \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--chain-name \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"increasing-and-decreasing-an-allowance",children:"Increasing and Decreasing an Allowance"}),"\n",(0,a.jsx)(n.h4,{id:"increasing-an-allowance",children:"Increasing an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command increases the designated ",(0,a.jsx)(n.code,{children:"allowance"})," for the provided account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"decreasing-an-allowance",children:"Decreasing an Allowance"}),"\n",(0,a.jsx)(n.p,{children:"The following command decreases the designated allowance for the provided account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"minting-and-burning-additional-cep-18-tokens",children:"Minting and Burning Additional CEP-18 Tokens"}),"\n",(0,a.jsx)(n.h4,{id:"minting-additional-tokens",children:"Minting Additional Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"burning-tokens",children:"Burning Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"changing-account-security-permissions",children:"Changing Account Security Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"change_security"})," entrypoint can be used by an account with ",(0,a.jsx)(n.code,{children:"admin"})," access to alter the security level of other accounts."]}),"\n",(0,a.jsx)(n.p,{children:"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"None"})," - ",(0,a.jsx)(n.code,{children:"None"})," overrides other security levels and removes all admin, minting and burning access of an account."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Admin"})," - Allows the account full access and control over the CEP-18 contract."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"MintAndBurn"})," - Allows the account to mint new tokens and burn existing tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Burner"})," - The account can burn tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Minter"})," - The account can mint new tokens."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Here is an example of a ",(0,a.jsx)(n.code,{children:"session-arg"})," that provides a list of account hashes to be included on the ",(0,a.jsx)(n.code,{children:"mint_and_burn_list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Be aware that removing all admin accounts will lock out all admin functionality."})}),"\n",(0,a.jsx)(n.p,{children:"The following command can be supplied with any of the optional arguments above:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://: \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'\'" \\\n--session-arg "admin_list:string:\'\'" \\\n--session-arg "mint_and_burn_list:string:\'\'" \\\n--session-arg "burner_list:string:\'\'" \\\n--chain-name \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsx)(n.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var a=s(96540);const c={},t=a.createContext(c);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/053d5d89.4f1b46a0.js b/assets/js/053d5d89.4f1b46a0.js deleted file mode 100644 index e194b77d9..000000000 --- a/assets/js/053d5d89.4f1b46a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8953],{14764:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),r=t(28453);const i={},c="Upgrading and Maintaining Smart Contracts",o={id:"developers/writing-onchain-code/upgrading-contracts",title:"Upgrading and Maintaining Smart Contracts",description:"Our smart contract packaging tools enable you to:",source:"@site/docs/developers/writing-onchain-code/upgrading-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/upgrading-contracts",permalink:"/next/developers/writing-onchain-code/upgrading-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"developers",previous:{title:"Testing Smart Contracts",permalink:"/next/developers/writing-onchain-code/testing-contracts"},next:{title:"Calling Contracts",permalink:"/next/developers/writing-onchain-code/calling-contracts"}},s={},d=[{value:"The Contract Package",id:"the-contract-package",level:2},{value:"Videos and Tutorials",id:"videos-and-tutorials",level:2},{value:"Maintaining a Contract",id:"maintaining-a-contract",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-and-maintaining-smart-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),"\n",(0,a.jsx)(n.p,{children:"Our smart contract packaging tools enable you to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Upgrade your contracts and specify how the state of the contract is managed"}),"\n",(0,a.jsx)(n.li,{children:"Specify whether a contract is upgradable or immutable"}),"\n",(0,a.jsx)(n.li,{children:"Version your contracts and deprecate old versions"}),"\n",(0,a.jsx)(n.li,{children:"Set permissions around who can perform contract upgrades"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"the-contract-package",children:"The Contract Package"}),"\n",(0,a.jsx)(n.p,{children:"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. If you find that you need to use a disabled contract version, you may also re-enable it."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Package Representation",src:t(80739).A+"",width:"1170",height:"472"})}),"\n",(0,a.jsx)(n.p,{children:"The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain."}),"\n",(0,a.jsx)(n.h2,{id:"videos-and-tutorials",children:"Videos and Tutorials"}),"\n",(0,a.jsxs)(n.p,{children:["To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})," documentation."]}),"\n",(0,a.jsxs)(n.p,{align:"center",children:["\n",(0,a.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=10",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Or, for a different perspective, consult the ",(0,a.jsx)(n.a,{href:"/next/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrade Tutorial"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"maintaining-a-contract",children:"Maintaining a Contract"}),"\n",(0,a.jsx)(n.p,{children:"The contract maintenance process is generally covered through the contract upgrade process."}),"\n",(0,a.jsx)(n.p,{children:"Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance."}),"\n",(0,a.jsx)(n.p,{children:"On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},80739:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/package-representation-5e72ef8539f89dbe682c86c52d9536c8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var a=t(96540);const r={},i=a.createContext(r);function c(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/053d5d89.4f2907f5.js b/assets/js/053d5d89.4f2907f5.js new file mode 100644 index 000000000..4ac462eae --- /dev/null +++ b/assets/js/053d5d89.4f2907f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98953],{14764:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),r=t(28453);const i={},c="Upgrading and Maintaining Smart Contracts",o={id:"developers/writing-onchain-code/upgrading-contracts",title:"Upgrading and Maintaining Smart Contracts",description:"Our smart contract packaging tools enable you to:",source:"@site/docs/developers/writing-onchain-code/upgrading-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/upgrading-contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"developers",previous:{title:"Testing Smart Contracts",permalink:"/developers/writing-onchain-code/testing-contracts"},next:{title:"Calling Contracts",permalink:"/developers/writing-onchain-code/calling-contracts"}},s={},d=[{value:"The Contract Package",id:"the-contract-package",level:2},{value:"Videos and Tutorials",id:"videos-and-tutorials",level:2},{value:"Maintaining a Contract",id:"maintaining-a-contract",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-and-maintaining-smart-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),"\n",(0,a.jsx)(n.p,{children:"Our smart contract packaging tools enable you to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Upgrade your contracts and specify how the state of the contract is managed"}),"\n",(0,a.jsx)(n.li,{children:"Specify whether a contract is upgradable or immutable"}),"\n",(0,a.jsx)(n.li,{children:"Version your contracts and deprecate old versions"}),"\n",(0,a.jsx)(n.li,{children:"Set permissions around who can perform contract upgrades"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"the-contract-package",children:"The Contract Package"}),"\n",(0,a.jsx)(n.p,{children:"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. If you find that you need to use a disabled contract version, you may also re-enable it."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Package Representation",src:t(47593).A+"",width:"1170",height:"472"})}),"\n",(0,a.jsx)(n.p,{children:"The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain."}),"\n",(0,a.jsx)(n.h2,{id:"videos-and-tutorials",children:"Videos and Tutorials"}),"\n",(0,a.jsxs)(n.p,{children:["To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})," documentation."]}),"\n",(0,a.jsxs)(n.p,{align:"center",children:["\n",(0,a.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=10",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Or, for a different perspective, consult the ",(0,a.jsx)(n.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrade Tutorial"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"maintaining-a-contract",children:"Maintaining a Contract"}),"\n",(0,a.jsx)(n.p,{children:"The contract maintenance process is generally covered through the contract upgrade process."}),"\n",(0,a.jsx)(n.p,{children:"Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance."}),"\n",(0,a.jsx)(n.p,{children:"On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},47593:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/package-representation-5e72ef8539f89dbe682c86c52d9536c8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var a=t(96540);const r={},i=a.createContext(r);function c(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/056155c0.abd058a6.js b/assets/js/056155c0.abd058a6.js new file mode 100644 index 000000000..c4e8021b0 --- /dev/null +++ b/assets/js/056155c0.abd058a6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[12250],{91368:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var r=n(74848),s=n(28453);const a={slug:"/resources/tutorials/advanced/"},i="Advanced Tutorials",d={id:"resources/advanced/index",title:"Advanced Tutorials",description:"| Title | Description |",source:"@site/versioned_docs/version-2.0.0/resources/advanced/index.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/",permalink:"/2.0.0/resources/tutorials/advanced/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{slug:"/resources/tutorials/advanced/"},sidebar:"tutorials",previous:{title:"AWS Casper Nodes",permalink:"/2.0.0/resources/tutorials/beginner/aws-node"},next:{title:"Two-Party Multi-Sig",permalink:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig"}},o={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"advanced-tutorials",children:"Advanced Tutorials"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Title"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Transactions"})}),(0,r.jsx)(t.td,{children:"A trivial two-party multi-signature scheme for signing and sending transactions"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/advanced/multi-sig/",children:"Multi-Sig Management"})}),(0,r.jsx)(t.td,{children:"Integrate key management on Casper accounts and sign transactions with multiple keys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsxs)(t.td,{children:["Contract code returning a value to the immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(t.td,{children:"Two methods to handle tokens via a contract"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})}),(0,r.jsx)(t.td,{children:"Methods to read and write data to global state on a Casper network using Rust"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/cross-contract",children:"Cross Contract Communication"})}),(0,r.jsx)(t.td,{children:"Variations of cross-contract communication for more complex scenarios"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/2.0.0/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(t.td,{children:"Retrieve and use the authorization keys associated with a transaction"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>d});var r=n(96540);const s={},a=r.createContext(s);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05a3aa78.7bddfc8e.js b/assets/js/05a3aa78.7bddfc8e.js new file mode 100644 index 000000000..bd0312b37 --- /dev/null +++ b/assets/js/05a3aa78.7bddfc8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80885],{95773:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=n(74848),o=n(28453);const r={},a="Casper-Client Commands",i={id:"resources/beginner/counter-testnet/commands",title:"Casper-Client Commands",description:"State Root Hash",source:"@site/docs/resources/beginner/counter-testnet/commands.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/commands",permalink:"/resources/beginner/counter-testnet/commands",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/beginner/counter-testnet/overview"},next:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough"}},c={},l=[{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,s.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address http://[IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find a list of Testnet IP addresses at ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"CSPR live"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The first command to cover is the ",(0,s.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,s.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"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."})}),"\n",(0,s.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"node-address"})," is the server on the network."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,s.jsxs)(t.li,{children:["The optional query path argument (",(0,s.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,s.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,s.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,s.jsx)(t.em,{children:"chain-name"}),'. The Testnet is "casper-test" but this is configurable.']}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This second usage of ",(0,s.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,s.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,s.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,s.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,s.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/05a3aa78.baa762b5.js b/assets/js/05a3aa78.baa762b5.js deleted file mode 100644 index 947f61d1b..000000000 --- a/assets/js/05a3aa78.baa762b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[885],{95773:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=n(74848),o=n(28453);const r={},a="Casper-Client Commands",i={id:"resources/beginner/counter-testnet/commands",title:"Casper-Client Commands",description:"State Root Hash",source:"@site/docs/resources/beginner/counter-testnet/commands.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/commands",permalink:"/next/resources/beginner/counter-testnet/commands",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/next/resources/beginner/counter-testnet/overview"},next:{title:"Tutorial Walkthrough",permalink:"/next/resources/beginner/counter-testnet/walkthrough"}},c={},l=[{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,s.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address http://[IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find a list of Testnet IP addresses at ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"CSPR live"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The first command to cover is the ",(0,s.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,s.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"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."})}),"\n",(0,s.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"node-address"})," is the server on the network."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,s.jsxs)(t.li,{children:["The optional query path argument (",(0,s.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,s.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,s.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,s.jsx)(t.em,{children:"chain-name"}),'. The Testnet is "casper-test" but this is configurable.']}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This second usage of ",(0,s.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,s.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,s.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,s.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,s.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06c1e821.b8aa7d80.js b/assets/js/06c1e821.b8aa7d80.js new file mode 100644 index 000000000..4d9e17ddd --- /dev/null +++ b/assets/js/06c1e821.b8aa7d80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1381],{91015:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=s(74848),a=s(28453);const r={},o=".NET SDK",c={id:"developers/dapps/sdk/csharp-sdk",title:".NET SDK",description:"The C# .NET SDK allows developers to interact with a Casper network using C#.",source:"@site/docs/developers/dapps/sdk/csharp-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/csharp-sdk",permalink:"/developers/dapps/sdk/csharp-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"},next:{title:"Go SDK",permalink:"/developers/dapps/sdk/go-sdk"}},i={},d=[{value:"Documentation",id:"documentation",level:2},{value:"Get started",id:"get-started",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"net-sdk",children:".NET SDK"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"C# .NET SDK"})," allows developers to interact with a Casper network using C#."]}),"\n",(0,t.jsx)(n.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find the SDK documentation, examples, and tutorials."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get started"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing."}),"\n",(0,t.jsx)(n.p,{children:"Open a terminal window and create a new console app:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet new console -o GetAccountBalance\ncd GetAccountBalance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The Casper.Network.SDK for .NET is published on ",(0,t.jsx)(n.a,{href:"https://www.nuget.org/packages/Casper.Network.SDK",children:"nuget.org"})," as a NuGet package."]}),"\n",(0,t.jsxs)(n.p,{children:["To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the ",(0,t.jsx)(n.code,{children:"dotnet"})," CLI tool."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Package Manager (Windows)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Install-Package Casper.Network.SDK\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"dotnet CLI Tool (Windows, Mac, and Linux)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet add package Casper.Network.SDK\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, replace the default code in ",(0,t.jsx)(n.code,{children:"Program.cs"})," with this main program:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'using System;\nusing System.Threading.Tasks;\nusing Casper.Network.SDK;\nusing Casper.Network.SDK.JsonRpc;\nusing Casper.Network.SDK.Types;\n\nnamespace Casper.NET.SDK.Examples\n{\n public class GetAccountBalance\n {\n public static async Task Main(string[] args)\n {\n string nodeAddress = "http://testnet-node.make.services:7777";\n\n var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";\n var publicKey = PublicKey.FromHexString(hex);\n\n try\n {\n var casperSdk = new NetCasperClient(nodeAddress);\n\n // Get the balance using the account public key\n //\n var rpcResponse = await casperSdk.GetAccountBalance(publicKey);\n Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);\n }\n catch (RpcClientException e)\n {\n Console.WriteLine("ERROR:\\n" + e.RpcError.Message);\n }\n catch (Exception e)\n {\n Console.WriteLine(e);\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, run the example with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet run\n"})}),"\n",(0,t.jsx)(n.p,{children:"The program will print the account's main purse balance retrieved from the testnet."}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find other examples, tutorials, and complete documentation for this SDK."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/06c1e821.b9348323.js b/assets/js/06c1e821.b9348323.js deleted file mode 100644 index bea770fbf..000000000 --- a/assets/js/06c1e821.b9348323.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1381],{91015:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=s(74848),a=s(28453);const r={},o=".NET SDK",c={id:"developers/dapps/sdk/csharp-sdk",title:".NET SDK",description:"The C# .NET SDK allows developers to interact with a Casper network using C#.",source:"@site/docs/developers/dapps/sdk/csharp-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/csharp-sdk",permalink:"/next/developers/dapps/sdk/csharp-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"JavaScript/TypeScript SDK",permalink:"/next/developers/dapps/sdk/script-sdk"},next:{title:"Go SDK",permalink:"/next/developers/dapps/sdk/go-sdk"}},i={},d=[{value:"Documentation",id:"documentation",level:2},{value:"Get started",id:"get-started",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"net-sdk",children:".NET SDK"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"C# .NET SDK"})," allows developers to interact with a Casper network using C#."]}),"\n",(0,t.jsx)(n.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find the SDK documentation, examples, and tutorials."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get started"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing."}),"\n",(0,t.jsx)(n.p,{children:"Open a terminal window and create a new console app:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet new console -o GetAccountBalance\ncd GetAccountBalance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The Casper.Network.SDK for .NET is published on ",(0,t.jsx)(n.a,{href:"https://www.nuget.org/packages/Casper.Network.SDK",children:"nuget.org"})," as a NuGet package."]}),"\n",(0,t.jsxs)(n.p,{children:["To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the ",(0,t.jsx)(n.code,{children:"dotnet"})," CLI tool."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Package Manager (Windows)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Install-Package Casper.Network.SDK\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"dotnet CLI Tool (Windows, Mac, and Linux)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet add package Casper.Network.SDK\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, replace the default code in ",(0,t.jsx)(n.code,{children:"Program.cs"})," with this main program:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'using System;\nusing System.Threading.Tasks;\nusing Casper.Network.SDK;\nusing Casper.Network.SDK.JsonRpc;\nusing Casper.Network.SDK.Types;\n\nnamespace Casper.NET.SDK.Examples\n{\n public class GetAccountBalance\n {\n public static async Task Main(string[] args)\n {\n string nodeAddress = "http://testnet-node.make.services:7777";\n\n var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";\n var publicKey = PublicKey.FromHexString(hex);\n\n try\n {\n var casperSdk = new NetCasperClient(nodeAddress);\n\n // Get the balance using the account public key\n //\n var rpcResponse = await casperSdk.GetAccountBalance(publicKey);\n Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);\n }\n catch (RpcClientException e)\n {\n Console.WriteLine("ERROR:\\n" + e.RpcError.Message);\n }\n catch (Exception e)\n {\n Console.WriteLine(e);\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, run the example with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet run\n"})}),"\n",(0,t.jsx)(n.p,{children:"The program will print the account's main purse balance retrieved from the testnet."}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find other examples, tutorials, and complete documentation for this SDK."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/074e7bdc.1512fa35.js b/assets/js/074e7bdc.1512fa35.js new file mode 100644 index 000000000..777762e49 --- /dev/null +++ b/assets/js/074e7bdc.1512fa35.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62289],{29066:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=s(74848),t=s(28453);const a={title:"Archive and Restore a DB"},o="Archiving and Restoring a Database",i={id:"operators/maintenance/archiving-and-restoring",title:"Archive and Restore a DB",description:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.",source:"@site/docs/operators/maintenance/archiving-and-restoring.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/archiving-and-restoring",permalink:"/operators/maintenance/archiving-and-restoring",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Archive and Restore a DB"},sidebar:"operators",previous:{title:"Node Maintenance",permalink:"/operators/maintenance/"},next:{title:"Move a Node",permalink:"/operators/maintenance/moving-node"}},d={},c=[{value:"Zstandard Limitations",id:"zstandard-limitations",level:2},{value:"Zstandard Installation",id:"zstandard-installation",level:2},{value:"Initial Warnings",id:"initial-warnings",level:2},{value:"Compression",id:"compression",level:2},{value:"Compression level",id:"compression-level",level:3},{value:"Thread count",id:"thread-count",level:3},{value:"Long-distance matching",id:"long-distance-matching",level:3},{value:"Summary of commands",id:"summary-of-commands",level:3},{value:"Decompression",id:"decompression",level:2},{value:"Streamed Decompression",id:"streamed-decompression",level:2},{value:"Starting a New Node with a Decompressed DB",id:"starting-a-new-node-with-a-decompressed-db",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"archiving-and-restoring-a-database",children:"Archiving and Restoring a Database"})}),"\n",(0,r.jsx)(n.p,{children:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"http://facebook.github.io/zstd/",children:"Zstandard"})," is the best method for compression speed and space for the current LMDB-based database system that the ",(0,r.jsx)(n.code,{children:"casper-node"})," uses."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The values presented in this document assume that the ",(0,r.jsx)(n.code,{children:"trie-compact"})," tool was run on a Mainnet database for compression. Contact the ",(0,r.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb",children:"support team"})," if you have questions."]})}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-limitations",children:"Zstandard Limitations"}),"\n",(0,r.jsxs)(n.p,{children:["The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use ",(0,r.jsx)(n.code,{children:"tar"})," as a pre-filter for stripping sparse data, as shown ",(0,r.jsx)(n.a,{href:"#compression",children:"here"}),", thus eliminating the need to read the full DB size and improving processing."]}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-installation",children:"Zstandard Installation"}),"\n",(0,r.jsx)(n.p,{children:"To install Zstandard, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo apt install zstd\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation."}),"\n",(0,r.jsx)(n.h2,{id:"initial-warnings",children:"Initial Warnings"}),"\n",(0,r.jsxs)(n.p,{children:["You need to stop the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," process of the node (and, therefore, the ",(0,r.jsx)(n.code,{children:"casper-node"})," process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur."]}),"\n",(0,r.jsx)(n.h2,{id:"compression",children:"Compression"}),"\n",(0,r.jsxs)(n.p,{children:["Run the following basic ",(0,r.jsx)(n.code,{children:"tar"})," command from the DB directory. For Mainnet, the directory would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper"}),", and for Testnet it would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper-test"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -cv --sparse .\n"})}),"\n",(0,r.jsx)(n.p,{children:"On some systems, you may get better performance if you specify the block number as an argument:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse .\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then stream the result into ",(0,r.jsx)(n.code,{children:"zstd"}),". The sections below discuss the ",(0,r.jsx)(n.a,{href:"#compression-level",children:"level"}),", ",(0,r.jsx)(n.a,{href:"#thread-count",children:"thread count"}),", and ",(0,r.jsx)(n.a,{href:"#long-distance-matching",children:"long"})," arguments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compression-level",children:"Compression level"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-[level]"})," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."]}),"\n",(0,r.jsx)(n.p,{children:"Here are some examples of a Mainnet DB compression at block 741160:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Level"}),(0,r.jsx)(n.th,{children:"Time (min:sec)"}),(0,r.jsx)(n.th,{children:"Size"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"12"}),(0,r.jsx)(n.td,{children:"29:20"}),(0,r.jsx)(n.td,{children:"15.8 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"15"}),(0,r.jsx)(n.td,{children:"46:15"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"17"}),(0,r.jsx)(n.td,{children:"87:42"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"19"}),(0,r.jsx)(n.td,{children:"197:08"}),(0,r.jsx)(n.td,{children:"12.9 GB"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For local backups, using 1-5 is a great compression speed-to-size trade-off."}),"\n",(0,r.jsx)(n.h3,{id:"thread-count",children:"Thread count"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-T[thread count]"})," is the number of threads that ",(0,r.jsx)(n.code,{children:"zstd"})," should use for compression. If running a script or command on varying machines, use ",(0,r.jsx)(n.code,{children:"T0"})," to allow ",(0,r.jsx)(n.code,{children:"zstd"})," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,r.jsx)(n.code,{children:"-T0"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"long-distance-matching",children:"Long-distance matching"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"--long=31"})," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."]}),"\n",(0,r.jsxs)(n.p,{children:["At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,r.jsx)(n.code,{children:"--long=31"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."}),"\n",(0,r.jsx)(n.h3,{id:"summary-of-commands",children:"Summary of commands"}),"\n",(0,r.jsx)(n.p,{children:"The general command for compression is:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.p,{children:"For local backups, use a lower compression level:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h2,{id:"decompression",children:"Decompression"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zstd -d"})," is the command for decompression; however, the same ",(0,r.jsx)(n.code,{children:"--long"})," value used for compression must be specified. For all ",(0,r.jsx)(n.code,{children:"casper-node"})," DB-related decompression, you will likely use this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"--long=31"})," is omitted, you might see an error such as this, which also gives you the solution:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding \n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then use the ",(0,r.jsx)(n.code,{children:"zstd"})," result to populate a ",(0,r.jsx)(n.code,{children:"tar -xv"})," command. Also, create the decompressed files using ",(0,r.jsx)(n.code,{children:"sudo -u casper"}),", because the files will be used by the ",(0,r.jsx)(n.code,{children:"casper-node"}),". Run the following command inside an empty DB location:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.p,{children:"To fix ownership, use this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py fix_permissions\n"})}),"\n",(0,r.jsx)(n.h2,{id:"streamed-decompression",children:"Streamed Decompression"}),"\n",(0,r.jsxs)(n.p,{children:["If a ",(0,r.jsx)(n.code,{children:".tar.zst"})," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,r.jsx)(n.code,{children:"curl"}),", which can output to stdout with ",(0,r.jsx)(n.code,{children:"--output"})," and stream binary to your terminal."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - \n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you use the output along with the previous process, you can decompress the files from ",(0,r.jsx)(n.code,{children:"curl"})," directly into a local directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - | zstd -d --long=31 | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"starting-a-new-node-with-a-decompressed-db",children:"Starting a New Node with a Decompressed DB"}),"\n",(0,r.jsxs)(n.p,{children:["If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,r.jsx)(n.code,{children:"node_util.py"})," script included in the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," installation."]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py force_run_version 1_4_5\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/074e7bdc.4eb0678a.js b/assets/js/074e7bdc.4eb0678a.js deleted file mode 100644 index 41305f93f..000000000 --- a/assets/js/074e7bdc.4eb0678a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2289],{29066:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=s(74848),t=s(28453);const a={title:"Archive and Restore a DB"},o="Archiving and Restoring a Database",i={id:"operators/maintenance/archiving-and-restoring",title:"Archive and Restore a DB",description:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.",source:"@site/docs/operators/maintenance/archiving-and-restoring.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/archiving-and-restoring",permalink:"/next/operators/maintenance/archiving-and-restoring",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Archive and Restore a DB"},sidebar:"operators",previous:{title:"Node Maintenance",permalink:"/next/operators/maintenance/"},next:{title:"Move a Node",permalink:"/next/operators/maintenance/moving-node"}},d={},c=[{value:"Zstandard Limitations",id:"zstandard-limitations",level:2},{value:"Zstandard Installation",id:"zstandard-installation",level:2},{value:"Initial Warnings",id:"initial-warnings",level:2},{value:"Compression",id:"compression",level:2},{value:"Compression level",id:"compression-level",level:3},{value:"Thread count",id:"thread-count",level:3},{value:"Long-distance matching",id:"long-distance-matching",level:3},{value:"Summary of commands",id:"summary-of-commands",level:3},{value:"Decompression",id:"decompression",level:2},{value:"Streamed Decompression",id:"streamed-decompression",level:2},{value:"Starting a New Node with a Decompressed DB",id:"starting-a-new-node-with-a-decompressed-db",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"archiving-and-restoring-a-database",children:"Archiving and Restoring a Database"})}),"\n",(0,r.jsx)(n.p,{children:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"http://facebook.github.io/zstd/",children:"Zstandard"})," is the best method for compression speed and space for the current LMDB-based database system that the ",(0,r.jsx)(n.code,{children:"casper-node"})," uses."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The values presented in this document assume that the ",(0,r.jsx)(n.code,{children:"trie-compact"})," tool was run on a Mainnet database for compression. Contact the ",(0,r.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb",children:"support team"})," if you have questions."]})}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-limitations",children:"Zstandard Limitations"}),"\n",(0,r.jsxs)(n.p,{children:["The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use ",(0,r.jsx)(n.code,{children:"tar"})," as a pre-filter for stripping sparse data, as shown ",(0,r.jsx)(n.a,{href:"#compression",children:"here"}),", thus eliminating the need to read the full DB size and improving processing."]}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-installation",children:"Zstandard Installation"}),"\n",(0,r.jsx)(n.p,{children:"To install Zstandard, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo apt install zstd\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation."}),"\n",(0,r.jsx)(n.h2,{id:"initial-warnings",children:"Initial Warnings"}),"\n",(0,r.jsxs)(n.p,{children:["You need to stop the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," process of the node (and, therefore, the ",(0,r.jsx)(n.code,{children:"casper-node"})," process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur."]}),"\n",(0,r.jsx)(n.h2,{id:"compression",children:"Compression"}),"\n",(0,r.jsxs)(n.p,{children:["Run the following basic ",(0,r.jsx)(n.code,{children:"tar"})," command from the DB directory. For Mainnet, the directory would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper"}),", and for Testnet it would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper-test"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -cv --sparse .\n"})}),"\n",(0,r.jsx)(n.p,{children:"On some systems, you may get better performance if you specify the block number as an argument:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse .\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then stream the result into ",(0,r.jsx)(n.code,{children:"zstd"}),". The sections below discuss the ",(0,r.jsx)(n.a,{href:"#compression-level",children:"level"}),", ",(0,r.jsx)(n.a,{href:"#thread-count",children:"thread count"}),", and ",(0,r.jsx)(n.a,{href:"#long-distance-matching",children:"long"})," arguments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compression-level",children:"Compression level"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-[level]"})," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."]}),"\n",(0,r.jsx)(n.p,{children:"Here are some examples of a Mainnet DB compression at block 741160:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Level"}),(0,r.jsx)(n.th,{children:"Time (min:sec)"}),(0,r.jsx)(n.th,{children:"Size"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"12"}),(0,r.jsx)(n.td,{children:"29:20"}),(0,r.jsx)(n.td,{children:"15.8 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"15"}),(0,r.jsx)(n.td,{children:"46:15"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"17"}),(0,r.jsx)(n.td,{children:"87:42"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"19"}),(0,r.jsx)(n.td,{children:"197:08"}),(0,r.jsx)(n.td,{children:"12.9 GB"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For local backups, using 1-5 is a great compression speed-to-size trade-off."}),"\n",(0,r.jsx)(n.h3,{id:"thread-count",children:"Thread count"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-T[thread count]"})," is the number of threads that ",(0,r.jsx)(n.code,{children:"zstd"})," should use for compression. If running a script or command on varying machines, use ",(0,r.jsx)(n.code,{children:"T0"})," to allow ",(0,r.jsx)(n.code,{children:"zstd"})," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,r.jsx)(n.code,{children:"-T0"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"long-distance-matching",children:"Long-distance matching"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"--long=31"})," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."]}),"\n",(0,r.jsxs)(n.p,{children:["At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,r.jsx)(n.code,{children:"--long=31"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."}),"\n",(0,r.jsx)(n.h3,{id:"summary-of-commands",children:"Summary of commands"}),"\n",(0,r.jsx)(n.p,{children:"The general command for compression is:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.p,{children:"For local backups, use a lower compression level:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h2,{id:"decompression",children:"Decompression"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zstd -d"})," is the command for decompression; however, the same ",(0,r.jsx)(n.code,{children:"--long"})," value used for compression must be specified. For all ",(0,r.jsx)(n.code,{children:"casper-node"})," DB-related decompression, you will likely use this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"--long=31"})," is omitted, you might see an error such as this, which also gives you the solution:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding \n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then use the ",(0,r.jsx)(n.code,{children:"zstd"})," result to populate a ",(0,r.jsx)(n.code,{children:"tar -xv"})," command. Also, create the decompressed files using ",(0,r.jsx)(n.code,{children:"sudo -u casper"}),", because the files will be used by the ",(0,r.jsx)(n.code,{children:"casper-node"}),". Run the following command inside an empty DB location:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.p,{children:"To fix ownership, use this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py fix_permissions\n"})}),"\n",(0,r.jsx)(n.h2,{id:"streamed-decompression",children:"Streamed Decompression"}),"\n",(0,r.jsxs)(n.p,{children:["If a ",(0,r.jsx)(n.code,{children:".tar.zst"})," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,r.jsx)(n.code,{children:"curl"}),", which can output to stdout with ",(0,r.jsx)(n.code,{children:"--output"})," and stream binary to your terminal."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - \n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you use the output along with the previous process, you can decompress the files from ",(0,r.jsx)(n.code,{children:"curl"})," directly into a local directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - | zstd -d --long=31 | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"starting-a-new-node-with-a-decompressed-db",children:"Starting a New Node with a Decompressed DB"}),"\n",(0,r.jsxs)(n.p,{children:["If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,r.jsx)(n.code,{children:"node_util.py"})," script included in the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," installation."]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py force_run_version 1_4_5\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0753c93f.38bf38b5.js b/assets/js/0753c93f.38bf38b5.js deleted file mode 100644 index 91a500bd3..000000000 --- a/assets/js/0753c93f.38bf38b5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8579],{46963:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>h});var t=s(74848),d=s(28453);const r={title:"OpCode Costs Tables"},i="OpCode Costs Tables",c={id:"developers/cli/opcode-costs",title:"OpCode Costs Tables",description:"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.",source:"@site/versioned_docs/version-1.5.X/developers/cli/opcode-costs.md",sourceDirName:"developers/cli",slug:"/developers/cli/opcode-costs",permalink:"/developers/cli/opcode-costs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"OpCode Costs Tables"},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/developers/cli/calling-contracts"},next:{title:"Execution Error Codes",permalink:"/developers/cli/execution-error-codes"}},l={},h=[{value:"Storage Costs",id:"storage-costs",level:2},{value:"OpCode Costs",id:"opcode-costs",level:2},{value:"Control Flow Operation Costs",id:"control-flow-operation-costs",level:2},{value:"Br_Table OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"Protocol Operating Costs",id:"protocol-operating-costs",level:2},{value:"Auction System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"Mint System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"Handle_Payment System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"Standard_Payment System Contract Costs",id:"standard_payment-system-contract-costs",level:3}];function o(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"opcode-costs-tables",children:"OpCode Costs Tables"})}),"\n",(0,t.jsxs)(e.p,{children:["The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,t.jsx)(e.code,{children:"chainspec.toml"}),"."]}),"\n",(0,t.jsxs)(e.p,{children:["More information on ",(0,t.jsx)(e.code,{children:"chainspec"}),"s for private networks can be found ",(0,t.jsx)(e.a,{href:"/operators/setup-network/chain-spec",children:"here"})]}),"\n",(0,t.jsx)(e.admonition,{type:"note",children:(0,t.jsxs)(e.p,{children:["All costs in this table are in ",(0,t.jsx)(e.a,{href:"/concepts/glossary/M/#motes",children:"motes"}),", not CSPR, and the corresponding chainspec is ",(0,t.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129",children:"here"}),"."]})}),"\n",(0,t.jsx)(e.h2,{id:"storage-costs",children:"Storage Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"gas_per_byte"}),(0,t.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,t.jsx)(e.td,{children:"630,000"})]})})]}),"\n",(0,t.jsx)(e.h2,{id:"opcode-costs",children:"OpCode Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"bit"}),(0,t.jsx)(e.td,{children:"Bit operations multiplier."}),(0,t.jsx)(e.td,{children:"300"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,t.jsx)(e.td,{children:"210"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mul"}),(0,t.jsx)(e.td,{children:"Mul operations multiplier."}),(0,t.jsx)(e.td,{children:"240"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"div"}),(0,t.jsx)(e.td,{children:"Div operations multiplier."}),(0,t.jsx)(e.td,{children:"320"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load"}),(0,t.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,t.jsx)(e.td,{children:"2_500"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"store"}),(0,t.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,t.jsx)(e.td,{children:"4,700"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"const"}),(0,t.jsx)(e.td,{children:"Const store operation multiplier."}),(0,t.jsx)(e.td,{children:"110"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"local"}),(0,t.jsx)(e.td,{children:"Local operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"global"}),(0,t.jsx)(e.td,{children:"Global operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"integer_comparison"}),(0,t.jsx)(e.td,{children:"Integer operations multiplier."}),(0,t.jsx)(e.td,{children:"250"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"conversion"}),(0,t.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,t.jsx)(e.td,{children:"420"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"unreachable"}),(0,t.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,t.jsx)(e.td,{children:"270"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"nop"}),(0,t.jsx)(e.td,{children:"Nop operation multiplier."}),(0,t.jsx)(e.td,{children:"200"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"current_memory"}),(0,t.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,t.jsx)(e.td,{children:"290"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"grow_memory"}),(0,t.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,t.jsx)(e.td,{children:"240,000"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"control-flow-operation-costs",children:"Control Flow Operation Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"block"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"block"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"loop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"loop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"if"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"else"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"else"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"end"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"end"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br"})," opcode."]}),(0,t.jsx)(e.td,{children:"35_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br_if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,t.jsx)(e.td,{children:"35,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"return"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"return"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"select"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"select"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call"})," opcode."]}),(0,t.jsx)(e.td,{children:"68_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_indirect"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,t.jsx)(e.td,{children:"68,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"drop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"drop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,t.jsxs)(e.h2,{id:"br_table-opcode-costs",children:[(0,t.jsx)(e.code,{children:"Br_Table"})," OpCode Costs"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"cost"}),(0,t.jsxs)(e.td,{children:["Fixed cost per ",(0,t.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,t.jsx)(e.td,{children:"35,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"size_multiplier"}),(0,t.jsxs)(e.td,{children:["Size of target labels in the ",(0,t.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,t.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,t.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"external-function-costs",children:"External Function Costs"}),"\n",(0,t.jsxs)(e.p,{children:['The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,t.jsx)(e.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Host-Side Function"}),(0,t.jsx)(e.th,{children:"Cost"}),(0,t.jsx)(e.th,{children:"Arguments"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"5,800"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_associated_key"}),(0,t.jsx)(e.td,{children:"9,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"blake2b"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_contract"}),(0,t.jsx)(e.td,{children:"4,500"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 420, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_versioned_contract"}),(0,t.jsx)(e.td,{children:"4,500"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 420, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_purse"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"disable_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_balance"}),(0,t.jsx)(e.td,{children:"3,800"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_blocktime"}),(0,t.jsx)(e.td,{children:"330"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_caller"}),(0,t.jsx)(e.td,{children:"380"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_key"}),(0,t.jsx)(e.td,{children:"2,000"}),(0,t.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_main_purse"}),(0,t.jsx)(e.td,{children:"1,300"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg_size"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_phase"}),(0,t.jsx)(e.td,{children:"710"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_system_contract"}),(0,t.jsx)(e.td,{children:"1,100"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"has_key"}),(0,t.jsx)(e.td,{children:"1,500"}),(0,t.jsx)(e.td,{children:"[0, 840]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"is_valid_uref"}),(0,t.jsx)(e.td,{children:"760"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load_named_keys"}),(0,t.jsx)(e.td,{children:"42,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"new_uref"}),(0,t.jsx)(e.td,{children:"17,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"random_bytes"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"print"}),(0,t.jsx)(e.td,{children:"20,000"}),(0,t.jsx)(e.td,{children:"[0, 4,600]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"put_key"}),(0,t.jsx)(e.td,{children:"38,000"}),(0,t.jsx)(e.td,{children:"[0, 1,100, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_host_buffer"}),(0,t.jsx)(e.td,{children:"3,500"}),(0,t.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value"}),(0,t.jsx)(e.td,{children:"6,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value_local"}),(0,t.jsx)(e.td,{children:"5,500"}),(0,t.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_associated_key"}),(0,t.jsx)(e.td,{children:"4,200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_key"}),(0,t.jsx)(e.td,{children:"61,000"}),(0,t.jsx)(e.td,{children:"[0, 3,200]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"ret"}),(0,t.jsx)(e.td,{children:"23,000"}),(0,t.jsx)(e.td,{children:"[0, 420,000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"revert"}),(0,t.jsx)(e.td,{children:"500"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_action_threshold"}),(0,t.jsx)(e.td,{children:"74,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,t.jsx)(e.td,{children:"82,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_to_account"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"update_associated_key"}),(0,t.jsx)(e.td,{children:"4,200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"write"}),(0,t.jsx)(e.td,{children:"14,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"write_local"}),(0,t.jsx)(e.td,{children:"9,500"}),(0,t.jsx)(e.td,{children:"[0, 1,800, 0, 520]"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"protocol-operating-costs",children:"Protocol Operating Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"wasmless_transfer_cost"}),(0,t.jsx)(e.td,{children:"Default gas cost for a wasmless transfer."}),(0,t.jsx)(e.td,{children:"100,000,000"})]})})]}),"\n",(0,t.jsxs)(e.h3,{id:"auction-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Auction"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_era_validators"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"delegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"undelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"run_auction"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"slash"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"distribute"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_era_id"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"activate_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"redelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"mint-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Mint"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"reduce_total_supply"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"balance"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_base_round_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"handle_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Handle_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_payment_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"finalize_payment"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"standard_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Standard_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"pay"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,t.jsx)(e.td,{children:"10,000"})]})})]})]})}function x(n={}){const{wrapper:e}={...(0,d.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(o,{...n})}):o(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>i,x:()=>c});var t=s(96540);const d={},r=t.createContext(d);function i(n){const e=t.useContext(r);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(d):n.components||d:i(n.components),t.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/0753c93f.c3fc9760.js b/assets/js/0753c93f.c3fc9760.js new file mode 100644 index 000000000..4c43b96d2 --- /dev/null +++ b/assets/js/0753c93f.c3fc9760.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28579],{46963:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>h});var t=s(74848),d=s(28453);const r={title:"OpCode Costs Tables"},i="OpCode Costs Tables",c={id:"developers/cli/opcode-costs",title:"OpCode Costs Tables",description:"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.",source:"@site/versioned_docs/version-1.5.X/developers/cli/opcode-costs.md",sourceDirName:"developers/cli",slug:"/developers/cli/opcode-costs",permalink:"/1.5.X/developers/cli/opcode-costs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"OpCode Costs Tables"},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/1.5.X/developers/cli/calling-contracts"},next:{title:"Execution Error Codes",permalink:"/1.5.X/developers/cli/execution-error-codes"}},l={},h=[{value:"Storage Costs",id:"storage-costs",level:2},{value:"OpCode Costs",id:"opcode-costs",level:2},{value:"Control Flow Operation Costs",id:"control-flow-operation-costs",level:2},{value:"Br_Table OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"Protocol Operating Costs",id:"protocol-operating-costs",level:2},{value:"Auction System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"Mint System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"Handle_Payment System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"Standard_Payment System Contract Costs",id:"standard_payment-system-contract-costs",level:3}];function o(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"opcode-costs-tables",children:"OpCode Costs Tables"})}),"\n",(0,t.jsxs)(e.p,{children:["The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,t.jsx)(e.code,{children:"chainspec.toml"}),"."]}),"\n",(0,t.jsxs)(e.p,{children:["More information on ",(0,t.jsx)(e.code,{children:"chainspec"}),"s for private networks can be found ",(0,t.jsx)(e.a,{href:"/1.5.X/operators/setup-network/chain-spec",children:"here"})]}),"\n",(0,t.jsx)(e.admonition,{type:"note",children:(0,t.jsxs)(e.p,{children:["All costs in this table are in ",(0,t.jsx)(e.a,{href:"/concepts/glossary/M/#motes",children:"motes"}),", not CSPR, and the corresponding chainspec is ",(0,t.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129",children:"here"}),"."]})}),"\n",(0,t.jsx)(e.h2,{id:"storage-costs",children:"Storage Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"gas_per_byte"}),(0,t.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,t.jsx)(e.td,{children:"630,000"})]})})]}),"\n",(0,t.jsx)(e.h2,{id:"opcode-costs",children:"OpCode Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"bit"}),(0,t.jsx)(e.td,{children:"Bit operations multiplier."}),(0,t.jsx)(e.td,{children:"300"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,t.jsx)(e.td,{children:"210"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mul"}),(0,t.jsx)(e.td,{children:"Mul operations multiplier."}),(0,t.jsx)(e.td,{children:"240"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"div"}),(0,t.jsx)(e.td,{children:"Div operations multiplier."}),(0,t.jsx)(e.td,{children:"320"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load"}),(0,t.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,t.jsx)(e.td,{children:"2_500"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"store"}),(0,t.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,t.jsx)(e.td,{children:"4,700"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"const"}),(0,t.jsx)(e.td,{children:"Const store operation multiplier."}),(0,t.jsx)(e.td,{children:"110"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"local"}),(0,t.jsx)(e.td,{children:"Local operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"global"}),(0,t.jsx)(e.td,{children:"Global operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"integer_comparison"}),(0,t.jsx)(e.td,{children:"Integer operations multiplier."}),(0,t.jsx)(e.td,{children:"250"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"conversion"}),(0,t.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,t.jsx)(e.td,{children:"420"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"unreachable"}),(0,t.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,t.jsx)(e.td,{children:"270"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"nop"}),(0,t.jsx)(e.td,{children:"Nop operation multiplier."}),(0,t.jsx)(e.td,{children:"200"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"current_memory"}),(0,t.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,t.jsx)(e.td,{children:"290"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"grow_memory"}),(0,t.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,t.jsx)(e.td,{children:"240,000"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"control-flow-operation-costs",children:"Control Flow Operation Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"block"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"block"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"loop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"loop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"if"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"else"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"else"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"end"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"end"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br"})," opcode."]}),(0,t.jsx)(e.td,{children:"35_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br_if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,t.jsx)(e.td,{children:"35,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"return"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"return"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"select"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"select"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call"})," opcode."]}),(0,t.jsx)(e.td,{children:"68_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_indirect"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,t.jsx)(e.td,{children:"68,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"drop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"drop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,t.jsxs)(e.h2,{id:"br_table-opcode-costs",children:[(0,t.jsx)(e.code,{children:"Br_Table"})," OpCode Costs"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"cost"}),(0,t.jsxs)(e.td,{children:["Fixed cost per ",(0,t.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,t.jsx)(e.td,{children:"35,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"size_multiplier"}),(0,t.jsxs)(e.td,{children:["Size of target labels in the ",(0,t.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,t.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,t.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"external-function-costs",children:"External Function Costs"}),"\n",(0,t.jsxs)(e.p,{children:['The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,t.jsx)(e.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Host-Side Function"}),(0,t.jsx)(e.th,{children:"Cost"}),(0,t.jsx)(e.th,{children:"Arguments"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"5,800"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_associated_key"}),(0,t.jsx)(e.td,{children:"9,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"blake2b"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_contract"}),(0,t.jsx)(e.td,{children:"4,500"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 420, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_versioned_contract"}),(0,t.jsx)(e.td,{children:"4,500"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 420, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_purse"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"disable_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_balance"}),(0,t.jsx)(e.td,{children:"3,800"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_blocktime"}),(0,t.jsx)(e.td,{children:"330"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_caller"}),(0,t.jsx)(e.td,{children:"380"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_key"}),(0,t.jsx)(e.td,{children:"2,000"}),(0,t.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_main_purse"}),(0,t.jsx)(e.td,{children:"1,300"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg_size"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_phase"}),(0,t.jsx)(e.td,{children:"710"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_system_contract"}),(0,t.jsx)(e.td,{children:"1,100"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"has_key"}),(0,t.jsx)(e.td,{children:"1,500"}),(0,t.jsx)(e.td,{children:"[0, 840]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"is_valid_uref"}),(0,t.jsx)(e.td,{children:"760"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load_named_keys"}),(0,t.jsx)(e.td,{children:"42,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"new_uref"}),(0,t.jsx)(e.td,{children:"17,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"random_bytes"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"print"}),(0,t.jsx)(e.td,{children:"20,000"}),(0,t.jsx)(e.td,{children:"[0, 4,600]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"put_key"}),(0,t.jsx)(e.td,{children:"38,000"}),(0,t.jsx)(e.td,{children:"[0, 1,100, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_host_buffer"}),(0,t.jsx)(e.td,{children:"3,500"}),(0,t.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value"}),(0,t.jsx)(e.td,{children:"6,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value_local"}),(0,t.jsx)(e.td,{children:"5,500"}),(0,t.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_associated_key"}),(0,t.jsx)(e.td,{children:"4,200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_key"}),(0,t.jsx)(e.td,{children:"61,000"}),(0,t.jsx)(e.td,{children:"[0, 3,200]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"ret"}),(0,t.jsx)(e.td,{children:"23,000"}),(0,t.jsx)(e.td,{children:"[0, 420,000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"revert"}),(0,t.jsx)(e.td,{children:"500"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_action_threshold"}),(0,t.jsx)(e.td,{children:"74,000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,t.jsx)(e.td,{children:"82,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_to_account"}),(0,t.jsx)(e.td,{children:"2,500,000,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"update_associated_key"}),(0,t.jsx)(e.td,{children:"4,200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"write"}),(0,t.jsx)(e.td,{children:"14,000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"write_local"}),(0,t.jsx)(e.td,{children:"9,500"}),(0,t.jsx)(e.td,{children:"[0, 1,800, 0, 520]"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"protocol-operating-costs",children:"Protocol Operating Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"wasmless_transfer_cost"}),(0,t.jsx)(e.td,{children:"Default gas cost for a wasmless transfer."}),(0,t.jsx)(e.td,{children:"100,000,000"})]})})]}),"\n",(0,t.jsxs)(e.h3,{id:"auction-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Auction"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_era_validators"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"delegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"undelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"run_auction"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"slash"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"distribute"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_era_id"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"activate_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"redelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"mint-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Mint"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"reduce_total_supply"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"balance"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_base_round_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2,500,000,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"handle_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Handle_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_payment_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"finalize_payment"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10,000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"standard_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Standard_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"pay"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,t.jsx)(e.td,{children:"10,000"})]})})]})]})}function x(n={}){const{wrapper:e}={...(0,d.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(o,{...n})}):o(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>i,x:()=>c});var t=s(96540);const d={},r=t.createContext(d);function i(n){const e=t.useContext(r);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(d):n.components||d:i(n.components),t.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/0791978c.6cb20991.js b/assets/js/0791978c.6cb20991.js deleted file mode 100644 index 4888d9248..000000000 --- a/assets/js/0791978c.6cb20991.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2905],{22285:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var a=t(74848),c=t(28453);const s={title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},r="Cross-Contract Communication",o={id:"resources/advanced/cross-contract",title:"Cross-Contract Communication",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-1.5.X/resources/advanced/cross-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/cross-contract",permalink:"/resources/tutorials/advanced/cross-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},sidebar:"tutorials",previous:{title:"Storage Workflow",permalink:"/resources/tutorials/advanced/storage-workflow"}},d={},i=[{value:"Tutorial Outline",id:"outline",level:2},{value:"Creating the Project",id:"create-project",level:2},{value:"Changing the Standard Contract",id:"changing-contract",level:2},{value:"Deploying the Contract",id:"deploying-contract",level:2},{value:"Create Another Contract for the Cross-Contract Call",id:"cross-contract",level:2},{value:"Summary",id:"summary",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cross-contract-communication",children:"Cross-Contract Communication"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"outline",children:"Tutorial Outline"}),"\n",(0,a.jsx)(n.p,{children:"This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol."}),"\n",(0,a.jsx)(n.p,{children:"Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose. The contracts are as follows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Factory"}),"\n",(0,a.jsx)(n.li,{children:"Pair"}),"\n",(0,a.jsx)(n.li,{children:"Pair (ERC20)"}),"\n",(0,a.jsx)(n.li,{children:"Library"}),"\n",(0,a.jsx)(n.li,{children:"Router01"}),"\n",(0,a.jsx)(n.li,{children:"Router02"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash. The Pair smart contract is used to perform operations like mint or burn on a created pair of tokens."}),"\n",(0,a.jsx)(n.p,{children:"Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called."}),"\n",(0,a.jsx)(n.h2,{id:"create-project",children:"Creating the Project"}),"\n",(0,a.jsx)(n.p,{children:"In the appropriate folder, create the project for the contract using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cargo casper cross-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will create the following directory structure within your smart contract folder."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cross-contract\n\u251c\u2500\u2500contract\n\u2502 \u251c\u2500\u2500 Cargo.toml\n\u2502\xa0\xa0 \u251c\u2500\u2500 rust-toolchain\n\u2502\xa0\xa0 \u251c\u2500\u2500 src\n\u2502\xa0\xa0 \u2502\xa0\xa0 \u2514\u2500\u2500 main.rs\n\u2502\xa0\xa0 \u2514\u2500\u2500 target\n\u251c\u2500\u2500tests\n\u2502 \u251c\u2500\u2500 Cargo.toml\n\u2502 \u251c\u2500\u2500 src\n\u2502 \u2502\xa0\xa0 \u2514\u2500\u2500 integration_tests.rs\n\u2502 \u2514\u2500\u2500 target\n\u2514\u2500\u2500 Makefile\n"})}),"\n",(0,a.jsx)(n.p,{children:"After creating the project directory structure, use the following commands to go into the project folder and compile the files:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This will produce the ",(0,a.jsx)(n.code,{children:".wasm"})," file of our contract. It can be found in ",(0,a.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),". Additionally you can check if the tests can be performed using the following command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"When you try to run the tests, you might encounter errors if the project's dependencies are outdated. If you see an error message similar to the following:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'warning: `tests` (bin "integration-tests" test) generated 2 warnings\nerror: could not compile `tests` due to 3 previous errors; 2 warnings emitted\nmake: *** [test] Error 101\n'})}),(0,a.jsxs)(n.p,{children:["This indicates potential issues with outdated dependencies. Use the ",(0,a.jsx)(n.code,{children:"cargo update"})," command to check for and install any available updates for your project's dependencies or do it manually through ",(0,a.jsx)(n.code,{children:"Cargo.toml"})," file."]}),(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:t(34006).A+"",width:"1570",height:"614"})}),(0,a.jsx)(n.p,{children:"If you are using cargo extensions in your editor you will see a warning next to the outdated dependencies."})]}),"\n",(0,a.jsx)(n.h2,{id:"changing-contract",children:"Changing the Standard Contract"}),"\n",(0,a.jsxs)(n.p,{children:["The standard Casper contract from ",(0,a.jsx)(n.code,{children:"cargo-casper"})," contains some methods that we will reuse. However, we will remove most of the automatically generated code."]}),"\n",(0,a.jsxs)(n.p,{children:["We will be changing the ",(0,a.jsx)(n.code,{children:"main.rs"})," file. Your code should look exactly as below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"This will serve as a base for introducing the elements needed for cross-contract communication."}),"\n",(0,a.jsxs)(n.p,{children:["In a contract, you should first define the ",(0,a.jsx)(n.code,{children:"call"})," entry point. It should be understood as a ",(0,a.jsx)(n.code,{children:"constructor"})," for the contract. Everything included in the ",(0,a.jsx)(n.code,{children:"call"})," entry point will be visible as metadata on a Casper network, in the contract's context. You should already be familiar with the ",(0,a.jsx)(n.code,{children:"call"})," entry point from the ",(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})," document. If this is not the case, be sure to familiarize yourself with it now."]}),"\n",(0,a.jsxs)(n.p,{children:["The contract code, with changes to the ",(0,a.jsx)(n.code,{children:"call"})," entry point, should look as shown below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Get the value of the runtime argument named "message"\n let value: String = runtime::get_named_arg("message");\n\n // The value will be written under a URef\n let value_ref = storage::new_uref(value);\n\n // Creating the new set of named keys\n // The keys are a Map of String/casper_types::Key\n let mut named_keys: BTreeMap = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector\n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"runtime"})," and ",(0,a.jsx)(n.code,{children:"storage"})," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"Contract API Modules"}),"."]})}),"\n",(0,a.jsxs)(n.p,{children:["The metadata for each of the contract's entry points is defined in the ",(0,a.jsx)(n.code,{children:"call"})," entry point. When installing the contract, the Casper Node will search for the entry point based on the name specified in its metadata. Therefore, each of the entry points defined in the code must share the same name as the ",(0,a.jsx)(n.code,{children:"String"})," value passed when defining the metadata for the entry point."]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"#[no_mangle]"})," attribute guarantees that the compiler won't alter the entry point's name. It doesn't mandate that the name matches its metadata definition, so developers need to be cautious when specifying entry points."]}),"\n",(0,a.jsxs)(n.p,{children:["In our case, we will define the entry point ",(0,a.jsx)(n.code,{children:"update_msg"})," in the contract code just before ",(0,a.jsx)(n.code,{children:"call"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract should match the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value\n let mut named_keys: BTreeMap = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector\n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["There is a distinction between storing data in a contract\u2019s ",(0,a.jsx)(n.code,{children:"NamedKeys"})," and using a dictionary. ",(0,a.jsx)(n.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application."]})}),"\n",(0,a.jsx)(n.h2,{id:"deploying-contract",children:"Deploying the Contract"}),"\n",(0,a.jsxs)(n.p,{children:["There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts#installing-contract-code",children:"put_deploy"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Be sure to go through the prerequisites from the ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})," documentation."]}),"\n",(0,a.jsx)(n.p,{children:"Make sure that after doing this you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"A valid private key for your account."}),"\n",(0,a.jsx)(n.li,{children:"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,a.jsx)(n.code,{children:"secret_key.pem"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Compile the contract in the contract directory so you obtain the contracts ",(0,a.jsx)(n.code,{children:".wasm"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this step everything is in place to deploy the contract."}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands."})}),"\n",(0,a.jsxs)(n.p,{children:["Since we are using a default contract structure, the command called from the ",(0,a.jsx)(n.code,{children:"cross-contract"})," folder should be the following:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,a.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," and ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installing contracts"}),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of this command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["To verify that the contract was successfully deployed, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," subcommand, providing as a parameter the ",(0,a.jsx)(n.code,{children:"deploy_hash"})," received from the ",(0,a.jsx)(n.code,{children:"put-deploy"})," above."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,a.jsx)(n.code,{children:"verbose"})," flag with the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand. Take time to familiarize yourself with the structure of the output."]}),"\n",(0,a.jsxs)(n.p,{children:["We can use the supplied deploy hash, ",(0,a.jsx)(n.code,{children:"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"})," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,a.jsx)(n.code,{children:"Success"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["From your ",(0,a.jsx)(n.code,{children:"cspr.live"})," account, you will find a tab called ",(0,a.jsx)(n.code,{children:"NamedKeys"}),". This tab includes a list of all contracts deployed using the private key connected to your account."]}),"\n",(0,a.jsxs)(n.p,{children:["By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."]}),"\n",(0,a.jsxs)(n.p,{children:["An additional tab, ",(0,a.jsx)(n.code,{children:"Deploys"}),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,a.jsx)(n.code,{children:"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"cross-contract",children:"Create Another Contract for the Cross-Contract Call"}),"\n",(0,a.jsxs)(n.p,{children:["This section describes the process of writing an additional contract, which will use an entry point titled ",(0,a.jsx)(n.code,{children:"call_contract_2"})," to invoke the ",(0,a.jsx)(n.code,{children:"update_msg"})," entry point on the previous contract."]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial we will be passing the contract hash, as an argument, into the ",(0,a.jsx)(n.code,{children:"call"})," entry point and use this to perform the calls to the destination contract."]}),"\n",(0,a.jsxs)(n.p,{children:["Prepare the ",(0,a.jsx)(n.code,{children:"call"})," entry point as described below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This would be the easiest implementation of the ",(0,a.jsx)(n.code,{children:"call"})," entry point. There is only one entry point which accepts the key ",(0,a.jsx)(n.code,{children:"contract2"})," of type ",(0,a.jsx)(n.code,{children:"String"})," and the key ",(0,a.jsx)(n.code,{children:"hello_world_contract"})," of the type ",(0,a.jsx)(n.code,{children:"Key"}),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."]}),"\n",(0,a.jsxs)(n.p,{children:["Now that we have defined the metadata for the ",(0,a.jsx)(n.code,{children:"call_contract_2"})," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,a.jsx)(n.code,{children:"update_msg"}),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter\n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract implementation should look as follows:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After you run ",(0,a.jsx)(n.code,{children:"make build-contract"})," in your second contract's directory, you should obtain the outcome:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder and copy the keys from the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder in the first contract into this subfolder. The call from the terminal will look as follows:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,a.jsx)(n.code,{children:"cargo casper"})," project. You can change this by editing the ",(0,a.jsx)(n.code,{children:"Makefile"})," in the main directory. You can then observe the result by recompiling your contract with these commands;"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})})]}),"\n",(0,a.jsx)(n.p,{children:"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys."})}),"\n",(0,a.jsx)(n.p,{children:"Observing the deploy, we can see that it succeeded:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"execution_results"}),' JSON element we should see "Success".']}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n\n }\n }\n }\n }\n ]\n\n'})}),"\n",(0,a.jsx)(n.p,{children:"Get the state root hash of the current network state:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the",(0,a.jsx)(n.code,{children:"get-state-root-hash"})," command is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Query the state of Casper network using the account hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:" casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n"})}),"\n",(0,a.jsx)(n.p,{children:"If we check the account's named keys, we can see all of the account's deployed contracts:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Account's named keys"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."}),"\n",(0,a.jsx)(n.p,{children:"The Uref of the message variable is stored under the Named Keys in the contract."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Checking the state of the message in the first contract, we observe the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This is a simple ",(0,a.jsx)(n.code,{children:"hello world"})," string. After invoking the entry point using the command below this value should change."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-hash"})," - is the contract hash, which is returned from the put-deploy."]}),(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-arg"}),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.']})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The contract hash has to be of type ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the contract itself. We can pass the hash as a ",(0,a.jsx)(n.code,{children:"Key"})," argument and change it to ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the smart contract."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Check the deploy with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n"})}),"\n",(0,a.jsx)(n.p,{children:"After the deploy finishes successfully, you should see a similar outcome to the following:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Deploy details"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"We would expect that the value of the message reference in the other contract would have changed, which we can check:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"With this we have succeeded in cross-contract communication between two contracts."}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"}),"\n",(0,a.jsx)(n.li,{children:"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},34006:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/CargoToml-0df722b819fb823a4a14d90b45076240.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const c={},s=a.createContext(c);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0791978c.8b8ea331.js b/assets/js/0791978c.8b8ea331.js new file mode 100644 index 000000000..576bea1a1 --- /dev/null +++ b/assets/js/0791978c.8b8ea331.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52905],{22285:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var a=t(74848),c=t(28453);const s={title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},r="Cross-Contract Communication",o={id:"resources/advanced/cross-contract",title:"Cross-Contract Communication",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-1.5.X/resources/advanced/cross-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/cross-contract",permalink:"/1.5.X/resources/tutorials/advanced/cross-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},sidebar:"tutorials",previous:{title:"Storage Workflow",permalink:"/1.5.X/resources/tutorials/advanced/storage-workflow"}},d={},i=[{value:"Tutorial Outline",id:"outline",level:2},{value:"Creating the Project",id:"create-project",level:2},{value:"Changing the Standard Contract",id:"changing-contract",level:2},{value:"Deploying the Contract",id:"deploying-contract",level:2},{value:"Create Another Contract for the Cross-Contract Call",id:"cross-contract",level:2},{value:"Summary",id:"summary",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cross-contract-communication",children:"Cross-Contract Communication"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"outline",children:"Tutorial Outline"}),"\n",(0,a.jsx)(n.p,{children:"This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol."}),"\n",(0,a.jsx)(n.p,{children:"Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose. The contracts are as follows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Factory"}),"\n",(0,a.jsx)(n.li,{children:"Pair"}),"\n",(0,a.jsx)(n.li,{children:"Pair (ERC20)"}),"\n",(0,a.jsx)(n.li,{children:"Library"}),"\n",(0,a.jsx)(n.li,{children:"Router01"}),"\n",(0,a.jsx)(n.li,{children:"Router02"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash. The Pair smart contract is used to perform operations like mint or burn on a created pair of tokens."}),"\n",(0,a.jsx)(n.p,{children:"Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called."}),"\n",(0,a.jsx)(n.h2,{id:"create-project",children:"Creating the Project"}),"\n",(0,a.jsx)(n.p,{children:"In the appropriate folder, create the project for the contract using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cargo casper cross-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will create the following directory structure within your smart contract folder."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cross-contract\n\u251c\u2500\u2500contract\n\u2502 \u251c\u2500\u2500 Cargo.toml\n\u2502\xa0\xa0 \u251c\u2500\u2500 rust-toolchain\n\u2502\xa0\xa0 \u251c\u2500\u2500 src\n\u2502\xa0\xa0 \u2502\xa0\xa0 \u2514\u2500\u2500 main.rs\n\u2502\xa0\xa0 \u2514\u2500\u2500 target\n\u251c\u2500\u2500tests\n\u2502 \u251c\u2500\u2500 Cargo.toml\n\u2502 \u251c\u2500\u2500 src\n\u2502 \u2502\xa0\xa0 \u2514\u2500\u2500 integration_tests.rs\n\u2502 \u2514\u2500\u2500 target\n\u2514\u2500\u2500 Makefile\n"})}),"\n",(0,a.jsx)(n.p,{children:"After creating the project directory structure, use the following commands to go into the project folder and compile the files:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This will produce the ",(0,a.jsx)(n.code,{children:".wasm"})," file of our contract. It can be found in ",(0,a.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),". Additionally you can check if the tests can be performed using the following command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"When you try to run the tests, you might encounter errors if the project's dependencies are outdated. If you see an error message similar to the following:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'warning: `tests` (bin "integration-tests" test) generated 2 warnings\nerror: could not compile `tests` due to 3 previous errors; 2 warnings emitted\nmake: *** [test] Error 101\n'})}),(0,a.jsxs)(n.p,{children:["This indicates potential issues with outdated dependencies. Use the ",(0,a.jsx)(n.code,{children:"cargo update"})," command to check for and install any available updates for your project's dependencies or do it manually through ",(0,a.jsx)(n.code,{children:"Cargo.toml"})," file."]}),(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:t(12572).A+"",width:"1570",height:"614"})}),(0,a.jsx)(n.p,{children:"If you are using cargo extensions in your editor you will see a warning next to the outdated dependencies."})]}),"\n",(0,a.jsx)(n.h2,{id:"changing-contract",children:"Changing the Standard Contract"}),"\n",(0,a.jsxs)(n.p,{children:["The standard Casper contract from ",(0,a.jsx)(n.code,{children:"cargo-casper"})," contains some methods that we will reuse. However, we will remove most of the automatically generated code."]}),"\n",(0,a.jsxs)(n.p,{children:["We will be changing the ",(0,a.jsx)(n.code,{children:"main.rs"})," file. Your code should look exactly as below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"This will serve as a base for introducing the elements needed for cross-contract communication."}),"\n",(0,a.jsxs)(n.p,{children:["In a contract, you should first define the ",(0,a.jsx)(n.code,{children:"call"})," entry point. It should be understood as a ",(0,a.jsx)(n.code,{children:"constructor"})," for the contract. Everything included in the ",(0,a.jsx)(n.code,{children:"call"})," entry point will be visible as metadata on a Casper network, in the contract's context. You should already be familiar with the ",(0,a.jsx)(n.code,{children:"call"})," entry point from the ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})," document. If this is not the case, be sure to familiarize yourself with it now."]}),"\n",(0,a.jsxs)(n.p,{children:["The contract code, with changes to the ",(0,a.jsx)(n.code,{children:"call"})," entry point, should look as shown below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Get the value of the runtime argument named "message"\n let value: String = runtime::get_named_arg("message");\n\n // The value will be written under a URef\n let value_ref = storage::new_uref(value);\n\n // Creating the new set of named keys\n // The keys are a Map of String/casper_types::Key\n let mut named_keys: BTreeMap = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector\n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"runtime"})," and ",(0,a.jsx)(n.code,{children:"storage"})," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"Contract API Modules"}),"."]})}),"\n",(0,a.jsxs)(n.p,{children:["The metadata for each of the contract's entry points is defined in the ",(0,a.jsx)(n.code,{children:"call"})," entry point. When installing the contract, the Casper Node will search for the entry point based on the name specified in its metadata. Therefore, each of the entry points defined in the code must share the same name as the ",(0,a.jsx)(n.code,{children:"String"})," value passed when defining the metadata for the entry point."]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"#[no_mangle]"})," attribute guarantees that the compiler won't alter the entry point's name. It doesn't mandate that the name matches its metadata definition, so developers need to be cautious when specifying entry points."]}),"\n",(0,a.jsxs)(n.p,{children:["In our case, we will define the entry point ",(0,a.jsx)(n.code,{children:"update_msg"})," in the contract code just before ",(0,a.jsx)(n.code,{children:"call"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract should match the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value\n let mut named_keys: BTreeMap = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector\n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys\n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["There is a distinction between storing data in a contract\u2019s ",(0,a.jsx)(n.code,{children:"NamedKeys"})," and using a dictionary. ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/dictionaries",children:"Dictionaries"})," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application."]})}),"\n",(0,a.jsx)(n.h2,{id:"deploying-contract",children:"Deploying the Contract"}),"\n",(0,a.jsxs)(n.p,{children:["There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts#installing-contract-code",children:"put_deploy"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Be sure to go through the prerequisites from the ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})," documentation."]}),"\n",(0,a.jsx)(n.p,{children:"Make sure that after doing this you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"A valid private key for your account."}),"\n",(0,a.jsx)(n.li,{children:"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,a.jsx)(n.code,{children:"secret_key.pem"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Compile the contract in the contract directory so you obtain the contracts ",(0,a.jsx)(n.code,{children:".wasm"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this step everything is in place to deploy the contract."}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands."})}),"\n",(0,a.jsxs)(n.p,{children:["Since we are using a default contract structure, the command called from the ",(0,a.jsx)(n.code,{children:"cross-contract"})," folder should be the following:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," and ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"installing contracts"}),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of this command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["To verify that the contract was successfully deployed, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," subcommand, providing as a parameter the ",(0,a.jsx)(n.code,{children:"deploy_hash"})," received from the ",(0,a.jsx)(n.code,{children:"put-deploy"})," above."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,a.jsx)(n.code,{children:"verbose"})," flag with the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand. Take time to familiarize yourself with the structure of the output."]}),"\n",(0,a.jsxs)(n.p,{children:["We can use the supplied deploy hash, ",(0,a.jsx)(n.code,{children:"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"})," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,a.jsx)(n.code,{children:"Success"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["From your ",(0,a.jsx)(n.code,{children:"cspr.live"})," account, you will find a tab called ",(0,a.jsx)(n.code,{children:"NamedKeys"}),". This tab includes a list of all contracts deployed using the private key connected to your account."]}),"\n",(0,a.jsxs)(n.p,{children:["By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."]}),"\n",(0,a.jsxs)(n.p,{children:["An additional tab, ",(0,a.jsx)(n.code,{children:"Deploys"}),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,a.jsx)(n.code,{children:"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"cross-contract",children:"Create Another Contract for the Cross-Contract Call"}),"\n",(0,a.jsxs)(n.p,{children:["This section describes the process of writing an additional contract, which will use an entry point titled ",(0,a.jsx)(n.code,{children:"call_contract_2"})," to invoke the ",(0,a.jsx)(n.code,{children:"update_msg"})," entry point on the previous contract."]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial we will be passing the contract hash, as an argument, into the ",(0,a.jsx)(n.code,{children:"call"})," entry point and use this to perform the calls to the destination contract."]}),"\n",(0,a.jsxs)(n.p,{children:["Prepare the ",(0,a.jsx)(n.code,{children:"call"})," entry point as described below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This would be the easiest implementation of the ",(0,a.jsx)(n.code,{children:"call"})," entry point. There is only one entry point which accepts the key ",(0,a.jsx)(n.code,{children:"contract2"})," of type ",(0,a.jsx)(n.code,{children:"String"})," and the key ",(0,a.jsx)(n.code,{children:"hello_world_contract"})," of the type ",(0,a.jsx)(n.code,{children:"Key"}),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."]}),"\n",(0,a.jsxs)(n.p,{children:["Now that we have defined the metadata for the ",(0,a.jsx)(n.code,{children:"call_contract_2"})," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,a.jsx)(n.code,{children:"update_msg"}),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter\n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract implementation should look as follows:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types\nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash,\n "update_msg",\n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys\n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After you run ",(0,a.jsx)(n.code,{children:"make build-contract"})," in your second contract's directory, you should obtain the outcome:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder and copy the keys from the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder in the first contract into this subfolder. The call from the terminal will look as follows:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,a.jsx)(n.code,{children:"cargo casper"})," project. You can change this by editing the ",(0,a.jsx)(n.code,{children:"Makefile"})," in the main directory. You can then observe the result by recompiling your contract with these commands;"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})})]}),"\n",(0,a.jsx)(n.p,{children:"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys."})}),"\n",(0,a.jsx)(n.p,{children:"Observing the deploy, we can see that it succeeded:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"execution_results"}),' JSON element we should see "Success".']}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n\n }\n }\n }\n }\n ]\n\n'})}),"\n",(0,a.jsx)(n.p,{children:"Get the state root hash of the current network state:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the",(0,a.jsx)(n.code,{children:"get-state-root-hash"})," command is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Query the state of Casper network using the account hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:" casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n"})}),"\n",(0,a.jsx)(n.p,{children:"If we check the account's named keys, we can see all of the account's deployed contracts:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Account's named keys"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."}),"\n",(0,a.jsx)(n.p,{children:"The Uref of the message variable is stored under the Named Keys in the contract."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Checking the state of the message in the first contract, we observe the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This is a simple ",(0,a.jsx)(n.code,{children:"hello world"})," string. After invoking the entry point using the command below this value should change."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-hash"})," - is the contract hash, which is returned from the put-deploy."]}),(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-arg"}),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.']})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The contract hash has to be of type ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the contract itself. We can pass the hash as a ",(0,a.jsx)(n.code,{children:"Key"})," argument and change it to ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the smart contract."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Check the deploy with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n"})}),"\n",(0,a.jsx)(n.p,{children:"After the deploy finishes successfully, you should see a similar outcome to the following:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Deploy details"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"We would expect that the value of the message reference in the other contract would have changed, which we can check:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"With this we have succeeded in cross-contract communication between two contracts."}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"}),"\n",(0,a.jsx)(n.li,{children:"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},12572:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/CargoToml-0df722b819fb823a4a14d90b45076240.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const c={},s=a.createContext(c);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/08996e66.378c3d02.js b/assets/js/08996e66.378c3d02.js deleted file mode 100644 index 31e8b0441..000000000 --- a/assets/js/08996e66.378c3d02.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4426],{57450:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="SDK Client Library Usage",i={id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/docs/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/next/developers/dapps/sdk/client-library-usage",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/next/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/next/developers/dapps/sdk/script-sdk"}},l={},o=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sdk-client-library-usage",children:"SDK Client Library Usage"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-sdks",children:"Installing the SDKs"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"npm"})," or ",(0,t.jsx)(n.code,{children:"yarn"})," to install the ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-js-sdk",children:"casper-js-sdk"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn install casper-js-sdk\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:(0,t.jsx)(n.code,{children:"pip"})})," to install the ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pycspr/",children:"pycspr"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install pycspr\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Include the casper-client dependency to your ",(0,t.jsx)(n.code,{children:"Cargo.toml"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ncasper-client="1.5.1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["and add it to your ",(0,t.jsx)(n.code,{children:"main.rs"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"extern crate casper_client;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Use types and methods from casper_client:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n"})}),"\n",(0,t.jsx)(n.p,{children:"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"creating-accounts",children:"Creating Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,t.jsx)(n.a,{href:"/next/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-account-keys",children:"Creating new account keys"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Create a keypair and write the files to a specified ",(0,t.jsx)(n.code,{children:"PATH"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"exporting-the-public-key-and-account-hash",children:"Exporting the public key and account hash"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"keypair"})," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"accountHashHex"}),' will be prefixed with the text "account-hash-".']}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"uploading-the-secret-key-from-a-file",children:"Uploading the secret key from a file"}),"\n",(0,t.jsx)(n.p,{children:"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.p,{children:"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"transferring-cspr",children:"Transferring CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"keypair"})," created ",(0,t.jsx)(n.a,{href:"#creating-accounts",children:"above"}),", you can sign a deploy that transfers CSPR."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\n\nconst amount = 2.5e9 // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper" // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(\n amount,\n recipientPublicKeyHex\n);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installing-contracts",children:"Installing Contracts"}),"\n",(0,t.jsx)(n.p,{children:"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")\nconst fs = require("fs")\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "argument": CLValueBuilder.string("Hello world!")\n})\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair]\n)\n\nconsole.log(await casperClient.putDeploy(deploy))\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, assuming that you cloned ",(0,t.jsx)(n.code,{children:"casper-node"})," from your project's root directory, ",(0,t.jsx)(n.code,{children:"cd"})," back into it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ../\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now in your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n \n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n \n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts",children:"Calling Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash(\n\t"hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"\n);\nconst runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string("Hello world!")\n})\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair]\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy))\n})();\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"staking-1",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/08996e66.45d2a303.js b/assets/js/08996e66.45d2a303.js new file mode 100644 index 000000000..2ab855c96 --- /dev/null +++ b/assets/js/08996e66.45d2a303.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94426],{57450:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="SDK Client Library Usage",i={id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/docs/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/developers/dapps/sdk/client-library-usage",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"}},l={},o=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sdk-client-library-usage",children:"SDK Client Library Usage"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-sdks",children:"Installing the SDKs"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"npm"})," or ",(0,t.jsx)(n.code,{children:"yarn"})," to install the ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-js-sdk",children:"casper-js-sdk"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn install casper-js-sdk\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:(0,t.jsx)(n.code,{children:"pip"})})," to install the ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pycspr/",children:"pycspr"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install pycspr\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Include the casper-client dependency to your ",(0,t.jsx)(n.code,{children:"Cargo.toml"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ncasper-client="1.5.1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["and add it to your ",(0,t.jsx)(n.code,{children:"main.rs"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"extern crate casper_client;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Use types and methods from casper_client:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n"})}),"\n",(0,t.jsx)(n.p,{children:"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"creating-accounts",children:"Creating Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-account-keys",children:"Creating new account keys"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Create a keypair and write the files to a specified ",(0,t.jsx)(n.code,{children:"PATH"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"exporting-the-public-key-and-account-hash",children:"Exporting the public key and account hash"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"keypair"})," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"accountHashHex"}),' will be prefixed with the text "account-hash-".']}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"uploading-the-secret-key-from-a-file",children:"Uploading the secret key from a file"}),"\n",(0,t.jsx)(n.p,{children:"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.p,{children:"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"transferring-cspr",children:"Transferring CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"keypair"})," created ",(0,t.jsx)(n.a,{href:"#creating-accounts",children:"above"}),", you can sign a deploy that transfers CSPR."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\n\nconst amount = 2.5e9 // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper" // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(\n amount,\n recipientPublicKeyHex\n);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installing-contracts",children:"Installing Contracts"}),"\n",(0,t.jsx)(n.p,{children:"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")\nconst fs = require("fs")\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "argument": CLValueBuilder.string("Hello world!")\n})\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair]\n)\n\nconsole.log(await casperClient.putDeploy(deploy))\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, assuming that you cloned ",(0,t.jsx)(n.code,{children:"casper-node"})," from your project's root directory, ",(0,t.jsx)(n.code,{children:"cd"})," back into it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ../\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now in your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n \n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n \n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts",children:"Calling Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash(\n\t"hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"\n);\nconst runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string("Hello world!")\n})\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair]\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy))\n})();\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"staking-1",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/08af526d.864924c4.js b/assets/js/08af526d.864924c4.js new file mode 100644 index 000000000..184900f94 --- /dev/null +++ b/assets/js/08af526d.864924c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30529],{41344:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/blog","page":1,"postsPerPage":5,"totalPages":1,"totalCount":5,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/08af526d.cefb371d.js b/assets/js/08af526d.cefb371d.js deleted file mode 100644 index 804be25c9..000000000 --- a/assets/js/08af526d.cefb371d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[529],{41344:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/blog","page":1,"postsPerPage":5,"totalPages":1,"totalCount":5,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/0904ce24.59e4ae24.js b/assets/js/0904ce24.59e4ae24.js deleted file mode 100644 index 2e932ac46..000000000 --- a/assets/js/0904ce24.59e4ae24.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5552],{18923:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=t(74848),o=t(28453);const s={title:"Overview",slug:"/operators"},i="Operators Overview",a={id:"operators/index",title:"Overview",description:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.",source:"@site/versioned_docs/version-1.5.X/operators/index.md",sourceDirName:"operators",slug:"/operators",permalink:"/operators",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/operators"},sidebar:"operators",next:{title:"Setting up a Node",permalink:"/operators/setup/"}},d={},c=[];function h(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"operators-overview",children:"Operators Overview"})}),"\n",(0,r.jsx)(n.p,{children:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section."}),"\n",(0,r.jsxs)(n.p,{children:["Prior knowledge of Unix-based operating systems and proficiency with ",(0,r.jsx)(n.code,{children:"systemd"})," and ",(0,r.jsx)(n.code,{children:"bash"})," scripting are recommended. If you are unfamiliar with ",(0,r.jsx)(n.code,{children:"systemd"}),", the ",(0,r.jsx)(n.a,{href:"https://wiki.archlinux.org/title/systemd",children:"Arch Linux page on systemd"})," is a good introduction."]}),"\n",(0,r.jsxs)(n.p,{children:["Operators should know the ",(0,r.jsx)(n.a,{href:"/operators/setup/hardware",children:"hardware requirements"})," before running a node."]}),"\n",(0,r.jsxs)(n.p,{children:["Also, the ",(0,r.jsx)(n.a,{href:"/operators/setup/install-node#network-requirements",children:"network requirements"})," specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes."]}),"\n",(0,r.jsxs)(n.p,{children:["Review the ",(0,r.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"node's configuration"})," first. Then, you can follow the node ",(0,r.jsx)(n.a,{href:"/operators/setup/install-node",children:"installation instructions"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/",children:"Node Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/",children:"Becoming a Validator"})}),(0,r.jsx)(n.td,{children:"How to join a network and become a validator"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup-network/",children:"Private Network Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a private Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/maintenance/",children:"Maintenance"})}),(0,r.jsx)(n.td,{children:"Topics related to node maintenance"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0904ce24.a293aebe.js b/assets/js/0904ce24.a293aebe.js new file mode 100644 index 000000000..611d8e615 --- /dev/null +++ b/assets/js/0904ce24.a293aebe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[85552],{18923:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=t(74848),o=t(28453);const s={title:"Overview",slug:"/operators"},i="Operators Overview",a={id:"operators/index",title:"Overview",description:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.",source:"@site/versioned_docs/version-1.5.X/operators/index.md",sourceDirName:"operators",slug:"/operators",permalink:"/1.5.X/operators",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/operators"},sidebar:"operators",next:{title:"Setting up a Node",permalink:"/1.5.X/operators/setup/"}},d={},c=[];function h(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"operators-overview",children:"Operators Overview"})}),"\n",(0,r.jsx)(n.p,{children:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section."}),"\n",(0,r.jsxs)(n.p,{children:["Prior knowledge of Unix-based operating systems and proficiency with ",(0,r.jsx)(n.code,{children:"systemd"})," and ",(0,r.jsx)(n.code,{children:"bash"})," scripting are recommended. If you are unfamiliar with ",(0,r.jsx)(n.code,{children:"systemd"}),", the ",(0,r.jsx)(n.a,{href:"https://wiki.archlinux.org/title/systemd",children:"Arch Linux page on systemd"})," is a good introduction."]}),"\n",(0,r.jsxs)(n.p,{children:["Operators should know the ",(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/hardware",children:"hardware requirements"})," before running a node."]}),"\n",(0,r.jsxs)(n.p,{children:["Also, the ",(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node#network-requirements",children:"network requirements"})," specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes."]}),"\n",(0,r.jsxs)(n.p,{children:["Review the ",(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration",children:"node's configuration"})," first. Then, you can follow the node ",(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node",children:"installation instructions"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/",children:"Node Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/",children:"Becoming a Validator"})}),(0,r.jsx)(n.td,{children:"How to join a network and become a validator"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup-network/",children:"Private Network Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a private Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/maintenance/",children:"Maintenance"})}),(0,r.jsx)(n.td,{children:"Topics related to node maintenance"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/09278318.4b956a66.js b/assets/js/09278318.4b956a66.js new file mode 100644 index 000000000..4b68b0fd3 --- /dev/null +++ b/assets/js/09278318.4b956a66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[503],{82395:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var i=s(74848),n=s(28453);const r={title:"Verifying Contracts"},c="Verifying Smart Contracts",o={id:"developers/cli/verifying-contracts",title:"Verifying Contracts",description:"This document describes actions needed for smart contract verification using the Casper CLI client.",source:"@site/versioned_docs/version-2.0.0/developers/cli/verifying-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/verifying-contracts",permalink:"/2.0.0/developers/cli/verifying-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Verifying Contracts"},sidebar:"developers",previous:{title:"Installing Contracts",permalink:"/2.0.0/developers/cli/installing-contracts"},next:{title:"Querying Global State",permalink:"/2.0.0/developers/cli/querying-global-state"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Verifying contracts using the Casper Client",id:"verifying-the-contract",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"verifying-smart-contracts",children:"Verifying Smart Contracts"})}),"\n",(0,i.jsxs)(t.p,{children:["This document describes actions needed for smart contract verification using the ",(0,i.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper CLI client"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"You have built and installed a contract"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"verifying-the-contract",children:"Verifying contracts using the Casper Client"}),"\n",(0,i.jsxs)(t.p,{children:["You can use the Casper client's ",(0,i.jsx)(t.code,{children:"verify-contract"})," command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"casper-client verify-contract --verification-url-basepath \n"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"verification-url-basepath"})," - The address of the verification service that will perform the operation; the current two options are ",(0,i.jsx)(t.a,{href:"https://staging.codeverifier.casper.network",children:"https://staging.codeverifier.casper.network"})," for Testnet and ",(0,i.jsx)(t.a,{href:"https://codeverifier.casper.network",children:"https://codeverifier.casper.network"})," for Mainnet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:""})," - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:""})," - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The prerequisites for the source code are the same as when installing it on the blockchain:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"The source code must be a Rust project as described in The Cargo Book."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.'}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on ",(0,i.jsx)(t.a,{href:"https://staging.casperecosystem.io/check-verification-status/",children:"https://staging.casperecosystem.io/check-verification-status/"})," for Testnet transactions and ",(0,i.jsx)(t.a,{href:"https://casperecosystem.io/check-verification-status/",children:"https://casperecosystem.io/check-verification-status/"})," for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function c(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/094b4aff.6cc550cf.js b/assets/js/094b4aff.6cc550cf.js new file mode 100644 index 000000000..30eee813c --- /dev/null +++ b/assets/js/094b4aff.6cc550cf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76749],{80626:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=s(74848),r=s(28453);const o={},i="Writing Session Code",c={id:"developers/writing-onchain-code/writing-session-code",title:"Writing Session Code",description:"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/writing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/writing-session-code",permalink:"/2.0.0/developers/writing-onchain-code/writing-session-code",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Contracts and Session Code",permalink:"/2.0.0/developers/writing-onchain-code/contract-vs-session"},next:{title:"Testing Session Code",permalink:"/2.0.0/developers/writing-onchain-code/testing-session-code"}},a={},d=[{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Example 1: Writing Session Code",id:"writing-session-code",level:2},{value:"Dependencies in Cargo.toml",id:"dependencies-in-cargotoml",level:3},{value:"Updating the main.rs File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"writing-session-code",children:"Writing Session Code"})}),"\n",(0,t.jsxs)(n.p,{children:["This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Comparing Session Code and Contract Code"}),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,t.jsxs)(n.p,{children:["For writing session code, we use the same project structure used for writing contracts, described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"writing-session-code",children:"Example 1: Writing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"https://github.com/casper-ecosystem/two-party-multi-sig/"}),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Account"})," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious."})}),"\n",(0,t.jsxs)(n.h3,{id:"dependencies-in-cargotoml",children:["Dependencies in ",(0,t.jsx)(n.code,{children:"Cargo.toml"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,t.jsx)(n.code,{children:"main.rs"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["Open the ",(0,t.jsx)(n.code,{children:"contract/src/main.rs"})," file that contains the sample session code. Notice these directives at the top of the file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_std]"})," - Specifies not to import the standard library."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_main]"})," - Indicates the ",(0,t.jsx)(n.code,{children:"main"})," function is not required since the session code has only one entry point as the ",(0,t.jsx)(n.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Next, review the imported crates and other required libraries."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the imported libraries, we usually find the constants."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, we see the ",(0,t.jsx)(n.code,{children:"call"})," function, the only entry point in this example session code. The ",(0,t.jsx)(n.code,{children:"#[no_mangle]"})," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,t.jsx)(n.code,{children:"call"})," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When compiled, the ",(0,t.jsx)(n.code,{children:"call"})," function could be used from another library. For example, a C library could link to the resulting Wasm."]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-code",children:"Example 2: Calling a Contract with Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Another example of session code is the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call/src/main.rs"})," file, in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter",children:"counter"})," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Observe how the project is set up and review the dependencies in the ",(0,t.jsx)(n.code,{children:"counter/counter-call/Cargo.toml"})," file. Then, open the ",(0,t.jsx)(n.code,{children:"counter/counter-call/src/main.rs"})," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," function interacts with the contract's ",(0,t.jsx)(n.code,{children:"counter_inc"})," and ",(0,t.jsx)(n.code,{children:"counter_get"})," entry points. This is how the session's ",(0,t.jsx)(n.code,{children:"call"})," entry point triggers the logic stored inside the counter contract."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:" // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n"})}),"\n",(0,t.jsx)(n.h2,{id:"transfers-using-session-code",children:"Example 3: Transfers using Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, we use session code to perform a transfer using the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html",children:"transfer_from_purse_to_purse"})," system function. The entire session code is available in ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14",children:"GitHub"}),", but this is the ",(0,t.jsx)(n.code,{children:"call"})," function:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Another system function is ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html",children:"transfer_to_public_key"}),". The full session code example is on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Other transfer functions are available here:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html",children:"transfer_from_purse_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html",children:"transfer_from_purse_to_public_key"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"compiling-session-code",children:"Compiling Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file and ",(0,t.jsx)(n.code,{children:"src"})," folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the examples above, you may use the Makefiles provided:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make build-contract\n"})}),"\n",(0,t.jsx)(n.h2,{id:"executing-session-code",children:"Executing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code on a live Casper network, test it as described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-session-code",children:"here"}),". You can also set up a local network using ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"NCTL"})," for additional tests."]}),"\n",(0,t.jsxs)(n.p,{children:["Session code can execute on a Casper network via a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/D#deploy",children:"Deploy"}),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and its ",(0,t.jsx)(n.code,{children:"put-deploy"})," command provide one way to execute session code."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address \\\n --chain-name \\\n --secret-key \\\n --payment-amount \\\n --session-path \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where the deploy should be sent. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - Path to the contract Wasm, pointing to the compiled contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - A named and typed argument passed to the Wasm code."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"--help"})," option to view an updated list of supported arguments."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsxs)(n.p,{children:["The following brief video describes ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-session-code",children:"test session code"})," using the Casper testing framework."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0ac4e675.ee46eb79.js b/assets/js/0ac4e675.ee46eb79.js deleted file mode 100644 index 73d7d8a35..000000000 --- a/assets/js/0ac4e675.ee46eb79.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8562],{17451:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var a=n(74848),o=n(28453);const r={},s="dApp Technology Stack",i={id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/developers/dapps/technology-stack",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"}},c={},l=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"dapp-technology-stack",children:"dApp Technology Stack"})}),"\n",(0,a.jsx)(t.p,{children:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."}),"\n",(0,a.jsx)(t.h2,{id:"front-end",children:"Front-End"}),"\n",(0,a.jsxs)(t.p,{children:["The front-end, or ",(0,a.jsx)(t.em,{children:"client-side"})," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."]}),"\n",(0,a.jsxs)(t.p,{children:["You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS"})," requirements."]}),"\n",(0,a.jsx)(t.h3,{id:"signing-transactions",children:"Signing Transactions"}),"\n",(0,a.jsx)(t.p,{children:"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The Casper Wallet"}),"\n",(0,a.jsxs)(t.p,{children:["Use the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Casper Wallet"})," to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."]}),"\n",(0,a.jsx)(t.admonition,{type:"caution",children:(0,a.jsxs)(t.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Third-party signers"}),"\n",(0,a.jsx)(t.p,{children:"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,a.jsx)(t.p,{children:"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."}),"\n",(0,a.jsx)(t.h2,{id:"backend",children:"Backend"}),"\n",(0,a.jsxs)(t.p,{children:["The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS headers"})," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."]}),"\n",(0,a.jsx)(t.p,{children:"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."}),"\n",(0,a.jsxs)(t.tabs,{children:["\n",(0,a.jsxs)(t.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.tabitem,{value:"py",label:"Python",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"tip",children:(0,a.jsxs)(t.p,{children:["You can find online peers for Mainnet at ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," or testnet at ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live",children:"testnet.cspr.live"})]})}),"\n",(0,a.jsx)(t.p,{children:"There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end."}),"\n",(0,a.jsx)(t.p,{children:"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."}),"\n",(0,a.jsx)(t.p,{children:"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."}),"\n",(0,a.jsx)(t.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,a.jsxs)(t.p,{children:["The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-transactional",children:"transactional"}),", ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-informational",children:"informational"}),", and ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake"})," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."]}),"\n",(0,a.jsxs)(t.p,{children:["More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,a.jsx)(t.a,{href:"https://webassembly.org/",children:"WebAssembly"})," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,a.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"Rust"})," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."]}),"\n",(0,a.jsxs)(t.p,{children:["To learn how to write smart contracts for your dApp, read the ",(0,a.jsx)(t.a,{href:"/writing-contracts",children:"smart contract documentation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0ac4e675.f7475e94.js b/assets/js/0ac4e675.f7475e94.js new file mode 100644 index 000000000..5c8b944d2 --- /dev/null +++ b/assets/js/0ac4e675.f7475e94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[48562],{17451:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var a=n(74848),o=n(28453);const r={},s="dApp Technology Stack",i={id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/1.5.X/developers/dapps/technology-stack",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/1.5.X/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/1.5.X/developers/dapps/template-frontend"}},c={},l=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"dapp-technology-stack",children:"dApp Technology Stack"})}),"\n",(0,a.jsx)(t.p,{children:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."}),"\n",(0,a.jsx)(t.h2,{id:"front-end",children:"Front-End"}),"\n",(0,a.jsxs)(t.p,{children:["The front-end, or ",(0,a.jsx)(t.em,{children:"client-side"})," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."]}),"\n",(0,a.jsxs)(t.p,{children:["You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS"})," requirements."]}),"\n",(0,a.jsx)(t.h3,{id:"signing-transactions",children:"Signing Transactions"}),"\n",(0,a.jsx)(t.p,{children:"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The Casper Wallet"}),"\n",(0,a.jsxs)(t.p,{children:["Use the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Casper Wallet"})," to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."]}),"\n",(0,a.jsx)(t.admonition,{type:"caution",children:(0,a.jsxs)(t.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Third-party signers"}),"\n",(0,a.jsx)(t.p,{children:"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,a.jsx)(t.p,{children:"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."}),"\n",(0,a.jsx)(t.h2,{id:"backend",children:"Backend"}),"\n",(0,a.jsxs)(t.p,{children:["The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS headers"})," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."]}),"\n",(0,a.jsx)(t.p,{children:"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."}),"\n",(0,a.jsxs)(t.tabs,{children:["\n",(0,a.jsxs)(t.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.tabitem,{value:"py",label:"Python",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"tip",children:(0,a.jsxs)(t.p,{children:["You can find online peers for Mainnet at ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," or testnet at ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live",children:"testnet.cspr.live"})]})}),"\n",(0,a.jsx)(t.p,{children:"There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end."}),"\n",(0,a.jsx)(t.p,{children:"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."}),"\n",(0,a.jsx)(t.p,{children:"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."}),"\n",(0,a.jsx)(t.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,a.jsxs)(t.p,{children:["The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/json-rpc-transactional",children:"transactional"}),", ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational",children:"informational"}),", and ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake"})," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."]}),"\n",(0,a.jsxs)(t.p,{children:["More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,a.jsx)(t.a,{href:"https://webassembly.org/",children:"WebAssembly"})," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,a.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"Rust"})," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."]}),"\n",(0,a.jsxs)(t.p,{children:["To learn how to write smart contracts for your dApp, read the ",(0,a.jsx)(t.a,{href:"/1.5.X/writing-contracts",children:"smart contract documentation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0ae07240.2f1af85d.js b/assets/js/0ae07240.2f1af85d.js new file mode 100644 index 000000000..2508036b4 --- /dev/null +++ b/assets/js/0ae07240.2f1af85d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57366],{33153:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var i=t(74848),s=t(28453);const a={title:"Recovery"},o="Recovering from Validator Eviction",c={id:"operators/becoming-a-validator/recovering",title:"Recovery",description:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/recovering.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/recovering",permalink:"/2.0.0/operators/becoming-a-validator/recovering",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Recovery"},sidebar:"operators",previous:{title:"Unbonding",permalink:"/2.0.0/operators/becoming-a-validator/unbonding"},next:{title:"Inactive and Faulty Nodes",permalink:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty"}},r={},d=[{value:"Detecting the Eviction",id:"detecting-the-eviction",level:2},{value:"Detection using CSPR.live",id:"detection-using-csprlive",level:3},{value:"Detection using the Casper Client",id:"detection-using-the-casper-client",level:3},{value:"Correcting any Underlying Node Issues",id:"correcting-any-underlying-node-issues",level:2},{value:"Activating the Bid",id:"activating-the-bid",level:2},{value:"Method 1: Activating the Bid with the System Auction Contract",id:"activating-system-auction",level:3},{value:"Method 2: Activating the Bid with Compiled Wasm",id:"activating-compiled-wasm",level:3},{value:"Checking the Bid Activation",id:"checking-the-bid-activation",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"recovering-from-validator-eviction",children:"Recovering from Validator Eviction"})}),"\n",(0,i.jsx)(n.p,{children:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Detecting the eviction"}),"\n",(0,i.jsx)(n.li,{children:"Correcting any underlying node issues"}),"\n",(0,i.jsx)(n.li,{children:"Re-building the contracts for bonding"}),"\n",(0,i.jsx)(n.li,{children:"Activating the bid"}),"\n",(0,i.jsx)(n.li,{children:"Checking the bid"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," topic explains why a node would be evicted."]}),"\n",(0,i.jsx)(n.h2,{id:"detecting-the-eviction",children:"Detecting the Eviction"}),"\n",(0,i.jsx)(n.p,{children:"The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era."}),"\n",(0,i.jsx)(n.p,{children:"For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era."}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-csprlive",children:"Detection using CSPR.live"}),"\n",(0,i.jsxs)(n.p,{children:["If you were a previous validator and still exist on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators-auction",children:"Validators Auction"})," tab but not in ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"}),", you may have been evicted or outbid."]}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-the-casper-client",children:"Detection using the Casper Client"}),"\n",(0,i.jsxs)(n.p,{children:["All auction information is returned with the ",(0,i.jsx)(n.code,{children:"casper-client get-auction-info"})," command. It would help if you filtered this down to your public key."]}),"\n",(0,i.jsxs)(n.p,{children:["You can replace the ",(0,i.jsx)(n.code,{children:"public_key"})," with your public key manually and run this command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"\")'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You know you were evicted if the ",(0,i.jsx)(n.code,{children:"get-auction-info"})," command returned your bid showing an ",(0,i.jsx)(n.strong,{children:"inactive"})," field. See the ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," page for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive a ",(0,i.jsx)(n.code,{children:"parse error: Invalid numeric literal at"}),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info\n"})}),"\n",(0,i.jsx)(n.h2,{id:"correcting-any-underlying-node-issues",children:"Correcting any Underlying Node Issues"}),"\n",(0,i.jsx)(n.p,{children:"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."}),"\n",(0,i.jsxs)(n.p,{children:["To check if your node is in sync, compare the current block height at ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," with the height from your node with:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl -s localhost:8888/status | jq .last_added_block_info\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you cannot figure out the issue, ask for help in the ",(0,i.jsx)(n.em,{children:"node-tech-support"})," channel on ",(0,i.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"activating-the-bid",children:"Activating the Bid"}),"\n",(0,i.jsxs)(n.p,{children:["Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. The second method involves building the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," contract as explained in ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,i.jsx)(n.h3,{id:"activating-system-auction",children:"Method 1: Activating the Bid with the System Auction Contract"}),"\n",(0,i.jsxs)(n.p,{children:["This method calls the existing ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-hash \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:"]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Testnet"}),": ",(0,i.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mainnet"}),": ",(0,i.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,i.jsx)(n.code,{children:"activate_bid"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,i.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point on the auction contract has a fixed cost of 10,000 motes."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.p,{children:"This example uses the Casper Testnet to reactivate a bid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, ",(0,i.jsx)(n.a,{href:"#checking-the-bid-activation",children:"check the bid activation"})," status."]}),"\n",(0,i.jsx)(n.h3,{id:"activating-compiled-wasm",children:"Method 2: Activating the Bid with Compiled Wasm"}),"\n",(0,i.jsxs)(n.p,{children:["The second method to rejoin the network is to reactivate your bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["As described above, this method is much more expensive than calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example that reactivates a bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"}),". For example, if you use the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," on a network with node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml",children:"1.4.9"}),", you will require a balance of at least 5 CSPR for this contract."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Check that the deploy was successful with the ",(0,i.jsx)(n.code,{children:"casper-client get-deploy "})," or by searching for the deploy hash on ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),". Also, check the bid activation status as shown below."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-the-bid-activation",children:"Checking the Bid Activation"}),"\n",(0,i.jsxs)(n.p,{children:["Once your deploy processes, you can ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/recovering#detecting-the-eviction-using-the-casper-client",children:"check your bid"})," again. You should now see ",(0,i.jsx)(n.code,{children:'"inactive": false'})," in the output."]}),"\n",(0,i.jsxs)(n.p,{children:["If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"})," tab."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b20c33e.4baa51ac.js b/assets/js/0b20c33e.4baa51ac.js new file mode 100644 index 000000000..73cfb41d9 --- /dev/null +++ b/assets/js/0b20c33e.4baa51ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75941],{59560:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=s(74848),n=s(28453);const o={},c="Execution Error Codes",i={id:"developers/cli/execution-error-codes",title:"Execution Error Codes",description:"This section covers smart contract execution error codes.",source:"@site/versioned_docs/version-2.0.0/developers/cli/execution-error-codes.md",sourceDirName:"developers/cli",slug:"/developers/cli/execution-error-codes",permalink:"/2.0.0/developers/cli/execution-error-codes",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"OpCode Costs Tables",permalink:"/2.0.0/developers/cli/opcode-costs"}},a={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"execution-error-codes",children:"Execution Error Codes"})}),"\n",(0,t.jsx)(r.p,{children:"This section covers smart contract execution error codes."}),"\n",(0,t.jsxs)(r.p,{children:["As mentioned in ",(0,t.jsx)(r.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts"}),", smart contracts can exit with an error code defined by an ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html",children:"ApiError"}),". Descriptions of each variant are found ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"})," and include the following sub-types:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.HandlePayment",children:"payment errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.Mint",children:"mint errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.User",children:"custom user errors"})}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["An ",(0,t.jsx)(r.code,{children:"ApiError"})," of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ",(0,t.jsx)(r.code,{children:"ApiError::User(2)"})," maps to an exit code of ",(0,t.jsx)(r.code,{children:"65538"})," (i.e. ",(0,t.jsx)(r.code,{children:"65536 + 2"}),"). You can find a mapping from contract exit codes to ",(0,t.jsx)(r.code,{children:"ApiError"})," variants ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>c,x:()=>i});var t=s(96540);const n={},o=t.createContext(n);function c(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b3fc8e9.ce7a5cab.js b/assets/js/0b3fc8e9.ce7a5cab.js new file mode 100644 index 000000000..3a21afd2a --- /dev/null +++ b/assets/js/0b3fc8e9.ce7a5cab.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[54041],{65357:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var r=s(74848),t=s(28453);const a={title:"Overview"},i="Concepts Overview",c={id:"concepts/index",title:"Overview",description:"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.",source:"@site/versioned_docs/version-2.0.0/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/2.0.0/concepts/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Overview"},sidebar:"concepts",next:{title:"What is Casper?",permalink:"/2.0.0/concepts/about"}},o={},d=[{value:"Concepts",id:"concepts",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3},{value:"Users",id:"users",level:3},{value:"Resources",id:"resources",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"concepts-overview",children:"Concepts Overview"})}),"\n",(0,r.jsxs)(n.p,{children:["The Casper blockchain is a ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"Casper Mainnet"})," is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup-network/",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/about",children:"Introduction to the Casper Blockchain"})}),(0,r.jsx)(n.td,{children:"High-level details about the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/intro-to-dapps",children:"Introduction to dApps"})}),(0,r.jsx)(n.td,{children:"Developing distributed applications on the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/addressable-entity",children:"Addressable Entities"})}),(0,r.jsx)(n.td,{children:"Learn about addressable entities and how they relate to accounts and smart contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})}),(0,r.jsx)(n.td,{children:"The Casper programming model is account-based. Learn how Casper accounts work and how they are secured"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/key-types",children:"Key Types"})}),(0,r.jsx)(n.td,{children:"Hashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/global-state",children:"Global State"})}),(0,r.jsx)(n.td,{children:"Learn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/callstack",children:"Call Stacks"})}),(0,r.jsx)(n.td,{children:"Learn how Casper manages the calling of a contract"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),(0,r.jsx)(n.td,{children:"Transactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/smart-contracts",children:"Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Learn how to develop smart contracts on Casper"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/dictionaries",children:"Dictionaries"})}),(0,r.jsx)(n.td,{children:"Learn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization"})}),(0,r.jsx)(n.td,{children:"Learn about serializing data types and the Casper Serialization Standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/design",children:"Design"})}),(0,r.jsx)(n.td,{children:"The high-level design of a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/economics",children:"Economics"})}),(0,r.jsx)(n.td,{children:"Learn about the Casper on-chain economics"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/glossary",children:"Glossary"})}),(0,r.jsx)(n.td,{children:"A compendium of all the terms used in Casper, in alphabetical order"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,r.jsx)(n.p,{children:"After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories."}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/2.0.0/developers",children:"Developers"})," area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/2.0.0/operators",children:"Operators"})," section caters to those who want to run and administrate a Casper node or network."]}),"\n",(0,r.jsx)(n.h3,{id:"users",children:"Users"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/2.0.0/users/",children:"Users"})," section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device."]}),"\n",(0,r.jsx)(n.h3,{id:"resources",children:"Resources"}),"\n",(0,r.jsxs)(n.p,{children:["Navigate to ",(0,r.jsx)(n.a,{href:"/2.0.0/resources/",children:"Resources"})," to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the ",(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/",children:"beginner tutorials"}),". Afterward, continue with more ",(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/",children:"advanced tutorials"})," to explore the multi-signature feature, runtime return values, and other essential features."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var r=s(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b8cc739.11d60f3d.js b/assets/js/0b8cc739.11d60f3d.js new file mode 100644 index 000000000..9defd3d79 --- /dev/null +++ b/assets/js/0b8cc739.11d60f3d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19356],{69833:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Installing Contracts"},s="Installing Smart Contracts",i={id:"developers/cli/installing-contracts",title:"Installing Contracts",description:"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.",source:"@site/docs/developers/cli/installing-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/installing-contracts",permalink:"/developers/cli/installing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Installing Contracts"},sidebar:"developers",previous:{title:"Sending Transactions",permalink:"/developers/cli/sending-transactions"},next:{title:"Verifying Contracts",permalink:"/developers/cli/verifying-contracts"}},r={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Contract in Global State",id:"installing-contract-code",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-smart-contracts",children:"Installing Smart Contracts"})}),"\n",(0,t.jsxs)(n.p,{children:["This document details the process of installing ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Casper smart contracts"})," using the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"You have a compiled contract Wasm to send to a Casper network."}),"\n",(0,t.jsxs)(n.li,{children:["You have installed the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper CLI client"})," to interact with the network."]}),"\n",(0,t.jsxs)(n.li,{children:["You have a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Casper Account"})," with a public and secret key pair to initiate the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:["You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"faucet"})," to fund your testing account's main purse."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-contract-code",children:"Installing a Contract in Global State"}),"\n",(0,t.jsxs)(n.p,{children:["To install a contract in ",(0,t.jsx)(n.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),", you need to send a transaction to the network with the contract Wasm. You can do so by using the ",(0,t.jsx)(n.code,{children:"put-transaction session"})," command, or the equivalent ",(0,t.jsx)(n.code,{children:"put-txn session"})," command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--gas-price-tolerance [MAX_GAS_AMOUNT] \\\n--pricing-mode fixed \\\n--transaction-path \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where you wish to send the transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the transaction"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum amount of gas a user is willing to pay for execution"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"}),' - Set to "fixed" for Mainnet and Testnet']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) on your computer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when installing the contract, which is usually ",(0,t.jsx)(n.code,{children:"call"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction type, based on Wasm size, with ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Once you call this command, it will return a transaction hash. You can use this hash to ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-transactions#sending-the-transaction",children:"verify"})," successful execution of the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The pricing mode varies based on each network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),'. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.']})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Contract Installation"})}),"\n",(0,t.jsxs)(n.p,{children:["Here we send a ",(0,t.jsx)(n.code,{children:"counter-installer.wasm"})," to a local NCTL network:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address http://localhost:11101 \\\n--chain-name casper-net-1 \\\n--secret-key ~/casper/casper-nctl/assets/net-1/users/user-1/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path ~/test_contracts/counter_installer.wasm \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The result of the query includes a ",(0,t.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 90342686534145684,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2"\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transaction, call ",(0,t.jsx)(n.code,{children:"get-transaction"})," and provide the transaction hash you received from ",(0,t.jsx)(n.code,{children:"put-transaction"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-transaction --node-address http://localhost:11101 [TRANSACTION_HASH]\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 5297043714444661948,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-08-21T11:21:36.201Z",\n "ttl": "30m",\n "body_hash": "543df05d05c456e9b6b5d657029e9ad20c674c6e6b56f498af0052ec87ee9f80",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n }\n },\n "body": {\n "args": [],\n "target": {\n "Session": {\n "module_bytes": "[105936 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d",\n "signature": "01537684dd531ce6a4c9383ba7ea565e9408ed2c5dd8bb12787f131e1148fd0f057f45dbaa7bbc0230743cc5740c67db64f66bab1df57547722899f7d7289c1f0c"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "24ead40278a71966e16823150b06c06675a216dbef761c1d6ad1439da4147f4a",\n "block_height": 8463,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "46747144601",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 53215,\n "effects": [\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-05c3e063406ddde43671e0d47c45e31a10e9204137171f96ce818bdc725a4e1b",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1050d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "parsed": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n "name": {\n "cl_type": "String",\n "bytes": "14000000636f756e7465725f7061636b6167655f6e616d65",\n "parsed": "counter_package_name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-6409273bf327d5a6a39a29dbd07c5cd2f48ee4f227fd443d025adc51e1bd5103",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0229feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a07",\n "parsed": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000636f756e7465725f6163636573735f75726566",\n "parsed": "counter_access_uref"\n }\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "package-f1c97c9b6228be3f316753e4e1289d910071fb880dddccce18881abfb9f53526",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[82290 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-5fed34ec1b2c38445b984eee743ce17fb1e5e89a8cb910cc2f9f12b005360eef",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab0363140707",\n "parsed": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "05000000636f756e74",\n "parsed": "count"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-399a84b0da15b34ecd774b1c4ad47c72a9e1298df057d83bee93d22ac4972aa5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-174ccaaa723ba74cee869017501fab28512b6ef9296d48a38daff7d0da13d1a1",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf07",\n "parsed": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0700000076657273696f6e",\n "parsed": "version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-83b1cde13136393741a1e906a892ccdd289e7827cc9ef84a98cc96e86464bde0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "parsed": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n "name": {\n "cl_type": "String",\n "bytes": "07000000636f756e746572",\n "parsed": "counter"\n }\n }\n }\n }\n },\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Prune": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000"\n }\n },\n {\n "key": "balance-hold-0021dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-b76adcf84d4900edec0af9001e727bcc3d4920a40afaa6a0e43137bacf62b91e",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1d29f1bd6ba7016f430498de2d0fe7c9d2c14c200d79be33e0ad240bc2a0d229",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d0903000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e4bb993269e0fe33d6e575ab6a642fdcaf692449a1529c4f73e636dfff9d3e61",\n "era_id": 777,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note the contract entity address in the above sample output. You will need this to ",(0,t.jsx)(n.a,{href:"/developers/cli/querying-global-state#query-the-contract",children:"query the contract"})," installed. In this example, the address is ",(0,t.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"/developers/cli/querying-global-state",children:"query global state"})," to see more details about the successfully installed contract."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/cli/querying-global-state",children:"query global state"})," using the Casper command-line client."]}),"\n"]})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0b8cc739.79de13f9.js b/assets/js/0b8cc739.79de13f9.js deleted file mode 100644 index 348d01271..000000000 --- a/assets/js/0b8cc739.79de13f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9356],{69833:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Installing Contracts"},s="Installing Smart Contracts",i={id:"developers/cli/installing-contracts",title:"Installing Contracts",description:"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.",source:"@site/docs/developers/cli/installing-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/installing-contracts",permalink:"/next/developers/cli/installing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Installing Contracts"},sidebar:"developers",previous:{title:"Sending Transactions",permalink:"/next/developers/cli/sending-transactions"},next:{title:"Verifying Contracts",permalink:"/next/developers/cli/verifying-contracts"}},r={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Contract in Global State",id:"installing-contract-code",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-smart-contracts",children:"Installing Smart Contracts"})}),"\n",(0,t.jsxs)(n.p,{children:["This document details the process of installing ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Casper smart contracts"})," using the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"You have a compiled contract Wasm to send to a Casper network."}),"\n",(0,t.jsxs)(n.li,{children:["You have installed the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper CLI client"})," to interact with the network."]}),"\n",(0,t.jsxs)(n.li,{children:["You have a ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"Casper Account"})," with a public and secret key pair to initiate the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:["You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the ",(0,t.jsx)(n.a,{href:"/next/users/testnet-faucet",children:"faucet"})," to fund your testing account's main purse."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-contract-code",children:"Installing a Contract in Global State"}),"\n",(0,t.jsxs)(n.p,{children:["To install a contract in ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"}),", you need to send a transaction to the network with the contract Wasm. You can do so by using the ",(0,t.jsx)(n.code,{children:"put-transaction session"})," command, or the equivalent ",(0,t.jsx)(n.code,{children:"put-txn session"})," command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--gas-price-tolerance [MAX_GAS_AMOUNT] \\\n--pricing-mode fixed \\\n--transaction-path \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where you wish to send the transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the transaction"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum amount of gas a user is willing to pay for execution"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"}),' - Set to "fixed" for Mainnet and Testnet']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) on your computer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when installing the contract, which is usually ",(0,t.jsx)(n.code,{children:"call"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction type, based on Wasm size, with ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Once you call this command, it will return a transaction hash. You can use this hash to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/sending-transactions#sending-the-transaction",children:"verify"})," successful execution of the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The pricing mode varies based on each network ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),'. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.']})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Contract Installation"})}),"\n",(0,t.jsxs)(n.p,{children:["Here we send a ",(0,t.jsx)(n.code,{children:"counter-installer.wasm"})," to a local NCTL network:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address http://localhost:11101 \\\n--chain-name casper-net-1 \\\n--secret-key ~/casper/casper-nctl/assets/net-1/users/user-1/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path ~/test_contracts/counter_installer.wasm \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The result of the query includes a ",(0,t.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 90342686534145684,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2"\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transaction, call ",(0,t.jsx)(n.code,{children:"get-transaction"})," and provide the transaction hash you received from ",(0,t.jsx)(n.code,{children:"put-transaction"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-transaction --node-address http://localhost:11101 [TRANSACTION_HASH]\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 5297043714444661948,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-08-21T11:21:36.201Z",\n "ttl": "30m",\n "body_hash": "543df05d05c456e9b6b5d657029e9ad20c674c6e6b56f498af0052ec87ee9f80",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n }\n },\n "body": {\n "args": [],\n "target": {\n "Session": {\n "module_bytes": "[105936 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d",\n "signature": "01537684dd531ce6a4c9383ba7ea565e9408ed2c5dd8bb12787f131e1148fd0f057f45dbaa7bbc0230743cc5740c67db64f66bab1df57547722899f7d7289c1f0c"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "24ead40278a71966e16823150b06c06675a216dbef761c1d6ad1439da4147f4a",\n "block_height": 8463,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "46747144601",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 53215,\n "effects": [\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-05c3e063406ddde43671e0d47c45e31a10e9204137171f96ce818bdc725a4e1b",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1050d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "parsed": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n "name": {\n "cl_type": "String",\n "bytes": "14000000636f756e7465725f7061636b6167655f6e616d65",\n "parsed": "counter_package_name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-6409273bf327d5a6a39a29dbd07c5cd2f48ee4f227fd443d025adc51e1bd5103",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0229feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a07",\n "parsed": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000636f756e7465725f6163636573735f75726566",\n "parsed": "counter_access_uref"\n }\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "package-f1c97c9b6228be3f316753e4e1289d910071fb880dddccce18881abfb9f53526",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[82290 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-5fed34ec1b2c38445b984eee743ce17fb1e5e89a8cb910cc2f9f12b005360eef",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab0363140707",\n "parsed": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "05000000636f756e74",\n "parsed": "count"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-399a84b0da15b34ecd774b1c4ad47c72a9e1298df057d83bee93d22ac4972aa5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-174ccaaa723ba74cee869017501fab28512b6ef9296d48a38daff7d0da13d1a1",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf07",\n "parsed": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0700000076657273696f6e",\n "parsed": "version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-83b1cde13136393741a1e906a892ccdd289e7827cc9ef84a98cc96e86464bde0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "parsed": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n "name": {\n "cl_type": "String",\n "bytes": "07000000636f756e746572",\n "parsed": "counter"\n }\n }\n }\n }\n },\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Prune": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000"\n }\n },\n {\n "key": "balance-hold-0021dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-b76adcf84d4900edec0af9001e727bcc3d4920a40afaa6a0e43137bacf62b91e",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1d29f1bd6ba7016f430498de2d0fe7c9d2c14c200d79be33e0ad240bc2a0d229",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d0903000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e4bb993269e0fe33d6e575ab6a642fdcaf692449a1529c4f73e636dfff9d3e61",\n "era_id": 777,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note the contract entity address in the above sample output. You will need this to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/querying-global-state#query-the-contract",children:"query the contract"})," installed. In this example, the address is ",(0,t.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"/next/developers/cli/querying-global-state",children:"query global state"})," to see more details about the successfully installed contract."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/querying-global-state",children:"query global state"})," using the Casper command-line client."]}),"\n"]})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bb2dbe9.0880aaaf.js b/assets/js/0bb2dbe9.0880aaaf.js deleted file mode 100644 index 29d845e85..000000000 --- a/assets/js/0bb2dbe9.0880aaaf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8061],{84303:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(74848),a=n(28453);const o={},s="Calling Contracts",c={id:"developers/writing-onchain-code/calling-contracts",title:"Calling Contracts",description:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.",source:"@site/docs/developers/writing-onchain-code/calling-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/calling-contracts",permalink:"/next/developers/writing-onchain-code/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/next/developers/writing-onchain-code/upgrading-contracts"},next:{title:"Contracts and Session Code",permalink:"/next/developers/writing-onchain-code/contract-vs-session"}},i={},d=[{value:"Using Legacy Deploy Variants",id:"using-legacy-deploy-variants",level:2},{value:"ModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionedContractByHash",id:"storedversionedcontractbyhash",level:3},{value:"StoredVersionedContractByName",id:"storedversionedcontractbyname",level:3},{value:"Transfer",id:"transfer",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"calling-contracts",children:"Calling Contracts"})}),"\n",(0,r.jsx)(t.p,{children:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm."}),"\n",(0,r.jsx)(t.h2,{id:"using-legacy-deploy-variants",children:"Using Legacy Deploy Variants"}),"\n",(0,r.jsx)(t.h3,{id:"modulebytes",children:"ModuleBytes"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"ModuleBytes"})," is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm."]}),"\n",(0,r.jsxs)(t.p,{children:["However, you can also use ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," to deploy session code that calls a contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," can be found in ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#modulebytes",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyhash",children:"StoredContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByHash"})," is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question."]}),"\n",(0,r.jsx)(t.p,{children:"While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract."}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#storedcontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyname",children:"StoredContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByName"})," is similar to ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", with the main difference being the reference used to invoke on-chain Wasm. Where ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," requires the contract hash, ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," uses a string stored as a ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#namedkey",children:(0,r.jsx)(t.code,{children:"NamedKey"})})," in the caller's account."]}),"\n",(0,r.jsxs)(t.p,{children:["This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's ",(0,r.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyhash",children:"StoredVersionedContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package."]}),"\n",(0,r.jsxs)(t.p,{children:["This makes ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," more stable than ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version."]}),"\n",(0,r.jsxs)(t.p,{children:["DApp developers that use contracts developed by other parties can use ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," to avoid interruptions from contract version changes."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#storedversioncontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyname",children:"StoredVersionedContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," combines the functionality of ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," and ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"}),". It allows a developer to store a reference string as a ",(0,r.jsx)(t.code,{children:"NamedKey"})," within their account context that references a contract by its contract package hash."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," can be found ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#storedversioncontractbyname",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"transfer",children:"Transfer"}),"\n",(0,r.jsxs)(t.p,{children:["Native ",(0,r.jsx)(t.code,{children:"Transfer"}),"s are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of a native ",(0,r.jsx)(t.code,{children:"Transfer"})," can be found ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#transfer",children:"here"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const a={},o=r.createContext(a);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bb2dbe9.25561148.js b/assets/js/0bb2dbe9.25561148.js new file mode 100644 index 000000000..c46868997 --- /dev/null +++ b/assets/js/0bb2dbe9.25561148.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[38061],{84303:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(74848),a=n(28453);const o={},s="Calling Contracts",c={id:"developers/writing-onchain-code/calling-contracts",title:"Calling Contracts",description:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.",source:"@site/docs/developers/writing-onchain-code/calling-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/calling-contracts",permalink:"/developers/writing-onchain-code/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts"},next:{title:"Contracts and Session Code",permalink:"/developers/writing-onchain-code/contract-vs-session"}},i={},d=[{value:"Using Legacy Deploy Variants",id:"using-legacy-deploy-variants",level:2},{value:"ModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionedContractByHash",id:"storedversionedcontractbyhash",level:3},{value:"StoredVersionedContractByName",id:"storedversionedcontractbyname",level:3},{value:"Transfer",id:"transfer",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"calling-contracts",children:"Calling Contracts"})}),"\n",(0,r.jsx)(t.p,{children:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm."}),"\n",(0,r.jsx)(t.h2,{id:"using-legacy-deploy-variants",children:"Using Legacy Deploy Variants"}),"\n",(0,r.jsx)(t.h3,{id:"modulebytes",children:"ModuleBytes"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"ModuleBytes"})," is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm."]}),"\n",(0,r.jsxs)(t.p,{children:["However, you can also use ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," to deploy session code that calls a contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," can be found in ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#modulebytes",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyhash",children:"StoredContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByHash"})," is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question."]}),"\n",(0,r.jsx)(t.p,{children:"While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract."}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedcontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyname",children:"StoredContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByName"})," is similar to ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", with the main difference being the reference used to invoke on-chain Wasm. Where ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," requires the contract hash, ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," uses a string stored as a ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:(0,r.jsx)(t.code,{children:"NamedKey"})})," in the caller's account."]}),"\n",(0,r.jsxs)(t.p,{children:["This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's ",(0,r.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyhash",children:"StoredVersionedContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package."]}),"\n",(0,r.jsxs)(t.p,{children:["This makes ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," more stable than ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version."]}),"\n",(0,r.jsxs)(t.p,{children:["DApp developers that use contracts developed by other parties can use ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," to avoid interruptions from contract version changes."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedversioncontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyname",children:"StoredVersionedContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," combines the functionality of ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," and ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"}),". It allows a developer to store a reference string as a ",(0,r.jsx)(t.code,{children:"NamedKey"})," within their account context that references a contract by its contract package hash."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedversioncontractbyname",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"transfer",children:"Transfer"}),"\n",(0,r.jsxs)(t.p,{children:["Native ",(0,r.jsx)(t.code,{children:"Transfer"}),"s are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of a native ",(0,r.jsx)(t.code,{children:"Transfer"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#transfer",children:"here"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const a={},o=r.createContext(a);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bd3b317.a7a76776.js b/assets/js/0bd3b317.a7a76776.js new file mode 100644 index 000000000..3f6ca6927 --- /dev/null +++ b/assets/js/0bd3b317.a7a76776.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24643],{40975:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=n(74848),i=n(28453);const s={title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},a="Fee Elimination on Casper 2.0",r={permalink:"/blog/condor-fee-elimination",source:"@site/blog/2024-07-16-fee-elimination.md",title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",date:"2024-07-16T22:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"features",permalink:"/blog/tags/features"},{inline:!0,label:"tokenomics",permalink:"/blog/tags/tokenomics"}],readingTime:8.84,hasTruncateMarker:!0,authors:[{name:"Dylan Ireland",page:{permalink:"/blog/authors/dylanireland"},title:"Developer Advocate for Casper Association",url:"https://github.com/dylanireland",permalink:"/dylanireland",imageURL:"https://github.com/dylanireland.png",key:"dylanireland"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"},nextItem:{title:"Setting Up a Local Casper Condor Network for Development",permalink:"/blog/condor-local-setup"}},l={authorsImageUrls:[void 0,void 0]},d=[{value:"Concepts",id:"concepts",level:2},{value:"Payment, Gas Price, Fees",id:"payment-gas-price-fees",level:2},{value:"Fee Elimination",id:"fee-elimination",level:2},{value:"Holds",id:"holds",level:3},{value:"Hold Release",id:"hold-release",level:3},{value:"Accrued",id:"accrued",level:4},{value:"Amortized",id:"amortized",level:4},{value:"More about Gas holds",id:"more-about-gas-holds",level:3},{value:"Preventing Exploitation",id:"preventing-exploitation",level:3},{value:"Opportunity Cost",id:"opportunity-cost",level:4},{value:"Incentivizing Validators",id:"incentivizing-validators",level:3},{value:"Looking Forward",id:"looking-forward",level:2},{value:"Further Reading/Terms",id:"further-readingterms",level:3},{value:"Proposer",id:"proposer",level:4},{value:"Fees",id:"fees",level:4}];function c(e){const t={a:"a",blockquote:"blockquote",br:"br",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as ",(0,o.jsx)(t.strong,{children:"Fee Elimination"})," for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released."]}),"\n",(0,o.jsx)(t.h2,{id:"concepts",children:"Concepts"}),"\n",(0,o.jsxs)(t.p,{children:['Public distributed blockchain networks that support smart contracts generally employ a concept known as "',(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/G/#gas",children:"gas"}),'", which can be thought of as "the ability to do work on-chain". The problem addressed by this mechanism is that ',(0,o.jsx)(t.strong,{children:"any finite resource on a publicly accessible computer network must be rate-limited"}),", because a resource made available without limit is a denial of service attack vector."]}),"\n",(0,o.jsx)(t.p,{children:"Gas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor's available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses."}),"\n",(0,o.jsx)(t.h2,{id:"payment-gas-price-fees",children:"Payment, Gas Price, Fees"}),"\n",(0,o.jsxs)(t.p,{children:["On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the ",(0,o.jsx)(t.a,{href:"#proposer",children:"proposer"})," of that block in the form of transaction ",(0,o.jsx)(t.a,{href:"#fees",children:"fees"}),". The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Limit"}),": An amount of gas, specified by the transactor, at which to cancel a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Price"}),": The network gas price; the ratio between the cost of 1 unit of gas and 1 mote."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Cost"}),": The amount of gas needed to pay for execution of a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Payment"}),": The amount of token specified by the transactor to pay for the execution of a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Refund"}),": All or a portion of the remaining token after gas is purchased for execution."]}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"fee-elimination",children:"Fee Elimination"}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["Under 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated ",(0,o.jsx)(t.strong,{children:"Gas Cost"})," for a configurable period of time known as the ",(0,o.jsx)(t.strong,{children:"Hold Period"}),". Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions."]}),"\n",(0,o.jsx)(t.h3,{id:"holds",children:"Holds"}),"\n",(0,o.jsx)(t.p,{children:"A hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse."}),"\n",(0,o.jsx)(t.h3,{id:"hold-release",children:"Hold Release"}),"\n",(0,o.jsxs)(t.p,{children:["The Casper Node 2.0 software currently supports two hold release models: ",(0,o.jsx)(t.strong,{children:"Accrued"})," and ",(0,o.jsx)(t.strong,{children:"Amortized"}),"."]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options."}),"\n"]}),"\n",(0,o.jsx)(t.h4,{id:"accrued",children:"Accrued"}),"\n",(0,o.jsx)(t.p,{children:"100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor."}),"\n",(0,o.jsx)(t.h4,{id:"amortized",children:"Amortized"}),"\n",(0,o.jsxs)(t.p,{children:["The effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold ",(0,o.jsx)(t.em,{children:"amount"})," is proportional to the percentage of the hold ",(0,o.jsx)(t.em,{children:"duration"})," that remains before expiry."]}),"\n",(0,o.jsx)(t.p,{children:"For example, if:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"A hold of 180 CSPR is placed on an purse which holds 1000 CSPR"}),"\n",(0,o.jsx)(t.li,{children:"The configured hold period is 90 days"}),"\n",(0,o.jsx)(t.li,{children:"The hold release model is configured to use amortization"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Then, 9 days after the hold was placed, the current effective amount of the hold may be calculated by"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"$\\frac{\\text{Hold Duration} - \\text{Time Elapsed}}{\\text{Hold Duration}} = \\frac{90 - 9}{90} = 0.9$"}),"\n",(0,o.jsx)(t.li,{children:"Multiplied by the hold amount: $180 \\times 0.9 = 162$"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The effective balance in that purse, at that point in time, is $1000 - 162 = 838 \\ \\text{CSPR}$"}),"\n",(0,o.jsx)(t.p,{children:"Over the course of the hold's duration, this calculation gives us:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,o.jsxs)(t.table,{children:[(0,o.jsx)(t.thead,{children:(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.th,{children:"Hold Amount"}),(0,o.jsx)(t.th,{children:"Hold Period"}),(0,o.jsx)(t.th,{children:"Time Elapsed"}),(0,o.jsx)(t.th,{children:"Effective Hold"})]})}),(0,o.jsxs)(t.tbody,{children:[(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"1"}),(0,o.jsx)(t.td,{children:"178"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"9"}),(0,o.jsx)(t.td,{children:"162"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"45"}),(0,o.jsx)(t.td,{children:"90"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"89"}),(0,o.jsx)(t.td,{children:"2"})]})]})]}),"\n",(0,o.jsx)(t.h3,{id:"more-about-gas-holds",children:"More about Gas holds"}),"\n",(0,o.jsxs)(t.p,{children:["The duration of gas holds is defined ",(0,o.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/feat-2.0/resources/production/chainspec.toml#L166",children:"here"})," in the ",(0,o.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," chainspec:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-toml",children:"# If fee_handling is set to 'no_fee', the system places a balance hold on the payer\n# equal to the value the fee would have been. Such balance holds expire after a time\n# interval has elapsed. This setting controls how long that interval is. The available\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\n#\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\n# a hold for 100 is placed on that purse and is considered when calculating total balance\n# for 24 hours starting from the block_time when the hold was placed.\ngas_hold_interval = '24 hours'\n"})}),"\n",(0,o.jsx)(t.h3,{id:"preventing-exploitation",children:"Preventing Exploitation"}),"\n",(0,o.jsx)(t.p,{children:"The ultimate goal of any gas mechanism is to prevent exploitation of a network's resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely."}),"\n",(0,o.jsx)(t.p,{children:"However, any gas mechanism that doesn't charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances."}),"\n",(0,o.jsx)(t.p,{children:"Attacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper's approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly."}),"\n",(0,o.jsxs)(t.p,{children:["Considering a token locking period of 30 days and the ",(0,o.jsx)(t.strong,{children:"Accrued"})," unlocking schedule, purchasing just 1% of the total block space of each block would cost:"]}),"\n",(0,o.jsx)(t.p,{children:"$\\frac{T}{B} \\cdot \\frac{G}{100} = 5,346,000 , \\text{CSPR}$"}),"\n",(0,o.jsx)(t.p,{children:"Where:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"T"})," = 30 day locking period"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"B"})," = 16 second blocktime"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"G"})," = 3300 CSPR block gas limit"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"If this proves to be too cheap, the locking period can be extended or the block gas limit increased."}),"\n",(0,o.jsx)(t.h4,{id:"opportunity-cost",children:"Opportunity Cost"}),"\n",(0,o.jsx)(t.p,{children:"In addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high."}),"\n",(0,o.jsx)(t.h3,{id:"incentivizing-validators",children:"Incentivizing Validators"}),"\n",(0,o.jsx)(t.p,{children:"The Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators."}),"\n",(0,o.jsxs)(t.p,{children:["Casper's solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current \"",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/E/#era",children:"era"}),'", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a "validator credit" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next ',(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/B/#booking-block",children:"booking block"})," appears."]}),"\n",(0,o.jsx)(t.h2,{id:"looking-forward",children:"Looking Forward"}),"\n",(0,o.jsx)(t.p,{children:"By introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols."}),"\n",(0,o.jsx)(t.p,{children:"As the model is rolled out to Casper's mainnet and testnet, economists and engineers will study its effects on Casper's transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented."}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.h3,{id:"further-readingterms",children:"Further Reading/Terms"}),"\n",(0,o.jsx)(t.h4,{id:"proposer",children:"Proposer"}),"\n",(0,o.jsxs)(t.p,{children:["A validator proposing a block to the network for execution",(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/economics/consensus/",children:"Consensus"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/V/#validator",children:"Validator"})]}),"\n",(0,o.jsx)(t.h4,{id:"fees",children:"Fees"}),"\n",(0,o.jsxs)(t.p,{children:["A portion of a transaction's gas costs given over to the proposer of the block containing that transaction.",(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/economics/gas-concepts/",children:"Gas Concepts"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/runtime/",children:"Runtime Economics"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/R/#reward",children:"Validator Rewards"})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0bd3b317.d740e1e1.js b/assets/js/0bd3b317.d740e1e1.js deleted file mode 100644 index 80b678453..000000000 --- a/assets/js/0bd3b317.d740e1e1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4643],{40975:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var o=n(74848),i=n(28453);const s={title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},a="Fee Elimination on Casper 2.0",r={permalink:"/blog/condor-fee-elimination",source:"@site/blog/2024-07-16-fee-elimination.md",title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",date:"2024-07-16T22:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"features",permalink:"/blog/tags/features"},{inline:!0,label:"tokenomics",permalink:"/blog/tags/tokenomics"}],readingTime:8.84,hasTruncateMarker:!0,authors:[{name:"Dylan Ireland",page:{permalink:"/blog/authors/dylanireland"},title:"Developer Advocate for Casper Association",url:"https://github.com/dylanireland",permalink:"/dylanireland",imageURL:"https://github.com/dylanireland.png",key:"dylanireland"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"},nextItem:{title:"Setting Up a Local Casper Condor Network for Development",permalink:"/blog/condor-local-setup"}},l={authorsImageUrls:[void 0,void 0]},d=[{value:"Concepts",id:"concepts",level:2},{value:"Payment, Gas Price, Fees",id:"payment-gas-price-fees",level:2},{value:"Fee Elimination",id:"fee-elimination",level:2},{value:"Holds",id:"holds",level:3},{value:"Hold Release",id:"hold-release",level:3},{value:"Accrued",id:"accrued",level:4},{value:"Amortized",id:"amortized",level:4},{value:"More about Gas holds",id:"more-about-gas-holds",level:3},{value:"Preventing Exploitation",id:"preventing-exploitation",level:3},{value:"Opportunity Cost",id:"opportunity-cost",level:4},{value:"Incentivizing Validators",id:"incentivizing-validators",level:3},{value:"Looking Forward",id:"looking-forward",level:2},{value:"Further Reading/Terms",id:"further-readingterms",level:3},{value:"Proposer",id:"proposer",level:4},{value:"Fees",id:"fees",level:4}];function c(e){const t={a:"a",blockquote:"blockquote",br:"br",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as ",(0,o.jsx)(t.strong,{children:"Fee Elimination"})," for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released."]}),"\n",(0,o.jsx)(t.h2,{id:"concepts",children:"Concepts"}),"\n",(0,o.jsxs)(t.p,{children:['Public distributed blockchain networks that support smart contracts generally employ a concept known as "',(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/G/#gas",children:"gas"}),'", which can be thought of as "the ability to do work on-chain". The problem addressed by this mechanism is that ',(0,o.jsx)(t.strong,{children:"any finite resource on a publicly accessible computer network must be rate-limited"}),", because a resource made available without limit is a denial of service attack vector."]}),"\n",(0,o.jsx)(t.p,{children:"Gas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor's available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses."}),"\n",(0,o.jsx)(t.h2,{id:"payment-gas-price-fees",children:"Payment, Gas Price, Fees"}),"\n",(0,o.jsxs)(t.p,{children:["On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the ",(0,o.jsx)(t.a,{href:"#proposer",children:"proposer"})," of that block in the form of transaction ",(0,o.jsx)(t.a,{href:"#fees",children:"fees"}),". The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:"]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Limit"}),": An amount of gas, specified by the transactor, at which to cancel a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Price"}),": The network gas price; the ratio between the cost of 1 unit of gas and 1 mote."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Gas Cost"}),": The amount of gas needed to pay for execution of a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Payment"}),": The amount of token specified by the transactor to pay for the execution of a transaction."]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.strong,{children:"Refund"}),": All or a portion of the remaining token after gas is purchased for execution."]}),"\n"]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article."}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"fee-elimination",children:"Fee Elimination"}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.p,{children:["Under 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated ",(0,o.jsx)(t.strong,{children:"Gas Cost"})," for a configurable period of time known as the ",(0,o.jsx)(t.strong,{children:"Hold Period"}),". Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions."]}),"\n",(0,o.jsx)(t.h3,{id:"holds",children:"Holds"}),"\n",(0,o.jsx)(t.p,{children:"A hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse."}),"\n",(0,o.jsx)(t.h3,{id:"hold-release",children:"Hold Release"}),"\n",(0,o.jsxs)(t.p,{children:["The Casper Node 2.0 software currently supports two hold release models: ",(0,o.jsx)(t.strong,{children:"Accrued"})," and ",(0,o.jsx)(t.strong,{children:"Amortized"}),"."]}),"\n",(0,o.jsxs)(t.blockquote,{children:["\n",(0,o.jsx)(t.p,{children:"The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options."}),"\n"]}),"\n",(0,o.jsx)(t.h4,{id:"accrued",children:"Accrued"}),"\n",(0,o.jsx)(t.p,{children:"100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor."}),"\n",(0,o.jsx)(t.h4,{id:"amortized",children:"Amortized"}),"\n",(0,o.jsxs)(t.p,{children:["The effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold ",(0,o.jsx)(t.em,{children:"amount"})," is proportional to the percentage of the hold ",(0,o.jsx)(t.em,{children:"duration"})," that remains before expiry."]}),"\n",(0,o.jsx)(t.p,{children:"For example, if:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"A hold of 180 CSPR is placed on an purse which holds 1000 CSPR"}),"\n",(0,o.jsx)(t.li,{children:"The configured hold period is 90 days"}),"\n",(0,o.jsx)(t.li,{children:"The hold release model is configured to use amortization"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"Then, 9 days after the hold was placed, the current effective amount of the hold may be calculated by"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"$\\frac{\\text{Hold Duration} - \\text{Time Elapsed}}{\\text{Hold Duration}} = \\frac{90 - 9}{90} = 0.9$"}),"\n",(0,o.jsx)(t.li,{children:"Multiplied by the hold amount: $180 \\times 0.9 = 162$"}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"The effective balance in that purse, at that point in time, is $1000 - 162 = 838 \\ \\text{CSPR}$"}),"\n",(0,o.jsx)(t.p,{children:"Over the course of the hold's duration, this calculation gives us:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,o.jsxs)(t.table,{children:[(0,o.jsx)(t.thead,{children:(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.th,{children:"Hold Amount"}),(0,o.jsx)(t.th,{children:"Hold Period"}),(0,o.jsx)(t.th,{children:"Time Elapsed"}),(0,o.jsx)(t.th,{children:"Effective Hold"})]})}),(0,o.jsxs)(t.tbody,{children:[(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"1"}),(0,o.jsx)(t.td,{children:"178"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"9"}),(0,o.jsx)(t.td,{children:"162"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"45"}),(0,o.jsx)(t.td,{children:"90"})]}),(0,o.jsxs)(t.tr,{children:[(0,o.jsx)(t.td,{children:"180"}),(0,o.jsx)(t.td,{children:"90"}),(0,o.jsx)(t.td,{children:"89"}),(0,o.jsx)(t.td,{children:"2"})]})]})]}),"\n",(0,o.jsx)(t.h3,{id:"more-about-gas-holds",children:"More about Gas holds"}),"\n",(0,o.jsxs)(t.p,{children:["The duration of gas holds is defined ",(0,o.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/feat-2.0/resources/production/chainspec.toml#L166",children:"here"})," in the ",(0,o.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," chainspec:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-toml",children:"# If fee_handling is set to 'no_fee', the system places a balance hold on the payer\n# equal to the value the fee would have been. Such balance holds expire after a time\n# interval has elapsed. This setting controls how long that interval is. The available\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\n#\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\n# a hold for 100 is placed on that purse and is considered when calculating total balance\n# for 24 hours starting from the block_time when the hold was placed.\ngas_hold_interval = '24 hours'\n"})}),"\n",(0,o.jsx)(t.h3,{id:"preventing-exploitation",children:"Preventing Exploitation"}),"\n",(0,o.jsx)(t.p,{children:"The ultimate goal of any gas mechanism is to prevent exploitation of a network's resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely."}),"\n",(0,o.jsx)(t.p,{children:"However, any gas mechanism that doesn't charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances."}),"\n",(0,o.jsx)(t.p,{children:"Attacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper's approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly."}),"\n",(0,o.jsxs)(t.p,{children:["Considering a token locking period of 30 days and the ",(0,o.jsx)(t.strong,{children:"Accrued"})," unlocking schedule, purchasing just 1% of the total block space of each block would cost:"]}),"\n",(0,o.jsx)(t.p,{children:"$\\frac{T}{B} \\cdot \\frac{G}{100} = 5,346,000 , \\text{CSPR}$"}),"\n",(0,o.jsx)(t.p,{children:"Where:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"T"})," = 30 day locking period"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"B"})," = 16 second blocktime"]}),"\n",(0,o.jsxs)(t.li,{children:[(0,o.jsx)(t.code,{children:"G"})," = 3300 CSPR block gas limit"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"If this proves to be too cheap, the locking period can be extended or the block gas limit increased."}),"\n",(0,o.jsx)(t.h4,{id:"opportunity-cost",children:"Opportunity Cost"}),"\n",(0,o.jsx)(t.p,{children:"In addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high."}),"\n",(0,o.jsx)(t.h3,{id:"incentivizing-validators",children:"Incentivizing Validators"}),"\n",(0,o.jsx)(t.p,{children:"The Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators."}),"\n",(0,o.jsxs)(t.p,{children:["Casper's solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current \"",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/E/#era",children:"era"}),'", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a "validator credit" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next ',(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/B/#booking-block",children:"booking block"})," appears."]}),"\n",(0,o.jsx)(t.h2,{id:"looking-forward",children:"Looking Forward"}),"\n",(0,o.jsx)(t.p,{children:"By introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols."}),"\n",(0,o.jsx)(t.p,{children:"As the model is rolled out to Casper's mainnet and testnet, economists and engineers will study its effects on Casper's transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented."}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.h3,{id:"further-readingterms",children:"Further Reading/Terms"}),"\n",(0,o.jsx)(t.h4,{id:"proposer",children:"Proposer"}),"\n",(0,o.jsxs)(t.p,{children:["A validator proposing a block to the network for execution",(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/economics/consensus/",children:"Consensus"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/V/#validator",children:"Validator"})]}),"\n",(0,o.jsx)(t.h4,{id:"fees",children:"Fees"}),"\n",(0,o.jsxs)(t.p,{children:["A portion of a transaction's gas costs given over to the proposer of the block containing that transaction.",(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/economics/gas-concepts/",children:"Gas Concepts"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/runtime/",children:"Runtime Economics"}),(0,o.jsx)(t.br,{}),"\n",(0,o.jsx)(t.a,{href:"https://docs.casper.network/concepts/glossary/R/#reward",children:"Validator Rewards"})]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var o=n(96540);const i={},s=o.createContext(i);function a(e){const t=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c098c15.5f193e57.js b/assets/js/0c098c15.5f193e57.js deleted file mode 100644 index 82fbf12f8..000000000 --- a/assets/js/0c098c15.5f193e57.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5884],{82880:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var a=t(74848),r=t(28453);const i={},o="Upgrading and Maintaining Smart Contracts",c={id:"developers/writing-onchain-code/upgrading-contracts",title:"Upgrading and Maintaining Smart Contracts",description:"Our smart contract packaging tools enable you to:",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/upgrading-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/upgrading-contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Testing Smart Contracts",permalink:"/developers/writing-onchain-code/testing-contracts"},next:{title:"Calling Contracts",permalink:"/developers/writing-onchain-code/calling-contracts"}},s={},d=[{value:"The Contract Package",id:"the-contract-package",level:2},{value:"Videos and Tutorials",id:"videos-and-tutorials",level:2},{value:"Maintaining a Contract",id:"maintaining-a-contract",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-and-maintaining-smart-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),"\n",(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsx)(n.p,{children:"Our smart contract packaging tools enable you to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Upgrade your contracts and specify how the state of the contract is managed"}),"\n",(0,a.jsx)(n.li,{children:"Specify whether a contract is upgradable or immutable"}),"\n",(0,a.jsx)(n.li,{children:"Version your contracts and deprecate old versions"}),"\n",(0,a.jsx)(n.li,{children:"Set permissions around who can perform contract upgrades"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"the-contract-package",children:"The Contract Package"}),"\n",(0,a.jsx)(n.p,{children:"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. If you find that you need to use a disabled contract version, you may also re-enable it."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:t(66407).A+"",width:"1170",height:"472"})}),"\n",(0,a.jsx)(n.p,{children:"The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain."}),"\n",(0,a.jsx)(n.h2,{id:"videos-and-tutorials",children:"Videos and Tutorials"}),"\n",(0,a.jsxs)(n.p,{children:["To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})," documentation."]}),"\n",(0,a.jsxs)(n.p,{align:"center",children:["\n",(0,a.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=10",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Or, for a different perspective, consult the ",(0,a.jsx)(n.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrade Tutorial"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"maintaining-a-contract",children:"Maintaining a Contract"}),"\n",(0,a.jsx)(n.p,{children:"The contract maintenance process is generally covered through the contract upgrade process."}),"\n",(0,a.jsx)(n.p,{children:"Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance."}),"\n",(0,a.jsx)(n.p,{children:"On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},66407:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/package-representation-5e72ef8539f89dbe682c86c52d9536c8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var a=t(96540);const r={},i=a.createContext(r);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0c098c15.9fdd6a6d.js b/assets/js/0c098c15.9fdd6a6d.js new file mode 100644 index 000000000..9b812e519 --- /dev/null +++ b/assets/js/0c098c15.9fdd6a6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[45884],{82880:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var a=t(74848),r=t(28453);const i={},o="Upgrading and Maintaining Smart Contracts",c={id:"developers/writing-onchain-code/upgrading-contracts",title:"Upgrading and Maintaining Smart Contracts",description:"Our smart contract packaging tools enable you to:",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/upgrading-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/upgrading-contracts",permalink:"/1.5.X/developers/writing-onchain-code/upgrading-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Testing Smart Contracts",permalink:"/1.5.X/developers/writing-onchain-code/testing-contracts"},next:{title:"Calling Contracts",permalink:"/1.5.X/developers/writing-onchain-code/calling-contracts"}},s={},d=[{value:"The Contract Package",id:"the-contract-package",level:2},{value:"Videos and Tutorials",id:"videos-and-tutorials",level:2},{value:"Maintaining a Contract",id:"maintaining-a-contract",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-and-maintaining-smart-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),"\n",(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsx)(n.p,{children:"Our smart contract packaging tools enable you to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Upgrade your contracts and specify how the state of the contract is managed"}),"\n",(0,a.jsx)(n.li,{children:"Specify whether a contract is upgradable or immutable"}),"\n",(0,a.jsx)(n.li,{children:"Version your contracts and deprecate old versions"}),"\n",(0,a.jsx)(n.li,{children:"Set permissions around who can perform contract upgrades"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"the-contract-package",children:"The Contract Package"}),"\n",(0,a.jsx)(n.p,{children:"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. If you find that you need to use a disabled contract version, you may also re-enable it."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:t(84181).A+"",width:"1170",height:"472"})}),"\n",(0,a.jsx)(n.p,{children:"The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain."}),"\n",(0,a.jsx)(n.h2,{id:"videos-and-tutorials",children:"Videos and Tutorials"}),"\n",(0,a.jsxs)(n.p,{children:["To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})," documentation."]}),"\n",(0,a.jsxs)(n.p,{align:"center",children:["\n",(0,a.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=10",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Or, for a different perspective, consult the ",(0,a.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrade Tutorial"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"maintaining-a-contract",children:"Maintaining a Contract"}),"\n",(0,a.jsx)(n.p,{children:"The contract maintenance process is generally covered through the contract upgrade process."}),"\n",(0,a.jsx)(n.p,{children:"Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance."}),"\n",(0,a.jsx)(n.p,{children:"On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},84181:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/package-representation-5e72ef8539f89dbe682c86c52d9536c8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var a=t(96540);const r={},i=a.createContext(r);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0cde4ba3.766b9399.js b/assets/js/0cde4ba3.766b9399.js new file mode 100644 index 000000000..c93fa281e --- /dev/null +++ b/assets/js/0cde4ba3.766b9399.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97491],{8542:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var r=t(74848),s=t(28453);const d={slug:"/resources/tokens/"},c="Casper Token Standards",i={id:"resources/tokens/index",title:"Casper Token Standards",description:"CEP-18 Casper Fungible Token Standard",source:"@site/docs/resources/tokens/index.md",sourceDirName:"resources/tokens",slug:"/resources/tokens/",permalink:"/resources/tokens/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{slug:"/resources/tokens/"},sidebar:"resources",previous:{title:"Move to Casper",permalink:"/resources/moving-to-casper"},next:{title:"Fungible Token Workflow",permalink:"/resources/tokens/cep18/full-tutorial"}},a={},o=[{value:"CEP-18 Casper Fungible Token Standard",id:"cep-18-casper-fungible-token-standard",level:2},{value:"CEP-78 Enhanced NFT Standard",id:"cep-78-enhanced-nft-standard",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"casper-token-standards",children:"Casper Token Standards"})}),"\n",(0,r.jsx)(n.h2,{id:"cep-18-casper-fungible-token-standard",children:"CEP-18 Casper Fungible Token Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/full-tutorial",children:"A Casper Fungible Token Tutorial"})}),(0,r.jsx)(n.td,{children:"A full tutorial for use of the CEP-18 Casper Fungible Token Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/quickstart-guide",children:"Installing and Interacting with a CEP-18 Contract"})}),(0,r.jsx)(n.td,{children:"A quickstart guide for installing a CEP-18 contract with the Rust Casper Client."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP-18 Contracts"})}),(0,r.jsx)(n.td,{children:"A guide to interacting with installed CEP-18 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),(0,r.jsx)(n.td,{children:"A guide for transferring Casper Fungible Tokens."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),(0,r.jsx)(n.td,{children:"A CEP-18 testing framework using the Casper engine test support crate."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"cep-78-enhanced-nft-standard",children:"CEP-78 Enhanced NFT Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),(0,r.jsx)(n.td,{children:"An introduction to the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/introduction",children:"CEP-78 Modalities"})}),(0,r.jsx)(n.td,{children:"Information on the features available when installing a CEP-78 contract instance."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/using-casper-client",children:"Installing and Interacting with a CEP-78 Contract"})}),(0,r.jsx)(n.td,{children:"An introduction to features present in the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"Owner Reverse Lookup Functionality"})}),(0,r.jsx)(n.td,{children:"Information on the Onwer Reverse Lookup feature of CEP-78 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/js-tutorial",children:"A CEP-78 JavaScript Client Tutorial"})}),(0,r.jsx)(n.td,{children:"A tutorial for using the JavaScript CEP-78 client."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var r=t(96540);const s={},d=r.createContext(s);function c(e){const n=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0cde4ba3.db3b01f2.js b/assets/js/0cde4ba3.db3b01f2.js deleted file mode 100644 index 2cd5402d7..000000000 --- a/assets/js/0cde4ba3.db3b01f2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7491],{8542:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var r=t(74848),s=t(28453);const d={slug:"/resources/tokens/"},c="Casper Token Standards",i={id:"resources/tokens/index",title:"Casper Token Standards",description:"CEP-18 Casper Fungible Token Standard",source:"@site/docs/resources/tokens/index.md",sourceDirName:"resources/tokens",slug:"/resources/tokens/",permalink:"/next/resources/tokens/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{slug:"/resources/tokens/"},sidebar:"resources",previous:{title:"Move to Casper",permalink:"/next/resources/moving-to-casper"},next:{title:"Fungible Token Workflow",permalink:"/next/resources/tokens/cep18/full-tutorial"}},a={},o=[{value:"CEP-18 Casper Fungible Token Standard",id:"cep-18-casper-fungible-token-standard",level:2},{value:"CEP-78 Enhanced NFT Standard",id:"cep-78-enhanced-nft-standard",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"casper-token-standards",children:"Casper Token Standards"})}),"\n",(0,r.jsx)(n.h2,{id:"cep-18-casper-fungible-token-standard",children:"CEP-18 Casper Fungible Token Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep18/full-tutorial",children:"A Casper Fungible Token Tutorial"})}),(0,r.jsx)(n.td,{children:"A full tutorial for use of the CEP-18 Casper Fungible Token Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep18/quickstart-guide",children:"Installing and Interacting with a CEP-18 Contract"})}),(0,r.jsx)(n.td,{children:"A quickstart guide for installing a CEP-18 contract with the Rust Casper Client."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep18/query",children:"Exploring the CEP-18 Contracts"})}),(0,r.jsx)(n.td,{children:"A guide to interacting with installed CEP-18 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),(0,r.jsx)(n.td,{children:"A guide for transferring Casper Fungible Tokens."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),(0,r.jsx)(n.td,{children:"A CEP-18 testing framework using the Casper engine test support crate."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"cep-78-enhanced-nft-standard",children:"CEP-78 Enhanced NFT Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep78/introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),(0,r.jsx)(n.td,{children:"An introduction to the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep78/introduction",children:"CEP-78 Modalities"})}),(0,r.jsx)(n.td,{children:"Information on the features available when installing a CEP-78 contract instance."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/using-casper-client",children:"Installing and Interacting with a CEP-78 Contract"})}),(0,r.jsx)(n.td,{children:"An introduction to features present in the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep78/reverse-lookup",children:"Owner Reverse Lookup Functionality"})}),(0,r.jsx)(n.td,{children:"Information on the Onwer Reverse Lookup feature of CEP-78 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tokens/cep78/js-tutorial",children:"A CEP-78 JavaScript Client Tutorial"})}),(0,r.jsx)(n.td,{children:"A tutorial for using the JavaScript CEP-78 client."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>i});var r=t(96540);const s={},d=r.createContext(s);function c(e){const n=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0dea8207.469d8eba.js b/assets/js/0dea8207.469d8eba.js new file mode 100644 index 000000000..701d6034d --- /dev/null +++ b/assets/js/0dea8207.469d8eba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72352],{48563:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=s(74848),a=s(28453);const r={},o=".NET SDK",c={id:"developers/dapps/sdk/csharp-sdk",title:".NET SDK",description:"The C# .NET SDK allows developers to interact with a Casper network using C#.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/csharp-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/csharp-sdk",permalink:"/1.5.X/developers/dapps/sdk/csharp-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"JavaScript/TypeScript SDK",permalink:"/1.5.X/developers/dapps/sdk/script-sdk"},next:{title:"Go SDK",permalink:"/1.5.X/developers/dapps/sdk/go-sdk"}},i={},d=[{value:"Documentation",id:"documentation",level:2},{value:"Get started",id:"get-started",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"net-sdk",children:".NET SDK"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"C# .NET SDK"})," allows developers to interact with a Casper network using C#."]}),"\n",(0,t.jsx)(n.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find the SDK documentation, examples, and tutorials."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get started"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing."}),"\n",(0,t.jsx)(n.p,{children:"Open a terminal window and create a new console app:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet new console -o GetAccountBalance\ncd GetAccountBalance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The Casper.Network.SDK for .NET is published on ",(0,t.jsx)(n.a,{href:"https://www.nuget.org/packages/Casper.Network.SDK",children:"nuget.org"})," as a NuGet package."]}),"\n",(0,t.jsxs)(n.p,{children:["To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the ",(0,t.jsx)(n.code,{children:"dotnet"})," CLI tool."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Package Manager (Windows)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Install-Package Casper.Network.SDK\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"dotnet CLI Tool (Windows, Mac, and Linux)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet add package Casper.Network.SDK\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, replace the default code in ",(0,t.jsx)(n.code,{children:"Program.cs"})," with this main program:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'using System;\nusing System.Threading.Tasks;\nusing Casper.Network.SDK;\nusing Casper.Network.SDK.JsonRpc;\nusing Casper.Network.SDK.Types;\n\nnamespace Casper.NET.SDK.Examples\n{\n public class GetAccountBalance\n {\n public static async Task Main(string[] args)\n {\n string nodeAddress = "http://testnet-node.make.services:7777";\n\n var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";\n var publicKey = PublicKey.FromHexString(hex);\n\n try\n {\n var casperSdk = new NetCasperClient(nodeAddress);\n\n // Get the balance using the account public key\n //\n var rpcResponse = await casperSdk.GetAccountBalance(publicKey);\n Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);\n }\n catch (RpcClientException e)\n {\n Console.WriteLine("ERROR:\\n" + e.RpcError.Message);\n }\n catch (Exception e)\n {\n Console.WriteLine(e);\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, run the example with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet run\n"})}),"\n",(0,t.jsx)(n.p,{children:"The program will print the account's main purse balance retrieved from the testnet."}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find other examples, tutorials, and complete documentation for this SDK."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0dea8207.4f27fd0b.js b/assets/js/0dea8207.4f27fd0b.js deleted file mode 100644 index 654abb31d..000000000 --- a/assets/js/0dea8207.4f27fd0b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2352],{48563:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=s(74848),a=s(28453);const r={},o=".NET SDK",c={id:"developers/dapps/sdk/csharp-sdk",title:".NET SDK",description:"The C# .NET SDK allows developers to interact with a Casper network using C#.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/csharp-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/csharp-sdk",permalink:"/developers/dapps/sdk/csharp-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"},next:{title:"Go SDK",permalink:"/developers/dapps/sdk/go-sdk"}},i={},d=[{value:"Documentation",id:"documentation",level:2},{value:"Get started",id:"get-started",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"net-sdk",children:".NET SDK"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"C# .NET SDK"})," allows developers to interact with a Casper network using C#."]}),"\n",(0,t.jsx)(n.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find the SDK documentation, examples, and tutorials."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get started"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing."}),"\n",(0,t.jsx)(n.p,{children:"Open a terminal window and create a new console app:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet new console -o GetAccountBalance\ncd GetAccountBalance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The Casper.Network.SDK for .NET is published on ",(0,t.jsx)(n.a,{href:"https://www.nuget.org/packages/Casper.Network.SDK",children:"nuget.org"})," as a NuGet package."]}),"\n",(0,t.jsxs)(n.p,{children:["To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the ",(0,t.jsx)(n.code,{children:"dotnet"})," CLI tool."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Package Manager (Windows)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Install-Package Casper.Network.SDK\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"dotnet CLI Tool (Windows, Mac, and Linux)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet add package Casper.Network.SDK\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, replace the default code in ",(0,t.jsx)(n.code,{children:"Program.cs"})," with this main program:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'using System;\nusing System.Threading.Tasks;\nusing Casper.Network.SDK;\nusing Casper.Network.SDK.JsonRpc;\nusing Casper.Network.SDK.Types;\n\nnamespace Casper.NET.SDK.Examples\n{\n public class GetAccountBalance\n {\n public static async Task Main(string[] args)\n {\n string nodeAddress = "http://testnet-node.make.services:7777";\n\n var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";\n var publicKey = PublicKey.FromHexString(hex);\n\n try\n {\n var casperSdk = new NetCasperClient(nodeAddress);\n\n // Get the balance using the account public key\n //\n var rpcResponse = await casperSdk.GetAccountBalance(publicKey);\n Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);\n }\n catch (RpcClientException e)\n {\n Console.WriteLine("ERROR:\\n" + e.RpcError.Message);\n }\n catch (Exception e)\n {\n Console.WriteLine(e);\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, run the example with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet run\n"})}),"\n",(0,t.jsx)(n.p,{children:"The program will print the account's main purse balance retrieved from the testnet."}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find other examples, tutorials, and complete documentation for this SDK."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0fa7e001.d0182770.js b/assets/js/0fa7e001.d0182770.js new file mode 100644 index 000000000..eccb0365f --- /dev/null +++ b/assets/js/0fa7e001.d0182770.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1971],{21239:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=s(74848),r=s(28453);const i={},a="Prerequisites",o={id:"developers/dapps/prerequisites",title:"Prerequisites",description:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:",source:"@site/versioned_docs/version-2.0.0/developers/dapps/prerequisites.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/prerequisites",permalink:"/2.0.0/developers/dapps/prerequisites",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"What is a dApp?",permalink:"/2.0.0/developers/dapps/dapp"},next:{title:"SDK Client Libraries",permalink:"/2.0.0/sdk"}},d={},l=[{value:"Development Considerations",id:"development-considerations",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"prerequisites",children:"Prerequisites"})}),"\n",(0,t.jsx)(n.p,{children:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up your ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"development environment"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Be sure you understand the language(s) you are developing in."}),"\n",(0,t.jsx)(n.p,{children:"Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you."}),"\n",(0,t.jsxs)(n.p,{children:["The preferred stack for building on Casper is JavaScript using the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),", however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the ",(0,t.jsx)(n.a,{href:"/2.0.0/sdk",children:"Introduction to SDKs"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Familiarize yourself with the fundamentals of Casper networks."}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the ",(0,t.jsx)(n.a,{href:"/2.0.0/design",children:"design section"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Read the documentation or source code of your chosen SDK."}),"\n",(0,t.jsxs)(n.p,{children:["Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/sdk/client-library-usage",children:"Client Library Usage"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"development-considerations",children:"Development Considerations"}),"\n",(0,t.jsx)(n.p,{children:"When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value."}),"\n",(0,t.jsx)(n.p,{children:"To ensure the highest level of security, consider the following practices:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code."}),"\n",(0,t.jsx)(n.li,{children:"Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors."}),"\n",(0,t.jsx)(n.li,{children:"Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet."}),"\n",(0,t.jsx)(n.li,{children:"Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes."}),"\n",(0,t.jsx)(n.li,{children:"Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/106a38e1.01a8cfcd.js b/assets/js/106a38e1.01a8cfcd.js deleted file mode 100644 index 4ddad8ee4..000000000 --- a/assets/js/106a38e1.01a8cfcd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8256],{82480:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(74848),i=t(28453);const a={},o="Redelegating Tokens with the Casper Client",r={id:"developers/cli/redelegate",title:"Redelegating Tokens with the Casper Client",description:"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.",source:"@site/versioned_docs/version-1.5.X/developers/cli/redelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/redelegate",permalink:"/developers/cli/redelegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Delegating Tokens",permalink:"/developers/cli/delegate"},next:{title:"Undelegating Tokens",permalink:"/developers/cli/undelegate"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Redelegating with the System Auction Contract",id:"redelegating-system-auction",level:2},{value:"Method 2: Redelegating with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Sending the redelegation request",id:"sending-the-redelegation-deploy",level:3},{value:"Verifying the Redelegation",id:"verifying-the-redelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"redelegating-tokens-with-the-casper-client",children:"Redelegating Tokens with the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an ",(0,s.jsx)(n.a,{href:"/developers/cli/undelegate",children:"unbonding request"})," first and then ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegate"})," the tokens to the new validator."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network, and you have the validator's public key"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the public key of the new validator to whom you wish to redelegate tokens. See ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})," for more details"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"redelegating-system-auction",children:"Method 1: Redelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount 2500000000 \\\n--session-hash \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-redelegation",children:"verify the redelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Redelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a redelegation is to compile the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that will include the redelegation Wasm."]}),"\n",(0,s.jsx)(n.h3,{id:"sending-the-redelegation-deploy",children:"Sending the redelegation request"}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," to the network to initiate the redelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /redelegate.wasm \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Save the returned ",(0,s.jsx)(n.em,{children:"deploy_hash"})," from the output to ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"query information"})," about the redelegation Deploy."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Running the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," is a more expensive operation than calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entrypoint from the system auction contract."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-redelegation",children:"Verifying the Redelegation"}),"\n",(0,s.jsx)(n.p,{children:"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."}),"\n",(0,s.jsxs)(n.p,{children:["Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#confirming-the-delegation",children:"verifying a delegation request"})," using the ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/106a38e1.08a834c1.js b/assets/js/106a38e1.08a834c1.js new file mode 100644 index 000000000..fea5c5f14 --- /dev/null +++ b/assets/js/106a38e1.08a834c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8256],{82480:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(74848),i=t(28453);const a={},o="Redelegating Tokens with the Casper Client",r={id:"developers/cli/redelegate",title:"Redelegating Tokens with the Casper Client",description:"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.",source:"@site/versioned_docs/version-1.5.X/developers/cli/redelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/redelegate",permalink:"/1.5.X/developers/cli/redelegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Delegating Tokens",permalink:"/1.5.X/developers/cli/delegate"},next:{title:"Undelegating Tokens",permalink:"/1.5.X/developers/cli/undelegate"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Redelegating with the System Auction Contract",id:"redelegating-system-auction",level:2},{value:"Method 2: Redelegating with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Sending the redelegation request",id:"sending-the-redelegation-deploy",level:3},{value:"Verifying the Redelegation",id:"verifying-the-redelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"redelegating-tokens-with-the-casper-client",children:"Redelegating Tokens with the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/undelegate",children:"unbonding request"})," first and then ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"delegate"})," the tokens to the new validator."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network, and you have the validator's public key"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the public key of the new validator to whom you wish to redelegate tokens. See ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})," for more details"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"redelegating-system-auction",children:"Method 1: Redelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount 2500000000 \\\n--session-hash \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-redelegation",children:"verify the redelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Redelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a redelegation is to compile the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that will include the redelegation Wasm."]}),"\n",(0,s.jsx)(n.h3,{id:"sending-the-redelegation-deploy",children:"Sending the redelegation request"}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," to the network to initiate the redelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address \\\n--secret-key \\\n--chain-name \\\n--payment-amount \\\n--session-path /redelegate.wasm \\\n--session-arg \"delegator:public_key=''\" \\\n--session-arg \"validator:public_key=''\" \\\n--session-arg \"amount:u512=''\" \\\n--session-arg \"new_validator:public_key=''\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Save the returned ",(0,s.jsx)(n.em,{children:"deploy_hash"})," from the output to ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"query information"})," about the redelegation Deploy."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Running the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," is a more expensive operation than calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entrypoint from the system auction contract."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-redelegation",children:"Verifying the Redelegation"}),"\n",(0,s.jsx)(n.p,{children:"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."}),"\n",(0,s.jsxs)(n.p,{children:["Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate#confirming-the-delegation",children:"verifying a delegation request"})," using the ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/106b67a5.5be98423.js b/assets/js/106b67a5.5be98423.js new file mode 100644 index 000000000..c420c0e41 --- /dev/null +++ b/assets/js/106b67a5.5be98423.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50899],{65699:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=n(74848),r=n(28453);const c={},i="Testing Smart Contracts",a={id:"developers/writing-onchain-code/testing-contracts",title:"Testing Smart Contracts",description:"Introduction",source:"@site/docs/developers/writing-onchain-code/testing-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-contracts",permalink:"/developers/writing-onchain-code/testing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing a Basic Smart Contract in Rust",permalink:"/developers/writing-onchain-code/simple-contract"},next:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts"}},o={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Defining Dependencies in Cargo.toml",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-smart-contracts",children:"Testing Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the Casper development environment, we provide a ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/",children:"testing framework"})," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful transactions and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework."})}),"\n",(0,s.jsxs)(t.h3,{id:"defining-dependencies-in-cargotoml",children:["Defining Dependencies in ",(0,s.jsx)(t.code,{children:"Cargo.toml"})]}),"\n",(0,s.jsxs)(t.p,{children:["This guide uses the project structure, and example contract outlined ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"})," for creating tests."]}),"\n",(0,s.jsxs)(t.p,{children:["To begin, outline the required test dependencies in the ",(0,s.jsx)(t.code,{children:"/tests/Cargo.toml"})," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'[dependencies]\ncasper-execution-engine = "2.0.1"\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-types = "1.5.0"\n'})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The tests for the contract usually reside in the ",(0,s.jsx)(t.code,{children:"tests"})," directory. Tests for the counter contract reside in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file. Notice that this file contains an empty ",(0,s.jsx)(t.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,s.jsx)(t.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.jsx)(t.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.jsx)(t.code,{children:"mod tests"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"importing-builders-and-constants",children:"Importing Builders and Constants"}),"\n",(0,s.jsxs)(t.p,{children:["Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/types_cl",children:"CLTypes"})," used within the contract code to be tested."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n"})}),"\n",(0,s.jsx)(t.p,{children:"Next, you need to define any global variables or constants for the test."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract\n const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract\n const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract\n\n const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract\n const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement\n const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package\n\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value\n'})}),"\n",(0,s.jsx)(t.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,s.jsxs)(t.p,{children:["Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.jsx)(t.code,{children:"InMemoryWasmTestBuilder"})," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."]}),"\n",(0,s.jsxs)(t.p,{children:["As part of this process, we use the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"})," to install the system contracts necessary for the tests, including the ",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"}),", and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"contracts, as well as establishing a default account and funding the associated purse."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n"})}),"\n",(0,s.jsx)(t.h4,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["Test functions use the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," established by our genesis builder as the account sending the transaction."]}),"\n",(0,s.jsxs)(t.p,{children:["After building the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," (in this example, ",(0,s.jsx)(t.code,{children:"contract_installation_request"}),"), we process the request through ",(0,s.jsx)(t.code,{children:"builder.exec"})," and then add and process other requests as necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-by-hash",children:"Calling the Contract by Hash"}),"\n",(0,s.jsxs)(t.p,{children:["To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," function. The following code retrieves the contract hash from the named keys of the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that sent the installation transaction."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n'})}),"\n",(0,s.jsx)(t.p,{children:"Next, we test an entry point that should not exist in the first version of the contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-using-session-code",children:"Calling the Contract using Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["In the counter example, we use the session code included in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call.wasm"})," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"next section"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following session code uses the contract hash to identify the contract, the account for sending the transaction (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the transaction to be sent (",(0,s.jsx)(t.code,{children:"COUNTER_CALL_WASM"}),"), and the runtime arguments required. Once again, the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," simulates the execution of session code and calls the ",(0,s.jsx)(t.code,{children:"counter-inc"})," entry point."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"evaluating-and-comparing-results",children:"Evaluating and Comparing Results"}),"\n",(0,s.jsxs)(t.p,{children:["After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.jsx)(t.code,{children:"builder"})," method retrieves the required information and converts it to the value type required. Then, ",(0,s.jsx)(t.code,{children:"assert_eq!()"})," compares the result against the expected value."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,s.jsxs)(t.p,{children:["For more test examples, visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,s.jsx)(t.h2,{id:"testing-contracts-that-call-contracts",children:"Testing Contracts that Call Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"}),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."]}),"\n",(0,s.jsxs)(t.p,{children:["Each contract installation will require an additional Wasm file installed through a ",(0,s.jsx)(t.code,{children:"Transaction"})," using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"return values"})," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."]}),"\n",(0,s.jsxs)(t.p,{children:["The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," - Calling a contract by its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_name"})," - Calling a contract referenced by a named key in the signer's Account context."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_hash"})," - Calling a specific contract version using its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_name"})," - Calling a specific version of a contract referenced by a named key in the signer's Account context."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, the counter example uses a ",(0,s.jsx)(t.code,{children:"Makefile"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Under the hood, the ",(0,s.jsx)(t.code,{children:"Makefile"})," generates a ",(0,s.jsx)(t.code,{children:"tests/wasm"})," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.jsx)(t.code,{children:"cargo test"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"test: build-contract\n\tmkdir -p tests/wasm\n\tcp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n\tcp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n\tcp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n\tcd tests && cargo test\n"})}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsxs)(t.p,{children:["The following brief video describes testing ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"sample contract code"}),"."]}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"further-testing",children:"Further Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"local network testing"})," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.jsx)(t.a,{href:"/developers/dapps/nctl-test",children:"testing in an other simulated network environment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You may also wish to test your contracts on the Casper ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Understand ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,s.jsxs)(t.li,{children:["Learn to ",(0,s.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},c=s.createContext(r);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/106b67a5.9d743cdc.js b/assets/js/106b67a5.9d743cdc.js deleted file mode 100644 index f3e74b4b0..000000000 --- a/assets/js/106b67a5.9d743cdc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[899],{65699:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=n(74848),r=n(28453);const c={},i="Testing Smart Contracts",a={id:"developers/writing-onchain-code/testing-contracts",title:"Testing Smart Contracts",description:"Introduction",source:"@site/docs/developers/writing-onchain-code/testing-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-contracts",permalink:"/next/developers/writing-onchain-code/testing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing a Basic Smart Contract in Rust",permalink:"/next/developers/writing-onchain-code/simple-contract"},next:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/next/developers/writing-onchain-code/upgrading-contracts"}},o={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Defining Dependencies in Cargo.toml",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-smart-contracts",children:"Testing Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the Casper development environment, we provide a ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/",children:"testing framework"})," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful transactions and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework."})}),"\n",(0,s.jsxs)(t.h3,{id:"defining-dependencies-in-cargotoml",children:["Defining Dependencies in ",(0,s.jsx)(t.code,{children:"Cargo.toml"})]}),"\n",(0,s.jsxs)(t.p,{children:["This guide uses the project structure, and example contract outlined ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"})," for creating tests."]}),"\n",(0,s.jsxs)(t.p,{children:["To begin, outline the required test dependencies in the ",(0,s.jsx)(t.code,{children:"/tests/Cargo.toml"})," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'[dependencies]\ncasper-execution-engine = "2.0.1"\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-types = "1.5.0"\n'})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The tests for the contract usually reside in the ",(0,s.jsx)(t.code,{children:"tests"})," directory. Tests for the counter contract reside in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file. Notice that this file contains an empty ",(0,s.jsx)(t.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,s.jsx)(t.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.jsx)(t.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.jsx)(t.code,{children:"mod tests"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"importing-builders-and-constants",children:"Importing Builders and Constants"}),"\n",(0,s.jsxs)(t.p,{children:["Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.jsx)(t.a,{href:"/next/developers/json-rpc/types_cl",children:"CLTypes"})," used within the contract code to be tested."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n"})}),"\n",(0,s.jsx)(t.p,{children:"Next, you need to define any global variables or constants for the test."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract\n const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract\n const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract\n\n const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract\n const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement\n const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package\n\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value\n'})}),"\n",(0,s.jsx)(t.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,s.jsxs)(t.p,{children:["Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.jsx)(t.code,{children:"InMemoryWasmTestBuilder"})," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."]}),"\n",(0,s.jsxs)(t.p,{children:["As part of this process, we use the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"})," to install the system contracts necessary for the tests, including the ",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"}),", and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"contracts, as well as establishing a default account and funding the associated purse."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n"})}),"\n",(0,s.jsx)(t.h4,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["Test functions use the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," established by our genesis builder as the account sending the transaction."]}),"\n",(0,s.jsxs)(t.p,{children:["After building the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," (in this example, ",(0,s.jsx)(t.code,{children:"contract_installation_request"}),"), we process the request through ",(0,s.jsx)(t.code,{children:"builder.exec"})," and then add and process other requests as necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-by-hash",children:"Calling the Contract by Hash"}),"\n",(0,s.jsxs)(t.p,{children:["To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," function. The following code retrieves the contract hash from the named keys of the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that sent the installation transaction."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n'})}),"\n",(0,s.jsx)(t.p,{children:"Next, we test an entry point that should not exist in the first version of the contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-using-session-code",children:"Calling the Contract using Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["In the counter example, we use the session code included in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call.wasm"})," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"next section"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following session code uses the contract hash to identify the contract, the account for sending the transaction (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the transaction to be sent (",(0,s.jsx)(t.code,{children:"COUNTER_CALL_WASM"}),"), and the runtime arguments required. Once again, the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," simulates the execution of session code and calls the ",(0,s.jsx)(t.code,{children:"counter-inc"})," entry point."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"evaluating-and-comparing-results",children:"Evaluating and Comparing Results"}),"\n",(0,s.jsxs)(t.p,{children:["After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.jsx)(t.code,{children:"builder"})," method retrieves the required information and converts it to the value type required. Then, ",(0,s.jsx)(t.code,{children:"assert_eq!()"})," compares the result against the expected value."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,s.jsxs)(t.p,{children:["For more test examples, visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,s.jsx)(t.h2,{id:"testing-contracts-that-call-contracts",children:"Testing Contracts that Call Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"}),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."]}),"\n",(0,s.jsxs)(t.p,{children:["Each contract installation will require an additional Wasm file installed through a ",(0,s.jsx)(t.code,{children:"Transaction"})," using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.jsx)(t.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"return values"})," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."]}),"\n",(0,s.jsxs)(t.p,{children:["The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," - Calling a contract by its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_name"})," - Calling a contract referenced by a named key in the signer's Account context."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_hash"})," - Calling a specific contract version using its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_name"})," - Calling a specific version of a contract referenced by a named key in the signer's Account context."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, the counter example uses a ",(0,s.jsx)(t.code,{children:"Makefile"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Under the hood, the ",(0,s.jsx)(t.code,{children:"Makefile"})," generates a ",(0,s.jsx)(t.code,{children:"tests/wasm"})," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.jsx)(t.code,{children:"cargo test"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"test: build-contract\n\tmkdir -p tests/wasm\n\tcp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n\tcp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n\tcp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n\tcd tests && cargo test\n"})}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsxs)(t.p,{children:["The following brief video describes testing ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"sample contract code"}),"."]}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"further-testing",children:"Further Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.jsx)(t.a,{href:"/next/developers/dapps/setup-nctl",children:"local network testing"})," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.jsx)(t.a,{href:"/next/developers/dapps/nctl-test",children:"testing in an other simulated network environment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You may also wish to test your contracts on the Casper ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Understand ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,s.jsxs)(t.li,{children:["Learn to ",(0,s.jsx)(t.a,{href:"/next/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},c=s.createContext(r);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/10ab4195.ee7630a9.js b/assets/js/10ab4195.ee7630a9.js new file mode 100644 index 000000000..73d058a6a --- /dev/null +++ b/assets/js/10ab4195.ee7630a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98806],{97032:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var s=t(74848),r=t(28453);const a={},o="Go SDK",d={id:"developers/dapps/sdk/go-sdk",title:"Go SDK",description:"Usage Examples",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/go-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/go-sdk",permalink:"/2.0.0/developers/dapps/sdk/go-sdk",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:".NET SDK",permalink:"/2.0.0/developers/dapps/sdk/csharp-sdk"},next:{title:"Python SDK",permalink:"/2.0.0/developers/dapps/sdk/python-sdk"}},l={},c=[{value:"Usage Examples",id:"usage-examples",level:2},{value:"Get a Deploy from the Network",id:"get-a-deploy-from-the-network",level:3},{value:"Handle the Deploy Processed Event",id:"handle-the-deploy-processed-event",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"go-sdk",children:"Go SDK"})}),"\n",(0,s.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,s.jsx)(n.p,{children:"This section includes some examples of how to use Go SDK:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"#get-a-deploy-from-the-network",children:["Get a ",(0,s.jsx)(n.em,{children:"Deploy"})," from the Network"]})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a Transfer"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"get-a-deploy-from-the-network",children:"Get a Deploy from the Network"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "fmt"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n)\n\nfunc main() {\n handler := casper.NewRPCHandler("https:///rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https:///events")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n'})})]})}function i(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/10dd5949.d7da3af3.js b/assets/js/10dd5949.d7da3af3.js new file mode 100644 index 000000000..11d9e357a --- /dev/null +++ b/assets/js/10dd5949.d7da3af3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91415],{4785:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>r,toc:()=>h});var a=n(74848),s=n(28453);const i={},o="Authorization Keys",r={id:"concepts/list-auth-keys",title:"Authorization Keys",description:"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.",source:"@site/versioned_docs/version-2.0.0/concepts/list-auth-keys.md",sourceDirName:"concepts",slug:"/concepts/list-auth-keys",permalink:"/2.0.0/concepts/list-auth-keys",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Smart Contracts",permalink:"/2.0.0/concepts/smart-contracts"},next:{title:"Call Stacks",permalink:"/2.0.0/concepts/callstack"}},c={},h=[{value:"Associated Keys vs. Authorization Keys",id:"associated-keys-vs-authorization-keys",level:2},{value:"Accessing Authorization Keys from a Smart Contract",id:"accessing-authorization-keys-from-a-smart-contract",level:2},{value:"When to Use Authorization Keys",id:"when-to-use-authorization-keys",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"authorization-keys",children:"Authorization Keys"})}),"\n",(0,a.jsxs)(t.p,{children:["This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the ",(0,a.jsx)(t.a,{href:"/2.0.0/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial for an example."]}),"\n",(0,a.jsx)(t.h2,{id:"associated-keys-vs-authorization-keys",children:"Associated Keys vs. Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Let's review the difference between associated keys to an Account and authorization keys for a transaction."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys and weights"})," and try the ",(0,a.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:["Authorization keys are public keys used to sign a transaction and are listed in the transaction's ",(0,a.jsx)(t.code,{children:"approvals"}),". Authorization keys are a subset of the associated keys of the account under which the transaction is executed."]}),"\n",(0,a.jsxs)(t.li,{children:["When a node receives a transaction, it checks that the transaction has the required authorization keys under ",(0,a.jsx)(t.code,{children:"approvals"})," before including it in a block."]}),"\n",(0,a.jsx)(t.li,{children:"Different transactions executing the same smart contract can have different authorization keys."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Auth Keys",src:n(51603).A+"",width:"862",height:"842"})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of an Account's associated keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"associated_keys": [\n{\n "account_hash": "account-hash-1ab\u202611",\n "weight": 1\n},\n{\n "account_hash": "account-hash-2cd\u202622",\n "weight": 1\n},\n{\n "account_hash": "account-hash-3de\u202633",\n "weight": 1\n },\n{\n "account_hash": "account-hash-4fg\u202644",\n "weight": 1\n}\n ], ...\n'})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of a transaction's authorization keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"approvals": [\n {\n "signer": " 2cd...22",\n "signature": "02df8c...f481"\n },\n {\n "signer": "4fg...44",\n "signature": "02ef21...756a"\n }\n]\n'})}),"\n",(0,a.jsx)(t.h2,{id:"accessing-authorization-keys-from-a-smart-contract",children:"Accessing Authorization Keys from a Smart Contract"}),"\n",(0,a.jsxs)(t.p,{children:["Contract code can retrieve the set of authorization keys for a given transaction by calling the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"contract_api::runtime::list_authorization_keys"})," function, which returns the set of account hashes representing the keys used to sign the transaction."]}),"\n",(0,a.jsx)(t.h2,{id:"when-to-use-authorization-keys",children:"When to Use Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations."}),"\n",(0,a.jsxs)(t.p,{children:["Try the ",(0,a.jsx)(t.a,{href:"/2.0.0/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial to view an example workflow."]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},51603:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/authorization-keys-9187fa39eca478722639797b5109fa50.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/116fa82a.4ab1633b.js b/assets/js/116fa82a.4ab1633b.js new file mode 100644 index 000000000..e70a8493e --- /dev/null +++ b/assets/js/116fa82a.4ab1633b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13509],{85298:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(74848),s=r(28453);const o={},i="Setting up Private Networks",a={id:"operators/setup-network/index",title:"Setting up Private Networks",description:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.",source:"@site/docs/operators/setup-network/index.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/",permalink:"/operators/setup-network/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"operators",previous:{title:"Inactive and Faulty Nodes",permalink:"/operators/becoming-a-validator/inactive-vs-faulty"},next:{title:"Genesis",permalink:"/operators/setup-network/genesis"}},c={},d=[];function p(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"setting-up-private-networks",children:"Setting up Private Networks"})}),"\n",(0,n.jsx)(t.p,{children:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Title"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/genesis",children:"The Genesis Block"})}),(0,n.jsx)(t.td,{children:"Files needed to create a genesis block"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/chain-spec",children:"The Chain Specification"})}),(0,n.jsx)(t.td,{children:"Configuration settings describing the network state"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/create-private",children:"Setting up a Private Casper Network"})}),(0,n.jsx)(t.td,{children:"A step-by-step guide to establishing and configuring a private Casper network"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/staging-files-for-new-network",children:"Staging Files for a New Network"})}),(0,n.jsx)(t.td,{children:"A guide to hosting protocol files for a new Casper network"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const s={},o=n.createContext(s);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/116fa82a.7fdfa28d.js b/assets/js/116fa82a.7fdfa28d.js deleted file mode 100644 index 31c62a718..000000000 --- a/assets/js/116fa82a.7fdfa28d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3509],{85298:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(74848),s=r(28453);const o={},i="Setting up Private Networks",a={id:"operators/setup-network/index",title:"Setting up Private Networks",description:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.",source:"@site/docs/operators/setup-network/index.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/",permalink:"/next/operators/setup-network/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"operators",previous:{title:"Inactive and Faulty Nodes",permalink:"/next/operators/becoming-a-validator/inactive-vs-faulty"},next:{title:"Genesis",permalink:"/next/operators/setup-network/genesis"}},c={},d=[];function p(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"setting-up-private-networks",children:"Setting up Private Networks"})}),"\n",(0,n.jsx)(t.p,{children:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Title"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/next/operators/setup-network/genesis",children:"The Genesis Block"})}),(0,n.jsx)(t.td,{children:"Files needed to create a genesis block"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/next/operators/setup-network/chain-spec",children:"The Chain Specification"})}),(0,n.jsx)(t.td,{children:"Configuration settings describing the network state"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/next/operators/setup-network/create-private",children:"Setting up a Private Casper Network"})}),(0,n.jsx)(t.td,{children:"A step-by-step guide to establishing and configuring a private Casper network"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/next/operators/setup-network/staging-files-for-new-network",children:"Staging Files for a New Network"})}),(0,n.jsx)(t.td,{children:"A guide to hosting protocol files for a new Casper network"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const s={},o=n.createContext(s);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/124873a8.3f86c852.js b/assets/js/124873a8.3f86c852.js deleted file mode 100644 index c57133928..000000000 --- a/assets/js/124873a8.3f86c852.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7795],{39026:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var s=n(74848),r=n(28453);const i={title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},a="AddressableEntity in Casper 2.0",o={permalink:"/blog/addressable-entity",source:"@site/blog/2024-07-17-addressable-entity.md",title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",date:"2024-07-17T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"}],readingTime:3.665,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"},nextItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},c={authorsImageUrls:[void 0,void 0]},d=[{value:"Key Concepts",id:"key-concepts",level:2},{value:"The inner workings of AddressableEntity",id:"the-inner-workings-of-addressableentity",level:2},{value:"Obtaining and converting Keys",id:"obtaining-and-converting-keys",level:2},{value:"Creating AddressableEntity Keys",id:"creating-addressableentity-keys",level:3},{value:"Extracting AccountHash or ContractHash from a Key",id:"extracting-accounthash-or-contracthash-from-a-key",level:3},{value:"The Address Merge in Condor",id:"the-address-merge-in-condor",level:2}];function l(e){const t={blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," type. This new structure replaces the separate ",(0,s.jsx)(t.code,{children:"AccountHash"})," and ",(0,s.jsx)(t.code,{children:"ContractHash"})," used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control."]}),"\n",(0,s.jsxs)(t.p,{children:["In this article, we'll dive into the details of ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", exploring its structure and functionalities."]}),"\n",(0,s.jsx)(t.h2,{id:"key-concepts",children:"Key Concepts"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"AddressableEntity"})}),"\n",(0,s.jsxs)(t.p,{children:["At its core, an ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," provides a unified interface for various operations, including authorization, access control, and execution of functions."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"EntityAddr"})}),"\n",(0,s.jsxs)(t.p,{children:["An ",(0,s.jsx)(t.code,{children:"EntityAddr"})," serves as the address for an ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),". It not only encodes the unique identifier (hash) of the entity but also its type. There are three distinct variants of ",(0,s.jsx)(t.code,{children:"EntityAddr"}),":"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"System:"})," Used for built-in, native contracts crucial for the blockchain's operation."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Account:"})," Represents a user's account."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"SmartContract:"})," Represents a user-deployed smart contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"AddressableEntityHash"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"AddressableEntityHash"})," is a newtype wrapper around a 32-byte hash (",(0,s.jsx)(t.code,{children:"HashAddr"}),"). This hash functions as a unique identifier for the ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", typically derived from either the account's public key or the smart contract's hash using hashing algorithm."]}),"\n",(0,s.jsx)(t.h2,{id:"the-inner-workings-of-addressableentity",children:"The inner workings of AddressableEntity"}),"\n",(0,s.jsxs)(t.p,{children:["Let's dive into the critical components within an ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),":"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"protocol_version"})," (ProtocolVersion):"]})," This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"entity_kind"})," (EntityKind):"]})," As mentioned earlier, this enum determines the type of entity \u2013 System, Account, or SmartContract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"associated_keys"})," (AssociatedKeys):"]})," This data structure stores a map of public keys authorized to interact with the entity. Each key is associated with a weight that represents its voting power in decision-making processes within the entity."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"action_thresholds"})," (ActionThresholds):"]})," These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are ",(0,s.jsx)(t.code,{children:"deployment"}),", ",(0,s.jsx)(t.code,{children:"key_management"}),", and ",(0,s.jsx)(t.code,{children:"upgrade_management"}),". Each action type has its own weight threshold, allowing for fine-grained control over permissions."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"entry_points"})," (EntryPoints):"]})," This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"obtaining-and-converting-keys",children:"Obtaining and converting Keys"}),"\n",(0,s.jsxs)(t.p,{children:["In Casper 2.0, developers will primarily work with ",(0,s.jsx)(t.code,{children:"Key::AddressableEntity"})," when referring to accounts and smart contracts. Here's how you can create them and convert between different key formats:"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-addressableentity-keys",children:"Creating AddressableEntity Keys"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"From Account Hash:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); \n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"From Smart Contract Hash:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));\n"})}),"\n",(0,s.jsx)(t.h3,{id:"extracting-accounthash-or-contracthash-from-a-key",children:"Extracting AccountHash or ContractHash from a Key"}),"\n",(0,s.jsxs)(t.p,{children:["You can extract the ",(0,s.jsx)(t.code,{children:"AccountHash"})," or ",(0,s.jsx)(t.code,{children:"ContractHash"})," from a ",(0,s.jsx)(t.code,{children:"Key::AddressableEntity"})," using pattern matching:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'//For Accounts\nlet account_hash = match addressable_entity_key {\n Key::AddressableEntity(EntityAddr::Account(hash)) => hash,\n _ => panic!("Not an account key"), \n};\n//For Contracts\nlet contract_hash = match addressable_entity_key {\n Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,\n _ => panic!("Not a contract key"), \n};\n'})}),"\n",(0,s.jsx)(t.h2,{id:"the-address-merge-in-condor",children:"The Address Merge in Condor"}),"\n",(0,s.jsx)(t.p,{children:'The "Address Merge" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with.'}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Global State Transformation:"})}),"\n",(0,s.jsxs)(t.p,{children:["Post-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," structure. This means the network itself will recognize and handle these entities using the new format."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Smart Contract Compatibility Considerations:"})}),"\n",(0,s.jsxs)(t.p,{children:["While the global state automatically transitions to ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", existing contracts are expected to function without any modification."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Caller Identification:"}),"\nExisting host functions used to identify the caller within your contract will continue to work as before, ensuring no disruption to your contract's functionality. However, new host functions have been introduced that are specifically designed to work with the AddressableEntity format."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"External Contract Interaction:"})," Other contracts may have updated their interfaces to accept AddressableEntity arguments. Its worth to verify the argument types to avoid potential errors."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Note"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Upgrading a contract to a newer version may involve complexities, such as changes to the contract's addressable hash. These changes might require coordination with centralized and decentralized exchanges, as well as communication with your community to ensure a smooth transition."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/124873a8.ea47be98.js b/assets/js/124873a8.ea47be98.js new file mode 100644 index 000000000..9f1c34a14 --- /dev/null +++ b/assets/js/124873a8.ea47be98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57795],{39026:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var s=n(74848),r=n(28453);const i={title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},a="AddressableEntity in Casper 2.0",o={permalink:"/blog/addressable-entity",source:"@site/blog/2024-07-17-addressable-entity.md",title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",date:"2024-07-17T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"}],readingTime:3.665,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"},nextItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},c={authorsImageUrls:[void 0,void 0]},d=[{value:"Key Concepts",id:"key-concepts",level:2},{value:"The inner workings of AddressableEntity",id:"the-inner-workings-of-addressableentity",level:2},{value:"Obtaining and converting Keys",id:"obtaining-and-converting-keys",level:2},{value:"Creating AddressableEntity Keys",id:"creating-addressableentity-keys",level:3},{value:"Extracting AccountHash or ContractHash from a Key",id:"extracting-accounthash-or-contracthash-from-a-key",level:3},{value:"The Address Merge in Condor",id:"the-address-merge-in-condor",level:2}];function l(e){const t={blockquote:"blockquote",code:"code",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(t.p,{children:["Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," type. This new structure replaces the separate ",(0,s.jsx)(t.code,{children:"AccountHash"})," and ",(0,s.jsx)(t.code,{children:"ContractHash"})," used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control."]}),"\n",(0,s.jsxs)(t.p,{children:["In this article, we'll dive into the details of ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", exploring its structure and functionalities."]}),"\n",(0,s.jsx)(t.h2,{id:"key-concepts",children:"Key Concepts"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"AddressableEntity"})}),"\n",(0,s.jsxs)(t.p,{children:["At its core, an ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," provides a unified interface for various operations, including authorization, access control, and execution of functions."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"EntityAddr"})}),"\n",(0,s.jsxs)(t.p,{children:["An ",(0,s.jsx)(t.code,{children:"EntityAddr"})," serves as the address for an ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),". It not only encodes the unique identifier (hash) of the entity but also its type. There are three distinct variants of ",(0,s.jsx)(t.code,{children:"EntityAddr"}),":"]}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"System:"})," Used for built-in, native contracts crucial for the blockchain's operation."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Account:"})," Represents a user's account."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"SmartContract:"})," Represents a user-deployed smart contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"AddressableEntityHash"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"AddressableEntityHash"})," is a newtype wrapper around a 32-byte hash (",(0,s.jsx)(t.code,{children:"HashAddr"}),"). This hash functions as a unique identifier for the ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", typically derived from either the account's public key or the smart contract's hash using hashing algorithm."]}),"\n",(0,s.jsx)(t.h2,{id:"the-inner-workings-of-addressableentity",children:"The inner workings of AddressableEntity"}),"\n",(0,s.jsxs)(t.p,{children:["Let's dive into the critical components within an ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),":"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"protocol_version"})," (ProtocolVersion):"]})," This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"entity_kind"})," (EntityKind):"]})," As mentioned earlier, this enum determines the type of entity \u2013 System, Account, or SmartContract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"associated_keys"})," (AssociatedKeys):"]})," This data structure stores a map of public keys authorized to interact with the entity. Each key is associated with a weight that represents its voting power in decision-making processes within the entity."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"action_thresholds"})," (ActionThresholds):"]})," These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are ",(0,s.jsx)(t.code,{children:"deployment"}),", ",(0,s.jsx)(t.code,{children:"key_management"}),", and ",(0,s.jsx)(t.code,{children:"upgrade_management"}),". Each action type has its own weight threshold, allowing for fine-grained control over permissions."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:[(0,s.jsx)(t.code,{children:"entry_points"})," (EntryPoints):"]})," This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"obtaining-and-converting-keys",children:"Obtaining and converting Keys"}),"\n",(0,s.jsxs)(t.p,{children:["In Casper 2.0, developers will primarily work with ",(0,s.jsx)(t.code,{children:"Key::AddressableEntity"})," when referring to accounts and smart contracts. Here's how you can create them and convert between different key formats:"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-addressableentity-keys",children:"Creating AddressableEntity Keys"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"From Account Hash:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); \n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"From Smart Contract Hash:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));\n"})}),"\n",(0,s.jsx)(t.h3,{id:"extracting-accounthash-or-contracthash-from-a-key",children:"Extracting AccountHash or ContractHash from a Key"}),"\n",(0,s.jsxs)(t.p,{children:["You can extract the ",(0,s.jsx)(t.code,{children:"AccountHash"})," or ",(0,s.jsx)(t.code,{children:"ContractHash"})," from a ",(0,s.jsx)(t.code,{children:"Key::AddressableEntity"})," using pattern matching:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'//For Accounts\nlet account_hash = match addressable_entity_key {\n Key::AddressableEntity(EntityAddr::Account(hash)) => hash,\n _ => panic!("Not an account key"), \n};\n//For Contracts\nlet contract_hash = match addressable_entity_key {\n Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,\n _ => panic!("Not a contract key"), \n};\n'})}),"\n",(0,s.jsx)(t.h2,{id:"the-address-merge-in-condor",children:"The Address Merge in Condor"}),"\n",(0,s.jsx)(t.p,{children:'The "Address Merge" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with.'}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Global State Transformation:"})}),"\n",(0,s.jsxs)(t.p,{children:["Post-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the ",(0,s.jsx)(t.code,{children:"AddressableEntity"})," structure. This means the network itself will recognize and handle these entities using the new format."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Smart Contract Compatibility Considerations:"})}),"\n",(0,s.jsxs)(t.p,{children:["While the global state automatically transitions to ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", existing contracts are expected to function without any modification."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Caller Identification:"}),"\nExisting host functions used to identify the caller within your contract will continue to work as before, ensuring no disruption to your contract's functionality. However, new host functions have been introduced that are specifically designed to work with the AddressableEntity format."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"External Contract Interaction:"})," Other contracts may have updated their interfaces to accept AddressableEntity arguments. Its worth to verify the argument types to avoid potential errors."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Note"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Upgrading a contract to a newer version may involve complexities, such as changes to the contract's addressable hash. These changes might require coordination with centralized and decentralized exchanges, as well as communication with your community to ensure a smooth transition."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12984b65.704e4746.js b/assets/js/12984b65.704e4746.js new file mode 100644 index 000000000..178ab2a26 --- /dev/null +++ b/assets/js/12984b65.704e4746.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[90236],{92694:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var a=s(74848),r=s(28453);const t={},d="Verifying a Transfer",c={id:"developers/cli/transfers/verify-transfer",title:"Verifying a Transfer",description:"Prerequisites",source:"@site/versioned_docs/version-2.0.0/developers/cli/transfers/verify-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/verify-transfer",permalink:"/2.0.0/developers/cli/transfers/verify-transfer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer"},next:{title:"Delegating Tokens",permalink:"/2.0.0/developers/cli/delegate"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Query the State Root Hash",id:"query-the-state-root-hash",level:2},{value:"Query the Transfer Details",id:"query-transfer-details",level:2},{value:"Query the Account State",id:"query-account-state",level:2},{value:"Query the Purse Balance",id:"get-purse-balance",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"verifying-a-transfer",children:"Verifying a Transfer"})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before verifying a transfer, make sure you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Initiated a ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/direct-token-transfer",children:"Direct Transfer"})," or ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer",children:"Multi-sig Deploy Transfer"})]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"deploy_hash"})," of the transfer you want to verify"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"public key"})," of the source and target accounts"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"query-the-state-root-hash",children:"Query the State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io \n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Sample output of the get-state-root-hash command"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 6458079936180872466,\n "result": {\n "api_version": "1.5.3",\n "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"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."})}),"\n",(0,a.jsx)(n.h2,{id:"query-transfer-details",children:"Query the Transfer Details"}),"\n",(0,a.jsxs)(n.p,{children:["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 ",(0,a.jsx)(n.code,{children:"transfer-address"})," identifies each transfer. The ",(0,a.jsx)(n.code,{children:"transfer-address"})," consists of a formatted string with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Transfer hash",src:s(17362).A+"",width:"1558",height:"1228"})}),"\n",(0,a.jsxs)(n.p,{children:["First, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,a.jsx)(n.em,{children:"deploy_hash"})," to identify the corresponding transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] \\\n[DEPLOY_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."execution_results"."result"."Success"."transfers"'})," - List of transfers contained in a successful deploy"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After obtaining the transfer identifier, query the transfer details."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [TRANSFER_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - The hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"key"})," - The base key for the query. This must be a properly formatted transfer address with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix, i.e., ",(0,a.jsx)(n.code,{children:"transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 3 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",\n "path": []\n },\n "id": 3\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Transfer": {\n "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n },\n "merkle_proof": "[42526 hex chars]"\n },\n "id": 3\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"query-account-state",children:"Query the Account State"}),"\n",(0,a.jsxs)(n.p,{children:["Next, query for information about the ",(0,a.jsx)(n.em,{children:"Source"})," account, using the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," of the block containing the transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [SOURCE_PUBLIC_KEY]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the network state"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Source Account Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 4 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [...],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[31406 hex chars]"\n },\n "id": 4\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Query:"})}),"\n",(0,a.jsxs)(n.p,{children:["Repeat the same step to query information about the ",(0,a.jsx)(n.em,{children:"Target"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 5 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 5\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [...],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [...],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32060 hex chars]"\n },\n "id": 5\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"get-purse-balance",children:"Query the Purse Balance"}),"\n",(0,a.jsxs)(n.p,{children:["All accounts on a Casper network have a purse associated with the Casper system mint, which is the ",(0,a.jsx)(n.em,{children:"main purse"}),". The balance associated with a given purse is recorded in global state, and the value can be queried using the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Verify the source purse balance using the ",(0,a.jsx)(n.code,{children:"query-balance"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [SOURCE_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Query Source Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 6 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "1109111876194"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Similarly, query the balance of the target purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-balance \\\n--id 7 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [TARGET_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 7 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"\n }\n },\n "id": 7\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "46200000000"\n },\n "id": 7\n}\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},17362:(e,n,s)=>{s.d(n,{A:()=>a});const a=s.p+"assets/images/transfer-hash-example-b8695f1d7d28b36e8e8cf67b26df6945.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var a=s(96540);const r={},t=a.createContext(r);function d(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12e95288.283682c6.js b/assets/js/12e95288.283682c6.js new file mode 100644 index 000000000..878889730 --- /dev/null +++ b/assets/js/12e95288.283682c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50889],{88738:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(74848),t=n(28453);const o={},a="N",c={id:"concepts/glossary/N",title:"N",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/N.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/N",permalink:"/1.5.X/concepts/glossary/N",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"M",permalink:"/1.5.X/concepts/glossary/M"},next:{title:"O",permalink:"/1.5.X/concepts/glossary/O"}},i={},l=[{value:"NamedKeys",id:"named-keys",level:2},{value:"Node",id:"node",level:2},{value:"Node operator",id:"node-operator",level:2},{value:"Non-Fungible Token (NFT)",id:"non-fungible-token",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"n",children:"N"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),"\nare a collection of String-Key pairs used to easily identify some data on the network."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node",children:"Node"}),"\n",(0,r.jsx)(s.p,{children:"A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data."}),"\n",(0,r.jsx)(s.p,{children:"You will encounter different types of nodes on the network:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Bonded node"}),": a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Unbonded node"}),": a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization)."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node-operator",children:"Node operator"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O#operator",children:"operator"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"non-fungible-token",children:"Non-Fungible Token (NFT)"}),"\n",(0,r.jsx)(s.p,{children:"Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const t={},o=r.createContext(t);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12e95288.dcfe96df.js b/assets/js/12e95288.dcfe96df.js deleted file mode 100644 index be3b6bcd1..000000000 --- a/assets/js/12e95288.dcfe96df.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[889],{88738:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(74848),t=n(28453);const o={},a="N",c={id:"concepts/glossary/N",title:"N",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/N.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/N",permalink:"/concepts/glossary/N",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"M",permalink:"/concepts/glossary/M"},next:{title:"O",permalink:"/concepts/glossary/O"}},i={},l=[{value:"NamedKeys",id:"named-keys",level:2},{value:"Node",id:"node",level:2},{value:"Node operator",id:"node-operator",level:2},{value:"Non-Fungible Token (NFT)",id:"non-fungible-token",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"n",children:"N"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),"\nare a collection of String-Key pairs used to easily identify some data on the network."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node",children:"Node"}),"\n",(0,r.jsx)(s.p,{children:"A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data."}),"\n",(0,r.jsx)(s.p,{children:"You will encounter different types of nodes on the network:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Bonded node"}),": a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Unbonded node"}),": a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization)."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node-operator",children:"Node operator"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O#operator",children:"operator"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"non-fungible-token",children:"Non-Fungible Token (NFT)"}),"\n",(0,r.jsx)(s.p,{children:"Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const t={},o=r.createContext(t);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/130631d9.473508f7.js b/assets/js/130631d9.473508f7.js deleted file mode 100644 index e1fb0c6b9..000000000 --- a/assets/js/130631d9.473508f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2748],{59869:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var r=n(74848),t=n(28453);const c={},a="W",o={id:"concepts/glossary/W",title:"W",description:"---",source:"@site/docs/concepts/glossary/W.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/W",permalink:"/next/concepts/glossary/W",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"V",permalink:"/next/concepts/glossary/V"},next:{title:"X",permalink:"/next/concepts/glossary/X"}},l={},i=[{value:"Web3",id:"web3",level:2},{value:"WebAssembly",id:"webassembly",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"w",children:"W"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"web3",children:"Web3"}),"\n",(0,r.jsx)(s.p,{children:"An advanced version of the internet based on decentralization and trustless interactions."}),"\n",(0,r.jsx)(s.h2,{id:"webassembly",children:"WebAssembly"}),"\n",(0,r.jsx)(s.p,{children:"WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var r=n(96540);const t={},c=r.createContext(t);function a(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/130631d9.5fa36173.js b/assets/js/130631d9.5fa36173.js new file mode 100644 index 000000000..08db9a46b --- /dev/null +++ b/assets/js/130631d9.5fa36173.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32748],{59869:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>o,toc:()=>i});var r=n(74848),c=n(28453);const t={},a="W",o={id:"concepts/glossary/W",title:"W",description:"---",source:"@site/docs/concepts/glossary/W.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/W",permalink:"/concepts/glossary/W",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"V",permalink:"/concepts/glossary/V"},next:{title:"X",permalink:"/concepts/glossary/X"}},l={},i=[{value:"Web3",id:"web3",level:2},{value:"WebAssembly",id:"webassembly",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"w",children:"W"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"web3",children:"Web3"}),"\n",(0,r.jsx)(s.p,{children:"An advanced version of the internet based on decentralization and trustless interactions."}),"\n",(0,r.jsx)(s.h2,{id:"webassembly",children:"WebAssembly"}),"\n",(0,r.jsx)(s.p,{children:"WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var r=n(96540);const c={},t=r.createContext(c);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/134a9ec2.0ccdf24e.js b/assets/js/134a9ec2.0ccdf24e.js new file mode 100644 index 000000000..a255c8d5c --- /dev/null +++ b/assets/js/134a9ec2.0ccdf24e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19635],{41392:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=d(74848),s=d(28453);const r={title:"Key Types"},i="Understanding Key Types",c={id:"concepts/key-types",title:"Key Types",description:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.",source:"@site/docs/concepts/key-types.md",sourceDirName:"concepts",slug:"/concepts/key-types",permalink:"/concepts/key-types",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723747045e3,frontMatter:{title:"Key Types"},sidebar:"concepts",previous:{title:"Accounts and Keys",permalink:"/concepts/accounts-and-keys"},next:{title:"Transaction Lifecycle",permalink:"/transactions-and-transaction-lifecycle"}},t={},l=[{value:"Key Explanations",id:"key-explanations",level:2},{value:"Account",id:"account",level:3},{value:"Hash",id:"hash",level:3},{value:"URef",id:"uref",level:3},{value:"Transfer",id:"transfer",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"EraInfo",id:"erainfo",level:3},{value:"Balance",id:"balance",level:3},{value:"BalanceHold",id:"balancehold",level:3},{value:"Bid",id:"bid",level:3},{value:"Withdraw",id:"withdraw",level:3},{value:"Dictionary",id:"dictionary",level:3},{value:"SystemContractRegistry",id:"systemcontractregistry",level:3},{value:"EraSummary",id:"erasummary",level:3},{value:"Unbond",id:"unbond",level:3},{value:"ChainspecRegistry",id:"chainspecregistry",level:3},{value:"ChecksumRegistry",id:"checksumregistry",level:3},{value:"BidAddr",id:"bidaddr",level:3},{value:"Package",id:"package",level:3},{value:"AddressableEntity",id:"addressableentity",level:3},{value:"ByteCode",id:"bytecode",level:3},{value:"Message",id:"message",level:3},{value:"NamedKey",id:"namedkey",level:3},{value:"BlockGlobal",id:"blockglobal",level:3},{value:"EntryPoint",id:"entrypoint",level:3}];function h(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"understanding-key-types",children:"Understanding Key Types"})}),"\n",(0,a.jsx)(n.p,{children:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used."}),"\n",(0,a.jsx)(n.h2,{id:"key-explanations",children:"Key Explanations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key"})," is a wrapper type that may contain one of several possible sets of data."]}),"\n",(0,a.jsx)(n.h3,{id:"account",children:"Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Account"})," contains an AccountHash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Account"}),(0,a.jsx)(n.td,{children:"account-hash-"}),(0,a.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"hash",children:"Hash"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Hash"})," contains a byte array with a length of 32, which can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for the implementation of any checks necessary on the receiving side."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Hash"}),(0,a.jsx)(n.td,{children:"hash-"}),(0,a.jsx)(n.td,{children:"hash-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"uref",children:"URef"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::URef"})," contains an URef suffixed by ",(0,a.jsx)(n.a,{href:"/developers/dapps/uref-security",children:"access rights"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::URef"}),(0,a.jsx)(n.td,{children:"uref-"}),(0,a.jsx)(n.td,{children:"uref-0101010101010101010101010101010101010101010101010101010101010101-001"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Transfer"})," should contain the address hash for a transfer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Transfer"}),(0,a.jsx)(n.td,{children:"transfer-"}),(0,a.jsx)(n.td,{children:"transfer-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::DeployInfo"})," retains the address hash of deploy information."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::DeployInfo"}),(0,a.jsx)(n.td,{children:"deploy-"}),(0,a.jsx)(n.td,{children:"deploy-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erainfo",children:"EraInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraInfo"})," is the integer number of the associated era."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraInfo"}),(0,a.jsx)(n.td,{children:"era-"}),(0,a.jsx)(n.td,{children:"era-1"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balance",children:"Balance"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Balance"})," is the balance of a purse."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Balance"}),(0,a.jsx)(n.td,{children:"balance-"}),(0,a.jsx)(n.td,{children:"balance-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balancehold",children:"BalanceHold"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BalanceHold"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a hold on a purse balance is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::BalanceHold"}),(0,a.jsx)(n.td,{children:"balance-hold-"}),(0,a.jsx)(n.td,{children:"balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a6400000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"bid",children:"Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Bid"})," is used to keep track of bids for the auction contract. It is not generally used by users."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Bid"}),(0,a.jsx)(n.td,{children:"bid-"}),(0,a.jsx)(n.td,{children:"bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw",children:"Withdraw"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Withdraw"})," is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Withdraw"}),(0,a.jsx)(n.td,{children:"withdraw-"}),(0,a.jsx)(n.td,{children:"withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"dictionary",children:"Dictionary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Dictionary"})," is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Dictionary"}),(0,a.jsx)(n.td,{children:"dictionary-"}),(0,a.jsx)(n.td,{children:"dictionary-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::SystemContractRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ContractHashes for system contracts, including ",(0,a.jsx)(n.code,{children:"Mint"}),", ",(0,a.jsx)(n.code,{children:"Auction"}),", ",(0,a.jsx)(n.code,{children:"HandlePayment"})," and ",(0,a.jsx)(n.code,{children:"StandardPayment"}),", is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::SystemContractRegistry"}),(0,a.jsx)(n.td,{children:"system-entity-registry-"}),(0,a.jsx)(n.td,{children:"system-entity-registry-0000000000000000000000000000000000000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erasummary",children:"EraSummary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraSummary"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which we store current era info."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraSummary"}),(0,a.jsx)(n.td,{children:"era-summary-"}),(0,a.jsx)(n.td,{children:"era-summary-00000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"unbond",children:"Unbond"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Unbond"})," is a variant of the key type that tracks unbonding purses."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Unbond"}),(0,a.jsx)(n.td,{children:"unbond-"}),(0,a.jsx)(n.td,{children:"unbond-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChainspecRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," which contains a mapping of file names to the hash of the file itself. These files include ",(0,a.jsx)(n.em,{children:"Chainspec.toml"})," and may also include ",(0,a.jsx)(n.em,{children:"Accounts.toml"})," and ",(0,a.jsx)(n.em,{children:"GlobalState.toml"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::ChainspecRegistry"}),(0,a.jsx)(n.td,{children:"chainspec-registry-"}),(0,a.jsx)(n.td,{children:"chainspec-registry-11111111111111111111111111111111"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"checksumregistry",children:"ChecksumRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChecksumRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"key"})," variant under which we write a registry of checksums for a given block. There are two checksums in the registry, one for the execution results and the other for the approvals of all transactions in the block."]}),"\n",(0,a.jsx)(n.p,{children:"|Key::ChecksumRegistry | checksum-registry- | checksum-registry-00000000000000000000000000000000 |"}),"\n",(0,a.jsx)(n.h3,{id:"bidaddr",children:"BidAddr"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BidAddr"})," manages data associated with bids for the ",(0,a.jsx)(n.code,{children:"Auction"})," contract. It may be any one of three variants: ",(0,a.jsx)(n.code,{children:"unified"}),", ",(0,a.jsx)(n.code,{children:"validator"}),", or ",(0,a.jsx)(n.code,{children:"delegator"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Unified"})}),(0,a.jsx)(n.td,{children:"bid-addr-00"}),(0,a.jsx)(n.td,{children:"bid-addr-00ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Validator"})}),(0,a.jsx)(n.td,{children:"bid-addr-01"}),(0,a.jsx)(n.td,{children:"bid-addr-01ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Delegator"})}),(0,a.jsx)(n.td,{children:"bid-addr-02"}),(0,a.jsx)(n.td,{children:"bid-addr-02ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Package"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which package information is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Package"}),(0,a.jsx)(n.td,{children:"package-"}),(0,a.jsx)(n.td,{children:"package-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::AddressableEntity"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an ",(0,a.jsx)(n.a,{href:"/developers/json-rpc/types_chain#addressableentity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," is stored. It may be one of three variants: ",(0,a.jsx)(n.code,{children:"Account"}),", ",(0,a.jsx)(n.code,{children:"System"})," or ",(0,a.jsx)(n.code,{children:"SmartContract"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Account"})}),(0,a.jsx)(n.td,{children:"addressable-entity-account-"}),(0,a.jsx)(n.td,{children:"addressable-entity-account-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"System"})}),(0,a.jsx)(n.td,{children:"addressable-entity-system-"}),(0,a.jsx)(n.td,{children:"addressable-entity-system-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"SmartContract"})}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-"}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"bytecode",children:"ByteCode"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ByteCode"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a byte code record is stored. It may be one of two variants: ",(0,a.jsx)(n.code,{children:"v1-wasm"})," or ",(0,a.jsx)(n.code,{children:"empty"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"v1-wasm"})}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-"}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"empty"})}),(0,a.jsx)(n.td,{children:"byte-code-empty-"}),(0,a.jsx)(n.td,{children:"byte-code-empty-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"message",children:"Message"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Message"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a message is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message Topic"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message"}),(0,a.jsx)(n.td,{children:"message-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-0202020202020202020202020202020202020202020202020202020202020202-f"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"namedkey",children:"NamedKey"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::NamedKey"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a single named key entry is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Account Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-928d914bdcad3ca269e750f63ed3615c5d3f615cf97dba87006fd9f979dacb3c-dde6f264c89fe385a5b07c26d77284d6fddabe79653c5ca25cec39a6363e6ec7"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Contract Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"blockglobal",children:"BlockGlobal"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BlockGlobal"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which per-block details are stored to global state."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Time"}),(0,a.jsx)(n.td,{children:"block-time-"}),(0,a.jsx)(n.td,{children:"block-time-00000000000000000000000000000000000000000000000000000000000000"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Message Count"}),(0,a.jsx)(n.td,{children:"block-message-count-"}),(0,a.jsx)(n.td,{children:"block-message-count-00000000000000000000000000000000000000000000000000000000000000"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EntryPoint"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an entrypoint record is written."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V1 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V2 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1"})]})]})]})]})}function x(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>i,x:()=>c});var a=d(96540);const s={},r=a.createContext(s);function i(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/134a9ec2.a9986cfa.js b/assets/js/134a9ec2.a9986cfa.js deleted file mode 100644 index 1f7155feb..000000000 --- a/assets/js/134a9ec2.a9986cfa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9635],{41392:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=d(74848),s=d(28453);const r={title:"Key Types"},i="Understanding Key Types",c={id:"concepts/key-types",title:"Key Types",description:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.",source:"@site/docs/concepts/key-types.md",sourceDirName:"concepts",slug:"/concepts/key-types",permalink:"/next/concepts/key-types",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723747045e3,frontMatter:{title:"Key Types"},sidebar:"concepts",previous:{title:"Accounts and Keys",permalink:"/next/concepts/accounts-and-keys"},next:{title:"Transaction Lifecycle",permalink:"/next/transactions-and-transaction-lifecycle"}},t={},l=[{value:"Key Explanations",id:"key-explanations",level:2},{value:"Account",id:"account",level:3},{value:"Hash",id:"hash",level:3},{value:"URef",id:"uref",level:3},{value:"Transfer",id:"transfer",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"EraInfo",id:"erainfo",level:3},{value:"Balance",id:"balance",level:3},{value:"BalanceHold",id:"balancehold",level:3},{value:"Bid",id:"bid",level:3},{value:"Withdraw",id:"withdraw",level:3},{value:"Dictionary",id:"dictionary",level:3},{value:"SystemContractRegistry",id:"systemcontractregistry",level:3},{value:"EraSummary",id:"erasummary",level:3},{value:"Unbond",id:"unbond",level:3},{value:"ChainspecRegistry",id:"chainspecregistry",level:3},{value:"ChecksumRegistry",id:"checksumregistry",level:3},{value:"BidAddr",id:"bidaddr",level:3},{value:"Package",id:"package",level:3},{value:"AddressableEntity",id:"addressableentity",level:3},{value:"ByteCode",id:"bytecode",level:3},{value:"Message",id:"message",level:3},{value:"NamedKey",id:"namedkey",level:3},{value:"BlockGlobal",id:"blockglobal",level:3},{value:"EntryPoint",id:"entrypoint",level:3}];function h(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"understanding-key-types",children:"Understanding Key Types"})}),"\n",(0,a.jsx)(n.p,{children:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used."}),"\n",(0,a.jsx)(n.h2,{id:"key-explanations",children:"Key Explanations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key"})," is a wrapper type that may contain one of several possible sets of data."]}),"\n",(0,a.jsx)(n.h3,{id:"account",children:"Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Account"})," contains an AccountHash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Account"}),(0,a.jsx)(n.td,{children:"account-hash-"}),(0,a.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"hash",children:"Hash"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Hash"})," contains a byte array with a length of 32, which can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for the implementation of any checks necessary on the receiving side."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Hash"}),(0,a.jsx)(n.td,{children:"hash-"}),(0,a.jsx)(n.td,{children:"hash-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"uref",children:"URef"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::URef"})," contains an URef suffixed by ",(0,a.jsx)(n.a,{href:"/next/developers/dapps/uref-security",children:"access rights"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::URef"}),(0,a.jsx)(n.td,{children:"uref-"}),(0,a.jsx)(n.td,{children:"uref-0101010101010101010101010101010101010101010101010101010101010101-001"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Transfer"})," should contain the address hash for a transfer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Transfer"}),(0,a.jsx)(n.td,{children:"transfer-"}),(0,a.jsx)(n.td,{children:"transfer-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::DeployInfo"})," retains the address hash of deploy information."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::DeployInfo"}),(0,a.jsx)(n.td,{children:"deploy-"}),(0,a.jsx)(n.td,{children:"deploy-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erainfo",children:"EraInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraInfo"})," is the integer number of the associated era."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraInfo"}),(0,a.jsx)(n.td,{children:"era-"}),(0,a.jsx)(n.td,{children:"era-1"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balance",children:"Balance"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Balance"})," is the balance of a purse."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Balance"}),(0,a.jsx)(n.td,{children:"balance-"}),(0,a.jsx)(n.td,{children:"balance-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balancehold",children:"BalanceHold"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BalanceHold"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a hold on a purse balance is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::BalanceHold"}),(0,a.jsx)(n.td,{children:"balance-hold-"}),(0,a.jsx)(n.td,{children:"balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a6400000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"bid",children:"Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Bid"})," is used to keep track of bids for the auction contract. It is not generally used by users."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Bid"}),(0,a.jsx)(n.td,{children:"bid-"}),(0,a.jsx)(n.td,{children:"bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw",children:"Withdraw"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Withdraw"})," is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Withdraw"}),(0,a.jsx)(n.td,{children:"withdraw-"}),(0,a.jsx)(n.td,{children:"withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"dictionary",children:"Dictionary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Dictionary"})," is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Dictionary"}),(0,a.jsx)(n.td,{children:"dictionary-"}),(0,a.jsx)(n.td,{children:"dictionary-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::SystemContractRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ContractHashes for system contracts, including ",(0,a.jsx)(n.code,{children:"Mint"}),", ",(0,a.jsx)(n.code,{children:"Auction"}),", ",(0,a.jsx)(n.code,{children:"HandlePayment"})," and ",(0,a.jsx)(n.code,{children:"StandardPayment"}),", is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::SystemContractRegistry"}),(0,a.jsx)(n.td,{children:"system-entity-registry-"}),(0,a.jsx)(n.td,{children:"system-entity-registry-0000000000000000000000000000000000000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erasummary",children:"EraSummary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraSummary"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which we store current era info."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraSummary"}),(0,a.jsx)(n.td,{children:"era-summary-"}),(0,a.jsx)(n.td,{children:"era-summary-00000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"unbond",children:"Unbond"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Unbond"})," is a variant of the key type that tracks unbonding purses."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Unbond"}),(0,a.jsx)(n.td,{children:"unbond-"}),(0,a.jsx)(n.td,{children:"unbond-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChainspecRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," which contains a mapping of file names to the hash of the file itself. These files include ",(0,a.jsx)(n.em,{children:"Chainspec.toml"})," and may also include ",(0,a.jsx)(n.em,{children:"Accounts.toml"})," and ",(0,a.jsx)(n.em,{children:"GlobalState.toml"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::ChainspecRegistry"}),(0,a.jsx)(n.td,{children:"chainspec-registry-"}),(0,a.jsx)(n.td,{children:"chainspec-registry-11111111111111111111111111111111"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"checksumregistry",children:"ChecksumRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChecksumRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"key"})," variant under which we write a registry of checksums for a given block. There are two checksums in the registry, one for the execution results and the other for the approvals of all transactions in the block."]}),"\n",(0,a.jsx)(n.p,{children:"|Key::ChecksumRegistry | checksum-registry- | checksum-registry-00000000000000000000000000000000 |"}),"\n",(0,a.jsx)(n.h3,{id:"bidaddr",children:"BidAddr"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BidAddr"})," manages data associated with bids for the ",(0,a.jsx)(n.code,{children:"Auction"})," contract. It may be any one of three variants: ",(0,a.jsx)(n.code,{children:"unified"}),", ",(0,a.jsx)(n.code,{children:"validator"}),", or ",(0,a.jsx)(n.code,{children:"delegator"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Unified"})}),(0,a.jsx)(n.td,{children:"bid-addr-00"}),(0,a.jsx)(n.td,{children:"bid-addr-00ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Validator"})}),(0,a.jsx)(n.td,{children:"bid-addr-01"}),(0,a.jsx)(n.td,{children:"bid-addr-01ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Delegator"})}),(0,a.jsx)(n.td,{children:"bid-addr-02"}),(0,a.jsx)(n.td,{children:"bid-addr-02ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Package"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which package information is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Package"}),(0,a.jsx)(n.td,{children:"package-"}),(0,a.jsx)(n.td,{children:"package-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::AddressableEntity"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an ",(0,a.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#addressableentity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," is stored. It may be one of three variants: ",(0,a.jsx)(n.code,{children:"Account"}),", ",(0,a.jsx)(n.code,{children:"System"})," or ",(0,a.jsx)(n.code,{children:"SmartContract"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Account"})}),(0,a.jsx)(n.td,{children:"addressable-entity-account-"}),(0,a.jsx)(n.td,{children:"addressable-entity-account-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"System"})}),(0,a.jsx)(n.td,{children:"addressable-entity-system-"}),(0,a.jsx)(n.td,{children:"addressable-entity-system-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"SmartContract"})}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-"}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"bytecode",children:"ByteCode"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ByteCode"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a byte code record is stored. It may be one of two variants: ",(0,a.jsx)(n.code,{children:"v1-wasm"})," or ",(0,a.jsx)(n.code,{children:"empty"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"v1-wasm"})}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-"}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"empty"})}),(0,a.jsx)(n.td,{children:"byte-code-empty-"}),(0,a.jsx)(n.td,{children:"byte-code-empty-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"message",children:"Message"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Message"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a message is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message Topic"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message"}),(0,a.jsx)(n.td,{children:"message-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-0202020202020202020202020202020202020202020202020202020202020202-f"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"namedkey",children:"NamedKey"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::NamedKey"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a single named key entry is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Account Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-928d914bdcad3ca269e750f63ed3615c5d3f615cf97dba87006fd9f979dacb3c-dde6f264c89fe385a5b07c26d77284d6fddabe79653c5ca25cec39a6363e6ec7"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Contract Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"blockglobal",children:"BlockGlobal"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BlockGlobal"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which per-block details are stored to global state."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Time"}),(0,a.jsx)(n.td,{children:"block-time-"}),(0,a.jsx)(n.td,{children:"block-time-00000000000000000000000000000000000000000000000000000000000000"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Message Count"}),(0,a.jsx)(n.td,{children:"block-message-count-"}),(0,a.jsx)(n.td,{children:"block-message-count-00000000000000000000000000000000000000000000000000000000000000"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EntryPoint"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an entrypoint record is written."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V1 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V2 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1"})]})]})]})]})}function x(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>i,x:()=>c});var a=d(96540);const s={},r=a.createContext(s);function i(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/13f7cbc7.8e07b7af.js b/assets/js/13f7cbc7.8e07b7af.js new file mode 100644 index 000000000..ab9c6dcd5 --- /dev/null +++ b/assets/js/13f7cbc7.8e07b7af.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27167],{43254:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>o,frontMatter:()=>d,metadata:()=>i,toc:()=>l});var t=s(74848),r=s(28453);const d={title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},c="Ecosystem Open-Source Software",i={id:"resources/casper-open-source-software",title:"Open-Source Software",description:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.",source:"@site/versioned_docs/version-2.0.0/resources/casper-open-source-software.md",sourceDirName:"resources",slug:"/resources/build-on-casper/casper-open-source-software",permalink:"/2.0.0/resources/build-on-casper/casper-open-source-software",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},sidebar:"resources",previous:{title:"CEP-78 JavaScript Client",permalink:"/2.0.0/resources/tokens/cep78/js-tutorial"},next:{title:"Quickstart",permalink:"/2.0.0/resources/quick-start"}},h={},l=[];function a(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ecosystem-open-source-software",children:"Ecosystem Open-Source Software"})}),"\n",(0,t.jsx)(n.p,{children:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Name"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Author"}),(0,t.jsx)(n.th,{children:"Language"}),(0,t.jsx)(n.th,{children:"License"}),(0,t.jsx)(n.th,{children:"Last Update Date"}),(0,t.jsx)(n.th,{children:"Type"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-StakingRewards",children:"Basic Yield Farm"})}),(0,t.jsx)(n.td,{children:"Staking Rewards"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/amazanzan/casper-cert-issuer",children:"Blockcerts on Casper"})}),(0,t.jsx)(n.td,{children:"Issues Blockcerts using the Bitcoin, Ethereum, or Casper blockchain"}),(0,t.jsx)(n.td,{children:"amazanzan"}),(0,t.jsx)(n.td,{children:"Python"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-22"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://blockmatcher.ledgerleap.com/",children:"BlockMatcher"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-frontend",children:"Frontend"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-backend",children:"Backend"})]}),(0,t.jsx)(n.td,{children:"Private Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches."}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-15"}),(0,t.jsx)(n.td,{children:"Exchange"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/camel-casper",children:"Camel Casper"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://camel.apache.org/",children:"Apache Camel"})," connector for the Casper Blockchain"]}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"Casper .NET SDK"})}),(0,t.jsx)(n.td,{children:"Casper .NET Client SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:".NET"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-19"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/casper-analytics-app",children:"Casper Analytics App"})}),(0,t.jsx)(n.td,{children:"Casper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod App"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-20"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercppsdk/casper-cpp-sdk",children:"Casper C++ SDK"})}),(0,t.jsx)(n.td,{children:"C++ library to interact with Casper network nodes via RPC"}),(0,t.jsx)(n.td,{children:"Yusuf Keten"}),(0,t.jsx)(n.td,{children:"C++"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/nad128668/casper-calculator",children:"Casper Calculator"})}),(0,t.jsx)(n.td,{children:"Casper Earnings Calculator and Node Monitor"}),(0,t.jsx)(n.td,{children:"Charles Nguyen"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2021-09-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/contract-upgrade-example",children:"Casper Contract Upgrade"})}),(0,t.jsx)(n.td,{children:"Example contract to demonstrate the general way of upgrading a contract and the necessary steps"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-21"}),(0,t.jsx)(n.td,{children:"Example Contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/cdolaz/casper_dart_sdk",children:"Casper Dart SDK"})}),(0,t.jsx)(n.td,{children:"Casper Dart SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"Temiltas"}),(0,t.jsx)(n.td,{children:"Dart"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-26"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market's Casper variant of ERC20"})}),(0,t.jsx)(n.td,{children:"Implementation of the ERC20 standard for Casper networks"}),(0,t.jsx)(n.td,{children:"Friendly Market"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-10"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-go-sdk",children:"Casper Go SDK"})}),(0,t.jsx)(n.td,{children:"Casper Go SDK"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-01"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"Casper Hello World Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKey"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-13"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JavaScript SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client JavaScript SDK"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-Kotlin-sdk",children:"Casper Kotlin SDK"})}),(0,t.jsx)(n.td,{children:"Casper Kotlin Client SDK to interact with a Casper network."}),(0,t.jsx)(n.td,{children:"tqhuy2018"}),(0,t.jsx)(n.td,{children:"Kotlin"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-21"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/Casper-Metrics",children:"Casper Metrics"})}),(0,t.jsx)(n.td,{children:"Casper Metrics - fast blockchain crawler, API, and analysis tool"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-09"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-nctl-docker",children:"Casper NCTL Docker"})}),(0,t.jsx)(n.td,{children:"A Docker container that runs Casper NCTL as a service"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Shell"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-17"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/node-red-contrib-casper",children:"Casper Node-RED"})}),(0,t.jsx)(n.td,{children:"Nodes to communicate with the Casper's Blockchain using node-red"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-02-08"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-ObjectiveC-sdk",children:"Casper Objective-C SDK"})}),(0,t.jsx)(n.td,{children:"Casper Objective-C SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Objective-C"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-18"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-php-sdk",children:"Casper PHP SDK"})}),(0,t.jsx)(n.td,{children:"PHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHP"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/saitgulmez/casper-ruby-sdk",children:"Casper Ruby Client SDK"})}),(0,t.jsx)(n.td,{children:"Ruby SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"Sait Gulmez"}),(0,t.jsx)(n.td,{children:"Ruby"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"Casper Scala SDK"})}),(0,t.jsx)(n.td,{children:"Casper Scala client SDK to interact with the Casper Network nodes via RPC"}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Scala"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-23"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})}),(0,t.jsx)(n.td,{children:"A browser wallet for the Casper Network"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-04-12"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/credentia-network/casper-ssi-demo",children:"Casper SSI Web App"})}),(0,t.jsx)(n.td,{children:"Casper SSI Framework in the form of a demo web application."}),(0,t.jsx)(n.td,{children:"Credentia Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casper-storage",children:"Casper Storage"})}),(0,t.jsx)(n.td,{children:"Casper storage - HD wallets"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/hienbui9999/CasperSDKInSwift",children:"Casper Swift SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client SDK. Casper SDK methods implementation in Swift."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Swift"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig",children:"Casper Two-Party MultiSig Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys."}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-04-26"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/NodesGuru/casper-world",children:"Casper World"})}),(0,t.jsx)(n.td,{children:"Casper network status and decentralization map web application"}),(0,t.jsx)(n.td,{children:"Nodes Guru"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-26"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casperdash-client",children:"CasperDash Wallet"})}),(0,t.jsx)(n.td,{children:"A non-custodial wallet for the Casper blockchain"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/casperfyre-frontend",children:"CasperFYRE API"})}),(0,t.jsx)(n.td,{children:"Dispensory API interface for Casper Mainnet"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-06"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casperholders/casperholdersfront",children:"CasperHolders"})}),(0,t.jsx)(n.td,{children:"First 3rd party UI to interact with Casper Blockchain"}),(0,t.jsx)(n.td,{children:"CasperHolders"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/chronologic/caspersign-validator-ui",children:"CasperSign"})}),(0,t.jsx)(n.td,{children:"The First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper Blockchain"}),(0,t.jsx)(n.td,{children:"ChronoLogic and Digital Strategies"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-08-31"}),(0,t.jsx)(n.td,{children:"dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"CEP-78 Enhanced NFT Standard"})}),(0,t.jsx)(n.td,{children:"Standard Contract Generator for NFTs"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"CES Rust Event Emitter"})}),(0,t.jsx)(n.td,{children:"Rust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-05-11"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-js-parser",children:"CES JS Parser"})}),(0,t.jsx)(n.td,{children:"JS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-03-27"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-go-parser",children:"CES Go Parser"})}),(0,t.jsx)(n.td,{children:"Go library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-02"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/cleareststake-frontend",children:"Clearest Stake"})}),(0,t.jsx)(n.td,{children:"Staking Asset Manager for Node operators and groups"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-02"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/dao-contracts",children:"DAO Contracts"})}),(0,t.jsx)(n.td,{children:"Smart Contracts for the MVPR On-Chain Governance System on Casper"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-07-17"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/DHFinance/dhf-pay-front",children:"DHF PAY"})}),(0,t.jsx)(n.td,{children:"The crypto currency payment gateway on the CSPR blockchain"}),(0,t.jsx)(n.td,{children:"DHFinance"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-28"}),(0,t.jsx)(n.td,{children:"Payments"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dlndao/start/",children:"DLN DAO"})}),(0,t.jsx)(n.td,{children:"DLN DAO"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-10"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dotoracle/bridge-ui",children:"DotOracle"})}),(0,t.jsx)(n.td,{children:"Realtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains."}),(0,t.jsx)(n.td,{children:"DotOracle Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-09-26"}),(0,t.jsx)(n.td,{children:"Bridge"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Dragonlair",children:"Dragon\u2019s Lair Style Staking"})}),(0,t.jsx)(n.td,{children:"Lair Style Staking"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-EIP1337",children:"Subscription Billing"})}),(0,t.jsx)(n.td,{children:"ERC-1337 subscription billing"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-04-07"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Casper Fungible Token"})}),(0,t.jsx)(n.td,{children:"Implementation of Fungible Tokens for Casper networks"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-01"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-ERC777",children:"Advanced Fungible Token"})}),(0,t.jsx)(n.td,{children:"ERC-777 + 1820 Advanced Fungible Token with Callbacks & Self Identification"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-16"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/helperbot",children:"Helper Bot"})}),(0,t.jsx)(n.td,{children:"Helper bot for improving DevDao VAs productivity"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-08-19"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-java-sdk",children:"Java SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client Java SDK"}),(0,t.jsx)(n.td,{children:"SyntiFi"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2021-04-20"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/kyc-proxy-contract",children:"KYC Proxy Contact"})}),(0,t.jsx)(n.td,{children:"This is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-01"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-LiquidNFT",children:"LiquidNFT"})}),(0,t.jsx)(n.td,{children:"NFT Collateralized Loans"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GNU General Public License v3.0"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/payment-example",children:"Payment Example Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the usage of purses to transfer motes inside a contract"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-06-22"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/EKON-YAZILIM/ServicesDAO",children:"ServicesDAO"})}),(0,t.jsx)(n.td,{children:"The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR."}),(0,t.jsx)(n.td,{children:"Ekon Yazilim"}),(0,t.jsx)(n.td,{children:"HTML-CSS-C#"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp",children:"Uniswap DemoApp"})}),(0,t.jsx)(n.td,{children:"Uniswap UI + Contracts"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GPL-3.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/AdelElMessiry/Verified-Impact-NFTs",children:"Verified Impact NFT"})}),(0,t.jsx)(n.td,{children:"An NFT platform dedicated to impact causes with verification of the beneficiaries"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"JavaScript-Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-08"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://usewallet.casperdash.io",children:"UseWallet"})}),(0,t.jsx)(n.td,{children:"useWallet is a collection of React Hooks containing everything you need to start working with a Casper network"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://faucet.casperdash.io",children:"Testnet Faucet"})}),(0,t.jsx)(n.td,{children:"A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"Tools"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>i});var t=s(96540);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/14620e15.210101ba.js b/assets/js/14620e15.210101ba.js deleted file mode 100644 index 8d2083e5f..000000000 --- a/assets/js/14620e15.210101ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2447],{12114:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="J",a={id:"concepts/glossary/J",title:"J",description:"---",source:"@site/docs/concepts/glossary/J.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/J",permalink:"/next/concepts/glossary/J",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"I",permalink:"/next/concepts/glossary/I"},next:{title:"K",permalink:"/next/concepts/glossary/K"}},l={},h=[{value:"JSON",id:"json",level:2}];function x(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"j",children:"J"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"json",children:"JSON"}),"\n",(0,r.jsxs)(s.p,{children:["JSON (",(0,r.jsx)(s.strong,{children:"J"}),"ava",(0,r.jsx)(s.strong,{children:"S"}),"cript ",(0,r.jsx)(s.strong,{children:"O"}),"bject ",(0,r.jsx)(s.strong,{children:"N"}),"otation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found ",(0,r.jsx)(s.a,{href:"https://www.json.org/json-en.html",children:"here"}),"."]})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/14620e15.e55ff3e7.js b/assets/js/14620e15.e55ff3e7.js new file mode 100644 index 000000000..abb48c836 --- /dev/null +++ b/assets/js/14620e15.e55ff3e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82447],{12114:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="J",a={id:"concepts/glossary/J",title:"J",description:"---",source:"@site/docs/concepts/glossary/J.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/J",permalink:"/concepts/glossary/J",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"I",permalink:"/concepts/glossary/I"},next:{title:"K",permalink:"/concepts/glossary/K"}},l={},h=[{value:"JSON",id:"json",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"j",children:"J"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"json",children:"JSON"}),"\n",(0,n.jsxs)(e.p,{children:["JSON (",(0,n.jsx)(e.strong,{children:"J"}),"ava",(0,n.jsx)(e.strong,{children:"S"}),"cript ",(0,n.jsx)(e.strong,{children:"O"}),"bject ",(0,n.jsx)(e.strong,{children:"N"}),"otation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found ",(0,n.jsx)(e.a,{href:"https://www.json.org/json-en.html",children:"here"}),"."]})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/1494.44935779.js b/assets/js/1494.44935779.js deleted file mode 100644 index 9418cd9ff..000000000 --- a/assets/js/1494.44935779.js +++ /dev/null @@ -1 +0,0 @@ -(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1494],{27293:(e,t,n)=>{"use strict";n.d(t,{A:()=>L});var s=n(96540),a=n(74848);function o(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=t.filter((e=>e!==n)),c=n?.props.children;return{mdxAdmonitionTitle:c,rest:o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}}(e.children),o=e.title??t;return{...e,...o&&{title:o},children:n}}var c=n(34164),i=n(21312),r=n(17559);const l={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:t,className:n,children:s}=e;return(0,a.jsx)("div",{className:(0,c.A)(r.G.common.admonition,r.G.common.admonitionType(t),l.admonition,n),children:s})}function u(e){let{icon:t,title:n}=e;return(0,a.jsxs)("div",{className:l.admonitionHeading,children:[(0,a.jsx)("span",{className:l.admonitionIcon,children:t}),n]})}function m(e){let{children:t}=e;return t?(0,a.jsx)("div",{className:l.admonitionContent,children:t}):null}function h(e){const{type:t,icon:n,title:s,children:o,className:c}=e;return(0,a.jsxs)(d,{type:t,className:c,children:[s||n?(0,a.jsx)(u,{title:s,icon:n}):null,(0,a.jsx)(m,{children:o})]})}function p(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const f={icon:(0,a.jsx)(p,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function g(e){return(0,a.jsx)(h,{...f,...e,className:(0,c.A)("alert alert--secondary",e.className),children:e.children})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function b(e){return(0,a.jsx)(h,{...j,...e,className:(0,c.A)("alert alert--success",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function y(e){return(0,a.jsx)(h,{...N,...e,className:(0,c.A)("alert alert--info",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const k={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function B(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const C={icon:(0,a.jsx)(B,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:g,tip:b,info:y,warning:function(e){return(0,a.jsx)(h,{...k,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(h,{...C,...e,className:(0,c.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(g,{title:"secondary",...e}),important:e=>(0,a.jsx)(y,{title:"important",...e}),success:e=>(0,a.jsx)(b,{title:"success",...e}),caution:function(e){return(0,a.jsx)(h,{...w,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})}}};function L(e){const t=o(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(96540);var s=n(34164),a=n(21312),o=n(17559),c=n(28774);const i={iconEdit:"iconEdit_Z9Sw"};var r=n(74848);function l(e){let{className:t,...n}=e;return(0,r.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(i.iconEdit,t),"aria-hidden":"true",...n,children:(0,r.jsx)("g",{children:(0,r.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d(e){let{editUrl:t}=e;return(0,r.jsxs)(c.A,{to:t,className:o.G.common.editThisPage,children:[(0,r.jsx)(l,{}),(0,r.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(36266);function m(e){let{lastUpdatedAt:t}=e;const n=new Date(t),s=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(n);return(0,r.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,r.jsx)("b",{children:(0,r.jsx)("time",{dateTime:n.toISOString(),itemProp:"dateModified",children:s})})},children:" on {date}"})}function h(e){let{lastUpdatedBy:t}=e;return(0,r.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,r.jsx)("b",{children:t})},children:" by {user}"})}function p(e){let{lastUpdatedAt:t,lastUpdatedBy:n}=e;return(0,r.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,r.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t?(0,r.jsx)(m,{lastUpdatedAt:t}):"",byUser:n?(0,r.jsx)(h,{lastUpdatedBy:n}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const f={lastUpdated:"lastUpdated_JAkA"};function g(e){let{className:t,editUrl:n,lastUpdatedAt:a,lastUpdatedBy:o}=e;return(0,r.jsxs)("div",{className:(0,s.A)("row",t),children:[(0,r.jsx)("div",{className:"col",children:n&&(0,r.jsx)(d,{editUrl:n})}),(0,r.jsx)("div",{className:(0,s.A)("col",f.lastUpdated),children:(a||o)&&(0,r.jsx)(p,{lastUpdatedAt:a,lastUpdatedBy:o})})]})}},88509:(e,t,n)=>{"use strict";n.d(t,{A:()=>ie});var s=n(96540),a=n(28453),o=n(5260),c=n(92303),i=n(34164),r=n(95293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,r.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(17559),m=n(18426),h=n.n(m);const p=/title=(?["'])(?.*?)\1/,f=/\{(?<range>[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},x={...g,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},j=Object.keys(g);function b(e,t){const n=e.map((e=>{const{start:n,end:s}=x[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&f.test(o)){const e=o.match(f).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=h()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return b(["tex"],t);case"lua":case"haskell":case"sql":return b(["lua"],t);case"wasm":return b(["wasm"],t);case"vb":case"vba":case"visual-basic":return b(["vb","rem"],t);case"vbnet":return b(["vbnet","rem"],t);case"batch":return b(["rem"],t);case"basic":return b(["rem","f90"],t);case"fsharp":return b(["js","ml"],t);case"ocaml":case"sml":return b(["ml"],t);case"fortran":return b(["f90"],t);case"cobol":return b(["cobol"],t);default:return b(j,t)}}(s,a),i=n.split("\n"),r=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),l=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h<i.length;){const e=i[h].match(c);if(!e){h+=1;continue}const t=e.slice(1).find((e=>void 0!==e));l[t]?r[l[t]].range+=`${h},`:d[t]?r[d[t]].start=h:u[t]&&(r[u[t]].range+=`${r[u[t]].start}-${h-1},`),i.splice(h,1)}n=i.join("\n");const m={};return Object.entries(r).forEach((e=>{let[t,{range:n}]=e;h()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const N={codeBlockContainer:"codeBlockContainer_Ckt0"};var y=n(74848);function A(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(d());return(0,y.jsx)(t,{...n,style:s,className:(0,i.A)(n.className,N.codeBlockContainer,u.G.common.codeBlock)})}const k={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function B(e){let{children:t,className:n}=e;return(0,y.jsx)(A,{as:"pre",tabIndex:0,className:(0,i.A)(k.codeBlockStandalone,"thin-scrollbar",n),children:(0,y.jsx)("code",{className:k.codeBlockLines,children:t})})}var C=n(89532);const w={attributes:!0,characterData:!0,childList:!0,subtree:!0};function _(e,t){const[n,a]=(0,s.useState)(),o=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=w);const a=(0,C._q)(t),o=(0,C.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,o),()=>t.disconnect()}),[e,a,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var L=n(71765);const E={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function T(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const c=a({line:t,className:(0,i.A)(n,s&&E.codeLine)}),r=t.map(((e,t)=>(0,y.jsx)("span",{...o({token:e})},t)));return(0,y.jsxs)("span",{...c,children:[s?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)("span",{className:E.codeLineNumber}),(0,y.jsx)("span",{className:E.codeLineContent,children:r})]}):r,(0,y.jsx)("br",{})]})}var S=n(21312);function U(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function M(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const z={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),c=(0,s.useRef)(void 0),r=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),c=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let i=!1;try{i=document.execCommand("copy")}catch{}s.remove(),c&&(o.removeAllRanges(),o.addRange(c)),a&&a.focus()}(t),o(!0),c.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),(0,y.jsx)("button",{type:"button","aria-label":a?(0,S.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,S.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,S.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.A)("clean-btn",n,z.copyButton,a&&z.copyButtonCopied),onClick:r,children:(0,y.jsxs)("span",{className:z.copyButtonIcons,"aria-hidden":"true",children:[(0,y.jsx)(U,{className:z.copyButtonIcon}),(0,y.jsx)(M,{className:z.copyButtonSuccessIcon})]})})}function H(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const R={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function V(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,S.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,y.jsx)("button",{type:"button",onClick:n,className:(0,i.A)("clean-btn",t,s&&R.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,y.jsx)(H,{className:R.wordWrapButtonIcon,"aria-hidden":"true"})})}function W(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:c,language:r}=e;const{prism:{defaultLanguage:u,magicComments:m}}=(0,l.p)(),h=function(e){return e?.toLowerCase()}(r??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??u),f=d(),g=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),c=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return _(o,i),(0,s.useEffect)((()=>{i()}),[e,i]),(0,s.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:c}}(),x=function(e){return e?.match(p)?.groups.title??""}(a)||o,{lineClassNames:j,code:b}=v(t,{metastring:a,language:h,magicComments:m}),N=c??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,y.jsxs)(A,{as:"div",className:(0,i.A)(n,h&&!n.includes(`language-${h}`)&&`language-${h}`),children:[x&&(0,y.jsx)("div",{className:k.codeBlockTitle,children:x}),(0,y.jsxs)("div",{className:k.codeBlockContent,children:[(0,y.jsx)(L.f4,{theme:f,code:b,language:h??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,y.jsx)("pre",{tabIndex:0,ref:g.codeBlockRef,className:(0,i.A)(t,k.codeBlock,"thin-scrollbar"),style:n,children:(0,y.jsx)("code",{className:(0,i.A)(k.codeBlockLines,N&&k.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,y.jsx)(T,{line:e,getLineProps:a,getTokenProps:o,classNames:j[t],showLineNumbers:N},t)))})})}}),(0,y.jsxs)("div",{className:k.buttonGroup,children:[(g.isEnabled||g.isCodeScrollable)&&(0,y.jsx)(V,{className:k.codeButton,onClick:()=>g.toggle(),isEnabled:g.isEnabled}),(0,y.jsx)(I,{className:k.codeButton,code:b})]})]})]})}function $(e){let{children:t,...n}=e;const a=(0,c.A)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof o?W:B;return(0,y.jsx)(i,{...n,children:o},String(a))}function D(e){return(0,y.jsx)("code",{...e})}var P=n(28774);var G=n(63427),q=n(41422);const O={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function F(e){return!!e&&("SUMMARY"===e.tagName||F(e.parentElement))}function Z(e,t){return!!e&&(e===t||Z(e.parentElement,t))}function J(e){let{summary:t,children:n,...a}=e;(0,G.A)().collectAnchor(a.id);const o=(0,c.A)(),r=(0,s.useRef)(null),{collapsed:l,setCollapsed:d}=(0,q.u)({initialState:!a.open}),[u,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,y.jsx)("summary",{children:t??"Details"});return(0,y.jsxs)("details",{...a,ref:r,open:u,"data-collapsed":l,className:(0,i.A)(O.details,o&&O.isBrowser,a.className),onMouseDown:e=>{F(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;F(t)&&Z(t,r.current)&&(e.preventDefault(),l?(d(!1),m(!0)):d(!0))},children:[h,(0,y.jsx)(q.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{d(e),m(!e)},children:(0,y.jsx)("div",{className:O.collapsibleContent,children:n})})]})}const Y={details:"details_b_Ee"},K="alert alert--info";function Q(e){let{...t}=e;return(0,y.jsx)(J,{...t,className:(0,i.A)(K,Y.details,t.className)})}function X(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,y.jsx)(y.Fragment,{children:t.filter((e=>e!==n))});return(0,y.jsx)(Q,{...e,summary:n,children:a})}var ee=n(51107);function te(e){return(0,y.jsx)(ee.A,{...e})}const ne={containsTaskList:"containsTaskList_mC6p"};function se(e){if(void 0!==e)return(0,i.A)(e,e?.includes("contains-task-list")&&ne.containsTaskList)}const ae={img:"img_ev3q"};var oe=n(27293);const ce={Head:o.A,details:X,Details:X,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,y.jsx)(D,{...e}):(0,y.jsx)($,{...e})},a:function(e){return(0,y.jsx)(P.A,{...e})},pre:function(e){return(0,y.jsx)(y.Fragment,{children:e.children})},ul:function(e){return(0,y.jsx)("ul",{...e,className:se(e.className)})},li:function(e){return(0,G.A)().collectAnchor(e.id),(0,y.jsx)("li",{...e})},img:function(e){return(0,y.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,i.A)(t,ae.img))});var t},h1:e=>(0,y.jsx)(te,{as:"h1",...e}),h2:e=>(0,y.jsx)(te,{as:"h2",...e}),h3:e=>(0,y.jsx)(te,{as:"h3",...e}),h4:e=>(0,y.jsx)(te,{as:"h4",...e}),h5:e=>(0,y.jsx)(te,{as:"h5",...e}),h6:e=>(0,y.jsx)(te,{as:"h6",...e}),admonition:oe.A,mermaid:()=>null};function ie(e){let{children:t}=e;return(0,y.jsx)(a.x,{components:ce,children:t})}},39022:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(28774),o=n(74848);function c(e){const{permalink:t,title:n,subLabel:c,isNext:i}=e;return(0,o.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[c&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:c}),(0,o.jsx)("div",{className:"pagination-nav__label",children:n})]})}},56133:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(96540);var s=n(34164),a=n(28774);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var c=n(74848);function i(e){let{permalink:t,label:n,count:i,description:r}=e;return(0,c.jsxs)(a.A,{href:t,title:r,className:(0,s.A)(o.tag,i?o.tagWithCount:o.tagRegular),children:[n,i&&(0,c.jsx)("span",{children:i})]})}},62053:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});n(96540);var s=n(34164),a=n(21312),o=n(56133);const c={tags:"tags_jXut",tag:"tag_QGVx"};var i=n(74848);function r(e){let{tags:t}=e;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("b",{children:(0,i.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,i.jsx)("ul",{className:(0,s.A)(c.tags,"padding--none","margin-left--sm"),children:t.map((e=>(0,i.jsx)("li",{className:c.tag,children:(0,i.jsx)(o.A,{...e})},e.permalink)))})]})}},36266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(44586);function a(e){void 0===e&&(e={});const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},18426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s<o?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(o+=e);for(let t=s;t!==o;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},28453:(e,t,n)=>{"use strict";n.d(t,{R:()=>c,x:()=>i});var s=n(96540);const a={},o=s.createContext(a);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/157e4bc2.7b9ed566.js b/assets/js/157e4bc2.7b9ed566.js new file mode 100644 index 000000000..70efd9743 --- /dev/null +++ b/assets/js/157e4bc2.7b9ed566.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93632],{84775:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),a=s(28453);const i={title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},c="Installing and Interacting with a CEP-78 Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client",title:"On-chain Installation",description:"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.",source:"@site/docs/resources/tokens/cep78/using-casper-client.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/using-casper-client",permalink:"/resources/tokens/using-casper-client",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},sidebar:"resources",previous:{title:"CEP-78 Modalities",permalink:"/resources/tokens/cep78/modalities"},next:{title:"Ownership Lookup",permalink:"/resources/tokens/cep78/reverse-lookup"}},o={},d=[{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Directly Invoking Entrypoints",id:"directly-invoking-entrypoints",level:2},{value:"Minting an NFT",id:"minting-an-nft",level:2},{value:"Transferring NFTs Between Users",id:"transferring-nfts-between-users",level:2},{value:"Burning an NFT",id:"burning-an-nft",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-and-interacting-with-a-cep-78-contract-using-the-rust-casper-client",children:"Installing and Interacting with a CEP-78 Contract using the Rust Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of ",(0,t.jsx)(n.code,{children:"1.63.0"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Information on the modalities used throughout this installation process can be found in the ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"modalities documentation"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,t.jsxs)(n.p,{children:["Installing the enhanced NFT contract to global state requires the use of a ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Deploy"}),". In this case, the session code can be compiled to Wasm by running the ",(0,t.jsx)(n.code,{children:"make build-contract"})," command provided in the Makefile at the top level. The Wasm will be found in the ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory as ",(0,t.jsx)(n.code,{children:"contract.wasm"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='CEP-78-collection'\""})}),"\n",(0,t.jsx)(n.p,{children:'The name of the NFT collection as a string. In this instance, "CEP-78-collection".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_symbol:string='CEP78'\""})}),"\n",(0,t.jsx)(n.p,{children:'The symbol representing the NFT collection as a string. In this instance, "CEP78".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"total_token_supply:u64='100'\""})}),"\n",(0,t.jsx)(n.p,{children:"The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"ownership_mode:u8='2'\""})}),"\n",(0,t.jsx)(n.p,{children:'The ownership mode for this contract. In this instance the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_kind:u8='1'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_metadata_kind:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"json_schema:string=''\""})}),"\n",(0,t.jsx)(n.p,{children:"An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom validated modality would require passing through a valid JSON schema for your custom metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"identifier_mode:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"metadata_mutability:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The session arguments match the available modalities as listed ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"}),"\n",(0,t.jsxs)(n.p,{children:["With the release of CEP-78 version 1.1, users that are interacting with a CEP-78 contract that does not use ",(0,t.jsx)(n.code,{children:"ReverseLookupMode"})," should opt out of using the client Wasms provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost compared against using the provided client Wasm to invoke the entrypoint."]}),"\n",(0,t.jsxs)(n.p,{children:["You may invoke the ",(0,t.jsx)(n.code,{children:"mint"}),", ",(0,t.jsx)(n.code,{children:"transfer"})," or ",(0,t.jsx)(n.code,{children:"burn"})," entrypoints directly through either the contract package hash or the contract hash directly."]}),"\n",(0,t.jsxs)(n.p,{children:["Specifically in the case of ",(0,t.jsx)(n.code,{children:"mint"}),", there are fewer runtime arguments that must be provided, thereby reducing the total gas cost of minting an NFT."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Mint using StoredVersionByHash"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-package-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "mint" \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Transfer using StoredContractByHash"})}),"\n",(0,t.jsxs)(n.p,{children:["Based on the identifier mode for the given contract instance, either the ",(0,t.jsx)(n.code,{children:"token_id"})," runtime argument must be passed in or in the case of the hash identifier mode, the ",(0,t.jsx)(n.code,{children:"token_hash"})," runtime argument."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "transfer" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "token_id:u64=\'0\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"minting-an-nft",children:"Minting an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"mint"})," function of the contract to mint an NFT for the user associated with ",(0,t.jsx)(n.code,{children:"node-1"})," in an ",(0,t.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"NCTL environment"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='cep78_<collection_name>'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,t.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,t.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95\'" \\\n--session-arg "collection_name:string=\'cep78_<collection_name>\'"` \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-nfts-between-users",children:"Transferring NFTs Between Users"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"transfer"})," function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with ",(0,t.jsx)(n.code,{children:"node-2"})," to the user associated with ",(0,t.jsx)(n.code,{children:"node-3"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,t.jsxs)(n.p,{children:["Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,t.jsx)(n.code,{children:"token_id"})," rather than a ",(0,t.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"burning-an-nft",children:"Burning an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"burn"})," function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,t.jsx)(n.p,{children:"The session hash corresponding to the NFT's contract hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-entry-point "burn"'})}),"\n",(0,t.jsxs)(n.p,{children:["The entrypoint corresponding to the ",(0,t.jsx)(n.code,{children:"burn"})," function."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The token ID for the NFT to be burned. If the ",(0,t.jsx)(n.code,{children:"identifier_mode"})," is not set to ",(0,t.jsx)(n.code,{children:"Ordinal"}),", you must provide the ",(0,t.jsx)(n.code,{children:"token_hash"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/157e4bc2.eba0692b.js b/assets/js/157e4bc2.eba0692b.js deleted file mode 100644 index 1fa4f25f1..000000000 --- a/assets/js/157e4bc2.eba0692b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3632],{84775:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),a=s(28453);const i={title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},c="Installing and Interacting with a CEP-78 Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client",title:"On-chain Installation",description:"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.",source:"@site/docs/resources/tokens/cep78/using-casper-client.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/using-casper-client",permalink:"/next/resources/tokens/using-casper-client",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},sidebar:"resources",previous:{title:"CEP-78 Modalities",permalink:"/next/resources/tokens/cep78/modalities"},next:{title:"Ownership Lookup",permalink:"/next/resources/tokens/cep78/reverse-lookup"}},o={},d=[{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Directly Invoking Entrypoints",id:"directly-invoking-entrypoints",level:2},{value:"Minting an NFT",id:"minting-an-nft",level:2},{value:"Transferring NFTs Between Users",id:"transferring-nfts-between-users",level:2},{value:"Burning an NFT",id:"burning-an-nft",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-and-interacting-with-a-cep-78-contract-using-the-rust-casper-client",children:"Installing and Interacting with a CEP-78 Contract using the Rust Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of ",(0,t.jsx)(n.code,{children:"1.63.0"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Information on the modalities used throughout this installation process can be found in the ",(0,t.jsx)(n.a,{href:"/next/resources/tokens/cep78/modalities",children:"modalities documentation"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,t.jsxs)(n.p,{children:["Installing the enhanced NFT contract to global state requires the use of a ",(0,t.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Deploy"}),". In this case, the session code can be compiled to Wasm by running the ",(0,t.jsx)(n.code,{children:"make build-contract"})," command provided in the Makefile at the top level. The Wasm will be found in the ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory as ",(0,t.jsx)(n.code,{children:"contract.wasm"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='CEP-78-collection'\""})}),"\n",(0,t.jsx)(n.p,{children:'The name of the NFT collection as a string. In this instance, "CEP-78-collection".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_symbol:string='CEP78'\""})}),"\n",(0,t.jsx)(n.p,{children:'The symbol representing the NFT collection as a string. In this instance, "CEP78".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"total_token_supply:u64='100'\""})}),"\n",(0,t.jsx)(n.p,{children:"The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"ownership_mode:u8='2'\""})}),"\n",(0,t.jsx)(n.p,{children:'The ownership mode for this contract. In this instance the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_kind:u8='1'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_metadata_kind:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"json_schema:string=''\""})}),"\n",(0,t.jsx)(n.p,{children:"An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom validated modality would require passing through a valid JSON schema for your custom metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"identifier_mode:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"metadata_mutability:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The session arguments match the available modalities as listed ",(0,t.jsx)(n.a,{href:"/next/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"}),"\n",(0,t.jsxs)(n.p,{children:["With the release of CEP-78 version 1.1, users that are interacting with a CEP-78 contract that does not use ",(0,t.jsx)(n.code,{children:"ReverseLookupMode"})," should opt out of using the client Wasms provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost compared against using the provided client Wasm to invoke the entrypoint."]}),"\n",(0,t.jsxs)(n.p,{children:["You may invoke the ",(0,t.jsx)(n.code,{children:"mint"}),", ",(0,t.jsx)(n.code,{children:"transfer"})," or ",(0,t.jsx)(n.code,{children:"burn"})," entrypoints directly through either the contract package hash or the contract hash directly."]}),"\n",(0,t.jsxs)(n.p,{children:["Specifically in the case of ",(0,t.jsx)(n.code,{children:"mint"}),", there are fewer runtime arguments that must be provided, thereby reducing the total gas cost of minting an NFT."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Mint using StoredVersionByHash"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-package-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "mint" \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Transfer using StoredContractByHash"})}),"\n",(0,t.jsxs)(n.p,{children:["Based on the identifier mode for the given contract instance, either the ",(0,t.jsx)(n.code,{children:"token_id"})," runtime argument must be passed in or in the case of the hash identifier mode, the ",(0,t.jsx)(n.code,{children:"token_hash"})," runtime argument."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "transfer" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "token_id:u64=\'0\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"minting-an-nft",children:"Minting an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"mint"})," function of the contract to mint an NFT for the user associated with ",(0,t.jsx)(n.code,{children:"node-1"})," in an ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/nctl-test",children:"NCTL environment"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='cep78_<collection_name>'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,t.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,t.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95\'" \\\n--session-arg "collection_name:string=\'cep78_<collection_name>\'"` \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-nfts-between-users",children:"Transferring NFTs Between Users"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"transfer"})," function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with ",(0,t.jsx)(n.code,{children:"node-2"})," to the user associated with ",(0,t.jsx)(n.code,{children:"node-3"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,t.jsxs)(n.p,{children:["Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,t.jsx)(n.code,{children:"token_id"})," rather than a ",(0,t.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"burning-an-nft",children:"Burning an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"burn"})," function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,t.jsx)(n.p,{children:"The session hash corresponding to the NFT's contract hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-entry-point "burn"'})}),"\n",(0,t.jsxs)(n.p,{children:["The entrypoint corresponding to the ",(0,t.jsx)(n.code,{children:"burn"})," function."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The token ID for the NFT to be burned. If the ",(0,t.jsx)(n.code,{children:"identifier_mode"})," is not set to ",(0,t.jsx)(n.code,{children:"Ordinal"}),", you must provide the ",(0,t.jsx)(n.code,{children:"token_hash"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/158765df.0818e83f.js b/assets/js/158765df.0818e83f.js new file mode 100644 index 000000000..0cb3a97cb --- /dev/null +++ b/assets/js/158765df.0818e83f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11595],{93194:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var t=s(74848),i=s(28453);const r={title:"Ledger and Ledger Live"},c="Using Ledger and Ledger Live",d={id:"users/ledger/ledger-live",title:"Ledger and Ledger Live",description:"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.",source:"@site/versioned_docs/version-2.0.0/users/ledger/ledger-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-live",permalink:"/2.0.0/users/ledger/ledger-live",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Ledger and Ledger Live"},sidebar:"users",previous:{title:"Set up Ledger",permalink:"/2.0.0/workflow/ledger-setup/"},next:{title:"Ledger and CSPR.live",permalink:"/2.0.0/users/ledger/ledger-cspr-live"}},a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Connecting to Ledger Live",id:"connect-ledge-live",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function l(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-ledger-live",children:"Using Ledger and Ledger Live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect accounts from the Ledger device to the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.admonition,{type:"important",children:(0,t.jsx)(n.p,{children:"From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,t.jsxs)(n.li,{children:["Install the Casper app as described ",(0,t.jsx)(n.a,{href:"/2.0.0/workflow/ledger-setup/",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"connect-ledge-live",children:"Connecting to Ledger Live"}),"\n",(0,t.jsxs)(n.p,{children:["This section describes using the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application and your Casper accounts."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect the Ledger to your computer",src:s(11865).A+"",width:"2024",height:"770"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Allow Ledger Manager to connect by clicking the two buttons on the Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Unlock the ledger",src:s(14044).A+"",width:"2018",height:"974"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will verify your Ledger device and display the following confirmation:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(99798).A+"",width:"2014",height:"362"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"My Ledger"})," in the left-side navigation bar, and search for ",(0,t.jsx)(n.em,{children:"Casper"})," or ",(0,t.jsx)(n.em,{children:"CSPR"})," in the ",(0,t.jsx)(n.strong,{children:"App catalog"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(3860).A+"",width:"2272",height:"1536"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["To import a Casper account from the Ledger device into the Ledger Live application, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click the Add account link",src:s(61048).A+"",width:"2044",height:"390"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Open the Casper app on your Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Open the Casper app",src:s(35405).A+"",width:"1006",height:"932"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will import the first account listed on your Ledger device. Choose a name for the account."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Name the account",src:s(58010).A+"",width:"999",height:"714"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"After synchronizing the account, Ledger Live will confirm that the account was successfully added."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Synchronizing the account",src:s(46703).A+"",width:"1001",height:"626"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the account was added",src:s(7796).A+"",width:"1001",height:"955"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"Click on the account summary, to view more details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account summary",src:s(43076).A+"",width:"2278",height:"726"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account details",src:s(19790).A+"",width:"2252",height:"1452"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["To add another account, open the ",(0,t.jsx)(n.strong,{children:"Account"})," option in the left-side navigation bar. Then, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Add a second account",src:s(85285).A+"",width:"2180",height:"466"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Receive"})," option in the left-side navigation bar."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click on Receive",src:s(13663).A+"",width:"990",height:"934"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Choose an account from the drop-down list."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account",src:s(63142).A+"",width:"998",height:"920"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Copy the address displayed, or use the corresponding QR code."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account 2",src:s(73437).A+"",width:"990",height:"1192"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click ",(0,t.jsx)(n.strong,{children:"APPROVE"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 1",src:s(29772).A+"",width:"640",height:"313"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 2",src:s(73179).A+"",width:"640",height:"247"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click approve",src:s(57890).A+"",width:"640",height:"297"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation displayed",src:s(70233).A+"",width:"986",height:"748"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsx)(n.p,{children:"Ledger Live supports sending CSPR tokens from one Casper account to another."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Start by clicking on the ",(0,t.jsx)(n.strong,{children:"Send"})," option in the left-side navigation bar. Choose the account to debit:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose the account to debit",src:s(28309).A+"",width:"994",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the recipient's address and click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter reciepient",src:s(32297).A+"",width:"990",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the amount and an optional transfer ID. Click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter amount and transfer ID",src:s(42838).A+"",width:"992",height:"1052"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Review the summary, and if everything is correct, click ",(0,t.jsx)(n.strong,{children:"Continue"}),". Otherwise, click the ",(0,t.jsx)(n.strong,{children:"Back"})," link in the top-left corner."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transfer",src:s(26391).A+"",width:"990",height:"1132"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount. Meanwhile, Ledger Live will display this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transaction in the Ledger",src:s(93292).A+"",width:"990",height:"1290"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details until you see ",(0,t.jsx)(n.strong,{children:'"APPROVE"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.strong,{children:"Txn hash"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(75528).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-tx-2",src:s(49852).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["The next screen displays the transaction ",(0,t.jsx)(n.strong,{children:"Type"}),", which will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(25176).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"chain ID"}),", which for Mainnet should be ",(0,t.jsx)(n.strong,{children:"casper"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(65019).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"})," initiating the token transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(9356).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(23994).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(11342).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", which is the recipient's public key."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(94594).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(95276).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(10485).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(98456).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Broadcasting transaction",src:s(64237).A+"",width:"979",height:"938"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction sent",src:s(2042).A+"",width:"992",height:"992"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsxs)(n.li,{children:["To view the transaction details, click on the ",(0,t.jsx)(n.strong,{children:"View details"})," button. The following screen will appear:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction details",src:s(83979).A+"",width:"982",height:"1334"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsxs)(n.li,{children:["You can view the transaction in the CSPR.live block explorer by clicking on the ",(0,t.jsx)(n.strong,{children:"View in explorer"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Explorer chowing transaction",src:s(48304).A+"",width:"1960",height:"1140"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},11342:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},94594:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},95276:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},10485:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},98456:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},75528:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},49852:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},25176:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},65019:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},9356:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},23994:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},11865:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/0-connect-51dc63eac8bb4108b5819e53b2320101.png"},14044:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-unlock-3bd74f14f8d1c98ed8e0693e4b60ee08.png"},19790:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-account-details-b948b4322fa45f1eb4084921908054da.png"},85285:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-second-account-452dfda3813f97866e7109c383b52494.png"},13663:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-receive-e96873468302c422b0f759cf7dc2b452.png"},63142:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-receive-39af424b927864f776f577543e6d5617.png"},73437:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/14-receive-dc8f6cf7abd29ecd60fde182f8a3eb2b.png"},29772:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-receive-4ff498e5dd601eb18cd46a0d7648f675.png"},73179:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/16-receive-3fefa1c9455c51718f5414c0941efe8d.png"},57890:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/17-receive-e560cc80468abe4d8cff6582c7c916af.png"},70233:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/18-receive-50241c9e26a773568154d73110fa0eaf.png"},28309:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/19-send-f0b733857a605b692aef8d985ca53cf7.png"},99798:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-confirmation-93db08f91f73e80e194b83a38335e2f7.png"},32297:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/20-send-a47149d85a3a55b96523dd39d071eec9.png"},42838:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/21-send-dbff3394e9ee1dc0ba7e3455139f6857.png"},26391:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/22-send-710e2cb1e9623e8285386e9d2401bf6a.png"},93292:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/23-send-6b6a8ededcf9f387ca3ad2a969b794eb.png"},64237:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/24-send-fe804e955323f7d7efa274791f1f3b19.png"},2042:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/25-send-8b261293298a9a96470f648907576326.png"},83979:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/26-send-59402163032dba28406efe5fa1ac2bc6.png"},48304:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/27-send-28a4e6195b22c34240acd3f162fe0a5c.png"},3860:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-app-cspr-a6c84f316cd2e0c1ee8ee2dce4052d1d.png"},61048:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-add-account-601e6f86db467e2dc565a8f450bdccb0.png"},35405:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-add-account-9497a448d27f533f230e3e681b568eb7.png"},58010:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/6-add-account-ef77a19736e2fec10e5e3e58610b6cd2.png"},46703:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-add-account-993de3e6854e0b2713bd8df1b1b3bd80.png"},7796:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-add-account-746309f12b6b97426a1696b3a9712730.png"},43076:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-summary-e314cd0c1ca2e839a48ef4b80c44f198.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/15ce11b3.3da7da11.js b/assets/js/15ce11b3.3da7da11.js new file mode 100644 index 000000000..d097ac3d0 --- /dev/null +++ b/assets/js/15ce11b3.3da7da11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87746],{84209:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const c={title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},a="Two-Party Multi-Signature Deploys",i={id:"resources/advanced/two-party-multi-sig",title:"Two-Party Multi-Sig",description:"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.",source:"@site/docs/resources/advanced/two-party-multi-sig.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/two-party-multi-sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},sidebar:"tutorials",previous:{title:"Advanced Tutorials",permalink:"/resources/tutorials/advanced/"},next:{title:"Introduction",permalink:"/resources/advanced/multi-sig/"}},r={},d=[{value:"Configuring the Main Account",id:"configuring-the-main-account",level:2},{value:"Running session code to set up associated keys",id:"running-session-code-to-set-up-associated-keys",level:3},{value:"Confirming Processing and Account Status",id:"confirming-execution-and-account-status",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"two-party-multi-signature-deploys",children:"Two-Party Multi-Signature Deploys"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Accounts"})," on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys."]}),"\n",(0,s.jsx)(n.p,{children:"This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having the Casper command-line client and a valid node address"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the main account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex (",(0,s.jsx)(n.strong,{children:"MA"}),") and another ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex to associate (",(0,s.jsx)(n.strong,{children:"AA"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"sent deploys"})," to a Casper network"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-the-main-account",children:"Configuring the Main Account"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet."})}),"\n",(0,s.jsxs)(n.p,{children:["Each Account has an ",(0,s.jsx)(n.code,{children:"associated_keys"})," field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the ",(0,s.jsx)(n.code,{children:"associated_keys"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the ",(0,s.jsx)(n.code,{children:"action_thresholds"})," for the account."]}),"\n",(0,s.jsx)(n.p,{children:"Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Send a deploy to the network; determined by the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold"]}),"\n",(0,s.jsxs)(n.li,{children:["Edit the ",(0,s.jsx)(n.code,{children:"associated keys"})," and the ",(0,s.jsx)(n.code,{children:"action_thresholds"}),"; determined by the ",(0,s.jsx)(n.code,{children:"key_management"})," threshold"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the ",(0,s.jsx)(n.em,{children:"main key"})," and ",(0,s.jsx)(n.em,{children:"associated key"}),"'s combined weight must be greater than or equal to the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold. This can be achieved by having each key's weight equal to half of the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold."]}),"\n",(0,s.jsx)(n.h3,{id:"running-session-code-to-set-up-associated-keys",children:"Running session code to set up associated keys"}),"\n",(0,s.jsxs)(n.p,{children:["To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"GitHub"}),". Note that this session code is not a general-purpose program and needs to be modified for each use case."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/contract/src/main.rs",children:"session code"})," executes ",(0,s.jsx)(n.strong,{children:"3 crucial steps"})," to enforce the multi-sig scheme for the main account:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Adds an associated key to the account; we will refer to this key as ",(0,s.jsx)(n.strong,{children:"AA"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"action"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", such that the weight required to send a deploy is split equally between the keys associated with the account"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The repository contains a ",(0,s.jsx)(n.em,{children:"Makefile"})," with the build commands necessary to compile the contract and generate the necessary Wasm."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd two-party-multi-sig\nmake build-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The compiled Wasm will be saved on this path: ",(0,s.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper command-line client can be used to send the compiled Wasm to the network for execution."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://<peer-ip-address>:7777 \\\n--secret-key <secret-key-MA>.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path <path-to-contract-wasm> \\\n--session-arg \"deployment-account:account_hash='account-hash-<hash-AA>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the main account"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-arg"})," - The contract takes the account hash of the associated account as an argument labeled ",(0,s.jsx)(n.code,{children:"deployment-account"}),". You can pass this argument using the ",(0,s.jsx)(n.code,{children:"--session-arg"})," flag in the command line client"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'"result"."deploy_hash"'})," - the address of the executed deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Save the returned ",(0,s.jsx)(n.code,{children:"deploy_hash"})," from the output to query information about execution status."]}),"\n",(0,s.jsx)(n.h3,{id:"confirming-execution-and-account-status",children:"Confirming Processing and Account Status"}),"\n",(0,s.jsxs)(n.p,{children:["Account configuration on a Casper blockchain is stored in a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/M#merkle-tree",children:"Merkle Tree"})," and is a snapshot of the blockchain's ",(0,s.jsx)(n.a,{href:"/concepts/global-state#global-state-head",children:"Global State"}),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," and is stored in every executed block."]}),"\n",(0,s.jsxs)(n.p,{children:["To check that the account was configured correctly, you need the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," corresponding to the block that contains your deploy. To obtain the ",(0,s.jsx)(n.code,{children:"state-root-hash"}),", you need to:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Confirm the execution status of the deploy"})," and obtain the hash of the block containing it"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-blocks",children:"Query the block containing the deploy"})," to obtain the corresponding ",(0,s.jsx)(n.code,{children:"state_root_hash"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," and the ",(0,s.jsx)(n.code,{children:"hex-encoded-public-key"})," of the main account, query the network and check the account's configuration."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<peer-ip-address>:7777 \\\n--state-root-hash <state-root-hash-from-block> \\\n--key <hex-encoded-public-key-MA>\n"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example output"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In the example output, you can see the account hashes listed within the ",(0,s.jsx)(n.code,{children:"associated_keys"})," section. Each key has weight ",(0,s.jsx)(n.code,{children:"1"}),"; since the action threshold for ",(0,s.jsx)(n.code,{children:"deployment"})," is ",(0,s.jsx)(n.code,{children:"2"}),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},c=s.createContext(o);function a(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/15ce11b3.dca58b4c.js b/assets/js/15ce11b3.dca58b4c.js deleted file mode 100644 index 7510e645f..000000000 --- a/assets/js/15ce11b3.dca58b4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7746],{84209:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const c={title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},a="Two-Party Multi-Signature Deploys",i={id:"resources/advanced/two-party-multi-sig",title:"Two-Party Multi-Sig",description:"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.",source:"@site/docs/resources/advanced/two-party-multi-sig.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/two-party-multi-sig",permalink:"/next/resources/tutorials/advanced/two-party-multi-sig",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},sidebar:"tutorials",previous:{title:"Advanced Tutorials",permalink:"/next/resources/tutorials/advanced/"},next:{title:"Introduction",permalink:"/next/resources/advanced/multi-sig/"}},r={},d=[{value:"Configuring the Main Account",id:"configuring-the-main-account",level:2},{value:"Running session code to set up associated keys",id:"running-session-code-to-set-up-associated-keys",level:3},{value:"Confirming Processing and Account Status",id:"confirming-execution-and-account-status",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"two-party-multi-signature-deploys",children:"Two-Party Multi-Signature Deploys"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Accounts"})," on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys."]}),"\n",(0,s.jsx)(n.p,{children:"This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet the ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"prerequisites"}),", including having the Casper command-line client and a valid node address"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the main account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex (",(0,s.jsx)(n.strong,{children:"MA"}),") and another ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex to associate (",(0,s.jsx)(n.strong,{children:"AA"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"sent deploys"})," to a Casper network"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-the-main-account",children:"Configuring the Main Account"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet."})}),"\n",(0,s.jsxs)(n.p,{children:["Each Account has an ",(0,s.jsx)(n.code,{children:"associated_keys"})," field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the ",(0,s.jsx)(n.code,{children:"associated_keys"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the ",(0,s.jsx)(n.code,{children:"action_thresholds"})," for the account."]}),"\n",(0,s.jsx)(n.p,{children:"Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Send a deploy to the network; determined by the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold"]}),"\n",(0,s.jsxs)(n.li,{children:["Edit the ",(0,s.jsx)(n.code,{children:"associated keys"})," and the ",(0,s.jsx)(n.code,{children:"action_thresholds"}),"; determined by the ",(0,s.jsx)(n.code,{children:"key_management"})," threshold"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the ",(0,s.jsx)(n.em,{children:"main key"})," and ",(0,s.jsx)(n.em,{children:"associated key"}),"'s combined weight must be greater than or equal to the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold. This can be achieved by having each key's weight equal to half of the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold."]}),"\n",(0,s.jsx)(n.h3,{id:"running-session-code-to-set-up-associated-keys",children:"Running session code to set up associated keys"}),"\n",(0,s.jsxs)(n.p,{children:["To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"GitHub"}),". Note that this session code is not a general-purpose program and needs to be modified for each use case."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/contract/src/main.rs",children:"session code"})," executes ",(0,s.jsx)(n.strong,{children:"3 crucial steps"})," to enforce the multi-sig scheme for the main account:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Adds an associated key to the account; we will refer to this key as ",(0,s.jsx)(n.strong,{children:"AA"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"action"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", such that the weight required to send a deploy is split equally between the keys associated with the account"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The repository contains a ",(0,s.jsx)(n.em,{children:"Makefile"})," with the build commands necessary to compile the contract and generate the necessary Wasm."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd two-party-multi-sig\nmake build-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The compiled Wasm will be saved on this path: ",(0,s.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper command-line client can be used to send the compiled Wasm to the network for execution."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://<peer-ip-address>:7777 \\\n--secret-key <secret-key-MA>.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path <path-to-contract-wasm> \\\n--session-arg \"deployment-account:account_hash='account-hash-<hash-AA>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the main account"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-arg"})," - The contract takes the account hash of the associated account as an argument labeled ",(0,s.jsx)(n.code,{children:"deployment-account"}),". You can pass this argument using the ",(0,s.jsx)(n.code,{children:"--session-arg"})," flag in the command line client"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'"result"."deploy_hash"'})," - the address of the executed deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Save the returned ",(0,s.jsx)(n.code,{children:"deploy_hash"})," from the output to query information about execution status."]}),"\n",(0,s.jsx)(n.h3,{id:"confirming-execution-and-account-status",children:"Confirming Processing and Account Status"}),"\n",(0,s.jsxs)(n.p,{children:["Account configuration on a Casper blockchain is stored in a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/M#merkle-tree",children:"Merkle Tree"})," and is a snapshot of the blockchain's ",(0,s.jsx)(n.a,{href:"/next/concepts/global-state#global-state-head",children:"Global State"}),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," and is stored in every executed block."]}),"\n",(0,s.jsxs)(n.p,{children:["To check that the account was configured correctly, you need the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," corresponding to the block that contains your deploy. To obtain the ",(0,s.jsx)(n.code,{children:"state-root-hash"}),", you need to:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Confirm the execution status of the deploy"})," and obtain the hash of the block containing it"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-blocks",children:"Query the block containing the deploy"})," to obtain the corresponding ",(0,s.jsx)(n.code,{children:"state_root_hash"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," and the ",(0,s.jsx)(n.code,{children:"hex-encoded-public-key"})," of the main account, query the network and check the account's configuration."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<peer-ip-address>:7777 \\\n--state-root-hash <state-root-hash-from-block> \\\n--key <hex-encoded-public-key-MA>\n"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example output"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In the example output, you can see the account hashes listed within the ",(0,s.jsx)(n.code,{children:"associated_keys"})," section. Each key has weight ",(0,s.jsx)(n.code,{children:"1"}),"; since the action threshold for ",(0,s.jsx)(n.code,{children:"deployment"})," is ",(0,s.jsx)(n.code,{children:"2"}),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},c=s.createContext(o);function a(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/168da062.e84c3ca9.js b/assets/js/168da062.e84c3ca9.js new file mode 100644 index 000000000..1f1c0276a --- /dev/null +++ b/assets/js/168da062.e84c3ca9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[56365],{26962:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={title:"Move a Node"},o="Moving a Validating Node",d={id:"operators/maintenance/moving-node",title:"Move a Node",description:"This guide is for active validators who want to move their node to another machine.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/moving-node.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/moving-node",permalink:"/1.5.X/operators/maintenance/moving-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Move a Node"},sidebar:"operators",previous:{title:"Archive and Restore a DB",permalink:"/1.5.X/operators/maintenance/archiving-and-restoring"}},a={},c=[{value:"Swapping Keys with a Hot Backup",id:"swapping-keys-with-a-hot-backup",level:2},{value:"Preparation for swapping",id:"preparation-for-swapping",level:3},{value:"Swapping the nodes",id:"swapping-the-nodes",level:3},{value:"Understanding rewards impact",id:"understanding-rewards-impact",level:3},{value:"Checking file permissions",id:"checking-file-permissions",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"moving-a-validating-node",children:"Moving a Validating Node"})}),"\n",(0,i.jsx)(n.p,{children:"This guide is for active validators who want to move their node to another machine."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"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."})}),"\n",(0,i.jsx)(n.h2,{id:"swapping-keys-with-a-hot-backup",children:"Swapping Keys with a Hot Backup"}),"\n",(0,i.jsx)(n.p,{children:"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."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Once a node is running (",(0,i.jsx)(n.code,{children:"current_node"}),"), create a second node (",(0,i.jsx)(n.code,{children:"backup_node"}),") on another machine. These two nodes will run in parallel."]}),"\n",(0,i.jsxs)(n.li,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Move the unit files at the DB level using ",(0,i.jsx)(n.code,{children:"rsync"}),". This step allows moving the node with nearly zero rewards loss."]}),"\n",(0,i.jsxs)(n.li,{children:["Stop the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"backup_node"}),", now the new validator."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"current_node"}),", now the new backup."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"preparation-for-swapping",children:"Preparation for swapping"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Prepare to swap keys by following these steps:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create the following folder structure on both nodes under the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/"})," directory."]}),"\n",(0,i.jsxs)(n.li,{children:["Create subdirectories for the ",(0,i.jsx)(n.code,{children:"current_node"})," and ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Copy each node's keyset under the corresponding directories."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" /etc/casper/validator_keys/\n \u251c\u2500\u2500 public_key.pem\n \u251c\u2500\u2500 public_key_hex\n \u251c\u2500\u2500 secret_key.pem\n \u251c\u2500\u2500 current_node\n \u2502 \u251c\u2500\u2500 public_key.pem\n \u2502 \u251c\u2500\u2500 public_key_hex\n \u2502 \u2514\u2500\u2500 secret_key.pem\n \u2514\u2500\u2500 backup_node\n | \u251c\u2500\u2500 public_key.pem\n | \u251c\u2500\u2500 public_key_hex\n | \u2514\u2500\u2500 secret_key.pem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This setup allows key swapping by running the ",(0,i.jsx)(n.code,{children:"sudo -u casper cp * ../"})," command, as shown below."]}),"\n",(0,i.jsx)(n.h3,{id:"swapping-the-nodes",children:"Swapping the nodes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"})," (the future validator), use ",(0,i.jsx)(n.code,{children:"rsync"})," to move the unit files from the ",(0,i.jsx)(n.code,{children:"current_node"}),", located in ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"}),", run these commands to stop the node, swap keys, and restart the node:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/current_node\nsudo -u casper cp * ../\nsudo systemctl start casper-node-launcher\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"current_node"}),", run these commands to stop the node and swap keys:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/backup_node\nsudo -u casper cp * ../\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Restart the original validator node (",(0,i.jsx)(n.code,{children:"current_node"}),"), which is now the new backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher \n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"understanding-rewards-impact",children:"Understanding rewards impact"}),"\n",(0,i.jsx)(n.p,{children:"After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"You could time the swap right before the era ends to minimize reward losses."})}),"\n",(0,i.jsx)(n.h3,{id:"checking-file-permissions",children:"Checking file permissions"}),"\n",(0,i.jsxs)(n.p,{children:["After the swap, check and fix file permissions by running the ",(0,i.jsx)(n.code,{children:"/etc/casper/node_util.py"})," utility."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/168da062.f79ac659.js b/assets/js/168da062.f79ac659.js deleted file mode 100644 index 2acae9f16..000000000 --- a/assets/js/168da062.f79ac659.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6365],{26962:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={title:"Move a Node"},o="Moving a Validating Node",d={id:"operators/maintenance/moving-node",title:"Move a Node",description:"This guide is for active validators who want to move their node to another machine.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/moving-node.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/moving-node",permalink:"/operators/maintenance/moving-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Move a Node"},sidebar:"operators",previous:{title:"Archive and Restore a DB",permalink:"/operators/maintenance/archiving-and-restoring"}},a={},c=[{value:"Swapping Keys with a Hot Backup",id:"swapping-keys-with-a-hot-backup",level:2},{value:"Preparation for swapping",id:"preparation-for-swapping",level:3},{value:"Swapping the nodes",id:"swapping-the-nodes",level:3},{value:"Understanding rewards impact",id:"understanding-rewards-impact",level:3},{value:"Checking file permissions",id:"checking-file-permissions",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"moving-a-validating-node",children:"Moving a Validating Node"})}),"\n",(0,i.jsx)(n.p,{children:"This guide is for active validators who want to move their node to another machine."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"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."})}),"\n",(0,i.jsx)(n.h2,{id:"swapping-keys-with-a-hot-backup",children:"Swapping Keys with a Hot Backup"}),"\n",(0,i.jsx)(n.p,{children:"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."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Once a node is running (",(0,i.jsx)(n.code,{children:"current_node"}),"), create a second node (",(0,i.jsx)(n.code,{children:"backup_node"}),") on another machine. These two nodes will run in parallel."]}),"\n",(0,i.jsxs)(n.li,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Move the unit files at the DB level using ",(0,i.jsx)(n.code,{children:"rsync"}),". This step allows moving the node with nearly zero rewards loss."]}),"\n",(0,i.jsxs)(n.li,{children:["Stop the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"backup_node"}),", now the new validator."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"current_node"}),", now the new backup."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"preparation-for-swapping",children:"Preparation for swapping"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Prepare to swap keys by following these steps:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create the following folder structure on both nodes under the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/"})," directory."]}),"\n",(0,i.jsxs)(n.li,{children:["Create subdirectories for the ",(0,i.jsx)(n.code,{children:"current_node"})," and ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Copy each node's keyset under the corresponding directories."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" /etc/casper/validator_keys/\n \u251c\u2500\u2500 public_key.pem\n \u251c\u2500\u2500 public_key_hex\n \u251c\u2500\u2500 secret_key.pem\n \u251c\u2500\u2500 current_node\n \u2502 \u251c\u2500\u2500 public_key.pem\n \u2502 \u251c\u2500\u2500 public_key_hex\n \u2502 \u2514\u2500\u2500 secret_key.pem\n \u2514\u2500\u2500 backup_node\n | \u251c\u2500\u2500 public_key.pem\n | \u251c\u2500\u2500 public_key_hex\n | \u2514\u2500\u2500 secret_key.pem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This setup allows key swapping by running the ",(0,i.jsx)(n.code,{children:"sudo -u casper cp * ../"})," command, as shown below."]}),"\n",(0,i.jsx)(n.h3,{id:"swapping-the-nodes",children:"Swapping the nodes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"})," (the future validator), use ",(0,i.jsx)(n.code,{children:"rsync"})," to move the unit files from the ",(0,i.jsx)(n.code,{children:"current_node"}),", located in ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"}),", run these commands to stop the node, swap keys, and restart the node:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/current_node\nsudo -u casper cp * ../\nsudo systemctl start casper-node-launcher\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"current_node"}),", run these commands to stop the node and swap keys:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/backup_node\nsudo -u casper cp * ../\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Restart the original validator node (",(0,i.jsx)(n.code,{children:"current_node"}),"), which is now the new backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher \n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"understanding-rewards-impact",children:"Understanding rewards impact"}),"\n",(0,i.jsx)(n.p,{children:"After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"You could time the swap right before the era ends to minimize reward losses."})}),"\n",(0,i.jsx)(n.h3,{id:"checking-file-permissions",children:"Checking file permissions"}),"\n",(0,i.jsxs)(n.p,{children:["After the swap, check and fix file permissions by running the ",(0,i.jsx)(n.code,{children:"/etc/casper/node_util.py"})," utility."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/175e85c1.ae48dd54.js b/assets/js/175e85c1.ae48dd54.js new file mode 100644 index 000000000..78de77f10 --- /dev/null +++ b/assets/js/175e85c1.ae48dd54.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80724],{91335:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=n(74848),s=n(28453);const r={title:"Delegate Tokens",slug:"/users/delegate-ui"},o="Delegating Tokens with a Block Explorer",a={id:"users/csprlive/delegate-ui",title:"Delegate Tokens",description:"Introduction",source:"@site/versioned_docs/version-2.0.0/users/csprlive/delegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/delegate-ui",permalink:"/2.0.0/users/delegate-ui",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Delegate Tokens",slug:"/users/delegate-ui"},sidebar:"users",previous:{title:"Testnet Funding",permalink:"/2.0.0/users/testnet-faucet"},next:{title:"Undelegate Tokens",permalink:"/2.0.0/users/undelegate-ui"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Reviewing your Account",id:"account-review",level:3},{value:"Accessing the Delegation Feature",id:"delegation-access",level:2},{value:"Stepping through the Delegation Process",id:"stepping-through-the-delegation-process",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-tokens-with-a-block-explorer",children:"Delegating Tokens with a Block Explorer"})}),"\n",(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"This tutorial covers how to delegate Casper tokens to a validator on the network."}),"\n",(0,i.jsxs)(t.p,{children:["Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called ",(0,i.jsx)(t.strong,{children:"delegation"})," or ",(0,i.jsx)(t.strong,{children:"staking"}),". We will use these terms interchangeably in this guide. See the ",(0,i.jsx)(t.a,{href:"/2.0.0/concepts/economics/staking",children:"Staking Key Concepts"})," page for more details about the differences."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})," by following the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide."]}),"\n",(0,i.jsxs)(t.li,{children:["You need to ",(0,i.jsx)(t.a,{href:"/2.0.0/users/funding-from-exchanges",children:"fund the account's main purse"})," to delegate tokens."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect to a block explorer to set up the delegation. This guide uses ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," and the Casper Wallet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"#account-review",children:"Review your account"})," before starting the process."]}),"\n",(0,i.jsxs)(t.li,{children:["Review the current ",(0,i.jsx)(t.a,{href:"/2.0.0/users/delegating#delegation-cost",children:"delegation cost"})," and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"account-review",children:"Reviewing your Account"}),"\n",(0,i.jsx)(t.p,{children:"Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Liquid Account Balance"}),", representing the tokens you have for immediate use"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegated Account Balance"}),", representing the delegated tokens already staked with validators on the network"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegations"})," tab, listing the validators to whom you have delegated tokens"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and delegations details",src:n(32847).A+"",width:"2420",height:"1456"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Staking Rewards"})," tab, showing the rewards received in each era"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and rewards",src:n(40247).A+"",width:"2422",height:"1592"})}),"\n",(0,i.jsx)(t.h2,{id:"delegation-access",children:"Accessing the Delegation Feature"}),"\n",(0,i.jsx)(t.p,{children:"You can access the delegation functionality in two ways."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,i.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,i.jsx)(t.strong,{children:"Delegate"}),". In the next screen, you will need to specify the validator's public key or search for a validator."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from the Wallet",src:n(53537).A+"",width:"252",height:"333"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,i.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the ",(0,i.jsx)(t.strong,{children:"Delegate"})," button. The next screen will have the validator's public key pre-populated."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from a Validator",src:n(98183).A+"",width:"2304",height:"822"})}),"\n",(0,i.jsx)(t.h2,{id:"stepping-through-the-delegation-process",children:"Stepping through the Delegation Process"}),"\n",(0,i.jsx)(t.p,{children:'The following instructions will take you through the delegation process, starting with the "Delegation details" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 1 - Delegation details"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,i.jsx)(t.li,{children:"Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee."}),"\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegation details",src:n(52499).A+"",width:"1174",height:"1402"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 2 - Confirm the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Review the delegation details."}),"\n",(0,i.jsxs)(t.li,{children:["If everything is correct, click ",(0,i.jsx)(t.strong,{children:"Confirm and delegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confirm delegation details",src:n(23816).A+"",width:"1218",height:"1562"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 3 - Sign the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Sign the delegation by clicking ",(0,i.jsx)(t.strong,{children:"Sign with Casper Wallet"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Sign delegation",src:n(25942).A+"",width:"1198",height:"1754"})}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,i.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Signature Request window",src:n(63817).A+"",width:"2098",height:"1730"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the delegation."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Completed delegation",src:n(82299).A+"",width:"1238",height:"1442"})}),"\n",(0,i.jsxs)(t.p,{children:["The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the ",(0,i.jsx)(t.strong,{children:"Deploy Details"})," highlighted above."]}),"\n",(0,i.jsxs)(t.p,{children:["Remember to ",(0,i.jsx)(t.a,{href:"/2.0.0/users/delegating#monitoring-rewards",children:"Monitor your Stake"}),". Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the ",(0,i.jsx)(t.em,{children:"Rewards"})," tab on your account page on ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If you want to undelegate your tokens, you can do so at any time. See the ",(0,i.jsx)(t.a,{href:"/2.0.0/users/undelegate-ui",children:"Undelegation Guide"})," for details."]}),"\n",(0,i.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,i.jsx)(t.p,{children:"This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step."}),"\n",(0,i.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed/cR3v8AthlkQ",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},82299:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/10.completed-delegation-0ac5b9f9f8652f84699d6399327e2fdf.png"},32847:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/2.delegations-9003a8fe3ea1027b5c2979309d3fea8f.png"},40247:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/3.rewards-115f13a27134c16ee910cfbe03007772.png"},53537:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/4.wallet-delegate-5e55bb39f50718c18135516a3b2cc300.png"},98183:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/5.validator-delegate-0b1707fc714ad98ffe9c51589da77d80.png"},52499:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/6.delegation-details-c24d81971b747b1a9690bbd19326491d.png"},23816:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/7.confirm-delegation-1f04705b09036ea673b306ef2d1792a7.png"},25942:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/8.sign-delegation-4cd652c44f821f2db9c825b07f7c1ba2.png"},63817:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/9.wallet-window-f16c8950d24a74274d9dd6e3aa39c62e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/17896441.a80fb57c.js b/assets/js/17896441.a80fb57c.js new file mode 100644 index 000000000..76d2f1c2a --- /dev/null +++ b/assets/js/17896441.a80fb57c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18401],{32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,i.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(r,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var s=n(34164),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Yh,{}),className:(0,s.A)(t,i.G.common.draftBanner),children:(0,l.jsx)(a.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:s}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||s.unlisted)&&(0,l.jsx)(c.A,{}),s.draft&&(0,l.jsx)(r,{})]})}},30575:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ae});var s=n(96540),a=n(45500),i=n(89532),o=n(74848);const l=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(l.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(34164),m=n(24581),h=n(21312),v=n(39022);function b(e){const{previous:t,next:n}=e;return(0,o.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,o.jsx)(v.A,{...t,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,o.jsx)(v.A,{...n,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,o.jsx)(b,{previous:e.previous,next:e.next})}var f=n(44586),p=n(28774),g=n(44070),j=n(17559),A=n(53886),L=n(23025);const C={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function N(e){const t=C[e.versionMetadata.banner];return(0,o.jsx)(t,{...e})}function _(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,o.jsx)("b",{children:(0,o.jsx)(p.A,{to:n,onClick:s,children:(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function T(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:s}}=(0,f.A)(),{pluginId:a}=(0,g.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,A.g1)(a),{latestDocSuggestion:l,latestVersionSuggestion:r}=(0,g.HW)(a),c=l??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,o.jsxs)("div",{className:(0,u.A)(t,j.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,o.jsx)("div",{children:(0,o.jsx)(N,{siteTitle:s,versionMetadata:n})}),(0,o.jsx)("div",{className:"margin-top--md",children:(0,o.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function k(e){let{className:t}=e;const n=(0,L.r)();return n.banner?(0,o.jsx)(T,{className:t,versionMetadata:n}):null}function H(e){let{className:t}=e;const n=(0,L.r)();return n.badge?(0,o.jsx)("span",{className:(0,u.A)(t,j.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(h.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}var M=n(62053),y=n(4336);function B(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(t||n||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(j.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",j.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(M.A,{tags:a})})}),l&&(0,o.jsx)(y.A,{className:(0,u.A)("margin-top--sm",j.G.docs.docFooterEditMetaRow),editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s})]}):null}var I=n(41422),w=n(65195);const E={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function V(e){let{collapsed:t,...n}=e;return(0,o.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",E.tocCollapsibleButton,!t&&E.tocCollapsibleButtonExpanded,n.className),children:(0,o.jsx)(h.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const O={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,I.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(O.tocCollapsible,!i&&O.tocCollapsibleExpanded,n),children:[(0,o.jsx)(V,{collapsed:i,onClick:l}),(0,o.jsx)(I.N,{lazy:!0,className:O.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(w.A,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const S={tocMobile:"tocMobile_ITEo"};function P(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(G,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.A)(j.G.docs.docTocMobile,S.tocMobile)})}var R=n(67763);function U(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(R.A,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:j.G.docs.docTocDesktop})}var F=n(51107),D=n(88509);function z(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(j.G.docs.docMarkdown,"markdown"),children:[n&&(0,o.jsx)("header",{children:(0,o.jsx)(F.A,{as:"h1",children:n})}),(0,o.jsx)(D.A,{children:t})]})}var q=n(26972),Y=n(99169),$=n(86025);function W(e){return(0,o.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,o.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const Z={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function J(){const e=(0,$.Ay)("/");return(0,o.jsx)("li",{className:"breadcrumbs__item",children:(0,o.jsx)(p.A,{"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,o.jsx)(W,{className:Z.breadcrumbHomeIcon})})})}const K={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function Q(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,o.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,o.jsx)(p.A,{className:a,href:n,itemProp:"item",children:(0,o.jsx)("span",{itemProp:"name",children:t})}):(0,o.jsx)("span",{className:a,children:t})}function X(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,o.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,o.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function ee(){const e=(0,q.OF)(),t=(0,Y.Dt)();return e?(0,o.jsx)("nav",{className:(0,u.A)(j.G.docs.docBreadcrumbs,K.breadcrumbsContainer),"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,o.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,o.jsx)(J,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,o.jsx)(X,{active:s,index:n,addMicrodata:!!a,children:(0,o.jsx)(Q,{href:a,isLast:s,children:t.label})},n)}))]})}):null}var te=n(41689);const ne={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function se(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,o.jsx)(P,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,o.jsx)(U,{})}}(),{metadata:s}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&ne.docItemCol),children:[(0,o.jsx)(te.A,{metadata:s}),(0,o.jsx)(k,{}),(0,o.jsxs)("div",{className:ne.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(ee,{}),(0,o.jsx)(H,{}),n.mobile,(0,o.jsx)(z,{children:t}),(0,o.jsx)(B,{})]}),(0,o.jsx)(x,{})]})]}),n.desktop&&(0,o.jsx)("div",{className:"col col--3",children:n.desktop})]})}function ae(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:t,children:[(0,o.jsx)(d,{}),(0,o.jsx)(se,{children:(0,o.jsx)(n,{})})]})})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(65195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=n(74848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",t),children:(0,o.jsx)(a.A,{...n,linkClassName:l,linkActiveClassName:r})})}},65195:(e,t,n)=>{n.d(t,{A:()=>b});var s=n(96540),a=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>l(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(s))?s:e[e.indexOf(s)-1]??null}return e[e.length-1]??null}function c(){const e=(0,s.useRef)(0),{navbar:{hideOnScroll:t}}=(0,a.p)();return(0,s.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var u=n(28774),m=n(74848);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const v=s.memo(h);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const b=(0,a.p)(),x=c??b.tableOfContents.minHeadingLevel,f=u??b.tableOfContents.maxHeadingLevel,p=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(v,{toc:p,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>r,Rc:()=>o,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),i=n(74848);function o(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/17896441.e301f0ef.js b/assets/js/17896441.e301f0ef.js deleted file mode 100644 index 2463f5779..000000000 --- a/assets/js/17896441.e301f0ef.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8401],{32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,i.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(r,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var s=n(34164),a=n(44084),i=n(17559),o=n(27293),l=n(74848);function r(e){let{className:t}=e;return(0,l.jsx)(o.A,{type:"caution",title:(0,l.jsx)(a.Yh,{}),className:(0,s.A)(t,i.G.common.draftBanner),children:(0,l.jsx)(a.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:s}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||s.unlisted)&&(0,l.jsx)(c.A,{}),s.draft&&(0,l.jsx)(r,{})]})}},30575:(e,t,n)=>{n.r(t),n.d(t,{default:()=>ae});var s=n(96540),a=n(45500),i=n(89532),o=n(74848);const l=s.createContext(null);function r(e){let{children:t,content:n}=e;const a=function(e){return(0,s.useMemo)((()=>({metadata:e.metadata,frontMatter:e.frontMatter,assets:e.assets,contentTitle:e.contentTitle,toc:e.toc})),[e])}(n);return(0,o.jsx)(l.Provider,{value:a,children:t})}function c(){const e=(0,s.useContext)(l);if(null===e)throw new i.dV("DocProvider");return e}function d(){const{metadata:e,frontMatter:t,assets:n}=c();return(0,o.jsx)(a.be,{title:e.title,description:e.description,keywords:t.keywords,image:n.image??t.image})}var u=n(34164),m=n(24581),h=n(21312),v=n(39022);function b(e){const{previous:t,next:n}=e;return(0,o.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,h.T)({id:"theme.docs.paginator.navAriaLabel",message:"Docs pages",description:"The ARIA label for the docs pagination"}),children:[t&&(0,o.jsx)(v.A,{...t,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.previous",description:"The label used to navigate to the previous doc",children:"Previous"})}),n&&(0,o.jsx)(v.A,{...n,subLabel:(0,o.jsx)(h.A,{id:"theme.docs.paginator.next",description:"The label used to navigate to the next doc",children:"Next"}),isNext:!0})]})}function x(){const{metadata:e}=c();return(0,o.jsx)(b,{previous:e.previous,next:e.next})}var f=n(44586),p=n(28774),g=n(44070),j=n(17559),A=n(53886),L=n(23025);const C={unreleased:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unreleasedVersionLabel",description:"The label used to tell the user that he's browsing an unreleased doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is unreleased documentation for {siteTitle} {versionLabel} version."})},unmaintained:function(e){let{siteTitle:t,versionMetadata:n}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.unmaintainedVersionLabel",description:"The label used to tell the user that he's browsing an unmaintained doc version",values:{siteTitle:t,versionLabel:(0,o.jsx)("b",{children:n.label})},children:"This is documentation for {siteTitle} {versionLabel}, which is no longer actively maintained."})}};function N(e){const t=C[e.versionMetadata.banner];return(0,o.jsx)(t,{...e})}function _(e){let{versionLabel:t,to:n,onClick:s}=e;return(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionSuggestionLabel",description:"The label used to tell the user to check the latest version",values:{versionLabel:t,latestVersionLink:(0,o.jsx)("b",{children:(0,o.jsx)(p.A,{to:n,onClick:s,children:(0,o.jsx)(h.A,{id:"theme.docs.versions.latestVersionLinkLabel",description:"The label used for the latest version suggestion link label",children:"latest version"})})})},children:"For up-to-date documentation, see the {latestVersionLink} ({versionLabel})."})}function T(e){let{className:t,versionMetadata:n}=e;const{siteConfig:{title:s}}=(0,f.A)(),{pluginId:a}=(0,g.vT)({failfast:!0}),{savePreferredVersionName:i}=(0,A.g1)(a),{latestDocSuggestion:l,latestVersionSuggestion:r}=(0,g.HW)(a),c=l??(d=r).docs.find((e=>e.id===d.mainDocId));var d;return(0,o.jsxs)("div",{className:(0,u.A)(t,j.G.docs.docVersionBanner,"alert alert--warning margin-bottom--md"),role:"alert",children:[(0,o.jsx)("div",{children:(0,o.jsx)(N,{siteTitle:s,versionMetadata:n})}),(0,o.jsx)("div",{className:"margin-top--md",children:(0,o.jsx)(_,{versionLabel:r.label,to:c.path,onClick:()=>i(r.name)})})]})}function k(e){let{className:t}=e;const n=(0,L.r)();return n.banner?(0,o.jsx)(T,{className:t,versionMetadata:n}):null}function H(e){let{className:t}=e;const n=(0,L.r)();return n.badge?(0,o.jsx)("span",{className:(0,u.A)(t,j.G.docs.docVersionBadge,"badge badge--secondary"),children:(0,o.jsx)(h.A,{id:"theme.docs.versionBadge.label",values:{versionLabel:n.label},children:"Version: {versionLabel}"})}):null}var M=n(62053),y=n(4336);function B(){const{metadata:e}=c(),{editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s,tags:a}=e,i=a.length>0,l=!!(t||n||s);return i||l?(0,o.jsxs)("footer",{className:(0,u.A)(j.G.docs.docFooter,"docusaurus-mt-lg"),children:[i&&(0,o.jsx)("div",{className:(0,u.A)("row margin-top--sm",j.G.docs.docFooterTagsRow),children:(0,o.jsx)("div",{className:"col",children:(0,o.jsx)(M.A,{tags:a})})}),l&&(0,o.jsx)(y.A,{className:(0,u.A)("margin-top--sm",j.G.docs.docFooterEditMetaRow),editUrl:t,lastUpdatedAt:n,lastUpdatedBy:s})]}):null}var I=n(41422),w=n(65195);const E={tocCollapsibleButton:"tocCollapsibleButton_TO0P",tocCollapsibleButtonExpanded:"tocCollapsibleButtonExpanded_MG3E"};function V(e){let{collapsed:t,...n}=e;return(0,o.jsx)("button",{type:"button",...n,className:(0,u.A)("clean-btn",E.tocCollapsibleButton,!t&&E.tocCollapsibleButtonExpanded,n.className),children:(0,o.jsx)(h.A,{id:"theme.TOCCollapsible.toggleButtonLabel",description:"The label used by the button on the collapsible TOC component",children:"On this page"})})}const O={tocCollapsible:"tocCollapsible_ETCw",tocCollapsibleContent:"tocCollapsibleContent_vkbj",tocCollapsibleExpanded:"tocCollapsibleExpanded_sAul"};function G(e){let{toc:t,className:n,minHeadingLevel:s,maxHeadingLevel:a}=e;const{collapsed:i,toggleCollapsed:l}=(0,I.u)({initialState:!0});return(0,o.jsxs)("div",{className:(0,u.A)(O.tocCollapsible,!i&&O.tocCollapsibleExpanded,n),children:[(0,o.jsx)(V,{collapsed:i,onClick:l}),(0,o.jsx)(I.N,{lazy:!0,className:O.tocCollapsibleContent,collapsed:i,children:(0,o.jsx)(w.A,{toc:t,minHeadingLevel:s,maxHeadingLevel:a})})]})}const S={tocMobile:"tocMobile_ITEo"};function P(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(G,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:(0,u.A)(j.G.docs.docTocMobile,S.tocMobile)})}var R=n(67763);function U(){const{toc:e,frontMatter:t}=c();return(0,o.jsx)(R.A,{toc:e,minHeadingLevel:t.toc_min_heading_level,maxHeadingLevel:t.toc_max_heading_level,className:j.G.docs.docTocDesktop})}var F=n(51107),D=n(88509);function z(e){let{children:t}=e;const n=function(){const{metadata:e,frontMatter:t,contentTitle:n}=c();return t.hide_title||void 0!==n?null:e.title}();return(0,o.jsxs)("div",{className:(0,u.A)(j.G.docs.docMarkdown,"markdown"),children:[n&&(0,o.jsx)("header",{children:(0,o.jsx)(F.A,{as:"h1",children:n})}),(0,o.jsx)(D.A,{children:t})]})}var q=n(26972),Y=n(99169),$=n(86025);function W(e){return(0,o.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,o.jsx)("path",{d:"M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z",fill:"currentColor"})})}const Z={breadcrumbHomeIcon:"breadcrumbHomeIcon_YNFT"};function J(){const e=(0,$.Ay)("/");return(0,o.jsx)("li",{className:"breadcrumbs__item",children:(0,o.jsx)(p.A,{"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.home",message:"Home page",description:"The ARIA label for the home page in the breadcrumbs"}),className:"breadcrumbs__link",href:e,children:(0,o.jsx)(W,{className:Z.breadcrumbHomeIcon})})})}const K={breadcrumbsContainer:"breadcrumbsContainer_Z_bl"};function Q(e){let{children:t,href:n,isLast:s}=e;const a="breadcrumbs__link";return s?(0,o.jsx)("span",{className:a,itemProp:"name",children:t}):n?(0,o.jsx)(p.A,{className:a,href:n,itemProp:"item",children:(0,o.jsx)("span",{itemProp:"name",children:t})}):(0,o.jsx)("span",{className:a,children:t})}function X(e){let{children:t,active:n,index:s,addMicrodata:a}=e;return(0,o.jsxs)("li",{...a&&{itemScope:!0,itemProp:"itemListElement",itemType:"https://schema.org/ListItem"},className:(0,u.A)("breadcrumbs__item",{"breadcrumbs__item--active":n}),children:[t,(0,o.jsx)("meta",{itemProp:"position",content:String(s+1)})]})}function ee(){const e=(0,q.OF)(),t=(0,Y.Dt)();return e?(0,o.jsx)("nav",{className:(0,u.A)(j.G.docs.docBreadcrumbs,K.breadcrumbsContainer),"aria-label":(0,h.T)({id:"theme.docs.breadcrumbs.navAriaLabel",message:"Breadcrumbs",description:"The ARIA label for the breadcrumbs"}),children:(0,o.jsxs)("ul",{className:"breadcrumbs",itemScope:!0,itemType:"https://schema.org/BreadcrumbList",children:[t&&(0,o.jsx)(J,{}),e.map(((t,n)=>{const s=n===e.length-1,a="category"===t.type&&t.linkUnlisted?void 0:t.href;return(0,o.jsx)(X,{active:s,index:n,addMicrodata:!!a,children:(0,o.jsx)(Q,{href:a,isLast:s,children:t.label})},n)}))]})}):null}var te=n(41689);const ne={docItemContainer:"docItemContainer_Djhp",docItemCol:"docItemCol_VOVn"};function se(e){let{children:t}=e;const n=function(){const{frontMatter:e,toc:t}=c(),n=(0,m.l)(),s=e.hide_table_of_contents,a=!s&&t.length>0;return{hidden:s,mobile:a?(0,o.jsx)(P,{}):void 0,desktop:!a||"desktop"!==n&&"ssr"!==n?void 0:(0,o.jsx)(U,{})}}(),{metadata:s}=c();return(0,o.jsxs)("div",{className:"row",children:[(0,o.jsxs)("div",{className:(0,u.A)("col",!n.hidden&&ne.docItemCol),children:[(0,o.jsx)(te.A,{metadata:s}),(0,o.jsx)(k,{}),(0,o.jsxs)("div",{className:ne.docItemContainer,children:[(0,o.jsxs)("article",{children:[(0,o.jsx)(ee,{}),(0,o.jsx)(H,{}),n.mobile,(0,o.jsx)(z,{children:t}),(0,o.jsx)(B,{})]}),(0,o.jsx)(x,{})]})]}),n.desktop&&(0,o.jsx)("div",{className:"col col--3",children:n.desktop})]})}function ae(e){const t=`docs-doc-id-${e.content.metadata.id}`,n=e.content;return(0,o.jsx)(r,{content:e.content,children:(0,o.jsxs)(a.e3,{className:t,children:[(0,o.jsx)(d,{}),(0,o.jsx)(se,{children:(0,o.jsx)(n,{})})]})})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(65195);const i={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var o=n(74848);const l="table-of-contents__link toc-highlight",r="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,o.jsx)("div",{className:(0,s.A)(i.tableOfContents,"thin-scrollbar",t),children:(0,o.jsx)(a.A,{...n,linkClassName:l,linkActiveClassName:r})})}},65195:(e,t,n)=>{n.d(t,{A:()=>b});var s=n(96540),a=n(6342);function i(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const s=n.slice(2,e.level);e.parentIndex=Math.max(...s),n[e.level]=t}));const s=[];return t.forEach((e=>{const{parentIndex:n,...a}=e;n>=0?t[n].children.push(a):s.push(a)})),s}function o(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return t.flatMap((e=>{const t=o({toc:e.children,minHeadingLevel:n,maxHeadingLevel:s});return function(e){return e.level>=n&&e.level<=s}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function r(e,t){let{anchorTopOffset:n}=t;const s=e.find((e=>l(e).top>=n));if(s){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(s))?s:e[e.indexOf(s)-1]??null}return e[e.length-1]??null}function c(){const e=(0,s.useRef)(0),{navbar:{hideOnScroll:t}}=(0,a.p)();return(0,s.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,s.useRef)(void 0),n=c();(0,s.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:s,linkActiveClassName:a,minHeadingLevel:i,maxHeadingLevel:o}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(s),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const s=[];for(let a=t;a<=n;a+=1)s.push(`h${a}.anchor`);return Array.from(document.querySelectorAll(s.join()))}({minHeadingLevel:i,maxHeadingLevel:o}),c=r(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(a),e.classList.add(a),t.current=e):e.classList.remove(a)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var u=n(28774),m=n(74848);function h(e){let{toc:t,className:n,linkClassName:s,isChild:a}=e;return t.length?(0,m.jsx)("ul",{className:a?void 0:n,children:t.map((e=>(0,m.jsxs)("li",{children:[(0,m.jsx)(u.A,{to:`#${e.id}`,className:s??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,m.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:s})]},e.id)))}):null}const v=s.memo(h);function b(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:r,minHeadingLevel:c,maxHeadingLevel:u,...h}=e;const b=(0,a.p)(),x=c??b.tableOfContents.minHeadingLevel,f=u??b.tableOfContents.maxHeadingLevel,p=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return(0,s.useMemo)((()=>o({toc:i(t),minHeadingLevel:n,maxHeadingLevel:a})),[t,n,a])}({toc:t,minHeadingLevel:x,maxHeadingLevel:f});return d((0,s.useMemo)((()=>{if(l&&r)return{linkClassName:l,linkActiveClassName:r,minHeadingLevel:x,maxHeadingLevel:f}}),[l,r,x,f])),(0,m.jsx)(v,{toc:p,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>r,Rc:()=>o,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),i=n(74848);function o(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function r(){return(0,i.jsx)(a.A,{children:(0,i.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,i.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/1871ac35.4fb85a4c.js b/assets/js/1871ac35.4fb85a4c.js new file mode 100644 index 000000000..418dc7c43 --- /dev/null +++ b/assets/js/1871ac35.4fb85a4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57356],{61594:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>o});var r=t(74848),s=t(28453);const d={slug:"/resources/tokens/"},i="Casper Token Standards",c={id:"resources/tokens/index",title:"Casper Token Standards",description:"CEP-18 Casper Fungible Token Standard",source:"@site/versioned_docs/version-1.5.X/resources/tokens/index.md",sourceDirName:"resources/tokens",slug:"/resources/tokens/",permalink:"/1.5.X/resources/tokens/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tokens/"},sidebar:"resources",previous:{title:"Move to Casper",permalink:"/1.5.X/resources/moving-to-casper"},next:{title:"Fungible Token Workflow",permalink:"/1.5.X/resources/tokens/cep18/full-tutorial"}},a={},o=[{value:"CEP-18 Casper Fungible Token Standard",id:"cep-18-casper-fungible-token-standard",level:2},{value:"CEP-78 Enhanced NFT Standard",id:"cep-78-enhanced-nft-standard",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"casper-token-standards",children:"Casper Token Standards"})}),"\n",(0,r.jsx)(n.h2,{id:"cep-18-casper-fungible-token-standard",children:"CEP-18 Casper Fungible Token Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/full-tutorial",children:"A Casper Fungible Token Tutorial"})}),(0,r.jsx)(n.td,{children:"A full tutorial for use of the CEP-18 Casper Fungible Token Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/quickstart-guide",children:"Installing and Interacting with a CEP-18 Contract"})}),(0,r.jsx)(n.td,{children:"A quickstart guide for installing a CEP-18 contract with the Rust Casper Client."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/query",children:"Exploring the CEP-18 Contracts"})}),(0,r.jsx)(n.td,{children:"A guide to interacting with installed CEP-18 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),(0,r.jsx)(n.td,{children:"A guide for transferring Casper Fungible Tokens."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),(0,r.jsx)(n.td,{children:"A CEP-18 testing framework using the Casper engine test support crate."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"cep-78-enhanced-nft-standard",children:"CEP-78 Enhanced NFT Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),(0,r.jsx)(n.td,{children:"An introduction to the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/introduction",children:"CEP-78 Modalities"})}),(0,r.jsx)(n.td,{children:"Information on the features available when installing a CEP-78 contract instance."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Installing and Interacting with a CEP-78 Contract"})}),(0,r.jsx)(n.td,{children:"An introduction to features present in the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/reverse-lookup",children:"Owner Reverse Lookup Functionality"})}),(0,r.jsx)(n.td,{children:"Information on the Onwer Reverse Lookup feature of CEP-78 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/js-tutorial",children:"A CEP-78 JavaScript Client Tutorial"})}),(0,r.jsx)(n.td,{children:"A tutorial for using the JavaScript CEP-78 client."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var r=t(96540);const s={},d=r.createContext(s);function i(e){const n=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1871ac35.c8a05ff4.js b/assets/js/1871ac35.c8a05ff4.js deleted file mode 100644 index 984ef5160..000000000 --- a/assets/js/1871ac35.c8a05ff4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7356],{61594:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>o});var r=t(74848),s=t(28453);const d={slug:"/resources/tokens/"},i="Casper Token Standards",c={id:"resources/tokens/index",title:"Casper Token Standards",description:"CEP-18 Casper Fungible Token Standard",source:"@site/versioned_docs/version-1.5.X/resources/tokens/index.md",sourceDirName:"resources/tokens",slug:"/resources/tokens/",permalink:"/resources/tokens/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tokens/"},sidebar:"resources",previous:{title:"Move to Casper",permalink:"/resources/moving-to-casper"},next:{title:"Fungible Token Workflow",permalink:"/resources/tokens/cep18/full-tutorial"}},a={},o=[{value:"CEP-18 Casper Fungible Token Standard",id:"cep-18-casper-fungible-token-standard",level:2},{value:"CEP-78 Enhanced NFT Standard",id:"cep-78-enhanced-nft-standard",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"casper-token-standards",children:"Casper Token Standards"})}),"\n",(0,r.jsx)(n.h2,{id:"cep-18-casper-fungible-token-standard",children:"CEP-18 Casper Fungible Token Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/full-tutorial",children:"A Casper Fungible Token Tutorial"})}),(0,r.jsx)(n.td,{children:"A full tutorial for use of the CEP-18 Casper Fungible Token Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/quickstart-guide",children:"Installing and Interacting with a CEP-18 Contract"})}),(0,r.jsx)(n.td,{children:"A quickstart guide for installing a CEP-18 contract with the Rust Casper Client."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP-18 Contracts"})}),(0,r.jsx)(n.td,{children:"A guide to interacting with installed CEP-18 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),(0,r.jsx)(n.td,{children:"A guide for transferring Casper Fungible Tokens."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),(0,r.jsx)(n.td,{children:"A CEP-18 testing framework using the Casper engine test support crate."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"cep-78-enhanced-nft-standard",children:"CEP-78 Enhanced NFT Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),(0,r.jsx)(n.td,{children:"An introduction to the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/introduction",children:"CEP-78 Modalities"})}),(0,r.jsx)(n.td,{children:"Information on the features available when installing a CEP-78 contract instance."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Installing and Interacting with a CEP-78 Contract"})}),(0,r.jsx)(n.td,{children:"An introduction to features present in the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"Owner Reverse Lookup Functionality"})}),(0,r.jsx)(n.td,{children:"Information on the Onwer Reverse Lookup feature of CEP-78 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tokens/cep78/js-tutorial",children:"A CEP-78 JavaScript Client Tutorial"})}),(0,r.jsx)(n.td,{children:"A tutorial for using the JavaScript CEP-78 client."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var r=t(96540);const s={},d=r.createContext(s);function i(e){const n=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/18b84202.39914aaa.js b/assets/js/18b84202.39914aaa.js new file mode 100644 index 000000000..95fa55166 --- /dev/null +++ b/assets/js/18b84202.39914aaa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53462],{30047:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Getting Started with Rust"},a="Getting Started with Rust Casper Contracts",o={id:"developers/writing-onchain-code/getting-started",title:"Getting Started with Rust",description:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/getting-started.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/getting-started",permalink:"/2.0.0/developers/writing-onchain-code/getting-started",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Getting Started with Rust"},sidebar:"developers",previous:{title:"Introduction",permalink:"/2.0.0/writing-contracts"},next:{title:"Getting Started with AssemblyScript",permalink:"/2.0.0/developers/writing-onchain-code/assembly-script"}},c={},l=[{value:"Creating a Project",id:"creating-a-project",level:2},{value:"Reproducibility",id:"reproducibility",level:3},{value:"Using the nightly toolchain",id:"using-the-nightly-toolchain",level:3},{value:"Available Casper Rust crates",id:"available-casper-rust-crates",level:3},{value:"Available API documentation",id:"available-api-documentation",level:3},{value:"Compiling to Wasm",id:"compiling-to-wasm",level:2},{value:"Testing the Contract",id:"test-the-contract",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Rust Resources",id:"rust-resources",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started-with-rust-casper-contracts",children:"Getting Started with Rust Casper Contracts"})}),"\n",(0,s.jsx)(t.p,{children:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine."}),"\n",(0,s.jsxs)(t.p,{children:["Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/prerequisites",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsxs)(t.p,{children:["You can create a new sample project very easily with the ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate. For example, let's say that I want to create a project named ",(0,s.jsx)(t.strong,{children:"my-project"})," for this tutorial (you can choose a different name if you wish), then I can simply run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If you look inside the newly-created ",(0,s.jsx)(t.em,{children:"my-project"})," folder, you will find two crates: ",(0,s.jsx)(t.code,{children:"contract"})," and ",(0,s.jsx)(t.code,{children:"tests"}),". This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The ",(0,s.jsx)(t.code,{children:"tests"})," crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test."]}),"\n",(0,s.jsx)(t.h3,{id:"reproducibility",children:"Reproducibility"}),"\n",(0,s.jsxs)(t.p,{children:["Currently, ",(0,s.jsx)(t.a,{href:"https://github.com/rust-lang/cargo/issues/8140",children:"cargo"})," does not provide cross-platform reproducibility for binary files, including WebAssembly. The ability to compile a smart contract to the same binary file is important, for example, when verifying that the smart contract binary stored on the blockchain is the same as the provided source code."]}),"\n",(0,s.jsxs)(t.p,{children:["To work around the issue, ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate provides ",(0,s.jsx)(t.code,{children:"rustc"})," wrapper, which can be enabled using ",(0,s.jsx)(t.code,{children:"--wrapper"})," option."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my_project --wrapper\n"})}),"\n",(0,s.jsx)(t.h3,{id:"using-the-nightly-toolchain",children:"Using the nightly toolchain"}),"\n",(0,s.jsxs)(t.p,{children:["Navigate to the ",(0,s.jsx)(t.code,{children:"my-project"})," folder and open the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/channels.html",children:"Rust Documentation on Channels"})," and the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/toolchains.html",children:"Rust Documentation on Toolchains"})," for further information."]}),"\n",(0,s.jsxs)(t.p,{children:["As shown in this example, we recommend setting up the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file in your project's top-level directory."]}),"\n",(0,s.jsx)(t.p,{children:"You can also install the nightly Rust toolchain with this command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,s.jsx)(t.h3,{id:"available-casper-rust-crates",children:"Available Casper Rust crates"}),"\n",(0,s.jsx)(t.p,{children:"To support smart contract development with Rust, the following crates are published:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"casper-contract"})," - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"casper-engine-test-support"})," - a virtual machine against which you can test your smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"casper-types"})," - a library with types we use across the Rust ecosystem."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"A crate is a compilation unit that can be compiled into a binary or a library."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["For a comprehensive list of crates, visit the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/essential-crates",children:"Essential Casper Crates"})," page."]})}),"\n",(0,s.jsx)(t.h3,{id:"available-api-documentation",children:"Available API documentation"}),"\n",(0,s.jsxs)(t.p,{children:["Each of the Casper crates comes with API documentation and examples for each function, located at ",(0,s.jsx)(t.a,{href:"https://docs.rs/releases/search?query=casper",children:"https://docs.rs"}),". The latest contract API documentation can be found ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"compiling-to-wasm",children:"Compiling to Wasm"}),"\n",(0,s.jsx)(t.p,{children:"The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["To compile the smart contract into Wasm, go into the ",(0,s.jsx)(t.em,{children:"my-project"})," folder, and run the following commands:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd my-project\nmake prepare\nmake build-contract\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find the compiled contract on this path: ",(0,s.jsx)(t.code,{children:"my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Linting"})}),"\n",(0,s.jsxs)(t.p,{children:["Casper contracts support Rust tooling such as ",(0,s.jsx)(t.code,{children:"clippy"})," for linting contracts. Feel free to use them! You can also use the ",(0,s.jsx)(t.code,{children:"make check-lint"})," command for linting your contract. Run this command inside the ",(0,s.jsx)(t.em,{children:"my-project"})," folder:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make check-lint\n"})}),"\n",(0,s.jsx)(t.h2,{id:"test-the-contract",children:"Testing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to creating the contract, the Casper crate also automatically created sample tests in the ",(0,s.jsx)(t.em,{children:"my-project/tests"})," folder."]}),"\n",(0,s.jsxs)(t.p,{children:["The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named ",(0,s.jsx)(t.em,{children:"build.rs"})," if you are interested in looking more into it."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Since the test script automatically builds the contract, during development you only need to run the command ",(0,s.jsx)(t.code,{children:"make test"})," without the need for ",(0,s.jsx)(t.code,{children:"make build-contract"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"A successful test run indicates that your smart contract environment is set up correctly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsx)(t.p,{children:"After the compilation finishes, the test should run and you should see output similar to this message in your terminal:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,s.jsxs)(t.p,{children:["As a brief example, open up ",(0,s.jsx)(t.em,{children:"my-project/contract/src/main.rs"})," in your editor, modify the ",(0,s.jsx)(t.em,{children:"KEY_NAME"})," value in the contract, and then rerun the ",(0,s.jsx)(t.code,{children:"make test"})," command. You should observe that the smart contract recompiles and the test fails now."]}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"The following video tutorial complements this guide."}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/aIhA5fPIHus",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"rust-resources",children:"Rust Resources"}),"\n",(0,s.jsx)(t.p,{children:"These Rust resources are excellent and we highly recommend them:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/book/foreword.html",children:"https://doc.rust-lang.org/book/foreword.html"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://rustwasm.github.io/docs/book/",children:"https://rustwasm.github.io/docs/book/"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/stable/rust-by-example",children:"https://doc.rust-lang.org/stable/rust-by-example"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1966dde1.2677b260.js b/assets/js/1966dde1.2677b260.js new file mode 100644 index 000000000..0dfc8e9dc --- /dev/null +++ b/assets/js/1966dde1.2677b260.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65951],{89328:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=s(74848),t=s(28453);const a={title:"Archive and Restore a DB"},o="Archiving and Restoring a Database",i={id:"operators/maintenance/archiving-and-restoring",title:"Archive and Restore a DB",description:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.",source:"@site/versioned_docs/version-2.0.0/operators/maintenance/archiving-and-restoring.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/archiving-and-restoring",permalink:"/2.0.0/operators/maintenance/archiving-and-restoring",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Archive and Restore a DB"},sidebar:"operators",previous:{title:"Node Maintenance",permalink:"/2.0.0/operators/maintenance/"},next:{title:"Move a Node",permalink:"/2.0.0/operators/maintenance/moving-node"}},d={},c=[{value:"Zstandard Limitations",id:"zstandard-limitations",level:2},{value:"Zstandard Installation",id:"zstandard-installation",level:2},{value:"Initial Warnings",id:"initial-warnings",level:2},{value:"Compression",id:"compression",level:2},{value:"Compression level",id:"compression-level",level:3},{value:"Thread count",id:"thread-count",level:3},{value:"Long-distance matching",id:"long-distance-matching",level:3},{value:"Summary of commands",id:"summary-of-commands",level:3},{value:"Decompression",id:"decompression",level:2},{value:"Streamed Decompression",id:"streamed-decompression",level:2},{value:"Starting a New Node with a Decompressed DB",id:"starting-a-new-node-with-a-decompressed-db",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"archiving-and-restoring-a-database",children:"Archiving and Restoring a Database"})}),"\n",(0,r.jsx)(n.p,{children:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"http://facebook.github.io/zstd/",children:"Zstandard"})," is the best method for compression speed and space for the current LMDB-based database system that the ",(0,r.jsx)(n.code,{children:"casper-node"})," uses."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The values presented in this document assume that the ",(0,r.jsx)(n.code,{children:"trie-compact"})," tool was run on a Mainnet database for compression. Contact the ",(0,r.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb",children:"support team"})," if you have questions."]})}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-limitations",children:"Zstandard Limitations"}),"\n",(0,r.jsxs)(n.p,{children:["The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use ",(0,r.jsx)(n.code,{children:"tar"})," as a pre-filter for stripping sparse data, as shown ",(0,r.jsx)(n.a,{href:"#compression",children:"here"}),", thus eliminating the need to read the full DB size and improving processing."]}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-installation",children:"Zstandard Installation"}),"\n",(0,r.jsx)(n.p,{children:"To install Zstandard, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo apt install zstd\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation."}),"\n",(0,r.jsx)(n.h2,{id:"initial-warnings",children:"Initial Warnings"}),"\n",(0,r.jsxs)(n.p,{children:["You need to stop the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," process of the node (and, therefore, the ",(0,r.jsx)(n.code,{children:"casper-node"})," process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur."]}),"\n",(0,r.jsx)(n.h2,{id:"compression",children:"Compression"}),"\n",(0,r.jsxs)(n.p,{children:["Run the following basic ",(0,r.jsx)(n.code,{children:"tar"})," command from the DB directory. For Mainnet, the directory would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper"}),", and for Testnet it would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper-test"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -cv --sparse .\n"})}),"\n",(0,r.jsx)(n.p,{children:"On some systems, you may get better performance if you specify the block number as an argument:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse .\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then stream the result into ",(0,r.jsx)(n.code,{children:"zstd"}),". The sections below discuss the ",(0,r.jsx)(n.a,{href:"#compression-level",children:"level"}),", ",(0,r.jsx)(n.a,{href:"#thread-count",children:"thread count"}),", and ",(0,r.jsx)(n.a,{href:"#long-distance-matching",children:"long"})," arguments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compression-level",children:"Compression level"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-[level]"})," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."]}),"\n",(0,r.jsx)(n.p,{children:"Here are some examples of a Mainnet DB compression at block 741160:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Level"}),(0,r.jsx)(n.th,{children:"Time (min:sec)"}),(0,r.jsx)(n.th,{children:"Size"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"12"}),(0,r.jsx)(n.td,{children:"29:20"}),(0,r.jsx)(n.td,{children:"15.8 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"15"}),(0,r.jsx)(n.td,{children:"46:15"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"17"}),(0,r.jsx)(n.td,{children:"87:42"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"19"}),(0,r.jsx)(n.td,{children:"197:08"}),(0,r.jsx)(n.td,{children:"12.9 GB"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For local backups, using 1-5 is a great compression speed-to-size trade-off."}),"\n",(0,r.jsx)(n.h3,{id:"thread-count",children:"Thread count"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-T[thread count]"})," is the number of threads that ",(0,r.jsx)(n.code,{children:"zstd"})," should use for compression. If running a script or command on varying machines, use ",(0,r.jsx)(n.code,{children:"T0"})," to allow ",(0,r.jsx)(n.code,{children:"zstd"})," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,r.jsx)(n.code,{children:"-T0"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"long-distance-matching",children:"Long-distance matching"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"--long=31"})," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."]}),"\n",(0,r.jsxs)(n.p,{children:["At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,r.jsx)(n.code,{children:"--long=31"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."}),"\n",(0,r.jsx)(n.h3,{id:"summary-of-commands",children:"Summary of commands"}),"\n",(0,r.jsx)(n.p,{children:"The general command for compression is:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.p,{children:"For local backups, use a lower compression level:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h2,{id:"decompression",children:"Decompression"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zstd -d"})," is the command for decompression; however, the same ",(0,r.jsx)(n.code,{children:"--long"})," value used for compression must be specified. For all ",(0,r.jsx)(n.code,{children:"casper-node"})," DB-related decompression, you will likely use this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"--long=31"})," is omitted, you might see an error such as this, which also gives you the solution:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding \n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then use the ",(0,r.jsx)(n.code,{children:"zstd"})," result to populate a ",(0,r.jsx)(n.code,{children:"tar -xv"})," command. Also, create the decompressed files using ",(0,r.jsx)(n.code,{children:"sudo -u casper"}),", because the files will be used by the ",(0,r.jsx)(n.code,{children:"casper-node"}),". Run the following command inside an empty DB location:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.p,{children:"To fix ownership, use this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py fix_permissions\n"})}),"\n",(0,r.jsx)(n.h2,{id:"streamed-decompression",children:"Streamed Decompression"}),"\n",(0,r.jsxs)(n.p,{children:["If a ",(0,r.jsx)(n.code,{children:".tar.zst"})," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,r.jsx)(n.code,{children:"curl"}),", which can output to stdout with ",(0,r.jsx)(n.code,{children:"--output"})," and stream binary to your terminal."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <URL for tar.zstd file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you use the output along with the previous process, you can decompress the files from ",(0,r.jsx)(n.code,{children:"curl"})," directly into a local directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <tar.zst URL> | zstd -d --long=31 | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"starting-a-new-node-with-a-decompressed-db",children:"Starting a New Node with a Decompressed DB"}),"\n",(0,r.jsxs)(n.p,{children:["If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,r.jsx)(n.code,{children:"node_util.py"})," script included in the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," installation."]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py force_run_version 1_4_5\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/197196c4.10c851c2.js b/assets/js/197196c4.10c851c2.js new file mode 100644 index 000000000..681bbda04 --- /dev/null +++ b/assets/js/197196c4.10c851c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59941],{37581:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var r=s(74848),t=s(28453);const c={title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},o="Setting Up a Local Casper Condor Network for Development",i={permalink:"/blog/condor-local-setup",source:"@site/blog/2024-07-16-setting-up-condor-local.md",title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",date:"2024-07-16T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!1,label:"Set-up",permalink:"/blog/tags/setup",description:"Getting set up on Casper"}],readingTime:4.08,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"}],frontMatter:{title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},l={authorsImageUrls:[void 0]},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Part 1: The Dockerized NCTL (Network Control Tool)",id:"part-1-the-dockerized-nctl-network-control-tool",level:2},{value:"Part 2: Casper Client (Rust)",id:"part-2-casper-client-rust",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Using the Casper Client",id:"using-the-casper-client",level:2},{value:"Accessing the NCTL Block Web Explorer",id:"accessing-the-nctl-block-web-explorer",level:2},{value:"Important Notes",id:"important-notes",level:2},{value:"Additional Tips",id:"additional-tips",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Docker installed and running on your machine"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"part-1-the-dockerized-nctl-network-control-tool",children:"Part 1: The Dockerized NCTL (Network Control Tool)"}),"\n",(0,r.jsx)(n.p,{children:"NCTL is your tool for managing the Casper network. We'll use a Dockerized version for easier setup."}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Clone the Repository:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/make-software/casper-nctl-docker.git\ncd casper-nctl-docker\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Switch to the Condor Branch:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git checkout feat-2.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:["Clone the ",(0,r.jsx)(n.code,{children:"casper-node"})," Repository:"]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node\ngit checkout release-2.0.0-rc3\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Ensure you're in the ",(0,r.jsx)(n.code,{children:"casper-nctl-docker"})," directory when running this command"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Build the Docker Image:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .\n"})}),"\n",(0,r.jsx)(n.p,{children:"This may take a while"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Verify the Image:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker image ls\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Look for the ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"})," image in the output"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"REPOSITORY TAG IMAGE ID CREATED SIZE\ncasper-nctl rc3 9fd1e7b25d42 40 hours ago 433MB\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Start the NCTL Docker Container:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Docker Compose (Recommended):"})," If you're using the ",(0,r.jsx)(n.code,{children:"docker-compose.yml"})," file, make sure that the ",(0,r.jsx)(n.code,{children:"image"})," under the ",(0,r.jsx)(n.code,{children:"mynctl"})," service points to ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"}),". Then run ",(0,r.jsx)(n.code,{children:"docker-compose up"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Manual Docker Command:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -d --name mynctl -p 11101:11101 casper-nctl:rc3\n"})}),"\n",(0,r.jsx)(n.p,{children:"Once it is up and running you should see that there are 5 nodes and 5 sidecars running and another 5 nodes and 5 sidecars that are inactive:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" casper-nctl | validators-1:casper-net-1-node-1 RUNNING pid 996, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-node-2 RUNNING pid 998, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-node-3 RUNNING pid 1002, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-1 RUNNING pid 997, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-2 RUNNING pid 1000, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-3 RUNNING pid 1011, uptime 0:00:03\n casper-nctl | validators-2:casper-net-1-node-4 RUNNING pid 1082, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-node-5 RUNNING pid 1084, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-sidecar-4 RUNNING pid 1083, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-sidecar-5 RUNNING pid 1085, uptime 0:00:02\n casper-nctl | validators-3:casper-net-1-node-10 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-6 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-7 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-8 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-9 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-10 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-6 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-7 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-8 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-9 STOPPED Not started\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"part-2-casper-client-rust",children:"Part 2: Casper Client (Rust)"}),"\n",(0,r.jsx)(n.p,{children:"To interact with your local Condor network, we'll use the Casper Client. You have two options for using the Casper Client:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Option 1: Using the Casper Client from the Docker Image"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"})," Docker image already includes the ",(0,r.jsx)(n.code,{children:"casper-client"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"You can skip the next two steps if you want to use the pre-installed client."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Option 2: Using Your Local Casper Client"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Clone the Repository (Optional):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/casper-client-rs.git\ncd casper-client-rs\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Switch to the Condor-Compatible Branch (Optional):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git checkout feat-track-node-2.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Activate NCTL scripts:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"source nctl-activate.sh casper-nctl\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["4 ",(0,r.jsx)(n.strong,{children:"Test Your Setup:"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"nctl-view-node-status\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'------------------------------------------------------------------------------------------------------------------------------------\n2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:\n{\n"api_version": "2.0.0",\n"peers": [\n {\n "node_id": "tls:05b5..7b39",\n "address": "127.0.0.1:22103"\n },\n {\n "node_id": "tls:527e..37d2",\n "address": "127.0.0.1:22105"\n },\n {\n "node_id": "tls:b1d0..870f",\n "address": "127.0.0.1:22102"\n },\n {\n "node_id": "tls:dcdf..e348",\n "address": "127.0.0.1:22104"\n }\n],\n"build_version": "2.0.0-d5c0d238f",\n"chainspec_name": "casper-net-1",\n"starting_state_root_hash": "2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80",\n"last_added_block_info": {\n "hash": "c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395",\n "timestamp": "2024-07-10T15:31:38.601Z",\n "era_id": 19,\n "height": 205,\n "state_root_hash": "6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612",\n "creator": "0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab"\n},\n"our_public_signing_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b",\n"round_length": "4s 96ms",\n"next_upgrade": null,\n"uptime": "13m 15s",\n"reactor_state": "Validate",\n"last_progress": "2024-07-10T15:18:26.354Z",\n"available_block_range": {\n "low": 0,\n "high": 205\n},\n"block_sync": {\n "historical": null,\n "forward": null\n},\n"latest_switch_block_hash": "5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68"\n}\n.\n.\n.\n'})}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"If sidecars or nodes are not running:"})," If you see ",(0,r.jsx)(n.code,{children:"null"})," values under each node in the output of ",(0,r.jsx)(n.code,{children:"nctl-view-node-status"}),", it means the version of ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," is not compatible with the ",(0,r.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Solution:"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Go to the ",(0,r.jsx)(n.code,{children:"casper-node/ci/ci.json"})," file."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," branch under ",(0,r.jsx)(n.code,{children:"external_deps"})," from:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'"branch": "feat-2.0"\n'})}),"\n",(0,r.jsx)(n.p,{children:"to:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'"branch": "release-1.0.0rc2_node-2.0.0rc3" \n'})}),"\n",(0,r.jsxs)(n.p,{children:["This is because the ",(0,r.jsx)(n.code,{children:"casper-node"})," we are using is ",(0,r.jsx)(n.code,{children:"release-2.0.0-rc3"}),". The required combination of versions of ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," and ",(0,r.jsx)(n.code,{children:"casper-node"})," may change in the future (rc4 etc.)."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Rebuild the NCTL image: ",(0,r.jsx)(n.code,{children:"docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 ."})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"using-the-casper-client",children:"Using the Casper Client"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Command Format(Using local casper-client):"})," ",(0,r.jsx)(n.code,{children:"cargo run --release [command] --node-address http://127.0.0.1:11101"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Command Format(Using casper-client from the docker image):"})," ",(0,r.jsx)(n.code,{children:"casper-client [command] --node-address http://127.0.0.1:11101"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"accessing-the-nctl-block-web-explorer",children:"Accessing the NCTL Block Web Explorer"}),"\n",(0,r.jsx)(n.p,{children:"The NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"http://127.0.0.1:8080\n"})}),"\n",(0,r.jsx)(n.p,{children:"This allows you to visually explore blocks, transactions, and other details of your local network."}),"\n",(0,r.jsx)(n.h2,{id:"important-notes",children:"Important Notes"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Work in Progress:"})," Condor compatibility is still evolving. Some features may be unstable or incomplete."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"additional-tips",children:"Additional Tips"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Community Resources:"})," Join the ",(0,r.jsx)(n.a,{href:"https://t.me/CSPRCondor",children:"Casper Telegram"})," for help and discussion."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},c=r.createContext(t);function o(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/197196c4.af135d1b.js b/assets/js/197196c4.af135d1b.js deleted file mode 100644 index 9ab036184..000000000 --- a/assets/js/197196c4.af135d1b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9941],{37581:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var r=s(74848),t=s(28453);const c={title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},o="Setting Up a Local Casper Condor Network for Development",i={permalink:"/blog/condor-local-setup",source:"@site/blog/2024-07-16-setting-up-condor-local.md",title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",date:"2024-07-16T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"setup",permalink:"/blog/tags/setup"}],readingTime:4.08,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"}],frontMatter:{title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},l={authorsImageUrls:[void 0]},a=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Part 1: The Dockerized NCTL (Network Control Tool)",id:"part-1-the-dockerized-nctl-network-control-tool",level:2},{value:"Part 2: Casper Client (Rust)",id:"part-2-casper-client-rust",level:2},{value:"Troubleshooting",id:"troubleshooting",level:2},{value:"Using the Casper Client",id:"using-the-casper-client",level:2},{value:"Accessing the NCTL Block Web Explorer",id:"accessing-the-nctl-block-web-explorer",level:2},{value:"Important Notes",id:"important-notes",level:2},{value:"Additional Tips",id:"additional-tips",level:2}];function d(e){const n={a:"a",code:"code",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"Docker installed and running on your machine"}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"part-1-the-dockerized-nctl-network-control-tool",children:"Part 1: The Dockerized NCTL (Network Control Tool)"}),"\n",(0,r.jsx)(n.p,{children:"NCTL is your tool for managing the Casper network. We'll use a Dockerized version for easier setup."}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Clone the Repository:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/make-software/casper-nctl-docker.git\ncd casper-nctl-docker\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Switch to the Condor Branch:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git checkout feat-2.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsxs)(n.strong,{children:["Clone the ",(0,r.jsx)(n.code,{children:"casper-node"})," Repository:"]})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node\ngit checkout release-2.0.0-rc3\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Ensure you're in the ",(0,r.jsx)(n.code,{children:"casper-nctl-docker"})," directory when running this command"]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Build the Docker Image:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .\n"})}),"\n",(0,r.jsx)(n.p,{children:"This may take a while"}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Verify the Image:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker image ls\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Look for the ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"})," image in the output"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"REPOSITORY TAG IMAGE ID CREATED SIZE\ncasper-nctl rc3 9fd1e7b25d42 40 hours ago 433MB\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Start the NCTL Docker Container:"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"Docker Compose (Recommended):"})," If you're using the ",(0,r.jsx)(n.code,{children:"docker-compose.yml"})," file, make sure that the ",(0,r.jsx)(n.code,{children:"image"})," under the ",(0,r.jsx)(n.code,{children:"mynctl"})," service points to ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"}),". Then run ",(0,r.jsx)(n.code,{children:"docker-compose up"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Manual Docker Command:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker run -d --name mynctl -p 11101:11101 casper-nctl:rc3\n"})}),"\n",(0,r.jsx)(n.p,{children:"Once it is up and running you should see that there are 5 nodes and 5 sidecars running and another 5 nodes and 5 sidecars that are inactive:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" casper-nctl | validators-1:casper-net-1-node-1 RUNNING pid 996, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-node-2 RUNNING pid 998, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-node-3 RUNNING pid 1002, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-1 RUNNING pid 997, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-2 RUNNING pid 1000, uptime 0:00:03\n casper-nctl | validators-1:casper-net-1-sidecar-3 RUNNING pid 1011, uptime 0:00:03\n casper-nctl | validators-2:casper-net-1-node-4 RUNNING pid 1082, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-node-5 RUNNING pid 1084, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-sidecar-4 RUNNING pid 1083, uptime 0:00:02\n casper-nctl | validators-2:casper-net-1-sidecar-5 RUNNING pid 1085, uptime 0:00:02\n casper-nctl | validators-3:casper-net-1-node-10 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-6 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-7 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-8 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-node-9 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-10 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-6 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-7 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-8 STOPPED Not started\n casper-nctl | validators-3:casper-net-1-sidecar-9 STOPPED Not started\n"})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"part-2-casper-client-rust",children:"Part 2: Casper Client (Rust)"}),"\n",(0,r.jsx)(n.p,{children:"To interact with your local Condor network, we'll use the Casper Client. You have two options for using the Casper Client:"}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Option 1: Using the Casper Client from the Docker Image"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The ",(0,r.jsx)(n.code,{children:"casper-nctl:rc3"})," Docker image already includes the ",(0,r.jsx)(n.code,{children:"casper-client"}),"."]}),"\n",(0,r.jsx)(n.li,{children:"You can skip the next two steps if you want to use the pre-installed client."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Option 2: Using Your Local Casper Client"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Clone the Repository (Optional):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/casper-client-rs.git\ncd casper-client-rs\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Switch to the Condor-Compatible Branch (Optional):"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"git checkout feat-track-node-2.0\n"})}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Activate NCTL scripts:"})}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"source nctl-activate.sh casper-nctl\n"})}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["4 ",(0,r.jsx)(n.strong,{children:"Test Your Setup:"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"nctl-view-node-status\n"})}),"\n",(0,r.jsx)(n.p,{children:"This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:'------------------------------------------------------------------------------------------------------------------------------------\n2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:\n{\n"api_version": "2.0.0",\n"peers": [\n {\n "node_id": "tls:05b5..7b39",\n "address": "127.0.0.1:22103"\n },\n {\n "node_id": "tls:527e..37d2",\n "address": "127.0.0.1:22105"\n },\n {\n "node_id": "tls:b1d0..870f",\n "address": "127.0.0.1:22102"\n },\n {\n "node_id": "tls:dcdf..e348",\n "address": "127.0.0.1:22104"\n }\n],\n"build_version": "2.0.0-d5c0d238f",\n"chainspec_name": "casper-net-1",\n"starting_state_root_hash": "2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80",\n"last_added_block_info": {\n "hash": "c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395",\n "timestamp": "2024-07-10T15:31:38.601Z",\n "era_id": 19,\n "height": 205,\n "state_root_hash": "6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612",\n "creator": "0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab"\n},\n"our_public_signing_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b",\n"round_length": "4s 96ms",\n"next_upgrade": null,\n"uptime": "13m 15s",\n"reactor_state": "Validate",\n"last_progress": "2024-07-10T15:18:26.354Z",\n"available_block_range": {\n "low": 0,\n "high": 205\n},\n"block_sync": {\n "historical": null,\n "forward": null\n},\n"latest_switch_block_hash": "5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68"\n}\n.\n.\n.\n'})}),"\n",(0,r.jsx)(n.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.strong,{children:"If sidecars or nodes are not running:"})," If you see ",(0,r.jsx)(n.code,{children:"null"})," values under each node in the output of ",(0,r.jsx)(n.code,{children:"nctl-view-node-status"}),", it means the version of ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," is not compatible with the ",(0,r.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Solution:"})}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Go to the ",(0,r.jsx)(n.code,{children:"casper-node/ci/ci.json"})," file."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Change the ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," branch under ",(0,r.jsx)(n.code,{children:"external_deps"})," from:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'"branch": "feat-2.0"\n'})}),"\n",(0,r.jsx)(n.p,{children:"to:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-json",children:'"branch": "release-1.0.0rc2_node-2.0.0rc3" \n'})}),"\n",(0,r.jsxs)(n.p,{children:["This is because the ",(0,r.jsx)(n.code,{children:"casper-node"})," we are using is ",(0,r.jsx)(n.code,{children:"release-2.0.0-rc3"}),". The required combination of versions of ",(0,r.jsx)(n.code,{children:"casper-sidecar"})," and ",(0,r.jsx)(n.code,{children:"casper-node"})," may change in the future (rc4 etc.)."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Rebuild the NCTL image: ",(0,r.jsx)(n.code,{children:"docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 ."})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"using-the-casper-client",children:"Using the Casper Client"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Command Format(Using local casper-client):"})," ",(0,r.jsx)(n.code,{children:"cargo run --release [command] --node-address http://127.0.0.1:11101"})]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Command Format(Using casper-client from the docker image):"})," ",(0,r.jsx)(n.code,{children:"casper-client [command] --node-address http://127.0.0.1:11101"})]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"accessing-the-nctl-block-web-explorer",children:"Accessing the NCTL Block Web Explorer"}),"\n",(0,r.jsx)(n.p,{children:"The NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"http://127.0.0.1:8080\n"})}),"\n",(0,r.jsx)(n.p,{children:"This allows you to visually explore blocks, transactions, and other details of your local network."}),"\n",(0,r.jsx)(n.h2,{id:"important-notes",children:"Important Notes"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Work in Progress:"})," Condor compatibility is still evolving. Some features may be unstable or incomplete."]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"additional-tips",children:"Additional Tips"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Community Resources:"})," Join the ",(0,r.jsx)(n.a,{href:"https://t.me/CSPRCondor",children:"Casper Telegram"})," for help and discussion."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},c=r.createContext(t);function o(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19770ceb.8387e9e3.js b/assets/js/19770ceb.8387e9e3.js deleted file mode 100644 index db85efe9d..000000000 --- a/assets/js/19770ceb.8387e9e3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1393],{7132:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={},c="Best Practices for Casper Smart Contract Authors",a={id:"developers/writing-onchain-code/best-practices",title:"Best Practices for Casper Smart Contract Authors",description:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.",source:"@site/docs/developers/writing-onchain-code/best-practices.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/best-practices",permalink:"/next/developers/writing-onchain-code/best-practices",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Factory Contracts",permalink:"/next/developers/writing-onchain-code/factory-pattern"},next:{title:"Overview",permalink:"/next/developers/json-rpc/"}},o={},l=[{value:"Data Efficiency",id:"data-efficiency",level:2},{value:"Costs",id:"costs",level:2},{value:"Tips to reduce WASM size",id:"tips-to-reduce-wasm-size",level:3},{value:"Inlining",id:"inlining",level:2},{value:"Testing",id:"testing",level:2}];function d(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"best-practices-for-casper-smart-contract-authors",children:"Best Practices for Casper Smart Contract Authors"})}),"\n",(0,s.jsx)(n.p,{children:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources."}),"\n",(0,s.jsx)(n.h2,{id:"data-efficiency",children:"Data Efficiency"}),"\n",(0,s.jsxs)(n.p,{children:["When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary ",(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"transactions"})," will drastically decrease the overall cost."]}),"\n",(0,s.jsxs)(n.p,{children:["When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent transaction of session code. This entry point creates the internal structure of the contract and cannot be called after the initial transaction. Below is an example of a self-initalizing entry point that can be used within the ",(0,s.jsx)(n.code,{children:"call"})," function."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example Self-initialization Entry Point"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'\n// This entry point initializes the donation system, setting up the fundraising purse\n// and creating a dictionary to track the account hashes and the number of donations\n// made.\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary(LEDGER).unwrap_or_revert();\n}\n\npub extern "C" fn call() {\n let init_entry_point = EntryPoint::new(\n ENTRY_POINT_INIT,\n vec![],\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial transaction."}),"\n",(0,s.jsx)(n.h2,{id:"costs",children:"Costs"}),"\n",(0,s.jsxs)(n.p,{children:["Computations occurring on-chain come with associated ",(0,s.jsx)(n.a,{href:"/next/concepts/economics/gas-concepts",children:"gas costs"}),". Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical."]}),"\n",(0,s.jsxs)(n.p,{children:["Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/advanced/transfer-token-to-contract#scenario2",children:"reuse of purses"})," should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author."]}),"\n",(0,s.jsx)(n.h3,{id:"tips-to-reduce-wasm-size",children:"Tips to reduce WASM size"}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a maxim size specified in each network chainspec as ",(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576"}),". For example, networks running node version 2.0, have the following maximum transaction size in bytes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here are a few tips to reduce the size of Wasm included in a transaction:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the smart contract in release mode. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L10",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run\xa0",(0,s.jsx)(n.code,{children:"wasm-strip"}),"\xa0on the compiled code (see\xa0",(0,s.jsx)(n.a,{href:"https://github.com/WebAssembly/wabt",children:"WABT"}),"). You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L12",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"wasm-strip target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Don't enable the\xa0",(0,s.jsx)(n.code,{children:"std"}),"\xa0feature when linking to the\xa0",(0,s.jsx)(n.code,{children:"casper-contract"}),"\xa0or\xa0",(0,s.jsx)(n.code,{children:"casper-types"}),"\xa0crates using the ",(0,s.jsx)(n.code,{children:"#![no_std]"})," attribute, which tells the program not to import the standard libraries. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/cep18/src/main.rs#L1",children:"here"})," and further details ",(0,s.jsx)(n.a,{href:"https://docs.rust-embedded.org/book/intro/no-std.html",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with ",(0,s.jsx)(n.code,{children:"codegen-units"})," set to 1 by adding ",(0,s.jsx)(n.code,{children:"codegen-units = 1"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release])"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L14",children:"here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with link-time optimizations enabled by adding ",(0,s.jsx)(n.code,{children:"lto = true"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release]"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L15",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"inlining",children:"Inlining"}),"\n",(0,s.jsxs)(n.p,{children:["As often as practicable, developers should inline functions by including the body of the function within their code rather than making ",(0,s.jsx)(n.code,{children:"call"})," or ",(0,s.jsx)(n.code,{children:"call_indirect"})," to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances."]}),"\n",(0,s.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(n.p,{children:["Testing all transactions prior to committing them to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending transactions to ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Information on these processes can be found at the following locations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter/",children:"A Counter On An NCTL Network"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter-testnet",children:"A Counter On The Testnet"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/19770ceb.85de565a.js b/assets/js/19770ceb.85de565a.js new file mode 100644 index 000000000..8e51ea064 --- /dev/null +++ b/assets/js/19770ceb.85de565a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61393],{7132:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={},c="Best Practices for Casper Smart Contract Authors",a={id:"developers/writing-onchain-code/best-practices",title:"Best Practices for Casper Smart Contract Authors",description:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.",source:"@site/docs/developers/writing-onchain-code/best-practices.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/best-practices",permalink:"/developers/writing-onchain-code/best-practices",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Factory Contracts",permalink:"/developers/writing-onchain-code/factory-pattern"},next:{title:"Overview",permalink:"/developers/json-rpc/"}},o={},l=[{value:"Data Efficiency",id:"data-efficiency",level:2},{value:"Costs",id:"costs",level:2},{value:"Tips to reduce WASM size",id:"tips-to-reduce-wasm-size",level:3},{value:"Inlining",id:"inlining",level:2},{value:"Testing",id:"testing",level:2}];function d(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"best-practices-for-casper-smart-contract-authors",children:"Best Practices for Casper Smart Contract Authors"})}),"\n",(0,s.jsx)(n.p,{children:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources."}),"\n",(0,s.jsx)(n.h2,{id:"data-efficiency",children:"Data Efficiency"}),"\n",(0,s.jsxs)(n.p,{children:["When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"transactions"})," will drastically decrease the overall cost."]}),"\n",(0,s.jsxs)(n.p,{children:["When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent transaction of session code. This entry point creates the internal structure of the contract and cannot be called after the initial transaction. Below is an example of a self-initalizing entry point that can be used within the ",(0,s.jsx)(n.code,{children:"call"})," function."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example Self-initialization Entry Point"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'\n// This entry point initializes the donation system, setting up the fundraising purse\n// and creating a dictionary to track the account hashes and the number of donations\n// made.\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary(LEDGER).unwrap_or_revert();\n}\n\npub extern "C" fn call() {\n let init_entry_point = EntryPoint::new(\n ENTRY_POINT_INIT,\n vec![],\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial transaction."}),"\n",(0,s.jsx)(n.h2,{id:"costs",children:"Costs"}),"\n",(0,s.jsxs)(n.p,{children:["Computations occurring on-chain come with associated ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:"gas costs"}),". Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical."]}),"\n",(0,s.jsxs)(n.p,{children:["Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract#scenario2",children:"reuse of purses"})," should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author."]}),"\n",(0,s.jsx)(n.h3,{id:"tips-to-reduce-wasm-size",children:"Tips to reduce WASM size"}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a maxim size specified in each network chainspec as ",(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576"}),". For example, networks running node version 2.0, have the following maximum transaction size in bytes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here are a few tips to reduce the size of Wasm included in a transaction:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the smart contract in release mode. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L10",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run\xa0",(0,s.jsx)(n.code,{children:"wasm-strip"}),"\xa0on the compiled code (see\xa0",(0,s.jsx)(n.a,{href:"https://github.com/WebAssembly/wabt",children:"WABT"}),"). You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L12",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"wasm-strip target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Don't enable the\xa0",(0,s.jsx)(n.code,{children:"std"}),"\xa0feature when linking to the\xa0",(0,s.jsx)(n.code,{children:"casper-contract"}),"\xa0or\xa0",(0,s.jsx)(n.code,{children:"casper-types"}),"\xa0crates using the ",(0,s.jsx)(n.code,{children:"#![no_std]"})," attribute, which tells the program not to import the standard libraries. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/cep18/src/main.rs#L1",children:"here"})," and further details ",(0,s.jsx)(n.a,{href:"https://docs.rust-embedded.org/book/intro/no-std.html",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with ",(0,s.jsx)(n.code,{children:"codegen-units"})," set to 1 by adding ",(0,s.jsx)(n.code,{children:"codegen-units = 1"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release])"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L14",children:"here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with link-time optimizations enabled by adding ",(0,s.jsx)(n.code,{children:"lto = true"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release]"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L15",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"inlining",children:"Inlining"}),"\n",(0,s.jsxs)(n.p,{children:["As often as practicable, developers should inline functions by including the body of the function within their code rather than making ",(0,s.jsx)(n.code,{children:"call"})," or ",(0,s.jsx)(n.code,{children:"call_indirect"})," to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances."]}),"\n",(0,s.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(n.p,{children:["Testing all transactions prior to committing them to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending transactions to ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Information on these processes can be found at the following locations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter/",children:"A Counter On An NCTL Network"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter-testnet",children:"A Counter On The Testnet"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3fe76c6c.fdefcb5a.js b/assets/js/19b85f8d.9543118f.js similarity index 67% rename from assets/js/3fe76c6c.fdefcb5a.js rename to assets/js/19b85f8d.9543118f.js index cdc33452a..6e9b637ff 100644 --- a/assets/js/3fe76c6c.fdefcb5a.js +++ b/assets/js/19b85f8d.9543118f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9672],{19259:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=n(74848),o=n(28453);const a={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/walkthrough.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/walkthrough",permalink:"/resources/beginner/counter/walkthrough",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter/commands"},next:{title:"Introduction",permalink:"/counter-testnet"}},i={},l=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"Create a Local Network",id:"create-a-local-network",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are three versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"contract-v1"})})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["It defines two named keys:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"counter"}),": References the contract itself."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"count"}),": Stores the current counter value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["It provides functions for:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"get_count"}),": Retrieves the current counter value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"counter_inc"}),": Increments the counter value by 1."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"contract-v2"})})," (Not Used in This Tutorial)"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["An extension of ",(0,s.jsx)(t.code,{children:"contract-v1"}),". It demonstrates decrementing the counter and contract upgrades."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["**",(0,s.jsx)(t.code,{children:"contract-v3"})," ** (Not Used in This Tutorial)"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["This version showcases how to add new functionalities during smart contract upgrades. It extends ",(0,s.jsx)(t.code,{children:"contract-v1"})," and ",(0,s.jsx)(t.code,{children:"contract-v2"})," by introducing:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["A new named key: ",(0,s.jsx)(t.code,{children:"last_updated_at"})," - Tracks the timestamp of the last counter update."]}),"\n",(0,s.jsxs)(t.li,{children:["A new entry point: ",(0,s.jsx)(t.code,{children:"get_last_updated_at"})," - Retrieves the ",(0,s.jsx)(t.code,{children:"last_updated_at"})," timestamp."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["It focuses on the process of adding new fields like ",(0,s.jsx)(t.code,{children:"last_updated_at"})," to existing contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"counter-call"})})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Session code that retrieves the specific contract version (e.g., ",(0,s.jsx)(t.code,{children:"contract-v1"}),"), interacts with its functions (e.g., ",(0,s.jsx)(t.code,{children:"get_count"}),", ",(0,s.jsx)(t.code,{children:"counter_inc"}),"), and verifies the expected behavior."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-local-network",children:"Create a Local Network"}),"\n",(0,s.jsx)(t.p,{children:"After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network."}),"\n",(0,s.jsx)(t.p,{children:"If you run the following line in your terminal, you should be able to spin up a network effortlessly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["If it fails for any reason, please refer the ",(0,s.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"NCTL tutorial"})," and make sure that all your packages are up to date."]})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"AccountHash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"nctl-view-faucet-account"})," - Get the faucet's account hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state root hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," - Get the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the ",(0,s.jsx)(t.em,{children:"account-hash"})," field and the ",(0,s.jsx)(t.em,{children:"secret_key.pem"})," path because you will often use both."]}),"\n",(0,s.jsx)(t.p,{children:"Get the state root hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You are using localhost as the node server since the network is running on our local machine. Make a note of the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call ",(0,s.jsx)(t.em,{children:"nctl-view-faucet-account"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to install the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on your local network!"})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const o={},a=s.createContext(o);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28114],{3273:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter/walkthrough.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/walkthrough",permalink:"/2.0.0/resources/beginner/counter/walkthrough",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/2.0.0/resources/beginner/counter/commands"},next:{title:"Introduction",permalink:"/2.0.0/counter-testnet"}},i={},l=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"Create a Local Network",id:"create-a-local-network",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-local-network",children:"Create a Local Network"}),"\n",(0,s.jsx)(t.p,{children:"After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network."}),"\n",(0,s.jsx)(t.p,{children:"If you run the following line in your terminal, you should be able to spin up a network effortlessly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["If it fails for any reason, please refer the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"NCTL tutorial"})," and make sure that all your packages are up to date."]})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"AccountHash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"nctl-view-faucet-account"})," - Get the faucet's account hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state root hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," - Get the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the ",(0,s.jsx)(t.em,{children:"account-hash"})," field and the ",(0,s.jsx)(t.em,{children:"secret_key.pem"})," path because you will often use both."]}),"\n",(0,s.jsx)(t.p,{children:"Get the state root hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You are using localhost as the node server since the network is running on our local machine. Make a note of the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call ",(0,s.jsx)(t.em,{children:"nctl-view-faucet-account"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to install the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on your local network!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.87166043.js b/assets/js/1a4e3797.87166043.js new file mode 100644 index 000000000..964c67725 --- /dev/null +++ b/assets/js/1a4e3797.87166043.js @@ -0,0 +1,2 @@ +/*! For license information please see 1a4e3797.87166043.js.LICENSE.txt */ +(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62138],{72733:e=>{function t(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function n(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}e.exports=t,t.prototype._events=void 0,t.prototype._maxListeners=void 0,t.defaultMaxListeners=10,t.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},t.prototype.emit=function(e){var t,s,a,c,o,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||n(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var h=new Error('Uncaught, unspecified "error" event. ('+t+")");throw h.context=t,h}if(i(s=this._events[e]))return!1;if(r(s))switch(arguments.length){case 1:s.call(this);break;case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:c=Array.prototype.slice.call(arguments,1),s.apply(this,c)}else if(n(s))for(c=Array.prototype.slice.call(arguments,1),a=(u=s.slice()).length,o=0;o<a;o++)u[o].apply(this,c);return!0},t.prototype.addListener=function(e,s){var a;if(!r(s))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(s.listener)?s.listener:s),this._events[e]?n(this._events[e])?this._events[e].push(s):this._events[e]=[this._events[e],s]:this._events[e]=s,n(this._events[e])&&!this._events[e].warned&&(a=i(this._maxListeners)?t.defaultMaxListeners:this._maxListeners)&&a>0&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},t.prototype.on=t.prototype.addListener,t.prototype.once=function(e,t){if(!r(t))throw TypeError("listener must be a function");var n=!1;function i(){this.removeListener(e,i),n||(n=!0,t.apply(this,arguments))}return i.listener=t,this.on(e,i),this},t.prototype.removeListener=function(e,t){var i,s,a,c;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(a=(i=this._events[e]).length,s=-1,i===t||r(i.listener)&&i.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(n(i)){for(c=a;c-- >0;)if(i[c]===t||i[c].listener&&i[c].listener===t){s=c;break}if(s<0)return this;1===i.length?(i.length=0,delete this._events[e]):i.splice(s,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},t.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r(n=this._events[e]))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},t.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},t.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},t.listenerCount=function(e,t){return e.listenerCount(t)}},74103:(e,t,r)=>{"use strict";var n=r(36571),i=r(19127),s=r(42223),a=r(33371),c=r(67691);function o(e,t,r,i){return new n(e,t,r,i)}o.version=r(16938),o.AlgoliaSearchHelper=n,o.SearchParameters=a,o.RecommendParameters=i,o.SearchResults=c,o.RecommendResults=s,e.exports=o},46732:(e,t,r)=>{"use strict";var n=r(72733);function i(e,t,r){this.main=e,this.fn=t,this.recommendFn=r,this.lastResults=null,this.lastRecommendResults=null}r(73014)(i,n),i.prototype.detach=function(){this.removeAllListeners(),this.main.detachDerivedHelper(this)},i.prototype.getModifiedState=function(e){return this.fn(e)},i.prototype.getModifiedRecommendState=function(e){return this.recommendFn(e)},e.exports=i},19127:e=>{"use strict";function t(e){e=e||{},this.params=e.params||[]}t.prototype={constructor:t,addParams:function(e){var r=this.params.slice();return r.push(e),new t({params:r})},removeParams:function(e){return new t({params:this.params.filter((function(t){return t.$$id!==e}))})},addFrequentlyBoughtTogether:function(e){return this.addParams(Object.assign({},e,{model:"bought-together"}))},addRelatedProducts:function(e){return this.addParams(Object.assign({},e,{model:"related-products"}))},addTrendingItems:function(e){return this.addParams(Object.assign({},e,{model:"trending-items"}))},addTrendingFacets:function(e){return this.addParams(Object.assign({},e,{model:"trending-facets"}))},addLookingSimilar:function(e){return this.addParams(Object.assign({},e,{model:"looking-similar"}))},_buildQueries:function(e,t){return this.params.filter((function(e){return void 0===t[e.$$id]})).map((function(t){var r=Object.assign({},t,{indexName:e});return delete r.$$id,r}))}},e.exports=t},42223:e=>{"use strict";function t(e,t){this._state=e,this._rawResults={};var r=this;e.params.forEach((function(e){var n=e.$$id;r[n]=t[n],r._rawResults[n]=t[n]}))}t.prototype={constructor:t},e.exports=t},44054:(e,t,r)=>{"use strict";var n=r(29110),i=r(40317),s=r(21383),a={addRefinement:function(e,t,r){if(a.isRefined(e,t,r))return e;var i=""+r,s=e[t]?e[t].concat(i):[i],c={};return c[t]=s,n({},c,e)},removeRefinement:function(e,t,r){if(void 0===r)return a.clearRefinement(e,(function(e,r){return t===r}));var n=""+r;return a.clearRefinement(e,(function(e,r){return t===r&&n===e}))},toggleRefinement:function(e,t,r){if(void 0===r)throw new Error("toggleRefinement should be used with a value");return a.isRefined(e,t,r)?a.removeRefinement(e,t,r):a.addRefinement(e,t,r)},clearRefinement:function(e,t,r){if(void 0===t)return i(e)?{}:e;if("string"==typeof t)return s(e,[t]);if("function"==typeof t){var n=!1,a=Object.keys(e).reduce((function(i,s){var a=e[s]||[],c=a.filter((function(e){return!t(e,s,r)}));return c.length!==a.length&&(n=!0),i[s]=c,i}),{});return n?a:e}},isRefined:function(e,t,r){var n=Boolean(e[t])&&e[t].length>0;if(void 0===r||!n)return n;var i=""+r;return-1!==e[t].indexOf(i)}};e.exports=a},33371:(e,t,r)=>{"use strict";var n=r(29110),i=r(20849),s=r(14843),a=r(44728),c=r(40317),o=r(21383),u=r(17507),h=r(72208),f=r(44054);function l(e,t){return Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((function(e,r){return l(t[r],e)})):e===t}function m(e){var t=e?m._parseNumbers(e):{};void 0===t.userToken||h(t.userToken)||console.warn("[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\n - Format: [a-zA-Z0-9_-]{1,64}"),this.facets=t.facets||[],this.disjunctiveFacets=t.disjunctiveFacets||[],this.hierarchicalFacets=t.hierarchicalFacets||[],this.facetsRefinements=t.facetsRefinements||{},this.facetsExcludes=t.facetsExcludes||{},this.disjunctiveFacetsRefinements=t.disjunctiveFacetsRefinements||{},this.numericRefinements=t.numericRefinements||{},this.tagRefinements=t.tagRefinements||[],this.hierarchicalFacetsRefinements=t.hierarchicalFacetsRefinements||{};var r=this;Object.keys(t).forEach((function(e){var n=-1!==m.PARAMETERS.indexOf(e),i=void 0!==t[e];!n&&i&&(r[e]=t[e])}))}m.PARAMETERS=Object.keys(new m),m._parseNumbers=function(e){if(e instanceof m)return e;var t={};if(["aroundPrecision","aroundRadius","getRankingInfo","minWordSizefor2Typos","minWordSizefor1Typo","page","maxValuesPerFacet","distinct","minimumAroundRadius","hitsPerPage","minProximity"].forEach((function(r){var n=e[r];if("string"==typeof n){var i=parseFloat(n);t[r]=isNaN(i)?n:i}})),Array.isArray(e.insideBoundingBox)&&(t.insideBoundingBox=e.insideBoundingBox.map((function(e){return Array.isArray(e)?e.map((function(e){return parseFloat(e)})):e}))),e.numericRefinements){var r={};Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t]||{};r[t]={},Object.keys(n).forEach((function(e){var i=n[e].map((function(e){return Array.isArray(e)?e.map((function(e){return"string"==typeof e?parseFloat(e):e})):"string"==typeof e?parseFloat(e):e}));r[t][e]=i}))})),t.numericRefinements=r}return a(e,t)},m.make=function(e){var t=new m(e);return(e.hierarchicalFacets||[]).forEach((function(e){if(e.rootPath){var r=t.getHierarchicalRefinement(e.name);r.length>0&&0!==r[0].indexOf(e.rootPath)&&(t=t.clearRefinements(e.name)),0===(r=t.getHierarchicalRefinement(e.name)).length&&(t=t.toggleHierarchicalFacetRefinement(e.name,e.rootPath))}})),t},m.validate=function(e,t){var r=t||{};return e.tagFilters&&r.tagRefinements&&r.tagRefinements.length>0?new Error("[Tags] Cannot switch from the managed tag API to the advanced API. It is probably an error, if it is really what you want, you should first clear the tags with clearTags method."):e.tagRefinements.length>0&&r.tagFilters?new Error("[Tags] Cannot switch from the advanced tag API to the managed API. It is probably an error, if it is not, you should first clear the tags with clearTags method."):e.numericFilters&&r.numericRefinements&&c(r.numericRefinements)?new Error("[Numeric filters] Can't switch from the advanced to the managed API. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):c(e.numericRefinements)&&r.numericFilters?new Error("[Numeric filters] Can't switch from the managed API to the advanced. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):null},m.prototype={constructor:m,clearRefinements:function(e){var t={numericRefinements:this._clearNumericRefinements(e),facetsRefinements:f.clearRefinement(this.facetsRefinements,e,"conjunctiveFacet"),facetsExcludes:f.clearRefinement(this.facetsExcludes,e,"exclude"),disjunctiveFacetsRefinements:f.clearRefinement(this.disjunctiveFacetsRefinements,e,"disjunctiveFacet"),hierarchicalFacetsRefinements:f.clearRefinement(this.hierarchicalFacetsRefinements,e,"hierarchicalFacet")};return t.numericRefinements===this.numericRefinements&&t.facetsRefinements===this.facetsRefinements&&t.facetsExcludes===this.facetsExcludes&&t.disjunctiveFacetsRefinements===this.disjunctiveFacetsRefinements&&t.hierarchicalFacetsRefinements===this.hierarchicalFacetsRefinements?this:this.setQueryParameters(t)},clearTags:function(){return void 0===this.tagFilters&&0===this.tagRefinements.length?this:this.setQueryParameters({tagFilters:void 0,tagRefinements:[]})},setIndex:function(e){return e===this.index?this:this.setQueryParameters({index:e})},setQuery:function(e){return e===this.query?this:this.setQueryParameters({query:e})},setPage:function(e){return e===this.page?this:this.setQueryParameters({page:e})},setFacets:function(e){return this.setQueryParameters({facets:e})},setDisjunctiveFacets:function(e){return this.setQueryParameters({disjunctiveFacets:e})},setHitsPerPage:function(e){return this.hitsPerPage===e?this:this.setQueryParameters({hitsPerPage:e})},setTypoTolerance:function(e){return this.typoTolerance===e?this:this.setQueryParameters({typoTolerance:e})},addNumericRefinement:function(e,t,r){var n=u(r);if(this.isNumericRefined(e,t,n))return this;var i=a({},this.numericRefinements);return i[e]=a({},i[e]),i[e][t]?(i[e][t]=i[e][t].slice(),i[e][t].push(n)):i[e][t]=[n],this.setQueryParameters({numericRefinements:i})},getConjunctiveRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsRefinements[e]||[]},getDisjunctiveRefinements:function(e){return this.isDisjunctiveFacet(e)&&this.disjunctiveFacetsRefinements[e]||[]},getHierarchicalRefinement:function(e){return this.hierarchicalFacetsRefinements[e]||[]},getExcludeRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsExcludes[e]||[]},removeNumericRefinement:function(e,t,r){var n=r;return void 0!==n?this.isNumericRefined(e,t,n)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,i){return i===e&&r.op===t&&l(r.val,u(n))}))}):this:void 0!==t?this.isNumericRefined(e,t)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,n){return n===e&&r.op===t}))}):this:this.isNumericRefined(e)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(t,r){return r===e}))}):this},getNumericRefinements:function(e){return this.numericRefinements[e]||{}},getNumericRefinement:function(e,t){return this.numericRefinements[e]&&this.numericRefinements[e][t]},_clearNumericRefinements:function(e){if(void 0===e)return c(this.numericRefinements)?{}:this.numericRefinements;if("string"==typeof e)return o(this.numericRefinements,[e]);if("function"==typeof e){var t=!1,r=this.numericRefinements,n=Object.keys(r).reduce((function(n,i){var s=r[i],a={};return s=s||{},Object.keys(s).forEach((function(r){var n=s[r]||[],c=[];n.forEach((function(t){e({val:t,op:r},i,"numeric")||c.push(t)})),c.length!==n.length&&(t=!0),a[r]=c})),n[i]=a,n}),{});return t?n:this.numericRefinements}},addFacet:function(e){return this.isConjunctiveFacet(e)?this:this.setQueryParameters({facets:this.facets.concat([e])})},addDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this:this.setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.concat([e])})},addHierarchicalFacet:function(e){if(this.isHierarchicalFacet(e.name))throw new Error("Cannot declare two hierarchical facets with the same name: `"+e.name+"`");return this.setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.concat([e])})},addFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this:this.setQueryParameters({facetsRefinements:f.addRefinement(this.facetsRefinements,e,t)})},addExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this:this.setQueryParameters({facetsExcludes:f.addRefinement(this.facetsExcludes,e,t)})},addDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this:this.setQueryParameters({disjunctiveFacetsRefinements:f.addRefinement(this.disjunctiveFacetsRefinements,e,t)})},addTagRefinement:function(e){if(this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.concat(e)};return this.setQueryParameters(t)},removeFacet:function(e){return this.isConjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({facets:this.facets.filter((function(t){return t!==e}))}):this},removeDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.filter((function(t){return t!==e}))}):this},removeHierarchicalFacet:function(e){return this.isHierarchicalFacet(e)?this.clearRefinements(e).setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.filter((function(t){return t.name!==e}))}):this},removeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this.setQueryParameters({facetsRefinements:f.removeRefinement(this.facetsRefinements,e,t)}):this},removeExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this.setQueryParameters({facetsExcludes:f.removeRefinement(this.facetsExcludes,e,t)}):this},removeDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this.setQueryParameters({disjunctiveFacetsRefinements:f.removeRefinement(this.disjunctiveFacetsRefinements,e,t)}):this},removeTagRefinement:function(e){if(!this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.filter((function(t){return t!==e}))};return this.setQueryParameters(t)},toggleRefinement:function(e,t){return this.toggleFacetRefinement(e,t)},toggleFacetRefinement:function(e,t){if(this.isHierarchicalFacet(e))return this.toggleHierarchicalFacetRefinement(e,t);if(this.isConjunctiveFacet(e))return this.toggleConjunctiveFacetRefinement(e,t);if(this.isDisjunctiveFacet(e))return this.toggleDisjunctiveFacetRefinement(e,t);throw new Error("Cannot refine the undeclared facet "+e+"; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets")},toggleConjunctiveFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsRefinements:f.toggleRefinement(this.facetsRefinements,e,t)})},toggleExcludeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsExcludes:f.toggleRefinement(this.facetsExcludes,e,t)})},toggleDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return this.setQueryParameters({disjunctiveFacetsRefinements:f.toggleRefinement(this.disjunctiveFacetsRefinements,e,t)})},toggleHierarchicalFacetRefinement:function(e,t){if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration");var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e)),i={};return void 0!==this.hierarchicalFacetsRefinements[e]&&this.hierarchicalFacetsRefinements[e].length>0&&(this.hierarchicalFacetsRefinements[e][0]===t||0===this.hierarchicalFacetsRefinements[e][0].indexOf(t+r))?-1===t.indexOf(r)?i[e]=[]:i[e]=[t.slice(0,t.lastIndexOf(r))]:i[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},i,this.hierarchicalFacetsRefinements)})},addHierarchicalFacetRefinement:function(e,t){if(this.isHierarchicalFacetRefined(e))throw new Error(e+" is already refined.");if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration.");var r={};return r[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},r,this.hierarchicalFacetsRefinements)})},removeHierarchicalFacetRefinement:function(e){if(!this.isHierarchicalFacetRefined(e))return this;var t={};return t[e]=[],this.setQueryParameters({hierarchicalFacetsRefinements:n({},t,this.hierarchicalFacetsRefinements)})},toggleTagRefinement:function(e){return this.isTagRefined(e)?this.removeTagRefinement(e):this.addTagRefinement(e)},isDisjunctiveFacet:function(e){return this.disjunctiveFacets.indexOf(e)>-1},isHierarchicalFacet:function(e){return void 0!==this.getHierarchicalFacetByName(e)},isConjunctiveFacet:function(e){return this.facets.indexOf(e)>-1},isFacetRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsRefinements,e,t)},isExcludeRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsExcludes,e,t)},isDisjunctiveFacetRefined:function(e,t){return!!this.isDisjunctiveFacet(e)&&f.isRefined(this.disjunctiveFacetsRefinements,e,t)},isHierarchicalFacetRefined:function(e,t){if(!this.isHierarchicalFacet(e))return!1;var r=this.getHierarchicalRefinement(e);return t?-1!==r.indexOf(t):r.length>0},isNumericRefined:function(e,t,r){if(void 0===r&&void 0===t)return Boolean(this.numericRefinements[e]);var n=this.numericRefinements[e]&&void 0!==this.numericRefinements[e][t];if(void 0===r||!n)return n;var s,a,c=u(r),o=void 0!==(s=this.numericRefinements[e][t],a=c,i(s,(function(e){return l(e,a)})));return n&&o},isTagRefined:function(e){return-1!==this.tagRefinements.indexOf(e)},getRefinedDisjunctiveFacets:function(){var e=this,t=s(Object.keys(this.numericRefinements).filter((function(t){return Object.keys(e.numericRefinements[t]).length>0})),this.disjunctiveFacets);return Object.keys(this.disjunctiveFacetsRefinements).filter((function(t){return e.disjunctiveFacetsRefinements[t].length>0})).concat(t).concat(this.getRefinedHierarchicalFacets()).sort()},getRefinedHierarchicalFacets:function(){var e=this;return s(this.hierarchicalFacets.map((function(e){return e.name})),Object.keys(this.hierarchicalFacetsRefinements).filter((function(t){return e.hierarchicalFacetsRefinements[t].length>0}))).sort()},getUnrefinedDisjunctiveFacets:function(){var e=this.getRefinedDisjunctiveFacets();return this.disjunctiveFacets.filter((function(t){return-1===e.indexOf(t)}))},managedParameters:["index","facets","disjunctiveFacets","facetsRefinements","hierarchicalFacets","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements"],getQueryParams:function(){var e=this.managedParameters,t={},r=this;return Object.keys(this).forEach((function(n){var i=r[n];-1===e.indexOf(n)&&void 0!==i&&(t[n]=i)})),t},setQueryParameter:function(e,t){if(this[e]===t)return this;var r={};return r[e]=t,this.setQueryParameters(r)},setQueryParameters:function(e){if(!e)return this;var t=m.validate(this,e);if(t)throw t;var r=this,n=m._parseNumbers(e),i=Object.keys(this).reduce((function(e,t){return e[t]=r[t],e}),{}),s=Object.keys(n).reduce((function(e,t){var r=void 0!==e[t],i=void 0!==n[t];return r&&!i?o(e,[t]):(i&&(e[t]=n[t]),e)}),i);return new this.constructor(s)},resetPage:function(){return void 0===this.page?this:this.setPage(0)},_getHierarchicalFacetSortBy:function(e){return e.sortBy||["isRefined:desc","name:asc"]},_getHierarchicalFacetSeparator:function(e){return e.separator||" > "},_getHierarchicalRootPath:function(e){return e.rootPath||null},_getHierarchicalShowParentLevel:function(e){return"boolean"!=typeof e.showParentLevel||e.showParentLevel},getHierarchicalFacetByName:function(e){return i(this.hierarchicalFacets,(function(t){return t.name===e}))},getHierarchicalFacetBreadcrumb:function(e){if(!this.isHierarchicalFacet(e))return[];var t=this.getHierarchicalRefinement(e)[0];if(!t)return[];var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e));return t.split(r).map((function(e){return e.trim()}))},toString:function(){return JSON.stringify(this,null,2)}},e.exports=m},76673:(e,t,r)=>{"use strict";e.exports=function(e){return function(t,r){var n=e.hierarchicalFacets[r],u=e.hierarchicalFacetsRefinements[n.name]&&e.hierarchicalFacetsRefinements[n.name][0]||"",h=e._getHierarchicalFacetSeparator(n),f=e._getHierarchicalRootPath(n),l=e._getHierarchicalShowParentLevel(n),m=s(e._getHierarchicalFacetSortBy(n)),d=t.every((function(e){return e.exhaustive})),p=function(e,t,r,n,s){return function(u,h,f){var l=u;if(f>0){var m=0;for(l=u;m<f;){var d=l&&Array.isArray(l.data)?l.data:[];l=i(d,(function(e){return e.isRefined})),m++}}if(l){var p=Object.keys(h.data).map((function(e){return[e,h.data[e]]})).filter((function(e){return function(e,t,r,n,i,s){if(i&&(0!==e.indexOf(i)||i===e))return!1;return!i&&-1===e.indexOf(n)||i&&e.split(n).length-i.split(n).length==1||-1===e.indexOf(n)&&-1===r.indexOf(n)||0===r.indexOf(e)||0===e.indexOf(t+n)&&(s||0===e.indexOf(r))}(e[0],l.path||r,s,t,r,n)}));l.data=a(p.map((function(e){var r=e[0];return function(e,t,r,n,i){var s=t.split(r);return{name:s[s.length-1].trim(),path:t,escapedValue:c(t),count:e,isRefined:n===t||0===n.indexOf(t+r),exhaustive:i,data:null}}(e[1],r,t,o(s),h.exhaustive)})),e[0],e[1])}return u}}(m,h,f,l,u),g=t;return f&&(g=t.slice(f.split(h).length)),g.reduce(p,{name:e.hierarchicalFacets[r].name,count:null,isRefined:!0,path:null,escapedValue:null,exhaustive:d,data:null})}};var n=r(2909),i=r(20849),s=r(7577),a=r(38601),c=n.escapeFacetValue,o=n.unescapeFacetValue},67691:(e,t,r)=>{"use strict";var n=r(78965),i=r(29110),s=r(2909),a=r(20849),c=r(43917),o=r(7577),u=r(44728),h=r(38601),f=s.escapeFacetValue,l=s.unescapeFacetValue,m=r(76673);function d(e){var t={};return e.forEach((function(e,r){t[e]=r})),t}function p(e,t,r){t&&t[r]&&(e.stats=t[r])}function g(e,t,r){var s=t[0]||{};this._rawResults=t;var o=this;Object.keys(s).forEach((function(e){o[e]=s[e]}));var h=u({persistHierarchicalRootCount:!1},r);Object.keys(h).forEach((function(e){o[e]=h[e]})),this.processingTimeMS=t.reduce((function(e,t){return void 0===t.processingTimeMS?e:e+t.processingTimeMS}),0),this.disjunctiveFacets=[],this.hierarchicalFacets=e.hierarchicalFacets.map((function(){return[]})),this.facets=[];var f=e.getRefinedDisjunctiveFacets(),g=d(e.facets),v=d(e.disjunctiveFacets),y=1,R=s.facets||{};Object.keys(R).forEach((function(t){var r,n,i=R[t],u=(r=e.hierarchicalFacets,n=t,a(r,(function(e){return(e.attributes||[]).indexOf(n)>-1})));if(u){var h=u.attributes.indexOf(t),f=c(e.hierarchicalFacets,(function(e){return e.name===u.name}));o.hierarchicalFacets[f][h]={attribute:t,data:i,exhaustive:s.exhaustiveFacetsCount}}else{var l,m=-1!==e.disjunctiveFacets.indexOf(t),d=-1!==e.facets.indexOf(t);m&&(l=v[t],o.disjunctiveFacets[l]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(o.disjunctiveFacets[l],s.facets_stats,t)),d&&(l=g[t],o.facets[l]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(o.facets[l],s.facets_stats,t))}})),this.hierarchicalFacets=n(this.hierarchicalFacets),f.forEach((function(r){var n=t[y],a=n&&n.facets?n.facets:{},h=e.getHierarchicalFacetByName(r);Object.keys(a).forEach((function(t){var r,f=a[t];if(h){r=c(e.hierarchicalFacets,(function(e){return e.name===h.name}));var m=c(o.hierarchicalFacets[r],(function(e){return e.attribute===t}));if(-1===m)return;o.hierarchicalFacets[r][m].data=u({},o.hierarchicalFacets[r][m].data,f)}else{r=v[t];var d=s.facets&&s.facets[t]||{};o.disjunctiveFacets[r]={name:t,data:i({},f,d),exhaustive:n.exhaustiveFacetsCount},p(o.disjunctiveFacets[r],n.facets_stats,t),e.disjunctiveFacetsRefinements[t]&&e.disjunctiveFacetsRefinements[t].forEach((function(n){!o.disjunctiveFacets[r].data[n]&&e.disjunctiveFacetsRefinements[t].indexOf(l(n))>-1&&(o.disjunctiveFacets[r].data[n]=0)}))}})),y++})),e.getRefinedHierarchicalFacets().forEach((function(r){var n=e.getHierarchicalFacetByName(r),s=e._getHierarchicalFacetSeparator(n),a=e.getHierarchicalRefinement(r);0===a.length||a[0].split(s).length<2||t.slice(y).forEach((function(t){var r=t&&t.facets?t.facets:{};Object.keys(r).forEach((function(t){var u=r[t],h=c(e.hierarchicalFacets,(function(e){return e.name===n.name})),f=c(o.hierarchicalFacets[h],(function(e){return e.attribute===t}));if(-1!==f){var l={};if(a.length>0&&!o.persistHierarchicalRootCount){var m=a[0].split(s)[0];l[m]=o.hierarchicalFacets[h][f].data[m]}o.hierarchicalFacets[h][f].data=i(l,u,o.hierarchicalFacets[h][f].data)}})),y++}))})),Object.keys(e.facetsExcludes).forEach((function(t){var r=e.facetsExcludes[t],n=g[t];o.facets[n]={name:t,data:R[t],exhaustive:s.exhaustiveFacetsCount},r.forEach((function(e){o.facets[n]=o.facets[n]||{name:t},o.facets[n].data=o.facets[n].data||{},o.facets[n].data[e]=0}))})),this.hierarchicalFacets=this.hierarchicalFacets.map(m(e)),this.facets=n(this.facets),this.disjunctiveFacets=n(this.disjunctiveFacets),this._state=e}function v(e,t){function r(e){return e.name===t}if(e._state.isConjunctiveFacet(t)){var n=a(e.facets,r);return n?Object.keys(n.data).map((function(r){var i=f(r);return{name:r,escapedValue:i,count:n.data[r],isRefined:e._state.isFacetRefined(t,i),isExcluded:e._state.isExcludeRefined(t,r)}})):[]}if(e._state.isDisjunctiveFacet(t)){var i=a(e.disjunctiveFacets,r);return i?Object.keys(i.data).map((function(r){var n=f(r);return{name:r,escapedValue:n,count:i.data[r],isRefined:e._state.isDisjunctiveFacetRefined(t,n)}})):[]}if(e._state.isHierarchicalFacet(t)){var s=a(e.hierarchicalFacets,r);if(!s)return s;var c=e._state.getHierarchicalFacetByName(t),o=e._state._getHierarchicalFacetSeparator(c),u=l(e._state.getHierarchicalRefinement(t)[0]||"");0===u.indexOf(c.rootPath)&&(u=u.replace(c.rootPath+o,""));var h=u.split(o);return h.unshift(t),y(s,h,0),s}}function y(e,t,r){e.isRefined=e.name===(t[r]&&t[r].trim()),e.data&&e.data.forEach((function(e){y(e,t,r+1)}))}function R(e,t,r,n){if(n=n||0,Array.isArray(t))return e(t,r[n]);if(!t.data||0===t.data.length)return t;var s=t.data.map((function(t){return R(e,t,r,n+1)})),a=e(s,r[n]);return i({data:a},t)}function F(e,t){var r=a(e,(function(e){return e.name===t}));return r&&r.stats}function b(e,t,r,n,i){var s=a(i,(function(e){return e.name===r})),c=s&&s.data&&s.data[n]?s.data[n]:0,o=s&&s.exhaustive||!1;return{type:t,attributeName:r,name:n,count:c,exhaustive:o}}g.prototype.getFacetByName=function(e){function t(t){return t.name===e}return a(this.facets,t)||a(this.disjunctiveFacets,t)||a(this.hierarchicalFacets,t)},g.DEFAULT_SORT=["isRefined:desc","count:desc","name:asc"],g.prototype.getFacetValues=function(e,t){var r=v(this,e);if(r){var n,s=i({},t,{sortBy:g.DEFAULT_SORT,facetOrdering:!(t&&t.sortBy)}),a=this;if(Array.isArray(r))n=[e];else n=a._state.getHierarchicalFacetByName(r.name).attributes;return R((function(e,t){if(s.facetOrdering){var r=function(e,t){return e.renderingContent&&e.renderingContent.facetOrdering&&e.renderingContent.facetOrdering.values&&e.renderingContent.facetOrdering.values[t]}(a,t);if(r)return function(e,t){var r=[],n=[],i=t.hide||[],s=(t.order||[]).reduce((function(e,t,r){return e[t]=r,e}),{});e.forEach((function(e){var t=e.path||e.name,a=i.indexOf(t)>-1;a||void 0===s[t]?a||n.push(e):r[s[t]]=e})),r=r.filter((function(e){return e}));var a,c=t.sortRemainingBy;return"hidden"===c?r:(a="alpha"===c?[["path","name"],["asc","asc"]]:[["count"],["desc"]],r.concat(h(n,a[0],a[1])))}(e,r)}if(Array.isArray(s.sortBy)){var n=o(s.sortBy,g.DEFAULT_SORT);return h(e,n[0],n[1])}if("function"==typeof s.sortBy)return function(e,t){return t.sort(e)}(s.sortBy,e);throw new Error("options.sortBy is optional but if defined it must be either an array of string (predicates) or a sorting function")}),r,n)}},g.prototype.getFacetStats=function(e){return this._state.isConjunctiveFacet(e)?F(this.facets,e):this._state.isDisjunctiveFacet(e)?F(this.disjunctiveFacets,e):void 0},g.prototype.getRefinements=function(){var e=this._state,t=this,r=[];return Object.keys(e.facetsRefinements).forEach((function(n){e.facetsRefinements[n].forEach((function(i){r.push(b(e,"facet",n,i,t.facets))}))})),Object.keys(e.facetsExcludes).forEach((function(n){e.facetsExcludes[n].forEach((function(i){r.push(b(e,"exclude",n,i,t.facets))}))})),Object.keys(e.disjunctiveFacetsRefinements).forEach((function(n){e.disjunctiveFacetsRefinements[n].forEach((function(i){r.push(b(e,"disjunctive",n,i,t.disjunctiveFacets))}))})),Object.keys(e.hierarchicalFacetsRefinements).forEach((function(n){e.hierarchicalFacetsRefinements[n].forEach((function(i){r.push(function(e,t,r,n){var i=e.getHierarchicalFacetByName(t),s=e._getHierarchicalFacetSeparator(i),c=r.split(s),o=a(n,(function(e){return e.name===t})),u=c.reduce((function(e,t){var r=e&&a(e.data,(function(e){return e.name===t}));return void 0!==r?r:e}),o),h=u&&u.count||0,f=u&&u.exhaustive||!1,l=u&&u.path||"";return{type:"hierarchical",attributeName:t,name:l,count:h,exhaustive:f}}(e,n,i,t.hierarchicalFacets))}))})),Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t];Object.keys(n).forEach((function(e){n[e].forEach((function(n){r.push({type:"numeric",attributeName:t,name:n,numericValue:n,operator:e})}))}))})),e.tagRefinements.forEach((function(e){r.push({type:"tag",attributeName:"_tags",name:e})})),r},e.exports=g},36571:(e,t,r)=>{"use strict";var n=r(72733),i=r(46732),s=r(2909).escapeFacetValue,a=r(73014),c=r(44728),o=r(40317),u=r(21383),h=r(19127),f=r(42223),l=r(49228),m=r(33371),d=r(67691),p=r(57749),g=r(16938);function v(e,t,r,n){"function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+g+")"),this.setClient(e);var i=r||{};i.index=t,this.state=m.make(i),this.recommendState=new h({params:i.recommendState}),this.lastResults=null,this.lastRecommendResults=null,this._queryId=0,this._recommendQueryId=0,this._lastQueryIdReceived=-1,this._lastRecommendQueryIdReceived=-1,this.derivedHelpers=[],this._currentNbQueries=0,this._currentNbRecommendQueries=0,this._searchResultsOptions=n,this._recommendCache={}}function y(e){if(e<0)throw new Error("Page requested below 0.");return this._change({state:this.state.setPage(e),isPageReset:!1}),this}function R(){return this.state.page}a(v,n),v.prototype.search=function(){return this._search({onlyWithDerivedHelpers:!1}),this},v.prototype.searchOnlyWithDerivedHelpers=function(){return this._search({onlyWithDerivedHelpers:!0}),this},v.prototype.recommend=function(){return this._recommend(),this},v.prototype.getQuery=function(){var e=this.state;return l._getHitsSearchParams(e)},v.prototype.searchOnce=function(e,t){var r=e?this.state.setQueryParameters(e):this.state,n=l._getQueries(r.index,r),i=this;if(this._currentNbQueries++,this.emit("searchOnce",{state:r}),!t)return this.client.search(n).then((function(e){return i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),{content:new d(r,e.results),state:r,_originalResponse:e}}),(function(e){throw i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),e}));this.client.search(n).then((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(null,new d(r,e.results),r)})).catch((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(e,null,r)}))},v.prototype.findAnswers=function(e){console.warn("[algoliasearch-helper] answers is no longer supported");var t=this.state,r=this.derivedHelpers[0];if(!r)return Promise.resolve([]);var n=r.getModifiedState(t),i=c({attributesForPrediction:e.attributesForPrediction,nbHits:e.nbHits},{params:u(l._getHitsSearchParams(n),["attributesToSnippet","hitsPerPage","restrictSearchableAttributes","snippetEllipsisText"])}),s="search for answers was called, but this client does not have a function client.initIndex(index).findAnswers";if("function"!=typeof this.client.initIndex)throw new Error(s);var a=this.client.initIndex(n.index);if("function"!=typeof a.findAnswers)throw new Error(s);return a.findAnswers(n.query,e.queryLanguages,i)},v.prototype.searchForFacetValues=function(e,t,r,n){var i="function"==typeof this.client.searchForFacetValues,a="function"==typeof this.client.initIndex;if(!i&&!a&&"function"!=typeof this.client.search)throw new Error("search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues");var c=this.state.setQueryParameters(n||{}),o=c.isDisjunctiveFacet(e),u=l.getSearchForFacetQuery(e,t,r,c);this._currentNbQueries++;var h,f=this;return i?h=this.client.searchForFacetValues([{indexName:c.index,params:u}]):a?h=this.client.initIndex(c.index).searchForFacetValues(u):(delete u.facetName,h=this.client.search([{type:"facet",facet:e,indexName:c.index,params:u}]).then((function(e){return e.results[0]}))),this.emit("searchForFacetValues",{state:c,facet:e,query:t}),h.then((function(t){return f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),(t=Array.isArray(t)?t[0]:t).facetHits.forEach((function(t){t.escapedValue=s(t.value),t.isRefined=o?c.isDisjunctiveFacetRefined(e,t.escapedValue):c.isFacetRefined(e,t.escapedValue)})),t}),(function(e){throw f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),e}))},v.prototype.setQuery=function(e){return this._change({state:this.state.resetPage().setQuery(e),isPageReset:!0}),this},v.prototype.clearRefinements=function(e){return this._change({state:this.state.resetPage().clearRefinements(e),isPageReset:!0}),this},v.prototype.clearTags=function(){return this._change({state:this.state.resetPage().clearTags(),isPageReset:!0}),this},v.prototype.addDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addDisjunctiveRefine=function(){return this.addDisjunctiveFacetRefinement.apply(this,arguments)},v.prototype.addHierarchicalFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addHierarchicalFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().addNumericRefinement(e,t,r),isPageReset:!0}),this},v.prototype.addFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addRefine=function(){return this.addFacetRefinement.apply(this,arguments)},v.prototype.addFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().addExcludeRefinement(e,t),isPageReset:!0}),this},v.prototype.addExclude=function(){return this.addFacetExclusion.apply(this,arguments)},v.prototype.addTag=function(e){return this._change({state:this.state.resetPage().addTagRefinement(e),isPageReset:!0}),this},v.prototype.addFrequentlyBoughtTogether=function(e){return this._recommendChange({state:this.recommendState.addFrequentlyBoughtTogether(e)}),this},v.prototype.addRelatedProducts=function(e){return this._recommendChange({state:this.recommendState.addRelatedProducts(e)}),this},v.prototype.addTrendingItems=function(e){return this._recommendChange({state:this.recommendState.addTrendingItems(e)}),this},v.prototype.addTrendingFacets=function(e){return this._recommendChange({state:this.recommendState.addTrendingFacets(e)}),this},v.prototype.addLookingSimilar=function(e){return this._recommendChange({state:this.recommendState.addLookingSimilar(e)}),this},v.prototype.removeNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().removeNumericRefinement(e,t,r),isPageReset:!0}),this},v.prototype.removeDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.removeDisjunctiveRefine=function(){return this.removeDisjunctiveFacetRefinement.apply(this,arguments)},v.prototype.removeHierarchicalFacetRefinement=function(e){return this._change({state:this.state.resetPage().removeHierarchicalFacetRefinement(e),isPageReset:!0}),this},v.prototype.removeFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.removeRefine=function(){return this.removeFacetRefinement.apply(this,arguments)},v.prototype.removeFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().removeExcludeRefinement(e,t),isPageReset:!0}),this},v.prototype.removeExclude=function(){return this.removeFacetExclusion.apply(this,arguments)},v.prototype.removeTag=function(e){return this._change({state:this.state.resetPage().removeTagRefinement(e),isPageReset:!0}),this},v.prototype.removeFrequentlyBoughtTogether=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeRelatedProducts=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeTrendingItems=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeTrendingFacets=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeLookingSimilar=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.toggleFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().toggleExcludeFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.toggleExclude=function(){return this.toggleFacetExclusion.apply(this,arguments)},v.prototype.toggleRefinement=function(e,t){return this.toggleFacetRefinement(e,t)},v.prototype.toggleFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().toggleFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.toggleRefine=function(){return this.toggleFacetRefinement.apply(this,arguments)},v.prototype.toggleTag=function(e){return this._change({state:this.state.resetPage().toggleTagRefinement(e),isPageReset:!0}),this},v.prototype.nextPage=function(){var e=this.state.page||0;return this.setPage(e+1)},v.prototype.previousPage=function(){var e=this.state.page||0;return this.setPage(e-1)},v.prototype.setCurrentPage=y,v.prototype.setPage=y,v.prototype.setIndex=function(e){return this._change({state:this.state.resetPage().setIndex(e),isPageReset:!0}),this},v.prototype.setQueryParameter=function(e,t){return this._change({state:this.state.resetPage().setQueryParameter(e,t),isPageReset:!0}),this},v.prototype.setState=function(e){return this._change({state:m.make(e),isPageReset:!1}),this},v.prototype.overrideStateWithoutTriggeringChangeEvent=function(e){return this.state=new m(e),this},v.prototype.hasRefinements=function(e){return!!o(this.state.getNumericRefinements(e))||(this.state.isConjunctiveFacet(e)?this.state.isFacetRefined(e):this.state.isDisjunctiveFacet(e)?this.state.isDisjunctiveFacetRefined(e):!!this.state.isHierarchicalFacet(e)&&this.state.isHierarchicalFacetRefined(e))},v.prototype.isExcluded=function(e,t){return this.state.isExcludeRefined(e,t)},v.prototype.isDisjunctiveRefined=function(e,t){return this.state.isDisjunctiveFacetRefined(e,t)},v.prototype.hasTag=function(e){return this.state.isTagRefined(e)},v.prototype.isTagRefined=function(){return this.hasTagRefinements.apply(this,arguments)},v.prototype.getIndex=function(){return this.state.index},v.prototype.getCurrentPage=R,v.prototype.getPage=R,v.prototype.getTags=function(){return this.state.tagRefinements},v.prototype.getRefinements=function(e){var t=[];if(this.state.isConjunctiveFacet(e))this.state.getConjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"conjunctive"})})),this.state.getExcludeRefinements(e).forEach((function(e){t.push({value:e,type:"exclude"})}));else if(this.state.isDisjunctiveFacet(e)){this.state.getDisjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"disjunctive"})}))}var r=this.state.getNumericRefinements(e);return Object.keys(r).forEach((function(e){var n=r[e];t.push({value:n,operator:e,type:"numeric"})})),t},v.prototype.getNumericRefinement=function(e,t){return this.state.getNumericRefinement(e,t)},v.prototype.getHierarchicalFacetBreadcrumb=function(e){return this.state.getHierarchicalFacetBreadcrumb(e)},v.prototype._search=function(e){var t=this.state,r=[],n=[];e.onlyWithDerivedHelpers||(n=l._getQueries(t.index,t),r.push({state:t,queriesCount:n.length,helper:this}),this.emit("search",{state:t,results:this.lastResults}));var i=this.derivedHelpers.map((function(e){var n=e.getModifiedState(t),i=n.index?l._getQueries(n.index,n):[];return r.push({state:n,queriesCount:i.length,helper:e}),e.emit("search",{state:n,results:e.lastResults}),i})),s=Array.prototype.concat.apply(n,i),a=this._queryId++;if(this._currentNbQueries++,!s.length)return Promise.resolve({results:[]}).then(this._dispatchAlgoliaResponse.bind(this,r,a));try{this.client.search(s).then(this._dispatchAlgoliaResponse.bind(this,r,a)).catch(this._dispatchAlgoliaError.bind(this,a))}catch(c){this.emit("error",{error:c})}},v.prototype._recommend=function(){var e=this.state,t=this.recommendState,r=this.getIndex(),n=[{state:t,index:r,helper:this}],i=t.params.map((function(e){return e.$$id}));this.emit("fetch",{recommend:{state:t,results:this.lastRecommendResults}});var s=this._recommendCache,a=this.derivedHelpers.map((function(t){var r=t.getModifiedState(e).index;if(!r)return[];var a=t.getModifiedRecommendState(new h);return n.push({state:a,index:r,helper:t}),i=Array.prototype.concat.apply(i,a.params.map((function(e){return e.$$id}))),t.emit("fetch",{recommend:{state:a,results:t.lastRecommendResults}}),a._buildQueries(r,s)})),c=Array.prototype.concat.apply(this.recommendState._buildQueries(r,s),a);if(0!==c.length)if(c.length>0&&void 0===this.client.getRecommendations)console.warn("Please update algoliasearch/lite to the latest version in order to use recommend widgets.");else{var o=this._recommendQueryId++;this._currentNbRecommendQueries++;try{this.client.getRecommendations(c).then(this._dispatchRecommendResponse.bind(this,o,n,i)).catch(this._dispatchRecommendError.bind(this,o))}catch(u){this.emit("error",{error:u})}}},v.prototype._dispatchAlgoliaResponse=function(e,t,r){var n=this;if(!(t<this._lastQueryIdReceived)){this._currentNbQueries-=t-this._lastQueryIdReceived,this._lastQueryIdReceived=t,0===this._currentNbQueries&&this.emit("searchQueueEmpty");var i=r.results.slice();e.forEach((function(e){var t=e.state,r=e.queriesCount,s=e.helper,a=i.splice(0,r);t.index?(s.lastResults=new d(t,a,n._searchResultsOptions),s.emit("result",{results:s.lastResults,state:t})):s.emit("result",{results:null,state:t})}))}},v.prototype._dispatchRecommendResponse=function(e,t,r,n){if(!(e<this._lastRecommendQueryIdReceived)){this._currentNbRecommendQueries-=e-this._lastRecommendQueryIdReceived,this._lastRecommendQueryIdReceived=e,0===this._currentNbRecommendQueries&&this.emit("recommendQueueEmpty");var i=this._recommendCache,s={};r.filter((function(e){return void 0===i[e]})).forEach((function(e,t){s[e]||(s[e]=[]),s[e].push(t)})),Object.keys(s).forEach((function(e){var t=s[e],r=n.results[t[0]];1!==t.length?i[e]=Object.assign({},r,{hits:p(t.map((function(e){return n.results[e].hits})))}):i[e]=r}));var a={};r.forEach((function(e){a[e]=i[e]})),t.forEach((function(e){var t=e.state,r=e.helper;e.index?(r.lastRecommendResults=new f(t,a),r.emit("recommend:result",{recommend:{results:r.lastRecommendResults,state:t}})):r.emit("recommend:result",{results:null,state:t})}))}},v.prototype._dispatchAlgoliaError=function(e,t){e<this._lastQueryIdReceived||(this._currentNbQueries-=e-this._lastQueryIdReceived,this._lastQueryIdReceived=e,this.emit("error",{error:t}),0===this._currentNbQueries&&this.emit("searchQueueEmpty"))},v.prototype._dispatchRecommendError=function(e,t){e<this._lastRecommendQueryIdReceived||(this._currentNbRecommendQueries-=e-this._lastRecommendQueryIdReceived,this._lastRecommendQueryIdReceived=e,this.emit("error",{error:t}),0===this._currentNbRecommendQueries&&this.emit("recommendQueueEmpty"))},v.prototype.containsRefinement=function(e,t,r,n){return e||0!==t.length||0!==r.length||0!==n.length},v.prototype._hasDisjunctiveRefinements=function(e){return this.state.disjunctiveRefinements[e]&&this.state.disjunctiveRefinements[e].length>0},v.prototype._change=function(e){var t=e.state,r=e.isPageReset;t!==this.state&&(this.state=t,this.emit("change",{state:this.state,results:this.lastResults,isPageReset:r}))},v.prototype._recommendChange=function(e){var t=e.state;t!==this.recommendState&&(this.recommendState=t,this.emit("recommend:change",{search:{results:this.lastResults,state:this.state},recommend:{results:this.lastRecommendResults,state:this.recommendState}}))},v.prototype.clearCache=function(){return this.client.clearCache&&this.client.clearCache(),this},v.prototype.setClient=function(e){return this.client===e||("function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+g+")"),this.client=e),this},v.prototype.getClient=function(){return this.client},v.prototype.derive=function(e,t){var r=new i(this,e,t);return this.derivedHelpers.push(r),r},v.prototype.detachDerivedHelper=function(e){var t=this.derivedHelpers.indexOf(e);if(-1===t)throw new Error("Derived helper already detached");this.derivedHelpers.splice(t,1)},v.prototype.hasPendingRequests=function(){return this._currentNbQueries>0},e.exports=v},78965:e=>{"use strict";e.exports=function(e){return Array.isArray(e)?e.filter(Boolean):[]}},29110:e=>{"use strict";e.exports=function(){return Array.prototype.slice.call(arguments).reduceRight((function(e,t){return Object.keys(Object(t)).forEach((function(r){void 0!==t[r]&&(void 0!==e[r]&&delete e[r],e[r]=t[r])})),e}),{})}},2909:e=>{"use strict";e.exports={escapeFacetValue:function(e){return"string"!=typeof e?e:String(e).replace(/^-/,"\\-")},unescapeFacetValue:function(e){return"string"!=typeof e?e:e.replace(/^\\-/,"-")}}},20849:e=>{"use strict";e.exports=function(e,t){if(Array.isArray(e))for(var r=0;r<e.length;r++)if(t(e[r]))return e[r]}},43917:e=>{"use strict";e.exports=function(e,t){if(!Array.isArray(e))return-1;for(var r=0;r<e.length;r++)if(t(e[r]))return r;return-1}},38657:e=>{e.exports=function(e){return e.reduce((function(e,t){return e.concat(t)}),[])}},7577:(e,t,r)=>{"use strict";var n=r(20849);e.exports=function(e,t){var r=(t||[]).map((function(e){return e.split(":")}));return e.reduce((function(e,t){var i=t.split(":"),s=n(r,(function(e){return e[0]===i[0]}));return i.length>1||!s?(e[0].push(i[0]),e[1].push(i[1]),e):(e[0].push(s[0]),e[1].push(s[1]),e)}),[[],[]])}},73014:e=>{"use strict";e.exports=function(e,t){e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}},14843:e=>{"use strict";e.exports=function(e,t){return e.filter((function(r,n){return t.indexOf(r)>-1&&e.indexOf(r)===n}))}},44728:e=>{"use strict";function t(e){return"function"==typeof e||Array.isArray(e)||"[object Object]"===Object.prototype.toString.call(e)}function r(e,n){if(e===n)return e;for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)&&"__proto__"!==i&&"constructor"!==i){var s=n[i],a=e[i];void 0!==a&&void 0===s||(t(a)&&t(s)?e[i]=r(a,s):e[i]="object"==typeof(c=s)&&null!==c?r(Array.isArray(c)?[]:{},c):c)}var c;return e}e.exports=function(e){t(e)||(e={});for(var n=1,i=arguments.length;n<i;n++){var s=arguments[n];t(s)&&r(e,s)}return e}},40317:e=>{"use strict";e.exports=function(e){return e&&Object.keys(e).length>0}},21383:e=>{"use strict";e.exports=function(e,t){if(null===e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}},38601:e=>{"use strict";function t(e,t){if(e!==t){var r=void 0!==e,n=null===e,i=void 0!==t,s=null===t;if(!s&&e>t||n&&i||!r)return 1;if(!n&&e<t||s&&r||!i)return-1}return 0}e.exports=function(e,r,n){if(!Array.isArray(e))return[];Array.isArray(n)||(n=[]);var i=e.map((function(e,t){return{criteria:r.map((function(t){return e[t]})),index:t,value:e}}));return i.sort((function(e,r){for(var i=-1;++i<e.criteria.length;){var s=t(e.criteria[i],r.criteria[i]);if(s)return i>=n.length?s:"desc"===n[i]?-s:s}return e.index-r.index})),i.map((function(e){return e.value}))}},17507:e=>{"use strict";e.exports=function e(t){if("number"==typeof t)return t;if("string"==typeof t)return parseFloat(t);if(Array.isArray(t))return t.map(e);throw new Error("The value should be a number, a parsable string or an array of those.")}},49228:(e,t,r)=>{"use strict";var n=r(44728);function i(e){return Object.keys(e).sort().reduce((function(t,r){return t[r]=e[r],t}),{})}var s={_getQueries:function(e,t){var r=[];return r.push({indexName:e,params:s._getHitsSearchParams(t)}),t.getRefinedDisjunctiveFacets().forEach((function(n){r.push({indexName:e,params:s._getDisjunctiveFacetSearchParams(t,n)})})),t.getRefinedHierarchicalFacets().forEach((function(n){var i=t.getHierarchicalFacetByName(n),a=t.getHierarchicalRefinement(n),c=t._getHierarchicalFacetSeparator(i);if(a.length>0&&a[0].split(c).length>1){var o=a[0].split(c).slice(0,-1).reduce((function(e,t,r){return e.concat({attribute:i.attributes[r],value:0===r?t:[e[e.length-1].value,t].join(c)})}),[]);o.forEach((function(n,a){var c=s._getDisjunctiveFacetSearchParams(t,n.attribute,0===a);function u(e){return i.attributes.some((function(t){return t===e.split(":")[0]}))}var h=(c.facetFilters||[]).reduce((function(e,t){if(Array.isArray(t)){var r=t.filter((function(e){return!u(e)}));r.length>0&&e.push(r)}return"string"!=typeof t||u(t)||e.push(t),e}),[]),f=o[a-1];c.facetFilters=a>0?h.concat(f.attribute+":"+f.value):h.length>0?h:void 0,r.push({indexName:e,params:c})}))}})),r},_getHitsSearchParams:function(e){var t=e.facets.concat(e.disjunctiveFacets).concat(s._getHitsHierarchicalFacetsAttributes(e)).sort(),r=s._getFacetFilters(e),a=s._getNumericFilters(e),c=s._getTagFilters(e),o={};return t.length>0&&(o.facets=t.indexOf("*")>-1?["*"]:t),c.length>0&&(o.tagFilters=c),r.length>0&&(o.facetFilters=r),a.length>0&&(o.numericFilters=a),i(n({},e.getQueryParams(),o))},_getDisjunctiveFacetSearchParams:function(e,t,r){var a=s._getFacetFilters(e,t,r),c=s._getNumericFilters(e,t),o=s._getTagFilters(e),u={hitsPerPage:0,page:0,analytics:!1,clickAnalytics:!1};o.length>0&&(u.tagFilters=o);var h=e.getHierarchicalFacetByName(t);return u.facets=h?s._getDisjunctiveHierarchicalFacetAttribute(e,h,r):t,c.length>0&&(u.numericFilters=c),a.length>0&&(u.facetFilters=a),i(n({},e.getQueryParams(),u))},_getNumericFilters:function(e,t){if(e.numericFilters)return e.numericFilters;var r=[];return Object.keys(e.numericRefinements).forEach((function(n){var i=e.numericRefinements[n]||{};Object.keys(i).forEach((function(e){var s=i[e]||[];t!==n&&s.forEach((function(t){if(Array.isArray(t)){var i=t.map((function(t){return n+e+t}));r.push(i)}else r.push(n+e+t)}))}))})),r},_getTagFilters:function(e){return e.tagFilters?e.tagFilters:e.tagRefinements.join(",")},_getFacetFilters:function(e,t,r){var n=[],i=e.facetsRefinements||{};Object.keys(i).sort().forEach((function(e){(i[e]||[]).slice().sort().forEach((function(t){n.push(e+":"+t)}))}));var s=e.facetsExcludes||{};Object.keys(s).sort().forEach((function(e){(s[e]||[]).sort().forEach((function(t){n.push(e+":-"+t)}))}));var a=e.disjunctiveFacetsRefinements||{};Object.keys(a).sort().forEach((function(e){var r=a[e]||[];if(e!==t&&r&&0!==r.length){var i=[];r.slice().sort().forEach((function(t){i.push(e+":"+t)})),n.push(i)}}));var c=e.hierarchicalFacetsRefinements||{};return Object.keys(c).sort().forEach((function(i){var s=(c[i]||[])[0];if(void 0!==s){var a,o,u=e.getHierarchicalFacetByName(i),h=e._getHierarchicalFacetSeparator(u),f=e._getHierarchicalRootPath(u);if(t===i){if(-1===s.indexOf(h)||!f&&!0===r||f&&f.split(h).length===s.split(h).length)return;f?(o=f.split(h).length-1,s=f):(o=s.split(h).length-2,s=s.slice(0,s.lastIndexOf(h))),a=u.attributes[o]}else o=s.split(h).length-1,a=u.attributes[o];a&&n.push([a+":"+s])}})),n},_getHitsHierarchicalFacetsAttributes:function(e){return e.hierarchicalFacets.reduce((function(t,r){var n=e.getHierarchicalRefinement(r.name)[0];if(!n)return t.push(r.attributes[0]),t;var i=e._getHierarchicalFacetSeparator(r),s=n.split(i).length,a=r.attributes.slice(0,s+1);return t.concat(a)}),[])},_getDisjunctiveHierarchicalFacetAttribute:function(e,t,r){var n=e._getHierarchicalFacetSeparator(t);if(!0===r){var i=e._getHierarchicalRootPath(t),s=0;return i&&(s=i.split(n).length),[t.attributes[s]]}var a=(e.getHierarchicalRefinement(t.name)[0]||"").split(n).length-1;return t.attributes.slice(0,a+1)},getSearchForFacetQuery:function(e,t,r,a){var c=a.isDisjunctiveFacet(e)?a.clearRefinements(e):a,o={facetQuery:t,facetName:e};return"number"==typeof r&&(o.maxFacetHits=r),i(n({},s._getHitsSearchParams(c),o))}};e.exports=s},72208:e=>{"use strict";e.exports=function(e){return null!==e&&/^[a-zA-Z0-9_-]{1,64}$/.test(e)}},57749:(e,t,r)=>{"use strict";var n=r(20849),i=r(38657);e.exports=function(e){var t={};return e.forEach((function(e){e.forEach((function(e,r){t[e.objectID]?t[e.objectID]={indexSum:t[e.objectID].indexSum+r,count:t[e.objectID].count+1}:t[e.objectID]={indexSum:r,count:1}}))})),function(e,t){var r=[];return Object.keys(e).forEach((function(n){e[n].count<2&&(e[n].indexSum+=100),r.push({objectID:n,avgOfIndices:e[n].indexSum/t})})),r.sort((function(e,t){return e.avgOfIndices>t.avgOfIndices?1:-1}))}(t,e.length).reduce((function(t,r){var s=n(i(e),(function(e){return e.objectID===r.objectID}));return s?t.concat(s):t}),[])}},16938:e=>{"use strict";e.exports="3.22.1"},83643:function(e){e.exports=function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?t(Object(i),!0).forEach((function(t){e(r,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(i)):t(Object(i)).forEach((function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(i,e))}))}return r}function n(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var r=[],n=!0,i=!1,s=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){i=!0,s=e}finally{try{n||null==c.return||c.return()}finally{if(i)throw s}}return r}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function s(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t<e.length;t++)r[t]=e[t];return r}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(e){var t,r="algoliasearch-client-js-".concat(e.key),n=function(){return void 0===t&&(t=e.localStorage||window.localStorage),t},s=function(){return JSON.parse(n().getItem(r)||"{}")},a=function(e){n().setItem(r,JSON.stringify(e))},c=function(){var t=e.timeToLive?1e3*e.timeToLive:null,r=s(),n=Object.fromEntries(Object.entries(r).filter((function(e){return void 0!==i(e,2)[1].timestamp})));if(a(n),t){var c=Object.fromEntries(Object.entries(n).filter((function(e){var r=i(e,2)[1],n=(new Date).getTime();return!(r.timestamp+t<n)})));a(c)}};return{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){c();var t=JSON.stringify(e);return s()[t]})).then((function(e){return Promise.all([e?e.value:t(),void 0!==e])})).then((function(e){var t=i(e,2),n=t[0],s=t[1];return Promise.all([n,s||r.miss(n)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var i=s();return i[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:t},n().setItem(r,JSON.stringify(i)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=s();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function c(e){var t=s(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,i).catch((function(){return c({caches:t}).get(e,n,i)}))},set:function(e,n){return r.set(e,n).catch((function(){return c({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return c({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return c({caches:t}).clear()}))}}}function o(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},s=JSON.stringify(r);if(s in t)return Promise.resolve(e.serializable?JSON.parse(t[s]):t[s]);var a=n(),c=i&&i.miss||function(){return Promise.resolve()};return a.then((function(e){return c(e)})).then((function(){return a}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function u(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function h(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];var i=0;return e.replace(/%s/g,(function(){return encodeURIComponent(r[i++])}))}var l={WithinQueryParameters:0,WithinHeaders:1};function m(e,t){var r=e||{},n=r.data||{};return Object.keys(r).forEach((function(e){-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(n[e]=r[e])})),{data:Object.entries(n).length>0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var d={Read:1,Write:2,Any:3},p=1,g=2,v=3;function y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function R(e){return"string"==typeof e?{protocol:"https",url:e,accept:d.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||d.Any}}var F="GET",b="POST";function j(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(y(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===v&&Date.now()-e.lastUpdate<=12e4}(e)})),i=[].concat(s(r),s(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:i.length>0?i.map((function(e){return R(e)})):t}}))}function _(e,t,n,i){var a=[],c=function(e,t){if(e.method!==F&&(void 0!==e.data||void 0!==t.data)){var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}}(n,i),o=function(e,t){var n=r(r({},e.headers),t.headers),i={};return Object.keys(n).forEach((function(e){var t=n[e];i[e.toLowerCase()]=t})),i}(e,i),u=n.method,h=n.method!==F?{}:r(r({},n.data),i.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),h),i.queryParameters),l=0,m=function t(r,s){var h=r.pop();if(void 0===h)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, please reach out to the Algolia Support team: https://alg.li/support .",transporterStackTrace:O(a)};var m={data:c,headers:o,method:u,url:x(h,n.path,f),connectTimeout:s(l,e.timeouts.connect),responseTimeout:s(l,i.timeout)},d=function(e){var t={request:m,response:e,host:h,triesLeft:r.length};return a.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var i=d(n);return n.isTimedOut&&l++,Promise.all([e.logger.info("Retryable failure",w(i)),e.hostsCache.set(h,y(h,n.isTimedOut?v:g))]).then((function(){return t(r,s)}))},onFail:function(e){throw d(e),function(e,t){var r=e.content,n=e.status,i=r;try{i=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(i,n,t)}(e,O(a))}};return e.requester.send(m).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&!~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return j(e.hostsCache,t).then((function(e){return m(s(e.statelessHosts).reverse(),e.getTimeout)}))}function P(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function x(e,t,r){var n=E(r),i="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(i+="?".concat(n)),i}function E(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function O(e){return e.map((function(e){return w(e)}))}function w(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var S=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===l.WithinHeaders?n:{}},queryParameters:function(){return e===l.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:l.WithinHeaders,t,e.apiKey),s=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,s=e.requestsCache,a=e.responsesCache,c=e.timeouts,o=e.userAgent,u=e.hosts,h=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:s,responsesCache:a,timeouts:c,userAgent:o,headers:e.headers,queryParameters:h,hosts:u.map((function(e){return R(e)})),read:function(e,t){var r=m(t,f.timeouts.read),n=function(){return _(f,f.hosts.filter((function(e){return!!(e.accept&d.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var s={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(s,(function(){return f.requestsCache.get(s,(function(){return f.requestsCache.set(s,n()).then((function(e){return Promise.all([f.requestsCache.delete(s),e])}),(function(e){return Promise.all([f.requestsCache.delete(s),Promise.reject(e)])})).then((function(e){var t=i(e,2);return t[0],t[1]}))}))}),{miss:function(e){return f.responsesCache.set(s,e)}})},write:function(e,t){return _(f,f.hosts.filter((function(e){return!!(e.accept&d.Write)})),e,m(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:d.Read},{url:"".concat(t,".algolia.net"),accept:d.Write}].concat(u([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return h({transporter:s,appId:t,addAlgoliaAgent:function(e,t){s.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then((function(){}))}},e.methods)},A=function(e){return function(t,r){return t.method===F?e.transporter.read(t,r):e.transporter.write(t,r)}},N=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return h({transporter:e.transporter,appId:e.appId,indexName:t},r.methods)}},T=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{params:E(e.params||{})})}));return e.transporter.read({method:b,path:"1/indexes/*/queries",data:{requests:i},cacheable:!0},n)}},H=function(e){return function(t,i){return Promise.all(t.map((function(t){var s=t.params,a=s.facetName,c=s.facetQuery,o=n(s,["facetName","facetQuery"]);return N(e)(t.indexName,{methods:{searchForFacetValues:I}}).searchForFacetValues(a,c,r(r({},i),o))})))}},Q=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},C=function(e){return function(t,r){return e.transporter.read({method:b,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},I=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},D=1,k=2,q=3,L=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{threshold:e.threshold||0})}));return e.transporter.read({method:b,path:"1/indexes/*/recommendations",data:{requests:i},cacheable:!0},n)}};function V(e,t,n){var i,s={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,i=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},s=i(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(s),n=i(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(s),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(s),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(i=q,{debug:function(e,t){return D>=i&&console.debug(e,t),Promise.resolve()},info:function(e,t){return k>=i&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:o(),requestsCache:o({serializable:!1}),hostsCache:c({caches:[a({key:"".concat("4.24.0","-").concat(e)}),o()]}),userAgent:P("4.24.0").add({segment:"Browser",version:"lite"}),authMode:l.WithinQueryParameters};return S(r(r(r({},s),n),{},{methods:{search:T,searchForFacetValues:H,multipleQueries:T,multipleSearchForFacetValues:H,customRequest:A,initIndex:function(e){return function(t){return N(e)(t,{methods:{search:C,searchForFacetValues:I,findAnswers:Q}})}},getRecommendations:L}}))}return V.version="4.24.0",V}()},53465:(e,t,r)=>{"use strict";r.d(t,{W:()=>u});var n=r(96540),i=r(44586);const s=["zero","one","two","few","many","other"];function a(e){return s.filter((t=>e.includes(t)))}const c={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),c}}),[e])}function u(){const e=o();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const i=r.select(t),s=r.pluralForms.indexOf(i);return n[Math.min(s,n.length-1)]}(r,t,e)}}},74604:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>w});var n=r(96540),i=r(34164),s=r(74103),a=r.n(s),c=r(83643),o=r.n(c),u=r(38193),h=r(5260),f=r(28774),l=r(44070),m=r(53465),d=r(24255),p=r(89532),g=r(45500),v=r(20481),y=r(21312),R=r(44586),F=r(38126),b=r(51062),j=r(79201),_=r(51107);const P={searchQueryInput:"searchQueryInput_u2C7",searchVersionInput:"searchVersionInput_m0Ui",searchResultsColumn:"searchResultsColumn_JPFH",algoliaLogo:"algoliaLogo_rT1R",algoliaLogoPathFill:"algoliaLogoPathFill_WdUC",searchResultItem:"searchResultItem_Tv2o",searchResultItemHeading:"searchResultItemHeading_KbCB",searchResultItemPath:"searchResultItemPath_lhe1",searchResultItemSummary:"searchResultItemSummary_AEaO",searchQueryColumn:"searchQueryColumn_RTkw",searchVersionColumn:"searchVersionColumn_ypXd",searchLogoColumn:"searchLogoColumn_rJIA",loadingSpinner:"loadingSpinner_XVxU","loading-spin":"loading-spin_vzvp",loader:"loader_vvXV"};var x=r(74848);function E(e){let{docsSearchVersionsHelpers:t}=e;const r=Object.entries(t.allDocsData).filter((e=>{let[,t]=e;return t.versions.length>1}));return(0,x.jsx)("div",{className:(0,i.A)("col","col--3","padding-left--none",P.searchVersionColumn),children:r.map((e=>{let[n,i]=e;const s=r.length>1?`${n}: `:"";return(0,x.jsx)("select",{onChange:e=>t.setSearchVersion(n,e.target.value),defaultValue:t.searchVersions[n],className:P.searchVersionInput,children:i.versions.map(((e,t)=>(0,x.jsx)("option",{label:`${s}${e.label}`,value:e.name},t)))},n)}))})}function O(){const{i18n:{currentLocale:e}}=(0,R.A)(),{algolia:{appId:t,apiKey:r,indexName:s,contextualSearch:c}}=(0,F.c)(),g=(0,b.C)(),O=function(){const{selectMessage:e}=(0,m.W)();return t=>e(t,(0,y.T)({id:"theme.SearchPage.documentsFound.plurals",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One document found|{count} documents found"},{count:t}))}(),w=function(){const e=(0,l.Gy)(),[t,r]=(0,n.useState)((()=>Object.entries(e).reduce(((e,t)=>{let[r,n]=t;return{...e,[r]:n.versions[0].name}}),{}))),i=Object.values(e).some((e=>e.versions.length>1));return{allDocsData:e,versioningEnabled:i,searchVersions:t,setSearchVersion:(e,t)=>r((r=>({...r,[e]:t})))}}(),[S,A]=(0,d.b)(),N={items:[],query:null,totalResults:null,totalPages:null,lastPage:null,hasMore:null,loading:null},[T,H]=(0,n.useReducer)(((e,t)=>{switch(t.type){case"reset":return N;case"loading":return{...e,loading:!0};case"update":return S!==t.value.query?e:{...t.value,items:0===t.value.lastPage?t.value.items:e.items.concat(t.value.items)};case"advance":{const t=e.totalPages>e.lastPage+1;return{...e,lastPage:t?e.lastPage+1:e.lastPage,hasMore:t}}default:return e}}),N),Q=c?["language","docusaurus_tag"]:[],C=o()(t,r),I=a()(C,s,{hitsPerPage:15,advancedSyntax:!0,disjunctiveFacets:Q});I.on("result",(e=>{let{results:{query:t,hits:r,page:n,nbHits:i,nbPages:s}}=e;if(""===t||!Array.isArray(r))return void H({type:"reset"});const a=e=>e.replace(/algolia-docsearch-suggestion--highlight/g,"search-result-match"),c=r.map((e=>{let{url:t,_highlightResult:{hierarchy:r},_snippetResult:n={}}=e;const i=Object.keys(r).map((e=>a(r[e].value)));return{title:i.pop(),url:g(t),summary:n.content?`${a(n.content.value)}...`:"",breadcrumbs:i}}));H({type:"update",value:{items:c,query:t,totalResults:i,totalPages:s,lastPage:n,hasMore:s>n+1,loading:!1}})}));const[D,k]=(0,n.useState)(null),q=(0,n.useRef)(0),L=(0,n.useRef)(u.A.canUseIntersectionObserver&&new IntersectionObserver((e=>{const{isIntersecting:t,boundingClientRect:{y:r}}=e[0];t&&q.current>r&&H({type:"advance"}),q.current=r}),{threshold:1})),V=()=>S?(0,y.T)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:S}):(0,y.T)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"}),B=(0,p._q)((function(t){void 0===t&&(t=0),c&&(I.addDisjunctiveFacetRefinement("docusaurus_tag","default"),I.addDisjunctiveFacetRefinement("language",e),Object.entries(w.searchVersions).forEach((e=>{let[t,r]=e;I.addDisjunctiveFacetRefinement("docusaurus_tag",`docs-${t}-${r}`)}))),I.setQuery(S).setPage(t).search()}));return(0,n.useEffect)((()=>{if(!D)return;const e=L.current;return e?(e.observe(D),()=>e.unobserve(D)):()=>!0}),[D]),(0,n.useEffect)((()=>{H({type:"reset"}),S&&(H({type:"loading"}),setTimeout((()=>{B()}),300))}),[S,w.searchVersions,B]),(0,n.useEffect)((()=>{T.lastPage&&0!==T.lastPage&&B(T.lastPage)}),[B,T.lastPage]),(0,x.jsxs)(j.A,{children:[(0,x.jsxs)(h.A,{children:[(0,x.jsx)("title",{children:(0,v.s)(V())}),(0,x.jsx)("meta",{property:"robots",content:"noindex, follow"})]}),(0,x.jsxs)("div",{className:"container margin-vert--lg",children:[(0,x.jsx)(_.A,{as:"h1",children:V()}),(0,x.jsxs)("form",{className:"row",onSubmit:e=>e.preventDefault(),children:[(0,x.jsx)("div",{className:(0,i.A)("col",P.searchQueryColumn,{"col--9":w.versioningEnabled,"col--12":!w.versioningEnabled}),children:(0,x.jsx)("input",{type:"search",name:"q",className:P.searchQueryInput,placeholder:(0,y.T)({id:"theme.SearchPage.inputPlaceholder",message:"Type your search here",description:"The placeholder for search page input"}),"aria-label":(0,y.T)({id:"theme.SearchPage.inputLabel",message:"Search",description:"The ARIA label for search page input"}),onChange:e=>A(e.target.value),value:S,autoComplete:"off",autoFocus:!0})}),c&&w.versioningEnabled&&(0,x.jsx)(E,{docsSearchVersionsHelpers:w})]}),(0,x.jsxs)("div",{className:"row",children:[(0,x.jsx)("div",{className:(0,i.A)("col","col--8",P.searchResultsColumn),children:!!T.totalResults&&O(T.totalResults)}),(0,x.jsx)("div",{className:(0,i.A)("col","col--4","text--right",P.searchLogoColumn),children:(0,x.jsx)(f.A,{to:"https://www.algolia.com/","aria-label":(0,y.T)({id:"theme.SearchPage.algoliaLabel",message:"Search by Algolia",description:"The ARIA label for Algolia mention"}),children:(0,x.jsx)("svg",{viewBox:"0 0 168 24",className:P.algoliaLogo,children:(0,x.jsxs)("g",{fill:"none",children:[(0,x.jsx)("path",{className:P.algoliaLogoPathFill,d:"M120.925 18.804c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17zM6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z"}),(0,x.jsx)("path",{fill:"#5468FF",d:"M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938z"}),(0,x.jsx)("path",{fill:"white",d:"M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36"})]})})})})]}),T.items.length>0?(0,x.jsx)("main",{children:T.items.map(((e,t)=>{let{title:r,url:n,summary:s,breadcrumbs:a}=e;return(0,x.jsxs)("article",{className:P.searchResultItem,children:[(0,x.jsx)(_.A,{as:"h2",className:P.searchResultItemHeading,children:(0,x.jsx)(f.A,{to:n,dangerouslySetInnerHTML:{__html:r}})}),a.length>0&&(0,x.jsx)("nav",{"aria-label":"breadcrumbs",children:(0,x.jsx)("ul",{className:(0,i.A)("breadcrumbs",P.searchResultItemPath),children:a.map(((e,t)=>(0,x.jsx)("li",{className:"breadcrumbs__item",dangerouslySetInnerHTML:{__html:e}},t)))})}),s&&(0,x.jsx)("p",{className:P.searchResultItemSummary,dangerouslySetInnerHTML:{__html:s}})]},t)}))}):[S&&!T.loading&&(0,x.jsx)("p",{children:(0,x.jsx)(y.A,{id:"theme.SearchPage.noResultsText",description:"The paragraph for empty search result",children:"No results were found"})},"no-results"),!!T.loading&&(0,x.jsx)("div",{className:P.loadingSpinner},"spinner")],T.hasMore&&(0,x.jsx)("div",{className:P.loader,ref:k,children:(0,x.jsx)(y.A,{id:"theme.SearchPage.fetchingNewResults",description:"The paragraph for fetching new search results",children:"Fetching new results..."})})]})]})}function w(){return(0,x.jsx)(g.e3,{className:"search-page-wrapper",children:(0,x.jsx)(O,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1a4e3797.db7f4d3c.js.LICENSE.txt b/assets/js/1a4e3797.87166043.js.LICENSE.txt similarity index 100% rename from assets/js/1a4e3797.db7f4d3c.js.LICENSE.txt rename to assets/js/1a4e3797.87166043.js.LICENSE.txt diff --git a/assets/js/1a4e3797.db7f4d3c.js b/assets/js/1a4e3797.db7f4d3c.js deleted file mode 100644 index f3505c47f..000000000 --- a/assets/js/1a4e3797.db7f4d3c.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see 1a4e3797.db7f4d3c.js.LICENSE.txt */ -(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2138],{72733:e=>{function t(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function r(e){return"function"==typeof e}function n(e){return"object"==typeof e&&null!==e}function i(e){return void 0===e}e.exports=t,t.prototype._events=void 0,t.prototype._maxListeners=void 0,t.defaultMaxListeners=10,t.prototype.setMaxListeners=function(e){if("number"!=typeof e||e<0||isNaN(e))throw TypeError("n must be a positive number");return this._maxListeners=e,this},t.prototype.emit=function(e){var t,s,a,c,o,u;if(this._events||(this._events={}),"error"===e&&(!this._events.error||n(this._events.error)&&!this._events.error.length)){if((t=arguments[1])instanceof Error)throw t;var h=new Error('Uncaught, unspecified "error" event. ('+t+")");throw h.context=t,h}if(i(s=this._events[e]))return!1;if(r(s))switch(arguments.length){case 1:s.call(this);break;case 2:s.call(this,arguments[1]);break;case 3:s.call(this,arguments[1],arguments[2]);break;default:c=Array.prototype.slice.call(arguments,1),s.apply(this,c)}else if(n(s))for(c=Array.prototype.slice.call(arguments,1),a=(u=s.slice()).length,o=0;o<a;o++)u[o].apply(this,c);return!0},t.prototype.addListener=function(e,s){var a;if(!r(s))throw TypeError("listener must be a function");return this._events||(this._events={}),this._events.newListener&&this.emit("newListener",e,r(s.listener)?s.listener:s),this._events[e]?n(this._events[e])?this._events[e].push(s):this._events[e]=[this._events[e],s]:this._events[e]=s,n(this._events[e])&&!this._events[e].warned&&(a=i(this._maxListeners)?t.defaultMaxListeners:this._maxListeners)&&a>0&&this._events[e].length>a&&(this._events[e].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length),"function"==typeof console.trace&&console.trace()),this},t.prototype.on=t.prototype.addListener,t.prototype.once=function(e,t){if(!r(t))throw TypeError("listener must be a function");var n=!1;function i(){this.removeListener(e,i),n||(n=!0,t.apply(this,arguments))}return i.listener=t,this.on(e,i),this},t.prototype.removeListener=function(e,t){var i,s,a,c;if(!r(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(a=(i=this._events[e]).length,s=-1,i===t||r(i.listener)&&i.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(n(i)){for(c=a;c-- >0;)if(i[c]===t||i[c].listener&&i[c].listener===t){s=c;break}if(s<0)return this;1===i.length?(i.length=0,delete this._events[e]):i.splice(s,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},t.prototype.removeAllListeners=function(e){var t,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r(n=this._events[e]))this.removeListener(e,n);else if(n)for(;n.length;)this.removeListener(e,n[n.length-1]);return delete this._events[e],this},t.prototype.listeners=function(e){return this._events&&this._events[e]?r(this._events[e])?[this._events[e]]:this._events[e].slice():[]},t.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(r(t))return 1;if(t)return t.length}return 0},t.listenerCount=function(e,t){return e.listenerCount(t)}},74103:(e,t,r)=>{"use strict";var n=r(36571),i=r(19127),s=r(42223),a=r(33371),c=r(67691);function o(e,t,r,i){return new n(e,t,r,i)}o.version=r(16938),o.AlgoliaSearchHelper=n,o.SearchParameters=a,o.RecommendParameters=i,o.SearchResults=c,o.RecommendResults=s,e.exports=o},46732:(e,t,r)=>{"use strict";var n=r(72733);function i(e,t,r){this.main=e,this.fn=t,this.recommendFn=r,this.lastResults=null,this.lastRecommendResults=null}r(73014)(i,n),i.prototype.detach=function(){this.removeAllListeners(),this.main.detachDerivedHelper(this)},i.prototype.getModifiedState=function(e){return this.fn(e)},i.prototype.getModifiedRecommendState=function(e){return this.recommendFn(e)},e.exports=i},19127:e=>{"use strict";function t(e){e=e||{},this.params=e.params||[]}t.prototype={constructor:t,addParams:function(e){var r=this.params.slice();return r.push(e),new t({params:r})},removeParams:function(e){return new t({params:this.params.filter((function(t){return t.$$id!==e}))})},addFrequentlyBoughtTogether:function(e){return this.addParams(Object.assign({},e,{model:"bought-together"}))},addRelatedProducts:function(e){return this.addParams(Object.assign({},e,{model:"related-products"}))},addTrendingItems:function(e){return this.addParams(Object.assign({},e,{model:"trending-items"}))},addTrendingFacets:function(e){return this.addParams(Object.assign({},e,{model:"trending-facets"}))},addLookingSimilar:function(e){return this.addParams(Object.assign({},e,{model:"looking-similar"}))},_buildQueries:function(e,t){return this.params.filter((function(e){return void 0===t[e.$$id]})).map((function(t){var r=Object.assign({},t,{indexName:e});return delete r.$$id,r}))}},e.exports=t},42223:e=>{"use strict";function t(e,t){this._state=e,this._rawResults={};var r=this;e.params.forEach((function(e){var n=e.$$id;r[n]=t[n],r._rawResults[n]=t[n]}))}t.prototype={constructor:t},e.exports=t},44054:(e,t,r)=>{"use strict";var n=r(29110),i=r(40317),s=r(21383),a={addRefinement:function(e,t,r){if(a.isRefined(e,t,r))return e;var i=""+r,s=e[t]?e[t].concat(i):[i],c={};return c[t]=s,n({},c,e)},removeRefinement:function(e,t,r){if(void 0===r)return a.clearRefinement(e,(function(e,r){return t===r}));var n=""+r;return a.clearRefinement(e,(function(e,r){return t===r&&n===e}))},toggleRefinement:function(e,t,r){if(void 0===r)throw new Error("toggleRefinement should be used with a value");return a.isRefined(e,t,r)?a.removeRefinement(e,t,r):a.addRefinement(e,t,r)},clearRefinement:function(e,t,r){if(void 0===t)return i(e)?{}:e;if("string"==typeof t)return s(e,[t]);if("function"==typeof t){var n=!1,a=Object.keys(e).reduce((function(i,s){var a=e[s]||[],c=a.filter((function(e){return!t(e,s,r)}));return c.length!==a.length&&(n=!0),i[s]=c,i}),{});return n?a:e}},isRefined:function(e,t,r){var n=Boolean(e[t])&&e[t].length>0;if(void 0===r||!n)return n;var i=""+r;return-1!==e[t].indexOf(i)}};e.exports=a},33371:(e,t,r)=>{"use strict";var n=r(29110),i=r(20849),s=r(14843),a=r(44728),c=r(40317),o=r(21383),u=r(17507),h=r(72208),f=r(44054);function l(e,t){return Array.isArray(e)&&Array.isArray(t)?e.length===t.length&&e.every((function(e,r){return l(t[r],e)})):e===t}function m(e){var t=e?m._parseNumbers(e):{};void 0===t.userToken||h(t.userToken)||console.warn("[algoliasearch-helper] The `userToken` parameter is invalid. This can lead to wrong analytics.\n - Format: [a-zA-Z0-9_-]{1,64}"),this.facets=t.facets||[],this.disjunctiveFacets=t.disjunctiveFacets||[],this.hierarchicalFacets=t.hierarchicalFacets||[],this.facetsRefinements=t.facetsRefinements||{},this.facetsExcludes=t.facetsExcludes||{},this.disjunctiveFacetsRefinements=t.disjunctiveFacetsRefinements||{},this.numericRefinements=t.numericRefinements||{},this.tagRefinements=t.tagRefinements||[],this.hierarchicalFacetsRefinements=t.hierarchicalFacetsRefinements||{};var r=this;Object.keys(t).forEach((function(e){var n=-1!==m.PARAMETERS.indexOf(e),i=void 0!==t[e];!n&&i&&(r[e]=t[e])}))}m.PARAMETERS=Object.keys(new m),m._parseNumbers=function(e){if(e instanceof m)return e;var t={};if(["aroundPrecision","aroundRadius","getRankingInfo","minWordSizefor2Typos","minWordSizefor1Typo","page","maxValuesPerFacet","distinct","minimumAroundRadius","hitsPerPage","minProximity"].forEach((function(r){var n=e[r];if("string"==typeof n){var i=parseFloat(n);t[r]=isNaN(i)?n:i}})),Array.isArray(e.insideBoundingBox)&&(t.insideBoundingBox=e.insideBoundingBox.map((function(e){return Array.isArray(e)?e.map((function(e){return parseFloat(e)})):e}))),e.numericRefinements){var r={};Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t]||{};r[t]={},Object.keys(n).forEach((function(e){var i=n[e].map((function(e){return Array.isArray(e)?e.map((function(e){return"string"==typeof e?parseFloat(e):e})):"string"==typeof e?parseFloat(e):e}));r[t][e]=i}))})),t.numericRefinements=r}return a(e,t)},m.make=function(e){var t=new m(e);return(e.hierarchicalFacets||[]).forEach((function(e){if(e.rootPath){var r=t.getHierarchicalRefinement(e.name);r.length>0&&0!==r[0].indexOf(e.rootPath)&&(t=t.clearRefinements(e.name)),0===(r=t.getHierarchicalRefinement(e.name)).length&&(t=t.toggleHierarchicalFacetRefinement(e.name,e.rootPath))}})),t},m.validate=function(e,t){var r=t||{};return e.tagFilters&&r.tagRefinements&&r.tagRefinements.length>0?new Error("[Tags] Cannot switch from the managed tag API to the advanced API. It is probably an error, if it is really what you want, you should first clear the tags with clearTags method."):e.tagRefinements.length>0&&r.tagFilters?new Error("[Tags] Cannot switch from the advanced tag API to the managed API. It is probably an error, if it is not, you should first clear the tags with clearTags method."):e.numericFilters&&r.numericRefinements&&c(r.numericRefinements)?new Error("[Numeric filters] Can't switch from the advanced to the managed API. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):c(e.numericRefinements)&&r.numericFilters?new Error("[Numeric filters] Can't switch from the managed API to the advanced. It is probably an error, if this is really what you want, you have to first clear the numeric filters."):null},m.prototype={constructor:m,clearRefinements:function(e){var t={numericRefinements:this._clearNumericRefinements(e),facetsRefinements:f.clearRefinement(this.facetsRefinements,e,"conjunctiveFacet"),facetsExcludes:f.clearRefinement(this.facetsExcludes,e,"exclude"),disjunctiveFacetsRefinements:f.clearRefinement(this.disjunctiveFacetsRefinements,e,"disjunctiveFacet"),hierarchicalFacetsRefinements:f.clearRefinement(this.hierarchicalFacetsRefinements,e,"hierarchicalFacet")};return t.numericRefinements===this.numericRefinements&&t.facetsRefinements===this.facetsRefinements&&t.facetsExcludes===this.facetsExcludes&&t.disjunctiveFacetsRefinements===this.disjunctiveFacetsRefinements&&t.hierarchicalFacetsRefinements===this.hierarchicalFacetsRefinements?this:this.setQueryParameters(t)},clearTags:function(){return void 0===this.tagFilters&&0===this.tagRefinements.length?this:this.setQueryParameters({tagFilters:void 0,tagRefinements:[]})},setIndex:function(e){return e===this.index?this:this.setQueryParameters({index:e})},setQuery:function(e){return e===this.query?this:this.setQueryParameters({query:e})},setPage:function(e){return e===this.page?this:this.setQueryParameters({page:e})},setFacets:function(e){return this.setQueryParameters({facets:e})},setDisjunctiveFacets:function(e){return this.setQueryParameters({disjunctiveFacets:e})},setHitsPerPage:function(e){return this.hitsPerPage===e?this:this.setQueryParameters({hitsPerPage:e})},setTypoTolerance:function(e){return this.typoTolerance===e?this:this.setQueryParameters({typoTolerance:e})},addNumericRefinement:function(e,t,r){var n=u(r);if(this.isNumericRefined(e,t,n))return this;var i=a({},this.numericRefinements);return i[e]=a({},i[e]),i[e][t]?(i[e][t]=i[e][t].slice(),i[e][t].push(n)):i[e][t]=[n],this.setQueryParameters({numericRefinements:i})},getConjunctiveRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsRefinements[e]||[]},getDisjunctiveRefinements:function(e){return this.isDisjunctiveFacet(e)&&this.disjunctiveFacetsRefinements[e]||[]},getHierarchicalRefinement:function(e){return this.hierarchicalFacetsRefinements[e]||[]},getExcludeRefinements:function(e){return this.isConjunctiveFacet(e)&&this.facetsExcludes[e]||[]},removeNumericRefinement:function(e,t,r){var n=r;return void 0!==n?this.isNumericRefined(e,t,n)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,i){return i===e&&r.op===t&&l(r.val,u(n))}))}):this:void 0!==t?this.isNumericRefined(e,t)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(r,n){return n===e&&r.op===t}))}):this:this.isNumericRefined(e)?this.setQueryParameters({numericRefinements:this._clearNumericRefinements((function(t,r){return r===e}))}):this},getNumericRefinements:function(e){return this.numericRefinements[e]||{}},getNumericRefinement:function(e,t){return this.numericRefinements[e]&&this.numericRefinements[e][t]},_clearNumericRefinements:function(e){if(void 0===e)return c(this.numericRefinements)?{}:this.numericRefinements;if("string"==typeof e)return o(this.numericRefinements,[e]);if("function"==typeof e){var t=!1,r=this.numericRefinements,n=Object.keys(r).reduce((function(n,i){var s=r[i],a={};return s=s||{},Object.keys(s).forEach((function(r){var n=s[r]||[],c=[];n.forEach((function(t){e({val:t,op:r},i,"numeric")||c.push(t)})),c.length!==n.length&&(t=!0),a[r]=c})),n[i]=a,n}),{});return t?n:this.numericRefinements}},addFacet:function(e){return this.isConjunctiveFacet(e)?this:this.setQueryParameters({facets:this.facets.concat([e])})},addDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this:this.setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.concat([e])})},addHierarchicalFacet:function(e){if(this.isHierarchicalFacet(e.name))throw new Error("Cannot declare two hierarchical facets with the same name: `"+e.name+"`");return this.setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.concat([e])})},addFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this:this.setQueryParameters({facetsRefinements:f.addRefinement(this.facetsRefinements,e,t)})},addExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this:this.setQueryParameters({facetsExcludes:f.addRefinement(this.facetsExcludes,e,t)})},addDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this:this.setQueryParameters({disjunctiveFacetsRefinements:f.addRefinement(this.disjunctiveFacetsRefinements,e,t)})},addTagRefinement:function(e){if(this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.concat(e)};return this.setQueryParameters(t)},removeFacet:function(e){return this.isConjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({facets:this.facets.filter((function(t){return t!==e}))}):this},removeDisjunctiveFacet:function(e){return this.isDisjunctiveFacet(e)?this.clearRefinements(e).setQueryParameters({disjunctiveFacets:this.disjunctiveFacets.filter((function(t){return t!==e}))}):this},removeHierarchicalFacet:function(e){return this.isHierarchicalFacet(e)?this.clearRefinements(e).setQueryParameters({hierarchicalFacets:this.hierarchicalFacets.filter((function(t){return t.name!==e}))}):this},removeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsRefinements,e,t)?this.setQueryParameters({facetsRefinements:f.removeRefinement(this.facetsRefinements,e,t)}):this},removeExcludeRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return f.isRefined(this.facetsExcludes,e,t)?this.setQueryParameters({facetsExcludes:f.removeRefinement(this.facetsExcludes,e,t)}):this},removeDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return f.isRefined(this.disjunctiveFacetsRefinements,e,t)?this.setQueryParameters({disjunctiveFacetsRefinements:f.removeRefinement(this.disjunctiveFacetsRefinements,e,t)}):this},removeTagRefinement:function(e){if(!this.isTagRefined(e))return this;var t={tagRefinements:this.tagRefinements.filter((function(t){return t!==e}))};return this.setQueryParameters(t)},toggleRefinement:function(e,t){return this.toggleFacetRefinement(e,t)},toggleFacetRefinement:function(e,t){if(this.isHierarchicalFacet(e))return this.toggleHierarchicalFacetRefinement(e,t);if(this.isConjunctiveFacet(e))return this.toggleConjunctiveFacetRefinement(e,t);if(this.isDisjunctiveFacet(e))return this.toggleDisjunctiveFacetRefinement(e,t);throw new Error("Cannot refine the undeclared facet "+e+"; it should be added to the helper options facets, disjunctiveFacets or hierarchicalFacets")},toggleConjunctiveFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsRefinements:f.toggleRefinement(this.facetsRefinements,e,t)})},toggleExcludeFacetRefinement:function(e,t){if(!this.isConjunctiveFacet(e))throw new Error(e+" is not defined in the facets attribute of the helper configuration");return this.setQueryParameters({facetsExcludes:f.toggleRefinement(this.facetsExcludes,e,t)})},toggleDisjunctiveFacetRefinement:function(e,t){if(!this.isDisjunctiveFacet(e))throw new Error(e+" is not defined in the disjunctiveFacets attribute of the helper configuration");return this.setQueryParameters({disjunctiveFacetsRefinements:f.toggleRefinement(this.disjunctiveFacetsRefinements,e,t)})},toggleHierarchicalFacetRefinement:function(e,t){if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration");var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e)),i={};return void 0!==this.hierarchicalFacetsRefinements[e]&&this.hierarchicalFacetsRefinements[e].length>0&&(this.hierarchicalFacetsRefinements[e][0]===t||0===this.hierarchicalFacetsRefinements[e][0].indexOf(t+r))?-1===t.indexOf(r)?i[e]=[]:i[e]=[t.slice(0,t.lastIndexOf(r))]:i[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},i,this.hierarchicalFacetsRefinements)})},addHierarchicalFacetRefinement:function(e,t){if(this.isHierarchicalFacetRefined(e))throw new Error(e+" is already refined.");if(!this.isHierarchicalFacet(e))throw new Error(e+" is not defined in the hierarchicalFacets attribute of the helper configuration.");var r={};return r[e]=[t],this.setQueryParameters({hierarchicalFacetsRefinements:n({},r,this.hierarchicalFacetsRefinements)})},removeHierarchicalFacetRefinement:function(e){if(!this.isHierarchicalFacetRefined(e))return this;var t={};return t[e]=[],this.setQueryParameters({hierarchicalFacetsRefinements:n({},t,this.hierarchicalFacetsRefinements)})},toggleTagRefinement:function(e){return this.isTagRefined(e)?this.removeTagRefinement(e):this.addTagRefinement(e)},isDisjunctiveFacet:function(e){return this.disjunctiveFacets.indexOf(e)>-1},isHierarchicalFacet:function(e){return void 0!==this.getHierarchicalFacetByName(e)},isConjunctiveFacet:function(e){return this.facets.indexOf(e)>-1},isFacetRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsRefinements,e,t)},isExcludeRefined:function(e,t){return!!this.isConjunctiveFacet(e)&&f.isRefined(this.facetsExcludes,e,t)},isDisjunctiveFacetRefined:function(e,t){return!!this.isDisjunctiveFacet(e)&&f.isRefined(this.disjunctiveFacetsRefinements,e,t)},isHierarchicalFacetRefined:function(e,t){if(!this.isHierarchicalFacet(e))return!1;var r=this.getHierarchicalRefinement(e);return t?-1!==r.indexOf(t):r.length>0},isNumericRefined:function(e,t,r){if(void 0===r&&void 0===t)return Boolean(this.numericRefinements[e]);var n=this.numericRefinements[e]&&void 0!==this.numericRefinements[e][t];if(void 0===r||!n)return n;var s,a,c=u(r),o=void 0!==(s=this.numericRefinements[e][t],a=c,i(s,(function(e){return l(e,a)})));return n&&o},isTagRefined:function(e){return-1!==this.tagRefinements.indexOf(e)},getRefinedDisjunctiveFacets:function(){var e=this,t=s(Object.keys(this.numericRefinements).filter((function(t){return Object.keys(e.numericRefinements[t]).length>0})),this.disjunctiveFacets);return Object.keys(this.disjunctiveFacetsRefinements).filter((function(t){return e.disjunctiveFacetsRefinements[t].length>0})).concat(t).concat(this.getRefinedHierarchicalFacets()).sort()},getRefinedHierarchicalFacets:function(){var e=this;return s(this.hierarchicalFacets.map((function(e){return e.name})),Object.keys(this.hierarchicalFacetsRefinements).filter((function(t){return e.hierarchicalFacetsRefinements[t].length>0}))).sort()},getUnrefinedDisjunctiveFacets:function(){var e=this.getRefinedDisjunctiveFacets();return this.disjunctiveFacets.filter((function(t){return-1===e.indexOf(t)}))},managedParameters:["index","facets","disjunctiveFacets","facetsRefinements","hierarchicalFacets","facetsExcludes","disjunctiveFacetsRefinements","numericRefinements","tagRefinements","hierarchicalFacetsRefinements"],getQueryParams:function(){var e=this.managedParameters,t={},r=this;return Object.keys(this).forEach((function(n){var i=r[n];-1===e.indexOf(n)&&void 0!==i&&(t[n]=i)})),t},setQueryParameter:function(e,t){if(this[e]===t)return this;var r={};return r[e]=t,this.setQueryParameters(r)},setQueryParameters:function(e){if(!e)return this;var t=m.validate(this,e);if(t)throw t;var r=this,n=m._parseNumbers(e),i=Object.keys(this).reduce((function(e,t){return e[t]=r[t],e}),{}),s=Object.keys(n).reduce((function(e,t){var r=void 0!==e[t],i=void 0!==n[t];return r&&!i?o(e,[t]):(i&&(e[t]=n[t]),e)}),i);return new this.constructor(s)},resetPage:function(){return void 0===this.page?this:this.setPage(0)},_getHierarchicalFacetSortBy:function(e){return e.sortBy||["isRefined:desc","name:asc"]},_getHierarchicalFacetSeparator:function(e){return e.separator||" > "},_getHierarchicalRootPath:function(e){return e.rootPath||null},_getHierarchicalShowParentLevel:function(e){return"boolean"!=typeof e.showParentLevel||e.showParentLevel},getHierarchicalFacetByName:function(e){return i(this.hierarchicalFacets,(function(t){return t.name===e}))},getHierarchicalFacetBreadcrumb:function(e){if(!this.isHierarchicalFacet(e))return[];var t=this.getHierarchicalRefinement(e)[0];if(!t)return[];var r=this._getHierarchicalFacetSeparator(this.getHierarchicalFacetByName(e));return t.split(r).map((function(e){return e.trim()}))},toString:function(){return JSON.stringify(this,null,2)}},e.exports=m},76673:(e,t,r)=>{"use strict";e.exports=function(e){return function(t,r){var n=e.hierarchicalFacets[r],u=e.hierarchicalFacetsRefinements[n.name]&&e.hierarchicalFacetsRefinements[n.name][0]||"",h=e._getHierarchicalFacetSeparator(n),f=e._getHierarchicalRootPath(n),l=e._getHierarchicalShowParentLevel(n),m=s(e._getHierarchicalFacetSortBy(n)),d=t.every((function(e){return e.exhaustive})),p=function(e,t,r,n,s){return function(u,h,f){var l=u;if(f>0){var m=0;for(l=u;m<f;){var d=l&&Array.isArray(l.data)?l.data:[];l=i(d,(function(e){return e.isRefined})),m++}}if(l){var p=Object.keys(h.data).map((function(e){return[e,h.data[e]]})).filter((function(e){return function(e,t,r,n,i,s){if(i&&(0!==e.indexOf(i)||i===e))return!1;return!i&&-1===e.indexOf(n)||i&&e.split(n).length-i.split(n).length==1||-1===e.indexOf(n)&&-1===r.indexOf(n)||0===r.indexOf(e)||0===e.indexOf(t+n)&&(s||0===e.indexOf(r))}(e[0],l.path||r,s,t,r,n)}));l.data=a(p.map((function(e){var r=e[0];return function(e,t,r,n,i){var s=t.split(r);return{name:s[s.length-1].trim(),path:t,escapedValue:c(t),count:e,isRefined:n===t||0===n.indexOf(t+r),exhaustive:i,data:null}}(e[1],r,t,o(s),h.exhaustive)})),e[0],e[1])}return u}}(m,h,f,l,u),g=t;return f&&(g=t.slice(f.split(h).length)),g.reduce(p,{name:e.hierarchicalFacets[r].name,count:null,isRefined:!0,path:null,escapedValue:null,exhaustive:d,data:null})}};var n=r(2909),i=r(20849),s=r(7577),a=r(38601),c=n.escapeFacetValue,o=n.unescapeFacetValue},67691:(e,t,r)=>{"use strict";var n=r(78965),i=r(29110),s=r(2909),a=r(20849),c=r(43917),o=r(7577),u=r(44728),h=r(38601),f=s.escapeFacetValue,l=s.unescapeFacetValue,m=r(76673);function d(e){var t={};return e.forEach((function(e,r){t[e]=r})),t}function p(e,t,r){t&&t[r]&&(e.stats=t[r])}function g(e,t,r){var s=t[0]||{};this._rawResults=t;var o=this;Object.keys(s).forEach((function(e){o[e]=s[e]}));var h=u({persistHierarchicalRootCount:!1},r);Object.keys(h).forEach((function(e){o[e]=h[e]})),this.processingTimeMS=t.reduce((function(e,t){return void 0===t.processingTimeMS?e:e+t.processingTimeMS}),0),this.disjunctiveFacets=[],this.hierarchicalFacets=e.hierarchicalFacets.map((function(){return[]})),this.facets=[];var f=e.getRefinedDisjunctiveFacets(),g=d(e.facets),v=d(e.disjunctiveFacets),y=1,R=s.facets||{};Object.keys(R).forEach((function(t){var r,n,i=R[t],u=(r=e.hierarchicalFacets,n=t,a(r,(function(e){return(e.attributes||[]).indexOf(n)>-1})));if(u){var h=u.attributes.indexOf(t),f=c(e.hierarchicalFacets,(function(e){return e.name===u.name}));o.hierarchicalFacets[f][h]={attribute:t,data:i,exhaustive:s.exhaustiveFacetsCount}}else{var l,m=-1!==e.disjunctiveFacets.indexOf(t),d=-1!==e.facets.indexOf(t);m&&(l=v[t],o.disjunctiveFacets[l]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(o.disjunctiveFacets[l],s.facets_stats,t)),d&&(l=g[t],o.facets[l]={name:t,data:i,exhaustive:s.exhaustiveFacetsCount},p(o.facets[l],s.facets_stats,t))}})),this.hierarchicalFacets=n(this.hierarchicalFacets),f.forEach((function(r){var n=t[y],a=n&&n.facets?n.facets:{},h=e.getHierarchicalFacetByName(r);Object.keys(a).forEach((function(t){var r,f=a[t];if(h){r=c(e.hierarchicalFacets,(function(e){return e.name===h.name}));var m=c(o.hierarchicalFacets[r],(function(e){return e.attribute===t}));if(-1===m)return;o.hierarchicalFacets[r][m].data=u({},o.hierarchicalFacets[r][m].data,f)}else{r=v[t];var d=s.facets&&s.facets[t]||{};o.disjunctiveFacets[r]={name:t,data:i({},f,d),exhaustive:n.exhaustiveFacetsCount},p(o.disjunctiveFacets[r],n.facets_stats,t),e.disjunctiveFacetsRefinements[t]&&e.disjunctiveFacetsRefinements[t].forEach((function(n){!o.disjunctiveFacets[r].data[n]&&e.disjunctiveFacetsRefinements[t].indexOf(l(n))>-1&&(o.disjunctiveFacets[r].data[n]=0)}))}})),y++})),e.getRefinedHierarchicalFacets().forEach((function(r){var n=e.getHierarchicalFacetByName(r),s=e._getHierarchicalFacetSeparator(n),a=e.getHierarchicalRefinement(r);0===a.length||a[0].split(s).length<2||t.slice(y).forEach((function(t){var r=t&&t.facets?t.facets:{};Object.keys(r).forEach((function(t){var u=r[t],h=c(e.hierarchicalFacets,(function(e){return e.name===n.name})),f=c(o.hierarchicalFacets[h],(function(e){return e.attribute===t}));if(-1!==f){var l={};if(a.length>0&&!o.persistHierarchicalRootCount){var m=a[0].split(s)[0];l[m]=o.hierarchicalFacets[h][f].data[m]}o.hierarchicalFacets[h][f].data=i(l,u,o.hierarchicalFacets[h][f].data)}})),y++}))})),Object.keys(e.facetsExcludes).forEach((function(t){var r=e.facetsExcludes[t],n=g[t];o.facets[n]={name:t,data:R[t],exhaustive:s.exhaustiveFacetsCount},r.forEach((function(e){o.facets[n]=o.facets[n]||{name:t},o.facets[n].data=o.facets[n].data||{},o.facets[n].data[e]=0}))})),this.hierarchicalFacets=this.hierarchicalFacets.map(m(e)),this.facets=n(this.facets),this.disjunctiveFacets=n(this.disjunctiveFacets),this._state=e}function v(e,t){function r(e){return e.name===t}if(e._state.isConjunctiveFacet(t)){var n=a(e.facets,r);return n?Object.keys(n.data).map((function(r){var i=f(r);return{name:r,escapedValue:i,count:n.data[r],isRefined:e._state.isFacetRefined(t,i),isExcluded:e._state.isExcludeRefined(t,r)}})):[]}if(e._state.isDisjunctiveFacet(t)){var i=a(e.disjunctiveFacets,r);return i?Object.keys(i.data).map((function(r){var n=f(r);return{name:r,escapedValue:n,count:i.data[r],isRefined:e._state.isDisjunctiveFacetRefined(t,n)}})):[]}if(e._state.isHierarchicalFacet(t)){var s=a(e.hierarchicalFacets,r);if(!s)return s;var c=e._state.getHierarchicalFacetByName(t),o=e._state._getHierarchicalFacetSeparator(c),u=l(e._state.getHierarchicalRefinement(t)[0]||"");0===u.indexOf(c.rootPath)&&(u=u.replace(c.rootPath+o,""));var h=u.split(o);return h.unshift(t),y(s,h,0),s}}function y(e,t,r){e.isRefined=e.name===(t[r]&&t[r].trim()),e.data&&e.data.forEach((function(e){y(e,t,r+1)}))}function R(e,t,r,n){if(n=n||0,Array.isArray(t))return e(t,r[n]);if(!t.data||0===t.data.length)return t;var s=t.data.map((function(t){return R(e,t,r,n+1)})),a=e(s,r[n]);return i({data:a},t)}function F(e,t){var r=a(e,(function(e){return e.name===t}));return r&&r.stats}function b(e,t,r,n,i){var s=a(i,(function(e){return e.name===r})),c=s&&s.data&&s.data[n]?s.data[n]:0,o=s&&s.exhaustive||!1;return{type:t,attributeName:r,name:n,count:c,exhaustive:o}}g.prototype.getFacetByName=function(e){function t(t){return t.name===e}return a(this.facets,t)||a(this.disjunctiveFacets,t)||a(this.hierarchicalFacets,t)},g.DEFAULT_SORT=["isRefined:desc","count:desc","name:asc"],g.prototype.getFacetValues=function(e,t){var r=v(this,e);if(r){var n,s=i({},t,{sortBy:g.DEFAULT_SORT,facetOrdering:!(t&&t.sortBy)}),a=this;if(Array.isArray(r))n=[e];else n=a._state.getHierarchicalFacetByName(r.name).attributes;return R((function(e,t){if(s.facetOrdering){var r=function(e,t){return e.renderingContent&&e.renderingContent.facetOrdering&&e.renderingContent.facetOrdering.values&&e.renderingContent.facetOrdering.values[t]}(a,t);if(r)return function(e,t){var r=[],n=[],i=t.hide||[],s=(t.order||[]).reduce((function(e,t,r){return e[t]=r,e}),{});e.forEach((function(e){var t=e.path||e.name,a=i.indexOf(t)>-1;a||void 0===s[t]?a||n.push(e):r[s[t]]=e})),r=r.filter((function(e){return e}));var a,c=t.sortRemainingBy;return"hidden"===c?r:(a="alpha"===c?[["path","name"],["asc","asc"]]:[["count"],["desc"]],r.concat(h(n,a[0],a[1])))}(e,r)}if(Array.isArray(s.sortBy)){var n=o(s.sortBy,g.DEFAULT_SORT);return h(e,n[0],n[1])}if("function"==typeof s.sortBy)return function(e,t){return t.sort(e)}(s.sortBy,e);throw new Error("options.sortBy is optional but if defined it must be either an array of string (predicates) or a sorting function")}),r,n)}},g.prototype.getFacetStats=function(e){return this._state.isConjunctiveFacet(e)?F(this.facets,e):this._state.isDisjunctiveFacet(e)?F(this.disjunctiveFacets,e):void 0},g.prototype.getRefinements=function(){var e=this._state,t=this,r=[];return Object.keys(e.facetsRefinements).forEach((function(n){e.facetsRefinements[n].forEach((function(i){r.push(b(e,"facet",n,i,t.facets))}))})),Object.keys(e.facetsExcludes).forEach((function(n){e.facetsExcludes[n].forEach((function(i){r.push(b(e,"exclude",n,i,t.facets))}))})),Object.keys(e.disjunctiveFacetsRefinements).forEach((function(n){e.disjunctiveFacetsRefinements[n].forEach((function(i){r.push(b(e,"disjunctive",n,i,t.disjunctiveFacets))}))})),Object.keys(e.hierarchicalFacetsRefinements).forEach((function(n){e.hierarchicalFacetsRefinements[n].forEach((function(i){r.push(function(e,t,r,n){var i=e.getHierarchicalFacetByName(t),s=e._getHierarchicalFacetSeparator(i),c=r.split(s),o=a(n,(function(e){return e.name===t})),u=c.reduce((function(e,t){var r=e&&a(e.data,(function(e){return e.name===t}));return void 0!==r?r:e}),o),h=u&&u.count||0,f=u&&u.exhaustive||!1,l=u&&u.path||"";return{type:"hierarchical",attributeName:t,name:l,count:h,exhaustive:f}}(e,n,i,t.hierarchicalFacets))}))})),Object.keys(e.numericRefinements).forEach((function(t){var n=e.numericRefinements[t];Object.keys(n).forEach((function(e){n[e].forEach((function(n){r.push({type:"numeric",attributeName:t,name:n,numericValue:n,operator:e})}))}))})),e.tagRefinements.forEach((function(e){r.push({type:"tag",attributeName:"_tags",name:e})})),r},e.exports=g},36571:(e,t,r)=>{"use strict";var n=r(72733),i=r(46732),s=r(2909).escapeFacetValue,a=r(73014),c=r(44728),o=r(40317),u=r(21383),h=r(19127),f=r(42223),l=r(49228),m=r(33371),d=r(67691),p=r(57749),g=r(16938);function v(e,t,r,n){"function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+g+")"),this.setClient(e);var i=r||{};i.index=t,this.state=m.make(i),this.recommendState=new h({params:i.recommendState}),this.lastResults=null,this.lastRecommendResults=null,this._queryId=0,this._recommendQueryId=0,this._lastQueryIdReceived=-1,this._lastRecommendQueryIdReceived=-1,this.derivedHelpers=[],this._currentNbQueries=0,this._currentNbRecommendQueries=0,this._searchResultsOptions=n,this._recommendCache={}}function y(e){if(e<0)throw new Error("Page requested below 0.");return this._change({state:this.state.setPage(e),isPageReset:!1}),this}function R(){return this.state.page}a(v,n),v.prototype.search=function(){return this._search({onlyWithDerivedHelpers:!1}),this},v.prototype.searchOnlyWithDerivedHelpers=function(){return this._search({onlyWithDerivedHelpers:!0}),this},v.prototype.recommend=function(){return this._recommend(),this},v.prototype.getQuery=function(){var e=this.state;return l._getHitsSearchParams(e)},v.prototype.searchOnce=function(e,t){var r=e?this.state.setQueryParameters(e):this.state,n=l._getQueries(r.index,r),i=this;if(this._currentNbQueries++,this.emit("searchOnce",{state:r}),!t)return this.client.search(n).then((function(e){return i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),{content:new d(r,e.results),state:r,_originalResponse:e}}),(function(e){throw i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),e}));this.client.search(n).then((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(null,new d(r,e.results),r)})).catch((function(e){i._currentNbQueries--,0===i._currentNbQueries&&i.emit("searchQueueEmpty"),t(e,null,r)}))},v.prototype.findAnswers=function(e){console.warn("[algoliasearch-helper] answers is no longer supported");var t=this.state,r=this.derivedHelpers[0];if(!r)return Promise.resolve([]);var n=r.getModifiedState(t),i=c({attributesForPrediction:e.attributesForPrediction,nbHits:e.nbHits},{params:u(l._getHitsSearchParams(n),["attributesToSnippet","hitsPerPage","restrictSearchableAttributes","snippetEllipsisText"])}),s="search for answers was called, but this client does not have a function client.initIndex(index).findAnswers";if("function"!=typeof this.client.initIndex)throw new Error(s);var a=this.client.initIndex(n.index);if("function"!=typeof a.findAnswers)throw new Error(s);return a.findAnswers(n.query,e.queryLanguages,i)},v.prototype.searchForFacetValues=function(e,t,r,n){var i="function"==typeof this.client.searchForFacetValues,a="function"==typeof this.client.initIndex;if(!i&&!a&&"function"!=typeof this.client.search)throw new Error("search for facet values (searchable) was called, but this client does not have a function client.searchForFacetValues or client.initIndex(index).searchForFacetValues");var c=this.state.setQueryParameters(n||{}),o=c.isDisjunctiveFacet(e),u=l.getSearchForFacetQuery(e,t,r,c);this._currentNbQueries++;var h,f=this;return i?h=this.client.searchForFacetValues([{indexName:c.index,params:u}]):a?h=this.client.initIndex(c.index).searchForFacetValues(u):(delete u.facetName,h=this.client.search([{type:"facet",facet:e,indexName:c.index,params:u}]).then((function(e){return e.results[0]}))),this.emit("searchForFacetValues",{state:c,facet:e,query:t}),h.then((function(t){return f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),(t=Array.isArray(t)?t[0]:t).facetHits.forEach((function(t){t.escapedValue=s(t.value),t.isRefined=o?c.isDisjunctiveFacetRefined(e,t.escapedValue):c.isFacetRefined(e,t.escapedValue)})),t}),(function(e){throw f._currentNbQueries--,0===f._currentNbQueries&&f.emit("searchQueueEmpty"),e}))},v.prototype.setQuery=function(e){return this._change({state:this.state.resetPage().setQuery(e),isPageReset:!0}),this},v.prototype.clearRefinements=function(e){return this._change({state:this.state.resetPage().clearRefinements(e),isPageReset:!0}),this},v.prototype.clearTags=function(){return this._change({state:this.state.resetPage().clearTags(),isPageReset:!0}),this},v.prototype.addDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addDisjunctiveRefine=function(){return this.addDisjunctiveFacetRefinement.apply(this,arguments)},v.prototype.addHierarchicalFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addHierarchicalFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().addNumericRefinement(e,t,r),isPageReset:!0}),this},v.prototype.addFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().addFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.addRefine=function(){return this.addFacetRefinement.apply(this,arguments)},v.prototype.addFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().addExcludeRefinement(e,t),isPageReset:!0}),this},v.prototype.addExclude=function(){return this.addFacetExclusion.apply(this,arguments)},v.prototype.addTag=function(e){return this._change({state:this.state.resetPage().addTagRefinement(e),isPageReset:!0}),this},v.prototype.addFrequentlyBoughtTogether=function(e){return this._recommendChange({state:this.recommendState.addFrequentlyBoughtTogether(e)}),this},v.prototype.addRelatedProducts=function(e){return this._recommendChange({state:this.recommendState.addRelatedProducts(e)}),this},v.prototype.addTrendingItems=function(e){return this._recommendChange({state:this.recommendState.addTrendingItems(e)}),this},v.prototype.addTrendingFacets=function(e){return this._recommendChange({state:this.recommendState.addTrendingFacets(e)}),this},v.prototype.addLookingSimilar=function(e){return this._recommendChange({state:this.recommendState.addLookingSimilar(e)}),this},v.prototype.removeNumericRefinement=function(e,t,r){return this._change({state:this.state.resetPage().removeNumericRefinement(e,t,r),isPageReset:!0}),this},v.prototype.removeDisjunctiveFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeDisjunctiveFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.removeDisjunctiveRefine=function(){return this.removeDisjunctiveFacetRefinement.apply(this,arguments)},v.prototype.removeHierarchicalFacetRefinement=function(e){return this._change({state:this.state.resetPage().removeHierarchicalFacetRefinement(e),isPageReset:!0}),this},v.prototype.removeFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().removeFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.removeRefine=function(){return this.removeFacetRefinement.apply(this,arguments)},v.prototype.removeFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().removeExcludeRefinement(e,t),isPageReset:!0}),this},v.prototype.removeExclude=function(){return this.removeFacetExclusion.apply(this,arguments)},v.prototype.removeTag=function(e){return this._change({state:this.state.resetPage().removeTagRefinement(e),isPageReset:!0}),this},v.prototype.removeFrequentlyBoughtTogether=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeRelatedProducts=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeTrendingItems=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeTrendingFacets=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.removeLookingSimilar=function(e){return this._recommendChange({state:this.recommendState.removeParams(e)}),this},v.prototype.toggleFacetExclusion=function(e,t){return this._change({state:this.state.resetPage().toggleExcludeFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.toggleExclude=function(){return this.toggleFacetExclusion.apply(this,arguments)},v.prototype.toggleRefinement=function(e,t){return this.toggleFacetRefinement(e,t)},v.prototype.toggleFacetRefinement=function(e,t){return this._change({state:this.state.resetPage().toggleFacetRefinement(e,t),isPageReset:!0}),this},v.prototype.toggleRefine=function(){return this.toggleFacetRefinement.apply(this,arguments)},v.prototype.toggleTag=function(e){return this._change({state:this.state.resetPage().toggleTagRefinement(e),isPageReset:!0}),this},v.prototype.nextPage=function(){var e=this.state.page||0;return this.setPage(e+1)},v.prototype.previousPage=function(){var e=this.state.page||0;return this.setPage(e-1)},v.prototype.setCurrentPage=y,v.prototype.setPage=y,v.prototype.setIndex=function(e){return this._change({state:this.state.resetPage().setIndex(e),isPageReset:!0}),this},v.prototype.setQueryParameter=function(e,t){return this._change({state:this.state.resetPage().setQueryParameter(e,t),isPageReset:!0}),this},v.prototype.setState=function(e){return this._change({state:m.make(e),isPageReset:!1}),this},v.prototype.overrideStateWithoutTriggeringChangeEvent=function(e){return this.state=new m(e),this},v.prototype.hasRefinements=function(e){return!!o(this.state.getNumericRefinements(e))||(this.state.isConjunctiveFacet(e)?this.state.isFacetRefined(e):this.state.isDisjunctiveFacet(e)?this.state.isDisjunctiveFacetRefined(e):!!this.state.isHierarchicalFacet(e)&&this.state.isHierarchicalFacetRefined(e))},v.prototype.isExcluded=function(e,t){return this.state.isExcludeRefined(e,t)},v.prototype.isDisjunctiveRefined=function(e,t){return this.state.isDisjunctiveFacetRefined(e,t)},v.prototype.hasTag=function(e){return this.state.isTagRefined(e)},v.prototype.isTagRefined=function(){return this.hasTagRefinements.apply(this,arguments)},v.prototype.getIndex=function(){return this.state.index},v.prototype.getCurrentPage=R,v.prototype.getPage=R,v.prototype.getTags=function(){return this.state.tagRefinements},v.prototype.getRefinements=function(e){var t=[];if(this.state.isConjunctiveFacet(e))this.state.getConjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"conjunctive"})})),this.state.getExcludeRefinements(e).forEach((function(e){t.push({value:e,type:"exclude"})}));else if(this.state.isDisjunctiveFacet(e)){this.state.getDisjunctiveRefinements(e).forEach((function(e){t.push({value:e,type:"disjunctive"})}))}var r=this.state.getNumericRefinements(e);return Object.keys(r).forEach((function(e){var n=r[e];t.push({value:n,operator:e,type:"numeric"})})),t},v.prototype.getNumericRefinement=function(e,t){return this.state.getNumericRefinement(e,t)},v.prototype.getHierarchicalFacetBreadcrumb=function(e){return this.state.getHierarchicalFacetBreadcrumb(e)},v.prototype._search=function(e){var t=this.state,r=[],n=[];e.onlyWithDerivedHelpers||(n=l._getQueries(t.index,t),r.push({state:t,queriesCount:n.length,helper:this}),this.emit("search",{state:t,results:this.lastResults}));var i=this.derivedHelpers.map((function(e){var n=e.getModifiedState(t),i=n.index?l._getQueries(n.index,n):[];return r.push({state:n,queriesCount:i.length,helper:e}),e.emit("search",{state:n,results:e.lastResults}),i})),s=Array.prototype.concat.apply(n,i),a=this._queryId++;if(this._currentNbQueries++,!s.length)return Promise.resolve({results:[]}).then(this._dispatchAlgoliaResponse.bind(this,r,a));try{this.client.search(s).then(this._dispatchAlgoliaResponse.bind(this,r,a)).catch(this._dispatchAlgoliaError.bind(this,a))}catch(c){this.emit("error",{error:c})}},v.prototype._recommend=function(){var e=this.state,t=this.recommendState,r=this.getIndex(),n=[{state:t,index:r,helper:this}],i=t.params.map((function(e){return e.$$id}));this.emit("fetch",{recommend:{state:t,results:this.lastRecommendResults}});var s=this._recommendCache,a=this.derivedHelpers.map((function(t){var r=t.getModifiedState(e).index;if(!r)return[];var a=t.getModifiedRecommendState(new h);return n.push({state:a,index:r,helper:t}),i=Array.prototype.concat.apply(i,a.params.map((function(e){return e.$$id}))),t.emit("fetch",{recommend:{state:a,results:t.lastRecommendResults}}),a._buildQueries(r,s)})),c=Array.prototype.concat.apply(this.recommendState._buildQueries(r,s),a);if(0!==c.length)if(c.length>0&&void 0===this.client.getRecommendations)console.warn("Please update algoliasearch/lite to the latest version in order to use recommend widgets.");else{var o=this._recommendQueryId++;this._currentNbRecommendQueries++;try{this.client.getRecommendations(c).then(this._dispatchRecommendResponse.bind(this,o,n,i)).catch(this._dispatchRecommendError.bind(this,o))}catch(u){this.emit("error",{error:u})}}},v.prototype._dispatchAlgoliaResponse=function(e,t,r){var n=this;if(!(t<this._lastQueryIdReceived)){this._currentNbQueries-=t-this._lastQueryIdReceived,this._lastQueryIdReceived=t,0===this._currentNbQueries&&this.emit("searchQueueEmpty");var i=r.results.slice();e.forEach((function(e){var t=e.state,r=e.queriesCount,s=e.helper,a=i.splice(0,r);t.index?(s.lastResults=new d(t,a,n._searchResultsOptions),s.emit("result",{results:s.lastResults,state:t})):s.emit("result",{results:null,state:t})}))}},v.prototype._dispatchRecommendResponse=function(e,t,r,n){if(!(e<this._lastRecommendQueryIdReceived)){this._currentNbRecommendQueries-=e-this._lastRecommendQueryIdReceived,this._lastRecommendQueryIdReceived=e,0===this._currentNbRecommendQueries&&this.emit("recommendQueueEmpty");var i=this._recommendCache,s={};r.filter((function(e){return void 0===i[e]})).forEach((function(e,t){s[e]||(s[e]=[]),s[e].push(t)})),Object.keys(s).forEach((function(e){var t=s[e],r=n.results[t[0]];1!==t.length?i[e]=Object.assign({},r,{hits:p(t.map((function(e){return n.results[e].hits})))}):i[e]=r}));var a={};r.forEach((function(e){a[e]=i[e]})),t.forEach((function(e){var t=e.state,r=e.helper;e.index?(r.lastRecommendResults=new f(t,a),r.emit("recommend:result",{recommend:{results:r.lastRecommendResults,state:t}})):r.emit("recommend:result",{results:null,state:t})}))}},v.prototype._dispatchAlgoliaError=function(e,t){e<this._lastQueryIdReceived||(this._currentNbQueries-=e-this._lastQueryIdReceived,this._lastQueryIdReceived=e,this.emit("error",{error:t}),0===this._currentNbQueries&&this.emit("searchQueueEmpty"))},v.prototype._dispatchRecommendError=function(e,t){e<this._lastRecommendQueryIdReceived||(this._currentNbRecommendQueries-=e-this._lastRecommendQueryIdReceived,this._lastRecommendQueryIdReceived=e,this.emit("error",{error:t}),0===this._currentNbRecommendQueries&&this.emit("recommendQueueEmpty"))},v.prototype.containsRefinement=function(e,t,r,n){return e||0!==t.length||0!==r.length||0!==n.length},v.prototype._hasDisjunctiveRefinements=function(e){return this.state.disjunctiveRefinements[e]&&this.state.disjunctiveRefinements[e].length>0},v.prototype._change=function(e){var t=e.state,r=e.isPageReset;t!==this.state&&(this.state=t,this.emit("change",{state:this.state,results:this.lastResults,isPageReset:r}))},v.prototype._recommendChange=function(e){var t=e.state;t!==this.recommendState&&(this.recommendState=t,this.emit("recommend:change",{search:{results:this.lastResults,state:this.state},recommend:{results:this.lastRecommendResults,state:this.recommendState}}))},v.prototype.clearCache=function(){return this.client.clearCache&&this.client.clearCache(),this},v.prototype.setClient=function(e){return this.client===e||("function"==typeof e.addAlgoliaAgent&&e.addAlgoliaAgent("JS Helper ("+g+")"),this.client=e),this},v.prototype.getClient=function(){return this.client},v.prototype.derive=function(e,t){var r=new i(this,e,t);return this.derivedHelpers.push(r),r},v.prototype.detachDerivedHelper=function(e){var t=this.derivedHelpers.indexOf(e);if(-1===t)throw new Error("Derived helper already detached");this.derivedHelpers.splice(t,1)},v.prototype.hasPendingRequests=function(){return this._currentNbQueries>0},e.exports=v},78965:e=>{"use strict";e.exports=function(e){return Array.isArray(e)?e.filter(Boolean):[]}},29110:e=>{"use strict";e.exports=function(){return Array.prototype.slice.call(arguments).reduceRight((function(e,t){return Object.keys(Object(t)).forEach((function(r){void 0!==t[r]&&(void 0!==e[r]&&delete e[r],e[r]=t[r])})),e}),{})}},2909:e=>{"use strict";e.exports={escapeFacetValue:function(e){return"string"!=typeof e?e:String(e).replace(/^-/,"\\-")},unescapeFacetValue:function(e){return"string"!=typeof e?e:e.replace(/^\\-/,"-")}}},20849:e=>{"use strict";e.exports=function(e,t){if(Array.isArray(e))for(var r=0;r<e.length;r++)if(t(e[r]))return e[r]}},43917:e=>{"use strict";e.exports=function(e,t){if(!Array.isArray(e))return-1;for(var r=0;r<e.length;r++)if(t(e[r]))return r;return-1}},38657:e=>{e.exports=function(e){return e.reduce((function(e,t){return e.concat(t)}),[])}},7577:(e,t,r)=>{"use strict";var n=r(20849);e.exports=function(e,t){var r=(t||[]).map((function(e){return e.split(":")}));return e.reduce((function(e,t){var i=t.split(":"),s=n(r,(function(e){return e[0]===i[0]}));return i.length>1||!s?(e[0].push(i[0]),e[1].push(i[1]),e):(e[0].push(s[0]),e[1].push(s[1]),e)}),[[],[]])}},73014:e=>{"use strict";e.exports=function(e,t){e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}},14843:e=>{"use strict";e.exports=function(e,t){return e.filter((function(r,n){return t.indexOf(r)>-1&&e.indexOf(r)===n}))}},44728:e=>{"use strict";function t(e){return"function"==typeof e||Array.isArray(e)||"[object Object]"===Object.prototype.toString.call(e)}function r(e,n){if(e===n)return e;for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)&&"__proto__"!==i&&"constructor"!==i){var s=n[i],a=e[i];void 0!==a&&void 0===s||(t(a)&&t(s)?e[i]=r(a,s):e[i]="object"==typeof(c=s)&&null!==c?r(Array.isArray(c)?[]:{},c):c)}var c;return e}e.exports=function(e){t(e)||(e={});for(var n=1,i=arguments.length;n<i;n++){var s=arguments[n];t(s)&&r(e,s)}return e}},40317:e=>{"use strict";e.exports=function(e){return e&&Object.keys(e).length>0}},21383:e=>{"use strict";e.exports=function(e,t){if(null===e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}},38601:e=>{"use strict";function t(e,t){if(e!==t){var r=void 0!==e,n=null===e,i=void 0!==t,s=null===t;if(!s&&e>t||n&&i||!r)return 1;if(!n&&e<t||s&&r||!i)return-1}return 0}e.exports=function(e,r,n){if(!Array.isArray(e))return[];Array.isArray(n)||(n=[]);var i=e.map((function(e,t){return{criteria:r.map((function(t){return e[t]})),index:t,value:e}}));return i.sort((function(e,r){for(var i=-1;++i<e.criteria.length;){var s=t(e.criteria[i],r.criteria[i]);if(s)return i>=n.length?s:"desc"===n[i]?-s:s}return e.index-r.index})),i.map((function(e){return e.value}))}},17507:e=>{"use strict";e.exports=function e(t){if("number"==typeof t)return t;if("string"==typeof t)return parseFloat(t);if(Array.isArray(t))return t.map(e);throw new Error("The value should be a number, a parsable string or an array of those.")}},49228:(e,t,r)=>{"use strict";var n=r(44728);function i(e){return Object.keys(e).sort().reduce((function(t,r){return t[r]=e[r],t}),{})}var s={_getQueries:function(e,t){var r=[];return r.push({indexName:e,params:s._getHitsSearchParams(t)}),t.getRefinedDisjunctiveFacets().forEach((function(n){r.push({indexName:e,params:s._getDisjunctiveFacetSearchParams(t,n)})})),t.getRefinedHierarchicalFacets().forEach((function(n){var i=t.getHierarchicalFacetByName(n),a=t.getHierarchicalRefinement(n),c=t._getHierarchicalFacetSeparator(i);if(a.length>0&&a[0].split(c).length>1){var o=a[0].split(c).slice(0,-1).reduce((function(e,t,r){return e.concat({attribute:i.attributes[r],value:0===r?t:[e[e.length-1].value,t].join(c)})}),[]);o.forEach((function(n,a){var c=s._getDisjunctiveFacetSearchParams(t,n.attribute,0===a);function u(e){return i.attributes.some((function(t){return t===e.split(":")[0]}))}var h=(c.facetFilters||[]).reduce((function(e,t){if(Array.isArray(t)){var r=t.filter((function(e){return!u(e)}));r.length>0&&e.push(r)}return"string"!=typeof t||u(t)||e.push(t),e}),[]),f=o[a-1];c.facetFilters=a>0?h.concat(f.attribute+":"+f.value):h.length>0?h:void 0,r.push({indexName:e,params:c})}))}})),r},_getHitsSearchParams:function(e){var t=e.facets.concat(e.disjunctiveFacets).concat(s._getHitsHierarchicalFacetsAttributes(e)).sort(),r=s._getFacetFilters(e),a=s._getNumericFilters(e),c=s._getTagFilters(e),o={};return t.length>0&&(o.facets=t.indexOf("*")>-1?["*"]:t),c.length>0&&(o.tagFilters=c),r.length>0&&(o.facetFilters=r),a.length>0&&(o.numericFilters=a),i(n({},e.getQueryParams(),o))},_getDisjunctiveFacetSearchParams:function(e,t,r){var a=s._getFacetFilters(e,t,r),c=s._getNumericFilters(e,t),o=s._getTagFilters(e),u={hitsPerPage:0,page:0,analytics:!1,clickAnalytics:!1};o.length>0&&(u.tagFilters=o);var h=e.getHierarchicalFacetByName(t);return u.facets=h?s._getDisjunctiveHierarchicalFacetAttribute(e,h,r):t,c.length>0&&(u.numericFilters=c),a.length>0&&(u.facetFilters=a),i(n({},e.getQueryParams(),u))},_getNumericFilters:function(e,t){if(e.numericFilters)return e.numericFilters;var r=[];return Object.keys(e.numericRefinements).forEach((function(n){var i=e.numericRefinements[n]||{};Object.keys(i).forEach((function(e){var s=i[e]||[];t!==n&&s.forEach((function(t){if(Array.isArray(t)){var i=t.map((function(t){return n+e+t}));r.push(i)}else r.push(n+e+t)}))}))})),r},_getTagFilters:function(e){return e.tagFilters?e.tagFilters:e.tagRefinements.join(",")},_getFacetFilters:function(e,t,r){var n=[],i=e.facetsRefinements||{};Object.keys(i).sort().forEach((function(e){(i[e]||[]).slice().sort().forEach((function(t){n.push(e+":"+t)}))}));var s=e.facetsExcludes||{};Object.keys(s).sort().forEach((function(e){(s[e]||[]).sort().forEach((function(t){n.push(e+":-"+t)}))}));var a=e.disjunctiveFacetsRefinements||{};Object.keys(a).sort().forEach((function(e){var r=a[e]||[];if(e!==t&&r&&0!==r.length){var i=[];r.slice().sort().forEach((function(t){i.push(e+":"+t)})),n.push(i)}}));var c=e.hierarchicalFacetsRefinements||{};return Object.keys(c).sort().forEach((function(i){var s=(c[i]||[])[0];if(void 0!==s){var a,o,u=e.getHierarchicalFacetByName(i),h=e._getHierarchicalFacetSeparator(u),f=e._getHierarchicalRootPath(u);if(t===i){if(-1===s.indexOf(h)||!f&&!0===r||f&&f.split(h).length===s.split(h).length)return;f?(o=f.split(h).length-1,s=f):(o=s.split(h).length-2,s=s.slice(0,s.lastIndexOf(h))),a=u.attributes[o]}else o=s.split(h).length-1,a=u.attributes[o];a&&n.push([a+":"+s])}})),n},_getHitsHierarchicalFacetsAttributes:function(e){return e.hierarchicalFacets.reduce((function(t,r){var n=e.getHierarchicalRefinement(r.name)[0];if(!n)return t.push(r.attributes[0]),t;var i=e._getHierarchicalFacetSeparator(r),s=n.split(i).length,a=r.attributes.slice(0,s+1);return t.concat(a)}),[])},_getDisjunctiveHierarchicalFacetAttribute:function(e,t,r){var n=e._getHierarchicalFacetSeparator(t);if(!0===r){var i=e._getHierarchicalRootPath(t),s=0;return i&&(s=i.split(n).length),[t.attributes[s]]}var a=(e.getHierarchicalRefinement(t.name)[0]||"").split(n).length-1;return t.attributes.slice(0,a+1)},getSearchForFacetQuery:function(e,t,r,a){var c=a.isDisjunctiveFacet(e)?a.clearRefinements(e):a,o={facetQuery:t,facetName:e};return"number"==typeof r&&(o.maxFacetHits=r),i(n({},s._getHitsSearchParams(c),o))}};e.exports=s},72208:e=>{"use strict";e.exports=function(e){return null!==e&&/^[a-zA-Z0-9_-]{1,64}$/.test(e)}},57749:(e,t,r)=>{"use strict";var n=r(20849),i=r(38657);e.exports=function(e){var t={};return e.forEach((function(e){e.forEach((function(e,r){t[e.objectID]?t[e.objectID]={indexSum:t[e.objectID].indexSum+r,count:t[e.objectID].count+1}:t[e.objectID]={indexSum:r,count:1}}))})),function(e,t){var r=[];return Object.keys(e).forEach((function(n){e[n].count<2&&(e[n].indexSum+=100),r.push({objectID:n,avgOfIndices:e[n].indexSum/t})})),r.sort((function(e,t){return e.avgOfIndices>t.avgOfIndices?1:-1}))}(t,e.length).reduce((function(t,r){var s=n(i(e),(function(e){return e.objectID===r.objectID}));return s?t.concat(s):t}),[])}},16938:e=>{"use strict";e.exports="3.22.1"},83643:function(e){e.exports=function(){"use strict";function e(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function t(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function r(r){for(var n=1;n<arguments.length;n++){var i=null!=arguments[n]?arguments[n]:{};n%2?t(Object(i),!0).forEach((function(t){e(r,t,i[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(r,Object.getOwnPropertyDescriptors(i)):t(Object(i)).forEach((function(e){Object.defineProperty(r,e,Object.getOwnPropertyDescriptor(i,e))}))}return r}function n(e,t){if(null==e)return{};var r,n,i=function(e,t){if(null==e)return{};var r,n,i={},s=Object.keys(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||(i[r]=e[r]);return i}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n<s.length;n++)r=s[n],t.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(i[r]=e[r])}return i}function i(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e)){var r=[],n=!0,i=!1,s=void 0;try{for(var a,c=e[Symbol.iterator]();!(n=(a=c.next()).done)&&(r.push(a.value),!t||r.length!==t);n=!0);}catch(e){i=!0,s=e}finally{try{n||null==c.return||c.return()}finally{if(i)throw s}}return r}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}function s(e){return function(e){if(Array.isArray(e)){for(var t=0,r=new Array(e.length);t<e.length;t++)r[t]=e[t];return r}}(e)||function(e){if(Symbol.iterator in Object(e)||"[object Arguments]"===Object.prototype.toString.call(e))return Array.from(e)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}function a(e){var t,r="algoliasearch-client-js-".concat(e.key),n=function(){return void 0===t&&(t=e.localStorage||window.localStorage),t},s=function(){return JSON.parse(n().getItem(r)||"{}")},a=function(e){n().setItem(r,JSON.stringify(e))},c=function(){var t=e.timeToLive?1e3*e.timeToLive:null,r=s(),n=Object.fromEntries(Object.entries(r).filter((function(e){return void 0!==i(e,2)[1].timestamp})));if(a(n),t){var c=Object.fromEntries(Object.entries(n).filter((function(e){var r=i(e,2)[1],n=(new Date).getTime();return!(r.timestamp+t<n)})));a(c)}};return{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return Promise.resolve().then((function(){c();var t=JSON.stringify(e);return s()[t]})).then((function(e){return Promise.all([e?e.value:t(),void 0!==e])})).then((function(e){var t=i(e,2),n=t[0],s=t[1];return Promise.all([n,s||r.miss(n)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve().then((function(){var i=s();return i[JSON.stringify(e)]={timestamp:(new Date).getTime(),value:t},n().setItem(r,JSON.stringify(i)),t}))},delete:function(e){return Promise.resolve().then((function(){var t=s();delete t[JSON.stringify(e)],n().setItem(r,JSON.stringify(t))}))},clear:function(){return Promise.resolve().then((function(){n().removeItem(r)}))}}}function c(e){var t=s(e.caches),r=t.shift();return void 0===r?{get:function(e,t){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return t().then((function(e){return Promise.all([e,r.miss(e)])})).then((function(e){return i(e,1)[0]}))},set:function(e,t){return Promise.resolve(t)},delete:function(e){return Promise.resolve()},clear:function(){return Promise.resolve()}}:{get:function(e,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}};return r.get(e,n,i).catch((function(){return c({caches:t}).get(e,n,i)}))},set:function(e,n){return r.set(e,n).catch((function(){return c({caches:t}).set(e,n)}))},delete:function(e){return r.delete(e).catch((function(){return c({caches:t}).delete(e)}))},clear:function(){return r.clear().catch((function(){return c({caches:t}).clear()}))}}}function o(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{serializable:!0},t={};return{get:function(r,n){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{miss:function(){return Promise.resolve()}},s=JSON.stringify(r);if(s in t)return Promise.resolve(e.serializable?JSON.parse(t[s]):t[s]);var a=n(),c=i&&i.miss||function(){return Promise.resolve()};return a.then((function(e){return c(e)})).then((function(){return a}))},set:function(r,n){return t[JSON.stringify(r)]=e.serializable?JSON.stringify(n):n,Promise.resolve(n)},delete:function(e){return delete t[JSON.stringify(e)],Promise.resolve()},clear:function(){return t={},Promise.resolve()}}}function u(e){for(var t=e.length-1;t>0;t--){var r=Math.floor(Math.random()*(t+1)),n=e[t];e[t]=e[r],e[r]=n}return e}function h(e,t){return t?(Object.keys(t).forEach((function(r){e[r]=t[r](e)})),e):e}function f(e){for(var t=arguments.length,r=new Array(t>1?t-1:0),n=1;n<t;n++)r[n-1]=arguments[n];var i=0;return e.replace(/%s/g,(function(){return encodeURIComponent(r[i++])}))}var l={WithinQueryParameters:0,WithinHeaders:1};function m(e,t){var r=e||{},n=r.data||{};return Object.keys(r).forEach((function(e){-1===["timeout","headers","queryParameters","data","cacheable"].indexOf(e)&&(n[e]=r[e])})),{data:Object.entries(n).length>0?n:void 0,timeout:r.timeout||t,headers:r.headers||{},queryParameters:r.queryParameters||{},cacheable:r.cacheable}}var d={Read:1,Write:2,Any:3},p=1,g=2,v=3;function y(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:p;return r(r({},e),{},{status:t,lastUpdate:Date.now()})}function R(e){return"string"==typeof e?{protocol:"https",url:e,accept:d.Any}:{protocol:e.protocol||"https",url:e.url,accept:e.accept||d.Any}}var F="GET",b="POST";function j(e,t){return Promise.all(t.map((function(t){return e.get(t,(function(){return Promise.resolve(y(t))}))}))).then((function(e){var r=e.filter((function(e){return function(e){return e.status===p||Date.now()-e.lastUpdate>12e4}(e)})),n=e.filter((function(e){return function(e){return e.status===v&&Date.now()-e.lastUpdate<=12e4}(e)})),i=[].concat(s(r),s(n));return{getTimeout:function(e,t){return(0===n.length&&0===e?1:n.length+3+e)*t},statelessHosts:i.length>0?i.map((function(e){return R(e)})):t}}))}function _(e,t,n,i){var a=[],c=function(e,t){if(e.method!==F&&(void 0!==e.data||void 0!==t.data)){var n=Array.isArray(e.data)?e.data:r(r({},e.data),t.data);return JSON.stringify(n)}}(n,i),o=function(e,t){var n=r(r({},e.headers),t.headers),i={};return Object.keys(n).forEach((function(e){var t=n[e];i[e.toLowerCase()]=t})),i}(e,i),u=n.method,h=n.method!==F?{}:r(r({},n.data),i.data),f=r(r(r({"x-algolia-agent":e.userAgent.value},e.queryParameters),h),i.queryParameters),l=0,m=function t(r,s){var h=r.pop();if(void 0===h)throw{name:"RetryError",message:"Unreachable hosts - your application id may be incorrect. If the error persists, please reach out to the Algolia Support team: https://alg.li/support .",transporterStackTrace:O(a)};var m={data:c,headers:o,method:u,url:x(h,n.path,f),connectTimeout:s(l,e.timeouts.connect),responseTimeout:s(l,i.timeout)},d=function(e){var t={request:m,response:e,host:h,triesLeft:r.length};return a.push(t),t},p={onSuccess:function(e){return function(e){try{return JSON.parse(e.content)}catch(t){throw function(e,t){return{name:"DeserializationError",message:e,response:t}}(t.message,e)}}(e)},onRetry:function(n){var i=d(n);return n.isTimedOut&&l++,Promise.all([e.logger.info("Retryable failure",w(i)),e.hostsCache.set(h,y(h,n.isTimedOut?v:g))]).then((function(){return t(r,s)}))},onFail:function(e){throw d(e),function(e,t){var r=e.content,n=e.status,i=r;try{i=JSON.parse(r).message}catch(e){}return function(e,t,r){return{name:"ApiError",message:e,status:t,transporterStackTrace:r}}(i,n,t)}(e,O(a))}};return e.requester.send(m).then((function(e){return function(e,t){return function(e){var t=e.status;return e.isTimedOut||function(e){var t=e.isTimedOut,r=e.status;return!t&&!~~r}(e)||2!=~~(t/100)&&4!=~~(t/100)}(e)?t.onRetry(e):2==~~(e.status/100)?t.onSuccess(e):t.onFail(e)}(e,p)}))};return j(e.hostsCache,t).then((function(e){return m(s(e.statelessHosts).reverse(),e.getTimeout)}))}function P(e){var t={value:"Algolia for JavaScript (".concat(e,")"),add:function(e){var r="; ".concat(e.segment).concat(void 0!==e.version?" (".concat(e.version,")"):"");return-1===t.value.indexOf(r)&&(t.value="".concat(t.value).concat(r)),t}};return t}function x(e,t,r){var n=E(r),i="".concat(e.protocol,"://").concat(e.url,"/").concat("/"===t.charAt(0)?t.substr(1):t);return n.length&&(i+="?".concat(n)),i}function E(e){return Object.keys(e).map((function(t){return f("%s=%s",t,(r=e[t],"[object Object]"===Object.prototype.toString.call(r)||"[object Array]"===Object.prototype.toString.call(r)?JSON.stringify(e[t]):e[t]));var r})).join("&")}function O(e){return e.map((function(e){return w(e)}))}function w(e){var t=e.request.headers["x-algolia-api-key"]?{"x-algolia-api-key":"*****"}:{};return r(r({},e),{},{request:r(r({},e.request),{},{headers:r(r({},e.request.headers),t)})})}var S=function(e){var t=e.appId,n=function(e,t,r){var n={"x-algolia-api-key":r,"x-algolia-application-id":t};return{headers:function(){return e===l.WithinHeaders?n:{}},queryParameters:function(){return e===l.WithinQueryParameters?n:{}}}}(void 0!==e.authMode?e.authMode:l.WithinHeaders,t,e.apiKey),s=function(e){var t=e.hostsCache,r=e.logger,n=e.requester,s=e.requestsCache,a=e.responsesCache,c=e.timeouts,o=e.userAgent,u=e.hosts,h=e.queryParameters,f={hostsCache:t,logger:r,requester:n,requestsCache:s,responsesCache:a,timeouts:c,userAgent:o,headers:e.headers,queryParameters:h,hosts:u.map((function(e){return R(e)})),read:function(e,t){var r=m(t,f.timeouts.read),n=function(){return _(f,f.hosts.filter((function(e){return!!(e.accept&d.Read)})),e,r)};if(!0!==(void 0!==r.cacheable?r.cacheable:e.cacheable))return n();var s={request:e,mappedRequestOptions:r,transporter:{queryParameters:f.queryParameters,headers:f.headers}};return f.responsesCache.get(s,(function(){return f.requestsCache.get(s,(function(){return f.requestsCache.set(s,n()).then((function(e){return Promise.all([f.requestsCache.delete(s),e])}),(function(e){return Promise.all([f.requestsCache.delete(s),Promise.reject(e)])})).then((function(e){var t=i(e,2);return t[0],t[1]}))}))}),{miss:function(e){return f.responsesCache.set(s,e)}})},write:function(e,t){return _(f,f.hosts.filter((function(e){return!!(e.accept&d.Write)})),e,m(t,f.timeouts.write))}};return f}(r(r({hosts:[{url:"".concat(t,"-dsn.algolia.net"),accept:d.Read},{url:"".concat(t,".algolia.net"),accept:d.Write}].concat(u([{url:"".concat(t,"-1.algolianet.com")},{url:"".concat(t,"-2.algolianet.com")},{url:"".concat(t,"-3.algolianet.com")}]))},e),{},{headers:r(r(r({},n.headers()),{"content-type":"application/x-www-form-urlencoded"}),e.headers),queryParameters:r(r({},n.queryParameters()),e.queryParameters)}));return h({transporter:s,appId:t,addAlgoliaAgent:function(e,t){s.userAgent.add({segment:e,version:t})},clearCache:function(){return Promise.all([s.requestsCache.clear(),s.responsesCache.clear()]).then((function(){}))}},e.methods)},A=function(e){return function(t,r){return t.method===F?e.transporter.read(t,r):e.transporter.write(t,r)}},N=function(e){return function(t){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return h({transporter:e.transporter,appId:e.appId,indexName:t},r.methods)}},T=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{params:E(e.params||{})})}));return e.transporter.read({method:b,path:"1/indexes/*/queries",data:{requests:i},cacheable:!0},n)}},H=function(e){return function(t,i){return Promise.all(t.map((function(t){var s=t.params,a=s.facetName,c=s.facetQuery,o=n(s,["facetName","facetQuery"]);return N(e)(t.indexName,{methods:{searchForFacetValues:I}}).searchForFacetValues(a,c,r(r({},i),o))})))}},Q=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/answers/%s/prediction",e.indexName),data:{query:t,queryLanguages:r},cacheable:!0},n)}},C=function(e){return function(t,r){return e.transporter.read({method:b,path:f("1/indexes/%s/query",e.indexName),data:{query:t},cacheable:!0},r)}},I=function(e){return function(t,r,n){return e.transporter.read({method:b,path:f("1/indexes/%s/facets/%s/query",e.indexName,t),data:{facetQuery:r},cacheable:!0},n)}},D=1,k=2,q=3,L=function(e){return function(t,n){var i=t.map((function(e){return r(r({},e),{},{threshold:e.threshold||0})}));return e.transporter.read({method:b,path:"1/indexes/*/recommendations",data:{requests:i},cacheable:!0},n)}};function V(e,t,n){var i,s={appId:e,apiKey:t,timeouts:{connect:1,read:2,write:30},requester:{send:function(e){return new Promise((function(t){var r=new XMLHttpRequest;r.open(e.method,e.url,!0),Object.keys(e.headers).forEach((function(t){return r.setRequestHeader(t,e.headers[t])}));var n,i=function(e,n){return setTimeout((function(){r.abort(),t({status:0,content:n,isTimedOut:!0})}),1e3*e)},s=i(e.connectTimeout,"Connection timeout");r.onreadystatechange=function(){r.readyState>r.OPENED&&void 0===n&&(clearTimeout(s),n=i(e.responseTimeout,"Socket timeout"))},r.onerror=function(){0===r.status&&(clearTimeout(s),clearTimeout(n),t({content:r.responseText||"Network request failed",status:r.status,isTimedOut:!1}))},r.onload=function(){clearTimeout(s),clearTimeout(n),t({content:r.responseText,status:r.status,isTimedOut:!1})},r.send(e.data)}))}},logger:(i=q,{debug:function(e,t){return D>=i&&console.debug(e,t),Promise.resolve()},info:function(e,t){return k>=i&&console.info(e,t),Promise.resolve()},error:function(e,t){return console.error(e,t),Promise.resolve()}}),responsesCache:o(),requestsCache:o({serializable:!1}),hostsCache:c({caches:[a({key:"".concat("4.24.0","-").concat(e)}),o()]}),userAgent:P("4.24.0").add({segment:"Browser",version:"lite"}),authMode:l.WithinQueryParameters};return S(r(r(r({},s),n),{},{methods:{search:T,searchForFacetValues:H,multipleQueries:T,multipleSearchForFacetValues:H,customRequest:A,initIndex:function(e){return function(t){return N(e)(t,{methods:{search:C,searchForFacetValues:I,findAnswers:Q}})}},getRecommendations:L}}))}return V.version="4.24.0",V}()},53465:(e,t,r)=>{"use strict";r.d(t,{W:()=>u});var n=r(96540),i=r(44586);const s=["zero","one","two","few","many","other"];function a(e){return s.filter((t=>e.includes(t)))}const c={locale:"en",pluralForms:a(["one","other"]),select:e=>1===e?"one":"other"};function o(){const{i18n:{currentLocale:e}}=(0,i.A)();return(0,n.useMemo)((()=>{try{return function(e){const t=new Intl.PluralRules(e);return{locale:e,pluralForms:a(t.resolvedOptions().pluralCategories),select:e=>t.select(e)}}(e)}catch(t){return console.error(`Failed to use Intl.PluralRules for locale "${e}".\nDocusaurus will fallback to the default (English) implementation.\nError: ${t.message}\n`),c}}),[e])}function u(){const e=o();return{selectMessage:(t,r)=>function(e,t,r){const n=e.split("|");if(1===n.length)return n[0];n.length>r.pluralForms.length&&console.error(`For locale=${r.locale}, a maximum of ${r.pluralForms.length} plural forms are expected (${r.pluralForms.join(",")}), but the message contains ${n.length}: ${e}`);const i=r.select(t),s=r.pluralForms.indexOf(i);return n[Math.min(s,n.length-1)]}(r,t,e)}}},74604:(e,t,r)=>{"use strict";r.r(t),r.d(t,{default:()=>w});var n=r(96540),i=r(34164),s=r(74103),a=r.n(s),c=r(83643),o=r.n(c),u=r(38193),h=r(5260),f=r(28774),l=r(44070),m=r(53465),d=r(24255),p=r(89532),g=r(45500),v=r(20481),y=r(21312),R=r(44586),F=r(38126),b=r(51062),j=r(79201),_=r(51107);const P={searchQueryInput:"searchQueryInput_u2C7",searchVersionInput:"searchVersionInput_m0Ui",searchResultsColumn:"searchResultsColumn_JPFH",algoliaLogo:"algoliaLogo_rT1R",algoliaLogoPathFill:"algoliaLogoPathFill_WdUC",searchResultItem:"searchResultItem_Tv2o",searchResultItemHeading:"searchResultItemHeading_KbCB",searchResultItemPath:"searchResultItemPath_lhe1",searchResultItemSummary:"searchResultItemSummary_AEaO",searchQueryColumn:"searchQueryColumn_RTkw",searchVersionColumn:"searchVersionColumn_ypXd",searchLogoColumn:"searchLogoColumn_rJIA",loadingSpinner:"loadingSpinner_XVxU","loading-spin":"loading-spin_vzvp",loader:"loader_vvXV"};var x=r(74848);function E(e){let{docsSearchVersionsHelpers:t}=e;const r=Object.entries(t.allDocsData).filter((e=>{let[,t]=e;return t.versions.length>1}));return(0,x.jsx)("div",{className:(0,i.A)("col","col--3","padding-left--none",P.searchVersionColumn),children:r.map((e=>{let[n,i]=e;const s=r.length>1?`${n}: `:"";return(0,x.jsx)("select",{onChange:e=>t.setSearchVersion(n,e.target.value),defaultValue:t.searchVersions[n],className:P.searchVersionInput,children:i.versions.map(((e,t)=>(0,x.jsx)("option",{label:`${s}${e.label}`,value:e.name},t)))},n)}))})}function O(){const{i18n:{currentLocale:e}}=(0,R.A)(),{algolia:{appId:t,apiKey:r,indexName:s,contextualSearch:c}}=(0,F.c)(),g=(0,b.C)(),O=function(){const{selectMessage:e}=(0,m.W)();return t=>e(t,(0,y.T)({id:"theme.SearchPage.documentsFound.plurals",description:'Pluralized label for "{count} documents found". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One document found|{count} documents found"},{count:t}))}(),w=function(){const e=(0,l.Gy)(),[t,r]=(0,n.useState)((()=>Object.entries(e).reduce(((e,t)=>{let[r,n]=t;return{...e,[r]:n.versions[0].name}}),{}))),i=Object.values(e).some((e=>e.versions.length>1));return{allDocsData:e,versioningEnabled:i,searchVersions:t,setSearchVersion:(e,t)=>r((r=>({...r,[e]:t})))}}(),[S,A]=(0,d.b)(),N={items:[],query:null,totalResults:null,totalPages:null,lastPage:null,hasMore:null,loading:null},[T,H]=(0,n.useReducer)(((e,t)=>{switch(t.type){case"reset":return N;case"loading":return{...e,loading:!0};case"update":return S!==t.value.query?e:{...t.value,items:0===t.value.lastPage?t.value.items:e.items.concat(t.value.items)};case"advance":{const t=e.totalPages>e.lastPage+1;return{...e,lastPage:t?e.lastPage+1:e.lastPage,hasMore:t}}default:return e}}),N),Q=c?["language","docusaurus_tag"]:[],C=o()(t,r),I=a()(C,s,{hitsPerPage:15,advancedSyntax:!0,disjunctiveFacets:Q});I.on("result",(e=>{let{results:{query:t,hits:r,page:n,nbHits:i,nbPages:s}}=e;if(""===t||!Array.isArray(r))return void H({type:"reset"});const a=e=>e.replace(/algolia-docsearch-suggestion--highlight/g,"search-result-match"),c=r.map((e=>{let{url:t,_highlightResult:{hierarchy:r},_snippetResult:n={}}=e;const i=Object.keys(r).map((e=>a(r[e].value)));return{title:i.pop(),url:g(t),summary:n.content?`${a(n.content.value)}...`:"",breadcrumbs:i}}));H({type:"update",value:{items:c,query:t,totalResults:i,totalPages:s,lastPage:n,hasMore:s>n+1,loading:!1}})}));const[D,k]=(0,n.useState)(null),q=(0,n.useRef)(0),L=(0,n.useRef)(u.A.canUseIntersectionObserver&&new IntersectionObserver((e=>{const{isIntersecting:t,boundingClientRect:{y:r}}=e[0];t&&q.current>r&&H({type:"advance"}),q.current=r}),{threshold:1})),V=()=>S?(0,y.T)({id:"theme.SearchPage.existingResultsTitle",message:'Search results for "{query}"',description:"The search page title for non-empty query"},{query:S}):(0,y.T)({id:"theme.SearchPage.emptyResultsTitle",message:"Search the documentation",description:"The search page title for empty query"}),B=(0,p._q)((function(t){void 0===t&&(t=0),c&&(I.addDisjunctiveFacetRefinement("docusaurus_tag","default"),I.addDisjunctiveFacetRefinement("language",e),Object.entries(w.searchVersions).forEach((e=>{let[t,r]=e;I.addDisjunctiveFacetRefinement("docusaurus_tag",`docs-${t}-${r}`)}))),I.setQuery(S).setPage(t).search()}));return(0,n.useEffect)((()=>{if(!D)return;const e=L.current;return e?(e.observe(D),()=>e.unobserve(D)):()=>!0}),[D]),(0,n.useEffect)((()=>{H({type:"reset"}),S&&(H({type:"loading"}),setTimeout((()=>{B()}),300))}),[S,w.searchVersions,B]),(0,n.useEffect)((()=>{T.lastPage&&0!==T.lastPage&&B(T.lastPage)}),[B,T.lastPage]),(0,x.jsxs)(j.A,{children:[(0,x.jsxs)(h.A,{children:[(0,x.jsx)("title",{children:(0,v.s)(V())}),(0,x.jsx)("meta",{property:"robots",content:"noindex, follow"})]}),(0,x.jsxs)("div",{className:"container margin-vert--lg",children:[(0,x.jsx)(_.A,{as:"h1",children:V()}),(0,x.jsxs)("form",{className:"row",onSubmit:e=>e.preventDefault(),children:[(0,x.jsx)("div",{className:(0,i.A)("col",P.searchQueryColumn,{"col--9":w.versioningEnabled,"col--12":!w.versioningEnabled}),children:(0,x.jsx)("input",{type:"search",name:"q",className:P.searchQueryInput,placeholder:(0,y.T)({id:"theme.SearchPage.inputPlaceholder",message:"Type your search here",description:"The placeholder for search page input"}),"aria-label":(0,y.T)({id:"theme.SearchPage.inputLabel",message:"Search",description:"The ARIA label for search page input"}),onChange:e=>A(e.target.value),value:S,autoComplete:"off",autoFocus:!0})}),c&&w.versioningEnabled&&(0,x.jsx)(E,{docsSearchVersionsHelpers:w})]}),(0,x.jsxs)("div",{className:"row",children:[(0,x.jsx)("div",{className:(0,i.A)("col","col--8",P.searchResultsColumn),children:!!T.totalResults&&O(T.totalResults)}),(0,x.jsx)("div",{className:(0,i.A)("col","col--4","text--right",P.searchLogoColumn),children:(0,x.jsx)(f.A,{to:"https://www.algolia.com/","aria-label":(0,y.T)({id:"theme.SearchPage.algoliaLabel",message:"Search by Algolia",description:"The ARIA label for Algolia mention"}),children:(0,x.jsx)("svg",{viewBox:"0 0 168 24",className:P.algoliaLogo,children:(0,x.jsxs)("g",{fill:"none",children:[(0,x.jsx)("path",{className:P.algoliaLogoPathFill,d:"M120.925 18.804c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17zM6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z"}),(0,x.jsx)("path",{fill:"#5468FF",d:"M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938z"}),(0,x.jsx)("path",{fill:"white",d:"M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36"})]})})})})]}),T.items.length>0?(0,x.jsx)("main",{children:T.items.map(((e,t)=>{let{title:r,url:n,summary:s,breadcrumbs:a}=e;return(0,x.jsxs)("article",{className:P.searchResultItem,children:[(0,x.jsx)(_.A,{as:"h2",className:P.searchResultItemHeading,children:(0,x.jsx)(f.A,{to:n,dangerouslySetInnerHTML:{__html:r}})}),a.length>0&&(0,x.jsx)("nav",{"aria-label":"breadcrumbs",children:(0,x.jsx)("ul",{className:(0,i.A)("breadcrumbs",P.searchResultItemPath),children:a.map(((e,t)=>(0,x.jsx)("li",{className:"breadcrumbs__item",dangerouslySetInnerHTML:{__html:e}},t)))})}),s&&(0,x.jsx)("p",{className:P.searchResultItemSummary,dangerouslySetInnerHTML:{__html:s}})]},t)}))}):[S&&!T.loading&&(0,x.jsx)("p",{children:(0,x.jsx)(y.A,{id:"theme.SearchPage.noResultsText",description:"The paragraph for empty search result",children:"No results were found"})},"no-results"),!!T.loading&&(0,x.jsx)("div",{className:P.loadingSpinner},"spinner")],T.hasMore&&(0,x.jsx)("div",{className:P.loader,ref:k,children:(0,x.jsx)(y.A,{id:"theme.SearchPage.fetchingNewResults",description:"The paragraph for fetching new search results",children:"Fetching new results..."})})]})]})}function w(){return(0,x.jsx)(g.e3,{className:"search-page-wrapper",children:(0,x.jsx)(O,{})})}}}]); \ No newline at end of file diff --git a/assets/js/1b0eecbc.03a68f28.js b/assets/js/1b0eecbc.03a68f28.js new file mode 100644 index 000000000..5d08cb281 --- /dev/null +++ b/assets/js/1b0eecbc.03a68f28.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80526],{62284:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>s,default:()=>i,frontMatter:()=>t,metadata:()=>r,toc:()=>o});var c=a(74848),d=a(28453);const t={},s="Transactional JSON-RPC Methods {#transactional}",r={id:"developers/json-rpc/json-rpc-transactional",title:"Transactional JSON-RPC Methods",description:"transactional}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-transactional.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-transactional",permalink:"/1.5.X/developers/json-rpc/json-rpc-transactional",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Required Methods for Minimal Compliance",permalink:"/1.5.X/developers/json-rpc/minimal-compliance"},next:{title:"Informational JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-informational"}},f={},o=[{value:"account_put_deploy",id:"account-put-deploy",level:2},{value:"<code>account_put_deploy_result</code>",id:"account_put_deploy_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"<code>speculative_exec_result</code>",id:"speculative_exec_result",level:3}];function b(e){const n={a:"a",blockquote:"blockquote",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"transactional",children:"Transactional JSON-RPC Methods"})}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"account-put-deploy",children:"account_put_deploy"}),"\n",(0,c.jsxs)(n.p,{children:["This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy"})," as a parameter, prior to sending it to a node on a network for execution."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,c.jsxs)(n.blockquote,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Note"}),": You can find a list of ",(0,c.jsx)(n.a,{href:"/1.5.X/operators/setup/joining",children:"trusted peers"})," in the network's configuration file, ",(0,c.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example config.toml"}),". You may send deploys to one of the trusted nodes or use them to query other online nodes."]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example account_put_deploy request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "approvals": [\n {\n "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"\n }\n ],\n "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",\n "header": {\n "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",\n "chain_name": "casper-net-1",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2023-09-26T14:07:10.024Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512"\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"\n }\n ]\n ]\n }\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"account_put_deploy_result",children:(0,c.jsx)(n.code,{children:"account_put_deploy_result"})}),"\n",(0,c.jsxs)(n.p,{children:["The result contains the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"}),", which is the primary identifier of a Deploy within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"A hex-encoded hash of the Deploy as sent."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example account_put_deploy result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"speculative_exec",children:"speculative_exec"}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a ",(0,c.jsx)(n.code,{children:"Deploy"})," without committing its execution effects to global state. By default, ",(0,c.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, ",(0,c.jsx)(n.code,{children:"speculative_exec"})," operates on a separate port from the primary JSON-RPC, using 7778."]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"speculative_exec"})," executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example speculative_exec request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "block_identifier": null,\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"speculative_exec_result",children:(0,c.jsx)(n.code,{children:"speculative_exec_result"})}),"\n",(0,c.jsx)(n.p,{children:"The result contains the hash of the targeted block and the results of the execution."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash on top of which the deploy was executed."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#executionresult",children:"execution_results"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The map of Block hash to execution result."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example speculative_exec result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -8801853076373554652,\n "result": {\n "api_version": "1.5.0",\n "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0ed2d5887",\n "parsed": "581299990000"\n }\n }\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": {\n "AddUInt512": "2500000000"\n }\n },\n {\n "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",\n "amount": "2500000000",\n "gas": "0",\n "id": 0\n }\n }\n },\n {\n "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function i(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(b,{...e})}):b(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var c=a(96540);const d={},t=c.createContext(d);function s(e){const n=c.useContext(t);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:s(e.components),c.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1b0eecbc.35fe077e.js b/assets/js/1b0eecbc.35fe077e.js deleted file mode 100644 index 4ddb13317..000000000 --- a/assets/js/1b0eecbc.35fe077e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[526],{62284:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>s,default:()=>i,frontMatter:()=>t,metadata:()=>r,toc:()=>o});var c=a(74848),d=a(28453);const t={},s="Transactional JSON-RPC Methods {#transactional}",r={id:"developers/json-rpc/json-rpc-transactional",title:"Transactional JSON-RPC Methods",description:"transactional}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-transactional.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-transactional",permalink:"/developers/json-rpc/json-rpc-transactional",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Required Methods for Minimal Compliance",permalink:"/developers/json-rpc/minimal-compliance"},next:{title:"Informational JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-informational"}},f={},o=[{value:"account_put_deploy",id:"account-put-deploy",level:2},{value:"<code>account_put_deploy_result</code>",id:"account_put_deploy_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"<code>speculative_exec_result</code>",id:"speculative_exec_result",level:3}];function b(e){const n={a:"a",blockquote:"blockquote",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"transactional",children:"Transactional JSON-RPC Methods"})}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"account-put-deploy",children:"account_put_deploy"}),"\n",(0,c.jsxs)(n.p,{children:["This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy"})," as a parameter, prior to sending it to a node on a network for execution."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,c.jsxs)(n.blockquote,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Note"}),": You can find a list of ",(0,c.jsx)(n.a,{href:"/operators/setup/joining",children:"trusted peers"})," in the network's configuration file, ",(0,c.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example config.toml"}),". You may send deploys to one of the trusted nodes or use them to query other online nodes."]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example account_put_deploy request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "approvals": [\n {\n "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"\n }\n ],\n "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",\n "header": {\n "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",\n "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",\n "chain_name": "casper-net-1",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2023-09-26T14:07:10.024Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512"\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"\n }\n ]\n ]\n }\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"account_put_deploy_result",children:(0,c.jsx)(n.code,{children:"account_put_deploy_result"})}),"\n",(0,c.jsxs)(n.p,{children:["The result contains the ",(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"}),", which is the primary identifier of a Deploy within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"A hex-encoded hash of the Deploy as sent."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example account_put_deploy result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"speculative_exec",children:"speculative_exec"}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a ",(0,c.jsx)(n.code,{children:"Deploy"})," without committing its execution effects to global state. By default, ",(0,c.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, ",(0,c.jsx)(n.code,{children:"speculative_exec"})," operates on a separate port from the primary JSON-RPC, using 7778."]}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"speculative_exec"})," executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example speculative_exec request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "block_identifier": null,\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"speculative_exec_result",children:(0,c.jsx)(n.code,{children:"speculative_exec_result"})}),"\n",(0,c.jsx)(n.p,{children:"The result contains the hash of the targeted block and the results of the execution."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash on top of which the deploy was executed."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#executionresult",children:"execution_results"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The map of Block hash to execution result."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example speculative_exec result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -8801853076373554652,\n "result": {\n "api_version": "1.5.0",\n "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0e630ed87",\n "parsed": "583799990000"\n }\n }\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": "Identity"\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": "Identity"\n },\n {\n "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05f0ed2d5887",\n "parsed": "581299990000"\n }\n }\n },\n {\n "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",\n "transform": {\n "AddUInt512": "2500000000"\n }\n },\n {\n "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",\n "amount": "2500000000",\n "gas": "0",\n "id": 0\n }\n }\n },\n {\n "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",\n "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",\n "transform": "Identity"\n },\n {\n "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": "Identity"\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": "Identity"\n },\n {\n "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function i(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(b,{...e})}):b(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var c=a(96540);const d={},t=c.createContext(d);function s(e){const n=c.useContext(t);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:s(e.components),c.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1b2f0a70.1f2d7217.js b/assets/js/1b2f0a70.1f2d7217.js new file mode 100644 index 000000000..a89f359ae --- /dev/null +++ b/assets/js/1b2f0a70.1f2d7217.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[414],{77553:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=t(74848),s=t(28453);const r={},i="Required Methods for Minimal Compliance",a={id:"developers/json-rpc/minimal-compliance",title:"Required Methods for Minimal Compliance",description:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.",source:"@site/docs/developers/json-rpc/minimal-compliance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/minimal-compliance",permalink:"/developers/json-rpc/minimal-compliance",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/developers/json-rpc/guidance"},next:{title:"Transactional JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-transactional"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"required-methods-for-minimal-compliance",children:"Required Methods for Minimal Compliance"})}),"\n",(0,o.jsx)(n.p,{children:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#chain_get_block",children:(0,o.jsx)(n.code,{children:"chain_get_block"})})," - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#info_get_deploy",children:(0,o.jsx)(n.code,{children:"info_get_deploy"})})," - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-transactional#account_put_deploy",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#chain_get_state_root_hash",children:(0,o.jsx)(n.code,{children:"chain_get_state_root_hash"})})," - The state root hash is one of the several ",(0,o.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"global state identifiers"})," used to query the network state after sending deploys."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#state_get_account_info",children:(0,o.jsx)(n.code,{children:"state_get_account_info"})})," - This method returns a JSON representation of an Account from the network. ",(0,o.jsx)(n.code,{children:"state_get_account_info"})," is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#query_balance",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#state_get_dictionary_item",children:(0,o.jsx)(n.code,{children:"state_get_dictionary_item"})})," - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["The deprecated methods ",(0,o.jsx)(n.code,{children:"state_get_balance"})," and ",(0,o.jsx)(n.code,{children:"state_get_item"})," should not be used."]})}),"\n",(0,o.jsxs)(n.p,{children:["In addition to these methods, a minimally compliant Casper SDK must account for the ",(0,o.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"types"})," 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."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1b2f0a70.d99e2656.js b/assets/js/1b2f0a70.d99e2656.js deleted file mode 100644 index e348ab6c9..000000000 --- a/assets/js/1b2f0a70.d99e2656.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[414],{77553:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=t(74848),s=t(28453);const r={},i="Required Methods for Minimal Compliance",a={id:"developers/json-rpc/minimal-compliance",title:"Required Methods for Minimal Compliance",description:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.",source:"@site/docs/developers/json-rpc/minimal-compliance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/minimal-compliance",permalink:"/next/developers/json-rpc/minimal-compliance",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/next/developers/json-rpc/guidance"},next:{title:"Transactional JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-transactional"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"required-methods-for-minimal-compliance",children:"Required Methods for Minimal Compliance"})}),"\n",(0,o.jsx)(n.p,{children:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#chain_get_block",children:(0,o.jsx)(n.code,{children:"chain_get_block"})})," - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#info_get_deploy",children:(0,o.jsx)(n.code,{children:"info_get_deploy"})})," - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-transactional#account_put_deploy",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#chain_get_state_root_hash",children:(0,o.jsx)(n.code,{children:"chain_get_state_root_hash"})})," - The state root hash is one of the several ",(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#globalstateidentifier",children:"global state identifiers"})," used to query the network state after sending deploys."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#state_get_account_info",children:(0,o.jsx)(n.code,{children:"state_get_account_info"})})," - This method returns a JSON representation of an Account from the network. ",(0,o.jsx)(n.code,{children:"state_get_account_info"})," is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#query_balance",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#state_get_dictionary_item",children:(0,o.jsx)(n.code,{children:"state_get_dictionary_item"})})," - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["The deprecated methods ",(0,o.jsx)(n.code,{children:"state_get_balance"})," and ",(0,o.jsx)(n.code,{children:"state_get_item"})," should not be used."]})}),"\n",(0,o.jsxs)(n.p,{children:["In addition to these methods, a minimally compliant Casper SDK must account for the ",(0,o.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain",children:"types"})," 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."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1b312e15.3da2e07f.js b/assets/js/1b312e15.3da2e07f.js new file mode 100644 index 000000000..45051b5ed --- /dev/null +++ b/assets/js/1b312e15.3da2e07f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[44683],{84147:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=r(74848),o=r(28453);const i={title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},s="Getting Started Video",a={id:"resources/beginner/getting-started-tutorial",title:"Getting Started",description:"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/getting-started-tutorial.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/getting-started-tutorial",permalink:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},sidebar:"tutorials",previous:{title:"Overview",permalink:"/2.0.0/resources/tutorials/beginner/"},next:{title:"Introduction",permalink:"/2.0.0/counter"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",iframe:"iframe",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started-video",children:"Getting Started Video"})}),"\n",(0,n.jsxs)(t.p,{children:["This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started documentation"}),"."]}),"\n",(0,n.jsxs)(t.p,{align:"center",children:["\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=XvV02iBoctc&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=1",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1c694ffb.e2c21c8e.js b/assets/js/1c694ffb.e2c21c8e.js new file mode 100644 index 000000000..6debe46cf --- /dev/null +++ b/assets/js/1c694ffb.e2c21c8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86898],{10289:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const c={},i="Getting Started with AssemblyScript",a={id:"developers/writing-onchain-code/assembly-script",title:"Getting Started with AssemblyScript",description:"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.",source:"@site/docs/developers/writing-onchain-code/assembly-script.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/assembly-script",permalink:"/developers/writing-onchain-code/assembly-script",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with Rust",permalink:"/developers/writing-onchain-code/getting-started"},next:{title:"Writing a Basic Smart Contract in Rust",permalink:"/developers/writing-onchain-code/simple-contract"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing AssemblyScript",id:"installing-assemblyscript",level:3},{value:"Development Environment Setup",id:"development-environment-setup",level:2},{value:"Installing the Casper Package",id:"installing-the-casper-package",level:3},{value:"Creating a Project",id:"creating-a-project",level:3},{value:"Script Entries",id:"script-entries",level:3},{value:"Sample Smart Contract",id:"sample-smart-contract",level:3},{value:"Compile to Wasm",id:"compile-to-wasm",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"getting-started-with-assemblyscript",children:"Getting Started with AssemblyScript"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper Labs maintains the ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"casper-contract"})," to allow developers to create smart contracts using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"AssemblyScript"}),". The package source is hosted in the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/smart_contracts/contract_as/assembly",children:"main Casper Network repository"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.h3,{id:"installing-assemblyscript",children:"Installing AssemblyScript"}),"\n",(0,s.jsxs)(n.p,{children:["Installation of AssemblyScript requires ",(0,s.jsx)(n.a,{href:"https://nodejs.org/",children:"Node.js"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After installation of Node.js, the following command will install AssemblyScript:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i assemblyscript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Full instructions and details for installing AssemblyScript can be found ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"development-environment-setup",children:"Development Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-casper-package",children:"Installing the Casper Package"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-contract"})," package can be installed using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i casper-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Assemblyscript contract API documentation can be found at ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"https://www.npmjs.com/package/casper-contract"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsx)(n.p,{children:"For each smart contract, it is necessary to create a project directory and initialize it."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"npm init"})," process prompts for various details about the project. Answer as you see fit, but you may safely default everything except ",(0,s.jsx)(n.code,{children:"name"}),", which needs to be specified. In this guide, we will refer to the contract name as ",(0,s.jsx)(n.code,{children:"your-contract-name"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir project\ncd project\nnpm init\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then install AssemblyScript and this package in the project directory."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev assemblyscript@0.9.1\nnpm install --save casper-contract\n"})}),"\n",(0,s.jsx)(n.h3,{id:"script-entries",children:"Script Entries"}),"\n",(0,s.jsxs)(n.p,{children:["Add script entries for AssemblyScript to your project's ",(0,s.jsx)(n.code,{children:"package.json"}),". Note that your contract name is used for the name of the Wasm file. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "your-contract-name",\n ...\n "scripts": {\n "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",\n "asbuild": "npm run asbuild:optimized",\n ...\n },\n ...\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the project root, create an ",(0,s.jsx)(n.code,{children:"index.js"})," file with the following contents. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'const fs = require("fs");\n\nconst compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));\n\nconst imports = {\n env: {\n abort(_msg, _file, line, column) {\n console.error("abort called at index.ts:" + line + ":" + column);\n },\n },\n};\n\nObject.defineProperty(module, "exports", {\n get: () => new WebAssembly.Instance(compiled, imports).exports,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a directory called ",(0,s.jsx)(n.code,{children:"assembly"}),", and in that directory, create a file called ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," in the following way:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-smart-contract",children:"Sample Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"assembly"})," directory, also create an ",(0,s.jsx)(n.code,{children:"index.ts"})," file, where the code for the contract needs to go."]}),"\n",(0,s.jsx)(n.p,{children:"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer a more complicated first contract, you can look at example contracts on the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem GitHub"})," repository for inspiration."]}),"\n",(0,s.jsx)(n.h3,{id:"compile-to-wasm",children:"Compile to Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["To compile the contract to Wasm, use ",(0,s.jsx)(n.em,{children:"npm"})," to run the ",(0,s.jsx)(n.em,{children:"asbuild"})," script from the project root:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm run asbuild\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the build is successful, there will be a ",(0,s.jsx)(n.code,{children:"dist"})," folder in the ",(0,s.jsx)(n.code,{children:"root"})," folder and in it should be ",(0,s.jsx)(n.code,{children:"your-contract-name.wasm"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1c694ffb.eb41d9b2.js b/assets/js/1c694ffb.eb41d9b2.js deleted file mode 100644 index 3028238d5..000000000 --- a/assets/js/1c694ffb.eb41d9b2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6898],{10289:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const c={},i="Getting Started with AssemblyScript",a={id:"developers/writing-onchain-code/assembly-script",title:"Getting Started with AssemblyScript",description:"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.",source:"@site/docs/developers/writing-onchain-code/assembly-script.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/assembly-script",permalink:"/next/developers/writing-onchain-code/assembly-script",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with Rust",permalink:"/next/developers/writing-onchain-code/getting-started"},next:{title:"Writing a Basic Smart Contract in Rust",permalink:"/next/developers/writing-onchain-code/simple-contract"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing AssemblyScript",id:"installing-assemblyscript",level:3},{value:"Development Environment Setup",id:"development-environment-setup",level:2},{value:"Installing the Casper Package",id:"installing-the-casper-package",level:3},{value:"Creating a Project",id:"creating-a-project",level:3},{value:"Script Entries",id:"script-entries",level:3},{value:"Sample Smart Contract",id:"sample-smart-contract",level:3},{value:"Compile to Wasm",id:"compile-to-wasm",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"getting-started-with-assemblyscript",children:"Getting Started with AssemblyScript"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper Labs maintains the ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"casper-contract"})," to allow developers to create smart contracts using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"AssemblyScript"}),". The package source is hosted in the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/smart_contracts/contract_as/assembly",children:"main Casper Network repository"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.h3,{id:"installing-assemblyscript",children:"Installing AssemblyScript"}),"\n",(0,s.jsxs)(n.p,{children:["Installation of AssemblyScript requires ",(0,s.jsx)(n.a,{href:"https://nodejs.org/",children:"Node.js"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After installation of Node.js, the following command will install AssemblyScript:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i assemblyscript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Full instructions and details for installing AssemblyScript can be found ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"development-environment-setup",children:"Development Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-casper-package",children:"Installing the Casper Package"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-contract"})," package can be installed using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i casper-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Assemblyscript contract API documentation can be found at ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"https://www.npmjs.com/package/casper-contract"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsx)(n.p,{children:"For each smart contract, it is necessary to create a project directory and initialize it."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"npm init"})," process prompts for various details about the project. Answer as you see fit, but you may safely default everything except ",(0,s.jsx)(n.code,{children:"name"}),", which needs to be specified. In this guide, we will refer to the contract name as ",(0,s.jsx)(n.code,{children:"your-contract-name"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir project\ncd project\nnpm init\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then install AssemblyScript and this package in the project directory."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev assemblyscript@0.9.1\nnpm install --save casper-contract\n"})}),"\n",(0,s.jsx)(n.h3,{id:"script-entries",children:"Script Entries"}),"\n",(0,s.jsxs)(n.p,{children:["Add script entries for AssemblyScript to your project's ",(0,s.jsx)(n.code,{children:"package.json"}),". Note that your contract name is used for the name of the Wasm file. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "your-contract-name",\n ...\n "scripts": {\n "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",\n "asbuild": "npm run asbuild:optimized",\n ...\n },\n ...\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the project root, create an ",(0,s.jsx)(n.code,{children:"index.js"})," file with the following contents. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'const fs = require("fs");\n\nconst compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));\n\nconst imports = {\n env: {\n abort(_msg, _file, line, column) {\n console.error("abort called at index.ts:" + line + ":" + column);\n },\n },\n};\n\nObject.defineProperty(module, "exports", {\n get: () => new WebAssembly.Instance(compiled, imports).exports,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a directory called ",(0,s.jsx)(n.code,{children:"assembly"}),", and in that directory, create a file called ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," in the following way:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-smart-contract",children:"Sample Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"assembly"})," directory, also create an ",(0,s.jsx)(n.code,{children:"index.ts"})," file, where the code for the contract needs to go."]}),"\n",(0,s.jsx)(n.p,{children:"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer a more complicated first contract, you can look at example contracts on the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem GitHub"})," repository for inspiration."]}),"\n",(0,s.jsx)(n.h3,{id:"compile-to-wasm",children:"Compile to Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["To compile the contract to Wasm, use ",(0,s.jsx)(n.em,{children:"npm"})," to run the ",(0,s.jsx)(n.em,{children:"asbuild"})," script from the project root:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm run asbuild\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the build is successful, there will be a ",(0,s.jsx)(n.code,{children:"dist"})," folder in the ",(0,s.jsx)(n.code,{children:"root"})," folder and in it should be ",(0,s.jsx)(n.code,{children:"your-contract-name.wasm"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1cd8ca26.cbdbeb37.js b/assets/js/1cd8ca26.cbdbeb37.js new file mode 100644 index 000000000..1381b9b13 --- /dev/null +++ b/assets/js/1cd8ca26.cbdbeb37.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94531],{18144:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>t,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>l});var s=a(74848),r=a(28453);const d={},t="Informational JSON-RPC Methods",c={id:"developers/json-rpc/json-rpc-informational",title:"Informational JSON-RPC Methods",description:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-informational.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-informational",permalink:"/2.0.0/developers/json-rpc/json-rpc-informational",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Transactional JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-transactional"},next:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-pos"}},i={},l=[{value:"chain_get_block",id:"chain_get_block",level:2},{value:"<code>chain_get_block_result</code>",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain_get_block_transfers",level:2},{value:"<code>chain_get_block_transfers_result</code>",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain_get_era_summary",level:2},{value:"<code>chain_get_era_summary_result</code>",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain_get_state_root_hash",level:2},{value:"<code>chain_get_state_root_hash_result</code>",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info_get_chainspec",level:2},{value:"<code>info_get_chainspec_result</code>",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info_get_deploy",level:2},{value:"<code>info_get_deploy_result</code>",id:"info_get_deploy_result",level:3},{value:"info_get_reward",id:"info_get_reward",level:2},{value:"<code>info_get_reward_result</code>",id:"info_get_reward_result",level:3},{value:"info_get_transaction",id:"info_get_transaction",level:2},{value:"<code>info_get_transaction_result</code>",id:"info_get_transaction_result",level:3},{value:"query_balance",id:"query_balance",level:2},{value:"<code>query_balance_result</code>",id:"query_balance_result",level:3},{value:"query_balance_details",id:"query_balance_details",level:2},{value:"<code>query_balance_details_result</code>",id:"query_balance_details_result",level:3},{value:"query_global_state",id:"query_global_state",level:2},{value:"<code>query_global_state_result</code>",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state_get_account_info",level:2},{value:"<code>state_get_account_info_result</code>",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state_get_dictionary_item",level:2},{value:"<code>state_get_dictionary_item_result</code>",id:"state_get_dictionary_item_result",level:3},{value:"state_get_entity",id:"state_get_entity",level:2},{value:"<code>state_get_entity_result</code>",id:"state_get_entity_result",level:3},{value:"info_get_peers",id:"info_get_peers",level:2},{value:"<code>info_get_peers_result</code>",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info_get_status",level:2},{value:"<code>info_get_status_result</code>",id:"info_get_status_result",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"informational-json-rpc-methods",children:"Informational JSON-RPC Methods"})}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block",children:"chain_get_block"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the JSON representation of a ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"})," from the network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash or the Block height. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_result"})}),"\n",(0,s.jsxs)(n.p,{children:["The result from ",(0,s.jsx)(n.code,{children:"chain_get_block"})," depends on block availability from a given node. If ",(0,s.jsx)(n.code,{children:"chain_get_block"})," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#jsonblockwithsignatures",children:"block"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_result",\n "value": {\n "api_version": "2.0.0",\n "block_with_signatures": {\n "block": {\n "Version2": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "header": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "48859fb4865d8637d6a35cb224e222cd0e1b1c2dd72928932c1e35ac0550818b",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a"\n },\n "body": {\n "transactions": {\n "0": [\n {\n "Version1": "1414141414141414141414141414141414141414141414141414141414141414"\n }\n ],\n "1": [\n {\n "Version1": "1515151515151515151515151515151515151515151515151515151515151515"\n }\n ],\n "2": [\n {\n "Version1": "1616161616161616161616161616161616161616161616161616161616161616"\n }\n ],\n "3": [\n {\n "Version1": "1717171717171717171717171717171717171717171717171717171717171717"\n }\n ]\n },\n "rewarded_signatures": []\n }\n }\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "01e18ca03d2ef0238a6a2460a222e0b818406bda99d4c05502c80232013559b926d1c8bca6bf65386f54a847d7850cb76c0c5fd5e633c34c749b8b9958a638d806"\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block_transfers",children:"chain_get_block_transfers"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns all ",(0,s.jsx)(n.strong,{children:"successful"})," native transfers within a given ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"})," from a network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the transfers from the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_transfers_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_transfers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash, if found. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#transfer",children:"transfers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The Block's successful transfers, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_transfers_result",\n "value": {\n "api_version": "2.0.0",\n "block_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_era_summary",children:"chain_get_era_summary"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the era summary at a given ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the era summary at the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_era_summary_result",children:(0,s.jsx)(n.code,{children:"chain_get_era_summary_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "chain_get_era_summary_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_state_root_hash",children:"chain_get_state_root_hash"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a state root hash at a given ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Height": 10\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_state_root_hash_result",children:(0,s.jsx)(n.code,{children:"chain_get_state_root_hash_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hex-encoded hash of the state root."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_state_root_hash_result",\n "value": {\n "api_version": "2.0.0",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_chainspec",children:"info_get_chainspec"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 5510244237763930243,\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_chainspec_result",children:(0,s.jsx)(n.code,{children:"info_get_chainspec_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#chainspecrawbytes",children:"chainspec_bytes"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec result"}),"\n",(0,s.jsxs)(n.p,{children:["Please note that adding a ",(0,s.jsx)(n.code,{children:"--vv"})," flag will return the full chainspec bytes."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_chainspec_result",\n "value": {\n "api_version": "2.0.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n }\n },\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_deploy",children:"info_get_deploy"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"DEPRECATED"}),": Use ",(0,s.jsx)(n.a,{href:"#info_get_transaction",children:"info_get_transaction"})," instead."]})}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#execution-semantics-deploys",children:"Deploy"})," from a network. It requires a ",(0,s.jsx)(n.code,{children:"deploy_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The Deploy hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n {\n "name": "deploy_hash",\n "value": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_deploy_result",children:(0,s.jsx)(n.code,{children:"info_get_deploy_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the Deploy and the results of executing the Deploy."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", but has yet to execute it. If the network executed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Deploy."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_reward",children:"info_get_reward"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the reward for a given era and a validator or delegator."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#publickey",children:"validator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key of the validator."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#eraidentifier",children:"era_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsxs)(n.td,{children:["The era identifier. If ",(0,s.jsx)(n.code,{children:"None"}),", the last finalized era is used. (Optional)"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#publickey",children:"delegator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsxs)(n.td,{children:["The public key of the delegator. If ",(0,s.jsx)(n.code,{children:"Some"}),", the rewards for the delegator are returned. If ",(0,s.jsx)(n.code,{children:"None"}),", the rewards for the validator are returned. (Optional)"]})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_reward",\n "params": [\n {\n "name": "era_identifier",\n "value": {\n "Era": 1\n }\n },\n {\n "name": "validator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n {\n "name": "delegator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_reward_result",children:(0,s.jsx)(n.code,{children:"info_get_reward_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#eraid",children:"era_id"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The era for which the reward was calculated."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#u512",children:"reward_amount"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The total reward amount in the requested era."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_reward_result",\n "value": {\n "api_version": "2.0.0",\n "reward_amount": "42",\n "era_id": 1\n }\n } \n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_transaction",children:"info_get_transaction"}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a transaction from a network. It requires a ",(0,s.jsx)(n.code,{children:"transaction_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The transaction hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the transaction with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_transaction",\n "params": [\n {\n "name": "transaction_hash",\n "value": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_transaction_result",children:(0,s.jsx)(n.code,{children:"info_get_transaction_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the transaction and the results of executing it on the network."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the transaction but has yet to execute it. If the network executed the transaction, it will return the execution information, along with the block hash containing the transaction."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The transaction."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n } \n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance",children:"query_balance"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for the balance of a purse using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_result",children:(0,s.jsx)(n.code,{children:"query_balance_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#u512",children:"balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The balance represented in motes."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_result",\n "value": {\n "api_version": "2.0.0",\n "balance": "123456"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance_details",children:"query_balance_details"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for full balance information using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance_details",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_details_result",children:(0,s.jsx)(n.code,{children:"query_balance_details_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#u512",children:"available_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available balance in motes (total balance - sum of all active holds)."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#balanceholdwithproof",children:"holds"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The holds active at the requested point in time."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#u512",children:"total_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The purses total balance, not considering holds."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"`total_balance_proof"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"A proof that the given value is present in the Merkle trie."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_details_result",\n "value": {\n "api_version": "2.0.0",\n "total_balance": "123456",\n "available_balance": "123456",\n "total_balance_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "holds": [\n {\n "time": 0,\n "amount": "123456",\n "proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_global_state",children:"query_global_state"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block_hash",children:"Block hash"})," or state root hash."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Note: Querying a purse's balance requires the use of ",(0,s.jsx)(n.code,{children:"query_balance"}),", rather than any iteration of ",(0,s.jsx)(n.code,{children:"query_global_state"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#key",children:"key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key as a formatted string, under which data can be stored in global state."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier used for the query. If not provided, the tip of the chain will be used. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"path"}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The path components starting from the key as base. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n },\n {\n "name": "key",\n "value": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"\n },\n {\n "name": "path",\n "value": []\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_global_state_result",children:(0,s.jsx)(n.code,{children:"query_global_state_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockheaderv2",children:"block_header"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block header if a Block hash was provided. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "2.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "0505050505050505050505050505050505050505050505050505050505050505",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0909090909090909090909090909090909090909090909090909090909090909"\n }\n },\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_account_info",children:"state_get_account_info"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Account"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the account at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the Account's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#accountidentifier",children:"account_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key or account hash of the Account."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "name": "account_identifier",\n "value": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_account_info_result",children:(0,s.jsx)(n.code,{children:"state_get_account_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#account",children:"account"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the Account structure."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_account_info_result",\n "value": {\n "api_version": "2.0.0",\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_dictionary_item",children:"state_get_dictionary_item"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,s.jsx)(n.code,{children:"dictionary_identifier"}),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."]}),"\n",(0,s.jsx)(n.p,{children:"You may query a stored value directly using the dictionary address."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hash of the state root."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#dictionaryidentifier",children:"dictionary_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Dictionary query identifier."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "name": "state_root_hash",\n "value": "0808080808080808080808080808080808080808080808080808080808080808"\n },\n {\n "name": "dictionary_identifier",\n "value": {\n "URef": {\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "dictionary_item_key": "a_unique_entry_identifier"\n }\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_dictionary_item_result",children:(0,s.jsx)(n.code,{children:"state_get_dictionary_item_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"dictionary_key"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key under which the value is stored."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_dictionary_item_result",\n "value": {\n "api_version": "2.0.0",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "stored_value": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_entity",children:"state_get_entity"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#addressableentity",children:"AddressableEntity"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the entity at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the entity's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#entityidentifier",children:"entity_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Identifier of an addressable entity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_entity",\n "params": [\n {\n "name": "entity_identifier",\n "value": {\n "EntityAddr": "entity-account-0000000000000000000000000000000000000000000000000000000000000000"\n }\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_entity_result",children:(0,s.jsx)(n.code,{children:"state_get_entity_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#addressableentity",children:"entity"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the AddressableEntity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_entity_result",\n "value": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c"\n },\n "package_hash": "package-0000000000000000000000000000000000000000000000000000000000000000",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "topic",\n "topic_name_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n ]\n },\n "named_keys": [\n {\n "name": "key",\n "key": "hash-0000000000000000000000000000000000000000000000000000000000000000"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "entry_point",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Caller",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h1,{id:"node-informational-json-rpc-methods",children:"Node Informational JSON-RPC Methods"}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"info_get_peers",children:"info_get_peers"}),"\n",(0,s.jsx)(n.p,{children:"This method returns a list of peers connected to the node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_peers_result",children:(0,s.jsx)(n.code,{children:"info_get_peers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#peers",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_peers_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_status",children:"info_get_status"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the current status of a node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_status_result",children:(0,s.jsx)(n.code,{children:"info_get_status_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#availableblockrange",children:"available_block_range"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available block range in storage."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blocksynchronizerstatus",children:"block_sync"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The status of the block synchronizer builders."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"build_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The compiled node version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"chainspec_name"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The chainspec name, used to identify the currently connected network."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#minimalblockinfo",children:"last_added_block_info"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The minimal info of the last Block from the linear chain. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#timestamp",children:"last_progress"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Timestamp of the last recorded progress in the reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockhash",children:"latest_switch_block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The hash of the latest switch block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#nextupgrade",children:"next_upgrade"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"Information about the next scheduled upgrade. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#publickey",children:"our_public_signing_key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Our public signing key. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#reactorstate",children:"reactor_state"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The current state of the node reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#timediff",children:"round_length"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#digest",children:"starting_state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The state root hash used at the start of the current session."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#timediff",children:"uptime"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"Time that passed since the node has started."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "last_added_block_info": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n },\n "latest_switch_block_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n }\n}\n}\n\n'})}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>t,x:()=>c});var s=a(96540);const r={},d=s.createContext(r);function t(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e144f6d.3fce115e.js b/assets/js/1e144f6d.3fce115e.js new file mode 100644 index 000000000..989ba9c25 --- /dev/null +++ b/assets/js/1e144f6d.3fce115e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72702],{10816:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const s={},i="Overview",c={id:"resources/beginner/counter-testnet/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/docs/resources/beginner/counter-testnet/overview.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/overview",permalink:"/resources/beginner/counter-testnet/overview",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/counter-testnet"},next:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter-testnet/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(97665).A+"",width:"977",height:"368"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},97665:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-testnet-40880f888b79830685dee11e2093091d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e144f6d.846df292.js b/assets/js/1e144f6d.846df292.js deleted file mode 100644 index d56b2d4dc..000000000 --- a/assets/js/1e144f6d.846df292.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2702],{10816:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const s={},i="Overview",c={id:"resources/beginner/counter-testnet/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/docs/resources/beginner/counter-testnet/overview.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/overview",permalink:"/next/resources/beginner/counter-testnet/overview",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/next/counter-testnet"},next:{title:"Casper-Client Commands",permalink:"/next/resources/beginner/counter-testnet/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(91855).A+"",width:"977",height:"368"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},91855:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-testnet-40880f888b79830685dee11e2093091d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/1e2c8091.780b66ed.js b/assets/js/1e2c8091.780b66ed.js new file mode 100644 index 000000000..251e8a867 --- /dev/null +++ b/assets/js/1e2c8091.780b66ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2810],{32241:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var r=n(74848),i=n(28453);const a={title:"Sidecar Setup"},t="The Casper Sidecar",c={id:"operators/setup/casper-sidecar",title:"Sidecar Setup",description:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:",source:"@site/versioned_docs/version-2.0.0/operators/setup/casper-sidecar.md",sourceDirName:"operators/setup",slug:"/operators/setup/casper-sidecar",permalink:"/2.0.0/operators/setup/casper-sidecar",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Sidecar Setup"},sidebar:"operators",previous:{title:"Node Events",permalink:"/2.0.0/operators/setup/node-events"},next:{title:"Becoming a Validator",permalink:"/2.0.0/operators/becoming-a-validator/"}},d={},o=[{value:"Configuring the Sidecar Service",id:"configuring-the-sidecar",level:2},{value:"Installing the Sidecar",id:"installing-the-sidecar",level:2},{value:"Monitoring the Installation",id:"monitoring-the-sidecar",level:3},{value:"The Admin Server",id:"the-admin-server",level:2},{value:"Swagger Documentation",id:"swagger-documentation",level:2},{value:"OpenAPI Specification",id:"openapi-specification",level:2},{value:"Using the Sidecar",id:"using-the-sidecar",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function l(e){const s={a:"a",b:"b",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"the-casper-sidecar",children:"The Casper Sidecar"})}),"\n",(0,r.jsx)(s.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,r.jsx)(s.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Visit GitHub for the latest source code and information on ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"system architecture"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configurations"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"testing"})," and ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"troubleshooting"}),"."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Sidecar components and architecture diagram",src:n(82094).A+"",width:"1416",height:"978"})}),"\n",(0,r.jsx)(s.h2,{id:"configuring-the-sidecar",children:"Configuring the Sidecar Service"}),"\n",(0,r.jsxs)(s.p,{children:["Operators need to update the Sidecar configuration file according to their needs. Detailed configuration instructions are available in ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/ETC_README.md",children:"GitHub"}),". Further details regarding each ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configuration option"})," are available in GitHub."]}),"\n",(0,r.jsx)(s.h2,{id:"installing-the-sidecar",children:"Installing the Sidecar"}),"\n",(0,r.jsx)(s.p,{children:"The following command will install the Debian package for the Casper Sidecar service on various Linux flavors."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo apt install ./casper-sidecar_0.1.0-0_amd64.deb\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Reading package lists... Done\nBuilding dependency tree \nReading state information... Done\nNote, selecting 'casper-sidecar' instead of './casper-sidecar_0.1.0-0_amd64.deb'\nThe following NEW packages will be installed:\n casper-sidecar\n0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.\nNeed to get 0 B/4162 kB of archives.\nAfter this operation, 20.2 MB of additional disk space will be used.\nGet:1 /home/ubuntu/casper-sidecar_0.1.0-0_amd64.deb casper-sidecar amd64 0.1.0-0 [4162 kB]\nSelecting previously unselected package casper-sidecar.\n(Reading database ... 102241 files and directories currently installed.)\nPreparing to unpack .../casper-sidecar_0.1.0-0_amd64.deb ...\nUnpacking casper-sidecar (0.1.0-0) ...\nSetting up casper-sidecar (0.1.0-0) ...\nAdding system user `csidecar' (UID 114) ...\nAdding new group `csidecar' (GID 120) ...\nAdding new user `csidecar' (UID 114) with group `csidecar' ...\nNot creating home directory `/home/csidecar'.\nCreated symlink /etc/systemd/system/multi-user.target.wants/casper-sidecar.service \u2192 /lib/systemd/system/casper-sidecar.service.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.h3,{id:"monitoring-the-sidecar",children:"Monitoring the Installation"}),"\n",(0,r.jsx)(s.p,{children:"Check the service status:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"systemctl status casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"casper-sidecar.service - Casper Event Sidecar\n Loaded: loaded (/lib/systemd/system/casper-sidecar.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-12-07 20:33:29 UTC; 1min 3s ago\n Docs: https://docs.casperlabs.io\n Main PID: 16707 (casper-si)\n Tasks: 5 (limit: 9401)\n Memory: 7.1M\n CGroup: /system.slice/casper-sidecar.service\n \u2514\u250016707 /usr/bin/casper-sidecar /etc/casper-sidecar/config.toml\n\nDec 07 20:33:29 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.p,{children:"Check the logs and make sure the service is running as expected."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"journalctl --no-pager -u casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Dec 05 17:24:53 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsxs)(s.p,{children:["If you see any errors, you may need to ",(0,r.jsx)(s.a,{href:"#configuring-the-service",children:"update the configuration"})," and restart the service with the commands below."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Stopping the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl stop casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Starting the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl start casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.h2,{id:"the-admin-server",children:"The Admin Server"}),"\n",(0,r.jsxs)(s.p,{children:["If enabled, the Sidecar's administrative API can be accessed using the following command. The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18887"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"http://localhost:PORT/metrics/\n"})}),"\n",(0,r.jsx)(s.h2,{id:"swagger-documentation",children:"Swagger Documentation"}),"\n",(0,r.jsxs)(s.p,{children:["You can access the Swagger documentation at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/swagger-ui/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"openapi-specification",children:"OpenAPI Specification"}),"\n",(0,r.jsxs)(s.p,{children:["An OpenAPI schema is available at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/api-doc.json/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"using-the-sidecar",children:"Using the Sidecar"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes how to consume events and perform queries using the Sidecar, covering the following topics:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Node-generated events emitted by the node(s) to which the Sidecar connects"}),"\n",(0,r.jsx)(s.li,{children:"Sidecar-generated events originating solely from the Sidecar service and not from a node"}),"\n",(0,r.jsx)(s.li,{children:"The RESTful endpoint for performing useful queries about the state of the network"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,r.jsxs)(s.p,{children:["For troubleshooting tips, visit ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},82094:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var r=n(96540);const i={},a=r.createContext(i);function t(e){const s=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/202767e6.650f5669.js b/assets/js/202767e6.650f5669.js new file mode 100644 index 000000000..ea05993aa --- /dev/null +++ b/assets/js/202767e6.650f5669.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34008],{5385:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var r=s(74848),l=s(28453);const c={},d="CLType {#cltype}",i={id:"developers/json-rpc/types_cl",title:"CLType",description:"cltype}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_cl.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_cl",permalink:"/1.5.X/developers/json-rpc/types_cl",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Types",permalink:"/1.5.X/developers/json-rpc/types_chain"},next:{title:"Overview of Casper dApps",permalink:"/1.5.X/developers/dapps/"}},t={},a=[{value:"CLValue",id:"clvalue",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"cltype",children:"CLType"})}),"\n",(0,r.jsxs)(n.p,{children:["Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a ",(0,r.jsx)(n.a,{href:"#clvalue",children:(0,r.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" `Bool`\n `I32`\n `I64`\n `U8`\n `U32`\n `U64`\n `U128`\n `U256`\n `U512`\n `Unit`\n `String`\n `Key`\n `URef`\n `PublicKey`\n `Any`\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Option"})," Option of a ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"List"})," Variable-length list of a single ",(0,r.jsx)(n.code,{children:"CLType"})," (comparable to a ",(0,r.jsx)(n.code,{children:"Vec"}),")."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"ByteArray"})," Fixed-length list of a single ",(0,r.jsx)(n.code,{children:"CLType"})," (comparable to a Rust array)."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Result"})," ",(0,r.jsx)(n.code,{children:"Result"})," with ",(0,r.jsx)(n.code,{children:"Ok"})," and ",(0,r.jsx)(n.code,{children:"Err"})," variants of ",(0,r.jsx)(n.code,{children:"CLType"}),"'s."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Map"})," Map with keys of a single ",(0,r.jsx)(n.code,{children:"CLType"})," and values of a single ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple1"})," 1-ary tuple of a ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple2"})," 2-ary tuple of ",(0,r.jsx)(n.code,{children:"CLType"}),"s."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple3"})," 3-ary tuple of ",(0,r.jsx)(n.code,{children:"CLType"}),"s."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"clvalue",children:"CLValue"}),"\n",(0,r.jsxs)(n.p,{children:["A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized ",(0,r.jsx)(n.code,{children:"Vec<u8>"})," and also holds the CLType of the underlying data as a separate member. The ",(0,r.jsx)(n.code,{children:"parsed"})," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"bytes"})," A Casper serialized representation of the underlying value. For more information, reference the ",(0,r.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization Standard"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.code,{children:"cl_type"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>i});var r=s(96540);const l={},c=r.createContext(l);function d(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:d(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/202767e6.662bbd94.js b/assets/js/202767e6.662bbd94.js deleted file mode 100644 index 5b7ec24cf..000000000 --- a/assets/js/202767e6.662bbd94.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4008],{5385:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>p,frontMatter:()=>c,metadata:()=>i,toc:()=>a});var r=s(74848),l=s(28453);const c={},d="CLType {#cltype}",i={id:"developers/json-rpc/types_cl",title:"CLType",description:"cltype}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_cl.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_cl",permalink:"/developers/json-rpc/types_cl",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Types",permalink:"/developers/json-rpc/types_chain"},next:{title:"Overview of Casper dApps",permalink:"/developers/dapps/"}},t={},a=[{value:"CLValue",id:"clvalue",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,l.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"cltype",children:"CLType"})}),"\n",(0,r.jsxs)(n.p,{children:["Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a ",(0,r.jsx)(n.a,{href:"#clvalue",children:(0,r.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:" `Bool`\n `I32`\n `I64`\n `U8`\n `U32`\n `U64`\n `U128`\n `U256`\n `U512`\n `Unit`\n `String`\n `Key`\n `URef`\n `PublicKey`\n `Any`\n"})}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Option"})," Option of a ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"List"})," Variable-length list of a single ",(0,r.jsx)(n.code,{children:"CLType"})," (comparable to a ",(0,r.jsx)(n.code,{children:"Vec"}),")."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"ByteArray"})," Fixed-length list of a single ",(0,r.jsx)(n.code,{children:"CLType"})," (comparable to a Rust array)."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Result"})," ",(0,r.jsx)(n.code,{children:"Result"})," with ",(0,r.jsx)(n.code,{children:"Ok"})," and ",(0,r.jsx)(n.code,{children:"Err"})," variants of ",(0,r.jsx)(n.code,{children:"CLType"}),"'s."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Map"})," Map with keys of a single ",(0,r.jsx)(n.code,{children:"CLType"})," and values of a single ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple1"})," 1-ary tuple of a ",(0,r.jsx)(n.code,{children:"CLType"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple2"})," 2-ary tuple of ",(0,r.jsx)(n.code,{children:"CLType"}),"s."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Tuple3"})," 3-ary tuple of ",(0,r.jsx)(n.code,{children:"CLType"}),"s."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"clvalue",children:"CLValue"}),"\n",(0,r.jsxs)(n.p,{children:["A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized ",(0,r.jsx)(n.code,{children:"Vec<u8>"})," and also holds the CLType of the underlying data as a separate member. The ",(0,r.jsx)(n.code,{children:"parsed"})," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"bytes"})," A Casper serialized representation of the underlying value. For more information, reference the ",(0,r.jsx)(n.a,{href:"/concepts/serialization-standard",children:"Serialization Standard"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.code,{children:"cl_type"})}),"\n"]}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>i});var r=s(96540);const l={},c=r.createContext(l);function d(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:d(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2063472f.3db4a69b.js b/assets/js/2063472f.3db4a69b.js new file mode 100644 index 000000000..1d93572a0 --- /dev/null +++ b/assets/js/2063472f.3db4a69b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13215],{17646:e=>{e.exports=JSON.parse('{"tags":[{"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade","count":4},{"label":"Validators","permalink":"/blog/tags/validators","description":"Validators","count":1},{"label":"hello","permalink":"/blog/tags/hello","count":1},{"label":"new docs","permalink":"/blog/tags/new-docs","count":1},{"label":"docs-redux","permalink":"/blog/tags/docs-redux","count":1},{"label":"features","permalink":"/blog/tags/features","count":1},{"label":"tokenomics","permalink":"/blog/tags/tokenomics","count":1},{"label":"Set-up","permalink":"/blog/tags/setup","description":"Getting set up on Casper","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/2063472f.f81204a0.js b/assets/js/2063472f.f81204a0.js deleted file mode 100644 index 6f5ebc007..000000000 --- a/assets/js/2063472f.f81204a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3215],{17646:e=>{e.exports=JSON.parse('{"tags":[{"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade","count":4},{"label":"validators","permalink":"/blog/tags/validators","count":1},{"label":"hello","permalink":"/blog/tags/hello","count":1},{"label":"new docs","permalink":"/blog/tags/new-docs","count":1},{"label":"docs-redux","permalink":"/blog/tags/docs-redux","count":1},{"label":"features","permalink":"/blog/tags/features","count":1},{"label":"tokenomics","permalink":"/blog/tags/tokenomics","count":1},{"label":"setup","permalink":"/blog/tags/setup","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/20e65df1.58813634.js b/assets/js/20e65df1.58813634.js new file mode 100644 index 000000000..18ed1bf2e --- /dev/null +++ b/assets/js/20e65df1.58813634.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66476],{5143:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const i={title:"Set up Ledger",slug:"/workflow/ledger-setup/"},d="Ledger Setup with Casper",a={id:"users/ledger/ledger-setup",title:"Set up Ledger",description:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.",source:"@site/versioned_docs/version-2.0.0/users/ledger/ledger-setup.md",sourceDirName:"users/ledger",slug:"/workflow/ledger-setup/",permalink:"/2.0.0/workflow/ledger-setup/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Set up Ledger",slug:"/workflow/ledger-setup/"},sidebar:"users",previous:{title:"Casper on Ledger",permalink:"/2.0.0/users/ledger/"},next:{title:"Ledger and Ledger Live",permalink:"/2.0.0/users/ledger/ledger-live"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing the Casper App on a Ledger Device",id:"install-the-casper-app-on-the-ledger-device",level:2},{value:"Sending and Receiving Tokens",id:"sending-and-receiving-tokens",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"ledger-setup-with-casper",children:"Ledger Setup with Casper"})}),"\n",(0,r.jsx)(s.p,{children:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users."}),"\n",(0,r.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,r.jsx)(s.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,r.jsxs)(s.li,{children:["Make sure the Ledger Live application version is at least at ",(0,r.jsx)(s.code,{children:"2.73.1"}),", which is the version that includes Casper accounts."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["If you need help, contact us on ",(0,r.jsx)(s.a,{href:"https://twitter.com/Casper_Network",children:"Twitter"}),", ",(0,r.jsx)(s.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),", or ",(0,r.jsx)(s.a,{href:"https://t.me/casperblockchain",children:"Telegram"}),"."]})}),"\n",(0,r.jsx)(s.h2,{id:"install-the-casper-app-on-the-ledger-device",children:"Installing the Casper App on a Ledger Device"}),"\n",(0,r.jsxs)(s.p,{children:["Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official ",(0,r.jsx)(s.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger support site"}),"."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"In Ledger Live, open My Ledger at the bottom of the left-hand menu."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Open My Ledger",src:n(74125).A+"",width:"2034",height:"1608"})}),"\n",(0,r.jsxs)(s.ol,{start:"2",children:["\n",(0,r.jsx)(s.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Unlock your Ledger device",src:n(53377).A+"",width:"629",height:"203"})}),"\n",(0,r.jsxs)(s.ol,{start:"3",children:["\n",(0,r.jsx)(s.li,{children:"If asked, allow Ledger manager on your device."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Allow Ledger",src:n(95153).A+"",width:"2028",height:"602"})}),"\n",(0,r.jsxs)(s.ol,{start:"4",children:["\n",(0,r.jsxs)(s.li,{children:["Find ",(0,r.jsx)(s.strong,{children:"Casper"})," in the app catalog."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Find the Casper app",src:n(3286).A+"",width:"2032",height:"1208"})}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsx)(s.p,{children:'Having trouble finding the Casper app?\nPlease search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.'})}),"\n",(0,r.jsxs)(s.ol,{start:"5",children:["\n",(0,r.jsxs)(s.li,{children:["Click the ",(0,r.jsx)(s.strong,{children:"Install"})," button of the app."]}),"\n"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"An installation window appears."}),"\n",(0,r.jsxs)(s.li,{children:["Your device will display ",(0,r.jsx)(s.strong,{children:'"Processing..."'})]}),"\n",(0,r.jsx)(s.li,{children:"The app installation is confirmed."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Casper installation confirmed",src:n(61819).A+"",width:"2036",height:"1242"})}),"\n",(0,r.jsxs)(s.ol,{start:"6",children:["\n",(0,r.jsx)(s.li,{children:"Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Select Casper on Ledger",src:n(47949).A+"",width:"588",height:"233"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Casper app is ready",src:n(92872).A+"",width:"576",height:"218"})}),"\n",(0,r.jsx)(s.h2,{id:"sending-and-receiving-tokens",children:"Sending and Receiving Tokens"}),"\n",(0,r.jsx)(s.p,{children:"To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/2.0.0/users/ledger/ledger-live",children:"Manage Casper Accounts using Ledger and Ledger Live"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/2.0.0/users/ledger/ledger-cspr-live",children:"Manage Casper Accounts using Ledger and CSPR.live"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in ",(0,r.jsx)(s.a,{href:"/2.0.0/users/staking-ledger",children:"Delegating with Ledger Devices"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},95153:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/allow-ledger-8503f8c9fa4e335ac88048a9ae4dccff.png"},61819:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-installed-a733e3a3b7b239ae69cae952da0ec0da.png"},92872:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-ready-063ffa244f6b9eb8f5b729faa56f8215.png"},53377:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-unlock-87a46771b509175ba3f5f79655391584.png"},3286:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/find-casper-db1c451d8e1bc4e2d0ada760474ee733.png"},74125:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/open-my-ledger-2cdb0ad9b46ac6eeb6212eaed8c38dd9.png"},47949:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/select-casper-d33429fc63a355b702fc38926a84e870.png"},28453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>a});var r=n(96540);const t={},i=r.createContext(t);function d(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/20f436ec.0bdc9c76.js b/assets/js/20f436ec.0bdc9c76.js deleted file mode 100644 index d9af05760..000000000 --- a/assets/js/20f436ec.0bdc9c76.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9392],{95578:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var s=t(74848),i=t(28453);const a={title:"Undelegating Tokens"},o="Undelegating Tokens with the Casper Client",d={id:"developers/cli/undelegate",title:"Undelegating Tokens",description:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.",source:"@site/versioned_docs/version-1.5.X/developers/cli/undelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/undelegate",permalink:"/developers/cli/undelegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Undelegating Tokens"},sidebar:"developers",previous:{title:"Redelegating Tokens with the Casper Client",permalink:"/developers/cli/redelegate"},next:{title:"Sending Deploys",permalink:"/developers/cli/sending-deploys"}},r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sending the Undelegation Request",id:"sending-the-undelegation-deploy",level:2},{value:"Method 1: Undelegating with the System Auction Contract",id:"undelegating-system-auction",level:3},{value:"Method 2: Undelegating with Compiled Wasm",id:"undelegating-compiled-wasm",level:3},{value:"Verifying the Undelegation",id:"verifying-the-undelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens-with-the-casper-client",children:"Undelegating Tokens with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network and you have the validator's public key"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-undelegation-deploy",children:"Sending the Undelegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-system-auction",children:"Method 1: Undelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 100 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-compiled-wasm",children:"Method 2: Undelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["As part of this process, you need to ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that produce the undelegation Wasm."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, use the Casper CLI client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," to the network to initiate the undelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/undelegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-undelegation",children:"Verifying the Undelegation"}),"\n",(0,s.jsx)(n.p,{children:"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."}),"\n",(0,s.jsx)(n.p,{children:"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the public key and the amount are absent from the ",(0,s.jsx)(n.code,{children:"bids"})," structure, we can safely conclude that we have indeed undelegated from the validator."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Important Note"}),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/20f436ec.d9cf2a40.js b/assets/js/20f436ec.d9cf2a40.js new file mode 100644 index 000000000..974e9c508 --- /dev/null +++ b/assets/js/20f436ec.d9cf2a40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49392],{95578:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var s=t(74848),i=t(28453);const a={title:"Undelegating Tokens"},o="Undelegating Tokens with the Casper Client",d={id:"developers/cli/undelegate",title:"Undelegating Tokens",description:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.",source:"@site/versioned_docs/version-1.5.X/developers/cli/undelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/undelegate",permalink:"/1.5.X/developers/cli/undelegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Undelegating Tokens"},sidebar:"developers",previous:{title:"Redelegating Tokens with the Casper Client",permalink:"/1.5.X/developers/cli/redelegate"},next:{title:"Sending Deploys",permalink:"/1.5.X/developers/cli/sending-deploys"}},r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sending the Undelegation Request",id:"sending-the-undelegation-deploy",level:2},{value:"Method 1: Undelegating with the System Auction Contract",id:"undelegating-system-auction",level:3},{value:"Method 2: Undelegating with Compiled Wasm",id:"undelegating-compiled-wasm",level:3},{value:"Verifying the Undelegation",id:"verifying-the-undelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens-with-the-casper-client",children:"Undelegating Tokens with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network and you have the validator's public key"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-undelegation-deploy",children:"Sending the Undelegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-system-auction",children:"Method 1: Undelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 100 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-compiled-wasm",children:"Method 2: Undelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["As part of this process, you need to ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that produce the undelegation Wasm."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, use the Casper CLI client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," to the network to initiate the undelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/undelegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-undelegation",children:"Verifying the Undelegation"}),"\n",(0,s.jsx)(n.p,{children:"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."}),"\n",(0,s.jsx)(n.p,{children:"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the public key and the amount are absent from the ",(0,s.jsx)(n.code,{children:"bids"})," structure, we can safely conclude that we have indeed undelegated from the validator."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Important Note"}),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/212aab5d.1a701a70.js b/assets/js/212aab5d.1a701a70.js deleted file mode 100644 index 6b42c40b7..000000000 --- a/assets/js/212aab5d.1a701a70.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2709],{93522:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var t=s(74848),i=s(28453);const a={},r="Development Prerequisites",l={id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.",source:"@site/versioned_docs/version-1.5.X/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/developers/prerequisites",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers"},next:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"}},c={},o=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing <code>curl</code>",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing <code>cargo</code> on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing <code>brew</code>",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"development-prerequisites",children:"Development Prerequisites"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,t.jsx)(n.code,{children:"Linux Ubuntu 20.04"}),". Casper does not officially support ",(0,t.jsx)(n.code,{children:"macOS"}),", but the commands are included for your convenience. If you encounter any problems, reach out to the community on ",(0,t.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"})," or ",(0,t.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),". Developing on Windows is not advised."]}),"\n",(0,t.jsx)(n.h2,{id:"preparing-your-development-environment",children:"Preparing your Development Environment"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsxs)(n.h3,{id:"install-curl",children:["Installing ",(0,t.jsx)(n.code,{children:"curl"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install curl\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-essential",children:"Installing essential Linux packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-linux-cargo",children:["Installing ",(0,t.jsx)(n.code,{children:"cargo"})," on Linux"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install cargo\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.h3,{id:"install-xcode",children:"Installing Xcode developer tools for macOS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select -p\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-brew",children:["Installing ",(0,t.jsx)(n.code,{children:"brew"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds-macos",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-rust",children:"Installing Rust"}),"\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust programming language"})," if you don't already have it on your computer."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"official Rust guide"})," recommends installing Rust by using ",(0,t.jsx)(n.code,{children:"curl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.p,{children:"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source $HOME/.cargo/env\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: You can also use ",(0,t.jsx)(n.code,{children:"brew"})," on MacOS or ",(0,t.jsx)(n.code,{children:"apt"})," on Linux to install Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-casper-crates",children:"Installing the Casper Crates"}),"\n",(0,t.jsxs)(n.p,{children:["The best and fastest way to set up a Casper Rust project is to use ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/cargo-casper",children:"cargo casper"}),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,t.jsx)(n.em,{children:"Cargo"})," is a build system and package manager for Rust (much like ",(0,t.jsx)(n.em,{children:"pip"})," if you are familiar with Python, or ",(0,t.jsx)(n.em,{children:"npm"})," and ",(0,t.jsx)(n.em,{children:"yarn"})," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install cargo-casper\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo-casper --version\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Familiarize yourself with the essential Casper crates described ",(0,t.jsx)(n.a,{href:"/developers/essential-crates",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"install-casper-client",children:"Installing the Casper Client"}),"\n",(0,t.jsxs)(n.p,{children:["The default Casper client is on ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-client",children:"crates.io"}),". This client can transmit your deploys to a Casper network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install casper-client\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"help"})," for each command to get the most up-to-date arguments and descriptions."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client <command> --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"building-client-from-source",children:"Accessing the Casper client source code"}),"\n",(0,t.jsxs)(n.p,{children:["You can access the Casper client source code ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs",children:"here"}),". The ",(0,t.jsx)(n.code,{children:"lib"})," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,t.jsx)(n.code,{children:"casper-client"})," uses this library to implement its functionality."]}),"\n",(0,t.jsx)(n.p,{children:"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, compile the source code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You will find the ",(0,t.jsx)(n.code,{children:"casper-client"})," executable in the ",(0,t.jsx)(n.code,{children:"target/release"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"install-cmake",children:"Installing CMake"}),"\n",(0,t.jsxs)(n.p,{children:["If you plan to compile contracts from the source code, including those provided in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, install ",(0,t.jsx)(n.code,{children:"CMake"})," with the commands below."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://cmake.org/",children:"CMake"})," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,t.jsx)(n.a,{href:"https://cmake.org/resources/",children:"CMake website"}),". Once installed, check your version as shown below."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get -y install cmake\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install cmake\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sample output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-an-ide",children:"Installing an IDE"}),"\n",(0,t.jsx)(n.p,{children:"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://code.visualstudio.com",children:"Visual Studio Code"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/clion/",children:"CLion"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/idea/",children:"IntelliJ Idea"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.vim.org/",children:"Vim"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."}),"\n",(0,t.jsx)(n.p,{children:"If you are using VSC, you might find the following extensions useful:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"CodeLLDB"})," \u2013 An important extension for debugging Rust code"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rust-analyzer"})," \u2013 The official Rust language extension"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Better TOML"})," \u2013 Support for formatting TOML files"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"crates"})," \u2013 An extension to help manage crates"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Error Lens"})," \u2013 Enhances the programming experience by highlighting syntax errors"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-an-account",children:"Setting up a Casper Account"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," creation process consists of two steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Creating an Account"}),"\n",(0,t.jsx)(n.li,{children:"Funding the Account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following video complements the instructions below, showing you the expected output."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"creating-an-account",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,t.jsx)(n.code,{children:"Deploy"})," cryptographically signed by the key-pair corresponding to the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,t.jsxs)(n.p,{children:["Developers must create accounts using the ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," to access the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file needed during development."]}),"\n",(0,t.jsx)(n.p,{children:"Some Casper networks, such as the official Testnet and Mainnet, provide wallets that allow account creation as outlined\xa0here. However, these wallets do not give developers access to the secret key file."}),"\n",(0,t.jsx)(n.h3,{id:"generating-the-account-hash",children:"Generating the account hash"}),"\n",(0,t.jsxs)(n.p,{children:["As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,t.jsx)(n.code,{children:"AccountHashes"})," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,t.jsx)(n.code,{children:"account-address"})," option of the Casper CLI client:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"fund-your-account",children:"Funding an Account"}),"\n",(0,t.jsx)(n.p,{children:"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."}),"\n",(0,t.jsxs)(n.p,{children:["On Testnet, you can fund an account by requesting test tokens according to ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"this guide"}),". You can request test tokens ",(0,t.jsx)(n.strong,{children:"only once"})," for each account."]}),"\n",(0,t.jsx)(n.p,{children:"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."}),"\n",(0,t.jsx)(n.h2,{id:"acquire-node-address-from-network-peers",children:"Acquiring a Node Address from the Network"}),"\n",(0,t.jsxs)(n.p,{children:["Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,t.jsx)(n.code,{children:"http://<node-address>:7777"})," by default."]}),"\n",(0,t.jsx)(n.p,{children:"The node address is the IP address or URL of a peer node."}),"\n",(0,t.jsx)(n.p,{children:"Casper Labs provides public Casper node JSON-RPC endpoints for each network:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Mainnet: ",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io/rpc",children:"https://rpc.mainnet.casperlabs.io/rpc"})]}),"\n",(0,t.jsxs)(n.li,{children:["Testnet: ",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io/rpc",children:"https://rpc.testnet.casperlabs.io/rpc"})]}),"\n",(0,t.jsxs)(n.li,{children:["Integration network: ",(0,t.jsx)(n.a,{href:"https://rpc.integration.casperlabs.io/rpc",children:"https://rpc.integration.casperlabs.io/rpc"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Additionally, both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."}),"\n",(0,t.jsxs)(n.p,{children:["You can get the ",(0,t.jsx)(n.code,{children:"node-ip-address"})," of a node on the network by visiting the following block explorers:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Peers"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Peers"})," on Mainnet"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You will see a list of peers, and you can select the IP of any peer on the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": If the selected peer is unresponsive, pick a different peer and try again."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/212aab5d.5eef133e.js b/assets/js/212aab5d.5eef133e.js new file mode 100644 index 000000000..833318f1c --- /dev/null +++ b/assets/js/212aab5d.5eef133e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92709],{93522:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var t=s(74848),i=s(28453);const a={},r="Development Prerequisites",l={id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.",source:"@site/versioned_docs/version-1.5.X/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/1.5.X/developers/prerequisites",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/1.5.X/developers"},next:{title:"Essential Rust Crates",permalink:"/1.5.X/developers/essential-crates"}},c={},o=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing <code>curl</code>",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing <code>cargo</code> on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing <code>brew</code>",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"development-prerequisites",children:"Development Prerequisites"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,t.jsx)(n.code,{children:"Linux Ubuntu 20.04"}),". Casper does not officially support ",(0,t.jsx)(n.code,{children:"macOS"}),", but the commands are included for your convenience. If you encounter any problems, reach out to the community on ",(0,t.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"})," or ",(0,t.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),". Developing on Windows is not advised."]}),"\n",(0,t.jsx)(n.h2,{id:"preparing-your-development-environment",children:"Preparing your Development Environment"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsxs)(n.h3,{id:"install-curl",children:["Installing ",(0,t.jsx)(n.code,{children:"curl"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install curl\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-essential",children:"Installing essential Linux packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-linux-cargo",children:["Installing ",(0,t.jsx)(n.code,{children:"cargo"})," on Linux"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install cargo\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.h3,{id:"install-xcode",children:"Installing Xcode developer tools for macOS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select -p\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-brew",children:["Installing ",(0,t.jsx)(n.code,{children:"brew"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds-macos",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-rust",children:"Installing Rust"}),"\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust programming language"})," if you don't already have it on your computer."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"official Rust guide"})," recommends installing Rust by using ",(0,t.jsx)(n.code,{children:"curl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.p,{children:"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source $HOME/.cargo/env\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: You can also use ",(0,t.jsx)(n.code,{children:"brew"})," on MacOS or ",(0,t.jsx)(n.code,{children:"apt"})," on Linux to install Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-casper-crates",children:"Installing the Casper Crates"}),"\n",(0,t.jsxs)(n.p,{children:["The best and fastest way to set up a Casper Rust project is to use ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/cargo-casper",children:"cargo casper"}),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,t.jsx)(n.em,{children:"Cargo"})," is a build system and package manager for Rust (much like ",(0,t.jsx)(n.em,{children:"pip"})," if you are familiar with Python, or ",(0,t.jsx)(n.em,{children:"npm"})," and ",(0,t.jsx)(n.em,{children:"yarn"})," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install cargo-casper\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo-casper --version\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Familiarize yourself with the essential Casper crates described ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/essential-crates",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"install-casper-client",children:"Installing the Casper Client"}),"\n",(0,t.jsxs)(n.p,{children:["The default Casper client is on ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-client",children:"crates.io"}),". This client can transmit your deploys to a Casper network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install casper-client\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"help"})," for each command to get the most up-to-date arguments and descriptions."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client <command> --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"building-client-from-source",children:"Accessing the Casper client source code"}),"\n",(0,t.jsxs)(n.p,{children:["You can access the Casper client source code ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs",children:"here"}),". The ",(0,t.jsx)(n.code,{children:"lib"})," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,t.jsx)(n.code,{children:"casper-client"})," uses this library to implement its functionality."]}),"\n",(0,t.jsx)(n.p,{children:"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, compile the source code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You will find the ",(0,t.jsx)(n.code,{children:"casper-client"})," executable in the ",(0,t.jsx)(n.code,{children:"target/release"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"install-cmake",children:"Installing CMake"}),"\n",(0,t.jsxs)(n.p,{children:["If you plan to compile contracts from the source code, including those provided in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, install ",(0,t.jsx)(n.code,{children:"CMake"})," with the commands below."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://cmake.org/",children:"CMake"})," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,t.jsx)(n.a,{href:"https://cmake.org/resources/",children:"CMake website"}),". Once installed, check your version as shown below."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get -y install cmake\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install cmake\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sample output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-an-ide",children:"Installing an IDE"}),"\n",(0,t.jsx)(n.p,{children:"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://code.visualstudio.com",children:"Visual Studio Code"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/clion/",children:"CLion"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/idea/",children:"IntelliJ Idea"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.vim.org/",children:"Vim"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."}),"\n",(0,t.jsx)(n.p,{children:"If you are using VSC, you might find the following extensions useful:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"CodeLLDB"})," \u2013 An important extension for debugging Rust code"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rust-analyzer"})," \u2013 The official Rust language extension"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Better TOML"})," \u2013 Support for formatting TOML files"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"crates"})," \u2013 An extension to help manage crates"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Error Lens"})," \u2013 Enhances the programming experience by highlighting syntax errors"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-an-account",children:"Setting up a Casper Account"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Account"})," creation process consists of two steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Creating an Account"}),"\n",(0,t.jsx)(n.li,{children:"Funding the Account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following video complements the instructions below, showing you the expected output."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"creating-an-account",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,t.jsx)(n.code,{children:"Deploy"})," cryptographically signed by the key-pair corresponding to the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,t.jsxs)(n.p,{children:["Developers must create accounts using the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," to access the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file needed during development."]}),"\n",(0,t.jsx)(n.p,{children:"Some Casper networks, such as the official Testnet and Mainnet, provide wallets that allow account creation as outlined\xa0here. However, these wallets do not give developers access to the secret key file."}),"\n",(0,t.jsx)(n.h3,{id:"generating-the-account-hash",children:"Generating the account hash"}),"\n",(0,t.jsxs)(n.p,{children:["As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,t.jsx)(n.code,{children:"AccountHashes"})," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,t.jsx)(n.code,{children:"account-address"})," option of the Casper CLI client:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"fund-your-account",children:"Funding an Account"}),"\n",(0,t.jsx)(n.p,{children:"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."}),"\n",(0,t.jsxs)(n.p,{children:["On Testnet, you can fund an account by requesting test tokens according to ",(0,t.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"this guide"}),". You can request test tokens ",(0,t.jsx)(n.strong,{children:"only once"})," for each account."]}),"\n",(0,t.jsx)(n.p,{children:"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."}),"\n",(0,t.jsx)(n.h2,{id:"acquire-node-address-from-network-peers",children:"Acquiring a Node Address from the Network"}),"\n",(0,t.jsxs)(n.p,{children:["Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,t.jsx)(n.code,{children:"http://<node-address>:7777"})," by default."]}),"\n",(0,t.jsx)(n.p,{children:"The node address is the IP address or URL of a peer node."}),"\n",(0,t.jsx)(n.p,{children:"Casper Labs provides public Casper node JSON-RPC endpoints for each network:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Mainnet: ",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io/rpc",children:"https://rpc.mainnet.casperlabs.io/rpc"})]}),"\n",(0,t.jsxs)(n.li,{children:["Testnet: ",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io/rpc",children:"https://rpc.testnet.casperlabs.io/rpc"})]}),"\n",(0,t.jsxs)(n.li,{children:["Integration network: ",(0,t.jsx)(n.a,{href:"https://rpc.integration.casperlabs.io/rpc",children:"https://rpc.integration.casperlabs.io/rpc"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Additionally, both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."}),"\n",(0,t.jsxs)(n.p,{children:["You can get the ",(0,t.jsx)(n.code,{children:"node-ip-address"})," of a node on the network by visiting the following block explorers:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Peers"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Peers"})," on Mainnet"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You will see a list of peers, and you can select the IP of any peer on the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": If the selected peer is unresponsive, pick a different peer and try again."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/21ae0e7e.0ab591f6.js b/assets/js/21ae0e7e.0ab591f6.js deleted file mode 100644 index 70ee57ca9..000000000 --- a/assets/js/21ae0e7e.0ab591f6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5819],{73177:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var a=n(74848),i=n(28453);const o={title:"Staking vs. Delegating",slug:"/staking"},r="Staking vs. Delegating {#staking-vs-delegating}",s={id:"concepts/economics/staking/staking",title:"Staking vs. Delegating",description:"staking-vs-delegating}",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/staking.md",sourceDirName:"concepts/economics/staking",slug:"/staking",permalink:"/staking",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Staking vs. Delegating",slug:"/staking"},sidebar:"concepts",previous:{title:"Staking Concepts",permalink:"/concepts/economics/concepts"},next:{title:"Delegation Details",permalink:"/concepts/economics/delegation"}},l={},d=[{value:"Slashing",id:"slashing",level:2},{value:"Delegation Rate",id:"delegation-rate",level:2},{value:"Delegation Fees",id:"delegation-fees",level:2},{value:"Rewards",id:"rewards",level:2},{value:"Selecting a Node for Delegating",id:"selecting-a-node-for-delegating",level:2},{value:"Monitoring Rewards",id:"monitoring-rewards",level:2},{value:"Unbonding Period",id:"unbonding-period",level:2},{value:"Tutorials",id:"tutorials",level:2}];function c(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"staking-vs-delegating",children:"Staking vs. Delegating"})}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as ",(0,a.jsx)(t.strong,{children:"staking"})," or ",(0,a.jsx)(t.strong,{children:"delegation"}),". They can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider."]}),"\n",(0,a.jsx)(t.p,{children:"Here are a few common topics related to staking, but we also encourage you to do your own research."}),"\n",(0,a.jsx)(t.p,{children:"Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network."}),"\n",(0,a.jsx)(t.p,{children:"Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate."}),"\n",(0,a.jsx)(t.p,{children:"Casper does not treat validator stake differently than delegator stake for security reasons."}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsx)(t.p,{children:"Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-rate",children:"Delegation Rate"}),"\n",(0,a.jsx)(t.p,{children:"Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-fees",children:"Delegation Fees"}),"\n",(0,a.jsx)(t.p,{children:"It is important to know that the cost of the delegation process is approximately 3 CSPR. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse."}),"\n",(0,a.jsx)(t.h2,{id:"rewards",children:"Rewards"}),"\n",(0,a.jsx)(t.p,{children:"Validators receive rewards proportional to their stake for securing the network and participating in consensus (by voting and finalizing blocks). Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot vote on many blocks."}),"\n",(0,a.jsx)(t.p,{children:"There is no precise reward per block. Rewards are split proportionally among stakes within an era and are distributed at the end of each era."}),"\n",(0,a.jsx)(t.h2,{id:"selecting-a-node-for-delegating",children:"Selecting a Node for Delegating"}),"\n",(0,a.jsxs)(t.p,{children:["As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," provide ",(0,a.jsx)(t.a,{href:"https://cspr.live/validators",children:"validator performance statistics"}),", including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{src:n(10636).A+"",width:"2440",height:"1211"})}),"\n",(0,a.jsx)(t.h2,{id:"monitoring-rewards",children:"Monitoring Rewards"}),"\n",(0,a.jsx)(t.p,{children:"It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations."}),"\n",(0,a.jsx)(t.p,{children:"Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"unbonding-period",children:"Unbonding Period"}),"\n",(0,a.jsx)(t.p,{children:"For security purposes, whenever tokens are un-delegated, the protocol will continue to keep the token locked for 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,a.jsx)(t.p,{children:"Navigate to these pages for step-by-step tutorials on creating an account and delegating and undelegating tokens."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Creating an account with the Casper Wallet"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/funding-from-exchanges",children:"Funding an account from an exchange"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/delegate-ui",children:"Delegating tokens using a block explorer"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/staking-ledger",children:"Delegating with Ledger devices"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper client"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/undelegate-ui",children:"Undelegating tokens using a block explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},10636:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/1.validators-e03196f06d8422ff744f2796db8db22f.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var a=n(96540);const i={},o=a.createContext(i);function r(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/21ae0e7e.b7e7da29.js b/assets/js/21ae0e7e.b7e7da29.js new file mode 100644 index 000000000..15e897406 --- /dev/null +++ b/assets/js/21ae0e7e.b7e7da29.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15819],{73177:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var a=n(74848),i=n(28453);const o={title:"Staking vs. Delegating",slug:"/staking"},r="Staking vs. Delegating {#staking-vs-delegating}",s={id:"concepts/economics/staking/staking",title:"Staking vs. Delegating",description:"staking-vs-delegating}",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/staking.md",sourceDirName:"concepts/economics/staking",slug:"/staking",permalink:"/1.5.X/staking",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Staking vs. Delegating",slug:"/staking"},sidebar:"concepts",previous:{title:"Staking Concepts",permalink:"/1.5.X/concepts/economics/concepts"},next:{title:"Delegation Details",permalink:"/1.5.X/concepts/economics/delegation"}},l={},d=[{value:"Slashing",id:"slashing",level:2},{value:"Delegation Rate",id:"delegation-rate",level:2},{value:"Delegation Fees",id:"delegation-fees",level:2},{value:"Rewards",id:"rewards",level:2},{value:"Selecting a Node for Delegating",id:"selecting-a-node-for-delegating",level:2},{value:"Monitoring Rewards",id:"monitoring-rewards",level:2},{value:"Unbonding Period",id:"unbonding-period",level:2},{value:"Tutorials",id:"tutorials",level:2}];function c(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"staking-vs-delegating",children:"Staking vs. Delegating"})}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as ",(0,a.jsx)(t.strong,{children:"staking"})," or ",(0,a.jsx)(t.strong,{children:"delegation"}),". They can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider."]}),"\n",(0,a.jsx)(t.p,{children:"Here are a few common topics related to staking, but we also encourage you to do your own research."}),"\n",(0,a.jsx)(t.p,{children:"Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network."}),"\n",(0,a.jsx)(t.p,{children:"Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate."}),"\n",(0,a.jsx)(t.p,{children:"Casper does not treat validator stake differently than delegator stake for security reasons."}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsx)(t.p,{children:"Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-rate",children:"Delegation Rate"}),"\n",(0,a.jsx)(t.p,{children:"Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-fees",children:"Delegation Fees"}),"\n",(0,a.jsx)(t.p,{children:"It is important to know that the cost of the delegation process is approximately 3 CSPR. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse."}),"\n",(0,a.jsx)(t.h2,{id:"rewards",children:"Rewards"}),"\n",(0,a.jsx)(t.p,{children:"Validators receive rewards proportional to their stake for securing the network and participating in consensus (by voting and finalizing blocks). Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot vote on many blocks."}),"\n",(0,a.jsx)(t.p,{children:"There is no precise reward per block. Rewards are split proportionally among stakes within an era and are distributed at the end of each era."}),"\n",(0,a.jsx)(t.h2,{id:"selecting-a-node-for-delegating",children:"Selecting a Node for Delegating"}),"\n",(0,a.jsxs)(t.p,{children:["As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," provide ",(0,a.jsx)(t.a,{href:"https://cspr.live/validators",children:"validator performance statistics"}),", including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{src:n(50078).A+"",width:"2440",height:"1211"})}),"\n",(0,a.jsx)(t.h2,{id:"monitoring-rewards",children:"Monitoring Rewards"}),"\n",(0,a.jsx)(t.p,{children:"It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations."}),"\n",(0,a.jsx)(t.p,{children:"Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"unbonding-period",children:"Unbonding Period"}),"\n",(0,a.jsx)(t.p,{children:"For security purposes, whenever tokens are un-delegated, the protocol will continue to keep the token locked for 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,a.jsx)(t.p,{children:"Navigate to these pages for step-by-step tutorials on creating an account and delegating and undelegating tokens."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Creating an account with the Casper Wallet"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/1.5.X/users/funding-from-exchanges",children:"Funding an account from an exchange"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/1.5.X/users/delegate-ui",children:"Delegating tokens using a block explorer"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/1.5.X/users/staking-ledger",children:"Delegating with Ledger devices"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/1.5.X/developers/cli/delegate",children:"Delegating with the Casper client"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/1.5.X/users/undelegate-ui",children:"Undelegating tokens using a block explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},50078:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/1.validators-e03196f06d8422ff744f2796db8db22f.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>s});var a=n(96540);const i={},o=a.createContext(i);function r(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/21d2c26c.34fe9668.js b/assets/js/21d2c26c.34fe9668.js new file mode 100644 index 000000000..87c96b9da --- /dev/null +++ b/assets/js/21d2c26c.34fe9668.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74280],{1469:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var a=t(74848),r=t(28453);const o={},s="Node Maintenance",i={id:"operators/maintenance/index",title:"Node Maintenance",description:"This section covers maintenance actions such as moving a node to a different location and restoring a database.",source:"@site/versioned_docs/version-2.0.0/operators/maintenance/index.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/",permalink:"/2.0.0/operators/maintenance/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"operators",previous:{title:"Staging Files",permalink:"/2.0.0/operators/setup-network/staging-files-for-new-network"},next:{title:"Archive and Restore a DB",permalink:"/2.0.0/operators/maintenance/archiving-and-restoring"}},c={},d=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"node-maintenance",children:"Node Maintenance"})}),"\n",(0,a.jsx)(n.p,{children:"This section covers maintenance actions such as moving a node to a different location and restoring a database."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Title"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/2.0.0/operators/maintenance/archiving-and-restoring",children:"Archiving and Restoring a Database"})}),(0,a.jsxs)(n.td,{children:["Using ",(0,a.jsx)(n.code,{children:"zstd"})," for the compression and decompression of a Casper node database and streaming from a backup location"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/2.0.0/operators/maintenance/moving-node",children:"Moving a Validating Node"})}),(0,a.jsx)(n.td,{children:"Ways to move a validator node to another machine"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2237.2be052d4.js b/assets/js/2237.2be052d4.js deleted file mode 100644 index 71d7a4398..000000000 --- a/assets/js/2237.2be052d4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2237],{23363:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(34164),i=n(21312),o=n(51107),r=n(74848);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,s.A)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(o.A,{as:"h1",className:"hero__title",children:(0,r.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(i.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},82237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});n(96540);var s=n(21312),i=n(45500),o=n(79201),r=n(23363),a=n(74848);function c(){const e=(0,s.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.be,{title:e}),(0,a.jsx)(o.A,{children:(0,a.jsx)(r.A,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/22dd74f7.d59e4fd6.js b/assets/js/22dd74f7.d59e4fd6.js deleted file mode 100644 index 58c8064a6..000000000 --- a/assets/js/22dd74f7.d59e4fd6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1567],{55226:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"1.5.X","label":"1.5.X","banner":null,"badge":true,"noIndex":false,"className":"docs-version-1.5.X","isLast":true,"docsSidebars":{"concepts":[{"type":"link","label":"Overview","href":"/concepts/","docId":"concepts/index","unlisted":false},{"type":"link","label":"What is Casper?","href":"/","docId":"concepts/about","unlisted":false},{"type":"link","label":"dApps","href":"/concepts/intro-to-dapps","docId":"concepts/intro-to-dapps","unlisted":false},{"type":"link","label":"Accounts and Keys","href":"/concepts/accounts-and-keys","docId":"concepts/accounts-and-keys","unlisted":false},{"type":"link","label":"Hash Types","href":"/concepts/hash-types","docId":"concepts/hash-types","unlisted":false},{"type":"link","label":"Deploy Lifecycle","href":"/deploy-and-deploy-lifecycle","docId":"concepts/deploy-and-deploy-lifecycle","unlisted":false},{"type":"link","label":"Global State","href":"/concepts/global-state","docId":"concepts/global-state","unlisted":false},{"type":"link","label":"Smart Contracts","href":"/concepts/smart-contracts","docId":"concepts/smart-contracts","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/concepts/list-auth-keys","docId":"concepts/list-auth-keys","unlisted":false},{"type":"link","label":"Call Stacks","href":"/concepts/callstack","docId":"concepts/callstack","unlisted":false},{"type":"link","label":"Dictionaries","href":"/concepts/dictionaries","docId":"concepts/dictionaries","unlisted":false},{"type":"link","label":"Serialization Standard","href":"/concepts/serialization-standard","docId":"concepts/serialization-standard","unlisted":false},{"type":"category","label":"Design","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Network Design","href":"/concepts/design/casper-design","docId":"concepts/design/casper-design","unlisted":false},{"type":"link","label":"Network Communication","href":"/concepts/design/p2p","docId":"concepts/design/p2p","unlisted":false},{"type":"link","label":"Highway Consensus","href":"/concepts/design/highway","docId":"concepts/design/highway","unlisted":false},{"type":"link","label":"Reading and Writing Data","href":"/concepts/design/reading-and-writing-to-the-blockchain","docId":"concepts/design/reading-and-writing-to-the-blockchain","unlisted":false}],"href":"/design"},{"type":"category","label":"Economics","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Consensus","href":"/concepts/economics/consensus","docId":"concepts/economics/consensus","unlisted":false},{"type":"link","label":"Runtime","href":"/runtime","docId":"concepts/economics/runtime","unlisted":false},{"type":"link","label":"Gas Cost","href":"/concepts/economics/gas-concepts","docId":"concepts/economics/gas-concepts","unlisted":false},{"type":"category","label":"Staking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Staking vs. Delegating","href":"/staking","docId":"concepts/economics/staking/staking","unlisted":false},{"type":"link","label":"Delegation Details","href":"/concepts/economics/delegation","docId":"concepts/economics/staking/delegation","unlisted":false}],"href":"/concepts/economics/concepts"}],"href":"/economics"},{"type":"category","label":"Glossary","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"A","href":"/concepts/glossary/A","docId":"concepts/glossary/A","unlisted":false},{"type":"link","label":"B","href":"/concepts/glossary/B","docId":"concepts/glossary/B","unlisted":false},{"type":"link","label":"C","href":"/concepts/glossary/C","docId":"concepts/glossary/C","unlisted":false},{"type":"link","label":"D","href":"/concepts/glossary/D","docId":"concepts/glossary/D","unlisted":false},{"type":"link","label":"E","href":"/concepts/glossary/E","docId":"concepts/glossary/E","unlisted":false},{"type":"link","label":"F","href":"/concepts/glossary/F","docId":"concepts/glossary/F","unlisted":false},{"type":"link","label":"G","href":"/concepts/glossary/G","docId":"concepts/glossary/G","unlisted":false},{"type":"link","label":"H","href":"/concepts/glossary/H","docId":"concepts/glossary/H","unlisted":false},{"type":"link","label":"I","href":"/concepts/glossary/I","docId":"concepts/glossary/I","unlisted":false},{"type":"link","label":"J","href":"/concepts/glossary/J","docId":"concepts/glossary/J","unlisted":false},{"type":"link","label":"K","href":"/concepts/glossary/K","docId":"concepts/glossary/K","unlisted":false},{"type":"link","label":"L","href":"/concepts/glossary/L","docId":"concepts/glossary/L","unlisted":false},{"type":"link","label":"M","href":"/concepts/glossary/M","docId":"concepts/glossary/M","unlisted":false},{"type":"link","label":"N","href":"/concepts/glossary/N","docId":"concepts/glossary/N","unlisted":false},{"type":"link","label":"O","href":"/concepts/glossary/O","docId":"concepts/glossary/O","unlisted":false},{"type":"link","label":"P","href":"/concepts/glossary/P","docId":"concepts/glossary/P","unlisted":false},{"type":"link","label":"Q","href":"/concepts/glossary/Q","docId":"concepts/glossary/Q","unlisted":false},{"type":"link","label":"R","href":"/concepts/glossary/R","docId":"concepts/glossary/R","unlisted":false},{"type":"link","label":"S","href":"/concepts/glossary/S","docId":"concepts/glossary/S","unlisted":false},{"type":"link","label":"T","href":"/concepts/glossary/T","docId":"concepts/glossary/T","unlisted":false},{"type":"link","label":"U","href":"/concepts/glossary/U","docId":"concepts/glossary/U","unlisted":false},{"type":"link","label":"V","href":"/concepts/glossary/V","docId":"concepts/glossary/V","unlisted":false},{"type":"link","label":"W","href":"/concepts/glossary/W","docId":"concepts/glossary/W","unlisted":false},{"type":"link","label":"X","href":"/concepts/glossary/X","docId":"concepts/glossary/X","unlisted":false},{"type":"link","label":"Y","href":"/concepts/glossary/Y","docId":"concepts/glossary/Y","unlisted":false},{"type":"link","label":"Z","href":"/concepts/glossary/Z","docId":"concepts/glossary/Z","unlisted":false}],"href":"/glossary"}],"developers":[{"type":"link","label":"Overview","href":"/developers","docId":"developers/index","unlisted":false},{"type":"link","label":"Development Prerequisites","href":"/developers/prerequisites","docId":"developers/prerequisites","unlisted":false},{"type":"link","label":"Essential Rust Crates","href":"/developers/essential-crates","docId":"developers/essential-crates","unlisted":false},{"type":"category","label":"Writing On-Chain Code","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started with Rust","href":"/developers/writing-onchain-code/getting-started","docId":"developers/writing-onchain-code/getting-started","unlisted":false},{"type":"link","label":"Getting Started with AssemblyScript","href":"/developers/writing-onchain-code/assembly-script","docId":"developers/writing-onchain-code/assembly-script","unlisted":false},{"type":"link","label":"Writing a Basic Smart Contract in Rust","href":"/developers/writing-onchain-code/simple-contract","docId":"developers/writing-onchain-code/simple-contract","unlisted":false},{"type":"link","label":"Testing Smart Contracts","href":"/developers/writing-onchain-code/testing-contracts","docId":"developers/writing-onchain-code/testing-contracts","unlisted":false},{"type":"link","label":"Upgrading and Maintaining Smart Contracts","href":"/developers/writing-onchain-code/upgrading-contracts","docId":"developers/writing-onchain-code/upgrading-contracts","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/developers/writing-onchain-code/calling-contracts","docId":"developers/writing-onchain-code/calling-contracts","unlisted":false},{"type":"link","label":"Contracts and Session Code","href":"/developers/writing-onchain-code/contract-vs-session","docId":"developers/writing-onchain-code/contract-vs-session","unlisted":false},{"type":"link","label":"Writing Session Code","href":"/developers/writing-onchain-code/writing-session-code","docId":"developers/writing-onchain-code/writing-session-code","unlisted":false},{"type":"link","label":"Testing Session Code","href":"/developers/writing-onchain-code/testing-session-code","docId":"developers/writing-onchain-code/testing-session-code","unlisted":false},{"type":"link","label":"Contract Hash vs. Package Hash","href":"/developers/writing-onchain-code/contract-hash-vs-package-hash","docId":"developers/writing-onchain-code/contract-hash-vs-package-hash","unlisted":false},{"type":"link","label":"Best Practices for Casper Smart Contract Authors","href":"/developers/writing-onchain-code/best-practices","docId":"developers/writing-onchain-code/best-practices","unlisted":false}],"href":"/writing-contracts"},{"type":"category","label":"Casper JSON-RPC API","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Guidance for JSON-RPC SDK Compliance","href":"/developers/json-rpc/guidance","docId":"developers/json-rpc/guidance","unlisted":false},{"type":"link","label":"Required Methods for Minimal Compliance","href":"/developers/json-rpc/minimal-compliance","docId":"developers/json-rpc/minimal-compliance","unlisted":false},{"type":"link","label":"Transactional JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-transactional","docId":"developers/json-rpc/json-rpc-transactional","unlisted":false},{"type":"link","label":"Informational JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-informational","docId":"developers/json-rpc/json-rpc-informational","unlisted":false},{"type":"link","label":"Proof-of-Stake JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-pos","docId":"developers/json-rpc/json-rpc-pos","unlisted":false},{"type":"link","label":"Types","href":"/developers/json-rpc/types_chain","docId":"developers/json-rpc/types_chain","unlisted":false},{"type":"link","label":"CLType","href":"/developers/json-rpc/types_cl","docId":"developers/json-rpc/types_cl","unlisted":false}],"href":"/developers/json-rpc/"},{"type":"category","label":"Building dApps","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is a dApp?","href":"/developers/dapps/dapp","docId":"developers/dapps/dapp","unlisted":false},{"type":"link","label":"Prerequisites","href":"/developers/dapps/prerequisites","docId":"developers/dapps/prerequisites","unlisted":false},{"type":"category","label":"SDK Client Libraries","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SDK Client Library Usage","href":"/developers/dapps/sdk/client-library-usage","docId":"developers/dapps/sdk/client-library-usage","unlisted":false},{"type":"link","label":"JavaScript/TypeScript SDK","href":"/developers/dapps/sdk/script-sdk","docId":"developers/dapps/sdk/script-sdk","unlisted":false},{"type":"link","label":".NET SDK","href":"/developers/dapps/sdk/csharp-sdk","docId":"developers/dapps/sdk/csharp-sdk","unlisted":false},{"type":"link","label":"Go SDK","href":"/developers/dapps/sdk/go-sdk","docId":"developers/dapps/sdk/go-sdk","unlisted":false},{"type":"link","label":"Python SDK","href":"/developers/dapps/sdk/python-sdk","docId":"developers/dapps/sdk/python-sdk","unlisted":false}],"href":"/sdk"},{"type":"link","label":"dApp Technology Stack","href":"/developers/dapps/technology-stack","docId":"developers/dapps/technology-stack","unlisted":false},{"type":"link","label":"Front-end in React","href":"/developers/dapps/template-frontend","docId":"developers/dapps/template-frontend","unlisted":false},{"type":"link","label":"URef Access Rights","href":"/developers/dapps/uref-security","docId":"developers/dapps/uref-security","unlisted":false},{"type":"link","label":"Signing Deploys","href":"/developers/dapps/signing-a-deploy","docId":"developers/dapps/signing-a-deploy","unlisted":false},{"type":"link","label":"Estimating Gas Costs with Speculative Execution","href":"/developers/dapps/speculative-exec","docId":"developers/dapps/speculative-exec","unlisted":false},{"type":"link","label":"Local Network Setup","href":"/developers/dapps/setup-nctl","docId":"developers/dapps/setup-nctl","unlisted":false},{"type":"link","label":"Local Network Testing","href":"/developers/dapps/nctl-test","docId":"developers/dapps/nctl-test","unlisted":false},{"type":"link","label":"Monitoring and Consuming Events","href":"/developers/dapps/monitor-and-consume-events","docId":"developers/dapps/monitor-and-consume-events","unlisted":false}],"href":"/developers/dapps/"},{"type":"category","label":"Interacting with the Blockchain","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Transferring Tokens","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Direct Token Transfer","href":"/developers/cli/transfers/direct-token-transfer","docId":"developers/cli/transfers/direct-token-transfer","unlisted":false},{"type":"link","label":"Transferring Tokens using a Multi-Sig Deploy","href":"/developers/cli/transfers/multisig-deploy-transfer","docId":"developers/cli/transfers/multisig-deploy-transfer","unlisted":false},{"type":"link","label":"Verifying a Transfer","href":"/developers/cli/transfers/verify-transfer","docId":"developers/cli/transfers/verify-transfer","unlisted":false}],"href":"/developers/cli/transfers/"},{"type":"link","label":"Delegating Tokens","href":"/developers/cli/delegate","docId":"developers/cli/delegate","unlisted":false},{"type":"link","label":"Redelegating Tokens with the Casper Client","href":"/developers/cli/redelegate","docId":"developers/cli/redelegate","unlisted":false},{"type":"link","label":"Undelegating Tokens","href":"/developers/cli/undelegate","docId":"developers/cli/undelegate","unlisted":false},{"type":"link","label":"Sending Deploys","href":"/developers/cli/sending-deploys","docId":"developers/cli/sending-deploys","unlisted":false},{"type":"link","label":"Installing Contracts","href":"/developers/cli/installing-contracts","docId":"developers/cli/installing-contracts","unlisted":false},{"type":"link","label":"Querying Global State","href":"/developers/cli/querying-global-state","docId":"developers/cli/querying-global-state","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/developers/cli/calling-contracts","docId":"developers/cli/calling-contracts","unlisted":false},{"type":"link","label":"OpCode Costs Tables","href":"/developers/cli/opcode-costs","docId":"developers/cli/opcode-costs","unlisted":false},{"type":"link","label":"Execution Error Codes","href":"/developers/cli/execution-error-codes","docId":"developers/cli/execution-error-codes","unlisted":false}],"href":"/developers/cli/"}],"operators":[{"type":"link","label":"Overview","href":"/operators","docId":"operators/index","unlisted":false},{"type":"category","label":"Node Setup","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Hardware","href":"/operators/setup/hardware","docId":"operators/setup/hardware","unlisted":false},{"type":"link","label":"Configuration","href":"/operators/setup/basic-node-configuration","docId":"operators/setup/basic-node-configuration","unlisted":false},{"type":"link","label":"Endpoints","href":"/operators/setup/node-endpoints","docId":"operators/setup/node-endpoints","unlisted":false},{"type":"link","label":"Installation","href":"/operators/setup/install-node","docId":"operators/setup/install-node","unlisted":false},{"type":"link","label":"Fast Sync","href":"/operators/setup/fast-sync","docId":"operators/setup/fast-sync","unlisted":false},{"type":"link","label":"Open Files Limit","href":"/operators/setup/open-files","docId":"operators/setup/open-files","unlisted":false},{"type":"link","label":"Upgrades","href":"/operators/setup/upgrade","docId":"operators/setup/upgrade","unlisted":false},{"type":"link","label":"Join a Network","href":"/operators/setup/joining","docId":"operators/setup/joining","unlisted":false},{"type":"link","label":"Non-Root Users","href":"/operators/setup/non-root-user","docId":"operators/setup/non-root-user","unlisted":false}],"href":"/operators/setup/"},{"type":"category","label":"Validators","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bonding","href":"/operators/becoming-a-validator/bonding","docId":"operators/becoming-a-validator/bonding","unlisted":false},{"type":"link","label":"Unbonding","href":"/operators/becoming-a-validator/unbonding","docId":"operators/becoming-a-validator/unbonding","unlisted":false},{"type":"link","label":"Recovery","href":"/operators/becoming-a-validator/recovering","docId":"operators/becoming-a-validator/recovering","unlisted":false},{"type":"link","label":"Inactive and Faulty Nodes","href":"/operators/becoming-a-validator/inactive-vs-faulty","docId":"operators/becoming-a-validator/inactive-vs-faulty","unlisted":false}],"href":"/operators/becoming-a-validator/"},{"type":"category","label":"Private Networks","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Genesis","href":"/operators/setup-network/genesis","docId":"operators/setup-network/genesis","unlisted":false},{"type":"link","label":"The Chainspec","href":"/operators/setup-network/chain-spec","docId":"operators/setup-network/chain-spec","unlisted":false},{"type":"link","label":"Private Network Setup","href":"/operators/setup-network/create-private","docId":"operators/setup-network/create-private","unlisted":false},{"type":"link","label":"Staging Files","href":"/operators/setup-network/staging-files-for-new-network","docId":"operators/setup-network/staging-files-for-new-network","unlisted":false}],"href":"/operators/setup-network/"},{"type":"category","label":"Maintenance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Archive and Restore a DB","href":"/operators/maintenance/archiving-and-restoring","docId":"operators/maintenance/archiving-and-restoring","unlisted":false},{"type":"link","label":"Move a Node","href":"/operators/maintenance/moving-node","docId":"operators/maintenance/moving-node","unlisted":false}],"href":"/operators/maintenance/"}],"resources":[{"type":"link","label":"Resources Overview","href":"/resources/","docId":"resources/index","unlisted":false},{"type":"link","label":"Build on Casper","href":"/resources/build-on-casper/introduction","docId":"resources/build-on-casper","unlisted":false},{"type":"link","label":"Move to Casper","href":"/resources/moving-to-casper","docId":"resources/moving-to-casper","unlisted":false},{"type":"category","label":"Casper Token Standards","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CEP-18 Fungible Token","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"On-chain Installation","href":"/resources/tokens/cep18/quickstart-guide","docId":"resources/tokens/cep18/quickstart-guide","unlisted":false},{"type":"link","label":"CEP-18 Contract Details","href":"/resources/tokens/cep18/query","docId":"resources/tokens/cep18/query","unlisted":false},{"type":"link","label":"CEP-18 Transfers","href":"/resources/tokens/cep18/transfer","docId":"resources/tokens/cep18/transfer","unlisted":false},{"type":"link","label":"Testing Guide","href":"/resources/tokens/cep18/tests","docId":"resources/tokens/cep18/tests","unlisted":false}],"href":"/resources/tokens/cep18/full-tutorial"},{"type":"category","label":"CEP-78 Enhanced NFT Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CEP-78 Modalities","href":"/resources/tokens/cep78/modalities","docId":"resources/tokens/cep78/modalities","unlisted":false},{"type":"category","label":"On-chain Installation","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation Workflow","href":"/resources/tokens/cep78/using-casper-client/full-installation-tutorial","docId":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","unlisted":false},{"type":"link","label":"Interaction Workflow","href":"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs","docId":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","unlisted":false},{"type":"link","label":"CEP-78 Contract Details","href":"/resources/tokens/cep78/using-casper-client/querying-NFTs","docId":"resources/tokens/cep78/using-casper-client/querying-NFTs","unlisted":false},{"type":"link","label":"Testing NFTs","href":"/resources/tokens/cep78/using-casper-client/testing-NFTs","docId":"resources/tokens/cep78/using-casper-client/testing-NFTs","unlisted":false}],"href":"/resources/tokens/cep78/using-casper-client/quickstart-guide"},{"type":"link","label":"Ownership Lookup","href":"/resources/tokens/cep78/reverse-lookup","docId":"resources/tokens/cep78/reverse-lookup","unlisted":false},{"type":"link","label":"CEP-78 JavaScript Client","href":"/resources/tokens/cep78/js-tutorial","docId":"resources/tokens/cep78/js-tutorial","unlisted":false}],"href":"/resources/tokens/cep78/introduction"}],"href":"/resources/tokens/"},{"type":"link","label":"Open-Source Software","href":"/resources/build-on-casper/casper-open-source-software","docId":"resources/casper-open-source-software","unlisted":false},{"type":"link","label":"Quickstart","href":"/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/resources/tutorials/advanced/"}],"users":[{"type":"link","label":"Users Overview","href":"/users/","docId":"users/index","unlisted":false},{"type":"link","label":"Block Explorers","href":"/users/block-explorer","docId":"users/block-explorer","unlisted":false},{"type":"link","label":"Funding Mainnet Accounts","href":"/users/funding-from-exchanges","docId":"users/funding-from-exchanges","unlisted":false},{"type":"category","label":"Using CSPR.live","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testnet Funding","href":"/users/testnet-faucet","docId":"users/csprlive/testnet-faucet","unlisted":false},{"type":"link","label":"Delegate Tokens","href":"/users/delegate-ui","docId":"users/csprlive/delegate-ui","unlisted":false},{"type":"link","label":"Undelegate Tokens","href":"/users/undelegate-ui","docId":"users/csprlive/undelegate-ui","unlisted":false},{"type":"link","label":"Transfer Tokens","href":"/users/token-transfer","docId":"users/csprlive/token-transfer","unlisted":false}],"href":"/users/csprlive/"},{"type":"category","label":"Ledger Devices","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Set up Ledger","href":"/workflow/ledger-setup/","docId":"users/ledger/ledger-setup","unlisted":false},{"type":"link","label":"Ledger and Ledger Live","href":"/users/ledger/ledger-live","docId":"users/ledger/ledger-live","unlisted":false},{"type":"link","label":"Ledger and CSPR.live","href":"/users/ledger/ledger-cspr-live","docId":"users/ledger/ledger-cspr-live","unlisted":false},{"type":"link","label":"Delegate with Ledger","href":"/users/staking-ledger","docId":"users/ledger/staking-ledger","unlisted":false}],"href":"/users/ledger/"}],"tutorials":[{"type":"link","label":"Quickstart","href":"/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/resources/tutorials/advanced/"}]},"docs":{"concepts/about":{"id":"concepts/about","title":"What is Casper?","description":"What is Casper?","sidebar":"concepts"},"concepts/accounts-and-keys":{"id":"concepts/accounts-and-keys","title":"Accounts and Keys","description":"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.","sidebar":"concepts"},"concepts/callstack":{"id":"concepts/callstack","title":"Call Stacks","description":"Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.","sidebar":"concepts"},"concepts/deploy-and-deploy-lifecycle":{"id":"concepts/deploy-and-deploy-lifecycle","title":"Deploy Lifecycle","description":"Deploys","sidebar":"concepts"},"concepts/design/casper-design":{"id":"concepts/design/casper-design","title":"Network Design","description":"Introduction","sidebar":"concepts"},"concepts/design/highway":{"id":"concepts/design/highway","title":"Highway Consensus","description":"What is Consensus?","sidebar":"concepts"},"concepts/design/index":{"id":"concepts/design/index","title":"Design Overview","description":"| Topic | Description |","sidebar":"concepts"},"concepts/design/networking-protocol":{"id":"concepts/design/networking-protocol","title":"Casper Node Networking Protocol","description":"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"},"concepts/design/p2p":{"id":"concepts/design/p2p","title":"Network Communication","description":"communications-head}","sidebar":"concepts"},"concepts/design/reading-and-writing-to-the-blockchain":{"id":"concepts/design/reading-and-writing-to-the-blockchain","title":"Reading and Writing Data","description":"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.","sidebar":"concepts"},"concepts/dictionaries":{"id":"concepts/dictionaries","title":"Dictionaries","description":"dictionaries}","sidebar":"concepts"},"concepts/economics/consensus":{"id":"concepts/economics/consensus","title":"Consensus","description":"Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.","sidebar":"concepts"},"concepts/economics/gas-concepts":{"id":"concepts/economics/gas-concepts","title":"Gas Cost","description":"What is gas?","sidebar":"concepts"},"concepts/economics/index":{"id":"concepts/economics/index","title":"Overview","description":"Casper\'s economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform\'s value.","sidebar":"concepts"},"concepts/economics/runtime":{"id":"concepts/economics/runtime","title":"Runtime","description":"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.","sidebar":"concepts"},"concepts/economics/staking/concepts":{"id":"concepts/economics/staking/concepts","title":"Staking Concepts","description":"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.","sidebar":"concepts"},"concepts/economics/staking/delegation":{"id":"concepts/economics/staking/delegation","title":"Delegation Details","description":"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.","sidebar":"concepts"},"concepts/economics/staking/staking":{"id":"concepts/economics/staking/staking","title":"Staking vs. Delegating","description":"staking-vs-delegating}","sidebar":"concepts"},"concepts/global-state":{"id":"concepts/global-state","title":"Global State","description":"global-state-head}","sidebar":"concepts"},"concepts/glossary/A":{"id":"concepts/glossary/A","title":"A","description":"---","sidebar":"concepts"},"concepts/glossary/B":{"id":"concepts/glossary/B","title":"B","description":"---","sidebar":"concepts"},"concepts/glossary/C":{"id":"concepts/glossary/C","title":"C","description":"---","sidebar":"concepts"},"concepts/glossary/D":{"id":"concepts/glossary/D","title":"D","description":"---","sidebar":"concepts"},"concepts/glossary/E":{"id":"concepts/glossary/E","title":"E","description":"---","sidebar":"concepts"},"concepts/glossary/F":{"id":"concepts/glossary/F","title":"F","description":"---","sidebar":"concepts"},"concepts/glossary/G":{"id":"concepts/glossary/G","title":"G","description":"---","sidebar":"concepts"},"concepts/glossary/H":{"id":"concepts/glossary/H","title":"H","description":"---","sidebar":"concepts"},"concepts/glossary/I":{"id":"concepts/glossary/I","title":"I","description":"---","sidebar":"concepts"},"concepts/glossary/index":{"id":"concepts/glossary/index","title":"Glossary","description":"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.","sidebar":"concepts"},"concepts/glossary/J":{"id":"concepts/glossary/J","title":"J","description":"---","sidebar":"concepts"},"concepts/glossary/K":{"id":"concepts/glossary/K","title":"K","description":"---","sidebar":"concepts"},"concepts/glossary/L":{"id":"concepts/glossary/L","title":"L","description":"---","sidebar":"concepts"},"concepts/glossary/M":{"id":"concepts/glossary/M","title":"M","description":"---","sidebar":"concepts"},"concepts/glossary/N":{"id":"concepts/glossary/N","title":"N","description":"---","sidebar":"concepts"},"concepts/glossary/O":{"id":"concepts/glossary/O","title":"O","description":"---","sidebar":"concepts"},"concepts/glossary/P":{"id":"concepts/glossary/P","title":"P","description":"---","sidebar":"concepts"},"concepts/glossary/Q":{"id":"concepts/glossary/Q","title":"Q","description":"---","sidebar":"concepts"},"concepts/glossary/R":{"id":"concepts/glossary/R","title":"R","description":"---","sidebar":"concepts"},"concepts/glossary/S":{"id":"concepts/glossary/S","title":"S","description":"---","sidebar":"concepts"},"concepts/glossary/T":{"id":"concepts/glossary/T","title":"T","description":"---","sidebar":"concepts"},"concepts/glossary/U":{"id":"concepts/glossary/U","title":"U","description":"---","sidebar":"concepts"},"concepts/glossary/V":{"id":"concepts/glossary/V","title":"V","description":"---","sidebar":"concepts"},"concepts/glossary/W":{"id":"concepts/glossary/W","title":"W","description":"---","sidebar":"concepts"},"concepts/glossary/X":{"id":"concepts/glossary/X","title":"X","description":"---","sidebar":"concepts"},"concepts/glossary/Y":{"id":"concepts/glossary/Y","title":"Y","description":"---","sidebar":"concepts"},"concepts/glossary/Z":{"id":"concepts/glossary/Z","title":"Z","description":"---","sidebar":"concepts"},"concepts/hash-types":{"id":"concepts/hash-types","title":"Hash Types","description":"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.","sidebar":"concepts"},"concepts/index":{"id":"concepts/index","title":"Overview","description":"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.","sidebar":"concepts"},"concepts/intro-to-dapps":{"id":"concepts/intro-to-dapps","title":"dApps","description":"What is a dApp?","sidebar":"concepts"},"concepts/list-auth-keys":{"id":"concepts/list-auth-keys","title":"Authorization Keys","description":"This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.","sidebar":"concepts"},"concepts/serialization-standard":{"id":"concepts/serialization-standard","title":"Serialization Standard","description":"serialization-standard-head}","sidebar":"concepts"},"concepts/smart-contracts":{"id":"concepts/smart-contracts","title":"Smart Contracts","description":"Smart Contracts in General","sidebar":"concepts"},"developers/cli/calling-contracts":{"id":"developers/cli/calling-contracts","title":"Calling Contracts","description":"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.","sidebar":"developers"},"developers/cli/delegate":{"id":"developers/cli/delegate","title":"Delegating Tokens","description":"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.","sidebar":"developers"},"developers/cli/execution-error-codes":{"id":"developers/cli/execution-error-codes","title":"Execution Error Codes","description":"This section covers smart contract execution error codes.","sidebar":"developers"},"developers/cli/index":{"id":"developers/cli/index","title":"Interacting with the Blockchain","description":"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.","sidebar":"developers"},"developers/cli/installing-contracts":{"id":"developers/cli/installing-contracts","title":"Installing Contracts","description":"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.","sidebar":"developers"},"developers/cli/opcode-costs":{"id":"developers/cli/opcode-costs","title":"OpCode Costs Tables","description":"The following tables outline the cost, in motes, for a given operation on Casper\'s Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.","sidebar":"developers"},"developers/cli/querying-global-state":{"id":"developers/cli/querying-global-state","title":"Querying Global State","description":"This page explains how to query global state after contract installation.","sidebar":"developers"},"developers/cli/redelegate":{"id":"developers/cli/redelegate","title":"Redelegating Tokens with the Casper Client","description":"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.","sidebar":"developers"},"developers/cli/sending-deploys":{"id":"developers/cli/sending-deploys","title":"Sending Deploys","description":"To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:","sidebar":"developers"},"developers/cli/transfers/direct-token-transfer":{"id":"developers/cli/transfers/direct-token-transfer","title":"Direct Token Transfer","description":"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.","sidebar":"developers"},"developers/cli/transfers/index":{"id":"developers/cli/transfers/index","title":"Transferring Tokens","description":"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.","sidebar":"developers"},"developers/cli/transfers/multisig-deploy-transfer":{"id":"developers/cli/transfers/multisig-deploy-transfer","title":"Transferring Tokens using a Multi-Sig Deploy","description":"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.","sidebar":"developers"},"developers/cli/transfers/verify-transfer":{"id":"developers/cli/transfers/verify-transfer","title":"Verifying a Transfer","description":"Prerequisites","sidebar":"developers"},"developers/cli/undelegate":{"id":"developers/cli/undelegate","title":"Undelegating Tokens","description":"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.","sidebar":"developers"},"developers/dapps/dapp":{"id":"developers/dapps/dapp","title":"What is a dApp?","description":"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.","sidebar":"developers"},"developers/dapps/index":{"id":"developers/dapps/index","title":"Overview of Casper dApps","description":"The following topics are essential for developers building decentralized applications on a Casper network.","sidebar":"developers"},"developers/dapps/monitor-and-consume-events":{"id":"developers/dapps/monitor-and-consume-events","title":"Monitoring and Consuming Events","description":"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper\'s client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.","sidebar":"developers"},"developers/dapps/nctl-test":{"id":"developers/dapps/nctl-test","title":"Local Network Testing","description":"NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.","sidebar":"developers"},"developers/dapps/prerequisites":{"id":"developers/dapps/prerequisites","title":"Prerequisites","description":"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:","sidebar":"developers"},"developers/dapps/sdk/client-library-usage":{"id":"developers/dapps/sdk/client-library-usage","title":"SDK Client Library Usage","description":"Installing the SDKs","sidebar":"developers"},"developers/dapps/sdk/csharp-sdk":{"id":"developers/dapps/sdk/csharp-sdk","title":".NET SDK","description":"The C# .NET SDK allows developers to interact with a Casper network using C#.","sidebar":"developers"},"developers/dapps/sdk/go-sdk":{"id":"developers/dapps/sdk/go-sdk","title":"Go SDK","description":"Usage Examples","sidebar":"developers"},"developers/dapps/sdk/index":{"id":"developers/dapps/sdk/index","title":"SDK Client Libraries","description":"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.","sidebar":"developers"},"developers/dapps/sdk/python-sdk":{"id":"developers/dapps/sdk/python-sdk","title":"Python SDK","description":"The Python SDK allows developers to interact with the Casper platform using Python 3.12+.","sidebar":"developers"},"developers/dapps/sdk/script-sdk":{"id":"developers/dapps/sdk/script-sdk","title":"JavaScript/TypeScript SDK","description":"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.","sidebar":"developers"},"developers/dapps/setup-nctl":{"id":"developers/dapps/setup-nctl","title":"Local Network Setup","description":"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.","sidebar":"developers"},"developers/dapps/signing-a-deploy":{"id":"developers/dapps/signing-a-deploy","title":"Signing Deploys","description":"When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account\'s cryptographic key-pair. This key-pair is a combination of the account\'s secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.","sidebar":"developers"},"developers/dapps/speculative-exec":{"id":"developers/dapps/speculative-exec","title":"Estimating Gas Costs with Speculative Execution","description":"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.","sidebar":"developers"},"developers/dapps/technology-stack":{"id":"developers/dapps/technology-stack","title":"dApp Technology Stack","description":"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.","sidebar":"developers"},"developers/dapps/template-frontend":{"id":"developers/dapps/template-frontend","title":"Front-end in React","description":"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.","sidebar":"developers"},"developers/dapps/uref-security":{"id":"developers/dapps/uref-security","title":"URef Access Rights","description":"Understanding Access Rights","sidebar":"developers"},"developers/essential-crates":{"id":"developers/essential-crates","title":"Essential Rust Crates","description":"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.","sidebar":"developers"},"developers/index":{"id":"developers/index","title":"Overview","description":"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.","sidebar":"developers"},"developers/json-rpc/errors":{"id":"developers/json-rpc/errors","title":"Casper JSON-RPC Error Codes","description":"The following document expands on custom error codes provided by casper-json-rpc crate."},"developers/json-rpc/guidance":{"id":"developers/json-rpc/guidance","title":"Guidance for JSON-RPC SDK Compliance","description":"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.","sidebar":"developers"},"developers/json-rpc/index":{"id":"developers/json-rpc/index","title":"Overview","description":"Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node\'s JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.","sidebar":"developers"},"developers/json-rpc/json-rpc-informational":{"id":"developers/json-rpc/json-rpc-informational","title":"Informational JSON-RPC Methods","description":"informational}","sidebar":"developers"},"developers/json-rpc/json-rpc-pos":{"id":"developers/json-rpc/json-rpc-pos","title":"Proof-of-Stake JSON-RPC Methods","description":"proof-of-stake}","sidebar":"developers"},"developers/json-rpc/json-rpc-transactional":{"id":"developers/json-rpc/json-rpc-transactional","title":"Transactional JSON-RPC Methods","description":"transactional}","sidebar":"developers"},"developers/json-rpc/minimal-compliance":{"id":"developers/json-rpc/minimal-compliance","title":"Required Methods for Minimal Compliance","description":"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.","sidebar":"developers"},"developers/json-rpc/types_chain":{"id":"developers/json-rpc/types_chain","title":"Types","description":"types}","sidebar":"developers"},"developers/json-rpc/types_cl":{"id":"developers/json-rpc/types_cl","title":"CLType","description":"cltype}","sidebar":"developers"},"developers/prerequisites":{"id":"developers/prerequisites","title":"Development Prerequisites","description":"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.","sidebar":"developers"},"developers/writing-onchain-code/assembly-script":{"id":"developers/writing-onchain-code/assembly-script","title":"Getting Started with AssemblyScript","description":"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.","sidebar":"developers"},"developers/writing-onchain-code/best-practices":{"id":"developers/writing-onchain-code/best-practices","title":"Best Practices for Casper Smart Contract Authors","description":"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.","sidebar":"developers"},"developers/writing-onchain-code/calling-contracts":{"id":"developers/writing-onchain-code/calling-contracts","title":"Calling Contracts","description":"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.","sidebar":"developers"},"developers/writing-onchain-code/contract-hash-vs-package-hash":{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","title":"Contract Hash vs. Package Hash","description":"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.","sidebar":"developers"},"developers/writing-onchain-code/contract-vs-session":{"id":"developers/writing-onchain-code/contract-vs-session","title":"Contracts and Session Code","description":"What is Session Code?","sidebar":"developers"},"developers/writing-onchain-code/getting-started":{"id":"developers/writing-onchain-code/getting-started","title":"Getting Started with Rust","description":"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.","sidebar":"developers"},"developers/writing-onchain-code/index":{"id":"developers/writing-onchain-code/index","title":"Introduction","description":"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.","sidebar":"developers"},"developers/writing-onchain-code/simple-contract":{"id":"developers/writing-onchain-code/simple-contract","title":"Writing a Basic Smart Contract in Rust","description":"What is a Smart Contract?","sidebar":"developers"},"developers/writing-onchain-code/testing-contracts":{"id":"developers/writing-onchain-code/testing-contracts","title":"Testing Smart Contracts","description":"Introduction","sidebar":"developers"},"developers/writing-onchain-code/testing-session-code":{"id":"developers/writing-onchain-code/testing-session-code","title":"Testing Session Code","description":"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.","sidebar":"developers"},"developers/writing-onchain-code/upgrading-contracts":{"id":"developers/writing-onchain-code/upgrading-contracts","title":"Upgrading and Maintaining Smart Contracts","description":"Our smart contract packaging tools enable you to:","sidebar":"developers"},"developers/writing-onchain-code/writing-session-code":{"id":"developers/writing-onchain-code/writing-session-code","title":"Writing Session Code","description":"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.","sidebar":"developers"},"disclaimer":{"id":"disclaimer","title":"Disclaimer","description":"disclaimer}"},"operators/becoming-a-validator/bonding":{"id":"operators/becoming-a-validator/bonding","title":"Bonding","description":"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.","sidebar":"operators"},"operators/becoming-a-validator/inactive-vs-faulty":{"id":"operators/becoming-a-validator/inactive-vs-faulty","title":"Inactive and Faulty Nodes","description":"This page describes the differences between a validator node being considered inactive or faulty.","sidebar":"operators"},"operators/becoming-a-validator/index":{"id":"operators/becoming-a-validator/index","title":"Becoming a Validator","description":"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.","sidebar":"operators"},"operators/becoming-a-validator/recovering":{"id":"operators/becoming-a-validator/recovering","title":"Recovery","description":"This topic discusses the steps a validator needs to take if it is evicted from the validator set:","sidebar":"operators"},"operators/becoming-a-validator/unbonding":{"id":"operators/becoming-a-validator/unbonding","title":"Unbonding","description":"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.","sidebar":"operators"},"operators/index":{"id":"operators/index","title":"Overview","description":"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.","sidebar":"operators"},"operators/maintenance/archiving-and-restoring":{"id":"operators/maintenance/archiving-and-restoring","title":"Archive and Restore a DB","description":"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.","sidebar":"operators"},"operators/maintenance/index":{"id":"operators/maintenance/index","title":"Node Maintenance","description":"This section covers maintenance actions such as moving a node to a different location and restoring a database.","sidebar":"operators"},"operators/maintenance/moving-node":{"id":"operators/maintenance/moving-node","title":"Move a Node","description":"This guide is for active validators who want to move their node to another machine.","sidebar":"operators"},"operators/setup-network/chain-spec":{"id":"operators/setup-network/chain-spec","title":"The Chainspec","description":"the-chain-specification}","sidebar":"operators"},"operators/setup-network/create-private":{"id":"operators/setup-network/create-private","title":"Private Network Setup","description":"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.","sidebar":"operators"},"operators/setup-network/genesis":{"id":"operators/setup-network/genesis","title":"Genesis","description":"the-genesis-block}","sidebar":"operators"},"operators/setup-network/index":{"id":"operators/setup-network/index","title":"Setting up Private Networks","description":"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.","sidebar":"operators"},"operators/setup-network/staging-files-for-new-network":{"id":"operators/setup-network/staging-files-for-new-network","title":"Staging Files","description":"Staging files is not needed for already established running networks.","sidebar":"operators"},"operators/setup/basic-node-configuration":{"id":"operators/setup/basic-node-configuration","title":"Configuration","description":"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.","sidebar":"operators"},"operators/setup/fast-sync":{"id":"operators/setup/fast-sync","title":"Fast Sync","description":"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.","sidebar":"operators"},"operators/setup/hardware":{"id":"operators/setup/hardware","title":"Hardware","description":"System Requirements","sidebar":"operators"},"operators/setup/index":{"id":"operators/setup/index","title":"Setting up a Node","description":"The prerequisite for becoming a validator is to set up a node and join a network as described here.","sidebar":"operators"},"operators/setup/install-node":{"id":"operators/setup/install-node","title":"Installation","description":"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.","sidebar":"operators"},"operators/setup/joining":{"id":"operators/setup/joining","title":"Join a Network","description":"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.","sidebar":"operators"},"operators/setup/node-endpoints":{"id":"operators/setup/node-endpoints","title":"Endpoints","description":"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.","sidebar":"operators"},"operators/setup/non-root-user":{"id":"operators/setup/non-root-user","title":"Non-Root Users","description":"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.","sidebar":"operators"},"operators/setup/open-files":{"id":"operators/setup/open-files","title":"Open Files Limit","description":"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.","sidebar":"operators"},"operators/setup/upgrade":{"id":"operators/setup/upgrade","title":"Upgrades","description":"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.","sidebar":"operators"},"resources/advanced/cross-contract":{"id":"resources/advanced/cross-contract","title":"Cross-Contract Communication","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/advanced/index":{"id":"resources/advanced/index","title":"Advanced Tutorials","description":"| Title | Description |","sidebar":"tutorials"},"resources/advanced/list-auth-keys-tutorial":{"id":"resources/advanced/list-auth-keys-tutorial","title":"Authorization Keys","description":"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.","sidebar":"tutorials"},"resources/advanced/list-cspr":{"id":"resources/advanced/list-cspr","title":"Listing CSPR","description":"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."},"resources/advanced/multi-sig/index":{"id":"resources/advanced/multi-sig/index","title":"Introduction","description":"In this tutorial, you will use Casper\'s permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.","sidebar":"tutorials"},"resources/advanced/multi-sig/multi-sig-workflow":{"id":"resources/advanced/multi-sig/multi-sig-workflow","title":"Multi-Sig Workflow","description":"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.","sidebar":"tutorials"},"resources/advanced/multi-sig/other-scenarios":{"id":"resources/advanced/multi-sig/other-scenarios","title":"Additional Examples","description":"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.","sidebar":"tutorials"},"resources/advanced/return-values-tutorial":{"id":"resources/advanced/return-values-tutorial","title":"Runtime Return Values","description":"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.","sidebar":"tutorials"},"resources/advanced/storage-workflow":{"id":"resources/advanced/storage-workflow","title":"Storage Workflow","description":"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.","sidebar":"tutorials"},"resources/advanced/transfer-token-to-contract":{"id":"resources/advanced/transfer-token-to-contract","title":"Token Transfers","description":"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.","sidebar":"tutorials"},"resources/advanced/two-party-multi-sig":{"id":"resources/advanced/two-party-multi-sig","title":"Two-Party Multi-Sig","description":"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.","sidebar":"tutorials"},"resources/beginner/aws-node":{"id":"resources/beginner/aws-node","title":"AWS Casper Nodes","description":"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.","sidebar":"tutorials"},"resources/beginner/cep18":{"id":"resources/beginner/cep18","title":"Fungible Tokens","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/beginner/counter-testnet/commands":{"id":"resources/beginner/counter-testnet/commands","title":"Casper-Client Commands","description":"State Root Hash","sidebar":"tutorials"},"resources/beginner/counter-testnet/index":{"id":"resources/beginner/counter-testnet/index","title":"Introduction","description":"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter-testnet/overview":{"id":"resources/beginner/counter-testnet/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter-testnet/walkthrough":{"id":"resources/beginner/counter-testnet/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/counter/commands":{"id":"resources/beginner/counter/commands","title":"Casper-Client Commands","description":"Faucet Account Information","sidebar":"tutorials"},"resources/beginner/counter/index":{"id":"resources/beginner/counter/index","title":"Introduction","description":"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter/overview":{"id":"resources/beginner/counter/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter/walkthrough":{"id":"resources/beginner/counter/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/getting-started-tutorial":{"id":"resources/beginner/getting-started-tutorial","title":"Getting Started","description":"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.","sidebar":"tutorials"},"resources/beginner/index":{"id":"resources/beginner/index","title":"Overview","description":"Beginner Tutorials","sidebar":"tutorials"},"resources/beginner/querying-network":{"id":"resources/beginner/querying-network","title":"Querying a Node","description":"The Casper node supports queries for users and developers to obtain information stored on the blockchain.","sidebar":"tutorials"},"resources/beginner/upgrade-contract":{"id":"resources/beginner/upgrade-contract","title":"Contract Upgrades","description":"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.","sidebar":"tutorials"},"resources/build-on-casper":{"id":"resources/build-on-casper","title":"Build on Casper","description":"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.","sidebar":"resources"},"resources/casper-open-source-software":{"id":"resources/casper-open-source-software","title":"Open-Source Software","description":"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.","sidebar":"resources"},"resources/condor-for-exchanges":{"id":"resources/condor-for-exchanges","title":"Condor Release Notes for Exchanges","description":"Account/Contract Merge"},"resources/index":{"id":"resources/index","title":"Resources Overview","description":"Building on Casper","sidebar":"resources"},"resources/moving-to-casper":{"id":"resources/moving-to-casper","title":"Move to Casper","description":"moving-to-casper}","sidebar":"resources"},"resources/quick-start":{"id":"resources/quick-start","title":"Quickstart","description":"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.","sidebar":"tutorials"},"resources/tokens/cep18/full-tutorial":{"id":"resources/tokens/cep18/full-tutorial","title":"Fungible Token Workflow","description":"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.","sidebar":"resources"},"resources/tokens/cep18/query":{"id":"resources/tokens/cep18/query","title":"CEP-18 Contract Details","description":"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:","sidebar":"resources"},"resources/tokens/cep18/quickstart-guide":{"id":"resources/tokens/cep18/quickstart-guide","title":"On-chain Installation","description":"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.","sidebar":"resources"},"resources/tokens/cep18/tests":{"id":"resources/tokens/cep18/tests","title":"Testing Guide","description":"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.","sidebar":"resources"},"resources/tokens/cep18/transfer":{"id":"resources/tokens/cep18/transfer","title":"CEP-18 Transfers","description":"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.","sidebar":"resources"},"resources/tokens/cep78/introduction":{"id":"resources/tokens/cep78/introduction","title":"Introduction","description":"Usage","sidebar":"resources"},"resources/tokens/cep78/js-tutorial":{"id":"resources/tokens/cep78/js-tutorial","title":"CEP-78 JavaScript Client","description":"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.","sidebar":"resources"},"resources/tokens/cep78/modalities":{"id":"resources/tokens/cep78/modalities","title":"CEP-78 Modalities","description":"The enhanced NFT implementation supports various \'modalities\' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.","sidebar":"resources"},"resources/tokens/cep78/reverse-lookup":{"id":"resources/tokens/cep78/reverse-lookup","title":"Ownership Lookup","description":"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/full-installation-tutorial":{"id":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","title":"Installation Workflow","description":"This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper\'s Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of 1.63.0. The code for this tutorial is available in GitHub. A portion of this tutorial reviews the contract.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/interacting-with-NFTs":{"id":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","title":"Interaction Workflow","description":"This document describes interacting with NFTs on a Casper network using the Rust command-line client.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/querying-NFTs":{"id":"resources/tokens/cep78/using-casper-client/querying-NFTs","title":"CEP-78 Contract Details","description":"This document covers different commands to query and interact with an NFT (CEP-78) contract instance.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/quickstart-guide":{"id":"resources/tokens/cep78/using-casper-client/quickstart-guide","title":"Quick Installation","description":"This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/testing-NFTs":{"id":"resources/tokens/cep78/using-casper-client/testing-NFTs","title":"Testing NFTs","description":"Prerequisites","sidebar":"resources"},"resources/tokens/index":{"id":"resources/tokens/index","title":"Casper Token Standards","description":"CEP-18 Casper Fungible Token Standard","sidebar":"resources"},"users/block-explorer":{"id":"users/block-explorer","title":"Block Explorers","description":"The Casper blockchain is available as the Mainnet and Testnet.","sidebar":"users"},"users/csprlive/delegate-ui":{"id":"users/csprlive/delegate-ui","title":"Delegate Tokens","description":"Introduction","sidebar":"users"},"users/csprlive/index":{"id":"users/csprlive/index","title":"Using CSPR.live","description":"| Topic | Description |","sidebar":"users"},"users/csprlive/testnet-faucet":{"id":"users/csprlive/testnet-faucet","title":"Testnet Funding","description":"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.","sidebar":"users"},"users/csprlive/token-transfer":{"id":"users/csprlive/token-transfer","title":"Transfer Tokens","description":"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user\'s purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.","sidebar":"users"},"users/csprlive/undelegate-ui":{"id":"users/csprlive/undelegate-ui","title":"Undelegate Tokens","description":"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.","sidebar":"users"},"users/funding-from-exchanges":{"id":"users/funding-from-exchanges","title":"Funding Mainnet Accounts","description":"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account\'s public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.","sidebar":"users"},"users/index":{"id":"users/index","title":"Users Overview","description":"General Topics","sidebar":"users"},"users/ledger/index":{"id":"users/ledger/index","title":"Casper on Ledger","description":"| Topic | Description |","sidebar":"users"},"users/ledger/ledger-cspr-live":{"id":"users/ledger/ledger-cspr-live","title":"Ledger and CSPR.live","description":"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-live":{"id":"users/ledger/ledger-live","title":"Ledger and Ledger Live","description":"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-setup":{"id":"users/ledger/ledger-setup","title":"Set up Ledger","description":"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.","sidebar":"users"},"users/ledger/staking-ledger":{"id":"users/ledger/staking-ledger","title":"Delegate with Ledger","description":"Ledger Initialization","sidebar":"users"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/22dd74f7.e428a829.js b/assets/js/22dd74f7.e428a829.js new file mode 100644 index 000000000..17d29a112 --- /dev/null +++ b/assets/js/22dd74f7.e428a829.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11567],{55226:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":true,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"concepts":[{"type":"link","label":"Overview","href":"/concepts/","docId":"concepts/index","unlisted":false},{"type":"link","label":"What is Casper?","href":"/concepts/about","docId":"concepts/about","unlisted":false},{"type":"category","label":"Design","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Network Design","href":"/concepts/design/casper-design","docId":"concepts/design/casper-design","unlisted":false},{"type":"link","label":"Network Communication","href":"/concepts/design/p2p","docId":"concepts/design/p2p","unlisted":false},{"type":"category","label":"Consensus","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Zug Consensus","href":"/concepts/design/zug","docId":"concepts/design/zug","unlisted":false},{"type":"link","label":"Highway Consensus","href":"/concepts/design/highway","docId":"concepts/design/highway","unlisted":false}],"href":"/concepts/design/consensus"},{"type":"link","label":"Rewards Design","href":"/concepts/design/rewards","docId":"concepts/design/rewards","unlisted":false},{"type":"link","label":"Reading and Writing Data","href":"/concepts/design/reading-and-writing-to-the-blockchain","docId":"concepts/design/reading-and-writing-to-the-blockchain","unlisted":false}],"href":"/design"},{"type":"category","label":"Economics","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Consensus","href":"/concepts/economics/consensus","docId":"concepts/economics/consensus","unlisted":false},{"type":"link","label":"Runtime","href":"/runtime","docId":"concepts/economics/runtime","unlisted":false},{"type":"link","label":"Gas Cost","href":"/concepts/economics/gas-concepts","docId":"concepts/economics/gas-concepts","unlisted":false},{"type":"link","label":"Dynamic Gas Pricing","href":"/concepts/economics/dynamic-gas-pricing","docId":"concepts/economics/dynamic-gas-pricing","unlisted":false},{"type":"link","label":"Fee Elimination","href":"/concepts/economics/fee-elimination","docId":"concepts/economics/fee-elimination","unlisted":false},{"type":"link","label":"Staking","href":"/concepts/economics/staking","docId":"concepts/economics/staking","unlisted":false}],"href":"/economics"},{"type":"category","label":"Glossary","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"A","href":"/concepts/glossary/A","docId":"concepts/glossary/A","unlisted":false},{"type":"link","label":"B","href":"/concepts/glossary/B","docId":"concepts/glossary/B","unlisted":false},{"type":"link","label":"C","href":"/concepts/glossary/C","docId":"concepts/glossary/C","unlisted":false},{"type":"link","label":"D","href":"/concepts/glossary/D","docId":"concepts/glossary/D","unlisted":false},{"type":"link","label":"E","href":"/concepts/glossary/E","docId":"concepts/glossary/E","unlisted":false},{"type":"link","label":"F","href":"/concepts/glossary/F","docId":"concepts/glossary/F","unlisted":false},{"type":"link","label":"G","href":"/concepts/glossary/G","docId":"concepts/glossary/G","unlisted":false},{"type":"link","label":"H","href":"/concepts/glossary/H","docId":"concepts/glossary/H","unlisted":false},{"type":"link","label":"I","href":"/concepts/glossary/I","docId":"concepts/glossary/I","unlisted":false},{"type":"link","label":"J","href":"/concepts/glossary/J","docId":"concepts/glossary/J","unlisted":false},{"type":"link","label":"K","href":"/concepts/glossary/K","docId":"concepts/glossary/K","unlisted":false},{"type":"link","label":"L","href":"/concepts/glossary/L","docId":"concepts/glossary/L","unlisted":false},{"type":"link","label":"M","href":"/concepts/glossary/M","docId":"concepts/glossary/M","unlisted":false},{"type":"link","label":"N","href":"/concepts/glossary/N","docId":"concepts/glossary/N","unlisted":false},{"type":"link","label":"O","href":"/concepts/glossary/O","docId":"concepts/glossary/O","unlisted":false},{"type":"link","label":"P","href":"/concepts/glossary/P","docId":"concepts/glossary/P","unlisted":false},{"type":"link","label":"Q","href":"/concepts/glossary/Q","docId":"concepts/glossary/Q","unlisted":false},{"type":"link","label":"R","href":"/concepts/glossary/R","docId":"concepts/glossary/R","unlisted":false},{"type":"link","label":"S","href":"/concepts/glossary/S","docId":"concepts/glossary/S","unlisted":false},{"type":"link","label":"T","href":"/concepts/glossary/T","docId":"concepts/glossary/T","unlisted":false},{"type":"link","label":"U","href":"/concepts/glossary/U","docId":"concepts/glossary/U","unlisted":false},{"type":"link","label":"V","href":"/concepts/glossary/V","docId":"concepts/glossary/V","unlisted":false},{"type":"link","label":"W","href":"/concepts/glossary/W","docId":"concepts/glossary/W","unlisted":false},{"type":"link","label":"X","href":"/concepts/glossary/X","docId":"concepts/glossary/X","unlisted":false},{"type":"link","label":"Y","href":"/concepts/glossary/Y","docId":"concepts/glossary/Y","unlisted":false},{"type":"link","label":"Z","href":"/concepts/glossary/Z","docId":"concepts/glossary/Z","unlisted":false}],"href":"/glossary"},{"type":"category","label":"Binary Serialization Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Primitives and Basic Serialization Rules","href":"/concepts/serialization/primitives","docId":"concepts/serialization/primitives","unlisted":false},{"type":"link","label":"Major Structures","href":"/concepts/serialization/structures","docId":"concepts/serialization/structures","unlisted":false},{"type":"link","label":"Type Serialization","href":"/concepts/serialization/types","docId":"concepts/serialization/types","unlisted":false}],"href":"/concepts/serialization/"},{"type":"link","label":"dApps","href":"/concepts/intro-to-dapps","docId":"concepts/intro-to-dapps","unlisted":false},{"type":"link","label":"Addressable Entities","href":"/concepts/addressable-entity","docId":"concepts/addressable-entity","unlisted":false},{"type":"link","label":"Accounts and Keys","href":"/concepts/accounts-and-keys","docId":"concepts/accounts-and-keys","unlisted":false},{"type":"link","label":"Key Types","href":"/concepts/key-types","docId":"concepts/key-types","unlisted":false},{"type":"link","label":"Transaction Lifecycle","href":"/transactions-and-transaction-lifecycle","docId":"concepts/transactions-and-transaction-lifecycle","unlisted":false},{"type":"link","label":"Global State","href":"/concepts/global-state","docId":"concepts/global-state","unlisted":false},{"type":"link","label":"Smart Contracts","href":"/concepts/smart-contracts","docId":"concepts/smart-contracts","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/concepts/list-auth-keys","docId":"concepts/list-auth-keys","unlisted":false},{"type":"link","label":"Call Stacks","href":"/concepts/callstack","docId":"concepts/callstack","unlisted":false},{"type":"link","label":"Dictionaries","href":"/concepts/dictionaries","docId":"concepts/dictionaries","unlisted":false}],"developers":[{"type":"link","label":"Overview","href":"/developers","docId":"developers/index","unlisted":false},{"type":"link","label":"Development Prerequisites","href":"/developers/prerequisites","docId":"developers/prerequisites","unlisted":false},{"type":"link","label":"Essential Rust Crates","href":"/developers/essential-crates","docId":"developers/essential-crates","unlisted":false},{"type":"category","label":"Writing On-Chain Code","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started with Rust","href":"/developers/writing-onchain-code/getting-started","docId":"developers/writing-onchain-code/getting-started","unlisted":false},{"type":"link","label":"Getting Started with AssemblyScript","href":"/developers/writing-onchain-code/assembly-script","docId":"developers/writing-onchain-code/assembly-script","unlisted":false},{"type":"link","label":"Writing a Basic Smart Contract in Rust","href":"/developers/writing-onchain-code/simple-contract","docId":"developers/writing-onchain-code/simple-contract","unlisted":false},{"type":"link","label":"Testing Smart Contracts","href":"/developers/writing-onchain-code/testing-contracts","docId":"developers/writing-onchain-code/testing-contracts","unlisted":false},{"type":"link","label":"Upgrading and Maintaining Smart Contracts","href":"/developers/writing-onchain-code/upgrading-contracts","docId":"developers/writing-onchain-code/upgrading-contracts","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/developers/writing-onchain-code/calling-contracts","docId":"developers/writing-onchain-code/calling-contracts","unlisted":false},{"type":"link","label":"Contracts and Session Code","href":"/developers/writing-onchain-code/contract-vs-session","docId":"developers/writing-onchain-code/contract-vs-session","unlisted":false},{"type":"link","label":"Writing Session Code","href":"/developers/writing-onchain-code/writing-session-code","docId":"developers/writing-onchain-code/writing-session-code","unlisted":false},{"type":"link","label":"Testing Session Code","href":"/developers/writing-onchain-code/testing-session-code","docId":"developers/writing-onchain-code/testing-session-code","unlisted":false},{"type":"link","label":"Contract-Level Events","href":"/developers/writing-onchain-code/emitting-contract-events","docId":"developers/writing-onchain-code/emitting-contract-events","unlisted":false},{"type":"link","label":"Contract Hash vs. Package Hash","href":"/developers/writing-onchain-code/contract-hash-vs-package-hash","docId":"developers/writing-onchain-code/contract-hash-vs-package-hash","unlisted":false},{"type":"link","label":"Factory Contracts","href":"/developers/writing-onchain-code/factory-pattern","docId":"developers/writing-onchain-code/factory-pattern","unlisted":false},{"type":"link","label":"Best Practices for Casper Smart Contract Authors","href":"/developers/writing-onchain-code/best-practices","docId":"developers/writing-onchain-code/best-practices","unlisted":false}],"href":"/writing-contracts"},{"type":"category","label":"Casper JSON-RPC API","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Guidance for JSON-RPC SDK Compliance","href":"/developers/json-rpc/guidance","docId":"developers/json-rpc/guidance","unlisted":false},{"type":"link","label":"Required Methods for Minimal Compliance","href":"/developers/json-rpc/minimal-compliance","docId":"developers/json-rpc/minimal-compliance","unlisted":false},{"type":"link","label":"Transactional JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-transactional","docId":"developers/json-rpc/json-rpc-transactional","unlisted":false},{"type":"link","label":"Informational JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-informational","docId":"developers/json-rpc/json-rpc-informational","unlisted":false},{"type":"link","label":"Proof-of-Stake JSON-RPC Methods","href":"/developers/json-rpc/json-rpc-pos","docId":"developers/json-rpc/json-rpc-pos","unlisted":false},{"type":"link","label":"Types","href":"/developers/json-rpc/types_chain","docId":"developers/json-rpc/types_chain","unlisted":false},{"type":"link","label":"CLType","href":"/developers/json-rpc/types_cl","docId":"developers/json-rpc/types_cl","unlisted":false}],"href":"/developers/json-rpc/"},{"type":"category","label":"Building dApps","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is a dApp?","href":"/developers/dapps/dapp","docId":"developers/dapps/dapp","unlisted":false},{"type":"link","label":"Prerequisites","href":"/developers/dapps/prerequisites","docId":"developers/dapps/prerequisites","unlisted":false},{"type":"category","label":"SDK Client Libraries","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SDK Client Library Usage","href":"/developers/dapps/sdk/client-library-usage","docId":"developers/dapps/sdk/client-library-usage","unlisted":false},{"type":"link","label":"JavaScript/TypeScript SDK","href":"/developers/dapps/sdk/script-sdk","docId":"developers/dapps/sdk/script-sdk","unlisted":false},{"type":"link","label":".NET SDK","href":"/developers/dapps/sdk/csharp-sdk","docId":"developers/dapps/sdk/csharp-sdk","unlisted":false},{"type":"link","label":"Go SDK","href":"/developers/dapps/sdk/go-sdk","docId":"developers/dapps/sdk/go-sdk","unlisted":false},{"type":"link","label":"Python SDK","href":"/developers/dapps/sdk/python-sdk","docId":"developers/dapps/sdk/python-sdk","unlisted":false}],"href":"/sdk"},{"type":"link","label":"dApp Technology Stack","href":"/developers/dapps/technology-stack","docId":"developers/dapps/technology-stack","unlisted":false},{"type":"link","label":"Front-end in React","href":"/developers/dapps/template-frontend","docId":"developers/dapps/template-frontend","unlisted":false},{"type":"link","label":"URef Access Rights","href":"/developers/dapps/uref-security","docId":"developers/dapps/uref-security","unlisted":false},{"type":"link","label":"Signing Transactions","href":"/developers/dapps/signing-a-transaction","docId":"developers/dapps/signing-a-transaction","unlisted":false},{"type":"link","label":"Estimating Gas Costs with Speculative Execution","href":"/developers/dapps/speculative-exec","docId":"developers/dapps/speculative-exec","unlisted":false},{"type":"link","label":"Local Network Setup","href":"/developers/dapps/setup-nctl","docId":"developers/dapps/setup-nctl","unlisted":false},{"type":"link","label":"Local Network Testing","href":"/developers/dapps/nctl-test","docId":"developers/dapps/nctl-test","unlisted":false},{"type":"link","label":"Monitoring Events with the Casper Sidecar","href":"/developers/dapps/monitor-and-consume-events","docId":"developers/dapps/monitor-and-consume-events","unlisted":false}],"href":"/developers/dapps/"},{"type":"category","label":"Interacting with the Blockchain","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Transferring Tokens","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Direct Token Transfer","href":"/developers/cli/transfers/direct-token-transfer","docId":"developers/cli/transfers/direct-token-transfer","unlisted":false},{"type":"link","label":"Transferring Tokens using a Multi-Sig Deploy","href":"/developers/cli/transfers/multisig-deploy-transfer","docId":"developers/cli/transfers/multisig-deploy-transfer","unlisted":false},{"type":"link","label":"Verifying a Transfer","href":"/developers/cli/transfers/verify-transfer","docId":"developers/cli/transfers/verify-transfer","unlisted":false}],"href":"/developers/cli/transfers/"},{"type":"link","label":"Delegating Tokens","href":"/developers/cli/delegate","docId":"developers/cli/delegate","unlisted":false},{"type":"link","label":"Redelegating Tokens with the Casper Client","href":"/developers/cli/redelegate","docId":"developers/cli/redelegate","unlisted":false},{"type":"link","label":"Undelegating Tokens","href":"/developers/cli/undelegate","docId":"developers/cli/undelegate","unlisted":false},{"type":"link","label":"Sending Transactions","href":"/developers/cli/sending-transactions","docId":"developers/cli/sending-transactions","unlisted":false},{"type":"link","label":"Installing Contracts","href":"/developers/cli/installing-contracts","docId":"developers/cli/installing-contracts","unlisted":false},{"type":"link","label":"Verifying Contracts","href":"/developers/cli/verifying-contracts","docId":"developers/cli/verifying-contracts","unlisted":false},{"type":"link","label":"Querying Global State","href":"/developers/cli/querying-global-state","docId":"developers/cli/querying-global-state","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/developers/cli/calling-contracts","docId":"developers/cli/calling-contracts","unlisted":false},{"type":"link","label":"OpCode Costs Tables","href":"/developers/cli/opcode-costs","docId":"developers/cli/opcode-costs","unlisted":false},{"type":"link","label":"Execution Error Codes","href":"/developers/cli/execution-error-codes","docId":"developers/cli/execution-error-codes","unlisted":false}],"href":"/developers/cli/"}],"operators":[{"type":"link","label":"Overview","href":"/operators","docId":"operators/index","unlisted":false},{"type":"category","label":"Node Setup","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Hardware","href":"/operators/setup/hardware","docId":"operators/setup/hardware","unlisted":false},{"type":"link","label":"Configuration","href":"/operators/setup/basic-node-configuration","docId":"operators/setup/basic-node-configuration","unlisted":false},{"type":"link","label":"Endpoints","href":"/operators/setup/node-endpoints","docId":"operators/setup/node-endpoints","unlisted":false},{"type":"link","label":"Installation","href":"/operators/setup/install-node","docId":"operators/setup/install-node","unlisted":false},{"type":"link","label":"Fast Sync","href":"/operators/setup/fast-sync","docId":"operators/setup/fast-sync","unlisted":false},{"type":"link","label":"Open Files Limit","href":"/operators/setup/open-files","docId":"operators/setup/open-files","unlisted":false},{"type":"link","label":"Upgrades","href":"/operators/setup/upgrade","docId":"operators/setup/upgrade","unlisted":false},{"type":"link","label":"Join a Network","href":"/operators/setup/joining","docId":"operators/setup/joining","unlisted":false},{"type":"link","label":"Non-Root Users","href":"/operators/setup/non-root-user","docId":"operators/setup/non-root-user","unlisted":false},{"type":"link","label":"Node Events","href":"/operators/setup/node-events","docId":"operators/setup/node-events","unlisted":false},{"type":"link","label":"Sidecar Setup","href":"/operators/setup/casper-sidecar","docId":"operators/setup/casper-sidecar","unlisted":false}],"href":"/operators/setup/"},{"type":"category","label":"Validators","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bonding","href":"/operators/becoming-a-validator/bonding","docId":"operators/becoming-a-validator/bonding","unlisted":false},{"type":"link","label":"Unbonding","href":"/operators/becoming-a-validator/unbonding","docId":"operators/becoming-a-validator/unbonding","unlisted":false},{"type":"link","label":"Recovery","href":"/operators/becoming-a-validator/recovering","docId":"operators/becoming-a-validator/recovering","unlisted":false},{"type":"link","label":"Inactive and Faulty Nodes","href":"/operators/becoming-a-validator/inactive-vs-faulty","docId":"operators/becoming-a-validator/inactive-vs-faulty","unlisted":false}],"href":"/operators/becoming-a-validator/"},{"type":"category","label":"Private Networks","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Genesis","href":"/operators/setup-network/genesis","docId":"operators/setup-network/genesis","unlisted":false},{"type":"link","label":"The Chainspec","href":"/operators/setup-network/chain-spec","docId":"operators/setup-network/chain-spec","unlisted":false},{"type":"link","label":"Private Network Setup","href":"/operators/setup-network/create-private","docId":"operators/setup-network/create-private","unlisted":false},{"type":"link","label":"Staging Files","href":"/operators/setup-network/staging-files-for-new-network","docId":"operators/setup-network/staging-files-for-new-network","unlisted":false}],"href":"/operators/setup-network/"},{"type":"category","label":"Maintenance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Archive and Restore a DB","href":"/operators/maintenance/archiving-and-restoring","docId":"operators/maintenance/archiving-and-restoring","unlisted":false},{"type":"link","label":"Move a Node","href":"/operators/maintenance/moving-node","docId":"operators/maintenance/moving-node","unlisted":false}],"href":"/operators/maintenance/"}],"resources":[{"type":"link","label":"Resources Overview","href":"/resources/","docId":"resources/index","unlisted":false},{"type":"link","label":"Build on Casper","href":"/resources/build-on-casper/introduction","docId":"resources/build-on-casper","unlisted":false},{"type":"link","label":"Move to Casper","href":"/resources/moving-to-casper","docId":"resources/moving-to-casper","unlisted":false},{"type":"category","label":"Casper Token Standards","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CEP-18 Fungible Token","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"On-chain Installation","href":"/resources/tokens/cep18/quickstart-guide","docId":"resources/tokens/cep18/quickstart-guide","unlisted":false},{"type":"link","label":"CEP-18 Contract Details","href":"/resources/tokens/cep18/query","docId":"resources/tokens/cep18/query","unlisted":false},{"type":"link","label":"CEP-18 Transfers","href":"/resources/tokens/cep18/transfer","docId":"resources/tokens/cep18/transfer","unlisted":false},{"type":"link","label":"Testing Guide","href":"/resources/tokens/cep18/tests","docId":"resources/tokens/cep18/tests","unlisted":false}],"href":"/resources/tokens/cep18/full-tutorial"},{"type":"category","label":"CEP-78 Enhanced NFT Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CEP-78 Modalities","href":"/resources/tokens/cep78/modalities","docId":"resources/tokens/cep78/modalities","unlisted":false},{"type":"link","label":"On-chain Installation","href":"/resources/tokens/using-casper-client","docId":"resources/tokens/cep78/using-casper-client","unlisted":false},{"type":"link","label":"Ownership Lookup","href":"/resources/tokens/cep78/reverse-lookup","docId":"resources/tokens/cep78/reverse-lookup","unlisted":false},{"type":"link","label":"CEP-78 JavaScript Client","href":"/resources/tokens/cep78/js-tutorial","docId":"resources/tokens/cep78/js-tutorial","unlisted":false}],"href":"/resources/tokens/cep78/introduction"}],"href":"/resources/tokens/"},{"type":"link","label":"Open-Source Software","href":"/resources/build-on-casper/casper-open-source-software","docId":"resources/casper-open-source-software","unlisted":false},{"type":"link","label":"Quickstart","href":"/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/resources/tutorials/advanced/"}],"users":[{"type":"link","label":"Users Overview","href":"/users/","docId":"users/index","unlisted":false},{"type":"link","label":"Block Explorers","href":"/users/block-explorer","docId":"users/block-explorer","unlisted":false},{"type":"link","label":"Funding Mainnet Accounts","href":"/users/funding-from-exchanges","docId":"users/funding-from-exchanges","unlisted":false},{"type":"link","label":"Delegating Tokens","href":"/users/delegating","docId":"users/delegating","unlisted":false},{"type":"category","label":"Using CSPR.live","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testnet Funding","href":"/users/testnet-faucet","docId":"users/csprlive/testnet-faucet","unlisted":false},{"type":"link","label":"Delegate Tokens","href":"/users/delegate-ui","docId":"users/csprlive/delegate-ui","unlisted":false},{"type":"link","label":"Undelegate Tokens","href":"/users/undelegate-ui","docId":"users/csprlive/undelegate-ui","unlisted":false},{"type":"link","label":"Transfer Tokens","href":"/users/token-transfer","docId":"users/csprlive/token-transfer","unlisted":false}],"href":"/users/csprlive/"},{"type":"category","label":"Ledger Devices","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Set up Ledger","href":"/workflow/ledger-setup/","docId":"users/ledger/ledger-setup","unlisted":false},{"type":"link","label":"Ledger and Ledger Live","href":"/users/ledger/ledger-live","docId":"users/ledger/ledger-live","unlisted":false},{"type":"link","label":"Ledger and CSPR.live","href":"/users/ledger/ledger-cspr-live","docId":"users/ledger/ledger-cspr-live","unlisted":false},{"type":"link","label":"Delegate with Ledger","href":"/users/staking-ledger","docId":"users/ledger/staking-ledger","unlisted":false}],"href":"/users/ledger/"}],"tutorials":[{"type":"link","label":"Quickstart","href":"/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/resources/tutorials/advanced/"}]},"docs":{"concepts/about":{"id":"concepts/about","title":"What is Casper?","description":"What is Casper?","sidebar":"concepts"},"concepts/accounts-and-keys":{"id":"concepts/accounts-and-keys","title":"Accounts and Keys","description":"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.","sidebar":"concepts"},"concepts/addressable-entity":{"id":"concepts/addressable-entity","title":"Addressable Entities","description":"What is an Addressable Entity?","sidebar":"concepts"},"concepts/callstack":{"id":"concepts/callstack","title":"Call Stacks","description":"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.","sidebar":"concepts"},"concepts/design/casper-design":{"id":"concepts/design/casper-design","title":"Network Design","description":"Introduction","sidebar":"concepts"},"concepts/design/consensus":{"id":"concepts/design/consensus","title":"Consensus in a Casper Network","description":"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network\'s consensus protocol is a mechanism for the validators to agree on each finalized block.","sidebar":"concepts"},"concepts/design/highway":{"id":"concepts/design/highway","title":"Highway Consensus","description":"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.","sidebar":"concepts"},"concepts/design/index":{"id":"concepts/design/index","title":"Design Overview","description":"| Topic | Description |","sidebar":"concepts"},"concepts/design/networking-protocol":{"id":"concepts/design/networking-protocol","title":"Casper Node Networking Protocol","description":"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"},"concepts/design/p2p":{"id":"concepts/design/p2p","title":"Network Communication","description":"communications-head}","sidebar":"concepts"},"concepts/design/reading-and-writing-to-the-blockchain":{"id":"concepts/design/reading-and-writing-to-the-blockchain","title":"Reading and Writing Data","description":"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.","sidebar":"concepts"},"concepts/design/rewards":{"id":"concepts/design/rewards","title":"Rewards Design","description":"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.","sidebar":"concepts"},"concepts/design/zug":{"id":"concepts/design/zug","title":"Zug Consensus","description":"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.","sidebar":"concepts"},"concepts/dictionaries":{"id":"concepts/dictionaries","title":"Dictionaries","description":"dictionaries}","sidebar":"concepts"},"concepts/economics/consensus":{"id":"concepts/economics/consensus","title":"Consensus","description":"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.","sidebar":"concepts"},"concepts/economics/dynamic-gas-pricing":{"id":"concepts/economics/dynamic-gas-pricing","title":"Dynamic Gas Pricing","description":"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.","sidebar":"concepts"},"concepts/economics/fee-elimination":{"id":"concepts/economics/fee-elimination","title":"Fee Elimination","description":"Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled \\"fee elimination\\", also known as the \\"no fee mode\\", or \\"no fee transactions\\" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.","sidebar":"concepts"},"concepts/economics/gas-concepts":{"id":"concepts/economics/gas-concepts","title":"Gas Cost","description":"What is gas?","sidebar":"concepts"},"concepts/economics/index":{"id":"concepts/economics/index","title":"Overview","description":"Casper\'s economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform\'s value.","sidebar":"concepts"},"concepts/economics/runtime":{"id":"concepts/economics/runtime","title":"Runtime","description":"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:","sidebar":"concepts"},"concepts/economics/staking":{"id":"concepts/economics/staking","title":"Staking","description":"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.","sidebar":"concepts"},"concepts/global-state":{"id":"concepts/global-state","title":"Global State","description":"global-state-head}","sidebar":"concepts"},"concepts/glossary/A":{"id":"concepts/glossary/A","title":"A","description":"---","sidebar":"concepts"},"concepts/glossary/B":{"id":"concepts/glossary/B","title":"B","description":"---","sidebar":"concepts"},"concepts/glossary/C":{"id":"concepts/glossary/C","title":"C","description":"---","sidebar":"concepts"},"concepts/glossary/D":{"id":"concepts/glossary/D","title":"D","description":"---","sidebar":"concepts"},"concepts/glossary/E":{"id":"concepts/glossary/E","title":"E","description":"---","sidebar":"concepts"},"concepts/glossary/F":{"id":"concepts/glossary/F","title":"F","description":"---","sidebar":"concepts"},"concepts/glossary/G":{"id":"concepts/glossary/G","title":"G","description":"---","sidebar":"concepts"},"concepts/glossary/H":{"id":"concepts/glossary/H","title":"H","description":"---","sidebar":"concepts"},"concepts/glossary/I":{"id":"concepts/glossary/I","title":"I","description":"---","sidebar":"concepts"},"concepts/glossary/index":{"id":"concepts/glossary/index","title":"Glossary","description":"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.","sidebar":"concepts"},"concepts/glossary/J":{"id":"concepts/glossary/J","title":"J","description":"---","sidebar":"concepts"},"concepts/glossary/K":{"id":"concepts/glossary/K","title":"K","description":"---","sidebar":"concepts"},"concepts/glossary/L":{"id":"concepts/glossary/L","title":"L","description":"---","sidebar":"concepts"},"concepts/glossary/M":{"id":"concepts/glossary/M","title":"M","description":"---","sidebar":"concepts"},"concepts/glossary/N":{"id":"concepts/glossary/N","title":"N","description":"---","sidebar":"concepts"},"concepts/glossary/O":{"id":"concepts/glossary/O","title":"O","description":"---","sidebar":"concepts"},"concepts/glossary/P":{"id":"concepts/glossary/P","title":"P","description":"---","sidebar":"concepts"},"concepts/glossary/Q":{"id":"concepts/glossary/Q","title":"Q","description":"---","sidebar":"concepts"},"concepts/glossary/R":{"id":"concepts/glossary/R","title":"R","description":"---","sidebar":"concepts"},"concepts/glossary/S":{"id":"concepts/glossary/S","title":"S","description":"---","sidebar":"concepts"},"concepts/glossary/T":{"id":"concepts/glossary/T","title":"T","description":"---","sidebar":"concepts"},"concepts/glossary/U":{"id":"concepts/glossary/U","title":"U","description":"---","sidebar":"concepts"},"concepts/glossary/V":{"id":"concepts/glossary/V","title":"V","description":"---","sidebar":"concepts"},"concepts/glossary/W":{"id":"concepts/glossary/W","title":"W","description":"---","sidebar":"concepts"},"concepts/glossary/X":{"id":"concepts/glossary/X","title":"X","description":"---","sidebar":"concepts"},"concepts/glossary/Y":{"id":"concepts/glossary/Y","title":"Y","description":"---","sidebar":"concepts"},"concepts/glossary/Z":{"id":"concepts/glossary/Z","title":"Z","description":"---","sidebar":"concepts"},"concepts/index":{"id":"concepts/index","title":"Overview","description":"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.","sidebar":"concepts"},"concepts/intro-to-dapps":{"id":"concepts/intro-to-dapps","title":"dApps","description":"What is a dApp?","sidebar":"concepts"},"concepts/key-types":{"id":"concepts/key-types","title":"Key Types","description":"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.","sidebar":"concepts"},"concepts/list-auth-keys":{"id":"concepts/list-auth-keys","title":"Authorization Keys","description":"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.","sidebar":"concepts"},"concepts/serialization/index":{"id":"concepts/serialization/index","title":"Binary Serialization Standard","description":"serialization-standard-head}","sidebar":"concepts"},"concepts/serialization/primitives":{"id":"concepts/serialization/primitives","title":"Primitives and Basic Serialization Rules","description":"CLValue","sidebar":"concepts"},"concepts/serialization/structures":{"id":"concepts/serialization/structures","title":"Major Structures","description":"Account","sidebar":"concepts"},"concepts/serialization/types":{"id":"concepts/serialization/types","title":"Type Serialization","description":"Account Action Thresholds","sidebar":"concepts"},"concepts/smart-contracts":{"id":"concepts/smart-contracts","title":"Smart Contracts","description":"Smart Contracts in General","sidebar":"concepts"},"concepts/transactions":{"id":"concepts/transactions","title":"Transactions","description":"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."},"concepts/transactions-and-transaction-lifecycle":{"id":"concepts/transactions-and-transaction-lifecycle","title":"Transaction Lifecycle","description":"Transactions","sidebar":"concepts"},"developers/cli/calling-contracts":{"id":"developers/cli/calling-contracts","title":"Calling Contracts","description":"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.","sidebar":"developers"},"developers/cli/delegate":{"id":"developers/cli/delegate","title":"Delegating Tokens","description":"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.","sidebar":"developers"},"developers/cli/execution-error-codes":{"id":"developers/cli/execution-error-codes","title":"Execution Error Codes","description":"This section covers smart contract execution error codes.","sidebar":"developers"},"developers/cli/index":{"id":"developers/cli/index","title":"Interacting with the Blockchain","description":"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.","sidebar":"developers"},"developers/cli/installing-contracts":{"id":"developers/cli/installing-contracts","title":"Installing Contracts","description":"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.","sidebar":"developers"},"developers/cli/opcode-costs":{"id":"developers/cli/opcode-costs","title":"OpCode Costs Tables","description":"The following tables outline the cost, in motes, for a given operation on Casper\'s Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.","sidebar":"developers"},"developers/cli/querying-global-state":{"id":"developers/cli/querying-global-state","title":"Querying Global State","description":"This page explains how to query global state to find account, contract, and package details.","sidebar":"developers"},"developers/cli/redelegate":{"id":"developers/cli/redelegate","title":"Redelegating Tokens with the Casper Client","description":"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.","sidebar":"developers"},"developers/cli/sending-transactions":{"id":"developers/cli/sending-transactions","title":"Sending Transactions","description":"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:","sidebar":"developers"},"developers/cli/transfers/direct-token-transfer":{"id":"developers/cli/transfers/direct-token-transfer","title":"Direct Token Transfer","description":"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.","sidebar":"developers"},"developers/cli/transfers/index":{"id":"developers/cli/transfers/index","title":"Transferring Tokens","description":"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.","sidebar":"developers"},"developers/cli/transfers/multisig-deploy-transfer":{"id":"developers/cli/transfers/multisig-deploy-transfer","title":"Transferring Tokens using a Multi-Sig Deploy","description":"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.","sidebar":"developers"},"developers/cli/transfers/verify-transfer":{"id":"developers/cli/transfers/verify-transfer","title":"Verifying a Transfer","description":"Prerequisites","sidebar":"developers"},"developers/cli/undelegate":{"id":"developers/cli/undelegate","title":"Undelegating Tokens","description":"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.","sidebar":"developers"},"developers/cli/verifying-contracts":{"id":"developers/cli/verifying-contracts","title":"Verifying Contracts","description":"This document describes actions needed for smart contract verification using the Casper CLI client.","sidebar":"developers"},"developers/dapps/dapp":{"id":"developers/dapps/dapp","title":"What is a dApp?","description":"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.","sidebar":"developers"},"developers/dapps/index":{"id":"developers/dapps/index","title":"Overview of Casper dApps","description":"The following topics are essential for developers building decentralized applications on a Casper network.","sidebar":"developers"},"developers/dapps/monitor-and-consume-events":{"id":"developers/dapps/monitor-and-consume-events","title":"Monitoring Events with the Casper Sidecar","description":"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.","sidebar":"developers"},"developers/dapps/nctl-test":{"id":"developers/dapps/nctl-test","title":"Local Network Testing","description":"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.","sidebar":"developers"},"developers/dapps/prerequisites":{"id":"developers/dapps/prerequisites","title":"Prerequisites","description":"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:","sidebar":"developers"},"developers/dapps/sdk/client-library-usage":{"id":"developers/dapps/sdk/client-library-usage","title":"SDK Client Library Usage","description":"Installing the SDKs","sidebar":"developers"},"developers/dapps/sdk/csharp-sdk":{"id":"developers/dapps/sdk/csharp-sdk","title":".NET SDK","description":"The C# .NET SDK allows developers to interact with a Casper network using C#.","sidebar":"developers"},"developers/dapps/sdk/go-sdk":{"id":"developers/dapps/sdk/go-sdk","title":"Go SDK","description":"Usage Examples","sidebar":"developers"},"developers/dapps/sdk/index":{"id":"developers/dapps/sdk/index","title":"SDK Client Libraries","description":"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.","sidebar":"developers"},"developers/dapps/sdk/python-sdk":{"id":"developers/dapps/sdk/python-sdk","title":"Python SDK","description":"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.","sidebar":"developers"},"developers/dapps/sdk/script-sdk":{"id":"developers/dapps/sdk/script-sdk","title":"JavaScript/TypeScript SDK","description":"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.","sidebar":"developers"},"developers/dapps/setup-nctl":{"id":"developers/dapps/setup-nctl","title":"Local Network Setup","description":"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.","sidebar":"developers"},"developers/dapps/signing-a-transaction":{"id":"developers/dapps/signing-a-transaction","title":"Signing Transactions","description":"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account\'s cryptographic key-pair. This key-pair is a combination of the account\'s secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.","sidebar":"developers"},"developers/dapps/speculative-exec":{"id":"developers/dapps/speculative-exec","title":"Estimating Gas Costs with Speculative Execution","description":"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.","sidebar":"developers"},"developers/dapps/technology-stack":{"id":"developers/dapps/technology-stack","title":"dApp Technology Stack","description":"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.","sidebar":"developers"},"developers/dapps/template-frontend":{"id":"developers/dapps/template-frontend","title":"Front-end in React","description":"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.","sidebar":"developers"},"developers/dapps/uref-security":{"id":"developers/dapps/uref-security","title":"URef Access Rights","description":"Understanding Access Rights","sidebar":"developers"},"developers/essential-crates":{"id":"developers/essential-crates","title":"Essential Rust Crates","description":"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.","sidebar":"developers"},"developers/index":{"id":"developers/index","title":"Overview","description":"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.","sidebar":"developers"},"developers/json-rpc/errors":{"id":"developers/json-rpc/errors","title":"Casper JSON-RPC Error Codes","description":"The following document expands on custom error codes provided by casper-json-rpc crate."},"developers/json-rpc/guidance":{"id":"developers/json-rpc/guidance","title":"Guidance for JSON-RPC SDK Compliance","description":"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.","sidebar":"developers"},"developers/json-rpc/index":{"id":"developers/json-rpc/index","title":"Overview","description":"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.","sidebar":"developers"},"developers/json-rpc/json-rpc-informational":{"id":"developers/json-rpc/json-rpc-informational","title":"Informational JSON-RPC Methods","description":"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.","sidebar":"developers"},"developers/json-rpc/json-rpc-pos":{"id":"developers/json-rpc/json-rpc-pos","title":"Proof-of-Stake JSON-RPC Methods","description":"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.","sidebar":"developers"},"developers/json-rpc/json-rpc-transactional":{"id":"developers/json-rpc/json-rpc-transactional","title":"Transactional JSON-RPC Methods","description":"---","sidebar":"developers"},"developers/json-rpc/minimal-compliance":{"id":"developers/json-rpc/minimal-compliance","title":"Required Methods for Minimal Compliance","description":"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.","sidebar":"developers"},"developers/json-rpc/types_chain":{"id":"developers/json-rpc/types_chain","title":"Types","description":"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.","sidebar":"developers"},"developers/json-rpc/types_cl":{"id":"developers/json-rpc/types_cl","title":"CLType","description":"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.","sidebar":"developers"},"developers/prerequisites":{"id":"developers/prerequisites","title":"Development Prerequisites","description":"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.","sidebar":"developers"},"developers/writing-onchain-code/assembly-script":{"id":"developers/writing-onchain-code/assembly-script","title":"Getting Started with AssemblyScript","description":"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.","sidebar":"developers"},"developers/writing-onchain-code/best-practices":{"id":"developers/writing-onchain-code/best-practices","title":"Best Practices for Casper Smart Contract Authors","description":"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.","sidebar":"developers"},"developers/writing-onchain-code/calling-contracts":{"id":"developers/writing-onchain-code/calling-contracts","title":"Calling Contracts","description":"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.","sidebar":"developers"},"developers/writing-onchain-code/contract-hash-vs-package-hash":{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","title":"Contract Hash vs. Package Hash","description":"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.","sidebar":"developers"},"developers/writing-onchain-code/contract-vs-session":{"id":"developers/writing-onchain-code/contract-vs-session","title":"Contracts and Session Code","description":"What is Session Code?","sidebar":"developers"},"developers/writing-onchain-code/emitting-contract-events":{"id":"developers/writing-onchain-code/emitting-contract-events","title":"Contract-Level Events","description":"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.","sidebar":"developers"},"developers/writing-onchain-code/factory-pattern":{"id":"developers/writing-onchain-code/factory-pattern","title":"Factory Contracts","description":"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.","sidebar":"developers"},"developers/writing-onchain-code/getting-started":{"id":"developers/writing-onchain-code/getting-started","title":"Getting Started with Rust","description":"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.","sidebar":"developers"},"developers/writing-onchain-code/index":{"id":"developers/writing-onchain-code/index","title":"Introduction","description":"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.","sidebar":"developers"},"developers/writing-onchain-code/simple-contract":{"id":"developers/writing-onchain-code/simple-contract","title":"Writing a Basic Smart Contract in Rust","description":"What is a Smart Contract?","sidebar":"developers"},"developers/writing-onchain-code/testing-contracts":{"id":"developers/writing-onchain-code/testing-contracts","title":"Testing Smart Contracts","description":"Introduction","sidebar":"developers"},"developers/writing-onchain-code/testing-session-code":{"id":"developers/writing-onchain-code/testing-session-code","title":"Testing Session Code","description":"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.","sidebar":"developers"},"developers/writing-onchain-code/upgrading-contracts":{"id":"developers/writing-onchain-code/upgrading-contracts","title":"Upgrading and Maintaining Smart Contracts","description":"Our smart contract packaging tools enable you to:","sidebar":"developers"},"developers/writing-onchain-code/writing-session-code":{"id":"developers/writing-onchain-code/writing-session-code","title":"Writing Session Code","description":"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.","sidebar":"developers"},"disclaimer":{"id":"disclaimer","title":"Disclaimer","description":"disclaimer}"},"index":{"id":"index","title":"Welcome to the official Casper documentation","description":"What is Casper?"},"operators/becoming-a-validator/bonding":{"id":"operators/becoming-a-validator/bonding","title":"Bonding","description":"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.","sidebar":"operators"},"operators/becoming-a-validator/change-bid-public-key":{"id":"operators/becoming-a-validator/change-bid-public-key","title":"Change bid public key","description":"The public key associated with a given validator bid can be changed through the auction contract\'s changebidpublic_key entry point."},"operators/becoming-a-validator/inactive-vs-faulty":{"id":"operators/becoming-a-validator/inactive-vs-faulty","title":"Inactive and Faulty Nodes","description":"This page describes the differences between a validator node being considered inactive or faulty.","sidebar":"operators"},"operators/becoming-a-validator/index":{"id":"operators/becoming-a-validator/index","title":"Becoming a Validator","description":"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.","sidebar":"operators"},"operators/becoming-a-validator/recovering":{"id":"operators/becoming-a-validator/recovering","title":"Recovery","description":"This topic discusses the steps a validator needs to take if it is evicted from the validator set:","sidebar":"operators"},"operators/becoming-a-validator/unbonding":{"id":"operators/becoming-a-validator/unbonding","title":"Unbonding","description":"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.","sidebar":"operators"},"operators/index":{"id":"operators/index","title":"Overview","description":"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.","sidebar":"operators"},"operators/maintenance/archiving-and-restoring":{"id":"operators/maintenance/archiving-and-restoring","title":"Archive and Restore a DB","description":"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.","sidebar":"operators"},"operators/maintenance/index":{"id":"operators/maintenance/index","title":"Node Maintenance","description":"This section covers maintenance actions such as moving a node to a different location and restoring a database.","sidebar":"operators"},"operators/maintenance/moving-node":{"id":"operators/maintenance/moving-node","title":"Move a Node","description":"This guide is for active validators who want to move their node to another machine.","sidebar":"operators"},"operators/setup-network/chain-spec":{"id":"operators/setup-network/chain-spec","title":"The Chainspec","description":"the-chain-specification}","sidebar":"operators"},"operators/setup-network/create-private":{"id":"operators/setup-network/create-private","title":"Private Network Setup","description":"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.","sidebar":"operators"},"operators/setup-network/genesis":{"id":"operators/setup-network/genesis","title":"Genesis","description":"the-genesis-block}","sidebar":"operators"},"operators/setup-network/index":{"id":"operators/setup-network/index","title":"Setting up Private Networks","description":"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.","sidebar":"operators"},"operators/setup-network/staging-files-for-new-network":{"id":"operators/setup-network/staging-files-for-new-network","title":"Staging Files","description":"Staging files is not needed for already established running networks.","sidebar":"operators"},"operators/setup/basic-node-configuration":{"id":"operators/setup/basic-node-configuration","title":"Configuration","description":"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.","sidebar":"operators"},"operators/setup/casper-sidecar":{"id":"operators/setup/casper-sidecar","title":"Sidecar Setup","description":"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node\'s event stream, query stored events, and query the node\'s JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:","sidebar":"operators"},"operators/setup/fast-sync":{"id":"operators/setup/fast-sync","title":"Fast Sync","description":"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 transaction 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.","sidebar":"operators"},"operators/setup/hardware":{"id":"operators/setup/hardware","title":"Hardware","description":"System Requirements","sidebar":"operators"},"operators/setup/index":{"id":"operators/setup/index","title":"Setting up a Node","description":"The prerequisite for becoming a validator is to set up a node and join a network as described here.","sidebar":"operators"},"operators/setup/install-node":{"id":"operators/setup/install-node","title":"Installation","description":"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.","sidebar":"operators"},"operators/setup/joining":{"id":"operators/setup/joining","title":"Join a Network","description":"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.","sidebar":"operators"},"operators/setup/node-endpoints":{"id":"operators/setup/node-endpoints","title":"Endpoints","description":"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.","sidebar":"operators"},"operators/setup/node-events":{"id":"operators/setup/node-events","title":"Node Events","description":"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node\'s config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.","sidebar":"operators"},"operators/setup/non-root-user":{"id":"operators/setup/non-root-user","title":"Non-Root Users","description":"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.","sidebar":"operators"},"operators/setup/open-files":{"id":"operators/setup/open-files","title":"Open Files Limit","description":"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.","sidebar":"operators"},"operators/setup/upgrade":{"id":"operators/setup/upgrade","title":"Upgrades","description":"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.","sidebar":"operators"},"resources/advanced/cross-contract":{"id":"resources/advanced/cross-contract","title":"Cross-Contract Communication","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/advanced/index":{"id":"resources/advanced/index","title":"Advanced Tutorials","description":"| Title | Description |","sidebar":"tutorials"},"resources/advanced/list-auth-keys-tutorial":{"id":"resources/advanced/list-auth-keys-tutorial","title":"Authorization Keys","description":"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.","sidebar":"tutorials"},"resources/advanced/list-cspr":{"id":"resources/advanced/list-cspr","title":"Listing CSPR","description":"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."},"resources/advanced/multi-sig/index":{"id":"resources/advanced/multi-sig/index","title":"Introduction","description":"In this tutorial, you will use Casper\'s permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.","sidebar":"tutorials"},"resources/advanced/multi-sig/multi-sig-workflow":{"id":"resources/advanced/multi-sig/multi-sig-workflow","title":"Multi-Sig Workflow","description":"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.","sidebar":"tutorials"},"resources/advanced/multi-sig/other-scenarios":{"id":"resources/advanced/multi-sig/other-scenarios","title":"Additional Examples","description":"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.","sidebar":"tutorials"},"resources/advanced/return-values-tutorial":{"id":"resources/advanced/return-values-tutorial","title":"Runtime Return Values","description":"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.","sidebar":"tutorials"},"resources/advanced/storage-workflow":{"id":"resources/advanced/storage-workflow","title":"Storage Workflow","description":"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.","sidebar":"tutorials"},"resources/advanced/transfer-token-to-contract":{"id":"resources/advanced/transfer-token-to-contract","title":"Token Transfers","description":"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.","sidebar":"tutorials"},"resources/advanced/two-party-multi-sig":{"id":"resources/advanced/two-party-multi-sig","title":"Two-Party Multi-Sig","description":"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.","sidebar":"tutorials"},"resources/beginner/aws-node":{"id":"resources/beginner/aws-node","title":"AWS Casper Nodes","description":"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.","sidebar":"tutorials"},"resources/beginner/cep18":{"id":"resources/beginner/cep18","title":"Fungible Tokens","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/beginner/counter-testnet/commands":{"id":"resources/beginner/counter-testnet/commands","title":"Casper-Client Commands","description":"State Root Hash","sidebar":"tutorials"},"resources/beginner/counter-testnet/index":{"id":"resources/beginner/counter-testnet/index","title":"Introduction","description":"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter-testnet/overview":{"id":"resources/beginner/counter-testnet/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter-testnet/walkthrough":{"id":"resources/beginner/counter-testnet/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/counter/commands":{"id":"resources/beginner/counter/commands","title":"Casper-Client Commands","description":"Faucet Account Information","sidebar":"tutorials"},"resources/beginner/counter/index":{"id":"resources/beginner/counter/index","title":"Introduction","description":"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter/overview":{"id":"resources/beginner/counter/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter/walkthrough":{"id":"resources/beginner/counter/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/getting-started-tutorial":{"id":"resources/beginner/getting-started-tutorial","title":"Getting Started","description":"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.","sidebar":"tutorials"},"resources/beginner/index":{"id":"resources/beginner/index","title":"Overview","description":"Beginner Tutorials","sidebar":"tutorials"},"resources/beginner/querying-network":{"id":"resources/beginner/querying-network","title":"Querying a Node","description":"The Casper node supports queries for users and developers to obtain information stored on the blockchain.","sidebar":"tutorials"},"resources/beginner/upgrade-contract":{"id":"resources/beginner/upgrade-contract","title":"Contract Upgrades","description":"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.","sidebar":"tutorials"},"resources/build-on-casper":{"id":"resources/build-on-casper","title":"Build on Casper","description":"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.","sidebar":"resources"},"resources/casper-open-source-software":{"id":"resources/casper-open-source-software","title":"Open-Source Software","description":"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.","sidebar":"resources"},"resources/changelog":{"id":"resources/changelog","title":"Documentation Updates by Protocol Release","description":"Condor (2.0)"},"resources/index":{"id":"resources/index","title":"Resources Overview","description":"Building on Casper","sidebar":"resources"},"resources/moving-to-casper":{"id":"resources/moving-to-casper","title":"Move to Casper","description":"moving-to-casper}","sidebar":"resources"},"resources/quick-start":{"id":"resources/quick-start","title":"Quickstart","description":"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.","sidebar":"tutorials"},"resources/tokens/cep18/full-tutorial":{"id":"resources/tokens/cep18/full-tutorial","title":"Fungible Token Workflow","description":"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.","sidebar":"resources"},"resources/tokens/cep18/query":{"id":"resources/tokens/cep18/query","title":"CEP-18 Contract Details","description":"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:","sidebar":"resources"},"resources/tokens/cep18/quickstart-guide":{"id":"resources/tokens/cep18/quickstart-guide","title":"On-chain Installation","description":"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.","sidebar":"resources"},"resources/tokens/cep18/tests":{"id":"resources/tokens/cep18/tests","title":"Testing Guide","description":"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.","sidebar":"resources"},"resources/tokens/cep18/transfer":{"id":"resources/tokens/cep18/transfer","title":"CEP-18 Transfers","description":"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.","sidebar":"resources"},"resources/tokens/cep78/introduction":{"id":"resources/tokens/cep78/introduction","title":"Introduction","description":"Usage","sidebar":"resources"},"resources/tokens/cep78/js-tutorial":{"id":"resources/tokens/cep78/js-tutorial","title":"CEP-78 JavaScript Client","description":"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.","sidebar":"resources"},"resources/tokens/cep78/modalities":{"id":"resources/tokens/cep78/modalities","title":"CEP-78 Modalities","description":"The enhanced NFT implementation supports various \'modalities\' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.","sidebar":"resources"},"resources/tokens/cep78/reverse-lookup":{"id":"resources/tokens/cep78/reverse-lookup","title":"Ownership Lookup","description":"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client":{"id":"resources/tokens/cep78/using-casper-client","title":"On-chain Installation","description":"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper\'s Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.","sidebar":"resources"},"resources/tokens/index":{"id":"resources/tokens/index","title":"Casper Token Standards","description":"CEP-18 Casper Fungible Token Standard","sidebar":"resources"},"users/block-explorer":{"id":"users/block-explorer","title":"Block Explorers","description":"The Casper blockchain is available as the Mainnet and Testnet.","sidebar":"users"},"users/csprlive/delegate-ui":{"id":"users/csprlive/delegate-ui","title":"Delegate Tokens","description":"Introduction","sidebar":"users"},"users/csprlive/index":{"id":"users/csprlive/index","title":"Using CSPR.live","description":"| Topic | Description |","sidebar":"users"},"users/csprlive/testnet-faucet":{"id":"users/csprlive/testnet-faucet","title":"Testnet Funding","description":"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.","sidebar":"users"},"users/csprlive/token-transfer":{"id":"users/csprlive/token-transfer","title":"Transfer Tokens","description":"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user\'s purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.","sidebar":"users"},"users/csprlive/undelegate-ui":{"id":"users/csprlive/undelegate-ui","title":"Undelegate Tokens","description":"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.","sidebar":"users"},"users/delegating":{"id":"users/delegating","title":"Delegating Tokens","description":"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.","sidebar":"users"},"users/funding-from-exchanges":{"id":"users/funding-from-exchanges","title":"Funding Mainnet Accounts","description":"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account\'s public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.","sidebar":"users"},"users/index":{"id":"users/index","title":"Users Overview","description":"General Topics","sidebar":"users"},"users/ledger/index":{"id":"users/ledger/index","title":"Casper on Ledger","description":"| Topic | Description |","sidebar":"users"},"users/ledger/ledger-cspr-live":{"id":"users/ledger/ledger-cspr-live","title":"Ledger and CSPR.live","description":"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-live":{"id":"users/ledger/ledger-live","title":"Ledger and Ledger Live","description":"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-setup":{"id":"users/ledger/ledger-setup","title":"Set up Ledger","description":"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.","sidebar":"users"},"users/ledger/staking-ledger":{"id":"users/ledger/staking-ledger","title":"Delegate with Ledger","description":"Ledger Initialization","sidebar":"users"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/236eb0f0.5852e7f6.js b/assets/js/236eb0f0.5852e7f6.js new file mode 100644 index 000000000..863196e5d --- /dev/null +++ b/assets/js/236eb0f0.5852e7f6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53101],{61055:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/docs/resources/beginner/counter/walkthrough.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/walkthrough",permalink:"/resources/beginner/counter/walkthrough",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter/commands"},next:{title:"Introduction",permalink:"/counter-testnet"}},i={},l=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"Create a Local Network",id:"create-a-local-network",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-local-network",children:"Create a Local Network"}),"\n",(0,s.jsx)(t.p,{children:"After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network."}),"\n",(0,s.jsx)(t.p,{children:"If you run the following line in your terminal, you should be able to spin up a network effortlessly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["If it fails for any reason, please refer the ",(0,s.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"NCTL tutorial"})," and make sure that all your packages are up to date."]})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"AccountHash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"nctl-view-faucet-account"})," - Get the faucet's account hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state root hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," - Get the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the ",(0,s.jsx)(t.em,{children:"account-hash"})," field and the ",(0,s.jsx)(t.em,{children:"secret_key.pem"})," path because you will often use both."]}),"\n",(0,s.jsx)(t.p,{children:"Get the state root hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You are using localhost as the node server since the network is running on our local machine. Make a note of the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call ",(0,s.jsx)(t.em,{children:"nctl-view-faucet-account"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to install the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on your local network!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/236eb0f0.ea22eadd.js b/assets/js/236eb0f0.ea22eadd.js deleted file mode 100644 index 013689694..000000000 --- a/assets/js/236eb0f0.ea22eadd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3101],{61055:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/docs/resources/beginner/counter/walkthrough.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/walkthrough",permalink:"/next/resources/beginner/counter/walkthrough",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/next/resources/beginner/counter/commands"},next:{title:"Introduction",permalink:"/next/counter-testnet"}},i={},l=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"Create a Local Network",id:"create-a-local-network",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-local-network",children:"Create a Local Network"}),"\n",(0,s.jsx)(t.p,{children:"After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network."}),"\n",(0,s.jsx)(t.p,{children:"If you run the following line in your terminal, you should be able to spin up a network effortlessly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["If it fails for any reason, please refer the ",(0,s.jsx)(t.a,{href:"/next/developers/dapps/setup-nctl",children:"NCTL tutorial"})," and make sure that all your packages are up to date."]})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"AccountHash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"nctl-view-faucet-account"})," - Get the faucet's account hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state root hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," - Get the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the ",(0,s.jsx)(t.em,{children:"account-hash"})," field and the ",(0,s.jsx)(t.em,{children:"secret_key.pem"})," path because you will often use both."]}),"\n",(0,s.jsx)(t.p,{children:"Get the state root hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You are using localhost as the node server since the network is running on our local machine. Make a note of the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call ",(0,s.jsx)(t.em,{children:"nctl-view-faucet-account"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to install the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on your local network!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23e022aa.6c773674.js b/assets/js/23e022aa.6c773674.js deleted file mode 100644 index 5debd5ce6..000000000 --- a/assets/js/23e022aa.6c773674.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9155],{62267:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var d=r(74848),s=r(28453);const t={},i="Casper JSON-RPC Error Codes",c={id:"developers/json-rpc/errors",title:"Casper JSON-RPC Error Codes",description:"The following document expands on custom error codes provided by casper-json-rpc crate.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/errors.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/errors",permalink:"/developers/json-rpc/errors",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},l={},o=[{value:"Error Codes",id:"codes",level:2},{value:"Invalid <code>Params</code>",id:"invalid-params",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"casper-json-rpc-error-codes",children:"Casper JSON-RPC Error Codes"})}),"\n",(0,d.jsxs)(n.p,{children:["The following document expands on custom error codes provided by ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," crate."]}),"\n",(0,d.jsx)(n.h2,{id:"codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Code"}),(0,d.jsx)(n.th,{children:"Error"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-1"}),(0,d.jsx)(n.td,{children:"NoSuchDeploy"}),(0,d.jsx)(n.td,{children:"The requested Deploy was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-2"}),(0,d.jsx)(n.td,{children:"NoSuchBlock"}),(0,d.jsx)(n.td,{children:"The requested Block was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-3"}),(0,d.jsx)(n.td,{children:"FailedToParseQueryKey"}),(0,d.jsx)(n.td,{children:"Parsing the Key from a query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-4"}),(0,d.jsx)(n.td,{children:"QueryFailed"}),(0,d.jsx)(n.td,{children:"The query failed to find a result."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-5"}),(0,d.jsx)(n.td,{children:"QueryFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-6"}),(0,d.jsx)(n.td,{children:"FailedToParseGetBalanceURef"}),(0,d.jsx)(n.td,{children:"Parsing the URef while getting a balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-7"}),(0,d.jsx)(n.td,{children:"FailedToGetBalance"}),(0,d.jsx)(n.td,{children:"Failed to get the requested balance."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-8"}),(0,d.jsx)(n.td,{children:"GetBalanceFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query to retrieve the balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-9"}),(0,d.jsx)(n.td,{children:"InvalidDeploy"}),(0,d.jsx)(n.td,{children:"The given Deploy cannot be executed as it is invalid."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-10"}),(0,d.jsx)(n.td,{children:"NoSuchAccount"}),(0,d.jsx)(n.td,{children:"The given account was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-11"}),(0,d.jsx)(n.td,{children:"FailedToGetDictionaryURef"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary URef."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-12"}),(0,d.jsx)(n.td,{children:"FailedToGetTrie"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary trie."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-13"}),(0,d.jsx)(n.td,{children:"NoSuchStateRoot"}),(0,d.jsx)(n.td,{children:"The requested state root hash was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32600"}),(0,d.jsx)(n.td,{children:"InvalidRequest"}),(0,d.jsx)(n.td,{children:"The JSON sent is not a valid Request object."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32601"}),(0,d.jsx)(n.td,{children:"MethodNotFound"}),(0,d.jsx)(n.td,{children:"The method does not exist or is not available."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32602"}),(0,d.jsx)(n.td,{children:"InvalidParams"}),(0,d.jsx)(n.td,{children:"Invalid method parameter(s)"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32603"}),(0,d.jsx)(n.td,{children:"InternalError"}),(0,d.jsx)(n.td,{children:"Internal JSON-RPC error."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32700"}),(0,d.jsx)(n.td,{children:"ParseError"}),(0,d.jsx)(n.td,{children:"Invalid JSON was received by the server."})]})]})]}),"\n",(0,d.jsxs)(n.h2,{id:"invalid-params",children:["Invalid ",(0,d.jsx)(n.code,{children:"Params"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," no longer ignores invalid ",(0,d.jsx)(n.code,{children:"params"})," fields. ",(0,d.jsx)(n.code,{children:"Params"})," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."]}),"\n",(0,d.jsxs)(n.p,{children:["Failing to adhere to this will result in an ",(0,d.jsx)(n.code,{children:"InvalidParams"})," error."]})]})}function a(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var d=r(96540);const s={},t=d.createContext(s);function i(e){const n=d.useContext(t);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),d.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/23e022aa.9f08479d.js b/assets/js/23e022aa.9f08479d.js new file mode 100644 index 000000000..ff926a756 --- /dev/null +++ b/assets/js/23e022aa.9f08479d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29155],{62267:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var d=r(74848),s=r(28453);const t={},i="Casper JSON-RPC Error Codes",c={id:"developers/json-rpc/errors",title:"Casper JSON-RPC Error Codes",description:"The following document expands on custom error codes provided by casper-json-rpc crate.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/errors.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/errors",permalink:"/1.5.X/developers/json-rpc/errors",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},l={},o=[{value:"Error Codes",id:"codes",level:2},{value:"Invalid <code>Params</code>",id:"invalid-params",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"casper-json-rpc-error-codes",children:"Casper JSON-RPC Error Codes"})}),"\n",(0,d.jsxs)(n.p,{children:["The following document expands on custom error codes provided by ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," crate."]}),"\n",(0,d.jsx)(n.h2,{id:"codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Code"}),(0,d.jsx)(n.th,{children:"Error"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-1"}),(0,d.jsx)(n.td,{children:"NoSuchDeploy"}),(0,d.jsx)(n.td,{children:"The requested Deploy was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-2"}),(0,d.jsx)(n.td,{children:"NoSuchBlock"}),(0,d.jsx)(n.td,{children:"The requested Block was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-3"}),(0,d.jsx)(n.td,{children:"FailedToParseQueryKey"}),(0,d.jsx)(n.td,{children:"Parsing the Key from a query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-4"}),(0,d.jsx)(n.td,{children:"QueryFailed"}),(0,d.jsx)(n.td,{children:"The query failed to find a result."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-5"}),(0,d.jsx)(n.td,{children:"QueryFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-6"}),(0,d.jsx)(n.td,{children:"FailedToParseGetBalanceURef"}),(0,d.jsx)(n.td,{children:"Parsing the URef while getting a balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-7"}),(0,d.jsx)(n.td,{children:"FailedToGetBalance"}),(0,d.jsx)(n.td,{children:"Failed to get the requested balance."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-8"}),(0,d.jsx)(n.td,{children:"GetBalanceFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query to retrieve the balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-9"}),(0,d.jsx)(n.td,{children:"InvalidDeploy"}),(0,d.jsx)(n.td,{children:"The given Deploy cannot be executed as it is invalid."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-10"}),(0,d.jsx)(n.td,{children:"NoSuchAccount"}),(0,d.jsx)(n.td,{children:"The given account was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-11"}),(0,d.jsx)(n.td,{children:"FailedToGetDictionaryURef"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary URef."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-12"}),(0,d.jsx)(n.td,{children:"FailedToGetTrie"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary trie."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-13"}),(0,d.jsx)(n.td,{children:"NoSuchStateRoot"}),(0,d.jsx)(n.td,{children:"The requested state root hash was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32600"}),(0,d.jsx)(n.td,{children:"InvalidRequest"}),(0,d.jsx)(n.td,{children:"The JSON sent is not a valid Request object."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32601"}),(0,d.jsx)(n.td,{children:"MethodNotFound"}),(0,d.jsx)(n.td,{children:"The method does not exist or is not available."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32602"}),(0,d.jsx)(n.td,{children:"InvalidParams"}),(0,d.jsx)(n.td,{children:"Invalid method parameter(s)"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32603"}),(0,d.jsx)(n.td,{children:"InternalError"}),(0,d.jsx)(n.td,{children:"Internal JSON-RPC error."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32700"}),(0,d.jsx)(n.td,{children:"ParseError"}),(0,d.jsx)(n.td,{children:"Invalid JSON was received by the server."})]})]})]}),"\n",(0,d.jsxs)(n.h2,{id:"invalid-params",children:["Invalid ",(0,d.jsx)(n.code,{children:"Params"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," no longer ignores invalid ",(0,d.jsx)(n.code,{children:"params"})," fields. ",(0,d.jsx)(n.code,{children:"Params"})," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."]}),"\n",(0,d.jsxs)(n.p,{children:["Failing to adhere to this will result in an ",(0,d.jsx)(n.code,{children:"InvalidParams"})," error."]})]})}function a(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var d=r(96540);const s={},t=d.createContext(s);function i(e){const n=d.useContext(t);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),d.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/241648bf.39c48090.js b/assets/js/241648bf.39c48090.js new file mode 100644 index 000000000..bf985b8d5 --- /dev/null +++ b/assets/js/241648bf.39c48090.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[26220],{1202:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=s(74848),n=s(28453);const o={},c="Execution Error Codes",i={id:"developers/cli/execution-error-codes",title:"Execution Error Codes",description:"This section covers smart contract execution error codes.",source:"@site/versioned_docs/version-1.5.X/developers/cli/execution-error-codes.md",sourceDirName:"developers/cli",slug:"/developers/cli/execution-error-codes",permalink:"/1.5.X/developers/cli/execution-error-codes",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"OpCode Costs Tables",permalink:"/1.5.X/developers/cli/opcode-costs"}},a={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"execution-error-codes",children:"Execution Error Codes"})}),"\n",(0,t.jsx)(r.p,{children:"This section covers smart contract execution error codes."}),"\n",(0,t.jsxs)(r.p,{children:["As mentioned in ",(0,t.jsx)(r.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts"}),", smart contracts can exit with an error code defined by an ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html",children:"ApiError"}),". Descriptions of each variant are found ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"})," and include the following sub-types:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.HandlePayment",children:"payment errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.Mint",children:"mint errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.User",children:"custom user errors"})}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["An ",(0,t.jsx)(r.code,{children:"ApiError"})," of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ",(0,t.jsx)(r.code,{children:"ApiError::User(2)"})," maps to an exit code of ",(0,t.jsx)(r.code,{children:"65538"})," (i.e. ",(0,t.jsx)(r.code,{children:"65536 + 2"}),"). You can find a mapping from contract exit codes to ",(0,t.jsx)(r.code,{children:"ApiError"})," variants ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>c,x:()=>i});var t=s(96540);const n={},o=t.createContext(n);function c(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/241648bf.5946a39a.js b/assets/js/241648bf.5946a39a.js deleted file mode 100644 index ad6584c51..000000000 --- a/assets/js/241648bf.5946a39a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6220],{1202:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=s(74848),n=s(28453);const o={},c="Execution Error Codes",i={id:"developers/cli/execution-error-codes",title:"Execution Error Codes",description:"This section covers smart contract execution error codes.",source:"@site/versioned_docs/version-1.5.X/developers/cli/execution-error-codes.md",sourceDirName:"developers/cli",slug:"/developers/cli/execution-error-codes",permalink:"/developers/cli/execution-error-codes",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"OpCode Costs Tables",permalink:"/developers/cli/opcode-costs"}},a={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"execution-error-codes",children:"Execution Error Codes"})}),"\n",(0,t.jsx)(r.p,{children:"This section covers smart contract execution error codes."}),"\n",(0,t.jsxs)(r.p,{children:["As mentioned in ",(0,t.jsx)(r.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts"}),", smart contracts can exit with an error code defined by an ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html",children:"ApiError"}),". Descriptions of each variant are found ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"})," and include the following sub-types:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.HandlePayment",children:"payment errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.Mint",children:"mint errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.User",children:"custom user errors"})}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["An ",(0,t.jsx)(r.code,{children:"ApiError"})," of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ",(0,t.jsx)(r.code,{children:"ApiError::User(2)"})," maps to an exit code of ",(0,t.jsx)(r.code,{children:"65538"})," (i.e. ",(0,t.jsx)(r.code,{children:"65536 + 2"}),"). You can find a mapping from contract exit codes to ",(0,t.jsx)(r.code,{children:"ApiError"})," variants ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>c,x:()=>i});var t=s(96540);const n={},o=t.createContext(n);function c(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/241f36ed.20e39934.js b/assets/js/241f36ed.20e39934.js new file mode 100644 index 000000000..12175528a --- /dev/null +++ b/assets/js/241f36ed.20e39934.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24972],{34394:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>t,metadata:()=>d,toc:()=>a});var s=i(74848),l=i(28453);const t={},r="Primitives and Basic Serialization Rules",d={id:"concepts/serialization/primitives",title:"Primitives and Basic Serialization Rules",description:"CLValue",source:"@site/versioned_docs/version-2.0.0/concepts/serialization/primitives.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/primitives",permalink:"/2.0.0/concepts/serialization/primitives",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Binary Serialization Standard",permalink:"/2.0.0/concepts/serialization/"},next:{title:"Major Structures",permalink:"/2.0.0/concepts/serialization/structures"}},c={},a=[{value:"<code>CLValue</code>",id:"clvalue",level:2},{value:"Boolean",id:"clvalue-boolean",level:3},{value:"Numeric",id:"clvalue-numeric",level:3},{value:"Unit",id:"clvalue-unit",level:3},{value:"String",id:"clvalue-string",level:3},{value:"Option",id:"clvalue-option",level:3},{value:"List",id:"clvalue-list",level:3},{value:"ByteArray",id:"clvalue-ByteArray",level:3},{value:"Result",id:"clvalue-result",level:3},{value:"Tuple",id:"clvalue-tuple",level:3},{value:"Map",id:"clvalue-map",level:3},{value:"URef",id:"clvalue-uref",level:3},{value:"PublicKey",id:"clvalue-publickey",level:3},{value:"Key",id:"clvalue-key",level:3},{value:"CLType",id:"clvalue-cltype",level:3},{value:"CLValue",id:"clvalue-clvalue",level:3},{value:"Contracts",id:"global-state-contracts",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"primitives-and-basic-serialization-rules",children:"Primitives and Basic Serialization Rules"})}),"\n",(0,s.jsx)(n.h2,{id:"clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," describes data that is used by smart contracts. This could be a local state variable, input argument, or return value. A ",(0,s.jsx)(n.code,{children:"CLValue"})," consists of two parts: a ",(0,s.jsx)(n.code,{children:"CLType"})," describing the type of the value and an array of bytes representing the data in our serialization format."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," is described by the following recursive data type:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All data that can be assigned a (non-",(0,s.jsx)(n.code,{children:"Any"}),") ",(0,s.jsx)(n.code,{children:"CLType"})," can be serialized according to the following rules, which define the Casper serialization format:"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-boolean",children:"Boolean"}),"\n",(0,s.jsxs)(n.p,{children:["Boolean values serialize as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-numeric",children:"Numeric"}),"\n",(0,s.jsx)(n.p,{children:"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u8"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"1024u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00040000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Wider numeric values (i.e. ",(0,s.jsx)(n.code,{children:"U128"}),", ",(0,s.jsx)(n.code,{children:"U256"}),", ",(0,s.jsx)(n.code,{children:"U512"}),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This reduces the serialization size when small numbers are represented within a wide data type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(7)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x0107"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(1024)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x020004"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:'U512::from("123456789101112131415")'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0957ff1ada959f4eb106"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-unit",children:"Unit"}),"\n",(0,s.jsx)(n.p,{children:"Unit serializes to an empty byte array."}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-string",children:"String"}),"\n",(0,s.jsx)(n.p,{children:"Strings serialize as a 32-bit integer representing the length in bytes (that might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:'"Hello, World!"'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0d00000048656c6c6f2c20576f726c6421"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-option",children:"Option"}),"\n",(0,s.jsxs)(n.p,{children:["Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,s.jsx)(n.code,{children:"0"})," if the value is missing, and ",(0,s.jsx)(n.code,{children:"1"})," if it is present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"None"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"Some(10u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010a000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-list",children:"List"}),"\n",(0,s.jsxs)(n.p,{children:["A list of values serializes as a 32-bit integer representing the number of elements in the list (differing from strings where it gives the number of ",(0,s.jsx)(n.em,{children:"bytes"}),"), followed by the concatenation of each serialized element."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List()"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00000000"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List(1u32, 2u32, 3u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x03000000010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-ByteArray",children:"ByteArray"}),"\n",(0,s.jsx)(n.p,{children:"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"[1u32, 2u32, 3u32]"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-result",children:"Result"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Result"})," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,s.jsx)(n.code,{children:"1"})," for the success variant and ",(0,s.jsx)(n.code,{children:"0"})," for the error variant."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-tuple",children:"Tuple"}),"\n",(0,s.jsxs)(n.p,{children:["Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,s.jsx)(n.code,{children:"ByteArray"})," the number of elements is not included in the serialization because it is statically known in the type."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-map",children:"Map"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Map"})," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,s.jsx)(n.code,{children:"Map"})," data structures can be unordered."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-uref",children:"URef"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," values serialize as the concatenation of their address (a fixed-length list of ",(0,s.jsx)(n.code,{children:"u8"}),") and a single byte tag representing access rights, which are converted as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Access Rights"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"NONE"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WRITE"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_WRITE"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"7"})]})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["When passing a URef to another entity on chain, you must ensure that the ",(0,s.jsx)(n.code,{children:"AccessRights"})," are set correctly. If the URef represents a ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/P#purse",children:"purse"}),", ",(0,s.jsx)(n.code,{children:"AccessRights"})," impact who can deposit and withdraw CSPR."]})}),"\n",(0,s.jsxs)(n.p,{children:["If a passed URef contains ",(0,s.jsx)(n.code,{children:"ADD"})," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions. In this event, ",(0,s.jsx)(n.code,{children:"READ"})," and ",(0,s.jsx)(n.code,{children:"ADD"})," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions unintentionally."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PublicKey"})," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,s.jsx)(n.code,{children:"PublicKey"})," itself:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"System"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"0"}),". With this variant, the single byte of ",(0,s.jsx)(n.code,{children:"0"})," is the entire key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the single tag byte is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-key",children:"Key"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Key"})," values serialize as a single byte tag representing the variant, followed by the serialization of the data that the variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,s.jsx)(n.code,{children:"Key::URef"}),", which contains a ",(0,s.jsx)(n.code,{children:"URef"}),"; so its data serializes per the description above. The tags are as follows: ",(0,s.jsx)(n.code,{children:"Key::Account"})," serializes as ",(0,s.jsx)(n.code,{children:"0"}),", ",(0,s.jsx)(n.code,{children:"Key::Hash"})," as ",(0,s.jsx)(n.code,{children:"1"}),", ",(0,s.jsx)(n.code,{children:"Key::URef"})," as ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-cltype",children:"CLType"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," itself also has rules for serialization. A ",(0,s.jsx)(n.code,{children:"CLType"})," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,s.jsx)(n.code,{children:"ByteArray"})," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"CLType"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I32"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I64"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U8"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U32"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U64"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U128"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U256"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U512"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unit"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"12"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Option"})}),(0,s.jsx)(n.td,{children:"13"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"List"})}),(0,s.jsx)(n.td,{children:"14"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ByteArray"})}),(0,s.jsx)(n.td,{children:"15"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Result"})}),(0,s.jsx)(n.td,{children:"16"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Map"})}),(0,s.jsx)(n.td,{children:"17"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple1"})}),(0,s.jsx)(n.td,{children:"18"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple2"})}),(0,s.jsx)(n.td,{children:"19"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple3"})}),(0,s.jsx)(n.td,{children:"20"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Any"})}),(0,s.jsx)(n.td,{children:"21"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PublicKey"})}),(0,s.jsx)(n.td,{children:"22"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-clvalue",children:"CLValue"}),"\n",(0,s.jsxs)(n.p,{children:["A complete ",(0,s.jsx)(n.code,{children:"CLValue"}),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-contracts",children:"Contracts"}),"\n",(0,s.jsxs)(n.p,{children:["Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,s.jsx)(n.em,{children:"contract"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a ",(0,s.jsx)(n.a,{href:"https://webassembly.github.io/spec/core/syntax/modules.html",children:"wasm module"})]}),"\n",(0,s.jsx)(n.li,{children:"a collection of named keys"}),"\n",(0,s.jsx)(n.li,{children:"a protocol version"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The wasm module must contain a function named ",(0,s.jsx)(n.code,{children:"call"}),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#execution-semantics-runtime",children:"Casper runtime"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note: though the ",(0,s.jsx)(n.code,{children:"call"})," function signature has no arguments and no return value, within the ",(0,s.jsx)(n.code,{children:"call"})," function body, the ",(0,s.jsx)(n.code,{children:"get_named_arg"})," runtime function can be used to accept arguments (by ordinal), and the ",(0,s.jsx)(n.code,{children:"ret"})," runtime function can be used to return a single ",(0,s.jsx)(n.code,{children:"CLValue"})," to the caller."]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,s.jsx)(n.code,{children:"URef"}),"s, which are known to the contract (see the section on Permissions for details)."]}),"\n",(0,s.jsx)(n.p,{children:"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."})]})}function o(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var s=i(96540);const l={},t=s.createContext(l);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/24433f15.4be389a9.js b/assets/js/24433f15.4be389a9.js new file mode 100644 index 000000000..78acb78d0 --- /dev/null +++ b/assets/js/24433f15.4be389a9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25959],{57698:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var a=n(74848),r=n(28453);const s={title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},o="Safely Transfer Tokens to a Contract",i={id:"resources/advanced/transfer-token-to-contract",title:"Token Transfers",description:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/transfer-token-to-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/transfer-token-to-contract",permalink:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},sidebar:"tutorials",previous:{title:"Authorization Keys",permalink:"/2.0.0/resources/advanced/list-auth-keys-tutorial"},next:{title:"Storage Workflow",permalink:"/2.0.0/resources/tutorials/advanced/storage-workflow"}},c={},h=[{value:"Scenario 1 - Creating a Throw-Away Purse",id:"scenario1",level:2},{value:"Scenario 1 - Advanced Variation",id:"scenario1-advanced",level:3},{value:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic",id:"scenario2",level:2},{value:"Scenario 2 - Advanced Variation",id:"scenario2-advanced",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"safely-transfer-tokens-to-a-contract",children:"Safely Transfer Tokens to a Contract"})}),"\n",(0,a.jsx)(t.p,{children:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs."}),"\n",(0,a.jsxs)(t.p,{children:["For increased security, token transfers from a main purse must be handled via session code (WASM), as shown ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code#transfers-using-session-code",children:"here"}),". Therefore, ",(0,a.jsx)(t.code,{children:"transfer-*"})," methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario1",children:"Scenario 1 - Creating a Throw-Away Purse"}),"\n",(0,a.jsx)(t.p,{children:"The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee."}),"\n",(0,a.jsx)(t.p,{children:"In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues."}),"\n",(0,a.jsx)(t.p,{children:"This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation."}),"\n",(0,a.jsx)(t.p,{children:"Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_name of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n let entry_point_name = runtime::get_named_arg("entry_point_name");\n\n // This creates a new empty purse that the caller will use just this one time.\n let new_purse = system::create_purse();\n \n // Transfer from the caller\'s main purse to the new purse that was just created.\n // Note that transfer is done safely by the host logic.\n system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)\n .unwrap_or_revert();\n \n // Pass the newly created purse to the smart contract with full access rights; \n // the called contract should receive the new purse, extract the token from it, and then do\n // whatever else it is meant to do if a valid amount was transferred to it. Note that the\n // caller\'s main purse is never exposed to the called contract; the newly created purse\n // is provided instead.\n runtime::call_contract(contract_hash, entry_point_name, runtime_args! {\n // The arg names are defined by the contract that you are calling,\n // there is no canonical name. The contract you are calling may have other\n // runtime args that it requires.\n "????" => new_purse\n });\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario1-advanced",children:"Scenario 1 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs",children:"This example"})," provides a framework for the idea, but will require modification to suit developer needs."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario2",children:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"}),"\n",(0,a.jsx)(t.p,{children:"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."}),"\n",(0,a.jsxs)(t.p,{children:["In ",(0,a.jsx)(t.a,{href:"#scenario1",children:"Scenario 1"}),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,a.jsx)(t.a,{href:"#scenario1-advanced",children:"Scenario 1's Advanced Variation"})," in that the purse in question is under the control of the contract rather than the caller."]}),"\n",(0,a.jsx)(t.p,{children:"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic. \n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments. \n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario2-advanced",children:"Scenario 2 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."}),"\n",(0,a.jsx)(t.p,{children:"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var a=n(96540);const r={},s=a.createContext(r);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/25f19435.e9c61eb7.js b/assets/js/25f19435.e9c61eb7.js deleted file mode 100644 index cdea9bf1c..000000000 --- a/assets/js/25f19435.e9c61eb7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8344],{82432:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var a=n(74848),o=n(28453);const s={},i="Global State {#global-state-head}",r={id:"concepts/global-state",title:"Global State",description:"global-state-head}",source:"@site/docs/concepts/global-state.md",sourceDirName:"concepts",slug:"/concepts/global-state",permalink:"/next/concepts/global-state",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"concepts",previous:{title:"Transaction Lifecycle",permalink:"/next/transactions-and-transaction-lifecycle"},next:{title:"Smart Contracts",permalink:"/next/concepts/smart-contracts"}},c={},l=[{value:"Introduction",id:"global-state-intro",level:2},{value:"Merkle Trie Structure",id:"global-state-trie",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"global-state-head",children:"Global State"})}),"\n",(0,a.jsx)(t.h2,{id:"global-state-intro",children:"Introduction"}),"\n",(0,a.jsxs)(t.p,{children:["The storage layer for the Casper blockchain is called ",(0,a.jsx)(t.em,{children:"global state"})," and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Refer to ",(0,a.jsx)(t.a,{href:"/next/concepts/serialization/types#serialization-standard-serialization-key",children:"Keys and Permissions"})," for further information on keys."]})}),"\n",(0,a.jsxs)(t.p,{children:["Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a ",(0,a.jsx)(t.a,{href:"#global-state-trie",children:"Merkle trie"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"global-state-trie",children:"Merkle Trie Structure"}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Global State",src:n(11032).A+"",width:"5344",height:"4496"})}),"\n",(0,a.jsx)(t.p,{children:"At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes."}),"\n",(0,a.jsx)(t.p,{children:"Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value."}),"\n",(0,a.jsx)(t.p,{children:"Formally, a trie node is one of the following:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"a leaf, which includes a key and a value"}),"\n",(0,a.jsxs)(t.li,{children:["a branch, which has up to 256 ",(0,a.jsx)(t.code,{children:"blake2b256"})," hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)"]}),"\n",(0,a.jsxs)(t.li,{children:["an extension node, which includes a byte array (called the affix) and a ",(0,a.jsx)(t.code,{children:"blake2b256"})," hash pointing to another node in the trie"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node."}),"\n",(0,a.jsx)(t.p,{children:"The Rust implementation of Casper's trie can be found on GitHub:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie/mod.rs#L340",children:"Definition of the trie data structure"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L44",children:"Reading from the trie"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L845",children:"Writing to the trie"})}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a ",(0,a.jsx)(t.code,{children:"TrieStore"}),", which allows us to look up the root node for each trie."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},11032:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/global-state-6ff422f087f093966968318f641d26fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const o={},s=a.createContext(o);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/25f19435.f0517f89.js b/assets/js/25f19435.f0517f89.js new file mode 100644 index 000000000..feb5304cb --- /dev/null +++ b/assets/js/25f19435.f0517f89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[88344],{82432:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var n=a(74848),o=a(28453);const s={},i="Global State {#global-state-head}",r={id:"concepts/global-state",title:"Global State",description:"global-state-head}",source:"@site/docs/concepts/global-state.md",sourceDirName:"concepts",slug:"/concepts/global-state",permalink:"/concepts/global-state",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"concepts",previous:{title:"Transaction Lifecycle",permalink:"/transactions-and-transaction-lifecycle"},next:{title:"Smart Contracts",permalink:"/concepts/smart-contracts"}},c={},l=[{value:"Introduction",id:"global-state-intro",level:2},{value:"Merkle Trie Structure",id:"global-state-trie",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"global-state-head",children:"Global State"})}),"\n",(0,n.jsx)(t.h2,{id:"global-state-intro",children:"Introduction"}),"\n",(0,n.jsxs)(t.p,{children:["The storage layer for the Casper blockchain is called ",(0,n.jsx)(t.em,{children:"global state"})," and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly."]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Refer to ",(0,n.jsx)(t.a,{href:"/concepts/serialization/types#serialization-standard-serialization-key",children:"Keys and Permissions"})," for further information on keys."]})}),"\n",(0,n.jsxs)(t.p,{children:["Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a ",(0,n.jsx)(t.a,{href:"#global-state-trie",children:"Merkle trie"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"global-state-trie",children:"Merkle Trie Structure"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Global State",src:a(3698).A+"",width:"5344",height:"4496"})}),"\n",(0,n.jsx)(t.p,{children:"At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes."}),"\n",(0,n.jsx)(t.p,{children:"Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value."}),"\n",(0,n.jsx)(t.p,{children:"Formally, a trie node is one of the following:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"a leaf, which includes a key and a value"}),"\n",(0,n.jsxs)(t.li,{children:["a branch, which has up to 256 ",(0,n.jsx)(t.code,{children:"blake2b256"})," hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)"]}),"\n",(0,n.jsxs)(t.li,{children:["an extension node, which includes a byte array (called the affix) and a ",(0,n.jsx)(t.code,{children:"blake2b256"})," hash pointing to another node in the trie"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node."}),"\n",(0,n.jsx)(t.p,{children:"The Rust implementation of Casper's trie can be found on GitHub:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie/mod.rs#L340",children:"Definition of the trie data structure"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L44",children:"Reading from the trie"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L845",children:"Writing to the trie"})}),"\n"]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a ",(0,n.jsx)(t.code,{children:"TrieStore"}),", which allows us to look up the root node for each trie."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},3698:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/global-state-6ff422f087f093966968318f641d26fc.png"},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>r});var n=a(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/261dbd4a.690860d0.js b/assets/js/261dbd4a.690860d0.js deleted file mode 100644 index 00bef55f5..000000000 --- a/assets/js/261dbd4a.690860d0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9899],{38123:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>b,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Contract-Level Events"},s="Enabling Contracts to Emit Events",i={id:"developers/writing-onchain-code/emitting-contract-events",title:"Contract-Level Events",description:"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.",source:"@site/docs/developers/writing-onchain-code/emitting-contract-events.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/emitting-contract-events",permalink:"/next/developers/writing-onchain-code/emitting-contract-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Contract-Level Events"},sidebar:"developers",previous:{title:"Testing Session Code",permalink:"/next/developers/writing-onchain-code/testing-session-code"},next:{title:"Contract Hash vs. Package Hash",permalink:"/next/developers/writing-onchain-code/contract-hash-vs-package-hash"}},r={},o=[{value:"Creating a Topic",id:"creating-a-topic",level:2},{value:"Verifying a Topic",id:"verifying-a-topic",level:2},{value:"Emitting a Message",id:"emitting-a-message",level:2},{value:"Verifying a Message",id:"verifying-a-message",level:2},{value:"Querying global state",id:"querying-global-state",level:3},{value:"Costs and Chainspec Settings",id:"costs-and-chainspec-settings",level:2},{value:"Topic Management during Contract Upgrades",id:"topic-management-during-contract-upgrades",level:2},{value:"What's Next?",id:"whats-next",level:2}];function f(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"enabling-contracts-to-emit-events",children:"Enabling Contracts to Emit Events"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Messages produced by smart contracts are visible on a node's SSE event stream in human-readable format, and they contain the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The address of the entity that produced the message, i.e., the contract hash"}),"\n",(0,t.jsx)(n.li,{children:"The message topic used to categorize the message"}),"\n",(0,t.jsx)(n.li,{children:"The human-readable message string"}),"\n",(0,t.jsx)(n.li,{children:"The index identifying the message in a message array"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["A checksum of the message is permanently stored in global state to protect against message spoofing and repudiation. For more details regarding the design and implementation of this feature, read the corresponding ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/ceps/pull/88",children:"CEP-88 documentation"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"})," provides the following two runtime functions to manage and emit messages:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"manage_message_topic"})," - Creates a topic to help categorize messages. When used for the first time, this function registers the contract's intent to emit messages. The maximum number of topics is specified in the chainspec. "]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"emit_message"})," - Emits a human-readable string message under a pre-registered topic."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following sections contain more details about using these functions."}),"\n",(0,t.jsx)(n.h2,{id:"creating-a-topic",children:"Creating a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["To create a new topic, call the ",(0,t.jsx)(n.code,{children:"manage_message_topic"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code adds a new message topic called ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),", on which the contract can emit messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::manage_message_topic(EVENTS_TOPIC, MessageTopicOperation::Add).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-topic",children:"Verifying a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["No SSE event is emitted when a contract creates a new message topic. However, some applications need to determine which message topics are available to listen to messages on those topics. In global state, each contract entity contains a field called ",(0,t.jsx)(n.code,{children:"message_topics"}),", which stores a map of registered topic names by topic name hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsxs)(n.p,{children:["You can view the contract using the Casper CLI client and the ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the block identifier or the state root hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the key that identifies the contract, e.g., addressable-entity-contract-HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://127.0.0.1:11101 \\\n--key "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5" \\\n--block-identifier 58d26bf0eeeefb698d76b319014efd2eaa2198ad754a489a23131948ef41fdd2\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample contract"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4994937296370433409,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "deafd8e5c1aff47ae8528fa2d343b711c2f5cb18ee29527961b37d4d173ad42a",\n "state_root_hash": "96d8962c03899277f9a4bd667c0510c0eab490dd6253ae0b8cee4ebfbcd52be6",\n "body_hash": "28812ec460ab82f94f3c658e946bb4779c6b76dea9c55d18beaf1e47fe8dd9c9",\n "random_bit": false,\n "accumulated_seed": "96a09ea136bb7e4e99b039ee0f1f6d9dd88d663927faffc7eb5c60804056354c",\n "era_end": null,\n "timestamp": "2023-11-28T23:59:53.856Z",\n "era_id": 112,\n "height": 1066,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "AddressableEntity": {\n "package_hash": "contract-package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "byte_code_hash": "contract-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "named_keys": [\n {\n "name": "acl_package_mode",\n "key": "uref-2a088bc6c30d1499cd9348d388a03c8162ab26d09b0484f634e6f4022581fe99-007"\n },\n {\n "name": "acl_whitelist",\n "key": "uref-d17ecf3fe6e46f9a6063cfb31cdb03cdd6b99d095b71d2247319c293f864c4d1-007"\n },\n {\n "name": "allow_minting",\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-007"\n },\n {\n "name": "approved",\n "key": "uref-87a0de173fd6a56fb867bab46d8a508a43259a244ffdd8b0d98e5c286261f9af-007"\n },\n {\n "name": "balances",\n "key": "uref-0c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f-007"\n },\n {\n "name": "burn_mode",\n "key": "uref-e507551382a6217b9165dd222854e6c877d33eab9845c4b7e8444559303e5b8a-007"\n },\n {\n "name": "burnt_tokens",\n "key": "uref-4711c3ee36ac9639af509f45164fdb5a88692b109c3b2360e57d09fcdd702f63-007"\n },\n {\n "name": "cep78_CEP-78",\n "key": "uref-a02fc32366a7187448afb8263a8f3716e933d28d84db6c6403893d94917cf98d-007"\n },\n {\n "name": "collection_name",\n "key": "uref-89e904724d79a9f6d41958a3621b437c9e220ad081805f39040ff51c79a8d67c-007"\n },\n {\n "name": "collection_symbol",\n "key": "uref-d41a40789a84cc8e0314135695acc279875d6c7455daafe517cc4ae5329d95de-007"\n },\n {\n "name": "events_mode",\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-007"\n },\n {\n "name": "hash_by_index",\n "key": "uref-7c9751097762ad778a6a11151780d377cbc57e0807e289d278831ca9263aa844-007"\n },\n {\n "name": "holder_mode",\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-007"\n },\n {\n "name": "identifier_mode",\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-007"\n },\n {\n "name": "index_by_hash",\n "key": "uref-e67fecb85654def8b1440907728491f4f1ae125a97f3fed93872c075e6fb4ad5-007"\n },\n {\n "name": "installer",\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c"\n },\n {\n "name": "json_schema",\n "key": "uref-f8b2f63a4c69a84c795908e9abd0f66b857790b8df627a21336d6d1e07bf7103-007"\n },\n {\n "name": "metadata_cep78",\n "key": "uref-5cf8084639c2b7b8f54ab78700e0a82107c0bb28966cdc3ffdd4bd0877a47f64-007"\n },\n {\n "name": "metadata_custom_validated",\n "key": "uref-f5ce01c02a1942a4833159d72414c014b0838b607b4f419af9e19cd2fb123658-007"\n },\n {\n "name": "metadata_mutability",\n "key": "uref-c11c8e99c52477efaae636890a49625f54e32b832e23e288e00952c8bf34610a-007"\n },\n {\n "name": "metadata_nft721",\n "key": "uref-d39ee0c77f9864b05297ac504ee5919d60dddb6c8c0d6ccce8225801885f8972-007"\n },\n {\n "name": "metadata_raw",\n "key": "uref-dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a-007"\n },\n {\n "name": "minting_mode",\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-007"\n },\n {\n "name": "nft_kind",\n "key": "uref-001ffa305e021b5d411a3e04707b3c17f0d31ee400e6c5faa9b8f66e0ebfdc99-007"\n },\n {\n "name": "nft_metadata_kind",\n "key": "uref-8dfb98ccdd030aae1e0dcda03dc728dd4332eb18c945fd25a55b43f9e487141e-007"\n },\n {\n "name": "nft_metadata_kinds",\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-007"\n },\n {\n "name": "number_of_minted_tokens",\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-007"\n },\n {\n "name": "operator_burn_mode",\n "key": "uref-40977d32bbfb85454c9e7b5ca03192efcd406f228d5c2e593210b3960e05604e-007"\n },\n {\n "name": "operators",\n "key": "uref-cbcb06403fbd8cb9f397029718f1f7e66bf5ec4e33aa58315dd3d5ecf5d078a7-007"\n },\n {\n "name": "ownership_mode",\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-007"\n },\n {\n "name": "package_operator_mode",\n "key": "uref-c05e3e87f5a64fbc20615afffaa6e4c81d98431b698f681322f5d8730ff40590-007"\n },\n {\n "name": "page_table",\n "key": "uref-4c545e6e4860629fd138fcb91f24d21498e69b076d472660ff769dfc2a994301-007"\n },\n {\n "name": "receipt_name",\n "key": "uref-6ddba59f56a5d52df5b8f85d03d19003feec3307a9d9ac6b420486d1a440a586-007"\n },\n {\n "name": "reporting_mode",\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-007"\n },\n {\n "name": "rlo_mflag",\n "key": "uref-d520d8cbca2b28a42f0db9493e94bdbb93f74702e20eac1a77b48dda39367afe-007"\n },\n {\n "name": "token_issuers",\n "key": "uref-c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a-007"\n },\n {\n "name": "token_owners",\n "key": "uref-1cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d-007"\n },\n {\n "name": "total_token_supply",\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-007"\n },\n {\n "name": "whitelist_mode",\n "key": "uref-af7ba884bbddf91530279c0ea005c56a4951f5330ebe5395528471302b791b3e-007"\n }\n ],\n "entry_points": [\n {\n "name": "approve",\n "entry_point": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "balance_of",\n "entry_point": {\n "name": "balance_of",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n }\n ],\n "ret": "U64",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "burn",\n "entry_point": {\n "name": "burn",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "get_approved",\n "entry_point": {\n "name": "get_approved",\n "args": [],\n "ret": {\n "Option": "Key"\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "init",\n "entry_point": {\n "name": "init",\n "args": [\n {\n "name": "collection_name",\n "cl_type": "String"\n },\n {\n "name": "collection_symbol",\n "cl_type": "String"\n },\n {\n "name": "total_token_supply",\n "cl_type": "U64"\n },\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "minting_mode",\n "cl_type": "U8"\n },\n {\n "name": "ownership_mode",\n "cl_type": "U8"\n },\n {\n "name": "nft_kind",\n "cl_type": "U8"\n },\n {\n "name": "holder_mode",\n "cl_type": "U8"\n },\n {\n "name": "whitelist_mode",\n "cl_type": "U8"\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "json_schema",\n "cl_type": "String"\n },\n {\n "name": "receipt_name",\n "cl_type": "String"\n },\n {\n "name": "identifier_mode",\n "cl_type": "U8"\n },\n {\n "name": "burn_mode",\n "cl_type": "U8"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n },\n {\n "name": "nft_metadata_kind",\n "cl_type": "U8"\n },\n {\n "name": "metadata_mutability",\n "cl_type": "U8"\n },\n {\n "name": "owner_reverse_lookup_mode",\n "cl_type": "U8"\n },\n {\n "name": "events_mode",\n "cl_type": "U8"\n },\n {\n "name": "transfer_filter_contract",\n "cl_type": {\n "Option": "Key"\n }\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "is_approved_for_all",\n "entry_point": {\n "name": "is_approved_for_all",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Bool",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "metadata",\n "entry_point": {\n "name": "metadata",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "migrate",\n "entry_point": {\n "name": "migrate",\n "args": [\n {\n "name": "cep78_package_key",\n "cl_type": "Any"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "mint",\n "entry_point": {\n "name": "mint",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": {\n "Tuple3": [\n "String",\n "Key",\n "String"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "owner_of",\n "entry_point": {\n "name": "owner_of",\n "args": [],\n "ret": "Key",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "register_owner",\n "entry_point": {\n "name": "register_owner",\n "args": [],\n "ret": {\n "Tuple2": [\n "String",\n "URef"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "revoke",\n "entry_point": {\n "name": "revoke",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_approval_for_all",\n "entry_point": {\n "name": "set_approval_for_all",\n "args": [\n {\n "name": "approve_all",\n "cl_type": "Bool"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_token_metadata",\n "entry_point": {\n "name": "set_token_metadata",\n "args": [\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_variables",\n "entry_point": {\n "name": "set_variables",\n "args": [\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "contract_whitelist",\n "cl_type": {\n "List": {\n "ByteArray": 32\n }\n }\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "transfer",\n "entry_point": {\n "name": "transfer",\n "args": [\n {\n "name": "source_key",\n "cl_type": "Key"\n },\n {\n "name": "target_key",\n "cl_type": "Key"\n }\n ],\n "ret": {\n "Tuple2": [\n "String",\n "Key"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "updated_receipts",\n "entry_point": {\n "name": "updated_receipts",\n "args": [],\n "ret": {\n "List": {\n "Tuple2": [\n "String",\n "Key"\n ]\n }\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n }\n ],\n "protocol_version": "1.0.0",\n "main_purse": "uref-596d134ad1078315a5e0cd2f40802b65cf53b6c789f0a38ba04157d04e15ab2b-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n ]\n }\n },\n "merkle_proof": "[8288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Under ",(0,t.jsx)(n.code,{children:"message_topics"}),", you will find the control record for that topic, which has a composite key derived from the caller's entity address and the hash of the topic name:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h2,{id:"emitting-a-message",children:"Emitting a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To emit a message on a previously-created topic, call the ",(0,t.jsx)(n.code,{children:"emit_message"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code sends a new message on the topic ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::emit_message(EVENTS_TOPIC, &message.try_into().unwrap()).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-message",children:"Verifying a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To verify a message, check a node's SSE endpoint, which streams messages in a human-readable format. Messages are visible as part of the ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. The messages sent out on the event stream contain the following:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The identity of the entity that produced the message"}),"\n",(0,t.jsx)(n.li,{children:"The payload of the message"}),"\n",(0,t.jsx)(n.li,{children:"The name of the topic on which the message was emitted"}),"\n",(0,t.jsx)(n.li,{children:"The blake2b hash of the topic name"}),"\n",(0,t.jsx)(n.li,{children:"The message index in the topic"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The following is a sample message logged inside a ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n]\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the full TransactionProcessed message"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'data: {\n "TransactionProcessed": {\n "transaction_hash": {\n "Deploy": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26"\n },\n "account": "0130a16c8b0918cbfa8da00b6c0910ae0f2799dfd5ef7f092d0c4c1688031d60ac",\n "timestamp": "2023-11-29T01:35:41.522Z",\n "ttl": "30m",\n "block_hash": "b90c61cd1e3bc3be36110f04a7aec97b22bcfe9f36291cb011a14c4a663753bd",\n "execution_result": {\n "Version2": {\n "Success": {\n "effects": [\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "package-c092060112b445d1706f6962d7ad2da72a2e8312000e99d2b58f6a3e1624649a",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "0e9a6a8aff995ac138938d44c64d31",\n "parsed": "999999999999999999999518955956890"\n }\n }\n }\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "AddUInt512": "7500000000"\n }\n },\n {\n "key": "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "kind": "Identity"\n },\n {\n "key": "package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "kind": "Identity"\n },\n {\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-000",\n "kind": "Identity"\n },\n {\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": "Identity"\n },\n {\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-000",\n "kind": "Identity"\n },\n {\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-000",\n "kind": "Identity"\n },\n {\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-79bb2f90d7ab9cef266efe53e70722dc6e4fa56372ce8cd859b89cec3ff05307",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "8f0000008b0000007b226e616d65223a20224a6f686e20446f65222c22746f6b656e5f757269223a202268747470733a5c2f5c2f7777772e626172666f6f2e636f6d222c22636865636b73756d223a202239343062666662336632626261333566383433313361613236646130396563653361643437303435633661313239326332626264326466346162316135356662227d0a20000000dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-203953bdea81a8373a987786d74eb94d8626c401a28625bb66c006079fd2bde7",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b200000001cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-453603548bb0d677edaa9bbc014bff6e30801a8d86eb85f884ad08e874fdc0f1",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b20000000c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-3344eae47d44ef595de8219a32c69e9ac51ee14f020bd5da24f899fd49d12abf",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "08000000010000000000000005200000000c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f4000000032313266666464303430623635343935343139663430353763383339323933306534313066376266323462616565633864653539613631313762363365343563",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-000",\n "kind": "Identity"\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": "Identity"\n },\n {\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n },\n {\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-000",\n "kind": "Identity"\n },\n {\n "key": "deploy-09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "kind": {\n "Write": {\n "DeployInfo": {\n "deploy_hash": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "transfers": [],\n "from": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "source": "uref-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861-007",\n "gas": "610139570"\n }\n }\n }\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-account-a4cb74407b8da22b5dbf8cec4b2280fd2f2276bfeaa34ec64753071adf8960f5",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "04df4c7928",\n "parsed": "679038175"\n }\n }\n }\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "AddUInt512": "6820961825"\n }\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": {\n "AddUInt512": "679038175"\n }\n }\n ],\n "transfers": [],\n "cost": "610139570"\n }\n }\n },\n "messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"querying-global-state",children:"Querying global state"}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are not stored in global state. However, global state stores a checksum of each message, allowing users to verify the origin and integrity of the message. The checksums in global state are unique and can be identified by the hash of the entity that emitted the message, the hash of the topic name, and the index of the message."}),"\n",(0,t.jsx)(n.p,{children:"You will find two types of stored values in global state:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The checksum of the message payload, as a 32-byte BLAKE2b hash of the serialized ",(0,t.jsx)(n.code,{children:"MessagePayload"})]}),"\n",(0,t.jsx)(n.li,{children:"The topic control record containing the number of messages sent on the topic and the timestamp of the block in which the messages were emitted"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Message key structure",src:a(51982).A+"",width:"2636",height:"730"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample keys"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n},\n{\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n},\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can query global state to get the message checksum, given the block identifier and the composite key of the message. The message key includes the message hash, the topic name hash, and the message index."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message, i.e., message-CONTRACT_HASH-topic-name-TOPIC_HASH-MESSAGE_INDEX."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message checksum:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3085511981091403408,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "Message": "message-checksum-56098444c4f0dff8f321cfa3769d400f4b5bfa9e01e6ad6b147d81b87130bfb9"\n },\n "merkle_proof": "[1336 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are temporary by design. Sometimes, message checksums are pruned from global state to manage storage. Pruning of old message records for a particular contract only happens if the contract emits messages again in a new block. Otherwise, the last entries from the time the contract was last executed are still retained in global state. Applications can query old checksums using the state root hash of the block that contains them."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view an example"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Let's assume we have a contract that executes in a block with block time 1 and emits 100 messages."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block with block time 1, then we will see a control struct for the topic indicating message count 100 and block time 1."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume the contract executes in another block with block time 2 and emits 50 messages."}),"\n",(0,t.jsx)(n.li,{children:"Then, if we query the global state at the root hash of the block at block time 2, we will see message count 50 and block time 2."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume 3 blocks go by, and the contract doesn't execute in those blocks (block time 3, 4, 5)."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block at block time 5, we will see message count 50 and block time 2."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can determine the number of messages emitted in a particular block:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message topic, e.g., message-topic-CONTRACT_HASH-topic-name-TOPIC_HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message topic:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-topic-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1227453659579324378,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701479952384\n }\n },\n "merkle_proof": "[1288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The message payload cannot be reconstructed by reading the entry from global state since that entry contains only the checksum of the messages sent."})}),"\n",(0,t.jsx)(n.h2,{id:"costs-and-chainspec-settings",children:"Costs and Chainspec Settings"}),"\n",(0,t.jsxs)(n.p,{children:["The following chainspec settings manage the cost of contract-level messages. These limits are bundled into the Wasm configuration settings under the ",(0,t.jsx)(n.code,{children:"wasm.messages_limits"}),". Consult the chainspec of the network you are working with, as the following are only examples."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.messages_limits]\n# Maximum size of the topic name.\nmax_topic_name_size = 256\n# Maximum number of topics that can be added for each contract.\nmax_topics_per_contract = 128\n# Maximum size in bytes of the serialized message payload.\nmax_message_size = 1_024\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Since contract-level messages are handled through FFIs, the gas cost related to using the new interface is captured in the ",(0,t.jsx)(n.code,{children:"wasm.host_function_costs"})," chainspec settings:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.host_function_costs]\nmanage_message_topic = { cost = 200, arguments = [0, 0, 0, 0] }\nemit_message = { cost = 200, arguments = [0, 0, 0, 0] }\ncost_increase_per_message = 50\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting increases the gas cost for each subsequent message when emitting multiple messages within a single execution. In the example above, within a single execution, the first message will cost 200 motes, the second will cost 250 motes, and so on. Each subsequent call will increase the gas cost by the value specified under the ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting. The subsequent execution will start from the base cost specified in the ",(0,t.jsx)(n.code,{children:"emit_message"})," setting; in this case, the following execution will start at 200 motes."]}),"\n",(0,t.jsxs)(n.p,{children:["Storage is charged based on the ",(0,t.jsx)(n.code,{children:"wasm.storage_costs.gas_per_byte"})," chainspec parameter.\nWhen a new topic is added, two records are written in global state: the topic control record and the addressable entity record extended with the new topic name and topic name hash. Because the topic name is variable, the cost depends on the length of the topic name.\nWhen a message is emitted, two records are written in global state: the topic control record and the message checksum. Writing these records incurs a fixed cost based on ",(0,t.jsx)(n.code,{children:"gas_per_byte"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"topic-management-during-contract-upgrades",children:"Topic Management during Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"When a new contract version is added to the contract package, the message topics registered from the previous version are automatically carried over to the new contract. A new control record will be written for each topic for the new contract version."}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"monitor and consume the event stream"}),"."]}),"\n"]})]})}function b(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(f,{...e})}):f(e)}},51982:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/message_keys-f4d30d684fcb186bbc91625a10f2870a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/261dbd4a.98bcfe9f.js b/assets/js/261dbd4a.98bcfe9f.js new file mode 100644 index 000000000..f644a1827 --- /dev/null +++ b/assets/js/261dbd4a.98bcfe9f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79899],{38123:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>b,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Contract-Level Events"},s="Enabling Contracts to Emit Events",i={id:"developers/writing-onchain-code/emitting-contract-events",title:"Contract-Level Events",description:"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.",source:"@site/docs/developers/writing-onchain-code/emitting-contract-events.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/emitting-contract-events",permalink:"/developers/writing-onchain-code/emitting-contract-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Contract-Level Events"},sidebar:"developers",previous:{title:"Testing Session Code",permalink:"/developers/writing-onchain-code/testing-session-code"},next:{title:"Contract Hash vs. Package Hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash"}},r={},o=[{value:"Creating a Topic",id:"creating-a-topic",level:2},{value:"Verifying a Topic",id:"verifying-a-topic",level:2},{value:"Emitting a Message",id:"emitting-a-message",level:2},{value:"Verifying a Message",id:"verifying-a-message",level:2},{value:"Querying global state",id:"querying-global-state",level:3},{value:"Costs and Chainspec Settings",id:"costs-and-chainspec-settings",level:2},{value:"Topic Management during Contract Upgrades",id:"topic-management-during-contract-upgrades",level:2},{value:"What's Next?",id:"whats-next",level:2}];function f(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"enabling-contracts-to-emit-events",children:"Enabling Contracts to Emit Events"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in ",(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Messages produced by smart contracts are visible on a node's SSE event stream in human-readable format, and they contain the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The address of the entity that produced the message, i.e., the contract hash"}),"\n",(0,t.jsx)(n.li,{children:"The message topic used to categorize the message"}),"\n",(0,t.jsx)(n.li,{children:"The human-readable message string"}),"\n",(0,t.jsx)(n.li,{children:"The index identifying the message in a message array"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["A checksum of the message is permanently stored in global state to protect against message spoofing and repudiation. For more details regarding the design and implementation of this feature, read the corresponding ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/ceps/pull/88",children:"CEP-88 documentation"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"})," provides the following two runtime functions to manage and emit messages:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"manage_message_topic"})," - Creates a topic to help categorize messages. When used for the first time, this function registers the contract's intent to emit messages. The maximum number of topics is specified in the chainspec. "]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"emit_message"})," - Emits a human-readable string message under a pre-registered topic."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following sections contain more details about using these functions."}),"\n",(0,t.jsx)(n.h2,{id:"creating-a-topic",children:"Creating a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["To create a new topic, call the ",(0,t.jsx)(n.code,{children:"manage_message_topic"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code adds a new message topic called ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),", on which the contract can emit messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::manage_message_topic(EVENTS_TOPIC, MessageTopicOperation::Add).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-topic",children:"Verifying a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["No SSE event is emitted when a contract creates a new message topic. However, some applications need to determine which message topics are available to listen to messages on those topics. In global state, each contract entity contains a field called ",(0,t.jsx)(n.code,{children:"message_topics"}),", which stores a map of registered topic names by topic name hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsxs)(n.p,{children:["You can view the contract using the Casper CLI client and the ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the block identifier or the state root hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the key that identifies the contract, e.g., addressable-entity-contract-HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://127.0.0.1:11101 \\\n--key "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5" \\\n--block-identifier 58d26bf0eeeefb698d76b319014efd2eaa2198ad754a489a23131948ef41fdd2\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample contract"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4994937296370433409,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "deafd8e5c1aff47ae8528fa2d343b711c2f5cb18ee29527961b37d4d173ad42a",\n "state_root_hash": "96d8962c03899277f9a4bd667c0510c0eab490dd6253ae0b8cee4ebfbcd52be6",\n "body_hash": "28812ec460ab82f94f3c658e946bb4779c6b76dea9c55d18beaf1e47fe8dd9c9",\n "random_bit": false,\n "accumulated_seed": "96a09ea136bb7e4e99b039ee0f1f6d9dd88d663927faffc7eb5c60804056354c",\n "era_end": null,\n "timestamp": "2023-11-28T23:59:53.856Z",\n "era_id": 112,\n "height": 1066,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "AddressableEntity": {\n "package_hash": "contract-package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "byte_code_hash": "contract-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "named_keys": [\n {\n "name": "acl_package_mode",\n "key": "uref-2a088bc6c30d1499cd9348d388a03c8162ab26d09b0484f634e6f4022581fe99-007"\n },\n {\n "name": "acl_whitelist",\n "key": "uref-d17ecf3fe6e46f9a6063cfb31cdb03cdd6b99d095b71d2247319c293f864c4d1-007"\n },\n {\n "name": "allow_minting",\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-007"\n },\n {\n "name": "approved",\n "key": "uref-87a0de173fd6a56fb867bab46d8a508a43259a244ffdd8b0d98e5c286261f9af-007"\n },\n {\n "name": "balances",\n "key": "uref-0c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f-007"\n },\n {\n "name": "burn_mode",\n "key": "uref-e507551382a6217b9165dd222854e6c877d33eab9845c4b7e8444559303e5b8a-007"\n },\n {\n "name": "burnt_tokens",\n "key": "uref-4711c3ee36ac9639af509f45164fdb5a88692b109c3b2360e57d09fcdd702f63-007"\n },\n {\n "name": "cep78_CEP-78",\n "key": "uref-a02fc32366a7187448afb8263a8f3716e933d28d84db6c6403893d94917cf98d-007"\n },\n {\n "name": "collection_name",\n "key": "uref-89e904724d79a9f6d41958a3621b437c9e220ad081805f39040ff51c79a8d67c-007"\n },\n {\n "name": "collection_symbol",\n "key": "uref-d41a40789a84cc8e0314135695acc279875d6c7455daafe517cc4ae5329d95de-007"\n },\n {\n "name": "events_mode",\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-007"\n },\n {\n "name": "hash_by_index",\n "key": "uref-7c9751097762ad778a6a11151780d377cbc57e0807e289d278831ca9263aa844-007"\n },\n {\n "name": "holder_mode",\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-007"\n },\n {\n "name": "identifier_mode",\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-007"\n },\n {\n "name": "index_by_hash",\n "key": "uref-e67fecb85654def8b1440907728491f4f1ae125a97f3fed93872c075e6fb4ad5-007"\n },\n {\n "name": "installer",\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c"\n },\n {\n "name": "json_schema",\n "key": "uref-f8b2f63a4c69a84c795908e9abd0f66b857790b8df627a21336d6d1e07bf7103-007"\n },\n {\n "name": "metadata_cep78",\n "key": "uref-5cf8084639c2b7b8f54ab78700e0a82107c0bb28966cdc3ffdd4bd0877a47f64-007"\n },\n {\n "name": "metadata_custom_validated",\n "key": "uref-f5ce01c02a1942a4833159d72414c014b0838b607b4f419af9e19cd2fb123658-007"\n },\n {\n "name": "metadata_mutability",\n "key": "uref-c11c8e99c52477efaae636890a49625f54e32b832e23e288e00952c8bf34610a-007"\n },\n {\n "name": "metadata_nft721",\n "key": "uref-d39ee0c77f9864b05297ac504ee5919d60dddb6c8c0d6ccce8225801885f8972-007"\n },\n {\n "name": "metadata_raw",\n "key": "uref-dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a-007"\n },\n {\n "name": "minting_mode",\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-007"\n },\n {\n "name": "nft_kind",\n "key": "uref-001ffa305e021b5d411a3e04707b3c17f0d31ee400e6c5faa9b8f66e0ebfdc99-007"\n },\n {\n "name": "nft_metadata_kind",\n "key": "uref-8dfb98ccdd030aae1e0dcda03dc728dd4332eb18c945fd25a55b43f9e487141e-007"\n },\n {\n "name": "nft_metadata_kinds",\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-007"\n },\n {\n "name": "number_of_minted_tokens",\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-007"\n },\n {\n "name": "operator_burn_mode",\n "key": "uref-40977d32bbfb85454c9e7b5ca03192efcd406f228d5c2e593210b3960e05604e-007"\n },\n {\n "name": "operators",\n "key": "uref-cbcb06403fbd8cb9f397029718f1f7e66bf5ec4e33aa58315dd3d5ecf5d078a7-007"\n },\n {\n "name": "ownership_mode",\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-007"\n },\n {\n "name": "package_operator_mode",\n "key": "uref-c05e3e87f5a64fbc20615afffaa6e4c81d98431b698f681322f5d8730ff40590-007"\n },\n {\n "name": "page_table",\n "key": "uref-4c545e6e4860629fd138fcb91f24d21498e69b076d472660ff769dfc2a994301-007"\n },\n {\n "name": "receipt_name",\n "key": "uref-6ddba59f56a5d52df5b8f85d03d19003feec3307a9d9ac6b420486d1a440a586-007"\n },\n {\n "name": "reporting_mode",\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-007"\n },\n {\n "name": "rlo_mflag",\n "key": "uref-d520d8cbca2b28a42f0db9493e94bdbb93f74702e20eac1a77b48dda39367afe-007"\n },\n {\n "name": "token_issuers",\n "key": "uref-c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a-007"\n },\n {\n "name": "token_owners",\n "key": "uref-1cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d-007"\n },\n {\n "name": "total_token_supply",\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-007"\n },\n {\n "name": "whitelist_mode",\n "key": "uref-af7ba884bbddf91530279c0ea005c56a4951f5330ebe5395528471302b791b3e-007"\n }\n ],\n "entry_points": [\n {\n "name": "approve",\n "entry_point": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "balance_of",\n "entry_point": {\n "name": "balance_of",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n }\n ],\n "ret": "U64",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "burn",\n "entry_point": {\n "name": "burn",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "get_approved",\n "entry_point": {\n "name": "get_approved",\n "args": [],\n "ret": {\n "Option": "Key"\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "init",\n "entry_point": {\n "name": "init",\n "args": [\n {\n "name": "collection_name",\n "cl_type": "String"\n },\n {\n "name": "collection_symbol",\n "cl_type": "String"\n },\n {\n "name": "total_token_supply",\n "cl_type": "U64"\n },\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "minting_mode",\n "cl_type": "U8"\n },\n {\n "name": "ownership_mode",\n "cl_type": "U8"\n },\n {\n "name": "nft_kind",\n "cl_type": "U8"\n },\n {\n "name": "holder_mode",\n "cl_type": "U8"\n },\n {\n "name": "whitelist_mode",\n "cl_type": "U8"\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "json_schema",\n "cl_type": "String"\n },\n {\n "name": "receipt_name",\n "cl_type": "String"\n },\n {\n "name": "identifier_mode",\n "cl_type": "U8"\n },\n {\n "name": "burn_mode",\n "cl_type": "U8"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n },\n {\n "name": "nft_metadata_kind",\n "cl_type": "U8"\n },\n {\n "name": "metadata_mutability",\n "cl_type": "U8"\n },\n {\n "name": "owner_reverse_lookup_mode",\n "cl_type": "U8"\n },\n {\n "name": "events_mode",\n "cl_type": "U8"\n },\n {\n "name": "transfer_filter_contract",\n "cl_type": {\n "Option": "Key"\n }\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "is_approved_for_all",\n "entry_point": {\n "name": "is_approved_for_all",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Bool",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "metadata",\n "entry_point": {\n "name": "metadata",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "migrate",\n "entry_point": {\n "name": "migrate",\n "args": [\n {\n "name": "cep78_package_key",\n "cl_type": "Any"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "mint",\n "entry_point": {\n "name": "mint",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": {\n "Tuple3": [\n "String",\n "Key",\n "String"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "owner_of",\n "entry_point": {\n "name": "owner_of",\n "args": [],\n "ret": "Key",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "register_owner",\n "entry_point": {\n "name": "register_owner",\n "args": [],\n "ret": {\n "Tuple2": [\n "String",\n "URef"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "revoke",\n "entry_point": {\n "name": "revoke",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_approval_for_all",\n "entry_point": {\n "name": "set_approval_for_all",\n "args": [\n {\n "name": "approve_all",\n "cl_type": "Bool"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_token_metadata",\n "entry_point": {\n "name": "set_token_metadata",\n "args": [\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_variables",\n "entry_point": {\n "name": "set_variables",\n "args": [\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "contract_whitelist",\n "cl_type": {\n "List": {\n "ByteArray": 32\n }\n }\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "transfer",\n "entry_point": {\n "name": "transfer",\n "args": [\n {\n "name": "source_key",\n "cl_type": "Key"\n },\n {\n "name": "target_key",\n "cl_type": "Key"\n }\n ],\n "ret": {\n "Tuple2": [\n "String",\n "Key"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "updated_receipts",\n "entry_point": {\n "name": "updated_receipts",\n "args": [],\n "ret": {\n "List": {\n "Tuple2": [\n "String",\n "Key"\n ]\n }\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n }\n ],\n "protocol_version": "1.0.0",\n "main_purse": "uref-596d134ad1078315a5e0cd2f40802b65cf53b6c789f0a38ba04157d04e15ab2b-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n ]\n }\n },\n "merkle_proof": "[8288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Under ",(0,t.jsx)(n.code,{children:"message_topics"}),", you will find the control record for that topic, which has a composite key derived from the caller's entity address and the hash of the topic name:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h2,{id:"emitting-a-message",children:"Emitting a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To emit a message on a previously-created topic, call the ",(0,t.jsx)(n.code,{children:"emit_message"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code sends a new message on the topic ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::emit_message(EVENTS_TOPIC, &message.try_into().unwrap()).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-message",children:"Verifying a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To verify a message, check a node's SSE endpoint, which streams messages in a human-readable format. Messages are visible as part of the ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. The messages sent out on the event stream contain the following:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The identity of the entity that produced the message"}),"\n",(0,t.jsx)(n.li,{children:"The payload of the message"}),"\n",(0,t.jsx)(n.li,{children:"The name of the topic on which the message was emitted"}),"\n",(0,t.jsx)(n.li,{children:"The blake2b hash of the topic name"}),"\n",(0,t.jsx)(n.li,{children:"The message index in the topic"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The following is a sample message logged inside a ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n]\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the full TransactionProcessed message"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'data: {\n "TransactionProcessed": {\n "transaction_hash": {\n "Deploy": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26"\n },\n "account": "0130a16c8b0918cbfa8da00b6c0910ae0f2799dfd5ef7f092d0c4c1688031d60ac",\n "timestamp": "2023-11-29T01:35:41.522Z",\n "ttl": "30m",\n "block_hash": "b90c61cd1e3bc3be36110f04a7aec97b22bcfe9f36291cb011a14c4a663753bd",\n "execution_result": {\n "Version2": {\n "Success": {\n "effects": [\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "package-c092060112b445d1706f6962d7ad2da72a2e8312000e99d2b58f6a3e1624649a",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "0e9a6a8aff995ac138938d44c64d31",\n "parsed": "999999999999999999999518955956890"\n }\n }\n }\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "AddUInt512": "7500000000"\n }\n },\n {\n "key": "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "kind": "Identity"\n },\n {\n "key": "package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "kind": "Identity"\n },\n {\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-000",\n "kind": "Identity"\n },\n {\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": "Identity"\n },\n {\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-000",\n "kind": "Identity"\n },\n {\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-000",\n "kind": "Identity"\n },\n {\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-79bb2f90d7ab9cef266efe53e70722dc6e4fa56372ce8cd859b89cec3ff05307",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "8f0000008b0000007b226e616d65223a20224a6f686e20446f65222c22746f6b656e5f757269223a202268747470733a5c2f5c2f7777772e626172666f6f2e636f6d222c22636865636b73756d223a202239343062666662336632626261333566383433313361613236646130396563653361643437303435633661313239326332626264326466346162316135356662227d0a20000000dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-203953bdea81a8373a987786d74eb94d8626c401a28625bb66c006079fd2bde7",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b200000001cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-453603548bb0d677edaa9bbc014bff6e30801a8d86eb85f884ad08e874fdc0f1",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b20000000c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-3344eae47d44ef595de8219a32c69e9ac51ee14f020bd5da24f899fd49d12abf",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "08000000010000000000000005200000000c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f4000000032313266666464303430623635343935343139663430353763383339323933306534313066376266323462616565633864653539613631313762363365343563",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-000",\n "kind": "Identity"\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": "Identity"\n },\n {\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n },\n {\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-000",\n "kind": "Identity"\n },\n {\n "key": "deploy-09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "kind": {\n "Write": {\n "DeployInfo": {\n "deploy_hash": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "transfers": [],\n "from": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "source": "uref-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861-007",\n "gas": "610139570"\n }\n }\n }\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-account-a4cb74407b8da22b5dbf8cec4b2280fd2f2276bfeaa34ec64753071adf8960f5",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "04df4c7928",\n "parsed": "679038175"\n }\n }\n }\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "AddUInt512": "6820961825"\n }\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": {\n "AddUInt512": "679038175"\n }\n }\n ],\n "transfers": [],\n "cost": "610139570"\n }\n }\n },\n "messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"querying-global-state",children:"Querying global state"}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are not stored in global state. However, global state stores a checksum of each message, allowing users to verify the origin and integrity of the message. The checksums in global state are unique and can be identified by the hash of the entity that emitted the message, the hash of the topic name, and the index of the message."}),"\n",(0,t.jsx)(n.p,{children:"You will find two types of stored values in global state:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The checksum of the message payload, as a 32-byte BLAKE2b hash of the serialized ",(0,t.jsx)(n.code,{children:"MessagePayload"})]}),"\n",(0,t.jsx)(n.li,{children:"The topic control record containing the number of messages sent on the topic and the timestamp of the block in which the messages were emitted"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Message key structure",src:a(92668).A+"",width:"2636",height:"730"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample keys"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n},\n{\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n},\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can query global state to get the message checksum, given the block identifier and the composite key of the message. The message key includes the message hash, the topic name hash, and the message index."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message, i.e., message-CONTRACT_HASH-topic-name-TOPIC_HASH-MESSAGE_INDEX."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message checksum:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3085511981091403408,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "Message": "message-checksum-56098444c4f0dff8f321cfa3769d400f4b5bfa9e01e6ad6b147d81b87130bfb9"\n },\n "merkle_proof": "[1336 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are temporary by design. Sometimes, message checksums are pruned from global state to manage storage. Pruning of old message records for a particular contract only happens if the contract emits messages again in a new block. Otherwise, the last entries from the time the contract was last executed are still retained in global state. Applications can query old checksums using the state root hash of the block that contains them."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view an example"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Let's assume we have a contract that executes in a block with block time 1 and emits 100 messages."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block with block time 1, then we will see a control struct for the topic indicating message count 100 and block time 1."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume the contract executes in another block with block time 2 and emits 50 messages."}),"\n",(0,t.jsx)(n.li,{children:"Then, if we query the global state at the root hash of the block at block time 2, we will see message count 50 and block time 2."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume 3 blocks go by, and the contract doesn't execute in those blocks (block time 3, 4, 5)."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block at block time 5, we will see message count 50 and block time 2."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can determine the number of messages emitted in a particular block:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message topic, e.g., message-topic-CONTRACT_HASH-topic-name-TOPIC_HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message topic:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-topic-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1227453659579324378,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701479952384\n }\n },\n "merkle_proof": "[1288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The message payload cannot be reconstructed by reading the entry from global state since that entry contains only the checksum of the messages sent."})}),"\n",(0,t.jsx)(n.h2,{id:"costs-and-chainspec-settings",children:"Costs and Chainspec Settings"}),"\n",(0,t.jsxs)(n.p,{children:["The following chainspec settings manage the cost of contract-level messages. These limits are bundled into the Wasm configuration settings under the ",(0,t.jsx)(n.code,{children:"wasm.messages_limits"}),". Consult the chainspec of the network you are working with, as the following are only examples."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.messages_limits]\n# Maximum size of the topic name.\nmax_topic_name_size = 256\n# Maximum number of topics that can be added for each contract.\nmax_topics_per_contract = 128\n# Maximum size in bytes of the serialized message payload.\nmax_message_size = 1_024\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Since contract-level messages are handled through FFIs, the gas cost related to using the new interface is captured in the ",(0,t.jsx)(n.code,{children:"wasm.host_function_costs"})," chainspec settings:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.host_function_costs]\nmanage_message_topic = { cost = 200, arguments = [0, 0, 0, 0] }\nemit_message = { cost = 200, arguments = [0, 0, 0, 0] }\ncost_increase_per_message = 50\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting increases the gas cost for each subsequent message when emitting multiple messages within a single execution. In the example above, within a single execution, the first message will cost 200 motes, the second will cost 250 motes, and so on. Each subsequent call will increase the gas cost by the value specified under the ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting. The subsequent execution will start from the base cost specified in the ",(0,t.jsx)(n.code,{children:"emit_message"})," setting; in this case, the following execution will start at 200 motes."]}),"\n",(0,t.jsxs)(n.p,{children:["Storage is charged based on the ",(0,t.jsx)(n.code,{children:"wasm.storage_costs.gas_per_byte"})," chainspec parameter.\nWhen a new topic is added, two records are written in global state: the topic control record and the addressable entity record extended with the new topic name and topic name hash. Because the topic name is variable, the cost depends on the length of the topic name.\nWhen a message is emitted, two records are written in global state: the topic control record and the message checksum. Writing these records incurs a fixed cost based on ",(0,t.jsx)(n.code,{children:"gas_per_byte"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"topic-management-during-contract-upgrades",children:"Topic Management during Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"When a new contract version is added to the contract package, the message topics registered from the previous version are automatically carried over to the new contract. A new control record will be written for each topic for the new contract version."}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"monitor and consume the event stream"}),"."]}),"\n"]})]})}function b(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(f,{...e})}):f(e)}},92668:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/message_keys-f4d30d684fcb186bbc91625a10f2870a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2668f34f.81895d61.js b/assets/js/2668f34f.81895d61.js deleted file mode 100644 index 39044f9b8..000000000 --- a/assets/js/2668f34f.81895d61.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1458],{93517:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=s(74848),t=s(28453);const i={title:"Set up Ledger",slug:"/workflow/ledger-setup/"},d="Ledger Setup with Casper",a={id:"users/ledger/ledger-setup",title:"Set up Ledger",description:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.",source:"@site/docs/users/ledger/ledger-setup.md",sourceDirName:"users/ledger",slug:"/workflow/ledger-setup/",permalink:"/next/workflow/ledger-setup/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Set up Ledger",slug:"/workflow/ledger-setup/"},sidebar:"users",previous:{title:"Casper on Ledger",permalink:"/next/users/ledger/"},next:{title:"Ledger and Ledger Live",permalink:"/next/users/ledger/ledger-live"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing the Casper App on a Ledger Device",id:"install-the-casper-app-on-the-ledger-device",level:2},{value:"Sending and Receiving Tokens",id:"sending-and-receiving-tokens",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"ledger-setup-with-casper",children:"Ledger Setup with Casper"})}),"\n",(0,r.jsx)(n.p,{children:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users."}),"\n",(0,r.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,r.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,r.jsxs)(n.li,{children:["Make sure the Ledger Live application version is at least at ",(0,r.jsx)(n.code,{children:"2.73.1"}),", which is the version that includes Casper accounts."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["If you need help, contact us on ",(0,r.jsx)(n.a,{href:"https://twitter.com/Casper_Network",children:"Twitter"}),", ",(0,r.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),", or ",(0,r.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"install-the-casper-app-on-the-ledger-device",children:"Installing the Casper App on a Ledger Device"}),"\n",(0,r.jsxs)(n.p,{children:["Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official ",(0,r.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger support site"}),"."]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:"In Ledger Live, open My Ledger at the bottom of the left-hand menu."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Open My Ledger",src:s(56769).A+"",width:"2034",height:"1608"})}),"\n",(0,r.jsxs)(n.ol,{start:"2",children:["\n",(0,r.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Unlock your Ledger device",src:s(6053).A+"",width:"629",height:"203"})}),"\n",(0,r.jsxs)(n.ol,{start:"3",children:["\n",(0,r.jsx)(n.li,{children:"If asked, allow Ledger manager on your device."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Allow Ledger",src:s(76909).A+"",width:"2028",height:"602"})}),"\n",(0,r.jsxs)(n.ol,{start:"4",children:["\n",(0,r.jsxs)(n.li,{children:["Find ",(0,r.jsx)(n.strong,{children:"Casper"})," in the app catalog."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Find the Casper app",src:s(15170).A+"",width:"2032",height:"1208"})}),"\n",(0,r.jsx)(n.admonition,{type:"important",children:(0,r.jsx)(n.p,{children:'Having trouble finding the Casper app?\nPlease search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.'})}),"\n",(0,r.jsxs)(n.ol,{start:"5",children:["\n",(0,r.jsxs)(n.li,{children:["Click the ",(0,r.jsx)(n.strong,{children:"Install"})," button of the app."]}),"\n"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"An installation window appears."}),"\n",(0,r.jsxs)(n.li,{children:["Your device will display ",(0,r.jsx)(n.strong,{children:'"Processing..."'})]}),"\n",(0,r.jsx)(n.li,{children:"The app installation is confirmed."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Casper installation confirmed",src:s(75607).A+"",width:"2036",height:"1242"})}),"\n",(0,r.jsxs)(n.ol,{start:"6",children:["\n",(0,r.jsx)(n.li,{children:"Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps."}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Select Casper on Ledger",src:s(47457).A+"",width:"588",height:"233"})}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.img,{alt:"Casper app is ready",src:s(93748).A+"",width:"576",height:"218"})}),"\n",(0,r.jsx)(n.h2,{id:"sending-and-receiving-tokens",children:"Sending and Receiving Tokens"}),"\n",(0,r.jsx)(n.p,{children:"To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:"}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/next/users/ledger/ledger-live",children:"Manage Casper Accounts using Ledger and Ledger Live"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"/next/users/ledger/ledger-cspr-live",children:"Manage Casper Accounts using Ledger and CSPR.live"})}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in ",(0,r.jsx)(n.a,{href:"/next/users/staking-ledger",children:"Delegating with Ledger Devices"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},76909:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/allow-ledger-8503f8c9fa4e335ac88048a9ae4dccff.png"},75607:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/casper-installed-a733e3a3b7b239ae69cae952da0ec0da.png"},93748:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/casper-ready-063ffa244f6b9eb8f5b729faa56f8215.png"},6053:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/casper-unlock-87a46771b509175ba3f5f79655391584.png"},15170:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/find-casper-db1c451d8e1bc4e2d0ada760474ee733.png"},56769:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/open-my-ledger-2cdb0ad9b46ac6eeb6212eaed8c38dd9.png"},47457:(e,n,s)=>{s.d(n,{A:()=>r});const r=s.p+"assets/images/select-casper-d33429fc63a355b702fc38926a84e870.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>a});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2668f34f.8cbf8a64.js b/assets/js/2668f34f.8cbf8a64.js new file mode 100644 index 000000000..826dbf044 --- /dev/null +++ b/assets/js/2668f34f.8cbf8a64.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31458],{93517:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const i={title:"Set up Ledger",slug:"/workflow/ledger-setup/"},d="Ledger Setup with Casper",a={id:"users/ledger/ledger-setup",title:"Set up Ledger",description:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.",source:"@site/docs/users/ledger/ledger-setup.md",sourceDirName:"users/ledger",slug:"/workflow/ledger-setup/",permalink:"/workflow/ledger-setup/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Set up Ledger",slug:"/workflow/ledger-setup/"},sidebar:"users",previous:{title:"Casper on Ledger",permalink:"/users/ledger/"},next:{title:"Ledger and Ledger Live",permalink:"/users/ledger/ledger-live"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing the Casper App on a Ledger Device",id:"install-the-casper-app-on-the-ledger-device",level:2},{value:"Sending and Receiving Tokens",id:"sending-and-receiving-tokens",level:2}];function c(e){const s={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"ledger-setup-with-casper",children:"Ledger Setup with Casper"})}),"\n",(0,r.jsx)(s.p,{children:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users."}),"\n",(0,r.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsxs)(s.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,r.jsx)(s.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,r.jsxs)(s.li,{children:["Make sure the Ledger Live application version is at least at ",(0,r.jsx)(s.code,{children:"2.73.1"}),", which is the version that includes Casper accounts."]}),"\n"]}),"\n",(0,r.jsx)(s.admonition,{type:"note",children:(0,r.jsxs)(s.p,{children:["If you need help, contact us on ",(0,r.jsx)(s.a,{href:"https://twitter.com/Casper_Network",children:"Twitter"}),", ",(0,r.jsx)(s.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),", or ",(0,r.jsx)(s.a,{href:"https://t.me/casperblockchain",children:"Telegram"}),"."]})}),"\n",(0,r.jsx)(s.h2,{id:"install-the-casper-app-on-the-ledger-device",children:"Installing the Casper App on a Ledger Device"}),"\n",(0,r.jsxs)(s.p,{children:["Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official ",(0,r.jsx)(s.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger support site"}),"."]}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:"In Ledger Live, open My Ledger at the bottom of the left-hand menu."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Open My Ledger",src:n(17887).A+"",width:"2034",height:"1608"})}),"\n",(0,r.jsxs)(s.ol,{start:"2",children:["\n",(0,r.jsx)(s.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Unlock your Ledger device",src:n(10419).A+"",width:"629",height:"203"})}),"\n",(0,r.jsxs)(s.ol,{start:"3",children:["\n",(0,r.jsx)(s.li,{children:"If asked, allow Ledger manager on your device."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Allow Ledger",src:n(3867).A+"",width:"2028",height:"602"})}),"\n",(0,r.jsxs)(s.ol,{start:"4",children:["\n",(0,r.jsxs)(s.li,{children:["Find ",(0,r.jsx)(s.strong,{children:"Casper"})," in the app catalog."]}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Find the Casper app",src:n(33968).A+"",width:"2032",height:"1208"})}),"\n",(0,r.jsx)(s.admonition,{type:"important",children:(0,r.jsx)(s.p,{children:'Having trouble finding the Casper app?\nPlease search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.'})}),"\n",(0,r.jsxs)(s.ol,{start:"5",children:["\n",(0,r.jsxs)(s.li,{children:["Click the ",(0,r.jsx)(s.strong,{children:"Install"})," button of the app."]}),"\n"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"An installation window appears."}),"\n",(0,r.jsxs)(s.li,{children:["Your device will display ",(0,r.jsx)(s.strong,{children:'"Processing..."'})]}),"\n",(0,r.jsx)(s.li,{children:"The app installation is confirmed."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Casper installation confirmed",src:n(38769).A+"",width:"2036",height:"1242"})}),"\n",(0,r.jsxs)(s.ol,{start:"6",children:["\n",(0,r.jsx)(s.li,{children:"Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps."}),"\n"]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Select Casper on Ledger",src:n(54903).A+"",width:"588",height:"233"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Casper app is ready",src:n(93602).A+"",width:"576",height:"218"})}),"\n",(0,r.jsx)(s.h2,{id:"sending-and-receiving-tokens",children:"Sending and Receiving Tokens"}),"\n",(0,r.jsx)(s.p,{children:"To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:"}),"\n",(0,r.jsxs)(s.ol,{children:["\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/users/ledger/ledger-live",children:"Manage Casper Accounts using Ledger and Ledger Live"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/users/ledger/ledger-cspr-live",children:"Manage Casper Accounts using Ledger and CSPR.live"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in ",(0,r.jsx)(s.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"}),"."]}),"\n",(0,r.jsx)(s.p,{children:"Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},3867:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/allow-ledger-8503f8c9fa4e335ac88048a9ae4dccff.png"},38769:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-installed-a733e3a3b7b239ae69cae952da0ec0da.png"},93602:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-ready-063ffa244f6b9eb8f5b729faa56f8215.png"},10419:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/casper-unlock-87a46771b509175ba3f5f79655391584.png"},33968:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/find-casper-db1c451d8e1bc4e2d0ada760474ee733.png"},17887:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/open-my-ledger-2cdb0ad9b46ac6eeb6212eaed8c38dd9.png"},54903:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/select-casper-d33429fc63a355b702fc38926a84e870.png"},28453:(e,s,n)=>{n.d(s,{R:()=>d,x:()=>a});var r=n(96540);const t={},i=r.createContext(t);function d(e){const s=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26a33332.6303f856.js b/assets/js/26a33332.6303f856.js new file mode 100644 index 000000000..212e81928 --- /dev/null +++ b/assets/js/26a33332.6303f856.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94998],{33219:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var s=n(74848),i=n(28453);const a={title:"Authorization Keys"},r="Working with Authorization Keys",o={id:"resources/advanced/list-auth-keys-tutorial",title:"Authorization Keys",description:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/list-auth-keys-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/advanced/list-auth-keys-tutorial",permalink:"/1.5.X/resources/advanced/list-auth-keys-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Authorization Keys"},sidebar:"tutorials",previous:{title:"Runtime Return Values",permalink:"/1.5.X/resources/tutorials/advanced/return-values-tutorial"},next:{title:"Token Transfers",permalink:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Workflow",id:"workflow",level:2},{value:"The example contract",id:"the-example-contract",level:3},{value:"Client Wasm files",id:"client-wasm-files",level:3},{value:"<code>add_keys.wasm</code>",id:"add_keyswasm",level:4},{value:"<code>contract_call.wasm</code>",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: <code>should_allow_install_contract_with_default_account</code>",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: <code>should_disallow_install_with_non_added_authorization_key</code>",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: <code>should_allow_install_with_added_authorization_key</code>",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: <code>should_allow_entry_point_with_installer_authorization_key</code>",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: <code>should_allow_entry_point_with_account_authorization_key</code>",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: <code>should_disallow_entry_point_without_authorization_key</code>",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: <code>should_allow_entry_point_through_contract_call_with_authorization_key</code>",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: <code>should_disallow_entry_point_through_contract_call_without_authorization_key</code>",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-authorization-keys",children:"Working with Authorization Keys"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use."})}),"\n",(0,s.jsxs)(t.p,{children:["This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"list_authorization_keys"})," function."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys = runtime::list_authorization_keys();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember that authorization keys are listed under a Deploy's ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-deploy",children:"approvals"})," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," function. In other words, ",(0,s.jsx)(t.code,{children:"list_authorization_keys"})," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["You meet the ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/prerequisites",children:"development prerequisites"})," and are familiar with ",(0,s.jsx)(t.a,{href:"/1.5.X/writing-contracts",children:"writing and testing on-chain code"})]}),"\n",(0,s.jsxs)(t.li,{children:["You know how to ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"send and verify deploys"})]}),"\n",(0,s.jsxs)(t.li,{children:["You are familiar with these concepts:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-account",children:"Casper Accounts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-deploy",children:"Deploys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#associatedkey",children:"Associated Keys"})}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#approval",children:"Approvals"}),", also known as authorization keys"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"workflow",children:"Workflow"}),"\n",(0,s.jsxs)(t.p,{children:["To start, clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm",children:"tutorials-example-wasm"})," repository. Then, open the ",(0,s.jsx)(t.code,{children:"authorization-keys-example"})," directory, prepare your Rust environment, and build the tests with the following commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n"})}),"\n",(0,s.jsx)(t.p,{children:"Review the repository's structure:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client",children:"client"})," - A client folder containing two Wasm files\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"add_keys.wasm"})," - Session code that adds an associated key to the calling account"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call.wasm"})," - Session code that calls the contract's entry point and stores the result into a named key"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract",children:"contract"})," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests",children:"tests"})," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior"]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This tutorial highlights certain lines of code found in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example",children:"GitHub"}),"."]})}),"\n",(0,s.jsx)(t.h3,{id:"the-example-contract",children:"The example contract"}),"\n",(0,s.jsxs)(t.p,{children:["Upon ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75",children:"installation"}),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52",children:"usage"})," of ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," retrieves the set of account hashes representing the keys signing the caller deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys_caller: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n"})}),"\n",(0,s.jsx)(t.h3,{id:"client-wasm-files",children:"Client Wasm files"}),"\n",(0,s.jsx)(t.h4,{id:"add_keyswasm",children:(0,s.jsx)(t.code,{children:"add_keys.wasm"})}),"\n",(0,s.jsxs)(t.p,{children:["This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,s.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,s.jsx)(t.h4,{id:"contract_callwasm",children:(0,s.jsx)(t.code,{children:"contract_call.wasm"})}),"\n",(0,s.jsx)(t.p,{children:"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"}),"\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy)."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The intersection result is a list stored under a named key of the account calling the ",(0,s.jsx)(t.code,{children:"contract_call.wasm"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"testing-this-example",children:"Testing this example"}),"\n",(0,s.jsx)(t.p,{children:"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Testing the contract installation"}),"\n",(0,s.jsx)(t.li,{children:"Testing the contract's unique entry point"}),"\n",(0,s.jsx)(t.li,{children:"Testing the entry point using a client contract call"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"These tests focus on testing the contract installation."}),"\n",(0,s.jsxs)(t.h4,{id:"test-1-should_allow_install_contract_with_default_account",children:["Test 1: ",(0,s.jsx)(t.code,{children:"should_allow_install_contract_with_default_account"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28",children:"test"})," signs the installer deploy with an authorization key ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," can be used to sign the deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-2-should_disallow_install_with_non_added_authorization_key",children:["Test 2: ",(0,s.jsx)(t.code,{children:"should_disallow_install_with_non_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Failed contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57",children:"test"})," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-3-should_allow_install_with_added_authorization_key",children:["Test 3: ",(0,s.jsx)(t.code,{children:"should_allow_install_with_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83",children:"test"})," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,s.jsx)(t.code,{children:"account_addr_1"})," to the default account's associated keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". See ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n"})}),"\n",(0,s.jsx)(t.p,{children:"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."}),"\n",(0,s.jsxs)(t.h4,{id:"test-4-should_allow_entry_point_with_installer_authorization_key",children:["Test 4: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_installer_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_1"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144",children:"test"})," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," signed only with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". This is possible because the deploy action threshold for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," is 1 as you can see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". Thus, the caller deploy is expected to succeed and return a result."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-5-should_allow_entry_point_with_account_authorization_key",children:["Test 5: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_account_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This is the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224",children:"main test"})," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," as an associated key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," and has two authorization keys, ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-6-should_disallow_entry_point_without_authorization_key",children:["Test 6: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_2"})}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304",children:"test"})," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."]}),"\n",(0,s.jsx)(t.p,{children:"The default account hash is used to sign the installer deploy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["In the test, a new account, ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_2"}),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,s.jsx)(t.code,{children:"account_addr_2"}),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The following tests exercise the entry point using a ",(0,s.jsx)(t.a,{href:"#contract_callwasm",children:"contract call"})," and verifying the result returned."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",children:["Test 7: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_through_contract_call_with_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403",children:"test"})," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The caller deploy is signed by ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The test then verifies that the result returned was saved in the named keys for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"}),", containing the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",children:["Test 8: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_through_contract_call_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"})]}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509",children:"final test"})," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"}),") and the installer deploy's authorization keys (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the entry point returns an error."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26a33332.9159dc58.js b/assets/js/26a33332.9159dc58.js deleted file mode 100644 index 5ff2bafc1..000000000 --- a/assets/js/26a33332.9159dc58.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4998],{33219:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var s=n(74848),i=n(28453);const a={title:"Authorization Keys"},r="Working with Authorization Keys",o={id:"resources/advanced/list-auth-keys-tutorial",title:"Authorization Keys",description:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/list-auth-keys-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/advanced/list-auth-keys-tutorial",permalink:"/resources/advanced/list-auth-keys-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Authorization Keys"},sidebar:"tutorials",previous:{title:"Runtime Return Values",permalink:"/resources/tutorials/advanced/return-values-tutorial"},next:{title:"Token Transfers",permalink:"/resources/tutorials/advanced/transfer-token-to-contract"}},l={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Workflow",id:"workflow",level:2},{value:"The example contract",id:"the-example-contract",level:3},{value:"Client Wasm files",id:"client-wasm-files",level:3},{value:"<code>add_keys.wasm</code>",id:"add_keyswasm",level:4},{value:"<code>contract_call.wasm</code>",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: <code>should_allow_install_contract_with_default_account</code>",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: <code>should_disallow_install_with_non_added_authorization_key</code>",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: <code>should_allow_install_with_added_authorization_key</code>",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: <code>should_allow_entry_point_with_installer_authorization_key</code>",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: <code>should_allow_entry_point_with_account_authorization_key</code>",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: <code>should_disallow_entry_point_without_authorization_key</code>",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: <code>should_allow_entry_point_through_contract_call_with_authorization_key</code>",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: <code>should_disallow_entry_point_through_contract_call_without_authorization_key</code>",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-authorization-keys",children:"Working with Authorization Keys"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use."})}),"\n",(0,s.jsxs)(t.p,{children:["This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"list_authorization_keys"})," function."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys = runtime::list_authorization_keys();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember that authorization keys are listed under a Deploy's ",(0,s.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-deploy",children:"approvals"})," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," function. In other words, ",(0,s.jsx)(t.code,{children:"list_authorization_keys"})," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["You meet the ",(0,s.jsx)(t.a,{href:"/developers/prerequisites",children:"development prerequisites"})," and are familiar with ",(0,s.jsx)(t.a,{href:"/writing-contracts",children:"writing and testing on-chain code"})]}),"\n",(0,s.jsxs)(t.li,{children:["You know how to ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-deploys",children:"send and verify deploys"})]}),"\n",(0,s.jsxs)(t.li,{children:["You are familiar with these concepts:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-account",children:"Casper Accounts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-deploy",children:"Deploys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization-standard#associatedkey",children:"Associated Keys"})}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/concepts/serialization-standard#approval",children:"Approvals"}),", also known as authorization keys"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"workflow",children:"Workflow"}),"\n",(0,s.jsxs)(t.p,{children:["To start, clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm",children:"tutorials-example-wasm"})," repository. Then, open the ",(0,s.jsx)(t.code,{children:"authorization-keys-example"})," directory, prepare your Rust environment, and build the tests with the following commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n"})}),"\n",(0,s.jsx)(t.p,{children:"Review the repository's structure:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client",children:"client"})," - A client folder containing two Wasm files\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"add_keys.wasm"})," - Session code that adds an associated key to the calling account"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call.wasm"})," - Session code that calls the contract's entry point and stores the result into a named key"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract",children:"contract"})," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests",children:"tests"})," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior"]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This tutorial highlights certain lines of code found in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example",children:"GitHub"}),"."]})}),"\n",(0,s.jsx)(t.h3,{id:"the-example-contract",children:"The example contract"}),"\n",(0,s.jsxs)(t.p,{children:["Upon ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75",children:"installation"}),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52",children:"usage"})," of ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," retrieves the set of account hashes representing the keys signing the caller deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys_caller: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n"})}),"\n",(0,s.jsx)(t.h3,{id:"client-wasm-files",children:"Client Wasm files"}),"\n",(0,s.jsx)(t.h4,{id:"add_keyswasm",children:(0,s.jsx)(t.code,{children:"add_keys.wasm"})}),"\n",(0,s.jsxs)(t.p,{children:["This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,s.jsx)(t.h4,{id:"contract_callwasm",children:(0,s.jsx)(t.code,{children:"contract_call.wasm"})}),"\n",(0,s.jsx)(t.p,{children:"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"}),"\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy)."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The intersection result is a list stored under a named key of the account calling the ",(0,s.jsx)(t.code,{children:"contract_call.wasm"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"testing-this-example",children:"Testing this example"}),"\n",(0,s.jsx)(t.p,{children:"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Testing the contract installation"}),"\n",(0,s.jsx)(t.li,{children:"Testing the contract's unique entry point"}),"\n",(0,s.jsx)(t.li,{children:"Testing the entry point using a client contract call"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"These tests focus on testing the contract installation."}),"\n",(0,s.jsxs)(t.h4,{id:"test-1-should_allow_install_contract_with_default_account",children:["Test 1: ",(0,s.jsx)(t.code,{children:"should_allow_install_contract_with_default_account"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28",children:"test"})," signs the installer deploy with an authorization key ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," can be used to sign the deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-2-should_disallow_install_with_non_added_authorization_key",children:["Test 2: ",(0,s.jsx)(t.code,{children:"should_disallow_install_with_non_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Failed contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57",children:"test"})," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-3-should_allow_install_with_added_authorization_key",children:["Test 3: ",(0,s.jsx)(t.code,{children:"should_allow_install_with_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83",children:"test"})," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,s.jsx)(t.code,{children:"account_addr_1"})," to the default account's associated keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". See ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n"})}),"\n",(0,s.jsx)(t.p,{children:"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."}),"\n",(0,s.jsxs)(t.h4,{id:"test-4-should_allow_entry_point_with_installer_authorization_key",children:["Test 4: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_installer_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_1"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144",children:"test"})," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," signed only with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". This is possible because the deploy action threshold for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," is 1 as you can see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". Thus, the caller deploy is expected to succeed and return a result."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-5-should_allow_entry_point_with_account_authorization_key",children:["Test 5: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_account_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This is the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224",children:"main test"})," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," as an associated key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," and has two authorization keys, ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-6-should_disallow_entry_point_without_authorization_key",children:["Test 6: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_2"})}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304",children:"test"})," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."]}),"\n",(0,s.jsx)(t.p,{children:"The default account hash is used to sign the installer deploy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["In the test, a new account, ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_2"}),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,s.jsx)(t.code,{children:"account_addr_2"}),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The following tests exercise the entry point using a ",(0,s.jsx)(t.a,{href:"#contract_callwasm",children:"contract call"})," and verifying the result returned."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",children:["Test 7: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_through_contract_call_with_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403",children:"test"})," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The caller deploy is signed by ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The test then verifies that the result returned was saved in the named keys for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"}),", containing the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",children:["Test 8: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_through_contract_call_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"})]}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509",children:"final test"})," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"}),") and the installer deploy's authorization keys (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the entry point returns an error."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26ab9a7a.06a0c1d8.js b/assets/js/26ab9a7a.06a0c1d8.js new file mode 100644 index 000000000..8728cf3e1 --- /dev/null +++ b/assets/js/26ab9a7a.06a0c1d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3568],{93511:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var t=s(74848),i=s(28453);const o={},a="Consensus in a Casper Network",r={id:"concepts/design/consensus",title:"Consensus in a Casper Network",description:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.",source:"@site/versioned_docs/version-2.0.0/concepts/design/consensus.md",sourceDirName:"concepts/design",slug:"/concepts/design/consensus",permalink:"/2.0.0/concepts/design/consensus",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Communication",permalink:"/2.0.0/concepts/design/p2p"},next:{title:"Zug Consensus",permalink:"/2.0.0/concepts/design/zug"}},c={},l=[{value:"Safety, Liveness, and Byzantine Fault Tolerance",id:"safety-liveness-and-byzantine-fault-tolerance",level:2},{value:"Casper Consensus Protocols",id:"casper-consensus-protocols",level:2},{value:"Consensus in the Casper Mainnet",id:"consensus-in-the-casper-mainnet",level:2},{value:"Dynamic Round Length",id:"dynamic-round-length",level:3},{value:"Eras",id:"eras",level:3},{value:"Finality",id:"finality",level:3},{value:"Important Links",id:"important-links",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"consensus-in-a-casper-network",children:"Consensus in a Casper Network"})}),"\n",(0,t.jsx)(n.p,{children:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block."}),"\n",(0,t.jsx)(n.h2,{id:"safety-liveness-and-byzantine-fault-tolerance",children:"Safety, Liveness, and Byzantine Fault Tolerance"}),"\n",(0,t.jsxs)(n.p,{children:["In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The ",(0,t.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle",children:"Transaction Lifecycle"})," describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called ",(0,t.jsx)(n.strong,{children:"safety"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called ",(0,t.jsx)(n.strong,{children:"liveness"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a ",(0,t.jsx)(n.strong,{children:"Byzantine fault"})," and thus secure against malicious activity."]}),"\n",(0,t.jsx)(n.p,{children:"To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Safety"}),": All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Liveness"}),": The network runs indefinitely and adds new blocks to the chain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Byzantine Fault Tolerance (BFT)"}),": All honest nodes eventually agree on the final value, even if some are faulty."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"casper-consensus-protocols",children:"Casper Consensus Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," and ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/highway",children:"Highway"}),". ",(0,t.jsx)(n.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"})," served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper ",(0,t.jsx)(n.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),", which describes how Zug meets the safety, liveness, and resiliency requirements."]}),"\n",(0,t.jsx)(n.h2,{id:"consensus-in-the-casper-mainnet",children:"Consensus in the Casper Mainnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper Mainnet is a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/P#proof-of-stake",children:"Proof-of-Stake"})," network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#node",children:"nodes"}),", which participate in the consensus process by staking CSPR tokens. These active nodes are known as ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validators"}),". The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus."]}),"\n",(0,t.jsxs)(n.p,{children:["The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are ",(0,t.jsx)(n.em,{children:"honest"})," nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model."})}),"\n",(0,t.jsx)(n.h3,{id:"dynamic-round-length",children:"Dynamic Round Length"}),"\n",(0,t.jsx)(n.p,{children:"Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner."}),"\n",(0,t.jsx)(n.h3,{id:"eras",children:"Eras"}),"\n",(0,t.jsx)(n.p,{children:"The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Data Reduction"}),' - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.']}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Banning Equivocators"})," - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Rotating Validators"})," - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (",(0,t.jsx)(n.code,{children:"current era"}),"+ 2)."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (",(0,t.jsx)(n.code,{children:"current era"})," + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain."]}),"\n",(0,t.jsxs)(n.p,{children:["The final block of an era is a ",(0,t.jsx)(n.em,{children:"switch block"})," and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the ",(0,t.jsx)(n.em,{children:"switch block"})," and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/consensus",children:"Consensus Economics"})," page."]}),"\n",(0,t.jsx)(n.h3,{id:"finality",children:"Finality"}),"\n",(0,t.jsx)(n.p,{children:"Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart."}),"\n",(0,t.jsx)(n.p,{children:"On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously."}),"\n",(0,t.jsx)(n.h2,{id:"important-links",children:"Important Links"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/zug",children:"Zug Consensus"})," - An overview of the Zug consensus used in Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/highway",children:"Highway Consensus"})," - Brief overview of the Highway consensus available as an alternative to Zug"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26f7e8fd.759ba063.js b/assets/js/26f7e8fd.759ba063.js deleted file mode 100644 index a49e8331f..000000000 --- a/assets/js/26f7e8fd.759ba063.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4891],{85947:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>h});var t=s(74848),i=s(28453);const a={title:"Network Design"},o="Casper Network Design",c={id:"concepts/design/casper-design",title:"Network Design",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/concepts/design/casper-design.md",sourceDirName:"concepts/design",slug:"/concepts/design/casper-design",permalink:"/concepts/design/casper-design",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Network Design"},sidebar:"concepts",previous:{title:"Design Overview",permalink:"/design"},next:{title:"Network Communication",permalink:"/concepts/design/p2p"}},r={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Execution Semantics",id:"execution-semantics-head",level:2},{value:"Measuring Computational Work",id:"execution-semantics-gas",level:3},{value:"The Casper Network Runtime",id:"execution-semantics-runtime",level:3},{value:"Generating <code>URef</code>s",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for <code>URef</code>s",id:"uref-permissions",level:3},{value:"<code>URef</code>s and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"<code>block_hash</code>",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Accounts",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-network-design",children:"Casper Network Design"})}),"\n",(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#consensus",children:"consensus"}),". A Casper network stores data in a structure known as ",(0,t.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"}),". Users interact with global state through session code sent in a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"}),". Deploys contain ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"Wasm"})," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."]}),"\n",(0,t.jsxs)(n.p,{children:["A deploy executes in the context of the user's ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"Account"})," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(n.code,{children:"URef"}),". After a node accepts a deploy as valid, it places the deploy in a proposed ",(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block"})," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#accounts-head",children:"Accounts"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference (URef)"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block Structure"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#tokens-head",children:"Tokens"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-head",children:"Execution Semantics"}),"\n",(0,t.jsx)(n.p,{children:"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-gas",children:"Measuring Computational Work"}),"\n",(0,t.jsxs)(n.p,{children:["Computation is done in a ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"WebAssembly (Wasm)"})," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,t.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:(0,t.jsx)(n.code,{children:"Gas"})})," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,t.jsx)(n.code,{children:"Gas"})," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."]}),"\n",(0,t.jsxs)(n.p,{children:["Costs for opcode instructions on the Casper Mainnet network can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["All executions are finite because each has a finite ",(0,t.jsx)(n.em,{children:"gas limit"})," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy."]}),"\n",(0,t.jsxs)(n.p,{children:["Although the network measures costs in ",(0,t.jsx)(n.code,{children:"Gas"}),", payment for computation occurs in ",(0,t.jsx)(n.a,{href:"#tokens-divisibility",children:"motes"}),". Therefore, there is a conversion rate between ",(0,t.jsx)(n.code,{children:"Gas"})," and motes."]}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsx)(n.p,{children:"Please note that Casper will not refund any amount of unused gas."}),(0,t.jsxs)(n.p,{children:["This decision is taken to incentivize the ",(0,t.jsx)(n.a,{href:"/runtime",children:"Casper Runtime Economics"})," by efficiently allocating the computational resources. The ",(0,t.jsx)(n.a,{href:"/runtime#consensus-before-execution--basics-of-payment",children:"consensus-before-execution model"})," implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys."]})]}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-runtime",children:"The Casper Network Runtime"}),"\n",(0,t.jsx)(n.p,{children:"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Casper Network Runtime",src:s(65497).A+"",width:"1220",height:"604"})}),"\n",(0,t.jsxs)(n.p,{children:["All these features are accessible via functions in the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"execution-semantics-urefs",children:["Generating ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"URef"}),"s are generated using a ",(0,t.jsx)(n.a,{href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html",children:"cryptographically secure random number generator"})," using the ",(0,t.jsx)(n.a,{href:"https://cr.yp.to/chacha.html",children:"ChaCha algorithm"}),". The random number generator is seeded by taking the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,t.jsx)(n.code,{children:"URef"}),"s generated in different phases of the same deploy)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Generating URefs",src:s(16886).A+"",width:"1121",height:"289"})}),"\n",(0,t.jsx)(n.h2,{id:"accounts-head",children:"Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),". The ",(0,t.jsx)(n.a,{href:"/concepts/global-state#global-state-trie",children:"global state trie store"})," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."]}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#ecdsa-keys",children:"Secp256k1"})," keys, commonly known as Ethereum keys, which are 68 bytes long"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,t.jsx)(n.a,{href:"#tokens-purses-and-accounts",children:"Tokens"})," for more information)."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."}),"\n",(0,t.jsx)(n.h3,{id:"accounts-creating",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["Account creation automatically happens upon transferring tokens to a yet unused ",(0,t.jsx)(n.code,{children:"PublicKey"}),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account Data Structure",src:s(4101).A+"",width:"426",height:"618"})}),"\n",(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"Account"})," contains the following data:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"URef"}),' representing the account\'s "main purse"']}),"\n",(0,t.jsx)(n.li,{children:"A collection of named keys (playing the same role as the named keys in a stored contract)"}),"\n",(0,t.jsxs)(n.li,{children:['A collection of "associated keys" (see ',(0,t.jsx)(n.a,{href:"#accounts-associated-keys-weights",children:"below for more information"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:['"Action thresholds" (see ',(0,t.jsx)(n.a,{href:"#accounts-actions-thresholds",children:"below for more information"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"accounts-permissions",children:"Permissions Model"}),"\n",(0,t.jsx)(n.h4,{id:"accounts-actions-thresholds",children:"Actions and Thresholds"}),"\n",(0,t.jsx)(n.p,{children:"An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ActionThresholds"})," contained in the ",(0,t.jsx)(n.code,{children:"Account"})," data structure set a ",(0,t.jsx)(n.code,{children:"Weight"}),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold."]}),"\n",(0,t.jsx)(n.h4,{id:"accounts-associated-keys-weights",children:"Associated Keys and Weights"}),"\n",(0,t.jsxs)(n.p,{children:["Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's ",(0,t.jsx)(n.em,{children:"associated keys"}),' are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.'})}),"\n",(0,t.jsx)(n.h4,{id:"accounts-key-management",children:"Key Management Actions"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"key management action"})," is a change to the account permissions, including:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Adding or removing an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the weight of an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the threshold of any action"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."}),"\n",(0,t.jsx)(n.h4,{id:"accounts-recovery",children:"Account security and recovery using key management"}),"\n",(0,t.jsx)(n.p,{children:"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").'})}),"\n",(0,t.jsx)(n.h3,{id:"accounts-context",children:"The Account Context"}),"\n",(0,t.jsxs)(n.p,{children:["A deploy is a user request to perform some execution on the blockchain (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"}),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account\'s context.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account."})}),"\n",(0,t.jsx)(n.h2,{id:"uref-head",children:"Unforgeable Reference (URef)"}),"\n",(0,t.jsxs)(n.p,{children:["This key type is used for storing any value except ",(0,t.jsx)(n.code,{children:"Account"}),". Additionally, ",(0,t.jsx)(n.code,{children:"URef"}),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,t.jsx)(n.code,{children:"URef"}),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,t.jsx)(n.code,{children:"URef"})," error. Permissions for a ",(0,t.jsx)(n.code,{children:"URef"})," can be given across contract calls, allowing data stored under a ",(0,t.jsx)(n.code,{children:"URef"})," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})," for more information). The serialization for ",(0,t.jsx)(n.code,{children:"Access Rights"})," that define the permissions for ",(0,t.jsx)(n.code,{children:"URefs"})," is detailed in the ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard",children:"CLValues"})," section."]}),"\n",(0,t.jsxs)(n.h3,{id:"uref-permissions",children:["Permissions for ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:["In the runtime, a ",(0,t.jsx)(n.code,{children:"URef"})," carries its permissions called ",(0,t.jsx)(n.code,{children:"AccessRights"}),". Additionally, the runtime tracks what ",(0,t.jsx)(n.code,{children:"AccessRights"})," would be valid for each ",(0,t.jsx)(n.code,{children:"URef"})," in each context. The system assumes that a sent ",(0,t.jsx)(n.code,{children:"URef"})," is invalid, regardless of declared ",(0,t.jsx)(n.code,{children:"AccessRights"}),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,t.jsx)(n.code,{children:"URef"}),", in the following ways:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['It can exist in a set of "known" ',(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.li,{children:["It can be freshly created by the runtime via the ",(0,t.jsx)(n.code,{children:"new_uref"})," function"]}),"\n",(0,t.jsxs)(n.li,{children:["For called contracts, the caller can pass it in via the arguments to ",(0,t.jsx)(n.code,{children:"call_contract"})]}),"\n",(0,t.jsxs)(n.li,{children:["It can be returned to the caller from ",(0,t.jsx)(n.code,{children:"call_contract"})," via the ",(0,t.jsx)(n.code,{children:"ret"})," function"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that only valid ",(0,t.jsx)(n.code,{children:"URef"}),"s may be added to the known ",(0,t.jsx)(n.code,{children:"URef"}),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,t.jsx)(n.code,{children:"URef"})," by getting it through a contract or stashing it in the known ",(0,t.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,t.jsxs)(n.p,{children:["The ability to pass ",(0,t.jsx)(n.code,{children:"URef"}),"s between contexts via ",(0,t.jsx)(n.code,{children:"call_contract"})," / ",(0,t.jsx)(n.code,{children:"ret"}),", allows them to share state among a fixed number of parties while keeping it private from all others."]}),"\n",(0,t.jsxs)(n.h3,{id:"urefs-and-purses",children:[(0,t.jsx)(n.code,{children:"URef"}),"s and Purses"]}),"\n",(0,t.jsxs)(n.p,{children:["Purses represent a unique type of ",(0,t.jsx)(n.code,{children:"URef"})," used for accounting measures within a Casper network. ",(0,t.jsx)(n.code,{children:"URef"}),"s exist as a top-level entity, meaning that individual accounts do not own \u2018URef\u2019s. As described above, accounts and contracts possess certain ",(0,t.jsx)(n.code,{children:"Access Rights"}),", allowing them to interact with the given ",(0,t.jsx)(n.code,{children:"URef"}),". While an account will possess an associated ",(0,t.jsx)(n.code,{children:"URef"})," representing their main purse, this ",(0,t.jsx)(n.code,{children:"URef"})," exists as a ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#clvalue-unit",children:(0,t.jsx)(n.code,{children:"Unit"})})," and corresponds to a ",(0,t.jsx)(n.em,{children:"balance"})," key within the Casper ",(0,t.jsx)(n.em,{children:"mint"}),". The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated ",(0,t.jsx)(n.code,{children:"URef"})," and the ",(0,t.jsx)(n.code,{children:"Access Rights"})," granted to it."]}),"\n",(0,t.jsx)(n.p,{children:"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required."}),"\n",(0,t.jsx)(n.h2,{id:"block-structure-head",children:"Block Structure"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"block"})," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."]}),"\n",(0,t.jsx)(n.h3,{id:"block-structure-data",children:"Data Fields"}),"\n",(0,t.jsx)(n.p,{children:"A block consists of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"block_hash"})]}),"\n",(0,t.jsx)(n.li,{children:"A header"}),"\n",(0,t.jsx)(n.li,{children:"A body"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Each of these fields is detailed in the subsequent sections."}),"\n",(0,t.jsx)(n.h4,{id:"block_hash",children:(0,t.jsx)(n.code,{children:"block_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"block_hash"})," is the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the block header."]}),"\n",(0,t.jsx)(n.h4,{id:"header",children:"Header"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-block",children:"block header"})," contains the following fields:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"parent_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["A list of ",(0,t.jsx)(n.code,{children:"block_hash"}),"es giving the parents of the block."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"state_root_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The global state root hash produced by executing this block's body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"body_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The hash of the block body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"random_bit"})}),"\n",(0,t.jsx)(n.p,{children:"A boolean needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"accumulated_seed"})}),"\n",(0,t.jsx)(n.p,{children:"A seed needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_end"})}),"\n",(0,t.jsx)(n.p,{children:"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"timestamp"})}),"\n",(0,t.jsx)(n.p,{children:"The timestamp from when the block was proposed."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_id"})}),"\n",(0,t.jsx)(n.p,{children:"Era ID in which this block was created."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"height"})}),"\n",(0,t.jsx)(n.p,{children:"The height of this block, i.e., the number of ancestors."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,t.jsx)(n.p,{children:"The version of the Casper network when this block was proposed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"body",children:"Body"}),"\n",(0,t.jsxs)(n.p,{children:["The block body contains an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of ",(0,t.jsx)(n.code,{children:"DeployHashes"})," which refer to deploys, and an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of ",(0,t.jsx)(n.code,{children:"DeployHashes"})," for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,t.jsx)(n.a,{href:"/concepts/global-state#global-state-intro",children:"Global State"}),". A valid block may contain no deploys and / or native transfers."]}),"\n",(0,t.jsx)(n.p,{children:"The block body also contains the public key of the validator that proposed the block."}),"\n",(0,t.jsxs)(n.p,{children:["Refer to the ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard",children:"Serialization Standard"})," for additional information on how blocks and deploy are serialized."]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-head",children:"Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called ",(0,t.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway"}),". Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,t.jsx)(n.a,{href:"/staking",children:"stake"})," to bond. In the blockchain space, this unit of value is a ",(0,t.jsx)(n.em,{children:"token"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes tokens and how one can use them on the Casper platform."}),"\n",(0,t.jsx)(n.h3,{id:"token-generation-and-distribution",children:"Token Generation and Distribution"}),"\n",(0,t.jsxs)(n.p,{children:["A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,t.jsx)(n.a,{href:"https://api.cspr.live/supply",children:"here"}),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."]}),"\n",(0,t.jsx)(n.p,{children:"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Token Lifecycle",src:s(15168).A+"",width:"1013",height:"656"})}),"\n",(0,t.jsx)(n.h3,{id:"tokens-divisibility",children:"Divisibility of Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Typically, a ",(0,t.jsx)(n.em,{children:"token"})," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,t.jsx)(n.em,{children:"motes"}),". Each CSPR is divisible into 10",(0,t.jsx)(n.sup,{children:"9"})," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,t.jsx)(n.sup,{children:"18"})," parts called Wei."]}),"\n",(0,t.jsxs)(n.p,{children:["The concept of ",(0,t.jsx)(n.code,{children:"CSPR"})," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,t.jsx)(n.em,{children:"motes"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"tokens-purses-and-accounts",children:"Purses and Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["All ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"accounts"})," on the Casper system have a purse associated with the Casper system mint, called the ",(0,t.jsx)(n.em,{children:"main purse"}),". However, for security reasons, the ",(0,t.jsx)(n.code,{children:"URef"})," of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's ",(0,t.jsx)(n.code,{children:"transfer"})," method that accepts ",(0,t.jsx)(n.code,{children:"URef"}),"s is not the most convenient when transferring between account main purses. For this reason, Casper supplies a ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})," function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the ",(0,t.jsx)(n.code,{children:"source"})," and the main purse of the account at the provided key as the ",(0,t.jsx)(n.code,{children:"target"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"mint-contract",children:"The Casper Mint Contract"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.em,{children:"mint"})," is a system contract that manages the balance of ",(0,t.jsx)(n.em,{children:"motes"})," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's ",(0,t.jsx)(n.em,{children:"main purse"}),". Each balance is associated with a ",(0,t.jsx)(n.code,{children:"URef"}),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,t.jsx)(n.em,{children:"purses"})," and conceptually represent a container for motes. The ",(0,t.jsx)(n.code,{children:"URef"})," is how a purse is referenced externally, outside the mint."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"AccessRights"})," of the URefs permissions model determines what actions can be performed when using a ",(0,t.jsx)(n.code,{children:"URef"})," associated with a purse."]}),"\n",(0,t.jsxs)(n.p,{children:["As all ",(0,t.jsx)(n.code,{children:"URef"}),"s are unforgeable, the only way to interact with a purse is for a ",(0,t.jsx)(n.code,{children:"URef"})," with appropriate ",(0,t.jsx)(n.code,{children:"AccessRights"})," to be validly given to the current context."]}),"\n",(0,t.jsx)(n.p,{children:"The basic global state options map onto more standard monetary operations according to the table below:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Global State"}),(0,t.jsx)(n.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Add"}),(0,t.jsx)(n.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Write"}),(0,t.jsx)(n.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Read"}),(0,t.jsx)(n.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-mint-interface",children:"The mint Contract Interface"}),"\n",(0,t.jsx)(n.p,{children:"The mint system contract exposes the following methods:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"source"})," must have at least ",(0,t.jsx)(n.code,{children:"Write"})," access rights, ",(0,t.jsx)(n.code,{children:"target"})," must have at least ",(0,t.jsx)(n.code,{children:"Add"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"TransferResult"})," may be a success acknowledgment or an error in the case of invalid ",(0,t.jsx)(n.code,{children:"source"})," or ",(0,t.jsx)(n.code,{children:"target"})," or insufficient balance in the ",(0,t.jsx)(n.code,{children:"source"})," purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"mint(amount: Motes) -> MintResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MintResult"})," either gives the created ",(0,t.jsx)(n.code,{children:"URef"})," (with full access rights), which now has a balance equal to the given ",(0,t.jsx)(n.code,{children:"amount"}),"; or an error due to the minting of new motes not being allowed"]}),"\n",(0,t.jsxs)(n.li,{children:["In the Casper mint, only the system account can call ",(0,t.jsx)(n.code,{children:"mint"}),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"create() -> URef"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["a convenience function for ",(0,t.jsx)(n.code,{children:"mint(0)"})," which cannot fail because it is always allowed to create an empty purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"balance(purse: URef) -> Option<Motes>"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"purse"})," must have at least ",(0,t.jsx)(n.code,{children:"Read"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"BalanceResult"})," either returns the number of motes held by the ",(0,t.jsx)(n.code,{children:"purse"}),", or nothing if the ",(0,t.jsx)(n.code,{children:"URef"})," is not valid"]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},4101:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-structure-89919dedef5e84cf8168afa72b34ed5f.png"},65497:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},16886:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"},15168:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/token-lifecycle-3b64dfdb785ffc07a0e2df0869520f33.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/26f7e8fd.9da42033.js b/assets/js/26f7e8fd.9da42033.js new file mode 100644 index 000000000..ad71c6fc4 --- /dev/null +++ b/assets/js/26f7e8fd.9da42033.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84891],{85947:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>h});var t=s(74848),i=s(28453);const a={title:"Network Design"},o="Casper Network Design",c={id:"concepts/design/casper-design",title:"Network Design",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/concepts/design/casper-design.md",sourceDirName:"concepts/design",slug:"/concepts/design/casper-design",permalink:"/1.5.X/concepts/design/casper-design",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Network Design"},sidebar:"concepts",previous:{title:"Design Overview",permalink:"/1.5.X/design"},next:{title:"Network Communication",permalink:"/1.5.X/concepts/design/p2p"}},r={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Execution Semantics",id:"execution-semantics-head",level:2},{value:"Measuring Computational Work",id:"execution-semantics-gas",level:3},{value:"The Casper Network Runtime",id:"execution-semantics-runtime",level:3},{value:"Generating <code>URef</code>s",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for <code>URef</code>s",id:"uref-permissions",level:3},{value:"<code>URef</code>s and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"<code>block_hash</code>",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Accounts",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-network-design",children:"Casper Network Design"})}),"\n",(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#consensus",children:"consensus"}),". A Casper network stores data in a structure known as ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Global State"}),". Users interact with global state through session code sent in a ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploy"}),". Deploys contain ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"Wasm"})," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."]}),"\n",(0,t.jsxs)(n.p,{children:["A deploy executes in the context of the user's ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"Account"})," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(n.code,{children:"URef"}),". After a node accepts a deploy as valid, it places the deploy in a proposed ",(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block"})," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#accounts-head",children:"Accounts"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference (URef)"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block Structure"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#tokens-head",children:"Tokens"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-head",children:"Execution Semantics"}),"\n",(0,t.jsx)(n.p,{children:"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-gas",children:"Measuring Computational Work"}),"\n",(0,t.jsxs)(n.p,{children:["Computation is done in a ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"WebAssembly (Wasm)"})," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/economics/gas-concepts",children:(0,t.jsx)(n.code,{children:"Gas"})})," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,t.jsx)(n.code,{children:"Gas"})," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."]}),"\n",(0,t.jsxs)(n.p,{children:["Costs for opcode instructions on the Casper Mainnet network can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["All executions are finite because each has a finite ",(0,t.jsx)(n.em,{children:"gas limit"})," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy."]}),"\n",(0,t.jsxs)(n.p,{children:["Although the network measures costs in ",(0,t.jsx)(n.code,{children:"Gas"}),", payment for computation occurs in ",(0,t.jsx)(n.a,{href:"#tokens-divisibility",children:"motes"}),". Therefore, there is a conversion rate between ",(0,t.jsx)(n.code,{children:"Gas"})," and motes."]}),"\n",(0,t.jsxs)(n.admonition,{type:"note",children:[(0,t.jsx)(n.p,{children:"Please note that Casper will not refund any amount of unused gas."}),(0,t.jsxs)(n.p,{children:["This decision is taken to incentivize the ",(0,t.jsx)(n.a,{href:"/1.5.X/runtime",children:"Casper Runtime Economics"})," by efficiently allocating the computational resources. The ",(0,t.jsx)(n.a,{href:"/1.5.X/runtime#consensus-before-execution--basics-of-payment",children:"consensus-before-execution model"})," implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys."]})]}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-runtime",children:"The Casper Network Runtime"}),"\n",(0,t.jsx)(n.p,{children:"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Casper Network Runtime",src:s(37439).A+"",width:"1220",height:"604"})}),"\n",(0,t.jsxs)(n.p,{children:["All these features are accessible via functions in the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"execution-semantics-urefs",children:["Generating ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"URef"}),"s are generated using a ",(0,t.jsx)(n.a,{href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html",children:"cryptographically secure random number generator"})," using the ",(0,t.jsx)(n.a,{href:"https://cr.yp.to/chacha.html",children:"ChaCha algorithm"}),". The random number generator is seeded by taking the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,t.jsx)(n.code,{children:"URef"}),"s generated in different phases of the same deploy)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Generating URefs",src:s(55688).A+"",width:"1121",height:"289"})}),"\n",(0,t.jsx)(n.h2,{id:"accounts-head",children:"Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),". The ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/global-state#global-state-trie",children:"global state trie store"})," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."]}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys#ecdsa-keys",children:"Secp256k1"})," keys, commonly known as Ethereum keys, which are 68 bytes long"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,t.jsx)(n.a,{href:"#tokens-purses-and-accounts",children:"Tokens"})," for more information)."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."}),"\n",(0,t.jsx)(n.h3,{id:"accounts-creating",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["Account creation automatically happens upon transferring tokens to a yet unused ",(0,t.jsx)(n.code,{children:"PublicKey"}),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account Data Structure",src:s(91235).A+"",width:"426",height:"618"})}),"\n",(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"Account"})," contains the following data:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"URef"}),' representing the account\'s "main purse"']}),"\n",(0,t.jsx)(n.li,{children:"A collection of named keys (playing the same role as the named keys in a stored contract)"}),"\n",(0,t.jsxs)(n.li,{children:['A collection of "associated keys" (see ',(0,t.jsx)(n.a,{href:"#accounts-associated-keys-weights",children:"below for more information"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:['"Action thresholds" (see ',(0,t.jsx)(n.a,{href:"#accounts-actions-thresholds",children:"below for more information"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"accounts-permissions",children:"Permissions Model"}),"\n",(0,t.jsx)(n.h4,{id:"accounts-actions-thresholds",children:"Actions and Thresholds"}),"\n",(0,t.jsx)(n.p,{children:"An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ActionThresholds"})," contained in the ",(0,t.jsx)(n.code,{children:"Account"})," data structure set a ",(0,t.jsx)(n.code,{children:"Weight"}),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold."]}),"\n",(0,t.jsx)(n.h4,{id:"accounts-associated-keys-weights",children:"Associated Keys and Weights"}),"\n",(0,t.jsxs)(n.p,{children:["Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's ",(0,t.jsx)(n.em,{children:"associated keys"}),' are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.'})}),"\n",(0,t.jsx)(n.h4,{id:"accounts-key-management",children:"Key Management Actions"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"key management action"})," is a change to the account permissions, including:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Adding or removing an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the weight of an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the threshold of any action"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."}),"\n",(0,t.jsx)(n.h4,{id:"accounts-recovery",children:"Account security and recovery using key management"}),"\n",(0,t.jsx)(n.p,{children:"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").'})}),"\n",(0,t.jsx)(n.h3,{id:"accounts-context",children:"The Account Context"}),"\n",(0,t.jsxs)(n.p,{children:["A deploy is a user request to perform some execution on the blockchain (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"}),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account\'s context.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account."})}),"\n",(0,t.jsx)(n.h2,{id:"uref-head",children:"Unforgeable Reference (URef)"}),"\n",(0,t.jsxs)(n.p,{children:["This key type is used for storing any value except ",(0,t.jsx)(n.code,{children:"Account"}),". Additionally, ",(0,t.jsx)(n.code,{children:"URef"}),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,t.jsx)(n.code,{children:"URef"}),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,t.jsx)(n.code,{children:"URef"})," error. Permissions for a ",(0,t.jsx)(n.code,{children:"URef"})," can be given across contract calls, allowing data stored under a ",(0,t.jsx)(n.code,{children:"URef"})," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})," for more information). The serialization for ",(0,t.jsx)(n.code,{children:"Access Rights"})," that define the permissions for ",(0,t.jsx)(n.code,{children:"URefs"})," is detailed in the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"CLValues"})," section."]}),"\n",(0,t.jsxs)(n.h3,{id:"uref-permissions",children:["Permissions for ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:["In the runtime, a ",(0,t.jsx)(n.code,{children:"URef"})," carries its permissions called ",(0,t.jsx)(n.code,{children:"AccessRights"}),". Additionally, the runtime tracks what ",(0,t.jsx)(n.code,{children:"AccessRights"})," would be valid for each ",(0,t.jsx)(n.code,{children:"URef"})," in each context. The system assumes that a sent ",(0,t.jsx)(n.code,{children:"URef"})," is invalid, regardless of declared ",(0,t.jsx)(n.code,{children:"AccessRights"}),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,t.jsx)(n.code,{children:"URef"}),", in the following ways:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['It can exist in a set of "known" ',(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.li,{children:["It can be freshly created by the runtime via the ",(0,t.jsx)(n.code,{children:"new_uref"})," function"]}),"\n",(0,t.jsxs)(n.li,{children:["For called contracts, the caller can pass it in via the arguments to ",(0,t.jsx)(n.code,{children:"call_contract"})]}),"\n",(0,t.jsxs)(n.li,{children:["It can be returned to the caller from ",(0,t.jsx)(n.code,{children:"call_contract"})," via the ",(0,t.jsx)(n.code,{children:"ret"})," function"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that only valid ",(0,t.jsx)(n.code,{children:"URef"}),"s may be added to the known ",(0,t.jsx)(n.code,{children:"URef"}),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,t.jsx)(n.code,{children:"URef"})," by getting it through a contract or stashing it in the known ",(0,t.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,t.jsxs)(n.p,{children:["The ability to pass ",(0,t.jsx)(n.code,{children:"URef"}),"s between contexts via ",(0,t.jsx)(n.code,{children:"call_contract"})," / ",(0,t.jsx)(n.code,{children:"ret"}),", allows them to share state among a fixed number of parties while keeping it private from all others."]}),"\n",(0,t.jsxs)(n.h3,{id:"urefs-and-purses",children:[(0,t.jsx)(n.code,{children:"URef"}),"s and Purses"]}),"\n",(0,t.jsxs)(n.p,{children:["Purses represent a unique type of ",(0,t.jsx)(n.code,{children:"URef"})," used for accounting measures within a Casper network. ",(0,t.jsx)(n.code,{children:"URef"}),"s exist as a top-level entity, meaning that individual accounts do not own \u2018URef\u2019s. As described above, accounts and contracts possess certain ",(0,t.jsx)(n.code,{children:"Access Rights"}),", allowing them to interact with the given ",(0,t.jsx)(n.code,{children:"URef"}),". While an account will possess an associated ",(0,t.jsx)(n.code,{children:"URef"})," representing their main purse, this ",(0,t.jsx)(n.code,{children:"URef"})," exists as a ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#clvalue-unit",children:(0,t.jsx)(n.code,{children:"Unit"})})," and corresponds to a ",(0,t.jsx)(n.em,{children:"balance"})," key within the Casper ",(0,t.jsx)(n.em,{children:"mint"}),". The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated ",(0,t.jsx)(n.code,{children:"URef"})," and the ",(0,t.jsx)(n.code,{children:"Access Rights"})," granted to it."]}),"\n",(0,t.jsx)(n.p,{children:"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required."}),"\n",(0,t.jsx)(n.h2,{id:"block-structure-head",children:"Block Structure"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"block"})," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."]}),"\n",(0,t.jsx)(n.h3,{id:"block-structure-data",children:"Data Fields"}),"\n",(0,t.jsx)(n.p,{children:"A block consists of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"block_hash"})]}),"\n",(0,t.jsx)(n.li,{children:"A header"}),"\n",(0,t.jsx)(n.li,{children:"A body"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Each of these fields is detailed in the subsequent sections."}),"\n",(0,t.jsx)(n.h4,{id:"block_hash",children:(0,t.jsx)(n.code,{children:"block_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"block_hash"})," is the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the block header."]}),"\n",(0,t.jsx)(n.h4,{id:"header",children:"Header"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-block",children:"block header"})," contains the following fields:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"parent_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["A list of ",(0,t.jsx)(n.code,{children:"block_hash"}),"es giving the parents of the block."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"state_root_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The global state root hash produced by executing this block's body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"body_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The hash of the block body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"random_bit"})}),"\n",(0,t.jsx)(n.p,{children:"A boolean needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"accumulated_seed"})}),"\n",(0,t.jsx)(n.p,{children:"A seed needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_end"})}),"\n",(0,t.jsx)(n.p,{children:"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"timestamp"})}),"\n",(0,t.jsx)(n.p,{children:"The timestamp from when the block was proposed."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_id"})}),"\n",(0,t.jsx)(n.p,{children:"Era ID in which this block was created."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"height"})}),"\n",(0,t.jsx)(n.p,{children:"The height of this block, i.e., the number of ancestors."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,t.jsx)(n.p,{children:"The version of the Casper network when this block was proposed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"body",children:"Body"}),"\n",(0,t.jsxs)(n.p,{children:["The block body contains an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of ",(0,t.jsx)(n.code,{children:"DeployHashes"})," which refer to deploys, and an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of ",(0,t.jsx)(n.code,{children:"DeployHashes"})," for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/global-state#global-state-intro",children:"Global State"}),". A valid block may contain no deploys and / or native transfers."]}),"\n",(0,t.jsx)(n.p,{children:"The block body also contains the public key of the validator that proposed the block."}),"\n",(0,t.jsxs)(n.p,{children:["Refer to the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization Standard"})," for additional information on how blocks and deploy are serialized."]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-head",children:"Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/highway",children:"Highway"}),". Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,t.jsx)(n.a,{href:"/1.5.X/staking",children:"stake"})," to bond. In the blockchain space, this unit of value is a ",(0,t.jsx)(n.em,{children:"token"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes tokens and how one can use them on the Casper platform."}),"\n",(0,t.jsx)(n.h3,{id:"token-generation-and-distribution",children:"Token Generation and Distribution"}),"\n",(0,t.jsxs)(n.p,{children:["A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,t.jsx)(n.a,{href:"https://api.cspr.live/supply",children:"here"}),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."]}),"\n",(0,t.jsx)(n.p,{children:"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Token Lifecycle",src:s(19910).A+"",width:"1013",height:"656"})}),"\n",(0,t.jsx)(n.h3,{id:"tokens-divisibility",children:"Divisibility of Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Typically, a ",(0,t.jsx)(n.em,{children:"token"})," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,t.jsx)(n.em,{children:"motes"}),". Each CSPR is divisible into 10",(0,t.jsx)(n.sup,{children:"9"})," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,t.jsx)(n.sup,{children:"18"})," parts called Wei."]}),"\n",(0,t.jsxs)(n.p,{children:["The concept of ",(0,t.jsx)(n.code,{children:"CSPR"})," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,t.jsx)(n.em,{children:"motes"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"tokens-purses-and-accounts",children:"Purses and Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["All ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"accounts"})," on the Casper system have a purse associated with the Casper system mint, called the ",(0,t.jsx)(n.em,{children:"main purse"}),". However, for security reasons, the ",(0,t.jsx)(n.code,{children:"URef"})," of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's ",(0,t.jsx)(n.code,{children:"transfer"})," method that accepts ",(0,t.jsx)(n.code,{children:"URef"}),"s is not the most convenient when transferring between account main purses. For this reason, Casper supplies a ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})," function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the ",(0,t.jsx)(n.code,{children:"source"})," and the main purse of the account at the provided key as the ",(0,t.jsx)(n.code,{children:"target"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"mint-contract",children:"The Casper Mint Contract"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.em,{children:"mint"})," is a system contract that manages the balance of ",(0,t.jsx)(n.em,{children:"motes"})," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's ",(0,t.jsx)(n.em,{children:"main purse"}),". Each balance is associated with a ",(0,t.jsx)(n.code,{children:"URef"}),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,t.jsx)(n.em,{children:"purses"})," and conceptually represent a container for motes. The ",(0,t.jsx)(n.code,{children:"URef"})," is how a purse is referenced externally, outside the mint."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"AccessRights"})," of the URefs permissions model determines what actions can be performed when using a ",(0,t.jsx)(n.code,{children:"URef"})," associated with a purse."]}),"\n",(0,t.jsxs)(n.p,{children:["As all ",(0,t.jsx)(n.code,{children:"URef"}),"s are unforgeable, the only way to interact with a purse is for a ",(0,t.jsx)(n.code,{children:"URef"})," with appropriate ",(0,t.jsx)(n.code,{children:"AccessRights"})," to be validly given to the current context."]}),"\n",(0,t.jsx)(n.p,{children:"The basic global state options map onto more standard monetary operations according to the table below:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Global State"}),(0,t.jsx)(n.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Add"}),(0,t.jsx)(n.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Write"}),(0,t.jsx)(n.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Read"}),(0,t.jsx)(n.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-mint-interface",children:"The mint Contract Interface"}),"\n",(0,t.jsx)(n.p,{children:"The mint system contract exposes the following methods:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"source"})," must have at least ",(0,t.jsx)(n.code,{children:"Write"})," access rights, ",(0,t.jsx)(n.code,{children:"target"})," must have at least ",(0,t.jsx)(n.code,{children:"Add"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"TransferResult"})," may be a success acknowledgment or an error in the case of invalid ",(0,t.jsx)(n.code,{children:"source"})," or ",(0,t.jsx)(n.code,{children:"target"})," or insufficient balance in the ",(0,t.jsx)(n.code,{children:"source"})," purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"mint(amount: Motes) -> MintResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MintResult"})," either gives the created ",(0,t.jsx)(n.code,{children:"URef"})," (with full access rights), which now has a balance equal to the given ",(0,t.jsx)(n.code,{children:"amount"}),"; or an error due to the minting of new motes not being allowed"]}),"\n",(0,t.jsxs)(n.li,{children:["In the Casper mint, only the system account can call ",(0,t.jsx)(n.code,{children:"mint"}),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"create() -> URef"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["a convenience function for ",(0,t.jsx)(n.code,{children:"mint(0)"})," which cannot fail because it is always allowed to create an empty purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"balance(purse: URef) -> Option<Motes>"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"purse"})," must have at least ",(0,t.jsx)(n.code,{children:"Read"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"BalanceResult"})," either returns the number of motes held by the ",(0,t.jsx)(n.code,{children:"purse"}),", or nothing if the ",(0,t.jsx)(n.code,{children:"URef"})," is not valid"]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},91235:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-structure-89919dedef5e84cf8168afa72b34ed5f.png"},37439:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},55688:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"},19910:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/token-lifecycle-3b64dfdb785ffc07a0e2df0869520f33.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/277b6be0.0f968348.js b/assets/js/277b6be0.0f968348.js new file mode 100644 index 000000000..586a1de1d --- /dev/null +++ b/assets/js/277b6be0.0f968348.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24054],{96738:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=i(74848),t=i(28453);const r={title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},o="Validator rewards with Casper 2.0",s={permalink:"/blog/condor-validator-rewards",source:"@site/blog/2024-08-20-validator-rewards.md",title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",date:"2024-08-20T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!1,label:"Validators",permalink:"/blog/tags/validators",description:"Validators"}],readingTime:6.96,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"},{name:"Alexander Limonov",page:{permalink:"/blog/authors/alexanderlimonov"},title:"Economist for Casper Labs",url:"https://github.com/AlexanderLimonov",permalink:"/alexanderlimonov",imageURL:"https://github.com/AlexanderLimonov.png",key:"alexanderlimonov"}],frontMatter:{title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"}},l={authorsImageUrls:[void 0,void 0]},d=[{value:"Economics of consensus",id:"economics-of-consensus",level:2},{value:"Casper 1.X Highway-specific incentives",id:"casper-1x-highway-specific-incentives",level:2},{value:"Casper 2.0",id:"casper-20",level:2},{value:"Public knowledge of finality",id:"public-knowledge-of-finality",level:3},{value:"Design",id:"design",level:3},{value:"Expected rewards & volatility",id:"expected-rewards--volatility",level:4},{value:"Rewards formula",id:"rewards-formula",level:4},{value:"Notes on implementation",id:"notes-on-implementation",level:4},{value:"Impact on validator revenue",id:"impact-on-validator-revenue",level:3}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"In this post we discuss the changes to validator rewards in Casper v2.0."}),"\n",(0,a.jsx)(n.h2,{id:"economics-of-consensus",children:"Economics of consensus"}),"\n",(0,a.jsx)(n.p,{children:"Proof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally."}),"\n",(0,a.jsx)(n.p,{children:"Proof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress."}),"\n",(0,a.jsx)(n.p,{children:"Incentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain."}),"\n",(0,a.jsx)(n.h2,{id:"casper-1x-highway-specific-incentives",children:"Casper 1.X Highway-specific incentives"}),"\n",(0,a.jsx)(n.p,{children:"The 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round."}),"\n",(0,a.jsx)(n.p,{children:"Degrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others."}),"\n",(0,a.jsx)(n.p,{children:"The weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality."}),"\n",(0,a.jsx)(n.h2,{id:"casper-20",children:"Casper 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"public-knowledge-of-finality",children:"Public knowledge of finality"}),"\n",(0,a.jsx)(n.p,{children:"A necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators."}),"\n",(0,a.jsx)(n.p,{children:"This mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators' knowledge of the canonical history be attested publicly."}),"\n",(0,a.jsx)(n.p,{children:"In Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one's own and other validators' finality signatures."}),"\n",(0,a.jsx)(n.h3,{id:"design",children:"Design"}),"\n",(0,a.jsx)(n.p,{children:"Rewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Block proposal"}),"\n",(0,a.jsx)(n.li,{children:"Signature creation"}),"\n",(0,a.jsx)(n.li,{children:"Signature publication"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Note that we expect very little, if any, rewards to be allocated for block proposals on mainnet, but the feature remains available."}),"\n",(0,a.jsx)(n.p,{children:'The rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era\'s end multiplied by an inflation factor derived from the chainspec. "Nominal" here means that all rounds result in a finalized block and that all finality signatures are collected and published.'}),"\n",(0,a.jsx)(n.p,{children:"The rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication."}),"\n",(0,a.jsx)(n.p,{children:"Note that this split ensures that validators' incentives are aligned, in the sense that other validators' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators' signature, and because each validator benefits from other publishing its own signatures."}),"\n",(0,a.jsx)(n.h4,{id:"expected-rewards--volatility",children:"Expected rewards & volatility"}),"\n",(0,a.jsx)(n.p,{children:"Under nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable."}),"\n",(0,a.jsx)(n.p,{children:"In the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility."}),"\n",(0,a.jsx)(n.h4,{id:"rewards-formula",children:"Rewards formula"}),"\n",(0,a.jsx)(n.p,{children:"The rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section."}),"\n",(0,a.jsx)(n.p,{children:"Let us define some notation first"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"N"})," - expected number of blocks in an era"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"N"}),"* - the ",(0,a.jsx)(n.em,{children:"set"})," of observed blocks in an era"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"R"})," - total potential reward pot for the era (i.e., nominal inflation based on chainspec and current supply)"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"r"})," - fraction of reward pot dedicated to block production rewards"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"f"})," - finder's fee for finality signatures"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"I"})," - validator index set"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"i"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> {0,1} - indicator function for blocks produced by validator i (with abuse of notation)"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"w"}),": ",(0,a.jsx)(n.strong,{children:"I"})," -> [0,1] - validator's weight"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"W"})," - total weight of the validator set"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"S"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> ",(0,a.jsx)(n.strong,{children:"P(I)"})," - set of validators associated with finality signatures for a particular observed block"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"s_i"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> {0,1} - indicator functions for existence of finality signatures associated with validator i for particular observed blocks"]}),"\n",(0,a.jsx)(n.p,{children:"Now, we can use our defined symbols to concisely describe era rewards for a particular validator"}),"\n",(0,a.jsx)(n.p,{children:"Era rewards for validator i ="}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"i(n)"})," * (",(0,a.jsx)(n.strong,{children:"rR/N"}),") (block production)"]}),"\n",(0,a.jsxs)(n.p,{children:["+ ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"i(n)"})," * ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (j in ",(0,a.jsx)(n.strong,{children:"S(n)"}),") (",(0,a.jsx)(n.strong,{children:"w(j)/W"}),") * (",(0,a.jsx)(n.strong,{children:"f(1-r)R/N"}),") (finality signature publication)"]}),"\n",(0,a.jsxs)(n.p,{children:["+ ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"s_i(n)"})," * (",(0,a.jsx)(n.strong,{children:"w(i)/W"}),") * (",(0,a.jsx)(n.strong,{children:"(1-f)(1-r)R/N"}),") (finality signature contribution)"]}),"\n",(0,a.jsx)(n.p,{children:"The meanings of the three additive components in the formula above are, in order"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding blocks not proposed by this validator\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each block, add the per-block reward allocation for block proposals from the total pot for the era"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding blocks not proposed by this validator\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["For each block, sum over published signatures\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each signature, add the per-block reward allocation for signature publication from the total pot for the era, weighing each signature by its creator's proportion of total validator weight"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding those for which this validator did not create a signature\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each block, add the per-block reward allocation for signature creation from the total pot for the era, weighing it by the validator's proportion of total validator weight"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"notes-on-implementation",children:"Notes on implementation"}),"\n",(0,a.jsx)(n.p,{children:"In a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block."}),"\n",(0,a.jsx)(n.p,{children:"We solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards."}),"\n",(0,a.jsx)(n.p,{children:"However, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created."}),"\n",(0,a.jsx)(n.h3,{id:"impact-on-validator-revenue",children:"Impact on validator revenue"}),"\n",(0,a.jsx)(n.p,{children:"No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>s});var a=i(96540);const t={},r=a.createContext(t);function o(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/277b6be0.6924c872.js b/assets/js/277b6be0.6924c872.js deleted file mode 100644 index 81cbbbd1a..000000000 --- a/assets/js/277b6be0.6924c872.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4054],{96738:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=i(74848),t=i(28453);const r={title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},o="Validator rewards with Casper 2.0",s={permalink:"/blog/condor-validator-rewards",source:"@site/blog/2024-08-20-validator-rewards.md",title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",date:"2024-08-20T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"validators",permalink:"/blog/tags/validators"}],readingTime:6.96,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"},{name:"Alexander Limonov",page:{permalink:"/blog/authors/alexanderlimonov"},title:"Economist for Casper Labs",url:"https://github.com/AlexanderLimonov",permalink:"/alexanderlimonov",imageURL:"https://github.com/AlexanderLimonov.png",key:"alexanderlimonov"}],frontMatter:{title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"}},l={authorsImageUrls:[void 0,void 0]},d=[{value:"Economics of consensus",id:"economics-of-consensus",level:2},{value:"Casper 1.X Highway-specific incentives",id:"casper-1x-highway-specific-incentives",level:2},{value:"Casper 2.0",id:"casper-20",level:2},{value:"Public knowledge of finality",id:"public-knowledge-of-finality",level:3},{value:"Design",id:"design",level:3},{value:"Expected rewards & volatility",id:"expected-rewards--volatility",level:4},{value:"Rewards formula",id:"rewards-formula",level:4},{value:"Notes on implementation",id:"notes-on-implementation",level:4},{value:"Impact on validator revenue",id:"impact-on-validator-revenue",level:3}];function c(e){const n={em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.p,{children:"In this post we discuss the changes to validator rewards in Casper v2.0."}),"\n",(0,a.jsx)(n.h2,{id:"economics-of-consensus",children:"Economics of consensus"}),"\n",(0,a.jsx)(n.p,{children:"Proof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally."}),"\n",(0,a.jsx)(n.p,{children:"Proof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress."}),"\n",(0,a.jsx)(n.p,{children:"Incentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain."}),"\n",(0,a.jsx)(n.h2,{id:"casper-1x-highway-specific-incentives",children:"Casper 1.X Highway-specific incentives"}),"\n",(0,a.jsx)(n.p,{children:"The 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round."}),"\n",(0,a.jsx)(n.p,{children:"Degrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others."}),"\n",(0,a.jsx)(n.p,{children:"The weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality."}),"\n",(0,a.jsx)(n.h2,{id:"casper-20",children:"Casper 2.0"}),"\n",(0,a.jsx)(n.h3,{id:"public-knowledge-of-finality",children:"Public knowledge of finality"}),"\n",(0,a.jsx)(n.p,{children:"A necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators."}),"\n",(0,a.jsx)(n.p,{children:"This mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators' knowledge of the canonical history be attested publicly."}),"\n",(0,a.jsx)(n.p,{children:"In Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one's own and other validators' finality signatures."}),"\n",(0,a.jsx)(n.h3,{id:"design",children:"Design"}),"\n",(0,a.jsx)(n.p,{children:"Rewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Block proposal"}),"\n",(0,a.jsx)(n.li,{children:"Signature creation"}),"\n",(0,a.jsx)(n.li,{children:"Signature publication"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Note that we expect very little, if any, rewards to be allocated for block proposals on mainnet, but the feature remains available."}),"\n",(0,a.jsx)(n.p,{children:'The rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era\'s end multiplied by an inflation factor derived from the chainspec. "Nominal" here means that all rounds result in a finalized block and that all finality signatures are collected and published.'}),"\n",(0,a.jsx)(n.p,{children:"The rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication."}),"\n",(0,a.jsx)(n.p,{children:"Note that this split ensures that validators' incentives are aligned, in the sense that other validators' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators' signature, and because each validator benefits from other publishing its own signatures."}),"\n",(0,a.jsx)(n.h4,{id:"expected-rewards--volatility",children:"Expected rewards & volatility"}),"\n",(0,a.jsx)(n.p,{children:"Under nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable."}),"\n",(0,a.jsx)(n.p,{children:"In the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility."}),"\n",(0,a.jsx)(n.h4,{id:"rewards-formula",children:"Rewards formula"}),"\n",(0,a.jsx)(n.p,{children:"The rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section."}),"\n",(0,a.jsx)(n.p,{children:"Let us define some notation first"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"N"})," - expected number of blocks in an era"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"N"}),"* - the ",(0,a.jsx)(n.em,{children:"set"})," of observed blocks in an era"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"R"})," - total potential reward pot for the era (i.e., nominal inflation based on chainspec and current supply)"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"r"})," - fraction of reward pot dedicated to block production rewards"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"f"})," - finder's fee for finality signatures"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"I"})," - validator index set"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"i"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> {0,1} - indicator function for blocks produced by validator i (with abuse of notation)"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"w"}),": ",(0,a.jsx)(n.strong,{children:"I"})," -> [0,1] - validator's weight"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"W"})," - total weight of the validator set"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"S"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> ",(0,a.jsx)(n.strong,{children:"P(I)"})," - set of validators associated with finality signatures for a particular observed block"]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"s_i"}),": ",(0,a.jsx)(n.strong,{children:"N"}),"* -> {0,1} - indicator functions for existence of finality signatures associated with validator i for particular observed blocks"]}),"\n",(0,a.jsx)(n.p,{children:"Now, we can use our defined symbols to concisely describe era rewards for a particular validator"}),"\n",(0,a.jsx)(n.p,{children:"Era rewards for validator i ="}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"i(n)"})," * (",(0,a.jsx)(n.strong,{children:"rR/N"}),") (block production)"]}),"\n",(0,a.jsxs)(n.p,{children:["+ ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"i(n)"})," * ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (j in ",(0,a.jsx)(n.strong,{children:"S(n)"}),") (",(0,a.jsx)(n.strong,{children:"w(j)/W"}),") * (",(0,a.jsx)(n.strong,{children:"f(1-r)R/N"}),") (finality signature publication)"]}),"\n",(0,a.jsxs)(n.p,{children:["+ ",(0,a.jsx)(n.strong,{children:"\u03a3"})," (n in ",(0,a.jsx)(n.strong,{children:"N"}),"*) ",(0,a.jsx)(n.strong,{children:"s_i(n)"})," * (",(0,a.jsx)(n.strong,{children:"w(i)/W"}),") * (",(0,a.jsx)(n.strong,{children:"(1-f)(1-r)R/N"}),") (finality signature contribution)"]}),"\n",(0,a.jsx)(n.p,{children:"The meanings of the three additive components in the formula above are, in order"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding blocks not proposed by this validator\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each block, add the per-block reward allocation for block proposals from the total pot for the era"}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding blocks not proposed by this validator\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["For each block, sum over published signatures\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each signature, add the per-block reward allocation for signature publication from the total pot for the era, weighing each signature by its creator's proportion of total validator weight"}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["Sum over blocks, discarding those for which this validator did not create a signature\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"For each block, add the per-block reward allocation for signature creation from the total pot for the era, weighing it by the validator's proportion of total validator weight"}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"notes-on-implementation",children:"Notes on implementation"}),"\n",(0,a.jsx)(n.p,{children:"In a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block."}),"\n",(0,a.jsx)(n.p,{children:"We solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards."}),"\n",(0,a.jsx)(n.p,{children:"However, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created."}),"\n",(0,a.jsx)(n.h3,{id:"impact-on-validator-revenue",children:"Impact on validator revenue"}),"\n",(0,a.jsx)(n.p,{children:"No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>s});var a=i(96540);const t={},r=a.createContext(t);function o(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/280f0f40.42bc3e47.js b/assets/js/280f0f40.42bc3e47.js new file mode 100644 index 000000000..c1f1b7c79 --- /dev/null +++ b/assets/js/280f0f40.42bc3e47.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[42081],{237:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Block Explorers"},i="Block Explorers",a={id:"users/block-explorer",title:"Block Explorers",description:"The Casper blockchain is available as the Mainnet and Testnet.",source:"@site/versioned_docs/version-2.0.0/users/block-explorer.md",sourceDirName:"users",slug:"/users/block-explorer",permalink:"/2.0.0/users/block-explorer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Block Explorers"},sidebar:"users",previous:{title:"Users Overview",permalink:"/2.0.0/users/"},next:{title:"Funding Mainnet Accounts",permalink:"/2.0.0/users/funding-from-exchanges"}},l={},c=[{value:"What is a Block Explorer",id:"what-is-a-block-explorer",level:2},{value:"Using a Block Explorer",id:"using-a-block-explorer",level:2}];function h(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"block-explorers",children:"Block Explorers"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper blockchain is available as the Mainnet and Testnet.\nThe Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR).\nThe Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet."}),"\n",(0,t.jsx)(n.p,{children:"You can use block explorers to explore the Casper blockchain such as :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"what-is-a-block-explorer",children:"What is a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history."}),"\n",(0,t.jsx)(n.h2,{id:"using-a-block-explorer",children:"Using a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator."}),"\n",(0,t.jsxs)(n.p,{children:["The following topics link you to detailed instructions on using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to access and work with your CSPR tokens."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn how to access your Casper account using the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the process of ",(0,t.jsx)(n.a,{href:"/2.0.0/users/token-transfer",children:"Transferring Tokens using a Block Explorer"})]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the concepts and the process of ",(0,t.jsx)(n.a,{href:"/2.0.0/users/delegate-ui",children:"Delegating"})," and ",(0,t.jsx)(n.a,{href:"/2.0.0/users/undelegate-ui",children:"Undelegating"})," CSPR tokens"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["To perform actions using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, you must sign in to your Casper account using one of the wallets provided."]})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/285c66e7.2cc1f187.js b/assets/js/285c66e7.2cc1f187.js new file mode 100644 index 000000000..cf5e69d47 --- /dev/null +++ b/assets/js/285c66e7.2cc1f187.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[71049],{4110:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var r=t(74848),s=t(28453);const i={title:"Interacting with the Blockchain"},c="Using the Casper CLI Client",l={id:"developers/cli/index",title:"Interacting with the Blockchain",description:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.",source:"@site/versioned_docs/version-2.0.0/developers/cli/index.md",sourceDirName:"developers/cli",slug:"/developers/cli/",permalink:"/2.0.0/developers/cli/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Interacting with the Blockchain"},sidebar:"developers",previous:{title:"Monitoring Events with the Casper Sidecar",permalink:"/2.0.0/developers/dapps/monitor-and-consume-events"},next:{title:"Transferring Tokens",permalink:"/2.0.0/developers/cli/transfers/"}},o={},a=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-the-casper-cli-client",children:"Using the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/",children:"Transferring Tokens"})}),(0,r.jsx)(n.td,{children:"Transferring tokens from one account to another using the Casper command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"Delegating tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/undelegate",children:"Undelegating Tokens with the Casper Client"})}),(0,r.jsx)(n.td,{children:"Undelegating tokens from a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending Deploys to a Network"})}),(0,r.jsx)(n.td,{children:"Sending Deploys to a Casper network using the Rust CLI Client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to install a contract on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/verifying-contracts",children:"Verifying contracts using the Casper Client"})}),(0,r.jsx)(n.td,{children:"How to use Smart Contract Verification Service"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/querying-global-state",children:"Querying Global State"})}),(0,r.jsx)(n.td,{children:"How to query global state after contract installation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Various ways to call a contract's entry-points"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Error codes for smart contract execution"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>l});var r=t(96540);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28b5b925.0168630d.js b/assets/js/28b5b925.0cbd1f9b.js similarity index 57% rename from assets/js/28b5b925.0168630d.js rename to assets/js/28b5b925.0cbd1f9b.js index f623d02c7..bc8af5fa0 100644 --- a/assets/js/28b5b925.0168630d.js +++ b/assets/js/28b5b925.0cbd1f9b.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1818],{95038:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),a=t(28453);const r={title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},c="Casper Fungible Token Tutorial",o={id:"resources/tokens/cep18/full-tutorial",title:"Fungible Token Workflow",description:"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.",source:"@site/docs/resources/tokens/cep18/full-tutorial.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/full-tutorial",permalink:"/next/resources/tokens/cep18/full-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724330007e3,frontMatter:{title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},sidebar:"resources",previous:{title:"Casper Token Standards",permalink:"/next/resources/tokens/"},next:{title:"On-chain Installation",permalink:"/next/resources/tokens/cep18/quickstart-guide"}},i={},l=[{value:"Preparation",id:"preparation",level:2},{value:"Contract Implementation",id:"contract-implementation",level:2},{value:"Installing Required Crates",id:"installing-crates",level:3},{value:"Initializing the Contract",id:"initializing-the-contract",level:3},{value:"Contract Methods",id:"contract-methods",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Deploy Prerequisites",id:"deploy-prerequisites",level:3},{value:"Basic Flow",id:"basic-flow",level:3},{value:"Cloning the Token Contract",id:"cloning-the-token-contract",level:3},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address",level:3},{value:"Viewing the Network Status",id:"viewing-network-status",level:3},{value:"Installing the Contract",id:"deploying-the-contract",level:3},{value:"Querying the Network Status",id:"querying-the-network-status",level:3},{value:"Verifying the Deploy",id:"verifying-the-deploy",level:3},{value:"Querying with Arguments",id:"querying-with-arguments",level:3},{value:"Example Deploy on Testnet",id:"sample-deploy-testnet",level:3},{value:"Cloning the Fungible Token Contract",id:"cloning-the-fungible-token-contract",level:4},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address-from-a-testnet-peer",level:3},{value:"Viewing the Network Status",id:"viewing-the-network-status",level:4},{value:"Sending the Deploy",id:"sending-the-deploy",level:4},{value:"Viewing the Deploy Details",id:"viewing-the-deploy-details",level:4},{value:"Querying Contract Entry Points",id:"querying-contract-entry-points",level:4}];function d(e){const n={a:"a",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-fungible-token-tutorial",children:"Casper Fungible Token Tutorial"})}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper Fungible Token standard is the Casper Platform's ERC-20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed."}),"\n",(0,s.jsxs)(n.p,{children:["The following functions implement the rules defined by Casper Fungible Tokens: ",(0,s.jsx)(n.code,{children:"totalSupply"}),", ",(0,s.jsx)(n.code,{children:"transfer"}),", ",(0,s.jsx)(n.code,{children:"transferFrom"}),", ",(0,s.jsx)(n.code,{children:"approve"}),", ",(0,s.jsx)(n.code,{children:"balanceOf"}),", and ",(0,s.jsx)(n.code,{children:"allowance"}),". A portion of this tutorial reviews the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract"})," and the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_fungible_token"})," library."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read first."]}),"\n",(0,s.jsx)(n.h2,{id:"preparation",children:"Preparation"}),"\n",(0,s.jsx)(n.p,{children:"First clone the contract from GitHub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18 && cd cep18\n"})}),"\n",(0,s.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,s.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Next, compile your contract and run the contract unit tests."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make build-contract\nmake test\n"})}),"\n",(0,s.jsx)(n.h2,{id:"contract-implementation",children:"Contract Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),", you will find a library and an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"example implementation"})," of the Fungible Token for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,s.jsx)(n.p,{children:"There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,s.jsx)(n.li,{children:"Perform any customization changes necessary on your personal fork of the example contract."}),"\n",(0,s.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,s.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"installing-crates",children:"Installing Required Crates"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow creation of Wasm contracts and tests for use on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," - A library for developing Fungible Tokens for Casper networks"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here is the code snippet which imports those crates:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nuse casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};\n\nuse casper_types::{CLValue, U256};\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In Rust, the keyword ",(0,s.jsx)(n.code,{children:"use"})," is like an include statement in C/C++."]}),"\n",(0,s.jsx)(n.h3,{id:"initializing-the-contract",children:"Initializing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,s.jsx)(n.code,{children:"call()"})," function inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"}),". When you deploy the contract, you need to initialize it with a ",(0,s.jsx)(n.code,{children:"call()"})," function and define ",(0,s.jsx)(n.code,{children:"name"}),", ",(0,s.jsx)(n.code,{children:"symbol"}),", ",(0,s.jsx)(n.code,{children:"decimals"}),", and ",(0,s.jsx)(n.code,{children:"total_supply"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The code snippet for initializing the contract should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\n#[no_mangle]\nfn call() {\n let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);\n let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);\n let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);\n let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);\n\n let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"contract-methods",children:"Contract Methods"}),"\n",(0,s.jsx)(n.p,{children:"This section briefly explains the contract methods used in the Casper Fungible Token contract."}),"\n",(0,s.jsxs)(n.p,{children:["To see the full implementation of the below contract methods, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"})," in Github. If you have any questions, review the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," library and the ",(0,s.jsx)(n.a,{href:"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#",children:"EIP-20"})," standard."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, for further unresolved issues please contact the Casper support team via the ",(0,s.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Contract methods are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L83",children:(0,s.jsx)(n.strong,{children:"allowance"})})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L92",children:(0,s.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L75",children:(0,s.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L220",children:(0,s.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L331",children:(0,s.jsx)(n.strong,{children:"change_security"})})," - An administrator-level entry point to manipulate security access granted to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L65",children:(0,s.jsx)(n.strong,{children:"decimals"})})," - Returns the decimals of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L106",children:(0,s.jsx)(n.strong,{children:"decrease_allowance"})})," - Decrease the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L123",children:(0,s.jsx)(n.strong,{children:"increase_allowance"})})," - Increases the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L182",children:(0,s.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens, increasing the total supply"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L55",children:(0,s.jsx)(n.strong,{children:"name"})}),"- Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L60",children:(0,s.jsx)(n.strong,{children:"symbol"})})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L70",children:(0,s.jsx)(n.strong,{children:"total_supply"})})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L140",children:(0,s.jsx)(n.strong,{children:"transfer"})})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L155",children:(0,s.jsx)(n.strong,{children:"transfer_from"})})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the ",(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Sending Deploys to a Casper network using the Rust Client"})," section to learn more about install contracts."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-prerequisites",children:"Deploy Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Set up your machine as per the ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have ",(0,s.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#creating-accounts-and-keys",children:"set up an account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:["Since we are deploying to the Casper Testnet, ensure your ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/faucet",children:"Testnet faucet account"})," contains enough CSPR tokens to perform the contract execution. Follow the guide to ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites#fund-your-account",children:"fund your account"})," or to ",(0,s.jsx)(n.a,{href:"/next/developers/cli/transfers/direct-token-transfer",children:"transfer tokens"})," as needed"]}),"\n",(0,s.jsxs)(n.li,{children:["Install the ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," to interact with the network"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-flow",children:"Basic Flow"}),"\n",(0,s.jsx)(n.p,{children:"Here are the basic steps to install the Casper Fungible Token contract on a Casper Network."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cloning-the-token-contract",children:"Clone the contract"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-an-ip-address",children:"Get the IP address of a node"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#viewing-network-status",children:"View the network state"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploying-the-contract",children:"Install the contract via a deploy"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#querying-the-network-status",children:"View the network state"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cloning-the-token-contract",children:"Cloning the Token Contract"}),"\n",(0,s.jsx)(n.p,{children:"This step includes cloning and preparing the token contract for the deployment."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ngit clone https://github.com/casper-ecosystem/cep18.git\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncd cep18\nmake prepare\nmake build-contracts\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\nmake test\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["We will use a Testnet ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peer"})," to send the deploy. Read the guide to ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"acquiring a node address"})," if needed."]}),"\n",(0,s.jsx)(n.h3,{id:"viewing-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the state root hash"})}),"\n",(0,s.jsxs)(n.p,{children:["Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"Node IP address"})," taken from a Testnet peer."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the account hash"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Querying global state"})}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network status with regard to your account."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsx)(n.p,{children:"Now you can install the contract to the network and check how it behaves."}),"\n",(0,s.jsxs)(n.p,{children:["If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts/",children:"Gas and the Casper Blockchain"})," documentation for further details."]}),"\n",(0,s.jsx)(n.p,{children:"Use the following command template to deploy the contract:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NETWORK_NAME"}),": Use the relevant network name. Here we use '",(0,s.jsx)(n.em,{children:"casper-test"}),"'"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PATH_TO_YOUR_KEY"}),": Replace this with the actual path of your secret key"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PAYMENT_AMOUNT"}),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"WASM FILE PATH"}),": The session-path argument should point to the location of your compiled Fungible Token Wasm file"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here is a sample ",(0,s.jsx)(n.em,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-the-network-status",children:"Querying the Network Status"}),"\n",(0,s.jsxs)(n.p,{children:["You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"viewing the network state"})," section to execute this step with the new state root hash."]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-the-deploy",children:"Verifying the Deploy"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can verify the sent deploy using the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command. This will output the details of the sent deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-with-arguments",children:"Querying with Arguments"}),"\n",(0,s.jsxs)(n.p,{children:["This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"Fungible Token contract"})," to derive arguments."]}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network state with arguments:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-deploy-testnet",children:"Example Deploy on Testnet"}),"\n",(0,s.jsx)(n.p,{children:"The following steps will guide you through the process with sample values and results."}),"\n",(0,s.jsx)(n.h4,{id:"cloning-the-fungible-token-contract",children:"Cloning the Fungible Token Contract"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address-from-a-testnet-peer",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peers"})," to get the node IP address."]}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"Here is the command to query the state of the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--key account-hash-<account-address> \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This result contains the network state before the deploy. You can see the ",(0,s.jsx)(n.code,{children:"named-key"})," field is empty since we haven't sent the deploy to the network yet."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the network status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-<account-address> ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-<account-address> ",\n "weight": 1\n }\n ],\n "main_purse": "uref-<hash>",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-deploy",children:"Sending the Deploy"}),"\n",(0,s.jsx)(n.p,{children:"Send the Deploy containing your contract with this command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This command execution will output the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," of the applied deploy. We can use the deploy_hash to get the details of the deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-deploy-details",children:"Viewing the Deploy Details"}),"\n",(0,s.jsx)(n.p,{children:"You can view the details of the sent deploy using the command below:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> \\\nb00E59f8aBA5c7aB9.....\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"This contains the header, payment, and session details along with the execution results."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the execution result field appears as ",(0,s.jsx)(n.code,{children:'"execution_results":[]'}),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"querying-contract-entry-points",children:"Querying Contract Entry Points"}),"\n",(0,s.jsx)(n.p,{children:"We will query the argument 'name' in this example."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["You can see that the name is ",(0,s.jsx)(n.code,{children:"CasperTest"})," in this example."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const a={},r=s.createContext(a);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[81818],{95038:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),a=t(28453);const r={title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},c="Casper Fungible Token Tutorial",o={id:"resources/tokens/cep18/full-tutorial",title:"Fungible Token Workflow",description:"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.",source:"@site/docs/resources/tokens/cep18/full-tutorial.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/full-tutorial",permalink:"/resources/tokens/cep18/full-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724330007e3,frontMatter:{title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},sidebar:"resources",previous:{title:"Casper Token Standards",permalink:"/resources/tokens/"},next:{title:"On-chain Installation",permalink:"/resources/tokens/cep18/quickstart-guide"}},i={},l=[{value:"Preparation",id:"preparation",level:2},{value:"Contract Implementation",id:"contract-implementation",level:2},{value:"Installing Required Crates",id:"installing-crates",level:3},{value:"Initializing the Contract",id:"initializing-the-contract",level:3},{value:"Contract Methods",id:"contract-methods",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Deploy Prerequisites",id:"deploy-prerequisites",level:3},{value:"Basic Flow",id:"basic-flow",level:3},{value:"Cloning the Token Contract",id:"cloning-the-token-contract",level:3},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address",level:3},{value:"Viewing the Network Status",id:"viewing-network-status",level:3},{value:"Installing the Contract",id:"deploying-the-contract",level:3},{value:"Querying the Network Status",id:"querying-the-network-status",level:3},{value:"Verifying the Deploy",id:"verifying-the-deploy",level:3},{value:"Querying with Arguments",id:"querying-with-arguments",level:3},{value:"Example Deploy on Testnet",id:"sample-deploy-testnet",level:3},{value:"Cloning the Fungible Token Contract",id:"cloning-the-fungible-token-contract",level:4},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address-from-a-testnet-peer",level:3},{value:"Viewing the Network Status",id:"viewing-the-network-status",level:4},{value:"Sending the Deploy",id:"sending-the-deploy",level:4},{value:"Viewing the Deploy Details",id:"viewing-the-deploy-details",level:4},{value:"Querying Contract Entry Points",id:"querying-contract-entry-points",level:4}];function d(e){const n={a:"a",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-fungible-token-tutorial",children:"Casper Fungible Token Tutorial"})}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper Fungible Token standard is the Casper Platform's ERC-20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed."}),"\n",(0,s.jsxs)(n.p,{children:["The following functions implement the rules defined by Casper Fungible Tokens: ",(0,s.jsx)(n.code,{children:"totalSupply"}),", ",(0,s.jsx)(n.code,{children:"transfer"}),", ",(0,s.jsx)(n.code,{children:"transferFrom"}),", ",(0,s.jsx)(n.code,{children:"approve"}),", ",(0,s.jsx)(n.code,{children:"balanceOf"}),", and ",(0,s.jsx)(n.code,{children:"allowance"}),". A portion of this tutorial reviews the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract"})," and the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_fungible_token"})," library."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read first."]}),"\n",(0,s.jsx)(n.h2,{id:"preparation",children:"Preparation"}),"\n",(0,s.jsx)(n.p,{children:"First clone the contract from GitHub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18 && cd cep18\n"})}),"\n",(0,s.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,s.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Next, compile your contract and run the contract unit tests."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make build-contract\nmake test\n"})}),"\n",(0,s.jsx)(n.h2,{id:"contract-implementation",children:"Contract Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),", you will find a library and an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"example implementation"})," of the Fungible Token for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,s.jsx)(n.p,{children:"There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,s.jsx)(n.li,{children:"Perform any customization changes necessary on your personal fork of the example contract."}),"\n",(0,s.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,s.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"installing-crates",children:"Installing Required Crates"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow creation of Wasm contracts and tests for use on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," - A library for developing Fungible Tokens for Casper networks"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here is the code snippet which imports those crates:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nuse casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};\n\nuse casper_types::{CLValue, U256};\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In Rust, the keyword ",(0,s.jsx)(n.code,{children:"use"})," is like an include statement in C/C++."]}),"\n",(0,s.jsx)(n.h3,{id:"initializing-the-contract",children:"Initializing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,s.jsx)(n.code,{children:"call()"})," function inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"}),". When you deploy the contract, you need to initialize it with a ",(0,s.jsx)(n.code,{children:"call()"})," function and define ",(0,s.jsx)(n.code,{children:"name"}),", ",(0,s.jsx)(n.code,{children:"symbol"}),", ",(0,s.jsx)(n.code,{children:"decimals"}),", and ",(0,s.jsx)(n.code,{children:"total_supply"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The code snippet for initializing the contract should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\n#[no_mangle]\nfn call() {\n let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);\n let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);\n let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);\n let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);\n\n let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"contract-methods",children:"Contract Methods"}),"\n",(0,s.jsx)(n.p,{children:"This section briefly explains the contract methods used in the Casper Fungible Token contract."}),"\n",(0,s.jsxs)(n.p,{children:["To see the full implementation of the below contract methods, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"})," in Github. If you have any questions, review the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," library and the ",(0,s.jsx)(n.a,{href:"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#",children:"EIP-20"})," standard."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, for further unresolved issues please contact the Casper support team via the ",(0,s.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Contract methods are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L83",children:(0,s.jsx)(n.strong,{children:"allowance"})})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L92",children:(0,s.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L75",children:(0,s.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L220",children:(0,s.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L331",children:(0,s.jsx)(n.strong,{children:"change_security"})})," - An administrator-level entry point to manipulate security access granted to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L65",children:(0,s.jsx)(n.strong,{children:"decimals"})})," - Returns the decimals of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L106",children:(0,s.jsx)(n.strong,{children:"decrease_allowance"})})," - Decrease the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L123",children:(0,s.jsx)(n.strong,{children:"increase_allowance"})})," - Increases the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L182",children:(0,s.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens, increasing the total supply"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L55",children:(0,s.jsx)(n.strong,{children:"name"})}),"- Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L60",children:(0,s.jsx)(n.strong,{children:"symbol"})})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L70",children:(0,s.jsx)(n.strong,{children:"total_supply"})})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L140",children:(0,s.jsx)(n.strong,{children:"transfer"})})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L155",children:(0,s.jsx)(n.strong,{children:"transfer_from"})})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Sending Deploys to a Casper network using the Rust Client"})," section to learn more about install contracts."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-prerequisites",children:"Deploy Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Set up your machine as per the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have ",(0,s.jsx)(n.a,{href:"/concepts/accounts-and-keys#creating-accounts-and-keys",children:"set up an account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:["Since we are deploying to the Casper Testnet, ensure your ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/faucet",children:"Testnet faucet account"})," contains enough CSPR tokens to perform the contract execution. Follow the guide to ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#fund-your-account",children:"fund your account"})," or to ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"transfer tokens"})," as needed"]}),"\n",(0,s.jsxs)(n.li,{children:["Install the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," to interact with the network"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-flow",children:"Basic Flow"}),"\n",(0,s.jsx)(n.p,{children:"Here are the basic steps to install the Casper Fungible Token contract on a Casper Network."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cloning-the-token-contract",children:"Clone the contract"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-an-ip-address",children:"Get the IP address of a node"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#viewing-network-status",children:"View the network state"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploying-the-contract",children:"Install the contract via a deploy"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#querying-the-network-status",children:"View the network state"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cloning-the-token-contract",children:"Cloning the Token Contract"}),"\n",(0,s.jsx)(n.p,{children:"This step includes cloning and preparing the token contract for the deployment."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ngit clone https://github.com/casper-ecosystem/cep18.git\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncd cep18\nmake prepare\nmake build-contracts\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\nmake test\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["We will use a Testnet ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peer"})," to send the deploy. Read the guide to ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"acquiring a node address"})," if needed."]}),"\n",(0,s.jsx)(n.h3,{id:"viewing-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the state root hash"})}),"\n",(0,s.jsxs)(n.p,{children:["Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"Node IP address"})," taken from a Testnet peer."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the account hash"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Querying global state"})}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network status with regard to your account."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsx)(n.p,{children:"Now you can install the contract to the network and check how it behaves."}),"\n",(0,s.jsxs)(n.p,{children:["If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts/",children:"Gas and the Casper Blockchain"})," documentation for further details."]}),"\n",(0,s.jsx)(n.p,{children:"Use the following command template to deploy the contract:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NETWORK_NAME"}),": Use the relevant network name. Here we use '",(0,s.jsx)(n.em,{children:"casper-test"}),"'"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PATH_TO_YOUR_KEY"}),": Replace this with the actual path of your secret key"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PAYMENT_AMOUNT"}),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"WASM FILE PATH"}),": The session-path argument should point to the location of your compiled Fungible Token Wasm file"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here is a sample ",(0,s.jsx)(n.em,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-the-network-status",children:"Querying the Network Status"}),"\n",(0,s.jsxs)(n.p,{children:["You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"viewing the network state"})," section to execute this step with the new state root hash."]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-the-deploy",children:"Verifying the Deploy"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can verify the sent deploy using the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command. This will output the details of the sent deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-with-arguments",children:"Querying with Arguments"}),"\n",(0,s.jsxs)(n.p,{children:["This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"Fungible Token contract"})," to derive arguments."]}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network state with arguments:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-deploy-testnet",children:"Example Deploy on Testnet"}),"\n",(0,s.jsx)(n.p,{children:"The following steps will guide you through the process with sample values and results."}),"\n",(0,s.jsx)(n.h4,{id:"cloning-the-fungible-token-contract",children:"Cloning the Fungible Token Contract"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address-from-a-testnet-peer",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peers"})," to get the node IP address."]}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"Here is the command to query the state of the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--key account-hash-<account-address> \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This result contains the network state before the deploy. You can see the ",(0,s.jsx)(n.code,{children:"named-key"})," field is empty since we haven't sent the deploy to the network yet."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the network status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-<account-address> ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-<account-address> ",\n "weight": 1\n }\n ],\n "main_purse": "uref-<hash>",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-deploy",children:"Sending the Deploy"}),"\n",(0,s.jsx)(n.p,{children:"Send the Deploy containing your contract with this command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This command execution will output the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," of the applied deploy. We can use the deploy_hash to get the details of the deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-deploy-details",children:"Viewing the Deploy Details"}),"\n",(0,s.jsx)(n.p,{children:"You can view the details of the sent deploy using the command below:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> \\\nb00E59f8aBA5c7aB9.....\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"This contains the header, payment, and session details along with the execution results."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the execution result field appears as ",(0,s.jsx)(n.code,{children:'"execution_results":[]'}),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"querying-contract-entry-points",children:"Querying Contract Entry Points"}),"\n",(0,s.jsx)(n.p,{children:"We will query the argument 'name' in this example."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["You can see that the name is ",(0,s.jsx)(n.code,{children:"CasperTest"})," in this example."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const a={},r=s.createContext(a);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28bc9864.246d5f11.js b/assets/js/28bc9864.246d5f11.js new file mode 100644 index 000000000..9cd235bee --- /dev/null +++ b/assets/js/28bc9864.246d5f11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5069],{1697:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var s=t(74848),a=t(28453);const i={title:"Unbonding"},o="Unbonding as a Validator",r={id:"operators/becoming-a-validator/unbonding",title:"Unbonding",description:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.",source:"@site/docs/operators/becoming-a-validator/unbonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/unbonding",permalink:"/operators/becoming-a-validator/unbonding",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Unbonding"},sidebar:"operators",previous:{title:"Bonding",permalink:"/operators/becoming-a-validator/bonding"},next:{title:"Recovery",permalink:"/operators/becoming-a-validator/recovering"}},c={},d=[{value:"Method 1: Unbonding with the System Auction Contract",id:"withdraw-system-auction",level:2},{value:"Method 2: Unbonding with Compiled Wasm",id:"withdraw-compiled-wasm",level:2},{value:"Check the Auction Contract",id:"check-the-auction-contract",level:2},{value:"Unbonding Wait Period",id:"unbonding-wait-period",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"unbonding-as-a-validator",children:"Unbonding as a Validator"})}),"\n",(0,s.jsx)(n.p,{children:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction."}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-system-auction",children:"Method 1: Unbonding with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method withdraws a bid using the system auction contract. Call the existing ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,s.jsx)(n.strong,{children:"Adjust all the values to your use case."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-compiled-wasm",children:"Method 2: Unbonding with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["There is a second way to withdraw a bid, using the compiled Wasm ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The process is the same as bonding but uses a different contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes estimated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"})," expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["Here is an example request to unbond stake using the ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"check-the-auction-contract",children:"Check the Auction Contract"}),"\n",(0,s.jsx)(n.p,{children:"Check the auction contract for updates to the bid amounts."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"unbonding-wait-period",children:"Unbonding Wait Period"}),"\n",(0,s.jsx)(n.p,{children:"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/28bc9864.9af5621d.js b/assets/js/28bc9864.9af5621d.js deleted file mode 100644 index ca653d767..000000000 --- a/assets/js/28bc9864.9af5621d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5069],{1697:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var s=t(74848),a=t(28453);const i={title:"Unbonding"},o="Unbonding as a Validator",r={id:"operators/becoming-a-validator/unbonding",title:"Unbonding",description:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.",source:"@site/docs/operators/becoming-a-validator/unbonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/unbonding",permalink:"/next/operators/becoming-a-validator/unbonding",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Unbonding"},sidebar:"operators",previous:{title:"Bonding",permalink:"/next/operators/becoming-a-validator/bonding"},next:{title:"Recovery",permalink:"/next/operators/becoming-a-validator/recovering"}},c={},d=[{value:"Method 1: Unbonding with the System Auction Contract",id:"withdraw-system-auction",level:2},{value:"Method 2: Unbonding with Compiled Wasm",id:"withdraw-compiled-wasm",level:2},{value:"Check the Auction Contract",id:"check-the-auction-contract",level:2},{value:"Unbonding Wait Period",id:"unbonding-wait-period",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"unbonding-as-a-validator",children:"Unbonding as a Validator"})}),"\n",(0,s.jsx)(n.p,{children:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction."}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-system-auction",children:"Method 1: Unbonding with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method withdraws a bid using the system auction contract. Call the existing ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,s.jsx)(n.strong,{children:"Adjust all the values to your use case."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-compiled-wasm",children:"Method 2: Unbonding with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["There is a second way to withdraw a bid, using the compiled Wasm ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The process is the same as bonding but uses a different contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes estimated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"})," expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["Here is an example request to unbond stake using the ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"check-the-auction-contract",children:"Check the Auction Contract"}),"\n",(0,s.jsx)(n.p,{children:"Check the auction contract for updates to the bid amounts."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"unbonding-wait-period",children:"Unbonding Wait Period"}),"\n",(0,s.jsx)(n.p,{children:"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2a21571b.eb912000.js b/assets/js/2a21571b.eb912000.js new file mode 100644 index 000000000..d7cecd3fe --- /dev/null +++ b/assets/js/2a21571b.eb912000.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2306],{57011:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var t=s(74848),i=s(28453);const r={title:"Join a Network"},d="Joining a Running Network",o={id:"operators/setup/joining",title:"Join a Network",description:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.",source:"@site/versioned_docs/version-2.0.0/operators/setup/joining.md",sourceDirName:"operators/setup",slug:"/operators/setup/joining",permalink:"/2.0.0/operators/setup/joining",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Join a Network"},sidebar:"operators",previous:{title:"Upgrades",permalink:"/2.0.0/operators/setup/upgrade"},next:{title:"Non-Root Users",permalink:"/2.0.0/operators/setup/non-root-user"}},a={},l=[{value:"Step 1: Provisioning Hardware",id:"step-1-provision-hardware",level:2},{value:"Step 2: Setting Up the Node",id:"step-2-set-up-the-node",level:2},{value:"Step 3: Building the Required Contracts",id:"step-3-build-contracts",level:2},{value:"Step 4: Creating and Fund Keys for Bonding",id:"step-4-create--fund-keys-for-bonding",level:2},{value:"Step 5: Updating the Trusted Hash",id:"step-5-update-the-trusted-hash",level:2},{value:"Step 6: Starting the Node",id:"step-6-start-the-node",level:2},{value:"Step 7: Confirming the Node is Synchronized",id:"step-7-confirm-the-node-is-synchronized",level:2},{value:"Step 8: Sending the Bonding Request",id:"step-7-send-the-bonding-request",level:2}];function c(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"joining-a-running-network",children:"Joining a Running Network"})}),"\n",(0,t.jsx)(n.p,{children:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network."}),"\n",(0,t.jsx)(n.h2,{id:"step-1-provision-hardware",children:"Step 1: Provisioning Hardware"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/hardware",children:"Hardware Specifications"})," section and provision your node hardware."]}),"\n",(0,t.jsx)(n.h2,{id:"step-2-set-up-the-node",children:"Step 2: Setting Up the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the instructions on the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"step-3-build-contracts",children:"Step 3: Building the Required Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the casper-node repository."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Install these prerequisites, which are also listed ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node#pre-requisites-for-building",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started#installing-rust",children:"Rust"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"CMake"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pkg-config"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install pkg-config"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"openssl"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install openssl"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"libssl-dev"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install libssl-dev"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Rust casper-client"})," and fund the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#create-fund-keys",children:"keys"})," you will use for bonding."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Use the following commands to build the contracts in release mode. Make sure you have ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started#installing-rust",children:"installed Rust"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-client-contracts\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will build all the necessary Wasm contracts for operating as a validator:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"activate_bid.wasm"})," - Reactivates an ejected validator"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_bid.wasm"})," - Enables bonding for validator stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegate.wasm"})," - Delegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"undelegate.wasm"})," - Undelegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"withdraw_bid.wasm"})," - Enables unbonding for validator stake"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-4-create--fund-keys-for-bonding",children:"Step 4: Creating and Fund Keys for Bonding"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," instructions if you have not generated and funded your validator keys."]}),"\n",(0,t.jsx)(n.h2,{id:"step-5-update-the-trusted-hash",children:"Step 5: Updating the Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["The node's ",(0,t.jsx)(n.code,{children:"config.toml"})," needs to be updated with a recent trusted hash."]}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Trusted Hash for Synchronizing"})," instructions if you have not set up a trusted hash during node installation."]}),"\n",(0,t.jsx)(n.h2,{id:"step-6-start-the-node",children:"Step 6: Starting the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Start the node with the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above Debian package installs a casper-node service for systemd."}),"\n",(0,t.jsxs)(n.p,{children:["For more information, visit ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/wiki#node-operators",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-confirm-the-node-is-synchronized",children:"Step 7: Confirming the Node is Synchronized"}),"\n",(0,t.jsxs)(n.p,{children:["While the node is synchronizing, the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint is available. You will be able to compare this to another node's status endpoint ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," to determine if you are caught up. You will not be able to perform any ",(0,t.jsx)(n.code,{children:"casper-client"})," calls to your ",(0,t.jsx)(n.code,{children:"7777"})," RPC port until your node is fully caught up."]}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, notice the ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," that you can use to determine if your node has completed synchronizing."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsxs)(n.summary,{children:["Sample output of the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.3",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",\n "peers": [\n {\n "node_id": "tls:0097..b253",\n "address": "18.163.249.168:35000"\n },\n ...\n ...\n ...\n {\n "node_id": "tls:ff95..c014",\n "address": "93.186.201.14:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",\n "timestamp": "2022-01-04T15:33:08.224Z",\n "era_id": 3240,\n "height": 430162,\n "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",\n "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"\n },\n "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",\n "round_length": null,\n "next_upgrade": null,\n "build_version": "1.4.3-a44bed1fd-casper-mainnet",\n "uptime": "25days 1h 48m 22s 47ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-send-the-bonding-request",children:"Step 8: Sending the Bonding Request"}),"\n",(0,t.jsxs)(n.p,{children:["You can submit a ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/bonding",children:"bonding request"})," to change your synchronized node to a validating node."]}),"\n",(0,t.jsx)(n.p,{children:"The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var t=s(96540);const i={},r=t.createContext(i);function d(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ac03470.9c632600.js b/assets/js/2ac03470.9c632600.js new file mode 100644 index 000000000..ff4e88436 --- /dev/null +++ b/assets/js/2ac03470.9c632600.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27941],{22426:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const i={title:"Move to Casper"},r="Moving to Casper from another Blockchain {#moving-to-casper}",o={id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/versioned_docs/version-2.0.0/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/2.0.0/resources/moving-to-casper",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/2.0.0/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/2.0.0/resources/tokens/"}},c={},l=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"moving-to-casper",children:"Moving to Casper from another Blockchain"})}),"\n",(0,s.jsx)(t.p,{children:"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-overview",children:"Smart Contract Platform Overview"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#variable-storage",children:"Variable Storage and State Management"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-functions",children:"Contract Functions"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#passing-arguments",children:"Passing Arguments"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"#additional-considerations",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"contract-overview",children:"Smart Contract Platform"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"Casper smart contracts are written in Rust."}),"\n",(0,s.jsxs)(t.p,{children:["Variables defined within the smart contract can be stored as either ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#namedkey",children:"Named Keys"})," or ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/dictionaries",children:"Dictionaries"})," as described in ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"call"})," function serves as the main entry point of the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"smart contract"}),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."]}),"\n",(0,s.jsxs)(t.p,{children:["It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"All public methods defined within the contract serve as its interface, exposing its functionality."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The Module's public methods are its interface and can be invoked from code outside the blockchain."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Solana smart contracts are primarily written in Rust."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"variable-storage",children:"Variable Storage and State Management"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsxs)(t.p,{children:["Variables can be stored as Named Keys or Dictionaries as described in ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"contract-functions",children:"Contract Functions"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n \n // Entry point body\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html",children:"RuntimeArgs"})," passed to the contract. Entry points are instantiated within the ",(0,s.jsx)(t.code,{children:"call"})," entry point."]}),"\n",(0,s.jsxs)(t.p,{children:["If a return value is needed, it should be declared using the syntax described in the ",(0,s.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"runtime::ret(value);\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Each call to an entry point is treated as a ",(0,s.jsx)(t.a,{href:"/2.0.0/transactions-and-transaction-lifecycle",children:"Deploy"})," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit)."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The declaration of public methods in Ethereum follows the format:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function update_name(string value) public {\n dapp_name = value;\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"In the Near blockchain, there are three types of public functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Init Methods"})," - These are used as the class constructors to initialize the state of the contract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"View Methods"})," - These functions are used to read the state of the contract variables."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Call Methods"})," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The definition of public methods in Near is as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn add_message(&mut self, ...) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public methods that return variables, the definition would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun start_collection(account: &signer) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public functions that return variables, the definition would be as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun max(a: u8, b: u8): (u8, bool) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In the Aptos blockchain, it is possible to return one or more values from a function."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"entrypoint!(process_instruction);\n"})}),"\n",(0,s.jsx)(t.p,{children:"The implementation of the entry point may resemble the following:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Within the entry point function, the necessary parameters are specified, such as ",(0,s.jsx)(t.code,{children:"program_id"}),", which represents the program's identifier, ",(0,s.jsx)(t.code,{children:"accounts"}),", an array of ",(0,s.jsx)(t.code,{children:"AccountInfo"})," providing account details, and ",(0,s.jsx)(t.code,{children:"_instruction_data"}),", representing the instruction data received. The function returns a ",(0,s.jsx)(t.code,{children:"ProgramResult"}),", which indicates the success or failure of the instruction execution."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"passing-arguments",children:"Passing Arguments"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To understand the context of this example, refer to: ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/cli/delegate",children:"Delegating with the Casper Client"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In the contract, you can access the session arguments as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"let uref: URef = runtime::get_key(Key_Name)\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to retrieve the desired session argument by specifying the key's name."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are uncertain how to use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to obtain a specific session argument, check how to ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"write a basic smart contract on Casper"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"additional-considerations",children:"Additional Considerations"}),"\n",(0,s.jsx)(t.p,{children:"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)."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."}),"\n",(0,s.jsx)(t.p,{children:"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},i=s.createContext(a);function r(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2b8e251b.baf2f328.js b/assets/js/2b8e251b.baf2f328.js new file mode 100644 index 000000000..67c984c30 --- /dev/null +++ b/assets/js/2b8e251b.baf2f328.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31180],{6994:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),a=t(28453);const r={title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},c="Casper Fungible Token Tutorial",o={id:"resources/tokens/cep18/full-tutorial",title:"Fungible Token Workflow",description:"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/full-tutorial.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/full-tutorial",permalink:"/1.5.X/resources/tokens/cep18/full-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726495933e3,frontMatter:{title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},sidebar:"resources",previous:{title:"Casper Token Standards",permalink:"/1.5.X/resources/tokens/"},next:{title:"On-chain Installation",permalink:"/1.5.X/resources/tokens/cep18/quickstart-guide"}},i={},l=[{value:"Preparation",id:"preparation",level:2},{value:"Contract Implementation",id:"contract-implementation",level:2},{value:"Installing Required Crates",id:"installing-crates",level:3},{value:"Initializing the Contract",id:"initializing-the-contract",level:3},{value:"Contract Methods",id:"contract-methods",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Deploy Prerequisites",id:"deploy-prerequisites",level:3},{value:"Basic Flow",id:"basic-flow",level:3},{value:"Cloning the Token Contract",id:"cloning-the-token-contract",level:3},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address",level:3},{value:"Viewing the Network Status",id:"viewing-network-status",level:3},{value:"Installing the Contract",id:"deploying-the-contract",level:3},{value:"Querying the Network Status",id:"querying-the-network-status",level:3},{value:"Verifying the Deploy",id:"verifying-the-deploy",level:3},{value:"Querying with Arguments",id:"querying-with-arguments",level:3},{value:"Example Deploy on Testnet",id:"sample-deploy-testnet",level:3},{value:"Cloning the Fungible Token Contract",id:"cloning-the-fungible-token-contract",level:4},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address-from-a-testnet-peer",level:3},{value:"Viewing the Network Status",id:"viewing-the-network-status",level:4},{value:"Sending the Deploy",id:"sending-the-deploy",level:4},{value:"Viewing the Deploy Details",id:"viewing-the-deploy-details",level:4},{value:"Querying Contract Entry Points",id:"querying-contract-entry-points",level:4}];function d(e){const n={a:"a",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-fungible-token-tutorial",children:"Casper Fungible Token Tutorial"})}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper Fungible Token standard is the Casper Platform's ER-C20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed."}),"\n",(0,s.jsxs)(n.p,{children:["The following functions implement the rules defined by Casper Fungible Tokens: ",(0,s.jsx)(n.code,{children:"totalSupply"}),", ",(0,s.jsx)(n.code,{children:"transfer"}),", ",(0,s.jsx)(n.code,{children:"transferFrom"}),", ",(0,s.jsx)(n.code,{children:"approve"}),", ",(0,s.jsx)(n.code,{children:"balanceOf"}),", and ",(0,s.jsx)(n.code,{children:"allowance"}),". A portion of this tutorial reviews the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract"})," and the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_fungible_token"})," library."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read first."]}),"\n",(0,s.jsx)(n.h2,{id:"preparation",children:"Preparation"}),"\n",(0,s.jsx)(n.p,{children:"First clone the contract from GitHub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18 && cd cep18\n"})}),"\n",(0,s.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,s.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Next, compile your contract and run the contract unit tests."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make build-contract\nmake test\n"})}),"\n",(0,s.jsx)(n.h2,{id:"contract-implementation",children:"Contract Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),", you will find a library and an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"example implementation"})," of the Fungible Token for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,s.jsx)(n.p,{children:"There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,s.jsx)(n.li,{children:"Perform any customization changes necessary on your personal fork of the example contract."}),"\n",(0,s.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,s.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"installing-crates",children:"Installing Required Crates"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow creation of Wasm contracts and tests for use on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," - A library for developing Fungible Tokens for Casper networks"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here is the code snippet which imports those crates:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nuse casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};\n\nuse casper_types::{CLValue, U256};\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In Rust, the keyword ",(0,s.jsx)(n.code,{children:"use"})," is like an include statement in C/C++."]}),"\n",(0,s.jsx)(n.h3,{id:"initializing-the-contract",children:"Initializing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,s.jsx)(n.code,{children:"call()"})," function inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"}),". When you deploy the contract, you need to initialize it with a ",(0,s.jsx)(n.code,{children:"call()"})," function and define ",(0,s.jsx)(n.code,{children:"name"}),", ",(0,s.jsx)(n.code,{children:"symbol"}),", ",(0,s.jsx)(n.code,{children:"decimals"}),", and ",(0,s.jsx)(n.code,{children:"total_supply"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The code snippet for initializing the contract should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\n#[no_mangle]\nfn call() {\n let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);\n let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);\n let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);\n let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);\n\n let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"contract-methods",children:"Contract Methods"}),"\n",(0,s.jsx)(n.p,{children:"This section briefly explains the contract methods used in the Casper Fungible Token contract."}),"\n",(0,s.jsxs)(n.p,{children:["To see the full implementation of the below contract methods, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"})," in Github. If you have any questions, review the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," library and the ",(0,s.jsx)(n.a,{href:"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#",children:"EIP-20"})," standard."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, for further unresolved issues please contact the Casper support team via the ",(0,s.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Contract methods are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L83",children:(0,s.jsx)(n.strong,{children:"allowance"})})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L92",children:(0,s.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L75",children:(0,s.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L220",children:(0,s.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L331",children:(0,s.jsx)(n.strong,{children:"change_security"})})," - An administrator-level entry point to manipulate security access granted to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L65",children:(0,s.jsx)(n.strong,{children:"decimals"})})," - Returns the decimals of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L106",children:(0,s.jsx)(n.strong,{children:"decrease_allowance"})})," - Decrease the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L123",children:(0,s.jsx)(n.strong,{children:"increase_allowance"})})," - Increases the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L182",children:(0,s.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens, increasing the total supply"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L55",children:(0,s.jsx)(n.strong,{children:"name"})}),"- Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L60",children:(0,s.jsx)(n.strong,{children:"symbol"})})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L70",children:(0,s.jsx)(n.strong,{children:"total_supply"})})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L140",children:(0,s.jsx)(n.strong,{children:"transfer"})})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L155",children:(0,s.jsx)(n.strong,{children:"transfer_from"})})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys/",children:"Sending Deploys to a Casper network using the Rust Client"})," section to learn more about install contracts."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-prerequisites",children:"Deploy Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Set up your machine as per the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have ",(0,s.jsx)(n.a,{href:"../../../concepts/accounts-and-keys/#creating-accounts-and-keys",children:"set up an account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:["Since we are deploying to the Casper Testnet, ensure your ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/faucet",children:"Testnet faucet account"})," contains enough CSPR tokens to perform the contract execution. Follow the guide to ",(0,s.jsx)(n.a,{href:"../../../developers/prerequisites/#fund-your-account",children:"fund your account"})," or to ",(0,s.jsx)(n.a,{href:"../../../developers/cli/transfers/",children:"transfer tokens"})," as needed"]}),"\n",(0,s.jsxs)(n.li,{children:["Install the ",(0,s.jsx)(n.a,{href:"../../../developers/prerequisites/#install-casper-client",children:"Casper command-line client"})," to interact with the network"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-flow",children:"Basic Flow"}),"\n",(0,s.jsx)(n.p,{children:"Here are the basic steps to install the Casper Fungible Token contract on a Casper Network."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cloning-the-token-contract",children:"Clone the contract"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-an-ip-address-from-a-testnet-peer",children:"Get the IP address of a node"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"View the network state"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#installing-the-contract",children:"Install the contract via a deploy"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#querying-the-network-status",children:"View the network state"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cloning-the-token-contract",children:"Cloning the Token Contract"}),"\n",(0,s.jsx)(n.p,{children:"This step includes cloning and preparing the token contract for the deployment."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ngit clone https://github.com/casper-ecosystem/cep18.git\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncd cep18\nmake prepare\nmake build-contracts\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\nmake test\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["We will use a Testnet ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peer"})," to send the deploy. Read the guide to ",(0,s.jsx)(n.a,{href:"../../../developers/prerequisites/#acquire-node-address-from-network-peers",children:"acquiring a node address"})," if needed."]}),"\n",(0,s.jsx)(n.h3,{id:"viewing-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the state root hash"})}),"\n",(0,s.jsxs)(n.p,{children:["Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the ",(0,s.jsx)(n.a,{href:"../../../developers/prerequisites/#acquire-node-address-from-network-peers",children:"Node IP address"})," taken from a Testnet peer."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the account hash"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Querying global state"})}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network status with regard to your account."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsx)(n.p,{children:"Now you can install the contract to the network and check how it behaves."}),"\n",(0,s.jsxs)(n.p,{children:["If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.jsx)(n.a,{href:"../../../developers/cli/sending-deploys/#a-note-about-gas-price",children:"note about gas price"})," to understand more about payment amounts and gas price adjustments."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"The Casper platform currently does not refund any tokens as part of sending a deploy."})," For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the ",(0,s.jsx)(n.a,{href:"../../../concepts/economics/gas-concepts/",children:"Gas and the Casper Blockchain"})," documentation for further details."]}),"\n",(0,s.jsx)(n.p,{children:"Use the following command template to deploy the contract:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NETWORK_NAME"}),": Use the relevant network name. Here we use '",(0,s.jsx)(n.em,{children:"casper-test"}),"'"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PATH_TO_YOUR_KEY"}),": Replace this with the actual path of your secret key"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PAYMENT_AMOUNT"}),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"WASM FILE PATH"}),": The session-path argument should point to the location of your compiled Fungible Token Wasm file"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here is a sample ",(0,s.jsx)(n.em,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-the-network-status",children:"Querying the Network Status"}),"\n",(0,s.jsxs)(n.p,{children:["You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"viewing the network state"})," section to execute this step with the new state root hash."]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-the-deploy",children:"Verifying the Deploy"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can verify the sent deploy using the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command. This will output the details of the sent deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-with-arguments",children:"Querying with Arguments"}),"\n",(0,s.jsxs)(n.p,{children:["This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"Fungible Token contract"})," to derive arguments."]}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network state with arguments:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-deploy-testnet",children:"Example Deploy on Testnet"}),"\n",(0,s.jsx)(n.p,{children:"The following steps will guide you through the process with sample values and results."}),"\n",(0,s.jsx)(n.h4,{id:"cloning-the-fungible-token-contract",children:"Cloning the Fungible Token Contract"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address-from-a-testnet-peer",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peers"})," to get the node IP address."]}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"Here is the command to query the state of the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--key account-hash-<account-address> \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This result contains the network state before the deploy. You can see the ",(0,s.jsx)(n.code,{children:"named-key"})," field is empty since we haven't sent the deploy to the network yet."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the network status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-<account-address> ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-<account-address> ",\n "weight": 1\n }\n ],\n "main_purse": "uref-<hash>",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-deploy",children:"Sending the Deploy"}),"\n",(0,s.jsx)(n.p,{children:"Send the Deploy containing your contract with this command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This command execution will output the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," of the applied deploy. We can use the deploy_hash to get the details of the deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-deploy-details",children:"Viewing the Deploy Details"}),"\n",(0,s.jsx)(n.p,{children:"You can view the details of the sent deploy using the command below:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> \\\nb00E59f8aBA5c7aB9.....\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"This contains the header, payment, and session details along with the execution results."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the execution result field appears as ",(0,s.jsx)(n.code,{children:'"execution_results":[]'}),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"querying-contract-entry-points",children:"Querying Contract Entry Points"}),"\n",(0,s.jsx)(n.p,{children:"We will query the argument 'name' in this example."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["You can see that the name is ",(0,s.jsx)(n.code,{children:"CasperTest"})," in this example."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const a={},r=s.createContext(a);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2b8e251b.f0bf2b40.js b/assets/js/2b8e251b.f0bf2b40.js deleted file mode 100644 index 92dac7bdd..000000000 --- a/assets/js/2b8e251b.f0bf2b40.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1180],{6994:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),a=t(28453);const r={title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},c="Casper Fungible Token Tutorial",o={id:"resources/tokens/cep18/full-tutorial",title:"Fungible Token Workflow",description:"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/full-tutorial.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/full-tutorial",permalink:"/resources/tokens/cep18/full-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},sidebar:"resources",previous:{title:"Casper Token Standards",permalink:"/resources/tokens/"},next:{title:"On-chain Installation",permalink:"/resources/tokens/cep18/quickstart-guide"}},i={},l=[{value:"Preparation",id:"preparation",level:2},{value:"Contract Implementation",id:"contract-implementation",level:2},{value:"Installing Required Crates",id:"installing-crates",level:3},{value:"Initializing the Contract",id:"initializing-the-contract",level:3},{value:"Contract Methods",id:"contract-methods",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Deploy Prerequisites",id:"deploy-prerequisites",level:3},{value:"Basic Flow",id:"basic-flow",level:3},{value:"Cloning the Token Contract",id:"cloning-the-token-contract",level:3},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address",level:3},{value:"Viewing the Network Status",id:"viewing-network-status",level:3},{value:"Installing the Contract",id:"deploying-the-contract",level:3},{value:"Querying the Network Status",id:"querying-the-network-status",level:3},{value:"Verifying the Deploy",id:"verifying-the-deploy",level:3},{value:"Querying with Arguments",id:"querying-with-arguments",level:3},{value:"Example Deploy on Testnet",id:"sample-deploy-testnet",level:3},{value:"Cloning the Fungible Token Contract",id:"cloning-the-fungible-token-contract",level:4},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address-from-a-testnet-peer",level:3},{value:"Viewing the Network Status",id:"viewing-the-network-status",level:4},{value:"Sending the Deploy",id:"sending-the-deploy",level:4},{value:"Viewing the Deploy Details",id:"viewing-the-deploy-details",level:4},{value:"Querying Contract Entry Points",id:"querying-contract-entry-points",level:4}];function d(e){const n={a:"a",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-fungible-token-tutorial",children:"Casper Fungible Token Tutorial"})}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper Fungible Token standard is the Casper Platform's ER-C20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed."}),"\n",(0,s.jsxs)(n.p,{children:["The following functions implement the rules defined by Casper Fungible Tokens: ",(0,s.jsx)(n.code,{children:"totalSupply"}),", ",(0,s.jsx)(n.code,{children:"transfer"}),", ",(0,s.jsx)(n.code,{children:"transferFrom"}),", ",(0,s.jsx)(n.code,{children:"approve"}),", ",(0,s.jsx)(n.code,{children:"balanceOf"}),", and ",(0,s.jsx)(n.code,{children:"allowance"}),". A portion of this tutorial reviews the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract"})," and the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_fungible_token"})," library."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract/",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read first."]}),"\n",(0,s.jsx)(n.h2,{id:"preparation",children:"Preparation"}),"\n",(0,s.jsx)(n.p,{children:"First clone the contract from GitHub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18 && cd cep18\n"})}),"\n",(0,s.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,s.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started/",children:"Getting Started Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Next, compile your contract and run the contract unit tests."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make build-contract\nmake test\n"})}),"\n",(0,s.jsx)(n.h2,{id:"contract-implementation",children:"Contract Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),", you will find a library and an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"example implementation"})," of the Fungible Token for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,s.jsx)(n.p,{children:"There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,s.jsx)(n.li,{children:"Perform any customization changes necessary on your personal fork of the example contract."}),"\n",(0,s.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,s.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"installing-crates",children:"Installing Required Crates"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow creation of Wasm contracts and tests for use on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," - A library for developing Fungible Tokens for Casper networks"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here is the code snippet which imports those crates:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nuse casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};\n\nuse casper_types::{CLValue, U256};\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In Rust, the keyword ",(0,s.jsx)(n.code,{children:"use"})," is like an include statement in C/C++."]}),"\n",(0,s.jsx)(n.h3,{id:"initializing-the-contract",children:"Initializing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,s.jsx)(n.code,{children:"call()"})," function inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"}),". When you deploy the contract, you need to initialize it with a ",(0,s.jsx)(n.code,{children:"call()"})," function and define ",(0,s.jsx)(n.code,{children:"name"}),", ",(0,s.jsx)(n.code,{children:"symbol"}),", ",(0,s.jsx)(n.code,{children:"decimals"}),", and ",(0,s.jsx)(n.code,{children:"total_supply"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The code snippet for initializing the contract should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\n#[no_mangle]\nfn call() {\n let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);\n let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);\n let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);\n let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);\n\n let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"contract-methods",children:"Contract Methods"}),"\n",(0,s.jsx)(n.p,{children:"This section briefly explains the contract methods used in the Casper Fungible Token contract."}),"\n",(0,s.jsxs)(n.p,{children:["To see the full implementation of the below contract methods, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"})," in Github. If you have any questions, review the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," library and the ",(0,s.jsx)(n.a,{href:"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#",children:"EIP-20"})," standard."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, for further unresolved issues please contact the Casper support team via the ",(0,s.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Contract methods are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L83",children:(0,s.jsx)(n.strong,{children:"allowance"})})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L92",children:(0,s.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L75",children:(0,s.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L220",children:(0,s.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L331",children:(0,s.jsx)(n.strong,{children:"change_security"})})," - An administrator-level entry point to manipulate security access granted to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L65",children:(0,s.jsx)(n.strong,{children:"decimals"})})," - Returns the decimals of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L106",children:(0,s.jsx)(n.strong,{children:"decrease_allowance"})})," - Decrease the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L123",children:(0,s.jsx)(n.strong,{children:"increase_allowance"})})," - Increases the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L182",children:(0,s.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens, increasing the total supply"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L55",children:(0,s.jsx)(n.strong,{children:"name"})}),"- Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L60",children:(0,s.jsx)(n.strong,{children:"symbol"})})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L70",children:(0,s.jsx)(n.strong,{children:"total_supply"})})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L140",children:(0,s.jsx)(n.strong,{children:"transfer"})})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L155",children:(0,s.jsx)(n.strong,{children:"transfer_from"})})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys/",children:"Sending Deploys to a Casper network using the Rust Client"})," section to learn more about install contracts."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-prerequisites",children:"Deploy Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Set up your machine as per the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites/",children:"prerequisites"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have ",(0,s.jsx)(n.a,{href:"/concepts/accounts-and-keys/#creating-accounts-and-keys",children:"set up an account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:["Since we are deploying to the Casper Testnet, ensure your ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/faucet",children:"Testnet faucet account"})," contains enough CSPR tokens to perform the contract execution. Follow the guide to ",(0,s.jsx)(n.a,{href:"/developers/prerequisites/#fund-your-account",children:"fund your account"})," or to ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/",children:"transfer tokens"})," as needed"]}),"\n",(0,s.jsxs)(n.li,{children:["Install the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites/#install-casper-client",children:"Casper command-line client"})," to interact with the network"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-flow",children:"Basic Flow"}),"\n",(0,s.jsx)(n.p,{children:"Here are the basic steps to install the Casper Fungible Token contract on a Casper Network."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cloning-the-token-contract",children:"Clone the contract"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-an-ip-address-from-a-testnet-peer",children:"Get the IP address of a node"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"View the network state"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#installing-the-contract",children:"Install the contract via a deploy"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#querying-the-network-status",children:"View the network state"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cloning-the-token-contract",children:"Cloning the Token Contract"}),"\n",(0,s.jsx)(n.p,{children:"This step includes cloning and preparing the token contract for the deployment."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ngit clone https://github.com/casper-ecosystem/cep18.git\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncd cep18\nmake prepare\nmake build-contracts\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\nmake test\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["We will use a Testnet ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peer"})," to send the deploy. Read the guide to ",(0,s.jsx)(n.a,{href:"/developers/prerequisites/#acquire-node-address-from-network-peers",children:"acquiring a node address"})," if needed."]}),"\n",(0,s.jsx)(n.h3,{id:"viewing-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the state root hash"})}),"\n",(0,s.jsxs)(n.p,{children:["Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites/#acquire-node-address-from-network-peers",children:"Node IP address"})," taken from a Testnet peer."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the account hash"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Querying global state"})}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network status with regard to your account."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsx)(n.p,{children:"Now you can install the contract to the network and check how it behaves."}),"\n",(0,s.jsxs)(n.p,{children:["If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys/#a-note-about-gas-price",children:"note about gas price"})," to understand more about payment amounts and gas price adjustments."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"The Casper platform currently does not refund any tokens as part of sending a deploy."})," For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts/",children:"Gas and the Casper Blockchain"})," documentation for further details."]}),"\n",(0,s.jsx)(n.p,{children:"Use the following command template to deploy the contract:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NETWORK_NAME"}),": Use the relevant network name. Here we use '",(0,s.jsx)(n.em,{children:"casper-test"}),"'"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PATH_TO_YOUR_KEY"}),": Replace this with the actual path of your secret key"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PAYMENT_AMOUNT"}),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"WASM FILE PATH"}),": The session-path argument should point to the location of your compiled Fungible Token Wasm file"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here is a sample ",(0,s.jsx)(n.em,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-the-network-status",children:"Querying the Network Status"}),"\n",(0,s.jsxs)(n.p,{children:["You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"viewing the network state"})," section to execute this step with the new state root hash."]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-the-deploy",children:"Verifying the Deploy"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can verify the sent deploy using the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command. This will output the details of the sent deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-with-arguments",children:"Querying with Arguments"}),"\n",(0,s.jsxs)(n.p,{children:["This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"Fungible Token contract"})," to derive arguments."]}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network state with arguments:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-deploy-testnet",children:"Example Deploy on Testnet"}),"\n",(0,s.jsx)(n.p,{children:"The following steps will guide you through the process with sample values and results."}),"\n",(0,s.jsx)(n.h4,{id:"cloning-the-fungible-token-contract",children:"Cloning the Fungible Token Contract"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address-from-a-testnet-peer",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peers"})," to get the node IP address."]}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"Here is the command to query the state of the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--key account-hash-<account-address> \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This result contains the network state before the deploy. You can see the ",(0,s.jsx)(n.code,{children:"named-key"})," field is empty since we haven't sent the deploy to the network yet."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the network status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-<account-address> ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-<account-address> ",\n "weight": 1\n }\n ],\n "main_purse": "uref-<hash>",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-deploy",children:"Sending the Deploy"}),"\n",(0,s.jsx)(n.p,{children:"Send the Deploy containing your contract with this command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This command execution will output the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," of the applied deploy. We can use the deploy_hash to get the details of the deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-deploy-details",children:"Viewing the Deploy Details"}),"\n",(0,s.jsx)(n.p,{children:"You can view the details of the sent deploy using the command below:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> \\\nb00E59f8aBA5c7aB9.....\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"This contains the header, payment, and session details along with the execution results."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the execution result field appears as ",(0,s.jsx)(n.code,{children:'"execution_results":[]'}),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"querying-contract-entry-points",children:"Querying Contract Entry Points"}),"\n",(0,s.jsx)(n.p,{children:"We will query the argument 'name' in this example."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["You can see that the name is ",(0,s.jsx)(n.code,{children:"CasperTest"})," in this example."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const a={},r=s.createContext(a);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2bd0ed90.2b52c78d.js b/assets/js/2bd0ed90.2b52c78d.js new file mode 100644 index 000000000..a962d0041 --- /dev/null +++ b/assets/js/2bd0ed90.2b52c78d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36595],{95239:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Q",a={id:"concepts/glossary/Q",title:"Q",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Q.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Q",permalink:"/1.5.X/concepts/glossary/Q",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"P",permalink:"/1.5.X/concepts/glossary/P"},next:{title:"R",permalink:"/1.5.X/concepts/glossary/R"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"q",children:"Q"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/2bd0ed90.42d1714b.js b/assets/js/2bd0ed90.42d1714b.js deleted file mode 100644 index 629158717..000000000 --- a/assets/js/2bd0ed90.42d1714b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6595],{95239:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Q",a={id:"concepts/glossary/Q",title:"Q",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Q.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Q",permalink:"/concepts/glossary/Q",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"P",permalink:"/concepts/glossary/P"},next:{title:"R",permalink:"/concepts/glossary/R"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"q",children:"Q"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c04116d.a32622f9.js b/assets/js/2c04116d.a32622f9.js new file mode 100644 index 000000000..cdebcb880 --- /dev/null +++ b/assets/js/2c04116d.a32622f9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37802],{54575:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=r(74848),t=r(28453);const i={},o="Resources Overview",c={id:"resources/index",title:"Resources Overview",description:"Building on Casper",source:"@site/versioned_docs/version-1.5.X/resources/index.md",sourceDirName:"resources",slug:"/resources/",permalink:"/1.5.X/resources/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"resources",next:{title:"Build on Casper",permalink:"/1.5.X/resources/build-on-casper/introduction"}},d={},l=[{value:"Building on Casper",id:"building-on-casper",level:2},{value:"Move to Casper",id:"move-to-casper",level:2},{value:"Tutorials",id:"tutorials",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources-overview",children:"Resources Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"building-on-casper",children:"Building on Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/introduction#wallets",children:"Wallets and Block Explorers"})}),(0,s.jsx)(n.td,{children:"Wallets that support the native Casper token $CSPR"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/introduction#developer-friendly-language",children:"WebAssembly"})}),(0,s.jsx)(n.td,{children:"Learn why WebAssembly is an advantage in contract development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/introduction#powerful-accounts",children:"Accounts"})}),(0,s.jsx)(n.td,{children:"The Casper account-model allowing for multi-signature deploys"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/introduction#development-tools",children:"Developer tools"})}),(0,s.jsx)(n.td,{children:"Available development tools"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Projects"})}),(0,s.jsx)(n.td,{children:"Explore some open-source code available in the Casper ecosystem"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"move-to-casper",children:"Move to Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/moving-to-casper",children:"Move to Casper"})}),(0,s.jsx)(n.td,{children:"Learn how to start working with Casper, having previous knowledge of other blockchains"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/quick-start",children:"Quickstart"})}),(0,s.jsx)(n.td,{children:"Install Rust and setup a Casper environment"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/",children:"Beginner"})}),(0,s.jsx)(n.td,{children:"Learn the basics, such as installing and upgrading contracts"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/",children:"Advanced"})}),(0,s.jsx)(n.td,{children:"Learn about multi-sig, authorization keys, exchange integration, and storage"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},i=s.createContext(t);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c04116d.e52985c2.js b/assets/js/2c04116d.e52985c2.js deleted file mode 100644 index 694fc29cf..000000000 --- a/assets/js/2c04116d.e52985c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7802],{54575:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=r(74848),t=r(28453);const i={},o="Resources Overview",c={id:"resources/index",title:"Resources Overview",description:"Building on Casper",source:"@site/versioned_docs/version-1.5.X/resources/index.md",sourceDirName:"resources",slug:"/resources/",permalink:"/resources/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"resources",next:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"}},d={},l=[{value:"Building on Casper",id:"building-on-casper",level:2},{value:"Move to Casper",id:"move-to-casper",level:2},{value:"Tutorials",id:"tutorials",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources-overview",children:"Resources Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"building-on-casper",children:"Building on Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#wallets",children:"Wallets and Block Explorers"})}),(0,s.jsx)(n.td,{children:"Wallets that support the native Casper token $CSPR"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#developer-friendly-language",children:"WebAssembly"})}),(0,s.jsx)(n.td,{children:"Learn why WebAssembly is an advantage in contract development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#powerful-accounts",children:"Accounts"})}),(0,s.jsx)(n.td,{children:"The Casper account-model allowing for multi-signature deploys"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#development-tools",children:"Developer tools"})}),(0,s.jsx)(n.td,{children:"Available development tools"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Projects"})}),(0,s.jsx)(n.td,{children:"Explore some open-source code available in the Casper ecosystem"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"move-to-casper",children:"Move to Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/moving-to-casper",children:"Move to Casper"})}),(0,s.jsx)(n.td,{children:"Learn how to start working with Casper, having previous knowledge of other blockchains"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/quick-start",children:"Quickstart"})}),(0,s.jsx)(n.td,{children:"Install Rust and setup a Casper environment"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/",children:"Beginner"})}),(0,s.jsx)(n.td,{children:"Learn the basics, such as installing and upgrading contracts"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/tutorials/advanced/",children:"Advanced"})}),(0,s.jsx)(n.td,{children:"Learn about multi-sig, authorization keys, exchange integration, and storage"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},i=s.createContext(t);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c27a7b4.6fa37b9d.js b/assets/js/2c27a7b4.6fa37b9d.js deleted file mode 100644 index 714a9893e..000000000 --- a/assets/js/2c27a7b4.6fa37b9d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4805],{35224:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const i={title:"Move to Casper"},r="Moving to Casper from another Blockchain {#moving-to-casper}",o={id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/docs/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/next/resources/moving-to-casper",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/next/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/next/resources/tokens/"}},c={},l=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"moving-to-casper",children:"Moving to Casper from another Blockchain"})}),"\n",(0,s.jsx)(t.p,{children:"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-overview",children:"Smart Contract Platform Overview"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#variable-storage",children:"Variable Storage and State Management"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-functions",children:"Contract Functions"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#passing-arguments",children:"Passing Arguments"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"#additional-considerations",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"contract-overview",children:"Smart Contract Platform"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"Casper smart contracts are written in Rust."}),"\n",(0,s.jsxs)(t.p,{children:["Variables defined within the smart contract can be stored as either ",(0,s.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#namedkey",children:"Named Keys"})," or ",(0,s.jsx)(t.a,{href:"/next/concepts/dictionaries",children:"Dictionaries"})," as described in ",(0,s.jsx)(t.a,{href:"/next/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"call"})," function serves as the main entry point of the ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"smart contract"}),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."]}),"\n",(0,s.jsxs)(t.p,{children:["It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"All public methods defined within the contract serve as its interface, exposing its functionality."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The Module's public methods are its interface and can be invoked from code outside the blockchain."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Solana smart contracts are primarily written in Rust."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"variable-storage",children:"Variable Storage and State Management"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsxs)(t.p,{children:["Variables can be stored as Named Keys or Dictionaries as described in ",(0,s.jsx)(t.a,{href:"/next/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"contract-functions",children:"Contract Functions"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n \n // Entry point body\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html",children:"RuntimeArgs"})," passed to the contract. Entry points are instantiated within the ",(0,s.jsx)(t.code,{children:"call"})," entry point."]}),"\n",(0,s.jsxs)(t.p,{children:["If a return value is needed, it should be declared using the syntax described in the ",(0,s.jsx)(t.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"runtime::ret(value);\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Each call to an entry point is treated as a ",(0,s.jsx)(t.a,{href:"/next/transactions-and-transaction-lifecycle",children:"Deploy"})," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit)."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The declaration of public methods in Ethereum follows the format:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function update_name(string value) public {\n dapp_name = value;\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"In the Near blockchain, there are three types of public functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Init Methods"})," - These are used as the class constructors to initialize the state of the contract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"View Methods"})," - These functions are used to read the state of the contract variables."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Call Methods"})," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The definition of public methods in Near is as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn add_message(&mut self, ...) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public methods that return variables, the definition would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun start_collection(account: &signer) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public functions that return variables, the definition would be as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun max(a: u8, b: u8): (u8, bool) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In the Aptos blockchain, it is possible to return one or more values from a function."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"entrypoint!(process_instruction);\n"})}),"\n",(0,s.jsx)(t.p,{children:"The implementation of the entry point may resemble the following:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Within the entry point function, the necessary parameters are specified, such as ",(0,s.jsx)(t.code,{children:"program_id"}),", which represents the program's identifier, ",(0,s.jsx)(t.code,{children:"accounts"}),", an array of ",(0,s.jsx)(t.code,{children:"AccountInfo"})," providing account details, and ",(0,s.jsx)(t.code,{children:"_instruction_data"}),", representing the instruction data received. The function returns a ",(0,s.jsx)(t.code,{children:"ProgramResult"}),", which indicates the success or failure of the instruction execution."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"passing-arguments",children:"Passing Arguments"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To understand the context of this example, refer to: ",(0,s.jsx)(t.a,{href:"/next/developers/cli/delegate",children:"Delegating with the Casper Client"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In the contract, you can access the session arguments as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"let uref: URef = runtime::get_key(Key_Name)\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to retrieve the desired session argument by specifying the key's name."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are uncertain how to use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to obtain a specific session argument, check how to ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"write a basic smart contract on Casper"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"additional-considerations",children:"Additional Considerations"}),"\n",(0,s.jsx)(t.p,{children:"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)."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."}),"\n",(0,s.jsx)(t.p,{children:"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},i=s.createContext(a);function r(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2c27a7b4.dfdad9af.js b/assets/js/2c27a7b4.dfdad9af.js new file mode 100644 index 000000000..31c6b1bd1 --- /dev/null +++ b/assets/js/2c27a7b4.dfdad9af.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64805],{35224:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const i={title:"Move to Casper"},r="Moving to Casper from another Blockchain {#moving-to-casper}",o={id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/docs/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/resources/moving-to-casper",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/resources/tokens/"}},c={},l=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"moving-to-casper",children:"Moving to Casper from another Blockchain"})}),"\n",(0,s.jsx)(t.p,{children:"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-overview",children:"Smart Contract Platform Overview"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#variable-storage",children:"Variable Storage and State Management"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-functions",children:"Contract Functions"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#passing-arguments",children:"Passing Arguments"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"#additional-considerations",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"contract-overview",children:"Smart Contract Platform"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"Casper smart contracts are written in Rust."}),"\n",(0,s.jsxs)(t.p,{children:["Variables defined within the smart contract can be stored as either ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:"Named Keys"})," or ",(0,s.jsx)(t.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," as described in ",(0,s.jsx)(t.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"call"})," function serves as the main entry point of the ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"smart contract"}),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."]}),"\n",(0,s.jsxs)(t.p,{children:["It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"All public methods defined within the contract serve as its interface, exposing its functionality."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The Module's public methods are its interface and can be invoked from code outside the blockchain."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Solana smart contracts are primarily written in Rust."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"variable-storage",children:"Variable Storage and State Management"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsxs)(t.p,{children:["Variables can be stored as Named Keys or Dictionaries as described in ",(0,s.jsx)(t.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"contract-functions",children:"Contract Functions"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n \n // Entry point body\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html",children:"RuntimeArgs"})," passed to the contract. Entry points are instantiated within the ",(0,s.jsx)(t.code,{children:"call"})," entry point."]}),"\n",(0,s.jsxs)(t.p,{children:["If a return value is needed, it should be declared using the syntax described in the ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"runtime::ret(value);\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Each call to an entry point is treated as a ",(0,s.jsx)(t.a,{href:"/transactions-and-transaction-lifecycle",children:"Deploy"})," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit)."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The declaration of public methods in Ethereum follows the format:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function update_name(string value) public {\n dapp_name = value;\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"In the Near blockchain, there are three types of public functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Init Methods"})," - These are used as the class constructors to initialize the state of the contract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"View Methods"})," - These functions are used to read the state of the contract variables."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Call Methods"})," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The definition of public methods in Near is as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn add_message(&mut self, ...) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public methods that return variables, the definition would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun start_collection(account: &signer) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public functions that return variables, the definition would be as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun max(a: u8, b: u8): (u8, bool) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In the Aptos blockchain, it is possible to return one or more values from a function."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"entrypoint!(process_instruction);\n"})}),"\n",(0,s.jsx)(t.p,{children:"The implementation of the entry point may resemble the following:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Within the entry point function, the necessary parameters are specified, such as ",(0,s.jsx)(t.code,{children:"program_id"}),", which represents the program's identifier, ",(0,s.jsx)(t.code,{children:"accounts"}),", an array of ",(0,s.jsx)(t.code,{children:"AccountInfo"})," providing account details, and ",(0,s.jsx)(t.code,{children:"_instruction_data"}),", representing the instruction data received. The function returns a ",(0,s.jsx)(t.code,{children:"ProgramResult"}),", which indicates the success or failure of the instruction execution."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"passing-arguments",children:"Passing Arguments"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To understand the context of this example, refer to: ",(0,s.jsx)(t.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper Client"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In the contract, you can access the session arguments as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"let uref: URef = runtime::get_key(Key_Name)\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to retrieve the desired session argument by specifying the key's name."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are uncertain how to use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to obtain a specific session argument, check how to ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"write a basic smart contract on Casper"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"additional-considerations",children:"Additional Considerations"}),"\n",(0,s.jsx)(t.p,{children:"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)."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."}),"\n",(0,s.jsx)(t.p,{children:"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},i=s.createContext(a);function r(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cb8ed3d.81fd42ba.js b/assets/js/2cb8ed3d.81fd42ba.js deleted file mode 100644 index 18afd49ed..000000000 --- a/assets/js/2cb8ed3d.81fd42ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8794],{35946:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>h});var n=r(74848),t=r(28453);const a={},c="R",o={id:"concepts/glossary/R",title:"R",description:"---",source:"@site/docs/concepts/glossary/R.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/R",permalink:"/next/concepts/glossary/R",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"Q",permalink:"/next/concepts/glossary/Q"},next:{title:"S",permalink:"/next/concepts/glossary/S"}},l={},h=[{value:"Reward",id:"reward",level:2},{value:"Root hash",id:"root-hash",level:2},{value:"Rust",id:"rust",level:2},{value:"Rustdocs",id:"rustdocs",level:2}];function i(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"r",children:"R"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"reward",children:"Reward"}),"\n",(0,n.jsxs)(s.p,{children:["Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/D#delegation-rate",children:"delegation rate"}),". Rewards are distributed at the end of each era."]}),"\n",(0,n.jsx)(s.h2,{id:"root-hash",children:"Root hash"}),"\n",(0,n.jsxs)(s.p,{children:["The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/M#merkle-tree",children:"Merkle tree"})," if you wish to learn more."]}),"\n",(0,n.jsx)(s.h2,{id:"rust",children:"Rust"}),"\n",(0,n.jsx)(s.p,{children:"A programming language similar to C++, designed for performance and safety, especially safe concurrency."}),"\n",(0,n.jsx)(s.h2,{id:"rustdocs",children:"Rustdocs"}),"\n",(0,n.jsxs)(s.p,{children:["As part of the Rust development environment, the Rustdocs describe the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-contract/",children:"Casper contracts library"}),", the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-types/",children:"Casper types library"}),", and the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"Casper test support library"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>c,x:()=>o});var n=r(96540);const t={},a=n.createContext(t);function c(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cb8ed3d.cd46c6fa.js b/assets/js/2cb8ed3d.cd46c6fa.js new file mode 100644 index 000000000..af036b137 --- /dev/null +++ b/assets/js/2cb8ed3d.cd46c6fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18794],{35946:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>t,metadata:()=>o,toc:()=>h});var n=r(74848),a=r(28453);const t={},c="R",o={id:"concepts/glossary/R",title:"R",description:"---",source:"@site/docs/concepts/glossary/R.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/R",permalink:"/concepts/glossary/R",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"Q",permalink:"/concepts/glossary/Q"},next:{title:"S",permalink:"/concepts/glossary/S"}},l={},h=[{value:"Reward",id:"reward",level:2},{value:"Root hash",id:"root-hash",level:2},{value:"Rust",id:"rust",level:2},{value:"Rustdocs",id:"rustdocs",level:2}];function i(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"r",children:"R"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"reward",children:"Reward"}),"\n",(0,n.jsxs)(s.p,{children:["Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D#delegation-rate",children:"delegation rate"}),". Rewards are distributed at the end of each era."]}),"\n",(0,n.jsx)(s.h2,{id:"root-hash",children:"Root hash"}),"\n",(0,n.jsxs)(s.p,{children:["The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M#merkle-tree",children:"Merkle tree"})," if you wish to learn more."]}),"\n",(0,n.jsx)(s.h2,{id:"rust",children:"Rust"}),"\n",(0,n.jsx)(s.p,{children:"A programming language similar to C++, designed for performance and safety, especially safe concurrency."}),"\n",(0,n.jsx)(s.h2,{id:"rustdocs",children:"Rustdocs"}),"\n",(0,n.jsxs)(s.p,{children:["As part of the Rust development environment, the Rustdocs describe the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-contract/",children:"Casper contracts library"}),", the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-types/",children:"Casper types library"}),", and the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"Casper test support library"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>c,x:()=>o});var n=r(96540);const a={},t=n.createContext(a);function c(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cc4f81c.309d1501.js b/assets/js/2cc4f81c.309d1501.js new file mode 100644 index 000000000..f482bc297 --- /dev/null +++ b/assets/js/2cc4f81c.309d1501.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91741],{69319:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>h});var t=s(74848),d=s(28453);const c={title:"Hash Types"},r="Understanding Hash Types",i={id:"concepts/hash-types",title:"Hash Types",description:"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.",source:"@site/versioned_docs/version-1.5.X/concepts/hash-types.md",sourceDirName:"concepts",slug:"/concepts/hash-types",permalink:"/1.5.X/concepts/hash-types",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Hash Types"},sidebar:"concepts",previous:{title:"Accounts and Keys",permalink:"/1.5.X/concepts/accounts-and-keys"},next:{title:"Deploy Lifecycle",permalink:"/1.5.X/deploy-and-deploy-lifecycle"}},a={},h=[{value:"Table of Associated Hash Types",id:"table-of-associated-hash-types",level:2},{value:"Hash and Key Explanations",id:"hash-and-key-explanations",level:2}];function o(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"understanding-hash-types",children:"Understanding Hash Types"})}),"\n",(0,t.jsx)(n.p,{children:"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used."}),"\n",(0,t.jsx)(n.h2,{id:"table-of-associated-hash-types",children:"Table of Associated Hash Types"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Prefix"}),(0,t.jsx)(n.th,{children:"Example"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"PublicKey"}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{children:"018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"AccountHash"}),(0,t.jsx)(n.td,{children:"account-hash-"}),(0,t.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"ContractHash"}),(0,t.jsx)(n.td,{children:"contract-"}),(0,t.jsx)(n.td,{children:"contract-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"ContractPackageHash"}),(0,t.jsx)(n.td,{children:"contract-package-"}),(0,t.jsx)(n.td,{children:"contract-package-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Account"}),(0,t.jsx)(n.td,{children:"account-hash-"}),(0,t.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Hash"}),(0,t.jsx)(n.td,{children:"hash-"}),(0,t.jsx)(n.td,{children:"hash-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::URef"}),(0,t.jsx)(n.td,{children:"uref-"}),(0,t.jsx)(n.td,{children:"uref-0101010101010101010101010101010101010101010101010101010101010101-001"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Transfer"}),(0,t.jsx)(n.td,{children:"transfer-"}),(0,t.jsx)(n.td,{children:"transfer-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::DeployInfo"}),(0,t.jsx)(n.td,{children:"deploy-"}),(0,t.jsx)(n.td,{children:"deploy-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::EraInfo"}),(0,t.jsx)(n.td,{children:"era-"}),(0,t.jsx)(n.td,{children:"era-1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Balance"}),(0,t.jsx)(n.td,{children:"balance-"}),(0,t.jsx)(n.td,{children:"balance-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Bid"}),(0,t.jsx)(n.td,{children:"bid-"}),(0,t.jsx)(n.td,{children:"bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Withdraw"}),(0,t.jsx)(n.td,{children:"withdraw-"}),(0,t.jsx)(n.td,{children:"withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Dictionary"}),(0,t.jsx)(n.td,{children:"dictionary-"}),(0,t.jsx)(n.td,{children:"dictionary-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::SystemContractRegistry"}),(0,t.jsx)(n.td,{children:"system-contract-registry-"}),(0,t.jsx)(n.td,{children:"system-contract-registry-00000000000000000000000000000000"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::EraSummary"}),(0,t.jsx)(n.td,{children:"era-summary-"}),(0,t.jsx)(n.td,{children:"era-summary-00000000000000000000000000000000"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"hash-and-key-explanations",children:"Hash and Key Explanations"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"PublicKey"})," is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is ",(0,t.jsx)(n.code,{children:"ed25519"})," or ",(0,t.jsx)(n.code,{children:"secp256k1"}),". There is a third type of ",(0,t.jsx)(n.code,{children:"PublicKey"})," that refers to the system and it is a single ",(0,t.jsx)(n.code,{children:"00"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"AccountHash"})," is a 32 byte hash of the ",(0,t.jsx)(n.code,{children:"PublicKey"})," serving to identify user accounts."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ContractHash"})," is the 32 byte hash of specific smart contract versions. You can use this to call specific contract versions."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ContractPackageHash"})," is a 32 byte hash of the smart contract package. This hash directs you to the contract package. The function ",(0,t.jsx)(n.code,{children:"call_versioned_contract"})," uses ",(0,t.jsx)(n.code,{children:"ContractPackageHash"})," and allows you to call the latest version of the contract (by default). It also allows you to call any version stored previously to the package."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Key"})," is a wrapper type that may contain one of several possible sets of data."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Account"})," contains an AccountHash."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Hash"})," contains a byte array with a length of 32, and as such can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for implementation of any checks necessary on the receiving side."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::URef"})," contains an URef suffixed by access rights."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Transfer"})," should contain the address hash for a transfer."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::DeployInfo"})," retains the address hash of deploy information."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::EraInfo"})," is the integer number of the associated era."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Balance"})," is the balance of a purse."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Bid"})," is used to keep track of bids for the auction contract. It is not generally used by users."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Withdraw"})," is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Dictionary"})," is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::SystemContractRegistry"})," is a unique ",(0,t.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ContractHashes for system contracts, including ",(0,t.jsx)(n.code,{children:"Mint"}),", ",(0,t.jsx)(n.code,{children:"Auction"}),", ",(0,t.jsx)(n.code,{children:"HandlePayment"})," and ",(0,t.jsx)(n.code,{children:"StandardPayment"}),", is stored."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::EraSummary"})," is a ",(0,t.jsx)(n.code,{children:"Key"})," under which we store current era info."]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const d={},c=t.createContext(d);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2cc4f81c.f99f6439.js b/assets/js/2cc4f81c.f99f6439.js deleted file mode 100644 index 2d06daf92..000000000 --- a/assets/js/2cc4f81c.f99f6439.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1741],{69319:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>h});var t=s(74848),d=s(28453);const c={title:"Hash Types"},r="Understanding Hash Types",i={id:"concepts/hash-types",title:"Hash Types",description:"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.",source:"@site/versioned_docs/version-1.5.X/concepts/hash-types.md",sourceDirName:"concepts",slug:"/concepts/hash-types",permalink:"/concepts/hash-types",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Hash Types"},sidebar:"concepts",previous:{title:"Accounts and Keys",permalink:"/concepts/accounts-and-keys"},next:{title:"Deploy Lifecycle",permalink:"/deploy-and-deploy-lifecycle"}},a={},h=[{value:"Table of Associated Hash Types",id:"table-of-associated-hash-types",level:2},{value:"Hash and Key Explanations",id:"hash-and-key-explanations",level:2}];function o(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"understanding-hash-types",children:"Understanding Hash Types"})}),"\n",(0,t.jsx)(n.p,{children:"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used."}),"\n",(0,t.jsx)(n.h2,{id:"table-of-associated-hash-types",children:"Table of Associated Hash Types"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Prefix"}),(0,t.jsx)(n.th,{children:"Example"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"PublicKey"}),(0,t.jsx)(n.td,{}),(0,t.jsx)(n.td,{children:"018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"AccountHash"}),(0,t.jsx)(n.td,{children:"account-hash-"}),(0,t.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"ContractHash"}),(0,t.jsx)(n.td,{children:"contract-"}),(0,t.jsx)(n.td,{children:"contract-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"ContractPackageHash"}),(0,t.jsx)(n.td,{children:"contract-package-"}),(0,t.jsx)(n.td,{children:"contract-package-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Account"}),(0,t.jsx)(n.td,{children:"account-hash-"}),(0,t.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Hash"}),(0,t.jsx)(n.td,{children:"hash-"}),(0,t.jsx)(n.td,{children:"hash-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::URef"}),(0,t.jsx)(n.td,{children:"uref-"}),(0,t.jsx)(n.td,{children:"uref-0101010101010101010101010101010101010101010101010101010101010101-001"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Transfer"}),(0,t.jsx)(n.td,{children:"transfer-"}),(0,t.jsx)(n.td,{children:"transfer-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::DeployInfo"}),(0,t.jsx)(n.td,{children:"deploy-"}),(0,t.jsx)(n.td,{children:"deploy-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::EraInfo"}),(0,t.jsx)(n.td,{children:"era-"}),(0,t.jsx)(n.td,{children:"era-1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Balance"}),(0,t.jsx)(n.td,{children:"balance-"}),(0,t.jsx)(n.td,{children:"balance-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Bid"}),(0,t.jsx)(n.td,{children:"bid-"}),(0,t.jsx)(n.td,{children:"bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Withdraw"}),(0,t.jsx)(n.td,{children:"withdraw-"}),(0,t.jsx)(n.td,{children:"withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::Dictionary"}),(0,t.jsx)(n.td,{children:"dictionary-"}),(0,t.jsx)(n.td,{children:"dictionary-0101010101010101010101010101010101010101010101010101010101010101"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::SystemContractRegistry"}),(0,t.jsx)(n.td,{children:"system-contract-registry-"}),(0,t.jsx)(n.td,{children:"system-contract-registry-00000000000000000000000000000000"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Key::EraSummary"}),(0,t.jsx)(n.td,{children:"era-summary-"}),(0,t.jsx)(n.td,{children:"era-summary-00000000000000000000000000000000"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"hash-and-key-explanations",children:"Hash and Key Explanations"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"PublicKey"})," is a 32 byte asymmetric public key, preceded by a one-byte prefix that tells whether the key is ",(0,t.jsx)(n.code,{children:"ed25519"})," or ",(0,t.jsx)(n.code,{children:"secp256k1"}),". There is a third type of ",(0,t.jsx)(n.code,{children:"PublicKey"})," that refers to the system and it is a single ",(0,t.jsx)(n.code,{children:"00"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"AccountHash"})," is a 32 byte hash of the ",(0,t.jsx)(n.code,{children:"PublicKey"})," serving to identify user accounts."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ContractHash"})," is the 32 byte hash of specific smart contract versions. You can use this to call specific contract versions."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ContractPackageHash"})," is a 32 byte hash of the smart contract package. This hash directs you to the contract package. The function ",(0,t.jsx)(n.code,{children:"call_versioned_contract"})," uses ",(0,t.jsx)(n.code,{children:"ContractPackageHash"})," and allows you to call the latest version of the contract (by default). It also allows you to call any version stored previously to the package."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Key"})," is a wrapper type that may contain one of several possible sets of data."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Account"})," contains an AccountHash."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Hash"})," contains a byte array with a length of 32, and as such can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for implementation of any checks necessary on the receiving side."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::URef"})," contains an URef suffixed by access rights."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Transfer"})," should contain the address hash for a transfer."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::DeployInfo"})," retains the address hash of deploy information."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::EraInfo"})," is the integer number of the associated era."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Balance"})," is the balance of a purse."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Bid"})," is used to keep track of bids for the auction contract. It is not generally used by users."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Withdraw"})," is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::Dictionary"})," is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::SystemContractRegistry"})," is a unique ",(0,t.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ContractHashes for system contracts, including ",(0,t.jsx)(n.code,{children:"Mint"}),", ",(0,t.jsx)(n.code,{children:"Auction"}),", ",(0,t.jsx)(n.code,{children:"HandlePayment"})," and ",(0,t.jsx)(n.code,{children:"StandardPayment"}),", is stored."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Key::EraSummary"})," is a ",(0,t.jsx)(n.code,{children:"Key"})," under which we store current era info."]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const d={},c=t.createContext(d);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d971abe.1121b1e3.js b/assets/js/2d971abe.1121b1e3.js new file mode 100644 index 000000000..535a3ace6 --- /dev/null +++ b/assets/js/2d971abe.1121b1e3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5768],{35040:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Local Network Testing"},o="Testing Smart Contracts with NCTL",a={id:"developers/dapps/nctl-test",title:"Local Network Testing",description:"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.",source:"@site/docs/developers/dapps/nctl-test.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/nctl-test",permalink:"/developers/dapps/nctl-test",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724754971e3,frontMatter:{title:"Local Network Testing"},sidebar:"developers",previous:{title:"Local Network Setup",permalink:"/developers/dapps/setup-nctl"},next:{title:"Monitoring Events with the Casper Sidecar",permalink:"/developers/dapps/monitor-and-consume-events"}},c={},l=[{value:"Getting Started with NCTL",id:"getting-started-with-nctl",level:2},{value:"NCTL Verification Prior to Testing",id:"nctl-verification-prior-to-testing",level:2},{value:"Installing the Smart Contract",id:"installing-the-smart-contract",level:2},{value:"Verifying Transaction Execution",id:"verifying-transaction-execution",level:2},{value:"Interacting with the Installed Contract",id:"interacting-with-the-installed-contract",level:2},{value:"Verifying Correct Contract Behavior",id:"verifying-correct-contract-behavior",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"testing-smart-contracts-with-nctl",children:"Testing Smart Contracts with NCTL"})}),"\n",(0,s.jsxs)(n.p,{children:["NCTL effectively simulates a live Casper network. The process for sending a ",(0,s.jsx)(n.code,{children:"Transaction"})," to an NCTL-based network is therefore similar to doing so on a live network."]}),"\n",(0,s.jsxs)(n.p,{children:["Testing ",(0,s.jsx)(n.code,{children:"Transactions"})," prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"writing your smart contract"})," and testing it ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"using the provided framework"}),", NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code."]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started-with-nctl",children:"Getting Started with NCTL"}),"\n",(0,s.jsxs)(n.p,{children:["Prior to testing a ",(0,s.jsx)(n.code,{children:"Transaction"})," through NCTL, you should have the following steps accomplished:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Completed writing a Transaction"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Tested the Transaction"})," using the Casper testing framework"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"Setup NCTL"})," on your system"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nctl-verification-prior-to-testing",children:"NCTL Verification Prior to Testing"}),"\n",(0,s.jsx)(n.p,{children:"Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-status\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You should see five nodes and instances of sidecar ",(0,s.jsx)(n.code,{children:"RUNNING"})," and five ",(0,s.jsx)(n.code,{children:"STOPPED"}),". Further, verify that the node and user information propagated within the ",(0,s.jsx)(n.em,{children:"casper-node/utils/assets"})," directory. Each node and user should have the associated ",(0,s.jsx)(n.code,{children:"Keys"})," necessary to interact with the network. Run the following command to view first user details:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-view-user-account user=1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-smart-contract",children:"Installing the Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This document assumes that you setup your NCTL network using the standard settings in a directory called ",(0,s.jsx)(n.em,{children:"/casper/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will need the following information to use the ",(0,s.jsx)(n.code,{children:"put-transaction session"})," command:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", in this case ",(0,s.jsx)(n.code,{children:"casper-net-1"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"secret key"})," of the account sending the ",(0,s.jsx)(n.code,{children:"Transaction"}),". For this example, we are using node-1 as the sender. The secret key file can be found at ",(0,s.jsx)(n.em,{children:"casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". In our example put-transaction, this will appear as ",(0,s.jsx)(n.code,{children:"--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". If your Transaction is more complex and requires multiple accounts, NCTL also establishes multiple users for testing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"pricing mode"})," for this transaction. In this case, we are using the ",(0,s.jsx)(n.code,{children:"fixed"})," pricing mode."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--gas-price-tolerance 10"}),". ",(0,s.jsxs)(n.strong,{children:["NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions#a-note-about-gas-price",children:"note about gas prices"}),"."]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"path"})," to your ",(0,s.jsx)(n.code,{children:"Transaction"})," that you wish to send to the NCTL network. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--transaction-path <PATH>"})," and will require you to define the path to your specific ",(0,s.jsx)(n.code,{children:"Transaction"})," Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"category"})," of the transaction, based on the size of the Wasm included. ",(0,s.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,s.jsx)(n.code,{children:"large"}),", ",(0,s.jsx)(n.code,{children:"medium"}),", and ",(0,s.jsx)(n.code,{children:"small"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--category 'install-upgrade'"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"session entry point"}),", which at installation time is usually ",(0,s.jsx)(n.code,{children:"call"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"})," for a node on your NCTL network. In this example, we are using the node at ",(0,s.jsx)(n.code,{children:"http://localhost:11101"}),". On the Casper Mainnet or Testnet, nodes will use port ",(0,s.jsx)(n.code,{children:"7777"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--node-address http://<HOST>:7777"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command to send your ",(0,s.jsx)(n.code,{children:"Transaction"})," should look similar to the following code snippet:"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Use of the ",(0,s.jsx)(n.code,{children:"$(get_path_to_client)"})," command assumes that you are operating in an activated NCTL environment."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) put-transaction session \\\n--chain-name \"casper-net-1\" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path <PATH> \\\n--category 'install-upgrade' \\\n--session-entry-point call \\\n--node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The response will return something similar to the following information. Note the ",(0,s.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-transaction-execution",children:"Verifying Transaction Execution"}),"\n",(0,s.jsxs)(n.p,{children:["The previous command sent the ",(0,s.jsx)(n.code,{children:"Transaction"})," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,s.jsx)(n.code,{children:"transaction_hash"})," received in the response allows you to query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status."]}),"\n",(0,s.jsxs)(n.p,{children:["To query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status, you will pass both the ",(0,s.jsx)(n.code,{children:"transaction_hash"})," and the same ",(0,s.jsx)(n.code,{children:"node-address"})," from above using the following command. This will return either an error message in the event of failure or the ",(0,s.jsx)(n.code,{children:"Transaction"})," details if it succeeds."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-transaction efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e -n http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interacting-with-the-installed-contract",children:"Interacting with the Installed Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Once your NCTL network executes your ",(0,s.jsx)(n.code,{children:"Transaction"}),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,s.jsx)(n.code,{children:"PackageHash"})," itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,s.jsxs)(n.a,{href:"/developers/cli/sending-transactions",children:["send the ",(0,s.jsx)(n.code,{children:"Transaction"})]}),", we can retrieve the ",(0,s.jsx)(n.code,{children:"PackageHash"})," from the node-1 account information. To do so, we will use the following NCTL command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This will return the NCTL faucet account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"AccountHash"}),". We can then query the ",(0,s.jsx)(n.code,{children:"PublicKey"})," using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) query-global-state \\\n--node-address http://localhost:11101 \\\n--key <PUBLIC KEY> \\\n--state-root-hash <STATE ROOT HASH>\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["You can retrieve the current state root hash using the command ",(0,s.jsx)(n.code,{children:"casper client get-state-root-hash"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return an ",(0,s.jsx)(n.code,{children:"entity-account-"})," value that you can use as an entity identifier in the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier <ENTITY IDENTIFIER>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return information pertaining to the account, including the ",(0,s.jsx)(n.code,{children:"NamedKeys"}),". The ",(0,s.jsx)(n.code,{children:"PackageHash"})," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,s.jsx)(n.code,{children:"Transaction"}),". In this instance, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--node-address http://localhost:11101"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"package hash"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})," on the contract that you wish to invoke."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.strong,{children:"session arguments"})," specific to the contract that you are testing. Multiple instances of ",(0,s.jsx)(n.code,{children:"--session-arg"})," may be used as necessary to provide values to the contract. In the example below, you will see a demonstration of a session arg of ",(0,s.jsx)(n.code,{children:"amount"})," as ",(0,s.jsx)(n.code,{children:"--session-arg \"amount:u256='100'\""}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$(get_path_to_client) put-transaction package \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4 \\ \n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--session-arg "amount:u256=\'100\'"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-correct-contract-behavior",children:"Verifying Correct Contract Behavior"}),"\n",(0,s.jsxs)(n.p,{children:["After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,s.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"global state"}),". Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the ",(0,s.jsx)(n.a,{href:"/resources/beginner/counter/walkthrough",children:"basic counter contract tutorial"}),", the NCTL process would have the following flow:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Send a ",(0,s.jsx)(n.code,{children:"Transaction"}),' to install the "Counter" smart contract.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Verify the execution of the ",(0,s.jsx)(n.code,{children:"Transaction"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Interact with the installed contract package using an additional ",(0,s.jsx)(n.code,{children:"Transaction"})," that calls one or several of the entry points. For example, calling the ",(0,s.jsx)(n.code,{children:"increment"})," entry point to increase the counter by one."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify the associated change in global state. Namely, an increase in the counter."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2d971abe.26e71149.js b/assets/js/2d971abe.26e71149.js deleted file mode 100644 index f365d85b2..000000000 --- a/assets/js/2d971abe.26e71149.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5768],{35040:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Local Network Testing"},o="Testing Smart Contracts with NCTL",a={id:"developers/dapps/nctl-test",title:"Local Network Testing",description:"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.",source:"@site/docs/developers/dapps/nctl-test.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/nctl-test",permalink:"/next/developers/dapps/nctl-test",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724754971e3,frontMatter:{title:"Local Network Testing"},sidebar:"developers",previous:{title:"Local Network Setup",permalink:"/next/developers/dapps/setup-nctl"},next:{title:"Monitoring Events with the Casper Sidecar",permalink:"/next/developers/dapps/monitor-and-consume-events"}},c={},l=[{value:"Getting Started with NCTL",id:"getting-started-with-nctl",level:2},{value:"NCTL Verification Prior to Testing",id:"nctl-verification-prior-to-testing",level:2},{value:"Installing the Smart Contract",id:"installing-the-smart-contract",level:2},{value:"Verifying Transaction Execution",id:"verifying-transaction-execution",level:2},{value:"Interacting with the Installed Contract",id:"interacting-with-the-installed-contract",level:2},{value:"Verifying Correct Contract Behavior",id:"verifying-correct-contract-behavior",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"testing-smart-contracts-with-nctl",children:"Testing Smart Contracts with NCTL"})}),"\n",(0,s.jsxs)(n.p,{children:["NCTL effectively simulates a live Casper network. The process for sending a ",(0,s.jsx)(n.code,{children:"Transaction"})," to an NCTL-based network is therefore similar to doing so on a live network."]}),"\n",(0,s.jsxs)(n.p,{children:["Testing ",(0,s.jsx)(n.code,{children:"Transactions"})," prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"writing your smart contract"})," and testing it ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"using the provided framework"}),", NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code."]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started-with-nctl",children:"Getting Started with NCTL"}),"\n",(0,s.jsxs)(n.p,{children:["Prior to testing a ",(0,s.jsx)(n.code,{children:"Transaction"})," through NCTL, you should have the following steps accomplished:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Completed writing a Transaction"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"Tested the Transaction"})," using the Casper testing framework"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/next/developers/dapps/setup-nctl",children:"Setup NCTL"})," on your system"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nctl-verification-prior-to-testing",children:"NCTL Verification Prior to Testing"}),"\n",(0,s.jsx)(n.p,{children:"Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-status\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You should see five nodes and instances of sidecar ",(0,s.jsx)(n.code,{children:"RUNNING"})," and five ",(0,s.jsx)(n.code,{children:"STOPPED"}),". Further, verify that the node and user information propagated within the ",(0,s.jsx)(n.em,{children:"casper-node/utils/assets"})," directory. Each node and user should have the associated ",(0,s.jsx)(n.code,{children:"Keys"})," necessary to interact with the network. Run the following command to view first user details:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-view-user-account user=1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-smart-contract",children:"Installing the Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This document assumes that you setup your NCTL network using the standard settings in a directory called ",(0,s.jsx)(n.em,{children:"/casper/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will need the following information to use the ",(0,s.jsx)(n.code,{children:"put-transaction session"})," command:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", in this case ",(0,s.jsx)(n.code,{children:"casper-net-1"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"secret key"})," of the account sending the ",(0,s.jsx)(n.code,{children:"Transaction"}),". For this example, we are using node-1 as the sender. The secret key file can be found at ",(0,s.jsx)(n.em,{children:"casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". In our example put-transaction, this will appear as ",(0,s.jsx)(n.code,{children:"--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". If your Transaction is more complex and requires multiple accounts, NCTL also establishes multiple users for testing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"pricing mode"})," for this transaction. In this case, we are using the ",(0,s.jsx)(n.code,{children:"fixed"})," pricing mode."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--gas-price-tolerance 10"}),". ",(0,s.jsxs)(n.strong,{children:["NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our ",(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions#a-note-about-gas-price",children:"note about gas prices"}),"."]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"path"})," to your ",(0,s.jsx)(n.code,{children:"Transaction"})," that you wish to send to the NCTL network. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--transaction-path <PATH>"})," and will require you to define the path to your specific ",(0,s.jsx)(n.code,{children:"Transaction"})," Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"category"})," of the transaction, based on the size of the Wasm included. ",(0,s.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,s.jsx)(n.code,{children:"large"}),", ",(0,s.jsx)(n.code,{children:"medium"}),", and ",(0,s.jsx)(n.code,{children:"small"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--category 'install-upgrade'"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"session entry point"}),", which at installation time is usually ",(0,s.jsx)(n.code,{children:"call"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"})," for a node on your NCTL network. In this example, we are using the node at ",(0,s.jsx)(n.code,{children:"http://localhost:11101"}),". On the Casper Mainnet or Testnet, nodes will use port ",(0,s.jsx)(n.code,{children:"7777"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--node-address http://<HOST>:7777"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command to send your ",(0,s.jsx)(n.code,{children:"Transaction"})," should look similar to the following code snippet:"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Use of the ",(0,s.jsx)(n.code,{children:"$(get_path_to_client)"})," command assumes that you are operating in an activated NCTL environment."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) put-transaction session \\\n--chain-name \"casper-net-1\" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path <PATH> \\\n--category 'install-upgrade' \\\n--session-entry-point call \\\n--node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The response will return something similar to the following information. Note the ",(0,s.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-transaction-execution",children:"Verifying Transaction Execution"}),"\n",(0,s.jsxs)(n.p,{children:["The previous command sent the ",(0,s.jsx)(n.code,{children:"Transaction"})," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,s.jsx)(n.code,{children:"transaction_hash"})," received in the response allows you to query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status."]}),"\n",(0,s.jsxs)(n.p,{children:["To query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status, you will pass both the ",(0,s.jsx)(n.code,{children:"transaction_hash"})," and the same ",(0,s.jsx)(n.code,{children:"node-address"})," from above using the following command. This will return either an error message in the event of failure or the ",(0,s.jsx)(n.code,{children:"Transaction"})," details if it succeeds."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-transaction efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e -n http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interacting-with-the-installed-contract",children:"Interacting with the Installed Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Once your NCTL network executes your ",(0,s.jsx)(n.code,{children:"Transaction"}),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,s.jsx)(n.code,{children:"PackageHash"})," itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,s.jsxs)(n.a,{href:"/next/developers/cli/sending-transactions",children:["send the ",(0,s.jsx)(n.code,{children:"Transaction"})]}),", we can retrieve the ",(0,s.jsx)(n.code,{children:"PackageHash"})," from the node-1 account information. To do so, we will use the following NCTL command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This will return the NCTL faucet account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"AccountHash"}),". We can then query the ",(0,s.jsx)(n.code,{children:"PublicKey"})," using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) query-global-state \\\n--node-address http://localhost:11101 \\\n--key <PUBLIC KEY> \\\n--state-root-hash <STATE ROOT HASH>\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["You can retrieve the current state root hash using the command ",(0,s.jsx)(n.code,{children:"casper client get-state-root-hash"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return an ",(0,s.jsx)(n.code,{children:"entity-account-"})," value that you can use as an entity identifier in the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier <ENTITY IDENTIFIER>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return information pertaining to the account, including the ",(0,s.jsx)(n.code,{children:"NamedKeys"}),". The ",(0,s.jsx)(n.code,{children:"PackageHash"})," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,s.jsx)(n.code,{children:"Transaction"}),". In this instance, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--node-address http://localhost:11101"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"package hash"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})," on the contract that you wish to invoke."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.strong,{children:"session arguments"})," specific to the contract that you are testing. Multiple instances of ",(0,s.jsx)(n.code,{children:"--session-arg"})," may be used as necessary to provide values to the contract. In the example below, you will see a demonstration of a session arg of ",(0,s.jsx)(n.code,{children:"amount"})," as ",(0,s.jsx)(n.code,{children:"--session-arg \"amount:u256='100'\""}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$(get_path_to_client) put-transaction package \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4 \\ \n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--session-arg "amount:u256=\'100\'"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-correct-contract-behavior",children:"Verifying Correct Contract Behavior"}),"\n",(0,s.jsxs)(n.p,{children:["After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,s.jsx)(n.a,{href:"/next/developers/cli/installing-contracts#querying-global-state",children:"global state"}),". Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the ",(0,s.jsx)(n.a,{href:"/next/resources/beginner/counter/walkthrough",children:"basic counter contract tutorial"}),", the NCTL process would have the following flow:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Send a ",(0,s.jsx)(n.code,{children:"Transaction"}),' to install the "Counter" smart contract.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Verify the execution of the ",(0,s.jsx)(n.code,{children:"Transaction"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Interact with the installed contract package using an additional ",(0,s.jsx)(n.code,{children:"Transaction"})," that calls one or several of the entry points. For example, calling the ",(0,s.jsx)(n.code,{children:"increment"})," entry point to increase the counter by one."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify the associated change in global state. Namely, an increase in the counter."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e4bdb60.94cd32d7.js b/assets/js/2e4bdb60.94cd32d7.js new file mode 100644 index 000000000..3813017c2 --- /dev/null +++ b/assets/js/2e4bdb60.94cd32d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74586],{476:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const t={title:"Glossary",slug:"/glossary"},o="Glossary",a={id:"concepts/glossary/index",title:"Glossary",description:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.",source:"@site/docs/concepts/glossary/index.md",sourceDirName:"concepts/glossary",slug:"/glossary",permalink:"/glossary",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Glossary",slug:"/glossary"},sidebar:"concepts",previous:{title:"Staking",permalink:"/concepts/economics/staking"},next:{title:"A",permalink:"/concepts/glossary/A"}},l={},i=[];function h(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,n.jsx)(e.p,{children:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts."}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>o,x:()=>a});var n=r(96540);const c={},t=n.createContext(c);function o(s){const e=n.useContext(t);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:o(s.components),n.createElement(t.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/2e4bdb60.fa0d0d8f.js b/assets/js/2e4bdb60.fa0d0d8f.js deleted file mode 100644 index 51c35eef5..000000000 --- a/assets/js/2e4bdb60.fa0d0d8f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4586],{476:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>x,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var t=n(74848),r=n(28453);const c={title:"Glossary",slug:"/glossary"},o="Glossary",a={id:"concepts/glossary/index",title:"Glossary",description:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.",source:"@site/docs/concepts/glossary/index.md",sourceDirName:"concepts/glossary",slug:"/glossary",permalink:"/next/glossary",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Glossary",slug:"/glossary"},sidebar:"concepts",previous:{title:"Staking",permalink:"/next/concepts/economics/staking"},next:{title:"A",permalink:"/next/concepts/glossary/A"}},l={},i=[];function h(e){const s={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,t.jsx)(s.p,{children:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts."}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{})]})}function x(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const r={},c=t.createContext(r);function o(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2fb5589e.18083c1f.js b/assets/js/2fb5589e.18083c1f.js deleted file mode 100644 index a9cc732c9..000000000 --- a/assets/js/2fb5589e.18083c1f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3213],{91376:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var r=s(74848),n=s(28453);const i={title:"Introduction"},o="The Native Multi-Signature Feature",a={id:"resources/advanced/multi-sig/index",title:"Introduction",description:"In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.",source:"@site/docs/resources/advanced/multi-sig/index.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/",permalink:"/next/resources/advanced/multi-sig/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Introduction"},sidebar:"tutorials",previous:{title:"Two-Party Multi-Sig",permalink:"/next/resources/tutorials/advanced/two-party-multi-sig"},next:{title:"Multi-Sig Workflow",permalink:"/next/resources/advanced/multi-sig/multi-sig-workflow"}},u={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-native-multi-signature-feature",children:"The Native Multi-Signature Feature"})}),"\n",(0,r.jsxs)(t.p,{children:["In this ",(0,r.jsx)(t.a,{href:"/next/resources/advanced/multi-sig/multi-sig-workflow",children:"tutorial"}),", you will use ",(0,r.jsx)(t.a,{href:"/next/concepts/design/casper-design#accounts-permissions",children:"Casper's permissions model"})," to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/next/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," present use cases where Casper's multi-signature feature would be helpful."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var r=s(96540);const n={},i=r.createContext(n);function o(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2fb5589e.7b8c9375.js b/assets/js/2fb5589e.7b8c9375.js new file mode 100644 index 000000000..ea9d02c2c --- /dev/null +++ b/assets/js/2fb5589e.7b8c9375.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73213],{91376:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var r=s(74848),i=s(28453);const n={title:"Introduction"},o="The Native Multi-Signature Feature",a={id:"resources/advanced/multi-sig/index",title:"Introduction",description:"In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.",source:"@site/docs/resources/advanced/multi-sig/index.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/",permalink:"/resources/advanced/multi-sig/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Introduction"},sidebar:"tutorials",previous:{title:"Two-Party Multi-Sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig"},next:{title:"Multi-Sig Workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow"}},u={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-native-multi-signature-feature",children:"The Native Multi-Signature Feature"})}),"\n",(0,r.jsxs)(t.p,{children:["In this ",(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/multi-sig-workflow",children:"tutorial"}),", you will use ",(0,r.jsx)(t.a,{href:"/concepts/design/casper-design#accounts-permissions",children:"Casper's permissions model"})," to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," present use cases where Casper's multi-signature feature would be helpful."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var r=s(96540);const i={},n=r.createContext(i);function o(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2fe2b30f.134c1dc9.js b/assets/js/2fe2b30f.134c1dc9.js new file mode 100644 index 000000000..792f2d9e4 --- /dev/null +++ b/assets/js/2fe2b30f.134c1dc9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61109],{62121:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const t={},o="M",a={id:"concepts/glossary/M",title:"M",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/M.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/M",permalink:"/2.0.0/concepts/glossary/M",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"L",permalink:"/2.0.0/concepts/glossary/L"},next:{title:"N",permalink:"/2.0.0/concepts/glossary/N"}},l={},i=[{value:"Mainnet",id:"mainnet",level:2},{value:"Merkle tree",id:"merkle-tree",level:2},{value:"Motes",id:"motes",level:2},{value:"Multi-Sig",id:"multisig",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"m",children:"M"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"mainnet",children:"Mainnet"}),"\n",(0,n.jsx)(s.p,{children:"The live, decentralized, and public Casper platform, with version 1.0."}),"\n",(0,n.jsx)(s.h2,{id:"merkle-tree",children:"Merkle tree"}),"\n",(0,n.jsx)(s.p,{children:"A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes."}),"\n",(0,n.jsx)(s.h2,{id:"motes",children:"Motes"}),"\n",(0,n.jsxs)(s.p,{children:["A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#cspr",children:"CSPR"})," token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes."]}),"\n",(0,n.jsx)(s.h2,{id:"multisig",children:"Multi-Sig"}),"\n",(0,n.jsxs)(s.p,{children:["Short for ",(0,n.jsx)(s.code,{children:"Multi-Signature"}),". Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found ",(0,n.jsx)(s.a,{href:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const c={},t=n.createContext(c);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ffce966.32a561e7.js b/assets/js/2ffce966.32a561e7.js new file mode 100644 index 000000000..e1fa3a31b --- /dev/null +++ b/assets/js/2ffce966.32a561e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66552],{25255:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Transferring Tokens"},a="Transferring Tokens with the Casper CLI Client",o={id:"developers/cli/transfers/index",title:"Transferring Tokens",description:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.",source:"@site/docs/developers/cli/transfers/index.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/",permalink:"/developers/cli/transfers/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Transferring Tokens"},sidebar:"developers",previous:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"},next:{title:"Direct Token Transfer",permalink:"/developers/cli/transfers/direct-token-transfer"}},c={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-with-the-casper-cli-client",children:"Transferring Tokens with the Casper CLI Client"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a direct transfer"})}),"\n",(0,t.jsxs)(n.p,{children:["Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Transferring Tokens Using Direct Transfer"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a multi-sig tranasction"})}),"\n",(0,t.jsxs)(n.p,{children:["Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature transactions"})," workflow. To use a multi-sig transaction transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Transferring Tokens Using a Multi-sig Account"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verifying a transfer using the command-line client"})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the status of a transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]})]})}function f(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var t=r(96540);const s={},i=t.createContext(s);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/2ffce966.af34eb97.js b/assets/js/2ffce966.af34eb97.js deleted file mode 100644 index 9cf3db65c..000000000 --- a/assets/js/2ffce966.af34eb97.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6552],{25255:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var r=t(74848),s=t(28453);const i={title:"Transferring Tokens"},a="Transferring Tokens with the Casper CLI Client",o={id:"developers/cli/transfers/index",title:"Transferring Tokens",description:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.",source:"@site/docs/developers/cli/transfers/index.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/",permalink:"/next/developers/cli/transfers/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Transferring Tokens"},sidebar:"developers",previous:{title:"Interacting with the Blockchain",permalink:"/next/developers/cli/"},next:{title:"Direct Token Transfer",permalink:"/next/developers/cli/transfers/direct-token-transfer"}},c={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"transferring-tokens-with-the-casper-cli-client",children:"Transferring Tokens with the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized."}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Transferring tokens using a direct transfer"})}),"\n",(0,r.jsxs)(n.p,{children:["Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see ",(0,r.jsx)(n.a,{href:"/next/developers/cli/transfers/direct-token-transfer",children:"Transferring Tokens Using Direct Transfer"}),"."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Transferring tokens using a multi-sig tranasction"})}),"\n",(0,r.jsxs)(n.p,{children:["Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the ",(0,r.jsx)(n.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature transactions"})," workflow. To use a multi-sig transaction transfer, see ",(0,r.jsx)(n.a,{href:"/next/developers/cli/transfers/multisig-deploy-transfer",children:"Transferring Tokens Using a Multi-sig Account"}),"."]}),"\n",(0,r.jsx)(n.p,{children:(0,r.jsx)(n.strong,{children:"Verifying a transfer using the command-line client"})}),"\n",(0,r.jsxs)(n.p,{children:["To verify the status of a transfer, see ",(0,r.jsx)(n.a,{href:"/next/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]})]})}function f(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31722bc4.8b17745a.js b/assets/js/31722bc4.8b17745a.js new file mode 100644 index 000000000..124499295 --- /dev/null +++ b/assets/js/31722bc4.8b17745a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91961],{45539:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var r=n(74848),i=n(28453);const a={title:"Sidecar Setup"},t="The Casper Sidecar",c={id:"operators/setup/casper-sidecar",title:"Sidecar Setup",description:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:",source:"@site/docs/operators/setup/casper-sidecar.md",sourceDirName:"operators/setup",slug:"/operators/setup/casper-sidecar",permalink:"/operators/setup/casper-sidecar",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Sidecar Setup"},sidebar:"operators",previous:{title:"Node Events",permalink:"/operators/setup/node-events"},next:{title:"Becoming a Validator",permalink:"/operators/becoming-a-validator/"}},d={},o=[{value:"Configuring the Sidecar Service",id:"configuring-the-sidecar",level:2},{value:"Installing the Sidecar",id:"installing-the-sidecar",level:2},{value:"Monitoring the Installation",id:"monitoring-the-sidecar",level:3},{value:"The Admin Server",id:"the-admin-server",level:2},{value:"Swagger Documentation",id:"swagger-documentation",level:2},{value:"OpenAPI Specification",id:"openapi-specification",level:2},{value:"Using the Sidecar",id:"using-the-sidecar",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function l(e){const s={a:"a",b:"b",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"the-casper-sidecar",children:"The Casper Sidecar"})}),"\n",(0,r.jsx)(s.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,r.jsx)(s.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Visit GitHub for the latest source code and information on ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"system architecture"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configurations"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"testing"})," and ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"troubleshooting"}),"."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Sidecar components and architecture diagram",src:n(66e3).A+"",width:"1416",height:"978"})}),"\n",(0,r.jsx)(s.h2,{id:"configuring-the-sidecar",children:"Configuring the Sidecar Service"}),"\n",(0,r.jsxs)(s.p,{children:["Operators need to update the Sidecar configuration file according to their needs. Detailed configuration instructions are available in ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/ETC_README.md",children:"GitHub"}),". Further details regarding each ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configuration option"})," are available in GitHub."]}),"\n",(0,r.jsx)(s.h2,{id:"installing-the-sidecar",children:"Installing the Sidecar"}),"\n",(0,r.jsx)(s.p,{children:"The following command will install the Debian package for the Casper Sidecar service on various Linux flavors."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo apt install ./casper-sidecar_0.1.0-0_amd64.deb\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Reading package lists... Done\nBuilding dependency tree \nReading state information... Done\nNote, selecting 'casper-sidecar' instead of './casper-sidecar_0.1.0-0_amd64.deb'\nThe following NEW packages will be installed:\n casper-sidecar\n0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.\nNeed to get 0 B/4162 kB of archives.\nAfter this operation, 20.2 MB of additional disk space will be used.\nGet:1 /home/ubuntu/casper-sidecar_0.1.0-0_amd64.deb casper-sidecar amd64 0.1.0-0 [4162 kB]\nSelecting previously unselected package casper-sidecar.\n(Reading database ... 102241 files and directories currently installed.)\nPreparing to unpack .../casper-sidecar_0.1.0-0_amd64.deb ...\nUnpacking casper-sidecar (0.1.0-0) ...\nSetting up casper-sidecar (0.1.0-0) ...\nAdding system user `csidecar' (UID 114) ...\nAdding new group `csidecar' (GID 120) ...\nAdding new user `csidecar' (UID 114) with group `csidecar' ...\nNot creating home directory `/home/csidecar'.\nCreated symlink /etc/systemd/system/multi-user.target.wants/casper-sidecar.service \u2192 /lib/systemd/system/casper-sidecar.service.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.h3,{id:"monitoring-the-sidecar",children:"Monitoring the Installation"}),"\n",(0,r.jsx)(s.p,{children:"Check the service status:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"systemctl status casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"casper-sidecar.service - Casper Event Sidecar\n Loaded: loaded (/lib/systemd/system/casper-sidecar.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-12-07 20:33:29 UTC; 1min 3s ago\n Docs: https://docs.casperlabs.io\n Main PID: 16707 (casper-si)\n Tasks: 5 (limit: 9401)\n Memory: 7.1M\n CGroup: /system.slice/casper-sidecar.service\n \u2514\u250016707 /usr/bin/casper-sidecar /etc/casper-sidecar/config.toml\n\nDec 07 20:33:29 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.p,{children:"Check the logs and make sure the service is running as expected."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"journalctl --no-pager -u casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Dec 05 17:24:53 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsxs)(s.p,{children:["If you see any errors, you may need to ",(0,r.jsx)(s.a,{href:"#configuring-the-service",children:"update the configuration"})," and restart the service with the commands below."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Stopping the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl stop casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Starting the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl start casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.h2,{id:"the-admin-server",children:"The Admin Server"}),"\n",(0,r.jsxs)(s.p,{children:["If enabled, the Sidecar's administrative API can be accessed using the following command. The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18887"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"http://localhost:PORT/metrics/\n"})}),"\n",(0,r.jsx)(s.h2,{id:"swagger-documentation",children:"Swagger Documentation"}),"\n",(0,r.jsxs)(s.p,{children:["You can access the Swagger documentation at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/swagger-ui/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"openapi-specification",children:"OpenAPI Specification"}),"\n",(0,r.jsxs)(s.p,{children:["An OpenAPI schema is available at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/api-doc.json/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"using-the-sidecar",children:"Using the Sidecar"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes how to consume events and perform queries using the Sidecar, covering the following topics:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Node-generated events emitted by the node(s) to which the Sidecar connects"}),"\n",(0,r.jsx)(s.li,{children:"Sidecar-generated events originating solely from the Sidecar service and not from a node"}),"\n",(0,r.jsx)(s.li,{children:"The RESTful endpoint for performing useful queries about the state of the network"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,r.jsxs)(s.p,{children:["For troubleshooting tips, visit ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},66e3:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var r=n(96540);const i={},a=r.createContext(i);function t(e){const s=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31722bc4.9f4ab15b.js b/assets/js/31722bc4.9f4ab15b.js deleted file mode 100644 index 20bd16d7c..000000000 --- a/assets/js/31722bc4.9f4ab15b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1961],{45539:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>t,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>o});var r=n(74848),i=n(28453);const a={title:"Sidecar Setup"},t="The Casper Sidecar",c={id:"operators/setup/casper-sidecar",title:"Sidecar Setup",description:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:",source:"@site/docs/operators/setup/casper-sidecar.md",sourceDirName:"operators/setup",slug:"/operators/setup/casper-sidecar",permalink:"/next/operators/setup/casper-sidecar",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Sidecar Setup"},sidebar:"operators",previous:{title:"Node Events",permalink:"/next/operators/setup/node-events"},next:{title:"Becoming a Validator",permalink:"/next/operators/becoming-a-validator/"}},d={},o=[{value:"Configuring the Sidecar Service",id:"configuring-the-sidecar",level:2},{value:"Installing the Sidecar",id:"installing-the-sidecar",level:2},{value:"Monitoring the Installation",id:"monitoring-the-sidecar",level:3},{value:"The Admin Server",id:"the-admin-server",level:2},{value:"Swagger Documentation",id:"swagger-documentation",level:2},{value:"OpenAPI Specification",id:"openapi-specification",level:2},{value:"Using the Sidecar",id:"using-the-sidecar",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function l(e){const s={a:"a",b:"b",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"the-casper-sidecar",children:"The Casper Sidecar"})}),"\n",(0,r.jsx)(s.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,r.jsx)(s.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,r.jsxs)(s.li,{children:["A ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Visit GitHub for the latest source code and information on ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"system architecture"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configurations"}),", ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"testing"})," and ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"troubleshooting"}),"."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.img,{alt:"Sidecar components and architecture diagram",src:n(6874).A+"",width:"1416",height:"978"})}),"\n",(0,r.jsx)(s.h2,{id:"configuring-the-sidecar",children:"Configuring the Sidecar Service"}),"\n",(0,r.jsxs)(s.p,{children:["Operators need to update the Sidecar configuration file according to their needs. Detailed configuration instructions are available in ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/ETC_README.md",children:"GitHub"}),". Further details regarding each ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"configuration option"})," are available in GitHub."]}),"\n",(0,r.jsx)(s.h2,{id:"installing-the-sidecar",children:"Installing the Sidecar"}),"\n",(0,r.jsx)(s.p,{children:"The following command will install the Debian package for the Casper Sidecar service on various Linux flavors."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo apt install ./casper-sidecar_0.1.0-0_amd64.deb\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Reading package lists... Done\nBuilding dependency tree \nReading state information... Done\nNote, selecting 'casper-sidecar' instead of './casper-sidecar_0.1.0-0_amd64.deb'\nThe following NEW packages will be installed:\n casper-sidecar\n0 upgraded, 1 newly installed, 0 to remove and 18 not upgraded.\nNeed to get 0 B/4162 kB of archives.\nAfter this operation, 20.2 MB of additional disk space will be used.\nGet:1 /home/ubuntu/casper-sidecar_0.1.0-0_amd64.deb casper-sidecar amd64 0.1.0-0 [4162 kB]\nSelecting previously unselected package casper-sidecar.\n(Reading database ... 102241 files and directories currently installed.)\nPreparing to unpack .../casper-sidecar_0.1.0-0_amd64.deb ...\nUnpacking casper-sidecar (0.1.0-0) ...\nSetting up casper-sidecar (0.1.0-0) ...\nAdding system user `csidecar' (UID 114) ...\nAdding new group `csidecar' (GID 120) ...\nAdding new user `csidecar' (UID 114) with group `csidecar' ...\nNot creating home directory `/home/csidecar'.\nCreated symlink /etc/systemd/system/multi-user.target.wants/casper-sidecar.service \u2192 /lib/systemd/system/casper-sidecar.service.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.h3,{id:"monitoring-the-sidecar",children:"Monitoring the Installation"}),"\n",(0,r.jsx)(s.p,{children:"Check the service status:"}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"systemctl status casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"casper-sidecar.service - Casper Event Sidecar\n Loaded: loaded (/lib/systemd/system/casper-sidecar.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-12-07 20:33:29 UTC; 1min 3s ago\n Docs: https://docs.casperlabs.io\n Main PID: 16707 (casper-si)\n Tasks: 5 (limit: 9401)\n Memory: 7.1M\n CGroup: /system.slice/casper-sidecar.service\n \u2514\u250016707 /usr/bin/casper-sidecar /etc/casper-sidecar/config.toml\n\nDec 07 20:33:29 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsx)(s.p,{children:"Check the logs and make sure the service is running as expected."}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"journalctl --no-pager -u casper-sidecar\n"})}),"\n",(0,r.jsxs)(s.details,{children:["\n",(0,r.jsx)(s.summary,{children:(0,r.jsx)(s.b,{children:"Sample output"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"Dec 05 17:24:53 user systemd[1]: Started Casper Event Sidecar.\n"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.br,{}),(0,r.jsx)(s.br,{})]}),"\n",(0,r.jsxs)(s.p,{children:["If you see any errors, you may need to ",(0,r.jsx)(s.a,{href:"#configuring-the-service",children:"update the configuration"})," and restart the service with the commands below."]}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Stopping the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl stop casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.p,{children:(0,r.jsx)(s.strong,{children:"Starting the service:"})}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"sudo systemctl start casper-sidecar.service\n"})}),"\n",(0,r.jsx)(s.h2,{id:"the-admin-server",children:"The Admin Server"}),"\n",(0,r.jsxs)(s.p,{children:["If enabled, the Sidecar's administrative API can be accessed using the following command. The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18887"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.pre,{children:(0,r.jsx)(s.code,{className:"language-bash",children:"http://localhost:PORT/metrics/\n"})}),"\n",(0,r.jsx)(s.h2,{id:"swagger-documentation",children:"Swagger Documentation"}),"\n",(0,r.jsxs)(s.p,{children:["You can access the Swagger documentation at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/swagger-ui/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"openapi-specification",children:"OpenAPI Specification"}),"\n",(0,r.jsxs)(s.p,{children:["An OpenAPI schema is available at ",(0,r.jsx)(s.code,{children:"http://localhost:PORT/api-doc.json/"}),". The ",(0,r.jsx)(s.code,{children:"PORT"})," is usually ",(0,r.jsx)(s.code,{children:"18888"}),", depending on how the Sidecar was configured."]}),"\n",(0,r.jsx)(s.h2,{id:"using-the-sidecar",children:"Using the Sidecar"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes how to consume events and perform queries using the Sidecar, covering the following topics:"]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"Node-generated events emitted by the node(s) to which the Sidecar connects"}),"\n",(0,r.jsx)(s.li,{children:"Sidecar-generated events originating solely from the Sidecar service and not from a node"}),"\n",(0,r.jsx)(s.li,{children:"The RESTful endpoint for performing useful queries about the state of the network"}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,r.jsxs)(s.p,{children:["For troubleshooting tips, visit ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},6874:(e,s,n)=>{n.d(s,{A:()=>r});const r=n.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>c});var r=n(96540);const i={},a=r.createContext(i);function t(e){const s=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:t(e.components),r.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31dbaea7.4f18e31a.js b/assets/js/31dbaea7.4f18e31a.js new file mode 100644 index 000000000..e0fe3f59c --- /dev/null +++ b/assets/js/31dbaea7.4f18e31a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[77675],{87669:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>i,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="K",a={id:"concepts/glossary/K",title:"K",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/K.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/K",permalink:"/1.5.X/concepts/glossary/K",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"J",permalink:"/1.5.X/concepts/glossary/J"},next:{title:"L",permalink:"/1.5.X/concepts/glossary/L"}},l={},h=[{value:"Key",id:"key",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"k",children:"K"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"key",children:"Key"}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.code,{children:"Keys"})," are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found ",(0,c.jsx)(s.a,{href:"/1.5.X/concepts/accounts-and-keys",children:"here"}),"."]})]})}function i(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(e){const s=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),c.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31dbaea7.cb2ad24d.js b/assets/js/31dbaea7.cb2ad24d.js deleted file mode 100644 index 92bd411b7..000000000 --- a/assets/js/31dbaea7.cb2ad24d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7675],{87669:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>i,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="K",a={id:"concepts/glossary/K",title:"K",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/K.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/K",permalink:"/concepts/glossary/K",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"J",permalink:"/concepts/glossary/J"},next:{title:"L",permalink:"/concepts/glossary/L"}},l={},h=[{value:"Key",id:"key",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"k",children:"K"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"key",children:"Key"}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.code,{children:"Keys"})," are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found ",(0,c.jsx)(s.a,{href:"/concepts/accounts-and-keys",children:"here"}),"."]})]})}function i(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(e){const s=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),c.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/31e8518f.78747659.js b/assets/js/31e8518f.78747659.js new file mode 100644 index 000000000..92754ffdd --- /dev/null +++ b/assets/js/31e8518f.78747659.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62604],{21905:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=n(74848),r=n(28453);const c={},i="Testing Smart Contracts",a={id:"developers/writing-onchain-code/testing-contracts",title:"Testing Smart Contracts",description:"Introduction",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/testing-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-contracts",permalink:"/2.0.0/developers/writing-onchain-code/testing-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing a Basic Smart Contract in Rust",permalink:"/2.0.0/developers/writing-onchain-code/simple-contract"},next:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/2.0.0/developers/writing-onchain-code/upgrading-contracts"}},o={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Defining Dependencies in <code>Cargo.toml</code>",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-smart-contracts",children:"Testing Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the Casper development environment, we provide a ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/",children:"testing framework"})," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful transactions and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework."})}),"\n",(0,s.jsxs)(t.h3,{id:"defining-dependencies-in-cargotoml",children:["Defining Dependencies in ",(0,s.jsx)(t.code,{children:"Cargo.toml"})]}),"\n",(0,s.jsxs)(t.p,{children:["This guide uses the project structure, and example contract outlined ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"})," for creating tests."]}),"\n",(0,s.jsxs)(t.p,{children:["To begin, outline the required test dependencies in the ",(0,s.jsx)(t.code,{children:"/tests/Cargo.toml"})," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'[dependencies]\ncasper-execution-engine = "2.0.1"\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-types = "1.5.0"\n'})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The tests for the contract usually reside in the ",(0,s.jsx)(t.code,{children:"tests"})," directory. Tests for the counter contract reside in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file. Notice that this file contains an empty ",(0,s.jsx)(t.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,s.jsx)(t.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.jsx)(t.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.jsx)(t.code,{children:"mod tests"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"importing-builders-and-constants",children:"Importing Builders and Constants"}),"\n",(0,s.jsxs)(t.p,{children:["Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_cl",children:"CLTypes"})," used within the contract code to be tested."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n"})}),"\n",(0,s.jsx)(t.p,{children:"Next, you need to define any global variables or constants for the test."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract\n const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract\n const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract\n\n const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract\n const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement\n const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package\n\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value\n'})}),"\n",(0,s.jsx)(t.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,s.jsxs)(t.p,{children:["Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.jsx)(t.code,{children:"InMemoryWasmTestBuilder"})," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."]}),"\n",(0,s.jsxs)(t.p,{children:["As part of this process, we use the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"})," to install the system contracts necessary for the tests, including the ",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"}),", and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"contracts, as well as establishing a default account and funding the associated purse."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n"})}),"\n",(0,s.jsx)(t.h4,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["Test functions use the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," established by our genesis builder as the account sending the transaction."]}),"\n",(0,s.jsxs)(t.p,{children:["After building the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," (in this example, ",(0,s.jsx)(t.code,{children:"contract_installation_request"}),"), we process the request through ",(0,s.jsx)(t.code,{children:"builder.exec"})," and then add and process other requests as necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-by-hash",children:"Calling the Contract by Hash"}),"\n",(0,s.jsxs)(t.p,{children:["To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," function. The following code retrieves the contract hash from the named keys of the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that sent the installation transaction."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n'})}),"\n",(0,s.jsx)(t.p,{children:"Next, we test an entry point that should not exist in the first version of the contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-using-session-code",children:"Calling the Contract using Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["In the counter example, we use the session code included in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call.wasm"})," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"next section"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following session code uses the contract hash to identify the contract, the account for sending the transaction (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the transaction to be sent (",(0,s.jsx)(t.code,{children:"COUNTER_CALL_WASM"}),"), and the runtime arguments required. Once again, the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," simulates the execution of session code and calls the ",(0,s.jsx)(t.code,{children:"counter-inc"})," entry point."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"evaluating-and-comparing-results",children:"Evaluating and Comparing Results"}),"\n",(0,s.jsxs)(t.p,{children:["After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.jsx)(t.code,{children:"builder"})," method retrieves the required information and converts it to the value type required. Then, ",(0,s.jsx)(t.code,{children:"assert_eq!()"})," compares the result against the expected value."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,s.jsxs)(t.p,{children:["For more test examples, visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,s.jsx)(t.h2,{id:"testing-contracts-that-call-contracts",children:"Testing Contracts that Call Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"}),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."]}),"\n",(0,s.jsxs)(t.p,{children:["Each contract installation will require an additional Wasm file installed through a ",(0,s.jsx)(t.code,{children:"Transaction"})," using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"return values"})," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."]}),"\n",(0,s.jsxs)(t.p,{children:["The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," - Calling a contract by its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_name"})," - Calling a contract referenced by a named key in the signer's Account context."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_hash"})," - Calling a specific contract version using its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_name"})," - Calling a specific version of a contract referenced by a named key in the signer's Account context."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, the counter example uses a ",(0,s.jsx)(t.code,{children:"Makefile"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Under the hood, the ",(0,s.jsx)(t.code,{children:"Makefile"})," generates a ",(0,s.jsx)(t.code,{children:"tests/wasm"})," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.jsx)(t.code,{children:"cargo test"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"test: build-contract\n\tmkdir -p tests/wasm\n\tcp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n\tcp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n\tcp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n\tcd tests && cargo test\n"})}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsxs)(t.p,{children:["The following brief video describes testing ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"sample contract code"}),"."]}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"further-testing",children:"Further Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"local network testing"})," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/dapps/nctl-test",children:"testing in an other simulated network environment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You may also wish to test your contracts on the Casper ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Understand ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,s.jsxs)(t.li,{children:["Learn to ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var s=n(96540);const r={},c=s.createContext(r);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/32dd135c.20dd4de8.js b/assets/js/32dd135c.20dd4de8.js deleted file mode 100644 index ab5513f10..000000000 --- a/assets/js/32dd135c.20dd4de8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9540],{29683:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),d=t(28453);const s={title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},r="CEP-78 Modalities",o={id:"resources/tokens/cep78/modalities",title:"CEP-78 Modalities",description:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/modalities.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/modalities",permalink:"/resources/tokens/cep78/modalities",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},sidebar:"resources",previous:{title:"Introduction",permalink:"/resources/tokens/cep78/introduction"},next:{title:"Quick Installation",permalink:"/resources/tokens/cep78/using-casper-client/quickstart-guide"}},c={},a=[{value:"Ownership",id:"ownership",level:2},{value:"NFTKind",id:"nftkind",level:2},{value:"NFTHolderMode",id:"nftholdermode",level:2},{value:"WhitelistMode",id:"whitelistmode",level:2},{value:"Minting",id:"minting",level:2},{value:"NFTMetadataKind",id:"nftmetadatakind",level:2},{value:"CEP-78 metadata example",id:"cep-78-metadata-example",level:3},{value:"NFT-721 metadata example",id:"nft-721-metadata-example",level:3},{value:"Custom Validated",id:"custom-validated",level:3},{value:"Example Custom Validated schema",id:"example-custom-validated-schema",level:4},{value:"Example Custom Metadata",id:"example-custom-metadata",level:4},{value:"NFTIdentifierMode",id:"nftidentifiermode",level:2},{value:"Metadata Mutability",id:"metadata-mutability",level:2},{value:"BurnMode",id:"burnmode",level:2},{value:"OwnerReverseLookupMode",id:"ownerreverselookupmode",level:2},{value:"NamedKeyConventionMode",id:"namedkeyconventionmode",level:2},{value:"EventsMode",id:"eventsmode",level:2},{value:"Transfer Filter Hook",id:"transfer-filter-hook",level:3},{value:"CEP47 Mode",id:"cep47-mode",level:3},{value:"Casper Event Standard",id:"casper-event-standard",level:3},{value:"Modality Conflicts",id:"modality-conflicts",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cep-78-modalities",children:"CEP-78 Modalities"})}),"\n",(0,i.jsx)(n.p,{children:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior."}),"\n",(0,i.jsx)(n.h2,{id:"ownership",children:"Ownership"}),"\n",(0,i.jsx)(n.p,{children:"This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Minter"}),": ",(0,i.jsx)(n.code,{children:"Minter"})," mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the ",(0,i.jsx)(n.code,{children:"Minter"})," mode the owner of the NFT will not change and thus cannot be transferred to another entity."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Assigned"}),": ",(0,i.jsx)(n.code,{children:"Assigned"})," mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the ",(0,i.jsx)(n.code,{children:"Minter"})," mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Transferable"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode the owner of the newly minted NFT must be specified by the minter. However, in the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, NFTs can be transferred from the owner to another entity."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In all the three mentioned modes, the owner entity is currently restricted to ",(0,i.jsx)(n.code,{children:"Accounts"})," on the Casper network."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, it is possible to transfer the NFT to an ",(0,i.jsx)(n.code,{children:"Account"})," that does not exist."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"Ownership"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:'"ownership_mode"'})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Ownership"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Minter"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Assigned"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transferable"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ownership mode of a contract can be determined by querying the ",(0,i.jsx)(n.code,{children:"ownership_mode"})," entry within the contract's ",(0,i.jsx)(n.code,{children:"NamedKeys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"nftkind",children:"NFTKind"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality does not alter or govern the behavior of the contract itself\nand only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Physical"}),": The NFT represents a real-world physical item e.g., a house."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Digital"}),": The NFT represents a digital item, e.g., a unique JPEG or digital art."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Virtual"}),": The NFT is the virtual representation of a physical notion, e.g., a patent or copyright."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_kind"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Physical"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Digital"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftholdermode",children:"NFTHolderMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Accounts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Accounts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Contracts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mixed"}),": In this mode both ",(0,i.jsx)(n.code,{children:"Accounts"})," and ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," is set to ",(0,i.jsx)(n.code,{children:"Contracts"})," a ",(0,i.jsx)(n.code,{children:"ContractHash"})," whitelist must be provided. This whitelist dictates which\n",(0,i.jsx)(n.code,{children:"Contracts"})," are allowed to mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"Installer"})," minting mode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTHolderMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Accounts"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Contracts"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mixed"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Mixed"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_holder_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"whitelistmode",children:"WhitelistMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unlocked"}),": The ACL whitelist is unlocked and can be updated via the set variables endpoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Locked"}),": The ACL whitelist is locked and cannot be updated further."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is set to ",(0,i.jsx)(n.code,{children:"Locked"})," an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"ACL"})," minting mode. These entities include ",(0,i.jsx)(n.code,{children:"Accounts"})," and/or ",(0,i.jsx)(n.code,{children:"Contracts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"whitelist_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"WhitelistMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Unlocked"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Locked"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"minting",children:"Minting"}),"\n",(0,i.jsx)(n.p,{children:"The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Installer"}),": This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Public"}),": This mode allows any account to mint NFT tokens."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ACL"}),": This mode allows whitelisted accounts or contracts to mint NFT tokens."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Installer"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"minting_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MintingMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Installer"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Public"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ACL"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftmetadatakind",children:"NFTMetadataKind"}),"\n",(0,i.jsx)(n.p,{children:"This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP78"}),": This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NFT721"}),": This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Raw"}),": This mode specifies that metadata validation will not occur and raw strings can be passed to ",(0,i.jsx)(n.code,{children:"token_metadata"})," runtime argument as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CustomValidated"}),": This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["During installation, one ",(0,i.jsx)(n.code,{children:"NFTMetadataKind"})," must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the ",(0,i.jsx)(n.code,{children:"additional_required_metadata"})," or ",(0,i.jsx)(n.code,{children:"optional_metadata"})," arguments."]}),"\n",(0,i.jsx)(n.h3,{id:"cep-78-metadata-example",children:"CEP-78 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "token_uri": "https://www.barfoo.com",\n "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"nft-721-metadata-example",children:"NFT-721 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "symbol": "abc",\n "token_uri": "https://www.barfoo.com"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"custom-validated",children:"Custom Validated"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation.\nThe schema is passed as a String value to ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument at the time of installation. Once provided, the schema\nfor a given instance of the contract cannot be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["The custom JSON schema must contain a top-level ",(0,i.jsx)(n.code,{children:"properties"})," field. An example of a ",(0,i.jsx)(n.a,{href:"#example-custom-validated-schema",children:(0,i.jsx)(n.code,{children:"valid JSON schema"})})," is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata.\nIf the metadata kind is not set to custom validated, then the value passed to the ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument will be ignored."]}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-validated-schema",children:"Example Custom Validated schema"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "properties": {\n "deity_name": {\n "name": "deity_name",\n "description": "The name of deity from a particular pantheon.",\n "required": true\n },\n "mythology": {\n "name": "mythology",\n "description": "The mythology the deity belongs to.",\n "required": true\n }\n }\n}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-metadata",children:"Example Custom Metadata"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "deity_name": "Baldur",\n "mythology": "Nordic"\n}\n'})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTMetadataKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP78"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NFT721"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Raw"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CustomValidated"}),(0,i.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftidentifiermode",children:"NFTIdentifierMode"}),"\n",(0,i.jsx)(n.p,{children:"The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Ordinal"}),": NFTs minted in this modality are identified by a ",(0,i.jsx)(n.code,{children:"u64"})," value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Hash"}),": NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since the primary identifier in the ",(0,i.jsx)(n.code,{children:"Hash"})," mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint."]}),"\n",(0,i.jsxs)(n.p,{children:["Attempting to install the contract with the ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," modality set to ",(0,i.jsx)(n.code,{children:"Mutable"})," in the ",(0,i.jsx)(n.code,{children:"Hash"})," identifier mode will raise an error."]}),"\n",(0,i.jsx)(n.p,{children:"This modality is a required installation parameter and cannot be changed once the contract has been installed."}),"\n",(0,i.jsxs)(n.p,{children:["It is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"identifier_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTIdentifierMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ordinal"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Hash"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"metadata-mutability",children:"Metadata Mutability"}),"\n",(0,i.jsx)(n.p,{children:"The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Immutable"}),": Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mutable"}),": Metadata for NFTs minted in this mode can update the metadata via the ",(0,i.jsx)(n.code,{children:"set_token_metadata"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Mutable"})," option cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"Hash"})," modality for the NFT identifier; attempting to install the contract with this configuration raises ",(0,i.jsx)(n.code,{children:"InvalidMetadataMutability"})," error.\nThis modality is a required installation parameter and cannot be changed once the contract has been installed.\nIt is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"metadata_mutability"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MetadataMutability"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Immutable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mutable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"burnmode",children:"BurnMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"BurnMode"})," modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality\nprovides two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Burnable"}),": Minted tokens can be burnt."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NonBurnable"}),": Minted tokens cannot be burnt."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"BurnMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burnable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NonBurnable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Burnable"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"burn_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"ownerreverselookupmode",children:"OwnerReverseLookupMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides the following options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoLookup"}),": The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Complete"}),": The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransfersOnly"}),": The reporting and receipt functionality is supported like ",(0,i.jsx)(n.code,{children:"Complete"}),". However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, when set to ",(0,i.jsx)(n.code,{children:"Complete"}),", causes a receipt to be returned by the ",(0,i.jsx)(n.code,{children:"mint"})," or ",(0,i.jsx)(n.code,{children:"transfer"})," entrypoints, which the caller can store in their account or contract context for later reference."]}),"\n",(0,i.jsxs)(n.p,{children:["Further, two special entrypoints are enabled in ",(0,i.jsx)(n.code,{children:"Complete"})," mode. First, ",(0,i.jsx)(n.code,{children:"register_owner"})," which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, ",(0,i.jsx)(n.code,{children:"updated_receipts"}),", which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"OwnerReverseLookupMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoLookup"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Complete"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TransfersOnly"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"NoLookup"})," mode if not provided. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"owner_reverse_lookup_mode"})," runtime argument. This mode cannot be changed once the contract has been installed."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"ownership_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Minter"})," and the ",(0,i.jsx)(n.code,{children:"minting_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Installer"})," only, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"NoLookup"}),". This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,i.jsx)(n.code,{children:"TransfersOnly"})," then ",(0,i.jsx)(n.code,{children:"ownership_mode"})," has to be set to ",(0,i.jsx)(n.code,{children:"Transferable"})," only. This is because other ownership modes do not allow transfer."]}),"\n",(0,i.jsxs)(n.p,{children:["If you are upgrading a contract from CEP-78 version 1.0 to 1.1, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"Complete"}),", as this was the standard behavior of CEP-78 1.0. In addition to being set to ",(0,i.jsx)(n.code,{children:"Complete"}),", existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration."]}),"\n",(0,i.jsx)(n.p,{children:"If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option."}),"\n",(0,i.jsx)(n.h2,{id:"namedkeyconventionmode",children:"NamedKeyConventionMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NamedKeyConvention"})," modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"DerivedFromCollectionName"}),": This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's ",(0,i.jsx)(n.code,{children:"NamedKeys"})," as ",(0,i.jsx)(n.code,{children:"cep78_contract_package_<collection_name>"})," and ",(0,i.jsx)(n.code,{children:"cep78_contract_package_access_<collection_name>"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_standard"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries originally created during the 1.0 installation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_custom"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,i.jsx)(n.code,{children:"access_key_name"})," and ",(0,i.jsx)(n.code,{children:"hash_key_name"})," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NamedKeyConvention"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"DerivedFromCollectionName"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_standard"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_custom"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"eventsmode",children:"EventsMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."]}),"\n",(0,i.jsx)(n.p,{children:"The modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoEvents"}),": This modality will signal the contract to not record events at all. This is the default mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP47"}),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,i.jsx)(n.a,{href:"#cep47-mode",children:"below"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CES"}),": This modality will signal the contract to record events using the ",(0,i.jsx)(n.a,{href:"#casper-event-standard",children:"Casper Event Standard"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"EventsMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoEvents"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP47"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CES"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"transfer-filter-hook",children:"Transfer Filter Hook"}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,i.jsx)(n.code,{children:"transfer"})," method is invoked on the contract. CEP-78 will call the ",(0,i.jsx)(n.code,{children:"can_transfer"}),"\nmethod on the specified callback contract, which is expected to return a value of ",(0,i.jsx)(n.code,{children:"TransferFilterContractResult"}),", represented as a u8."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::DenyTransfer"})," will block the transfer regardless of the outcome of other checks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::ProceedTransfer"})," will allow the transfer to proceed if other checks also pass"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter can be enabled by passing a ",(0,i.jsx)(n.code,{children:"ARG_TRANSFER_FILTER_CONTRACT"})," argument to the install method, with a value of type ",(0,i.jsx)(n.code,{children:"Option<Key>"})]}),"\n",(0,i.jsx)(n.h3,{id:"cep47-mode",children:"CEP47 Mode"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP47 ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,i.jsx)(n.code,{children:"BTreeMap"})," within a dictionary (",(0,i.jsx)(n.code,{children:"EVENTS"}),") in the contract's context. Entries consist of the ",(0,i.jsx)(n.code,{children:"PREFIX_HASH_KEY_NAME"}),", followed by the ",(0,i.jsx)(n.code,{children:"EVENT_TYPE"})," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,i.jsx)(n.a,{href:"/concepts/dictionaries",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalGranted"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdate"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"token_id (String)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"casper-event-standard",children:"Casper Event Standard"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CES"})," is an option within the ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,i.jsx)(n.code,{children:"__events"})," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The emitted events are encoded according to the ",(0,i.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"Casper Event Standard"}),", and the schema is visible to an observer reading the ",(0,i.jsx)(n.code,{children:"__events_schema"})," contract named key."]}),"\n",(0,i.jsx)(n.p,{children:"For this CEP-78 reference implementation, the events schema is as follows:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Approval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdated"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"modality-conflicts",children:"Modality Conflicts"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," option set to ",(0,i.jsx)(n.code,{children:"Mutable"})," cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"NFTIdentifierMode"})," modality set to ",(0,i.jsx)(n.code,{children:"Hash"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const d={},s=i.createContext(d);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/32dd135c.45237611.js b/assets/js/32dd135c.45237611.js new file mode 100644 index 000000000..b219f636d --- /dev/null +++ b/assets/js/32dd135c.45237611.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49540],{29683:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),d=t(28453);const s={title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},r="CEP-78 Modalities",o={id:"resources/tokens/cep78/modalities",title:"CEP-78 Modalities",description:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/modalities.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/modalities",permalink:"/1.5.X/resources/tokens/cep78/modalities",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},sidebar:"resources",previous:{title:"Introduction",permalink:"/1.5.X/resources/tokens/cep78/introduction"},next:{title:"Quick Installation",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide"}},c={},a=[{value:"Ownership",id:"ownership",level:2},{value:"NFTKind",id:"nftkind",level:2},{value:"NFTHolderMode",id:"nftholdermode",level:2},{value:"WhitelistMode",id:"whitelistmode",level:2},{value:"Minting",id:"minting",level:2},{value:"NFTMetadataKind",id:"nftmetadatakind",level:2},{value:"CEP-78 metadata example",id:"cep-78-metadata-example",level:3},{value:"NFT-721 metadata example",id:"nft-721-metadata-example",level:3},{value:"Custom Validated",id:"custom-validated",level:3},{value:"Example Custom Validated schema",id:"example-custom-validated-schema",level:4},{value:"Example Custom Metadata",id:"example-custom-metadata",level:4},{value:"NFTIdentifierMode",id:"nftidentifiermode",level:2},{value:"Metadata Mutability",id:"metadata-mutability",level:2},{value:"BurnMode",id:"burnmode",level:2},{value:"OwnerReverseLookupMode",id:"ownerreverselookupmode",level:2},{value:"NamedKeyConventionMode",id:"namedkeyconventionmode",level:2},{value:"EventsMode",id:"eventsmode",level:2},{value:"Transfer Filter Hook",id:"transfer-filter-hook",level:3},{value:"CEP47 Mode",id:"cep47-mode",level:3},{value:"Casper Event Standard",id:"casper-event-standard",level:3},{value:"Modality Conflicts",id:"modality-conflicts",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cep-78-modalities",children:"CEP-78 Modalities"})}),"\n",(0,i.jsx)(n.p,{children:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior."}),"\n",(0,i.jsx)(n.h2,{id:"ownership",children:"Ownership"}),"\n",(0,i.jsx)(n.p,{children:"This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Minter"}),": ",(0,i.jsx)(n.code,{children:"Minter"})," mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the ",(0,i.jsx)(n.code,{children:"Minter"})," mode the owner of the NFT will not change and thus cannot be transferred to another entity."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Assigned"}),": ",(0,i.jsx)(n.code,{children:"Assigned"})," mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the ",(0,i.jsx)(n.code,{children:"Minter"})," mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Transferable"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode the owner of the newly minted NFT must be specified by the minter. However, in the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, NFTs can be transferred from the owner to another entity."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In all the three mentioned modes, the owner entity is currently restricted to ",(0,i.jsx)(n.code,{children:"Accounts"})," on the Casper network."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, it is possible to transfer the NFT to an ",(0,i.jsx)(n.code,{children:"Account"})," that does not exist."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"Ownership"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:'"ownership_mode"'})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Ownership"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Minter"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Assigned"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transferable"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ownership mode of a contract can be determined by querying the ",(0,i.jsx)(n.code,{children:"ownership_mode"})," entry within the contract's ",(0,i.jsx)(n.code,{children:"NamedKeys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"nftkind",children:"NFTKind"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality does not alter or govern the behavior of the contract itself\nand only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Physical"}),": The NFT represents a real-world physical item e.g., a house."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Digital"}),": The NFT represents a digital item, e.g., a unique JPEG or digital art."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Virtual"}),": The NFT is the virtual representation of a physical notion, e.g., a patent or copyright."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_kind"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Physical"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Digital"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftholdermode",children:"NFTHolderMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Accounts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Accounts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Contracts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mixed"}),": In this mode both ",(0,i.jsx)(n.code,{children:"Accounts"})," and ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," is set to ",(0,i.jsx)(n.code,{children:"Contracts"})," a ",(0,i.jsx)(n.code,{children:"ContractHash"})," whitelist must be provided. This whitelist dictates which\n",(0,i.jsx)(n.code,{children:"Contracts"})," are allowed to mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"Installer"})," minting mode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTHolderMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Accounts"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Contracts"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mixed"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Mixed"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_holder_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"whitelistmode",children:"WhitelistMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unlocked"}),": The ACL whitelist is unlocked and can be updated via the set variables endpoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Locked"}),": The ACL whitelist is locked and cannot be updated further."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is set to ",(0,i.jsx)(n.code,{children:"Locked"})," an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"ACL"})," minting mode. These entities include ",(0,i.jsx)(n.code,{children:"Accounts"})," and/or ",(0,i.jsx)(n.code,{children:"Contracts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"whitelist_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"WhitelistMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Unlocked"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Locked"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"minting",children:"Minting"}),"\n",(0,i.jsx)(n.p,{children:"The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Installer"}),": This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Public"}),": This mode allows any account to mint NFT tokens."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ACL"}),": This mode allows whitelisted accounts or contracts to mint NFT tokens."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Installer"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"minting_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MintingMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Installer"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Public"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ACL"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftmetadatakind",children:"NFTMetadataKind"}),"\n",(0,i.jsx)(n.p,{children:"This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP78"}),": This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NFT721"}),": This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Raw"}),": This mode specifies that metadata validation will not occur and raw strings can be passed to ",(0,i.jsx)(n.code,{children:"token_metadata"})," runtime argument as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CustomValidated"}),": This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["During installation, one ",(0,i.jsx)(n.code,{children:"NFTMetadataKind"})," must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the ",(0,i.jsx)(n.code,{children:"additional_required_metadata"})," or ",(0,i.jsx)(n.code,{children:"optional_metadata"})," arguments."]}),"\n",(0,i.jsx)(n.h3,{id:"cep-78-metadata-example",children:"CEP-78 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "token_uri": "https://www.barfoo.com",\n "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"nft-721-metadata-example",children:"NFT-721 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "symbol": "abc",\n "token_uri": "https://www.barfoo.com"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"custom-validated",children:"Custom Validated"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation.\nThe schema is passed as a String value to ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument at the time of installation. Once provided, the schema\nfor a given instance of the contract cannot be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["The custom JSON schema must contain a top-level ",(0,i.jsx)(n.code,{children:"properties"})," field. An example of a ",(0,i.jsx)(n.a,{href:"#example-custom-validated-schema",children:(0,i.jsx)(n.code,{children:"valid JSON schema"})})," is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata.\nIf the metadata kind is not set to custom validated, then the value passed to the ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument will be ignored."]}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-validated-schema",children:"Example Custom Validated schema"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "properties": {\n "deity_name": {\n "name": "deity_name",\n "description": "The name of deity from a particular pantheon.",\n "required": true\n },\n "mythology": {\n "name": "mythology",\n "description": "The mythology the deity belongs to.",\n "required": true\n }\n }\n}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-metadata",children:"Example Custom Metadata"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "deity_name": "Baldur",\n "mythology": "Nordic"\n}\n'})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTMetadataKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP78"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NFT721"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Raw"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CustomValidated"}),(0,i.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftidentifiermode",children:"NFTIdentifierMode"}),"\n",(0,i.jsx)(n.p,{children:"The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Ordinal"}),": NFTs minted in this modality are identified by a ",(0,i.jsx)(n.code,{children:"u64"})," value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Hash"}),": NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since the primary identifier in the ",(0,i.jsx)(n.code,{children:"Hash"})," mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint."]}),"\n",(0,i.jsxs)(n.p,{children:["Attempting to install the contract with the ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," modality set to ",(0,i.jsx)(n.code,{children:"Mutable"})," in the ",(0,i.jsx)(n.code,{children:"Hash"})," identifier mode will raise an error."]}),"\n",(0,i.jsx)(n.p,{children:"This modality is a required installation parameter and cannot be changed once the contract has been installed."}),"\n",(0,i.jsxs)(n.p,{children:["It is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"identifier_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTIdentifierMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ordinal"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Hash"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"metadata-mutability",children:"Metadata Mutability"}),"\n",(0,i.jsx)(n.p,{children:"The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Immutable"}),": Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mutable"}),": Metadata for NFTs minted in this mode can update the metadata via the ",(0,i.jsx)(n.code,{children:"set_token_metadata"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Mutable"})," option cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"Hash"})," modality for the NFT identifier; attempting to install the contract with this configuration raises ",(0,i.jsx)(n.code,{children:"InvalidMetadataMutability"})," error.\nThis modality is a required installation parameter and cannot be changed once the contract has been installed.\nIt is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"metadata_mutability"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MetadataMutability"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Immutable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mutable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"burnmode",children:"BurnMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"BurnMode"})," modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality\nprovides two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Burnable"}),": Minted tokens can be burnt."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NonBurnable"}),": Minted tokens cannot be burnt."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"BurnMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burnable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NonBurnable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Burnable"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"burn_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"ownerreverselookupmode",children:"OwnerReverseLookupMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides the following options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoLookup"}),": The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Complete"}),": The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransfersOnly"}),": The reporting and receipt functionality is supported like ",(0,i.jsx)(n.code,{children:"Complete"}),". However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, when set to ",(0,i.jsx)(n.code,{children:"Complete"}),", causes a receipt to be returned by the ",(0,i.jsx)(n.code,{children:"mint"})," or ",(0,i.jsx)(n.code,{children:"transfer"})," entrypoints, which the caller can store in their account or contract context for later reference."]}),"\n",(0,i.jsxs)(n.p,{children:["Further, two special entrypoints are enabled in ",(0,i.jsx)(n.code,{children:"Complete"})," mode. First, ",(0,i.jsx)(n.code,{children:"register_owner"})," which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, ",(0,i.jsx)(n.code,{children:"updated_receipts"}),", which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"OwnerReverseLookupMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoLookup"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Complete"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TransfersOnly"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"NoLookup"})," mode if not provided. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"owner_reverse_lookup_mode"})," runtime argument. This mode cannot be changed once the contract has been installed."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"ownership_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Minter"})," and the ",(0,i.jsx)(n.code,{children:"minting_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Installer"})," only, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"NoLookup"}),". This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,i.jsx)(n.code,{children:"TransfersOnly"})," then ",(0,i.jsx)(n.code,{children:"ownership_mode"})," has to be set to ",(0,i.jsx)(n.code,{children:"Transferable"})," only. This is because other ownership modes do not allow transfer."]}),"\n",(0,i.jsxs)(n.p,{children:["If you are upgrading a contract from CEP-78 version 1.0 to 1.1, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"Complete"}),", as this was the standard behavior of CEP-78 1.0. In addition to being set to ",(0,i.jsx)(n.code,{children:"Complete"}),", existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration."]}),"\n",(0,i.jsx)(n.p,{children:"If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option."}),"\n",(0,i.jsx)(n.h2,{id:"namedkeyconventionmode",children:"NamedKeyConventionMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NamedKeyConvention"})," modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"DerivedFromCollectionName"}),": This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's ",(0,i.jsx)(n.code,{children:"NamedKeys"})," as ",(0,i.jsx)(n.code,{children:"cep78_contract_package_<collection_name>"})," and ",(0,i.jsx)(n.code,{children:"cep78_contract_package_access_<collection_name>"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_standard"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries originally created during the 1.0 installation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_custom"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,i.jsx)(n.code,{children:"access_key_name"})," and ",(0,i.jsx)(n.code,{children:"hash_key_name"})," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NamedKeyConvention"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"DerivedFromCollectionName"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_standard"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_custom"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"eventsmode",children:"EventsMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."]}),"\n",(0,i.jsx)(n.p,{children:"The modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoEvents"}),": This modality will signal the contract to not record events at all. This is the default mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP47"}),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,i.jsx)(n.a,{href:"#cep47-mode",children:"below"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CES"}),": This modality will signal the contract to record events using the ",(0,i.jsx)(n.a,{href:"#casper-event-standard",children:"Casper Event Standard"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"EventsMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoEvents"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP47"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CES"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"transfer-filter-hook",children:"Transfer Filter Hook"}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,i.jsx)(n.code,{children:"transfer"})," method is invoked on the contract. CEP-78 will call the ",(0,i.jsx)(n.code,{children:"can_transfer"}),"\nmethod on the specified callback contract, which is expected to return a value of ",(0,i.jsx)(n.code,{children:"TransferFilterContractResult"}),", represented as a u8."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::DenyTransfer"})," will block the transfer regardless of the outcome of other checks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::ProceedTransfer"})," will allow the transfer to proceed if other checks also pass"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter can be enabled by passing a ",(0,i.jsx)(n.code,{children:"ARG_TRANSFER_FILTER_CONTRACT"})," argument to the install method, with a value of type ",(0,i.jsx)(n.code,{children:"Option<Key>"})]}),"\n",(0,i.jsx)(n.h3,{id:"cep47-mode",children:"CEP47 Mode"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP47 ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,i.jsx)(n.code,{children:"BTreeMap"})," within a dictionary (",(0,i.jsx)(n.code,{children:"EVENTS"}),") in the contract's context. Entries consist of the ",(0,i.jsx)(n.code,{children:"PREFIX_HASH_KEY_NAME"}),", followed by the ",(0,i.jsx)(n.code,{children:"EVENT_TYPE"})," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,i.jsx)(n.a,{href:"/1.5.X/concepts/dictionaries",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalGranted"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdate"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"token_id (String)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"casper-event-standard",children:"Casper Event Standard"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CES"})," is an option within the ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,i.jsx)(n.code,{children:"__events"})," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The emitted events are encoded according to the ",(0,i.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"Casper Event Standard"}),", and the schema is visible to an observer reading the ",(0,i.jsx)(n.code,{children:"__events_schema"})," contract named key."]}),"\n",(0,i.jsx)(n.p,{children:"For this CEP-78 reference implementation, the events schema is as follows:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Approval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdated"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"modality-conflicts",children:"Modality Conflicts"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," option set to ",(0,i.jsx)(n.code,{children:"Mutable"})," cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"NFTIdentifierMode"})," modality set to ",(0,i.jsx)(n.code,{children:"Hash"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const d={},s=i.createContext(d);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/331badc5.26951b81.js b/assets/js/331badc5.26951b81.js new file mode 100644 index 000000000..30c1f745a --- /dev/null +++ b/assets/js/331badc5.26951b81.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4707],{39824:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>g,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var i=r(74848),s=r(28453);const t={title:"Ledger and Ledger Live"},l="Using Ledger and Ledger Live",a={id:"users/ledger/ledger-live",title:"Ledger and Ledger Live",description:"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-live",permalink:"/1.5.X/users/ledger/ledger-live",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ledger and Ledger Live"},sidebar:"users",previous:{title:"Set up Ledger",permalink:"/1.5.X/workflow/ledger-setup/"},next:{title:"Ledger and CSPR.live",permalink:"/1.5.X/users/ledger/ledger-cspr-live"}},d={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Connecting to Ledger Live",id:"connect-ledge-live",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function o(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"using-ledger-and-ledger-live",children:"Using Ledger and Ledger Live"})}),"\n",(0,i.jsxs)(n.p,{children:["This guide will help you connect accounts from the Ledger device to the ",(0,i.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application to send and receive CSPR tokens."]}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsx)(n.p,{children:"From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live."})}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,i.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,i.jsxs)(n.li,{children:["Install the Casper app as described ",(0,i.jsx)(n.a,{href:"/1.5.X/workflow/ledger-setup/",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"connect-ledge-live",children:"Connecting to Ledger Live"}),"\n",(0,i.jsxs)(n.p,{children:["This section describes using the Ledger device with the ",(0,i.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application and your Casper accounts."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/0-connect.png")}',alt:"Connect the Ledger to your computer",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"Allow Ledger Manager to connect by clicking the two buttons on the Ledger device."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/1-unlock.png")}',alt:"Unlock the Ledger",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"Ledger Live will verify your Ledger device and display the following confirmation:"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/2-confirmation.png")}',alt:"Confirmation that the Ledger is genuine",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Click ",(0,i.jsx)(n.strong,{children:"My Ledger"})," in the left-side navigation bar, and search for ",(0,i.jsx)(n.em,{children:"Casper"})," or ",(0,i.jsx)(n.em,{children:"CSPR"})," in the ",(0,i.jsx)(n.strong,{children:"App catalog"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/3-app-cspr.png")}',alt:"Confirmation that the Ledger is genuine",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["To import a Casper account from the Ledger device into the Ledger Live application, click on the ",(0,i.jsx)(n.strong,{children:"Add account"})," link."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/4-add-account.png")}',alt:"Click the Add account link",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsx)(n.li,{children:"Open the Casper app on your Ledger device."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/5-add-account.png")}',alt:"Open the Casper app",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsx)(n.li,{children:"Ledger Live will import the first account listed on your Ledger device. Choose a name for the account."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/6-add-account.png")}',alt:"Name the account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsx)(n.li,{children:"After synchronizing the account, Ledger Live will confirm that the account was successfully added."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/7-add-account.png")}',alt:"Synchronizing the account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/8-add-account.png")}',alt:"Confirmation that the account was added",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"9",children:["\n",(0,i.jsx)(n.li,{children:"Click on the account summary, to view more details."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/9-account-summary.png")}',alt:"Account summary",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/10-account-details.png")}',alt:"Account details",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsxs)(n.li,{children:["To add another account, open the ",(0,i.jsx)(n.strong,{children:"Account"})," option in the left-side navigation bar. Then, click on the ",(0,i.jsx)(n.strong,{children:"Add account"})," button."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/11-second-account.png")}',alt:"Add a second account",width:"800"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,i.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key."}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsx)(n.p,{children:"Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds."})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Click on the ",(0,i.jsx)(n.strong,{children:"Receive"})," option in the left-side navigation bar."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/12-receive.png")}',alt:"Click on Receive",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"Choose an account from the drop-down list."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/13-receive.png")}',alt:"Choose an account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"Copy the address displayed, or use the corresponding QR code."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/14-receive.png")}',alt:"Choose an account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click ",(0,i.jsx)(n.strong,{children:"APPROVE"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/15-receive.png")}',alt:"Verify address part 1",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/16-receive.png")}',alt:"Verify address part 2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/17-receive.png")}',alt:"Click APPROVE",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/18-receive.png")}',alt:"Confirmation displayed",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,i.jsx)(n.p,{children:"Ledger Live supports sending CSPR tokens from one Casper account to another."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Start by clicking on the ",(0,i.jsx)(n.strong,{children:"Send"})," option in the left-side navigation bar. Choose the account to debit:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/19-send.png")}',alt:"Choose the account to debit",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["Enter the recipient's address and click ",(0,i.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/20-send.png")}',alt:"Enter recipient",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["Enter the amount and an optional transfer ID. Click ",(0,i.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/21-send.png")}',alt:"Enter amount and transfer ID",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Review the summary, and if everything is correct, click ",(0,i.jsx)(n.strong,{children:"Continue"}),". Otherwise, click the ",(0,i.jsx)(n.strong,{children:"Back"})," link in the top-left corner."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/22-send.png")}',alt:"Review the transfer",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source ",(0,i.jsx)(n.strong,{children:"account"}),", fee, target, and amount. Meanwhile, Ledger Live will display this message:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/23-send.png")}',alt:"Review the transaction in the Ledger",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,i.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details until you see ",(0,i.jsx)(n.strong,{children:'"APPROVE"'}),"."]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:["Review the ",(0,i.jsx)(n.strong,{children:"Txn hash"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/3-txn-1.jpg")}',alt:"3-txn-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/4-txn-2.jpg")}',alt:"4-txn-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:["The next screen displays the transaction ",(0,i.jsx)(n.strong,{children:"Type"}),", which will be ",(0,i.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/5-type.jpg")}',alt:"5-type",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"chain ID"}),", which for Mainnet should be ",(0,i.jsx)(n.strong,{children:"casper"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/7-chain.jpg")}',alt:"7-chain",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"9",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Account"})," initiating the token transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/8-account-1.jpg")}',alt:"8-account-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/9-account-2.jpg")}',alt:"9-account-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/10-fee.jpg")}',alt:"10-fee",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"11",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Target"}),", which is the recipient's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/11-target-1.jpg")}',alt:"11-target-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/12-target-2.jpg")}',alt:"12-target-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"12",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/13-amount.jpg")}',alt:"13-amount",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"13",children:["\n",(0,i.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,i.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/15-approve.jpg")}',alt:"15-approve",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"14",children:["\n",(0,i.jsx)(n.li,{children:"After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/24-send.png")}',alt:"Broadcasting transaction",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/25-send.png")}',alt:"Transaction sent",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"15",children:["\n",(0,i.jsxs)(n.li,{children:["To view the transaction details, click on the ",(0,i.jsx)(n.strong,{children:"View details"})," button. The following screen will appear:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/26-send.png")}',alt:"Transaction details",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"16",children:["\n",(0,i.jsxs)(n.li,{children:["You can view the transaction in the CSPR.live block explorer by clicking on the ",(0,i.jsx)(n.strong,{children:"View in explorer"})," link."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/27-send.png")}',alt:"Explorer showing transaction",width:"800"}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>a});var i=r(96540);const s={},t=i.createContext(s);function l(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/331badc5.a0e388dd.js b/assets/js/331badc5.a0e388dd.js deleted file mode 100644 index 8a0111c63..000000000 --- a/assets/js/331badc5.a0e388dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4707],{39824:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>g,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var i=r(74848),s=r(28453);const t={title:"Ledger and Ledger Live"},l="Using Ledger and Ledger Live",a={id:"users/ledger/ledger-live",title:"Ledger and Ledger Live",description:"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-live",permalink:"/users/ledger/ledger-live",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ledger and Ledger Live"},sidebar:"users",previous:{title:"Set up Ledger",permalink:"/workflow/ledger-setup/"},next:{title:"Ledger and CSPR.live",permalink:"/users/ledger/ledger-cspr-live"}},d={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Connecting to Ledger Live",id:"connect-ledge-live",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function o(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"using-ledger-and-ledger-live",children:"Using Ledger and Ledger Live"})}),"\n",(0,i.jsxs)(n.p,{children:["This guide will help you connect accounts from the Ledger device to the ",(0,i.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application to send and receive CSPR tokens."]}),"\n",(0,i.jsx)(n.admonition,{type:"important",children:(0,i.jsx)(n.p,{children:"From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live."})}),"\n",(0,i.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,i.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,i.jsxs)(n.li,{children:["Install the Casper app as described ",(0,i.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"connect-ledge-live",children:"Connecting to Ledger Live"}),"\n",(0,i.jsxs)(n.p,{children:["This section describes using the Ledger device with the ",(0,i.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application and your Casper accounts."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/0-connect.png")}',alt:"Connect the Ledger to your computer",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"Allow Ledger Manager to connect by clicking the two buttons on the Ledger device."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/1-unlock.png")}',alt:"Unlock the Ledger",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"Ledger Live will verify your Ledger device and display the following confirmation:"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/2-confirmation.png")}',alt:"Confirmation that the Ledger is genuine",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Click ",(0,i.jsx)(n.strong,{children:"My Ledger"})," in the left-side navigation bar, and search for ",(0,i.jsx)(n.em,{children:"Casper"})," or ",(0,i.jsx)(n.em,{children:"CSPR"})," in the ",(0,i.jsx)(n.strong,{children:"App catalog"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/3-app-cspr.png")}',alt:"Confirmation that the Ledger is genuine",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["To import a Casper account from the Ledger device into the Ledger Live application, click on the ",(0,i.jsx)(n.strong,{children:"Add account"})," link."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/4-add-account.png")}',alt:"Click the Add account link",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsx)(n.li,{children:"Open the Casper app on your Ledger device."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/5-add-account.png")}',alt:"Open the Casper app",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsx)(n.li,{children:"Ledger Live will import the first account listed on your Ledger device. Choose a name for the account."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/6-add-account.png")}',alt:"Name the account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsx)(n.li,{children:"After synchronizing the account, Ledger Live will confirm that the account was successfully added."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/7-add-account.png")}',alt:"Synchronizing the account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/8-add-account.png")}',alt:"Confirmation that the account was added",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"9",children:["\n",(0,i.jsx)(n.li,{children:"Click on the account summary, to view more details."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/9-account-summary.png")}',alt:"Account summary",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/10-account-details.png")}',alt:"Account details",width:"800"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsxs)(n.li,{children:["To add another account, open the ",(0,i.jsx)(n.strong,{children:"Account"})," option in the left-side navigation bar. Then, click on the ",(0,i.jsx)(n.strong,{children:"Add account"})," button."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/11-second-account.png")}',alt:"Add a second account",width:"800"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,i.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key."}),"\n",(0,i.jsx)(n.admonition,{type:"caution",children:(0,i.jsx)(n.p,{children:"Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds."})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Click on the ",(0,i.jsx)(n.strong,{children:"Receive"})," option in the left-side navigation bar."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/12-receive.png")}',alt:"Click on Receive",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsx)(n.li,{children:"Choose an account from the drop-down list."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/13-receive.png")}',alt:"Choose an account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsx)(n.li,{children:"Copy the address displayed, or use the corresponding QR code."}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/14-receive.png")}',alt:"Choose an account",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click ",(0,i.jsx)(n.strong,{children:"APPROVE"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/15-receive.png")}',alt:"Verify address part 1",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/16-receive.png")}',alt:"Verify address part 2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/17-receive.png")}',alt:"Click APPROVE",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/18-receive.png")}',alt:"Confirmation displayed",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,i.jsx)(n.p,{children:"Ledger Live supports sending CSPR tokens from one Casper account to another."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Start by clicking on the ",(0,i.jsx)(n.strong,{children:"Send"})," option in the left-side navigation bar. Choose the account to debit:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/19-send.png")}',alt:"Choose the account to debit",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"2",children:["\n",(0,i.jsxs)(n.li,{children:["Enter the recipient's address and click ",(0,i.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/20-send.png")}',alt:"Enter recipient",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"3",children:["\n",(0,i.jsxs)(n.li,{children:["Enter the amount and an optional transfer ID. Click ",(0,i.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/21-send.png")}',alt:"Enter amount and transfer ID",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"4",children:["\n",(0,i.jsxs)(n.li,{children:["Review the summary, and if everything is correct, click ",(0,i.jsx)(n.strong,{children:"Continue"}),". Otherwise, click the ",(0,i.jsx)(n.strong,{children:"Back"})," link in the top-left corner."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/22-send.png")}',alt:"Review the transfer",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"5",children:["\n",(0,i.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source ",(0,i.jsx)(n.strong,{children:"account"}),", fee, target, and amount. Meanwhile, Ledger Live will display this message:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/23-send.png")}',alt:"Review the transaction in the Ledger",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,i.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details until you see ",(0,i.jsx)(n.strong,{children:'"APPROVE"'}),"."]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:["Review the ",(0,i.jsx)(n.strong,{children:"Txn hash"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/3-txn-1.jpg")}',alt:"3-txn-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/4-txn-2.jpg")}',alt:"4-txn-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:["The next screen displays the transaction ",(0,i.jsx)(n.strong,{children:"Type"}),", which will be ",(0,i.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/5-type.jpg")}',alt:"5-type",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"8",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"chain ID"}),", which for Mainnet should be ",(0,i.jsx)(n.strong,{children:"casper"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/7-chain.jpg")}',alt:"7-chain",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"9",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Account"})," initiating the token transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/8-account-1.jpg")}',alt:"8-account-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/9-account-2.jpg")}',alt:"9-account-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"10",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/10-fee.jpg")}',alt:"10-fee",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"11",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Target"}),", which is the recipient's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/11-target-1.jpg")}',alt:"11-target-1",width:"400"}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/12-target-2.jpg")}',alt:"12-target-2",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"12",children:["\n",(0,i.jsxs)(n.li,{children:["Verify the ",(0,i.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/13-amount.jpg")}',alt:"13-amount",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"13",children:["\n",(0,i.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,i.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/device/15-approve.jpg")}',alt:"15-approve",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"14",children:["\n",(0,i.jsx)(n.li,{children:"After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/24-send.png")}',alt:"Broadcasting transaction",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/25-send.png")}',alt:"Transaction sent",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"15",children:["\n",(0,i.jsxs)(n.li,{children:["To view the transaction details, click on the ",(0,i.jsx)(n.strong,{children:"View details"})," button. The following screen will appear:"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/26-send.png")}',alt:"Transaction details",width:"400"}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"16",children:["\n",(0,i.jsxs)(n.li,{children:["You can view the transaction in the CSPR.live block explorer by clicking on the ",(0,i.jsx)(n.strong,{children:"View in explorer"})," link."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{align:"center",children:["\n",(0,i.jsx)(n.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/27-send.png")}',alt:"Explorer showing transaction",width:"800"}),"\n"]})]})}function g(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>l,x:()=>a});var i=r(96540);const s={},t=i.createContext(s);function l(e){const n=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),i.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3362155c.196ff25b.js b/assets/js/3362155c.196ff25b.js deleted file mode 100644 index 58d84cad9..000000000 --- a/assets/js/3362155c.196ff25b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4635],{20633:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const i={},d="Monitoring and Consuming Events",c={id:"developers/dapps/monitor-and-consume-events",title:"Monitoring and Consuming Events",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/developers/dapps/monitor-and-consume-events",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"}},r={},l=[{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:2},{value:"Event Types",id:"event-types",level:2},{value:"ApiVersion",id:"apiversion",level:3},{value:"BlockAdded",id:"blockadded",level:3},{value:"DeployAccepted",id:"deployaccepted",level:3},{value:"DeployProcessed",id:"deployprocessed",level:3},{value:"DeployExpired",id:"deployexpired",level:3},{value:"Fault",id:"fault",level:3},{value:"FinalitySignature",id:"finalitysignature",level:3},{value:"Step",id:"step",level:3},{value:"Shutdown",id:"shutdown",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:2},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:2},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"monitoring-and-consuming-events",children:"Monitoring and Consuming Events"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data."}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the ",(0,t.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,t.jsx)(n.em,{children:"config.toml"}),". This port is by default ",(0,t.jsx)(n.code,{children:"9999"})," for nodes on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet"})," and ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Events are divided into three categories and streamed on their respective endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Deploy events"})," - Associated with ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploys"})," on a node. Currently, only a ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/deploys/"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Finality Signature events"})," - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/sigs/"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Main events"})," - All other events fall under this type, including: ",(0,t.jsx)(n.code,{children:"BlockAdded"}),", ",(0,t.jsx)(n.code,{children:"DeployProcessed"}),", ",(0,t.jsx)(n.code,{children:"DeployExpired"}),", ",(0,t.jsx)(n.code,{children:"Fault"}),", ",(0,t.jsx)(n.code,{children:"Step"}),", and ",(0,t.jsx)(n.code,{children:"Shutdown"})," events. The URL to consume these events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/main/"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version."]})}),"\n",(0,t.jsx)(n.h2,{id:"listening-to-the-event-stream",children:"Listening to the Event Stream"}),"\n",(0,t.jsx)(n.p,{children:"Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { EventStream, EventName } = require("casper-js-sdk")\n\nconst es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL)\nes.start()\nes.subscribe(EventName.EVENT_NAME, eventHandler)\n\nconst eventHandler = (event) => {\n console.log(event)\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nclient.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:9999/events/CHANNEL\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["You can find node addresses of active online peers to replace ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"}),", by navigating to ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," for Mainnet and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"})," for Testnet."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"EVENT_NAME"})," with one of the event types listed ",(0,t.jsx)(n.a,{href:"#event-types",children:"below"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"CHANNEL"})," with one of the following event streams:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"main"})," for ",(0,t.jsx)(n.code,{children:"ApiVersion"}),", ",(0,t.jsx)(n.code,{children:"BlockAdded"}),", ",(0,t.jsx)(n.code,{children:"DeployExpired"}),", ",(0,t.jsx)(n.code,{children:"DeployProcessed"}),", ",(0,t.jsx)(n.code,{children:"Fault"}),", or ",(0,t.jsx)(n.code,{children:"Step"})," events."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"deploys"})," for ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," events."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sigs"})," for ",(0,t.jsx)(n.code,{children:"FinalitySignature"})," events."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"event-types",children:"Event Types"}),"\n",(0,t.jsx)(n.h3,{id:"apiversion",children:"ApiVersion"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event structure."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'data:{"ApiVersion":"1.0.0"}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"blockadded",children:"BlockAdded"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"BlockAdded"})," event is emitted when a new block is added to the blockchain and stored locally in the node."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "BlockAdded": {\n "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",\n "block": {\n "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",\n "header": {\n "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",\n "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",\n "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",\n "random_bit": true,\n "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",\n "era_end": null,\n "timestamp": "2023-01-01T09:55:25.312Z",\n "era_id": 8426,\n "height": 1566677,\n "protocol_version": "1.4.13"\n },\n "body": {\n "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",\n "deploy_hashes": [],\n "transfer_hashes": []\n },\n "proofs": []\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#block-hash",children:"block_hash"})," - The cryptographic hash that identifies a block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-block",children:"block"})," - The JSON representation of the block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#body",children:"proposer"})," - The validator selected to propose the block."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deployaccepted",children:"DeployAccepted"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"DeployAccepted"})," events are emitted when a node on the network receives a deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployAccepted": {\n "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",\n "header": {\n "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "timestamp": "2023-01-01T20:22:45.383Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "040008af2f",\n "parsed": "800000000"\n }\n ]\n ]\n }\n },\n "session": {\n "StoredContractByHash": {\n "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",\n "entry_point": "test_entry_point",\n "args": [\n [\n "cost",\n {\n "cl_type": "U512",\n "bytes": "0500c817a804",\n "parsed": "20000000000"\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"\n }\n ]\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/hash-types",children:"hash"})," - The blake2b hash of the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-account",children:"account"})," - The hexadecimal-encoded public key of the account submitting the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/hash-types",children:"body_hash"})," - The blake2b hash of the Deploy body."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/glossary/P#payment-code",children:"payment"})," - Gas payment information."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session"})," - The session logic defining the Deploy's functionality."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#approval",children:"approvals"})," - The signer's hexadecimal-encoded public key and signature."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For details on custom serializations, check the ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard",children:"Serialization Standard"}),". Also, the ",(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"Types"})," page defines the terms used in the event stream output."]}),"\n",(0,t.jsx)(n.h3,{id:"deployprocessed",children:"DeployProcessed"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"DeployProcessed"})," event is emitted when a given Deploy has been executed."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployProcessed": {\n "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",\n "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",\n "timestamp": "2023-01-01T10:07:00.401Z",\n "ttl": "30m",\n "dependencies": [],\n "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",\n "transform": "Identity"\n },\n ]\n },\n "transfers": [\n "transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#deploy-hash",children:"deploy_hash"})," - The cryptographic hash of a Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-account",children:"account"})," - The hexadecimal-encoded public key of the account submitting the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#timestamp",children:"timestamp"})," - A timestamp type representing a concrete moment in time."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#deploy-header",children:"dependencies"})," - A list of Deploy hashes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#block-hash",children:"block_hash"})," - A cryptographic hash identifying a Block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#executionresult",children:"execution_result"})," - The execution status of the Deploy, which is either ",(0,t.jsx)(n.code,{children:"Success"})," or ",(0,t.jsx)(n.code,{children:"Failure"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deployexpired",children:"DeployExpired"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployExpired": {\n "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#deploy-hash",children:"deploy_hash"})," - The cryptographic hash of a Deploy."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"fault",children:"Fault"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Fault"})," event is emitted if there is a validator error."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand the below section to view the Fault event details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "Fault": {\n "era_id": 4591448806312642600,\n "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",\n "timestamp": "2023-01-01T01:26:58.364Z"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#publickey",children:"public_key"})," - The hexadecimal-encoded public key of the validator that caused the fault."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#timestamp",children:"timestamp"})," - A timestamp representing the moment the validator faulted."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"finalitysignature",children:"FinalitySignature"}),"\n",(0,t.jsxs)(n.p,{children:["This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the ",(0,t.jsx)(n.a,{href:"/deploy-and-deploy-lifecycle#consensus-reached",children:"consensus reached"})," and ",(0,t.jsx)(n.a,{href:"/concepts/glossary/B#block-finality",children:"block finality"})," sections to learn more about finality signatures."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "FinalitySignature": {\n "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",\n "era_id": 8419,\n "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",\n "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#block-hash",children:"block_hash"})," - A cryptographic hash identifying a Block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#signature",children:"signature"})," - Serialized bytes representing the validator's signature."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#publickey",children:"public_key"})," - The hexadecimal-encoded public key of the validator."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step",children:"Step"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Step"})," event is emitted at the end of every era and contains the execution effects produced by running the auction contract's ",(0,t.jsx)(n.code,{children:"step"})," function."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "Step": {\n "era_id": 1,\n "execution_effect": {\n "operations": [],\n "transforms": [\n {\n "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",\n "transform": "Identity"\n },\n {\n "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": {\n "WriteBid": {\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",\n "staked_amount": "1000000000000005",\n "delegation_rate": 5,\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n },\n "delegators": {\n "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {\n "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",\n "staked_amount": "51312014671568117976319379",\n "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n }\n }\n },\n "inactive": false\n }\n }\n }\n ]\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#executioneffect",children:"execution_effect"})," - The journal of execution transforms from a single Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#operation",children:"operations"})," - Operations performed while executing a Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#transform",children:"transform"})," - The actual transformation performed while executing a Deploy."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"shutdown",children:"Shutdown"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Shutdown"})," event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand the below section to view the Shutdown event details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'"Shutdown"\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.'}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"reacting-to-events",children:"Reacting to Events"}),"\n",(0,t.jsxs)(n.p,{children:["An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const eventHandler = (event) => {\n if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'def eventHandler(event):\n if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"unsubscribing-from-events",children:"Unsubscribing from Events"}),"\n",(0,t.jsxs)(n.p,{children:["In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,t.jsx)(n.code,{children:"unsubscribe"})," function:"]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"es.unsubscribe(EventName.EVENT_NAME)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"EVENT_NAME"})," - One of the different ",(0,t.jsx)(n.a,{href:"#event-types",children:"event types"})," emitted by a Casper node."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-event-stream",children:"Stopping the Event Stream"}),"\n",(0,t.jsxs)(n.p,{children:["A dApp may cease listening to all events using the ",(0,t.jsx)(n.code,{children:"stop"})," function:"]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"es.stop()\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"replaying-the-event-stream",children:"Replaying the Event Stream"}),"\n",(0,t.jsxs)(n.p,{children:["This command will replay the event stream from an old event onward. Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"}),", ",(0,t.jsx)(n.code,{children:"CHANNEL"}),", and ",(0,t.jsx)(n.code,{children:"ID"})," fields with the values of your scenario."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.em,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:9999/events/main?start_from=29267508\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Each URL can have a query string added to the form ",(0,t.jsx)(n.code,{children:"?start_from=ID"}),", where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["The server keeps only a limited number of events cached to allow replaying the stream to clients using the ",(0,t.jsx)(n.code,{children:"?start_from="})," query string. The cache size can be set differently on each node using the ",(0,t.jsx)(n.code,{children:"event_stream_buffer_length"})," value in the ",(0,t.jsx)(n.em,{children:"config.toml"}),". By default, it is only 5000.\nThe intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected."]})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var t=s(96540);const a={},i=t.createContext(a);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3362155c.2951497f.js b/assets/js/3362155c.2951497f.js new file mode 100644 index 000000000..d25f8ab10 --- /dev/null +++ b/assets/js/3362155c.2951497f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34635],{20633:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const i={},d="Monitoring and Consuming Events",c={id:"developers/dapps/monitor-and-consume-events",title:"Monitoring and Consuming Events",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/1.5.X/developers/dapps/monitor-and-consume-events",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/1.5.X/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/1.5.X/developers/cli/"}},r={},l=[{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:2},{value:"Event Types",id:"event-types",level:2},{value:"ApiVersion",id:"apiversion",level:3},{value:"BlockAdded",id:"blockadded",level:3},{value:"DeployAccepted",id:"deployaccepted",level:3},{value:"DeployProcessed",id:"deployprocessed",level:3},{value:"DeployExpired",id:"deployexpired",level:3},{value:"Fault",id:"fault",level:3},{value:"FinalitySignature",id:"finalitysignature",level:3},{value:"Step",id:"step",level:3},{value:"Shutdown",id:"shutdown",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:2},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:2},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"monitoring-and-consuming-events",children:"Monitoring and Consuming Events"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data."}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the ",(0,t.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,t.jsx)(n.em,{children:"config.toml"}),". This port is by default ",(0,t.jsx)(n.code,{children:"9999"})," for nodes on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet"})," and ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Events are divided into three categories and streamed on their respective endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Deploy events"})," - Associated with ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploys"})," on a node. Currently, only a ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/deploys/"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Finality Signature events"})," - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/sigs/"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Main events"})," - All other events fall under this type, including: ",(0,t.jsx)(n.code,{children:"BlockAdded"}),", ",(0,t.jsx)(n.code,{children:"DeployProcessed"}),", ",(0,t.jsx)(n.code,{children:"DeployExpired"}),", ",(0,t.jsx)(n.code,{children:"Fault"}),", ",(0,t.jsx)(n.code,{children:"Step"}),", and ",(0,t.jsx)(n.code,{children:"Shutdown"})," events. The URL to consume these events on Mainnet and Testnet is ",(0,t.jsx)(n.code,{children:"http://<HOST>:9999/events/main/"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version."]})}),"\n",(0,t.jsx)(n.h2,{id:"listening-to-the-event-stream",children:"Listening to the Event Stream"}),"\n",(0,t.jsx)(n.p,{children:"Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { EventStream, EventName } = require("casper-js-sdk")\n\nconst es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL)\nes.start()\nes.subscribe(EventName.EVENT_NAME, eventHandler)\n\nconst eventHandler = (event) => {\n console.log(event)\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nclient.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:9999/events/CHANNEL\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["You can find node addresses of active online peers to replace ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"}),", by navigating to ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," for Mainnet and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"})," for Testnet."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"EVENT_NAME"})," with one of the event types listed ",(0,t.jsx)(n.a,{href:"#event-types",children:"below"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"CHANNEL"})," with one of the following event streams:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"main"})," for ",(0,t.jsx)(n.code,{children:"ApiVersion"}),", ",(0,t.jsx)(n.code,{children:"BlockAdded"}),", ",(0,t.jsx)(n.code,{children:"DeployExpired"}),", ",(0,t.jsx)(n.code,{children:"DeployProcessed"}),", ",(0,t.jsx)(n.code,{children:"Fault"}),", or ",(0,t.jsx)(n.code,{children:"Step"})," events."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"deploys"})," for ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," events."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sigs"})," for ",(0,t.jsx)(n.code,{children:"FinalitySignature"})," events."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"event-types",children:"Event Types"}),"\n",(0,t.jsx)(n.h3,{id:"apiversion",children:"ApiVersion"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ",(0,t.jsx)(n.code,{children:"ApiVersion"})," event structure."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'data:{"ApiVersion":"1.0.0"}\n'})}),"\n",(0,t.jsx)(n.h3,{id:"blockadded",children:"BlockAdded"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"BlockAdded"})," event is emitted when a new block is added to the blockchain and stored locally in the node."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "BlockAdded": {\n "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",\n "block": {\n "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",\n "header": {\n "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",\n "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",\n "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",\n "random_bit": true,\n "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",\n "era_end": null,\n "timestamp": "2023-01-01T09:55:25.312Z",\n "era_id": 8426,\n "height": 1566677,\n "protocol_version": "1.4.13"\n },\n "body": {\n "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",\n "deploy_hashes": [],\n "transfer_hashes": []\n },\n "proofs": []\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#block-hash",children:"block_hash"})," - The cryptographic hash that identifies a block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-block",children:"block"})," - The JSON representation of the block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#body",children:"proposer"})," - The validator selected to propose the block."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deployaccepted",children:"DeployAccepted"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"DeployAccepted"})," events are emitted when a node on the network receives a deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployAccepted": {\n "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",\n "header": {\n "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "timestamp": "2023-01-01T20:22:45.383Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "040008af2f",\n "parsed": "800000000"\n }\n ]\n ]\n }\n },\n "session": {\n "StoredContractByHash": {\n "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",\n "entry_point": "test_entry_point",\n "args": [\n [\n "cost",\n {\n "cl_type": "U512",\n "bytes": "0500c817a804",\n "parsed": "20000000000"\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",\n "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"\n }\n ]\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/hash-types",children:"hash"})," - The blake2b hash of the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-account",children:"account"})," - The hexadecimal-encoded public key of the account submitting the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/hash-types",children:"body_hash"})," - The blake2b hash of the Deploy body."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/P#payment-code",children:"payment"})," - Gas payment information."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session"})," - The session logic defining the Deploy's functionality."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#approval",children:"approvals"})," - The signer's hexadecimal-encoded public key and signature."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["For details on custom serializations, check the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization Standard"}),". Also, the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain",children:"Types"})," page defines the terms used in the event stream output."]}),"\n",(0,t.jsx)(n.h3,{id:"deployprocessed",children:"DeployProcessed"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"DeployProcessed"})," event is emitted when a given Deploy has been executed."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployProcessed": {\n "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",\n "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",\n "timestamp": "2023-01-01T10:07:00.401Z",\n "ttl": "30m",\n "dependencies": [],\n "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",\n "execution_result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",\n "transform": "Identity"\n },\n ]\n },\n "transfers": [\n "transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"\n ],\n "cost": "100000000"\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#deploy-hash",children:"deploy_hash"})," - The cryptographic hash of a Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-account",children:"account"})," - The hexadecimal-encoded public key of the account submitting the Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#timestamp",children:"timestamp"})," - A timestamp type representing a concrete moment in time."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#deploy-header",children:"dependencies"})," - A list of Deploy hashes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#block-hash",children:"block_hash"})," - A cryptographic hash identifying a Block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#executionresult",children:"execution_result"})," - The execution status of the Deploy, which is either ",(0,t.jsx)(n.code,{children:"Success"})," or ",(0,t.jsx)(n.code,{children:"Failure"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deployexpired",children:"DeployExpired"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "DeployExpired": {\n "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#deploy-hash",children:"deploy_hash"})," - The cryptographic hash of a Deploy."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"fault",children:"Fault"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Fault"})," event is emitted if there is a validator error."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand the below section to view the Fault event details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "Fault": {\n "era_id": 4591448806312642600,\n "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",\n "timestamp": "2023-01-01T01:26:58.364Z"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#publickey",children:"public_key"})," - The hexadecimal-encoded public key of the validator that caused the fault."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#timestamp",children:"timestamp"})," - A timestamp representing the moment the validator faulted."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"finalitysignature",children:"FinalitySignature"}),"\n",(0,t.jsxs)(n.p,{children:["This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the ",(0,t.jsx)(n.a,{href:"/1.5.X/deploy-and-deploy-lifecycle#consensus-reached",children:"consensus reached"})," and ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/B#block-finality",children:"block finality"})," sections to learn more about finality signatures."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "FinalitySignature": {\n "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",\n "era_id": 8419,\n "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",\n "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#block-hash",children:"block_hash"})," - A cryptographic hash identifying a Block."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#signature",children:"signature"})," - Serialized bytes representing the validator's signature."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#publickey",children:"public_key"})," - The hexadecimal-encoded public key of the validator."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step",children:"Step"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Step"})," event is emitted at the end of every era and contains the execution effects produced by running the auction contract's ",(0,t.jsx)(n.code,{children:"step"})," function."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "Step": {\n "era_id": 1,\n "execution_effect": {\n "operations": [],\n "transforms": [\n {\n "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",\n "transform": "Identity"\n },\n {\n "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": "Identity"\n },\n {\n "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",\n "transform": {\n "WriteBid": {\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",\n "staked_amount": "1000000000000005",\n "delegation_rate": 5,\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n },\n "delegators": {\n "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {\n "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",\n "staked_amount": "51312014671568117976319379",\n "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",\n "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",\n "vesting_schedule": {\n "initial_release_timestamp_millis": 1664475057182,\n "locked_amounts": null\n }\n }\n },\n "inactive": false\n }\n }\n }\n ]\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#eraid",children:"era_id"})," - A period of time during which the validator set does not change."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#executioneffect",children:"execution_effect"})," - The journal of execution transforms from a single Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#operation",children:"operations"})," - Operations performed while executing a Deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#transform",children:"transform"})," - The actual transformation performed while executing a Deploy."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"shutdown",children:"Shutdown"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Shutdown"})," event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand the below section to view the Shutdown event details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'"Shutdown"\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:'Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.'}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"reacting-to-events",children:"Reacting to Events"}),"\n",(0,t.jsxs)(n.p,{children:["An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const eventHandler = (event) => {\n if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'def eventHandler(event):\n if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"unsubscribing-from-events",children:"Unsubscribing from Events"}),"\n",(0,t.jsxs)(n.p,{children:["In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,t.jsx)(n.code,{children:"unsubscribe"})," function:"]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"es.unsubscribe(EventName.EVENT_NAME)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"EVENT_NAME"})," - One of the different ",(0,t.jsx)(n.a,{href:"#event-types",children:"event types"})," emitted by a Casper node."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-event-stream",children:"Stopping the Event Stream"}),"\n",(0,t.jsxs)(n.p,{children:["A dApp may cease listening to all events using the ",(0,t.jsx)(n.code,{children:"stop"})," function:"]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"es.stop()\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"replaying-the-event-stream",children:"Replaying the Event Stream"}),"\n",(0,t.jsxs)(n.p,{children:["This command will replay the event stream from an old event onward. Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"}),", ",(0,t.jsx)(n.code,{children:"CHANNEL"}),", and ",(0,t.jsx)(n.code,{children:"ID"})," fields with the values of your scenario."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.em,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:9999/events/main?start_from=29267508\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Each URL can have a query string added to the form ",(0,t.jsx)(n.code,{children:"?start_from=ID"}),", where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["The server keeps only a limited number of events cached to allow replaying the stream to clients using the ",(0,t.jsx)(n.code,{children:"?start_from="})," query string. The cache size can be set differently on each node using the ",(0,t.jsx)(n.code,{children:"event_stream_buffer_length"})," value in the ",(0,t.jsx)(n.em,{children:"config.toml"}),". By default, it is only 5000.\nThe intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected."]})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var t=s(96540);const a={},i=t.createContext(a);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/33a9c3bd.2116c2c6.js b/assets/js/33a9c3bd.2116c2c6.js new file mode 100644 index 000000000..fab272eee --- /dev/null +++ b/assets/js/33a9c3bd.2116c2c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[38631],{48018:l=>{l.exports=JSON.parse('{"tag":{"label":"hello","permalink":"/blog/tags/hello","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/hello","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/33a9c3bd.3a1f4799.js b/assets/js/33a9c3bd.3a1f4799.js deleted file mode 100644 index a8666ddec..000000000 --- a/assets/js/33a9c3bd.3a1f4799.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8631],{48018:l=>{l.exports=JSON.parse('{"tag":{"label":"hello","permalink":"/blog/tags/hello","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/hello","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/33fc5bb8.1380a971.js b/assets/js/33fc5bb8.1380a971.js new file mode 100644 index 000000000..ec2caed42 --- /dev/null +++ b/assets/js/33fc5bb8.1380a971.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50867],{30778:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(96540);var s=a(34164),r=a(45500),n=a(17559),o=a(96461),l=a(28774),i=a(44096),c=a(28027),d=a(47713),u=a(41463),m=a(33892),g=a(56913),h=a(74848);function p(e){let{author:t}=e;const a=(0,o.wI)(t);return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(r.be,{title:a}),(0,h.jsx)(u.A,{tag:"blog_authors_posts"})]})}function x(){const{authorsListPath:e}=(0,i.x)();return(0,h.jsx)(l.A,{href:e,children:(0,h.jsx)(o.np,{})})}function j(e){let{author:t,items:a,sidebar:s,listMetadata:r}=e;return(0,h.jsxs)(c.A,{sidebar:s,children:[(0,h.jsxs)("header",{className:"margin-bottom--xl",children:[(0,h.jsx)(g.A,{as:"h1",author:t}),t.description&&(0,h.jsx)("p",{children:t.description}),(0,h.jsx)(x,{})]}),(0,h.jsx)("hr",{}),(0,h.jsx)(m.A,{items:a}),(0,h.jsx)(d.A,{metadata:r})]})}function b(e){return(0,h.jsxs)(r.e3,{className:(0,s.A)(n.G.wrapper.blogPages,n.G.page.blogAuthorsPostsPage),children:[(0,h.jsx)(p,{...e}),(0,h.jsx)(j,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var s=a(21312),r=a(39022),n=a(74848);function o(e){const{metadata:t}=e,{previousPage:a,nextPage:o}=t;return(0,n.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,n.jsx)(r.A,{permalink:a,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),o&&(0,n.jsx)(r.A,{permalink:o,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,a)=>{a.d(t,{A:()=>O});a(96540);var s=a(34164),r=a(44096),n=a(74848);function o(e){let{children:t,className:a}=e;return(0,n.jsx)("article",{className:a,children:t})}var l=a(28774);const i={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,r.e7)(),{permalink:c,title:d}=a,u=o?"h1":"h2";return(0,n.jsx)(u,{className:(0,s.A)(i.title,t),children:o?d:(0,n.jsx)(l.A,{to:c,children:d})})}var d=a(21312),u=a(53465),m=a(36266);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,u.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,n.jsx)(n.Fragment,{children:a(t)})}function p(e){let{date:t,formattedDate:a}=e;return(0,n.jsx)("time",{dateTime:t,children:a})}function x(){return(0,n.jsx)(n.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:a}=(0,r.e7)(),{date:o,readingTime:l}=a,i=(0,m.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,n.jsxs)("div",{className:(0,s.A)(g.container,"margin-vert--md",t),children:[(0,n.jsx)(p,{date:o,formattedDate:(c=o,i.format(new Date(c)))}),void 0!==l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(x,{}),(0,n.jsx)(h,{readingTime:l})]})]});var c}var b=a(56913);const f={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,r.e7)();if(0===a.length)return null;const l=a.every((e=>{let{name:t}=e;return!t})),i=1===a.length;return(0,n.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?f.imageOnlyAuthorRow:"row",t),children:a.map(((e,t)=>(0,n.jsx)("div",{className:(0,s.A)(!l&&(i?"col col--12":"col col--6"),l?f.imageOnlyAuthorCol:f.authorCol),children:(0,n.jsx)(b.A,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,n.jsxs)("header",{children:[(0,n.jsx)(c,{}),(0,n.jsx)(j,{}),(0,n.jsx)(A,{})]})}var T=a(70440),N=a(88509);function w(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,r.e7)();return(0,n.jsx)("div",{id:o?T.LU:void 0,className:(0,s.A)("markdown",a),children:(0,n.jsx)(N.A,{children:t})})}var P=a(17559),y=a(4336),k=a(62053);function _(){return(0,n.jsx)("b",{children:(0,n.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function U(e){const{blogPostTitle:t,...a}=e;return(0,n.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,n.jsx)(_,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,r.e7)(),{tags:a,title:o,editUrl:l,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=a.length>0;if(!(m||u||l))return null;if(t){const e=!!(l||d||c);return(0,n.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,n.jsx)("div",{className:(0,s.A)("row","margin-top--sm",P.G.blog.blogFooterEditMetaRow),children:(0,n.jsx)("div",{className:"col",children:(0,n.jsx)(k.A,{tags:a})})}),e&&(0,n.jsx)(y.A,{className:(0,s.A)("margin-top--sm",P.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,n.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,n.jsx)("div",{className:(0,s.A)("col",{"col--9":u}),children:(0,n.jsx)(k.A,{tags:a})}),u&&(0,n.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":m}),children:(0,n.jsx)(U,{blogPostTitle:o,to:e.permalink})})]})}function O(e){let{children:t,className:a}=e;const l=function(){const{isBlogPostPage:e}=(0,r.e7)();return e?void 0:"margin-bottom--xl"}();return(0,n.jsxs)(o,{className:(0,s.A)(l,a),children:[(0,n.jsx)(v,{}),(0,n.jsx)(w,{children:t}),(0,n.jsx)(R,{})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var s=a(44096),r=a(82907),n=a(74848);function o(e){let{items:t,component:a=r.A}=e;return(0,n.jsx)(n.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,n.jsx)(s.in,{content:t,children:(0,n.jsx)(a,{children:(0,n.jsx)(t,{})})},t.metadata.permalink)}))})}},96461:(e,t,a)=>{a.d(t,{ZD:()=>l,np:()=>d,uz:()=>c,wI:()=>i});a(96540);var s=a(21312),r=a(53465),n=a(74848);function o(){const{selectMessage:e}=(0,r.W)();return t=>e(t,(0,s.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function l(e){const t=o();return(0,s.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function i(e){const t=o();return(0,s.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:t(e.count),authorName:e.name||e.key})}const c=()=>(0,s.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function d(){return(0,n.jsx)(s.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}}}]); \ No newline at end of file diff --git a/assets/js/33fc5bb8.4b577c2a.js b/assets/js/33fc5bb8.4b577c2a.js deleted file mode 100644 index 98820348b..000000000 --- a/assets/js/33fc5bb8.4b577c2a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[867],{30778:(e,t,a)=>{a.r(t),a.d(t,{default:()=>b});a(96540);var s=a(34164),r=a(45500),n=a(17559),o=a(96461),l=a(28774),i=a(44096),c=a(28027),d=a(47713),u=a(41463),m=a(33892),g=a(56913),h=a(74848);function p(e){let{author:t}=e;const a=(0,o.wI)(t);return(0,h.jsxs)(h.Fragment,{children:[(0,h.jsx)(r.be,{title:a}),(0,h.jsx)(u.A,{tag:"blog_authors_posts"})]})}function x(){const{authorsListPath:e}=(0,i.x)();return(0,h.jsx)(l.A,{href:e,children:(0,h.jsx)(o.np,{})})}function j(e){let{author:t,items:a,sidebar:s,listMetadata:r}=e;return(0,h.jsxs)(c.A,{sidebar:s,children:[(0,h.jsxs)("header",{className:"margin-bottom--xl",children:[(0,h.jsx)(g.A,{as:"h1",author:t}),t.description&&(0,h.jsx)("p",{children:t.description}),(0,h.jsx)(x,{})]}),(0,h.jsx)("hr",{}),(0,h.jsx)(m.A,{items:a}),(0,h.jsx)(d.A,{metadata:r})]})}function b(e){return(0,h.jsxs)(r.e3,{className:(0,s.A)(n.G.wrapper.blogPages,n.G.page.blogAuthorsPostsPage),children:[(0,h.jsx)(p,{...e}),(0,h.jsx)(j,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var s=a(21312),r=a(39022),n=a(74848);function o(e){const{metadata:t}=e,{previousPage:a,nextPage:o}=t;return(0,n.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,n.jsx)(r.A,{permalink:a,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),o&&(0,n.jsx)(r.A,{permalink:o,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,a)=>{a.d(t,{A:()=>O});a(96540);var s=a(34164),r=a(44096),n=a(74848);function o(e){let{children:t,className:a}=e;return(0,n.jsx)("article",{className:a,children:t})}var l=a(28774);const i={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:o}=(0,r.e7)(),{permalink:c,title:d}=a,u=o?"h1":"h2";return(0,n.jsx)(u,{className:(0,s.A)(i.title,t),children:o?d:(0,n.jsx)(l.A,{to:c,children:d})})}var d=a(21312),u=a(53465),m=a(36266);const g={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,u.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,n.jsx)(n.Fragment,{children:a(t)})}function p(e){let{date:t,formattedDate:a}=e;return(0,n.jsx)("time",{dateTime:t,children:a})}function x(){return(0,n.jsx)(n.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:a}=(0,r.e7)(),{date:o,readingTime:l}=a,i=(0,m.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,n.jsxs)("div",{className:(0,s.A)(g.container,"margin-vert--md",t),children:[(0,n.jsx)(p,{date:o,formattedDate:(c=o,i.format(new Date(c)))}),void 0!==l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(x,{}),(0,n.jsx)(h,{readingTime:l})]})]});var c}var b=a(56913);const f={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:a},assets:o}=(0,r.e7)();if(0===a.length)return null;const l=a.every((e=>{let{name:t}=e;return!t})),i=1===a.length;return(0,n.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?f.imageOnlyAuthorRow:"row",t),children:a.map(((e,t)=>(0,n.jsx)("div",{className:(0,s.A)(!l&&(i?"col col--12":"col col--6"),l?f.imageOnlyAuthorCol:f.authorCol),children:(0,n.jsx)(b.A,{author:{...e,imageURL:o.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,n.jsxs)("header",{children:[(0,n.jsx)(c,{}),(0,n.jsx)(j,{}),(0,n.jsx)(A,{})]})}var T=a(70440),N=a(88509);function w(e){let{children:t,className:a}=e;const{isBlogPostPage:o}=(0,r.e7)();return(0,n.jsx)("div",{id:o?T.LU:void 0,className:(0,s.A)("markdown",a),children:(0,n.jsx)(N.A,{children:t})})}var P=a(17559),y=a(4336),k=a(62053);function _(){return(0,n.jsx)("b",{children:(0,n.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function U(e){const{blogPostTitle:t,...a}=e;return(0,n.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,n.jsx)(_,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,r.e7)(),{tags:a,title:o,editUrl:l,hasTruncateMarker:i,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&i,m=a.length>0;if(!(m||u||l))return null;if(t){const e=!!(l||d||c);return(0,n.jsxs)("footer",{className:"docusaurus-mt-lg",children:[m&&(0,n.jsx)("div",{className:(0,s.A)("row","margin-top--sm",P.G.blog.blogFooterEditMetaRow),children:(0,n.jsx)("div",{className:"col",children:(0,n.jsx)(k.A,{tags:a})})}),e&&(0,n.jsx)(y.A,{className:(0,s.A)("margin-top--sm",P.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,n.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[m&&(0,n.jsx)("div",{className:(0,s.A)("col",{"col--9":u}),children:(0,n.jsx)(k.A,{tags:a})}),u&&(0,n.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":m}),children:(0,n.jsx)(U,{blogPostTitle:o,to:e.permalink})})]})}function O(e){let{children:t,className:a}=e;const l=function(){const{isBlogPostPage:e}=(0,r.e7)();return e?void 0:"margin-bottom--xl"}();return(0,n.jsxs)(o,{className:(0,s.A)(l,a),children:[(0,n.jsx)(v,{}),(0,n.jsx)(w,{children:t}),(0,n.jsx)(R,{})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>o});a(96540);var s=a(44096),r=a(82907),n=a(74848);function o(e){let{items:t,component:a=r.A}=e;return(0,n.jsx)(n.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,n.jsx)(s.in,{content:t,children:(0,n.jsx)(a,{children:(0,n.jsx)(t,{})})},t.metadata.permalink)}))})}},96461:(e,t,a)=>{a.d(t,{ZD:()=>l,np:()=>d,uz:()=>c,wI:()=>i});a(96540);var s=a(21312),r=a(53465),n=a(74848);function o(){const{selectMessage:e}=(0,r.W)();return t=>e(t,(0,s.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function l(e){const t=o();return(0,s.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function i(e){const t=o();return(0,s.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:t(e.count),authorName:e.name||e.key})}const c=()=>(0,s.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function d(){return(0,n.jsx)(s.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}}}]); \ No newline at end of file diff --git a/assets/js/340c2365.a24dd798.js b/assets/js/340c2365.a24dd798.js deleted file mode 100644 index 11865e7e0..000000000 --- a/assets/js/340c2365.a24dd798.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1187],{62651:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={title:"Installation"},i="Installing a Node",a={id:"operators/setup/install-node",title:"Installation",description:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.",source:"@site/versioned_docs/version-1.5.X/operators/setup/install-node.md",sourceDirName:"operators/setup",slug:"/operators/setup/install-node",permalink:"/operators/setup/install-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installation"},sidebar:"operators",previous:{title:"Endpoints",permalink:"/operators/setup/node-endpoints"},next:{title:"Fast Sync",permalink:"/operators/setup/fast-sync"}},l={},c=[{value:"Network Requirements",id:"network-requirements",level:2},{value:"Operating System Requirements",id:"operating-system-requirements",level:2},{value:"Using Ubuntu 22.04",id:"using-ubuntu-2204",level:3},{value:"Required Number of Open Files",id:"required-number-of-open-files",level:2},{value:"Required Clean Up",id:"required-clean-up",level:2},{value:"Required Packages",id:"required-packages",level:2},{value:"Required Tools",id:"required-tools",level:2},{value:"Enable Bash Auto-Completion for <code>casper-client</code> (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load <code>trusted_hash</code> in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-a-node",children:"Installing a Node"})}),"\n",(0,t.jsx)(n.p,{children:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."}),"\n",(0,t.jsx)(n.h2,{id:"network-requirements",children:"Network Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The following ports are used by the node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"35000 (required to be externally visible)"}),"\n",(0,t.jsx)(n.li,{children:"7777 RPC endpoint for interaction with JSON-RPC API"}),"\n",(0,t.jsx)(n.li,{children:"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"}),"\n",(0,t.jsx)(n.li,{children:"9999 SSE endpoint for event stream"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Of these ",(0,t.jsx)(n.code,{children:"35000"})," is the only port required to be open for your node to function, however, opening ",(0,t.jsx)(n.code,{children:"8888"})," will allow others to know general network health. For more details, see the additional information on ",(0,t.jsx)(n.a,{href:"/operators/setup/node-endpoints",children:"Node Endpoints"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"operating-system-requirements",children:"Operating System Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The recommended OS version is Ubuntu 20.04."}),"\n",(0,t.jsx)(n.h3,{id:"using-ubuntu-2204",children:"Using Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"}),"\n",(0,t.jsx)(n.p,{children:"If you try to install packages, you will receive:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This message is due to the default ",(0,t.jsx)(n.code,{children:"openssl"})," moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-number-of-open-files",children:"Required Number of Open Files"}),"\n",(0,t.jsxs)(n.p,{children:["Before beginning, ",(0,t.jsx)(n.a,{href:"/operators/setup/open-files",children:"update the maximum open files limit"})," for your system. Specifically, update the node's ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file as described ",(0,t.jsx)(n.a,{href:"/operators/setup/open-files#updating-limits-conf",children:"here"}),", to ensure proper node operation."]}),"\n",(0,t.jsx)(n.h2,{id:"required-clean-up",children:"Required Clean Up"}),"\n",(0,t.jsxs)(n.p,{children:["If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,t.jsx)(n.code,{children:"apt remove"})," may give errors, but this is not a problem."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-packages",children:"Required Packages"}),"\n",(0,t.jsx)(n.p,{children:"The following commands will set up the Casper Labs repository for packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n'})}),"\n",(0,t.jsx)(n.h2,{id:"required-tools",children:"Required Tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install -y casper-client casper-node-launcher jq\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"enable-bash-auto-completion-for-casper-client-optional",children:["Enable Bash Auto-Completion for ",(0,t.jsx)(n.code,{children:"casper-client"})," (Optional)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo casper-client generate-completion\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It defaults to ",(0,t.jsx)(n.code,{children:"bash"})," but can be changed with the ",(0,t.jsx)(n.code,{children:"--shell"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"--shell <STRING> The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n"})}),"\n",(0,t.jsx)(n.p,{children:"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source /usr/share/bash-completion/completions/casper-client\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now you can use ",(0,t.jsx)(n.code,{children:"casper-client"})," and press the ",(0,t.jsx)(n.code,{children:"tab"})," key to get auto completion for your commands."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-all-protocols",children:"Installing All Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Mainnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Testnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,t.jsx)(n.h2,{id:"validator-keys",children:"Validator Keys"}),"\n",(0,t.jsx)(n.p,{children:"If you do not have keys yet, you can create them using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-a-trusted-hash",children:"Getting a Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["In the past, we have used a lower ",(0,t.jsx)(n.code,{children:"trusted_hash"}),". Connecting at the tip, we now use as high of a ",(0,t.jsx)(n.code,{children:"trusted_hash"})," as possible. Find out more about ",(0,t.jsx)(n.a,{href:"/operators/setup/fast-sync",children:"Fast Sync"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"node-address",children:"Node Address"}),"\n",(0,t.jsx)(n.p,{children:"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"}),"\n",(0,t.jsxs)(n.p,{children:["You can find active peers at ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"https://cspr.live/tools/peers"})," or use the following Casper Labs public nodes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Testnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io",children:"https://rpc.testnet.casperlabs.io"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Mainnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io",children:"https://rpc.mainnet.casperlabs.io"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,t.jsxs)(n.p,{children:["Protocol version should be set to the largest available protocol version you see in ",(0,t.jsx)(n.code,{children:"ls /etc/casper"}),". As of writing this, it was 1_5_2:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"PROTOCOL=1_5_2\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"load-trusted_hash-in-configtoml-of-the-protocol-version",children:["Load ",(0,t.jsx)(n.code,{children:"trusted_hash"})," in Config.toml of the Protocol Version"]}),"\n",(0,t.jsxs)(n.p,{children:["The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,t.jsx)(n.code,{children:"trusted_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"syncing-to-genesis",children:"Syncing to Genesis"}),"\n",(0,t.jsxs)(n.p,{children:["In the latest protocol version's ",(0,t.jsx)(n.em,{children:"Config.toml"}),", you will find the option ",(0,t.jsx)(n.code,{children:"sync_to_genesis"}),". By default, this value will be set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sync_to_genesis = false\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."}),"\n",(0,t.jsx)(n.h2,{id:"starting-the-node",children:"Starting the Node"}),"\n",(0,t.jsx)(n.p,{children:"Start the node using the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n"})}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-synchronization-process",children:"Monitoring the Synchronization Process"}),"\n",(0,t.jsx)(n.p,{children:"The following command will display the node synchronization details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"/etc/casper/node_util.py watch\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When you first run the watch command, you may see the message ",(0,t.jsx)(n.code,{children:"RPC: Not Ready"}),". Once the node is synchronized, the status will change to ",(0,t.jsx)(n.code,{children:"RPC: Ready"})," and a similar output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,t.jsx)(n.code,{children:"sync_to_genesis"})," as ",(0,t.jsx)(n.code,{children:"true"}),", it will begin syncing back history at this time."]}),"\n",(0,t.jsx)(n.p,{children:"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the node is not showing active (running) status, it is either stopped or in the process of restarting."}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-running-node",children:"Monitoring the Running Node"}),"\n",(0,t.jsx)(n.p,{children:"The community has created a few tools to monitor your node once it is running, such as:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Status.py: ",(0,t.jsx)(n.a,{href:"https://github.com/RapidMark/casper-tools",children:"https://github.com/RapidMark/casper-tools"})]}),"\n",(0,t.jsxs)(n.li,{children:["Grafana: ",(0,t.jsx)(n.a,{href:"https://github.com/matsuro-hadouken/casper-tools",children:"https://github.com/matsuro-hadouken/casper-tools"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"a-note-on-speculative-execution",children:"A Note on Speculative Execution"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"speculative_exec_server"})," defaults to off and can be enabled in your ",(0,t.jsx)(n.em,{children:"Config.toml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"should not"})})," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/340c2365.f9fb5495.js b/assets/js/340c2365.f9fb5495.js new file mode 100644 index 000000000..a0c9ab153 --- /dev/null +++ b/assets/js/340c2365.f9fb5495.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11187],{62651:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={title:"Installation"},i="Installing a Node",a={id:"operators/setup/install-node",title:"Installation",description:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.",source:"@site/versioned_docs/version-1.5.X/operators/setup/install-node.md",sourceDirName:"operators/setup",slug:"/operators/setup/install-node",permalink:"/1.5.X/operators/setup/install-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installation"},sidebar:"operators",previous:{title:"Endpoints",permalink:"/1.5.X/operators/setup/node-endpoints"},next:{title:"Fast Sync",permalink:"/1.5.X/operators/setup/fast-sync"}},l={},c=[{value:"Network Requirements",id:"network-requirements",level:2},{value:"Operating System Requirements",id:"operating-system-requirements",level:2},{value:"Using Ubuntu 22.04",id:"using-ubuntu-2204",level:3},{value:"Required Number of Open Files",id:"required-number-of-open-files",level:2},{value:"Required Clean Up",id:"required-clean-up",level:2},{value:"Required Packages",id:"required-packages",level:2},{value:"Required Tools",id:"required-tools",level:2},{value:"Enable Bash Auto-Completion for <code>casper-client</code> (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load <code>trusted_hash</code> in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-a-node",children:"Installing a Node"})}),"\n",(0,t.jsx)(n.p,{children:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."}),"\n",(0,t.jsx)(n.h2,{id:"network-requirements",children:"Network Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The following ports are used by the node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"35000 (required to be externally visible)"}),"\n",(0,t.jsx)(n.li,{children:"7777 RPC endpoint for interaction with JSON-RPC API"}),"\n",(0,t.jsx)(n.li,{children:"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"}),"\n",(0,t.jsx)(n.li,{children:"9999 SSE endpoint for event stream"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Of these ",(0,t.jsx)(n.code,{children:"35000"})," is the only port required to be open for your node to function, however, opening ",(0,t.jsx)(n.code,{children:"8888"})," will allow others to know general network health. For more details, see the additional information on ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/node-endpoints",children:"Node Endpoints"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"operating-system-requirements",children:"Operating System Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The recommended OS version is Ubuntu 20.04."}),"\n",(0,t.jsx)(n.h3,{id:"using-ubuntu-2204",children:"Using Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"}),"\n",(0,t.jsx)(n.p,{children:"If you try to install packages, you will receive:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This message is due to the default ",(0,t.jsx)(n.code,{children:"openssl"})," moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-number-of-open-files",children:"Required Number of Open Files"}),"\n",(0,t.jsxs)(n.p,{children:["Before beginning, ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/open-files",children:"update the maximum open files limit"})," for your system. Specifically, update the node's ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file as described ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/open-files#updating-limits-conf",children:"here"}),", to ensure proper node operation."]}),"\n",(0,t.jsx)(n.h2,{id:"required-clean-up",children:"Required Clean Up"}),"\n",(0,t.jsxs)(n.p,{children:["If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,t.jsx)(n.code,{children:"apt remove"})," may give errors, but this is not a problem."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-packages",children:"Required Packages"}),"\n",(0,t.jsx)(n.p,{children:"The following commands will set up the Casper Labs repository for packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n'})}),"\n",(0,t.jsx)(n.h2,{id:"required-tools",children:"Required Tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install -y casper-client casper-node-launcher jq\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"enable-bash-auto-completion-for-casper-client-optional",children:["Enable Bash Auto-Completion for ",(0,t.jsx)(n.code,{children:"casper-client"})," (Optional)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo casper-client generate-completion\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It defaults to ",(0,t.jsx)(n.code,{children:"bash"})," but can be changed with the ",(0,t.jsx)(n.code,{children:"--shell"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"--shell <STRING> The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n"})}),"\n",(0,t.jsx)(n.p,{children:"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source /usr/share/bash-completion/completions/casper-client\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now you can use ",(0,t.jsx)(n.code,{children:"casper-client"})," and press the ",(0,t.jsx)(n.code,{children:"tab"})," key to get auto completion for your commands."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-all-protocols",children:"Installing All Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Mainnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Testnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,t.jsx)(n.h2,{id:"validator-keys",children:"Validator Keys"}),"\n",(0,t.jsx)(n.p,{children:"If you do not have keys yet, you can create them using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-a-trusted-hash",children:"Getting a Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["In the past, we have used a lower ",(0,t.jsx)(n.code,{children:"trusted_hash"}),". Connecting at the tip, we now use as high of a ",(0,t.jsx)(n.code,{children:"trusted_hash"})," as possible. Find out more about ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/fast-sync",children:"Fast Sync"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"node-address",children:"Node Address"}),"\n",(0,t.jsx)(n.p,{children:"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"}),"\n",(0,t.jsxs)(n.p,{children:["You can find active peers at ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"https://cspr.live/tools/peers"})," or use the following Casper Labs public nodes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Testnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io",children:"https://rpc.testnet.casperlabs.io"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Mainnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io",children:"https://rpc.mainnet.casperlabs.io"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,t.jsxs)(n.p,{children:["Protocol version should be set to the largest available protocol version you see in ",(0,t.jsx)(n.code,{children:"ls /etc/casper"}),". As of writing this, it was 1_5_2:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"PROTOCOL=1_5_2\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"load-trusted_hash-in-configtoml-of-the-protocol-version",children:["Load ",(0,t.jsx)(n.code,{children:"trusted_hash"})," in Config.toml of the Protocol Version"]}),"\n",(0,t.jsxs)(n.p,{children:["The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,t.jsx)(n.code,{children:"trusted_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"syncing-to-genesis",children:"Syncing to Genesis"}),"\n",(0,t.jsxs)(n.p,{children:["In the latest protocol version's ",(0,t.jsx)(n.em,{children:"Config.toml"}),", you will find the option ",(0,t.jsx)(n.code,{children:"sync_to_genesis"}),". By default, this value will be set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sync_to_genesis = false\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."}),"\n",(0,t.jsx)(n.h2,{id:"starting-the-node",children:"Starting the Node"}),"\n",(0,t.jsx)(n.p,{children:"Start the node using the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n"})}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-synchronization-process",children:"Monitoring the Synchronization Process"}),"\n",(0,t.jsx)(n.p,{children:"The following command will display the node synchronization details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"/etc/casper/node_util.py watch\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When you first run the watch command, you may see the message ",(0,t.jsx)(n.code,{children:"RPC: Not Ready"}),". Once the node is synchronized, the status will change to ",(0,t.jsx)(n.code,{children:"RPC: Ready"})," and a similar output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,t.jsx)(n.code,{children:"sync_to_genesis"})," as ",(0,t.jsx)(n.code,{children:"true"}),", it will begin syncing back history at this time."]}),"\n",(0,t.jsx)(n.p,{children:"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the node is not showing active (running) status, it is either stopped or in the process of restarting."}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-running-node",children:"Monitoring the Running Node"}),"\n",(0,t.jsx)(n.p,{children:"The community has created a few tools to monitor your node once it is running, such as:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Status.py: ",(0,t.jsx)(n.a,{href:"https://github.com/RapidMark/casper-tools",children:"https://github.com/RapidMark/casper-tools"})]}),"\n",(0,t.jsxs)(n.li,{children:["Grafana: ",(0,t.jsx)(n.a,{href:"https://github.com/matsuro-hadouken/casper-tools",children:"https://github.com/matsuro-hadouken/casper-tools"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"a-note-on-speculative-execution",children:"A Note on Speculative Execution"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"speculative_exec_server"})," defaults to off and can be enabled in your ",(0,t.jsx)(n.em,{children:"Config.toml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"should not"})})," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/34b086e1.d56022ae.js b/assets/js/34b086e1.d56022ae.js new file mode 100644 index 000000000..64585a768 --- /dev/null +++ b/assets/js/34b086e1.d56022ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50140],{98733:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var t=n(74848),s=n(28453);const a={title:"Consensus"},o="Consensus Economics",r={id:"concepts/economics/consensus",title:"Consensus",description:"Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/consensus.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/consensus",permalink:"/1.5.X/concepts/economics/consensus",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Consensus"},sidebar:"concepts",previous:{title:"Overview",permalink:"/1.5.X/economics"},next:{title:"Runtime",permalink:"/1.5.X/runtime"}},c={},d=[{value:"Entry",id:"entry",level:2},{value:"Bids",id:"bids",level:3},{value:"Delegation",id:"delegation",level:3},{value:"Incentives",id:"incentives",level:2},{value:"Participation",id:"participation",level:3},{value:"Distribution",id:"distribution",level:4},{value:"Participation schedule",id:"participation-schedule",level:5},{value:"Eligibility",id:"eligibility",level:5},{value:"Inactivity",id:"inactivity",level:3},{value:"Slashing",id:"slashing",level:3},{value:"Founding validators",id:"founding-validators",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"consensus-economics",children:"Consensus Economics"})}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.a,{href:"/1.5.X/concepts/design/highway",children:"Highway consensus"})," is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule."]}),"\n",(0,t.jsx)(i.h2,{id:"entry",children:"Entry"}),"\n",(0,t.jsxs)(i.p,{children:["After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a ",(0,t.jsx)(i.em,{children:"chainspec"})," configuration file specifies a few key parameters:"]}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"auction_delay"})," specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the ",(0,t.jsx)(i.em,{children:"auction_delay"})," is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era."]}),"\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"validator_slots"})," parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids."]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"bids",children:"Bids"}),"\n",(0,t.jsxs)(i.p,{children:["Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the ",(0,t.jsx)(i.code,{children:"unbonding_delay"})," chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners."]}),"\n",(0,t.jsx)(i.p,{children:"Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document."}),"\n",(0,t.jsx)(i.h3,{id:"delegation",children:"Delegation"}),"\n",(0,t.jsx)(i.p,{children:"Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate."}),"\n",(0,t.jsxs)(i.p,{children:["Currently, delegation is unrestricted. Please visit ",(0,t.jsx)(i.a,{href:"/1.5.X/concepts/economics/delegation",children:"Delegation details"})," page to check more about delegation cost and related details."]}),"\n",(0,t.jsx)(i.h2,{id:"incentives",children:"Incentives"}),"\n",(0,t.jsx)(i.p,{children:"Correct operation of the Highway protocol requires the economics of the platform to discourage equivocation for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals."}),"\n",(0,t.jsx)(i.p,{children:"Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future."}),"\n",(0,t.jsx)(i.p,{children:"The network incentivizes participation by scaling rewards for on-time proposals and responses, taking into account the speed of finalizing blocks. All rewards are added directly to the corresponding bids and delegations."}),"\n",(0,t.jsx)(i.h3,{id:"participation",children:"Participation"}),"\n",(0,t.jsx)(i.p,{children:"Issuance of new tokens and their distribution to validators incentivizes work even under low transaction load."}),"\n",(0,t.jsx)(i.p,{children:"CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"The growth of CSPR supply is exponential"}),"\n",(0,t.jsx)(i.li,{children:"Issuance takes into account slashed CSPR"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"i"})," - the era's index as a positive integer [0, 1, 2, ..., n]"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"initial_supply"})," - the number of CSPR at genesis"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"issuance_rate"})," - the annual rate at which new CSPR tokens are minted"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"ticks_per_year"})," - the number of milliseconds in a year equal to 31,536,000,000"]}),"\n"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)\n"})}),"\n",(0,t.jsxs)(i.p,{children:["We introduce the ",(0,t.jsx)(i.em,{children:"round issuance rate"})," (corresponding to the chainspec parameter ",(0,t.jsx)(i.code,{children:"round_seigniorage_rate"}),") with this formula:"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1\n"})}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.em,{children:"round issuance rate"})," is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter ",(0,t.jsx)(i.code,{children:"minimum_round_exponent"}),". For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds."]}),"\n",(0,t.jsx)(i.p,{children:"Finally, the base round reward is computed as:"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"base_round_reward(i) = round_issuance_rate * supply(i)\n"})}),"\n",(0,t.jsx)(i.p,{children:"This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block."}),"\n",(0,t.jsx)(i.h4,{id:"distribution",children:"Distribution"}),"\n",(0,t.jsx)(i.p,{children:"Validators receive tokens for proposing and finalizing blocks according to their performance. The concept of weight is crucial for understanding this distribution scheme:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Weight:"})," A validator's bonded stake, used in consensus"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Assigned weight of a block/round:"})," The total stake of validators scheduled to participate in a block"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Participated weight of a block/round:"})," The total stake of validators that end up participating or sending messages to finalize a block before the end of their respective round"]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["To determine eligibility, we look at ",(0,t.jsx)(i.strong,{children:"on-time finalization (OTF)"}),". Validators should finalize blocks on time by sending required messages before the end of their respective round."]}),"\n",(0,t.jsx)(i.p,{children:"Switch blocks are not visible to the issuance calculation (as this calculation is performed in the switch block itself for each era), and, consequently, no tokens are issued for switch blocks."}),"\n",(0,t.jsx)(i.h5,{id:"participation-schedule",children:"Participation schedule"}),"\n",(0,t.jsxs)(i.p,{children:["The participation schedule is segmented into rounds, which are allocated dynamically according to the validators' exponents and a deterministic (randomized at era start) assignment of validators to milliseconds of an era. Thus, a validator with the round exponent ",(0,t.jsx)(i.code,{children:"n"})," must participate in rounds that repeat every ",(0,t.jsx)(i.code,{children:"2^n"})," ticks."]}),"\n",(0,t.jsx)(i.p,{children:"Each validator is assessed according to its round exponent. All assigned validators become eligible to receive tokens as long as the block gets finalized with messages sent within each validator's round."}),"\n",(0,t.jsx)(i.h5,{id:"eligibility",children:"Eligibility"}),"\n",(0,t.jsxs)(i.p,{children:["Once a block has been proposed and enough time has passed, the history of protocol messages can be examined to detect whether the block was finalized on time, according to the conditions given above. If the block was ",(0,t.jsx)(i.em,{children:"not"})," finalized on time, validators receive a fraction of the expected tokens, governed by the ",(0,t.jsx)(i.code,{children:"reduced_reward_multiplier"})," chainspec parameter. If the block was finalized on time, assigned validators share the reward proportionally to their stake, regardless of whether they have sent messages or not."]}),"\n",(0,t.jsx)(i.h3,{id:"inactivity",children:"Inactivity"}),"\n",(0,t.jsx)(i.p,{children:"Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special deploy that reactivates their bid."}),"\n",(0,t.jsx)(i.h3,{id:"slashing",children:"Slashing"}),"\n",(0,t.jsxs)(i.p,{children:["Please review our ",(0,t.jsx)(i.a,{href:"https://github.com/casper-network/ceps/blob/master/text/0038-equivocator-policy.md",children:"Equivocator Policy"}),". We are currently conducting research into the utility of slashing as an incentive mechanism."]}),"\n",(0,t.jsx)(i.h2,{id:"founding-validators",children:"Founding validators"}),"\n",(0,t.jsx)(i.p,{children:"Founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days, then releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days."})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>o,x:()=>r});var t=n(96540);const s={},a=t.createContext(s);function o(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/34b086e1.d5c23182.js b/assets/js/34b086e1.d5c23182.js deleted file mode 100644 index af8c33217..000000000 --- a/assets/js/34b086e1.d5c23182.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[140],{98733:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var t=n(74848),s=n(28453);const a={title:"Consensus"},o="Consensus Economics",r={id:"concepts/economics/consensus",title:"Consensus",description:"Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/consensus.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/consensus",permalink:"/concepts/economics/consensus",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Consensus"},sidebar:"concepts",previous:{title:"Overview",permalink:"/economics"},next:{title:"Runtime",permalink:"/runtime"}},c={},d=[{value:"Entry",id:"entry",level:2},{value:"Bids",id:"bids",level:3},{value:"Delegation",id:"delegation",level:3},{value:"Incentives",id:"incentives",level:2},{value:"Participation",id:"participation",level:3},{value:"Distribution",id:"distribution",level:4},{value:"Participation schedule",id:"participation-schedule",level:5},{value:"Eligibility",id:"eligibility",level:5},{value:"Inactivity",id:"inactivity",level:3},{value:"Slashing",id:"slashing",level:3},{value:"Founding validators",id:"founding-validators",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",h5:"h5",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"consensus-economics",children:"Consensus Economics"})}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.a,{href:"/concepts/design/highway",children:"Highway consensus"})," is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule."]}),"\n",(0,t.jsx)(i.h2,{id:"entry",children:"Entry"}),"\n",(0,t.jsxs)(i.p,{children:["After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a ",(0,t.jsx)(i.em,{children:"chainspec"})," configuration file specifies a few key parameters:"]}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"auction_delay"})," specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the ",(0,t.jsx)(i.em,{children:"auction_delay"})," is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era."]}),"\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"validator_slots"})," parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids."]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"bids",children:"Bids"}),"\n",(0,t.jsxs)(i.p,{children:["Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the ",(0,t.jsx)(i.code,{children:"unbonding_delay"})," chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners."]}),"\n",(0,t.jsx)(i.p,{children:"Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document."}),"\n",(0,t.jsx)(i.h3,{id:"delegation",children:"Delegation"}),"\n",(0,t.jsx)(i.p,{children:"Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate."}),"\n",(0,t.jsxs)(i.p,{children:["Currently, delegation is unrestricted. Please visit ",(0,t.jsx)(i.a,{href:"/concepts/economics/delegation",children:"Delegation details"})," page to check more about delegation cost and related details."]}),"\n",(0,t.jsx)(i.h2,{id:"incentives",children:"Incentives"}),"\n",(0,t.jsx)(i.p,{children:"Correct operation of the Highway protocol requires the economics of the platform to discourage equivocation for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals."}),"\n",(0,t.jsx)(i.p,{children:"Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future."}),"\n",(0,t.jsx)(i.p,{children:"The network incentivizes participation by scaling rewards for on-time proposals and responses, taking into account the speed of finalizing blocks. All rewards are added directly to the corresponding bids and delegations."}),"\n",(0,t.jsx)(i.h3,{id:"participation",children:"Participation"}),"\n",(0,t.jsx)(i.p,{children:"Issuance of new tokens and their distribution to validators incentivizes work even under low transaction load."}),"\n",(0,t.jsx)(i.p,{children:"CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"The growth of CSPR supply is exponential"}),"\n",(0,t.jsx)(i.li,{children:"Issuance takes into account slashed CSPR"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"i"})," - the era's index as a positive integer [0, 1, 2, ..., n]"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"initial_supply"})," - the number of CSPR at genesis"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"issuance_rate"})," - the annual rate at which new CSPR tokens are minted"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"ticks_per_year"})," - the number of milliseconds in a year equal to 31,536,000,000"]}),"\n"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)\n"})}),"\n",(0,t.jsxs)(i.p,{children:["We introduce the ",(0,t.jsx)(i.em,{children:"round issuance rate"})," (corresponding to the chainspec parameter ",(0,t.jsx)(i.code,{children:"round_seigniorage_rate"}),") with this formula:"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1\n"})}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.em,{children:"round issuance rate"})," is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter ",(0,t.jsx)(i.code,{children:"minimum_round_exponent"}),". For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds."]}),"\n",(0,t.jsx)(i.p,{children:"Finally, the base round reward is computed as:"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"base_round_reward(i) = round_issuance_rate * supply(i)\n"})}),"\n",(0,t.jsx)(i.p,{children:"This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block."}),"\n",(0,t.jsx)(i.h4,{id:"distribution",children:"Distribution"}),"\n",(0,t.jsx)(i.p,{children:"Validators receive tokens for proposing and finalizing blocks according to their performance. The concept of weight is crucial for understanding this distribution scheme:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Weight:"})," A validator's bonded stake, used in consensus"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Assigned weight of a block/round:"})," The total stake of validators scheduled to participate in a block"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Participated weight of a block/round:"})," The total stake of validators that end up participating or sending messages to finalize a block before the end of their respective round"]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["To determine eligibility, we look at ",(0,t.jsx)(i.strong,{children:"on-time finalization (OTF)"}),". Validators should finalize blocks on time by sending required messages before the end of their respective round."]}),"\n",(0,t.jsx)(i.p,{children:"Switch blocks are not visible to the issuance calculation (as this calculation is performed in the switch block itself for each era), and, consequently, no tokens are issued for switch blocks."}),"\n",(0,t.jsx)(i.h5,{id:"participation-schedule",children:"Participation schedule"}),"\n",(0,t.jsxs)(i.p,{children:["The participation schedule is segmented into rounds, which are allocated dynamically according to the validators' exponents and a deterministic (randomized at era start) assignment of validators to milliseconds of an era. Thus, a validator with the round exponent ",(0,t.jsx)(i.code,{children:"n"})," must participate in rounds that repeat every ",(0,t.jsx)(i.code,{children:"2^n"})," ticks."]}),"\n",(0,t.jsx)(i.p,{children:"Each validator is assessed according to its round exponent. All assigned validators become eligible to receive tokens as long as the block gets finalized with messages sent within each validator's round."}),"\n",(0,t.jsx)(i.h5,{id:"eligibility",children:"Eligibility"}),"\n",(0,t.jsxs)(i.p,{children:["Once a block has been proposed and enough time has passed, the history of protocol messages can be examined to detect whether the block was finalized on time, according to the conditions given above. If the block was ",(0,t.jsx)(i.em,{children:"not"})," finalized on time, validators receive a fraction of the expected tokens, governed by the ",(0,t.jsx)(i.code,{children:"reduced_reward_multiplier"})," chainspec parameter. If the block was finalized on time, assigned validators share the reward proportionally to their stake, regardless of whether they have sent messages or not."]}),"\n",(0,t.jsx)(i.h3,{id:"inactivity",children:"Inactivity"}),"\n",(0,t.jsx)(i.p,{children:"Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special deploy that reactivates their bid."}),"\n",(0,t.jsx)(i.h3,{id:"slashing",children:"Slashing"}),"\n",(0,t.jsxs)(i.p,{children:["Please review our ",(0,t.jsx)(i.a,{href:"https://github.com/casper-network/ceps/blob/master/text/0038-equivocator-policy.md",children:"Equivocator Policy"}),". We are currently conducting research into the utility of slashing as an incentive mechanism."]}),"\n",(0,t.jsx)(i.h2,{id:"founding-validators",children:"Founding validators"}),"\n",(0,t.jsx)(i.p,{children:"Founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days, then releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days."})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>o,x:()=>r});var t=n(96540);const s={},a=t.createContext(s);function o(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35808b61.27d7ec33.js b/assets/js/35808b61.27d7ec33.js deleted file mode 100644 index 96c79a12b..000000000 --- a/assets/js/35808b61.27d7ec33.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2714],{30347:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const r={},i="JavaScript/TypeScript SDK",c={id:"developers/dapps/sdk/script-sdk",title:"JavaScript/TypeScript SDK",description:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/script-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/script-sdk",permalink:"/developers/dapps/sdk/script-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Library Usage",permalink:"/developers/dapps/sdk/client-library-usage"},next:{title:".NET SDK",permalink:"/developers/dapps/sdk/csharp-sdk"}},o={},l=[{value:"Usage of JavaScript Clients",id:"usage-of-javascript-clients",level:2},{value:"Repository & Client Packages",id:"repository-7-client-packages",level:3},{value:"Casper SDK for JavaScript",id:"casper-sdk-for-javascript",level:2},{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Generating Account Keys",id:"generating-account-keys",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"javascripttypescript-sdk",children:"JavaScript/TypeScript SDK"})}),"\n",(0,t.jsx)(n.p,{children:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK."}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-javascript-clients",children:"Usage of JavaScript Clients"}),"\n",(0,t.jsx)(n.p,{children:"The Casper team has implemented specific JS clients to support interaction with the Casper contracts."}),"\n",(0,t.jsx)(n.h3,{id:"repository-7-client-packages",children:"Repository & Client Packages"}),"\n",(0,t.jsx)(n.p,{children:"We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/README.md",children:"Casper CEP-78 (NFT) Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/client-js#readme",children:"Casper CEP-18 Client"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These packages give you an easy way to install and interact with the corresponding Casper contract."}),"\n",(0,t.jsx)(n.h2,{id:"casper-sdk-for-javascript",children:"Casper SDK for JavaScript"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"TypeScript/JavaScript SDK"})," allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"To install this library using Node.js, run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk@next --save\n"})}),"\n",(0,t.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,t.jsxs)(n.p,{children:["You can find basic examples for how to use this library in the ",(0,t.jsx)(n.code,{children:"test"})," directory. To run the tests, use this command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,t.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating account keys"}),"\n",(0,t.jsx)(n.li,{children:"Sending a transfer"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"generating-account-keys",children:"Generating Account Keys"}),"\n",(0,t.jsx)(n.p,{children:"This example shows you how to use the SDK to generate account keys to sign your deploy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst { Keys } = require("casper-js-sdk");\n\nconst createAccountKeys = () => {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["After generating the keys with this code, you can add them to the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet Chrome extension"})," and use them to sign your transactions."]}),"\n",(0,t.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,t.jsx)(n.code,{children:"sender-public-key"})," and ",(0,t.jsx)(n.code,{children:"recipient-public-key"})," in the code below."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"sendTransfer"})," function below will return a ",(0,t.jsx)(n.code,{children:"transfer-hash"})," which you can check on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"https://testnet.cspr.live/"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "<sender-public-key>",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "<recipient-public-key>",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Here is the code you can use to serialize the deploy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you can reconstruct the deploy object using this function:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35808b61.5e787011.js b/assets/js/35808b61.5e787011.js new file mode 100644 index 000000000..dc7933333 --- /dev/null +++ b/assets/js/35808b61.5e787011.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2714],{30347:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const r={},i="JavaScript/TypeScript SDK",c={id:"developers/dapps/sdk/script-sdk",title:"JavaScript/TypeScript SDK",description:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/script-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/script-sdk",permalink:"/1.5.X/developers/dapps/sdk/script-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Library Usage",permalink:"/1.5.X/developers/dapps/sdk/client-library-usage"},next:{title:".NET SDK",permalink:"/1.5.X/developers/dapps/sdk/csharp-sdk"}},o={},l=[{value:"Usage of JavaScript Clients",id:"usage-of-javascript-clients",level:2},{value:"Repository & Client Packages",id:"repository-7-client-packages",level:3},{value:"Casper SDK for JavaScript",id:"casper-sdk-for-javascript",level:2},{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Generating Account Keys",id:"generating-account-keys",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"javascripttypescript-sdk",children:"JavaScript/TypeScript SDK"})}),"\n",(0,t.jsx)(n.p,{children:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK."}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-javascript-clients",children:"Usage of JavaScript Clients"}),"\n",(0,t.jsx)(n.p,{children:"The Casper team has implemented specific JS clients to support interaction with the Casper contracts."}),"\n",(0,t.jsx)(n.h3,{id:"repository-7-client-packages",children:"Repository & Client Packages"}),"\n",(0,t.jsx)(n.p,{children:"We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/README.md",children:"Casper CEP-78 (NFT) Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/client-js#readme",children:"Casper CEP-18 Client"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These packages give you an easy way to install and interact with the corresponding Casper contract."}),"\n",(0,t.jsx)(n.h2,{id:"casper-sdk-for-javascript",children:"Casper SDK for JavaScript"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"TypeScript/JavaScript SDK"})," allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"To install this library using Node.js, run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk@next --save\n"})}),"\n",(0,t.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,t.jsxs)(n.p,{children:["You can find basic examples for how to use this library in the ",(0,t.jsx)(n.code,{children:"test"})," directory. To run the tests, use this command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,t.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating account keys"}),"\n",(0,t.jsx)(n.li,{children:"Sending a transfer"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"generating-account-keys",children:"Generating Account Keys"}),"\n",(0,t.jsx)(n.p,{children:"This example shows you how to use the SDK to generate account keys to sign your deploy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst { Keys } = require("casper-js-sdk");\n\nconst createAccountKeys = () => {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["After generating the keys with this code, you can add them to the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet Chrome extension"})," and use them to sign your transactions."]}),"\n",(0,t.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,t.jsx)(n.code,{children:"sender-public-key"})," and ",(0,t.jsx)(n.code,{children:"recipient-public-key"})," in the code below."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"sendTransfer"})," function below will return a ",(0,t.jsx)(n.code,{children:"transfer-hash"})," which you can check on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"https://testnet.cspr.live/"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "<sender-public-key>",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "<recipient-public-key>",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Here is the code you can use to serialize the deploy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you can reconstruct the deploy object using this function:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/358cf6da.1b3e0934.js b/assets/js/358cf6da.1b3e0934.js deleted file mode 100644 index 7a2b66b34..000000000 --- a/assets/js/358cf6da.1b3e0934.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6109],{13275:e=>{e.exports=JSON.parse('{"author":{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor","count":2},"listMetadata":{"permalink":"/blog/authors/sczembor","page":1,"postsPerPage":2,"totalPages":1,"totalCount":2,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/358cf6da.50a774a3.js b/assets/js/358cf6da.50a774a3.js new file mode 100644 index 000000000..5e78a470f --- /dev/null +++ b/assets/js/358cf6da.50a774a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46109],{13275:e=>{e.exports=JSON.parse('{"author":{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor","count":2},"listMetadata":{"permalink":"/blog/authors/sczembor","page":1,"postsPerPage":2,"totalPages":1,"totalCount":2,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/35a4f7b3.e6576d4a.js b/assets/js/35a4f7b3.e6576d4a.js deleted file mode 100644 index fe92ba968..000000000 --- a/assets/js/35a4f7b3.e6576d4a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[956],{87675:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Transferring Tokens"},a="Transferring Tokens with the Casper CLI Client",o={id:"developers/cli/transfers/index",title:"Transferring Tokens",description:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/index.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/",permalink:"/developers/cli/transfers/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Transferring Tokens"},sidebar:"developers",previous:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"},next:{title:"Direct Token Transfer",permalink:"/developers/cli/transfers/direct-token-transfer"}},c={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-with-the-casper-cli-client",children:"Transferring Tokens with the Casper CLI Client"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a direct transfer"})}),"\n",(0,t.jsxs)(n.p,{children:["Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Transferring Tokens Using Direct Transfer"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a multi-sig deploy"})}),"\n",(0,t.jsxs)(n.p,{children:["Multi-sig deploy transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the deploy. To set up the account's associated keys, see the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow. To use a multi-sig deploy transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Transferring Tokens Using a Multi-sig Account"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verifying a transfer using the command-line client"})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the status of a transfer, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var t=r(96540);const s={},i=t.createContext(s);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/35a4f7b3.f6ca0fad.js b/assets/js/35a4f7b3.f6ca0fad.js new file mode 100644 index 000000000..ced8ff282 --- /dev/null +++ b/assets/js/35a4f7b3.f6ca0fad.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70956],{87675:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Transferring Tokens"},a="Transferring Tokens with the Casper CLI Client",o={id:"developers/cli/transfers/index",title:"Transferring Tokens",description:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/index.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/",permalink:"/1.5.X/developers/cli/transfers/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Transferring Tokens"},sidebar:"developers",previous:{title:"Interacting with the Blockchain",permalink:"/1.5.X/developers/cli/"},next:{title:"Direct Token Transfer",permalink:"/1.5.X/developers/cli/transfers/direct-token-transfer"}},c={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-with-the-casper-cli-client",children:"Transferring Tokens with the Casper CLI Client"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a direct transfer"})}),"\n",(0,t.jsxs)(n.p,{children:["Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/direct-token-transfer",children:"Transferring Tokens Using Direct Transfer"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a multi-sig deploy"})}),"\n",(0,t.jsxs)(n.p,{children:["Multi-sig deploy transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the deploy. To set up the account's associated keys, see the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow. To use a multi-sig deploy transfer, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer",children:"Transferring Tokens Using a Multi-sig Account"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verifying a transfer using the command-line client"})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the status of a transfer, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var t=r(96540);const s={},i=t.createContext(s);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3619739c.59a850b5.js b/assets/js/3619739c.59a850b5.js new file mode 100644 index 000000000..ecdb654ca --- /dev/null +++ b/assets/js/3619739c.59a850b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[10124],{97409:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Runtime",slug:"/runtime"},o="Runtime Economics",r={id:"concepts/economics/runtime",title:"Runtime",description:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:",source:"@site/docs/concepts/economics/runtime.md",sourceDirName:"concepts/economics",slug:"/runtime",permalink:"/runtime",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{title:"Runtime",slug:"/runtime"},sidebar:"concepts",previous:{title:"Consensus",permalink:"/concepts/economics/consensus"},next:{title:"Gas Cost",permalink:"/concepts/economics/gas-concepts"}},c={},l=[{value:"Gas Allocation",id:"gas-allocation",level:2},{value:"Consensus before execution & basics of payment",id:"consensus-before-execution-basics-of-payment",level:3},{value:"Costs and limits",id:"costs-and-limits",level:3},{value:"Lanes and gas costs",id:"lanes",level:3},{value:"Dynamic Gas Pricing",id:"dynamic-gas-pricing",level:2},{value:"Eliminating Gas Fees",id:"gas-fees",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"runtime-economics",children:"Runtime Economics"})}),"\n",(0,s.jsx)(n.p,{children:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See ",(0,s.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]}),"\n",(0,s.jsxs)(n.li,{children:["A form of ",(0,s.jsx)(n.a,{href:"#dynamic-gas-pricing",children:"dynamic pricing"})," that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era."]}),"\n",(0,s.jsxs)(n.li,{children:["Blocks are structured into ",(0,s.jsx)(n.a,{href:"#lanes-lanes",children:"lanes"})," that can only hold a particular number of transactions of specified types."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These economic features are configurable using chainspec parameters."}),"\n",(0,s.jsx)(n.h2,{id:"gas-allocation",children:"Gas Allocation"}),"\n",(0,s.jsxs)(n.p,{children:["Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:"gas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/ceps",children:"CEPs"}),". In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model."]}),"\n",(0,s.jsx)(n.h3,{id:"consensus-before-execution-basics-of-payment",children:"Consensus before execution & basics of payment"}),"\n",(0,s.jsx)(n.p,{children:"The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas."}),"\n",(0,s.jsx)(n.p,{children:"Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future."}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-limits",children:"Costs and limits"}),"\n",(0,s.jsxs)(n.p,{children:["Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex ",(0,s.jsx)(n.em,{children:"host-side"})," functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"})," and may vary according to arguments. Read more about how Casper measures computational work ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"here"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades."}),"\n",(0,s.jsx)(n.h3,{id:"lanes",children:"Lanes and gas costs"}),"\n",(0,s.jsx)(n.p,{children:"There are several platform parameters that delineate the sets of transactions that may be included in a valid block:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Number of lanes and lane types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"System interaction lanes for Mint (transfers) and Auction transactions."}),"\n",(0,s.jsx)(n.li,{children:"WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction."}),"\n",(0,s.jsx)(n.li,{children:"All lanes can contain some finite number of transactions, set separately for each lane."}),"\n",(0,s.jsx)(n.li,{children:"For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Block gas and size limits"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots."}),"\n",(0,s.jsx)(n.li,{children:"The block size limit imposes an absolute ceiling on the total byte size of included transactions."}),"\n",(0,s.jsx)(n.li,{children:"Individual transaction size limits are also enforced."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These are the lane configuration settings for the Condor release on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[transactions.v1]\n# The configuration settings for the lanes of transactions including both native and Wasm based interactions.\n# Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1\n# respectively\n# The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction\n# within a given lane.\n# The maximum length in bytes of runtime args per V1 transaction.\n# [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)\n# Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and\n# the lane must be present and defined.\n# Different casper networks may not impose such a restriction.\n# [1] -> Max transaction size in bytes for a given transaction in a certain lane\n# [2] -> Max args length size in bytes for a given transaction in a certain lane\n# [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane\n# [4] -> The maximum number of transactions the lane can contain\nnative_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]\nnative_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]\nwasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]\n"})}),"\n",(0,s.jsx)(n.p,{children:"These are the block gas and size limits for the Condor release on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[transactions]\n...\n# Maximum block size in bytes including transactions contained by the block. 0 means unlimited.\nmax_block_size = 5_242_880\n# The upper limit of total gas of all transactions in a block.\nblock_gas_limit = 3_300_000_000_000\n"})}),"\n",(0,s.jsx)(n.h2,{id:"dynamic-gas-pricing",children:"Dynamic Gas Pricing"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack."]}),"\n",(0,s.jsx)(n.h2,{id:"gas-fees",children:"Eliminating Gas Fees"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:"Gas"})," and ",(0,s.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3619739c.88978e27.js b/assets/js/3619739c.88978e27.js deleted file mode 100644 index 47bce901e..000000000 --- a/assets/js/3619739c.88978e27.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[124],{19790:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var i=t(74848),s=t(28453);const a={title:"Runtime",slug:"/runtime"},o="Runtime Economics",r={id:"concepts/economics/runtime",title:"Runtime",description:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:",source:"@site/docs/concepts/economics/runtime.md",sourceDirName:"concepts/economics",slug:"/runtime",permalink:"/next/runtime",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{title:"Runtime",slug:"/runtime"},sidebar:"concepts",previous:{title:"Consensus",permalink:"/next/concepts/economics/consensus"},next:{title:"Gas Cost",permalink:"/next/concepts/economics/gas-concepts"}},c={},l=[{value:"Gas Allocation",id:"gas-allocation",level:2},{value:"Consensus before execution & basics of payment",id:"consensus-before-execution-basics-of-payment",level:3},{value:"Costs and limits",id:"costs-and-limits",level:3},{value:"Lanes and gas costs",id:"lanes",level:3},{value:"Dynamic Gas Pricing",id:"dynamic-gas-pricing",level:2},{value:"Eliminating Gas Fees",id:"gas-fees",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"runtime-economics",children:"Runtime Economics"})}),"\n",(0,i.jsx)(n.p,{children:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See ",(0,i.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]}),"\n",(0,i.jsxs)(n.li,{children:["A form of ",(0,i.jsx)(n.a,{href:"#dynamic-gas-pricing",children:"dynamic pricing"})," that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era."]}),"\n",(0,i.jsxs)(n.li,{children:["Blocks are structured into ",(0,i.jsx)(n.a,{href:"#lanes-lanes",children:"lanes"})," that can only hold a particular number of transactions of specified types."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"These economic features are configurable using chainspec parameters."}),"\n",(0,i.jsx)(n.h2,{id:"gas-allocation",children:"Gas Allocation"}),"\n",(0,i.jsxs)(n.p,{children:["Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the ",(0,i.jsx)(n.a,{href:"/next/concepts/economics/gas-concepts",children:"gas"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/ceps",children:"CEPs"}),". In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model."]}),"\n",(0,i.jsx)(n.h3,{id:"consensus-before-execution-basics-of-payment",children:"Consensus before execution & basics of payment"}),"\n",(0,i.jsx)(n.p,{children:"The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas."}),"\n",(0,i.jsx)(n.p,{children:"Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future."}),"\n",(0,i.jsx)(n.h3,{id:"costs-and-limits",children:"Costs and limits"}),"\n",(0,i.jsxs)(n.p,{children:["Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex ",(0,i.jsx)(n.em,{children:"host-side"})," functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the ",(0,i.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"})," and may vary according to arguments. Read more about how Casper measures computational work ",(0,i.jsx)(n.a,{href:"/next/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"here"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades."}),"\n",(0,i.jsx)(n.h3,{id:"lanes",children:"Lanes and gas costs"}),"\n",(0,i.jsx)(n.p,{children:"There are several platform parameters that delineate the sets of transactions that may be included in a valid block:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Number of lanes and lane types"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"System interaction lanes for Mint (transfers) and Auction transactions."}),"\n",(0,i.jsx)(n.li,{children:"WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction."}),"\n",(0,i.jsx)(n.li,{children:"All lanes can contain some finite number of transactions, set separately for each lane."}),"\n",(0,i.jsx)(n.li,{children:"For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Block gas and size limits"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots."}),"\n",(0,i.jsx)(n.li,{children:"The block size limit imposes an absolute ceiling on the total byte size of included transactions."}),"\n",(0,i.jsx)(n.li,{children:"Individual transaction size limits are also enforced."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"These are the lane configuration settings for the Condor release on Mainnet:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-toml",children:"[transactions.v1]\n# The configuration settings for the lanes of transactions including both native and Wasm based interactions.\n# Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1\n# respectively\n# The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction\n# within a given lane.\n# The maximum length in bytes of runtime args per V1 transaction.\n# [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)\n# Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and\n# the lane must be present and defined.\n# Different casper networks may not impose such a restriction.\n# [1] -> Max transaction size in bytes for a given transaction in a certain lane\n# [2] -> Max args length size in bytes for a given transaction in a certain lane\n# [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane\n# [4] -> The maximum number of transactions the lane can contain\nnative_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]\nnative_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]\nwasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]\n"})}),"\n",(0,i.jsx)(n.p,{children:"These are the block gas and size limits for the Condor release on Mainnet:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-toml",children:"[transactions]\n...\n# Maximum block size in bytes including transactions contained by the block. 0 means unlimited.\nmax_block_size = 5_242_880\n# The upper limit of total gas of all transactions in a block.\nblock_gas_limit = 3_300_000_000_000\n"})}),"\n",(0,i.jsx)(n.h2,{id:"dynamic-gas-pricing",children:"Dynamic Gas Pricing"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/next/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack."]}),"\n",(0,i.jsx)(n.h2,{id:"gas-fees",children:"Eliminating Gas Fees"}),"\n",(0,i.jsxs)(n.p,{children:["See ",(0,i.jsx)(n.a,{href:"/next/concepts/economics/gas-concepts",children:"Gas"})," and ",(0,i.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/362368d5.3185e36c.js b/assets/js/362368d5.3185e36c.js deleted file mode 100644 index 2961dc071..000000000 --- a/assets/js/362368d5.3185e36c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8190],{60940:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var r=n(74848),o=n(28453);const t={},a="P",c={id:"concepts/glossary/P",title:"P",description:"---",source:"@site/docs/concepts/glossary/P.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/P",permalink:"/next/concepts/glossary/P",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"O",permalink:"/next/concepts/glossary/O"},next:{title:"Q",permalink:"/next/concepts/glossary/Q"}},i={},l=[{value:"Partial synchrony",id:"partial-synchrony",level:2},{value:"Participate in consensus",id:"participate-in-consensus",level:2},{value:"Payment code",id:"payment-code",level:2},{value:"Peer node",id:"peer-node",level:2},{value:"Permissionless",id:"permissionless",level:2},{value:"Primary token",id:"primary-token",level:2},{value:"Private key",id:"private-key",level:2},{value:"Proof-of-Stake",id:"proof-of-stake",level:2},{value:"Proof-of-Work",id:"proof-of-work",level:2},{value:"Proposer",id:"proposer",level:2},{value:"Proto block",id:"proto-block",level:2},{value:"Purse",id:"purse",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"p",children:"P"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"partial-synchrony",children:"Partial synchrony"}),"\n",(0,r.jsxs)(s.p,{children:["Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"participate-in-consensus",children:"Participate in consensus"}),"\n",(0,r.jsxs)(s.p,{children:["The process of following the ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C#consensus",children:"consensus"})," algorithm. The primary participants are ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V#validator",children:"validators"}),", bonded with their stake and part of the validator set for that particular era. ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D#delegator",children:"Delegators"})," participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network."]}),"\n",(0,r.jsx)(s.h2,{id:"payment-code",children:"Payment code"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.em,{children:"payment code"})," is the ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W#webassembly",children:"Wasm"})," program that pays the transaction execution fee."]}),"\n",(0,r.jsx)(s.h2,{id:"peer-node",children:"Peer node"}),"\n",(0,r.jsx)(s.p,{children:"A node on a peer-to-peer (P2P) network."}),"\n",(0,r.jsx)(s.h2,{id:"permissionless",children:"Permissionless"}),"\n",(0,r.jsx)(s.p,{children:"A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants."}),"\n",(0,r.jsx)(s.h2,{id:"primary-token",children:"Primary token"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"private-key",children:"Private key"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S#secret-key",children:"secret key"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake",children:"Proof-of-Stake"}),"\n",(0,r.jsx)(s.p,{children:"Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-work",children:"Proof-of-Work"}),"\n",(0,r.jsx)(s.p,{children:"A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed."}),"\n",(0,r.jsx)(s.h2,{id:"proposer",children:"Proposer"}),"\n",(0,r.jsx)(s.p,{children:"The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proto-block",children:"Proto block"}),"\n",(0,r.jsx)(s.p,{children:"The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated."}),"\n",(0,r.jsx)(s.p,{children:"A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era."}),"\n",(0,r.jsx)(s.h2,{id:"purse",children:"Purse"}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.code,{children:"purse"})," is a unique type of ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U#uref",children:"URef"})," representing a token balance. An entity's ",(0,r.jsx)(s.em,{children:"main purse"})," represents the balance of CSPR tokens (in ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M#motes",children:"motes"}),") the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found ",(0,r.jsx)(s.a,{href:"/next/concepts/design/casper-design#urefs-and-purses",children:"here"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const o={},t=r.createContext(o);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/362368d5.b933ef02.js b/assets/js/362368d5.b933ef02.js new file mode 100644 index 000000000..bf2d5bed2 --- /dev/null +++ b/assets/js/362368d5.b933ef02.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58190],{60940:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var n=r(74848),o=r(28453);const t={},a="P",c={id:"concepts/glossary/P",title:"P",description:"---",source:"@site/docs/concepts/glossary/P.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/P",permalink:"/concepts/glossary/P",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"O",permalink:"/concepts/glossary/O"},next:{title:"Q",permalink:"/concepts/glossary/Q"}},i={},l=[{value:"Partial synchrony",id:"partial-synchrony",level:2},{value:"Participate in consensus",id:"participate-in-consensus",level:2},{value:"Payment code",id:"payment-code",level:2},{value:"Peer node",id:"peer-node",level:2},{value:"Permissionless",id:"permissionless",level:2},{value:"Primary token",id:"primary-token",level:2},{value:"Private key",id:"private-key",level:2},{value:"Proof-of-Stake",id:"proof-of-stake",level:2},{value:"Proof-of-Work",id:"proof-of-work",level:2},{value:"Proposer",id:"proposer",level:2},{value:"Proto block",id:"proto-block",level:2},{value:"Purse",id:"purse",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"p",children:"P"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"partial-synchrony",children:"Partial synchrony"}),"\n",(0,n.jsxs)(s.p,{children:["Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"participate-in-consensus",children:"Participate in consensus"}),"\n",(0,n.jsxs)(s.p,{children:["The process of following the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C#consensus",children:"consensus"})," algorithm. The primary participants are ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V#validator",children:"validators"}),", bonded with their stake and part of the validator set for that particular era. ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D#delegator",children:"Delegators"})," participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network."]}),"\n",(0,n.jsx)(s.h2,{id:"payment-code",children:"Payment code"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.em,{children:"payment code"})," is the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," program that pays the transaction execution fee."]}),"\n",(0,n.jsx)(s.h2,{id:"peer-node",children:"Peer node"}),"\n",(0,n.jsx)(s.p,{children:"A node on a peer-to-peer (P2P) network."}),"\n",(0,n.jsx)(s.h2,{id:"permissionless",children:"Permissionless"}),"\n",(0,n.jsx)(s.p,{children:"A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants."}),"\n",(0,n.jsx)(s.h2,{id:"primary-token",children:"Primary token"}),"\n",(0,n.jsxs)(s.p,{children:["See ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"private-key",children:"Private key"}),"\n",(0,n.jsxs)(s.p,{children:["See ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S#secret-key",children:"secret key"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"proof-of-stake",children:"Proof-of-Stake"}),"\n",(0,n.jsx)(s.p,{children:"Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain."}),"\n",(0,n.jsx)(s.h2,{id:"proof-of-work",children:"Proof-of-Work"}),"\n",(0,n.jsx)(s.p,{children:"A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed."}),"\n",(0,n.jsx)(s.h2,{id:"proposer",children:"Proposer"}),"\n",(0,n.jsx)(s.p,{children:"The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain."}),"\n",(0,n.jsx)(s.h2,{id:"proto-block",children:"Proto block"}),"\n",(0,n.jsx)(s.p,{children:"The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated."}),"\n",(0,n.jsx)(s.p,{children:"A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era."}),"\n",(0,n.jsx)(s.h2,{id:"purse",children:"Purse"}),"\n",(0,n.jsxs)(s.p,{children:["A ",(0,n.jsx)(s.code,{children:"purse"})," is a unique type of ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U#uref",children:"URef"})," representing a token balance. An entity's ",(0,n.jsx)(s.em,{children:"main purse"})," represents the balance of CSPR tokens (in ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M#motes",children:"motes"}),") the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found ",(0,n.jsx)(s.a,{href:"/concepts/design/casper-design#urefs-and-purses",children:"here"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>a,x:()=>c});var n=r(96540);const o={},t=n.createContext(o);function a(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3669623c.858e4657.js b/assets/js/3669623c.858e4657.js deleted file mode 100644 index bb5da0ae3..000000000 --- a/assets/js/3669623c.858e4657.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[442],{68329:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>t,metadata:()=>d,toc:()=>o});var s=n(74848),i=n(28453);const t={title:"Set up Ledger",slug:"/workflow/ledger-setup/"},l="Ledger Setup with Casper",d={id:"users/ledger/ledger-setup",title:"Set up Ledger",description:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-setup.md",sourceDirName:"users/ledger",slug:"/workflow/ledger-setup/",permalink:"/workflow/ledger-setup/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Set up Ledger",slug:"/workflow/ledger-setup/"},sidebar:"users",previous:{title:"Casper on Ledger",permalink:"/users/ledger/"},next:{title:"Ledger and Ledger Live",permalink:"/users/ledger/ledger-live"}},a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing the Casper App on a Ledger Device",id:"install-the-casper-app-on-the-ledger-device",level:2},{value:"Sending and Receiving Tokens",id:"sending-and-receiving-tokens",level:2}];function c(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.header,{children:(0,s.jsx)(r.h1,{id:"ledger-setup-with-casper",children:"Ledger Setup with Casper"})}),"\n",(0,s.jsx)(r.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(r.p,{children:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users."}),"\n",(0,s.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,s.jsx)(r.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,s.jsxs)(r.li,{children:[(0,s.jsx)(r.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,s.jsxs)(r.li,{children:["Make sure the Ledger Live application version is at least at ",(0,s.jsx)(r.code,{children:"2.73.1"}),", which is the version that includes Casper accounts."]}),"\n"]}),"\n",(0,s.jsx)(r.admonition,{type:"note",children:(0,s.jsxs)(r.p,{children:["If you need help, contact us on ",(0,s.jsx)(r.a,{href:"https://twitter.com/Casper_Network",children:"Twitter"}),", ",(0,s.jsx)(r.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),", or ",(0,s.jsx)(r.a,{href:"https://t.me/casperblockchain",children:"Telegram"}),"."]})}),"\n",(0,s.jsx)(r.h2,{id:"install-the-casper-app-on-the-ledger-device",children:"Installing the Casper App on a Ledger Device"}),"\n",(0,s.jsxs)(r.p,{children:["Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official ",(0,s.jsx)(r.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger support site"}),"."]}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsx)(r.li,{children:"In Ledger Live, open My Ledger at the bottom of the left-hand menu."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/open-my-ledger.png")}',alt:"Open My Ledger",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"2",children:["\n",(0,s.jsx)(r.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-unlock.png")}',alt:"Unlock your Ledger device",width:"350"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"3",children:["\n",(0,s.jsx)(r.li,{children:"If asked, allow Ledger manager on your device."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/allow-ledger.png")}',alt:"Allow Ledger",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"4",children:["\n",(0,s.jsxs)(r.li,{children:["Find ",(0,s.jsx)(r.strong,{children:"Casper"})," in the app catalog."]}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/find-casper.png")}',alt:"Find the Casper app",width:"800"}),"\n"]}),"\n",(0,s.jsx)(r.admonition,{type:"important",children:(0,s.jsx)(r.p,{children:'Having trouble finding the Casper app?\nPlease search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.'})}),"\n",(0,s.jsxs)(r.ol,{start:"5",children:["\n",(0,s.jsxs)(r.li,{children:["Click the ",(0,s.jsx)(r.strong,{children:"Install"})," button of the app."]}),"\n"]}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsx)(r.li,{children:"An installation window appears."}),"\n",(0,s.jsxs)(r.li,{children:["Your device will display ",(0,s.jsx)(r.strong,{children:'"Processing..."'})]}),"\n",(0,s.jsx)(r.li,{children:"The app installation is confirmed."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-installed.png")}',alt:"Casper installation confirmed",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"6",children:["\n",(0,s.jsx)(r.li,{children:"Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/select-casper.png")}',alt:"Select Casper on Ledger",width:"350"}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-ready.png")}',alt:"Casper app is ready",width:"350"}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"sending-and-receiving-tokens",children:"Sending and Receiving Tokens"}),"\n",(0,s.jsx)(r.p,{children:"To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"/users/ledger/ledger-live",children:"Manage Casper Accounts using Ledger and Ledger Live"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"/users/ledger/ledger-cspr-live",children:"Manage Casper Accounts using Ledger and CSPR.live"})}),"\n"]}),"\n",(0,s.jsxs)(r.p,{children:["To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in ",(0,s.jsx)(r.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"}),"."]}),"\n",(0,s.jsx)(r.p,{children:"Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange."})]})}function p(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,r,n)=>{n.d(r,{R:()=>l,x:()=>d});var s=n(96540);const i={},t=s.createContext(i);function l(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3669623c.b2f466b1.js b/assets/js/3669623c.b2f466b1.js new file mode 100644 index 000000000..667142edb --- /dev/null +++ b/assets/js/3669623c.b2f466b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58061],{68329:(e,r,n)=>{n.r(r),n.d(r,{assets:()=>a,contentTitle:()=>l,default:()=>p,frontMatter:()=>t,metadata:()=>d,toc:()=>o});var s=n(74848),i=n(28453);const t={title:"Set up Ledger",slug:"/workflow/ledger-setup/"},l="Ledger Setup with Casper",d={id:"users/ledger/ledger-setup",title:"Set up Ledger",description:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-setup.md",sourceDirName:"users/ledger",slug:"/workflow/ledger-setup/",permalink:"/1.5.X/workflow/ledger-setup/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Set up Ledger",slug:"/workflow/ledger-setup/"},sidebar:"users",previous:{title:"Casper on Ledger",permalink:"/1.5.X/users/ledger/"},next:{title:"Ledger and Ledger Live",permalink:"/1.5.X/users/ledger/ledger-live"}},a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing the Casper App on a Ledger Device",id:"install-the-casper-app-on-the-ledger-device",level:2},{value:"Sending and Receiving Tokens",id:"sending-and-receiving-tokens",level:2}];function c(e){const r={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(r.header,{children:(0,s.jsx)(r.h1,{id:"ledger-setup-with-casper",children:"Ledger Setup with Casper"})}),"\n",(0,s.jsx)(r.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(r.p,{children:"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users."}),"\n",(0,s.jsx)(r.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsxs)(r.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,s.jsx)(r.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,s.jsxs)(r.li,{children:[(0,s.jsx)(r.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,s.jsxs)(r.li,{children:["Make sure the Ledger Live application version is at least at ",(0,s.jsx)(r.code,{children:"2.73.1"}),", which is the version that includes Casper accounts."]}),"\n"]}),"\n",(0,s.jsx)(r.admonition,{type:"note",children:(0,s.jsxs)(r.p,{children:["If you need help, contact us on ",(0,s.jsx)(r.a,{href:"https://twitter.com/Casper_Network",children:"Twitter"}),", ",(0,s.jsx)(r.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),", or ",(0,s.jsx)(r.a,{href:"https://t.me/casperblockchain",children:"Telegram"}),"."]})}),"\n",(0,s.jsx)(r.h2,{id:"install-the-casper-app-on-the-ledger-device",children:"Installing the Casper App on a Ledger Device"}),"\n",(0,s.jsxs)(r.p,{children:["Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official ",(0,s.jsx)(r.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger support site"}),"."]}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsx)(r.li,{children:"In Ledger Live, open My Ledger at the bottom of the left-hand menu."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/open-my-ledger.png")}',alt:"Open My Ledger",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"2",children:["\n",(0,s.jsx)(r.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-unlock.png")}',alt:"Unlock your Ledger device",width:"350"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"3",children:["\n",(0,s.jsx)(r.li,{children:"If asked, allow Ledger manager on your device."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/allow-ledger.png")}',alt:"Allow Ledger",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"4",children:["\n",(0,s.jsxs)(r.li,{children:["Find ",(0,s.jsx)(r.strong,{children:"Casper"})," in the app catalog."]}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/find-casper.png")}',alt:"Find the Casper app",width:"800"}),"\n"]}),"\n",(0,s.jsx)(r.admonition,{type:"important",children:(0,s.jsx)(r.p,{children:'Having trouble finding the Casper app?\nPlease search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.'})}),"\n",(0,s.jsxs)(r.ol,{start:"5",children:["\n",(0,s.jsxs)(r.li,{children:["Click the ",(0,s.jsx)(r.strong,{children:"Install"})," button of the app."]}),"\n"]}),"\n",(0,s.jsxs)(r.ul,{children:["\n",(0,s.jsx)(r.li,{children:"An installation window appears."}),"\n",(0,s.jsxs)(r.li,{children:["Your device will display ",(0,s.jsx)(r.strong,{children:'"Processing..."'})]}),"\n",(0,s.jsx)(r.li,{children:"The app installation is confirmed."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-installed.png")}',alt:"Casper installation confirmed",width:"800"}),"\n"]}),"\n",(0,s.jsxs)(r.ol,{start:"6",children:["\n",(0,s.jsx)(r.li,{children:"Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps."}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/select-casper.png")}',alt:"Select Casper on Ledger",width:"350"}),"\n"]}),"\n",(0,s.jsxs)(r.p,{align:"center",children:["\n",(0,s.jsx)(r.img,{src:'{useBaseUrl("/image/tutorials/ledger/ledger-live/casper-ready.png")}',alt:"Casper app is ready",width:"350"}),"\n"]}),"\n",(0,s.jsx)(r.h2,{id:"sending-and-receiving-tokens",children:"Sending and Receiving Tokens"}),"\n",(0,s.jsx)(r.p,{children:"To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:"}),"\n",(0,s.jsxs)(r.ol,{children:["\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"/1.5.X/users/ledger/ledger-live",children:"Manage Casper Accounts using Ledger and Ledger Live"})}),"\n",(0,s.jsx)(r.li,{children:(0,s.jsx)(r.a,{href:"/1.5.X/users/ledger/ledger-cspr-live",children:"Manage Casper Accounts using Ledger and CSPR.live"})}),"\n"]}),"\n",(0,s.jsxs)(r.p,{children:["To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in ",(0,s.jsx)(r.a,{href:"/1.5.X/users/staking-ledger",children:"Delegating with Ledger Devices"}),"."]}),"\n",(0,s.jsx)(r.p,{children:"Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange."})]})}function p(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,s.jsx)(r,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,r,n)=>{n.d(r,{R:()=>l,x:()=>d});var s=n(96540);const i={},t=s.createContext(i);function l(e){const r=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),s.createElement(t.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/36994c47.31271808.js b/assets/js/36994c47.31271808.js deleted file mode 100644 index 101863e5f..000000000 --- a/assets/js/36994c47.31271808.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9858],{45516:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/36994c47.ce48ef1d.js b/assets/js/36994c47.ce48ef1d.js new file mode 100644 index 000000000..0d5a6f3cb --- /dev/null +++ b/assets/js/36994c47.ce48ef1d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[89858],{45516:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-blog","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/3724f9ed.5eafca9c.js b/assets/js/3724f9ed.5eafca9c.js new file mode 100644 index 000000000..1a6f6f0dc --- /dev/null +++ b/assets/js/3724f9ed.5eafca9c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15255],{58592:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=s(74848),r=s(28453);const o={},i="Writing Session Code",c={id:"developers/writing-onchain-code/writing-session-code",title:"Writing Session Code",description:"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.",source:"@site/docs/developers/writing-onchain-code/writing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/writing-session-code",permalink:"/developers/writing-onchain-code/writing-session-code",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"developers",previous:{title:"Contracts and Session Code",permalink:"/developers/writing-onchain-code/contract-vs-session"},next:{title:"Testing Session Code",permalink:"/developers/writing-onchain-code/testing-session-code"}},a={},d=[{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Example 1: Writing Session Code",id:"writing-session-code",level:2},{value:"Dependencies in <code>Cargo.toml</code>",id:"dependencies-in-cargotoml",level:3},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"writing-session-code",children:"Writing Session Code"})}),"\n",(0,t.jsxs)(n.p,{children:["This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Comparing Session Code and Contract Code"}),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,t.jsxs)(n.p,{children:["For writing session code, we use the same project structure used for writing contracts, described ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"writing-session-code",children:"Example 1: Writing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"https://github.com/casper-ecosystem/two-party-multi-sig/"}),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious."})}),"\n",(0,t.jsxs)(n.h3,{id:"dependencies-in-cargotoml",children:["Dependencies in ",(0,t.jsx)(n.code,{children:"Cargo.toml"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,t.jsx)(n.code,{children:"main.rs"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["Open the ",(0,t.jsx)(n.code,{children:"contract/src/main.rs"})," file that contains the sample session code. Notice these directives at the top of the file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_std]"})," - Specifies not to import the standard library."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_main]"})," - Indicates the ",(0,t.jsx)(n.code,{children:"main"})," function is not required since the session code has only one entry point as the ",(0,t.jsx)(n.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Next, review the imported crates and other required libraries."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the imported libraries, we usually find the constants."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, we see the ",(0,t.jsx)(n.code,{children:"call"})," function, the only entry point in this example session code. The ",(0,t.jsx)(n.code,{children:"#[no_mangle]"})," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,t.jsx)(n.code,{children:"call"})," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When compiled, the ",(0,t.jsx)(n.code,{children:"call"})," function could be used from another library. For example, a C library could link to the resulting Wasm."]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-code",children:"Example 2: Calling a Contract with Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Another example of session code is the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call/src/main.rs"})," file, in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter",children:"counter"})," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Observe how the project is set up and review the dependencies in the ",(0,t.jsx)(n.code,{children:"counter/counter-call/Cargo.toml"})," file. Then, open the ",(0,t.jsx)(n.code,{children:"counter/counter-call/src/main.rs"})," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," function interacts with the contract's ",(0,t.jsx)(n.code,{children:"counter_inc"})," and ",(0,t.jsx)(n.code,{children:"counter_get"})," entry points. This is how the session's ",(0,t.jsx)(n.code,{children:"call"})," entry point triggers the logic stored inside the counter contract."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:" // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n"})}),"\n",(0,t.jsx)(n.h2,{id:"transfers-using-session-code",children:"Example 3: Transfers using Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, we use session code to perform a transfer using the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html",children:"transfer_from_purse_to_purse"})," system function. The entire session code is available in ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14",children:"GitHub"}),", but this is the ",(0,t.jsx)(n.code,{children:"call"})," function:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Another system function is ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html",children:"transfer_to_public_key"}),". The full session code example is on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Other transfer functions are available here:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html",children:"transfer_from_purse_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html",children:"transfer_from_purse_to_public_key"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"compiling-session-code",children:"Compiling Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file and ",(0,t.jsx)(n.code,{children:"src"})," folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the examples above, you may use the Makefiles provided:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make build-contract\n"})}),"\n",(0,t.jsx)(n.h2,{id:"executing-session-code",children:"Executing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code on a live Casper network, test it as described ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"here"}),". You can also set up a local network using ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"NCTL"})," for additional tests."]}),"\n",(0,t.jsxs)(n.p,{children:["Session code can execute on a Casper network via a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"}),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and its ",(0,t.jsx)(n.code,{children:"put-deploy"})," command provide one way to execute session code."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name <NETWORK-NAME> \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH> \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where the deploy should be sent. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - Path to the contract Wasm, pointing to the compiled contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - A named and typed argument passed to the Wasm code."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"--help"})," option to view an updated list of supported arguments."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsxs)(n.p,{children:["The following brief video describes ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"test session code"})," using the Casper testing framework."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3724f9ed.c1aaf3d4.js b/assets/js/3724f9ed.c1aaf3d4.js deleted file mode 100644 index 5d1ef3449..000000000 --- a/assets/js/3724f9ed.c1aaf3d4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5255],{58592:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=s(74848),r=s(28453);const o={},i="Writing Session Code",c={id:"developers/writing-onchain-code/writing-session-code",title:"Writing Session Code",description:"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.",source:"@site/docs/developers/writing-onchain-code/writing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/writing-session-code",permalink:"/next/developers/writing-onchain-code/writing-session-code",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"developers",previous:{title:"Contracts and Session Code",permalink:"/next/developers/writing-onchain-code/contract-vs-session"},next:{title:"Testing Session Code",permalink:"/next/developers/writing-onchain-code/testing-session-code"}},a={},d=[{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Example 1: Writing Session Code",id:"writing-session-code",level:2},{value:"Dependencies in <code>Cargo.toml</code>",id:"dependencies-in-cargotoml",level:3},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"writing-session-code",children:"Writing Session Code"})}),"\n",(0,t.jsxs)(n.p,{children:["This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Comparing Session Code and Contract Code"}),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,t.jsxs)(n.p,{children:["For writing session code, we use the same project structure used for writing contracts, described ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"writing-session-code",children:"Example 1: Writing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"https://github.com/casper-ecosystem/two-party-multi-sig/"}),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Account"})," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious."})}),"\n",(0,t.jsxs)(n.h3,{id:"dependencies-in-cargotoml",children:["Dependencies in ",(0,t.jsx)(n.code,{children:"Cargo.toml"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,t.jsx)(n.code,{children:"main.rs"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["Open the ",(0,t.jsx)(n.code,{children:"contract/src/main.rs"})," file that contains the sample session code. Notice these directives at the top of the file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_std]"})," - Specifies not to import the standard library."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_main]"})," - Indicates the ",(0,t.jsx)(n.code,{children:"main"})," function is not required since the session code has only one entry point as the ",(0,t.jsx)(n.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Next, review the imported crates and other required libraries."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the imported libraries, we usually find the constants."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, we see the ",(0,t.jsx)(n.code,{children:"call"})," function, the only entry point in this example session code. The ",(0,t.jsx)(n.code,{children:"#[no_mangle]"})," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,t.jsx)(n.code,{children:"call"})," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When compiled, the ",(0,t.jsx)(n.code,{children:"call"})," function could be used from another library. For example, a C library could link to the resulting Wasm."]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-code",children:"Example 2: Calling a Contract with Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Another example of session code is the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call/src/main.rs"})," file, in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter",children:"counter"})," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Observe how the project is set up and review the dependencies in the ",(0,t.jsx)(n.code,{children:"counter/counter-call/Cargo.toml"})," file. Then, open the ",(0,t.jsx)(n.code,{children:"counter/counter-call/src/main.rs"})," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," function interacts with the contract's ",(0,t.jsx)(n.code,{children:"counter_inc"})," and ",(0,t.jsx)(n.code,{children:"counter_get"})," entry points. This is how the session's ",(0,t.jsx)(n.code,{children:"call"})," entry point triggers the logic stored inside the counter contract."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:" // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n"})}),"\n",(0,t.jsx)(n.h2,{id:"transfers-using-session-code",children:"Example 3: Transfers using Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, we use session code to perform a transfer using the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html",children:"transfer_from_purse_to_purse"})," system function. The entire session code is available in ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14",children:"GitHub"}),", but this is the ",(0,t.jsx)(n.code,{children:"call"})," function:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Another system function is ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html",children:"transfer_to_public_key"}),". The full session code example is on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Other transfer functions are available here:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html",children:"transfer_from_purse_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html",children:"transfer_from_purse_to_public_key"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"compiling-session-code",children:"Compiling Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file and ",(0,t.jsx)(n.code,{children:"src"})," folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the examples above, you may use the Makefiles provided:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make build-contract\n"})}),"\n",(0,t.jsx)(n.h2,{id:"executing-session-code",children:"Executing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code on a live Casper network, test it as described ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-session-code",children:"here"}),". You can also set up a local network using ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/setup-nctl",children:"NCTL"})," for additional tests."]}),"\n",(0,t.jsxs)(n.p,{children:["Session code can execute on a Casper network via a ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D#deploy",children:"Deploy"}),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and its ",(0,t.jsx)(n.code,{children:"put-deploy"})," command provide one way to execute session code."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name <NETWORK-NAME> \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH> \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where the deploy should be sent. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - Path to the contract Wasm, pointing to the compiled contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - A named and typed argument passed to the Wasm code."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"--help"})," option to view an updated list of supported arguments."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsxs)(n.p,{children:["The following brief video describes ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-session-code",children:"test session code"})," using the Casper testing framework."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/372c0574.041c94fa.js b/assets/js/372c0574.041c94fa.js new file mode 100644 index 000000000..e123e7020 --- /dev/null +++ b/assets/js/372c0574.041c94fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11208],{11044:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var t=s(74848),a=s(28453);const c={title:"Calling Contracts"},r="Calling Smart Contracts with the Rust Client",i={id:"developers/cli/calling-contracts",title:"Calling Contracts",description:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.",source:"@site/versioned_docs/version-2.0.0/developers/cli/calling-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/calling-contracts",permalink:"/2.0.0/developers/cli/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Calling Contracts"},sidebar:"developers",previous:{title:"Querying Global State",permalink:"/2.0.0/developers/cli/querying-global-state"},next:{title:"OpCode Costs Tables",permalink:"/2.0.0/developers/cli/opcode-costs"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Calling Contracts by Contract Hash",id:"calling-contracts-by-hash",level:2},{value:"Calling Contracts with Session Arguments",id:"calling-contracts-with-session-args",level:2},{value:"Calling Contracts by Package Hash",id:"calling-contracts-by-package-hash",level:2},{value:"Calling Contracts by Contract Name",id:"calling-contracts-by-name",level:2},{value:"Calling Contracts by Package Name",id:"calling-contracts-by-package-name",level:2},{value:"Calling a Contract using Wasm",id:"calling-a-contract-using-wasm",level:2},{value:"Calling Contracts that Return a Value",id:"calling-contracts-that-return-a-value",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"calling-smart-contracts-with-the-rust-client",children:"Calling Smart Contracts with the Rust Client"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Each section below includes a short video demonstrating some example output."]}),"\n",(0,t.jsxs)(n.p,{children:["The following examples use two contracts on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," described while ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),". You will need to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install this contract"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The Auction contract found in ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"this contract package"}),", already installed on Testnet as a system contract. The examples will call its ",(0,t.jsx)(n.code,{children:"delegate"})," entry point"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install contracts and query global state"})," using the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," on Testnet if you have not done so already"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"system Auction contract"})," on Testnet"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-hash",children:"Calling Contracts by Contract Hash"}),"\n",(0,t.jsxs)(n.p,{children:["After ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"installing a contract"})," in global state, you can use the contract's hash to call one of its entry points. The following usage of ",(0,t.jsx)(n.code,{children:"put-deploy"})," allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name of the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Counter contract by hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.code,{children:"--session-hash"}),' option identifies a stored contract with an entry-point called "counter-inc".']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \\\n --session-entry-point "counter-inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.code,{children:"put-deploy"})," command is nearly identical to the command used to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts#installing-contract-code",children:"install the contract"}),". Here, instead of ",(0,t.jsx)(n.code,{children:"session-path"})," pointing to the Wasm binary, we have ",(0,t.jsx)(n.code,{children:"session-hash"})," and ",(0,t.jsx)(n.code,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn\u2019t return a value. If an entry point returns a value, use code to ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"interact with runtime return values"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The following sample response contains a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", needed to verify the changes in global state, as described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts#querying-global-state",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'{\n "id": 1197172763279676268,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract by hash:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to query a previously installed Counter contract by hash."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=11",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-args",children:"Calling Contracts with Session Arguments"}),"\n",(0,t.jsxs)(n.p,{children:["When calling contract entry points, you may need to pass in information using session arguments. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command allows you to do this with the ",(0,t.jsx)(n.code,{children:"--session-arg"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-arg ["NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null"]...\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Auction contract using session arguments:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's entry point ",(0,t.jsx)(n.code,{children:"delegate"})," with three arguments:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"validator"})," is the public key of the validator to whom the tokens will be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"amount"})," is the number of tokens to be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"delegator"})," is the public key of the account delegating tokens to a validator"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To make the call, we use the contract hash, ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"}),", and the ",(0,t.jsx)(n.code,{children:"--session-hash"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract with session arguments:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to call a modified Counter contract using session arguments."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/XB_ojY1_0Uo",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-hash",children:"Calling Contracts by Package Hash"}),"\n",(0,t.jsxs)(n.p,{children:["You can also call an entry point in a contract that is part of a contract package (see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts",children:"contract upgrades"}),"). Call ",(0,t.jsx)(n.code,{children:"put-deploy"})," using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-hash"})," - Hex-encoded hash of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter using the package hash and version:"})}),"\n",(0,t.jsx)(n.p,{children:'In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:"To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction using the package hash and version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's ",(0,t.jsx)(n.code,{children:"delegate"})," entry point by specifying the package hash using the ",(0,t.jsx)(n.code,{children:"--session-package-hash"})," option. The call defaults to the highest enabled version since no version was specified with the ",(0,t.jsx)(n.code,{children:"--session-version"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package hash:"})}),"\n",(0,t.jsx)(n.p,{children:"The video shows how to query the previously installed Counter contract package."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=15",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-name",children:"Calling Contracts by Contract Name"}),"\n",(0,t.jsxs)(n.p,{children:["We can also reference a contract using a key as the contract name. When you write the contract, use the ",(0,t.jsx)(n.code,{children:"put_key"})," function to add the ContractHash under the contract's ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html#",children:"NamedKeys"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Having a key enables you to call a contract's entry-point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-name"})," - Name of the stored contract (associated with the executing account) to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on ',(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/934a452ccba8c5cf12f8bde706736400e047fba5/contract-v1/src/main.rs#L110",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,t.jsx)(n.p,{children:'The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The sample response will contain a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", which you need to use as described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts#querying-global-state",children:"here"})," to verify the changes in global state."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the system Auction contract stored in global state under the "auction" key and its ',(0,t.jsx)(n.code,{children:"delegate"})," entry point."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-name "auction" \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using a named key:"})}),"\n",(0,t.jsx)(n.p,{children:"This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=12",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-name",children:"Calling Contracts by Package Name"}),"\n",(0,t.jsxs)(n.p,{children:["To call an entry point in a contract by referencing the contract package name, you can use the ",(0,t.jsx)(n.code,{children:"session-package-name"}),", ",(0,t.jsx)(n.code,{children:"session-entry-point"}),", and ",(0,t.jsx)(n.code,{children:"session-version"})," arguments. This will enable you to access the entry point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name [NAMED_KEY_FOR_PACKAGE] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-name"})," - Name of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Specifying the package name and version number:"})}),"\n",(0,t.jsx)(n.p,{children:'This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.'}),"\n",(0,t.jsxs)(n.p,{children:["You should have previously created the contract by using ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),", and provided the contract package name as the ",(0,t.jsx)(n.code,{children:"hash_name"})," argument of ",(0,t.jsx)(n.code,{children:"new_contract"}),"."]}),"\n",(0,t.jsx)(n.p,{children:'This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' let (stored_contract_hash, contract_version) =\n storage::new_contract(counter_entry_points, \n Some(counter_named_keys), \n Some("counter_package_name".to_string()),\n Some("counter_access_uref".to_string())\n );\n'})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command to call the contract using the package name:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the package without specifying the version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call a contract that is part of the ",(0,t.jsx)(n.code,{children:"erc20_test_call"}),' package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper-client put-deploy \\\n --node-address http://3.143.158.19:7777 \\\n --chain-name integration-test \\\n --secret-key ~/casper/demo/user_a/secret_key.pem \\\n --payment-amount 1000000000 \\\n --session-package-name "erc20_test_call" \\\n --session-entry-point "check_balance_of" \\\n --session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n --session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package name:"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates how to call versioned contracts by package name."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=16",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-a-contract-using-wasm",children:"Calling a Contract using Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Session code or contract code (compiled to Wasm) can act on a contract and change its state. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command supports this mechanism as well:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/[FILE_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The argument of interest is:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Session code acting on a contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/counter",children:"Counter Contract Tutorial"})," shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"\ncasper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 25000000000 \\\n --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm\n\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using Wasm:"})}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=13",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-that-return-a-value",children:"Calling Contracts that Return a Value"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial to learn how to call a contract that returns a value using session code or contract code."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/counter",children:"Counter Contract Tutorial"})," takes you through a detailed walkthrough on how to query global state to verify a contract's state"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"Delegating with the Casper Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Look into the ",(0,t.jsx)(n.a,{href:"/resources/",children:"Resources for Smart Contract Authors"})]}),"\n",(0,t.jsxs)(n.li,{children:["See the ",(0,t.jsx)(n.a,{href:"/developers",children:"Developer How To Guides"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const a={},c=t.createContext(a);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/381391cb.1c3e00bf.js b/assets/js/381391cb.1c3e00bf.js deleted file mode 100644 index c38210df1..000000000 --- a/assets/js/381391cb.1c3e00bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6139],{35170:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var r=n(74848),s=n(28453);const a={slug:"/resources/tutorials/advanced/"},i="Advanced Tutorials",d={id:"resources/advanced/index",title:"Advanced Tutorials",description:"| Title | Description |",source:"@site/docs/resources/advanced/index.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/",permalink:"/next/resources/tutorials/advanced/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{slug:"/resources/tutorials/advanced/"},sidebar:"tutorials",previous:{title:"AWS Casper Nodes",permalink:"/next/resources/tutorials/beginner/aws-node"},next:{title:"Two-Party Multi-Sig",permalink:"/next/resources/tutorials/advanced/two-party-multi-sig"}},o={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"advanced-tutorials",children:"Advanced Tutorials"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Title"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Transactions"})}),(0,r.jsx)(t.td,{children:"A trivial two-party multi-signature scheme for signing and sending transactions"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/advanced/multi-sig/",children:"Multi-Sig Management"})}),(0,r.jsx)(t.td,{children:"Integrate key management on Casper accounts and sign transactions with multiple keys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsxs)(t.td,{children:["Contract code returning a value to the immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(t.td,{children:"Two methods to handle tokens via a contract"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})}),(0,r.jsx)(t.td,{children:"Methods to read and write data to global state on a Casper network using Rust"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/tutorials/advanced/cross-contract",children:"Cross Contract Communication"})}),(0,r.jsx)(t.td,{children:"Variations of cross-contract communication for more complex scenarios"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(t.td,{children:"Retrieve and use the authorization keys associated with a transaction"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>d});var r=n(96540);const s={},a=r.createContext(s);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/381391cb.289be185.js b/assets/js/381391cb.289be185.js new file mode 100644 index 000000000..4329b69ba --- /dev/null +++ b/assets/js/381391cb.289be185.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36139],{35170:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var r=n(74848),s=n(28453);const a={slug:"/resources/tutorials/advanced/"},i="Advanced Tutorials",d={id:"resources/advanced/index",title:"Advanced Tutorials",description:"| Title | Description |",source:"@site/docs/resources/advanced/index.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/",permalink:"/resources/tutorials/advanced/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{slug:"/resources/tutorials/advanced/"},sidebar:"tutorials",previous:{title:"AWS Casper Nodes",permalink:"/resources/tutorials/beginner/aws-node"},next:{title:"Two-Party Multi-Sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig"}},o={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"advanced-tutorials",children:"Advanced Tutorials"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Title"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Transactions"})}),(0,r.jsx)(t.td,{children:"A trivial two-party multi-signature scheme for signing and sending transactions"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/",children:"Multi-Sig Management"})}),(0,r.jsx)(t.td,{children:"Integrate key management on Casper accounts and sign transactions with multiple keys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsxs)(t.td,{children:["Contract code returning a value to the immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(t.td,{children:"Two methods to handle tokens via a contract"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})}),(0,r.jsx)(t.td,{children:"Methods to read and write data to global state on a Casper network using Rust"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/cross-contract",children:"Cross Contract Communication"})}),(0,r.jsx)(t.td,{children:"Variations of cross-contract communication for more complex scenarios"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(t.td,{children:"Retrieve and use the authorization keys associated with a transaction"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>d});var r=n(96540);const s={},a=r.createContext(s);function i(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38296185.1abf2f2d.js b/assets/js/38296185.1abf2f2d.js deleted file mode 100644 index 25059eb74..000000000 --- a/assets/js/38296185.1abf2f2d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2743],{42311:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=s(74848),r=s(28453);const c={},o="E",a={id:"concepts/glossary/E",title:"E",description:"---",source:"@site/docs/concepts/glossary/E.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/E",permalink:"/next/concepts/glossary/E",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"D",permalink:"/next/concepts/glossary/D"},next:{title:"F",permalink:"/next/concepts/glossary/F"}},i={},l=[{value:"Ecosystem",id:"ecosystem",level:2},{value:"Entry point",id:"entry-point",level:2},{value:"Equivocation",id:"equivocation",level:2},{value:"Era",id:"era",level:2},{value:"Eviction",id:"eviction",level:2},{value:"External client",id:"external-client",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"e",children:"E"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The ecosystem layer in Casper encompasses dApp design and operation."}),"\n",(0,t.jsx)(n.h2,{id:"entry-point",children:"Entry point"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#entrypoint",children:"EntryPoint"})," and ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract#step-4-defining-the-contract-entry-points",children:"Defining the Contract Entry Points"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"equivocation",children:"Equivocation"}),"\n",(0,t.jsx)(n.p,{children:"A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive."}),"\n",(0,t.jsx)(n.h2,{id:"era",children:"Era"}),"\n",(0,t.jsx)(n.p,{children:"A period of time during which the validator set does not change."}),"\n",(0,t.jsxs)(n.p,{children:["In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A#auction",children:"auction"}),". At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B#booking-block",children:"booking block"}),")."]}),"\n",(0,t.jsx)(n.h2,{id:"eviction",children:"Eviction"}),"\n",(0,t.jsxs)(n.p,{children:["Validators that fail to participate in ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E#era",children:"era"})," will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A#auction-contract",children:"auction contract"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"external-client",children:"External client"}),"\n",(0,t.jsx)(n.p,{children:"Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain."})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},c=t.createContext(r);function o(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38296185.4a41b532.js b/assets/js/38296185.4a41b532.js new file mode 100644 index 000000000..5f45d92a6 --- /dev/null +++ b/assets/js/38296185.4a41b532.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22743],{42311:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=s(74848),t=s(28453);const c={},o="E",a={id:"concepts/glossary/E",title:"E",description:"---",source:"@site/docs/concepts/glossary/E.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/E",permalink:"/concepts/glossary/E",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"D",permalink:"/concepts/glossary/D"},next:{title:"F",permalink:"/concepts/glossary/F"}},i={},l=[{value:"Ecosystem",id:"ecosystem",level:2},{value:"Entry point",id:"entry-point",level:2},{value:"Equivocation",id:"equivocation",level:2},{value:"Era",id:"era",level:2},{value:"Eviction",id:"eviction",level:2},{value:"External client",id:"external-client",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"e",children:"E"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(n.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,r.jsx)(n.p,{children:"The ecosystem layer in Casper encompasses dApp design and operation."}),"\n",(0,r.jsx)(n.h2,{id:"entry-point",children:"Entry point"}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"/developers/json-rpc/types_chain#entrypoint",children:"EntryPoint"})," and ",(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract#step-4-defining-the-contract-entry-points",children:"Defining the Contract Entry Points"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"equivocation",children:"Equivocation"}),"\n",(0,r.jsx)(n.p,{children:"A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive."}),"\n",(0,r.jsx)(n.h2,{id:"era",children:"Era"}),"\n",(0,r.jsx)(n.p,{children:"A period of time during which the validator set does not change."}),"\n",(0,r.jsxs)(n.p,{children:["In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an ",(0,r.jsx)(n.a,{href:"/concepts/glossary/A#auction",children:"auction"}),". At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see ",(0,r.jsx)(n.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"eviction",children:"Eviction"}),"\n",(0,r.jsxs)(n.p,{children:["Validators that fail to participate in ",(0,r.jsx)(n.a,{href:"/concepts/glossary/E#era",children:"era"})," will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the ",(0,r.jsx)(n.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"external-client",children:"External client"}),"\n",(0,r.jsx)(n.p,{children:"Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain."})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var r=s(96540);const t={},c=r.createContext(t);function o(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/387aabc2.5dc9fb8c.js b/assets/js/387aabc2.5dc9fb8c.js new file mode 100644 index 000000000..c8744b3b9 --- /dev/null +++ b/assets/js/387aabc2.5dc9fb8c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67880],{24651:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"Using CSPR.live"},d="Using the CSPR.live block explorer",l={id:"users/csprlive/index",title:"Using CSPR.live",description:"| Topic | Description |",source:"@site/versioned_docs/version-2.0.0/users/csprlive/index.md",sourceDirName:"users/csprlive",slug:"/users/csprlive/",permalink:"/2.0.0/users/csprlive/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Using CSPR.live"},sidebar:"users",previous:{title:"Delegating Tokens",permalink:"/2.0.0/users/delegating"},next:{title:"Testnet Funding",permalink:"/2.0.0/users/testnet-faucet"}},c={},o=[];function a(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-the-csprlive-block-explorer",children:"Using the CSPR.live block explorer"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,s.jsx)(n.td,{children:"Fund a Testnet account for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/users/token-transfer",children:"Transferring Tokens"})}),(0,s.jsx)(n.td,{children:"Transfer tokens using the CSPR.live block explorer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/users/delegate-ui",children:"Delegating Tokens"})}),(0,s.jsx)(n.td,{children:"Delegate tokens to a validator"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,s.jsx)(n.td,{children:"Undelegate tokens from a validator"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38b4dbd3.7e645026.js b/assets/js/38b4dbd3.7e645026.js new file mode 100644 index 000000000..4ddaf7afb --- /dev/null +++ b/assets/js/38b4dbd3.7e645026.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72033],{99648:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>r});var s=n(74848),i=n(28453);const o={slug:"/concepts/economics/delegation"},a="Delegation Details",c={id:"concepts/economics/staking/delegation",title:"Delegation Details",description:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/delegation.md",sourceDirName:"concepts/economics/staking",slug:"/concepts/economics/delegation",permalink:"/1.5.X/concepts/economics/delegation",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/concepts/economics/delegation"},sidebar:"concepts",previous:{title:"Staking vs. Delegating",permalink:"/1.5.X/staking"},next:{title:"Glossary",permalink:"/1.5.X/glossary"}},l={},r=[{value:"Delegation Cost",id:"delegation-cost",level:2},{value:"First-time Delegation",id:"first-time-delegation",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",img:"img",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"delegation-details",children:"Delegation Details"})}),"\n",(0,s.jsx)(t.p,{children:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details."}),"\n",(0,s.jsx)(t.h2,{id:"delegation-cost",children:"Delegation Cost"}),"\n",(0,s.jsxs)(t.p,{children:["The delegation cost is defined in the ",(0,s.jsx)(t.code,{children:"chainspec.toml"})," file for each Casper network. In this ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.3.2/resources/production/chainspec.toml",children:"example chainspec"}),", the delegation is set to cost 2.5 CSPR. However, ",(0,s.jsx)(t.code,{children:"when you perform the delegation, you see that it costs a little more"})," than what is specified in the chainspec. Let\u2019s discuss why this happens."]}),"\n",(0,s.jsx)(t.p,{children:"When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is addition to the delegation cost defined in the chainspec file."}),"\n",(0,s.jsx)(t.p,{children:"For example, the chainspec file in release 1.3.2 will contain the following information. This is how the delegation cost is defined in the chainspec.toml file of a Casper network."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Figure 1"}),": Delegation cost is defined in the chainspec.toml file of a Casper network"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network\n",src:n(29510).A+"",width:"543",height:"552"})}),"\n",(0,s.jsxs)(t.p,{children:["Delegation fees may change over time, so, it is essential to stay up to date. To do so, select the latest release in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"Github"}),", and navigate to the chainspec.toml file."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are unsure about anything, please join the ",(0,s.jsx)(t.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"})," to ask us questions."]}),"\n",(0,s.jsx)(t.h2,{id:"first-time-delegation",children:"First-time Delegation"}),"\n",(0,s.jsx)(t.p,{children:"If you perform the delegation for the first time, the system charges some gas to create a purse to hold the delegated tokens."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Example:"})," The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on ",(0,s.jsx)(t.a,{href:"https://cspr.live/",children:"Mainnet"})]}),"\n",(0,s.jsx)(t.p,{children:"It is essential to have enough funds in your account's main purse when you set up a delegation transaction. Otherwise, the transaction will fail, and you will lose the transfer cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer."}),"\n",(0,s.jsxs)(t.p,{children:["As a result, when performing a ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/delegate",children:"delegation using the command line"}),", we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Figure 2"})," : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR\n",(0,s.jsx)(t.img,{alt:"Delegation Details",src:n(70623).A+"",width:"1256",height:"1266"})]}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"NOTE:"})})}),"\n",(0,s.jsx)(t.p,{children:"Transaction costs depend on each Casper network and the cost tables defined in the chainspec. The examples you will find in the documentation are general."}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsxs)(t.p,{children:["Lastly, we recommend that you try out delegations on the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/%3E",children:"Casper Testnet"})," before making actual transactions on the ",(0,s.jsx)(t.a,{href:"https://cspr.live/",children:"Casper Mainnet"}),". This way, you will understand the costs involved in delegating tokens."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},29510:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/economic-delegationCost-d5686179171d910405bd9ba70380ecd7.png"},70623:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/economic-delegationDetails-39ff9fadcf1ff742716046d64ef6789e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38b4dbd3.bdc4f617.js b/assets/js/38b4dbd3.bdc4f617.js deleted file mode 100644 index d4611b4f0..000000000 --- a/assets/js/38b4dbd3.bdc4f617.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2033],{99648:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>r});var s=n(74848),i=n(28453);const o={slug:"/concepts/economics/delegation"},a="Delegation Details",c={id:"concepts/economics/staking/delegation",title:"Delegation Details",description:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/delegation.md",sourceDirName:"concepts/economics/staking",slug:"/concepts/economics/delegation",permalink:"/concepts/economics/delegation",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/concepts/economics/delegation"},sidebar:"concepts",previous:{title:"Staking vs. Delegating",permalink:"/staking"},next:{title:"Glossary",permalink:"/glossary"}},l={},r=[{value:"Delegation Cost",id:"delegation-cost",level:2},{value:"First-time Delegation",id:"first-time-delegation",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",img:"img",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"delegation-details",children:"Delegation Details"})}),"\n",(0,s.jsx)(t.p,{children:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details."}),"\n",(0,s.jsx)(t.h2,{id:"delegation-cost",children:"Delegation Cost"}),"\n",(0,s.jsxs)(t.p,{children:["The delegation cost is defined in the ",(0,s.jsx)(t.code,{children:"chainspec.toml"})," file for each Casper network. In this ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.3.2/resources/production/chainspec.toml",children:"example chainspec"}),", the delegation is set to cost 2.5 CSPR. However, ",(0,s.jsx)(t.code,{children:"when you perform the delegation, you see that it costs a little more"})," than what is specified in the chainspec. Let\u2019s discuss why this happens."]}),"\n",(0,s.jsx)(t.p,{children:"When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is addition to the delegation cost defined in the chainspec file."}),"\n",(0,s.jsx)(t.p,{children:"For example, the chainspec file in release 1.3.2 will contain the following information. This is how the delegation cost is defined in the chainspec.toml file of a Casper network."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Figure 1"}),": Delegation cost is defined in the chainspec.toml file of a Casper network"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network\n",src:n(40880).A+"",width:"543",height:"552"})}),"\n",(0,s.jsxs)(t.p,{children:["Delegation fees may change over time, so, it is essential to stay up to date. To do so, select the latest release in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"Github"}),", and navigate to the chainspec.toml file."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are unsure about anything, please join the ",(0,s.jsx)(t.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"})," to ask us questions."]}),"\n",(0,s.jsx)(t.h2,{id:"first-time-delegation",children:"First-time Delegation"}),"\n",(0,s.jsx)(t.p,{children:"If you perform the delegation for the first time, the system charges some gas to create a purse to hold the delegated tokens."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Example:"})," The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on ",(0,s.jsx)(t.a,{href:"https://cspr.live/",children:"Mainnet"})]}),"\n",(0,s.jsx)(t.p,{children:"It is essential to have enough funds in your account's main purse when you set up a delegation transaction. Otherwise, the transaction will fail, and you will lose the transfer cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer."}),"\n",(0,s.jsxs)(t.p,{children:["As a result, when performing a ",(0,s.jsx)(t.a,{href:"/developers/cli/delegate",children:"delegation using the command line"}),", we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Figure 2"})," : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR\n",(0,s.jsx)(t.img,{alt:"Delegation Details",src:n(20477).A+"",width:"1256",height:"1266"})]}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"NOTE:"})})}),"\n",(0,s.jsx)(t.p,{children:"Transaction costs depend on each Casper network and the cost tables defined in the chainspec. The examples you will find in the documentation are general."}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsxs)(t.p,{children:["Lastly, we recommend that you try out delegations on the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/%3E",children:"Casper Testnet"})," before making actual transactions on the ",(0,s.jsx)(t.a,{href:"https://cspr.live/",children:"Casper Mainnet"}),". This way, you will understand the costs involved in delegating tokens."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},40880:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/economic-delegationCost-d5686179171d910405bd9ba70380ecd7.png"},20477:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/economic-delegationDetails-39ff9fadcf1ff742716046d64ef6789e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38ff73e5.a2c2ca1e.js b/assets/js/38ff73e5.a2c2ca1e.js new file mode 100644 index 000000000..31b4313b3 --- /dev/null +++ b/assets/js/38ff73e5.a2c2ca1e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65438],{99793:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="U",a={id:"concepts/glossary/U",title:"U",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/U.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/U",permalink:"/2.0.0/concepts/glossary/U",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"T",permalink:"/2.0.0/concepts/glossary/T"},next:{title:"V",permalink:"/2.0.0/concepts/glossary/V"}},i={},l=[{value:"Unbonding",id:"unbonding",level:2},{value:"URef",id:"uref",level:2},{value:"Users",id:"users",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"u",children:"U"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"unbonding",children:"Unbonding"}),"\n",(0,r.jsxs)(s.p,{children:["Withdrawing money from the ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A#auction",children:"auction"})," contract with ",(0,r.jsx)(s.em,{children:"withdraw bid"})," and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed."]}),"\n",(0,r.jsx)(s.h2,{id:"uref",children:"URef"}),"\n",(0,r.jsxs)(s.p,{children:["An ",(0,r.jsx)(s.strong,{children:"U"}),"nforgeable ",(0,r.jsx)(s.strong,{children:"Ref"}),"erence, used by a Casper network to store any value other than ",(0,r.jsx)(s.code,{children:"Account"}),". More information can be found ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/design/casper-design#uref-head",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"users",children:"Users"}),"\n",(0,r.jsx)(s.p,{children:"Users execute session and contract code using the platform's computational resources."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/396a697c.6fa30002.js b/assets/js/396a697c.6fa30002.js new file mode 100644 index 000000000..6503026b6 --- /dev/null +++ b/assets/js/396a697c.6fa30002.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25005],{48949:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),d=t(28453);const s={title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},r="CEP-78 Modalities",o={id:"resources/tokens/cep78/modalities",title:"CEP-78 Modalities",description:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/modalities.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/modalities",permalink:"/2.0.0/resources/tokens/cep78/modalities",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},sidebar:"resources",previous:{title:"Introduction",permalink:"/2.0.0/resources/tokens/cep78/introduction"},next:{title:"On-chain Installation",permalink:"/2.0.0/resources/tokens/using-casper-client"}},c={},a=[{value:"Ownership",id:"ownership",level:2},{value:"NFTKind",id:"nftkind",level:2},{value:"NFTHolderMode",id:"nftholdermode",level:2},{value:"WhitelistMode",id:"whitelistmode",level:2},{value:"Minting",id:"minting",level:2},{value:"NFTMetadataKind",id:"nftmetadatakind",level:2},{value:"CEP-78 metadata example",id:"cep-78-metadata-example",level:3},{value:"NFT-721 metadata example",id:"nft-721-metadata-example",level:3},{value:"Custom Validated",id:"custom-validated",level:3},{value:"Example Custom Validated schema",id:"example-custom-validated-schema",level:4},{value:"Example Custom Metadata",id:"example-custom-metadata",level:4},{value:"NFTIdentifierMode",id:"nftidentifiermode",level:2},{value:"Metadata Mutability",id:"metadata-mutability",level:2},{value:"BurnMode",id:"burnmode",level:2},{value:"OwnerReverseLookupMode",id:"ownerreverselookupmode",level:2},{value:"NamedKeyConventionMode",id:"namedkeyconventionmode",level:2},{value:"EventsMode",id:"eventsmode",level:2},{value:"Transfer Filter Hook",id:"transfer-filter-hook",level:3},{value:"CEP47 Mode",id:"cep47-mode",level:3},{value:"Casper Event Standard",id:"casper-event-standard",level:3},{value:"Modality Conflicts",id:"modality-conflicts",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cep-78-modalities",children:"CEP-78 Modalities"})}),"\n",(0,i.jsx)(n.p,{children:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior."}),"\n",(0,i.jsx)(n.h2,{id:"ownership",children:"Ownership"}),"\n",(0,i.jsx)(n.p,{children:"This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Minter"}),": ",(0,i.jsx)(n.code,{children:"Minter"})," mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the ",(0,i.jsx)(n.code,{children:"Minter"})," mode the owner of the NFT will not change and thus cannot be transferred to another entity."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Assigned"}),": ",(0,i.jsx)(n.code,{children:"Assigned"})," mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the ",(0,i.jsx)(n.code,{children:"Minter"})," mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Transferable"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode the owner of the newly minted NFT must be specified by the minter. However, in the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, NFTs can be transferred from the owner to another entity."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In all the three mentioned modes, the owner entity is currently restricted to ",(0,i.jsx)(n.code,{children:"Accounts"})," on the Casper network."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, it is possible to transfer the NFT to an ",(0,i.jsx)(n.code,{children:"Account"})," that does not exist."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"Ownership"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:'"ownership_mode"'})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Ownership"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Minter"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Assigned"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transferable"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ownership mode of a contract can be determined by querying the ",(0,i.jsx)(n.code,{children:"ownership_mode"})," entry within the contract's ",(0,i.jsx)(n.code,{children:"NamedKeys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"nftkind",children:"NFTKind"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality does not alter or govern the behavior of the contract itself\nand only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Physical"}),": The NFT represents a real-world physical item e.g., a house."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Digital"}),": The NFT represents a digital item, e.g., a unique JPEG or digital art."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Virtual"}),": The NFT is the virtual representation of a physical notion, e.g., a patent or copyright."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_kind"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Physical"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Digital"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftholdermode",children:"NFTHolderMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Accounts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Accounts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Contracts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mixed"}),": In this mode both ",(0,i.jsx)(n.code,{children:"Accounts"})," and ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," is set to ",(0,i.jsx)(n.code,{children:"Contracts"})," a ",(0,i.jsx)(n.code,{children:"ContractHash"})," whitelist must be provided. This whitelist dictates which\n",(0,i.jsx)(n.code,{children:"Contracts"})," are allowed to mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"Installer"})," minting mode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTHolderMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Accounts"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Contracts"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mixed"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Mixed"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_holder_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"whitelistmode",children:"WhitelistMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unlocked"}),": The ACL whitelist is unlocked and can be updated via the set variables endpoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Locked"}),": The ACL whitelist is locked and cannot be updated further."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is set to ",(0,i.jsx)(n.code,{children:"Locked"})," an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"ACL"})," minting mode. These entities include ",(0,i.jsx)(n.code,{children:"Accounts"})," and/or ",(0,i.jsx)(n.code,{children:"Contracts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"whitelist_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"WhitelistMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Unlocked"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Locked"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"minting",children:"Minting"}),"\n",(0,i.jsx)(n.p,{children:"The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Installer"}),": This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Public"}),": This mode allows any account to mint NFT tokens."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ACL"}),": This mode allows whitelisted accounts or contracts to mint NFT tokens."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Installer"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"minting_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MintingMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Installer"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Public"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ACL"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftmetadatakind",children:"NFTMetadataKind"}),"\n",(0,i.jsx)(n.p,{children:"This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP78"}),": This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NFT721"}),": This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Raw"}),": This mode specifies that metadata validation will not occur and raw strings can be passed to ",(0,i.jsx)(n.code,{children:"token_metadata"})," runtime argument as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CustomValidated"}),": This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["During installation, one ",(0,i.jsx)(n.code,{children:"NFTMetadataKind"})," must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the ",(0,i.jsx)(n.code,{children:"additional_required_metadata"})," or ",(0,i.jsx)(n.code,{children:"optional_metadata"})," arguments."]}),"\n",(0,i.jsx)(n.h3,{id:"cep-78-metadata-example",children:"CEP-78 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "token_uri": "https://www.barfoo.com",\n "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"nft-721-metadata-example",children:"NFT-721 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "symbol": "abc",\n "token_uri": "https://www.barfoo.com"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"custom-validated",children:"Custom Validated"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation.\nThe schema is passed as a String value to ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument at the time of installation. Once provided, the schema\nfor a given instance of the contract cannot be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["The custom JSON schema must contain a top-level ",(0,i.jsx)(n.code,{children:"properties"})," field. An example of a ",(0,i.jsx)(n.a,{href:"#example-custom-validated-schema",children:(0,i.jsx)(n.code,{children:"valid JSON schema"})})," is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata.\nIf the metadata kind is not set to custom validated, then the value passed to the ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument will be ignored."]}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-validated-schema",children:"Example Custom Validated schema"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "properties": {\n "deity_name": {\n "name": "deity_name",\n "description": "The name of deity from a particular pantheon.",\n "required": true\n },\n "mythology": {\n "name": "mythology",\n "description": "The mythology the deity belongs to.",\n "required": true\n }\n }\n}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-metadata",children:"Example Custom Metadata"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "deity_name": "Baldur",\n "mythology": "Nordic"\n}\n'})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTMetadataKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP78"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NFT721"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Raw"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CustomValidated"}),(0,i.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftidentifiermode",children:"NFTIdentifierMode"}),"\n",(0,i.jsx)(n.p,{children:"The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Ordinal"}),": NFTs minted in this modality are identified by a ",(0,i.jsx)(n.code,{children:"u64"})," value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Hash"}),": NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since the primary identifier in the ",(0,i.jsx)(n.code,{children:"Hash"})," mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint."]}),"\n",(0,i.jsxs)(n.p,{children:["Attempting to install the contract with the ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," modality set to ",(0,i.jsx)(n.code,{children:"Mutable"})," in the ",(0,i.jsx)(n.code,{children:"Hash"})," identifier mode will raise an error."]}),"\n",(0,i.jsx)(n.p,{children:"This modality is a required installation parameter and cannot be changed once the contract has been installed."}),"\n",(0,i.jsxs)(n.p,{children:["It is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"identifier_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTIdentifierMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ordinal"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Hash"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"metadata-mutability",children:"Metadata Mutability"}),"\n",(0,i.jsx)(n.p,{children:"The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Immutable"}),": Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mutable"}),": Metadata for NFTs minted in this mode can update the metadata via the ",(0,i.jsx)(n.code,{children:"set_token_metadata"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Mutable"})," option cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"Hash"})," modality for the NFT identifier; attempting to install the contract with this configuration raises ",(0,i.jsx)(n.code,{children:"InvalidMetadataMutability"})," error.\nThis modality is a required installation parameter and cannot be changed once the contract has been installed.\nIt is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"metadata_mutability"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MetadataMutability"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Immutable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mutable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"burnmode",children:"BurnMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"BurnMode"})," modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality\nprovides two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Burnable"}),": Minted tokens can be burnt."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NonBurnable"}),": Minted tokens cannot be burnt."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"BurnMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burnable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NonBurnable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Burnable"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"burn_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"ownerreverselookupmode",children:"OwnerReverseLookupMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides the following options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoLookup"}),": The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Complete"}),": The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransfersOnly"}),": The reporting and receipt functionality is supported like ",(0,i.jsx)(n.code,{children:"Complete"}),". However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, when set to ",(0,i.jsx)(n.code,{children:"Complete"}),", causes a receipt to be returned by the ",(0,i.jsx)(n.code,{children:"mint"})," or ",(0,i.jsx)(n.code,{children:"transfer"})," entrypoints, which the caller can store in their account or contract context for later reference."]}),"\n",(0,i.jsxs)(n.p,{children:["Further, two special entrypoints are enabled in ",(0,i.jsx)(n.code,{children:"Complete"})," mode. First, ",(0,i.jsx)(n.code,{children:"register_owner"})," which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, ",(0,i.jsx)(n.code,{children:"updated_receipts"}),", which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"OwnerReverseLookupMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoLookup"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Complete"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TransfersOnly"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"NoLookup"})," mode if not provided. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"owner_reverse_lookup_mode"})," runtime argument. This mode cannot be changed once the contract has been installed."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"ownership_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Minter"})," and the ",(0,i.jsx)(n.code,{children:"minting_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Installer"})," only, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"NoLookup"}),". This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,i.jsx)(n.code,{children:"TransfersOnly"})," then ",(0,i.jsx)(n.code,{children:"ownership_mode"})," has to be set to ",(0,i.jsx)(n.code,{children:"Transferable"})," only. This is because other ownership modes do not allow transfer."]}),"\n",(0,i.jsxs)(n.p,{children:["If you are upgrading a contract from CEP-78 version 1.0 to 1.1, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"Complete"}),", as this was the standard behavior of CEP-78 1.0. In addition to being set to ",(0,i.jsx)(n.code,{children:"Complete"}),", existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration."]}),"\n",(0,i.jsx)(n.p,{children:"If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option."}),"\n",(0,i.jsx)(n.h2,{id:"namedkeyconventionmode",children:"NamedKeyConventionMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NamedKeyConvention"})," modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"DerivedFromCollectionName"}),": This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's ",(0,i.jsx)(n.code,{children:"NamedKeys"})," as ",(0,i.jsx)(n.code,{children:"cep78_contract_package_<collection_name>"})," and ",(0,i.jsx)(n.code,{children:"cep78_contract_package_access_<collection_name>"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_standard"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries originally created during the 1.0 installation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_custom"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,i.jsx)(n.code,{children:"access_key_name"})," and ",(0,i.jsx)(n.code,{children:"hash_key_name"})," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NamedKeyConvention"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"DerivedFromCollectionName"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_standard"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_custom"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"eventsmode",children:"EventsMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."]}),"\n",(0,i.jsx)(n.p,{children:"The modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoEvents"}),": This modality will signal the contract to not record events at all. This is the default mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP47"}),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,i.jsx)(n.a,{href:"#cep47-mode",children:"below"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CES"}),": This modality will signal the contract to record events using the ",(0,i.jsx)(n.a,{href:"#casper-event-standard",children:"Casper Event Standard"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"EventsMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoEvents"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP47"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CES"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"transfer-filter-hook",children:"Transfer Filter Hook"}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,i.jsx)(n.code,{children:"transfer"})," method is invoked on the contract. CEP-78 will call the ",(0,i.jsx)(n.code,{children:"can_transfer"}),"\nmethod on the specified callback contract, which is expected to return a value of ",(0,i.jsx)(n.code,{children:"TransferFilterContractResult"}),", represented as a u8."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::DenyTransfer"})," will block the transfer regardless of the outcome of other checks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::ProceedTransfer"})," will allow the transfer to proceed if other checks also pass"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter can be enabled by passing a ",(0,i.jsx)(n.code,{children:"ARG_TRANSFER_FILTER_CONTRACT"})," argument to the install method, with a value of type ",(0,i.jsx)(n.code,{children:"Option<Key>"})]}),"\n",(0,i.jsx)(n.h3,{id:"cep47-mode",children:"CEP47 Mode"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP47 ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,i.jsx)(n.code,{children:"BTreeMap"})," within a dictionary (",(0,i.jsx)(n.code,{children:"EVENTS"}),") in the contract's context. Entries consist of the ",(0,i.jsx)(n.code,{children:"PREFIX_HASH_KEY_NAME"}),", followed by the ",(0,i.jsx)(n.code,{children:"EVENT_TYPE"})," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/dictionaries",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalGranted"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdate"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"token_id (String)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"casper-event-standard",children:"Casper Event Standard"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CES"})," is an option within the ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,i.jsx)(n.code,{children:"__events"})," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The emitted events are encoded according to the ",(0,i.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"Casper Event Standard"}),", and the schema is visible to an observer reading the ",(0,i.jsx)(n.code,{children:"__events_schema"})," contract named key."]}),"\n",(0,i.jsx)(n.p,{children:"For this CEP-78 reference implementation, the events schema is as follows:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Approval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdated"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"modality-conflicts",children:"Modality Conflicts"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," option set to ",(0,i.jsx)(n.code,{children:"Mutable"})," cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"NFTIdentifierMode"})," modality set to ",(0,i.jsx)(n.code,{children:"Hash"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const d={},s=i.createContext(d);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/398cf21c.1c69896e.js b/assets/js/398cf21c.1c69896e.js new file mode 100644 index 000000000..24471861e --- /dev/null +++ b/assets/js/398cf21c.1c69896e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57320],{68259:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>h});var a=n(74848),s=n(28453);const i={},o="Authorization Keys",r={id:"concepts/list-auth-keys",title:"Authorization Keys",description:"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.",source:"@site/docs/concepts/list-auth-keys.md",sourceDirName:"concepts",slug:"/concepts/list-auth-keys",permalink:"/concepts/list-auth-keys",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"concepts",previous:{title:"Smart Contracts",permalink:"/concepts/smart-contracts"},next:{title:"Call Stacks",permalink:"/concepts/callstack"}},c={},h=[{value:"Associated Keys vs. Authorization Keys",id:"associated-keys-vs-authorization-keys",level:2},{value:"Accessing Authorization Keys from a Smart Contract",id:"accessing-authorization-keys-from-a-smart-contract",level:2},{value:"When to Use Authorization Keys",id:"when-to-use-authorization-keys",level:2}];function u(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"authorization-keys",children:"Authorization Keys"})}),"\n",(0,a.jsxs)(t.p,{children:["This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the ",(0,a.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial for an example."]}),"\n",(0,a.jsx)(t.h2,{id:"associated-keys-vs-authorization-keys",children:"Associated Keys vs. Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Let's review the difference between associated keys to an Account and authorization keys for a transaction."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about ",(0,a.jsx)(t.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys and weights"})," and try the ",(0,a.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:["Authorization keys are public keys used to sign a transaction and are listed in the transaction's ",(0,a.jsx)(t.code,{children:"approvals"}),". Authorization keys are a subset of the associated keys of the account under which the transaction is executed."]}),"\n",(0,a.jsxs)(t.li,{children:["When a node receives a transaction, it checks that the transaction has the required authorization keys under ",(0,a.jsx)(t.code,{children:"approvals"})," before including it in a block."]}),"\n",(0,a.jsx)(t.li,{children:"Different transactions executing the same smart contract can have different authorization keys."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Auth Keys",src:n(77969).A+"",width:"862",height:"842"})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of an Account's associated keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"associated_keys": [\n{\n "account_hash": "account-hash-1ab\u202611",\n "weight": 1\n},\n{\n "account_hash": "account-hash-2cd\u202622",\n "weight": 1\n},\n{\n "account_hash": "account-hash-3de\u202633",\n "weight": 1\n },\n{\n "account_hash": "account-hash-4fg\u202644",\n "weight": 1\n}\n ], ...\n'})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of a transaction's authorization keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"approvals": [\n {\n "signer": " 2cd...22",\n "signature": "02df8c...f481"\n },\n {\n "signer": "4fg...44",\n "signature": "02ef21...756a"\n }\n]\n'})}),"\n",(0,a.jsx)(t.h2,{id:"accessing-authorization-keys-from-a-smart-contract",children:"Accessing Authorization Keys from a Smart Contract"}),"\n",(0,a.jsxs)(t.p,{children:["Contract code can retrieve the set of authorization keys for a given transaction by calling the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"contract_api::runtime::list_authorization_keys"})," function, which returns the set of account hashes representing the keys used to sign the transaction."]}),"\n",(0,a.jsx)(t.h2,{id:"when-to-use-authorization-keys",children:"When to Use Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations."}),"\n",(0,a.jsxs)(t.p,{children:["Try the ",(0,a.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial to view an example workflow."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},77969:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/authorization-keys-9187fa39eca478722639797b5109fa50.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/398cf21c.db34c60d.js b/assets/js/398cf21c.db34c60d.js deleted file mode 100644 index c64017370..000000000 --- a/assets/js/398cf21c.db34c60d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7320],{68259:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>h});var a=n(74848),s=n(28453);const i={},o="Authorization Keys",r={id:"concepts/list-auth-keys",title:"Authorization Keys",description:"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.",source:"@site/docs/concepts/list-auth-keys.md",sourceDirName:"concepts",slug:"/concepts/list-auth-keys",permalink:"/next/concepts/list-auth-keys",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"concepts",previous:{title:"Smart Contracts",permalink:"/next/concepts/smart-contracts"},next:{title:"Call Stacks",permalink:"/next/concepts/callstack"}},c={},h=[{value:"Associated Keys vs. Authorization Keys",id:"associated-keys-vs-authorization-keys",level:2},{value:"Accessing Authorization Keys from a Smart Contract",id:"accessing-authorization-keys-from-a-smart-contract",level:2},{value:"When to Use Authorization Keys",id:"when-to-use-authorization-keys",level:2}];function u(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"authorization-keys",children:"Authorization Keys"})}),"\n",(0,a.jsxs)(t.p,{children:["This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the ",(0,a.jsx)(t.a,{href:"/next/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial for an example."]}),"\n",(0,a.jsx)(t.h2,{id:"associated-keys-vs-authorization-keys",children:"Associated Keys vs. Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Let's review the difference between associated keys to an Account and authorization keys for a transaction."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about ",(0,a.jsx)(t.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys and weights"})," and try the ",(0,a.jsx)(t.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:["Authorization keys are public keys used to sign a transaction and are listed in the transaction's ",(0,a.jsx)(t.code,{children:"approvals"}),". Authorization keys are a subset of the associated keys of the account under which the transaction is executed."]}),"\n",(0,a.jsxs)(t.li,{children:["When a node receives a transaction, it checks that the transaction has the required authorization keys under ",(0,a.jsx)(t.code,{children:"approvals"})," before including it in a block."]}),"\n",(0,a.jsx)(t.li,{children:"Different transactions executing the same smart contract can have different authorization keys."}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Auth Keys",src:n(41431).A+"",width:"862",height:"842"})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of an Account's associated keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"associated_keys": [\n{\n "account_hash": "account-hash-1ab\u202611",\n "weight": 1\n},\n{\n "account_hash": "account-hash-2cd\u202622",\n "weight": 1\n},\n{\n "account_hash": "account-hash-3de\u202633",\n "weight": 1\n },\n{\n "account_hash": "account-hash-4fg\u202644",\n "weight": 1\n}\n ], ...\n'})}),"\n",(0,a.jsx)(t.p,{children:"Here is a sample JSON representation of a transaction's authorization keys:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{children:'"approvals": [\n {\n "signer": " 2cd...22",\n "signature": "02df8c...f481"\n },\n {\n "signer": "4fg...44",\n "signature": "02ef21...756a"\n }\n]\n'})}),"\n",(0,a.jsx)(t.h2,{id:"accessing-authorization-keys-from-a-smart-contract",children:"Accessing Authorization Keys from a Smart Contract"}),"\n",(0,a.jsxs)(t.p,{children:["Contract code can retrieve the set of authorization keys for a given transaction by calling the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"contract_api::runtime::list_authorization_keys"})," function, which returns the set of account hashes representing the keys used to sign the transaction."]}),"\n",(0,a.jsx)(t.h2,{id:"when-to-use-authorization-keys",children:"When to Use Authorization Keys"}),"\n",(0,a.jsx)(t.p,{children:"Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations."}),"\n",(0,a.jsxs)(t.p,{children:["Try the ",(0,a.jsx)(t.a,{href:"/next/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial to view an example workflow."]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(u,{...e})}):u(e)}},41431:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/authorization-keys-9187fa39eca478722639797b5109fa50.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/39ac5a41.0cb58650.js b/assets/js/39ac5a41.0cb58650.js new file mode 100644 index 000000000..6b7f00e68 --- /dev/null +++ b/assets/js/39ac5a41.0cb58650.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8016],{55847:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var c=n(74848),s=n(28453);const i={title:"Call Stacks"},a="Understanding Call Stacks",o={id:"concepts/callstack",title:"Call Stacks",description:"Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.",source:"@site/versioned_docs/version-1.5.X/concepts/callstack.md",sourceDirName:"concepts",slug:"/concepts/callstack",permalink:"/1.5.X/concepts/callstack",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Call Stacks"},sidebar:"concepts",previous:{title:"Authorization Keys",permalink:"/1.5.X/concepts/list-auth-keys"},next:{title:"Dictionaries",permalink:"/1.5.X/concepts/dictionaries"}},r={},l=[{value:"The Caller",id:"the-caller",level:2},{value:"The Call Stack",id:"the-call-stack",level:2},{value:"Limitations",id:"limitations",level:2}];function h(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,s.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"understanding-call-stacks",children:"Understanding Call Stacks"})}),"\n",(0,c.jsxs)(e.p,{children:["Users wishing to interact with a Casper network must do so through ",(0,c.jsx)(e.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"sending a Deploy"}),". All Deploys consist of ",(0,c.jsx)(e.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"session code"})," run in the context of the user account that sent the Deploy. The session code may ",(0,c.jsx)(e.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install contract code to global state"}),", or interact with previously ",(0,c.jsx)(e.a,{href:"/1.5.X/developers/writing-onchain-code/calling-contracts",children:"installed contract code"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["When the session code within a Deploy interacts with one or more contracts, this is the beginning of a ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-types/latest/casper_types/system/enum.CallStackElement.html",children:(0,c.jsx)(e.code,{children:"Call Stack"})}),". A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code."]}),"\n",(0,c.jsx)(e.h2,{id:"the-caller",children:"The Caller"}),"\n",(0,c.jsxs)(e.p,{children:["In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in each call stack. The account that initiated the deploy can be retrieved with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_caller.html",children:"contract_api::runtime::get_caller"})," function."]}),"\n",(0,c.jsx)(e.h2,{id:"the-call-stack",children:"The Call Stack"}),"\n",(0,c.jsxs)(e.p,{children:["Developers can access the call stack with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_call_stack.html",children:"contract_api::runtime::get_call_stack"})," function."]}),"\n",(0,c.jsxs)(e.p,{children:["If session code calls a contract, which in turn calls another contract, then the session code would represent the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in the stack, the contract called by the initiating session code would be the ",(0,c.jsx)(e.em,{children:"first"})," and the contract called by the first contract would be the ",(0,c.jsx)(e.em,{children:"second"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["In this example, the first contract would be the ",(0,c.jsx)(e.code,{children:"immediate caller"})," of the second contract, meaning it interacted directly with it. The session code would remain the ",(0,c.jsx)(e.code,{children:"caller"}),"."]}),"\n",(0,c.jsx)(e.p,{children:(0,c.jsx)(e.img,{src:n(29602).A+"",width:"1024",height:"576"})}),"\n",(0,c.jsx)(e.h2,{id:"limitations",children:"Limitations"}),"\n",(0,c.jsxs)(e.p,{children:["Casper networks place a limitation on the maximum height of a call stack. This value can be set within the ",(0,c.jsx)(e.code,{children:"chainspec"})," for the network in question. For the Casper Mainnet, this limit is set at ",(0,c.jsx)(e.code,{children:"10"})," contracts. This does not include the initiating session code, which would still count as the ",(0,c.jsx)(e.em,{children:"zeroth"})," instance within the stack."]}),"\n",(0,c.jsx)(e.p,{children:"As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation."}),"\n",(0,c.jsx)(e.admonition,{type:"note",children:(0,c.jsx)(e.p,{children:"Contract code cannot call session code, only other contract code."})})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(h,{...t})}):h(t)}},29602:(t,e,n)=>{n.d(e,{A:()=>c});const c=n.p+"assets/images/callstack-b77837c35962b1314c65801ee56f8321.png"},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>o});var c=n(96540);const s={},i=c.createContext(s);function a(t){const e=c.useContext(i);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:a(t.components),c.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/39ac5a41.6476776a.js b/assets/js/39ac5a41.6476776a.js deleted file mode 100644 index 58ae18a0f..000000000 --- a/assets/js/39ac5a41.6476776a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8016],{55847:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var c=n(74848),s=n(28453);const i={title:"Call Stacks"},a="Understanding Call Stacks",o={id:"concepts/callstack",title:"Call Stacks",description:"Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.",source:"@site/versioned_docs/version-1.5.X/concepts/callstack.md",sourceDirName:"concepts",slug:"/concepts/callstack",permalink:"/concepts/callstack",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Call Stacks"},sidebar:"concepts",previous:{title:"Authorization Keys",permalink:"/concepts/list-auth-keys"},next:{title:"Dictionaries",permalink:"/concepts/dictionaries"}},r={},l=[{value:"The Caller",id:"the-caller",level:2},{value:"The Call Stack",id:"the-call-stack",level:2},{value:"Limitations",id:"limitations",level:2}];function h(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,s.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"understanding-call-stacks",children:"Understanding Call Stacks"})}),"\n",(0,c.jsxs)(e.p,{children:["Users wishing to interact with a Casper network must do so through ",(0,c.jsx)(e.a,{href:"/developers/cli/sending-deploys",children:"sending a Deploy"}),". All Deploys consist of ",(0,c.jsx)(e.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"session code"})," run in the context of the user account that sent the Deploy. The session code may ",(0,c.jsx)(e.a,{href:"/developers/cli/installing-contracts",children:"install contract code to global state"}),", or interact with previously ",(0,c.jsx)(e.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"installed contract code"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["When the session code within a Deploy interacts with one or more contracts, this is the beginning of a ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-types/latest/casper_types/system/enum.CallStackElement.html",children:(0,c.jsx)(e.code,{children:"Call Stack"})}),". A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code."]}),"\n",(0,c.jsx)(e.h2,{id:"the-caller",children:"The Caller"}),"\n",(0,c.jsxs)(e.p,{children:["In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in each call stack. The account that initiated the deploy can be retrieved with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_caller.html",children:"contract_api::runtime::get_caller"})," function."]}),"\n",(0,c.jsx)(e.h2,{id:"the-call-stack",children:"The Call Stack"}),"\n",(0,c.jsxs)(e.p,{children:["Developers can access the call stack with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_call_stack.html",children:"contract_api::runtime::get_call_stack"})," function."]}),"\n",(0,c.jsxs)(e.p,{children:["If session code calls a contract, which in turn calls another contract, then the session code would represent the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in the stack, the contract called by the initiating session code would be the ",(0,c.jsx)(e.em,{children:"first"})," and the contract called by the first contract would be the ",(0,c.jsx)(e.em,{children:"second"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["In this example, the first contract would be the ",(0,c.jsx)(e.code,{children:"immediate caller"})," of the second contract, meaning it interacted directly with it. The session code would remain the ",(0,c.jsx)(e.code,{children:"caller"}),"."]}),"\n",(0,c.jsx)(e.p,{children:(0,c.jsx)(e.img,{src:n(44912).A+"",width:"1024",height:"576"})}),"\n",(0,c.jsx)(e.h2,{id:"limitations",children:"Limitations"}),"\n",(0,c.jsxs)(e.p,{children:["Casper networks place a limitation on the maximum height of a call stack. This value can be set within the ",(0,c.jsx)(e.code,{children:"chainspec"})," for the network in question. For the Casper Mainnet, this limit is set at ",(0,c.jsx)(e.code,{children:"10"})," contracts. This does not include the initiating session code, which would still count as the ",(0,c.jsx)(e.em,{children:"zeroth"})," instance within the stack."]}),"\n",(0,c.jsx)(e.p,{children:"As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation."}),"\n",(0,c.jsx)(e.admonition,{type:"note",children:(0,c.jsx)(e.p,{children:"Contract code cannot call session code, only other contract code."})})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(h,{...t})}):h(t)}},44912:(t,e,n)=>{n.d(e,{A:()=>c});const c=n.p+"assets/images/callstack-b77837c35962b1314c65801ee56f8321.png"},28453:(t,e,n)=>{n.d(e,{R:()=>a,x:()=>o});var c=n(96540);const s={},i=c.createContext(s);function a(t){const e=c.useContext(i);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:a(t.components),c.createElement(i.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a19cb34.19cbf1ee.js b/assets/js/3a19cb34.19cbf1ee.js new file mode 100644 index 000000000..7857b64c4 --- /dev/null +++ b/assets/js/3a19cb34.19cbf1ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3155],{86767:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const o={},t="C",a={id:"concepts/glossary/C",title:"C",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/C.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/C",permalink:"/2.0.0/concepts/glossary/C",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"B",permalink:"/2.0.0/concepts/glossary/B"},next:{title:"D",permalink:"/2.0.0/concepts/glossary/D"}},i={},l=[{value:"Cargo",id:"cargo",level:2},{value:"Casper network",id:"casper-network",level:2},{value:"CBC",id:"cbc",level:2},{value:"Chainspec",id:"chainspec",level:2},{value:"Consensus",id:"consensus",level:2},{value:"Contract runtime",id:"contract-runtime",level:2},{value:"Correct by construction",id:"correct-by-construction",level:2},{value:"Crate",id:"crate",level:2},{value:"CSPR",id:"cspr",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"c",children:"C"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"cargo",children:"Cargo"}),"\n",(0,r.jsx)(s.p,{children:"Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies."}),"\n",(0,r.jsx)(s.h2,{id:"casper-network",children:"Casper network"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/design/casper-design",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"cbc",children:"CBC"}),"\n",(0,r.jsx)(s.p,{children:"Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval."}),"\n",(0,r.jsx)(s.li,{children:"The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted."}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"chainspec",children:"Chainspec"}),"\n",(0,r.jsxs)(s.p,{children:["A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G#genesis",children:"genesis"}),". Here is an example ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"chainspec"}),", which will change with newer releases."]}),"\n",(0,r.jsx)(s.h2,{id:"consensus",children:"Consensus"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/design/consensus",children:"Consensus"})," is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as ",(0,r.jsx)(s.em,{children:"consensus"}),". The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer."]}),"\n",(0,r.jsx)(s.h2,{id:"contract-runtime",children:"Contract runtime"}),"\n",(0,r.jsxs)(s.p,{children:["Enables developers to use a seamless workflow for authoring and testing their ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S#smart-contract",children:"smart contracts"}),". This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices."]}),"\n",(0,r.jsx)(s.h2,{id:"correct-by-construction",children:"Correct by construction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"crate",children:"Crate"}),"\n",(0,r.jsxs)(s.p,{children:["A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, ",(0,r.jsx)(s.em,{children:"rustc"}),", the compiler for the Rust programming language, will produce a binary from a crate."]}),"\n",(0,r.jsx)(s.h2,{id:"cspr",children:"CSPR"}),"\n",(0,r.jsxs)(s.p,{children:["CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S#staking",children:"staking"})," (securing the network)."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a5d5492.554dd0cb.js b/assets/js/3a5d5492.554dd0cb.js deleted file mode 100644 index 8805f54e5..000000000 --- a/assets/js/3a5d5492.554dd0cb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5418],{63944:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>h});var t=s(74848),i=s(28453);const d={title:"Introduction",slug:"/resources/tokens/cep78/introduction"},r="CEP-78 Enhanced NFT Standard Introduction",l={id:"resources/tokens/cep78/introduction",title:"Introduction",description:"Usage",source:"@site/docs/resources/tokens/cep78/introduction.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/introduction",permalink:"/next/resources/tokens/cep78/introduction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Introduction",slug:"/resources/tokens/cep78/introduction"},sidebar:"resources",previous:{title:"Testing Guide",permalink:"/next/resources/tokens/cep18/tests"},next:{title:"CEP-78 Modalities",permalink:"/next/resources/tokens/cep78/modalities"}},c={},h=[{value:"Usage",id:"usage",level:2},{value:"Building the Contract",id:"building-the-contract",level:3},{value:"Required Runtime Arguments",id:"required-runtime-arguments",level:3},{value:"Example deploy",id:"example-deploy",level:4},{value:"Utility Session Code",id:"utility-session-code",level:3},{value:"Checking Token Ownership",id:"checking-token-ownership",level:3},{value:"Upgrading to Version 1.1.1",id:"upgrading-to-version-111",level:3},{value:"Installing and Interacting with the Contract using the Rust Casper Client",id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",level:2},{value:"Test Suite and Specification",id:"test-suite-and-specification",level:2},{value:"Error Codes",id:"error-codes",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"cep-78-enhanced-nft-standard-introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),"\n",(0,t.jsx)(e.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(e.h3,{id:"building-the-contract",children:"Building the Contract"}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"main.rs"})," file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command from the Makefile provided."]}),"\n",(0,t.jsxs)(e.p,{children:["The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command provided in the Makefile. Please note, however, that you must install ",(0,t.jsx)(e.code,{children:"wasm-strip"})," to build the contract."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"call"})," method will install the contract with the necessary entrypoints and call the ",(0,t.jsx)(e.code,{children:"init()"})," entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation."]}),"\n",(0,t.jsx)(e.h3,{id:"required-runtime-arguments",children:"Required Runtime Arguments"}),"\n",(0,t.jsxs)(e.p,{children:["The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities",children:"Modalities"})," documentation."]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_name":'})," The name of the NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_symbol"'}),": The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"total_token_supply"'}),": The total number of NFTs that a specific instance of a contract will mint passed in as a ",(0,t.jsx)(e.code,{children:"U64"})," value. This parameter is required."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"ownership_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#ownership",children:(0,t.jsx)(e.code,{children:"OwnershipMode"})})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_kind"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#nftkind",children:(0,t.jsx)(e.code,{children:"NFTKind"})})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"json_schema"'}),": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required if the metadata kind is set to ",(0,t.jsx)(e.code,{children:"CustomValidated(3)"})," and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_metadata_kind"'}),": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"identifier_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#nftidentifiermode",children:(0,t.jsx)(e.code,{children:"NFTIdentifierMode"})})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"metadata_mutability"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#metadata-mutability",children:(0,t.jsx)(e.code,{children:"MetadataMutability"})})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The following are the optional parameters that can be passed in at the time of installation."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"minting_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#minting",children:(0,t.jsx)(e.code,{children:"MintingMode"})})," modality that dictates the access to the ",(0,t.jsx)(e.code,{children:"mint()"})," entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"allow_minting"'}),": The ",(0,t.jsx)(e.code,{children:'"allow_minting"'})," flag allows the installer of the contract to pause the minting of new NFTs. The ",(0,t.jsx)(e.code,{children:"allow_minting"})," is a boolean toggle that allows minting when ",(0,t.jsx)(e.code,{children:"true"}),". If not provided at install the toggle will default to ",(0,t.jsx)(e.code,{children:"true"}),". This value can be changed by the installer by calling the ",(0,t.jsx)(e.code,{children:"set_variables()"})," entrypoint."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"whitelist_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#whitelistmode",children:(0,t.jsx)(e.code,{children:"WhitelistMode"})})," modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"holder_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#nftholdermode",children:(0,t.jsx)(e.code,{children:"NFTHolderMode"})})," modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either ",(0,t.jsx)(e.code,{children:"Accounts"})," or ",(0,t.jsx)(e.code,{children:"Contracts"})," to hold NFTs. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"contract_whitelist"'}),": The contract whitelist is a list of contract hashes that specifies which contracts can call the ",(0,t.jsx)(e.code,{children:"mint()"})," entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the ",(0,t.jsx)(e.code,{children:"set_variables"})," post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"burn_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#burnmode",children:(0,t.jsx)(e.code,{children:"BurnMode"})})," modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"owner_reverse_lookup_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#reportingmode",children:(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})})," modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"events_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/modalities#eventsmode",children:(0,t.jsx)(e.code,{children:"EventsMode"})})," modality selects the event schema used to record any changes that occur to tokens issued by the contract instance."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"additional_required_metdata"'}),": An additional metadata schema that must be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"optional_metdata"'}),": An optional metadata schema that may be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.h4,{id:"example-deploy",children:"Example deploy"}),"\n",(0,t.jsxs)(e.p,{children:["The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:'casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'enhanced-nft-1\'" \\\n--session-arg "collection_symbol:string=\'ENFT-1\'" \\\n--session-arg "total_token_supply:u64=\'10\'" \\\n--session-arg "ownership_mode:u8=\'0\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "allow_minting:bool=\'true\'" \\\n--session-arg "owner_reverse_lookup_mode:u8=\'0\'" \\\n--session-arg "nft_metadata_kind:u8=\'2\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(e.h3,{id:"utility-session-code",children:"Utility Session Code"}),"\n",(0,t.jsxs)(e.p,{children:["Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary.\nIn order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that\nusers and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the ",(0,t.jsx)(e.code,{children:"client"}),"\nfolder within the project folder."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint name"}),(0,t.jsx)(e.th,{children:"Session code"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"mint"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/mint_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"balance_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/balance_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"get_approved'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/get_approved_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"owner_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/owner_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"transfer"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/transfer_session"})})]})]})]}),"\n",(0,t.jsx)(e.h3,{id:"checking-token-ownership",children:"Checking Token Ownership"}),"\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/tutorials/token-ownership-tutorial.md",children:"Learn to check token ownership"})," starting with version ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1",children:"v1.1.1"}),". The ",(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})," modality must be set to ",(0,t.jsx)(e.code,{children:"Complete"})," as described ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"upgrading-to-version-111",children:"Upgrading to Version 1.1.1"}),"\n",(0,t.jsxs)(e.p,{children:["Upgrade to v1.1.1 using a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/standard-migration-tutorial.md",children:"Standard NamedKey Convention"})," or a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/custom-migration-tutorial.md",children:"Custom NamedKey Convention"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",children:"Installing and Interacting with the Contract using the Rust Casper Client"}),"\n",(0,t.jsxs)(e.p,{children:["You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client ",(0,t.jsx)(e.a,{href:"/next/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"test-suite-and-specification",children:"Test Suite and Specification"}),"\n",(0,t.jsxs)(e.p,{children:["The expected behavior of the NFT contract implementation is asserted by its test suite found in the ",(0,t.jsx)(e.code,{children:"tests"})," folder.\nThe test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors\nof the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite\nensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced.\nThe test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run\nby using the provided ",(0,t.jsx)(e.code,{children:"Makefile"})," and running the ",(0,t.jsx)(e.code,{children:"make test"})," command."]}),"\n",(0,t.jsx)(e.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Code"}),(0,t.jsx)(e.th,{children:"Error"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"1"}),(0,t.jsx)(e.td,{children:"InvalidAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"2"}),(0,t.jsx)(e.td,{children:"MissingInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"3"}),(0,t.jsx)(e.td,{children:"InvalidInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"4"}),(0,t.jsx)(e.td,{children:"UnexpectedKeyVariant"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"5"}),(0,t.jsx)(e.td,{children:"MissingTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"6"}),(0,t.jsx)(e.td,{children:"InvalidTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"7"}),(0,t.jsx)(e.td,{children:"FailedToGetArgBytes"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"8"}),(0,t.jsx)(e.td,{children:"FailedToCreateDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"9"}),(0,t.jsx)(e.td,{children:"MissingStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"10"}),(0,t.jsx)(e.td,{children:"InvalidStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"11"}),(0,t.jsx)(e.td,{children:"MissingOwnerUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"12"}),(0,t.jsx)(e.td,{children:"InvalidOwnersUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"13"}),(0,t.jsx)(e.td,{children:"FailedToAccessStorageDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"14"}),(0,t.jsx)(e.td,{children:"FailedToAccessOwnershipDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"15"}),(0,t.jsx)(e.td,{children:"DuplicateMinted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"16"}),(0,t.jsx)(e.td,{children:"FailedToConvertCLValue"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"17"}),(0,t.jsx)(e.td,{children:"MissingCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"18"}),(0,t.jsx)(e.td,{children:"InvalidCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"19"}),(0,t.jsx)(e.td,{children:"FailedToSerializeMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"20"}),(0,t.jsx)(e.td,{children:"MissingAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"21"}),(0,t.jsx)(e.td,{children:"MissingMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"22"}),(0,t.jsx)(e.td,{children:"InvalidMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"23"}),(0,t.jsx)(e.td,{children:"MissingCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"24"}),(0,t.jsx)(e.td,{children:"InvalidCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"25"}),(0,t.jsx)(e.td,{children:"MissingTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"26"}),(0,t.jsx)(e.td,{children:"InvalidTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"27"}),(0,t.jsx)(e.td,{children:"MissingTokenID"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"28"}),(0,t.jsx)(e.td,{children:"InvalidTokenIdentifier"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"29"}),(0,t.jsx)(e.td,{children:"MissingTokenOwners"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"30"}),(0,t.jsx)(e.td,{children:"MissingAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"31"}),(0,t.jsx)(e.td,{children:"InvalidAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"32"}),(0,t.jsx)(e.td,{children:"TokenSupplyDepleted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"33"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"34"}),(0,t.jsx)(e.td,{children:"TokenAlreadyBelongsToMinterFatal"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"35"}),(0,t.jsx)(e.td,{children:"FatalTokenIdDuplication"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"36"}),(0,t.jsx)(e.td,{children:"InvalidMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"37"}),(0,t.jsx)(e.td,{children:"MissingMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"38"}),(0,t.jsx)(e.td,{children:"InvalidMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"39"}),(0,t.jsx)(e.td,{children:"MissingInstallerKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"40"}),(0,t.jsx)(e.td,{children:"FailedToConvertToAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"41"}),(0,t.jsx)(e.td,{children:"InvalidBurner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"42"}),(0,t.jsx)(e.td,{children:"PreviouslyBurntToken"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"43"}),(0,t.jsx)(e.td,{children:"MissingAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"44"}),(0,t.jsx)(e.td,{children:"InvalidAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"45"}),(0,t.jsx)(e.td,{children:"MissingNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"46"}),(0,t.jsx)(e.td,{children:"InvalidNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"47"}),(0,t.jsx)(e.td,{children:"MissingTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"48"}),(0,t.jsx)(e.td,{children:"InvalidTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"49"}),(0,t.jsx)(e.td,{children:"MissingApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{children:"InvalidApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"51"}),(0,t.jsx)(e.td,{children:"MissingApprovedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"52"}),(0,t.jsx)(e.td,{children:"TokenAlreadyApproved"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"53"}),(0,t.jsx)(e.td,{children:"MissingApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"54"}),(0,t.jsx)(e.td,{children:"InvalidApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"55"}),(0,t.jsx)(e.td,{children:"MissingOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"56"}),(0,t.jsx)(e.td,{children:"InvalidOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"57"}),(0,t.jsx)(e.td,{children:"Phantom"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"58"}),(0,t.jsx)(e.td,{children:"ContractAlreadyInitialized"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"59"}),(0,t.jsx)(e.td,{children:"MintingIsPaused"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"60"}),(0,t.jsx)(e.td,{children:"FailureToParseAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"61"}),(0,t.jsx)(e.td,{children:"VacantValueInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"62"}),(0,t.jsx)(e.td,{children:"MissingOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"63"}),(0,t.jsx)(e.td,{children:"InvalidOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"64"}),(0,t.jsx)(e.td,{children:"InvalidTokenMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"65"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"66"}),(0,t.jsx)(e.td,{children:"InvalidAccountKeyInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"67"}),(0,t.jsx)(e.td,{children:"MissingJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"68"}),(0,t.jsx)(e.td,{children:"InvalidJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"69"}),(0,t.jsx)(e.td,{children:"InvalidKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"70"}),(0,t.jsx)(e.td,{children:"InvalidOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"71"}),(0,t.jsx)(e.td,{children:"MissingTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"72"}),(0,t.jsx)(e.td,{children:"InvalidTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"73"}),(0,t.jsx)(e.td,{children:"MissingNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"74"}),(0,t.jsx)(e.td,{children:"InvalidNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"75"}),(0,t.jsx)(e.td,{children:"MissingHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"76"}),(0,t.jsx)(e.td,{children:"InvalidHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"77"}),(0,t.jsx)(e.td,{children:"MissingWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"78"}),(0,t.jsx)(e.td,{children:"InvalidWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"79"}),(0,t.jsx)(e.td,{children:"MissingContractWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"80"}),(0,t.jsx)(e.td,{children:"InvalidContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"81"}),(0,t.jsx)(e.td,{children:"UnlistedContractHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"82"}),(0,t.jsx)(e.td,{children:"InvalidContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"83"}),(0,t.jsx)(e.td,{children:"EmptyContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"84"}),(0,t.jsx)(e.td,{children:"MissingReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"85"}),(0,t.jsx)(e.td,{children:"InvalidReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"86"}),(0,t.jsx)(e.td,{children:"InvalidJsonMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"87"}),(0,t.jsx)(e.td,{children:"InvalidJsonFormat"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"88"}),(0,t.jsx)(e.td,{children:"FailedToParseCep78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"89"}),(0,t.jsx)(e.td,{children:"FailedToParse721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"90"}),(0,t.jsx)(e.td,{children:"FailedToParseCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"91"}),(0,t.jsx)(e.td,{children:"InvalidCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"92"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"93"}),(0,t.jsx)(e.td,{children:"InvalidNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"94"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"95"}),(0,t.jsx)(e.td,{children:"InvalidCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"96"}),(0,t.jsx)(e.td,{children:"MissingNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"97"}),(0,t.jsx)(e.td,{children:"InvalidNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"98"}),(0,t.jsx)(e.td,{children:"MissingIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"99"}),(0,t.jsx)(e.td,{children:"InvalidIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"100"}),(0,t.jsx)(e.td,{children:"FailedToParseTokenId"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"101"}),(0,t.jsx)(e.td,{children:"MissingMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"102"}),(0,t.jsx)(e.td,{children:"InvalidMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"103"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"104"}),(0,t.jsx)(e.td,{children:"ForbiddenMetadataUpdate"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"105"}),(0,t.jsx)(e.td,{children:"MissingBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"106"}),(0,t.jsx)(e.td,{children:"InvalidBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"107"}),(0,t.jsx)(e.td,{children:"MissingHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"108"}),(0,t.jsx)(e.td,{children:"InvalidHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"109"}),(0,t.jsx)(e.td,{children:"MissingIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"110"}),(0,t.jsx)(e.td,{children:"InvalidIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"111"}),(0,t.jsx)(e.td,{children:"MissingPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"112"}),(0,t.jsx)(e.td,{children:"InvalidPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"113"}),(0,t.jsx)(e.td,{children:"MissingPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"114"}),(0,t.jsx)(e.td,{children:"InvalidPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"115"}),(0,t.jsx)(e.td,{children:"InvalidPageNumber"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"116"}),(0,t.jsx)(e.td,{children:"InvalidPageIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"117"}),(0,t.jsx)(e.td,{children:"MissingUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"118"}),(0,t.jsx)(e.td,{children:"InvalidUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"119"}),(0,t.jsx)(e.td,{children:"MissingPackageHashForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"120"}),(0,t.jsx)(e.td,{children:"MissingPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"121"}),(0,t.jsx)(e.td,{children:"InvalidPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"122"}),(0,t.jsx)(e.td,{children:"CannotUpgradeWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"123"}),(0,t.jsx)(e.td,{children:"CannotInstallWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"124"}),(0,t.jsx)(e.td,{children:"MissingMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"125"}),(0,t.jsx)(e.td,{children:"InvalidMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"126"}),(0,t.jsx)(e.td,{children:"ContractAlreadyMigrated"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"127"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInMint"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"128"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInTransfer"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"129"}),(0,t.jsx)(e.td,{children:"MissingReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"130"}),(0,t.jsx)(e.td,{children:"InvalidReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"131"}),(0,t.jsx)(e.td,{children:"MissingPage"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"132"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerFromMigration"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"133"}),(0,t.jsx)(e.td,{children:"ExceededMaxTotalSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"134"}),(0,t.jsx)(e.td,{children:"MissingCep78PackageHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"135"}),(0,t.jsx)(e.td,{children:"InvalidCep78InvalidHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"136"}),(0,t.jsx)(e.td,{children:"InvalidPackageHashName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"137"}),(0,t.jsx)(e.td,{children:"InvalidAccessKeyName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"138"}),(0,t.jsx)(e.td,{children:"InvalidCheckForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"139"}),(0,t.jsx)(e.td,{children:"InvalidNamedKeyConvention"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"140"}),(0,t.jsx)(e.td,{children:"OwnerReverseLookupModeNotTransferable"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"141"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalRequiredMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"142"}),(0,t.jsx)(e.td,{children:"InvalidOptionalMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"143"}),(0,t.jsx)(e.td,{children:"MissingOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"144"}),(0,t.jsx)(e.td,{children:"InvalidOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"145"}),(0,t.jsx)(e.td,{children:"MissingAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"146"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"147"}),(0,t.jsx)(e.td,{children:"InvalidRequirement"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"148"}),(0,t.jsx)(e.td,{children:"MissingEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"149"}),(0,t.jsx)(e.td,{children:"InvalidEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"150"}),(0,t.jsx)(e.td,{children:"CannotUpgradeToMoreSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"151"}),(0,t.jsx)(e.td,{children:"MissingOperatorDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"152"}),(0,t.jsx)(e.td,{children:"MissingApprovedDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"153"}),(0,t.jsx)(e.td,{children:"MissingSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"154"}),(0,t.jsx)(e.td,{children:"InvalidSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"155"}),(0,t.jsx)(e.td,{children:"MissingOwnerTokenIdentifierKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"156"}),(0,t.jsx)(e.td,{children:"InvalidTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"157"}),(0,t.jsx)(e.td,{children:"MissingTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"158"}),(0,t.jsx)(e.td,{children:"TransferFilterContractNeedsTransferableMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"159"}),(0,t.jsx)(e.td,{children:"TransferFilterContractDenied"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"160"}),(0,t.jsx)(e.td,{children:"MissingACLWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"161"}),(0,t.jsx)(e.td,{children:"InvalidACLWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"162"}),(0,t.jsx)(e.td,{children:"EmptyACLWhitelist"})]})]})]})]})}function o(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>r,x:()=>l});var t=s(96540);const i={},d=t.createContext(i);function r(n){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function l(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(i):n.components||i:r(n.components),t.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a5d5492.d650666a.js b/assets/js/3a5d5492.d650666a.js new file mode 100644 index 000000000..32d070a47 --- /dev/null +++ b/assets/js/3a5d5492.d650666a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75418],{63944:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>h});var t=s(74848),i=s(28453);const d={title:"Introduction",slug:"/resources/tokens/cep78/introduction"},r="CEP-78 Enhanced NFT Standard Introduction",l={id:"resources/tokens/cep78/introduction",title:"Introduction",description:"Usage",source:"@site/docs/resources/tokens/cep78/introduction.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/introduction",permalink:"/resources/tokens/cep78/introduction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Introduction",slug:"/resources/tokens/cep78/introduction"},sidebar:"resources",previous:{title:"Testing Guide",permalink:"/resources/tokens/cep18/tests"},next:{title:"CEP-78 Modalities",permalink:"/resources/tokens/cep78/modalities"}},c={},h=[{value:"Usage",id:"usage",level:2},{value:"Building the Contract",id:"building-the-contract",level:3},{value:"Required Runtime Arguments",id:"required-runtime-arguments",level:3},{value:"Example deploy",id:"example-deploy",level:4},{value:"Utility Session Code",id:"utility-session-code",level:3},{value:"Checking Token Ownership",id:"checking-token-ownership",level:3},{value:"Upgrading to Version 1.1.1",id:"upgrading-to-version-111",level:3},{value:"Installing and Interacting with the Contract using the Rust Casper Client",id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",level:2},{value:"Test Suite and Specification",id:"test-suite-and-specification",level:2},{value:"Error Codes",id:"error-codes",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"cep-78-enhanced-nft-standard-introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),"\n",(0,t.jsx)(e.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(e.h3,{id:"building-the-contract",children:"Building the Contract"}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"main.rs"})," file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command from the Makefile provided."]}),"\n",(0,t.jsxs)(e.p,{children:["The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command provided in the Makefile. Please note, however, that you must install ",(0,t.jsx)(e.code,{children:"wasm-strip"})," to build the contract."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"call"})," method will install the contract with the necessary entrypoints and call the ",(0,t.jsx)(e.code,{children:"init()"})," entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation."]}),"\n",(0,t.jsx)(e.h3,{id:"required-runtime-arguments",children:"Required Runtime Arguments"}),"\n",(0,t.jsxs)(e.p,{children:["The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities",children:"Modalities"})," documentation."]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_name":'})," The name of the NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_symbol"'}),": The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"total_token_supply"'}),": The total number of NFTs that a specific instance of a contract will mint passed in as a ",(0,t.jsx)(e.code,{children:"U64"})," value. This parameter is required."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"ownership_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#ownership",children:(0,t.jsx)(e.code,{children:"OwnershipMode"})})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_kind"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftkind",children:(0,t.jsx)(e.code,{children:"NFTKind"})})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"json_schema"'}),": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required if the metadata kind is set to ",(0,t.jsx)(e.code,{children:"CustomValidated(3)"})," and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_metadata_kind"'}),": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"identifier_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftidentifiermode",children:(0,t.jsx)(e.code,{children:"NFTIdentifierMode"})})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"metadata_mutability"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#metadata-mutability",children:(0,t.jsx)(e.code,{children:"MetadataMutability"})})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The following are the optional parameters that can be passed in at the time of installation."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"minting_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#minting",children:(0,t.jsx)(e.code,{children:"MintingMode"})})," modality that dictates the access to the ",(0,t.jsx)(e.code,{children:"mint()"})," entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"allow_minting"'}),": The ",(0,t.jsx)(e.code,{children:'"allow_minting"'})," flag allows the installer of the contract to pause the minting of new NFTs. The ",(0,t.jsx)(e.code,{children:"allow_minting"})," is a boolean toggle that allows minting when ",(0,t.jsx)(e.code,{children:"true"}),". If not provided at install the toggle will default to ",(0,t.jsx)(e.code,{children:"true"}),". This value can be changed by the installer by calling the ",(0,t.jsx)(e.code,{children:"set_variables()"})," entrypoint."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"whitelist_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#whitelistmode",children:(0,t.jsx)(e.code,{children:"WhitelistMode"})})," modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"holder_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftholdermode",children:(0,t.jsx)(e.code,{children:"NFTHolderMode"})})," modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either ",(0,t.jsx)(e.code,{children:"Accounts"})," or ",(0,t.jsx)(e.code,{children:"Contracts"})," to hold NFTs. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"contract_whitelist"'}),": The contract whitelist is a list of contract hashes that specifies which contracts can call the ",(0,t.jsx)(e.code,{children:"mint()"})," entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the ",(0,t.jsx)(e.code,{children:"set_variables"})," post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"burn_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#burnmode",children:(0,t.jsx)(e.code,{children:"BurnMode"})})," modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"owner_reverse_lookup_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#reportingmode",children:(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})})," modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"events_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#eventsmode",children:(0,t.jsx)(e.code,{children:"EventsMode"})})," modality selects the event schema used to record any changes that occur to tokens issued by the contract instance."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"additional_required_metdata"'}),": An additional metadata schema that must be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"optional_metdata"'}),": An optional metadata schema that may be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.h4,{id:"example-deploy",children:"Example deploy"}),"\n",(0,t.jsxs)(e.p,{children:["The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples ",(0,t.jsx)(e.a,{href:"/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:'casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'enhanced-nft-1\'" \\\n--session-arg "collection_symbol:string=\'ENFT-1\'" \\\n--session-arg "total_token_supply:u64=\'10\'" \\\n--session-arg "ownership_mode:u8=\'0\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "allow_minting:bool=\'true\'" \\\n--session-arg "owner_reverse_lookup_mode:u8=\'0\'" \\\n--session-arg "nft_metadata_kind:u8=\'2\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(e.h3,{id:"utility-session-code",children:"Utility Session Code"}),"\n",(0,t.jsxs)(e.p,{children:["Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary.\nIn order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that\nusers and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the ",(0,t.jsx)(e.code,{children:"client"}),"\nfolder within the project folder."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint name"}),(0,t.jsx)(e.th,{children:"Session code"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"mint"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/mint_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"balance_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/balance_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"get_approved'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/get_approved_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"owner_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/owner_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"transfer"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/transfer_session"})})]})]})]}),"\n",(0,t.jsx)(e.h3,{id:"checking-token-ownership",children:"Checking Token Ownership"}),"\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/tutorials/token-ownership-tutorial.md",children:"Learn to check token ownership"})," starting with version ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1",children:"v1.1.1"}),". The ",(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})," modality must be set to ",(0,t.jsx)(e.code,{children:"Complete"})," as described ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"upgrading-to-version-111",children:"Upgrading to Version 1.1.1"}),"\n",(0,t.jsxs)(e.p,{children:["Upgrade to v1.1.1 using a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/standard-migration-tutorial.md",children:"Standard NamedKey Convention"})," or a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/custom-migration-tutorial.md",children:"Custom NamedKey Convention"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",children:"Installing and Interacting with the Contract using the Rust Casper Client"}),"\n",(0,t.jsxs)(e.p,{children:["You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client ",(0,t.jsx)(e.a,{href:"/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"test-suite-and-specification",children:"Test Suite and Specification"}),"\n",(0,t.jsxs)(e.p,{children:["The expected behavior of the NFT contract implementation is asserted by its test suite found in the ",(0,t.jsx)(e.code,{children:"tests"})," folder.\nThe test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors\nof the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite\nensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced.\nThe test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run\nby using the provided ",(0,t.jsx)(e.code,{children:"Makefile"})," and running the ",(0,t.jsx)(e.code,{children:"make test"})," command."]}),"\n",(0,t.jsx)(e.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Code"}),(0,t.jsx)(e.th,{children:"Error"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"1"}),(0,t.jsx)(e.td,{children:"InvalidAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"2"}),(0,t.jsx)(e.td,{children:"MissingInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"3"}),(0,t.jsx)(e.td,{children:"InvalidInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"4"}),(0,t.jsx)(e.td,{children:"UnexpectedKeyVariant"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"5"}),(0,t.jsx)(e.td,{children:"MissingTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"6"}),(0,t.jsx)(e.td,{children:"InvalidTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"7"}),(0,t.jsx)(e.td,{children:"FailedToGetArgBytes"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"8"}),(0,t.jsx)(e.td,{children:"FailedToCreateDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"9"}),(0,t.jsx)(e.td,{children:"MissingStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"10"}),(0,t.jsx)(e.td,{children:"InvalidStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"11"}),(0,t.jsx)(e.td,{children:"MissingOwnerUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"12"}),(0,t.jsx)(e.td,{children:"InvalidOwnersUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"13"}),(0,t.jsx)(e.td,{children:"FailedToAccessStorageDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"14"}),(0,t.jsx)(e.td,{children:"FailedToAccessOwnershipDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"15"}),(0,t.jsx)(e.td,{children:"DuplicateMinted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"16"}),(0,t.jsx)(e.td,{children:"FailedToConvertCLValue"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"17"}),(0,t.jsx)(e.td,{children:"MissingCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"18"}),(0,t.jsx)(e.td,{children:"InvalidCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"19"}),(0,t.jsx)(e.td,{children:"FailedToSerializeMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"20"}),(0,t.jsx)(e.td,{children:"MissingAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"21"}),(0,t.jsx)(e.td,{children:"MissingMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"22"}),(0,t.jsx)(e.td,{children:"InvalidMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"23"}),(0,t.jsx)(e.td,{children:"MissingCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"24"}),(0,t.jsx)(e.td,{children:"InvalidCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"25"}),(0,t.jsx)(e.td,{children:"MissingTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"26"}),(0,t.jsx)(e.td,{children:"InvalidTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"27"}),(0,t.jsx)(e.td,{children:"MissingTokenID"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"28"}),(0,t.jsx)(e.td,{children:"InvalidTokenIdentifier"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"29"}),(0,t.jsx)(e.td,{children:"MissingTokenOwners"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"30"}),(0,t.jsx)(e.td,{children:"MissingAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"31"}),(0,t.jsx)(e.td,{children:"InvalidAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"32"}),(0,t.jsx)(e.td,{children:"TokenSupplyDepleted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"33"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"34"}),(0,t.jsx)(e.td,{children:"TokenAlreadyBelongsToMinterFatal"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"35"}),(0,t.jsx)(e.td,{children:"FatalTokenIdDuplication"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"36"}),(0,t.jsx)(e.td,{children:"InvalidMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"37"}),(0,t.jsx)(e.td,{children:"MissingMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"38"}),(0,t.jsx)(e.td,{children:"InvalidMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"39"}),(0,t.jsx)(e.td,{children:"MissingInstallerKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"40"}),(0,t.jsx)(e.td,{children:"FailedToConvertToAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"41"}),(0,t.jsx)(e.td,{children:"InvalidBurner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"42"}),(0,t.jsx)(e.td,{children:"PreviouslyBurntToken"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"43"}),(0,t.jsx)(e.td,{children:"MissingAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"44"}),(0,t.jsx)(e.td,{children:"InvalidAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"45"}),(0,t.jsx)(e.td,{children:"MissingNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"46"}),(0,t.jsx)(e.td,{children:"InvalidNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"47"}),(0,t.jsx)(e.td,{children:"MissingTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"48"}),(0,t.jsx)(e.td,{children:"InvalidTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"49"}),(0,t.jsx)(e.td,{children:"MissingApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{children:"InvalidApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"51"}),(0,t.jsx)(e.td,{children:"MissingApprovedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"52"}),(0,t.jsx)(e.td,{children:"TokenAlreadyApproved"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"53"}),(0,t.jsx)(e.td,{children:"MissingApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"54"}),(0,t.jsx)(e.td,{children:"InvalidApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"55"}),(0,t.jsx)(e.td,{children:"MissingOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"56"}),(0,t.jsx)(e.td,{children:"InvalidOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"57"}),(0,t.jsx)(e.td,{children:"Phantom"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"58"}),(0,t.jsx)(e.td,{children:"ContractAlreadyInitialized"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"59"}),(0,t.jsx)(e.td,{children:"MintingIsPaused"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"60"}),(0,t.jsx)(e.td,{children:"FailureToParseAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"61"}),(0,t.jsx)(e.td,{children:"VacantValueInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"62"}),(0,t.jsx)(e.td,{children:"MissingOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"63"}),(0,t.jsx)(e.td,{children:"InvalidOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"64"}),(0,t.jsx)(e.td,{children:"InvalidTokenMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"65"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"66"}),(0,t.jsx)(e.td,{children:"InvalidAccountKeyInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"67"}),(0,t.jsx)(e.td,{children:"MissingJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"68"}),(0,t.jsx)(e.td,{children:"InvalidJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"69"}),(0,t.jsx)(e.td,{children:"InvalidKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"70"}),(0,t.jsx)(e.td,{children:"InvalidOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"71"}),(0,t.jsx)(e.td,{children:"MissingTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"72"}),(0,t.jsx)(e.td,{children:"InvalidTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"73"}),(0,t.jsx)(e.td,{children:"MissingNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"74"}),(0,t.jsx)(e.td,{children:"InvalidNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"75"}),(0,t.jsx)(e.td,{children:"MissingHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"76"}),(0,t.jsx)(e.td,{children:"InvalidHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"77"}),(0,t.jsx)(e.td,{children:"MissingWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"78"}),(0,t.jsx)(e.td,{children:"InvalidWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"79"}),(0,t.jsx)(e.td,{children:"MissingContractWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"80"}),(0,t.jsx)(e.td,{children:"InvalidContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"81"}),(0,t.jsx)(e.td,{children:"UnlistedContractHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"82"}),(0,t.jsx)(e.td,{children:"InvalidContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"83"}),(0,t.jsx)(e.td,{children:"EmptyContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"84"}),(0,t.jsx)(e.td,{children:"MissingReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"85"}),(0,t.jsx)(e.td,{children:"InvalidReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"86"}),(0,t.jsx)(e.td,{children:"InvalidJsonMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"87"}),(0,t.jsx)(e.td,{children:"InvalidJsonFormat"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"88"}),(0,t.jsx)(e.td,{children:"FailedToParseCep78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"89"}),(0,t.jsx)(e.td,{children:"FailedToParse721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"90"}),(0,t.jsx)(e.td,{children:"FailedToParseCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"91"}),(0,t.jsx)(e.td,{children:"InvalidCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"92"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"93"}),(0,t.jsx)(e.td,{children:"InvalidNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"94"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"95"}),(0,t.jsx)(e.td,{children:"InvalidCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"96"}),(0,t.jsx)(e.td,{children:"MissingNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"97"}),(0,t.jsx)(e.td,{children:"InvalidNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"98"}),(0,t.jsx)(e.td,{children:"MissingIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"99"}),(0,t.jsx)(e.td,{children:"InvalidIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"100"}),(0,t.jsx)(e.td,{children:"FailedToParseTokenId"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"101"}),(0,t.jsx)(e.td,{children:"MissingMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"102"}),(0,t.jsx)(e.td,{children:"InvalidMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"103"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"104"}),(0,t.jsx)(e.td,{children:"ForbiddenMetadataUpdate"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"105"}),(0,t.jsx)(e.td,{children:"MissingBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"106"}),(0,t.jsx)(e.td,{children:"InvalidBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"107"}),(0,t.jsx)(e.td,{children:"MissingHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"108"}),(0,t.jsx)(e.td,{children:"InvalidHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"109"}),(0,t.jsx)(e.td,{children:"MissingIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"110"}),(0,t.jsx)(e.td,{children:"InvalidIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"111"}),(0,t.jsx)(e.td,{children:"MissingPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"112"}),(0,t.jsx)(e.td,{children:"InvalidPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"113"}),(0,t.jsx)(e.td,{children:"MissingPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"114"}),(0,t.jsx)(e.td,{children:"InvalidPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"115"}),(0,t.jsx)(e.td,{children:"InvalidPageNumber"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"116"}),(0,t.jsx)(e.td,{children:"InvalidPageIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"117"}),(0,t.jsx)(e.td,{children:"MissingUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"118"}),(0,t.jsx)(e.td,{children:"InvalidUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"119"}),(0,t.jsx)(e.td,{children:"MissingPackageHashForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"120"}),(0,t.jsx)(e.td,{children:"MissingPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"121"}),(0,t.jsx)(e.td,{children:"InvalidPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"122"}),(0,t.jsx)(e.td,{children:"CannotUpgradeWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"123"}),(0,t.jsx)(e.td,{children:"CannotInstallWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"124"}),(0,t.jsx)(e.td,{children:"MissingMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"125"}),(0,t.jsx)(e.td,{children:"InvalidMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"126"}),(0,t.jsx)(e.td,{children:"ContractAlreadyMigrated"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"127"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInMint"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"128"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInTransfer"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"129"}),(0,t.jsx)(e.td,{children:"MissingReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"130"}),(0,t.jsx)(e.td,{children:"InvalidReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"131"}),(0,t.jsx)(e.td,{children:"MissingPage"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"132"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerFromMigration"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"133"}),(0,t.jsx)(e.td,{children:"ExceededMaxTotalSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"134"}),(0,t.jsx)(e.td,{children:"MissingCep78PackageHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"135"}),(0,t.jsx)(e.td,{children:"InvalidCep78InvalidHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"136"}),(0,t.jsx)(e.td,{children:"InvalidPackageHashName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"137"}),(0,t.jsx)(e.td,{children:"InvalidAccessKeyName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"138"}),(0,t.jsx)(e.td,{children:"InvalidCheckForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"139"}),(0,t.jsx)(e.td,{children:"InvalidNamedKeyConvention"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"140"}),(0,t.jsx)(e.td,{children:"OwnerReverseLookupModeNotTransferable"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"141"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalRequiredMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"142"}),(0,t.jsx)(e.td,{children:"InvalidOptionalMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"143"}),(0,t.jsx)(e.td,{children:"MissingOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"144"}),(0,t.jsx)(e.td,{children:"InvalidOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"145"}),(0,t.jsx)(e.td,{children:"MissingAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"146"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"147"}),(0,t.jsx)(e.td,{children:"InvalidRequirement"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"148"}),(0,t.jsx)(e.td,{children:"MissingEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"149"}),(0,t.jsx)(e.td,{children:"InvalidEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"150"}),(0,t.jsx)(e.td,{children:"CannotUpgradeToMoreSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"151"}),(0,t.jsx)(e.td,{children:"MissingOperatorDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"152"}),(0,t.jsx)(e.td,{children:"MissingApprovedDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"153"}),(0,t.jsx)(e.td,{children:"MissingSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"154"}),(0,t.jsx)(e.td,{children:"InvalidSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"155"}),(0,t.jsx)(e.td,{children:"MissingOwnerTokenIdentifierKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"156"}),(0,t.jsx)(e.td,{children:"InvalidTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"157"}),(0,t.jsx)(e.td,{children:"MissingTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"158"}),(0,t.jsx)(e.td,{children:"TransferFilterContractNeedsTransferableMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"159"}),(0,t.jsx)(e.td,{children:"TransferFilterContractDenied"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"160"}),(0,t.jsx)(e.td,{children:"MissingACLWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"161"}),(0,t.jsx)(e.td,{children:"InvalidACLWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"162"}),(0,t.jsx)(e.td,{children:"EmptyACLWhitelist"})]})]})]})]})}function o(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>r,x:()=>l});var t=s(96540);const i={},d=t.createContext(i);function r(n){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function l(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(i):n.components||i:r(n.components),t.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a98aaad.38c11bd1.js b/assets/js/3a98aaad.38c11bd1.js new file mode 100644 index 000000000..8a653777c --- /dev/null +++ b/assets/js/3a98aaad.38c11bd1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28801],{56901:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=t(74848),o=t(28453);const s={title:"Overview",slug:"/operators"},i="Operators Overview",a={id:"operators/index",title:"Overview",description:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.",source:"@site/versioned_docs/version-2.0.0/operators/index.md",sourceDirName:"operators",slug:"/operators",permalink:"/2.0.0/operators",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Overview",slug:"/operators"},sidebar:"operators",next:{title:"Setting up a Node",permalink:"/2.0.0/operators/setup/"}},d={},c=[];function h(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"operators-overview",children:"Operators Overview"})}),"\n",(0,r.jsx)(n.p,{children:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section."}),"\n",(0,r.jsxs)(n.p,{children:["Prior knowledge of Unix-based operating systems and proficiency with ",(0,r.jsx)(n.code,{children:"systemd"})," and ",(0,r.jsx)(n.code,{children:"bash"})," scripting are recommended. If you are unfamiliar with ",(0,r.jsx)(n.code,{children:"systemd"}),", the ",(0,r.jsx)(n.a,{href:"https://wiki.archlinux.org/title/systemd",children:"Arch Linux page on systemd"})," is a good introduction."]}),"\n",(0,r.jsxs)(n.p,{children:["Operators should know the ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/hardware",children:"hardware requirements"})," before running a node."]}),"\n",(0,r.jsxs)(n.p,{children:["Also, the ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node#network-requirements",children:"network requirements"})," specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes."]}),"\n",(0,r.jsxs)(n.p,{children:["Review the ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration",children:"node's configuration"})," first. Then, you can follow the node ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node",children:"installation instructions"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/",children:"Node Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/",children:"Becoming a Validator"})}),(0,r.jsx)(n.td,{children:"How to join a network and become a validator"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup-network/",children:"Private Network Setup"})}),(0,r.jsx)(n.td,{children:"How to set up a private Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/maintenance/",children:"Maintenance"})}),(0,r.jsx)(n.td,{children:"Topics related to node maintenance"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function i(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a9d2720.81ccdd66.js b/assets/js/3a9d2720.81ccdd66.js new file mode 100644 index 000000000..5cda1fdb2 --- /dev/null +++ b/assets/js/3a9d2720.81ccdd66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[23127],{52886:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=a(74848),o=a(28453);const r={title:"Inactive and Faulty Nodes"},i="Inactive vs. Faulty Validator Nodes",s={id:"operators/becoming-a-validator/inactive-vs-faulty",title:"Inactive and Faulty Nodes",description:"This page describes the differences between a validator node being considered inactive or faulty.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/inactive-vs-faulty.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/inactive-vs-faulty",permalink:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Inactive and Faulty Nodes"},sidebar:"operators",previous:{title:"Recovery",permalink:"/1.5.X/operators/becoming-a-validator/recovering"},next:{title:"Setting up Private Networks",permalink:"/1.5.X/operators/setup-network/"}},l={},d=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"inactive-vs-faulty-validator-nodes",children:"Inactive vs. Faulty Validator Nodes"})}),"\n",(0,n.jsx)(t.p,{children:"This page describes the differences between a validator node being considered inactive or faulty."}),"\n",(0,n.jsxs)(t.p,{children:["In the last block of each era ",(0,n.jsx)(t.em,{children:"N"}),", the consensus algorithm checks whether there are ",(0,n.jsx)(t.em,{children:"any"})," messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as ",(0,n.jsx)(t.strong,{children:"inactive"})," in that block."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as ",(0,n.jsx)(t.strong,{children:"faulty"})," in that block. Usually, that means:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"inactive"}),", your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed."]}),"\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"faulty"}),", you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era ",(0,n.jsx)(t.em,{children:"N"}),". The auction determines the validator set for the era after the next (because ",(0,n.jsx)(t.code,{children:"auction_delay"})," is set to ",(0,n.jsx)(t.code,{children:"1"})," on mainnet), i.e., for era ",(0,n.jsx)(t.em,{children:"N + 2"}),". That means you will still be a validator (with a weight proportional to your stake) in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),", but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder."]}),"\n",(0,n.jsxs)(t.p,{children:["And even in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),":"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era ",(0,n.jsx)(t.em,{children:"N + 1"}),", it will get evicted for being offline in era ",(0,n.jsx)(t.em,{children:"N"}),"."]}),"\n",(0,n.jsx)(t.li,{children:"If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["In both cases, you remain evicted until you reactivate your bid, as described ",(0,n.jsx)(t.a,{href:"/1.5.X/operators/becoming-a-validator/recovering",children:"here"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>s});var n=a(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3a9d2720.e34e9dc9.js b/assets/js/3a9d2720.e34e9dc9.js deleted file mode 100644 index f69f46c3f..000000000 --- a/assets/js/3a9d2720.e34e9dc9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3127],{52886:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=a(74848),o=a(28453);const r={title:"Inactive and Faulty Nodes"},i="Inactive vs. Faulty Validator Nodes",s={id:"operators/becoming-a-validator/inactive-vs-faulty",title:"Inactive and Faulty Nodes",description:"This page describes the differences between a validator node being considered inactive or faulty.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/inactive-vs-faulty.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/inactive-vs-faulty",permalink:"/operators/becoming-a-validator/inactive-vs-faulty",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Inactive and Faulty Nodes"},sidebar:"operators",previous:{title:"Recovery",permalink:"/operators/becoming-a-validator/recovering"},next:{title:"Setting up Private Networks",permalink:"/operators/setup-network/"}},l={},d=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"inactive-vs-faulty-validator-nodes",children:"Inactive vs. Faulty Validator Nodes"})}),"\n",(0,n.jsx)(t.p,{children:"This page describes the differences between a validator node being considered inactive or faulty."}),"\n",(0,n.jsxs)(t.p,{children:["In the last block of each era ",(0,n.jsx)(t.em,{children:"N"}),", the consensus algorithm checks whether there are ",(0,n.jsx)(t.em,{children:"any"})," messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as ",(0,n.jsx)(t.strong,{children:"inactive"})," in that block."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as ",(0,n.jsx)(t.strong,{children:"faulty"})," in that block. Usually, that means:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"inactive"}),", your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed."]}),"\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"faulty"}),", you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era ",(0,n.jsx)(t.em,{children:"N"}),". The auction determines the validator set for the era after the next (because ",(0,n.jsx)(t.code,{children:"auction_delay"})," is set to ",(0,n.jsx)(t.code,{children:"1"})," on mainnet), i.e., for era ",(0,n.jsx)(t.em,{children:"N + 2"}),". That means you will still be a validator (with a weight proportional to your stake) in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),", but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder."]}),"\n",(0,n.jsxs)(t.p,{children:["And even in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),":"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era ",(0,n.jsx)(t.em,{children:"N + 1"}),", it will get evicted for being offline in era ",(0,n.jsx)(t.em,{children:"N"}),"."]}),"\n",(0,n.jsx)(t.li,{children:"If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["In both cases, you remain evicted until you reactivate your bid, as described ",(0,n.jsx)(t.a,{href:"/operators/becoming-a-validator/recovering",children:"here"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>s});var n=a(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3aa29420.3264772a.js b/assets/js/3aa29420.3264772a.js new file mode 100644 index 000000000..8931b7ff0 --- /dev/null +++ b/assets/js/3aa29420.3264772a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[81515],{28510:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>l,toc:()=>i});var n=s(74848),c=s(28453);const t={},a="B",l={id:"concepts/glossary/B",title:"B",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/B.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/B",permalink:"/1.5.X/concepts/glossary/B",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"A",permalink:"/1.5.X/concepts/glossary/A"},next:{title:"C",permalink:"/1.5.X/concepts/glossary/C"}},r={},i=[{value:"Blake2b",id:"blake2b",level:2},{value:"Block",id:"block",level:2},{value:"Block creation",id:"block-creation",level:2},{value:"Block finality",id:"block-finality",level:2},{value:"Block gossiping",id:"block-gossiping",level:2},{value:"Block height",id:"block-height",level:2},{value:"Block passing",id:"block-passing",level:2},{value:"Block processing",id:"block-processing",level:2},{value:"Block proposal",id:"block-proposal",level:2},{value:"Block validation",id:"block-validation",level:2},{value:"Blockchain",id:"blockchain",level:2},{value:"Block store",id:"block-store",level:2},{value:"Bond",id:"bond",level:2},{value:"Bonding",id:"bonding",level:2},{value:"Booking block",id:"booking-block",level:2}];function h(e){const o={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"b",children:"B"})}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsxs)(o.p,{children:[(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsx)(o.h2,{id:"blake2b",children:"Blake2b"}),"\n",(0,n.jsxs)(o.p,{children:["A function used within the Casper platform to create cryptographic ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/H#hash",children:"hashes"}),". More information can be found ",(0,n.jsx)(o.a,{href:"https://www.blake2.net/",children:"here"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block",children:"Block"}),"\n",(0,n.jsx)(o.p,{children:"Used in two contexts:"}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,n.jsx)(o.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,n.jsx)(o.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,n.jsx)(o.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,n.jsx)(o.h2,{id:"block-creation",children:"Block creation"}),"\n",(0,n.jsxs)(o.p,{children:["Block creation means computing the deployment results and collecting the results that belong together into a block. We follow a process called ",(0,n.jsx)(o.em,{children:"execution after consensus"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["The ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/B#block-proposal",children:"block proposal"})," happens first, and the proposed ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/P#proto-block",children:"proto block"})," contains a set of deploys that have not been executed yet."]}),"\n",(0,n.jsxs)(o.p,{children:["Only after consensus on a ",(0,n.jsx)(o.em,{children:"proto block"})," has been reached, the deploys are executed. The resulting new global state ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/R#root-hash",children:"root hash"})," is put into an actual block, together with the executed deploys."]}),"\n",(0,n.jsx)(o.p,{children:"Note that only validators can create valid blocks."}),"\n",(0,n.jsx)(o.h2,{id:"block-finality",children:"Block finality"}),"\n",(0,n.jsx)(o.p,{children:'A block is "finalized" if the validators agree on adding it to the blockchain.'}),"\n",(0,n.jsxs)(o.p,{children:["There are different levels of ",(0,n.jsx)(o.em,{children:"finality"})," in the ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/H#highway",children:"Highway"})," protocol. A finalized block has a fault-tolerance ",(0,n.jsx)(o.em,{children:"F"}),", expressed as a fraction of the total stake. For an observer to see a conflicting block as finalized, several validators whose total stake exceeds ",(0,n.jsx)(o.em,{children:"F"})," would have to collude and show different information in a way that would ultimately be detected and punished (see ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/S#slashing",children:"slashing"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"block-gossiping",children:"Block gossiping"}),"\n",(0,n.jsxs)(o.p,{children:["Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms ",(0,n.jsx)(o.em,{children:"block gossiping"})," and ",(0,n.jsx)(o.a,{href:"#block-passing",children:"block passing"})," are interchangeable."]}),"\n",(0,n.jsx)(o.h2,{id:"block-height",children:"Block height"}),"\n",(0,n.jsx)(o.p,{children:"Block height is an identifier for a given block based on the number of blocks completed prior to that block."}),"\n",(0,n.jsx)(o.h2,{id:"block-passing",children:"Block passing"}),"\n",(0,n.jsxs)(o.p,{children:["See ",(0,n.jsx)(o.a,{href:"#block-gossiping",children:"block gossiping"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-processing",children:"Block processing"}),"\n",(0,n.jsxs)(o.p,{children:["Block processing consists of running the deploys in a block received from another node to determine updates to the global state. Note that this is an essential part of ",(0,n.jsx)(o.a,{href:"#block-validation",children:"validating blocks"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-proposal",children:"Block proposal"}),"\n",(0,n.jsx)(o.p,{children:"Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only."}),"\n",(0,n.jsx)(o.h2,{id:"block-validation",children:"Block validation"}),"\n",(0,n.jsx)(o.p,{children:"The process of determining the validity of a block obtained from another node on the network."}),"\n",(0,n.jsx)(o.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,n.jsxs)(o.p,{children:["Blockchain is a P2P network where the collection of nodes (",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validators"}),") concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/T#transaction",children:"transactions"}),". For performance reasons, transactions are bundled in ",(0,n.jsx)(o.a,{href:"#block",children:"blocks"}),". According to a particular cooperation protocol (consensus protocol), the collection of ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/N#node",children:"nodes"})," connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"})," and has a sizeable map-like collection."]}),"\n",(0,n.jsx)(o.h2,{id:"block-store",children:"Block store"}),"\n",(0,n.jsx)(o.p,{children:"The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash."}),"\n",(0,n.jsx)(o.h2,{id:"bond",children:"Bond"}),"\n",(0,n.jsxs)(o.p,{children:["The amount of money (in crypto-currency) that is allocated by a node in order to participate in ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/C#consensus",children:"consensus"})," (and to be a ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validator"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"bonding",children:"Bonding"}),"\n",(0,n.jsxs)(o.p,{children:["Depositing money in the ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/A#auction-contract",children:"auction contract"})," and try to become a ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/S#staker",children:"staker"}),". The bonding request is a transaction that transfers tokens to the auction contract. In the next ",(0,n.jsx)(o.a,{href:"#booking-block",children:"booking block"}),", a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block."]}),"\n",(0,n.jsx)(o.h2,{id:"booking-block",children:"Booking block"}),"\n",(0,n.jsxs)(o.p,{children:["The booking block for an era is the block that determines the era's validator set. In it, the ",(0,n.jsx)(o.a,{href:"/1.5.X/concepts/glossary/A#auction-contract",children:"auction contract"})," selects the highest bidders to be the future era's validators. There is a configurable delay, the ",(0,n.jsx)(o.em,{children:"auction_delay"}),", which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era ",(0,n.jsx)(o.em,{children:"N + auction_delay + 1"})," is the last block of era ",(0,n.jsx)(o.em,{children:"N"}),"."]})]})}function d(e={}){const{wrapper:o}={...(0,c.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>a,x:()=>l});var n=s(96540);const c={},t=n.createContext(c);function a(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3aa29420.a18fd86b.js b/assets/js/3aa29420.a18fd86b.js deleted file mode 100644 index cb77e0327..000000000 --- a/assets/js/3aa29420.a18fd86b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1515],{28510:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>l,toc:()=>i});var n=s(74848),c=s(28453);const t={},a="B",l={id:"concepts/glossary/B",title:"B",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/B.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/B",permalink:"/concepts/glossary/B",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"A",permalink:"/concepts/glossary/A"},next:{title:"C",permalink:"/concepts/glossary/C"}},r={},i=[{value:"Blake2b",id:"blake2b",level:2},{value:"Block",id:"block",level:2},{value:"Block creation",id:"block-creation",level:2},{value:"Block finality",id:"block-finality",level:2},{value:"Block gossiping",id:"block-gossiping",level:2},{value:"Block height",id:"block-height",level:2},{value:"Block passing",id:"block-passing",level:2},{value:"Block processing",id:"block-processing",level:2},{value:"Block proposal",id:"block-proposal",level:2},{value:"Block validation",id:"block-validation",level:2},{value:"Blockchain",id:"blockchain",level:2},{value:"Block store",id:"block-store",level:2},{value:"Bond",id:"bond",level:2},{value:"Bonding",id:"bonding",level:2},{value:"Booking block",id:"booking-block",level:2}];function h(e){const o={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"b",children:"B"})}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsxs)(o.p,{children:[(0,n.jsx)(o.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsx)(o.h2,{id:"blake2b",children:"Blake2b"}),"\n",(0,n.jsxs)(o.p,{children:["A function used within the Casper platform to create cryptographic ",(0,n.jsx)(o.a,{href:"/concepts/glossary/H#hash",children:"hashes"}),". More information can be found ",(0,n.jsx)(o.a,{href:"https://www.blake2.net/",children:"here"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block",children:"Block"}),"\n",(0,n.jsx)(o.p,{children:"Used in two contexts:"}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,n.jsx)(o.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,n.jsx)(o.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,n.jsx)(o.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,n.jsx)(o.h2,{id:"block-creation",children:"Block creation"}),"\n",(0,n.jsxs)(o.p,{children:["Block creation means computing the deployment results and collecting the results that belong together into a block. We follow a process called ",(0,n.jsx)(o.em,{children:"execution after consensus"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["The ",(0,n.jsx)(o.a,{href:"/concepts/glossary/B#block-proposal",children:"block proposal"})," happens first, and the proposed ",(0,n.jsx)(o.a,{href:"/concepts/glossary/P#proto-block",children:"proto block"})," contains a set of deploys that have not been executed yet."]}),"\n",(0,n.jsxs)(o.p,{children:["Only after consensus on a ",(0,n.jsx)(o.em,{children:"proto block"})," has been reached, the deploys are executed. The resulting new global state ",(0,n.jsx)(o.a,{href:"/concepts/glossary/R#root-hash",children:"root hash"})," is put into an actual block, together with the executed deploys."]}),"\n",(0,n.jsx)(o.p,{children:"Note that only validators can create valid blocks."}),"\n",(0,n.jsx)(o.h2,{id:"block-finality",children:"Block finality"}),"\n",(0,n.jsx)(o.p,{children:'A block is "finalized" if the validators agree on adding it to the blockchain.'}),"\n",(0,n.jsxs)(o.p,{children:["There are different levels of ",(0,n.jsx)(o.em,{children:"finality"})," in the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/H#highway",children:"Highway"})," protocol. A finalized block has a fault-tolerance ",(0,n.jsx)(o.em,{children:"F"}),", expressed as a fraction of the total stake. For an observer to see a conflicting block as finalized, several validators whose total stake exceeds ",(0,n.jsx)(o.em,{children:"F"})," would have to collude and show different information in a way that would ultimately be detected and punished (see ",(0,n.jsx)(o.a,{href:"/concepts/glossary/S#slashing",children:"slashing"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"block-gossiping",children:"Block gossiping"}),"\n",(0,n.jsxs)(o.p,{children:["Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms ",(0,n.jsx)(o.em,{children:"block gossiping"})," and ",(0,n.jsx)(o.a,{href:"#block-passing",children:"block passing"})," are interchangeable."]}),"\n",(0,n.jsx)(o.h2,{id:"block-height",children:"Block height"}),"\n",(0,n.jsx)(o.p,{children:"Block height is an identifier for a given block based on the number of blocks completed prior to that block."}),"\n",(0,n.jsx)(o.h2,{id:"block-passing",children:"Block passing"}),"\n",(0,n.jsxs)(o.p,{children:["See ",(0,n.jsx)(o.a,{href:"#block-gossiping",children:"block gossiping"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-processing",children:"Block processing"}),"\n",(0,n.jsxs)(o.p,{children:["Block processing consists of running the deploys in a block received from another node to determine updates to the global state. Note that this is an essential part of ",(0,n.jsx)(o.a,{href:"#block-validation",children:"validating blocks"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-proposal",children:"Block proposal"}),"\n",(0,n.jsx)(o.p,{children:"Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only."}),"\n",(0,n.jsx)(o.h2,{id:"block-validation",children:"Block validation"}),"\n",(0,n.jsx)(o.p,{children:"The process of determining the validity of a block obtained from another node on the network."}),"\n",(0,n.jsx)(o.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,n.jsxs)(o.p,{children:["Blockchain is a P2P network where the collection of nodes (",(0,n.jsx)(o.a,{href:"/concepts/glossary/V#validator",children:"validators"}),") concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of ",(0,n.jsx)(o.a,{href:"/concepts/glossary/T#transaction",children:"transactions"}),". For performance reasons, transactions are bundled in ",(0,n.jsx)(o.a,{href:"#block",children:"blocks"}),". According to a particular cooperation protocol (consensus protocol), the collection of ",(0,n.jsx)(o.a,{href:"/concepts/glossary/N#node",children:"nodes"})," connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," and has a sizeable map-like collection."]}),"\n",(0,n.jsx)(o.h2,{id:"block-store",children:"Block store"}),"\n",(0,n.jsx)(o.p,{children:"The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash."}),"\n",(0,n.jsx)(o.h2,{id:"bond",children:"Bond"}),"\n",(0,n.jsxs)(o.p,{children:["The amount of money (in crypto-currency) that is allocated by a node in order to participate in ",(0,n.jsx)(o.a,{href:"/concepts/glossary/C#consensus",children:"consensus"})," (and to be a ",(0,n.jsx)(o.a,{href:"/concepts/glossary/V#validator",children:"validator"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"bonding",children:"Bonding"}),"\n",(0,n.jsxs)(o.p,{children:["Depositing money in the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"})," and try to become a ",(0,n.jsx)(o.a,{href:"/concepts/glossary/S#staker",children:"staker"}),". The bonding request is a transaction that transfers tokens to the auction contract. In the next ",(0,n.jsx)(o.a,{href:"#booking-block",children:"booking block"}),", a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block."]}),"\n",(0,n.jsx)(o.h2,{id:"booking-block",children:"Booking block"}),"\n",(0,n.jsxs)(o.p,{children:["The booking block for an era is the block that determines the era's validator set. In it, the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"})," selects the highest bidders to be the future era's validators. There is a configurable delay, the ",(0,n.jsx)(o.em,{children:"auction_delay"}),", which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era ",(0,n.jsx)(o.em,{children:"N + auction_delay + 1"})," is the last block of era ",(0,n.jsx)(o.em,{children:"N"}),"."]})]})}function d(e={}){const{wrapper:o}={...(0,c.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>a,x:()=>l});var n=s(96540);const c={},t=n.createContext(c);function a(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3aaf2bfb.7183a894.js b/assets/js/3aaf2bfb.7183a894.js deleted file mode 100644 index e3a5e60c5..000000000 --- a/assets/js/3aaf2bfb.7183a894.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[666],{76599:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>s,metadata:()=>c,toc:()=>o});var d=r(74848),t=r(28453);const s={},i="Casper JSON-RPC Error Codes",c={id:"developers/json-rpc/errors",title:"Casper JSON-RPC Error Codes",description:"The following document expands on custom error codes provided by casper-json-rpc crate.",source:"@site/docs/developers/json-rpc/errors.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/errors",permalink:"/next/developers/json-rpc/errors",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},l={},o=[{value:"Error Codes",id:"error-codes",level:2},{value:"Invalid <code>Params</code>",id:"invalid-params",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"casper-json-rpc-error-codes",children:"Casper JSON-RPC Error Codes"})}),"\n",(0,d.jsxs)(n.p,{children:["The following document expands on custom error codes provided by ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," crate."]}),"\n",(0,d.jsx)(n.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Code"}),(0,d.jsx)(n.th,{children:"Error"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-1"}),(0,d.jsx)(n.td,{children:"NoSuchDeploy"}),(0,d.jsx)(n.td,{children:"The requested Deploy was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-2"}),(0,d.jsx)(n.td,{children:"NoSuchBlock"}),(0,d.jsx)(n.td,{children:"The requested Block was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-3"}),(0,d.jsx)(n.td,{children:"FailedToParseQueryKey"}),(0,d.jsx)(n.td,{children:"Parsing the Key from a query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-4"}),(0,d.jsx)(n.td,{children:"QueryFailed"}),(0,d.jsx)(n.td,{children:"The query failed to find a result."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-5"}),(0,d.jsx)(n.td,{children:"QueryFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-6"}),(0,d.jsx)(n.td,{children:"FailedToParseGetBalanceURef"}),(0,d.jsx)(n.td,{children:"Parsing the URef while getting a balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-7"}),(0,d.jsx)(n.td,{children:"FailedToGetBalance"}),(0,d.jsx)(n.td,{children:"Failed to get the requested balance."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-8"}),(0,d.jsx)(n.td,{children:"GetBalanceFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query to retrieve the balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-9"}),(0,d.jsx)(n.td,{children:"InvalidDeploy"}),(0,d.jsx)(n.td,{children:"The given Deploy cannot be executed as it is invalid."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-10"}),(0,d.jsx)(n.td,{children:"NoSuchAccount"}),(0,d.jsx)(n.td,{children:"The given account was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-11"}),(0,d.jsx)(n.td,{children:"FailedToGetDictionaryURef"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary URef."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-12"}),(0,d.jsx)(n.td,{children:"FailedToGetTrie"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary trie."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-13"}),(0,d.jsx)(n.td,{children:"NoSuchStateRoot"}),(0,d.jsx)(n.td,{children:"The requested state root hash was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32600"}),(0,d.jsx)(n.td,{children:"InvalidRequest"}),(0,d.jsx)(n.td,{children:"The JSON sent is not a valid Request object."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32601"}),(0,d.jsx)(n.td,{children:"MethodNotFound"}),(0,d.jsx)(n.td,{children:"The method does not exist or is not available."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32602"}),(0,d.jsx)(n.td,{children:"InvalidParams"}),(0,d.jsx)(n.td,{children:"Invalid method parameter(s)"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32603"}),(0,d.jsx)(n.td,{children:"InternalError"}),(0,d.jsx)(n.td,{children:"Internal JSON-RPC error."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32700"}),(0,d.jsx)(n.td,{children:"ParseError"}),(0,d.jsx)(n.td,{children:"Invalid JSON was received by the server."})]})]})]}),"\n",(0,d.jsxs)(n.h2,{id:"invalid-params",children:["Invalid ",(0,d.jsx)(n.code,{children:"Params"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," no longer ignores invalid ",(0,d.jsx)(n.code,{children:"params"})," fields. ",(0,d.jsx)(n.code,{children:"Params"})," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."]}),"\n",(0,d.jsxs)(n.p,{children:["Failing to adhere to this will result in an ",(0,d.jsx)(n.code,{children:"InvalidParams"})," error."]})]})}function a(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var d=r(96540);const t={},s=d.createContext(t);function i(e){const n=d.useContext(s);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),d.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3aaf2bfb.b2e73a42.js b/assets/js/3aaf2bfb.b2e73a42.js new file mode 100644 index 000000000..1b42f72aa --- /dev/null +++ b/assets/js/3aaf2bfb.b2e73a42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30666],{76599:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>s,metadata:()=>c,toc:()=>o});var d=r(74848),t=r(28453);const s={},i="Casper JSON-RPC Error Codes",c={id:"developers/json-rpc/errors",title:"Casper JSON-RPC Error Codes",description:"The following document expands on custom error codes provided by casper-json-rpc crate.",source:"@site/docs/developers/json-rpc/errors.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/errors",permalink:"/developers/json-rpc/errors",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},l={},o=[{value:"Error Codes",id:"error-codes",level:2},{value:"Invalid <code>Params</code>",id:"invalid-params",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"casper-json-rpc-error-codes",children:"Casper JSON-RPC Error Codes"})}),"\n",(0,d.jsxs)(n.p,{children:["The following document expands on custom error codes provided by ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," crate."]}),"\n",(0,d.jsx)(n.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Code"}),(0,d.jsx)(n.th,{children:"Error"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-1"}),(0,d.jsx)(n.td,{children:"NoSuchDeploy"}),(0,d.jsx)(n.td,{children:"The requested Deploy was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-2"}),(0,d.jsx)(n.td,{children:"NoSuchBlock"}),(0,d.jsx)(n.td,{children:"The requested Block was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-3"}),(0,d.jsx)(n.td,{children:"FailedToParseQueryKey"}),(0,d.jsx)(n.td,{children:"Parsing the Key from a query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-4"}),(0,d.jsx)(n.td,{children:"QueryFailed"}),(0,d.jsx)(n.td,{children:"The query failed to find a result."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-5"}),(0,d.jsx)(n.td,{children:"QueryFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-6"}),(0,d.jsx)(n.td,{children:"FailedToParseGetBalanceURef"}),(0,d.jsx)(n.td,{children:"Parsing the URef while getting a balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-7"}),(0,d.jsx)(n.td,{children:"FailedToGetBalance"}),(0,d.jsx)(n.td,{children:"Failed to get the requested balance."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-8"}),(0,d.jsx)(n.td,{children:"GetBalanceFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query to retrieve the balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-9"}),(0,d.jsx)(n.td,{children:"InvalidDeploy"}),(0,d.jsx)(n.td,{children:"The given Deploy cannot be executed as it is invalid."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-10"}),(0,d.jsx)(n.td,{children:"NoSuchAccount"}),(0,d.jsx)(n.td,{children:"The given account was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-11"}),(0,d.jsx)(n.td,{children:"FailedToGetDictionaryURef"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary URef."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-12"}),(0,d.jsx)(n.td,{children:"FailedToGetTrie"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary trie."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-13"}),(0,d.jsx)(n.td,{children:"NoSuchStateRoot"}),(0,d.jsx)(n.td,{children:"The requested state root hash was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32600"}),(0,d.jsx)(n.td,{children:"InvalidRequest"}),(0,d.jsx)(n.td,{children:"The JSON sent is not a valid Request object."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32601"}),(0,d.jsx)(n.td,{children:"MethodNotFound"}),(0,d.jsx)(n.td,{children:"The method does not exist or is not available."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32602"}),(0,d.jsx)(n.td,{children:"InvalidParams"}),(0,d.jsx)(n.td,{children:"Invalid method parameter(s)"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32603"}),(0,d.jsx)(n.td,{children:"InternalError"}),(0,d.jsx)(n.td,{children:"Internal JSON-RPC error."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32700"}),(0,d.jsx)(n.td,{children:"ParseError"}),(0,d.jsx)(n.td,{children:"Invalid JSON was received by the server."})]})]})]}),"\n",(0,d.jsxs)(n.h2,{id:"invalid-params",children:["Invalid ",(0,d.jsx)(n.code,{children:"Params"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," no longer ignores invalid ",(0,d.jsx)(n.code,{children:"params"})," fields. ",(0,d.jsx)(n.code,{children:"Params"})," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."]}),"\n",(0,d.jsxs)(n.p,{children:["Failing to adhere to this will result in an ",(0,d.jsx)(n.code,{children:"InvalidParams"})," error."]})]})}function a(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var d=r(96540);const t={},s=d.createContext(t);function i(e){const n=d.useContext(s);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),d.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ac85609.12ab7143.js b/assets/js/3ac85609.12ab7143.js new file mode 100644 index 000000000..509b81810 --- /dev/null +++ b/assets/js/3ac85609.12ab7143.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28626],{42429:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var r=t(74848),s=t(28453);const i={title:"Introduction",slug:"/writing-contracts"},c="Writing On-Chain Code",o={id:"developers/writing-onchain-code/index",title:"Introduction",description:"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/index.md",sourceDirName:"developers/writing-onchain-code",slug:"/writing-contracts",permalink:"/1.5.X/writing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/writing-contracts"},sidebar:"developers",previous:{title:"Essential Rust Crates",permalink:"/1.5.X/developers/essential-crates"},next:{title:"Getting Started with Rust",permalink:"/1.5.X/developers/writing-onchain-code/getting-started"}},a={},d=[{value:"Interacting with Contracts on the Blockchain",id:"interacting-with-contracts-on-the-blockchain",level:2},{value:"Tutorials",id:"tutorials",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",iframe:"iframe",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"writing-on-chain-code",children:"Writing On-Chain Code"})}),"\n",(0,r.jsxs)(n.p,{children:["This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The ",(0,r.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj",children:"Video Series for Writing On-Chain Code"})," accompanies the topics below."]}),"\n",(0,r.jsxs)(n.p,{align:"center",children:["\n",(0,r.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/JoOjhSOnQzk",position:"middle",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),(0,r.jsx)(n.td,{children:"An introduction to using Rust with the Casper Platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/assembly-script",children:"Getting Started with AssemblyScript"})}),(0,r.jsx)(n.td,{children:"An introduction to using AssemblyScript with the Casper Platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),(0,r.jsx)(n.td,{children:"An example of a smart contract built in Rust"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to test contract code using the unit testing framework"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/upgrading-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),(0,r.jsx)(n.td,{children:"An introduction to versioning smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/calling-contracts",children:"Calling Contracts"})}),(0,r.jsx)(n.td,{})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),(0,r.jsx)(n.td,{children:"Understand what session code is and when you would use it over contract code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"})}),(0,r.jsx)(n.td,{children:"An introduction to writing session code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),(0,r.jsx)(n.td,{children:"Steps to test session code using the unit testing framework"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash",children:"Using Contract Hash vs. Package Hash"})}),(0,r.jsxs)(n.td,{children:["Advantages and disadvantages of using ",(0,r.jsx)(n.code,{children:"contract_hash"})," vs. ",(0,r.jsx)(n.code,{children:"contract_package_hash"})," when calling a contract"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})}),(0,r.jsx)(n.td,{children:"An outline of best practices when developing smart contracts on a Casper network"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"interacting-with-contracts-on-the-blockchain",children:"Interacting with Contracts on the Blockchain"}),"\n",(0,r.jsxs)(n.p,{children:["Additionally, the section on ",(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/",children:"Interacting with the Blockchain"})," covers installing and calling contracts using the Casper command-line client written in Rust."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})}),(0,r.jsx)(n.td,{children:"A guide on installing smart contracts and querying global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Steps to call a smart contract with the Rust command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})}),(0,r.jsx)(n.td,{children:"Information on Dictionaries and how to read and write to them on the Casper Platform."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Possible error codes when writing smart contracts."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,r.jsx)(n.p,{children:"The following tutorials outline some aspects of writing smart contracts on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsx)(n.td,{children:"Learning how to return a value using contract code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(n.td,{children:"Retrieving and using the authorization keys associated with a deploy"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(n.td,{children:"How to handle tokens via a contract"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ac85609.db0b618c.js b/assets/js/3ac85609.db0b618c.js deleted file mode 100644 index cbb5569eb..000000000 --- a/assets/js/3ac85609.db0b618c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8626],{42429:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var r=t(74848),s=t(28453);const i={title:"Introduction",slug:"/writing-contracts"},c="Writing On-Chain Code",o={id:"developers/writing-onchain-code/index",title:"Introduction",description:"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/index.md",sourceDirName:"developers/writing-onchain-code",slug:"/writing-contracts",permalink:"/writing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/writing-contracts"},sidebar:"developers",previous:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"},next:{title:"Getting Started with Rust",permalink:"/developers/writing-onchain-code/getting-started"}},a={},d=[{value:"Interacting with Contracts on the Blockchain",id:"interacting-with-contracts-on-the-blockchain",level:2},{value:"Tutorials",id:"tutorials",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",iframe:"iframe",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"writing-on-chain-code",children:"Writing On-Chain Code"})}),"\n",(0,r.jsxs)(n.p,{children:["This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The ",(0,r.jsx)(n.a,{href:"https://www.youtube.com/playlist?list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj",children:"Video Series for Writing On-Chain Code"})," accompanies the topics below."]}),"\n",(0,r.jsxs)(n.p,{align:"center",children:["\n",(0,r.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/JoOjhSOnQzk",position:"middle",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),(0,r.jsx)(n.td,{children:"An introduction to using Rust with the Casper Platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/assembly-script",children:"Getting Started with AssemblyScript"})}),(0,r.jsx)(n.td,{children:"An introduction to using AssemblyScript with the Casper Platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),(0,r.jsx)(n.td,{children:"An example of a smart contract built in Rust"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to test contract code using the unit testing framework"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),(0,r.jsx)(n.td,{children:"An introduction to versioning smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"Calling Contracts"})}),(0,r.jsx)(n.td,{})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),(0,r.jsx)(n.td,{children:"Understand what session code is and when you would use it over contract code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"})}),(0,r.jsx)(n.td,{children:"An introduction to writing session code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),(0,r.jsx)(n.td,{children:"Steps to test session code using the unit testing framework"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-hash-vs-package-hash",children:"Using Contract Hash vs. Package Hash"})}),(0,r.jsxs)(n.td,{children:["Advantages and disadvantages of using ",(0,r.jsx)(n.code,{children:"contract_hash"})," vs. ",(0,r.jsx)(n.code,{children:"contract_package_hash"})," when calling a contract"]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})}),(0,r.jsx)(n.td,{children:"An outline of best practices when developing smart contracts on a Casper network"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"interacting-with-contracts-on-the-blockchain",children:"Interacting with Contracts on the Blockchain"}),"\n",(0,r.jsxs)(n.p,{children:["Additionally, the section on ",(0,r.jsx)(n.a,{href:"/developers/cli/",children:"Interacting with the Blockchain"})," covers installing and calling contracts using the Casper command-line client written in Rust."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})}),(0,r.jsx)(n.td,{children:"A guide on installing smart contracts and querying global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Steps to call a smart contract with the Rust command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})}),(0,r.jsx)(n.td,{children:"Information on Dictionaries and how to read and write to them on the Casper Platform."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Possible error codes when writing smart contracts."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,r.jsx)(n.p,{children:"The following tutorials outline some aspects of writing smart contracts on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsx)(n.td,{children:"Learning how to return a value using contract code"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(n.td,{children:"Retrieving and using the authorization keys associated with a deploy"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(n.td,{children:"How to handle tokens via a contract"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b749ca6.12e4a5ed.js b/assets/js/3b749ca6.12e4a5ed.js new file mode 100644 index 000000000..c090f6ca9 --- /dev/null +++ b/assets/js/3b749ca6.12e4a5ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6708],{69261:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var s=n(74848),r=n(28453);const c={title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},a="Testing Framework for CEP-18",i={id:"resources/tokens/cep18/tests",title:"Testing Guide",description:"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/tests.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/tests",permalink:"/1.5.X/resources/tokens/cep18/tests",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},sidebar:"resources",previous:{title:"CEP-18 Transfers",permalink:"/1.5.X/resources/tokens/cep18/transfer"},next:{title:"Introduction",permalink:"/1.5.X/resources/tokens/cep78/introduction"}},o={},l=[{value:"Configuring the Test Package",id:"configuring-the-test-package",level:2},{value:"Testing Logic",id:"testing-logic",level:2},{value:"Setting up the Testing Context",id:"setting-up-the-testing-context",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:3},{value:"Creating Helper Functions",id:"creating-helper-functions",level:3},{value:"Creating Unit Tests",id:"creating-unit-tests",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function _(e){const t={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-framework-for-cep-18",children:"Testing Framework for CEP-18"})}),"\n",(0,s.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,s.jsxs)(t.p,{children:["The following section reviews the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/tests",children:"GitHub testing folder"}),", which creates a testing framework for the Casper ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Fungible Token"})," project. You can find more details about testing Casper contracts ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a complete test expecting a failed transfer:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[should_panic(expected = "ApiError::User(65534) [131070]")]\n#[test]\nfn should_not_transfer_with_insufficient_balance() {\n let mut fixture = TestFixture::install_contract();\n\n let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();\n assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);\n\n fixture.transfer(\n Key::from(fixture.bob),\n initial_ali_balance + U256::one(),\n fixture.ali,\n );\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To build and run the tests, issue the following command in the project folder, ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The project contains a ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,s.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file to the ",(0,s.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,s.jsx)(t.code,{children:"make test"})," command during development."]}),"\n",(0,s.jsx)(t.h2,{id:"configuring-the-test-package",children:"Configuring the Test Package"}),"\n",(0,s.jsxs)(t.p,{children:["In this project, we define a ",(0,s.jsx)(t.code,{children:"tests"})," package using the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/Cargo.toml",children:"tests/Cargo.toml"})," file."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'[package]\nname = "tests"\nversion = "1.0.0"\n...\n\n[dependencies]\ncasper-types = "2.0.0"\ncasper-engine-test-support = "4.0.0"\ncasper-execution-engine = "4.0.0"\nonce_cell = "1.16.0"\n\n[lib]\nname = "tests"\n...\n'})}),"\n",(0,s.jsx)(t.h2,{id:"testing-logic",children:"Testing Logic"}),"\n",(0,s.jsxs)(t.p,{children:["In Github, you will find an ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/cep18",children:"example"})," containing a Casper Fungible Token ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/cep18/src/main.rs",children:"contract"})," implementation with the corresponding ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"tests"}),". The tests follow this sequence:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#setting-up-the-testing-context",children:"Step 1"})," - Specify the starting state of the blockchain."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"Step 2"})," - Deploy the compiled contract to the blockchain and query it."]}),"\n",(0,s.jsx)(t.li,{children:"Step 3 - Create additional deploys for calling each of the entrypoints in the contract."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints."}),"\n",(0,s.jsx)(t.h3,{id:"setting-up-the-testing-context",children:"Setting up the Testing Context"}),"\n",(0,s.jsxs)(t.p,{children:["The code in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src/utility",children:"utility directory"})," initializes the blockchain's ",(0,s.jsx)(t.a,{href:"/concepts/glossary/G/#global-state",children:"global state"})," with all the data and entrypoints the smart contract needs."]}),"\n",(0,s.jsxs)(t.p,{children:["Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/constants.rs",children:(0,s.jsx)(t.code,{children:"constants.rs"})})," file within the ",(0,s.jsx)(t.code,{children:"utility"})," directory. For the most up-to-date version of the code, visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of required constants"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\nuse casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,\n};\nuse casper_execution_engine::core::engine_state::ExecuteRequest;\nuse casper_types::{\n account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,\n};\n\nuse crate::utility::constants::{\n ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,\n};\n\nuse super::constants::{\n ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,\n};\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a ",(0,s.jsx)(t.code,{children:"TestContext"})," of its own. The ",(0,s.jsx)(t.em,{children:"contract_hash"})," and the ",(0,s.jsx)(t.em,{children:"session_code"})," won\u2019t change after the contract is deployed, so it is good to keep them handy."]}),"\n",(0,s.jsxs)(t.p,{children:["This code snippet builds the context and includes the compiled contract ",(0,s.jsx)(t.em,{children:".wasm"})," binary being tested. The ",(0,s.jsx)(t.code,{children:"TestContext"})," struct creates a new instance of the ",(0,s.jsx)(t.code,{children:"cep18_token"})," with several test accounts."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),": These accounts have a positive initial balance."]}),"\n",(0,s.jsxs)(t.p,{children:["The full and most recent code implementation is available on ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of a CEP-18 token in a test"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\n// Creating the `TestContext` struct.\n\npub(crate) struct TestContext {\npub(crate) cep18_token: ContractHash,\npub(crate) cep18_test_contract_package: ContractPackageHash,\n}\n\n// Setting up the test instance of CEP-18.\n\npub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option<u64> = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-helper-functions",children:"Creating Helper Functions"}),"\n",(0,s.jsxs)(t.p,{children:["The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.jsx)(t.code,{children:"installer_request_builders.rs"})," defines helper functions that will be used throughout the testing framework:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_total_supply"})," - A function for testing the total supply of the CEP-18 contract instance."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_balance_of"})," - A function for checking an account's balance of CEP-18 tokens."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_allowance_of"})," - A function for checking an account's spending allowance from another account's balance."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.jsx)(t.code,{children:"test_cep18_transfer"}),", ",(0,s.jsx)(t.code,{children:"make_cep18_approve_request"})," and ",(0,s.jsx)(t.code,{children:"test_approve_for"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"contract installation"}),":"]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example helper function"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"creating-unit-tests",children:"Creating Unit Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Within this testing context, the ",(0,s.jsxs)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:[(0,s.jsx)(t.code,{children:"tests"})," directory"]})," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"installer_request_builders.rs"})," file."]}),"\n",(0,s.jsxs)(t.p,{children:["The example below shows one of the tests. Visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"GitHub"})," to find all the available tests."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example test querying token properties"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs",children:"lib.rs"})," file is configured to run the example integration tests via the ",(0,s.jsx)(t.code,{children:"make test"})," command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, navigate to the parent ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18 directory"})," and run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["This example uses ",(0,s.jsx)(t.code,{children:"bash"}),". If you are using a Rust IDE, you need to configure it to run the tests."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function a(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b749ca6.2b2c6cde.js b/assets/js/3b749ca6.2b2c6cde.js deleted file mode 100644 index 80183c029..000000000 --- a/assets/js/3b749ca6.2b2c6cde.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6708],{69261:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var s=n(74848),r=n(28453);const c={title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},a="Testing Framework for CEP-18",i={id:"resources/tokens/cep18/tests",title:"Testing Guide",description:"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/tests.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/tests",permalink:"/resources/tokens/cep18/tests",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},sidebar:"resources",previous:{title:"CEP-18 Transfers",permalink:"/resources/tokens/cep18/transfer"},next:{title:"Introduction",permalink:"/resources/tokens/cep78/introduction"}},o={},l=[{value:"Configuring the Test Package",id:"configuring-the-test-package",level:2},{value:"Testing Logic",id:"testing-logic",level:2},{value:"Setting up the Testing Context",id:"setting-up-the-testing-context",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:3},{value:"Creating Helper Functions",id:"creating-helper-functions",level:3},{value:"Creating Unit Tests",id:"creating-unit-tests",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function _(e){const t={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-framework-for-cep-18",children:"Testing Framework for CEP-18"})}),"\n",(0,s.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,s.jsxs)(t.p,{children:["The following section reviews the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/tests",children:"GitHub testing folder"}),", which creates a testing framework for the Casper ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Fungible Token"})," project. You can find more details about testing Casper contracts ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a complete test expecting a failed transfer:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[should_panic(expected = "ApiError::User(65534) [131070]")]\n#[test]\nfn should_not_transfer_with_insufficient_balance() {\n let mut fixture = TestFixture::install_contract();\n\n let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();\n assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);\n\n fixture.transfer(\n Key::from(fixture.bob),\n initial_ali_balance + U256::one(),\n fixture.ali,\n );\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To build and run the tests, issue the following command in the project folder, ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The project contains a ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,s.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file to the ",(0,s.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,s.jsx)(t.code,{children:"make test"})," command during development."]}),"\n",(0,s.jsx)(t.h2,{id:"configuring-the-test-package",children:"Configuring the Test Package"}),"\n",(0,s.jsxs)(t.p,{children:["In this project, we define a ",(0,s.jsx)(t.code,{children:"tests"})," package using the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/Cargo.toml",children:"tests/Cargo.toml"})," file."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'[package]\nname = "tests"\nversion = "1.0.0"\n...\n\n[dependencies]\ncasper-types = "2.0.0"\ncasper-engine-test-support = "4.0.0"\ncasper-execution-engine = "4.0.0"\nonce_cell = "1.16.0"\n\n[lib]\nname = "tests"\n...\n'})}),"\n",(0,s.jsx)(t.h2,{id:"testing-logic",children:"Testing Logic"}),"\n",(0,s.jsxs)(t.p,{children:["In Github, you will find an ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/cep18",children:"example"})," containing a Casper Fungible Token ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/cep18/src/main.rs",children:"contract"})," implementation with the corresponding ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"tests"}),". The tests follow this sequence:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#setting-up-the-testing-context",children:"Step 1"})," - Specify the starting state of the blockchain."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"Step 2"})," - Deploy the compiled contract to the blockchain and query it."]}),"\n",(0,s.jsx)(t.li,{children:"Step 3 - Create additional deploys for calling each of the entrypoints in the contract."}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints."}),"\n",(0,s.jsx)(t.h3,{id:"setting-up-the-testing-context",children:"Setting up the Testing Context"}),"\n",(0,s.jsxs)(t.p,{children:["The code in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src/utility",children:"utility directory"})," initializes the blockchain's ",(0,s.jsx)(t.a,{href:"/concepts/glossary/G/#global-state",children:"global state"})," with all the data and entrypoints the smart contract needs."]}),"\n",(0,s.jsxs)(t.p,{children:["Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/constants.rs",children:(0,s.jsx)(t.code,{children:"constants.rs"})})," file within the ",(0,s.jsx)(t.code,{children:"utility"})," directory. For the most up-to-date version of the code, visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of required constants"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\nuse casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,\n};\nuse casper_execution_engine::core::engine_state::ExecuteRequest;\nuse casper_types::{\n account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,\n};\n\nuse crate::utility::constants::{\n ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,\n};\n\nuse super::constants::{\n ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,\n};\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a ",(0,s.jsx)(t.code,{children:"TestContext"})," of its own. The ",(0,s.jsx)(t.em,{children:"contract_hash"})," and the ",(0,s.jsx)(t.em,{children:"session_code"})," won\u2019t change after the contract is deployed, so it is good to keep them handy."]}),"\n",(0,s.jsxs)(t.p,{children:["This code snippet builds the context and includes the compiled contract ",(0,s.jsx)(t.em,{children:".wasm"})," binary being tested. The ",(0,s.jsx)(t.code,{children:"TestContext"})," struct creates a new instance of the ",(0,s.jsx)(t.code,{children:"cep18_token"})," with several test accounts."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),": These accounts have a positive initial balance."]}),"\n",(0,s.jsxs)(t.p,{children:["The full and most recent code implementation is available on ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of a CEP-18 token in a test"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\n// Creating the `TestContext` struct.\n\npub(crate) struct TestContext {\npub(crate) cep18_token: ContractHash,\npub(crate) cep18_test_contract_package: ContractPackageHash,\n}\n\n// Setting up the test instance of CEP-18.\n\npub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option<u64> = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-helper-functions",children:"Creating Helper Functions"}),"\n",(0,s.jsxs)(t.p,{children:["The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.jsx)(t.code,{children:"installer_request_builders.rs"})," defines helper functions that will be used throughout the testing framework:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_total_supply"})," - A function for testing the total supply of the CEP-18 contract instance."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_balance_of"})," - A function for checking an account's balance of CEP-18 tokens."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_allowance_of"})," - A function for checking an account's spending allowance from another account's balance."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.jsx)(t.code,{children:"test_cep18_transfer"}),", ",(0,s.jsx)(t.code,{children:"make_cep18_approve_request"})," and ",(0,s.jsx)(t.code,{children:"test_approve_for"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"contract installation"}),":"]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example helper function"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"creating-unit-tests",children:"Creating Unit Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Within this testing context, the ",(0,s.jsxs)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:[(0,s.jsx)(t.code,{children:"tests"})," directory"]})," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"installer_request_builders.rs"})," file."]}),"\n",(0,s.jsxs)(t.p,{children:["The example below shows one of the tests. Visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"GitHub"})," to find all the available tests."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example test querying token properties"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs",children:"lib.rs"})," file is configured to run the example integration tests via the ",(0,s.jsx)(t.code,{children:"make test"})," command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, navigate to the parent ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18 directory"})," and run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["This example uses ",(0,s.jsx)(t.code,{children:"bash"}),". If you are using a Rust IDE, you need to configure it to run the tests."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function a(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b86d751.8b6804b4.js b/assets/js/3b86d751.8b6804b4.js deleted file mode 100644 index c995100bc..000000000 --- a/assets/js/3b86d751.8b6804b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6815],{25023:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var a=t(74848),r=t(28453);const o={},s="Node Maintenance",i={id:"operators/maintenance/index",title:"Node Maintenance",description:"This section covers maintenance actions such as moving a node to a different location and restoring a database.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/index.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/",permalink:"/operators/maintenance/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Staging Files",permalink:"/operators/setup-network/staging-files-for-new-network"},next:{title:"Archive and Restore a DB",permalink:"/operators/maintenance/archiving-and-restoring"}},c={},d=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"node-maintenance",children:"Node Maintenance"})}),"\n",(0,a.jsx)(n.p,{children:"This section covers maintenance actions such as moving a node to a different location and restoring a database."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Title"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/operators/maintenance/archiving-and-restoring",children:"Archiving and Restoring a Database"})}),(0,a.jsxs)(n.td,{children:["Using ",(0,a.jsx)(n.code,{children:"zstd"})," for the compression and decompression of a Casper node database and streaming from a backup location"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/operators/maintenance/moving-node",children:"Moving a Validating Node"})}),(0,a.jsx)(n.td,{children:"Ways to move a validator node to another machine"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3b86d751.aaac82d9.js b/assets/js/3b86d751.aaac82d9.js new file mode 100644 index 000000000..573e13dff --- /dev/null +++ b/assets/js/3b86d751.aaac82d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6815],{25023:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var a=t(74848),r=t(28453);const o={},s="Node Maintenance",i={id:"operators/maintenance/index",title:"Node Maintenance",description:"This section covers maintenance actions such as moving a node to a different location and restoring a database.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/index.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/",permalink:"/1.5.X/operators/maintenance/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Staging Files",permalink:"/1.5.X/operators/setup-network/staging-files-for-new-network"},next:{title:"Archive and Restore a DB",permalink:"/1.5.X/operators/maintenance/archiving-and-restoring"}},c={},d=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"node-maintenance",children:"Node Maintenance"})}),"\n",(0,a.jsx)(n.p,{children:"This section covers maintenance actions such as moving a node to a different location and restoring a database."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Title"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/1.5.X/operators/maintenance/archiving-and-restoring",children:"Archiving and Restoring a Database"})}),(0,a.jsxs)(n.td,{children:["Using ",(0,a.jsx)(n.code,{children:"zstd"})," for the compression and decompression of a Casper node database and streaming from a backup location"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/1.5.X/operators/maintenance/moving-node",children:"Moving a Validating Node"})}),(0,a.jsx)(n.td,{children:"Ways to move a validator node to another machine"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3bf1ce3c.4be36f8e.js b/assets/js/3bf1ce3c.4be36f8e.js deleted file mode 100644 index 49ecfa1eb..000000000 --- a/assets/js/3bf1ce3c.4be36f8e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2349],{86344:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var a=s(74848),r=s(28453);const t={},d="Verifying a Transfer",c={id:"developers/cli/transfers/verify-transfer",title:"Verifying a Transfer",description:"Prerequisites",source:"@site/docs/developers/cli/transfers/verify-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/verify-transfer",permalink:"/next/developers/cli/transfers/verify-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/next/developers/cli/transfers/multisig-deploy-transfer"},next:{title:"Delegating Tokens",permalink:"/next/developers/cli/delegate"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Query the State Root Hash",id:"query-the-state-root-hash",level:2},{value:"Query the Transfer Details",id:"query-transfer-details",level:2},{value:"Query the Account State",id:"query-account-state",level:2},{value:"Query the Purse Balance",id:"get-purse-balance",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"verifying-a-transfer",children:"Verifying a Transfer"})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before verifying a transfer, make sure you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Initiated a ",(0,a.jsx)(n.a,{href:"/next/developers/cli/transfers/direct-token-transfer",children:"Direct Transfer"})," or ",(0,a.jsx)(n.a,{href:"/next/developers/cli/transfers/multisig-deploy-transfer",children:"Multi-sig Deploy Transfer"})]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"deploy_hash"})," of the transfer you want to verify"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"public key"})," of the source and target accounts"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"query-the-state-root-hash",children:"Query the State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io \n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Sample output of the get-state-root-hash command"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 6458079936180872466,\n "result": {\n "api_version": "1.5.3",\n "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"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."})}),"\n",(0,a.jsx)(n.h2,{id:"query-transfer-details",children:"Query the Transfer Details"}),"\n",(0,a.jsxs)(n.p,{children:["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 ",(0,a.jsx)(n.code,{children:"transfer-address"})," identifies each transfer. The ",(0,a.jsx)(n.code,{children:"transfer-address"})," consists of a formatted string with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Transfer hash",src:s(4990).A+"",width:"1558",height:"1228"})}),"\n",(0,a.jsxs)(n.p,{children:["First, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,a.jsx)(n.em,{children:"deploy_hash"})," to identify the corresponding transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] \\\n[DEPLOY_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."execution_results"."result"."Success"."transfers"'})," - List of transfers contained in a successful deploy"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After obtaining the transfer identifier, query the transfer details."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [TRANSFER_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - The hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"key"})," - The base key for the query. This must be a properly formatted transfer address with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix, i.e., ",(0,a.jsx)(n.code,{children:"transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 3 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",\n "path": []\n },\n "id": 3\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Transfer": {\n "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n },\n "merkle_proof": "[42526 hex chars]"\n },\n "id": 3\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"query-account-state",children:"Query the Account State"}),"\n",(0,a.jsxs)(n.p,{children:["Next, query for information about the ",(0,a.jsx)(n.em,{children:"Source"})," account, using the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," of the block containing the transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [SOURCE_PUBLIC_KEY]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the network state"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Source Account Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 4 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [...],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[31406 hex chars]"\n },\n "id": 4\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Query:"})}),"\n",(0,a.jsxs)(n.p,{children:["Repeat the same step to query information about the ",(0,a.jsx)(n.em,{children:"Target"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 5 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 5\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [...],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [...],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32060 hex chars]"\n },\n "id": 5\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"get-purse-balance",children:"Query the Purse Balance"}),"\n",(0,a.jsxs)(n.p,{children:["All accounts on a Casper network have a purse associated with the Casper system mint, which is the ",(0,a.jsx)(n.em,{children:"main purse"}),". The balance associated with a given purse is recorded in global state, and the value can be queried using the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Verify the source purse balance using the ",(0,a.jsx)(n.code,{children:"query-balance"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [SOURCE_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Query Source Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 6 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "1109111876194"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Similarly, query the balance of the target purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-balance \\\n--id 7 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [TARGET_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 7 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"\n }\n },\n "id": 7\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "46200000000"\n },\n "id": 7\n}\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},4990:(e,n,s)=>{s.d(n,{A:()=>a});const a=s.p+"assets/images/transfer-hash-example-b8695f1d7d28b36e8e8cf67b26df6945.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var a=s(96540);const r={},t=a.createContext(r);function d(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3bf1ce3c.e158e2c3.js b/assets/js/3bf1ce3c.e158e2c3.js new file mode 100644 index 000000000..f6d488d14 --- /dev/null +++ b/assets/js/3bf1ce3c.e158e2c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52349],{86344:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var a=s(74848),r=s(28453);const t={},d="Verifying a Transfer",c={id:"developers/cli/transfers/verify-transfer",title:"Verifying a Transfer",description:"Prerequisites",source:"@site/docs/developers/cli/transfers/verify-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/verify-transfer",permalink:"/developers/cli/transfers/verify-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/developers/cli/transfers/multisig-deploy-transfer"},next:{title:"Delegating Tokens",permalink:"/developers/cli/delegate"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Query the State Root Hash",id:"query-the-state-root-hash",level:2},{value:"Query the Transfer Details",id:"query-transfer-details",level:2},{value:"Query the Account State",id:"query-account-state",level:2},{value:"Query the Purse Balance",id:"get-purse-balance",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"verifying-a-transfer",children:"Verifying a Transfer"})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before verifying a transfer, make sure you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Initiated a ",(0,a.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Direct Transfer"})," or ",(0,a.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Multi-sig Deploy Transfer"})]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"deploy_hash"})," of the transfer you want to verify"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"public key"})," of the source and target accounts"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"query-the-state-root-hash",children:"Query the State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io \n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Sample output of the get-state-root-hash command"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 6458079936180872466,\n "result": {\n "api_version": "1.5.3",\n "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"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."})}),"\n",(0,a.jsx)(n.h2,{id:"query-transfer-details",children:"Query the Transfer Details"}),"\n",(0,a.jsxs)(n.p,{children:["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 ",(0,a.jsx)(n.code,{children:"transfer-address"})," identifies each transfer. The ",(0,a.jsx)(n.code,{children:"transfer-address"})," consists of a formatted string with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Transfer hash",src:s(16280).A+"",width:"1558",height:"1228"})}),"\n",(0,a.jsxs)(n.p,{children:["First, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,a.jsx)(n.em,{children:"deploy_hash"})," to identify the corresponding transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] \\\n[DEPLOY_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."execution_results"."result"."Success"."transfers"'})," - List of transfers contained in a successful deploy"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After obtaining the transfer identifier, query the transfer details."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [TRANSFER_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - The hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"key"})," - The base key for the query. This must be a properly formatted transfer address with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix, i.e., ",(0,a.jsx)(n.code,{children:"transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 3 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",\n "path": []\n },\n "id": 3\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Transfer": {\n "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n },\n "merkle_proof": "[42526 hex chars]"\n },\n "id": 3\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"query-account-state",children:"Query the Account State"}),"\n",(0,a.jsxs)(n.p,{children:["Next, query for information about the ",(0,a.jsx)(n.em,{children:"Source"})," account, using the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," of the block containing the transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [SOURCE_PUBLIC_KEY]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the network state"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Source Account Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 4 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [...],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[31406 hex chars]"\n },\n "id": 4\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Query:"})}),"\n",(0,a.jsxs)(n.p,{children:["Repeat the same step to query information about the ",(0,a.jsx)(n.em,{children:"Target"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 5 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 5\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [...],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [...],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32060 hex chars]"\n },\n "id": 5\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"get-purse-balance",children:"Query the Purse Balance"}),"\n",(0,a.jsxs)(n.p,{children:["All accounts on a Casper network have a purse associated with the Casper system mint, which is the ",(0,a.jsx)(n.em,{children:"main purse"}),". The balance associated with a given purse is recorded in global state, and the value can be queried using the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Verify the source purse balance using the ",(0,a.jsx)(n.code,{children:"query-balance"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [SOURCE_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Query Source Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 6 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "1109111876194"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Similarly, query the balance of the target purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-balance \\\n--id 7 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [TARGET_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 7 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"\n }\n },\n "id": 7\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "46200000000"\n },\n "id": 7\n}\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},16280:(e,n,s)=>{s.d(n,{A:()=>a});const a=s.p+"assets/images/transfer-hash-example-b8695f1d7d28b36e8e8cf67b26df6945.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var a=s(96540);const r={},t=a.createContext(r);function d(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3c9a8a22.cbde2a2a.js b/assets/js/3c9a8a22.cbde2a2a.js new file mode 100644 index 000000000..c3045688b --- /dev/null +++ b/assets/js/3c9a8a22.cbde2a2a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32154],{24708:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const a={title:"Overview",slug:"/economics"},o="Overview of Casper Economics",r={id:"concepts/economics/index",title:"Overview",description:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.",source:"@site/versioned_docs/version-2.0.0/concepts/economics/index.md",sourceDirName:"concepts/economics",slug:"/economics",permalink:"/2.0.0/economics",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Overview",slug:"/economics"},sidebar:"concepts",previous:{title:"Reading and Writing Data",permalink:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain"},next:{title:"Consensus",permalink:"/2.0.0/concepts/economics/consensus"}},c={},l=[{value:"Consensus",id:"consensus",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer",level:3},{value:"Runtime",id:"runtime",level:2},{value:"Agents (runtime layer)",id:"agents-runtime-layer",level:3},{value:"Incentives (runtime layer)",id:"incentives-runtime-layer",level:3},{value:"Ecosystem",id:"ecosystem",level:2},{value:"Macroeconomy",id:"macroeconomy",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview-of-casper-economics",children:"Overview of Casper Economics"})}),"\n",(0,s.jsx)(t.p,{children:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value."}),"\n",(0,s.jsx)(t.p,{children:"This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active."}),"\n",(0,s.jsx)(t.h2,{id:"consensus",children:"Consensus"}),"\n",(0,s.jsxs)(t.p,{children:["The consensus layer of the Casper Mainnet runs the ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: ",(0,s.jsx)(t.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,s.jsx)(t.p,{children:'When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.'}),"\n",(0,s.jsx)(t.h3,{id:"agents-consensus-layer",children:"Agents (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"}),' are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain\'s security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Delegators"}),' are users who participate in the platform\'s security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.']}),"\n",(0,s.jsx)(t.h3,{id:"incentives-consensus-layer",children:"Incentives (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"auction"}),' determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Rewards"})," (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Evictions"})," deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract."]}),"\n",(0,s.jsx)(t.h2,{id:"runtime",children:"Runtime"}),"\n",(0,s.jsxs)(t.p,{children:["The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#execution-semantics-gas",children:"metering computing time"}),", measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost."]}),"\n",(0,s.jsx)(t.p,{children:"The Mainnet transaction selection mechanism is based on FIFO."}),"\n",(0,s.jsx)(t.p,{children:"We expect to continue to work on runtime resource markets."}),"\n",(0,s.jsx)(t.h3,{id:"agents-runtime-layer",children:"Agents (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"})," again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Users"})," execute session and contract code using the platform's computational resources"]}),"\n",(0,s.jsx)(t.h3,{id:"incentives-runtime-layer",children:"Incentives (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"fee elimination"})," model by default, setting the ",(0,s.jsx)(t.code,{children:"no_fee"}),",",(0,s.jsx)(t.code,{children:"no_refund"}),", and ",(0,s.jsx)(t.code,{children:"fixed"})," pricing configurations in the network's chainspec."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_fee"}),' mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.']}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_refund"})," mode means no refund is handled when fees are eliminated."]}),"\n",(0,s.jsxs)(t.p,{children:["Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes ",(0,s.jsx)(t.a,{href:"/2.0.0/runtime#lanes-lanes",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations."}),"\n",(0,s.jsxs)(t.p,{children:["The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, ",(0,s.jsx)(t.a,{href:"/2.0.0/operators/setup-network/create-private",children:"private networks"})," can set their fee, refund, and pricing strategies."]}),"\n",(0,s.jsx)(t.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,s.jsx)(t.p,{children:"The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps."}),"\n",(0,s.jsx)(t.h2,{id:"macroeconomy",children:"Macroeconomy"}),"\n",(0,s.jsx)(t.p,{children:'Casper\'s macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.'}),"\n",(0,s.jsx)(t.p,{children:"The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var s=n(96540);const i={},a=s.createContext(i);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ce1a06b.08bdbb80.js b/assets/js/3ce1a06b.08bdbb80.js new file mode 100644 index 000000000..fea92868d --- /dev/null +++ b/assets/js/3ce1a06b.08bdbb80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97816],{70151:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>r});var s=n(74848),o=n(28453);const i={},c="Estimating Gas Costs with Speculative Execution",a={id:"developers/dapps/speculative-exec",title:"Estimating Gas Costs with Speculative Execution",description:"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/speculative-exec.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/speculative-exec",permalink:"/1.5.X/developers/dapps/speculative-exec",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Signing Deploys",permalink:"/1.5.X/developers/dapps/signing-a-deploy"},next:{title:"Local Network Setup",permalink:"/1.5.X/developers/dapps/setup-nctl"}},l={},r=[{value:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client",id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"estimating-gas-costs-with-speculative-execution",children:"Estimating Gas Costs with Speculative Execution"})}),"\n",(0,s.jsxs)(t.p,{children:["Version 1.5 of the Casper Node includes a new JSON RPC endpoint called ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/json-rpc-transactional#speculative_exec",children:(0,s.jsx)(t.code,{children:"speculative_exec"})}),". This endpoint allows developers to send a ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploy"})," to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution."]}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the Deploy in question, ",(0,s.jsx)(t.code,{children:"speculative_exec"})," also accepts a [",(0,s.jsx)(t.code,{children:"block_identifier"}),"] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block."]}),"\n",(0,s.jsx)(t.h2,{id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",children:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Rust CLI Casper client"})," includes a ",(0,s.jsx)(t.code,{children:"speculative-exec"})," option that will flag a normal ",(0,s.jsx)(t.code,{children:"put-deploy"})," for execution but not commitment to global state. The following command shows an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncasper client put-deploy /\n--node-address <HOST:PORT> /\n--chain-name <CHAIN_NAME> /\n--secret-key <PATH> /\n--session-path <PATH> /\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES>\n--speculative-exec <BLOCK HEIGHT OR HASH>\n\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You should receive ",(0,s.jsx)(t.code,{children:"execution_result"}),"s that show a ",(0,s.jsx)(t.code,{children:"cost"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n <Deploy effects removed for conciseness.>\n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Cost estimates acquired through ",(0,s.jsx)(t.code,{children:"speculative_exec"})," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary."]})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3ce1a06b.211c5901.js b/assets/js/3ce1a06b.211c5901.js deleted file mode 100644 index 3c0699742..000000000 --- a/assets/js/3ce1a06b.211c5901.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7816],{70151:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>r});var s=n(74848),o=n(28453);const i={},c="Estimating Gas Costs with Speculative Execution",a={id:"developers/dapps/speculative-exec",title:"Estimating Gas Costs with Speculative Execution",description:"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/speculative-exec.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/speculative-exec",permalink:"/developers/dapps/speculative-exec",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Signing Deploys",permalink:"/developers/dapps/signing-a-deploy"},next:{title:"Local Network Setup",permalink:"/developers/dapps/setup-nctl"}},l={},r=[{value:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client",id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"estimating-gas-costs-with-speculative-execution",children:"Estimating Gas Costs with Speculative Execution"})}),"\n",(0,s.jsxs)(t.p,{children:["Version 1.5 of the Casper Node includes a new JSON RPC endpoint called ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-transactional#speculative_exec",children:(0,s.jsx)(t.code,{children:"speculative_exec"})}),". This endpoint allows developers to send a ",(0,s.jsx)(t.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"})," to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution."]}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the Deploy in question, ",(0,s.jsx)(t.code,{children:"speculative_exec"})," also accepts a [",(0,s.jsx)(t.code,{children:"block_identifier"}),"] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block."]}),"\n",(0,s.jsx)(t.h2,{id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",children:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-deploys",children:"Rust CLI Casper client"})," includes a ",(0,s.jsx)(t.code,{children:"speculative-exec"})," option that will flag a normal ",(0,s.jsx)(t.code,{children:"put-deploy"})," for execution but not commitment to global state. The following command shows an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncasper client put-deploy /\n--node-address <HOST:PORT> /\n--chain-name <CHAIN_NAME> /\n--secret-key <PATH> /\n--session-path <PATH> /\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES>\n--speculative-exec <BLOCK HEIGHT OR HASH>\n\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You should receive ",(0,s.jsx)(t.code,{children:"execution_result"}),"s that show a ",(0,s.jsx)(t.code,{children:"cost"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n <Deploy effects removed for conciseness.>\n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Cost estimates acquired through ",(0,s.jsx)(t.code,{children:"speculative_exec"})," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary."]})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d262e04.8ce8efde.js b/assets/js/3d262e04.8ce8efde.js new file mode 100644 index 000000000..0b8cfc686 --- /dev/null +++ b/assets/js/3d262e04.8ce8efde.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49105],{62672:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="SDK Client Library Usage",i={id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/2.0.0/developers/dapps/sdk/client-library-usage",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/2.0.0/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/2.0.0/developers/dapps/sdk/script-sdk"}},l={},o=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sdk-client-library-usage",children:"SDK Client Library Usage"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-sdks",children:"Installing the SDKs"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"npm"})," or ",(0,t.jsx)(n.code,{children:"yarn"})," to install the ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-js-sdk",children:"casper-js-sdk"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn install casper-js-sdk\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:(0,t.jsx)(n.code,{children:"pip"})})," to install the ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pycspr/",children:"pycspr"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install pycspr\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Include the casper-client dependency to your ",(0,t.jsx)(n.code,{children:"Cargo.toml"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ncasper-client="1.5.1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["and add it to your ",(0,t.jsx)(n.code,{children:"main.rs"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"extern crate casper_client;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Use types and methods from casper_client:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n"})}),"\n",(0,t.jsx)(n.p,{children:"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"creating-accounts",children:"Creating Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-account-keys",children:"Creating new account keys"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Create a keypair and write the files to a specified ",(0,t.jsx)(n.code,{children:"PATH"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"exporting-the-public-key-and-account-hash",children:"Exporting the public key and account hash"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"keypair"})," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"accountHashHex"}),' will be prefixed with the text "account-hash-".']}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"uploading-the-secret-key-from-a-file",children:"Uploading the secret key from a file"}),"\n",(0,t.jsx)(n.p,{children:"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.p,{children:"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"transferring-cspr",children:"Transferring CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"keypair"})," created ",(0,t.jsx)(n.a,{href:"#creating-accounts",children:"above"}),", you can sign a deploy that transfers CSPR."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\n\nconst amount = 2.5e9 // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper" // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(\n amount,\n recipientPublicKeyHex\n);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installing-contracts",children:"Installing Contracts"}),"\n",(0,t.jsx)(n.p,{children:"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")\nconst fs = require("fs")\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "argument": CLValueBuilder.string("Hello world!")\n})\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair]\n)\n\nconsole.log(await casperClient.putDeploy(deploy))\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, assuming that you cloned ",(0,t.jsx)(n.code,{children:"casper-node"})," from your project's root directory, ",(0,t.jsx)(n.code,{children:"cd"})," back into it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ../\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now in your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n \n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n \n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts",children:"Calling Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash(\n\t"hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"\n);\nconst runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string("Hello world!")\n})\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair]\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy))\n})();\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"staking-1",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d90f760.85ca88d2.js b/assets/js/3d90f760.85ca88d2.js new file mode 100644 index 000000000..a1710f841 --- /dev/null +++ b/assets/js/3d90f760.85ca88d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70186],{94150:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var n=i(74848),a=i(28453);const s={id:"disclaimer",title:"Disclaimer"},r="Disclaimer {#disclaimer}",o={id:"disclaimer",title:"Disclaimer",description:"disclaimer}",source:"@site/versioned_docs/version-1.5.X/disclaimer.md",sourceDirName:".",slug:"/disclaimer",permalink:"/1.5.X/disclaimer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{id:"disclaimer",title:"Disclaimer"}},c={},h=[{value:"Preliminary Nature of this Whitepaper",id:"preliminary-nature-of-this-whitepaper",level:4},{value:"Forward-Looking Statements",id:"forward-looking-statements",level:4},{value:"Risk Factors",id:"risk-factors",level:4}];function d(e){const t={h1:"h1",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"disclaimer",children:"Disclaimer"})}),"\n",(0,n.jsx)(t.p,{children:'By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR\u201d). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO\u201d) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA\u201d) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA\u201d) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.'}),"\n",(0,n.jsx)(t.p,{children:'The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC\u201d). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.'}),"\n",(0,n.jsx)(t.p,{children:"The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required."}),"\n",(0,n.jsx)(t.p,{children:"No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient\u2019s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature."}),"\n",(0,n.jsx)(t.h4,{id:"preliminary-nature-of-this-whitepaper",children:"Preliminary Nature of this Whitepaper"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA\u201d). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.'}),"\n",(0,n.jsx)(t.h4,{id:"forward-looking-statements",children:"Forward-Looking Statements"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper includes "forward-looking statements\u201d, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe\u201d, "anticipate\u201d, "expect\u201d, "project\u201d, "estimate\u201d, "predict\u201d, "intend\u201d, "target\u201d, "assume\u201d, "may\u201d, "might\u201d, "could\u201d, "should\u201d, "will\u201d and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 present and future expectations regarding the development of the Casper blockchain and the associated software.'}),"\n",(0,n.jsx)(t.p,{children:"These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based."}),"\n",(0,n.jsx)(t.h4,{id:"risk-factors",children:"Risk Factors"}),"\n",(0,n.jsx)(t.p,{children:'Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient\u201d) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.'}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CasperLabs Networks AG\u2019s experience"}),": the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CSPR relative value"}),": the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with (intellectual) property rights"}),": the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with blockchain"}),": the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risk of weaknesses in the field of cryptography"}),": the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Regulatory risks"}),": the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with abandonment / lack of success"}),": the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a loss of private key"}),": the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient\u2019s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient\u2019s account (address) will be unrecoverable and will be permanently lost."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with wallets"}),": the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with theft/hacks"}),": the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with mining attacks"}),": the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a lack of consensus"}),": the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with liquidity of CSPR"}),": the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with forking"}),": the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient\u2019s CSPR (if and when created and/or issued)."]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>o});var n=i(96540);const a={},s=n.createContext(a);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d90f760.a5aed92d.js b/assets/js/3d90f760.a5aed92d.js deleted file mode 100644 index 335a5481e..000000000 --- a/assets/js/3d90f760.a5aed92d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[186],{94150:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var n=i(74848),a=i(28453);const s={id:"disclaimer",title:"Disclaimer"},r="Disclaimer {#disclaimer}",o={id:"disclaimer",title:"Disclaimer",description:"disclaimer}",source:"@site/versioned_docs/version-1.5.X/disclaimer.md",sourceDirName:".",slug:"/disclaimer",permalink:"/disclaimer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{id:"disclaimer",title:"Disclaimer"}},c={},h=[{value:"Preliminary Nature of this Whitepaper",id:"preliminary-nature-of-this-whitepaper",level:4},{value:"Forward-Looking Statements",id:"forward-looking-statements",level:4},{value:"Risk Factors",id:"risk-factors",level:4}];function d(e){const t={h1:"h1",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"disclaimer",children:"Disclaimer"})}),"\n",(0,n.jsx)(t.p,{children:'By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR\u201d). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO\u201d) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA\u201d) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA\u201d) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.'}),"\n",(0,n.jsx)(t.p,{children:'The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC\u201d). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.'}),"\n",(0,n.jsx)(t.p,{children:"The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required."}),"\n",(0,n.jsx)(t.p,{children:"No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient\u2019s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature."}),"\n",(0,n.jsx)(t.h4,{id:"preliminary-nature-of-this-whitepaper",children:"Preliminary Nature of this Whitepaper"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA\u201d). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.'}),"\n",(0,n.jsx)(t.h4,{id:"forward-looking-statements",children:"Forward-Looking Statements"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper includes "forward-looking statements\u201d, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe\u201d, "anticipate\u201d, "expect\u201d, "project\u201d, "estimate\u201d, "predict\u201d, "intend\u201d, "target\u201d, "assume\u201d, "may\u201d, "might\u201d, "could\u201d, "should\u201d, "will\u201d and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 present and future expectations regarding the development of the Casper blockchain and the associated software.'}),"\n",(0,n.jsx)(t.p,{children:"These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based."}),"\n",(0,n.jsx)(t.h4,{id:"risk-factors",children:"Risk Factors"}),"\n",(0,n.jsx)(t.p,{children:'Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient\u201d) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.'}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CasperLabs Networks AG\u2019s experience"}),": the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CSPR relative value"}),": the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with (intellectual) property rights"}),": the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with blockchain"}),": the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risk of weaknesses in the field of cryptography"}),": the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Regulatory risks"}),": the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with abandonment / lack of success"}),": the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a loss of private key"}),": the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient\u2019s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient\u2019s account (address) will be unrecoverable and will be permanently lost."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with wallets"}),": the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with theft/hacks"}),": the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with mining attacks"}),": the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a lack of consensus"}),": the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with liquidity of CSPR"}),": the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with forking"}),": the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient\u2019s CSPR (if and when created and/or issued)."]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>o});var n=i(96540);const a={},s=n.createContext(a);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3d9ade7d.23253525.js b/assets/js/3d9ade7d.23253525.js new file mode 100644 index 000000000..6280b6f2d --- /dev/null +++ b/assets/js/3d9ade7d.23253525.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83184],{57155:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),a=t(28453);const i={title:"Delegating Tokens"},d="Delegating with the Casper Client",r={id:"developers/cli/delegate",title:"Delegating Tokens",description:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.",source:"@site/versioned_docs/version-2.0.0/developers/cli/delegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/delegate",permalink:"/2.0.0/developers/cli/delegate",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Delegating Tokens"},sidebar:"developers",previous:{title:"Verifying a Transfer",permalink:"/2.0.0/developers/cli/transfers/verify-transfer"},next:{title:"Redelegating Tokens with the Casper Client",permalink:"/2.0.0/developers/cli/redelegate"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Acquiring a Validator's Public Key",id:"acquiring-a-validators-public-key",level:3},{value:"Sending the Delegation Request",id:"sending-the-delegation-request",level:2},{value:"Method 1: Delegating with the System Auction Contract",id:"delegating-system-auction",level:3},{value:"Method 2: Delegating with Compiled Wasm",id:"delegating-compiled-wasm",level:3},{value:"Building the delegation Wasm",id:"building-the-delegation-wasm",level:4},{value:"Sending the delegation request",id:"sending-the-delegation-wasm-request",level:4},{value:"Confirming the Delegation",id:"confirming-the-delegation",level:2},{value:"Checking Validator Status",id:"checking-validator-status",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"delegating-with-the-casper-client",children:"Delegating with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all prerequisites listed ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"here"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"installed a smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"}),"\n",(0,s.jsxs)(n.p,{children:["This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate#sending-the-delegation-request",children:"delegation request"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process."}),"\n",(0,s.jsx)(n.p,{children:"The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set."}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-delegation-request",children:"Sending the Delegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"The minimum amount to delegate is 500 CSPR (500,000,000,000 motes)."})}),"\n",(0,s.jsx)(n.h3,{id:"delegating-system-auction",children:"Method 1: Delegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 500 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"delegating-compiled-wasm",children:"Method 2: Delegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a delegation is to compile the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," and send it to the network via a deploy. Here are the steps to compile the contract yourself."]}),"\n",(0,s.jsx)(n.h4,{id:"building-the-delegation-wasm",children:"Building the delegation Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Obtain the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," by cloning the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Prepare the Rust environment and then build the contracts using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/Makefile",children:"Makefile"})," provided in the repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Once you build the contracts, you can use the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,s.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release/"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ls target/wasm32-unknown-unknown/release/delegate.wasm\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-delegation-wasm-request",children:"Sending the delegation request"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, we use the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to the network to initiate the delegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/delegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"confirming-the-delegation",children:"Confirming the Delegation"}),"\n",(0,s.jsxs)(n.p,{children:["A Casper network maintains an ",(0,s.jsx)(n.em,{children:"auction"})," where validators ",(0,s.jsx)(n.em,{children:"bid"})," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Your delegation is part of the ",(0,s.jsx)(n.em,{children:"bid"})," to the ",(0,s.jsx)(n.em,{children:"auction"})]}),"\n",(0,s.jsxs)(n.li,{children:["The validator is part of the ",(0,s.jsx)(n.em,{children:"active"})," validator set"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"get-auction-info"})," call will return all the bids currently in the auction contract and the list of active validators for ",(0,s.jsx)(n.code,{children:"4"})," future eras from the present era."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a sample of the ",(0,s.jsx)(n.code,{children:"bids"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,s.jsx)(n.code,{children:"bid"})," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure."]}),"\n",(0,s.jsx)(n.h4,{id:"checking-validator-status",children:"Checking Validator Status"}),"\n",(0,s.jsxs)(n.p,{children:["The auction maintains a field called ",(0,s.jsx)(n.code,{children:"era_validators"}),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,s.jsx)(n.code,{children:"PublicKeys"})," of the active validators for that era, along with their stake in the network."]}),"\n",(0,s.jsxs)(n.p,{children:["If a validator is part of the set, its public key will be in the ",(0,s.jsx)(n.code,{children:"era_validators"})," field as part of the ",(0,s.jsx)(n.code,{children:"Auction"})," data structure returned by ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In the response, check the ",(0,s.jsx)(n.code,{children:'"auction_state"."era_validators"'})," structure, which should contain the public key of the selected validator for the era in which the validator will be active."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is an example of the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the above example, we see the public keys of the active validators in Era ",(0,s.jsx)(n.code,{children:"9"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3db2ed27.9501e9bc.js b/assets/js/3db2ed27.9501e9bc.js new file mode 100644 index 000000000..e2fbd69e7 --- /dev/null +++ b/assets/js/3db2ed27.9501e9bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[712],{26761:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=o(74848),s=o(28453);const r={title:"Staging Files"},t="Staging Files for a New Network",c={id:"operators/setup-network/staging-files-for-new-network",title:"Staging Files",description:"Staging files is not needed for already established running networks.",source:"@site/versioned_docs/version-2.0.0/operators/setup-network/staging-files-for-new-network.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/staging-files-for-new-network",permalink:"/2.0.0/operators/setup-network/staging-files-for-new-network",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Staging Files"},sidebar:"operators",previous:{title:"Private Network Setup",permalink:"/2.0.0/operators/setup-network/create-private"},next:{title:"Node Maintenance",permalink:"/2.0.0/operators/maintenance/"}},l={},d=[{value:"Hosting Server",id:"hosting-server",level:2},{value:"More on <code>protocol_versions</code>",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"staging-files-for-a-new-network",children:"Staging Files for a New Network"})}),"\n",(0,i.jsxs)(n.admonition,{type:"important",children:[(0,i.jsx)(n.p,{children:"Staging files is not needed for already established running networks."}),(0,i.jsx)(n.p,{children:"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network."})]}),"\n",(0,i.jsx)(n.h2,{id:"hosting-server",children:"Hosting Server"}),"\n",(0,i.jsx)(n.p,{children:"Files for staging protocol versions are hosted on a typical HTTP(S) server."}),"\n",(0,i.jsxs)(n.p,{children:["Scripts included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."]}),"\n",(0,i.jsx)(n.p,{children:"Since a given server can be used for multiple networks, a network named directory is used to\nhold files for that network."}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of Mainnet protocol version hosting (with network name: ",(0,i.jsx)(n.code,{children:"casper"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"genesis.casperlab.io"})," is the web server URL with the following directory structure:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"protocol_versions"})," - File listing active protocol versions so scripts know what directories to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0"})," - Genesis protocol version\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_1_0"})," - First upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_1_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_1_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"... (skipping many other protocol versions)"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_4_6"})," - A later upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_4_6"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_4_6"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"more-on-protocol_versions",children:["More on ",(0,i.jsx)(n.code,{children:"protocol_versions"})]}),"\n",(0,i.jsxs)(n.p,{children:["At the root of the hosting server directory for a given network, a ",(0,i.jsx)(n.code,{children:"protocol_versions"})," file exists. This holds the valid protocol versions for a network."]}),"\n",(0,i.jsxs)(n.p,{children:["We can look at this manually on Mainnet using ",(0,i.jsx)(n.em,{children:"curl"}),". As of writing this, ",(0,i.jsx)(n.code,{children:"1.4.6"})," is the latest version and the contents of this file will change."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We should find ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," in those directories under ",(0,i.jsx)(n.code,{children:"casper"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["The protocol version of a network is not related to the ",(0,i.jsx)(n.code,{children:"casper-node"})," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.jsx)(n.code,{children:"casper-node"})," version for your\n",(0,i.jsx)(n.code,{children:"1.0.0"})," protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"network-configuration-file",children:"Network Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," package is installed, both ",(0,i.jsx)(n.code,{children:"casper.conf"})," and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," are installed\nin ",(0,i.jsx)(n.code,{children:"/etc/casper/network_configs"}),". Once a valid config file for a new network is copied to this location,\nall commands with ",(0,i.jsx)(n.em,{children:"node_util.py"})," will work as they do on existing networks."]}),"\n",(0,i.jsxs)(n.p,{children:["By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.jsx)(n.code,{children:"casper"})," and we use\n",(0,i.jsx)(n.code,{children:"casper.conf"})," for the config file."]}),"\n",(0,i.jsxs)(n.p,{children:["For a new network using server ",(0,i.jsx)(n.code,{children:"casper.mydomain.com"})," to host files for ",(0,i.jsx)(n.code,{children:"our-network"})," network, we would have a\n",(0,i.jsx)(n.code,{children:"our-network.conf"})," file that looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Host this ",(0,i.jsx)(n.code,{children:"our-network.conf"})," in the root of ",(0,i.jsx)(n.code,{children:"casper.mydomain.com/our-network"})," at the same level as ",(0,i.jsx)(n.code,{children:"protocol_versions"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This allows any node which wants to use the new network to run the following to install this configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any command needing a network config from ",(0,i.jsx)(n.code,{children:"node_util.py"})," can use ",(0,i.jsx)(n.code,{children:"our-network.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n"})}),"\n",(0,i.jsx)(n.h2,{id:"setup-configuration-files",children:"Setup Configuration Files"}),"\n",(0,i.jsx)(n.p,{children:"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."}),"\n",(0,i.jsx)(n.h3,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"})," file is configuration for the network and must be exactly the same on all nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["The name for a network is specified ",(0,i.jsx)(n.code,{children:"network.name"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Each protocol will have a ",(0,i.jsx)(n.code,{children:"version"})," and ",(0,i.jsx)(n.code,{children:"activation_point"}),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.jsx)(n.code,{children:"era_id"})," for activation of the upgrade."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"config-exampletoml",children:"config-example.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.jsx)(n.code,{children:"public_address"})," is auto-detected with ",(0,i.jsx)(n.code,{children:"node_util.py stage_protocols"}),". If using a NAT environment, the public IP can be specified with the ",(0,i.jsx)(n.code,{children:"--ip"})," argument."]}),"\n",(0,i.jsxs)(n.p,{children:["This file should have ",(0,i.jsx)(n.code,{children:"known_addresses"})," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[network]\nknown_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.toml"})," can be setup to customized fields for a given node. ",(0,i.jsx)(n.code,{children:"config-example.toml"})," is a default configuration."]}),"\n",(0,i.jsx)(n.h2,{id:"staging-a-protocol-version",children:"Staging a Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["For the initial genesis protocol version or future upgrade protocol versions, you will typically use\nprebuilt and tested ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," that have been tested and staged for existing networks. The ",(0,i.jsx)(n.code,{children:"config.tar.gz"}),"\nfile must be customized for the specific network with a network name, protocol version and activation point at the very least."]}),"\n",(0,i.jsxs)(n.p,{children:["These archives should be created with no directory information stored. This is done by using ",(0,i.jsx)(n.code,{children:"tar"})," in the same directory as the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can test what was compressed with untar'ing the file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will expand files for verification."}),"\n",(0,i.jsxs)(n.p,{children:["For custom ",(0,i.jsx)(n.code,{children:"casper-node"})," builds, the minimum contents of ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," is the ",(0,i.jsx)(n.code,{children:"casper-node"})," executable."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A directory for the protocol_version will be created on the server. For example: ",(0,i.jsx)(n.code,{children:"1_1_0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will copy ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," into ",(0,i.jsx)(n.code,{children:"1_1_0"}),". Once this is done, we are safe to update\n",(0,i.jsx)(n.code,{children:"protocol_versions"})," by appending ",(0,i.jsx)(n.code,{children:"1_1_0"})," to the end of the file and uploading it into the root of the network directory."]}),"\n",(0,i.jsx)(n.p,{children:"Any node that runs the following command will get this new upgrade:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>c});var i=o(96540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e796ac9.77cf76db.js b/assets/js/3e796ac9.77cf76db.js new file mode 100644 index 000000000..8a7d03023 --- /dev/null +++ b/assets/js/3e796ac9.77cf76db.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15680],{98619:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var s=n(74848),a=n(28453);const c={title:"Addressable Entities"},i="Addressable Entities",r={id:"concepts/addressable-entity",title:"Addressable Entities",description:"What is an Addressable Entity?",source:"@site/docs/concepts/addressable-entity.md",sourceDirName:"concepts",slug:"/concepts/addressable-entity",permalink:"/concepts/addressable-entity",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725545028e3,frontMatter:{title:"Addressable Entities"},sidebar:"concepts",previous:{title:"dApps",permalink:"/concepts/intro-to-dapps"},next:{title:"Accounts and Keys",permalink:"/concepts/accounts-and-keys"}},d={},o=[{value:"What is an Addressable Entity?",id:"what-is-an-addressable-entity",level:2},{value:"Account",id:"account",level:2},{value:"SmartContract",id:"smartcontract",level:2},{value:"System",id:"system",level:2},{value:"Further Reading",id:"further-reading",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"addressable-entities",children:"Addressable Entities"})}),"\n",(0,s.jsx)(t.h2,{id:"what-is-an-addressable-entity",children:"What is an Addressable Entity?"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system.\nCasper 2.0 introduces the concept of an ",(0,s.jsx)(t.a,{href:"/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," which replaces the existing ",(0,s.jsx)(t.a,{href:"/concepts/glossary/A#account",children:(0,s.jsx)(t.code,{children:"Account"})})," and ",(0,s.jsx)(t.a,{href:"/concepts/glossary/S#smart-contract",children:(0,s.jsx)(t.code,{children:"Contract"})})," types."]}),"\n",(0,s.jsxs)(t.p,{children:["The merger of the ",(0,s.jsx)(t.code,{children:"Account"})," and ",(0,s.jsx)(t.code,{children:"Contract"})," concepts allows for some new possibilities."]}),"\n",(0,s.jsxs)(t.p,{children:["For any given ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", the ",(0,s.jsx)(t.code,{children:"EntityType"})," will identify if it is an ",(0,s.jsx)(t.code,{children:"Account"}),", a user-deployed ",(0,s.jsx)(t.code,{children:"SmartContract"}),", or a ",(0,s.jsx)(t.code,{children:"System"})," contract such as ",(0,s.jsx)(t.code,{children:"Mint"})," or ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.code,{children:"EntityType"})," will dictate what the addressable entity can and cannot do."]}),"\n",(0,s.jsx)(t.h2,{id:"account",children:"Account"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as an ",(0,s.jsx)(t.code,{children:"Account"})," will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a ",(0,s.jsx)(t.code,{children:"PublicKey"})," and a secret key, and an ",(0,s.jsx)(t.code,{children:"AccountHash"})," derived from the public key. There is also an associated main purse."]}),"\n",(0,s.jsx)(t.p,{children:"A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same."}),"\n",(0,s.jsx)(t.h2,{id:"smartcontract",children:"SmartContract"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as a ",(0,s.jsx)(t.code,{children:"SmartContract"})," will have the same functionality as a legacy contract, but with several new features. The ",(0,s.jsx)(t.code,{children:"SmartContract"})," now possesses a main purse, and may have ",(0,s.jsx)(t.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys"})," and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found ",(0,s.jsx)(t.a,{href:"/resources/advanced/multi-sig/multi-sig-workflow",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"system",children:"System"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the migration to Casper 2.0, system contracts (",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"})," and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),") will migrate to a special type of addressable entity with the ",(0,s.jsx)(t.code,{children:"EntityType"})," of ",(0,s.jsx)(t.code,{children:"System"}),". The ",(0,s.jsx)(t.code,{children:"StandardPayment"})," system contract will be pruned away."]}),"\n",(0,s.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Keys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/key-types",children:"Hash Types"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/advanced/multi-sig/",children:"Multi-Signature Management"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const a={},c=s.createContext(a);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3e796ac9.d85b7445.js b/assets/js/3e796ac9.d85b7445.js deleted file mode 100644 index b14ac9d84..000000000 --- a/assets/js/3e796ac9.d85b7445.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5680],{98619:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var s=n(74848),a=n(28453);const c={title:"Addressable Entities"},i="Addressable Entities",r={id:"concepts/addressable-entity",title:"Addressable Entities",description:"What is an Addressable Entity?",source:"@site/docs/concepts/addressable-entity.md",sourceDirName:"concepts",slug:"/concepts/addressable-entity",permalink:"/next/concepts/addressable-entity",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725545028e3,frontMatter:{title:"Addressable Entities"},sidebar:"concepts",previous:{title:"dApps",permalink:"/next/concepts/intro-to-dapps"},next:{title:"Accounts and Keys",permalink:"/next/concepts/accounts-and-keys"}},d={},o=[{value:"What is an Addressable Entity?",id:"what-is-an-addressable-entity",level:2},{value:"Account",id:"account",level:2},{value:"SmartContract",id:"smartcontract",level:2},{value:"System",id:"system",level:2},{value:"Further Reading",id:"further-reading",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"addressable-entities",children:"Addressable Entities"})}),"\n",(0,s.jsx)(t.h2,{id:"what-is-an-addressable-entity",children:"What is an Addressable Entity?"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system.\nCasper 2.0 introduces the concept of an ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," which replaces the existing ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/A#account",children:(0,s.jsx)(t.code,{children:"Account"})})," and ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/S#smart-contract",children:(0,s.jsx)(t.code,{children:"Contract"})})," types."]}),"\n",(0,s.jsxs)(t.p,{children:["The merger of the ",(0,s.jsx)(t.code,{children:"Account"})," and ",(0,s.jsx)(t.code,{children:"Contract"})," concepts allows for some new possibilities."]}),"\n",(0,s.jsxs)(t.p,{children:["For any given ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", the ",(0,s.jsx)(t.code,{children:"EntityType"})," will identify if it is an ",(0,s.jsx)(t.code,{children:"Account"}),", a user-deployed ",(0,s.jsx)(t.code,{children:"SmartContract"}),", or a ",(0,s.jsx)(t.code,{children:"System"})," contract such as ",(0,s.jsx)(t.code,{children:"Mint"})," or ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.code,{children:"EntityType"})," will dictate what the addressable entity can and cannot do."]}),"\n",(0,s.jsx)(t.h2,{id:"account",children:"Account"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as an ",(0,s.jsx)(t.code,{children:"Account"})," will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a ",(0,s.jsx)(t.code,{children:"PublicKey"})," and a secret key, and an ",(0,s.jsx)(t.code,{children:"AccountHash"})," derived from the public key. There is also an associated main purse."]}),"\n",(0,s.jsx)(t.p,{children:"A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same."}),"\n",(0,s.jsx)(t.h2,{id:"smartcontract",children:"SmartContract"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as a ",(0,s.jsx)(t.code,{children:"SmartContract"})," will have the same functionality as a legacy contract, but with several new features. The ",(0,s.jsx)(t.code,{children:"SmartContract"})," now possesses a main purse, and may have ",(0,s.jsx)(t.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys"})," and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found ",(0,s.jsx)(t.a,{href:"/next/resources/advanced/multi-sig/multi-sig-workflow",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"system",children:"System"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the migration to Casper 2.0, system contracts (",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"})," and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),") will migrate to a special type of addressable entity with the ",(0,s.jsx)(t.code,{children:"EntityType"})," of ",(0,s.jsx)(t.code,{children:"System"}),". The ",(0,s.jsx)(t.code,{children:"StandardPayment"})," system contract will be pruned away."]}),"\n",(0,s.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/accounts-and-keys",children:"Accounts and Keys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/key-types",children:"Hash Types"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/resources/advanced/multi-sig/",children:"Multi-Signature Management"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const a={},c=s.createContext(a);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3efe71e8.3d46f3c7.js b/assets/js/3efe71e8.3d46f3c7.js new file mode 100644 index 000000000..e09db6ab9 --- /dev/null +++ b/assets/js/3efe71e8.3d46f3c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87559],{63768:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="L",a={id:"concepts/glossary/L",title:"L",description:"---",source:"@site/docs/concepts/glossary/L.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/L",permalink:"/concepts/glossary/L",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"K",permalink:"/concepts/glossary/K"},next:{title:"M",permalink:"/concepts/glossary/M"}},l={},h=[{value:"Liveness",id:"liveness",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"l",children:"L"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"liveness",children:"Liveness"}),"\n",(0,n.jsx)(e.p,{children:"A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions)."}),"\n",(0,n.jsx)(e.p,{children:"If the protocol is not live, the blockchain does not grow anymore, and the network stalls."})]})}function p(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/3efe71e8.65395bbf.js b/assets/js/3efe71e8.65395bbf.js deleted file mode 100644 index c0aa0ddf7..000000000 --- a/assets/js/3efe71e8.65395bbf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7559],{63768:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>x,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="L",a={id:"concepts/glossary/L",title:"L",description:"---",source:"@site/docs/concepts/glossary/L.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/L",permalink:"/next/concepts/glossary/L",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"K",permalink:"/next/concepts/glossary/K"},next:{title:"M",permalink:"/next/concepts/glossary/M"}},l={},h=[{value:"Liveness",id:"liveness",level:2}];function i(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"l",children:"L"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"liveness",children:"Liveness"}),"\n",(0,r.jsx)(s.p,{children:"A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions)."}),"\n",(0,r.jsx)(s.p,{children:"If the protocol is not live, the blockchain does not grow anymore, and the network stalls."})]})}function x(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3fe76c6c.09dd3645.js b/assets/js/3fe76c6c.09dd3645.js new file mode 100644 index 000000000..5c241c7af --- /dev/null +++ b/assets/js/3fe76c6c.09dd3645.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59672],{19259:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=n(74848),o=n(28453);const a={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/walkthrough.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/walkthrough",permalink:"/1.5.X/resources/beginner/counter/walkthrough",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/1.5.X/resources/beginner/counter/commands"},next:{title:"Introduction",permalink:"/1.5.X/counter-testnet"}},i={},l=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"Create a Local Network",id:"create-a-local-network",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are three versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"contract-v1"})})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["It defines two named keys:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"counter"}),": References the contract itself."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"count"}),": Stores the current counter value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["It provides functions for:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"get_count"}),": Retrieves the current counter value."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"counter_inc"}),": Increments the counter value by 1."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"contract-v2"})})," (Not Used in This Tutorial)"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["An extension of ",(0,s.jsx)(t.code,{children:"contract-v1"}),". It demonstrates decrementing the counter and contract upgrades."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["**",(0,s.jsx)(t.code,{children:"contract-v3"})," ** (Not Used in This Tutorial)"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["This version showcases how to add new functionalities during smart contract upgrades. It extends ",(0,s.jsx)(t.code,{children:"contract-v1"})," and ",(0,s.jsx)(t.code,{children:"contract-v2"})," by introducing:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["A new named key: ",(0,s.jsx)(t.code,{children:"last_updated_at"})," - Tracks the timestamp of the last counter update."]}),"\n",(0,s.jsxs)(t.li,{children:["A new entry point: ",(0,s.jsx)(t.code,{children:"get_last_updated_at"})," - Retrieves the ",(0,s.jsx)(t.code,{children:"last_updated_at"})," timestamp."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["It focuses on the process of adding new fields like ",(0,s.jsx)(t.code,{children:"last_updated_at"})," to existing contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.code,{children:"counter-call"})})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Session code that retrieves the specific contract version (e.g., ",(0,s.jsx)(t.code,{children:"contract-v1"}),"), interacts with its functions (e.g., ",(0,s.jsx)(t.code,{children:"get_count"}),", ",(0,s.jsx)(t.code,{children:"counter_inc"}),"), and verifies the expected behavior."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"create-a-local-network",children:"Create a Local Network"}),"\n",(0,s.jsx)(t.p,{children:"After getting familiar with the counter source code, you need to create a local Casper network to install the contract. If you completed the NCTL tutorial, all you need to do is allocate the network assets and then start the network."}),"\n",(0,s.jsx)(t.p,{children:"If you run the following line in your terminal, you should be able to spin up a network effortlessly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["If it fails for any reason, please refer the ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"NCTL tutorial"})," and make sure that all your packages are up to date."]})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"AccountHash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"nctl-view-faucet-account"})," - Get the faucet's account hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state root hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," - Get the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If NCTL is correctly up and running, this command should return quite a bit of information about the faucet account. Feel free to look through the records and make a note of the ",(0,s.jsx)(t.em,{children:"account-hash"})," field and the ",(0,s.jsx)(t.em,{children:"secret_key.pem"})," path because you will often use both."]}),"\n",(0,s.jsx)(t.p,{children:"Get the state root hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You are using localhost as the node server since the network is running on our local machine. Make a note of the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," that is returned, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored. It is one of the fields that gets returned when you call ",(0,s.jsx)(t.em,{children:"nctl-view-faucet-account"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to install the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on your local network!"})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const o={},a=s.createContext(o);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/40078125.92fe6e66.js b/assets/js/40078125.92fe6e66.js new file mode 100644 index 000000000..4c79096bd --- /dev/null +++ b/assets/js/40078125.92fe6e66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36194],{69403:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>d,default:()=>a,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"The Chainspec"},d="The Blockchain Specification {#the-chain-specification}",c={id:"operators/setup-network/chain-spec",title:"The Chainspec",description:"the-chain-specification}",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/chain-spec.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/chain-spec",permalink:"/1.5.X/operators/setup-network/chain-spec",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"The Chainspec"},sidebar:"operators",previous:{title:"Genesis",permalink:"/1.5.X/operators/setup-network/genesis"},next:{title:"Private Network Setup",permalink:"/1.5.X/operators/setup-network/create-private"}},l={},o=[{value:"protocol",id:"protocol",level:2},{value:"network",id:"network",level:2},{value:"core",id:"core",level:2},{value:"highway",id:"highway",level:2},{value:"deploys",id:"deploys",level:2},{value:"wasm",id:"wasm",level:2},{value:"wasm.storage_costs",id:"wasmstorage_costs",level:3},{value:"wasm.opcode_costs",id:"wasmopcode_costs",level:3},{value:"wasm.opcode_costs.control_flow",id:"wasmopcode_costscontrol_flow",level:3},{value:"wasm.opcode_costs.control_flow.br_table",id:"wasmopcode_costscontrol_flowbr_table",level:3},{value:"wasm.host_function_costs",id:"wasmhost_function_costs",level:3},{value:"system_costs",id:"system_costs",level:2},{value:"system_costs.auction_costs",id:"system_costsauction_costs",level:3},{value:"system_costs.mint_costs",id:"system_costsmint_costs",level:3},{value:"system_costs.handle_payment_costs",id:"system_costshandle_payment_costs",level:3},{value:"system_costs.standard_payment_costs",id:"system_costsstandard_payment_costs",level:3}];function h(n){const e={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"the-chain-specification",children:"The Blockchain Specification"})}),"\n",(0,s.jsxs)(e.p,{children:["The blockchain specification, or ",(0,s.jsx)(e.code,{children:"chainspec"}),", is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on ",(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"version 1.5.2"})," of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring."]}),"\n",(0,s.jsx)(e.h2,{id:"protocol",children:"protocol"}),"\n",(0,s.jsx)(e.p,{children:"These settings describe the active protocol version."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"version"}),(0,s.jsx)(e.td,{children:"The Casper node protocol version."}),(0,s.jsx)(e.td,{children:"'1.5.2'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"hard_reset"}),(0,s.jsx)(e.td,{children:"When set to true, clear blocks and deploys back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activation_point"}),(0,s.jsxs)(e.td,{children:["The protocol version that should become active. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 \u2014 see the ",(0,s.jsx)(e.code,{children:"finality_threshold_fraction"})," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."]}),(0,s.jsx)(e.td,{children:"9100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"network",children:"network"}),"\n",(0,s.jsx)(e.p,{children:"The following settings configure the networking layer."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"name"}),(0,s.jsx)(e.td,{children:"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."}),(0,s.jsx)(e.td,{children:"'casper'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_net_message_size"}),(0,s.jsx)(e.td,{children:"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."}),(0,s.jsx)(e.td,{children:"25_165_824"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"core",children:"core"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage the core protocol behavior."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"era_duration"}),(0,s.jsx)(e.td,{children:"Era duration."}),(0,s.jsx)(e.td,{children:"'120min'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_era_height"}),(0,s.jsxs)(e.td,{children:["Minimum number of blocks per era. An era will take longer than ",(0,s.jsx)(e.code,{children:"era_duration"})," if that is necessary to reach the minimum height."]}),(0,s.jsx)(e.td,{children:"20"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_block_time"}),(0,s.jsx)(e.td,{children:"Minimum difference between a block's and its child's timestamp."}),(0,s.jsx)(e.td,{children:"'16384ms'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_slots"}),(0,s.jsx)(e.td,{children:"Number of slots available in the validator auction."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_threshold_fraction"}),(0,s.jsxs)(e.td,{children:["A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,s.jsx)(e.br,{}),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,s.jsx)(e.br,{}),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."]}),(0,s.jsx)(e.td,{children:"[1, 3]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsxs)(e.td,{children:["start_protocol_version_with_strict",(0,s.jsx)(e.br,{}),"_finality_signatures_required"]}),(0,s.jsx)(e.td,{children:"Protocol version from which nodes are required to hold strict finality signatures."}),(0,s.jsx)(e.td,{children:"'1.5.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"legacy_required_finality"}),(0,s.jsxs)(e.td,{children:["The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,s.jsx)(e.br,{}),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."]}),(0,s.jsx)(e.td,{children:"'Strict'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"auction_delay"}),(0,s.jsx)(e.td,{children:"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."}),(0,s.jsx)(e.td,{children:"1"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"locked_funds_period"}),(0,s.jsx)(e.td,{children:"The period after genesis during which a genesis validator's bid is locked."}),(0,s.jsx)(e.td,{children:"'90days'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"vesting_schedule_period"}),(0,s.jsx)(e.td,{children:"The period in which the genesis validator's bid is released over time after it is unlocked."}),(0,s.jsx)(e.td,{children:"'13 weeks'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unbonding_delay"}),(0,s.jsx)(e.td,{children:"Default number of eras that need to pass to be able to withdraw unbonded funds."}),(0,s.jsx)(e.td,{children:"7"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"round_seigniorage_rate"}),(0,s.jsxs)(e.td,{children:["Round seigniorage rate represented as a fraction of the total supply.",(0,s.jsx)(e.br,{}),"- Annual issuance: 8%.",(0,s.jsx)(e.br,{}),"- Minimum block time: 2^15 milliseconds.",(0,s.jsx)(e.br,{}),"- Ticks per year: 31536000000.",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.code,{children:"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)"})]}),(0,s.jsx)(e.td,{children:"[7, 87535408]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_associated_keys"}),(0,s.jsx)(e.td,{children:"Maximum number of associated keys for a single account."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_runtime_call_stack_height"}),(0,s.jsx)(e.td,{children:"Maximum height of the contract runtime call stack."}),(0,s.jsx)(e.td,{children:"12"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Minimum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"500_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"prune_batch_size"}),(0,s.jsxs)(e.td,{children:["Global state prune batch size for tip pruning in version 1.4.15. Possible values:",(0,s.jsx)(e.br,{}),"- 0 when the feature is OFF",(0,s.jsx)(e.br,{}),"- Integer if the feature is ON, representing the number of eras to process per block."]}),(0,s.jsx)(e.td,{children:"0"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"strict_argument_checking"}),(0,s.jsxs)(e.td,{children:["Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,s.jsx)(e.code,{children:"CLType"}),"."]}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"simultaneous_peer_requests"}),(0,s.jsx)(e.td,{children:"Number of simultaneous peer requests."}),(0,s.jsx)(e.td,{children:"5"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"consensus_protocol"}),(0,s.jsx)(e.td,{children:"The consensus protocol to use. Options are 'Zug' or 'Highway'."}),(0,s.jsx)(e.td,{children:"'Highway'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_delegators_per_validator"}),(0,s.jsx)(e.td,{children:"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."}),(0,s.jsx)(e.td,{children:"1200"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"highway",children:"highway"}),"\n",(0,s.jsx)(e.p,{children:"These settings configure the Highway Consensus protocol."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_round_length"}),(0,s.jsxs)(e.td,{children:["Highway dynamically chooses its round length between ",(0,s.jsx)(e.code,{children:"minimum_block_time"})," and ",(0,s.jsx)(e.code,{children:"maximum_round_length"}),"."]}),(0,s.jsx)(e.td,{children:"'132seconds'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduced_reward_multiplier"}),(0,s.jsx)(e.td,{children:"The factor by which rewards for a round are multiplied if the greatest summit has \u226450% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet)."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"deploys",children:"deploys"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage deploys and their lifecycle."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_payment_cost"}),(0,s.jsx)(e.td,{children:"The maximum number of motes allowed to be spent during payment. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"'0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_ttl"}),(0,s.jsx)(e.td,{children:"The duration after the deploy timestamp during which the deploy can be included in a block."}),(0,s.jsx)(e.td,{children:"'18hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_dependencies"}),(0,s.jsx)(e.td,{children:"The maximum number of other deploys a deploy can depend on (requiring them to have been executed before it can execute)."}),(0,s.jsx)(e.td,{children:"10"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_block_size"}),(0,s.jsx)(e.td,{children:"Maximum block size in bytes, including deploys contained by the block. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"10_485_760"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_deploy_size"}),(0,s.jsx)(e.td,{children:"Maximum deploy size in bytes. Size is of the deploy when serialized via ToBytes."}),(0,s.jsx)(e.td,{children:"1_048_576"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_deploy_count"}),(0,s.jsx)(e.td,{children:"The maximum number of non-transfer deploys permitted in a single block."}),(0,s.jsx)(e.td,{children:"50"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_transfer_count"}),(0,s.jsx)(e.td,{children:"The maximum number of Wasm-less transfer deploys permitted in a single block."}),(0,s.jsx)(e.td,{children:"1250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_approval_count"}),(0,s.jsx)(e.td,{children:"The maximum number of approvals permitted in a single block."}),(0,s.jsx)(e.td,{children:"2600"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_gas_limit"}),(0,s.jsx)(e.td,{children:"The upper limit of the total gas of all deploys in a block."}),(0,s.jsx)(e.td,{children:"4_000_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"payment_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized payment code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"session_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized session code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_transfer_minimum_motes"}),(0,s.jsx)(e.td,{children:"The minimum amount in motes for a valid native transfer."}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasm",children:"wasm"}),"\n",(0,s.jsx)(e.p,{children:"The following are Wasm-related settings."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_memory"}),(0,s.jsx)(e.td,{children:"Amount of free memory (in 64 kB pages) each contract can use for its stack."}),(0,s.jsx)(e.td,{children:"64"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_stack_height"}),(0,s.jsx)(e.td,{children:"Max stack height (native WebAssembly stack limiter)."}),(0,s.jsx)(e.td,{children:"500"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmstorage_costs",children:"wasm.storage_costs"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage Wasm storage costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"630_000"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costs",children:"wasm.opcode_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage the cost table for Wasm opcodes."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flow",children:"wasm.opcode_costs.control_flow"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage costs for control flow operations."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flowbr_table",children:"wasm.opcode_costs.control_flow.br_table"}),"\n",(0,s.jsxs)(e.p,{children:["The following settings manage ",(0,s.jsx)(e.code,{children:"br_table"})," Wasm opcodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmhost_function_costs",children:"wasm.host_function_costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs",children:"smart_contracts/contract/src/ext_ffi.rs"}),"."]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"- add = { cost = 5_800, arguments = [0, 0, 0, 0] }\n- add_associated_key = { cost = 9_000, arguments = [0, 0, 0] }\n- add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }\n- blake2b = { cost = 200, arguments = [0, 0, 0, 0] }\n- call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] }\n- call_versioned_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 0, 0, 420, 0] }\n- create_contract_package_at_hash = { cost = 200, arguments = [0, 0] }\n- create_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }\n- create_purse = { cost = 2_500_000_000, arguments = [0, 0] }\n- disable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] }\n- get_balance = { cost = 3_800, arguments = [0, 0, 0] }\n- get_blocktime = { cost = 330, arguments = [0] }\n- get_caller = { cost = 380, arguments = [0] }\n- get_key = { cost = 2_000, arguments = [0, 440, 0, 0, 0] }\n- get_main_purse = { cost = 1_300, arguments = [0] }\n- get_named_arg = { cost = 200, arguments = [0, 0, 0, 0] }\n- get_named_arg_size = { cost = 200, arguments = [0, 0, 0] }\n- get_phase = { cost = 710, arguments = [0] }\n- get_system_contract = { cost = 1_100, arguments = [0, 0, 0] }\n- has_key = { cost = 1_500, arguments = [0, 840] }\n- is_valid_uref = { cost = 760, arguments = [0, 0] }\n- load_named_keys = { cost = 42_000, arguments = [0, 0] }\n- new_uref = { cost = 17_000, arguments = [0, 0, 590] }\n- random_bytes = { cost = 200, arguments = [0, 0] }\n- print = { cost = 20_000, arguments = [0, 4_600] }\n- provision_contract_user_group_uref = { cost = 200, arguments = [0, 0, 0, 0, 0] }\n- put_key = { cost = 38_000, arguments = [0, 1_100, 0, 0] }\n- read_host_buffer = { cost = 3_500, arguments = [0, 310, 0] }\n- read_value = { cost = 6_000, arguments = [0, 0, 0] }\n- read_value_local = { cost = 5_500, arguments = [0, 590, 0] }\n- remove_associated_key = { cost = 4_200, arguments = [0, 0] }\n- remove_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0] }\n- remove_contract_user_group_urefs = { cost = 200, arguments = [0, 0, 0, 0, 0, 0] }\n- remove_key = { cost = 61_000, arguments = [0, 3_200] }\n- ret = { cost = 23_000, arguments = [0, 420_000] }\n- revert = { cost = 500, arguments = [0] }\n- set_action_threshold = { cost = 74_000, arguments = [0, 0] }\n- transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] }\n- transfer_from_purse_to_purse = { cost = 82_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }\n- transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] }\n- update_associated_key = { cost = 4_200, arguments = [0, 0, 0] }\n- write = { cost = 14_000, arguments = [0, 0, 0, 980] }\n- write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] }\n"})}),"\n",(0,s.jsx)(e.h2,{id:"system_costs",children:"system_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage protocol operating costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"wasmless_transfer_cost"}),(0,s.jsx)(e.td,{children:"Default gas cost for a wasmless transfer."}),(0,s.jsx)(e.td,{children:"100_000_000"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsauction_costs",children:"system_costs.auction_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsmint_costs",children:"system_costs.mint_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costshandle_payment_costs",children:"system_costs.handle_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsstandard_payment_costs",children:"system_costs.standard_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function a(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(h,{...n})}):h(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>d,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function d(n){const e=s.useContext(i);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:d(n.components),s.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/40078125.bd3a3d60.js b/assets/js/40078125.bd3a3d60.js deleted file mode 100644 index d009e88a8..000000000 --- a/assets/js/40078125.bd3a3d60.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6194],{69403:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>d,default:()=>a,frontMatter:()=>i,metadata:()=>c,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"The Chainspec"},d="The Blockchain Specification {#the-chain-specification}",c={id:"operators/setup-network/chain-spec",title:"The Chainspec",description:"the-chain-specification}",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/chain-spec.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/chain-spec",permalink:"/operators/setup-network/chain-spec",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"The Chainspec"},sidebar:"operators",previous:{title:"Genesis",permalink:"/operators/setup-network/genesis"},next:{title:"Private Network Setup",permalink:"/operators/setup-network/create-private"}},l={},o=[{value:"protocol",id:"protocol",level:2},{value:"network",id:"network",level:2},{value:"core",id:"core",level:2},{value:"highway",id:"highway",level:2},{value:"deploys",id:"deploys",level:2},{value:"wasm",id:"wasm",level:2},{value:"wasm.storage_costs",id:"wasmstorage_costs",level:3},{value:"wasm.opcode_costs",id:"wasmopcode_costs",level:3},{value:"wasm.opcode_costs.control_flow",id:"wasmopcode_costscontrol_flow",level:3},{value:"wasm.opcode_costs.control_flow.br_table",id:"wasmopcode_costscontrol_flowbr_table",level:3},{value:"wasm.host_function_costs",id:"wasmhost_function_costs",level:3},{value:"system_costs",id:"system_costs",level:2},{value:"system_costs.auction_costs",id:"system_costsauction_costs",level:3},{value:"system_costs.mint_costs",id:"system_costsmint_costs",level:3},{value:"system_costs.handle_payment_costs",id:"system_costshandle_payment_costs",level:3},{value:"system_costs.standard_payment_costs",id:"system_costsstandard_payment_costs",level:3}];function h(n){const e={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"the-chain-specification",children:"The Blockchain Specification"})}),"\n",(0,s.jsxs)(e.p,{children:["The blockchain specification, or ",(0,s.jsx)(e.code,{children:"chainspec"}),", is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on ",(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"version 1.5.2"})," of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring."]}),"\n",(0,s.jsx)(e.h2,{id:"protocol",children:"protocol"}),"\n",(0,s.jsx)(e.p,{children:"These settings describe the active protocol version."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"version"}),(0,s.jsx)(e.td,{children:"The Casper node protocol version."}),(0,s.jsx)(e.td,{children:"'1.5.2'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"hard_reset"}),(0,s.jsx)(e.td,{children:"When set to true, clear blocks and deploys back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activation_point"}),(0,s.jsxs)(e.td,{children:["The protocol version that should become active. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 \u2014 see the ",(0,s.jsx)(e.code,{children:"finality_threshold_fraction"})," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."]}),(0,s.jsx)(e.td,{children:"9100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"network",children:"network"}),"\n",(0,s.jsx)(e.p,{children:"The following settings configure the networking layer."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"name"}),(0,s.jsx)(e.td,{children:"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."}),(0,s.jsx)(e.td,{children:"'casper'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_net_message_size"}),(0,s.jsx)(e.td,{children:"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."}),(0,s.jsx)(e.td,{children:"25_165_824"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"core",children:"core"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage the core protocol behavior."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"era_duration"}),(0,s.jsx)(e.td,{children:"Era duration."}),(0,s.jsx)(e.td,{children:"'120min'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_era_height"}),(0,s.jsxs)(e.td,{children:["Minimum number of blocks per era. An era will take longer than ",(0,s.jsx)(e.code,{children:"era_duration"})," if that is necessary to reach the minimum height."]}),(0,s.jsx)(e.td,{children:"20"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_block_time"}),(0,s.jsx)(e.td,{children:"Minimum difference between a block's and its child's timestamp."}),(0,s.jsx)(e.td,{children:"'16384ms'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_slots"}),(0,s.jsx)(e.td,{children:"Number of slots available in the validator auction."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_threshold_fraction"}),(0,s.jsxs)(e.td,{children:["A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,s.jsx)(e.br,{}),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,s.jsx)(e.br,{}),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."]}),(0,s.jsx)(e.td,{children:"[1, 3]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsxs)(e.td,{children:["start_protocol_version_with_strict",(0,s.jsx)(e.br,{}),"_finality_signatures_required"]}),(0,s.jsx)(e.td,{children:"Protocol version from which nodes are required to hold strict finality signatures."}),(0,s.jsx)(e.td,{children:"'1.5.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"legacy_required_finality"}),(0,s.jsxs)(e.td,{children:["The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,s.jsx)(e.br,{}),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."]}),(0,s.jsx)(e.td,{children:"'Strict'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"auction_delay"}),(0,s.jsx)(e.td,{children:"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."}),(0,s.jsx)(e.td,{children:"1"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"locked_funds_period"}),(0,s.jsx)(e.td,{children:"The period after genesis during which a genesis validator's bid is locked."}),(0,s.jsx)(e.td,{children:"'90days'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"vesting_schedule_period"}),(0,s.jsx)(e.td,{children:"The period in which the genesis validator's bid is released over time after it is unlocked."}),(0,s.jsx)(e.td,{children:"'13 weeks'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unbonding_delay"}),(0,s.jsx)(e.td,{children:"Default number of eras that need to pass to be able to withdraw unbonded funds."}),(0,s.jsx)(e.td,{children:"7"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"round_seigniorage_rate"}),(0,s.jsxs)(e.td,{children:["Round seigniorage rate represented as a fraction of the total supply.",(0,s.jsx)(e.br,{}),"- Annual issuance: 8%.",(0,s.jsx)(e.br,{}),"- Minimum block time: 2^15 milliseconds.",(0,s.jsx)(e.br,{}),"- Ticks per year: 31536000000.",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.code,{children:"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)"})]}),(0,s.jsx)(e.td,{children:"[7, 87535408]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_associated_keys"}),(0,s.jsx)(e.td,{children:"Maximum number of associated keys for a single account."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_runtime_call_stack_height"}),(0,s.jsx)(e.td,{children:"Maximum height of the contract runtime call stack."}),(0,s.jsx)(e.td,{children:"12"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Minimum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"500_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"prune_batch_size"}),(0,s.jsxs)(e.td,{children:["Global state prune batch size for tip pruning in version 1.4.15. Possible values:",(0,s.jsx)(e.br,{}),"- 0 when the feature is OFF",(0,s.jsx)(e.br,{}),"- Integer if the feature is ON, representing the number of eras to process per block."]}),(0,s.jsx)(e.td,{children:"0"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"strict_argument_checking"}),(0,s.jsxs)(e.td,{children:["Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,s.jsx)(e.code,{children:"CLType"}),"."]}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"simultaneous_peer_requests"}),(0,s.jsx)(e.td,{children:"Number of simultaneous peer requests."}),(0,s.jsx)(e.td,{children:"5"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"consensus_protocol"}),(0,s.jsx)(e.td,{children:"The consensus protocol to use. Options are 'Zug' or 'Highway'."}),(0,s.jsx)(e.td,{children:"'Highway'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_delegators_per_validator"}),(0,s.jsx)(e.td,{children:"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."}),(0,s.jsx)(e.td,{children:"1200"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"highway",children:"highway"}),"\n",(0,s.jsx)(e.p,{children:"These settings configure the Highway Consensus protocol."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_round_length"}),(0,s.jsxs)(e.td,{children:["Highway dynamically chooses its round length between ",(0,s.jsx)(e.code,{children:"minimum_block_time"})," and ",(0,s.jsx)(e.code,{children:"maximum_round_length"}),"."]}),(0,s.jsx)(e.td,{children:"'132seconds'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduced_reward_multiplier"}),(0,s.jsx)(e.td,{children:"The factor by which rewards for a round are multiplied if the greatest summit has \u226450% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet)."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"deploys",children:"deploys"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage deploys and their lifecycle."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_payment_cost"}),(0,s.jsx)(e.td,{children:"The maximum number of motes allowed to be spent during payment. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"'0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_ttl"}),(0,s.jsx)(e.td,{children:"The duration after the deploy timestamp during which the deploy can be included in a block."}),(0,s.jsx)(e.td,{children:"'18hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_dependencies"}),(0,s.jsx)(e.td,{children:"The maximum number of other deploys a deploy can depend on (requiring them to have been executed before it can execute)."}),(0,s.jsx)(e.td,{children:"10"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_block_size"}),(0,s.jsx)(e.td,{children:"Maximum block size in bytes, including deploys contained by the block. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"10_485_760"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_deploy_size"}),(0,s.jsx)(e.td,{children:"Maximum deploy size in bytes. Size is of the deploy when serialized via ToBytes."}),(0,s.jsx)(e.td,{children:"1_048_576"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_deploy_count"}),(0,s.jsx)(e.td,{children:"The maximum number of non-transfer deploys permitted in a single block."}),(0,s.jsx)(e.td,{children:"50"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_transfer_count"}),(0,s.jsx)(e.td,{children:"The maximum number of Wasm-less transfer deploys permitted in a single block."}),(0,s.jsx)(e.td,{children:"1250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_approval_count"}),(0,s.jsx)(e.td,{children:"The maximum number of approvals permitted in a single block."}),(0,s.jsx)(e.td,{children:"2600"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_gas_limit"}),(0,s.jsx)(e.td,{children:"The upper limit of the total gas of all deploys in a block."}),(0,s.jsx)(e.td,{children:"4_000_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"payment_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized payment code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"session_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized session code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_transfer_minimum_motes"}),(0,s.jsx)(e.td,{children:"The minimum amount in motes for a valid native transfer."}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasm",children:"wasm"}),"\n",(0,s.jsx)(e.p,{children:"The following are Wasm-related settings."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_memory"}),(0,s.jsx)(e.td,{children:"Amount of free memory (in 64 kB pages) each contract can use for its stack."}),(0,s.jsx)(e.td,{children:"64"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_stack_height"}),(0,s.jsx)(e.td,{children:"Max stack height (native WebAssembly stack limiter)."}),(0,s.jsx)(e.td,{children:"500"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmstorage_costs",children:"wasm.storage_costs"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage Wasm storage costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"630_000"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costs",children:"wasm.opcode_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage the cost table for Wasm opcodes."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flow",children:"wasm.opcode_costs.control_flow"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage costs for control flow operations."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flowbr_table",children:"wasm.opcode_costs.control_flow.br_table"}),"\n",(0,s.jsxs)(e.p,{children:["The following settings manage ",(0,s.jsx)(e.code,{children:"br_table"})," Wasm opcodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmhost_function_costs",children:"wasm.host_function_costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs",children:"smart_contracts/contract/src/ext_ffi.rs"}),"."]}),"\n",(0,s.jsx)(e.pre,{children:(0,s.jsx)(e.code,{children:"- add = { cost = 5_800, arguments = [0, 0, 0, 0] }\n- add_associated_key = { cost = 9_000, arguments = [0, 0, 0] }\n- add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }\n- blake2b = { cost = 200, arguments = [0, 0, 0, 0] }\n- call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] }\n- call_versioned_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 0, 0, 420, 0] }\n- create_contract_package_at_hash = { cost = 200, arguments = [0, 0] }\n- create_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }\n- create_purse = { cost = 2_500_000_000, arguments = [0, 0] }\n- disable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] }\n- get_balance = { cost = 3_800, arguments = [0, 0, 0] }\n- get_blocktime = { cost = 330, arguments = [0] }\n- get_caller = { cost = 380, arguments = [0] }\n- get_key = { cost = 2_000, arguments = [0, 440, 0, 0, 0] }\n- get_main_purse = { cost = 1_300, arguments = [0] }\n- get_named_arg = { cost = 200, arguments = [0, 0, 0, 0] }\n- get_named_arg_size = { cost = 200, arguments = [0, 0, 0] }\n- get_phase = { cost = 710, arguments = [0] }\n- get_system_contract = { cost = 1_100, arguments = [0, 0, 0] }\n- has_key = { cost = 1_500, arguments = [0, 840] }\n- is_valid_uref = { cost = 760, arguments = [0, 0] }\n- load_named_keys = { cost = 42_000, arguments = [0, 0] }\n- new_uref = { cost = 17_000, arguments = [0, 0, 590] }\n- random_bytes = { cost = 200, arguments = [0, 0] }\n- print = { cost = 20_000, arguments = [0, 4_600] }\n- provision_contract_user_group_uref = { cost = 200, arguments = [0, 0, 0, 0, 0] }\n- put_key = { cost = 38_000, arguments = [0, 1_100, 0, 0] }\n- read_host_buffer = { cost = 3_500, arguments = [0, 310, 0] }\n- read_value = { cost = 6_000, arguments = [0, 0, 0] }\n- read_value_local = { cost = 5_500, arguments = [0, 590, 0] }\n- remove_associated_key = { cost = 4_200, arguments = [0, 0] }\n- remove_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0] }\n- remove_contract_user_group_urefs = { cost = 200, arguments = [0, 0, 0, 0, 0, 0] }\n- remove_key = { cost = 61_000, arguments = [0, 3_200] }\n- ret = { cost = 23_000, arguments = [0, 420_000] }\n- revert = { cost = 500, arguments = [0] }\n- set_action_threshold = { cost = 74_000, arguments = [0, 0] }\n- transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] }\n- transfer_from_purse_to_purse = { cost = 82_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }\n- transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] }\n- update_associated_key = { cost = 4_200, arguments = [0, 0, 0] }\n- write = { cost = 14_000, arguments = [0, 0, 0, 980] }\n- write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] }\n"})}),"\n",(0,s.jsx)(e.h2,{id:"system_costs",children:"system_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage protocol operating costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"wasmless_transfer_cost"}),(0,s.jsx)(e.td,{children:"Default gas cost for a wasmless transfer."}),(0,s.jsx)(e.td,{children:"100_000_000"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsauction_costs",children:"system_costs.auction_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsmint_costs",children:"system_costs.mint_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costshandle_payment_costs",children:"system_costs.handle_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsstandard_payment_costs",children:"system_costs.standard_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function a(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(h,{...n})}):h(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>d,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function d(n){const e=s.useContext(i);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:d(n.components),s.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/40c07125.9be41738.js b/assets/js/40c07125.9be41738.js deleted file mode 100644 index f32186f4b..000000000 --- a/assets/js/40c07125.9be41738.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3485],{40232:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var c=s(74848),i=s(28453);const t={title:"Accounts and Keys"},a="Accounts and Cryptographic Keys",r={id:"concepts/accounts-and-keys",title:"Accounts and Keys",description:"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.",source:"@site/versioned_docs/version-1.5.X/concepts/accounts-and-keys.md",sourceDirName:"concepts",slug:"/concepts/accounts-and-keys",permalink:"/concepts/accounts-and-keys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Accounts and Keys"},sidebar:"concepts",previous:{title:"dApps",permalink:"/concepts/intro-to-dapps"},next:{title:"Hash Types",permalink:"/concepts/hash-types"}},o={},d=[{value:"Creating Accounts and Keys",id:"creating-accounts-and-keys",level:2},{value:"Option 1: Generating keys using the Casper Client",id:"option-1-key-generation-using-the-casper-client",level:3},{value:"EdDSA Keys",id:"eddsa-keys",level:4},{value:"ECDSA Keys",id:"ecdsa-keys",level:4},{value:"Option 2: Generating keys using a block explorer",id:"option-2-key-generation-using-a-block-explorer",level:3},{value:"Funding your Account",id:"funding-your-account",level:2},{value:"Working with Existing Ethereum Keys",id:"working-with-existing-ethereum-keys",level:2},{value:"Option 3: Generating keys using OpenSSL",id:"option-3-generating-keys-using-openssl",level:3},{value:"Generating the <code>secret_key.pem</code> file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the <code>secret_key.pem</code> file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"accounts-and-cryptographic-keys",children:"Accounts and Cryptographic Keys"})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"account-based model"}),", uniquely identified by an ",(0,c.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,c.jsx)(n.code,{children:"PublicKey"}),". The ",(0,c.jsx)(n.code,{children:"AccountHash"})," is a 32-byte hash derived from any of the supported ",(0,c.jsx)(n.code,{children:"PublicKey"})," variants below to standardize keys that can vary in length."]}),"\n",(0,c.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,c.jsx)(n.code,{children:"Deploy"})," cryptographically signed by the key-pair corresponding to the ",(0,c.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#ecdsa-keys",children:"Secp256k1"})," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys using both formats, and it is also possible to ",(0,c.jsx)(n.a,{href:"#working-with-existing-ethereum-keys",children:"work with existing Ethereum keys"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["You can also ",(0,c.jsx)(n.a,{href:"#generating-an-account-hash",children:"generate an account hash"})," from a public key with the Casper command-line client."]}),"\n",(0,c.jsx)(n.h2,{id:"creating-accounts-and-keys",children:"Creating Accounts and Keys"}),"\n",(0,c.jsxs)(n.p,{children:["When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," or a block explorer. Developers must use the Casper command-line client as described below. Otherwise, they won't have access to the secret key file needed during development."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"SAVE your keys to a safe place, preferably offline."})}),"\n",(0,c.jsx)(n.h3,{id:"option-1-key-generation-using-the-casper-client",children:"Option 1: Generating keys using the Casper Client"}),"\n",(0,c.jsx)(n.p,{children:"This option describes how you can use the Casper command-line client to set up an account using either key type."}),"\n",(0,c.jsx)(n.h4,{id:"eddsa-keys",children:"EdDSA Keys"}),"\n",(0,c.jsx)(n.p,{children:"The command-line client generates EdDSA keys by default. Use the command below to create the account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"ed25519-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsx)(n.p,{children:"Here are some details about the files generated:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key.pem"})," is a ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key_hex"})," is a hexadecimal-encoded string of the public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"secret_key.pem"})," is the ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded secret key"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Ed25519"})," keys starts with 01 and is 66 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n"})}),"\n",(0,c.jsx)(n.h4,{id:"ecdsa-keys",children:"ECDSA Keys"}),"\n",(0,c.jsxs)(n.p,{children:["To create ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"secp256k1-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys starts with 02 and is 68 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"After generating keys for the account, you may add funds to the account's purse to finish the account creation process."})}),"\n",(0,c.jsx)(n.h3,{id:"option-2-key-generation-using-a-block-explorer",children:"Option 2: Generating keys using a block explorer"}),"\n",(0,c.jsx)(n.p,{children:"This option is available on networks that have a block explorer."}),"\n",(0,c.jsxs)(n.p,{children:["For instance, on the official Testnet, the ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"CSPR.live"})," block explorer is available, and the following instructions assume you are using it."]}),"\n",(0,c.jsxs)(n.p,{children:["Start by creating an account using the ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),", ",(0,c.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true",children:"Ledger"}),", or ",(0,c.jsx)(n.a,{href:"https://casper.tor.us/",children:"Torus Wallet"}),"."]}),"\n",(0,c.jsxs)(n.admonition,{type:"caution",children:[(0,c.jsxs)(n.p,{children:["Developers must generate keys using the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," to access the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file."]}),(0,c.jsxs)(n.p,{children:["The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/signer-user-start-here",children:"here"}),"."]})]}),"\n",(0,c.jsx)(n.h2,{id:"funding-your-account",children:"Funding your Account"}),"\n",(0,c.jsxs)(n.p,{children:["Once you create your account, you can ",(0,c.jsx)(n.a,{href:"/developers/prerequisites#fund-your-account",children:"fund the account's main purse"})," to finish the process of setting it up."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"Until you fund your account's main purse, it does not exist on the blockchain."})}),"\n",(0,c.jsx)(n.h2,{id:"working-with-existing-ethereum-keys",children:"Working with Existing Ethereum Keys"}),"\n",(0,c.jsx)(n.p,{children:"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,c.jsx)(n.code,{children:"Secp256k1"})," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper command-line client provides an example of how this works."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,c.jsx)(n.p,{children:"The following transaction sends 10 CSPR."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key <path-to-secret_key.pem> \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"tip",children:(0,c.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper command-line client requires the secret key in ",(0,c.jsx)(n.em,{children:"PEM"})," format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,c.jsx)(n.em,{children:"PEM"})," format is needed."]}),"\n",(0,c.jsxs)(n.p,{children:["The following example is a JS script that generates a ",(0,c.jsx)(n.em,{children:"PEM"})," file, using a ",(0,c.jsx)(n.a,{href:"https://github.com/stacks-network/key-encoder-js",children:"key encoder"})," and Node.js. To install these components, do the following:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"sudo apt install nodejs\nnpm install key-encoder\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Then create the JS script ",(0,c.jsx)(n.em,{children:"convert-to-pem.js"})," using ",(0,c.jsx)(n.em,{children:"vi"})," or ",(0,c.jsx)(n.em,{children:"nano"}),", and include this content:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:'var KeyEncoder = require("key-encoder"),\n keyEncoder = new KeyEncoder.default("secp256k1");\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n'})}),"\n",(0,c.jsx)(n.p,{children:"Then run the script using Node.js and name the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"node convert-to-pem.js > eth-secret.pem\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To view the secret key, use ",(0,c.jsx)(n.code,{children:"cat <filename>"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat eth-secret.pem\n"})}),"\n",(0,c.jsx)(n.p,{children:"Below is the sample output showing the contents of the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n"})}),"\n",(0,c.jsx)(n.h3,{id:"option-3-generating-keys-using-openssl",children:"Option 3: Generating keys using OpenSSL"}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys without the Casper client using the ",(0,c.jsx)(n.a,{href:"https://www.openssl.org/",children:"openssl"})," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."]}),"\n",(0,c.jsxs)(n.h4,{id:"generating-the-secret_keypem-file",children:["Generating the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"openssl genpkey -algorithm ed25519 -out secret_key.pem\n"})}),"\n",(0,c.jsxs)(n.h4,{id:"generating-public-keys-from-the-secret_keypem-file",children:["Generating public keys from the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsxs)(n.p,{children:["For default Ed25519 keys, you can generate the ",(0,c.jsx)(n.code,{children:"public_key.pem"})," and ",(0,c.jsx)(n.code,{children:"public_key_hex"})," using these commands:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n'})}),"\n",(0,c.jsx)(n.h2,{id:"generating-an-account-hash",children:"Generating an Account Hash"}),"\n",(0,c.jsxs)(n.p,{children:["To generate the account hash for a public key, use the ",(0,c.jsx)(n.em,{children:"account-address"})," option of the Casper client. The argument for the ",(0,c.jsx)(n.em,{children:"public-key"})," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,c.jsx)(n.em,{children:"keygen"})," command: ",(0,c.jsx)(n.em,{children:"public_key_hex"})," or ",(0,c.jsx)(n.em,{children:"public_key.pem"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsx)(n.h2,{id:"purse-uref",children:"Finding the Main Purse URef"}),"\n",(0,c.jsx)(n.p,{children:"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."}),"\n",(0,c.jsx)(n.h3,{id:"using-the-casper-cli-client",children:"Using the Casper CLI client"}),"\n",(0,c.jsxs)(n.p,{children:["With the ",(0,c.jsx)(n.code,{children:"casper-client"}),", use the ",(0,c.jsx)(n.code,{children:"get-account-info"})," subcommand."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info \\\n--node-address <HOST:PORT> \\\n--public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public-key"})," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,c.jsx)(n.code,{children:"keygen"}),' subcommand; "public_key_hex" or "public_key.pem"']}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Sample command and output"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Run the following help command for more details:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info --help\n"})}),"\n",(0,c.jsx)(n.h3,{id:"using-a-block-explorer",children:"Using a block explorer"}),"\n",(0,c.jsxs)(n.p,{children:["Using the block explorer for ",(0,c.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," or ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),", open the Account in question, and expand the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section. Look for the ",(0,c.jsx)(n.code,{children:"main_purse"})," field and find the corresponding URef. If you do not see data in the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section, then the account has not been funded yet."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Image showing an account's main purse",src:s(82703).A+"",width:"1576",height:"1494"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},82703:(e,n,s)=>{s.d(n,{A:()=>c});const c=s.p+"assets/images/main_purse_uref-96cffa61cd6ab63f2fb996efe8fc4197.png"},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var c=s(96540);const i={},t=c.createContext(i);function a(e){const n=c.useContext(t);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),c.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/40c07125.b0d71ef3.js b/assets/js/40c07125.b0d71ef3.js new file mode 100644 index 000000000..89d79afd2 --- /dev/null +++ b/assets/js/40c07125.b0d71ef3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63485],{40232:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var c=s(74848),i=s(28453);const t={title:"Accounts and Keys"},a="Accounts and Cryptographic Keys",r={id:"concepts/accounts-and-keys",title:"Accounts and Keys",description:"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.",source:"@site/versioned_docs/version-1.5.X/concepts/accounts-and-keys.md",sourceDirName:"concepts",slug:"/concepts/accounts-and-keys",permalink:"/1.5.X/concepts/accounts-and-keys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Accounts and Keys"},sidebar:"concepts",previous:{title:"dApps",permalink:"/1.5.X/concepts/intro-to-dapps"},next:{title:"Hash Types",permalink:"/1.5.X/concepts/hash-types"}},o={},d=[{value:"Creating Accounts and Keys",id:"creating-accounts-and-keys",level:2},{value:"Option 1: Generating keys using the Casper Client",id:"option-1-key-generation-using-the-casper-client",level:3},{value:"EdDSA Keys",id:"eddsa-keys",level:4},{value:"ECDSA Keys",id:"ecdsa-keys",level:4},{value:"Option 2: Generating keys using a block explorer",id:"option-2-key-generation-using-a-block-explorer",level:3},{value:"Funding your Account",id:"funding-your-account",level:2},{value:"Working with Existing Ethereum Keys",id:"working-with-existing-ethereum-keys",level:2},{value:"Option 3: Generating keys using OpenSSL",id:"option-3-generating-keys-using-openssl",level:3},{value:"Generating the <code>secret_key.pem</code> file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the <code>secret_key.pem</code> file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"accounts-and-cryptographic-keys",children:"Accounts and Cryptographic Keys"})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"account-based model"}),", uniquely identified by an ",(0,c.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,c.jsx)(n.code,{children:"PublicKey"}),". The ",(0,c.jsx)(n.code,{children:"AccountHash"})," is a 32-byte hash derived from any of the supported ",(0,c.jsx)(n.code,{children:"PublicKey"})," variants below to standardize keys that can vary in length."]}),"\n",(0,c.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,c.jsx)(n.code,{children:"Deploy"})," cryptographically signed by the key-pair corresponding to the ",(0,c.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#ecdsa-keys",children:"Secp256k1"})," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys using both formats, and it is also possible to ",(0,c.jsx)(n.a,{href:"#working-with-existing-ethereum-keys",children:"work with existing Ethereum keys"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["You can also ",(0,c.jsx)(n.a,{href:"#generating-an-account-hash",children:"generate an account hash"})," from a public key with the Casper command-line client."]}),"\n",(0,c.jsx)(n.h2,{id:"creating-accounts-and-keys",children:"Creating Accounts and Keys"}),"\n",(0,c.jsxs)(n.p,{children:["When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," or a block explorer. Developers must use the Casper command-line client as described below. Otherwise, they won't have access to the secret key file needed during development."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"SAVE your keys to a safe place, preferably offline."})}),"\n",(0,c.jsx)(n.h3,{id:"option-1-key-generation-using-the-casper-client",children:"Option 1: Generating keys using the Casper Client"}),"\n",(0,c.jsx)(n.p,{children:"This option describes how you can use the Casper command-line client to set up an account using either key type."}),"\n",(0,c.jsx)(n.h4,{id:"eddsa-keys",children:"EdDSA Keys"}),"\n",(0,c.jsx)(n.p,{children:"The command-line client generates EdDSA keys by default. Use the command below to create the account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"ed25519-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsx)(n.p,{children:"Here are some details about the files generated:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key.pem"})," is a ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key_hex"})," is a hexadecimal-encoded string of the public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"secret_key.pem"})," is the ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded secret key"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Ed25519"})," keys starts with 01 and is 66 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n"})}),"\n",(0,c.jsx)(n.h4,{id:"ecdsa-keys",children:"ECDSA Keys"}),"\n",(0,c.jsxs)(n.p,{children:["To create ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"secp256k1-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys starts with 02 and is 68 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"After generating keys for the account, you may add funds to the account's purse to finish the account creation process."})}),"\n",(0,c.jsx)(n.h3,{id:"option-2-key-generation-using-a-block-explorer",children:"Option 2: Generating keys using a block explorer"}),"\n",(0,c.jsx)(n.p,{children:"This option is available on networks that have a block explorer."}),"\n",(0,c.jsxs)(n.p,{children:["For instance, on the official Testnet, the ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"CSPR.live"})," block explorer is available, and the following instructions assume you are using it."]}),"\n",(0,c.jsxs)(n.p,{children:["Start by creating an account using the ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),", ",(0,c.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true",children:"Ledger"}),", or ",(0,c.jsx)(n.a,{href:"https://casper.tor.us/",children:"Torus Wallet"}),"."]}),"\n",(0,c.jsxs)(n.admonition,{type:"caution",children:[(0,c.jsxs)(n.p,{children:["Developers must generate keys using the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," to access the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file."]}),(0,c.jsxs)(n.p,{children:["The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/signer-user-start-here",children:"here"}),"."]})]}),"\n",(0,c.jsx)(n.h2,{id:"funding-your-account",children:"Funding your Account"}),"\n",(0,c.jsxs)(n.p,{children:["Once you create your account, you can ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#fund-your-account",children:"fund the account's main purse"})," to finish the process of setting it up."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"Until you fund your account's main purse, it does not exist on the blockchain."})}),"\n",(0,c.jsx)(n.h2,{id:"working-with-existing-ethereum-keys",children:"Working with Existing Ethereum Keys"}),"\n",(0,c.jsx)(n.p,{children:"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,c.jsx)(n.code,{children:"Secp256k1"})," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper command-line client provides an example of how this works."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,c.jsx)(n.p,{children:"The following transaction sends 10 CSPR."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key <path-to-secret_key.pem> \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"tip",children:(0,c.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper command-line client requires the secret key in ",(0,c.jsx)(n.em,{children:"PEM"})," format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,c.jsx)(n.em,{children:"PEM"})," format is needed."]}),"\n",(0,c.jsxs)(n.p,{children:["The following example is a JS script that generates a ",(0,c.jsx)(n.em,{children:"PEM"})," file, using a ",(0,c.jsx)(n.a,{href:"https://github.com/stacks-network/key-encoder-js",children:"key encoder"})," and Node.js. To install these components, do the following:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"sudo apt install nodejs\nnpm install key-encoder\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Then create the JS script ",(0,c.jsx)(n.em,{children:"convert-to-pem.js"})," using ",(0,c.jsx)(n.em,{children:"vi"})," or ",(0,c.jsx)(n.em,{children:"nano"}),", and include this content:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:'var KeyEncoder = require("key-encoder"),\n keyEncoder = new KeyEncoder.default("secp256k1");\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n'})}),"\n",(0,c.jsx)(n.p,{children:"Then run the script using Node.js and name the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"node convert-to-pem.js > eth-secret.pem\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To view the secret key, use ",(0,c.jsx)(n.code,{children:"cat <filename>"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat eth-secret.pem\n"})}),"\n",(0,c.jsx)(n.p,{children:"Below is the sample output showing the contents of the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n"})}),"\n",(0,c.jsx)(n.h3,{id:"option-3-generating-keys-using-openssl",children:"Option 3: Generating keys using OpenSSL"}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys without the Casper client using the ",(0,c.jsx)(n.a,{href:"https://www.openssl.org/",children:"openssl"})," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."]}),"\n",(0,c.jsxs)(n.h4,{id:"generating-the-secret_keypem-file",children:["Generating the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"openssl genpkey -algorithm ed25519 -out secret_key.pem\n"})}),"\n",(0,c.jsxs)(n.h4,{id:"generating-public-keys-from-the-secret_keypem-file",children:["Generating public keys from the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsxs)(n.p,{children:["For default Ed25519 keys, you can generate the ",(0,c.jsx)(n.code,{children:"public_key.pem"})," and ",(0,c.jsx)(n.code,{children:"public_key_hex"})," using these commands:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n'})}),"\n",(0,c.jsx)(n.h2,{id:"generating-an-account-hash",children:"Generating an Account Hash"}),"\n",(0,c.jsxs)(n.p,{children:["To generate the account hash for a public key, use the ",(0,c.jsx)(n.em,{children:"account-address"})," option of the Casper client. The argument for the ",(0,c.jsx)(n.em,{children:"public-key"})," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,c.jsx)(n.em,{children:"keygen"})," command: ",(0,c.jsx)(n.em,{children:"public_key_hex"})," or ",(0,c.jsx)(n.em,{children:"public_key.pem"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsx)(n.h2,{id:"purse-uref",children:"Finding the Main Purse URef"}),"\n",(0,c.jsx)(n.p,{children:"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."}),"\n",(0,c.jsx)(n.h3,{id:"using-the-casper-cli-client",children:"Using the Casper CLI client"}),"\n",(0,c.jsxs)(n.p,{children:["With the ",(0,c.jsx)(n.code,{children:"casper-client"}),", use the ",(0,c.jsx)(n.code,{children:"get-account-info"})," subcommand."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info \\\n--node-address <HOST:PORT> \\\n--public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public-key"})," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,c.jsx)(n.code,{children:"keygen"}),' subcommand; "public_key_hex" or "public_key.pem"']}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Sample command and output"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Run the following help command for more details:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info --help\n"})}),"\n",(0,c.jsx)(n.h3,{id:"using-a-block-explorer",children:"Using a block explorer"}),"\n",(0,c.jsxs)(n.p,{children:["Using the block explorer for ",(0,c.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," or ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),", open the Account in question, and expand the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section. Look for the ",(0,c.jsx)(n.code,{children:"main_purse"})," field and find the corresponding URef. If you do not see data in the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section, then the account has not been funded yet."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Image showing an account's main purse",src:s(79429).A+"",width:"1576",height:"1494"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},79429:(e,n,s)=>{s.d(n,{A:()=>c});const c=s.p+"assets/images/main_purse_uref-96cffa61cd6ab63f2fb996efe8fc4197.png"},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var c=s(96540);const i={},t=c.createContext(i);function a(e){const n=c.useContext(t);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),c.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/411a45a4.bfced875.js b/assets/js/411a45a4.bfced875.js new file mode 100644 index 000000000..3849f5c1e --- /dev/null +++ b/assets/js/411a45a4.bfced875.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27686],{28312:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>o});var r=t(74848),s=t(28453);const d={slug:"/resources/tokens/"},i="Casper Token Standards",c={id:"resources/tokens/index",title:"Casper Token Standards",description:"CEP-18 Casper Fungible Token Standard",source:"@site/versioned_docs/version-2.0.0/resources/tokens/index.md",sourceDirName:"resources/tokens",slug:"/resources/tokens/",permalink:"/2.0.0/resources/tokens/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{slug:"/resources/tokens/"},sidebar:"resources",previous:{title:"Move to Casper",permalink:"/2.0.0/resources/moving-to-casper"},next:{title:"Fungible Token Workflow",permalink:"/2.0.0/resources/tokens/cep18/full-tutorial"}},a={},o=[{value:"CEP-18 Casper Fungible Token Standard",id:"cep-18-casper-fungible-token-standard",level:2},{value:"CEP-78 Enhanced NFT Standard",id:"cep-78-enhanced-nft-standard",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"casper-token-standards",children:"Casper Token Standards"})}),"\n",(0,r.jsx)(n.h2,{id:"cep-18-casper-fungible-token-standard",children:"CEP-18 Casper Fungible Token Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/full-tutorial",children:"A Casper Fungible Token Tutorial"})}),(0,r.jsx)(n.td,{children:"A full tutorial for use of the CEP-18 Casper Fungible Token Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/quickstart-guide",children:"Installing and Interacting with a CEP-18 Contract"})}),(0,r.jsx)(n.td,{children:"A quickstart guide for installing a CEP-18 contract with the Rust Casper Client."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/query",children:"Exploring the CEP-18 Contracts"})}),(0,r.jsx)(n.td,{children:"A guide to interacting with installed CEP-18 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),(0,r.jsx)(n.td,{children:"A guide for transferring Casper Fungible Tokens."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),(0,r.jsx)(n.td,{children:"A CEP-18 testing framework using the Casper engine test support crate."})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"cep-78-enhanced-nft-standard",children:"CEP-78 Enhanced NFT Standard"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),(0,r.jsx)(n.td,{children:"An introduction to the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/introduction",children:"CEP-78 Modalities"})}),(0,r.jsx)(n.td,{children:"Information on the features available when installing a CEP-78 contract instance."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/using-casper-client",children:"Installing and Interacting with a CEP-78 Contract"})}),(0,r.jsx)(n.td,{children:"An introduction to features present in the CEP-78 Enhanced NFT Standard."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/reverse-lookup",children:"Owner Reverse Lookup Functionality"})}),(0,r.jsx)(n.td,{children:"Information on the Onwer Reverse Lookup feature of CEP-78 contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/js-tutorial",children:"A CEP-78 JavaScript Client Tutorial"})}),(0,r.jsx)(n.td,{children:"A tutorial for using the JavaScript CEP-78 client."})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var r=t(96540);const s={},d=r.createContext(s);function i(e){const n=r.useContext(d);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41905acb.2fa671b8.js b/assets/js/41905acb.2fa671b8.js new file mode 100644 index 000000000..58be295be --- /dev/null +++ b/assets/js/41905acb.2fa671b8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93920],{88694:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Transfer Tokens",slug:"/users/token-transfer"},o="Transferring Tokens",a={id:"users/csprlive/token-transfer",title:"Transfer Tokens",description:"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/token-transfer.md",sourceDirName:"users/csprlive",slug:"/users/token-transfer",permalink:"/1.5.X/users/token-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Transfer Tokens",slug:"/users/token-transfer"},sidebar:"users",previous:{title:"Undelegate Tokens",permalink:"/1.5.X/users/undelegate-ui"},next:{title:"Casper on Ledger",permalink:"/1.5.X/users/ledger/"}},l={},c=[{value:"Transferring Tokens",id:"transferring-tokens-1",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens",children:"Transferring Tokens"})}),"\n",(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsxs)(n.p,{children:["You can transfer Casper tokens (CSPR) using any ",(0,t.jsx)(n.a,{href:"/1.5.X/users/block-explorer",children:"block explorer"})," built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-tokens-1",children:"Transferring Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To transfer tokens, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Sign in to your account with the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Wallet"})," on the top menu bar and select ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"})," from the drop-down menu."]}),"\n",(0,t.jsx)(n.li,{children:"Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one."}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Next"})," to proceed."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(9436).A+"",width:"1248",height:"1698"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["A confirmation window appears to verify the details entered. Click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"})," to proceed to the next step."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(95677).A+"",width:"1178",height:"1332"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Review the following important fields:"}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The Deploy hash, which uniquely identifies your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient public key of the person receiving your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient account hash used by the system to track the transaction"}),"\n",(0,t.jsx)(n.li,{children:"The Transfer Amount containing the value of the transfer"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Sign the transaction by selecting the ",(0,t.jsx)(n.strong,{children:"Sign with Casper Wallet"})," button to proceed to the next step."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(33773).A+"",width:"1212",height:"1734"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,t.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click ',(0,t.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to complete the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(75039).A+"",width:"2018",height:"1704"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"You completed the transaction and successfully transferred tokens."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(59865).A+"",width:"1210",height:"1396"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"View the updated CSPR balance in the account's main purse next."}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},9436:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1.transfer-details-52f3e9784bb7cdea4de42d410d030a7f.png"},95677:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2.confirm-transfer-a8905cf1c517bda6dca65fd328d32359.png"},33773:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3.sign-transfer-c9f0f40bb26b346cfe8cf2f6db848c4e.png"},75039:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4.wallet-window-34d341c968c49554406e732382b5f597.png"},59865:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5.transfer-completed-c913311be299c8d18915f0cbc5b447b0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41905acb.9b219f55.js b/assets/js/41905acb.9b219f55.js deleted file mode 100644 index e1dc654a6..000000000 --- a/assets/js/41905acb.9b219f55.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3920],{88694:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Transfer Tokens",slug:"/users/token-transfer"},o="Transferring Tokens",a={id:"users/csprlive/token-transfer",title:"Transfer Tokens",description:"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/token-transfer.md",sourceDirName:"users/csprlive",slug:"/users/token-transfer",permalink:"/users/token-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Transfer Tokens",slug:"/users/token-transfer"},sidebar:"users",previous:{title:"Undelegate Tokens",permalink:"/users/undelegate-ui"},next:{title:"Casper on Ledger",permalink:"/users/ledger/"}},l={},c=[{value:"Transferring Tokens",id:"transferring-tokens-1",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens",children:"Transferring Tokens"})}),"\n",(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsxs)(n.p,{children:["You can transfer Casper tokens (CSPR) using any ",(0,t.jsx)(n.a,{href:"/users/block-explorer",children:"block explorer"})," built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-tokens-1",children:"Transferring Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To transfer tokens, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Sign in to your account with the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Wallet"})," on the top menu bar and select ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"})," from the drop-down menu."]}),"\n",(0,t.jsx)(n.li,{children:"Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one."}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Next"})," to proceed."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(14002).A+"",width:"1248",height:"1698"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["A confirmation window appears to verify the details entered. Click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"})," to proceed to the next step."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(44703).A+"",width:"1178",height:"1332"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Review the following important fields:"}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The Deploy hash, which uniquely identifies your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient public key of the person receiving your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient account hash used by the system to track the transaction"}),"\n",(0,t.jsx)(n.li,{children:"The Transfer Amount containing the value of the transfer"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Sign the transaction by selecting the ",(0,t.jsx)(n.strong,{children:"Sign with Casper Wallet"})," button to proceed to the next step."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(61603).A+"",width:"1212",height:"1734"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,t.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click ',(0,t.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to complete the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(58645).A+"",width:"2018",height:"1704"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"You completed the transaction and successfully transferred tokens."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(92611).A+"",width:"1210",height:"1396"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"View the updated CSPR balance in the account's main purse next."}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},14002:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1.transfer-details-52f3e9784bb7cdea4de42d410d030a7f.png"},44703:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2.confirm-transfer-a8905cf1c517bda6dca65fd328d32359.png"},61603:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3.sign-transfer-c9f0f40bb26b346cfe8cf2f6db848c4e.png"},58645:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4.wallet-window-34d341c968c49554406e732382b5f597.png"},92611:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5.transfer-completed-c913311be299c8d18915f0cbc5b447b0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41e7d56e.2064be67.js b/assets/js/41e7d56e.2064be67.js deleted file mode 100644 index 80c3bb0d8..000000000 --- a/assets/js/41e7d56e.2064be67.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4932],{40529:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>t,metadata:()=>a,toc:()=>h});var r=n(74848),c=n(28453);const t={},o="K",a={id:"concepts/glossary/K",title:"K",description:"---",source:"@site/docs/concepts/glossary/K.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/K",permalink:"/next/concepts/glossary/K",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"J",permalink:"/next/concepts/glossary/J"},next:{title:"L",permalink:"/next/concepts/glossary/L"}},l={},h=[{value:"Key",id:"key",level:2}];function x(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"k",children:"K"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"key",children:"Key"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.code,{children:"Keys"})," are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found ",(0,r.jsx)(s.a,{href:"/next/concepts/accounts-and-keys",children:"here"}),"."]})]})}function i(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41e7d56e.3c81128b.js b/assets/js/41e7d56e.3c81128b.js new file mode 100644 index 000000000..a9c6854d1 --- /dev/null +++ b/assets/js/41e7d56e.3c81128b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64932],{40529:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="K",a={id:"concepts/glossary/K",title:"K",description:"---",source:"@site/docs/concepts/glossary/K.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/K",permalink:"/concepts/glossary/K",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"J",permalink:"/concepts/glossary/J"},next:{title:"L",permalink:"/concepts/glossary/L"}},l={},h=[{value:"Key",id:"key",level:2}];function i(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"k",children:"K"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"key",children:"Key"}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.code,{children:"Keys"})," are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found ",(0,c.jsx)(s.a,{href:"/concepts/accounts-and-keys",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(e){const s=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),c.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41eb5a6a.25e46683.js b/assets/js/41eb5a6a.25e46683.js new file mode 100644 index 000000000..ca4965866 --- /dev/null +++ b/assets/js/41eb5a6a.25e46683.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5650],{78593:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=n(74848),o=n(28453);const r={},a="Casper-Client Commands",i={id:"resources/beginner/counter-testnet/commands",title:"Casper-Client Commands",description:"State Root Hash",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/commands.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/commands",permalink:"/1.5.X/resources/beginner/counter-testnet/commands",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/1.5.X/resources/beginner/counter-testnet/overview"},next:{title:"Tutorial Walkthrough",permalink:"/1.5.X/resources/beginner/counter-testnet/walkthrough"}},c={},l=[{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,s.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address http://[IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find a list of Testnet IP addresses at ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"CSPR live"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The first command to cover is the ",(0,s.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,s.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"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."})}),"\n",(0,s.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"node-address"})," is the server on the network."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,s.jsxs)(t.li,{children:["The optional query path argument (",(0,s.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,s.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,s.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,s.jsx)(t.em,{children:"chain-name"}),'. The Testnet is "casper-test" but this is configurable.']}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This second usage of ",(0,s.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,s.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,s.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter-testnet/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,s.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,s.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/41eb5a6a.432785b3.js b/assets/js/41eb5a6a.432785b3.js deleted file mode 100644 index 9c2da1af6..000000000 --- a/assets/js/41eb5a6a.432785b3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5650],{78593:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=n(74848),o=n(28453);const r={},a="Casper-Client Commands",i={id:"resources/beginner/counter-testnet/commands",title:"Casper-Client Commands",description:"State Root Hash",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/commands.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/commands",permalink:"/resources/beginner/counter-testnet/commands",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/beginner/counter-testnet/overview"},next:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough"}},c={},l=[{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,s.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address http://[IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find a list of Testnet IP addresses at ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"CSPR live"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The first command to cover is the ",(0,s.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,s.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"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."})}),"\n",(0,s.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"node-address"})," is the server on the network."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,s.jsxs)(t.li,{children:["The optional query path argument (",(0,s.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,s.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,s.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,s.jsx)(t.em,{children:"chain-name"}),'. The Testnet is "casper-test" but this is configurable.']}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This second usage of ",(0,s.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,s.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,s.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,s.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,s.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/42744730.53821c1f.js b/assets/js/42744730.53821c1f.js new file mode 100644 index 000000000..cf5a357fd --- /dev/null +++ b/assets/js/42744730.53821c1f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[12478],{37100:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},o="Transactions and the Transaction Lifecycle",c={id:"concepts/transactions-and-transaction-lifecycle",title:"Transaction Lifecycle",description:"Transactions",source:"@site/versioned_docs/version-2.0.0/concepts/transactions-and-transaction-lifecycle.md",sourceDirName:"concepts",slug:"/transactions-and-transaction-lifecycle",permalink:"/2.0.0/transactions-and-transaction-lifecycle",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},sidebar:"concepts",previous:{title:"Key Types",permalink:"/2.0.0/concepts/key-types"},next:{title:"Global State",permalink:"/2.0.0/concepts/global-state"}},r={},d=[{value:"Transactions",id:"execution-semantics-transactions",level:2},{value:"The Transaction Lifecycle",id:"execution-semantics-phases",level:2},{value:"Transaction Received",id:"transaction-received",level:3},{value:"Transaction Gossiped",id:"transaction-gossiped",level:3},{value:"Block Proposed",id:"block-proposed",level:3},{value:"Block Gossiped",id:"block-gossiped",level:3},{value:"Consensus Reached",id:"consensus-reached",level:3},{value:"Transaction Executed",id:"transaction-executed",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"transactions-and-the-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-transactions",children:"Transactions"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transaction"})," is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions\u2019s structure is as follows:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Transaction Data Structure",src:t(63385).A+"",width:"900",height:"586"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Body: Containing payment code and session code (more details on these below)"}),"\n",(0,s.jsxs)(n.li,{children:["Header: containing\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/types#publickey",children:"Public Key"})," of the account in whose context the transaction will run"]}),"\n",(0,s.jsx)(n.li,{children:"The timestamp of the transaction\u2019s creation"}),"\n",(0,s.jsx)(n.li,{children:"A time-to-live, after which the transaction expires and cannot be included in a block"}),"\n",(0,s.jsxs)(n.li,{children:["the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the body"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Transaction hash: the ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of the Header"]}),"\n",(0,s.jsxs)(n.li,{children:["Approvals: the set of signatures which have signed the transaction hash; these are used in the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"account permissions model"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-phases",children:"The Transaction Lifecycle"}),"\n",(0,s.jsx)(n.p,{children:"A transaction goes through the following phases on Casper:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Transaction Received"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Block Proposed"}),"\n",(0,s.jsx)(n.li,{children:"Block Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Consensus Reached"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Executed"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-received",children:"Transaction Received"}),"\n",(0,s.jsxs)(n.p,{children:["A client sending the transaction will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given transaction matches configuration settings outlined in the network's chainspec. Transaction configuration for the Casper Mainnet can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L79",children:"here"}),". Once accepted, the system returns the transaction hash to the client to indicate it has been enqueued for execution. The transaction could expire while waiting to be gossiped; whenever this happens, a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event is emitted by the event stream servers of all nodes which have the expired transaction."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-gossiped",children:"Transaction Gossiped"}),"\n",(0,s.jsxs)(n.p,{children:["After a node accepts a new transaction, it will gossip to all other nodes. A validator node will put the transaction into the block proposer buffer. The validator leader will pick the transaction from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given transaction. Each node that accepts a gossiped transaction also emits a ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," event on its event stream server. The transaction may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event."]}),"\n",(0,s.jsx)(n.h3,{id:"block-proposed",children:"Block Proposed"}),"\n",(0,s.jsx)(n.p,{children:"The validator leader for this round will propose a block that includes as many transactions from the block proposer buffer as can fit in a block."}),"\n",(0,s.jsx)(n.h3,{id:"block-gossiped",children:"Block Gossiped"}),"\n",(0,s.jsx)(n.p,{children:"The proposed block propagates to all other nodes."}),"\n",(0,s.jsx)(n.h3,{id:"consensus-reached",children:"Consensus Reached"}),"\n",(0,s.jsxs)(n.p,{children:["Once the other validators reach consensus that the proposed block is valid, all transactions in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a ",(0,s.jsx)(n.code,{children:"BlockAdded"}),". ",(0,s.jsx)(n.code,{children:"FinalitySignature"})," events emit shortly after that. Finality signatures for the new block arrive from the validators."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-executed",children:"Transaction Executed"}),"\n",(0,s.jsxs)(n.p,{children:["A transaction executes in distinct phases to accommodate flexibly paying for computation. The phases of a transaction are ",(0,s.jsx)(n.em,{children:"payment"}),", ",(0,s.jsx)(n.em,{children:"session"}),", and ",(0,s.jsx)(n.em,{children:"finalization"}),". Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the transaction is executed, a ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event is emitted by the event stream server."]}),"\n",(0,s.jsx)(n.p,{children:"In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty transactions."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Payment code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Payment code"})," determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#tokens-purses-and-accounts",children:"main purse"}),". In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," motes (a constant of the system.)\nIf the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending entity's main purse."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Session code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Session code"})," provides the main logic for the transaction. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself)."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Specifying payment code and session code"})}),"\n",(0,s.jsx)(n.p,{children:"The user-defined logic of a transaction can be specified in a number of ways:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account entity or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the entity the transaction is running in.)"}),"\n",(0,s.jsxs)(n.li,{children:["a 32-byte identifier representing the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/types#hash-key-serialization-standard-hash-key",children:"hash"})," where a contract is already stored in the global state"]}),"\n",(0,s.jsx)(n.li,{children:"a name corresponding to a named key, where a contract is stored under the key"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module)."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},63385:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/transaction-structure-658d8000fd6a573bafc1e7b8535b3c07.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/433fdaab.7d8c5d7c.js b/assets/js/433fdaab.7d8c5d7c.js new file mode 100644 index 000000000..5b805a029 --- /dev/null +++ b/assets/js/433fdaab.7d8c5d7c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[78263],{41258:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>i});var c=a(74848),s=a(28453);const r={},d="Direct Token Transfer",t={id:"developers/cli/transfers/direct-token-transfer",title:"Direct Token Transfer",description:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.",source:"@site/versioned_docs/version-2.0.0/developers/cli/transfers/direct-token-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/direct-token-transfer",permalink:"/2.0.0/developers/cli/transfers/direct-token-transfer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens",permalink:"/2.0.0/developers/cli/transfers/"},next:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer"}},f={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Direct Transfer Example",id:"transfer",level:2},{value:"Verifying the Deploy",id:"verify-deploy",level:2},{value:"Verifying the Transfer",id:"verifying-the-transfer",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"direct-token-transfer",children:"Direct Token Transfer"})}),"\n",(0,c.jsx)(n.p,{children:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"This workflow assumes:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["You meet the general ",(0,c.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"development prerequisites"})]}),"\n",(0,c.jsx)(n.li,{children:"You are using the Casper command-line client"}),"\n",(0,c.jsxs)(n.li,{children:["You have a target ",(0,c.jsx)(n.em,{children:"public key"})]}),"\n",(0,c.jsxs)(n.li,{children:["You have a valid ",(0,c.jsx)(n.em,{children:"node address"})]}),"\n",(0,c.jsxs)(n.li,{children:["You must be able to sign a deploy for the source account using the source ",(0,c.jsx)(n.em,{children:"secret key"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transfer",children:"Direct Transfer Example"}),"\n",(0,c.jsxs)(n.p,{children:["The following ",(0,c.jsx)(n.code,{children:"transfer"})," command allows you to move CSPR from one account's purse to another as denominated in ",(0,c.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#tokens-divisibility",children:"Motes"}),". A ",(0,c.jsx)(n.em,{children:"Mote"})," is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id <ID> \\\n--transfer-id <TRANSFER_ID> \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"transfer-id"})," -<64-BIT INTEGER> The ",(0,c.jsx)(n.code,{children:"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,c.jsx)(n.code,{children:"0"})," or some ",(0,c.jsx)(n.code,{children:"u64"})," value that is meaningful to you"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint default:",(0,c.jsx)(n.a,{href:"http://localhost:7777",children:"http://localhost:7777"})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"amount"})," -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.jsx)(n.code,{children:"Motes"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"secret-key"})," - Path to secret key file"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"chain-name"})," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Testnet is ",(0,c.jsx)(n.strong,{children:"casper-test"})]}),"\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Mainnet is ",(0,c.jsx)(n.strong,{children:"casper"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"target-account"})," - Hex-encoded public key of the account that will receive the funds in its main purse"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"payment-amount"})," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", you can specify 10^8 motes"]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."deploy_hash"'})," - The address of the deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Save the returned ",(0,c.jsx)(n.em,{children:"deploy_hash"})," from the output to query information about the transfer deploy later."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Transfer:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"verify-deploy",children:"Verifying the Deploy"}),"\n",(0,c.jsx)(n.p,{children:"A transfer on a Casper network is only executed after it has been included in a finalized block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"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"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."execution_results"[0]."block_hash"'})," - contains the block hash of the block that included the transfer. We will require the ",(0,c.jsx)(n.em,{children:"state_root_hash"})," of this block to look up information about the accounts and their purse balances"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Transfer addresses use a ",(0,c.jsx)(n.code,{children:"transfer-"})," string prefix."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["Refer to the Section on ",(0,c.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"querying deploys"})," for more information."]}),"\n",(0,c.jsx)(n.h2,{id:"verifying-the-transfer",children:"Verifying the Transfer"}),"\n",(0,c.jsxs)(n.p,{children:["In addition to verifying the deploy, you also need to ",(0,c.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/verify-transfer",children:"verify the transfer details"}),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>t});var c=a(96540);const s={},r=c.createContext(s);function d(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43a834ef.022fd866.js b/assets/js/43a834ef.022fd866.js deleted file mode 100644 index 76bdf31f5..000000000 --- a/assets/js/43a834ef.022fd866.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1991],{48596:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const i={title:"Move to Casper"},r="Moving to Casper from another Blockchain {#moving-to-casper}",o={id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/versioned_docs/version-1.5.X/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/resources/moving-to-casper",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/resources/tokens/"}},c={},l=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"moving-to-casper",children:"Moving to Casper from another Blockchain"})}),"\n",(0,s.jsx)(t.p,{children:"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-overview",children:"Smart Contract Platform Overview"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#variable-storage",children:"Variable Storage and State Management"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-functions",children:"Contract Functions"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#passing-arguments",children:"Passing Arguments"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"#additional-considerations",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"contract-overview",children:"Smart Contract Platform"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"Casper smart contracts are written in Rust."}),"\n",(0,s.jsxs)(t.p,{children:["Variables defined within the smart contract can be stored as either ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:"Named Keys"})," or ",(0,s.jsx)(t.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," as described in ",(0,s.jsx)(t.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"call"})," function serves as the main entry point of the ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"smart contract"}),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."]}),"\n",(0,s.jsxs)(t.p,{children:["It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"All public methods defined within the contract serve as its interface, exposing its functionality."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The Module's public methods are its interface and can be invoked from code outside the blockchain."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Solana smart contracts are primarily written in Rust."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"variable-storage",children:"Variable Storage and State Management"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsxs)(t.p,{children:["Variables can be stored as Named Keys or Dictionaries as described in ",(0,s.jsx)(t.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"contract-functions",children:"Contract Functions"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n \n // Entry point body\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html",children:"RuntimeArgs"})," passed to the contract. Entry points are instantiated within the ",(0,s.jsx)(t.code,{children:"call"})," entry point."]}),"\n",(0,s.jsxs)(t.p,{children:["If a return value is needed, it should be declared using the syntax described in the ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"runtime::ret(value);\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Each call to an entry point is treated as a ",(0,s.jsx)(t.a,{href:"/deploy-and-deploy-lifecycle",children:"Deploy"})," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit)."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The declaration of public methods in Ethereum follows the format:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function update_name(string value) public {\n dapp_name = value;\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"In the Near blockchain, there are three types of public functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Init Methods"})," - These are used as the class constructors to initialize the state of the contract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"View Methods"})," - These functions are used to read the state of the contract variables."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Call Methods"})," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The definition of public methods in Near is as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn add_message(&mut self, ...) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public methods that return variables, the definition would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun start_collection(account: &signer) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public functions that return variables, the definition would be as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun max(a: u8, b: u8): (u8, bool) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In the Aptos blockchain, it is possible to return one or more values from a function."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"entrypoint!(process_instruction);\n"})}),"\n",(0,s.jsx)(t.p,{children:"The implementation of the entry point may resemble the following:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Within the entry point function, the necessary parameters are specified, such as ",(0,s.jsx)(t.code,{children:"program_id"}),", which represents the program's identifier, ",(0,s.jsx)(t.code,{children:"accounts"}),", an array of ",(0,s.jsx)(t.code,{children:"AccountInfo"})," providing account details, and ",(0,s.jsx)(t.code,{children:"_instruction_data"}),", representing the instruction data received. The function returns a ",(0,s.jsx)(t.code,{children:"ProgramResult"}),", which indicates the success or failure of the instruction execution."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"passing-arguments",children:"Passing Arguments"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To understand the context of this example, refer to: ",(0,s.jsx)(t.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper Client"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In the contract, you can access the session arguments as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"let uref: URef = runtime::get_key(Key_Name)\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to retrieve the desired session argument by specifying the key's name."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are uncertain how to use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to obtain a specific session argument, check how to ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"write a basic smart contract on Casper"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"additional-considerations",children:"Additional Considerations"}),"\n",(0,s.jsx)(t.p,{children:"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)."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."}),"\n",(0,s.jsx)(t.p,{children:"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},i=s.createContext(a);function r(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43a834ef.36ed403d.js b/assets/js/43a834ef.36ed403d.js new file mode 100644 index 000000000..9833fc69c --- /dev/null +++ b/assets/js/43a834ef.36ed403d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1991],{48596:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const i={title:"Move to Casper"},r="Moving to Casper from another Blockchain {#moving-to-casper}",o={id:"resources/moving-to-casper",title:"Move to Casper",description:"moving-to-casper}",source:"@site/versioned_docs/version-1.5.X/resources/moving-to-casper.md",sourceDirName:"resources",slug:"/resources/moving-to-casper",permalink:"/1.5.X/resources/moving-to-casper",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Move to Casper"},sidebar:"resources",previous:{title:"Build on Casper",permalink:"/1.5.X/resources/build-on-casper/introduction"},next:{title:"Casper Token Standards",permalink:"/1.5.X/resources/tokens/"}},c={},l=[{value:"Smart Contract Platform",id:"contract-overview",level:2},{value:"Variable Storage and State Management",id:"variable-storage",level:2},{value:"Contract Functions",id:"contract-functions",level:2},{value:"Passing Arguments",id:"passing-arguments",level:2},{value:"Additional Considerations",id:"additional-considerations",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';\nimport Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"moving-to-casper",children:"Moving to Casper from another Blockchain"})}),"\n",(0,s.jsx)(t.p,{children:"This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-overview",children:"Smart Contract Platform Overview"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#variable-storage",children:"Variable Storage and State Management"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#contract-functions",children:"Contract Functions"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"#passing-arguments",children:"Passing Arguments"})}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Since other blockchain projects use different technologies, it is essential to consider how those technologies serve your use case."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"#additional-considerations",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"contract-overview",children:"Smart Contract Platform"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"Casper smart contracts are written in Rust."}),"\n",(0,s.jsxs)(t.p,{children:["Variables defined within the smart contract can be stored as either ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#namedkey",children:"Named Keys"})," or ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/dictionaries",children:"Dictionaries"})," as described in ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"call"})," function serves as the main entry point of the ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"smart contract"}),". It automatically executes when the smart contract is installed, setting the initial state of the contract and defining all other entry points."]}),"\n",(0,s.jsxs)(t.p,{children:["It's worth noting that Casper only supports public entry points for contracts. Additionally, contracts can be defined as upgradable or immutable as described ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/upgrading-contracts",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"Solidity smart contracts adhere to object-oriented programming principles and support features such as inheritance and libraries."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n",(0,s.jsx)(t.p,{children:"All public methods defined within the contract serve as its interface, exposing its functionality."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The Module's public methods are its interface and can be invoked from code outside the blockchain."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Solana smart contracts are primarily written in Rust."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"Smart contracts are commonly referred to as on-chain programs. These programs expose their interface as a public entry point, allowing external interaction."}),"\n",(0,s.jsx)(t.p,{children:'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.'}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"variable-storage",children:"Variable Storage and State Management"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsxs)(t.p,{children:["Variables can be stored as Named Keys or Dictionaries as described in ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to the Blockchain"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"Variables in the contract can be stored as native types, SDK collections, or internal structures. SDK collections offer advantages over native types."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"contract-functions",children:"Contract Functions"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"For Casper smart contracts, public functions are called entry points. To declare them, the following format is used:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n \n // Entry point body\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["It's important to note that entry points do not have input arguments in their definition, but the arguments can be accessed using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.RuntimeArgs.html",children:"RuntimeArgs"})," passed to the contract. Entry points are instantiated within the ",(0,s.jsx)(t.code,{children:"call"})," entry point."]}),"\n",(0,s.jsxs)(t.p,{children:["If a return value is needed, it should be declared using the syntax described in the ",(0,s.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"runtime::ret(value);\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Each call to an entry point is treated as a ",(0,s.jsx)(t.a,{href:"/1.5.X/deploy-and-deploy-lifecycle",children:"Deploy"})," to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit)."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"The declaration of public methods in Ethereum follows the format:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function update_name(string value) public {\n dapp_name = value;\n}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In cases where a public method only returns a value without modifying the state, it should be defined as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"function balanceOf(address _owner) public view returns (uint256 return_parameter) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"It is worth noting that public view methods on Ethereum, which solely retrieve data without making state changes, do not consume gas."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"In the Near blockchain, there are three types of public functions:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Init Methods"})," - These are used as the class constructors to initialize the state of the contract."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"View Methods"})," - These functions are used to read the state of the contract variables."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Call Methods"})," - These methods can mutate the state of the contract and perform specific actions, such as calling another contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The definition of public methods in Near is as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn add_message(&mut self, ...) { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public methods that return variables, the definition would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn get_messages(&self, from_index: Option<U128>, limit: Option<u64>) -> Vec<PostedMessage> { }\n"})}),"\n",(0,s.jsx)(t.p,{children:"The actual implementation of the functions may include the necessary parameters and logic based on the contract's specific requirements."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun start_collection(account: &signer) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"For public functions that return variables, the definition would be as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"public fun max(a: u8, b: u8): (u8, bool) {}\n"})}),"\n",(0,s.jsx)(t.p,{children:"In the Aptos blockchain, it is possible to return one or more values from a function."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"entrypoint!(process_instruction);\n"})}),"\n",(0,s.jsx)(t.p,{children:"The implementation of the entry point may resemble the following:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"pub fn process_instruction(\n program_id: &Pubkey,\n accounts: &[AccountInfo],\n _instruction_data: &[u8],\n) -> ProgramResult {}\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Within the entry point function, the necessary parameters are specified, such as ",(0,s.jsx)(t.code,{children:"program_id"}),", which represents the program's identifier, ",(0,s.jsx)(t.code,{children:"accounts"}),", an array of ",(0,s.jsx)(t.code,{children:"AccountInfo"})," providing account details, and ",(0,s.jsx)(t.code,{children:"_instruction_data"}),", representing the instruction data received. The function returns a ",(0,s.jsx)(t.code,{children:"ProgramResult"}),", which indicates the success or failure of the instruction execution."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"passing-arguments",children:"Passing Arguments"}),"\n",(0,s.jsxs)(t.tabs,{children:["\n",(0,s.jsxs)(t.tabitem,{value:"Casper",label:"Casper",children:["\n",(0,s.jsx)(t.p,{children:"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:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To understand the context of this example, refer to: ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/delegate",children:"Delegating with the Casper Client"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"In the contract, you can access the session arguments as follows:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"let uref: URef = runtime::get_key(Key_Name)\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to retrieve the desired session argument by specifying the key's name."]}),"\n",(0,s.jsxs)(t.p,{children:["If you are uncertain how to use the ",(0,s.jsx)(t.code,{children:"get_key"})," function to obtain a specific session argument, check how to ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"write a basic smart contract on Casper"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Ethereum",label:"Ethereum",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Near",label:"Near",children:["\n",(0,s.jsx)(t.p,{children:"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."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Aptos",label:"Aptos",children:["\n",(0,s.jsx)(t.p,{children:"Like Near, Aptos requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n",(0,s.jsxs)(t.tabitem,{value:"Solana",label:"Solana",children:["\n",(0,s.jsx)(t.p,{children:"Like Near and Aptos, Solana requires strongly typed function arguments, thus preventing type-related errors and promoting code correctness."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"additional-considerations",children:"Additional Considerations"}),"\n",(0,s.jsx)(t.p,{children:"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)."}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Considering these aspects helps when selecting a blockchain that aligns with a project or application's specific requirements and goals."}),"\n",(0,s.jsx)(t.p,{children:"The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects."})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},i=s.createContext(a);function r(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43fd3112.179a51de.js b/assets/js/43fd3112.179a51de.js deleted file mode 100644 index 18a0411ba..000000000 --- a/assets/js/43fd3112.179a51de.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4191],{41699:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="E",a={id:"concepts/glossary/E",title:"E",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/E.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/E",permalink:"/concepts/glossary/E",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"D",permalink:"/concepts/glossary/D"},next:{title:"F",permalink:"/concepts/glossary/F"}},i={},l=[{value:"Ecosystem",id:"ecosystem",level:2},{value:"Entry point",id:"entry-point",level:2},{value:"Era",id:"era",level:2},{value:"Eviction",id:"eviction",level:2},{value:"External client",id:"external-client",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"e",children:"E"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,r.jsx)(s.p,{children:"The ecosystem layer in Casper encompasses dApp design and operation."}),"\n",(0,r.jsx)(s.h2,{id:"entry-point",children:"Entry point"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/developers/json-rpc/types_chain#entrypoint",children:"EntryPoint"})," and ",(0,r.jsx)(s.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Defining the Contract Entry Points"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"era",children:"Era"}),"\n",(0,r.jsx)(s.p,{children:"A period of time during which the validator set does not change."}),"\n",(0,r.jsxs)(s.p,{children:["In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an ",(0,r.jsx)(s.a,{href:"/concepts/glossary/A#auction",children:"auction"}),". At the beginning of the era, the validators create a new instance of the Highway protocol and run this consensus protocol until they finalize the era's last block (see ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"}),")."]}),"\n",(0,r.jsx)(s.h2,{id:"eviction",children:"Eviction"}),"\n",(0,r.jsxs)(s.p,{children:["Validators that fail to participate in ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E#era",children:"era"})," will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"external-client",children:"External client"}),"\n",(0,r.jsx)(s.p,{children:"Any hardware/software connecting to a Node for the purpose of sending deploys or querying the state of the blockchain."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/43fd3112.e7439ebf.js b/assets/js/43fd3112.e7439ebf.js new file mode 100644 index 000000000..dbaaab8d9 --- /dev/null +++ b/assets/js/43fd3112.e7439ebf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34191],{41699:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="E",a={id:"concepts/glossary/E",title:"E",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/E.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/E",permalink:"/1.5.X/concepts/glossary/E",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"D",permalink:"/1.5.X/concepts/glossary/D"},next:{title:"F",permalink:"/1.5.X/concepts/glossary/F"}},i={},l=[{value:"Ecosystem",id:"ecosystem",level:2},{value:"Entry point",id:"entry-point",level:2},{value:"Era",id:"era",level:2},{value:"Eviction",id:"eviction",level:2},{value:"External client",id:"external-client",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"e",children:"E"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,r.jsx)(s.p,{children:"The ecosystem layer in Casper encompasses dApp design and operation."}),"\n",(0,r.jsx)(s.h2,{id:"entry-point",children:"Entry point"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/developers/json-rpc/types_chain#entrypoint",children:"EntryPoint"})," and ",(0,r.jsx)(s.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Defining the Contract Entry Points"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"era",children:"Era"}),"\n",(0,r.jsx)(s.p,{children:"A period of time during which the validator set does not change."}),"\n",(0,r.jsxs)(s.p,{children:["In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A#auction",children:"auction"}),". At the beginning of the era, the validators create a new instance of the Highway protocol and run this consensus protocol until they finalize the era's last block (see ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#booking-block",children:"booking block"}),")."]}),"\n",(0,r.jsx)(s.h2,{id:"eviction",children:"Eviction"}),"\n",(0,r.jsxs)(s.p,{children:["Validators that fail to participate in ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E#era",children:"era"})," will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A#auction-contract",children:"auction contract"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"external-client",children:"External client"}),"\n",(0,r.jsx)(s.p,{children:"Any hardware/software connecting to a Node for the purpose of sending deploys or querying the state of the blockchain."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4423d65b.01606f7a.js b/assets/js/4423d65b.01606f7a.js deleted file mode 100644 index 8de45b753..000000000 --- a/assets/js/4423d65b.01606f7a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7201],{15944:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>h,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const t={},o="H",a={id:"concepts/glossary/H",title:"H",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/H.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/H",permalink:"/concepts/glossary/H",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"G",permalink:"/concepts/glossary/G"},next:{title:"I",permalink:"/concepts/glossary/I"}},h={},l=[{value:"Hash",id:"hash",level:2},{value:"Highway",id:"highway",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"h",children:"H"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"hash",children:"Hash"}),"\n",(0,r.jsxs)(s.p,{children:["A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B#blake2b",children:"blake2b"})," function."]}),"\n",(0,r.jsx)(s.h2,{id:"highway",children:"Highway"}),"\n",(0,r.jsxs)(s.p,{children:["A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is ",(0,r.jsx)(s.em,{children:"finalized"}),". The full paper is found in GitHub: ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/highway",children:"https://github.com/casper-network/highway"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4423d65b.43623fa8.js b/assets/js/4423d65b.43623fa8.js new file mode 100644 index 000000000..4f6ec94ac --- /dev/null +++ b/assets/js/4423d65b.43623fa8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[17201],{15944:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>h,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const t={},o="H",a={id:"concepts/glossary/H",title:"H",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/H.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/H",permalink:"/1.5.X/concepts/glossary/H",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"G",permalink:"/1.5.X/concepts/glossary/G"},next:{title:"I",permalink:"/1.5.X/concepts/glossary/I"}},h={},l=[{value:"Hash",id:"hash",level:2},{value:"Highway",id:"highway",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"h",children:"H"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"hash",children:"Hash"}),"\n",(0,r.jsxs)(s.p,{children:["A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#blake2b",children:"blake2b"})," function."]}),"\n",(0,r.jsx)(s.h2,{id:"highway",children:"Highway"}),"\n",(0,r.jsxs)(s.p,{children:["A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is ",(0,r.jsx)(s.em,{children:"finalized"}),". The full paper is found in GitHub: ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/highway",children:"https://github.com/casper-network/highway"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/449bc0d9.5dd63daf.js b/assets/js/449bc0d9.5dd63daf.js deleted file mode 100644 index 282529865..000000000 --- a/assets/js/449bc0d9.5dd63daf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2686],{34406:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>o,frontMatter:()=>i,metadata:()=>c,toc:()=>h});var r=s(74848),t=s(28453);const i={},d="Users Overview",c={id:"users/index",title:"Users Overview",description:"General Topics",source:"@site/docs/users/index.md",sourceDirName:"users",slug:"/users/",permalink:"/next/users/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{},sidebar:"users",next:{title:"Block Explorers",permalink:"/next/users/block-explorer"}},l={},h=[{value:"General Topics",id:"general-topics",level:2},{value:"Using CSPR.live",id:"using-csprlive",level:2},{value:"Using Ledger Devices",id:"using-ledger-devices",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"users-overview",children:"Users Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"general-topics",children:"General Topics"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/block-explorer",children:"Block Explorers"})}),(0,r.jsx)(n.td,{children:"A guide to understanding block explorers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/funding-from-exchanges",children:"Funding Mainnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding Mainnet accounts from an exchange"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/delegating",children:"Delegating Tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator (a.k.a. staking with a validator)"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-csprlive",children:"Using CSPR.live"}),"\n",(0,r.jsxs)(n.p,{children:["Interact with the Casper blockchain using the ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding your Testnet account using the Faucet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/delegate-ui",children:"Delegating Tokens"})}),(0,r.jsxs)(n.td,{children:["Staking your Casper tokens with ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,r.jsx)(n.td,{children:"Un-staking your Casper tokens"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/token-transfer",children:"Transferring Tokens"})}),(0,r.jsxs)(n.td,{children:["Transferring your Casper tokens using ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-ledger-devices",children:"Using Ledger Devices"}),"\n",(0,r.jsx)(n.p,{children:"Interact with the Casper blockchain using a Ledger device."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/workflow/ledger-setup/",children:"Ledger Setup"})}),(0,r.jsx)(n.td,{children:"A guide to setting up your Ledger device"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,r.jsx)(n.td,{children:"Delegating tokens using your Ledger device"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/449bc0d9.ed4526e9.js b/assets/js/449bc0d9.ed4526e9.js new file mode 100644 index 000000000..afc86a165 --- /dev/null +++ b/assets/js/449bc0d9.ed4526e9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32686],{34406:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>o,frontMatter:()=>i,metadata:()=>c,toc:()=>h});var r=s(74848),t=s(28453);const i={},d="Users Overview",c={id:"users/index",title:"Users Overview",description:"General Topics",source:"@site/docs/users/index.md",sourceDirName:"users",slug:"/users/",permalink:"/users/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{},sidebar:"users",next:{title:"Block Explorers",permalink:"/users/block-explorer"}},l={},h=[{value:"General Topics",id:"general-topics",level:2},{value:"Using CSPR.live",id:"using-csprlive",level:2},{value:"Using Ledger Devices",id:"using-ledger-devices",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"users-overview",children:"Users Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"general-topics",children:"General Topics"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/block-explorer",children:"Block Explorers"})}),(0,r.jsx)(n.td,{children:"A guide to understanding block explorers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/funding-from-exchanges",children:"Funding Mainnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding Mainnet accounts from an exchange"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/delegating",children:"Delegating Tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator (a.k.a. staking with a validator)"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-csprlive",children:"Using CSPR.live"}),"\n",(0,r.jsxs)(n.p,{children:["Interact with the Casper blockchain using the ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding your Testnet account using the Faucet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating Tokens"})}),(0,r.jsxs)(n.td,{children:["Staking your Casper tokens with ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,r.jsx)(n.td,{children:"Un-staking your Casper tokens"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens"})}),(0,r.jsxs)(n.td,{children:["Transferring your Casper tokens using ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-ledger-devices",children:"Using Ledger Devices"}),"\n",(0,r.jsx)(n.p,{children:"Interact with the Casper blockchain using a Ledger device."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup"})}),(0,r.jsx)(n.td,{children:"A guide to setting up your Ledger device"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,r.jsx)(n.td,{children:"Delegating tokens using your Ledger device"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/452e65d7.1de256df.js b/assets/js/452e65d7.1de256df.js new file mode 100644 index 000000000..789e27d85 --- /dev/null +++ b/assets/js/452e65d7.1de256df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[89109],{30383:(n,e,d)=>{d.r(e),d.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>x,frontMatter:()=>r,metadata:()=>i,toc:()=>h});var s=d(74848),t=d(28453);const r={title:"OpCode Costs Tables"},c="OpCode Costs Tables",i={id:"developers/cli/opcode-costs",title:"OpCode Costs Tables",description:"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.",source:"@site/docs/developers/cli/opcode-costs.md",sourceDirName:"developers/cli",slug:"/developers/cli/opcode-costs",permalink:"/developers/cli/opcode-costs",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"OpCode Costs Tables"},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/developers/cli/calling-contracts"},next:{title:"Execution Error Codes",permalink:"/developers/cli/execution-error-codes"}},l={},h=[{value:"Storage Costs",id:"storage-costs",level:2},{value:"OpCode Costs",id:"opcode-costs",level:2},{value:"Control Flow Operation Costs",id:"control-flow-operation-costs",level:2},{value:"<code>Br_Table</code> OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"<code>Auction</code> System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"<code>Mint</code> System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"<code>Handle_Payment</code> System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"<code>Standard_Payment</code> System Contract Costs",id:"standard_payment-system-contract-costs",level:3}];function o(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"opcode-costs-tables",children:"OpCode Costs Tables"})}),"\n",(0,s.jsxs)(e.p,{children:["The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,s.jsx)(e.code,{children:"chainspec.toml"}),"."]}),"\n",(0,s.jsxs)(e.p,{children:["More information on ",(0,s.jsx)(e.code,{children:"chainspec"}),"s for private networks can be found ",(0,s.jsx)(e.a,{href:"/operators/setup-network/chain-spec",children:"here"})]}),"\n",(0,s.jsx)(e.admonition,{type:"note",children:(0,s.jsxs)(e.p,{children:["All costs in this table are in ",(0,s.jsx)(e.a,{href:"/concepts/glossary/M/#motes",children:"motes"}),", not CSPR, and the corresponding chainspec is ",(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129",children:"here"}),"."]})}),"\n",(0,s.jsx)(e.h2,{id:"storage-costs",children:"Storage Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,s.jsx)(e.h2,{id:"opcode-costs",children:"OpCode Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"control-flow-operation-costs",children:"Control Flow Operation Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsxs)(e.h2,{id:"br_table-opcode-costs",children:[(0,s.jsx)(e.code,{children:"Br_Table"})," OpCode Costs"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"external-function-costs",children:"External Function Costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,s.jsx)(e.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Host-Side Function"}),(0,s.jsx)(e.th,{children:"Cost"}),(0,s.jsx)(e.th,{children:"Arguments"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"5_800"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_associated_key"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"blake2b"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_versioned_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_purse"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"disable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_balance"}),(0,s.jsx)(e.td,{children:"3_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_blocktime"}),(0,s.jsx)(e.td,{children:"330"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_caller"}),(0,s.jsx)(e.td,{children:"380"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_key"}),(0,s.jsx)(e.td,{children:"2_000"}),(0,s.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_main_purse"}),(0,s.jsx)(e.td,{children:"1_300"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg_size"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_phase"}),(0,s.jsx)(e.td,{children:"710"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_system_contract"}),(0,s.jsx)(e.td,{children:"1_100"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"has_key"}),(0,s.jsx)(e.td,{children:"1_500"}),(0,s.jsx)(e.td,{children:"[0, 840]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"is_valid_uref"}),(0,s.jsx)(e.td,{children:"760"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load_named_keys"}),(0,s.jsx)(e.td,{children:"42_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"new_uref"}),(0,s.jsx)(e.td,{children:"17_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"random_bytes"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"print"}),(0,s.jsx)(e.td,{children:"20_000"}),(0,s.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"put_key"}),(0,s.jsx)(e.td,{children:"100_000_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_host_buffer"}),(0,s.jsx)(e.td,{children:"3_500"}),(0,s.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value"}),(0,s.jsx)(e.td,{children:"60_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value_local"}),(0,s.jsx)(e.td,{children:"5_500"}),(0,s.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_key"}),(0,s.jsx)(e.td,{children:"61_000"}),(0,s.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"ret"}),(0,s.jsx)(e.td,{children:"23_000"}),(0,s.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"revert"}),(0,s.jsx)(e.td,{children:"500"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_action_threshold"}),(0,s.jsx)(e.td,{children:"74_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,s.jsx)(e.td,{children:"82_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"update_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"write"}),(0,s.jsx)(e.td,{children:"14_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"dictionary_put"}),(0,s.jsx)(e.td,{children:"9_500"}),(0,s.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"enable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"manage_message_topic"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"emit_message"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost_increase_per_message"}),(0,s.jsx)(e.td,{children:"50"}),(0,s.jsx)(e.td,{})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"auction-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Auction"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"change_bid_public_key"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"mint-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Mint"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"burn"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"handle_payment-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Handle_Payment"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"standard_payment-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Standard_Payment"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function x(n={}){const{wrapper:e}={...(0,t.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,d)=>{d.d(e,{R:()=>c,x:()=>i});var s=d(96540);const t={},r=s.createContext(t);function c(n){const e=s.useContext(r);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function i(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:c(n.components),s.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/452e65d7.cb4a29c5.js b/assets/js/452e65d7.cb4a29c5.js deleted file mode 100644 index 00edd2eee..000000000 --- a/assets/js/452e65d7.cb4a29c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9109],{30383:(n,e,d)=>{d.r(e),d.d(e,{assets:()=>l,contentTitle:()=>c,default:()=>x,frontMatter:()=>r,metadata:()=>i,toc:()=>h});var t=d(74848),s=d(28453);const r={title:"OpCode Costs Tables"},c="OpCode Costs Tables",i={id:"developers/cli/opcode-costs",title:"OpCode Costs Tables",description:"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.",source:"@site/docs/developers/cli/opcode-costs.md",sourceDirName:"developers/cli",slug:"/developers/cli/opcode-costs",permalink:"/next/developers/cli/opcode-costs",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"OpCode Costs Tables"},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/next/developers/cli/calling-contracts"},next:{title:"Execution Error Codes",permalink:"/next/developers/cli/execution-error-codes"}},l={},h=[{value:"Storage Costs",id:"storage-costs",level:2},{value:"OpCode Costs",id:"opcode-costs",level:2},{value:"Control Flow Operation Costs",id:"control-flow-operation-costs",level:2},{value:"<code>Br_Table</code> OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"<code>Auction</code> System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"<code>Mint</code> System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"<code>Handle_Payment</code> System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"<code>Standard_Payment</code> System Contract Costs",id:"standard_payment-system-contract-costs",level:3}];function o(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"opcode-costs-tables",children:"OpCode Costs Tables"})}),"\n",(0,t.jsxs)(e.p,{children:["The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,t.jsx)(e.code,{children:"chainspec.toml"}),"."]}),"\n",(0,t.jsxs)(e.p,{children:["More information on ",(0,t.jsx)(e.code,{children:"chainspec"}),"s for private networks can be found ",(0,t.jsx)(e.a,{href:"/next/operators/setup-network/chain-spec",children:"here"})]}),"\n",(0,t.jsx)(e.admonition,{type:"note",children:(0,t.jsxs)(e.p,{children:["All costs in this table are in ",(0,t.jsx)(e.a,{href:"/concepts/glossary/M/#motes",children:"motes"}),", not CSPR, and the corresponding chainspec is ",(0,t.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129",children:"here"}),"."]})}),"\n",(0,t.jsx)(e.h2,{id:"storage-costs",children:"Storage Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"gas_per_byte"}),(0,t.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,t.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,t.jsx)(e.h2,{id:"opcode-costs",children:"OpCode Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"bit"}),(0,t.jsx)(e.td,{children:"Bit operations multiplier."}),(0,t.jsx)(e.td,{children:"300"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,t.jsx)(e.td,{children:"210"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mul"}),(0,t.jsx)(e.td,{children:"Mul operations multiplier."}),(0,t.jsx)(e.td,{children:"240"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"div"}),(0,t.jsx)(e.td,{children:"Div operations multiplier."}),(0,t.jsx)(e.td,{children:"320"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load"}),(0,t.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,t.jsx)(e.td,{children:"2_500"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"store"}),(0,t.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,t.jsx)(e.td,{children:"4_700"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"const"}),(0,t.jsx)(e.td,{children:"Const store operation multiplier."}),(0,t.jsx)(e.td,{children:"110"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"local"}),(0,t.jsx)(e.td,{children:"Local operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"global"}),(0,t.jsx)(e.td,{children:"Global operations multiplier."}),(0,t.jsx)(e.td,{children:"390"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"integer_comparison"}),(0,t.jsx)(e.td,{children:"Integer operations multiplier."}),(0,t.jsx)(e.td,{children:"250"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"conversion"}),(0,t.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,t.jsx)(e.td,{children:"420"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"unreachable"}),(0,t.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,t.jsx)(e.td,{children:"270"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"nop"}),(0,t.jsx)(e.td,{children:"Nop operation multiplier."}),(0,t.jsx)(e.td,{children:"200"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"current_memory"}),(0,t.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,t.jsx)(e.td,{children:"290"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"grow_memory"}),(0,t.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,t.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"control-flow-operation-costs",children:"Control Flow Operation Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"block"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"block"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"loop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"loop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"if"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"else"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"else"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"end"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"end"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br"})," opcode."]}),(0,t.jsx)(e.td,{children:"35_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"br_if"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,t.jsx)(e.td,{children:"35_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"return"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"return"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"select"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"select"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call"})," opcode."]}),(0,t.jsx)(e.td,{children:"68_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_indirect"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,t.jsx)(e.td,{children:"68_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"drop"}),(0,t.jsxs)(e.td,{children:["Cost for ",(0,t.jsx)(e.code,{children:"drop"})," opcode."]}),(0,t.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,t.jsxs)(e.h2,{id:"br_table-opcode-costs",children:[(0,t.jsx)(e.code,{children:"Br_Table"})," OpCode Costs"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Attribute"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"cost"}),(0,t.jsxs)(e.td,{children:["Fixed cost per ",(0,t.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,t.jsx)(e.td,{children:"35_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"size_multiplier"}),(0,t.jsxs)(e.td,{children:["Size of target labels in the ",(0,t.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,t.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,t.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,t.jsx)(e.h2,{id:"external-function-costs",children:"External Function Costs"}),"\n",(0,t.jsxs)(e.p,{children:['The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,t.jsx)(e.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Host-Side Function"}),(0,t.jsx)(e.th,{children:"Cost"}),(0,t.jsx)(e.th,{children:"Arguments"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add"}),(0,t.jsx)(e.td,{children:"5_800"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_associated_key"}),(0,t.jsx)(e.td,{children:"1_200_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"blake2b"}),(0,t.jsx)(e.td,{children:"1_200_000"}),(0,t.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_contract"}),(0,t.jsx)(e.td,{children:"300_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"call_versioned_contract"}),(0,t.jsx)(e.td,{children:"300_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create_purse"}),(0,t.jsx)(e.td,{children:"2_500_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"disable_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_balance"}),(0,t.jsx)(e.td,{children:"3_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_blocktime"}),(0,t.jsx)(e.td,{children:"330"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_caller"}),(0,t.jsx)(e.td,{children:"380"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_key"}),(0,t.jsx)(e.td,{children:"2_000"}),(0,t.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_main_purse"}),(0,t.jsx)(e.td,{children:"1_300"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_named_arg_size"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_phase"}),(0,t.jsx)(e.td,{children:"710"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_system_contract"}),(0,t.jsx)(e.td,{children:"1_100"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"has_key"}),(0,t.jsx)(e.td,{children:"1_500"}),(0,t.jsx)(e.td,{children:"[0, 840]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"is_valid_uref"}),(0,t.jsx)(e.td,{children:"760"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"load_named_keys"}),(0,t.jsx)(e.td,{children:"42_000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"new_uref"}),(0,t.jsx)(e.td,{children:"17_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"random_bytes"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"print"}),(0,t.jsx)(e.td,{children:"20_000"}),(0,t.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"put_key"}),(0,t.jsx)(e.td,{children:"100_000_000"}),(0,t.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_host_buffer"}),(0,t.jsx)(e.td,{children:"3_500"}),(0,t.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value"}),(0,t.jsx)(e.td,{children:"60_000"}),(0,t.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_value_local"}),(0,t.jsx)(e.td,{children:"5_500"}),(0,t.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_associated_key"}),(0,t.jsx)(e.td,{children:"4_200"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"remove_key"}),(0,t.jsx)(e.td,{children:"61_000"}),(0,t.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"ret"}),(0,t.jsx)(e.td,{children:"23_000"}),(0,t.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"revert"}),(0,t.jsx)(e.td,{children:"500"}),(0,t.jsx)(e.td,{children:"[0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_action_threshold"}),(0,t.jsx)(e.td,{children:"74_000"}),(0,t.jsx)(e.td,{children:"[0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,t.jsx)(e.td,{children:"2_500_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,t.jsx)(e.td,{children:"82_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer_to_account"}),(0,t.jsx)(e.td,{children:"2_500_000_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"update_associated_key"}),(0,t.jsx)(e.td,{children:"4_200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"write"}),(0,t.jsx)(e.td,{children:"14_000"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"dictionary_put"}),(0,t.jsx)(e.td,{children:"9_500"}),(0,t.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"enable_contract_version"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"manage_message_topic"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"emit_message"}),(0,t.jsx)(e.td,{children:"200"}),(0,t.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"cost_increase_per_message"}),(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"auction-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Auction"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_era_validators"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"add_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"delegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"undelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"run_auction"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"slash"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"distribute"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_era_id"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"activate_bid"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"redelegate"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"change_bid_public_key"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"mint-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Mint"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling ",(0,t.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"reduce_total_supply"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"create"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"balance"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"burn"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"transfer"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"read_base_round_reward"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"handle_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Handle_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These are the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_payment_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"set_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"get_refund_purse"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"finalize_payment"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,t.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,t.jsxs)(e.h3,{id:"standard_payment-system-contract-costs",children:[(0,t.jsx)(e.code,{children:"Standard_Payment"})," System Contract Costs"]}),"\n",(0,t.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,t.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint"}),(0,t.jsx)(e.th,{children:"Description"}),(0,t.jsx)(e.th,{children:"Cost"})]})}),(0,t.jsx)(e.tbody,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"pay"}),(0,t.jsxs)(e.td,{children:["Cost of calling the ",(0,t.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,t.jsx)(e.td,{children:"10_000"})]})})]})]})}function x(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(o,{...n})}):o(n)}},28453:(n,e,d)=>{d.d(e,{R:()=>c,x:()=>i});var t=d(96540);const s={},r=t.createContext(s);function c(n){const e=t.useContext(r);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function i(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:c(n.components),t.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/4545390c.0ca5f8dc.js b/assets/js/4545390c.0ca5f8dc.js deleted file mode 100644 index e4cd143d4..000000000 --- a/assets/js/4545390c.0ca5f8dc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2720],{20688:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=s(74848),r=s(28453);const c={},o="T",a={id:"concepts/glossary/T",title:"T",description:"---",source:"@site/docs/concepts/glossary/T.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/T",permalink:"/next/concepts/glossary/T",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"S",permalink:"/next/concepts/glossary/S"},next:{title:"U",permalink:"/next/concepts/glossary/U"}},i={},l=[{value:"Token",id:"token",level:2},{value:"Transaction",id:"transaction",level:2},{value:"Turing-complete blockchain",id:"turing-complete-blockchain",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"t",children:"T"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"token",children:"Token"}),"\n",(0,t.jsxs)(n.p,{children:["A type of cryptocurrency that represents an asset. See ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,t.jsxs)(n.p,{children:["Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D#deploy",children:"Deploy"}),". Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found ",(0,t.jsx)(n.a,{href:"/next/transactions",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"turing-complete-blockchain",children:"Turing-complete blockchain"}),"\n",(0,t.jsx)(n.p,{children:"Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets."}),"\n",(0,t.jsx)(n.p,{children:"For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference."})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},c=t.createContext(r);function o(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4545390c.1d3a08c0.js b/assets/js/4545390c.1d3a08c0.js new file mode 100644 index 000000000..896d9c42b --- /dev/null +++ b/assets/js/4545390c.1d3a08c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82720],{20688:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const t={},o="T",a={id:"concepts/glossary/T",title:"T",description:"---",source:"@site/docs/concepts/glossary/T.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/T",permalink:"/concepts/glossary/T",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"S",permalink:"/concepts/glossary/S"},next:{title:"U",permalink:"/concepts/glossary/U"}},i={},l=[{value:"Token",id:"token",level:2},{value:"Transaction",id:"transaction",level:2},{value:"Turing-complete blockchain",id:"turing-complete-blockchain",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"t",children:"T"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"token",children:"Token"}),"\n",(0,r.jsxs)(s.p,{children:["A type of cryptocurrency that represents an asset. See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"transaction",children:"Transaction"}),"\n",(0,r.jsxs)(s.p,{children:["Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"}),". Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found ",(0,r.jsx)(s.a,{href:"/transactions",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"turing-complete-blockchain",children:"Turing-complete blockchain"}),"\n",(0,r.jsx)(s.p,{children:"Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets."}),"\n",(0,r.jsx)(s.p,{children:"For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/459c4db6.2d3b0e56.js b/assets/js/459c4db6.2d3b0e56.js deleted file mode 100644 index e4031335d..000000000 --- a/assets/js/459c4db6.2d3b0e56.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5338],{11878:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=s(74848),n=s(28453);const o={},c="Execution Error Codes",i={id:"developers/cli/execution-error-codes",title:"Execution Error Codes",description:"This section covers smart contract execution error codes.",source:"@site/docs/developers/cli/execution-error-codes.md",sourceDirName:"developers/cli",slug:"/developers/cli/execution-error-codes",permalink:"/next/developers/cli/execution-error-codes",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"OpCode Costs Tables",permalink:"/next/developers/cli/opcode-costs"}},a={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"execution-error-codes",children:"Execution Error Codes"})}),"\n",(0,t.jsx)(r.p,{children:"This section covers smart contract execution error codes."}),"\n",(0,t.jsxs)(r.p,{children:["As mentioned in ",(0,t.jsx)(r.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts"}),", smart contracts can exit with an error code defined by an ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html",children:"ApiError"}),". Descriptions of each variant are found ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"})," and include the following sub-types:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.HandlePayment",children:"payment errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.Mint",children:"mint errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.User",children:"custom user errors"})}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["An ",(0,t.jsx)(r.code,{children:"ApiError"})," of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ",(0,t.jsx)(r.code,{children:"ApiError::User(2)"})," maps to an exit code of ",(0,t.jsx)(r.code,{children:"65538"})," (i.e. ",(0,t.jsx)(r.code,{children:"65536 + 2"}),"). You can find a mapping from contract exit codes to ",(0,t.jsx)(r.code,{children:"ApiError"})," variants ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>c,x:()=>i});var t=s(96540);const n={},o=t.createContext(n);function c(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/459c4db6.5ba5952e.js b/assets/js/459c4db6.5ba5952e.js new file mode 100644 index 000000000..340b0ae2b --- /dev/null +++ b/assets/js/459c4db6.5ba5952e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15338],{11878:(e,r,s)=>{s.r(r),s.d(r,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var t=s(74848),n=s(28453);const o={},c="Execution Error Codes",i={id:"developers/cli/execution-error-codes",title:"Execution Error Codes",description:"This section covers smart contract execution error codes.",source:"@site/docs/developers/cli/execution-error-codes.md",sourceDirName:"developers/cli",slug:"/developers/cli/execution-error-codes",permalink:"/developers/cli/execution-error-codes",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"OpCode Costs Tables",permalink:"/developers/cli/opcode-costs"}},a={},d=[];function p(e){const r={a:"a",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,n.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(r.header,{children:(0,t.jsx)(r.h1,{id:"execution-error-codes",children:"Execution Error Codes"})}),"\n",(0,t.jsx)(r.p,{children:"This section covers smart contract execution error codes."}),"\n",(0,t.jsxs)(r.p,{children:["As mentioned in ",(0,t.jsx)(r.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts"}),", smart contracts can exit with an error code defined by an ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html",children:"ApiError"}),". Descriptions of each variant are found ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"})," and include the following sub-types:"]}),"\n",(0,t.jsxs)(r.ul,{children:["\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.HandlePayment",children:"payment errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.Mint",children:"mint errors"})}),"\n",(0,t.jsx)(r.li,{children:(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variant.User",children:"custom user errors"})}),"\n"]}),"\n",(0,t.jsxs)(r.p,{children:["An ",(0,t.jsx)(r.code,{children:"ApiError"})," of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ",(0,t.jsx)(r.code,{children:"ApiError::User(2)"})," maps to an exit code of ",(0,t.jsx)(r.code,{children:"65538"})," (i.e. ",(0,t.jsx)(r.code,{children:"65536 + 2"}),"). You can find a mapping from contract exit codes to ",(0,t.jsx)(r.code,{children:"ApiError"})," variants ",(0,t.jsx)(r.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.ApiError.html#variants",children:"here"}),"."]})]})}function l(e={}){const{wrapper:r}={...(0,n.R)(),...e.components};return r?(0,t.jsx)(r,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,r,s)=>{s.d(r,{R:()=>c,x:()=>i});var t=s(96540);const n={},o=t.createContext(n);function c(e){const r=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function i(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),t.createElement(o.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46206018.718b2b19.js b/assets/js/46206018.718b2b19.js new file mode 100644 index 000000000..6a662bb4c --- /dev/null +++ b/assets/js/46206018.718b2b19.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46198],{85102:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var a=n(74848),i=n(28453);const o={},s="Delegating Tokens",r={id:"users/delegating",title:"Delegating Tokens",description:"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.",source:"@site/versioned_docs/version-2.0.0/users/delegating.md",sourceDirName:"users",slug:"/users/delegating",permalink:"/2.0.0/users/delegating",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"users",previous:{title:"Funding Mainnet Accounts",permalink:"/2.0.0/users/funding-from-exchanges"},next:{title:"Using CSPR.live",permalink:"/2.0.0/users/csprlive/"}},l={},d=[{value:"Delegation Cost",id:"delegation-cost",level:2},{value:"Delegation Limits",id:"delegation-limits",level:2},{value:"Selecting a Node for Delegating",id:"selecting-a-node-for-delegating",level:2},{value:"First-time Delegation",id:"first-time-delegation",level:2},{value:"Monitoring Rewards",id:"monitoring-rewards",level:2},{value:"Tutorials",id:"tutorials",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"delegating-tokens",children:"Delegating Tokens"})}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as ",(0,a.jsx)(t.strong,{children:"delegating"})," or ",(0,a.jsx)(t.strong,{children:"staking"})," with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider."]}),"\n",(0,a.jsx)(t.p,{children:"Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network."}),"\n",(0,a.jsx)(t.p,{children:"Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate."}),"\n",(0,a.jsx)(t.p,{children:"Casper does not treat validator stake differently than delegator stake for security reasons."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-cost",children:"Delegation Cost"}),"\n",(0,a.jsx)(t.p,{children:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates to delegations, and where to find more details. Please note that the cost amounts are likely to change over time, and you may have to check the latest release details to get the most up-to-date and accurate delegation cost."}),"\n",(0,a.jsxs)(t.p,{children:["The delegation cost is defined in the chainspec.toml file of a Casper network. In this ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-2.0.0-rc1/resources/production/chainspec.toml",children:"example chainspec"}),", the delegation is set to cost 2.5 CSPR. However, ",(0,a.jsx)(t.code,{children:"when you perform the delegation, you see that it costs a little more"})," than what is specified in the chainspec. Let's discuss why this happens."]}),"\n",(0,a.jsx)(t.p,{children:"When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is added to the delegation cost defined in the chainspec file. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse."}),"\n",(0,a.jsxs)(t.p,{children:["For example, the chainspec file in release 2.0.0 contains the following information. Notice the delegation cost specified with ",(0,a.jsx)(t.code,{children:"delegate"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"[system_costs.auction_costs]\n...\ndelegate = 2_500_000_000\nundelegate = 2_500_000_000\n...\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Delegation fees may change over time, so it is essential to stay current. To do so, select the latest release in ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"Github"})," and navigate to the ",(0,a.jsx)(t.code,{children:"resources/production/chainspec.toml"})," file."]}),"\n",(0,a.jsxs)(t.p,{children:["For further questions, please join the ",(0,a.jsx)(t.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"delegation-limits",children:"Delegation Limits"}),"\n",(0,a.jsx)(t.p,{children:"The chainspec specifies delegation limits, such as the minimum and maximum amount allowed to be delegated. Also, each validator can have a maximum number of delegators."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"# Minimum allowed delegation amount in motes\nminimum_delegation_amount = 500_000_000_000\n# Maximum allowed delegation amount in motes\nmaximum_delegation_amount = 1_000_000_000_000_000_000\n# The maximum amount of delegators per validator.\nmax_delegators_per_validator = 1200\n"})}),"\n",(0,a.jsx)(t.h2,{id:"selecting-a-node-for-delegating",children:"Selecting a Node for Delegating"}),"\n",(0,a.jsxs)(t.p,{children:["As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," provide ",(0,a.jsx)(t.a,{href:"https://cspr.live/validators",children:"validator performance statistics"}),", including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Validators",src:n(9578).A+"",width:"2440",height:"1211"})}),"\n",(0,a.jsx)(t.h2,{id:"first-time-delegation",children:"First-time Delegation"}),"\n",(0,a.jsxs)(t.p,{children:["If you perform a delegation for the first time, the system charges some motes to create a purse to hold the delegated tokens. We recommend that you try out delegations on the ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Casper Testnet"})," before making transactions on the ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Casper Mainnet"}),". This will help you understand the costs involved in delegating tokens."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Example:"})," The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Mainnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"When you set up a delegation transaction, it is essential to have enough funds in your account's main purse. Otherwise, the transaction will fail, and you will lose the delegation cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer."}),"\n",(0,a.jsxs)(t.p,{children:["As a result, when performing a ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/delegate",children:"delegation using the command line"}),", we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.",src:n(33518).A+"",width:"1256",height:"1266"})}),"\n",(0,a.jsx)(t.p,{align:"center",children:"\n**Figure 2** : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.\n"}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Transaction costs depend on each Casper network and the cost tables defined in the chainspec. Most of these examples are from the Casper Mainnet or Testnet."})}),"\n",(0,a.jsx)(t.h2,{id:"monitoring-rewards",children:"Monitoring Rewards"}),"\n",(0,a.jsx)(t.p,{children:"It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations."}),"\n",(0,a.jsx)(t.p,{children:"Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,a.jsx)(t.p,{children:"Navigate to these pages for step-by-step tutorials on delegating and undelegating tokens."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/users/delegate-ui",children:"Delegating tokens using a block explorer"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/users/staking-ledger",children:"Delegating with Ledger devices"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/delegate",children:"Delegating with the Casper client"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/users/undelegate-ui",children:"Undelegating tokens using a block explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},9578:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/1.validators-e03196f06d8422ff744f2796db8db22f.png"},33518:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/economic-delegationDetails-39ff9fadcf1ff742716046d64ef6789e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(96540);const i={},o=a.createContext(i);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46c04ff3.0ad52045.js b/assets/js/46c04ff3.0ad52045.js deleted file mode 100644 index 256ff8383..000000000 --- a/assets/js/46c04ff3.0ad52045.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3919],{55737:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var a=t(74848),c=t(28453);const s={title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},r="Cross-Contract Communication",o={id:"resources/advanced/cross-contract",title:"Cross-Contract Communication",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/docs/resources/advanced/cross-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/cross-contract",permalink:"/next/resources/tutorials/advanced/cross-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},sidebar:"tutorials",previous:{title:"Storage Workflow",permalink:"/next/resources/tutorials/advanced/storage-workflow"}},d={},i=[{value:"Tutorial Outline",id:"outline",level:2},{value:"Creating the Project",id:"create-project",level:2},{value:"Changing the Standard Contract",id:"changing-contract",level:2},{value:"Deploying the Contract",id:"deploying-contract",level:2},{value:"Create Another Contract for the Cross-Contract Call",id:"cross-contract",level:2},{value:"Summary",id:"summary",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cross-contract-communication",children:"Cross-Contract Communication"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"outline",children:"Tutorial Outline"}),"\n",(0,a.jsx)(n.p,{children:"This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol."}),"\n",(0,a.jsx)(n.p,{children:"Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose.\nThe contracts are as follows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Factory"}),"\n",(0,a.jsx)(n.li,{children:"Pair"}),"\n",(0,a.jsx)(n.li,{children:"Pair (ERC20)"}),"\n",(0,a.jsx)(n.li,{children:"Library"}),"\n",(0,a.jsx)(n.li,{children:"Router01"}),"\n",(0,a.jsx)(n.li,{children:"Router02"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash.\nThe Pair smart contract is used to perform operations like mint or burn on a created pair of tokens."}),"\n",(0,a.jsx)(n.p,{children:"Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called."}),"\n",(0,a.jsx)(n.h2,{id:"create-project",children:"Creating the Project"}),"\n",(0,a.jsx)(n.p,{children:"In the appropriate folder, create the project for the contract using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cargo casper cross-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will create the following structure under your desired smart contract folder:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cross-contract/\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 .cargo/\n \u2514\u2500\u2500 config.toml\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 .travis.yml\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n"})}),"\n",(0,a.jsx)(n.p,{children:"After creating the project directory structure, use the following commands to go into the project folder and compile the files:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will also create a target folder under the contract folder where the .wasm of the contract can be found.\nAdditionally you can check if the tests can be performed using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"If this is not the case and you see the following error:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'warning: `tests` (bin "integration-tests" test) generated 2 warnings\nerror: could not compile `tests` due to 3 previous errors; 2 warnings emitted\nmake: *** [test] Error 101\n'})}),(0,a.jsxs)(n.p,{children:["Then it is useful to check if the dependencies in ",(0,a.jsx)(n.code,{children:"Cargo.toml"})," are still up to date."]}),(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"CargoToml",src:t(62503).A+"",width:"1570",height:"614"})}),(0,a.jsx)(n.p,{children:"If you see the red cross, it means the version is not up to date and has to be updated."})]}),"\n",(0,a.jsx)(n.h2,{id:"changing-contract",children:"Changing the Standard Contract"}),"\n",(0,a.jsxs)(n.p,{children:["The standard Casper contract from ",(0,a.jsx)(n.code,{children:"cargo-casper"})," contains some methods that we will reuse. However, we will be getting rid of most auto-generated code."]}),"\n",(0,a.jsxs)(n.p,{children:["We will be changing the ",(0,a.jsx)(n.code,{children:"main.rs"})," file. Your code should look exactly as below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"This will serve as a base for introducing the elements needed for cross-contract communication."}),"\n",(0,a.jsxs)(n.p,{children:["In a contract, you should first define the ",(0,a.jsx)(n.code,{children:"call"})," entry point. It should be understood as a ",(0,a.jsx)(n.code,{children:"constructor"})," for the contract. Everything included in the ",(0,a.jsx)(n.code,{children:"call"})," entry point will be visible as metadata on a Casper network, in the contract's context.\nYou should already be familiar with the ",(0,a.jsx)(n.code,{children:"call"})," entry point from the ",(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})," document. If this is not the case, be sure to familiarize yourself with it now."]}),"\n",(0,a.jsxs)(n.p,{children:["The contract code, with changes to the ",(0,a.jsx)(n.code,{children:"call"})," entry point, should look as shown below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Get the value of the runtime argument named "message"\n let value: String = runtime::get_named_arg("message");\n\n // The value will be written under a URef\n let value_ref = storage::new_uref(value);\n\n // Creating the new set of named keys\n // The keys are a Map of String/casper_types::Key\n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector \n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"runtime"})," and ",(0,a.jsx)(n.code,{children:"storage"})," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"Contract API Modules"}),"."]})}),"\n",(0,a.jsxs)(n.p,{children:["The metadata for each of the contract's entry points is defined in the ",(0,a.jsx)(n.code,{children:"call"})," entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the ",(0,a.jsx)(n.code,{children:"String"})," value passed when defining the metadata for the entry point."]}),"\n",(0,a.jsx)(n.p,{children:"The #[no_mangle] flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points."}),"\n",(0,a.jsxs)(n.p,{children:["In our case, we will define the entry point ",(0,a.jsx)(n.code,{children:"update_msg"})," in the contract code just before ",(0,a.jsx)(n.code,{children:"call"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract should match the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value \n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector \n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["There is a distinction between storing data in a contract\u2019s ",(0,a.jsx)(n.code,{children:"NamedKeys"})," and using a dictionary. ",(0,a.jsx)(n.a,{href:"/next/concepts/dictionaries",children:"Dictionaries"})," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application."]})}),"\n",(0,a.jsx)(n.h2,{id:"deploying-contract",children:"Deploying the Contract"}),"\n",(0,a.jsxs)(n.p,{children:["There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,a.jsx)(n.a,{href:"/next/developers/cli/installing-contracts#installing-contract-code",children:"put_deploy"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Be sure to go through the prerequisites from the ",(0,a.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})," documentation."]}),"\n",(0,a.jsx)(n.p,{children:"Make sure that after doing this you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"A valid private key for your account."}),"\n",(0,a.jsx)(n.li,{children:"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,a.jsx)(n.code,{children:"secret_key.pem"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Compile the contract in the contract directory so you obtain the contracts ",(0,a.jsx)(n.code,{children:".wasm"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this step everything is in place to deploy the contract."}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands."})}),"\n",(0,a.jsxs)(n.p,{children:["Since we are using a default contract structure, the command called from the ",(0,a.jsx)(n.code,{children:"cross-contract"})," folder should be the following:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,a.jsx)(n.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," and ",(0,a.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"installing contracts"}),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of this command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["To verify that the contract was successfully deployed, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," subcommand, providing as a parameter the ",(0,a.jsx)(n.code,{children:"deploy_hash"})," received from the ",(0,a.jsx)(n.code,{children:"put-deploy"})," above."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,a.jsx)(n.code,{children:"verbose"})," flag with the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand. Take time to familiarize yourself with the structure of the output."]}),"\n",(0,a.jsxs)(n.p,{children:["We can use the supplied deploy hash, ",(0,a.jsx)(n.code,{children:"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"})," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,a.jsx)(n.code,{children:"Success"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["From your ",(0,a.jsx)(n.code,{children:"cspr.live"})," account, you will find a tab called ",(0,a.jsx)(n.code,{children:"NamedKeys"}),". This tab includes a list of all contracts deployed using the private key connected to your account."]}),"\n",(0,a.jsxs)(n.p,{children:["By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."]}),"\n",(0,a.jsxs)(n.p,{children:["An additional tab, ",(0,a.jsx)(n.code,{children:"Deploys"}),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,a.jsx)(n.code,{children:"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"cross-contract",children:"Create Another Contract for the Cross-Contract Call"}),"\n",(0,a.jsxs)(n.p,{children:["This section describes the process of writing an additional contract, which will use an entry point titled ",(0,a.jsx)(n.code,{children:"call_contract_2"})," to invoke the ",(0,a.jsx)(n.code,{children:"update_msg"})," entry point on the previous contract."]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial we will be passing the contract hash, as an argument, into the ",(0,a.jsx)(n.code,{children:"call"})," entry point and use this to perform the calls to the destination contract."]}),"\n",(0,a.jsxs)(n.p,{children:["Prepare the ",(0,a.jsx)(n.code,{children:"call"})," entry point as described below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This would be the easiest implementation of the ",(0,a.jsx)(n.code,{children:"call"})," entry point. There is only one entry point which accepts the key ",(0,a.jsx)(n.code,{children:"contract2"})," of type ",(0,a.jsx)(n.code,{children:"String"})," and the key ",(0,a.jsx)(n.code,{children:"hello_world_contract"})," of the type ",(0,a.jsx)(n.code,{children:"Key"}),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."]}),"\n",(0,a.jsxs)(n.p,{children:["Now that we have defined the metadata for the ",(0,a.jsx)(n.code,{children:"call_contract_2"})," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,a.jsx)(n.code,{children:"update_msg"}),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter \n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract implementation should look as follows:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After you run ",(0,a.jsx)(n.code,{children:"make build-contract"})," in your second contract's directory, you should obtain the outcome:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder and copy the keys from the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder in the first contract into this subfolder.\nThe call from the terminal will look as follows:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,a.jsx)(n.code,{children:"cargo casper"})," project. You can change this by editing the ",(0,a.jsx)(n.code,{children:"Makefile"})," in the main directory. You can then observe the result by recompiling your contract with these commands;"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})})]}),"\n",(0,a.jsx)(n.p,{children:"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys."})}),"\n",(0,a.jsx)(n.p,{children:"Observing the deploy, we can see that it succeeded:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"execution_results"}),' JSON element we should see "Success".']}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n \n }\n }\n }\n }\n ]\n\n'})}),"\n",(0,a.jsx)(n.p,{children:"Get the state root hash of the current network state:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the",(0,a.jsx)(n.code,{children:"get-state-root-hash"})," command is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Query the state of Casper network using the account hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:" casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n"})}),"\n",(0,a.jsx)(n.p,{children:"If we check the account's named keys, we can see all of the account's deployed contracts:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Account's named keys"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."}),"\n",(0,a.jsx)(n.p,{children:"The Uref of the message variable is stored under the Named Keys in the contract."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Checking the state of the message in the first contract, we observe the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This is a simple ",(0,a.jsx)(n.code,{children:"hello world"})," string. After invoking the entry point using the command below this value should change."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-hash"})," - is the contract hash, which is returned from the put-deploy."]}),(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-arg"}),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.']})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The contract hash has to be of type ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the contract itself. We can pass the hash as a ",(0,a.jsx)(n.code,{children:"Key"})," argument and change it to ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the smart contract."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Check the deploy with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n"})}),"\n",(0,a.jsx)(n.p,{children:"After the deploy finishes successfully, you should see a similar outcome to the following:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Deploy details"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"We would expect that the value of the message reference in the other contract would have changed, which we can check:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"With this we have succeeded in cross-contract communication between two contracts."}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"}),"\n",(0,a.jsx)(n.li,{children:"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},62503:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/CargoToml-0df722b819fb823a4a14d90b45076240.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const c={},s=a.createContext(c);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46c04ff3.202aa580.js b/assets/js/46c04ff3.202aa580.js new file mode 100644 index 000000000..7e1af57ba --- /dev/null +++ b/assets/js/46c04ff3.202aa580.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[23919],{55737:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var a=t(74848),c=t(28453);const s={title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},r="Cross-Contract Communication",o={id:"resources/advanced/cross-contract",title:"Cross-Contract Communication",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/docs/resources/advanced/cross-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/cross-contract",permalink:"/resources/tutorials/advanced/cross-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},sidebar:"tutorials",previous:{title:"Storage Workflow",permalink:"/resources/tutorials/advanced/storage-workflow"}},d={},i=[{value:"Tutorial Outline",id:"outline",level:2},{value:"Creating the Project",id:"create-project",level:2},{value:"Changing the Standard Contract",id:"changing-contract",level:2},{value:"Deploying the Contract",id:"deploying-contract",level:2},{value:"Create Another Contract for the Cross-Contract Call",id:"cross-contract",level:2},{value:"Summary",id:"summary",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cross-contract-communication",children:"Cross-Contract Communication"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"outline",children:"Tutorial Outline"}),"\n",(0,a.jsx)(n.p,{children:"This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol."}),"\n",(0,a.jsx)(n.p,{children:"Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose.\nThe contracts are as follows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Factory"}),"\n",(0,a.jsx)(n.li,{children:"Pair"}),"\n",(0,a.jsx)(n.li,{children:"Pair (ERC20)"}),"\n",(0,a.jsx)(n.li,{children:"Library"}),"\n",(0,a.jsx)(n.li,{children:"Router01"}),"\n",(0,a.jsx)(n.li,{children:"Router02"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash.\nThe Pair smart contract is used to perform operations like mint or burn on a created pair of tokens."}),"\n",(0,a.jsx)(n.p,{children:"Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called."}),"\n",(0,a.jsx)(n.h2,{id:"create-project",children:"Creating the Project"}),"\n",(0,a.jsx)(n.p,{children:"In the appropriate folder, create the project for the contract using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cargo casper cross-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will create the following structure under your desired smart contract folder:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cross-contract/\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 .cargo/\n \u2514\u2500\u2500 config.toml\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 .travis.yml\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n"})}),"\n",(0,a.jsx)(n.p,{children:"After creating the project directory structure, use the following commands to go into the project folder and compile the files:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will also create a target folder under the contract folder where the .wasm of the contract can be found.\nAdditionally you can check if the tests can be performed using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"If this is not the case and you see the following error:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'warning: `tests` (bin "integration-tests" test) generated 2 warnings\nerror: could not compile `tests` due to 3 previous errors; 2 warnings emitted\nmake: *** [test] Error 101\n'})}),(0,a.jsxs)(n.p,{children:["Then it is useful to check if the dependencies in ",(0,a.jsx)(n.code,{children:"Cargo.toml"})," are still up to date."]}),(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"CargoToml",src:t(97205).A+"",width:"1570",height:"614"})}),(0,a.jsx)(n.p,{children:"If you see the red cross, it means the version is not up to date and has to be updated."})]}),"\n",(0,a.jsx)(n.h2,{id:"changing-contract",children:"Changing the Standard Contract"}),"\n",(0,a.jsxs)(n.p,{children:["The standard Casper contract from ",(0,a.jsx)(n.code,{children:"cargo-casper"})," contains some methods that we will reuse. However, we will be getting rid of most auto-generated code."]}),"\n",(0,a.jsxs)(n.p,{children:["We will be changing the ",(0,a.jsx)(n.code,{children:"main.rs"})," file. Your code should look exactly as below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"This will serve as a base for introducing the elements needed for cross-contract communication."}),"\n",(0,a.jsxs)(n.p,{children:["In a contract, you should first define the ",(0,a.jsx)(n.code,{children:"call"})," entry point. It should be understood as a ",(0,a.jsx)(n.code,{children:"constructor"})," for the contract. Everything included in the ",(0,a.jsx)(n.code,{children:"call"})," entry point will be visible as metadata on a Casper network, in the contract's context.\nYou should already be familiar with the ",(0,a.jsx)(n.code,{children:"call"})," entry point from the ",(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})," document. If this is not the case, be sure to familiarize yourself with it now."]}),"\n",(0,a.jsxs)(n.p,{children:["The contract code, with changes to the ",(0,a.jsx)(n.code,{children:"call"})," entry point, should look as shown below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Get the value of the runtime argument named "message"\n let value: String = runtime::get_named_arg("message");\n\n // The value will be written under a URef\n let value_ref = storage::new_uref(value);\n\n // Creating the new set of named keys\n // The keys are a Map of String/casper_types::Key\n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector \n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"runtime"})," and ",(0,a.jsx)(n.code,{children:"storage"})," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"Contract API Modules"}),"."]})}),"\n",(0,a.jsxs)(n.p,{children:["The metadata for each of the contract's entry points is defined in the ",(0,a.jsx)(n.code,{children:"call"})," entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the ",(0,a.jsx)(n.code,{children:"String"})," value passed when defining the metadata for the entry point."]}),"\n",(0,a.jsx)(n.p,{children:"The #[no_mangle] flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points."}),"\n",(0,a.jsxs)(n.p,{children:["In our case, we will define the entry point ",(0,a.jsx)(n.code,{children:"update_msg"})," in the contract code just before ",(0,a.jsx)(n.code,{children:"call"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract should match the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value \n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector \n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["There is a distinction between storing data in a contract\u2019s ",(0,a.jsx)(n.code,{children:"NamedKeys"})," and using a dictionary. ",(0,a.jsx)(n.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application."]})}),"\n",(0,a.jsx)(n.h2,{id:"deploying-contract",children:"Deploying the Contract"}),"\n",(0,a.jsxs)(n.p,{children:["There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts#installing-contract-code",children:"put_deploy"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Be sure to go through the prerequisites from the ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})," documentation."]}),"\n",(0,a.jsx)(n.p,{children:"Make sure that after doing this you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"A valid private key for your account."}),"\n",(0,a.jsx)(n.li,{children:"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,a.jsx)(n.code,{children:"secret_key.pem"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Compile the contract in the contract directory so you obtain the contracts ",(0,a.jsx)(n.code,{children:".wasm"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this step everything is in place to deploy the contract."}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands."})}),"\n",(0,a.jsxs)(n.p,{children:["Since we are using a default contract structure, the command called from the ",(0,a.jsx)(n.code,{children:"cross-contract"})," folder should be the following:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,a.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," and ",(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installing contracts"}),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of this command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["To verify that the contract was successfully deployed, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," subcommand, providing as a parameter the ",(0,a.jsx)(n.code,{children:"deploy_hash"})," received from the ",(0,a.jsx)(n.code,{children:"put-deploy"})," above."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,a.jsx)(n.code,{children:"verbose"})," flag with the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand. Take time to familiarize yourself with the structure of the output."]}),"\n",(0,a.jsxs)(n.p,{children:["We can use the supplied deploy hash, ",(0,a.jsx)(n.code,{children:"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"})," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,a.jsx)(n.code,{children:"Success"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["From your ",(0,a.jsx)(n.code,{children:"cspr.live"})," account, you will find a tab called ",(0,a.jsx)(n.code,{children:"NamedKeys"}),". This tab includes a list of all contracts deployed using the private key connected to your account."]}),"\n",(0,a.jsxs)(n.p,{children:["By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."]}),"\n",(0,a.jsxs)(n.p,{children:["An additional tab, ",(0,a.jsx)(n.code,{children:"Deploys"}),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,a.jsx)(n.code,{children:"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"cross-contract",children:"Create Another Contract for the Cross-Contract Call"}),"\n",(0,a.jsxs)(n.p,{children:["This section describes the process of writing an additional contract, which will use an entry point titled ",(0,a.jsx)(n.code,{children:"call_contract_2"})," to invoke the ",(0,a.jsx)(n.code,{children:"update_msg"})," entry point on the previous contract."]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial we will be passing the contract hash, as an argument, into the ",(0,a.jsx)(n.code,{children:"call"})," entry point and use this to perform the calls to the destination contract."]}),"\n",(0,a.jsxs)(n.p,{children:["Prepare the ",(0,a.jsx)(n.code,{children:"call"})," entry point as described below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This would be the easiest implementation of the ",(0,a.jsx)(n.code,{children:"call"})," entry point. There is only one entry point which accepts the key ",(0,a.jsx)(n.code,{children:"contract2"})," of type ",(0,a.jsx)(n.code,{children:"String"})," and the key ",(0,a.jsx)(n.code,{children:"hello_world_contract"})," of the type ",(0,a.jsx)(n.code,{children:"Key"}),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."]}),"\n",(0,a.jsxs)(n.p,{children:["Now that we have defined the metadata for the ",(0,a.jsx)(n.code,{children:"call_contract_2"})," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,a.jsx)(n.code,{children:"update_msg"}),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter \n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract implementation should look as follows:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After you run ",(0,a.jsx)(n.code,{children:"make build-contract"})," in your second contract's directory, you should obtain the outcome:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder and copy the keys from the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder in the first contract into this subfolder.\nThe call from the terminal will look as follows:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,a.jsx)(n.code,{children:"cargo casper"})," project. You can change this by editing the ",(0,a.jsx)(n.code,{children:"Makefile"})," in the main directory. You can then observe the result by recompiling your contract with these commands;"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})})]}),"\n",(0,a.jsx)(n.p,{children:"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys."})}),"\n",(0,a.jsx)(n.p,{children:"Observing the deploy, we can see that it succeeded:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"execution_results"}),' JSON element we should see "Success".']}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n \n }\n }\n }\n }\n ]\n\n'})}),"\n",(0,a.jsx)(n.p,{children:"Get the state root hash of the current network state:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the",(0,a.jsx)(n.code,{children:"get-state-root-hash"})," command is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Query the state of Casper network using the account hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:" casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n"})}),"\n",(0,a.jsx)(n.p,{children:"If we check the account's named keys, we can see all of the account's deployed contracts:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Account's named keys"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."}),"\n",(0,a.jsx)(n.p,{children:"The Uref of the message variable is stored under the Named Keys in the contract."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Checking the state of the message in the first contract, we observe the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This is a simple ",(0,a.jsx)(n.code,{children:"hello world"})," string. After invoking the entry point using the command below this value should change."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-hash"})," - is the contract hash, which is returned from the put-deploy."]}),(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-arg"}),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.']})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The contract hash has to be of type ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the contract itself. We can pass the hash as a ",(0,a.jsx)(n.code,{children:"Key"})," argument and change it to ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the smart contract."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Check the deploy with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n"})}),"\n",(0,a.jsx)(n.p,{children:"After the deploy finishes successfully, you should see a similar outcome to the following:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Deploy details"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"We would expect that the value of the message reference in the other contract would have changed, which we can check:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"With this we have succeeded in cross-contract communication between two contracts."}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"}),"\n",(0,a.jsx)(n.li,{children:"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},97205:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/CargoToml-0df722b819fb823a4a14d90b45076240.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const c={},s=a.createContext(c);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46e94768.dab245b0.js b/assets/js/46e94768.dab245b0.js new file mode 100644 index 000000000..b83b79b71 --- /dev/null +++ b/assets/js/46e94768.dab245b0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72646],{25120:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var r=t(74848),s=t(28453);const i={title:"Interacting with the Blockchain"},c="Using the Casper CLI Client",l={id:"developers/cli/index",title:"Interacting with the Blockchain",description:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.",source:"@site/docs/developers/cli/index.md",sourceDirName:"developers/cli",slug:"/developers/cli/",permalink:"/developers/cli/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724192882e3,frontMatter:{title:"Interacting with the Blockchain"},sidebar:"developers",previous:{title:"Monitoring Events with the Casper Sidecar",permalink:"/developers/dapps/monitor-and-consume-events"},next:{title:"Transferring Tokens",permalink:"/developers/cli/transfers/"}},o={},a=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-the-casper-cli-client",children:"Using the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/transfers/",children:"Transferring Tokens"})}),(0,r.jsx)(n.td,{children:"Transferring tokens from one account to another using the Casper command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/delegate",children:"Delegating tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/undelegate",children:"Undelegating Tokens with the Casper Client"})}),(0,r.jsx)(n.td,{children:"Undelegating tokens from a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Sending Deploys to a Network"})}),(0,r.jsx)(n.td,{children:"Sending Deploys to a Casper network using the Rust CLI Client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to install a contract on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/verifying-contracts",children:"Verifying contracts using the Casper Client"})}),(0,r.jsx)(n.td,{children:"How to use Smart Contract Verification Service"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/querying-global-state",children:"Querying Global State"})}),(0,r.jsx)(n.td,{children:"How to query global state after contract installation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Various ways to call a contract's entry-points"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Error codes for smart contract execution"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>l});var r=t(96540);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46e94768.e7996bf8.js b/assets/js/46e94768.e7996bf8.js deleted file mode 100644 index a9d3f1088..000000000 --- a/assets/js/46e94768.e7996bf8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2646],{25120:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>a});var r=t(74848),s=t(28453);const i={title:"Interacting with the Blockchain"},c="Using the Casper CLI Client",l={id:"developers/cli/index",title:"Interacting with the Blockchain",description:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.",source:"@site/docs/developers/cli/index.md",sourceDirName:"developers/cli",slug:"/developers/cli/",permalink:"/next/developers/cli/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724192882e3,frontMatter:{title:"Interacting with the Blockchain"},sidebar:"developers",previous:{title:"Monitoring Events with the Casper Sidecar",permalink:"/next/developers/dapps/monitor-and-consume-events"},next:{title:"Transferring Tokens",permalink:"/next/developers/cli/transfers/"}},o={},a=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-the-casper-cli-client",children:"Using the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/transfers/",children:"Transferring Tokens"})}),(0,r.jsx)(n.td,{children:"Transferring tokens from one account to another using the Casper command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/delegate",children:"Delegating tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/undelegate",children:"Undelegating Tokens with the Casper Client"})}),(0,r.jsx)(n.td,{children:"Undelegating tokens from a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Sending Deploys to a Network"})}),(0,r.jsx)(n.td,{children:"Sending Deploys to a Casper network using the Rust CLI Client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to install a contract on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/verifying-contracts",children:"Verifying contracts using the Casper Client"})}),(0,r.jsx)(n.td,{children:"How to use Smart Contract Verification Service"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/querying-global-state",children:"Querying Global State"})}),(0,r.jsx)(n.td,{children:"How to query global state after contract installation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Various ways to call a contract's entry-points"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Error codes for smart contract execution"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>l});var r=t(96540);const s={},i=r.createContext(s);function c(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/471ca6e4.a462efc0.js b/assets/js/471ca6e4.a462efc0.js deleted file mode 100644 index 902f279a4..000000000 --- a/assets/js/471ca6e4.a462efc0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7174],{78139:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={},r="Staking",o={id:"concepts/economics/staking",title:"Staking",description:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.",source:"@site/docs/concepts/economics/staking.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/staking",permalink:"/next/concepts/economics/staking",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Fee Elimination",permalink:"/next/concepts/economics/fee-elimination"},next:{title:"Glossary",permalink:"/next/glossary"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"staking",children:"Staking"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Consensus mechanism:"})," The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called ",(0,a.jsx)(n.a,{href:"/next/concepts/design/zug",children:"Zug"}),". Another Casper network can choose between Zug and ",(0,a.jsx)(n.a,{href:"/next/concepts/design/highway",children:"Highway"})," using the network's chainspec."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Number of validators:"})," The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Permission-less bonding:"})," For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Unbonding:"})," To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution ",(0,a.jsx)(n.a,{href:"/next/concepts/economics/consensus#distribution",children:"here"}),". The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Eras and block times:"})," An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Block rewards:"})," Validators receive ",(0,a.jsx)(n.a,{href:"/next/concepts/design/rewards",children:"rewards"})," proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward calculations:"})," Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward cycle:"})," Rewards are ",(0,a.jsx)(n.a,{href:"/next/concepts/economics/consensus#distribution",children:"calculated and distributed"})," to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Token supply and inflation:"})," Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Annual reward percentage:"})," Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Slashing:"})," Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Delegation rate:"})," Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/471ca6e4.fc8efafc.js b/assets/js/471ca6e4.fc8efafc.js new file mode 100644 index 000000000..5d9e3762d --- /dev/null +++ b/assets/js/471ca6e4.fc8efafc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87174],{78139:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={},r="Staking",o={id:"concepts/economics/staking",title:"Staking",description:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.",source:"@site/docs/concepts/economics/staking.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/staking",permalink:"/concepts/economics/staking",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Fee Elimination",permalink:"/concepts/economics/fee-elimination"},next:{title:"Glossary",permalink:"/glossary"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"staking",children:"Staking"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Consensus mechanism:"})," The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called ",(0,a.jsx)(n.a,{href:"/concepts/design/zug",children:"Zug"}),". Another Casper network can choose between Zug and ",(0,a.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway"})," using the network's chainspec."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Number of validators:"})," The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Permission-less bonding:"})," For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Unbonding:"})," To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution ",(0,a.jsx)(n.a,{href:"/concepts/economics/consensus#distribution",children:"here"}),". The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Eras and block times:"})," An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Block rewards:"})," Validators receive ",(0,a.jsx)(n.a,{href:"/concepts/design/rewards",children:"rewards"})," proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward calculations:"})," Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward cycle:"})," Rewards are ",(0,a.jsx)(n.a,{href:"/concepts/economics/consensus#distribution",children:"calculated and distributed"})," to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Token supply and inflation:"})," Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Annual reward percentage:"})," Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Slashing:"})," Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Delegation rate:"})," Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4732c0e2.3853b69c.js b/assets/js/4732c0e2.3853b69c.js new file mode 100644 index 000000000..d72414781 --- /dev/null +++ b/assets/js/4732c0e2.3853b69c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[23963],{59073:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter-testnet"},i="A Counter on the Testnet",a={id:"resources/beginner/counter-testnet/index",title:"Introduction",description:"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/index.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/counter-testnet",permalink:"/2.0.0/counter-testnet",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Introduction",slug:"/counter-testnet"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/2.0.0/resources/beginner/counter/walkthrough"},next:{title:"Overview",permalink:"/2.0.0/resources/beginner/counter-testnet/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-the-testnet",children:"A Counter on the Testnet"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a ",(0,n.jsx)(t.a,{href:"/2.0.0/counter",children:"similar tutorial"})," and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n",(0,n.jsxs)(t.li,{children:["You were able to ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"set up and fund an account"})," on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The location of your account\u2019s ",(0,n.jsx)(t.strong,{children:"secret_key.pem"})," file"]}),"\n",(0,n.jsxs)(t.li,{children:["Your ",(0,n.jsx)(t.strong,{children:"account hash"})," identifier"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["You ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"selected a node"})," whose RPC port will be receiving the transactions coming from your account."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,n.jsx)(t.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rWaUiFFEyaY&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=3",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/473a077c.eb7aa5a0.js b/assets/js/473a077c.eb7aa5a0.js new file mode 100644 index 000000000..dd73278fd --- /dev/null +++ b/assets/js/473a077c.eb7aa5a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24281],{58376:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),o=s(28453);const i={},c="Contracts and Session Code",r={id:"developers/writing-onchain-code/contract-vs-session",title:"Contracts and Session Code",description:"What is Session Code?",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/contract-vs-session.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-vs-session",permalink:"/2.0.0/developers/writing-onchain-code/contract-vs-session",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/2.0.0/developers/writing-onchain-code/calling-contracts"},next:{title:"Writing Session Code",permalink:"/2.0.0/developers/writing-onchain-code/writing-session-code"}},a={},d=[{value:"What is Session Code?",id:"what-is-session-code",level:2},{value:"Comparing Session and Contract Code",id:"comparing-session-and-contract",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"contracts-and-session-code",children:"Contracts and Session Code"})}),"\n",(0,t.jsx)(n.h2,{id:"what-is-session-code",children:"What is Session Code?"}),"\n",(0,t.jsxs)(n.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the ",(0,t.jsx)(n.code,{children:"call"})," function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse."]}),"\n",(0,t.jsxs)(n.p,{children:["The best use of session code is when the situation calls for ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/S#stateless",children:"stateless"})," execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary."]}),"\n",(0,t.jsx)(n.h2,{id:"comparing-session-and-contract",children:"Comparing Session and Contract Code"}),"\n",(0,t.jsx)(n.p,{children:"The following table summarizes the key differences between session code and contract code on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Session Code"}),(0,t.jsx)(n.th,{children:"Contract Code"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Session code always executes in the context of the account that signed the transaction containing the session code."}),(0,t.jsx)(n.td,{children:"A smart contract, which is stored on-chain logic, executes within its own context."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Session code has only one entry point, ",(0,t.jsx)(n.code,{children:"call"}),", which can be used to interact with the session code."]}),(0,t.jsx)(n.td,{children:"A smart contract can have multiple entry points that can be invoked."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," entry point initiates any action the session code takes."]}),(0,t.jsx)(n.td,{children:"Any action undertaken by a contract must initiate through an outside call, usually via session code."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the body of the session code, the key is added to the account's named keys."]}),(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the smart contract's context, the contract's record is modified to have a new named_key entry."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["For more information on how to write session code, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),"."]}),(0,t.jsxs)(n.td,{children:["For more information on writing contracts, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"The following image depicts the comparison presented in the table."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Comparing Session and Contract Code",src:s(35598).A+"",width:"3716",height:"2652"})}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"write session code"})]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-session-code",children:"test session code"})]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},35598:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/session-contract-context-eeb5191bad40f018d30b138e5fb2f964.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4804492c.1872c747.js b/assets/js/4804492c.1872c747.js deleted file mode 100644 index 0a6d4ea3e..000000000 --- a/assets/js/4804492c.1872c747.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7375],{43894:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="J",a={id:"concepts/glossary/J",title:"J",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/J.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/J",permalink:"/concepts/glossary/J",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"I",permalink:"/concepts/glossary/I"},next:{title:"K",permalink:"/concepts/glossary/K"}},l={},h=[{value:"JSON",id:"json",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"j",children:"J"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"json",children:"JSON"}),"\n",(0,n.jsxs)(e.p,{children:["JSON (",(0,n.jsx)(e.strong,{children:"J"}),"ava",(0,n.jsx)(e.strong,{children:"S"}),"cript ",(0,n.jsx)(e.strong,{children:"O"}),"bject ",(0,n.jsx)(e.strong,{children:"N"}),"otation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found ",(0,n.jsx)(e.a,{href:"https://www.json.org/json-en.html",children:"here"}),"."]})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/4804492c.9bff2638.js b/assets/js/4804492c.9bff2638.js new file mode 100644 index 000000000..4bf514343 --- /dev/null +++ b/assets/js/4804492c.9bff2638.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87375],{43894:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="J",a={id:"concepts/glossary/J",title:"J",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/J.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/J",permalink:"/1.5.X/concepts/glossary/J",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"I",permalink:"/1.5.X/concepts/glossary/I"},next:{title:"K",permalink:"/1.5.X/concepts/glossary/K"}},l={},h=[{value:"JSON",id:"json",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"j",children:"J"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"json",children:"JSON"}),"\n",(0,n.jsxs)(e.p,{children:["JSON (",(0,n.jsx)(e.strong,{children:"J"}),"ava",(0,n.jsx)(e.strong,{children:"S"}),"cript ",(0,n.jsx)(e.strong,{children:"O"}),"bject ",(0,n.jsx)(e.strong,{children:"N"}),"otation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found ",(0,n.jsx)(e.a,{href:"https://www.json.org/json-en.html",children:"here"}),"."]})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/480fa8f7.75e26ad2.js b/assets/js/480fa8f7.75e26ad2.js new file mode 100644 index 000000000..97039c99a --- /dev/null +++ b/assets/js/480fa8f7.75e26ad2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87903],{69029:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=t(74848),s=t(28453);const r={},i="Required Methods for Minimal Compliance",a={id:"developers/json-rpc/minimal-compliance",title:"Required Methods for Minimal Compliance",description:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/minimal-compliance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/minimal-compliance",permalink:"/1.5.X/developers/json-rpc/minimal-compliance",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/1.5.X/developers/json-rpc/guidance"},next:{title:"Transactional JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-transactional"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"required-methods-for-minimal-compliance",children:"Required Methods for Minimal Compliance"})}),"\n",(0,o.jsx)(n.p,{children:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#chain-get-block",children:(0,o.jsx)(n.code,{children:"chain_get_block"})})," - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#info-get-deploy",children:(0,o.jsx)(n.code,{children:"info_get_deploy"})})," - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-transactional#account-put-deploy",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#chain-get-state-root-hash",children:(0,o.jsx)(n.code,{children:"chain_get_state_root_hash"})})," - The state root hash is one of the several ",(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#globalstateidentifier",children:"global state identifiers"})," used to query the network state after sending deploys."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#state-get-account-info",children:(0,o.jsx)(n.code,{children:"state_get_account_info"})})," - This method returns a JSON representation of an Account from the network. ",(0,o.jsx)(n.code,{children:"state_get_account_info"})," is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#query-balance",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#state-get-dictionary-item",children:(0,o.jsx)(n.code,{children:"state_get_dictionary_item"})})," - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#query-global-state",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["The deprecated method ",(0,o.jsx)(n.code,{children:"state_get_balance"})," should not be used."]})}),"\n",(0,o.jsxs)(n.p,{children:["In addition to these methods, a minimally compliant Casper SDK must account for the ",(0,o.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain",children:"types"})," 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."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/480fa8f7.d7f8bb82.js b/assets/js/480fa8f7.d7f8bb82.js deleted file mode 100644 index 36623926d..000000000 --- a/assets/js/480fa8f7.d7f8bb82.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7903],{69029:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=t(74848),s=t(28453);const r={},i="Required Methods for Minimal Compliance",a={id:"developers/json-rpc/minimal-compliance",title:"Required Methods for Minimal Compliance",description:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/minimal-compliance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/minimal-compliance",permalink:"/developers/json-rpc/minimal-compliance",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/developers/json-rpc/guidance"},next:{title:"Transactional JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-transactional"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"required-methods-for-minimal-compliance",children:"Required Methods for Minimal Compliance"})}),"\n",(0,o.jsx)(n.p,{children:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#chain-get-block",children:(0,o.jsx)(n.code,{children:"chain_get_block"})})," - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#info-get-deploy",children:(0,o.jsx)(n.code,{children:"info_get_deploy"})})," - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-transactional#account-put-deploy",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#chain-get-state-root-hash",children:(0,o.jsx)(n.code,{children:"chain_get_state_root_hash"})})," - The state root hash is one of the several ",(0,o.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"global state identifiers"})," used to query the network state after sending deploys."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#state-get-account-info",children:(0,o.jsx)(n.code,{children:"state_get_account_info"})})," - This method returns a JSON representation of an Account from the network. ",(0,o.jsx)(n.code,{children:"state_get_account_info"})," is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#query-balance",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#state-get-dictionary-item",children:(0,o.jsx)(n.code,{children:"state_get_dictionary_item"})})," - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#query-global-state",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["The deprecated method ",(0,o.jsx)(n.code,{children:"state_get_balance"})," should not be used."]})}),"\n",(0,o.jsxs)(n.p,{children:["In addition to these methods, a minimally compliant Casper SDK must account for the ",(0,o.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"types"})," 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."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/481163ce.aa41f256.js b/assets/js/481163ce.aa41f256.js deleted file mode 100644 index e7a3bb8d9..000000000 --- a/assets/js/481163ce.aa41f256.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3552],{22999:e=>{e.exports=JSON.parse('{"tag":{"label":"new docs","permalink":"/blog/tags/new-docs","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/new-docs","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/481163ce.cef26660.js b/assets/js/481163ce.cef26660.js new file mode 100644 index 000000000..dc755ce4b --- /dev/null +++ b/assets/js/481163ce.cef26660.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93552],{22999:e=>{e.exports=JSON.parse('{"tag":{"label":"new docs","permalink":"/blog/tags/new-docs","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/new-docs","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/4832c6fe.1c554d77.js b/assets/js/4832c6fe.1c554d77.js deleted file mode 100644 index 88935bffa..000000000 --- a/assets/js/4832c6fe.1c554d77.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9408],{50929:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=t(74848),s=t(28453);const o={title:"Delegate with Ledger",slug:"/users/staking-ledger"},r="Delegating with Ledger Devices",a={id:"users/ledger/staking-ledger",title:"Delegate with Ledger",description:"Ledger Initialization",source:"@site/versioned_docs/version-1.5.X/users/ledger/staking-ledger.md",sourceDirName:"users/ledger",slug:"/users/staking-ledger",permalink:"/users/staking-ledger",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Delegate with Ledger",slug:"/users/staking-ledger"},sidebar:"users",previous:{title:"Ledger and CSPR.live",permalink:"/users/ledger/ledger-cspr-live"}},l={},d=[{value:"Ledger Initialization",id:"1-initialization",level:2},{value:"<strong>Important Notes</strong>",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"delegating-with-ledger-devices",children:"Delegating with Ledger Devices"})}),"\n",(0,i.jsx)(n.h2,{id:"1-initialization",children:"Ledger Initialization"}),"\n",(0,i.jsx)(n.p,{children:"Before getting started, you need to complete two prerequisite steps:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Set up your Ledger device using the ",(0,i.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"official documentation"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Connect the Ledger to your ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," account by following the ",(0,i.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup"})," guide."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"important-notes",children:(0,i.jsx)(n.strong,{children:"Important Notes"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,i.jsxs)(n.li,{children:["When logging in to ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.jsx)(n.a,{href:"https://www.ledger.com/academy/crypto/where-are-my-coins",children:"more info here"}),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"2-staking",children:"Staking with a Validator"}),"\n",(0,i.jsx)(n.h3,{id:"connect-and-login-with-ledger",children:"Connect and Login with Ledger"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect your Ledger to your computer via USB and enter your PIN to unlock it."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Open the Casper app on the Ledger (you will see the message "Casper Ready").'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(7808).A+"",width:"1849",height:"1479"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Sign in to ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(86139).A+"",width:"1850",height:"726"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Select the public key connected to your Ledger account."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(71314).A+"",width:"1999",height:"1295"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"View your account by clicking on your public key at the top right corner."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(76173).A+"",width:"1982",height:"1384"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"receive-tokens-from-an-external-source",children:"Receive Tokens from an External Source"}),"\n",(0,i.jsxs)(n.p,{children:["This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.jsx)(n.a,{href:"/workflow/ledger-setup/#sending-and-receiving-tokens",children:"documentation"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"staking-tokens",children:"Staking Tokens"}),"\n",(0,i.jsx)(n.p,{children:"Once you have tokens in your account, staking (delegating) with a validator is easy."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['Go back to your account, but this time open the "delegate" tab located at: ',(0,i.jsx)(n.a,{href:"https://cspr.live/delegate-stake",children:"https://cspr.live/delegate-stake"})," (alternatively, click on ",(0,i.jsx)(n.code,{children:"Wallet \u21d2 Delegate Stake"})," to go there)."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:'}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."}),"\n",(0,i.jsx)(n.li,{children:"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Click "Next" to continue, as shown below.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(22276).A+"",width:"1255",height:"995"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(59135).A+"",width:"1190",height:"1778"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(45846).A+"",width:"1999",height:"791"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.img,{src:t(23153).A+"",width:"1230",height:"370"}),"\n",(0,i.jsx)(n.img,{src:t(29288).A+"",width:"1324",height:"427"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(2370).A+"",width:"1999",height:"1203"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"3-unstaking",children:"Unstaking with a Validator"}),"\n",(0,i.jsx)(n.h3,{id:"initiate-the-undelegation",children:"Initiate the Undelegation"}),"\n",(0,i.jsx)(n.p,{children:'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(92875).A+"",width:"1211",height:"861"})}),"\n",(0,i.jsx)(n.p,{children:'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(79056).A+"",width:"1212",height:"958"})}),"\n",(0,i.jsx)(n.p,{children:'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'}),"\n",(0,i.jsx)(n.h3,{id:"sign-the-undelegation",children:"Sign the Undelegation"}),"\n",(0,i.jsx)(n.p,{children:"You will have to sign the transaction to verify your account is initiating this action."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect your Ledger device to your computer."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unlock your Ledger by entering your PIN."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Open the "Casper" app and ensure you see "Casper Ready".'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Then back on ",(0,i.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),' click the "Sign with Ledger" button shown below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(85305).A+"",width:"1202",height:"1318"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(82886).A+"",width:"1208",height:"921"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(64431).A+"",width:"1205",height:"736"})}),"\n",(0,i.jsx)(n.p,{children:"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},7808:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger1-39686f6ffc5ad108d8e08973a40103f5.png"},2370:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger10-ee4f4fd9d8bf12ad0f33c5e3b4ada52c.png"},92875:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger11-475f40691a8f46d17fdeb029786ac923.png"},79056:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger12-7fe9fa74a7040dcf0fdb703c2ad1464f.png"},85305:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger13-4e3e030cf508f30ff250d22230e7dec9.png"},82886:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger14-35808a8e588d4316a63c8c7c1b050dd2.png"},64431:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger15-5d758ba4698580290a72e3d4d564c9b1.png"},86139:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger2-f1e2691594ec0cdcc0bec706cd2aade5.png"},71314:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger3-9b464ab0befd3928a5c659c77cf9555c.png"},76173:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger4-9a921643c0431d1eac3009da497cb280.png"},22276:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger5-9853a9b9bebe07a3a24f1febfac4ca03.png"},59135:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger6-b50bdcc2ba945ebf349fc3396785adc0.png"},45846:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger7-2d020b9e8d2b40169e089bda6ff77dda.png"},23153:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger8-c3399bf73ccd1e844f6f5790c7ad1796.png"},29288:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger9-97001e377d0f7629626696f888dde09a.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4832c6fe.829d1c30.js b/assets/js/4832c6fe.829d1c30.js new file mode 100644 index 000000000..42c14ffe0 --- /dev/null +++ b/assets/js/4832c6fe.829d1c30.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29408],{50929:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var i=t(74848),s=t(28453);const o={title:"Delegate with Ledger",slug:"/users/staking-ledger"},r="Delegating with Ledger Devices",a={id:"users/ledger/staking-ledger",title:"Delegate with Ledger",description:"Ledger Initialization",source:"@site/versioned_docs/version-1.5.X/users/ledger/staking-ledger.md",sourceDirName:"users/ledger",slug:"/users/staking-ledger",permalink:"/1.5.X/users/staking-ledger",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Delegate with Ledger",slug:"/users/staking-ledger"},sidebar:"users",previous:{title:"Ledger and CSPR.live",permalink:"/1.5.X/users/ledger/ledger-cspr-live"}},l={},d=[{value:"Ledger Initialization",id:"1-initialization",level:2},{value:"<strong>Important Notes</strong>",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"delegating-with-ledger-devices",children:"Delegating with Ledger Devices"})}),"\n",(0,i.jsx)(n.h2,{id:"1-initialization",children:"Ledger Initialization"}),"\n",(0,i.jsx)(n.p,{children:"Before getting started, you need to complete two prerequisite steps:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Set up your Ledger device using the ",(0,i.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"official documentation"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Connect the Ledger to your ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," account by following the ",(0,i.jsx)(n.a,{href:"/1.5.X/workflow/ledger-setup/",children:"Ledger Setup"})," guide."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"important-notes",children:(0,i.jsx)(n.strong,{children:"Important Notes"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,i.jsxs)(n.li,{children:["When logging in to ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.jsx)(n.a,{href:"https://www.ledger.com/academy/crypto/where-are-my-coins",children:"more info here"}),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"2-staking",children:"Staking with a Validator"}),"\n",(0,i.jsx)(n.h3,{id:"connect-and-login-with-ledger",children:"Connect and Login with Ledger"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect your Ledger to your computer via USB and enter your PIN to unlock it."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Open the Casper app on the Ledger (you will see the message "Casper Ready").'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(58798).A+"",width:"1849",height:"1479"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Sign in to ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(29157).A+"",width:"1850",height:"726"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Select the public key connected to your Ledger account."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(46268).A+"",width:"1999",height:"1295"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"View your account by clicking on your public key at the top right corner."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(1139).A+"",width:"1982",height:"1384"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"receive-tokens-from-an-external-source",children:"Receive Tokens from an External Source"}),"\n",(0,i.jsxs)(n.p,{children:["This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.jsx)(n.a,{href:"/1.5.X/workflow/ledger-setup/#sending-and-receiving-tokens",children:"documentation"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"staking-tokens",children:"Staking Tokens"}),"\n",(0,i.jsx)(n.p,{children:"Once you have tokens in your account, staking (delegating) with a validator is easy."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['Go back to your account, but this time open the "delegate" tab located at: ',(0,i.jsx)(n.a,{href:"https://cspr.live/delegate-stake",children:"https://cspr.live/delegate-stake"})," (alternatively, click on ",(0,i.jsx)(n.code,{children:"Wallet \u21d2 Delegate Stake"})," to go there)."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:'}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."}),"\n",(0,i.jsx)(n.li,{children:"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Click "Next" to continue, as shown below.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(62282).A+"",width:"1255",height:"995"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(76513).A+"",width:"1190",height:"1778"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:['On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(55384).A+"",width:"1999",height:"791"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.img,{src:t(80335).A+"",width:"1230",height:"370"}),"\n",(0,i.jsx)(n.img,{src:t(57670).A+"",width:"1324",height:"427"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(77964).A+"",width:"1999",height:"1203"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"3-unstaking",children:"Unstaking with a Validator"}),"\n",(0,i.jsx)(n.h3,{id:"initiate-the-undelegation",children:"Initiate the Undelegation"}),"\n",(0,i.jsx)(n.p,{children:'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(60853).A+"",width:"1211",height:"861"})}),"\n",(0,i.jsx)(n.p,{children:'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(75102).A+"",width:"1212",height:"958"})}),"\n",(0,i.jsx)(n.p,{children:'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'}),"\n",(0,i.jsx)(n.h3,{id:"sign-the-undelegation",children:"Sign the Undelegation"}),"\n",(0,i.jsx)(n.p,{children:"You will have to sign the transaction to verify your account is initiating this action."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Connect your Ledger device to your computer."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Unlock your Ledger by entering your PIN."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Open the "Casper" app and ensure you see "Casper Ready".'}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Then back on ",(0,i.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),' click the "Sign with Ledger" button shown below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(46439).A+"",width:"1202",height:"1318"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(71272).A+"",width:"1208",height:"921"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.']}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{src:t(11217).A+"",width:"1205",height:"736"})}),"\n",(0,i.jsx)(n.p,{children:"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},58798:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger1-39686f6ffc5ad108d8e08973a40103f5.png"},77964:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger10-ee4f4fd9d8bf12ad0f33c5e3b4ada52c.png"},60853:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger11-475f40691a8f46d17fdeb029786ac923.png"},75102:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger12-7fe9fa74a7040dcf0fdb703c2ad1464f.png"},46439:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger13-4e3e030cf508f30ff250d22230e7dec9.png"},71272:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger14-35808a8e588d4316a63c8c7c1b050dd2.png"},11217:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger15-5d758ba4698580290a72e3d4d564c9b1.png"},29157:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger2-f1e2691594ec0cdcc0bec706cd2aade5.png"},46268:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger3-9b464ab0befd3928a5c659c77cf9555c.png"},1139:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger4-9a921643c0431d1eac3009da497cb280.png"},62282:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger5-9853a9b9bebe07a3a24f1febfac4ca03.png"},76513:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger6-b50bdcc2ba945ebf349fc3396785adc0.png"},55384:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger7-2d020b9e8d2b40169e089bda6ff77dda.png"},80335:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger8-c3399bf73ccd1e844f6f5790c7ad1796.png"},57670:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/ledger9-97001e377d0f7629626696f888dde09a.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4a522ab0.74a2f484.js b/assets/js/4a522ab0.74a2f484.js new file mode 100644 index 000000000..86c0d2794 --- /dev/null +++ b/assets/js/4a522ab0.74a2f484.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9950],{63369:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),a=s(28453);const i={title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},c="Installing and Interacting with a CEP-78 Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client",title:"On-chain Installation",description:"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/using-casper-client.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/using-casper-client",permalink:"/2.0.0/resources/tokens/using-casper-client",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/using-casper-client"},sidebar:"resources",previous:{title:"CEP-78 Modalities",permalink:"/2.0.0/resources/tokens/cep78/modalities"},next:{title:"Ownership Lookup",permalink:"/2.0.0/resources/tokens/cep78/reverse-lookup"}},o={},d=[{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Directly Invoking Entrypoints",id:"directly-invoking-entrypoints",level:2},{value:"Minting an NFT",id:"minting-an-nft",level:2},{value:"Transferring NFTs Between Users",id:"transferring-nfts-between-users",level:2},{value:"Burning an NFT",id:"burning-an-nft",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-and-interacting-with-a-cep-78-contract-using-the-rust-casper-client",children:"Installing and Interacting with a CEP-78 Contract using the Rust Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of ",(0,t.jsx)(n.code,{children:"1.63.0"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Information on the modalities used throughout this installation process can be found in the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/modalities",children:"modalities documentation"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,t.jsxs)(n.p,{children:["Installing the enhanced NFT contract to global state requires the use of a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Deploy"}),". In this case, the session code can be compiled to Wasm by running the ",(0,t.jsx)(n.code,{children:"make build-contract"})," command provided in the Makefile at the top level. The Wasm will be found in the ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory as ",(0,t.jsx)(n.code,{children:"contract.wasm"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='CEP-78-collection'\""})}),"\n",(0,t.jsx)(n.p,{children:'The name of the NFT collection as a string. In this instance, "CEP-78-collection".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_symbol:string='CEP78'\""})}),"\n",(0,t.jsx)(n.p,{children:'The symbol representing the NFT collection as a string. In this instance, "CEP78".'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"total_token_supply:u64='100'\""})}),"\n",(0,t.jsx)(n.p,{children:"The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"ownership_mode:u8='2'\""})}),"\n",(0,t.jsx)(n.p,{children:'The ownership mode for this contract. In this instance the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.'}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_kind:u8='1'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_metadata_kind:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"json_schema:string=''\""})}),"\n",(0,t.jsx)(n.p,{children:"An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom validated modality would require passing through a valid JSON schema for your custom metadata."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"identifier_mode:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"metadata_mutability:u8='0'\""})}),"\n",(0,t.jsx)(n.p,{children:"A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata."}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The session arguments match the available modalities as listed ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"}),"\n",(0,t.jsxs)(n.p,{children:["With the release of CEP-78 version 1.1, users that are interacting with a CEP-78 contract that does not use ",(0,t.jsx)(n.code,{children:"ReverseLookupMode"})," should opt out of using the client Wasms provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost compared against using the provided client Wasm to invoke the entrypoint."]}),"\n",(0,t.jsxs)(n.p,{children:["You may invoke the ",(0,t.jsx)(n.code,{children:"mint"}),", ",(0,t.jsx)(n.code,{children:"transfer"})," or ",(0,t.jsx)(n.code,{children:"burn"})," entrypoints directly through either the contract package hash or the contract hash directly."]}),"\n",(0,t.jsxs)(n.p,{children:["Specifically in the case of ",(0,t.jsx)(n.code,{children:"mint"}),", there are fewer runtime arguments that must be provided, thereby reducing the total gas cost of minting an NFT."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Mint using StoredVersionByHash"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-package-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "mint" \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Example Transfer using StoredContractByHash"})}),"\n",(0,t.jsxs)(n.p,{children:["Based on the identifier mode for the given contract instance, either the ",(0,t.jsx)(n.code,{children:"token_id"})," runtime argument must be passed in or in the case of the hash identifier mode, the ",(0,t.jsx)(n.code,{children:"token_hash"})," runtime argument."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\ --payment-amount 7500000000 \\ -k ~/secret_key.pem \\\n--session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \\\n--session-entry-point "transfer" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "token_id:u64=\'0\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"minting-an-nft",children:"Minting an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"mint"})," function of the contract to mint an NFT for the user associated with ",(0,t.jsx)(n.code,{children:"node-1"})," in an ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/nctl-test",children:"NCTL environment"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"collection_name:string='cep78_<collection_name>'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,t.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,t.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95\'" \\\n--session-arg "collection_name:string=\'cep78_<collection_name>\'"` \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-nfts-between-users",children:"Transferring NFTs Between Users"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"transfer"})," function to transfer ownership of an NFT from one user to another. In this case, we are transferring the previously minted NFT from the user associated with ",(0,t.jsx)(n.code,{children:"node-2"})," to the user associated with ",(0,t.jsx)(n.code,{children:"node-3"}),"."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,t.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,t.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,t.jsxs)(n.p,{children:["Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,t.jsx)(n.code,{children:"token_id"})," rather than a ",(0,t.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"burning-an-nft",children:"Burning an NFT"}),"\n",(0,t.jsxs)(n.p,{children:["Below is an example of a ",(0,t.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,t.jsx)(n.code,{children:"burn"})," function to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'})}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,t.jsx)(n.p,{children:"The session hash corresponding to the NFT's contract hash."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:'--session-entry-point "burn"'})}),"\n",(0,t.jsxs)(n.p,{children:["The entrypoint corresponding to the ",(0,t.jsx)(n.code,{children:"burn"})," function."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,t.jsxs)(n.p,{children:["The token ID for the NFT to be burned. If the ",(0,t.jsx)(n.code,{children:"identifier_mode"})," is not set to ",(0,t.jsx)(n.code,{children:"Ordinal"}),", you must provide the ",(0,t.jsx)(n.code,{children:"token_hash"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:(0,t.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ab63648.4c995b82.js b/assets/js/4ab63648.4c995b82.js new file mode 100644 index 000000000..f4f7d5d4e --- /dev/null +++ b/assets/js/4ab63648.4c995b82.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31973],{87630:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(74848),a=r(28453);const o={},t="R",c={id:"concepts/glossary/R",title:"R",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/R.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/R",permalink:"/1.5.X/concepts/glossary/R",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Q",permalink:"/1.5.X/concepts/glossary/Q"},next:{title:"S",permalink:"/1.5.X/concepts/glossary/S"}},l={},i=[{value:"Reward",id:"reward",level:2},{value:"Root hash",id:"root-hash",level:2},{value:"Rust",id:"rust",level:2},{value:"Rustdocs",id:"rustdocs",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"r",children:"R"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"reward",children:"Reward"}),"\n",(0,n.jsxs)(s.p,{children:["Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D#delegation-rate",children:"delegation rate"}),". Rewards are distributed at the end of each era."]}),"\n",(0,n.jsx)(s.h2,{id:"root-hash",children:"Root hash"}),"\n",(0,n.jsxs)(s.p,{children:["The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M#merkle-tree",children:"Merkle tree"})," if you wish to learn more."]}),"\n",(0,n.jsx)(s.h2,{id:"rust",children:"Rust"}),"\n",(0,n.jsx)(s.p,{children:"A programming language similar to C++, designed for performance and safety, especially safe concurrency."}),"\n",(0,n.jsx)(s.h2,{id:"rustdocs",children:"Rustdocs"}),"\n",(0,n.jsxs)(s.p,{children:["As part of the Rust development environment, the Rustdocs describe the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-contract/",children:"Casper contracts library"}),", the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-types/",children:"Casper types library"}),", and the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"Casper test support library"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>c});var n=r(96540);const a={},o=n.createContext(a);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ab63648.80eee16a.js b/assets/js/4ab63648.80eee16a.js deleted file mode 100644 index bbe4c8f8a..000000000 --- a/assets/js/4ab63648.80eee16a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1973],{87630:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(74848),a=r(28453);const o={},t="R",c={id:"concepts/glossary/R",title:"R",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/R.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/R",permalink:"/concepts/glossary/R",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Q",permalink:"/concepts/glossary/Q"},next:{title:"S",permalink:"/concepts/glossary/S"}},l={},i=[{value:"Reward",id:"reward",level:2},{value:"Root hash",id:"root-hash",level:2},{value:"Rust",id:"rust",level:2},{value:"Rustdocs",id:"rustdocs",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"r",children:"R"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"reward",children:"Reward"}),"\n",(0,n.jsxs)(s.p,{children:["Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D#delegation-rate",children:"delegation rate"}),". Rewards are distributed at the end of each era."]}),"\n",(0,n.jsx)(s.h2,{id:"root-hash",children:"Root hash"}),"\n",(0,n.jsxs)(s.p,{children:["The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M#merkle-tree",children:"Merkle tree"})," if you wish to learn more."]}),"\n",(0,n.jsx)(s.h2,{id:"rust",children:"Rust"}),"\n",(0,n.jsx)(s.p,{children:"A programming language similar to C++, designed for performance and safety, especially safe concurrency."}),"\n",(0,n.jsx)(s.h2,{id:"rustdocs",children:"Rustdocs"}),"\n",(0,n.jsxs)(s.p,{children:["As part of the Rust development environment, the Rustdocs describe the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-contract/",children:"Casper contracts library"}),", the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-types/",children:"Casper types library"}),", and the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"Casper test support library"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>c});var n=r(96540);const a={},o=n.createContext(a);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ba3ceff.081c4b34.js b/assets/js/4ba3ceff.081c4b34.js new file mode 100644 index 000000000..2b62e8548 --- /dev/null +++ b/assets/js/4ba3ceff.081c4b34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[69457],{36921:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=r(74848),o=r(28453);const i={title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},s="Getting Started Video",a={id:"resources/beginner/getting-started-tutorial",title:"Getting Started",description:"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.",source:"@site/docs/resources/beginner/getting-started-tutorial.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/getting-started-tutorial",permalink:"/resources/tutorials/beginner/getting-started-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/tutorials/beginner/"},next:{title:"Introduction",permalink:"/counter"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",iframe:"iframe",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started-video",children:"Getting Started Video"})}),"\n",(0,n.jsxs)(t.p,{children:["This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started documentation"}),"."]}),"\n",(0,n.jsxs)(t.p,{align:"center",children:["\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=XvV02iBoctc&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=1",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ba3ceff.df7f2c6a.js b/assets/js/4ba3ceff.df7f2c6a.js deleted file mode 100644 index e277aef3f..000000000 --- a/assets/js/4ba3ceff.df7f2c6a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9457],{36921:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=r(74848),o=r(28453);const i={title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},s="Getting Started Video",a={id:"resources/beginner/getting-started-tutorial",title:"Getting Started",description:"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.",source:"@site/docs/resources/beginner/getting-started-tutorial.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/getting-started-tutorial",permalink:"/next/resources/tutorials/beginner/getting-started-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},sidebar:"tutorials",previous:{title:"Overview",permalink:"/next/resources/tutorials/beginner/"},next:{title:"Introduction",permalink:"/next/counter"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",iframe:"iframe",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started-video",children:"Getting Started Video"})}),"\n",(0,n.jsxs)(t.p,{children:["This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding ",(0,n.jsx)(t.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started documentation"}),"."]}),"\n",(0,n.jsxs)(t.p,{align:"center",children:["\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=XvV02iBoctc&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=1",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4bf77031.6626d6ed.js b/assets/js/4bf77031.6626d6ed.js new file mode 100644 index 000000000..d4642252a --- /dev/null +++ b/assets/js/4bf77031.6626d6ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92805],{86151:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter-testnet/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/walkthrough.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/walkthrough",permalink:"/2.0.0/resources/beginner/counter-testnet/walkthrough",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/2.0.0/resources/beginner/counter-testnet/commands"},next:{title:"Querying a Node",permalink:"/2.0.0/resources/tutorials/beginner/querying-network"}},i={},h=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"account hash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, you can check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]"})," - Get the account-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state-root-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-state"})," - Query the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first."}),"\n",(0,s.jsx)(t.p,{children:"Next, get the state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You need to use the IP address of one of the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to deploy the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on the Testnet!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4c91363f.93a6ede3.js b/assets/js/4c91363f.93a6ede3.js new file mode 100644 index 000000000..64eacecc9 --- /dev/null +++ b/assets/js/4c91363f.93a6ede3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74374],{92383:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(74848),s=n(28453);const i={title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},r="Owner Reverse Lookup Functionality",a={id:"resources/tokens/cep78/reverse-lookup",title:"Ownership Lookup",description:"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.",source:"@site/docs/resources/tokens/cep78/reverse-lookup.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/reverse-lookup",permalink:"/resources/tokens/cep78/reverse-lookup",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/resources/tokens/using-casper-client"},next:{title:"CEP-78 JavaScript Client",permalink:"/resources/tokens/cep78/js-tutorial"}},c={},l=[{value:"The CEP-78 Page System",id:"the-cep-78-page-system",level:2},{value:"Updated Receipts",id:"updated-receipts",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"owner-reverse-lookup-functionality",children:"Owner Reverse Lookup Functionality"})}),"\n",(0,o.jsxs)(t.p,{children:["In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found ",(0,o.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"here"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract."}),"\n",(0,o.jsx)(t.p,{children:"This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page."}),"\n",(0,o.jsx)(t.h2,{id:"the-cep-78-page-system",children:"The CEP-78 Page System"}),"\n",(0,o.jsxs)(t.p,{children:["Ownership of NFTs within a CEP-78 contract is now tracked with a series of ",(0,o.jsx)(t.code,{children:"pages"}),", with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs."]}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"page_table"})," tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the ",(0,o.jsx)(t.code,{children:"register_owner"})," entrypoint."]}),"\n",(0,o.jsxs)(t.p,{children:["After registering as an owner, the contract creates an entry within the ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for the minting account or contract. This dictionary entry consists of a series of ",(0,o.jsx)(t.code,{children:"boolean"})," values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false."]}),"\n",(0,o.jsxs)(t.p,{children:["Upon minting the token, the user will pay for a page allocation. This adds them to the ",(0,o.jsx)(t.code,{children:"page"})," dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the ",(0,o.jsx)(t.code,{children:"page"})," dictionary will consist of 1,000 ",(0,o.jsx)(t.code,{children:"page_address"})," bits set to ",(0,o.jsx)(t.code,{children:"False"})," upon allocation, and the minting of any given token in that page will set the ",(0,o.jsx)(t.code,{children:"page_address"})," bit to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, that account or contract's ",(0,o.jsx)(t.code,{children:"page_table"})," will be updated by marking the corresponding page number's bit as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"The contract registers their account as an owner."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The contract creates a ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for that account, with 10 boolean values. As the numbering system begins with ",(0,o.jsx)(t.code,{children:"0"}),", the third boolean value corresponding with page ",(0,o.jsx)(t.code,{children:"2"})," is set to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The account pays for allocation of page 2, creating an entry in the ",(0,o.jsx)(t.code,{children:"Page 2"})," dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 350 as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for ",(0,o.jsx)(t.code,{children:"page 5"})," to be allocated to them. They would then be added to the ",(0,o.jsx)(t.code,{children:"page 5"})," dictionary with the ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 125 set as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"This system binds the data writing costs to a maximum size of any given page dictionary."}),"\n",(0,o.jsx)(t.h2,{id:"updated-receipts",children:"Updated Receipts"}),"\n",(0,o.jsxs)(t.p,{children:["If the contract enables ",(0,o.jsx)(t.code,{children:"OwnerReverseLookupMode"}),", calling the ",(0,o.jsx)(t.code,{children:"updated_receipts"})," entrypoint will return a list of receipt names alongside the dictionary for the relevant pages."]}),"\n",(0,o.jsxs)(t.p,{children:["Updated receipts come in the format of ",(0,o.jsx)(t.code,{children:'"{<collection name>}\\_m{modulo}\\_p{<page number>}"'}),". Once again using the 2,350th token as an example, the receipt would read:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"cep78_collection_m_350_p_2\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can determine the token number by multiplying the ",(0,o.jsx)(t.code,{children:"page_number"})," by the ",(0,o.jsx)(t.code,{children:"page_size"}),"(1,000) and adding the ",(0,o.jsx)(t.code,{children:"modulo"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["If the ",(0,o.jsx)(t.code,{children:"NFTIdentifierMode"})," is set to ",(0,o.jsx)(t.code,{children:"Ordinal"}),", this number corresponds directly to the token ID."]}),"\n",(0,o.jsxs)(t.p,{children:["If it is set to ",(0,o.jsx)(t.code,{children:"Hash"}),", you will need to reference the ",(0,o.jsx)(t.code,{children:"HASH_BY_INDEX"})," dictionary to determine the mapping of token numbers to token hashes."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4c91363f.d784b1bc.js b/assets/js/4c91363f.d784b1bc.js deleted file mode 100644 index 7e1093438..000000000 --- a/assets/js/4c91363f.d784b1bc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4374],{92383:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(74848),s=n(28453);const i={title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},r="Owner Reverse Lookup Functionality",a={id:"resources/tokens/cep78/reverse-lookup",title:"Ownership Lookup",description:"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.",source:"@site/docs/resources/tokens/cep78/reverse-lookup.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/reverse-lookup",permalink:"/next/resources/tokens/cep78/reverse-lookup",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/next/resources/tokens/using-casper-client"},next:{title:"CEP-78 JavaScript Client",permalink:"/next/resources/tokens/cep78/js-tutorial"}},c={},l=[{value:"The CEP-78 Page System",id:"the-cep-78-page-system",level:2},{value:"Updated Receipts",id:"updated-receipts",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"owner-reverse-lookup-functionality",children:"Owner Reverse Lookup Functionality"})}),"\n",(0,o.jsxs)(t.p,{children:["In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found ",(0,o.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"here"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract."}),"\n",(0,o.jsx)(t.p,{children:"This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page."}),"\n",(0,o.jsx)(t.h2,{id:"the-cep-78-page-system",children:"The CEP-78 Page System"}),"\n",(0,o.jsxs)(t.p,{children:["Ownership of NFTs within a CEP-78 contract is now tracked with a series of ",(0,o.jsx)(t.code,{children:"pages"}),", with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs."]}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"page_table"})," tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the ",(0,o.jsx)(t.code,{children:"register_owner"})," entrypoint."]}),"\n",(0,o.jsxs)(t.p,{children:["After registering as an owner, the contract creates an entry within the ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for the minting account or contract. This dictionary entry consists of a series of ",(0,o.jsx)(t.code,{children:"boolean"})," values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false."]}),"\n",(0,o.jsxs)(t.p,{children:["Upon minting the token, the user will pay for a page allocation. This adds them to the ",(0,o.jsx)(t.code,{children:"page"})," dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the ",(0,o.jsx)(t.code,{children:"page"})," dictionary will consist of 1,000 ",(0,o.jsx)(t.code,{children:"page_address"})," bits set to ",(0,o.jsx)(t.code,{children:"False"})," upon allocation, and the minting of any given token in that page will set the ",(0,o.jsx)(t.code,{children:"page_address"})," bit to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, that account or contract's ",(0,o.jsx)(t.code,{children:"page_table"})," will be updated by marking the corresponding page number's bit as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"The contract registers their account as an owner."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The contract creates a ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for that account, with 10 boolean values. As the numbering system begins with ",(0,o.jsx)(t.code,{children:"0"}),", the third boolean value corresponding with page ",(0,o.jsx)(t.code,{children:"2"})," is set to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The account pays for allocation of page 2, creating an entry in the ",(0,o.jsx)(t.code,{children:"Page 2"})," dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 350 as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for ",(0,o.jsx)(t.code,{children:"page 5"})," to be allocated to them. They would then be added to the ",(0,o.jsx)(t.code,{children:"page 5"})," dictionary with the ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 125 set as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"This system binds the data writing costs to a maximum size of any given page dictionary."}),"\n",(0,o.jsx)(t.h2,{id:"updated-receipts",children:"Updated Receipts"}),"\n",(0,o.jsxs)(t.p,{children:["If the contract enables ",(0,o.jsx)(t.code,{children:"OwnerReverseLookupMode"}),", calling the ",(0,o.jsx)(t.code,{children:"updated_receipts"})," entrypoint will return a list of receipt names alongside the dictionary for the relevant pages."]}),"\n",(0,o.jsxs)(t.p,{children:["Updated receipts come in the format of ",(0,o.jsx)(t.code,{children:'"{<collection name>}\\_m{modulo}\\_p{<page number>}"'}),". Once again using the 2,350th token as an example, the receipt would read:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"cep78_collection_m_350_p_2\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can determine the token number by multiplying the ",(0,o.jsx)(t.code,{children:"page_number"})," by the ",(0,o.jsx)(t.code,{children:"page_size"}),"(1,000) and adding the ",(0,o.jsx)(t.code,{children:"modulo"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["If the ",(0,o.jsx)(t.code,{children:"NFTIdentifierMode"})," is set to ",(0,o.jsx)(t.code,{children:"Ordinal"}),", this number corresponds directly to the token ID."]}),"\n",(0,o.jsxs)(t.p,{children:["If it is set to ",(0,o.jsx)(t.code,{children:"Hash"}),", you will need to reference the ",(0,o.jsx)(t.code,{children:"HASH_BY_INDEX"})," dictionary to determine the mapping of token numbers to token hashes."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4cc44e19.7d979e88.js b/assets/js/4cc44e19.7d979e88.js new file mode 100644 index 000000000..11423bfa6 --- /dev/null +++ b/assets/js/4cc44e19.7d979e88.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73030],{19066:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var a=n(74848),o=n(28453);const s={},i="Global State {#global-state-head}",r={id:"concepts/global-state",title:"Global State",description:"global-state-head}",source:"@site/versioned_docs/version-2.0.0/concepts/global-state.md",sourceDirName:"concepts",slug:"/concepts/global-state",permalink:"/2.0.0/concepts/global-state",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Transaction Lifecycle",permalink:"/2.0.0/transactions-and-transaction-lifecycle"},next:{title:"Smart Contracts",permalink:"/2.0.0/concepts/smart-contracts"}},c={},l=[{value:"Introduction",id:"global-state-intro",level:2},{value:"Merkle Trie Structure",id:"global-state-trie",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"global-state-head",children:"Global State"})}),"\n",(0,a.jsx)(t.h2,{id:"global-state-intro",children:"Introduction"}),"\n",(0,a.jsxs)(t.p,{children:["The storage layer for the Casper blockchain is called ",(0,a.jsx)(t.em,{children:"global state"})," and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Refer to ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/serialization/types#serialization-standard-serialization-key",children:"Keys and Permissions"})," for further information on keys."]})}),"\n",(0,a.jsxs)(t.p,{children:["Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a ",(0,a.jsx)(t.a,{href:"#global-state-trie",children:"Merkle trie"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"global-state-trie",children:"Merkle Trie Structure"}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Global State",src:n(67324).A+"",width:"5344",height:"4496"})}),"\n",(0,a.jsx)(t.p,{children:"At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes."}),"\n",(0,a.jsx)(t.p,{children:"Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value."}),"\n",(0,a.jsx)(t.p,{children:"Formally, a trie node is one of the following:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"a leaf, which includes a key and a value"}),"\n",(0,a.jsxs)(t.li,{children:["a branch, which has up to 256 ",(0,a.jsx)(t.code,{children:"blake2b256"})," hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)"]}),"\n",(0,a.jsxs)(t.li,{children:["an extension node, which includes a byte array (called the affix) and a ",(0,a.jsx)(t.code,{children:"blake2b256"})," hash pointing to another node in the trie"]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node."}),"\n",(0,a.jsx)(t.p,{children:"The Rust implementation of Casper's trie can be found on GitHub:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie/mod.rs#L340",children:"Definition of the trie data structure"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L44",children:"Reading from the trie"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L845",children:"Writing to the trie"})}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a ",(0,a.jsx)(t.code,{children:"TrieStore"}),", which allows us to look up the root node for each trie."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},67324:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/global-state-6ff422f087f093966968318f641d26fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const o={},s=a.createContext(o);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4cc75cd6.34166208.js b/assets/js/4cc75cd6.34166208.js deleted file mode 100644 index 907482c79..000000000 --- a/assets/js/4cc75cd6.34166208.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3580],{98924:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=a(74848),s=a(28453);const c={title:"Querying Global State"},r="Querying Global State",o={id:"developers/cli/querying-global-state",title:"Querying Global State",description:"This page explains how to query global state after contract installation.",source:"@site/versioned_docs/version-1.5.X/developers/cli/querying-global-state.md",sourceDirName:"developers/cli",slug:"/developers/cli/querying-global-state",permalink:"/developers/cli/querying-global-state",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Querying Global State"},sidebar:"developers",previous:{title:"Installing Contracts",permalink:"/developers/cli/installing-contracts"},next:{title:"Calling Contracts",permalink:"/developers/cli/calling-contracts"}},l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Getting the State Root Hash",id:"get-state-root-hash",level:2},{value:"Sending the Query",id:"query-global-state",level:2},{value:"Query the account",id:"query-the-account",level:3},{value:"Query the contract",id:"query-the-contract",level:3},{value:"Query a value using its key and the contract hash",id:"query-a-value-using-its-key-and-the-contract-hash",level:3},{value:"Query a value using the account hash and named keys",id:"query-a-value-using-the-account-hash-and-named-keys",level:3},{value:"Query contract package state",id:"query-contract-package-state",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"querying-global-state",children:"Querying Global State"})}),"\n",(0,t.jsx)(n.p,{children:"This page explains how to query global state after contract installation."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You have ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installed a contract"})," on a Casper network"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"get-state-root-hash",children:"Getting the State Root Hash"}),"\n",(0,t.jsx)(n.p,{children:"The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,t.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,t.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,t.jsx)(n.h2,{id:"query-global-state",children:"Sending the Query"}),"\n",(0,t.jsxs)(n.p,{children:["Next, query the state of a Casper network at a given time, specified by the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," described above. You can dive into the data stored in global state using the optional query path argument ",(0,t.jsx)(n.code,{children:"-q"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [HASH_STRING] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"q"})," - An optional query path argument that allows you to drill into the specifics of a query with respect to the key"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"query-the-account",children:"Query the account"}),"\n",(0,t.jsx)(n.p,{children:"To find your account details, query global state using your account hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d\n"})}),"\n",(0,t.jsx)(n.p,{children:'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.'}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample account state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6831525034388467034,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[27614 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "weight": 1\n }\n ],\n "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",\n "named_keys": [\n {\n "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "name": "counter"\n },\n {\n "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "name": "counter_access_uref"\n },\n {\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n },\n {\n "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",\n "name": "version"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"If you don't know your account hash, you can run this command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,t.jsx)(n.h3,{id:"query-the-contract",children:"Query the contract"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to query global state given a contract hash. We use the contract hash from the sample response above."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the sample contract would look and would contain details such as the ",(0,t.jsx)(n.code,{children:"contract_package_hash"}),", the contract ",(0,t.jsx)(n.code,{children:"entry_points"}),", and the ",(0,t.jsx)(n.code,{children:"named_keys"})," for the contract."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -4657473054587773855,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[21330 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.5"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"query-a-value-using-its-key-and-the-contract-hash",children:"Query a value using its key and the contract hash"}),"\n",(0,t.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,t.jsx)(n.code,{children:"-q"})," option. This example comes from the ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"}),', where a "count" variable is incremented and stored under a named key.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [CONTRACT_HASH] \\\n -q "count"\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample stored value"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -2540117660598287261,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[56562 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"query-a-value-using-the-account-hash-and-named-keys",children:"Query a value using the account hash and named keys"}),"\n",(0,t.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \\\n -q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The response should be the same as in Example 3, above."}),"\n",(0,t.jsx)(n.h3,{id:"query-contract-package-state",children:"Query contract package state"}),"\n",(0,t.jsx)(n.p,{children:"You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the contract package details would look. The response would contain the ",(0,t.jsx)(n.code,{children:"contract_hash"}),", which you would need to ",(0,t.jsx)(n.a,{href:"/developers/cli/calling-contracts#calling-contracts-by-hash",children:"call a contract by hash"})," in the next section. You would also see the ",(0,t.jsx)(n.code,{children:"access_key"})," for the ",(0,t.jsx)(n.code,{children:"ContractPackage"})," and the current ",(0,t.jsx)(n.code,{children:"contract_version"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract package state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6225901853092301031,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[20964 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsx)(n.p,{children:"This video shows you what to expect when querying the network."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=9",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn ",(0,t.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>o});var t=a(96540);const s={},c=t.createContext(s);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4cc75cd6.c5db8ce8.js b/assets/js/4cc75cd6.c5db8ce8.js new file mode 100644 index 000000000..eb7c2a008 --- /dev/null +++ b/assets/js/4cc75cd6.c5db8ce8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13580],{98924:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=a(74848),s=a(28453);const c={title:"Querying Global State"},r="Querying Global State",o={id:"developers/cli/querying-global-state",title:"Querying Global State",description:"This page explains how to query global state after contract installation.",source:"@site/versioned_docs/version-1.5.X/developers/cli/querying-global-state.md",sourceDirName:"developers/cli",slug:"/developers/cli/querying-global-state",permalink:"/1.5.X/developers/cli/querying-global-state",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Querying Global State"},sidebar:"developers",previous:{title:"Installing Contracts",permalink:"/1.5.X/developers/cli/installing-contracts"},next:{title:"Calling Contracts",permalink:"/1.5.X/developers/cli/calling-contracts"}},l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Getting the State Root Hash",id:"get-state-root-hash",level:2},{value:"Sending the Query",id:"query-global-state",level:2},{value:"Query the account",id:"query-the-account",level:3},{value:"Query the contract",id:"query-the-contract",level:3},{value:"Query a value using its key and the contract hash",id:"query-a-value-using-its-key-and-the-contract-hash",level:3},{value:"Query a value using the account hash and named keys",id:"query-a-value-using-the-account-hash-and-named-keys",level:3},{value:"Query contract package state",id:"query-contract-package-state",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"querying-global-state",children:"Querying Global State"})}),"\n",(0,t.jsx)(n.p,{children:"This page explains how to query global state after contract installation."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You have ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"installed a contract"})," on a Casper network"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"get-state-root-hash",children:"Getting the State Root Hash"}),"\n",(0,t.jsx)(n.p,{children:"The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,t.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,t.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,t.jsx)(n.h2,{id:"query-global-state",children:"Sending the Query"}),"\n",(0,t.jsxs)(n.p,{children:["Next, query the state of a Casper network at a given time, specified by the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," described above. You can dive into the data stored in global state using the optional query path argument ",(0,t.jsx)(n.code,{children:"-q"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [HASH_STRING] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"q"})," - An optional query path argument that allows you to drill into the specifics of a query with respect to the key"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"query-the-account",children:"Query the account"}),"\n",(0,t.jsx)(n.p,{children:"To find your account details, query global state using your account hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d\n"})}),"\n",(0,t.jsx)(n.p,{children:'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.'}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample account state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6831525034388467034,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[27614 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "weight": 1\n }\n ],\n "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",\n "named_keys": [\n {\n "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "name": "counter"\n },\n {\n "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "name": "counter_access_uref"\n },\n {\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n },\n {\n "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",\n "name": "version"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"If you don't know your account hash, you can run this command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,t.jsx)(n.h3,{id:"query-the-contract",children:"Query the contract"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to query global state given a contract hash. We use the contract hash from the sample response above."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the sample contract would look and would contain details such as the ",(0,t.jsx)(n.code,{children:"contract_package_hash"}),", the contract ",(0,t.jsx)(n.code,{children:"entry_points"}),", and the ",(0,t.jsx)(n.code,{children:"named_keys"})," for the contract."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -4657473054587773855,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[21330 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.5"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"query-a-value-using-its-key-and-the-contract-hash",children:"Query a value using its key and the contract hash"}),"\n",(0,t.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,t.jsx)(n.code,{children:"-q"})," option. This example comes from the ",(0,t.jsx)(n.a,{href:"/1.5.X/counter",children:"Counter Contract Tutorial"}),', where a "count" variable is incremented and stored under a named key.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [CONTRACT_HASH] \\\n -q "count"\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample stored value"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -2540117660598287261,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[56562 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"query-a-value-using-the-account-hash-and-named-keys",children:"Query a value using the account hash and named keys"}),"\n",(0,t.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \\\n -q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The response should be the same as in Example 3, above."}),"\n",(0,t.jsx)(n.h3,{id:"query-contract-package-state",children:"Query contract package state"}),"\n",(0,t.jsx)(n.p,{children:"You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the contract package details would look. The response would contain the ",(0,t.jsx)(n.code,{children:"contract_hash"}),", which you would need to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts#calling-contracts-by-hash",children:"call a contract by hash"})," in the next section. You would also see the ",(0,t.jsx)(n.code,{children:"access_key"})," for the ",(0,t.jsx)(n.code,{children:"ContractPackage"})," and the current ",(0,t.jsx)(n.code,{children:"contract_version"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract package state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6225901853092301031,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[20964 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsx)(n.p,{children:"This video shows you what to expect when querying the network."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=9",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>o});var t=a(96540);const s={},c=t.createContext(s);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d118a4e.26672722.js b/assets/js/4d118a4e.26672722.js new file mode 100644 index 000000000..c8cd31b02 --- /dev/null +++ b/assets/js/4d118a4e.26672722.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18621],{33041:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),a=t(28453);const i={title:"Delegating Tokens"},d="Delegating with the Casper Client",r={id:"developers/cli/delegate",title:"Delegating Tokens",description:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.",source:"@site/docs/developers/cli/delegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/delegate",permalink:"/developers/cli/delegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Delegating Tokens"},sidebar:"developers",previous:{title:"Verifying a Transfer",permalink:"/developers/cli/transfers/verify-transfer"},next:{title:"Redelegating Tokens with the Casper Client",permalink:"/developers/cli/redelegate"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Acquiring a Validator's Public Key",id:"acquiring-a-validators-public-key",level:3},{value:"Sending the Delegation Request",id:"sending-the-delegation-request",level:2},{value:"Method 1: Delegating with the System Auction Contract",id:"delegating-system-auction",level:3},{value:"Method 2: Delegating with Compiled Wasm",id:"delegating-compiled-wasm",level:3},{value:"Building the delegation Wasm",id:"building-the-delegation-wasm",level:4},{value:"Sending the delegation request",id:"sending-the-delegation-wasm-request",level:4},{value:"Confirming the Delegation",id:"confirming-the-delegation",level:2},{value:"Checking Validator Status",id:"checking-validator-status",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"delegating-with-the-casper-client",children:"Delegating with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all prerequisites listed ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"here"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"installed a smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"}),"\n",(0,s.jsxs)(n.p,{children:["This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#sending-the-delegation-request",children:"delegation request"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process."}),"\n",(0,s.jsx)(n.p,{children:"The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set."}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-delegation-request",children:"Sending the Delegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"The minimum amount to delegate is 500 CSPR (500,000,000,000 motes)."})}),"\n",(0,s.jsx)(n.h3,{id:"delegating-system-auction",children:"Method 1: Delegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 500 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"delegating-compiled-wasm",children:"Method 2: Delegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a delegation is to compile the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," and send it to the network via a deploy. Here are the steps to compile the contract yourself."]}),"\n",(0,s.jsx)(n.h4,{id:"building-the-delegation-wasm",children:"Building the delegation Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Obtain the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," by cloning the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Prepare the Rust environment and then build the contracts using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/Makefile",children:"Makefile"})," provided in the repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Once you build the contracts, you can use the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,s.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release/"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ls target/wasm32-unknown-unknown/release/delegate.wasm\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-delegation-wasm-request",children:"Sending the delegation request"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, we use the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to the network to initiate the delegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/delegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"confirming-the-delegation",children:"Confirming the Delegation"}),"\n",(0,s.jsxs)(n.p,{children:["A Casper network maintains an ",(0,s.jsx)(n.em,{children:"auction"})," where validators ",(0,s.jsx)(n.em,{children:"bid"})," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Your delegation is part of the ",(0,s.jsx)(n.em,{children:"bid"})," to the ",(0,s.jsx)(n.em,{children:"auction"})]}),"\n",(0,s.jsxs)(n.li,{children:["The validator is part of the ",(0,s.jsx)(n.em,{children:"active"})," validator set"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"get-auction-info"})," call will return all the bids currently in the auction contract and the list of active validators for ",(0,s.jsx)(n.code,{children:"4"})," future eras from the present era."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a sample of the ",(0,s.jsx)(n.code,{children:"bids"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,s.jsx)(n.code,{children:"bid"})," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure."]}),"\n",(0,s.jsx)(n.h4,{id:"checking-validator-status",children:"Checking Validator Status"}),"\n",(0,s.jsxs)(n.p,{children:["The auction maintains a field called ",(0,s.jsx)(n.code,{children:"era_validators"}),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,s.jsx)(n.code,{children:"PublicKeys"})," of the active validators for that era, along with their stake in the network."]}),"\n",(0,s.jsxs)(n.p,{children:["If a validator is part of the set, its public key will be in the ",(0,s.jsx)(n.code,{children:"era_validators"})," field as part of the ",(0,s.jsx)(n.code,{children:"Auction"})," data structure returned by ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In the response, check the ",(0,s.jsx)(n.code,{children:'"auction_state"."era_validators"'})," structure, which should contain the public key of the selected validator for the era in which the validator will be active."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is an example of the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the above example, we see the public keys of the active validators in Era ",(0,s.jsx)(n.code,{children:"9"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d118a4e.fd0876b0.js b/assets/js/4d118a4e.fd0876b0.js deleted file mode 100644 index d38bbe1bf..000000000 --- a/assets/js/4d118a4e.fd0876b0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8621],{33041:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),a=t(28453);const i={title:"Delegating Tokens"},d="Delegating with the Casper Client",r={id:"developers/cli/delegate",title:"Delegating Tokens",description:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.",source:"@site/docs/developers/cli/delegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/delegate",permalink:"/next/developers/cli/delegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Delegating Tokens"},sidebar:"developers",previous:{title:"Verifying a Transfer",permalink:"/next/developers/cli/transfers/verify-transfer"},next:{title:"Redelegating Tokens with the Casper Client",permalink:"/next/developers/cli/redelegate"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Acquiring a Validator's Public Key",id:"acquiring-a-validators-public-key",level:3},{value:"Sending the Delegation Request",id:"sending-the-delegation-request",level:2},{value:"Method 1: Delegating with the System Auction Contract",id:"delegating-system-auction",level:3},{value:"Method 2: Delegating with Compiled Wasm",id:"delegating-compiled-wasm",level:3},{value:"Building the delegation Wasm",id:"building-the-delegation-wasm",level:4},{value:"Sending the delegation request",id:"sending-the-delegation-wasm-request",level:4},{value:"Confirming the Delegation",id:"confirming-the-delegation",level:2},{value:"Checking Validator Status",id:"checking-validator-status",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"delegating-with-the-casper-client",children:"Delegating with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all prerequisites listed ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"here"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"installed a smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"}),"\n",(0,s.jsxs)(n.p,{children:["This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate#sending-the-delegation-request",children:"delegation request"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process."}),"\n",(0,s.jsx)(n.p,{children:"The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set."}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-delegation-request",children:"Sending the Delegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"The minimum amount to delegate is 500 CSPR (500,000,000,000 motes)."})}),"\n",(0,s.jsx)(n.h3,{id:"delegating-system-auction",children:"Method 1: Delegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 500 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"delegating-compiled-wasm",children:"Method 2: Delegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a delegation is to compile the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," and send it to the network via a deploy. Here are the steps to compile the contract yourself."]}),"\n",(0,s.jsx)(n.h4,{id:"building-the-delegation-wasm",children:"Building the delegation Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Obtain the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," by cloning the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Prepare the Rust environment and then build the contracts using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/Makefile",children:"Makefile"})," provided in the repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Once you build the contracts, you can use the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,s.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release/"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ls target/wasm32-unknown-unknown/release/delegate.wasm\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-delegation-wasm-request",children:"Sending the delegation request"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, we use the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to the network to initiate the delegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/delegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"confirming-the-delegation",children:"Confirming the Delegation"}),"\n",(0,s.jsxs)(n.p,{children:["A Casper network maintains an ",(0,s.jsx)(n.em,{children:"auction"})," where validators ",(0,s.jsx)(n.em,{children:"bid"})," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Your delegation is part of the ",(0,s.jsx)(n.em,{children:"bid"})," to the ",(0,s.jsx)(n.em,{children:"auction"})]}),"\n",(0,s.jsxs)(n.li,{children:["The validator is part of the ",(0,s.jsx)(n.em,{children:"active"})," validator set"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"get-auction-info"})," call will return all the bids currently in the auction contract and the list of active validators for ",(0,s.jsx)(n.code,{children:"4"})," future eras from the present era."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a sample of the ",(0,s.jsx)(n.code,{children:"bids"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,s.jsx)(n.code,{children:"bid"})," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure."]}),"\n",(0,s.jsx)(n.h4,{id:"checking-validator-status",children:"Checking Validator Status"}),"\n",(0,s.jsxs)(n.p,{children:["The auction maintains a field called ",(0,s.jsx)(n.code,{children:"era_validators"}),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,s.jsx)(n.code,{children:"PublicKeys"})," of the active validators for that era, along with their stake in the network."]}),"\n",(0,s.jsxs)(n.p,{children:["If a validator is part of the set, its public key will be in the ",(0,s.jsx)(n.code,{children:"era_validators"})," field as part of the ",(0,s.jsx)(n.code,{children:"Auction"})," data structure returned by ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In the response, check the ",(0,s.jsx)(n.code,{children:'"auction_state"."era_validators"'})," structure, which should contain the public key of the selected validator for the era in which the validator will be active."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is an example of the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the above example, we see the public keys of the active validators in Era ",(0,s.jsx)(n.code,{children:"9"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d355c12.2357dd50.js b/assets/js/4d355c12.2357dd50.js new file mode 100644 index 000000000..a3c059b2e --- /dev/null +++ b/assets/js/4d355c12.2357dd50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49546],{33580:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var s=t(74848),i=t(28453);const a={title:"Undelegating Tokens"},o="Undelegating Tokens with the Casper Client",d={id:"developers/cli/undelegate",title:"Undelegating Tokens",description:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.",source:"@site/versioned_docs/version-2.0.0/developers/cli/undelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/undelegate",permalink:"/2.0.0/developers/cli/undelegate",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Undelegating Tokens"},sidebar:"developers",previous:{title:"Redelegating Tokens with the Casper Client",permalink:"/2.0.0/developers/cli/redelegate"},next:{title:"Sending Transactions",permalink:"/2.0.0/developers/cli/sending-transactions"}},r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sending the Undelegation Request",id:"sending-the-undelegation-deploy",level:2},{value:"Method 1: Undelegating with the System Auction Contract",id:"undelegating-system-auction",level:3},{value:"Method 2: Undelegating with Compiled Wasm",id:"undelegating-compiled-wasm",level:3},{value:"Verifying the Undelegation",id:"verifying-the-undelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens-with-the-casper-client",children:"Undelegating Tokens with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network and you have the validator's public key"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-undelegation-deploy",children:"Sending the Undelegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-system-auction",children:"Method 1: Undelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 100 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-compiled-wasm",children:"Method 2: Undelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["As part of this process, you need to ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that produce the undelegation Wasm."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, use the Casper CLI client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," to the network to initiate the undelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/undelegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-undelegation",children:"Verifying the Undelegation"}),"\n",(0,s.jsx)(n.p,{children:"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."}),"\n",(0,s.jsx)(n.p,{children:"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the public key and the amount are absent from the ",(0,s.jsx)(n.code,{children:"bids"})," structure, we can safely conclude that we have indeed undelegated from the validator."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Important Note"}),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4d4c05c4.06123333.js b/assets/js/4d4c05c4.06123333.js new file mode 100644 index 000000000..e53346252 --- /dev/null +++ b/assets/js/4d4c05c4.06123333.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46928],{90719:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var r=t(74848),s=t(28453);const i={title:"Introduction",slug:"/writing-contracts"},c="Writing On-Chain Code",o={id:"developers/writing-onchain-code/index",title:"Introduction",description:"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/index.md",sourceDirName:"developers/writing-onchain-code",slug:"/writing-contracts",permalink:"/2.0.0/writing-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Introduction",slug:"/writing-contracts"},sidebar:"developers",previous:{title:"Essential Rust Crates",permalink:"/2.0.0/developers/essential-crates"},next:{title:"Getting Started with Rust",permalink:"/2.0.0/developers/writing-onchain-code/getting-started"}},a={},d=[{value:"Interacting with Contracts on the Blockchain",id:"interacting-with-contracts-on-the-blockchain",level:2},{value:"Tutorials",id:"tutorials",level:2}];function l(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",iframe:"iframe",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...n.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"writing-on-chain-code",children:"Writing On-Chain Code"})}),"\n",(0,r.jsxs)(e.p,{children:["This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The ",(0,r.jsx)(e.a,{href:"https://www.youtube.com/playlist?list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj",children:"Video Series for Writing On-Chain Code"})," accompanies the topics below."]}),"\n",(0,r.jsxs)(e.p,{align:"center",children:["\n",(0,r.jsx)(e.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/JoOjhSOnQzk",position:"middle",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),(0,r.jsx)(e.td,{children:"An introduction to using Rust with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/assembly-script",children:"Getting Started with AssemblyScript"})}),(0,r.jsx)(e.td,{children:"An introduction to using AssemblyScript with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),(0,r.jsx)(e.td,{children:"An example of a smart contract built in Rust"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Steps to test contract code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),(0,r.jsx)(e.td,{children:"An introduction to versioning smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/calling-contracts",children:"Calling Contracts"})}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),(0,r.jsx)(e.td,{children:"Understand what session code is and when you would use it over contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"})}),(0,r.jsx)(e.td,{children:"An introduction to writing session code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),(0,r.jsx)(e.td,{children:"Steps to test session code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/emitting-contract-events",children:"Contract-Level Events"})}),(0,r.jsx)(e.td,{children:"Enabling smart contracts to emit messages while executing on the blockchain"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash",children:"Using Contract Hash vs. Package Hash"})}),(0,r.jsxs)(e.td,{children:["Advantages and disadvantages of using ",(0,r.jsx)(e.code,{children:"contract_hash"})," vs. ",(0,r.jsx)(e.code,{children:"contract_package_hash"})," when calling a contract"]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern for Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Learn to implement the contract factory pattern on a Casper network"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})}),(0,r.jsx)(e.td,{children:"An outline of best practices when developing smart contracts on a Casper network"})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"interacting-with-contracts-on-the-blockchain",children:"Interacting with Contracts on the Blockchain"}),"\n",(0,r.jsxs)(e.p,{children:["Additionally, the section on ",(0,r.jsx)(e.a,{href:"/2.0.0/developers/cli/",children:"Interacting with the Blockchain"})," covers installing and calling contracts using the Casper command-line client written in Rust."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})}),(0,r.jsx)(e.td,{children:"A guide on installing smart contracts and querying global state"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(e.td,{children:"Steps to call a smart contract with the Rust command-line client"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})}),(0,r.jsx)(e.td,{children:"Information on Dictionaries and how to read and write to them on the Casper Platform."})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(e.td,{children:"Possible error codes when writing smart contracts."})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,r.jsx)(e.p,{children:"The following tutorials outline some aspects of writing smart contracts on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(e.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(e.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(e.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(e.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(e.td,{children:"Implement the Casper Fungible Token standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsx)(e.td,{children:"Learning how to return a value using contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(e.td,{children:"Retrieving and using the authorization keys associated with a transaction"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(e.td,{children:"How to handle tokens via a contract"})]})]})]})]})}function h(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,r.jsx)(e,{...n,children:(0,r.jsx)(l,{...n})}):l(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>c,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function c(n){const e=r.useContext(i);return r.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function o(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:c(n.components),r.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/4db682c6.25cb8a9e.js b/assets/js/4db682c6.25cb8a9e.js new file mode 100644 index 000000000..c6e6521ab --- /dev/null +++ b/assets/js/4db682c6.25cb8a9e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3766],{86243:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>r,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var c=n(74848),s=n(28453);const a={title:"Call Stacks"},i="Understanding Call Stacks",o={id:"concepts/callstack",title:"Call Stacks",description:"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.",source:"@site/docs/concepts/callstack.md",sourceDirName:"concepts",slug:"/concepts/callstack",permalink:"/concepts/callstack",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Call Stacks"},sidebar:"concepts",previous:{title:"Authorization Keys",permalink:"/concepts/list-auth-keys"},next:{title:"Dictionaries",permalink:"/concepts/dictionaries"}},r={},l=[{value:"The Caller",id:"the-caller",level:2},{value:"The Call Stack",id:"the-call-stack",level:2},{value:"Limitations",id:"limitations",level:2}];function h(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,s.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"understanding-call-stacks",children:"Understanding Call Stacks"})}),"\n",(0,c.jsxs)(e.p,{children:["Users wishing to interact with a Casper network must do so through ",(0,c.jsx)(e.a,{href:"/developers/cli/sending-transactions",children:"sending a transaction"}),". All transactions consist of ",(0,c.jsx)(e.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"session code"})," run in the context of the user account entity that sent the transaction. The session code may ",(0,c.jsx)(e.a,{href:"/developers/cli/installing-contracts",children:"install contract code to global state"}),", or interact with previously ",(0,c.jsx)(e.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"installed contract code"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["When the session code within a transaction interacts with one or more contracts, this is the beginning of a ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-types/latest/casper_types/system/enum.CallStackElement.html",children:(0,c.jsx)(e.code,{children:"Call Stack"})}),". A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code."]}),"\n",(0,c.jsx)(e.h2,{id:"the-caller",children:"The Caller"}),"\n",(0,c.jsxs)(e.p,{children:["In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in each call stack. The account that initiated the transaction can be retrieved with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_caller.html",children:"contract_api::runtime::get_caller"})," function."]}),"\n",(0,c.jsx)(e.h2,{id:"the-call-stack",children:"The Call Stack"}),"\n",(0,c.jsxs)(e.p,{children:["Developers can access the call stack with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_call_stack.html",children:"contract_api::runtime::get_call_stack"})," function."]}),"\n",(0,c.jsxs)(e.p,{children:["If session code calls a contract, which in turn calls another contract, then the session code would represent the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in the stack, the contract called by the initiating session code would be the ",(0,c.jsx)(e.em,{children:"first"})," and the contract called by the first contract would be the ",(0,c.jsx)(e.em,{children:"second"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["In this example, the first contract would be the ",(0,c.jsx)(e.code,{children:"immediate caller"})," of the second contract, meaning it interacted directly with it. The session code would remain the ",(0,c.jsx)(e.code,{children:"caller"}),"."]}),"\n",(0,c.jsx)(e.p,{children:(0,c.jsx)(e.img,{alt:"Call Stack",src:n(60939).A+"",width:"1024",height:"576"})}),"\n",(0,c.jsx)(e.h2,{id:"limitations",children:"Limitations"}),"\n",(0,c.jsxs)(e.p,{children:["Casper networks place a limitation on the maximum height of a call stack. This value can be set within the ",(0,c.jsx)(e.code,{children:"chainspec"})," for the network in question. For the Casper Mainnet, this limit is set at ",(0,c.jsx)(e.code,{children:"10"})," contracts. This does not include the initiating session code, which would still count as the ",(0,c.jsx)(e.em,{children:"zeroth"})," instance within the stack."]}),"\n",(0,c.jsx)(e.p,{children:"As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation."}),"\n",(0,c.jsx)(e.admonition,{type:"note",children:(0,c.jsx)(e.p,{children:"Contract code cannot call session code, only other contract code."})})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(h,{...t})}):h(t)}},60939:(t,e,n)=>{n.d(e,{A:()=>c});const c=n.p+"assets/images/callstack-b77837c35962b1314c65801ee56f8321.png"},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>o});var c=n(96540);const s={},a=c.createContext(s);function i(t){const e=c.useContext(a);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),c.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/4db682c6.c730ac08.js b/assets/js/4db682c6.c730ac08.js deleted file mode 100644 index b82bb6be0..000000000 --- a/assets/js/4db682c6.c730ac08.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3766],{86243:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>r,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var c=n(74848),s=n(28453);const a={title:"Call Stacks"},i="Understanding Call Stacks",o={id:"concepts/callstack",title:"Call Stacks",description:"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.",source:"@site/docs/concepts/callstack.md",sourceDirName:"concepts",slug:"/concepts/callstack",permalink:"/next/concepts/callstack",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Call Stacks"},sidebar:"concepts",previous:{title:"Authorization Keys",permalink:"/next/concepts/list-auth-keys"},next:{title:"Dictionaries",permalink:"/next/concepts/dictionaries"}},r={},l=[{value:"The Caller",id:"the-caller",level:2},{value:"The Call Stack",id:"the-call-stack",level:2},{value:"Limitations",id:"limitations",level:2}];function h(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,s.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"understanding-call-stacks",children:"Understanding Call Stacks"})}),"\n",(0,c.jsxs)(e.p,{children:["Users wishing to interact with a Casper network must do so through ",(0,c.jsx)(e.a,{href:"/next/developers/cli/sending-transactions",children:"sending a transaction"}),". All transactions consist of ",(0,c.jsx)(e.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"session code"})," run in the context of the user account entity that sent the transaction. The session code may ",(0,c.jsx)(e.a,{href:"/next/developers/cli/installing-contracts",children:"install contract code to global state"}),", or interact with previously ",(0,c.jsx)(e.a,{href:"/next/developers/writing-onchain-code/calling-contracts",children:"installed contract code"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["When the session code within a transaction interacts with one or more contracts, this is the beginning of a ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-types/latest/casper_types/system/enum.CallStackElement.html",children:(0,c.jsx)(e.code,{children:"Call Stack"})}),". A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code."]}),"\n",(0,c.jsx)(e.h2,{id:"the-caller",children:"The Caller"}),"\n",(0,c.jsxs)(e.p,{children:["In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in each call stack. The account that initiated the transaction can be retrieved with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_caller.html",children:"contract_api::runtime::get_caller"})," function."]}),"\n",(0,c.jsx)(e.h2,{id:"the-call-stack",children:"The Call Stack"}),"\n",(0,c.jsxs)(e.p,{children:["Developers can access the call stack with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_call_stack.html",children:"contract_api::runtime::get_call_stack"})," function."]}),"\n",(0,c.jsxs)(e.p,{children:["If session code calls a contract, which in turn calls another contract, then the session code would represent the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in the stack, the contract called by the initiating session code would be the ",(0,c.jsx)(e.em,{children:"first"})," and the contract called by the first contract would be the ",(0,c.jsx)(e.em,{children:"second"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["In this example, the first contract would be the ",(0,c.jsx)(e.code,{children:"immediate caller"})," of the second contract, meaning it interacted directly with it. The session code would remain the ",(0,c.jsx)(e.code,{children:"caller"}),"."]}),"\n",(0,c.jsx)(e.p,{children:(0,c.jsx)(e.img,{alt:"Call Stack",src:n(66121).A+"",width:"1024",height:"576"})}),"\n",(0,c.jsx)(e.h2,{id:"limitations",children:"Limitations"}),"\n",(0,c.jsxs)(e.p,{children:["Casper networks place a limitation on the maximum height of a call stack. This value can be set within the ",(0,c.jsx)(e.code,{children:"chainspec"})," for the network in question. For the Casper Mainnet, this limit is set at ",(0,c.jsx)(e.code,{children:"10"})," contracts. This does not include the initiating session code, which would still count as the ",(0,c.jsx)(e.em,{children:"zeroth"})," instance within the stack."]}),"\n",(0,c.jsx)(e.p,{children:"As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation."}),"\n",(0,c.jsx)(e.admonition,{type:"note",children:(0,c.jsx)(e.p,{children:"Contract code cannot call session code, only other contract code."})})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(h,{...t})}):h(t)}},66121:(t,e,n)=>{n.d(e,{A:()=>c});const c=n.p+"assets/images/callstack-b77837c35962b1314c65801ee56f8321.png"},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>o});var c=n(96540);const s={},a=c.createContext(s);function i(t){const e=c.useContext(a);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),c.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e015808.64ad3dfe.js b/assets/js/4e015808.64ad3dfe.js new file mode 100644 index 000000000..6ed25ea13 --- /dev/null +++ b/assets/js/4e015808.64ad3dfe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95712],{90710:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},l="Quickstart",c={id:"resources/quick-start",title:"Quickstart",description:"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.",source:"@site/versioned_docs/version-1.5.X/resources/quick-start.md",sourceDirName:"resources",slug:"/resources/quick-start",permalink:"/1.5.X/resources/quick-start",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",next:{title:"Overview",permalink:"/1.5.X/resources/tutorials/beginner/"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps",id:"steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsxs)(n.p,{children:["Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Consult the ",(0,t.jsx)(n.a,{href:"/writing-contracts",children:"complete documentation"})," for context and additional help."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"rustup --version"}),". Restart the shell if needed."]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://cmake.org/resources/",children:"cmake"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"cmake --version"}),".\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["On Ubuntu, you can follow ",(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"this guide"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["On MacOS, use this command: ",(0,t.jsx)(n.code,{children:"brew install cmake"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install ",(0,t.jsx)(n.code,{children:"cargo-casper"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["You have download ",(0,t.jsx)(n.a,{href:"https://git-scm.com/download/",children:"Git"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Install Cargo Casper with this command:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install cargo-casper"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper client"}),":"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install casper-client"})}),"\n",(0,t.jsx)(n.p,{children:"If you have issues installing the casper-client, you may need additional libraries."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On Ubuntu:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Make sure you also have the development packages of ",(0,t.jsx)(n.code,{children:"openssl"})," installed. For example, ",(0,t.jsx)(n.code,{children:"libssl-dev"})," on Ubuntu or ",(0,t.jsx)(n.code,{children:"openssl-devel"})," on Fedora."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Test the ",(0,t.jsx)(n.code,{children:"casper-client"})," by ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," on the network and getting the latest ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/S#state-root-hash",children:"state root hash"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://65.21.235.219:7777\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up a ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"Casper Account"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clone a simple counter contract or download it from GitHub:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/casper-ecosystem/counter"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the folder and prepare the dependencies to build the contract:"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd counter\nmake prepare\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsx)(n.li,{children:"Build the contract and tests:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make test"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Install the contract on Testnet using the ",(0,t.jsx)(n.code,{children:"casper-client"}),"'s ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name casper-test \\\n--secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \\\n--payment-amount 30000000000 \\\n--session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsx)(n.li,{children:"Check the deploy status given the deploy hash from the previous command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"Get the latest state root hash:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsx)(n.li,{children:"Open the deploy tab of the account on the Testnet to see the deploy details."}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"As an alternative to step 15, check your account using the command line:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["As another alternative, use the account hash for the ",(0,t.jsx)(n.code,{children:"--key"})," argument. To get the account hash, look at the account details on the block explorer, or run this command:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, query the blockchain using the account hash:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsx)(n.li,{children:'Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let\'s make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example output:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"17",children:["\n",(0,t.jsxs)(n.li,{children:["Now increment the count value by calling the entry point ",(0,t.jsx)(n.code,{children:"counter_inc"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [PATH_TO_YOUR_KEY] \\\n--payment-amount 100000000 \\\n--session-name "counter" \\\n--session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"18",children:["\n",(0,t.jsxs)(n.li,{children:["Get the NEW ",(0,t.jsx)(n.code,{children:"state root hash"}),", to get the latest snapshot of the blockchain state \u2013 this is EXTREMELY IMPORTANT!"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"19",children:["\n",(0,t.jsx)(n.li,{children:"Query the state of the network."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:'If everything went according to plan, the value should be 1. Look at the "parsed" value below.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 1\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e015808.a485ffdf.js b/assets/js/4e015808.a485ffdf.js deleted file mode 100644 index 1da6afa32..000000000 --- a/assets/js/4e015808.a485ffdf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5712],{90710:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},l="Quickstart",c={id:"resources/quick-start",title:"Quickstart",description:"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.",source:"@site/versioned_docs/version-1.5.X/resources/quick-start.md",sourceDirName:"resources",slug:"/resources/quick-start",permalink:"/resources/quick-start",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",next:{title:"Overview",permalink:"/resources/tutorials/beginner/"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps",id:"steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsxs)(n.p,{children:["Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Consult the ",(0,t.jsx)(n.a,{href:"/writing-contracts",children:"complete documentation"})," for context and additional help."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"rustup --version"}),". Restart the shell if needed."]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://cmake.org/resources/",children:"cmake"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"cmake --version"}),".\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["On Ubuntu, you can follow ",(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"this guide"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["On MacOS, use this command: ",(0,t.jsx)(n.code,{children:"brew install cmake"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install ",(0,t.jsx)(n.code,{children:"cargo-casper"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["You have download ",(0,t.jsx)(n.a,{href:"https://git-scm.com/download/",children:"Git"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Install Cargo Casper with this command:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install cargo-casper"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"}),":"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install casper-client"})}),"\n",(0,t.jsx)(n.p,{children:"If you have issues installing the casper-client, you may need additional libraries."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On Ubuntu:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Make sure you also have the development packages of ",(0,t.jsx)(n.code,{children:"openssl"})," installed. For example, ",(0,t.jsx)(n.code,{children:"libssl-dev"})," on Ubuntu or ",(0,t.jsx)(n.code,{children:"openssl-devel"})," on Fedora."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Test the ",(0,t.jsx)(n.code,{children:"casper-client"})," by ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," on the network and getting the latest ",(0,t.jsx)(n.a,{href:"/concepts/glossary/S#state-root-hash",children:"state root hash"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://65.21.235.219:7777\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Casper Account"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clone a simple counter contract or download it from GitHub:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/casper-ecosystem/counter"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the folder and prepare the dependencies to build the contract:"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd counter\nmake prepare\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsx)(n.li,{children:"Build the contract and tests:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make test"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Install the contract on Testnet using the ",(0,t.jsx)(n.code,{children:"casper-client"}),"'s ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name casper-test \\\n--secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \\\n--payment-amount 30000000000 \\\n--session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsx)(n.li,{children:"Check the deploy status given the deploy hash from the previous command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"Get the latest state root hash:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsx)(n.li,{children:"Open the deploy tab of the account on the Testnet to see the deploy details."}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"As an alternative to step 15, check your account using the command line:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["As another alternative, use the account hash for the ",(0,t.jsx)(n.code,{children:"--key"})," argument. To get the account hash, look at the account details on the block explorer, or run this command:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, query the blockchain using the account hash:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsx)(n.li,{children:'Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let\'s make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example output:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"17",children:["\n",(0,t.jsxs)(n.li,{children:["Now increment the count value by calling the entry point ",(0,t.jsx)(n.code,{children:"counter_inc"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [PATH_TO_YOUR_KEY] \\\n--payment-amount 100000000 \\\n--session-name "counter" \\\n--session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"18",children:["\n",(0,t.jsxs)(n.li,{children:["Get the NEW ",(0,t.jsx)(n.code,{children:"state root hash"}),", to get the latest snapshot of the blockchain state \u2013 this is EXTREMELY IMPORTANT!"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"19",children:["\n",(0,t.jsx)(n.li,{children:"Query the state of the network."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:'If everything went according to plan, the value should be 1. Look at the "parsed" value below.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 1\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e4df367.6b2bf3f2.js b/assets/js/4e4df367.6b2bf3f2.js new file mode 100644 index 000000000..b73b37bb9 --- /dev/null +++ b/assets/js/4e4df367.6b2bf3f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11894],{74299:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var i=t(74848),s=t(28453);const a={title:"Recovery"},o="Recovering from Validator Eviction",c={id:"operators/becoming-a-validator/recovering",title:"Recovery",description:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/recovering.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/recovering",permalink:"/1.5.X/operators/becoming-a-validator/recovering",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Recovery"},sidebar:"operators",previous:{title:"Unbonding",permalink:"/1.5.X/operators/becoming-a-validator/unbonding"},next:{title:"Inactive and Faulty Nodes",permalink:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty"}},r={},d=[{value:"Detecting the Eviction",id:"detecting-the-eviction",level:2},{value:"Detection using CSPR.live",id:"detection-using-csprlive",level:3},{value:"Detection using the Casper Client",id:"detection-using-the-casper-client",level:3},{value:"Correcting any Underlying Node Issues",id:"correcting-any-underlying-node-issues",level:2},{value:"Activating the Bid",id:"activating-the-bid",level:2},{value:"Method 1: Activating the Bid with the System Auction Contract",id:"activating-system-auction",level:3},{value:"Method 2: Activating the Bid with Compiled Wasm",id:"activating-compiled-wasm",level:3},{value:"Checking the Bid Activation",id:"checking-the-bid-activation",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"recovering-from-validator-eviction",children:"Recovering from Validator Eviction"})}),"\n",(0,i.jsx)(n.p,{children:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Detecting the eviction"}),"\n",(0,i.jsx)(n.li,{children:"Correcting any underlying node issues"}),"\n",(0,i.jsx)(n.li,{children:"Re-building the contracts for bonding"}),"\n",(0,i.jsx)(n.li,{children:"Activating the bid"}),"\n",(0,i.jsx)(n.li,{children:"Checking the bid"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," topic explains why a node would be evicted."]}),"\n",(0,i.jsx)(n.h2,{id:"detecting-the-eviction",children:"Detecting the Eviction"}),"\n",(0,i.jsx)(n.p,{children:"The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era."}),"\n",(0,i.jsx)(n.p,{children:"For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era."}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-csprlive",children:"Detection using CSPR.live"}),"\n",(0,i.jsxs)(n.p,{children:["If you were a previous validator and still exist on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators-auction",children:"Validators Auction"})," tab but not in ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"}),", you may have been evicted or outbid."]}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-the-casper-client",children:"Detection using the Casper Client"}),"\n",(0,i.jsxs)(n.p,{children:["All auction information is returned with the ",(0,i.jsx)(n.code,{children:"casper-client get-auction-info"})," command. It would help if you filtered this down to your public key."]}),"\n",(0,i.jsxs)(n.p,{children:["You can replace the ",(0,i.jsx)(n.code,{children:"public_key"})," with your public key manually and run this command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"<public_key>\")'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You know you were evicted if the ",(0,i.jsx)(n.code,{children:"get-auction-info"})," command returned your bid showing an ",(0,i.jsx)(n.strong,{children:"inactive"})," field. See the ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," page for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive a ",(0,i.jsx)(n.code,{children:"parse error: Invalid numeric literal at"}),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info\n"})}),"\n",(0,i.jsx)(n.h2,{id:"correcting-any-underlying-node-issues",children:"Correcting any Underlying Node Issues"}),"\n",(0,i.jsx)(n.p,{children:"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."}),"\n",(0,i.jsxs)(n.p,{children:["To check if your node is in sync, compare the current block height at ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," with the height from your node with:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl -s localhost:8888/status | jq .last_added_block_info\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you cannot figure out the issue, ask for help in the ",(0,i.jsx)(n.em,{children:"node-tech-support"})," channel on ",(0,i.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"activating-the-bid",children:"Activating the Bid"}),"\n",(0,i.jsxs)(n.p,{children:["Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. The second method involves building the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," contract as explained in ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,i.jsx)(n.h3,{id:"activating-system-auction",children:"Method 1: Activating the Bid with the System Auction Contract"}),"\n",(0,i.jsxs)(n.p,{children:["This method calls the existing ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:"]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Testnet"}),": ",(0,i.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mainnet"}),": ",(0,i.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,i.jsx)(n.code,{children:"activate_bid"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,i.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point on the auction contract has a fixed cost of 10,000 motes."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.p,{children:"This example uses the Casper Testnet to reactivate a bid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, ",(0,i.jsx)(n.a,{href:"#checking-the-bid-activation",children:"check the bid activation"})," status."]}),"\n",(0,i.jsx)(n.h3,{id:"activating-compiled-wasm",children:"Method 2: Activating the Bid with Compiled Wasm"}),"\n",(0,i.jsxs)(n.p,{children:["The second method to rejoin the network is to reactivate your bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["As described above, this method is much more expensive than calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example that reactivates a bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,i.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"}),". For example, if you use the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," on a network with node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml",children:"1.4.9"}),", you will require a balance of at least 5 CSPR for this contract."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Check that the deploy was successful with the ",(0,i.jsx)(n.code,{children:"casper-client get-deploy <deploy_hash>"})," or by searching for the deploy hash on ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),". Also, check the bid activation status as shown below."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-the-bid-activation",children:"Checking the Bid Activation"}),"\n",(0,i.jsxs)(n.p,{children:["Once your deploy processes, you can ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/recovering",children:"check your bid"})," again. You should now see ",(0,i.jsx)(n.code,{children:'"inactive": false'})," in the output."]}),"\n",(0,i.jsxs)(n.p,{children:["If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"})," tab."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e4df367.d91fcd1d.js b/assets/js/4e4df367.d91fcd1d.js deleted file mode 100644 index 87e84b0d4..000000000 --- a/assets/js/4e4df367.d91fcd1d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1894],{74299:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var i=t(74848),s=t(28453);const a={title:"Recovery"},o="Recovering from Validator Eviction",c={id:"operators/becoming-a-validator/recovering",title:"Recovery",description:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/recovering.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/recovering",permalink:"/operators/becoming-a-validator/recovering",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Recovery"},sidebar:"operators",previous:{title:"Unbonding",permalink:"/operators/becoming-a-validator/unbonding"},next:{title:"Inactive and Faulty Nodes",permalink:"/operators/becoming-a-validator/inactive-vs-faulty"}},r={},d=[{value:"Detecting the Eviction",id:"detecting-the-eviction",level:2},{value:"Detection using CSPR.live",id:"detection-using-csprlive",level:3},{value:"Detection using the Casper Client",id:"detection-using-the-casper-client",level:3},{value:"Correcting any Underlying Node Issues",id:"correcting-any-underlying-node-issues",level:2},{value:"Activating the Bid",id:"activating-the-bid",level:2},{value:"Method 1: Activating the Bid with the System Auction Contract",id:"activating-system-auction",level:3},{value:"Method 2: Activating the Bid with Compiled Wasm",id:"activating-compiled-wasm",level:3},{value:"Checking the Bid Activation",id:"checking-the-bid-activation",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"recovering-from-validator-eviction",children:"Recovering from Validator Eviction"})}),"\n",(0,i.jsx)(n.p,{children:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Detecting the eviction"}),"\n",(0,i.jsx)(n.li,{children:"Correcting any underlying node issues"}),"\n",(0,i.jsx)(n.li,{children:"Re-building the contracts for bonding"}),"\n",(0,i.jsx)(n.li,{children:"Activating the bid"}),"\n",(0,i.jsx)(n.li,{children:"Checking the bid"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," topic explains why a node would be evicted."]}),"\n",(0,i.jsx)(n.h2,{id:"detecting-the-eviction",children:"Detecting the Eviction"}),"\n",(0,i.jsx)(n.p,{children:"The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era."}),"\n",(0,i.jsx)(n.p,{children:"For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era."}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-csprlive",children:"Detection using CSPR.live"}),"\n",(0,i.jsxs)(n.p,{children:["If you were a previous validator and still exist on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators-auction",children:"Validators Auction"})," tab but not in ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"}),", you may have been evicted or outbid."]}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-the-casper-client",children:"Detection using the Casper Client"}),"\n",(0,i.jsxs)(n.p,{children:["All auction information is returned with the ",(0,i.jsx)(n.code,{children:"casper-client get-auction-info"})," command. It would help if you filtered this down to your public key."]}),"\n",(0,i.jsxs)(n.p,{children:["You can replace the ",(0,i.jsx)(n.code,{children:"public_key"})," with your public key manually and run this command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"<public_key>\")'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You know you were evicted if the ",(0,i.jsx)(n.code,{children:"get-auction-info"})," command returned your bid showing an ",(0,i.jsx)(n.strong,{children:"inactive"})," field. See the ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," page for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive a ",(0,i.jsx)(n.code,{children:"parse error: Invalid numeric literal at"}),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info\n"})}),"\n",(0,i.jsx)(n.h2,{id:"correcting-any-underlying-node-issues",children:"Correcting any Underlying Node Issues"}),"\n",(0,i.jsx)(n.p,{children:"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."}),"\n",(0,i.jsxs)(n.p,{children:["To check if your node is in sync, compare the current block height at ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," with the height from your node with:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl -s localhost:8888/status | jq .last_added_block_info\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you cannot figure out the issue, ask for help in the ",(0,i.jsx)(n.em,{children:"node-tech-support"})," channel on ",(0,i.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"activating-the-bid",children:"Activating the Bid"}),"\n",(0,i.jsxs)(n.p,{children:["Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. The second method involves building the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," contract as explained in ",(0,i.jsx)(n.a,{href:"/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,i.jsx)(n.h3,{id:"activating-system-auction",children:"Method 1: Activating the Bid with the System Auction Contract"}),"\n",(0,i.jsxs)(n.p,{children:["This method calls the existing ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:"]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Testnet"}),": ",(0,i.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mainnet"}),": ",(0,i.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,i.jsx)(n.code,{children:"activate_bid"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,i.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point on the auction contract has a fixed cost of 10,000 motes."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.p,{children:"This example uses the Casper Testnet to reactivate a bid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, ",(0,i.jsx)(n.a,{href:"#checking-the-bid-activation",children:"check the bid activation"})," status."]}),"\n",(0,i.jsx)(n.h3,{id:"activating-compiled-wasm",children:"Method 2: Activating the Bid with Compiled Wasm"}),"\n",(0,i.jsxs)(n.p,{children:["The second method to rejoin the network is to reactivate your bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["As described above, this method is much more expensive than calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example that reactivates a bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,i.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),". For example, if you use the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," on a network with node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml",children:"1.4.9"}),", you will require a balance of at least 5 CSPR for this contract."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Check that the deploy was successful with the ",(0,i.jsx)(n.code,{children:"casper-client get-deploy <deploy_hash>"})," or by searching for the deploy hash on ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),". Also, check the bid activation status as shown below."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-the-bid-activation",children:"Checking the Bid Activation"}),"\n",(0,i.jsxs)(n.p,{children:["Once your deploy processes, you can ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering",children:"check your bid"})," again. You should now see ",(0,i.jsx)(n.code,{children:'"inactive": false'})," in the output."]}),"\n",(0,i.jsxs)(n.p,{children:["If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"})," tab."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e8b7bcc.034fae29.js b/assets/js/4e8b7bcc.034fae29.js deleted file mode 100644 index 318b1e447..000000000 --- a/assets/js/4e8b7bcc.034fae29.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3469],{28010:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var r=n(74848),c=n(28453);const t={},o="F",a={id:"concepts/glossary/F",title:"F",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/F.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/F",permalink:"/concepts/glossary/F",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"E",permalink:"/concepts/glossary/E"},next:{title:"G",permalink:"/concepts/glossary/G"}},l={},i=[{value:"Finality",id:"finality",level:2},{value:"Fungible",id:"fungible",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"f",children:"F"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"finality",children:"Finality"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B#block-finality",children:"block finality"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"fungible",children:"Fungible"}),"\n",(0,r.jsxs)(s.p,{children:["A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N#non-fungible-token",children:"non-fungible token"}),", where each token is unique and not interchangeable."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4e8b7bcc.d320f421.js b/assets/js/4e8b7bcc.d320f421.js new file mode 100644 index 000000000..5becc19a4 --- /dev/null +++ b/assets/js/4e8b7bcc.d320f421.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93469],{28010:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var r=n(74848),c=n(28453);const t={},o="F",a={id:"concepts/glossary/F",title:"F",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/F.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/F",permalink:"/1.5.X/concepts/glossary/F",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"E",permalink:"/1.5.X/concepts/glossary/E"},next:{title:"G",permalink:"/1.5.X/concepts/glossary/G"}},l={},i=[{value:"Finality",id:"finality",level:2},{value:"Fungible",id:"fungible",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"f",children:"F"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"finality",children:"Finality"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block-finality",children:"block finality"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"fungible",children:"Fungible"}),"\n",(0,r.jsxs)(s.p,{children:["A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N#non-fungible-token",children:"non-fungible token"}),", where each token is unique and not interchangeable."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4ed7ac06.e7cc3604.js b/assets/js/4ed7ac06.e7cc3604.js new file mode 100644 index 000000000..d9579efba --- /dev/null +++ b/assets/js/4ed7ac06.e7cc3604.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82399],{49208:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var n=r(74848),a=r(28453);const o={},t="R",c={id:"concepts/glossary/R",title:"R",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/R.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/R",permalink:"/2.0.0/concepts/glossary/R",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Q",permalink:"/2.0.0/concepts/glossary/Q"},next:{title:"S",permalink:"/2.0.0/concepts/glossary/S"}},l={},i=[{value:"Reward",id:"reward",level:2},{value:"Root hash",id:"root-hash",level:2},{value:"Rust",id:"rust",level:2},{value:"Rustdocs",id:"rustdocs",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"r",children:"R"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"reward",children:"Reward"}),"\n",(0,n.jsxs)(s.p,{children:["Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D#delegation-rate",children:"delegation rate"}),". Rewards are distributed at the end of each era."]}),"\n",(0,n.jsx)(s.h2,{id:"root-hash",children:"Root hash"}),"\n",(0,n.jsxs)(s.p,{children:["The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M#merkle-tree",children:"Merkle tree"})," if you wish to learn more."]}),"\n",(0,n.jsx)(s.h2,{id:"rust",children:"Rust"}),"\n",(0,n.jsx)(s.p,{children:"A programming language similar to C++, designed for performance and safety, especially safe concurrency."}),"\n",(0,n.jsx)(s.h2,{id:"rustdocs",children:"Rustdocs"}),"\n",(0,n.jsxs)(s.p,{children:["As part of the Rust development environment, the Rustdocs describe the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-contract/",children:"Casper contracts library"}),", the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-types/",children:"Casper types library"}),", and the ",(0,n.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"Casper test support library"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>c});var n=r(96540);const a={},o=n.createContext(a);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4fdb6df3.2cd2adde.js b/assets/js/4fdb6df3.2cd2adde.js deleted file mode 100644 index 7f521cffb..000000000 --- a/assets/js/4fdb6df3.2cd2adde.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5844],{15366:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var t=s(74848),r=s(28453);const o={},a="N",c={id:"concepts/glossary/N",title:"N",description:"---",source:"@site/docs/concepts/glossary/N.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/N",permalink:"/next/concepts/glossary/N",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"M",permalink:"/next/concepts/glossary/M"},next:{title:"O",permalink:"/next/concepts/glossary/O"}},i={},l=[{value:"NamedKeys",id:"named-keys",level:2},{value:"Node",id:"node",level:2},{value:"Node operator",id:"node-operator",level:2},{value:"Non-Fungible Token (NFT)",id:"non-fungible-token",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"n",children:"N"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),"\nare a collection of String-Key pairs used to easily identify some data on the network."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"node",children:"Node"}),"\n",(0,t.jsx)(n.p,{children:"A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data."}),"\n",(0,t.jsx)(n.p,{children:"You will encounter different types of nodes on the network:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Bonded node"}),": a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Unbonded node"}),": a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization)."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"node-operator",children:"Node operator"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O#operator",children:"operator"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"non-fungible-token",children:"Non-Fungible Token (NFT)"}),"\n",(0,t.jsx)(n.p,{children:"Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions."})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4fdb6df3.3ae7fba2.js b/assets/js/4fdb6df3.3ae7fba2.js new file mode 100644 index 000000000..9ee3f4987 --- /dev/null +++ b/assets/js/4fdb6df3.3ae7fba2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55844],{15366:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var r=n(74848),t=n(28453);const o={},a="N",c={id:"concepts/glossary/N",title:"N",description:"---",source:"@site/docs/concepts/glossary/N.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/N",permalink:"/concepts/glossary/N",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"M",permalink:"/concepts/glossary/M"},next:{title:"O",permalink:"/concepts/glossary/O"}},i={},l=[{value:"NamedKeys",id:"named-keys",level:2},{value:"Node",id:"node",level:2},{value:"Node operator",id:"node-operator",level:2},{value:"Non-Fungible Token (NFT)",id:"non-fungible-token",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"n",children:"N"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),"\nare a collection of String-Key pairs used to easily identify some data on the network."]}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(s.li,{children:["The ",(0,r.jsx)(s.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node",children:"Node"}),"\n",(0,r.jsx)(s.p,{children:"A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data."}),"\n",(0,r.jsx)(s.p,{children:"You will encounter different types of nodes on the network:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Bonded node"}),": a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era."]}),"\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.strong,{children:"Unbonded node"}),": a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization)."]}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"node-operator",children:"Node operator"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O#operator",children:"operator"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"non-fungible-token",children:"Non-Fungible Token (NFT)"}),"\n",(0,r.jsx)(s.p,{children:"Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions."})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const t={},o=r.createContext(t);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5052751d.2ecba4e7.js b/assets/js/5052751d.2ecba4e7.js new file mode 100644 index 000000000..a4a37e632 --- /dev/null +++ b/assets/js/5052751d.2ecba4e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96590],{9184:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>r});var t=a(74848),s=a(28453);const i={title:"Bonding"},d="Bonding as a Validator",o={id:"operators/becoming-a-validator/bonding",title:"Bonding",description:"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/bonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/bonding",permalink:"/1.5.X/operators/becoming-a-validator/bonding",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Bonding"},sidebar:"operators",previous:{title:"Becoming a Validator",permalink:"/1.5.X/operators/becoming-a-validator/"},next:{title:"Unbonding",permalink:"/1.5.X/operators/becoming-a-validator/unbonding"}},c={},r=[{value:"Method 1: Bonding with the System Auction Contract",id:"bonding-system-auction",level:2},{value:"Method 2: Bonding with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Checking the Bid Status",id:"check-the-status-of-the-bid-in-the-auction",level:2},{value:"A Losing Bid",id:"losing-bid",level:2},{value:"Avoiding Ejection",id:"avoiding-ejection",level:2},{value:"Withdrawing a Bid",id:"withdrawing-a-bid",level:2}];function h(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bonding-as-a-validator",children:"Bonding as a Validator"})}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," contract. The auction runs for a future era, every era. The ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era."]}),"\n",(0,t.jsxs)(n.p,{children:["In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, ",(0,t.jsx)(n.strong,{children:"the time for bid submission to inclusion in the validator set is a minimum of six hours"}),". Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-system-auction",children:"Method 1: Bonding with the System Auction Contract"}),"\n",(0,t.jsxs)(n.p,{children:["This method submits a bid using the system auction contract. Call the existing ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point add_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<BID_AMOUNT>'\" \\\n--session-arg=\"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.p,{children:"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"#check-the-status-of-the-bid-in-the-auction",children:"check the status of the auction"})," to see if you have won a validator slot."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Bonding with Compiled Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". For details, refer to ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following deploy is a template for sending a bonding request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<BID-AMOUNT>'\" \\\n--session-arg=\"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public_key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example request to bond using the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Next, check the bid status to see if you have won a validator slot."}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status-of-the-bid-in-the-auction",children:"Checking the Bid Status"}),"\n",(0,t.jsxs)(n.p,{children:["Since the bid was submitted using a deploy like any other, perform ",(0,t.jsx)(n.code,{children:"get-deploy"})," using the ",(0,t.jsx)(n.code,{children:"casper-client"}),", to see the execution status."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example auction info response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Note the ",(0,t.jsx)(n.code,{children:"era_id"})," and the ",(0,t.jsx)(n.code,{children:"validator_weights"})," in the response above. The current era is the one with the lowest ID in the ",(0,t.jsx)(n.code,{children:"era_validators"})," array. For a given ",(0,t.jsx)(n.code,{children:"era_id"}),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,t.jsx)(n.code,{children:"validator_weights"})," structure for an era, then the account is bonded in that era."]}),"\n",(0,t.jsx)(n.h2,{id:"losing-bid",children:"A Losing Bid"}),"\n",(0,t.jsx)(n.p,{children:"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-ejection",children:"Avoiding Ejection"}),"\n",(0,t.jsxs)(n.p,{children:["To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/recovering",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"withdrawing-a-bid",children:"Withdrawing a Bid"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the steps in ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/unbonding",children:"Unbonding"})," to withdraw a bid."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>o});var t=a(96540);const s={},i=t.createContext(s);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5052751d.e6a325fc.js b/assets/js/5052751d.e6a325fc.js deleted file mode 100644 index a4721601c..000000000 --- a/assets/js/5052751d.e6a325fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6590],{9184:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>r});var t=a(74848),s=a(28453);const i={title:"Bonding"},d="Bonding as a Validator",o={id:"operators/becoming-a-validator/bonding",title:"Bonding",description:"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/bonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/bonding",permalink:"/operators/becoming-a-validator/bonding",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Bonding"},sidebar:"operators",previous:{title:"Becoming a Validator",permalink:"/operators/becoming-a-validator/"},next:{title:"Unbonding",permalink:"/operators/becoming-a-validator/unbonding"}},c={},r=[{value:"Method 1: Bonding with the System Auction Contract",id:"bonding-system-auction",level:2},{value:"Method 2: Bonding with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Checking the Bid Status",id:"check-the-status-of-the-bid-in-the-auction",level:2},{value:"A Losing Bid",id:"losing-bid",level:2},{value:"Avoiding Ejection",id:"avoiding-ejection",level:2},{value:"Withdrawing a Bid",id:"withdrawing-a-bid",level:2}];function h(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bonding-as-a-validator",children:"Bonding as a Validator"})}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," contract. The auction runs for a future era, every era. The ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era."]}),"\n",(0,t.jsxs)(n.p,{children:["In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, ",(0,t.jsx)(n.strong,{children:"the time for bid submission to inclusion in the validator set is a minimum of six hours"}),". Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-system-auction",children:"Method 1: Bonding with the System Auction Contract"}),"\n",(0,t.jsxs)(n.p,{children:["This method submits a bid using the system auction contract. Call the existing ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point add_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<BID_AMOUNT>'\" \\\n--session-arg=\"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.p,{children:"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"#check-the-status-of-the-bid-in-the-auction",children:"check the status of the auction"})," to see if you have won a validator slot."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Bonding with Compiled Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". For details, refer to ",(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following deploy is a template for sending a bonding request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<BID-AMOUNT>'\" \\\n--session-arg=\"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public_key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example request to bond using the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg=\"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Next, check the bid status to see if you have won a validator slot."}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status-of-the-bid-in-the-auction",children:"Checking the Bid Status"}),"\n",(0,t.jsxs)(n.p,{children:["Since the bid was submitted using a deploy like any other, perform ",(0,t.jsx)(n.code,{children:"get-deploy"})," using the ",(0,t.jsx)(n.code,{children:"casper-client"}),", to see the execution status."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example auction info response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Note the ",(0,t.jsx)(n.code,{children:"era_id"})," and the ",(0,t.jsx)(n.code,{children:"validator_weights"})," in the response above. The current era is the one with the lowest ID in the ",(0,t.jsx)(n.code,{children:"era_validators"})," array. For a given ",(0,t.jsx)(n.code,{children:"era_id"}),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,t.jsx)(n.code,{children:"validator_weights"})," structure for an era, then the account is bonded in that era."]}),"\n",(0,t.jsx)(n.h2,{id:"losing-bid",children:"A Losing Bid"}),"\n",(0,t.jsx)(n.p,{children:"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-ejection",children:"Avoiding Ejection"}),"\n",(0,t.jsxs)(n.p,{children:["To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"withdrawing-a-bid",children:"Withdrawing a Bid"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the steps in ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"Unbonding"})," to withdraw a bid."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>o});var t=a(96540);const s={},i=t.createContext(s);function d(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/50c21d96.c39e8686.js b/assets/js/50c21d96.c39e8686.js new file mode 100644 index 000000000..8e5400a03 --- /dev/null +++ b/assets/js/50c21d96.c39e8686.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40145],{13358:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="X",a={id:"concepts/glossary/X",title:"X",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/X.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/X",permalink:"/2.0.0/concepts/glossary/X",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"W",permalink:"/2.0.0/concepts/glossary/W"},next:{title:"Y",permalink:"/2.0.0/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"x",children:"X"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/5109d3ad.4be6508a.js b/assets/js/5109d3ad.4be6508a.js new file mode 100644 index 000000000..17b0e33fe --- /dev/null +++ b/assets/js/5109d3ad.4be6508a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6224],{1222:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"Private Network Setup"},r="Setting Up a Private Casper Network",o={id:"operators/setup-network/create-private",title:"Private Network Setup",description:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/create-private.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/create-private",permalink:"/1.5.X/operators/setup-network/create-private",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Private Network Setup"},sidebar:"operators",previous:{title:"The Chainspec",permalink:"/1.5.X/operators/setup-network/chain-spec"},next:{title:"Staging Files",permalink:"/1.5.X/operators/setup-network/staging-files-for-new-network"}},c={},d=[{value:"Contents",id:"contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1. Setting up a Validator Node",id:"step-1-setting-up-a-validator-node",level:2},{value:"Step 2. Setting up the Directory",id:"step-2-setting-up-the-directory",level:2},{value:"Step 3. Configuring the Genesis Block",id:"step-3-configuring-the-genesis-block",level:2},{value:"Unrestricted transfers configuration",id:"unrestricted-transfers-configuration",level:3},{value:"Refund handling configuration",id:"refund-handling-configuration",level:3},{value:"Fee handling configuration",id:"fee-handling-configuration",level:3},{value:"Auction behavior configuration",id:"auction-behavior-configuration",level:3},{value:"Step 4. Configuring the Administrator Accounts",id:"step-4-configuring-the-administrator-accounts",level:2},{value:"Configuring administrator accounts",id:"configuring-administrator-accounts",level:3},{value:"Generating new administrator accounts",id:"generating-new-administrator-accounts",level:3},{value:"Managing accounts and smart contracts",id:"managing-accounts-and-smart-contracts",level:3},{value:"Step 5. Starting the Casper Node",id:"step-5-starting-the-casper-node",level:2},{value:"Step 6. Rotating the Validator Accounts",id:"step-6-rotating-the-validator-accounts",level:2},{value:"Step 7. Testing the Private Network",id:"step-7-testing-the-private-network",level:2},{value:"Sample configuration files",id:"sample-configuration-files",level:3},{value:"Specifying IP addresses",id:"specifying-ip-addresses",level:3},{value:"Setting up the node",id:"setting-up-the-node",level:3},{value:"Network access control",id:"network-access-control",level:3},{value:"Funding Alice's account",id:"funding-alices-account",level:3},{value:"Adding a bid as Alice",id:"adding-a-bid-as-alice",level:3},{value:"Disabling Alice's account",id:"disabling-alices-account",level:3},{value:"Enabling Alice's account",id:"enabling-alices-account",level:3},{value:"Enabling a contract",id:"enabling-a-contract",level:3},{value:"Disabling a contract",id:"disabling-a-contract",level:3},{value:"Verifying seigniorage allocations",id:"verifying-seigniorage-allocations",level:3},{value:"Operating guide",id:"operating-guide",level:3},{value:"Rotating validators",id:"rotating-validators",level:3},{value:"Adding new administrators",id:"adding-new-administrators",level:3},{value:"Setting up a Block Explorer",id:"setting-up-a-block-explorer",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"setting-up-a-private-casper-network",children:"Setting Up a Private Casper Network"})}),"\n",(0,a.jsx)(n.p,{children:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network."}),"\n",(0,a.jsx)(n.h2,{id:"contents",children:"Contents"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"Setting up a Validator Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-2-setting-up-the-directory",children:"Setting up the Directory"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-3-configuring-the-genesis-block",children:"Configuring the Genesis Block"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-4-configuring-the-administrator-accounts",children:"Configuring the Administrator Accounts"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-5-starting-the-casper-node",children:"Starting the Casper Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-7-testing-the-private-network",children:"Testing the Private Network"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#setting-up-a-block-explorer",children:"Setting up a Block Explorer"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Follow these guides to set up the required environment and user accounts."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Setting up the Casper client"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/blob/dev/README.md#casper-client",children:"Setting up the client for interacting with the network"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"Setting up an Account"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-1-setting-up-a-validator-node",children:"Step 1. Setting up a Validator Node"}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/N#node",children:"Casper node"})," is a physical or virtual device participating in a Casper network. You need to set up several ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validator"})," nodes on your private network. An ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/O#operator",children:"operator"})," who has won an ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/A#auction",children:"auction"})," bid will be a validator for the private network."]}),"\n",(0,a.jsx)(n.p,{children:"Use the below guides to set up and manage validator nodes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup - GitHub guide"}),": A guide to configuring a system with the new Rust node to operate within a network."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration",children:"Basic node setup tutorial"}),": A guide on using the ",(0,a.jsx)(n.code,{children:"casper-node-launcher"}),", generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://docs.cspr.community/",children:"Set up Mainnet and Testnet validator nodes"}),": A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use these FAQ collections for tips and details for validators."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-2-setting-up-the-directory",children:"Step 2. Setting up the Directory"}),"\n",(0,a.jsx)(n.p,{children:"Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Go through the ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#file-locations",children:"file location"})," section to understand how directories are created and managed in a Casper private network."]}),"\n",(0,a.jsxs)(n.li,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup-network/chain-spec",children:"setting up a new network"})," guide to identify the required configuration files to set up a genesis block."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-3-configuring-the-genesis-block",children:"Step 3. Configuring the Genesis Block"}),"\n",(0,a.jsxs)(n.p,{children:["A Casper private network contains a different set of configurations when compared to the public network. The ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:(0,a.jsx)(n.code,{children:"chainspec.toml"})})," file contains the required configurations for the genesis process in a private network."]}),"\n",(0,a.jsxs)(n.p,{children:["You should add the configuration options below to the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file inside the ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup-network/create-private#step-2-setting-up-the-directory",children:"private network directory"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"unrestricted-transfers-configuration",children:"Unrestricted transfers configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"In contrast, users in the public network can freely transfer funds to different accounts."}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nallow_unrestricted_transfers = false\ncompute_rewards = false\nallow_auction_bids = false\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\nfee_handling = { type = "accumulate" }\nadministrators = ["ADMIN_PUBLIC_KEY"]\n'})})]}),"\n",(0,a.jsx)(n.h3,{id:"refund-handling-configuration",children:"Refund handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user."}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After deducting the gas fee, the distribution of the remaining payment amount is handled based on the ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup-network/create-private",children:"fee_handling"})," configuration."]}),"\n",(0,a.jsx)(n.p,{children:"The default configuration for a public chain, including the Casper Mainet, looks like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [0, 100] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The refund variant with ",(0,a.jsx)(n.code,{children:"refund_ratio"})," of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return."]}),"\n",(0,a.jsx)(n.h3,{id:"fee-handling-configuration",children:"Fee handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed."}),"\n",(0,a.jsx)(n.p,{children:"Set up the configuration as below:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nfee_handling = { type = "pay_to_proposer" }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"fee_handling"})," configuration has three variations:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"pay_to_proposer"}),": The rest of the payment amount after deducing the gas fee from a refund is paid to the block's ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/P#proposer",children:"proposer"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"burn"}),": The tokens paid are burned, and the total supply is reduced."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"accumulate"}),": The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"auction-behavior-configuration",children:"Auction behavior configuration"}),"\n",(0,a.jsx)(n.p,{children:"A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set."}),"\n",(0,a.jsx)(n.p,{children:"Use the configuration below to limit the auction validators:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_auction_bids = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Other configurations related to the auction:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"allow_auction_bids"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"})," then ",(0,a.jsx)(n.code,{children:"add_bid"})," and ",(0,a.jsx)(n.code,{children:"delegate"})," options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an ",(0,a.jsx)(n.code,{children:"AuctionBidsDisabled"})," error."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"core.compute_rewards"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"}),", then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In a public network, ",(0,a.jsx)(n.code,{children:"allow_auction_bid"})," is set to ",(0,a.jsx)(n.em,{children:"true"}),", which allows bidding for new entries and validator nodes."]}),"\n",(0,a.jsx)(n.h2,{id:"step-4-configuring-the-administrator-accounts",children:"Step 4. Configuring the Administrator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["An administrator is mandatory for a private network since it manages all the other ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validator"})," accounts. There should be at least one administrator account configured within a network to operate it as a ",(0,a.jsx)(n.code,{children:"private network"}),". You can create new administrators and ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup-network/create-private#step-6-rotating-the-validator-accounts",children:"rotate the validator set"})," in a single configuration update. The operator must first ensure the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances."]}),"\n",(0,a.jsx)(n.h3,{id:"configuring-administrator-accounts",children:"Configuring administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use this configuration option in the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," to add administrator accounts to the private network:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_ACCOUNT_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note"}),": Regular accounts are not allowed to manage their associated keys on a private network."]}),"\n",(0,a.jsx)(n.h3,{id:"generating-new-administrator-accounts",children:"Generating new administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use the command below to generate new administrator accounts in your private network. This generates the contents of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the entries required to create new administrator accounts at the upgrade point."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen \\\n generate-admins --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n --admin $PUBLIC_KEY_HEX, $BALANCE\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_PUBLIC_KEY"})," - Public key of the administrator in a hex format."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_BALANCE"})," - Balance for the administrator\u2019s main purse."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"DATA_DIR"})," - Path to the global state directory."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"STATE_ROOT_HASH"})," - State root hash, taken from the latest block before an upgrade."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"managing-accounts-and-smart-contracts",children:"Managing accounts and smart contracts"}),"\n",(0,a.jsxs)(n.p,{children:["Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/c8023736786b2c2b0fd17250fcfd50502ff4151f/smart_contracts/contracts/private_chain/control-management/src/main.rs",children:"Casper node's private chain control management"})," file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key."]}),"\n",(0,a.jsx)(n.p,{children:"Use this command to generate these contracts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"make build-contracts-rs\n"})}),"\n",(0,a.jsx)(n.p,{children:"Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"disable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"enable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with argument ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='255'"})," and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='255'"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='1'"})," set to 1 and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='0'"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-5-starting-the-casper-node",children:"Step 5. Starting the Casper Node"}),"\n",(0,a.jsx)(n.p,{children:"After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup GitHub"})," guide to know more details about configuring a new node to operate within a network."]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally, refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"casper-node-launcher"})," to check whether the installed node binaries match the installed configurations by comparing the version numbers."]}),"\n",(0,a.jsx)(n.h2,{id:"step-6-rotating-the-validator-accounts",children:"Step 6. Rotating the Validator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["You need to go through ",(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"setting up a validator node "})," guide before starting this section."]}),"\n",(0,a.jsxs)(n.p,{children:["To rotate the validators set, you must perform a network upgrade using a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.p,{children:"When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block."}),"\n",(0,a.jsxs)(n.p,{children:["After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"\nglobal-state-update-gen validators \\\n --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE\n\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Each use of the ",(0,a.jsx)(n.code,{children:"--validator"})," parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter."]}),"\n",(0,a.jsxs)(n.p,{children:["After designating the next era's validators, you must set the chainspec activation point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to ",(0,a.jsx)(n.code,{children:"X"}),", where ",(0,a.jsx)(n.code,{children:"X"})," is equal to the new era after the switch block from above. Finally, set ",(0,a.jsx)(n.code,{children:"hard_reset = true"}),". This makes the network revert to the end of the previous era when restarted with the upgrade."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),", set the activaction point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to 10 and ",(0,a.jsx)(n.code,{children:"hard_reset"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Please make sure you are running this tool as the same user that owns ",(0,a.jsx)(n.code,{children:"$DATA_DIR"}),". Otherwise, you may receive a permission denied error."]})}),"\n",(0,a.jsxs)(n.p,{children:["You can find more details on enabling new validators in the ",(0,a.jsx)(n.a,{href:"/1.5.X/operators/setup/joining",children:"joining a running network"})," guide. The guide explains how to join the network and provide additional security to the system."]}),"\n",(0,a.jsx)(n.h2,{id:"step-7-testing-the-private-network",children:"Step 7. Testing the Private Network"}),"\n",(0,a.jsx)(n.p,{children:"We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer."}),"\n",(0,a.jsx)(n.h3,{id:"sample-configuration-files",children:"Sample configuration files"}),"\n",(0,a.jsx)(n.p,{children:"Here are sample configurations that can be adapted for testing:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["A ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/chainspec.toml.in",children:"chainspec template"})," that is specific to the customer's private chain."]}),"\n",(0,a.jsxs)(n.li,{children:["An ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/accounts.toml.in",children:"accounts template"})," with one administrator in the ",(0,a.jsx)(n.code,{children:"administrators"})," settings."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"specifying-ip-addresses",children:"Specifying IP addresses"}),"\n",(0,a.jsx)(n.p,{children:"Here is an example set of IP addresses in use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"http://18.224.190.213:7777\nhttp://18.188.11.97:7777\nhttp://18.188.206.170:7777\nhttp://18.116.201.114:7777\n"})}),"\n",(0,a.jsx)(n.h3,{id:"setting-up-the-node",children:"Setting up the node"}),"\n",(0,a.jsx)(n.p,{children:"Set up the node address, chain name, and the administrator's secret key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'export NODE_ADDR=http://18.224.190.213:7777\nexport CHAIN_NAME="private-test"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This testing example will also use an ",(0,a.jsx)(n.code,{children:"alice/secret_key.pem"})," file, a secret key generated through the ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys#creating-accounts-and-keys",children:"keys generation process"}),". Alice is a regular user in this testing example."]}),"\n",(0,a.jsx)(n.h3,{id:"network-access-control",children:"Network access control"}),"\n",(0,a.jsx)(n.p,{children:"With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed."}),"\n",(0,a.jsx)(n.p,{children:"To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "local_node_cert.pem"\nsecret_key = "local_node.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"tls_certificate"})," is the certificate signed by a ",(0,a.jsx)(n.code,{children:"ca_cert.pem"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secret_key"})," refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ca_certificate"})," is the network CA that should be the same on each of the nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'# Recommended EC curve algorithm to use\nexport CURVE="secp521r1"\n\n# Generate secret key for CA and save it to ca_key.pem\nopenssl ecparam -out ca_key.pem -name $CURVE -genkey\n# Create ca_cert.pem signed by ca_key.pem\nopenssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem\n\n# Generate secret key for a node and a certificate signed by the CA\nopenssl ecparam -out node_1.pem -name $CURVE -genkey\nopenssl req -new -key node_1.pem -out node_1.csr -sha256\nopenssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem\n'})}),"\n",(0,a.jsx)(n.p,{children:"And then configure the node with the following settings:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "node_1_cert.pem"\nsecret_key = "node_1.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Every node in the private chain network has to be configured with the same CA certificate, and each ",(0,a.jsx)(n.code,{children:"tls_certificate"})," and ",(0,a.jsx)(n.code,{children:"secret_key"})," pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Keep in mind that for security reasons ",(0,a.jsx)(n.code,{children:"ca_key.pem"})," should be stored securely and never present on each of participating machines."]}),"\n",(0,a.jsx)(n.h3,{id:"funding-alices-account",children:"Funding Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command transfers tokens to Alice's main purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n transfer \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<admin/public_key_hex) \\\n --target-account=$(<alice/public_key_hex) \\\n --amount=100000000000 \\\n --payment-amount=3000000000 \\\n --transfer-id=123\n"})}),"\n",(0,a.jsx)(n.p,{children:"To check the account information, use this command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-account-info -n $NODE_ADDR\n --public-key alice/public_key.pem\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-a-bid-as-alice",children:"Adding a bid as Alice"}),"\n",(0,a.jsxs)(n.p,{children:["The following command attempts to add an auction bid on the network. It should return ",(0,a.jsx)(n.code,{children:"ApiError::AuctionError(AuctionBidsDisabled) [64559]"}),"."]}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["All payment amounts in these examples must be adjusted based on the network ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key alice/secret_key.pem \\\n --session-path add_bid.wasm \\\n --payment-amount 5000000000 \\\n --session-arg "public_key:public_key=\'$(<alice/public_key_hex)\'" \\\n --session-arg "amount:u512=\'10000\'" \\\n --session-arg "delegation_rate:u8=\'5\'"\n\n# Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"\n'})}),"\n",(0,a.jsx)(n.p,{children:"We should get a similar error for the delegate entry point."}),"\n",(0,a.jsx)(n.h3,{id:"disabling-alices-account",children:"Disabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='255'\" \\\n --session-arg \"deploy_threshold:u8='255'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-alices-account",children:"Enabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='0'\" \\\n --session-arg \"deploy_threshold:u8='1'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-a-contract",children:"Enabling a contract"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables a contract using its hash."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path enable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"disabling-a-contract",children:"Disabling a contract"}),"\n",(0,a.jsxs)(n.p,{children:["The following command disables a contract using its hash. Executing this contract using ",(0,a.jsx)(n.code,{children:"CONTRACT_HASH"})," again should fail."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path disable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:"Alice needs a container access key for the contract package in her named keys."}),"\n",(0,a.jsx)(n.h3,{id:"verifying-seigniorage-allocations",children:"Verifying seigniorage allocations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://www.investopedia.com/terms/s/seigniorage.asp",children:"Seigniorage"})," allocations should be zero at each switch block. This is the related configuration:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\ncompute_rewards = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Validator stakes should not increase on each switch block. Run this command to verify this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-era-info -n $NODE_ADDR -b 153\n"})}),"\n",(0,a.jsx)(n.p,{children:"The total supply shouldn't increase, and the validator's stakes should remain the same."}),"\n",(0,a.jsx)(n.h3,{id:"operating-guide",children:"Operating guide"}),"\n",(0,a.jsxs)(n.p,{children:["Some configuration options such as ",(0,a.jsx)(n.code,{children:"allow_auction_bids"})," require a private chain operator to perform specific tasks manually through a network upgrade with chainspec and contents of ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file generated by a provided tool ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can find this tool by either downloading a package or by installing it manually from the sources:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ cargo install --git https://github.com/casper-network/casper-node/ --tag private-1.4.6 global-state-update-gen\n$ global-state-update-gen --help\nGlobal State Update Generator 0.2.0\nGenerates a global state update file based on the supplied parameters\n\nUSAGE:\n global-state-update-gen [SUBCOMMAND]\n\nFLAGS:\n -h, --help Prints help information\n -V, --version Prints version information\n\nSUBCOMMANDS:\n balances Generates an update changing account balances\n generate-admins Generates entries to create new admin accounts on a private chain\n help Prints this message or the help of the given subcommand(s)\n system-contract-registry Generates an update creating the system contract registry\n validators Generates an update changing the validators set\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The standard output of running commands listed above is the content of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file, which contains a list of direct global state modifications."]}),"\n",(0,a.jsxs)(n.p,{children:["Example output of running a ",(0,a.jsx)(n.code,{children:"generate-admins"})," subcommand:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[[entries]]\nkey = "balance-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13"\nvalue = "AAIAAAABCgg="\n\n[[entries]]\nkey = "uref-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13-007"\nvalue = "AAAAAAAJ"\n\n[[entries]]\nkey = "account-hash-ac2f4caa3e3ce1cd1dfb3d089854020b18a50cac49977d0a4c873c4d3d5a2409"\nvalue = "AawvTKo+POHNHfs9CJhUAgsYpQysSZd9CkyHPE09WiQJAAAAAJe7zCQls+2lFJqJPGGAti8UctUUO7FFDQHI4elr4J8TBwEAAACsL0yqPjzhzR37PQiYVAILGKUMrEmXfQpMhzxNPVokCQEBAQ=="\n\n# total supply increases from 200000000000000000 to 200000000000000010\n[[entries]]\nkey = "uref-f8475fd4125484be39a0793530f09a29d220ffda8e48387b3d2194ddfc22894e-007"\nvalue = "AAkAAAAICgAUu/CKxgII"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Currently, this tool outputs contents into standard output. You should redirect standard output to a file named ",(0,a.jsx)(n.code,{children:"global_state.toml"})," and place this file in the same directory as ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," before performing a network upgrade."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ global-state-update-gen generate-admins --data-dir $DATA_DIR --state-hash $STATE_HASH --admin NEW_PUBLIC_KEY,BALANCE >> global_state.toml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By using ",(0,a.jsx)(n.code,{children:">>"})," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."]}),"\n",(0,a.jsx)(n.p,{children:"Common options:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--data-dir"})," path to a global state directory where ",(0,a.jsx)(n.code,{children:"data.lmdb"})," can be found"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--state-hash"})," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"rotating-validators",children:"Rotating validators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command rotates the validator set. Perform a network upgrade with a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-new-administrators",children:"Adding new administrators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command produces the administrator content in the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n"})}),"\n",(0,a.jsx)(n.p,{children:"Remember that new administrators can be created, and the validator set can also be rotated in a single update."}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"After this step, the private network would be ready for use."}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-a-block-explorer",children:"Setting up a Block Explorer"}),"\n",(0,a.jsxs)(n.p,{children:["Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-blockexplorer-frontend",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5109d3ad.b642a8c5.js b/assets/js/5109d3ad.b642a8c5.js deleted file mode 100644 index 1c80f0f98..000000000 --- a/assets/js/5109d3ad.b642a8c5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6224],{1222:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"Private Network Setup"},r="Setting Up a Private Casper Network",o={id:"operators/setup-network/create-private",title:"Private Network Setup",description:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/create-private.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/create-private",permalink:"/operators/setup-network/create-private",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Private Network Setup"},sidebar:"operators",previous:{title:"The Chainspec",permalink:"/operators/setup-network/chain-spec"},next:{title:"Staging Files",permalink:"/operators/setup-network/staging-files-for-new-network"}},c={},d=[{value:"Contents",id:"contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1. Setting up a Validator Node",id:"step-1-setting-up-a-validator-node",level:2},{value:"Step 2. Setting up the Directory",id:"step-2-setting-up-the-directory",level:2},{value:"Step 3. Configuring the Genesis Block",id:"step-3-configuring-the-genesis-block",level:2},{value:"Unrestricted transfers configuration",id:"unrestricted-transfers-configuration",level:3},{value:"Refund handling configuration",id:"refund-handling-configuration",level:3},{value:"Fee handling configuration",id:"fee-handling-configuration",level:3},{value:"Auction behavior configuration",id:"auction-behavior-configuration",level:3},{value:"Step 4. Configuring the Administrator Accounts",id:"step-4-configuring-the-administrator-accounts",level:2},{value:"Configuring administrator accounts",id:"configuring-administrator-accounts",level:3},{value:"Generating new administrator accounts",id:"generating-new-administrator-accounts",level:3},{value:"Managing accounts and smart contracts",id:"managing-accounts-and-smart-contracts",level:3},{value:"Step 5. Starting the Casper Node",id:"step-5-starting-the-casper-node",level:2},{value:"Step 6. Rotating the Validator Accounts",id:"step-6-rotating-the-validator-accounts",level:2},{value:"Step 7. Testing the Private Network",id:"step-7-testing-the-private-network",level:2},{value:"Sample configuration files",id:"sample-configuration-files",level:3},{value:"Specifying IP addresses",id:"specifying-ip-addresses",level:3},{value:"Setting up the node",id:"setting-up-the-node",level:3},{value:"Network access control",id:"network-access-control",level:3},{value:"Funding Alice's account",id:"funding-alices-account",level:3},{value:"Adding a bid as Alice",id:"adding-a-bid-as-alice",level:3},{value:"Disabling Alice's account",id:"disabling-alices-account",level:3},{value:"Enabling Alice's account",id:"enabling-alices-account",level:3},{value:"Enabling a contract",id:"enabling-a-contract",level:3},{value:"Disabling a contract",id:"disabling-a-contract",level:3},{value:"Verifying seigniorage allocations",id:"verifying-seigniorage-allocations",level:3},{value:"Operating guide",id:"operating-guide",level:3},{value:"Rotating validators",id:"rotating-validators",level:3},{value:"Adding new administrators",id:"adding-new-administrators",level:3},{value:"Setting up a Block Explorer",id:"setting-up-a-block-explorer",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"setting-up-a-private-casper-network",children:"Setting Up a Private Casper Network"})}),"\n",(0,a.jsx)(n.p,{children:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network."}),"\n",(0,a.jsx)(n.h2,{id:"contents",children:"Contents"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"Setting up a Validator Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-2-setting-up-the-directory",children:"Setting up the Directory"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-3-configuring-the-genesis-block",children:"Configuring the Genesis Block"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-4-configuring-the-administrator-accounts",children:"Configuring the Administrator Accounts"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-5-starting-the-casper-node",children:"Starting the Casper Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-7-testing-the-private-network",children:"Testing the Private Network"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#setting-up-a-block-explorer",children:"Setting up a Block Explorer"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Follow these guides to set up the required environment and user accounts."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Setting up the Casper client"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/blob/dev/README.md#casper-client",children:"Setting up the client for interacting with the network"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Setting up an Account"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-1-setting-up-a-validator-node",children:"Step 1. Setting up a Validator Node"}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"Casper node"})," is a physical or virtual device participating in a Casper network. You need to set up several ",(0,a.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validator"})," nodes on your private network. An ",(0,a.jsx)(n.a,{href:"/concepts/glossary/O#operator",children:"operator"})," who has won an ",(0,a.jsx)(n.a,{href:"/concepts/glossary/A#auction",children:"auction"})," bid will be a validator for the private network."]}),"\n",(0,a.jsx)(n.p,{children:"Use the below guides to set up and manage validator nodes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup - GitHub guide"}),": A guide to configuring a system with the new Rust node to operate within a network."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic node setup tutorial"}),": A guide on using the ",(0,a.jsx)(n.code,{children:"casper-node-launcher"}),", generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://docs.cspr.community/",children:"Set up Mainnet and Testnet validator nodes"}),": A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use these FAQ collections for tips and details for validators."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-2-setting-up-the-directory",children:"Step 2. Setting up the Directory"}),"\n",(0,a.jsx)(n.p,{children:"Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Go through the ",(0,a.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#file-locations",children:"file location"})," section to understand how directories are created and managed in a Casper private network."]}),"\n",(0,a.jsxs)(n.li,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"setting up a new network"})," guide to identify the required configuration files to set up a genesis block."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-3-configuring-the-genesis-block",children:"Step 3. Configuring the Genesis Block"}),"\n",(0,a.jsxs)(n.p,{children:["A Casper private network contains a different set of configurations when compared to the public network. The ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:(0,a.jsx)(n.code,{children:"chainspec.toml"})})," file contains the required configurations for the genesis process in a private network."]}),"\n",(0,a.jsxs)(n.p,{children:["You should add the configuration options below to the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file inside the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private#step-2-setting-up-the-directory",children:"private network directory"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"unrestricted-transfers-configuration",children:"Unrestricted transfers configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"In contrast, users in the public network can freely transfer funds to different accounts."}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nallow_unrestricted_transfers = false\ncompute_rewards = false\nallow_auction_bids = false\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\nfee_handling = { type = "accumulate" }\nadministrators = ["ADMIN_PUBLIC_KEY"]\n'})})]}),"\n",(0,a.jsx)(n.h3,{id:"refund-handling-configuration",children:"Refund handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user."}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After deducting the gas fee, the distribution of the remaining payment amount is handled based on the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private",children:"fee_handling"})," configuration."]}),"\n",(0,a.jsx)(n.p,{children:"The default configuration for a public chain, including the Casper Mainet, looks like this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [0, 100] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The refund variant with ",(0,a.jsx)(n.code,{children:"refund_ratio"})," of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return."]}),"\n",(0,a.jsx)(n.h3,{id:"fee-handling-configuration",children:"Fee handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed."}),"\n",(0,a.jsx)(n.p,{children:"Set up the configuration as below:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nfee_handling = { type = "pay_to_proposer" }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"fee_handling"})," configuration has three variations:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"pay_to_proposer"}),": The rest of the payment amount after deducing the gas fee from a refund is paid to the block's ",(0,a.jsx)(n.a,{href:"/concepts/glossary/P#proposer",children:"proposer"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"burn"}),": The tokens paid are burned, and the total supply is reduced."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"accumulate"}),": The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"auction-behavior-configuration",children:"Auction behavior configuration"}),"\n",(0,a.jsx)(n.p,{children:"A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set."}),"\n",(0,a.jsx)(n.p,{children:"Use the configuration below to limit the auction validators:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_auction_bids = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Other configurations related to the auction:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"allow_auction_bids"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"})," then ",(0,a.jsx)(n.code,{children:"add_bid"})," and ",(0,a.jsx)(n.code,{children:"delegate"})," options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an ",(0,a.jsx)(n.code,{children:"AuctionBidsDisabled"})," error."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"core.compute_rewards"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"}),", then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In a public network, ",(0,a.jsx)(n.code,{children:"allow_auction_bid"})," is set to ",(0,a.jsx)(n.em,{children:"true"}),", which allows bidding for new entries and validator nodes."]}),"\n",(0,a.jsx)(n.h2,{id:"step-4-configuring-the-administrator-accounts",children:"Step 4. Configuring the Administrator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["An administrator is mandatory for a private network since it manages all the other ",(0,a.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validator"})," accounts. There should be at least one administrator account configured within a network to operate it as a ",(0,a.jsx)(n.code,{children:"private network"}),". You can create new administrators and ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private#step-6-rotating-the-validator-accounts",children:"rotate the validator set"})," in a single configuration update. The operator must first ensure the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances."]}),"\n",(0,a.jsx)(n.h3,{id:"configuring-administrator-accounts",children:"Configuring administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use this configuration option in the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," to add administrator accounts to the private network:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_ACCOUNT_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note"}),": Regular accounts are not allowed to manage their associated keys on a private network."]}),"\n",(0,a.jsx)(n.h3,{id:"generating-new-administrator-accounts",children:"Generating new administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use the command below to generate new administrator accounts in your private network. This generates the contents of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the entries required to create new administrator accounts at the upgrade point."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen \\\n generate-admins --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n --admin $PUBLIC_KEY_HEX, $BALANCE\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_PUBLIC_KEY"})," - Public key of the administrator in a hex format."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_BALANCE"})," - Balance for the administrator\u2019s main purse."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"DATA_DIR"})," - Path to the global state directory."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"STATE_ROOT_HASH"})," - State root hash, taken from the latest block before an upgrade."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"managing-accounts-and-smart-contracts",children:"Managing accounts and smart contracts"}),"\n",(0,a.jsxs)(n.p,{children:["Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/c8023736786b2c2b0fd17250fcfd50502ff4151f/smart_contracts/contracts/private_chain/control-management/src/main.rs",children:"Casper node's private chain control management"})," file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key."]}),"\n",(0,a.jsx)(n.p,{children:"Use this command to generate these contracts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"make build-contracts-rs\n"})}),"\n",(0,a.jsx)(n.p,{children:"Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"disable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"enable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with argument ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='255'"})," and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='255'"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='1'"})," set to 1 and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='0'"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-5-starting-the-casper-node",children:"Step 5. Starting the Casper Node"}),"\n",(0,a.jsx)(n.p,{children:"After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup GitHub"})," guide to know more details about configuring a new node to operate within a network."]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally, refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"casper-node-launcher"})," to check whether the installed node binaries match the installed configurations by comparing the version numbers."]}),"\n",(0,a.jsx)(n.h2,{id:"step-6-rotating-the-validator-accounts",children:"Step 6. Rotating the Validator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["You need to go through ",(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"setting up a validator node "})," guide before starting this section."]}),"\n",(0,a.jsxs)(n.p,{children:["To rotate the validators set, you must perform a network upgrade using a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.p,{children:"When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block."}),"\n",(0,a.jsxs)(n.p,{children:["After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"\nglobal-state-update-gen validators \\\n --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE\n\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Each use of the ",(0,a.jsx)(n.code,{children:"--validator"})," parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter."]}),"\n",(0,a.jsxs)(n.p,{children:["After designating the next era's validators, you must set the chainspec activation point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to ",(0,a.jsx)(n.code,{children:"X"}),", where ",(0,a.jsx)(n.code,{children:"X"})," is equal to the new era after the switch block from above. Finally, set ",(0,a.jsx)(n.code,{children:"hard_reset = true"}),". This makes the network revert to the end of the previous era when restarted with the upgrade."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),", set the activaction point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to 10 and ",(0,a.jsx)(n.code,{children:"hard_reset"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Please make sure you are running this tool as the same user that owns ",(0,a.jsx)(n.code,{children:"$DATA_DIR"}),". Otherwise, you may receive a permission denied error."]})}),"\n",(0,a.jsxs)(n.p,{children:["You can find more details on enabling new validators in the ",(0,a.jsx)(n.a,{href:"/operators/setup/joining",children:"joining a running network"})," guide. The guide explains how to join the network and provide additional security to the system."]}),"\n",(0,a.jsx)(n.h2,{id:"step-7-testing-the-private-network",children:"Step 7. Testing the Private Network"}),"\n",(0,a.jsx)(n.p,{children:"We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer."}),"\n",(0,a.jsx)(n.h3,{id:"sample-configuration-files",children:"Sample configuration files"}),"\n",(0,a.jsx)(n.p,{children:"Here are sample configurations that can be adapted for testing:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["A ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/chainspec.toml.in",children:"chainspec template"})," that is specific to the customer's private chain."]}),"\n",(0,a.jsxs)(n.li,{children:["An ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/accounts.toml.in",children:"accounts template"})," with one administrator in the ",(0,a.jsx)(n.code,{children:"administrators"})," settings."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"specifying-ip-addresses",children:"Specifying IP addresses"}),"\n",(0,a.jsx)(n.p,{children:"Here is an example set of IP addresses in use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"http://18.224.190.213:7777\nhttp://18.188.11.97:7777\nhttp://18.188.206.170:7777\nhttp://18.116.201.114:7777\n"})}),"\n",(0,a.jsx)(n.h3,{id:"setting-up-the-node",children:"Setting up the node"}),"\n",(0,a.jsx)(n.p,{children:"Set up the node address, chain name, and the administrator's secret key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'export NODE_ADDR=http://18.224.190.213:7777\nexport CHAIN_NAME="private-test"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This testing example will also use an ",(0,a.jsx)(n.code,{children:"alice/secret_key.pem"})," file, a secret key generated through the ",(0,a.jsx)(n.a,{href:"/concepts/accounts-and-keys#creating-accounts-and-keys",children:"keys generation process"}),". Alice is a regular user in this testing example."]}),"\n",(0,a.jsx)(n.h3,{id:"network-access-control",children:"Network access control"}),"\n",(0,a.jsx)(n.p,{children:"With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed."}),"\n",(0,a.jsx)(n.p,{children:"To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "local_node_cert.pem"\nsecret_key = "local_node.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"tls_certificate"})," is the certificate signed by a ",(0,a.jsx)(n.code,{children:"ca_cert.pem"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secret_key"})," refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ca_certificate"})," is the network CA that should be the same on each of the nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'# Recommended EC curve algorithm to use\nexport CURVE="secp521r1"\n\n# Generate secret key for CA and save it to ca_key.pem\nopenssl ecparam -out ca_key.pem -name $CURVE -genkey\n# Create ca_cert.pem signed by ca_key.pem\nopenssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem\n\n# Generate secret key for a node and a certificate signed by the CA\nopenssl ecparam -out node_1.pem -name $CURVE -genkey\nopenssl req -new -key node_1.pem -out node_1.csr -sha256\nopenssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem\n'})}),"\n",(0,a.jsx)(n.p,{children:"And then configure the node with the following settings:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "node_1_cert.pem"\nsecret_key = "node_1.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Every node in the private chain network has to be configured with the same CA certificate, and each ",(0,a.jsx)(n.code,{children:"tls_certificate"})," and ",(0,a.jsx)(n.code,{children:"secret_key"})," pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Keep in mind that for security reasons ",(0,a.jsx)(n.code,{children:"ca_key.pem"})," should be stored securely and never present on each of participating machines."]}),"\n",(0,a.jsx)(n.h3,{id:"funding-alices-account",children:"Funding Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command transfers tokens to Alice's main purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n transfer \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<admin/public_key_hex) \\\n --target-account=$(<alice/public_key_hex) \\\n --amount=100000000000 \\\n --payment-amount=3000000000 \\\n --transfer-id=123\n"})}),"\n",(0,a.jsx)(n.p,{children:"To check the account information, use this command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-account-info -n $NODE_ADDR\n --public-key alice/public_key.pem\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-a-bid-as-alice",children:"Adding a bid as Alice"}),"\n",(0,a.jsxs)(n.p,{children:["The following command attempts to add an auction bid on the network. It should return ",(0,a.jsx)(n.code,{children:"ApiError::AuctionError(AuctionBidsDisabled) [64559]"}),"."]}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["All payment amounts in these examples must be adjusted based on the network ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key alice/secret_key.pem \\\n --session-path add_bid.wasm \\\n --payment-amount 5000000000 \\\n --session-arg "public_key:public_key=\'$(<alice/public_key_hex)\'" \\\n --session-arg "amount:u512=\'10000\'" \\\n --session-arg "delegation_rate:u8=\'5\'"\n\n# Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"\n'})}),"\n",(0,a.jsx)(n.p,{children:"We should get a similar error for the delegate entry point."}),"\n",(0,a.jsx)(n.h3,{id:"disabling-alices-account",children:"Disabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='255'\" \\\n --session-arg \"deploy_threshold:u8='255'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-alices-account",children:"Enabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='0'\" \\\n --session-arg \"deploy_threshold:u8='1'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-a-contract",children:"Enabling a contract"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables a contract using its hash."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path enable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"disabling-a-contract",children:"Disabling a contract"}),"\n",(0,a.jsxs)(n.p,{children:["The following command disables a contract using its hash. Executing this contract using ",(0,a.jsx)(n.code,{children:"CONTRACT_HASH"})," again should fail."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path disable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:"Alice needs a container access key for the contract package in her named keys."}),"\n",(0,a.jsx)(n.h3,{id:"verifying-seigniorage-allocations",children:"Verifying seigniorage allocations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://www.investopedia.com/terms/s/seigniorage.asp",children:"Seigniorage"})," allocations should be zero at each switch block. This is the related configuration:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\ncompute_rewards = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Validator stakes should not increase on each switch block. Run this command to verify this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-era-info -n $NODE_ADDR -b 153\n"})}),"\n",(0,a.jsx)(n.p,{children:"The total supply shouldn't increase, and the validator's stakes should remain the same."}),"\n",(0,a.jsx)(n.h3,{id:"operating-guide",children:"Operating guide"}),"\n",(0,a.jsxs)(n.p,{children:["Some configuration options such as ",(0,a.jsx)(n.code,{children:"allow_auction_bids"})," require a private chain operator to perform specific tasks manually through a network upgrade with chainspec and contents of ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file generated by a provided tool ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can find this tool by either downloading a package or by installing it manually from the sources:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ cargo install --git https://github.com/casper-network/casper-node/ --tag private-1.4.6 global-state-update-gen\n$ global-state-update-gen --help\nGlobal State Update Generator 0.2.0\nGenerates a global state update file based on the supplied parameters\n\nUSAGE:\n global-state-update-gen [SUBCOMMAND]\n\nFLAGS:\n -h, --help Prints help information\n -V, --version Prints version information\n\nSUBCOMMANDS:\n balances Generates an update changing account balances\n generate-admins Generates entries to create new admin accounts on a private chain\n help Prints this message or the help of the given subcommand(s)\n system-contract-registry Generates an update creating the system contract registry\n validators Generates an update changing the validators set\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The standard output of running commands listed above is the content of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file, which contains a list of direct global state modifications."]}),"\n",(0,a.jsxs)(n.p,{children:["Example output of running a ",(0,a.jsx)(n.code,{children:"generate-admins"})," subcommand:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[[entries]]\nkey = "balance-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13"\nvalue = "AAIAAAABCgg="\n\n[[entries]]\nkey = "uref-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13-007"\nvalue = "AAAAAAAJ"\n\n[[entries]]\nkey = "account-hash-ac2f4caa3e3ce1cd1dfb3d089854020b18a50cac49977d0a4c873c4d3d5a2409"\nvalue = "AawvTKo+POHNHfs9CJhUAgsYpQysSZd9CkyHPE09WiQJAAAAAJe7zCQls+2lFJqJPGGAti8UctUUO7FFDQHI4elr4J8TBwEAAACsL0yqPjzhzR37PQiYVAILGKUMrEmXfQpMhzxNPVokCQEBAQ=="\n\n# total supply increases from 200000000000000000 to 200000000000000010\n[[entries]]\nkey = "uref-f8475fd4125484be39a0793530f09a29d220ffda8e48387b3d2194ddfc22894e-007"\nvalue = "AAkAAAAICgAUu/CKxgII"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Currently, this tool outputs contents into standard output. You should redirect standard output to a file named ",(0,a.jsx)(n.code,{children:"global_state.toml"})," and place this file in the same directory as ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," before performing a network upgrade."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ global-state-update-gen generate-admins --data-dir $DATA_DIR --state-hash $STATE_HASH --admin NEW_PUBLIC_KEY,BALANCE >> global_state.toml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By using ",(0,a.jsx)(n.code,{children:">>"})," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."]}),"\n",(0,a.jsx)(n.p,{children:"Common options:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--data-dir"})," path to a global state directory where ",(0,a.jsx)(n.code,{children:"data.lmdb"})," can be found"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--state-hash"})," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"rotating-validators",children:"Rotating validators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command rotates the validator set. Perform a network upgrade with a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-new-administrators",children:"Adding new administrators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command produces the administrator content in the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n"})}),"\n",(0,a.jsx)(n.p,{children:"Remember that new administrators can be created, and the validator set can also be rotated in a single update."}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"After this step, the private network would be ready for use."}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-a-block-explorer",children:"Setting up a Block Explorer"}),"\n",(0,a.jsxs)(n.p,{children:["Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-blockexplorer-frontend",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5168ee15.9f3c0d6d.js b/assets/js/5168ee15.9f3c0d6d.js new file mode 100644 index 000000000..c80377387 --- /dev/null +++ b/assets/js/5168ee15.9f3c0d6d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30471],{59781:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Q",a={id:"concepts/glossary/Q",title:"Q",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/Q.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Q",permalink:"/2.0.0/concepts/glossary/Q",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"P",permalink:"/2.0.0/concepts/glossary/P"},next:{title:"R",permalink:"/2.0.0/concepts/glossary/R"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"q",children:"Q"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/51719dea.6107622a.js b/assets/js/51719dea.6107622a.js deleted file mode 100644 index 261cdf4bb..000000000 --- a/assets/js/51719dea.6107622a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6444],{9431:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=n(74848),s=n(28453);const i={title:"What is a dApp?"},o="What is a dApp?",r={id:"developers/dapps/dapp",title:"What is a dApp?",description:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.",source:"@site/docs/developers/dapps/dapp.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/dapp",permalink:"/next/developers/dapps/dapp",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"What is a dApp?"},sidebar:"developers",previous:{title:"Overview of Casper dApps",permalink:"/next/developers/dapps/"},next:{title:"Prerequisites",permalink:"/next/developers/dapps/prerequisites"}},c={},d=[{value:"How are Decentralized Applications Different?",id:"how-are-decentralized-applications-different",level:2},{value:"Interacting with a Decentralized Network",id:"interacting-with-a-decentralized-network",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"what-is-a-dapp",children:"What is a dApp?"})}),"\n",(0,a.jsx)(t.p,{children:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network."}),"\n",(0,a.jsx)(t.p,{children:"The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself."}),"\n",(0,a.jsx)(t.h2,{id:"how-are-decentralized-applications-different",children:"How are Decentralized Applications Different?"}),"\n",(0,a.jsxs)(t.p,{children:["A decentralized system consists of a group of interchangeable machines that can perform as a full system or ",(0,a.jsx)(t.code,{children:"distributed database"}),". Additional machines strengthen the overall system by adding redundancy and computational power."]}),"\n",(0,a.jsxs)(t.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"node"}),". The ",(0,a.jsx)(t.code,{children:"decentralized"})," aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsxs)(t.p,{children:["Routine operations in a decentralized network may result in nodes coming on or offline. This ",(0,a.jsx)(t.em,{children:"node churn"})," can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node."]}),"\n",(0,a.jsx)(t.h2,{id:"interacting-with-a-decentralized-network",children:"Interacting with a Decentralized Network"}),"\n",(0,a.jsxs)(t.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(t.a,{href:"/next/concepts/glossary/T#transaction",children:"transactions"})," via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(t.a,{href:"/next/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(t.p,{children:["A transaction contains ",(0,a.jsx)(t.a,{href:"/next/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(t.a,{href:"/next/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later."]}),"\n",(0,a.jsx)(t.p,{children:"Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."}),"\n",(0,a.jsx)(t.p,{children:"All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."}),"\n",(0,a.jsx)(t.p,{children:"Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."}),"\n",(0,a.jsxs)(t.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(t.a,{href:"/next/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/51719dea.65346675.js b/assets/js/51719dea.65346675.js new file mode 100644 index 000000000..ee7e486b6 --- /dev/null +++ b/assets/js/51719dea.65346675.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76444],{9431:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=n(74848),s=n(28453);const i={title:"What is a dApp?"},o="What is a dApp?",r={id:"developers/dapps/dapp",title:"What is a dApp?",description:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.",source:"@site/docs/developers/dapps/dapp.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/dapp",permalink:"/developers/dapps/dapp",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"What is a dApp?"},sidebar:"developers",previous:{title:"Overview of Casper dApps",permalink:"/developers/dapps/"},next:{title:"Prerequisites",permalink:"/developers/dapps/prerequisites"}},c={},d=[{value:"How are Decentralized Applications Different?",id:"how-are-decentralized-applications-different",level:2},{value:"Interacting with a Decentralized Network",id:"interacting-with-a-decentralized-network",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"what-is-a-dapp",children:"What is a dApp?"})}),"\n",(0,a.jsx)(t.p,{children:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network."}),"\n",(0,a.jsx)(t.p,{children:"The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself."}),"\n",(0,a.jsx)(t.h2,{id:"how-are-decentralized-applications-different",children:"How are Decentralized Applications Different?"}),"\n",(0,a.jsxs)(t.p,{children:["A decentralized system consists of a group of interchangeable machines that can perform as a full system or ",(0,a.jsx)(t.code,{children:"distributed database"}),". Additional machines strengthen the overall system by adding redundancy and computational power."]}),"\n",(0,a.jsxs)(t.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"node"}),". The ",(0,a.jsx)(t.code,{children:"decentralized"})," aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsxs)(t.p,{children:["Routine operations in a decentralized network may result in nodes coming on or offline. This ",(0,a.jsx)(t.em,{children:"node churn"})," can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node."]}),"\n",(0,a.jsx)(t.h2,{id:"interacting-with-a-decentralized-network",children:"Interacting with a Decentralized Network"}),"\n",(0,a.jsxs)(t.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T#transaction",children:"transactions"})," via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(t.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(t.p,{children:["A transaction contains ",(0,a.jsx)(t.a,{href:"/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(t.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later."]}),"\n",(0,a.jsx)(t.p,{children:"Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."}),"\n",(0,a.jsx)(t.p,{children:"All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."}),"\n",(0,a.jsx)(t.p,{children:"Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."}),"\n",(0,a.jsxs)(t.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(t.a,{href:"/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/51ce653c.21c89cba.js b/assets/js/51ce653c.21c89cba.js deleted file mode 100644 index 7834d5c1d..000000000 --- a/assets/js/51ce653c.21c89cba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2072],{18801:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var r=t(74848),s=t(28453);const i={title:"Introduction",slug:"/writing-contracts"},c="Writing On-Chain Code",o={id:"developers/writing-onchain-code/index",title:"Introduction",description:"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.",source:"@site/docs/developers/writing-onchain-code/index.md",sourceDirName:"developers/writing-onchain-code",slug:"/writing-contracts",permalink:"/next/writing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Introduction",slug:"/writing-contracts"},sidebar:"developers",previous:{title:"Essential Rust Crates",permalink:"/next/developers/essential-crates"},next:{title:"Getting Started with Rust",permalink:"/next/developers/writing-onchain-code/getting-started"}},a={},d=[{value:"Interacting with Contracts on the Blockchain",id:"interacting-with-contracts-on-the-blockchain",level:2},{value:"Tutorials",id:"tutorials",level:2}];function l(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",iframe:"iframe",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...n.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"writing-on-chain-code",children:"Writing On-Chain Code"})}),"\n",(0,r.jsxs)(e.p,{children:["This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The ",(0,r.jsx)(e.a,{href:"https://www.youtube.com/playlist?list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj",children:"Video Series for Writing On-Chain Code"})," accompanies the topics below."]}),"\n",(0,r.jsxs)(e.p,{align:"center",children:["\n",(0,r.jsx)(e.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/JoOjhSOnQzk",position:"middle",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),(0,r.jsx)(e.td,{children:"An introduction to using Rust with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/assembly-script",children:"Getting Started with AssemblyScript"})}),(0,r.jsx)(e.td,{children:"An introduction to using AssemblyScript with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),(0,r.jsx)(e.td,{children:"An example of a smart contract built in Rust"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Steps to test contract code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),(0,r.jsx)(e.td,{children:"An introduction to versioning smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/calling-contracts",children:"Calling Contracts"})}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),(0,r.jsx)(e.td,{children:"Understand what session code is and when you would use it over contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"})}),(0,r.jsx)(e.td,{children:"An introduction to writing session code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),(0,r.jsx)(e.td,{children:"Steps to test session code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/emitting-contract-events",children:"Contract-Level Events"})}),(0,r.jsx)(e.td,{children:"Enabling smart contracts to emit messages while executing on the blockchain"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/contract-hash-vs-package-hash",children:"Using Contract Hash vs. Package Hash"})}),(0,r.jsxs)(e.td,{children:["Advantages and disadvantages of using ",(0,r.jsx)(e.code,{children:"contract_hash"})," vs. ",(0,r.jsx)(e.code,{children:"contract_package_hash"})," when calling a contract"]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern for Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Learn to implement the contract factory pattern on a Casper network"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})}),(0,r.jsx)(e.td,{children:"An outline of best practices when developing smart contracts on a Casper network"})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"interacting-with-contracts-on-the-blockchain",children:"Interacting with Contracts on the Blockchain"}),"\n",(0,r.jsxs)(e.p,{children:["Additionally, the section on ",(0,r.jsx)(e.a,{href:"/next/developers/cli/",children:"Interacting with the Blockchain"})," covers installing and calling contracts using the Casper command-line client written in Rust."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})}),(0,r.jsx)(e.td,{children:"A guide on installing smart contracts and querying global state"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(e.td,{children:"Steps to call a smart contract with the Rust command-line client"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})}),(0,r.jsx)(e.td,{children:"Information on Dictionaries and how to read and write to them on the Casper Platform."})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(e.td,{children:"Possible error codes when writing smart contracts."})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,r.jsx)(e.p,{children:"The following tutorials outline some aspects of writing smart contracts on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(e.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(e.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(e.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(e.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(e.td,{children:"Implement the Casper Fungible Token standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsx)(e.td,{children:"Learning how to return a value using contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(e.td,{children:"Retrieving and using the authorization keys associated with a transaction"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/next/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(e.td,{children:"How to handle tokens via a contract"})]})]})]})]})}function h(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,r.jsx)(e,{...n,children:(0,r.jsx)(l,{...n})}):l(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>c,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function c(n){const e=r.useContext(i);return r.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function o(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:c(n.components),r.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/51ce653c.dc35e1ca.js b/assets/js/51ce653c.dc35e1ca.js new file mode 100644 index 000000000..90905164f --- /dev/null +++ b/assets/js/51ce653c.dc35e1ca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32072],{18801:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var r=t(74848),s=t(28453);const i={title:"Introduction",slug:"/writing-contracts"},c="Writing On-Chain Code",o={id:"developers/writing-onchain-code/index",title:"Introduction",description:"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.",source:"@site/docs/developers/writing-onchain-code/index.md",sourceDirName:"developers/writing-onchain-code",slug:"/writing-contracts",permalink:"/writing-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Introduction",slug:"/writing-contracts"},sidebar:"developers",previous:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"},next:{title:"Getting Started with Rust",permalink:"/developers/writing-onchain-code/getting-started"}},a={},d=[{value:"Interacting with Contracts on the Blockchain",id:"interacting-with-contracts-on-the-blockchain",level:2},{value:"Tutorials",id:"tutorials",level:2}];function l(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",iframe:"iframe",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...n.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(e.header,{children:(0,r.jsx)(e.h1,{id:"writing-on-chain-code",children:"Writing On-Chain Code"})}),"\n",(0,r.jsxs)(e.p,{children:["This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The ",(0,r.jsx)(e.a,{href:"https://www.youtube.com/playlist?list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj",children:"Video Series for Writing On-Chain Code"})," accompanies the topics below."]}),"\n",(0,r.jsxs)(e.p,{align:"center",children:["\n",(0,r.jsx)(e.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/JoOjhSOnQzk",position:"middle",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),(0,r.jsx)(e.td,{children:"An introduction to using Rust with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/assembly-script",children:"Getting Started with AssemblyScript"})}),(0,r.jsx)(e.td,{children:"An introduction to using AssemblyScript with the Casper Platform"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),(0,r.jsx)(e.td,{children:"An example of a smart contract built in Rust"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Steps to test contract code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),(0,r.jsx)(e.td,{children:"An introduction to versioning smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"Calling Contracts"})}),(0,r.jsx)(e.td,{})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),(0,r.jsx)(e.td,{children:"Understand what session code is and when you would use it over contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"})}),(0,r.jsx)(e.td,{children:"An introduction to writing session code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),(0,r.jsx)(e.td,{children:"Steps to test session code using the unit testing framework"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/emitting-contract-events",children:"Contract-Level Events"})}),(0,r.jsx)(e.td,{children:"Enabling smart contracts to emit messages while executing on the blockchain"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/contract-hash-vs-package-hash",children:"Using Contract Hash vs. Package Hash"})}),(0,r.jsxs)(e.td,{children:["Advantages and disadvantages of using ",(0,r.jsx)(e.code,{children:"contract_hash"})," vs. ",(0,r.jsx)(e.code,{children:"contract_package_hash"})," when calling a contract"]})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern for Smart Contracts"})}),(0,r.jsx)(e.td,{children:"Learn to implement the contract factory pattern on a Casper network"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})}),(0,r.jsx)(e.td,{children:"An outline of best practices when developing smart contracts on a Casper network"})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"interacting-with-contracts-on-the-blockchain",children:"Interacting with Contracts on the Blockchain"}),"\n",(0,r.jsxs)(e.p,{children:["Additionally, the section on ",(0,r.jsx)(e.a,{href:"/developers/cli/",children:"Interacting with the Blockchain"})," covers installing and calling contracts using the Casper command-line client written in Rust."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})}),(0,r.jsx)(e.td,{children:"A guide on installing smart contracts and querying global state"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(e.td,{children:"Steps to call a smart contract with the Rust command-line client"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})}),(0,r.jsx)(e.td,{children:"Information on Dictionaries and how to read and write to them on the Casper Platform."})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(e.td,{children:"Possible error codes when writing smart contracts."})]})]})]}),"\n",(0,r.jsx)(e.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,r.jsx)(e.p,{children:"The following tutorials outline some aspects of writing smart contracts on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(e.table,{children:[(0,r.jsx)(e.thead,{children:(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.th,{children:"Title"}),(0,r.jsx)(e.th,{children:"Description"})]})}),(0,r.jsxs)(e.tbody,{children:[(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(e.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(e.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(e.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(e.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(e.td,{children:"Implement the Casper Fungible Token standard"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsx)(e.td,{children:"Learning how to return a value using contract code"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(e.td,{children:"Retrieving and using the authorization keys associated with a transaction"})]}),(0,r.jsxs)(e.tr,{children:[(0,r.jsx)(e.td,{children:(0,r.jsx)(e.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(e.td,{children:"How to handle tokens via a contract"})]})]})]})]})}function h(n={}){const{wrapper:e}={...(0,s.R)(),...n.components};return e?(0,r.jsx)(e,{...n,children:(0,r.jsx)(l,{...n})}):l(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>c,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function c(n){const e=r.useContext(i);return r.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function o(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(s):n.components||s:c(n.components),r.createElement(i.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/521a6610.546443b5.js b/assets/js/521a6610.546443b5.js new file mode 100644 index 000000000..032dd99db --- /dev/null +++ b/assets/js/521a6610.546443b5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73027],{38764:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var r=t(74848),s=t(28453);const i={title:"Interacting with the Blockchain"},l="Using the Casper CLI Client",o={id:"developers/cli/index",title:"Interacting with the Blockchain",description:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.",source:"@site/versioned_docs/version-1.5.X/developers/cli/index.md",sourceDirName:"developers/cli",slug:"/developers/cli/",permalink:"/1.5.X/developers/cli/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Interacting with the Blockchain"},sidebar:"developers",previous:{title:"Monitoring and Consuming Events",permalink:"/1.5.X/developers/dapps/monitor-and-consume-events"},next:{title:"Transferring Tokens",permalink:"/1.5.X/developers/cli/transfers/"}},c={},a=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-the-casper-cli-client",children:"Using the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/",children:"Transferring Tokens"})}),(0,r.jsx)(n.td,{children:"Transferring tokens from one account to another using the Casper command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"Delegating tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/undelegate",children:"Undelegating Tokens with the Casper Client"})}),(0,r.jsx)(n.td,{children:"Undelegating tokens from a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Sending Deploys to a Network"})}),(0,r.jsx)(n.td,{children:"Sending Deploys to a Casper network using the Rust CLI Client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to install a contract on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/querying-global-state",children:"Querying Global State"})}),(0,r.jsx)(n.td,{children:"How to query global state after contract installation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Various ways to call a contract's entry-points"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Error codes for smart contract execution"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/521a6610.95717138.js b/assets/js/521a6610.95717138.js deleted file mode 100644 index d4f13d64f..000000000 --- a/assets/js/521a6610.95717138.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3027],{38764:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>a});var r=t(74848),s=t(28453);const i={title:"Interacting with the Blockchain"},l="Using the Casper CLI Client",o={id:"developers/cli/index",title:"Interacting with the Blockchain",description:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.",source:"@site/versioned_docs/version-1.5.X/developers/cli/index.md",sourceDirName:"developers/cli",slug:"/developers/cli/",permalink:"/developers/cli/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Interacting with the Blockchain"},sidebar:"developers",previous:{title:"Monitoring and Consuming Events",permalink:"/developers/dapps/monitor-and-consume-events"},next:{title:"Transferring Tokens",permalink:"/developers/cli/transfers/"}},c={},a=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"using-the-casper-cli-client",children:"Using the Casper CLI Client"})}),"\n",(0,r.jsx)(n.p,{children:"This section explains how to interact with a Casper network using the Casper command-line client written in Rust."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/transfers/",children:"Transferring Tokens"})}),(0,r.jsx)(n.td,{children:"Transferring tokens from one account to another using the Casper command-line client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/delegate",children:"Delegating tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/undelegate",children:"Undelegating Tokens with the Casper Client"})}),(0,r.jsx)(n.td,{children:"Undelegating tokens from a validator on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"Sending Deploys to a Network"})}),(0,r.jsx)(n.td,{children:"Sending Deploys to a Casper network using the Rust CLI Client"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Steps to install a contract on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/querying-global-state",children:"Querying Global State"})}),(0,r.jsx)(n.td,{children:"How to query global state after contract installation"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts with the Rust Client"})}),(0,r.jsx)(n.td,{children:"Various ways to call a contract's entry-points"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/developers/cli/execution-error-codes",children:"Execution Error Codes"})}),(0,r.jsx)(n.td,{children:"Error codes for smart contract execution"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>l,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function l(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52927c97.de1bbc11.js b/assets/js/52927c97.de1bbc11.js new file mode 100644 index 000000000..04f84bf27 --- /dev/null +++ b/assets/js/52927c97.de1bbc11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64917],{1028:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var r=n(74848),c=n(28453);const t={},o="F",a={id:"concepts/glossary/F",title:"F",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/F.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/F",permalink:"/2.0.0/concepts/glossary/F",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"E",permalink:"/2.0.0/concepts/glossary/E"},next:{title:"G",permalink:"/2.0.0/concepts/glossary/G"}},l={},i=[{value:"Finality",id:"finality",level:2},{value:"Fungible",id:"fungible",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"f",children:"F"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"finality",children:"Finality"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block-finality",children:"block finality"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"fungible",children:"Fungible"}),"\n",(0,r.jsxs)(s.p,{children:["A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N#non-fungible-token",children:"non-fungible token"}),", where each token is unique and not interchangeable."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52ab49a5.7e1e13d0.js b/assets/js/52ab49a5.7e1e13d0.js new file mode 100644 index 000000000..b8892228c --- /dev/null +++ b/assets/js/52ab49a5.7e1e13d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[85240],{76164:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var a=t(74848),s=t(28453);const i={title:"Transactions",slug:"/transactions"},r="Transactions",o={id:"concepts/transactions",title:"Transactions",description:"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.",source:"@site/versioned_docs/version-2.0.0/concepts/transactions.md",sourceDirName:"concepts",slug:"/transactions",permalink:"/2.0.0/transactions",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Transactions",slug:"/transactions"}},l={},c=[{value:"Transaction Types",id:"transaction-types",level:2},{value:"Withdraw Bid",id:"withdraw-bid",level:3},{value:"Add Bid",id:"add-bid",level:3},{value:"Delegate",id:"delegate",level:3},{value:"Undelegate",id:"undelegate",level:3},{value:"Redelegate",id:"redelegate",level:3},{value:"Invocable Entity",id:"invocable-entity",level:3},{value:"Invocable Entity Alias",id:"invocable-entity-alias",level:3},{value:"Package",id:"package",level:3},{value:"Package Name",id:"package-name",level:3},{value:"Session",id:"session",level:3},{value:"Transfer",id:"transfer",level:3}];function d(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",summary:"summary",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"transactions",children:"Transactions"})}),"\n",(0,a.jsxs)(n.p,{children:["Transactions are ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:"a new structure"})," that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/D#deploy",children:"Deploys"}),", allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."]}),"\n",(0,a.jsx)(n.p,{children:"The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute."}),"\n",(0,a.jsx)(n.h2,{id:"transaction-types",children:"Transaction Types"}),"\n",(0,a.jsxs)(n.p,{children:["The following is a list of Transaction types included within the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/tree/dev",children:"CLI Casper client"})," ",(0,a.jsx)(n.code,{children:"put-transaction"})," or ",(0,a.jsx)(n.code,{children:"put-txn"})," command."]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw-bid",children:"Withdraw Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"withdraw-bid"})," allows validators to withdraw their auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn withdraw-bid\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be withdrawn.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"add-bid",children:"Add Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"add-bid"})," allows validators to place an auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn add-bid\n/// The [delegation rate](../concepts/economics/staking.md#delegation-rate) for delegators staking on to this validator.\n --delegation-rate <INTEGER>\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be bid.\n --transaction-amount <INTEGER>\n/// The minimum amount of motes that a delegator can stake to this validator.\n --minimum-delegation-amount <INTEGER>\n/// The maximum amount of motes that a delegator can stake to this validator.\n --maximum-delegation-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"delegate",children:"Delegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"delegate"})," allows a user to delegate a stake of CSPR to a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn delegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to stake with this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"undelegate",children:"Undelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"undelegate"})," allows a user to undelegate their previously staked CSPR from a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn undelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to undelegate from this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"redelegate",children:"Redelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"redelegate"})," allows a user to redelegate their previously staked CSPR to a new validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn redelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The old validator's public key.\n --validator <STRING>\n/// The new validator's public key.\n --new-validator <STRING>\n/// The amount in motes to redelegate from the old validator to the new validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity",children:"Invocable Entity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/key-types#addressableentity",children:(0,a.jsx)(n.code,{children:"Entity Address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity\n/// The [`entity-hash`](../developers/json-rpc/types_chain.md#addressableentityhash) of the entity to invoke.\n --entity-address <FORMATTED STRING or PATH>\n/// The entry point on the invocable entity.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity-alias",children:"Invocable Entity Alias"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity-alias"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an alias stored in their ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity-alias\n/// The entity alias stored in the calling entity's named keys.\n --entity-alias <STRING>\n/// The entry point on the invocable entity. \n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using the associated ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/key-types#package",children:(0,a.jsx)(n.code,{children:"package-address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package\n/// The address of the contract package.\n --package-address <FORMATTED STRING or PATH>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package-name",children:"Package Name"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package-name"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using an alias stored in their ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package-name\n/// The package alias stored in the calling entity's named keys.\n --package-alias <STRING>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"session",children:"Session"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"session"})," allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending Transactions"})," covers this in depth."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn session\n/// The local path pointing to Wasm that will be sent to global state.\n --transaction-path <PATH>\n/// An entry point on a previously installed contract, if applicable.\n --session-entry-point <NAME>\n/// The category of the Transaction, in decreasing size order.\n --category <install-upgrade|large|medium|small>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"transfer"})," allows a user to transfer the designated number of ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/M#motes",children:"motes"})," to a target address."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn transfer\n/// The recipient of the transfer.\n --target <FORMATTED STRING>\n/// The amount in motes to be transferred.\n --transfer-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n "]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52fa5650.b182f278.js b/assets/js/52fa5650.b182f278.js deleted file mode 100644 index 87120a08a..000000000 --- a/assets/js/52fa5650.b182f278.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2275],{64954:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var n=r(74848),o=r(28453);const c={},t="V",a={id:"concepts/glossary/V",title:"V",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/V.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/V",permalink:"/concepts/glossary/V",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"U",permalink:"/concepts/glossary/U"},next:{title:"W",permalink:"/concepts/glossary/W"}},l={},i=[{value:"Validator",id:"validator",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"v",children:"V"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"validator",children:"Validator"}),"\n",(0,n.jsx)(s.p,{children:'Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.'}),"\n",(0,n.jsx)(s.p,{children:"The responsibilities of a validator include:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-creation",children:"block creation"})," and ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-proposal",children:"block proposal"})]}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-validation",children:"block validation"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-gossiping",children:"block gossiping"})}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending deploys). Validators and ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S#staker",children:"stakers"})," can lose their bond (be slashed) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const o={},c=n.createContext(o);function t(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/52fa5650.deb039aa.js b/assets/js/52fa5650.deb039aa.js new file mode 100644 index 000000000..52c720fa7 --- /dev/null +++ b/assets/js/52fa5650.deb039aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92275],{64954:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var n=r(74848),o=r(28453);const c={},t="V",a={id:"concepts/glossary/V",title:"V",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/V.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/V",permalink:"/1.5.X/concepts/glossary/V",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"U",permalink:"/1.5.X/concepts/glossary/U"},next:{title:"W",permalink:"/1.5.X/concepts/glossary/W"}},l={},i=[{value:"Validator",id:"validator",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"v",children:"V"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"validator",children:"Validator"}),"\n",(0,n.jsx)(s.p,{children:'Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.'}),"\n",(0,n.jsx)(s.p,{children:"The responsibilities of a validator include:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block-creation",children:"block creation"})," and ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block-proposal",children:"block proposal"})]}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block-validation",children:"block validation"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block-gossiping",children:"block gossiping"})}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending deploys). Validators and ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S#staker",children:"stakers"})," can lose their bond (be slashed) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const o={},c=n.createContext(o);function t(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/533ebf6b.62b843d3.js b/assets/js/533ebf6b.62b843d3.js deleted file mode 100644 index ce4a2acfb..000000000 --- a/assets/js/533ebf6b.62b843d3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3931],{56193:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var c=s(74848),t=s(28453);const a={title:"Interaction Workflow"},i="Interacting with the NFT Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client/interacting-with-NFTs",title:"Interaction Workflow",description:"This document describes interacting with NFTs on a Casper network using the Rust command-line client.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",permalink:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Interaction Workflow"},sidebar:"resources",previous:{title:"Installation Workflow",permalink:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial"},next:{title:"CEP-78 Contract Details",permalink:"/resources/tokens/cep78/using-casper-client/querying-NFTs"}},o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Directly Invoking Entrypoints",id:"directly-invoking-entrypoints",level:2},{value:"Minting NFTs",id:"minting-nfts",level:2},{value:"Minting NFTs using Wasm",id:"minting-nfts-using-wasm",level:3},{value:"Transferring NFTs",id:"transferring-nfts",level:2},{value:"Transferring NFTs using Wasm",id:"transferring-nfts-using-wasm",level:3},{value:"Checking Balances",id:"checking-balances",level:2},{value:"Approving an Account",id:"approving-an-account",level:2},{value:"Burning NFTs",id:"burning-nfts",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"interacting-with-the-nft-contract-using-the-rust-casper-client",children:"Interacting with the NFT Contract using the Rust Casper Client"})}),"\n",(0,c.jsx)(n.p,{children:"This document describes interacting with NFTs on a Casper network using the Rust command-line client."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Install the contract using the ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query NFT Contracts"})," and save the various hashes and URefs required throughout this document"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#minting-nfts",children:"Minting NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#transferring-nfts",children:"Transferring NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#checking-balances",children:"Checking Balances"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#approving-an-account",children:"Approving an Account"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#burning-nfts",children:"Burning NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#next-steps",children:"Next Steps"})}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"}),"\n",(0,c.jsxs)(n.p,{children:["With the release of CEP-78 version 1.1, users interacting with a CEP-78 contract that does not use ",(0,c.jsx)(n.code,{children:"ReverseLookupMode"})," should opt out of using the client Wasm files provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost than using the provided client Wasm to invoke the entrypoint."]}),"\n",(0,c.jsxs)(n.p,{children:["You may invoke the ",(0,c.jsx)(n.code,{children:"mint"}),", ",(0,c.jsx)(n.code,{children:"transfer"}),", or ",(0,c.jsx)(n.code,{children:"burn"})," entrypoints directly through either the contract package hash or the contract hash directly."]}),"\n",(0,c.jsxs)(n.p,{children:["In the case of ",(0,c.jsx)(n.code,{children:"mint"}),", fewer runtime arguments must be provided, thereby reducing the total gas cost of minting an NFT."]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Example `mint` using the stored package hash"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \\\n--session-entry-point "mint" \\\n--session-arg "token_owner:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Example `transfer` using the stored contract hash"})}),"\n",(0,c.jsxs)(n.p,{children:["Based on the identifier mode for the given contract instance, either the ",(0,c.jsx)(n.code,{children:"token_id"})," runtime argument must be passed in or, in the case of the hash identifier mode, the ",(0,c.jsx)(n.code,{children:"token_hash"})," runtime argument."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--session-entry-point "transfer" \\\n--session-arg "source_key:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "target_key:key=\'account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"minting-nfts",children:"Minting NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"mint"})," entrypoint of the contract to mint an NFT for the user associated with ",(0,c.jsx)(n.code,{children:"node-1"})," in an ",(0,c.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"NCTL environment"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "mint"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"})}),"\n",(0,c.jsx)(n.p,{children:"The package hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,c.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,c.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "mint" \\\n--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \\\n--session-arg "token_owner:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["If the ",(0,c.jsx)(n.code,{children:"identifier_mode"})," was set to hash (1) during installation, the ",(0,c.jsx)(n.code,{children:"token_hash"})," runtime argument needs to be specified during minting. Since you already know the NFT's identifier, you can easily query the NFT's ",(0,c.jsx)(n.code,{children:"meta_data"}),", which is a very useful feature. This example uses an ordinal (0) ",(0,c.jsx)(n.code,{children:"identifier_mode"}),"."]})}),"\n",(0,c.jsx)(n.h3,{id:"minting-nfts-using-wasm",children:"Minting NFTs using Wasm"}),"\n",(0,c.jsxs)(n.p,{children:["This example invokes the ",(0,c.jsx)(n.code,{children:"mint_call.wasm"})," session code provided in the ",(0,c.jsx)(n.code,{children:"client"})," folder."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_name:string='cep78_<collection_name>'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,c.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,c.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95\'" \\\n--session-arg "collection_name:string=\'cep78_<collection_name>\'" \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transferring-nfts",children:"Transferring NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"transfer"})," entrypoint to transfer ownership of an NFT from one user to another."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "transfer"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The argument that the hash identifier mode is ordinal, thereby requiring a ",(0,c.jsx)(n.code,{children:"token_id"})," rather than a ",(0,c.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "transfer" \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,c.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the deploy allows you to verify execution success, but you will need to use the ",(0,c.jsx)(n.code,{children:"balance_of"})," entrypoint to verify the account's balance as shown ",(0,c.jsx)(n.a,{href:"#checking-balances",children:"below"}),"."]}),"\n",(0,c.jsx)(n.h3,{id:"transferring-nfts-using-wasm",children:"Transferring NFTs using Wasm"}),"\n",(0,c.jsxs)(n.p,{children:["This example uses the ",(0,c.jsx)(n.code,{children:"transfer_call.wasm"})," session code to transfer ownership of an NFT from one user to another."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,c.jsxs)(n.p,{children:["Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,c.jsx)(n.code,{children:"token_id"})," rather than a ",(0,c.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"checking-balances",children:"Checking Balances"}),"\n",(0,c.jsxs)(n.p,{children:["To check an account's balance, get the latest state root hash and query the ",(0,c.jsx)(n.code,{children:"balances"}),' dictionary given the NFT contract hash and the owner\'s account hash without the "account-hash-" prefix, as shown below.']}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"casper-client get-dictionary-item -n http://localhost:11101/rpc"})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f"})}),"\n",(0,c.jsx)(n.p,{children:"The latest state root hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796"})}),"\n",(0,c.jsx)(n.p,{children:"The NFT contract hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--dictionary-name "balances"'})}),"\n",(0,c.jsx)(n.p,{children:"The dictionary tracking the number of tokens for each account hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34"'})}),"\n",(0,c.jsxs)(n.p,{children:["The account hash of the user whose token balance we are checking without the ",(0,c.jsx)(n.code,{children:"account-hash-"})," prefix."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client commands without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client get-dictionary-item -n http://localhost:11101/rpc/ \\\n--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f \\\n--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--dictionary-name "balances" \\\n--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"approving-an-account",children:"Approving an Account"}),"\n",(0,c.jsxs)(n.p,{children:["The Casper NFT contract features an ",(0,c.jsx)(n.code,{children:"approve"})," entrypoint, allowing another account to manage a specific token. During contract installation, the ",(0,c.jsx)(n.code,{children:"ownership_mode"})," must be set to 2, meaning ",(0,c.jsx)(n.code,{children:"Transferable"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "approve"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'\""})}),"\n",(0,c.jsx)(n.p,{children:"The hash of the account receiving the approval."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,c.jsx)(n.p,{children:"The token ID of the approved NFT."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "approve" \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"burning-nfts",children:"Burning NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"burn"})," entrypoint to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,c.jsx)(n.p,{children:"The session hash corresponding to the NFT's contract hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-entry-point "burn"'})}),"\n",(0,c.jsxs)(n.p,{children:["The entrypoint corresponding to the ",(0,c.jsx)(n.code,{children:"burn"})," function."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The token ID for the NFT to be burned. If the ",(0,c.jsx)(n.code,{children:"identifier_mode"})," is not set to ",(0,c.jsx)(n.code,{children:"Ordinal"}),", you must provide the ",(0,c.jsx)(n.code,{children:"token_hash"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/testing-NFTs",children:"Testing Framework for CEP-78"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>r});var c=s(96540);const t={},a=c.createContext(t);function i(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/533ebf6b.d593cda4.js b/assets/js/533ebf6b.d593cda4.js new file mode 100644 index 000000000..2d2f26d27 --- /dev/null +++ b/assets/js/533ebf6b.d593cda4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73931],{56193:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var c=s(74848),t=s(28453);const a={title:"Interaction Workflow"},i="Interacting with the NFT Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client/interacting-with-NFTs",title:"Interaction Workflow",description:"This document describes interacting with NFTs on a Casper network using the Rust command-line client.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Interaction Workflow"},sidebar:"resources",previous:{title:"Installation Workflow",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial"},next:{title:"CEP-78 Contract Details",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs"}},o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Directly Invoking Entrypoints",id:"directly-invoking-entrypoints",level:2},{value:"Minting NFTs",id:"minting-nfts",level:2},{value:"Minting NFTs using Wasm",id:"minting-nfts-using-wasm",level:3},{value:"Transferring NFTs",id:"transferring-nfts",level:2},{value:"Transferring NFTs using Wasm",id:"transferring-nfts-using-wasm",level:3},{value:"Checking Balances",id:"checking-balances",level:2},{value:"Approving an Account",id:"approving-an-account",level:2},{value:"Burning NFTs",id:"burning-nfts",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"interacting-with-the-nft-contract-using-the-rust-casper-client",children:"Interacting with the NFT Contract using the Rust Casper Client"})}),"\n",(0,c.jsx)(n.p,{children:"This document describes interacting with NFTs on a Casper network using the Rust command-line client."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Install the contract using the ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query NFT Contracts"})," and save the various hashes and URefs required throughout this document"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#minting-nfts",children:"Minting NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#transferring-nfts",children:"Transferring NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#checking-balances",children:"Checking Balances"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#approving-an-account",children:"Approving an Account"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#burning-nfts",children:"Burning NFTs"})}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.a,{href:"#next-steps",children:"Next Steps"})}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"directly-invoking-entrypoints",children:"Directly Invoking Entrypoints"}),"\n",(0,c.jsxs)(n.p,{children:["With the release of CEP-78 version 1.1, users interacting with a CEP-78 contract that does not use ",(0,c.jsx)(n.code,{children:"ReverseLookupMode"})," should opt out of using the client Wasm files provided as part of the release. Opting out in this situation is recommended, as directly invoking the entrypoints incurs a lower gas cost than using the provided client Wasm to invoke the entrypoint."]}),"\n",(0,c.jsxs)(n.p,{children:["You may invoke the ",(0,c.jsx)(n.code,{children:"mint"}),", ",(0,c.jsx)(n.code,{children:"transfer"}),", or ",(0,c.jsx)(n.code,{children:"burn"})," entrypoints directly through either the contract package hash or the contract hash directly."]}),"\n",(0,c.jsxs)(n.p,{children:["In the case of ",(0,c.jsx)(n.code,{children:"mint"}),", fewer runtime arguments must be provided, thereby reducing the total gas cost of minting an NFT."]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Example `mint` using the stored package hash"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \\\n--session-entry-point "mint" \\\n--session-arg "token_owner:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Example `transfer` using the stored contract hash"})}),"\n",(0,c.jsxs)(n.p,{children:["Based on the identifier mode for the given contract instance, either the ",(0,c.jsx)(n.code,{children:"token_id"})," runtime argument must be passed in or, in the case of the hash identifier mode, the ",(0,c.jsx)(n.code,{children:"token_hash"})," runtime argument."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--session-entry-point "transfer" \\\n--session-arg "source_key:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "target_key:key=\'account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"minting-nfts",children:"Minting NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"mint"})," entrypoint of the contract to mint an NFT for the user associated with ",(0,c.jsx)(n.code,{children:"node-1"})," in an ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/dapps/nctl-test",children:"NCTL environment"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "mint"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"})}),"\n",(0,c.jsx)(n.p,{children:"The package hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,c.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,c.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "mint" \\\n--session-package-hash hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30 \\\n--session-arg "token_owner:key=\'account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["If the ",(0,c.jsx)(n.code,{children:"identifier_mode"})," was set to hash (1) during installation, the ",(0,c.jsx)(n.code,{children:"token_hash"})," runtime argument needs to be specified during minting. Since you already know the NFT's identifier, you can easily query the NFT's ",(0,c.jsx)(n.code,{children:"meta_data"}),", which is a very useful feature. This example uses an ordinal (0) ",(0,c.jsx)(n.code,{children:"identifier_mode"}),"."]})}),"\n",(0,c.jsx)(n.h3,{id:"minting-nfts-using-wasm",children:"Minting NFTs using Wasm"}),"\n",(0,c.jsxs)(n.p,{children:["This example invokes the ",(0,c.jsx)(n.code,{children:"mint_call.wasm"})," session code provided in the ",(0,c.jsx)(n.code,{children:"client"})," folder."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_name:string='cep78_<collection_name>'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the previously installed CEP-78 NFT contract from which we will be minting."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_owner:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The collection name of the NFT to be minted."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"'})}),"\n",(0,c.jsxs)(n.p,{children:["Metadata describing the NFT to be minted, passed in as a ",(0,c.jsx)(n.code,{children:"string"}),"."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1\u201d \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-206339c3deb8e6146974125bb271eb510795be6f250c21b1bd4b698956669f95\'" \\\n--session-arg "collection_name:string=\'cep78_<collection_name>\'" \\\n--session-arg "token_owner:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "token_meta_data:string=\'{\\"name\\": \\"John Doe\\",\\"token_uri\\": \\"https:\\/\\/www.barfoo.com\\",\\"checksum\\": \\"940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb\\"}\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transferring-nfts",children:"Transferring NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"transfer"})," entrypoint to transfer ownership of an NFT from one user to another."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "transfer"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The argument that the hash identifier mode is ordinal, thereby requiring a ",(0,c.jsx)(n.code,{children:"token_id"})," rather than a ",(0,c.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "transfer" \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,c.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the deploy allows you to verify execution success, but you will need to use the ",(0,c.jsx)(n.code,{children:"balance_of"})," entrypoint to verify the account's balance as shown ",(0,c.jsx)(n.a,{href:"#checking-balances",children:"below"}),"."]}),"\n",(0,c.jsx)(n.h3,{id:"transferring-nfts-using-wasm",children:"Transferring NFTs using Wasm"}),"\n",(0,c.jsxs)(n.p,{children:["This example uses the ",(0,c.jsx)(n.code,{children:"transfer_call.wasm"})," session code to transfer ownership of an NFT from one user to another."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/secret_key.pem --session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_contract_hash:key='hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5'\""})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the CEP-78 NFT Contract associated with the NFT to be transferred."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that currently owns the NFT and wishes to transfer it."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"target_key:key='account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'\""})}),"\n",(0,c.jsx)(n.p,{children:"The account hash of the user that will receive the NFT."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"is_hash_identifier_mode:bool='false'\""})}),"\n",(0,c.jsxs)(n.p,{children:["Argument that the hash identifier mode is ordinal, thereby requiring a ",(0,c.jsx)(n.code,{children:"token_id"})," rather than a ",(0,c.jsx)(n.code,{children:"token_hash"}),"."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='0'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.code,{children:"token_id"})," of the NFT to be transferred."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem \\\n--session-path ~/casper/enhanced-nft/client/transfer_session/target/wasm32-unknown-unknown/release/transfer_call.wasm \\\n--session-arg "nft_contract_hash:key=\'hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5\'" \\\n--session-arg "source_key:key=\'account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb\'" \\\n--session-arg "target_key:key=\'account-hash-b4772e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab\'" \\\n--session-arg "is_hash_identifier_mode:bool=\'false\'" \\\n--session-arg "token_id:u64=\'0\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"checking-balances",children:"Checking Balances"}),"\n",(0,c.jsxs)(n.p,{children:["To check an account's balance, get the latest state root hash and query the ",(0,c.jsx)(n.code,{children:"balances"}),' dictionary given the NFT contract hash and the owner\'s account hash without the "account-hash-" prefix, as shown below.']}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"casper-client get-dictionary-item -n http://localhost:11101/rpc"})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f"})}),"\n",(0,c.jsx)(n.p,{children:"The latest state root hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796"})}),"\n",(0,c.jsx)(n.p,{children:"The NFT contract hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--dictionary-name "balances"'})}),"\n",(0,c.jsx)(n.p,{children:"The dictionary tracking the number of tokens for each account hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34"'})}),"\n",(0,c.jsxs)(n.p,{children:["The account hash of the user whose token balance we are checking without the ",(0,c.jsx)(n.code,{children:"account-hash-"})," prefix."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client commands without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client get-dictionary-item -n http://localhost:11101/rpc/ \\\n--state-root-hash f22e8ecfb3d2700d5f902c83da456c32f130b73d0d35037fe89b2d4b4933673f \\\n--contract-hash hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--dictionary-name "balances" \\\n--dictionary-item-key "0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"approving-an-account",children:"Approving an Account"}),"\n",(0,c.jsxs)(n.p,{children:["The Casper NFT contract features an ",(0,c.jsx)(n.code,{children:"approve"})," entrypoint, allowing another account to manage a specific token. During contract installation, the ",(0,c.jsx)(n.code,{children:"ownership_mode"})," must be set to 2, meaning ",(0,c.jsx)(n.code,{children:"Transferable"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-entry-point "approve"'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,c.jsx)(n.p,{children:"The contract hash of the previously installed CEP-78 NFT contract."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"spender:key='account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513'\""})}),"\n",(0,c.jsx)(n.p,{children:"The hash of the account receiving the approval."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,c.jsx)(n.p,{children:"The token ID of the approved NFT."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-entry-point "approve" \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"burning-nfts",children:"Burning NFTs"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that uses the ",(0,c.jsx)(n.code,{children:"burn"})," entrypoint to burn an NFT within a CEP-78 collection. If this command is used, the NFT in question will no longer be accessible by anyone."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5"})}),"\n",(0,c.jsx)(n.p,{children:"The session hash corresponding to the NFT's contract hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:'--session-entry-point "burn"'})}),"\n",(0,c.jsxs)(n.p,{children:["The entrypoint corresponding to the ",(0,c.jsx)(n.code,{children:"burn"})," function."]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"token_id:u64='1'\""})}),"\n",(0,c.jsxs)(n.p,{children:["The token ID for the NFT to be burned. If the ",(0,c.jsx)(n.code,{children:"identifier_mode"})," is not set to ",(0,c.jsx)(n.code,{children:"Ordinal"}),", you must provide the ",(0,c.jsx)(n.code,{children:"token_hash"})," instead."]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n-k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \\\n--session-entry-point "burn" \\\n--session-arg "token_id:u64=\'1\'"\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs",children:"Testing Framework for CEP-78"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>r});var c=s(96540);const t={},a=c.createContext(t);function i(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5364a150.134445fe.js b/assets/js/5364a150.134445fe.js new file mode 100644 index 000000000..cca46dec5 --- /dev/null +++ b/assets/js/5364a150.134445fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92152],{31487:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var t=n(74848),a=n(28453);const i={},o="Signing Deploys",r={id:"developers/dapps/signing-a-deploy",title:"Signing Deploys",description:"When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/signing-a-deploy.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/signing-a-deploy",permalink:"/1.5.X/developers/dapps/signing-a-deploy",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"URef Access Rights",permalink:"/1.5.X/developers/dapps/uref-security"},next:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/1.5.X/developers/dapps/speculative-exec"}},d={},c=[{value:"Public Key Cryptography",id:"public-key-cryptography",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"signing-deploys",children:"Signing Deploys"})}),"\n",(0,t.jsxs)(s.p,{children:["When creating a ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-deploy",children:(0,t.jsx)(s.code,{children:"Deploy"})})," to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed."]}),"\n",(0,t.jsxs)(s.p,{children:["When a signature is attached to a deploy, it is paired with the public key of the signer, and referred to as an ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard#approval",children:(0,t.jsx)(s.code,{children:"Approval"})}),". Every valid deploy has at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The signature creation process begins with the hashing of the payment and session of the deploy to create the ",(0,t.jsx)(s.code,{children:"BodyHash"}),". The ",(0,t.jsx)(s.code,{children:"BodyHash"})," becomes a component of the ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard#deploy-header",children:(0,t.jsx)(s.code,{children:"DeployHeader"})})," as outlined in the serialization standard. From there, the ",(0,t.jsx)(s.code,{children:"DeployHeader"})," can be hashed to create the ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard#deploy-hash",children:(0,t.jsx)(s.code,{children:"DeployHash"})}),". As outlined above, the ",(0,t.jsx)(s.code,{children:"DeployHash"})," is then combined with the account's key-pair to create the deploy's signature."]}),"\n",(0,t.jsxs)(s.p,{children:["As the ",(0,t.jsx)(s.code,{children:"DeployHash"})," contains a hash of the deploy's body within, any variation to any aspect of the deploy or sending account's keys would render the ",(0,t.jsx)(s.code,{children:"DeployHash"})," invalid."]}),"\n",(0,t.jsx)(s.h2,{id:"public-key-cryptography",children:"Public Key Cryptography"}),"\n",(0,t.jsxs)(s.p,{children:["Casper networks are compatible with both ",(0,t.jsx)(s.code,{children:"Ed25519"})," and ",(0,t.jsx)(s.code,{children:"Secp256k1"})," public key cryptography. When ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard",children:"serialized"}),", public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with ",(0,t.jsx)(s.code,{children:"1"}),", whereas Secp256k1 are prefixed with ",(0,t.jsx)(s.code,{children:"2"}),"."]}),"\n",(0,t.jsxs)(s.p,{children:["Casper uses ",(0,t.jsx)(s.code,{children:"blake2b"})," hashing within our ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard",children:"serialization"}),". However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Ed25519 signs over a SHA-512 digest."}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Secp256k1 signs over a SHA-256 digest."}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>r});var t=n(96540);const a={},i=t.createContext(a);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5364a150.155bae67.js b/assets/js/5364a150.155bae67.js deleted file mode 100644 index b36bbb6a0..000000000 --- a/assets/js/5364a150.155bae67.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2152],{31487:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>c});var t=n(74848),a=n(28453);const i={},o="Signing Deploys",r={id:"developers/dapps/signing-a-deploy",title:"Signing Deploys",description:"When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/signing-a-deploy.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/signing-a-deploy",permalink:"/developers/dapps/signing-a-deploy",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"},next:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/developers/dapps/speculative-exec"}},d={},c=[{value:"Public Key Cryptography",id:"public-key-cryptography",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"signing-deploys",children:"Signing Deploys"})}),"\n",(0,t.jsxs)(s.p,{children:["When creating a ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard#serialization-standard-deploy",children:(0,t.jsx)(s.code,{children:"Deploy"})})," to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed."]}),"\n",(0,t.jsxs)(s.p,{children:["When a signature is attached to a deploy, it is paired with the public key of the signer, and referred to as an ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard#approval",children:(0,t.jsx)(s.code,{children:"Approval"})}),". Every valid deploy has at least one approval."]}),"\n",(0,t.jsxs)(s.p,{children:["The signature creation process begins with the hashing of the payment and session of the deploy to create the ",(0,t.jsx)(s.code,{children:"BodyHash"}),". The ",(0,t.jsx)(s.code,{children:"BodyHash"})," becomes a component of the ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard#deploy-header",children:(0,t.jsx)(s.code,{children:"DeployHeader"})})," as outlined in the serialization standard. From there, the ",(0,t.jsx)(s.code,{children:"DeployHeader"})," can be hashed to create the ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard#deploy-hash",children:(0,t.jsx)(s.code,{children:"DeployHash"})}),". As outlined above, the ",(0,t.jsx)(s.code,{children:"DeployHash"})," is then combined with the account's key-pair to create the deploy's signature."]}),"\n",(0,t.jsxs)(s.p,{children:["As the ",(0,t.jsx)(s.code,{children:"DeployHash"})," contains a hash of the deploy's body within, any variation to any aspect of the deploy or sending account's keys would render the ",(0,t.jsx)(s.code,{children:"DeployHash"})," invalid."]}),"\n",(0,t.jsx)(s.h2,{id:"public-key-cryptography",children:"Public Key Cryptography"}),"\n",(0,t.jsxs)(s.p,{children:["Casper networks are compatible with both ",(0,t.jsx)(s.code,{children:"Ed25519"})," and ",(0,t.jsx)(s.code,{children:"Secp256k1"})," public key cryptography. When ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard",children:"serialized"}),", public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with ",(0,t.jsx)(s.code,{children:"1"}),", whereas Secp256k1 are prefixed with ",(0,t.jsx)(s.code,{children:"2"}),"."]}),"\n",(0,t.jsxs)(s.p,{children:["Casper uses ",(0,t.jsx)(s.code,{children:"blake2b"})," hashing within our ",(0,t.jsx)(s.a,{href:"/concepts/serialization-standard",children:"serialization"}),". However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Ed25519 signs over a SHA-512 digest."}),"\n"]}),"\n",(0,t.jsxs)(s.li,{children:["\n",(0,t.jsx)(s.p,{children:"Secp256k1 signs over a SHA-256 digest."}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>r});var t=n(96540);const a={},i=t.createContext(a);function o(e){const s=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function r(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53d095ec.27dbcfb8.js b/assets/js/53d095ec.27dbcfb8.js new file mode 100644 index 000000000..c6b3bdfef --- /dev/null +++ b/assets/js/53d095ec.27dbcfb8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[48425],{91722:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>a});var t=s(74848),o=s(28453);const i={},c="Contracts and Session Code",r={id:"developers/writing-onchain-code/contract-vs-session",title:"Contracts and Session Code",description:"What is Session Code?",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-vs-session.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-vs-session",permalink:"/1.5.X/developers/writing-onchain-code/contract-vs-session",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/1.5.X/developers/writing-onchain-code/calling-contracts"},next:{title:"Writing Session Code",permalink:"/1.5.X/developers/writing-onchain-code/writing-session-code"}},d={},a=[{value:"What is Session Code?",id:"what-is-session-code",level:2},{value:"Comparing Session and Contract Code",id:"comparing-session-and-contract",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"contracts-and-session-code",children:"Contracts and Session Code"})}),"\n",(0,t.jsx)(n.h2,{id:"what-is-session-code",children:"What is Session Code?"}),"\n",(0,t.jsxs)(n.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the ",(0,t.jsx)(n.code,{children:"call"})," function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse."]}),"\n",(0,t.jsxs)(n.p,{children:["The best use of session code is when the situation calls for ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/S#stateless",children:"stateless"})," execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary."]}),"\n",(0,t.jsx)(n.h2,{id:"comparing-session-and-contract",children:"Comparing Session and Contract Code"}),"\n",(0,t.jsx)(n.p,{children:"The following table summarizes the key differences between session code and contract code on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Session Code"}),(0,t.jsx)(n.th,{children:"Contract Code"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Session code always executes in the context of the account that signed the deploy containing the session code."}),(0,t.jsx)(n.td,{children:"A smart contract, which is stored on-chain logic, executes within its own context."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Session code has only one entry point, ",(0,t.jsx)(n.code,{children:"call"}),", which can be used to interact with the session code."]}),(0,t.jsx)(n.td,{children:"A smart contract can have multiple entry points that can be invoked."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," entry point initiates any action the session code takes."]}),(0,t.jsx)(n.td,{children:"Any action undertaken by a contract must initiate through an outside call, usually via session code."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the body of the session code, the key is added to the account's named keys."]}),(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the smart contract's context, the contract's record is modified to have a new named_key entry."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["For more information on how to write session code, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),"."]}),(0,t.jsxs)(n.td,{children:["For more information on writing contracts, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"The following image depicts the comparison presented in the table."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Comparing Session and Contract Code",src:s(87532).A+"",width:"3716",height:"2652"})}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"write session code"})]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-session-code",children:"test session code"})]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},87532:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/session-contract-context-eeb5191bad40f018d30b138e5fb2f964.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53d095ec.d55cf378.js b/assets/js/53d095ec.d55cf378.js deleted file mode 100644 index 07c3d20b0..000000000 --- a/assets/js/53d095ec.d55cf378.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8425],{91722:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>a});var t=s(74848),o=s(28453);const i={},c="Contracts and Session Code",r={id:"developers/writing-onchain-code/contract-vs-session",title:"Contracts and Session Code",description:"What is Session Code?",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-vs-session.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-vs-session",permalink:"/developers/writing-onchain-code/contract-vs-session",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/developers/writing-onchain-code/calling-contracts"},next:{title:"Writing Session Code",permalink:"/developers/writing-onchain-code/writing-session-code"}},d={},a=[{value:"What is Session Code?",id:"what-is-session-code",level:2},{value:"Comparing Session and Contract Code",id:"comparing-session-and-contract",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"contracts-and-session-code",children:"Contracts and Session Code"})}),"\n",(0,t.jsx)(n.h2,{id:"what-is-session-code",children:"What is Session Code?"}),"\n",(0,t.jsxs)(n.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the ",(0,t.jsx)(n.code,{children:"call"})," function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse."]}),"\n",(0,t.jsxs)(n.p,{children:["The best use of session code is when the situation calls for ",(0,t.jsx)(n.a,{href:"/concepts/glossary/S#stateless",children:"stateless"})," execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary."]}),"\n",(0,t.jsx)(n.h2,{id:"comparing-session-and-contract",children:"Comparing Session and Contract Code"}),"\n",(0,t.jsx)(n.p,{children:"The following table summarizes the key differences between session code and contract code on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Session Code"}),(0,t.jsx)(n.th,{children:"Contract Code"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Session code always executes in the context of the account that signed the deploy containing the session code."}),(0,t.jsx)(n.td,{children:"A smart contract, which is stored on-chain logic, executes within its own context."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Session code has only one entry point, ",(0,t.jsx)(n.code,{children:"call"}),", which can be used to interact with the session code."]}),(0,t.jsx)(n.td,{children:"A smart contract can have multiple entry points that can be invoked."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," entry point initiates any action the session code takes."]}),(0,t.jsx)(n.td,{children:"Any action undertaken by a contract must initiate through an outside call, usually via session code."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the body of the session code, the key is added to the account's named keys."]}),(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the smart contract's context, the contract's record is modified to have a new named_key entry."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["For more information on how to write session code, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),"."]}),(0,t.jsxs)(n.td,{children:["For more information on writing contracts, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"The following image depicts the comparison presented in the table."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Comparing Session and Contract Code",src:s(12118).A+"",width:"3716",height:"2652"})}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"write session code"})]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"test session code"})]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},12118:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/session-contract-context-eeb5191bad40f018d30b138e5fb2f964.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/53dc618d.924994dd.js b/assets/js/53dc618d.924994dd.js new file mode 100644 index 000000000..3d090ce0a --- /dev/null +++ b/assets/js/53dc618d.924994dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[10419],{3317:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var t=s(74848),o=s(28453);const r={title:"Installation"},i="Installing a Node",a={id:"operators/setup/install-node",title:"Installation",description:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.",source:"@site/versioned_docs/version-2.0.0/operators/setup/install-node.md",sourceDirName:"operators/setup",slug:"/operators/setup/install-node",permalink:"/2.0.0/operators/setup/install-node",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Installation"},sidebar:"operators",previous:{title:"Endpoints",permalink:"/2.0.0/operators/setup/node-endpoints"},next:{title:"Fast Sync",permalink:"/2.0.0/operators/setup/fast-sync"}},l={},c=[{value:"Network Requirements",id:"network-requirements",level:2},{value:"Operating System Requirements",id:"operating-system-requirements",level:2},{value:"Using Ubuntu 22.04",id:"using-ubuntu-2204",level:3},{value:"Required Number of Open Files",id:"required-number-of-open-files",level:2},{value:"Required Clean Up",id:"required-clean-up",level:2},{value:"Required Packages",id:"required-packages",level:2},{value:"Required Tools",id:"required-tools",level:2},{value:"Enable Bash Auto-Completion for <code>casper-client</code> (Optional)",id:"enable-bash-auto-completion-for-casper-client-optional",level:2},{value:"Installing All Protocols",id:"installing-all-protocols",level:2},{value:"Validator Keys",id:"validator-keys",level:2},{value:"Getting a Trusted Hash",id:"getting-a-trusted-hash",level:2},{value:"Node Address",id:"node-address",level:3},{value:"Protocol Version",id:"protocol-version",level:3},{value:"Load <code>trusted_hash</code> in Config.toml of the Protocol Version",id:"load-trusted_hash-in-configtoml-of-the-protocol-version",level:3},{value:"Syncing to Genesis",id:"syncing-to-genesis",level:2},{value:"Starting the Node",id:"starting-the-node",level:2},{value:"Monitoring the Synchronization Process",id:"monitoring-the-synchronization-process",level:3},{value:"Monitoring the Running Node",id:"monitoring-the-running-node",level:3},{value:"A Note on Speculative Execution",id:"a-note-on-speculative-execution",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-a-node",children:"Installing a Node"})}),"\n",(0,t.jsx)(n.p,{children:"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet."}),"\n",(0,t.jsx)(n.h2,{id:"network-requirements",children:"Network Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The following ports are used by the node:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"35000 (required to be externally visible)"}),"\n",(0,t.jsx)(n.li,{children:"7777 RPC endpoint for interaction with JSON-RPC API"}),"\n",(0,t.jsx)(n.li,{children:"8888 REST endpoint for status and metrics (having this accessible allows your node to be part of network status)"}),"\n",(0,t.jsx)(n.li,{children:"9999 SSE endpoint for event stream"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Of these ",(0,t.jsx)(n.code,{children:"35000"})," is the only port required to be open for your node to function, however, opening ",(0,t.jsx)(n.code,{children:"8888"})," will allow others to know general network health. For more details, see the additional information on ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/node-endpoints",children:"Node Endpoints"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"operating-system-requirements",children:"Operating System Requirements"}),"\n",(0,t.jsx)(n.p,{children:"The recommended OS version is Ubuntu 20.04."}),"\n",(0,t.jsx)(n.h3,{id:"using-ubuntu-2204",children:"Using Ubuntu 22.04"}),"\n",(0,t.jsx)(n.p,{children:"Installing using Ubuntu 22.04 follows the same instructions as 20.04 with one exception:"}),"\n",(0,t.jsx)(n.p,{children:"If you try to install packages, you will receive:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"casper-client : Depends: libssl1.1 (>= 1.1.0) but it is not installable\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This message is due to the default ",(0,t.jsx)(n.code,{children:"openssl"})," moving to 3.* with Ubuntu 22.04. You need to install OpenSSL 1.* for prior versions of Ubuntu to use the Casper binaries with the following command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"curl -f -JLO http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1f-1ubuntu2.20_amd64.deb\nsudo apt install ./libssl1.1_1.1.1f-1ubuntu2.19_amd64.deb\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-number-of-open-files",children:"Required Number of Open Files"}),"\n",(0,t.jsxs)(n.p,{children:["Before beginning, ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/open-files",children:"update the maximum open files limit"})," for your system. Specifically, update the node's ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file as described ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/open-files#updating-limits-conf",children:"here"}),", to ensure proper node operation."]}),"\n",(0,t.jsx)(n.h2,{id:"required-clean-up",children:"Required Clean Up"}),"\n",(0,t.jsxs)(n.p,{children:["If you were running a previous node on this box, this will clean up state. If packages are not installed, the ",(0,t.jsx)(n.code,{children:"apt remove"})," may give errors, but this is not a problem."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher.service\nsudo apt remove -y casper-client\nsudo apt remove -y casper-node\nsudo apt remove -y casper-node-launcher\nsudo rm /etc/casper/casper-node-launcher-state.toml\nsudo rm -rf /etc/casper/1_*\nsudo rm -rf /var/lib/casper/*\n"})}),"\n",(0,t.jsx)(n.h2,{id:"required-packages",children:"Required Packages"}),"\n",(0,t.jsx)(n.p,{children:"The following commands will set up the Casper Labs repository for packages:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'echo "deb [arch=amd64] https://repo.casperlabs.io/releases focal main" | sudo tee -a /etc/apt/sources.list.d/casper.list\ncurl -O https://repo.casperlabs.io/casper-repo-pubkey.asc\nsudo apt-key add casper-repo-pubkey.asc\nsudo apt update\n'})}),"\n",(0,t.jsx)(n.h2,{id:"required-tools",children:"Required Tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install -y casper-client casper-node-launcher jq\n"})}),"\n",(0,t.jsxs)(n.h2,{id:"enable-bash-auto-completion-for-casper-client-optional",children:["Enable Bash Auto-Completion for ",(0,t.jsx)(n.code,{children:"casper-client"})," (Optional)"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo casper-client generate-completion\n"})}),"\n",(0,t.jsxs)(n.p,{children:["It defaults to ",(0,t.jsx)(n.code,{children:"bash"})," but can be changed with the ",(0,t.jsx)(n.code,{children:"--shell"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"--shell <STRING> The type of shell to generate the completion script for [default: bash] [possible values:\n zsh, bash, fish, powershell, elvish]\n\nsudo casper-client generate-completion --shell powershell\n"})}),"\n",(0,t.jsx)(n.p,{children:"You need to source the new auto completion script or log out and log in again to activate it for the current shell:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source /usr/share/bash-completion/completions/casper-client\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now you can use ",(0,t.jsx)(n.code,{children:"casper-client"})," and press the ",(0,t.jsx)(n.code,{children:"tab"})," key to get auto completion for your commands."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-all-protocols",children:"Installing All Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Mainnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,t.jsxs)(n.p,{children:["On ",(0,t.jsx)(n.strong,{children:"Testnet"}),", run:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,t.jsx)(n.h2,{id:"validator-keys",children:"Validator Keys"}),"\n",(0,t.jsx)(n.p,{children:"If you do not have keys yet, you can create them using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,t.jsxs)(n.p,{children:["For more details, see the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"getting-a-trusted-hash",children:"Getting a Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["In the past, we have used a lower ",(0,t.jsx)(n.code,{children:"trusted_hash"}),". Connecting at the tip, we now use as high of a ",(0,t.jsx)(n.code,{children:"trusted_hash"})," as possible. Find out more about ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/fast-sync",children:"Fast Sync"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"node-address",children:"Node Address"}),"\n",(0,t.jsx)(n.p,{children:"NODE_ADDR can be set to an IP of a trusted node, or to Casper Labs' public nodes"}),"\n",(0,t.jsxs)(n.p,{children:["You can find active peers at ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"https://cspr.live/tools/peers"})," or use the following Casper Labs public nodes:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Testnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.testnet.casperlabs.io",children:"https://rpc.testnet.casperlabs.io"})]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Mainnet - NODE_ADDR=",(0,t.jsx)(n.a,{href:"https://rpc.mainnet.casperlabs.io",children:"https://rpc.mainnet.casperlabs.io"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,t.jsxs)(n.p,{children:["Protocol version should be set to the largest available protocol version you see in ",(0,t.jsx)(n.code,{children:"ls /etc/casper"}),". As of writing this, it was 1_5_2:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"PROTOCOL=1_5_2\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"load-trusted_hash-in-configtoml-of-the-protocol-version",children:["Load ",(0,t.jsx)(n.code,{children:"trusted_hash"})," in Config.toml of the Protocol Version"]}),"\n",(0,t.jsxs)(n.p,{children:["The following command uses the previously established NODE_ADDR and PROTOCOL to load the ",(0,t.jsx)(n.code,{children:"trusted_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"NODE_ADDR=https://rpc.mainnet.casperlabs.io\nPROTOCOL=1_5_2\nsudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address $NODE_ADDR | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/$PROTOCOL/config.toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"syncing-to-genesis",children:"Syncing to Genesis"}),"\n",(0,t.jsxs)(n.p,{children:["In the latest protocol version's ",(0,t.jsx)(n.em,{children:"Config.toml"}),", you will find the option ",(0,t.jsx)(n.code,{children:"sync_to_genesis"}),". By default, this value will be set to ",(0,t.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"If you are planning to run a validator node, it is better to not sync your node to genesis. This will increase node performance. In this case, the option should be changed to:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sync_to_genesis = false\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you are using the node for historical data and want to query back to genesis, you can leave the default value in place."}),"\n",(0,t.jsx)(n.h2,{id:"starting-the-node",children:"Starting the Node"}),"\n",(0,t.jsx)(n.p,{children:"Start the node using the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py rotate_logs\nsudo /etc/casper/node_util.py start\n"})}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-synchronization-process",children:"Monitoring the Synchronization Process"}),"\n",(0,t.jsx)(n.p,{children:"The following command will display the node synchronization details:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"/etc/casper/node_util.py watch\n"})}),"\n",(0,t.jsxs)(n.p,{children:["When you first run the watch command, you may see the message ",(0,t.jsx)(n.code,{children:"RPC: Not Ready"}),". Once the node is synchronized, the status will change to ",(0,t.jsx)(n.code,{children:"RPC: Ready"})," and a similar output:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Last Block: 630151 (Era: 4153)\nPeer Count: 297\nUptime: 4days 6h 40m 18s 553ms\nBuild: 1.4.5-a7f6a648d-casper-mainnet\nKey: 0147b4cae09d64ab6acd02dd0868722be9a9bcc355c2fdff7c2c244cbfcd30f158\nNext Upgrade: None\n\nRPC: Ready\n\n\u25cf casper-node-launcher.service - Casper Node Launcher\n Loaded: loaded (/lib/systemd/system/casper-node-launcher.service; enabled; vendor preset: enabled)\n Active: active (running) since Wed 2022-03-16 21:08:50 UTC; 4 days ago\n Docs: https://docs.casper.network\n Main PID: 2934 (casper-node-lau)\n Tasks: 12 (limit: 4915)\n CGroup: /system.slice/casper-node-launcher.service\n \u251c\u2500 2934 /usr/bin/casper-node-launcher\n \u2514\u250016842 /var/lib/casper/bin/1_4_5/casper-node validator /etc/casper/1_4_5/config.toml\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The reactor state will be in CatchUp mode until it acquires the full tip state, at which point it will shift to KeepUp mode. If you left ",(0,t.jsx)(n.code,{children:"sync_to_genesis"})," as ",(0,t.jsx)(n.code,{children:"true"}),", it will begin syncing back history at this time."]}),"\n",(0,t.jsx)(n.p,{children:"Seeing available block range - Low: 0 High: 0 is normal until the fill tip is downloaded. You can see download progress with a look at metrics:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl -s 127.0.0.1:8888/metrics | grep trie_or_chunk\n# HELP trie_or_chunk_fetch_total number of trie_or_chunk all fetch requests made\n# TYPE trie_or_chunk_fetch_total counter\ntrie_or_chunk_fetch_total 102647\n# HELP trie_or_chunk_found_in_storage number of fetch requests that found trie_or_chunk in local storage\n# TYPE trie_or_chunk_found_in_storage counter\ntrie_or_chunk_found_in_storage 0\n# HELP trie_or_chunk_found_on_peer number of fetch requests that fetched trie_or_chunk from peer\n# TYPE trie_or_chunk_found_on_peer counter\ntrie_or_chunk_found_on_peer 102263\n# HELP trie_or_chunk_timeouts number of trie_or_chunk fetch requests that timed out\n# TYPE trie_or_chunk_timeouts counter\ntrie_or_chunk_timeouts 0\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the node is not showing active (running) status, it is either stopped or in the process of restarting."}),"\n",(0,t.jsx)(n.h3,{id:"monitoring-the-running-node",children:"Monitoring the Running Node"}),"\n",(0,t.jsx)(n.p,{children:"The community has created a few tools to monitor your node once it is running, such as:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Status.py: ",(0,t.jsx)(n.a,{href:"https://github.com/RapidMark/casper-tools",children:"https://github.com/RapidMark/casper-tools"})]}),"\n",(0,t.jsxs)(n.li,{children:["Grafana: ",(0,t.jsx)(n.a,{href:"https://github.com/matsuro-hadouken/casper-tools",children:"https://github.com/matsuro-hadouken/casper-tools"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"a-note-on-speculative-execution",children:"A Note on Speculative Execution"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"speculative_exec_server"})," defaults to off and can be enabled in your ",(0,t.jsx)(n.em,{children:"Config.toml"})," file."]}),"\n",(0,t.jsxs)(n.p,{children:["While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You ",(0,t.jsx)(n.em,{children:(0,t.jsx)(n.strong,{children:"should not"})})," use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const o={},r=t.createContext(o);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/546b5549.3f31a8ae.js b/assets/js/546b5549.3f31a8ae.js new file mode 100644 index 000000000..4eb0ada40 --- /dev/null +++ b/assets/js/546b5549.3f31a8ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91651],{76419:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},r="Fungible Tokens (CEP-18) Implementation and Usage",i={id:"resources/beginner/cep18",title:"Fungible Tokens",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/docs/resources/beginner/cep18.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/cep18",permalink:"/resources/tutorials/beginner/cep18",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},sidebar:"tutorials",previous:{title:"Contract Upgrades",permalink:"/resources/tutorials/beginner/upgrade-contract"},next:{title:"AWS Casper Nodes",permalink:"/resources/tutorials/beginner/aws-node"}},l={},c=[{value:"Outline of the Tutorial",id:"outline",level:2},{value:"ERC-20 Standard",id:"erc20-standard",level:2},{value:"Interaction of ERC-20 Based Tokens with the Uniswap Standard",id:"erc20-uniswap",level:2},{value:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges",id:"erc20-implications",level:2},{value:"The Casper CEP-18 Standard",id:"cep18-standard",level:2},{value:"Creating a CEP-18 Token on the Testnet",id:"cep18-testnet",level:2},{value:"Clone and Compile the CEP-18 Contract",id:"cep18-contract-clone",level:3},{value:"Install the CEP-18 Contract",id:"cep18-contract-install",level:3},{value:"Query the Entry Points in the CEP-18 contract",id:"cep18-contract-clone",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"fungible-tokens-cep-18-implementation-and-usage",children:"Fungible Tokens (CEP-18) Implementation and Usage"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"outline",children:"Outline of the Tutorial"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-standard",children:"ERC-20 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain."}),"\n",(0,s.jsx)(n.p,{children:"It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana.\nSome key points of the ERC-20 standard include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Optional metadata functions like ",(0,s.jsx)(n.code,{children:"name()"}),", ",(0,s.jsx)(n.code,{children:"symbol()"}),", and ",(0,s.jsx)(n.code,{children:"decimals()"}),", which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets.\nBy adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-uniswap",children:"Interaction of ERC-20 Based Tokens with the Uniswap Standard"}),"\n",(0,s.jsx)(n.p,{children:"By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2."}),"\n",(0,s.jsx)(n.p,{children:"Uniswap V2 uses ERC-20 tokens in the following scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Listing Tokens \u2013 Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard."}),"\n",(0,s.jsx)(n.li,{children:"Liquidity Pools \u2013 any two pairs of ERC-20 tokens can be used to create a liquidity pool."}),"\n",(0,s.jsxs)(n.li,{children:["Uniswap V2 uses the ERC-20 standard ",(0,s.jsx)(n.code,{children:"transfer()"})," function to allow an exchange of tokens within the liquidity pools."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erc20-implications",children:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges"}),"\n",(0,s.jsx)(n.p,{children:"There exist at least two different implementations of the ERC-20 Standard on Casper networks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/Rengo-Labs/casper-erc20",children:"Rengo-Labs implementation"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market implementation"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks."}),"\n",(0,s.jsx)(n.p,{children:"The following considerations should be applied when trying to create an ERC-20 Token:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Interoperability \u2013 Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Project Security Audits \u2013 Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ecosystem \u2013 The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities."}),"\n",(0,s.jsx)(n.h2,{id:"cep18-standard",children:"The Casper CEP-18 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"allowance"})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approve"})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance_of"})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"decimals"})," - Returns the decimal places applied to the balance of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," - Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"symbol"})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"total_supply"})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer"})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from"})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more detail on these methods, there is a reference implementation available on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"cep18-testnet",children:"Creating a CEP-18 Token on the Testnet"}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Clone and Compile the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state."}),"\n",(0,s.jsxs)(n.p,{children:["If you are unsure how to interact with Casper Contracts please refer to the following tutorial: ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We will clone the token repository and prepare the token contract for sending in a Deploy."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tgit clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" cd cep18\n make prepare\n make build-contract\n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"build-contract"})," finishes with an error ",(0,s.jsx)(n.code,{children:"wasm-strip: command not found"}),", make sure you install an additional package on MacOS:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" brew install wabt\n"})})]}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tmake test\n"})}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-install",children:"Install the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet."}),"\n",(0,s.jsx)(n.p,{children:"Use the following template to install the contract on the Testnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777 \n\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should obtain a response similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"An exemplary deploy to the Casper Testnet is as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n'})}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Always be mindful of the ",(0,s.jsx)(n.code,{children:"--secret-key"})," and ",(0,s.jsx)(n.code,{children:"--session-path"})," arguments.\nPath provided to the arguments should always be with regard to the current folder, where the command is executed."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"keys"})," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored."]})]}),"\n",(0,s.jsxs)(n.p,{children:["The response from the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command should look like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," the state of the deploy can be checked:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the execution results we can see, that the deploy was successful:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n... \n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,s.jsx)(n.code,{children:"Out of gas error"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Query the Entry Points in the CEP-18 contract"}),"\n",(0,s.jsx)(n.p,{children:"Get the state root hash from the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n"})}),"\n",(0,s.jsx)(n.p,{children:"Your response should look similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The above command will query the contract for the name. The template for the query is ",(0,s.jsx)(n.code,{children:"contract_name/named_key"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You will obtain the following response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Try to query the contract for other Named Keys and check how the contract behaves."}),"\n",(0,s.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,s.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Explained the ERC20 standard and what the implications are for not using the standard implementations."}),"\n",(0,s.jsx)(n.li,{children:"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."}),"\n",(0,s.jsx)(n.li,{children:"Installed the contract on the Testnet"}),"\n",(0,s.jsxs)(n.li,{children:["Called an entry point on the contract to get the value of the Named Key ",(0,s.jsx)(n.code,{children:"name"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/546b5549.588a9376.js b/assets/js/546b5549.588a9376.js deleted file mode 100644 index 5d82652d0..000000000 --- a/assets/js/546b5549.588a9376.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1651],{76419:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},r="Fungible Tokens (CEP-18) Implementation and Usage",i={id:"resources/beginner/cep18",title:"Fungible Tokens",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/docs/resources/beginner/cep18.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/cep18",permalink:"/next/resources/tutorials/beginner/cep18",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},sidebar:"tutorials",previous:{title:"Contract Upgrades",permalink:"/next/resources/tutorials/beginner/upgrade-contract"},next:{title:"AWS Casper Nodes",permalink:"/next/resources/tutorials/beginner/aws-node"}},l={},c=[{value:"Outline of the Tutorial",id:"outline",level:2},{value:"ERC-20 Standard",id:"erc20-standard",level:2},{value:"Interaction of ERC-20 Based Tokens with the Uniswap Standard",id:"erc20-uniswap",level:2},{value:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges",id:"erc20-implications",level:2},{value:"The Casper CEP-18 Standard",id:"cep18-standard",level:2},{value:"Creating a CEP-18 Token on the Testnet",id:"cep18-testnet",level:2},{value:"Clone and Compile the CEP-18 Contract",id:"cep18-contract-clone",level:3},{value:"Install the CEP-18 Contract",id:"cep18-contract-install",level:3},{value:"Query the Entry Points in the CEP-18 contract",id:"cep18-contract-clone",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"fungible-tokens-cep-18-implementation-and-usage",children:"Fungible Tokens (CEP-18) Implementation and Usage"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"outline",children:"Outline of the Tutorial"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-standard",children:"ERC-20 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain."}),"\n",(0,s.jsx)(n.p,{children:"It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana.\nSome key points of the ERC-20 standard include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Optional metadata functions like ",(0,s.jsx)(n.code,{children:"name()"}),", ",(0,s.jsx)(n.code,{children:"symbol()"}),", and ",(0,s.jsx)(n.code,{children:"decimals()"}),", which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets.\nBy adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-uniswap",children:"Interaction of ERC-20 Based Tokens with the Uniswap Standard"}),"\n",(0,s.jsx)(n.p,{children:"By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2."}),"\n",(0,s.jsx)(n.p,{children:"Uniswap V2 uses ERC-20 tokens in the following scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Listing Tokens \u2013 Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard."}),"\n",(0,s.jsx)(n.li,{children:"Liquidity Pools \u2013 any two pairs of ERC-20 tokens can be used to create a liquidity pool."}),"\n",(0,s.jsxs)(n.li,{children:["Uniswap V2 uses the ERC-20 standard ",(0,s.jsx)(n.code,{children:"transfer()"})," function to allow an exchange of tokens within the liquidity pools."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erc20-implications",children:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges"}),"\n",(0,s.jsx)(n.p,{children:"There exist at least two different implementations of the ERC-20 Standard on Casper networks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/Rengo-Labs/casper-erc20",children:"Rengo-Labs implementation"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market implementation"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks."}),"\n",(0,s.jsx)(n.p,{children:"The following considerations should be applied when trying to create an ERC-20 Token:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Interoperability \u2013 Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Project Security Audits \u2013 Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ecosystem \u2013 The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities."}),"\n",(0,s.jsx)(n.h2,{id:"cep18-standard",children:"The Casper CEP-18 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"allowance"})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approve"})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance_of"})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"decimals"})," - Returns the decimal places applied to the balance of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," - Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"symbol"})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"total_supply"})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer"})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from"})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more detail on these methods, there is a reference implementation available on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"cep18-testnet",children:"Creating a CEP-18 Token on the Testnet"}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Clone and Compile the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state."}),"\n",(0,s.jsxs)(n.p,{children:["If you are unsure how to interact with Casper Contracts please refer to the following tutorial: ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We will clone the token repository and prepare the token contract for sending in a Deploy."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tgit clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" cd cep18\n make prepare\n make build-contract\n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"build-contract"})," finishes with an error ",(0,s.jsx)(n.code,{children:"wasm-strip: command not found"}),", make sure you install an additional package on MacOS:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" brew install wabt\n"})})]}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tmake test\n"})}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-install",children:"Install the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet."}),"\n",(0,s.jsx)(n.p,{children:"Use the following template to install the contract on the Testnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777 \n\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should obtain a response similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"An exemplary deploy to the Casper Testnet is as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n'})}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Always be mindful of the ",(0,s.jsx)(n.code,{children:"--secret-key"})," and ",(0,s.jsx)(n.code,{children:"--session-path"})," arguments.\nPath provided to the arguments should always be with regard to the current folder, where the command is executed."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"keys"})," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored."]})]}),"\n",(0,s.jsxs)(n.p,{children:["The response from the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command should look like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," the state of the deploy can be checked:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the execution results we can see, that the deploy was successful:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n... \n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,s.jsx)(n.code,{children:"Out of gas error"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Query the Entry Points in the CEP-18 contract"}),"\n",(0,s.jsx)(n.p,{children:"Get the state root hash from the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n"})}),"\n",(0,s.jsx)(n.p,{children:"Your response should look similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The above command will query the contract for the name. The template for the query is ",(0,s.jsx)(n.code,{children:"contract_name/named_key"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You will obtain the following response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Try to query the contract for other Named Keys and check how the contract behaves."}),"\n",(0,s.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,s.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Explained the ERC20 standard and what the implications are for not using the standard implementations."}),"\n",(0,s.jsx)(n.li,{children:"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."}),"\n",(0,s.jsx)(n.li,{children:"Installed the contract on the Testnet"}),"\n",(0,s.jsxs)(n.li,{children:["Called an entry point on the contract to get the value of the Named Key ",(0,s.jsx)(n.code,{children:"name"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5496fb16.e37b2d67.js b/assets/js/5496fb16.e37b2d67.js new file mode 100644 index 000000000..d6daa73ba --- /dev/null +++ b/assets/js/5496fb16.e37b2d67.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39468],{96588:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=r(74848),t=r(28453);const o={title:"Overview"},i="Interacting with the Casper JSON-RPC API",c={id:"developers/json-rpc/index",title:"Overview",description:"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/index.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/",permalink:"/2.0.0/developers/json-rpc/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Overview"},sidebar:"developers",previous:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/2.0.0/developers/writing-onchain-code/best-practices"},next:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/2.0.0/developers/json-rpc/guidance"}},a={},d=[{value:"Table of Contents",id:"table-of-contents",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"interacting-with-the-casper-json-rpc-api",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses a custom JSON-RPC implementation called ",(0,s.jsx)(n.code,{children:"casper-json-rpc"})," that complies with the ",(0,s.jsx)(n.a,{href:"https://www.jsonrpc.org/specification",children:"JSON-RPC 2.0 specification"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/2.0.0/operators/setup/casper-sidecar",children:"Casper Sidecar"})," service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"})," in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar."]}),"\n",(0,s.jsxs)(n.p,{children:["You can find the latest RPC schema in the Sidecar's ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/test/rpc_schema.json",children:"GitHub repository"}),". "]}),"\n",(0,s.jsxs)(n.p,{children:["The Casper client subcommand ",(0,s.jsx)(n.code,{children:"list-rpcs"})," also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"casper-client list-rpcs --node-address <HOST:PORT>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may use ",(0,s.jsx)(n.a,{href:"https://www.postman.com/",children:"Postman"})," or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification."]}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Page"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/guidance",children:"Guidance for JSON-RPC SDK Compliance"})}),(0,s.jsx)(n.td,{children:"Requirements for a compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/minimal-compliance",children:"Required JSON-RPC Methods for Minimal Compliance"})}),(0,s.jsx)(n.td,{children:"Methods required for a minimally compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-transactional",children:"Transactional JSON-RPC Method"})}),(0,s.jsx)(n.td,{children:"Methods allowing interaction with a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational",children:"Informational JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods returning information about the network from a Casper node"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods pertaining to Proof-of-Stake functionality on a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain",children:"Types"})}),(0,s.jsx)(n.td,{children:"Information on types used within JSON-RPC methods"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_cl",children:"CL Types"})}),(0,s.jsx)(n.td,{children:"Information related to CL Types"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5497691c.3c574e7f.js b/assets/js/5497691c.3c574e7f.js deleted file mode 100644 index 91cd58b38..000000000 --- a/assets/js/5497691c.3c574e7f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4035],{48025:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Getting Started with Rust"},a="Getting Started with Rust Casper Contracts",o={id:"developers/writing-onchain-code/getting-started",title:"Getting Started with Rust",description:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.",source:"@site/docs/developers/writing-onchain-code/getting-started.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/getting-started",permalink:"/next/developers/writing-onchain-code/getting-started",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Getting Started with Rust"},sidebar:"developers",previous:{title:"Introduction",permalink:"/next/writing-contracts"},next:{title:"Getting Started with AssemblyScript",permalink:"/next/developers/writing-onchain-code/assembly-script"}},c={},l=[{value:"Creating a Project",id:"creating-a-project",level:2},{value:"Reproducibility",id:"reproducibility",level:3},{value:"Using the nightly toolchain",id:"using-the-nightly-toolchain",level:3},{value:"Available Casper Rust crates",id:"available-casper-rust-crates",level:3},{value:"Available API documentation",id:"available-api-documentation",level:3},{value:"Compiling to Wasm",id:"compiling-to-wasm",level:2},{value:"Testing the Contract",id:"test-the-contract",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Rust Resources",id:"rust-resources",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started-with-rust-casper-contracts",children:"Getting Started with Rust Casper Contracts"})}),"\n",(0,s.jsx)(t.p,{children:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine."}),"\n",(0,s.jsxs)(t.p,{children:["Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described ",(0,s.jsx)(t.a,{href:"/next/developers/prerequisites",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsxs)(t.p,{children:["You can create a new sample project very easily with the ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate. For example, let's say that I want to create a project named ",(0,s.jsx)(t.strong,{children:"my-project"})," for this tutorial (you can choose a different name if you wish), then I can simply run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If you look inside the newly-created ",(0,s.jsx)(t.em,{children:"my-project"})," folder, you will find two crates: ",(0,s.jsx)(t.code,{children:"contract"})," and ",(0,s.jsx)(t.code,{children:"tests"}),". This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The ",(0,s.jsx)(t.code,{children:"tests"})," crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test."]}),"\n",(0,s.jsx)(t.h3,{id:"reproducibility",children:"Reproducibility"}),"\n",(0,s.jsxs)(t.p,{children:["Currently, ",(0,s.jsx)(t.a,{href:"https://github.com/rust-lang/cargo/issues/8140",children:"cargo"})," does not provide cross-platform reproducibility for binary files, including WebAssembly. The ability to compile a smart contract to the same binary file is important, for example, when verifying that the smart contract binary stored on the blockchain is the same as the provided source code."]}),"\n",(0,s.jsxs)(t.p,{children:["To work around the issue, ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate provides ",(0,s.jsx)(t.code,{children:"rustc"})," wrapper, which can be enabled using ",(0,s.jsx)(t.code,{children:"--wrapper"})," option."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my_project --wrapper\n"})}),"\n",(0,s.jsx)(t.h3,{id:"using-the-nightly-toolchain",children:"Using the nightly toolchain"}),"\n",(0,s.jsxs)(t.p,{children:["Navigate to the ",(0,s.jsx)(t.code,{children:"my-project"})," folder and open the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/channels.html",children:"Rust Documentation on Channels"})," and the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/toolchains.html",children:"Rust Documentation on Toolchains"})," for further information."]}),"\n",(0,s.jsxs)(t.p,{children:["As shown in this example, we recommend setting up the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file in your project's top-level directory."]}),"\n",(0,s.jsx)(t.p,{children:"You can also install the nightly Rust toolchain with this command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,s.jsx)(t.h3,{id:"available-casper-rust-crates",children:"Available Casper Rust crates"}),"\n",(0,s.jsx)(t.p,{children:"To support smart contract development with Rust, the following crates are published:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"casper-contract"})," - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"casper-engine-test-support"})," - a virtual machine against which you can test your smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"casper-types"})," - a library with types we use across the Rust ecosystem."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"A crate is a compilation unit that can be compiled into a binary or a library."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["For a comprehensive list of crates, visit the ",(0,s.jsx)(t.a,{href:"/next/developers/essential-crates",children:"Essential Casper Crates"})," page."]})}),"\n",(0,s.jsx)(t.h3,{id:"available-api-documentation",children:"Available API documentation"}),"\n",(0,s.jsxs)(t.p,{children:["Each of the Casper crates comes with API documentation and examples for each function, located at ",(0,s.jsx)(t.a,{href:"https://docs.rs/releases/search?query=casper",children:"https://docs.rs"}),". The latest contract API documentation can be found ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"compiling-to-wasm",children:"Compiling to Wasm"}),"\n",(0,s.jsx)(t.p,{children:"The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["To compile the smart contract into Wasm, go into the ",(0,s.jsx)(t.em,{children:"my-project"})," folder, and run the following commands:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd my-project\nmake prepare\nmake build-contract\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find the compiled contract on this path: ",(0,s.jsx)(t.code,{children:"my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Linting"})}),"\n",(0,s.jsxs)(t.p,{children:["Casper contracts support Rust tooling such as ",(0,s.jsx)(t.code,{children:"clippy"})," for linting contracts. Feel free to use them! You can also use the ",(0,s.jsx)(t.code,{children:"make check-lint"})," command for linting your contract. Run this command inside the ",(0,s.jsx)(t.em,{children:"my-project"})," folder:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make check-lint\n"})}),"\n",(0,s.jsx)(t.h2,{id:"test-the-contract",children:"Testing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to creating the contract, the Casper crate also automatically created sample tests in the ",(0,s.jsx)(t.em,{children:"my-project/tests"})," folder."]}),"\n",(0,s.jsxs)(t.p,{children:["The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named ",(0,s.jsx)(t.em,{children:"build.rs"})," if you are interested in looking more into it."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Since the test script automatically builds the contract, during development you only need to run the command ",(0,s.jsx)(t.code,{children:"make test"})," without the need for ",(0,s.jsx)(t.code,{children:"make build-contract"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"A successful test run indicates that your smart contract environment is set up correctly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsx)(t.p,{children:"After the compilation finishes, the test should run and you should see output similar to this message in your terminal:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,s.jsxs)(t.p,{children:["As a brief example, open up ",(0,s.jsx)(t.em,{children:"my-project/contract/src/main.rs"})," in your editor, modify the ",(0,s.jsx)(t.em,{children:"KEY_NAME"})," value in the contract, and then rerun the ",(0,s.jsx)(t.code,{children:"make test"})," command. You should observe that the smart contract recompiles and the test fails now."]}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"The following video tutorial complements this guide."}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/aIhA5fPIHus",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"rust-resources",children:"Rust Resources"}),"\n",(0,s.jsx)(t.p,{children:"These Rust resources are excellent and we highly recommend them:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/book/foreword.html",children:"https://doc.rust-lang.org/book/foreword.html"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://rustwasm.github.io/docs/book/",children:"https://rustwasm.github.io/docs/book/"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/stable/rust-by-example",children:"https://doc.rust-lang.org/stable/rust-by-example"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5497691c.7a0da876.js b/assets/js/5497691c.7a0da876.js new file mode 100644 index 000000000..74908ac6a --- /dev/null +++ b/assets/js/5497691c.7a0da876.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24035],{48025:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Getting Started with Rust"},a="Getting Started with Rust Casper Contracts",o={id:"developers/writing-onchain-code/getting-started",title:"Getting Started with Rust",description:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.",source:"@site/docs/developers/writing-onchain-code/getting-started.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/getting-started",permalink:"/developers/writing-onchain-code/getting-started",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Getting Started with Rust"},sidebar:"developers",previous:{title:"Introduction",permalink:"/writing-contracts"},next:{title:"Getting Started with AssemblyScript",permalink:"/developers/writing-onchain-code/assembly-script"}},c={},l=[{value:"Creating a Project",id:"creating-a-project",level:2},{value:"Reproducibility",id:"reproducibility",level:3},{value:"Using the nightly toolchain",id:"using-the-nightly-toolchain",level:3},{value:"Available Casper Rust crates",id:"available-casper-rust-crates",level:3},{value:"Available API documentation",id:"available-api-documentation",level:3},{value:"Compiling to Wasm",id:"compiling-to-wasm",level:2},{value:"Testing the Contract",id:"test-the-contract",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Rust Resources",id:"rust-resources",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started-with-rust-casper-contracts",children:"Getting Started with Rust Casper Contracts"})}),"\n",(0,s.jsx)(t.p,{children:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine."}),"\n",(0,s.jsxs)(t.p,{children:["Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described ",(0,s.jsx)(t.a,{href:"/developers/prerequisites",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsxs)(t.p,{children:["You can create a new sample project very easily with the ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate. For example, let's say that I want to create a project named ",(0,s.jsx)(t.strong,{children:"my-project"})," for this tutorial (you can choose a different name if you wish), then I can simply run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If you look inside the newly-created ",(0,s.jsx)(t.em,{children:"my-project"})," folder, you will find two crates: ",(0,s.jsx)(t.code,{children:"contract"})," and ",(0,s.jsx)(t.code,{children:"tests"}),". This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The ",(0,s.jsx)(t.code,{children:"tests"})," crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test."]}),"\n",(0,s.jsx)(t.h3,{id:"reproducibility",children:"Reproducibility"}),"\n",(0,s.jsxs)(t.p,{children:["Currently, ",(0,s.jsx)(t.a,{href:"https://github.com/rust-lang/cargo/issues/8140",children:"cargo"})," does not provide cross-platform reproducibility for binary files, including WebAssembly. The ability to compile a smart contract to the same binary file is important, for example, when verifying that the smart contract binary stored on the blockchain is the same as the provided source code."]}),"\n",(0,s.jsxs)(t.p,{children:["To work around the issue, ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate provides ",(0,s.jsx)(t.code,{children:"rustc"})," wrapper, which can be enabled using ",(0,s.jsx)(t.code,{children:"--wrapper"})," option."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my_project --wrapper\n"})}),"\n",(0,s.jsx)(t.h3,{id:"using-the-nightly-toolchain",children:"Using the nightly toolchain"}),"\n",(0,s.jsxs)(t.p,{children:["Navigate to the ",(0,s.jsx)(t.code,{children:"my-project"})," folder and open the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/channels.html",children:"Rust Documentation on Channels"})," and the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/toolchains.html",children:"Rust Documentation on Toolchains"})," for further information."]}),"\n",(0,s.jsxs)(t.p,{children:["As shown in this example, we recommend setting up the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file in your project's top-level directory."]}),"\n",(0,s.jsx)(t.p,{children:"You can also install the nightly Rust toolchain with this command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,s.jsx)(t.h3,{id:"available-casper-rust-crates",children:"Available Casper Rust crates"}),"\n",(0,s.jsx)(t.p,{children:"To support smart contract development with Rust, the following crates are published:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"casper-contract"})," - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"casper-engine-test-support"})," - a virtual machine against which you can test your smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"casper-types"})," - a library with types we use across the Rust ecosystem."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"A crate is a compilation unit that can be compiled into a binary or a library."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["For a comprehensive list of crates, visit the ",(0,s.jsx)(t.a,{href:"/developers/essential-crates",children:"Essential Casper Crates"})," page."]})}),"\n",(0,s.jsx)(t.h3,{id:"available-api-documentation",children:"Available API documentation"}),"\n",(0,s.jsxs)(t.p,{children:["Each of the Casper crates comes with API documentation and examples for each function, located at ",(0,s.jsx)(t.a,{href:"https://docs.rs/releases/search?query=casper",children:"https://docs.rs"}),". The latest contract API documentation can be found ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"compiling-to-wasm",children:"Compiling to Wasm"}),"\n",(0,s.jsx)(t.p,{children:"The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["To compile the smart contract into Wasm, go into the ",(0,s.jsx)(t.em,{children:"my-project"})," folder, and run the following commands:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd my-project\nmake prepare\nmake build-contract\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find the compiled contract on this path: ",(0,s.jsx)(t.code,{children:"my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Linting"})}),"\n",(0,s.jsxs)(t.p,{children:["Casper contracts support Rust tooling such as ",(0,s.jsx)(t.code,{children:"clippy"})," for linting contracts. Feel free to use them! You can also use the ",(0,s.jsx)(t.code,{children:"make check-lint"})," command for linting your contract. Run this command inside the ",(0,s.jsx)(t.em,{children:"my-project"})," folder:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make check-lint\n"})}),"\n",(0,s.jsx)(t.h2,{id:"test-the-contract",children:"Testing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to creating the contract, the Casper crate also automatically created sample tests in the ",(0,s.jsx)(t.em,{children:"my-project/tests"})," folder."]}),"\n",(0,s.jsxs)(t.p,{children:["The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named ",(0,s.jsx)(t.em,{children:"build.rs"})," if you are interested in looking more into it."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Since the test script automatically builds the contract, during development you only need to run the command ",(0,s.jsx)(t.code,{children:"make test"})," without the need for ",(0,s.jsx)(t.code,{children:"make build-contract"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"A successful test run indicates that your smart contract environment is set up correctly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsx)(t.p,{children:"After the compilation finishes, the test should run and you should see output similar to this message in your terminal:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,s.jsxs)(t.p,{children:["As a brief example, open up ",(0,s.jsx)(t.em,{children:"my-project/contract/src/main.rs"})," in your editor, modify the ",(0,s.jsx)(t.em,{children:"KEY_NAME"})," value in the contract, and then rerun the ",(0,s.jsx)(t.code,{children:"make test"})," command. You should observe that the smart contract recompiles and the test fails now."]}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"The following video tutorial complements this guide."}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/aIhA5fPIHus",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"rust-resources",children:"Rust Resources"}),"\n",(0,s.jsx)(t.p,{children:"These Rust resources are excellent and we highly recommend them:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/book/foreword.html",children:"https://doc.rust-lang.org/book/foreword.html"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://rustwasm.github.io/docs/book/",children:"https://rustwasm.github.io/docs/book/"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/stable/rust-by-example",children:"https://doc.rust-lang.org/stable/rust-by-example"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/54fcde43.7c8f527d.js b/assets/js/54fcde43.7c8f527d.js new file mode 100644 index 000000000..2d8677714 --- /dev/null +++ b/assets/js/54fcde43.7c8f527d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6107],{56994:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var n=r(74848),a=r(28453);const t={},o="D",c={id:"concepts/glossary/D",title:"D",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/D.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/D",permalink:"/2.0.0/concepts/glossary/D",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"C",permalink:"/2.0.0/concepts/glossary/C"},next:{title:"E",permalink:"/2.0.0/concepts/glossary/E"}},i={},l=[{value:"dApp",id:"dapp",level:2},{value:"Delegation rate",id:"delegation-rate",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Dynamic gas pricing",id:"dynamic-gas-pricing",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"d",children:"D"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"dapp",children:"dApp"}),"\n",(0,n.jsxs)(s.p,{children:["A decentralized application (dApp) employs ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S#smart-contract",children:"smart contracts"})," installed on a decentralized peer-to-peer network such as a blockchain."]}),"\n",(0,n.jsx)(s.h2,{id:"delegation-rate",children:"Delegation rate"}),"\n",(0,n.jsxs)(s.p,{children:["Node operators (",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validators"}),") define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services."]}),"\n",(0,n.jsx)(s.h2,{id:"delegator",children:"Delegator"}),"\n",(0,n.jsx)(s.p,{children:'Delegators are users who participate in the platform\'s security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.'}),"\n",(0,n.jsx)(s.h2,{id:"deploy",children:"Deploy"}),"\n",(0,n.jsx)(s.p,{children:"Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network."}),"\n",(0,n.jsxs)(s.p,{children:["Casper's Condor release introduces the ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"Transaction"}),". Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected."]}),"\n",(0,n.jsxs)(s.p,{children:["All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Review the ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/serialization/structures#serialization-standard-deploy",children:"deploy data structure"})," and the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/master/node/src/types/deploy.rs#L475",children:"deploy implementation"})," for more details."]}),"\n",(0,n.jsx)(s.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,n.jsxs)(s.p,{children:["A ",(0,n.jsx)(s.code,{children:"Dictionary"})," is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N#named-keys",children:(0,n.jsx)(s.code,{children:"NamedKeys"})}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["More information can be found in the ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," document."]}),"\n",(0,n.jsx)(s.h2,{id:"dynamic-gas-pricing",children:"Dynamic gas pricing"}),"\n",(0,n.jsxs)(s.p,{children:["Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/economics/dynamic-gas-pricing",children:"here"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>c});var n=r(96540);const a={},t=n.createContext(a);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55568807.2e91d1c2.js b/assets/js/55568807.2e91d1c2.js deleted file mode 100644 index 5c10cd3d4..000000000 --- a/assets/js/55568807.2e91d1c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7543],{71870:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>n,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var t=r(74848),c=r(28453);const a={},n="Essential Rust Crates",i={id:"developers/essential-crates",title:"Essential Rust Crates",description:"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.",source:"@site/versioned_docs/version-1.5.X/developers/essential-crates.md",sourceDirName:"developers",slug:"/developers/essential-crates",permalink:"/developers/essential-crates",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Development Prerequisites",permalink:"/developers/prerequisites"},next:{title:"Introduction",permalink:"/writing-contracts"}},l={},d=[{value:"<code>casper-types</code>",id:"casper-types",level:2},{value:"<code>casper-contract</code>",id:"casper-contract",level:2},{value:"<code>casper-engine-test-support</code>",id:"casper-engine-test-support",level:2},{value:"<code>casper-node</code>",id:"casper-node",level:2},{value:"<code>casper-client</code>",id:"casper-client",level:2},{value:"<code>casper-event-standard</code>",id:"casper-event-standard",level:2},{value:"<code>casper-hashing</code>",id:"casper-hashing",level:2},{value:"<code>casper-wasm-utils</code>",id:"casper-wasm-utils",level:2},{value:"<code>cargo-casper</code>",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"essential-rust-crates",children:"Essential Rust Crates"})}),"\n",(0,t.jsxs)(s.p,{children:["Several Rust crates are available on ",(0,t.jsx)(s.a,{href:"https://crates.io/",children:"crates.io"})," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,t.jsx)(s.a,{href:"https://docs.rs",children:"docs.rs"}),". The most important crates are listed below."]}),"\n",(0,t.jsx)(s.h2,{id:"casper-types",children:(0,t.jsx)(s.code,{children:"casper-types"})}),"\n",(0,t.jsx)(s.p,{children:"Types shared by many Casper crates:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-types",children:"https://crates.io/crates/casper-types"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-types/latest",children:"https://docs.rs/casper-types/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-contract",children:(0,t.jsx)(s.code,{children:"casper-contract"})}),"\n",(0,t.jsx)(s.p,{children:"A library for developing Casper smart contracts:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-contract",children:"https://crates.io/crates/casper-contract"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-contract/latest",children:"https://docs.rs/casper-contract/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-engine-test-support",children:(0,t.jsx)(s.code,{children:"casper-engine-test-support"})}),"\n",(0,t.jsx)(s.p,{children:"The Casper test support library:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"https://crates.io/crates/casper-engine-test-support"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"https://docs.rs/casper-engine-test-support/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-node",children:(0,t.jsx)(s.code,{children:"casper-node"})}),"\n",(0,t.jsx)(s.p,{children:"The component for running a node on a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-node",children:"https://crates.io/crates/casper-node"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-node/latest",children:"https://docs.rs/casper-node/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-client",children:(0,t.jsx)(s.code,{children:"casper-client"})}),"\n",(0,t.jsx)(s.p,{children:"A client library for interacting with a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-client",children:"https://crates.io/crates/casper-client"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-client/latest",children:"https://docs.rs/casper-client/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-event-standard",children:(0,t.jsx)(s.code,{children:"casper-event-standard"})}),"\n",(0,t.jsx)(s.p,{children:"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-event-standard",children:"https://crates.io/crates/casper-event-standard"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-event-standard/latest",children:"https://docs.rs/casper-event-standard/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-hashing",children:(0,t.jsx)(s.code,{children:"casper-hashing"})}),"\n",(0,t.jsx)(s.p,{children:"A library providing hashing functionality including Merkle Proof utilities:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-hashing",children:"https://crates.io/crates/casper-hashing"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-hashing/latest/",children:"https://docs.rs/casper-hashing/latest/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-wasm-utils",children:(0,t.jsx)(s.code,{children:"casper-wasm-utils"})}),"\n",(0,t.jsx)(s.p,{children:"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-wasm-utils",children:"https://crates.io/crates/casper-wasm-utils"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-wasm-utils/latest",children:"https://docs.rs/casper-wasm-utils/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cargo-casper",children:(0,t.jsx)(s.code,{children:"cargo-casper"})}),"\n",(0,t.jsx)(s.p,{children:"A command line tool for creating a Wasm smart contract and tests:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/cargo-casper",children:"https://crates.io/crates/cargo-casper"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/crate/cargo-casper/latest",children:"https://docs.rs/crate/cargo-casper/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"other-libraries",children:"Other Libraries"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Open-Source Software"})," page provides other community-curated tools and libraries."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>n,x:()=>i});var t=r(96540);const c={},a=t.createContext(c);function n(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/55568807.da999a9a.js b/assets/js/55568807.da999a9a.js new file mode 100644 index 000000000..d4cba6d86 --- /dev/null +++ b/assets/js/55568807.da999a9a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[77543],{71870:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>n,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var t=r(74848),c=r(28453);const a={},n="Essential Rust Crates",i={id:"developers/essential-crates",title:"Essential Rust Crates",description:"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.",source:"@site/versioned_docs/version-1.5.X/developers/essential-crates.md",sourceDirName:"developers",slug:"/developers/essential-crates",permalink:"/1.5.X/developers/essential-crates",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Development Prerequisites",permalink:"/1.5.X/developers/prerequisites"},next:{title:"Introduction",permalink:"/1.5.X/writing-contracts"}},l={},d=[{value:"<code>casper-types</code>",id:"casper-types",level:2},{value:"<code>casper-contract</code>",id:"casper-contract",level:2},{value:"<code>casper-engine-test-support</code>",id:"casper-engine-test-support",level:2},{value:"<code>casper-node</code>",id:"casper-node",level:2},{value:"<code>casper-client</code>",id:"casper-client",level:2},{value:"<code>casper-event-standard</code>",id:"casper-event-standard",level:2},{value:"<code>casper-hashing</code>",id:"casper-hashing",level:2},{value:"<code>casper-wasm-utils</code>",id:"casper-wasm-utils",level:2},{value:"<code>cargo-casper</code>",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"essential-rust-crates",children:"Essential Rust Crates"})}),"\n",(0,t.jsxs)(s.p,{children:["Several Rust crates are available on ",(0,t.jsx)(s.a,{href:"https://crates.io/",children:"crates.io"})," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,t.jsx)(s.a,{href:"https://docs.rs",children:"docs.rs"}),". The most important crates are listed below."]}),"\n",(0,t.jsx)(s.h2,{id:"casper-types",children:(0,t.jsx)(s.code,{children:"casper-types"})}),"\n",(0,t.jsx)(s.p,{children:"Types shared by many Casper crates:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-types",children:"https://crates.io/crates/casper-types"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-types/latest",children:"https://docs.rs/casper-types/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-contract",children:(0,t.jsx)(s.code,{children:"casper-contract"})}),"\n",(0,t.jsx)(s.p,{children:"A library for developing Casper smart contracts:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-contract",children:"https://crates.io/crates/casper-contract"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-contract/latest",children:"https://docs.rs/casper-contract/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-engine-test-support",children:(0,t.jsx)(s.code,{children:"casper-engine-test-support"})}),"\n",(0,t.jsx)(s.p,{children:"The Casper test support library:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"https://crates.io/crates/casper-engine-test-support"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"https://docs.rs/casper-engine-test-support/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-node",children:(0,t.jsx)(s.code,{children:"casper-node"})}),"\n",(0,t.jsx)(s.p,{children:"The component for running a node on a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-node",children:"https://crates.io/crates/casper-node"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-node/latest",children:"https://docs.rs/casper-node/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-client",children:(0,t.jsx)(s.code,{children:"casper-client"})}),"\n",(0,t.jsx)(s.p,{children:"A client library for interacting with a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-client",children:"https://crates.io/crates/casper-client"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-client/latest",children:"https://docs.rs/casper-client/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-event-standard",children:(0,t.jsx)(s.code,{children:"casper-event-standard"})}),"\n",(0,t.jsx)(s.p,{children:"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-event-standard",children:"https://crates.io/crates/casper-event-standard"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-event-standard/latest",children:"https://docs.rs/casper-event-standard/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-hashing",children:(0,t.jsx)(s.code,{children:"casper-hashing"})}),"\n",(0,t.jsx)(s.p,{children:"A library providing hashing functionality including Merkle Proof utilities:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-hashing",children:"https://crates.io/crates/casper-hashing"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-hashing/latest/",children:"https://docs.rs/casper-hashing/latest/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-wasm-utils",children:(0,t.jsx)(s.code,{children:"casper-wasm-utils"})}),"\n",(0,t.jsx)(s.p,{children:"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-wasm-utils",children:"https://crates.io/crates/casper-wasm-utils"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-wasm-utils/latest",children:"https://docs.rs/casper-wasm-utils/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cargo-casper",children:(0,t.jsx)(s.code,{children:"cargo-casper"})}),"\n",(0,t.jsx)(s.p,{children:"A command line tool for creating a Wasm smart contract and tests:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/cargo-casper",children:"https://crates.io/crates/cargo-casper"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/crate/cargo-casper/latest",children:"https://docs.rs/crate/cargo-casper/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"other-libraries",children:"Other Libraries"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/1.5.X/resources/build-on-casper/casper-open-source-software",children:"Open-Source Software"})," page provides other community-curated tools and libraries."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>n,x:()=>i});var t=r(96540);const c={},a=t.createContext(c);function n(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/555a4473.0aea839c.js b/assets/js/555a4473.0aea839c.js deleted file mode 100644 index 2113197c7..000000000 --- a/assets/js/555a4473.0aea839c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9861],{45493:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Getting Started with Rust"},a="Getting Started with Rust Casper Contracts",o={id:"developers/writing-onchain-code/getting-started",title:"Getting Started with Rust",description:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/getting-started.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/getting-started",permalink:"/developers/writing-onchain-code/getting-started",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Getting Started with Rust"},sidebar:"developers",previous:{title:"Introduction",permalink:"/writing-contracts"},next:{title:"Getting Started with AssemblyScript",permalink:"/developers/writing-onchain-code/assembly-script"}},c={},l=[{value:"Creating a Project",id:"creating-a-project",level:2},{value:"Using the nightly toolchain",id:"using-the-nightly-toolchain",level:3},{value:"Available Casper Rust crates",id:"available-casper-rust-crates",level:3},{value:"Available API documentation",id:"available-api-documentation",level:3},{value:"Compiling to Wasm",id:"compiling-to-wasm",level:2},{value:"Testing the Contract",id:"test-the-contract",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Rust Resources",id:"rust-resources",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started-with-rust-casper-contracts",children:"Getting Started with Rust Casper Contracts"})}),"\n",(0,s.jsx)(t.p,{children:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine."}),"\n",(0,s.jsxs)(t.p,{children:["Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described ",(0,s.jsx)(t.a,{href:"/developers/prerequisites",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsxs)(t.p,{children:["You can create a new sample project very easily with the ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate. For example, let's say that I want to create a project named ",(0,s.jsx)(t.strong,{children:"my-project"})," for this tutorial (you can choose a different name if you wish), then I can simply run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If you look inside the newly-created ",(0,s.jsx)(t.em,{children:"my-project"})," folder, you will find two crates: ",(0,s.jsx)(t.code,{children:"contract"})," and ",(0,s.jsx)(t.code,{children:"tests"}),". This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The ",(0,s.jsx)(t.code,{children:"tests"})," crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test."]}),"\n",(0,s.jsx)(t.h3,{id:"using-the-nightly-toolchain",children:"Using the nightly toolchain"}),"\n",(0,s.jsxs)(t.p,{children:["Navigate to the ",(0,s.jsx)(t.code,{children:"my-project"})," folder and open the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/channels.html",children:"Rust Documentation on Channels"})," and the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/toolchains.html",children:"Rust Documentation on Toolchains"})," for further information."]}),"\n",(0,s.jsxs)(t.p,{children:["As shown in this example, we recommend setting up the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file in your project's top-level directory."]}),"\n",(0,s.jsx)(t.p,{children:"You can also install the nightly Rust toolchain with this command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,s.jsx)(t.h3,{id:"available-casper-rust-crates",children:"Available Casper Rust crates"}),"\n",(0,s.jsx)(t.p,{children:"To support smart contract development with Rust, the following crates are published:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"casper-contract"})," - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"casper-engine-test-support"})," - a virtual machine against which you can test your smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"casper-types"})," - a library with types we use across the Rust ecosystem."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"A crate is a compilation unit that can be compiled into a binary or a library."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["For a comprehensive list of crates, visit the ",(0,s.jsx)(t.a,{href:"/developers/essential-crates",children:"Essential Casper Crates"})," page."]})}),"\n",(0,s.jsx)(t.h3,{id:"available-api-documentation",children:"Available API documentation"}),"\n",(0,s.jsxs)(t.p,{children:["Each of the Casper crates comes with API documentation and examples for each function, located at ",(0,s.jsx)(t.a,{href:"https://docs.rs/releases/search?query=casper",children:"https://docs.rs"}),". The latest contract API documentation can be found ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"compiling-to-wasm",children:"Compiling to Wasm"}),"\n",(0,s.jsx)(t.p,{children:"The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["To compile the smart contract into Wasm, go into the ",(0,s.jsx)(t.em,{children:"my-project"})," folder, and run the following commands:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd my-project\nmake prepare\nmake build-contract\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find the compiled contract on this path: ",(0,s.jsx)(t.code,{children:"my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Linting"})}),"\n",(0,s.jsxs)(t.p,{children:["Casper contracts support Rust tooling such as ",(0,s.jsx)(t.code,{children:"clippy"})," for linting contracts. Feel free to use them! You can also use the ",(0,s.jsx)(t.code,{children:"make check-lint"})," command for linting your contract. Run this command inside the ",(0,s.jsx)(t.em,{children:"my-project"})," folder:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make check-lint\n"})}),"\n",(0,s.jsx)(t.h2,{id:"test-the-contract",children:"Testing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to creating the contract, the Casper crate also automatically created sample tests in the ",(0,s.jsx)(t.em,{children:"my-project/tests"})," folder."]}),"\n",(0,s.jsxs)(t.p,{children:["The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named ",(0,s.jsx)(t.em,{children:"build.rs"})," if you are interested in looking more into it."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Since the test script automatically builds the contract, during development you only need to run the command ",(0,s.jsx)(t.code,{children:"make test"})," without the need for ",(0,s.jsx)(t.code,{children:"make build-contract"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"A successful test run indicates that your smart contract environment is set up correctly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsx)(t.p,{children:"After the compilation finishes, the test should run and you should see output similar to this message in your terminal:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,s.jsxs)(t.p,{children:["As a brief example, open up ",(0,s.jsx)(t.em,{children:"my-project/contract/src/main.rs"})," in your editor, modify the ",(0,s.jsx)(t.em,{children:"KEY_NAME"})," value in the contract, and then rerun the ",(0,s.jsx)(t.code,{children:"make test"})," command. You should observe that the smart contract recompiles and the test fails now."]}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"The following video tutorial complements this guide."}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/aIhA5fPIHus",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"rust-resources",children:"Rust Resources"}),"\n",(0,s.jsx)(t.p,{children:"These Rust resources are excellent and we highly recommend them:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/book/foreword.html",children:"https://doc.rust-lang.org/book/foreword.html"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://rustwasm.github.io/docs/book/",children:"https://rustwasm.github.io/docs/book/"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/stable/rust-by-example",children:"https://doc.rust-lang.org/stable/rust-by-example"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/555a4473.fbed11b1.js b/assets/js/555a4473.fbed11b1.js new file mode 100644 index 000000000..6b53c43ff --- /dev/null +++ b/assets/js/555a4473.fbed11b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29861],{45493:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Getting Started with Rust"},a="Getting Started with Rust Casper Contracts",o={id:"developers/writing-onchain-code/getting-started",title:"Getting Started with Rust",description:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/getting-started.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/getting-started",permalink:"/1.5.X/developers/writing-onchain-code/getting-started",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Getting Started with Rust"},sidebar:"developers",previous:{title:"Introduction",permalink:"/1.5.X/writing-contracts"},next:{title:"Getting Started with AssemblyScript",permalink:"/1.5.X/developers/writing-onchain-code/assembly-script"}},c={},l=[{value:"Creating a Project",id:"creating-a-project",level:2},{value:"Using the nightly toolchain",id:"using-the-nightly-toolchain",level:3},{value:"Available Casper Rust crates",id:"available-casper-rust-crates",level:3},{value:"Available API documentation",id:"available-api-documentation",level:3},{value:"Compiling to Wasm",id:"compiling-to-wasm",level:2},{value:"Testing the Contract",id:"test-the-contract",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Rust Resources",id:"rust-resources",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"getting-started-with-rust-casper-contracts",children:"Getting Started with Rust Casper Contracts"})}),"\n",(0,s.jsx)(t.p,{children:"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine."}),"\n",(0,s.jsxs)(t.p,{children:["Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/prerequisites",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsxs)(t.p,{children:["You can create a new sample project very easily with the ",(0,s.jsx)(t.code,{children:"cargo casper"})," crate. For example, let's say that I want to create a project named ",(0,s.jsx)(t.strong,{children:"my-project"})," for this tutorial (you can choose a different name if you wish), then I can simply run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,s.jsxs)(t.p,{children:["If you look inside the newly-created ",(0,s.jsx)(t.em,{children:"my-project"})," folder, you will find two crates: ",(0,s.jsx)(t.code,{children:"contract"})," and ",(0,s.jsx)(t.code,{children:"tests"}),". This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The ",(0,s.jsx)(t.code,{children:"tests"})," crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test."]}),"\n",(0,s.jsx)(t.h3,{id:"using-the-nightly-toolchain",children:"Using the nightly toolchain"}),"\n",(0,s.jsxs)(t.p,{children:["Navigate to the ",(0,s.jsx)(t.code,{children:"my-project"})," folder and open the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Having the latest nightly toolchain to develop smart contracts in Rust would be best. Please refer to the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/channels.html",children:"Rust Documentation on Channels"})," and the ",(0,s.jsx)(t.a,{href:"https://rust-lang.github.io/rustup/concepts/toolchains.html",children:"Rust Documentation on Toolchains"})," for further information."]}),"\n",(0,s.jsxs)(t.p,{children:["As shown in this example, we recommend setting up the ",(0,s.jsx)(t.code,{children:"rust-toolchain"})," file in your project's top-level directory."]}),"\n",(0,s.jsx)(t.p,{children:"You can also install the nightly Rust toolchain with this command:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,s.jsx)(t.h3,{id:"available-casper-rust-crates",children:"Available Casper Rust crates"}),"\n",(0,s.jsx)(t.p,{children:"To support smart contract development with Rust, the following crates are published:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"casper-contract"})," - a library supporting communication with the blockchain. This is the main library you will need to write smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"casper-engine-test-support"})," - a virtual machine against which you can test your smart contracts."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"casper-types"})," - a library with types we use across the Rust ecosystem."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"A crate is a compilation unit that can be compiled into a binary or a library."}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["For a comprehensive list of crates, visit the ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/essential-crates",children:"Essential Casper Crates"})," page."]})}),"\n",(0,s.jsx)(t.h3,{id:"available-api-documentation",children:"Available API documentation"}),"\n",(0,s.jsxs)(t.p,{children:["Each of the Casper crates comes with API documentation and examples for each function, located at ",(0,s.jsx)(t.a,{href:"https://docs.rs/releases/search?query=casper",children:"https://docs.rs"}),". The latest contract API documentation can be found ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"compiling-to-wasm",children:"Compiling to Wasm"}),"\n",(0,s.jsx)(t.p,{children:"The Casper blockchain uses WebAssembly (Wasm) in its runtime environment. Compilation targets for Wasm are available for Rust, giving developers access to all the Rust ecosystem tools when developing smart contracts."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Note: Wasm allows for the use of other languages, including but not limited to: C/C++, C#, Go, Julia, Lobster and ZIG."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["To compile the smart contract into Wasm, go into the ",(0,s.jsx)(t.em,{children:"my-project"})," folder, and run the following commands:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd my-project\nmake prepare\nmake build-contract\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find the compiled contract on this path: ",(0,s.jsx)(t.code,{children:"my-project/contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Linting"})}),"\n",(0,s.jsxs)(t.p,{children:["Casper contracts support Rust tooling such as ",(0,s.jsx)(t.code,{children:"clippy"})," for linting contracts. Feel free to use them! You can also use the ",(0,s.jsx)(t.code,{children:"make check-lint"})," command for linting your contract. Run this command inside the ",(0,s.jsx)(t.em,{children:"my-project"})," folder:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make check-lint\n"})}),"\n",(0,s.jsx)(t.h2,{id:"test-the-contract",children:"Testing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["In addition to creating the contract, the Casper crate also automatically created sample tests in the ",(0,s.jsx)(t.em,{children:"my-project/tests"})," folder."]}),"\n",(0,s.jsxs)(t.p,{children:["The Casper local environment provides a virtual machine against which you can run your contract for testing. When you run the test crate, it will automatically build the smart contract in release mode and then run a series of tests against it in the Casper runtime environment. The custom build script is named ",(0,s.jsx)(t.em,{children:"build.rs"})," if you are interested in looking more into it."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Since the test script automatically builds the contract, during development you only need to run the command ",(0,s.jsx)(t.code,{children:"make test"})," without the need for ",(0,s.jsx)(t.code,{children:"make build-contract"}),"."]})}),"\n",(0,s.jsx)(t.p,{children:"A successful test run indicates that your smart contract environment is set up correctly."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsx)(t.p,{children:"After the compilation finishes, the test should run and you should see output similar to this message in your terminal:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,s.jsxs)(t.p,{children:["As a brief example, open up ",(0,s.jsx)(t.em,{children:"my-project/contract/src/main.rs"})," in your editor, modify the ",(0,s.jsx)(t.em,{children:"KEY_NAME"})," value in the contract, and then rerun the ",(0,s.jsx)(t.code,{children:"make test"})," command. You should observe that the smart contract recompiles and the test fails now."]}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsx)(t.p,{children:"The following video tutorial complements this guide."}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/aIhA5fPIHus",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"rust-resources",children:"Rust Resources"}),"\n",(0,s.jsx)(t.p,{children:"These Rust resources are excellent and we highly recommend them:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/book/foreword.html",children:"https://doc.rust-lang.org/book/foreword.html"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://rustwasm.github.io/docs/book/",children:"https://rustwasm.github.io/docs/book/"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"https://doc.rust-lang.org/stable/rust-by-example",children:"https://doc.rust-lang.org/stable/rust-by-example"})}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/559dc838.8f1fde69.js b/assets/js/559dc838.8f1fde69.js new file mode 100644 index 000000000..c865d9a64 --- /dev/null +++ b/assets/js/559dc838.8f1fde69.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94686],{67092:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var n=r(74848),o=r(28453);const c={},t="V",a={id:"concepts/glossary/V",title:"V",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/V.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/V",permalink:"/2.0.0/concepts/glossary/V",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"U",permalink:"/2.0.0/concepts/glossary/U"},next:{title:"W",permalink:"/2.0.0/concepts/glossary/W"}},l={},i=[{value:"Validator",id:"validator",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"v",children:"V"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"validator",children:"Validator"}),"\n",(0,n.jsx)(s.p,{children:'Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.'}),"\n",(0,n.jsx)(s.p,{children:"The responsibilities of a validator include:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block-creation",children:"block creation"})," and ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block-proposal",children:"block proposal"})]}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block-validation",children:"block validation"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block-gossiping",children:"block gossiping"})}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S#staker",children:"stakers"})," can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const o={},c=n.createContext(o);function t(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/560adf9d.033a09e9.js b/assets/js/560adf9d.033a09e9.js deleted file mode 100644 index 4358e64b5..000000000 --- a/assets/js/560adf9d.033a09e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1574],{41711:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=n(74848),s=n(28453);const a={},r="Casper-Client Commands",i={id:"resources/beginner/counter/commands",title:"Casper-Client Commands",description:"Faucet Account Information",source:"@site/docs/resources/beginner/counter/commands.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/commands",permalink:"/next/resources/beginner/counter/commands",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/next/resources/beginner/counter/overview"},next:{title:"Tutorial Walkthrough",permalink:"/next/resources/beginner/counter/walkthrough"}},c={},l=[{value:"Faucet Account Information",id:"faucet-account-information",level:2},{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,o.jsx)(t.h2,{id:"faucet-account-information",children:"Faucet Account Information"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"nctl-view-faucet-account\n"})}),"\n",(0,o.jsxs)(t.p,{children:["This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's ",(0,o.jsx)(t.em,{children:"secret key"})," location and the ",(0,o.jsx)(t.em,{children:"account hash"}),", which are used to sign deploys and query the network state, respectively."]}),"\n",(0,o.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,o.jsxs)(t.p,{children:["The first command to cover is the ",(0,o.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,o.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,o.jsx)(t.admonition,{type:"note",children:(0,o.jsx)(t.p,{children:"After sending 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."})}),"\n",(0,o.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,o.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,o.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"node-address"})," is the location of the RPC endpoint, which is typically represented in the form ",(0,o.jsx)(t.code,{children:"http://IP:PORT"}),". In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is ",(0,o.jsx)(t.code,{children:"http://localhost:11101"}),"."]}),"\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,o.jsxs)(t.li,{children:["The optional query path argument (",(0,o.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,o.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,o.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,o.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,o.jsx)(t.em,{children:"chain-name"}),'. By default, NCTL names the chain "casper-net-1" but this is configurable.']}),"\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,o.jsxs)(t.p,{children:["This second usage of ",(0,o.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,o.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,o.jsx)(t.a,{href:"/next/resources/beginner/counter/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,o.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,o.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,o.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,o.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/560adf9d.05f652ff.js b/assets/js/560adf9d.05f652ff.js new file mode 100644 index 000000000..8904d292c --- /dev/null +++ b/assets/js/560adf9d.05f652ff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[81574],{41711:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var o=n(74848),s=n(28453);const a={},r="Casper-Client Commands",i={id:"resources/beginner/counter/commands",title:"Casper-Client Commands",description:"Faucet Account Information",source:"@site/docs/resources/beginner/counter/commands.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/commands",permalink:"/resources/beginner/counter/commands",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/beginner/counter/overview"},next:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter/walkthrough"}},c={},l=[{value:"Faucet Account Information",id:"faucet-account-information",level:2},{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,o.jsx)(t.h2,{id:"faucet-account-information",children:"Faucet Account Information"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"nctl-view-faucet-account\n"})}),"\n",(0,o.jsxs)(t.p,{children:["This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's ",(0,o.jsx)(t.em,{children:"secret key"})," location and the ",(0,o.jsx)(t.em,{children:"account hash"}),", which are used to sign deploys and query the network state, respectively."]}),"\n",(0,o.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,o.jsxs)(t.p,{children:["The first command to cover is the ",(0,o.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,o.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,o.jsx)(t.admonition,{type:"note",children:(0,o.jsx)(t.p,{children:"After sending 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."})}),"\n",(0,o.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,o.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,o.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"node-address"})," is the location of the RPC endpoint, which is typically represented in the form ",(0,o.jsx)(t.code,{children:"http://IP:PORT"}),". In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is ",(0,o.jsx)(t.code,{children:"http://localhost:11101"}),"."]}),"\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,o.jsxs)(t.li,{children:["The optional query path argument (",(0,o.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,o.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,o.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,o.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,o.jsx)(t.em,{children:"chain-name"}),'. By default, NCTL names the chain "casper-net-1" but this is configurable.']}),"\n",(0,o.jsxs)(t.li,{children:["The ",(0,o.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,o.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,o.jsxs)(t.p,{children:["This second usage of ",(0,o.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,o.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,o.jsx)(t.a,{href:"/resources/beginner/counter/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,o.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,o.jsxs)(t.p,{children:["The ",(0,o.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,o.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,o.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,o.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5611a8f0.95614330.js b/assets/js/5611a8f0.95614330.js new file mode 100644 index 000000000..dca15c531 --- /dev/null +++ b/assets/js/5611a8f0.95614330.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98069],{39981:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Y",a={id:"concepts/glossary/Y",title:"Y",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/Y.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Y",permalink:"/2.0.0/concepts/glossary/Y",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"X",permalink:"/2.0.0/concepts/glossary/X"},next:{title:"Z",permalink:"/2.0.0/concepts/glossary/Z"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"y",children:"Y"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/56746dcb.51ad8181.js b/assets/js/56746dcb.51ad8181.js new file mode 100644 index 000000000..822421127 --- /dev/null +++ b/assets/js/56746dcb.51ad8181.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80690],{29010:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const o={title:"Runtime",slug:"/runtime"},a="Runtime Economics",r={id:"concepts/economics/runtime",title:"Runtime",description:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/runtime.md",sourceDirName:"concepts/economics",slug:"/runtime",permalink:"/1.5.X/runtime",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Runtime",slug:"/runtime"},sidebar:"concepts",previous:{title:"Consensus",permalink:"/1.5.X/concepts/economics/consensus"},next:{title:"Gas Cost",permalink:"/1.5.X/concepts/economics/gas-concepts"}},c={},l=[{value:"Gas allocation",id:"gas-allocation",level:2},{value:"Consensus before execution & basics of payment",id:"consensus-before-execution--basics-of-payment",level:3},{value:"Costs and limits",id:"costs-and-limits",level:3},{value:"Lanes",id:"lanes",level:3},{value:"Gas fees",id:"gas-fees",level:2},{value:"Fee allocation",id:"fee-allocation",level:3},{value:"Spot pricing",id:"spot-pricing",level:3},{value:"Futures pricing",id:"futures-pricing",level:3}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",sup:"sup",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"runtime-economics",children:"Runtime Economics"})}),"\n",(0,s.jsxs)(t.p,{children:["The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/economics/gas-concepts",children:"gas"})," is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/10",(0,s.jsx)(t.sup,{children:"9"})," part of a CSPR token) per 1 unit of gas."]}),"\n",(0,s.jsx)(t.h2,{id:"gas-allocation",children:"Gas allocation"}),"\n",(0,s.jsxs)(t.p,{children:["Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas. We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps",children:"CEPs"}),". In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme."]}),"\n",(0,s.jsx)(t.h3,{id:"consensus-before-execution--basics-of-payment",children:"Consensus before execution & basics of payment"}),"\n",(0,s.jsxs)(t.p,{children:["The Highway protocol in its Mainnet implementation reaches consensus on a block ",(0,s.jsx)(t.em,{children:"before"})," the block is executed, introducing a subtle difference from platforms like Ethereum. In addition, deploys sent to a Casper network can only be selected based on claimed, rather than used, gas. Consequently, to incentivize user-side optimization and prevent block space exhaustion by poorly optimized deploys, the platform provides no refunds for unused gas."]}),"\n",(0,s.jsx)(t.p,{children:"Additionally, a minimal amount of CSPR must be present in the user account's main purse to ensure that the payment computation is covered. The community may introduce additional balance checks in the future."}),"\n",(0,s.jsx)(t.h3,{id:"costs-and-limits",children:"Costs and limits"}),"\n",(0,s.jsxs)(t.p,{children:["Gas cost is a measure of relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific more complex ",(0,s.jsx)(t.em,{children:"host-side"})," functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"})," and may vary according to arguments."]}),"\n",(0,s.jsx)(t.p,{children:"We expect to refine the current gas cost table to reflect time use more closely, with updates introduced in future upgrades. We also anticipate that, with the introduction of state pruning, storage costs will be calculated separately from computing time."}),"\n",(0,s.jsx)(t.h3,{id:"lanes",children:"Lanes"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/b94c4f79ac4ca00e996c418dcc3a98607779a193/resources/production/chainspec.toml#L96-L97",children:"block gas limit"})," is split into two lanes, one for native transfers and one for general deploys. The number of transfers, which cost a fixed amount of gas, is governed directly by the ",(0,s.jsx)(t.code,{children:"block_max_transfer_count"})," chainspec parameter, set to 2500 when Mainnet launched."]}),"\n",(0,s.jsx)(t.h2,{id:"gas-fees",children:"Gas fees"}),"\n",(0,s.jsx)(t.p,{children:"Currently, the price of gas is fixed at 1 mote per 1 unit of gas."}),"\n",(0,s.jsx)(t.h3,{id:"fee-allocation",children:"Fee allocation"}),"\n",(0,s.jsx)(t.p,{children:"All fees from a particular block accrue to its proposer, incentivizing non-empty block production and allowing major dApps to execute deploys for free, provided they operate a validator node and are comfortable with the latency introduced by validator scheduling."}),"\n",(0,s.jsx)(t.h3,{id:"spot-pricing",children:"Spot pricing"}),"\n",(0,s.jsxs)(t.p,{children:["Please see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/22",children:"CEP #22"})," for one potential design of a gas spot market."]}),"\n",(0,s.jsx)(t.h3,{id:"futures-pricing",children:"Futures pricing"}),"\n",(0,s.jsxs)(t.p,{children:["Please see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/17",children:"CEP #17"})," for our draft proposal of a gas futures market."]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56746dcb.f4900217.js b/assets/js/56746dcb.f4900217.js deleted file mode 100644 index d9d98b5be..000000000 --- a/assets/js/56746dcb.f4900217.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[690],{29010:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const o={title:"Runtime",slug:"/runtime"},a="Runtime Economics",r={id:"concepts/economics/runtime",title:"Runtime",description:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/runtime.md",sourceDirName:"concepts/economics",slug:"/runtime",permalink:"/runtime",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Runtime",slug:"/runtime"},sidebar:"concepts",previous:{title:"Consensus",permalink:"/concepts/economics/consensus"},next:{title:"Gas Cost",permalink:"/concepts/economics/gas-concepts"}},c={},l=[{value:"Gas allocation",id:"gas-allocation",level:2},{value:"Consensus before execution & basics of payment",id:"consensus-before-execution--basics-of-payment",level:3},{value:"Costs and limits",id:"costs-and-limits",level:3},{value:"Lanes",id:"lanes",level:3},{value:"Gas fees",id:"gas-fees",level:2},{value:"Fee allocation",id:"fee-allocation",level:3},{value:"Spot pricing",id:"spot-pricing",level:3},{value:"Futures pricing",id:"futures-pricing",level:3}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",sup:"sup",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"runtime-economics",children:"Runtime Economics"})}),"\n",(0,s.jsxs)(t.p,{children:["The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, ",(0,s.jsx)(t.a,{href:"/concepts/economics/gas-concepts",children:"gas"})," is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/10",(0,s.jsx)(t.sup,{children:"9"})," part of a CSPR token) per 1 unit of gas."]}),"\n",(0,s.jsx)(t.h2,{id:"gas-allocation",children:"Gas allocation"}),"\n",(0,s.jsxs)(t.p,{children:["Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas. We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps",children:"CEPs"}),". In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme."]}),"\n",(0,s.jsx)(t.h3,{id:"consensus-before-execution--basics-of-payment",children:"Consensus before execution & basics of payment"}),"\n",(0,s.jsxs)(t.p,{children:["The Highway protocol in its Mainnet implementation reaches consensus on a block ",(0,s.jsx)(t.em,{children:"before"})," the block is executed, introducing a subtle difference from platforms like Ethereum. In addition, deploys sent to a Casper network can only be selected based on claimed, rather than used, gas. Consequently, to incentivize user-side optimization and prevent block space exhaustion by poorly optimized deploys, the platform provides no refunds for unused gas."]}),"\n",(0,s.jsx)(t.p,{children:"Additionally, a minimal amount of CSPR must be present in the user account's main purse to ensure that the payment computation is covered. The community may introduce additional balance checks in the future."}),"\n",(0,s.jsx)(t.h3,{id:"costs-and-limits",children:"Costs and limits"}),"\n",(0,s.jsxs)(t.p,{children:["Gas cost is a measure of relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific more complex ",(0,s.jsx)(t.em,{children:"host-side"})," functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the ",(0,s.jsx)(t.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"})," and may vary according to arguments."]}),"\n",(0,s.jsx)(t.p,{children:"We expect to refine the current gas cost table to reflect time use more closely, with updates introduced in future upgrades. We also anticipate that, with the introduction of state pruning, storage costs will be calculated separately from computing time."}),"\n",(0,s.jsx)(t.h3,{id:"lanes",children:"Lanes"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/b94c4f79ac4ca00e996c418dcc3a98607779a193/resources/production/chainspec.toml#L96-L97",children:"block gas limit"})," is split into two lanes, one for native transfers and one for general deploys. The number of transfers, which cost a fixed amount of gas, is governed directly by the ",(0,s.jsx)(t.code,{children:"block_max_transfer_count"})," chainspec parameter, set to 2500 when Mainnet launched."]}),"\n",(0,s.jsx)(t.h2,{id:"gas-fees",children:"Gas fees"}),"\n",(0,s.jsx)(t.p,{children:"Currently, the price of gas is fixed at 1 mote per 1 unit of gas."}),"\n",(0,s.jsx)(t.h3,{id:"fee-allocation",children:"Fee allocation"}),"\n",(0,s.jsx)(t.p,{children:"All fees from a particular block accrue to its proposer, incentivizing non-empty block production and allowing major dApps to execute deploys for free, provided they operate a validator node and are comfortable with the latency introduced by validator scheduling."}),"\n",(0,s.jsx)(t.h3,{id:"spot-pricing",children:"Spot pricing"}),"\n",(0,s.jsxs)(t.p,{children:["Please see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/22",children:"CEP #22"})," for one potential design of a gas spot market."]}),"\n",(0,s.jsx)(t.h3,{id:"futures-pricing",children:"Futures pricing"}),"\n",(0,s.jsxs)(t.p,{children:["Please see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/17",children:"CEP #17"})," for our draft proposal of a gas futures market."]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var s=n(96540);const i={},o=s.createContext(i);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56aa8058.bdb374f9.js b/assets/js/56aa8058.bdb374f9.js new file mode 100644 index 000000000..8fe7d15c5 --- /dev/null +++ b/assets/js/56aa8058.bdb374f9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63055],{63784:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"dApps"},o="Introduction to dApps",r={id:"concepts/intro-to-dapps",title:"dApps",description:"What is a dApp?",source:"@site/versioned_docs/version-2.0.0/concepts/intro-to-dapps.md",sourceDirName:"concepts",slug:"/concepts/intro-to-dapps",permalink:"/2.0.0/concepts/intro-to-dapps",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"dApps"},sidebar:"concepts",previous:{title:"Type Serialization",permalink:"/2.0.0/concepts/serialization/types"},next:{title:"Addressable Entities",permalink:"/2.0.0/concepts/addressable-entity"}},c={},d=[{value:"What is a dApp?",id:"what-is-a-dapp",level:3},{value:"Interacting with a Casper Decentralized Network",id:"interacting-with-a-casper-decentralized-network",level:3},{value:"Updating data in a Casper dApp",id:"updating-data-in-a-casper-dapp",level:4},{value:"Post-Consensus Execution in a Casper network",id:"post-consensus-execution-in-a-casper-network",level:4},{value:"Transaction lifecycle",id:"transaction-lifecycle",level:4},{value:"Related reading",id:"related-reading",level:3}];function l(e){const n={a:"a",em:"em",h1:"h1",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"introduction-to-dapps",children:"Introduction to dApps"})}),"\n",(0,a.jsx)(n.h3,{id:"what-is-a-dapp",children:"What is a dApp?"}),"\n",(0,a.jsxs)(n.p,{children:["DApp stands for ",(0,a.jsx)(n.strong,{children:"Decentralized Application"}),". Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface."]}),"\n",(0,a.jsx)(n.p,{children:"A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power."}),"\n",(0,a.jsxs)(n.p,{children:["A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#node",children:"nodes"})," does the processing of smart contracts instead of a single central server."]}),"\n",(0,a.jsxs)(n.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N#node",children:"node"}),". The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsx)(n.h3,{id:"interacting-with-a-casper-decentralized-network",children:"Interacting with a Casper Decentralized Network"}),"\n",(0,a.jsxs)(n.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transactions"})," via the ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/",children:"JSON-RPC"}),". Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(n.p,{children:["A transaction contains ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A#account",children:"account entity"}),". Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly.\nA dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"updating-data-in-a-casper-dapp",children:"Updating data in a Casper dApp"}),"\n",(0,a.jsxs)(n.p,{children:["Sending a transaction is the only means by which a dApp can change ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"}),". All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."]}),"\n",(0,a.jsx)(n.h4,{id:"post-consensus-execution-in-a-casper-network",children:"Post-Consensus Execution in a Casper network"}),"\n",(0,a.jsxs)(n.p,{children:["Unlike other blockchain networks, a Casper network performs execution ",(0,a.jsx)(n.em,{children:(0,a.jsx)(n.strong,{children:"after"})})," ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#consensus",children:"consensus"}),". This means that observing the execution of the transaction is sufficient proof of ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/B#block-finality",children:"finality"})," for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"transaction-lifecycle",children:"Transaction lifecycle"}),"\n",(0,a.jsxs)(n.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]}),"\n",(0,a.jsx)(n.h3,{id:"related-reading",children:"Related reading"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction lifecycle"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/concepts/global-state",children:"Global State"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Session Code"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var a=t(96540);const s={},i=a.createContext(s);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56ad65de.d53d5c28.js b/assets/js/56ad65de.d53d5c28.js deleted file mode 100644 index c516d17f3..000000000 --- a/assets/js/56ad65de.d53d5c28.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3471],{98132:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>t,toc:()=>d});var s=i(74848),r=i(28453);const a={},c="Major Structures",t={id:"concepts/serialization/structures",title:"Major Structures",description:"Account",source:"@site/docs/concepts/serialization/structures.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/structures",permalink:"/next/concepts/serialization/structures",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Primitives and Basic Serialization Rules",permalink:"/next/concepts/serialization/primitives"},next:{title:"Type Serialization",permalink:"/next/concepts/serialization/types"}},l={},d=[{value:"Account",id:"serialization-standard-account",level:2},{value:"AddressableEntity",id:"addressable-entity",level:2},{value:"Block",id:"serialization-standard-block",level:2},{value:"BlockHash",id:"block-hash",level:3},{value:"BlockHeader",id:"block-header",level:3},{value:"EraEndV1",id:"eraendV1",level:3},{value:"EraEndV2",id:"eraendV2",level:3},{value:"BlockBodyV1",id:"blockbodyV1",level:3},{value:"BlockBodyV2 {blockbodyv2}",id:"blockbodyv2-blockbodyv2",level:3},{value:"Contract",id:"contract",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:3},{value:"ContractWasmHash",id:"contractwasmhash",level:3},{value:"ContractHash",id:"contracthash",level:3},{value:"ContractPackageStatus",id:"contractpackagestatus",level:3},{value:"ContractVersion",id:"contractversion",level:3},{value:"ContractVersionKey",id:"contractversionkey",level:3},{value:"ContractWasm",id:"contractwasm",level:3},{value:"Message",id:"message",level:2},{value:"MessageAddr",id:"message-addr",level:3},{value:"MessageChecksum",id:"message-checksum",level:3},{value:"MessageLimits",id:"message-limits",level:3},{value:"MessagePayload",id:"message-payload",level:3},{value:"MessageTopicOperation",id:"message-topic-operation",level:3},{value:"TopicNameHash",id:"topic-name-hash",level:3},{value:"Transaction",id:"transaction",level:2},{value:"Deploy",id:"serialization-standard-deploy",level:3},{value:"DeployHash",id:"deploy-hash",level:3},{value:"DeployHeader",id:"deploy-header",level:3},{value:"Approval",id:"approval",level:3},{value:"ApprovalsHash",id:"approvals-hash",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"DeployConfig",id:"deployconfig",level:2},{value:"TransactionV1",id:"transactionV1",level:3},{value:"TransactionV1Hash",id:"transactionv1hash",level:3},{value:"TransactionV1Header",id:"transactionv1header",level:3},{value:"TransactionV1Body",id:"transactionv1body",level:3},{value:"TransactionRuntime",id:"transactionruntime",level:3},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:3},{value:"TransactionConfig",id:"transactionconfig",level:3},{value:"TransactionV1Config",id:"transactionV1config",level:3},{value:"TransactionHash",id:"transactionhash",level:3},{value:"TransactionHeader",id:"transactionheader",level:3},{value:"TransactionId",id:"transactionid",level:3},{value:"TransactionScheduling",id:"transactionscheduling",level:3},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:3},{value:"TransactionTarget",id:"transactiontarget",level:3},{value:"TransactionWithExecutionInfo",id:"transaction-with-execution-info",level:3}];function o(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"major-structures",children:"Major Structures"})}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-account",children:"Account"}),"\n",(0,s.jsxs)(n.p,{children:["An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, ",(0,s.jsx)(n.code,{children:"Accounts"})," were replaced with ",(0,s.jsx)(n.code,{children:"AddressableEntities"})," of the type ",(0,s.jsx)(n.code,{children:"Account"}),". The account structure consists of the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse"}),": The account's main purse ",(0,s.jsx)(n.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(n.code,{children:"URef"})," serialization ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#account-action-thresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressable-entity",children:"AddressableEntity"}),"\n",(0,s.jsx)(n.p,{children:"An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#package-hash",children:(0,s.jsx)(n.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#byte-code-hash",children:(0,s.jsx)(n.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entrypoints",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse"}),": The entity's main purse ",(0,s.jsx)(n.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(n.code,{children:"URef"})," serialization ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entity-action-thresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#message-topics",children:(0,s.jsx)(n.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entity-kind",children:(0,s.jsx)(n.code,{children:"entity_kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block is the core component of the Casper linear blockchain, used in two contexts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(n.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(n.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(n.p,{children:"A block is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": A hash over the header of the block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": The header of the block that contains information about the contents of the block with additional metadata."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body"}),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Further, a block may consist of one of the following types:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Version1"}),": A legacy block created prior to the Condor upgrade."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Version2"}),": A modern block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"block-hash",children:"BlockHash"}),"\n",(0,s.jsxs)(n.p,{children:["The block hash is a ",(0,s.jsx)(n.code,{children:"Digest"})," over the contents of the block Header. The ",(0,s.jsx)(n.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.h3,{id:"block-header",children:"BlockHeader"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"parent_hash"})," is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"parent_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"state_root_hash"})," is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"})," the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"body_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"accumulated_seed"})," is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"accumulated_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_end"})," contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,s.jsx)(n.code,{children:"None"}),", it serializes to ",(0,s.jsx)(n.em,{children:"0"}),". The serialization of the other case is described in the EraEnd."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"})," The timestamp from when the block was proposed. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value. The serialization of a ",(0,s.jsx)(n.code,{children:"u64"})," value is described in the CLValues section."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_id"})," Era ID in which this block was created. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"protocol_version"})," The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,s.jsx)(n.code,{children:"u32"})," values. It serializes as a buffer containing the three ",(0,s.jsx)(n.code,{children:"u32"})," serialized values. Refer to the CLValues section on how ",(0,s.jsx)(n.code,{children:"u32"})," values are serialized."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Both ",(0,s.jsx)(n.code,{children:"BlockHeaderV1"})," and ",(0,s.jsx)(n.code,{children:"BlockHeaderV2"})," serialize in the same way."]}),"\n",(0,s.jsx)(n.h3,{id:"eraendV1",children:"EraEndV1"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing two fields."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_report"}),": The first field is termed as ",(0,s.jsx)(n.code,{children:"EraReport"})," and contains information about equivocators and rewards for an era."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"next_era_validator_weights"}),": The second field is map for the validators and their weights for the era to follow."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraReport"})," itself contains two fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"inactive_validators"}),": A vector of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When serializing the overarching struct of ",(0,s.jsx)(n.code,{children:"EraEndV1"}),", we first allocate a buffer, which contains the serialized representation of the ",(0,s.jsx)(n.code,{children:"EraReport"})," as described above, followed by the serialized BTreeMap."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"EraEndV1"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(n.code,{children:"EraEndV1"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(n.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"eraendV2",children:"EraEndV2"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing four fields."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(n.code,{children:"PublicKey"})," listing equivocators for the era."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"inactive_validators"}),": A list of inactive validators for the era."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"next_era_validator_weights"}),": A map of validators and their weights for the era to follow."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"next_era_gas_price"}),": The next era's gas price as a ",(0,s.jsx)(n.code,{children:"u8"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"EraEndV2"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(n.code,{children:"EraEndV2"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(n.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"blockbodyV1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block, prior to the Condor upgrade, is structurally defined as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"}),": The PublicKey which proposed this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"}),": Is a vector of hex-encoded hashes identifying Deploys included in this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"}),": Is a vector of hex-encoded hashes identifying Transfers included in this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When we serialize the ",(0,s.jsx)(n.code,{children:"BlockBodyV1"}),", we create a buffer that contains the serialized representations of the individual fields present within the block."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"})," serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of deploy hashes present within the body."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of transfers present within the body."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"blockbodyv2-blockbodyv2",children:"BlockBodyV2 {blockbodyv2}"}),"\n",(0,s.jsx)(n.p,{children:"A modern block is structurally defined as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transaction",children:(0,s.jsx)(n.code,{children:"transactions"})}),": Is a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," of transaction hashes and their given categories. It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating pattern of transaction categories as a ",(0,s.jsx)(n.code,{children:"u8"})," value and then the associated ",(0,s.jsx)(n.code,{children:"TransactionHash"})," the category tag describes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#rewarded-signatures",children:(0,s.jsx)(n.code,{children:"rewarded_signatures"})}),": A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(n.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct containing the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entrypoints",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."]}),"\n",(0,s.jsx)(n.h3,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."]}),"\n",(0,s.jsx)(n.h3,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."]}),"\n",(0,s.jsx)(n.h3,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsxs)(n.p,{children:["The lock status of the contract package, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(n.code,{children:"boolean"})})," where ",(0,s.jsx)(n.code,{children:"true"})," indicates a locked contract and ",(0,s.jsx)(n.code,{children:"false"})," indicates an unlocked contract package."]}),"\n",(0,s.jsx)(n.h3,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})}),": The contract hash of the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["The major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"Contract"})," Version serialized as two ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(n.h3,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes, serialized as the byte representation of itself."}),"\n",(0,s.jsx)(n.h2,{id:"message",children:"Message"}),"\n",(0,s.jsxs)(n.p,{children:["A message emitted by an addressable entity during execution. The message ",(0,s.jsx)(n.code,{children:"struct"})," contains the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entity_hash"}),": The identity of the entity that produced the message, serialized as an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entity-addr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"message"}),": The payload of the message, serialized as a ",(0,s.jsx)(n.a,{href:"#message-payload",children:(0,s.jsx)(n.code,{children:"MessagePayload"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name"}),": The name of the topic on which the message was emitted, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(n.a,{href:"#topic-name-hash",children:(0,s.jsx)(n.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_index"}),": The message index in the topic, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_index"}),": The message index in the block, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"message-addr",children:"MessageAddr"}),"\n",(0,s.jsx)(n.p,{children:"A message topic address, a structure which consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entity_addr"}),": The entity address, serialized as an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entity-addr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(n.a,{href:"#topic-name-hash",children:(0,s.jsx)(n.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"message_index"}),": The message index, serialized as an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})})," of ",(0,s.jsx)(n.code,{children:"u32"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"message-checksum",children:"MessageChecksum"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a ",(0,s.jsx)(n.code,{children:"CLType"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," tag followed by a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-ByteArray",children:(0,s.jsx)(n.code,{children:"ByteArray"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"message-limits",children:"MessageLimits"}),"\n",(0,s.jsxs)(n.p,{children:["Configuration for message lists, serialized as three ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})," values:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_topic_name_size"}),": Maximum size in bytes of a topic name string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_message_size"}),": Maximum message size in bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_topics_per_contract"}),": Maximum number of topics that a contract can register."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"message-payload",children:"MessagePayload"}),"\n",(0,s.jsxs)(n.p,{children:["The payload of a message emitted by an addressable entity during execution. It serializes as either a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 0 followed by a a serialized version of a human-readable ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),", or as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 1 followed by serialized raw ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#bytes",children:(0,s.jsx)(n.code,{children:"Bytes"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"message-topic-operation",children:"MessageTopicOperation"}),"\n",(0,s.jsxs)(n.p,{children:["Operations that can be performed on message topics. Currently, serializes as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," of 0 representing the ",(0,s.jsx)(n.code,{children:"Add"})," function."]}),"\n",(0,s.jsx)(n.h3,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hash of the name of a message topic, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," describing the length of the string and the 32-byte serialized representation of the ",(0,s.jsx)(n.code,{children:"string"})," itself."]}),"\n",(0,s.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsxs)(n.p,{children:["A versioned wrapper for a transaction or deploy. It serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"0"})," followed by a ",(0,s.jsx)(n.a,{href:"#serialization-standard-deploy",children:(0,s.jsx)(n.code,{children:"Deploy"})})," or a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"1"})," followed by a ",(0,s.jsx)(n.a,{href:"#transactionV1",children:(0,s.jsx)(n.code,{children:"TransactionV1"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": The hash of the deploy header."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": Contains metadata about the deploy. The structure of the header is detailed further in this document."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment"}),": The payment code for contained smart contract."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session"}),": The stored contract itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-hash",children:"DeployHash"}),"\n",(0,s.jsx)(n.p,{children:"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(n.h3,{id:"deploy-header",children:"DeployHeader"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"account"}),": A supported public key variant (currently either ",(0,s.jsx)(n.code,{children:"Ed25519"})," or ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"). An ",(0,s.jsx)(n.code,{children:"Ed25519"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"1"})," for ",(0,s.jsx)(n.code,{children:"Ed25519"}),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(n.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(n.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(n.code,{children:"0xbd3a847575010000"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ttl"}),": The ",(0,s.jsx)(n.strong,{children:"Time to live"})," is defined as the amount of time for which deploy is considered valid. The ",(0,s.jsx)(n.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"gas_price"}),": The gas is ",(0,s.jsx)(n.code,{children:"u64"})," value which is serialized as ",(0,s.jsx)(n.code,{children:"u64"})," CLValue discussed below."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"dependencies"}),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"Approval contains two fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(n.code,{children:"Signature"}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(n.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#digest",children:(0,s.jsx)(n.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to a given deploy. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deploy_hash"}),": The hash of the relevant deploy, serialized as a byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"}),": Transfers performed by the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"from"}),": The account identifier of the creator of the deploy, serialized as an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"source"}),": The source purse used for payment of the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas"}),": The gas cost of executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployconfig",children:"DeployConfig"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(n.code,{children:"deploys"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_payment_cost"}),": The maximum amount any deploy can pay, serialized in ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#motes",children:(0,s.jsx)(n.code,{children:"Motes"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_dependencies"}),": The maximum time to live any deploy can specify, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"payment_args_max_length"}),": The maximum length in bytes of payment args per deploy, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session_args_max_length"}),": The maximum length in bytes of session args per deploy, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionV1",children:"TransactionV1"}),"\n",(0,s.jsx)(n.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered. It is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1hash",children:(0,s.jsx)(n.code,{children:"TransactionV1Hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1header",children:(0,s.jsx)(n.code,{children:"TransactionV1Header"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1body",children:(0,s.jsx)(n.code,{children:"TransactionV1Body"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(n.p,{children:"The transaction hash is a digest over the contents of the transaction header. The transaction hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(n.h3,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a transaction, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(n.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(n.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(n.code,{children:"0xbd3a847575010000"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ttl"}),": The ",(0,s.jsx)(n.strong,{children:"Time to live"})," is defined as the amount of time for which the transaction is considered valid. The ",(0,s.jsx)(n.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": Body hash is a hash over the contents of the ",(0,s.jsx)(n.a,{href:"#transactionv1body",children:"transaction body"}),". It serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#pricingmode",children:(0,s.jsx)(n.code,{children:"pricing_mode"})})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initator_addr"})})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsxs)(n.p,{children:["The body of a ",(0,s.jsx)(n.code,{children:"TransactionV1"}),", consisting of the following:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#runtimeargs",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactiontarget",children:(0,s.jsx)(n.code,{children:"target"})})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactionentrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactionscheduling",children:(0,s.jsx)(n.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsxs)(n.p,{children:["The runtime used to execute a transaction, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})}),". Currently, only the ",(0,s.jsx)(n.code,{children:"VmCasperV1"})," is available, which serializes as a ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["An entry point of a transaction, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," value based on the type of entry point. The following table outlines the available types:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Tag"}),(0,s.jsx)(n.th,{children:"Entry Point"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"Custom"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"1"}),(0,s.jsx)(n.td,{children:"Transfer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"2"}),(0,s.jsx)(n.td,{children:"Add_Bid"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"3"}),(0,s.jsx)(n.td,{children:"Withdraw_Bid"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"4"}),(0,s.jsx)(n.td,{children:"Delegate"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"5"}),(0,s.jsx)(n.td,{children:"Undelegate"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"6"}),(0,s.jsx)(n.td,{children:"Redelegate"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"7"}),(0,s.jsx)(n.td,{children:"Activate_Bid"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"8"}),(0,s.jsx)(n.td,{children:"ChangePublicKey"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"9"}),(0,s.jsx)(n.td,{children:"Call"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"transactionconfig",children:"TransactionConfig"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(n.code,{children:"Transactions"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_ttl"}),": The maximum time to live any transaction can specify, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#timediff",children:(0,s.jsx)(n.code,{children:"TimeDiff"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_max_approval_count"}),": The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_block_size"}),": The maximum possible size in bytes of a block, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_gas_limit"}),": The maximum sum of payment across al transactions included in a block, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native_transfer_minimum_motes"}),": The minimum token amount for a native transfer deploy or transaction, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"max_timestamp_leeway"}),": The maximum value to which a ",(0,s.jsx)(n.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the ",(0,s.jsx)(n.em,{children:"config.toml"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployconfig",children:(0,s.jsx)(n.code,{children:"deploy_config"})}),": Configuration values specific to Deploy transactions."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionV1config",children:(0,s.jsx)(n.code,{children:"transaction_v1_config"})}),": Configuration values specific to V1 transactions."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionV1config",children:"TransactionV1Config"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(n.code,{children:"TransactionV1s"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native_mint_lane"}),": The lane configuration for the native mint interaction, serializing as a vector of ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native_auction_lane"}),": The lane configuration for the native auction interaction, serializing as a vector of ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"wasm_lanes"}),": The lane configuration for the Wasm-based lanes, serializing as a nested vector of ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," values."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsxs)(n.p,{children:["A versioned wrapper for transaction hash or deploy hash. It serializes as either a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(n.a,{href:"#deploy-hash",children:(0,s.jsx)(n.code,{children:"DeployHash"})})," or a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(n.a,{href:"#transactionv1hash",children:(0,s.jsx)(n.code,{children:"TransactionV1Hash"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"transactionheader",children:"TransactionHeader"}),"\n",(0,s.jsxs)(n.p,{children:["A versioned wrapper for transaction header or deploy header. It serializes as either a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(n.a,{href:"#deploy-header",children:(0,s.jsx)(n.code,{children:"DeployHeader"})})," or a ",(0,s.jsx)(n.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(n.a,{href:"#transactionv1header",children:(0,s.jsx)(n.code,{children:"TransactionV1Header"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"transactionid",children:"TransactionId"}),"\n",(0,s.jsxs)(n.p,{children:["The unique identifier of a ",(0,s.jsx)(n.code,{children:"Transaction"}),", serialized as its ",(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"TransactionHash"})})," and ",(0,s.jsx)(n.a,{href:"#approvals-hash",children:(0,s.jsx)(n.code,{children:"ApprovalsHash"})}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsxs)(n.p,{children:["The scheduling mode of a transaction, serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," tag identifying the type:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Standard"})," serializes as a ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureEra"})," serializes as a ",(0,s.jsx)(n.code,{children:"1"})," followed by a future ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureTimestamp"})," serializes as a ",(0,s.jsx)(n.code,{children:"2"})," followed by a future ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(n.p,{children:["The identifier of a ",(0,s.jsx)(n.code,{children:"stored"})," transaction target, serialized as one of the following:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"InvocableEntity"})," serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"0"})," followed by the hex-encoded entity address serialized as the byte representation of itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"InvocableEntityAlias"})," serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"1"})," followed by the alias serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(n.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Package"})," serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"2"})," followed by the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#package-hash",children:(0,s.jsx)(n.code,{children:"package hash"})})," and optionally the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(n.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PackageAlias"})," serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag of ",(0,s.jsx)(n.code,{children:"3"})," followed by the alias serialized as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(n.code,{children:"string"})})," and optionally the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(n.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsxs)(n.p,{children:["The execution target of a transaction, serializing as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," that identifies the type, followed by any additional data."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native"})," serializes as a ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stored"})," serializes as a ",(0,s.jsx)(n.code,{children:"1"})," followed by the ",(0,s.jsx)(n.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(n.code,{children:"id"})})," and ",(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session"})," serializes as a ",(0,s.jsx)(n.code,{children:"2"})," followed by the ",(0,s.jsx)(n.a,{href:"#transactionsessionkind",children:(0,s.jsx)(n.code,{children:"kind"})}),", ",(0,s.jsx)(n.a,{href:"#payment--session",children:(0,s.jsx)(n.code,{children:"module_bytes"})})," and ",(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-with-execution-info",children:"TransactionWithExecutionInfo"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"struct"})," containing a",(0,s.jsx)(n.code,{children:"Transaction"})," with execution info. It serializes as a ",(0,s.jsx)(n.a,{href:"#transaction",children:(0,s.jsx)(n.code,{children:"Transaction"})})," followed by an ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})})," of ",(0,s.jsx)(n.code,{children:"ExecutionInfo"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>t});var s=i(96540);const r={},a=s.createContext(r);function c(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56ad65de.fcda7351.js b/assets/js/56ad65de.fcda7351.js new file mode 100644 index 000000000..c17a40087 --- /dev/null +++ b/assets/js/56ad65de.fcda7351.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[23471],{98132:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>t,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=n(74848),r=n(28453);const a={},c="Major Structures",l={id:"concepts/serialization/structures",title:"Major Structures",description:"Account",source:"@site/docs/concepts/serialization/structures.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/structures",permalink:"/concepts/serialization/structures",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Primitives and Basic Serialization Rules",permalink:"/concepts/serialization/primitives"},next:{title:"Type Serialization",permalink:"/concepts/serialization/types"}},t={},d=[{value:"Account",id:"serialization-standard-account",level:2},{value:"AddressableEntity",id:"addressable-entity",level:2},{value:"Block",id:"serialization-standard-block",level:2},{value:"BlockHash",id:"block-hash",level:3},{value:"BlockHeader",id:"block-header",level:3},{value:"EraEndV1",id:"eraendV1",level:3},{value:"EraEndV2",id:"eraendV2",level:3},{value:"BlockBodyV1",id:"blockbodyV1",level:3},{value:"BlockBodyV2 {blockbodyv2}",id:"blockbodyv2-blockbodyv2",level:3},{value:"Contract",id:"contract",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:3},{value:"ContractWasmHash",id:"contractwasmhash",level:3},{value:"ContractHash",id:"contracthash",level:3},{value:"ContractPackageStatus",id:"contractpackagestatus",level:3},{value:"ContractVersion",id:"contractversion",level:3},{value:"ContractVersionKey",id:"contractversionkey",level:3},{value:"ContractWasm",id:"contractwasm",level:3},{value:"Message",id:"message",level:2},{value:"MessageAddr",id:"message-addr",level:3},{value:"MessageChecksum",id:"message-checksum",level:3},{value:"MessageLimits",id:"message-limits",level:3},{value:"MessagePayload",id:"message-payload",level:3},{value:"MessageTopicOperation",id:"message-topic-operation",level:3},{value:"TopicNameHash",id:"topic-name-hash",level:3},{value:"Transaction",id:"transaction",level:2},{value:"Deploy",id:"serialization-standard-deploy",level:3},{value:"DeployHash",id:"deploy-hash",level:3},{value:"DeployHeader",id:"deploy-header",level:3},{value:"Approval",id:"approval",level:3},{value:"ApprovalsHash",id:"approvals-hash",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"DeployConfig",id:"deployconfig",level:2},{value:"TransactionV1",id:"transactionV1",level:3},{value:"TransactionV1Hash",id:"transactionv1hash",level:3},{value:"TransactionV1Header",id:"transactionv1header",level:3},{value:"TransactionV1Body",id:"transactionv1body",level:3},{value:"TransactionRuntime",id:"transactionruntime",level:3},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:3},{value:"TransactionConfig",id:"transactionconfig",level:3},{value:"TransactionV1Config",id:"transactionV1config",level:3},{value:"TransactionHash",id:"transactionhash",level:3},{value:"TransactionHeader",id:"transactionheader",level:3},{value:"TransactionId",id:"transactionid",level:3},{value:"TransactionScheduling",id:"transactionscheduling",level:3},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:3},{value:"TransactionTarget",id:"transactiontarget",level:3},{value:"TransactionWithExecutionInfo",id:"transaction-with-execution-info",level:3}];function o(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.header,{children:(0,s.jsx)(i.h1,{id:"major-structures",children:"Major Structures"})}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-account",children:"Account"}),"\n",(0,s.jsxs)(i.p,{children:["An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, ",(0,s.jsx)(i.code,{children:"Accounts"})," were replaced with ",(0,s.jsx)(i.code,{children:"AddressableEntities"})," of the type ",(0,s.jsx)(i.code,{children:"Account"}),". The account structure consists of the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#namedkey",children:(0,s.jsx)(i.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"main_purse"}),": The account's main purse ",(0,s.jsx)(i.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(i.code,{children:"URef"})," serialization ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#associatedkey",children:(0,s.jsx)(i.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#account-action-thresholds",children:(0,s.jsx)(i.code,{children:"action_thresholds"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"addressable-entity",children:"AddressableEntity"}),"\n",(0,s.jsx)(i.p,{children:"An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#package-hash",children:(0,s.jsx)(i.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#byte-code-hash",children:(0,s.jsx)(i.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entrypoints",children:(0,s.jsx)(i.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#protocolversion",children:(0,s.jsx)(i.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"main_purse"}),": The entity's main purse ",(0,s.jsx)(i.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(i.code,{children:"URef"})," serialization ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#associatedkey",children:(0,s.jsx)(i.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entity-action-thresholds",children:(0,s.jsx)(i.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#message-topics",children:(0,s.jsx)(i.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entity-kind",children:(0,s.jsx)(i.code,{children:"entity_kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-block",children:"Block"}),"\n",(0,s.jsx)(i.p,{children:"A block is the core component of the Casper linear blockchain, used in two contexts:"}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsx)(i.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(i.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(i.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(i.p,{children:"A block is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hash"}),": A hash over the header of the block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"header"}),": The header of the block that contains information about the contents of the block with additional metadata."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body"}),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Further, a block may consist of one of the following types:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Version1"}),": A legacy block created prior to the Condor upgrade."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Version2"}),": A modern block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-hash",children:"BlockHash"}),"\n",(0,s.jsxs)(i.p,{children:["The block hash is a ",(0,s.jsx)(i.code,{children:"Digest"})," over the contents of the block Header. The ",(0,s.jsx)(i.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.h3,{id:"block-header",children:"BlockHeader"}),"\n",(0,s.jsx)(i.p,{children:"The header portion of a block, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"parent_hash"})," is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"parent_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"state_root_hash"})," is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(i.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"})," the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"body_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"random_bit"})," is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"accumulated_seed"})," is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"accumulated_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_end"})," contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,s.jsx)(i.code,{children:"None"}),", it serializes to ",(0,s.jsx)(i.em,{children:"0"}),". The serialization of the other case is described in the EraEnd."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"})," The timestamp from when the block was proposed. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value. The serialization of a ",(0,s.jsx)(i.code,{children:"u64"})," value is described in the CLValues section."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_id"})," Era ID in which this block was created. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"height"})," The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"protocol_version"})," The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,s.jsx)(i.code,{children:"u32"})," values. It serializes as a buffer containing the three ",(0,s.jsx)(i.code,{children:"u32"})," serialized values. Refer to the CLValues section on how ",(0,s.jsx)(i.code,{children:"u32"})," values are serialized."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Both ",(0,s.jsx)(i.code,{children:"BlockHeaderV1"})," and ",(0,s.jsx)(i.code,{children:"BlockHeaderV2"})," serialize in the same way."]}),"\n",(0,s.jsx)(i.h3,{id:"eraendV1",children:"EraEndV1"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing two fields."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_report"}),": The first field is termed as ",(0,s.jsx)(i.code,{children:"EraReport"})," and contains information about equivocators and rewards for an era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_validator_weights"}),": The second field is map for the validators and their weights for the era to follow."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraReport"})," itself contains two fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(i.code,{children:"PublicKey"})," and ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"inactive_validators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, the first byte within the buffer is a ",(0,s.jsx)(i.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(i.li,{children:["If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Secp256k1"})," key, the first byte within the buffer is a ",(0,s.jsx)(i.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["When serializing the overarching struct of ",(0,s.jsx)(i.code,{children:"EraEndV1"}),", we first allocate a buffer, which contains the serialized representation of the ",(0,s.jsx)(i.code,{children:"EraReport"})," as described above, followed by the serialized BTreeMap."]}),"\n",(0,s.jsxs)(i.p,{children:["Note that ",(0,s.jsx)(i.code,{children:"EraEndV1"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(i.code,{children:"EraEndV1"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(i.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"eraendV2",children:"EraEndV2"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing four fields."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"})," listing equivocators for the era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"inactive_validators"}),": A list of inactive validators for the era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_validator_weights"}),": A map of validators and their weights for the era to follow."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(i.code,{children:"PublicKey"})," and ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_gas_price"}),": The next era's gas price as a ",(0,s.jsx)(i.code,{children:"u8"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note that ",(0,s.jsx)(i.code,{children:"EraEndV2"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(i.code,{children:"EraEndV2"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(i.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"blockbodyV1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(i.p,{children:"The body portion of a block, prior to the Condor upgrade, is structurally defined as:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"proposer"}),": The PublicKey which proposed this block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"deploy_hashes"}),": Is a vector of hex-encoded hashes identifying Deploys included in this block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"transfer_hashes"}),": Is a vector of hex-encoded hashes identifying Transfers included in this block."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["When we serialize the ",(0,s.jsx)(i.code,{children:"BlockBodyV1"}),", we create a buffer that contains the serialized representations of the individual fields present within the block."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"proposer"})," serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"deploy_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(i.code,{children:"32 * n"}),", where n denotes the number of deploy hashes present within the body."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"transfer_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(i.code,{children:"32 * n"}),", where n denotes the number of transfers present within the body."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"blockbodyv2-blockbodyv2",children:"BlockBodyV2 {blockbodyv2}"}),"\n",(0,s.jsx)(i.p,{children:"A modern block is structurally defined as:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#transaction",children:(0,s.jsx)(i.code,{children:"transactions"})}),": Is a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," of transaction hashes and their given categories. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating pattern of transaction categories as a ",(0,s.jsx)(i.code,{children:"u8"})," value and then the associated ",(0,s.jsx)(i.code,{children:"TransactionHash"})," the category tag describes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/concepts/serialization/types#rewarded-signatures",children:(0,s.jsx)(i.code,{children:"rewarded_signatures"})}),": A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(i.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(i.p,{children:"A contract struct containing the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#contractwasmhash",children:(0,s.jsx)(i.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#namedkey",children:(0,s.jsx)(i.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entrypoints",children:(0,s.jsx)(i.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#protocolversion",children:(0,s.jsx)(i.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The lock status of the contract package, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})})," where ",(0,s.jsx)(i.code,{children:"true"})," indicates a locked contract and ",(0,s.jsx)(i.code,{children:"false"})," indicates an unlocked contract package."]}),"\n",(0,s.jsx)(i.h3,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(i.p,{children:"The version of the contract."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),": The contract hash of the contract."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(i.p,{children:["The major element of ",(0,s.jsx)(i.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(i.code,{children:"Contract"})," Version serialized as two ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(i.h3,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(i.p,{children:"A container for a contract's Wasm bytes, serialized as the byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"message",children:"Message"}),"\n",(0,s.jsxs)(i.p,{children:["A message emitted by an addressable entity during execution. The message ",(0,s.jsx)(i.code,{children:"struct"})," contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entity_hash"}),": The identity of the entity that produced the message, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"message"}),": The payload of the message, serialized as a ",(0,s.jsx)(i.a,{href:"#message-payload",children:(0,s.jsx)(i.code,{children:"MessagePayload"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name"}),": The name of the topic on which the message was emitted, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_index"}),": The message index in the topic, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_index"}),": The message index in the block, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-addr",children:"MessageAddr"}),"\n",(0,s.jsx)(i.p,{children:"A message topic address, a structure which consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entity_addr"}),": The entity address, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"message_index"}),": The message index, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," of ",(0,s.jsx)(i.code,{children:"u32"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-checksum",children:"MessageChecksum"}),"\n",(0,s.jsxs)(i.p,{children:["A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a ",(0,s.jsx)(i.code,{children:"CLType"})," ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-ByteArray",children:(0,s.jsx)(i.code,{children:"ByteArray"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"message-limits",children:"MessageLimits"}),"\n",(0,s.jsxs)(i.p,{children:["Configuration for message lists, serialized as three ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_topic_name_size"}),": Maximum size in bytes of a topic name string."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_message_size"}),": Maximum message size in bytes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_topics_per_contract"}),": Maximum number of topics that a contract can register."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-payload",children:"MessagePayload"}),"\n",(0,s.jsxs)(i.p,{children:["The payload of a message emitted by an addressable entity during execution. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a a serialized version of a human-readable ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),", or as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by serialized raw ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#bytes",children:(0,s.jsx)(i.code,{children:"Bytes"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"message-topic-operation",children:"MessageTopicOperation"}),"\n",(0,s.jsxs)(i.p,{children:["Operations that can be performed on message topics. Currently, serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," of 0 representing the ",(0,s.jsx)(i.code,{children:"Add"})," function."]}),"\n",(0,s.jsx)(i.h3,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(i.p,{children:["The hash of the name of a message topic, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," describing the length of the string and the 32-byte serialized representation of the ",(0,s.jsx)(i.code,{children:"string"})," itself."]}),"\n",(0,s.jsx)(i.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for a transaction or deploy. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"0"})," followed by a ",(0,s.jsx)(i.a,{href:"#serialization-standard-deploy",children:(0,s.jsx)(i.code,{children:"Deploy"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"1"})," followed by a ",(0,s.jsx)(i.a,{href:"#transactionV1",children:(0,s.jsx)(i.code,{children:"TransactionV1"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-deploy",children:"Deploy"}),"\n",(0,s.jsx)(i.p,{children:"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hash"}),": The hash of the deploy header."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"header"}),": Contains metadata about the deploy. The structure of the header is detailed further in this document."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"payment"}),": The payment code for contained smart contract."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"session"}),": The stored contract itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"deploy-hash",children:"DeployHash"}),"\n",(0,s.jsx)(i.p,{children:"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h3,{id:"deploy-header",children:"DeployHeader"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"account"}),": A supported public key variant (currently either ",(0,s.jsx)(i.code,{children:"Ed25519"})," or ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"). An ",(0,s.jsx)(i.code,{children:"Ed25519"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(i.code,{children:"1"})," for ",(0,s.jsx)(i.code,{children:"Ed25519"}),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,s.jsx)(i.code,{children:"Secp256k1"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(i.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(i.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(i.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(i.code,{children:"0xbd3a847575010000"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ttl"}),": The ",(0,s.jsx)(i.strong,{children:"Time to live"})," is defined as the amount of time for which deploy is considered valid. The ",(0,s.jsx)(i.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"gas_price"}),": The gas is ",(0,s.jsx)(i.code,{children:"u64"})," value which is serialized as ",(0,s.jsx)(i.code,{children:"u64"})," CLValue discussed below."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"}),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"dependencies"}),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(i.p,{children:"Approval contains two fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(i.code,{children:"Signature"}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(i.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#digest",children:(0,s.jsx)(i.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(i.p,{children:"Information relating to a given deploy. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deploy_hash"}),": The hash of the relevant deploy, serialized as a byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": Transfers performed by the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"from"}),": The account identifier of the creator of the deploy, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"source"}),": The source purse used for payment of the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"gas"}),": The gas cost of executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"deployconfig",children:"DeployConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"deploys"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_payment_cost"}),": The maximum amount any deploy can pay, serialized in ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#motes",children:(0,s.jsx)(i.code,{children:"Motes"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_dependencies"}),": The maximum time to live any deploy can specify, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"payment_args_max_length"}),": The maximum length in bytes of payment args per deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"session_args_max_length"}),": The maximum length in bytes of session args per deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionV1",children:"TransactionV1"}),"\n",(0,s.jsx)(i.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered. It is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1hash",children:(0,s.jsx)(i.code,{children:"TransactionV1Hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1header",children:(0,s.jsx)(i.code,{children:"TransactionV1Header"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1body",children:(0,s.jsx)(i.code,{children:"TransactionV1Body"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(i.p,{children:"The transaction hash is a digest over the contents of the transaction header. The transaction hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(i.p,{children:"The header portion of a transaction, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(i.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(i.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(i.code,{children:"0xbd3a847575010000"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ttl"}),": The ",(0,s.jsx)(i.strong,{children:"Time to live"})," is defined as the amount of time for which the transaction is considered valid. The ",(0,s.jsx)(i.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"}),": Body hash is a hash over the contents of the ",(0,s.jsx)(i.a,{href:"#transactionv1body",children:"transaction body"}),". It serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#pricingmode",children:(0,s.jsx)(i.code,{children:"pricing_mode"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#initiatoraddr",children:(0,s.jsx)(i.code,{children:"initator_addr"})})}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsxs)(i.p,{children:["The body of a ",(0,s.jsx)(i.code,{children:"TransactionV1"}),", consisting of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/types#runtimeargs",children:(0,s.jsx)(i.code,{children:"args"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactiontarget",children:(0,s.jsx)(i.code,{children:"target"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactionentrypoint",children:(0,s.jsx)(i.code,{children:"entry_point"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactionscheduling",children:(0,s.jsx)(i.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsxs)(i.p,{children:["The runtime used to execute a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),". Currently, only the ",(0,s.jsx)(i.code,{children:"VmCasperV1"})," is available, which serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsxs)(i.p,{children:["An entry point of a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," value based on the type of entry point. The following table outlines the available types:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"Entry Point"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Custom"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Transfer"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"Add_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:"Withdraw_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"4"}),(0,s.jsx)(i.td,{children:"Delegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"5"}),(0,s.jsx)(i.td,{children:"Undelegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"6"}),(0,s.jsx)(i.td,{children:"Redelegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"7"}),(0,s.jsx)(i.td,{children:"Activate_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"8"}),(0,s.jsx)(i.td,{children:"ChangePublicKey"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"9"}),(0,s.jsx)(i.td,{children:"Call"})]})]})]}),"\n",(0,s.jsx)(i.h3,{id:"transactionconfig",children:"TransactionConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"Transactions"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_ttl"}),": The maximum time to live any transaction can specify, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#timediff",children:(0,s.jsx)(i.code,{children:"TimeDiff"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_max_approval_count"}),": The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_block_size"}),": The maximum possible size in bytes of a block, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_gas_limit"}),": The maximum sum of payment across al transactions included in a block, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_transfer_minimum_motes"}),": The minimum token amount for a native transfer deploy or transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_timestamp_leeway"}),": The maximum value to which a ",(0,s.jsx)(i.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the ",(0,s.jsx)(i.em,{children:"config.toml"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#deployconfig",children:(0,s.jsx)(i.code,{children:"deploy_config"})}),": Configuration values specific to Deploy transactions."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#transactionV1config",children:(0,s.jsx)(i.code,{children:"transaction_v1_config"})}),": Configuration values specific to V1 transactions."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionV1config",children:"TransactionV1Config"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"TransactionV1s"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_mint_lane"}),": The lane configuration for the native mint interaction, serializing as a vector of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_auction_lane"}),": The lane configuration for the native auction interaction, serializing as a vector of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"wasm_lanes"}),": The lane configuration for the Wasm-based lanes, serializing as a nested vector of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for transaction hash or deploy hash. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(i.a,{href:"#deploy-hash",children:(0,s.jsx)(i.code,{children:"DeployHash"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(i.a,{href:"#transactionv1hash",children:(0,s.jsx)(i.code,{children:"TransactionV1Hash"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionheader",children:"TransactionHeader"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for transaction header or deploy header. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(i.a,{href:"#deploy-header",children:(0,s.jsx)(i.code,{children:"DeployHeader"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(i.a,{href:"#transactionv1header",children:(0,s.jsx)(i.code,{children:"TransactionV1Header"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionid",children:"TransactionId"}),"\n",(0,s.jsxs)(i.p,{children:["The unique identifier of a ",(0,s.jsx)(i.code,{children:"Transaction"}),", serialized as its ",(0,s.jsx)(i.a,{href:"#transactionhash",children:(0,s.jsx)(i.code,{children:"TransactionHash"})})," and ",(0,s.jsx)(i.a,{href:"#approvals-hash",children:(0,s.jsx)(i.code,{children:"ApprovalsHash"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsxs)(i.p,{children:["The scheduling mode of a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag identifying the type:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Standard"})," serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"FutureEra"})," serializes as a ",(0,s.jsx)(i.code,{children:"1"})," followed by a future ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"FutureTimestamp"})," serializes as a ",(0,s.jsx)(i.code,{children:"2"})," followed by a future ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#timestamp",children:(0,s.jsx)(i.code,{children:"timestamp"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(i.p,{children:["The identifier of a ",(0,s.jsx)(i.code,{children:"stored"})," transaction target, serialized as one of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"InvocableEntity"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"0"})," followed by the hex-encoded entity address serialized as the byte representation of itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"InvocableEntityAlias"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"1"})," followed by the alias serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Package"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#package-hash",children:(0,s.jsx)(i.code,{children:"package hash"})})," and optionally the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(i.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"PackageAlias"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"3"})," followed by the alias serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})})," and optionally the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(i.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsxs)(i.p,{children:["The execution target of a transaction, serializing as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," that identifies the type, followed by any additional data."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native"})," serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"stored"})," serializes as a ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(i.code,{children:"id"})})," and ",(0,s.jsx)(i.a,{href:"#transactionruntime",children:(0,s.jsx)(i.code,{children:"runtime"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"session"})," serializes as a ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"#transactionsessionkind",children:(0,s.jsx)(i.code,{children:"kind"})}),", ",(0,s.jsx)(i.a,{href:"#payment--session",children:(0,s.jsx)(i.code,{children:"module_bytes"})})," and ",(0,s.jsx)(i.a,{href:"#transactionruntime",children:(0,s.jsx)(i.code,{children:"runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transaction-with-execution-info",children:"TransactionWithExecutionInfo"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing a",(0,s.jsx)(i.code,{children:"Transaction"})," with execution info. It serializes as a ",(0,s.jsx)(i.a,{href:"#transaction",children:(0,s.jsx)(i.code,{children:"Transaction"})})," followed by an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," of ",(0,s.jsx)(i.code,{children:"ExecutionInfo"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>c,x:()=>l});var s=n(96540);const r={},a=s.createContext(r);function c(e){const i=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56fae639.036d3ba6.js b/assets/js/56fae639.036d3ba6.js new file mode 100644 index 000000000..21614e423 --- /dev/null +++ b/assets/js/56fae639.036d3ba6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67920],{41982:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const s={},i="Overview",c={id:"resources/beginner/counter-testnet/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/overview.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/overview",permalink:"/2.0.0/resources/beginner/counter-testnet/overview",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/2.0.0/counter-testnet"},next:{title:"Casper-Client Commands",permalink:"/2.0.0/resources/beginner/counter-testnet/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(32323).A+"",width:"977",height:"368"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},32323:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-testnet-40880f888b79830685dee11e2093091d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/56ffdb25.995afe37.js b/assets/js/56ffdb25.995afe37.js new file mode 100644 index 000000000..f94242a2a --- /dev/null +++ b/assets/js/56ffdb25.995afe37.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[45647],{4944:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),s=t(28453);const i={slug:"/resources/tutorials/beginner/"},a="Overview",d={id:"resources/beginner/index",title:"Overview",description:"Beginner Tutorials",source:"@site/versioned_docs/version-2.0.0/resources/beginner/index.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/",permalink:"/2.0.0/resources/tutorials/beginner/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{slug:"/resources/tutorials/beginner/"},sidebar:"tutorials",previous:{title:"Quickstart",permalink:"/2.0.0/resources/quick-start"},next:{title:"Getting Started",permalink:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial"}},o={},c=[{value:"Beginner Tutorials",id:"beginner-tutorials",level:2},{value:"GitHub Tutorials",id:"github-tutorials",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"beginner-tutorials",children:"Beginner Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/counter",children:"A Counter on an NCTL Network"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on a local Casper Network with NCTL"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})}),(0,r.jsx)(n.td,{children:"Queries for users and developers to obtain information stored on the blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/cep18",children:"The Casper Fungible Token Standard (CEP-18)"})}),(0,r.jsx)(n.td,{children:"Fungible Token Standard (CEP-18) Implementation and Usage"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/aws-node",children:"Launching a Casper Node with AWS Marketplace"})}),(0,r.jsx)(n.td,{children:"Learn how to launch a Casper Node through the AWS Marketplace"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"github-tutorials",children:"GitHub Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>d});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/576e11bb.b19d9462.js b/assets/js/576e11bb.b19d9462.js new file mode 100644 index 000000000..798ba30b4 --- /dev/null +++ b/assets/js/576e11bb.b19d9462.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[71914],{67472:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),a=t(28453);const r={title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},c="Casper Fungible Token Tutorial",o={id:"resources/tokens/cep18/full-tutorial",title:"Fungible Token Workflow",description:"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/full-tutorial.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/full-tutorial",permalink:"/2.0.0/resources/tokens/cep18/full-tutorial",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Fungible Token Workflow",slug:"/resources/tokens/cep18/full-tutorial"},sidebar:"resources",previous:{title:"Casper Token Standards",permalink:"/2.0.0/resources/tokens/"},next:{title:"On-chain Installation",permalink:"/2.0.0/resources/tokens/cep18/quickstart-guide"}},i={},l=[{value:"Preparation",id:"preparation",level:2},{value:"Contract Implementation",id:"contract-implementation",level:2},{value:"Installing Required Crates",id:"installing-crates",level:3},{value:"Initializing the Contract",id:"initializing-the-contract",level:3},{value:"Contract Methods",id:"contract-methods",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Deploy Prerequisites",id:"deploy-prerequisites",level:3},{value:"Basic Flow",id:"basic-flow",level:3},{value:"Cloning the Token Contract",id:"cloning-the-token-contract",level:3},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address",level:3},{value:"Viewing the Network Status",id:"viewing-network-status",level:3},{value:"Installing the Contract",id:"deploying-the-contract",level:3},{value:"Querying the Network Status",id:"querying-the-network-status",level:3},{value:"Verifying the Deploy",id:"verifying-the-deploy",level:3},{value:"Querying with Arguments",id:"querying-with-arguments",level:3},{value:"Example Deploy on Testnet",id:"sample-deploy-testnet",level:3},{value:"Cloning the Fungible Token Contract",id:"cloning-the-fungible-token-contract",level:4},{value:"Getting an IP Address from a Testnet Peer",id:"getting-an-ip-address-from-a-testnet-peer",level:3},{value:"Viewing the Network Status",id:"viewing-the-network-status",level:4},{value:"Sending the Deploy",id:"sending-the-deploy",level:4},{value:"Viewing the Deploy Details",id:"viewing-the-deploy-details",level:4},{value:"Querying Contract Entry Points",id:"querying-contract-entry-points",level:4}];function d(e){const n={a:"a",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-fungible-token-tutorial",children:"Casper Fungible Token Tutorial"})}),"\n",(0,s.jsxs)(n.p,{children:["This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper Fungible Token standard is the Casper Platform's ERC-20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed."}),"\n",(0,s.jsxs)(n.p,{children:["The following functions implement the rules defined by Casper Fungible Tokens: ",(0,s.jsx)(n.code,{children:"totalSupply"}),", ",(0,s.jsx)(n.code,{children:"transfer"}),", ",(0,s.jsx)(n.code,{children:"transferFrom"}),", ",(0,s.jsx)(n.code,{children:"approve"}),", ",(0,s.jsx)(n.code,{children:"balanceOf"}),", and ",(0,s.jsx)(n.code,{children:"allowance"}),". A portion of this tutorial reviews the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract"})," and the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_fungible_token"})," library."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read first."]}),"\n",(0,s.jsx)(n.h2,{id:"preparation",children:"Preparation"}),"\n",(0,s.jsx)(n.p,{children:"First clone the contract from GitHub:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18 && cd cep18\n"})}),"\n",(0,s.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,s.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Next, compile your contract and run the contract unit tests."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"make build-contract\nmake test\n"})}),"\n",(0,s.jsx)(n.h2,{id:"contract-implementation",children:"Contract Implementation"}),"\n",(0,s.jsxs)(n.p,{children:["In ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),", you will find a library and an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"example implementation"})," of the Fungible Token for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,s.jsx)(n.p,{children:"There are four steps to follow when you intend to create your own implementation of the Fungible Token contract, as follows:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,s.jsx)(n.li,{children:"Perform any customization changes necessary on your personal fork of the example contract."}),"\n",(0,s.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,s.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"installing-crates",children:"Installing Required Crates"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial applies to the Rust implementation of the Casper Fungible Token standard, and requires the following Casper crates:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow creation of Wasm contracts and tests for use on Casper networks"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," - A library for developing Fungible Tokens for Casper networks"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Here is the code snippet which imports those crates:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\nuse casper_contract::{contract_api::runtime, unwrap_or_revert::UnwrapOrRevert};\n\nuse casper_types::{CLValue, U256};\n\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": In Rust, the keyword ",(0,s.jsx)(n.code,{children:"use"})," is like an include statement in C/C++."]}),"\n",(0,s.jsx)(n.h3,{id:"initializing-the-contract",children:"Initializing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,s.jsx)(n.code,{children:"call()"})," function inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"}),". When you deploy the contract, you need to initialize it with a ",(0,s.jsx)(n.code,{children:"call()"})," function and define ",(0,s.jsx)(n.code,{children:"name"}),", ",(0,s.jsx)(n.code,{children:"symbol"}),", ",(0,s.jsx)(n.code,{children:"decimals"}),", and ",(0,s.jsx)(n.code,{children:"total_supply"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The code snippet for initializing the contract should look like this:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"\n#[no_mangle]\nfn call() {\n let name: String = runtime::get_named_arg(NAME_RUNTIME_ARG_NAME);\n let symbol: String = runtime::get_named_arg(SYMBOL_RUNTIME_ARG_NAME);\n let decimals = runtime::get_named_arg(DECIMALS_RUNTIME_ARG_NAME);\n let total_supply = runtime::get_named_arg(TOTAL_SUPPLY_RUNTIME_ARG_NAME);\n\n let _token = CEP18::install(name, symbol, decimals, total_supply).unwrap_or_revert();\n}\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"contract-methods",children:"Contract Methods"}),"\n",(0,s.jsx)(n.p,{children:"This section briefly explains the contract methods used in the Casper Fungible Token contract."}),"\n",(0,s.jsxs)(n.p,{children:["To see the full implementation of the below contract methods, refer to the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"contract file"})," in Github. If you have any questions, review the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-erc20-crate/latest/casper_erc20_crate/",children:"casper_erc20"})," library and the ",(0,s.jsx)(n.a,{href:"https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md#",children:"EIP-20"})," standard."]}),"\n",(0,s.jsxs)(n.p,{children:["Also, for further unresolved issues please contact the Casper support team via the ",(0,s.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Contract methods are:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L83",children:(0,s.jsx)(n.strong,{children:"allowance"})})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L92",children:(0,s.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L75",children:(0,s.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L220",children:(0,s.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L331",children:(0,s.jsx)(n.strong,{children:"change_security"})})," - An administrator-level entry point to manipulate security access granted to users"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L65",children:(0,s.jsx)(n.strong,{children:"decimals"})})," - Returns the decimals of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L106",children:(0,s.jsx)(n.strong,{children:"decrease_allowance"})})," - Decrease the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L123",children:(0,s.jsx)(n.strong,{children:"increase_allowance"})})," - Increases the allotted allowance for an account approved to spend from an owner's token balance"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L182",children:(0,s.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens, increasing the total supply"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L55",children:(0,s.jsx)(n.strong,{children:"name"})}),"- Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L60",children:(0,s.jsx)(n.strong,{children:"symbol"})})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L70",children:(0,s.jsx)(n.strong,{children:"total_supply"})})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L140",children:(0,s.jsx)(n.strong,{children:"transfer"})})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/370952ddbd2b3bc08cd0394babc6fbaf291c52aa/cep18/src/main.rs#L155",children:(0,s.jsx)(n.strong,{children:"transfer_from"})})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(n.p,{children:["After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending Deploys to a Casper network using the Rust Client"})," section to learn more about install contracts."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-prerequisites",children:"Deploy Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Set up your machine as per the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#creating-accounts-and-keys",children:"set up an account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:["Since we are deploying to the Casper Testnet, ensure your ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/faucet",children:"Testnet faucet account"})," contains enough CSPR tokens to perform the contract execution. Follow the guide to ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#fund-your-account",children:"fund your account"})," or to ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/direct-token-transfer",children:"transfer tokens"})," as needed"]}),"\n",(0,s.jsxs)(n.li,{children:["Install the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," to interact with the network"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"basic-flow",children:"Basic Flow"}),"\n",(0,s.jsx)(n.p,{children:"Here are the basic steps to install the Casper Fungible Token contract on a Casper Network."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#cloning-the-token-contract",children:"Clone the contract"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#getting-an-ip-address",children:"Get the IP address of a node"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#viewing-network-status",children:"View the network state"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploying-the-contract",children:"Install the contract via a deploy"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#querying-the-network-status",children:"View the network state"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"cloning-the-token-contract",children:"Cloning the Token Contract"}),"\n",(0,s.jsx)(n.p,{children:"This step includes cloning and preparing the token contract for the deployment."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ngit clone https://github.com/casper-ecosystem/cep18.git\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncd cep18\nmake prepare\nmake build-contracts\n\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\nmake test\n\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["We will use a Testnet ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peer"})," to send the deploy. Read the guide to ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"acquiring a node address"})," if needed."]}),"\n",(0,s.jsx)(n.h3,{id:"viewing-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"This query captures any information related to the state of the blockchain at the specific time denoted by the network's state root hash. You need to have the state root hash and the account hash to run the query."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the state root hash"})}),"\n",(0,s.jsxs)(n.p,{children:["Get the state root hash, which marks a snapshot of the network state at a moment in time. Use the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"Node IP address"})," taken from a Testnet peer."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Getting the account hash"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client account-address --public-key "[PATH_TO_YOUR_KEY]/public_key_hex"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Querying global state"})}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network status with regard to your account."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"deploying-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsx)(n.p,{children:"Now you can install the contract to the network and check how it behaves."}),"\n",(0,s.jsxs)(n.p,{children:["If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts/",children:"Gas and the Casper Blockchain"})," documentation for further details."]}),"\n",(0,s.jsx)(n.p,{children:"Use the following command template to deploy the contract:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"NETWORK_NAME"}),": Use the relevant network name. Here we use '",(0,s.jsx)(n.em,{children:"casper-test"}),"'"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PATH_TO_YOUR_KEY"}),": Replace this with the actual path of your secret key"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"PAYMENT_AMOUNT"}),": Gas amount in tokens needed for contract execution. If there are no adequate tokens, the deploy will not execute and will return an error"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"WASM FILE PATH"}),": The session-path argument should point to the location of your compiled Fungible Token Wasm file"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Here is a sample ",(0,s.jsx)(n.em,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://95.216.24.237:7777 \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"querying-the-network-status",children:"Querying the Network Status"}),"\n",(0,s.jsxs)(n.p,{children:["You will need the newest state root hash to view the network status, as it changed with the deploy. The account hash remains the same since you are using the same account. Follow the ",(0,s.jsx)(n.a,{href:"#viewing-the-network-status",children:"viewing the network state"})," section to execute this step with the new state root hash."]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-the-deploy",children:"Verifying the Deploy"}),"\n",(0,s.jsxs)(n.p,{children:["Now you can verify the sent deploy using the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command. This will output the details of the sent deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(n.h3,{id:"querying-with-arguments",children:"Querying with Arguments"}),"\n",(0,s.jsxs)(n.p,{children:["This step will narrow down the context and check the status of a specific entry point. You will use the details inside the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/cep18/src/main.rs",children:"Fungible Token contract"})," to derive arguments."]}),"\n",(0,s.jsx)(n.p,{children:"Use the command template below to query the network state with arguments:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "[CONTRACT_NAME/ARGUMENT]"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-deploy-testnet",children:"Example Deploy on Testnet"}),"\n",(0,s.jsx)(n.p,{children:"The following steps will guide you through the process with sample values and results."}),"\n",(0,s.jsx)(n.h4,{id:"cloning-the-fungible-token-contract",children:"Cloning the Fungible Token Contract"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsx)(n.h3,{id:"getting-an-ip-address-from-a-testnet-peer",children:"Getting an IP Address from a Testnet Peer"}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"peers"})," to get the node IP address."]}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-network-status",children:"Viewing the Network Status"}),"\n",(0,s.jsx)(n.p,{children:"Here is the command to query the state of the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--key account-hash-<account-address> \\\n--node-address http://<HOST:PORT> \\\n--state-root-hash E5B679BD1562fE6257257F5f969A79482E8DCEBBD501501BfA6d5844b61cBE3f\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This result contains the network state before the deploy. You can see the ",(0,s.jsx)(n.code,{children:"named-key"})," field is empty since we haven't sent the deploy to the network yet."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the network status"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 401803927542812599,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "merkle_proof": "[25564 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-<account-address> ",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-<account-address> ",\n "weight": 1\n }\n ],\n "main_purse": "uref-<hash>",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-deploy",children:"Sending the Deploy"}),"\n",(0,s.jsx)(n.p,{children:"Send the Deploy containing your contract with this command:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--chain-name casper-test \\\n--secret-key "/home/ubuntu/secret_key.pem" \\\n--payment-amount 1000000 \\\n--session-path "<machine-path>/cep18/target/wasm32-unknown-unknown/release/cep18.wasm"\n--session-arg "name=\'Token test\', symbol=\'TEST\', decimals:u8=10, total_supply:u256=1000"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["This command execution will output the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," of the applied deploy. We can use the deploy_hash to get the details of the deploy."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 931694842944790108,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy_hash": "b00E59f8aBA5c7aB9...."\n }\n}\n'})}),"\n",(0,s.jsx)(n.h4,{id:"viewing-the-deploy-details",children:"Viewing the Deploy Details"}),"\n",(0,s.jsx)(n.p,{children:"You can view the details of the sent deploy using the command below:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address http://<HOST:PORT> \\\nb00E59f8aBA5c7aB9.....\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsx)(n.p,{children:"This contains the header, payment, and session details along with the execution results."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the execution result field appears as ",(0,s.jsx)(n.code,{children:'"execution_results":[]'}),", it means that the deploy hasn't been executed yet. The time to load the execution result may vary depending on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Result from querying the deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n {\n "id": -870982079597140956,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "deploy": {\n "approvals": [\n {\n "signature": "[130 hex chars]",\n "signer": "017B8CE645c728......................."\n }\n ],\n "hash": "F9D4C649Fa78Da07E.......................",\n "header": {\n "account": "017B8CE645c7285.......................",\n "body_hash": "8eAEd6B7bCBB493d75d.......................",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-01-04T15:14:29.203Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500e8764817",\n "cl_type": "U512",\n "parsed": "100000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[417800 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "d3644f0306F20fa6.......................",\n "result": {\n "Success": {\n "cost": "45040980830",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5E4aCF51f54Eb5.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-624dBE2395b9D9503FB.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77.......................",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08De.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243.......................",\n "transform": "Identity"\n },\n {\n "key": "balance-C051e7EC16e08Def8b556",\n "transform": {\n "WriteCLValue": {\n "bytes": "06E07f3abEa001",\n "cl_type": "U512",\n "parsed": "1789897900000"\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "AddUInt512": "100000000000"\n }\n },\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A3...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-d29a34C29769D4BaC250CF9efD3c6372d8e6a89B62fAD122b3BF009990Ae61CD-007",\n "name": "balances"\n }\n ]\n }\n },\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "uref-075874B98e3CF57Ea6326746336A0Aa908e770D3ADe0cf953f7E146f8B64F837-007",\n "name": "allowances"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0400ca9A3B",\n "cl_type": "U256",\n "parsed": "1000000000"\n }\n }\n },\n {\n "key": "uref-4EB0a2A42afBb1d3D5ae9BD4781dc96E528C7AD3f0eEC240Cf1DbDaDF4f3D486-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n },\n {\n "key": "uref-6e87fd661D5a65aF95f02baDfEb64f8E0F44C006661d4903A68E9dF8dEAa413d-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "050000004353505254",\n "cl_type": "String",\n "parsed": "CSPRT"\n }\n }\n },\n {\n "key": "uref-aCA2425C80584391fB883603460578B1472d13a429Ebbd1a18a55cE19cE8F3C6-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "08",\n "cl_type": "U8",\n "parsed": 8\n }\n }\n },\n {\n "key": "dictionary-baA61231F04B1c2Ee97025f425eaD2F70CAd9c1E8c24355246d159038AdCb2e9",\n "transform": {\n "WriteCLValue": {\n "bytes": "[188 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a75...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53"\n }\n },\n {\n "key": "account-hash-7f4bf39A311a7538...................................................",\n "transform": "Identity"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8C...................................................",\n "transform": {\n "WriteAccount": "account-hash-7f4bf39A311a75..................................................."\n }\n },\n {\n "key": "uref-868c0e0BEB2EB3C10e893be96E6D6bE7FC6375f3f038e46c3262509245c117a0-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "Identity"\n },\n {\n "key": "hash-AdF81845d77907054ACb250c196392c7DAEE5481d4EabEB76c318A307c11E5cB",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "transform": "WriteContract"\n },\n {\n "key": "hash-28f982A396052b5068383E725ab48965AB941167f53DB36a0911ba0C98bc39F0",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-7f4bf39A311a7538d8...................................................",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-Faa81ED758ecE1B99E2Ce48073D13D7f6185d9dc5233E39DE5c192Bebb9483D6",\n "name": "test_contract"\n }\n ]\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-04932d42aff9367579770E219ce1C4Da83D1Fd42Fa0FaA4Ae98AE07914c4c1E4",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04400cAa3b",\n "cl_type": "U256",\n "parsed": "1001000000"\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": "Identity"\n },\n {\n "key": "dictionary-Ec3f20485A29255dd2c2D7b8c008207A0d139dFDCE89224DA8b63F21c157A97F",\n "transform": {\n "WriteCLValue": {\n "bytes": "[186 hex chars]",\n "cl_type": "Any",\n "parsed": null\n }\n }\n },\n {\n "key": "uref-66Bf928E1F6A28b174A48Fca4c002Bc8b77Dd851d7EFFb9Dc1A450cB211E484a-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "04C090c83b",\n "cl_type": "U256",\n "parsed": "1003000000"\n }\n }\n },\n {\n "key": "deploy-F9D4C649Fa78Da...................................................",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "F9D4C649Fa78Da07Ec6EFcFC615ff1Bd3B68347750FA0C81B6a74C3f9582d7E4",\n "from": "account-hash-7f4bf39A311a...................................................",\n "gas": "45040980830",\n "source": "uref-C051e7EC16e08Def8b556F9...................................................",\n "transfers": []\n }\n }\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5E4aCF51f54Eb59291599187838Dc3BC234089c46fc6cA8AD17e762aE4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3Fe81B7b862E50C77EF9A958a05BfA98444F26f96f23d37A13c96244cFB7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dC3A5c44A20b9FD260a412437933835B52Fc683d8AE36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": "Identity"\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324F865243B7c02C0417AB6eaC361c5c56602FD42ced834a1Ba201B6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-c69d353A5a3b6433368A8FC2F6b308ce4Ec10291782f61BA15C96F260f91FFC0",\n "transform": {\n "AddUInt512": "100000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{}),"\n",(0,s.jsx)(n.h4,{id:"querying-contract-entry-points",children:"Querying Contract Entry Points"}),"\n",(0,s.jsx)(n.p,{children:"We will query the argument 'name' in this example."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://95.216.24.237:7777 \\\n--state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \\\n--key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \\\n-q "test_contract/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Result"}),":"]}),"\n",(0,s.jsxs)(n.p,{children:["You can see that the name is ",(0,s.jsx)(n.code,{children:"CasperTest"})," in this example."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3650676146668320186,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.3",\n "block_header": null,\n "merkle_proof": "[80252 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0A00000043617370657254657374",\n "cl_type": "String",\n "parsed": "CasperTest"\n }\n }\n }\n}\n\n'})})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const a={},r=s.createContext(a);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/57d593f0.9081b32b.js b/assets/js/57d593f0.9081b32b.js new file mode 100644 index 000000000..9829722ae --- /dev/null +++ b/assets/js/57d593f0.9081b32b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25120],{90459:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>h});var i=n(74848),s=n(28453);const o={title:"Highway Consensus"},a="The Highway Consensus Protocol",r={id:"concepts/design/highway",title:"Highway Consensus",description:"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.",source:"@site/versioned_docs/version-2.0.0/concepts/design/highway.md",sourceDirName:"concepts/design",slug:"/concepts/design/highway",permalink:"/2.0.0/concepts/design/highway",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Highway Consensus"},sidebar:"concepts",previous:{title:"Zug Consensus",permalink:"/2.0.0/concepts/design/zug"},next:{title:"Rewards Design",permalink:"/2.0.0/concepts/design/rewards"}},c={},h=[{value:"Unit Broadcasting",id:"unit-broadcasting",level:2},{value:"Block Finalization",id:"block-finalization",level:2},{value:"Important Links",id:"important-links",level:2}];function l(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"the-highway-consensus-protocol",children:"The Highway Consensus Protocol"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159",children:"Highway"})," consensus protocol was used on the Casper Mainnet until the ",(0,i.jsx)(t.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail ",(0,i.jsx)(t.a,{href:"/2.0.0/concepts/design/consensus",children:"here"}),". This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs."]}),"\n",(0,i.jsx)(t.h2,{id:"unit-broadcasting",children:"Unit Broadcasting"}),"\n",(0,i.jsx)(t.p,{children:"In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"Citations of other units (at most one per node), subject to validity conditions"}),"\n",(0,i.jsx)(t.li,{children:"An optional proposed list of transactions to be included in a block. Note that the list can be empty"}),"\n",(0,i.jsx)(t.li,{children:"The unit's creator and its digital signature"}),"\n",(0,i.jsx)(t.li,{children:"Additional metadata, including a timestamp, sequence number, round length, etc."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:'An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn\'t clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.'}),"\n",(0,i.jsx)(t.p,{children:"Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"DAG",src:n(72164).A+"",width:"787",height:"479"})}),"\n",(0,i.jsx)(t.p,{children:"Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator."}),"\n",(0,i.jsx)(t.p,{children:"The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era."}),"\n",(0,i.jsx)(t.h2,{id:"block-finalization",children:"Block Finalization"}),"\n",(0,i.jsxs)(t.p,{children:["In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum ",(0,i.jsx)(t.em,{children:"q"}),", a percentage of the participating validator weight, and a level ",(0,i.jsx)(t.em,{children:"k"}),". Level ",(0,i.jsx)(t.em,{children:"k"})," represents the depth in the graph. For a given fault tolerance threshold ",(0,i.jsx)(t.em,{children:"t"})," (FTT), finality is defined as:"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Finality Equation",src:n(28714).A+"",width:"474",height:"62"})}),"\n",(0,i.jsxs)(t.p,{children:["If ",(0,i.jsx)(t.em,{children:"q"})," is close to ",(0,i.jsx)(t.em,{children:"n"}),", meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT)."]}),"\n",(0,i.jsxs)(t.p,{children:["The existence of such a summit means that a weight of more than ",(0,i.jsx)(t.em,{children:"t"})," would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block."]}),"\n",(0,i.jsx)(t.p,{children:"In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network."}),"\n",(0,i.jsx)(t.h2,{id:"important-links",children:"Important Links"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway Whitepaper"})," - Describes the protocol, and the liveness and safety proofs in detail"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"/2.0.0/concepts/design/zug",children:"Zug Consensus"})," - The protocol currently used in Mainnet and Testnet"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},72164:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-dag-cd0520491022e0a3dfdab640eadc36eb.png"},28714:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/highway-finality-3085c2c54335e90870c04d973492a99d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>r});var i=n(96540);const s={},o=i.createContext(s);function a(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/57f923a9.ad12da5f.js b/assets/js/57f923a9.ad12da5f.js deleted file mode 100644 index 8ae9abf4b..000000000 --- a/assets/js/57f923a9.ad12da5f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3627],{46896:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(74848),s=t(28453);const o={title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},r="Launching a Casper Node with AWS Marketplace",a={id:"resources/beginner/aws-node",title:"AWS Casper Nodes",description:"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/aws-node.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/aws-node",permalink:"/resources/tutorials/beginner/aws-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},sidebar:"tutorials",previous:{title:"Fungible Tokens",permalink:"/resources/tutorials/beginner/cep18"},next:{title:"Advanced Tutorials",permalink:"/resources/tutorials/advanced/"}},c={},h=[{value:"Step 1 - Subscribing",id:"step-1---subscribing",level:2},{value:"Step 2 - Initial Configuration",id:"step-2---initial-configuration",level:2},{value:"Step 3 - Launch Configuration",id:"step-3---launch-configuration",level:2},{value:"EC2 Key Pair Settings",id:"ec2-key-pair-settings",level:3},{value:"Launching Your Node",id:"launching-your-node",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"launching-a-casper-node-with-aws-marketplace",children:"Launching a Casper Node with AWS Marketplace"})}),"\n",(0,i.jsxs)(n.p,{children:["The following tutorial outlines the process for launching a ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-d7xpciuetjq5u",children:"Casper Node through the Amazon AWS Marketplace"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1---subscribing",children:"Step 1 - Subscribing"}),"\n",(0,i.jsx)(n.p,{children:"You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 01",src:t(21587).A+"",width:"900",height:"214"})}),"\n",(0,i.jsx)(n.p,{children:"If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe."}),"\n",(0,i.jsxs)(n.p,{children:["You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/ec2/instance-types/",children:"Amazon EC2 (Amazon Elastic Compute Cloud) instance type"})," if you prefer."]}),"\n",(0,i.jsxs)(n.p,{children:["After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the ",(0,i.jsx)(n.code,{children:"Continue to Configuration"})," button grayed out, as shown below:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 04",src:t(75832).A+"",width:"259",height:"60"})}),"\n",(0,i.jsx)(n.p,{children:"Once the system processes your request, the button will light orange, and you may continue to the configuration options."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 05",src:t(96961).A+"",width:"266",height:"68"})}),"\n",(0,i.jsx)(n.h2,{id:"step-2---initial-configuration",children:"Step 2 - Initial Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Configuration"})," page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release."]}),"\n",(0,i.jsx)(n.p,{children:"The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 06",src:t(79246).A+"",width:"1138",height:"713"})}),"\n",(0,i.jsx)(n.h2,{id:"step-3---launch-configuration",children:"Step 3 - Launch Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Launch"})," page will show your previously selected configuration details and a ",(0,i.jsx)(n.code,{children:"Usage instructions"})," button that leads to the most recent instructions based on your chosen software version."]}),"\n",(0,i.jsx)(n.p,{children:'Below this, you will see a drop-down menu with the title "Choose Action":'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 08",src:t(8471).A+"",width:"834",height:"189"})}),"\n",(0,i.jsx)(n.p,{children:"This drop-down menu includes the following options:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Launch through EC2 - This option launches your configuration through the ",(0,i.jsx)(n.a,{href:"https://console.aws.amazon.com/ec2/",children:"Amazon EC2 Console"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Launch from Website - This option will launch directly from the current page, using further configuration options outlined below."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy to Service Catalog - Copy your configuration of the software to the ",(0,i.jsx)(n.code,{children:"Service Catalog"})," console, where you can manage your company's cloud resources."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional drop-down menus include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.'}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-key-pair-settings",children:"EC2 Key Pair Settings"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 11",src:t(66716).A+"",width:"830",height:"245"})}),"\n",(0,i.jsx)(n.p,{children:'You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 12",src:t(33253).A+"",width:"339",height:"43"})}),"\n",(0,i.jsx)(n.h3,{id:"launching-your-node",children:"Launching Your Node"}),"\n",(0,i.jsxs)(n.p,{children:["If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange ",(0,i.jsx)(n.code,{children:"Launch"})," button to launch your AWS-hosted Casper node."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 13",src:t(55074).A+"",width:"137",height:"58"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},21587:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS01-26219ce99c140282c6ad9137863a954a.png"},75832:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAA8CAIAAADt6EhQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAiFSURBVHhe7ZyJchpJEobpbu7TgCWhA+uwxp6dHUfMW+y8086DzT7IHjFrW7JBB4izgeZs2K+ohmCEhCXNWIus/IKQu6u7qrKq8s/KQgobTrfrE4Rnj+n9KwjPG1GCIChECYKgECUIgkKUIAgKUYIgKEQJgqAQJQiCYtVv1k6KRe9KEL4JDvf2vKslZE8QBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEASFKEEQFKIEQVCIEgRBIUoQBIUo4VtgMplUGo0PxeJZ+Wrkul6pcB/W8a+y7U7nslLtDwZc+/3+7ZfZF4mEfvRgmu3254vLTCq5u7npFa0BeO1lpdJsd8bjsWGa8Ugkn9uyzHuHp4tKpVyrR0KhgN+fTiYKpXIiGjnY2fEef2UKpVKj1T7YziViMa9oXXlKf5VdLJVPzs7HrovXbqTT4VBwPJ54z+7DcDT698lpuVbTt6FAMBGLxiIRffung8z++7ng3dyNbr//2+mnWtOOhMOMNJ2IG4YxGY+9x/fB6fWCgcDh7g4fxpiIRr+qU2L5Pz98bLRa+jYWjiRjsVAopG+fKOulBLvdqdv2i0T87eEBwTv3Mnu4s4Mk9FN3PCa08+FCl8whPWB5arY9GI10CVEWOelrQFHEyGt7S384xBF7vb53vxKkVbdbLcehYa9ogaHr9TtnhbWAwedXlfFkcpTfO9rdYaSMd387xx6on+rh8JNrXWXOstmLwYJt4WBnO5tK6Vuqtx2n2encaMZtMFh64YLBdnu9SqOJ2OaWMMmLVrFAWB6cWg484mUs1C0swqNry7Q+rFd2VCyX602bwBaPRr2iGeTBF1eViU8tAKuwlc3kslmuicQsmzHNNPTi7G5suGMXP5veKTLJ5EYm/aFQ2Mxk+BC/bcchCRmxomp1fITknY2XlHd6veP8Hs5Em+8LxVg4/Go7xxtn5TJLSwIzmYwt08LCaDisG2dpaXnken4WCgZpAQHcaO0ccr/3nwvRaASpe0Uzhq57en7uOF3TslzXJec53NvFz240m1xosfc5DBnLcbiT4hkWWpZFIbNE8Kb8tpGq8m6Xl3Fl9pbNTJoS1ZxhaEuO9nYZF66sCqcwb/xk732dz/MCfZ2eXwyGQ9M0URGNoHOub1ym7AtPro/Gk8mOmCzTMFge734G81uqVpHHu+NjPiz/Va3enmkY78xv5959d/wmn2fSWUvc/e3Bvt8yWaef3r5hjfWbc9guCMNU+eHoKBQMUMV7cBOcW8gEdjY33h2/fru/z3JWGw3vmc/H8v94fMyS86GvvxwesNgrrNUwUjaE5ZFCqVLt9QeHu7t0992rPMI4L5f1o2Wz572jwL++PsIAPXD9PhXp6PhVnqbwe7IvXb4CxBOPRhgFGwtZ1g+vj+iO6ntbm/g3PTKZPEKQ/KQ7ptqrOQ35BCB+MktUeZXbcnrd0ixBXV4mXb4mrJcS3JFrMsdLR0bcyHXH5DasJRDwVKHj6KemaYUCAS4sv3XH46ZpGuFgkAtqEON14W2QEdFp0B9AkLiv5ff3Btf3/UVWW6shihMa6d27n0EOg4uEAwFONdxOBRamXxya23uZTVP9wRCFcBDndjo3X54cyzTSySS1UCnvU4eu2cH0rrIapNJjMwmHyUW5TcXj4WCo3XHU/vWgZXpM1ssgjn24iF71RdQ5UjmVd8uqcD1Y6Y5/ImNlkvvp8pJ8hs9gMAivPB3exVoiumn4+n31/dgi6niD36jqXn3LMMlMHvDdqNfUH4D94T+nn/718eS3T58Ll6UvtkV3pG1zyxES16Px+AHGPz7rpYRIJMzykY149zOIf8zufFnxDK4JW979V8bvtwKW9YYcgzxh+slvrfoq9i7WovmAP+DMgv0cgqWKl7jUrL7LycRSYVTf3h2qENU5Mj3YEUuVCsZ/f7DPkEl1ZtK+FbXpmNbc8qkSJ9jwAOMfn/VSQjqRYPcvV2sXV1f94VCnCuQViXiM2SQ7V+etyaTatImay6fqRQy1HAbpAe+zJLpwNcQy2idHp0rbIcPxfDQeibKk5XpDrzGt6d91LIKXUBe35p14LPpFa3GaTCpFOvGxeGa3OzgcbTZbbToiL+oO+nVbfUdJYtZx1GHgxhPFaojHyXh8MBwVS2XaIYOfq+62kV5jLmZe6/5u+1KiwHjKQRcB8o6GQ61ut9VRqWC91eoNBszGfJdYZ6y///KLd7lEY+ErgseBkJJKJEiLa7ZdqTfKtRoOwRZL5oorUHhZrZaqNfKTXDZDIVVqTRvvyaSS+BY+yjtBvz+ViBNHaYeTLlVG7igaidRtW59rm+12fzjAEbV70QI/1deOhtFstarNZrlWn/q6wdLSFEkzS1mp12kKky6rNbb9a1/Y4w4Nu0XFRqv9MpWiyo3WLsIBwG/52QB1j5VGo9N1yK35OP3BFd1VqthMJsZBk9HdavbvJwEXpxYGYDldkLI0Oh3qMi1EFj2i20Z6rQuGyXCupgvB3NJFMhbDHjZJzkJ0yujokTcJWLoW89zqdKazVEUPzNLe5gZKuG2ZqPuYLK/CnDX9n7+INIQT4jpJBfKYFxKHmFD2ja8UZlgkEnpyEe0Ki9xo0grubi2hGvelTX2g1OC1VGdvWbbkYdDL+0Jh+mts9U3aipEuol8LBAPa4++IHhHquletR2DFt6jyf+B9y5BYjtwxOwMyu6hU6k07n9v643+68nQRJTxTOHgUy6XhSJ2Y2V42s5nNdFo/ep6IEgRB8ZT+Ak8Q/i+IEgRBIUoQBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEATFqr87+sevv3pXgvBN8Leff/aulpA9QRAUq/YEQXg+yJ4gCApRgiAoRAmCoBAlCIJClCAIClGCIChECYKgECUIgs/n8/0Ps5JgKFFEE0IAAAAASUVORK5CYII="},96961:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQoAAABECAIAAAD2jOw2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAoZSURBVHhe7Zx3cFTXFca3F+2uCuqsGkKWEDIWEiOaKDYgAsKywLaCnTY2EOwkkzaMJ4ntTDITx+SP2CmT8XhsQ4zHYwwulNASQEh0iSK6wepCfbXqW7Q1n/ZdrRl2r7RgjBc4v3mzere8984t37nnvlmt2GyxiAiC8IeE/SUIwgeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBJexv7Gr3q1mZwRxX2BZFui31Gn1IAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJI/7B7dbdNoQ/peq9J2NcUNOGtk7QPB2Yn2/5qUTD+dvm4dj1aHcL/u0rOBrUN2rnfrJgh318SwdHGAqf1KrL943Ey1dvCv/vS9SbK7bGZf/Nccs3zezw6Js6Nc0DITM2jb/7SsTWNk3z8c1CdM/f7RxIISl7wukr7z6KjvlIK/+Mzu7i3xap1+5Py9WPbQms/E7SZ0ysTtZa4lRD7HigDE7pKvLciNVtmTd8Ff8JRK3WuaaGds9TmUXKtxZ3r+WhIm+MMHA0gHQZVWsLs/dUpNQMrFlZVrL1Mg+aCNrXL9M4mY1AgadppU7/jb74px4Y4jMKRG7Z8T0xIfccqcFCCx/9kBeTmRflNqGpFgkwgBNj+lRSF1ChaDFkT7GnPcSjKtHXb/mtTMZf8r74v3HzhRPaFuoN/x8Sh1mjFCK2YMKOHxdLKKL7iHFxe7QQbtMyLE5JV1WpXAOIhT2FyfXp4WZWNrDgF2GS3AhS48K9HatV9s8qHa4MB9upt2sYmcjjGItgMEbryYbLMqDRUd/OaUWLUV7n8toUnlmmLc5+MT5TfiaPWBjrQaQxwuTG3Ki+oSkyy1uNqmxpPg1gwcai6fgBI01WBVnu8I7zErcSihFJ3v7GWCAfpzZAH0KSVRDZVgo3OFGfIcpaAnG/xb8vG78+qr07UtO6jVWljUCYus1ZblOzwj1Dsk3LTizQD/sql+pmFw3oHG6xDX9GnS6yy36dHFlv1226D9zPNcN8878qseT2xF+vD7j8rx4Izz9R9WJSTrz6c4I3BBRwZaCyqVJHcgvbYl+e945zDDMjxcPT8UjMGUxqHDPv6nIilLZLA5pis684dGz3gUNrhR3ruyMEJLPpDXjDld6dH6t9YLM7x3MW5rYDv2zrBHwiNer0hFoJWvNiDOXp7a+MesSJp9fs/Niem58uhc0GZajQ9adeHh73fgJoSaxWKSUup7LaEQ+r6XI39MYh8r/upT6qym1yCnZPx1rES6s69OsSG19c/bFrbX6teU57DEi0YGio/h8uSILo4b+MVoVCIz3N8fEa6y1fZpfZ9f8duqXWA/9DtPUEQ3fNe7t/xZsMami1TaNzMnSI8Dl/OFU5qpJjedLSi+UHHxtxpXfV2a2mpjD7rfJ/p5/4ezTh04+WT4xzHzOGAYNtP5o7/SYHgyebe0ODLNQ00uLWbUuu+ZcSenppw5hQh9ti2QF/qgf0Pzj4sStBZWVT5YdXX5YKXVi+FmZSIQ5gcyXsqtx4FkfLDhjdUpHsVbA5JAaLApfLwD2NMUeaI45uaIczTn33VJMsg+rE4UiX7O9T0eyd9UuGCA0XKiPC6/16qpKSnGr3YUnwhRjB5YVhog5ccaWH+57edo16OTUU4fQsSdWlO9edvxUZ0TTQAg680JJaV50Dz7xOHQ1u9KzOGy4mtxnk11YeRB9dWT5YYSOB1uihVLfYRLyg5NglIdxSBmhtMl9QtiaPk3DYMiihE54MnjBRfpOhApXe3VCKTYY4crhgVdJnbFqPxPOF8Ra0aph9w+/KJyMwrmuMEysaJUNC4XdJU7SWq50s0f7ZXRrBcx2GWIPwewbQU1oY358V5LWjGR8iLU4pe1IWyTkhOQtmY1bne8Ky481jveIEJ0TiDwSNZZZcd0wDE4KXl8ucWN5wVqnkTtxB1aJQ59NXtYaXZjcATuRTA8bRCccaokW4sPbGKZvkWCUR4rOhGDd5BOYWp2SIYfEazEmB46mwbsU+yFUQzzzzIG84r0zcVR0RDwSybZDfgnE2giVDY6/3udtD2J9KEHq0ZWATuFAHIWIi6UDRrgVS9wWiIJ+eiQ7c8uiZXtmoeEdlq/2cn5xuMVYImC8kIS6QqTOVrPK4vxaZnwrBKM8JkcMYO97qTuUpUcIlTtCFQ7vmjKE+eeUwIuz9DcMthnTYnr3Fh4/tuKwcKxMa2Zl/gjEWlSYMq6/vDUKvplleVBIXPCy2Fp4d+TYdifrzGqfgHNM1FLn+BCrwarE01nWLbKjIR4x4fmnS9HknUtOxo71/hBeAMuCsOMC0KfZKYUNsETIuYcIRnlkR/Y9kdL2syPZiL8ReyA8aDOrsCFJCzOlhZq21iZgpF1u8Z6mOHimSeED7DJ/SMTD3qvFpMY88/uuyRcEEgiBuq3DL4uuD6qxjgn5k8IHO8zK/16PFV7d4G4INoQiL3Kpu8OqxFxHnYmhY1sLGWCXjP3x7yqysDigpbhnbb8Gc2tJYsfuprhLPcM+As7is3r93Hij735sTLD+FCa3l7ZEYcON5mBLfbx9nFDEa+lNIJIUTtCKZpMKeyohifXB5JAZPJcLfSKgkzsKEg2bqxNgNpKXe0L3NsU+pjd4V8J7iGCUB9zPX2dden5S4/Ol0yL/vUz7XlHG5oJj7ZFauQMb3MOtkboNRap3n3jzfBqqCSE1jwiF7dm06y+U5yjfLd5Sm8ByRyU/zojxTv1ocdjGorcup+o1zN+nhpr+OefCH09Pit+0FKX6D5ZiMyAUeVkxofVYW2T4xsfXlOVg7xSItTNie3YuPYlp+tDmArQ0ZlPhL44+gmm3UG9Yk9mQv22+4p3ijI8XYRP8g4eus2tukblxxrfmnv+sTr+6LNfhksD7CPm8lt7EgvFdPUOKKVsXpm0u2N8cg2VNyE/SmYtS2pbsnq3dUHSig0lOAKbmRPXBbBg/d/u8n2TVozms7J4iqH8GDj6p1zbsoUPldrheIRMjis2fSyQOV9ix6xUy7yxYGfrtcuwdQ3y8tV+TRiFwa7Hm4IBrgPdlWZ6NNeJ4mOFrye2Bfcja8pzCpI7ve8Q2SktvRKgG94TljmUFgNAiBJC3dNVdIPAXu/Qrifc/iEvNdplea4GedzXEra9K/3Dh6YzwQVb84EHyIL4CmxkEbGWtUXaXZE6ccf2My4joWNkDCcmDILjQb+wSxB2A5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMFl7O9cnV2Xxc4I4r4g943L7GwsaPUgCC5jrx4E8cBCqwdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcBCJ/g+JpAip6TfCDgAAAABJRU5ErkJggg=="},79246:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS04-f0a5f08295ac98ac10216dda2c6ac467.png"},8471:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS05-ef5cc7abd1f5093685ce82cb5794a2aa.png"},66716:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS06-fa837b0e61647fe37340261a3ae8fde3.png"},33253:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAArCAIAAABKL/w7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAC3hJREFUeF7tnV9IW1kex2tq/f+n1dbqVOiTT/pSaFkYH+ZhfWj70AWRUp1i7SozVtBm65QGsVhlm+K4EkJrBmmV8aE+uJXCECglOIuEHQTJS9xuW3TdBpnS6A4GsTQEIfs75/xyc++5N7fJNXE0OR++DPeef/d47/ne8zvndsihkEAgyDyE8wWCTEQ4XyDIRITzBYJMRDhfIMhEhPMFgkxEOF8gyESE8wWCTETP+a65+T/f+EvT1x37RNAZ6BJ2TsV+6+2Blv6t3nn1ODxZFB4/JLTfNVkEDwsfmxI958PjX/7Pf8P7BugMdAk7p2K/9fZAo3+rhe0PkiaL8LEp0XM+vPtxIOwboEvYORX7sLcHGp1bzY8tof0tfGxKhPMF2gjnp43wsSkRzhdoI5yfNsLHpkQ4X6CNcH7aCB+bkhQ6f339fzOzPw38dQTauWG+A3o0Pvmvf79huZBooH2d4bjL3go4dG41N7CE9rnwsSlJlfPB81BdU/AugALsmBWOH6iCnVNhoDWBDjq3mhtYQvtc+NiUpMT5bJ4Hgf/ZJA/zPwsBWDrM/+yAlY8fqIKdU2GgteSz5VvyvPbv4NmBRudWcwProCs4kuO25HlHsrj0PZZ/MG/RauISkyJ8bEqS73xmb/C2FNjLAf9LtjfQPlTBzqkw0JoWIc9Ub9et3q6phRCmxE/A/T35o/pevseEg4zOreYGljEFh/OfNpU31p8kaiib6E/JoI9H/u4TFVWnr3cf5tL3VIMlf6w6XVFVusilJ0P42JQk2flgbKgF0rQ9y5ILM+IGqmDnVBhoTYOtn63YN/vCJ0yLjecJlBxw+vE0vLn04737joUPeLo3SBGWWo/GJ7FQ4kB1vLMquIFlQL7esotkoINOXayvPJs84zEb2/r5dB3tC+ePZTubyi2dOUEuPRnCx6Ykyc6HoQa1YNrHcyVsOMqFGXEDVbBzKgy0pmZzfgja6Ru6C/+1ugOYKvEpsLb8em3rI55+eH4b/oq+mdWtwPYnGiJ8CmxvBULyaD+0sfpqwfNqZVMeQpBitBGau/ROdqGd0OY7r8fjXV2PXOVzyGMoTpCFhRIHquOdVcENrIRly7fUgOcrLeZsfqCPmQJ2E03MihwQBYchIM99a1ME5EG7yTeYx6UvXiEvFOt3UjtUY6a3/XnuwezgD5EUmTjnQ7NQNzCGuUHbkUVYCwxHLvFQkRv+gfQzYOdXCqSRh3CQFbify18XqoySNpXpinYi1enl2MEuhI9NSUqc/4/5f+J5stEZjgZ6qyIw9wAMY19Yc/aBc77/eRvTwZAbC+O9zRFHNU95w0sOdoya9ECppUly/GSJ1Qn73X/riJbpGXHjKoAWs4w8uis12DHlJW+Gj54nZkwBxblqgPDq257bUi25NCOvOIHqeGdVcAMrUQV6y8hsf6EgoMqiJqy2dhWaa8HAJ2ZHYOjn2r6sJuWJqhuv5jI/e1tPRRJpentOePzwbIOUAqLVIb7oKYeYAhNry53D0csxyZ3v6z5eV3W67nyhj2RlOy9Er3L2QgEkBi1HoUBFUx7rBqvb0pkttUaVa4My5ypayF9Bda7MRTsTHi0wk7deRLVlLhtNHym8DqcNhX6pekPx7NWT5FotubKWjQgfm5IkO5/NPxDz43my0RmOBnrLE3h5DwxDDL/y7BY4Z2guMhn7X5IooLnv8dyyb/vX1+4378OBFc/zB5DYdMsx51nw0Hlb4fxfZ25CbtvQs+UN//JMXxtk3X2xTnJYsZuT7tX1wJrbfo0UewyVNl0k4rjn8kHgsL2+svoh3q0GaetUrliRV5xAC3hnVXADK1F5rxInN37DuYWIGamittLcVOJoLXaPZrkvQ+EKx4ApPG5yX6mK+rm/wDtMp9/R/AHwUk2pdzzLP1BgrSeOMndALJDjh5nZWtQCTr5U4IfZdbgI3FWnMpLk/GB/KVmDnCtdpNOsr7MC3imWHvpG6CSvJLqIyHGcgUscc5Np3+S6BMfYJZmodatOTAweDtizXZcrof26y/RlYYfg5YifTO8mbwe0f7qTtq/h/Krq+q/KrK0l1p4jysYTFj42Jb+b89noxJO40RmOBlrjYPZmQf7a8144vjfPrL/xYgh62zO1TM8k2LQvW+fLnc9sfG36Nc0JL02RrD7XBjmWvyDWaXzxtQPOQot2iAKazQ+mf1nZTPADARfz7ybOZ0AjeGdVcAMrUS22EHNqrqvl0y9Vjg1c/YejsxAbW/KcV05CbnQNj5F2Np3q2d4YTvtSGX/PcTg1t5PqbkuxOequqPCiV0o7yRvk+CwGBYed56Gp8gl6aXdHudQx9kYgl7DnW6BBjeCFWTeyXTdMXU3eTViALSiCllKpTS3nJ223Dx+bkiQ7n+02fTbIhOUAFDOw/6QzHA30VonvpzvEM81ddG+/6wYcR1z9/sUAZOGMHUXX+ew9IkXs8tNYzodwf/Wl/WY7yW1qvzv9Jt6lPsDF/LuJ8xnQCN5ZFdzASlS+b4iBK65oBLEq5zMPyFXlGCRZvt5jjfKwOZbzWRAh16V8zqisTF0NiUTq2cxMxK0diCy99AMEiyNacoN3jkUTFVJa9yF9QbDThzkTDfJ1Sro4n4Wdn7V0nMXU6AxHA71VwILz9h5ie6pr0ficzfkRr0roOn/bTdYCzXT9D7AsFlDEdj5lJ+T3OEhnhpybmBQXUsy/yzifAe3gnVXBDayExb5gRWfXqLTn/DMl0myJGssbgBbqi9+SHTJm0RjOZ3O+We+TIV60K3f2PJi/urObLUNwzneydbhCJucF0itHS3VFzVEa9nNSWtda1Eh6W+SLvPXwZdGfRnO+/lc9BmR9tkwsoBZ2TgVkYSFDsPC+6/kKnkf8edPpg+NN9wOyG9c9ND2/4PG8fOYmieG1mS5IbLM8mV+YWyIpCksHfrbCu4PmeuYf3ybHD9jngljO3/Q8f/HLwtK7jbWlH0ligs4HIMhn/0Ry90AP8c6q4AZW4oLlMd20q/mik6znSxxN5Y1tOZClcv4hbxsskqsbG4tcNOp2dRcu2iNh9pmj7lGTf7DQQhbezCdZ7ibi/It/KnJ9l+eFkuw7Qu0Jh5kF/AVPe/n9hehFH+bazkH1Sls/2WMP9JbVVZ0+21DiZAG/uchlxSq4zyet3nkx61aa2wvgiravyB/LdgG9bVXkWp1HYJHibiHr/DRxPsAieRiCmsaWbG9sXtIZjsZ6i+ysTJMtPcVKPrRgJ129M7NGzj6+/Xt0K/7atJcWCUgb/mS3n7M0TPtvnt5moTtIFr3HdP48fb9g+aEXe/vvAjigD3hnVXADy5BMi63H66PhenV9DOeHx7NdjXSLm6m23DUKiVneVkys+/KYJTrnHwrfL7qOO+rHnaTkoeBgcSQFhBeSS3FRGslH4pEsb/uJ6HeBmi8cA5FaY3lW0nlceqjErFtxHQN7eHPl048F4PAC+tkCdOp6YxnEAunjfJj22bc9ENib+R8S4UAKRw3PS1AXO6cCsrBQ6tgJ8Z/rgZ0Qn6IgFNqKfL2PB3qJBMqnDJ1bzQ2s3Qj3urQ+sytEv/Pzn83Jp3X+QzpqTOsDezwXUkv7i/2RiXqtZQhKZl3oJL8coA1qrBFSJXxsSpLvfAB8Lplcrd2sQqE6dk4FZGEhQTLQudXcwMowZbtaS6wXyIc61Wd8SUmetHcpfGxKUuJ8Bpv82W4/W3+C5yERsw0hnL9nCOfHEN10lAfwGsqZIP8/QnGMiGCvhY9NSQqdnwqE8/cM4fy0ET42JcL5Am2E89NG+NiUCOcLtBHOTxvhY1MinC/QRjg/bYSPTYme88UvbWQs4pc20kcGfmlD/LpWxkr/Votf1zowMvbrWgKBIF0RzhcIMhHhfIEgExHOFwgyEeF8gSATEc4XCDIR4XyB4Pdh/bff8GjvCYX+DxMofqYM+5EQAAAAAElFTkSuQmCC"},55074:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAA6CAIAAAALGO1FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMmSURBVHhe7ZxRSFNRGMev1+6cF2pr2NRYoRU+pEhgWSTGQERTxpAg7cGgp7AeevTRx/BpTyFEMLUgsdIksk3FXpIEg8okJSqFzBRUrgruzMtm5+4ehYZL9qD8h9+Py/adb2eXc/ntfDuHXZa2ubkpEZDI4pnAg9zgQm5wITe4kBtcyA0u5AaXBPubF2kiIPaBaztvMWne4EJucCE3uJAbXMgNLuQGF3KDC7nBhdzgQm5wITe4kBtcyA0uB9eNtpT9dk5looUIjhtHW1dl87cM0dp7piYvVY1la6KFCI4bWVtVpzfSRYtIjZqmK5rmGF1StYhI7I6uzCw4ZnTREkRljSkai79kFlanFmxJnHy/QHfz6b3H8qSiPlDS0l/hbK/0zRkDnp8ot/Tlz5s9JLWrz3t9QuWRkX9e4huqLO5y3x4oK/B7WqYVsxObLfR2eJxPK+qf1VreZZlJKZTt660p7Sm7F7jibHf7l0UaBHQ350pfb9wKBBsGg42BvpNq80+HeCERy9bci4Pjjbz/QLdLvv/bZiRDrubgKdv5YeNUja82Li/GunLW6672j9/gnUdaD9nezBmCcYCvaelR/sCYwqL60Uwz9X/W8g6bQTjniBlI2qyrLfLrTuGaaG9fdOZanjUWyCzXHguQQHdj1CK/p7TX7e2uvvlVJJOFhXlli+J/DuMAH2+WL3gmrzxglJ2GQOdZkU0Wu7ouSUoobmkAD5gbviQzllLmERvb9vIpos6sitAY9aJjMmyEbNXxcbdNijV3oSn9uP+LTTMKpMT01JhBWKN8OeZ2dtZsHUWj0mLdhZWe4erixzUF3UV/1BWzW07+dJPsqurwWh566j9Yc46Z6cRkzrbWfmef3c5H/C3e4qETW2s8aFLh3kE+maIRe0bsM78N36zwjaqi25PZrfIvHibrdrGuhiGF7x3kAuLEcOSo3ZqcGI41A09MYlKj8h5MyA0u5AYXcoMLucGF3OBCbnAhN7iQG1zIDS7kBhdygwu5wWXn3whG7p4WEbH3lD34IaJ/oXmDC/3vIC40b3AhN7iQG1zIDS7kBhdygwu5QUWS/gKbZ/EkaoCEzgAAAABJRU5ErkJggg=="},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/57f923a9.f57d37c0.js b/assets/js/57f923a9.f57d37c0.js new file mode 100644 index 000000000..b6ee3a8df --- /dev/null +++ b/assets/js/57f923a9.f57d37c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83627],{46896:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(74848),s=t(28453);const o={title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},r="Launching a Casper Node with AWS Marketplace",a={id:"resources/beginner/aws-node",title:"AWS Casper Nodes",description:"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/aws-node.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/aws-node",permalink:"/1.5.X/resources/tutorials/beginner/aws-node",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},sidebar:"tutorials",previous:{title:"Fungible Tokens",permalink:"/1.5.X/resources/tutorials/beginner/cep18"},next:{title:"Advanced Tutorials",permalink:"/1.5.X/resources/tutorials/advanced/"}},c={},h=[{value:"Step 1 - Subscribing",id:"step-1---subscribing",level:2},{value:"Step 2 - Initial Configuration",id:"step-2---initial-configuration",level:2},{value:"Step 3 - Launch Configuration",id:"step-3---launch-configuration",level:2},{value:"EC2 Key Pair Settings",id:"ec2-key-pair-settings",level:3},{value:"Launching Your Node",id:"launching-your-node",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"launching-a-casper-node-with-aws-marketplace",children:"Launching a Casper Node with AWS Marketplace"})}),"\n",(0,i.jsxs)(n.p,{children:["The following tutorial outlines the process for launching a ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-d7xpciuetjq5u",children:"Casper Node through the Amazon AWS Marketplace"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1---subscribing",children:"Step 1 - Subscribing"}),"\n",(0,i.jsx)(n.p,{children:"You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 01",src:t(66217).A+"",width:"900",height:"214"})}),"\n",(0,i.jsx)(n.p,{children:"If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe."}),"\n",(0,i.jsxs)(n.p,{children:["You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/ec2/instance-types/",children:"Amazon EC2 (Amazon Elastic Compute Cloud) instance type"})," if you prefer."]}),"\n",(0,i.jsxs)(n.p,{children:["After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the ",(0,i.jsx)(n.code,{children:"Continue to Configuration"})," button grayed out, as shown below:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 04",src:t(1682).A+"",width:"259",height:"60"})}),"\n",(0,i.jsx)(n.p,{children:"Once the system processes your request, the button will light orange, and you may continue to the configuration options."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 05",src:t(23227).A+"",width:"266",height:"68"})}),"\n",(0,i.jsx)(n.h2,{id:"step-2---initial-configuration",children:"Step 2 - Initial Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Configuration"})," page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release."]}),"\n",(0,i.jsx)(n.p,{children:"The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 06",src:t(68420).A+"",width:"1138",height:"713"})}),"\n",(0,i.jsx)(n.h2,{id:"step-3---launch-configuration",children:"Step 3 - Launch Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Launch"})," page will show your previously selected configuration details and a ",(0,i.jsx)(n.code,{children:"Usage instructions"})," button that leads to the most recent instructions based on your chosen software version."]}),"\n",(0,i.jsx)(n.p,{children:'Below this, you will see a drop-down menu with the title "Choose Action":'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 08",src:t(48013).A+"",width:"834",height:"189"})}),"\n",(0,i.jsx)(n.p,{children:"This drop-down menu includes the following options:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Launch through EC2 - This option launches your configuration through the ",(0,i.jsx)(n.a,{href:"https://console.aws.amazon.com/ec2/",children:"Amazon EC2 Console"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Launch from Website - This option will launch directly from the current page, using further configuration options outlined below."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy to Service Catalog - Copy your configuration of the software to the ",(0,i.jsx)(n.code,{children:"Service Catalog"})," console, where you can manage your company's cloud resources."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional drop-down menus include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.'}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-key-pair-settings",children:"EC2 Key Pair Settings"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 11",src:t(16246).A+"",width:"830",height:"245"})}),"\n",(0,i.jsx)(n.p,{children:'You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 12",src:t(70047).A+"",width:"339",height:"43"})}),"\n",(0,i.jsx)(n.h3,{id:"launching-your-node",children:"Launching Your Node"}),"\n",(0,i.jsxs)(n.p,{children:["If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange ",(0,i.jsx)(n.code,{children:"Launch"})," button to launch your AWS-hosted Casper node."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 13",src:t(6632).A+"",width:"137",height:"58"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},66217:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS01-26219ce99c140282c6ad9137863a954a.png"},1682:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAA8CAIAAADt6EhQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAiFSURBVHhe7ZyJchpJEobpbu7TgCWhA+uwxp6dHUfMW+y8086DzT7IHjFrW7JBB4izgeZs2K+ohmCEhCXNWIus/IKQu6u7qrKq8s/KQgobTrfrE4Rnj+n9KwjPG1GCIChECYKgECUIgkKUIAgKUYIgKEQJgqAQJQiCYtVv1k6KRe9KEL4JDvf2vKslZE8QBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEASFKEEQFKIEQVCIEgRBIUoQBIUo4VtgMplUGo0PxeJZ+Wrkul6pcB/W8a+y7U7nslLtDwZc+/3+7ZfZF4mEfvRgmu3254vLTCq5u7npFa0BeO1lpdJsd8bjsWGa8Ugkn9uyzHuHp4tKpVyrR0KhgN+fTiYKpXIiGjnY2fEef2UKpVKj1T7YziViMa9oXXlKf5VdLJVPzs7HrovXbqTT4VBwPJ54z+7DcDT698lpuVbTt6FAMBGLxiIRffung8z++7ng3dyNbr//2+mnWtOOhMOMNJ2IG4YxGY+9x/fB6fWCgcDh7g4fxpiIRr+qU2L5Pz98bLRa+jYWjiRjsVAopG+fKOulBLvdqdv2i0T87eEBwTv3Mnu4s4Mk9FN3PCa08+FCl8whPWB5arY9GI10CVEWOelrQFHEyGt7S384xBF7vb53vxKkVbdbLcehYa9ogaHr9TtnhbWAwedXlfFkcpTfO9rdYaSMd387xx6on+rh8JNrXWXOstmLwYJt4WBnO5tK6Vuqtx2n2encaMZtMFh64YLBdnu9SqOJ2OaWMMmLVrFAWB6cWg484mUs1C0swqNry7Q+rFd2VCyX602bwBaPRr2iGeTBF1eViU8tAKuwlc3kslmuicQsmzHNNPTi7G5suGMXP5veKTLJ5EYm/aFQ2Mxk+BC/bcchCRmxomp1fITknY2XlHd6veP8Hs5Em+8LxVg4/Go7xxtn5TJLSwIzmYwt08LCaDisG2dpaXnken4WCgZpAQHcaO0ccr/3nwvRaASpe0Uzhq57en7uOF3TslzXJec53NvFz240m1xosfc5DBnLcbiT4hkWWpZFIbNE8Kb8tpGq8m6Xl3Fl9pbNTJoS1ZxhaEuO9nYZF66sCqcwb/xk732dz/MCfZ2eXwyGQ9M0URGNoHOub1ym7AtPro/Gk8mOmCzTMFge734G81uqVpHHu+NjPiz/Va3enmkY78xv5959d/wmn2fSWUvc/e3Bvt8yWaef3r5hjfWbc9guCMNU+eHoKBQMUMV7cBOcW8gEdjY33h2/fru/z3JWGw3vmc/H8v94fMyS86GvvxwesNgrrNUwUjaE5ZFCqVLt9QeHu7t0992rPMI4L5f1o2Wz572jwL++PsIAPXD9PhXp6PhVnqbwe7IvXb4CxBOPRhgFGwtZ1g+vj+iO6ntbm/g3PTKZPEKQ/KQ7ptqrOQ35BCB+MktUeZXbcnrd0ixBXV4mXb4mrJcS3JFrMsdLR0bcyHXH5DasJRDwVKHj6KemaYUCAS4sv3XH46ZpGuFgkAtqEON14W2QEdFp0B9AkLiv5ff3Btf3/UVWW6shihMa6d27n0EOg4uEAwFONdxOBRamXxya23uZTVP9wRCFcBDndjo3X54cyzTSySS1UCnvU4eu2cH0rrIapNJjMwmHyUW5TcXj4WCo3XHU/vWgZXpM1ssgjn24iF71RdQ5UjmVd8uqcD1Y6Y5/ImNlkvvp8pJ8hs9gMAivPB3exVoiumn4+n31/dgi6niD36jqXn3LMMlMHvDdqNfUH4D94T+nn/718eS3T58Ll6UvtkV3pG1zyxES16Px+AHGPz7rpYRIJMzykY149zOIf8zufFnxDK4JW979V8bvtwKW9YYcgzxh+slvrfoq9i7WovmAP+DMgv0cgqWKl7jUrL7LycRSYVTf3h2qENU5Mj3YEUuVCsZ/f7DPkEl1ZtK+FbXpmNbc8qkSJ9jwAOMfn/VSQjqRYPcvV2sXV1f94VCnCuQViXiM2SQ7V+etyaTatImay6fqRQy1HAbpAe+zJLpwNcQy2idHp0rbIcPxfDQeibKk5XpDrzGt6d91LIKXUBe35p14LPpFa3GaTCpFOvGxeGa3OzgcbTZbbToiL+oO+nVbfUdJYtZx1GHgxhPFaojHyXh8MBwVS2XaIYOfq+62kV5jLmZe6/5u+1KiwHjKQRcB8o6GQ61ut9VRqWC91eoNBszGfJdYZ6y///KLd7lEY+ErgseBkJJKJEiLa7ZdqTfKtRoOwRZL5oorUHhZrZaqNfKTXDZDIVVqTRvvyaSS+BY+yjtBvz+ViBNHaYeTLlVG7igaidRtW59rm+12fzjAEbV70QI/1deOhtFstarNZrlWn/q6wdLSFEkzS1mp12kKky6rNbb9a1/Y4w4Nu0XFRqv9MpWiyo3WLsIBwG/52QB1j5VGo9N1yK35OP3BFd1VqthMJsZBk9HdavbvJwEXpxYGYDldkLI0Oh3qMi1EFj2i20Z6rQuGyXCupgvB3NJFMhbDHjZJzkJ0yujokTcJWLoW89zqdKazVEUPzNLe5gZKuG2ZqPuYLK/CnDX9n7+INIQT4jpJBfKYFxKHmFD2ja8UZlgkEnpyEe0Ki9xo0grubi2hGvelTX2g1OC1VGdvWbbkYdDL+0Jh+mts9U3aipEuol8LBAPa4++IHhHquletR2DFt6jyf+B9y5BYjtwxOwMyu6hU6k07n9v643+68nQRJTxTOHgUy6XhSJ2Y2V42s5nNdFo/ep6IEgRB8ZT+Ak8Q/i+IEgRBIUoQBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEATFqr87+sevv3pXgvBN8Leff/aulpA9QRAUq/YEQXg+yJ4gCApRgiAoRAmCoBAlCIJClCAIClGCIChECYKgECUIgs/n8/0Ps5JgKFFEE0IAAAAASUVORK5CYII="},23227:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQoAAABECAIAAAD2jOw2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAoZSURBVHhe7Zx3cFTXFca3F+2uCuqsGkKWEDIWEiOaKDYgAsKywLaCnTY2EOwkkzaMJ4ntTDITx+SP2CmT8XhsQ4zHYwwulNASQEh0iSK6wepCfbXqW7Q1n/ZdrRl2r7RgjBc4v3mzere8984t37nnvlmt2GyxiAiC8IeE/SUIwgeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBJexv7Gr3q1mZwRxX2BZFui31Gn1IAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJI/7B7dbdNoQ/peq9J2NcUNOGtk7QPB2Yn2/5qUTD+dvm4dj1aHcL/u0rOBrUN2rnfrJgh318SwdHGAqf1KrL943Ey1dvCv/vS9SbK7bGZf/Nccs3zezw6Js6Nc0DITM2jb/7SsTWNk3z8c1CdM/f7RxIISl7wukr7z6KjvlIK/+Mzu7i3xap1+5Py9WPbQms/E7SZ0ysTtZa4lRD7HigDE7pKvLciNVtmTd8Ff8JRK3WuaaGds9TmUXKtxZ3r+WhIm+MMHA0gHQZVWsLs/dUpNQMrFlZVrL1Mg+aCNrXL9M4mY1AgadppU7/jb74px4Y4jMKRG7Z8T0xIfccqcFCCx/9kBeTmRflNqGpFgkwgBNj+lRSF1ChaDFkT7GnPcSjKtHXb/mtTMZf8r74v3HzhRPaFuoN/x8Sh1mjFCK2YMKOHxdLKKL7iHFxe7QQbtMyLE5JV1WpXAOIhT2FyfXp4WZWNrDgF2GS3AhS48K9HatV9s8qHa4MB9upt2sYmcjjGItgMEbryYbLMqDRUd/OaUWLUV7n8toUnlmmLc5+MT5TfiaPWBjrQaQxwuTG3Ki+oSkyy1uNqmxpPg1gwcai6fgBI01WBVnu8I7zErcSihFJ3v7GWCAfpzZAH0KSVRDZVgo3OFGfIcpaAnG/xb8vG78+qr07UtO6jVWljUCYus1ZblOzwj1Dsk3LTizQD/sql+pmFw3oHG6xDX9GnS6yy36dHFlv1226D9zPNcN8878qseT2xF+vD7j8rx4Izz9R9WJSTrz6c4I3BBRwZaCyqVJHcgvbYl+e945zDDMjxcPT8UjMGUxqHDPv6nIilLZLA5pis684dGz3gUNrhR3ruyMEJLPpDXjDld6dH6t9YLM7x3MW5rYDv2zrBHwiNer0hFoJWvNiDOXp7a+MesSJp9fs/Niem58uhc0GZajQ9adeHh73fgJoSaxWKSUup7LaEQ+r6XI39MYh8r/upT6qym1yCnZPx1rES6s69OsSG19c/bFrbX6teU57DEi0YGio/h8uSILo4b+MVoVCIz3N8fEa6y1fZpfZ9f8duqXWA/9DtPUEQ3fNe7t/xZsMami1TaNzMnSI8Dl/OFU5qpJjedLSi+UHHxtxpXfV2a2mpjD7rfJ/p5/4ezTh04+WT4xzHzOGAYNtP5o7/SYHgyebe0ODLNQ00uLWbUuu+ZcSenppw5hQh9ti2QF/qgf0Pzj4sStBZWVT5YdXX5YKXVi+FmZSIQ5gcyXsqtx4FkfLDhjdUpHsVbA5JAaLApfLwD2NMUeaI45uaIczTn33VJMsg+rE4UiX7O9T0eyd9UuGCA0XKiPC6/16qpKSnGr3YUnwhRjB5YVhog5ccaWH+57edo16OTUU4fQsSdWlO9edvxUZ0TTQAg680JJaV50Dz7xOHQ1u9KzOGy4mtxnk11YeRB9dWT5YYSOB1uihVLfYRLyg5NglIdxSBmhtMl9QtiaPk3DYMiihE54MnjBRfpOhApXe3VCKTYY4crhgVdJnbFqPxPOF8Ra0aph9w+/KJyMwrmuMEysaJUNC4XdJU7SWq50s0f7ZXRrBcx2GWIPwewbQU1oY358V5LWjGR8iLU4pe1IWyTkhOQtmY1bne8Ky481jveIEJ0TiDwSNZZZcd0wDE4KXl8ucWN5wVqnkTtxB1aJQ59NXtYaXZjcATuRTA8bRCccaokW4sPbGKZvkWCUR4rOhGDd5BOYWp2SIYfEazEmB46mwbsU+yFUQzzzzIG84r0zcVR0RDwSybZDfgnE2giVDY6/3udtD2J9KEHq0ZWATuFAHIWIi6UDRrgVS9wWiIJ+eiQ7c8uiZXtmoeEdlq/2cn5xuMVYImC8kIS6QqTOVrPK4vxaZnwrBKM8JkcMYO97qTuUpUcIlTtCFQ7vmjKE+eeUwIuz9DcMthnTYnr3Fh4/tuKwcKxMa2Zl/gjEWlSYMq6/vDUKvplleVBIXPCy2Fp4d+TYdifrzGqfgHNM1FLn+BCrwarE01nWLbKjIR4x4fmnS9HknUtOxo71/hBeAMuCsOMC0KfZKYUNsETIuYcIRnlkR/Y9kdL2syPZiL8ReyA8aDOrsCFJCzOlhZq21iZgpF1u8Z6mOHimSeED7DJ/SMTD3qvFpMY88/uuyRcEEgiBuq3DL4uuD6qxjgn5k8IHO8zK/16PFV7d4G4INoQiL3Kpu8OqxFxHnYmhY1sLGWCXjP3x7yqysDigpbhnbb8Gc2tJYsfuprhLPcM+As7is3r93Hij735sTLD+FCa3l7ZEYcON5mBLfbx9nFDEa+lNIJIUTtCKZpMKeyohifXB5JAZPJcLfSKgkzsKEg2bqxNgNpKXe0L3NsU+pjd4V8J7iGCUB9zPX2dden5S4/Ol0yL/vUz7XlHG5oJj7ZFauQMb3MOtkboNRap3n3jzfBqqCSE1jwiF7dm06y+U5yjfLd5Sm8ByRyU/zojxTv1ocdjGorcup+o1zN+nhpr+OefCH09Pit+0FKX6D5ZiMyAUeVkxofVYW2T4xsfXlOVg7xSItTNie3YuPYlp+tDmArQ0ZlPhL44+gmm3UG9Yk9mQv22+4p3ijI8XYRP8g4eus2tukblxxrfmnv+sTr+6LNfhksD7CPm8lt7EgvFdPUOKKVsXpm0u2N8cg2VNyE/SmYtS2pbsnq3dUHSig0lOAKbmRPXBbBg/d/u8n2TVozms7J4iqH8GDj6p1zbsoUPldrheIRMjis2fSyQOV9ix6xUy7yxYGfrtcuwdQ3y8tV+TRiFwa7Hm4IBrgPdlWZ6NNeJ4mOFrye2Bfcja8pzCpI7ve8Q2SktvRKgG94TljmUFgNAiBJC3dNVdIPAXu/Qrifc/iEvNdplea4GedzXEra9K/3Dh6YzwQVb84EHyIL4CmxkEbGWtUXaXZE6ccf2My4joWNkDCcmDILjQb+wSxB2A5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMFl7O9cnV2Xxc4I4r4g943L7GwsaPUgCC5jrx4E8cBCqwdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcBCJ/g+JpAip6TfCDgAAAABJRU5ErkJggg=="},68420:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS04-f0a5f08295ac98ac10216dda2c6ac467.png"},48013:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS05-ef5cc7abd1f5093685ce82cb5794a2aa.png"},16246:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS06-fa837b0e61647fe37340261a3ae8fde3.png"},70047:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAArCAIAAABKL/w7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAC3hJREFUeF7tnV9IW1kex2tq/f+n1dbqVOiTT/pSaFkYH+ZhfWj70AWRUp1i7SozVtBm65QGsVhlm+K4EkJrBmmV8aE+uJXCECglOIuEHQTJS9xuW3TdBpnS6A4GsTQEIfs75/xyc++5N7fJNXE0OR++DPeef/d47/ne8zvndsihkEAgyDyE8wWCTEQ4XyDIRITzBYJMRDhfIMhEhPMFgkxEOF8gyESE8wWCTETP+a65+T/f+EvT1x37RNAZ6BJ2TsV+6+2Blv6t3nn1ODxZFB4/JLTfNVkEDwsfmxI958PjX/7Pf8P7BugMdAk7p2K/9fZAo3+rhe0PkiaL8LEp0XM+vPtxIOwboEvYORX7sLcHGp1bzY8tof0tfGxKhPMF2gjnp43wsSkRzhdoI5yfNsLHpkQ4X6CNcH7aCB+bkhQ6f339fzOzPw38dQTauWG+A3o0Pvmvf79huZBooH2d4bjL3go4dG41N7CE9rnwsSlJlfPB81BdU/AugALsmBWOH6iCnVNhoDWBDjq3mhtYQvtc+NiUpMT5bJ4Hgf/ZJA/zPwsBWDrM/+yAlY8fqIKdU2GgteSz5VvyvPbv4NmBRudWcwProCs4kuO25HlHsrj0PZZ/MG/RauISkyJ8bEqS73xmb/C2FNjLAf9LtjfQPlTBzqkw0JoWIc9Ub9et3q6phRCmxE/A/T35o/pevseEg4zOreYGljEFh/OfNpU31p8kaiib6E/JoI9H/u4TFVWnr3cf5tL3VIMlf6w6XVFVusilJ0P42JQk2flgbKgF0rQ9y5ILM+IGqmDnVBhoTYOtn63YN/vCJ0yLjecJlBxw+vE0vLn04737joUPeLo3SBGWWo/GJ7FQ4kB1vLMquIFlQL7esotkoINOXayvPJs84zEb2/r5dB3tC+ePZTubyi2dOUEuPRnCx6Ykyc6HoQa1YNrHcyVsOMqFGXEDVbBzKgy0pmZzfgja6Ru6C/+1ugOYKvEpsLb8em3rI55+eH4b/oq+mdWtwPYnGiJ8CmxvBULyaD+0sfpqwfNqZVMeQpBitBGau/ROdqGd0OY7r8fjXV2PXOVzyGMoTpCFhRIHquOdVcENrIRly7fUgOcrLeZsfqCPmQJ2E03MihwQBYchIM99a1ME5EG7yTeYx6UvXiEvFOt3UjtUY6a3/XnuwezgD5EUmTjnQ7NQNzCGuUHbkUVYCwxHLvFQkRv+gfQzYOdXCqSRh3CQFbify18XqoySNpXpinYi1enl2MEuhI9NSUqc/4/5f+J5stEZjgZ6qyIw9wAMY19Yc/aBc77/eRvTwZAbC+O9zRFHNU95w0sOdoya9ECppUly/GSJ1Qn73X/riJbpGXHjKoAWs4w8uis12DHlJW+Gj54nZkwBxblqgPDq257bUi25NCOvOIHqeGdVcAMrUQV6y8hsf6EgoMqiJqy2dhWaa8HAJ2ZHYOjn2r6sJuWJqhuv5jI/e1tPRRJpentOePzwbIOUAqLVIb7oKYeYAhNry53D0csxyZ3v6z5eV3W67nyhj2RlOy9Er3L2QgEkBi1HoUBFUx7rBqvb0pkttUaVa4My5ypayF9Bda7MRTsTHi0wk7deRLVlLhtNHym8DqcNhX6pekPx7NWT5FotubKWjQgfm5IkO5/NPxDz43my0RmOBnrLE3h5DwxDDL/y7BY4Z2guMhn7X5IooLnv8dyyb/vX1+4378OBFc/zB5DYdMsx51nw0Hlb4fxfZ25CbtvQs+UN//JMXxtk3X2xTnJYsZuT7tX1wJrbfo0UewyVNl0k4rjn8kHgsL2+svoh3q0GaetUrliRV5xAC3hnVXADK1F5rxInN37DuYWIGamittLcVOJoLXaPZrkvQ+EKx4ApPG5yX6mK+rm/wDtMp9/R/AHwUk2pdzzLP1BgrSeOMndALJDjh5nZWtQCTr5U4IfZdbgI3FWnMpLk/GB/KVmDnCtdpNOsr7MC3imWHvpG6CSvJLqIyHGcgUscc5Np3+S6BMfYJZmodatOTAweDtizXZcrof26y/RlYYfg5YifTO8mbwe0f7qTtq/h/Krq+q/KrK0l1p4jysYTFj42Jb+b89noxJO40RmOBlrjYPZmQf7a8144vjfPrL/xYgh62zO1TM8k2LQvW+fLnc9sfG36Nc0JL02RrD7XBjmWvyDWaXzxtQPOQot2iAKazQ+mf1nZTPADARfz7ybOZ0AjeGdVcAMrUS22EHNqrqvl0y9Vjg1c/YejsxAbW/KcV05CbnQNj5F2Np3q2d4YTvtSGX/PcTg1t5PqbkuxOequqPCiV0o7yRvk+CwGBYed56Gp8gl6aXdHudQx9kYgl7DnW6BBjeCFWTeyXTdMXU3eTViALSiCllKpTS3nJ223Dx+bkiQ7n+02fTbIhOUAFDOw/6QzHA30VonvpzvEM81ddG+/6wYcR1z9/sUAZOGMHUXX+ew9IkXs8tNYzodwf/Wl/WY7yW1qvzv9Jt6lPsDF/LuJ8xnQCN5ZFdzASlS+b4iBK65oBLEq5zMPyFXlGCRZvt5jjfKwOZbzWRAh16V8zqisTF0NiUTq2cxMxK0diCy99AMEiyNacoN3jkUTFVJa9yF9QbDThzkTDfJ1Sro4n4Wdn7V0nMXU6AxHA71VwILz9h5ie6pr0ficzfkRr0roOn/bTdYCzXT9D7AsFlDEdj5lJ+T3OEhnhpybmBQXUsy/yzifAe3gnVXBDayExb5gRWfXqLTn/DMl0myJGssbgBbqi9+SHTJm0RjOZ3O+We+TIV60K3f2PJi/urObLUNwzneydbhCJucF0itHS3VFzVEa9nNSWtda1Eh6W+SLvPXwZdGfRnO+/lc9BmR9tkwsoBZ2TgVkYSFDsPC+6/kKnkf8edPpg+NN9wOyG9c9ND2/4PG8fOYmieG1mS5IbLM8mV+YWyIpCksHfrbCu4PmeuYf3ybHD9jngljO3/Q8f/HLwtK7jbWlH0ligs4HIMhn/0Ry90AP8c6q4AZW4oLlMd20q/mik6znSxxN5Y1tOZClcv4hbxsskqsbG4tcNOp2dRcu2iNh9pmj7lGTf7DQQhbezCdZ7ibi/It/KnJ9l+eFkuw7Qu0Jh5kF/AVPe/n9hehFH+bazkH1Sls/2WMP9JbVVZ0+21DiZAG/uchlxSq4zyet3nkx61aa2wvgiravyB/LdgG9bVXkWp1HYJHibiHr/DRxPsAieRiCmsaWbG9sXtIZjsZ6i+ysTJMtPcVKPrRgJ129M7NGzj6+/Xt0K/7atJcWCUgb/mS3n7M0TPtvnt5moTtIFr3HdP48fb9g+aEXe/vvAjigD3hnVXADy5BMi63H66PhenV9DOeHx7NdjXSLm6m23DUKiVneVkys+/KYJTrnHwrfL7qOO+rHnaTkoeBgcSQFhBeSS3FRGslH4pEsb/uJ6HeBmi8cA5FaY3lW0nlceqjErFtxHQN7eHPl048F4PAC+tkCdOp6YxnEAunjfJj22bc9ENib+R8S4UAKRw3PS1AXO6cCsrBQ6tgJ8Z/rgZ0Qn6IgFNqKfL2PB3qJBMqnDJ1bzQ2s3Qj3urQ+sytEv/Pzn83Jp3X+QzpqTOsDezwXUkv7i/2RiXqtZQhKZl3oJL8coA1qrBFSJXxsSpLvfAB8Lplcrd2sQqE6dk4FZGEhQTLQudXcwMowZbtaS6wXyIc61Wd8SUmetHcpfGxKUuJ8Bpv82W4/W3+C5yERsw0hnL9nCOfHEN10lAfwGsqZIP8/QnGMiGCvhY9NSQqdnwqE8/cM4fy0ET42JcL5Am2E89NG+NiUCOcLtBHOTxvhY1MinC/QRjg/bYSPTYme88UvbWQs4pc20kcGfmlD/LpWxkr/Votf1zowMvbrWgKBIF0RzhcIMhHhfIEgExHOFwgyEeF8gSATEc4XCDIR4XyB4Pdh/bff8GjvCYX+DxMofqYM+5EQAAAAAElFTkSuQmCC"},6632:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAA6CAIAAAALGO1FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMmSURBVHhe7ZxRSFNRGMev1+6cF2pr2NRYoRU+pEhgWSTGQERTxpAg7cGgp7AeevTRx/BpTyFEMLUgsdIksk3FXpIEg8okJSqFzBRUrgruzMtm5+4ehYZL9qD8h9+Py/adb2eXc/ntfDuHXZa2ubkpEZDI4pnAg9zgQm5wITe4kBtcyA0u5AaXBPubF2kiIPaBaztvMWne4EJucCE3uJAbXMgNLuQGF3KDC7nBhdzgQm5wITe4kBtcyA0uB9eNtpT9dk5looUIjhtHW1dl87cM0dp7piYvVY1la6KFCI4bWVtVpzfSRYtIjZqmK5rmGF1StYhI7I6uzCw4ZnTREkRljSkai79kFlanFmxJnHy/QHfz6b3H8qSiPlDS0l/hbK/0zRkDnp8ot/Tlz5s9JLWrz3t9QuWRkX9e4huqLO5y3x4oK/B7WqYVsxObLfR2eJxPK+qf1VreZZlJKZTt660p7Sm7F7jibHf7l0UaBHQ350pfb9wKBBsGg42BvpNq80+HeCERy9bci4Pjjbz/QLdLvv/bZiRDrubgKdv5YeNUja82Li/GunLW6672j9/gnUdaD9nezBmCcYCvaelR/sCYwqL60Uwz9X/W8g6bQTjniBlI2qyrLfLrTuGaaG9fdOZanjUWyCzXHguQQHdj1CK/p7TX7e2uvvlVJJOFhXlli+J/DuMAH2+WL3gmrzxglJ2GQOdZkU0Wu7ouSUoobmkAD5gbviQzllLmERvb9vIpos6sitAY9aJjMmyEbNXxcbdNijV3oSn9uP+LTTMKpMT01JhBWKN8OeZ2dtZsHUWj0mLdhZWe4erixzUF3UV/1BWzW07+dJPsqurwWh566j9Yc46Z6cRkzrbWfmef3c5H/C3e4qETW2s8aFLh3kE+maIRe0bsM78N36zwjaqi25PZrfIvHibrdrGuhiGF7x3kAuLEcOSo3ZqcGI41A09MYlKj8h5MyA0u5AYXcoMLucGF3OBCbnAhN7iQG1zIDS7kBhdygwu5wWXn3whG7p4WEbH3lD34IaJ/oXmDC/3vIC40b3AhN7iQG1zIDS7kBhdygwu5QUWS/gKbZ/EkaoCEzgAAAABJRU5ErkJggg=="},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/58092c27.8c31d248.js b/assets/js/58092c27.8c31d248.js new file mode 100644 index 000000000..9e1582bba --- /dev/null +++ b/assets/js/58092c27.8c31d248.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82697],{81832:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const a={},c="Smart Contracts",o={id:"concepts/smart-contracts",title:"Smart Contracts",description:"Smart Contracts in General",source:"@site/docs/concepts/smart-contracts.md",sourceDirName:"concepts",slug:"/concepts/smart-contracts",permalink:"/concepts/smart-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Global State",permalink:"/concepts/global-state"},next:{title:"Authorization Keys",permalink:"/concepts/list-auth-keys"}},i={},l=[{value:"Smart Contracts in General",id:"smart-contracts-in-general",level:2},{value:"Casper Smart Contracts",id:"casper-smart-contracts",level:2},{value:"Session Code",id:"session-code",level:2},{value:"Factory Pattern",id:"factory-pattern",level:2},{value:"Further Reading",id:"further-reading",level:3}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"smart-contracts",children:"Smart Contracts"})}),"\n",(0,r.jsx)(t.h2,{id:"smart-contracts-in-general",children:"Smart Contracts in General"}),"\n",(0,r.jsx)(t.p,{children:"A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism."}),"\n",(0,r.jsx)(t.h2,{id:"casper-smart-contracts",children:"Casper Smart Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Casper smart contracts can be implemented in any programming language that compiles to ",(0,r.jsx)(t.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"}),", which can be installed and executed on-chain using ",(0,r.jsx)(t.a,{href:"/concepts/glossary/T#transaction",children:"transactions"}),". Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. Understand when you would use session code over contract code ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"factory-pattern",children:"Factory Pattern"}),"\n",(0,r.jsxs)(t.p,{children:["From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"Casper Enhancement Proposal"})," provides additional details. Also, you can learn to write a simple contract with factory entry points by following the ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})," developer guide."]}),"\n",(0,r.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"Sending a Transaction"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"Calling Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts using the Casper Client"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>o});var r=n(96540);const s={},a=r.createContext(s);function c(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/58092c27.b116ed08.js b/assets/js/58092c27.b116ed08.js deleted file mode 100644 index b2923abdd..000000000 --- a/assets/js/58092c27.b116ed08.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2697],{81832:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const a={},c="Smart Contracts",o={id:"concepts/smart-contracts",title:"Smart Contracts",description:"Smart Contracts in General",source:"@site/docs/concepts/smart-contracts.md",sourceDirName:"concepts",slug:"/concepts/smart-contracts",permalink:"/next/concepts/smart-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Global State",permalink:"/next/concepts/global-state"},next:{title:"Authorization Keys",permalink:"/next/concepts/list-auth-keys"}},i={},l=[{value:"Smart Contracts in General",id:"smart-contracts-in-general",level:2},{value:"Casper Smart Contracts",id:"casper-smart-contracts",level:2},{value:"Session Code",id:"session-code",level:2},{value:"Factory Pattern",id:"factory-pattern",level:2},{value:"Further Reading",id:"further-reading",level:3}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"smart-contracts",children:"Smart Contracts"})}),"\n",(0,r.jsx)(t.h2,{id:"smart-contracts-in-general",children:"Smart Contracts in General"}),"\n",(0,r.jsx)(t.p,{children:"A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism."}),"\n",(0,r.jsx)(t.h2,{id:"casper-smart-contracts",children:"Casper Smart Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Casper smart contracts can be implemented in any programming language that compiles to ",(0,r.jsx)(t.a,{href:"/next/concepts/glossary/W#webassembly",children:"Wasm"}),", which can be installed and executed on-chain using ",(0,r.jsx)(t.a,{href:"/next/concepts/glossary/T#transaction",children:"transactions"}),". Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. Understand when you would use session code over contract code ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"factory-pattern",children:"Factory Pattern"}),"\n",(0,r.jsxs)(t.p,{children:["From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"Casper Enhancement Proposal"})," provides additional details. Also, you can learn to write a simple contract with factory entry points by following the ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})," developer guide."]}),"\n",(0,r.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"Sending a Transaction"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/calling-contracts",children:"Calling Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/cli/calling-contracts",children:"Calling Smart Contracts using the Casper Client"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>o});var r=n(96540);const s={},a=r.createContext(s);function c(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/58718032.25ddfdd1.js b/assets/js/58718032.25ddfdd1.js deleted file mode 100644 index e6e98e0d3..000000000 --- a/assets/js/58718032.25ddfdd1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2071],{63785:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=n(74848),r=n(28453);const c={},a="G",o={id:"concepts/glossary/G",title:"G",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/G.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/G",permalink:"/concepts/glossary/G",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"F",permalink:"/concepts/glossary/F"},next:{title:"H",permalink:"/concepts/glossary/H"}},l={},i=[{value:"Gas",id:"gas",level:2},{value:"Genesis",id:"genesis",level:2},{value:"Groups",id:"groups",level:2},{value:"Global state",id:"global-state",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"g",children:"G"})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.h2,{id:"gas",children:"Gas"}),"\n",(0,t.jsx)(s.p,{children:"Gas is the virtual currency for calculating the cost of transaction execution. The transaction cost is expressed as a given amount of gas consumed and can be seen intuitively as some cycles of the virtual processor that has to be used to run the computation defined as the transaction's code."}),"\n",(0,t.jsx)(s.h2,{id:"genesis",children:"Genesis"}),"\n",(0,t.jsx)(s.p,{children:"The state of the virtual machine at the beginning of the blockchain."}),"\n",(0,t.jsx)(s.h2,{id:"groups",children:"Groups"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"user groups"})," feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"User groups associate a set of URefs with a label."}),"\n",(0,t.jsx)(s.li,{children:"The entry points on a contract can accept a list of labels"}),"\n",(0,t.jsx)(s.li,{children:"The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"global-state",children:"Global state"}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"})," as a decentralized computer, the global state is its memory state."]}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"})," as a shared database, the global state is the snapshot of the database's data."]}),"\n",(0,t.jsxs)(s.p,{children:["Technically, a ",(0,t.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs)."]}),"\n",(0,t.jsxs)(s.p,{children:["For every ",(0,t.jsx)(s.a,{href:"/concepts/glossary/B#block",children:"block"})," B in the ",(0,t.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"}),", one can compute the ",(0,t.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," achieved by executing all ",(0,t.jsx)(s.a,{href:"/concepts/glossary/T#transaction",children:"transactions"})," in this block and its ancestors. The ",(0,t.jsx)(s.a,{href:"/concepts/glossary/R#root-hash",children:"root hash"})," identifying this state is stored in every executed block."]})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const r={},c=t.createContext(r);function a(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/58718032.68396545.js b/assets/js/58718032.68396545.js new file mode 100644 index 000000000..7a55e76f3 --- /dev/null +++ b/assets/js/58718032.68396545.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52071],{63785:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=n(74848),r=n(28453);const c={},a="G",o={id:"concepts/glossary/G",title:"G",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/G.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/G",permalink:"/1.5.X/concepts/glossary/G",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"F",permalink:"/1.5.X/concepts/glossary/F"},next:{title:"H",permalink:"/1.5.X/concepts/glossary/H"}},l={},i=[{value:"Gas",id:"gas",level:2},{value:"Genesis",id:"genesis",level:2},{value:"Groups",id:"groups",level:2},{value:"Global state",id:"global-state",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"g",children:"G"})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.h2,{id:"gas",children:"Gas"}),"\n",(0,t.jsx)(s.p,{children:"Gas is the virtual currency for calculating the cost of transaction execution. The transaction cost is expressed as a given amount of gas consumed and can be seen intuitively as some cycles of the virtual processor that has to be used to run the computation defined as the transaction's code."}),"\n",(0,t.jsx)(s.h2,{id:"genesis",children:"Genesis"}),"\n",(0,t.jsx)(s.p,{children:"The state of the virtual machine at the beginning of the blockchain."}),"\n",(0,t.jsx)(s.h2,{id:"groups",children:"Groups"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"user groups"})," feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"User groups associate a set of URefs with a label."}),"\n",(0,t.jsx)(s.li,{children:"The entry points on a contract can accept a list of labels"}),"\n",(0,t.jsx)(s.li,{children:"The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"global-state",children:"Global state"}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#blockchain",children:"blockchain"})," as a decentralized computer, the global state is its memory state."]}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#blockchain",children:"blockchain"})," as a shared database, the global state is the snapshot of the database's data."]}),"\n",(0,t.jsxs)(s.p,{children:["Technically, a ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"})," is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs)."]}),"\n",(0,t.jsxs)(s.p,{children:["For every ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#block",children:"block"})," B in the ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#blockchain",children:"blockchain"}),", one can compute the ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"})," achieved by executing all ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T#transaction",children:"transactions"})," in this block and its ancestors. The ",(0,t.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R#root-hash",children:"root hash"})," identifying this state is stored in every executed block."]})]})}function d(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const r={},c=t.createContext(r);function a(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/416.c7de0599.js b/assets/js/58913.6eee2a6e.js similarity index 55% rename from assets/js/416.c7de0599.js rename to assets/js/58913.6eee2a6e.js index 8d33a9c91..ea2d4c687 100644 --- a/assets/js/416.c7de0599.js +++ b/assets/js/58913.6eee2a6e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[416],{90416:(s,c,e)=>{e.r(c)}}]); \ No newline at end of file +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58913],{58913:(s,c,e)=>{e.r(c)}}]); \ No newline at end of file diff --git a/assets/js/5979a0ec.621162c0.js b/assets/js/5979a0ec.621162c0.js new file mode 100644 index 000000000..cb2819a73 --- /dev/null +++ b/assets/js/5979a0ec.621162c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93226],{5513:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var t=s(74848),i=s(28453);const r={title:"Ledger and CSPR.live"},c="Using Ledger and CSPR.live",l={id:"users/ledger/ledger-cspr-live",title:"Ledger and CSPR.live",description:"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.",source:"@site/docs/users/ledger/ledger-cspr-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-cspr-live",permalink:"/users/ledger/ledger-cspr-live",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Ledger and CSPR.live"},sidebar:"users",previous:{title:"Ledger and Ledger Live",permalink:"/users/ledger/ledger-live"},next:{title:"Delegate with Ledger",permalink:"/users/staking-ledger"}},a={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Signing In",id:"sign-in",level:2},{value:"Viewing Account Details",id:"view-account-details",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-csprlive",children:"Using Ledger and CSPR.live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect your Ledger device to a Casper account using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Install a Chromium-based browser, such as Chrome or Brave, for use with ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," for the Casper Mainnet."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"sign-in",children:"Signing In"}),"\n",(0,t.jsxs)(n.p,{children:["To use the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, follow these steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n",(0,t.jsx)(n.li,{children:"Open the Casper app on the Ledger device as shown above."}),"\n",(0,t.jsxs)(n.li,{children:["While keeping the Casper app open, navigate to ",(0,t.jsx)(n.a,{href:"https://cspr.live/sign-in",children:"cspr.live/sign-in"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Sign into cspr.live",src:s(55251).A+"",width:"2302",height:"224"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Connect"})," button in the Ledger section."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose to connect with ledger",src:s(85663).A+"",width:"2228",height:"1398"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click the ",(0,t.jsx)(n.strong,{children:"Connect to Ledger wallet"})," button next."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect to Ledger Wallet in CSPR Live",src:s(650).A+"",width:"1966",height:"1304"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Select an account you want to use."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account to connect",src:s(54671).A+"",width:"1966",height:"1470"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Your Ledger device is now connected to the block explorer, displaying your account details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account connected",src:s(70859).A+"",width:"2192",height:"926"})}),"\n",(0,t.jsx)(n.h2,{id:"view-account-details",children:"Viewing Account Details"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Click on the account in the upper-right corner of the page."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-view-account",src:s(60799).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"View Account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-view-account-button",src:s(52938).A+"",width:"1962",height:"566"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["You are presented with a page displaying details about your account. Check your account's main purse balance in the ",(0,t.jsx)(n.strong,{children:"Liquid"})," row under ",(0,t.jsx)(n.strong,{children:"Total Balance"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-account-details",src:s(69604).A+"",width:"2180",height:"1255"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open the account details page as described ",(0,t.jsx)(n.a,{href:"#view-account-details",children:"here"})," and copy the public key in the ",(0,t.jsx)(n.strong,{children:"Public Key"})," row."]}),"\n",(0,t.jsx)(n.li,{children:"Alternatively, click on the drop-down menu on your account address."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"View account",src:s(60799).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Copy Public Key"})," button and share it with the sender."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Copy public key",src:s(18197).A+"",width:"2194",height:"512"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Sign in with your Ledger device."}),"\n",(0,t.jsxs)(n.li,{children:["Click on ",(0,t.jsx)(n.strong,{children:"Wallet"})," and then ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-transfer-wallet",src:s(34625).A+"",width:"2306",height:"430"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsx)(n.li,{children:"Fill in the details for the transfer."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"1-transfer-details",src:s(91981).A+"",width:"1134",height:"1674"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Next"})," button."]}),"\n",(0,t.jsxs)(n.li,{children:["On the next page, click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"2-transfer-confirm",src:s(38622).A+"",width:"1162",height:"1348"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["On the ",(0,t.jsx)(n.strong,{children:"Sign transaction"})," page, click on the ",(0,t.jsx)(n.strong,{children:"Sign with Ledger"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(88818).A+"",width:"852",height:"1780"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount). Meanwhile, the block explorer will show this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(1934).A+"",width:"870",height:"190"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see ",(0,t.jsx)(n.strong,{children:'"Approve"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Txn hash"})," - ensure it matches the value displayed on ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(72678).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-txn-2",src:s(57362).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["The next page displays transaction ",(0,t.jsx)(n.strong,{children:"Type"})," - for CSPR transfers, that will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(8810).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Chain ID"}),", which identifies the network to which you want to send the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(68533).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"}),", the account's public key initiating the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(80514).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(98516).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(58900).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", the recipient's public key. Compare this value with the one in the block explorer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(3984).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(22026).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(88767).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(13046).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.p,{children:["After approving the transaction with your Ledger hardware wallet, the ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),' block explorer will display a "Transfer completed" page.']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-transfer-completed",src:s(43435).A+"",width:"856",height:"1000"})}),"\n",(0,t.jsx)(n.p,{children:"You can now check your account to see a list of all the completed transfers."})]})}function o(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},91981:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-transfer-details-d728078c48d947c328a3b23bc15cc17f.png"},38622:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-transfer-confirm-cafb3d92204942f3666af11f77d8cd61.png"},88818:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-sign-eb761f9759ce1a3c70c7968f0e2f1e82.png"},1934:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-submitted-7cfc5128325445455a67726758f30891.png"},43435:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-transfer-completed-e9f855a5ceaa8c958312420012496973.png"},58900:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},3984:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},22026:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},88767:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},13046:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},72678:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},57362:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},8810:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},68533:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},80514:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},98516:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},70859:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-connected-ce22088786c03da93e7686c5375000c1.png"},69604:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-details-3e4ce3ed866005ac2e670604c6a0a1c4.png"},650:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-ledger-5cccc2f985729730a69b62543732c2a9.png"},54671:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-select-account-98453e231f218ddfc35417eeb3ff61f4.png"},18197:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/copy-public-key-3f7fc15c50bb5e3410019c468527dc12.png"},85663:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-connect-5c26775af933c4e7bf446690ed2be84a.png"},55251:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-signin-62933017bd15b98d7d3a588ba8f3f579.png"},34625:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/transfer-wallet-dc9b61bfe299341e3e42fc8cadc707ea.png"},52938:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-button-8c0f2e206de1dbf6547dd21bb8f27ba4.png"},60799:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-4d1ba8d5125c4ebd4e80a7016d0f62b6.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>l});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5979a0ec.ef4511ba.js b/assets/js/5979a0ec.ef4511ba.js deleted file mode 100644 index ada758fcc..000000000 --- a/assets/js/5979a0ec.ef4511ba.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3226],{5513:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var t=s(74848),i=s(28453);const r={title:"Ledger and CSPR.live"},c="Using Ledger and CSPR.live",l={id:"users/ledger/ledger-cspr-live",title:"Ledger and CSPR.live",description:"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.",source:"@site/docs/users/ledger/ledger-cspr-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-cspr-live",permalink:"/next/users/ledger/ledger-cspr-live",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Ledger and CSPR.live"},sidebar:"users",previous:{title:"Ledger and Ledger Live",permalink:"/next/users/ledger/ledger-live"},next:{title:"Delegate with Ledger",permalink:"/next/users/staking-ledger"}},a={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Signing In",id:"sign-in",level:2},{value:"Viewing Account Details",id:"view-account-details",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-csprlive",children:"Using Ledger and CSPR.live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect your Ledger device to a Casper account using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Install a Chromium-based browser, such as Chrome or Brave, for use with ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," for the Casper Mainnet."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"sign-in",children:"Signing In"}),"\n",(0,t.jsxs)(n.p,{children:["To use the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, follow these steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n",(0,t.jsx)(n.li,{children:"Open the Casper app on the Ledger device as shown above."}),"\n",(0,t.jsxs)(n.li,{children:["While keeping the Casper app open, navigate to ",(0,t.jsx)(n.a,{href:"https://cspr.live/sign-in",children:"cspr.live/sign-in"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Sign into cspr.live",src:s(99945).A+"",width:"2302",height:"224"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Connect"})," button in the Ledger section."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose to connect with ledger",src:s(20701).A+"",width:"2228",height:"1398"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click the ",(0,t.jsx)(n.strong,{children:"Connect to Ledger wallet"})," button next."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect to Ledger Wallet in CSPR Live",src:s(76580).A+"",width:"1966",height:"1304"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Select an account you want to use."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account to connect",src:s(8585).A+"",width:"1966",height:"1470"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Your Ledger device is now connected to the block explorer, displaying your account details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account connected",src:s(22209).A+"",width:"2192",height:"926"})}),"\n",(0,t.jsx)(n.h2,{id:"view-account-details",children:"Viewing Account Details"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Click on the account in the upper-right corner of the page."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-view-account",src:s(34029).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"View Account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-view-account-button",src:s(24928).A+"",width:"1962",height:"566"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["You are presented with a page displaying details about your account. Check your account's main purse balance in the ",(0,t.jsx)(n.strong,{children:"Liquid"})," row under ",(0,t.jsx)(n.strong,{children:"Total Balance"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-account-details",src:s(73874).A+"",width:"2180",height:"1255"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open the account details page as described ",(0,t.jsx)(n.a,{href:"#view-account-details",children:"here"})," and copy the public key in the ",(0,t.jsx)(n.strong,{children:"Public Key"})," row."]}),"\n",(0,t.jsx)(n.li,{children:"Alternatively, click on the drop-down menu on your account address."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"View account",src:s(34029).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Copy Public Key"})," button and share it with the sender."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Copy public key",src:s(79179).A+"",width:"2194",height:"512"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Sign in with your Ledger device."}),"\n",(0,t.jsxs)(n.li,{children:["Click on ",(0,t.jsx)(n.strong,{children:"Wallet"})," and then ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-transfer-wallet",src:s(80307).A+"",width:"2306",height:"430"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsx)(n.li,{children:"Fill in the details for the transfer."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"1-transfer-details",src:s(77467).A+"",width:"1134",height:"1674"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Next"})," button."]}),"\n",(0,t.jsxs)(n.li,{children:["On the next page, click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"2-transfer-confirm",src:s(16240).A+"",width:"1162",height:"1348"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["On the ",(0,t.jsx)(n.strong,{children:"Sign transaction"})," page, click on the ",(0,t.jsx)(n.strong,{children:"Sign with Ledger"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(74160).A+"",width:"852",height:"1780"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount). Meanwhile, the block explorer will show this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(48204).A+"",width:"870",height:"190"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see ",(0,t.jsx)(n.strong,{children:'"Approve"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Txn hash"})," - ensure it matches the value displayed on ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(86580).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-txn-2",src:s(48592).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["The next page displays transaction ",(0,t.jsx)(n.strong,{children:"Type"})," - for CSPR transfers, that will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(93532).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Chain ID"}),", which identifies the network to which you want to send the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(47263).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"}),", the account's public key initiating the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(64840).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(25702).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(88706).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", the recipient's public key. Compare this value with the one in the block explorer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(24222).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(68328).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(66785).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(58180).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.p,{children:["After approving the transaction with your Ledger hardware wallet, the ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),' block explorer will display a "Transfer completed" page.']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-transfer-completed",src:s(15325).A+"",width:"856",height:"1000"})}),"\n",(0,t.jsx)(n.p,{children:"You can now check your account to see a list of all the completed transfers."})]})}function o(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},77467:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-transfer-details-d728078c48d947c328a3b23bc15cc17f.png"},16240:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-transfer-confirm-cafb3d92204942f3666af11f77d8cd61.png"},74160:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-sign-eb761f9759ce1a3c70c7968f0e2f1e82.png"},48204:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-submitted-7cfc5128325445455a67726758f30891.png"},15325:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-transfer-completed-e9f855a5ceaa8c958312420012496973.png"},88706:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},24222:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},68328:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},66785:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},58180:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},86580:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},48592:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},93532:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},47263:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},64840:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},25702:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},22209:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-connected-ce22088786c03da93e7686c5375000c1.png"},73874:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-details-3e4ce3ed866005ac2e670604c6a0a1c4.png"},76580:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-ledger-5cccc2f985729730a69b62543732c2a9.png"},8585:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-select-account-98453e231f218ddfc35417eeb3ff61f4.png"},79179:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/copy-public-key-3f7fc15c50bb5e3410019c468527dc12.png"},20701:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-connect-5c26775af933c4e7bf446690ed2be84a.png"},99945:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-signin-62933017bd15b98d7d3a588ba8f3f579.png"},80307:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/transfer-wallet-dc9b61bfe299341e3e42fc8cadc707ea.png"},24928:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-button-8c0f2e206de1dbf6547dd21bb8f27ba4.png"},34029:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-4d1ba8d5125c4ebd4e80a7016d0f62b6.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>l});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/59b77803.fd87f57e.js b/assets/js/59b77803.fd87f57e.js new file mode 100644 index 000000000..885c13e82 --- /dev/null +++ b/assets/js/59b77803.fd87f57e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34346],{8368:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>a});var t=r(74848),s=r(28453);const d={title:"Casper on Ledger"},i="Using Ledger with Casper",l={id:"users/ledger/index",title:"Casper on Ledger",description:"| Topic | Description |",source:"@site/versioned_docs/version-2.0.0/users/ledger/index.md",sourceDirName:"users/ledger",slug:"/users/ledger/",permalink:"/2.0.0/users/ledger/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Casper on Ledger"},sidebar:"users",previous:{title:"Transfer Tokens",permalink:"/2.0.0/users/token-transfer"},next:{title:"Set up Ledger",permalink:"/2.0.0/workflow/ledger-setup/"}},c={},a=[];function o(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-with-casper",children:"Using Ledger with Casper"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/workflow/ledger-setup/",children:"Ledger Setup with Casper"})}),(0,t.jsx)(n.td,{children:"Connect a Ledger device to the Casper application"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/users/ledger/ledger-live",children:"Using Ledger and Ledger Live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and Ledger Live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/users/ledger/ledger-cspr-live",children:"Using Ledger and CSPR.live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and CSPR.live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,t.jsx)(n.td,{children:"Delegate tokens using a Ledger device and CSPR.live"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>l});var t=r(96540);const s={},d=t.createContext(s);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a22b142.b646e6c0.js b/assets/js/5a22b142.b646e6c0.js new file mode 100644 index 000000000..ebe4d80b5 --- /dev/null +++ b/assets/js/5a22b142.b646e6c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[69940],{47609:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var i=n(74848),s=n(28453);const r={title:"Delegate Tokens",slug:"/users/delegate-ui"},a="Delegating Tokens with a Block Explorer",o={id:"users/csprlive/delegate-ui",title:"Delegate Tokens",description:"Introduction",source:"@site/docs/users/csprlive/delegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/delegate-ui",permalink:"/users/delegate-ui",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Delegate Tokens",slug:"/users/delegate-ui"},sidebar:"users",previous:{title:"Testnet Funding",permalink:"/users/testnet-faucet"},next:{title:"Undelegate Tokens",permalink:"/users/undelegate-ui"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Reviewing your Account",id:"account-review",level:3},{value:"Accessing the Delegation Feature",id:"delegation-access",level:2},{value:"Stepping through the Delegation Process",id:"stepping-through-the-delegation-process",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-tokens-with-a-block-explorer",children:"Delegating Tokens with a Block Explorer"})}),"\n",(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"This tutorial covers how to delegate Casper tokens to a validator on the network."}),"\n",(0,i.jsxs)(t.p,{children:["Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called ",(0,i.jsx)(t.strong,{children:"delegation"})," or ",(0,i.jsx)(t.strong,{children:"staking"}),". We will use these terms interchangeably in this guide. See the ",(0,i.jsx)(t.a,{href:"/concepts/economics/staking",children:"Staking Key Concepts"})," page for more details about the differences."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})," by following the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide."]}),"\n",(0,i.jsxs)(t.li,{children:["You need to ",(0,i.jsx)(t.a,{href:"/users/funding-from-exchanges",children:"fund the account's main purse"})," to delegate tokens."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect to a block explorer to set up the delegation. This guide uses ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," and the Casper Wallet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"#account-review",children:"Review your account"})," before starting the process."]}),"\n",(0,i.jsxs)(t.li,{children:["Review the current ",(0,i.jsx)(t.a,{href:"/users/delegating#delegation-cost",children:"delegation cost"})," and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"account-review",children:"Reviewing your Account"}),"\n",(0,i.jsx)(t.p,{children:"Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Liquid Account Balance"}),", representing the tokens you have for immediate use"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegated Account Balance"}),", representing the delegated tokens already staked with validators on the network"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegations"})," tab, listing the validators to whom you have delegated tokens"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and delegations details",src:n(32973).A+"",width:"2420",height:"1456"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Staking Rewards"})," tab, showing the rewards received in each era"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and rewards",src:n(55757).A+"",width:"2422",height:"1592"})}),"\n",(0,i.jsx)(t.h2,{id:"delegation-access",children:"Accessing the Delegation Feature"}),"\n",(0,i.jsx)(t.p,{children:"You can access the delegation functionality in two ways."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,i.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,i.jsx)(t.strong,{children:"Delegate"}),". In the next screen, you will need to specify the validator's public key or search for a validator."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from the Wallet",src:n(79883).A+"",width:"252",height:"333"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,i.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the ",(0,i.jsx)(t.strong,{children:"Delegate"})," button. The next screen will have the validator's public key pre-populated."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from a Validator",src:n(60845).A+"",width:"2304",height:"822"})}),"\n",(0,i.jsx)(t.h2,{id:"stepping-through-the-delegation-process",children:"Stepping through the Delegation Process"}),"\n",(0,i.jsx)(t.p,{children:'The following instructions will take you through the delegation process, starting with the "Delegation details" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 1 - Delegation details"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,i.jsx)(t.li,{children:"Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee."}),"\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegation details",src:n(18165).A+"",width:"1174",height:"1402"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 2 - Confirm the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Review the delegation details."}),"\n",(0,i.jsxs)(t.li,{children:["If everything is correct, click ",(0,i.jsx)(t.strong,{children:"Confirm and delegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confirm delegation details",src:n(81922).A+"",width:"1218",height:"1562"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 3 - Sign the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Sign the delegation by clicking ",(0,i.jsx)(t.strong,{children:"Sign with Casper Wallet"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Sign delegation",src:n(88008).A+"",width:"1198",height:"1754"})}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,i.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Signature Request window",src:n(92967).A+"",width:"2098",height:"1730"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the delegation."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Completed delegation",src:n(82945).A+"",width:"1238",height:"1442"})}),"\n",(0,i.jsxs)(t.p,{children:["The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the ",(0,i.jsx)(t.strong,{children:"Deploy Details"})," highlighted above."]}),"\n",(0,i.jsxs)(t.p,{children:["Remember to ",(0,i.jsx)(t.a,{href:"/users/delegating#monitoring-rewards",children:"Monitor your Stake"}),". Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the ",(0,i.jsx)(t.em,{children:"Rewards"})," tab on your account page on ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If you want to undelegate your tokens, you can do so at any time. See the ",(0,i.jsx)(t.a,{href:"/users/undelegate-ui",children:"Undelegation Guide"})," for details."]}),"\n",(0,i.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,i.jsx)(t.p,{children:"This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step."}),"\n",(0,i.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed/cR3v8AthlkQ",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},82945:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/10.completed-delegation-0ac5b9f9f8652f84699d6399327e2fdf.png"},32973:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/2.delegations-9003a8fe3ea1027b5c2979309d3fea8f.png"},55757:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/3.rewards-115f13a27134c16ee910cfbe03007772.png"},79883:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/4.wallet-delegate-5e55bb39f50718c18135516a3b2cc300.png"},60845:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/5.validator-delegate-0b1707fc714ad98ffe9c51589da77d80.png"},18165:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/6.delegation-details-c24d81971b747b1a9690bbd19326491d.png"},81922:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/7.confirm-delegation-1f04705b09036ea673b306ef2d1792a7.png"},88008:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/8.sign-delegation-4cd652c44f821f2db9c825b07f7c1ba2.png"},92967:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/9.wallet-window-f16c8950d24a74274d9dd6e3aa39c62e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a22b142.d6483baa.js b/assets/js/5a22b142.d6483baa.js deleted file mode 100644 index 609c174ca..000000000 --- a/assets/js/5a22b142.d6483baa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9940],{47609:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var i=n(74848),s=n(28453);const r={title:"Delegate Tokens",slug:"/users/delegate-ui"},a="Delegating Tokens with a Block Explorer",o={id:"users/csprlive/delegate-ui",title:"Delegate Tokens",description:"Introduction",source:"@site/docs/users/csprlive/delegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/delegate-ui",permalink:"/next/users/delegate-ui",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Delegate Tokens",slug:"/users/delegate-ui"},sidebar:"users",previous:{title:"Testnet Funding",permalink:"/next/users/testnet-faucet"},next:{title:"Undelegate Tokens",permalink:"/next/users/undelegate-ui"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Reviewing your Account",id:"account-review",level:3},{value:"Accessing the Delegation Feature",id:"delegation-access",level:2},{value:"Stepping through the Delegation Process",id:"stepping-through-the-delegation-process",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-tokens-with-a-block-explorer",children:"Delegating Tokens with a Block Explorer"})}),"\n",(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"This tutorial covers how to delegate Casper tokens to a validator on the network."}),"\n",(0,i.jsxs)(t.p,{children:["Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called ",(0,i.jsx)(t.strong,{children:"delegation"})," or ",(0,i.jsx)(t.strong,{children:"staking"}),". We will use these terms interchangeably in this guide. See the ",(0,i.jsx)(t.a,{href:"/next/concepts/economics/staking",children:"Staking Key Concepts"})," page for more details about the differences."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})," by following the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide."]}),"\n",(0,i.jsxs)(t.li,{children:["You need to ",(0,i.jsx)(t.a,{href:"/next/users/funding-from-exchanges",children:"fund the account's main purse"})," to delegate tokens."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect to a block explorer to set up the delegation. This guide uses ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," and the Casper Wallet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"#account-review",children:"Review your account"})," before starting the process."]}),"\n",(0,i.jsxs)(t.li,{children:["Review the current ",(0,i.jsx)(t.a,{href:"/next/users/delegating#delegation-cost",children:"delegation cost"})," and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"account-review",children:"Reviewing your Account"}),"\n",(0,i.jsx)(t.p,{children:"Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Liquid Account Balance"}),", representing the tokens you have for immediate use"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegated Account Balance"}),", representing the delegated tokens already staked with validators on the network"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegations"})," tab, listing the validators to whom you have delegated tokens"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and delegations details",src:n(44523).A+"",width:"2420",height:"1456"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Staking Rewards"})," tab, showing the rewards received in each era"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Account and rewards",src:n(4779).A+"",width:"2422",height:"1592"})}),"\n",(0,i.jsx)(t.h2,{id:"delegation-access",children:"Accessing the Delegation Feature"}),"\n",(0,i.jsx)(t.p,{children:"You can access the delegation functionality in two ways."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,i.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,i.jsx)(t.strong,{children:"Delegate"}),". In the next screen, you will need to specify the validator's public key or search for a validator."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from the Wallet",src:n(27085).A+"",width:"252",height:"333"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,i.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the ",(0,i.jsx)(t.strong,{children:"Delegate"})," button. The next screen will have the validator's public key pre-populated."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegate from a Validator",src:n(40667).A+"",width:"2304",height:"822"})}),"\n",(0,i.jsx)(t.h2,{id:"stepping-through-the-delegation-process",children:"Stepping through the Delegation Process"}),"\n",(0,i.jsx)(t.p,{children:'The following instructions will take you through the delegation process, starting with the "Delegation details" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 1 - Delegation details"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,i.jsx)(t.li,{children:"Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee."}),"\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Delegation details",src:n(93367).A+"",width:"1174",height:"1402"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 2 - Confirm the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Review the delegation details."}),"\n",(0,i.jsxs)(t.li,{children:["If everything is correct, click ",(0,i.jsx)(t.strong,{children:"Confirm and delegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Confirm delegation details",src:n(50364).A+"",width:"1218",height:"1562"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 3 - Sign the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Sign the delegation by clicking ",(0,i.jsx)(t.strong,{children:"Sign with Casper Wallet"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Sign delegation",src:n(81978).A+"",width:"1198",height:"1754"})}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,i.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Signature Request window",src:n(69933).A+"",width:"2098",height:"1730"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the delegation."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Completed delegation",src:n(73927).A+"",width:"1238",height:"1442"})}),"\n",(0,i.jsxs)(t.p,{children:["The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the ",(0,i.jsx)(t.strong,{children:"Deploy Details"})," highlighted above."]}),"\n",(0,i.jsxs)(t.p,{children:["Remember to ",(0,i.jsx)(t.a,{href:"/next/users/delegating#monitoring-rewards",children:"Monitor your Stake"}),". Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the ",(0,i.jsx)(t.em,{children:"Rewards"})," tab on your account page on ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If you want to undelegate your tokens, you can do so at any time. See the ",(0,i.jsx)(t.a,{href:"/next/users/undelegate-ui",children:"Undelegation Guide"})," for details."]}),"\n",(0,i.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,i.jsx)(t.p,{children:"This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step."}),"\n",(0,i.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed/cR3v8AthlkQ",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},73927:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/10.completed-delegation-0ac5b9f9f8652f84699d6399327e2fdf.png"},44523:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/2.delegations-9003a8fe3ea1027b5c2979309d3fea8f.png"},4779:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/3.rewards-115f13a27134c16ee910cfbe03007772.png"},27085:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/4.wallet-delegate-5e55bb39f50718c18135516a3b2cc300.png"},40667:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/5.validator-delegate-0b1707fc714ad98ffe9c51589da77d80.png"},93367:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/6.delegation-details-c24d81971b747b1a9690bbd19326491d.png"},50364:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/7.confirm-delegation-1f04705b09036ea673b306ef2d1792a7.png"},81978:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/8.sign-delegation-4cd652c44f821f2db9c825b07f7c1ba2.png"},69933:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/9.wallet-window-f16c8950d24a74274d9dd6e3aa39c62e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a3b84ba.63717aa0.js b/assets/js/5a3b84ba.63717aa0.js new file mode 100644 index 000000000..9305f0dd3 --- /dev/null +++ b/assets/js/5a3b84ba.63717aa0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65409],{47398:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=r(74848),t=r(28453);const o={title:"Overview"},i="Interacting with the Casper JSON-RPC API",c={id:"developers/json-rpc/index",title:"Overview",description:"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.",source:"@site/docs/developers/json-rpc/index.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/",permalink:"/developers/json-rpc/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Overview"},sidebar:"developers",previous:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/developers/writing-onchain-code/best-practices"},next:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/developers/json-rpc/guidance"}},a={},d=[{value:"Table of Contents",id:"table-of-contents",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"interacting-with-the-casper-json-rpc-api",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses a custom JSON-RPC implementation called ",(0,s.jsx)(n.code,{children:"casper-json-rpc"})," that complies with the ",(0,s.jsx)(n.a,{href:"https://www.jsonrpc.org/specification",children:"JSON-RPC 2.0 specification"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/operators/setup/casper-sidecar",children:"Casper Sidecar"})," service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"})," in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar."]}),"\n",(0,s.jsxs)(n.p,{children:["You can find the latest RPC schema in the Sidecar's ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/test/rpc_schema.json",children:"GitHub repository"}),". "]}),"\n",(0,s.jsxs)(n.p,{children:["The Casper client subcommand ",(0,s.jsx)(n.code,{children:"list-rpcs"})," also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"casper-client list-rpcs --node-address <HOST:PORT>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You may use ",(0,s.jsx)(n.a,{href:"https://www.postman.com/",children:"Postman"})," or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification."]}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Page"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/guidance",children:"Guidance for JSON-RPC SDK Compliance"})}),(0,s.jsx)(n.td,{children:"Requirements for a compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/minimal-compliance",children:"Required JSON-RPC Methods for Minimal Compliance"})}),(0,s.jsx)(n.td,{children:"Methods required for a minimally compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-transactional",children:"Transactional JSON-RPC Method"})}),(0,s.jsx)(n.td,{children:"Methods allowing interaction with a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational",children:"Informational JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods returning information about the network from a Casper node"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods pertaining to Proof-of-Stake functionality on a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"Types"})}),(0,s.jsx)(n.td,{children:"Information on types used within JSON-RPC methods"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_cl",children:"CL Types"})}),(0,s.jsx)(n.td,{children:"Information related to CL Types"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var s=r(96540);const t={},o=s.createContext(t);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a3b84ba.73c72eda.js b/assets/js/5a3b84ba.73c72eda.js deleted file mode 100644 index 61afb2d80..000000000 --- a/assets/js/5a3b84ba.73c72eda.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5409],{47398:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=t(74848),s=t(28453);const o={title:"Overview"},i="Interacting with the Casper JSON-RPC API",c={id:"developers/json-rpc/index",title:"Overview",description:"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.",source:"@site/docs/developers/json-rpc/index.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/",permalink:"/next/developers/json-rpc/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Overview"},sidebar:"developers",previous:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/next/developers/writing-onchain-code/best-practices"},next:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/next/developers/json-rpc/guidance"}},a={},d=[{value:"Table of Contents",id:"table-of-contents",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"interacting-with-the-casper-json-rpc-api",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,r.jsxs)(n.p,{children:["Casper uses a custom JSON-RPC implementation called ",(0,r.jsx)(n.code,{children:"casper-json-rpc"})," that complies with the ",(0,r.jsx)(n.a,{href:"https://www.jsonrpc.org/specification",children:"JSON-RPC 2.0 specification"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/next/operators/setup/casper-sidecar",children:"Casper Sidecar"})," service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the ",(0,r.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"})," in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar."]}),"\n",(0,r.jsxs)(n.p,{children:["You can find the latest RPC schema in the Sidecar's ",(0,r.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/resources/test/rpc_schema.json",children:"GitHub repository"}),". "]}),"\n",(0,r.jsxs)(n.p,{children:["The Casper client subcommand ",(0,r.jsx)(n.code,{children:"list-rpcs"})," also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-sh",children:"casper-client list-rpcs --node-address <HOST:PORT>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You may use ",(0,r.jsx)(n.a,{href:"https://www.postman.com/",children:"Postman"})," or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification."]}),"\n",(0,r.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Page"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/guidance",children:"Guidance for JSON-RPC SDK Compliance"})}),(0,r.jsx)(n.td,{children:"Requirements for a compliant Casper SDK"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/minimal-compliance",children:"Required JSON-RPC Methods for Minimal Compliance"})}),(0,r.jsx)(n.td,{children:"Methods required for a minimally compliant Casper SDK"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-transactional",children:"Transactional JSON-RPC Method"})}),(0,r.jsx)(n.td,{children:"Methods allowing interaction with a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational",children:"Informational JSON-RPC Methods"})}),(0,r.jsx)(n.td,{children:"Methods returning information about the network from a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake JSON-RPC Methods"})}),(0,r.jsx)(n.td,{children:"Methods pertaining to Proof-of-Stake functionality on a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain",children:"Types"})}),(0,r.jsx)(n.td,{children:"Information on types used within JSON-RPC methods"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/types_cl",children:"CL Types"})}),(0,r.jsx)(n.td,{children:"Information related to CL Types"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var r=t(96540);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5a6ba1cd.fa112277.js b/assets/js/5a6ba1cd.fa112277.js new file mode 100644 index 000000000..7578df2cf --- /dev/null +++ b/assets/js/5a6ba1cd.fa112277.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60570],{24029:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=s(74848),o=s(28453);const a={title:"Fast Sync"},r="Introducing Fast Sync",c={id:"operators/setup/fast-sync",title:"Fast Sync",description:"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 transaction 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.",source:"@site/versioned_docs/version-2.0.0/operators/setup/fast-sync.md",sourceDirName:"operators/setup",slug:"/operators/setup/fast-sync",permalink:"/2.0.0/operators/setup/fast-sync",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Fast Sync"},sidebar:"operators",previous:{title:"Installation",permalink:"/2.0.0/operators/setup/install-node"},next:{title:"Open Files Limit",permalink:"/2.0.0/operators/setup/open-files"}},i={},l=[{value:"How Fast Sync Works",id:"how-fast-sync-works",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"introducing-fast-sync",children:"Introducing Fast Sync"})}),"\n",(0,n.jsx)(t.p,{children:"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 transaction 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."}),"\n",(0,n.jsxs)(t.p,{children:["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 ",(0,n.jsx)(t.a,{href:"/2.0.0/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"trusted hash"})," 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."]}),"\n",(0,n.jsx)(t.h2,{id:"how-fast-sync-works",children:"How Fast Sync Works"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Fast-sync process",src:s(42459).A+"",width:"661",height:"81"})}),"\n",(0,n.jsxs)(t.p,{children:["For fast sync, operators must provide the trusted hash of a block in the ",(0,n.jsx)(t.code,{children:"config.toml"})," file. An example can be found ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},42459:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/fast-sync-process-b20a3732a0c1a20e1ff682568f6a8390.png"},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>c});var n=s(96540);const o={},a=n.createContext(o);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b38c543.7266d270.js b/assets/js/5b38c543.7266d270.js new file mode 100644 index 000000000..3ae1d1825 --- /dev/null +++ b/assets/js/5b38c543.7266d270.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19744],{95284:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>r,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Sending Transactions"},s="Sending Transactions using the Casper Client",r={id:"developers/cli/sending-transactions",title:"Sending Transactions",description:"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:",source:"@site/versioned_docs/version-2.0.0/developers/cli/sending-transactions.md",sourceDirName:"developers/cli",slug:"/developers/cli/sending-transactions",permalink:"/2.0.0/developers/cli/sending-transactions",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Sending Transactions"},sidebar:"developers",previous:{title:"Undelegating Tokens",permalink:"/2.0.0/developers/cli/undelegate"},next:{title:"Installing Contracts",permalink:"/2.0.0/developers/cli/installing-contracts"}},i={},o=[{value:"Paying for Transactions",id:"paying-for-transactions",level:2},{value:"Monitoring the Event Stream for Transactions",id:"monitoring-the-event-stream-for-transactions",level:2},{value:"Sending a Transaction to the Network",id:"sending-the-transaction",level:2},{value:"Time-to-live",id:"ttl",level:3},{value:"Legacy Deploy Payments",id:"deploy-payments",level:3},{value:"Using Arguments with Transactions",id:"using-arguments-with-transactions",level:2},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Gas Cost for Transactions",id:"gas-cost-for-transactions",level:2},{value:"Common Errors Related to Payments",id:"common-errors-related-to-payments",level:2},{value:"Out of gas error",id:"out-of-gas-error",level:3},{value:"Gas limit error",id:"gas-limit-error",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sending-transactions-using-the-casper-client",children:"Sending Transactions using the Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["To install smart contracts on the blockchain, you can send your Wasm to the network via a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"Transaction"}),". To do this, you will need to meet a few prerequisites:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You will need a client to interact with the network, such as the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Ensure you have an ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"Account"})," and its associated ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"keys"})," This account will pay for the Transaction, and its secret key will sign the Transaction"]}),"\n",(0,t.jsx)(n.li,{children:"Ensure this account has enough CSPR tokens to pay for the Transaction"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"paying-for-transactions",children:"Paying for Transactions"}),"\n",(0,t.jsx)(n.p,{children:"CSPR tokens are used to pay for transactions on the Casper Mainnet and Testnet. There are several ways to fund your account:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You may want to ",(0,t.jsx)(n.a,{href:"/2.0.0/users/funding-from-exchanges",children:"transfer tokens from an exchange"})]}),"\n",(0,t.jsxs)(n.li,{children:["You can use a ",(0,t.jsx)(n.a,{href:"/2.0.0/users/token-transfer",children:"block explorer to transfer tokens"})," between accounts' purses"]}),"\n",(0,t.jsxs)(n.li,{children:["You can also ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/",children:"transfer tokens using the default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["On the Testnet, you can use the ",(0,t.jsx)(n.a,{href:"/2.0.0/users/testnet-faucet",children:"faucet functionality"})," for testing your smart contracts"]}),"\n",(0,t.jsxs)(n.li,{children:["If running a network locally using ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/nctl-test",children:"NCTL"}),", the tool provides several funded accounts"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"monitoring-the-event-stream-for-transactions",children:"Monitoring the Event Stream for Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to follow the ",(0,t.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"lifecycle"})," of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"here"}),". You need the following information to proceed:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The IP address of a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"peer"})," on the network"]}),"\n",(0,t.jsxs)(n.li,{children:["The port specified as the ",(0,t.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,t.jsx)(n.em,{children:"config.toml"}),", which is by default 9999 on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The URL for streamed events, which is ",(0,t.jsx)(n.a,{href:"HOST:PORT",children:"HOST:PORT"}),"/events"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"With the following command, you can start watching the event stream. Note the event ID recorded when you send the Transaction in the next section."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://65.21.235.219:9999/events\n"})}),"\n",(0,t.jsx)(n.h2,{id:"sending-the-transaction",children:"Sending a Transaction to the Network"}),"\n",(0,t.jsxs)(n.p,{children:["You can call the Casper client's ",(0,t.jsx)(n.code,{children:"put-txn"})," command to put the compiled contract on the chain. In this example, the Transaction will execute in the account's context. See the ",(0,t.jsx)(n.a,{href:"#advanced-features",children:"advanced features"})," section for key delegation."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session\\\n --node-address <HOST:PORT> \\\n --chain-name casper-net-1 \\\n --transaction-path <transaction-PATH> \\\n --session-entry-point <NAME> \\\n --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n --gas-price-tolerance <INTEGER> \\\n --pricing-mode fixed \\\n --secret-key <PATH> | --initiator-address <HEX STRING>\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of the sidecar's JSON-RPC server on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,t.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),". As you can see, this example uses the Testnet."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction category, based on size of the Wasm included. ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,t.jsx)(n.code,{children:"large"}),", ",(0,t.jsx)(n.code,{children:"medium"})," and ",(0,t.jsx)(n.code,{children:"small"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum gas price that the user is willing to pay for this transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"})," - The pricing mode used for this transaction, in this case ",(0,t.jsx)(n.code,{children:"fixed"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," or ",(0,t.jsx)(n.code,{children:"initiator-address"})," - The file name containing the secret key of the account paying for the Transaction, or the address of the account initiating the transaction. ",(0,t.jsx)(n.code,{children:"initiator-address"})," can be a public key, account hash or an entity address."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's execution results. Sending the transaction and receiving the transaction hash does not mean the transaction was processed successfully. Therefore, you must check the transaction execution using the transaction hash. See the transaction lifecycle for more details."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": Each Transaction gets a unique hash, which is part of the cryptographic security of blockchain technology. No two transactions will ever return the same hash."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample put-txn result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Verify the transaction details with the ",(0,t.jsx)(n.code,{children:"get-txn"})," command and the ",(0,t.jsx)(n.code,{children:"transaction_hash"})," received above."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-txn \\\n --node-address <HOST:PORT> <TRANSACTION-HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If the Transaction succeeded, the ",(0,t.jsx)(n.code,{children:"get-txn"})," command would return a JSON object with the full transaction details."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample get-transaction result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -3929997047953574815,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-07-17T16:45:43.821Z",\n "ttl": "30m",\n "body_hash": "c5c4f7ae2fecb68937c19a1439eefddd8d4c32de779fe3ffee292977f161b234",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n }\n },\n "body": {\n "args": [\n [\n "name",\n {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n ],\n [\n "symbol",\n {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n ],\n [\n "total_supply",\n {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n ],\n [\n "decimals",\n {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n ]\n ],\n "target": {\n "Session": {\n "module_bytes": "[655810 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65",\n "signature": "012ac4fc94d4ba269eb94aad1b9e90d1f701ed0e660995c1a15afc69010b74b51dd1334f9a59a9587aaf6aa6ab5ad35a7e86a9dcba39c2d21843e56d5d4014f00f"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "23f21d3af261dd830790926b240dbded4362bb3c1183d9ee4ec1aea132bfa5e0",\n "block_height": 624,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "371736413663",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 328238,\n "effects": [\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n }\n }\n },\n {\n "key": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n }\n }\n },\n {\n "key": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-987369d1ce9ffff037841f4a221d7fc63924d565196de9e67ea8bdb897bc22e7",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f7061636b6167655f4345503138",\n "parsed": "cep18_contract_package_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-eb635428d8eb01ac5683a333755ba85f6299df45cab9048c18d84fbc5367e932",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b507",\n "parsed": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "2300000063657031385f636f6e74726163745f7061636b6167655f6163636573735f4345503138",\n "parsed": "cep18_contract_package_access_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "package-1b937640b847113bb5adeccdd1aae96a913c340c1911949f90c90a0dd025d9a4",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[659014 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f07",\n "parsed": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "08000000646563696d616c73",\n "parsed": "decimals"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f26520fac960fb1abac44a358923ab6a064baffb1707c885886d157f66c55209",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce07",\n "parsed": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000656e61626c655f6d696e745f6275726e",\n "parsed": "enable_mint_burn"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-7114a751e72d65a0290c975396374e0120ac8f3ddbb6e4e21e3c6810135b40d0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0216baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e0307",\n "parsed": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0b0000006576656e74735f6d6f6465",\n "parsed": "events_mode"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d07",\n "parsed": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "040000006e616d65",\n "parsed": "name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0221a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a07",\n "parsed": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0600000073796d626f6c",\n "parsed": "symbol"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad107",\n "parsed": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c000000746f74616c5f737570706c79",\n "parsed": "total_supply"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e3c8f46f39b1ee1cbadb774ffaf842226b7cbf1fef3bbc04abfa80b86daca11",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "allowance",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44528c1898e30df62037a76e0c45123f4f4437336ca63236b10ebfc16a5edb78",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fcc296caa05679d0d11121e7629b29f222a857018f50985046b73a56e9a10701",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "balance_of",\n "args": [\n {\n "name": "address",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-768c370eb010604bd19029a409dca8b5fbf9af9bc14a36c2b294a2a7a922161e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "burn",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bab8615f758ed79acb7dd7577b1a6c12d625d1a19592a2b1ded0dc352407e4d5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_events_mode",\n "args": [\n {\n "name": "events_mode",\n "cl_type": "U8"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-82a811993cf9ccb5e46c9608c69d86e3c9b7b499520fd48cdca1424f2a08efdc",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_security",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "condor",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decimals",\n "args": [],\n "ret": "U8",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-ac07c23dc90a33282d553af890e30e62335c5ae986629d643778e2d4516f26ad",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decrease_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-a7e05838c728d16c4ba3e1980b6729c857ef4c21d1b0c34e6eefbb486cdc2b89",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "increase_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "init",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fc79236fd0e4521c8feddcc2094c6a0ea04fcaafb17fef63ef060744a6bab401",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_sec_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-18bff854e9d908cf20fb1db53a47ab69968917b53b8c71371e7dd0f88b363e60",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_allowance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e7babf918642bd9636d3c121691bd85534b41084a5c22fe1e2bf196224dade6",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_balance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-233964bb1dc667b37a8abbb938d7647b2c4ab41f0c26dbbcd26c62e7870f72ba",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "mint",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "name",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "symbol",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "total_supply",\n "args": [],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-3820ce25e54df0470fb738e3e0f63ee50b2719cf2680da2bdb579e21aebc8f63",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer",\n "args": [\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44208043191e40d3417df6878e1a23894172cf37cf2e4444384ada99e25430e7",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer_from",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "byte_code_hash": "byte-code-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "main_purse": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-dc1e638c71901f1e8fd375ce7a9c6eb2f240241b4ca9cbb7abd65ce16f879a22",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "errors",\n "topic_name_hash": "b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc"\n }\n ]\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "message-topic-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 0,\n "blocktime": 1721234748003\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-0268d6df10a5edcebe0d3790d2eba676dba455e46a2c880085fdbeca4ab762fb",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1900000063657031385f636f6e74726163745f686173685f4345503138",\n "parsed": "cep18_contract_hash_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-da1fb8c629dc3b127c4cc7e8b09431872aa846af6777bb15b280126ca65663cd",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "021075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a07",\n "parsed": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f76657273696f6e5f4345503138",\n "parsed": "cep18_contract_version_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a7807607",\n "parsed": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": "Identity"\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": "Identity"\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-c45567f4859db5b100d4c45a9638973ccdf0a7068a2a50f7a1c8709d5e84fbd2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c0000007061636b6167655f68617368",\n "parsed": "package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-d447c1e29c0d374421e2c3f290c580a73aa748eba54e1b6bb3da0acdd4cdcee5",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0d000000636f6e74726163745f68617368",\n "parsed": "contract_hash"\n }\n }\n }\n }\n },\n {\n "key": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bce0df2b23ec57062235795dd9b7a1a6dc07885918c6cee5c5859a9df3d498e0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e21422207",\n "parsed": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0a000000616c6c6f77616e636573",\n "parsed": "allowances"\n }\n }\n }\n }\n },\n {\n "key": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-058ed80a0c85bcf8470ac5b8ca4c14f1086c3cd5ae00f1f0592fee3addf4073c",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d1707",\n "parsed": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0800000062616c616e636573",\n "parsed": "balances"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-52d71098e9663be90740263d98e5596d99a9c854beada13b2fa1be0e5ab1dd4b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[190 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-5f4fd818ad44d4ae056e151759a8585de97a1c7c4d53ceecac6631f9fbb39ab6",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf07",\n "parsed": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0f00000073656375726974795f626164676573",\n "parsed": "security_badges"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-4e62a209ec9eda0bdfffd2039d231751690eb4594bab0744d59ae01f3b44b875",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[188 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": "Identity"\n },\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Prune": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000"\n }\n },\n {\n "key": "balance-hold-004c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-11a9f79f8943382d3bff560b55d3153bf33f7a883b0da8da4ad879c5648a4d5b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "entity-system-b317612414e2c1f864730f98386c906db6ea330555f57ba2e5c50daca8eec817",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c1100300",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c11003003900000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e9f55f093d23c687d249f63e7ffaa567560500e794751c0ca897af06af3e5102",\n "era_id": 57,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"We want to draw your attention to a few properties in the example output:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Execution consumed 371736413663 motes, which is less than our ",(0,t.jsx)(n.code,{children:"gas price tolerance"})," of 1000000000000. Read about ",(0,t.jsx)(n.a,{href:"#gas-cost-for-transactions",children:"gas cost for transactions"})]}),"\n",(0,t.jsxs)(n.li,{children:['The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,t.jsx)(n.code,{children:"--gas-price-tolerance"})," arg"]}),"\n",(0,t.jsx)(n.li,{children:"The time-to-live was 30 minutes"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to get a summary of the transaction's information by performing a ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address <HOST:PORT>\n\ncasper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX-STRING> \\\n --state-root-hash <STATE-ROOT-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX STRING>\n --block-hash <BLOCK-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Run the help command for ",(0,t.jsx)(n.code,{children:"query-global-state"})," to see its usage."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"ttl",children:"Time-to-live"}),"\n",(0,t.jsxs)(n.p,{children:["Time-to-live is the parameter that determines how long a transaction will wait for execution. The acceptable maximum ",(0,t.jsx)(n.code,{children:"ttl"})," is configurable by chain, with the Casper Mainnet maximum set to ",(0,t.jsx)(n.code,{children:"18hours"}),". If you are sending a transaction to a different network, you will need to check ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid transaction."]}),"\n",(0,t.jsxs)(n.p,{children:["In the event of a network outage or other event that prevents execution within the ",(0,t.jsx)(n.code,{children:"ttl"}),", the solution is to resend the transaction in question."]}),"\n",(0,t.jsxs)(n.p,{children:["Should the transaction's ",(0,t.jsx)(n.code,{children:"ttl"})," exceed the allowable limit, or if the transaction expires, the network's transaction acceptor will find the transaction invalid and return a warning."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-payments",children:"Legacy Deploy Payments"}),"\n",(0,t.jsxs)(n.p,{children:["Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution. All legacy deploys will go through the ",(0,t.jsx)(n.code,{children:"session"})," subcommand for ",(0,t.jsx)(n.code,{children:"put-txn"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,t.jsx)(n.strong,{children:"empty"})," ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," as your payment code. However, you must specify the amount within a runtime argument. ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."]}),"\n",(0,t.jsx)(n.p,{children:"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByName"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByName"})]}),"\n",(0,t.jsx)(n.h2,{id:"using-arguments-with-transactions",children:"Using Arguments with Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["The session Wasm (or payment Wasm if you choose to ",(0,t.jsx)(n.em,{children:"not"}),' use the standard payment) of a Transaction often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,t.jsx)(n.code,{children:"--session-arg"})," or ",(0,t.jsx)(n.code,{children:"--payment-arg"})," options, once for each arg required. The Casper client provides some examples of how to do this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"advanced-features",children:"Advanced Features"}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks support complex transactions using multiple signatures. ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Casper Accounts"})," use a powerful permissions model that enables a multi-signature scheme for transactions."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"put-transaction"})," command performs multiple actions under the hood, optimizing the typical use case. It creates a transaction, signs it, and sends the Transaction to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-transaction"})," - Creates a Transaction and outputs it to a file or stdout. As a file, the transaction can subsequently be signed by other parties using the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," subcommand and then sent to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-transaction"})," subcommand"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-transaction"})," - Reads a previously-saved Transaction from a file, cryptographically signs it, and outputs it to a file or stdout"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-transaction"})," - Reads a previously-saved Transaction from a file and sends it to the network for execution"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To sign a Transaction with multiple keys, create the Transaction with the ",(0,t.jsx)(n.code,{children:"make-transaction"})," command. The generated transaction file can be sent to the other signers, who then sign it with their keys by calling the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," for each key. Signatures need to be gathered on the Transaction one after another until all required parties have signed the Transaction. Finally, the signed Transaction is sent to the network with the ",(0,t.jsx)(n.code,{children:"send-transaction"})," command for processing."]}),"\n",(0,t.jsxs)(n.p,{children:["For a step-by-step workflow, visit the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer",children:"Two-Party Multi-Signature Transaction"})," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network."]}),"\n",(0,t.jsx)(n.h2,{id:"gas-cost-for-transactions",children:"Gas Cost for Transactions"}),"\n",(0,t.jsx)(n.p,{children:'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'}),"\n",(0,t.jsxs)(n.p,{children:["We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the transaction. If you plan on sending a transaction to ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", you can use the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to estimate the payment amount needed for the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:['Casper\'s "Condor" release introduces a new payment system that includes the concept of ',(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"fee elimination"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["If your test configuration matches your production ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),", you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,t.jsx)(n.a,{href:"/2.0.0/runtime#gas-allocation",children:"runtime economics"})," section for more details about gas usage and fees."]}),"\n",(0,t.jsxs)(n.p,{children:["Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,t.jsxs)(n.p,{children:["If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/types#executionresultv2",children:"failed execution"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"However, if the failure occurs prior to session execution, the penalty payment will not appear in the transaction's gas cost. Depending on the network configuration, the system will deduct the processing fee from the sending account's main purse or place a processing hold on the purse."}),"\n",(0,t.jsx)(n.h2,{id:"common-errors-related-to-payments",children:"Common Errors Related to Payments"}),"\n",(0,t.jsx)(n.h3,{id:"out-of-gas-error",children:"Out of gas error"}),"\n",(0,t.jsx)(n.p,{children:'You might encounter an "Out of gas error" when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.'}),"\n",(0,t.jsxs)(n.p,{children:["Here is an ",(0,t.jsx)(n.a,{href:"https://cspr.live/deploy/afeb43036c41e667af8bc34782c48a66cf4da3818defe9f761291fa515cc38b9",children:"example"}),' of a transaction that resulted in an "Out of gas error" on the Mainnet.']}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 1"}),": In the Deploys tab of an account on ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),', a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an "Out of gas error".']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Out of gas error",src:a(87434).A+"",width:"2048",height:"1118"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 2"}),": Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in account",src:a(27835).A+"",width:"1698",height:"824"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 3"}),": Click the ",(0,t.jsx)(n.strong,{children:"Show raw data"})," button, to see more details about the deploy. Towards the end of the raw data, you can see the error message."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in raw data",src:a(42620).A+"",width:"1472",height:"424"})}),"\n",(0,t.jsx)(n.h3,{id:"gas-limit-error",children:"Gas limit error"}),"\n",(0,t.jsx)(n.p,{children:'You may sometimes see an error such as "payment: 2.5, cost: 2.5, Error::GasLimit". This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error.'}),"\n",(0,t.jsx)(n.p,{children:"This error message tries to communicate that execution stopped at 2.5 CSPR, and the transaction did not run to completion. In other words, the computation resulted in an error because there were insufficient funds for the transaction to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution and charged that much, resulting in a failed transaction. The execution engine does not know how much it would have cost if allowed to run to completion because it did not allow the transaction to finish since it would have run over its gas limit."}),"\n",(0,t.jsx)(n.p,{children:"In summary, when a transaction hits its gas limit (the payment amount), execution stops."})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},27835:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-account-75086cfae6160dfca8cce66fc2b80f44.png"},87434:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-deploys-82cd87f7fc9013f4a7da13e4dd6123e3.png"},42620:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-raw-5b014abd0817fd1c15b225a083a68e3a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b827590.803d7896.js b/assets/js/5b827590.803d7896.js deleted file mode 100644 index 2de5eff01..000000000 --- a/assets/js/5b827590.803d7896.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7371],{33143:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Block Explorers"},i="Block Explorers",a={id:"users/block-explorer",title:"Block Explorers",description:"The Casper blockchain is available as the Mainnet and Testnet.",source:"@site/versioned_docs/version-1.5.X/users/block-explorer.md",sourceDirName:"users",slug:"/users/block-explorer",permalink:"/users/block-explorer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Block Explorers"},sidebar:"users",previous:{title:"Users Overview",permalink:"/users/"},next:{title:"Funding Mainnet Accounts",permalink:"/users/funding-from-exchanges"}},l={},c=[{value:"What is a Block Explorer",id:"what-is-a-block-explorer",level:2},{value:"Using a Block Explorer",id:"using-a-block-explorer",level:2}];function h(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"block-explorers",children:"Block Explorers"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper blockchain is available as the Mainnet and Testnet.\nThe Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR).\nThe Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet."}),"\n",(0,t.jsx)(n.p,{children:"You can use block explorers to explore the Casper blockchain such as :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"what-is-a-block-explorer",children:"What is a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history."}),"\n",(0,t.jsx)(n.h2,{id:"using-a-block-explorer",children:"Using a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of deploys, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator."}),"\n",(0,t.jsxs)(n.p,{children:["The following topics link you to detailed instructions on using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to access and work with your CSPR tokens."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn how to access your Casper account using the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the process of ",(0,t.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens using a Block Explorer"})]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the concepts and the process of ",(0,t.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating"})," and ",(0,t.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating"})," CSPR tokens"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["To perform actions using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, you must sign in to your Casper account using one of the wallets provided."]})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5b827590.e6f4f0a7.js b/assets/js/5b827590.e6f4f0a7.js new file mode 100644 index 000000000..835b7b292 --- /dev/null +++ b/assets/js/5b827590.e6f4f0a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57371],{33143:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Block Explorers"},i="Block Explorers",a={id:"users/block-explorer",title:"Block Explorers",description:"The Casper blockchain is available as the Mainnet and Testnet.",source:"@site/versioned_docs/version-1.5.X/users/block-explorer.md",sourceDirName:"users",slug:"/users/block-explorer",permalink:"/1.5.X/users/block-explorer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Block Explorers"},sidebar:"users",previous:{title:"Users Overview",permalink:"/1.5.X/users/"},next:{title:"Funding Mainnet Accounts",permalink:"/1.5.X/users/funding-from-exchanges"}},l={},c=[{value:"What is a Block Explorer",id:"what-is-a-block-explorer",level:2},{value:"Using a Block Explorer",id:"using-a-block-explorer",level:2}];function h(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"block-explorers",children:"Block Explorers"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper blockchain is available as the Mainnet and Testnet.\nThe Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR).\nThe Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet."}),"\n",(0,t.jsx)(n.p,{children:"You can use block explorers to explore the Casper blockchain such as :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"what-is-a-block-explorer",children:"What is a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history."}),"\n",(0,t.jsx)(n.h2,{id:"using-a-block-explorer",children:"Using a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of deploys, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator."}),"\n",(0,t.jsxs)(n.p,{children:["The following topics link you to detailed instructions on using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to access and work with your CSPR tokens."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn how to access your Casper account using the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the process of ",(0,t.jsx)(n.a,{href:"/1.5.X/users/token-transfer",children:"Transferring Tokens using a Block Explorer"})]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the concepts and the process of ",(0,t.jsx)(n.a,{href:"/1.5.X/users/delegate-ui",children:"Delegating"})," and ",(0,t.jsx)(n.a,{href:"/1.5.X/users/undelegate-ui",children:"Undelegating"})," CSPR tokens"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["To perform actions using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, you must sign in to your Casper account using one of the wallets provided."]})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c07109c.72972707.js b/assets/js/5c07109c.72972707.js deleted file mode 100644 index b8fe74e60..000000000 --- a/assets/js/5c07109c.72972707.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8183],{70843:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(74848),o=s(28453);const r={title:"Configuration"},t="Basic Node Configuration",c={id:"operators/setup/basic-node-configuration",title:"Configuration",description:"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.",source:"@site/versioned_docs/version-1.5.X/operators/setup/basic-node-configuration.md",sourceDirName:"operators/setup",slug:"/operators/setup/basic-node-configuration",permalink:"/operators/setup/basic-node-configuration",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Configuration"},sidebar:"operators",previous:{title:"Hardware",permalink:"/operators/setup/hardware"},next:{title:"Endpoints",permalink:"/operators/setup/node-endpoints"}},l={},d=[{value:"The Casper Node Launcher",id:"casper-node-launcher",level:2},{value:"File Locations",id:"file-locations",level:2},{value:"<code>/usr/bin/</code>",id:"usrbin",level:3},{value:"<code>/etc/casper/</code>",id:"etccasper",level:3},{value:"<code>/var/lib/casper/</code>",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the <code>config.toml</code> file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-node-configuration",children:"Basic Node Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,i.jsx)(n.a,{href:"/operators/setup/install-node",children:"Node Setup"})," guide."]}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-launcher",children:"The Casper Node Launcher"}),"\n",(0,i.jsxs)(n.p,{children:["A node is usually run by executing the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),", which executes the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process and also handles upgrades to bring the node to the latest version released."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," can be installed via a Debian package, which also creates the ",(0,i.jsx)(n.code,{children:"casper"})," user and directory structures and sets up a ",(0,i.jsx)(n.code,{children:"systemd"})," unit and logging."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian package can be obtained from ",(0,i.jsx)(n.a,{href:"https://repo.casperlabs.io",children:"https://repo.casperlabs.io"}),". You only need to run the steps detailed there once."]}),"\n",(0,i.jsxs)(n.p,{children:["Then, proceed to install the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," by running these commands:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install casper-node-launcher\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also build ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"from source"}),". However, all the setup and pull of casper-node releases will be manual."]}),"\n",(0,i.jsx)(n.h2,{id:"file-locations",children:"File Locations"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian installation creates the directories and files needed to run ",(0,i.jsx)(n.code,{children:"casper-node"})," versions and perform upgrades. A ",(0,i.jsx)(n.code,{children:"casper"})," user and ",(0,i.jsx)(n.code,{children:"casper"})," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,i.jsx)(n.code,{children:"/etc/casper"})," and ",(0,i.jsx)(n.code,{children:"/var/lib/casper"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"The casper-node install version"})}),"\n",(0,i.jsxs)(n.p,{children:["Each version of the ",(0,i.jsx)(n.code,{children:"casper-node"})," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,i.jsx)(n.code,{children:"1_0_3"}),". This convention applies to both binary and configuration file locations. Versioning with ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," represents the major, minor, and patch of a semantic version."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Multiple versioned folders will exist on a system when upgrades are set up."})}),"\n",(0,i.jsxs)(n.p,{children:["The following is the filesystem's state after installing the ",(0,i.jsx)(n.code,{children:"casper-client"})," and ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian packages, and after running the command ",(0,i.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf"})," (Use casper-test.conf if on Testnet)."]}),"\n",(0,i.jsx)(n.h3,{id:"usrbin",children:(0,i.jsx)(n.code,{children:"/usr/bin/"})}),"\n",(0,i.jsxs)(n.p,{children:["The default location for executables from the Debian package install is ",(0,i.jsx)(n.code,{children:"/usr/bin"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-client"})," - A client for interacting with a Casper network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher"})," - The launcher application which starts the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"etccasper",children:(0,i.jsx)(n.code,{children:"/etc/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the default location for configuration files. It can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_CONFIG_DIR"})," environment variable. The paths in this document assume the default configuration file location of ",(0,i.jsx)(n.code,{children:"/etc/casper"}),". The data is organized as follows:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"delete_local_db.sh"})," - Removes ",(0,i.jsx)(n.code,{children:"*.lmdb*"})," files from ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"})," - Pulls ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," from ",(0,i.jsx)(n.a,{href:"https://genesis.casperlabs.io/",children:"genesis.casperlabs.io"})," for a specified protocol version and extracts them into ",(0,i.jsx)(n.code,{children:"/var/lib/bin/<protocol_version>"})," and ",(0,i.jsx)(n.code,{children:"/etc/casper/<protocol_version>"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config_from_example.sh"})," - Gets external IP to replace and create the ",(0,i.jsx)(n.code,{children:"config.toml"})," from ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node_util.py"})," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"}),", ",(0,i.jsx)(n.code,{children:"config_from_example.sh"}),", and ",(0,i.jsx)(n.code,{children:"delete_local_db.sh"}),". Other scripts will be deprecated in future releases of ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher-state.toml"})," - The local state for the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," which is created during the first run"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_keys/"})," - The default folder for node keys, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Instructions on how to create validator keys using the ",(0,i.jsx)(n.code,{children:"casper-client"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret_key.pem"})," - Secret key used by the validator node to sign blocks and peer-to-peer messages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key.pem"})," - Public key associated with the secret key above, stored in PEM format"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key_hex"})," - Public key associated with the secret key above, stored in hex format"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"accounts.toml"})," - Contains the genesis validators and delegators"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," (network start time) as a timestamp"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - Example for creating a ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,i.jsx)(n.code,{children:"config_from_example.sh 1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package's configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," as an era ID (the era at which this protocol version of the node became or will become active)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config-example.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"varlibcasper",children:(0,i.jsx)(n.code,{children:"/var/lib/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the location for larger and variable data for the ",(0,i.jsx)(n.code,{children:"casper-node"}),", organized in the following folders and files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bin/"})," - The parent folder storing the versions of ",(0,i.jsx)(n.code,{children:"casper-node"})," executables. This location can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_BIN_DIR"})," environment variable. The paths in this document assume the default of ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis binary files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - The node executable - defaults to the Ubuntu 20.04 compatible binary"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/casper-node"}),", but the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/README.md"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"casper-node/<NETWORK NAME>"})," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,i.jsx)(n.code,{children:"casper"})," and for Testnet it is ",(0,i.jsx)(n.code,{children:"casper-test"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmdb"})," - Persistent global state store of the network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmbd-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"data.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb"})," - Persistent store of all other network data, primarily Blocks and Deploys"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"storage.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"unit_files/"})," - Folder containing transient caches of consensus information"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"node-version-installation",children:"Node Version Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is ",(0,i.jsx)(n.code,{children:"node_util.py"})," for installing ",(0,i.jsx)(n.code,{children:"casper-node"})," versions. This command will stage all current ",(0,i.jsx)(n.code,{children:"casper-node"})," versions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"<NETWORK_CONFIG>"}),", we use ",(0,i.jsx)(n.code,{children:"casper.conf"})," for Mainnet and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," for Testnet. This will install all currently released protocols in one step."]}),"\n",(0,i.jsx)(n.p,{children:"This command will do the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," containing at a minimum ",(0,i.jsx)(n.code,{children:"casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," containing ",(0,i.jsx)(n.code,{children:"chainspec.toml"}),", ",(0,i.jsx)(n.code,{children:"config-example.toml"}),", and possibly ",(0,i.jsx)(n.code,{children:"accounts.csv"})," and other files"]}),"\n",(0,i.jsxs)(n.li,{children:["Remove the archive files and run ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh 1_0_2"})," to create a ",(0,i.jsx)(n.code,{children:"config.toml"})," from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Release versions are invoked using the underscore format, such as:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-file",children:"The Node Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["One ",(0,i.jsx)(n.code,{children:"config.toml"})," file exists for each ",(0,i.jsx)(n.code,{children:"casper-node"})," version installed. It is located in the ",(0,i.jsx)(n.code,{children:"/etc/casper/[m_n_p]/"})," directory, where ",(0,i.jsx)(n.code,{children:"m_n_p"})," is the current semantic version. This can be created from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})," by using ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh [m_n_p]"})," where ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," is replaced with the current version, using underscores."]}),"\n",(0,i.jsxs)(n.p,{children:["Below are some fields in the ",(0,i.jsx)(n.code,{children:"config.toml"})," that you may need to adjust."]}),"\n",(0,i.jsx)(n.h3,{id:"trusted-hash-for-synchronizing",children:"The Trusted Hash for Synchronizing"}),"\n",(0,i.jsx)(n.p,{children:"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."}),"\n",(0,i.jsx)(n.p,{children:"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Find a list of trusted validators"}),"\n",(0,i.jsxs)(n.li,{children:["Query the status endpoint of a trusted validator (",(0,i.jsx)(n.code,{children:"http://<NODE_IP_ADDRESS>:8888/status"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Obtain the hash of a block from the status endpoint"}),"\n",(0,i.jsxs)(n.li,{children:["Update the ",(0,i.jsx)(n.code,{children:"config.toml"})," for the node to include the trusted hash. There is a field dedicated to this near the top of the file"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"known-addresses",children:"Known Addresses"}),"\n",(0,i.jsxs)(n.p,{children:["For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", these are listed in the ",(0,i.jsx)(n.code,{children:"config.toml"})," as ",(0,i.jsx)(n.code,{children:"known_addresses"}),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"example configuration"}),". The ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release",children:"casper-protocol-release"})," repository stores configurations for various environments, which you can also use as examples."]}),"\n",(0,i.jsxs)(n.h3,{id:"updating-config-file",children:["Updating the ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.p,{children:["At the top of a ",(0,i.jsx)(n.code,{children:"config.toml"})," file as shown here, enter the trusted block hash to replace the ",(0,i.jsx)(n.code,{children:"'HEX-FORMATTED BLOCK HASH'"})," and uncomment the line by deleting the leading '#'. See the ",(0,i.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"Configuration File"})," for more details."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secret-keys",children:"Secret Keys"}),"\n",(0,i.jsxs)(n.p,{children:["Provide the path to the secret keys for the node. This path is set to ",(0,i.jsx)(n.code,{children:"etc/casper/validator_keys/"})," by default. See ",(0,i.jsx)(n.a,{href:"#create-fund-keys",children:"Creating Keys and Funding Accounts"})," for more details."]}),"\n",(0,i.jsx)(n.h3,{id:"networking--gossiping",children:"Networking and Gossiping"}),"\n",(0,i.jsxs)(n.p,{children:["The node requires a publicly accessible IP address. The ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," and ",(0,i.jsx)(n.code,{children:"node_util.py"})," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," external services are called to find your IP and this is inserted into the ",(0,i.jsx)(n.code,{children:"config.toml"})," created."]}),"\n",(0,i.jsx)(n.p,{children:"The following default values are specified in the file if you want to change them:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The port that will be used for status and deploys"}),"\n",(0,i.jsx)(n.li,{children:"The port used for networking"}),"\n",(0,i.jsx)(n.li,{children:"Known_addresses - these are the bootstrap nodes (there is no need to change these)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"enabling-speculative-execution",children:"Enabling Speculative Execution"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, ",(0,i.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"speculative_exec"})," can be enabled within ",(0,i.jsx)(n.em,{children:"config.toml"})," by changing ",(0,i.jsx)(n.code,{children:"enable_server"})," to ",(0,i.jsx)(n.code,{children:"true"})," under the configuration options for the speculative execution JSON-RPC HTTP server."]}),"\n",(0,i.jsxs)(n.p,{children:["Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,i.jsx)(n.code,{children:"7778"}),". Further, you can choose to alter the ",(0,i.jsx)(n.code,{children:"qps_limit"})," and ",(0,i.jsx)(n.code,{children:"max_body_bytes"}),", which limit the amount and size of requests to the speculative execution server."]}),"\n",(0,i.jsx)(n.h4,{id:"example-configtoml-configuration-with-speculative-execution-enabled",children:"Example Config.toml configuration with speculative execution enabled"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client-installation",children:"Rust Client Installation"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Prerequisites"})," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."]}),"\n",(0,i.jsx)(n.h2,{id:"create-fund-keys",children:"Creating Keys and Funding Accounts"}),"\n",(0,i.jsxs)(n.p,{children:["The following command will create keys in the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys"})," folder."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To learn about other options for generating keys, see ",(0,i.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," or run the Rust client ",(0,i.jsx)(n.code,{children:"keygen"})," command with the ",(0,i.jsx)(n.code,{children:"--help"})," option."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More about keys and key generation can also be found in ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/README.md"})," if the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," was installed from the Debian package."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Save your keys in a secure location, preferably offline."})}),"\n",(0,i.jsxs)(n.p,{children:["To submit a bonding request, you will need to ",(0,i.jsx)(n.a,{href:"/developers/prerequisites#fund-your-account",children:"fund your account"})," as well."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c07109c.9dc5bbd3.js b/assets/js/5c07109c.9dc5bbd3.js new file mode 100644 index 000000000..86dd0610b --- /dev/null +++ b/assets/js/5c07109c.9dc5bbd3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98183],{70843:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(74848),o=s(28453);const r={title:"Configuration"},t="Basic Node Configuration",c={id:"operators/setup/basic-node-configuration",title:"Configuration",description:"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.",source:"@site/versioned_docs/version-1.5.X/operators/setup/basic-node-configuration.md",sourceDirName:"operators/setup",slug:"/operators/setup/basic-node-configuration",permalink:"/1.5.X/operators/setup/basic-node-configuration",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Configuration"},sidebar:"operators",previous:{title:"Hardware",permalink:"/1.5.X/operators/setup/hardware"},next:{title:"Endpoints",permalink:"/1.5.X/operators/setup/node-endpoints"}},l={},d=[{value:"The Casper Node Launcher",id:"casper-node-launcher",level:2},{value:"File Locations",id:"file-locations",level:2},{value:"<code>/usr/bin/</code>",id:"usrbin",level:3},{value:"<code>/etc/casper/</code>",id:"etccasper",level:3},{value:"<code>/var/lib/casper/</code>",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the <code>config.toml</code> file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-node-configuration",children:"Basic Node Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node",children:"Node Setup"})," guide."]}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-launcher",children:"The Casper Node Launcher"}),"\n",(0,i.jsxs)(n.p,{children:["A node is usually run by executing the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),", which executes the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process and also handles upgrades to bring the node to the latest version released."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," can be installed via a Debian package, which also creates the ",(0,i.jsx)(n.code,{children:"casper"})," user and directory structures and sets up a ",(0,i.jsx)(n.code,{children:"systemd"})," unit and logging."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian package can be obtained from ",(0,i.jsx)(n.a,{href:"https://repo.casperlabs.io",children:"https://repo.casperlabs.io"}),". You only need to run the steps detailed there once."]}),"\n",(0,i.jsxs)(n.p,{children:["Then, proceed to install the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," by running these commands:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install casper-node-launcher\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also build ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"from source"}),". However, all the setup and pull of casper-node releases will be manual."]}),"\n",(0,i.jsx)(n.h2,{id:"file-locations",children:"File Locations"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian installation creates the directories and files needed to run ",(0,i.jsx)(n.code,{children:"casper-node"})," versions and perform upgrades. A ",(0,i.jsx)(n.code,{children:"casper"})," user and ",(0,i.jsx)(n.code,{children:"casper"})," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,i.jsx)(n.code,{children:"/etc/casper"})," and ",(0,i.jsx)(n.code,{children:"/var/lib/casper"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"The casper-node install version"})}),"\n",(0,i.jsxs)(n.p,{children:["Each version of the ",(0,i.jsx)(n.code,{children:"casper-node"})," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,i.jsx)(n.code,{children:"1_0_3"}),". This convention applies to both binary and configuration file locations. Versioning with ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," represents the major, minor, and patch of a semantic version."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Multiple versioned folders will exist on a system when upgrades are set up."})}),"\n",(0,i.jsxs)(n.p,{children:["The following is the filesystem's state after installing the ",(0,i.jsx)(n.code,{children:"casper-client"})," and ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian packages, and after running the command ",(0,i.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf"})," (Use casper-test.conf if on Testnet)."]}),"\n",(0,i.jsx)(n.h3,{id:"usrbin",children:(0,i.jsx)(n.code,{children:"/usr/bin/"})}),"\n",(0,i.jsxs)(n.p,{children:["The default location for executables from the Debian package install is ",(0,i.jsx)(n.code,{children:"/usr/bin"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-client"})," - A client for interacting with a Casper network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher"})," - The launcher application which starts the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"etccasper",children:(0,i.jsx)(n.code,{children:"/etc/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the default location for configuration files. It can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_CONFIG_DIR"})," environment variable. The paths in this document assume the default configuration file location of ",(0,i.jsx)(n.code,{children:"/etc/casper"}),". The data is organized as follows:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"delete_local_db.sh"})," - Removes ",(0,i.jsx)(n.code,{children:"*.lmdb*"})," files from ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"})," - Pulls ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," from ",(0,i.jsx)(n.a,{href:"https://genesis.casperlabs.io/",children:"genesis.casperlabs.io"})," for a specified protocol version and extracts them into ",(0,i.jsx)(n.code,{children:"/var/lib/bin/<protocol_version>"})," and ",(0,i.jsx)(n.code,{children:"/etc/casper/<protocol_version>"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config_from_example.sh"})," - Gets external IP to replace and create the ",(0,i.jsx)(n.code,{children:"config.toml"})," from ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node_util.py"})," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"}),", ",(0,i.jsx)(n.code,{children:"config_from_example.sh"}),", and ",(0,i.jsx)(n.code,{children:"delete_local_db.sh"}),". Other scripts will be deprecated in future releases of ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher-state.toml"})," - The local state for the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," which is created during the first run"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_keys/"})," - The default folder for node keys, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Instructions on how to create validator keys using the ",(0,i.jsx)(n.code,{children:"casper-client"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret_key.pem"})," - Secret key used by the validator node to sign blocks and peer-to-peer messages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key.pem"})," - Public key associated with the secret key above, stored in PEM format"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key_hex"})," - Public key associated with the secret key above, stored in hex format"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"accounts.toml"})," - Contains the genesis validators and delegators"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," (network start time) as a timestamp"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - Example for creating a ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,i.jsx)(n.code,{children:"config_from_example.sh 1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package's configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," as an era ID (the era at which this protocol version of the node became or will become active)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config-example.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"varlibcasper",children:(0,i.jsx)(n.code,{children:"/var/lib/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the location for larger and variable data for the ",(0,i.jsx)(n.code,{children:"casper-node"}),", organized in the following folders and files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bin/"})," - The parent folder storing the versions of ",(0,i.jsx)(n.code,{children:"casper-node"})," executables. This location can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_BIN_DIR"})," environment variable. The paths in this document assume the default of ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis binary files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - The node executable - defaults to the Ubuntu 20.04 compatible binary"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/casper-node"}),", but the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/README.md"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"casper-node/<NETWORK NAME>"})," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,i.jsx)(n.code,{children:"casper"})," and for Testnet it is ",(0,i.jsx)(n.code,{children:"casper-test"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmdb"})," - Persistent global state store of the network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmbd-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"data.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb"})," - Persistent store of all other network data, primarily Blocks and Deploys"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"storage.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"unit_files/"})," - Folder containing transient caches of consensus information"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"node-version-installation",children:"Node Version Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is ",(0,i.jsx)(n.code,{children:"node_util.py"})," for installing ",(0,i.jsx)(n.code,{children:"casper-node"})," versions. This command will stage all current ",(0,i.jsx)(n.code,{children:"casper-node"})," versions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"<NETWORK_CONFIG>"}),", we use ",(0,i.jsx)(n.code,{children:"casper.conf"})," for Mainnet and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," for Testnet. This will install all currently released protocols in one step."]}),"\n",(0,i.jsx)(n.p,{children:"This command will do the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," containing at a minimum ",(0,i.jsx)(n.code,{children:"casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," containing ",(0,i.jsx)(n.code,{children:"chainspec.toml"}),", ",(0,i.jsx)(n.code,{children:"config-example.toml"}),", and possibly ",(0,i.jsx)(n.code,{children:"accounts.csv"})," and other files"]}),"\n",(0,i.jsxs)(n.li,{children:["Remove the archive files and run ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh 1_0_2"})," to create a ",(0,i.jsx)(n.code,{children:"config.toml"})," from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Release versions are invoked using the underscore format, such as:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-file",children:"The Node Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["One ",(0,i.jsx)(n.code,{children:"config.toml"})," file exists for each ",(0,i.jsx)(n.code,{children:"casper-node"})," version installed. It is located in the ",(0,i.jsx)(n.code,{children:"/etc/casper/[m_n_p]/"})," directory, where ",(0,i.jsx)(n.code,{children:"m_n_p"})," is the current semantic version. This can be created from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})," by using ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh [m_n_p]"})," where ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," is replaced with the current version, using underscores."]}),"\n",(0,i.jsxs)(n.p,{children:["Below are some fields in the ",(0,i.jsx)(n.code,{children:"config.toml"})," that you may need to adjust."]}),"\n",(0,i.jsx)(n.h3,{id:"trusted-hash-for-synchronizing",children:"The Trusted Hash for Synchronizing"}),"\n",(0,i.jsx)(n.p,{children:"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."}),"\n",(0,i.jsx)(n.p,{children:"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Find a list of trusted validators"}),"\n",(0,i.jsxs)(n.li,{children:["Query the status endpoint of a trusted validator (",(0,i.jsx)(n.code,{children:"http://<NODE_IP_ADDRESS>:8888/status"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Obtain the hash of a block from the status endpoint"}),"\n",(0,i.jsxs)(n.li,{children:["Update the ",(0,i.jsx)(n.code,{children:"config.toml"})," for the node to include the trusted hash. There is a field dedicated to this near the top of the file"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"known-addresses",children:"Known Addresses"}),"\n",(0,i.jsxs)(n.p,{children:["For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", these are listed in the ",(0,i.jsx)(n.code,{children:"config.toml"})," as ",(0,i.jsx)(n.code,{children:"known_addresses"}),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"example configuration"}),". The ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release",children:"casper-protocol-release"})," repository stores configurations for various environments, which you can also use as examples."]}),"\n",(0,i.jsxs)(n.h3,{id:"updating-config-file",children:["Updating the ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.p,{children:["At the top of a ",(0,i.jsx)(n.code,{children:"config.toml"})," file as shown here, enter the trusted block hash to replace the ",(0,i.jsx)(n.code,{children:"'HEX-FORMATTED BLOCK HASH'"})," and uncomment the line by deleting the leading '#'. See the ",(0,i.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#config-file",children:"Configuration File"})," for more details."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secret-keys",children:"Secret Keys"}),"\n",(0,i.jsxs)(n.p,{children:["Provide the path to the secret keys for the node. This path is set to ",(0,i.jsx)(n.code,{children:"etc/casper/validator_keys/"})," by default. See ",(0,i.jsx)(n.a,{href:"#create-fund-keys",children:"Creating Keys and Funding Accounts"})," for more details."]}),"\n",(0,i.jsx)(n.h3,{id:"networking--gossiping",children:"Networking and Gossiping"}),"\n",(0,i.jsxs)(n.p,{children:["The node requires a publicly accessible IP address. The ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," and ",(0,i.jsx)(n.code,{children:"node_util.py"})," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," external services are called to find your IP and this is inserted into the ",(0,i.jsx)(n.code,{children:"config.toml"})," created."]}),"\n",(0,i.jsx)(n.p,{children:"The following default values are specified in the file if you want to change them:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The port that will be used for status and deploys"}),"\n",(0,i.jsx)(n.li,{children:"The port used for networking"}),"\n",(0,i.jsx)(n.li,{children:"Known_addresses - these are the bootstrap nodes (there is no need to change these)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"enabling-speculative-execution",children:"Enabling Speculative Execution"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, ",(0,i.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"speculative_exec"})," can be enabled within ",(0,i.jsx)(n.em,{children:"config.toml"})," by changing ",(0,i.jsx)(n.code,{children:"enable_server"})," to ",(0,i.jsx)(n.code,{children:"true"})," under the configuration options for the speculative execution JSON-RPC HTTP server."]}),"\n",(0,i.jsxs)(n.p,{children:["Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,i.jsx)(n.code,{children:"7778"}),". Further, you can choose to alter the ",(0,i.jsx)(n.code,{children:"qps_limit"})," and ",(0,i.jsx)(n.code,{children:"max_body_bytes"}),", which limit the amount and size of requests to the speculative execution server."]}),"\n",(0,i.jsx)(n.h4,{id:"example-configtoml-configuration-with-speculative-execution-enabled",children:"Example Config.toml configuration with speculative execution enabled"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client-installation",children:"Rust Client Installation"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Prerequisites"})," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."]}),"\n",(0,i.jsx)(n.h2,{id:"create-fund-keys",children:"Creating Keys and Funding Accounts"}),"\n",(0,i.jsxs)(n.p,{children:["The following command will create keys in the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys"})," folder."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To learn about other options for generating keys, see ",(0,i.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," or run the Rust client ",(0,i.jsx)(n.code,{children:"keygen"})," command with the ",(0,i.jsx)(n.code,{children:"--help"})," option."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More about keys and key generation can also be found in ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/README.md"})," if the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," was installed from the Debian package."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Save your keys in a secure location, preferably offline."})}),"\n",(0,i.jsxs)(n.p,{children:["To submit a bonding request, you will need to ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#fund-your-account",children:"fund your account"})," as well."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c08a95a.26a3ecb2.js b/assets/js/5c08a95a.26a3ecb2.js new file mode 100644 index 000000000..deba36ea0 --- /dev/null +++ b/assets/js/5c08a95a.26a3ecb2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[54635],{47051:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},l="Quickstart",c={id:"resources/quick-start",title:"Quickstart",description:"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.",source:"@site/versioned_docs/version-2.0.0/resources/quick-start.md",sourceDirName:"resources",slug:"/resources/quick-start",permalink:"/2.0.0/resources/quick-start",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",next:{title:"Overview",permalink:"/2.0.0/resources/tutorials/beginner/"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps",id:"steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Consult the ",(0,t.jsx)(n.a,{href:"/writing-contracts",children:"complete documentation"})," for context and additional help."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"rustup --version"}),". Restart the shell if needed."]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"cmake"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"cmake --version"}),".\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["On Ubuntu, you can follow ",(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"this guide"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["On MacOS, use this command: ",(0,t.jsx)(n.code,{children:"brew install cmake"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install ",(0,t.jsx)(n.code,{children:"cargo-casper"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["You have download ",(0,t.jsx)(n.a,{href:"https://git-scm.com/download/",children:"Git"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Install Cargo Casper with this command:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install cargo-casper"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper client"}),":"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install casper-client"})}),"\n",(0,t.jsx)(n.p,{children:"If you have issues installing the casper-client, you may need additional libraries."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On Ubuntu:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Make sure you also have the development packages of ",(0,t.jsx)(n.code,{children:"openssl"})," installed. For example, ",(0,t.jsx)(n.code,{children:"libssl-dev"})," on Ubuntu or ",(0,t.jsx)(n.code,{children:"openssl-devel"})," on Fedora."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Test the ",(0,t.jsx)(n.code,{children:"casper-client"})," by ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," on the network and getting the latest ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/S#state-root-hash",children:"state root hash"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://65.21.235.219:7777\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"Casper Account"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clone a simple counter contract or download it from GitHub:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/casper-ecosystem/counter"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the folder and prepare the dependencies to build the contract:"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd counter\nmake prepare\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsx)(n.li,{children:"Build the contract and tests:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make test"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Install the contract on Testnet using the ",(0,t.jsx)(n.code,{children:"casper-client"}),"'s ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name casper-test \\\n--secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \\\n--payment-amount 30000000000 \\\n--session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsx)(n.li,{children:"Check the deploy status given the deploy hash from the previous command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"Get the latest state root hash:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsx)(n.li,{children:"Open the deploy tab of the account on the Testnet to see the deploy details."}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"As an alternative to step 15, check your account using the command line:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["As another alternative, use the account hash for the ",(0,t.jsx)(n.code,{children:"--key"})," argument. To get the account hash, look at the account details on the block explorer, or run this command:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, query the blockchain using the account hash:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsx)(n.li,{children:'Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let\'s make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example output:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"17",children:["\n",(0,t.jsxs)(n.li,{children:["Now increment the count value by calling the entry point ",(0,t.jsx)(n.code,{children:"counter_inc"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [PATH_TO_YOUR_KEY] \\\n--payment-amount 100000000 \\\n--session-name "counter" \\\n--session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"18",children:["\n",(0,t.jsxs)(n.li,{children:["Get the NEW ",(0,t.jsx)(n.code,{children:"state root hash"}),", to get the latest snapshot of the blockchain state \u2013 this is EXTREMELY IMPORTANT!"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"19",children:["\n",(0,t.jsx)(n.li,{children:"Query the state of the network."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:'If everything went according to plan, the value should be 1. Look at the "parsed" value below.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 1\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c3f78ae.1c8dc26f.js b/assets/js/5c3f78ae.1c8dc26f.js new file mode 100644 index 000000000..7c5f2ee0a --- /dev/null +++ b/assets/js/5c3f78ae.1c8dc26f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40871],{39911:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const o={title:"Front-end in React"},i="Front-end Template with React",a={id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/1.5.X/developers/dapps/template-frontend",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/1.5.X/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/1.5.X/developers/dapps/uref-security"}},c={},l=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"front-end-template-with-react",children:"Front-end Template with React"})}),"\n",(0,s.jsxs)(n.p,{children:["For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide will walk you through setting up and developing a React application with ",(0,s.jsx)(n.a,{href:"https://vitejs.dev/",children:"Vite"})," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,s.jsx)(n.a,{href:"https://reactjs.org/docs/getting-started.html",children:"reading the React documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,s.jsx)(n.p,{children:"Begin by opening a terminal and running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"node -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"To get your Node.js version."}),"\n",(0,s.jsxs)(n.p,{children:["To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:"Node Version Manager"})," or another tool if you are running an earlier version."]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",children:"npm"}),", create a new Vite project by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install -g vite\nnpm create vite@latest\n"})}),"\n",(0,s.jsx)(n.p,{children:'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'}),"\n",(0,s.jsxs)(n.p,{children:["Head into your new project directory, replacing ",(0,s.jsx)(n.code,{children:"vite-project"})," with your project name:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd vite-project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command to test the server:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install\nvite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Quit the server by pressing ",(0,s.jsx)(n.code,{children:"q"}),". Install the Casper JS SDK by running the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide will use ",(0,s.jsx)(n.a,{href:"https://axios-http.com/",children:"axios"})," to communicate with the backend; install it by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install axios\n"})}),"\n",(0,s.jsx)(n.h2,{id:"casper-wallet-integration",children:"Casper Wallet Integration"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,s.jsx)(n.code,{children:"window.CasperWalletProvider"})," and ",(0,s.jsx)(n.code,{children:"window.CasperWalletEventTypes"}),". If the value of these variables is ",(0,s.jsx)(n.code,{children:"undefined"})," the Casper Wallet is not installed."]}),"\n",(0,s.jsx)(n.p,{children:"Start with a helper for getting the provider instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/casper-wallet.js\n"})}),"\n",(0,s.jsx)(n.p,{children:"Fill the file with the following content:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS\n });\n return provider;\n}\n\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For complete integration details, refer to ",(0,s.jsx)(n.a,{href:"https://github.com/make-software/casper-wallet-sdk/#readme",children:"README of Casper Wallet SDK"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," or another parent component that encapsulates the components that should have access to this public key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n </>)}\n </div>\n </>\n );\n}\n\nexport default App;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This is an example of ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," that imports and displays the ",(0,s.jsx)(n.code,{children:"Connect"})," component that is described next. The ",(0,s.jsx)(n.code,{children:"setPublicKey"})," function is passed to the ",(0,s.jsx)(n.code,{children:"Connect"})," component as a ",(0,s.jsx)(n.a,{href:"https://legacy.reactjs.org/docs/components-and-props.html",children:"prop"})," so that it may set the public key and make it available to all of ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),". This way, when more components are added to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", they may utilize the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable."]}),"\n",(0,s.jsxs)(n.p,{children:["To connect to the Casper Wallet within your React app, create the ",(0,s.jsx)(n.code,{children:"Connect"})," component and import the ",(0,s.jsx)(n.code,{children:"getProvider"})," helper."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Connect.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n {/* Place for disconnect button */}\n </>\n );\n}\n\nexport default Connect;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Notice that ",(0,s.jsx)(n.code,{children:"Connect"})," accepts props, and forwards them to the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," using ",(0,s.jsx)(n.code,{children:"props.setPublicKey()"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Write the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function under the ",(0,s.jsx)(n.code,{children:"Connect"})," function component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const connectToWallet = (props) => {\n provider.requestConnection().then(connected => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider.getActivePublicKey().then(publicKey => {\n props.setPublicKey(publicKey);\n }).catch(error => {\n alert(error.message);\n });\n }\n })\n .catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"connectToWallet()"})," function calls ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," will throw an error if the Wallet is not installed as an extension or if it is locked."]}),"\n",(0,s.jsx)(n.h3,{id:"disconnect-the-casper-wallet",children:"Disconnect the Casper Wallet"}),"\n",(0,s.jsxs)(n.p,{children:["To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,s.jsx)(n.em,{children:"src/Connect.jsx"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const disconnect = (props) => {\n provider.disconnectFromSite().then(disconnected => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n } \n }).catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then connect it to a button:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:"const Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n // highlight-next-line-green\n <button onClick={ () => disconnect(props) }>Disconnect</button>\n </>\n );\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"call-a-smart-contract",children:"Call a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:['For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,s.jsx)(n.code,{children:"input"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,s.jsx)(n.code,{children:"input"}),", then grab the value within the smart-contract-calling function."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/UpdateMessage.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { useState } from \'react\';\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />\n <button onClick={ () => updateMessage(props, message) }>Update Message</button>\n </>\n );\n}\n\nexport default UpdateMessage;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable passed in as a prop from ",(0,s.jsx)(n.code,{children:"src/App.jsx"}),". Write this function under your ",(0,s.jsx)(n.code,{children:"UpdateMessage"})," component function."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string(message)\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request\n axios.post("/sendDeploy", signedDeploy, {\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then((response) => {\n alert(response.data);\n }).catch((error) => {\n console.error(error.message);\n });\n }).catch((error) => {\n console.error(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In this example, ",(0,s.jsx)(n.code,{children:"updateMessage"})," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,s.jsx)(n.code,{children:"signedDeploy"})," is forwarded to the backend at the ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," endpoint using ",(0,s.jsx)(n.code,{children:"axios.post"})," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,s.jsx)(n.code,{children:"stderr"}),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert",children:"alert"}),"; however, you may do with the response data as you wish."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["The backend endpoint ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," should handle signed deployment by simply passing it to a Casper node."]}),(0,s.jsxs)(n.p,{children:["In Casper node ",(0,s.jsx)(n.code,{children:"v1.5.0"}),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node."]})]}),"\n",(0,s.jsxs)(n.p,{children:["Now that this component is created, render it to the user interface in ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", passing along the ",(0,s.jsx)(n.code,{children:"publicKey"})," as a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n // highlight-next-line-green\n <UpdateMessage publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"query-a-smart-contract",children:"Query a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Consider that the message written to the chain during the ",(0,s.jsx)(n.code,{children:"update_message"})," entrypoint invocation is stored in the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/D#dictionary",children:"dictionary"})," ",(0,s.jsx)(n.code,{children:"messages"})," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/A#account-hash",children:"account hash"})," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Query.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return <button onClick={ () => query(props) }>Query</button>;\n}\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {\n alert(response.data)\n }).catch((error) => {\n console.error(error.message);\n });\n}\n\nexport default Query;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All this component does is render an HTML ",(0,s.jsx)(n.code,{children:"button"})," element that, when pressed, performs a ",(0,s.jsx)(n.code,{children:"GET"})," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"toAccountHashStr"}),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,s.jsx)(n.code,{children:"substring(13)"})," method."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["This functionality relies on the ",(0,s.jsx)(n.code,{children:"/queryMessage"})," endpoint, which should be implemented in your backend."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now add this component to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", making available the ",(0,s.jsx)(n.code,{children:"publicKey"})," state variable via a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n <UpdateMessage publicKey={ publicKey } />\n // highlight-next-line-green\n <Query publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"test-application",children:"Test Application"}),"\n",(0,s.jsx)(n.p,{children:"Test your application by running the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,s.jsx)(n.code,{children:"h"}),", then ",(0,s.jsx)(n.code,{children:"o"})," to open the app in a browser."]}),"\n",(0,s.jsx)(n.h2,{id:"build-for-production",children:"Build for Production"}),"\n",(0,s.jsx)(n.p,{children:"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite build\n"})}),"\n",(0,s.jsx)(n.p,{children:"Once this is complete, you can preview your production build by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite preview\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5c3f78ae.c5d549a0.js b/assets/js/5c3f78ae.c5d549a0.js deleted file mode 100644 index 5e559ecf7..000000000 --- a/assets/js/5c3f78ae.c5d549a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[871],{39911:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const o={title:"Front-end in React"},i="Front-end Template with React",a={id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/developers/dapps/template-frontend",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"}},c={},l=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"front-end-template-with-react",children:"Front-end Template with React"})}),"\n",(0,s.jsxs)(n.p,{children:["For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide will walk you through setting up and developing a React application with ",(0,s.jsx)(n.a,{href:"https://vitejs.dev/",children:"Vite"})," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,s.jsx)(n.a,{href:"https://reactjs.org/docs/getting-started.html",children:"reading the React documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,s.jsx)(n.p,{children:"Begin by opening a terminal and running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"node -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"To get your Node.js version."}),"\n",(0,s.jsxs)(n.p,{children:["To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:"Node Version Manager"})," or another tool if you are running an earlier version."]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",children:"npm"}),", create a new Vite project by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install -g vite\nnpm create vite@latest\n"})}),"\n",(0,s.jsx)(n.p,{children:'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'}),"\n",(0,s.jsxs)(n.p,{children:["Head into your new project directory, replacing ",(0,s.jsx)(n.code,{children:"vite-project"})," with your project name:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd vite-project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command to test the server:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install\nvite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Quit the server by pressing ",(0,s.jsx)(n.code,{children:"q"}),". Install the Casper JS SDK by running the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide will use ",(0,s.jsx)(n.a,{href:"https://axios-http.com/",children:"axios"})," to communicate with the backend; install it by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install axios\n"})}),"\n",(0,s.jsx)(n.h2,{id:"casper-wallet-integration",children:"Casper Wallet Integration"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,s.jsx)(n.code,{children:"window.CasperWalletProvider"})," and ",(0,s.jsx)(n.code,{children:"window.CasperWalletEventTypes"}),". If the value of these variables is ",(0,s.jsx)(n.code,{children:"undefined"})," the Casper Wallet is not installed."]}),"\n",(0,s.jsx)(n.p,{children:"Start with a helper for getting the provider instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/casper-wallet.js\n"})}),"\n",(0,s.jsx)(n.p,{children:"Fill the file with the following content:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS\n });\n return provider;\n}\n\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For complete integration details, refer to ",(0,s.jsx)(n.a,{href:"https://github.com/make-software/casper-wallet-sdk/#readme",children:"README of Casper Wallet SDK"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," or another parent component that encapsulates the components that should have access to this public key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n </>)}\n </div>\n </>\n );\n}\n\nexport default App;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This is an example of ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," that imports and displays the ",(0,s.jsx)(n.code,{children:"Connect"})," component that is described next. The ",(0,s.jsx)(n.code,{children:"setPublicKey"})," function is passed to the ",(0,s.jsx)(n.code,{children:"Connect"})," component as a ",(0,s.jsx)(n.a,{href:"https://legacy.reactjs.org/docs/components-and-props.html",children:"prop"})," so that it may set the public key and make it available to all of ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),". This way, when more components are added to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", they may utilize the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable."]}),"\n",(0,s.jsxs)(n.p,{children:["To connect to the Casper Wallet within your React app, create the ",(0,s.jsx)(n.code,{children:"Connect"})," component and import the ",(0,s.jsx)(n.code,{children:"getProvider"})," helper."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Connect.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n {/* Place for disconnect button */}\n </>\n );\n}\n\nexport default Connect;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Notice that ",(0,s.jsx)(n.code,{children:"Connect"})," accepts props, and forwards them to the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," using ",(0,s.jsx)(n.code,{children:"props.setPublicKey()"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Write the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function under the ",(0,s.jsx)(n.code,{children:"Connect"})," function component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const connectToWallet = (props) => {\n provider.requestConnection().then(connected => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider.getActivePublicKey().then(publicKey => {\n props.setPublicKey(publicKey);\n }).catch(error => {\n alert(error.message);\n });\n }\n })\n .catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"connectToWallet()"})," function calls ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," will throw an error if the Wallet is not installed as an extension or if it is locked."]}),"\n",(0,s.jsx)(n.h3,{id:"disconnect-the-casper-wallet",children:"Disconnect the Casper Wallet"}),"\n",(0,s.jsxs)(n.p,{children:["To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,s.jsx)(n.em,{children:"src/Connect.jsx"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const disconnect = (props) => {\n provider.disconnectFromSite().then(disconnected => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n } \n }).catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then connect it to a button:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:"const Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n // highlight-next-line-green\n <button onClick={ () => disconnect(props) }>Disconnect</button>\n </>\n );\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"call-a-smart-contract",children:"Call a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:['For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,s.jsx)(n.code,{children:"input"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,s.jsx)(n.code,{children:"input"}),", then grab the value within the smart-contract-calling function."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/UpdateMessage.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { useState } from \'react\';\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />\n <button onClick={ () => updateMessage(props, message) }>Update Message</button>\n </>\n );\n}\n\nexport default UpdateMessage;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable passed in as a prop from ",(0,s.jsx)(n.code,{children:"src/App.jsx"}),". Write this function under your ",(0,s.jsx)(n.code,{children:"UpdateMessage"})," component function."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string(message)\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request\n axios.post("/sendDeploy", signedDeploy, {\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then((response) => {\n alert(response.data);\n }).catch((error) => {\n console.error(error.message);\n });\n }).catch((error) => {\n console.error(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In this example, ",(0,s.jsx)(n.code,{children:"updateMessage"})," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,s.jsx)(n.code,{children:"signedDeploy"})," is forwarded to the backend at the ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," endpoint using ",(0,s.jsx)(n.code,{children:"axios.post"})," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,s.jsx)(n.code,{children:"stderr"}),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert",children:"alert"}),"; however, you may do with the response data as you wish."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["The backend endpoint ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," should handle signed deployment by simply passing it to a Casper node."]}),(0,s.jsxs)(n.p,{children:["In Casper node ",(0,s.jsx)(n.code,{children:"v1.5.0"}),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node."]})]}),"\n",(0,s.jsxs)(n.p,{children:["Now that this component is created, render it to the user interface in ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", passing along the ",(0,s.jsx)(n.code,{children:"publicKey"})," as a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n // highlight-next-line-green\n <UpdateMessage publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"query-a-smart-contract",children:"Query a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Consider that the message written to the chain during the ",(0,s.jsx)(n.code,{children:"update_message"})," entrypoint invocation is stored in the ",(0,s.jsx)(n.a,{href:"/concepts/glossary/D#dictionary",children:"dictionary"})," ",(0,s.jsx)(n.code,{children:"messages"})," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/A#account-hash",children:"account hash"})," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Query.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return <button onClick={ () => query(props) }>Query</button>;\n}\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {\n alert(response.data)\n }).catch((error) => {\n console.error(error.message);\n });\n}\n\nexport default Query;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All this component does is render an HTML ",(0,s.jsx)(n.code,{children:"button"})," element that, when pressed, performs a ",(0,s.jsx)(n.code,{children:"GET"})," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"toAccountHashStr"}),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,s.jsx)(n.code,{children:"substring(13)"})," method."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["This functionality relies on the ",(0,s.jsx)(n.code,{children:"/queryMessage"})," endpoint, which should be implemented in your backend."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now add this component to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", making available the ",(0,s.jsx)(n.code,{children:"publicKey"})," state variable via a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n <UpdateMessage publicKey={ publicKey } />\n // highlight-next-line-green\n <Query publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"test-application",children:"Test Application"}),"\n",(0,s.jsx)(n.p,{children:"Test your application by running the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,s.jsx)(n.code,{children:"h"}),", then ",(0,s.jsx)(n.code,{children:"o"})," to open the app in a browser."]}),"\n",(0,s.jsx)(n.h2,{id:"build-for-production",children:"Build for Production"}),"\n",(0,s.jsx)(n.p,{children:"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite build\n"})}),"\n",(0,s.jsx)(n.p,{children:"Once this is complete, you can preview your production build by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite preview\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5ce0f216.2ca1cbe8.js b/assets/js/5ce0f216.2ca1cbe8.js deleted file mode 100644 index 0354a07f2..000000000 --- a/assets/js/5ce0f216.2ca1cbe8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2321],{36433:e=>{e.exports=JSON.parse('{"tag":{"label":"features","permalink":"/blog/tags/features","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/features","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/5ce0f216.5f134790.js b/assets/js/5ce0f216.5f134790.js new file mode 100644 index 000000000..eec74f2ff --- /dev/null +++ b/assets/js/5ce0f216.5f134790.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52321],{36433:e=>{e.exports=JSON.parse('{"tag":{"label":"features","permalink":"/blog/tags/features","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/features","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/5cf40dea.940a452c.js b/assets/js/5cf40dea.940a452c.js new file mode 100644 index 000000000..7f8a450c3 --- /dev/null +++ b/assets/js/5cf40dea.940a452c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27927],{47994:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"dApps"},o="Introduction to dApps",r={id:"concepts/intro-to-dapps",title:"dApps",description:"What is a dApp?",source:"@site/docs/concepts/intro-to-dapps.md",sourceDirName:"concepts",slug:"/concepts/intro-to-dapps",permalink:"/concepts/intro-to-dapps",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"dApps"},sidebar:"concepts",previous:{title:"Type Serialization",permalink:"/concepts/serialization/types"},next:{title:"Addressable Entities",permalink:"/concepts/addressable-entity"}},c={},d=[{value:"What is a dApp?",id:"what-is-a-dapp",level:3},{value:"Interacting with a Casper Decentralized Network",id:"interacting-with-a-casper-decentralized-network",level:3},{value:"Updating data in a Casper dApp",id:"updating-data-in-a-casper-dapp",level:4},{value:"Post-Consensus Execution in a Casper network",id:"post-consensus-execution-in-a-casper-network",level:4},{value:"Transaction lifecycle",id:"transaction-lifecycle",level:4},{value:"Related reading",id:"related-reading",level:3}];function l(e){const n={a:"a",em:"em",h1:"h1",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"introduction-to-dapps",children:"Introduction to dApps"})}),"\n",(0,a.jsx)(n.h3,{id:"what-is-a-dapp",children:"What is a dApp?"}),"\n",(0,a.jsxs)(n.p,{children:["DApp stands for ",(0,a.jsx)(n.strong,{children:"Decentralized Application"}),". Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface."]}),"\n",(0,a.jsx)(n.p,{children:"A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power."}),"\n",(0,a.jsxs)(n.p,{children:["A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"nodes"})," does the processing of smart contracts instead of a single central server."]}),"\n",(0,a.jsxs)(n.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"node"}),". The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsx)(n.h3,{id:"interacting-with-a-casper-decentralized-network",children:"Interacting with a Casper Decentralized Network"}),"\n",(0,a.jsxs)(n.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(n.a,{href:"/concepts/glossary/T#transaction",children:"transactions"})," via the ",(0,a.jsx)(n.a,{href:"/developers/json-rpc/",children:"JSON-RPC"}),". Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(n.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(n.p,{children:["A transaction contains ",(0,a.jsx)(n.a,{href:"/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(n.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending ",(0,a.jsx)(n.a,{href:"/concepts/glossary/A#account",children:"account entity"}),". Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly.\nA dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"updating-data-in-a-casper-dapp",children:"Updating data in a Casper dApp"}),"\n",(0,a.jsxs)(n.p,{children:["Sending a transaction is the only means by which a dApp can change ",(0,a.jsx)(n.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),". All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."]}),"\n",(0,a.jsx)(n.h4,{id:"post-consensus-execution-in-a-casper-network",children:"Post-Consensus Execution in a Casper network"}),"\n",(0,a.jsxs)(n.p,{children:["Unlike other blockchain networks, a Casper network performs execution ",(0,a.jsx)(n.em,{children:(0,a.jsx)(n.strong,{children:"after"})})," ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#consensus",children:"consensus"}),". This means that observing the execution of the transaction is sufficient proof of ",(0,a.jsx)(n.a,{href:"/concepts/glossary/B#block-finality",children:"finality"})," for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"transaction-lifecycle",children:"Transaction lifecycle"}),"\n",(0,a.jsxs)(n.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]}),"\n",(0,a.jsx)(n.h3,{id:"related-reading",children:"Related reading"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction lifecycle"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Session Code"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var a=t(96540);const s={},i=a.createContext(s);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5cf40dea.eeda9684.js b/assets/js/5cf40dea.eeda9684.js deleted file mode 100644 index 6108b3278..000000000 --- a/assets/js/5cf40dea.eeda9684.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7927],{47994:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"dApps"},o="Introduction to dApps",r={id:"concepts/intro-to-dapps",title:"dApps",description:"What is a dApp?",source:"@site/docs/concepts/intro-to-dapps.md",sourceDirName:"concepts",slug:"/concepts/intro-to-dapps",permalink:"/next/concepts/intro-to-dapps",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"dApps"},sidebar:"concepts",previous:{title:"Type Serialization",permalink:"/next/concepts/serialization/types"},next:{title:"Addressable Entities",permalink:"/next/concepts/addressable-entity"}},c={},d=[{value:"What is a dApp?",id:"what-is-a-dapp",level:3},{value:"Interacting with a Casper Decentralized Network",id:"interacting-with-a-casper-decentralized-network",level:3},{value:"Updating data in a Casper dApp",id:"updating-data-in-a-casper-dapp",level:4},{value:"Post-Consensus Execution in a Casper network",id:"post-consensus-execution-in-a-casper-network",level:4},{value:"Transaction lifecycle",id:"transaction-lifecycle",level:4},{value:"Related reading",id:"related-reading",level:3}];function l(e){const n={a:"a",em:"em",h1:"h1",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"introduction-to-dapps",children:"Introduction to dApps"})}),"\n",(0,a.jsx)(n.h3,{id:"what-is-a-dapp",children:"What is a dApp?"}),"\n",(0,a.jsxs)(n.p,{children:["DApp stands for ",(0,a.jsx)(n.strong,{children:"Decentralized Application"}),". Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface."]}),"\n",(0,a.jsx)(n.p,{children:"A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power."}),"\n",(0,a.jsxs)(n.p,{children:["A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/N#node",children:"nodes"})," does the processing of smart contracts instead of a single central server."]}),"\n",(0,a.jsxs)(n.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/N#node",children:"node"}),". The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsx)(n.h3,{id:"interacting-with-a-casper-decentralized-network",children:"Interacting with a Casper Decentralized Network"}),"\n",(0,a.jsxs)(n.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"transactions"})," via the ",(0,a.jsx)(n.a,{href:"/next/developers/json-rpc/",children:"JSON-RPC"}),". Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(n.a,{href:"/next/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(n.p,{children:["A transaction contains ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/A#account",children:"account entity"}),". Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly.\nA dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"updating-data-in-a-casper-dapp",children:"Updating data in a Casper dApp"}),"\n",(0,a.jsxs)(n.p,{children:["Sending a transaction is the only means by which a dApp can change ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"}),". All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."]}),"\n",(0,a.jsx)(n.h4,{id:"post-consensus-execution-in-a-casper-network",children:"Post-Consensus Execution in a Casper network"}),"\n",(0,a.jsxs)(n.p,{children:["Unlike other blockchain networks, a Casper network performs execution ",(0,a.jsx)(n.em,{children:(0,a.jsx)(n.strong,{children:"after"})})," ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/C#consensus",children:"consensus"}),". This means that observing the execution of the transaction is sufficient proof of ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/B#block-finality",children:"finality"})," for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."]}),"\n",(0,a.jsx)(n.h4,{id:"transaction-lifecycle",children:"Transaction lifecycle"}),"\n",(0,a.jsxs)(n.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]}),"\n",(0,a.jsx)(n.h3,{id:"related-reading",children:"Related reading"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction lifecycle"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/concepts/global-state",children:"Global State"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Session Code"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var a=t(96540);const s={},i=a.createContext(s);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5d4e9672.00906f33.js b/assets/js/5d4e9672.00906f33.js deleted file mode 100644 index d3d5bfb3c..000000000 --- a/assets/js/5d4e9672.00906f33.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5059],{41788:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>h});var t=s(74848),i=s(28453);const d={title:"Introduction",slug:"/resources/tokens/cep78/introduction"},r="CEP-78 Enhanced NFT Standard Introduction",l={id:"resources/tokens/cep78/introduction",title:"Introduction",description:"Usage",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/introduction.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/introduction",permalink:"/resources/tokens/cep78/introduction",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/resources/tokens/cep78/introduction"},sidebar:"resources",previous:{title:"Testing Guide",permalink:"/resources/tokens/cep18/tests"},next:{title:"CEP-78 Modalities",permalink:"/resources/tokens/cep78/modalities"}},c={},h=[{value:"Usage",id:"usage",level:2},{value:"Building the Contract",id:"building-the-contract",level:3},{value:"Required Runtime Arguments",id:"required-runtime-arguments",level:3},{value:"Example deploy",id:"example-deploy",level:4},{value:"Utility Session Code",id:"utility-session-code",level:3},{value:"Checking Token Ownership",id:"checking-token-ownership",level:3},{value:"Upgrading to Version 1.1.1",id:"upgrading-to-version-111",level:3},{value:"Installing and Interacting with the Contract using the Rust Casper Client",id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",level:2},{value:"Test Suite and Specification",id:"test-suite-and-specification",level:2},{value:"Error Codes",id:"error-codes",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"cep-78-enhanced-nft-standard-introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),"\n",(0,t.jsx)(e.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(e.h3,{id:"building-the-contract",children:"Building the Contract"}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"main.rs"})," file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command from the Makefile provided."]}),"\n",(0,t.jsxs)(e.p,{children:["The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command provided in the Makefile. Please note, however, that you must install ",(0,t.jsx)(e.code,{children:"wasm-strip"})," to build the contract."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"call"})," method will install the contract with the necessary entrypoints and call the ",(0,t.jsx)(e.code,{children:"init()"})," entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation Tutorial"})," provides a step-by-step workflow."]}),"\n",(0,t.jsx)(e.h3,{id:"required-runtime-arguments",children:"Required Runtime Arguments"}),"\n",(0,t.jsxs)(e.p,{children:["The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities",children:"Modalities"})," documentation."]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_name":'})," The name of the NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_symbol"'}),": The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"total_token_supply"'}),": The total number of NFTs that a specific instance of a contract will mint passed in as a ",(0,t.jsx)(e.code,{children:"U64"})," value. This parameter is required."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"ownership_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#ownership",children:(0,t.jsx)(e.code,{children:"OwnershipMode"})})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_kind"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftkind",children:(0,t.jsx)(e.code,{children:"NFTKind"})})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"json_schema"'}),": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required if the metadata kind is set to ",(0,t.jsx)(e.code,{children:"CustomValidated(3)"})," and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_metadata_kind"'}),": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"identifier_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftidentifiermode",children:(0,t.jsx)(e.code,{children:"NFTIdentifierMode"})})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"metadata_mutability"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#metadata-mutability",children:(0,t.jsx)(e.code,{children:"MetadataMutability"})})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The following are the optional parameters that can be passed in at the time of installation."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"minting_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#minting",children:(0,t.jsx)(e.code,{children:"MintingMode"})})," modality that dictates the access to the ",(0,t.jsx)(e.code,{children:"mint()"})," entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"allow_minting"'}),": The ",(0,t.jsx)(e.code,{children:'"allow_minting"'})," flag allows the installer of the contract to pause the minting of new NFTs. The ",(0,t.jsx)(e.code,{children:"allow_minting"})," is a boolean toggle that allows minting when ",(0,t.jsx)(e.code,{children:"true"}),". If not provided at install the toggle will default to ",(0,t.jsx)(e.code,{children:"true"}),". This value can be changed by the installer by calling the ",(0,t.jsx)(e.code,{children:"set_variables()"})," entrypoint."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"whitelist_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#whitelistmode",children:(0,t.jsx)(e.code,{children:"WhitelistMode"})})," modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"holder_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#nftholdermode",children:(0,t.jsx)(e.code,{children:"NFTHolderMode"})})," modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either ",(0,t.jsx)(e.code,{children:"Accounts"})," or ",(0,t.jsx)(e.code,{children:"Contracts"})," to hold NFTs. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"contract_whitelist"'}),": The contract whitelist is a list of contract hashes that specifies which contracts can call the ",(0,t.jsx)(e.code,{children:"mint()"})," entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the ",(0,t.jsx)(e.code,{children:"set_variables"})," post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"burn_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#burnmode",children:(0,t.jsx)(e.code,{children:"BurnMode"})})," modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"owner_reverse_lookup_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#ownerreverselookupmode",children:(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})})," modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"events_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/modalities#eventsmode",children:(0,t.jsx)(e.code,{children:"EventsMode"})})," modality selects the event schema used to record any changes that occur to tokens issued by the contract instance."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"additional_required_metdata"'}),": An additional metadata schema that must be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"optional_metdata"'}),": An optional metadata schema that may be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.h4,{id:"example-deploy",children:"Example deploy"}),"\n",(0,t.jsxs)(e.p,{children:["The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"here"}),"."]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:'casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'enhanced-nft-1\'" \\\n--session-arg "collection_symbol:string=\'ENFT-1\'" \\\n--session-arg "total_token_supply:u64=\'10\'" \\\n--session-arg "ownership_mode:u8=\'0\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "allow_minting:bool=\'true\'" \\\n--session-arg "owner_reverse_lookup_mode:u8=\'0\'" \\\n--session-arg "nft_metadata_kind:u8=\'2\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(e.h3,{id:"utility-session-code",children:"Utility Session Code"}),"\n",(0,t.jsxs)(e.p,{children:["Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary.\nIn order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that\nusers and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the ",(0,t.jsx)(e.code,{children:"client"}),"\nfolder within the project folder."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint name"}),(0,t.jsx)(e.th,{children:"Session code"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"mint"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/mint_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"balance_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/balance_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"get_approved'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/get_approved_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"owner_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/owner_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"transfer"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/transfer_session"})})]})]})]}),"\n",(0,t.jsx)(e.h3,{id:"checking-token-ownership",children:"Checking Token Ownership"}),"\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"Learn to check token ownership"})," starting with version ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1",children:"v1.1.1"}),". The ",(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})," modality must be set to ",(0,t.jsx)(e.code,{children:"Complete"})," as described ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"upgrading-to-version-111",children:"Upgrading to Version 1.1.1"}),"\n",(0,t.jsxs)(e.p,{children:["Upgrade to v1.1.1 using a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/tutorials/standard-migration-tutorial.md",children:"Standard NamedKey Convention"})," or a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/custom-migration-tutorial.md",children:"Custom NamedKey Convention"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",children:"Installing and Interacting with the Contract using the Rust Casper Client"}),"\n",(0,t.jsxs)(e.p,{children:["You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"test-suite-and-specification",children:"Test Suite and Specification"}),"\n",(0,t.jsxs)(e.p,{children:["The expected behavior of the NFT contract implementation is asserted by its test suite found in the ",(0,t.jsx)(e.code,{children:"tests"})," folder.\nThe test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors\nof the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite\nensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced.\nThe test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run\nby using the provided ",(0,t.jsx)(e.code,{children:"Makefile"})," and running the ",(0,t.jsx)(e.code,{children:"make test"})," command."]}),"\n",(0,t.jsx)(e.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Code"}),(0,t.jsx)(e.th,{children:"Error"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"1"}),(0,t.jsx)(e.td,{children:"InvalidAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"2"}),(0,t.jsx)(e.td,{children:"MissingInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"3"}),(0,t.jsx)(e.td,{children:"InvalidInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"4"}),(0,t.jsx)(e.td,{children:"UnexpectedKeyVariant"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"5"}),(0,t.jsx)(e.td,{children:"MissingTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"6"}),(0,t.jsx)(e.td,{children:"InvalidTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"7"}),(0,t.jsx)(e.td,{children:"FailedToGetArgBytes"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"8"}),(0,t.jsx)(e.td,{children:"FailedToCreateDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"9"}),(0,t.jsx)(e.td,{children:"MissingStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"10"}),(0,t.jsx)(e.td,{children:"InvalidStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"11"}),(0,t.jsx)(e.td,{children:"MissingOwnerUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"12"}),(0,t.jsx)(e.td,{children:"InvalidOwnersUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"13"}),(0,t.jsx)(e.td,{children:"FailedToAccessStorageDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"14"}),(0,t.jsx)(e.td,{children:"FailedToAccessOwnershipDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"15"}),(0,t.jsx)(e.td,{children:"DuplicateMinted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"16"}),(0,t.jsx)(e.td,{children:"FailedToConvertCLValue"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"17"}),(0,t.jsx)(e.td,{children:"MissingCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"18"}),(0,t.jsx)(e.td,{children:"InvalidCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"19"}),(0,t.jsx)(e.td,{children:"FailedToSerializeMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"20"}),(0,t.jsx)(e.td,{children:"MissingAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"21"}),(0,t.jsx)(e.td,{children:"MissingMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"22"}),(0,t.jsx)(e.td,{children:"InvalidMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"23"}),(0,t.jsx)(e.td,{children:"MissingCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"24"}),(0,t.jsx)(e.td,{children:"InvalidCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"25"}),(0,t.jsx)(e.td,{children:"MissingTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"26"}),(0,t.jsx)(e.td,{children:"InvalidTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"27"}),(0,t.jsx)(e.td,{children:"MissingTokenID"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"28"}),(0,t.jsx)(e.td,{children:"InvalidTokenIdentifier"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"29"}),(0,t.jsx)(e.td,{children:"MissingTokenOwners"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"30"}),(0,t.jsx)(e.td,{children:"MissingAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"31"}),(0,t.jsx)(e.td,{children:"InvalidAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"32"}),(0,t.jsx)(e.td,{children:"TokenSupplyDepleted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"33"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"34"}),(0,t.jsx)(e.td,{children:"TokenAlreadyBelongsToMinterFatal"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"35"}),(0,t.jsx)(e.td,{children:"FatalTokenIdDuplication"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"36"}),(0,t.jsx)(e.td,{children:"InvalidMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"37"}),(0,t.jsx)(e.td,{children:"MissingMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"38"}),(0,t.jsx)(e.td,{children:"InvalidMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"39"}),(0,t.jsx)(e.td,{children:"MissingInstallerKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"40"}),(0,t.jsx)(e.td,{children:"FailedToConvertToAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"41"}),(0,t.jsx)(e.td,{children:"InvalidBurner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"42"}),(0,t.jsx)(e.td,{children:"PreviouslyBurntToken"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"43"}),(0,t.jsx)(e.td,{children:"MissingAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"44"}),(0,t.jsx)(e.td,{children:"InvalidAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"45"}),(0,t.jsx)(e.td,{children:"MissingNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"46"}),(0,t.jsx)(e.td,{children:"InvalidNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"47"}),(0,t.jsx)(e.td,{children:"MissingTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"48"}),(0,t.jsx)(e.td,{children:"InvalidTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"49"}),(0,t.jsx)(e.td,{children:"MissingApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{children:"InvalidApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"51"}),(0,t.jsx)(e.td,{children:"MissingApprovedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"52"}),(0,t.jsx)(e.td,{children:"TokenAlreadyApproved"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"53"}),(0,t.jsx)(e.td,{children:"MissingApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"54"}),(0,t.jsx)(e.td,{children:"InvalidApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"55"}),(0,t.jsx)(e.td,{children:"MissingOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"56"}),(0,t.jsx)(e.td,{children:"InvalidOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"57"}),(0,t.jsx)(e.td,{children:"Phantom"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"58"}),(0,t.jsx)(e.td,{children:"ContractAlreadyInitialized"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"59"}),(0,t.jsx)(e.td,{children:"MintingIsPaused"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"60"}),(0,t.jsx)(e.td,{children:"FailureToParseAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"61"}),(0,t.jsx)(e.td,{children:"VacantValueInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"62"}),(0,t.jsx)(e.td,{children:"MissingOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"63"}),(0,t.jsx)(e.td,{children:"InvalidOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"64"}),(0,t.jsx)(e.td,{children:"InvalidTokenMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"65"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"66"}),(0,t.jsx)(e.td,{children:"InvalidAccountKeyInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"67"}),(0,t.jsx)(e.td,{children:"MissingJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"68"}),(0,t.jsx)(e.td,{children:"InvalidJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"69"}),(0,t.jsx)(e.td,{children:"InvalidKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"70"}),(0,t.jsx)(e.td,{children:"InvalidOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"71"}),(0,t.jsx)(e.td,{children:"MissingTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"72"}),(0,t.jsx)(e.td,{children:"InvalidTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"73"}),(0,t.jsx)(e.td,{children:"MissingNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"74"}),(0,t.jsx)(e.td,{children:"InvalidNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"75"}),(0,t.jsx)(e.td,{children:"MissingHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"76"}),(0,t.jsx)(e.td,{children:"InvalidHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"77"}),(0,t.jsx)(e.td,{children:"MissingWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"78"}),(0,t.jsx)(e.td,{children:"InvalidWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"79"}),(0,t.jsx)(e.td,{children:"MissingContractWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"80"}),(0,t.jsx)(e.td,{children:"InvalidContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"81"}),(0,t.jsx)(e.td,{children:"UnlistedContractHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"82"}),(0,t.jsx)(e.td,{children:"InvalidContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"83"}),(0,t.jsx)(e.td,{children:"EmptyContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"84"}),(0,t.jsx)(e.td,{children:"MissingReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"85"}),(0,t.jsx)(e.td,{children:"InvalidReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"86"}),(0,t.jsx)(e.td,{children:"InvalidJsonMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"87"}),(0,t.jsx)(e.td,{children:"InvalidJsonFormat"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"88"}),(0,t.jsx)(e.td,{children:"FailedToParseCep78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"89"}),(0,t.jsx)(e.td,{children:"FailedToParse721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"90"}),(0,t.jsx)(e.td,{children:"FailedToParseCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"91"}),(0,t.jsx)(e.td,{children:"InvalidCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"92"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"93"}),(0,t.jsx)(e.td,{children:"InvalidNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"94"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"95"}),(0,t.jsx)(e.td,{children:"InvalidCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"96"}),(0,t.jsx)(e.td,{children:"MissingNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"97"}),(0,t.jsx)(e.td,{children:"InvalidNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"98"}),(0,t.jsx)(e.td,{children:"MissingIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"99"}),(0,t.jsx)(e.td,{children:"InvalidIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"100"}),(0,t.jsx)(e.td,{children:"FailedToParseTokenId"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"101"}),(0,t.jsx)(e.td,{children:"MissingMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"102"}),(0,t.jsx)(e.td,{children:"InvalidMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"103"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"104"}),(0,t.jsx)(e.td,{children:"ForbiddenMetadataUpdate"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"105"}),(0,t.jsx)(e.td,{children:"MissingBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"106"}),(0,t.jsx)(e.td,{children:"InvalidBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"107"}),(0,t.jsx)(e.td,{children:"MissingHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"108"}),(0,t.jsx)(e.td,{children:"InvalidHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"109"}),(0,t.jsx)(e.td,{children:"MissingIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"110"}),(0,t.jsx)(e.td,{children:"InvalidIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"111"}),(0,t.jsx)(e.td,{children:"MissingPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"112"}),(0,t.jsx)(e.td,{children:"InvalidPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"113"}),(0,t.jsx)(e.td,{children:"MissingPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"114"}),(0,t.jsx)(e.td,{children:"InvalidPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"115"}),(0,t.jsx)(e.td,{children:"InvalidPageNumber"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"116"}),(0,t.jsx)(e.td,{children:"InvalidPageIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"117"}),(0,t.jsx)(e.td,{children:"MissingUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"118"}),(0,t.jsx)(e.td,{children:"InvalidUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"119"}),(0,t.jsx)(e.td,{children:"MissingPackageHashForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"120"}),(0,t.jsx)(e.td,{children:"MissingPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"121"}),(0,t.jsx)(e.td,{children:"InvalidPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"122"}),(0,t.jsx)(e.td,{children:"CannotUpgradeWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"123"}),(0,t.jsx)(e.td,{children:"CannotInstallWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"124"}),(0,t.jsx)(e.td,{children:"MissingMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"125"}),(0,t.jsx)(e.td,{children:"InvalidMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"126"}),(0,t.jsx)(e.td,{children:"ContractAlreadyMigrated"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"127"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInMint"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"128"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInTransfer"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"129"}),(0,t.jsx)(e.td,{children:"MissingReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"130"}),(0,t.jsx)(e.td,{children:"InvalidReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"131"}),(0,t.jsx)(e.td,{children:"MissingPage"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"132"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerFromMigration"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"133"}),(0,t.jsx)(e.td,{children:"ExceededMaxTotalSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"134"}),(0,t.jsx)(e.td,{children:"MissingCep78PackageHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"135"}),(0,t.jsx)(e.td,{children:"InvalidCep78InvalidHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"136"}),(0,t.jsx)(e.td,{children:"InvalidPackageHashName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"137"}),(0,t.jsx)(e.td,{children:"InvalidAccessKeyName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"138"}),(0,t.jsx)(e.td,{children:"InvalidCheckForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"139"}),(0,t.jsx)(e.td,{children:"InvalidNamedKeyConvention"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"140"}),(0,t.jsx)(e.td,{children:"OwnerReverseLookupModeNotTransferable"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"141"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalRequiredMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"142"}),(0,t.jsx)(e.td,{children:"InvalidOptionalMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"143"}),(0,t.jsx)(e.td,{children:"MissingOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"144"}),(0,t.jsx)(e.td,{children:"InvalidOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"145"}),(0,t.jsx)(e.td,{children:"MissingAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"146"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"147"}),(0,t.jsx)(e.td,{children:"InvalidRequirement"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"148"}),(0,t.jsx)(e.td,{children:"MissingEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"149"}),(0,t.jsx)(e.td,{children:"InvalidEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"150"}),(0,t.jsx)(e.td,{children:"CannotUpgradeToMoreSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"151"}),(0,t.jsx)(e.td,{children:"MissingOperatorDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"152"}),(0,t.jsx)(e.td,{children:"MissingApprovedDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"153"}),(0,t.jsx)(e.td,{children:"MissingSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"154"}),(0,t.jsx)(e.td,{children:"InvalidSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"155"}),(0,t.jsx)(e.td,{children:"MissingOwnerTokenIdentifierKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"156"}),(0,t.jsx)(e.td,{children:"InvalidTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"157"}),(0,t.jsx)(e.td,{children:"MissingTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"158"}),(0,t.jsx)(e.td,{children:"TransferFilterContractNeedsTransferableMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"159"}),(0,t.jsx)(e.td,{children:"TransferFilterContractDenied"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"160"}),(0,t.jsx)(e.td,{children:"MissingACLWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"161"}),(0,t.jsx)(e.td,{children:"InvalidACLWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"162"}),(0,t.jsx)(e.td,{children:"EmptyACLWhitelist"})]})]})]})]})}function o(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>r,x:()=>l});var t=s(96540);const i={},d=t.createContext(i);function r(n){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function l(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(i):n.components||i:r(n.components),t.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/5d4e9672.604f7974.js b/assets/js/5d4e9672.604f7974.js new file mode 100644 index 000000000..b5b9901c6 --- /dev/null +++ b/assets/js/5d4e9672.604f7974.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65059],{41788:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>h});var t=s(74848),i=s(28453);const d={title:"Introduction",slug:"/resources/tokens/cep78/introduction"},r="CEP-78 Enhanced NFT Standard Introduction",l={id:"resources/tokens/cep78/introduction",title:"Introduction",description:"Usage",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/introduction.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/introduction",permalink:"/1.5.X/resources/tokens/cep78/introduction",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/resources/tokens/cep78/introduction"},sidebar:"resources",previous:{title:"Testing Guide",permalink:"/1.5.X/resources/tokens/cep18/tests"},next:{title:"CEP-78 Modalities",permalink:"/1.5.X/resources/tokens/cep78/modalities"}},c={},h=[{value:"Usage",id:"usage",level:2},{value:"Building the Contract",id:"building-the-contract",level:3},{value:"Required Runtime Arguments",id:"required-runtime-arguments",level:3},{value:"Example deploy",id:"example-deploy",level:4},{value:"Utility Session Code",id:"utility-session-code",level:3},{value:"Checking Token Ownership",id:"checking-token-ownership",level:3},{value:"Upgrading to Version 1.1.1",id:"upgrading-to-version-111",level:3},{value:"Installing and Interacting with the Contract using the Rust Casper Client",id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",level:2},{value:"Test Suite and Specification",id:"test-suite-and-specification",level:2},{value:"Error Codes",id:"error-codes",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"cep-78-enhanced-nft-standard-introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),"\n",(0,t.jsx)(e.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(e.h3,{id:"building-the-contract",children:"Building the Contract"}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"main.rs"})," file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command from the Makefile provided."]}),"\n",(0,t.jsxs)(e.p,{children:["The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command provided in the Makefile. Please note, however, that you must install ",(0,t.jsx)(e.code,{children:"wasm-strip"})," to build the contract."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"call"})," method will install the contract with the necessary entrypoints and call the ",(0,t.jsx)(e.code,{children:"init()"})," entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation Tutorial"})," provides a step-by-step workflow."]}),"\n",(0,t.jsx)(e.h3,{id:"required-runtime-arguments",children:"Required Runtime Arguments"}),"\n",(0,t.jsxs)(e.p,{children:["The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities",children:"Modalities"})," documentation."]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_name":'})," The name of the NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_symbol"'}),": The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"total_token_supply"'}),": The total number of NFTs that a specific instance of a contract will mint passed in as a ",(0,t.jsx)(e.code,{children:"U64"})," value. This parameter is required."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"ownership_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#ownership",children:(0,t.jsx)(e.code,{children:"OwnershipMode"})})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_kind"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#nftkind",children:(0,t.jsx)(e.code,{children:"NFTKind"})})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"json_schema"'}),": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required if the metadata kind is set to ",(0,t.jsx)(e.code,{children:"CustomValidated(3)"})," and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_metadata_kind"'}),": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"identifier_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#nftidentifiermode",children:(0,t.jsx)(e.code,{children:"NFTIdentifierMode"})})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"metadata_mutability"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#metadata-mutability",children:(0,t.jsx)(e.code,{children:"MetadataMutability"})})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The following are the optional parameters that can be passed in at the time of installation."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"minting_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#minting",children:(0,t.jsx)(e.code,{children:"MintingMode"})})," modality that dictates the access to the ",(0,t.jsx)(e.code,{children:"mint()"})," entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"allow_minting"'}),": The ",(0,t.jsx)(e.code,{children:'"allow_minting"'})," flag allows the installer of the contract to pause the minting of new NFTs. The ",(0,t.jsx)(e.code,{children:"allow_minting"})," is a boolean toggle that allows minting when ",(0,t.jsx)(e.code,{children:"true"}),". If not provided at install the toggle will default to ",(0,t.jsx)(e.code,{children:"true"}),". This value can be changed by the installer by calling the ",(0,t.jsx)(e.code,{children:"set_variables()"})," entrypoint."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"whitelist_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#whitelistmode",children:(0,t.jsx)(e.code,{children:"WhitelistMode"})})," modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"holder_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#nftholdermode",children:(0,t.jsx)(e.code,{children:"NFTHolderMode"})})," modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either ",(0,t.jsx)(e.code,{children:"Accounts"})," or ",(0,t.jsx)(e.code,{children:"Contracts"})," to hold NFTs. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"contract_whitelist"'}),": The contract whitelist is a list of contract hashes that specifies which contracts can call the ",(0,t.jsx)(e.code,{children:"mint()"})," entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the ",(0,t.jsx)(e.code,{children:"set_variables"})," post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"burn_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#burnmode",children:(0,t.jsx)(e.code,{children:"BurnMode"})})," modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"owner_reverse_lookup_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#ownerreverselookupmode",children:(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})})," modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"events_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/modalities#eventsmode",children:(0,t.jsx)(e.code,{children:"EventsMode"})})," modality selects the event schema used to record any changes that occur to tokens issued by the contract instance."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"additional_required_metdata"'}),": An additional metadata schema that must be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"optional_metdata"'}),": An optional metadata schema that may be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.h4,{id:"example-deploy",children:"Example deploy"}),"\n",(0,t.jsxs)(e.p,{children:["The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"here"}),"."]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:'casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'enhanced-nft-1\'" \\\n--session-arg "collection_symbol:string=\'ENFT-1\'" \\\n--session-arg "total_token_supply:u64=\'10\'" \\\n--session-arg "ownership_mode:u8=\'0\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "allow_minting:bool=\'true\'" \\\n--session-arg "owner_reverse_lookup_mode:u8=\'0\'" \\\n--session-arg "nft_metadata_kind:u8=\'2\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(e.h3,{id:"utility-session-code",children:"Utility Session Code"}),"\n",(0,t.jsxs)(e.p,{children:["Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary.\nIn order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that\nusers and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the ",(0,t.jsx)(e.code,{children:"client"}),"\nfolder within the project folder."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint name"}),(0,t.jsx)(e.th,{children:"Session code"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"mint"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/mint_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"balance_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/balance_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"get_approved'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/get_approved_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"owner_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/owner_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"transfer"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/transfer_session"})})]})]})]}),"\n",(0,t.jsx)(e.h3,{id:"checking-token-ownership",children:"Checking Token Ownership"}),"\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"Learn to check token ownership"})," starting with version ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1",children:"v1.1.1"}),". The ",(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})," modality must be set to ",(0,t.jsx)(e.code,{children:"Complete"})," as described ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"upgrading-to-version-111",children:"Upgrading to Version 1.1.1"}),"\n",(0,t.jsxs)(e.p,{children:["Upgrade to v1.1.1 using a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/tutorials/standard-migration-tutorial.md",children:"Standard NamedKey Convention"})," or a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/custom-migration-tutorial.md",children:"Custom NamedKey Convention"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",children:"Installing and Interacting with the Contract using the Rust Casper Client"}),"\n",(0,t.jsxs)(e.p,{children:["You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"test-suite-and-specification",children:"Test Suite and Specification"}),"\n",(0,t.jsxs)(e.p,{children:["The expected behavior of the NFT contract implementation is asserted by its test suite found in the ",(0,t.jsx)(e.code,{children:"tests"})," folder.\nThe test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors\nof the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite\nensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced.\nThe test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run\nby using the provided ",(0,t.jsx)(e.code,{children:"Makefile"})," and running the ",(0,t.jsx)(e.code,{children:"make test"})," command."]}),"\n",(0,t.jsx)(e.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Code"}),(0,t.jsx)(e.th,{children:"Error"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"1"}),(0,t.jsx)(e.td,{children:"InvalidAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"2"}),(0,t.jsx)(e.td,{children:"MissingInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"3"}),(0,t.jsx)(e.td,{children:"InvalidInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"4"}),(0,t.jsx)(e.td,{children:"UnexpectedKeyVariant"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"5"}),(0,t.jsx)(e.td,{children:"MissingTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"6"}),(0,t.jsx)(e.td,{children:"InvalidTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"7"}),(0,t.jsx)(e.td,{children:"FailedToGetArgBytes"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"8"}),(0,t.jsx)(e.td,{children:"FailedToCreateDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"9"}),(0,t.jsx)(e.td,{children:"MissingStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"10"}),(0,t.jsx)(e.td,{children:"InvalidStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"11"}),(0,t.jsx)(e.td,{children:"MissingOwnerUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"12"}),(0,t.jsx)(e.td,{children:"InvalidOwnersUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"13"}),(0,t.jsx)(e.td,{children:"FailedToAccessStorageDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"14"}),(0,t.jsx)(e.td,{children:"FailedToAccessOwnershipDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"15"}),(0,t.jsx)(e.td,{children:"DuplicateMinted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"16"}),(0,t.jsx)(e.td,{children:"FailedToConvertCLValue"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"17"}),(0,t.jsx)(e.td,{children:"MissingCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"18"}),(0,t.jsx)(e.td,{children:"InvalidCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"19"}),(0,t.jsx)(e.td,{children:"FailedToSerializeMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"20"}),(0,t.jsx)(e.td,{children:"MissingAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"21"}),(0,t.jsx)(e.td,{children:"MissingMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"22"}),(0,t.jsx)(e.td,{children:"InvalidMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"23"}),(0,t.jsx)(e.td,{children:"MissingCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"24"}),(0,t.jsx)(e.td,{children:"InvalidCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"25"}),(0,t.jsx)(e.td,{children:"MissingTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"26"}),(0,t.jsx)(e.td,{children:"InvalidTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"27"}),(0,t.jsx)(e.td,{children:"MissingTokenID"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"28"}),(0,t.jsx)(e.td,{children:"InvalidTokenIdentifier"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"29"}),(0,t.jsx)(e.td,{children:"MissingTokenOwners"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"30"}),(0,t.jsx)(e.td,{children:"MissingAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"31"}),(0,t.jsx)(e.td,{children:"InvalidAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"32"}),(0,t.jsx)(e.td,{children:"TokenSupplyDepleted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"33"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"34"}),(0,t.jsx)(e.td,{children:"TokenAlreadyBelongsToMinterFatal"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"35"}),(0,t.jsx)(e.td,{children:"FatalTokenIdDuplication"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"36"}),(0,t.jsx)(e.td,{children:"InvalidMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"37"}),(0,t.jsx)(e.td,{children:"MissingMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"38"}),(0,t.jsx)(e.td,{children:"InvalidMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"39"}),(0,t.jsx)(e.td,{children:"MissingInstallerKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"40"}),(0,t.jsx)(e.td,{children:"FailedToConvertToAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"41"}),(0,t.jsx)(e.td,{children:"InvalidBurner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"42"}),(0,t.jsx)(e.td,{children:"PreviouslyBurntToken"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"43"}),(0,t.jsx)(e.td,{children:"MissingAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"44"}),(0,t.jsx)(e.td,{children:"InvalidAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"45"}),(0,t.jsx)(e.td,{children:"MissingNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"46"}),(0,t.jsx)(e.td,{children:"InvalidNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"47"}),(0,t.jsx)(e.td,{children:"MissingTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"48"}),(0,t.jsx)(e.td,{children:"InvalidTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"49"}),(0,t.jsx)(e.td,{children:"MissingApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{children:"InvalidApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"51"}),(0,t.jsx)(e.td,{children:"MissingApprovedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"52"}),(0,t.jsx)(e.td,{children:"TokenAlreadyApproved"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"53"}),(0,t.jsx)(e.td,{children:"MissingApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"54"}),(0,t.jsx)(e.td,{children:"InvalidApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"55"}),(0,t.jsx)(e.td,{children:"MissingOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"56"}),(0,t.jsx)(e.td,{children:"InvalidOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"57"}),(0,t.jsx)(e.td,{children:"Phantom"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"58"}),(0,t.jsx)(e.td,{children:"ContractAlreadyInitialized"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"59"}),(0,t.jsx)(e.td,{children:"MintingIsPaused"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"60"}),(0,t.jsx)(e.td,{children:"FailureToParseAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"61"}),(0,t.jsx)(e.td,{children:"VacantValueInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"62"}),(0,t.jsx)(e.td,{children:"MissingOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"63"}),(0,t.jsx)(e.td,{children:"InvalidOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"64"}),(0,t.jsx)(e.td,{children:"InvalidTokenMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"65"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"66"}),(0,t.jsx)(e.td,{children:"InvalidAccountKeyInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"67"}),(0,t.jsx)(e.td,{children:"MissingJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"68"}),(0,t.jsx)(e.td,{children:"InvalidJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"69"}),(0,t.jsx)(e.td,{children:"InvalidKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"70"}),(0,t.jsx)(e.td,{children:"InvalidOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"71"}),(0,t.jsx)(e.td,{children:"MissingTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"72"}),(0,t.jsx)(e.td,{children:"InvalidTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"73"}),(0,t.jsx)(e.td,{children:"MissingNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"74"}),(0,t.jsx)(e.td,{children:"InvalidNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"75"}),(0,t.jsx)(e.td,{children:"MissingHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"76"}),(0,t.jsx)(e.td,{children:"InvalidHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"77"}),(0,t.jsx)(e.td,{children:"MissingWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"78"}),(0,t.jsx)(e.td,{children:"InvalidWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"79"}),(0,t.jsx)(e.td,{children:"MissingContractWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"80"}),(0,t.jsx)(e.td,{children:"InvalidContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"81"}),(0,t.jsx)(e.td,{children:"UnlistedContractHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"82"}),(0,t.jsx)(e.td,{children:"InvalidContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"83"}),(0,t.jsx)(e.td,{children:"EmptyContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"84"}),(0,t.jsx)(e.td,{children:"MissingReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"85"}),(0,t.jsx)(e.td,{children:"InvalidReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"86"}),(0,t.jsx)(e.td,{children:"InvalidJsonMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"87"}),(0,t.jsx)(e.td,{children:"InvalidJsonFormat"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"88"}),(0,t.jsx)(e.td,{children:"FailedToParseCep78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"89"}),(0,t.jsx)(e.td,{children:"FailedToParse721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"90"}),(0,t.jsx)(e.td,{children:"FailedToParseCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"91"}),(0,t.jsx)(e.td,{children:"InvalidCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"92"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"93"}),(0,t.jsx)(e.td,{children:"InvalidNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"94"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"95"}),(0,t.jsx)(e.td,{children:"InvalidCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"96"}),(0,t.jsx)(e.td,{children:"MissingNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"97"}),(0,t.jsx)(e.td,{children:"InvalidNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"98"}),(0,t.jsx)(e.td,{children:"MissingIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"99"}),(0,t.jsx)(e.td,{children:"InvalidIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"100"}),(0,t.jsx)(e.td,{children:"FailedToParseTokenId"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"101"}),(0,t.jsx)(e.td,{children:"MissingMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"102"}),(0,t.jsx)(e.td,{children:"InvalidMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"103"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"104"}),(0,t.jsx)(e.td,{children:"ForbiddenMetadataUpdate"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"105"}),(0,t.jsx)(e.td,{children:"MissingBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"106"}),(0,t.jsx)(e.td,{children:"InvalidBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"107"}),(0,t.jsx)(e.td,{children:"MissingHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"108"}),(0,t.jsx)(e.td,{children:"InvalidHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"109"}),(0,t.jsx)(e.td,{children:"MissingIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"110"}),(0,t.jsx)(e.td,{children:"InvalidIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"111"}),(0,t.jsx)(e.td,{children:"MissingPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"112"}),(0,t.jsx)(e.td,{children:"InvalidPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"113"}),(0,t.jsx)(e.td,{children:"MissingPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"114"}),(0,t.jsx)(e.td,{children:"InvalidPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"115"}),(0,t.jsx)(e.td,{children:"InvalidPageNumber"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"116"}),(0,t.jsx)(e.td,{children:"InvalidPageIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"117"}),(0,t.jsx)(e.td,{children:"MissingUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"118"}),(0,t.jsx)(e.td,{children:"InvalidUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"119"}),(0,t.jsx)(e.td,{children:"MissingPackageHashForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"120"}),(0,t.jsx)(e.td,{children:"MissingPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"121"}),(0,t.jsx)(e.td,{children:"InvalidPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"122"}),(0,t.jsx)(e.td,{children:"CannotUpgradeWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"123"}),(0,t.jsx)(e.td,{children:"CannotInstallWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"124"}),(0,t.jsx)(e.td,{children:"MissingMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"125"}),(0,t.jsx)(e.td,{children:"InvalidMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"126"}),(0,t.jsx)(e.td,{children:"ContractAlreadyMigrated"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"127"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInMint"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"128"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInTransfer"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"129"}),(0,t.jsx)(e.td,{children:"MissingReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"130"}),(0,t.jsx)(e.td,{children:"InvalidReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"131"}),(0,t.jsx)(e.td,{children:"MissingPage"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"132"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerFromMigration"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"133"}),(0,t.jsx)(e.td,{children:"ExceededMaxTotalSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"134"}),(0,t.jsx)(e.td,{children:"MissingCep78PackageHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"135"}),(0,t.jsx)(e.td,{children:"InvalidCep78InvalidHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"136"}),(0,t.jsx)(e.td,{children:"InvalidPackageHashName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"137"}),(0,t.jsx)(e.td,{children:"InvalidAccessKeyName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"138"}),(0,t.jsx)(e.td,{children:"InvalidCheckForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"139"}),(0,t.jsx)(e.td,{children:"InvalidNamedKeyConvention"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"140"}),(0,t.jsx)(e.td,{children:"OwnerReverseLookupModeNotTransferable"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"141"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalRequiredMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"142"}),(0,t.jsx)(e.td,{children:"InvalidOptionalMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"143"}),(0,t.jsx)(e.td,{children:"MissingOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"144"}),(0,t.jsx)(e.td,{children:"InvalidOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"145"}),(0,t.jsx)(e.td,{children:"MissingAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"146"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"147"}),(0,t.jsx)(e.td,{children:"InvalidRequirement"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"148"}),(0,t.jsx)(e.td,{children:"MissingEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"149"}),(0,t.jsx)(e.td,{children:"InvalidEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"150"}),(0,t.jsx)(e.td,{children:"CannotUpgradeToMoreSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"151"}),(0,t.jsx)(e.td,{children:"MissingOperatorDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"152"}),(0,t.jsx)(e.td,{children:"MissingApprovedDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"153"}),(0,t.jsx)(e.td,{children:"MissingSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"154"}),(0,t.jsx)(e.td,{children:"InvalidSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"155"}),(0,t.jsx)(e.td,{children:"MissingOwnerTokenIdentifierKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"156"}),(0,t.jsx)(e.td,{children:"InvalidTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"157"}),(0,t.jsx)(e.td,{children:"MissingTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"158"}),(0,t.jsx)(e.td,{children:"TransferFilterContractNeedsTransferableMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"159"}),(0,t.jsx)(e.td,{children:"TransferFilterContractDenied"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"160"}),(0,t.jsx)(e.td,{children:"MissingACLWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"161"}),(0,t.jsx)(e.td,{children:"InvalidACLWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"162"}),(0,t.jsx)(e.td,{children:"EmptyACLWhitelist"})]})]})]})]})}function o(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>r,x:()=>l});var t=s(96540);const i={},d=t.createContext(i);function r(n){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function l(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(i):n.components||i:r(n.components),t.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/5db8b942.1835e546.js b/assets/js/5db8b942.1835e546.js new file mode 100644 index 000000000..6792a3f1e --- /dev/null +++ b/assets/js/5db8b942.1835e546.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[14235],{75995:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>i});var c=n(74848),t=n(28453);const r={},a="G",o={id:"concepts/glossary/G",title:"G",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/G.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/G",permalink:"/2.0.0/concepts/glossary/G",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"F",permalink:"/2.0.0/concepts/glossary/F"},next:{title:"H",permalink:"/2.0.0/concepts/glossary/H"}},l={},i=[{value:"Gas",id:"gas",level:2},{value:"Gas cost",id:"gas-cost",level:2},{value:"Gas price",id:"gas-price",level:2},{value:"Genesis",id:"genesis",level:2},{value:"Groups",id:"groups",level:2},{value:"Global state",id:"global-state",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"g",children:"G"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"gas",children:"Gas"}),"\n",(0,c.jsx)(s.p,{children:"Gas is a conceptual measure of resources used when executing transactions on the blockchain."}),"\n",(0,c.jsx)(s.h2,{id:"gas-cost",children:"Gas cost"}),"\n",(0,c.jsx)(s.p,{children:"Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,c.jsx)(s.h2,{id:"gas-price",children:"Gas price"}),"\n",(0,c.jsxs)(s.p,{children:["Multiplier applied to gas cost. See ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"genesis",children:"Genesis"}),"\n",(0,c.jsx)(s.p,{children:"The state of the virtual machine at the beginning of the blockchain."}),"\n",(0,c.jsx)(s.h2,{id:"groups",children:"Groups"}),"\n",(0,c.jsxs)(s.p,{children:["The ",(0,c.jsx)(s.em,{children:"user groups"})," feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:"]}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:"User groups associate a set of URefs with a label."}),"\n",(0,c.jsx)(s.li,{children:"The entry points on a contract can accept a list of labels"}),"\n",(0,c.jsx)(s.li,{children:"The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution."}),"\n"]}),"\n",(0,c.jsx)(s.h2,{id:"global-state",children:"Global state"}),"\n",(0,c.jsxs)(s.p,{children:["When thinking of a ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#blockchain",children:"blockchain"})," as a decentralized computer, the global state is its memory state."]}),"\n",(0,c.jsxs)(s.p,{children:["When thinking of a ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#blockchain",children:"blockchain"})," as a shared database, the global state is the snapshot of the database's data."]}),"\n",(0,c.jsxs)(s.p,{children:["Technically, a ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"})," is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs)."]}),"\n",(0,c.jsxs)(s.p,{children:["For every ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#block",children:"block"})," B in the ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#blockchain",children:"blockchain"}),", one can compute the ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"})," achieved by executing all ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transactions"})," in this block and its ancestors. The ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R#root-hash",children:"root hash"})," identifying this state is stored in every executed block."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var c=n(96540);const t={},r=c.createContext(t);function a(e){const s=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e5b712e.6e7d89b9.js b/assets/js/5e5b712e.6e7d89b9.js new file mode 100644 index 000000000..4018fed02 --- /dev/null +++ b/assets/js/5e5b712e.6e7d89b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25235],{83779:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>t,toc:()=>h});var n=r(74848),o=r(28453);const c={},a="O",t={id:"concepts/glossary/O",title:"O",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/O.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/O",permalink:"/2.0.0/concepts/glossary/O",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"N",permalink:"/2.0.0/concepts/glossary/N"},next:{title:"P",permalink:"/2.0.0/concepts/glossary/P"}},l={},h=[{value:"Operator",id:"operator",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"o",children:"O"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"operator",children:"Operator"}),"\n",(0,n.jsx)(s.p,{children:"Anyone running a node is an\xa0operator."}),"\n",(0,n.jsx)(s.p,{children:"An operator that has staked a bid but does not currently have a validator slot is a\xa0*staked operator*."}),"\n",(0,n.jsxs)(s.p,{children:["An operator whose bid has won a validator slot in the auction for a specific era is a\xa0",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validator"}),"\xa0in that era."]}),"\n",(0,n.jsxs)(s.p,{children:["It is common for a ",(0,n.jsx)(s.em,{children:"staked operator"})," to win an auction slot for many eras in a row and thus be a validator for a range of eras."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>a,x:()=>t});var n=r(96540);const o={},c=n.createContext(o);function a(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e9306ee.35f8dd24.js b/assets/js/5e9306ee.35f8dd24.js deleted file mode 100644 index 64ec5a21c..000000000 --- a/assets/js/5e9306ee.35f8dd24.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9029],{70580:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var a=s(74848),r=s(28453);const t={title:"Verifying a Transfer"},d="Verifying a Transfer",c={id:"developers/cli/transfers/verify-transfer",title:"Verifying a Transfer",description:"Prerequisites",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/verify-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/verify-transfer",permalink:"/developers/cli/transfers/verify-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Verifying a Transfer"},sidebar:"developers",previous:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/developers/cli/transfers/multisig-deploy-transfer"},next:{title:"Delegating Tokens",permalink:"/developers/cli/delegate"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Query the State Root Hash",id:"query-the-state-root-hash",level:2},{value:"Query the Transfer Details",id:"query-transfer-details",level:2},{value:"Query the Account State",id:"query-account-state",level:2},{value:"Query the Purse Balance",id:"get-purse-balance",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"verifying-a-transfer",children:"Verifying a Transfer"})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before verifying a transfer, make sure you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Initiated a ",(0,a.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Direct Transfer"})," or ",(0,a.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Multi-sig Deploy Transfer"})]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"deploy_hash"})," of the transfer you want to verify"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"public key"})," of the source and target accounts"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"query-the-state-root-hash",children:"Query the State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io \n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Sample output of the get-state-root-hash command"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 6458079936180872466,\n "result": {\n "api_version": "1.5.3",\n "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"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."})}),"\n",(0,a.jsx)(n.h2,{id:"query-transfer-details",children:"Query the Transfer Details"}),"\n",(0,a.jsxs)(n.p,{children:["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 ",(0,a.jsx)(n.code,{children:"transfer-address"})," identifies each transfer. The ",(0,a.jsx)(n.code,{children:"transfer-address"})," consists of a formatted string with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:s(54906).A+"",width:"1558",height:"1228"})}),"\n",(0,a.jsxs)(n.p,{children:["First, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,a.jsx)(n.em,{children:"deploy_hash"})," to identify the corresponding transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."execution_results"."result"."Success"."transfers"'})," - List of transfers contained in a successful deploy"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After obtaining the transfer identifier, query the transfer details."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [TRANSFER_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - The hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"key"})," - The base key for the query. This must be a properly formatted transfer address with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix, i.e., ",(0,a.jsx)(n.code,{children:"transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 3 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",\n "path": []\n },\n "id": 3\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Transfer": {\n "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n },\n "merkle_proof": "[42526 hex chars]"\n },\n "id": 3\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"query-account-state",children:"Query the Account State"}),"\n",(0,a.jsxs)(n.p,{children:["Next, query for information about the ",(0,a.jsx)(n.em,{children:"Source"})," account, using the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," of the block containing the transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [SOURCE_PUBLIC_KEY]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the network state"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Source Account Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 4 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [...],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[31406 hex chars]"\n },\n "id": 4\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Query:"})}),"\n",(0,a.jsxs)(n.p,{children:["Repeat the same step to query information about the ",(0,a.jsx)(n.em,{children:"Target"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 5 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 5\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [...],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [...],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32060 hex chars]"\n },\n "id": 5\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"get-purse-balance",children:"Query the Purse Balance"}),"\n",(0,a.jsxs)(n.p,{children:["All accounts on a Casper network have a purse associated with the Casper system mint, which is the ",(0,a.jsx)(n.em,{children:"main purse"}),". The balance associated with a given purse is recorded in global state, and the value can be queried using the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Verify the source purse balance using the ",(0,a.jsx)(n.code,{children:"query-balance"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [SOURCE_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Query Source Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 6 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "1109111876194"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Similarly, query the balance of the target purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-balance \\\n--id 7 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [TARGET_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 7 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"\n }\n },\n "id": 7\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "46200000000"\n },\n "id": 7\n}\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},54906:(e,n,s)=>{s.d(n,{A:()=>a});const a=s.p+"assets/images/transfer-hash-example-b8695f1d7d28b36e8e8cf67b26df6945.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var a=s(96540);const r={},t=a.createContext(r);function d(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5e9306ee.39afcc18.js b/assets/js/5e9306ee.39afcc18.js new file mode 100644 index 000000000..7b5989b4f --- /dev/null +++ b/assets/js/5e9306ee.39afcc18.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59029],{70580:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var a=s(74848),r=s(28453);const t={title:"Verifying a Transfer"},d="Verifying a Transfer",c={id:"developers/cli/transfers/verify-transfer",title:"Verifying a Transfer",description:"Prerequisites",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/verify-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/verify-transfer",permalink:"/1.5.X/developers/cli/transfers/verify-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Verifying a Transfer"},sidebar:"developers",previous:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer"},next:{title:"Delegating Tokens",permalink:"/1.5.X/developers/cli/delegate"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Query the State Root Hash",id:"query-the-state-root-hash",level:2},{value:"Query the Transfer Details",id:"query-transfer-details",level:2},{value:"Query the Account State",id:"query-account-state",level:2},{value:"Query the Purse Balance",id:"get-purse-balance",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"verifying-a-transfer",children:"Verifying a Transfer"})}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Before verifying a transfer, make sure you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Initiated a ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/direct-token-transfer",children:"Direct Transfer"})," or ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer",children:"Multi-sig Deploy Transfer"})]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"deploy_hash"})," of the transfer you want to verify"]}),"\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.em,{children:"public key"})," of the source and target accounts"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"query-the-state-root-hash",children:"Query the State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io \n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Sample output of the get-state-root-hash command"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 6458079936180872466,\n "result": {\n "api_version": "1.5.3",\n "state_root_hash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"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."})}),"\n",(0,a.jsx)(n.h2,{id:"query-transfer-details",children:"Query the Transfer Details"}),"\n",(0,a.jsxs)(n.p,{children:["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 ",(0,a.jsx)(n.code,{children:"transfer-address"})," identifies each transfer. The ",(0,a.jsx)(n.code,{children:"transfer-address"})," consists of a formatted string with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{src:s(59228).A+"",width:"1558",height:"1228"})}),"\n",(0,a.jsxs)(n.p,{children:["First, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,a.jsx)(n.em,{children:"deploy_hash"})," to identify the corresponding transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."execution_results"."result"."Success"."transfers"'})," - List of transfers contained in a successful deploy"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"After obtaining the transfer identifier, query the transfer details."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [TRANSFER_HASH]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - The hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"key"})," - The base key for the query. This must be a properly formatted transfer address with a ",(0,a.jsx)(n.code,{children:"transfer-"})," prefix, i.e., ",(0,a.jsx)(n.code,{children:"transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb"})]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 3 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "transfer-ab3e11fd612ccf9ddf5ddb3e5c0b3d3b5e5c0921fd1b45e8c657a63f01d6adcb",\n "path": []\n },\n "id": 3\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Transfer": {\n "deploy_hash": "4eedbb5cf4a571748cf7ae9c2f17777364a01f80f79f3633a0cec32b7e8cf2e3",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n },\n "merkle_proof": "[42526 hex chars]"\n },\n "id": 3\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"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."}),"\n",(0,a.jsx)(n.h2,{id:"query-account-state",children:"Query the Account State"}),"\n",(0,a.jsxs)(n.p,{children:["Next, query for information about the ",(0,a.jsx)(n.em,{children:"Source"})," account, using the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," of the block containing the transfer:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--id [ID] \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [SOURCE_PUBLIC_KEY]\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the network state"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Source Account Query:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 4 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [...],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[31406 hex chars]"\n },\n "id": 4\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Query:"})}),"\n",(0,a.jsxs)(n.p,{children:["Repeat the same step to query information about the ",(0,a.jsx)(n.em,{children:"Target"})," account:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n--id 5 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 5\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [...],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [...],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32060 hex chars]"\n },\n "id": 5\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"get-purse-balance",children:"Query the Purse Balance"}),"\n",(0,a.jsxs)(n.p,{children:["All accounts on a Casper network have a purse associated with the Casper system mint, which is the ",(0,a.jsx)(n.em,{children:"main purse"}),". The balance associated with a given purse is recorded in global state, and the value can be queried using the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Verify the source purse balance using the ",(0,a.jsx)(n.code,{children:"query-balance"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [SOURCE_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Query Source Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 6 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "1109111876194"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Similarly, query the balance of the target purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-balance \\\n--id 7 \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HAHS] \\\n--purse-identifier [TARGET_PUBLIC_KEY_HEX] \n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Target Account Example:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v --id 7 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1 \\\n--purse-identifier account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"\n },\n "purse_identifier": {\n "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"\n }\n },\n "id": 7\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "balance": "46200000000"\n },\n "id": 7\n}\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},59228:(e,n,s)=>{s.d(n,{A:()=>a});const a=s.p+"assets/images/transfer-hash-example-b8695f1d7d28b36e8e8cf67b26df6945.png"},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var a=s(96540);const r={},t=a.createContext(r);function d(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5eb62c95.f9ba076c.js b/assets/js/5eb62c95.f9ba076c.js new file mode 100644 index 000000000..d35e6303c --- /dev/null +++ b/assets/js/5eb62c95.f9ba076c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35774],{47294:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>h,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const t={},o="H",a={id:"concepts/glossary/H",title:"H",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/H.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/H",permalink:"/2.0.0/concepts/glossary/H",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"G",permalink:"/2.0.0/concepts/glossary/G"},next:{title:"I",permalink:"/2.0.0/concepts/glossary/I"}},h={},l=[{value:"Hash",id:"hash",level:2},{value:"Highway",id:"highway",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"h",children:"H"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"hash",children:"Hash"}),"\n",(0,r.jsxs)(s.p,{children:["A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#blake2b",children:"blake2b"})," function."]}),"\n",(0,r.jsx)(s.h2,{id:"highway",children:"Highway"}),"\n",(0,r.jsxs)(s.p,{children:["A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is ",(0,r.jsx)(s.em,{children:"finalized"}),". The full paper is found in GitHub: ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/highway",children:"https://github.com/casper-network/highway"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const c={},t=r.createContext(c);function o(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5ed91ab5.744eaccf.js b/assets/js/5ed91ab5.744eaccf.js new file mode 100644 index 000000000..534d0d4e5 --- /dev/null +++ b/assets/js/5ed91ab5.744eaccf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53337],{65483:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="I",a={id:"concepts/glossary/I",title:"I",description:"---",source:"@site/docs/concepts/glossary/I.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/I",permalink:"/concepts/glossary/I",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"H",permalink:"/concepts/glossary/H"},next:{title:"J",permalink:"/concepts/glossary/J"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"i",children:"I"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/5ed91ab5.d74e522c.js b/assets/js/5ed91ab5.d74e522c.js deleted file mode 100644 index 4e273a43e..000000000 --- a/assets/js/5ed91ab5.d74e522c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3337],{65483:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="I",a={id:"concepts/glossary/I",title:"I",description:"---",source:"@site/docs/concepts/glossary/I.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/I",permalink:"/next/concepts/glossary/I",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"H",permalink:"/next/concepts/glossary/H"},next:{title:"J",permalink:"/next/concepts/glossary/J"}},l={},h=[];function x(e){const s={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"i",children:"I"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5f02ec4e.25f504ac.js b/assets/js/5f02ec4e.25f504ac.js new file mode 100644 index 000000000..9c0e7339f --- /dev/null +++ b/assets/js/5f02ec4e.25f504ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57753],{4879:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(74848),o=n(28453);const s={title:"Overview",slug:"/operators"},i="Operators Overview",a={id:"operators/index",title:"Overview",description:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.",source:"@site/docs/operators/index.md",sourceDirName:"operators",slug:"/operators",permalink:"/operators",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Overview",slug:"/operators"},sidebar:"operators",next:{title:"Setting up a Node",permalink:"/operators/setup/"}},d={},c=[];function h(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"operators-overview",children:"Operators Overview"})}),"\n",(0,r.jsx)(t.p,{children:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section."}),"\n",(0,r.jsxs)(t.p,{children:["Prior knowledge of Unix-based operating systems and proficiency with ",(0,r.jsx)(t.code,{children:"systemd"})," and ",(0,r.jsx)(t.code,{children:"bash"})," scripting are recommended. If you are unfamiliar with ",(0,r.jsx)(t.code,{children:"systemd"}),", the ",(0,r.jsx)(t.a,{href:"https://wiki.archlinux.org/title/systemd",children:"Arch Linux page on systemd"})," is a good introduction."]}),"\n",(0,r.jsxs)(t.p,{children:["Operators should know the ",(0,r.jsx)(t.a,{href:"/operators/setup/hardware",children:"hardware requirements"})," before running a node."]}),"\n",(0,r.jsxs)(t.p,{children:["Also, the ",(0,r.jsx)(t.a,{href:"/operators/setup/install-node#network-requirements",children:"network requirements"})," specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes."]}),"\n",(0,r.jsxs)(t.p,{children:["Review the ",(0,r.jsx)(t.a,{href:"/operators/setup/basic-node-configuration",children:"node's configuration"})," first. Then, you can follow the node ",(0,r.jsx)(t.a,{href:"/operators/setup/install-node",children:"installation instructions"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Topic"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/operators/setup/",children:"Node Setup"})}),(0,r.jsx)(t.td,{children:"How to set up a Casper node"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/operators/becoming-a-validator/",children:"Becoming a Validator"})}),(0,r.jsx)(t.td,{children:"How to join a network and become a validator"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/operators/setup-network/",children:"Private Network Setup"})}),(0,r.jsx)(t.td,{children:"How to set up a private Casper network"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/operators/maintenance/",children:"Maintenance"})}),(0,r.jsx)(t.td,{children:"Topics related to node maintenance"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5f02ec4e.e8115c1a.js b/assets/js/5f02ec4e.e8115c1a.js deleted file mode 100644 index 82d1d7815..000000000 --- a/assets/js/5f02ec4e.e8115c1a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7753],{4879:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>l,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var r=n(74848),o=n(28453);const s={title:"Overview",slug:"/operators"},i="Operators Overview",a={id:"operators/index",title:"Overview",description:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.",source:"@site/docs/operators/index.md",sourceDirName:"operators",slug:"/operators",permalink:"/next/operators",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Overview",slug:"/operators"},sidebar:"operators",next:{title:"Setting up a Node",permalink:"/next/operators/setup/"}},d={},c=[];function h(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"operators-overview",children:"Operators Overview"})}),"\n",(0,r.jsx)(t.p,{children:"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section."}),"\n",(0,r.jsxs)(t.p,{children:["Prior knowledge of Unix-based operating systems and proficiency with ",(0,r.jsx)(t.code,{children:"systemd"})," and ",(0,r.jsx)(t.code,{children:"bash"})," scripting are recommended. If you are unfamiliar with ",(0,r.jsx)(t.code,{children:"systemd"}),", the ",(0,r.jsx)(t.a,{href:"https://wiki.archlinux.org/title/systemd",children:"Arch Linux page on systemd"})," is a good introduction."]}),"\n",(0,r.jsxs)(t.p,{children:["Operators should know the ",(0,r.jsx)(t.a,{href:"/next/operators/setup/hardware",children:"hardware requirements"})," before running a node."]}),"\n",(0,r.jsxs)(t.p,{children:["Also, the ",(0,r.jsx)(t.a,{href:"/next/operators/setup/install-node#network-requirements",children:"network requirements"})," specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes."]}),"\n",(0,r.jsxs)(t.p,{children:["Review the ",(0,r.jsx)(t.a,{href:"/next/operators/setup/basic-node-configuration",children:"node's configuration"})," first. Then, you can follow the node ",(0,r.jsx)(t.a,{href:"/next/operators/setup/install-node",children:"installation instructions"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Topic"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/operators/setup/",children:"Node Setup"})}),(0,r.jsx)(t.td,{children:"How to set up a Casper node"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/operators/becoming-a-validator/",children:"Becoming a Validator"})}),(0,r.jsx)(t.td,{children:"How to join a network and become a validator"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/operators/setup-network/",children:"Private Network Setup"})}),(0,r.jsx)(t.td,{children:"How to set up a private Casper network"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/operators/maintenance/",children:"Maintenance"})}),(0,r.jsx)(t.td,{children:"Topics related to node maintenance"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/5f241059.4b623e89.js b/assets/js/5f241059.4b623e89.js new file mode 100644 index 000000000..38e752894 --- /dev/null +++ b/assets/js/5f241059.4b623e89.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18193],{97005:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const r={},i="JavaScript/TypeScript SDK",c={id:"developers/dapps/sdk/script-sdk",title:"JavaScript/TypeScript SDK",description:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/script-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/script-sdk",permalink:"/2.0.0/developers/dapps/sdk/script-sdk",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Library Usage",permalink:"/2.0.0/developers/dapps/sdk/client-library-usage"},next:{title:".NET SDK",permalink:"/2.0.0/developers/dapps/sdk/csharp-sdk"}},o={},l=[{value:"Usage of JavaScript Clients",id:"usage-of-javascript-clients",level:2},{value:"Repository & Client Packages",id:"repository-7-client-packages",level:3},{value:"Casper SDK for JavaScript",id:"casper-sdk-for-javascript",level:2},{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Generating Account Keys",id:"generating-account-keys",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"javascripttypescript-sdk",children:"JavaScript/TypeScript SDK"})}),"\n",(0,t.jsx)(n.p,{children:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK."}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-javascript-clients",children:"Usage of JavaScript Clients"}),"\n",(0,t.jsx)(n.p,{children:"The Casper team has implemented specific JS clients to support interaction with the Casper contracts."}),"\n",(0,t.jsx)(n.h3,{id:"repository-7-client-packages",children:"Repository & Client Packages"}),"\n",(0,t.jsx)(n.p,{children:"We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/README.md",children:"Casper CEP-78 (NFT) Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/client-js#readme",children:"Casper CEP-18 Client"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These packages give you an easy way to install and interact with the corresponding Casper contract."}),"\n",(0,t.jsx)(n.h2,{id:"casper-sdk-for-javascript",children:"Casper SDK for JavaScript"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"TypeScript/JavaScript SDK"})," allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"To install this library using Node.js, run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk@next --save\n"})}),"\n",(0,t.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,t.jsxs)(n.p,{children:["You can find basic examples for how to use this library in the ",(0,t.jsx)(n.code,{children:"test"})," directory. To run the tests, use this command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,t.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating account keys"}),"\n",(0,t.jsx)(n.li,{children:"Sending a transfer"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"generating-account-keys",children:"Generating Account Keys"}),"\n",(0,t.jsx)(n.p,{children:"This example shows you how to use the SDK to generate account keys to sign your deploy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst { Keys } = require("casper-js-sdk");\n\nconst createAccountKeys = () => {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["After generating the keys with this code, you can add them to the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet Chrome extension"})," and use them to sign your transactions."]}),"\n",(0,t.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,t.jsx)(n.code,{children:"sender-public-key"})," and ",(0,t.jsx)(n.code,{children:"recipient-public-key"})," in the code below."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"sendTransfer"})," function below will return a ",(0,t.jsx)(n.code,{children:"transfer-hash"})," which you can check on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"https://testnet.cspr.live/"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "<sender-public-key>",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "<recipient-public-key>",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Here is the code you can use to serialize the deploy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you can reconstruct the deploy object using this function:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/603aca9e.56ef5275.js b/assets/js/603aca9e.56ef5275.js deleted file mode 100644 index 608701d0e..000000000 --- a/assets/js/603aca9e.56ef5275.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2059],{2839:(e,s,c)=>{c.r(s),c.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=c(74848),t=c(28453);const r={},a="A",o={id:"concepts/glossary/A",title:"A",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/A.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/A",permalink:"/concepts/glossary/A",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Glossary",permalink:"/glossary"},next:{title:"B",permalink:"/concepts/glossary/B"}},i={},l=[{value:"Account",id:"account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"AssemblyScript",id:"assemblyscript",level:2},{value:"Auction",id:"auction",level:2},{value:"Auction contract",id:"auction-contract",level:2},{value:"Auction delay",id:"auction-delay",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"a",children:"A"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"account",children:"Account"}),"\n",(0,n.jsxs)(s.p,{children:["An Account is a structure that represents a user on a Casper network. Information on creating an account can be found ",(0,n.jsx)(s.a,{href:"/concepts/design/casper-design#accounts-head",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,n.jsxs)(s.p,{children:["The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found ",(0,n.jsx)(s.a,{href:"https://support.casperlabs.io/hc/en-gb/articles/13781616975131-How-do-I-generate-an-account-hash-",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"assemblyscript",children:"AssemblyScript"}),"\n",(0,n.jsxs)(s.p,{children:["AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using ",(0,n.jsx)(s.em,{children:"asc"}),", the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community."]}),"\n",(0,n.jsx)(s.h2,{id:"auction",children:"Auction"}),"\n",(0,n.jsx)(s.p,{children:'The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.'}),"\n",(0,n.jsx)(s.h2,{id:"auction-contract",children:"Auction contract"}),"\n",(0,n.jsx)(s.p,{children:"The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction."}),"\n",(0,n.jsx)(s.h2,{id:"auction-delay",children:"Auction delay"}),"\n",(0,n.jsxs)(s.p,{children:["The number of full eras that pass between the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"})," and the era whose validator set it defines. The auction delay is configurable and can be several eras long."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,c)=>{c.d(s,{R:()=>a,x:()=>o});var n=c(96540);const t={},r=n.createContext(t);function a(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/603aca9e.d3942f34.js b/assets/js/603aca9e.d3942f34.js new file mode 100644 index 000000000..7c3d10c45 --- /dev/null +++ b/assets/js/603aca9e.d3942f34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[12059],{2839:(e,s,c)=>{c.r(s),c.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=c(74848),t=c(28453);const r={},a="A",o={id:"concepts/glossary/A",title:"A",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/A.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/A",permalink:"/1.5.X/concepts/glossary/A",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Glossary",permalink:"/1.5.X/glossary"},next:{title:"B",permalink:"/1.5.X/concepts/glossary/B"}},i={},l=[{value:"Account",id:"account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"AssemblyScript",id:"assemblyscript",level:2},{value:"Auction",id:"auction",level:2},{value:"Auction contract",id:"auction-contract",level:2},{value:"Auction delay",id:"auction-delay",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"a",children:"A"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"account",children:"Account"}),"\n",(0,n.jsxs)(s.p,{children:["An Account is a structure that represents a user on a Casper network. Information on creating an account can be found ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,n.jsxs)(s.p,{children:["The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found ",(0,n.jsx)(s.a,{href:"https://support.casperlabs.io/hc/en-gb/articles/13781616975131-How-do-I-generate-an-account-hash-",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"assemblyscript",children:"AssemblyScript"}),"\n",(0,n.jsxs)(s.p,{children:["AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using ",(0,n.jsx)(s.em,{children:"asc"}),", the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community."]}),"\n",(0,n.jsx)(s.h2,{id:"auction",children:"Auction"}),"\n",(0,n.jsx)(s.p,{children:'The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.'}),"\n",(0,n.jsx)(s.h2,{id:"auction-contract",children:"Auction contract"}),"\n",(0,n.jsx)(s.p,{children:"The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction."}),"\n",(0,n.jsx)(s.h2,{id:"auction-delay",children:"Auction delay"}),"\n",(0,n.jsxs)(s.p,{children:["The number of full eras that pass between the ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#booking-block",children:"booking block"})," and the era whose validator set it defines. The auction delay is configurable and can be several eras long."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,c)=>{c.d(s,{R:()=>a,x:()=>o});var n=c(96540);const t={},r=n.createContext(t);function a(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6043c3f4.024a7c77.js b/assets/js/6043c3f4.024a7c77.js deleted file mode 100644 index 5d3069331..000000000 --- a/assets/js/6043c3f4.024a7c77.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6046],{38513:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(74848),a=r(28453);const s={title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},o="Reading and Writing to Global State using Rust",i={id:"resources/advanced/storage-workflow",title:"Storage Workflow",description:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/storage-workflow.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/storage-workflow",permalink:"/resources/tutorials/advanced/storage-workflow",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},sidebar:"tutorials",previous:{title:"Token Transfers",permalink:"/resources/tutorials/advanced/transfer-token-to-contract"},next:{title:"Cross-Contract Communication",permalink:"/resources/tutorials/advanced/cross-contract"}},d={},c=[{value:"Description of Functions",id:"description-of-functions",level:2},{value:"<code>runtime::put_key</code> / <code>runtime::get_key</code>",id:"runtimeput_key--runtimeget_key",level:3},{value:"<code>storage::write</code> / <code>storage::read</code>",id:"storagewrite--storageread",level:3},{value:"<code>storage:dictionary_put</code> / <code>storage::dictionary_get</code>",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of <code>put_key</code> and <code>storage::write</code>",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of <code>get_key</code> and <code>storage::read</code>",id:"example-of-get_key-and-storageread",level:3},{value:"Example of <code>dictionary_put</code> and <code>dictionary_get</code>",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"reading-and-writing-to-global-state-using-rust",children:"Reading and Writing to Global State using Rust"})}),"\n",(0,n.jsx)(t.p,{children:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."}),"\n",(0,n.jsxs)(t.p,{children:["Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,n.jsx)(t.code,{children:"runtime::put_key"}),", ",(0,n.jsx)(t.code,{children:"storage::write"}),"(alongside ",(0,n.jsx)(t.code,{children:"storage::new_uref"})," as explained below) and ",(0,n.jsx)(t.code,{children:"storage::dictionary_put"}),". These stored values can be read using ",(0,n.jsx)(t.code,{children:"runtime::get_key"}),", ",(0,n.jsx)(t.code,{children:"storage::read"})," and ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"}),", respectively. Each method stores data in a specific way, and it's important to understand the differences."]}),"\n",(0,n.jsx)(t.h2,{id:"description-of-functions",children:"Description of Functions"}),"\n",(0,n.jsxs)(t.h3,{id:"runtimeput_key--runtimeget_key",children:[(0,n.jsx)(t.code,{children:"runtime::put_key"})," / ",(0,n.jsx)(t.code,{children:"runtime::get_key"})]}),"\n",(0,n.jsxs)(t.p,{children:["Both the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:(0,n.jsx)(t.code,{children:"put_key"})})," and ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:(0,n.jsx)(t.code,{children:"get_key"})})," functions refer to Casper ",(0,n.jsx)(t.code,{children:"Key"})," types as outlined in both the ",(0,n.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-state-keys",children:"Understanding Hash Types"})," and ",(0,n.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-state-keys",children:"Serialization Standard"}),". These keys are stored within a URef as a ",(0,n.jsx)(t.code,{children:"Key"})," type."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagewrite--storageread",children:[(0,n.jsx)(t.code,{children:"storage::write"})," / ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:(0,n.jsx)(t.code,{children:"storage::write"})})," writes a given value to a previously established URef (created using ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:(0,n.jsx)(t.code,{children:"storage::new_uref"})}),"). Unlike ",(0,n.jsx)(t.code,{children:"put_key"}),", this value is not one of the ",(0,n.jsx)(t.code,{children:"Key"})," types listed above, but rather any of the potential ",(0,n.jsx)(t.a,{href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype",children:(0,n.jsx)(t.code,{children:"CLType"})}),"s as outlined. ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:(0,n.jsx)(t.code,{children:"storage::read"})})," provides a method to retrieve these values from the associated URef."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagedictionary_put--storagedictionary_get",children:[(0,n.jsx)(t.code,{children:"storage:dictionary_put"})," / ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,n.jsx)(t.code,{children:"NamedKeys"}),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."]}),"\n",(0,n.jsxs)(t.p,{children:["More information on dictionaries can be found on the ",(0,n.jsx)(t.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," page."]}),"\n",(0,n.jsx)(t.h2,{id:"example-code",children:"Example Code"}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-put_key-and-storagewrite",children:["Example of ",(0,n.jsx)(t.code,{children:"put_key"})," and ",(0,n.jsx)(t.code,{children:"storage::write"})]}),"\n",(0,n.jsxs)(t.p,{children:["This sample code creates a new contract and stores the contract hash in global state using the ",(0,n.jsx)(t.code,{children:"runtime::put_key"})," function."]}),"\n",(0,n.jsxs)(t.p,{children:["Once the stored value has been initialized, the ",(0,n.jsx)(t.code,{children:"storage::write"})," function overwrites the existing value with ",(0,n.jsx)(t.code,{children:"true"}),". The URef is then stored in the current context as a ",(0,n.jsx)(t.code,{children:"NamedKey"})," titled ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-get_key-and-storageread",children:["Example of ",(0,n.jsx)(t.code,{children:"get_key"})," and ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:["This example compliments the code sample above by retrieving the ",(0,n.jsx)(t.code,{children:"CONTRACT_HASH"})," using the ",(0,n.jsx)(t.code,{children:"get_key"})," function, before comparing a provided runtime argument ",(0,n.jsx)(t.code,{children:"ARG_MY_STORED_VALUE"})," against the previously stored ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"})," using ",(0,n.jsx)(t.code,{children:"storage::read"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-dictionary_put-and-dictionary_get",children:["Example of ",(0,n.jsx)(t.code,{children:"dictionary_put"})," and ",(0,n.jsx)(t.code,{children:"dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["Examples of dictionary usage for storage can be found in the ",(0,n.jsx)(t.em,{children:"Writing Entries into a Dictionary"})," section of ",(0,n.jsx)(t.a,{href:"/concepts/dictionaries#writing-entries-into-a-dictionary",children:"Reading and Writing to Dictionaries"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"additional-functions-for-named-keys",children:"Additional Functions for Named Keys"}),"\n",(0,n.jsx)(t.p,{children:"The following functions might also be of interest for working with named keys:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html",children:"list_named_keys"})," - Returns the named keys of the current context"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html",children:"has_key"})," - Returns true if the key exists in the current context\u2019s named keys"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html",children:"remove_key"})," - Removes the requested ",(0,n.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6043c3f4.9b2ce9e7.js b/assets/js/6043c3f4.9b2ce9e7.js new file mode 100644 index 000000000..d9eb9bc70 --- /dev/null +++ b/assets/js/6043c3f4.9b2ce9e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46046],{38513:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=r(74848),a=r(28453);const s={title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},o="Reading and Writing to Global State using Rust",i={id:"resources/advanced/storage-workflow",title:"Storage Workflow",description:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/storage-workflow.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/storage-workflow",permalink:"/1.5.X/resources/tutorials/advanced/storage-workflow",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},sidebar:"tutorials",previous:{title:"Token Transfers",permalink:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract"},next:{title:"Cross-Contract Communication",permalink:"/1.5.X/resources/tutorials/advanced/cross-contract"}},d={},c=[{value:"Description of Functions",id:"description-of-functions",level:2},{value:"<code>runtime::put_key</code> / <code>runtime::get_key</code>",id:"runtimeput_key--runtimeget_key",level:3},{value:"<code>storage::write</code> / <code>storage::read</code>",id:"storagewrite--storageread",level:3},{value:"<code>storage:dictionary_put</code> / <code>storage::dictionary_get</code>",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of <code>put_key</code> and <code>storage::write</code>",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of <code>get_key</code> and <code>storage::read</code>",id:"example-of-get_key-and-storageread",level:3},{value:"Example of <code>dictionary_put</code> and <code>dictionary_get</code>",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"reading-and-writing-to-global-state-using-rust",children:"Reading and Writing to Global State using Rust"})}),"\n",(0,n.jsx)(t.p,{children:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."}),"\n",(0,n.jsxs)(t.p,{children:["Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,n.jsx)(t.code,{children:"runtime::put_key"}),", ",(0,n.jsx)(t.code,{children:"storage::write"}),"(alongside ",(0,n.jsx)(t.code,{children:"storage::new_uref"})," as explained below) and ",(0,n.jsx)(t.code,{children:"storage::dictionary_put"}),". These stored values can be read using ",(0,n.jsx)(t.code,{children:"runtime::get_key"}),", ",(0,n.jsx)(t.code,{children:"storage::read"})," and ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"}),", respectively. Each method stores data in a specific way, and it's important to understand the differences."]}),"\n",(0,n.jsx)(t.h2,{id:"description-of-functions",children:"Description of Functions"}),"\n",(0,n.jsxs)(t.h3,{id:"runtimeput_key--runtimeget_key",children:[(0,n.jsx)(t.code,{children:"runtime::put_key"})," / ",(0,n.jsx)(t.code,{children:"runtime::get_key"})]}),"\n",(0,n.jsxs)(t.p,{children:["Both the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:(0,n.jsx)(t.code,{children:"put_key"})})," and ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:(0,n.jsx)(t.code,{children:"get_key"})})," functions refer to Casper ",(0,n.jsx)(t.code,{children:"Key"})," types as outlined in both the ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-state-keys",children:"Understanding Hash Types"})," and ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-state-keys",children:"Serialization Standard"}),". These keys are stored within a URef as a ",(0,n.jsx)(t.code,{children:"Key"})," type."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagewrite--storageread",children:[(0,n.jsx)(t.code,{children:"storage::write"})," / ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:(0,n.jsx)(t.code,{children:"storage::write"})})," writes a given value to a previously established URef (created using ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:(0,n.jsx)(t.code,{children:"storage::new_uref"})}),"). Unlike ",(0,n.jsx)(t.code,{children:"put_key"}),", this value is not one of the ",(0,n.jsx)(t.code,{children:"Key"})," types listed above, but rather any of the potential ",(0,n.jsx)(t.a,{href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype",children:(0,n.jsx)(t.code,{children:"CLType"})}),"s as outlined. ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:(0,n.jsx)(t.code,{children:"storage::read"})})," provides a method to retrieve these values from the associated URef."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagedictionary_put--storagedictionary_get",children:[(0,n.jsx)(t.code,{children:"storage:dictionary_put"})," / ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,n.jsx)(t.code,{children:"NamedKeys"}),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."]}),"\n",(0,n.jsxs)(t.p,{children:["More information on dictionaries can be found on the ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," page."]}),"\n",(0,n.jsx)(t.h2,{id:"example-code",children:"Example Code"}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-put_key-and-storagewrite",children:["Example of ",(0,n.jsx)(t.code,{children:"put_key"})," and ",(0,n.jsx)(t.code,{children:"storage::write"})]}),"\n",(0,n.jsxs)(t.p,{children:["This sample code creates a new contract and stores the contract hash in global state using the ",(0,n.jsx)(t.code,{children:"runtime::put_key"})," function."]}),"\n",(0,n.jsxs)(t.p,{children:["Once the stored value has been initialized, the ",(0,n.jsx)(t.code,{children:"storage::write"})," function overwrites the existing value with ",(0,n.jsx)(t.code,{children:"true"}),". The URef is then stored in the current context as a ",(0,n.jsx)(t.code,{children:"NamedKey"})," titled ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-get_key-and-storageread",children:["Example of ",(0,n.jsx)(t.code,{children:"get_key"})," and ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:["This example compliments the code sample above by retrieving the ",(0,n.jsx)(t.code,{children:"CONTRACT_HASH"})," using the ",(0,n.jsx)(t.code,{children:"get_key"})," function, before comparing a provided runtime argument ",(0,n.jsx)(t.code,{children:"ARG_MY_STORED_VALUE"})," against the previously stored ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"})," using ",(0,n.jsx)(t.code,{children:"storage::read"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-dictionary_put-and-dictionary_get",children:["Example of ",(0,n.jsx)(t.code,{children:"dictionary_put"})," and ",(0,n.jsx)(t.code,{children:"dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["Examples of dictionary usage for storage can be found in the ",(0,n.jsx)(t.em,{children:"Writing Entries into a Dictionary"})," section of ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/dictionaries#writing-entries-into-a-dictionary",children:"Reading and Writing to Dictionaries"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"additional-functions-for-named-keys",children:"Additional Functions for Named Keys"}),"\n",(0,n.jsx)(t.p,{children:"The following functions might also be of interest for working with named keys:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html",children:"list_named_keys"})," - Returns the named keys of the current context"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html",children:"has_key"})," - Returns true if the key exists in the current context\u2019s named keys"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html",children:"remove_key"})," - Removes the requested ",(0,n.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/60d3a705.8959a6ed.js b/assets/js/60d3a705.8959a6ed.js new file mode 100644 index 000000000..17f3ce27f --- /dev/null +++ b/assets/js/60d3a705.8959a6ed.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43979],{57921:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var s=i(74848),r=i(28453);const d={},l="Types",c={id:"developers/json-rpc/types_chain",title:"Types",description:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.",source:"@site/docs/developers/json-rpc/types_chain.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_chain",permalink:"/developers/json-rpc/types_chain",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-pos"},next:{title:"CLType",permalink:"/developers/json-rpc/types_cl"}},h={},a=[{value:"Account",id:"account",level:2},{value:"AccountActionThresholds",id:"accountactionthresholds",level:2},{value:"AccountAssociatedKeys",id:"accountassociatedkeys",level:2},{value:"AccountAssociatedKeyWeight",id:"accountassociatedkeyweight",level:2},{value:"AccountHash",id:"accounthash",level:2},{value:"AccountIdentifier",id:"accountidentifier",level:2},{value:"ActivationPoint",id:"activationpoint",level:2},{value:"AddressableEntity",id:"addressableentity",level:2},{value:"AddressableEntityHash",id:"addressableentityhash",level:2},{value:"Approval",id:"approval",level:2},{value:"Array_of_AssociatedKey",id:"array_of_associatedkey",level:2},{value:"Array_of_BlockProof",id:"array_of_blockproof",level:2},{value:"Array_of_EntityVersionAndHash",id:"array_of_entityversionandhash",level:2},{value:"Array_of_EraReward",id:"array_of_erareward",level:2},{value:"Array_of_MessageTopic",id:"array_of_messagetopic",level:2},{value:"Array_of_NamedEntryPoint",id:"array_of_namedentrypoint",level:2},{value:"Array_of_NamedUserGroup",id:"array_of_namedusergroup",level:2},{value:"Array_of_PublicKeyAndBid",id:"array_of_publickeyandbid",level:2},{value:"Array_of_PublicKeyAndDelegator",id:"array_of_publickeyanddelegator",level:2},{value:"Array_of_ValidatorWeight",id:"array_of_validatorweight",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AuctionState",id:"auctionstate",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldWithProof",id:"balanceholdwithproof",level:2},{value:"Bid",id:"bid",level:2},{value:"BidKind",id:"bidkind",level:2},{value:"Block",id:"block",level:2},{value:"BlockBodyV1",id:"blockbodyv1",level:2},{value:"BlockBodyV2",id:"blockbodyv2",level:2},{value:"BlockHash",id:"blockhash",level:2},{value:"BlockHeader",id:"blockheader",level:2},{value:"BlockHeaderV1",id:"blockheaderv1",level:2},{value:"BlockHeaderV2",id:"blockheaderv2",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockProof",id:"blockproof",level:2},{value:"BlockSynchronizerStatus",id:"blocksynchronizerstatus",level:2},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BlockV1",id:"blockv1",level:2},{value:"BlockV2",id:"blockv2",level:2},{value:"Bridge",id:"bridge",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"ByteCodeHash",id:"bytecodehash",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"BytesreprError",id:"bytesreprerror",level:2},{value:"ChainspecRawBytes",id:"chainspecrawbytes",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackage",id:"contractpackage",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractPackageStatus",id:"contractpackagestatus",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractVersionKey",id:"contractversionkey",level:2},{value:"ContractWasm",id:"contractwasm",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"DeployHash",id:"deployhash",level:2},{value:"DeployHeader",id:"deployheader",level:2},{value:"DeployInfo",id:"deployinfo",level:2},{value:"DictionaryIdentifier",id:"dictionaryidentifier",level:2},{value:"Digest",id:"digest",level:2},{value:"Effects",id:"effects",level:2},{value:"EntityActionThresholds",id:"entityactionthresholds",level:2},{value:"EntityAddr",id:"entityaddr",level:2},{value:"EntityAssociatedKeys",id:"entityassociatedkeys",level:2},{value:"EntityAssociatedKeyWeight",id:"entityassociatedkeyweight",level:2},{value:"EntityIdentifier",id:"entityidentifier",level:2},{value:"EntityKind",id:"entitykind",level:2},{value:"EntityOrAccount",id:"entityoraccount",level:2},{value:"EntityVersionAndHash",id:"entityversionandhash",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EntryPoint2",id:"entrypoint2",level:2},{value:"EntryPointAccess",id:"entrypointaccess",level:2},{value:"EntryPointPayment",id:"entrypointpayment",level:2},{value:"EntryPointType",id:"entrypointtype",level:2},{value:"EntryPointValue",id:"entrypointvalue",level:2},{value:"EntryPointV2",id:"entrypointv2",level:2},{value:"EraEndV1",id:"eraendv1",level:2},{value:"EraEndV2",id:"eraendv2",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraIdentifier",id:"eraidentifier",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"EraReport_for_PublicKey",id:"erareport_for_publickey",level:2},{value:"EraReward",id:"erareward",level:2},{value:"EraSummary",id:"erasummary",level:2},{value:"ExecutableDeployItem",id:"executabledeployitem",level:2},{value:"ExecutionInfo",id:"executioninfo",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"Gas",id:"gas",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"JsonBlockWithSignatures",id:"jsonblockwithsignatures",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorsweights",level:2},{value:"Key",id:"key",level:2},{value:"MessageChecksum",id:"messagechecksum",level:2},{value:"MessageTopic",id:"messagetopic",level:2},{value:"MessageTopicSummary",id:"messagetopicsummary",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedEntryPoint",id:"namedentrypoint",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeys",id:"namedkeys",level:2},{value:"NamedKeyValue",id:"namedkeyvalue",level:2},{value:"NamedUserGroup",id:"namedusergroup",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Package",id:"package",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PackageHash",id:"packagehash",level:2},{value:"PackageStatus",id:"packagestatus",level:2},{value:"PaymentInfo",id:"paymentinfo",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"Peers",id:"peers",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PublicKeyAndBid",id:"publickeyandbid",level:2},{value:"PublicKeyAndDelegator",id:"publickeyanddelegator",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReservationKind",id:"reservationkind",level:2},{value:"RewardedSignatures",id:"rewardedsignatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SingleBlockRewardedSignatures",id:"singleblockrewardedsignatures",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"SystemEntityType",id:"systementitytype",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topicnamehash",level:2},{value:"Transaction",id:"transaction",level:2},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:2},{value:"TransactionHash",id:"transactionhash",level:2},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:2},{value:"TransactionRuntime",id:"transactionruntime",level:2},{value:"TransactionScheduling",id:"transactionscheduling",level:2},{value:"TransactionTarget",id:"transactiontarget",level:2},{value:"TransactionV1",id:"transactionv1",level:2},{value:"TransactionV1Body",id:"transactionv1body",level:2},{value:"TransactionV1Hash",id:"transactionv1hash",level:2},{value:"TransactionV1Header",id:"transactionv1header",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransferV1",id:"transferv1",level:2},{value:"TransferV2",id:"transferv2",level:2},{value:"TransformError",id:"transformerror",level:2},{value:"TransformV1",id:"transformv1",level:2},{value:"TransformV2",id:"transformv2",level:2},{value:"TransformKindV1",id:"transformkindv1",level:2},{value:"TransformKindV2",id:"transformkindv2",level:2},{value:"TypeMismatch",id:"typemismatch",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorCredit",id:"validatorcredit",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function t(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"types",children:"Types"})}),"\n",(0,s.jsx)(n.p,{children:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."}),"\n",(0,s.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,s.jsx)(n.p,{children:"Structure representing a user's Account, stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accountactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountactionthresholds",children:"AccountActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeys",children:"AccountAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"collection of weighted public keys"})," (represented as account hashes) associated with an account."]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeyweight",children:"AccountAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an account's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"accounthash",children:"AccountHash"}),"\n",(0,s.jsx)(n.p,{children:"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."}),"\n",(0,s.jsx)(n.h2,{id:"accountidentifier",children:"AccountIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an account."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"activationpoint",children:"ActivationPoint"}),"\n",(0,s.jsx)(n.p,{children:"The first era to which the associated protocol version applies."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," Genesis timestamp."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityassociatedkeys",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodehash",children:(0,s.jsx)(n.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entitykind",children:(0,s.jsx)(n.code,{children:"entity_kind"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_messagetopic",children:(0,s.jsx)(n.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#packagehash",children:(0,s.jsx)(n.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentityhash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(n.p,{children:"The hex-encoded address of the addressable entity."}),"\n",(0,s.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"signer"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_associatedkey",children:"Array_of_AssociatedKey"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#associatedkey",children:"AssociatedKeys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_blockproof",children:"Array_of_BlockProof"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#blockproof",children:(0,s.jsx)(n.code,{children:"BlockProofs"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_entityversionandhash",children:"Array_of_EntityVersionAndHash"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#entityversionandhash",children:"EntityVersionAndHashes"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_erareward",children:"Array_of_EraReward"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#erareward",children:"EraRewards"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_messagetopic",children:"Array_of_MessageTopic"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"MessageTopics"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedentrypoint",children:"Array_of_NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedentrypoint",children:"named entry points"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedusergroup",children:"Array_of_NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedusergroup",children:"NamedUserGroups"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyandbid",children:"Array_of_PublicKeyAndBid"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#publickeyandbid",children:"bids associated with given public keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyanddelegator",children:"Array_of_PublicKeyAndDelegator"}),"\n",(0,s.jsxs)(n.p,{children:["An array consisting of ",(0,s.jsx)(n.a,{href:"#publickeyanddelegator",children:"PublicKeyAndDelegators"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_validatorweight",children:"Array_of_ValidatorWeight"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#validatorweight",children:(0,s.jsx)(n.code,{children:"ValidatorWeights"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsx)(n.p,{children:"A key granted limited permissions to an Account, for purposes such as multisig."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#weight",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"auctionstate",children:"AuctionState"}),"\n",(0,s.jsx)(n.p,{children:"Data structure summarizing auction contract data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_publickeyandbid",children:(0,s.jsx)(n.code,{children:"bids"})})," All bids contained within a vector."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," Block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsoneravalidators",children:(0,s.jsx)(n.code,{children:"era_validators"})})," Era validators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Global state hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsx)(n.p,{children:"An unbroken, inclusive range of blocks."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"high"})," The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"balanceholdwithproof",children:"BalanceHoldWithProof"}),"\n",(0,s.jsx)(n.p,{children:"Hold amount at a given block time."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The amount in the hold."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"proof"})," A string proof that the given value is present in the Merkle trie."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"time"})})," The block time at which the hold was created."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegators"})})," The validator's delegators, indexed by their public keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})," Vesting schedule for a genesis validator. ",(0,s.jsx)(n.code,{children:"None"})," if non-genesis validator."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bidkind",children:"BidKind"}),"\n",(0,s.jsx)(n.p,{children:"Auction bid variants."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unified"})," A unified record indexed on validator data, with an embedded collection of all delegator bids assigned to that validator. The `Unified`` variant is for legacy retrograde support; new instances will not be created going forward."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," A bid record containing only validator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," A bid record containing only delegator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Bridge"})," A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Credit"})," Credited amount."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv2",children:(0,s.jsx)(n.code,{children:"Version2"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hashes"})})," The deploy hashes of the non-transfer deploys within the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator that proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"transfer_hashes"})})," The deploy hashes of the transfers within the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv2",children:"BlockBodyV2"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#rewardedsignatures",children:(0,s.jsx)(n.code,{children:"rewarded_signatures"})})," List of identifiers for finality signatures for a particular past block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transactions"})})," Map of transactions mapping categories to a list of transaction hashes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockhash",children:"BlockHash"}),"\n",(0,s.jsxs)(n.p,{children:["A cryptographic hash identifying a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"blockheader",children:"BlockHeader"}),"\n",(0,s.jsxs)(n.p,{children:["The versioned header portion of a block. It encapsulates different variants of the ",(0,s.jsx)(n.code,{children:"BlockHeader"})," struct."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," The legacy, initial version of the header portion of a block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," The version 2 of the header portion of a block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv1",children:"BlockHeaderV1"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraendv1",children:(0,s.jsx)(n.code,{children:"era_end"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv2",children:"BlockHeaderV2"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})," A seed needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})," The hash of the block's body."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"current_gas_price"})," The gas price of the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})," The parent block's hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator which proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})," The protocol version of the network from when this block was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," The root hash of global state after the deploys in this block have been executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," The timestamp from when the block was proposed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraendv2",children:(0,s.jsx)(n.code,{children:"era_end"})})," The ",(0,s.jsx)(n.code,{children:"EraEnd"})," of a block if it is a switch block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"last_switch_block_hash"})})," The most recent switch block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"Hash"})})," Identify and retrieve the Block with its hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Height"})," Identify and retrieve the Block with its height."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockproof",children:"BlockProof"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a corresponding signature of a given block hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksynchronizerstatus",children:"BlockSynchronizerStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of the block synchronizer."}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Historical"})})," The status of syncing a historical block, if any."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Forward"})})," The status of syncing a forward block, if any."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of syncing an individual block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype wrapping a ",(0,s.jsx)(n.code,{children:"u64"}),", which represents the block time."]}),"\n",(0,s.jsx)(n.h2,{id:"blockv1",children:"BlockV1"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution with the resulting global state root hash prior to Casper 2.0. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv1",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockv2",children:"BlockV2"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution, with the resulting global state root hash. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv2",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bridge",children:"Bridge"}),"\n",(0,s.jsxs)(n.p,{children:["A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era when bridge record was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"old_validator_public_key"})})," Previous validator public key associated with the bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator_public_key"})})," New validator public key associated with the bid."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded bytes."}),"\n",(0,s.jsx)(n.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodekind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodehash",children:"ByteCodeHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a smart contract ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of byte code."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Empty"})," Empty byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"V1CasperWasm"})," Byte code to be executed with the version 1 Casper execution engine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytesreprerror",children:"BytesreprError"}),"\n",(0,s.jsx)(n.p,{children:"Serialization and deserialization errors."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EarlyEndOfStream"})," Early end of stream while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Formatting"})," Formatting error while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"LeftOverBytes"})," Not all input bytes were consumed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"OutOfMemory"})," Out of memory error."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NotRepresentable"})," No serialized representation is available for a value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ExceededRecursionDepth"})," Exceeded a recursion depth limit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspecrawbytes",children:"ChainspecRawBytes"}),"\n",(0,s.jsx)(n.p,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"chainspec_bytes"})})," Hex-encoded raw bytes of the current chainspec.toml file."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_genesis_accounts_bytes"})})," Hex-encoded raw bytes of the current genesis accounts.toml file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_global_state_bytes"})})," Hex-encoded raw bytes of the current global_state.toml file."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct that can be serialized as a JSON object."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackage",children:"ContractPackage"}),"\n",(0,s.jsx)(n.p,{children:"Contract definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract package."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the contract package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"ContractVersion"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameter:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract Wasm."}),"\n",(0,s.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee").'}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A Deploy; an item containing a smart contract along with the requester's signature(s)."}),"\n",(0,s.jsx)(n.p,{children:"Required properties:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployheader",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"session"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployhash",children:"DeployHash"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded Deploy hash."}),"\n",(0,s.jsx)(n.h2,{id:"deployheader",children:"DeployHeader"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"account"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"chain_name"})," A user defined string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"dependencies"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas_price"})," Defined as an integer in UInt64 format."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to the given Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," The relevant Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account identifier of the creator of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"gas"})})," Gas cost of executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse used for payment of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})," Transfers performed by the Deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionaryidentifier",children:"DictionaryIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Options for dictionary item lookups."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AccountNamedKey"})," Lookup a dictionary item via an Account's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The Account key as a formatted string whose named keys contain dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractNamedKey"})," Lookup a dictionary item via a Contract's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The contract key as a formatted string whose named keys contains dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"EntityNamedKey"})}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The entity address formatted as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," Lookup a dictionary item via its seed URef."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"seed_uref"})," The dictionary's seed URef."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Dictionary"})," Lookup a dictionary item via its unique key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded hash digest."}),"\n",(0,s.jsx)(n.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(n.p,{children:["A log of all ",(0,s.jsx)(n.a,{href:"#transformv2",children:"transforms"})," produced during execution."]}),"\n",(0,s.jsx)(n.h2,{id:"entityactionthresholds",children:"EntityActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"upgrade_management"})})," Threshold for upgrading contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityaddr",children:"EntityAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address for an AddressableEntity which contains the 32 bytes and tagging information."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address for a system entity account or contract."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to an Account."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to a user (non-system) smart contract."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeys",children:"EntityAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A collection of weighted public keys (represented as account hashes) associated with an account. See ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"Array_of_AssociatedKey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeyweight",children:"EntityAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an entity's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"entityidentifier",children:"EntityIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an addressable entity."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entitykind",children:"EntityKind"}),"\n",(0,s.jsxs)(n.p,{children:["The type of ",(0,s.jsx)(n.a,{href:"#package",children:(0,s.jsx)(n.code,{children:"Package"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#systementitytype",children:(0,s.jsx)(n.code,{children:"System"})})," Package associated with a native contract implementation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"Account"})})," Package associated with an Account hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"SmartContract"})})," Packages associated with Wasm stored on chain."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityoraccount",children:"EntityOrAccount"}),"\n",(0,s.jsx)(n.p,{children:"An addressable entity or a legacy account."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An addressable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," A legacy account."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionandhash",children:"EntityVersionAndHash"}),"\n",(0,s.jsx)(n.p,{children:"An entity version associated with the given hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#addressableentityhash",children:(0,s.jsx)(n.code,{children:"addressable_entity_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"entity_version_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"EntityVersion"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entity_version"})," Automatically incremented value for a contract version within a major ",(0,s.jsx)(n.code,{children:"ProtocolVersion"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," with which a ",(0,s.jsx)(n.code,{children:"ContractVersion"})," is compatible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint2",children:"EntryPoint2"}),"\n",(0,s.jsx)(n.p,{children:"Type signature of a method. Order of arguments matters since they can be referenced by index as well as their name."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointpayment",children:(0,s.jsx)(n.code,{children:"entry_point_payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The string name of the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointaccess",children:"EntryPointAccess"}),"\n",(0,s.jsx)(n.p,{children:"Enum describing the possible access control options for a contract entry point."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Public"})," A public entry point is callable by any caller."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"Groups"})})," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Template"})," A string type that can't be accessed directly but is kept in the derived Wasm bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointpayment",children:"EntryPointPayment"}),"\n",(0,s.jsx)(n.p,{children:"An enum specifying who pays for the invocation and execution of the entrypoint."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," The caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnly"})," The current execution will cover the cost to execute self but not the cost of any subsequently invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnward"})," The current execution will cover the cost to execute self and the cost of any subsequently invoked contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointtype",children:"EntryPointType"}),"\n",(0,s.jsxs)(n.p,{children:["Context of an entry point execution. The most significant bit represents the version. For example, ",(0,s.jsx)(n.code,{children:"0b0"})," represents session and contract entry points up to version 2.0. And, ",(0,s.jsx)(n.code,{children:"0b1"})," is for versions 2.x and later (i.e. installer and utility entry points)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," Runs using the calling entity's context. In v1.x, this was used for both session code that ran using the originating account's context and stored session code that ran in the caller's context. In v2.x, the renamed Caller variant is exclusively used for Wasm running using the initiating account entity's context. Previously installed 1.x stored session code should continue to work as the binary value matches, but we no longer allow such logic to be upgraded, nor do we allow new stored session code to be installed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Called"})," Runs within the called entity's context."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Factory"})," This entry point is intended to extract a subset of bytecode. Runs within the called entity's context."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointvalue",children:"EntryPointValue"}),"\n",(0,s.jsx)(n.p,{children:"The encaspulated representation of entrypoints."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint2",children:(0,s.jsx)(n.code,{children:"V1CasperVm"})})," Entrypoints to be executed against the V1 Casper VM."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypointv2",children:(0,s.jsx)(n.code,{children:"V2CasperVm"})})," Entrypoints to be executed against the V2 Casper VM."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointv2",children:"EntryPointV2"}),"\n",(0,s.jsx)(n.p,{children:"The entry point for the V2 Casper VM."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"flags"})," The flags as a uint32 integer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"function_index"})," The selector as a uint32 integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv1",children:"EraEndV1"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#erareport_for_publickey",children:(0,s.jsx)(n.code,{children:"era_report"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv2",children:"EraEndV2"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any units during the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"next_era_gas_price"})," The gas price for the next era as a ",(0,s.jsx)(n.code,{children:"uint8"})," integer. Minimum 0.0 motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})," The validators for the upcoming era and their respective weights."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"rewards"})})," The rewards distributed to the validators."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsx)(n.p,{children:"Era ID newtype."}),"\n",(0,s.jsx)(n.h2,{id:"eraidentifier",children:"EraIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for an era."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"Era"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockidentifier",children:(0,s.jsx)(n.code,{children:"Block"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsx)(n.p,{children:"Auction metadata. Intended to be recorded at each era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#seigniorageallocation",children:(0,s.jsx)(n.code,{children:"seigniorage_allocation"})})," Information about a seigniorage allocation."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareport_for_publickey",children:"EraReport_for_PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Equivocation, reward and validator inactivity information."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_erareward",children:(0,s.jsx)(n.code,{children:"rewards"})})," Rewards for finalization of earlier blocks."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any unit during the era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareward",children:"EraReward"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a measure of the value of its contribution to consensus, as a fraction of the configured maximum block reward."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The reward amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erasummary",children:"EraSummary"}),"\n",(0,s.jsx)(n.p,{children:"The summary of an era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The Block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#merkle-proof",children:(0,s.jsx)(n.code,{children:"merkle_proof"})})," The merkle proof."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"stored_value"})})," The StoredValue containing era information."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executabledeployitem",children:"ExecutableDeployItem"}),"\n",(0,s.jsx)(n.p,{children:"Represents possible variants of an executable Deploy."}),"\n",(0,s.jsx)(n.h2,{id:"executioninfo",children:"ExecutionInfo"}),"\n",(0,s.jsx)(n.p,{children:"The block hash and height in which a given deploy was executed, along with the execution result if known."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The hash of the block in which the deploy was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block in which the deploy was executed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#executionresult",children:(0,s.jsx)(n.code,{children:"execution_result"})})," The execution result if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(n.p,{children:"The journal of execution transforms from a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#operation",children:(0,s.jsx)(n.code,{children:"operations"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transformentry",children:(0,s.jsx)(n.code,{children:"transforms"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,s.jsx)(n.p,{children:"The versioned result of executing a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," Version 1 of execution result type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," Version 2 of execution result type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single deploy prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," The result of a failed execution"]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"error_message"})," The error message associated with executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Success"})," The result of a successful execution."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single transaction."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"consumed"})})," How much gas was consumed executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})," How much was paid for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#effects",children:(0,s.jsx)(n.code,{children:"effects"})})," The effects of executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator"})})," Who initiated this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"limit"})})," The maximum allowed gas limit for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#paymentinfo",children:(0,s.jsx)(n.code,{children:"payment"})})," Breakdown of payments made to cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"size_estimate"})," The size estimate of the transaction"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"transfers"})})," A record of transfers performed while executing this transaction."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"error_message"})," If there is no error message, this execution was processed successfully. If there is an error message, this execution failed to fully process for the stated reason."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Gas"})," struct represents a ",(0,s.jsx)(n.code,{children:"U512"})," amount of gas."]}),"\n",(0,s.jsx)(n.h2,{id:"globalstateidentifier",children:"GlobalStateIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to query global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"BlockHash"})})," Query using a block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"BlockHeight"})," Query using a block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"StateRootHash"})})," Query using the state root hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,s.jsx)(n.p,{children:'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'}),"\n",(0,s.jsx)(n.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address of the initiator of a transaction"}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"publickey"})})," The public key of the initiator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"accounthash"})})," The account hash derived from the public key of the initiator."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonblockwithsignatures",children:"JsonBlockWithSignatures"}),"\n",(0,s.jsx)(n.p,{children:"A JSON-friendly representation of a block and the signatures for that block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#block",children:(0,s.jsx)(n.code,{children:"block"})})," The block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_blockproof",children:(0,s.jsx)(n.code,{children:"proofs"})})," The proofs of the block, i.e. a collection of validators' signatures of the block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsoneravalidators",children:"JsonEraValidators"}),"\n",(0,s.jsx)(n.p,{children:"The validators for the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#jsonvalidatorsweights",children:(0,s.jsx)(n.code,{children:"validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorchanges",children:"JsonValidatorChanges"}),"\n",(0,s.jsx)(n.p,{children:"The changes in a validator's status."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})," The public key of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsonvalidatorstatuschange",children:(0,s.jsx)(n.code,{children:"status_changes"})})," The set of changes to the validator's status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorstatuschange",children:"JsonValidatorStatusChange"}),"\n",(0,s.jsx)(n.p,{children:"A single change to a validator's status in the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era in which the change occurred."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#validatorchange",children:(0,s.jsx)(n.code,{children:"validator_change"})})," The change in validator status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorsweights",children:"JsonValidatorsWeights"}),"\n",(0,s.jsx)(n.p,{children:"A validator's weight."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"key",children:"Key"}),"\n",(0,s.jsx)(n.p,{children:"The key as a formatted string, under which data can be stored in global state."}),"\n",(0,s.jsx)(n.h2,{id:"messagechecksum",children:"MessageChecksum"}),"\n",(0,s.jsx)(n.p,{children:"Message checksum as a formatted string."}),"\n",(0,s.jsx)(n.h2,{id:"messagetopic",children:"MessageTopic"}),"\n",(0,s.jsx)(n.p,{children:"A topic for contract-level messages."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name"})," A string used to identify the message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#topicnamehash",children:(0,s.jsx)(n.code,{children:"topic_name_hash"})})," The hash of the name of the message topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"messagetopicsummary",children:"MessageTopicSummary"}),"\n",(0,s.jsx)(n.p,{children:"Summary of a message topic that will be stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"blocktime"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"message_count"})," The number of messages in this topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"minimalblockinfo",children:"MinimalBlockInfo"}),"\n",(0,s.jsxs)(n.p,{children:["Minimal info of a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"creator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsx)(n.p,{children:"Named arguments to a contract."}),"\n",(0,s.jsx)(n.h2,{id:"namedentrypoint",children:"NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#entrypoint",children:"entry point"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," A string identifying the entry point."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsx)(n.p,{children:"A named key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The value of the entry: a casper ",(0,s.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeys",children:"NamedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#namedkey",children:"collection of named keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeyvalue",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"NamedKey"})," value."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"named_key"})," The actual ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedusergroup",children:"NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group_name"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"group_users"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nextupgrade",children:"NextUpgrade"}),"\n",(0,s.jsx)(n.p,{children:"Information about the next protocol upgrade."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#activationpoint",children:(0,s.jsx)(n.code,{children:"activation_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(n.p,{children:"An operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#opkind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"opkind",children:"OpKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Read"})," A read operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," A write operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Add"})," An addition."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NoOp"})," An operation which has no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," A prune operation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(n.p,{children:"Entity definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})," Collection of disabled entity versions. The runtime will not permit disabled entity versions to be executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})," Mapping maintaining the set of URefs associated with each user group, used to control access to methods in a particular version of the entity. A method is callable by any context which knows any of the URefs associated with the method's user group."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#packagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})," A flag that determines whether a entity is locked."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_entityversionandhash",children:(0,s.jsx)(n.code,{children:"versions"})})," All versions (enabled & disabled)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsx)(n.p,{children:"Parameter to an entry point."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"packagehash",children:"PackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"packagestatus",children:"PackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"paymentinfo",children:"PaymentInfo"}),"\n",(0,s.jsx)(n.p,{children:"Breakdown of payments made to cover the cost."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"source"})," Source purse used for payment of the transaction."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peerentry",children:"PeerEntry"}),"\n",(0,s.jsx)(n.p,{children:"Node peer entry."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"address"})," Node address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"node_id"})," Node ID."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peers",children:"Peers"}),"\n",(0,s.jsx)(n.p,{children:"Map of peer IDs to network addresses."}),"\n",(0,s.jsx)(n.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsx)(n.p,{children:"The pricing mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Classic"})," The original payment model, where the creator of the transaction specifies how much they will pay, at what gas price."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Fixed"})," The cost of the transaction is determined by the cost table, per the transaction category."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Reserved"})," The payment for this transaction was previously reserved (Not currently implemented)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsx)(n.p,{children:"Casper Platform protocol version."}),"\n",(0,s.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic public key, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"publickeyandbid",children:"PublicKeyAndBid"}),"\n",(0,s.jsx)(n.p,{children:"A bid associated with the given public key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"bid"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"publickeyanddelegator",children:"PublicKeyAndDelegator"}),"\n",(0,s.jsx)(n.p,{children:"A delegator associated with the given validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegator"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"purseidentifier",children:"PurseIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"The identifier of a purse."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_public_key"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_account_hash"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_entity_addr"})," The main purse of the account identified by this ",(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"purse_uref"})," A specific purse identified by the associated ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"reservationkind",children:"ReservationKind"}),"\n",(0,s.jsx)(n.p,{children:"Container for bytes recording location, type and data for a gas reservation."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"receipt"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"reservation_data"})})," Hex-encoded bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"reservation_kind"})," A ",(0,s.jsx)(n.code,{children:"uint8"})," integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rewardedsignatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["Describes finality signatures that will be rewarded in a block. Consists of a vector of ",(0,s.jsx)(n.a,{href:"#singleblockrewardedsignatures",children:(0,s.jsx)(n.code,{children:"SingleBlockRewardedSignatures"})}),", each of which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsx)(n.p,{children:"Represents a collection of arguments passed to a smart contract."}),"\n",(0,s.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(n.p,{children:"Information about a seigniorage allocation."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," Info about a seigniorage allocation for a validator."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," Info about a seigniorage allocation for a delegator."]}),"\n",(0,s.jsx)(n.p,{children:"Require Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})," Delegator's public key."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic signature, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"singleblockrewardedsignatures",children:"SingleBlockRewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["List of identifiers for finality signatures for a particular past block. That past block height is equal to ",(0,s.jsx)(n.code,{children:"current_height"})," minus ",(0,s.jsx)(n.code,{children:"signature_rewards_max_delay"}),", the latter being defined in the chainspec."]}),"\n",(0,s.jsx)(n.h2,{id:"storedvalue",children:"StoredValue"}),"\n",(0,s.jsx)(n.p,{children:"Representation of a value stored in global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})})," A Casper-specific value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," An Account."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractWasm"})," A contract's Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contract",children:(0,s.jsx)(n.code,{children:"Contract"})})," Entry points supported by a contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contractpackage",children:(0,s.jsx)(n.code,{children:"ContractPackage"})})," A contract definition, metadata, and security container."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"LegacyTransfer"})})," A version 1 (legacy) transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployinfo",children:(0,s.jsx)(n.code,{children:"DeployInfo"})})," A record of a Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})})," Information about an era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"Bid"})})," A bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Withdraw"})})," A withdraw."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Unbonding"})})," Unbonding information."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An AddressableEntity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bidkind",children:(0,s.jsx)(n.code,{children:"BidKind"})})," A variant that stored ",(0,s.jsx)(n.code,{children:"BidKind"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"Package"}),"] A ",(0,s.jsx)(n.code,{children:"Package"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"ByteCode"}),"] A record of byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagetopic",children:(0,s.jsx)(n.code,{children:"MessageTopic"})})," A variant that stores a message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagechecksum",children:(0,s.jsx)(n.code,{children:"Message"})})," A variant that stores a message digest."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"NamedKey"})})," A NamedKey record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#reservationkind",children:(0,s.jsx)(n.code,{children:"Reservation"})})," A reservation record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"EntryPoint"})})," An entrypoint record."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"systementitytype",children:"SystemEntityType"}),"\n",(0,s.jsx)(n.p,{children:"System contract types."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Mint"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"HandlePayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"StandardPayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Auction"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsx)(n.p,{children:"Human-readable duration."}),"\n",(0,s.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsx)(n.p,{children:"Timestamp formatted as per RFC 3339."}),"\n",(0,s.jsx)(n.h2,{id:"topicnamehash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hash of the name of the ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"message topic"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction or deploy."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy",children:(0,s.jsx)(n.code,{children:"deploy"})})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"or"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactionv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"An entry point of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Call"})," The standard ",(0,s.jsx)(n.code,{children:"call"})," entry point used in session code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Custom"})," A non-native, arbitrary entry point."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Transfer"})," The ",(0,s.jsx)(n.code,{children:"transfer"})," native entry point, used to reference motes from a source purse to a target purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddBid"})," The ",(0,s.jsx)(n.code,{children:"add_bid"})," native entry point, used to create or top off a bid purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WithdrawBid"})," The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," native entry point, used to decrease a validator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegate"})," The ",(0,s.jsx)(n.code,{children:"delegate"})," native entry point, used to add a new delegator or increase an existing delegator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Undelegate"})," The ",(0,s.jsx)(n.code,{children:"undelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Redelegate"})," The ",(0,s.jsx)(n.code,{children:"redelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero. After the unbonding delay, it will automatically delegate to a new validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ActivateBid"})," The ",(0,s.jsx)(n.code,{children:"activate_bid"})," native entry point, used to used to reactivate an inactive bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ChangeBidPublicKey"})," The ",(0,s.jsx)(n.code,{children:"change_bid_public_key"})," native entry point, used to change a bid's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction hash or deploy hash."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"Deploy"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1hash",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(n.p,{children:["The identifier of a ",(0,s.jsx)(n.code,{children:"stored"})," transaction target."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByHash"})," The hex-encoded entity address identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByName"})," The alias identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageHash"})," The address and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"addr"})," The hex-encoded address of the package."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageName"})," The alias and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," The package name."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsx)(n.p,{children:"Runtime used to execute a transaction."}),"\n",(0,s.jsx)(n.p,{children:"Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV1"})," The Casper Version 1 Virtual Machine."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV2"})," The Casper Version 2 Virtual Machine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsx)(n.p,{children:"The scheduling mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Standard"})," No special scheduling applied."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureEra"})," Execution should be scheduled for the specific era."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureEra"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"FutureEra"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureTimestamp"})," Execution should be scheduled for the specific timestamp or later."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureTimestamp"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"FutureTimestamp"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsx)(n.p,{children:"The execution target of a Transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native"})," The execution target is a native operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stored"})," The execution target is a stored entity or package."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"stored"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(n.code,{children:"id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session"})," The execution target is the included module bytes."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"session"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"module_bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1",children:"TransactionV1"}),"\n",(0,s.jsx)(n.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1body",children:(0,s.jsx)(n.code,{children:"body"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1hash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1header",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsx)(n.p,{children:"The body of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#runtimeargs",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionscheduling",children:(0,s.jsx)(n.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactiontarget",children:(0,s.jsx)(n.code,{children:"target"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(n.p,{children:"A hex-encoded TransactionV1 hash."}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"chain_name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator_addr"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#pricingmode",children:(0,s.jsx)(n.code,{children:"pricing_mode"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transfer",children:"Transfer"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transfer."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," A version 1 transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," A version 2 transfer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded version 1 transfer address."}),"\n",(0,s.jsx)(n.h2,{id:"transferv1",children:"TransferV1"}),"\n",(0,s.jsx)(n.p,{children:"Represents a transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," Deploy that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferv2",children:"TransferV2"}),"\n",(0,s.jsx)(n.p,{children:"Represents a version 2 transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transaction_hash"})})," Transaction that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"from"})})," Entity from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformerror",children:"TransformError"}),"\n",(0,s.jsxs)(n.p,{children:["Error type for applying and combining transforms. A ",(0,s.jsx)(n.code,{children:"TypeMismatch"})," occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytesreprerror",children:(0,s.jsx)(n.code,{children:"serialization"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#typemismatch",children:(0,s.jsx)(n.code,{children:"typemismatch"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deprecated"})," Type no longer supported."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv1",children:"TransformV1"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv1",children:(0,s.jsx)(n.code,{children:"transforms"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv2",children:"TransformV2"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv2",children:(0,s.jsx)(n.code,{children:"kind"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv1",children:"TransformKindV1"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 1."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteCLValue"})," Writes the given CLValue to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAccount"})," Writes the given Account to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractWasm"})," Writes a smart contract as Wasm to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContract"})," Writes a smart contract to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractPackage"})," Writes a smart contract package to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteDeployInfo"})," Writes the given DeployInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteEraInfo"})," Writes the given EraInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteTransfer"})," Writes the given Transfer to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBid"})," Writes the given Bid to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteWithdraw"})," Writes the given Withdraw to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteUnbonding"})," Writes the given Unbonding to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAddressableEntity"})," Writes the addressable entity to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBidKind"})," Writes the given BidKind to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv2",children:"TransformKindV2"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 2."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," Writes the new value in global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"typemismatch",children:"TypeMismatch"}),"\n",(0,s.jsxs)(n.p,{children:["An error struct representing a type mismatch in ",(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"StoredValue"})})," operations."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"expected"})," The name of the expected type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"found"})," The actual type found."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"u128",children:"U128"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 128-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u256",children:"U256"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 256-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u512",children:"U512"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 512-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(n.p,{children:"Unbonding purse."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator"})})," The redelegated validator's public key."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded, formatted URef."}),"\n",(0,s.jsx)(n.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if the validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"maximum_delegation_amount"})," Minimum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"minimum_delegation_amount"})," Maximum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorchange",children:"ValidatorChange"}),"\n",(0,s.jsx)(n.p,{children:"A change to a validator's status between two eras."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Added"})," The validator was just added to the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Removed"})," The validator was removed from the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Banned"})," The validator was banned from this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CannotPropose"})," The validator was excluded from proposing new blocks in this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SeenAsFaulty"})," We saw the validator misbehave in this era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorcredit",children:"ValidatorCredit"}),"\n",(0,s.jsx)(n.p,{children:"Validator credit record."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The credit amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorweight",children:"ValidatorWeight"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with its weight, i.e. the total number of motes it staked together with its delegators."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"vestingschedule",children:"VestingSchedule"}),"\n",(0,s.jsx)(n.p,{children:"Vesting schedule for a genesis validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"initial_release_timestamp_millies"})," Timestamp of the initial release."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"locked_amounts"})})," The amount of locked motes."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsx)(n.p,{children:"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(t,{...e})}):t(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>c});var s=i(96540);const r={},d=s.createContext(r);function l(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/60d3a705.cec61f0b.js b/assets/js/60d3a705.cec61f0b.js deleted file mode 100644 index fc3ce5cea..000000000 --- a/assets/js/60d3a705.cec61f0b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3979],{57921:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var s=i(74848),r=i(28453);const d={},l="Types",c={id:"developers/json-rpc/types_chain",title:"Types",description:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.",source:"@site/docs/developers/json-rpc/types_chain.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_chain",permalink:"/next/developers/json-rpc/types_chain",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-pos"},next:{title:"CLType",permalink:"/next/developers/json-rpc/types_cl"}},h={},a=[{value:"Account",id:"account",level:2},{value:"AccountActionThresholds",id:"accountactionthresholds",level:2},{value:"AccountAssociatedKeys",id:"accountassociatedkeys",level:2},{value:"AccountAssociatedKeyWeight",id:"accountassociatedkeyweight",level:2},{value:"AccountHash",id:"accounthash",level:2},{value:"AccountIdentifier",id:"accountidentifier",level:2},{value:"ActivationPoint",id:"activationpoint",level:2},{value:"AddressableEntity",id:"addressableentity",level:2},{value:"AddressableEntityHash",id:"addressableentityhash",level:2},{value:"Approval",id:"approval",level:2},{value:"Array_of_AssociatedKey",id:"array_of_associatedkey",level:2},{value:"Array_of_BlockProof",id:"array_of_blockproof",level:2},{value:"Array_of_EntityVersionAndHash",id:"array_of_entityversionandhash",level:2},{value:"Array_of_EraReward",id:"array_of_erareward",level:2},{value:"Array_of_MessageTopic",id:"array_of_messagetopic",level:2},{value:"Array_of_NamedEntryPoint",id:"array_of_namedentrypoint",level:2},{value:"Array_of_NamedUserGroup",id:"array_of_namedusergroup",level:2},{value:"Array_of_PublicKeyAndBid",id:"array_of_publickeyandbid",level:2},{value:"Array_of_PublicKeyAndDelegator",id:"array_of_publickeyanddelegator",level:2},{value:"Array_of_ValidatorWeight",id:"array_of_validatorweight",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AuctionState",id:"auctionstate",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldWithProof",id:"balanceholdwithproof",level:2},{value:"Bid",id:"bid",level:2},{value:"BidKind",id:"bidkind",level:2},{value:"Block",id:"block",level:2},{value:"BlockBodyV1",id:"blockbodyv1",level:2},{value:"BlockBodyV2",id:"blockbodyv2",level:2},{value:"BlockHash",id:"blockhash",level:2},{value:"BlockHeader",id:"blockheader",level:2},{value:"BlockHeaderV1",id:"blockheaderv1",level:2},{value:"BlockHeaderV2",id:"blockheaderv2",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockProof",id:"blockproof",level:2},{value:"BlockSynchronizerStatus",id:"blocksynchronizerstatus",level:2},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BlockV1",id:"blockv1",level:2},{value:"BlockV2",id:"blockv2",level:2},{value:"Bridge",id:"bridge",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"ByteCodeHash",id:"bytecodehash",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"BytesreprError",id:"bytesreprerror",level:2},{value:"ChainspecRawBytes",id:"chainspecrawbytes",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackage",id:"contractpackage",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractPackageStatus",id:"contractpackagestatus",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractVersionKey",id:"contractversionkey",level:2},{value:"ContractWasm",id:"contractwasm",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"DeployHash",id:"deployhash",level:2},{value:"DeployHeader",id:"deployheader",level:2},{value:"DeployInfo",id:"deployinfo",level:2},{value:"DictionaryIdentifier",id:"dictionaryidentifier",level:2},{value:"Digest",id:"digest",level:2},{value:"Effects",id:"effects",level:2},{value:"EntityActionThresholds",id:"entityactionthresholds",level:2},{value:"EntityAddr",id:"entityaddr",level:2},{value:"EntityAssociatedKeys",id:"entityassociatedkeys",level:2},{value:"EntityAssociatedKeyWeight",id:"entityassociatedkeyweight",level:2},{value:"EntityIdentifier",id:"entityidentifier",level:2},{value:"EntityKind",id:"entitykind",level:2},{value:"EntityOrAccount",id:"entityoraccount",level:2},{value:"EntityVersionAndHash",id:"entityversionandhash",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EntryPoint2",id:"entrypoint2",level:2},{value:"EntryPointAccess",id:"entrypointaccess",level:2},{value:"EntryPointPayment",id:"entrypointpayment",level:2},{value:"EntryPointType",id:"entrypointtype",level:2},{value:"EntryPointValue",id:"entrypointvalue",level:2},{value:"EntryPointV2",id:"entrypointv2",level:2},{value:"EraEndV1",id:"eraendv1",level:2},{value:"EraEndV2",id:"eraendv2",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraIdentifier",id:"eraidentifier",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"EraReport_for_PublicKey",id:"erareport_for_publickey",level:2},{value:"EraReward",id:"erareward",level:2},{value:"EraSummary",id:"erasummary",level:2},{value:"ExecutableDeployItem",id:"executabledeployitem",level:2},{value:"ExecutionInfo",id:"executioninfo",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"Gas",id:"gas",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"JsonBlockWithSignatures",id:"jsonblockwithsignatures",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorsweights",level:2},{value:"Key",id:"key",level:2},{value:"MessageChecksum",id:"messagechecksum",level:2},{value:"MessageTopic",id:"messagetopic",level:2},{value:"MessageTopicSummary",id:"messagetopicsummary",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedEntryPoint",id:"namedentrypoint",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeys",id:"namedkeys",level:2},{value:"NamedKeyValue",id:"namedkeyvalue",level:2},{value:"NamedUserGroup",id:"namedusergroup",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Package",id:"package",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PackageHash",id:"packagehash",level:2},{value:"PackageStatus",id:"packagestatus",level:2},{value:"PaymentInfo",id:"paymentinfo",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"Peers",id:"peers",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PublicKeyAndBid",id:"publickeyandbid",level:2},{value:"PublicKeyAndDelegator",id:"publickeyanddelegator",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReservationKind",id:"reservationkind",level:2},{value:"RewardedSignatures",id:"rewardedsignatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SingleBlockRewardedSignatures",id:"singleblockrewardedsignatures",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"SystemEntityType",id:"systementitytype",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topicnamehash",level:2},{value:"Transaction",id:"transaction",level:2},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:2},{value:"TransactionHash",id:"transactionhash",level:2},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:2},{value:"TransactionRuntime",id:"transactionruntime",level:2},{value:"TransactionScheduling",id:"transactionscheduling",level:2},{value:"TransactionTarget",id:"transactiontarget",level:2},{value:"TransactionV1",id:"transactionv1",level:2},{value:"TransactionV1Body",id:"transactionv1body",level:2},{value:"TransactionV1Hash",id:"transactionv1hash",level:2},{value:"TransactionV1Header",id:"transactionv1header",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransferV1",id:"transferv1",level:2},{value:"TransferV2",id:"transferv2",level:2},{value:"TransformError",id:"transformerror",level:2},{value:"TransformV1",id:"transformv1",level:2},{value:"TransformV2",id:"transformv2",level:2},{value:"TransformKindV1",id:"transformkindv1",level:2},{value:"TransformKindV2",id:"transformkindv2",level:2},{value:"TypeMismatch",id:"typemismatch",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorCredit",id:"validatorcredit",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function t(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"types",children:"Types"})}),"\n",(0,s.jsx)(n.p,{children:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."}),"\n",(0,s.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,s.jsx)(n.p,{children:"Structure representing a user's Account, stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accountactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountactionthresholds",children:"AccountActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeys",children:"AccountAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"collection of weighted public keys"})," (represented as account hashes) associated with an account."]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeyweight",children:"AccountAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an account's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"accounthash",children:"AccountHash"}),"\n",(0,s.jsx)(n.p,{children:"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."}),"\n",(0,s.jsx)(n.h2,{id:"accountidentifier",children:"AccountIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an account."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"activationpoint",children:"ActivationPoint"}),"\n",(0,s.jsx)(n.p,{children:"The first era to which the associated protocol version applies."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," Genesis timestamp."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityassociatedkeys",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodehash",children:(0,s.jsx)(n.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entitykind",children:(0,s.jsx)(n.code,{children:"entity_kind"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_messagetopic",children:(0,s.jsx)(n.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#packagehash",children:(0,s.jsx)(n.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentityhash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(n.p,{children:"The hex-encoded address of the addressable entity."}),"\n",(0,s.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"signer"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_associatedkey",children:"Array_of_AssociatedKey"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#associatedkey",children:"AssociatedKeys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_blockproof",children:"Array_of_BlockProof"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#blockproof",children:(0,s.jsx)(n.code,{children:"BlockProofs"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_entityversionandhash",children:"Array_of_EntityVersionAndHash"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#entityversionandhash",children:"EntityVersionAndHashes"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_erareward",children:"Array_of_EraReward"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#erareward",children:"EraRewards"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_messagetopic",children:"Array_of_MessageTopic"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"MessageTopics"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedentrypoint",children:"Array_of_NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedentrypoint",children:"named entry points"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedusergroup",children:"Array_of_NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedusergroup",children:"NamedUserGroups"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyandbid",children:"Array_of_PublicKeyAndBid"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#publickeyandbid",children:"bids associated with given public keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyanddelegator",children:"Array_of_PublicKeyAndDelegator"}),"\n",(0,s.jsxs)(n.p,{children:["An array consisting of ",(0,s.jsx)(n.a,{href:"#publickeyanddelegator",children:"PublicKeyAndDelegators"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_validatorweight",children:"Array_of_ValidatorWeight"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#validatorweight",children:(0,s.jsx)(n.code,{children:"ValidatorWeights"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsx)(n.p,{children:"A key granted limited permissions to an Account, for purposes such as multisig."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#weight",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"auctionstate",children:"AuctionState"}),"\n",(0,s.jsx)(n.p,{children:"Data structure summarizing auction contract data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_publickeyandbid",children:(0,s.jsx)(n.code,{children:"bids"})})," All bids contained within a vector."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," Block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsoneravalidators",children:(0,s.jsx)(n.code,{children:"era_validators"})})," Era validators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Global state hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsx)(n.p,{children:"An unbroken, inclusive range of blocks."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"high"})," The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"balanceholdwithproof",children:"BalanceHoldWithProof"}),"\n",(0,s.jsx)(n.p,{children:"Hold amount at a given block time."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The amount in the hold."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"proof"})," A string proof that the given value is present in the Merkle trie."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"time"})})," The block time at which the hold was created."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegators"})})," The validator's delegators, indexed by their public keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})," Vesting schedule for a genesis validator. ",(0,s.jsx)(n.code,{children:"None"})," if non-genesis validator."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bidkind",children:"BidKind"}),"\n",(0,s.jsx)(n.p,{children:"Auction bid variants."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unified"})," A unified record indexed on validator data, with an embedded collection of all delegator bids assigned to that validator. The `Unified`` variant is for legacy retrograde support; new instances will not be created going forward."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," A bid record containing only validator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," A bid record containing only delegator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Bridge"})," A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Credit"})," Credited amount."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv2",children:(0,s.jsx)(n.code,{children:"Version2"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hashes"})})," The deploy hashes of the non-transfer deploys within the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator that proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"transfer_hashes"})})," The deploy hashes of the transfers within the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv2",children:"BlockBodyV2"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#rewardedsignatures",children:(0,s.jsx)(n.code,{children:"rewarded_signatures"})})," List of identifiers for finality signatures for a particular past block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transactions"})})," Map of transactions mapping categories to a list of transaction hashes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockhash",children:"BlockHash"}),"\n",(0,s.jsxs)(n.p,{children:["A cryptographic hash identifying a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"blockheader",children:"BlockHeader"}),"\n",(0,s.jsxs)(n.p,{children:["The versioned header portion of a block. It encapsulates different variants of the ",(0,s.jsx)(n.code,{children:"BlockHeader"})," struct."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," The legacy, initial version of the header portion of a block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," The version 2 of the header portion of a block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv1",children:"BlockHeaderV1"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraendv1",children:(0,s.jsx)(n.code,{children:"era_end"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv2",children:"BlockHeaderV2"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})," A seed needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})," The hash of the block's body."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"current_gas_price"})," The gas price of the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})," The parent block's hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator which proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})," The protocol version of the network from when this block was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," The root hash of global state after the deploys in this block have been executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," The timestamp from when the block was proposed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraendv2",children:(0,s.jsx)(n.code,{children:"era_end"})})," The ",(0,s.jsx)(n.code,{children:"EraEnd"})," of a block if it is a switch block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"last_switch_block_hash"})})," The most recent switch block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"Hash"})})," Identify and retrieve the Block with its hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Height"})," Identify and retrieve the Block with its height."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockproof",children:"BlockProof"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a corresponding signature of a given block hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksynchronizerstatus",children:"BlockSynchronizerStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of the block synchronizer."}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Historical"})})," The status of syncing a historical block, if any."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Forward"})})," The status of syncing a forward block, if any."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of syncing an individual block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype wrapping a ",(0,s.jsx)(n.code,{children:"u64"}),", which represents the block time."]}),"\n",(0,s.jsx)(n.h2,{id:"blockv1",children:"BlockV1"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution with the resulting global state root hash prior to Casper 2.0. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv1",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockv2",children:"BlockV2"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution, with the resulting global state root hash. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv2",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bridge",children:"Bridge"}),"\n",(0,s.jsxs)(n.p,{children:["A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era when bridge record was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"old_validator_public_key"})})," Previous validator public key associated with the bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator_public_key"})})," New validator public key associated with the bid."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded bytes."}),"\n",(0,s.jsx)(n.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodekind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodehash",children:"ByteCodeHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a smart contract ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of byte code."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Empty"})," Empty byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"V1CasperWasm"})," Byte code to be executed with the version 1 Casper execution engine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytesreprerror",children:"BytesreprError"}),"\n",(0,s.jsx)(n.p,{children:"Serialization and deserialization errors."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EarlyEndOfStream"})," Early end of stream while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Formatting"})," Formatting error while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"LeftOverBytes"})," Not all input bytes were consumed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"OutOfMemory"})," Out of memory error."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NotRepresentable"})," No serialized representation is available for a value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ExceededRecursionDepth"})," Exceeded a recursion depth limit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspecrawbytes",children:"ChainspecRawBytes"}),"\n",(0,s.jsx)(n.p,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"chainspec_bytes"})})," Hex-encoded raw bytes of the current chainspec.toml file."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_genesis_accounts_bytes"})})," Hex-encoded raw bytes of the current genesis accounts.toml file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_global_state_bytes"})})," Hex-encoded raw bytes of the current global_state.toml file."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct that can be serialized as a JSON object."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackage",children:"ContractPackage"}),"\n",(0,s.jsx)(n.p,{children:"Contract definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract package."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the contract package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"ContractVersion"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameter:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract Wasm."}),"\n",(0,s.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee").'}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A Deploy; an item containing a smart contract along with the requester's signature(s)."}),"\n",(0,s.jsx)(n.p,{children:"Required properties:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployheader",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"session"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployhash",children:"DeployHash"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded Deploy hash."}),"\n",(0,s.jsx)(n.h2,{id:"deployheader",children:"DeployHeader"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"account"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"chain_name"})," A user defined string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"dependencies"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas_price"})," Defined as an integer in UInt64 format."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to the given Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," The relevant Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account identifier of the creator of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"gas"})})," Gas cost of executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse used for payment of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})," Transfers performed by the Deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionaryidentifier",children:"DictionaryIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Options for dictionary item lookups."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AccountNamedKey"})," Lookup a dictionary item via an Account's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The Account key as a formatted string whose named keys contain dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractNamedKey"})," Lookup a dictionary item via a Contract's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The contract key as a formatted string whose named keys contains dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"EntityNamedKey"})}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The entity address formatted as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," Lookup a dictionary item via its seed URef."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"seed_uref"})," The dictionary's seed URef."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Dictionary"})," Lookup a dictionary item via its unique key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded hash digest."}),"\n",(0,s.jsx)(n.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(n.p,{children:["A log of all ",(0,s.jsx)(n.a,{href:"#transformv2",children:"transforms"})," produced during execution."]}),"\n",(0,s.jsx)(n.h2,{id:"entityactionthresholds",children:"EntityActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"upgrade_management"})})," Threshold for upgrading contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityaddr",children:"EntityAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address for an AddressableEntity which contains the 32 bytes and tagging information."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address for a system entity account or contract."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to an Account."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to a user (non-system) smart contract."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeys",children:"EntityAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A collection of weighted public keys (represented as account hashes) associated with an account. See ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"Array_of_AssociatedKey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeyweight",children:"EntityAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an entity's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"entityidentifier",children:"EntityIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an addressable entity."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entitykind",children:"EntityKind"}),"\n",(0,s.jsxs)(n.p,{children:["The type of ",(0,s.jsx)(n.a,{href:"#package",children:(0,s.jsx)(n.code,{children:"Package"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#systementitytype",children:(0,s.jsx)(n.code,{children:"System"})})," Package associated with a native contract implementation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"Account"})})," Package associated with an Account hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"SmartContract"})})," Packages associated with Wasm stored on chain."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityoraccount",children:"EntityOrAccount"}),"\n",(0,s.jsx)(n.p,{children:"An addressable entity or a legacy account."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An addressable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," A legacy account."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionandhash",children:"EntityVersionAndHash"}),"\n",(0,s.jsx)(n.p,{children:"An entity version associated with the given hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#addressableentityhash",children:(0,s.jsx)(n.code,{children:"addressable_entity_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"entity_version_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"EntityVersion"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entity_version"})," Automatically incremented value for a contract version within a major ",(0,s.jsx)(n.code,{children:"ProtocolVersion"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," with which a ",(0,s.jsx)(n.code,{children:"ContractVersion"})," is compatible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint2",children:"EntryPoint2"}),"\n",(0,s.jsx)(n.p,{children:"Type signature of a method. Order of arguments matters since they can be referenced by index as well as their name."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointpayment",children:(0,s.jsx)(n.code,{children:"entry_point_payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The string name of the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointaccess",children:"EntryPointAccess"}),"\n",(0,s.jsx)(n.p,{children:"Enum describing the possible access control options for a contract entry point."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Public"})," A public entry point is callable by any caller."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"Groups"})})," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Template"})," A string type that can't be accessed directly but is kept in the derived Wasm bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointpayment",children:"EntryPointPayment"}),"\n",(0,s.jsx)(n.p,{children:"An enum specifying who pays for the invocation and execution of the entrypoint."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," The caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnly"})," The current execution will cover the cost to execute self but not the cost of any subsequently invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnward"})," The current execution will cover the cost to execute self and the cost of any subsequently invoked contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointtype",children:"EntryPointType"}),"\n",(0,s.jsxs)(n.p,{children:["Context of an entry point execution. The most significant bit represents the version. For example, ",(0,s.jsx)(n.code,{children:"0b0"})," represents session and contract entry points up to version 2.0. And, ",(0,s.jsx)(n.code,{children:"0b1"})," is for versions 2.x and later (i.e. installer and utility entry points)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," Runs using the calling entity's context. In v1.x, this was used for both session code that ran using the originating account's context and stored session code that ran in the caller's context. In v2.x, the renamed Caller variant is exclusively used for Wasm running using the initiating account entity's context. Previously installed 1.x stored session code should continue to work as the binary value matches, but we no longer allow such logic to be upgraded, nor do we allow new stored session code to be installed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Called"})," Runs within the called entity's context."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Factory"})," This entry point is intended to extract a subset of bytecode. Runs within the called entity's context."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointvalue",children:"EntryPointValue"}),"\n",(0,s.jsx)(n.p,{children:"The encaspulated representation of entrypoints."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint2",children:(0,s.jsx)(n.code,{children:"V1CasperVm"})})," Entrypoints to be executed against the V1 Casper VM."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypointv2",children:(0,s.jsx)(n.code,{children:"V2CasperVm"})})," Entrypoints to be executed against the V2 Casper VM."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointv2",children:"EntryPointV2"}),"\n",(0,s.jsx)(n.p,{children:"The entry point for the V2 Casper VM."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"flags"})," The flags as a uint32 integer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"function_index"})," The selector as a uint32 integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv1",children:"EraEndV1"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#erareport_for_publickey",children:(0,s.jsx)(n.code,{children:"era_report"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv2",children:"EraEndV2"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any units during the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"next_era_gas_price"})," The gas price for the next era as a ",(0,s.jsx)(n.code,{children:"uint8"})," integer. Minimum 0.0 motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})," The validators for the upcoming era and their respective weights."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"rewards"})})," The rewards distributed to the validators."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsx)(n.p,{children:"Era ID newtype."}),"\n",(0,s.jsx)(n.h2,{id:"eraidentifier",children:"EraIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for an era."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"Era"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockidentifier",children:(0,s.jsx)(n.code,{children:"Block"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsx)(n.p,{children:"Auction metadata. Intended to be recorded at each era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#seigniorageallocation",children:(0,s.jsx)(n.code,{children:"seigniorage_allocation"})})," Information about a seigniorage allocation."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareport_for_publickey",children:"EraReport_for_PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Equivocation, reward and validator inactivity information."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_erareward",children:(0,s.jsx)(n.code,{children:"rewards"})})," Rewards for finalization of earlier blocks."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any unit during the era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareward",children:"EraReward"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a measure of the value of its contribution to consensus, as a fraction of the configured maximum block reward."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The reward amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erasummary",children:"EraSummary"}),"\n",(0,s.jsx)(n.p,{children:"The summary of an era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The Block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#merkle-proof",children:(0,s.jsx)(n.code,{children:"merkle_proof"})})," The merkle proof."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"stored_value"})})," The StoredValue containing era information."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executabledeployitem",children:"ExecutableDeployItem"}),"\n",(0,s.jsx)(n.p,{children:"Represents possible variants of an executable Deploy."}),"\n",(0,s.jsx)(n.h2,{id:"executioninfo",children:"ExecutionInfo"}),"\n",(0,s.jsx)(n.p,{children:"The block hash and height in which a given deploy was executed, along with the execution result if known."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The hash of the block in which the deploy was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block in which the deploy was executed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#executionresult",children:(0,s.jsx)(n.code,{children:"execution_result"})})," The execution result if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(n.p,{children:"The journal of execution transforms from a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#operation",children:(0,s.jsx)(n.code,{children:"operations"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transformentry",children:(0,s.jsx)(n.code,{children:"transforms"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,s.jsx)(n.p,{children:"The versioned result of executing a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," Version 1 of execution result type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," Version 2 of execution result type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single deploy prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," The result of a failed execution"]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"error_message"})," The error message associated with executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Success"})," The result of a successful execution."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single transaction."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"consumed"})})," How much gas was consumed executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})," How much was paid for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#effects",children:(0,s.jsx)(n.code,{children:"effects"})})," The effects of executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator"})})," Who initiated this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"limit"})})," The maximum allowed gas limit for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#paymentinfo",children:(0,s.jsx)(n.code,{children:"payment"})})," Breakdown of payments made to cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"size_estimate"})," The size estimate of the transaction"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"transfers"})})," A record of transfers performed while executing this transaction."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"error_message"})," If there is no error message, this execution was processed successfully. If there is an error message, this execution failed to fully process for the stated reason."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Gas"})," struct represents a ",(0,s.jsx)(n.code,{children:"U512"})," amount of gas."]}),"\n",(0,s.jsx)(n.h2,{id:"globalstateidentifier",children:"GlobalStateIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to query global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"BlockHash"})})," Query using a block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"BlockHeight"})," Query using a block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"StateRootHash"})})," Query using the state root hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,s.jsx)(n.p,{children:'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'}),"\n",(0,s.jsx)(n.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address of the initiator of a transaction"}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"publickey"})})," The public key of the initiator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"accounthash"})})," The account hash derived from the public key of the initiator."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonblockwithsignatures",children:"JsonBlockWithSignatures"}),"\n",(0,s.jsx)(n.p,{children:"A JSON-friendly representation of a block and the signatures for that block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#block",children:(0,s.jsx)(n.code,{children:"block"})})," The block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_blockproof",children:(0,s.jsx)(n.code,{children:"proofs"})})," The proofs of the block, i.e. a collection of validators' signatures of the block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsoneravalidators",children:"JsonEraValidators"}),"\n",(0,s.jsx)(n.p,{children:"The validators for the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#jsonvalidatorsweights",children:(0,s.jsx)(n.code,{children:"validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorchanges",children:"JsonValidatorChanges"}),"\n",(0,s.jsx)(n.p,{children:"The changes in a validator's status."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})," The public key of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsonvalidatorstatuschange",children:(0,s.jsx)(n.code,{children:"status_changes"})})," The set of changes to the validator's status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorstatuschange",children:"JsonValidatorStatusChange"}),"\n",(0,s.jsx)(n.p,{children:"A single change to a validator's status in the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era in which the change occurred."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#validatorchange",children:(0,s.jsx)(n.code,{children:"validator_change"})})," The change in validator status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorsweights",children:"JsonValidatorsWeights"}),"\n",(0,s.jsx)(n.p,{children:"A validator's weight."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"key",children:"Key"}),"\n",(0,s.jsx)(n.p,{children:"The key as a formatted string, under which data can be stored in global state."}),"\n",(0,s.jsx)(n.h2,{id:"messagechecksum",children:"MessageChecksum"}),"\n",(0,s.jsx)(n.p,{children:"Message checksum as a formatted string."}),"\n",(0,s.jsx)(n.h2,{id:"messagetopic",children:"MessageTopic"}),"\n",(0,s.jsx)(n.p,{children:"A topic for contract-level messages."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name"})," A string used to identify the message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#topicnamehash",children:(0,s.jsx)(n.code,{children:"topic_name_hash"})})," The hash of the name of the message topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"messagetopicsummary",children:"MessageTopicSummary"}),"\n",(0,s.jsx)(n.p,{children:"Summary of a message topic that will be stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"blocktime"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"message_count"})," The number of messages in this topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"minimalblockinfo",children:"MinimalBlockInfo"}),"\n",(0,s.jsxs)(n.p,{children:["Minimal info of a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"creator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsx)(n.p,{children:"Named arguments to a contract."}),"\n",(0,s.jsx)(n.h2,{id:"namedentrypoint",children:"NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#entrypoint",children:"entry point"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," A string identifying the entry point."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsx)(n.p,{children:"A named key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The value of the entry: a casper ",(0,s.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeys",children:"NamedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#namedkey",children:"collection of named keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeyvalue",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"NamedKey"})," value."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"named_key"})," The actual ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedusergroup",children:"NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group_name"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"group_users"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nextupgrade",children:"NextUpgrade"}),"\n",(0,s.jsx)(n.p,{children:"Information about the next protocol upgrade."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#activationpoint",children:(0,s.jsx)(n.code,{children:"activation_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(n.p,{children:"An operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#opkind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"opkind",children:"OpKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Read"})," A read operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," A write operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Add"})," An addition."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NoOp"})," An operation which has no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," A prune operation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(n.p,{children:"Entity definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})," Collection of disabled entity versions. The runtime will not permit disabled entity versions to be executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})," Mapping maintaining the set of URefs associated with each user group, used to control access to methods in a particular version of the entity. A method is callable by any context which knows any of the URefs associated with the method's user group."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#packagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})," A flag that determines whether a entity is locked."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_entityversionandhash",children:(0,s.jsx)(n.code,{children:"versions"})})," All versions (enabled & disabled)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsx)(n.p,{children:"Parameter to an entry point."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"packagehash",children:"PackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"packagestatus",children:"PackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"paymentinfo",children:"PaymentInfo"}),"\n",(0,s.jsx)(n.p,{children:"Breakdown of payments made to cover the cost."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"source"})," Source purse used for payment of the transaction."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peerentry",children:"PeerEntry"}),"\n",(0,s.jsx)(n.p,{children:"Node peer entry."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"address"})," Node address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"node_id"})," Node ID."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peers",children:"Peers"}),"\n",(0,s.jsx)(n.p,{children:"Map of peer IDs to network addresses."}),"\n",(0,s.jsx)(n.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsx)(n.p,{children:"The pricing mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Classic"})," The original payment model, where the creator of the transaction specifies how much they will pay, at what gas price."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Fixed"})," The cost of the transaction is determined by the cost table, per the transaction category."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Reserved"})," The payment for this transaction was previously reserved (Not currently implemented)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsx)(n.p,{children:"Casper Platform protocol version."}),"\n",(0,s.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic public key, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"publickeyandbid",children:"PublicKeyAndBid"}),"\n",(0,s.jsx)(n.p,{children:"A bid associated with the given public key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"bid"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"publickeyanddelegator",children:"PublicKeyAndDelegator"}),"\n",(0,s.jsx)(n.p,{children:"A delegator associated with the given validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegator"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"purseidentifier",children:"PurseIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"The identifier of a purse."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_public_key"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_account_hash"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_entity_addr"})," The main purse of the account identified by this ",(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"purse_uref"})," A specific purse identified by the associated ",(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"reservationkind",children:"ReservationKind"}),"\n",(0,s.jsx)(n.p,{children:"Container for bytes recording location, type and data for a gas reservation."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"receipt"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"reservation_data"})})," Hex-encoded bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"reservation_kind"})," A ",(0,s.jsx)(n.code,{children:"uint8"})," integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rewardedsignatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["Describes finality signatures that will be rewarded in a block. Consists of a vector of ",(0,s.jsx)(n.a,{href:"#singleblockrewardedsignatures",children:(0,s.jsx)(n.code,{children:"SingleBlockRewardedSignatures"})}),", each of which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsx)(n.p,{children:"Represents a collection of arguments passed to a smart contract."}),"\n",(0,s.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(n.p,{children:"Information about a seigniorage allocation."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," Info about a seigniorage allocation for a validator."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," Info about a seigniorage allocation for a delegator."]}),"\n",(0,s.jsx)(n.p,{children:"Require Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})," Delegator's public key."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic signature, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"singleblockrewardedsignatures",children:"SingleBlockRewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["List of identifiers for finality signatures for a particular past block. That past block height is equal to ",(0,s.jsx)(n.code,{children:"current_height"})," minus ",(0,s.jsx)(n.code,{children:"signature_rewards_max_delay"}),", the latter being defined in the chainspec."]}),"\n",(0,s.jsx)(n.h2,{id:"storedvalue",children:"StoredValue"}),"\n",(0,s.jsx)(n.p,{children:"Representation of a value stored in global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})})," A Casper-specific value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," An Account."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractWasm"})," A contract's Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contract",children:(0,s.jsx)(n.code,{children:"Contract"})})," Entry points supported by a contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contractpackage",children:(0,s.jsx)(n.code,{children:"ContractPackage"})})," A contract definition, metadata, and security container."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"LegacyTransfer"})})," A version 1 (legacy) transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployinfo",children:(0,s.jsx)(n.code,{children:"DeployInfo"})})," A record of a Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})})," Information about an era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"Bid"})})," A bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Withdraw"})})," A withdraw."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Unbonding"})})," Unbonding information."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An AddressableEntity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bidkind",children:(0,s.jsx)(n.code,{children:"BidKind"})})," A variant that stored ",(0,s.jsx)(n.code,{children:"BidKind"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"Package"}),"] A ",(0,s.jsx)(n.code,{children:"Package"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"ByteCode"}),"] A record of byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagetopic",children:(0,s.jsx)(n.code,{children:"MessageTopic"})})," A variant that stores a message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagechecksum",children:(0,s.jsx)(n.code,{children:"Message"})})," A variant that stores a message digest."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"NamedKey"})})," A NamedKey record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#reservationkind",children:(0,s.jsx)(n.code,{children:"Reservation"})})," A reservation record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"EntryPoint"})})," An entrypoint record."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"systementitytype",children:"SystemEntityType"}),"\n",(0,s.jsx)(n.p,{children:"System contract types."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Mint"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"HandlePayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"StandardPayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Auction"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsx)(n.p,{children:"Human-readable duration."}),"\n",(0,s.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsx)(n.p,{children:"Timestamp formatted as per RFC 3339."}),"\n",(0,s.jsx)(n.h2,{id:"topicnamehash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hash of the name of the ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"message topic"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction or deploy."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy",children:(0,s.jsx)(n.code,{children:"deploy"})})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"or"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactionv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"An entry point of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Call"})," The standard ",(0,s.jsx)(n.code,{children:"call"})," entry point used in session code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Custom"})," A non-native, arbitrary entry point."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Transfer"})," The ",(0,s.jsx)(n.code,{children:"transfer"})," native entry point, used to reference motes from a source purse to a target purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddBid"})," The ",(0,s.jsx)(n.code,{children:"add_bid"})," native entry point, used to create or top off a bid purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WithdrawBid"})," The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," native entry point, used to decrease a validator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegate"})," The ",(0,s.jsx)(n.code,{children:"delegate"})," native entry point, used to add a new delegator or increase an existing delegator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Undelegate"})," The ",(0,s.jsx)(n.code,{children:"undelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Redelegate"})," The ",(0,s.jsx)(n.code,{children:"redelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero. After the unbonding delay, it will automatically delegate to a new validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ActivateBid"})," The ",(0,s.jsx)(n.code,{children:"activate_bid"})," native entry point, used to used to reactivate an inactive bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ChangeBidPublicKey"})," The ",(0,s.jsx)(n.code,{children:"change_bid_public_key"})," native entry point, used to change a bid's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction hash or deploy hash."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"Deploy"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1hash",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(n.p,{children:["The identifier of a ",(0,s.jsx)(n.code,{children:"stored"})," transaction target."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByHash"})," The hex-encoded entity address identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByName"})," The alias identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageHash"})," The address and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"addr"})," The hex-encoded address of the package."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageName"})," The alias and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," The package name."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsx)(n.p,{children:"Runtime used to execute a transaction."}),"\n",(0,s.jsx)(n.p,{children:"Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV1"})," The Casper Version 1 Virtual Machine."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV2"})," The Casper Version 2 Virtual Machine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsx)(n.p,{children:"The scheduling mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Standard"})," No special scheduling applied."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureEra"})," Execution should be scheduled for the specific era."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureEra"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"FutureEra"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureTimestamp"})," Execution should be scheduled for the specific timestamp or later."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureTimestamp"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"FutureTimestamp"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsx)(n.p,{children:"The execution target of a Transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native"})," The execution target is a native operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stored"})," The execution target is a stored entity or package."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"stored"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(n.code,{children:"id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session"})," The execution target is the included module bytes."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"session"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"module_bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1",children:"TransactionV1"}),"\n",(0,s.jsx)(n.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1body",children:(0,s.jsx)(n.code,{children:"body"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1hash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1header",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsx)(n.p,{children:"The body of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#runtimeargs",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionscheduling",children:(0,s.jsx)(n.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactiontarget",children:(0,s.jsx)(n.code,{children:"target"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(n.p,{children:"A hex-encoded TransactionV1 hash."}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"chain_name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator_addr"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#pricingmode",children:(0,s.jsx)(n.code,{children:"pricing_mode"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transfer",children:"Transfer"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transfer."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," A version 1 transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," A version 2 transfer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded version 1 transfer address."}),"\n",(0,s.jsx)(n.h2,{id:"transferv1",children:"TransferV1"}),"\n",(0,s.jsx)(n.p,{children:"Represents a transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," Deploy that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferv2",children:"TransferV2"}),"\n",(0,s.jsx)(n.p,{children:"Represents a version 2 transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transaction_hash"})})," Transaction that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"from"})})," Entity from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformerror",children:"TransformError"}),"\n",(0,s.jsxs)(n.p,{children:["Error type for applying and combining transforms. A ",(0,s.jsx)(n.code,{children:"TypeMismatch"})," occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytesreprerror",children:(0,s.jsx)(n.code,{children:"serialization"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#typemismatch",children:(0,s.jsx)(n.code,{children:"typemismatch"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deprecated"})," Type no longer supported."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv1",children:"TransformV1"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv1",children:(0,s.jsx)(n.code,{children:"transforms"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv2",children:"TransformV2"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv2",children:(0,s.jsx)(n.code,{children:"kind"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv1",children:"TransformKindV1"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 1."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteCLValue"})," Writes the given CLValue to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAccount"})," Writes the given Account to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractWasm"})," Writes a smart contract as Wasm to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContract"})," Writes a smart contract to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractPackage"})," Writes a smart contract package to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteDeployInfo"})," Writes the given DeployInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteEraInfo"})," Writes the given EraInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteTransfer"})," Writes the given Transfer to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBid"})," Writes the given Bid to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteWithdraw"})," Writes the given Withdraw to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteUnbonding"})," Writes the given Unbonding to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAddressableEntity"})," Writes the addressable entity to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBidKind"})," Writes the given BidKind to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv2",children:"TransformKindV2"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 2."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," Writes the new value in global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"typemismatch",children:"TypeMismatch"}),"\n",(0,s.jsxs)(n.p,{children:["An error struct representing a type mismatch in ",(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"StoredValue"})})," operations."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"expected"})," The name of the expected type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"found"})," The actual type found."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"u128",children:"U128"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 128-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u256",children:"U256"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 256-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u512",children:"U512"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 512-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(n.p,{children:"Unbonding purse."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator"})})," The redelegated validator's public key."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded, formatted URef."}),"\n",(0,s.jsx)(n.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if the validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"maximum_delegation_amount"})," Minimum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"minimum_delegation_amount"})," Maximum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorchange",children:"ValidatorChange"}),"\n",(0,s.jsx)(n.p,{children:"A change to a validator's status between two eras."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Added"})," The validator was just added to the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Removed"})," The validator was removed from the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Banned"})," The validator was banned from this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CannotPropose"})," The validator was excluded from proposing new blocks in this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SeenAsFaulty"})," We saw the validator misbehave in this era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorcredit",children:"ValidatorCredit"}),"\n",(0,s.jsx)(n.p,{children:"Validator credit record."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The credit amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorweight",children:"ValidatorWeight"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with its weight, i.e. the total number of motes it staked together with its delegators."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"vestingschedule",children:"VestingSchedule"}),"\n",(0,s.jsx)(n.p,{children:"Vesting schedule for a genesis validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"initial_release_timestamp_millies"})," Timestamp of the initial release."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"locked_amounts"})})," The amount of locked motes."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsx)(n.p,{children:"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(t,{...e})}):t(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>c});var s=i(96540);const r={},d=s.createContext(r);function l(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/60fa9972.532892dc.js b/assets/js/60fa9972.532892dc.js new file mode 100644 index 000000000..8b145aa8a --- /dev/null +++ b/assets/js/60fa9972.532892dc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[56215],{44881:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=t(74848),r=t(28453);const a={title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"},o="Listing CSPR on an Exchange",i={id:"resources/advanced/list-cspr",title:"Listing CSPR",description:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/list-cspr.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/list-cspr",permalink:"/1.5.X/resources/tutorials/advanced/list-cspr",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726495933e3,frontMatter:{title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"}},c={},d=[{value:"Setting up a Node",id:"setting-up-a-node",level:2},{value:"Casper Account",id:"casper-account",level:2},{value:"Understanding Basic Transactions",id:"understanding-basic-transactions",level:2},{value:"Native transfer",id:"native-transfer",level:3},{value:"Bulk or batched Wasm transfer",id:"bulk-or-batched-wasm-transfer",level:3},{value:"Integrating CSPR",id:"integrating-cspr",level:2},{value:"Testing the Integration",id:"testing-the-integration",level:2},{value:"The Casper Protocol",id:"the-casper-protocol",level:2},{value:"Staking Integration for Exchanges",id:"staking-integration-for-exchanges",level:2},{value:"Deploy Structures and Parameters",id:"deploy-structures-and-parameters",level:3},{value:"1. Creating a deploy object",id:"1-creating-a-deploy-object",level:4},{value:"2a. Sign the deploy (Casper Signer)",id:"2a-sign-the-deploy-casper-signer",level:4},{value:"2b. Sign the deploy (Ledger)",id:"2b-sign-the-deploy-ledger",level:4},{value:"Costs and Minimums",id:"costs-and-minimums",level:3},{value:"The Delegation Cap",id:"the-delegation-cap",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"listing-cspr-on-an-exchange",children:"Listing CSPR on an Exchange"})}),"\n",(0,s.jsx)(n.p,{children:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-a-node",children:"Setting up a Node"}),"\n",(0,s.jsxs)(n.p,{children:["While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see ",(0,s.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration",children:"Basic Node Setup"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions."}),"\n",(0,s.jsx)(n.h2,{id:"casper-account",children:"Casper Account"}),"\n",(0,s.jsxs)(n.p,{children:["You will need a Casper Account to handle the transactions on an exchange. Casper has an ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Account model"})," and instructions on how to ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-creating",children:"create an Account"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users."}),"\n",(0,s.jsx)(n.h2,{id:"understanding-basic-transactions",children:"Understanding Basic Transactions"}),"\n",(0,s.jsx)(n.p,{children:"We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice."}),"\n",(0,s.jsx)(n.p,{children:"Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others."}),"\n",(0,s.jsx)(n.h3,{id:"native-transfer",children:"Native transfer"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"payment"})," field describes how we are paying for the deploy, in this case a native transfer, while the ",(0,s.jsx)(n.code,{children:"session"})," field describes the actual transfer."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Native Transfer Deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n"id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "approvals": [\n {\n "signature": "130 chars",\n "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"\n }\n ],\n "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713",\n "header": {\n "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e",\n "chain_name": "casper-net-1",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2021-04-20T18:04:40.333Z",\n "ttl": "1h"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "021027",\n "cl_type": "U512",\n "parsed": "10000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668",\n "cl_type": {\n "ByteArray": 32\n },\n "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668"\n }\n ],\n [\n "id",\n {\n "bytes": "00",\n "cl_type": {\n "Option": "U64"\n },\n "parsed": null\n }\n ]\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/direct-token-transfer",children:"Direct Token Transfer"}),". The following command transfers 10 CSPR from ",(0,s.jsx)(n.em,{children:"account A's main purse"})," to ",(0,s.jsx)(n.em,{children:"account B's main purse"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id 1 \\\n--transfer-id 123456 \\\n--node-address http://<node-ip-address>:7777 \\\n--amount 10000000000 \\\n--secret-key <accountA-secret-key>.pem \\\n--chain-name casper \\\n--target-account <accountB-hex-encoded-public-key> \\\n--payment-amount <payment-in-motes>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The payment amount varies based on the deploy and network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". For node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes."]}),"\n",(0,s.jsx)(n.h3,{id:"bulk-or-batched-wasm-transfer",children:"Bulk or batched Wasm transfer"}),"\n",(0,s.jsxs)(n.p,{children:["Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html",children:"Rust contract API"}),", which can be used in session code to achieve batched Wasm transfer:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_account"}),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_public_key"}),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_purse"}),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_public_key"}),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_account"}),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on how to write session code, see ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),". There are equivalent ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305",children:"assembly script"})," methods available. Alternatively, you can program directly against the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370",children:"ext-FFI"})," methods."]}),"\n",(0,s.jsx)(n.h2,{id:"integrating-cspr",children:"Integrating CSPR"}),"\n",(0,s.jsxs)(n.p,{children:["You can integrate with the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/",children:"JSON-RPC API"})," of a node on the Casper Mainnet.\nYou can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,s.jsx)(n.a,{href:"/1.5.X/sdk",children:"SDK Libraries"}),".\nCasper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-integration",children:"Testing the Integration"}),"\n",(0,s.jsxs)(n.p,{children:["Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", then you can do so with your own test accounts."]}),"\n",(0,s.jsx)(n.p,{children:"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-protocol",children:"The Casper Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."}),"\n",(0,s.jsxs)(n.li,{children:["Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Execution Semantics"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"staking-integration-for-exchanges",children:"Staking Integration for Exchanges"}),"\n",(0,s.jsxs)(n.p,{children:["Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"})," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,s.jsx)(n.a,{href:"/1.5.X/staking",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-structures-and-parameters",children:"Deploy Structures and Parameters"}),"\n",(0,s.jsx)(n.p,{children:"Staking operations consists of two parts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Creating a deploy object"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/signing-a-deploy",children:"Signing the deploy"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The staking deploy requires the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The delegator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The validator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The new validator's public key (For redelegation only)"}),"\n",(0,s.jsx)(n.li,{children:"The amount to be delegated"}),"\n",(0,s.jsx)(n.li,{children:"The gas cost"}),"\n",(0,s.jsx)(n.li,{children:"The auction manager contract's hash"}),"\n",(0,s.jsx)(n.li,{children:"The appropriate entry point"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate",children:"Delegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate",children:"Undelegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate",children:"Redelegate"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-creating-a-deploy-object",children:"1. Creating a deploy object"}),"\n",(0,s.jsxs)(n.p,{children:["To create a deploy using the JavaScript SDK, we will need ",(0,s.jsx)(n.code,{children:"deployParams"}),", ",(0,s.jsx)(n.code,{children:"session"})," and a ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Deploy params is a ",(0,s.jsx)(n.code,{children:"DeployUtil.DeployParams"})," object created from the delegator's ",(0,s.jsx)(n.code,{children:"publicKey"})," and the network name as shown in the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For creating a ",(0,s.jsx)(n.code,{children:"session"})," object, which is ",(0,s.jsx)(n.code,{children:"DeployUtil.ExecutableDeployItem"}),", we need"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"delegator"})," and ",(0,s.jsx)(n.strong,{children:"validator's public keys"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"amount"})," of tokens to delegate/undelegate/redelgate"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"auction manager contract's hash"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["First, create a variable ",(0,s.jsx)(n.code,{children:"RuntimeArgs"})," from the public keys and the amount. We will need to use it below in ",(0,s.jsx)(n.code,{children:"session"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Second, create a ",(0,s.jsx)(n.code,{children:"session"})," parameter. It is a ",(0,s.jsx)(n.code,{children:"Uint8Array"})," consisting of the ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"}),", the ",(0,s.jsx)(n.code,{children:"entry points"})," and ",(0,s.jsx)(n.code,{children:"runtime arguments"}),", which we previously created."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"})," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Mainnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Testnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Your ",(0,s.jsx)(n.code,{children:"entry point"})," will depend on which action you are performing, with the following three available:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegate"})," - Initial delegation to a validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"undelegate"})," - Undelegating tokens from a validator back to the delegator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"redelegate"})," - Redelegating tokens to a new validator"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the ",(0,s.jsx)(n.code,{children:"payment"})," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml",children:(0,s.jsx)(n.code,{children:"chainspec for version 1.4.8"})}),". You will need the chainspec for the network version you are using."]}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"DeployUtil.standardPayment"})," method for creating ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n"})}),"\n",(0,s.jsx)(n.p,{children:"The last operation is creating the deploy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Redelegation"}),", occurs the same way as delegation, but with the introduction of a third public_key."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2a-sign-the-deploy-casper-signer",children:"2a. Sign the deploy (Casper Signer)"}),"\n",(0,s.jsxs)(n.p,{children:["To get the signature, you will need to use ",(0,s.jsx)(n.code,{children:"Signer.sign"})," from the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"}),". It will return ",(0,s.jsx)(n.code,{children:"Promise<{ deploy }>"}),", which is the signed object."]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"DeployUtil.deployFromJson"})," to convert the result and sent it to network with:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2b-sign-the-deploy-ledger",children:"2b. Sign the deploy (Ledger)"}),"\n",(0,s.jsxs)(n.p,{children:["You will need to connect with your ",(0,s.jsx)(n.code,{children:"Ledger"})," first to get the signature."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Signature will be in a property called ",(0,s.jsx)(n.code,{children:"res.signatureRS"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After that, we can create a signed deploy,"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can then send it to a network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"casperService.deploy(signedDeploy)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-minimums",children:"Costs and Minimums"}),"\n",(0,s.jsxs)(n.p,{children:["The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Transfer Cost: 100,000,000 motes or 0.1 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,s.jsx)(n.strong,{children:"CSPR"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"the-delegation-cap",children:"The Delegation Cap"}),"\n",(0,s.jsxs)(n.p,{children:["Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,s.jsx)(n.code,{children:"953"}),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."]}),"\n",(0,s.jsxs)(n.p,{children:["Validators with a delegator count at or above ",(0,s.jsx)(n.code,{children:"953"})," at the time of the ",(0,s.jsx)(n.strong,{children:"1.4.5"})," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,s.jsx)(n.code,{children:"953"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,s.jsx)(n.strong,{children:"CSPR"})," to that validator. However, no new delegators may join the validator until it drops below the ",(0,s.jsx)(n.code,{children:"953"})," limit."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/60fa9972.b69bb4a6.js b/assets/js/60fa9972.b69bb4a6.js deleted file mode 100644 index 086e56685..000000000 --- a/assets/js/60fa9972.b69bb4a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6215],{44881:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=t(74848),r=t(28453);const a={title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"},o="Listing CSPR on an Exchange",i={id:"resources/advanced/list-cspr",title:"Listing CSPR",description:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/list-cspr.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/list-cspr",permalink:"/resources/tutorials/advanced/list-cspr",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"}},c={},d=[{value:"Setting up a Node",id:"setting-up-a-node",level:2},{value:"Casper Account",id:"casper-account",level:2},{value:"Understanding Basic Transactions",id:"understanding-basic-transactions",level:2},{value:"Native transfer",id:"native-transfer",level:3},{value:"Bulk or batched Wasm transfer",id:"bulk-or-batched-wasm-transfer",level:3},{value:"Integrating CSPR",id:"integrating-cspr",level:2},{value:"Testing the Integration",id:"testing-the-integration",level:2},{value:"The Casper Protocol",id:"the-casper-protocol",level:2},{value:"Staking Integration for Exchanges",id:"staking-integration-for-exchanges",level:2},{value:"Deploy Structures and Parameters",id:"deploy-structures-and-parameters",level:3},{value:"1. Creating a deploy object",id:"1-creating-a-deploy-object",level:4},{value:"2a. Sign the deploy (Casper Signer)",id:"2a-sign-the-deploy-casper-signer",level:4},{value:"2b. Sign the deploy (Ledger)",id:"2b-sign-the-deploy-ledger",level:4},{value:"Costs and Minimums",id:"costs-and-minimums",level:3},{value:"The Delegation Cap",id:"the-delegation-cap",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"listing-cspr-on-an-exchange",children:"Listing CSPR on an Exchange"})}),"\n",(0,s.jsx)(n.p,{children:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-a-node",children:"Setting up a Node"}),"\n",(0,s.jsxs)(n.p,{children:["While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see ",(0,s.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic Node Setup"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions."}),"\n",(0,s.jsx)(n.h2,{id:"casper-account",children:"Casper Account"}),"\n",(0,s.jsxs)(n.p,{children:["You will need a Casper Account to handle the transactions on an exchange. Casper has an ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account model"})," and instructions on how to ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-creating",children:"create an Account"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users."}),"\n",(0,s.jsx)(n.h2,{id:"understanding-basic-transactions",children:"Understanding Basic Transactions"}),"\n",(0,s.jsx)(n.p,{children:"We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice."}),"\n",(0,s.jsx)(n.p,{children:"Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others."}),"\n",(0,s.jsx)(n.h3,{id:"native-transfer",children:"Native transfer"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"payment"})," field describes how we are paying for the deploy, in this case a native transfer, while the ",(0,s.jsx)(n.code,{children:"session"})," field describes the actual transfer."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Native Transfer Deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n"id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "approvals": [\n {\n "signature": "130 chars",\n "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"\n }\n ],\n "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713",\n "header": {\n "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e",\n "chain_name": "casper-net-1",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2021-04-20T18:04:40.333Z",\n "ttl": "1h"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "021027",\n "cl_type": "U512",\n "parsed": "10000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668",\n "cl_type": {\n "ByteArray": 32\n },\n "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668"\n }\n ],\n [\n "id",\n {\n "bytes": "00",\n "cl_type": {\n "Option": "U64"\n },\n "parsed": null\n }\n ]\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Direct Token Transfer"}),". The following command transfers 10 CSPR from ",(0,s.jsx)(n.em,{children:"account A's main purse"})," to ",(0,s.jsx)(n.em,{children:"account B's main purse"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id 1 \\\n--transfer-id 123456 \\\n--node-address http://<node-ip-address>:7777 \\\n--amount 10000000000 \\\n--secret-key <accountA-secret-key>.pem \\\n--chain-name casper \\\n--target-account <accountB-hex-encoded-public-key> \\\n--payment-amount <payment-in-motes>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The payment amount varies based on the deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes."]}),"\n",(0,s.jsx)(n.h3,{id:"bulk-or-batched-wasm-transfer",children:"Bulk or batched Wasm transfer"}),"\n",(0,s.jsxs)(n.p,{children:["Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html",children:"Rust contract API"}),", which can be used in session code to achieve batched Wasm transfer:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_account"}),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_public_key"}),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_purse"}),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_public_key"}),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_account"}),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on how to write session code, see ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),". There are equivalent ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305",children:"assembly script"})," methods available. Alternatively, you can program directly against the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370",children:"ext-FFI"})," methods."]}),"\n",(0,s.jsx)(n.h2,{id:"integrating-cspr",children:"Integrating CSPR"}),"\n",(0,s.jsxs)(n.p,{children:["You can integrate with the ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/",children:"JSON-RPC API"})," of a node on the Casper Mainnet.\nYou can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,s.jsx)(n.a,{href:"/sdk",children:"SDK Libraries"}),".\nCasper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-integration",children:"Testing the Integration"}),"\n",(0,s.jsxs)(n.p,{children:["Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", then you can do so with your own test accounts."]}),"\n",(0,s.jsx)(n.p,{children:"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-protocol",children:"The Casper Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."}),"\n",(0,s.jsxs)(n.li,{children:["Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Execution Semantics"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"staking-integration-for-exchanges",children:"Staking Integration for Exchanges"}),"\n",(0,s.jsxs)(n.p,{children:["Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"})," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,s.jsx)(n.a,{href:"/staking/",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-structures-and-parameters",children:"Deploy Structures and Parameters"}),"\n",(0,s.jsx)(n.p,{children:"Staking operations consists of two parts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"Creating a deploy object"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/dapps/signing-a-deploy",children:"Signing the deploy"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The staking deploy requires the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The delegator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The validator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The new validator's public key (For redelegation only)"}),"\n",(0,s.jsx)(n.li,{children:"The amount to be delegated"}),"\n",(0,s.jsx)(n.li,{children:"The gas cost"}),"\n",(0,s.jsx)(n.li,{children:"The auction manager contract's hash"}),"\n",(0,s.jsx)(n.li,{children:"The appropriate entry point"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate",children:"Delegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate",children:"Undelegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate",children:"Redelegate"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-creating-a-deploy-object",children:"1. Creating a deploy object"}),"\n",(0,s.jsxs)(n.p,{children:["To create a deploy using the JavaScript SDK, we will need ",(0,s.jsx)(n.code,{children:"deployParams"}),", ",(0,s.jsx)(n.code,{children:"session"})," and a ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Deploy params is a ",(0,s.jsx)(n.code,{children:"DeployUtil.DeployParams"})," object created from the delegator's ",(0,s.jsx)(n.code,{children:"publicKey"})," and the network name as shown in the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For creating a ",(0,s.jsx)(n.code,{children:"session"})," object, which is ",(0,s.jsx)(n.code,{children:"DeployUtil.ExecutableDeployItem"}),", we need"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"delegator"})," and ",(0,s.jsx)(n.strong,{children:"validator's public keys"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"amount"})," of tokens to delegate/undelegate/redelgate"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"auction manager contract's hash"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["First, create a variable ",(0,s.jsx)(n.code,{children:"RuntimeArgs"})," from the public keys and the amount. We will need to use it below in ",(0,s.jsx)(n.code,{children:"session"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Second, create a ",(0,s.jsx)(n.code,{children:"session"})," parameter. It is a ",(0,s.jsx)(n.code,{children:"Uint8Array"})," consisting of the ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"}),", the ",(0,s.jsx)(n.code,{children:"entry points"})," and ",(0,s.jsx)(n.code,{children:"runtime arguments"}),", which we previously created."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"})," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Mainnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Testnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Your ",(0,s.jsx)(n.code,{children:"entry point"})," will depend on which action you are performing, with the following three available:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegate"})," - Initial delegation to a validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"undelegate"})," - Undelegating tokens from a validator back to the delegator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"redelegate"})," - Redelegating tokens to a new validator"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the ",(0,s.jsx)(n.code,{children:"payment"})," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml",children:(0,s.jsx)(n.code,{children:"chainspec for version 1.4.8"})}),". You will need the chainspec for the network version you are using."]}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"DeployUtil.standardPayment"})," method for creating ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n"})}),"\n",(0,s.jsx)(n.p,{children:"The last operation is creating the deploy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Redelegation"}),", occurs the same way as delegation, but with the introduction of a third public_key."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2a-sign-the-deploy-casper-signer",children:"2a. Sign the deploy (Casper Signer)"}),"\n",(0,s.jsxs)(n.p,{children:["To get the signature, you will need to use ",(0,s.jsx)(n.code,{children:"Signer.sign"})," from the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"}),". It will return ",(0,s.jsx)(n.code,{children:"Promise<{ deploy }>"}),", which is the signed object."]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"DeployUtil.deployFromJson"})," to convert the result and sent it to network with:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2b-sign-the-deploy-ledger",children:"2b. Sign the deploy (Ledger)"}),"\n",(0,s.jsxs)(n.p,{children:["You will need to connect with your ",(0,s.jsx)(n.code,{children:"Ledger"})," first to get the signature."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Signature will be in a property called ",(0,s.jsx)(n.code,{children:"res.signatureRS"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After that, we can create a signed deploy,"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can then send it to a network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"casperService.deploy(signedDeploy)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-minimums",children:"Costs and Minimums"}),"\n",(0,s.jsxs)(n.p,{children:["The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Transfer Cost: 100,000,000 motes or 0.1 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,s.jsx)(n.strong,{children:"CSPR"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"the-delegation-cap",children:"The Delegation Cap"}),"\n",(0,s.jsxs)(n.p,{children:["Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,s.jsx)(n.code,{children:"953"}),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."]}),"\n",(0,s.jsxs)(n.p,{children:["Validators with a delegator count at or above ",(0,s.jsx)(n.code,{children:"953"})," at the time of the ",(0,s.jsx)(n.strong,{children:"1.4.5"})," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,s.jsx)(n.code,{children:"953"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,s.jsx)(n.strong,{children:"CSPR"})," to that validator. However, no new delegators may join the validator until it drops below the ",(0,s.jsx)(n.code,{children:"953"})," limit."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61415b83.6de3dfdc.js b/assets/js/61415b83.6de3dfdc.js new file mode 100644 index 000000000..a1b7bc864 --- /dev/null +++ b/assets/js/61415b83.6de3dfdc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70687],{12099:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>t,contentTitle:()=>d,default:()=>o,frontMatter:()=>l,metadata:()=>c,toc:()=>a});var s=n(74848),r=n(28453);const l={},d="Type Serialization",c={id:"concepts/serialization/types",title:"Type Serialization",description:"Account Action Thresholds",source:"@site/versioned_docs/version-2.0.0/concepts/serialization/types.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/types",permalink:"/2.0.0/concepts/serialization/types",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Major Structures",permalink:"/2.0.0/concepts/serialization/structures"},next:{title:"dApps",permalink:"/2.0.0/concepts/intro-to-dapps"}},t={},a=[{value:"Account Action Thresholds",id:"account-action-thresholds",level:2},{value:"Account Config",id:"account-config",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Account Identifier",id:"account-identifier",level:2},{value:"Activation Point",id:"activation-point",level:2},{value:"AddressableEntityHash",id:"addressable-entity-hash",level:2},{value:"Approval",id:"approval",level:2},{value:"ApprovalsHash",id:"approvals-hash",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldAddr",id:"balanceholdaddr",level:2},{value:"BalanceHoldAddrTag",id:"balanceholdaddrtag",level:2},{value:"BalanceResponse",id:"balance-response",level:2},{value:"Bid",id:"bid",level:2},{value:"BidAddr",id:"bidaddr",level:2},{value:"BidKind",id:"bid-kind",level:2},{value:"BlockGlobalAddr",id:"blockglobaladdr",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockSignatures",id:"block-signatures",level:2},{value:"BlockSignaturesV1",id:"block-signatures-v1",level:3},{value:"BlockSignaturesV2",id:"block-signatures-v2",level:3},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BTreeMap",id:"btreemap",level:2},{value:"BTreeSet",id:"btreeset",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"Caller",id:"caller",level:2},{value:"CallStackElement",id:"call-stack-element",level:2},{value:"ChainNameDigest",id:"chain-name-digest",level:2},{value:"ChainspecRegistry",id:"chainspecregistry",level:2},{value:"ChecksumRegistry",id:"checksum-registry",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"Effects",id:"effects",level:2},{value:"Entity Action Thresholds",id:"entity-action-thresholds",level:2},{value:"EntityAddr",id:"entity-addr",level:2},{value:"EntityKind",id:"entity-kind",level:2},{value:"EntityKindTag",id:"entity-kind-tag",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntityVersions",id:"entity-versions",level:2},{value:"EntryPoint (Contract)",id:"entrypoint",level:2},{value:"EntryPoint (Entity)",id:"entry-point",level:2},{value:"EntryPointAddr",id:"entrypointaddr",level:3},{value:"EntrypointPayment",id:"entrypointpayment",level:3},{value:"EntrypointType",id:"entrypointtype",level:3},{value:"EntrypointV2",id:"entrypointv2",level:2},{value:"EntryPoints",id:"entrypoints",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"ExecutableDeployItem",id:"executable-deploy-item",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"<code>Failure</code>",id:"failure",level:3},{value:"<code>Success</code>",id:"success",level:3},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"<code>Failure</code>",id:"failure-1",level:3},{value:"<code>Success</code>",id:"success-1",level:3},{value:"Gas",id:"gas",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account Identity Key",id:"global-state-account-key",level:3},{value:"Hash Key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (<code>URef</code>)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for <code>Key</code>",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:3},{value:"MessageTopics",id:"message-topics",level:2},{value:"MessageTopicSummary",id:"message-topic-summary",level:2},{value:"Motes",id:"motes",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeyAddr",id:"named-key-addr",level:2},{value:"NamedKeyValue",id:"named-key-value",level:2},{value:"NamedKeys",id:"named-keys",level:2},{value:"Operation",id:"operation",level:2},{value:"Package",id:"package",level:2},{value:"PackageHash",id:"package-hash",level:2},{value:"PackageStatus",id:"package-status",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"Classic",id:"pricingmode-classic",level:3},{value:"Fixed",id:"pricingmode-fixed",level:3},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RewardedSignatures",id:"rewarded-signatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"SemVer",id:"semver",level:2},{value:"Signature",id:"signature",level:2},{value:"Stored Values",id:"serialization-standard-values",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"SystemEntityType",id:"system-entity-type",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topic-name-hash",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransformKindV1",id:"transformkindV1",level:2},{value:"TransformKindV2",id:"transformkindV2",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"TransformV1",id:"transformV1",level:2},{value:"Transformv2",id:"transformV2",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validator-change",level:2},{value:"ValidatorConfig",id:"validator-config",level:2},{value:"ValidatorCredit",id:"validator-credit",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function h(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.header,{children:(0,s.jsx)(i.h1,{id:"type-serialization",children:"Type Serialization"})}),"\n",(0,s.jsx)(i.h2,{id:"account-action-thresholds",children:"Account Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-config",children:"Account Config"}),"\n",(0,s.jsxs)(i.p,{children:["Configuration of an individual account in ",(0,s.jsx)(i.em,{children:"accounts.toml"}),", containing the account's public key, main purse balance and validator config."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"public_key"})," The public key of the account, serialized as the byte representation of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:"itself"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance"})," The balance of the account's main purse, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512 value"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator"})," The validator configuration for the account, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."]}),"\n",(0,s.jsx)(i.h2,{id:"account-identifier",children:"Account Identifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve an Account. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),": The account's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),": The ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the account's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"activation-point",children:"Activation Point"}),"\n",(0,s.jsxs)(i.p,{children:["The first era to which the associated protocol version applies. It serializes as a single ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,s.jsx)(i.code,{children:"timestamp"}),". If not, the bytes represent an ",(0,s.jsx)(i.code,{children:"era_id"}),"."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_id"}),": An ",(0,s.jsx)(i.a,{href:"#eraid",children:"Era ID newtype"})," identifying the era when the protocol version will activate."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A ",(0,s.jsx)(i.a,{href:"#timestamp",children:"timestamp"})," if the activation point is of the Genesis variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"addressable-entity-hash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(i.p,{children:"The hex-encoded address of an addressable entity, which serializes as the byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(i.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"Signature"})}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(i.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(i.a,{href:"#digest",children:(0,s.jsx)(i.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"account_hash"}),": The ",(0,s.jsx)(i.a,{href:"#account-hash",children:"account hash"})," of the associated key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"weight"}),": The weight of an associated key. The weight serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsxs)(i.p,{children:["An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," values"]})," containing the following two fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"low"}),": The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"high"}),": - The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddr",children:"BalanceHoldAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A balance hold address. It serializes as a ",(0,s.jsx)(i.a,{href:"#balanceholdaddrtag",children:(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})})," describing the type of balance hold address as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Gas"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Processing"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddrtag",children:"BalanceHoldAddrTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag describing the type of ",(0,s.jsx)(i.code,{children:"BalanceHoldAddr"}),", serializing as a single ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"balance-response",children:"BalanceResponse"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BalanceResponse"})," is a struct that provides the response to a balance query. It consists of the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance"}),": The purse's total balance, not considering holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"available_balance"}),": The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance_proof"}),": A proof that the given value is present in the Merkle trie. It serializes as a ",(0,s.jsx)(i.code,{children:"TrieMerkleProof"}),", consisting of a key, a value and a ",(0,s.jsx)(i.code,{children:"proof_step"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance_holds"}),": Any time-relevant active holds on the balance. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"BlockTime"})," and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"BlockTime"}),"s and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"}),"s of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The validator's public key. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The purse used for bonding. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"Uref"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate of the bid. It serializes as an ",(0,s.jsx)(i.code,{children:"i32"})," signed 32-bit integer primitive."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for a genesis validator. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegators"}),": The validator's delegators, indexed by their public keys. They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and then delegators of the length dictated by the first four bytes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": If the validator has been evicted. A ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-boolean",children:"boolean"})," value that serializes as a single byte; ",(0,s.jsx)(i.code,{children:"true"})," maps to ",(0,s.jsx)(i.code,{children:"1"}),", while ",(0,s.jsx)(i.code,{children:"false"})," maps to ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bidaddr",children:"BidAddr"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," manages data associated with bids for the ",(0,s.jsx)(i.code,{children:"Auction"})," system contract. It serializes as a single ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Unified"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," for legacy unified bids. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," identifying the legacy bid."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Validator"})," A validator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," A delegator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the associated validator and then the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the delegator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Credit"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," representing an auction credit. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"4"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator and the ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," for the applicable credit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid-kind",children:"BidKind"}),"\n",(0,s.jsxs)(i.p,{children:["Auction bid variants. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]})," indicating the type of bid kind as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"BidKind"}),(0,s.jsx)(i.th,{children:"u8"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#bid",children:"Unified"})}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Legacy data that contains all delegators for a given validator."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#validatorbid",children:"Validator"})}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"A bid record containing only validator data."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#delegatorbid",children:"Delegator"})}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"A bid record containing only delegator data."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"blockglobaladdr",children:"BlockGlobalAddr"}),"\n",(0,s.jsx)(i.p,{children:"An address for singleton values associated to a specific block. These are values which are calculated or set during the execution of a block such as the block timestamp, or the total count of messages emitted during the execution of the block."}),"\n",(0,s.jsxs)(i.p,{children:["It serializes as two ",(0,s.jsx)(i.code,{children:"u8"})," values, the first of which describes the category, followed by the underlying value as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockTime"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"u8"})," of the block time."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"MessageCount"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 1, followed by message count as a ",(0,s.jsx)(i.code,{children:"u8"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"hash"})}),": Identify and retrieve a Block with its hash. The ",(0,s.jsx)(i.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"height"}),": Identify and retrieve the Block with its height. Height serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"state_root_hash"}),": Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(i.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"block-signatures",children:"BlockSignatures"}),"\n",(0,s.jsx)(i.p,{children:"A collection of signatures for a single block, along with the associated block's hash and era ID."}),"\n",(0,s.jsxs)(i.p,{children:["There are two possible versions for ",(0,s.jsx)(i.code,{children:"BlockSignatures"}),", with a prefixed ",(0,s.jsx)(i.code,{children:"u8"})," tag describing which version it is."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v1",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v2",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV2"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v1",children:"BlockSignaturesV1"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})," is a legacy version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created before the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v2",children:"BlockSignaturesV2"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})," is the current version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created after the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_height"}),": The block height. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#chain-name-digest",children:(0,s.jsx)(i.code,{children:"chain_name_hash"})}),": The hash of the chain name of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The status of syncing an individual block. It serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#block-hash",children:"block hash"})," of the block in question, followed by an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"option"})})," representing a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," of the block height and the remainder is the byte representation of the ",(0,s.jsx)(i.code,{children:"acquisition_state"})," as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"string"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(i.p,{children:["The block time serialized as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"btreemap",children:"BTreeMap"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeMap"})," is a method of mapping keys to values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and values held within. The remainder consists of a repeating pattern of serialized keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"btreeset",children:"BTreeSet"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeSet"})," is a method of storing a set of values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating series of values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsxs)(i.p,{children:["A container for a contract's Wasm bytes. It serializes as the single ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#bid-kind",children:"BidKind"}),", followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value describing the size of the remaining ",(0,s.jsx)(i.a,{href:"#bytes",children:"Bytes"})," and then the bytes as described."]}),"\n",(0,s.jsx)(i.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded bytes serialized as a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the length of the bytes, followed by the bytes themselves."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of byte code, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," value. A ",(0,s.jsx)(i.code,{children:"0"})," indicates empty byte code, while a ",(0,s.jsx)(i.code,{children:"1"})," indicates a ",(0,s.jsx)(i.code,{children:"V1CasperWasm"})," to be executed with the first version of the Casper execution engine."]}),"\n",(0,s.jsx)(i.h2,{id:"caller",children:"Caller"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"})," is the identity of a calling entity. It serializes as one of two variants, described below:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Initiator"})," is the overall calling account and serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Entity"})," is a calling entity, such as a smart contract or a system contract. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"package_hash"})})," and ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"entity_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"call-stack-element",children:"CallStackElement"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"CallStackElement"})," is a legacy ",(0,s.jsx)(i.code,{children:"enum"})," created pre-Condor release that represents the origin of a sub-call in a call stack. It begins with a ",(0,s.jsx)(i.code,{children:"u8"})," tag that describes the type of caller as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Session"}),": Session code, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredSession"}),": Stored access to a session, serializing as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),", ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContract"}),": A contract, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"chain-name-digest",children:"ChainNameDigest"}),"\n",(0,s.jsx)(i.p,{children:"The cryptographic hash of a chain name, serialized as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h2,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,s.jsx)(i.em,{children:"Chainspec.toml"})," and may include ",(0,s.jsx)(i.em,{children:"Accounts.toml"})," and ",(0,s.jsx)(i.em,{children:"GlobalState.toml"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"chainspec_raw_hash"})," will always be included."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"genesis_accounts_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"global_state_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"checksum-registry",children:"ChecksumRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["The checksum registry. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of checksum names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(i.p,{children:'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegator_public_key"}),": The public key of the delegator, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash digest. The digest serializes as a byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,s.jsx)(i.p,{children:"Disabled contract versions, containing the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(i.p,{children:["A log of all transforms produced during execution, serialized as a vector of ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transforms"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-action-thresholds",children:"Entity Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"upgrade_management"}),": The minimum weight threshold required to perform upgrade management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-addr",children:"EntityAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address for an ",(0,s.jsx)(i.code,{children:"AddressableEntity"}),". It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," followed by the 32-byte buffer containing the bytes of the ",(0,s.jsx)(i.code,{children:"hash_addr"})," as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind",children:"EntityKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of ",(0,s.jsx)(i.code,{children:"Package"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," describing the type followed by further data as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by a ",(0,s.jsx)(i.a,{href:"#system-entity-type",children:(0,s.jsx)(i.code,{children:"SystemEntityType"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#transactionruntime",children:(0,s.jsx)(i.code,{children:"transaction_runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind-tag",children:"EntityKindTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag for the variants of ",(0,s.jsx)(i.code,{children:"EntityKind"}),", serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 for ",(0,s.jsx)(i.code,{children:"System"}),", 1 for ",(0,s.jsx)(i.code,{children:"Account"})," and 2 for ",(0,s.jsx)(i.code,{children:"SmartContract"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(i.p,{children:["The major element of ",(0,s.jsx)(i.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(i.code,{children:"EntityVersion"})," serialized as two ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-versions",children:"EntityVersions"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of entity versions, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"EntityVersionKeys"})})," mapped to ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})})," within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"EntityVersionKeys"})," and ",(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoint",children:"EntryPoint (Contract)"}),"\n",(0,s.jsx)(i.p,{children:"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entry_point_type"}),": Identifies the type of entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"0"})," for Session and a ",(0,s.jsx)(i.code,{children:"1"})," for Contract."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entry-point",children:"EntryPoint (Entity)"}),"\n",(0,s.jsx)(i.p,{children:"The type signature of a method. This structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/developers/json-rpc/types_chain#entrypoint",children:(0,s.jsx)(i.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/developers/json-rpc/types_chain#entrypointpayment",children:(0,s.jsx)(i.code,{children:"entry_point_payment"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointaddr",children:"EntryPointAddr"}),"\n",(0,s.jsx)(i.p,{children:"An entry point's address. It serializes as one of the two following variants:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV1"}),": A V1 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," and ",(0,s.jsx)(i.code,{children:"name_bytes"}),", which is the 32-byte hash of the name of the entry point."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV2"}),": A V2 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," ",(0,s.jsx)(i.code,{children:"Selector"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointpayment",children:"EntrypointPayment"}),"\n",(0,s.jsxs)(i.p,{children:["An ",(0,s.jsx)(i.code,{children:"enum"})," specifying who pays for the invocation and execution of an entry point. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," byte tag as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a 0 and indicates that the caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnly"}),": Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnward"}),": Serializes as a 2 and indicates that the contract will pay for executing itself and any subsequent invocations."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointtype",children:"EntrypointType"}),"\n",(0,s.jsx)(i.p,{children:"The context of method execution. It serializes as one of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000000"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Called"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000001"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Factory"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b10000000"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entrypointv2",children:"EntrypointV2"}),"\n",(0,s.jsxs)(i.p,{children:["The entry point for the V2 Casper VM. It serializes as a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Selector"})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Flags"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoints",children:"EntryPoints"}),"\n",(0,s.jsxs)(i.p,{children:["Entry points for a given entity, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"String"})," to ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"String"}),"s and then ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsxs)(i.p,{children:["An Era ID newtype. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsxs)(i.p,{children:["Auction metadata, intended to be recorded each era. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#seigniorageallocation",children:"seigniorage allocations"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"executable-deploy-item",children:"ExecutableDeployItem"}),"\n",(0,s.jsxs)(i.p,{children:["The executable component of a ",(0,s.jsx)(i.code,{children:"Deploy"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," identifying tag followed by additional bytes as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ModuleBytes"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by ",(0,s.jsx)(i.a,{href:"#bytes",children:(0,s.jsx)(i.code,{children:"bytes"})})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the contract hash as an ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHash"})}),", the name of an entry point as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 3 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"PackageHash"})}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", an entry point as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 4 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Transfer"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 5 followed by ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(i.p,{children:"The journal of execution transforms from a single deploy."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"operations"}),": The resulting operations, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#operation",children:"operations"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transforms"}),": The actual ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transformation"})," performed while executing a deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single deploy. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single transaction. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure-1",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effect"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success-1",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effects"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"Gas"})," structure serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," amount of gas."]}),"\n",(0,s.jsx)(i.h2,{id:"group",children:"Group"}),"\n",(0,s.jsxs)(i.p,{children:['A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"groups",children:"Groups"}),"\n",(0,s.jsxs)(i.p,{children:["They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address of the initiator of a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#transactionV1",children:(0,s.jsx)(i.code,{children:"TransactionV1"})}),", which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by a ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," or a ",(0,s.jsx)(i.code,{children:"1"})," followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-state-keys",children:"Keys"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.em,{children:"key"})," in ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design",children:"Global State"})," is one of the following data types:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:'32-byte account identifier (called an "account identity key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte immutable contract identifier (called a "hash key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte reference identifier (called an "unforgeable reference")'}),"\n",(0,s.jsx)(i.li,{children:"32-byte transfer identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte deploy information identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte purse balance identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction bid identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction withdrawal identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Dictionary identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte System Contract Registry"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction unbond identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Chainspec Registry"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The one exception to note here is the identifier for ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})}),", which actually serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value with an additional byte for the tag."]}),"\n",(0,s.jsx)(i.h3,{id:"global-state-account-key",children:"Account Identity Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-hash-key",children:"Hash Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy hash (see ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#block-structure-head",children:"block-structure-head"})," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-uref",children:["Unforgeable Reference (",(0,s.jsx)(i.code,{children:"URef"}),")"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"URef"})," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,s.jsx)(i.code,{children:"URef"}),". ",(0,s.jsx)(i.code,{children:"URef"})," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#uref-head",children:"Unforgeable Reference"})," section for details on how ",(0,s.jsx)(i.code,{children:"URefs"})," are managed."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-transfer-key",children:"Transfer Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the transfer address associated with the given transfer."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-deploy-info-key",children:"DeployInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy itself."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-era-info-key",children:"EraInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to the ",(0,s.jsx)(i.code,{children:"Auction"})," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,s.jsx)(i.code,{children:"u64"})," data type and co-relates to the era number when the auction information was stored."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-serialization-key",children:["Serialization for ",(0,s.jsx)(i.code,{children:"Key"})]}),"\n",(0,s.jsxs)(i.p,{children:["Given the different variants for the over-arching ",(0,s.jsx)(i.code,{children:"Key"})," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:(0,s.jsx)(i.code,{children:"Key"})}),(0,s.jsx)(i.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Account"})}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Hash"})}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"URef"})}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Transfer"})}),(0,s.jsx)(i.td,{children:"3"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"DeployInfo"})}),(0,s.jsx)(i.td,{children:"4"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraInfo"})}),(0,s.jsx)(i.td,{children:"5"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Balance"})}),(0,s.jsx)(i.td,{children:"6"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Bid"})}),(0,s.jsx)(i.td,{children:"7"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Withdraw"})}),(0,s.jsx)(i.td,{children:"8"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Dictionary"})}),(0,s.jsx)(i.td,{children:"9"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"SystemContractRegistry"})}),(0,s.jsx)(i.td,{children:"10"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraSummary"})}),(0,s.jsx)(i.td,{children:"11"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Unbond"})}),(0,s.jsx)(i.td,{children:"12"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChainspecRegistry"})}),(0,s.jsx)(i.td,{children:"13"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChecksumRegistry"})}),(0,s.jsx)(i.td,{children:"14"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"BidAddr"})}),(0,s.jsx)(i.td,{children:"15"})]})]})]}),"\n",(0,s.jsxs)(i.p,{children:["| ",(0,s.jsx)(i.code,{children:"Package"})," | 16 |\n| ",(0,s.jsx)(i.code,{children:"AddressableEntity"})," | 17 |\n| ",(0,s.jsx)(i.code,{children:"ByteCode"})," | 18 |\n| ",(0,s.jsx)(i.code,{children:"Message"})," | 19 |"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"AccountHash"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Hash"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"Hash"})," itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"URef"})," is a tuple that contains the address of the URef and the access rights to that ",(0,s.jsx)(i.code,{children:"URef"}),". The serialized representation of the ",(0,s.jsx)(i.code,{children:"URef"})," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,s.jsx)(i.code,{children:"URef"})," address, and the last byte contains the bits corresponding to the access rights of the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:"CLValue"})," section of this chapter for details on how ",(0,s.jsx)(i.code,{children:"AccessRights"})," are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Transfer"})," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"DeployInfo"})," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraInfo"})," serializes a ",(0,s.jsx)(i.code,{children:"u64"})," primitive type containing the little-endian byte representation of ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Balance"})," serializes as 32 byte long buffer containing the byte representation of the URef address."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Bid"})," and ",(0,s.jsx)(i.code,{children:"Withdraw"})," both contain the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as their identifier; therefore, they serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Dictionary"})," serializes as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"SystemContractRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraSummary"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unbond"})," contains the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as its identifier; therefore, it serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChainspecRegistry"})," serializes as a 32 byte long buffer of ones."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChecksumRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," may be one of three types:\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unified"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"0"})," followed by a 32 byte long buffer containing the byte representation of a legacy bid."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Validator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"1"})," followed by a 32 byte long buffer containing the byte representation of a validator's hash."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"2"})," followed by a 32 byte long buffer containing the byte representation of the associated validator's hash, appended with a 32 byte long buffer containing the byte representation of the given delegator's hash."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-permissions",children:"Permissions"}),"\n",(0,s.jsxs)(i.p,{children:["There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,s.jsx)(i.em,{children:"add"})," to be called out separately from ",(0,s.jsx)(i.em,{children:"write"})," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Key"}),(0,s.jsx)(i.th,{children:"Type Available Actions"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Account"}),(0,s.jsx)(i.td,{children:"Read + Add (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Hash"}),(0,s.jsx)(i.td,{children:"Read"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"URef"}),(0,s.jsx)(i.td,{children:"Read + Write and/or Add"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Transfer"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Deploy"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"EraInfo"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Balance"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Bid"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Withdraw"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Dictionary"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"SystemContractRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Unbond"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"ChainspecRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]})]})]}),"\n",(0,s.jsx)(i.hr,{}),"\n",(0,s.jsxs)(i.p,{children:["Refer to ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#uref-permissions",children:"URef permissions"})," on how permissions are handled in the case of ",(0,s.jsx)(i.code,{children:"URef"}),"s."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topics",children:"MessageTopics"}),"\n",(0,s.jsxs)(i.p,{children:["A topic for contract-level messages. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"topic_name"})," strings and ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"topic_name_hash"})})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"topic_name"})," and ",(0,s.jsx)(i.code,{children:"topic_name_hash"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topic-summary",children:"MessageTopicSummary"}),"\n",(0,s.jsxs)(i.p,{children:["A summary of a message topic that will be stored in global state. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value for the ",(0,s.jsx)(i.code,{children:"message_count"})," followed by the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"BlockTime"})})]}),"\n",(0,s.jsx)(i.h2,{id:"motes",children:"Motes"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing a number of ",(0,s.jsx)(i.code,{children:"Motes"})," serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsxs)(i.p,{children:["Named arguments to a contract. It is serialized by the combination of a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by the associated ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A mapping of string identifiers to a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The value of the entry, which is a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,s.jsx)(i.code,{children:"Key"})," values as described ",(0,s.jsx)(i.a,{href:"#serialization-standard-serialization-key",children:"here"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-addr",children:"NamedKeyAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey address, serialized as an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," describing the length of a string and the 32-byte representation of the string itself."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-value",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey value, serialized as the ",(0,s.jsx)(i.code,{children:"named_key"})," serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," followed by the ",(0,s.jsx)(i.code,{children:"name"})," of the key also serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of named keys. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"names"})})," and ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-key",children:(0,s.jsx)(i.code,{children:"keys"})})," held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(i.p,{children:"An operation performed while executing a deploy. It contains:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The formatted string of the key, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"kind"}),": OpKind, The type of operation performed. It serializes as a single byte based on the following table:"]}),"\n"]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"OpKind"}),(0,s.jsx)(i.th,{children:"Serialization"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Read"}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add"}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"NoOp"}),(0,s.jsx)(i.td,{children:"3"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(i.p,{children:"A structure defining an entity, metadata and security container. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"versions"}),": An array of entity versions associated with given hashes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#group",children:(0,s.jsx)(i.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contractpackagestatus",children:(0,s.jsx)(i.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"package-hash",children:"PackageHash"}),"\n",(0,s.jsxs)(i.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#addressable-entity",children:(0,s.jsx)(i.code,{children:"AddressableEntity"})}),", serialized as the byte representation of itself."]}),"\n",(0,s.jsx)(i.h2,{id:"package-status",children:"PackageStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The lock status of the package, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})})," where ",(0,s.jsx)(i.code,{children:"true"})," indicates a locked package and ",(0,s.jsx)(i.code,{children:"false"})," indicates an unlocked package."]}),"\n",(0,s.jsx)(i.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsxs)(i.p,{children:["Parameter to a method, structured as a name followed by a ",(0,s.jsx)(i.code,{children:"CLType"}),". It is serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(i.code,{children:"CLType"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsxs)(i.p,{children:["The pricing mode of a transaction, with two possible variants. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag followed by additional data based on the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"PricingMode"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Classic"}),(0,s.jsx)(i.td,{children:"The original payment model, in which the creator of a transaction specifies how much they will pay and at which gas price."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Fixed"}),(0,s.jsx)(i.td,{children:"The cost of the transaction is determined by the cost table, per the transaction kind."})]})]})]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-classic",children:"Classic"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"0"})," tag, a ",(0,s.jsx)(i.code,{children:"Classic"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"payment_amount"})," followed by the ",(0,s.jsx)(i.code,{children:"u64"})," value of the ",(0,s.jsx)(i.code,{children:"gas_price"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-fixed",children:"Fixed"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"1"})," tag, a ",(0,s.jsx)(i.code,{children:"Fixed"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"gas_price_tolerance"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsxs)(i.p,{children:["A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values indicating major, minor and patch versions in that order."]}),"\n",(0,s.jsx)(i.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"rewarded-signatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(i.p,{children:["A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(i.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(i.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsxs)(i.p,{children:["Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," comprised of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-tuple",children:(0,s.jsx)(i.code,{children:"Tuples"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(i.p,{children:"Information about seigniorage allocation."}),"\n",(0,s.jsxs)(i.p,{children:["If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," followed by the ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["If it is a delegator, it serializes as the delegator's ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),", followed by the validator's ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," and finally the ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"semver",children:"SemVer"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," for semantic versioning, it serializes as three ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," that describe the major version, minor version and patch version."]}),"\n",(0,s.jsx)(i.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsxs)(i.p,{children:["The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-values",children:"Stored Values"}),"\n",(0,s.jsxs)(i.p,{children:["A value stored in the global state is a ",(0,s.jsx)(i.code,{children:"StoredValue"}),". A ",(0,s.jsx)(i.code,{children:"StoredValue"})," is one of three possible variants:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["A ",(0,s.jsx)(i.code,{children:"CLValue"})]}),"\n",(0,s.jsx)(i.li,{children:"A contract"}),"\n",(0,s.jsx)(i.li,{children:"An account"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["We discuss ",(0,s.jsx)(i.code,{children:"CLValue"})," and contract in more detail below. Details about accounts can be found in ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"accounts-head"}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["Each ",(0,s.jsx)(i.code,{children:"StoredValue"})," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,s.jsx)(i.code,{children:"StoredValue"})," it is, followed by the serialization of that variant. The tag for each variant is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"CLValue"})," is ",(0,s.jsx)(i.code,{children:"0"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," is ",(0,s.jsx)(i.code,{children:"1"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Contract"})," is ",(0,s.jsx)(i.code,{children:"2"})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The details of ",(0,s.jsx)(i.code,{children:"CLType"})," serialization are in the following section. Using the serialization format for ",(0,s.jsx)(i.code,{children:"CLValue"})," as a basis, we can succinctly write the serialization rules for contracts and accounts:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["contracts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"}),";"]}),"\n",(0,s.jsxs)(i.li,{children:["accounts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note: ",(0,s.jsx)(i.code,{children:"Tuple5"})," is not a presently supported ",(0,s.jsx)(i.code,{children:"CLType"}),". However, it is clear how to generalize the rules for ",(0,s.jsx)(i.code,{children:"Tuple1"}),", ",(0,s.jsx)(i.code,{children:"Tuple2"}),", ",(0,s.jsx)(i.code,{children:"Tuple3"})," to any size tuple."]}),"\n",(0,s.jsx)(i.h2,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["SystemContractRegistry is a unique ",(0,s.jsx)(i.code,{children:"Key"})," under which a mapping of the names and ",(0,s.jsx)(i.code,{children:"ContractHashes"})," for system contracts. This includes ",(0,s.jsx)(i.code,{children:"Mint"}),", ",(0,s.jsx)(i.code,{children:"Auction"}),", ",(0,s.jsx)(i.code,{children:"HandlePayment"})," and ",(0,s.jsx)(i.code,{children:"StandardPayment"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contracthash",children:"ContractHashes"})," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"system-entity-type",children:"SystemEntityType"}),"\n",(0,s.jsxs)(i.p,{children:["Entity types for system contracts, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag identifying the contract as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"System Contract"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Mint"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Auction"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"StandardPayment"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"HandlePayment"})})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsxs)(i.p,{children:["A human-readable duration between two timestamps. It serializes as a single ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsxs)(i.p,{children:["A timestamp formatted as per RFC 3339 and serialized as a single ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a topic name. The topic name hash serializes as a 32-byte buffer containing the bytes of the topic name hash."]}),"\n",(0,s.jsx)(i.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(i.p,{children:"Hex-encoded transfer address, which serializes as a byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV1",children:"TransformKindV1"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_CLValue"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Account"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"Account"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_WASM"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contractwasmhash",children:"contract as Wasm"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contracthash",children:"contract"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_Package"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#contractpackagehash",children:"contract package"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Deploy_Info"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/structures#deployinfo",children:(0,s.jsx)(i.code,{children:"DeployInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Transfer"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#transferaddr",children:"Transfer"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Era_Info"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Bid"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#bid",children:(0,s.jsx)(i.code,{children:"Bid"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Withdraw"}),(0,s.jsx)(i.td,{children:"10"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_INT32"}),(0,s.jsx)(i.td,{children:"11"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT64"}),(0,s.jsx)(i.td,{children:"12"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT128"}),(0,s.jsx)(i.td,{children:"13"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT256"}),(0,s.jsx)(i.td,{children:"14"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT512"}),(0,s.jsx)(i.td,{children:"15"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_Keys"}),(0,s.jsx)(i.td,{children:"16"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"17"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV2",children:"TransformKindV2"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect, created as a result of reading from the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Writes a new value in the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddInt32"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt64"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt128"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt256"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt512"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddKeys"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Prune"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsx)(i.td,{children:"Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,s.jsx)(i.p,{children:"A transformation performed while executing a deploy."}),"\n",(0,s.jsx)(i.h2,{id:"transformV1",children:"TransformV1"}),"\n",(0,s.jsxs)(i.p,{children:["A legacy transform struct serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV1",children:(0,s.jsx)(i.code,{children:"transformkindv1"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"transformV2",children:"Transformv2"}),"\n",(0,s.jsxs)(i.p,{children:["A struct representing an executed transformation serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV2",children:(0,s.jsx)(i.code,{children:"transformkindv2"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(i.p,{children:"A purse used for unbonding. The structure consists of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"}),": Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"new_validator"}),": The validator public key to redelegate to, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," containing the public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate serialized as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": The validator's inactivity status, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validator-change",children:"ValidatorChange"}),"\n",(0,s.jsxs)(i.p,{children:["A change to a validator's status between two eras, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"Change"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Added"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Removed"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"Banned"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:"Cannot Propose"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"4"}),(0,s.jsx)(i.td,{children:"Seen as Faulty"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"validator-config",children:"ValidatorConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A validator account configuration, serialized as a ",(0,s.jsx)(i.a,{href:"#motes",children:(0,s.jsx)(i.code,{children:"bonded_amount"})})," followed by the ",(0,s.jsx)(i.code,{children:"delegation_rate"})," as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"validator-credit",children:"ValidatorCredit"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing the record of a validator credit, with fields as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"validator_public_key"})}),": The validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The credit amount as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsxs)(i.p,{children:["A purse used for unbonding, replaced in 1.5 by ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>d,x:()=>c});var s=n(96540);const r={},l=s.createContext(r);function d(e){const i=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6193b30e.8d7754ae.js b/assets/js/6193b30e.8d7754ae.js new file mode 100644 index 000000000..2c01de75a --- /dev/null +++ b/assets/js/6193b30e.8d7754ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96232],{52850:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const c={title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},r="Installing and Interacting with a CEP-18 Contract",o={id:"resources/tokens/cep18/quickstart-guide",title:"On-chain Installation",description:"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.",source:"@site/docs/resources/tokens/cep18/quickstart-guide.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/quickstart-guide",permalink:"/resources/tokens/cep18/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},sidebar:"resources",previous:{title:"Fungible Token Workflow",permalink:"/resources/tokens/cep18/full-tutorial"},next:{title:"CEP-18 Contract Details",permalink:"/resources/tokens/cep18/query"}},i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Main Fungible Token Contract",id:"install-the-main-fungible-token-contract",level:2},{value:"Install the <code>cep18_test_contract</code> Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"installing-and-interacting-with-a-cep-18-contract",children:"Installing and Interacting with a CEP-18 Contract"})}),"\n",(0,s.jsxs)(t.p,{children:["This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,s.jsx)(t.a,{href:"https://cspr.live",children:"Casper network"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(t.p,{children:"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."}),"\n",(0,s.jsxs)(t.p,{children:["For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/full-tutorial",children:"Casper Fungible Token Tutorial"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(t.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Set up your machine as per the ",(0,s.jsx)(t.a,{href:"/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsx)(t.li,{children:"Use the [Casper command-line client]"}),"\n",(0,s.jsxs)(t.li,{children:["Get a valid ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:(0,s.jsx)(t.code,{children:"node-address"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Know how to deploy a ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(t.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,s.jsx)(t.h1,{id:"setup",children:"Setup"}),"\n",(0,s.jsxs)(t.p,{children:["Clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"fungible token (CEP-18) contract repository"})," and run the ",(0,s.jsx)(t.code,{children:"make build-contract"})," command. This will create the ",(0,s.jsx)(t.code,{children:"cep18.wasm"})," and the ",(0,s.jsx)(t.code,{children:"cep18_test_contract.wasm"}),". The token Wasm is the main contract. We will use the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."]}),"\n",(0,s.jsx)(t.h2,{id:"install-the-main-fungible-token-contract",children:"Install the Main Fungible Token Contract"}),"\n",(0,s.jsx)(t.p,{children:"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Name"})," - The name of your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Symbol"})," - The symbol used to refer to your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Total_supply"})," - The total supply of the CEP-18 token to be minted"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Decimals"})," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,s.jsx)(t.code,{children:"decimals"})," setting of 3 would be 1,000.000 tokens)"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n"})}),"\n",(0,s.jsxs)(t.h2,{id:"install-the-cep18_test_contract-contract-package",children:["Install the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Contract Package"]}),"\n",(0,s.jsx)(t.p,{children:"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n"})}),"\n",(0,s.jsx)(t.p,{children:"At this point, the account that installed both the main contract and the helper contract will look like this."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'{\n\t"src": {\n\t"Account": {\n\t"_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t"namedKeys": [\n\t\t{\n\t\t"name": "cep18_test_contract",\n\t\t"key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n\t\t},\n\t\t{\n\t\t"name": "cep18_token_contract",\n\t\t"key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n\t\t},\n\t],\n\t"mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n\t"associatedKeys": [\n\t\t{\n\t\t"accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t\t"weight": 1\n\t\t}\n\t],\n\t"actionThresholds": {\n\t\t"deployment": 1,\n\t\t"keyManagement": 1\n\t\t}\n\t\t}\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"Note:"})})}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_token_contract"})," is the main contract, and is a stored contract, record its hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_test_call"})," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(t.p,{children:"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6193b30e.8f5c08a1.js b/assets/js/6193b30e.8f5c08a1.js deleted file mode 100644 index 189441e8d..000000000 --- a/assets/js/6193b30e.8f5c08a1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6232],{52850:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const c={title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},r="Installing and Interacting with a CEP-18 Contract",o={id:"resources/tokens/cep18/quickstart-guide",title:"On-chain Installation",description:"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.",source:"@site/docs/resources/tokens/cep18/quickstart-guide.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/quickstart-guide",permalink:"/next/resources/tokens/cep18/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},sidebar:"resources",previous:{title:"Fungible Token Workflow",permalink:"/next/resources/tokens/cep18/full-tutorial"},next:{title:"CEP-18 Contract Details",permalink:"/next/resources/tokens/cep18/query"}},i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Main Fungible Token Contract",id:"install-the-main-fungible-token-contract",level:2},{value:"Install the <code>cep18_test_contract</code> Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"installing-and-interacting-with-a-cep-18-contract",children:"Installing and Interacting with a CEP-18 Contract"})}),"\n",(0,s.jsxs)(t.p,{children:["This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,s.jsx)(t.a,{href:"https://cspr.live",children:"Casper network"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(t.p,{children:"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."}),"\n",(0,s.jsxs)(t.p,{children:["For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,s.jsx)(t.a,{href:"/next/resources/tokens/cep18/full-tutorial",children:"Casper Fungible Token Tutorial"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(t.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Set up your machine as per the ",(0,s.jsx)(t.a,{href:"/next/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsx)(t.li,{children:"Use the [Casper command-line client]"}),"\n",(0,s.jsxs)(t.li,{children:["Get a valid ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:(0,s.jsx)(t.code,{children:"node-address"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Know how to deploy a ",(0,s.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(t.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,s.jsx)(t.h1,{id:"setup",children:"Setup"}),"\n",(0,s.jsxs)(t.p,{children:["Clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"fungible token (CEP-18) contract repository"})," and run the ",(0,s.jsx)(t.code,{children:"make build-contract"})," command. This will create the ",(0,s.jsx)(t.code,{children:"cep18.wasm"})," and the ",(0,s.jsx)(t.code,{children:"cep18_test_contract.wasm"}),". The token Wasm is the main contract. We will use the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."]}),"\n",(0,s.jsx)(t.h2,{id:"install-the-main-fungible-token-contract",children:"Install the Main Fungible Token Contract"}),"\n",(0,s.jsx)(t.p,{children:"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Name"})," - The name of your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Symbol"})," - The symbol used to refer to your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Total_supply"})," - The total supply of the CEP-18 token to be minted"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Decimals"})," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,s.jsx)(t.code,{children:"decimals"})," setting of 3 would be 1,000.000 tokens)"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n"})}),"\n",(0,s.jsxs)(t.h2,{id:"install-the-cep18_test_contract-contract-package",children:["Install the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Contract Package"]}),"\n",(0,s.jsx)(t.p,{children:"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n"})}),"\n",(0,s.jsx)(t.p,{children:"At this point, the account that installed both the main contract and the helper contract will look like this."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'{\n\t"src": {\n\t"Account": {\n\t"_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t"namedKeys": [\n\t\t{\n\t\t"name": "cep18_test_contract",\n\t\t"key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n\t\t},\n\t\t{\n\t\t"name": "cep18_token_contract",\n\t\t"key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n\t\t},\n\t],\n\t"mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n\t"associatedKeys": [\n\t\t{\n\t\t"accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t\t"weight": 1\n\t\t}\n\t],\n\t"actionThresholds": {\n\t\t"deployment": 1,\n\t\t"keyManagement": 1\n\t\t}\n\t\t}\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"Note:"})})}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_token_contract"})," is the main contract, and is a stored contract, record its hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_test_call"})," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(t.p,{children:"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/621db11d.72d8a767.js b/assets/js/621db11d.72d8a767.js new file mode 100644 index 000000000..30c3889a5 --- /dev/null +++ b/assets/js/621db11d.72d8a767.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64212],{13250:(t,e,s)=>{s.r(e),s.d(e,{default:()=>m});s(96540);var a=s(34164),o=s(45500),r=s(17559),l=s(96461),n=s(28027),u=s(41463),i=s(51107),h=s(56913);const c={authorListItem:"authorListItem_n3yI"};var g=s(74848);function p(t){let{author:e}=t;return(0,g.jsx)("li",{className:c.authorListItem,children:(0,g.jsx)(h.A,{as:"h2",author:e,count:e.count})})}function d(t){let{authors:e}=t;return(0,g.jsx)("section",{className:(0,a.A)("margin-vert--lg",c.authorsListSection),children:(0,g.jsx)("ul",{children:e.map((t=>(0,g.jsx)(p,{author:t},t.key)))})})}function m(t){let{authors:e,sidebar:s}=t;const h=(0,l.uz)();return(0,g.jsxs)(o.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogAuthorsListPage),children:[(0,g.jsx)(o.be,{title:h}),(0,g.jsx)(u.A,{tag:"blog_authors_list"}),(0,g.jsxs)(n.A,{sidebar:s,children:[(0,g.jsx)(i.A,{as:"h1",children:h}),(0,g.jsx)(d,{authors:e})]})]})}},96461:(t,e,s)=>{s.d(e,{ZD:()=>n,np:()=>h,uz:()=>i,wI:()=>u});s(96540);var a=s(21312),o=s(53465),r=s(74848);function l(){const{selectMessage:t}=(0,o.W)();return e=>t(e,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:e}))}function n(t){const e=l();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:e(t.count),tagName:t.label})}function u(t){const e=l();return(0,a.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:e(t.count),authorName:t.name||t.key})}const i=()=>(0,a.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function h(){return(0,r.jsx)(a.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}}}]); \ No newline at end of file diff --git a/assets/js/621db11d.81ae89ad.js b/assets/js/621db11d.81ae89ad.js deleted file mode 100644 index 9f251eb0c..000000000 --- a/assets/js/621db11d.81ae89ad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4212],{13250:(t,e,s)=>{s.r(e),s.d(e,{default:()=>m});s(96540);var a=s(34164),o=s(45500),r=s(17559),l=s(96461),n=s(28027),u=s(41463),i=s(51107),h=s(56913);const c={authorListItem:"authorListItem_n3yI"};var g=s(74848);function p(t){let{author:e}=t;return(0,g.jsx)("li",{className:c.authorListItem,children:(0,g.jsx)(h.A,{as:"h2",author:e,count:e.count})})}function d(t){let{authors:e}=t;return(0,g.jsx)("section",{className:(0,a.A)("margin-vert--lg",c.authorsListSection),children:(0,g.jsx)("ul",{children:e.map((t=>(0,g.jsx)(p,{author:t},t.key)))})})}function m(t){let{authors:e,sidebar:s}=t;const h=(0,l.uz)();return(0,g.jsxs)(o.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogAuthorsListPage),children:[(0,g.jsx)(o.be,{title:h}),(0,g.jsx)(u.A,{tag:"blog_authors_list"}),(0,g.jsxs)(n.A,{sidebar:s,children:[(0,g.jsx)(i.A,{as:"h1",children:h}),(0,g.jsx)(d,{authors:e})]})]})}},96461:(t,e,s)=>{s.d(e,{ZD:()=>n,np:()=>h,uz:()=>i,wI:()=>u});s(96540);var a=s(21312),o=s(53465),r=s(74848);function l(){const{selectMessage:t}=(0,o.W)();return e=>t(e,(0,a.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:e}))}function n(t){const e=l();return(0,a.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:e(t.count),tagName:t.label})}function u(t){const e=l();return(0,a.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:e(t.count),authorName:t.name||t.key})}const i=()=>(0,a.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function h(){return(0,r.jsx)(a.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}}}]); \ No newline at end of file diff --git a/assets/js/6245c126.30b30088.js b/assets/js/6245c126.30b30088.js deleted file mode 100644 index f12f43270..000000000 --- a/assets/js/6245c126.30b30088.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6342],{85916:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var r=n(74848),c=n(28453);const o={},t="T",a={id:"concepts/glossary/T",title:"T",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/T.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/T",permalink:"/concepts/glossary/T",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"S",permalink:"/concepts/glossary/S"},next:{title:"U",permalink:"/concepts/glossary/U"}},l={},i=[{value:"Token",id:"token",level:2},{value:"Transaction",id:"transaction",level:2},{value:"Turing-complete blockchain",id:"turing-complete-blockchain",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"t",children:"T"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"token",children:"Token"}),"\n",(0,r.jsxs)(s.p,{children:["A type of cryptocurrency that represents an asset. See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"transaction",children:"Transaction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D#deploy",children:"deploy"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"turing-complete-blockchain",children:"Turing-complete blockchain"}),"\n",(0,r.jsx)(s.p,{children:"Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets."}),"\n",(0,r.jsx)(s.p,{children:"For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6245c126.8cf7cbff.js b/assets/js/6245c126.8cf7cbff.js new file mode 100644 index 000000000..86309a587 --- /dev/null +++ b/assets/js/6245c126.8cf7cbff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96342],{85916:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var r=n(74848),c=n(28453);const o={},t="T",a={id:"concepts/glossary/T",title:"T",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/T.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/T",permalink:"/1.5.X/concepts/glossary/T",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"S",permalink:"/1.5.X/concepts/glossary/S"},next:{title:"U",permalink:"/1.5.X/concepts/glossary/U"}},l={},i=[{value:"Token",id:"token",level:2},{value:"Transaction",id:"transaction",level:2},{value:"Turing-complete blockchain",id:"turing-complete-blockchain",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"t",children:"T"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"token",children:"Token"}),"\n",(0,r.jsxs)(s.p,{children:["A type of cryptocurrency that represents an asset. See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"transaction",children:"Transaction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"deploy"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"turing-complete-blockchain",children:"Turing-complete blockchain"}),"\n",(0,r.jsx)(s.p,{children:"Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets."}),"\n",(0,r.jsx)(s.p,{children:"For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/62569fa7.4c155b8f.js b/assets/js/62569fa7.4c155b8f.js new file mode 100644 index 000000000..002f18684 --- /dev/null +++ b/assets/js/62569fa7.4c155b8f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[17287],{59213:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const r={title:"Testnet Funding",slug:"/users/testnet-faucet"},o="Funding Testnet Accounts",a={id:"users/csprlive/testnet-faucet",title:"Testnet Funding",description:"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.",source:"@site/versioned_docs/version-2.0.0/users/csprlive/testnet-faucet.md",sourceDirName:"users/csprlive",slug:"/users/testnet-faucet",permalink:"/2.0.0/users/testnet-faucet",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Testnet Funding",slug:"/users/testnet-faucet"},sidebar:"users",previous:{title:"Using CSPR.live",permalink:"/2.0.0/users/csprlive/"},next:{title:"Delegate Tokens",permalink:"/2.0.0/users/delegate-ui"}},c={},l=[{value:"Requesting Testnet Tokens",id:"requesting-testnet-tokens",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"funding-testnet-accounts",children:"Funding Testnet Accounts"})}),"\n",(0,s.jsxs)(t.p,{children:["The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"cspr.live"})," block explorer."]}),"\n",(0,s.jsx)(t.p,{children:"Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below."}),"\n",(0,s.jsx)(t.h3,{id:"requesting-testnet-tokens",children:"Requesting Testnet Tokens"}),"\n",(0,s.jsx)(t.p,{children:"To request test tokens, follow these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Log into the Casper Testnet with the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Tools"})," on the top menu bar and select ",(0,s.jsx)(t.strong,{children:"Faucet"})," from the drop-down menu. Or, navigate to the Faucet using this link: ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/faucet",children:"https://testnet.cspr.live/tools/faucet"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Request tokens"})," on the Faucet page:"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Faucet",src:n(11353).A+"",width:"1379",height:"617"})}),"\n",(0,s.jsxs)(t.admonition,{type:"caution",children:[(0,s.jsxs)(t.p,{children:["Tokens can be requested ",(0,s.jsx)(t.strong,{children:"only once per account"}),". Otherwise, the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/deploy/f0f6b25db767d1a6c2244324661d853ad7d4766f8489d81c36b5e2c9d982891e",children:"deploy will fail"})," with status ",(0,s.jsx)(t.code,{children:"User error: 1"}),"."]}),(0,s.jsxs)(t.p,{children:["If you have already exhausted your test funds, you can always ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#creating-an-account",children:"create a new account"}),"."]})]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:"The Testnet will credit your account with test tokens."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},11353:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/faucet-function-f3c2d05a9fd17287ec2fb304731a0197.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6318ac72.262b8dce.js b/assets/js/6318ac72.262b8dce.js new file mode 100644 index 000000000..28b7441ea --- /dev/null +++ b/assets/js/6318ac72.262b8dce.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39238],{34198:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>c});var i=n(74848),r=n(28453);const t={title:"Rewards Design"},s="Network Participation Rewards",o={id:"concepts/design/rewards",title:"Rewards Design",description:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.",source:"@site/docs/concepts/design/rewards.md",sourceDirName:"concepts/design",slug:"/concepts/design/rewards",permalink:"/concepts/design/rewards",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{title:"Rewards Design"},sidebar:"concepts",previous:{title:"Highway Consensus",permalink:"/concepts/design/highway"},next:{title:"Reading and Writing Data",permalink:"/concepts/design/reading-and-writing-to-the-blockchain"}},l={},c=[{value:"Calculating Rewards",id:"calculating-rewards",level:2},{value:"Chainspec settings for calculating rewards",id:"chainspec-settings-for-calculating-rewards",level:3},{value:"Rewards distribution summary",id:"rewards-distribution-summary",level:3}];function d(e){const a={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.header,{children:(0,i.jsx)(a.h1,{id:"network-participation-rewards",children:"Network Participation Rewards"})}),"\n",(0,i.jsx)(a.p,{children:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP. "}),"\n",(0,i.jsx)(a.p,{children:"Like other Proof-of-Stake chains, a Casper network rewards validators for participating in building a linear chain of blocks, each containing ordered state changes and ensuring that the entire ecosystem of validators, builders, and users eventually achieve common knowledge of the chain's history. External, non-validator participants in the ecosystem can thus have a high degree of confidence on the canonical history of the blockchain's state, thus making the blockchain economically useful."}),"\n",(0,i.jsxs)(a.p,{children:["The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both ",(0,i.jsx)(a.a,{href:"/concepts/design/zug",children:"Zug"})," and ",(0,i.jsx)(a.a,{href:"/concepts/design/highway",children:"Highway"}),". The current reward scheme has the following properties:"]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Rewards are proportional to a validator's weight on average."}),"\n",(0,i.jsx)(a.li,{children:"The reward scheme incentivizes cooperation."}),"\n",(0,i.jsx)(a.li,{children:"Rewards are distributed at the end of an era for all blocks in that era and several eligible blocks from the previous era."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations depend only on the linear structure of the blockchain and published finality signatures, rather than any internal details of the consensus protocol."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations assume a known constant token supply inflation with nominal platform operation."}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"Previously, with Highway, the reward scheme incentivized block production and participation in their finalization. Unfortunately, this scheme was highly coupled with the consensus protocol and unsuitable for adaptation with the Zug consensus. The current scheme calculates rewards after blocks have been finalized, as described below."}),"\n",(0,i.jsx)(a.h2,{id:"calculating-rewards",children:"Calculating Rewards"}),"\n",(0,i.jsx)(a.p,{children:'The execution engine calculates rewards for block production and finality signature generation and distribution in each switch block. Finality signatures are produced after a block has been finalized by consensus. Thus, rewards are independent of the consensus algorithm used. Block proposers collect those finality signatures and include them in future blocks. The rewards scheme allows blocks to cite finality signatures for several past blocks so that validators can agree on which finality signatures have been produced and should be rewarded. This mechanism to "look back" is necessary because signatures cannot be distributed instantly.'}),"\n",(0,i.jsx)(a.p,{children:"Rewards are divided into these categories:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Block rewards"}),": These rewards are received for each proposed block that is finalized. They incentivize timely participation in building the chain."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Finality signature rewards"}),": These rewards are received for collecting finality signatures for each block and generating a finality signature to sign a block. They incentivize the creation, propagation and publication of finality signatures, which is critical in establishing common knowledge of the canonical chain."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"In each round, a total reward pool is shared among all participating validators proportionally to their weight, as long as all validators fully participate in the processes that are rewarded by this mechanism. These processes are block creation, signature creation, signature propagation and signature publication as part of block proposals."}),"\n",(0,i.jsxs)(a.p,{children:["The ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," setting in the chainspec determines the total reward pool for a block. This value, along with the current total supply and minimum round length, is used to compute the full allocation of rewards for a particular block. The rate itself is set to result in a target annual inflation, provided validators fully participate in the rewardable processes described above."]}),"\n",(0,i.jsxs)(a.p,{children:['Each switch block triggers a reward calculation. To account for potential network lag delaying the timely arrival of signatures for finalized blocks, the calculation "looks back" into previous eras. In particular, this enables rewards for switch blocks, which was impossible with the prior Highway-specific calculation. The number of prior blocks to look up is specified using the ',(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," setting in the chainspec."]}),"\n",(0,i.jsxs)(a.p,{children:["Blocks carry information on their proposer and the finality signatures collected for several past blocks, the depth being determined by the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter. Global state contains data on token supply and validator weights as part of the Mint and Auction states. Based on these inputs, the rewards are calculated according to a formula. Rewards are designed to be proportional to weight on average, as long as blocks are created and the finality signatures are propagated and published in a timely manner. "]}),"\n",(0,i.jsx)(a.p,{children:"Validators are motivated to produce, propagate and publish (i.e., include in the block body) finality signatures as quickly as possible. If they do not include a finality signature in a block, the next validator can include it in their block and get the collection fee."}),"\n",(0,i.jsx)(a.h3,{id:"chainspec-settings-for-calculating-rewards",children:"Chainspec settings for calculating rewards"}),"\n",(0,i.jsx)(a.p,{children:"Each Casper network chainspec contains 4 settings related to calculating rewards:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finality_signature_proportion"}),": The proportion of baseline rewards going to reward finality signatures, rather than block proposal rewards."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finders_fee"}),": The proportion of the rewards allocated to finality signatures that are due for signature publication in a block proposal."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"}),": The number of prior blocks to include for the reward calculation."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"round_seigniorage_rate"}),": Setting that calculates the fraction of the total supply that will constitute the reward pool for every round."]}),"\n"]}),"\n",(0,i.jsxs)(a.details,{children:["\n",(0,i.jsx)(a.summary,{children:(0,i.jsx)(a.b,{children:"Expand to see sample values"})}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-json",children:"# The split in finality signature rewards between block producer and participating signers.\nfinders_fee = [1, 5]\n# The proportion of baseline rewards going to reward finality signatures specifically.\nfinality_signature_proportion = [1, 2]\n# Lookback interval indicating which past block we are looking at to reward.\nsignature_rewards_max_delay = 3\n...\n# Round seigniorage rate represented as a fraction of the total supply.\n#\n# Annual issuance: 8%\n# Minimum block time: 2^14 milliseconds\n# Ticks per year: 31536000000\n#\n# (1+0.08)^((2^14)/31536000000)-1 is expressed as a fractional number below\n# Python:\n# from fractions import Fraction\n# Fraction((1 + 0.08)**((2**14)/31536000000) - 1).limit_denominator(1000000000)\nround_seigniorage_rate = [7, 175070816]\n"})}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"rewards-distribution-summary",children:"Rewards distribution summary"}),"\n",(0,i.jsx)(a.p,{children:"The following steps summarize the rewards distribution mechanism."}),"\n",(0,i.jsxs)(a.p,{children:["Each round has a reward pool calculated from the ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," chainspec parameter and the current total supply for the relevant era."]}),"\n",(0,i.jsxs)(a.p,{children:["In each round, the reward pool is split into two parts for block proposals and finality signature rewards, based on the ",(0,i.jsx)(a.code,{children:"finality_signature_proportion"})," chainspec parameter."]}),"\n",(0,i.jsxs)(a.p,{children:["The amount allocated for finality signatures is split further into two parts: creating and publishing finality signatures. The split is configurable in the chainspec using the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter."]}),"\n",(0,i.jsx)(a.p,{children:"For each finality signature:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"The creator gets a portion of what was allocated for creating signatures, in proportion to relative consensus weight."}),"\n",(0,i.jsxs)(a.li,{children:["The block proposer gets a portion corresponding to the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter, scaled by the total collected signature creator weight divided by the total weight in the relevant era."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Rewards Pot",src:n(66767).A+"",width:"747",height:"743"})}),"\n",(0,i.jsxs)(a.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter, to compensate for the delay in creating and distributing finality signatures."]})]})}function h(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},66767:(e,a,n)=>{n.d(a,{A:()=>i});const i=n.p+"assets/images/rewards-pot-abc6a18cf2901d137d80907cdedd6d8f.png"},28453:(e,a,n)=>{n.d(a,{R:()=>s,x:()=>o});var i=n(96540);const r={},t=i.createContext(r);function s(e){const a=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6318ac72.49f55d51.js b/assets/js/6318ac72.49f55d51.js deleted file mode 100644 index 09bfcd80a..000000000 --- a/assets/js/6318ac72.49f55d51.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9238],{34198:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(74848),t=n(28453);const r={title:"Rewards Design"},s="Network Participation Rewards",o={id:"concepts/design/rewards",title:"Rewards Design",description:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.",source:"@site/docs/concepts/design/rewards.md",sourceDirName:"concepts/design",slug:"/concepts/design/rewards",permalink:"/next/concepts/design/rewards",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{title:"Rewards Design"},sidebar:"concepts",previous:{title:"Highway Consensus",permalink:"/next/concepts/design/highway"},next:{title:"Reading and Writing Data",permalink:"/next/concepts/design/reading-and-writing-to-the-blockchain"}},l={},c=[{value:"Calculating Rewards",id:"calculating-rewards",level:2},{value:"Chainspec settings for calculating rewards",id:"chainspec-settings-for-calculating-rewards",level:3},{value:"Rewards distribution summary",id:"rewards-distribution-summary",level:3}];function d(e){const a={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.header,{children:(0,i.jsx)(a.h1,{id:"network-participation-rewards",children:"Network Participation Rewards"})}),"\n",(0,i.jsx)(a.p,{children:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP. "}),"\n",(0,i.jsx)(a.p,{children:"Like other Proof-of-Stake chains, a Casper network rewards validators for participating in building a linear chain of blocks, each containing ordered state changes and ensuring that the entire ecosystem of validators, builders, and users eventually achieve common knowledge of the chain's history. External, non-validator participants in the ecosystem can thus have a high degree of confidence on the canonical history of the blockchain's state, thus making the blockchain economically useful."}),"\n",(0,i.jsxs)(a.p,{children:["The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both ",(0,i.jsx)(a.a,{href:"/next/concepts/design/zug",children:"Zug"})," and ",(0,i.jsx)(a.a,{href:"/next/concepts/design/highway",children:"Highway"}),". The current reward scheme has the following properties:"]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Rewards are proportional to a validator's weight on average."}),"\n",(0,i.jsx)(a.li,{children:"The reward scheme incentivizes cooperation."}),"\n",(0,i.jsx)(a.li,{children:"Rewards are distributed at the end of an era for all blocks in that era and several eligible blocks from the previous era."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations depend only on the linear structure of the blockchain and published finality signatures, rather than any internal details of the consensus protocol."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations assume a known constant token supply inflation with nominal platform operation."}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"Previously, with Highway, the reward scheme incentivized block production and participation in their finalization. Unfortunately, this scheme was highly coupled with the consensus protocol and unsuitable for adaptation with the Zug consensus. The current scheme calculates rewards after blocks have been finalized, as described below."}),"\n",(0,i.jsx)(a.h2,{id:"calculating-rewards",children:"Calculating Rewards"}),"\n",(0,i.jsx)(a.p,{children:'The execution engine calculates rewards for block production and finality signature generation and distribution in each switch block. Finality signatures are produced after a block has been finalized by consensus. Thus, rewards are independent of the consensus algorithm used. Block proposers collect those finality signatures and include them in future blocks. The rewards scheme allows blocks to cite finality signatures for several past blocks so that validators can agree on which finality signatures have been produced and should be rewarded. This mechanism to "look back" is necessary because signatures cannot be distributed instantly.'}),"\n",(0,i.jsx)(a.p,{children:"Rewards are divided into these categories:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Block rewards"}),": These rewards are received for each proposed block that is finalized. They incentivize timely participation in building the chain."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Finality signature rewards"}),": These rewards are received for collecting finality signatures for each block and generating a finality signature to sign a block. They incentivize the creation, propagation and publication of finality signatures, which is critical in establishing common knowledge of the canonical chain."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"In each round, a total reward pool is shared among all participating validators proportionally to their weight, as long as all validators fully participate in the processes that are rewarded by this mechanism. These processes are block creation, signature creation, signature propagation and signature publication as part of block proposals."}),"\n",(0,i.jsxs)(a.p,{children:["The ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," setting in the chainspec determines the total reward pool for a block. This value, along with the current total supply and minimum round length, is used to compute the full allocation of rewards for a particular block. The rate itself is set to result in a target annual inflation, provided validators fully participate in the rewardable processes described above."]}),"\n",(0,i.jsxs)(a.p,{children:['Each switch block triggers a reward calculation. To account for potential network lag delaying the timely arrival of signatures for finalized blocks, the calculation "looks back" into previous eras. In particular, this enables rewards for switch blocks, which was impossible with the prior Highway-specific calculation. The number of prior blocks to look up is specified using the ',(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," setting in the chainspec."]}),"\n",(0,i.jsxs)(a.p,{children:["Blocks carry information on their proposer and the finality signatures collected for several past blocks, the depth being determined by the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter. Global state contains data on token supply and validator weights as part of the Mint and Auction states. Based on these inputs, the rewards are calculated according to a formula. Rewards are designed to be proportional to weight on average, as long as blocks are created and the finality signatures are propagated and published in a timely manner. "]}),"\n",(0,i.jsx)(a.p,{children:"Validators are motivated to produce, propagate and publish (i.e., include in the block body) finality signatures as quickly as possible. If they do not include a finality signature in a block, the next validator can include it in their block and get the collection fee."}),"\n",(0,i.jsx)(a.h3,{id:"chainspec-settings-for-calculating-rewards",children:"Chainspec settings for calculating rewards"}),"\n",(0,i.jsx)(a.p,{children:"Each Casper network chainspec contains 4 settings related to calculating rewards:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finality_signature_proportion"}),": The proportion of baseline rewards going to reward finality signatures, rather than block proposal rewards."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finders_fee"}),": The proportion of the rewards allocated to finality signatures that are due for signature publication in a block proposal."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"}),": The number of prior blocks to include for the reward calculation."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"round_seigniorage_rate"}),": Setting that calculates the fraction of the total supply that will constitute the reward pool for every round."]}),"\n"]}),"\n",(0,i.jsxs)(a.details,{children:["\n",(0,i.jsx)(a.summary,{children:(0,i.jsx)(a.b,{children:"Expand to see sample values"})}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-json",children:"# The split in finality signature rewards between block producer and participating signers.\nfinders_fee = [1, 5]\n# The proportion of baseline rewards going to reward finality signatures specifically.\nfinality_signature_proportion = [1, 2]\n# Lookback interval indicating which past block we are looking at to reward.\nsignature_rewards_max_delay = 3\n...\n# Round seigniorage rate represented as a fraction of the total supply.\n#\n# Annual issuance: 8%\n# Minimum block time: 2^14 milliseconds\n# Ticks per year: 31536000000\n#\n# (1+0.08)^((2^14)/31536000000)-1 is expressed as a fractional number below\n# Python:\n# from fractions import Fraction\n# Fraction((1 + 0.08)**((2**14)/31536000000) - 1).limit_denominator(1000000000)\nround_seigniorage_rate = [7, 175070816]\n"})}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"rewards-distribution-summary",children:"Rewards distribution summary"}),"\n",(0,i.jsx)(a.p,{children:"The following steps summarize the rewards distribution mechanism."}),"\n",(0,i.jsxs)(a.p,{children:["Each round has a reward pool calculated from the ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," chainspec parameter and the current total supply for the relevant era."]}),"\n",(0,i.jsxs)(a.p,{children:["In each round, the reward pool is split into two parts for block proposals and finality signature rewards, based on the ",(0,i.jsx)(a.code,{children:"finality_signature_proportion"})," chainspec parameter."]}),"\n",(0,i.jsxs)(a.p,{children:["The amount allocated for finality signatures is split further into two parts: creating and publishing finality signatures. The split is configurable in the chainspec using the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter."]}),"\n",(0,i.jsx)(a.p,{children:"For each finality signature:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"The creator gets a portion of what was allocated for creating signatures, in proportion to relative consensus weight."}),"\n",(0,i.jsxs)(a.li,{children:["The block proposer gets a portion corresponding to the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter, scaled by the total collected signature creator weight divided by the total weight in the relevant era."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Rewards Pot",src:n(61141).A+"",width:"747",height:"743"})}),"\n",(0,i.jsxs)(a.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter, to compensate for the delay in creating and distributing finality signatures."]})]})}function h(e={}){const{wrapper:a}={...(0,t.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},61141:(e,a,n)=>{n.d(a,{A:()=>i});const i=n.p+"assets/images/rewards-pot-abc6a18cf2901d137d80907cdedd6d8f.png"},28453:(e,a,n)=>{n.d(a,{R:()=>s,x:()=>o});var i=n(96540);const t={},r=i.createContext(t);function s(e){const a=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:s(e.components),i.createElement(r.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/631bdc93.abd03f43.js b/assets/js/631bdc93.abd03f43.js new file mode 100644 index 000000000..e530e741d --- /dev/null +++ b/assets/js/631bdc93.abd03f43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[38656],{2781:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="I",a={id:"concepts/glossary/I",title:"I",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/I.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/I",permalink:"/2.0.0/concepts/glossary/I",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"H",permalink:"/2.0.0/concepts/glossary/H"},next:{title:"J",permalink:"/2.0.0/concepts/glossary/J"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"i",children:"I"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/63925da8.5e258b77.js b/assets/js/63925da8.5e258b77.js new file mode 100644 index 000000000..7423dfe4d --- /dev/null +++ b/assets/js/63925da8.5e258b77.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16871],{93061:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var n=t(74848),s=t(28453);const i={title:"Overview",slug:"/developers"},o="Developers Overview",d={id:"developers/index",title:"Overview",description:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.",source:"@site/docs/developers/index.md",sourceDirName:"developers",slug:"/developers",permalink:"/developers",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Overview",slug:"/developers"},sidebar:"developers",next:{title:"Development Prerequisites",permalink:"/developers/prerequisites"}},a={},l=[];function c(e){const r={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.header,{children:(0,n.jsx)(r.h1,{id:"developers-overview",children:"Developers Overview"})}),"\n",(0,n.jsx)(r.p,{children:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(r.table,{children:[(0,n.jsx)(r.thead,{children:(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.th,{children:"Topic"}),(0,n.jsx)(r.th,{children:"Description"})]})}),(0,n.jsxs)(r.tbody,{children:[(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/developers/prerequisites",children:"Development Prerequisites"})}),(0,n.jsx)(r.td,{children:"Setup needed for various workflows"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/developers/essential-crates",children:"Essential Casper Crates"})}),(0,n.jsx)(r.td,{children:"Available Casper crates and the corresponding documentation"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})}),(0,n.jsx)(r.td,{children:"Writing contracts in Rust and Wasm for a Casper network"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/developers/json-rpc/",children:"Casper JSON-RPC API"})}),(0,n.jsx)(r.td,{children:"Endpoints for developers wishing to interact directly with a Casper node's JSON-RPC API"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/developers/dapps/",children:"Building dApps"})}),(0,n.jsx)(r.td,{children:"Useful information for dApp developers"})]}),(0,n.jsxs)(r.tr,{children:[(0,n.jsx)(r.td,{children:(0,n.jsx)(r.a,{href:"/developers/cli/",children:"Interacting with the Blockchain Using CLI"})}),(0,n.jsx)(r.td,{children:"Using a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens."})]})]})]}),"\n",(0,n.jsxs)(r.p,{children:["The ",(0,n.jsx)(r.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open-Source Software"})," may provide other helpful examples."]}),"\n",(0,n.jsx)(r.p,{children:"The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together."})]})}function p(e={}){const{wrapper:r}={...(0,s.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,r,t)=>{t.d(r,{R:()=>o,x:()=>d});var n=t(96540);const s={},i=n.createContext(s);function o(e){const r=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function d(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63925da8.a65c70bf.js b/assets/js/63925da8.a65c70bf.js deleted file mode 100644 index e79e66a9e..000000000 --- a/assets/js/63925da8.a65c70bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6871],{93061:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var r=n(74848),s=n(28453);const i={title:"Overview",slug:"/developers"},o="Developers Overview",d={id:"developers/index",title:"Overview",description:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.",source:"@site/docs/developers/index.md",sourceDirName:"developers",slug:"/developers",permalink:"/next/developers",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Overview",slug:"/developers"},sidebar:"developers",next:{title:"Development Prerequisites",permalink:"/next/developers/prerequisites"}},a={},l=[];function c(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"developers-overview",children:"Developers Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Topic"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/developers/prerequisites",children:"Development Prerequisites"})}),(0,r.jsx)(t.td,{children:"Setup needed for various workflows"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/developers/essential-crates",children:"Essential Casper Crates"})}),(0,r.jsx)(t.td,{children:"Available Casper crates and the corresponding documentation"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/writing-contracts",children:"Writing On-Chain Code"})}),(0,r.jsx)(t.td,{children:"Writing contracts in Rust and Wasm for a Casper network"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/",children:"Casper JSON-RPC API"})}),(0,r.jsx)(t.td,{children:"Endpoints for developers wishing to interact directly with a Casper node's JSON-RPC API"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/developers/dapps/",children:"Building dApps"})}),(0,r.jsx)(t.td,{children:"Useful information for dApp developers"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/next/developers/cli/",children:"Interacting with the Blockchain Using CLI"})}),(0,r.jsx)(t.td,{children:"Using a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens."})]})]})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/next/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open-Source Software"})," may provide other helpful examples."]}),"\n",(0,r.jsx)(t.p,{children:"The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together."})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>d});var r=n(96540);const s={},i=r.createContext(s);function o(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function d(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63d4ce07.2ce275cd.js b/assets/js/63d4ce07.2ce275cd.js new file mode 100644 index 000000000..22af5bfb3 --- /dev/null +++ b/assets/js/63d4ce07.2ce275cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[21261],{64740:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(74848),i=t(28453);const a={},o="Redelegating Tokens with the Casper Client",r={id:"developers/cli/redelegate",title:"Redelegating Tokens with the Casper Client",description:"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.",source:"@site/docs/developers/cli/redelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/redelegate",permalink:"/developers/cli/redelegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Delegating Tokens",permalink:"/developers/cli/delegate"},next:{title:"Undelegating Tokens",permalink:"/developers/cli/undelegate"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Redelegating with the System Auction Contract",id:"redelegating-system-auction",level:2},{value:"Method 2: Redelegating with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Sending the redelegation request",id:"sending-the-redelegation-deploy",level:3},{value:"Verifying the Redelegation",id:"verifying-the-redelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"redelegating-tokens-with-the-casper-client",children:"Redelegating Tokens with the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an ",(0,s.jsx)(n.a,{href:"/developers/cli/undelegate",children:"unbonding request"})," first and then ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegate"})," the tokens to the new validator."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network, and you have the validator's public key"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the public key of the new validator to whom you wish to redelegate tokens. See ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})," for more details"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"redelegating-system-auction",children:"Method 1: Redelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount 2500000000 \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-redelegation",children:"verify the redelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Redelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a redelegation is to compile the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that will include the redelegation Wasm."]}),"\n",(0,s.jsx)(n.h3,{id:"sending-the-redelegation-deploy",children:"Sending the redelegation request"}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," to the network to initiate the redelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH_TO_WASM>/redelegate.wasm \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Save the returned ",(0,s.jsx)(n.em,{children:"deploy_hash"})," from the output to ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"query information"})," about the redelegation Deploy."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Running the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," is a more expensive operation than calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entrypoint from the system auction contract."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-redelegation",children:"Verifying the Redelegation"}),"\n",(0,s.jsx)(n.p,{children:"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."}),"\n",(0,s.jsxs)(n.p,{children:["Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#confirming-the-delegation",children:"verifying a delegation request"})," using the ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/63d4ce07.8dccf7cc.js b/assets/js/63d4ce07.8dccf7cc.js deleted file mode 100644 index 24e8167e3..000000000 --- a/assets/js/63d4ce07.8dccf7cc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1261],{64740:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(74848),i=t(28453);const a={},o="Redelegating Tokens with the Casper Client",r={id:"developers/cli/redelegate",title:"Redelegating Tokens with the Casper Client",description:"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.",source:"@site/docs/developers/cli/redelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/redelegate",permalink:"/next/developers/cli/redelegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Delegating Tokens",permalink:"/next/developers/cli/delegate"},next:{title:"Undelegating Tokens",permalink:"/next/developers/cli/undelegate"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Redelegating with the System Auction Contract",id:"redelegating-system-auction",level:2},{value:"Method 2: Redelegating with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Sending the redelegation request",id:"sending-the-redelegation-deploy",level:3},{value:"Verifying the Redelegation",id:"verifying-the-redelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"redelegating-tokens-with-the-casper-client",children:"Redelegating Tokens with the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an ",(0,s.jsx)(n.a,{href:"/next/developers/cli/undelegate",children:"unbonding request"})," first and then ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate",children:"delegate"})," the tokens to the new validator."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network, and you have the validator's public key"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the public key of the new validator to whom you wish to redelegate tokens. See ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})," for more details"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"redelegating-system-auction",children:"Method 1: Redelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount 2500000000 \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-redelegation",children:"verify the redelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Redelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a redelegation is to compile the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that will include the redelegation Wasm."]}),"\n",(0,s.jsx)(n.h3,{id:"sending-the-redelegation-deploy",children:"Sending the redelegation request"}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," to the network to initiate the redelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH_TO_WASM>/redelegate.wasm \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Save the returned ",(0,s.jsx)(n.em,{children:"deploy_hash"})," from the output to ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"query information"})," about the redelegation Deploy."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Running the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," is a more expensive operation than calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entrypoint from the system auction contract."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-redelegation",children:"Verifying the Redelegation"}),"\n",(0,s.jsx)(n.p,{children:"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."}),"\n",(0,s.jsxs)(n.p,{children:["Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate#confirming-the-delegation",children:"verifying a delegation request"})," using the ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64733a41.aa5d15dd.js b/assets/js/64733a41.aa5d15dd.js new file mode 100644 index 000000000..c71cba07c --- /dev/null +++ b/assets/js/64733a41.aa5d15dd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87914],{79985:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var o=t(74848),s=t(28453);const a={},i="Casper-Client Commands",r={id:"resources/beginner/counter/commands",title:"Casper-Client Commands",description:"Faucet Account Information",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter/commands.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/commands",permalink:"/2.0.0/resources/beginner/counter/commands",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/2.0.0/resources/beginner/counter/overview"},next:{title:"Tutorial Walkthrough",permalink:"/2.0.0/resources/beginner/counter/walkthrough"}},c={},l=[{value:"Faucet Account Information",id:"faucet-account-information",level:2},{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,o.jsx)(n.h2,{id:"faucet-account-information",children:"Faucet Account Information"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"nctl-view-faucet-account\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's ",(0,o.jsx)(n.em,{children:"secret key"})," location and the ",(0,o.jsx)(n.em,{children:"account hash"}),", which are used to sign deploys and query the network state, respectively."]}),"\n",(0,o.jsx)(n.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The first command to cover is the ",(0,o.jsx)(n.em,{children:"get-state-root-hash"})," command from the ",(0,o.jsx)(n.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"After sending 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."})}),"\n",(0,o.jsx)(n.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,o.jsx)(n.em,{children:"state-root-hash"})," described above."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"node-address"})," is the location of the RPC endpoint, which is typically represented in the form ",(0,o.jsx)(n.code,{children:"http://IP:PORT"}),". In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is ",(0,o.jsx)(n.code,{children:"http://localhost:11101"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,o.jsxs)(n.li,{children:["The optional query path argument (",(0,o.jsx)(n.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,o.jsx)(n.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,o.jsxs)(n.li,{children:["This contract is then installed on the network specified by the ",(0,o.jsx)(n.em,{children:"chain-name"}),'. By default, NCTL names the chain "casper-net-1" but this is configurable.']}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This second usage of ",(0,o.jsx)(n.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,o.jsxs)(n.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,o.jsx)(n.a,{href:"/2.0.0/resources/beginner/counter/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,o.jsx)(n.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"get-deploy"})," command is complementary to the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,o.jsx)(n.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6474e148.836b5554.js b/assets/js/6474e148.836b5554.js deleted file mode 100644 index d2f57b75c..000000000 --- a/assets/js/6474e148.836b5554.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9126],{79375:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="I",a={id:"concepts/glossary/I",title:"I",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/I.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/I",permalink:"/concepts/glossary/I",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"H",permalink:"/concepts/glossary/H"},next:{title:"J",permalink:"/concepts/glossary/J"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"i",children:"I"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/6474e148.f34dd9c3.js b/assets/js/6474e148.f34dd9c3.js new file mode 100644 index 000000000..073ac5879 --- /dev/null +++ b/assets/js/6474e148.f34dd9c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39126],{79375:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="I",a={id:"concepts/glossary/I",title:"I",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/I.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/I",permalink:"/1.5.X/concepts/glossary/I",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"H",permalink:"/1.5.X/concepts/glossary/H"},next:{title:"J",permalink:"/1.5.X/concepts/glossary/J"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"i",children:"I"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/64899cf9.892e78a4.js b/assets/js/64899cf9.892e78a4.js new file mode 100644 index 000000000..b6edda1c3 --- /dev/null +++ b/assets/js/64899cf9.892e78a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16087],{97329:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>t,contentTitle:()=>c,default:()=>o,frontMatter:()=>l,metadata:()=>d,toc:()=>a});var s=n(74848),r=n(28453);const l={},c="Type Serialization",d={id:"concepts/serialization/types",title:"Type Serialization",description:"Account Action Thresholds",source:"@site/docs/concepts/serialization/types.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/types",permalink:"/concepts/serialization/types",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Major Structures",permalink:"/concepts/serialization/structures"},next:{title:"dApps",permalink:"/concepts/intro-to-dapps"}},t={},a=[{value:"Account Action Thresholds",id:"account-action-thresholds",level:2},{value:"Account Config",id:"account-config",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Account Identifier",id:"account-identifier",level:2},{value:"Activation Point",id:"activation-point",level:2},{value:"AddressableEntityHash",id:"addressable-entity-hash",level:2},{value:"Approval",id:"approval",level:2},{value:"ApprovalsHash",id:"approvals-hash",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldAddr",id:"balanceholdaddr",level:2},{value:"BalanceHoldAddrTag",id:"balanceholdaddrtag",level:2},{value:"BalanceResponse",id:"balance-response",level:2},{value:"Bid",id:"bid",level:2},{value:"BidAddr",id:"bidaddr",level:2},{value:"BidKind",id:"bid-kind",level:2},{value:"BlockGlobalAddr",id:"blockglobaladdr",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockSignatures",id:"block-signatures",level:2},{value:"BlockSignaturesV1",id:"block-signatures-v1",level:3},{value:"BlockSignaturesV2",id:"block-signatures-v2",level:3},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BTreeMap",id:"btreemap",level:2},{value:"BTreeSet",id:"btreeset",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"Caller",id:"caller",level:2},{value:"CallStackElement",id:"call-stack-element",level:2},{value:"ChainNameDigest",id:"chain-name-digest",level:2},{value:"ChainspecRegistry",id:"chainspecregistry",level:2},{value:"ChecksumRegistry",id:"checksum-registry",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"Effects",id:"effects",level:2},{value:"Entity Action Thresholds",id:"entity-action-thresholds",level:2},{value:"EntityAddr",id:"entity-addr",level:2},{value:"EntityKind",id:"entity-kind",level:2},{value:"EntityKindTag",id:"entity-kind-tag",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntityVersions",id:"entity-versions",level:2},{value:"EntryPoint (Contract)",id:"entrypoint",level:2},{value:"EntryPoint (Entity)",id:"entry-point",level:2},{value:"EntryPointAddr",id:"entrypointaddr",level:3},{value:"EntrypointPayment",id:"entrypointpayment",level:3},{value:"EntrypointType",id:"entrypointtype",level:3},{value:"EntrypointV2",id:"entrypointv2",level:2},{value:"EntryPoints",id:"entrypoints",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"ExecutableDeployItem",id:"executable-deploy-item",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"<code>Failure</code>",id:"failure",level:3},{value:"<code>Success</code>",id:"success",level:3},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"<code>Failure</code>",id:"failure-1",level:3},{value:"<code>Success</code>",id:"success-1",level:3},{value:"Gas",id:"gas",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account Identity Key",id:"global-state-account-key",level:3},{value:"Hash Key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (<code>URef</code>)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for <code>Key</code>",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:3},{value:"MessageTopics",id:"message-topics",level:2},{value:"MessageTopicSummary",id:"message-topic-summary",level:2},{value:"Motes",id:"motes",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeyAddr",id:"named-key-addr",level:2},{value:"NamedKeyValue",id:"named-key-value",level:2},{value:"NamedKeys",id:"named-keys",level:2},{value:"Operation",id:"operation",level:2},{value:"Package",id:"package",level:2},{value:"PackageHash",id:"package-hash",level:2},{value:"PackageStatus",id:"package-status",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"Classic",id:"pricingmode-classic",level:3},{value:"Fixed",id:"pricingmode-fixed",level:3},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RewardedSignatures",id:"rewarded-signatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"SemVer",id:"semver",level:2},{value:"Signature",id:"signature",level:2},{value:"Stored Values",id:"serialization-standard-values",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"SystemEntityType",id:"system-entity-type",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topic-name-hash",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransformKindV1",id:"transformkindV1",level:2},{value:"TransformKindV2",id:"transformkindV2",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"TransformV1",id:"transformV1",level:2},{value:"Transformv2",id:"transformV2",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validator-change",level:2},{value:"ValidatorConfig",id:"validator-config",level:2},{value:"ValidatorCredit",id:"validator-credit",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function h(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.header,{children:(0,s.jsx)(i.h1,{id:"type-serialization",children:"Type Serialization"})}),"\n",(0,s.jsx)(i.h2,{id:"account-action-thresholds",children:"Account Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-config",children:"Account Config"}),"\n",(0,s.jsxs)(i.p,{children:["Configuration of an individual account in ",(0,s.jsx)(i.em,{children:"accounts.toml"}),", containing the account's public key, main purse balance and validator config."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"public_key"})," The public key of the account, serialized as the byte representation of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:"itself"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance"})," The balance of the account's main purse, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512 value"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator"})," The validator configuration for the account, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."]}),"\n",(0,s.jsx)(i.h2,{id:"account-identifier",children:"Account Identifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve an Account. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),": The account's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),": The ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the account's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"activation-point",children:"Activation Point"}),"\n",(0,s.jsxs)(i.p,{children:["The first era to which the associated protocol version applies. It serializes as a single ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,s.jsx)(i.code,{children:"timestamp"}),". If not, the bytes represent an ",(0,s.jsx)(i.code,{children:"era_id"}),"."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_id"}),": An ",(0,s.jsx)(i.a,{href:"#eraid",children:"Era ID newtype"})," identifying the era when the protocol version will activate."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A ",(0,s.jsx)(i.a,{href:"#timestamp",children:"timestamp"})," if the activation point is of the Genesis variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"addressable-entity-hash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(i.p,{children:"The hex-encoded address of an addressable entity, which serializes as the byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(i.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"Signature"})}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(i.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(i.a,{href:"#digest",children:(0,s.jsx)(i.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"account_hash"}),": The ",(0,s.jsx)(i.a,{href:"#account-hash",children:"account hash"})," of the associated key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"weight"}),": The weight of an associated key. The weight serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsxs)(i.p,{children:["An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," values"]})," containing the following two fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"low"}),": The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"high"}),": - The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddr",children:"BalanceHoldAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A balance hold address. It serializes as a ",(0,s.jsx)(i.a,{href:"#balanceholdaddrtag",children:(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})})," describing the type of balance hold address as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Gas"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Processing"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddrtag",children:"BalanceHoldAddrTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag describing the type of ",(0,s.jsx)(i.code,{children:"BalanceHoldAddr"}),", serializing as a single ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"balance-response",children:"BalanceResponse"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BalanceResponse"})," is a struct that provides the response to a balance query. It consists of the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance"}),": The purse's total balance, not considering holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"available_balance"}),": The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance_proof"}),": A proof that the given value is present in the Merkle trie. It serializes as a ",(0,s.jsx)(i.code,{children:"TrieMerkleProof"}),", consisting of a key, a value and a ",(0,s.jsx)(i.code,{children:"proof_step"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance_holds"}),": Any time-relevant active holds on the balance. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"BlockTime"})," and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"BlockTime"}),"s and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"}),"s of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The validator's public key. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The purse used for bonding. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"Uref"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate of the bid. It serializes as an ",(0,s.jsx)(i.code,{children:"i32"})," signed 32-bit integer primitive."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for a genesis validator. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegators"}),": The validator's delegators, indexed by their public keys. They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and then delegators of the length dictated by the first four bytes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": If the validator has been evicted. A ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-boolean",children:"boolean"})," value that serializes as a single byte; ",(0,s.jsx)(i.code,{children:"true"})," maps to ",(0,s.jsx)(i.code,{children:"1"}),", while ",(0,s.jsx)(i.code,{children:"false"})," maps to ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bidaddr",children:"BidAddr"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," manages data associated with bids for the ",(0,s.jsx)(i.code,{children:"Auction"})," system contract. It serializes as a single ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Unified"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," for legacy unified bids. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," identifying the legacy bid."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Validator"})," A validator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," A delegator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the associated validator and then the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the delegator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Credit"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," representing an auction credit. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"4"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator and the ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," for the applicable credit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid-kind",children:"BidKind"}),"\n",(0,s.jsxs)(i.p,{children:["Auction bid variants. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]})," indicating the type of bid kind as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"BidKind"}),(0,s.jsx)(i.th,{children:"u8"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#bid",children:"Unified"})}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Legacy data that contains all delegators for a given validator."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#validatorbid",children:"Validator"})}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"A bid record containing only validator data."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#delegatorbid",children:"Delegator"})}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"A bid record containing only delegator data."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"blockglobaladdr",children:"BlockGlobalAddr"}),"\n",(0,s.jsx)(i.p,{children:"An address for singleton values associated to a specific block. These are values which are calculated or set during the execution of a block such as the block timestamp, or the total count of messages emitted during the execution of the block."}),"\n",(0,s.jsxs)(i.p,{children:["It serializes as two ",(0,s.jsx)(i.code,{children:"u8"})," values, the first of which describes the category, followed by the underlying value as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockTime"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"u8"})," of the block time."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"MessageCount"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 1, followed by message count as a ",(0,s.jsx)(i.code,{children:"u8"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"hash"})}),": Identify and retrieve a Block with its hash. The ",(0,s.jsx)(i.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"height"}),": Identify and retrieve the Block with its height. Height serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"state_root_hash"}),": Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(i.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"block-signatures",children:"BlockSignatures"}),"\n",(0,s.jsx)(i.p,{children:"A collection of signatures for a single block, along with the associated block's hash and era ID."}),"\n",(0,s.jsxs)(i.p,{children:["There are two possible versions for ",(0,s.jsx)(i.code,{children:"BlockSignatures"}),", with a prefixed ",(0,s.jsx)(i.code,{children:"u8"})," tag describing which version it is."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v1",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v2",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV2"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v1",children:"BlockSignaturesV1"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})," is a legacy version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created before the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v2",children:"BlockSignaturesV2"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})," is the current version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created after the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_height"}),": The block height. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#chain-name-digest",children:(0,s.jsx)(i.code,{children:"chain_name_hash"})}),": The hash of the chain name of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The status of syncing an individual block. It serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#block-hash",children:"block hash"})," of the block in question, followed by an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"option"})})," representing a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," of the block height and the remainder is the byte representation of the ",(0,s.jsx)(i.code,{children:"acquisition_state"})," as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"string"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(i.p,{children:["The block time serialized as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"btreemap",children:"BTreeMap"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeMap"})," is a method of mapping keys to values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and values held within. The remainder consists of a repeating pattern of serialized keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"btreeset",children:"BTreeSet"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeSet"})," is a method of storing a set of values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating series of values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsxs)(i.p,{children:["A container for a contract's Wasm bytes. It serializes as the single ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#bid-kind",children:"BidKind"}),", followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value describing the size of the remaining ",(0,s.jsx)(i.a,{href:"#bytes",children:"Bytes"})," and then the bytes as described."]}),"\n",(0,s.jsx)(i.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded bytes serialized as a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the length of the bytes, followed by the bytes themselves."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of byte code, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," value. A ",(0,s.jsx)(i.code,{children:"0"})," indicates empty byte code, while a ",(0,s.jsx)(i.code,{children:"1"})," indicates a ",(0,s.jsx)(i.code,{children:"V1CasperWasm"})," to be executed with the first version of the Casper execution engine."]}),"\n",(0,s.jsx)(i.h2,{id:"caller",children:"Caller"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"})," is the identity of a calling entity. It serializes as one of two variants, described below:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Initiator"})," is the overall calling account and serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Entity"})," is a calling entity, such as a smart contract or a system contract. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"package_hash"})})," and ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"entity_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"call-stack-element",children:"CallStackElement"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"CallStackElement"})," is a legacy ",(0,s.jsx)(i.code,{children:"enum"})," created pre-Condor release that represents the origin of a sub-call in a call stack. It begins with a ",(0,s.jsx)(i.code,{children:"u8"})," tag that describes the type of caller as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Session"}),": Session code, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredSession"}),": Stored access to a session, serializing as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),", ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContract"}),": A contract, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"chain-name-digest",children:"ChainNameDigest"}),"\n",(0,s.jsx)(i.p,{children:"The cryptographic hash of a chain name, serialized as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h2,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,s.jsx)(i.em,{children:"Chainspec.toml"})," and may include ",(0,s.jsx)(i.em,{children:"Accounts.toml"})," and ",(0,s.jsx)(i.em,{children:"GlobalState.toml"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"chainspec_raw_hash"})," will always be included."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"genesis_accounts_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"global_state_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"checksum-registry",children:"ChecksumRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["The checksum registry. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of checksum names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(i.p,{children:'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegator_public_key"}),": The public key of the delegator, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash digest. The digest serializes as a byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,s.jsx)(i.p,{children:"Disabled contract versions, containing the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(i.p,{children:["A log of all transforms produced during execution, serialized as a vector of ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transforms"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-action-thresholds",children:"Entity Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"upgrade_management"}),": The minimum weight threshold required to perform upgrade management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-addr",children:"EntityAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address for an ",(0,s.jsx)(i.code,{children:"AddressableEntity"}),". It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," followed by the 32-byte buffer containing the bytes of the ",(0,s.jsx)(i.code,{children:"hash_addr"})," as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind",children:"EntityKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of ",(0,s.jsx)(i.code,{children:"Package"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," describing the type followed by further data as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by a ",(0,s.jsx)(i.a,{href:"#system-entity-type",children:(0,s.jsx)(i.code,{children:"SystemEntityType"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#transactionruntime",children:(0,s.jsx)(i.code,{children:"transaction_runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind-tag",children:"EntityKindTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag for the variants of ",(0,s.jsx)(i.code,{children:"EntityKind"}),", serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 for ",(0,s.jsx)(i.code,{children:"System"}),", 1 for ",(0,s.jsx)(i.code,{children:"Account"})," and 2 for ",(0,s.jsx)(i.code,{children:"SmartContract"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(i.p,{children:["The major element of ",(0,s.jsx)(i.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(i.code,{children:"EntityVersion"})," serialized as two ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-versions",children:"EntityVersions"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of entity versions, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"EntityVersionKeys"})})," mapped to ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})})," within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"EntityVersionKeys"})," and ",(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoint",children:"EntryPoint (Contract)"}),"\n",(0,s.jsx)(i.p,{children:"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entry_point_type"}),": Identifies the type of entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"0"})," for Session and a ",(0,s.jsx)(i.code,{children:"1"})," for Contract."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entry-point",children:"EntryPoint (Entity)"}),"\n",(0,s.jsx)(i.p,{children:"The type signature of a method. This structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/developers/json-rpc/types_chain#entrypoint",children:(0,s.jsx)(i.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/developers/json-rpc/types_chain#entrypointpayment",children:(0,s.jsx)(i.code,{children:"entry_point_payment"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointaddr",children:"EntryPointAddr"}),"\n",(0,s.jsx)(i.p,{children:"An entry point's address. It serializes as one of the two following variants:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV1"}),": A V1 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," and ",(0,s.jsx)(i.code,{children:"name_bytes"}),", which is the 32-byte hash of the name of the entry point."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV2"}),": A V2 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," ",(0,s.jsx)(i.code,{children:"Selector"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointpayment",children:"EntrypointPayment"}),"\n",(0,s.jsxs)(i.p,{children:["An ",(0,s.jsx)(i.code,{children:"enum"})," specifying who pays for the invocation and execution of an entry point. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," byte tag as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a 0 and indicates that the caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnly"}),": Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnward"}),": Serializes as a 2 and indicates that the contract will pay for executing itself and any subsequent invocations."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointtype",children:"EntrypointType"}),"\n",(0,s.jsx)(i.p,{children:"The context of method execution. It serializes as one of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000000"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Called"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000001"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Factory"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b10000000"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entrypointv2",children:"EntrypointV2"}),"\n",(0,s.jsxs)(i.p,{children:["The entry point for the V2 Casper VM. It serializes as a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Selector"})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Flags"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoints",children:"EntryPoints"}),"\n",(0,s.jsxs)(i.p,{children:["Entry points for a given entity, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"String"})," to ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"String"}),"s and then ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsxs)(i.p,{children:["An Era ID newtype. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsxs)(i.p,{children:["Auction metadata, intended to be recorded each era. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#seigniorageallocation",children:"seigniorage allocations"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"executable-deploy-item",children:"ExecutableDeployItem"}),"\n",(0,s.jsxs)(i.p,{children:["The executable component of a ",(0,s.jsx)(i.code,{children:"Deploy"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," identifying tag followed by additional bytes as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ModuleBytes"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by ",(0,s.jsx)(i.a,{href:"#bytes",children:(0,s.jsx)(i.code,{children:"bytes"})})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the contract hash as an ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHash"})}),", the name of an entry point as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 3 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"PackageHash"})}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", an entry point as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 4 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Transfer"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 5 followed by ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(i.p,{children:"The journal of execution transforms from a single deploy."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"operations"}),": The resulting operations, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#operation",children:"operations"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transforms"}),": The actual ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transformation"})," performed while executing a deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single deploy. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single transaction. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure-1",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effect"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success-1",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effects"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"Gas"})," structure serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," amount of gas."]}),"\n",(0,s.jsx)(i.h2,{id:"group",children:"Group"}),"\n",(0,s.jsxs)(i.p,{children:['A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"groups",children:"Groups"}),"\n",(0,s.jsxs)(i.p,{children:["They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address of the initiator of a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#transactionV1",children:(0,s.jsx)(i.code,{children:"TransactionV1"})}),", which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by a ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," or a ",(0,s.jsx)(i.code,{children:"1"})," followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-state-keys",children:"Keys"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.em,{children:"key"})," in ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design",children:"Global State"})," is one of the following data types:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:'32-byte account identifier (called an "account identity key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte immutable contract identifier (called a "hash key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte reference identifier (called an "unforgeable reference")'}),"\n",(0,s.jsx)(i.li,{children:"32-byte transfer identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte deploy information identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte purse balance identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction bid identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction withdrawal identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Dictionary identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte System Contract Registry"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction unbond identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Chainspec Registry"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The one exception to note here is the identifier for ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})}),", which actually serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value with an additional byte for the tag."]}),"\n",(0,s.jsx)(i.h3,{id:"global-state-account-key",children:"Account Identity Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-hash-key",children:"Hash Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy hash (see ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#block-structure-head",children:"block-structure-head"})," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-uref",children:["Unforgeable Reference (",(0,s.jsx)(i.code,{children:"URef"}),")"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"URef"})," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,s.jsx)(i.code,{children:"URef"}),". ",(0,s.jsx)(i.code,{children:"URef"})," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#uref-head",children:"Unforgeable Reference"})," section for details on how ",(0,s.jsx)(i.code,{children:"URefs"})," are managed."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-transfer-key",children:"Transfer Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the transfer address associated with the given transfer."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-deploy-info-key",children:"DeployInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy itself."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-era-info-key",children:"EraInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to the ",(0,s.jsx)(i.code,{children:"Auction"})," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,s.jsx)(i.code,{children:"u64"})," data type and co-relates to the era number when the auction information was stored."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-serialization-key",children:["Serialization for ",(0,s.jsx)(i.code,{children:"Key"})]}),"\n",(0,s.jsxs)(i.p,{children:["Given the different variants for the over-arching ",(0,s.jsx)(i.code,{children:"Key"})," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:(0,s.jsx)(i.code,{children:"Key"})}),(0,s.jsx)(i.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Account"})}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Hash"})}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"URef"})}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Transfer"})}),(0,s.jsx)(i.td,{children:"3"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"DeployInfo"})}),(0,s.jsx)(i.td,{children:"4"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraInfo"})}),(0,s.jsx)(i.td,{children:"5"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Balance"})}),(0,s.jsx)(i.td,{children:"6"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Bid"})}),(0,s.jsx)(i.td,{children:"7"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Withdraw"})}),(0,s.jsx)(i.td,{children:"8"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Dictionary"})}),(0,s.jsx)(i.td,{children:"9"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"SystemContractRegistry"})}),(0,s.jsx)(i.td,{children:"10"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraSummary"})}),(0,s.jsx)(i.td,{children:"11"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Unbond"})}),(0,s.jsx)(i.td,{children:"12"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChainspecRegistry"})}),(0,s.jsx)(i.td,{children:"13"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChecksumRegistry"})}),(0,s.jsx)(i.td,{children:"14"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"BidAddr"})}),(0,s.jsx)(i.td,{children:"15"})]})]})]}),"\n",(0,s.jsxs)(i.p,{children:["| ",(0,s.jsx)(i.code,{children:"Package"})," | 16 |\n| ",(0,s.jsx)(i.code,{children:"AddressableEntity"})," | 17 |\n| ",(0,s.jsx)(i.code,{children:"ByteCode"})," | 18 |\n| ",(0,s.jsx)(i.code,{children:"Message"})," | 19 |"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"AccountHash"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Hash"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"Hash"})," itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"URef"})," is a tuple that contains the address of the URef and the access rights to that ",(0,s.jsx)(i.code,{children:"URef"}),". The serialized representation of the ",(0,s.jsx)(i.code,{children:"URef"})," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,s.jsx)(i.code,{children:"URef"})," address, and the last byte contains the bits corresponding to the access rights of the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue",children:"CLValue"})," section of this chapter for details on how ",(0,s.jsx)(i.code,{children:"AccessRights"})," are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Transfer"})," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"DeployInfo"})," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraInfo"})," serializes a ",(0,s.jsx)(i.code,{children:"u64"})," primitive type containing the little-endian byte representation of ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Balance"})," serializes as 32 byte long buffer containing the byte representation of the URef address."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Bid"})," and ",(0,s.jsx)(i.code,{children:"Withdraw"})," both contain the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as their identifier; therefore, they serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Dictionary"})," serializes as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"SystemContractRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraSummary"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unbond"})," contains the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as its identifier; therefore, it serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChainspecRegistry"})," serializes as a 32 byte long buffer of ones."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChecksumRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," may be one of three types:\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unified"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"0"})," followed by a 32 byte long buffer containing the byte representation of a legacy bid."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Validator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"1"})," followed by a 32 byte long buffer containing the byte representation of a validator's hash."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"2"})," followed by a 32 byte long buffer containing the byte representation of the associated validator's hash, appended with a 32 byte long buffer containing the byte representation of the given delegator's hash."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-permissions",children:"Permissions"}),"\n",(0,s.jsxs)(i.p,{children:["There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,s.jsx)(i.em,{children:"add"})," to be called out separately from ",(0,s.jsx)(i.em,{children:"write"})," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Key"}),(0,s.jsx)(i.th,{children:"Type Available Actions"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Account"}),(0,s.jsx)(i.td,{children:"Read + Add (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Hash"}),(0,s.jsx)(i.td,{children:"Read"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"URef"}),(0,s.jsx)(i.td,{children:"Read + Write and/or Add"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Transfer"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Deploy"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"EraInfo"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Balance"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Bid"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Withdraw"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Dictionary"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"SystemContractRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Unbond"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"ChainspecRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]})]})]}),"\n",(0,s.jsx)(i.hr,{}),"\n",(0,s.jsxs)(i.p,{children:["Refer to ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#uref-permissions",children:"URef permissions"})," on how permissions are handled in the case of ",(0,s.jsx)(i.code,{children:"URef"}),"s."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topics",children:"MessageTopics"}),"\n",(0,s.jsxs)(i.p,{children:["A topic for contract-level messages. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"topic_name"})," strings and ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"topic_name_hash"})})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"topic_name"})," and ",(0,s.jsx)(i.code,{children:"topic_name_hash"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topic-summary",children:"MessageTopicSummary"}),"\n",(0,s.jsxs)(i.p,{children:["A summary of a message topic that will be stored in global state. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value for the ",(0,s.jsx)(i.code,{children:"message_count"})," followed by the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"BlockTime"})})]}),"\n",(0,s.jsx)(i.h2,{id:"motes",children:"Motes"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing a number of ",(0,s.jsx)(i.code,{children:"Motes"})," serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsxs)(i.p,{children:["Named arguments to a contract. It is serialized by the combination of a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by the associated ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A mapping of string identifiers to a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry. It serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The value of the entry, which is a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,s.jsx)(i.code,{children:"Key"})," values as described ",(0,s.jsx)(i.a,{href:"#serialization-standard-serialization-key",children:"here"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-addr",children:"NamedKeyAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey address, serialized as an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," describing the length of a string and the 32-byte representation of the string itself."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-value",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey value, serialized as the ",(0,s.jsx)(i.code,{children:"named_key"})," serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," followed by the ",(0,s.jsx)(i.code,{children:"name"})," of the key also serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of named keys. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"names"})})," and ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-key",children:(0,s.jsx)(i.code,{children:"keys"})})," held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(i.p,{children:"An operation performed while executing a deploy. It contains:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The formatted string of the key, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"kind"}),": OpKind, The type of operation performed. It serializes as a single byte based on the following table:"]}),"\n"]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"OpKind"}),(0,s.jsx)(i.th,{children:"Serialization"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Read"}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add"}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"NoOp"}),(0,s.jsx)(i.td,{children:"3"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(i.p,{children:"A structure defining an entity, metadata and security container. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"versions"}),": An array of entity versions associated with given hashes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#group",children:(0,s.jsx)(i.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contractpackagestatus",children:(0,s.jsx)(i.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"package-hash",children:"PackageHash"}),"\n",(0,s.jsxs)(i.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#addressable-entity",children:(0,s.jsx)(i.code,{children:"AddressableEntity"})}),", serialized as the byte representation of itself."]}),"\n",(0,s.jsx)(i.h2,{id:"package-status",children:"PackageStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The lock status of the package, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})})," where ",(0,s.jsx)(i.code,{children:"true"})," indicates a locked package and ",(0,s.jsx)(i.code,{children:"false"})," indicates an unlocked package."]}),"\n",(0,s.jsx)(i.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsxs)(i.p,{children:["Parameter to a method, structured as a name followed by a ",(0,s.jsx)(i.code,{children:"CLType"}),". It is serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(i.code,{children:"CLType"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsxs)(i.p,{children:["The pricing mode of a transaction, with two possible variants. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag followed by additional data based on the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"PricingMode"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Classic"}),(0,s.jsx)(i.td,{children:"The original payment model, in which the creator of a transaction specifies how much they will pay and at which gas price."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Fixed"}),(0,s.jsx)(i.td,{children:"The cost of the transaction is determined by the cost table, per the transaction kind."})]})]})]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-classic",children:"Classic"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"0"})," tag, a ",(0,s.jsx)(i.code,{children:"Classic"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"payment_amount"})," followed by the ",(0,s.jsx)(i.code,{children:"u64"})," value of the ",(0,s.jsx)(i.code,{children:"gas_price"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-fixed",children:"Fixed"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"1"})," tag, a ",(0,s.jsx)(i.code,{children:"Fixed"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"gas_price_tolerance"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsxs)(i.p,{children:["A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values indicating major, minor and patch versions in that order."]}),"\n",(0,s.jsx)(i.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"rewarded-signatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(i.p,{children:["A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(i.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(i.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsxs)(i.p,{children:["Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," comprised of ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-tuple",children:(0,s.jsx)(i.code,{children:"Tuples"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(i.p,{children:"Information about seigniorage allocation."}),"\n",(0,s.jsxs)(i.p,{children:["If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," followed by the ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["If it is a delegator, it serializes as the delegator's ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),", followed by the validator's ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," and finally the ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"semver",children:"SemVer"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," for semantic versioning, it serializes as three ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," that describe the major version, minor version and patch version."]}),"\n",(0,s.jsx)(i.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsxs)(i.p,{children:["The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-values",children:"Stored Values"}),"\n",(0,s.jsxs)(i.p,{children:["A value stored in the global state is a ",(0,s.jsx)(i.code,{children:"StoredValue"}),". A ",(0,s.jsx)(i.code,{children:"StoredValue"})," is one of three possible variants:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["A ",(0,s.jsx)(i.code,{children:"CLValue"})]}),"\n",(0,s.jsx)(i.li,{children:"A contract"}),"\n",(0,s.jsx)(i.li,{children:"An account"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["We discuss ",(0,s.jsx)(i.code,{children:"CLValue"})," and contract in more detail below. Details about accounts can be found in ",(0,s.jsx)(i.a,{href:"/concepts/design/casper-design#accounts-head",children:"accounts-head"}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["Each ",(0,s.jsx)(i.code,{children:"StoredValue"})," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,s.jsx)(i.code,{children:"StoredValue"})," it is, followed by the serialization of that variant. The tag for each variant is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"CLValue"})," is ",(0,s.jsx)(i.code,{children:"0"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," is ",(0,s.jsx)(i.code,{children:"1"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Contract"})," is ",(0,s.jsx)(i.code,{children:"2"})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The details of ",(0,s.jsx)(i.code,{children:"CLType"})," serialization are in the following section. Using the serialization format for ",(0,s.jsx)(i.code,{children:"CLValue"})," as a basis, we can succinctly write the serialization rules for contracts and accounts:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["contracts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"}),";"]}),"\n",(0,s.jsxs)(i.li,{children:["accounts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note: ",(0,s.jsx)(i.code,{children:"Tuple5"})," is not a presently supported ",(0,s.jsx)(i.code,{children:"CLType"}),". However, it is clear how to generalize the rules for ",(0,s.jsx)(i.code,{children:"Tuple1"}),", ",(0,s.jsx)(i.code,{children:"Tuple2"}),", ",(0,s.jsx)(i.code,{children:"Tuple3"})," to any size tuple."]}),"\n",(0,s.jsx)(i.h2,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["SystemContractRegistry is a unique ",(0,s.jsx)(i.code,{children:"Key"})," under which a mapping of the names and ",(0,s.jsx)(i.code,{children:"ContractHashes"})," for system contracts. This includes ",(0,s.jsx)(i.code,{children:"Mint"}),", ",(0,s.jsx)(i.code,{children:"Auction"}),", ",(0,s.jsx)(i.code,{children:"HandlePayment"})," and ",(0,s.jsx)(i.code,{children:"StandardPayment"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contracthash",children:"ContractHashes"})," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"system-entity-type",children:"SystemEntityType"}),"\n",(0,s.jsxs)(i.p,{children:["Entity types for system contracts, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag identifying the contract as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"System Contract"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Mint"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Auction"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"StandardPayment"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"HandlePayment"})})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsxs)(i.p,{children:["A human-readable duration between two timestamps. It serializes as a single ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsxs)(i.p,{children:["A timestamp formatted as per RFC 3339 and serialized as a single ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a topic name. The topic name hash serializes as a 32-byte buffer containing the bytes of the topic name hash."]}),"\n",(0,s.jsx)(i.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(i.p,{children:"Hex-encoded transfer address, which serializes as a byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV1",children:"TransformKindV1"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_CLValue"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Account"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"Account"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_WASM"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contractwasmhash",children:"contract as Wasm"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contracthash",children:"contract"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_Package"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#contractpackagehash",children:"contract package"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Deploy_Info"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/structures#deployinfo",children:(0,s.jsx)(i.code,{children:"DeployInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Transfer"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#transferaddr",children:"Transfer"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Era_Info"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Bid"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#bid",children:(0,s.jsx)(i.code,{children:"Bid"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Withdraw"}),(0,s.jsx)(i.td,{children:"10"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_INT32"}),(0,s.jsx)(i.td,{children:"11"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT64"}),(0,s.jsx)(i.td,{children:"12"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT128"}),(0,s.jsx)(i.td,{children:"13"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT256"}),(0,s.jsx)(i.td,{children:"14"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT512"}),(0,s.jsx)(i.td,{children:"15"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_Keys"}),(0,s.jsx)(i.td,{children:"16"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"17"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV2",children:"TransformKindV2"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect, created as a result of reading from the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Writes a new value in the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddInt32"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt64"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt128"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt256"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt512"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddKeys"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Prune"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsx)(i.td,{children:"Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,s.jsx)(i.p,{children:"A transformation performed while executing a deploy."}),"\n",(0,s.jsx)(i.h2,{id:"transformV1",children:"TransformV1"}),"\n",(0,s.jsxs)(i.p,{children:["A legacy transform struct serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV1",children:(0,s.jsx)(i.code,{children:"transformkindv1"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"transformV2",children:"Transformv2"}),"\n",(0,s.jsxs)(i.p,{children:["A struct representing an executed transformation serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV2",children:(0,s.jsx)(i.code,{children:"transformkindv2"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(i.p,{children:"A purse used for unbonding. The structure consists of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"}),": Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"new_validator"}),": The validator public key to redelegate to, serialized as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," containing the public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate serialized as a ",(0,s.jsxs)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": The validator's inactivity status, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validator-change",children:"ValidatorChange"}),"\n",(0,s.jsxs)(i.p,{children:["A change to a validator's status between two eras, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"Change"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Added"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Removed"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"Banned"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:"Cannot Propose"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"4"}),(0,s.jsx)(i.td,{children:"Seen as Faulty"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"validator-config",children:"ValidatorConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A validator account configuration, serialized as a ",(0,s.jsx)(i.a,{href:"#motes",children:(0,s.jsx)(i.code,{children:"bonded_amount"})})," followed by the ",(0,s.jsx)(i.code,{children:"delegation_rate"})," as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"validator-credit",children:"ValidatorCredit"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing the record of a validator credit, with fields as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"validator_public_key"})}),": The validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The credit amount as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsxs)(i.p,{children:["A purse used for unbonding, replaced in 1.5 by ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>c,x:()=>d});var s=n(96540);const r={},l=s.createContext(r);function c(e){const i=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function d(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64899cf9.d83e08cf.js b/assets/js/64899cf9.d83e08cf.js deleted file mode 100644 index 9b62c2815..000000000 --- a/assets/js/64899cf9.d83e08cf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6087],{97329:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>d,contentTitle:()=>l,default:()=>o,frontMatter:()=>t,metadata:()=>c,toc:()=>a});var s=n(74848),r=n(28453);const t={},l="Type Serialization",c={id:"concepts/serialization/types",title:"Type Serialization",description:"Account Action Thresholds",source:"@site/docs/concepts/serialization/types.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/types",permalink:"/next/concepts/serialization/types",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Major Structures",permalink:"/next/concepts/serialization/structures"},next:{title:"dApps",permalink:"/next/concepts/intro-to-dapps"}},d={},a=[{value:"Account Action Thresholds",id:"account-action-thresholds",level:2},{value:"Account Config",id:"account-config",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Account Identifier",id:"account-identifier",level:2},{value:"Activation Point",id:"activation-point",level:2},{value:"AddressableEntityHash",id:"addressable-entity-hash",level:2},{value:"Approval",id:"approval",level:2},{value:"ApprovalsHash",id:"approvals-hash",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldAddr",id:"balanceholdaddr",level:2},{value:"BalanceHoldAddrTag",id:"balanceholdaddrtag",level:2},{value:"BalanceResponse",id:"balance-response",level:2},{value:"Bid",id:"bid",level:2},{value:"BidAddr",id:"bidaddr",level:2},{value:"BidKind",id:"bid-kind",level:2},{value:"BlockGlobalAddr",id:"blockglobaladdr",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockSignatures",id:"block-signatures",level:2},{value:"BlockSignaturesV1",id:"block-signatures-v1",level:3},{value:"BlockSignaturesV2",id:"block-signatures-v2",level:3},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BTreeMap",id:"btreemap",level:2},{value:"BTreeSet",id:"btreeset",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"Caller",id:"caller",level:2},{value:"CallStackElement",id:"call-stack-element",level:2},{value:"ChainNameDigest",id:"chain-name-digest",level:2},{value:"ChainspecRegistry",id:"chainspecregistry",level:2},{value:"ChecksumRegistry",id:"checksum-registry",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"Effects",id:"effects",level:2},{value:"Entity Action Thresholds",id:"entity-action-thresholds",level:2},{value:"EntityAddr",id:"entity-addr",level:2},{value:"EntityKind",id:"entity-kind",level:2},{value:"EntityKindTag",id:"entity-kind-tag",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntityVersions",id:"entity-versions",level:2},{value:"EntryPoint (Contract)",id:"entrypoint",level:2},{value:"EntryPoint (Entity)",id:"entry-point",level:2},{value:"EntryPointAddr",id:"entrypointaddr",level:3},{value:"EntrypointPayment",id:"entrypointpayment",level:3},{value:"EntrypointType",id:"entrypointtype",level:3},{value:"EntrypointV2",id:"entrypointv2",level:2},{value:"EntryPoints",id:"entrypoints",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"ExecutableDeployItem",id:"executable-deploy-item",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"<code>Failure</code>",id:"failure",level:3},{value:"<code>Success</code>",id:"success",level:3},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"<code>Failure</code>",id:"failure-1",level:3},{value:"<code>Success</code>",id:"success-1",level:3},{value:"Gas",id:"gas",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account Identity Key",id:"global-state-account-key",level:3},{value:"Hash Key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (<code>URef</code>)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for <code>Key</code>",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:3},{value:"MessageTopics",id:"message-topics",level:2},{value:"MessageTopicSummary",id:"message-topic-summary",level:2},{value:"Motes",id:"motes",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeyAddr",id:"named-key-addr",level:2},{value:"NamedKeyValue",id:"named-key-value",level:2},{value:"NamedKeys",id:"named-keys",level:2},{value:"Operation",id:"operation",level:2},{value:"Package",id:"package",level:2},{value:"PackageHash",id:"package-hash",level:2},{value:"PackageStatus",id:"package-status",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"Classic",id:"pricingmode-classic",level:3},{value:"Fixed",id:"pricingmode-fixed",level:3},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RewardedSignatures",id:"rewarded-signatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"SemVer",id:"semver",level:2},{value:"Signature",id:"signature",level:2},{value:"Stored Values",id:"serialization-standard-values",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"SystemEntityType",id:"system-entity-type",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topic-name-hash",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransformKindV1",id:"transformkindV1",level:2},{value:"TransformKindV2",id:"transformkindV2",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"TransformV1",id:"transformV1",level:2},{value:"Transformv2",id:"transformV2",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validator-change",level:2},{value:"ValidatorConfig",id:"validator-config",level:2},{value:"ValidatorCredit",id:"validator-credit",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function h(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.header,{children:(0,s.jsx)(i.h1,{id:"type-serialization",children:"Type Serialization"})}),"\n",(0,s.jsx)(i.h2,{id:"account-action-thresholds",children:"Account Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-config",children:"Account Config"}),"\n",(0,s.jsxs)(i.p,{children:["Configuration of an individual account in ",(0,s.jsx)(i.em,{children:"accounts.toml"}),", containing the account's public key, main purse balance and validator config."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"public_key"})," The public key of the account, serialized as the byte representation of ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:"itself"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance"})," The balance of the account's main purse, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512 value"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator"})," The validator configuration for the account, serialized as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."]}),"\n",(0,s.jsx)(i.h2,{id:"account-identifier",children:"Account Identifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve an Account. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),": The account's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),": The ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of the account's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"activation-point",children:"Activation Point"}),"\n",(0,s.jsxs)(i.p,{children:["The first era to which the associated protocol version applies. It serializes as a single ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,s.jsx)(i.code,{children:"timestamp"}),". If not, the bytes represent an ",(0,s.jsx)(i.code,{children:"era_id"}),"."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_id"}),": An ",(0,s.jsx)(i.a,{href:"#eraid",children:"Era ID newtype"})," identifying the era when the protocol version will activate."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A ",(0,s.jsx)(i.a,{href:"#timestamp",children:"timestamp"})," if the activation point is of the Genesis variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"addressable-entity-hash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(i.p,{children:"The hex-encoded address of an addressable entity, which serializes as the byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(i.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"Signature"})}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(i.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(i.a,{href:"#digest",children:(0,s.jsx)(i.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"account_hash"}),": The ",(0,s.jsx)(i.a,{href:"#account-hash",children:"account hash"})," of the associated key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"weight"}),": The weight of an associated key. The weight serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsxs)(i.p,{children:["An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," values"]})," containing the following two fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"low"}),": The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"high"}),": - The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddr",children:"BalanceHoldAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A balance hold address. It serializes as a ",(0,s.jsx)(i.a,{href:"#balanceholdaddrtag",children:(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})})," describing the type of balance hold address as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Gas"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Processing"})," serializes as a ",(0,s.jsx)(i.code,{children:"BalanceHoldAddrTag"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:"URef"})," of the purse the hold will be placed on, and the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"block_time"})})," that the hold was placed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"balanceholdaddrtag",children:"BalanceHoldAddrTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag describing the type of ",(0,s.jsx)(i.code,{children:"BalanceHoldAddr"}),", serializing as a single ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"balance-response",children:"BalanceResponse"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BalanceResponse"})," is a struct that provides the response to a balance query. It consists of the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance"}),": The purse's total balance, not considering holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"available_balance"}),": The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"total_balance_proof"}),": A proof that the given value is present in the Merkle trie. It serializes as a ",(0,s.jsx)(i.code,{children:"TrieMerkleProof"}),", consisting of a key, a value and a ",(0,s.jsx)(i.code,{children:"proof_step"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"balance_holds"}),": Any time-relevant active holds on the balance. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"BlockTime"})," and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"BlockTime"}),"s and ",(0,s.jsx)(i.code,{children:"BalanceHoldsWithProof"}),"s of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The validator's public key. It serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The purse used for bonding. It serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"Uref"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate of the bid. It serializes as an ",(0,s.jsx)(i.code,{children:"i32"})," signed 32-bit integer primitive."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for a genesis validator. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegators"}),": The validator's delegators, indexed by their public keys. They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"PublicKey"}),"s and then delegators of the length dictated by the first four bytes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": If the validator has been evicted. A ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-boolean",children:"boolean"})," value that serializes as a single byte; ",(0,s.jsx)(i.code,{children:"true"})," maps to ",(0,s.jsx)(i.code,{children:"1"}),", while ",(0,s.jsx)(i.code,{children:"false"})," maps to ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bidaddr",children:"BidAddr"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," manages data associated with bids for the ",(0,s.jsx)(i.code,{children:"Auction"})," system contract. It serializes as a single ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Unified"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," for legacy unified bids. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," identifying the legacy bid."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Validator"})," A validator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," A delegator bid. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the associated validator and then the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the delegator."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Credit"})," A ",(0,s.jsx)(i.code,{children:"BidAddr"})," representing an auction credit. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"4"})," followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the validator and the ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," for the applicable credit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"bid-kind",children:"BidKind"}),"\n",(0,s.jsxs)(i.p,{children:["Auction bid variants. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]})," indicating the type of bid kind as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"BidKind"}),(0,s.jsx)(i.th,{children:"u8"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#bid",children:"Unified"})}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Legacy data that contains all delegators for a given validator."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#validatorbid",children:"Validator"})}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"A bid record containing only validator data."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.a,{href:"#delegatorbid",children:"Delegator"})}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"A bid record containing only delegator data."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"blockglobaladdr",children:"BlockGlobalAddr"}),"\n",(0,s.jsx)(i.p,{children:"An address for singleton values associated to a specific block. These are values which are calculated or set during the execution of a block such as the block timestamp, or the total count of messages emitted during the execution of the block."}),"\n",(0,s.jsxs)(i.p,{children:["It serializes as two ",(0,s.jsx)(i.code,{children:"u8"})," values, the first of which describes the category, followed by the underlying value as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockTime"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"u8"})," of the block time."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"MessageCount"})," begins with a ",(0,s.jsx)(i.code,{children:"u8"})," of 1, followed by message count as a ",(0,s.jsx)(i.code,{children:"u8"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(i.p,{children:"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"hash"})}),": Identify and retrieve a Block with its hash. The ",(0,s.jsx)(i.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"height"}),": Identify and retrieve the Block with its height. Height serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"state_root_hash"}),": Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(i.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"block-signatures",children:"BlockSignatures"}),"\n",(0,s.jsx)(i.p,{children:"A collection of signatures for a single block, along with the associated block's hash and era ID."}),"\n",(0,s.jsxs)(i.p,{children:["There are two possible versions for ",(0,s.jsx)(i.code,{children:"BlockSignatures"}),", with a prefixed ",(0,s.jsx)(i.code,{children:"u8"})," tag describing which version it is."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v1",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#block-signatures-v2",children:(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"BlockSignaturesV2"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v1",children:"BlockSignaturesV1"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV1"})," is a legacy version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created before the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-signatures-v2",children:"BlockSignaturesV2"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"BlockSignaturesV2"})," is the current version of ",(0,s.jsx)(i.code,{children:"BlockSignatures"})," that applies to blocks created after the Condor release. The structure is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#block-hash",children:(0,s.jsx)(i.code,{children:"block_hash"})}),": The block hash of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_height"}),": The block height. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID in which this block was created. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#chain-name-digest",children:(0,s.jsx)(i.code,{children:"chain_name_hash"})}),": The hash of the chain name of the associated block. It serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"proofs"}),": The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKeys"})})," and ",(0,s.jsx)(i.a,{href:"#signature",children:(0,s.jsx)(i.code,{children:"signatures"})})," held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The status of syncing an individual block. It serializes as the byte representation of the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#block-hash",children:"block hash"})," of the block in question, followed by an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"option"})})," representing a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," of the block height and the remainder is the byte representation of the ",(0,s.jsx)(i.code,{children:"acquisition_state"})," as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"string"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(i.p,{children:["The block time serialized as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"btreemap",children:"BTreeMap"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeMap"})," is a method of mapping keys to values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of keys and values held within. The remainder consists of a repeating pattern of serialized keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"btreeset",children:"BTreeSet"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"BTreeSet"})," is a method of storing a set of values within a Casper network. They serialize with the first 4 bytes representing a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating series of values of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsxs)(i.p,{children:["A container for a contract's Wasm bytes. It serializes as the single ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#bid-kind",children:"BidKind"}),", followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value describing the size of the remaining ",(0,s.jsx)(i.a,{href:"#bytes",children:"Bytes"})," and then the bytes as described."]}),"\n",(0,s.jsx)(i.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded bytes serialized as a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the length of the bytes, followed by the bytes themselves."]}),"\n",(0,s.jsx)(i.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of byte code, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," value. A ",(0,s.jsx)(i.code,{children:"0"})," indicates empty byte code, while a ",(0,s.jsx)(i.code,{children:"1"})," indicates a ",(0,s.jsx)(i.code,{children:"V1CasperWasm"})," to be executed with the first version of the Casper execution engine."]}),"\n",(0,s.jsx)(i.h2,{id:"caller",children:"Caller"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"})," is the identity of a calling entity. It serializes as one of two variants, described below:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Initiator"})," is the overall calling account and serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Entity"})," is a calling entity, such as a smart contract or a system contract. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"package_hash"})})," and ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"entity_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"call-stack-element",children:"CallStackElement"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"CallStackElement"})," is a legacy ",(0,s.jsx)(i.code,{children:"enum"})," created pre-Condor release that represents the origin of a sub-call in a call stack. It begins with a ",(0,s.jsx)(i.code,{children:"u8"})," tag that describes the type of caller as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Session"}),": Session code, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})," of the calling account."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredSession"}),": Stored access to a session, serializing as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),", ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContract"}),": A contract, which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})," and the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"chain-name-digest",children:"ChainNameDigest"}),"\n",(0,s.jsx)(i.p,{children:"The cryptographic hash of a chain name, serialized as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h2,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,s.jsx)(i.em,{children:"Chainspec.toml"})," and may include ",(0,s.jsx)(i.em,{children:"Accounts.toml"})," and ",(0,s.jsx)(i.em,{children:"GlobalState.toml"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"chainspec_raw_hash"})," will always be included."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"genesis_accounts_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"global_state_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"checksum-registry",children:"ChecksumRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["The checksum registry. It serializes as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of checksum names as strings and ",(0,s.jsx)(i.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(i.p,{children:'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegator_public_key"}),": The public key of the delegator, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash digest. The digest serializes as a byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,s.jsx)(i.p,{children:"Disabled contract versions, containing the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(i.p,{children:["A log of all transforms produced during execution, serialized as a vector of ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transforms"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-action-thresholds",children:"Entity Action Thresholds"}),"\n",(0,s.jsxs)(i.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deployment"}),": The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"upgrade_management"}),": The minimum weight threshold required to perform upgrade management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key_management"}),": The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(i.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-addr",children:"EntityAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address for an ",(0,s.jsx)(i.code,{children:"AddressableEntity"}),". It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," followed by the 32-byte buffer containing the bytes of the ",(0,s.jsx)(i.code,{children:"hash_addr"})," as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0, followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by the ",(0,s.jsx)(i.code,{children:"hash_addr"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind",children:"EntityKind"}),"\n",(0,s.jsxs)(i.p,{children:["The type of ",(0,s.jsx)(i.code,{children:"Package"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," ",(0,s.jsx)(i.a,{href:"#entity-kind-tag",children:(0,s.jsx)(i.code,{children:"EntityKindTag"})})," describing the type followed by further data as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"System"}),": A package associated with a native contract implementation. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by a ",(0,s.jsx)(i.a,{href:"#system-entity-type",children:(0,s.jsx)(i.code,{children:"SystemEntityType"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Account"}),": A package associated with an Account hash, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SmartContract"}),": A package associated with Wasm stored on chain, serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," of 2 followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#transactionruntime",children:(0,s.jsx)(i.code,{children:"transaction_runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entity-kind-tag",children:"EntityKindTag"}),"\n",(0,s.jsxs)(i.p,{children:["A tag for the variants of ",(0,s.jsx)(i.code,{children:"EntityKind"}),", serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 for ",(0,s.jsx)(i.code,{children:"System"}),", 1 for ",(0,s.jsx)(i.code,{children:"Account"})," and 2 for ",(0,s.jsx)(i.code,{children:"SmartContract"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(i.p,{children:["The major element of ",(0,s.jsx)(i.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(i.code,{children:"EntityVersion"})," serialized as two ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(i.h2,{id:"entity-versions",children:"EntityVersions"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of entity versions, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"EntityVersionKeys"})})," mapped to ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})})," within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"EntityVersionKeys"})," and ",(0,s.jsx)(i.code,{children:"AddressableEntityHashes"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoint",children:"EntryPoint (Contract)"}),"\n",(0,s.jsx)(i.p,{children:"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entry_point_type"}),": Identifies the type of entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"0"})," for Session and a ",(0,s.jsx)(i.code,{children:"1"})," for Contract."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entry-point",children:"EntryPoint (Entity)"}),"\n",(0,s.jsx)(i.p,{children:"The type signature of a method. This structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry point, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"args"}),": Arguments for this method. They serialize as a list of the ",(0,s.jsx)(i.a,{href:"#parameter",children:(0,s.jsx)(i.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ret"}),": The return type of the method, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(i.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"access"}),": An ",(0,s.jsx)(i.code,{children:"enum"})," describing the possible access control options for a contract entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," value of 1 for public or a 2 followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/next/developers/json-rpc/types_chain#entrypoint",children:(0,s.jsx)(i.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/next/developers/json-rpc/types_chain#entrypointpayment",children:(0,s.jsx)(i.code,{children:"entry_point_payment"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointaddr",children:"EntryPointAddr"}),"\n",(0,s.jsx)(i.p,{children:"An entry point's address. It serializes as one of the two following variants:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV1"}),": A V1 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 0 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," and ",(0,s.jsx)(i.code,{children:"name_bytes"}),", which is the 32-byte hash of the name of the entry point."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"VmCasperV2"}),": A V2 entry point. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of 1 followed by an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," ",(0,s.jsx)(i.code,{children:"Selector"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointpayment",children:"EntrypointPayment"}),"\n",(0,s.jsxs)(i.p,{children:["An ",(0,s.jsx)(i.code,{children:"enum"})," specifying who pays for the invocation and execution of an entry point. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," byte tag as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a 0 and indicates that the caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnly"}),": Serializes as a 1 and indicates that the contract will pay the cost to execute itself, but no subsequent invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"SelfOnward"}),": Serializes as a 2 and indicates that the contract will pay for executing itself and any subsequent invocations."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"entrypointtype",children:"EntrypointType"}),"\n",(0,s.jsx)(i.p,{children:"The context of method execution. It serializes as one of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Caller"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000000"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Called"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b00000001"})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Factory"}),": Serializes as a single ",(0,s.jsx)(i.code,{children:"u8"}),", ",(0,s.jsx)(i.code,{children:"0b10000000"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"entrypointv2",children:"EntrypointV2"}),"\n",(0,s.jsxs)(i.p,{children:["The entry point for the V2 Casper VM. It serializes as a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Selector"})," followed by a ",(0,s.jsx)(i.code,{children:"u32"})," representing the ",(0,s.jsx)(i.code,{children:"Flags"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"entrypoints",children:"EntryPoints"}),"\n",(0,s.jsxs)(i.p,{children:["Entry points for a given entity, serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"String"})," to ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"String"}),"s and then ",(0,s.jsx)(i.code,{children:"EntryPoint"}),"s of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsxs)(i.p,{children:["An Era ID newtype. It serializes as a single ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u64"})," value"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsxs)(i.p,{children:["Auction metadata, intended to be recorded each era. It serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#seigniorageallocation",children:"seigniorage allocations"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"executable-deploy-item",children:"ExecutableDeployItem"}),"\n",(0,s.jsxs)(i.p,{children:["The executable component of a ",(0,s.jsx)(i.code,{children:"Deploy"}),", serialized as a ",(0,s.jsx)(i.code,{children:"u8"})," identifying tag followed by additional bytes as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"ModuleBytes"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by ",(0,s.jsx)(i.a,{href:"#bytes",children:(0,s.jsx)(i.code,{children:"bytes"})})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by the contract hash as an ",(0,s.jsx)(i.a,{href:"#addressable-entity-hash",children:(0,s.jsx)(i.code,{children:"AddressableEntityHash"})}),", the name of an entry point as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 2 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByHash"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 3 followed by the ",(0,s.jsx)(i.a,{href:"#package-hash",children:(0,s.jsx)(i.code,{children:"PackageHash"})}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", an entry point as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"StoredVersionedContractByName"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 4 followed by the named key as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"}),", the ",(0,s.jsx)(i.code,{children:"version"})," as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),", the name of an entry point as a ",(0,s.jsx)(i.code,{children:"String"})," and ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Transfer"}),": Serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 5 followed by ",(0,s.jsx)(i.a,{href:"#runtimeargs",children:(0,s.jsx)(i.code,{children:"runtimeargs"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(i.p,{children:"The journal of execution transforms from a single deploy."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"operations"}),": The resulting operations, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," of ",(0,s.jsx)(i.a,{href:"#operation",children:"operations"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transforms"}),": The actual ",(0,s.jsx)(i.a,{href:"#transformV2",children:"transformation"})," performed while executing a deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single deploy. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effect"}),": The ",(0,s.jsx)(i.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the deploy, serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsxs)(i.p,{children:["The result of a single transaction. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(i.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(i.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(i.h3,{id:"failure-1",children:(0,s.jsx)(i.code,{children:"Failure"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effect"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"error_message"}),": The error message associated with executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"success-1",children:(0,s.jsx)(i.code,{children:"Success"})}),"\n",(0,s.jsx)(i.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"effects"}),": The ",(0,s.jsx)(i.a,{href:"#effects",children:"effects"})," of executing the transaction."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": A record of transfers performed while executing the transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"cost"}),": The cost of executing the transaction, serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(i.p,{children:["The ",(0,s.jsx)(i.code,{children:"Gas"})," structure serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," amount of gas."]}),"\n",(0,s.jsx)(i.h2,{id:"group",children:"Group"}),"\n",(0,s.jsxs)(i.p,{children:['A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"groups",children:"Groups"}),"\n",(0,s.jsxs)(i.p,{children:["They are serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,s.jsx)(i.code,{children:"BTreeSets"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsxs)(i.p,{children:["The address of the initiator of a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#transactionV1",children:(0,s.jsx)(i.code,{children:"TransactionV1"})}),", which serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," of ",(0,s.jsx)(i.code,{children:"0"})," followed by a ",(0,s.jsx)(i.a,{href:"#publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," or a ",(0,s.jsx)(i.code,{children:"1"})," followed by an ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"AccountHash"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-state-keys",children:"Keys"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.em,{children:"key"})," in ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design",children:"Global State"})," is one of the following data types:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:'32-byte account identifier (called an "account identity key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte immutable contract identifier (called a "hash key")'}),"\n",(0,s.jsx)(i.li,{children:'32-byte reference identifier (called an "unforgeable reference")'}),"\n",(0,s.jsx)(i.li,{children:"32-byte transfer identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte deploy information identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte purse balance identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction bid identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction withdrawal identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Dictionary identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte System Contract Registry"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Auction unbond identifier"}),"\n",(0,s.jsx)(i.li,{children:"32-byte Chainspec Registry"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The one exception to note here is the identifier for ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})}),", which actually serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value with an additional byte for the tag."]}),"\n",(0,s.jsx)(i.h3,{id:"global-state-account-key",children:"Account Identity Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-hash-key",children:"Hash Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy hash (see ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"block-structure-head"})," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-uref",children:["Unforgeable Reference (",(0,s.jsx)(i.code,{children:"URef"}),")"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"URef"})," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,s.jsx)(i.code,{children:"URef"}),". ",(0,s.jsx)(i.code,{children:"URef"})," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#uref-head",children:"Unforgeable Reference"})," section for details on how ",(0,s.jsx)(i.code,{children:"URefs"})," are managed."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-transfer-key",children:"Transfer Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the transfer address associated with the given transfer."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-deploy-info-key",children:"DeployInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the deploy itself."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-era-info-key",children:"EraInfo Key"}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to the ",(0,s.jsx)(i.code,{children:"Auction"})," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,s.jsx)(i.code,{children:"u64"})," data type and co-relates to the era number when the auction information was stored."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.p,{children:["This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(i.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(i.h3,{id:"serialization-standard-serialization-key",children:["Serialization for ",(0,s.jsx)(i.code,{children:"Key"})]}),"\n",(0,s.jsxs)(i.p,{children:["Given the different variants for the over-arching ",(0,s.jsx)(i.code,{children:"Key"})," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:(0,s.jsx)(i.code,{children:"Key"})}),(0,s.jsx)(i.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Account"})}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Hash"})}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"URef"})}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Transfer"})}),(0,s.jsx)(i.td,{children:"3"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"DeployInfo"})}),(0,s.jsx)(i.td,{children:"4"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraInfo"})}),(0,s.jsx)(i.td,{children:"5"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Balance"})}),(0,s.jsx)(i.td,{children:"6"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Bid"})}),(0,s.jsx)(i.td,{children:"7"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Withdraw"})}),(0,s.jsx)(i.td,{children:"8"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Dictionary"})}),(0,s.jsx)(i.td,{children:"9"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"SystemContractRegistry"})}),(0,s.jsx)(i.td,{children:"10"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"EraSummary"})}),(0,s.jsx)(i.td,{children:"11"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Unbond"})}),(0,s.jsx)(i.td,{children:"12"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChainspecRegistry"})}),(0,s.jsx)(i.td,{children:"13"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"ChecksumRegistry"})}),(0,s.jsx)(i.td,{children:"14"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"BidAddr"})}),(0,s.jsx)(i.td,{children:"15"})]})]})]}),"\n",(0,s.jsxs)(i.p,{children:["| ",(0,s.jsx)(i.code,{children:"Package"})," | 16 |\n| ",(0,s.jsx)(i.code,{children:"AddressableEntity"})," | 17 |\n| ",(0,s.jsx)(i.code,{children:"ByteCode"})," | 18 |\n| ",(0,s.jsx)(i.code,{children:"Message"})," | 19 |"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"AccountHash"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Hash"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(i.code,{children:"Hash"})," itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"URef"})," is a tuple that contains the address of the URef and the access rights to that ",(0,s.jsx)(i.code,{children:"URef"}),". The serialized representation of the ",(0,s.jsx)(i.code,{children:"URef"})," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,s.jsx)(i.code,{children:"URef"})," address, and the last byte contains the bits corresponding to the access rights of the ",(0,s.jsx)(i.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue",children:"CLValue"})," section of this chapter for details on how ",(0,s.jsx)(i.code,{children:"AccessRights"})," are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Transfer"})," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"DeployInfo"})," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraInfo"})," serializes a ",(0,s.jsx)(i.code,{children:"u64"})," primitive type containing the little-endian byte representation of ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Balance"})," serializes as 32 byte long buffer containing the byte representation of the URef address."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Bid"})," and ",(0,s.jsx)(i.code,{children:"Withdraw"})," both contain the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as their identifier; therefore, they serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Dictionary"})," serializes as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"SystemContractRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"EraSummary"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unbond"})," contains the ",(0,s.jsx)(i.code,{children:"AccountHash"})," as its identifier; therefore, it serialize in the same manner as the ",(0,s.jsx)(i.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChainspecRegistry"})," serializes as a 32 byte long buffer of ones."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ChecksumRegistry"})," serializes as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"BidAddr"})," may be one of three types:\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Unified"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"0"})," followed by a 32 byte long buffer containing the byte representation of a legacy bid."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Validator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"1"})," followed by a 32 byte long buffer containing the byte representation of a validator's hash."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Delegator"})," serializes as the tag ",(0,s.jsx)(i.code,{children:"2"})," followed by a 32 byte long buffer containing the byte representation of the associated validator's hash, appended with a 32 byte long buffer containing the byte representation of the given delegator's hash."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-permissions",children:"Permissions"}),"\n",(0,s.jsxs)(i.p,{children:["There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,s.jsx)(i.em,{children:"add"})," to be called out separately from ",(0,s.jsx)(i.em,{children:"write"})," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Key"}),(0,s.jsx)(i.th,{children:"Type Available Actions"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Account"}),(0,s.jsx)(i.td,{children:"Read + Add (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Hash"}),(0,s.jsx)(i.td,{children:"Read"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"URef"}),(0,s.jsx)(i.td,{children:"Read + Write and/or Add"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Transfer"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Deploy"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"EraInfo"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Balance"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Bid"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Withdraw"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Dictionary"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"SystemContractRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Unbond"}),(0,s.jsx)(i.td,{children:"System"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"ChainspecRegistry"}),(0,s.jsx)(i.td,{children:"Read (via API)"})]})]})]}),"\n",(0,s.jsx)(i.hr,{}),"\n",(0,s.jsxs)(i.p,{children:["Refer to ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#uref-permissions",children:"URef permissions"})," on how permissions are handled in the case of ",(0,s.jsx)(i.code,{children:"URef"}),"s."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topics",children:"MessageTopics"}),"\n",(0,s.jsxs)(i.p,{children:["A topic for contract-level messages. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.code,{children:"topic_name"})," strings and ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"topic_name_hash"})})," held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(i.code,{children:"topic_name"})," and ",(0,s.jsx)(i.code,{children:"topic_name_hash"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"message-topic-summary",children:"MessageTopicSummary"}),"\n",(0,s.jsxs)(i.p,{children:["A summary of a message topic that will be stored in global state. It serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value for the ",(0,s.jsx)(i.code,{children:"message_count"})," followed by the ",(0,s.jsx)(i.a,{href:"#blocktime",children:(0,s.jsx)(i.code,{children:"BlockTime"})})]}),"\n",(0,s.jsx)(i.h2,{id:"motes",children:"Motes"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing a number of ",(0,s.jsx)(i.code,{children:"Motes"})," serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsxs)(i.p,{children:["Named arguments to a contract. It is serialized by the combination of a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by the associated ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsxs)(i.p,{children:["A mapping of string identifiers to a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"name"}),": The name of the entry. It serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The value of the entry, which is a Casper ",(0,s.jsx)(i.code,{children:"Key"})," type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,s.jsx)(i.code,{children:"Key"})," values as described ",(0,s.jsx)(i.a,{href:"#serialization-standard-serialization-key",children:"here"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-addr",children:"NamedKeyAddr"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey address, serialized as an ",(0,s.jsx)(i.a,{href:"#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})})," followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," describing the length of a string and the 32-byte representation of the string itself."]}),"\n",(0,s.jsx)(i.h2,{id:"named-key-value",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(i.p,{children:["A NamedKey value, serialized as the ",(0,s.jsx)(i.code,{children:"named_key"})," serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," followed by the ",(0,s.jsx)(i.code,{children:"name"})," of the key also serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"named-keys",children:"NamedKeys"}),"\n",(0,s.jsxs)(i.p,{children:["A collection of named keys. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"names"})})," and ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-key",children:(0,s.jsx)(i.code,{children:"keys"})})," held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(i.p,{children:"An operation performed while executing a deploy. It contains:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"key"}),": The formatted string of the key, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"kind"}),": OpKind, The type of operation performed. It serializes as a single byte based on the following table:"]}),"\n"]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"OpKind"}),(0,s.jsx)(i.th,{children:"Serialization"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Read"}),(0,s.jsx)(i.td,{children:"0"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add"}),(0,s.jsx)(i.td,{children:"2"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"NoOp"}),(0,s.jsx)(i.td,{children:"3"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(i.p,{children:"A structure defining an entity, metadata and security container. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"versions"}),": An array of entity versions associated with given hashes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#entityversionkey",children:(0,s.jsx)(i.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#group",children:(0,s.jsx)(i.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contractpackagestatus",children:(0,s.jsx)(i.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"package-hash",children:"PackageHash"}),"\n",(0,s.jsxs)(i.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#addressable-entity",children:(0,s.jsx)(i.code,{children:"AddressableEntity"})}),", serialized as the byte representation of itself."]}),"\n",(0,s.jsx)(i.h2,{id:"package-status",children:"PackageStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The lock status of the package, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})})," where ",(0,s.jsx)(i.code,{children:"true"})," indicates a locked package and ",(0,s.jsx)(i.code,{children:"false"})," indicates an unlocked package."]}),"\n",(0,s.jsx)(i.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsxs)(i.p,{children:["Parameter to a method, structured as a name followed by a ",(0,s.jsx)(i.code,{children:"CLType"}),". It is serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," followed by a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(i.code,{children:"CLType"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsxs)(i.p,{children:["The pricing mode of a transaction, with two possible variants. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag followed by additional data based on the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"PricingMode"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Classic"}),(0,s.jsx)(i.td,{children:"The original payment model, in which the creator of a transaction specifies how much they will pay and at which gas price."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Fixed"}),(0,s.jsx)(i.td,{children:"The cost of the transaction is determined by the cost table, per the transaction kind."})]})]})]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-classic",children:"Classic"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"0"})," tag, a ",(0,s.jsx)(i.code,{children:"Classic"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"payment_amount"})," followed by the ",(0,s.jsx)(i.code,{children:"u64"})," value of the ",(0,s.jsx)(i.code,{children:"gas_price"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"pricingmode-fixed",children:"Fixed"}),"\n",(0,s.jsxs)(i.p,{children:["After the ",(0,s.jsx)(i.code,{children:"1"})," tag, a ",(0,s.jsx)(i.code,{children:"Fixed"})," ",(0,s.jsx)(i.code,{children:"PricingMode"})," serializes as the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," ",(0,s.jsx)(i.code,{children:"gas_price_tolerance"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsxs)(i.p,{children:["A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values indicating major, minor and patch versions in that order."]}),"\n",(0,s.jsx)(i.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(i.p,{children:["Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"rewarded-signatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(i.p,{children:["A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(i.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(i.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsxs)(i.p,{children:["Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})})," comprised of ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-tuple",children:(0,s.jsx)(i.code,{children:"Tuples"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(i.p,{children:"Information about seigniorage allocation."}),"\n",(0,s.jsxs)(i.p,{children:["If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," followed by the ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["If it is a delegator, it serializes as the delegator's ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),", followed by the validator's ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})})," and finally the ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"semver",children:"SemVer"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," for semantic versioning, it serializes as three ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," that describe the major version, minor version and patch version."]}),"\n",(0,s.jsx)(i.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsxs)(i.p,{children:["The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-values",children:"Stored Values"}),"\n",(0,s.jsxs)(i.p,{children:["A value stored in the global state is a ",(0,s.jsx)(i.code,{children:"StoredValue"}),". A ",(0,s.jsx)(i.code,{children:"StoredValue"})," is one of three possible variants:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["A ",(0,s.jsx)(i.code,{children:"CLValue"})]}),"\n",(0,s.jsx)(i.li,{children:"A contract"}),"\n",(0,s.jsx)(i.li,{children:"An account"}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["We discuss ",(0,s.jsx)(i.code,{children:"CLValue"})," and contract in more detail below. Details about accounts can be found in ",(0,s.jsx)(i.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"accounts-head"}),"."]}),"\n",(0,s.jsxs)(i.p,{children:["Each ",(0,s.jsx)(i.code,{children:"StoredValue"})," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,s.jsx)(i.code,{children:"StoredValue"})," it is, followed by the serialization of that variant. The tag for each variant is as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"CLValue"})," is ",(0,s.jsx)(i.code,{children:"0"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Account"})," is ",(0,s.jsx)(i.code,{children:"1"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"Contract"})," is ",(0,s.jsx)(i.code,{children:"2"})]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["The details of ",(0,s.jsx)(i.code,{children:"CLType"})," serialization are in the following section. Using the serialization format for ",(0,s.jsx)(i.code,{children:"CLValue"})," as a basis, we can succinctly write the serialization rules for contracts and accounts:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["contracts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"}),";"]}),"\n",(0,s.jsxs)(i.li,{children:["accounts serialize in the same way as data with ",(0,s.jsx)(i.code,{children:"CLType"})," equal to ",(0,s.jsx)(i.code,{children:"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note: ",(0,s.jsx)(i.code,{children:"Tuple5"})," is not a presently supported ",(0,s.jsx)(i.code,{children:"CLType"}),". However, it is clear how to generalize the rules for ",(0,s.jsx)(i.code,{children:"Tuple1"}),", ",(0,s.jsx)(i.code,{children:"Tuple2"}),", ",(0,s.jsx)(i.code,{children:"Tuple3"})," to any size tuple."]}),"\n",(0,s.jsx)(i.h2,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,s.jsxs)(i.p,{children:["SystemContractRegistry is a unique ",(0,s.jsx)(i.code,{children:"Key"})," under which a mapping of the names and ",(0,s.jsx)(i.code,{children:"ContractHashes"})," for system contracts. This includes ",(0,s.jsx)(i.code,{children:"Mint"}),", ",(0,s.jsx)(i.code,{children:"Auction"}),", ",(0,s.jsx)(i.code,{children:"HandlePayment"})," and ",(0,s.jsx)(i.code,{children:"StandardPayment"}),". It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contracthash",children:"ContractHashes"})," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(i.h2,{id:"system-entity-type",children:"SystemEntityType"}),"\n",(0,s.jsxs)(i.p,{children:["Entity types for system contracts, serialized as a single ",(0,s.jsx)(i.code,{children:"u8"})," tag identifying the contract as per the following table:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"System Contract"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Mint"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"Auction"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"StandardPayment"})})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:(0,s.jsx)(i.code,{children:"HandlePayment"})})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsxs)(i.p,{children:["A human-readable duration between two timestamps. It serializes as a single ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsxs)(i.p,{children:["A timestamp formatted as per RFC 3339 and serialized as a single ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(i.h2,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a topic name. The topic name hash serializes as a 32-byte buffer containing the bytes of the topic name hash."]}),"\n",(0,s.jsx)(i.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(i.p,{children:"Hex-encoded transfer address, which serializes as a byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV1",children:"TransformKindV1"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_CLValue"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue",children:(0,s.jsx)(i.code,{children:"CLValue"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Account"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#account-hash",children:(0,s.jsx)(i.code,{children:"Account"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_WASM"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contractwasmhash",children:"contract as Wasm"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contracthash",children:"contract"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Contract_Package"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Writes a smart ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#contractpackagehash",children:"contract package"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Deploy_Info"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/structures#deployinfo",children:(0,s.jsx)(i.code,{children:"DeployInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Transfer"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#transferaddr",children:"Transfer"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Era_Info"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#erainfo",children:(0,s.jsx)(i.code,{children:"EraInfo"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Bid"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#bid",children:(0,s.jsx)(i.code,{children:"Bid"})})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write_Withdraw"}),(0,s.jsx)(i.td,{children:"10"}),(0,s.jsxs)(i.td,{children:["Writes the given ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_INT32"}),(0,s.jsx)(i.td,{children:"11"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT64"}),(0,s.jsx)(i.td,{children:"12"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT128"}),(0,s.jsx)(i.td,{children:"13"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT256"}),(0,s.jsx)(i.td,{children:"14"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_UINT512"}),(0,s.jsx)(i.td,{children:"15"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Add_Keys"}),(0,s.jsx)(i.td,{children:"16"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"17"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformkindV2",children:"TransformKindV2"}),"\n",(0,s.jsxs)(i.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(i.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Transform Type"}),(0,s.jsx)(i.th,{children:"Serialization"}),(0,s.jsx)(i.th,{children:"Description"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Identity"}),(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"A transform having no effect, created as a result of reading from the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Write"}),(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Writes a new value in the global state."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddInt32"}),(0,s.jsx)(i.td,{children:"2"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt64"}),(0,s.jsx)(i.td,{children:"3"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt128"}),(0,s.jsx)(i.td,{children:"4"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt256"}),(0,s.jsx)(i.td,{children:"5"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddUInt512"}),(0,s.jsx)(i.td,{children:"6"}),(0,s.jsxs)(i.td,{children:["Adds the given ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"AddKeys"}),(0,s.jsx)(i.td,{children:"7"}),(0,s.jsxs)(i.td,{children:["Adds the given collection of ",(0,s.jsx)(i.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Failure"}),(0,s.jsx)(i.td,{children:"8"}),(0,s.jsx)(i.td,{children:"A failed transformation, containing an error message."})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"Prune"}),(0,s.jsx)(i.td,{children:"9"}),(0,s.jsx)(i.td,{children:"Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,s.jsx)(i.p,{children:"A transformation performed while executing a deploy."}),"\n",(0,s.jsx)(i.h2,{id:"transformV1",children:"TransformV1"}),"\n",(0,s.jsxs)(i.p,{children:["A legacy transform struct serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV1",children:(0,s.jsx)(i.code,{children:"transformkindv1"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"transformV2",children:"Transformv2"}),"\n",(0,s.jsxs)(i.p,{children:["A struct representing an executed transformation serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})})," of the ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-key",children:"key"})," followed by the ",(0,s.jsx)(i.a,{href:"#transformkindV2",children:(0,s.jsx)(i.code,{children:"transformkindv2"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(i.p,{children:"A purse used for unbonding. The structure consists of the following:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"}),": Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"new_validator"}),": The validator public key to redelegate to, serialized as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," containing the public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(i.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:[(0,s.jsx)(i.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"staked_amount"}),": The amount staked by the delegator, serialized as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"delegation_rate"}),": The delegation rate serialized as a ",(0,s.jsxs)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"vesting_schedule"}),": The vesting schedule for the provided delegator bid. ",(0,s.jsx)(i.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"inactive"}),": The validator's inactivity status, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"validator-change",children:"ValidatorChange"}),"\n",(0,s.jsxs)(i.p,{children:["A change to a validator's status between two eras, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"Change"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Added"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Removed"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"Banned"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:"Cannot Propose"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"4"}),(0,s.jsx)(i.td,{children:"Seen as Faulty"})]})]})]}),"\n",(0,s.jsx)(i.h2,{id:"validator-config",children:"ValidatorConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A validator account configuration, serialized as a ",(0,s.jsx)(i.a,{href:"#motes",children:(0,s.jsx)(i.code,{children:"bonded_amount"})})," followed by the ",(0,s.jsx)(i.code,{children:"delegation_rate"})," as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),"."]}),"\n",(0,s.jsx)(i.h2,{id:"validator-credit",children:"ValidatorCredit"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," representing the record of a validator credit, with fields as follows:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"validator_public_key"})}),": The validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),": The era ID the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"}),": The credit amount as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsxs)(i.p,{children:["A purse used for unbonding, replaced in 1.5 by ",(0,s.jsx)(i.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"bonding_purse"}),": The bonding purse, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"validator_public_key"}),": The public key of the validator, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"unbonder_public_key"}),": The public key of the unbonder, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-publickey",children:(0,s.jsx)(i.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(i.a,{href:"#eraid",children:(0,s.jsx)(i.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(i.a,{href:"/next/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>l,x:()=>c});var s=n(96540);const r={},t=s.createContext(r);function l(e){const i=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(t.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64959b1e.2d006066.js b/assets/js/64959b1e.2d006066.js new file mode 100644 index 000000000..d19a21bd5 --- /dev/null +++ b/assets/js/64959b1e.2d006066.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67796],{16527:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>h});var t=s(74848),i=s(28453);const a={title:"Network Design"},o="Casper Network Design",c={id:"concepts/design/casper-design",title:"Network Design",description:"Introduction",source:"@site/docs/concepts/design/casper-design.md",sourceDirName:"concepts/design",slug:"/concepts/design/casper-design",permalink:"/concepts/design/casper-design",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724755224e3,frontMatter:{title:"Network Design"},sidebar:"concepts",previous:{title:"Design Overview",permalink:"/design"},next:{title:"Network Communication",permalink:"/concepts/design/p2p"}},r={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Execution Semantics",id:"execution-semantics-head",level:2},{value:"Measuring Computational Work",id:"execution-semantics-gas",level:3},{value:"The Casper Network Runtime",id:"execution-semantics-runtime",level:3},{value:"Generating <code>URef</code>s",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for <code>URef</code>s",id:"uref-permissions",level:3},{value:"<code>URef</code>s and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"<code>block_hash</code>",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Addressable Entities",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-network-design",children:"Casper Network Design"})}),"\n",(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#consensus",children:"consensus"}),". A Casper network stores data in a structure known as ",(0,t.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"}),". Users interact with global state through session code sent in a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/T#transaction",children:"transaction"}),". Transactions may contain ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"Wasm"})," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."]}),"\n",(0,t.jsxs)(n.p,{children:["A transaction executes in the context of the user's ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"Account"})," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(n.code,{children:"URef"}),". After a node accepts a transaction as valid, it places the transaction in a proposed ",(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block"})," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#accounts-head",children:"Accounts"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference (URef)"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block Structure"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#tokens-head",children:"Tokens"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-head",children:"Execution Semantics"}),"\n",(0,t.jsx)(n.p,{children:"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-gas",children:"Measuring Computational Work"}),"\n",(0,t.jsxs)(n.p,{children:["Computation is done in a ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"WebAssembly (Wasm)"})," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,t.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:(0,t.jsx)(n.code,{children:"Gas"})})," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,t.jsx)(n.code,{children:"Gas"})," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."]}),"\n",(0,t.jsxs)(n.p,{children:["Costs for opcode instructions on the Casper Mainnet network can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["All executions are finite because each has a finite ",(0,t.jsx)(n.em,{children:"gas limit"})," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction."]}),"\n",(0,t.jsxs)(n.p,{children:["Although the network measures costs in ",(0,t.jsx)(n.code,{children:"Gas"}),", payment for computation occurs in ",(0,t.jsx)(n.a,{href:"#tokens-divisibility",children:"motes"}),". Therefore, there is a conversion rate between ",(0,t.jsx)(n.code,{children:"Gas"})," and motes."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Casper networks support configurable fee, refund, and pricing strategies to incentivize the ",(0,t.jsx)(n.a,{href:"/runtime#runtime-economics",children:"Casper Runtime Economics"})," by efficiently allocating computational resources. The ",(0,t.jsx)(n.a,{href:"/runtime#consensus-before-execution-basics-of-payment",children:"consensus-before-execution model"})," implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions."]})}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-runtime",children:"The Casper Network Runtime"}),"\n",(0,t.jsx)(n.p,{children:"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Casper Network Runtime",src:s(84603).A+"",width:"1220",height:"604"})}),"\n",(0,t.jsxs)(n.p,{children:["All these features are accessible via functions in the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"execution-semantics-urefs",children:["Generating ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"URef"}),"s are generated using a ",(0,t.jsx)(n.a,{href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html",children:"cryptographically secure random number generator"})," using the ",(0,t.jsx)(n.a,{href:"https://cr.yp.to/chacha.html",children:"ChaCha algorithm"}),". The random number generator is seeded by taking the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,t.jsx)(n.code,{children:"URef"}),"s generated in different phases of the same transaction)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Generating URefs",src:s(9732).A+"",width:"1121",height:"289"})}),"\n",(0,t.jsx)(n.h2,{id:"accounts-head",children:"Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),". The ",(0,t.jsx)(n.a,{href:"/concepts/global-state#global-state-trie",children:"global state trie store"})," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."]}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#ecdsa-keys",children:"Secp256k1"})," keys, commonly known as Ethereum keys, which are 68 bytes long"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,t.jsx)(n.a,{href:"#tokens-purses-and-accounts",children:"Tokens"})," for more information)."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."}),"\n",(0,t.jsx)(n.h3,{id:"accounts-creating",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["Account creation automatically happens upon transferring tokens to a yet unused ",(0,t.jsx)(n.code,{children:"PublicKey"}),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account Data Structure",src:s(42927).A+"",width:"426",height:"618"})}),"\n",(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"Account"})," contains the following data:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"URef"}),' representing the account\'s "main purse"']}),"\n",(0,t.jsx)(n.li,{children:"A collection of named keys (playing the same role as the named keys in a stored contract)"}),"\n",(0,t.jsxs)(n.li,{children:['A collection of "associated keys" (see ',(0,t.jsx)(n.a,{href:"#accounts-associated-keys-weights",children:"below for more information"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:['"Action thresholds" (see ',(0,t.jsx)(n.a,{href:"#accounts-actions-thresholds",children:"below for more information"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"accounts-permissions",children:"Permissions Model"}),"\n",(0,t.jsx)(n.h4,{id:"accounts-actions-thresholds",children:"Actions and Thresholds"}),"\n",(0,t.jsx)(n.p,{children:"An account can perform two types of actions: sending transactions and managing keys. A transaction is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a transaction; therefore, a key management action implies that a transaction is also taking place."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ActionThresholds"})," contained in the ",(0,t.jsx)(n.code,{children:"Account"})," data structure set a ",(0,t.jsx)(n.code,{children:"Weight"}),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a transaction, the key management threshold should always be greater than or equal to the transaction threshold."]}),"\n",(0,t.jsx)(n.h4,{id:"accounts-associated-keys-weights",children:"Associated Keys and Weights"}),"\n",(0,t.jsxs)(n.p,{children:["Addressable entities on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An addressable entity's ",(0,t.jsx)(n.em,{children:"associated keys"}),' are the set of public keys allowed to provide signatures on transactions for that entity. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each transaction must be signed by one or more keys associated with the entity that transaction is for, and the sum of the weights of those keys must be greater than or equal to the transaction threshold weight for that account. We call the keys that have signed a transaction the "authorizing keys". Similarly, if a transaction contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the entity.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.'})}),"\n",(0,t.jsx)(n.h4,{id:"accounts-key-management",children:"Key Management Actions"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"key management action"})," is a change to the account permissions, including:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Adding or removing an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the weight of an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the threshold of any action"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."}),"\n",(0,t.jsx)(n.h4,{id:"accounts-recovery",children:"Account security and recovery using key management"}),"\n",(0,t.jsx)(n.p,{children:"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign transactions from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the transaction threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").'})}),"\n",(0,t.jsx)(n.h3,{id:"accounts-context",children:"The Account Context"}),"\n",(0,t.jsxs)(n.p,{children:["A transaction is a user request to perform some execution on the blockchain (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"}),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity\'s context.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity."})}),"\n",(0,t.jsx)(n.h2,{id:"uref-head",children:"Unforgeable Reference (URef)"}),"\n",(0,t.jsxs)(n.p,{children:["This key type is used for storing any value except ",(0,t.jsx)(n.code,{children:"Account"}),". Additionally, ",(0,t.jsx)(n.code,{children:"URef"}),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,t.jsx)(n.code,{children:"URef"}),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,t.jsx)(n.code,{children:"URef"})," error. Permissions for a ",(0,t.jsx)(n.code,{children:"URef"})," can be given across contract calls, allowing data stored under a ",(0,t.jsx)(n.code,{children:"URef"})," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})," for more information). The serialization for ",(0,t.jsx)(n.code,{children:"Access Rights"})," that define the permissions for ",(0,t.jsx)(n.code,{children:"URefs"})," is detailed in the ",(0,t.jsx)(n.a,{href:"/concepts/serialization/primitives#clvalue",children:"CLValues"})," section."]}),"\n",(0,t.jsxs)(n.h3,{id:"uref-permissions",children:["Permissions for ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:["In the runtime, a ",(0,t.jsx)(n.code,{children:"URef"})," carries its permissions called ",(0,t.jsx)(n.code,{children:"AccessRights"}),". Additionally, the runtime tracks what ",(0,t.jsx)(n.code,{children:"AccessRights"})," would be valid for each ",(0,t.jsx)(n.code,{children:"URef"})," in each context. The system assumes that a sent ",(0,t.jsx)(n.code,{children:"URef"})," is invalid, regardless of declared ",(0,t.jsx)(n.code,{children:"AccessRights"}),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,t.jsx)(n.code,{children:"URef"}),", in the following ways:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['It can exist in a set of "known" ',(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.li,{children:["It can be freshly created by the runtime via the ",(0,t.jsx)(n.code,{children:"new_uref"})," function"]}),"\n",(0,t.jsxs)(n.li,{children:["For called contracts, the caller can pass it in via the arguments to ",(0,t.jsx)(n.code,{children:"call_contract"})]}),"\n",(0,t.jsxs)(n.li,{children:["It can be returned to the caller from ",(0,t.jsx)(n.code,{children:"call_contract"})," via the ",(0,t.jsx)(n.code,{children:"ret"})," function"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that only valid ",(0,t.jsx)(n.code,{children:"URef"}),"s may be added to the known ",(0,t.jsx)(n.code,{children:"URef"}),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,t.jsx)(n.code,{children:"URef"})," by getting it through a contract or stashing it in the known ",(0,t.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,t.jsxs)(n.p,{children:["The ability to pass ",(0,t.jsx)(n.code,{children:"URef"}),"s between contexts via ",(0,t.jsx)(n.code,{children:"call_contract"})," / ",(0,t.jsx)(n.code,{children:"ret"}),", allows them to share state among a fixed number of parties while keeping it private from all others."]}),"\n",(0,t.jsxs)(n.h3,{id:"urefs-and-purses",children:[(0,t.jsx)(n.code,{children:"URef"}),"s and Purses"]}),"\n",(0,t.jsxs)(n.p,{children:["Purses represent a unique type of ",(0,t.jsx)(n.code,{children:"URef"})," used for accounting measures within a Casper network. ",(0,t.jsx)(n.code,{children:"URef"}),"s exist as a top-level entity, meaning that individual entities do not own \u2018URef\u2019s. As described above, entities possess certain ",(0,t.jsx)(n.code,{children:"Access Rights"}),", allowing them to interact with the given ",(0,t.jsx)(n.code,{children:"URef"}),". While an account entity will possess an associated ",(0,t.jsx)(n.code,{children:"URef"})," representing their main purse, this ",(0,t.jsx)(n.code,{children:"URef"})," exists as a ",(0,t.jsx)(n.a,{href:"/concepts/serialization/primitives#clvalue-unit",children:(0,t.jsx)(n.code,{children:"Unit"})})," and corresponds to a ",(0,t.jsx)(n.em,{children:"balance"})," key within the Casper ",(0,t.jsx)(n.em,{children:"mint"}),". The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated ",(0,t.jsx)(n.code,{children:"URef"})," and the ",(0,t.jsx)(n.code,{children:"Access Rights"})," granted to it."]}),"\n",(0,t.jsx)(n.p,{children:"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required."}),"\n",(0,t.jsx)(n.h2,{id:"block-structure-head",children:"Block Structure"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"block"})," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."]}),"\n",(0,t.jsx)(n.h3,{id:"block-structure-data",children:"Data Fields"}),"\n",(0,t.jsx)(n.p,{children:"A block consists of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"block_hash"})]}),"\n",(0,t.jsx)(n.li,{children:"A header"}),"\n",(0,t.jsx)(n.li,{children:"A body"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Each of these fields is detailed in the subsequent sections."}),"\n",(0,t.jsx)(n.h4,{id:"block_hash",children:(0,t.jsx)(n.code,{children:"block_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"block_hash"})," is the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the block header."]}),"\n",(0,t.jsx)(n.h4,{id:"header",children:"Header"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/concepts/serialization/structures#block-header",children:"block header"})," contains the following fields:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"parent_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["A list of ",(0,t.jsx)(n.code,{children:"block_hash"}),"es giving the parents of the block."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"state_root_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The global state root hash produced by executing this block's body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"body_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The hash of the block body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"random_bit"})}),"\n",(0,t.jsx)(n.p,{children:"A boolean needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"accumulated_seed"})}),"\n",(0,t.jsx)(n.p,{children:"A seed needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_end"})}),"\n",(0,t.jsx)(n.p,{children:"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"timestamp"})}),"\n",(0,t.jsx)(n.p,{children:"The timestamp from when the block was proposed."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_id"})}),"\n",(0,t.jsx)(n.p,{children:"Era ID in which this block was created."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"height"})}),"\n",(0,t.jsx)(n.p,{children:"The height of this block, i.e., the number of ancestors."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,t.jsx)(n.p,{children:"The version of the Casper network when this block was proposed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"body",children:"Body"}),"\n",(0,t.jsxs)(n.p,{children:["The block body contains an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of transaction hashes. All transactions, including ",(0,t.jsx)(n.code,{children:"mint"}),", ",(0,t.jsx)(n.code,{children:"auction"}),", ",(0,t.jsx)(n.code,{children:"install_upgrade"})," and ",(0,t.jsx)(n.code,{children:"standard"})," transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,t.jsx)(n.a,{href:"/concepts/global-state#global-state-intro",children:"Global State"}),". A valid block may contain no transactions."]}),"\n",(0,t.jsx)(n.p,{children:"The block body also contains the public key of the validator that proposed the block."}),"\n",(0,t.jsxs)(n.p,{children:["Refer to the ",(0,t.jsx)(n.a,{href:"/concepts/serialization/",children:"Serialization Standard"})," for additional information on how blocks and transactions are serialized."]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-head",children:"Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a decentralized Proof-of-Stake blockchain platform that may use either the ",(0,t.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway"})," or ",(0,t.jsx)(n.a,{href:"/concepts/design/zug",children:"Zug"})," consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,t.jsx)(n.a,{href:"/concepts/economics/staking",children:"stake"})," to bond. In the blockchain space, this unit of value is a ",(0,t.jsx)(n.em,{children:"token"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes tokens and how one can use them on the Casper platform."}),"\n",(0,t.jsx)(n.h3,{id:"token-generation-and-distribution",children:"Token Generation and Distribution"}),"\n",(0,t.jsxs)(n.p,{children:["A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,t.jsx)(n.a,{href:"https://api.cspr.live/supply",children:"here"}),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."]}),"\n",(0,t.jsx)(n.p,{children:"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Token Lifecycle",src:s(64866).A+"",width:"1013",height:"656"})}),"\n",(0,t.jsx)(n.h3,{id:"tokens-divisibility",children:"Divisibility of Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Typically, a ",(0,t.jsx)(n.em,{children:"token"})," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,t.jsx)(n.em,{children:"motes"}),". Each CSPR is divisible into 10",(0,t.jsx)(n.sup,{children:"9"})," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,t.jsx)(n.sup,{children:"18"})," parts called Wei."]}),"\n",(0,t.jsxs)(n.p,{children:["The concept of ",(0,t.jsx)(n.code,{children:"CSPR"})," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,t.jsx)(n.em,{children:"motes"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"tokens-purses-and-accounts",children:"Purses and Addressable Entities"}),"\n",(0,t.jsxs)(n.p,{children:["All ",(0,t.jsx)(n.a,{href:"/concepts/addressable-entity",children:"entities"})," on the Casper system have a purse associated with the Casper system mint, called the ",(0,t.jsx)(n.em,{children:"main purse"}),". However, for security reasons, the ",(0,t.jsx)(n.code,{children:"URef"})," of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's ",(0,t.jsx)(n.code,{children:"transfer"})," method that accepts ",(0,t.jsx)(n.code,{children:"URef"}),"s is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})," function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the ",(0,t.jsx)(n.code,{children:"source"})," and the main purse of the account entity at the provided key as the ",(0,t.jsx)(n.code,{children:"target"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"mint-contract",children:"The Casper Mint Contract"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.em,{children:"mint"})," is a system contract that manages the balance of ",(0,t.jsx)(n.em,{children:"motes"})," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's ",(0,t.jsx)(n.em,{children:"main purse"}),". Each balance is associated with a ",(0,t.jsx)(n.code,{children:"URef"}),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,t.jsx)(n.em,{children:"purses"})," and conceptually represent a container for motes. The ",(0,t.jsx)(n.code,{children:"URef"})," is how a purse is referenced externally, outside the mint."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"AccessRights"})," of the URefs permissions model determines what actions can be performed when using a ",(0,t.jsx)(n.code,{children:"URef"})," associated with a purse."]}),"\n",(0,t.jsxs)(n.p,{children:["As all ",(0,t.jsx)(n.code,{children:"URef"}),"s are unforgeable, the only way to interact with a purse is for a ",(0,t.jsx)(n.code,{children:"URef"})," with appropriate ",(0,t.jsx)(n.code,{children:"AccessRights"})," to be validly given to the current context."]}),"\n",(0,t.jsx)(n.p,{children:"The basic global state options map onto more standard monetary operations according to the table below:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Global State"}),(0,t.jsx)(n.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Add"}),(0,t.jsx)(n.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Write"}),(0,t.jsx)(n.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Read"}),(0,t.jsx)(n.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-mint-interface",children:"The mint Contract Interface"}),"\n",(0,t.jsx)(n.p,{children:"The mint system contract exposes the following methods:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"source"})," must have at least ",(0,t.jsx)(n.code,{children:"Write"})," access rights, ",(0,t.jsx)(n.code,{children:"target"})," must have at least ",(0,t.jsx)(n.code,{children:"Add"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"TransferResult"})," may be a success acknowledgment or an error in the case of invalid ",(0,t.jsx)(n.code,{children:"source"})," or ",(0,t.jsx)(n.code,{children:"target"})," or insufficient balance in the ",(0,t.jsx)(n.code,{children:"source"})," purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"mint(amount: Motes) -> MintResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MintResult"})," either gives the created ",(0,t.jsx)(n.code,{children:"URef"})," (with full access rights), which now has a balance equal to the given ",(0,t.jsx)(n.code,{children:"amount"}),"; or an error due to the minting of new motes not being allowed"]}),"\n",(0,t.jsxs)(n.li,{children:["In the Casper mint, only the system account can call ",(0,t.jsx)(n.code,{children:"mint"}),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"create() -> URef"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["a convenience function for ",(0,t.jsx)(n.code,{children:"mint(0)"})," which cannot fail because it is always allowed to create an empty purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"balance(purse: URef) -> Option<Motes>"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"purse"})," must have at least ",(0,t.jsx)(n.code,{children:"Read"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"BalanceResult"})," either returns the number of motes held by the ",(0,t.jsx)(n.code,{children:"purse"}),", or nothing if the ",(0,t.jsx)(n.code,{children:"URef"})," is not valid"]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},42927:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-structure-89919dedef5e84cf8168afa72b34ed5f.png"},84603:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},9732:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"},64866:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/token-lifecycle-3b64dfdb785ffc07a0e2df0869520f33.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64959b1e.487a4de3.js b/assets/js/64959b1e.487a4de3.js deleted file mode 100644 index 9023ec3dd..000000000 --- a/assets/js/64959b1e.487a4de3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7796],{16527:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>h});var s=t(74848),i=t(28453);const a={title:"Network Design"},o="Casper Network Design",c={id:"concepts/design/casper-design",title:"Network Design",description:"Introduction",source:"@site/docs/concepts/design/casper-design.md",sourceDirName:"concepts/design",slug:"/concepts/design/casper-design",permalink:"/next/concepts/design/casper-design",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724755224e3,frontMatter:{title:"Network Design"},sidebar:"concepts",previous:{title:"Design Overview",permalink:"/next/design"},next:{title:"Network Communication",permalink:"/next/concepts/design/p2p"}},r={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Execution Semantics",id:"execution-semantics-head",level:2},{value:"Measuring Computational Work",id:"execution-semantics-gas",level:3},{value:"The Casper Network Runtime",id:"execution-semantics-runtime",level:3},{value:"Generating <code>URef</code>s",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for <code>URef</code>s",id:"uref-permissions",level:3},{value:"<code>URef</code>s and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"<code>block_hash</code>",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Addressable Entities",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"casper-network-design",children:"Casper Network Design"})}),"\n",(0,s.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#consensus",children:"consensus"}),". A Casper network stores data in a structure known as ",(0,s.jsx)(n.a,{href:"/next/concepts/global-state",children:"Global State"}),". Users interact with global state through session code sent in a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"transaction"}),". Transactions may contain ",(0,s.jsx)(n.a,{href:"https://webassembly.org/",children:"Wasm"})," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."]}),"\n",(0,s.jsxs)(n.p,{children:["A transaction executes in the context of the user's ",(0,s.jsx)(n.a,{href:"#accounts-head",children:"Account"})," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,s.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference"})," or ",(0,s.jsx)(n.code,{children:"URef"}),". After a node accepts a transaction as valid, it places the transaction in a proposed ",(0,s.jsx)(n.a,{href:"#block-structure-head",children:"Block"})," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction."]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounts-head",children:"Accounts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference (URef)"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#block-structure-head",children:"Block Structure"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#tokens-head",children:"Tokens"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-head",children:"Execution Semantics"}),"\n",(0,s.jsx)(n.p,{children:"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."}),"\n",(0,s.jsx)(n.h3,{id:"execution-semantics-gas",children:"Measuring Computational Work"}),"\n",(0,s.jsxs)(n.p,{children:["Computation is done in a ",(0,s.jsx)(n.a,{href:"https://webassembly.org/",children:"WebAssembly (Wasm)"})," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,s.jsx)(n.a,{href:"/next/concepts/economics/gas-concepts",children:(0,s.jsx)(n.code,{children:"Gas"})})," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,s.jsx)(n.code,{children:"Gas"})," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."]}),"\n",(0,s.jsxs)(n.p,{children:["Costs for opcode instructions on the Casper Mainnet network can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115",children:"here"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["All executions are finite because each has a finite ",(0,s.jsx)(n.em,{children:"gas limit"})," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction."]}),"\n",(0,s.jsxs)(n.p,{children:["Although the network measures costs in ",(0,s.jsx)(n.code,{children:"Gas"}),", payment for computation occurs in ",(0,s.jsx)(n.a,{href:"#tokens-divisibility",children:"motes"}),". Therefore, there is a conversion rate between ",(0,s.jsx)(n.code,{children:"Gas"})," and motes."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Casper networks support configurable fee, refund, and pricing strategies to incentivize the ",(0,s.jsx)(n.a,{href:"/next/runtime#runtime-economics",children:"Casper Runtime Economics"})," by efficiently allocating computational resources. The ",(0,s.jsx)(n.a,{href:"/next/runtime#consensus-before-execution-basics-of-payment",children:"consensus-before-execution model"})," implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions."]})}),"\n",(0,s.jsx)(n.h3,{id:"execution-semantics-runtime",children:"The Casper Network Runtime"}),"\n",(0,s.jsx)(n.p,{children:"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Casper Network Runtime",src:t(78701).A+"",width:"1220",height:"604"})}),"\n",(0,s.jsxs)(n.p,{children:["All these features are accessible via functions in the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"}),"."]}),"\n",(0,s.jsxs)(n.h4,{id:"execution-semantics-urefs",children:["Generating ",(0,s.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"}),"s are generated using a ",(0,s.jsx)(n.a,{href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html",children:"cryptographically secure random number generator"})," using the ",(0,s.jsx)(n.a,{href:"https://cr.yp.to/chacha.html",children:"ChaCha algorithm"}),". The random number generator is seeded by taking the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,s.jsx)(n.code,{children:"URef"}),"s generated in different phases of the same transaction)."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Generating URefs",src:t(82602).A+"",width:"1121",height:"289"})}),"\n",(0,s.jsx)(n.h2,{id:"accounts-head",children:"Accounts"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,s.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,s.jsx)(n.code,{children:"PublicKey"}),". The ",(0,s.jsx)(n.a,{href:"/next/concepts/global-state#global-state-trie",children:"global state trie store"})," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#ecdsa-keys",children:"Secp256k1"})," keys, commonly known as Ethereum keys, which are 68 bytes long"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:['By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,s.jsx)(n.a,{href:"#tokens-purses-and-accounts",children:"Tokens"})," for more information)."]}),"\n",(0,s.jsx)(n.p,{children:"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."}),"\n",(0,s.jsx)(n.h3,{id:"accounts-creating",children:"Creating an account"}),"\n",(0,s.jsxs)(n.p,{children:["Account creation automatically happens upon transferring tokens to a yet unused ",(0,s.jsx)(n.code,{children:"PublicKey"}),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,s.jsx)(n.code,{children:"PublicKey"})," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Account Data Structure",src:t(86169).A+"",width:"426",height:"618"})}),"\n",(0,s.jsxs)(n.p,{children:["An ",(0,s.jsx)(n.code,{children:"Account"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"URef"}),' representing the account\'s "main purse"']}),"\n",(0,s.jsx)(n.li,{children:"A collection of named keys (playing the same role as the named keys in a stored contract)"}),"\n",(0,s.jsxs)(n.li,{children:['A collection of "associated keys" (see ',(0,s.jsx)(n.a,{href:"#accounts-associated-keys-weights",children:"below for more information"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:['"Action thresholds" (see ',(0,s.jsx)(n.a,{href:"#accounts-actions-thresholds",children:"below for more information"}),")"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"accounts-permissions",children:"Permissions Model"}),"\n",(0,s.jsx)(n.h4,{id:"accounts-actions-thresholds",children:"Actions and Thresholds"}),"\n",(0,s.jsx)(n.p,{children:"An account can perform two types of actions: sending transactions and managing keys. A transaction is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a transaction; therefore, a key management action implies that a transaction is also taking place."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"ActionThresholds"})," contained in the ",(0,s.jsx)(n.code,{children:"Account"})," data structure set a ",(0,s.jsx)(n.code,{children:"Weight"}),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a transaction, the key management threshold should always be greater than or equal to the transaction threshold."]}),"\n",(0,s.jsx)(n.h4,{id:"accounts-associated-keys-weights",children:"Associated Keys and Weights"}),"\n",(0,s.jsxs)(n.p,{children:["Addressable entities on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An addressable entity's ",(0,s.jsx)(n.em,{children:"associated keys"}),' are the set of public keys allowed to provide signatures on transactions for that entity. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each transaction must be signed by one or more keys associated with the entity that transaction is for, and the sum of the weights of those keys must be greater than or equal to the transaction threshold weight for that account. We call the keys that have signed a transaction the "authorizing keys". Similarly, if a transaction contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the entity.']}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.'})}),"\n",(0,s.jsx)(n.h4,{id:"accounts-key-management",children:"Key Management Actions"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.em,{children:"key management action"})," is a change to the account permissions, including:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Adding or removing an associated key"}),"\n",(0,s.jsx)(n.li,{children:"Changing the weight of an associated key"}),"\n",(0,s.jsx)(n.li,{children:"Changing the threshold of any action"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."}),"\n",(0,s.jsx)(n.h4,{id:"accounts-recovery",children:"Account security and recovery using key management"}),"\n",(0,s.jsx)(n.p,{children:"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign transactions from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the transaction threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").'})}),"\n",(0,s.jsx)(n.h3,{id:"accounts-context",children:"The Account Context"}),"\n",(0,s.jsxs)(n.p,{children:["A transaction is a user request to perform some execution on the blockchain (see ",(0,s.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"}),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity\'s context.']}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity."})}),"\n",(0,s.jsx)(n.h2,{id:"uref-head",children:"Unforgeable Reference (URef)"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used for storing any value except ",(0,s.jsx)(n.code,{children:"Account"}),". Additionally, ",(0,s.jsx)(n.code,{children:"URef"}),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,s.jsx)(n.code,{children:"URef"}),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,s.jsx)(n.code,{children:"URef"})," error. Permissions for a ",(0,s.jsx)(n.code,{children:"URef"})," can be given across contract calls, allowing data stored under a ",(0,s.jsx)(n.code,{children:"URef"})," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,s.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})," for more information). The serialization for ",(0,s.jsx)(n.code,{children:"Access Rights"})," that define the permissions for ",(0,s.jsx)(n.code,{children:"URefs"})," is detailed in the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue",children:"CLValues"})," section."]}),"\n",(0,s.jsxs)(n.h3,{id:"uref-permissions",children:["Permissions for ",(0,s.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,s.jsxs)(n.p,{children:["In the runtime, a ",(0,s.jsx)(n.code,{children:"URef"})," carries its permissions called ",(0,s.jsx)(n.code,{children:"AccessRights"}),". Additionally, the runtime tracks what ",(0,s.jsx)(n.code,{children:"AccessRights"})," would be valid for each ",(0,s.jsx)(n.code,{children:"URef"})," in each context. The system assumes that a sent ",(0,s.jsx)(n.code,{children:"URef"})," is invalid, regardless of declared ",(0,s.jsx)(n.code,{children:"AccessRights"}),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,s.jsx)(n.code,{children:"URef"}),", in the following ways:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:['It can exist in a set of "known" ',(0,s.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,s.jsxs)(n.li,{children:["It can be freshly created by the runtime via the ",(0,s.jsx)(n.code,{children:"new_uref"})," function"]}),"\n",(0,s.jsxs)(n.li,{children:["For called contracts, the caller can pass it in via the arguments to ",(0,s.jsx)(n.code,{children:"call_contract"})]}),"\n",(0,s.jsxs)(n.li,{children:["It can be returned to the caller from ",(0,s.jsx)(n.code,{children:"call_contract"})," via the ",(0,s.jsx)(n.code,{children:"ret"})," function"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Note that only valid ",(0,s.jsx)(n.code,{children:"URef"}),"s may be added to the known ",(0,s.jsx)(n.code,{children:"URef"}),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,s.jsx)(n.code,{children:"URef"})," by getting it through a contract or stashing it in the known ",(0,s.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,s.jsxs)(n.p,{children:["The ability to pass ",(0,s.jsx)(n.code,{children:"URef"}),"s between contexts via ",(0,s.jsx)(n.code,{children:"call_contract"})," / ",(0,s.jsx)(n.code,{children:"ret"}),", allows them to share state among a fixed number of parties while keeping it private from all others."]}),"\n",(0,s.jsxs)(n.h3,{id:"urefs-and-purses",children:[(0,s.jsx)(n.code,{children:"URef"}),"s and Purses"]}),"\n",(0,s.jsxs)(n.p,{children:["Purses represent a unique type of ",(0,s.jsx)(n.code,{children:"URef"})," used for accounting measures within a Casper network. ",(0,s.jsx)(n.code,{children:"URef"}),"s exist as a top-level entity, meaning that individual entities do not own \u2018URef\u2019s. As described above, entities possess certain ",(0,s.jsx)(n.code,{children:"Access Rights"}),", allowing them to interact with the given ",(0,s.jsx)(n.code,{children:"URef"}),". While an account entity will possess an associated ",(0,s.jsx)(n.code,{children:"URef"})," representing their main purse, this ",(0,s.jsx)(n.code,{children:"URef"})," exists as a ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/primitives#clvalue-unit",children:(0,s.jsx)(n.code,{children:"Unit"})})," and corresponds to a ",(0,s.jsx)(n.em,{children:"balance"})," key within the Casper ",(0,s.jsx)(n.em,{children:"mint"}),". The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated ",(0,s.jsx)(n.code,{children:"URef"})," and the ",(0,s.jsx)(n.code,{children:"Access Rights"})," granted to it."]}),"\n",(0,s.jsx)(n.p,{children:"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required."}),"\n",(0,s.jsx)(n.h2,{id:"block-structure-head",children:"Block Structure"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.em,{children:"block"})," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."]}),"\n",(0,s.jsx)(n.h3,{id:"block-structure-data",children:"Data Fields"}),"\n",(0,s.jsx)(n.p,{children:"A block consists of the following:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"block_hash"})]}),"\n",(0,s.jsx)(n.li,{children:"A header"}),"\n",(0,s.jsx)(n.li,{children:"A body"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each of these fields is detailed in the subsequent sections."}),"\n",(0,s.jsx)(n.h4,{id:"block_hash",children:(0,s.jsx)(n.code,{children:"block_hash"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"block_hash"})," is the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the block header."]}),"\n",(0,s.jsx)(n.h4,{id:"header",children:"Header"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/structures#block-header",children:"block header"})," contains the following fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"parent_hash"})}),"\n",(0,s.jsxs)(n.p,{children:["A list of ",(0,s.jsx)(n.code,{children:"block_hash"}),"es giving the parents of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"state_root_hash"})}),"\n",(0,s.jsx)(n.p,{children:"The global state root hash produced by executing this block's body."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"body_hash"})}),"\n",(0,s.jsx)(n.p,{children:"The hash of the block body."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"random_bit"})}),"\n",(0,s.jsx)(n.p,{children:"A boolean needed for initializing a future era."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"accumulated_seed"})}),"\n",(0,s.jsx)(n.p,{children:"A seed needed for initializing a future era."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"era_end"})}),"\n",(0,s.jsx)(n.p,{children:"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"timestamp"})}),"\n",(0,s.jsx)(n.p,{children:"The timestamp from when the block was proposed."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"era_id"})}),"\n",(0,s.jsx)(n.p,{children:"Era ID in which this block was created."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"height"})}),"\n",(0,s.jsx)(n.p,{children:"The height of this block, i.e., the number of ancestors."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,s.jsx)(n.p,{children:"The version of the Casper network when this block was proposed."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"body",children:"Body"}),"\n",(0,s.jsxs)(n.p,{children:["The block body contains an ",(0,s.jsx)(n.strong,{children:"ordered"})," list of transaction hashes. All transactions, including ",(0,s.jsx)(n.code,{children:"mint"}),", ",(0,s.jsx)(n.code,{children:"auction"}),", ",(0,s.jsx)(n.code,{children:"install_upgrade"})," and ",(0,s.jsx)(n.code,{children:"standard"})," transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,s.jsx)(n.a,{href:"/next/concepts/global-state#global-state-intro",children:"Global State"}),". A valid block may contain no transactions."]}),"\n",(0,s.jsx)(n.p,{children:"The block body also contains the public key of the validator that proposed the block."}),"\n",(0,s.jsxs)(n.p,{children:["Refer to the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/",children:"Serialization Standard"})," for additional information on how blocks and transactions are serialized."]}),"\n",(0,s.jsx)(n.h2,{id:"tokens-head",children:"Tokens"}),"\n",(0,s.jsxs)(n.p,{children:["Casper is a decentralized Proof-of-Stake blockchain platform that may use either the ",(0,s.jsx)(n.a,{href:"/next/concepts/design/highway",children:"Highway"})," or ",(0,s.jsx)(n.a,{href:"/next/concepts/design/zug",children:"Zug"})," consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,s.jsx)(n.a,{href:"/next/concepts/economics/staking",children:"stake"})," to bond. In the blockchain space, this unit of value is a ",(0,s.jsx)(n.em,{children:"token"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This chapter describes tokens and how one can use them on the Casper platform."}),"\n",(0,s.jsx)(n.h3,{id:"token-generation-and-distribution",children:"Token Generation and Distribution"}),"\n",(0,s.jsxs)(n.p,{children:["A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,s.jsx)(n.a,{href:"https://api.cspr.live/supply",children:"here"}),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."]}),"\n",(0,s.jsx)(n.p,{children:"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Token Lifecycle",src:t(43700).A+"",width:"1013",height:"656"})}),"\n",(0,s.jsx)(n.h3,{id:"tokens-divisibility",children:"Divisibility of Tokens"}),"\n",(0,s.jsxs)(n.p,{children:["Typically, a ",(0,s.jsx)(n.em,{children:"token"})," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,s.jsx)(n.em,{children:"motes"}),". Each CSPR is divisible into 10",(0,s.jsx)(n.sup,{children:"9"})," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,s.jsx)(n.sup,{children:"18"})," parts called Wei."]}),"\n",(0,s.jsxs)(n.p,{children:["The concept of ",(0,s.jsx)(n.code,{children:"CSPR"})," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,s.jsx)(n.em,{children:"motes"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"tokens-purses-and-accounts",children:"Purses and Addressable Entities"}),"\n",(0,s.jsxs)(n.p,{children:["All ",(0,s.jsx)(n.a,{href:"/next/concepts/addressable-entity",children:"entities"})," on the Casper system have a purse associated with the Casper system mint, called the ",(0,s.jsx)(n.em,{children:"main purse"}),". However, for security reasons, the ",(0,s.jsx)(n.code,{children:"URef"})," of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's ",(0,s.jsx)(n.code,{children:"transfer"})," method that accepts ",(0,s.jsx)(n.code,{children:"URef"}),"s is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})," function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the ",(0,s.jsx)(n.code,{children:"source"})," and the main purse of the account entity at the provided key as the ",(0,s.jsx)(n.code,{children:"target"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"mint-contract",children:"The Casper Mint Contract"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper ",(0,s.jsx)(n.em,{children:"mint"})," is a system contract that manages the balance of ",(0,s.jsx)(n.em,{children:"motes"})," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's ",(0,s.jsx)(n.em,{children:"main purse"}),". Each balance is associated with a ",(0,s.jsx)(n.code,{children:"URef"}),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,s.jsx)(n.em,{children:"purses"})," and conceptually represent a container for motes. The ",(0,s.jsx)(n.code,{children:"URef"})," is how a purse is referenced externally, outside the mint."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"AccessRights"})," of the URefs permissions model determines what actions can be performed when using a ",(0,s.jsx)(n.code,{children:"URef"})," associated with a purse."]}),"\n",(0,s.jsxs)(n.p,{children:["As all ",(0,s.jsx)(n.code,{children:"URef"}),"s are unforgeable, the only way to interact with a purse is for a ",(0,s.jsx)(n.code,{children:"URef"})," with appropriate ",(0,s.jsx)(n.code,{children:"AccessRights"})," to be validly given to the current context."]}),"\n",(0,s.jsx)(n.p,{children:"The basic global state options map onto more standard monetary operations according to the table below:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Global State"}),(0,s.jsx)(n.th,{children:"Action Monetary Action"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add"}),(0,s.jsx)(n.td,{children:"Deposit (i.e. transfer to)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write"}),(0,s.jsx)(n.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Read"}),(0,s.jsx)(n.td,{children:"Balance check"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"tokens-mint-interface",children:"The mint Contract Interface"}),"\n",(0,s.jsx)(n.p,{children:"The mint system contract exposes the following methods:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"source"})," must have at least ",(0,s.jsx)(n.code,{children:"Write"})," access rights, ",(0,s.jsx)(n.code,{children:"target"})," must have at least ",(0,s.jsx)(n.code,{children:"Add"})," access rights"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"TransferResult"})," may be a success acknowledgment or an error in the case of invalid ",(0,s.jsx)(n.code,{children:"source"})," or ",(0,s.jsx)(n.code,{children:"target"})," or insufficient balance in the ",(0,s.jsx)(n.code,{children:"source"})," purse"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"mint(amount: Motes) -> MintResult"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"MintResult"})," either gives the created ",(0,s.jsx)(n.code,{children:"URef"})," (with full access rights), which now has a balance equal to the given ",(0,s.jsx)(n.code,{children:"amount"}),"; or an error due to the minting of new motes not being allowed"]}),"\n",(0,s.jsxs)(n.li,{children:["In the Casper mint, only the system account can call ",(0,s.jsx)(n.code,{children:"mint"}),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"create() -> URef"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a convenience function for ",(0,s.jsx)(n.code,{children:"mint(0)"})," which cannot fail because it is always allowed to create an empty purse"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance(purse: URef) -> Option<Motes>"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"purse"})," must have at least ",(0,s.jsx)(n.code,{children:"Read"})," access rights"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"BalanceResult"})," either returns the number of motes held by the ",(0,s.jsx)(n.code,{children:"purse"}),", or nothing if the ",(0,s.jsx)(n.code,{children:"URef"})," is not valid"]}),"\n"]}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},86169:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/account-structure-89919dedef5e84cf8168afa72b34ed5f.png"},78701:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},82602:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"},43700:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/token-lifecycle-3b64dfdb785ffc07a0e2df0869520f33.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64bdcaf3.e264dcdb.js b/assets/js/64bdcaf3.e264dcdb.js new file mode 100644 index 000000000..66a687541 --- /dev/null +++ b/assets/js/64bdcaf3.e264dcdb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1130],{84549:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var i=s(74848),t=s(28453);const r={title:"Open Files Limit"},o="Setting the Open Files Limit",l={id:"operators/setup/open-files",title:"Open Files Limit",description:"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.",source:"@site/versioned_docs/version-2.0.0/operators/setup/open-files.md",sourceDirName:"operators/setup",slug:"/operators/setup/open-files",permalink:"/2.0.0/operators/setup/open-files",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Open Files Limit"},sidebar:"operators",previous:{title:"Fast Sync",permalink:"/2.0.0/operators/setup/fast-sync"},next:{title:"Upgrades",permalink:"/2.0.0/operators/setup/upgrade"}},c={},a=[{value:"Setting the Limit Manually",id:"updating-manually",level:2},{value:"Updating the <code>limits.conf</code> File",id:"updating-limits-conf",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",summary:"summary",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"setting-the-open-files-limit",children:"Setting the Open Files Limit"})}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node"})," launches, it tries to set the maximum open files limit (",(0,i.jsx)(n.code,{children:"nofile"}),") for the process to ",(0,i.jsx)(n.code,{children:"64000"}),". With some systems, this limit will be larger than the default hard limit of ",(0,i.jsx)(n.code,{children:"4096"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.jsx)(n.code,{children:"nofile"})," limit needs to be increased."]}),"\n",(0,i.jsxs)(n.p,{children:["With the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.jsx)(n.code,{children:"casper-node"})," with the following command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'pgrep "casper-node$"\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ pgrep "casper-node$"\n275928\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.jsx)(n.code,{children:"275928"})," each time."]})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you do not get a value in return, you do not have the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running correctly."]}),"\n",(0,i.jsxs)(n.p,{children:["To find the current ",(0,i.jsx)(n.code,{children:"nofile"})," (number of open files) hard limit, run ",(0,i.jsx)(n.code,{children:"prlimit"})," with the PID from the previous command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo prlimit -n -p <PID>\n"})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can also embed both commands as shown here:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive ",(0,i.jsx)(n.code,{children:"prlimit: option requires an argument -- 'p'"}),", then ",(0,i.jsx)(n.code,{children:'pgrep "casper-node$"'})," is not returning anything because the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is no longer running."]}),"\n",(0,i.jsx)(n.h2,{id:"updating-manually",children:"Setting the Limit Manually"}),"\n",(0,i.jsxs)(n.p,{children:["Run the command below to set the ",(0,i.jsx)(n.code,{children:"nofile"})," limit for an active process without restarting the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," and ",(0,i.jsx)(n.code,{children:"casper-node"})," processes. Note that this setting is active only while the ",(0,i.jsx)(n.code,{children:"casper-node"})," process runs. To make this setting permanent, ",(0,i.jsxs)(n.a,{href:"#updating-limits-conf",children:["update the ",(0,i.jsx)(n.code,{children:"limits.conf"})]})," file instead."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Next, check that the ",(0,i.jsx)(n.code,{children:"prlimit"})," has changed:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"updating-limits-conf",children:["Updating the ",(0,i.jsx)(n.code,{children:"limits.conf"})," File"]}),"\n",(0,i.jsxs)(n.p,{children:["It is possible to persist the ",(0,i.jsx)(n.code,{children:"nofile"})," limit across server reboots, ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," restarts, and protocol upgrades, by adding the ",(0,i.jsx)(n.code,{children:"nofile"})," setting for the ",(0,i.jsx)(n.code,{children:"casper"})," user in ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Add the following row to the bottom of the ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper hard nofile 64000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.jsx)(n.code,{children:"nofile"})," setting."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64c09e2e.d5d788c7.js b/assets/js/64c09e2e.d5d788c7.js deleted file mode 100644 index 811c83aa2..000000000 --- a/assets/js/64c09e2e.d5d788c7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3697],{73571:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var a=t(74848),r=t(28453);const o={},s="Node Maintenance",i={id:"operators/maintenance/index",title:"Node Maintenance",description:"This section covers maintenance actions such as moving a node to a different location and restoring a database.",source:"@site/docs/operators/maintenance/index.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/",permalink:"/next/operators/maintenance/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"operators",previous:{title:"Staging Files",permalink:"/next/operators/setup-network/staging-files-for-new-network"},next:{title:"Archive and Restore a DB",permalink:"/next/operators/maintenance/archiving-and-restoring"}},c={},d=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"node-maintenance",children:"Node Maintenance"})}),"\n",(0,a.jsx)(n.p,{children:"This section covers maintenance actions such as moving a node to a different location and restoring a database."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Title"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/next/operators/maintenance/archiving-and-restoring",children:"Archiving and Restoring a Database"})}),(0,a.jsxs)(n.td,{children:["Using ",(0,a.jsx)(n.code,{children:"zstd"})," for the compression and decompression of a Casper node database and streaming from a backup location"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/next/operators/maintenance/moving-node",children:"Moving a Validating Node"})}),(0,a.jsx)(n.td,{children:"Ways to move a validator node to another machine"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/64c09e2e.fa6ac55d.js b/assets/js/64c09e2e.fa6ac55d.js new file mode 100644 index 000000000..60c89c7a1 --- /dev/null +++ b/assets/js/64c09e2e.fa6ac55d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[33697],{73571:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>d});var a=t(74848),r=t(28453);const o={},s="Node Maintenance",i={id:"operators/maintenance/index",title:"Node Maintenance",description:"This section covers maintenance actions such as moving a node to a different location and restoring a database.",source:"@site/docs/operators/maintenance/index.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/",permalink:"/operators/maintenance/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"operators",previous:{title:"Staging Files",permalink:"/operators/setup-network/staging-files-for-new-network"},next:{title:"Archive and Restore a DB",permalink:"/operators/maintenance/archiving-and-restoring"}},c={},d=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"node-maintenance",children:"Node Maintenance"})}),"\n",(0,a.jsx)(n.p,{children:"This section covers maintenance actions such as moving a node to a different location and restoring a database."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Title"}),(0,a.jsx)(n.th,{children:"Description"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/operators/maintenance/archiving-and-restoring",children:"Archiving and Restoring a Database"})}),(0,a.jsxs)(n.td,{children:["Using ",(0,a.jsx)(n.code,{children:"zstd"})," for the compression and decompression of a Casper node database and streaming from a backup location"]})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.a,{href:"/operators/maintenance/moving-node",children:"Moving a Validating Node"})}),(0,a.jsx)(n.td,{children:"Ways to move a validator node to another machine"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>i});var a=t(96540);const r={},o=a.createContext(r);function s(e){const n=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/650a8fc0.6c05b66c.js b/assets/js/650a8fc0.6c05b66c.js deleted file mode 100644 index c32cee909..000000000 --- a/assets/js/650a8fc0.6c05b66c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3894],{86943:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var r=n(74848),t=n(28453);const c={},o="M",a={id:"concepts/glossary/M",title:"M",description:"---",source:"@site/docs/concepts/glossary/M.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/M",permalink:"/next/concepts/glossary/M",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"concepts",previous:{title:"L",permalink:"/next/concepts/glossary/L"},next:{title:"N",permalink:"/next/concepts/glossary/N"}},l={},i=[{value:"Mainnet",id:"mainnet",level:2},{value:"Merkle tree",id:"merkle-tree",level:2},{value:"Motes",id:"motes",level:2},{value:"Multi-Sig",id:"multisig",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"m",children:"M"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"mainnet",children:"Mainnet"}),"\n",(0,r.jsx)(s.p,{children:"The live, decentralized, and public Casper platform, with version 1.0."}),"\n",(0,r.jsx)(s.h2,{id:"merkle-tree",children:"Merkle tree"}),"\n",(0,r.jsx)(s.p,{children:"A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes."}),"\n",(0,r.jsx)(s.h2,{id:"motes",children:"Motes"}),"\n",(0,r.jsxs)(s.p,{children:["A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C#cspr",children:"CSPR"})," token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes."]}),"\n",(0,r.jsx)(s.h2,{id:"multisig",children:"Multi-Sig"}),"\n",(0,r.jsxs)(s.p,{children:["Short for ",(0,r.jsx)(s.code,{children:"Multi-Signature"}),". Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found ",(0,r.jsx)(s.a,{href:"/next/developers/cli/transfers/multisig-deploy-transfer",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/650a8fc0.fcb9962e.js b/assets/js/650a8fc0.fcb9962e.js new file mode 100644 index 000000000..dd8bb79da --- /dev/null +++ b/assets/js/650a8fc0.fcb9962e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63894],{86943:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>t,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const t={},o="M",a={id:"concepts/glossary/M",title:"M",description:"---",source:"@site/docs/concepts/glossary/M.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/M",permalink:"/concepts/glossary/M",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"concepts",previous:{title:"L",permalink:"/concepts/glossary/L"},next:{title:"N",permalink:"/concepts/glossary/N"}},l={},i=[{value:"Mainnet",id:"mainnet",level:2},{value:"Merkle tree",id:"merkle-tree",level:2},{value:"Motes",id:"motes",level:2},{value:"Multi-Sig",id:"multisig",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"m",children:"M"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"mainnet",children:"Mainnet"}),"\n",(0,n.jsx)(s.p,{children:"The live, decentralized, and public Casper platform, with version 1.0."}),"\n",(0,n.jsx)(s.h2,{id:"merkle-tree",children:"Merkle tree"}),"\n",(0,n.jsx)(s.p,{children:"A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes."}),"\n",(0,n.jsx)(s.h2,{id:"motes",children:"Motes"}),"\n",(0,n.jsxs)(s.p,{children:["A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"})," token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes."]}),"\n",(0,n.jsx)(s.h2,{id:"multisig",children:"Multi-Sig"}),"\n",(0,n.jsxs)(s.p,{children:["Short for ",(0,n.jsx)(s.code,{children:"Multi-Signature"}),". Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found ",(0,n.jsx)(s.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const c={},t=n.createContext(c);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6520db96.0f7b780d.js b/assets/js/6520db96.0f7b780d.js new file mode 100644 index 000000000..d592fe8d3 --- /dev/null +++ b/assets/js/6520db96.0f7b780d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19025],{15820:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>h});var r=n(74848),s=n(28453);const c={title:"Factory Contracts"},a="Writing Contracts using the Factory Pattern",o={id:"developers/writing-onchain-code/factory-pattern",title:"Factory Contracts",description:"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.",source:"@site/docs/developers/writing-onchain-code/factory-pattern.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/factory-pattern",permalink:"/developers/writing-onchain-code/factory-pattern",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Factory Contracts"},sidebar:"developers",previous:{title:"Contract Hash vs. Package Hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash"},next:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/developers/writing-onchain-code/best-practices"}},i={},h=[{value:"The Counter Factory Example",id:"the-counter-factory-example",level:2},{value:"Unit tests",id:"unit-tests",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-contracts-using-the-factory-pattern",children:"Writing Contracts using the Factory Pattern"})}),"\n",(0,r.jsxs)(t.p,{children:["This guide presents a ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"factory pattern"})," for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"The factory pattern is a widely recognized software design concept used in various programming contexts. DApp developers may use factory implementations to create smart contracts from a given source (or factory), such as a factory method or entry point. A factory pattern ensures that the contracts produced maintain a specified behavior, such as specific entry points and arguments. In general, factories produce other smart contracts according to a template."}),"\n",(0,r.jsxs)(t.p,{children:["Casper factories are created using the entry point type called ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", which marks an entry point as a factory method responsible for creating and installing contracts on the chain. An installer entry point will derive new Wasm based on the original session Wasm and create a new contract with different sets of entry points as required. In other words, these installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"})," are the contract factories. When referring to the factory contract on this page, we mean the contract containing the factory entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marks an entry point that exists in the bytecode but is not callable. Thus, regular entry points can be referenced from within installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),". In object-oriented terms, entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," act as virtual abstract methods and cannot be called from session code."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["This factory pattern poses a known drawback when using Wasm. All the smart contracts created with the factory pattern share the same Wasm installed on the chain. Thus, developers cannot modify the Wasm once installed and create modified contracts using the factory pattern. Developers must specify all the possible entry points in the parent contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marker."]})}),"\n",(0,r.jsx)(t.h2,{id:"the-counter-factory-example",children:"The Counter Factory Example"}),"\n",(0,r.jsxs)(t.p,{children:["This section dives into a ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"simple counter that uses factory methods"})," to describe how to implement the factory pattern on a Casper network. The ",(0,r.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"})," demonstrates the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Let's start by exploring the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L115",children:"session code"}),", where the contract entry points are defined."]}),"\n",(0,r.jsxs)(t.p,{children:["Two installer entry points are marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", meaning these entry points will produce new counter contracts once this Wasm is installed in global state. They are also marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," so that they can be called from the session code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_DEFAULT_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\n"})}),"\n",(0,r.jsxs)(t.p,{children:["These two installers show how to declare multiple factory entry points and use them to initialize the Wasm they produce with different values. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L61C19-L61C35",children:"line 61"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point creates a counter contract with a given name and initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n let initial_value: U512 = runtime::get_named_arg(ARG_INITIAL_VALUE);\n installer(name, initial_value);\n}\n'})}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L68",children:"line 68"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," entry point creates a counter contract with a given name and a zero initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory_default() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n installer(name, U512::zero());\n}\n'})}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsx)(t.p,{children:"The factory pattern can produce contracts with different entry points. Suppose the session code defines entry points A, B, C, and D as templates. One installer factory entry point could use entry points A and B to create a contract, and the other installer entry point might use entry points C and D. Such support at the API level enables the implementation of more complex use cases."})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L73",children:"installer function"})," creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's ",(0,r.jsx)(t.code,{children:"decrement"})," and ",(0,r.jsx)(t.code,{children:"increment"})," functionality. These entry points are defined just like in any other smart contract, with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"}),", and they are callable for all the counters created. To learn how to call the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," functions, see the ",(0,r.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"}),", which is the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Sample installer code for a counter factory"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"fn installer(name: String, initial_value: U512) {\n let named_keys = {\n let new_uref = storage::new_uref(initial_value);\n let mut named_keys = NamedKeys::new();\n named_keys.insert(CURRENT_VALUE_KEY.to_string(), new_uref.into());\n named_keys\n };\n\n let entry_points = {\n let mut entry_points = EntryPoints::new();\n let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n let entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n\n entry_points\n };\n\n let (contract_hash, contract_version) = storage::new_contract(\n entry_points,\n Some(named_keys),\n Some(PACKAGE_HASH_KEY_NAME.to_string()),\n Some(ACCESS_KEY_NAME.to_string()),\n );\n\n runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\n runtime::put_key(&name, contract_hash.into());\n}\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["It is important to note that the installer logic ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L110-L111",children:"saves the newly created contract version and contract hash"})," under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#comparing-session-and-contract",children:"comparison between session and contract context"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\nruntime::put_key(&name, contract_hash.into());\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For example, if you install the factory counter contract, you will see only one named key for this contract in your account, with the two installer entry points ",(0,r.jsx)(t.code,{children:"contract_factory"})," and ",(0,r.jsx)(t.code,{children:"contract_factory_default"}),". See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L155C1-L163",children:"lines 155-163"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["If you call the installer three times to create 3 different counters, you will see 3 named keys for each counter in the factory contract's named keys. The counter contracts produced will have the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["As explained above, developers must define all the possible non-installer entry points in the factory contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"})," markers. See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L135C9-L149C11",children:"lines 135-139"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\n"})}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsxs)(t.p,{children:["Suppose developers forget to declare an entry point in the outermost session logic (the ",(0,r.jsx)(t.code,{children:"call"})," function) and mark it with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"}),"; that Wasm export will be removed when the factory contract is installed in global state. Creating the entry point in the installer logic is not sufficient."]})}),"\n",(0,r.jsx)(t.h3,{id:"unit-tests",children:"Unit tests"}),"\n",(0,r.jsxs)(t.p,{children:["Developers can test contracts that follow the factory pattern using the Casper testing framework described under ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"}),". The testing process is the same, but this section highlights a particular test called ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L116C4-L116C42",children:"should_install_and_use_factory_pattern"})," found in the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/execution_engine_testing/tests/src/test/counter_factory.rs",children:"unit test suite"})," of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior."]}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L120",children:"line 120"}),", the test starts building a request to call the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point with counter name ",(0,r.jsx)(t.code,{children:"new-counter-1"})," and value 1. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L134",children:"line 134"}),", the test calls another factory entry point called ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," with counter name ",(0,r.jsx)(t.code,{children:"new-counter-2"}),". The default counter value is 0."]}),"\n",(0,r.jsx)(t.p,{children:"Once the requests are processed, the test checks the contract hashes of the contracts created:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The factory contract on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L146",children:"line 146"})]}),"\n",(0,r.jsxs)(t.li,{children:["The first counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L157",children:"line 157"})]}),"\n",(0,r.jsxs)(t.li,{children:["The second counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L168",children:"line 168"})]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The test proceeds to get the contract Wasm for each counter produced and test the Wasm exports, which are the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points in each counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"setup"})," function on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L209",children:"line 209"})," is a helper function for installing the factory contract on the chain and getting the contract factory hash."]}),"\n",(0,r.jsx)(t.p,{children:"The other tests in this file are also interesting:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L25",children:"should_not_call_undefined_entrypoints_on_factory"})," - This test verifies that entry points marked as a template cannot be called directly from the factory contract"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L87C4-L87C54",children:"contract_factory_wasm_should_have_expected_exports"})," - This test checks the entry points declared in the contract factory"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6520db96.17ace29b.js b/assets/js/6520db96.17ace29b.js deleted file mode 100644 index fd0e42ab1..000000000 --- a/assets/js/6520db96.17ace29b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9025],{15820:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>o,toc:()=>h});var r=n(74848),s=n(28453);const c={title:"Factory Contracts"},a="Writing Contracts using the Factory Pattern",o={id:"developers/writing-onchain-code/factory-pattern",title:"Factory Contracts",description:"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.",source:"@site/docs/developers/writing-onchain-code/factory-pattern.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/factory-pattern",permalink:"/next/developers/writing-onchain-code/factory-pattern",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Factory Contracts"},sidebar:"developers",previous:{title:"Contract Hash vs. Package Hash",permalink:"/next/developers/writing-onchain-code/contract-hash-vs-package-hash"},next:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/next/developers/writing-onchain-code/best-practices"}},i={},h=[{value:"The Counter Factory Example",id:"the-counter-factory-example",level:2},{value:"Unit tests",id:"unit-tests",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-contracts-using-the-factory-pattern",children:"Writing Contracts using the Factory Pattern"})}),"\n",(0,r.jsxs)(t.p,{children:["This guide presents a ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"factory pattern"})," for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"The factory pattern is a widely recognized software design concept used in various programming contexts. DApp developers may use factory implementations to create smart contracts from a given source (or factory), such as a factory method or entry point. A factory pattern ensures that the contracts produced maintain a specified behavior, such as specific entry points and arguments. In general, factories produce other smart contracts according to a template."}),"\n",(0,r.jsxs)(t.p,{children:["Casper factories are created using the entry point type called ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", which marks an entry point as a factory method responsible for creating and installing contracts on the chain. An installer entry point will derive new Wasm based on the original session Wasm and create a new contract with different sets of entry points as required. In other words, these installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"})," are the contract factories. When referring to the factory contract on this page, we mean the contract containing the factory entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marks an entry point that exists in the bytecode but is not callable. Thus, regular entry points can be referenced from within installer entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),". In object-oriented terms, entry points marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," act as virtual abstract methods and cannot be called from session code."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:["This factory pattern poses a known drawback when using Wasm. All the smart contracts created with the factory pattern share the same Wasm installed on the chain. Thus, developers cannot modify the Wasm once installed and create modified contracts using the factory pattern. Developers must specify all the possible entry points in the parent contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," marker."]})}),"\n",(0,r.jsx)(t.h2,{id:"the-counter-factory-example",children:"The Counter Factory Example"}),"\n",(0,r.jsxs)(t.p,{children:["This section dives into a ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/smart_contracts/contracts/test/counter-factory/src/main.rs",children:"simple counter that uses factory methods"})," to describe how to implement the factory pattern on a Casper network. The ",(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"})," demonstrates the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Let's start by exploring the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L115",children:"session code"}),", where the contract entry points are defined."]}),"\n",(0,r.jsxs)(t.p,{children:["Two installer entry points are marked with ",(0,r.jsx)(t.code,{children:"EntryPointType::Install"}),", meaning these entry points will produce new counter contracts once this Wasm is installed in global state. They are also marked with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," so that they can be called from the session code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n CONTRACT_FACTORY_DEFAULT_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Install,\n);\n"})}),"\n",(0,r.jsxs)(t.p,{children:["These two installers show how to declare multiple factory entry points and use them to initialize the Wasm they produce with different values. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L61C19-L61C35",children:"line 61"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point creates a counter contract with a given name and initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n let initial_value: U512 = runtime::get_named_arg(ARG_INITIAL_VALUE);\n installer(name, initial_value);\n}\n'})}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L68",children:"line 68"}),", the ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," entry point creates a counter contract with a given name and a zero initial value."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn contract_factory_default() {\n let name: String = runtime::get_named_arg(ARG_NAME);\n installer(name, U512::zero());\n}\n'})}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsx)(t.p,{children:"The factory pattern can produce contracts with different entry points. Suppose the session code defines entry points A, B, C, and D as templates. One installer factory entry point could use entry points A and B to create a contract, and the other installer entry point might use entry points C and D. Such support at the API level enables the implementation of more complex use cases."})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L73",children:"installer function"})," creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's ",(0,r.jsx)(t.code,{children:"decrement"})," and ",(0,r.jsx)(t.code,{children:"increment"})," functionality. These entry points are defined just like in any other smart contract, with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Public"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"}),", and they are callable for all the counters created. To learn how to call the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," functions, see the ",(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/walkthrough",children:"Counter on the Testnet Tutorial"}),", which is the non-factory version of the counter contract."]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Sample installer code for a counter factory"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"fn installer(name: String, initial_value: U512) {\n let named_keys = {\n let new_uref = storage::new_uref(initial_value);\n let mut named_keys = NamedKeys::new();\n named_keys.insert(CURRENT_VALUE_KEY.to_string(), new_uref.into());\n named_keys\n };\n\n let entry_points = {\n let mut entry_points = EntryPoints::new();\n let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n let entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n entry_points.add_entry_point(entry_point);\n\n entry_points\n };\n\n let (contract_hash, contract_version) = storage::new_contract(\n entry_points,\n Some(named_keys),\n Some(PACKAGE_HASH_KEY_NAME.to_string()),\n Some(ACCESS_KEY_NAME.to_string()),\n );\n\n runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\n runtime::put_key(&name, contract_hash.into());\n}\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["It is important to note that the installer logic ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L110-L111",children:"saves the newly created contract version and contract hash"})," under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#comparing-session-and-contract",children:"comparison between session and contract context"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());\nruntime::put_key(&name, contract_hash.into());\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For example, if you install the factory counter contract, you will see only one named key for this contract in your account, with the two installer entry points ",(0,r.jsx)(t.code,{children:"contract_factory"})," and ",(0,r.jsx)(t.code,{children:"contract_factory_default"}),". See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L155C1-L163",children:"lines 155-163"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["If you call the installer three times to create 3 different counters, you will see 3 named keys for each counter in the factory contract's named keys. The counter contracts produced will have the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points."]}),"\n",(0,r.jsxs)(t.p,{children:["As explained above, developers must define all the possible non-installer entry points in the factory contract and tag them with the ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"})," and ",(0,r.jsx)(t.code,{children:"EntryPointType::Contract"})," markers. See ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/smart_contracts/contracts/test/counter-factory/src/main.rs#L135C9-L149C11",children:"lines 135-139"}),":"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let entry_point: EntryPoint = EntryPoint::new(\n INCREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\nentry_points.add_entry_point(entry_point);\nlet entry_point: EntryPoint = EntryPoint::new(\n DECREASE_ENTRY_POINT.to_string(),\n Parameters::new(),\n CLType::Unit,\n EntryPointAccess::Template,\n EntryPointType::Contract,\n);\n"})}),"\n",(0,r.jsx)(t.admonition,{type:"warning",children:(0,r.jsxs)(t.p,{children:["Suppose developers forget to declare an entry point in the outermost session logic (the ",(0,r.jsx)(t.code,{children:"call"})," function) and mark it with ",(0,r.jsx)(t.code,{children:"EntryPointAccess::Template"}),"; that Wasm export will be removed when the factory contract is installed in global state. Creating the entry point in the installer logic is not sufficient."]})}),"\n",(0,r.jsx)(t.h3,{id:"unit-tests",children:"Unit tests"}),"\n",(0,r.jsxs)(t.p,{children:["Developers can test contracts that follow the factory pattern using the Casper testing framework described under ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"Unit Testing Smart Contracts"}),". The testing process is the same, but this section highlights a particular test called ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L116C4-L116C42",children:"should_install_and_use_factory_pattern"})," found in the ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/gh-2064-factory-pattern/execution_engine_testing/tests/src/test/counter_factory.rs",children:"unit test suite"})," of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior."]}),"\n",(0,r.jsxs)(t.p,{children:["On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L120",children:"line 120"}),", the test starts building a request to call the ",(0,r.jsx)(t.code,{children:"contract_factory"})," entry point with counter name ",(0,r.jsx)(t.code,{children:"new-counter-1"})," and value 1. On ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L134",children:"line 134"}),", the test calls another factory entry point called ",(0,r.jsx)(t.code,{children:"contract_factory_default"})," with counter name ",(0,r.jsx)(t.code,{children:"new-counter-2"}),". The default counter value is 0."]}),"\n",(0,r.jsx)(t.p,{children:"Once the requests are processed, the test checks the contract hashes of the contracts created:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The factory contract on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L146",children:"line 146"})]}),"\n",(0,r.jsxs)(t.li,{children:["The first counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L157",children:"line 157"})]}),"\n",(0,r.jsxs)(t.li,{children:["The second counter on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L168",children:"line 168"})]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The test proceeds to get the contract Wasm for each counter produced and test the Wasm exports, which are the ",(0,r.jsx)(t.code,{children:"increment"})," and ",(0,r.jsx)(t.code,{children:"decrement"})," entry points in each counter contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"setup"})," function on ",(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L209",children:"line 209"})," is a helper function for installing the factory contract on the chain and getting the contract factory hash."]}),"\n",(0,r.jsx)(t.p,{children:"The other tests in this file are also interesting:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L25",children:"should_not_call_undefined_entrypoints_on_factory"})," - This test verifies that entry points marked as a template cannot be called directly from the factory contract"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://github.com/mpapierski/casper-node/blob/a4d7d5a4f67e7860b2e8c57d74c864860b4e74c8/execution_engine_testing/tests/src/test/counter_factory.rs#L87C4-L87C54",children:"contract_factory_wasm_should_have_expected_exports"})," - This test checks the entry points declared in the contract factory"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65961da4.2834b925.js b/assets/js/65961da4.2834b925.js new file mode 100644 index 000000000..7c964493f --- /dev/null +++ b/assets/js/65961da4.2834b925.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94889],{1051:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={},o="Casper Node Networking Protocol",d={id:"concepts/design/networking-protocol",title:"Casper Node Networking Protocol",description:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",source:"@site/docs/concepts/design/networking-protocol.md",sourceDirName:"concepts/design",slug:"/concepts/design/networking-protocol",permalink:"/concepts/design/networking-protocol",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},a={},c=[{value:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",id:"casper-node-networking-protocol-mainnet-protocol-version-150",level:2},{value:"Connection Level",id:"connection-level",level:2},{value:"Reciprocity, retries and data direction",id:"reciprocity-retries-and-data-direction",level:3},{value:"TLS parameters",id:"tls-parameters",level:3},{value:"Discovery",id:"discovery",level:3},{value:"Framing",id:"framing",level:2},{value:"Encoding",id:"encoding",level:2},{value:"The <code>Message</code> Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The <code>Payload</code> Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"casper-node-networking-protocol",children:"Casper Node Networking Protocol"})}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-networking-protocol-mainnet-protocol-version-150",children:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of the ",(0,i.jsx)(n.code,{children:"casper-node"}),"'s networking protocol. This document follows the conventions laid out in ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"connection-level",children:"Connection Level"}),"\n",(0,i.jsxs)(n.p,{children:["Any ",(0,i.jsx)(n.code,{children:"casper-node"})," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."]}),"\n",(0,i.jsx)(n.h3,{id:"reciprocity-retries-and-data-direction",children:"Reciprocity, retries and data direction"}),"\n",(0,i.jsxs)(n.p,{children:["A connection that was initiated by a node is considered an ",(0,i.jsx)(n.em,{children:"outgoing"})," connection by the node itself, but an ",(0,i.jsx)(n.em,{children:"incoming"})," connection by all other peers."]}),"\n",(0,i.jsx)(n.p,{children:"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."}),"\n",(0,i.jsx)(n.p,{children:"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."}),"\n",(0,i.jsx)(n.p,{children:"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."}),"\n",(0,i.jsx)(n.p,{children:"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."}),"\n",(0,i.jsx)(n.h3,{id:"tls-parameters",children:"TLS parameters"}),"\n",(0,i.jsx)(n.p,{children:"Any node creating a connection to a node MUST present a client certificate with the following properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Signature algorithm: ",(0,i.jsx)(n.code,{children:"ECDSA_WITH_SHA512"})]}),"\n",(0,i.jsx)(n.li,{children:"Subject name: Same as issuer name (self-signed certificate!)"}),"\n",(0,i.jsx)(n.li,{children:"Serial number: 1"}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not before"): Must be earlier than current time.'}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not after"): Must be later than current time.'}),"\n",(0,i.jsxs)(n.li,{children:["Signature: Must be using ",(0,i.jsx)(n.code,{children:"SECP521R1"})," with ",(0,i.jsx)(n.code,{children:"SHA512"})," and valid."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The SHA512 fingerprint of the ",(0,i.jsx)(n.em,{children:"public key"})," is considered the ",(0,i.jsx)(n.strong,{children:"NodeID"})," of the node."]}),"\n",(0,i.jsx)(n.p,{children:"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."}),"\n",(0,i.jsx)(n.p,{children:"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."}),"\n",(0,i.jsx)(n.h3,{id:"discovery",children:"Discovery"}),"\n",(0,i.jsx)(n.p,{children:"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."}),"\n",(0,i.jsxs)(n.p,{children:["Every node SHOULD have one or more so-called ",(0,i.jsx)(n.em,{children:"known node addresses"})," of other nodes configured."]}),"\n",(0,i.jsx)(n.p,{children:"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."}),"\n",(0,i.jsx)(n.p,{children:"Every node MUST periodically gossip its own node address to the network (see gossiping below)."}),"\n",(0,i.jsxs)(n.p,{children:["A node ",(0,i.jsx)(n.em,{children:"learns"})," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."]}),"\n",(0,i.jsx)(n.p,{children:"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."}),"\n",(0,i.jsxs)(n.p,{children:["After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,i.jsx)(n.em,{children:"forgetting"})," a node. An address that has been forgotten will be considered new the next time it is learned."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT forget the known addresses it was configured with initially."}),"\n",(0,i.jsx)(n.h2,{id:"framing",children:"Framing"}),"\n",(0,i.jsx)(n.p,{children:"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."}),"\n",(0,i.jsx)(n.p,{children:"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."}),"\n",(0,i.jsx)(n.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsxs)(n.p,{children:["The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,i.jsx)(n.a,{href:"https://msgpack.org",children:"MessagePack"}),", while regular messages are encoded using ",(0,i.jsx)(n.a,{href:"https://docs.rs/bincode",children:"bincode"}),". Many (but not all) data objects use ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html",children:(0,i.jsx)(n.code,{children:"bytesrepr"})})," for serialization."]}),"\n",(0,i.jsxs)(n.p,{children:["The node uses the ",(0,i.jsx)(n.a,{href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html",children:(0,i.jsx)(n.code,{children:"rmp-serde"})})," crate, version ",(0,i.jsx)(n.code,{children:"0.14.4"}),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."]}),"\n",(0,i.jsxs)(n.p,{children:["All nodes MUST use the following settings for ",(0,i.jsx)(n.code,{children:"bincode"})," encoding of network messages:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Varint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Not allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Any other use of ",(0,i.jsx)(n.code,{children:"bincode"})," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,i.jsx)(n.code,{children:"bincode"})," encoding settings:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Fixint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,i.jsx)(n.a,{href:"https://serde.rs",children:(0,i.jsx)(n.code,{children:"serde"})}),"-derived encoding. For ",(0,i.jsx)(n.code,{children:"bytesrepr"})," serialization refer to the specific implementations in the ",(0,i.jsx)(n.code,{children:"bytesrepr"})," crate."]}),"\n",(0,i.jsxs)(n.p,{children:["Any data types given from here on out are described using simplified ",(0,i.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," structure definitions."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-message-type",children:["The ",(0,i.jsx)(n.code,{children:"Message"})," Type"]}),"\n",(0,i.jsx)(n.p,{children:"The following data types make up the networking protocol:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option<ConsensusCertificate>,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option<Digest>,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/string/struct.String.html",children:(0,i.jsx)(n.code,{children:"String"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html",children:(0,i.jsx)(n.code,{children:"SocketAddr"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html",children:(0,i.jsx)(n.code,{children:"ProtocolVersion"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/option/enum.Option.html",children:(0,i.jsx)(n.code,{children:"Option"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html",children:(0,i.jsx)(n.code,{children:"Signature"})})," see the respective docs and details below."]}),"\n",(0,i.jsx)(n.h2,{id:"handshake-behavior",children:"Handshake Behavior"}),"\n",(0,i.jsx)(n.p,{children:"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."}),"\n",(0,i.jsxs)(n.p,{children:["A handshake MUST be encoded using the ",(0,i.jsx)(n.code,{children:"Message::Handshake"})," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,i.jsx)(n.code,{children:"protocol_version"}),", ",(0,i.jsx)(n.code,{children:"consensus_certificate"}),", ",(0,i.jsx)(n.code,{children:"is_syncing"}),", ",(0,i.jsx)(n.code,{children:"chainspec_hash"}),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."]}),"\n",(0,i.jsxs)(n.p,{children:["After receiving a handshake, a node MUST compare the ",(0,i.jsx)(n.code,{children:"network_name"}),", ",(0,i.jsx)(n.code,{children:"protocol_version"})," and ",(0,i.jsx)(n.code,{children:"chainspec_hash"})," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,i.jsx)(n.code,{children:"is_syncing"})," set to ",(0,i.jsx)(n.code,{children:"true"}),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.']}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY compare peers that provide a ",(0,i.jsx)(n.code,{children:"consensus_certificate"})," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon handshake completion, the node SHOULD learn the provided ",(0,i.jsx)(n.code,{children:"public_addr"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blocking-nodes",children:"Blocking Nodes"}),"\n",(0,i.jsx)(n.p,{children:"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."}),"\n",(0,i.jsxs)(n.p,{children:["After a block on a node is expired, the node SHOULD ",(0,i.jsx)(n.em,{children:"forget"})," the nodes IP address, allowing a later ",(0,i.jsx)(n.em,{children:"learning"})," of said address again."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-payload-type",children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," Type"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," (found in the node sources as ",(0,i.jsx)(n.code,{children:"Message"})," in ",(0,i.jsx)(n.code,{children:"payload.rs"}),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,i.jsx)(n.code,{children:"bincode"})," encoding, this should have no effect on implementations."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec<u8>,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:"Consensus"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/concepts/design/consensus",children:"consensus"})," message is sent exclusively between instances of the consensus component, from one peer to another."]}),"\n",(0,i.jsx)(n.h3,{id:"gossiping",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."}),"\n",(0,i.jsxs)(n.p,{children:["A node must support a gossiper for deploys and one for ",(0,i.jsx)(n.code,{children:"GossippedAddress"}),", which is an alias for the regular Rust standard library's ",(0,i.jsx)(n.code,{children:"SocketAddr"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,i.jsx)(n.code,{children:"AddressGossiperMessage::Gossip"})," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."]}),"\n",(0,i.jsx)(n.h3,{id:"unsafe-for-syncing",children:"Unsafe-for-syncing"}),"\n",(0,i.jsxs)(n.p,{children:["A node that is syncing MUST indicate this by setting ",(0,i.jsx)(n.code,{children:"is_syncing"})," to ",(0,i.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s that can cause issues with peers that are also sending GetRequests."]}),"\n",(0,i.jsxs)(n.p,{children:["A node that succeeds in a handshake with a peer that has set ",(0,i.jsx)(n.code,{children:"is_syncing"})," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s."]}),"\n",(0,i.jsx)(n.h2,{id:"gossiping-1",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."}),"\n",(0,i.jsx)(n.p,{children:"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."}),"\n",(0,i.jsx)(n.p,{children:"Gossiper messages have the following structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To gossip, a node MAY send a ",(0,i.jsx)(n.code,{children:"GossiperMessage::Gossip"})," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,i.jsx)(n.code,{children:"GossiperMessage:GossipResponse"}),", citing the given id and using ",(0,i.jsx)(n.code,{children:"is_already_held"})," to indicate whether it already possessed the given item."]}),"\n",(0,i.jsx)(n.p,{children:"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."}),"\n",(0,i.jsxs)(n.p,{children:["The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"true"}),") response and MUST NOT send another ",(0,i.jsx)(n.code,{children:"Gossip"})," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."]}),"\n",(0,i.jsxs)(n.p,{children:["If a node receives a negative ",(0,i.jsx)(n.code,{children:"GossiperMessage::GossipResponse"})," (i.e. ",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"false"}),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,i.jsx)(n.code,{children:"GetRequest"})," for the item (see GetRequests section below)."]}),"\n",(0,i.jsx)(n.h2,{id:"getrequests",children:"GetRequests"}),"\n",(0,i.jsx)(n.p,{children:'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'}),"\n",(0,i.jsxs)(n.p,{children:["A peer MAY send a ",(0,i.jsx)(n.code,{children:"GetRequest"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetRequest"}),") with a ",(0,i.jsx)(n.code,{children:"Tag"})," and ",(0,i.jsx)(n.code,{children:"serialized_id"})," payload. Both ",(0,i.jsx)(n.code,{children:"serialized_id"})," and ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST be encoded using ",(0,i.jsx)(n.code,{children:"bincode"}),' (see "Encoding" section for details).']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"The tag dictates which item is being retrieved, and which key (ID type) is being used."}),"\n",(0,i.jsxs)(n.p,{children:["A node that receives a ",(0,i.jsx)(n.code,{children:"GetRequest"})," from a peer SHOULD return a ",(0,i.jsx)(n.code,{children:"GetResponse"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetResponse"}),"). The ",(0,i.jsx)(n.code,{children:"GetResponse"})," MUST use the same ",(0,i.jsx)(n.code,{children:"Tag"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum FetchedOrNotFound<T, Id> {\n Fetched(T),\n NotFound(Id),\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the item was found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a serialized ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::Fetched"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"T"})," being the item."]}),"\n",(0,i.jsxs)(n.p,{children:["If the item was not found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::NotFound"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"Id"})," being the ID found in the originating ",(0,i.jsx)(n.code,{children:"GetRequest"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST not send any items to a peer that it itself has not verified."}),"\n",(0,i.jsxs)(n.p,{children:["The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,i.jsx)(n.code,{children:"DeployHash"})," and ",(0,i.jsx)(n.code,{children:"GossippedAddress"})," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,i.jsx)(n.a,{href:"/concepts/serialization/",children:"Serialization Standard"}),", but be aware that those docs describe serializing using bytesrepr rather than bincode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Tag"}),(0,i.jsx)(n.th,{children:"ID type"}),(0,i.jsx)(n.th,{children:"Payload (item) type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Deploy"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Deploy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalizedApprovals"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"FinalizedApprovalsWithId"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Block"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Block"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"GossipedAddress"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndMetadataByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeader"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderAndFinalitySignaturesByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeaderWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TrieOrChunk"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunkId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunk"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndDeploysByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockAndDeploys"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderBatch"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatch"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalitySignaturesByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockSignatures"})})]})]})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet<Approval>,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec<DeployHash>,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec<u8>,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec<NamedArg>);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec<u8>);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box<CLType>),\n List(Box<CLType>),\n ByteArray(u32),\n Result { ok: Box<CLType>, err: Box<CLType> },\n Map { key: Box<CLType>, value: Box<CLType> },\n Tuple1([Box<CLType>; 1]),\n Tuple2([Box<CLType>; 2]),\n Tuple3([Box<CLType>; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet<Approval>);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option<EraEnd>,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap<PublicKey, U512>,\n}\n\nstruct EraReport<VID> {\n equivocators: Vec<PublicKey>,\n rewards: BTreeMap<PublicKey, u64>,\n inactive_validators: Vec<PublicKey>,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec<DeployHash>,\n transfer_hashes: Vec<DeployHash>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Custom variable length encoding is used when serializing ",(0,i.jsx)(n.code,{children:"U512"}),", ",(0,i.jsx)(n.code,{children:"U256"})," and ",(0,i.jsx)(n.code,{children:"U128"})," types. They are encoded in a way equivalent to encoding the following pseudo struct:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"In other words, the following steps are taken:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"convert the bigint to an array of bytes in little-endian form"}),"\n",(0,i.jsxs)(n.li,{children:["strip the contiguous range of irrelevant padding ",(0,i.jsx)(n.code,{children:"0"})," bytes from the right hand end, if any"]}),"\n",(0,i.jsx)(n.li,{children:"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For a description explaining the use of ",(0,i.jsx)(n.code,{children:"TrieOrChunk"}),' and related types, see the "Trie chunking" section. The relevant types are:']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec<Digest>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})," is used to request multiple ",(0,i.jsx)(n.code,{children:"BlockHeader"}),"s with a single request."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap<PublicKey, Signature>,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec<Deploy>,\n}\n\nstruct BlockHeadersBatch(Vec<BlockHeader>);\n"})}),"\n",(0,i.jsx)(n.h2,{id:"finality-signatures",children:"Finality Signatures"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload::FinalitySignature"})," variant is used when broadcasting finality signatures."]}),"\n",(0,i.jsx)(n.p,{children:"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."}),"\n",(0,i.jsx)(n.h2,{id:"trie-chunking",children:"Trie Chunking"}),"\n",(0,i.jsxs)(n.p,{children:["Large trie nodes are split when transferred across the network, according to ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"}),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,i.jsx)(n.code,{children:"TrieOrChunk::Trie"})," instance."]}),"\n",(0,i.jsxs)(n.p,{children:["Should a trie node be larger than this, a Merkle tree is constructed with ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"})," sized chunks and is identified by the root hash of the resulting tree instead."]}),"\n",(0,i.jsxs)(n.p,{children:["Peers MUST only request chunks. The ",(0,i.jsx)(n.code,{children:"TrieOrChunkId"})," type allows for requesting the n-th chunk of a given trie node. See the ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-hashing",children:"casper-hashing"})," crate for details."]}),"\n",(0,i.jsxs)(n.p,{children:["A node receiving a ",(0,i.jsx)(n.code,{children:"TrieOrChunk"})," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65961da4.60f93cb9.js b/assets/js/65961da4.60f93cb9.js deleted file mode 100644 index 787972b01..000000000 --- a/assets/js/65961da4.60f93cb9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4889],{1051:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={},o="Casper Node Networking Protocol",d={id:"concepts/design/networking-protocol",title:"Casper Node Networking Protocol",description:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",source:"@site/docs/concepts/design/networking-protocol.md",sourceDirName:"concepts/design",slug:"/concepts/design/networking-protocol",permalink:"/next/concepts/design/networking-protocol",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},a={},c=[{value:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",id:"casper-node-networking-protocol-mainnet-protocol-version-150",level:2},{value:"Connection Level",id:"connection-level",level:2},{value:"Reciprocity, retries and data direction",id:"reciprocity-retries-and-data-direction",level:3},{value:"TLS parameters",id:"tls-parameters",level:3},{value:"Discovery",id:"discovery",level:3},{value:"Framing",id:"framing",level:2},{value:"Encoding",id:"encoding",level:2},{value:"The <code>Message</code> Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The <code>Payload</code> Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"casper-node-networking-protocol",children:"Casper Node Networking Protocol"})}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-networking-protocol-mainnet-protocol-version-150",children:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of the ",(0,i.jsx)(n.code,{children:"casper-node"}),"'s networking protocol. This document follows the conventions laid out in ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"connection-level",children:"Connection Level"}),"\n",(0,i.jsxs)(n.p,{children:["Any ",(0,i.jsx)(n.code,{children:"casper-node"})," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."]}),"\n",(0,i.jsx)(n.h3,{id:"reciprocity-retries-and-data-direction",children:"Reciprocity, retries and data direction"}),"\n",(0,i.jsxs)(n.p,{children:["A connection that was initiated by a node is considered an ",(0,i.jsx)(n.em,{children:"outgoing"})," connection by the node itself, but an ",(0,i.jsx)(n.em,{children:"incoming"})," connection by all other peers."]}),"\n",(0,i.jsx)(n.p,{children:"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."}),"\n",(0,i.jsx)(n.p,{children:"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."}),"\n",(0,i.jsx)(n.p,{children:"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."}),"\n",(0,i.jsx)(n.p,{children:"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."}),"\n",(0,i.jsx)(n.h3,{id:"tls-parameters",children:"TLS parameters"}),"\n",(0,i.jsx)(n.p,{children:"Any node creating a connection to a node MUST present a client certificate with the following properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Signature algorithm: ",(0,i.jsx)(n.code,{children:"ECDSA_WITH_SHA512"})]}),"\n",(0,i.jsx)(n.li,{children:"Subject name: Same as issuer name (self-signed certificate!)"}),"\n",(0,i.jsx)(n.li,{children:"Serial number: 1"}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not before"): Must be earlier than current time.'}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not after"): Must be later than current time.'}),"\n",(0,i.jsxs)(n.li,{children:["Signature: Must be using ",(0,i.jsx)(n.code,{children:"SECP521R1"})," with ",(0,i.jsx)(n.code,{children:"SHA512"})," and valid."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The SHA512 fingerprint of the ",(0,i.jsx)(n.em,{children:"public key"})," is considered the ",(0,i.jsx)(n.strong,{children:"NodeID"})," of the node."]}),"\n",(0,i.jsx)(n.p,{children:"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."}),"\n",(0,i.jsx)(n.p,{children:"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."}),"\n",(0,i.jsx)(n.h3,{id:"discovery",children:"Discovery"}),"\n",(0,i.jsx)(n.p,{children:"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."}),"\n",(0,i.jsxs)(n.p,{children:["Every node SHOULD have one or more so-called ",(0,i.jsx)(n.em,{children:"known node addresses"})," of other nodes configured."]}),"\n",(0,i.jsx)(n.p,{children:"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."}),"\n",(0,i.jsx)(n.p,{children:"Every node MUST periodically gossip its own node address to the network (see gossiping below)."}),"\n",(0,i.jsxs)(n.p,{children:["A node ",(0,i.jsx)(n.em,{children:"learns"})," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."]}),"\n",(0,i.jsx)(n.p,{children:"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."}),"\n",(0,i.jsxs)(n.p,{children:["After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,i.jsx)(n.em,{children:"forgetting"})," a node. An address that has been forgotten will be considered new the next time it is learned."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT forget the known addresses it was configured with initially."}),"\n",(0,i.jsx)(n.h2,{id:"framing",children:"Framing"}),"\n",(0,i.jsx)(n.p,{children:"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."}),"\n",(0,i.jsx)(n.p,{children:"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."}),"\n",(0,i.jsx)(n.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsxs)(n.p,{children:["The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,i.jsx)(n.a,{href:"https://msgpack.org",children:"MessagePack"}),", while regular messages are encoded using ",(0,i.jsx)(n.a,{href:"https://docs.rs/bincode",children:"bincode"}),". Many (but not all) data objects use ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html",children:(0,i.jsx)(n.code,{children:"bytesrepr"})})," for serialization."]}),"\n",(0,i.jsxs)(n.p,{children:["The node uses the ",(0,i.jsx)(n.a,{href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html",children:(0,i.jsx)(n.code,{children:"rmp-serde"})})," crate, version ",(0,i.jsx)(n.code,{children:"0.14.4"}),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."]}),"\n",(0,i.jsxs)(n.p,{children:["All nodes MUST use the following settings for ",(0,i.jsx)(n.code,{children:"bincode"})," encoding of network messages:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Varint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Not allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Any other use of ",(0,i.jsx)(n.code,{children:"bincode"})," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,i.jsx)(n.code,{children:"bincode"})," encoding settings:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Fixint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,i.jsx)(n.a,{href:"https://serde.rs",children:(0,i.jsx)(n.code,{children:"serde"})}),"-derived encoding. For ",(0,i.jsx)(n.code,{children:"bytesrepr"})," serialization refer to the specific implementations in the ",(0,i.jsx)(n.code,{children:"bytesrepr"})," crate."]}),"\n",(0,i.jsxs)(n.p,{children:["Any data types given from here on out are described using simplified ",(0,i.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," structure definitions."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-message-type",children:["The ",(0,i.jsx)(n.code,{children:"Message"})," Type"]}),"\n",(0,i.jsx)(n.p,{children:"The following data types make up the networking protocol:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option<ConsensusCertificate>,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option<Digest>,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/string/struct.String.html",children:(0,i.jsx)(n.code,{children:"String"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html",children:(0,i.jsx)(n.code,{children:"SocketAddr"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html",children:(0,i.jsx)(n.code,{children:"ProtocolVersion"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/option/enum.Option.html",children:(0,i.jsx)(n.code,{children:"Option"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html",children:(0,i.jsx)(n.code,{children:"Signature"})})," see the respective docs and details below."]}),"\n",(0,i.jsx)(n.h2,{id:"handshake-behavior",children:"Handshake Behavior"}),"\n",(0,i.jsx)(n.p,{children:"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."}),"\n",(0,i.jsxs)(n.p,{children:["A handshake MUST be encoded using the ",(0,i.jsx)(n.code,{children:"Message::Handshake"})," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,i.jsx)(n.code,{children:"protocol_version"}),", ",(0,i.jsx)(n.code,{children:"consensus_certificate"}),", ",(0,i.jsx)(n.code,{children:"is_syncing"}),", ",(0,i.jsx)(n.code,{children:"chainspec_hash"}),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."]}),"\n",(0,i.jsxs)(n.p,{children:["After receiving a handshake, a node MUST compare the ",(0,i.jsx)(n.code,{children:"network_name"}),", ",(0,i.jsx)(n.code,{children:"protocol_version"})," and ",(0,i.jsx)(n.code,{children:"chainspec_hash"})," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,i.jsx)(n.code,{children:"is_syncing"})," set to ",(0,i.jsx)(n.code,{children:"true"}),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.']}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY compare peers that provide a ",(0,i.jsx)(n.code,{children:"consensus_certificate"})," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon handshake completion, the node SHOULD learn the provided ",(0,i.jsx)(n.code,{children:"public_addr"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blocking-nodes",children:"Blocking Nodes"}),"\n",(0,i.jsx)(n.p,{children:"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."}),"\n",(0,i.jsxs)(n.p,{children:["After a block on a node is expired, the node SHOULD ",(0,i.jsx)(n.em,{children:"forget"})," the nodes IP address, allowing a later ",(0,i.jsx)(n.em,{children:"learning"})," of said address again."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-payload-type",children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," Type"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," (found in the node sources as ",(0,i.jsx)(n.code,{children:"Message"})," in ",(0,i.jsx)(n.code,{children:"payload.rs"}),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,i.jsx)(n.code,{children:"bincode"})," encoding, this should have no effect on implementations."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec<u8>,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:"Consensus"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/next/concepts/design/consensus",children:"consensus"})," message is sent exclusively between instances of the consensus component, from one peer to another."]}),"\n",(0,i.jsx)(n.h3,{id:"gossiping",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."}),"\n",(0,i.jsxs)(n.p,{children:["A node must support a gossiper for deploys and one for ",(0,i.jsx)(n.code,{children:"GossippedAddress"}),", which is an alias for the regular Rust standard library's ",(0,i.jsx)(n.code,{children:"SocketAddr"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,i.jsx)(n.code,{children:"AddressGossiperMessage::Gossip"})," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."]}),"\n",(0,i.jsx)(n.h3,{id:"unsafe-for-syncing",children:"Unsafe-for-syncing"}),"\n",(0,i.jsxs)(n.p,{children:["A node that is syncing MUST indicate this by setting ",(0,i.jsx)(n.code,{children:"is_syncing"})," to ",(0,i.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s that can cause issues with peers that are also sending GetRequests."]}),"\n",(0,i.jsxs)(n.p,{children:["A node that succeeds in a handshake with a peer that has set ",(0,i.jsx)(n.code,{children:"is_syncing"})," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s."]}),"\n",(0,i.jsx)(n.h2,{id:"gossiping-1",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."}),"\n",(0,i.jsx)(n.p,{children:"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."}),"\n",(0,i.jsx)(n.p,{children:"Gossiper messages have the following structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To gossip, a node MAY send a ",(0,i.jsx)(n.code,{children:"GossiperMessage::Gossip"})," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,i.jsx)(n.code,{children:"GossiperMessage:GossipResponse"}),", citing the given id and using ",(0,i.jsx)(n.code,{children:"is_already_held"})," to indicate whether it already possessed the given item."]}),"\n",(0,i.jsx)(n.p,{children:"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."}),"\n",(0,i.jsxs)(n.p,{children:["The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"true"}),") response and MUST NOT send another ",(0,i.jsx)(n.code,{children:"Gossip"})," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."]}),"\n",(0,i.jsxs)(n.p,{children:["If a node receives a negative ",(0,i.jsx)(n.code,{children:"GossiperMessage::GossipResponse"})," (i.e. ",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"false"}),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,i.jsx)(n.code,{children:"GetRequest"})," for the item (see GetRequests section below)."]}),"\n",(0,i.jsx)(n.h2,{id:"getrequests",children:"GetRequests"}),"\n",(0,i.jsx)(n.p,{children:'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'}),"\n",(0,i.jsxs)(n.p,{children:["A peer MAY send a ",(0,i.jsx)(n.code,{children:"GetRequest"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetRequest"}),") with a ",(0,i.jsx)(n.code,{children:"Tag"})," and ",(0,i.jsx)(n.code,{children:"serialized_id"})," payload. Both ",(0,i.jsx)(n.code,{children:"serialized_id"})," and ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST be encoded using ",(0,i.jsx)(n.code,{children:"bincode"}),' (see "Encoding" section for details).']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"The tag dictates which item is being retrieved, and which key (ID type) is being used."}),"\n",(0,i.jsxs)(n.p,{children:["A node that receives a ",(0,i.jsx)(n.code,{children:"GetRequest"})," from a peer SHOULD return a ",(0,i.jsx)(n.code,{children:"GetResponse"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetResponse"}),"). The ",(0,i.jsx)(n.code,{children:"GetResponse"})," MUST use the same ",(0,i.jsx)(n.code,{children:"Tag"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum FetchedOrNotFound<T, Id> {\n Fetched(T),\n NotFound(Id),\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the item was found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a serialized ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::Fetched"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"T"})," being the item."]}),"\n",(0,i.jsxs)(n.p,{children:["If the item was not found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::NotFound"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"Id"})," being the ID found in the originating ",(0,i.jsx)(n.code,{children:"GetRequest"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST not send any items to a peer that it itself has not verified."}),"\n",(0,i.jsxs)(n.p,{children:["The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,i.jsx)(n.code,{children:"DeployHash"})," and ",(0,i.jsx)(n.code,{children:"GossippedAddress"})," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,i.jsx)(n.a,{href:"/next/concepts/serialization/",children:"Serialization Standard"}),", but be aware that those docs describe serializing using bytesrepr rather than bincode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Tag"}),(0,i.jsx)(n.th,{children:"ID type"}),(0,i.jsx)(n.th,{children:"Payload (item) type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Deploy"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Deploy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalizedApprovals"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"FinalizedApprovalsWithId"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Block"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Block"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"GossipedAddress"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndMetadataByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeader"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderAndFinalitySignaturesByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeaderWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TrieOrChunk"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunkId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunk"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndDeploysByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockAndDeploys"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderBatch"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatch"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalitySignaturesByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockSignatures"})})]})]})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet<Approval>,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec<DeployHash>,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec<u8>,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec<NamedArg>);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec<u8>);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box<CLType>),\n List(Box<CLType>),\n ByteArray(u32),\n Result { ok: Box<CLType>, err: Box<CLType> },\n Map { key: Box<CLType>, value: Box<CLType> },\n Tuple1([Box<CLType>; 1]),\n Tuple2([Box<CLType>; 2]),\n Tuple3([Box<CLType>; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet<Approval>);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option<EraEnd>,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap<PublicKey, U512>,\n}\n\nstruct EraReport<VID> {\n equivocators: Vec<PublicKey>,\n rewards: BTreeMap<PublicKey, u64>,\n inactive_validators: Vec<PublicKey>,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec<DeployHash>,\n transfer_hashes: Vec<DeployHash>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Custom variable length encoding is used when serializing ",(0,i.jsx)(n.code,{children:"U512"}),", ",(0,i.jsx)(n.code,{children:"U256"})," and ",(0,i.jsx)(n.code,{children:"U128"})," types. They are encoded in a way equivalent to encoding the following pseudo struct:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"In other words, the following steps are taken:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"convert the bigint to an array of bytes in little-endian form"}),"\n",(0,i.jsxs)(n.li,{children:["strip the contiguous range of irrelevant padding ",(0,i.jsx)(n.code,{children:"0"})," bytes from the right hand end, if any"]}),"\n",(0,i.jsx)(n.li,{children:"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For a description explaining the use of ",(0,i.jsx)(n.code,{children:"TrieOrChunk"}),' and related types, see the "Trie chunking" section. The relevant types are:']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec<Digest>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})," is used to request multiple ",(0,i.jsx)(n.code,{children:"BlockHeader"}),"s with a single request."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap<PublicKey, Signature>,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec<Deploy>,\n}\n\nstruct BlockHeadersBatch(Vec<BlockHeader>);\n"})}),"\n",(0,i.jsx)(n.h2,{id:"finality-signatures",children:"Finality Signatures"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload::FinalitySignature"})," variant is used when broadcasting finality signatures."]}),"\n",(0,i.jsx)(n.p,{children:"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."}),"\n",(0,i.jsx)(n.h2,{id:"trie-chunking",children:"Trie Chunking"}),"\n",(0,i.jsxs)(n.p,{children:["Large trie nodes are split when transferred across the network, according to ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"}),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,i.jsx)(n.code,{children:"TrieOrChunk::Trie"})," instance."]}),"\n",(0,i.jsxs)(n.p,{children:["Should a trie node be larger than this, a Merkle tree is constructed with ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"})," sized chunks and is identified by the root hash of the resulting tree instead."]}),"\n",(0,i.jsxs)(n.p,{children:["Peers MUST only request chunks. The ",(0,i.jsx)(n.code,{children:"TrieOrChunkId"})," type allows for requesting the n-th chunk of a given trie node. See the ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-hashing",children:"casper-hashing"})," crate for details."]}),"\n",(0,i.jsxs)(n.p,{children:["A node receiving a ",(0,i.jsx)(n.code,{children:"TrieOrChunk"})," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65a9ed9e.3fe3d223.js b/assets/js/65a9ed9e.3fe3d223.js new file mode 100644 index 000000000..286bd9978 --- /dev/null +++ b/assets/js/65a9ed9e.3fe3d223.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5731],{92439:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="U",a={id:"concepts/glossary/U",title:"U",description:"---",source:"@site/docs/concepts/glossary/U.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/U",permalink:"/concepts/glossary/U",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"T",permalink:"/concepts/glossary/T"},next:{title:"V",permalink:"/concepts/glossary/V"}},i={},l=[{value:"Unbonding",id:"unbonding",level:2},{value:"URef",id:"uref",level:2},{value:"Users",id:"users",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"u",children:"U"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"unbonding",children:"Unbonding"}),"\n",(0,r.jsxs)(s.p,{children:["Withdrawing money from the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/A#auction",children:"auction"})," contract with ",(0,r.jsx)(s.em,{children:"withdraw bid"})," and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed."]}),"\n",(0,r.jsx)(s.h2,{id:"uref",children:"URef"}),"\n",(0,r.jsxs)(s.p,{children:["An ",(0,r.jsx)(s.strong,{children:"U"}),"nforgeable ",(0,r.jsx)(s.strong,{children:"Ref"}),"erence, used by a Casper network to store any value other than ",(0,r.jsx)(s.code,{children:"Account"}),". More information can be found ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design#uref-head",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"users",children:"Users"}),"\n",(0,r.jsx)(s.p,{children:"Users execute session and contract code using the platform's computational resources."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65a9ed9e.f11f4e01.js b/assets/js/65a9ed9e.f11f4e01.js deleted file mode 100644 index 3c561af2e..000000000 --- a/assets/js/65a9ed9e.f11f4e01.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5731],{92439:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=s(74848),t=s(28453);const c={},o="U",a={id:"concepts/glossary/U",title:"U",description:"---",source:"@site/docs/concepts/glossary/U.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/U",permalink:"/next/concepts/glossary/U",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"T",permalink:"/next/concepts/glossary/T"},next:{title:"V",permalink:"/next/concepts/glossary/V"}},i={},l=[{value:"Unbonding",id:"unbonding",level:2},{value:"URef",id:"uref",level:2},{value:"Users",id:"users",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"u",children:"U"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"unbonding",children:"Unbonding"}),"\n",(0,r.jsxs)(n.p,{children:["Withdrawing money from the ",(0,r.jsx)(n.a,{href:"/next/concepts/glossary/A#auction",children:"auction"})," contract with ",(0,r.jsx)(n.em,{children:"withdraw bid"})," and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed."]}),"\n",(0,r.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,r.jsxs)(n.p,{children:["An ",(0,r.jsx)(n.strong,{children:"U"}),"nforgeable ",(0,r.jsx)(n.strong,{children:"Ref"}),"erence, used by a Casper network to store any value other than ",(0,r.jsx)(n.code,{children:"Account"}),". More information can be found ",(0,r.jsx)(n.a,{href:"/next/concepts/design/casper-design#uref-head",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"users",children:"Users"}),"\n",(0,r.jsx)(n.p,{children:"Users execute session and contract code using the platform's computational resources."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var r=s(96540);const t={},c=r.createContext(t);function o(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65cd111b.64289a65.js b/assets/js/65cd111b.64289a65.js deleted file mode 100644 index e3f800a0f..000000000 --- a/assets/js/65cd111b.64289a65.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[910],{1879:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const c={},i="Testing Smart Contracts",o={id:"developers/writing-onchain-code/testing-contracts",title:"Testing Smart Contracts",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-contracts",permalink:"/developers/writing-onchain-code/testing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing a Basic Smart Contract in Rust",permalink:"/developers/writing-onchain-code/simple-contract"},next:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Defining Dependencies in <code>Cargo.toml</code>",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-smart-contracts",children:"Testing Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the Casper development environment, we provide a ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/",children:"testing framework"})," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework."})}),"\n",(0,s.jsxs)(t.h3,{id:"defining-dependencies-in-cargotoml",children:["Defining Dependencies in ",(0,s.jsx)(t.code,{children:"Cargo.toml"})]}),"\n",(0,s.jsxs)(t.p,{children:["This guide uses the project structure, and example contract outlined ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"})," for creating tests."]}),"\n",(0,s.jsxs)(t.p,{children:["To begin, outline the required test dependencies in the ",(0,s.jsx)(t.code,{children:"/tests/Cargo.toml"})," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'[dependencies]\ncasper-execution-engine = "5.0.0"\ncasper-engine-test-support = { version = "5.0.0", features = ["test-support"] }\ncasper-types = "3.0.0"\n'})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The tests for the contract usually reside in the ",(0,s.jsx)(t.code,{children:"tests"})," directory. Tests for the counter contract reside in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file. Notice that this file contains an empty ",(0,s.jsx)(t.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,s.jsx)(t.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.jsx)(t.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.jsx)(t.code,{children:"mod tests"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"importing-builders-and-constants",children:"Importing Builders and Constants"}),"\n",(0,s.jsxs)(t.p,{children:["Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/types_cl",children:"CLTypes"})," used within the contract code to be tested."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n PRODUCTION_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n"})}),"\n",(0,s.jsx)(t.p,{children:"Next, you need to define any global variables or constants for the test."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Contract Wasm File Paths (Constants)\n const COUNTER_V1_WASM: &str = "counter-v1.wasm";\n const COUNTER_V2_WASM: &str = "counter-v2.wasm";\n const COUNTER_V3_WASM: &str = "counter-v3.wasm";\n const COUNTER_CALL_WASM: &str = "counter-call.wasm";\n\n // Contract Storage Keys (Constants)\n const CONTRACT_KEY: &str = "counter";\n const COUNT_KEY: &str = "count";\n const LAST_UPDATED_KEY: &str = "last_updated";\n const CONTRACT_VERSION_KEY: &str = "version";\n\n // Contract Entry Points (Constants)\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement";\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\n const ENTRY_POINT_COUNTER_LAST_UPDATED_AT: &str = "counter_last_updated_at";\n'})}),"\n",(0,s.jsx)(t.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,s.jsxs)(t.p,{children:["Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.jsx)(t.code,{children:"InMemoryWasmTestBuilder"})," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."]}),"\n",(0,s.jsxs)(t.p,{children:["As part of this process, we use the ",(0,s.jsx)(t.code,{children:"PRODUCTION_RUN_GENESIS_REQUEST"})," to install the system contracts necessary for the tests, including the ",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"}),", and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"contracts, as well as establishing a default account and funding the associated purse."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n"})}),"\n",(0,s.jsx)(t.h4,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["Test functions use the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," established by our genesis builder as the account sending the Deploy."]}),"\n",(0,s.jsxs)(t.p,{children:["After building the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," (in this example, ",(0,s.jsx)(t.code,{children:"contract_installation_request"}),"), we process the request through ",(0,s.jsx)(t.code,{children:"builder.exec"})," and then add and process other requests as necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-by-hash",children:"Calling the Contract by Hash"}),"\n",(0,s.jsxs)(t.p,{children:["To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," function. The following code retrieves the contract hash from the named keys of the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that sent the installation Deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n'})}),"\n",(0,s.jsx)(t.p,{children:"Next, we test an entry point that should not exist in the first version of the contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-using-session-code",children:"Calling the Contract using Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["In the counter example, we use the session code included in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call.wasm"})," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"next section"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following session code uses the contract hash to identify the contract, the account for sending the deploy (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the deploy to be sent (",(0,s.jsx)(t.code,{children:"COUNTER_CALL_WASM"}),"), and the runtime arguments required. Once again, the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," simulates the execution of session code and calls the ",(0,s.jsx)(t.code,{children:"counter-inc"})," entry point."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsxs)(t.admonition,{type:"tip",children:[(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Testing Time-Sensitive Functions"})}),(0,s.jsx)(t.p,{children:"Normally, smart contracts operate on a blockchain where time advances in blocks. Testing functions that rely on time can be tricky."}),(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["Simulating Time with ",(0,s.jsx)(t.code,{children:"with_block_time"})]})}),(0,s.jsxs)(t.p,{children:["When building a request to call a contract function (using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),"), you can set a custom block time with ",(0,s.jsx)(t.code,{children:".with_block_time(desired_time)"}),". This pretends the function is called at that specific time."]}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n .with_block_time(5000)\n .build();\n"})}),(0,s.jsx)(t.p,{children:"This lets you test how your contract behaves at different points in time, all within your unit test."})]}),"\n",(0,s.jsx)(t.h4,{id:"evaluating-and-comparing-results",children:"Evaluating and Comparing Results"}),"\n",(0,s.jsxs)(t.p,{children:["After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.jsx)(t.code,{children:"builder"})," method retrieves the required information and converts it to the value type required. Then, ",(0,s.jsx)(t.code,{children:"assert_eq!()"})," compares the result against the expected value."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,s.jsxs)(t.p,{children:["For more test examples, visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,s.jsx)(t.h2,{id:"testing-contracts-that-call-contracts",children:"Testing Contracts that Call Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"}),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."]}),"\n",(0,s.jsxs)(t.p,{children:["Each contract installation will require an additional Wasm file installed through a ",(0,s.jsx)(t.code,{children:"Deploy"})," using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"return values"})," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."]}),"\n",(0,s.jsxs)(t.p,{children:["The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," - Calling a contract by its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_name"})," - Calling a contract referenced by a named key in the signer's Account context."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_hash"})," - Calling a specific contract version using its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_name"})," - Calling a specific version of a contract referenced by a named key in the signer's Account context."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, the counter example uses a ",(0,s.jsx)(t.code,{children:"Makefile"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Under the hood, the ",(0,s.jsx)(t.code,{children:"Makefile"})," generates a ",(0,s.jsx)(t.code,{children:"tests/wasm"})," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.jsx)(t.code,{children:"cargo test"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"test: build-contract\n\tmkdir -p tests/wasm\n\tcp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n\tcp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n\tcp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n\tcd tests && cargo test\n"})}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsxs)(t.p,{children:["The following brief video describes testing ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"sample contract code"}),"."]}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"further-testing",children:"Further Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"local network testing"})," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.jsx)(t.a,{href:"/developers/dapps/nctl-test",children:"testing in an other simulated network environment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You may also wish to test your contracts on the Casper ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Understand ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,s.jsxs)(t.li,{children:["Learn to ",(0,s.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var s=n(96540);const r={},c=s.createContext(r);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/65cd111b.9f4c0cef.js b/assets/js/65cd111b.9f4c0cef.js new file mode 100644 index 000000000..ce44b40e6 --- /dev/null +++ b/assets/js/65cd111b.9f4c0cef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[10910],{1879:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const c={},i="Testing Smart Contracts",o={id:"developers/writing-onchain-code/testing-contracts",title:"Testing Smart Contracts",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-contracts",permalink:"/1.5.X/developers/writing-onchain-code/testing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing a Basic Smart Contract in Rust",permalink:"/1.5.X/developers/writing-onchain-code/simple-contract"},next:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/1.5.X/developers/writing-onchain-code/upgrading-contracts"}},a={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Defining Dependencies in <code>Cargo.toml</code>",id:"defining-dependencies-in-cargotoml",level:3},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Builders and Constants",id:"importing-builders-and-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:4},{value:"Calling the Contract by Hash",id:"calling-the-contract-by-hash",level:4},{value:"Calling the Contract using Session Code",id:"calling-the-contract-using-session-code",level:4},{value:"Evaluating and Comparing Results",id:"evaluating-and-comparing-results",level:4},{value:"Testing Contracts that Call Contracts",id:"testing-contracts-that-call-contracts",level:2},{value:"Running the Tests",id:"running-the-tests",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"Further Testing",id:"further-testing",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-smart-contracts",children:"Testing Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the Casper development environment, we provide a ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-engine-test-support/latest/casper_engine_test_support/",children:"testing framework"})," to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework."})}),"\n",(0,s.jsxs)(t.h3,{id:"defining-dependencies-in-cargotoml",children:["Defining Dependencies in ",(0,s.jsx)(t.code,{children:"Cargo.toml"})]}),"\n",(0,s.jsxs)(t.p,{children:["This guide uses the project structure, and example contract outlined ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"})," for creating tests."]}),"\n",(0,s.jsxs)(t.p,{children:["To begin, outline the required test dependencies in the ",(0,s.jsx)(t.code,{children:"/tests/Cargo.toml"})," file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'[dependencies]\ncasper-execution-engine = "5.0.0"\ncasper-engine-test-support = { version = "5.0.0", features = ["test-support"] }\ncasper-types = "3.0.0"\n'})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The tests for the contract usually reside in the ",(0,s.jsx)(t.code,{children:"tests"})," directory. Tests for the counter contract reside in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file. Notice that this file contains an empty ",(0,s.jsx)(t.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,s.jsx)(t.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,s.jsx)(t.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,s.jsx)(t.code,{children:"mod tests"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"importing-builders-and-constants",children:"Importing Builders and Constants"}),"\n",(0,s.jsxs)(t.p,{children:["Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:"CLTypes"})," used within the contract code to be tested."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Outlining aspects of the Casper test support crate to include.\n use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n PRODUCTION_RUN_GENESIS_REQUEST,\n };\n // Custom Casper types that will be used within this test.\n use casper_types::{runtime_args, ContractHash, RuntimeArgs};\n"})}),"\n",(0,s.jsx)(t.p,{children:"Next, you need to define any global variables or constants for the test."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Contract Wasm File Paths (Constants)\n const COUNTER_V1_WASM: &str = "counter-v1.wasm";\n const COUNTER_V2_WASM: &str = "counter-v2.wasm";\n const COUNTER_V3_WASM: &str = "counter-v3.wasm";\n const COUNTER_CALL_WASM: &str = "counter-call.wasm";\n\n // Contract Storage Keys (Constants)\n const CONTRACT_KEY: &str = "counter";\n const COUNT_KEY: &str = "count";\n const LAST_UPDATED_KEY: &str = "last_updated";\n const CONTRACT_VERSION_KEY: &str = "version";\n\n // Contract Entry Points (Constants)\n const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement";\n const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\n const ENTRY_POINT_COUNTER_LAST_UPDATED_AT: &str = "counter_last_updated_at";\n'})}),"\n",(0,s.jsx)(t.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,s.jsxs)(t.p,{children:["Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the ",(0,s.jsx)(t.code,{children:"InMemoryWasmTestBuilder"})," to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain."]}),"\n",(0,s.jsxs)(t.p,{children:["As part of this process, we use the ",(0,s.jsx)(t.code,{children:"PRODUCTION_RUN_GENESIS_REQUEST"})," to install the system contracts necessary for the tests, including the ",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"}),", and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"contracts, as well as establishing a default account and funding the associated purse."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" #[test]\n /// Install version 1 of the counter contract and check its available entry points. ...\n fn install_version1_and_check_entry_points() {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST).commit();\n\n // See the repository for the full function.\n }\n"})}),"\n",(0,s.jsx)(t.h4,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["Test functions use the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," established by our genesis builder as the account sending the Deploy."]}),"\n",(0,s.jsxs)(t.p,{children:["After building the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," (in this example, ",(0,s.jsx)(t.code,{children:"contract_installation_request"}),"), we process the request through ",(0,s.jsx)(t.code,{children:"builder.exec"})," and then add and process other requests as necessary."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Install the contract.\n let contract_v1_installation_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_V1_WASM,\n runtime_args! {},\n )\n .build();\n\n builder\n .exec(contract_v1_installation_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-by-hash",children:"Calling the Contract by Hash"}),"\n",(0,s.jsxs)(t.p,{children:["To verify the installed contract, we need its contract hash. The test will then call its entry points using the ",(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," function. The following code retrieves the contract hash from the named keys of the ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that sent the installation Deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Check the contract hash.\n let contract_v1_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_KEY)\n .expect("must have contract hash key as part of contract creation")\n .into_hash()\n .map(ContractHash::new)\n .expect("must get contract hash");\n'})}),"\n",(0,s.jsx)(t.p,{children:"Next, we test an entry point that should not exist in the first version of the contract."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Call the decrement entry point, which should not be in version 1 before the upgrade.\n let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(\n *DEFAULT_ACCOUNT_ADDR,\n contract_v1_hash,\n ENTRY_POINT_COUNTER_DECREMENT,\n runtime_args! {},\n )\n .build();\n\n // Try executing the decrement entry point and expect an error.\n builder\n .exec(contract_decrement_request)\n .expect_failure()\n .commit();\n"})}),"\n",(0,s.jsx)(t.h4,{id:"calling-the-contract-using-session-code",children:"Calling the Contract using Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["In the counter example, we use the session code included in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call.wasm"})," file. For more details on what session code is and how it differs from contract code, see the ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"next section"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following session code uses the contract hash to identify the contract, the account for sending the deploy (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the deploy to be sent (",(0,s.jsx)(t.code,{children:"COUNTER_CALL_WASM"}),"), and the runtime arguments required. Once again, the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"})," simulates the execution of session code and calls the ",(0,s.jsx)(t.code,{children:"counter-inc"})," entry point."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,s.jsxs)(t.admonition,{type:"tip",children:[(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Testing Time-Sensitive Functions"})}),(0,s.jsx)(t.p,{children:"Normally, smart contracts operate on a blockchain where time advances in blocks. Testing functions that rely on time can be tricky."}),(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["Simulating Time with ",(0,s.jsx)(t.code,{children:"with_block_time"})]})}),(0,s.jsxs)(t.p,{children:["When building a request to call a contract function (using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),"), you can set a custom block time with ",(0,s.jsx)(t.code,{children:".with_block_time(desired_time)"}),". This pretends the function is called at that specific time."]}),(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:" let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n .with_block_time(5000)\n .build();\n"})}),(0,s.jsx)(t.p,{children:"This lets you test how your contract behaves at different points in time, all within your unit test."})]}),"\n",(0,s.jsx)(t.h4,{id:"evaluating-and-comparing-results",children:"Evaluating and Comparing Results"}),"\n",(0,s.jsxs)(t.p,{children:["After calling the contract, we should verify the results received to ensure the contract operated as intended. The ",(0,s.jsx)(t.code,{children:"builder"})," method retrieves the required information and converts it to the value type required. Then, ",(0,s.jsx)(t.code,{children:"assert_eq!()"})," compares the result against the expected value."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Verify the value of count is now 1.\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,s.jsxs)(t.p,{children:["For more test examples, visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,s.jsx)(t.h2,{id:"testing-contracts-that-call-contracts",children:"Testing Contracts that Call Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the ",(0,s.jsx)(t.code,{children:"DEFAULT_RUN_GENESIS_REQUEST"}),". The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include."]}),"\n",(0,s.jsxs)(t.p,{children:["Each contract installation will require an additional Wasm file installed through a ",(0,s.jsx)(t.code,{children:"Deploy"})," using ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Depending on your requirements as a smart contract author, you may need to use ",(0,s.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"return values"})," to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously."]}),"\n",(0,s.jsxs)(t.p,{children:["The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ",(0,s.jsx)(t.code,{children:"ExecuteRequestBuilder"}),". Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_hash"})," - Calling a contract by its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call_by_name"})," - Calling a contract referenced by a named key in the signer's Account context."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_hash"})," - Calling a specific contract version using its ",(0,s.jsx)(t.code,{children:"ContractHash"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"versioned_contract_call_by_name"})," - Calling a specific version of a contract referenced by a named key in the signer's Account context."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The calling contract must also provide an entry point and any necessary runtime arguments in all cases."}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, the counter example uses a ",(0,s.jsx)(t.code,{children:"Makefile"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Under the hood, the ",(0,s.jsx)(t.code,{children:"Makefile"})," generates a ",(0,s.jsx)(t.code,{children:"tests/wasm"})," folder, copies the Wasm files to the folder, and runs the tests using ",(0,s.jsx)(t.code,{children:"cargo test"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"test: build-contract\n\tmkdir -p tests/wasm\n\tcp contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm tests/wasm\n\tcp contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm tests/wasm\n\tcp counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm tests/wasm\n\tcd tests && cargo test\n"})}),"\n",(0,s.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,s.jsxs)(t.p,{children:["The following brief video describes testing ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"sample contract code"}),"."]}),"\n",(0,s.jsxs)(t.p,{align:"center",children:["\n",(0,s.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=7",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"further-testing",children:"Further Testing"}),"\n",(0,s.jsxs)(t.p,{children:["Unit testing is only one way to test contracts before installing them on a Casper network. After unit testing a contract, you may perform ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"local network testing"})," using NCTL. This allows you to set up and control multiple local Casper nodes to perform ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/dapps/nctl-test",children:"testing in an other simulated network environment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["You may also wish to test your contracts on the Casper ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Understand ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,s.jsxs)(t.li,{children:["Learn to ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var s=n(96540);const r={},c=s.createContext(r);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/680b7fa9.7fd0fcdc.js b/assets/js/680b7fa9.7fd0fcdc.js deleted file mode 100644 index 0bc5a89b8..000000000 --- a/assets/js/680b7fa9.7fd0fcdc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2446],{22210:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>n,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var t=r(74848),c=r(28453);const a={},n="Essential Rust Crates",i={id:"developers/essential-crates",title:"Essential Rust Crates",description:"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.",source:"@site/docs/developers/essential-crates.md",sourceDirName:"developers",slug:"/developers/essential-crates",permalink:"/next/developers/essential-crates",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Development Prerequisites",permalink:"/next/developers/prerequisites"},next:{title:"Introduction",permalink:"/next/writing-contracts"}},l={},d=[{value:"<code>casper-types</code>",id:"casper-types",level:2},{value:"<code>casper-contract</code>",id:"casper-contract",level:2},{value:"<code>casper-engine-test-support</code>",id:"casper-engine-test-support",level:2},{value:"<code>casper-node</code>",id:"casper-node",level:2},{value:"<code>casper-client</code>",id:"casper-client",level:2},{value:"<code>casper-event-standard</code>",id:"casper-event-standard",level:2},{value:"<code>casper-hashing</code>",id:"casper-hashing",level:2},{value:"<code>casper-wasm-utils</code>",id:"casper-wasm-utils",level:2},{value:"<code>cargo-casper</code>",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"essential-rust-crates",children:"Essential Rust Crates"})}),"\n",(0,t.jsxs)(s.p,{children:["Several Rust crates are available on ",(0,t.jsx)(s.a,{href:"https://crates.io/",children:"crates.io"})," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,t.jsx)(s.a,{href:"https://docs.rs",children:"docs.rs"}),". The most important crates are listed below."]}),"\n",(0,t.jsx)(s.h2,{id:"casper-types",children:(0,t.jsx)(s.code,{children:"casper-types"})}),"\n",(0,t.jsx)(s.p,{children:"Types shared by many Casper crates:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-types",children:"https://crates.io/crates/casper-types"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-types/latest",children:"https://docs.rs/casper-types/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-contract",children:(0,t.jsx)(s.code,{children:"casper-contract"})}),"\n",(0,t.jsx)(s.p,{children:"A library for developing Casper smart contracts:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-contract",children:"https://crates.io/crates/casper-contract"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-contract/latest",children:"https://docs.rs/casper-contract/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-engine-test-support",children:(0,t.jsx)(s.code,{children:"casper-engine-test-support"})}),"\n",(0,t.jsx)(s.p,{children:"The Casper test support library:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"https://crates.io/crates/casper-engine-test-support"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"https://docs.rs/casper-engine-test-support/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-node",children:(0,t.jsx)(s.code,{children:"casper-node"})}),"\n",(0,t.jsx)(s.p,{children:"The component for running a node on a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-node",children:"https://crates.io/crates/casper-node"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-node/latest",children:"https://docs.rs/casper-node/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-client",children:(0,t.jsx)(s.code,{children:"casper-client"})}),"\n",(0,t.jsx)(s.p,{children:"A client library for interacting with a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-client",children:"https://crates.io/crates/casper-client"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-client/latest",children:"https://docs.rs/casper-client/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-event-standard",children:(0,t.jsx)(s.code,{children:"casper-event-standard"})}),"\n",(0,t.jsx)(s.p,{children:"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-event-standard",children:"https://crates.io/crates/casper-event-standard"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-event-standard/latest",children:"https://docs.rs/casper-event-standard/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-hashing",children:(0,t.jsx)(s.code,{children:"casper-hashing"})}),"\n",(0,t.jsx)(s.p,{children:"A library providing hashing functionality including Merkle Proof utilities:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-hashing",children:"https://crates.io/crates/casper-hashing"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-hashing/latest/",children:"https://docs.rs/casper-hashing/latest/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-wasm-utils",children:(0,t.jsx)(s.code,{children:"casper-wasm-utils"})}),"\n",(0,t.jsx)(s.p,{children:"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-wasm-utils",children:"https://crates.io/crates/casper-wasm-utils"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-wasm-utils/latest",children:"https://docs.rs/casper-wasm-utils/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cargo-casper",children:(0,t.jsx)(s.code,{children:"cargo-casper"})}),"\n",(0,t.jsx)(s.p,{children:"A command line tool for creating a Wasm smart contract and tests:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/cargo-casper",children:"https://crates.io/crates/cargo-casper"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/crate/cargo-casper/latest",children:"https://docs.rs/crate/cargo-casper/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"other-libraries",children:"Other Libraries"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/next/resources/build-on-casper/casper-open-source-software",children:"Open-Source Software"})," page provides other community-curated tools and libraries."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>n,x:()=>i});var t=r(96540);const c={},a=t.createContext(c);function n(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/680b7fa9.83815de4.js b/assets/js/680b7fa9.83815de4.js new file mode 100644 index 000000000..c5f7fcd4d --- /dev/null +++ b/assets/js/680b7fa9.83815de4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32446],{22210:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>n,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var t=r(74848),c=r(28453);const a={},n="Essential Rust Crates",i={id:"developers/essential-crates",title:"Essential Rust Crates",description:"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.",source:"@site/docs/developers/essential-crates.md",sourceDirName:"developers",slug:"/developers/essential-crates",permalink:"/developers/essential-crates",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Development Prerequisites",permalink:"/developers/prerequisites"},next:{title:"Introduction",permalink:"/writing-contracts"}},l={},d=[{value:"<code>casper-types</code>",id:"casper-types",level:2},{value:"<code>casper-contract</code>",id:"casper-contract",level:2},{value:"<code>casper-engine-test-support</code>",id:"casper-engine-test-support",level:2},{value:"<code>casper-node</code>",id:"casper-node",level:2},{value:"<code>casper-client</code>",id:"casper-client",level:2},{value:"<code>casper-event-standard</code>",id:"casper-event-standard",level:2},{value:"<code>casper-hashing</code>",id:"casper-hashing",level:2},{value:"<code>casper-wasm-utils</code>",id:"casper-wasm-utils",level:2},{value:"<code>cargo-casper</code>",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"essential-rust-crates",children:"Essential Rust Crates"})}),"\n",(0,t.jsxs)(s.p,{children:["Several Rust crates are available on ",(0,t.jsx)(s.a,{href:"https://crates.io/",children:"crates.io"})," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,t.jsx)(s.a,{href:"https://docs.rs",children:"docs.rs"}),". The most important crates are listed below."]}),"\n",(0,t.jsx)(s.h2,{id:"casper-types",children:(0,t.jsx)(s.code,{children:"casper-types"})}),"\n",(0,t.jsx)(s.p,{children:"Types shared by many Casper crates:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-types",children:"https://crates.io/crates/casper-types"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-types/latest",children:"https://docs.rs/casper-types/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-contract",children:(0,t.jsx)(s.code,{children:"casper-contract"})}),"\n",(0,t.jsx)(s.p,{children:"A library for developing Casper smart contracts:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-contract",children:"https://crates.io/crates/casper-contract"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-contract/latest",children:"https://docs.rs/casper-contract/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-engine-test-support",children:(0,t.jsx)(s.code,{children:"casper-engine-test-support"})}),"\n",(0,t.jsx)(s.p,{children:"The Casper test support library:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"https://crates.io/crates/casper-engine-test-support"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"https://docs.rs/casper-engine-test-support/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-node",children:(0,t.jsx)(s.code,{children:"casper-node"})}),"\n",(0,t.jsx)(s.p,{children:"The component for running a node on a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-node",children:"https://crates.io/crates/casper-node"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-node/latest",children:"https://docs.rs/casper-node/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-client",children:(0,t.jsx)(s.code,{children:"casper-client"})}),"\n",(0,t.jsx)(s.p,{children:"A client library for interacting with a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-client",children:"https://crates.io/crates/casper-client"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-client/latest",children:"https://docs.rs/casper-client/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-event-standard",children:(0,t.jsx)(s.code,{children:"casper-event-standard"})}),"\n",(0,t.jsx)(s.p,{children:"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-event-standard",children:"https://crates.io/crates/casper-event-standard"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-event-standard/latest",children:"https://docs.rs/casper-event-standard/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-hashing",children:(0,t.jsx)(s.code,{children:"casper-hashing"})}),"\n",(0,t.jsx)(s.p,{children:"A library providing hashing functionality including Merkle Proof utilities:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-hashing",children:"https://crates.io/crates/casper-hashing"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-hashing/latest/",children:"https://docs.rs/casper-hashing/latest/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-wasm-utils",children:(0,t.jsx)(s.code,{children:"casper-wasm-utils"})}),"\n",(0,t.jsx)(s.p,{children:"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-wasm-utils",children:"https://crates.io/crates/casper-wasm-utils"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-wasm-utils/latest",children:"https://docs.rs/casper-wasm-utils/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cargo-casper",children:(0,t.jsx)(s.code,{children:"cargo-casper"})}),"\n",(0,t.jsx)(s.p,{children:"A command line tool for creating a Wasm smart contract and tests:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/cargo-casper",children:"https://crates.io/crates/cargo-casper"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/crate/cargo-casper/latest",children:"https://docs.rs/crate/cargo-casper/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"other-libraries",children:"Other Libraries"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Open-Source Software"})," page provides other community-curated tools and libraries."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>n,x:()=>i});var t=r(96540);const c={},a=t.createContext(c);function n(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/68730730.64e6198a.js b/assets/js/68730730.64e6198a.js new file mode 100644 index 000000000..1dc25f79a --- /dev/null +++ b/assets/js/68730730.64e6198a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8113],{85311:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(74848),s=r(28453);const i={title:"Hardware"},o="Recommended Hardware Specifications",a={id:"operators/setup/hardware",title:"Hardware",description:"System Requirements",source:"@site/versioned_docs/version-2.0.0/operators/setup/hardware.md",sourceDirName:"operators/setup",slug:"/operators/setup/hardware",permalink:"/2.0.0/operators/setup/hardware",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Hardware"},sidebar:"operators",previous:{title:"Setting up a Node",permalink:"/2.0.0/operators/setup/"},next:{title:"Configuration",permalink:"/2.0.0/operators/setup/basic-node-configuration"}},d={},c=[{value:"System Requirements",id:"system-requirements",level:2},{value:"CPU Requirements",id:"cpu-requirements",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"recommended-hardware-specifications",children:"Recommended Hardware Specifications"})}),"\n",(0,t.jsx)(n.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,t.jsxs)(n.p,{children:["The following hardware specifications are recommended for the Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"4 Cores"}),"\n",(0,t.jsx)(n.li,{children:"32 GB Ram"}),"\n",(0,t.jsx)(n.li,{children:"2 TB SSD or network SSD backed disk"}),"\n",(0,t.jsx)(n.li,{children:"Linux machine running Ubuntu 20.04"}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Notes",type:"note",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this."}),"\n"]}),"\n"]})}),"\n",(0,t.jsx)(n.h3,{id:"cpu-requirements",children:"CPU Requirements"}),"\n",(0,t.jsx)(n.p,{children:"Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions."}),"\n",(0,t.jsx)(n.p,{children:"To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question."})})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>a});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6875c492.b515c771.js b/assets/js/6875c492.b515c771.js deleted file mode 100644 index a6dee9564..000000000 --- a/assets/js/6875c492.b515c771.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4813],{47713:(e,t,n)=>{n.d(t,{A:()=>i});n(96540);var s=n(21312),a=n(39022),r=n(74848);function i(e){const{metadata:t}=e,{previousPage:n,nextPage:i}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,r.jsx)(a.A,{permalink:n,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,r.jsx)(a.A,{permalink:i,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,n)=>{n.d(t,{A:()=>B});n(96540);var s=n(34164),a=n(44096),r=n(74848);function i(e){let{children:t,className:n}=e;return(0,r.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:i}=(0,a.e7)(),{permalink:c,title:d}=n,u=i?"h1":"h2";return(0,r.jsx)(u,{className:(0,s.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=n(21312),u=n(53465),g=n(36266);const h={container:"container_mt6G"};function m(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,u.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,r.jsx)(r.Fragment,{children:n(t)})}function p(e){let{date:t,formattedDate:n}=e;return(0,r.jsx)("time",{dateTime:t,children:n})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:n}=(0,a.e7)(),{date:i,readingTime:l}=n,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,s.A)(h.container,"margin-vert--md",t),children:[(0,r.jsx)(p,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(m,{readingTime:l})]})]});var c}var f=n(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:n},assets:i}=(0,a.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,r.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,r.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,r.jsx)(f.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function T(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(j,{}),(0,r.jsx)(A,{})]})}var v=n(70440),N=n(88509);function w(e){let{children:t,className:n}=e;const{isBlogPostPage:i}=(0,a.e7)();return(0,r.jsx)("div",{id:i?v.LU:void 0,className:(0,s.A)("markdown",n),children:(0,r.jsx)(N.A,{children:t})})}var y=n(17559),P=n(4336),k=n(62053);function U(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function _(e){const{blogPostTitle:t,...n}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,r.jsx)(U,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,a.e7)(),{tags:n,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&o,g=n.length>0;if(!(g||u||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(k.A,{tags:n})})}),e&&(0,r.jsx)(P.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("col",{"col--9":u}),children:(0,r.jsx)(k.A,{tags:n})}),u&&(0,r.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,r.jsx)(_,{blogPostTitle:i,to:e.permalink})})]})}function B(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,a.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,s.A)(l,n),children:[(0,r.jsx)(T,{}),(0,r.jsx)(w,{children:t}),(0,r.jsx)(R,{})]})}},33892:(e,t,n)=>{n.d(t,{A:()=>i});n(96540);var s=n(44096),a=n(82907),r=n(74848);function i(e){let{items:t,component:n=a.A}=e;return(0,r.jsx)(r.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,r.jsx)(s.in,{content:t,children:(0,r.jsx)(n,{children:(0,r.jsx)(t,{})})},t.metadata.permalink)}))})}},33069:(e,t,n)=>{n.r(t),n.d(t,{default:()=>f});n(96540);var s=n(34164),a=n(21312),r=n(45500),i=n(17559),l=n(96461),o=n(28774),c=n(28027),d=n(47713),u=n(41463),g=n(33892),h=n(32234),m=n(51107),p=n(74848);function x(e){let{tag:t}=e;const n=(0,l.ZD)(t);return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(r.be,{title:n,description:t.description}),(0,p.jsx)(u.A,{tag:"blog_tags_posts"})]})}function j(e){let{tag:t,items:n,sidebar:s,listMetadata:r}=e;const i=(0,l.ZD)(t);return(0,p.jsxs)(c.A,{sidebar:s,children:[t.unlisted&&(0,p.jsx)(h.A,{}),(0,p.jsxs)("header",{className:"margin-bottom--xl",children:[(0,p.jsx)(m.A,{as:"h1",children:i}),t.description&&(0,p.jsx)("p",{children:t.description}),(0,p.jsx)(o.A,{href:t.allTagsPath,children:(0,p.jsx)(a.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,p.jsx)(g.A,{items:n}),(0,p.jsx)(d.A,{metadata:r})]})}function f(e){return(0,p.jsxs)(r.e3,{className:(0,s.A)(i.G.wrapper.blogPages,i.G.page.blogTagPostListPage),children:[(0,p.jsx)(x,{...e}),(0,p.jsx)(j,{...e})]})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,r.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(o,{...e})]})}},96461:(e,t,n)=>{n.d(t,{ZD:()=>l,np:()=>d,uz:()=>c,wI:()=>o});n(96540);var s=n(21312),a=n(53465),r=n(74848);function i(){const{selectMessage:e}=(0,a.W)();return t=>e(t,(0,s.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function l(e){const t=i();return(0,s.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function o(e){const t=i();return(0,s.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:t(e.count),authorName:e.name||e.key})}const c=()=>(0,s.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function d(){return(0,r.jsx)(s.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>i,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),r=n(74848);function i(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,r.jsx)(a.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/6875c492.b5181e60.js b/assets/js/6875c492.b5181e60.js new file mode 100644 index 000000000..60e97ea03 --- /dev/null +++ b/assets/js/6875c492.b5181e60.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84813],{47713:(e,t,n)=>{n.d(t,{A:()=>i});n(96540);var s=n(21312),a=n(39022),r=n(74848);function i(e){const{metadata:t}=e,{previousPage:n,nextPage:i}=t;return(0,r.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[n&&(0,r.jsx)(a.A,{permalink:n,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,r.jsx)(a.A,{permalink:i,title:(0,r.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,n)=>{n.d(t,{A:()=>B});n(96540);var s=n(34164),a=n(44096),r=n(74848);function i(e){let{children:t,className:n}=e;return(0,r.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:i}=(0,a.e7)(),{permalink:c,title:d}=n,u=i?"h1":"h2";return(0,r.jsx)(u,{className:(0,s.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=n(21312),u=n(53465),g=n(36266);const h={container:"container_mt6G"};function m(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,u.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,r.jsx)(r.Fragment,{children:n(t)})}function p(e){let{date:t,formattedDate:n}=e;return(0,r.jsx)("time",{dateTime:t,children:n})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:n}=(0,a.e7)(),{date:i,readingTime:l}=n,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,s.A)(h.container,"margin-vert--md",t),children:[(0,r.jsx)(p,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(m,{readingTime:l})]})]});var c}var f=n(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function A(e){let{className:t}=e;const{metadata:{authors:n},assets:i}=(0,a.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,r.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,r.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,r.jsx)(f.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function T(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(j,{}),(0,r.jsx)(A,{})]})}var v=n(70440),N=n(88509);function w(e){let{children:t,className:n}=e;const{isBlogPostPage:i}=(0,a.e7)();return(0,r.jsx)("div",{id:i?v.LU:void 0,className:(0,s.A)("markdown",n),children:(0,r.jsx)(N.A,{children:t})})}var y=n(17559),P=n(4336),k=n(62053);function U(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function _(e){const{blogPostTitle:t,...n}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,r.jsx)(U,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,a.e7)(),{tags:n,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,u=!t&&o,g=n.length>0;if(!(g||u||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(k.A,{tags:n})})}),e&&(0,r.jsx)(P.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,r.jsx)("div",{className:(0,s.A)("col",{"col--9":u}),children:(0,r.jsx)(k.A,{tags:n})}),u&&(0,r.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,r.jsx)(_,{blogPostTitle:i,to:e.permalink})})]})}function B(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,a.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,s.A)(l,n),children:[(0,r.jsx)(T,{}),(0,r.jsx)(w,{children:t}),(0,r.jsx)(R,{})]})}},33892:(e,t,n)=>{n.d(t,{A:()=>i});n(96540);var s=n(44096),a=n(82907),r=n(74848);function i(e){let{items:t,component:n=a.A}=e;return(0,r.jsx)(r.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,r.jsx)(s.in,{content:t,children:(0,r.jsx)(n,{children:(0,r.jsx)(t,{})})},t.metadata.permalink)}))})}},33069:(e,t,n)=>{n.r(t),n.d(t,{default:()=>f});n(96540);var s=n(34164),a=n(21312),r=n(45500),i=n(17559),l=n(96461),o=n(28774),c=n(28027),d=n(47713),u=n(41463),g=n(33892),h=n(32234),m=n(51107),p=n(74848);function x(e){let{tag:t}=e;const n=(0,l.ZD)(t);return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(r.be,{title:n,description:t.description}),(0,p.jsx)(u.A,{tag:"blog_tags_posts"})]})}function j(e){let{tag:t,items:n,sidebar:s,listMetadata:r}=e;const i=(0,l.ZD)(t);return(0,p.jsxs)(c.A,{sidebar:s,children:[t.unlisted&&(0,p.jsx)(h.A,{}),(0,p.jsxs)("header",{className:"margin-bottom--xl",children:[(0,p.jsx)(m.A,{as:"h1",children:i}),t.description&&(0,p.jsx)("p",{children:t.description}),(0,p.jsx)(o.A,{href:t.allTagsPath,children:(0,p.jsx)(a.A,{id:"theme.tags.tagsPageLink",description:"The label of the link targeting the tag list page",children:"View All Tags"})})]}),(0,p.jsx)(g.A,{items:n}),(0,p.jsx)(d.A,{metadata:r})]})}function f(e){return(0,p.jsxs)(r.e3,{className:(0,s.A)(i.G.wrapper.blogPages,i.G.page.blogTagPostListPage),children:[(0,p.jsx)(x,{...e}),(0,p.jsx)(j,{...e})]})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(a.Rc,{}),className:(0,s.A)(t,r.G.common.unlistedBanner),children:(0,l.jsx)(a.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(a.AE,{}),(0,l.jsx)(o,{...e})]})}},96461:(e,t,n)=>{n.d(t,{ZD:()=>l,np:()=>d,uz:()=>c,wI:()=>o});n(96540);var s=n(21312),a=n(53465),r=n(74848);function i(){const{selectMessage:e}=(0,a.W)();return t=>e(t,(0,s.T)({id:"theme.blog.post.plurals",description:'Pluralized label for "{count} posts". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One post|{count} posts"},{count:t}))}function l(e){const t=i();return(0,s.T)({id:"theme.blog.tagTitle",description:"The title of the page for a blog tag",message:'{nPosts} tagged with "{tagName}"'},{nPosts:t(e.count),tagName:e.label})}function o(e){const t=i();return(0,s.T)({id:"theme.blog.author.pageTitle",description:"The title of the page for a blog author",message:"{authorName} - {nPosts}"},{nPosts:t(e.count),authorName:e.name||e.key})}const c=()=>(0,s.T)({id:"theme.blog.authorsList.pageTitle",message:"Authors",description:"The title of the authors page"});function d(){return(0,r.jsx)(s.A,{id:"theme.blog.authorsList.viewAll",description:"The label of the link targeting the blog authors page",children:"View all authors"})}},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>i,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var s=n(21312),a=n(5260),r=n(74848);function i(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,r.jsx)(a.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,r.jsx)(s.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/68ccb7f6.108271e9.js b/assets/js/68ccb7f6.108271e9.js deleted file mode 100644 index b67707a21..000000000 --- a/assets/js/68ccb7f6.108271e9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6474],{88599:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var t=s(74848),i=s(28453);const r={title:"Open Files Limit"},o="Setting the Open Files Limit",l={id:"operators/setup/open-files",title:"Open Files Limit",description:"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.",source:"@site/docs/operators/setup/open-files.md",sourceDirName:"operators/setup",slug:"/operators/setup/open-files",permalink:"/next/operators/setup/open-files",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Open Files Limit"},sidebar:"operators",previous:{title:"Fast Sync",permalink:"/next/operators/setup/fast-sync"},next:{title:"Upgrades",permalink:"/next/operators/setup/upgrade"}},c={},a=[{value:"Setting the Limit Manually",id:"updating-manually",level:2},{value:"Updating the <code>limits.conf</code> File",id:"updating-limits-conf",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",summary:"summary",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-the-open-files-limit",children:"Setting the Open Files Limit"})}),"\n",(0,t.jsxs)(n.p,{children:["When the ",(0,t.jsx)(n.code,{children:"casper-node"})," launches, it tries to set the maximum open files limit (",(0,t.jsx)(n.code,{children:"nofile"}),") for the process to ",(0,t.jsx)(n.code,{children:"64000"}),". With some systems, this limit will be larger than the default hard limit of ",(0,t.jsx)(n.code,{children:"4096"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,t.jsx)(n.code,{children:"nofile"})," limit needs to be increased."]}),"\n",(0,t.jsxs)(n.p,{children:["With the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"})," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,t.jsx)(n.code,{children:"casper-node"})," with the following command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'pgrep "casper-node$"\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'$ pgrep "casper-node$"\n275928\n'})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,t.jsx)(n.code,{children:"275928"})," each time."]})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you do not get a value in return, you do not have the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"})," running correctly."]}),"\n",(0,t.jsxs)(n.p,{children:["To find the current ",(0,t.jsx)(n.code,{children:"nofile"})," (number of open files) hard limit, run ",(0,t.jsx)(n.code,{children:"prlimit"})," with the PID from the previous command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo prlimit -n -p <PID>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can also embed both commands as shown here:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["If you receive ",(0,t.jsx)(n.code,{children:"prlimit: option requires an argument -- 'p'"}),", then ",(0,t.jsx)(n.code,{children:'pgrep "casper-node$"'})," is not returning anything because the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"})," is no longer running."]}),"\n",(0,t.jsx)(n.h2,{id:"updating-manually",children:"Setting the Limit Manually"}),"\n",(0,t.jsxs)(n.p,{children:["Run the command below to set the ",(0,t.jsx)(n.code,{children:"nofile"})," limit for an active process without restarting the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"})," and ",(0,t.jsx)(n.code,{children:"casper-node"})," processes. Note that this setting is active only while the ",(0,t.jsx)(n.code,{children:"casper-node"})," process runs. To make this setting permanent, ",(0,t.jsxs)(n.a,{href:"#updating-limits-conf",children:["update the ",(0,t.jsx)(n.code,{children:"limits.conf"})]})," file instead."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, check that the ",(0,t.jsx)(n.code,{children:"prlimit"})," has changed:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.h2,{id:"updating-limits-conf",children:["Updating the ",(0,t.jsx)(n.code,{children:"limits.conf"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["It is possible to persist the ",(0,t.jsx)(n.code,{children:"nofile"})," limit across server reboots, ",(0,t.jsx)(n.code,{children:"casper-node-launcher"})," restarts, and protocol upgrades, by adding the ",(0,t.jsx)(n.code,{children:"nofile"})," setting for the ",(0,t.jsx)(n.code,{children:"casper"})," user in ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Add the following row to the bottom of the ",(0,t.jsx)(n.code,{children:"/etc/security/limits.conf"})," file:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper hard nofile 64000\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,t.jsx)(n.code,{children:"nofile"})," setting."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/68ccb7f6.22bc5312.js b/assets/js/68ccb7f6.22bc5312.js new file mode 100644 index 000000000..33e43ff15 --- /dev/null +++ b/assets/js/68ccb7f6.22bc5312.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[56474],{88599:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var i=s(74848),t=s(28453);const r={title:"Open Files Limit"},o="Setting the Open Files Limit",l={id:"operators/setup/open-files",title:"Open Files Limit",description:"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.",source:"@site/docs/operators/setup/open-files.md",sourceDirName:"operators/setup",slug:"/operators/setup/open-files",permalink:"/operators/setup/open-files",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Open Files Limit"},sidebar:"operators",previous:{title:"Fast Sync",permalink:"/operators/setup/fast-sync"},next:{title:"Upgrades",permalink:"/operators/setup/upgrade"}},c={},a=[{value:"Setting the Limit Manually",id:"updating-manually",level:2},{value:"Updating the <code>limits.conf</code> File",id:"updating-limits-conf",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",summary:"summary",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"setting-the-open-files-limit",children:"Setting the Open Files Limit"})}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node"})," launches, it tries to set the maximum open files limit (",(0,i.jsx)(n.code,{children:"nofile"}),") for the process to ",(0,i.jsx)(n.code,{children:"64000"}),". With some systems, this limit will be larger than the default hard limit of ",(0,i.jsx)(n.code,{children:"4096"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.jsx)(n.code,{children:"nofile"})," limit needs to be increased."]}),"\n",(0,i.jsxs)(n.p,{children:["With the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.jsx)(n.code,{children:"casper-node"})," with the following command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'pgrep "casper-node$"\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ pgrep "casper-node$"\n275928\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.jsx)(n.code,{children:"275928"})," each time."]})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you do not get a value in return, you do not have the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running correctly."]}),"\n",(0,i.jsxs)(n.p,{children:["To find the current ",(0,i.jsx)(n.code,{children:"nofile"})," (number of open files) hard limit, run ",(0,i.jsx)(n.code,{children:"prlimit"})," with the PID from the previous command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo prlimit -n -p <PID>\n"})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can also embed both commands as shown here:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive ",(0,i.jsx)(n.code,{children:"prlimit: option requires an argument -- 'p'"}),", then ",(0,i.jsx)(n.code,{children:'pgrep "casper-node$"'})," is not returning anything because the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is no longer running."]}),"\n",(0,i.jsx)(n.h2,{id:"updating-manually",children:"Setting the Limit Manually"}),"\n",(0,i.jsxs)(n.p,{children:["Run the command below to set the ",(0,i.jsx)(n.code,{children:"nofile"})," limit for an active process without restarting the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," and ",(0,i.jsx)(n.code,{children:"casper-node"})," processes. Note that this setting is active only while the ",(0,i.jsx)(n.code,{children:"casper-node"})," process runs. To make this setting permanent, ",(0,i.jsxs)(n.a,{href:"#updating-limits-conf",children:["update the ",(0,i.jsx)(n.code,{children:"limits.conf"})]})," file instead."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Next, check that the ",(0,i.jsx)(n.code,{children:"prlimit"})," has changed:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"updating-limits-conf",children:["Updating the ",(0,i.jsx)(n.code,{children:"limits.conf"})," File"]}),"\n",(0,i.jsxs)(n.p,{children:["It is possible to persist the ",(0,i.jsx)(n.code,{children:"nofile"})," limit across server reboots, ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," restarts, and protocol upgrades, by adding the ",(0,i.jsx)(n.code,{children:"nofile"})," setting for the ",(0,i.jsx)(n.code,{children:"casper"})," user in ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Add the following row to the bottom of the ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper hard nofile 64000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.jsx)(n.code,{children:"nofile"})," setting."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6a307077.51e38375.js b/assets/js/6a307077.51e38375.js deleted file mode 100644 index b1004959e..000000000 --- a/assets/js/6a307077.51e38375.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4110],{88261:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var i=s(74848),r=s(28453);const l={},d="CLType",c={id:"developers/json-rpc/types_cl",title:"CLType",description:"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.",source:"@site/docs/developers/json-rpc/types_cl.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_cl",permalink:"/next/developers/json-rpc/types_cl",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Types",permalink:"/next/developers/json-rpc/types_chain"},next:{title:"Overview of Casper dApps",permalink:"/next/developers/dapps/"}},t={},o=[{value:"CLValue",id:"clvalue",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cltype",children:"CLType"})}),"\n",(0,i.jsxs)(n.p,{children:["Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a ",(0,i.jsx)(n.a,{href:"#clvalue",children:(0,i.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Bool"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U8"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U128"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U256"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U512"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unit"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"String"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Key"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"URef"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"PublicKey"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Option"})," Option of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"List"})," Variable-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a ",(0,i.jsx)(n.code,{children:"Vec"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ByteArray"})," Fixed-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a Rust array)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Result"})," ",(0,i.jsx)(n.code,{children:"Result"})," with ",(0,i.jsx)(n.code,{children:"Ok"})," and ",(0,i.jsx)(n.code,{children:"Err"})," variants of ",(0,i.jsx)(n.code,{children:"CLType"}),"'s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Map"})," Map with keys of a single ",(0,i.jsx)(n.code,{children:"CLType"})," and values of a single ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple1"})," 1-ary tuple of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple2"})," 2-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple3"})," 3-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Any"})," Unspecified type"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"clvalue",children:"CLValue"}),"\n",(0,i.jsxs)(n.p,{children:["A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized ",(0,i.jsx)(n.code,{children:"Vec<u8>"})," and also holds the CLType of the underlying data as a separate member. The ",(0,i.jsx)(n.code,{children:"parsed"})," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bytes"})," A Casper serialized representation of the underlying value. For more information, reference the ",(0,i.jsx)(n.a,{href:"/next/concepts/serialization/",children:"Serialization Standard"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#cltype",children:(0,i.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var i=s(96540);const r={},l=i.createContext(r);function d(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6a307077.880239fa.js b/assets/js/6a307077.880239fa.js new file mode 100644 index 000000000..191fc8405 --- /dev/null +++ b/assets/js/6a307077.880239fa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84110],{88261:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var i=s(74848),r=s(28453);const l={},d="CLType",c={id:"developers/json-rpc/types_cl",title:"CLType",description:"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.",source:"@site/docs/developers/json-rpc/types_cl.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_cl",permalink:"/developers/json-rpc/types_cl",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Types",permalink:"/developers/json-rpc/types_chain"},next:{title:"Overview of Casper dApps",permalink:"/developers/dapps/"}},t={},o=[{value:"CLValue",id:"clvalue",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cltype",children:"CLType"})}),"\n",(0,i.jsxs)(n.p,{children:["Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a ",(0,i.jsx)(n.a,{href:"#clvalue",children:(0,i.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Bool"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U8"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U128"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U256"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U512"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unit"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"String"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Key"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"URef"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"PublicKey"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Option"})," Option of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"List"})," Variable-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a ",(0,i.jsx)(n.code,{children:"Vec"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ByteArray"})," Fixed-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a Rust array)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Result"})," ",(0,i.jsx)(n.code,{children:"Result"})," with ",(0,i.jsx)(n.code,{children:"Ok"})," and ",(0,i.jsx)(n.code,{children:"Err"})," variants of ",(0,i.jsx)(n.code,{children:"CLType"}),"'s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Map"})," Map with keys of a single ",(0,i.jsx)(n.code,{children:"CLType"})," and values of a single ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple1"})," 1-ary tuple of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple2"})," 2-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple3"})," 3-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Any"})," Unspecified type"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"clvalue",children:"CLValue"}),"\n",(0,i.jsxs)(n.p,{children:["A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized ",(0,i.jsx)(n.code,{children:"Vec<u8>"})," and also holds the CLType of the underlying data as a separate member. The ",(0,i.jsx)(n.code,{children:"parsed"})," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bytes"})," A Casper serialized representation of the underlying value. For more information, reference the ",(0,i.jsx)(n.a,{href:"/concepts/serialization/",children:"Serialization Standard"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#cltype",children:(0,i.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var i=s(96540);const r={},l=i.createContext(r);function d(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6bed00f2.4b14e37a.js b/assets/js/6bed00f2.4b14e37a.js new file mode 100644 index 000000000..2b886c712 --- /dev/null +++ b/assets/js/6bed00f2.4b14e37a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37832],{59694:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>l,contentTitle:()=>i,default:()=>c,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var n=s(74848),a=s(28453);const t={title:"Zug Consensus"},i="Simple and Fast Consensus with Zug",r={id:"concepts/design/zug",title:"Zug Consensus",description:"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.",source:"@site/versioned_docs/version-2.0.0/concepts/design/zug.md",sourceDirName:"concepts/design",slug:"/concepts/design/zug",permalink:"/2.0.0/concepts/design/zug",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Zug Consensus"},sidebar:"concepts",previous:{title:"Consensus in a Casper Network",permalink:"/2.0.0/concepts/design/consensus"},next:{title:"Highway Consensus",permalink:"/2.0.0/concepts/design/highway"}},l={},d=[{value:"How Zug Works",id:"how-zug-works",level:2},{value:"Some Advantages of Zug",id:"some-advantages-of-zug",level:2},{value:"Comparison with Highway",id:"comparison-with-highway",level:2},{value:"Block Rewards",id:"block-rewards",level:3},{value:"Read the Paper",id:"read-the-paper",level:2}];function h(e){const o={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"simple-and-fast-consensus-with-zug",children:"Simple and Fast Consensus with Zug"})}),"\n",(0,n.jsxs)(o.p,{children:["The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"a much simpler consensus protocol"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The Zug protocol requires that at most one-third of the validator weight could be attributed to faulty validators. It also assumes that there exists an upper bound for the network delay, which is the duration for a correct validator to deliver a message. The value of the upper bound may be unknown, but it exists. Under these conditions, all correct nodes will reach agreement on a chain of finalized blocks."}),"\n",(0,n.jsxs)(o.p,{children:["Of course, all nodes in a network have to run the same protocol to work together, but when starting a new network or upgrading an existing one, either ",(0,n.jsx)(o.code,{children:"Highway"})," or ",(0,n.jsx)(o.code,{children:"Zug"})," can now be selected as the ",(0,n.jsx)(o.code,{children:"consensus_protocol"})," in the chainspec file. The Casper Mainnet will switch to Zug."]}),"\n",(0,n.jsx)(o.h2,{id:"how-zug-works",children:"How Zug Works"}),"\n",(0,n.jsxs)(o.p,{children:["In every round, the designated leader can sign a ",(0,n.jsx)(o.strong,{children:"proposal message"})," to suggest a block. The proposal also points to an earlier round in which the parent block was proposed."]}),"\n",(0,n.jsxs)(o.p,{children:["Each validator then signs an ",(0,n.jsx)(o.strong,{children:"echo message"})," with the proposal's hash. Correct validators only sign one echo per round, so at most one proposal can get echo messages signed by a quorum. A ",(0,n.jsx)(o.strong,{children:"quorum"})," is a set of validators whose total weight is greater than ",(0,n.jsx)(o.code,{children:"(n + f) / 2"}),", where ",(0,n.jsx)(o.code,{children:"n"})," is the total weight of all validators and ",(0,n.jsx)(o.code,{children:"f"})," is the maximum allowed total weight of faulty validators. Thus, any two quorums always have a correct validator in common. As long as ",(0,n.jsx)(o.code,{children:"n > 3f"}),", the correct validators will constitute a quorum since ",(0,n.jsx)(o.code,{children:"(n + f) / 2 < n - f"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The proposal is accepted if there is a quorum and some other conditions are met (see below). Now, the next round's leader can make a new proposal that uses this proposal as a parent."}),"\n",(0,n.jsxs)(o.p,{children:["Each validator observing the proposal in time signs a ",(0,n.jsx)(o.code,{children:"Vote(true)"})," message. If validators time out while waiting, they sign ",(0,n.jsx)(o.code,{children:"Vote(false)"})," message instead. If a quorum signs ",(0,n.jsx)(o.em,{children:"true"}),", the round is committed and the proposal and all its ancestors are finalized. If a quorum signs ",(0,n.jsx)(o.em,{children:"false"}),", the round is ",(0,n.jsx)(o.strong,{children:"skippable"}),", meaning that the next round's leader can propose a block with a parent from an earlier round. Correct validators only sign either ",(0,n.jsx)(o.em,{children:"true"})," or ",(0,n.jsx)(o.em,{children:"false"}),", so a round can be either committed or skippable, but not both."]}),"\n",(0,n.jsxs)(o.p,{children:["If there is no accepted proposal, all correct validators will eventually vote ",(0,n.jsx)(o.em,{children:"false"}),", so the round becomes skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"live"}),". The next leader will eventually be allowed to make a proposal because either there is an accepted proposal that can be the parent, or the round will eventually be skippable, and an earlier round's proposal can be used as a parent. If the timeout is long enough, the correct proposers' blocks will usually get finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["For a proposal to be accepted, the parent proposal must also be accepted, and all rounds between the parent and the current round must be skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"safe"}),". If two rounds are committed, their proposals must be ancestors of each other because they are not skippable. Thus, the protocol cannot finalize two conflicting blocks."]}),"\n",(0,n.jsx)(o.p,{children:"Of course, there is also a first block. Whenever all earlier rounds are skippable (particularly the first round), the leader may propose a block with no parent."}),"\n",(0,n.jsxs)(o.p,{children:["Every new signed message is optimistically sent directly to all peers. We want to guarantee that it is eventually seen by all validators, even if they are not fully connected. This is achieved via a pull-based randomized gossip mechanism, where a ",(0,n.jsx)(o.code,{children:"SyncRequest"})," message containing information about a random part of the local protocol state is periodically sent to a random peer. The peer compares that to its local state and responds with all the signed messages that it has recorded."]}),"\n",(0,n.jsxs)(o.admonition,{type:"important",children:[(0,n.jsx)(o.p,{children:"The Zug protocol can be summarized as follows:"}),(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["In every round, the round leader proposes a new block, ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator creates and broadcasts an ",(0,n.jsx)(o.em,{children:"echo"})," message, with a signature of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["When a suitable block ",(0,n.jsx)(o.code,{children:"B"})," has received echoes from 67% of the validators:\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["The next round begins. The next leader can propose a child of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator signs and broadcasts a ",(0,n.jsx)(o.em,{children:"vote"})," message, voting ",(0,n.jsx)(o.code,{children:"yes"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If this does not happen before a timeout, the validators vote ",(0,n.jsx)(o.code,{children:"no"})," instead.\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"no"})," votes from 67%, the next round begins, too.\nThe next leader can propose a child from an earlier block and skip this round."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"yes"})," votes from 67%, ",(0,n.jsx)(o.code,{children:"B"})," is finalized and gets executed, together with all its ancestors. (Usually, the next round has already started at this point.)"]}),"\n"]})]}),"\n",(0,n.jsxs)(o.p,{children:["Notice that proposals, votes, and echoes are broadcast, so if one correct node receives a message, all nodes will eventually receive it. An honest validator sends only one echo or vote per round. So, unless 34% of validators double-sign, at most one block per round gets 67% echoes, and no finalized block can ever be skipped, ensuring safety. As long as there are 67% of echoes for a proposal, the next round begins and Zug doesn't get stuck. If there are not, everyone votes ",(0,n.jsx)(o.code,{children:"no"}),", and the next round also begins."]}),"\n",(0,n.jsxs)(o.details,{children:["\n",(0,n.jsx)(o.summary,{children:(0,n.jsx)(o.b,{children:"Expand to see a simple example"})}),"\n",(0,n.jsx)(o.p,{children:"Let's review a simple scenario demonstrating the Zug consensus. The example shows five rounds with a different leader and nodes voting on a card suit. The bottom row indicates whether or not the round was finalized. Notice that round 5 was the first finalized round."}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.img,{alt:"ZUG",src:s(17210).A+"",width:"1284",height:"528"})}),"\n",(0,n.jsxs)(o.p,{children:["In round 1, we had a leader who proposed ",(0,n.jsx)(o.code,{children:"\u2665"}),", but was slow, so the other nodes timed out and voted ",(0,n.jsx)(o.code,{children:"no."})," The first round had a proposal and was skippable, but nothing was finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 2, the second proposer saw ",(0,n.jsx)(o.code,{children:"\u2665"})," and proposed ",(0,n.jsx)(o.code,{children:"\u2663"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2665"}),". Some nodes voted ",(0,n.jsx)(o.code,{children:"yes"}),", and some timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),". So, round 2 will never output anything because there wasn't a decision."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 3, the leader proposed ",(0,n.jsx)(o.code,{children:"\u2666"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". Assuming the leader was still too slow, everyone voted ",(0,n.jsx)(o.code,{children:"no"}),", and round 3 became skippable even though it had a proposal."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 4, the proposer might have crashed or been malicious, so everyone timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 5, the leader didn't see the ",(0,n.jsx)(o.code,{children:"\u2666"})," proposal from round 3 but saw the ",(0,n.jsx)(o.code,{children:"no"})," decision. So, from their perspective, rounds 3 and 4 were skippable and had no proposals. Thus, the leader in round 5 proposed ",(0,n.jsx)(o.code,{children:"\u2660"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". ",(0,n.jsx)(o.strong,{children:"Notice that the algorithm encountered a fork"}),". Regardless, everyone voted ",(0,n.jsx)(o.code,{children:"yes"}),", and round 5 was finalized. I.e., at that moment, ",(0,n.jsx)(o.code,{children:"\u2665"}),", ",(0,n.jsx)(o.code,{children:"\u2663"}),", and ",(0,n.jsx)(o.code,{children:"\u2660"})," all become finalized and executed in that order. As a result, every future proposer needs to propose children of this round."]}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.strong,{children:"Important Notes:"})}),"\n",(0,n.jsxs)(o.p,{children:["Even proposals from rounds with a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes can become finalized indirectly."]}),"\n",(0,n.jsxs)(o.p,{children:["If a round is neither finalized nor skippable, the round will likely be finalized at some point in the future. When one-third of the network's weight votes ",(0,n.jsx)(o.code,{children:"yes"}),", a proposal with a quorum of echoes is formed. Consequently, all other honest nodes will eventually see this quorum of echoes and the accepted proposal, which will serve as a parent in future rounds."]}),"\n",(0,n.jsxs)(o.p,{children:["Nodes vote ",(0,n.jsx)(o.code,{children:"yes"})," when they have a quorum of echoes, and all the ancestors of that proposal have a quorum of echoes. Also, those ancestors have a quorum of echoes, and the rounds with no ancestors all have a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes (being skippable)."]}),"\n",(0,n.jsxs)(o.p,{children:["The algorithm will always produce a result in at least one of the ",(0,n.jsx)(o.code,{children:"Accepted proposal"})," or ",(0,n.jsx)(o.code,{children:"Finalized round"})," rows. If a proposal doesn't get accepted in a round, everyone times out and votes ",(0,n.jsx)(o.code,{children:"no"}),". Otherwise, a proposal is visible to someone with a quorum of votes and will eventually be visible to everyone."]}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"some-advantages-of-zug",children:"Some Advantages of Zug"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"Apart from the leader, who has to send the proposed block, each validator node broadcasts only two tiny messages in each round, making the communication overhead very small."}),"\n",(0,n.jsx)(o.li,{children:"Unlike in Highway and Practical Byzantine Fault Tolerance (PBFT), and similar to pipelined protocols like HotStuff, only one round of messages (the echoes) is needed for the next leader to propose a block, reducing the delay between a block and its child."}),"\n",(0,n.jsxs)(o.li,{children:["But ",(0,n.jsx)(o.em,{children:"unlike"})," HotStuff, Zug can finalize a block without waiting for its child or grandchild. And, unlike Highway, it does so without waiting for any timeout. Even if a network is configured to produce only one block per minute, every block gets finalized within seconds, as fast as the network connections allow."]}),"\n",(0,n.jsx)(o.li,{children:"Zug's technical description is more flexible than Highway's, giving us a family of related, correct implementations from which to choose."}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"comparison-with-highway",children:"Comparison with Highway"}),"\n",(0,n.jsxs)(o.p,{children:["Unlike Highway, Zug does not use a communication history DAG. Highway sends larger messages due to citing and is slower. Zug does not have any notion of citing units, as does Highway, and relies on exchanging signed messages. On the other hand, Highway allows for more fine-grained ",(0,n.jsx)(o.a,{href:"#block-rewards",children:"block rewards"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["With Zug, finality happens after nodes constituting two-thirds of the network's total weight vote ",(0,n.jsx)(o.code,{children:"true"})," for a round in which the block was proposed or a later round that has this one as an ancestor. Highways' criterion for detecting finality is the presence of a pattern of messages called a ",(0,n.jsx)(o.code,{children:"Summit."})," Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time. Both ways of detecting finality are improvements over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect."]}),"\n",(0,n.jsx)(o.p,{children:"Highway and Zug offer flexibility in terms of fault tolerance thresholds. Highway allows different clients to follow the protocol with varying thresholds, each with its own balance between security and latency. However, if a sufficient number of validators are online, Zug demonstrates lower latency than Highway at any threshold. This is because Zug does not have predefined, rigid values for the round length, and its design allows the network to adapt to actual delays. If delays occur, block times may vary. Otherwise, blocks should appear as soon as they are finalized. Highway has a defined minimum round length, and the round lengths have to be powers of two times that minimum. Zug has a defined minimum round length, but a round can finish anytime as soon as enough messages are successfully exchanged. So, with Zug, there is no need to wait for a power of two times the minimum if the actual time falls somewhere between."}),"\n",(0,n.jsx)(o.p,{children:"Highway is a much more complicated protocol than Zug. Implementing it takes more than twice as many lines of code. Also, Highway's proof of correctness has proved more difficult to verify than Zug's. Zug will make it easier for third parties to create compatible node software that works with the Casper node."}),"\n",(0,n.jsx)(o.p,{children:"Using Zug consensus and smaller messages, the network could scale to a larger number of validators."}),"\n",(0,n.jsx)(o.h3,{id:"block-rewards",children:"Block Rewards"}),"\n",(0,n.jsx)(o.p,{children:"Using a DAG in Highway makes fine-grained information about the validators' behavior available temporarily in the protocol state, so block rewards can be tuned to incentivize full participation in the consensus protocol. However, this does not apply at the end of each era. Any message sent after the era's last block was proposed cannot be taken into account, even though these messages are still needed to finalize that block. And this granularity comes at a cost: Highway messages are relatively big."}),"\n",(0,n.jsx)(o.p,{children:"The current system does not reward finality signatures, which are arguably the most important outcome. The signatures are the user-visible proof, signed by the validators, that an executed block is correct."}),"\n",(0,n.jsx)(o.p,{children:"In Zug, messages are much smaller, so a smaller incentive is needed to send them."}),"\n",(0,n.jsx)(o.p,{children:"Casper 2.0.0 will distribute a configurable fraction of the seigniorage as a reward for finality signatures and the rest as a simple reward for each block, both proportionally to the validators' stakes."}),"\n",(0,n.jsx)(o.p,{children:"This new reward system is simpler, fairer, predictable, and transparent. It will give equal weight to all blocks (including at the end of an era), but it will not take into account every single consensus message."}),"\n",(0,n.jsx)(o.h2,{id:"read-the-paper",children:"Read the Paper"}),"\n",(0,n.jsxs)(o.p,{children:["Here, we describe Zug, an implementation of the ideas from our paper ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),". The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the ",(0,n.jsx)(o.em,{children:"echo"})," messages are used by our Reliable Broadcast implementation, and the ",(0,n.jsx)(o.em,{children:"vote"})," messages are used by our Weakly-terminating Binary Agreement implementation."]})]})}function c(e={}){const{wrapper:o}={...(0,a.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},17210:(e,o,s)=>{s.d(o,{A:()=>n});const n=s.p+"assets/images/zug-example-5515691ed63d9f310e573eb5742c1701.png"},28453:(e,o,s)=>{s.d(o,{R:()=>i,x:()=>r});var n=s(96540);const a={},t=n.createContext(a);function i(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c606038.42035320.js b/assets/js/6c606038.42035320.js deleted file mode 100644 index 631c25ba9..000000000 --- a/assets/js/6c606038.42035320.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8471],{87251:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var t=n(74848),c=n(28453);const r={},a="A",o={id:"concepts/glossary/A",title:"A",description:"---",source:"@site/docs/concepts/glossary/A.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/A",permalink:"/next/concepts/glossary/A",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Glossary",permalink:"/next/glossary"},next:{title:"B",permalink:"/next/concepts/glossary/B"}},i={},l=[{value:"Account",id:"account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Addressable Entity",id:"addressable-entity",level:2},{value:"AssemblyScript",id:"assemblyscript",level:2},{value:"Auction",id:"auction",level:2},{value:"Auction contract",id:"auction-contract",level:2},{value:"Auction delay",id:"auction-delay",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"a",children:"A"})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.h2,{id:"account",children:"Account"}),"\n",(0,t.jsxs)(s.p,{children:["An Account is a structure that represents a user on a Casper network. Information on creating an account can be found ",(0,t.jsx)(s.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"here"}),". Casper's Condor release introduces the concept of an ",(0,t.jsx)(s.a,{href:"#addressable-entity",children:"addressable entity"}),", which contains an account entity type that supersedes legacy accounts."]}),"\n",(0,t.jsx)(s.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,t.jsxs)(s.p,{children:["The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found ",(0,t.jsx)(s.a,{href:"https://support.casperlabs.io/hc/en-gb/articles/13781616975131-How-do-I-generate-an-account-hash-",children:"here"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"addressable-entity",children:"Addressable Entity"}),"\n",(0,t.jsxs)(s.p,{children:["An addressable entity is a post-2.0 type that merges the concept of an ",(0,t.jsx)(s.code,{children:"Account"})," and a ",(0,t.jsx)(s.code,{children:"Contract"}),", bringing in features from both. More information can be found ",(0,t.jsx)(s.a,{href:"/next/concepts/addressable-entity",children:"here"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"assemblyscript",children:"AssemblyScript"}),"\n",(0,t.jsxs)(s.p,{children:["AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using ",(0,t.jsx)(s.em,{children:"asc"}),", the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community."]}),"\n",(0,t.jsx)(s.h2,{id:"auction",children:"Auction"}),"\n",(0,t.jsx)(s.p,{children:'The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.'}),"\n",(0,t.jsx)(s.h2,{id:"auction-contract",children:"Auction contract"}),"\n",(0,t.jsx)(s.p,{children:"The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction."}),"\n",(0,t.jsx)(s.h2,{id:"auction-delay",children:"Auction delay"}),"\n",(0,t.jsxs)(s.p,{children:["The number of full eras that pass between the ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#booking-block",children:"booking block"})," and the era whose validator set it defines. The auction delay is configurable and can be several eras long."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const c={},r=t.createContext(c);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6c606038.a21110c8.js b/assets/js/6c606038.a21110c8.js new file mode 100644 index 000000000..76dbb9697 --- /dev/null +++ b/assets/js/6c606038.a21110c8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98471],{87251:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var c=n(74848),t=n(28453);const r={},a="A",o={id:"concepts/glossary/A",title:"A",description:"---",source:"@site/docs/concepts/glossary/A.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/A",permalink:"/concepts/glossary/A",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Glossary",permalink:"/glossary"},next:{title:"B",permalink:"/concepts/glossary/B"}},i={},l=[{value:"Account",id:"account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Addressable Entity",id:"addressable-entity",level:2},{value:"AssemblyScript",id:"assemblyscript",level:2},{value:"Auction",id:"auction",level:2},{value:"Auction contract",id:"auction-contract",level:2},{value:"Auction delay",id:"auction-delay",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"a",children:"A"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"account",children:"Account"}),"\n",(0,c.jsxs)(s.p,{children:["An Account is a structure that represents a user on a Casper network. Information on creating an account can be found ",(0,c.jsx)(s.a,{href:"/concepts/design/casper-design#accounts-head",children:"here"}),". Casper's Condor release introduces the concept of an ",(0,c.jsx)(s.a,{href:"#addressable-entity",children:"addressable entity"}),", which contains an account entity type that supersedes legacy accounts."]}),"\n",(0,c.jsx)(s.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,c.jsxs)(s.p,{children:["The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found ",(0,c.jsx)(s.a,{href:"https://support.casperlabs.io/hc/en-gb/articles/13781616975131-How-do-I-generate-an-account-hash-",children:"here"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"addressable-entity",children:"Addressable Entity"}),"\n",(0,c.jsxs)(s.p,{children:["An addressable entity is a post-2.0 type that merges the concept of an ",(0,c.jsx)(s.code,{children:"Account"})," and a ",(0,c.jsx)(s.code,{children:"Contract"}),", bringing in features from both. More information can be found ",(0,c.jsx)(s.a,{href:"/concepts/addressable-entity",children:"here"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"assemblyscript",children:"AssemblyScript"}),"\n",(0,c.jsxs)(s.p,{children:["AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using ",(0,c.jsx)(s.em,{children:"asc"}),", the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community."]}),"\n",(0,c.jsx)(s.h2,{id:"auction",children:"Auction"}),"\n",(0,c.jsx)(s.p,{children:'The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.'}),"\n",(0,c.jsx)(s.h2,{id:"auction-contract",children:"Auction contract"}),"\n",(0,c.jsx)(s.p,{children:"The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction."}),"\n",(0,c.jsx)(s.h2,{id:"auction-delay",children:"Auction delay"}),"\n",(0,c.jsxs)(s.p,{children:["The number of full eras that pass between the ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"})," and the era whose validator set it defines. The auction delay is configurable and can be several eras long."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var c=n(96540);const t={},r=c.createContext(t);function a(e){const s=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6ceb2263.4869c915.js b/assets/js/6ceb2263.4869c915.js new file mode 100644 index 000000000..358726d3b --- /dev/null +++ b/assets/js/6ceb2263.4869c915.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65710],{56414:(a,b,c)=>{c.r(b),c.d(b,{assets:()=>s,contentTitle:()=>f,default:()=>o,frontMatter:()=>n,metadata:()=>t,toc:()=>r});var e=c(74848),d=c(28453);const n={},f="Transactional JSON-RPC Methods",t={id:"developers/json-rpc/json-rpc-transactional",title:"Transactional JSON-RPC Methods",description:"---",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-transactional.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-transactional",permalink:"/2.0.0/developers/json-rpc/json-rpc-transactional",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Required Methods for Minimal Compliance",permalink:"/2.0.0/developers/json-rpc/minimal-compliance"},next:{title:"Informational JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-informational"}},s={},r=[{value:"account_put_deploy",id:"account_put_deploy",level:2},{value:"<code>account_put_deploy_result</code>",id:"account_put_deploy_result",level:3},{value:"account_put_transaction",id:"account_put_transaction",level:2},{value:"<code>account_put_transaction_result</code>",id:"account_put_transaction_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"<code>speculative_exec_result</code>",id:"speculative_exec_result",level:3},{value:"speculative_exec_txn",id:"speculative_exec_txn",level:2},{value:"<code>speculative_exec_txn_result</code>",id:"speculative_exec_txn_result",level:3}];function i(a){const b={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(b.header,{children:(0,e.jsx)(b.h1,{id:"transactional-json-rpc-methods",children:"Transactional JSON-RPC Methods"})}),"\n",(0,e.jsx)(b.hr,{}),"\n",(0,e.jsx)(b.h2,{id:"account_put_deploy",children:"account_put_deploy"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#account-put-transaction",children:"account_put_transaction"})," instead."]})}),"\n",(0,e.jsx)(b.p,{children:"This endpoint allows sending a deploy to be executed by the network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "name": "deploy",\n "value": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_deploy_result",children:(0,e.jsx)(b.code,{children:"account_put_deploy_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and a ",(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"}),", which is the primary identifier of a Deploy within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the Deploy as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"account_put_transaction",children:"account_put_transaction"}),"\n",(0,e.jsxs)(b.p,{children:["This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the ",(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:"transaction"})," as a parameter, prior to sending it to a node on a network for execution."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsxs)(b.td,{children:["A transaction consists of an item containing a Deploy and a ",(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:(0,e.jsx)(b.code,{children:"Transaction"})})," along with the requester's signature(s)."]})]})})]}),"\n",(0,e.jsxs)(b.blockquote,{children:["\n",(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"Note"}),": You can find a list of ",(0,e.jsx)(b.a,{href:"/2.0.0/operators/setup/joining",children:"trusted peers"})," in the network's configuration file, ",(0,e.jsx)(b.code,{children:"config.toml"}),". Here is an ",(0,e.jsx)(b.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example config.toml"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n"]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_transaction",\n "params": [\n {\n "name": "transaction",\n "value": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_transaction_result",children:(0,e.jsx)(b.code,{children:"account_put_transaction_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and the ",(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"}),", which is the primary identifier of a transaction within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the transaction as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec",children:"speculative_exec"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#speculative-exec-txn",children:"speculative_exec_txn"})," instead."]})}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Deploy"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#executionresult",children:"execution_results"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"The map of Block hash to execution result."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec_txn",children:"speculative_exec_txn"}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Transaction"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Transaction is a versioned wrapper for a transaction or deploy."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec_txn",\n "params": {\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_txn_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_txn_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/2.0.0/developers/json-rpc/types_chain#executionresult",children:"execution_result"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"Result of the speculative execution."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_txn_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function o(a={}){const{wrapper:b}={...(0,d.R)(),...a.components};return b?(0,e.jsx)(b,{...a,children:(0,e.jsx)(i,{...a})}):i(a)}},28453:(a,b,c)=>{c.d(b,{R:()=>f,x:()=>t});var e=c(96540);const d={},n=e.createContext(d);function f(a){const b=e.useContext(n);return e.useMemo((function(){return"function"==typeof a?a(b):{...b,...a}}),[b,a])}function t(a){let b;return b=a.disableParentContext?"function"==typeof a.components?a.components(d):a.components||d:f(a.components),e.createElement(n.Provider,{value:b},a.children)}}}]); \ No newline at end of file diff --git a/assets/js/6dcb5e16.631ecf42.js b/assets/js/6dcb5e16.631ecf42.js new file mode 100644 index 000000000..18a8f512e --- /dev/null +++ b/assets/js/6dcb5e16.631ecf42.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4005],{14062:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=a(74848),o=a(28453);const i={title:"Fee Elimination"},s="Fee Elimination on Mainnet",r={id:"concepts/economics/fee-elimination",title:"Fee Elimination",description:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.',source:"@site/docs/concepts/economics/fee-elimination.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/fee-elimination",permalink:"/concepts/economics/fee-elimination",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Fee Elimination"},sidebar:"concepts",previous:{title:"Dynamic Gas Pricing",permalink:"/concepts/economics/dynamic-gas-pricing"},next:{title:"Staking",permalink:"/concepts/economics/staking"}},c={},l=[{value:"Chainspec Configurations",id:"chainspec-configurations",level:2},{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Computational and Storage Costs",id:"computational-and-storage-costs",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"fee-elimination-on-mainnet",children:"Fee Elimination on Mainnet"})}),"\n",(0,t.jsx)(n.p,{children:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.'}),"\n",(0,t.jsxs)(n.p,{children:["Instead of paying for gas to execute transactions, the ",(0,t.jsx)(n.code,{children:"no_fee"})," chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: ",(0,t.jsx)(n.code,{children:"fee_handling = { type = 'no_fee'}"}),'. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable ',(0,t.jsx)(n.code,{children:"gas_hold_interval"})," determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The ",(0,t.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational#query_balance_details",children:"query_balance_details"})," RPC endpoint provides details on available balances and hold records."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer."})}),"\n",(0,t.jsx)(n.h2,{id:"chainspec-configurations",children:"Chainspec Configurations"}),"\n",(0,t.jsxs)(n.p,{children:["The following ",(0,t.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"chainspec configurations"})," manage this feature:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"fee_handling"}),' - Defines how fees are handled. To enable the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_fee'}"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"refund_handling"}),' Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_refund'}"}),". If no fees are transferred from the paying purse, no refunds need to be paid out."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing_handling"})," - Defines how pricing is handled. For this setting to work with the ",(0,t.jsx)(n.code,{children:"no_fee"})," mode, set it to ",(0,t.jsx)(n.code,{children:"{ type = 'fixed'}"}),", which means that costs are fixed per the cost table, and senders do not specify how much they pay."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"validator_credit_cap"})," - The validator credit cannot exceed this percentage of their total stake."]}),"\n",(0,t.jsx)(n.li,{children:"`gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry)."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas_hold_interval"})," - Defines how long gas holds last."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,t.jsx)(n.p,{children:"These are the fee elimination settings for the Condor release on Mainnet:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-toml",children:"# Defines how refunds of the unused portion of payment amounts are calculated and handled.\n#\n# Valid options are:\n# 'refund': a ratio of the unspent token is returned to the spender.\n# 'burn': a ratio of the unspent token is burned.\n# 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.\n# This causes excess payment amounts to be sent to either a\n# pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount\n# minus the execution costs.\nrefund_handling = { type = 'no_refund' }\n# Defines how fees are handled.\n#\n# Valid options are:\n# 'no_fee': fees are eliminated.\n# 'pay_to_proposer': fees are paid to the block proposer\n# 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all\n# administrator accounts\n# 'burn': fees are burned\nfee_handling = { type = 'no_fee' }\n# If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.\nvalidator_credit_cap = [1, 5]\n# Defines how pricing is handled.\n#\n# Valid options are:\n# 'classic': senders of transaction self-specify how much they pay.\n# 'fixed': costs are fixed, per the cost table\n# 'reserved': prepaid transaction (currently not supported)\npricing_handling = { type = 'fixed' }\n\n# Defines how gas holds affect available balance calculations.\n#\n# Valid options are:\n# 'accrued': sum of full value of all non-expired holds.\n# 'amortized': sum of each hold is amortized over the time remaining until expiry.\n#\n# For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,\n# with accrued, the full hold amount would be applied\n# with amortized, half the hold amount would be applied\ngas_hold_balance_handling = { type = 'accrued' }\n# Defines how long gas holds last.\n#\n# If fee_handling is set to 'no_fee', the system places a balance hold on the payer\n# equal to the value the fee would have been. Such balance holds expire after a time\n# interval has elapsed. This setting controls how long that interval is. The available\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\n#\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\n# a hold for 100 is placed on that purse and is considered when calculating total balance\n# for 24 hours starting from the block_time when the hold was placed.\ngas_hold_interval = '24 hours'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"computational-and-storage-costs",children:"Computational and Storage Costs"}),"\n",(0,t.jsxs)(n.p,{children:["Despite the introduction of fee elimination, the network continues to track ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational cost"})," based on opcodes as defined in the chainspec, thus retaining the ",(0,t.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:"gas pricing mechanism"}),". Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines."]}),"\n",(0,t.jsx)(n.p,{children:"Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state."}),"\n",(0,t.jsxs)(n.p,{children:["This feature complements the ",(0,t.jsx)(n.a,{href:"/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," model introduced and configured to scale gas costs based on network utilization."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6dcb5e16.e806e70a.js b/assets/js/6dcb5e16.e806e70a.js deleted file mode 100644 index 3ad59b6b1..000000000 --- a/assets/js/6dcb5e16.e806e70a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4005],{14062:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=a(74848),o=a(28453);const i={title:"Fee Elimination"},s="Fee Elimination on Mainnet",r={id:"concepts/economics/fee-elimination",title:"Fee Elimination",description:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.',source:"@site/docs/concepts/economics/fee-elimination.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/fee-elimination",permalink:"/next/concepts/economics/fee-elimination",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Fee Elimination"},sidebar:"concepts",previous:{title:"Dynamic Gas Pricing",permalink:"/next/concepts/economics/dynamic-gas-pricing"},next:{title:"Staking",permalink:"/next/concepts/economics/staking"}},c={},l=[{value:"Chainspec Configurations",id:"chainspec-configurations",level:2},{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Computational and Storage Costs",id:"computational-and-storage-costs",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"fee-elimination-on-mainnet",children:"Fee Elimination on Mainnet"})}),"\n",(0,t.jsx)(n.p,{children:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.'}),"\n",(0,t.jsxs)(n.p,{children:["Instead of paying for gas to execute transactions, the ",(0,t.jsx)(n.code,{children:"no_fee"})," chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: ",(0,t.jsx)(n.code,{children:"fee_handling = { type = 'no_fee'}"}),'. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable ',(0,t.jsx)(n.code,{children:"gas_hold_interval"})," determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The ",(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational#query_balance_details",children:"query_balance_details"})," RPC endpoint provides details on available balances and hold records."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer."})}),"\n",(0,t.jsx)(n.h2,{id:"chainspec-configurations",children:"Chainspec Configurations"}),"\n",(0,t.jsxs)(n.p,{children:["The following ",(0,t.jsx)(n.a,{href:"/next/operators/setup-network/chain-spec",children:"chainspec configurations"})," manage this feature:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"fee_handling"}),' - Defines how fees are handled. To enable the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_fee'}"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"refund_handling"}),' Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_refund'}"}),". If no fees are transferred from the paying purse, no refunds need to be paid out."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing_handling"})," - Defines how pricing is handled. For this setting to work with the ",(0,t.jsx)(n.code,{children:"no_fee"})," mode, set it to ",(0,t.jsx)(n.code,{children:"{ type = 'fixed'}"}),", which means that costs are fixed per the cost table, and senders do not specify how much they pay."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"validator_credit_cap"})," - The validator credit cannot exceed this percentage of their total stake."]}),"\n",(0,t.jsx)(n.li,{children:"`gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry)."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas_hold_interval"})," - Defines how long gas holds last."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,t.jsx)(n.p,{children:"These are the fee elimination settings for the Condor release on Mainnet:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-toml",children:"# Defines how refunds of the unused portion of payment amounts are calculated and handled.\n#\n# Valid options are:\n# 'refund': a ratio of the unspent token is returned to the spender.\n# 'burn': a ratio of the unspent token is burned.\n# 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.\n# This causes excess payment amounts to be sent to either a\n# pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount\n# minus the execution costs.\nrefund_handling = { type = 'no_refund' }\n# Defines how fees are handled.\n#\n# Valid options are:\n# 'no_fee': fees are eliminated.\n# 'pay_to_proposer': fees are paid to the block proposer\n# 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all\n# administrator accounts\n# 'burn': fees are burned\nfee_handling = { type = 'no_fee' }\n# If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.\nvalidator_credit_cap = [1, 5]\n# Defines how pricing is handled.\n#\n# Valid options are:\n# 'classic': senders of transaction self-specify how much they pay.\n# 'fixed': costs are fixed, per the cost table\n# 'reserved': prepaid transaction (currently not supported)\npricing_handling = { type = 'fixed' }\n\n# Defines how gas holds affect available balance calculations.\n#\n# Valid options are:\n# 'accrued': sum of full value of all non-expired holds.\n# 'amortized': sum of each hold is amortized over the time remaining until expiry.\n#\n# For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,\n# with accrued, the full hold amount would be applied\n# with amortized, half the hold amount would be applied\ngas_hold_balance_handling = { type = 'accrued' }\n# Defines how long gas holds last.\n#\n# If fee_handling is set to 'no_fee', the system places a balance hold on the payer\n# equal to the value the fee would have been. Such balance holds expire after a time\n# interval has elapsed. This setting controls how long that interval is. The available\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\n#\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\n# a hold for 100 is placed on that purse and is considered when calculating total balance\n# for 24 hours starting from the block_time when the hold was placed.\ngas_hold_interval = '24 hours'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"computational-and-storage-costs",children:"Computational and Storage Costs"}),"\n",(0,t.jsxs)(n.p,{children:["Despite the introduction of fee elimination, the network continues to track ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational cost"})," based on opcodes as defined in the chainspec, thus retaining the ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/gas-concepts",children:"gas pricing mechanism"}),". Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines."]}),"\n",(0,t.jsx)(n.p,{children:"Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state."}),"\n",(0,t.jsxs)(n.p,{children:["This feature complements the ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," model introduced and configured to scale gas costs based on network utilization."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e2737c0.94881826.js b/assets/js/6e2737c0.94881826.js deleted file mode 100644 index 9e0b0eab7..000000000 --- a/assets/js/6e2737c0.94881826.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6958],{16484:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var c=t(74848),a=t(28453);const s={title:"Contract Hash vs. Package Hash"},r="Using the Contract Hash vs. the Package Hash",o={id:"developers/writing-onchain-code/contract-hash-vs-package-hash",title:"Contract Hash vs. Package Hash",description:"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.",source:"@site/docs/developers/writing-onchain-code/contract-hash-vs-package-hash.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-hash-vs-package-hash",permalink:"/next/developers/writing-onchain-code/contract-hash-vs-package-hash",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Contract Hash vs. Package Hash"},sidebar:"developers",previous:{title:"Contract-Level Events",permalink:"/next/developers/writing-onchain-code/emitting-contract-events"},next:{title:"Factory Contracts",permalink:"/next/developers/writing-onchain-code/factory-pattern"}},h={},i=[{value:"The Casper Call Stack",id:"the-casper-call-stack",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"using-the-contract-hash-vs-the-package-hash",children:"Using the Contract Hash vs. the Package Hash"})}),"\n",(0,c.jsxs)(n.p,{children:["This page describes the possibilities of using the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html",children:"contract hash"})," vs. the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html",children:"contract package hash"})," (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 ",(0,c.jsx)(n.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:"Upgrading and Maintaining Smart Contracts"}),", 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."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Package Representation",src:t(14681).A+"",width:"1170",height:"472"})}),"\n",(0,c.jsx)(n.p,{children:"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:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Want to identify specific versions of contracts within the same package and thus use a contract hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Need specific contract versions within the same package, and thus use both contract hash and contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need either hash for this use case"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers loosely at the package level?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers specifically at the contract level?"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Or a more fine-grained variation would be:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow or block callers at the package level but track by both package and contract hash?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow other combinations of these basic concepts?"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["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 ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/",children:"Casper External FFI"}),", versus use cases and interactions between two or more ecosystem entities such as accounts and contracts."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.h2,{id:"the-casper-call-stack",children:"The Casper Call Stack"}),"\n",(0,c.jsxs)(n.p,{children:["When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html",children:"casper_load_call_stack"}),", which provides a stack of one or more entries of this kind:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-rust",children:"/// Represents the origin of a sub-call.\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum CallStackElement {\n /// Session\n Session {\n /// The account hash of the caller\n account_hash: AccountHash,\n },\n /// Effectively an EntryPointType::Session - stored access to a session.\n StoredSession {\n /// The account hash of the caller\n account_hash: AccountHash,\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n /// contract\n StoredContract {\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["You can find the source code ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs",children:"here"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine."}),"\n",(0,c.jsxs)(n.p,{children:["Learn more about ",(0,c.jsx)(n.a,{href:"/next/concepts/callstack",children:"Call Stacks"})," and how Casper manages the calling of a contract."]}),"\n",(0,c.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,c.jsx)(n.p,{children:"Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash."}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only accounts to use the contract? If so, what kind of accounts are you considering?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify and track each account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Exactly one specific account"}),(0,c.jsx)(n.td,{children:"Use the account hash of a specific account to identify it."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts"}),(0,c.jsx)(n.td,{children:"There is no need to track the accounts by account hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only contracts to use it? If so, what kind of contracts?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions"}),(0,c.jsx)(n.td,{children:"Use the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the contract hash and the package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use only the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract version of any contract"}),(0,c.jsx)(n.td,{children:"There is no need to track by contract or package hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and contract versions"}),(0,c.jsx)(n.td,{children:"Use the account hash to track each account and the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and specific versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the contract hash and package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and any versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts and contracts"}),(0,c.jsx)(n.td,{children:"There is no need to track by account hash or contract hash."})]})]})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/next/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/next/resources/tutorials/advanced/cross-contract",children:"Cross-Contract Communication"})," - Variations of cross-contract communication for more complex scenarios"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," - Contract code returning a value to the immediate caller via ",(0,c.jsx)(n.code,{children:"runtime::ret()"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},14681:(e,n,t)=>{t.d(n,{A:()=>c});const c=t.p+"assets/images/package-representation-extended-a8ed26938de11cc769bc8fc6d8852b1b.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e2737c0.fc64a7ef.js b/assets/js/6e2737c0.fc64a7ef.js new file mode 100644 index 000000000..df3acc423 --- /dev/null +++ b/assets/js/6e2737c0.fc64a7ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76958],{16484:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var c=t(74848),a=t(28453);const s={title:"Contract Hash vs. Package Hash"},r="Using the Contract Hash vs. the Package Hash",o={id:"developers/writing-onchain-code/contract-hash-vs-package-hash",title:"Contract Hash vs. Package Hash",description:"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.",source:"@site/docs/developers/writing-onchain-code/contract-hash-vs-package-hash.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-hash-vs-package-hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Contract Hash vs. Package Hash"},sidebar:"developers",previous:{title:"Contract-Level Events",permalink:"/developers/writing-onchain-code/emitting-contract-events"},next:{title:"Factory Contracts",permalink:"/developers/writing-onchain-code/factory-pattern"}},h={},i=[{value:"The Casper Call Stack",id:"the-casper-call-stack",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"using-the-contract-hash-vs-the-package-hash",children:"Using the Contract Hash vs. the Package Hash"})}),"\n",(0,c.jsxs)(n.p,{children:["This page describes the possibilities of using the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html",children:"contract hash"})," vs. the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html",children:"contract package hash"})," (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 ",(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:"Upgrading and Maintaining Smart Contracts"}),", 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."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Package Representation",src:t(81695).A+"",width:"1170",height:"472"})}),"\n",(0,c.jsx)(n.p,{children:"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:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Want to identify specific versions of contracts within the same package and thus use a contract hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Need specific contract versions within the same package, and thus use both contract hash and contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need either hash for this use case"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers loosely at the package level?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers specifically at the contract level?"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Or a more fine-grained variation would be:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow or block callers at the package level but track by both package and contract hash?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow other combinations of these basic concepts?"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["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 ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/",children:"Casper External FFI"}),", versus use cases and interactions between two or more ecosystem entities such as accounts and contracts."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.h2,{id:"the-casper-call-stack",children:"The Casper Call Stack"}),"\n",(0,c.jsxs)(n.p,{children:["When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html",children:"casper_load_call_stack"}),", which provides a stack of one or more entries of this kind:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-rust",children:"/// Represents the origin of a sub-call.\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum CallStackElement {\n /// Session\n Session {\n /// The account hash of the caller\n account_hash: AccountHash,\n },\n /// Effectively an EntryPointType::Session - stored access to a session.\n StoredSession {\n /// The account hash of the caller\n account_hash: AccountHash,\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n /// contract\n StoredContract {\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["You can find the source code ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs",children:"here"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine."}),"\n",(0,c.jsxs)(n.p,{children:["Learn more about ",(0,c.jsx)(n.a,{href:"/concepts/callstack",children:"Call Stacks"})," and how Casper manages the calling of a contract."]}),"\n",(0,c.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,c.jsx)(n.p,{children:"Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash."}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only accounts to use the contract? If so, what kind of accounts are you considering?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify and track each account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Exactly one specific account"}),(0,c.jsx)(n.td,{children:"Use the account hash of a specific account to identify it."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts"}),(0,c.jsx)(n.td,{children:"There is no need to track the accounts by account hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only contracts to use it? If so, what kind of contracts?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions"}),(0,c.jsx)(n.td,{children:"Use the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the contract hash and the package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use only the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract version of any contract"}),(0,c.jsx)(n.td,{children:"There is no need to track by contract or package hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and contract versions"}),(0,c.jsx)(n.td,{children:"Use the account hash to track each account and the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and specific versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the contract hash and package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and any versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts and contracts"}),(0,c.jsx)(n.td,{children:"There is no need to track by account hash or contract hash."})]})]})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/resources/tutorials/advanced/cross-contract",children:"Cross-Contract Communication"})," - Variations of cross-contract communication for more complex scenarios"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," - Contract code returning a value to the immediate caller via ",(0,c.jsx)(n.code,{children:"runtime::ret()"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},81695:(e,n,t)=>{t.d(n,{A:()=>c});const c=t.p+"assets/images/package-representation-extended-a8ed26938de11cc769bc8fc6d8852b1b.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e34a484.5e7fcec6.js b/assets/js/6e34a484.5e7fcec6.js deleted file mode 100644 index 1a27cc0cd..000000000 --- a/assets/js/6e34a484.5e7fcec6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4814],{64930:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>r,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Sending Transactions"},s="Sending Transactions using the Casper Client",r={id:"developers/cli/sending-transactions",title:"Sending Transactions",description:"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:",source:"@site/docs/developers/cli/sending-transactions.md",sourceDirName:"developers/cli",slug:"/developers/cli/sending-transactions",permalink:"/next/developers/cli/sending-transactions",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Sending Transactions"},sidebar:"developers",previous:{title:"Undelegating Tokens",permalink:"/next/developers/cli/undelegate"},next:{title:"Installing Contracts",permalink:"/next/developers/cli/installing-contracts"}},i={},o=[{value:"Paying for Transactions",id:"paying-for-transactions",level:2},{value:"Monitoring the Event Stream for Transactions",id:"monitoring-the-event-stream-for-transactions",level:2},{value:"Sending a Transaction to the Network",id:"sending-the-transaction",level:2},{value:"Time-to-live",id:"ttl",level:3},{value:"Legacy Deploy Payments",id:"deploy-payments",level:3},{value:"Using Arguments with Transactions",id:"using-arguments-with-transactions",level:2},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Gas Cost for Transactions",id:"gas-cost-for-transactions",level:2},{value:"Common Errors Related to Payments",id:"common-errors-related-to-payments",level:2},{value:"Out of gas error",id:"out-of-gas-error",level:3},{value:"Gas limit error",id:"gas-limit-error",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sending-transactions-using-the-casper-client",children:"Sending Transactions using the Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["To install smart contracts on the blockchain, you can send your Wasm to the network via a ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"Transaction"}),". To do this, you will need to meet a few prerequisites:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You will need a client to interact with the network, such as the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Ensure you have an ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"Account"})," and its associated ",(0,t.jsx)(n.a,{href:"/next/concepts/accounts-and-keys",children:"keys"})," This account will pay for the Transaction, and its secret key will sign the Transaction"]}),"\n",(0,t.jsx)(n.li,{children:"Ensure this account has enough CSPR tokens to pay for the Transaction"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"paying-for-transactions",children:"Paying for Transactions"}),"\n",(0,t.jsx)(n.p,{children:"CSPR tokens are used to pay for transactions on the Casper Mainnet and Testnet. There are several ways to fund your account:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You may want to ",(0,t.jsx)(n.a,{href:"/next/users/funding-from-exchanges",children:"transfer tokens from an exchange"})]}),"\n",(0,t.jsxs)(n.li,{children:["You can use a ",(0,t.jsx)(n.a,{href:"/next/users/token-transfer",children:"block explorer to transfer tokens"})," between accounts' purses"]}),"\n",(0,t.jsxs)(n.li,{children:["You can also ",(0,t.jsx)(n.a,{href:"/next/developers/cli/transfers/",children:"transfer tokens using the default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["On the Testnet, you can use the ",(0,t.jsx)(n.a,{href:"/next/users/testnet-faucet",children:"faucet functionality"})," for testing your smart contracts"]}),"\n",(0,t.jsxs)(n.li,{children:["If running a network locally using ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/nctl-test",children:"NCTL"}),", the tool provides several funded accounts"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"monitoring-the-event-stream-for-transactions",children:"Monitoring the Event Stream for Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to follow the ",(0,t.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"lifecycle"})," of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"here"}),". You need the following information to proceed:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The IP address of a ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"peer"})," on the network"]}),"\n",(0,t.jsxs)(n.li,{children:["The port specified as the ",(0,t.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,t.jsx)(n.em,{children:"config.toml"}),", which is by default 9999 on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The URL for streamed events, which is ",(0,t.jsx)(n.a,{href:"HOST:PORT",children:"HOST:PORT"}),"/events"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"With the following command, you can start watching the event stream. Note the event ID recorded when you send the Transaction in the next section."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://65.21.235.219:9999/events\n"})}),"\n",(0,t.jsx)(n.h2,{id:"sending-the-transaction",children:"Sending a Transaction to the Network"}),"\n",(0,t.jsxs)(n.p,{children:["You can call the Casper client's ",(0,t.jsx)(n.code,{children:"put-txn"})," command to put the compiled contract on the chain. In this example, the Transaction will execute in the account's context. See the ",(0,t.jsx)(n.a,{href:"#advanced-features",children:"advanced features"})," section for key delegation."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session\\\n --node-address <HOST:PORT> \\\n --chain-name casper-net-1 \\\n --transaction-path <transaction-PATH> \\\n --session-entry-point <NAME> \\\n --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n --gas-price-tolerance <INTEGER> \\\n --pricing-mode fixed \\\n --secret-key <PATH> | --initiator-address <HEX STRING>\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of the sidecar's JSON-RPC server on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,t.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),". As you can see, this example uses the Testnet."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction category, based on size of the Wasm included. ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,t.jsx)(n.code,{children:"large"}),", ",(0,t.jsx)(n.code,{children:"medium"})," and ",(0,t.jsx)(n.code,{children:"small"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum gas price that the user is willing to pay for this transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"})," - The pricing mode used for this transaction, in this case ",(0,t.jsx)(n.code,{children:"fixed"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," or ",(0,t.jsx)(n.code,{children:"initiator-address"})," - The file name containing the secret key of the account paying for the Transaction, or the address of the account initiating the transaction. ",(0,t.jsx)(n.code,{children:"initiator-address"})," can be a public key, account hash or an entity address."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's execution results. Sending the transaction and receiving the transaction hash does not mean the transaction was processed successfully. Therefore, you must check the transaction execution using the transaction hash. See the transaction lifecycle for more details."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": Each Transaction gets a unique hash, which is part of the cryptographic security of blockchain technology. No two transactions will ever return the same hash."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample put-txn result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Verify the transaction details with the ",(0,t.jsx)(n.code,{children:"get-txn"})," command and the ",(0,t.jsx)(n.code,{children:"transaction_hash"})," received above."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-txn \\\n --node-address <HOST:PORT> <TRANSACTION-HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If the Transaction succeeded, the ",(0,t.jsx)(n.code,{children:"get-txn"})," command would return a JSON object with the full transaction details."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample get-transaction result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -3929997047953574815,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-07-17T16:45:43.821Z",\n "ttl": "30m",\n "body_hash": "c5c4f7ae2fecb68937c19a1439eefddd8d4c32de779fe3ffee292977f161b234",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n }\n },\n "body": {\n "args": [\n [\n "name",\n {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n ],\n [\n "symbol",\n {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n ],\n [\n "total_supply",\n {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n ],\n [\n "decimals",\n {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n ]\n ],\n "target": {\n "Session": {\n "module_bytes": "[655810 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65",\n "signature": "012ac4fc94d4ba269eb94aad1b9e90d1f701ed0e660995c1a15afc69010b74b51dd1334f9a59a9587aaf6aa6ab5ad35a7e86a9dcba39c2d21843e56d5d4014f00f"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "23f21d3af261dd830790926b240dbded4362bb3c1183d9ee4ec1aea132bfa5e0",\n "block_height": 624,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "371736413663",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 328238,\n "effects": [\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n }\n }\n },\n {\n "key": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n }\n }\n },\n {\n "key": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-987369d1ce9ffff037841f4a221d7fc63924d565196de9e67ea8bdb897bc22e7",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f7061636b6167655f4345503138",\n "parsed": "cep18_contract_package_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-eb635428d8eb01ac5683a333755ba85f6299df45cab9048c18d84fbc5367e932",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b507",\n "parsed": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "2300000063657031385f636f6e74726163745f7061636b6167655f6163636573735f4345503138",\n "parsed": "cep18_contract_package_access_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "package-1b937640b847113bb5adeccdd1aae96a913c340c1911949f90c90a0dd025d9a4",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[659014 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f07",\n "parsed": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "08000000646563696d616c73",\n "parsed": "decimals"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f26520fac960fb1abac44a358923ab6a064baffb1707c885886d157f66c55209",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce07",\n "parsed": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000656e61626c655f6d696e745f6275726e",\n "parsed": "enable_mint_burn"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-7114a751e72d65a0290c975396374e0120ac8f3ddbb6e4e21e3c6810135b40d0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0216baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e0307",\n "parsed": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0b0000006576656e74735f6d6f6465",\n "parsed": "events_mode"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d07",\n "parsed": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "040000006e616d65",\n "parsed": "name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0221a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a07",\n "parsed": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0600000073796d626f6c",\n "parsed": "symbol"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad107",\n "parsed": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c000000746f74616c5f737570706c79",\n "parsed": "total_supply"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e3c8f46f39b1ee1cbadb774ffaf842226b7cbf1fef3bbc04abfa80b86daca11",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "allowance",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44528c1898e30df62037a76e0c45123f4f4437336ca63236b10ebfc16a5edb78",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fcc296caa05679d0d11121e7629b29f222a857018f50985046b73a56e9a10701",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "balance_of",\n "args": [\n {\n "name": "address",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-768c370eb010604bd19029a409dca8b5fbf9af9bc14a36c2b294a2a7a922161e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "burn",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bab8615f758ed79acb7dd7577b1a6c12d625d1a19592a2b1ded0dc352407e4d5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_events_mode",\n "args": [\n {\n "name": "events_mode",\n "cl_type": "U8"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-82a811993cf9ccb5e46c9608c69d86e3c9b7b499520fd48cdca1424f2a08efdc",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_security",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "condor",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decimals",\n "args": [],\n "ret": "U8",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-ac07c23dc90a33282d553af890e30e62335c5ae986629d643778e2d4516f26ad",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decrease_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-a7e05838c728d16c4ba3e1980b6729c857ef4c21d1b0c34e6eefbb486cdc2b89",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "increase_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "init",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fc79236fd0e4521c8feddcc2094c6a0ea04fcaafb17fef63ef060744a6bab401",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_sec_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-18bff854e9d908cf20fb1db53a47ab69968917b53b8c71371e7dd0f88b363e60",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_allowance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e7babf918642bd9636d3c121691bd85534b41084a5c22fe1e2bf196224dade6",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_balance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-233964bb1dc667b37a8abbb938d7647b2c4ab41f0c26dbbcd26c62e7870f72ba",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "mint",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "name",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "symbol",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "total_supply",\n "args": [],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-3820ce25e54df0470fb738e3e0f63ee50b2719cf2680da2bdb579e21aebc8f63",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer",\n "args": [\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44208043191e40d3417df6878e1a23894172cf37cf2e4444384ada99e25430e7",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer_from",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "byte_code_hash": "byte-code-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "main_purse": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-dc1e638c71901f1e8fd375ce7a9c6eb2f240241b4ca9cbb7abd65ce16f879a22",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "errors",\n "topic_name_hash": "b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc"\n }\n ]\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "message-topic-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 0,\n "blocktime": 1721234748003\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-0268d6df10a5edcebe0d3790d2eba676dba455e46a2c880085fdbeca4ab762fb",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1900000063657031385f636f6e74726163745f686173685f4345503138",\n "parsed": "cep18_contract_hash_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-da1fb8c629dc3b127c4cc7e8b09431872aa846af6777bb15b280126ca65663cd",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "021075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a07",\n "parsed": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f76657273696f6e5f4345503138",\n "parsed": "cep18_contract_version_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a7807607",\n "parsed": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": "Identity"\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": "Identity"\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-c45567f4859db5b100d4c45a9638973ccdf0a7068a2a50f7a1c8709d5e84fbd2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c0000007061636b6167655f68617368",\n "parsed": "package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-d447c1e29c0d374421e2c3f290c580a73aa748eba54e1b6bb3da0acdd4cdcee5",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0d000000636f6e74726163745f68617368",\n "parsed": "contract_hash"\n }\n }\n }\n }\n },\n {\n "key": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bce0df2b23ec57062235795dd9b7a1a6dc07885918c6cee5c5859a9df3d498e0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e21422207",\n "parsed": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0a000000616c6c6f77616e636573",\n "parsed": "allowances"\n }\n }\n }\n }\n },\n {\n "key": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-058ed80a0c85bcf8470ac5b8ca4c14f1086c3cd5ae00f1f0592fee3addf4073c",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d1707",\n "parsed": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0800000062616c616e636573",\n "parsed": "balances"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-52d71098e9663be90740263d98e5596d99a9c854beada13b2fa1be0e5ab1dd4b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[190 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-5f4fd818ad44d4ae056e151759a8585de97a1c7c4d53ceecac6631f9fbb39ab6",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf07",\n "parsed": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0f00000073656375726974795f626164676573",\n "parsed": "security_badges"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-4e62a209ec9eda0bdfffd2039d231751690eb4594bab0744d59ae01f3b44b875",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[188 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": "Identity"\n },\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Prune": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000"\n }\n },\n {\n "key": "balance-hold-004c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-11a9f79f8943382d3bff560b55d3153bf33f7a883b0da8da4ad879c5648a4d5b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "entity-system-b317612414e2c1f864730f98386c906db6ea330555f57ba2e5c50daca8eec817",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c1100300",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c11003003900000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e9f55f093d23c687d249f63e7ffaa567560500e794751c0ca897af06af3e5102",\n "era_id": 57,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"We want to draw your attention to a few properties in the example output:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Execution consumed 371736413663 motes, which is less than our ",(0,t.jsx)(n.code,{children:"gas price tolerance"})," of 1000000000000. Read about ",(0,t.jsx)(n.a,{href:"#gas-cost-for-transactions",children:"gas cost for transactions"})]}),"\n",(0,t.jsxs)(n.li,{children:['The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,t.jsx)(n.code,{children:"--gas-price-tolerance"})," arg"]}),"\n",(0,t.jsx)(n.li,{children:"The time-to-live was 30 minutes"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to get a summary of the transaction's information by performing a ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address <HOST:PORT>\n\ncasper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX-STRING> \\\n --state-root-hash <STATE-ROOT-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX STRING>\n --block-hash <BLOCK-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Run the help command for ",(0,t.jsx)(n.code,{children:"query-global-state"})," to see its usage."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"ttl",children:"Time-to-live"}),"\n",(0,t.jsxs)(n.p,{children:["Time-to-live is the parameter that determines how long a transaction will wait for execution. The acceptable maximum ",(0,t.jsx)(n.code,{children:"ttl"})," is configurable by chain, with the Casper Mainnet maximum set to ",(0,t.jsx)(n.code,{children:"18hours"}),". If you are sending a transaction to a different network, you will need to check ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid transaction."]}),"\n",(0,t.jsxs)(n.p,{children:["In the event of a network outage or other event that prevents execution within the ",(0,t.jsx)(n.code,{children:"ttl"}),", the solution is to resend the transaction in question."]}),"\n",(0,t.jsxs)(n.p,{children:["Should the transaction's ",(0,t.jsx)(n.code,{children:"ttl"})," exceed the allowable limit, or if the transaction expires, the network's transaction acceptor will find the transaction invalid and return a warning."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-payments",children:"Legacy Deploy Payments"}),"\n",(0,t.jsxs)(n.p,{children:["Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution. All legacy deploys will go through the ",(0,t.jsx)(n.code,{children:"session"})," subcommand for ",(0,t.jsx)(n.code,{children:"put-txn"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,t.jsx)(n.strong,{children:"empty"})," ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," as your payment code. However, you must specify the amount within a runtime argument. ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."]}),"\n",(0,t.jsx)(n.p,{children:"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByName"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByName"})]}),"\n",(0,t.jsx)(n.h2,{id:"using-arguments-with-transactions",children:"Using Arguments with Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["The session Wasm (or payment Wasm if you choose to ",(0,t.jsx)(n.em,{children:"not"}),' use the standard payment) of a Transaction often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,t.jsx)(n.code,{children:"--session-arg"})," or ",(0,t.jsx)(n.code,{children:"--payment-arg"})," options, once for each arg required. The Casper client provides some examples of how to do this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"advanced-features",children:"Advanced Features"}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks support complex transactions using multiple signatures. ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Casper Accounts"})," use a powerful permissions model that enables a multi-signature scheme for transactions."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"put-transaction"})," command performs multiple actions under the hood, optimizing the typical use case. It creates a transaction, signs it, and sends the Transaction to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-transaction"})," - Creates a Transaction and outputs it to a file or stdout. As a file, the transaction can subsequently be signed by other parties using the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," subcommand and then sent to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-transaction"})," subcommand"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-transaction"})," - Reads a previously-saved Transaction from a file, cryptographically signs it, and outputs it to a file or stdout"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-transaction"})," - Reads a previously-saved Transaction from a file and sends it to the network for execution"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To sign a Transaction with multiple keys, create the Transaction with the ",(0,t.jsx)(n.code,{children:"make-transaction"})," command. The generated transaction file can be sent to the other signers, who then sign it with their keys by calling the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," for each key. Signatures need to be gathered on the Transaction one after another until all required parties have signed the Transaction. Finally, the signed Transaction is sent to the network with the ",(0,t.jsx)(n.code,{children:"send-transaction"})," command for processing."]}),"\n",(0,t.jsxs)(n.p,{children:["For a step-by-step workflow, visit the ",(0,t.jsx)(n.a,{href:"/next/developers/cli/transfers/multisig-deploy-transfer",children:"Two-Party Multi-Signature Transaction"})," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network."]}),"\n",(0,t.jsx)(n.h2,{id:"gas-cost-for-transactions",children:"Gas Cost for Transactions"}),"\n",(0,t.jsx)(n.p,{children:'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'}),"\n",(0,t.jsxs)(n.p,{children:["We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the transaction. If you plan on sending a transaction to ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", you can use the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to estimate the payment amount needed for the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:['Casper\'s "Condor" release introduces a new payment system that includes the concept of ',(0,t.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"fee elimination"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["If your test configuration matches your production ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),", you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,t.jsx)(n.a,{href:"/next/runtime#gas-allocation",children:"runtime economics"})," section for more details about gas usage and fees."]}),"\n",(0,t.jsxs)(n.p,{children:["Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,t.jsxs)(n.p,{children:["If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,t.jsx)(n.a,{href:"/next/concepts/serialization/types#executionresultv2",children:"failed execution"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"However, if the failure occurs prior to session execution, the penalty payment will not appear in the transaction's gas cost. Depending on the network configuration, the system will deduct the processing fee from the sending account's main purse or place a processing hold on the purse."}),"\n",(0,t.jsx)(n.h2,{id:"common-errors-related-to-payments",children:"Common Errors Related to Payments"}),"\n",(0,t.jsx)(n.h3,{id:"out-of-gas-error",children:"Out of gas error"}),"\n",(0,t.jsx)(n.p,{children:'You might encounter an "Out of gas error" when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.'}),"\n",(0,t.jsxs)(n.p,{children:["Here is an ",(0,t.jsx)(n.a,{href:"https://cspr.live/deploy/afeb43036c41e667af8bc34782c48a66cf4da3818defe9f761291fa515cc38b9",children:"example"}),' of a transaction that resulted in an "Out of gas error" on the Mainnet.']}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 1"}),": In the Deploys tab of an account on ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),', a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an "Out of gas error".']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Out of gas error",src:a(4966).A+"",width:"2048",height:"1118"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 2"}),": Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in account",src:a(16871).A+"",width:"1698",height:"824"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 3"}),": Click the ",(0,t.jsx)(n.strong,{children:"Show raw data"})," button, to see more details about the deploy. Towards the end of the raw data, you can see the error message."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in raw data",src:a(72528).A+"",width:"1472",height:"424"})}),"\n",(0,t.jsx)(n.h3,{id:"gas-limit-error",children:"Gas limit error"}),"\n",(0,t.jsx)(n.p,{children:'You may sometimes see an error such as "payment: 2.5, cost: 2.5, Error::GasLimit". This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error.'}),"\n",(0,t.jsx)(n.p,{children:"This error message tries to communicate that execution stopped at 2.5 CSPR, and the transaction did not run to completion. In other words, the computation resulted in an error because there were insufficient funds for the transaction to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution and charged that much, resulting in a failed transaction. The execution engine does not know how much it would have cost if allowed to run to completion because it did not allow the transaction to finish since it would have run over its gas limit."}),"\n",(0,t.jsx)(n.p,{children:"In summary, when a transaction hits its gas limit (the payment amount), execution stops."})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},16871:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-account-75086cfae6160dfca8cce66fc2b80f44.png"},4966:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-deploys-82cd87f7fc9013f4a7da13e4dd6123e3.png"},72528:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-raw-5b014abd0817fd1c15b225a083a68e3a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6e34a484.df202898.js b/assets/js/6e34a484.df202898.js new file mode 100644 index 000000000..d9c1dea8d --- /dev/null +++ b/assets/js/6e34a484.df202898.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4814],{64930:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>r,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Sending Transactions"},s="Sending Transactions using the Casper Client",r={id:"developers/cli/sending-transactions",title:"Sending Transactions",description:"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:",source:"@site/docs/developers/cli/sending-transactions.md",sourceDirName:"developers/cli",slug:"/developers/cli/sending-transactions",permalink:"/developers/cli/sending-transactions",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Sending Transactions"},sidebar:"developers",previous:{title:"Undelegating Tokens",permalink:"/developers/cli/undelegate"},next:{title:"Installing Contracts",permalink:"/developers/cli/installing-contracts"}},i={},o=[{value:"Paying for Transactions",id:"paying-for-transactions",level:2},{value:"Monitoring the Event Stream for Transactions",id:"monitoring-the-event-stream-for-transactions",level:2},{value:"Sending a Transaction to the Network",id:"sending-the-transaction",level:2},{value:"Time-to-live",id:"ttl",level:3},{value:"Legacy Deploy Payments",id:"deploy-payments",level:3},{value:"Using Arguments with Transactions",id:"using-arguments-with-transactions",level:2},{value:"Advanced Features",id:"advanced-features",level:2},{value:"Gas Cost for Transactions",id:"gas-cost-for-transactions",level:2},{value:"Common Errors Related to Payments",id:"common-errors-related-to-payments",level:2},{value:"Out of gas error",id:"out-of-gas-error",level:3},{value:"Gas limit error",id:"gas-limit-error",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sending-transactions-using-the-casper-client",children:"Sending Transactions using the Casper Client"})}),"\n",(0,t.jsxs)(n.p,{children:["To install smart contracts on the blockchain, you can send your Wasm to the network via a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/T#transaction",children:"Transaction"}),". To do this, you will need to meet a few prerequisites:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You will need a client to interact with the network, such as the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Ensure you have an ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Account"})," and its associated ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"keys"})," This account will pay for the Transaction, and its secret key will sign the Transaction"]}),"\n",(0,t.jsx)(n.li,{children:"Ensure this account has enough CSPR tokens to pay for the Transaction"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"paying-for-transactions",children:"Paying for Transactions"}),"\n",(0,t.jsx)(n.p,{children:"CSPR tokens are used to pay for transactions on the Casper Mainnet and Testnet. There are several ways to fund your account:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You may want to ",(0,t.jsx)(n.a,{href:"/users/funding-from-exchanges",children:"transfer tokens from an exchange"})]}),"\n",(0,t.jsxs)(n.li,{children:["You can use a ",(0,t.jsx)(n.a,{href:"/users/token-transfer",children:"block explorer to transfer tokens"})," between accounts' purses"]}),"\n",(0,t.jsxs)(n.li,{children:["You can also ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/",children:"transfer tokens using the default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["On the Testnet, you can use the ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"faucet functionality"})," for testing your smart contracts"]}),"\n",(0,t.jsxs)(n.li,{children:["If running a network locally using ",(0,t.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"NCTL"}),", the tool provides several funded accounts"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"monitoring-the-event-stream-for-transactions",children:"Monitoring the Event Stream for Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["If you want to follow the ",(0,t.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"lifecycle"})," of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described ",(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"here"}),". You need the following information to proceed:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The IP address of a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"peer"})," on the network"]}),"\n",(0,t.jsxs)(n.li,{children:["The port specified as the ",(0,t.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,t.jsx)(n.em,{children:"config.toml"}),", which is by default 9999 on Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The URL for streamed events, which is ",(0,t.jsx)(n.a,{href:"HOST:PORT",children:"HOST:PORT"}),"/events"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"With the following command, you can start watching the event stream. Note the event ID recorded when you send the Transaction in the next section."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://65.21.235.219:9999/events\n"})}),"\n",(0,t.jsx)(n.h2,{id:"sending-the-transaction",children:"Sending a Transaction to the Network"}),"\n",(0,t.jsxs)(n.p,{children:["You can call the Casper client's ",(0,t.jsx)(n.code,{children:"put-txn"})," command to put the compiled contract on the chain. In this example, the Transaction will execute in the account's context. See the ",(0,t.jsx)(n.a,{href:"#advanced-features",children:"advanced features"})," section for key delegation."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session\\\n --node-address <HOST:PORT> \\\n --chain-name casper-net-1 \\\n --transaction-path <transaction-PATH> \\\n --session-entry-point <NAME> \\\n --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n --gas-price-tolerance <INTEGER> \\\n --pricing-mode fixed \\\n --secret-key <PATH> | --initiator-address <HEX STRING>\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of the sidecar's JSON-RPC server on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,t.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),". As you can see, this example uses the Testnet."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction category, based on size of the Wasm included. ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,t.jsx)(n.code,{children:"large"}),", ",(0,t.jsx)(n.code,{children:"medium"})," and ",(0,t.jsx)(n.code,{children:"small"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum gas price that the user is willing to pay for this transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"})," - The pricing mode used for this transaction, in this case ",(0,t.jsx)(n.code,{children:"fixed"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," or ",(0,t.jsx)(n.code,{children:"initiator-address"})," - The file name containing the secret key of the account paying for the Transaction, or the address of the account initiating the transaction. ",(0,t.jsx)(n.code,{children:"initiator-address"})," can be a public key, account hash or an entity address."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's execution results. Sending the transaction and receiving the transaction hash does not mean the transaction was processed successfully. Therefore, you must check the transaction execution using the transaction hash. See the transaction lifecycle for more details."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": Each Transaction gets a unique hash, which is part of the cryptographic security of blockchain technology. No two transactions will ever return the same hash."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample put-txn result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Verify the transaction details with the ",(0,t.jsx)(n.code,{children:"get-txn"})," command and the ",(0,t.jsx)(n.code,{children:"transaction_hash"})," received above."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-txn \\\n --node-address <HOST:PORT> <TRANSACTION-HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If the Transaction succeeded, the ",(0,t.jsx)(n.code,{children:"get-txn"})," command would return a JSON object with the full transaction details."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample get-transaction result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -3929997047953574815,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-07-17T16:45:43.821Z",\n "ttl": "30m",\n "body_hash": "c5c4f7ae2fecb68937c19a1439eefddd8d4c32de779fe3ffee292977f161b234",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n }\n },\n "body": {\n "args": [\n [\n "name",\n {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n ],\n [\n "symbol",\n {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n ],\n [\n "total_supply",\n {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n ],\n [\n "decimals",\n {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n ]\n ],\n "target": {\n "Session": {\n "module_bytes": "[655810 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65",\n "signature": "012ac4fc94d4ba269eb94aad1b9e90d1f701ed0e660995c1a15afc69010b74b51dd1334f9a59a9587aaf6aa6ab5ad35a7e86a9dcba39c2d21843e56d5d4014f00f"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "23f21d3af261dd830790926b240dbded4362bb3c1183d9ee4ec1aea132bfa5e0",\n "block_height": 624,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01f4ed68f99591d583426d1700b9be6ebd34d8cd395710596bce3db8b127ea3f65"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "371736413663",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 328238,\n "effects": [\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "050000004345503138",\n "parsed": "CEP18"\n }\n }\n }\n },\n {\n "key": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "0400000067726973",\n "parsed": "gris"\n }\n }\n }\n },\n {\n "key": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U256",\n "bytes": "0164",\n "parsed": "100"\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-987369d1ce9ffff037841f4a221d7fc63924d565196de9e67ea8bdb897bc22e7",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f7061636b6167655f4345503138",\n "parsed": "cep18_contract_package_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-eb635428d8eb01ac5683a333755ba85f6299df45cab9048c18d84fbc5367e932",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b507",\n "parsed": "uref-efcac4a17c93c5ba3d3213ea4a00631c5da3fb8bba36c70ae1431db6ea93b8b5-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "2300000063657031385f636f6e74726163745f7061636b6167655f6163636573735f4345503138",\n "parsed": "cep18_contract_package_access_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "package-1b937640b847113bb5adeccdd1aae96a913c340c1911949f90c90a0dd025d9a4",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[659014 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f07",\n "parsed": "uref-303ab2a4aeb6a057a7a256aabf491dad6f0decbfd880d80f9052d5b2df83ba5f-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "08000000646563696d616c73",\n "parsed": "decimals"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f26520fac960fb1abac44a358923ab6a064baffb1707c885886d157f66c55209",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce07",\n "parsed": "uref-de4523d10773c2ee1fd48adb32d7121380c0febbf4f36f1029dc61ff079b83ce-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000656e61626c655f6d696e745f6275726e",\n "parsed": "enable_mint_burn"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-7114a751e72d65a0290c975396374e0120ac8f3ddbb6e4e21e3c6810135b40d0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0216baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e0307",\n "parsed": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0b0000006576656e74735f6d6f6465",\n "parsed": "events_mode"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d07",\n "parsed": "uref-4bb9770e4b7dfa5e9d12cfb35b55d862d6eebdced3205e422b48d7fb207b874d-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "040000006e616d65",\n "parsed": "name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0221a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a07",\n "parsed": "uref-21a2ada35583cfe2a63c59a70d5df464f9bd90833c261871b44e9cf7f7d28c1a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0600000073796d626f6c",\n "parsed": "symbol"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad107",\n "parsed": "uref-456742d5cec63a743907e61935567da1c8f73f95c5aba2c84801189fce936ad1-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c000000746f74616c5f737570706c79",\n "parsed": "total_supply"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e3c8f46f39b1ee1cbadb774ffaf842226b7cbf1fef3bbc04abfa80b86daca11",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "allowance",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44528c1898e30df62037a76e0c45123f4f4437336ca63236b10ebfc16a5edb78",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fcc296caa05679d0d11121e7629b29f222a857018f50985046b73a56e9a10701",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "balance_of",\n "args": [\n {\n "name": "address",\n "cl_type": "Key"\n }\n ],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-768c370eb010604bd19029a409dca8b5fbf9af9bc14a36c2b294a2a7a922161e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "burn",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bab8615f758ed79acb7dd7577b1a6c12d625d1a19592a2b1ded0dc352407e4d5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_events_mode",\n "args": [\n {\n "name": "events_mode",\n "cl_type": "U8"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-82a811993cf9ccb5e46c9608c69d86e3c9b7b499520fd48cdca1424f2a08efdc",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "change_security",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "condor",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-be138e764d5f26cd174471e18c82a7bef961da4c7e7ade7df068038aebdda9bf",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decimals",\n "args": [],\n "ret": "U8",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-ac07c23dc90a33282d553af890e30e62335c5ae986629d643778e2d4516f26ad",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "decrease_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-a7e05838c728d16c4ba3e1980b6729c857ef4c21d1b0c34e6eefbb486cdc2b89",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "increase_allowance",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "init",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-fc79236fd0e4521c8feddcc2094c6a0ea04fcaafb17fef63ef060744a6bab401",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_sec_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-18bff854e9d908cf20fb1db53a47ab69968917b53b8c71371e7dd0f88b363e60",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_allowance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-1e7babf918642bd9636d3c121691bd85534b41084a5c22fe1e2bf196224dade6",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "migrate_user_balance_keys",\n "args": [\n {\n "name": "events",\n "cl_type": "Bool"\n },\n {\n "name": "revert",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-233964bb1dc667b37a8abbb938d7647b2c4ab41f0c26dbbcd26c62e7870f72ba",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "mint",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-69cade231fc487185af830cfe041ce668a4763ab02ee5989b8baac6bee7e1a22",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "name",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-eef0c71bbea5a76f1da01cb395e12bc0388bec279852100e17e3843b3e559999",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "symbol",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-f99c57f016ee238df5bcdf8bec27869b1ba087a415050a9c6668644eeda11af0",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "total_supply",\n "args": [],\n "ret": "U256",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-3820ce25e54df0470fb738e3e0f63ee50b2719cf2680da2bdb579e21aebc8f63",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer",\n "args": [\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-44208043191e40d3417df6878e1a23894172cf37cf2e4444384ada99e25430e7",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "transfer_from",\n "args": [\n {\n "name": "owner",\n "cl_type": "Key"\n },\n {\n "name": "recipient",\n "cl_type": "Key"\n },\n {\n "name": "amount",\n "cl_type": "U256"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "byte_code_hash": "byte-code-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "main_purse": "uref-4d2ab9ebd75542172d2d94e2c8ebc107e9354c362b9542fdb5c667cb937704fd-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-dc1e638c71901f1e8fd375ce7a9c6eb2f240241b4ca9cbb7abd65ce16f879a22",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "errors",\n "topic_name_hash": "b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc"\n }\n ]\n }\n }\n }\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "message-topic-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-b38b3a8f7a7cb169b9869f1b660e328df63941f4f078d284a0058140375ec7fc",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 0,\n "blocktime": 1721234748003\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-0268d6df10a5edcebe0d3790d2eba676dba455e46a2c880085fdbeca4ab762fb",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1900000063657031385f636f6e74726163745f686173685f4345503138",\n "parsed": "cep18_contract_hash_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-da1fb8c629dc3b127c4cc7e8b09431872aa846af6777bb15b280126ca65663cd",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "021075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a07",\n "parsed": "uref-1075abe4693e237a359a586a9b444a4eb1bef3632bea353ded5ceb260047de0a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "1c00000063657031385f636f6e74726163745f76657273696f6e5f4345503138",\n "parsed": "cep18_contract_version_CEP18"\n }\n }\n }\n }\n },\n {\n "key": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-b2ba71785a4e071a467a03c3a4d3ca827ce5319e4ca92d148e8bcb2142eb4b8e-45ffbf1854843af5eeec6b167e14a9e97bdb526e66205b07559d4fb3928fb11e",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "024bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a7807607",\n "parsed": "uref-4bffd2c60663ad652eb4195ffd9bb7442602180f87b1b5623f5a761b02a78076-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "06000000636f6e646f72",\n "parsed": "condor"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "kind": "Identity"\n },\n {\n "key": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-4ca60287ae6129662475a8ce0d41c450d072b2430a8759f6178adeeff38523da",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-d1db7551d7b5e40760763d2e4e5a253a9c865ab4367e83341bca16548afd5bcd",\n "kind": "Identity"\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-c45567f4859db5b100d4c45a9638973ccdf0a7068a2a50f7a1c8709d5e84fbd2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c",\n "parsed": "package-dea470cf75f60abafcca7c68313f18fc2e21881d607ad75fa65e2bfe547da25c"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0c0000007061636b6167655f68617368",\n "parsed": "package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-d447c1e29c0d374421e2c3f290c580a73aa748eba54e1b6bb3da0acdd4cdcee5",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640",\n "parsed": "entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0d000000636f6e74726163745f68617368",\n "parsed": "contract_hash"\n }\n }\n }\n }\n },\n {\n "key": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-bce0df2b23ec57062235795dd9b7a1a6dc07885918c6cee5c5859a9df3d498e0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e21422207",\n "parsed": "uref-e4bd6745f62350383622b443e5e630ba1cf33833ee04b7c2146ef2be7e214222-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0a000000616c6c6f77616e636573",\n "parsed": "allowances"\n }\n }\n }\n }\n },\n {\n "key": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-058ed80a0c85bcf8470ac5b8ca4c14f1086c3cd5ae00f1f0592fee3addf4073c",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d1707",\n "parsed": "uref-7e3ead4b8b390dfab191c1653c66a5df4cce41cde8a1e3dafd0b3e4e2a177d17-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0800000062616c616e636573",\n "parsed": "balances"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-52d71098e9663be90740263d98e5596d99a9c854beada13b2fa1be0e5ab1dd4b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[190 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-363996106630892a964565574fcdfd2435f21a17a3ad1ed2054146e7d8461640-5f4fd818ad44d4ae056e151759a8585de97a1c7c4d53ceecac6631f9fbb39ab6",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "02a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf07",\n "parsed": "uref-a7e1339377ac39673b01527854f779dd3f1271a68388c6d270c3017ec24a3cdf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0f00000073656375726974795f626164676573",\n "parsed": "security_badges"\n }\n }\n }\n }\n },\n {\n "key": "dictionary-4e62a209ec9eda0bdfffd2039d231751690eb4594bab0744d59ae01f3b44b875",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "[188 hex chars]",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-16baf770d6b97cfa6abe0017ea33f17efdc51236db3b2fa44052080282e19e03-000",\n "kind": "Identity"\n },\n {\n "key": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Prune": "balance-hold-014c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000"\n }\n },\n {\n "key": "balance-hold-004c3f3c8ae53f894ff181b1c2aaa7b5bbea5eb26b30c51887f8e4995a59e933b463f295c190010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-11a9f79f8943382d3bff560b55d3153bf33f7a883b0da8da4ad879c5648a4d5b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-2aed4e1c6a7feaf307b16547e15e48e60c124abe2b93759f9b1d52ae052728ec",\n "kind": "Identity"\n },\n {\n "key": "entity-system-b317612414e2c1f864730f98386c906db6ea330555f57ba2e5c50daca8eec817",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c1100300",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04d730fa16e3b224925bf84493506b8b726aa425ad7b17463d1a2dccb4c11003003900000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e9f55f093d23c687d249f63e7ffaa567560500e794751c0ca897af06af3e5102",\n "era_id": 57,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"We want to draw your attention to a few properties in the example output:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Execution consumed 371736413663 motes, which is less than our ",(0,t.jsx)(n.code,{children:"gas price tolerance"})," of 1000000000000. Read about ",(0,t.jsx)(n.a,{href:"#gas-cost-for-transactions",children:"gas cost for transactions"})]}),"\n",(0,t.jsxs)(n.li,{children:['The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,t.jsx)(n.code,{children:"--gas-price-tolerance"})," arg"]}),"\n",(0,t.jsx)(n.li,{children:"The time-to-live was 30 minutes"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["It is also possible to get a summary of the transaction's information by performing a ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address <HOST:PORT>\n\ncasper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX-STRING> \\\n --state-root-hash <STATE-ROOT-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address <HOST:PORT> \\\n --key transaction-<TRANSACTION-HASH-HEX STRING>\n --block-hash <BLOCK-HASH-HEX-STRING>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Run the help command for ",(0,t.jsx)(n.code,{children:"query-global-state"})," to see its usage."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"ttl",children:"Time-to-live"}),"\n",(0,t.jsxs)(n.p,{children:["Time-to-live is the parameter that determines how long a transaction will wait for execution. The acceptable maximum ",(0,t.jsx)(n.code,{children:"ttl"})," is configurable by chain, with the Casper Mainnet maximum set to ",(0,t.jsx)(n.code,{children:"18hours"}),". If you are sending a transaction to a different network, you will need to check ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid transaction."]}),"\n",(0,t.jsxs)(n.p,{children:["In the event of a network outage or other event that prevents execution within the ",(0,t.jsx)(n.code,{children:"ttl"}),", the solution is to resend the transaction in question."]}),"\n",(0,t.jsxs)(n.p,{children:["Should the transaction's ",(0,t.jsx)(n.code,{children:"ttl"})," exceed the allowable limit, or if the transaction expires, the network's transaction acceptor will find the transaction invalid and return a warning."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-payments",children:"Legacy Deploy Payments"}),"\n",(0,t.jsxs)(n.p,{children:["Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution. All legacy deploys will go through the ",(0,t.jsx)(n.code,{children:"session"})," subcommand for ",(0,t.jsx)(n.code,{children:"put-txn"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,t.jsx)(n.strong,{children:"empty"})," ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," as your payment code. However, you must specify the amount within a runtime argument. ",(0,t.jsx)(n.code,{children:"ModuleBytes"})," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."]}),"\n",(0,t.jsx)(n.p,{children:"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredContractByName"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByHash"})]}),"\n",(0,t.jsxs)(n.p,{children:["\u2022\t",(0,t.jsx)(n.code,{children:"StoredVersionContractByName"})]}),"\n",(0,t.jsx)(n.h2,{id:"using-arguments-with-transactions",children:"Using Arguments with Transactions"}),"\n",(0,t.jsxs)(n.p,{children:["The session Wasm (or payment Wasm if you choose to ",(0,t.jsx)(n.em,{children:"not"}),' use the standard payment) of a Transaction often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,t.jsx)(n.code,{children:"--session-arg"})," or ",(0,t.jsx)(n.code,{children:"--payment-arg"})," options, once for each arg required. The Casper client provides some examples of how to do this:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-txn session --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"advanced-features",children:"Advanced Features"}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks support complex transactions using multiple signatures. ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Casper Accounts"})," use a powerful permissions model that enables a multi-signature scheme for transactions."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"put-transaction"})," command performs multiple actions under the hood, optimizing the typical use case. It creates a transaction, signs it, and sends the Transaction to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-transaction"})," - Creates a Transaction and outputs it to a file or stdout. As a file, the transaction can subsequently be signed by other parties using the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," subcommand and then sent to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-transaction"})," subcommand"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-transaction"})," - Reads a previously-saved Transaction from a file, cryptographically signs it, and outputs it to a file or stdout"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-transaction"})," - Reads a previously-saved Transaction from a file and sends it to the network for execution"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To sign a Transaction with multiple keys, create the Transaction with the ",(0,t.jsx)(n.code,{children:"make-transaction"})," command. The generated transaction file can be sent to the other signers, who then sign it with their keys by calling the ",(0,t.jsx)(n.code,{children:"sign-transaction"})," for each key. Signatures need to be gathered on the Transaction one after another until all required parties have signed the Transaction. Finally, the signed Transaction is sent to the network with the ",(0,t.jsx)(n.code,{children:"send-transaction"})," command for processing."]}),"\n",(0,t.jsxs)(n.p,{children:["For a step-by-step workflow, visit the ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Two-Party Multi-Signature Transaction"})," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network."]}),"\n",(0,t.jsx)(n.h2,{id:"gas-cost-for-transactions",children:"Gas Cost for Transactions"}),"\n",(0,t.jsx)(n.p,{children:'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'}),"\n",(0,t.jsxs)(n.p,{children:["We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the transaction. If you plan on sending a transaction to ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", you can use the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to estimate the payment amount needed for the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:['Casper\'s "Condor" release introduces a new payment system that includes the concept of ',(0,t.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"fee elimination"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["If your test configuration matches your production ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),", you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,t.jsx)(n.a,{href:"/runtime#gas-allocation",children:"runtime economics"})," section for more details about gas usage and fees."]}),"\n",(0,t.jsxs)(n.p,{children:["Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See ",(0,t.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,t.jsxs)(n.p,{children:["If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,t.jsx)(n.a,{href:"/concepts/serialization/types#executionresultv2",children:"failed execution"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"However, if the failure occurs prior to session execution, the penalty payment will not appear in the transaction's gas cost. Depending on the network configuration, the system will deduct the processing fee from the sending account's main purse or place a processing hold on the purse."}),"\n",(0,t.jsx)(n.h2,{id:"common-errors-related-to-payments",children:"Common Errors Related to Payments"}),"\n",(0,t.jsx)(n.h3,{id:"out-of-gas-error",children:"Out of gas error"}),"\n",(0,t.jsx)(n.p,{children:'You might encounter an "Out of gas error" when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.'}),"\n",(0,t.jsxs)(n.p,{children:["Here is an ",(0,t.jsx)(n.a,{href:"https://cspr.live/deploy/afeb43036c41e667af8bc34782c48a66cf4da3818defe9f761291fa515cc38b9",children:"example"}),' of a transaction that resulted in an "Out of gas error" on the Mainnet.']}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 1"}),": In the Deploys tab of an account on ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),', a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an "Out of gas error".']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Out of gas error",src:a(1204).A+"",width:"2048",height:"1118"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 2"}),": Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in account",src:a(10197).A+"",width:"1698",height:"824"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Figure 3"}),": Click the ",(0,t.jsx)(n.strong,{children:"Show raw data"})," button, to see more details about the deploy. Towards the end of the raw data, you can see the error message."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Gas error in raw data",src:a(82318).A+"",width:"1472",height:"424"})}),"\n",(0,t.jsx)(n.h3,{id:"gas-limit-error",children:"Gas limit error"}),"\n",(0,t.jsx)(n.p,{children:'You may sometimes see an error such as "payment: 2.5, cost: 2.5, Error::GasLimit". This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error.'}),"\n",(0,t.jsx)(n.p,{children:"This error message tries to communicate that execution stopped at 2.5 CSPR, and the transaction did not run to completion. In other words, the computation resulted in an error because there were insufficient funds for the transaction to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution and charged that much, resulting in a failed transaction. The execution engine does not know how much it would have cost if allowed to run to completion because it did not allow the transaction to finish since it would have run over its gas limit."}),"\n",(0,t.jsx)(n.p,{children:"In summary, when a transaction hits its gas limit (the payment amount), execution stops."})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},10197:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-account-75086cfae6160dfca8cce66fc2b80f44.png"},1204:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-deploys-82cd87f7fc9013f4a7da13e4dd6123e3.png"},82318:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/error-raw-5b014abd0817fd1c15b225a083a68e3a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/6fe126b9.1e04b30e.js b/assets/js/6fe126b9.1e04b30e.js deleted file mode 100644 index 69f0a85e8..000000000 --- a/assets/js/6fe126b9.1e04b30e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8950],{82244:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="L",a={id:"concepts/glossary/L",title:"L",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/L.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/L",permalink:"/concepts/glossary/L",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"K",permalink:"/concepts/glossary/K"},next:{title:"M",permalink:"/concepts/glossary/M"}},l={},h=[{value:"Liveness",id:"liveness",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"l",children:"L"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"liveness",children:"Liveness"}),"\n",(0,n.jsx)(e.p,{children:"A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions)."}),"\n",(0,n.jsx)(e.p,{children:"If the protocol is not live, the blockchain does not grow anymore, and the network stalls."})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/6fe126b9.e52a98b9.js b/assets/js/6fe126b9.e52a98b9.js new file mode 100644 index 000000000..ff9c1ad64 --- /dev/null +++ b/assets/js/6fe126b9.e52a98b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98950],{82244:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="L",a={id:"concepts/glossary/L",title:"L",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/L.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/L",permalink:"/1.5.X/concepts/glossary/L",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"K",permalink:"/1.5.X/concepts/glossary/K"},next:{title:"M",permalink:"/1.5.X/concepts/glossary/M"}},l={},h=[{value:"Liveness",id:"liveness",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"l",children:"L"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"liveness",children:"Liveness"}),"\n",(0,n.jsx)(e.p,{children:"A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions)."}),"\n",(0,n.jsx)(e.p,{children:"If the protocol is not live, the blockchain does not grow anymore, and the network stalls."})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/705e93ef.1d983d05.js b/assets/js/705e93ef.1d983d05.js deleted file mode 100644 index 4994b9596..000000000 --- a/assets/js/705e93ef.1d983d05.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8729],{52314:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>d,metadata:()=>o,toc:()=>a});var t=s(74848),r=s(28453);const d={},i="Overview of Casper dApps",o={id:"developers/dapps/index",title:"Overview of Casper dApps",description:"The following topics are essential for developers building decentralized applications on a Casper network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/index.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/",permalink:"/developers/dapps/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"CLType",permalink:"/developers/json-rpc/types_cl"},next:{title:"What is a dApp?",permalink:"/developers/dapps/dapp"}},p={},a=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"overview-of-casper-dapps",children:"Overview of Casper dApps"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics are essential for developers building decentralized applications on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/dapp",children:"Introducing dApps"})}),(0,t.jsx)(n.td,{children:"Introducing dApps on a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/prerequisites",children:"Prerequisites for Building dApps"})}),(0,t.jsx)(n.td,{children:"Recommended setup for building dApps on Casper"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/sdk",children:"SDK Client Libraries"})}),(0,t.jsx)(n.td,{children:"Client-side libraries providing ways to interact with a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/technology-stack",children:"dApp Technology Stack"})}),(0,t.jsx)(n.td,{children:"Building the front-end, backend, and on-chain logic of a dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/template-frontend",children:"Front-end Template with React"})}),(0,t.jsx)(n.td,{children:"Use the Casper JS SDK with React to build a dApp fron-tend"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/signing-a-deploy",children:"Signing Deploys"})}),(0,t.jsx)(n.td,{children:"Details about the signatures required for deploys"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"Setting up a Local Network with NCTL"})}),(0,t.jsx)(n.td,{children:"Learn to set up a local test network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),(0,t.jsx)(n.td,{children:"Test deploys locally before sending them to a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"})}),(0,t.jsx)(n.td,{children:"How dApps can listen for emitted events and perform actions based on event data"})]})]})]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var t=s(96540);const r={},d=t.createContext(r);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/705e93ef.e6ce9050.js b/assets/js/705e93ef.e6ce9050.js new file mode 100644 index 000000000..1d0035f12 --- /dev/null +++ b/assets/js/705e93ef.e6ce9050.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28729],{52314:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>p,contentTitle:()=>i,default:()=>c,frontMatter:()=>d,metadata:()=>o,toc:()=>a});var t=s(74848),r=s(28453);const d={},i="Overview of Casper dApps",o={id:"developers/dapps/index",title:"Overview of Casper dApps",description:"The following topics are essential for developers building decentralized applications on a Casper network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/index.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/",permalink:"/1.5.X/developers/dapps/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"CLType",permalink:"/1.5.X/developers/json-rpc/types_cl"},next:{title:"What is a dApp?",permalink:"/1.5.X/developers/dapps/dapp"}},p={},a=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"overview-of-casper-dapps",children:"Overview of Casper dApps"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics are essential for developers building decentralized applications on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/dapp",children:"Introducing dApps"})}),(0,t.jsx)(n.td,{children:"Introducing dApps on a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/prerequisites",children:"Prerequisites for Building dApps"})}),(0,t.jsx)(n.td,{children:"Recommended setup for building dApps on Casper"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/sdk",children:"SDK Client Libraries"})}),(0,t.jsx)(n.td,{children:"Client-side libraries providing ways to interact with a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/technology-stack",children:"dApp Technology Stack"})}),(0,t.jsx)(n.td,{children:"Building the front-end, backend, and on-chain logic of a dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/template-frontend",children:"Front-end Template with React"})}),(0,t.jsx)(n.td,{children:"Use the Casper JS SDK with React to build a dApp fron-tend"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/signing-a-deploy",children:"Signing Deploys"})}),(0,t.jsx)(n.td,{children:"Details about the signatures required for deploys"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"Setting up a Local Network with NCTL"})}),(0,t.jsx)(n.td,{children:"Learn to set up a local test network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),(0,t.jsx)(n.td,{children:"Test deploys locally before sending them to a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"})}),(0,t.jsx)(n.td,{children:"How dApps can listen for emitted events and perform actions based on event data"})]})]})]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var t=s(96540);const r={},d=t.createContext(r);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/709dfa47.62b3e248.js b/assets/js/709dfa47.62b3e248.js deleted file mode 100644 index 6b42e06e9..000000000 --- a/assets/js/709dfa47.62b3e248.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3297],{34238:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Build on Casper",slug:"build-on-casper/introduction"},o="Building on Casper",a={id:"resources/build-on-casper",title:"Build on Casper",description:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.",source:"@site/versioned_docs/version-1.5.X/resources/build-on-casper.md",sourceDirName:"resources",slug:"/resources/build-on-casper/introduction",permalink:"/resources/build-on-casper/introduction",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Build on Casper",slug:"build-on-casper/introduction"},sidebar:"resources",previous:{title:"Resources Overview",permalink:"/resources/"},next:{title:"Move to Casper",permalink:"/resources/moving-to-casper"}},l={},c=[{value:"Thriving Ecosystem",id:"thriving-ecosystem",level:2},{value:"Wallets",id:"wallets",level:3},{value:"Block Explorers",id:"block-explorers",level:3},{value:"Developer Tools",id:"developer-tools",level:3},{value:"Open Source Software",id:"open-source-software",level:3},{value:"Developer-Friendly Language",id:"developer-friendly-language",level:2},{value:"Powerful Accounts",id:"powerful-accounts",level:2},{value:"Contract Upgrades",id:"contract-upgrades",level:2},{value:"Development Tools",id:"development-tools",level:2},{value:"IDE Integration",id:"ide-integration",level:3},{value:"CI/CD",id:"ci-cd",level:3},{value:"Local Network Testing",id:"local-network-testing",level:3},{value:"Public Mainnet and Testnet",id:"public-mainnet-and-testnet",level:3},{value:"AWS",id:"aws",level:3},{value:"SDK Client Libraries",id:"sdk-client-libraries",level:2},{value:"Low Gas Fees",id:"low-gas-fees",level:2}];function d(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"building-on-casper",children:"Building on Casper"})}),"\n",(0,t.jsx)(n.p,{children:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#thriving-ecosystem",children:"Thriving Ecosystem"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#developer-friendly-language",children:"Developer-Friendly Language"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#powerful-accounts",children:"Powerful Accounts"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#contract-upgrades",children:"Contract Upgrades"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#development-tools",children:"Development Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#low-gas-fees",children:"Low Gas Fees"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"thriving-ecosystem",children:"Thriving Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use."}),"\n",(0,t.jsx)(n.h3,{id:"wallets",children:"Wallets"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper.tor.us",children:"Tor.us"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://metamask.io/",children:"Metamask"})," with ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-manager",children:"Casper Snap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in/",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"developer-tools",children:"Developer Tools"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casperholders.io",children:"casperholders.io"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://nownodes.io/nodes/casper-cspr",children:"NOWNodes.io"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"open-source-software",children:"Open Source Software"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open Source Software"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"developer-friendly-language",children:"Developer-Friendly Language"}),"\n",(0,t.jsx)(n.p,{children:"Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.p,{children:["Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Open_standard",children:"open standard"})," for performance and portability of modern web applications."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available."})}),"\n",(0,t.jsx)(n.h2,{id:"powerful-accounts",children:"Powerful Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-permissions",children:"Casper Permissions Model"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-upgrades",children:"Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts."}),"\n",(0,t.jsx)(n.h2,{id:"development-tools",children:"Development Tools"}),"\n",(0,t.jsx)(n.h3,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,t.jsx)(n.p,{children:"The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started."}),"\n",(0,t.jsx)(n.h3,{id:"ci-cd",children:"CI/CD"}),"\n",(0,t.jsx)(n.p,{children:"Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline."}),"\n",(0,t.jsx)(n.h3,{id:"local-network-testing",children:"Local Network Testing"}),"\n",(0,t.jsxs)(n.p,{children:["We also offer a tool to run a ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"local Casper Network"})," Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface."]}),"\n",(0,t.jsx)(n.h3,{id:"public-mainnet-and-testnet",children:"Public Mainnet and Testnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"Mainnet"})," is a public, open-source, community-driven ecosystem. You can also explore the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live",children:"Testnet"})," to test drive your applications and estimate gas costs."]}),"\n",(0,t.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,t.jsx)(n.p,{children:"We also offer several tools to run AWS instances of Casper nodes."}),"\n",(0,t.jsx)(n.h2,{id:"sdk-client-libraries",children:"SDK Client Libraries"}),"\n",(0,t.jsxs)(n.p,{children:["In addition to the default ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"command-line Rust client"}),", the Casper community is building ",(0,t.jsx)(n.a,{href:"/sdk",children:"other clients"})," in JavaScript, Java, Golang, Python, C#, and other languages."]}),"\n",(0,t.jsx)(n.h2,{id:"low-gas-fees",children:"Low Gas Fees"}),"\n",(0,t.jsx)(n.p,{children:"Casper seeks to eliminate volatility and improve developer and enterprise experiences by establishing transparent, consistent, and low gas prices. This feature seeks to promote active and diverse network behaviour and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/709dfa47.969b3e76.js b/assets/js/709dfa47.969b3e76.js new file mode 100644 index 000000000..b7385a47d --- /dev/null +++ b/assets/js/709dfa47.969b3e76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83297],{34238:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Build on Casper",slug:"build-on-casper/introduction"},o="Building on Casper",a={id:"resources/build-on-casper",title:"Build on Casper",description:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.",source:"@site/versioned_docs/version-1.5.X/resources/build-on-casper.md",sourceDirName:"resources",slug:"/resources/build-on-casper/introduction",permalink:"/1.5.X/resources/build-on-casper/introduction",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Build on Casper",slug:"build-on-casper/introduction"},sidebar:"resources",previous:{title:"Resources Overview",permalink:"/1.5.X/resources/"},next:{title:"Move to Casper",permalink:"/1.5.X/resources/moving-to-casper"}},l={},c=[{value:"Thriving Ecosystem",id:"thriving-ecosystem",level:2},{value:"Wallets",id:"wallets",level:3},{value:"Block Explorers",id:"block-explorers",level:3},{value:"Developer Tools",id:"developer-tools",level:3},{value:"Open Source Software",id:"open-source-software",level:3},{value:"Developer-Friendly Language",id:"developer-friendly-language",level:2},{value:"Powerful Accounts",id:"powerful-accounts",level:2},{value:"Contract Upgrades",id:"contract-upgrades",level:2},{value:"Development Tools",id:"development-tools",level:2},{value:"IDE Integration",id:"ide-integration",level:3},{value:"CI/CD",id:"ci-cd",level:3},{value:"Local Network Testing",id:"local-network-testing",level:3},{value:"Public Mainnet and Testnet",id:"public-mainnet-and-testnet",level:3},{value:"AWS",id:"aws",level:3},{value:"SDK Client Libraries",id:"sdk-client-libraries",level:2},{value:"Low Gas Fees",id:"low-gas-fees",level:2}];function d(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"building-on-casper",children:"Building on Casper"})}),"\n",(0,t.jsx)(n.p,{children:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#thriving-ecosystem",children:"Thriving Ecosystem"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#developer-friendly-language",children:"Developer-Friendly Language"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#powerful-accounts",children:"Powerful Accounts"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#contract-upgrades",children:"Contract Upgrades"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#development-tools",children:"Development Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#low-gas-fees",children:"Low Gas Fees"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"thriving-ecosystem",children:"Thriving Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use."}),"\n",(0,t.jsx)(n.h3,{id:"wallets",children:"Wallets"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper.tor.us",children:"Tor.us"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://metamask.io/",children:"Metamask"})," with ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-manager",children:"Casper Snap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in/",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"developer-tools",children:"Developer Tools"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casperholders.io",children:"casperholders.io"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://nownodes.io/nodes/casper-cspr",children:"NOWNodes.io"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"open-source-software",children:"Open Source Software"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open Source Software"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"developer-friendly-language",children:"Developer-Friendly Language"}),"\n",(0,t.jsx)(n.p,{children:"Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.p,{children:["Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Open_standard",children:"open standard"})," for performance and portability of modern web applications."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available."})}),"\n",(0,t.jsx)(n.h2,{id:"powerful-accounts",children:"Powerful Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-permissions",children:"Casper Permissions Model"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-upgrades",children:"Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts."}),"\n",(0,t.jsx)(n.h2,{id:"development-tools",children:"Development Tools"}),"\n",(0,t.jsx)(n.h3,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,t.jsx)(n.p,{children:"The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started."}),"\n",(0,t.jsx)(n.h3,{id:"ci-cd",children:"CI/CD"}),"\n",(0,t.jsx)(n.p,{children:"Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline."}),"\n",(0,t.jsx)(n.h3,{id:"local-network-testing",children:"Local Network Testing"}),"\n",(0,t.jsxs)(n.p,{children:["We also offer a tool to run a ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"local Casper Network"})," Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface."]}),"\n",(0,t.jsx)(n.h3,{id:"public-mainnet-and-testnet",children:"Public Mainnet and Testnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"Mainnet"})," is a public, open-source, community-driven ecosystem. You can also explore the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live",children:"Testnet"})," to test drive your applications and estimate gas costs."]}),"\n",(0,t.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,t.jsx)(n.p,{children:"We also offer several tools to run AWS instances of Casper nodes."}),"\n",(0,t.jsx)(n.h2,{id:"sdk-client-libraries",children:"SDK Client Libraries"}),"\n",(0,t.jsxs)(n.p,{children:["In addition to the default ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"command-line Rust client"}),", the Casper community is building ",(0,t.jsx)(n.a,{href:"/sdk",children:"other clients"})," in JavaScript, Java, Golang, Python, C#, and other languages."]}),"\n",(0,t.jsx)(n.h2,{id:"low-gas-fees",children:"Low Gas Fees"}),"\n",(0,t.jsx)(n.p,{children:"Casper seeks to eliminate volatility and improve developer and enterprise experiences by establishing transparent, consistent, and low gas prices. This feature seeks to promote active and diverse network behaviour and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72106d8f.bdea1c52.js b/assets/js/72106d8f.bdea1c52.js new file mode 100644 index 000000000..0597e69c5 --- /dev/null +++ b/assets/js/72106d8f.bdea1c52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7283],{43937:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"2.0.0","label":"2.0.0","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-2.0.0","isLast":false,"docsSidebars":{"concepts":[{"type":"link","label":"Overview","href":"/2.0.0/concepts/","docId":"concepts/index","unlisted":false},{"type":"link","label":"What is Casper?","href":"/2.0.0/concepts/about","docId":"concepts/about","unlisted":false},{"type":"category","label":"Design","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Network Design","href":"/2.0.0/concepts/design/casper-design","docId":"concepts/design/casper-design","unlisted":false},{"type":"link","label":"Network Communication","href":"/2.0.0/concepts/design/p2p","docId":"concepts/design/p2p","unlisted":false},{"type":"category","label":"Consensus","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Zug Consensus","href":"/2.0.0/concepts/design/zug","docId":"concepts/design/zug","unlisted":false},{"type":"link","label":"Highway Consensus","href":"/2.0.0/concepts/design/highway","docId":"concepts/design/highway","unlisted":false}],"href":"/2.0.0/concepts/design/consensus"},{"type":"link","label":"Rewards Design","href":"/2.0.0/concepts/design/rewards","docId":"concepts/design/rewards","unlisted":false},{"type":"link","label":"Reading and Writing Data","href":"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain","docId":"concepts/design/reading-and-writing-to-the-blockchain","unlisted":false}],"href":"/2.0.0/design"},{"type":"category","label":"Economics","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Consensus","href":"/2.0.0/concepts/economics/consensus","docId":"concepts/economics/consensus","unlisted":false},{"type":"link","label":"Runtime","href":"/2.0.0/runtime","docId":"concepts/economics/runtime","unlisted":false},{"type":"link","label":"Gas Cost","href":"/2.0.0/concepts/economics/gas-concepts","docId":"concepts/economics/gas-concepts","unlisted":false},{"type":"link","label":"Dynamic Gas Pricing","href":"/2.0.0/concepts/economics/dynamic-gas-pricing","docId":"concepts/economics/dynamic-gas-pricing","unlisted":false},{"type":"link","label":"Fee Elimination","href":"/2.0.0/concepts/economics/fee-elimination","docId":"concepts/economics/fee-elimination","unlisted":false},{"type":"link","label":"Staking","href":"/2.0.0/concepts/economics/staking","docId":"concepts/economics/staking","unlisted":false}],"href":"/2.0.0/economics"},{"type":"category","label":"Glossary","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"A","href":"/2.0.0/concepts/glossary/A","docId":"concepts/glossary/A","unlisted":false},{"type":"link","label":"B","href":"/2.0.0/concepts/glossary/B","docId":"concepts/glossary/B","unlisted":false},{"type":"link","label":"C","href":"/2.0.0/concepts/glossary/C","docId":"concepts/glossary/C","unlisted":false},{"type":"link","label":"D","href":"/2.0.0/concepts/glossary/D","docId":"concepts/glossary/D","unlisted":false},{"type":"link","label":"E","href":"/2.0.0/concepts/glossary/E","docId":"concepts/glossary/E","unlisted":false},{"type":"link","label":"F","href":"/2.0.0/concepts/glossary/F","docId":"concepts/glossary/F","unlisted":false},{"type":"link","label":"G","href":"/2.0.0/concepts/glossary/G","docId":"concepts/glossary/G","unlisted":false},{"type":"link","label":"H","href":"/2.0.0/concepts/glossary/H","docId":"concepts/glossary/H","unlisted":false},{"type":"link","label":"I","href":"/2.0.0/concepts/glossary/I","docId":"concepts/glossary/I","unlisted":false},{"type":"link","label":"J","href":"/2.0.0/concepts/glossary/J","docId":"concepts/glossary/J","unlisted":false},{"type":"link","label":"K","href":"/2.0.0/concepts/glossary/K","docId":"concepts/glossary/K","unlisted":false},{"type":"link","label":"L","href":"/2.0.0/concepts/glossary/L","docId":"concepts/glossary/L","unlisted":false},{"type":"link","label":"M","href":"/2.0.0/concepts/glossary/M","docId":"concepts/glossary/M","unlisted":false},{"type":"link","label":"N","href":"/2.0.0/concepts/glossary/N","docId":"concepts/glossary/N","unlisted":false},{"type":"link","label":"O","href":"/2.0.0/concepts/glossary/O","docId":"concepts/glossary/O","unlisted":false},{"type":"link","label":"P","href":"/2.0.0/concepts/glossary/P","docId":"concepts/glossary/P","unlisted":false},{"type":"link","label":"Q","href":"/2.0.0/concepts/glossary/Q","docId":"concepts/glossary/Q","unlisted":false},{"type":"link","label":"R","href":"/2.0.0/concepts/glossary/R","docId":"concepts/glossary/R","unlisted":false},{"type":"link","label":"S","href":"/2.0.0/concepts/glossary/S","docId":"concepts/glossary/S","unlisted":false},{"type":"link","label":"T","href":"/2.0.0/concepts/glossary/T","docId":"concepts/glossary/T","unlisted":false},{"type":"link","label":"U","href":"/2.0.0/concepts/glossary/U","docId":"concepts/glossary/U","unlisted":false},{"type":"link","label":"V","href":"/2.0.0/concepts/glossary/V","docId":"concepts/glossary/V","unlisted":false},{"type":"link","label":"W","href":"/2.0.0/concepts/glossary/W","docId":"concepts/glossary/W","unlisted":false},{"type":"link","label":"X","href":"/2.0.0/concepts/glossary/X","docId":"concepts/glossary/X","unlisted":false},{"type":"link","label":"Y","href":"/2.0.0/concepts/glossary/Y","docId":"concepts/glossary/Y","unlisted":false},{"type":"link","label":"Z","href":"/2.0.0/concepts/glossary/Z","docId":"concepts/glossary/Z","unlisted":false}],"href":"/2.0.0/glossary"},{"type":"category","label":"Binary Serialization Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Primitives and Basic Serialization Rules","href":"/2.0.0/concepts/serialization/primitives","docId":"concepts/serialization/primitives","unlisted":false},{"type":"link","label":"Major Structures","href":"/2.0.0/concepts/serialization/structures","docId":"concepts/serialization/structures","unlisted":false},{"type":"link","label":"Type Serialization","href":"/2.0.0/concepts/serialization/types","docId":"concepts/serialization/types","unlisted":false}],"href":"/2.0.0/concepts/serialization/"},{"type":"link","label":"dApps","href":"/2.0.0/concepts/intro-to-dapps","docId":"concepts/intro-to-dapps","unlisted":false},{"type":"link","label":"Addressable Entities","href":"/2.0.0/concepts/addressable-entity","docId":"concepts/addressable-entity","unlisted":false},{"type":"link","label":"Accounts and Keys","href":"/2.0.0/concepts/accounts-and-keys","docId":"concepts/accounts-and-keys","unlisted":false},{"type":"link","label":"Key Types","href":"/2.0.0/concepts/key-types","docId":"concepts/key-types","unlisted":false},{"type":"link","label":"Transaction Lifecycle","href":"/2.0.0/transactions-and-transaction-lifecycle","docId":"concepts/transactions-and-transaction-lifecycle","unlisted":false},{"type":"link","label":"Global State","href":"/2.0.0/concepts/global-state","docId":"concepts/global-state","unlisted":false},{"type":"link","label":"Smart Contracts","href":"/2.0.0/concepts/smart-contracts","docId":"concepts/smart-contracts","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/2.0.0/concepts/list-auth-keys","docId":"concepts/list-auth-keys","unlisted":false},{"type":"link","label":"Call Stacks","href":"/2.0.0/concepts/callstack","docId":"concepts/callstack","unlisted":false},{"type":"link","label":"Dictionaries","href":"/2.0.0/concepts/dictionaries","docId":"concepts/dictionaries","unlisted":false}],"developers":[{"type":"link","label":"Overview","href":"/2.0.0/developers","docId":"developers/index","unlisted":false},{"type":"link","label":"Development Prerequisites","href":"/2.0.0/developers/prerequisites","docId":"developers/prerequisites","unlisted":false},{"type":"link","label":"Essential Rust Crates","href":"/2.0.0/developers/essential-crates","docId":"developers/essential-crates","unlisted":false},{"type":"category","label":"Writing On-Chain Code","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started with Rust","href":"/2.0.0/developers/writing-onchain-code/getting-started","docId":"developers/writing-onchain-code/getting-started","unlisted":false},{"type":"link","label":"Getting Started with AssemblyScript","href":"/2.0.0/developers/writing-onchain-code/assembly-script","docId":"developers/writing-onchain-code/assembly-script","unlisted":false},{"type":"link","label":"Writing a Basic Smart Contract in Rust","href":"/2.0.0/developers/writing-onchain-code/simple-contract","docId":"developers/writing-onchain-code/simple-contract","unlisted":false},{"type":"link","label":"Testing Smart Contracts","href":"/2.0.0/developers/writing-onchain-code/testing-contracts","docId":"developers/writing-onchain-code/testing-contracts","unlisted":false},{"type":"link","label":"Upgrading and Maintaining Smart Contracts","href":"/2.0.0/developers/writing-onchain-code/upgrading-contracts","docId":"developers/writing-onchain-code/upgrading-contracts","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/2.0.0/developers/writing-onchain-code/calling-contracts","docId":"developers/writing-onchain-code/calling-contracts","unlisted":false},{"type":"link","label":"Contracts and Session Code","href":"/2.0.0/developers/writing-onchain-code/contract-vs-session","docId":"developers/writing-onchain-code/contract-vs-session","unlisted":false},{"type":"link","label":"Writing Session Code","href":"/2.0.0/developers/writing-onchain-code/writing-session-code","docId":"developers/writing-onchain-code/writing-session-code","unlisted":false},{"type":"link","label":"Testing Session Code","href":"/2.0.0/developers/writing-onchain-code/testing-session-code","docId":"developers/writing-onchain-code/testing-session-code","unlisted":false},{"type":"link","label":"Contract-Level Events","href":"/2.0.0/developers/writing-onchain-code/emitting-contract-events","docId":"developers/writing-onchain-code/emitting-contract-events","unlisted":false},{"type":"link","label":"Contract Hash vs. Package Hash","href":"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash","docId":"developers/writing-onchain-code/contract-hash-vs-package-hash","unlisted":false},{"type":"link","label":"Factory Contracts","href":"/2.0.0/developers/writing-onchain-code/factory-pattern","docId":"developers/writing-onchain-code/factory-pattern","unlisted":false},{"type":"link","label":"Best Practices for Casper Smart Contract Authors","href":"/2.0.0/developers/writing-onchain-code/best-practices","docId":"developers/writing-onchain-code/best-practices","unlisted":false}],"href":"/2.0.0/writing-contracts"},{"type":"category","label":"Casper JSON-RPC API","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Guidance for JSON-RPC SDK Compliance","href":"/2.0.0/developers/json-rpc/guidance","docId":"developers/json-rpc/guidance","unlisted":false},{"type":"link","label":"Required Methods for Minimal Compliance","href":"/2.0.0/developers/json-rpc/minimal-compliance","docId":"developers/json-rpc/minimal-compliance","unlisted":false},{"type":"link","label":"Transactional JSON-RPC Methods","href":"/2.0.0/developers/json-rpc/json-rpc-transactional","docId":"developers/json-rpc/json-rpc-transactional","unlisted":false},{"type":"link","label":"Informational JSON-RPC Methods","href":"/2.0.0/developers/json-rpc/json-rpc-informational","docId":"developers/json-rpc/json-rpc-informational","unlisted":false},{"type":"link","label":"Proof-of-Stake JSON-RPC Methods","href":"/2.0.0/developers/json-rpc/json-rpc-pos","docId":"developers/json-rpc/json-rpc-pos","unlisted":false},{"type":"link","label":"Types","href":"/2.0.0/developers/json-rpc/types_chain","docId":"developers/json-rpc/types_chain","unlisted":false},{"type":"link","label":"CLType","href":"/2.0.0/developers/json-rpc/types_cl","docId":"developers/json-rpc/types_cl","unlisted":false}],"href":"/2.0.0/developers/json-rpc/"},{"type":"category","label":"Building dApps","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is a dApp?","href":"/2.0.0/developers/dapps/dapp","docId":"developers/dapps/dapp","unlisted":false},{"type":"link","label":"Prerequisites","href":"/2.0.0/developers/dapps/prerequisites","docId":"developers/dapps/prerequisites","unlisted":false},{"type":"category","label":"SDK Client Libraries","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SDK Client Library Usage","href":"/2.0.0/developers/dapps/sdk/client-library-usage","docId":"developers/dapps/sdk/client-library-usage","unlisted":false},{"type":"link","label":"JavaScript/TypeScript SDK","href":"/2.0.0/developers/dapps/sdk/script-sdk","docId":"developers/dapps/sdk/script-sdk","unlisted":false},{"type":"link","label":".NET SDK","href":"/2.0.0/developers/dapps/sdk/csharp-sdk","docId":"developers/dapps/sdk/csharp-sdk","unlisted":false},{"type":"link","label":"Go SDK","href":"/2.0.0/developers/dapps/sdk/go-sdk","docId":"developers/dapps/sdk/go-sdk","unlisted":false},{"type":"link","label":"Python SDK","href":"/2.0.0/developers/dapps/sdk/python-sdk","docId":"developers/dapps/sdk/python-sdk","unlisted":false}],"href":"/2.0.0/sdk"},{"type":"link","label":"dApp Technology Stack","href":"/2.0.0/developers/dapps/technology-stack","docId":"developers/dapps/technology-stack","unlisted":false},{"type":"link","label":"Front-end in React","href":"/2.0.0/developers/dapps/template-frontend","docId":"developers/dapps/template-frontend","unlisted":false},{"type":"link","label":"URef Access Rights","href":"/2.0.0/developers/dapps/uref-security","docId":"developers/dapps/uref-security","unlisted":false},{"type":"link","label":"Signing Transactions","href":"/2.0.0/developers/dapps/signing-a-transaction","docId":"developers/dapps/signing-a-transaction","unlisted":false},{"type":"link","label":"Estimating Gas Costs with Speculative Execution","href":"/2.0.0/developers/dapps/speculative-exec","docId":"developers/dapps/speculative-exec","unlisted":false},{"type":"link","label":"Local Network Setup","href":"/2.0.0/developers/dapps/setup-nctl","docId":"developers/dapps/setup-nctl","unlisted":false},{"type":"link","label":"Local Network Testing","href":"/2.0.0/developers/dapps/nctl-test","docId":"developers/dapps/nctl-test","unlisted":false},{"type":"link","label":"Monitoring Events with the Casper Sidecar","href":"/2.0.0/developers/dapps/monitor-and-consume-events","docId":"developers/dapps/monitor-and-consume-events","unlisted":false}],"href":"/2.0.0/developers/dapps/"},{"type":"category","label":"Interacting with the Blockchain","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Transferring Tokens","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Direct Token Transfer","href":"/2.0.0/developers/cli/transfers/direct-token-transfer","docId":"developers/cli/transfers/direct-token-transfer","unlisted":false},{"type":"link","label":"Transferring Tokens using a Multi-Sig Deploy","href":"/2.0.0/developers/cli/transfers/multisig-deploy-transfer","docId":"developers/cli/transfers/multisig-deploy-transfer","unlisted":false},{"type":"link","label":"Verifying a Transfer","href":"/2.0.0/developers/cli/transfers/verify-transfer","docId":"developers/cli/transfers/verify-transfer","unlisted":false}],"href":"/2.0.0/developers/cli/transfers/"},{"type":"link","label":"Delegating Tokens","href":"/2.0.0/developers/cli/delegate","docId":"developers/cli/delegate","unlisted":false},{"type":"link","label":"Redelegating Tokens with the Casper Client","href":"/2.0.0/developers/cli/redelegate","docId":"developers/cli/redelegate","unlisted":false},{"type":"link","label":"Undelegating Tokens","href":"/2.0.0/developers/cli/undelegate","docId":"developers/cli/undelegate","unlisted":false},{"type":"link","label":"Sending Transactions","href":"/2.0.0/developers/cli/sending-transactions","docId":"developers/cli/sending-transactions","unlisted":false},{"type":"link","label":"Installing Contracts","href":"/2.0.0/developers/cli/installing-contracts","docId":"developers/cli/installing-contracts","unlisted":false},{"type":"link","label":"Verifying Contracts","href":"/2.0.0/developers/cli/verifying-contracts","docId":"developers/cli/verifying-contracts","unlisted":false},{"type":"link","label":"Querying Global State","href":"/2.0.0/developers/cli/querying-global-state","docId":"developers/cli/querying-global-state","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/2.0.0/developers/cli/calling-contracts","docId":"developers/cli/calling-contracts","unlisted":false},{"type":"link","label":"OpCode Costs Tables","href":"/2.0.0/developers/cli/opcode-costs","docId":"developers/cli/opcode-costs","unlisted":false},{"type":"link","label":"Execution Error Codes","href":"/2.0.0/developers/cli/execution-error-codes","docId":"developers/cli/execution-error-codes","unlisted":false}],"href":"/2.0.0/developers/cli/"}],"operators":[{"type":"link","label":"Overview","href":"/2.0.0/operators","docId":"operators/index","unlisted":false},{"type":"category","label":"Node Setup","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Hardware","href":"/2.0.0/operators/setup/hardware","docId":"operators/setup/hardware","unlisted":false},{"type":"link","label":"Configuration","href":"/2.0.0/operators/setup/basic-node-configuration","docId":"operators/setup/basic-node-configuration","unlisted":false},{"type":"link","label":"Endpoints","href":"/2.0.0/operators/setup/node-endpoints","docId":"operators/setup/node-endpoints","unlisted":false},{"type":"link","label":"Installation","href":"/2.0.0/operators/setup/install-node","docId":"operators/setup/install-node","unlisted":false},{"type":"link","label":"Fast Sync","href":"/2.0.0/operators/setup/fast-sync","docId":"operators/setup/fast-sync","unlisted":false},{"type":"link","label":"Open Files Limit","href":"/2.0.0/operators/setup/open-files","docId":"operators/setup/open-files","unlisted":false},{"type":"link","label":"Upgrades","href":"/2.0.0/operators/setup/upgrade","docId":"operators/setup/upgrade","unlisted":false},{"type":"link","label":"Join a Network","href":"/2.0.0/operators/setup/joining","docId":"operators/setup/joining","unlisted":false},{"type":"link","label":"Non-Root Users","href":"/2.0.0/operators/setup/non-root-user","docId":"operators/setup/non-root-user","unlisted":false},{"type":"link","label":"Node Events","href":"/2.0.0/operators/setup/node-events","docId":"operators/setup/node-events","unlisted":false},{"type":"link","label":"Sidecar Setup","href":"/2.0.0/operators/setup/casper-sidecar","docId":"operators/setup/casper-sidecar","unlisted":false}],"href":"/2.0.0/operators/setup/"},{"type":"category","label":"Validators","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bonding","href":"/2.0.0/operators/becoming-a-validator/bonding","docId":"operators/becoming-a-validator/bonding","unlisted":false},{"type":"link","label":"Unbonding","href":"/2.0.0/operators/becoming-a-validator/unbonding","docId":"operators/becoming-a-validator/unbonding","unlisted":false},{"type":"link","label":"Recovery","href":"/2.0.0/operators/becoming-a-validator/recovering","docId":"operators/becoming-a-validator/recovering","unlisted":false},{"type":"link","label":"Inactive and Faulty Nodes","href":"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty","docId":"operators/becoming-a-validator/inactive-vs-faulty","unlisted":false}],"href":"/2.0.0/operators/becoming-a-validator/"},{"type":"category","label":"Private Networks","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Genesis","href":"/2.0.0/operators/setup-network/genesis","docId":"operators/setup-network/genesis","unlisted":false},{"type":"link","label":"The Chainspec","href":"/2.0.0/operators/setup-network/chain-spec","docId":"operators/setup-network/chain-spec","unlisted":false},{"type":"link","label":"Private Network Setup","href":"/2.0.0/operators/setup-network/create-private","docId":"operators/setup-network/create-private","unlisted":false},{"type":"link","label":"Staging Files","href":"/2.0.0/operators/setup-network/staging-files-for-new-network","docId":"operators/setup-network/staging-files-for-new-network","unlisted":false}],"href":"/2.0.0/operators/setup-network/"},{"type":"category","label":"Maintenance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Archive and Restore a DB","href":"/2.0.0/operators/maintenance/archiving-and-restoring","docId":"operators/maintenance/archiving-and-restoring","unlisted":false},{"type":"link","label":"Move a Node","href":"/2.0.0/operators/maintenance/moving-node","docId":"operators/maintenance/moving-node","unlisted":false}],"href":"/2.0.0/operators/maintenance/"}],"resources":[{"type":"link","label":"Resources Overview","href":"/2.0.0/resources/","docId":"resources/index","unlisted":false},{"type":"link","label":"Build on Casper","href":"/2.0.0/resources/build-on-casper/introduction","docId":"resources/build-on-casper","unlisted":false},{"type":"link","label":"Move to Casper","href":"/2.0.0/resources/moving-to-casper","docId":"resources/moving-to-casper","unlisted":false},{"type":"category","label":"Casper Token Standards","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CEP-18 Fungible Token","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"On-chain Installation","href":"/2.0.0/resources/tokens/cep18/quickstart-guide","docId":"resources/tokens/cep18/quickstart-guide","unlisted":false},{"type":"link","label":"CEP-18 Contract Details","href":"/2.0.0/resources/tokens/cep18/query","docId":"resources/tokens/cep18/query","unlisted":false},{"type":"link","label":"CEP-18 Transfers","href":"/2.0.0/resources/tokens/cep18/transfer","docId":"resources/tokens/cep18/transfer","unlisted":false},{"type":"link","label":"Testing Guide","href":"/2.0.0/resources/tokens/cep18/tests","docId":"resources/tokens/cep18/tests","unlisted":false}],"href":"/2.0.0/resources/tokens/cep18/full-tutorial"},{"type":"category","label":"CEP-78 Enhanced NFT Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CEP-78 Modalities","href":"/2.0.0/resources/tokens/cep78/modalities","docId":"resources/tokens/cep78/modalities","unlisted":false},{"type":"link","label":"On-chain Installation","href":"/2.0.0/resources/tokens/using-casper-client","docId":"resources/tokens/cep78/using-casper-client","unlisted":false},{"type":"link","label":"Ownership Lookup","href":"/2.0.0/resources/tokens/cep78/reverse-lookup","docId":"resources/tokens/cep78/reverse-lookup","unlisted":false},{"type":"link","label":"CEP-78 JavaScript Client","href":"/2.0.0/resources/tokens/cep78/js-tutorial","docId":"resources/tokens/cep78/js-tutorial","unlisted":false}],"href":"/2.0.0/resources/tokens/cep78/introduction"}],"href":"/2.0.0/resources/tokens/"},{"type":"link","label":"Open-Source Software","href":"/2.0.0/resources/build-on-casper/casper-open-source-software","docId":"resources/casper-open-source-software","unlisted":false},{"type":"link","label":"Quickstart","href":"/2.0.0/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/2.0.0/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/2.0.0/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/2.0.0/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/2.0.0/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/2.0.0/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/2.0.0/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/2.0.0/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/2.0.0/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/2.0.0/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/2.0.0/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/2.0.0/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/2.0.0/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/2.0.0/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/2.0.0/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/2.0.0/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/2.0.0/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/2.0.0/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/2.0.0/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/2.0.0/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/2.0.0/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/2.0.0/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/2.0.0/resources/tutorials/advanced/"}],"users":[{"type":"link","label":"Users Overview","href":"/2.0.0/users/","docId":"users/index","unlisted":false},{"type":"link","label":"Block Explorers","href":"/2.0.0/users/block-explorer","docId":"users/block-explorer","unlisted":false},{"type":"link","label":"Funding Mainnet Accounts","href":"/2.0.0/users/funding-from-exchanges","docId":"users/funding-from-exchanges","unlisted":false},{"type":"link","label":"Delegating Tokens","href":"/2.0.0/users/delegating","docId":"users/delegating","unlisted":false},{"type":"category","label":"Using CSPR.live","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testnet Funding","href":"/2.0.0/users/testnet-faucet","docId":"users/csprlive/testnet-faucet","unlisted":false},{"type":"link","label":"Delegate Tokens","href":"/2.0.0/users/delegate-ui","docId":"users/csprlive/delegate-ui","unlisted":false},{"type":"link","label":"Undelegate Tokens","href":"/2.0.0/users/undelegate-ui","docId":"users/csprlive/undelegate-ui","unlisted":false},{"type":"link","label":"Transfer Tokens","href":"/2.0.0/users/token-transfer","docId":"users/csprlive/token-transfer","unlisted":false}],"href":"/2.0.0/users/csprlive/"},{"type":"category","label":"Ledger Devices","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Set up Ledger","href":"/2.0.0/workflow/ledger-setup/","docId":"users/ledger/ledger-setup","unlisted":false},{"type":"link","label":"Ledger and Ledger Live","href":"/2.0.0/users/ledger/ledger-live","docId":"users/ledger/ledger-live","unlisted":false},{"type":"link","label":"Ledger and CSPR.live","href":"/2.0.0/users/ledger/ledger-cspr-live","docId":"users/ledger/ledger-cspr-live","unlisted":false},{"type":"link","label":"Delegate with Ledger","href":"/2.0.0/users/staking-ledger","docId":"users/ledger/staking-ledger","unlisted":false}],"href":"/2.0.0/users/ledger/"}],"tutorials":[{"type":"link","label":"Quickstart","href":"/2.0.0/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/2.0.0/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/2.0.0/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/2.0.0/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/2.0.0/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/2.0.0/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/2.0.0/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/2.0.0/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/2.0.0/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/2.0.0/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/2.0.0/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/2.0.0/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/2.0.0/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/2.0.0/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/2.0.0/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/2.0.0/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/2.0.0/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/2.0.0/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/2.0.0/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/2.0.0/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/2.0.0/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/2.0.0/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/2.0.0/resources/tutorials/advanced/"}]},"docs":{"concepts/about":{"id":"concepts/about","title":"What is Casper?","description":"What is Casper?","sidebar":"concepts"},"concepts/accounts-and-keys":{"id":"concepts/accounts-and-keys","title":"Accounts and Keys","description":"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.","sidebar":"concepts"},"concepts/addressable-entity":{"id":"concepts/addressable-entity","title":"Addressable Entities","description":"What is an Addressable Entity?","sidebar":"concepts"},"concepts/callstack":{"id":"concepts/callstack","title":"Call Stacks","description":"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.","sidebar":"concepts"},"concepts/design/casper-design":{"id":"concepts/design/casper-design","title":"Network Design","description":"Introduction","sidebar":"concepts"},"concepts/design/consensus":{"id":"concepts/design/consensus","title":"Consensus in a Casper Network","description":"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network\'s consensus protocol is a mechanism for the validators to agree on each finalized block.","sidebar":"concepts"},"concepts/design/highway":{"id":"concepts/design/highway","title":"Highway Consensus","description":"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.","sidebar":"concepts"},"concepts/design/index":{"id":"concepts/design/index","title":"Design Overview","description":"| Topic | Description |","sidebar":"concepts"},"concepts/design/networking-protocol":{"id":"concepts/design/networking-protocol","title":"Casper Node Networking Protocol","description":"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"},"concepts/design/p2p":{"id":"concepts/design/p2p","title":"Network Communication","description":"communications-head}","sidebar":"concepts"},"concepts/design/reading-and-writing-to-the-blockchain":{"id":"concepts/design/reading-and-writing-to-the-blockchain","title":"Reading and Writing Data","description":"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.","sidebar":"concepts"},"concepts/design/rewards":{"id":"concepts/design/rewards","title":"Rewards Design","description":"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.","sidebar":"concepts"},"concepts/design/zug":{"id":"concepts/design/zug","title":"Zug Consensus","description":"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.","sidebar":"concepts"},"concepts/dictionaries":{"id":"concepts/dictionaries","title":"Dictionaries","description":"dictionaries}","sidebar":"concepts"},"concepts/economics/consensus":{"id":"concepts/economics/consensus","title":"Consensus","description":"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.","sidebar":"concepts"},"concepts/economics/dynamic-gas-pricing":{"id":"concepts/economics/dynamic-gas-pricing","title":"Dynamic Gas Pricing","description":"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.","sidebar":"concepts"},"concepts/economics/fee-elimination":{"id":"concepts/economics/fee-elimination","title":"Fee Elimination","description":"Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled \\"fee elimination\\", also known as the \\"no fee mode\\", or \\"no fee transactions\\" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.","sidebar":"concepts"},"concepts/economics/gas-concepts":{"id":"concepts/economics/gas-concepts","title":"Gas Cost","description":"What is gas?","sidebar":"concepts"},"concepts/economics/index":{"id":"concepts/economics/index","title":"Overview","description":"Casper\'s economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform\'s value.","sidebar":"concepts"},"concepts/economics/runtime":{"id":"concepts/economics/runtime","title":"Runtime","description":"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:","sidebar":"concepts"},"concepts/economics/staking":{"id":"concepts/economics/staking","title":"Staking","description":"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.","sidebar":"concepts"},"concepts/global-state":{"id":"concepts/global-state","title":"Global State","description":"global-state-head}","sidebar":"concepts"},"concepts/glossary/A":{"id":"concepts/glossary/A","title":"A","description":"---","sidebar":"concepts"},"concepts/glossary/B":{"id":"concepts/glossary/B","title":"B","description":"---","sidebar":"concepts"},"concepts/glossary/C":{"id":"concepts/glossary/C","title":"C","description":"---","sidebar":"concepts"},"concepts/glossary/D":{"id":"concepts/glossary/D","title":"D","description":"---","sidebar":"concepts"},"concepts/glossary/E":{"id":"concepts/glossary/E","title":"E","description":"---","sidebar":"concepts"},"concepts/glossary/F":{"id":"concepts/glossary/F","title":"F","description":"---","sidebar":"concepts"},"concepts/glossary/G":{"id":"concepts/glossary/G","title":"G","description":"---","sidebar":"concepts"},"concepts/glossary/H":{"id":"concepts/glossary/H","title":"H","description":"---","sidebar":"concepts"},"concepts/glossary/I":{"id":"concepts/glossary/I","title":"I","description":"---","sidebar":"concepts"},"concepts/glossary/index":{"id":"concepts/glossary/index","title":"Glossary","description":"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.","sidebar":"concepts"},"concepts/glossary/J":{"id":"concepts/glossary/J","title":"J","description":"---","sidebar":"concepts"},"concepts/glossary/K":{"id":"concepts/glossary/K","title":"K","description":"---","sidebar":"concepts"},"concepts/glossary/L":{"id":"concepts/glossary/L","title":"L","description":"---","sidebar":"concepts"},"concepts/glossary/M":{"id":"concepts/glossary/M","title":"M","description":"---","sidebar":"concepts"},"concepts/glossary/N":{"id":"concepts/glossary/N","title":"N","description":"---","sidebar":"concepts"},"concepts/glossary/O":{"id":"concepts/glossary/O","title":"O","description":"---","sidebar":"concepts"},"concepts/glossary/P":{"id":"concepts/glossary/P","title":"P","description":"---","sidebar":"concepts"},"concepts/glossary/Q":{"id":"concepts/glossary/Q","title":"Q","description":"---","sidebar":"concepts"},"concepts/glossary/R":{"id":"concepts/glossary/R","title":"R","description":"---","sidebar":"concepts"},"concepts/glossary/S":{"id":"concepts/glossary/S","title":"S","description":"---","sidebar":"concepts"},"concepts/glossary/T":{"id":"concepts/glossary/T","title":"T","description":"---","sidebar":"concepts"},"concepts/glossary/U":{"id":"concepts/glossary/U","title":"U","description":"---","sidebar":"concepts"},"concepts/glossary/V":{"id":"concepts/glossary/V","title":"V","description":"---","sidebar":"concepts"},"concepts/glossary/W":{"id":"concepts/glossary/W","title":"W","description":"---","sidebar":"concepts"},"concepts/glossary/X":{"id":"concepts/glossary/X","title":"X","description":"---","sidebar":"concepts"},"concepts/glossary/Y":{"id":"concepts/glossary/Y","title":"Y","description":"---","sidebar":"concepts"},"concepts/glossary/Z":{"id":"concepts/glossary/Z","title":"Z","description":"---","sidebar":"concepts"},"concepts/index":{"id":"concepts/index","title":"Overview","description":"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.","sidebar":"concepts"},"concepts/intro-to-dapps":{"id":"concepts/intro-to-dapps","title":"dApps","description":"What is a dApp?","sidebar":"concepts"},"concepts/key-types":{"id":"concepts/key-types","title":"Key Types","description":"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.","sidebar":"concepts"},"concepts/list-auth-keys":{"id":"concepts/list-auth-keys","title":"Authorization Keys","description":"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.","sidebar":"concepts"},"concepts/serialization/index":{"id":"concepts/serialization/index","title":"Binary Serialization Standard","description":"serialization-standard-head}","sidebar":"concepts"},"concepts/serialization/primitives":{"id":"concepts/serialization/primitives","title":"Primitives and Basic Serialization Rules","description":"CLValue","sidebar":"concepts"},"concepts/serialization/structures":{"id":"concepts/serialization/structures","title":"Major Structures","description":"Account","sidebar":"concepts"},"concepts/serialization/types":{"id":"concepts/serialization/types","title":"Type Serialization","description":"Account Action Thresholds","sidebar":"concepts"},"concepts/smart-contracts":{"id":"concepts/smart-contracts","title":"Smart Contracts","description":"Smart Contracts in General","sidebar":"concepts"},"concepts/transactions":{"id":"concepts/transactions","title":"Transactions","description":"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."},"concepts/transactions-and-transaction-lifecycle":{"id":"concepts/transactions-and-transaction-lifecycle","title":"Transaction Lifecycle","description":"Transactions","sidebar":"concepts"},"developers/cli/calling-contracts":{"id":"developers/cli/calling-contracts","title":"Calling Contracts","description":"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.","sidebar":"developers"},"developers/cli/delegate":{"id":"developers/cli/delegate","title":"Delegating Tokens","description":"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.","sidebar":"developers"},"developers/cli/execution-error-codes":{"id":"developers/cli/execution-error-codes","title":"Execution Error Codes","description":"This section covers smart contract execution error codes.","sidebar":"developers"},"developers/cli/index":{"id":"developers/cli/index","title":"Interacting with the Blockchain","description":"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.","sidebar":"developers"},"developers/cli/installing-contracts":{"id":"developers/cli/installing-contracts","title":"Installing Contracts","description":"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.","sidebar":"developers"},"developers/cli/opcode-costs":{"id":"developers/cli/opcode-costs","title":"OpCode Costs Tables","description":"The following tables outline the cost, in motes, for a given operation on Casper\'s Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.","sidebar":"developers"},"developers/cli/querying-global-state":{"id":"developers/cli/querying-global-state","title":"Querying Global State","description":"This page explains how to query global state to find account, contract, and package details.","sidebar":"developers"},"developers/cli/redelegate":{"id":"developers/cli/redelegate","title":"Redelegating Tokens with the Casper Client","description":"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.","sidebar":"developers"},"developers/cli/sending-transactions":{"id":"developers/cli/sending-transactions","title":"Sending Transactions","description":"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:","sidebar":"developers"},"developers/cli/transfers/direct-token-transfer":{"id":"developers/cli/transfers/direct-token-transfer","title":"Direct Token Transfer","description":"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.","sidebar":"developers"},"developers/cli/transfers/index":{"id":"developers/cli/transfers/index","title":"Transferring Tokens","description":"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.","sidebar":"developers"},"developers/cli/transfers/multisig-deploy-transfer":{"id":"developers/cli/transfers/multisig-deploy-transfer","title":"Transferring Tokens using a Multi-Sig Deploy","description":"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.","sidebar":"developers"},"developers/cli/transfers/verify-transfer":{"id":"developers/cli/transfers/verify-transfer","title":"Verifying a Transfer","description":"Prerequisites","sidebar":"developers"},"developers/cli/undelegate":{"id":"developers/cli/undelegate","title":"Undelegating Tokens","description":"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.","sidebar":"developers"},"developers/cli/verifying-contracts":{"id":"developers/cli/verifying-contracts","title":"Verifying Contracts","description":"This document describes actions needed for smart contract verification using the Casper CLI client.","sidebar":"developers"},"developers/dapps/dapp":{"id":"developers/dapps/dapp","title":"What is a dApp?","description":"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.","sidebar":"developers"},"developers/dapps/index":{"id":"developers/dapps/index","title":"Overview of Casper dApps","description":"The following topics are essential for developers building decentralized applications on a Casper network.","sidebar":"developers"},"developers/dapps/monitor-and-consume-events":{"id":"developers/dapps/monitor-and-consume-events","title":"Monitoring Events with the Casper Sidecar","description":"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.","sidebar":"developers"},"developers/dapps/nctl-test":{"id":"developers/dapps/nctl-test","title":"Local Network Testing","description":"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.","sidebar":"developers"},"developers/dapps/prerequisites":{"id":"developers/dapps/prerequisites","title":"Prerequisites","description":"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:","sidebar":"developers"},"developers/dapps/sdk/client-library-usage":{"id":"developers/dapps/sdk/client-library-usage","title":"SDK Client Library Usage","description":"Installing the SDKs","sidebar":"developers"},"developers/dapps/sdk/csharp-sdk":{"id":"developers/dapps/sdk/csharp-sdk","title":".NET SDK","description":"The C# .NET SDK allows developers to interact with a Casper network using C#.","sidebar":"developers"},"developers/dapps/sdk/go-sdk":{"id":"developers/dapps/sdk/go-sdk","title":"Go SDK","description":"Usage Examples","sidebar":"developers"},"developers/dapps/sdk/index":{"id":"developers/dapps/sdk/index","title":"SDK Client Libraries","description":"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.","sidebar":"developers"},"developers/dapps/sdk/python-sdk":{"id":"developers/dapps/sdk/python-sdk","title":"Python SDK","description":"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.","sidebar":"developers"},"developers/dapps/sdk/script-sdk":{"id":"developers/dapps/sdk/script-sdk","title":"JavaScript/TypeScript SDK","description":"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.","sidebar":"developers"},"developers/dapps/setup-nctl":{"id":"developers/dapps/setup-nctl","title":"Local Network Setup","description":"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.","sidebar":"developers"},"developers/dapps/signing-a-transaction":{"id":"developers/dapps/signing-a-transaction","title":"Signing Transactions","description":"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account\'s cryptographic key-pair. This key-pair is a combination of the account\'s secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.","sidebar":"developers"},"developers/dapps/speculative-exec":{"id":"developers/dapps/speculative-exec","title":"Estimating Gas Costs with Speculative Execution","description":"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.","sidebar":"developers"},"developers/dapps/technology-stack":{"id":"developers/dapps/technology-stack","title":"dApp Technology Stack","description":"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.","sidebar":"developers"},"developers/dapps/template-frontend":{"id":"developers/dapps/template-frontend","title":"Front-end in React","description":"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.","sidebar":"developers"},"developers/dapps/uref-security":{"id":"developers/dapps/uref-security","title":"URef Access Rights","description":"Understanding Access Rights","sidebar":"developers"},"developers/essential-crates":{"id":"developers/essential-crates","title":"Essential Rust Crates","description":"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.","sidebar":"developers"},"developers/index":{"id":"developers/index","title":"Overview","description":"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.","sidebar":"developers"},"developers/json-rpc/errors":{"id":"developers/json-rpc/errors","title":"Casper JSON-RPC Error Codes","description":"The following document expands on custom error codes provided by casper-json-rpc crate."},"developers/json-rpc/guidance":{"id":"developers/json-rpc/guidance","title":"Guidance for JSON-RPC SDK Compliance","description":"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.","sidebar":"developers"},"developers/json-rpc/index":{"id":"developers/json-rpc/index","title":"Overview","description":"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.","sidebar":"developers"},"developers/json-rpc/json-rpc-informational":{"id":"developers/json-rpc/json-rpc-informational","title":"Informational JSON-RPC Methods","description":"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.","sidebar":"developers"},"developers/json-rpc/json-rpc-pos":{"id":"developers/json-rpc/json-rpc-pos","title":"Proof-of-Stake JSON-RPC Methods","description":"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.","sidebar":"developers"},"developers/json-rpc/json-rpc-transactional":{"id":"developers/json-rpc/json-rpc-transactional","title":"Transactional JSON-RPC Methods","description":"---","sidebar":"developers"},"developers/json-rpc/minimal-compliance":{"id":"developers/json-rpc/minimal-compliance","title":"Required Methods for Minimal Compliance","description":"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.","sidebar":"developers"},"developers/json-rpc/types_chain":{"id":"developers/json-rpc/types_chain","title":"Types","description":"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.","sidebar":"developers"},"developers/json-rpc/types_cl":{"id":"developers/json-rpc/types_cl","title":"CLType","description":"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.","sidebar":"developers"},"developers/prerequisites":{"id":"developers/prerequisites","title":"Development Prerequisites","description":"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.","sidebar":"developers"},"developers/writing-onchain-code/assembly-script":{"id":"developers/writing-onchain-code/assembly-script","title":"Getting Started with AssemblyScript","description":"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.","sidebar":"developers"},"developers/writing-onchain-code/best-practices":{"id":"developers/writing-onchain-code/best-practices","title":"Best Practices for Casper Smart Contract Authors","description":"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.","sidebar":"developers"},"developers/writing-onchain-code/calling-contracts":{"id":"developers/writing-onchain-code/calling-contracts","title":"Calling Contracts","description":"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.","sidebar":"developers"},"developers/writing-onchain-code/contract-hash-vs-package-hash":{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","title":"Contract Hash vs. Package Hash","description":"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.","sidebar":"developers"},"developers/writing-onchain-code/contract-vs-session":{"id":"developers/writing-onchain-code/contract-vs-session","title":"Contracts and Session Code","description":"What is Session Code?","sidebar":"developers"},"developers/writing-onchain-code/emitting-contract-events":{"id":"developers/writing-onchain-code/emitting-contract-events","title":"Contract-Level Events","description":"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.","sidebar":"developers"},"developers/writing-onchain-code/factory-pattern":{"id":"developers/writing-onchain-code/factory-pattern","title":"Factory Contracts","description":"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.","sidebar":"developers"},"developers/writing-onchain-code/getting-started":{"id":"developers/writing-onchain-code/getting-started","title":"Getting Started with Rust","description":"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.","sidebar":"developers"},"developers/writing-onchain-code/index":{"id":"developers/writing-onchain-code/index","title":"Introduction","description":"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.","sidebar":"developers"},"developers/writing-onchain-code/simple-contract":{"id":"developers/writing-onchain-code/simple-contract","title":"Writing a Basic Smart Contract in Rust","description":"What is a Smart Contract?","sidebar":"developers"},"developers/writing-onchain-code/testing-contracts":{"id":"developers/writing-onchain-code/testing-contracts","title":"Testing Smart Contracts","description":"Introduction","sidebar":"developers"},"developers/writing-onchain-code/testing-session-code":{"id":"developers/writing-onchain-code/testing-session-code","title":"Testing Session Code","description":"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.","sidebar":"developers"},"developers/writing-onchain-code/upgrading-contracts":{"id":"developers/writing-onchain-code/upgrading-contracts","title":"Upgrading and Maintaining Smart Contracts","description":"Our smart contract packaging tools enable you to:","sidebar":"developers"},"developers/writing-onchain-code/writing-session-code":{"id":"developers/writing-onchain-code/writing-session-code","title":"Writing Session Code","description":"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.","sidebar":"developers"},"disclaimer":{"id":"disclaimer","title":"Disclaimer","description":"disclaimer}"},"index":{"id":"index","title":"Welcome to the official Casper documentation","description":"What is Casper?"},"operators/becoming-a-validator/bonding":{"id":"operators/becoming-a-validator/bonding","title":"Bonding","description":"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.","sidebar":"operators"},"operators/becoming-a-validator/change-bid-public-key":{"id":"operators/becoming-a-validator/change-bid-public-key","title":"Change bid public key","description":"The public key associated with a given validator bid can be changed through the auction contract\'s changebidpublic_key entry point."},"operators/becoming-a-validator/inactive-vs-faulty":{"id":"operators/becoming-a-validator/inactive-vs-faulty","title":"Inactive and Faulty Nodes","description":"This page describes the differences between a validator node being considered inactive or faulty.","sidebar":"operators"},"operators/becoming-a-validator/index":{"id":"operators/becoming-a-validator/index","title":"Becoming a Validator","description":"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.","sidebar":"operators"},"operators/becoming-a-validator/recovering":{"id":"operators/becoming-a-validator/recovering","title":"Recovery","description":"This topic discusses the steps a validator needs to take if it is evicted from the validator set:","sidebar":"operators"},"operators/becoming-a-validator/unbonding":{"id":"operators/becoming-a-validator/unbonding","title":"Unbonding","description":"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.","sidebar":"operators"},"operators/index":{"id":"operators/index","title":"Overview","description":"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.","sidebar":"operators"},"operators/maintenance/archiving-and-restoring":{"id":"operators/maintenance/archiving-and-restoring","title":"Archive and Restore a DB","description":"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.","sidebar":"operators"},"operators/maintenance/index":{"id":"operators/maintenance/index","title":"Node Maintenance","description":"This section covers maintenance actions such as moving a node to a different location and restoring a database.","sidebar":"operators"},"operators/maintenance/moving-node":{"id":"operators/maintenance/moving-node","title":"Move a Node","description":"This guide is for active validators who want to move their node to another machine.","sidebar":"operators"},"operators/setup-network/chain-spec":{"id":"operators/setup-network/chain-spec","title":"The Chainspec","description":"the-chain-specification}","sidebar":"operators"},"operators/setup-network/create-private":{"id":"operators/setup-network/create-private","title":"Private Network Setup","description":"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.","sidebar":"operators"},"operators/setup-network/genesis":{"id":"operators/setup-network/genesis","title":"Genesis","description":"the-genesis-block}","sidebar":"operators"},"operators/setup-network/index":{"id":"operators/setup-network/index","title":"Setting up Private Networks","description":"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.","sidebar":"operators"},"operators/setup-network/staging-files-for-new-network":{"id":"operators/setup-network/staging-files-for-new-network","title":"Staging Files","description":"Staging files is not needed for already established running networks.","sidebar":"operators"},"operators/setup/basic-node-configuration":{"id":"operators/setup/basic-node-configuration","title":"Configuration","description":"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.","sidebar":"operators"},"operators/setup/casper-sidecar":{"id":"operators/setup/casper-sidecar","title":"Sidecar Setup","description":"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node\'s event stream, query stored events, and query the node\'s JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:","sidebar":"operators"},"operators/setup/fast-sync":{"id":"operators/setup/fast-sync","title":"Fast Sync","description":"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 transaction 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.","sidebar":"operators"},"operators/setup/hardware":{"id":"operators/setup/hardware","title":"Hardware","description":"System Requirements","sidebar":"operators"},"operators/setup/index":{"id":"operators/setup/index","title":"Setting up a Node","description":"The prerequisite for becoming a validator is to set up a node and join a network as described here.","sidebar":"operators"},"operators/setup/install-node":{"id":"operators/setup/install-node","title":"Installation","description":"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.","sidebar":"operators"},"operators/setup/joining":{"id":"operators/setup/joining","title":"Join a Network","description":"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.","sidebar":"operators"},"operators/setup/node-endpoints":{"id":"operators/setup/node-endpoints","title":"Endpoints","description":"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.","sidebar":"operators"},"operators/setup/node-events":{"id":"operators/setup/node-events","title":"Node Events","description":"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node\'s config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.","sidebar":"operators"},"operators/setup/non-root-user":{"id":"operators/setup/non-root-user","title":"Non-Root Users","description":"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.","sidebar":"operators"},"operators/setup/open-files":{"id":"operators/setup/open-files","title":"Open Files Limit","description":"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.","sidebar":"operators"},"operators/setup/upgrade":{"id":"operators/setup/upgrade","title":"Upgrades","description":"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.","sidebar":"operators"},"resources/advanced/cross-contract":{"id":"resources/advanced/cross-contract","title":"Cross-Contract Communication","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/advanced/index":{"id":"resources/advanced/index","title":"Advanced Tutorials","description":"| Title | Description |","sidebar":"tutorials"},"resources/advanced/list-auth-keys-tutorial":{"id":"resources/advanced/list-auth-keys-tutorial","title":"Authorization Keys","description":"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.","sidebar":"tutorials"},"resources/advanced/list-cspr":{"id":"resources/advanced/list-cspr","title":"Listing CSPR","description":"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."},"resources/advanced/multi-sig/index":{"id":"resources/advanced/multi-sig/index","title":"Introduction","description":"In this tutorial, you will use Casper\'s permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.","sidebar":"tutorials"},"resources/advanced/multi-sig/multi-sig-workflow":{"id":"resources/advanced/multi-sig/multi-sig-workflow","title":"Multi-Sig Workflow","description":"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.","sidebar":"tutorials"},"resources/advanced/multi-sig/other-scenarios":{"id":"resources/advanced/multi-sig/other-scenarios","title":"Additional Examples","description":"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.","sidebar":"tutorials"},"resources/advanced/return-values-tutorial":{"id":"resources/advanced/return-values-tutorial","title":"Runtime Return Values","description":"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.","sidebar":"tutorials"},"resources/advanced/storage-workflow":{"id":"resources/advanced/storage-workflow","title":"Storage Workflow","description":"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.","sidebar":"tutorials"},"resources/advanced/transfer-token-to-contract":{"id":"resources/advanced/transfer-token-to-contract","title":"Token Transfers","description":"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.","sidebar":"tutorials"},"resources/advanced/two-party-multi-sig":{"id":"resources/advanced/two-party-multi-sig","title":"Two-Party Multi-Sig","description":"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.","sidebar":"tutorials"},"resources/beginner/aws-node":{"id":"resources/beginner/aws-node","title":"AWS Casper Nodes","description":"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.","sidebar":"tutorials"},"resources/beginner/cep18":{"id":"resources/beginner/cep18","title":"Fungible Tokens","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/beginner/counter-testnet/commands":{"id":"resources/beginner/counter-testnet/commands","title":"Casper-Client Commands","description":"State Root Hash","sidebar":"tutorials"},"resources/beginner/counter-testnet/index":{"id":"resources/beginner/counter-testnet/index","title":"Introduction","description":"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter-testnet/overview":{"id":"resources/beginner/counter-testnet/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter-testnet/walkthrough":{"id":"resources/beginner/counter-testnet/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/counter/commands":{"id":"resources/beginner/counter/commands","title":"Casper-Client Commands","description":"Faucet Account Information","sidebar":"tutorials"},"resources/beginner/counter/index":{"id":"resources/beginner/counter/index","title":"Introduction","description":"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter/overview":{"id":"resources/beginner/counter/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter/walkthrough":{"id":"resources/beginner/counter/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/getting-started-tutorial":{"id":"resources/beginner/getting-started-tutorial","title":"Getting Started","description":"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.","sidebar":"tutorials"},"resources/beginner/index":{"id":"resources/beginner/index","title":"Overview","description":"Beginner Tutorials","sidebar":"tutorials"},"resources/beginner/querying-network":{"id":"resources/beginner/querying-network","title":"Querying a Node","description":"The Casper node supports queries for users and developers to obtain information stored on the blockchain.","sidebar":"tutorials"},"resources/beginner/upgrade-contract":{"id":"resources/beginner/upgrade-contract","title":"Contract Upgrades","description":"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.","sidebar":"tutorials"},"resources/build-on-casper":{"id":"resources/build-on-casper","title":"Build on Casper","description":"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.","sidebar":"resources"},"resources/casper-open-source-software":{"id":"resources/casper-open-source-software","title":"Open-Source Software","description":"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.","sidebar":"resources"},"resources/changelog":{"id":"resources/changelog","title":"Documentation Updates by Protocol Release","description":"Condor (2.0)"},"resources/index":{"id":"resources/index","title":"Resources Overview","description":"Building on Casper","sidebar":"resources"},"resources/moving-to-casper":{"id":"resources/moving-to-casper","title":"Move to Casper","description":"moving-to-casper}","sidebar":"resources"},"resources/quick-start":{"id":"resources/quick-start","title":"Quickstart","description":"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.","sidebar":"tutorials"},"resources/tokens/cep18/full-tutorial":{"id":"resources/tokens/cep18/full-tutorial","title":"Fungible Token Workflow","description":"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.","sidebar":"resources"},"resources/tokens/cep18/query":{"id":"resources/tokens/cep18/query","title":"CEP-18 Contract Details","description":"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:","sidebar":"resources"},"resources/tokens/cep18/quickstart-guide":{"id":"resources/tokens/cep18/quickstart-guide","title":"On-chain Installation","description":"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.","sidebar":"resources"},"resources/tokens/cep18/tests":{"id":"resources/tokens/cep18/tests","title":"Testing Guide","description":"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.","sidebar":"resources"},"resources/tokens/cep18/transfer":{"id":"resources/tokens/cep18/transfer","title":"CEP-18 Transfers","description":"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.","sidebar":"resources"},"resources/tokens/cep78/introduction":{"id":"resources/tokens/cep78/introduction","title":"Introduction","description":"Usage","sidebar":"resources"},"resources/tokens/cep78/js-tutorial":{"id":"resources/tokens/cep78/js-tutorial","title":"CEP-78 JavaScript Client","description":"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.","sidebar":"resources"},"resources/tokens/cep78/modalities":{"id":"resources/tokens/cep78/modalities","title":"CEP-78 Modalities","description":"The enhanced NFT implementation supports various \'modalities\' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.","sidebar":"resources"},"resources/tokens/cep78/reverse-lookup":{"id":"resources/tokens/cep78/reverse-lookup","title":"Ownership Lookup","description":"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client":{"id":"resources/tokens/cep78/using-casper-client","title":"On-chain Installation","description":"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper\'s Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.","sidebar":"resources"},"resources/tokens/index":{"id":"resources/tokens/index","title":"Casper Token Standards","description":"CEP-18 Casper Fungible Token Standard","sidebar":"resources"},"users/block-explorer":{"id":"users/block-explorer","title":"Block Explorers","description":"The Casper blockchain is available as the Mainnet and Testnet.","sidebar":"users"},"users/csprlive/delegate-ui":{"id":"users/csprlive/delegate-ui","title":"Delegate Tokens","description":"Introduction","sidebar":"users"},"users/csprlive/index":{"id":"users/csprlive/index","title":"Using CSPR.live","description":"| Topic | Description |","sidebar":"users"},"users/csprlive/testnet-faucet":{"id":"users/csprlive/testnet-faucet","title":"Testnet Funding","description":"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.","sidebar":"users"},"users/csprlive/token-transfer":{"id":"users/csprlive/token-transfer","title":"Transfer Tokens","description":"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user\'s purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.","sidebar":"users"},"users/csprlive/undelegate-ui":{"id":"users/csprlive/undelegate-ui","title":"Undelegate Tokens","description":"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.","sidebar":"users"},"users/delegating":{"id":"users/delegating","title":"Delegating Tokens","description":"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.","sidebar":"users"},"users/funding-from-exchanges":{"id":"users/funding-from-exchanges","title":"Funding Mainnet Accounts","description":"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account\'s public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.","sidebar":"users"},"users/index":{"id":"users/index","title":"Users Overview","description":"General Topics","sidebar":"users"},"users/ledger/index":{"id":"users/ledger/index","title":"Casper on Ledger","description":"| Topic | Description |","sidebar":"users"},"users/ledger/ledger-cspr-live":{"id":"users/ledger/ledger-cspr-live","title":"Ledger and CSPR.live","description":"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-live":{"id":"users/ledger/ledger-live","title":"Ledger and Ledger Live","description":"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-setup":{"id":"users/ledger/ledger-setup","title":"Set up Ledger","description":"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.","sidebar":"users"},"users/ledger/staking-ledger":{"id":"users/ledger/staking-ledger","title":"Delegate with Ledger","description":"Ledger Initialization","sidebar":"users"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/727f767d.5bc07a55.js b/assets/js/727f767d.5bc07a55.js new file mode 100644 index 000000000..1e460bc97 --- /dev/null +++ b/assets/js/727f767d.5bc07a55.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[85833],{70827:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var r=n(74848),o=n(28453);const s={},a="Calling Contracts",c={id:"developers/writing-onchain-code/calling-contracts",title:"Calling Contracts",description:"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/calling-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/calling-contracts",permalink:"/1.5.X/developers/writing-onchain-code/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/1.5.X/developers/writing-onchain-code/upgrading-contracts"},next:{title:"Contracts and Session Code",permalink:"/1.5.X/developers/writing-onchain-code/contract-vs-session"}},i={},d=[{value:"Using Deploy Variants",id:"using-deploy-variants",level:2},{value:"ModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionedContractByHash",id:"stored-versioned-contract-by-hash",level:3},{value:"StoredVersionedContractByName",id:"stored-versioned-contract-by-name",level:3},{value:"Transfer",id:"transfer",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"calling-contracts",children:"Calling Contracts"})}),"\n",(0,r.jsx)(t.p,{children:"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm."}),"\n",(0,r.jsx)(t.h2,{id:"using-deploy-variants",children:"Using Deploy Variants"}),"\n",(0,r.jsx)(t.h3,{id:"modulebytes",children:"ModuleBytes"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"ModuleBytes"})," is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm."]}),"\n",(0,r.jsxs)(t.p,{children:["However, you can also use ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," to deploy session code that calls a contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," can be found in ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#modulebytes",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyhash",children:"StoredContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByHash"})," is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question."]}),"\n",(0,r.jsx)(t.p,{children:"While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract."}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#storedcontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyname",children:"StoredContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByName"})," is similar to ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", with the main difference being the reference used to invoke on-chain Wasm. Where ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," requires the contract hash, ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," uses a string stored as a ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#namedkey",children:(0,r.jsx)(t.code,{children:"NamedKey"})})," in the caller's account."]}),"\n",(0,r.jsxs)(t.p,{children:["This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's ",(0,r.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"stored-versioned-contract-by-hash",children:"StoredVersionedContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package."]}),"\n",(0,r.jsxs)(t.p,{children:["This makes ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," more stable than ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version."]}),"\n",(0,r.jsxs)(t.p,{children:["DApp developers that use contracts developed by other parties can use ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," to avoid interruptions from contract version changes."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#storedversioncontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"stored-versioned-contract-by-name",children:"StoredVersionedContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," combines the functionality of ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," and ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"}),". It allows a developer to store a reference string as a ",(0,r.jsx)(t.code,{children:"NamedKey"})," within their account context that references a contract by its contract package hash."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," can be found ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#storedversioncontractbyname",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"transfer",children:"Transfer"}),"\n",(0,r.jsxs)(t.p,{children:["Native ",(0,r.jsx)(t.code,{children:"Transfer"}),"s are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of a native ",(0,r.jsx)(t.code,{children:"Transfer"})," can be found ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#transfer",children:"here"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/727f767d.bf85bdde.js b/assets/js/727f767d.bf85bdde.js deleted file mode 100644 index 39dc1651d..000000000 --- a/assets/js/727f767d.bf85bdde.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5833],{70827:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var r=n(74848),o=n(28453);const s={},a="Calling Contracts",c={id:"developers/writing-onchain-code/calling-contracts",title:"Calling Contracts",description:"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/calling-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/calling-contracts",permalink:"/developers/writing-onchain-code/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/developers/writing-onchain-code/upgrading-contracts"},next:{title:"Contracts and Session Code",permalink:"/developers/writing-onchain-code/contract-vs-session"}},i={},d=[{value:"Using Deploy Variants",id:"using-deploy-variants",level:2},{value:"ModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionedContractByHash",id:"stored-versioned-contract-by-hash",level:3},{value:"StoredVersionedContractByName",id:"stored-versioned-contract-by-name",level:3},{value:"Transfer",id:"transfer",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"calling-contracts",children:"Calling Contracts"})}),"\n",(0,r.jsx)(t.p,{children:"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm."}),"\n",(0,r.jsx)(t.h2,{id:"using-deploy-variants",children:"Using Deploy Variants"}),"\n",(0,r.jsx)(t.h3,{id:"modulebytes",children:"ModuleBytes"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"ModuleBytes"})," is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm."]}),"\n",(0,r.jsxs)(t.p,{children:["However, you can also use ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," to deploy session code that calls a contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," can be found in ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#modulebytes",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyhash",children:"StoredContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByHash"})," is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question."]}),"\n",(0,r.jsx)(t.p,{children:"While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract."}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedcontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyname",children:"StoredContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByName"})," is similar to ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", with the main difference being the reference used to invoke on-chain Wasm. Where ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," requires the contract hash, ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," uses a string stored as a ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:(0,r.jsx)(t.code,{children:"NamedKey"})})," in the caller's account."]}),"\n",(0,r.jsxs)(t.p,{children:["This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's ",(0,r.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"stored-versioned-contract-by-hash",children:"StoredVersionedContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package."]}),"\n",(0,r.jsxs)(t.p,{children:["This makes ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," more stable than ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version."]}),"\n",(0,r.jsxs)(t.p,{children:["DApp developers that use contracts developed by other parties can use ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," to avoid interruptions from contract version changes."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedversioncontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"stored-versioned-contract-by-name",children:"StoredVersionedContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," combines the functionality of ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," and ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"}),". It allows a developer to store a reference string as a ",(0,r.jsx)(t.code,{children:"NamedKey"})," within their account context that references a contract by its contract package hash."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#storedversioncontractbyname",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"transfer",children:"Transfer"}),"\n",(0,r.jsxs)(t.p,{children:["Native ",(0,r.jsx)(t.code,{children:"Transfer"}),"s are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of a native ",(0,r.jsx)(t.code,{children:"Transfer"})," can be found ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_chain#transfer",children:"here"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function a(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72a89de8.820a02b4.js b/assets/js/72a89de8.820a02b4.js deleted file mode 100644 index 2004c3165..000000000 --- a/assets/js/72a89de8.820a02b4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5687],{65693:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=n(74848),s=n(28453);const r={title:"Delegate Tokens",slug:"/users/delegate-ui"},o="Delegating Tokens with a Block Explorer",a={id:"users/csprlive/delegate-ui",title:"Delegate Tokens",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/users/csprlive/delegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/delegate-ui",permalink:"/users/delegate-ui",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Delegate Tokens",slug:"/users/delegate-ui"},sidebar:"users",previous:{title:"Testnet Funding",permalink:"/users/testnet-faucet"},next:{title:"Undelegate Tokens",permalink:"/users/undelegate-ui"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Reviewing your Account",id:"account-review",level:3},{value:"Accessing the Delegation Feature",id:"delegation-access",level:2},{value:"Stepping through the Delegation Process",id:"stepping-through-the-delegation-process",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-tokens-with-a-block-explorer",children:"Delegating Tokens with a Block Explorer"})}),"\n",(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"This tutorial covers how to delegate Casper tokens to a validator on the network."}),"\n",(0,i.jsxs)(t.p,{children:["Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called ",(0,i.jsx)(t.strong,{children:"delegation"})," or ",(0,i.jsx)(t.strong,{children:"staking"}),". We will use these terms interchangeably in this guide. See the ",(0,i.jsx)(t.a,{href:"/staking",children:"Staking Key Concepts"})," page for more details about the differences."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})," by following the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide."]}),"\n",(0,i.jsxs)(t.li,{children:["You need to ",(0,i.jsx)(t.a,{href:"/users/funding-from-exchanges",children:"fund the account's main purse"})," to delegate tokens."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect to a block explorer to set up the delegation. This guide uses ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," and the Casper Wallet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"#account-review",children:"Review your account"})," before starting the process."]}),"\n",(0,i.jsxs)(t.li,{children:["Review the current ",(0,i.jsx)(t.a,{href:"/staking#delegation-fees",children:"delegation fees"})," and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"account-review",children:"Reviewing your Account"}),"\n",(0,i.jsx)(t.p,{children:"Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Liquid Account Balance"}),", representing the tokens you have for immediate use"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegated Account Balance"}),", representing the delegated tokens already staked with validators on the network"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegations"})," tab, listing the validators to whom you have delegated tokens"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(70647).A+"",width:"2420",height:"1456"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Staking Rewards"})," tab, showing the rewards received in each era"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(39871).A+"",width:"2422",height:"1592"})}),"\n",(0,i.jsx)(t.h2,{id:"delegation-access",children:"Accessing the Delegation Feature"}),"\n",(0,i.jsx)(t.p,{children:"You can access the delegation functionality in two ways."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,i.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,i.jsx)(t.strong,{children:"Delegate"}),". In the next screen, you will need to specify the validator's public key or search for a validator."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(39785).A+"",width:"252",height:"333"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,i.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the ",(0,i.jsx)(t.strong,{children:"Delegate"})," button. The next screen will have the validator's public key pre-populated."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(40719).A+"",width:"2304",height:"822"})}),"\n",(0,i.jsx)(t.h2,{id:"stepping-through-the-delegation-process",children:"Stepping through the Delegation Process"}),"\n",(0,i.jsx)(t.p,{children:'The following instructions will take you through the delegation process, starting with the "Delegation details" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 1 - Delegation details"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,i.jsx)(t.li,{children:"Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee."}),"\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(45275).A+"",width:"1174",height:"1402"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 2 - Confirm the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Review the delegation details."}),"\n",(0,i.jsxs)(t.li,{children:["If everything is correct, click ",(0,i.jsx)(t.strong,{children:"Confirm and delegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(79408).A+"",width:"1218",height:"1562"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 3 - Sign the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Sign the delegation by clicking ",(0,i.jsx)(t.strong,{children:"Sign with Casper Wallet"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(75454).A+"",width:"1198",height:"1754"})}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,i.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(43713).A+"",width:"2098",height:"1730"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the delegation."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(14979).A+"",width:"1238",height:"1442"})}),"\n",(0,i.jsxs)(t.p,{children:["The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the ",(0,i.jsx)(t.strong,{children:"Deploy Details"})," highlighted above."]}),"\n",(0,i.jsxs)(t.p,{children:["Remember to ",(0,i.jsx)(t.a,{href:"/staking/#monitoring-rewards",children:"Monitor your Stake"}),". Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the ",(0,i.jsx)(t.em,{children:"Rewards"})," tab on your account page on ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If you want to undelegate your tokens, you can do so at any time. See the ",(0,i.jsx)(t.a,{href:"/users/undelegate-ui",children:"Undelegation Guide"})," for details."]}),"\n",(0,i.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,i.jsx)(t.p,{children:"This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step."}),"\n",(0,i.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed/cR3v8AthlkQ",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},14979:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/10.completed-delegation-0ac5b9f9f8652f84699d6399327e2fdf.png"},70647:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/2.delegations-9003a8fe3ea1027b5c2979309d3fea8f.png"},39871:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/3.rewards-115f13a27134c16ee910cfbe03007772.png"},39785:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/4.wallet-delegate-5e55bb39f50718c18135516a3b2cc300.png"},40719:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/5.validator-delegate-0b1707fc714ad98ffe9c51589da77d80.png"},45275:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/6.delegation-details-c24d81971b747b1a9690bbd19326491d.png"},79408:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/7.confirm-delegation-1f04705b09036ea673b306ef2d1792a7.png"},75454:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/8.sign-delegation-4cd652c44f821f2db9c825b07f7c1ba2.png"},43713:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/9.wallet-window-f16c8950d24a74274d9dd6e3aa39c62e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72a89de8.adc4dd3e.js b/assets/js/72a89de8.adc4dd3e.js new file mode 100644 index 000000000..ceab94f26 --- /dev/null +++ b/assets/js/72a89de8.adc4dd3e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75687],{65693:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});var i=n(74848),s=n(28453);const r={title:"Delegate Tokens",slug:"/users/delegate-ui"},o="Delegating Tokens with a Block Explorer",a={id:"users/csprlive/delegate-ui",title:"Delegate Tokens",description:"Introduction",source:"@site/versioned_docs/version-1.5.X/users/csprlive/delegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/delegate-ui",permalink:"/1.5.X/users/delegate-ui",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726495933e3,frontMatter:{title:"Delegate Tokens",slug:"/users/delegate-ui"},sidebar:"users",previous:{title:"Testnet Funding",permalink:"/1.5.X/users/testnet-faucet"},next:{title:"Undelegate Tokens",permalink:"/1.5.X/users/undelegate-ui"}},l={},d=[{value:"Introduction",id:"introduction",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Reviewing your Account",id:"account-review",level:3},{value:"Accessing the Delegation Feature",id:"delegation-access",level:2},{value:"Stepping through the Delegation Process",id:"stepping-through-the-delegation-process",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function c(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-tokens-with-a-block-explorer",children:"Delegating Tokens with a Block Explorer"})}),"\n",(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsx)(t.p,{children:"This tutorial covers how to delegate Casper tokens to a validator on the network."}),"\n",(0,i.jsxs)(t.p,{children:["Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called ",(0,i.jsx)(t.strong,{children:"delegation"})," or ",(0,i.jsx)(t.strong,{children:"staking"}),". We will use these terms interchangeably in this guide. See the ",(0,i.jsx)(t.a,{href:"/staking",children:"Staking Key Concepts"})," page for more details about the differences."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})," by following the ",(0,i.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide."]}),"\n",(0,i.jsxs)(t.li,{children:["You need to ",(0,i.jsx)(t.a,{href:"/1.5.X/users/funding-from-exchanges",children:"fund the account's main purse"})," to delegate tokens."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect to a block explorer to set up the delegation. This guide uses ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," and the Casper Wallet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.a,{href:"#account-review",children:"Review your account"})," before starting the process."]}),"\n",(0,i.jsxs)(t.li,{children:["Review the current ",(0,i.jsx)(t.a,{href:"/1.5.X/staking#delegation-fees",children:"delegation fees"})," and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"account-review",children:"Reviewing your Account"}),"\n",(0,i.jsx)(t.p,{children:"Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Liquid Account Balance"}),", representing the tokens you have for immediate use"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegated Account Balance"}),", representing the delegated tokens already staked with validators on the network"]}),"\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Delegations"})," tab, listing the validators to whom you have delegated tokens"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(16161).A+"",width:"2420",height:"1456"})}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["The ",(0,i.jsx)(t.strong,{children:"Staking Rewards"})," tab, showing the rewards received in each era"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(857).A+"",width:"2422",height:"1592"})}),"\n",(0,i.jsx)(t.h2,{id:"delegation-access",children:"Accessing the Delegation Feature"}),"\n",(0,i.jsx)(t.p,{children:"You can access the delegation functionality in two ways."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,i.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,i.jsx)(t.strong,{children:"Delegate"}),". In the next screen, you will need to specify the validator's public key or search for a validator."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(85887).A+"",width:"252",height:"333"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,i.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the ",(0,i.jsx)(t.strong,{children:"Delegate"})," button. The next screen will have the validator's public key pre-populated."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(95129).A+"",width:"2304",height:"822"})}),"\n",(0,i.jsx)(t.h2,{id:"stepping-through-the-delegation-process",children:"Stepping through the Delegation Process"}),"\n",(0,i.jsx)(t.p,{children:'The following instructions will take you through the delegation process, starting with the "Delegation details" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 1 - Delegation details"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,i.jsx)(t.li,{children:"Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee."}),"\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(85057).A+"",width:"1174",height:"1402"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 2 - Confirm the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Review the delegation details."}),"\n",(0,i.jsxs)(t.li,{children:["If everything is correct, click ",(0,i.jsx)(t.strong,{children:"Confirm and delegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(25630).A+"",width:"1218",height:"1562"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Step 3 - Sign the delegation"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Sign the delegation by clicking ",(0,i.jsx)(t.strong,{children:"Sign with Casper Wallet"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(32212).A+"",width:"1198",height:"1754"})}),"\n",(0,i.jsxs)(t.ol,{start:"2",children:["\n",(0,i.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,i.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(93299).A+"",width:"2098",height:"1730"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Click ",(0,i.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the delegation."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:n(83749).A+"",width:"1238",height:"1442"})}),"\n",(0,i.jsxs)(t.p,{children:["The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the ",(0,i.jsx)(t.strong,{children:"Deploy Details"})," highlighted above."]}),"\n",(0,i.jsxs)(t.p,{children:["Remember to ",(0,i.jsx)(t.a,{href:"../../concepts/economics/staking.md/#monitoring-rewards",children:"Monitor your Stake"}),". Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the ",(0,i.jsx)(t.em,{children:"Rewards"})," tab on your account page on ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),"."]}),"\n",(0,i.jsxs)(t.p,{children:["If you want to undelegate your tokens, you can do so at any time. See the ",(0,i.jsx)(t.a,{href:"/1.5.X/users/undelegate-ui",children:"Undelegation Guide"})," for details."]}),"\n",(0,i.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,i.jsx)(t.p,{children:"This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step."}),"\n",(0,i.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed/cR3v8AthlkQ",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},83749:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/10.completed-delegation-0ac5b9f9f8652f84699d6399327e2fdf.png"},16161:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/2.delegations-9003a8fe3ea1027b5c2979309d3fea8f.png"},857:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/3.rewards-115f13a27134c16ee910cfbe03007772.png"},85887:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/4.wallet-delegate-5e55bb39f50718c18135516a3b2cc300.png"},95129:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/5.validator-delegate-0b1707fc714ad98ffe9c51589da77d80.png"},85057:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/6.delegation-details-c24d81971b747b1a9690bbd19326491d.png"},25630:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/7.confirm-delegation-1f04705b09036ea673b306ef2d1792a7.png"},32212:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/8.sign-delegation-4cd652c44f821f2db9c825b07f7c1ba2.png"},93299:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/9.wallet-window-f16c8950d24a74274d9dd6e3aa39c62e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var i=n(96540);const s={},r=i.createContext(s);function o(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72b43be8.3923b0c1.js b/assets/js/72b43be8.3923b0c1.js new file mode 100644 index 000000000..05f77f4f7 --- /dev/null +++ b/assets/js/72b43be8.3923b0c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6770],{68966:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),s=t(28453);const i={slug:"/resources/tutorials/beginner/"},a="Overview",d={id:"resources/beginner/index",title:"Overview",description:"Beginner Tutorials",source:"@site/versioned_docs/version-1.5.X/resources/beginner/index.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/",permalink:"/1.5.X/resources/tutorials/beginner/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tutorials/beginner/"},sidebar:"tutorials",previous:{title:"Quickstart",permalink:"/1.5.X/resources/quick-start"},next:{title:"Getting Started",permalink:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial"}},o={},c=[{value:"Beginner Tutorials",id:"beginner-tutorials",level:2},{value:"GitHub Tutorials",id:"github-tutorials",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"beginner-tutorials",children:"Beginner Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/counter",children:"A Counter on an NCTL Network"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on a local Casper Network with NCTL"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})}),(0,r.jsx)(n.td,{children:"Queries for users and developers to obtain information stored on the blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/cep18",children:"The Casper Fungible Token Standard (CEP-18)"})}),(0,r.jsx)(n.td,{children:"Fungible Token Standard (CEP-18) Implementation and Usage"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/aws-node",children:"Launching a Casper Node with AWS Marketplace"})}),(0,r.jsx)(n.td,{children:"Learn how to launch a Casper Node through the AWS Marketplace"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"github-tutorials",children:"GitHub Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>d});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72b43be8.5416988c.js b/assets/js/72b43be8.5416988c.js deleted file mode 100644 index 1aba49bb1..000000000 --- a/assets/js/72b43be8.5416988c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6770],{68966:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),s=t(28453);const i={slug:"/resources/tutorials/beginner/"},a="Overview",d={id:"resources/beginner/index",title:"Overview",description:"Beginner Tutorials",source:"@site/versioned_docs/version-1.5.X/resources/beginner/index.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/",permalink:"/resources/tutorials/beginner/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tutorials/beginner/"},sidebar:"tutorials",previous:{title:"Quickstart",permalink:"/resources/quick-start"},next:{title:"Getting Started",permalink:"/resources/tutorials/beginner/getting-started-tutorial"}},o={},c=[{value:"Beginner Tutorials",id:"beginner-tutorials",level:2},{value:"GitHub Tutorials",id:"github-tutorials",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"beginner-tutorials",children:"Beginner Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/counter",children:"A Counter on an NCTL Network"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on a local Casper Network with NCTL"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})}),(0,r.jsx)(n.td,{children:"Queries for users and developers to obtain information stored on the blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/cep18",children:"The Casper Fungible Token Standard (CEP-18)"})}),(0,r.jsx)(n.td,{children:"Fungible Token Standard (CEP-18) Implementation and Usage"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/aws-node",children:"Launching a Casper Node with AWS Marketplace"})}),(0,r.jsx)(n.td,{children:"Learn how to launch a Casper Node through the AWS Marketplace"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"github-tutorials",children:"GitHub Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>d});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72c6e609.3cf437f8.js b/assets/js/72c6e609.3cf437f8.js new file mode 100644 index 000000000..2deaa3d66 --- /dev/null +++ b/assets/js/72c6e609.3cf437f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22107],{56341:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const r={title:"Upgrades"},a="Upgrading the Node",i={id:"operators/setup/upgrade",title:"Upgrades",description:"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.",source:"@site/versioned_docs/version-1.5.X/operators/setup/upgrade.md",sourceDirName:"operators/setup",slug:"/operators/setup/upgrade",permalink:"/1.5.X/operators/setup/upgrade",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Upgrades"},sidebar:"operators",previous:{title:"Open Files Limit",permalink:"/1.5.X/operators/setup/open-files"},next:{title:"Join a Network",permalink:"/1.5.X/operators/setup/joining"}},c={},d=[{value:"Upgrading Protocol Versions",id:"upgrading-protocol-versions",level:2},{value:"Upgrade Staging Instructions",id:"upgrade-staging-instructions",level:3},{value:"Verifying Successful Staging",id:"verifying-successful-staging",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"upgrading-the-node",children:"Upgrading the Node"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:(0,s.jsx)(n.code,{children:"chainspec.toml"})})," contains a section to indicate from which era the given ",(0,s.jsx)(n.code,{children:"casper-node"})," version should start running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[protocol]\n# This protocol version becomes active at the start of this era.\nactivation_point = 100\n"})}),"\n",(0,s.jsxs)(n.p,{children:["At every block finalization, the ",(0,s.jsx)(n.code,{children:"casper-node"})," looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file. This will be the era before where the current casper-node will cleanly shut down."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-node-launcher"})," will detect a clean exit 0 condition and start the next version of the ",(0,s.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"upgrading-protocol-versions",children:"Upgrading Protocol Versions"}),"\n",(0,s.jsxs)(n.p,{children:["All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of ",(0,s.jsx)(n.code,{children:"casper-node"})," immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point."]}),"\n",(0,s.jsx)(n.p,{children:"Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point."}),"\n",(0,s.jsx)(n.h3,{id:"upgrade-staging-instructions",children:"Upgrade Staging Instructions"}),"\n",(0,s.jsx)(n.p,{children:"The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On Testnet, use ",(0,s.jsx)(n.code,{children:"casper-test.conf"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": To only view the list of staged and unstaged protocols, use this command: ",(0,s.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py check_protocols casper.conf"})]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-successful-staging",children:"Verifying Successful Staging"}),"\n",(0,s.jsx)(n.p,{children:"After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://127.0.0.1:8888/status | jq .next_upgrade\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should expect this output if properly staged, prior to upgrading:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ curl -s localhost:8888/status | jq .next_upgrade\n{\n "activation_point": 4968,\n "protocol_version": "1.4.6"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you see ",(0,s.jsx)(n.code,{children:"null"})," after waiting for a few minutes, then your upgrade staging was not executed successfully."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": The protocol version will change as per the next upgrade available."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72c6e609.8779ead0.js b/assets/js/72c6e609.8779ead0.js deleted file mode 100644 index a043a3581..000000000 --- a/assets/js/72c6e609.8779ead0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2107],{56341:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const r={title:"Upgrades"},a="Upgrading the Node",i={id:"operators/setup/upgrade",title:"Upgrades",description:"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.",source:"@site/versioned_docs/version-1.5.X/operators/setup/upgrade.md",sourceDirName:"operators/setup",slug:"/operators/setup/upgrade",permalink:"/operators/setup/upgrade",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Upgrades"},sidebar:"operators",previous:{title:"Open Files Limit",permalink:"/operators/setup/open-files"},next:{title:"Join a Network",permalink:"/operators/setup/joining"}},c={},d=[{value:"Upgrading Protocol Versions",id:"upgrading-protocol-versions",level:2},{value:"Upgrade Staging Instructions",id:"upgrade-staging-instructions",level:3},{value:"Verifying Successful Staging",id:"verifying-successful-staging",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"upgrading-the-node",children:"Upgrading the Node"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:(0,s.jsx)(n.code,{children:"chainspec.toml"})})," contains a section to indicate from which era the given ",(0,s.jsx)(n.code,{children:"casper-node"})," version should start running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[protocol]\n# This protocol version becomes active at the start of this era.\nactivation_point = 100\n"})}),"\n",(0,s.jsxs)(n.p,{children:["At every block finalization, the ",(0,s.jsx)(n.code,{children:"casper-node"})," looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file. This will be the era before where the current casper-node will cleanly shut down."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-node-launcher"})," will detect a clean exit 0 condition and start the next version of the ",(0,s.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"upgrading-protocol-versions",children:"Upgrading Protocol Versions"}),"\n",(0,s.jsxs)(n.p,{children:["All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of ",(0,s.jsx)(n.code,{children:"casper-node"})," immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point."]}),"\n",(0,s.jsx)(n.p,{children:"Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point."}),"\n",(0,s.jsx)(n.h3,{id:"upgrade-staging-instructions",children:"Upgrade Staging Instructions"}),"\n",(0,s.jsx)(n.p,{children:"The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On Testnet, use ",(0,s.jsx)(n.code,{children:"casper-test.conf"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": To only view the list of staged and unstaged protocols, use this command: ",(0,s.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py check_protocols casper.conf"})]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-successful-staging",children:"Verifying Successful Staging"}),"\n",(0,s.jsx)(n.p,{children:"After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://127.0.0.1:8888/status | jq .next_upgrade\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should expect this output if properly staged, prior to upgrading:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ curl -s localhost:8888/status | jq .next_upgrade\n{\n "activation_point": 4968,\n "protocol_version": "1.4.6"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you see ",(0,s.jsx)(n.code,{children:"null"})," after waiting for a few minutes, then your upgrade staging was not executed successfully."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": The protocol version will change as per the next upgrade available."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72cc2261.0d29617c.js b/assets/js/72cc2261.0d29617c.js new file mode 100644 index 000000000..c3631132f --- /dev/null +++ b/assets/js/72cc2261.0d29617c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73793],{7753:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=t(74848),c=t(28453);const r={title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},s="Upgrading a Contract",o={id:"resources/beginner/upgrade-contract",title:"Contract Upgrades",description:"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/upgrade-contract.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/upgrade-contract",permalink:"/1.5.X/resources/tutorials/beginner/upgrade-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},sidebar:"tutorials",previous:{title:"Querying a Node",permalink:"/1.5.X/resources/tutorials/beginner/querying-network"},next:{title:"Fungible Tokens",permalink:"/1.5.X/resources/tutorials/beginner/cep18"}},i={},l=[{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contract Versioning Flow",id:"contract-versioning-flow",level:2},{value:"Step 1. Create a new unlocked contract",id:"step-1-create-a-new-unlocked-contract",level:3},{value:"Step 2. Add a new contract to the package",id:"step-2-add-a-new-contract-to-the-package",level:3},{value:"Step 3. Build the contract Wasm",id:"step-3-build-the-contract-wasm",level:3},{value:"Step 4. Install the contract",id:"step-4-install-the-contract",level:3},{value:"Step 5. Verify your changes",id:"step-5-verify-your-changes",level:3},{value:"Disabling and Enabling Contract Versions",id:"disabling-and-enabling-contract-versions",level:2},{value:"Creating a Locked Contract Package",id:"locked-contract-package",level:2},{value:"Adding New Fields During Upgrades",id:"adding-new-fields-during-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-a-contract",children:"Upgrading a Contract"})}),"\n",(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsxs)(n.p,{children:["This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"contract package"})," by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," API. You can also create a ",(0,a.jsx)(n.a,{href:"#locked-contract-package",children:"locked contract package"})," that cannot be versioned and is therefore not upgradable."]}),"\n",(0,a.jsx)(n.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,a.jsx)(n.p,{children:"Here is a video walkthrough of this tutorial."}),"\n",(0,a.jsx)(n.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=Q4ZXNV8EVTk&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=4",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"})," referencing the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"ContractPackage"})," where an unlocked contract is stored in global state."]}),"\n",(0,a.jsxs)(n.li,{children:["You should be familiar with ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"writing smart contracts"}),", ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"on-chain contracts"}),", and ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"calling contracts"})," on a Casper network."]}),"\n",(0,a.jsxs)(n.li,{children:["You have installed ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," that you will upgrade as part of this tutorial."]}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Installing the first version of the contract (contract-v1.wasm) as shown in the ",(0,a.jsx)(n.a,{href:"/counter-testnet",children:"counter tutorial"})," is a prerequisite before installing the second version of the contract (contract-v2.wasm)."]})}),"\n",(0,a.jsxs)(n.p,{children:["If you explore ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/",children:"the code"}),", you will observe the different versions of the contract:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v1"})," is the counter contract you can see in the ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," tutorial."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v2"})," is the contract with the new ",(0,a.jsx)(n.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v3"})," is the contract with the new ",(0,a.jsx)(n.code,{children:"get_last_updated_at"})," entry point and ",(0,a.jsx)(n.code,{children:"last_updated_at"})," named key."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"contract-versioning-flow",children:"Contract Versioning Flow"}),"\n",(0,a.jsx)(n.p,{children:"The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Create a contract in the most common way, using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["Add a new version of the contract using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["Build the new contract and generate the corresponding ",(0,a.jsx)(n.code,{children:".wasm"})," file."]}),"\n",(0,a.jsx)(n.li,{children:"Install the contract on the network via a deploy."}),"\n",(0,a.jsx)(n.li,{children:"Verify that your new contract version works as desired."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial, you will use ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v2/src/main.rs",children:"the second version"})," of the counter contract to perform the upgrade."]}),"\n",(0,a.jsx)(n.h3,{id:"step-1-create-a-new-unlocked-contract",children:"Step 1. Create a new unlocked contract"}),"\n",(0,a.jsxs)(n.p,{children:["Create a new contract using the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned."]}),"\n",(0,a.jsx)(n.p,{children:"When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' // Create a new contract and specify a package name and access URef for further modifications\n let (stored_contract_hash, contract_version) = storage::new_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n );\n\n // The hash of the installed contract will be reachable through a named key\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n\n // The current version of the contract will be reachable through a named key\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L94",children:"first version of the counter"})," shows you a contract package that can be versioned. This step is covered in the tutorial for ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Additional details:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used."}),"\n",(0,a.jsx)(n.li,{children:"The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"step-2-add-a-new-contract-to-the-package",children:"Step 2. Add a new contract to the package"}),"\n",(0,a.jsx)(n.p,{children:"There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract."}),"\n",(0,a.jsxs)(n.p,{children:["To add a new contract version in the package, invoke the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," function and pass in the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"}),", ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.EntryPoints.html",children:"EntryPoints"}),", and ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),". In the counter example, you will find the ",(0,a.jsx)(n.code,{children:"add_contract_version"})," call ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v2/src/main.rs#L164",children:"here"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:" let (contract_hash, contract_version) =\n storage::add_contract_version(contract_package_hash,\n entry_points,\n named_keys);\n"})}),"\n",(0,a.jsx)(n.p,{children:"Explanation of arguments:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract_package_hash"})," - This hash directs you to the contract package. See ",(0,a.jsx)(n.a,{href:"/1.5.X/concepts/hash-types#hash-and-key-explanations",children:"Hash and Key Explanations"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"entry_points"})," - Entry points of the contract, which can be modified or newly added."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"named_keys"})," - Named key pairs of the contract."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract."}),"\n",(0,a.jsx)(n.p,{children:"You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"Pin your client contract to the contract hash of a specific version."}),"\n",(0,a.jsxs)(n.li,{children:["Use ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"})," with a version number to pin your client contract to that version."]}),"\n",(0,a.jsxs)(n.li,{children:["Call a contract using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),' and version "None", which uses the newest version of the contract.']}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"step-3-build-the-contract-wasm",children:"Step 3. Build the contract Wasm"}),"\n",(0,a.jsx)(n.p,{children:"Use these commands to prepare and build the newly added contract:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\n\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-4-install-the-contract",children:"Step 4. Install the contract"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"Install the contract"})," on the network via a deploy and verify the deploy status. You can also ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys#monitoring-the-event-stream-for-deploys",children:"monitor the event stream"})," to see when your deploy is accepted."]}),"\n",(0,a.jsxs)(n.p,{children:["To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the ",(0,a.jsx)(n.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Installing the first version of the contract, as shown in the ",(0,a.jsx)(n.a,{href:"/counter-testnet",children:"Counter tutorial"}),", is a prerequisite before installing the second version."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-5-verify-your-changes",children:"Step 5. Verify your changes"}),"\n",(0,a.jsxs)(n.p,{children:["You can write unit tests to verify the behavior of the new contract version with ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_contract.html",children:"call_contract"})," or ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),". When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version."]}),"\n",(0,a.jsxs)(n.p,{children:["For the simple example counter above, here are the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"corresponding tests"}),". Notice how the tests store and verify the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"contract's version"})," and entry points."]}),"\n",(0,a.jsxs)(n.p,{children:["You could store the latest version of the contract package under a NamedKey, as shown ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"here"}),". Then, you can query the NamedKey to check the latest version of the contract package."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example test function"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' // Verify the contract version is now 2.\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let version_key = *account\n .named_keys()\n .get(CONTRACT_VERSION_KEY)\n .expect("version uref should exist");\n\n let version = builder\n .query(None, version_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<u32>()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You can also test the new entry point by using the Rust command-line client."}),"\n",(0,a.jsx)(n.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Check the new contract entry points. You should see the ",(0,a.jsx)(n.em,{children:"counter_decrement"})," entry point now."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Check the version and package details with the latest state root hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'})}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Call the new entry point, ",(0,a.jsx)(n.em,{children:"counter_decrement"}),", using the package name and check the results."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n'})}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"There are two ways to call versioned contracts:"}),(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts/#stored-versioned-contract-by-hash",children:"Calling Contracts by Package Hash"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts/#stored-versioned-contract-by-name",children:"Calling Contracts by Package Name"})}),"\n"]})]}),"\n",(0,a.jsx)(n.p,{children:"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."}),"\n",(0,a.jsx)(n.h2,{id:"disabling-and-enabling-contract-versions",children:"Disabling and Enabling Contract Versions"}),"\n",(0,a.jsxs)(n.p,{children:["You can disable a contract version within a contract package by using the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html",children:"disable_contract_version"})," function."]}),"\n",(0,a.jsx)(n.p,{children:"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html",children:"Enable_contract_version"})," allows you to re-enable a previously disabled contract version."]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."})}),"\n",(0,a.jsx)(n.h2,{id:"locked-contract-package",children:"Creating a Locked Contract Package"}),"\n",(0,a.jsxs)(n.p,{children:["You can create a locked contract package with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," function. This contract can never be upgraded."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n'})}),"\n",(0,a.jsx)(n.p,{children:"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," as Step 1 explains."]})}),"\n",(0,a.jsx)(n.h2,{id:"adding-new-fields-during-upgrades",children:"Adding New Fields During Upgrades"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"contract-v3"})," demonstrates adding new data storage to your contract. It introduces a new field for the last update timestamp."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Key Steps:"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Define a Named Key:"})," A key (",(0,a.jsx)(n.code,{children:"LAST_UPDATED_KEY"}),") references the new field."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Initialize the Field:"})," A URef is created using ",(0,a.jsx)(n.code,{children:"storage::new_uref"})," to point to the storage location. It's then added to ",(0,a.jsx)(n.code,{children:"NamedKeys"})," along with the key."]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Code Breakdown:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:"// Create NamedKeys and initialize the new field (last_updated) with default value (0).\nlet mut named_keys = NamedKeys::new();\nlet last_updated = storage::new_uref(0_u64);\nnamed_keys.insert(String::from(LAST_UPDATED_KEY), last_updated.into());\n"})}),"\n",(0,a.jsxs)(n.p,{children:["For a deeper dive into the implementation details, explore the ",(0,a.jsx)(n.code,{children:"contract-v3"})," code itself. This hands-on exploration will further solidify your understanding of adding new fields during contract upgrades."]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>o});var a=t(96540);const c={},r=a.createContext(c);function s(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/72cc2261.d789919f.js b/assets/js/72cc2261.d789919f.js deleted file mode 100644 index b4891b1d7..000000000 --- a/assets/js/72cc2261.d789919f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3793],{7753:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=t(74848),c=t(28453);const r={title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},s="Upgrading a Contract",o={id:"resources/beginner/upgrade-contract",title:"Contract Upgrades",description:"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/upgrade-contract.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/upgrade-contract",permalink:"/resources/tutorials/beginner/upgrade-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},sidebar:"tutorials",previous:{title:"Querying a Node",permalink:"/resources/tutorials/beginner/querying-network"},next:{title:"Fungible Tokens",permalink:"/resources/tutorials/beginner/cep18"}},i={},l=[{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contract Versioning Flow",id:"contract-versioning-flow",level:2},{value:"Step 1. Create a new unlocked contract",id:"step-1-create-a-new-unlocked-contract",level:3},{value:"Step 2. Add a new contract to the package",id:"step-2-add-a-new-contract-to-the-package",level:3},{value:"Step 3. Build the contract Wasm",id:"step-3-build-the-contract-wasm",level:3},{value:"Step 4. Install the contract",id:"step-4-install-the-contract",level:3},{value:"Step 5. Verify your changes",id:"step-5-verify-your-changes",level:3},{value:"Disabling and Enabling Contract Versions",id:"disabling-and-enabling-contract-versions",level:2},{value:"Creating a Locked Contract Package",id:"locked-contract-package",level:2},{value:"Adding New Fields During Upgrades",id:"adding-new-fields-during-upgrades",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-a-contract",children:"Upgrading a Contract"})}),"\n",(0,a.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,a.jsxs)(n.p,{children:["This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"contract package"})," by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," API. You can also create a ",(0,a.jsx)(n.a,{href:"#locked-contract-package",children:"locked contract package"})," that cannot be versioned and is therefore not upgradable."]}),"\n",(0,a.jsx)(n.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,a.jsx)(n.p,{children:"Here is a video walkthrough of this tutorial."}),"\n",(0,a.jsx)(n.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=Q4ZXNV8EVTk&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=4",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["The ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"})," referencing the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"ContractPackage"})," where an unlocked contract is stored in global state."]}),"\n",(0,a.jsxs)(n.li,{children:["You should be familiar with ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"writing smart contracts"}),", ",(0,a.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"on-chain contracts"}),", and ",(0,a.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"calling contracts"})," on a Casper network."]}),"\n",(0,a.jsxs)(n.li,{children:["You have installed ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," that you will upgrade as part of this tutorial."]}),"\n"]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Installing the first version of the contract (contract-v1.wasm) as shown in the ",(0,a.jsx)(n.a,{href:"/counter-testnet",children:"counter tutorial"})," is a prerequisite before installing the second version of the contract (contract-v2.wasm)."]})}),"\n",(0,a.jsxs)(n.p,{children:["If you explore ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/",children:"the code"}),", you will observe the different versions of the contract:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v1"})," is the counter contract you can see in the ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," tutorial."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v2"})," is the contract with the new ",(0,a.jsx)(n.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract-v3"})," is the contract with the new ",(0,a.jsx)(n.code,{children:"get_last_updated_at"})," entry point and ",(0,a.jsx)(n.code,{children:"last_updated_at"})," named key."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"contract-versioning-flow",children:"Contract Versioning Flow"}),"\n",(0,a.jsx)(n.p,{children:"The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash."}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["Create a contract in the most common way, using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["Add a new version of the contract using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:["Build the new contract and generate the corresponding ",(0,a.jsx)(n.code,{children:".wasm"})," file."]}),"\n",(0,a.jsx)(n.li,{children:"Install the contract on the network via a deploy."}),"\n",(0,a.jsx)(n.li,{children:"Verify that your new contract version works as desired."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial, you will use ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v2/src/main.rs",children:"the second version"})," of the counter contract to perform the upgrade."]}),"\n",(0,a.jsx)(n.h3,{id:"step-1-create-a-new-unlocked-contract",children:"Step 1. Create a new unlocked contract"}),"\n",(0,a.jsxs)(n.p,{children:["Create a new contract using the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned."]}),"\n",(0,a.jsx)(n.p,{children:"When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' // Create a new contract and specify a package name and access URef for further modifications\n let (stored_contract_hash, contract_version) = storage::new_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n );\n\n // The hash of the installed contract will be reachable through a named key\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n\n // The current version of the contract will be reachable through a named key\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L94",children:"first version of the counter"})," shows you a contract package that can be versioned. This step is covered in the tutorial for ",(0,a.jsx)(n.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Additional details:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used."}),"\n",(0,a.jsx)(n.li,{children:"The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions."}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"step-2-add-a-new-contract-to-the-package",children:"Step 2. Add a new contract to the package"}),"\n",(0,a.jsx)(n.p,{children:"There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract."}),"\n",(0,a.jsxs)(n.p,{children:["To add a new contract version in the package, invoke the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," function and pass in the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"}),", ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.EntryPoints.html",children:"EntryPoints"}),", and ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),". In the counter example, you will find the ",(0,a.jsx)(n.code,{children:"add_contract_version"})," call ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v2/src/main.rs#L164",children:"here"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:" let (contract_hash, contract_version) =\n storage::add_contract_version(contract_package_hash,\n entry_points,\n named_keys);\n"})}),"\n",(0,a.jsx)(n.p,{children:"Explanation of arguments:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"contract_package_hash"})," - This hash directs you to the contract package. See ",(0,a.jsx)(n.a,{href:"/concepts/hash-types#hash-and-key-explanations",children:"Hash and Key Explanations"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"entry_points"})," - Entry points of the contract, which can be modified or newly added."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"named_keys"})," - Named key pairs of the contract."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract."}),"\n",(0,a.jsx)(n.p,{children:"You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"Pin your client contract to the contract hash of a specific version."}),"\n",(0,a.jsxs)(n.li,{children:["Use ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"})," with a version number to pin your client contract to that version."]}),"\n",(0,a.jsxs)(n.li,{children:["Call a contract using ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),' and version "None", which uses the newest version of the contract.']}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"step-3-build-the-contract-wasm",children:"Step 3. Build the contract Wasm"}),"\n",(0,a.jsx)(n.p,{children:"Use these commands to prepare and build the newly added contract:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\n\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-4-install-the-contract",children:"Step 4. Install the contract"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"Install the contract"})," on the network via a deploy and verify the deploy status. You can also ",(0,a.jsx)(n.a,{href:"/developers/cli/sending-deploys#monitoring-the-event-stream-for-deploys",children:"monitor the event stream"})," to see when your deploy is accepted."]}),"\n",(0,a.jsxs)(n.p,{children:["To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the ",(0,a.jsx)(n.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Installing the first version of the contract, as shown in the ",(0,a.jsx)(n.a,{href:"/counter-testnet",children:"Counter tutorial"}),", is a prerequisite before installing the second version."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm\n"})}),"\n",(0,a.jsx)(n.h3,{id:"step-5-verify-your-changes",children:"Step 5. Verify your changes"}),"\n",(0,a.jsxs)(n.p,{children:["You can write unit tests to verify the behavior of the new contract version with ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_contract.html",children:"call_contract"})," or ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),". When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version."]}),"\n",(0,a.jsxs)(n.p,{children:["For the simple example counter above, here are the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"corresponding tests"}),". Notice how the tests store and verify the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"contract's version"})," and entry points."]}),"\n",(0,a.jsxs)(n.p,{children:["You could store the latest version of the contract package under a NamedKey, as shown ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"here"}),". Then, you can query the NamedKey to check the latest version of the contract package."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example test function"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' // Verify the contract version is now 2.\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let version_key = *account\n .named_keys()\n .get(CONTRACT_VERSION_KEY)\n .expect("version uref should exist");\n\n let version = builder\n .query(None, version_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<u32>()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You can also test the new entry point by using the Rust command-line client."}),"\n",(0,a.jsx)(n.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Check the new contract entry points. You should see the ",(0,a.jsx)(n.em,{children:"counter_decrement"})," entry point now."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Check the version and package details with the latest state root hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'})}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Example output"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Call the new entry point, ",(0,a.jsx)(n.em,{children:"counter_decrement"}),", using the package name and check the results."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n'})}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"There are two ways to call versioned contracts:"}),(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts/#stored-versioned-contract-by-hash",children:"Calling Contracts by Package Hash"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts/#stored-versioned-contract-by-name",children:"Calling Contracts by Package Name"})}),"\n"]})]}),"\n",(0,a.jsx)(n.p,{children:"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."}),"\n",(0,a.jsx)(n.h2,{id:"disabling-and-enabling-contract-versions",children:"Disabling and Enabling Contract Versions"}),"\n",(0,a.jsxs)(n.p,{children:["You can disable a contract version within a contract package by using the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html",children:"disable_contract_version"})," function."]}),"\n",(0,a.jsx)(n.p,{children:"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html",children:"Enable_contract_version"})," allows you to re-enable a previously disabled contract version."]}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsx)(n.p,{children:"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."})}),"\n",(0,a.jsx)(n.h2,{id:"locked-contract-package",children:"Creating a Locked Contract Package"}),"\n",(0,a.jsxs)(n.p,{children:["You can create a locked contract package with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," function. This contract can never be upgraded."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n'})}),"\n",(0,a.jsx)(n.p,{children:"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," as Step 1 explains."]})}),"\n",(0,a.jsx)(n.h2,{id:"adding-new-fields-during-upgrades",children:"Adding New Fields During Upgrades"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"contract-v3"})," demonstrates adding new data storage to your contract. It introduces a new field for the last update timestamp."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Key Steps:"})}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Define a Named Key:"})," A key (",(0,a.jsx)(n.code,{children:"LAST_UPDATED_KEY"}),") references the new field."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Initialize the Field:"})," A URef is created using ",(0,a.jsx)(n.code,{children:"storage::new_uref"})," to point to the storage location. It's then added to ",(0,a.jsx)(n.code,{children:"NamedKeys"})," along with the key."]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Code Breakdown:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-rust",children:"// Create NamedKeys and initialize the new field (last_updated) with default value (0).\nlet mut named_keys = NamedKeys::new();\nlet last_updated = storage::new_uref(0_u64);\nnamed_keys.insert(String::from(LAST_UPDATED_KEY), last_updated.into());\n"})}),"\n",(0,a.jsxs)(n.p,{children:["For a deeper dive into the implementation details, explore the ",(0,a.jsx)(n.code,{children:"contract-v3"})," code itself. This hands-on exploration will further solidify your understanding of adding new fields during contract upgrades."]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>o});var a=t(96540);const c={},r=a.createContext(c);function s(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7366a28d.4e7c9bfa.js b/assets/js/7366a28d.4e7c9bfa.js new file mode 100644 index 000000000..067131314 --- /dev/null +++ b/assets/js/7366a28d.4e7c9bfa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73820],{67297:(t,e,n)=>{n.r(e),n.d(e,{assets:()=>r,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var c=n(74848),s=n(28453);const a={title:"Call Stacks"},i="Understanding Call Stacks",o={id:"concepts/callstack",title:"Call Stacks",description:"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.",source:"@site/versioned_docs/version-2.0.0/concepts/callstack.md",sourceDirName:"concepts",slug:"/concepts/callstack",permalink:"/2.0.0/concepts/callstack",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Call Stacks"},sidebar:"concepts",previous:{title:"Authorization Keys",permalink:"/2.0.0/concepts/list-auth-keys"},next:{title:"Dictionaries",permalink:"/2.0.0/concepts/dictionaries"}},r={},l=[{value:"The Caller",id:"the-caller",level:2},{value:"The Call Stack",id:"the-call-stack",level:2},{value:"Limitations",id:"limitations",level:2}];function h(t){const e={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,s.R)(),...t.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"understanding-call-stacks",children:"Understanding Call Stacks"})}),"\n",(0,c.jsxs)(e.p,{children:["Users wishing to interact with a Casper network must do so through ",(0,c.jsx)(e.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"sending a transaction"}),". All transactions consist of ",(0,c.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"session code"})," run in the context of the user account entity that sent the transaction. The session code may ",(0,c.jsx)(e.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install contract code to global state"}),", or interact with previously ",(0,c.jsx)(e.a,{href:"/2.0.0/developers/writing-onchain-code/calling-contracts",children:"installed contract code"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["When the session code within a transaction interacts with one or more contracts, this is the beginning of a ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-types/latest/casper_types/system/enum.CallStackElement.html",children:(0,c.jsx)(e.code,{children:"Call Stack"})}),". A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code."]}),"\n",(0,c.jsx)(e.h2,{id:"the-caller",children:"The Caller"}),"\n",(0,c.jsxs)(e.p,{children:["In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in each call stack. The account that initiated the transaction can be retrieved with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_caller.html",children:"contract_api::runtime::get_caller"})," function."]}),"\n",(0,c.jsx)(e.h2,{id:"the-call-stack",children:"The Call Stack"}),"\n",(0,c.jsxs)(e.p,{children:["Developers can access the call stack with the ",(0,c.jsx)(e.a,{href:"https://docs.rs/casper-contract/3.0.0/casper_contract/contract_api/runtime/fn.get_call_stack.html",children:"contract_api::runtime::get_call_stack"})," function."]}),"\n",(0,c.jsxs)(e.p,{children:["If session code calls a contract, which in turn calls another contract, then the session code would represent the ",(0,c.jsx)(e.em,{children:"zeroth"})," entity in the stack, the contract called by the initiating session code would be the ",(0,c.jsx)(e.em,{children:"first"})," and the contract called by the first contract would be the ",(0,c.jsx)(e.em,{children:"second"}),"."]}),"\n",(0,c.jsxs)(e.p,{children:["In this example, the first contract would be the ",(0,c.jsx)(e.code,{children:"immediate caller"})," of the second contract, meaning it interacted directly with it. The session code would remain the ",(0,c.jsx)(e.code,{children:"caller"}),"."]}),"\n",(0,c.jsx)(e.p,{children:(0,c.jsx)(e.img,{alt:"Call Stack",src:n(76605).A+"",width:"1024",height:"576"})}),"\n",(0,c.jsx)(e.h2,{id:"limitations",children:"Limitations"}),"\n",(0,c.jsxs)(e.p,{children:["Casper networks place a limitation on the maximum height of a call stack. This value can be set within the ",(0,c.jsx)(e.code,{children:"chainspec"})," for the network in question. For the Casper Mainnet, this limit is set at ",(0,c.jsx)(e.code,{children:"10"})," contracts. This does not include the initiating session code, which would still count as the ",(0,c.jsx)(e.em,{children:"zeroth"})," instance within the stack."]}),"\n",(0,c.jsx)(e.p,{children:"As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation."}),"\n",(0,c.jsx)(e.admonition,{type:"note",children:(0,c.jsx)(e.p,{children:"Contract code cannot call session code, only other contract code."})})]})}function d(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,c.jsx)(e,{...t,children:(0,c.jsx)(h,{...t})}):h(t)}},76605:(t,e,n)=>{n.d(e,{A:()=>c});const c=n.p+"assets/images/callstack-b77837c35962b1314c65801ee56f8321.png"},28453:(t,e,n)=>{n.d(e,{R:()=>i,x:()=>o});var c=n(96540);const s={},a=c.createContext(s);function i(t){const e=c.useContext(a);return c.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function o(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),c.createElement(a.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/738a6ad4.cf62d230.js b/assets/js/738a6ad4.cf62d230.js deleted file mode 100644 index d2059bc1d..000000000 --- a/assets/js/738a6ad4.cf62d230.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8727],{78009:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var t=s(74848),i=s(28453);const r={title:"Join a Network"},d="Joining a Running Network",o={id:"operators/setup/joining",title:"Join a Network",description:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.",source:"@site/versioned_docs/version-1.5.X/operators/setup/joining.md",sourceDirName:"operators/setup",slug:"/operators/setup/joining",permalink:"/operators/setup/joining",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Join a Network"},sidebar:"operators",previous:{title:"Upgrades",permalink:"/operators/setup/upgrade"},next:{title:"Non-Root Users",permalink:"/operators/setup/non-root-user"}},a={},l=[{value:"Step 1: Provisioning Hardware",id:"step-1-provision-hardware",level:2},{value:"Step 2: Setting Up the Node",id:"step-2-set-up-the-node",level:2},{value:"Step 3: Building the Required Contracts",id:"step-3-build-contracts",level:2},{value:"Step 4: Creating and Fund Keys for Bonding",id:"step-4-create--fund-keys-for-bonding",level:2},{value:"Step 5: Updating the Trusted Hash",id:"step-5-update-the-trusted-hash",level:2},{value:"Step 6: Starting the Node",id:"step-6-start-the-node",level:2},{value:"Step 7: Confirming the Node is Synchronized",id:"step-7-confirm-the-node-is-synchronized",level:2},{value:"Step 8: Sending the Bonding Request",id:"step-7-send-the-bonding-request",level:2}];function c(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"joining-a-running-network",children:"Joining a Running Network"})}),"\n",(0,t.jsx)(n.p,{children:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network."}),"\n",(0,t.jsx)(n.h2,{id:"step-1-provision-hardware",children:"Step 1: Provisioning Hardware"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/operators/setup/hardware",children:"Hardware Specifications"})," section and provision your node hardware."]}),"\n",(0,t.jsx)(n.h2,{id:"step-2-set-up-the-node",children:"Step 2: Setting Up the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the instructions on the ",(0,t.jsx)(n.a,{href:"/operators/setup/install-node",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"step-3-build-contracts",children:"Step 3: Building the Required Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the casper-node repository."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Install these prerequisites, which are also listed ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node#pre-requisites-for-building",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Rust"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"CMake"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pkg-config"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install pkg-config"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"openssl"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install openssl"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"libssl-dev"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install libssl-dev"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Rust casper-client"})," and fund the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"keys"})," you will use for bonding."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Use the following commands to build the contracts in release mode. Make sure you have ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"installed Rust"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-client-contracts\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will build all the necessary Wasm contracts for operating as a validator:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"activate_bid.wasm"})," - Reactivates an ejected validator"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_bid.wasm"})," - Enables bonding for validator stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegate.wasm"})," - Delegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"undelegate.wasm"})," - Undelegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"withdraw_bid.wasm"})," - Enables unbonding for validator stake"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-4-create--fund-keys-for-bonding",children:"Step 4: Creating and Fund Keys for Bonding"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," instructions if you have not generated and funded your validator keys."]}),"\n",(0,t.jsx)(n.h2,{id:"step-5-update-the-trusted-hash",children:"Step 5: Updating the Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["The node's ",(0,t.jsx)(n.code,{children:"config.toml"})," needs to be updated with a recent trusted hash."]}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Trusted Hash for Synchronizing"})," instructions if you have not set up a trusted hash during node installation."]}),"\n",(0,t.jsx)(n.h2,{id:"step-6-start-the-node",children:"Step 6: Starting the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Start the node with the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above Debian package installs a casper-node service for systemd."}),"\n",(0,t.jsxs)(n.p,{children:["For more information, visit ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/wiki#node-operators",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-confirm-the-node-is-synchronized",children:"Step 7: Confirming the Node is Synchronized"}),"\n",(0,t.jsxs)(n.p,{children:["While the node is synchronizing, the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint is available. You will be able to compare this to another node's status endpoint ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," to determine if you are caught up. You will not be able to perform any ",(0,t.jsx)(n.code,{children:"casper-client"})," calls to your ",(0,t.jsx)(n.code,{children:"7777"})," RPC port until your node is fully caught up."]}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, notice the ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," that you can use to determine if your node has completed synchronizing."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsxs)(n.summary,{children:["Sample output of the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.3",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",\n "peers": [\n {\n "node_id": "tls:0097..b253",\n "address": "18.163.249.168:35000"\n },\n ...\n ...\n ...\n {\n "node_id": "tls:ff95..c014",\n "address": "93.186.201.14:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",\n "timestamp": "2022-01-04T15:33:08.224Z",\n "era_id": 3240,\n "height": 430162,\n "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",\n "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"\n },\n "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",\n "round_length": null,\n "next_upgrade": null,\n "build_version": "1.4.3-a44bed1fd-casper-mainnet",\n "uptime": "25days 1h 48m 22s 47ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-send-the-bonding-request",children:"Step 8: Sending the Bonding Request"}),"\n",(0,t.jsxs)(n.p,{children:["You can submit a ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding",children:"bonding request"})," to change your synchronized node to a validating node."]}),"\n",(0,t.jsx)(n.p,{children:"The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var t=s(96540);const i={},r=t.createContext(i);function d(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/738a6ad4.df968aee.js b/assets/js/738a6ad4.df968aee.js new file mode 100644 index 000000000..851bf632e --- /dev/null +++ b/assets/js/738a6ad4.df968aee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28727],{78009:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var t=s(74848),i=s(28453);const r={title:"Join a Network"},d="Joining a Running Network",o={id:"operators/setup/joining",title:"Join a Network",description:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.",source:"@site/versioned_docs/version-1.5.X/operators/setup/joining.md",sourceDirName:"operators/setup",slug:"/operators/setup/joining",permalink:"/1.5.X/operators/setup/joining",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Join a Network"},sidebar:"operators",previous:{title:"Upgrades",permalink:"/1.5.X/operators/setup/upgrade"},next:{title:"Non-Root Users",permalink:"/1.5.X/operators/setup/non-root-user"}},a={},l=[{value:"Step 1: Provisioning Hardware",id:"step-1-provision-hardware",level:2},{value:"Step 2: Setting Up the Node",id:"step-2-set-up-the-node",level:2},{value:"Step 3: Building the Required Contracts",id:"step-3-build-contracts",level:2},{value:"Step 4: Creating and Fund Keys for Bonding",id:"step-4-create--fund-keys-for-bonding",level:2},{value:"Step 5: Updating the Trusted Hash",id:"step-5-update-the-trusted-hash",level:2},{value:"Step 6: Starting the Node",id:"step-6-start-the-node",level:2},{value:"Step 7: Confirming the Node is Synchronized",id:"step-7-confirm-the-node-is-synchronized",level:2},{value:"Step 8: Sending the Bonding Request",id:"step-7-send-the-bonding-request",level:2}];function c(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"joining-a-running-network",children:"Joining a Running Network"})}),"\n",(0,t.jsx)(n.p,{children:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network."}),"\n",(0,t.jsx)(n.h2,{id:"step-1-provision-hardware",children:"Step 1: Provisioning Hardware"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/hardware",children:"Hardware Specifications"})," section and provision your node hardware."]}),"\n",(0,t.jsx)(n.h2,{id:"step-2-set-up-the-node",children:"Step 2: Setting Up the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the instructions on the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"step-3-build-contracts",children:"Step 3: Building the Required Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the casper-node repository."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Install these prerequisites, which are also listed ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node#pre-requisites-for-building",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Rust"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"CMake"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pkg-config"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install pkg-config"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"openssl"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install openssl"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"libssl-dev"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install libssl-dev"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Rust casper-client"})," and fund the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#create-fund-keys",children:"keys"})," you will use for bonding."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Use the following commands to build the contracts in release mode. Make sure you have ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"installed Rust"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-client-contracts\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will build all the necessary Wasm contracts for operating as a validator:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"activate_bid.wasm"})," - Reactivates an ejected validator"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_bid.wasm"})," - Enables bonding for validator stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegate.wasm"})," - Delegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"undelegate.wasm"})," - Undelegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"withdraw_bid.wasm"})," - Enables unbonding for validator stake"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-4-create--fund-keys-for-bonding",children:"Step 4: Creating and Fund Keys for Bonding"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," instructions if you have not generated and funded your validator keys."]}),"\n",(0,t.jsx)(n.h2,{id:"step-5-update-the-trusted-hash",children:"Step 5: Updating the Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["The node's ",(0,t.jsx)(n.code,{children:"config.toml"})," needs to be updated with a recent trusted hash."]}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Trusted Hash for Synchronizing"})," instructions if you have not set up a trusted hash during node installation."]}),"\n",(0,t.jsx)(n.h2,{id:"step-6-start-the-node",children:"Step 6: Starting the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Start the node with the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above Debian package installs a casper-node service for systemd."}),"\n",(0,t.jsxs)(n.p,{children:["For more information, visit ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/wiki#node-operators",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-confirm-the-node-is-synchronized",children:"Step 7: Confirming the Node is Synchronized"}),"\n",(0,t.jsxs)(n.p,{children:["While the node is synchronizing, the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint is available. You will be able to compare this to another node's status endpoint ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," to determine if you are caught up. You will not be able to perform any ",(0,t.jsx)(n.code,{children:"casper-client"})," calls to your ",(0,t.jsx)(n.code,{children:"7777"})," RPC port until your node is fully caught up."]}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, notice the ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," that you can use to determine if your node has completed synchronizing."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsxs)(n.summary,{children:["Sample output of the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.3",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",\n "peers": [\n {\n "node_id": "tls:0097..b253",\n "address": "18.163.249.168:35000"\n },\n ...\n ...\n ...\n {\n "node_id": "tls:ff95..c014",\n "address": "93.186.201.14:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",\n "timestamp": "2022-01-04T15:33:08.224Z",\n "era_id": 3240,\n "height": 430162,\n "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",\n "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"\n },\n "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",\n "round_length": null,\n "next_upgrade": null,\n "build_version": "1.4.3-a44bed1fd-casper-mainnet",\n "uptime": "25days 1h 48m 22s 47ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-send-the-bonding-request",children:"Step 8: Sending the Bonding Request"}),"\n",(0,t.jsxs)(n.p,{children:["You can submit a ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/bonding",children:"bonding request"})," to change your synchronized node to a validating node."]}),"\n",(0,t.jsx)(n.p,{children:"The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>o});var t=s(96540);const i={},r=t.createContext(i);function d(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/74d57d33.872e0d5f.js b/assets/js/74d57d33.872e0d5f.js new file mode 100644 index 000000000..7d229baac --- /dev/null +++ b/assets/js/74d57d33.872e0d5f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60200],{92827:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Funding Mainnet Accounts"},a="Funding Mainnet Accounts from an Exchange",o={id:"users/funding-from-exchanges",title:"Funding Mainnet Accounts",description:"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.",source:"@site/docs/users/funding-from-exchanges.md",sourceDirName:"users",slug:"/users/funding-from-exchanges",permalink:"/users/funding-from-exchanges",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Funding Mainnet Accounts"},sidebar:"users",previous:{title:"Block Explorers",permalink:"/users/block-explorer"},next:{title:"Delegating Tokens",permalink:"/users/delegating"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Transfers from Coinlist to Casper Mainnet",id:"transfers-from-coinlist-to-casper-mainnet",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"funding-mainnet-accounts-from-an-exchange",children:"Funding Mainnet Accounts from an Exchange"})}),"\n",(0,s.jsxs)(n.p,{children:["To send CSPR tokens from an exchange to a Mainnet account, you need the ",(0,s.jsx)(n.strong,{children:"Mainnet account's public key"}),". Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide demonstrates a withdrawal from ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"Coinlist"})," to the Casper Mainnet using the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer. You need to contact the exchange for instructions if you are working with a different exchange."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," and the field you need to specify in the withdrawal request from Coinlist."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Account public key from CSPR.Live",src:t(33261).A+"",width:"2412",height:"1008"})}),"\n",(0,s.jsx)(n.h2,{id:"transfers-from-coinlist-to-casper-mainnet",children:"Transfers from Coinlist to Casper Mainnet"}),"\n",(0,s.jsx)(n.p,{children:"Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Log into your ",(0,s.jsx)(n.a,{href:"https://coinlist.co",children:"https://coinlist.co"})," account."]}),"\n",(0,s.jsx)(n.li,{children:'Go to the "Wallet" tab.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Coinlist Wallet tab",src:t(58812).A+"",width:"208",height:"385"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "CSPR" section.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CSPR on Coinlist",src:t(86254).A+"",width:"224",height:"241"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "Withdraw" button.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdraw on Coinlist",src:t(20793).A+"",width:"977",height:"389"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:'Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdrawal fields on Coinlist",src:t(23344).A+"",width:"433",height:"537"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['Enter 0 in the "Transfer ID" field or another value that is meaningful to you. ',(0,s.jsx)(n.strong,{children:"You MUST enter a value, or the transfer will fail!"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enter the CSPR amount you wish to transfer."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'Click "Review".'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Submit the transfer request. Wait approximately 5 minutes, and then go to the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),' site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.']}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},33261:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.account-public-key-bc632beb571934137e88fe4669e3fb2d.png"},58812:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.coinlist-wallet-cad5dafdacd2765f28866b9873302238.png"},86254:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.cspr-section-coinlist-0d627442f8f9412464d23060184c98b4.png"},20793:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.withdraw-coinlist-7823f45f8471dcfa637fc6e803b157ac.png"},23344:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.withdraw-fields-coinlist-e701e55f389ca38a109a393565234c56.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/74d57d33.882cb0d6.js b/assets/js/74d57d33.882cb0d6.js deleted file mode 100644 index 1fbe0c3ee..000000000 --- a/assets/js/74d57d33.882cb0d6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[200],{92827:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Funding Mainnet Accounts"},a="Funding Mainnet Accounts from an Exchange",o={id:"users/funding-from-exchanges",title:"Funding Mainnet Accounts",description:"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.",source:"@site/docs/users/funding-from-exchanges.md",sourceDirName:"users",slug:"/users/funding-from-exchanges",permalink:"/next/users/funding-from-exchanges",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Funding Mainnet Accounts"},sidebar:"users",previous:{title:"Block Explorers",permalink:"/next/users/block-explorer"},next:{title:"Delegating Tokens",permalink:"/next/users/delegating"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Transfers from Coinlist to Casper Mainnet",id:"transfers-from-coinlist-to-casper-mainnet",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"funding-mainnet-accounts-from-an-exchange",children:"Funding Mainnet Accounts from an Exchange"})}),"\n",(0,s.jsxs)(n.p,{children:["To send CSPR tokens from an exchange to a Mainnet account, you need the ",(0,s.jsx)(n.strong,{children:"Mainnet account's public key"}),". Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide demonstrates a withdrawal from ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"Coinlist"})," to the Casper Mainnet using the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer. You need to contact the exchange for instructions if you are working with a different exchange."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," and the field you need to specify in the withdrawal request from Coinlist."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Account public key from CSPR.Live",src:t(331).A+"",width:"2412",height:"1008"})}),"\n",(0,s.jsx)(n.h2,{id:"transfers-from-coinlist-to-casper-mainnet",children:"Transfers from Coinlist to Casper Mainnet"}),"\n",(0,s.jsx)(n.p,{children:"Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Log into your ",(0,s.jsx)(n.a,{href:"https://coinlist.co",children:"https://coinlist.co"})," account."]}),"\n",(0,s.jsx)(n.li,{children:'Go to the "Wallet" tab.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Coinlist Wallet tab",src:t(35882).A+"",width:"208",height:"385"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "CSPR" section.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CSPR on Coinlist",src:t(49756).A+"",width:"224",height:"241"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "Withdraw" button.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdraw on Coinlist",src:t(63651).A+"",width:"977",height:"389"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:'Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdrawal fields on Coinlist",src:t(6590).A+"",width:"433",height:"537"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['Enter 0 in the "Transfer ID" field or another value that is meaningful to you. ',(0,s.jsx)(n.strong,{children:"You MUST enter a value, or the transfer will fail!"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enter the CSPR amount you wish to transfer."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'Click "Review".'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Submit the transfer request. Wait approximately 5 minutes, and then go to the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),' site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.']}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},331:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.account-public-key-bc632beb571934137e88fe4669e3fb2d.png"},35882:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.coinlist-wallet-cad5dafdacd2765f28866b9873302238.png"},49756:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.cspr-section-coinlist-0d627442f8f9412464d23060184c98b4.png"},63651:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.withdraw-coinlist-7823f45f8471dcfa637fc6e803b157ac.png"},6590:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.withdraw-fields-coinlist-e701e55f389ca38a109a393565234c56.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/753d7b98.669096ae.js b/assets/js/753d7b98.669096ae.js new file mode 100644 index 000000000..c8c9f3346 --- /dev/null +++ b/assets/js/753d7b98.669096ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1790],{440:(a,b,c)=>{c.r(b),c.d(b,{assets:()=>s,contentTitle:()=>f,default:()=>o,frontMatter:()=>n,metadata:()=>t,toc:()=>r});var e=c(74848),d=c(28453);const n={},f="Transactional JSON-RPC Methods",t={id:"developers/json-rpc/json-rpc-transactional",title:"Transactional JSON-RPC Methods",description:"---",source:"@site/docs/developers/json-rpc/json-rpc-transactional.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-transactional",permalink:"/developers/json-rpc/json-rpc-transactional",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723747045e3,frontMatter:{},sidebar:"developers",previous:{title:"Required Methods for Minimal Compliance",permalink:"/developers/json-rpc/minimal-compliance"},next:{title:"Informational JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-informational"}},s={},r=[{value:"account_put_deploy",id:"account_put_deploy",level:2},{value:"<code>account_put_deploy_result</code>",id:"account_put_deploy_result",level:3},{value:"account_put_transaction",id:"account_put_transaction",level:2},{value:"<code>account_put_transaction_result</code>",id:"account_put_transaction_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"<code>speculative_exec_result</code>",id:"speculative_exec_result",level:3},{value:"speculative_exec_txn",id:"speculative_exec_txn",level:2},{value:"<code>speculative_exec_txn_result</code>",id:"speculative_exec_txn_result",level:3}];function i(a){const b={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(b.header,{children:(0,e.jsx)(b.h1,{id:"transactional-json-rpc-methods",children:"Transactional JSON-RPC Methods"})}),"\n",(0,e.jsx)(b.hr,{}),"\n",(0,e.jsx)(b.h2,{id:"account_put_deploy",children:"account_put_deploy"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#account-put-transaction",children:"account_put_transaction"})," instead."]})}),"\n",(0,e.jsx)(b.p,{children:"This endpoint allows sending a deploy to be executed by the network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "name": "deploy",\n "value": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_deploy_result",children:(0,e.jsx)(b.code,{children:"account_put_deploy_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and a ",(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"}),", which is the primary identifier of a Deploy within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the Deploy as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"account_put_transaction",children:"account_put_transaction"}),"\n",(0,e.jsxs)(b.p,{children:["This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the ",(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transaction",children:"transaction"})," as a parameter, prior to sending it to a node on a network for execution."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsxs)(b.td,{children:["A transaction consists of an item containing a Deploy and a ",(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transaction",children:(0,e.jsx)(b.code,{children:"Transaction"})})," along with the requester's signature(s)."]})]})})]}),"\n",(0,e.jsxs)(b.blockquote,{children:["\n",(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"Note"}),": You can find a list of ",(0,e.jsx)(b.a,{href:"/operators/setup/joining",children:"trusted peers"})," in the network's configuration file, ",(0,e.jsx)(b.code,{children:"config.toml"}),". Here is an ",(0,e.jsx)(b.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example config.toml"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n"]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_transaction",\n "params": [\n {\n "name": "transaction",\n "value": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_transaction_result",children:(0,e.jsx)(b.code,{children:"account_put_transaction_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and the ",(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"}),", which is the primary identifier of a transaction within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the transaction as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec",children:"speculative_exec"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#speculative-exec-txn",children:"speculative_exec_txn"})," instead."]})}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Deploy"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#executionresult",children:"execution_results"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"The map of Block hash to execution result."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec_txn",children:"speculative_exec_txn"}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Transaction"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Transaction is a versioned wrapper for a transaction or deploy."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec_txn",\n "params": {\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_txn_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_txn_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/developers/json-rpc/types_chain#executionresult",children:"execution_result"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"Result of the speculative execution."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_txn_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function o(a={}){const{wrapper:b}={...(0,d.R)(),...a.components};return b?(0,e.jsx)(b,{...a,children:(0,e.jsx)(i,{...a})}):i(a)}},28453:(a,b,c)=>{c.d(b,{R:()=>f,x:()=>t});var e=c(96540);const d={},n=e.createContext(d);function f(a){const b=e.useContext(n);return e.useMemo((function(){return"function"==typeof a?a(b):{...b,...a}}),[b,a])}function t(a){let b;return b=a.disableParentContext?"function"==typeof a.components?a.components(d):a.components||d:f(a.components),e.createElement(n.Provider,{value:b},a.children)}}}]); \ No newline at end of file diff --git a/assets/js/753d7b98.aa766a46.js b/assets/js/753d7b98.aa766a46.js deleted file mode 100644 index 30d8ab36b..000000000 --- a/assets/js/753d7b98.aa766a46.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1790],{440:(a,b,c)=>{c.r(b),c.d(b,{assets:()=>s,contentTitle:()=>f,default:()=>o,frontMatter:()=>n,metadata:()=>t,toc:()=>r});var e=c(74848),d=c(28453);const n={},f="Transactional JSON-RPC Methods",t={id:"developers/json-rpc/json-rpc-transactional",title:"Transactional JSON-RPC Methods",description:"---",source:"@site/docs/developers/json-rpc/json-rpc-transactional.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-transactional",permalink:"/next/developers/json-rpc/json-rpc-transactional",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723747045e3,frontMatter:{},sidebar:"developers",previous:{title:"Required Methods for Minimal Compliance",permalink:"/next/developers/json-rpc/minimal-compliance"},next:{title:"Informational JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-informational"}},s={},r=[{value:"account_put_deploy",id:"account_put_deploy",level:2},{value:"<code>account_put_deploy_result</code>",id:"account_put_deploy_result",level:3},{value:"account_put_transaction",id:"account_put_transaction",level:2},{value:"<code>account_put_transaction_result</code>",id:"account_put_transaction_result",level:3},{value:"speculative_exec",id:"speculative_exec",level:2},{value:"<code>speculative_exec_result</code>",id:"speculative_exec_result",level:3},{value:"speculative_exec_txn",id:"speculative_exec_txn",level:2},{value:"<code>speculative_exec_txn_result</code>",id:"speculative_exec_txn_result",level:3}];function i(a){const b={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,d.R)(),...a.components};return(0,e.jsxs)(e.Fragment,{children:[(0,e.jsx)(b.header,{children:(0,e.jsx)(b.h1,{id:"transactional-json-rpc-methods",children:"Transactional JSON-RPC Methods"})}),"\n",(0,e.jsx)(b.hr,{}),"\n",(0,e.jsx)(b.h2,{id:"account_put_deploy",children:"account_put_deploy"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#account-put-transaction",children:"account_put_transaction"})," instead."]})}),"\n",(0,e.jsx)(b.p,{children:"This endpoint allows sending a deploy to be executed by the network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": [\n {\n "name": "deploy",\n "value": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_deploy_result",children:(0,e.jsx)(b.code,{children:"account_put_deploy_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and a ",(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"}),", which is the primary identifier of a Deploy within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the Deploy as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_deploy result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"account_put_transaction",children:"account_put_transaction"}),"\n",(0,e.jsxs)(b.p,{children:["This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the ",(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:"transaction"})," as a parameter, prior to sending it to a node on a network for execution."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsxs)(b.td,{children:["A transaction consists of an item containing a Deploy and a ",(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:(0,e.jsx)(b.code,{children:"Transaction"})})," along with the requester's signature(s)."]})]})})]}),"\n",(0,e.jsxs)(b.blockquote,{children:["\n",(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"Note"}),": You can find a list of ",(0,e.jsx)(b.a,{href:"/next/operators/setup/joining",children:"trusted peers"})," in the network's configuration file, ",(0,e.jsx)(b.code,{children:"config.toml"}),". Here is an ",(0,e.jsx)(b.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example config.toml"}),". You may send transactions to one of the trusted nodes or use them to query other online nodes."]}),"\n"]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_transaction",\n "params": [\n {\n "name": "transaction",\n "value": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"account_put_transaction_result",children:(0,e.jsx)(b.code,{children:"account_put_transaction_result"})}),"\n",(0,e.jsxs)(b.p,{children:["The result contains the RPC API version and the ",(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"}),", which is the primary identifier of a transaction within a Casper network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"A hex-encoded hash of the transaction as sent."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example account_put_transaction result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "account_put_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec",children:"speculative_exec"}),"\n",(0,e.jsx)(b.admonition,{type:"caution",children:(0,e.jsxs)(b.p,{children:[(0,e.jsx)(b.strong,{children:"DEPRECATED"}),": Use ",(0,e.jsx)(b.a,{href:"#speculative-exec-txn",children:"speculative_exec_txn"})," instead."]})}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Deploy"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Deploy consists of an item containing a smart contract along with the requester's signature(s)."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec",\n "params": {\n "deploy": {\n "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",\n "header": {\n "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "timestamp": "2023-05-23T13:32:45.554Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",\n "dependencies": [],\n "chain_name": "integration-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",\n "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010000000000000000",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",\n "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"\n }\n ]\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#executionresult",children:"execution_results"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"The map of Block hash to execution result."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h2,{id:"speculative_exec_txn",children:"speculative_exec_txn"}),"\n",(0,e.jsxs)(b.p,{children:["The ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," endpoint allows executing a ",(0,e.jsx)(b.code,{children:"Transaction"})," without committing its execution effects to global state. By default, ",(0,e.jsx)(b.code,{children:"speculative_exec_txn"})," is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsx)(b.tbody,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"A Transaction is a versioned wrapper for a transaction or deploy."})]})})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn request"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "method": "speculative_exec_txn",\n "params": {\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n }\n },\n "id": 6889533540839698701\n}\n\n'})}),"\n"]}),"\n",(0,e.jsx)(b.h3,{id:"speculative_exec_txn_result",children:(0,e.jsx)(b.code,{children:"speculative_exec_txn_result"})}),"\n",(0,e.jsx)(b.p,{children:"The result contains the RPC API version and the speculative execution result."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,e.jsxs)(b.table,{children:[(0,e.jsx)(b.thead,{children:(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.th,{children:"Parameter"}),(0,e.jsx)(b.th,{children:"Type"}),(0,e.jsx)(b.th,{children:"Description"})]})}),(0,e.jsxs)(b.tbody,{children:[(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:"api_version"}),(0,e.jsx)(b.td,{children:"String"}),(0,e.jsx)(b.td,{children:"The RPC API version."})]}),(0,e.jsxs)(b.tr,{children:[(0,e.jsx)(b.td,{children:(0,e.jsx)(b.a,{href:"/next/developers/json-rpc/types_chain#executionresult",children:"execution_result"})}),(0,e.jsx)(b.td,{children:"Object"}),(0,e.jsx)(b.td,{children:"Result of the speculative execution."})]})]})]}),"\n",(0,e.jsxs)(b.details,{children:["\n",(0,e.jsx)(b.summary,{children:"Example speculative_exec_txn result"}),"\n",(0,e.jsx)(b.pre,{children:(0,e.jsx)(b.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "speculative_exec_txn_result",\n "value": {\n "api_version": "2.0.0",\n "execution_result": {\n "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",\n "transfers": [],\n "limit": "100000000000",\n "consumed": "23289743502",\n "effects": [\n {\n "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"\n },\n "name": {\n "cl_type": "String",\n "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",\n "parsed": "test_payment_package_hash"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",\n "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000746573745f7061796d656e745f616363657373",\n "parsed": "test_payment_access"\n }\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": "Identity"\n },\n {\n "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",\n "kind": "Identity"\n },\n {\n "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "pay",\n "args": [\n {\n "name": "amount",\n "cl_type": "U512"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",\n "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",\n "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "10000000636f6e74726163745f76657273696f6e",\n "parsed": "contract_version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",\n "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"\n },\n "name": {\n "cl_type": "String",\n "bytes": "11000000746573745f7061796d656e745f68617368",\n "parsed": "test_payment_hash"\n }\n }\n }\n }\n }\n ],\n "messages": [],\n "error": null\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function o(a={}){const{wrapper:b}={...(0,d.R)(),...a.components};return b?(0,e.jsx)(b,{...a,children:(0,e.jsx)(i,{...a})}):i(a)}},28453:(a,b,c)=>{c.d(b,{R:()=>f,x:()=>t});var e=c(96540);const d={},n=e.createContext(d);function f(a){const b=e.useContext(n);return e.useMemo((function(){return"function"==typeof a?a(b):{...b,...a}}),[b,a])}function t(a){let b;return b=a.disableParentContext?"function"==typeof a.components?a.components(d):a.components||d:f(a.components),e.createElement(n.Provider,{value:b},a.children)}}}]); \ No newline at end of file diff --git a/assets/js/75de5623.40d8f83e.js b/assets/js/75de5623.40d8f83e.js deleted file mode 100644 index 0b34e6740..000000000 --- a/assets/js/75de5623.40d8f83e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2670],{82799:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Funding Mainnet Accounts"},c="Funding Mainnet Accounts from an Exchange",o={id:"users/funding-from-exchanges",title:"Funding Mainnet Accounts",description:"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.",source:"@site/versioned_docs/version-1.5.X/users/funding-from-exchanges.md",sourceDirName:"users",slug:"/users/funding-from-exchanges",permalink:"/users/funding-from-exchanges",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Funding Mainnet Accounts"},sidebar:"users",previous:{title:"Block Explorers",permalink:"/users/block-explorer"},next:{title:"Using CSPR.live",permalink:"/users/csprlive/"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Transfers from Coinlist to Casper Mainnet",id:"transfers-from-coinlist-to-casper-mainnet",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"funding-mainnet-accounts-from-an-exchange",children:"Funding Mainnet Accounts from an Exchange"})}),"\n",(0,s.jsxs)(n.p,{children:["To send CSPR tokens from an exchange to a Mainnet account, you need the ",(0,s.jsx)(n.strong,{children:"Mainnet account's public key"}),". Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide demonstrates a withdrawal from ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"Coinlist"})," to the Casper Mainnet using the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer. You need to contact the exchange for instructions if you are working with a different exchange."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," and the field you need to specify in the withdrawal request from Coinlist."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(35528).A+"",width:"2412",height:"1008"})}),"\n",(0,s.jsx)(n.h2,{id:"transfers-from-coinlist-to-casper-mainnet",children:"Transfers from Coinlist to Casper Mainnet"}),"\n",(0,s.jsx)(n.p,{children:"Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Log into your ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"https://coinlist.co/"})," account."]}),"\n",(0,s.jsx)(n.li,{children:'Go to the "Wallet" tab.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(55095).A+"",width:"208",height:"385"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "CSPR" section.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(55581).A+"",width:"224",height:"241"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "Withdraw" button.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(74246).A+"",width:"977",height:"389"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:'Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(24869).A+"",width:"433",height:"537"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['Enter 0 in the "Transfer ID" field or another value that is meaningful to you. ',(0,s.jsx)(n.strong,{children:"You MUST enter a value, or the transfer will fail!"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enter the CSPR amount you wish to transfer."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'Click "Review".'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Submit the transfer request. Wait approximately 5 minutes, and then go to the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),' site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.']}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},35528:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.account-public-key-bc632beb571934137e88fe4669e3fb2d.png"},55095:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.coinlist-wallet-cad5dafdacd2765f28866b9873302238.png"},55581:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.cspr-section-coinlist-0d627442f8f9412464d23060184c98b4.png"},74246:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.withdraw-coinlist-7823f45f8471dcfa637fc6e803b157ac.png"},24869:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.withdraw-fields-coinlist-e701e55f389ca38a109a393565234c56.png"},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/75de5623.515b1f12.js b/assets/js/75de5623.515b1f12.js new file mode 100644 index 000000000..c585bfd0c --- /dev/null +++ b/assets/js/75de5623.515b1f12.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32670],{82799:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Funding Mainnet Accounts"},c="Funding Mainnet Accounts from an Exchange",o={id:"users/funding-from-exchanges",title:"Funding Mainnet Accounts",description:"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.",source:"@site/versioned_docs/version-1.5.X/users/funding-from-exchanges.md",sourceDirName:"users",slug:"/users/funding-from-exchanges",permalink:"/1.5.X/users/funding-from-exchanges",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Funding Mainnet Accounts"},sidebar:"users",previous:{title:"Block Explorers",permalink:"/1.5.X/users/block-explorer"},next:{title:"Using CSPR.live",permalink:"/1.5.X/users/csprlive/"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Transfers from Coinlist to Casper Mainnet",id:"transfers-from-coinlist-to-casper-mainnet",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"funding-mainnet-accounts-from-an-exchange",children:"Funding Mainnet Accounts from an Exchange"})}),"\n",(0,s.jsxs)(n.p,{children:["To send CSPR tokens from an exchange to a Mainnet account, you need the ",(0,s.jsx)(n.strong,{children:"Mainnet account's public key"}),". Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide demonstrates a withdrawal from ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"Coinlist"})," to the Casper Mainnet using the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer. You need to contact the exchange for instructions if you are working with a different exchange."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," and the field you need to specify in the withdrawal request from Coinlist."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(63114).A+"",width:"2412",height:"1008"})}),"\n",(0,s.jsx)(n.h2,{id:"transfers-from-coinlist-to-casper-mainnet",children:"Transfers from Coinlist to Casper Mainnet"}),"\n",(0,s.jsx)(n.p,{children:"Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Log into your ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"https://coinlist.co/"})," account."]}),"\n",(0,s.jsx)(n.li,{children:'Go to the "Wallet" tab.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(18209).A+"",width:"208",height:"385"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "CSPR" section.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(62071).A+"",width:"224",height:"241"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "Withdraw" button.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(57644).A+"",width:"977",height:"389"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:'Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{src:t(1903).A+"",width:"433",height:"537"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['Enter 0 in the "Transfer ID" field or another value that is meaningful to you. ',(0,s.jsx)(n.strong,{children:"You MUST enter a value, or the transfer will fail!"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enter the CSPR amount you wish to transfer."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'Click "Review".'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Submit the transfer request. Wait approximately 5 minutes, and then go to the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"}),' site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.']}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},63114:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.account-public-key-bc632beb571934137e88fe4669e3fb2d.png"},18209:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.coinlist-wallet-cad5dafdacd2765f28866b9873302238.png"},62071:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.cspr-section-coinlist-0d627442f8f9412464d23060184c98b4.png"},57644:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.withdraw-coinlist-7823f45f8471dcfa637fc6e803b157ac.png"},1903:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.withdraw-fields-coinlist-e701e55f389ca38a109a393565234c56.png"},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7607f1d5.09164840.js b/assets/js/7607f1d5.09164840.js deleted file mode 100644 index 5c77db0ab..000000000 --- a/assets/js/7607f1d5.09164840.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[793],{27843:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const o={title:"Front-end in React"},i="Front-end Template with React",a={id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/docs/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/next/developers/dapps/template-frontend",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/next/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/next/developers/dapps/uref-security"}},c={},l=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"front-end-template-with-react",children:"Front-end Template with React"})}),"\n",(0,s.jsxs)(n.p,{children:["For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide will walk you through setting up and developing a React application with ",(0,s.jsx)(n.a,{href:"https://vitejs.dev/",children:"Vite"})," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,s.jsx)(n.a,{href:"https://reactjs.org/docs/getting-started.html",children:"reading the React documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,s.jsx)(n.p,{children:"Begin by opening a terminal and running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"node -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"To get your Node.js version."}),"\n",(0,s.jsxs)(n.p,{children:["To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:"Node Version Manager"})," or another tool if you are running an earlier version."]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",children:"npm"}),", create a new Vite project by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install -g vite\nnpm create vite@latest\n"})}),"\n",(0,s.jsx)(n.p,{children:'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'}),"\n",(0,s.jsxs)(n.p,{children:["Head into your new project directory, replacing ",(0,s.jsx)(n.code,{children:"vite-project"})," with your project name:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd vite-project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command to test the server:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install\nvite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Quit the server by pressing ",(0,s.jsx)(n.code,{children:"q"}),". Install the Casper JS SDK by running the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide will use ",(0,s.jsx)(n.a,{href:"https://axios-http.com/",children:"axios"})," to communicate with the backend; install it by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install axios\n"})}),"\n",(0,s.jsx)(n.h2,{id:"casper-wallet-integration",children:"Casper Wallet Integration"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,s.jsx)(n.code,{children:"window.CasperWalletProvider"})," and ",(0,s.jsx)(n.code,{children:"window.CasperWalletEventTypes"}),". If the value of these variables is ",(0,s.jsx)(n.code,{children:"undefined"})," the Casper Wallet is not installed."]}),"\n",(0,s.jsx)(n.p,{children:"Start with a helper for getting the provider instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/casper-wallet.js\n"})}),"\n",(0,s.jsx)(n.p,{children:"Fill the file with the following content:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS\n });\n return provider;\n}\n\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For complete integration details, refer to ",(0,s.jsx)(n.a,{href:"https://github.com/make-software/casper-wallet-sdk/#readme",children:"README of Casper Wallet SDK"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," or another parent component that encapsulates the components that should have access to this public key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n </>)}\n </div>\n </>\n );\n}\n\nexport default App;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This is an example of ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," that imports and displays the ",(0,s.jsx)(n.code,{children:"Connect"})," component that is described next. The ",(0,s.jsx)(n.code,{children:"setPublicKey"})," function is passed to the ",(0,s.jsx)(n.code,{children:"Connect"})," component as a ",(0,s.jsx)(n.a,{href:"https://legacy.reactjs.org/docs/components-and-props.html",children:"prop"})," so that it may set the public key and make it available to all of ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),". This way, when more components are added to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", they may utilize the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable."]}),"\n",(0,s.jsxs)(n.p,{children:["To connect to the Casper Wallet within your React app, create the ",(0,s.jsx)(n.code,{children:"Connect"})," component and import the ",(0,s.jsx)(n.code,{children:"getProvider"})," helper."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Connect.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n {/* Place for disconnect button */}\n </>\n );\n}\n\nexport default Connect;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Notice that ",(0,s.jsx)(n.code,{children:"Connect"})," accepts props, and forwards them to the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," using ",(0,s.jsx)(n.code,{children:"props.setPublicKey()"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Write the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function under the ",(0,s.jsx)(n.code,{children:"Connect"})," function component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const connectToWallet = (props) => {\n provider.requestConnection().then(connected => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider.getActivePublicKey().then(publicKey => {\n props.setPublicKey(publicKey);\n }).catch(error => {\n alert(error.message);\n });\n }\n })\n .catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"connectToWallet()"})," function calls ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," will throw an error if the Wallet is not installed as an extension or if it is locked."]}),"\n",(0,s.jsx)(n.h3,{id:"disconnect-the-casper-wallet",children:"Disconnect the Casper Wallet"}),"\n",(0,s.jsxs)(n.p,{children:["To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,s.jsx)(n.em,{children:"src/Connect.jsx"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const disconnect = (props) => {\n provider.disconnectFromSite().then(disconnected => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n } \n }).catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then connect it to a button:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:"const Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n // highlight-next-line-green\n <button onClick={ () => disconnect(props) }>Disconnect</button>\n </>\n );\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"call-a-smart-contract",children:"Call a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:['For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,s.jsx)(n.code,{children:"input"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,s.jsx)(n.code,{children:"input"}),", then grab the value within the smart-contract-calling function."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/UpdateMessage.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { useState } from \'react\';\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />\n <button onClick={ () => updateMessage(props, message) }>Update Message</button>\n </>\n );\n}\n\nexport default UpdateMessage;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable passed in as a prop from ",(0,s.jsx)(n.code,{children:"src/App.jsx"}),". Write this function under your ",(0,s.jsx)(n.code,{children:"UpdateMessage"})," component function."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string(message)\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request\n axios.post("/sendDeploy", signedDeploy, {\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then((response) => {\n alert(response.data);\n }).catch((error) => {\n console.error(error.message);\n });\n }).catch((error) => {\n console.error(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In this example, ",(0,s.jsx)(n.code,{children:"updateMessage"})," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,s.jsx)(n.code,{children:"signedDeploy"})," is forwarded to the backend at the ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," endpoint using ",(0,s.jsx)(n.code,{children:"axios.post"})," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,s.jsx)(n.code,{children:"stderr"}),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert",children:"alert"}),"; however, you may do with the response data as you wish."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["The backend endpoint ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," should handle signed deployment by simply passing it to a Casper node."]}),(0,s.jsxs)(n.p,{children:["In Casper node ",(0,s.jsx)(n.code,{children:"v1.5.0"}),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node."]})]}),"\n",(0,s.jsxs)(n.p,{children:["Now that this component is created, render it to the user interface in ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", passing along the ",(0,s.jsx)(n.code,{children:"publicKey"})," as a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n // highlight-next-line-green\n <UpdateMessage publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"query-a-smart-contract",children:"Query a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Consider that the message written to the chain during the ",(0,s.jsx)(n.code,{children:"update_message"})," entrypoint invocation is stored in the ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/D#dictionary",children:"dictionary"})," ",(0,s.jsx)(n.code,{children:"messages"})," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/A#account-hash",children:"account hash"})," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Query.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return <button onClick={ () => query(props) }>Query</button>;\n}\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {\n alert(response.data)\n }).catch((error) => {\n console.error(error.message);\n });\n}\n\nexport default Query;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All this component does is render an HTML ",(0,s.jsx)(n.code,{children:"button"})," element that, when pressed, performs a ",(0,s.jsx)(n.code,{children:"GET"})," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"toAccountHashStr"}),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,s.jsx)(n.code,{children:"substring(13)"})," method."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["This functionality relies on the ",(0,s.jsx)(n.code,{children:"/queryMessage"})," endpoint, which should be implemented in your backend."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now add this component to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", making available the ",(0,s.jsx)(n.code,{children:"publicKey"})," state variable via a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n <UpdateMessage publicKey={ publicKey } />\n // highlight-next-line-green\n <Query publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"test-application",children:"Test Application"}),"\n",(0,s.jsx)(n.p,{children:"Test your application by running the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,s.jsx)(n.code,{children:"h"}),", then ",(0,s.jsx)(n.code,{children:"o"})," to open the app in a browser."]}),"\n",(0,s.jsx)(n.h2,{id:"build-for-production",children:"Build for Production"}),"\n",(0,s.jsx)(n.p,{children:"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite build\n"})}),"\n",(0,s.jsx)(n.p,{children:"Once this is complete, you can preview your production build by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite preview\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7607f1d5.d4ae0eb6.js b/assets/js/7607f1d5.d4ae0eb6.js new file mode 100644 index 000000000..2cb40b3e0 --- /dev/null +++ b/assets/js/7607f1d5.d4ae0eb6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40793],{27843:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const o={title:"Front-end in React"},i="Front-end Template with React",a={id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/docs/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/developers/dapps/template-frontend",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/developers/dapps/uref-security"}},c={},l=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"front-end-template-with-react",children:"Front-end Template with React"})}),"\n",(0,s.jsxs)(n.p,{children:["For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide will walk you through setting up and developing a React application with ",(0,s.jsx)(n.a,{href:"https://vitejs.dev/",children:"Vite"})," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,s.jsx)(n.a,{href:"https://reactjs.org/docs/getting-started.html",children:"reading the React documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,s.jsx)(n.p,{children:"Begin by opening a terminal and running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"node -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"To get your Node.js version."}),"\n",(0,s.jsxs)(n.p,{children:["To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:"Node Version Manager"})," or another tool if you are running an earlier version."]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",children:"npm"}),", create a new Vite project by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install -g vite\nnpm create vite@latest\n"})}),"\n",(0,s.jsx)(n.p,{children:'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'}),"\n",(0,s.jsxs)(n.p,{children:["Head into your new project directory, replacing ",(0,s.jsx)(n.code,{children:"vite-project"})," with your project name:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd vite-project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command to test the server:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install\nvite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Quit the server by pressing ",(0,s.jsx)(n.code,{children:"q"}),". Install the Casper JS SDK by running the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide will use ",(0,s.jsx)(n.a,{href:"https://axios-http.com/",children:"axios"})," to communicate with the backend; install it by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install axios\n"})}),"\n",(0,s.jsx)(n.h2,{id:"casper-wallet-integration",children:"Casper Wallet Integration"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,s.jsx)(n.code,{children:"window.CasperWalletProvider"})," and ",(0,s.jsx)(n.code,{children:"window.CasperWalletEventTypes"}),". If the value of these variables is ",(0,s.jsx)(n.code,{children:"undefined"})," the Casper Wallet is not installed."]}),"\n",(0,s.jsx)(n.p,{children:"Start with a helper for getting the provider instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/casper-wallet.js\n"})}),"\n",(0,s.jsx)(n.p,{children:"Fill the file with the following content:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS\n });\n return provider;\n}\n\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For complete integration details, refer to ",(0,s.jsx)(n.a,{href:"https://github.com/make-software/casper-wallet-sdk/#readme",children:"README of Casper Wallet SDK"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," or another parent component that encapsulates the components that should have access to this public key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n </>)}\n </div>\n </>\n );\n}\n\nexport default App;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This is an example of ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," that imports and displays the ",(0,s.jsx)(n.code,{children:"Connect"})," component that is described next. The ",(0,s.jsx)(n.code,{children:"setPublicKey"})," function is passed to the ",(0,s.jsx)(n.code,{children:"Connect"})," component as a ",(0,s.jsx)(n.a,{href:"https://legacy.reactjs.org/docs/components-and-props.html",children:"prop"})," so that it may set the public key and make it available to all of ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),". This way, when more components are added to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", they may utilize the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable."]}),"\n",(0,s.jsxs)(n.p,{children:["To connect to the Casper Wallet within your React app, create the ",(0,s.jsx)(n.code,{children:"Connect"})," component and import the ",(0,s.jsx)(n.code,{children:"getProvider"})," helper."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Connect.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n {/* Place for disconnect button */}\n </>\n );\n}\n\nexport default Connect;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Notice that ",(0,s.jsx)(n.code,{children:"Connect"})," accepts props, and forwards them to the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," using ",(0,s.jsx)(n.code,{children:"props.setPublicKey()"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Write the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function under the ",(0,s.jsx)(n.code,{children:"Connect"})," function component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const connectToWallet = (props) => {\n provider.requestConnection().then(connected => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider.getActivePublicKey().then(publicKey => {\n props.setPublicKey(publicKey);\n }).catch(error => {\n alert(error.message);\n });\n }\n })\n .catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"connectToWallet()"})," function calls ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," will throw an error if the Wallet is not installed as an extension or if it is locked."]}),"\n",(0,s.jsx)(n.h3,{id:"disconnect-the-casper-wallet",children:"Disconnect the Casper Wallet"}),"\n",(0,s.jsxs)(n.p,{children:["To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,s.jsx)(n.em,{children:"src/Connect.jsx"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const disconnect = (props) => {\n provider.disconnectFromSite().then(disconnected => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n } \n }).catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then connect it to a button:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:"const Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n // highlight-next-line-green\n <button onClick={ () => disconnect(props) }>Disconnect</button>\n </>\n );\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"call-a-smart-contract",children:"Call a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:['For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,s.jsx)(n.code,{children:"input"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,s.jsx)(n.code,{children:"input"}),", then grab the value within the smart-contract-calling function."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/UpdateMessage.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { useState } from \'react\';\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />\n <button onClick={ () => updateMessage(props, message) }>Update Message</button>\n </>\n );\n}\n\nexport default UpdateMessage;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable passed in as a prop from ",(0,s.jsx)(n.code,{children:"src/App.jsx"}),". Write this function under your ",(0,s.jsx)(n.code,{children:"UpdateMessage"})," component function."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string(message)\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request\n axios.post("/sendDeploy", signedDeploy, {\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then((response) => {\n alert(response.data);\n }).catch((error) => {\n console.error(error.message);\n });\n }).catch((error) => {\n console.error(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In this example, ",(0,s.jsx)(n.code,{children:"updateMessage"})," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,s.jsx)(n.code,{children:"signedDeploy"})," is forwarded to the backend at the ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," endpoint using ",(0,s.jsx)(n.code,{children:"axios.post"})," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,s.jsx)(n.code,{children:"stderr"}),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert",children:"alert"}),"; however, you may do with the response data as you wish."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["The backend endpoint ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," should handle signed deployment by simply passing it to a Casper node."]}),(0,s.jsxs)(n.p,{children:["In Casper node ",(0,s.jsx)(n.code,{children:"v1.5.0"}),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node."]})]}),"\n",(0,s.jsxs)(n.p,{children:["Now that this component is created, render it to the user interface in ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", passing along the ",(0,s.jsx)(n.code,{children:"publicKey"})," as a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n // highlight-next-line-green\n <UpdateMessage publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"query-a-smart-contract",children:"Query a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Consider that the message written to the chain during the ",(0,s.jsx)(n.code,{children:"update_message"})," entrypoint invocation is stored in the ",(0,s.jsx)(n.a,{href:"/concepts/glossary/D#dictionary",children:"dictionary"})," ",(0,s.jsx)(n.code,{children:"messages"})," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/A#account-hash",children:"account hash"})," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Query.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return <button onClick={ () => query(props) }>Query</button>;\n}\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {\n alert(response.data)\n }).catch((error) => {\n console.error(error.message);\n });\n}\n\nexport default Query;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All this component does is render an HTML ",(0,s.jsx)(n.code,{children:"button"})," element that, when pressed, performs a ",(0,s.jsx)(n.code,{children:"GET"})," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"toAccountHashStr"}),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,s.jsx)(n.code,{children:"substring(13)"})," method."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["This functionality relies on the ",(0,s.jsx)(n.code,{children:"/queryMessage"})," endpoint, which should be implemented in your backend."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now add this component to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", making available the ",(0,s.jsx)(n.code,{children:"publicKey"})," state variable via a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n <UpdateMessage publicKey={ publicKey } />\n // highlight-next-line-green\n <Query publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"test-application",children:"Test Application"}),"\n",(0,s.jsx)(n.p,{children:"Test your application by running the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,s.jsx)(n.code,{children:"h"}),", then ",(0,s.jsx)(n.code,{children:"o"})," to open the app in a browser."]}),"\n",(0,s.jsx)(n.h2,{id:"build-for-production",children:"Build for Production"}),"\n",(0,s.jsx)(n.p,{children:"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite build\n"})}),"\n",(0,s.jsx)(n.p,{children:"Once this is complete, you can preview your production build by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite preview\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/76839fc0.2942aa34.js b/assets/js/76839fc0.2942aa34.js new file mode 100644 index 000000000..55847a479 --- /dev/null +++ b/assets/js/76839fc0.2942aa34.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84259],{12525:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={},r="Staking",o={id:"concepts/economics/staking",title:"Staking",description:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.",source:"@site/versioned_docs/version-2.0.0/concepts/economics/staking.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/staking",permalink:"/2.0.0/concepts/economics/staking",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Fee Elimination",permalink:"/2.0.0/concepts/economics/fee-elimination"},next:{title:"Glossary",permalink:"/2.0.0/glossary"}},c={},d=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"staking",children:"Staking"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Consensus mechanism:"})," The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"}),". Another Casper network can choose between Zug and ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/design/highway",children:"Highway"})," using the network's chainspec."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Number of validators:"})," The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Permission-less bonding:"})," For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Unbonding:"})," To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/economics/consensus#distribution",children:"here"}),". The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Eras and block times:"})," An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Block rewards:"})," Validators receive ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/design/rewards",children:"rewards"})," proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward calculations:"})," Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Reward cycle:"})," Rewards are ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/economics/consensus#distribution",children:"calculated and distributed"})," to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Token supply and inflation:"})," Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Annual reward percentage:"})," Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Slashing:"})," Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated."]}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Delegation rate:"})," Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/76a75fbd.8393010c.js b/assets/js/76a75fbd.8393010c.js new file mode 100644 index 000000000..a24533891 --- /dev/null +++ b/assets/js/76a75fbd.8393010c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37667],{34868:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=n(74848),i=n(28453);const a={title:"Undelegate Tokens",slug:"/users/undelegate-ui"},o="Undelegating Tokens",l={id:"users/csprlive/undelegate-ui",title:"Undelegate Tokens",description:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.",source:"@site/docs/users/csprlive/undelegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/undelegate-ui",permalink:"/users/undelegate-ui",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Undelegate Tokens",slug:"/users/undelegate-ui"},sidebar:"users",previous:{title:"Delegate Tokens",permalink:"/users/delegate-ui"},next:{title:"Transfer Tokens",permalink:"/users/token-transfer"}},r={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Accessing the Undelegation Feature",id:"accessing-the-undelegation-feature",level:2},{value:"Stepping through the Undelegation Process",id:"stepping-through-the-undelegation-process",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"undelegating-tokens",children:"Undelegating Tokens"})}),"\n",(0,s.jsx)(t.p,{children:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR."}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.p,{children:["This guide assumes that you have previously delegated tokens to a validator using a ",(0,s.jsx)(t.a,{href:"/users/delegate-ui",children:"block explorer"})," or the ",(0,s.jsx)(t.a,{href:"/developers/cli/delegate",children:"Casper client"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"accessing-the-undelegation-feature",children:"Accessing the Undelegation Feature"}),"\n",(0,s.jsx)(t.p,{children:"You can access the undelegation functionality in three ways."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,s.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,s.jsx)(t.strong,{children:"Undelegate Stake"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Wallet",src:n(76824).A+"",width:"243",height:"325"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,s.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the ",(0,s.jsx)(t.strong,{children:"Undelegate Stake"})," button."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Validator",src:n(73956).A+"",width:"2222",height:"992"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 3:"})," Open your account details and select the ",(0,s.jsx)(t.strong,{children:"Delegations"})," tab. Click the ",(0,s.jsx)(t.strong,{children:"Undelegate"})," button next to the validator from whom you wish to undelegate."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Account",src:n(34942).A+"",width:"2482",height:"524"})}),"\n",(0,s.jsx)(t.h2,{id:"stepping-through-the-undelegation-process",children:"Stepping through the Undelegation Process"}),"\n",(0,s.jsx)(t.p,{children:'The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.'}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 1 - Undelegation details"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,s.jsx)(t.li,{children:"Enter the amount of Casper tokens you want to undelegate."}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegation details",src:n(59528).A+"",width:"1136",height:"1442"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 2 - Confirm the undelegation"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Review the undelegation details."}),"\n",(0,s.jsxs)(t.li,{children:["If everything looks correct, click ",(0,s.jsx)(t.strong,{children:"Confirm and undelegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Confirm undelegation",src:n(30804).A+"",width:"1156",height:"1480"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 3 - Sign the undelegation"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Sign with Casper Wallet"})," to sign the undelegation."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Sign the undelegation",src:n(16116).A+"",width:"1126",height:"1706"})}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.']}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Confirm deploy hash",src:n(8189).A+"",width:"1974",height:"1728"})}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegation confirmed",src:n(84678).A+"",width:"1114",height:"1336"})}),"\n",(0,s.jsx)(t.p,{children:'It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.'}),"\n",(0,s.jsx)(t.p,{children:"Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours."})]})}function c(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},76824:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/1.wallet-undelegate-9d248f8c648da6a81f11519504d7812b.png"},73956:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/2.validator-undelegate-5b02fc97aa94336f98b91ed2414630aa.png"},34942:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/3.account-undelegate-115ac530fff9a47a18e6e9faa1dd418b.png"},59528:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/4.undelegate-details-bc50ff78eb29ada22fab3ed956a833be.png"},30804:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/5.confirm-undelegation-ab54ef5443b66d944efc83b7d9623af7.png"},16116:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/6.sign-undelegation-0e412d3726ca39417062e53ae0e6fcca.png"},8189:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/7.confirm-hash-466847a8e9502b69d17c46350f4bcab2.png"},84678:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/8.undelegation-confirmed-a77491f86b955fe091fe6ebf6e685f91.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>l});var s=n(96540);const i={},a=s.createContext(i);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/76a75fbd.cb2ccf80.js b/assets/js/76a75fbd.cb2ccf80.js deleted file mode 100644 index 7f5f9f181..000000000 --- a/assets/js/76a75fbd.cb2ccf80.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7667],{34868:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>c,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=n(74848),i=n(28453);const a={title:"Undelegate Tokens",slug:"/users/undelegate-ui"},o="Undelegating Tokens",l={id:"users/csprlive/undelegate-ui",title:"Undelegate Tokens",description:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.",source:"@site/docs/users/csprlive/undelegate-ui.md",sourceDirName:"users/csprlive",slug:"/users/undelegate-ui",permalink:"/next/users/undelegate-ui",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Undelegate Tokens",slug:"/users/undelegate-ui"},sidebar:"users",previous:{title:"Delegate Tokens",permalink:"/next/users/delegate-ui"},next:{title:"Transfer Tokens",permalink:"/next/users/token-transfer"}},r={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Accessing the Undelegation Feature",id:"accessing-the-undelegation-feature",level:2},{value:"Stepping through the Undelegation Process",id:"stepping-through-the-undelegation-process",level:2}];function h(e){const t={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"undelegating-tokens",children:"Undelegating Tokens"})}),"\n",(0,s.jsx)(t.p,{children:"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR."}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.p,{children:["This guide assumes that you have previously delegated tokens to a validator using a ",(0,s.jsx)(t.a,{href:"/next/users/delegate-ui",children:"block explorer"})," or the ",(0,s.jsx)(t.a,{href:"/next/developers/cli/delegate",children:"Casper client"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"accessing-the-undelegation-feature",children:"Accessing the Undelegation Feature"}),"\n",(0,s.jsx)(t.p,{children:"You can access the undelegation functionality in three ways."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 1:"})," Click ",(0,s.jsx)(t.strong,{children:"Wallet"})," from the top navigation menu and then click ",(0,s.jsx)(t.strong,{children:"Undelegate Stake"}),"."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Wallet",src:n(93346).A+"",width:"243",height:"325"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 2:"})," Click ",(0,s.jsx)(t.strong,{children:"Validators"})," from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the ",(0,s.jsx)(t.strong,{children:"Undelegate Stake"})," button."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Validator",src:n(32134).A+"",width:"2222",height:"992"})}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Option 3:"})," Open your account details and select the ",(0,s.jsx)(t.strong,{children:"Delegations"})," tab. Click the ",(0,s.jsx)(t.strong,{children:"Undelegate"})," button next to the validator from whom you wish to undelegate."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegate from Account",src:n(77804).A+"",width:"2482",height:"524"})}),"\n",(0,s.jsx)(t.h2,{id:"stepping-through-the-undelegation-process",children:"Stepping through the Undelegation Process"}),"\n",(0,s.jsx)(t.p,{children:'The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.'}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 1 - Undelegation details"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field."}),"\n",(0,s.jsx)(t.li,{children:"Enter the amount of Casper tokens you want to undelegate."}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Next"}),"."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegation details",src:n(2918).A+"",width:"1136",height:"1442"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 2 - Confirm the undelegation"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsx)(t.li,{children:"Review the undelegation details."}),"\n",(0,s.jsxs)(t.li,{children:["If everything looks correct, click ",(0,s.jsx)(t.strong,{children:"Confirm and undelegate stake"}),". If you wish to make changes, return to the previous screen."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Confirm undelegation",src:n(83490).A+"",width:"1156",height:"1480"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Step 3 - Sign the undelegation"})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Sign with Casper Wallet"})," to sign the undelegation."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Sign the undelegation",src:n(37626).A+"",width:"1126",height:"1706"})}),"\n",(0,s.jsxs)(t.ol,{start:"2",children:["\n",(0,s.jsxs)(t.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(t.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.']}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Confirm deploy hash",src:n(71043).A+"",width:"1974",height:"1728"})}),"\n",(0,s.jsxs)(t.ol,{start:"3",children:["\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Sign"})," in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Undelegation confirmed",src:n(11588).A+"",width:"1114",height:"1336"})}),"\n",(0,s.jsx)(t.p,{children:'It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.'}),"\n",(0,s.jsx)(t.p,{children:"Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours."})]})}function c(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},93346:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/1.wallet-undelegate-9d248f8c648da6a81f11519504d7812b.png"},32134:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/2.validator-undelegate-5b02fc97aa94336f98b91ed2414630aa.png"},77804:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/3.account-undelegate-115ac530fff9a47a18e6e9faa1dd418b.png"},2918:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/4.undelegate-details-bc50ff78eb29ada22fab3ed956a833be.png"},83490:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/5.confirm-undelegation-ab54ef5443b66d944efc83b7d9623af7.png"},37626:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/6.sign-undelegation-0e412d3726ca39417062e53ae0e6fcca.png"},71043:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/7.confirm-hash-466847a8e9502b69d17c46350f4bcab2.png"},11588:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/8.undelegation-confirmed-a77491f86b955fe091fe6ebf6e685f91.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>l});var s=n(96540);const i={},a=s.createContext(i);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/76ea157b.4cf4a84d.js b/assets/js/76ea157b.4cf4a84d.js new file mode 100644 index 000000000..bd626acc6 --- /dev/null +++ b/assets/js/76ea157b.4cf4a84d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1867],{30599:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var t=s(74848),i=s(28453);const r={title:"Ledger and CSPR.live"},c="Using Ledger and CSPR.live",l={id:"users/ledger/ledger-cspr-live",title:"Ledger and CSPR.live",description:"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.",source:"@site/versioned_docs/version-2.0.0/users/ledger/ledger-cspr-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-cspr-live",permalink:"/2.0.0/users/ledger/ledger-cspr-live",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Ledger and CSPR.live"},sidebar:"users",previous:{title:"Ledger and Ledger Live",permalink:"/2.0.0/users/ledger/ledger-live"},next:{title:"Delegate with Ledger",permalink:"/2.0.0/users/staking-ledger"}},a={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Signing In",id:"sign-in",level:2},{value:"Viewing Account Details",id:"view-account-details",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-csprlive",children:"Using Ledger and CSPR.live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect your Ledger device to a Casper account using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Install a Chromium-based browser, such as Chrome or Brave, for use with ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," for the Casper Mainnet."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"sign-in",children:"Signing In"}),"\n",(0,t.jsxs)(n.p,{children:["To use the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, follow these steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n",(0,t.jsx)(n.li,{children:"Open the Casper app on the Ledger device as shown above."}),"\n",(0,t.jsxs)(n.li,{children:["While keeping the Casper app open, navigate to ",(0,t.jsx)(n.a,{href:"https://cspr.live/sign-in",children:"cspr.live/sign-in"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Sign into cspr.live",src:s(57541).A+"",width:"2302",height:"224"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Connect"})," button in the Ledger section."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose to connect with ledger",src:s(68689).A+"",width:"2228",height:"1398"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click the ",(0,t.jsx)(n.strong,{children:"Connect to Ledger wallet"})," button next."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect to Ledger Wallet in CSPR Live",src:s(54288).A+"",width:"1966",height:"1304"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Select an account you want to use."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account to connect",src:s(26869).A+"",width:"1966",height:"1470"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Your Ledger device is now connected to the block explorer, displaying your account details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account connected",src:s(7229).A+"",width:"2192",height:"926"})}),"\n",(0,t.jsx)(n.h2,{id:"view-account-details",children:"Viewing Account Details"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Click on the account in the upper-right corner of the page."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-view-account",src:s(28065).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"View Account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-view-account-button",src:s(19068).A+"",width:"1962",height:"566"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["You are presented with a page displaying details about your account. Check your account's main purse balance in the ",(0,t.jsx)(n.strong,{children:"Liquid"})," row under ",(0,t.jsx)(n.strong,{children:"Total Balance"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-account-details",src:s(86902).A+"",width:"2180",height:"1255"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open the account details page as described ",(0,t.jsx)(n.a,{href:"#view-account-details",children:"here"})," and copy the public key in the ",(0,t.jsx)(n.strong,{children:"Public Key"})," row."]}),"\n",(0,t.jsx)(n.li,{children:"Alternatively, click on the drop-down menu on your account address."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"View account",src:s(28065).A+"",width:"1934",height:"270"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Copy Public Key"})," button and share it with the sender."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Copy public key",src:s(16951).A+"",width:"2194",height:"512"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Open ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Sign in with your Ledger device."}),"\n",(0,t.jsxs)(n.li,{children:["Click on ",(0,t.jsx)(n.strong,{children:"Wallet"})," and then ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-transfer-wallet",src:s(67087).A+"",width:"2306",height:"430"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsx)(n.li,{children:"Fill in the details for the transfer."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"1-transfer-details",src:s(8343).A+"",width:"1134",height:"1674"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Next"})," button."]}),"\n",(0,t.jsxs)(n.li,{children:["On the next page, click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"2-transfer-confirm",src:s(84684).A+"",width:"1162",height:"1348"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["On the ",(0,t.jsx)(n.strong,{children:"Sign transaction"})," page, click on the ",(0,t.jsx)(n.strong,{children:"Sign with Ledger"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(70484).A+"",width:"852",height:"1780"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount). Meanwhile, the block explorer will show this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-transfer-sign",src:s(47144).A+"",width:"870",height:"190"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see ",(0,t.jsx)(n.strong,{children:'"Approve"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Txn hash"})," - ensure it matches the value displayed on ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(75528).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-txn-2",src:s(49852).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["The next page displays transaction ",(0,t.jsx)(n.strong,{children:"Type"})," - for CSPR transfers, that will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(25176).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Chain ID"}),", which identifies the network to which you want to send the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(65019).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"}),", the account's public key initiating the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(9356).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(23994).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(11342).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", the recipient's public key. Compare this value with the one in the block explorer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(94594).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(95276).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(10485).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(98456).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.p,{children:["After approving the transaction with your Ledger hardware wallet, the ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"}),' block explorer will display a "Transfer completed" page.']}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-transfer-completed",src:s(60393).A+"",width:"856",height:"1000"})}),"\n",(0,t.jsx)(n.p,{children:"You can now check your account to see a list of all the completed transfers."})]})}function o(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},8343:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-transfer-details-d728078c48d947c328a3b23bc15cc17f.png"},84684:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-transfer-confirm-cafb3d92204942f3666af11f77d8cd61.png"},70484:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-sign-eb761f9759ce1a3c70c7968f0e2f1e82.png"},47144:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-transfer-submitted-7cfc5128325445455a67726758f30891.png"},60393:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-transfer-completed-e9f855a5ceaa8c958312420012496973.png"},11342:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},94594:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},95276:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},10485:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},98456:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},75528:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},49852:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},25176:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},65019:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},9356:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},23994:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},7229:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-connected-ce22088786c03da93e7686c5375000c1.png"},86902:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-details-3e4ce3ed866005ac2e670604c6a0a1c4.png"},54288:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-ledger-5cccc2f985729730a69b62543732c2a9.png"},26869:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/connect-select-account-98453e231f218ddfc35417eeb3ff61f4.png"},16951:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/copy-public-key-3f7fc15c50bb5e3410019c468527dc12.png"},68689:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-connect-5c26775af933c4e7bf446690ed2be84a.png"},57541:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/cspr-signin-62933017bd15b98d7d3a588ba8f3f579.png"},67087:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/transfer-wallet-dc9b61bfe299341e3e42fc8cadc707ea.png"},19068:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-button-8c0f2e206de1dbf6547dd21bb8f27ba4.png"},28065:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/view-account-4d1ba8d5125c4ebd4e80a7016d0f62b6.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>l});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7708241d.76dde882.js b/assets/js/7708241d.76dde882.js deleted file mode 100644 index 266f29551..000000000 --- a/assets/js/7708241d.76dde882.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8728],{62157:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=n(74848),c=n(28453);const r={title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},s="Upgrading a Contract",o={id:"resources/beginner/upgrade-contract",title:"Contract Upgrades",description:"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.",source:"@site/docs/resources/beginner/upgrade-contract.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/upgrade-contract",permalink:"/next/resources/tutorials/beginner/upgrade-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},sidebar:"tutorials",previous:{title:"Querying a Node",permalink:"/next/resources/tutorials/beginner/querying-network"},next:{title:"Fungible Tokens",permalink:"/next/resources/tutorials/beginner/cep18"}},i={},l=[{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contract Versioning Flow",id:"contract-versioning-flow",level:2},{value:"Step 1. Create a new unlocked contract",id:"step-1-create-a-new-unlocked-contract",level:3},{value:"Step 2. Add a new contract to the package",id:"step-2-add-a-new-contract-to-the-package",level:3},{value:"Step 3. Build the contract Wasm",id:"step-3-build-the-contract-wasm",level:3},{value:"Step 4. Install the contract",id:"step-4-install-the-contract",level:3},{value:"Step 5. Verify your changes",id:"step-5-verify-your-changes",level:3},{value:"Disabling and Enabling Contract Versions",id:"disabling-and-enabling-contract-versions",level:2},{value:"Creating a Locked Contract Package",id:"locked-contract-package",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"upgrading-a-contract",children:"Upgrading a Contract"})}),"\n",(0,a.jsxs)(t.p,{children:["This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"contract package"})," by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," API. You can also create a ",(0,a.jsx)(t.a,{href:"#locked-contract-package",children:"locked contract package"})," that cannot be versioned and is therefore not upgradable."]}),"\n",(0,a.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,a.jsx)(t.p,{children:"Here is a video walkthrough of this tutorial."}),"\n",(0,a.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=Q4ZXNV8EVTk&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=4",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,a.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["The ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"})," referencing the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"ContractPackage"})," where an unlocked contract is stored in global state."]}),"\n",(0,a.jsxs)(t.li,{children:["You should be familiar with ",(0,a.jsx)(t.a,{href:"/writing-contracts",children:"writing smart contracts"}),", ",(0,a.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"on-chain contracts"}),", and ",(0,a.jsx)(t.a,{href:"/next/developers/cli/calling-contracts",children:"calling contracts"})," on a Casper network."]}),"\n",(0,a.jsxs)(t.li,{children:["You have installed ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," that you will upgrade as part of this tutorial."]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract (contract-v1.wasm) as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"counter tutorial"})," is a prerequisite before installing the second version of the contract (contract-v2.wasm)."]})}),"\n",(0,a.jsxs)(t.p,{children:["If you explore ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"the code"}),", you will observe the different versions of the contract:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v1"})," is the counter contract you can see in the ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v2"})," is the contract with the new ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"contract-versioning-flow",children:"Contract Versioning Flow"}),"\n",(0,a.jsx)(t.p,{children:"The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash."}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["Create a contract in the most common way, using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Add a new version of the contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Build the new contract and generate the corresponding ",(0,a.jsx)(t.code,{children:".wasm"})," file."]}),"\n",(0,a.jsx)(t.li,{children:"Install the contract on the network via a deploy."}),"\n",(0,a.jsx)(t.li,{children:"Verify that your new contract version works as desired."}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["In this tutorial, you will use ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v2/src/main.rs",children:"the second version"})," of the counter contract to perform the upgrade."]}),"\n",(0,a.jsx)(t.h3,{id:"step-1-create-a-new-unlocked-contract",children:"Step 1. Create a new unlocked contract"}),"\n",(0,a.jsxs)(t.p,{children:["Create a new contract using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned."]}),"\n",(0,a.jsx)(t.p,{children:"When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Create a new contract and specify a package name and access URef for further modifications\n let (stored_contract_hash, contract_version) = storage::new_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n );\n\n // The hash of the installed contract will be reachable through a named key\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n\n // The current version of the contract will be reachable through a named key\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n'})}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L94",children:"first version of the counter"})," shows you a contract package that can be versioned. This step is covered in the tutorial for ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"Additional details:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used."}),"\n",(0,a.jsx)(t.li,{children:"The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions."}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-2-add-a-new-contract-to-the-package",children:"Step 2. Add a new contract to the package"}),"\n",(0,a.jsx)(t.p,{children:"There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract."}),"\n",(0,a.jsxs)(t.p,{children:["To add a new contract version in the package, invoke the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," function and pass in the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"}),", ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.EntryPoints.html",children:"EntryPoints"}),", and ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),". In the counter example, you will find the ",(0,a.jsx)(t.code,{children:"add_contract_version"})," call ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v2/src/main.rs#L164",children:"here"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:" let (contract_hash, contract_version) = \n storage::add_contract_version(contract_package_hash, \n entry_points, \n named_keys);\n"})}),"\n",(0,a.jsx)(t.p,{children:"Explanation of arguments:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract_package_hash"})," - This hash directs you to the contract package. See ",(0,a.jsx)(t.a,{href:"/next/concepts/key-types#hash-and-key-explanations",children:"Hash and Key Explanations"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"entry_points"})," - Entry points of the contract, which can be modified or newly added."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"named_keys"})," - Named key pairs of the contract."]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract."}),"\n",(0,a.jsx)(t.p,{children:"You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"Pin your client contract to the contract hash of a specific version."}),"\n",(0,a.jsxs)(t.li,{children:["Use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"})," with a version number to pin your client contract to that version."]}),"\n",(0,a.jsxs)(t.li,{children:["Call a contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),' and version "None", which uses the newest version of the contract.']}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-3-build-the-contract-wasm",children:"Step 3. Build the contract Wasm"}),"\n",(0,a.jsx)(t.p,{children:"Use these commands to prepare and build the newly added contract:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"make prepare\n\nmake build-contract\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-4-install-the-contract",children:"Step 4. Install the contract"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/next/developers/cli/installing-contracts",children:"Install the contract"})," on the network via a deploy and verify the deploy status. You can also ",(0,a.jsx)(t.a,{href:"/next/developers/cli/sending-transactions#monitoring-the-event-stream-for-transactions",children:"monitor the event stream"})," to see when your deploy is accepted."]}),"\n",(0,a.jsxs)(t.p,{children:["To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract, as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"Counter tutorial"}),", is a prerequisite before installing the second version."]})}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-5-verify-your-changes",children:"Step 5. Verify your changes"}),"\n",(0,a.jsxs)(t.p,{children:["You can write unit tests to verify the behavior of the new contract version with ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_contract.html",children:"call_contract"})," or ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),". When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version."]}),"\n",(0,a.jsxs)(t.p,{children:["For the simple example counter above, here are the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"corresponding tests"}),". Notice how the tests store and verify the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"contract's version"})," and entry points."]}),"\n",(0,a.jsxs)(t.p,{children:["You could store the latest version of the contract package under a NamedKey, as shown ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"here"}),". Then, you can query the NamedKey to check the latest version of the contract package."]}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example test function"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Verify the contract version is now 2.\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let version_key = *account\n .named_keys()\n .get(CONTRACT_VERSION_KEY)\n .expect("version uref should exist");\n\n let version = builder\n .query(None, version_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<u32>()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"You can also test the new entry point by using the Rust command-line client."}),"\n",(0,a.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Check the new contract entry points. You should see the ",(0,a.jsx)(t.em,{children:"counter_decrement"})," entry point now."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Check the version and package details with the latest state root hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'})}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Call the new entry point, ",(0,a.jsx)(t.em,{children:"counter_decrement"}),", using the package name and check the results."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n'})}),"\n",(0,a.jsxs)(t.admonition,{type:"note",children:[(0,a.jsx)(t.p,{children:"There are two ways to call versioned contracts:"}),(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/developers/writing-onchain-code/calling-contracts#storedcontractbyhash",children:"Calling Contracts by Package Hash"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/developers/writing-onchain-code/calling-contracts#storedcontractbyname",children:"Calling Contracts by Package Name"})}),"\n"]})]}),"\n",(0,a.jsx)(t.p,{children:"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."}),"\n",(0,a.jsx)(t.h2,{id:"disabling-and-enabling-contract-versions",children:"Disabling and Enabling Contract Versions"}),"\n",(0,a.jsxs)(t.p,{children:["You can disable a contract version within a contract package by using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html",children:"disable_contract_version"})," function."]}),"\n",(0,a.jsx)(t.p,{children:"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html",children:"Enable_contract_version"})," allows you to re-enable a previously disabled contract version."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."})}),"\n",(0,a.jsx)(t.h2,{id:"locked-contract-package",children:"Creating a Locked Contract Package"}),"\n",(0,a.jsxs)(t.p,{children:["You can create a locked contract package with the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," function. This contract can never be upgraded."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points, \n Some(contract_named_keys), \n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n'})}),"\n",(0,a.jsx)(t.p,{children:"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," as Step 1 explains."]})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var a=n(96540);const c={},r=a.createContext(c);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7708241d.c2fc2488.js b/assets/js/7708241d.c2fc2488.js new file mode 100644 index 000000000..9ae64cce6 --- /dev/null +++ b/assets/js/7708241d.c2fc2488.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58728],{62157:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=n(74848),c=n(28453);const r={title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},s="Upgrading a Contract",o={id:"resources/beginner/upgrade-contract",title:"Contract Upgrades",description:"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.",source:"@site/docs/resources/beginner/upgrade-contract.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/upgrade-contract",permalink:"/resources/tutorials/beginner/upgrade-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},sidebar:"tutorials",previous:{title:"Querying a Node",permalink:"/resources/tutorials/beginner/querying-network"},next:{title:"Fungible Tokens",permalink:"/resources/tutorials/beginner/cep18"}},i={},l=[{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contract Versioning Flow",id:"contract-versioning-flow",level:2},{value:"Step 1. Create a new unlocked contract",id:"step-1-create-a-new-unlocked-contract",level:3},{value:"Step 2. Add a new contract to the package",id:"step-2-add-a-new-contract-to-the-package",level:3},{value:"Step 3. Build the contract Wasm",id:"step-3-build-the-contract-wasm",level:3},{value:"Step 4. Install the contract",id:"step-4-install-the-contract",level:3},{value:"Step 5. Verify your changes",id:"step-5-verify-your-changes",level:3},{value:"Disabling and Enabling Contract Versions",id:"disabling-and-enabling-contract-versions",level:2},{value:"Creating a Locked Contract Package",id:"locked-contract-package",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"upgrading-a-contract",children:"Upgrading a Contract"})}),"\n",(0,a.jsxs)(t.p,{children:["This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"contract package"})," by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," API. You can also create a ",(0,a.jsx)(t.a,{href:"#locked-contract-package",children:"locked contract package"})," that cannot be versioned and is therefore not upgradable."]}),"\n",(0,a.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,a.jsx)(t.p,{children:"Here is a video walkthrough of this tutorial."}),"\n",(0,a.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=Q4ZXNV8EVTk&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=4",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,a.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["The ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"})," referencing the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"ContractPackage"})," where an unlocked contract is stored in global state."]}),"\n",(0,a.jsxs)(t.li,{children:["You should be familiar with ",(0,a.jsx)(t.a,{href:"/writing-contracts",children:"writing smart contracts"}),", ",(0,a.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"on-chain contracts"}),", and ",(0,a.jsx)(t.a,{href:"/developers/cli/calling-contracts",children:"calling contracts"})," on a Casper network."]}),"\n",(0,a.jsxs)(t.li,{children:["You have installed ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," that you will upgrade as part of this tutorial."]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract (contract-v1.wasm) as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"counter tutorial"})," is a prerequisite before installing the second version of the contract (contract-v2.wasm)."]})}),"\n",(0,a.jsxs)(t.p,{children:["If you explore ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"the code"}),", you will observe the different versions of the contract:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v1"})," is the counter contract you can see in the ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v2"})," is the contract with the new ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"contract-versioning-flow",children:"Contract Versioning Flow"}),"\n",(0,a.jsx)(t.p,{children:"The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash."}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["Create a contract in the most common way, using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Add a new version of the contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Build the new contract and generate the corresponding ",(0,a.jsx)(t.code,{children:".wasm"})," file."]}),"\n",(0,a.jsx)(t.li,{children:"Install the contract on the network via a deploy."}),"\n",(0,a.jsx)(t.li,{children:"Verify that your new contract version works as desired."}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["In this tutorial, you will use ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v2/src/main.rs",children:"the second version"})," of the counter contract to perform the upgrade."]}),"\n",(0,a.jsx)(t.h3,{id:"step-1-create-a-new-unlocked-contract",children:"Step 1. Create a new unlocked contract"}),"\n",(0,a.jsxs)(t.p,{children:["Create a new contract using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned."]}),"\n",(0,a.jsx)(t.p,{children:"When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Create a new contract and specify a package name and access URef for further modifications\n let (stored_contract_hash, contract_version) = storage::new_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n );\n\n // The hash of the installed contract will be reachable through a named key\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n\n // The current version of the contract will be reachable through a named key\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n'})}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L94",children:"first version of the counter"})," shows you a contract package that can be versioned. This step is covered in the tutorial for ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"Additional details:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used."}),"\n",(0,a.jsx)(t.li,{children:"The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions."}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-2-add-a-new-contract-to-the-package",children:"Step 2. Add a new contract to the package"}),"\n",(0,a.jsx)(t.p,{children:"There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract."}),"\n",(0,a.jsxs)(t.p,{children:["To add a new contract version in the package, invoke the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," function and pass in the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"}),", ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.EntryPoints.html",children:"EntryPoints"}),", and ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),". In the counter example, you will find the ",(0,a.jsx)(t.code,{children:"add_contract_version"})," call ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v2/src/main.rs#L164",children:"here"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:" let (contract_hash, contract_version) = \n storage::add_contract_version(contract_package_hash, \n entry_points, \n named_keys);\n"})}),"\n",(0,a.jsx)(t.p,{children:"Explanation of arguments:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract_package_hash"})," - This hash directs you to the contract package. See ",(0,a.jsx)(t.a,{href:"/concepts/key-types#hash-and-key-explanations",children:"Hash and Key Explanations"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"entry_points"})," - Entry points of the contract, which can be modified or newly added."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"named_keys"})," - Named key pairs of the contract."]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract."}),"\n",(0,a.jsx)(t.p,{children:"You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"Pin your client contract to the contract hash of a specific version."}),"\n",(0,a.jsxs)(t.li,{children:["Use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"})," with a version number to pin your client contract to that version."]}),"\n",(0,a.jsxs)(t.li,{children:["Call a contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),' and version "None", which uses the newest version of the contract.']}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-3-build-the-contract-wasm",children:"Step 3. Build the contract Wasm"}),"\n",(0,a.jsx)(t.p,{children:"Use these commands to prepare and build the newly added contract:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"make prepare\n\nmake build-contract\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-4-install-the-contract",children:"Step 4. Install the contract"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"Install the contract"})," on the network via a deploy and verify the deploy status. You can also ",(0,a.jsx)(t.a,{href:"/developers/cli/sending-transactions#monitoring-the-event-stream-for-transactions",children:"monitor the event stream"})," to see when your deploy is accepted."]}),"\n",(0,a.jsxs)(t.p,{children:["To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract, as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"Counter tutorial"}),", is a prerequisite before installing the second version."]})}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-5-verify-your-changes",children:"Step 5. Verify your changes"}),"\n",(0,a.jsxs)(t.p,{children:["You can write unit tests to verify the behavior of the new contract version with ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_contract.html",children:"call_contract"})," or ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),". When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version."]}),"\n",(0,a.jsxs)(t.p,{children:["For the simple example counter above, here are the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"corresponding tests"}),". Notice how the tests store and verify the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"contract's version"})," and entry points."]}),"\n",(0,a.jsxs)(t.p,{children:["You could store the latest version of the contract package under a NamedKey, as shown ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"here"}),". Then, you can query the NamedKey to check the latest version of the contract package."]}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example test function"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Verify the contract version is now 2.\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let version_key = *account\n .named_keys()\n .get(CONTRACT_VERSION_KEY)\n .expect("version uref should exist");\n\n let version = builder\n .query(None, version_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<u32>()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"You can also test the new entry point by using the Rust command-line client."}),"\n",(0,a.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Check the new contract entry points. You should see the ",(0,a.jsx)(t.em,{children:"counter_decrement"})," entry point now."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Check the version and package details with the latest state root hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'})}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Call the new entry point, ",(0,a.jsx)(t.em,{children:"counter_decrement"}),", using the package name and check the results."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n'})}),"\n",(0,a.jsxs)(t.admonition,{type:"note",children:[(0,a.jsx)(t.p,{children:"There are two ways to call versioned contracts:"}),(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/developers/writing-onchain-code/calling-contracts#storedcontractbyhash",children:"Calling Contracts by Package Hash"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/developers/writing-onchain-code/calling-contracts#storedcontractbyname",children:"Calling Contracts by Package Name"})}),"\n"]})]}),"\n",(0,a.jsx)(t.p,{children:"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."}),"\n",(0,a.jsx)(t.h2,{id:"disabling-and-enabling-contract-versions",children:"Disabling and Enabling Contract Versions"}),"\n",(0,a.jsxs)(t.p,{children:["You can disable a contract version within a contract package by using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html",children:"disable_contract_version"})," function."]}),"\n",(0,a.jsx)(t.p,{children:"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html",children:"Enable_contract_version"})," allows you to re-enable a previously disabled contract version."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."})}),"\n",(0,a.jsx)(t.h2,{id:"locked-contract-package",children:"Creating a Locked Contract Package"}),"\n",(0,a.jsxs)(t.p,{children:["You can create a locked contract package with the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," function. This contract can never be upgraded."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points, \n Some(contract_named_keys), \n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n'})}),"\n",(0,a.jsx)(t.p,{children:"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," as Step 1 explains."]})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var a=n(96540);const c={},r=a.createContext(c);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/772d3db3.5265c340.js b/assets/js/772d3db3.5265c340.js new file mode 100644 index 000000000..d2110448e --- /dev/null +++ b/assets/js/772d3db3.5265c340.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94491],{95631:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=o(74848),s=o(28453);const r={title:"Staging Files"},t="Staging Files for a New Network",c={id:"operators/setup-network/staging-files-for-new-network",title:"Staging Files",description:"Staging files is not needed for already established running networks.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/staging-files-for-new-network.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/staging-files-for-new-network",permalink:"/1.5.X/operators/setup-network/staging-files-for-new-network",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Staging Files"},sidebar:"operators",previous:{title:"Private Network Setup",permalink:"/1.5.X/operators/setup-network/create-private"},next:{title:"Node Maintenance",permalink:"/1.5.X/operators/maintenance/"}},l={},d=[{value:"Hosting Server",id:"hosting-server",level:2},{value:"More on <code>protocol_versions</code>",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"staging-files-for-a-new-network",children:"Staging Files for a New Network"})}),"\n",(0,i.jsxs)(n.admonition,{type:"important",children:[(0,i.jsx)(n.p,{children:"Staging files is not needed for already established running networks."}),(0,i.jsx)(n.p,{children:"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network."})]}),"\n",(0,i.jsx)(n.h2,{id:"hosting-server",children:"Hosting Server"}),"\n",(0,i.jsx)(n.p,{children:"Files for staging protocol versions are hosted on a typical HTTP(S) server."}),"\n",(0,i.jsxs)(n.p,{children:["Scripts included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."]}),"\n",(0,i.jsx)(n.p,{children:"Since a given server can be used for multiple networks, a network named directory is used to\nhold files for that network."}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of Mainnet protocol version hosting (with network name: ",(0,i.jsx)(n.code,{children:"casper"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"genesis.casperlab.io"})," is the web server URL with the following directory structure:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"protocol_versions"})," - File listing active protocol versions so scripts know what directories to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0"})," - Genesis protocol version\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_1_0"})," - First upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_1_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_1_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"... (skipping many other protocol versions)"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_4_6"})," - A later upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_4_6"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_4_6"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"more-on-protocol_versions",children:["More on ",(0,i.jsx)(n.code,{children:"protocol_versions"})]}),"\n",(0,i.jsxs)(n.p,{children:["At the root of the hosting server directory for a given network, a ",(0,i.jsx)(n.code,{children:"protocol_versions"})," file exists. This holds the valid protocol versions for a network."]}),"\n",(0,i.jsxs)(n.p,{children:["We can look at this manually on Mainnet using ",(0,i.jsx)(n.em,{children:"curl"}),". As of writing this, ",(0,i.jsx)(n.code,{children:"1.4.6"})," is the latest version and the contents of this file will change."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We should find ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," in those directories under ",(0,i.jsx)(n.code,{children:"casper"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["The protocol version of a network is not related to the ",(0,i.jsx)(n.code,{children:"casper-node"})," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.jsx)(n.code,{children:"casper-node"})," version for your\n",(0,i.jsx)(n.code,{children:"1.0.0"})," protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"network-configuration-file",children:"Network Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," package is installed, both ",(0,i.jsx)(n.code,{children:"casper.conf"})," and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," are installed\nin ",(0,i.jsx)(n.code,{children:"/etc/casper/network_configs"}),". Once a valid config file for a new network is copied to this location,\nall commands with ",(0,i.jsx)(n.em,{children:"node_util.py"})," will work as they do on existing networks."]}),"\n",(0,i.jsxs)(n.p,{children:["By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.jsx)(n.code,{children:"casper"})," and we use\n",(0,i.jsx)(n.code,{children:"casper.conf"})," for the config file."]}),"\n",(0,i.jsxs)(n.p,{children:["For a new network using server ",(0,i.jsx)(n.code,{children:"casper.mydomain.com"})," to host files for ",(0,i.jsx)(n.code,{children:"our-network"})," network, we would have a\n",(0,i.jsx)(n.code,{children:"our-network.conf"})," file that looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Host this ",(0,i.jsx)(n.code,{children:"our-network.conf"})," in the root of ",(0,i.jsx)(n.code,{children:"casper.mydomain.com/our-network"})," at the same level as ",(0,i.jsx)(n.code,{children:"protocol_versions"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This allows any node which wants to use the new network to run the following to install this configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any command needing a network config from ",(0,i.jsx)(n.code,{children:"node_util.py"})," can use ",(0,i.jsx)(n.code,{children:"our-network.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n"})}),"\n",(0,i.jsx)(n.h2,{id:"setup-configuration-files",children:"Setup Configuration Files"}),"\n",(0,i.jsx)(n.p,{children:"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."}),"\n",(0,i.jsx)(n.h3,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"})," file is configuration for the network and must be exactly the same on all nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["The name for a network is specified ",(0,i.jsx)(n.code,{children:"network.name"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Each protocol will have a ",(0,i.jsx)(n.code,{children:"version"})," and ",(0,i.jsx)(n.code,{children:"activation_point"}),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.jsx)(n.code,{children:"era_id"})," for activation of the upgrade."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"config-exampletoml",children:"config-example.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.jsx)(n.code,{children:"public_address"})," is auto-detected with ",(0,i.jsx)(n.code,{children:"node_util.py stage_protocols"}),". If using a NAT environment, the public IP can be specified with the ",(0,i.jsx)(n.code,{children:"--ip"})," argument."]}),"\n",(0,i.jsxs)(n.p,{children:["This file should have ",(0,i.jsx)(n.code,{children:"known_addresses"})," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[network]\nknown_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.toml"})," can be setup to customized fields for a given node. ",(0,i.jsx)(n.code,{children:"config-example.toml"})," is a default configuration."]}),"\n",(0,i.jsx)(n.h2,{id:"staging-a-protocol-version",children:"Staging a Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["For the initial genesis protocol version or future upgrade protocol versions, you will typically use\nprebuilt and tested ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," that have been tested and staged for existing networks. The ",(0,i.jsx)(n.code,{children:"config.tar.gz"}),"\nfile must be customized for the specific network with a network name, protocol version and activation point at the very least."]}),"\n",(0,i.jsxs)(n.p,{children:["These archives should be created with no directory information stored. This is done by using ",(0,i.jsx)(n.code,{children:"tar"})," in the same directory as the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can test what was compressed with untar'ing the file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will expand files for verification."}),"\n",(0,i.jsxs)(n.p,{children:["For custom ",(0,i.jsx)(n.code,{children:"casper-node"})," builds, the minimum contents of ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," is the ",(0,i.jsx)(n.code,{children:"casper-node"})," executable."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A directory for the protocol_version will be created on the server. For example: ",(0,i.jsx)(n.code,{children:"1_1_0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will copy ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," into ",(0,i.jsx)(n.code,{children:"1_1_0"}),". Once this is done, we are safe to update\n",(0,i.jsx)(n.code,{children:"protocol_versions"})," by appending ",(0,i.jsx)(n.code,{children:"1_1_0"})," to the end of the file and uploading it into the root of the network directory."]}),"\n",(0,i.jsx)(n.p,{children:"Any node that runs the following command will get this new upgrade:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>c});var i=o(96540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/772d3db3.b3494ddc.js b/assets/js/772d3db3.b3494ddc.js deleted file mode 100644 index 5215c6e7f..000000000 --- a/assets/js/772d3db3.b3494ddc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4491],{95631:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=o(74848),s=o(28453);const r={title:"Staging Files"},t="Staging Files for a New Network",c={id:"operators/setup-network/staging-files-for-new-network",title:"Staging Files",description:"Staging files is not needed for already established running networks.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/staging-files-for-new-network.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/staging-files-for-new-network",permalink:"/operators/setup-network/staging-files-for-new-network",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Staging Files"},sidebar:"operators",previous:{title:"Private Network Setup",permalink:"/operators/setup-network/create-private"},next:{title:"Node Maintenance",permalink:"/operators/maintenance/"}},l={},d=[{value:"Hosting Server",id:"hosting-server",level:2},{value:"More on <code>protocol_versions</code>",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"staging-files-for-a-new-network",children:"Staging Files for a New Network"})}),"\n",(0,i.jsxs)(n.admonition,{type:"important",children:[(0,i.jsx)(n.p,{children:"Staging files is not needed for already established running networks."}),(0,i.jsx)(n.p,{children:"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network."})]}),"\n",(0,i.jsx)(n.h2,{id:"hosting-server",children:"Hosting Server"}),"\n",(0,i.jsx)(n.p,{children:"Files for staging protocol versions are hosted on a typical HTTP(S) server."}),"\n",(0,i.jsxs)(n.p,{children:["Scripts included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."]}),"\n",(0,i.jsx)(n.p,{children:"Since a given server can be used for multiple networks, a network named directory is used to\nhold files for that network."}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of Mainnet protocol version hosting (with network name: ",(0,i.jsx)(n.code,{children:"casper"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"genesis.casperlab.io"})," is the web server URL with the following directory structure:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"protocol_versions"})," - File listing active protocol versions so scripts know what directories to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0"})," - Genesis protocol version\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_1_0"})," - First upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_1_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_1_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"... (skipping many other protocol versions)"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_4_6"})," - A later upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_4_6"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_4_6"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"more-on-protocol_versions",children:["More on ",(0,i.jsx)(n.code,{children:"protocol_versions"})]}),"\n",(0,i.jsxs)(n.p,{children:["At the root of the hosting server directory for a given network, a ",(0,i.jsx)(n.code,{children:"protocol_versions"})," file exists. This holds the valid protocol versions for a network."]}),"\n",(0,i.jsxs)(n.p,{children:["We can look at this manually on Mainnet using ",(0,i.jsx)(n.em,{children:"curl"}),". As of writing this, ",(0,i.jsx)(n.code,{children:"1.4.6"})," is the latest version and the contents of this file will change."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We should find ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," in those directories under ",(0,i.jsx)(n.code,{children:"casper"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["The protocol version of a network is not related to the ",(0,i.jsx)(n.code,{children:"casper-node"})," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.jsx)(n.code,{children:"casper-node"})," version for your\n",(0,i.jsx)(n.code,{children:"1.0.0"})," protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"network-configuration-file",children:"Network Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," package is installed, both ",(0,i.jsx)(n.code,{children:"casper.conf"})," and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," are installed\nin ",(0,i.jsx)(n.code,{children:"/etc/casper/network_configs"}),". Once a valid config file for a new network is copied to this location,\nall commands with ",(0,i.jsx)(n.em,{children:"node_util.py"})," will work as they do on existing networks."]}),"\n",(0,i.jsxs)(n.p,{children:["By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.jsx)(n.code,{children:"casper"})," and we use\n",(0,i.jsx)(n.code,{children:"casper.conf"})," for the config file."]}),"\n",(0,i.jsxs)(n.p,{children:["For a new network using server ",(0,i.jsx)(n.code,{children:"casper.mydomain.com"})," to host files for ",(0,i.jsx)(n.code,{children:"our-network"})," network, we would have a\n",(0,i.jsx)(n.code,{children:"our-network.conf"})," file that looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Host this ",(0,i.jsx)(n.code,{children:"our-network.conf"})," in the root of ",(0,i.jsx)(n.code,{children:"casper.mydomain.com/our-network"})," at the same level as ",(0,i.jsx)(n.code,{children:"protocol_versions"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This allows any node which wants to use the new network to run the following to install this configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any command needing a network config from ",(0,i.jsx)(n.code,{children:"node_util.py"})," can use ",(0,i.jsx)(n.code,{children:"our-network.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n"})}),"\n",(0,i.jsx)(n.h2,{id:"setup-configuration-files",children:"Setup Configuration Files"}),"\n",(0,i.jsx)(n.p,{children:"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."}),"\n",(0,i.jsx)(n.h3,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"})," file is configuration for the network and must be exactly the same on all nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["The name for a network is specified ",(0,i.jsx)(n.code,{children:"network.name"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Each protocol will have a ",(0,i.jsx)(n.code,{children:"version"})," and ",(0,i.jsx)(n.code,{children:"activation_point"}),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.jsx)(n.code,{children:"era_id"})," for activation of the upgrade."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"config-exampletoml",children:"config-example.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.jsx)(n.code,{children:"public_address"})," is auto-detected with ",(0,i.jsx)(n.code,{children:"node_util.py stage_protocols"}),". If using a NAT environment, the public IP can be specified with the ",(0,i.jsx)(n.code,{children:"--ip"})," argument."]}),"\n",(0,i.jsxs)(n.p,{children:["This file should have ",(0,i.jsx)(n.code,{children:"known_addresses"})," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[network]\nknown_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.toml"})," can be setup to customized fields for a given node. ",(0,i.jsx)(n.code,{children:"config-example.toml"})," is a default configuration."]}),"\n",(0,i.jsx)(n.h2,{id:"staging-a-protocol-version",children:"Staging a Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["For the initial genesis protocol version or future upgrade protocol versions, you will typically use\nprebuilt and tested ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," that have been tested and staged for existing networks. The ",(0,i.jsx)(n.code,{children:"config.tar.gz"}),"\nfile must be customized for the specific network with a network name, protocol version and activation point at the very least."]}),"\n",(0,i.jsxs)(n.p,{children:["These archives should be created with no directory information stored. This is done by using ",(0,i.jsx)(n.code,{children:"tar"})," in the same directory as the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can test what was compressed with untar'ing the file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will expand files for verification."}),"\n",(0,i.jsxs)(n.p,{children:["For custom ",(0,i.jsx)(n.code,{children:"casper-node"})," builds, the minimum contents of ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," is the ",(0,i.jsx)(n.code,{children:"casper-node"})," executable."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A directory for the protocol_version will be created on the server. For example: ",(0,i.jsx)(n.code,{children:"1_1_0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will copy ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," into ",(0,i.jsx)(n.code,{children:"1_1_0"}),". Once this is done, we are safe to update\n",(0,i.jsx)(n.code,{children:"protocol_versions"})," by appending ",(0,i.jsx)(n.code,{children:"1_1_0"})," to the end of the file and uploading it into the root of the network directory."]}),"\n",(0,i.jsx)(n.p,{children:"Any node that runs the following command will get this new upgrade:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>c});var i=o(96540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/77395f9a.d869d436.js b/assets/js/77395f9a.d869d436.js new file mode 100644 index 000000000..90df24e83 --- /dev/null +++ b/assets/js/77395f9a.d869d436.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60710],{89249:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>c,toc:()=>h});var t=s(74848),i=s(28453);const a={title:"Network Design"},o="Casper Network Design",c={id:"concepts/design/casper-design",title:"Network Design",description:"Introduction",source:"@site/versioned_docs/version-2.0.0/concepts/design/casper-design.md",sourceDirName:"concepts/design",slug:"/concepts/design/casper-design",permalink:"/2.0.0/concepts/design/casper-design",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Network Design"},sidebar:"concepts",previous:{title:"Design Overview",permalink:"/2.0.0/design"},next:{title:"Network Communication",permalink:"/2.0.0/concepts/design/p2p"}},r={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Execution Semantics",id:"execution-semantics-head",level:2},{value:"Measuring Computational Work",id:"execution-semantics-gas",level:3},{value:"The Casper Network Runtime",id:"execution-semantics-runtime",level:3},{value:"Generating <code>URef</code>s",id:"execution-semantics-urefs",level:4},{value:"Accounts",id:"accounts-head",level:2},{value:"Creating an account",id:"accounts-creating",level:3},{value:"Permissions Model",id:"accounts-permissions",level:3},{value:"Actions and Thresholds",id:"accounts-actions-thresholds",level:4},{value:"Associated Keys and Weights",id:"accounts-associated-keys-weights",level:4},{value:"Key Management Actions",id:"accounts-key-management",level:4},{value:"Account security and recovery using key management",id:"accounts-recovery",level:4},{value:"The Account Context",id:"accounts-context",level:3},{value:"Unforgeable Reference (URef)",id:"uref-head",level:2},{value:"Permissions for <code>URef</code>s",id:"uref-permissions",level:3},{value:"<code>URef</code>s and Purses",id:"urefs-and-purses",level:3},{value:"Block Structure",id:"block-structure-head",level:2},{value:"Data Fields",id:"block-structure-data",level:3},{value:"<code>block_hash</code>",id:"block_hash",level:4},{value:"Header",id:"header",level:4},{value:"Body",id:"body",level:4},{value:"Tokens",id:"tokens-head",level:2},{value:"Token Generation and Distribution",id:"token-generation-and-distribution",level:3},{value:"Divisibility of Tokens",id:"tokens-divisibility",level:3},{value:"Purses and Addressable Entities",id:"tokens-purses-and-accounts",level:3},{value:"The Casper Mint Contract",id:"mint-contract",level:3},{value:"The mint Contract Interface",id:"tokens-mint-interface",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",sup:"sup",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-network-design",children:"Casper Network Design"})}),"\n",(0,t.jsx)(n.h2,{id:"introduction",children:"Introduction"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#consensus",children:"consensus"}),". A Casper network stores data in a structure known as ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/global-state",children:"Global State"}),". Users interact with global state through session code sent in a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transaction"}),". Transactions may contain ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"Wasm"})," to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language."]}),"\n",(0,t.jsxs)(n.p,{children:["A transaction executes in the context of the user's ",(0,t.jsx)(n.a,{href:"#accounts-head",children:"Account"})," but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an ",(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(n.code,{children:"URef"}),". After a node accepts a transaction as valid, it places the transaction in a proposed ",(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block"})," and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#accounts-head",children:"Accounts"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#uref-head",children:"Unforgeable Reference (URef)"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#block-structure-head",children:"Block Structure"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.a,{href:"#tokens-head",children:"Tokens"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-head",children:"Execution Semantics"}),"\n",(0,t.jsx)(n.p,{children:"A Casper network is a decentralized computation platform. This section describes aspects of the Casper computational model."}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-gas",children:"Measuring Computational Work"}),"\n",(0,t.jsxs)(n.p,{children:["Computation is done in a ",(0,t.jsx)(n.a,{href:"https://webassembly.org/",children:"WebAssembly (Wasm)"})," interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/gas-concepts",children:(0,t.jsx)(n.code,{children:"Gas"})})," to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a ",(0,t.jsx)(n.code,{children:"Gas"})," cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter."]}),"\n",(0,t.jsxs)(n.p,{children:["Costs for opcode instructions on the Casper Mainnet network can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L115",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["All executions are finite because each has a finite ",(0,t.jsx)(n.em,{children:"gas limit"})," that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction."]}),"\n",(0,t.jsxs)(n.p,{children:["Although the network measures costs in ",(0,t.jsx)(n.code,{children:"Gas"}),", payment for computation occurs in ",(0,t.jsx)(n.a,{href:"#tokens-divisibility",children:"motes"}),". Therefore, there is a conversion rate between ",(0,t.jsx)(n.code,{children:"Gas"})," and motes."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Casper networks support configurable fee, refund, and pricing strategies to incentivize the ",(0,t.jsx)(n.a,{href:"/2.0.0/runtime#runtime-economics",children:"Casper Runtime Economics"})," by efficiently allocating computational resources. The ",(0,t.jsx)(n.a,{href:"/2.0.0/runtime#consensus-before-execution-basics-of-payment",children:"consensus-before-execution model"})," implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions."]})}),"\n",(0,t.jsx)(n.h3,{id:"execution-semantics-runtime",children:"The Casper Network Runtime"}),"\n",(0,t.jsx)(n.p,{children:"A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Casper Network Runtime",src:s(77889).A+"",width:"1220",height:"604"})}),"\n",(0,t.jsxs)(n.p,{children:["All these features are accessible via functions in the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"}),"."]}),"\n",(0,t.jsxs)(n.h4,{id:"execution-semantics-urefs",children:["Generating ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"URef"}),"s are generated using a ",(0,t.jsx)(n.a,{href:"https://rust-random.github.io/rand/rand_chacha/struct.ChaCha20Rng.html",children:"cryptographically secure random number generator"})," using the ",(0,t.jsx)(n.a,{href:"https://cr.yp.to/chacha.html",children:"ChaCha algorithm"}),". The random number generator is seeded by taking the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between ",(0,t.jsx)(n.code,{children:"URef"}),"s generated in different phases of the same transaction)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Generating URefs",src:s(40702).A+"",width:"1121",height:"289"})}),"\n",(0,t.jsx)(n.h2,{id:"accounts-head",children:"Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),". The ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/global-state#global-state-trie",children:"global state trie store"})," requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants."]}),"\n",(0,t.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys#ecdsa-keys",children:"Secp256k1"})," keys, commonly known as Ethereum keys, which are 68 bytes long"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:['By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see ',(0,t.jsx)(n.a,{href:"#tokens-purses-and-accounts",children:"Tokens"})," for more information)."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts."}),"\n",(0,t.jsx)(n.h3,{id:"accounts-creating",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["Account creation automatically happens upon transferring tokens to a yet unused ",(0,t.jsx)(n.code,{children:"PublicKey"}),". On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account Data Structure",src:s(87021).A+"",width:"426",height:"618"})}),"\n",(0,t.jsxs)(n.p,{children:["An ",(0,t.jsx)(n.code,{children:"Account"})," contains the following data:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"URef"}),' representing the account\'s "main purse"']}),"\n",(0,t.jsx)(n.li,{children:"A collection of named keys (playing the same role as the named keys in a stored contract)"}),"\n",(0,t.jsxs)(n.li,{children:['A collection of "associated keys" (see ',(0,t.jsx)(n.a,{href:"#accounts-associated-keys-weights",children:"below for more information"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:['"Action thresholds" (see ',(0,t.jsx)(n.a,{href:"#accounts-actions-thresholds",children:"below for more information"}),")"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"accounts-permissions",children:"Permissions Model"}),"\n",(0,t.jsx)(n.h4,{id:"accounts-actions-thresholds",children:"Actions and Thresholds"}),"\n",(0,t.jsx)(n.p,{children:"An account can perform two types of actions: sending transactions and managing keys. A transaction is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a transaction; therefore, a key management action implies that a transaction is also taking place."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"ActionThresholds"})," contained in the ",(0,t.jsx)(n.code,{children:"Account"})," data structure set a ",(0,t.jsx)(n.code,{children:"Weight"}),", which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a transaction, the key management threshold should always be greater than or equal to the transaction threshold."]}),"\n",(0,t.jsx)(n.h4,{id:"accounts-associated-keys-weights",children:"Associated Keys and Weights"}),"\n",(0,t.jsxs)(n.p,{children:["Addressable entities on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An addressable entity's ",(0,t.jsx)(n.em,{children:"associated keys"}),' are the set of public keys allowed to provide signatures on transactions for that entity. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each transaction must be signed by one or more keys associated with the entity that transaction is for, and the sum of the weights of those keys must be greater than or equal to the transaction threshold weight for that account. We call the keys that have signed a transaction the "authorizing keys". Similarly, if a transaction contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the entity.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.'})}),"\n",(0,t.jsx)(n.h4,{id:"accounts-key-management",children:"Key Management Actions"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"key management action"})," is a change to the account permissions, including:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Adding or removing an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the weight of an associated key"}),"\n",(0,t.jsx)(n.li,{children:"Changing the threshold of any action"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys."}),"\n",(0,t.jsx)(n.h4,{id:"accounts-recovery",children:"Account security and recovery using key management"}),"\n",(0,t.jsx)(n.p,{children:"This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign transactions from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the transaction threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:'It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").'})}),"\n",(0,t.jsx)(n.h3,{id:"accounts-context",children:"The Account Context"}),"\n",(0,t.jsxs)(n.p,{children:["A transaction is a user request to perform some execution on the blockchain (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"}),' for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity\'s context.']}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity."})}),"\n",(0,t.jsx)(n.h2,{id:"uref-head",children:"Unforgeable Reference (URef)"}),"\n",(0,t.jsxs)(n.p,{children:["This key type is used for storing any value except ",(0,t.jsx)(n.code,{children:"Account"}),". Additionally, ",(0,t.jsx)(n.code,{children:"URef"}),"s used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a ",(0,t.jsx)(n.code,{children:"URef"}),' with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged ',(0,t.jsx)(n.code,{children:"URef"})," error. Permissions for a ",(0,t.jsx)(n.code,{children:"URef"})," can be given across contract calls, allowing data stored under a ",(0,t.jsx)(n.code,{children:"URef"})," to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see ",(0,t.jsx)(n.a,{href:"#execution-semantics-head",children:"Execution Semantics"})," for more information). The serialization for ",(0,t.jsx)(n.code,{children:"Access Rights"})," that define the permissions for ",(0,t.jsx)(n.code,{children:"URefs"})," is detailed in the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue",children:"CLValues"})," section."]}),"\n",(0,t.jsxs)(n.h3,{id:"uref-permissions",children:["Permissions for ",(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.p,{children:["In the runtime, a ",(0,t.jsx)(n.code,{children:"URef"})," carries its permissions called ",(0,t.jsx)(n.code,{children:"AccessRights"}),". Additionally, the runtime tracks what ",(0,t.jsx)(n.code,{children:"AccessRights"})," would be valid for each ",(0,t.jsx)(n.code,{children:"URef"})," in each context. The system assumes that a sent ",(0,t.jsx)(n.code,{children:"URef"})," is invalid, regardless of declared ",(0,t.jsx)(n.code,{children:"AccessRights"}),", and will check it against the executing context to determine validity on each usage. Only the host logic can add a ",(0,t.jsx)(n.code,{children:"URef"}),", in the following ways:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:['It can exist in a set of "known" ',(0,t.jsx)(n.code,{children:"URef"}),"s"]}),"\n",(0,t.jsxs)(n.li,{children:["It can be freshly created by the runtime via the ",(0,t.jsx)(n.code,{children:"new_uref"})," function"]}),"\n",(0,t.jsxs)(n.li,{children:["For called contracts, the caller can pass it in via the arguments to ",(0,t.jsx)(n.code,{children:"call_contract"})]}),"\n",(0,t.jsxs)(n.li,{children:["It can be returned to the caller from ",(0,t.jsx)(n.code,{children:"call_contract"})," via the ",(0,t.jsx)(n.code,{children:"ret"})," function"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that only valid ",(0,t.jsx)(n.code,{children:"URef"}),"s may be added to the known ",(0,t.jsx)(n.code,{children:"URef"}),"s or cross-call boundaries; this means the system cannot be tricked into accepting a forged ",(0,t.jsx)(n.code,{children:"URef"})," by getting it through a contract or stashing it in the known ",(0,t.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,t.jsxs)(n.p,{children:["The ability to pass ",(0,t.jsx)(n.code,{children:"URef"}),"s between contexts via ",(0,t.jsx)(n.code,{children:"call_contract"})," / ",(0,t.jsx)(n.code,{children:"ret"}),", allows them to share state among a fixed number of parties while keeping it private from all others."]}),"\n",(0,t.jsxs)(n.h3,{id:"urefs-and-purses",children:[(0,t.jsx)(n.code,{children:"URef"}),"s and Purses"]}),"\n",(0,t.jsxs)(n.p,{children:["Purses represent a unique type of ",(0,t.jsx)(n.code,{children:"URef"})," used for accounting measures within a Casper network. ",(0,t.jsx)(n.code,{children:"URef"}),"s exist as a top-level entity, meaning that individual entities do not own \u2018URef\u2019s. As described above, entities possess certain ",(0,t.jsx)(n.code,{children:"Access Rights"}),", allowing them to interact with the given ",(0,t.jsx)(n.code,{children:"URef"}),". While an account entity will possess an associated ",(0,t.jsx)(n.code,{children:"URef"})," representing their main purse, this ",(0,t.jsx)(n.code,{children:"URef"})," exists as a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-unit",children:(0,t.jsx)(n.code,{children:"Unit"})})," and corresponds to a ",(0,t.jsx)(n.em,{children:"balance"})," key within the Casper ",(0,t.jsx)(n.em,{children:"mint"}),". The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated ",(0,t.jsx)(n.code,{children:"URef"})," and the ",(0,t.jsx)(n.code,{children:"Access Rights"})," granted to it."]}),"\n",(0,t.jsx)(n.p,{children:"Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required."}),"\n",(0,t.jsx)(n.h2,{id:"block-structure-head",children:"Block Structure"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.em,{children:"block"})," is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure."]}),"\n",(0,t.jsx)(n.h3,{id:"block-structure-data",children:"Data Fields"}),"\n",(0,t.jsx)(n.p,{children:"A block consists of the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A ",(0,t.jsx)(n.code,{children:"block_hash"})]}),"\n",(0,t.jsx)(n.li,{children:"A header"}),"\n",(0,t.jsx)(n.li,{children:"A body"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Each of these fields is detailed in the subsequent sections."}),"\n",(0,t.jsx)(n.h4,{id:"block_hash",children:(0,t.jsx)(n.code,{children:"block_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"block_hash"})," is the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the block header."]}),"\n",(0,t.jsx)(n.h4,{id:"header",children:"Header"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/structures#block-header",children:"block header"})," contains the following fields:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"parent_hash"})}),"\n",(0,t.jsxs)(n.p,{children:["A list of ",(0,t.jsx)(n.code,{children:"block_hash"}),"es giving the parents of the block."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"state_root_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The global state root hash produced by executing this block's body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"body_hash"})}),"\n",(0,t.jsx)(n.p,{children:"The hash of the block body."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"random_bit"})}),"\n",(0,t.jsx)(n.p,{children:"A boolean needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"accumulated_seed"})}),"\n",(0,t.jsx)(n.p,{children:"A seed needed for initializing a future era."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_end"})}),"\n",(0,t.jsx)(n.p,{children:"Contains equivocation and reward information to be included in the terminal finalized block. It is an optional field."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"timestamp"})}),"\n",(0,t.jsx)(n.p,{children:"The timestamp from when the block was proposed."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"era_id"})}),"\n",(0,t.jsx)(n.p,{children:"Era ID in which this block was created."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"height"})}),"\n",(0,t.jsx)(n.p,{children:"The height of this block, i.e., the number of ancestors."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,t.jsx)(n.p,{children:"The version of the Casper network when this block was proposed."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h4,{id:"body",children:"Body"}),"\n",(0,t.jsxs)(n.p,{children:["The block body contains an ",(0,t.jsx)(n.strong,{children:"ordered"})," list of transaction hashes. All transactions, including ",(0,t.jsx)(n.code,{children:"mint"}),", ",(0,t.jsx)(n.code,{children:"auction"}),", ",(0,t.jsx)(n.code,{children:"install_upgrade"})," and ",(0,t.jsx)(n.code,{children:"standard"})," transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/global-state#global-state-intro",children:"Global State"}),". A valid block may contain no transactions."]}),"\n",(0,t.jsx)(n.p,{children:"The block body also contains the public key of the validator that proposed the block."}),"\n",(0,t.jsxs)(n.p,{children:["Refer to the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization Standard"})," for additional information on how blocks and transactions are serialized."]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-head",children:"Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a decentralized Proof-of-Stake blockchain platform that may use either the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/highway",children:"Highway"})," or ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/staking",children:"stake"})," to bond. In the blockchain space, this unit of value is a ",(0,t.jsx)(n.em,{children:"token"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"This chapter describes tokens and how one can use them on the Casper platform."}),"\n",(0,t.jsx)(n.h3,{id:"token-generation-and-distribution",children:"Token Generation and Distribution"}),"\n",(0,t.jsxs)(n.p,{children:["A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available ",(0,t.jsx)(n.a,{href:"https://api.cspr.live/supply",children:"here"}),". In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage."]}),"\n",(0,t.jsx)(n.p,{children:"The number of tokens used to calculate seigniorage is the initial supply of tokens at genesis."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Token Lifecycle",src:s(34488).A+"",width:"1013",height:"656"})}),"\n",(0,t.jsx)(n.h3,{id:"tokens-divisibility",children:"Divisibility of Tokens"}),"\n",(0,t.jsxs)(n.p,{children:["Typically, a ",(0,t.jsx)(n.em,{children:"token"})," is divisible into some number of parts. We call the indivisible units which make up the CSPR token ",(0,t.jsx)(n.em,{children:"motes"}),". Each CSPR is divisible into 10",(0,t.jsx)(n.sup,{children:"9"})," motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 10",(0,t.jsx)(n.sup,{children:"18"})," parts called Wei."]}),"\n",(0,t.jsxs)(n.p,{children:["The concept of ",(0,t.jsx)(n.code,{children:"CSPR"})," is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with ",(0,t.jsx)(n.em,{children:"motes"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"tokens-purses-and-accounts",children:"Purses and Addressable Entities"}),"\n",(0,t.jsxs)(n.p,{children:["All ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/addressable-entity",children:"entities"})," on the Casper system have a purse associated with the Casper system mint, called the ",(0,t.jsx)(n.em,{children:"main purse"}),". However, for security reasons, the ",(0,t.jsx)(n.code,{children:"URef"})," of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's ",(0,t.jsx)(n.code,{children:"transfer"})," method that accepts ",(0,t.jsx)(n.code,{children:"URef"}),"s is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})," function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the ",(0,t.jsx)(n.code,{children:"source"})," and the main purse of the account entity at the provided key as the ",(0,t.jsx)(n.code,{children:"target"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"mint-contract",children:"The Casper Mint Contract"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.em,{children:"mint"})," is a system contract that manages the balance of ",(0,t.jsx)(n.em,{children:"motes"})," within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's ",(0,t.jsx)(n.em,{children:"main purse"}),". Each balance is associated with a ",(0,t.jsx)(n.code,{children:"URef"}),", which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as ",(0,t.jsx)(n.em,{children:"purses"})," and conceptually represent a container for motes. The ",(0,t.jsx)(n.code,{children:"URef"})," is how a purse is referenced externally, outside the mint."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"AccessRights"})," of the URefs permissions model determines what actions can be performed when using a ",(0,t.jsx)(n.code,{children:"URef"})," associated with a purse."]}),"\n",(0,t.jsxs)(n.p,{children:["As all ",(0,t.jsx)(n.code,{children:"URef"}),"s are unforgeable, the only way to interact with a purse is for a ",(0,t.jsx)(n.code,{children:"URef"})," with appropriate ",(0,t.jsx)(n.code,{children:"AccessRights"})," to be validly given to the current context."]}),"\n",(0,t.jsx)(n.p,{children:"The basic global state options map onto more standard monetary operations according to the table below:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Global State"}),(0,t.jsx)(n.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Add"}),(0,t.jsx)(n.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Write"}),(0,t.jsx)(n.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Read"}),(0,t.jsx)(n.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"tokens-mint-interface",children:"The mint Contract Interface"}),"\n",(0,t.jsx)(n.p,{children:"The mint system contract exposes the following methods:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transfer(source: URef, target: URef, amount: Motes) -> TransferResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"source"})," must have at least ",(0,t.jsx)(n.code,{children:"Write"})," access rights, ",(0,t.jsx)(n.code,{children:"target"})," must have at least ",(0,t.jsx)(n.code,{children:"Add"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"TransferResult"})," may be a success acknowledgment or an error in the case of invalid ",(0,t.jsx)(n.code,{children:"source"})," or ",(0,t.jsx)(n.code,{children:"target"})," or insufficient balance in the ",(0,t.jsx)(n.code,{children:"source"})," purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"mint(amount: Motes) -> MintResult"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"MintResult"})," either gives the created ",(0,t.jsx)(n.code,{children:"URef"})," (with full access rights), which now has a balance equal to the given ",(0,t.jsx)(n.code,{children:"amount"}),"; or an error due to the minting of new motes not being allowed"]}),"\n",(0,t.jsxs)(n.li,{children:["In the Casper mint, only the system account can call ",(0,t.jsx)(n.code,{children:"mint"}),", and it has no private key to produce valid cryptographic signatures, which means only the software itself can execute contracts in the context of the system account"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"create() -> URef"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["a convenience function for ",(0,t.jsx)(n.code,{children:"mint(0)"})," which cannot fail because it is always allowed to create an empty purse"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"balance(purse: URef) -> Option<Motes>"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"purse"})," must have at least ",(0,t.jsx)(n.code,{children:"Read"})," access rights"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"BalanceResult"})," either returns the number of motes held by the ",(0,t.jsx)(n.code,{children:"purse"}),", or nothing if the ",(0,t.jsx)(n.code,{children:"URef"})," is not valid"]}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},87021:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/account-structure-89919dedef5e84cf8168afa72b34ed5f.png"},77889:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/casper-runtime-9bc2eb0948168ce8a2eef7f037af6ba4.png"},40702:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/generating-urefs-af02bd8d865f5da9599a205bb682678e.png"},34488:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/token-lifecycle-3b64dfdb785ffc07a0e2df0869520f33.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const i={},a=t.createContext(i);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/77981a3a.5c6f062e.js b/assets/js/77981a3a.5c6f062e.js new file mode 100644 index 000000000..7caaeda6f --- /dev/null +++ b/assets/js/77981a3a.5c6f062e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67440],{46453:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=r(74848),o=r(28453);const i={title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},s="Getting Started Video",a={id:"resources/beginner/getting-started-tutorial",title:"Getting Started",description:"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/getting-started-tutorial.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/getting-started-tutorial",permalink:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},sidebar:"tutorials",previous:{title:"Overview",permalink:"/1.5.X/resources/tutorials/beginner/"},next:{title:"Introduction",permalink:"/1.5.X/counter"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",iframe:"iframe",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started-video",children:"Getting Started Video"})}),"\n",(0,n.jsxs)(t.p,{children:["This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started documentation"}),"."]}),"\n",(0,n.jsxs)(t.p,{align:"center",children:["\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=XvV02iBoctc&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=1",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/77981a3a.abfda3cf.js b/assets/js/77981a3a.abfda3cf.js deleted file mode 100644 index f43790ad9..000000000 --- a/assets/js/77981a3a.abfda3cf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7440],{46453:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var n=r(74848),o=r(28453);const i={title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},s="Getting Started Video",a={id:"resources/beginner/getting-started-tutorial",title:"Getting Started",description:"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/getting-started-tutorial.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/getting-started-tutorial",permalink:"/resources/tutorials/beginner/getting-started-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Getting Started",slug:"/resources/tutorials/beginner/getting-started-tutorial"},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/tutorials/beginner/"},next:{title:"Introduction",permalink:"/counter"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",iframe:"iframe",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"getting-started-video",children:"Getting Started Video"})}),"\n",(0,n.jsxs)(t.p,{children:["This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started documentation"}),"."]}),"\n",(0,n.jsxs)(t.p,{align:"center",children:["\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=XvV02iBoctc&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=1",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>s,x:()=>a});var n=r(96540);const o={},i=n.createContext(o);function s(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/77c92c8c.228a09d7.js b/assets/js/77c92c8c.228a09d7.js new file mode 100644 index 000000000..f69b66a61 --- /dev/null +++ b/assets/js/77c92c8c.228a09d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59387],{63469:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=r(74848),t=r(28453);const i={},o="Resources Overview",c={id:"resources/index",title:"Resources Overview",description:"Building on Casper",source:"@site/versioned_docs/version-2.0.0/resources/index.md",sourceDirName:"resources",slug:"/resources/",permalink:"/2.0.0/resources/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"resources",next:{title:"Build on Casper",permalink:"/2.0.0/resources/build-on-casper/introduction"}},d={},l=[{value:"Building on Casper",id:"building-on-casper",level:2},{value:"Move to Casper",id:"move-to-casper",level:2},{value:"Tutorials",id:"tutorials",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources-overview",children:"Resources Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"building-on-casper",children:"Building on Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/introduction#wallets",children:"Wallets and Block Explorers"})}),(0,s.jsx)(n.td,{children:"Wallets that support the native Casper token $CSPR"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/introduction#developer-friendly-language",children:"WebAssembly"})}),(0,s.jsx)(n.td,{children:"Learn why WebAssembly is an advantage in contract development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/introduction#powerful-accounts",children:"Accounts"})}),(0,s.jsx)(n.td,{children:"The Casper account-model allowing for multi-signature deploys"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/introduction#development-tools",children:"Developer tools"})}),(0,s.jsx)(n.td,{children:"Available development tools"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Projects"})}),(0,s.jsx)(n.td,{children:"Explore some open-source code available in the Casper ecosystem"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"move-to-casper",children:"Move to Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/moving-to-casper",children:"Move to Casper"})}),(0,s.jsx)(n.td,{children:"Learn how to start working with Casper, having previous knowledge of other blockchains"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/quick-start",children:"Quickstart"})}),(0,s.jsx)(n.td,{children:"Install Rust and setup a Casper environment"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/",children:"Beginner"})}),(0,s.jsx)(n.td,{children:"Learn the basics, such as installing and upgrading contracts"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/",children:"Advanced"})}),(0,s.jsx)(n.td,{children:"Learn about multi-sig, authorization keys, exchange integration, and storage"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>c});var s=r(96540);const t={},i=s.createContext(t);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7850177d.e012839f.js b/assets/js/7850177d.e012839f.js new file mode 100644 index 000000000..0a2bc0b01 --- /dev/null +++ b/assets/js/7850177d.e012839f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[88668],{74219:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>i});var r=n(74848),c=n(28453);const o={},a="W",t={id:"concepts/glossary/W",title:"W",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/W.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/W",permalink:"/2.0.0/concepts/glossary/W",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"V",permalink:"/2.0.0/concepts/glossary/V"},next:{title:"X",permalink:"/2.0.0/concepts/glossary/X"}},l={},i=[{value:"Web3",id:"web3",level:2},{value:"WebAssembly",id:"webassembly",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"w",children:"W"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"web3",children:"Web3"}),"\n",(0,r.jsx)(s.p,{children:"An advanced version of the internet based on decentralization and trustless interactions."}),"\n",(0,r.jsx)(s.h2,{id:"webassembly",children:"WebAssembly"}),"\n",(0,r.jsx)(s.p,{children:"WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>t});var r=n(96540);const c={},o=r.createContext(c);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/78c66fad.28feae2f.js b/assets/js/78c66fad.28feae2f.js new file mode 100644 index 000000000..7f914c165 --- /dev/null +++ b/assets/js/78c66fad.28feae2f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39902],{4690:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var n=a(74848),o=a(28453);const r={title:"Inactive and Faulty Nodes"},i="Inactive vs. Faulty Validator Nodes",s={id:"operators/becoming-a-validator/inactive-vs-faulty",title:"Inactive and Faulty Nodes",description:"This page describes the differences between a validator node being considered inactive or faulty.",source:"@site/docs/operators/becoming-a-validator/inactive-vs-faulty.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/inactive-vs-faulty",permalink:"/operators/becoming-a-validator/inactive-vs-faulty",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Inactive and Faulty Nodes"},sidebar:"operators",previous:{title:"Recovery",permalink:"/operators/becoming-a-validator/recovering"},next:{title:"Setting up Private Networks",permalink:"/operators/setup-network/"}},l={},d=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"inactive-vs-faulty-validator-nodes",children:"Inactive vs. Faulty Validator Nodes"})}),"\n",(0,n.jsx)(t.p,{children:"This page describes the differences between a validator node being considered inactive or faulty."}),"\n",(0,n.jsxs)(t.p,{children:["In the last block of each era ",(0,n.jsx)(t.em,{children:"N"}),", the consensus algorithm checks whether there are ",(0,n.jsx)(t.em,{children:"any"})," messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as ",(0,n.jsx)(t.strong,{children:"inactive"})," in that block."]}),"\n",(0,n.jsxs)(t.p,{children:["Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as ",(0,n.jsx)(t.strong,{children:"faulty"})," in that block. Usually, that means:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"inactive"}),", your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed."]}),"\n",(0,n.jsxs)(t.li,{children:["If you got marked as ",(0,n.jsx)(t.strong,{children:"faulty"}),", you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file."]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era ",(0,n.jsx)(t.em,{children:"N"}),". The auction determines the validator set for the era after the next (because ",(0,n.jsx)(t.code,{children:"auction_delay"})," is set to ",(0,n.jsx)(t.code,{children:"1"})," on mainnet), i.e., for era ",(0,n.jsx)(t.em,{children:"N + 2"}),". That means you will still be a validator (with a weight proportional to your stake) in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),", but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder."]}),"\n",(0,n.jsxs)(t.p,{children:["And even in the next era, ",(0,n.jsx)(t.em,{children:"N + 1"}),":"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era ",(0,n.jsx)(t.em,{children:"N + 1"}),", it will get evicted for being offline in era ",(0,n.jsx)(t.em,{children:"N"}),"."]}),"\n",(0,n.jsx)(t.li,{children:"If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards."}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["In both cases, you remain evicted until you reactivate your bid, as described ",(0,n.jsx)(t.a,{href:"/operators/becoming-a-validator/recovering",children:"here"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>s});var n=a(96540);const o={},r=n.createContext(o);function i(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/78c66fad.6c958184.js b/assets/js/78c66fad.6c958184.js deleted file mode 100644 index 4394ac155..000000000 --- a/assets/js/78c66fad.6c958184.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9902],{4690:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=n(74848),o=n(28453);const r={title:"Inactive and Faulty Nodes"},i="Inactive vs. Faulty Validator Nodes",s={id:"operators/becoming-a-validator/inactive-vs-faulty",title:"Inactive and Faulty Nodes",description:"This page describes the differences between a validator node being considered inactive or faulty.",source:"@site/docs/operators/becoming-a-validator/inactive-vs-faulty.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/inactive-vs-faulty",permalink:"/next/operators/becoming-a-validator/inactive-vs-faulty",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Inactive and Faulty Nodes"},sidebar:"operators",previous:{title:"Recovery",permalink:"/next/operators/becoming-a-validator/recovering"},next:{title:"Setting up Private Networks",permalink:"/next/operators/setup-network/"}},l={},d=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"inactive-vs-faulty-validator-nodes",children:"Inactive vs. Faulty Validator Nodes"})}),"\n",(0,a.jsx)(t.p,{children:"This page describes the differences between a validator node being considered inactive or faulty."}),"\n",(0,a.jsxs)(t.p,{children:["In the last block of each era ",(0,a.jsx)(t.em,{children:"N"}),", the consensus algorithm checks whether there are ",(0,a.jsx)(t.em,{children:"any"})," messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as ",(0,a.jsx)(t.strong,{children:"inactive"})," in that block."]}),"\n",(0,a.jsxs)(t.p,{children:["Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as ",(0,a.jsx)(t.strong,{children:"faulty"})," in that block. Usually, that means:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you got marked as ",(0,a.jsx)(t.strong,{children:"inactive"}),", your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed."]}),"\n",(0,a.jsxs)(t.li,{children:["If you got marked as ",(0,a.jsx)(t.strong,{children:"faulty"}),", you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file."]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era ",(0,a.jsx)(t.em,{children:"N"}),". The auction determines the validator set for the era after the next (because ",(0,a.jsx)(t.code,{children:"auction_delay"})," is set to ",(0,a.jsx)(t.code,{children:"1"})," on mainnet), i.e., for era ",(0,a.jsx)(t.em,{children:"N + 2"}),". That means you will still be a validator (with a weight proportional to your stake) in the next era, ",(0,a.jsx)(t.em,{children:"N + 1"}),", but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder."]}),"\n",(0,a.jsxs)(t.p,{children:["And even in the next era, ",(0,a.jsx)(t.em,{children:"N + 1"}),":"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era ",(0,a.jsx)(t.em,{children:"N + 1"}),", it will get evicted for being offline in era ",(0,a.jsx)(t.em,{children:"N"}),"."]}),"\n",(0,a.jsx)(t.li,{children:"If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards."}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["In both cases, you remain evicted until you reactivate your bid, as described ",(0,a.jsx)(t.a,{href:"/next/operators/becoming-a-validator/recovering",children:"here"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var a=n(96540);const o={},r=a.createContext(o);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79113.6a88e948.js b/assets/js/79113.6a88e948.js new file mode 100644 index 000000000..67f7499af --- /dev/null +++ b/assets/js/79113.6a88e948.js @@ -0,0 +1 @@ +(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79113],{27293:(e,t,n)=>{"use strict";n.d(t,{A:()=>L});var s=n(96540),a=n(74848);function o(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=s.Children.toArray(e),n=t.find((e=>s.isValidElement(e)&&"mdxAdmonitionTitle"===e.type)),o=t.filter((e=>e!==n)),c=n?.props.children;return{mdxAdmonitionTitle:c,rest:o.length>0?(0,a.jsx)(a.Fragment,{children:o}):null}}(e.children),o=e.title??t;return{...e,...o&&{title:o},children:n}}var c=n(34164),i=n(21312),r=n(17559);const l={admonition:"admonition_xJq3",admonitionHeading:"admonitionHeading_Gvgb",admonitionIcon:"admonitionIcon_Rf37",admonitionContent:"admonitionContent_BuS1"};function d(e){let{type:t,className:n,children:s}=e;return(0,a.jsx)("div",{className:(0,c.A)(r.G.common.admonition,r.G.common.admonitionType(t),l.admonition,n),children:s})}function u(e){let{icon:t,title:n}=e;return(0,a.jsxs)("div",{className:l.admonitionHeading,children:[(0,a.jsx)("span",{className:l.admonitionIcon,children:t}),n]})}function m(e){let{children:t}=e;return t?(0,a.jsx)("div",{className:l.admonitionContent,children:t}):null}function h(e){const{type:t,icon:n,title:s,children:o,className:c}=e;return(0,a.jsxs)(d,{type:t,className:c,children:[s||n?(0,a.jsx)(u,{title:s,icon:n}):null,(0,a.jsx)(m,{children:o})]})}function p(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"})})}const f={icon:(0,a.jsx)(p,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)",children:"note"})};function g(e){return(0,a.jsx)(h,{...f,...e,className:(0,c.A)("alert alert--secondary",e.className),children:e.children})}function x(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"})})}const j={icon:(0,a.jsx)(x,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)",children:"tip"})};function b(e){return(0,a.jsx)(h,{...j,...e,className:(0,c.A)("alert alert--success",e.className),children:e.children})}function v(e){return(0,a.jsx)("svg",{viewBox:"0 0 14 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"})})}const N={icon:(0,a.jsx)(v,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)",children:"info"})};function y(e){return(0,a.jsx)(h,{...N,...e,className:(0,c.A)("alert alert--info",e.className),children:e.children})}function A(e){return(0,a.jsx)("svg",{viewBox:"0 0 16 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"})})}const k={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.warning",description:"The default label used for the Warning admonition (:::warning)",children:"warning"})};function B(e){return(0,a.jsx)("svg",{viewBox:"0 0 12 16",...e,children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"})})}const C={icon:(0,a.jsx)(B,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)",children:"danger"})};const w={icon:(0,a.jsx)(A,{}),title:(0,a.jsx)(i.A,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)",children:"caution"})};const _={...{note:g,tip:b,info:y,warning:function(e){return(0,a.jsx)(h,{...k,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})},danger:function(e){return(0,a.jsx)(h,{...C,...e,className:(0,c.A)("alert alert--danger",e.className),children:e.children})}},...{secondary:e=>(0,a.jsx)(g,{title:"secondary",...e}),important:e=>(0,a.jsx)(y,{title:"important",...e}),success:e=>(0,a.jsx)(b,{title:"success",...e}),caution:function(e){return(0,a.jsx)(h,{...w,...e,className:(0,c.A)("alert alert--warning",e.className),children:e.children})}}};function L(e){const t=o(e),n=(s=t.type,_[s]||(console.warn(`No admonition component found for admonition type "${s}". Using Info as fallback.`),_.info));var s;return(0,a.jsx)(n,{...t})}},4336:(e,t,n)=>{"use strict";n.d(t,{A:()=>g});n(96540);var s=n(34164),a=n(21312),o=n(17559),c=n(28774);const i={iconEdit:"iconEdit_Z9Sw"};var r=n(74848);function l(e){let{className:t,...n}=e;return(0,r.jsx)("svg",{fill:"currentColor",height:"20",width:"20",viewBox:"0 0 40 40",className:(0,s.A)(i.iconEdit,t),"aria-hidden":"true",...n,children:(0,r.jsx)("g",{children:(0,r.jsx)("path",{d:"m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"})})})}function d(e){let{editUrl:t}=e;return(0,r.jsxs)(c.A,{to:t,className:o.G.common.editThisPage,children:[(0,r.jsx)(l,{}),(0,r.jsx)(a.A,{id:"theme.common.editThisPage",description:"The link label to edit the current page",children:"Edit this page"})]})}var u=n(36266);function m(e){let{lastUpdatedAt:t}=e;const n=new Date(t),s=(0,u.i)({day:"numeric",month:"short",year:"numeric",timeZone:"UTC"}).format(n);return(0,r.jsx)(a.A,{id:"theme.lastUpdated.atDate",description:"The words used to describe on which date a page has been last updated",values:{date:(0,r.jsx)("b",{children:(0,r.jsx)("time",{dateTime:n.toISOString(),itemProp:"dateModified",children:s})})},children:" on {date}"})}function h(e){let{lastUpdatedBy:t}=e;return(0,r.jsx)(a.A,{id:"theme.lastUpdated.byUser",description:"The words used to describe by who the page has been last updated",values:{user:(0,r.jsx)("b",{children:t})},children:" by {user}"})}function p(e){let{lastUpdatedAt:t,lastUpdatedBy:n}=e;return(0,r.jsxs)("span",{className:o.G.common.lastUpdated,children:[(0,r.jsx)(a.A,{id:"theme.lastUpdated.lastUpdatedAtBy",description:"The sentence used to display when a page has been last updated, and by who",values:{atDate:t?(0,r.jsx)(m,{lastUpdatedAt:t}):"",byUser:n?(0,r.jsx)(h,{lastUpdatedBy:n}):""},children:"Last updated{atDate}{byUser}"}),!1]})}const f={lastUpdated:"lastUpdated_JAkA"};function g(e){let{className:t,editUrl:n,lastUpdatedAt:a,lastUpdatedBy:o}=e;return(0,r.jsxs)("div",{className:(0,s.A)("row",t),children:[(0,r.jsx)("div",{className:"col",children:n&&(0,r.jsx)(d,{editUrl:n})}),(0,r.jsx)("div",{className:(0,s.A)("col",f.lastUpdated),children:(a||o)&&(0,r.jsx)(p,{lastUpdatedAt:a,lastUpdatedBy:o})})]})}},88509:(e,t,n)=>{"use strict";n.d(t,{A:()=>ie});var s=n(96540),a=n(28453),o=n(5260),c=n(92303),i=n(34164),r=n(95293),l=n(6342);function d(){const{prism:e}=(0,l.p)(),{colorMode:t}=(0,r.G)(),n=e.theme,s=e.darkTheme||n;return"dark"===t?s:n}var u=n(17559),m=n(18426),h=n.n(m);const p=/title=(?<quote>["'])(?<title>.*?)\1/,f=/\{(?<range>[\d,-]+)\}/,g={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},x={...g,lua:{start:"--",end:""},wasm:{start:"\\;\\;",end:""},tex:{start:"%",end:""},vb:{start:"['\u2018\u2019]",end:""},vbnet:{start:"(?:_\\s*)?['\u2018\u2019]",end:""},rem:{start:"[Rr][Ee][Mm]\\b",end:""},f90:{start:"!",end:""},ml:{start:"\\(\\*",end:"\\*\\)"},cobol:{start:"\\*>",end:""}},j=Object.keys(g);function b(e,t){const n=e.map((e=>{const{start:n,end:s}=x[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${s})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function v(e,t){let n=e.replace(/\n$/,"");const{language:s,magicComments:a,metastring:o}=t;if(o&&f.test(o)){const e=o.match(f).groups.range;if(0===a.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${o}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=a[0].className,s=h()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(s),code:n}}if(void 0===s)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return b(["js","jsBlock"],t);case"jsx":case"tsx":return b(["js","jsBlock","jsx"],t);case"html":return b(["js","jsBlock","html"],t);case"python":case"py":case"bash":return b(["bash"],t);case"markdown":case"md":return b(["html","jsx","bash"],t);case"tex":case"latex":case"matlab":return b(["tex"],t);case"lua":case"haskell":case"sql":return b(["lua"],t);case"wasm":return b(["wasm"],t);case"vb":case"vba":case"visual-basic":return b(["vb","rem"],t);case"vbnet":return b(["vbnet","rem"],t);case"batch":return b(["rem"],t);case"basic":return b(["rem","f90"],t);case"fsharp":return b(["js","ml"],t);case"ocaml":case"sml":return b(["ml"],t);case"fortran":return b(["f90"],t);case"cobol":return b(["cobol"],t);default:return b(j,t)}}(s,a),i=n.split("\n"),r=Object.fromEntries(a.map((e=>[e.className,{start:0,range:""}]))),l=Object.fromEntries(a.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),d=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),u=Object.fromEntries(a.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let h=0;h<i.length;){const e=i[h].match(c);if(!e){h+=1;continue}const t=e.slice(1).find((e=>void 0!==e));l[t]?r[l[t]].range+=`${h},`:d[t]?r[d[t]].start=h:u[t]&&(r[u[t]].range+=`${r[u[t]].start}-${h-1},`),i.splice(h,1)}n=i.join("\n");const m={};return Object.entries(r).forEach((e=>{let[t,{range:n}]=e;h()(n).forEach((e=>{m[e]??=[],m[e].push(t)}))})),{lineClassNames:m,code:n}}const N={codeBlockContainer:"codeBlockContainer_Ckt0"};var y=n(74848);function A(e){let{as:t,...n}=e;const s=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[s,a]=e;const o=t[s];o&&"string"==typeof a&&(n[o]=a)})),n}(d());return(0,y.jsx)(t,{...n,style:s,className:(0,i.A)(n.className,N.codeBlockContainer,u.G.common.codeBlock)})}const k={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function B(e){let{children:t,className:n}=e;return(0,y.jsx)(A,{as:"pre",tabIndex:0,className:(0,i.A)(k.codeBlockStandalone,"thin-scrollbar",n),children:(0,y.jsx)("code",{className:k.codeBlockLines,children:t})})}var C=n(89532);const w={attributes:!0,characterData:!0,childList:!0,subtree:!0};function _(e,t){const[n,a]=(0,s.useState)(),o=(0,s.useCallback)((()=>{a(e.current?.closest("[role=tabpanel][hidden]"))}),[e,a]);(0,s.useEffect)((()=>{o()}),[o]),function(e,t,n){void 0===n&&(n=w);const a=(0,C._q)(t),o=(0,C.Be)(n);(0,s.useEffect)((()=>{const t=new MutationObserver(a);return e&&t.observe(e,o),()=>t.disconnect()}),[e,a,o])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),o())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}var L=n(71765);const E={codeLine:"codeLine_lJS_",codeLineNumber:"codeLineNumber_Tfdd",codeLineContent:"codeLineContent_feaV"};function T(e){let{line:t,classNames:n,showLineNumbers:s,getLineProps:a,getTokenProps:o}=e;1===t.length&&"\n"===t[0].content&&(t[0].content="");const c=a({line:t,className:(0,i.A)(n,s&&E.codeLine)}),r=t.map(((e,t)=>(0,y.jsx)("span",{...o({token:e})},t)));return(0,y.jsxs)("span",{...c,children:[s?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)("span",{className:E.codeLineNumber}),(0,y.jsx)("span",{className:E.codeLineContent,children:r})]}):r,(0,y.jsx)("br",{})]})}var S=n(21312);function U(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})})}function M(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"})})}const z={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function I(e){let{code:t,className:n}=e;const[a,o]=(0,s.useState)(!1),c=(0,s.useRef)(void 0),r=(0,s.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const s=document.createElement("textarea"),a=document.activeElement;s.value=e,s.setAttribute("readonly",""),s.style.contain="strict",s.style.position="absolute",s.style.left="-9999px",s.style.fontSize="12pt";const o=document.getSelection(),c=o.rangeCount>0&&o.getRangeAt(0);n.append(s),s.select(),s.selectionStart=0,s.selectionEnd=e.length;let i=!1;try{i=document.execCommand("copy")}catch{}s.remove(),c&&(o.removeAllRanges(),o.addRange(c)),a&&a.focus()}(t),o(!0),c.current=window.setTimeout((()=>{o(!1)}),1e3)}),[t]);return(0,s.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),(0,y.jsx)("button",{type:"button","aria-label":a?(0,S.T)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,S.T)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,S.T)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.A)("clean-btn",n,z.copyButton,a&&z.copyButtonCopied),onClick:r,children:(0,y.jsxs)("span",{className:z.copyButtonIcons,"aria-hidden":"true",children:[(0,y.jsx)(U,{className:z.copyButtonIcon}),(0,y.jsx)(M,{className:z.copyButtonSuccessIcon})]})})}function H(e){return(0,y.jsx)("svg",{viewBox:"0 0 24 24",...e,children:(0,y.jsx)("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})})}const R={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function V(e){let{className:t,onClick:n,isEnabled:s}=e;const a=(0,S.T)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return(0,y.jsx)("button",{type:"button",onClick:n,className:(0,i.A)("clean-btn",t,s&&R.wordWrapButtonEnabled),"aria-label":a,title:a,children:(0,y.jsx)(H,{className:R.wordWrapButtonIcon,"aria-hidden":"true"})})}function W(e){let{children:t,className:n="",metastring:a,title:o,showLineNumbers:c,language:r}=e;const{prism:{defaultLanguage:u,magicComments:m}}=(0,l.p)(),h=function(e){return e?.toLowerCase()}(r??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??u),f=d(),g=function(){const[e,t]=(0,s.useState)(!1),[n,a]=(0,s.useState)(!1),o=(0,s.useRef)(null),c=(0,s.useCallback)((()=>{const n=o.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[o,e]),i=(0,s.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=o.current,n=e>t||o.current.querySelector("code").hasAttribute("style");a(n)}),[o]);return _(o,i),(0,s.useEffect)((()=>{i()}),[e,i]),(0,s.useEffect)((()=>(window.addEventListener("resize",i,{passive:!0}),()=>{window.removeEventListener("resize",i)})),[i]),{codeBlockRef:o,isEnabled:e,isCodeScrollable:n,toggle:c}}(),x=function(e){return e?.match(p)?.groups.title??""}(a)||o,{lineClassNames:j,code:b}=v(t,{metastring:a,language:h,magicComments:m}),N=c??function(e){return Boolean(e?.includes("showLineNumbers"))}(a);return(0,y.jsxs)(A,{as:"div",className:(0,i.A)(n,h&&!n.includes(`language-${h}`)&&`language-${h}`),children:[x&&(0,y.jsx)("div",{className:k.codeBlockTitle,children:x}),(0,y.jsxs)("div",{className:k.codeBlockContent,children:[(0,y.jsx)(L.f4,{theme:f,code:b,language:h??"text",children:e=>{let{className:t,style:n,tokens:s,getLineProps:a,getTokenProps:o}=e;return(0,y.jsx)("pre",{tabIndex:0,ref:g.codeBlockRef,className:(0,i.A)(t,k.codeBlock,"thin-scrollbar"),style:n,children:(0,y.jsx)("code",{className:(0,i.A)(k.codeBlockLines,N&&k.codeBlockLinesWithNumbering),children:s.map(((e,t)=>(0,y.jsx)(T,{line:e,getLineProps:a,getTokenProps:o,classNames:j[t],showLineNumbers:N},t)))})})}}),(0,y.jsxs)("div",{className:k.buttonGroup,children:[(g.isEnabled||g.isCodeScrollable)&&(0,y.jsx)(V,{className:k.codeButton,onClick:()=>g.toggle(),isEnabled:g.isEnabled}),(0,y.jsx)(I,{className:k.codeButton,code:b})]})]})]})}function $(e){let{children:t,...n}=e;const a=(0,c.A)(),o=function(e){return s.Children.toArray(e).some((e=>(0,s.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof o?W:B;return(0,y.jsx)(i,{...n,children:o},String(a))}function D(e){return(0,y.jsx)("code",{...e})}var P=n(28774);var G=n(63427),q=n(41422);const O={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function F(e){return!!e&&("SUMMARY"===e.tagName||F(e.parentElement))}function Z(e,t){return!!e&&(e===t||Z(e.parentElement,t))}function J(e){let{summary:t,children:n,...a}=e;(0,G.A)().collectAnchor(a.id);const o=(0,c.A)(),r=(0,s.useRef)(null),{collapsed:l,setCollapsed:d}=(0,q.u)({initialState:!a.open}),[u,m]=(0,s.useState)(a.open),h=s.isValidElement(t)?t:(0,y.jsx)("summary",{children:t??"Details"});return(0,y.jsxs)("details",{...a,ref:r,open:u,"data-collapsed":l,className:(0,i.A)(O.details,o&&O.isBrowser,a.className),onMouseDown:e=>{F(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;F(t)&&Z(t,r.current)&&(e.preventDefault(),l?(d(!1),m(!0)):d(!0))},children:[h,(0,y.jsx)(q.N,{lazy:!1,collapsed:l,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{d(e),m(!e)},children:(0,y.jsx)("div",{className:O.collapsibleContent,children:n})})]})}const Y={details:"details_b_Ee"},K="alert alert--info";function Q(e){let{...t}=e;return(0,y.jsx)(J,{...t,className:(0,i.A)(K,Y.details,t.className)})}function X(e){const t=s.Children.toArray(e.children),n=t.find((e=>s.isValidElement(e)&&"summary"===e.type)),a=(0,y.jsx)(y.Fragment,{children:t.filter((e=>e!==n))});return(0,y.jsx)(Q,{...e,summary:n,children:a})}var ee=n(51107);function te(e){return(0,y.jsx)(ee.A,{...e})}const ne={containsTaskList:"containsTaskList_mC6p"};function se(e){if(void 0!==e)return(0,i.A)(e,e?.includes("contains-task-list")&&ne.containsTaskList)}const ae={img:"img_ev3q"};var oe=n(27293);const ce={Head:o.A,details:X,Details:X,code:function(e){return function(e){return void 0!==e.children&&s.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")))}(e)?(0,y.jsx)(D,{...e}):(0,y.jsx)($,{...e})},a:function(e){return(0,y.jsx)(P.A,{...e})},pre:function(e){return(0,y.jsx)(y.Fragment,{children:e.children})},ul:function(e){return(0,y.jsx)("ul",{...e,className:se(e.className)})},li:function(e){return(0,G.A)().collectAnchor(e.id),(0,y.jsx)("li",{...e})},img:function(e){return(0,y.jsx)("img",{decoding:"async",loading:"lazy",...e,className:(t=e.className,(0,i.A)(t,ae.img))});var t},h1:e=>(0,y.jsx)(te,{as:"h1",...e}),h2:e=>(0,y.jsx)(te,{as:"h2",...e}),h3:e=>(0,y.jsx)(te,{as:"h3",...e}),h4:e=>(0,y.jsx)(te,{as:"h4",...e}),h5:e=>(0,y.jsx)(te,{as:"h5",...e}),h6:e=>(0,y.jsx)(te,{as:"h6",...e}),admonition:oe.A,mermaid:()=>null};function ie(e){let{children:t}=e;return(0,y.jsx)(a.x,{components:ce,children:t})}},39022:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(96540);var s=n(34164),a=n(28774),o=n(74848);function c(e){const{permalink:t,title:n,subLabel:c,isNext:i}=e;return(0,o.jsxs)(a.A,{className:(0,s.A)("pagination-nav__link",i?"pagination-nav__link--next":"pagination-nav__link--prev"),to:t,children:[c&&(0,o.jsx)("div",{className:"pagination-nav__sublabel",children:c}),(0,o.jsx)("div",{className:"pagination-nav__label",children:n})]})}},56133:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(96540);var s=n(34164),a=n(28774);const o={tag:"tag_zVej",tagRegular:"tagRegular_sFm0",tagWithCount:"tagWithCount_h2kH"};var c=n(74848);function i(e){let{permalink:t,label:n,count:i,description:r}=e;return(0,c.jsxs)(a.A,{href:t,title:r,className:(0,s.A)(o.tag,i?o.tagWithCount:o.tagRegular),children:[n,i&&(0,c.jsx)("span",{children:i})]})}},62053:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});n(96540);var s=n(34164),a=n(21312),o=n(56133);const c={tags:"tags_jXut",tag:"tag_QGVx"};var i=n(74848);function r(e){let{tags:t}=e;return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)("b",{children:(0,i.jsx)(a.A,{id:"theme.tags.tagsListLabel",description:"The label alongside a tag list",children:"Tags:"})}),(0,i.jsx)("ul",{className:(0,s.A)(c.tags,"padding--none","margin-left--sm"),children:t.map((e=>(0,i.jsx)("li",{className:c.tag,children:(0,i.jsx)(o.A,{...e})},e.permalink)))})]})}},36266:(e,t,n)=>{"use strict";n.d(t,{i:()=>a});var s=n(44586);function a(e){void 0===e&&(e={});const{i18n:{currentLocale:t}}=(0,s.A)(),n=function(){const{i18n:{currentLocale:e,localeConfigs:t}}=(0,s.A)();return t[e].calendar}();return new Intl.DateTimeFormat(t,{calendar:n,...e})}},18426:(e,t)=>{function n(e){let t,n=[];for(let s of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(s))n.push(parseInt(s,10));else if(t=s.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,s,a,o]=t;if(s&&o){s=parseInt(s),o=parseInt(o);const e=s<o?1:-1;"-"!==a&&".."!==a&&"\u2025"!==a||(o+=e);for(let t=s;t!==o;t+=e)n.push(t)}}return n}t.default=n,e.exports=n},28453:(e,t,n)=>{"use strict";n.d(t,{R:()=>c,x:()=>i});var s=n(96540);const a={},o=s.createContext(a);function c(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:c(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79474bae.a5a4db28.js b/assets/js/79474bae.a5a4db28.js new file mode 100644 index 000000000..aabfe4d3c --- /dev/null +++ b/assets/js/79474bae.a5a4db28.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5296],{60507:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var o=s(74848),r=s(28453);const t={title:"Non-Root Users"},i="Setting up a Non-Root User",a={id:"operators/setup/non-root-user",title:"Non-Root Users",description:"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.",source:"@site/versioned_docs/version-1.5.X/operators/setup/non-root-user.md",sourceDirName:"operators/setup",slug:"/operators/setup/non-root-user",permalink:"/1.5.X/operators/setup/non-root-user",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Non-Root Users"},sidebar:"operators",previous:{title:"Join a Network",permalink:"/1.5.X/operators/setup/joining"},next:{title:"Becoming a Validator",permalink:"/1.5.X/operators/becoming-a-validator/"}},d={},c=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"setting-up-a-non-root-user",children:"Setting up a Non-Root User"})}),"\n",(0,o.jsxs)(n.p,{children:["Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace ",(0,o.jsx)(n.code,{children:"<username>"})," in the instructions below with your username."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use ",(0,o.jsx)(n.a,{href:"https://www.ssh.com/academy/ssh/keygen",children:"ssh-keygen"})," to generate a new SSH key."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Create the user with no password, as the key is your password."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo adduser <username> --disabled-password\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Create authorized_keys with your key to log in."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo su - <username>\nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use the editor of your choice and paste your .ssh public key i the ",(0,o.jsx)(n.code,{children:".ssh/authorized_keys"})," file."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Exit out of the ",(0,o.jsx)(n.code,{children:"<username>"})," account and log into the root or previous sudo-er account."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"exit\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Add your user to sudo-ers under the root account or your previous sudo-er account."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo visudo\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Type ",(0,o.jsx)(n.code,{children:"<username> ALL=(ALL:ALL) NOPASSWD:ALL"})," below the row containing ",(0,o.jsx)(n.code,{children:"root ALL=(ALL:ALL) ALL"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n<username> ALL=(ALL:ALL) NOPASSWD:ALL\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"You should be able to log in with the key and not use the root user."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i <your ssh private key> <username>@<server ip>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Here is an example command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var o=s(96540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79474bae.b05288fa.js b/assets/js/79474bae.b05288fa.js deleted file mode 100644 index 335e78542..000000000 --- a/assets/js/79474bae.b05288fa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5296],{60507:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>a,toc:()=>c});var o=s(74848),r=s(28453);const t={title:"Non-Root Users"},i="Setting up a Non-Root User",a={id:"operators/setup/non-root-user",title:"Non-Root Users",description:"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.",source:"@site/versioned_docs/version-1.5.X/operators/setup/non-root-user.md",sourceDirName:"operators/setup",slug:"/operators/setup/non-root-user",permalink:"/operators/setup/non-root-user",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Non-Root Users"},sidebar:"operators",previous:{title:"Join a Network",permalink:"/operators/setup/joining"},next:{title:"Becoming a Validator",permalink:"/operators/becoming-a-validator/"}},d={},c=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"setting-up-a-non-root-user",children:"Setting up a Non-Root User"})}),"\n",(0,o.jsxs)(n.p,{children:["Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace ",(0,o.jsx)(n.code,{children:"<username>"})," in the instructions below with your username."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use ",(0,o.jsx)(n.a,{href:"https://www.ssh.com/academy/ssh/keygen",children:"ssh-keygen"})," to generate a new SSH key."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Create the user with no password, as the key is your password."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo adduser <username> --disabled-password\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Create authorized_keys with your key to log in."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo su - <username>\nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use the editor of your choice and paste your .ssh public key i the ",(0,o.jsx)(n.code,{children:".ssh/authorized_keys"})," file."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Exit out of the ",(0,o.jsx)(n.code,{children:"<username>"})," account and log into the root or previous sudo-er account."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"exit\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Add your user to sudo-ers under the root account or your previous sudo-er account."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo visudo\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Type ",(0,o.jsx)(n.code,{children:"<username> ALL=(ALL:ALL) NOPASSWD:ALL"})," below the row containing ",(0,o.jsx)(n.code,{children:"root ALL=(ALL:ALL) ALL"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n<username> ALL=(ALL:ALL) NOPASSWD:ALL\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"You should be able to log in with the key and not use the root user."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i <your ssh private key> <username>@<server ip>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Here is an example command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var o=s(96540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79d896a3.09570395.js b/assets/js/79d896a3.09570395.js new file mode 100644 index 000000000..6f4d2c3b8 --- /dev/null +++ b/assets/js/79d896a3.09570395.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[48426],{70525:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=s(74848),a=s(28453);const i={title:"Gas Cost"},o="Gas and Resources",c={id:"concepts/economics/gas-concepts",title:"Gas Cost",description:"What is gas?",source:"@site/docs/concepts/economics/gas-concepts.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/gas-concepts",permalink:"/concepts/economics/gas-concepts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Gas Cost"},sidebar:"concepts",previous:{title:"Runtime",permalink:"/runtime"},next:{title:"Dynamic Gas Pricing",permalink:"/concepts/economics/dynamic-gas-pricing"}},r={},l=[{value:"What is gas?",id:"what-is-gas",level:2},{value:"How is gas cost determined?",id:"how-is-gas-cost-determined",level:2},{value:"Why do we need to charge a cost?",id:"why-do-we-need-to-charge-a-cost",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"gas-and-resources",children:"Gas and Resources"})}),"\n",(0,n.jsx)(t.h2,{id:"what-is-gas",children:"What is gas?"}),"\n",(0,n.jsx)(t.p,{children:"Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,n.jsxs)(t.p,{children:["Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures ",(0,n.jsx)(t.a,{href:"/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational work as gas"})," because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See ",(0,n.jsx)(t.a,{href:"/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,n.jsx)(t.h2,{id:"how-is-gas-cost-determined",children:"How is gas cost determined?"}),"\n",(0,n.jsxs)(t.p,{children:["The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to ",(0,n.jsx)(t.a,{href:"/concepts/economics/dynamic-gas-pricing",children:"dynamic pricing"})," can be configured in a Casper network's ",(0,n.jsx)(t.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"why-do-we-need-to-charge-a-cost",children:"Why do we need to charge a cost?"}),"\n",(0,n.jsx)(t.p,{children:"Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Rate-limiting is used to ensure a secure and live network:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era."}),"\n",(0,n.jsx)(t.li,{children:"It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators."}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Pricing leads to more meaningful transactions:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction."}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/79d896a3.a26aa031.js b/assets/js/79d896a3.a26aa031.js deleted file mode 100644 index d5b0cc65d..000000000 --- a/assets/js/79d896a3.a26aa031.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8426],{70525:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=s(74848),a=s(28453);const i={title:"Gas Cost"},o="Gas and Resources",c={id:"concepts/economics/gas-concepts",title:"Gas Cost",description:"What is gas?",source:"@site/docs/concepts/economics/gas-concepts.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/gas-concepts",permalink:"/next/concepts/economics/gas-concepts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Gas Cost"},sidebar:"concepts",previous:{title:"Runtime",permalink:"/next/runtime"},next:{title:"Dynamic Gas Pricing",permalink:"/next/concepts/economics/dynamic-gas-pricing"}},r={},l=[{value:"What is gas?",id:"what-is-gas",level:2},{value:"How is gas cost determined?",id:"how-is-gas-cost-determined",level:2},{value:"Why do we need to charge a cost?",id:"why-do-we-need-to-charge-a-cost",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"gas-and-resources",children:"Gas and Resources"})}),"\n",(0,n.jsx)(t.h2,{id:"what-is-gas",children:"What is gas?"}),"\n",(0,n.jsx)(t.p,{children:"Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,n.jsxs)(t.p,{children:["Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures ",(0,n.jsx)(t.a,{href:"/next/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational work as gas"})," because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See ",(0,n.jsx)(t.a,{href:"/next/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,n.jsx)(t.h2,{id:"how-is-gas-cost-determined",children:"How is gas cost determined?"}),"\n",(0,n.jsxs)(t.p,{children:["The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to ",(0,n.jsx)(t.a,{href:"/next/concepts/economics/dynamic-gas-pricing",children:"dynamic pricing"})," can be configured in a Casper network's ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"why-do-we-need-to-charge-a-cost",children:"Why do we need to charge a cost?"}),"\n",(0,n.jsx)(t.p,{children:"Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Rate-limiting is used to ensure a secure and live network:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era."}),"\n",(0,n.jsx)(t.li,{children:"It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators."}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Pricing leads to more meaningful transactions:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction."}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ade0b2a.77621e50.js b/assets/js/7ade0b2a.77621e50.js deleted file mode 100644 index ac230f0a6..000000000 --- a/assets/js/7ade0b2a.77621e50.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6163],{13868:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var n=r(74848),t=r(28453);const a={},o="D",c={id:"concepts/glossary/D",title:"D",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/D.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/D",permalink:"/concepts/glossary/D",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"C",permalink:"/concepts/glossary/C"},next:{title:"E",permalink:"/concepts/glossary/E"}},l={},i=[{value:"dApp",id:"dapp",level:2},{value:"Delegation rate",id:"delegation-rate",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Dictionary",id:"dictionary",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"d",children:"D"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"dapp",children:"dApp"}),"\n",(0,n.jsxs)(s.p,{children:["A decentralized application (dApp) employs ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S#smart-contract",children:"smart contracts"})," installed on a decentralized peer-to-peer network such as a blockchain."]}),"\n",(0,n.jsx)(s.h2,{id:"delegation-rate",children:"Delegation rate"}),"\n",(0,n.jsxs)(s.p,{children:["Node operators (",(0,n.jsx)(s.a,{href:"/concepts/glossary/V#validator",children:"validators"}),") define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services."]}),"\n",(0,n.jsx)(s.h2,{id:"delegator",children:"Delegator"}),"\n",(0,n.jsx)(s.p,{children:'Delegators are users who participate in the platform\'s security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.'}),"\n",(0,n.jsx)(s.h2,{id:"deploy",children:"Deploy"}),"\n",(0,n.jsx)(s.p,{children:"Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network."}),"\n",(0,n.jsxs)(s.p,{children:["All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Review the ",(0,n.jsx)(s.a,{href:"/concepts/serialization-standard#serialization-standard-deploy",children:"deploy data structure"})," and the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/master/node/src/types/deploy.rs#L475",children:"deploy implementation"})," for more details."]}),"\n",(0,n.jsx)(s.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,n.jsxs)(s.p,{children:["A ",(0,n.jsx)(s.code,{children:"Dictionary"})," is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N#named-keys",children:(0,n.jsx)(s.code,{children:"NamedKeys"})}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["More information can be found in the ",(0,n.jsx)(s.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," document."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>c});var n=r(96540);const t={},a=n.createContext(t);function o(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ade0b2a.9718930e.js b/assets/js/7ade0b2a.9718930e.js new file mode 100644 index 000000000..715ec76f6 --- /dev/null +++ b/assets/js/7ade0b2a.9718930e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76163],{13868:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var n=r(74848),t=r(28453);const a={},o="D",c={id:"concepts/glossary/D",title:"D",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/D.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/D",permalink:"/1.5.X/concepts/glossary/D",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"C",permalink:"/1.5.X/concepts/glossary/C"},next:{title:"E",permalink:"/1.5.X/concepts/glossary/E"}},l={},i=[{value:"dApp",id:"dapp",level:2},{value:"Delegation rate",id:"delegation-rate",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Dictionary",id:"dictionary",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"d",children:"D"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"dapp",children:"dApp"}),"\n",(0,n.jsxs)(s.p,{children:["A decentralized application (dApp) employs ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S#smart-contract",children:"smart contracts"})," installed on a decentralized peer-to-peer network such as a blockchain."]}),"\n",(0,n.jsx)(s.h2,{id:"delegation-rate",children:"Delegation rate"}),"\n",(0,n.jsxs)(s.p,{children:["Node operators (",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validators"}),") define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services."]}),"\n",(0,n.jsx)(s.h2,{id:"delegator",children:"Delegator"}),"\n",(0,n.jsx)(s.p,{children:'Delegators are users who participate in the platform\'s security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.'}),"\n",(0,n.jsx)(s.h2,{id:"deploy",children:"Deploy"}),"\n",(0,n.jsx)(s.p,{children:"Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network."}),"\n",(0,n.jsxs)(s.p,{children:["All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Review the ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-deploy",children:"deploy data structure"})," and the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/master/node/src/types/deploy.rs#L475",children:"deploy implementation"})," for more details."]}),"\n",(0,n.jsx)(s.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,n.jsxs)(s.p,{children:["A ",(0,n.jsx)(s.code,{children:"Dictionary"})," is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N#named-keys",children:(0,n.jsx)(s.code,{children:"NamedKeys"})}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["More information can be found in the ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," document."]})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>c});var n=r(96540);const t={},a=n.createContext(t);function o(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b1c3c68.2f0f9401.js b/assets/js/7b1c3c68.2f0f9401.js new file mode 100644 index 000000000..42c65d84f --- /dev/null +++ b/assets/js/7b1c3c68.2f0f9401.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[88652],{42903:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="Proof-of-Stake JSON-RPC Methods",i={id:"developers/json-rpc/json-rpc-pos",title:"Proof-of-Stake JSON-RPC Methods",description:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.",source:"@site/docs/developers/json-rpc/json-rpc-pos.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-pos",permalink:"/developers/json-rpc/json-rpc-pos",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Informational JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-informational"},next:{title:"Types",permalink:"/developers/json-rpc/types_chain"}},d={},o=[{value:"state_get_auction_info",id:"state_get_auction_info",level:2},{value:"<code>state_get_auction_info_result</code>",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info_get_validator_changes",level:2},{value:"<code>info_get_validator_changes_result</code>",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"<code>chain_get_era_info_by_switch_block_result</code>",id:"chain_get_era_info_by_switch_block_result",level:3}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"proof-of-stake-json-rpc-methods",children:"Proof-of-Stake JSON-RPC Methods"})}),"\n",(0,t.jsx)(n.p,{children:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"state_get_auction_info",children:"state_get_auction_info"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns the ",(0,t.jsx)(n.a,{href:"/concepts/economics/consensus#bids",children:"bids"})," and ",(0,t.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validators"})," from a specific Block (by height or hash). If you do not provide a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", ",(0,t.jsx)(n.code,{children:"state_get_auction_info"})," will return information from the most recent Block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The Block identifier. (Optional)"})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"state_get_auction_info_result",children:(0,t.jsx)(n.code,{children:"state_get_auction_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#auctionstate",children:"auction_state"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The auction state."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_auction_info_result",\n "value": {\n "api_version": "2.0.0",\n "auction_state": {\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "bids": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bid": {\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "staked_amount": "20",\n "delegation_rate": 0,\n "vesting_schedule": null,\n "delegators": [\n {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "delegator": {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "staked_amount": "10",\n "bonding_purse": "uref-fbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb-007",\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "vesting_schedule": null\n }\n }\n ],\n "inactive": false\n }\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"info_get_validator_changes",children:"info_get_validator_changes"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns status changes of active validators. Listed changes occurred during the ",(0,t.jsx)(n.code,{children:"EraId"})," contained within the response itself. A validator may show more than one change in a single era."]}),"\n",(0,t.jsx)(n.p,{children:"Potential change types:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Change Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Added"}),(0,t.jsx)(n.td,{children:"The validator has been added to the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Removed"}),(0,t.jsx)(n.td,{children:"The validator has been removed from the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Banned"}),(0,t.jsx)(n.td,{children:"The validator has been banned in the current era."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"CannotPropose"}),(0,t.jsx)(n.td,{children:"The validator cannot propose a Block."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SeenAsFaulty"}),(0,t.jsx)(n.td,{children:"The validator has performed questionable activity."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"info_get_validator_changes_result",children:(0,t.jsx)(n.code,{children:"info_get_validator_changes_result"})}),"\n",(0,t.jsxs)(n.p,{children:["If no changes occurred in the current era, ",(0,t.jsx)(n.code,{children:"info_get_validator_changes"})," will return empty."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonvalidatorchanges",children:"changes"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The validators' status changes."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_validator_changes_result",\n "value": {\n "api_version": "2.0.0",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chain_get_era_info_by_switch_block",children:"chain_get_era_info_by_switch_block"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns an EraInfo from the network. Only the last Block in an ",(0,t.jsx)(n.code,{children:"era"}),", known as a switch block, will contain an ",(0,t.jsx)(n.code,{children:"era_summary"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsxs)(n.td,{children:["The Block identifier. If you do not supply a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", the returned information will be the most recent Block. (Optional)"]})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"chain_get_era_info_by_switch_block_result",children:(0,t.jsx)(n.code,{children:"chain_get_era_info_by_switch_block_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_era_info_by_switch_block_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b1c3c68.e8be7755.js b/assets/js/7b1c3c68.e8be7755.js deleted file mode 100644 index 1b2d2a1f6..000000000 --- a/assets/js/7b1c3c68.e8be7755.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8652],{42903:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="Proof-of-Stake JSON-RPC Methods",i={id:"developers/json-rpc/json-rpc-pos",title:"Proof-of-Stake JSON-RPC Methods",description:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.",source:"@site/docs/developers/json-rpc/json-rpc-pos.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-pos",permalink:"/next/developers/json-rpc/json-rpc-pos",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Informational JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-informational"},next:{title:"Types",permalink:"/next/developers/json-rpc/types_chain"}},d={},o=[{value:"state_get_auction_info",id:"state_get_auction_info",level:2},{value:"<code>state_get_auction_info_result</code>",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info_get_validator_changes",level:2},{value:"<code>info_get_validator_changes_result</code>",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"<code>chain_get_era_info_by_switch_block_result</code>",id:"chain_get_era_info_by_switch_block_result",level:3}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"proof-of-stake-json-rpc-methods",children:"Proof-of-Stake JSON-RPC Methods"})}),"\n",(0,t.jsx)(n.p,{children:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"state_get_auction_info",children:"state_get_auction_info"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns the ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/consensus#bids",children:"bids"})," and ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validators"})," from a specific Block (by height or hash). If you do not provide a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", ",(0,t.jsx)(n.code,{children:"state_get_auction_info"})," will return information from the most recent Block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The Block identifier. (Optional)"})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"state_get_auction_info_result",children:(0,t.jsx)(n.code,{children:"state_get_auction_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#auctionstate",children:"auction_state"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The auction state."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_auction_info_result",\n "value": {\n "api_version": "2.0.0",\n "auction_state": {\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "bids": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bid": {\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "staked_amount": "20",\n "delegation_rate": 0,\n "vesting_schedule": null,\n "delegators": [\n {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "delegator": {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "staked_amount": "10",\n "bonding_purse": "uref-fbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb-007",\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "vesting_schedule": null\n }\n }\n ],\n "inactive": false\n }\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"info_get_validator_changes",children:"info_get_validator_changes"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns status changes of active validators. Listed changes occurred during the ",(0,t.jsx)(n.code,{children:"EraId"})," contained within the response itself. A validator may show more than one change in a single era."]}),"\n",(0,t.jsx)(n.p,{children:"Potential change types:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Change Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Added"}),(0,t.jsx)(n.td,{children:"The validator has been added to the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Removed"}),(0,t.jsx)(n.td,{children:"The validator has been removed from the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Banned"}),(0,t.jsx)(n.td,{children:"The validator has been banned in the current era."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"CannotPropose"}),(0,t.jsx)(n.td,{children:"The validator cannot propose a Block."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SeenAsFaulty"}),(0,t.jsx)(n.td,{children:"The validator has performed questionable activity."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"info_get_validator_changes_result",children:(0,t.jsx)(n.code,{children:"info_get_validator_changes_result"})}),"\n",(0,t.jsxs)(n.p,{children:["If no changes occurred in the current era, ",(0,t.jsx)(n.code,{children:"info_get_validator_changes"})," will return empty."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#jsonvalidatorchanges",children:"changes"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The validators' status changes."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_validator_changes_result",\n "value": {\n "api_version": "2.0.0",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chain_get_era_info_by_switch_block",children:"chain_get_era_info_by_switch_block"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns an EraInfo from the network. Only the last Block in an ",(0,t.jsx)(n.code,{children:"era"}),", known as a switch block, will contain an ",(0,t.jsx)(n.code,{children:"era_summary"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsxs)(n.td,{children:["The Block identifier. If you do not supply a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", the returned information will be the most recent Block. (Optional)"]})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"chain_get_era_info_by_switch_block_result",children:(0,t.jsx)(n.code,{children:"chain_get_era_info_by_switch_block_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_era_info_by_switch_block_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b8da7d8.8db3e644.js b/assets/js/7b8da7d8.8db3e644.js new file mode 100644 index 000000000..17db8e545 --- /dev/null +++ b/assets/js/7b8da7d8.8db3e644.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13e3],{6188:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(74848),s=t(28453);const o={title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},r="Launching a Casper Node with AWS Marketplace",a={id:"resources/beginner/aws-node",title:"AWS Casper Nodes",description:"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.",source:"@site/docs/resources/beginner/aws-node.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/aws-node",permalink:"/resources/tutorials/beginner/aws-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},sidebar:"tutorials",previous:{title:"Fungible Tokens",permalink:"/resources/tutorials/beginner/cep18"},next:{title:"Advanced Tutorials",permalink:"/resources/tutorials/advanced/"}},c={},h=[{value:"Step 1 - Subscribing",id:"step-1---subscribing",level:2},{value:"Step 2 - Initial Configuration",id:"step-2---initial-configuration",level:2},{value:"Step 3 - Launch Configuration",id:"step-3---launch-configuration",level:2},{value:"EC2 Key Pair Settings",id:"ec2-key-pair-settings",level:3},{value:"Launching Your Node",id:"launching-your-node",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"launching-a-casper-node-with-aws-marketplace",children:"Launching a Casper Node with AWS Marketplace"})}),"\n",(0,i.jsxs)(n.p,{children:["The following tutorial outlines the process for launching a ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-d7xpciuetjq5u",children:"Casper Node through the Amazon AWS Marketplace"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1---subscribing",children:"Step 1 - Subscribing"}),"\n",(0,i.jsx)(n.p,{children:"You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 01",src:t(78864).A+"",width:"900",height:"214"})}),"\n",(0,i.jsx)(n.p,{children:"If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe."}),"\n",(0,i.jsxs)(n.p,{children:["You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/ec2/instance-types/",children:"Amazon EC2 (Amazon Elastic Compute Cloud) instance type"})," if you prefer."]}),"\n",(0,i.jsxs)(n.p,{children:["After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the ",(0,i.jsx)(n.code,{children:"Continue to Configuration"})," button grayed out, as shown below:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 04",src:t(9035).A+"",width:"259",height:"60"})}),"\n",(0,i.jsx)(n.p,{children:"Once the system processes your request, the button will light orange, and you may continue to the configuration options."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 05",src:t(18530).A+"",width:"266",height:"68"})}),"\n",(0,i.jsx)(n.h2,{id:"step-2---initial-configuration",children:"Step 2 - Initial Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Configuration"})," page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release."]}),"\n",(0,i.jsx)(n.p,{children:"The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 06",src:t(63901).A+"",width:"1138",height:"713"})}),"\n",(0,i.jsx)(n.h2,{id:"step-3---launch-configuration",children:"Step 3 - Launch Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Launch"})," page will show your previously selected configuration details and a ",(0,i.jsx)(n.code,{children:"Usage instructions"})," button that leads to the most recent instructions based on your chosen software version."]}),"\n",(0,i.jsx)(n.p,{children:'Below this, you will see a drop-down menu with the title "Choose Action":'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 08",src:t(42772).A+"",width:"834",height:"189"})}),"\n",(0,i.jsx)(n.p,{children:"This drop-down menu includes the following options:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Launch through EC2 - This option launches your configuration through the ",(0,i.jsx)(n.a,{href:"https://console.aws.amazon.com/ec2/",children:"Amazon EC2 Console"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Launch from Website - This option will launch directly from the current page, using further configuration options outlined below."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy to Service Catalog - Copy your configuration of the software to the ",(0,i.jsx)(n.code,{children:"Service Catalog"})," console, where you can manage your company's cloud resources."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional drop-down menus include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.'}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-key-pair-settings",children:"EC2 Key Pair Settings"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 11",src:t(64239).A+"",width:"830",height:"245"})}),"\n",(0,i.jsx)(n.p,{children:'You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 12",src:t(82694).A+"",width:"339",height:"43"})}),"\n",(0,i.jsx)(n.h3,{id:"launching-your-node",children:"Launching Your Node"}),"\n",(0,i.jsxs)(n.p,{children:["If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange ",(0,i.jsx)(n.code,{children:"Launch"})," button to launch your AWS-hosted Casper node."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 13",src:t(10561).A+"",width:"137",height:"58"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},78864:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS01-26219ce99c140282c6ad9137863a954a.png"},9035:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAA8CAIAAADt6EhQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAiFSURBVHhe7ZyJchpJEobpbu7TgCWhA+uwxp6dHUfMW+y8086DzT7IHjFrW7JBB4izgeZs2K+ohmCEhCXNWIus/IKQu6u7qrKq8s/KQgobTrfrE4Rnj+n9KwjPG1GCIChECYKgECUIgkKUIAgKUYIgKEQJgqAQJQiCYtVv1k6KRe9KEL4JDvf2vKslZE8QBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEASFKEEQFKIEQVCIEgRBIUoQBIUo4VtgMplUGo0PxeJZ+Wrkul6pcB/W8a+y7U7nslLtDwZc+/3+7ZfZF4mEfvRgmu3254vLTCq5u7npFa0BeO1lpdJsd8bjsWGa8Ugkn9uyzHuHp4tKpVyrR0KhgN+fTiYKpXIiGjnY2fEef2UKpVKj1T7YziViMa9oXXlKf5VdLJVPzs7HrovXbqTT4VBwPJ54z+7DcDT698lpuVbTt6FAMBGLxiIRffung8z++7ng3dyNbr//2+mnWtOOhMOMNJ2IG4YxGY+9x/fB6fWCgcDh7g4fxpiIRr+qU2L5Pz98bLRa+jYWjiRjsVAopG+fKOulBLvdqdv2i0T87eEBwTv3Mnu4s4Mk9FN3PCa08+FCl8whPWB5arY9GI10CVEWOelrQFHEyGt7S384xBF7vb53vxKkVbdbLcehYa9ogaHr9TtnhbWAwedXlfFkcpTfO9rdYaSMd387xx6on+rh8JNrXWXOstmLwYJt4WBnO5tK6Vuqtx2n2encaMZtMFh64YLBdnu9SqOJ2OaWMMmLVrFAWB6cWg484mUs1C0swqNry7Q+rFd2VCyX602bwBaPRr2iGeTBF1eViU8tAKuwlc3kslmuicQsmzHNNPTi7G5suGMXP5veKTLJ5EYm/aFQ2Mxk+BC/bcchCRmxomp1fITknY2XlHd6veP8Hs5Em+8LxVg4/Go7xxtn5TJLSwIzmYwt08LCaDisG2dpaXnken4WCgZpAQHcaO0ccr/3nwvRaASpe0Uzhq57en7uOF3TslzXJec53NvFz240m1xosfc5DBnLcbiT4hkWWpZFIbNE8Kb8tpGq8m6Xl3Fl9pbNTJoS1ZxhaEuO9nYZF66sCqcwb/xk732dz/MCfZ2eXwyGQ9M0URGNoHOub1ym7AtPro/Gk8mOmCzTMFge734G81uqVpHHu+NjPiz/Va3enmkY78xv5959d/wmn2fSWUvc/e3Bvt8yWaef3r5hjfWbc9guCMNU+eHoKBQMUMV7cBOcW8gEdjY33h2/fru/z3JWGw3vmc/H8v94fMyS86GvvxwesNgrrNUwUjaE5ZFCqVLt9QeHu7t0992rPMI4L5f1o2Wz572jwL++PsIAPXD9PhXp6PhVnqbwe7IvXb4CxBOPRhgFGwtZ1g+vj+iO6ntbm/g3PTKZPEKQ/KQ7ptqrOQ35BCB+MktUeZXbcnrd0ixBXV4mXb4mrJcS3JFrMsdLR0bcyHXH5DasJRDwVKHj6KemaYUCAS4sv3XH46ZpGuFgkAtqEON14W2QEdFp0B9AkLiv5ff3Btf3/UVWW6shihMa6d27n0EOg4uEAwFONdxOBRamXxya23uZTVP9wRCFcBDndjo3X54cyzTSySS1UCnvU4eu2cH0rrIapNJjMwmHyUW5TcXj4WCo3XHU/vWgZXpM1ssgjn24iF71RdQ5UjmVd8uqcD1Y6Y5/ImNlkvvp8pJ8hs9gMAivPB3exVoiumn4+n31/dgi6niD36jqXn3LMMlMHvDdqNfUH4D94T+nn/718eS3T58Ll6UvtkV3pG1zyxES16Px+AHGPz7rpYRIJMzykY149zOIf8zufFnxDK4JW979V8bvtwKW9YYcgzxh+slvrfoq9i7WovmAP+DMgv0cgqWKl7jUrL7LycRSYVTf3h2qENU5Mj3YEUuVCsZ/f7DPkEl1ZtK+FbXpmNbc8qkSJ9jwAOMfn/VSQjqRYPcvV2sXV1f94VCnCuQViXiM2SQ7V+etyaTatImay6fqRQy1HAbpAe+zJLpwNcQy2idHp0rbIcPxfDQeibKk5XpDrzGt6d91LIKXUBe35p14LPpFa3GaTCpFOvGxeGa3OzgcbTZbbToiL+oO+nVbfUdJYtZx1GHgxhPFaojHyXh8MBwVS2XaIYOfq+62kV5jLmZe6/5u+1KiwHjKQRcB8o6GQ61ut9VRqWC91eoNBszGfJdYZ6y///KLd7lEY+ErgseBkJJKJEiLa7ZdqTfKtRoOwRZL5oorUHhZrZaqNfKTXDZDIVVqTRvvyaSS+BY+yjtBvz+ViBNHaYeTLlVG7igaidRtW59rm+12fzjAEbV70QI/1deOhtFstarNZrlWn/q6wdLSFEkzS1mp12kKky6rNbb9a1/Y4w4Nu0XFRqv9MpWiyo3WLsIBwG/52QB1j5VGo9N1yK35OP3BFd1VqthMJsZBk9HdavbvJwEXpxYGYDldkLI0Oh3qMi1EFj2i20Z6rQuGyXCupgvB3NJFMhbDHjZJzkJ0yujokTcJWLoW89zqdKazVEUPzNLe5gZKuG2ZqPuYLK/CnDX9n7+INIQT4jpJBfKYFxKHmFD2ja8UZlgkEnpyEe0Ki9xo0grubi2hGvelTX2g1OC1VGdvWbbkYdDL+0Jh+mts9U3aipEuol8LBAPa4++IHhHquletR2DFt6jyf+B9y5BYjtwxOwMyu6hU6k07n9v643+68nQRJTxTOHgUy6XhSJ2Y2V42s5nNdFo/ep6IEgRB8ZT+Ak8Q/i+IEgRBIUoQBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEATFqr87+sevv3pXgvBN8Leff/aulpA9QRAUq/YEQXg+yJ4gCApRgiAoRAmCoBAlCIJClCAIClGCIChECYKgECUIgs/n8/0Ps5JgKFFEE0IAAAAASUVORK5CYII="},18530:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQoAAABECAIAAAD2jOw2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAoZSURBVHhe7Zx3cFTXFca3F+2uCuqsGkKWEDIWEiOaKDYgAsKywLaCnTY2EOwkkzaMJ4ntTDITx+SP2CmT8XhsQ4zHYwwulNASQEh0iSK6wepCfbXqW7Q1n/ZdrRl2r7RgjBc4v3mzere8984t37nnvlmt2GyxiAiC8IeE/SUIwgeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBJexv7Gr3q1mZwRxX2BZFui31Gn1IAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJI/7B7dbdNoQ/peq9J2NcUNOGtk7QPB2Yn2/5qUTD+dvm4dj1aHcL/u0rOBrUN2rnfrJgh318SwdHGAqf1KrL943Ey1dvCv/vS9SbK7bGZf/Nccs3zezw6Js6Nc0DITM2jb/7SsTWNk3z8c1CdM/f7RxIISl7wukr7z6KjvlIK/+Mzu7i3xap1+5Py9WPbQms/E7SZ0ysTtZa4lRD7HigDE7pKvLciNVtmTd8Ff8JRK3WuaaGds9TmUXKtxZ3r+WhIm+MMHA0gHQZVWsLs/dUpNQMrFlZVrL1Mg+aCNrXL9M4mY1AgadppU7/jb74px4Y4jMKRG7Z8T0xIfccqcFCCx/9kBeTmRflNqGpFgkwgBNj+lRSF1ChaDFkT7GnPcSjKtHXb/mtTMZf8r74v3HzhRPaFuoN/x8Sh1mjFCK2YMKOHxdLKKL7iHFxe7QQbtMyLE5JV1WpXAOIhT2FyfXp4WZWNrDgF2GS3AhS48K9HatV9s8qHa4MB9upt2sYmcjjGItgMEbryYbLMqDRUd/OaUWLUV7n8toUnlmmLc5+MT5TfiaPWBjrQaQxwuTG3Ki+oSkyy1uNqmxpPg1gwcai6fgBI01WBVnu8I7zErcSihFJ3v7GWCAfpzZAH0KSVRDZVgo3OFGfIcpaAnG/xb8vG78+qr07UtO6jVWljUCYus1ZblOzwj1Dsk3LTizQD/sql+pmFw3oHG6xDX9GnS6yy36dHFlv1226D9zPNcN8878qseT2xF+vD7j8rx4Izz9R9WJSTrz6c4I3BBRwZaCyqVJHcgvbYl+e945zDDMjxcPT8UjMGUxqHDPv6nIilLZLA5pis684dGz3gUNrhR3ruyMEJLPpDXjDld6dH6t9YLM7x3MW5rYDv2zrBHwiNer0hFoJWvNiDOXp7a+MesSJp9fs/Niem58uhc0GZajQ9adeHh73fgJoSaxWKSUup7LaEQ+r6XI39MYh8r/upT6qym1yCnZPx1rES6s69OsSG19c/bFrbX6teU57DEi0YGio/h8uSILo4b+MVoVCIz3N8fEa6y1fZpfZ9f8duqXWA/9DtPUEQ3fNe7t/xZsMami1TaNzMnSI8Dl/OFU5qpJjedLSi+UHHxtxpXfV2a2mpjD7rfJ/p5/4ezTh04+WT4xzHzOGAYNtP5o7/SYHgyebe0ODLNQ00uLWbUuu+ZcSenppw5hQh9ti2QF/qgf0Pzj4sStBZWVT5YdXX5YKXVi+FmZSIQ5gcyXsqtx4FkfLDhjdUpHsVbA5JAaLApfLwD2NMUeaI45uaIczTn33VJMsg+rE4UiX7O9T0eyd9UuGCA0XKiPC6/16qpKSnGr3YUnwhRjB5YVhog5ccaWH+57edo16OTUU4fQsSdWlO9edvxUZ0TTQAg680JJaV50Dz7xOHQ1u9KzOGy4mtxnk11YeRB9dWT5YYSOB1uihVLfYRLyg5NglIdxSBmhtMl9QtiaPk3DYMiihE54MnjBRfpOhApXe3VCKTYY4crhgVdJnbFqPxPOF8Ra0aph9w+/KJyMwrmuMEysaJUNC4XdJU7SWq50s0f7ZXRrBcx2GWIPwewbQU1oY358V5LWjGR8iLU4pe1IWyTkhOQtmY1bne8Ky481jveIEJ0TiDwSNZZZcd0wDE4KXl8ucWN5wVqnkTtxB1aJQ59NXtYaXZjcATuRTA8bRCccaokW4sPbGKZvkWCUR4rOhGDd5BOYWp2SIYfEazEmB46mwbsU+yFUQzzzzIG84r0zcVR0RDwSybZDfgnE2giVDY6/3udtD2J9KEHq0ZWATuFAHIWIi6UDRrgVS9wWiIJ+eiQ7c8uiZXtmoeEdlq/2cn5xuMVYImC8kIS6QqTOVrPK4vxaZnwrBKM8JkcMYO97qTuUpUcIlTtCFQ7vmjKE+eeUwIuz9DcMthnTYnr3Fh4/tuKwcKxMa2Zl/gjEWlSYMq6/vDUKvplleVBIXPCy2Fp4d+TYdifrzGqfgHNM1FLn+BCrwarE01nWLbKjIR4x4fmnS9HknUtOxo71/hBeAMuCsOMC0KfZKYUNsETIuYcIRnlkR/Y9kdL2syPZiL8ReyA8aDOrsCFJCzOlhZq21iZgpF1u8Z6mOHimSeED7DJ/SMTD3qvFpMY88/uuyRcEEgiBuq3DL4uuD6qxjgn5k8IHO8zK/16PFV7d4G4INoQiL3Kpu8OqxFxHnYmhY1sLGWCXjP3x7yqysDigpbhnbb8Gc2tJYsfuprhLPcM+As7is3r93Hij735sTLD+FCa3l7ZEYcON5mBLfbx9nFDEa+lNIJIUTtCKZpMKeyohifXB5JAZPJcLfSKgkzsKEg2bqxNgNpKXe0L3NsU+pjd4V8J7iGCUB9zPX2dden5S4/Ol0yL/vUz7XlHG5oJj7ZFauQMb3MOtkboNRap3n3jzfBqqCSE1jwiF7dm06y+U5yjfLd5Sm8ByRyU/zojxTv1ocdjGorcup+o1zN+nhpr+OefCH09Pit+0FKX6D5ZiMyAUeVkxofVYW2T4xsfXlOVg7xSItTNie3YuPYlp+tDmArQ0ZlPhL44+gmm3UG9Yk9mQv22+4p3ijI8XYRP8g4eus2tukblxxrfmnv+sTr+6LNfhksD7CPm8lt7EgvFdPUOKKVsXpm0u2N8cg2VNyE/SmYtS2pbsnq3dUHSig0lOAKbmRPXBbBg/d/u8n2TVozms7J4iqH8GDj6p1zbsoUPldrheIRMjis2fSyQOV9ix6xUy7yxYGfrtcuwdQ3y8tV+TRiFwa7Hm4IBrgPdlWZ6NNeJ4mOFrye2Bfcja8pzCpI7ve8Q2SktvRKgG94TljmUFgNAiBJC3dNVdIPAXu/Qrifc/iEvNdplea4GedzXEra9K/3Dh6YzwQVb84EHyIL4CmxkEbGWtUXaXZE6ccf2My4joWNkDCcmDILjQb+wSxB2A5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMFl7O9cnV2Xxc4I4r4g943L7GwsaPUgCC5jrx4E8cBCqwdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcBCJ/g+JpAip6TfCDgAAAABJRU5ErkJggg=="},63901:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS04-f0a5f08295ac98ac10216dda2c6ac467.png"},42772:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS05-ef5cc7abd1f5093685ce82cb5794a2aa.png"},64239:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS06-fa837b0e61647fe37340261a3ae8fde3.png"},82694:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAArCAIAAABKL/w7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAC3hJREFUeF7tnV9IW1kex2tq/f+n1dbqVOiTT/pSaFkYH+ZhfWj70AWRUp1i7SozVtBm65QGsVhlm+K4EkJrBmmV8aE+uJXCECglOIuEHQTJS9xuW3TdBpnS6A4GsTQEIfs75/xyc++5N7fJNXE0OR++DPeef/d47/ne8zvndsihkEAgyDyE8wWCTEQ4XyDIRITzBYJMRDhfIMhEhPMFgkxEOF8gyESE8wWCTETP+a65+T/f+EvT1x37RNAZ6BJ2TsV+6+2Blv6t3nn1ODxZFB4/JLTfNVkEDwsfmxI958PjX/7Pf8P7BugMdAk7p2K/9fZAo3+rhe0PkiaL8LEp0XM+vPtxIOwboEvYORX7sLcHGp1bzY8tof0tfGxKhPMF2gjnp43wsSkRzhdoI5yfNsLHpkQ4X6CNcH7aCB+bkhQ6f339fzOzPw38dQTauWG+A3o0Pvmvf79huZBooH2d4bjL3go4dG41N7CE9rnwsSlJlfPB81BdU/AugALsmBWOH6iCnVNhoDWBDjq3mhtYQvtc+NiUpMT5bJ4Hgf/ZJA/zPwsBWDrM/+yAlY8fqIKdU2GgteSz5VvyvPbv4NmBRudWcwProCs4kuO25HlHsrj0PZZ/MG/RauISkyJ8bEqS73xmb/C2FNjLAf9LtjfQPlTBzqkw0JoWIc9Ub9et3q6phRCmxE/A/T35o/pevseEg4zOreYGljEFh/OfNpU31p8kaiib6E/JoI9H/u4TFVWnr3cf5tL3VIMlf6w6XVFVusilJ0P42JQk2flgbKgF0rQ9y5ILM+IGqmDnVBhoTYOtn63YN/vCJ0yLjecJlBxw+vE0vLn04737joUPeLo3SBGWWo/GJ7FQ4kB1vLMquIFlQL7esotkoINOXayvPJs84zEb2/r5dB3tC+ePZTubyi2dOUEuPRnCx6Ykyc6HoQa1YNrHcyVsOMqFGXEDVbBzKgy0pmZzfgja6Ru6C/+1ugOYKvEpsLb8em3rI55+eH4b/oq+mdWtwPYnGiJ8CmxvBULyaD+0sfpqwfNqZVMeQpBitBGau/ROdqGd0OY7r8fjXV2PXOVzyGMoTpCFhRIHquOdVcENrIRly7fUgOcrLeZsfqCPmQJ2E03MihwQBYchIM99a1ME5EG7yTeYx6UvXiEvFOt3UjtUY6a3/XnuwezgD5EUmTjnQ7NQNzCGuUHbkUVYCwxHLvFQkRv+gfQzYOdXCqSRh3CQFbify18XqoySNpXpinYi1enl2MEuhI9NSUqc/4/5f+J5stEZjgZ6qyIw9wAMY19Yc/aBc77/eRvTwZAbC+O9zRFHNU95w0sOdoya9ECppUly/GSJ1Qn73X/riJbpGXHjKoAWs4w8uis12DHlJW+Gj54nZkwBxblqgPDq257bUi25NCOvOIHqeGdVcAMrUQV6y8hsf6EgoMqiJqy2dhWaa8HAJ2ZHYOjn2r6sJuWJqhuv5jI/e1tPRRJpentOePzwbIOUAqLVIb7oKYeYAhNry53D0csxyZ3v6z5eV3W67nyhj2RlOy9Er3L2QgEkBi1HoUBFUx7rBqvb0pkttUaVa4My5ypayF9Bda7MRTsTHi0wk7deRLVlLhtNHym8DqcNhX6pekPx7NWT5FotubKWjQgfm5IkO5/NPxDz43my0RmOBnrLE3h5DwxDDL/y7BY4Z2guMhn7X5IooLnv8dyyb/vX1+4378OBFc/zB5DYdMsx51nw0Hlb4fxfZ25CbtvQs+UN//JMXxtk3X2xTnJYsZuT7tX1wJrbfo0UewyVNl0k4rjn8kHgsL2+svoh3q0GaetUrliRV5xAC3hnVXADK1F5rxInN37DuYWIGamittLcVOJoLXaPZrkvQ+EKx4ApPG5yX6mK+rm/wDtMp9/R/AHwUk2pdzzLP1BgrSeOMndALJDjh5nZWtQCTr5U4IfZdbgI3FWnMpLk/GB/KVmDnCtdpNOsr7MC3imWHvpG6CSvJLqIyHGcgUscc5Np3+S6BMfYJZmodatOTAweDtizXZcrof26y/RlYYfg5YifTO8mbwe0f7qTtq/h/Krq+q/KrK0l1p4jysYTFj42Jb+b89noxJO40RmOBlrjYPZmQf7a8144vjfPrL/xYgh62zO1TM8k2LQvW+fLnc9sfG36Nc0JL02RrD7XBjmWvyDWaXzxtQPOQot2iAKazQ+mf1nZTPADARfz7ybOZ0AjeGdVcAMrUS22EHNqrqvl0y9Vjg1c/YejsxAbW/KcV05CbnQNj5F2Np3q2d4YTvtSGX/PcTg1t5PqbkuxOequqPCiV0o7yRvk+CwGBYed56Gp8gl6aXdHudQx9kYgl7DnW6BBjeCFWTeyXTdMXU3eTViALSiCllKpTS3nJ223Dx+bkiQ7n+02fTbIhOUAFDOw/6QzHA30VonvpzvEM81ddG+/6wYcR1z9/sUAZOGMHUXX+ew9IkXs8tNYzodwf/Wl/WY7yW1qvzv9Jt6lPsDF/LuJ8xnQCN5ZFdzASlS+b4iBK65oBLEq5zMPyFXlGCRZvt5jjfKwOZbzWRAh16V8zqisTF0NiUTq2cxMxK0diCy99AMEiyNacoN3jkUTFVJa9yF9QbDThzkTDfJ1Sro4n4Wdn7V0nMXU6AxHA71VwILz9h5ie6pr0ficzfkRr0roOn/bTdYCzXT9D7AsFlDEdj5lJ+T3OEhnhpybmBQXUsy/yzifAe3gnVXBDayExb5gRWfXqLTn/DMl0myJGssbgBbqi9+SHTJm0RjOZ3O+We+TIV60K3f2PJi/urObLUNwzneydbhCJucF0itHS3VFzVEa9nNSWtda1Eh6W+SLvPXwZdGfRnO+/lc9BmR9tkwsoBZ2TgVkYSFDsPC+6/kKnkf8edPpg+NN9wOyG9c9ND2/4PG8fOYmieG1mS5IbLM8mV+YWyIpCksHfrbCu4PmeuYf3ybHD9jngljO3/Q8f/HLwtK7jbWlH0ligs4HIMhn/0Ry90AP8c6q4AZW4oLlMd20q/mik6znSxxN5Y1tOZClcv4hbxsskqsbG4tcNOp2dRcu2iNh9pmj7lGTf7DQQhbezCdZ7ibi/It/KnJ9l+eFkuw7Qu0Jh5kF/AVPe/n9hehFH+bazkH1Sls/2WMP9JbVVZ0+21DiZAG/uchlxSq4zyet3nkx61aa2wvgiravyB/LdgG9bVXkWp1HYJHibiHr/DRxPsAieRiCmsaWbG9sXtIZjsZ6i+ysTJMtPcVKPrRgJ129M7NGzj6+/Xt0K/7atJcWCUgb/mS3n7M0TPtvnt5moTtIFr3HdP48fb9g+aEXe/vvAjigD3hnVXADy5BMi63H66PhenV9DOeHx7NdjXSLm6m23DUKiVneVkys+/KYJTrnHwrfL7qOO+rHnaTkoeBgcSQFhBeSS3FRGslH4pEsb/uJ6HeBmi8cA5FaY3lW0nlceqjErFtxHQN7eHPl048F4PAC+tkCdOp6YxnEAunjfJj22bc9ENib+R8S4UAKRw3PS1AXO6cCsrBQ6tgJ8Z/rgZ0Qn6IgFNqKfL2PB3qJBMqnDJ1bzQ2s3Qj3urQ+sytEv/Pzn83Jp3X+QzpqTOsDezwXUkv7i/2RiXqtZQhKZl3oJL8coA1qrBFSJXxsSpLvfAB8Lplcrd2sQqE6dk4FZGEhQTLQudXcwMowZbtaS6wXyIc61Wd8SUmetHcpfGxKUuJ8Bpv82W4/W3+C5yERsw0hnL9nCOfHEN10lAfwGsqZIP8/QnGMiGCvhY9NSQqdnwqE8/cM4fy0ET42JcL5Am2E89NG+NiUCOcLtBHOTxvhY1MinC/QRjg/bYSPTYme88UvbWQs4pc20kcGfmlD/LpWxkr/Votf1zowMvbrWgKBIF0RzhcIMhHhfIEgExHOFwgyEeF8gSATEc4XCDIR4XyB4Pdh/bff8GjvCYX+DxMofqYM+5EQAAAAAElFTkSuQmCC"},10561:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAA6CAIAAAALGO1FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMmSURBVHhe7ZxRSFNRGMev1+6cF2pr2NRYoRU+pEhgWSTGQERTxpAg7cGgp7AeevTRx/BpTyFEMLUgsdIksk3FXpIEg8okJSqFzBRUrgruzMtm5+4ehYZL9qD8h9+Py/adb2eXc/ntfDuHXZa2ubkpEZDI4pnAg9zgQm5wITe4kBtcyA0u5AaXBPubF2kiIPaBaztvMWne4EJucCE3uJAbXMgNLuQGF3KDC7nBhdzgQm5wITe4kBtcyA0uB9eNtpT9dk5looUIjhtHW1dl87cM0dp7piYvVY1la6KFCI4bWVtVpzfSRYtIjZqmK5rmGF1StYhI7I6uzCw4ZnTREkRljSkai79kFlanFmxJnHy/QHfz6b3H8qSiPlDS0l/hbK/0zRkDnp8ot/Tlz5s9JLWrz3t9QuWRkX9e4huqLO5y3x4oK/B7WqYVsxObLfR2eJxPK+qf1VreZZlJKZTt660p7Sm7F7jibHf7l0UaBHQ350pfb9wKBBsGg42BvpNq80+HeCERy9bci4Pjjbz/QLdLvv/bZiRDrubgKdv5YeNUja82Li/GunLW6672j9/gnUdaD9nezBmCcYCvaelR/sCYwqL60Uwz9X/W8g6bQTjniBlI2qyrLfLrTuGaaG9fdOZanjUWyCzXHguQQHdj1CK/p7TX7e2uvvlVJJOFhXlli+J/DuMAH2+WL3gmrzxglJ2GQOdZkU0Wu7ouSUoobmkAD5gbviQzllLmERvb9vIpos6sitAY9aJjMmyEbNXxcbdNijV3oSn9uP+LTTMKpMT01JhBWKN8OeZ2dtZsHUWj0mLdhZWe4erixzUF3UV/1BWzW07+dJPsqurwWh566j9Yc46Z6cRkzrbWfmef3c5H/C3e4qETW2s8aFLh3kE+maIRe0bsM78N36zwjaqi25PZrfIvHibrdrGuhiGF7x3kAuLEcOSo3ZqcGI41A09MYlKj8h5MyA0u5AYXcoMLucGF3OBCbnAhN7iQG1zIDS7kBhdygwu5wWXn3whG7p4WEbH3lD34IaJ/oXmDC/3vIC40b3AhN7iQG1zIDS7kBhdygwu5QUWS/gKbZ/EkaoCEzgAAAABJRU5ErkJggg=="},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7b8da7d8.eab766d1.js b/assets/js/7b8da7d8.eab766d1.js deleted file mode 100644 index 5e88545a0..000000000 --- a/assets/js/7b8da7d8.eab766d1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3e3],{6188:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(74848),s=t(28453);const o={title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},r="Launching a Casper Node with AWS Marketplace",a={id:"resources/beginner/aws-node",title:"AWS Casper Nodes",description:"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.",source:"@site/docs/resources/beginner/aws-node.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/aws-node",permalink:"/next/resources/tutorials/beginner/aws-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},sidebar:"tutorials",previous:{title:"Fungible Tokens",permalink:"/next/resources/tutorials/beginner/cep18"},next:{title:"Advanced Tutorials",permalink:"/next/resources/tutorials/advanced/"}},c={},h=[{value:"Step 1 - Subscribing",id:"step-1---subscribing",level:2},{value:"Step 2 - Initial Configuration",id:"step-2---initial-configuration",level:2},{value:"Step 3 - Launch Configuration",id:"step-3---launch-configuration",level:2},{value:"EC2 Key Pair Settings",id:"ec2-key-pair-settings",level:3},{value:"Launching Your Node",id:"launching-your-node",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"launching-a-casper-node-with-aws-marketplace",children:"Launching a Casper Node with AWS Marketplace"})}),"\n",(0,i.jsxs)(n.p,{children:["The following tutorial outlines the process for launching a ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-d7xpciuetjq5u",children:"Casper Node through the Amazon AWS Marketplace"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1---subscribing",children:"Step 1 - Subscribing"}),"\n",(0,i.jsx)(n.p,{children:"You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 01",src:t(1106).A+"",width:"900",height:"214"})}),"\n",(0,i.jsx)(n.p,{children:"If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe."}),"\n",(0,i.jsxs)(n.p,{children:["You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/ec2/instance-types/",children:"Amazon EC2 (Amazon Elastic Compute Cloud) instance type"})," if you prefer."]}),"\n",(0,i.jsxs)(n.p,{children:["After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the ",(0,i.jsx)(n.code,{children:"Continue to Configuration"})," button grayed out, as shown below:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 04",src:t(91817).A+"",width:"259",height:"60"})}),"\n",(0,i.jsx)(n.p,{children:"Once the system processes your request, the button will light orange, and you may continue to the configuration options."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 05",src:t(36992).A+"",width:"266",height:"68"})}),"\n",(0,i.jsx)(n.h2,{id:"step-2---initial-configuration",children:"Step 2 - Initial Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Configuration"})," page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release."]}),"\n",(0,i.jsx)(n.p,{children:"The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 06",src:t(71967).A+"",width:"1138",height:"713"})}),"\n",(0,i.jsx)(n.h2,{id:"step-3---launch-configuration",children:"Step 3 - Launch Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Launch"})," page will show your previously selected configuration details and a ",(0,i.jsx)(n.code,{children:"Usage instructions"})," button that leads to the most recent instructions based on your chosen software version."]}),"\n",(0,i.jsx)(n.p,{children:'Below this, you will see a drop-down menu with the title "Choose Action":'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 08",src:t(91990).A+"",width:"834",height:"189"})}),"\n",(0,i.jsx)(n.p,{children:"This drop-down menu includes the following options:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Launch through EC2 - This option launches your configuration through the ",(0,i.jsx)(n.a,{href:"https://console.aws.amazon.com/ec2/",children:"Amazon EC2 Console"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Launch from Website - This option will launch directly from the current page, using further configuration options outlined below."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy to Service Catalog - Copy your configuration of the software to the ",(0,i.jsx)(n.code,{children:"Service Catalog"})," console, where you can manage your company's cloud resources."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional drop-down menus include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.'}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-key-pair-settings",children:"EC2 Key Pair Settings"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 11",src:t(73613).A+"",width:"830",height:"245"})}),"\n",(0,i.jsx)(n.p,{children:'You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 12",src:t(17316).A+"",width:"339",height:"43"})}),"\n",(0,i.jsx)(n.h3,{id:"launching-your-node",children:"Launching Your Node"}),"\n",(0,i.jsxs)(n.p,{children:["If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange ",(0,i.jsx)(n.code,{children:"Launch"})," button to launch your AWS-hosted Casper node."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 13",src:t(91331).A+"",width:"137",height:"58"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},1106:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS01-26219ce99c140282c6ad9137863a954a.png"},91817:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAA8CAIAAADt6EhQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAiFSURBVHhe7ZyJchpJEobpbu7TgCWhA+uwxp6dHUfMW+y8086DzT7IHjFrW7JBB4izgeZs2K+ohmCEhCXNWIus/IKQu6u7qrKq8s/KQgobTrfrE4Rnj+n9KwjPG1GCIChECYKgECUIgkKUIAgKUYIgKEQJgqAQJQiCYtVv1k6KRe9KEL4JDvf2vKslZE8QBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEASFKEEQFKIEQVCIEgRBIUoQBIUo4VtgMplUGo0PxeJZ+Wrkul6pcB/W8a+y7U7nslLtDwZc+/3+7ZfZF4mEfvRgmu3254vLTCq5u7npFa0BeO1lpdJsd8bjsWGa8Ugkn9uyzHuHp4tKpVyrR0KhgN+fTiYKpXIiGjnY2fEef2UKpVKj1T7YziViMa9oXXlKf5VdLJVPzs7HrovXbqTT4VBwPJ54z+7DcDT698lpuVbTt6FAMBGLxiIRffung8z++7ng3dyNbr//2+mnWtOOhMOMNJ2IG4YxGY+9x/fB6fWCgcDh7g4fxpiIRr+qU2L5Pz98bLRa+jYWjiRjsVAopG+fKOulBLvdqdv2i0T87eEBwTv3Mnu4s4Mk9FN3PCa08+FCl8whPWB5arY9GI10CVEWOelrQFHEyGt7S384xBF7vb53vxKkVbdbLcehYa9ogaHr9TtnhbWAwedXlfFkcpTfO9rdYaSMd387xx6on+rh8JNrXWXOstmLwYJt4WBnO5tK6Vuqtx2n2encaMZtMFh64YLBdnu9SqOJ2OaWMMmLVrFAWB6cWg484mUs1C0swqNry7Q+rFd2VCyX602bwBaPRr2iGeTBF1eViU8tAKuwlc3kslmuicQsmzHNNPTi7G5suGMXP5veKTLJ5EYm/aFQ2Mxk+BC/bcchCRmxomp1fITknY2XlHd6veP8Hs5Em+8LxVg4/Go7xxtn5TJLSwIzmYwt08LCaDisG2dpaXnken4WCgZpAQHcaO0ccr/3nwvRaASpe0Uzhq57en7uOF3TslzXJec53NvFz240m1xosfc5DBnLcbiT4hkWWpZFIbNE8Kb8tpGq8m6Xl3Fl9pbNTJoS1ZxhaEuO9nYZF66sCqcwb/xk732dz/MCfZ2eXwyGQ9M0URGNoHOub1ym7AtPro/Gk8mOmCzTMFge734G81uqVpHHu+NjPiz/Va3enmkY78xv5959d/wmn2fSWUvc/e3Bvt8yWaef3r5hjfWbc9guCMNU+eHoKBQMUMV7cBOcW8gEdjY33h2/fru/z3JWGw3vmc/H8v94fMyS86GvvxwesNgrrNUwUjaE5ZFCqVLt9QeHu7t0992rPMI4L5f1o2Wz572jwL++PsIAPXD9PhXp6PhVnqbwe7IvXb4CxBOPRhgFGwtZ1g+vj+iO6ntbm/g3PTKZPEKQ/KQ7ptqrOQ35BCB+MktUeZXbcnrd0ixBXV4mXb4mrJcS3JFrMsdLR0bcyHXH5DasJRDwVKHj6KemaYUCAS4sv3XH46ZpGuFgkAtqEON14W2QEdFp0B9AkLiv5ff3Btf3/UVWW6shihMa6d27n0EOg4uEAwFONdxOBRamXxya23uZTVP9wRCFcBDndjo3X54cyzTSySS1UCnvU4eu2cH0rrIapNJjMwmHyUW5TcXj4WCo3XHU/vWgZXpM1ssgjn24iF71RdQ5UjmVd8uqcD1Y6Y5/ImNlkvvp8pJ8hs9gMAivPB3exVoiumn4+n31/dgi6niD36jqXn3LMMlMHvDdqNfUH4D94T+nn/718eS3T58Ll6UvtkV3pG1zyxES16Px+AHGPz7rpYRIJMzykY149zOIf8zufFnxDK4JW979V8bvtwKW9YYcgzxh+slvrfoq9i7WovmAP+DMgv0cgqWKl7jUrL7LycRSYVTf3h2qENU5Mj3YEUuVCsZ/f7DPkEl1ZtK+FbXpmNbc8qkSJ9jwAOMfn/VSQjqRYPcvV2sXV1f94VCnCuQViXiM2SQ7V+etyaTatImay6fqRQy1HAbpAe+zJLpwNcQy2idHp0rbIcPxfDQeibKk5XpDrzGt6d91LIKXUBe35p14LPpFa3GaTCpFOvGxeGa3OzgcbTZbbToiL+oO+nVbfUdJYtZx1GHgxhPFaojHyXh8MBwVS2XaIYOfq+62kV5jLmZe6/5u+1KiwHjKQRcB8o6GQ61ut9VRqWC91eoNBszGfJdYZ6y///KLd7lEY+ErgseBkJJKJEiLa7ZdqTfKtRoOwRZL5oorUHhZrZaqNfKTXDZDIVVqTRvvyaSS+BY+yjtBvz+ViBNHaYeTLlVG7igaidRtW59rm+12fzjAEbV70QI/1deOhtFstarNZrlWn/q6wdLSFEkzS1mp12kKky6rNbb9a1/Y4w4Nu0XFRqv9MpWiyo3WLsIBwG/52QB1j5VGo9N1yK35OP3BFd1VqthMJsZBk9HdavbvJwEXpxYGYDldkLI0Oh3qMi1EFj2i20Z6rQuGyXCupgvB3NJFMhbDHjZJzkJ0yujokTcJWLoW89zqdKazVEUPzNLe5gZKuG2ZqPuYLK/CnDX9n7+INIQT4jpJBfKYFxKHmFD2ja8UZlgkEnpyEe0Ki9xo0grubi2hGvelTX2g1OC1VGdvWbbkYdDL+0Jh+mts9U3aipEuol8LBAPa4++IHhHquletR2DFt6jyf+B9y5BYjtwxOwMyu6hU6k07n9v643+68nQRJTxTOHgUy6XhSJ2Y2V42s5nNdFo/ep6IEgRB8ZT+Ak8Q/i+IEgRBIUoQBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEATFqr87+sevv3pXgvBN8Leff/aulpA9QRAUq/YEQXg+yJ4gCApRgiAoRAmCoBAlCIJClCAIClGCIChECYKgECUIgs/n8/0Ps5JgKFFEE0IAAAAASUVORK5CYII="},36992:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQoAAABECAIAAAD2jOw2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAoZSURBVHhe7Zx3cFTXFca3F+2uCuqsGkKWEDIWEiOaKDYgAsKywLaCnTY2EOwkkzaMJ4ntTDITx+SP2CmT8XhsQ4zHYwwulNASQEh0iSK6wepCfbXqW7Q1n/ZdrRl2r7RgjBc4v3mzere8984t37nnvlmt2GyxiAiC8IeE/SUIwgeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBJexv7Gr3q1mZwRxX2BZFui31Gn1IAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJI/7B7dbdNoQ/peq9J2NcUNOGtk7QPB2Yn2/5qUTD+dvm4dj1aHcL/u0rOBrUN2rnfrJgh318SwdHGAqf1KrL943Ey1dvCv/vS9SbK7bGZf/Nccs3zezw6Js6Nc0DITM2jb/7SsTWNk3z8c1CdM/f7RxIISl7wukr7z6KjvlIK/+Mzu7i3xap1+5Py9WPbQms/E7SZ0ysTtZa4lRD7HigDE7pKvLciNVtmTd8Ff8JRK3WuaaGds9TmUXKtxZ3r+WhIm+MMHA0gHQZVWsLs/dUpNQMrFlZVrL1Mg+aCNrXL9M4mY1AgadppU7/jb74px4Y4jMKRG7Z8T0xIfccqcFCCx/9kBeTmRflNqGpFgkwgBNj+lRSF1ChaDFkT7GnPcSjKtHXb/mtTMZf8r74v3HzhRPaFuoN/x8Sh1mjFCK2YMKOHxdLKKL7iHFxe7QQbtMyLE5JV1WpXAOIhT2FyfXp4WZWNrDgF2GS3AhS48K9HatV9s8qHa4MB9upt2sYmcjjGItgMEbryYbLMqDRUd/OaUWLUV7n8toUnlmmLc5+MT5TfiaPWBjrQaQxwuTG3Ki+oSkyy1uNqmxpPg1gwcai6fgBI01WBVnu8I7zErcSihFJ3v7GWCAfpzZAH0KSVRDZVgo3OFGfIcpaAnG/xb8vG78+qr07UtO6jVWljUCYus1ZblOzwj1Dsk3LTizQD/sql+pmFw3oHG6xDX9GnS6yy36dHFlv1226D9zPNcN8878qseT2xF+vD7j8rx4Izz9R9WJSTrz6c4I3BBRwZaCyqVJHcgvbYl+e945zDDMjxcPT8UjMGUxqHDPv6nIilLZLA5pis684dGz3gUNrhR3ruyMEJLPpDXjDld6dH6t9YLM7x3MW5rYDv2zrBHwiNer0hFoJWvNiDOXp7a+MesSJp9fs/Niem58uhc0GZajQ9adeHh73fgJoSaxWKSUup7LaEQ+r6XI39MYh8r/upT6qym1yCnZPx1rES6s69OsSG19c/bFrbX6teU57DEi0YGio/h8uSILo4b+MVoVCIz3N8fEa6y1fZpfZ9f8duqXWA/9DtPUEQ3fNe7t/xZsMami1TaNzMnSI8Dl/OFU5qpJjedLSi+UHHxtxpXfV2a2mpjD7rfJ/p5/4ezTh04+WT4xzHzOGAYNtP5o7/SYHgyebe0ODLNQ00uLWbUuu+ZcSenppw5hQh9ti2QF/qgf0Pzj4sStBZWVT5YdXX5YKXVi+FmZSIQ5gcyXsqtx4FkfLDhjdUpHsVbA5JAaLApfLwD2NMUeaI45uaIczTn33VJMsg+rE4UiX7O9T0eyd9UuGCA0XKiPC6/16qpKSnGr3YUnwhRjB5YVhog5ccaWH+57edo16OTUU4fQsSdWlO9edvxUZ0TTQAg680JJaV50Dz7xOHQ1u9KzOGy4mtxnk11YeRB9dWT5YYSOB1uihVLfYRLyg5NglIdxSBmhtMl9QtiaPk3DYMiihE54MnjBRfpOhApXe3VCKTYY4crhgVdJnbFqPxPOF8Ra0aph9w+/KJyMwrmuMEysaJUNC4XdJU7SWq50s0f7ZXRrBcx2GWIPwewbQU1oY358V5LWjGR8iLU4pe1IWyTkhOQtmY1bne8Ky481jveIEJ0TiDwSNZZZcd0wDE4KXl8ucWN5wVqnkTtxB1aJQ59NXtYaXZjcATuRTA8bRCccaokW4sPbGKZvkWCUR4rOhGDd5BOYWp2SIYfEazEmB46mwbsU+yFUQzzzzIG84r0zcVR0RDwSybZDfgnE2giVDY6/3udtD2J9KEHq0ZWATuFAHIWIi6UDRrgVS9wWiIJ+eiQ7c8uiZXtmoeEdlq/2cn5xuMVYImC8kIS6QqTOVrPK4vxaZnwrBKM8JkcMYO97qTuUpUcIlTtCFQ7vmjKE+eeUwIuz9DcMthnTYnr3Fh4/tuKwcKxMa2Zl/gjEWlSYMq6/vDUKvplleVBIXPCy2Fp4d+TYdifrzGqfgHNM1FLn+BCrwarE01nWLbKjIR4x4fmnS9HknUtOxo71/hBeAMuCsOMC0KfZKYUNsETIuYcIRnlkR/Y9kdL2syPZiL8ReyA8aDOrsCFJCzOlhZq21iZgpF1u8Z6mOHimSeED7DJ/SMTD3qvFpMY88/uuyRcEEgiBuq3DL4uuD6qxjgn5k8IHO8zK/16PFV7d4G4INoQiL3Kpu8OqxFxHnYmhY1sLGWCXjP3x7yqysDigpbhnbb8Gc2tJYsfuprhLPcM+As7is3r93Hij735sTLD+FCa3l7ZEYcON5mBLfbx9nFDEa+lNIJIUTtCKZpMKeyohifXB5JAZPJcLfSKgkzsKEg2bqxNgNpKXe0L3NsU+pjd4V8J7iGCUB9zPX2dden5S4/Ol0yL/vUz7XlHG5oJj7ZFauQMb3MOtkboNRap3n3jzfBqqCSE1jwiF7dm06y+U5yjfLd5Sm8ByRyU/zojxTv1ocdjGorcup+o1zN+nhpr+OefCH09Pit+0FKX6D5ZiMyAUeVkxofVYW2T4xsfXlOVg7xSItTNie3YuPYlp+tDmArQ0ZlPhL44+gmm3UG9Yk9mQv22+4p3ijI8XYRP8g4eus2tukblxxrfmnv+sTr+6LNfhksD7CPm8lt7EgvFdPUOKKVsXpm0u2N8cg2VNyE/SmYtS2pbsnq3dUHSig0lOAKbmRPXBbBg/d/u8n2TVozms7J4iqH8GDj6p1zbsoUPldrheIRMjis2fSyQOV9ix6xUy7yxYGfrtcuwdQ3y8tV+TRiFwa7Hm4IBrgPdlWZ6NNeJ4mOFrye2Bfcja8pzCpI7ve8Q2SktvRKgG94TljmUFgNAiBJC3dNVdIPAXu/Qrifc/iEvNdplea4GedzXEra9K/3Dh6YzwQVb84EHyIL4CmxkEbGWtUXaXZE6ccf2My4joWNkDCcmDILjQb+wSxB2A5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMFl7O9cnV2Xxc4I4r4g943L7GwsaPUgCC5jrx4E8cBCqwdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcBCJ/g+JpAip6TfCDgAAAABJRU5ErkJggg=="},71967:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS04-f0a5f08295ac98ac10216dda2c6ac467.png"},91990:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS05-ef5cc7abd1f5093685ce82cb5794a2aa.png"},73613:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS06-fa837b0e61647fe37340261a3ae8fde3.png"},17316:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAArCAIAAABKL/w7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAC3hJREFUeF7tnV9IW1kex2tq/f+n1dbqVOiTT/pSaFkYH+ZhfWj70AWRUp1i7SozVtBm65QGsVhlm+K4EkJrBmmV8aE+uJXCECglOIuEHQTJS9xuW3TdBpnS6A4GsTQEIfs75/xyc++5N7fJNXE0OR++DPeef/d47/ne8zvndsihkEAgyDyE8wWCTEQ4XyDIRITzBYJMRDhfIMhEhPMFgkxEOF8gyESE8wWCTETP+a65+T/f+EvT1x37RNAZ6BJ2TsV+6+2Blv6t3nn1ODxZFB4/JLTfNVkEDwsfmxI958PjX/7Pf8P7BugMdAk7p2K/9fZAo3+rhe0PkiaL8LEp0XM+vPtxIOwboEvYORX7sLcHGp1bzY8tof0tfGxKhPMF2gjnp43wsSkRzhdoI5yfNsLHpkQ4X6CNcH7aCB+bkhQ6f339fzOzPw38dQTauWG+A3o0Pvmvf79huZBooH2d4bjL3go4dG41N7CE9rnwsSlJlfPB81BdU/AugALsmBWOH6iCnVNhoDWBDjq3mhtYQvtc+NiUpMT5bJ4Hgf/ZJA/zPwsBWDrM/+yAlY8fqIKdU2GgteSz5VvyvPbv4NmBRudWcwProCs4kuO25HlHsrj0PZZ/MG/RauISkyJ8bEqS73xmb/C2FNjLAf9LtjfQPlTBzqkw0JoWIc9Ub9et3q6phRCmxE/A/T35o/pevseEg4zOreYGljEFh/OfNpU31p8kaiib6E/JoI9H/u4TFVWnr3cf5tL3VIMlf6w6XVFVusilJ0P42JQk2flgbKgF0rQ9y5ILM+IGqmDnVBhoTYOtn63YN/vCJ0yLjecJlBxw+vE0vLn04737joUPeLo3SBGWWo/GJ7FQ4kB1vLMquIFlQL7esotkoINOXayvPJs84zEb2/r5dB3tC+ePZTubyi2dOUEuPRnCx6Ykyc6HoQa1YNrHcyVsOMqFGXEDVbBzKgy0pmZzfgja6Ru6C/+1ugOYKvEpsLb8em3rI55+eH4b/oq+mdWtwPYnGiJ8CmxvBULyaD+0sfpqwfNqZVMeQpBitBGau/ROdqGd0OY7r8fjXV2PXOVzyGMoTpCFhRIHquOdVcENrIRly7fUgOcrLeZsfqCPmQJ2E03MihwQBYchIM99a1ME5EG7yTeYx6UvXiEvFOt3UjtUY6a3/XnuwezgD5EUmTjnQ7NQNzCGuUHbkUVYCwxHLvFQkRv+gfQzYOdXCqSRh3CQFbify18XqoySNpXpinYi1enl2MEuhI9NSUqc/4/5f+J5stEZjgZ6qyIw9wAMY19Yc/aBc77/eRvTwZAbC+O9zRFHNU95w0sOdoya9ECppUly/GSJ1Qn73X/riJbpGXHjKoAWs4w8uis12DHlJW+Gj54nZkwBxblqgPDq257bUi25NCOvOIHqeGdVcAMrUQV6y8hsf6EgoMqiJqy2dhWaa8HAJ2ZHYOjn2r6sJuWJqhuv5jI/e1tPRRJpentOePzwbIOUAqLVIb7oKYeYAhNry53D0csxyZ3v6z5eV3W67nyhj2RlOy9Er3L2QgEkBi1HoUBFUx7rBqvb0pkttUaVa4My5ypayF9Bda7MRTsTHi0wk7deRLVlLhtNHym8DqcNhX6pekPx7NWT5FotubKWjQgfm5IkO5/NPxDz43my0RmOBnrLE3h5DwxDDL/y7BY4Z2guMhn7X5IooLnv8dyyb/vX1+4378OBFc/zB5DYdMsx51nw0Hlb4fxfZ25CbtvQs+UN//JMXxtk3X2xTnJYsZuT7tX1wJrbfo0UewyVNl0k4rjn8kHgsL2+svoh3q0GaetUrliRV5xAC3hnVXADK1F5rxInN37DuYWIGamittLcVOJoLXaPZrkvQ+EKx4ApPG5yX6mK+rm/wDtMp9/R/AHwUk2pdzzLP1BgrSeOMndALJDjh5nZWtQCTr5U4IfZdbgI3FWnMpLk/GB/KVmDnCtdpNOsr7MC3imWHvpG6CSvJLqIyHGcgUscc5Np3+S6BMfYJZmodatOTAweDtizXZcrof26y/RlYYfg5YifTO8mbwe0f7qTtq/h/Krq+q/KrK0l1p4jysYTFj42Jb+b89noxJO40RmOBlrjYPZmQf7a8144vjfPrL/xYgh62zO1TM8k2LQvW+fLnc9sfG36Nc0JL02RrD7XBjmWvyDWaXzxtQPOQot2iAKazQ+mf1nZTPADARfz7ybOZ0AjeGdVcAMrUS22EHNqrqvl0y9Vjg1c/YejsxAbW/KcV05CbnQNj5F2Np3q2d4YTvtSGX/PcTg1t5PqbkuxOequqPCiV0o7yRvk+CwGBYed56Gp8gl6aXdHudQx9kYgl7DnW6BBjeCFWTeyXTdMXU3eTViALSiCllKpTS3nJ223Dx+bkiQ7n+02fTbIhOUAFDOw/6QzHA30VonvpzvEM81ddG+/6wYcR1z9/sUAZOGMHUXX+ew9IkXs8tNYzodwf/Wl/WY7yW1qvzv9Jt6lPsDF/LuJ8xnQCN5ZFdzASlS+b4iBK65oBLEq5zMPyFXlGCRZvt5jjfKwOZbzWRAh16V8zqisTF0NiUTq2cxMxK0diCy99AMEiyNacoN3jkUTFVJa9yF9QbDThzkTDfJ1Sro4n4Wdn7V0nMXU6AxHA71VwILz9h5ie6pr0ficzfkRr0roOn/bTdYCzXT9D7AsFlDEdj5lJ+T3OEhnhpybmBQXUsy/yzifAe3gnVXBDayExb5gRWfXqLTn/DMl0myJGssbgBbqi9+SHTJm0RjOZ3O+We+TIV60K3f2PJi/urObLUNwzneydbhCJucF0itHS3VFzVEa9nNSWtda1Eh6W+SLvPXwZdGfRnO+/lc9BmR9tkwsoBZ2TgVkYSFDsPC+6/kKnkf8edPpg+NN9wOyG9c9ND2/4PG8fOYmieG1mS5IbLM8mV+YWyIpCksHfrbCu4PmeuYf3ybHD9jngljO3/Q8f/HLwtK7jbWlH0ligs4HIMhn/0Ry90AP8c6q4AZW4oLlMd20q/mik6znSxxN5Y1tOZClcv4hbxsskqsbG4tcNOp2dRcu2iNh9pmj7lGTf7DQQhbezCdZ7ibi/It/KnJ9l+eFkuw7Qu0Jh5kF/AVPe/n9hehFH+bazkH1Sls/2WMP9JbVVZ0+21DiZAG/uchlxSq4zyet3nkx61aa2wvgiravyB/LdgG9bVXkWp1HYJHibiHr/DRxPsAieRiCmsaWbG9sXtIZjsZ6i+ysTJMtPcVKPrRgJ129M7NGzj6+/Xt0K/7atJcWCUgb/mS3n7M0TPtvnt5moTtIFr3HdP48fb9g+aEXe/vvAjigD3hnVXADy5BMi63H66PhenV9DOeHx7NdjXSLm6m23DUKiVneVkys+/KYJTrnHwrfL7qOO+rHnaTkoeBgcSQFhBeSS3FRGslH4pEsb/uJ6HeBmi8cA5FaY3lW0nlceqjErFtxHQN7eHPl048F4PAC+tkCdOp6YxnEAunjfJj22bc9ENib+R8S4UAKRw3PS1AXO6cCsrBQ6tgJ8Z/rgZ0Qn6IgFNqKfL2PB3qJBMqnDJ1bzQ2s3Qj3urQ+sytEv/Pzn83Jp3X+QzpqTOsDezwXUkv7i/2RiXqtZQhKZl3oJL8coA1qrBFSJXxsSpLvfAB8Lplcrd2sQqE6dk4FZGEhQTLQudXcwMowZbtaS6wXyIc61Wd8SUmetHcpfGxKUuJ8Bpv82W4/W3+C5yERsw0hnL9nCOfHEN10lAfwGsqZIP8/QnGMiGCvhY9NSQqdnwqE8/cM4fy0ET42JcL5Am2E89NG+NiUCOcLtBHOTxvhY1MinC/QRjg/bYSPTYme88UvbWQs4pc20kcGfmlD/LpWxkr/Votf1zowMvbrWgKBIF0RzhcIMhHhfIEgExHOFwgyEeF8gSATEc4XCDIR4XyB4Pdh/bff8GjvCYX+DxMofqYM+5EQAAAAAElFTkSuQmCC"},91331:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAA6CAIAAAALGO1FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMmSURBVHhe7ZxRSFNRGMev1+6cF2pr2NRYoRU+pEhgWSTGQERTxpAg7cGgp7AeevTRx/BpTyFEMLUgsdIksk3FXpIEg8okJSqFzBRUrgruzMtm5+4ehYZL9qD8h9+Py/adb2eXc/ntfDuHXZa2ubkpEZDI4pnAg9zgQm5wITe4kBtcyA0u5AaXBPubF2kiIPaBaztvMWne4EJucCE3uJAbXMgNLuQGF3KDC7nBhdzgQm5wITe4kBtcyA0uB9eNtpT9dk5looUIjhtHW1dl87cM0dp7piYvVY1la6KFCI4bWVtVpzfSRYtIjZqmK5rmGF1StYhI7I6uzCw4ZnTREkRljSkai79kFlanFmxJnHy/QHfz6b3H8qSiPlDS0l/hbK/0zRkDnp8ot/Tlz5s9JLWrz3t9QuWRkX9e4huqLO5y3x4oK/B7WqYVsxObLfR2eJxPK+qf1VreZZlJKZTt660p7Sm7F7jibHf7l0UaBHQ350pfb9wKBBsGg42BvpNq80+HeCERy9bci4Pjjbz/QLdLvv/bZiRDrubgKdv5YeNUja82Li/GunLW6672j9/gnUdaD9nezBmCcYCvaelR/sCYwqL60Uwz9X/W8g6bQTjniBlI2qyrLfLrTuGaaG9fdOZanjUWyCzXHguQQHdj1CK/p7TX7e2uvvlVJJOFhXlli+J/DuMAH2+WL3gmrzxglJ2GQOdZkU0Wu7ouSUoobmkAD5gbviQzllLmERvb9vIpos6sitAY9aJjMmyEbNXxcbdNijV3oSn9uP+LTTMKpMT01JhBWKN8OeZ2dtZsHUWj0mLdhZWe4erixzUF3UV/1BWzW07+dJPsqurwWh566j9Yc46Z6cRkzrbWfmef3c5H/C3e4qETW2s8aFLh3kE+maIRe0bsM78N36zwjaqi25PZrfIvHibrdrGuhiGF7x3kAuLEcOSo3ZqcGI41A09MYlKj8h5MyA0u5AYXcoMLucGF3OBCbnAhN7iQG1zIDS7kBhdygwu5wWXn3whG7p4WEbH3lD34IaJ/oXmDC/3vIC40b3AhN7iQG1zIDS7kBhdygwu5QUWS/gKbZ/EkaoCEzgAAAABJRU5ErkJggg=="},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7bf3b0fc.dec4d3c2.js b/assets/js/7bf3b0fc.dec4d3c2.js new file mode 100644 index 000000000..3975a2b0f --- /dev/null +++ b/assets/js/7bf3b0fc.dec4d3c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94338],{72241:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var s=n(74848),a=n(28453);const c={title:"Addressable Entities"},i="Addressable Entities",r={id:"concepts/addressable-entity",title:"Addressable Entities",description:"What is an Addressable Entity?",source:"@site/versioned_docs/version-2.0.0/concepts/addressable-entity.md",sourceDirName:"concepts",slug:"/concepts/addressable-entity",permalink:"/2.0.0/concepts/addressable-entity",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Addressable Entities"},sidebar:"concepts",previous:{title:"dApps",permalink:"/2.0.0/concepts/intro-to-dapps"},next:{title:"Accounts and Keys",permalink:"/2.0.0/concepts/accounts-and-keys"}},d={},o=[{value:"What is an Addressable Entity?",id:"what-is-an-addressable-entity",level:2},{value:"Account",id:"account",level:2},{value:"SmartContract",id:"smartcontract",level:2},{value:"System",id:"system",level:2},{value:"Further Reading",id:"further-reading",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"addressable-entities",children:"Addressable Entities"})}),"\n",(0,s.jsx)(t.h2,{id:"what-is-an-addressable-entity",children:"What is an Addressable Entity?"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system.\nCasper 2.0 introduces the concept of an ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/A#addressable-entity",children:(0,s.jsx)(t.code,{children:"AddressableEntity"})})," which replaces the existing ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/A#account",children:(0,s.jsx)(t.code,{children:"Account"})})," and ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/S#smart-contract",children:(0,s.jsx)(t.code,{children:"Contract"})})," types."]}),"\n",(0,s.jsxs)(t.p,{children:["The merger of the ",(0,s.jsx)(t.code,{children:"Account"})," and ",(0,s.jsx)(t.code,{children:"Contract"})," concepts allows for some new possibilities."]}),"\n",(0,s.jsxs)(t.p,{children:["For any given ",(0,s.jsx)(t.code,{children:"AddressableEntity"}),", the ",(0,s.jsx)(t.code,{children:"EntityType"})," will identify if it is an ",(0,s.jsx)(t.code,{children:"Account"}),", a user-deployed ",(0,s.jsx)(t.code,{children:"SmartContract"}),", or a ",(0,s.jsx)(t.code,{children:"System"})," contract such as ",(0,s.jsx)(t.code,{children:"Mint"})," or ",(0,s.jsx)(t.code,{children:"HandlePayment"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.code,{children:"EntityType"})," will dictate what the addressable entity can and cannot do."]}),"\n",(0,s.jsx)(t.h2,{id:"account",children:"Account"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as an ",(0,s.jsx)(t.code,{children:"Account"})," will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a ",(0,s.jsx)(t.code,{children:"PublicKey"})," and a secret key, and an ",(0,s.jsx)(t.code,{children:"AccountHash"})," derived from the public key. There is also an associated main purse."]}),"\n",(0,s.jsx)(t.p,{children:"A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same."}),"\n",(0,s.jsx)(t.h2,{id:"smartcontract",children:"SmartContract"}),"\n",(0,s.jsxs)(t.p,{children:["An addressable entity marked as a ",(0,s.jsx)(t.code,{children:"SmartContract"})," will have the same functionality as a legacy contract, but with several new features. The ",(0,s.jsx)(t.code,{children:"SmartContract"})," now possesses a main purse, and may have ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys"})," and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found ",(0,s.jsx)(t.a,{href:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"system",children:"System"}),"\n",(0,s.jsxs)(t.p,{children:["As part of the migration to Casper 2.0, system contracts (",(0,s.jsx)(t.code,{children:"Mint"}),", ",(0,s.jsx)(t.code,{children:"Auction"})," and ",(0,s.jsx)(t.code,{children:"HandlePayment"}),") will migrate to a special type of addressable entity with the ",(0,s.jsx)(t.code,{children:"EntityType"})," of ",(0,s.jsx)(t.code,{children:"System"}),". The ",(0,s.jsx)(t.code,{children:"StandardPayment"})," system contract will be pruned away."]}),"\n",(0,s.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"Accounts and Keys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/key-types",children:"Hash Types"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/resources/advanced/multi-sig/",children:"Multi-Signature Management"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var s=n(96540);const a={},c=s.createContext(a);function i(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7c67ea25.976f293e.js b/assets/js/7c67ea25.976f293e.js new file mode 100644 index 000000000..06a9d7ee9 --- /dev/null +++ b/assets/js/7c67ea25.976f293e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97937],{62301:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=a(74848),s=a(28453);const c={title:"Installing Contracts"},r="Installing Smart Contracts",o={id:"developers/cli/installing-contracts",title:"Installing Contracts",description:"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.",source:"@site/versioned_docs/version-1.5.X/developers/cli/installing-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/installing-contracts",permalink:"/1.5.X/developers/cli/installing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installing Contracts"},sidebar:"developers",previous:{title:"Sending Deploys",permalink:"/1.5.X/developers/cli/sending-deploys"},next:{title:"Querying Global State",permalink:"/1.5.X/developers/cli/querying-global-state"}},l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Contract in Global State",id:"installing-contract-code",level:2},{value:"Querying Global State",id:"querying-global-state",level:2},{value:"Get the state root hash",id:"get-state-root-hash",level:3},{value:"Query global state",id:"query-global-state",level:3},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-smart-contracts",children:"Installing Smart Contracts"})}),"\n",(0,t.jsxs)(n.p,{children:["This document details the process of installing ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Casper smart contracts"})," using the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You have a compiled contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) to send to a Casper network"]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper CLI client"})," to interact with the network"]}),"\n",(0,t.jsxs)(n.li,{children:["You have a ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"Casper Account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:["You have enough CSPR tokens in your account's main purse to pay for deploys. If you plan to use the Casper Testnet, learn about the ",(0,t.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"faucet"})," to fund your testing account's main purse"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-contract-code",children:"Installing a Contract in Global State"}),"\n",(0,t.jsxs)(n.p,{children:["To install a contract in ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"}),", you need to send a deploy to the network with the contract Wasm. You can do so by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/[CONTRACT_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name to the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Once you call this command, it will return a deploy hash. You can use this hash to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys#sending-the-deploy",children:"verify"})," successful execution of the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Install the contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here we send a ",(0,t.jsx)(n.code,{children:"counter-v1.wasm"})," to a local NCTL network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 5000000000000 \\\n --session-path ./counter/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each contract and network ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the deploy, call ",(0,t.jsx)(n.code,{children:"get-deploy"})," and provide the deploy hash you received from ",(0,t.jsx)(n.code,{children:"put-deploy"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Contract Installation Walkthrough"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates the commands described above for installing a contract on-chain."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=8",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,t.jsx)(n.p,{children:"Here we look at how to query global state to see details about a successfully installed contract."}),"\n",(0,t.jsx)(n.h3,{id:"get-state-root-hash",children:"Get the state root hash"}),"\n",(0,t.jsx)(n.p,{children:"The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,t.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,t.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,t.jsx)(n.h3,{id:"query-global-state",children:"Query global state"}),"\n",(0,t.jsxs)(n.p,{children:["Next, query the state of a Casper network at a given time, specified by the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," described above. You can dive into the data stored in global state using the optional query path argument ",(0,t.jsx)(n.code,{children:"-q"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [HASH_STRING] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"q"})," - An optional query path argument that allows you to drill into the specifics of a query with respect to the key"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query the account:"})}),"\n",(0,t.jsx)(n.p,{children:"To find your account details, query global state using your account hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d\n"})}),"\n",(0,t.jsx)(n.p,{children:'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.'}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample account state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6831525034388467034,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[27614 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "weight": 1\n }\n ],\n "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",\n "named_keys": [\n {\n "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "name": "counter"\n },\n {\n "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "name": "counter_access_uref"\n },\n {\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n },\n {\n "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",\n "name": "version"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"If you don't know your account hash, you can run this command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query the contract:"})}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to query global state given a contract hash. We use the contract hash from the sample response above."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the sample contract would look and would contain details such as the ",(0,t.jsx)(n.code,{children:"contract_package_hash"}),", the contract ",(0,t.jsx)(n.code,{children:"entry_points"}),", and the ",(0,t.jsx)(n.code,{children:"named_keys"})," for the contract."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -4657473054587773855,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[21330 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.5"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query a value using its key and the contract hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,t.jsx)(n.code,{children:"-q"})," option. This example comes from the ",(0,t.jsx)(n.a,{href:"/1.5.X/counter",children:"Counter Contract Tutorial"}),', where a "count" variable is incremented and stored under a named key.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [CONTRACT_HASH] \\\n -q "count"\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample stored value"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -2540117660598287261,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[56562 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query a value using the account hash and named keys:"})}),"\n",(0,t.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \\\n -q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The response should be the same as in Example 3, above."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query contract package state:"})}),"\n",(0,t.jsx)(n.p,{children:"You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the contract package details would look. The response would contain the ",(0,t.jsx)(n.code,{children:"contract_hash"}),", which you would need to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts#calling-contracts-by-hash",children:"call a contract by hash"})," in the next section. You would also see the ",(0,t.jsx)(n.code,{children:"access_key"})," for the ",(0,t.jsx)(n.code,{children:"ContractPackage"})," and the current ",(0,t.jsx)(n.code,{children:"contract_version"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract package state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6225901853092301031,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[20964 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Querying Walkthrough"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows you what to expect when querying the network."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=9",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>o});var t=a(96540);const s={},c=t.createContext(s);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7c67ea25.dbf66f2d.js b/assets/js/7c67ea25.dbf66f2d.js deleted file mode 100644 index 03e20f750..000000000 --- a/assets/js/7c67ea25.dbf66f2d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7937],{62301:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=a(74848),s=a(28453);const c={title:"Installing Contracts"},r="Installing Smart Contracts",o={id:"developers/cli/installing-contracts",title:"Installing Contracts",description:"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.",source:"@site/versioned_docs/version-1.5.X/developers/cli/installing-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/installing-contracts",permalink:"/developers/cli/installing-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installing Contracts"},sidebar:"developers",previous:{title:"Sending Deploys",permalink:"/developers/cli/sending-deploys"},next:{title:"Querying Global State",permalink:"/developers/cli/querying-global-state"}},l={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Contract in Global State",id:"installing-contract-code",level:2},{value:"Querying Global State",id:"querying-global-state",level:2},{value:"Get the state root hash",id:"get-state-root-hash",level:3},{value:"Query global state",id:"query-global-state",level:3},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-smart-contracts",children:"Installing Smart Contracts"})}),"\n",(0,t.jsxs)(n.p,{children:["This document details the process of installing ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Casper smart contracts"})," using the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You have a compiled contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) to send to a Casper network"]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper CLI client"})," to interact with the network"]}),"\n",(0,t.jsxs)(n.li,{children:["You have a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Casper Account"})," with a public and secret key pair to initiate the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:["You have enough CSPR tokens in your account's main purse to pay for deploys. If you plan to use the Casper Testnet, learn about the ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"faucet"})," to fund your testing account's main purse"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-contract-code",children:"Installing a Contract in Global State"}),"\n",(0,t.jsxs)(n.p,{children:["To install a contract in ",(0,t.jsx)(n.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),", you need to send a deploy to the network with the contract Wasm. You can do so by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/[CONTRACT_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name to the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Once you call this command, it will return a deploy hash. You can use this hash to ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-deploys#sending-the-deploy",children:"verify"})," successful execution of the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Install the contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here we send a ",(0,t.jsx)(n.code,{children:"counter-v1.wasm"})," to a local NCTL network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://localhost:11101 \\\n --chain-name casper-net-1 \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 5000000000000 \\\n --session-path ./counter/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each contract and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the deploy, call ",(0,t.jsx)(n.code,{children:"get-deploy"})," and provide the deploy hash you received from ",(0,t.jsx)(n.code,{children:"put-deploy"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://localhost:11101 [DEPLOY_HASH]\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Contract Installation Walkthrough"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates the commands described above for installing a contract on-chain."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=8",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,t.jsx)(n.p,{children:"Here we look at how to query global state to see details about a successfully installed contract."}),"\n",(0,t.jsx)(n.h3,{id:"get-state-root-hash",children:"Get the state root hash"}),"\n",(0,t.jsx)(n.p,{children:"The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,t.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,t.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,t.jsx)(n.h3,{id:"query-global-state",children:"Query global state"}),"\n",(0,t.jsxs)(n.p,{children:["Next, query the state of a Casper network at a given time, specified by the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," described above. You can dive into the data stored in global state using the optional query path argument ",(0,t.jsx)(n.code,{children:"-q"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [HASH_STRING] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"q"})," - An optional query path argument that allows you to drill into the specifics of a query with respect to the key"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query the account:"})}),"\n",(0,t.jsx)(n.p,{children:"To find your account details, query global state using your account hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d\n"})}),"\n",(0,t.jsx)(n.p,{children:'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.'}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample account state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6831525034388467034,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[27614 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",\n "weight": 1\n }\n ],\n "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",\n "named_keys": [\n {\n "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "name": "counter"\n },\n {\n "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "name": "counter_access_uref"\n },\n {\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n },\n {\n "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",\n "name": "version"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.p,{children:"If you don't know your account hash, you can run this command:"}),(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query the contract:"})}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to query global state given a contract hash. We use the contract hash from the sample response above."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the sample contract would look and would contain details such as the ",(0,t.jsx)(n.code,{children:"contract_package_hash"}),", the contract ",(0,t.jsx)(n.code,{children:"entry_points"}),", and the ",(0,t.jsx)(n.code,{children:"named_keys"})," for the contract."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -4657473054587773855,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[21330 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.5"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query a value using its key and the contract hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,t.jsx)(n.code,{children:"-q"})," option. This example comes from the ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"}),', where a "count" variable is incremented and stored under a named key.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [CONTRACT_HASH] \\\n -q "count"\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample stored value"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -2540117660598287261,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[56562 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query a value using the account hash and named keys:"})}),"\n",(0,t.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \\\n --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \\\n -q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:"The response should be the same as in Example 3, above."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Query contract package state:"})}),"\n",(0,t.jsx)(n.p,{children:"You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is how the contract package details would look. The response would contain the ",(0,t.jsx)(n.code,{children:"contract_hash"}),", which you would need to ",(0,t.jsx)(n.a,{href:"/developers/cli/calling-contracts#calling-contracts-by-hash",children:"call a contract by hash"})," in the next section. You would also see the ",(0,t.jsx)(n.code,{children:"access_key"})," for the ",(0,t.jsx)(n.code,{children:"ContractPackage"})," and the current ",(0,t.jsx)(n.code,{children:"contract_version"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample contract package state"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6225901853092301031,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "block_header": null,\n "merkle_proof": "[20964 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Querying Walkthrough"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows you what to expect when querying the network."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=9",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn ",(0,t.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>r,x:()=>o});var t=a(96540);const s={},c=t.createContext(s);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7c798d59.93f88623.js b/assets/js/7c798d59.93f88623.js deleted file mode 100644 index 43398dee6..000000000 --- a/assets/js/7c798d59.93f88623.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1535],{51753:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var t=s(74848),r=s(28453);const a={},i="Transferring Tokens using a Multi-Sig Deploy",d={id:"developers/cli/transfers/multisig-deploy-transfer",title:"Transferring Tokens using a Multi-Sig Deploy",description:"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.",source:"@site/docs/developers/cli/transfers/multisig-deploy-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/multisig-deploy-transfer",permalink:"/next/developers/cli/transfers/multisig-deploy-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"developers",previous:{title:"Direct Token Transfer",permalink:"/next/developers/cli/transfers/direct-token-transfer"},next:{title:"Verifying a Transfer",permalink:"/next/developers/cli/transfers/verify-transfer"}},c={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Token Transfer Workflow",id:"token-transfer-workflow",level:2},{value:"Creating the transfer",id:"creating-the-transfer",level:3},{value:"Signing the transfer",id:"signing-the-transfer",level:3},{value:"Sending the deploy",id:"sending-the-transaction",level:3},{value:"Verifying the transfer",id:"verifying-the-transfer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",mdxadmonitiontitle:"mdxadmonitiontitle",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-using-a-multi-sig-deploy",children:"Transferring Tokens using a Multi-Sig Deploy"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"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 ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command and send it to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"You must ensure the following prerequisites are met."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the prerequisites listed ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites",children:"here"}),", including:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A funded ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"Account"})," on Testnet or Mainnet"]}),"\n",(0,t.jsxs)(n.li,{children:["A valid ",(0,t.jsx)(n.em,{children:"node address"})," from the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet peers"})," or ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet peers"})]}),"\n",(0,t.jsxs)(n.li,{children:["The Casper ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"command-line client"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up the source account for multi-signature deploys, as outlined in the ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the path of the source account's ",(0,t.jsx)(n.em,{children:"secret key"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the target account's ",(0,t.jsx)(n.em,{children:"public key"})," in hex format"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"token-transfer-workflow",children:"Token Transfer Workflow"}),"\n",(0,t.jsx)(n.p,{children:"The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"make-transfer"})," command creates and signs a transfer, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command adds additional signatures for a multi-signature transfer"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"send-deploy"})," command sends the deploy containing the transfer to the network"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Deployment flow",src:s(448).A+"",width:"802",height:"274"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-the-transfer",children:"Creating the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This section explains the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file) to a target account. To use this example on the Mainnet, the ",(0,t.jsx)(n.em,{children:"chain-name"})," would be ",(0,t.jsx)(n.code,{children:"casper"})," instead of ",(0,t.jsx)(n.code,{children:"casper-test"}),". Note that we are saving the output of the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command in a ",(0,t.jsx)(n.code,{children:"transfer.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key [PATH]/secret_key.pem \\\n--chain-name casper-test \\\n--target-account [PUBLIC_KEY_HEX] \\\n--transfer-id [ID] \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following table explains the parameters used in the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"amount"}),(0,t.jsx)(n.td,{children:"The number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file for the source account"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"chain-name"}),(0,t.jsxs)(n.td,{children:["The name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain ",(0,t.jsxs)(n.ul,{children:[(0,t.jsxs)(n.li,{children:["For Testnet use ",(0,t.jsx)(n.strong,{children:"casper-test"})]}),(0,t.jsxs)(n.li,{children:["For Mainnet use ",(0,t.jsx)(n.strong,{children:"casper"})]})]})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"target-account"}),(0,t.jsx)(n.td,{children:"Hex-encoded public key of the target account from which the main purse will be used"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"transfer-id"}),(0,t.jsx)(n.td,{children:"A user-defined identifier permanently associated with the transfer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"payment-amount"}),(0,t.jsxs)(n.td,{children:["The payment for the transfer in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In the output, you will see a section named ",(0,t.jsx)(n.strong,{children:"approvals"}),". This is where a signature from the source account is added to the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \\\n--chain-name casper-test \\\n--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \\\n--transfer-id 1 \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output of the make-transfer command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"signing-the-transfer",children:"Signing the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a ",(0,t.jsx)(n.code,{children:"transfer2.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key [PATH]/another_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which needs to be signed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file used to sign the deploy"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"output"}),(0,t.jsx)(n.td,{children:"The path of the output file used to save the deploy with multiple signatures"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, you can observe that there is an ",(0,t.jsx)(n.strong,{children:"approvals"})," section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output saved in the transfer2.deploy file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n },\n {\n "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",\n "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sending-the-transaction",children:"Sending the deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The next step is to send the deploy for processing on the network. As described in the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})," section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node ",(0,t.jsx)(n.code,{children:"https://rpc.testnet.casperlabs.io/"})," from the Testnet."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy \\\n--input transfer2.deploy \\\n--node-address https://rpc.testnet.casperlabs.io/ \n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which is used as the input"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"node-address"}),(0,t.jsx)(n.td,{children:"The Hostname or IP and port of the node"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Make a note of the ",(0,t.jsx)(n.em,{children:"deploy_hash"})," from the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command output to verify the status of the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Successful output of the send-deploy command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -818883417884028030,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If you encounter an account authorization error, you ",(0,t.jsx)(n.strong,{children:"must set up the source account to allow multi-signature deploys"})," using session code. The ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow is an example of how to accomplish this."]})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example of an account authorization error"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "code": -32008,\n "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"verifying-the-transfer",children:"Verifying the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transfer status, see ",(0,t.jsx)(n.a,{href:"/next/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.mdxadmonitiontitle,{}),(0,t.jsxs)(n.p,{children:["You can also verify if the transfer was successful by checking your account balance using a ",(0,t.jsx)(n.a,{href:"/next/users/block-explorer",children:"block explorer"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},448:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-flow-a20851cf502515fa17e5f53f90bf3982.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7c798d59.a338572d.js b/assets/js/7c798d59.a338572d.js new file mode 100644 index 000000000..d53df97a4 --- /dev/null +++ b/assets/js/7c798d59.a338572d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91535],{51753:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var t=s(74848),r=s(28453);const a={},i="Transferring Tokens using a Multi-Sig Deploy",d={id:"developers/cli/transfers/multisig-deploy-transfer",title:"Transferring Tokens using a Multi-Sig Deploy",description:"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.",source:"@site/docs/developers/cli/transfers/multisig-deploy-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/multisig-deploy-transfer",permalink:"/developers/cli/transfers/multisig-deploy-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"developers",previous:{title:"Direct Token Transfer",permalink:"/developers/cli/transfers/direct-token-transfer"},next:{title:"Verifying a Transfer",permalink:"/developers/cli/transfers/verify-transfer"}},c={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Token Transfer Workflow",id:"token-transfer-workflow",level:2},{value:"Creating the transfer",id:"creating-the-transfer",level:3},{value:"Signing the transfer",id:"signing-the-transfer",level:3},{value:"Sending the deploy",id:"sending-the-transaction",level:3},{value:"Verifying the transfer",id:"verifying-the-transfer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",mdxadmonitiontitle:"mdxadmonitiontitle",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-using-a-multi-sig-deploy",children:"Transferring Tokens using a Multi-Sig Deploy"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"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 ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command and send it to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"You must ensure the following prerequisites are met."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the prerequisites listed ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"here"}),", including:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A funded ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Account"})," on Testnet or Mainnet"]}),"\n",(0,t.jsxs)(n.li,{children:["A valid ",(0,t.jsx)(n.em,{children:"node address"})," from the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet peers"})," or ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet peers"})]}),"\n",(0,t.jsxs)(n.li,{children:["The Casper ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"command-line client"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up the source account for multi-signature deploys, as outlined in the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the path of the source account's ",(0,t.jsx)(n.em,{children:"secret key"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the target account's ",(0,t.jsx)(n.em,{children:"public key"})," in hex format"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"token-transfer-workflow",children:"Token Transfer Workflow"}),"\n",(0,t.jsx)(n.p,{children:"The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"make-transfer"})," command creates and signs a transfer, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command adds additional signatures for a multi-signature transfer"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"send-deploy"})," command sends the deploy containing the transfer to the network"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Deployment flow",src:s(13870).A+"",width:"802",height:"274"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-the-transfer",children:"Creating the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This section explains the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file) to a target account. To use this example on the Mainnet, the ",(0,t.jsx)(n.em,{children:"chain-name"})," would be ",(0,t.jsx)(n.code,{children:"casper"})," instead of ",(0,t.jsx)(n.code,{children:"casper-test"}),". Note that we are saving the output of the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command in a ",(0,t.jsx)(n.code,{children:"transfer.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key [PATH]/secret_key.pem \\\n--chain-name casper-test \\\n--target-account [PUBLIC_KEY_HEX] \\\n--transfer-id [ID] \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following table explains the parameters used in the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"amount"}),(0,t.jsx)(n.td,{children:"The number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file for the source account"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"chain-name"}),(0,t.jsxs)(n.td,{children:["The name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain ",(0,t.jsxs)(n.ul,{children:[(0,t.jsxs)(n.li,{children:["For Testnet use ",(0,t.jsx)(n.strong,{children:"casper-test"})]}),(0,t.jsxs)(n.li,{children:["For Mainnet use ",(0,t.jsx)(n.strong,{children:"casper"})]})]})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"target-account"}),(0,t.jsx)(n.td,{children:"Hex-encoded public key of the target account from which the main purse will be used"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"transfer-id"}),(0,t.jsx)(n.td,{children:"A user-defined identifier permanently associated with the transfer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"payment-amount"}),(0,t.jsxs)(n.td,{children:["The payment for the transfer in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In the output, you will see a section named ",(0,t.jsx)(n.strong,{children:"approvals"}),". This is where a signature from the source account is added to the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \\\n--chain-name casper-test \\\n--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \\\n--transfer-id 1 \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output of the make-transfer command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"signing-the-transfer",children:"Signing the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a ",(0,t.jsx)(n.code,{children:"transfer2.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key [PATH]/another_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which needs to be signed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file used to sign the deploy"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"output"}),(0,t.jsx)(n.td,{children:"The path of the output file used to save the deploy with multiple signatures"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, you can observe that there is an ",(0,t.jsx)(n.strong,{children:"approvals"})," section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output saved in the transfer2.deploy file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n },\n {\n "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",\n "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sending-the-transaction",children:"Sending the deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The next step is to send the deploy for processing on the network. As described in the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})," section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node ",(0,t.jsx)(n.code,{children:"https://rpc.testnet.casperlabs.io/"})," from the Testnet."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy \\\n--input transfer2.deploy \\\n--node-address https://rpc.testnet.casperlabs.io/ \n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which is used as the input"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"node-address"}),(0,t.jsx)(n.td,{children:"The Hostname or IP and port of the node"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Make a note of the ",(0,t.jsx)(n.em,{children:"deploy_hash"})," from the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command output to verify the status of the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Successful output of the send-deploy command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -818883417884028030,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If you encounter an account authorization error, you ",(0,t.jsx)(n.strong,{children:"must set up the source account to allow multi-signature deploys"})," using session code. The ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow is an example of how to accomplish this."]})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example of an account authorization error"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "code": -32008,\n "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"verifying-the-transfer",children:"Verifying the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transfer status, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.mdxadmonitiontitle,{}),(0,t.jsxs)(n.p,{children:["You can also verify if the transfer was successful by checking your account balance using a ",(0,t.jsx)(n.a,{href:"/users/block-explorer",children:"block explorer"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},13870:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-flow-a20851cf502515fa17e5f53f90bf3982.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ce4a62a.76742a6b.js b/assets/js/7ce4a62a.76742a6b.js new file mode 100644 index 000000000..0153bea03 --- /dev/null +++ b/assets/js/7ce4a62a.76742a6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76568],{83277:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const c={},i="Getting Started with AssemblyScript",a={id:"developers/writing-onchain-code/assembly-script",title:"Getting Started with AssemblyScript",description:"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/assembly-script.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/assembly-script",permalink:"/1.5.X/developers/writing-onchain-code/assembly-script",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with Rust",permalink:"/1.5.X/developers/writing-onchain-code/getting-started"},next:{title:"Writing a Basic Smart Contract in Rust",permalink:"/1.5.X/developers/writing-onchain-code/simple-contract"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing AssemblyScript",id:"installing-assemblyscript",level:3},{value:"Development Environment Setup",id:"development-environment-setup",level:2},{value:"Installing the Casper Package",id:"installing-the-casper-package",level:3},{value:"Creating a Project",id:"creating-a-project",level:3},{value:"Script Entries",id:"script-entries",level:3},{value:"Sample Smart Contract",id:"sample-smart-contract",level:3},{value:"Compile to Wasm",id:"compile-to-wasm",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"getting-started-with-assemblyscript",children:"Getting Started with AssemblyScript"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper Labs maintains the ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"casper-contract"})," to allow developers to create smart contracts using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"AssemblyScript"}),". The package source is hosted in the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/smart_contracts/contract_as/assembly",children:"main Casper Network repository"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.h3,{id:"installing-assemblyscript",children:"Installing AssemblyScript"}),"\n",(0,s.jsxs)(n.p,{children:["Installation of AssemblyScript requires ",(0,s.jsx)(n.a,{href:"https://nodejs.org/",children:"Node.js"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After installation of Node.js, the following command will install AssemblyScript:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i assemblyscript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Full instructions and details for installing AssemblyScript can be found ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"development-environment-setup",children:"Development Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-casper-package",children:"Installing the Casper Package"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-contract"})," package can be installed using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i casper-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The AssemblyScript contract API documentation can be found at ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"https://www.npmjs.com/package/casper-contract"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsx)(n.p,{children:"For each smart contract, it is necessary to create a project directory and initialize it."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"npm init"})," process prompts for various details about the project. Answer as you see fit, but you may safely default everything except ",(0,s.jsx)(n.code,{children:"name"}),", which needs to be specified. In this guide, we will refer to the contract name as ",(0,s.jsx)(n.code,{children:"your-contract-name"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir project\ncd project\nnpm init\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then install AssemblyScript and this package in the project directory."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev assemblyscript@0.9.1\nnpm install --save casper-contract\n"})}),"\n",(0,s.jsx)(n.h3,{id:"script-entries",children:"Script Entries"}),"\n",(0,s.jsxs)(n.p,{children:["Add script entries for AssemblyScript to your project's ",(0,s.jsx)(n.code,{children:"package.json"}),". Note that your contract name is used for the name of the Wasm file. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "your-contract-name",\n ...\n "scripts": {\n "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",\n "asbuild": "npm run asbuild:optimized",\n ...\n },\n ...\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the project root, create an ",(0,s.jsx)(n.code,{children:"index.js"})," file with the following contents. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'const fs = require("fs");\n\nconst compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));\n\nconst imports = {\n env: {\n abort(_msg, _file, line, column) {\n console.error("abort called at index.ts:" + line + ":" + column);\n },\n },\n};\n\nObject.defineProperty(module, "exports", {\n get: () => new WebAssembly.Instance(compiled, imports).exports,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a directory called ",(0,s.jsx)(n.code,{children:"assembly"}),", and in that directory, create a file called ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," in the following way:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-smart-contract",children:"Sample Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"assembly"})," directory, also create an ",(0,s.jsx)(n.code,{children:"index.ts"})," file, where the code for the contract needs to go."]}),"\n",(0,s.jsx)(n.p,{children:"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer a more complicated first contract, you can look at example contracts on the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem GitHub"})," repository for inspiration."]}),"\n",(0,s.jsx)(n.h3,{id:"compile-to-wasm",children:"Compile to Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["To compile the contract to Wasm, use ",(0,s.jsx)(n.em,{children:"npm"})," to run the ",(0,s.jsx)(n.em,{children:"asbuild"})," script from the project root:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm run asbuild\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the build is successful, there will be a ",(0,s.jsx)(n.code,{children:"dist"})," folder in the ",(0,s.jsx)(n.code,{children:"root"})," folder and in it should be ",(0,s.jsx)(n.code,{children:"your-contract-name.wasm"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ce4a62a.8943f664.js b/assets/js/7ce4a62a.8943f664.js deleted file mode 100644 index c69c2d0a9..000000000 --- a/assets/js/7ce4a62a.8943f664.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6568],{83277:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const c={},i="Getting Started with AssemblyScript",a={id:"developers/writing-onchain-code/assembly-script",title:"Getting Started with AssemblyScript",description:"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/assembly-script.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/assembly-script",permalink:"/developers/writing-onchain-code/assembly-script",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with Rust",permalink:"/developers/writing-onchain-code/getting-started"},next:{title:"Writing a Basic Smart Contract in Rust",permalink:"/developers/writing-onchain-code/simple-contract"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing AssemblyScript",id:"installing-assemblyscript",level:3},{value:"Development Environment Setup",id:"development-environment-setup",level:2},{value:"Installing the Casper Package",id:"installing-the-casper-package",level:3},{value:"Creating a Project",id:"creating-a-project",level:3},{value:"Script Entries",id:"script-entries",level:3},{value:"Sample Smart Contract",id:"sample-smart-contract",level:3},{value:"Compile to Wasm",id:"compile-to-wasm",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"getting-started-with-assemblyscript",children:"Getting Started with AssemblyScript"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper Labs maintains the ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"casper-contract"})," to allow developers to create smart contracts using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"AssemblyScript"}),". The package source is hosted in the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/smart_contracts/contract_as/assembly",children:"main Casper Network repository"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.h3,{id:"installing-assemblyscript",children:"Installing AssemblyScript"}),"\n",(0,s.jsxs)(n.p,{children:["Installation of AssemblyScript requires ",(0,s.jsx)(n.a,{href:"https://nodejs.org/",children:"Node.js"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After installation of Node.js, the following command will install AssemblyScript:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i assemblyscript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Full instructions and details for installing AssemblyScript can be found ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"development-environment-setup",children:"Development Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-casper-package",children:"Installing the Casper Package"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-contract"})," package can be installed using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i casper-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The AssemblyScript contract API documentation can be found at ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"https://www.npmjs.com/package/casper-contract"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsx)(n.p,{children:"For each smart contract, it is necessary to create a project directory and initialize it."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"npm init"})," process prompts for various details about the project. Answer as you see fit, but you may safely default everything except ",(0,s.jsx)(n.code,{children:"name"}),", which needs to be specified. In this guide, we will refer to the contract name as ",(0,s.jsx)(n.code,{children:"your-contract-name"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir project\ncd project\nnpm init\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then install AssemblyScript and this package in the project directory."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev assemblyscript@0.9.1\nnpm install --save casper-contract\n"})}),"\n",(0,s.jsx)(n.h3,{id:"script-entries",children:"Script Entries"}),"\n",(0,s.jsxs)(n.p,{children:["Add script entries for AssemblyScript to your project's ",(0,s.jsx)(n.code,{children:"package.json"}),". Note that your contract name is used for the name of the Wasm file. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "your-contract-name",\n ...\n "scripts": {\n "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",\n "asbuild": "npm run asbuild:optimized",\n ...\n },\n ...\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the project root, create an ",(0,s.jsx)(n.code,{children:"index.js"})," file with the following contents. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'const fs = require("fs");\n\nconst compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));\n\nconst imports = {\n env: {\n abort(_msg, _file, line, column) {\n console.error("abort called at index.ts:" + line + ":" + column);\n },\n },\n};\n\nObject.defineProperty(module, "exports", {\n get: () => new WebAssembly.Instance(compiled, imports).exports,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a directory called ",(0,s.jsx)(n.code,{children:"assembly"}),", and in that directory, create a file called ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," in the following way:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-smart-contract",children:"Sample Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"assembly"})," directory, also create an ",(0,s.jsx)(n.code,{children:"index.ts"})," file, where the code for the contract needs to go."]}),"\n",(0,s.jsx)(n.p,{children:"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer a more complicated first contract, you can look at example contracts on the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem GitHub"})," repository for inspiration."]}),"\n",(0,s.jsx)(n.h3,{id:"compile-to-wasm",children:"Compile to Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["To compile the contract to Wasm, use ",(0,s.jsx)(n.em,{children:"npm"})," to run the ",(0,s.jsx)(n.em,{children:"asbuild"})," script from the project root:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm run asbuild\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the build is successful, there will be a ",(0,s.jsx)(n.code,{children:"dist"})," folder in the ",(0,s.jsx)(n.code,{children:"root"})," folder and in it should be ",(0,s.jsx)(n.code,{children:"your-contract-name.wasm"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7ce91694.521657b2.js b/assets/js/7ce91694.521657b2.js new file mode 100644 index 000000000..adb606f7e --- /dev/null +++ b/assets/js/7ce91694.521657b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51721],{13923:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Unbonding"},o="Unbonding as a Validator",r={id:"operators/becoming-a-validator/unbonding",title:"Unbonding",description:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/unbonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/unbonding",permalink:"/2.0.0/operators/becoming-a-validator/unbonding",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Unbonding"},sidebar:"operators",previous:{title:"Bonding",permalink:"/2.0.0/operators/becoming-a-validator/bonding"},next:{title:"Recovery",permalink:"/2.0.0/operators/becoming-a-validator/recovering"}},c={},d=[{value:"Method 1: Unbonding with the System Auction Contract",id:"withdraw-system-auction",level:2},{value:"Method 2: Unbonding with Compiled Wasm",id:"withdraw-compiled-wasm",level:2},{value:"Check the Auction Contract",id:"check-the-auction-contract",level:2},{value:"Unbonding Wait Period",id:"unbonding-wait-period",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"unbonding-as-a-validator",children:"Unbonding as a Validator"})}),"\n",(0,s.jsx)(n.p,{children:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction."}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-system-auction",children:"Method 1: Unbonding with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method withdraws a bid using the system auction contract. Call the existing ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,s.jsx)(n.strong,{children:"Adjust all the values to your use case."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-compiled-wasm",children:"Method 2: Unbonding with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["There is a second way to withdraw a bid, using the compiled Wasm ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The process is the same as bonding but uses a different contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes estimated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"})," expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["Here is an example request to unbond stake using the ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"check-the-auction-contract",children:"Check the Auction Contract"}),"\n",(0,s.jsx)(n.p,{children:"Check the auction contract for updates to the bid amounts."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"unbonding-wait-period",children:"Unbonding Wait Period"}),"\n",(0,s.jsx)(n.p,{children:"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cf62e8d.1ebdf3ec.js b/assets/js/7cf62e8d.1ebdf3ec.js new file mode 100644 index 000000000..9220951c7 --- /dev/null +++ b/assets/js/7cf62e8d.1ebdf3ec.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[566],{54814:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(74848),o=t(28453);const a={},s="Guidance for JSON-RPC SDK Compliance",r={id:"developers/json-rpc/guidance",title:"Guidance for JSON-RPC SDK Compliance",description:"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/guidance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/guidance",permalink:"/1.5.X/developers/json-rpc/guidance",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/1.5.X/developers/json-rpc/"},next:{title:"Required Methods for Minimal Compliance",permalink:"/1.5.X/developers/json-rpc/minimal-compliance"}},l={},c=[{value:"Consistency",id:"consistency",level:2},{value:"Advanced Functionality",id:"advanced-functionality",level:2}];function d(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"guidance-for-json-rpc-sdk-compliance",children:"Guidance for JSON-RPC SDK Compliance"})}),"\n",(0,i.jsxs)(n.p,{children:["A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational",children:"informational JSON-RPC methods"})," page."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["A Casper JSON-RPC SDK claiming to be complete is expected to implement ",(0,i.jsx)(n.em,{children:"all"})," endpoints and ",(0,i.jsx)(n.em,{children:"all"})," types defined in the serialization standard."]})}),"\n",(0,i.jsx)(n.h2,{id:"consistency",children:"Consistency"}),"\n",(0,i.jsx)(n.p,{children:"A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and Deploy, not similar terms such as wallet or transaction."}),"\n",(0,i.jsx)(n.p,{children:"Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-functionality",children:"Advanced Functionality"}),"\n",(0,i.jsx)(n.p,{children:"SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations."}),"\n",(0,i.jsx)(n.p,{children:"However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience."}),"\n",(0,i.jsx)(n.p,{children:"For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cf62e8d.f6f618ae.js b/assets/js/7cf62e8d.f6f618ae.js deleted file mode 100644 index 528cc311d..000000000 --- a/assets/js/7cf62e8d.f6f618ae.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[566],{54814:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(74848),o=t(28453);const a={},s="Guidance for JSON-RPC SDK Compliance",r={id:"developers/json-rpc/guidance",title:"Guidance for JSON-RPC SDK Compliance",description:"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/guidance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/guidance",permalink:"/developers/json-rpc/guidance",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers/json-rpc/"},next:{title:"Required Methods for Minimal Compliance",permalink:"/developers/json-rpc/minimal-compliance"}},l={},c=[{value:"Consistency",id:"consistency",level:2},{value:"Advanced Functionality",id:"advanced-functionality",level:2}];function d(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"guidance-for-json-rpc-sdk-compliance",children:"Guidance for JSON-RPC SDK Compliance"})}),"\n",(0,i.jsxs)(n.p,{children:["A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational",children:"informational JSON-RPC methods"})," page."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["A Casper JSON-RPC SDK claiming to be complete is expected to implement ",(0,i.jsx)(n.em,{children:"all"})," endpoints and ",(0,i.jsx)(n.em,{children:"all"})," types defined in the serialization standard."]})}),"\n",(0,i.jsx)(n.h2,{id:"consistency",children:"Consistency"}),"\n",(0,i.jsx)(n.p,{children:"A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and Deploy, not similar terms such as wallet or transaction."}),"\n",(0,i.jsx)(n.p,{children:"Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-functionality",children:"Advanced Functionality"}),"\n",(0,i.jsx)(n.p,{children:"SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations."}),"\n",(0,i.jsx)(n.p,{children:"However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience."}),"\n",(0,i.jsx)(n.p,{children:"For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cff47a5.24df3477.js b/assets/js/7cff47a5.24df3477.js new file mode 100644 index 000000000..615f09483 --- /dev/null +++ b/assets/js/7cff47a5.24df3477.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[48916],{93507:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>r});var s=n(74848),o=n(28453);const i={},c="Estimating Gas Costs with Speculative Execution",a={id:"developers/dapps/speculative-exec",title:"Estimating Gas Costs with Speculative Execution",description:"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.",source:"@site/docs/developers/dapps/speculative-exec.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/speculative-exec",permalink:"/developers/dapps/speculative-exec",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Signing Transactions",permalink:"/developers/dapps/signing-a-transaction"},next:{title:"Local Network Setup",permalink:"/developers/dapps/setup-nctl"}},l={},r=[{value:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client",id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"estimating-gas-costs-with-speculative-execution",children:"Estimating Gas Costs with Speculative Execution"})}),"\n",(0,s.jsxs)(t.p,{children:["Version 1.5 of the Casper Node includes a new JSON RPC endpoint called ",(0,s.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-transactional#speculative_exec",children:(0,s.jsx)(t.code,{children:"speculative_exec"})}),". This endpoint allows developers to send a ",(0,s.jsx)(t.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"})," to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution."]}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the Deploy in question, ",(0,s.jsx)(t.code,{children:"speculative_exec"})," also accepts a [",(0,s.jsx)(t.code,{children:"block_identifier"}),"] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block."]}),"\n",(0,s.jsx)(t.h2,{id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",children:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"Rust CLI Casper client"})," includes a ",(0,s.jsx)(t.code,{children:"speculative-exec"})," option that will flag a normal ",(0,s.jsx)(t.code,{children:"put-deploy"})," for execution but not commitment to global state. The following command shows an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncasper client put-deploy /\n--node-address <HOST:PORT> /\n--chain-name <CHAIN_NAME> /\n--secret-key <PATH> /\n--session-path <PATH> /\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES>\n--speculative-exec <BLOCK HEIGHT OR HASH>\n\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You should receive ",(0,s.jsx)(t.code,{children:"execution_result"}),"s that show a ",(0,s.jsx)(t.code,{children:"cost"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n <Deploy effects removed for conciseness.>\n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Cost estimates acquired through ",(0,s.jsx)(t.code,{children:"speculative_exec"})," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary."]})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7cff47a5.af4053dd.js b/assets/js/7cff47a5.af4053dd.js deleted file mode 100644 index f5c0453b8..000000000 --- a/assets/js/7cff47a5.af4053dd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8916],{93507:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>r});var s=n(74848),o=n(28453);const i={},c="Estimating Gas Costs with Speculative Execution",a={id:"developers/dapps/speculative-exec",title:"Estimating Gas Costs with Speculative Execution",description:"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.",source:"@site/docs/developers/dapps/speculative-exec.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/speculative-exec",permalink:"/next/developers/dapps/speculative-exec",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"developers",previous:{title:"Signing Transactions",permalink:"/next/developers/dapps/signing-a-transaction"},next:{title:"Local Network Setup",permalink:"/next/developers/dapps/setup-nctl"}},l={},r=[{value:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client",id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"estimating-gas-costs-with-speculative-execution",children:"Estimating Gas Costs with Speculative Execution"})}),"\n",(0,s.jsxs)(t.p,{children:["Version 1.5 of the Casper Node includes a new JSON RPC endpoint called ",(0,s.jsx)(t.a,{href:"/next/developers/json-rpc/json-rpc-transactional#speculative_exec",children:(0,s.jsx)(t.code,{children:"speculative_exec"})}),". This endpoint allows developers to send a ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/D#deploy",children:"Deploy"})," to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution."]}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the Deploy in question, ",(0,s.jsx)(t.code,{children:"speculative_exec"})," also accepts a [",(0,s.jsx)(t.code,{children:"block_identifier"}),"] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block."]}),"\n",(0,s.jsx)(t.h2,{id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",children:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"Rust CLI Casper client"})," includes a ",(0,s.jsx)(t.code,{children:"speculative-exec"})," option that will flag a normal ",(0,s.jsx)(t.code,{children:"put-deploy"})," for execution but not commitment to global state. The following command shows an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncasper client put-deploy /\n--node-address <HOST:PORT> /\n--chain-name <CHAIN_NAME> /\n--secret-key <PATH> /\n--session-path <PATH> /\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES>\n--speculative-exec <BLOCK HEIGHT OR HASH>\n\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You should receive ",(0,s.jsx)(t.code,{children:"execution_result"}),"s that show a ",(0,s.jsx)(t.code,{children:"cost"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n <Deploy effects removed for conciseness.>\n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Cost estimates acquired through ",(0,s.jsx)(t.code,{children:"speculative_exec"})," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary."]})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e55f6e6.22836de1.js b/assets/js/7e55f6e6.22836de1.js deleted file mode 100644 index 5d2a7c436..000000000 --- a/assets/js/7e55f6e6.22836de1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2028],{60588:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const a={},c="Smart Contracts",o={id:"concepts/smart-contracts",title:"Smart Contracts",description:"Smart Contracts in General",source:"@site/versioned_docs/version-1.5.X/concepts/smart-contracts.md",sourceDirName:"concepts",slug:"/concepts/smart-contracts",permalink:"/concepts/smart-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Global State",permalink:"/concepts/global-state"},next:{title:"Authorization Keys",permalink:"/concepts/list-auth-keys"}},i={},l=[{value:"Smart Contracts in General",id:"smart-contracts-in-general",level:2},{value:"Casper Smart Contracts",id:"casper-smart-contracts",level:2},{value:"Session Code",id:"session-code",level:2},{value:"Further Reading",id:"further-reading",level:3}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"smart-contracts-in-general",children:"Smart Contracts in General"}),"\n",(0,s.jsx)(t.p,{children:"A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism."}),"\n",(0,s.jsx)(t.h2,{id:"casper-smart-contracts",children:"Casper Smart Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["Casper smart contracts can be implemented in any programming language that compiles to ",(0,s.jsx)(t.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"}),", which can be installed and executed on-chain using ",(0,s.jsx)(t.a,{href:"/concepts/glossary/D#deploy",children:"Deploys"}),". Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"session-code",children:"Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. Understand when you would use session code over contract code ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/cli/sending-deploys",children:"Sending a Deploy"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"Calling Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/cli/calling-contracts",children:"Calling Smart Contracts using the Casper Client"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>o});var s=n(96540);const r={},a=s.createContext(r);function c(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7e55f6e6.80a4eced.js b/assets/js/7e55f6e6.80a4eced.js new file mode 100644 index 000000000..87cea4962 --- /dev/null +++ b/assets/js/7e55f6e6.80a4eced.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72028],{60588:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const a={},c="Smart Contracts",o={id:"concepts/smart-contracts",title:"Smart Contracts",description:"Smart Contracts in General",source:"@site/versioned_docs/version-1.5.X/concepts/smart-contracts.md",sourceDirName:"concepts",slug:"/concepts/smart-contracts",permalink:"/1.5.X/concepts/smart-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Global State",permalink:"/1.5.X/concepts/global-state"},next:{title:"Authorization Keys",permalink:"/1.5.X/concepts/list-auth-keys"}},i={},l=[{value:"Smart Contracts in General",id:"smart-contracts-in-general",level:2},{value:"Casper Smart Contracts",id:"casper-smart-contracts",level:2},{value:"Session Code",id:"session-code",level:2},{value:"Further Reading",id:"further-reading",level:3}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(t.h2,{id:"smart-contracts-in-general",children:"Smart Contracts in General"}),"\n",(0,s.jsx)(t.p,{children:"A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism."}),"\n",(0,s.jsx)(t.h2,{id:"casper-smart-contracts",children:"Casper Smart Contracts"}),"\n",(0,s.jsxs)(t.p,{children:["Casper smart contracts can be implemented in any programming language that compiles to ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/glossary/W#webassembly",children:"Wasm"}),", which can be installed and executed on-chain using ",(0,s.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploys"}),". Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"session-code",children:"Session Code"}),"\n",(0,s.jsxs)(t.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. Understand when you would use session code over contract code ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session",children:"here"}),"."]}),"\n",(0,s.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Sending a Deploy"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/calling-contracts",children:"Calling Smart Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/cli/calling-contracts",children:"Calling Smart Contracts using the Casper Client"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>o});var s=n(96540);const r={},a=s.createContext(r);function c(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7effaf45.395677e0.js b/assets/js/7effaf45.395677e0.js deleted file mode 100644 index 8bac4c8c6..000000000 --- a/assets/js/7effaf45.395677e0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5087],{58347:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=n(74848),o=n(28453);const a={slug:"/concepts/economics/concepts"},r="Staking Concepts",i={id:"concepts/economics/staking/concepts",title:"Staking Concepts",description:"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/concepts.md",sourceDirName:"concepts/economics/staking",slug:"/concepts/economics/concepts",permalink:"/concepts/economics/concepts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/concepts/economics/concepts"},sidebar:"concepts",previous:{title:"Gas Cost",permalink:"/concepts/economics/gas-concepts"},next:{title:"Staking vs. Delegating",permalink:"/staking"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"staking-concepts",children:"Staking Concepts"})}),"\n",(0,s.jsx)(t.p,{children:"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Consensus mechanism:"})," Casper operates using a Proof-of-Stake consensus mechanism per the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/highway",children:"Highway Protocol"}),", a specification of Correct-by-Construction Casper (CBC Casper)."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Number of validators:"})," The Casper Mainnet supports up to 100 validators on the network. This number is chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through a process of permission-less bonding by participating in an auction for the validator slot."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Permission-less bonding:"})," For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permission-less, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Unbonding:"})," To detach from a Casper network, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards during the seven eras required for unbonding, as they are not actively contributing to the network's security during that time."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Eras and block times:"})," An era on Casper is roughly 2 hours long. Casper's Highway protocol allows validators to propose blocks as quickly as network conditions allow, subject to a platform-wide limit that may be adjusted with upgrades. We anticipate block times to last between thirty seconds and eight minutes."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Block rewards:"})," Block time is orthogonal to rewards, so there is no precise reward per block. Instead, the number of rewards is split proportionally among stakes and reduced for failure to participate in the protocol promptly."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Reward cycle:"})," Rewards are distributed to validators and delegators once per era."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Token supply and inflation:"})," Mainnet launched with ten billion CSPR at the time of genesis. The target annual supply growth rate is 8%."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Annual reward percentage:"})," Validators on the Casper Mainnet earn between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes is dependent on total active stake, as only a fixed number of tokens is created per era."]}),"\n",(0,s.jsxs)(t.p,{children:["Please visit the ",(0,s.jsx)(t.a,{href:"/staking",children:"Staking Guide"})," for further details on the staking mechanism."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var s=n(96540);const o={},a=s.createContext(o);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7effaf45.b7576d51.js b/assets/js/7effaf45.b7576d51.js new file mode 100644 index 000000000..11c389e39 --- /dev/null +++ b/assets/js/7effaf45.b7576d51.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15087],{58347:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=n(74848),o=n(28453);const a={slug:"/concepts/economics/concepts"},r="Staking Concepts",i={id:"concepts/economics/staking/concepts",title:"Staking Concepts",description:"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/staking/concepts.md",sourceDirName:"concepts/economics/staking",slug:"/concepts/economics/concepts",permalink:"/1.5.X/concepts/economics/concepts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/concepts/economics/concepts"},sidebar:"concepts",previous:{title:"Gas Cost",permalink:"/1.5.X/concepts/economics/gas-concepts"},next:{title:"Staking vs. Delegating",permalink:"/1.5.X/staking"}},c={},d=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"staking-concepts",children:"Staking Concepts"})}),"\n",(0,s.jsx)(t.p,{children:"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras."}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Consensus mechanism:"})," Casper operates using a Proof-of-Stake consensus mechanism per the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/highway",children:"Highway Protocol"}),", a specification of Correct-by-Construction Casper (CBC Casper)."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Number of validators:"})," The Casper Mainnet supports up to 100 validators on the network. This number is chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through a process of permission-less bonding by participating in an auction for the validator slot."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Permission-less bonding:"})," For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permission-less, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Unbonding:"})," To detach from a Casper network, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards during the seven eras required for unbonding, as they are not actively contributing to the network's security during that time."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Eras and block times:"})," An era on Casper is roughly 2 hours long. Casper's Highway protocol allows validators to propose blocks as quickly as network conditions allow, subject to a platform-wide limit that may be adjusted with upgrades. We anticipate block times to last between thirty seconds and eight minutes."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Block rewards:"})," Block time is orthogonal to rewards, so there is no precise reward per block. Instead, the number of rewards is split proportionally among stakes and reduced for failure to participate in the protocol promptly."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Reward cycle:"})," Rewards are distributed to validators and delegators once per era."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Token supply and inflation:"})," Mainnet launched with ten billion CSPR at the time of genesis. The target annual supply growth rate is 8%."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Annual reward percentage:"})," Validators on the Casper Mainnet earn between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes is dependent on total active stake, as only a fixed number of tokens is created per era."]}),"\n",(0,s.jsxs)(t.p,{children:["Please visit the ",(0,s.jsx)(t.a,{href:"/1.5.X/staking",children:"Staking Guide"})," for further details on the staking mechanism."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var s=n(96540);const o={},a=s.createContext(o);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7f115b1f.08f8427a.js b/assets/js/7f115b1f.08f8427a.js new file mode 100644 index 000000000..affbf9a86 --- /dev/null +++ b/assets/js/7f115b1f.08f8427a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64358],{59460:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=t(74848),i=t(28453);const r={},c="Testing Session Code",o={id:"developers/writing-onchain-code/testing-session-code",title:"Testing Session Code",description:"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.",source:"@site/docs/developers/writing-onchain-code/testing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-session-code",permalink:"/developers/writing-onchain-code/testing-session-code",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing Session Code",permalink:"/developers/writing-onchain-code/writing-session-code"},next:{title:"Contract-Level Events",permalink:"/developers/writing-onchain-code/emitting-contract-events"}},a={},d=[{value:"Specifying Dependencies in Cargo.toml",id:"specifying-dependencies",level:2},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Required Packages",id:"importing-required-packages",level:3},{value:"Defining The Constants",id:"defining-the-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Running the Test",id:"running-the-test",level:3},{value:"Other Examples",id:"other-examples",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testing-session-code",children:"Testing Session Code"})}),"\n",(0,n.jsxs)(s.p,{children:["This section describes how to test session code using the Casper unit-testing framework. The ",(0,n.jsx)(s.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"writing session code"})," section is a prerequisite for this tutorial, which uses the example code described ",(0,n.jsx)(s.a,{href:"/developers/writing-onchain-code/writing-session-code#writing-session-code",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"specifying-dependencies",children:"Specifying Dependencies in Cargo.toml"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/Cargo.toml",children:"Cargo.toml"})," sample file in the ",(0,n.jsx)(s.code,{children:"tests"})," directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'[dev-dependencies]\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-execution-engine = "2.0.0"\ncasper-types = "1.5.0"\n'})}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,n.jsxs)(s.p,{children:["Tests for this example session code reside in the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file."]}),"\n",(0,n.jsxs)(s.p,{children:["Notice that this file contains an empty ",(0,n.jsx)(s.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,n.jsx)(s.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/contract/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,n.jsx)(s.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,n.jsx)(s.code,{children:"mod tests"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"importing-required-packages",children:"Importing Required Packages"}),"\n",(0,n.jsx)(s.p,{children:"Next, import the packages required for the tests to run. The example tests use these packages:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n use casper_types::account::AccountHash;\n use casper_types::{runtime_args, RuntimeArgs};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"defining-the-constants",children:"Defining The Constants"}),"\n",(0,n.jsx)(s.p,{children:"The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account\nconst ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument\nconst CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE\n'})}),"\n",(0,n.jsx)(s.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,n.jsxs)(s.p,{children:["In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the ",(0,n.jsx)(s.code,{children:"#[test]"})," attribute."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[test]\nfn <unit-test-name>{\n // Test function implementation\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["This ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"unit test"})," is a good example of testing session code. At a high level, the test follows this process:"]}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["Initialize an instance of the execution engine and the ",(0,n.jsx)(s.code,{children:"InMemoryWasmTestBuilder"}),"."]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let mut builder = InMemoryWasmTestBuilder::default();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Execute the genesis process."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"GitHub"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsx)(s.p,{children:"Retrieve runtime arguments, which should be the same as defined in the contract."}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Create the execution request that sets up the session code to be processed. In this example, the ",(0,n.jsx)(s.code,{children:"CONTRACT_WASM"})," is the session code."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Invoke the execution engine to process the session code."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.exec(execute_request).expect_success().commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Verify that the results match the expected output. This example checks the associated keys."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n"})}),"\n",(0,n.jsx)(s.h3,{id:"running-the-test",children:"Running the Test"}),"\n",(0,n.jsxs)(s.p,{children:["This example uses a ",(0,n.jsx)(s.code,{children:"Makefile"})," to run the tests."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Under the hood, the ",(0,n.jsx)(s.code,{children:"Makefile"})," generates a ",(0,n.jsx)(s.code,{children:"tests/wasm"})," folder, copies the Wasm to the folder, and runs the tests with ",(0,n.jsx)(s.code,{children:"cargo test"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n"})}),"\n",(0,n.jsx)(s.h3,{id:"other-examples",children:"Other Examples"}),"\n",(0,n.jsxs)(s.p,{children:["In the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"counter unit tests"}),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,n.jsx)(s.p,{children:"The verification step looks like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,n.jsxs)(s.p,{children:["For many more examples, visit the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,n.jsx)(s.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,n.jsxs)(s.p,{children:["The following brief video describes testing the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,n.jsxs)(s.p,{align:"center",children:["\n",(0,n.jsx)(s.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Learn to ",(0,n.jsx)(s.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>o});var n=t(96540);const i={},r=n.createContext(i);function c(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7f115b1f.4ae39270.js b/assets/js/7f115b1f.4ae39270.js deleted file mode 100644 index 7332d7df3..000000000 --- a/assets/js/7f115b1f.4ae39270.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4358],{59460:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=t(74848),i=t(28453);const r={},c="Testing Session Code",o={id:"developers/writing-onchain-code/testing-session-code",title:"Testing Session Code",description:"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.",source:"@site/docs/developers/writing-onchain-code/testing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-session-code",permalink:"/next/developers/writing-onchain-code/testing-session-code",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing Session Code",permalink:"/next/developers/writing-onchain-code/writing-session-code"},next:{title:"Contract-Level Events",permalink:"/next/developers/writing-onchain-code/emitting-contract-events"}},a={},d=[{value:"Specifying Dependencies in Cargo.toml",id:"specifying-dependencies",level:2},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Required Packages",id:"importing-required-packages",level:3},{value:"Defining The Constants",id:"defining-the-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Running the Test",id:"running-the-test",level:3},{value:"Other Examples",id:"other-examples",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testing-session-code",children:"Testing Session Code"})}),"\n",(0,n.jsxs)(s.p,{children:["This section describes how to test session code using the Casper unit-testing framework. The ",(0,n.jsx)(s.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"writing session code"})," section is a prerequisite for this tutorial, which uses the example code described ",(0,n.jsx)(s.a,{href:"/next/developers/writing-onchain-code/writing-session-code#writing-session-code",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"specifying-dependencies",children:"Specifying Dependencies in Cargo.toml"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/Cargo.toml",children:"Cargo.toml"})," sample file in the ",(0,n.jsx)(s.code,{children:"tests"})," directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'[dev-dependencies]\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-execution-engine = "2.0.0"\ncasper-types = "1.5.0"\n'})}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,n.jsxs)(s.p,{children:["Tests for this example session code reside in the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file."]}),"\n",(0,n.jsxs)(s.p,{children:["Notice that this file contains an empty ",(0,n.jsx)(s.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,n.jsx)(s.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/contract/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,n.jsx)(s.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,n.jsx)(s.code,{children:"mod tests"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"importing-required-packages",children:"Importing Required Packages"}),"\n",(0,n.jsx)(s.p,{children:"Next, import the packages required for the tests to run. The example tests use these packages:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n use casper_types::account::AccountHash;\n use casper_types::{runtime_args, RuntimeArgs};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"defining-the-constants",children:"Defining The Constants"}),"\n",(0,n.jsx)(s.p,{children:"The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account\nconst ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument\nconst CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE\n'})}),"\n",(0,n.jsx)(s.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,n.jsxs)(s.p,{children:["In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the ",(0,n.jsx)(s.code,{children:"#[test]"})," attribute."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[test]\nfn <unit-test-name>{\n // Test function implementation\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["This ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"unit test"})," is a good example of testing session code. At a high level, the test follows this process:"]}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["Initialize an instance of the execution engine and the ",(0,n.jsx)(s.code,{children:"InMemoryWasmTestBuilder"}),"."]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let mut builder = InMemoryWasmTestBuilder::default();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Execute the genesis process."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"GitHub"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsx)(s.p,{children:"Retrieve runtime arguments, which should be the same as defined in the contract."}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Create the execution request that sets up the session code to be processed. In this example, the ",(0,n.jsx)(s.code,{children:"CONTRACT_WASM"})," is the session code."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Invoke the execution engine to process the session code."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.exec(execute_request).expect_success().commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Verify that the results match the expected output. This example checks the associated keys."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n"})}),"\n",(0,n.jsx)(s.h3,{id:"running-the-test",children:"Running the Test"}),"\n",(0,n.jsxs)(s.p,{children:["This example uses a ",(0,n.jsx)(s.code,{children:"Makefile"})," to run the tests."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Under the hood, the ",(0,n.jsx)(s.code,{children:"Makefile"})," generates a ",(0,n.jsx)(s.code,{children:"tests/wasm"})," folder, copies the Wasm to the folder, and runs the tests with ",(0,n.jsx)(s.code,{children:"cargo test"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n"})}),"\n",(0,n.jsx)(s.h3,{id:"other-examples",children:"Other Examples"}),"\n",(0,n.jsxs)(s.p,{children:["In the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"counter unit tests"}),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,n.jsx)(s.p,{children:"The verification step looks like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,n.jsxs)(s.p,{children:["For many more examples, visit the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,n.jsx)(s.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,n.jsxs)(s.p,{children:["The following brief video describes testing the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,n.jsxs)(s.p,{align:"center",children:["\n",(0,n.jsx)(s.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Learn to ",(0,n.jsx)(s.a,{href:"/next/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>o});var n=t(96540);const i={},r=n.createContext(i);function c(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7feecbc1.0bd89ed5.js b/assets/js/7feecbc1.0bd89ed5.js new file mode 100644 index 000000000..29923b951 --- /dev/null +++ b/assets/js/7feecbc1.0bd89ed5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95773],{57440:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var n=t(74848),r=t(28453);const o={title:"What is Casper?"},i=void 0,a={id:"concepts/about",title:"What is Casper?",description:"What is Casper?",source:"@site/versioned_docs/version-2.0.0/concepts/about.md",sourceDirName:"concepts",slug:"/concepts/about",permalink:"/2.0.0/concepts/about",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"What is Casper?"},sidebar:"concepts",previous:{title:"Overview",permalink:"/2.0.0/concepts/"},next:{title:"Design Overview",permalink:"/2.0.0/design"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How does Casper work?",id:"how-does-casper-work",level:2},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const s={a:"a",em:"em",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,n.jsxs)(s.p,{children:["Casper is a ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,n.jsxs)(s.p,{children:["The network's consensus protocol is called ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"}),", and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of ",(0,n.jsx)(s.em,{children:"finality"}),", meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: ",(0,n.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's ",(0,n.jsx)(s.a,{href:"/2.0.0/resources/build-on-casper/introduction",children:"core features and strengths"})," enable developers and enterprises to reap the benefits of blockchain technology."]}),"\n",(0,n.jsx)(s.p,{children:"Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises."}),"\n",(0,n.jsx)(s.h2,{id:"how-does-casper-work",children:"How does Casper work?"}),"\n",(0,n.jsx)(s.p,{children:"Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network."}),"\n",(0,n.jsxs)(s.p,{children:["To understand the design further, read ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/design/casper-design",children:"this article"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,n.jsxs)(s.p,{children:["Read the ",(0,n.jsx)(s.a,{href:"/2.0.0/disclaimer",children:"Legal Disclaimer"}),' regarding this CasperLabs Tech Spec (this "Whitepaper").']})]})}function p(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var n=t(96540);const r={},o=n.createContext(r);function i(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/80510dbd.8f6dc460.js b/assets/js/80510dbd.8f6dc460.js new file mode 100644 index 000000000..4461a444b --- /dev/null +++ b/assets/js/80510dbd.8f6dc460.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95283],{51871:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var s=t(74848),r=t(28453);const a={title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"},o="Listing CSPR on an Exchange",i={id:"resources/advanced/list-cspr",title:"Listing CSPR",description:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/list-cspr.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/list-cspr",permalink:"/2.0.0/resources/tutorials/advanced/list-cspr",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"}},c={},d=[{value:"Setting up a Node",id:"setting-up-a-node",level:2},{value:"Casper Account",id:"casper-account",level:2},{value:"Understanding Basic Transactions",id:"understanding-basic-transactions",level:2},{value:"Native transfer",id:"native-transfer",level:3},{value:"Bulk or batched Wasm transfer",id:"bulk-or-batched-wasm-transfer",level:3},{value:"Integrating CSPR",id:"integrating-cspr",level:2},{value:"Testing the Integration",id:"testing-the-integration",level:2},{value:"The Casper Protocol",id:"the-casper-protocol",level:2},{value:"Staking Integration for Exchanges",id:"staking-integration-for-exchanges",level:2},{value:"Deploy Structures and Parameters",id:"deploy-structures-and-parameters",level:3},{value:"1. Creating a deploy object",id:"1-creating-a-deploy-object",level:4},{value:"2a. Sign the deploy (Casper Signer)",id:"2a-sign-the-deploy-casper-signer",level:4},{value:"2b. Sign the deploy (Ledger)",id:"2b-sign-the-deploy-ledger",level:4},{value:"Costs and Minimums",id:"costs-and-minimums",level:3},{value:"The Delegation Cap",id:"the-delegation-cap",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"listing-cspr-on-an-exchange",children:"Listing CSPR on an Exchange"})}),"\n",(0,s.jsx)(n.p,{children:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-a-node",children:"Setting up a Node"}),"\n",(0,s.jsxs)(n.p,{children:["While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see ",(0,s.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration",children:"Basic Node Setup"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions."}),"\n",(0,s.jsx)(n.h2,{id:"casper-account",children:"Casper Account"}),"\n",(0,s.jsxs)(n.p,{children:["You will need a Casper Account to handle the transactions on an exchange. Casper has an ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Account model"})," and instructions on how to ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-creating",children:"create an Account"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users."}),"\n",(0,s.jsx)(n.h2,{id:"understanding-basic-transactions",children:"Understanding Basic Transactions"}),"\n",(0,s.jsx)(n.p,{children:"We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice."}),"\n",(0,s.jsx)(n.p,{children:"Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others."}),"\n",(0,s.jsx)(n.h3,{id:"native-transfer",children:"Native transfer"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"payment"})," field describes how we are paying for the deploy, in this case a native transfer, while the ",(0,s.jsx)(n.code,{children:"session"})," field describes the actual transfer."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Native Transfer Deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n"id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "approvals": [\n {\n "signature": "130 chars",\n "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"\n }\n ],\n "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713",\n "header": {\n "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e",\n "chain_name": "casper-net-1",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2021-04-20T18:04:40.333Z",\n "ttl": "1h"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "021027",\n "cl_type": "U512",\n "parsed": "10000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668",\n "cl_type": {\n "ByteArray": 32\n },\n "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668"\n }\n ],\n [\n "id",\n {\n "bytes": "00",\n "cl_type": {\n "Option": "U64"\n },\n "parsed": null\n }\n ]\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/direct-token-transfer",children:"Direct Token Transfer"}),". The following command transfers 10 CSPR from ",(0,s.jsx)(n.em,{children:"account A's main purse"})," to ",(0,s.jsx)(n.em,{children:"account B's main purse"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id 1 \\\n--transfer-id 123456 \\\n--node-address http://<node-ip-address>:7777 \\\n--amount 10000000000 \\\n--secret-key <accountA-secret-key>.pem \\\n--chain-name casper \\\n--target-account <accountB-hex-encoded-public-key> \\\n--payment-amount <payment-in-motes>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The payment amount varies based on the deploy and network ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),". For node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes."]}),"\n",(0,s.jsx)(n.h3,{id:"bulk-or-batched-wasm-transfer",children:"Bulk or batched Wasm transfer"}),"\n",(0,s.jsxs)(n.p,{children:["Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html",children:"Rust contract API"}),", which can be used in session code to achieve batched Wasm transfer:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_account"}),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_public_key"}),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_purse"}),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_public_key"}),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_account"}),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on how to write session code, see ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),". There are equivalent ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305",children:"assembly script"})," methods available. Alternatively, you can program directly against the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370",children:"ext-FFI"})," methods."]}),"\n",(0,s.jsx)(n.h2,{id:"integrating-cspr",children:"Integrating CSPR"}),"\n",(0,s.jsxs)(n.p,{children:["You can integrate with the ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/",children:"JSON-RPC API"})," of a node on the Casper Mainnet.\nYou can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,s.jsx)(n.a,{href:"/2.0.0/sdk",children:"SDK Libraries"}),".\nCasper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-integration",children:"Testing the Integration"}),"\n",(0,s.jsxs)(n.p,{children:["Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", then you can do so with your own test accounts."]}),"\n",(0,s.jsx)(n.p,{children:"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-protocol",children:"The Casper Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."}),"\n",(0,s.jsxs)(n.li,{children:["Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#execution-semantics-head",children:"Execution Semantics"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"staking-integration-for-exchanges",children:"Staking Integration for Exchanges"}),"\n",(0,s.jsxs)(n.p,{children:["Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"})," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,s.jsx)(n.a,{href:"/2.0.0/users/delegating",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-structures-and-parameters",children:"Deploy Structures and Parameters"}),"\n",(0,s.jsx)(n.p,{children:"Staking operations consists of two parts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Creating a deploy object"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/dapps/signing-a-transaction",children:"Signing the deploy"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The staking deploy requires the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The delegator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The validator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The new validator's public key (For redelegation only)"}),"\n",(0,s.jsx)(n.li,{children:"The amount to be delegated"}),"\n",(0,s.jsx)(n.li,{children:"The gas cost"}),"\n",(0,s.jsx)(n.li,{children:"The auction manager contract's hash"}),"\n",(0,s.jsx)(n.li,{children:"The appropriate entry point"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate",children:"Delegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate",children:"Undelegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate",children:"Redelegate"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-creating-a-deploy-object",children:"1. Creating a deploy object"}),"\n",(0,s.jsxs)(n.p,{children:["To create a deploy using the JavaScript SDK, we will need ",(0,s.jsx)(n.code,{children:"deployParams"}),", ",(0,s.jsx)(n.code,{children:"session"})," and a ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Deploy params is a ",(0,s.jsx)(n.code,{children:"DeployUtil.DeployParams"})," object created from the delegator's ",(0,s.jsx)(n.code,{children:"publicKey"})," and the network name as shown in the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For creating a ",(0,s.jsx)(n.code,{children:"session"})," object, which is ",(0,s.jsx)(n.code,{children:"DeployUtil.ExecutableDeployItem"}),", we need"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"delegator"})," and ",(0,s.jsx)(n.strong,{children:"validator's public keys"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"amount"})," of tokens to delegate/undelegate/redelgate"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"auction manager contract's hash"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["First, create a variable ",(0,s.jsx)(n.code,{children:"RuntimeArgs"})," from the public keys and the amount. We will need to use it below in ",(0,s.jsx)(n.code,{children:"session"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Second, create a ",(0,s.jsx)(n.code,{children:"session"})," parameter. It is a ",(0,s.jsx)(n.code,{children:"Uint8Array"})," consisting of the ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"}),", the ",(0,s.jsx)(n.code,{children:"entry points"})," and ",(0,s.jsx)(n.code,{children:"runtime arguments"}),", which we previously created."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"})," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Mainnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Testnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Your ",(0,s.jsx)(n.code,{children:"entry point"})," will depend on which action you are performing, with the following three available:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegate"})," - Initial delegation to a validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"undelegate"})," - Undelegating tokens from a validator back to the delegator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"redelegate"})," - Redelegating tokens to a new validator"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the ",(0,s.jsx)(n.code,{children:"payment"})," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml",children:(0,s.jsx)(n.code,{children:"chainspec for version 1.4.8"})}),". You will need the chainspec for the network version you are using."]}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"DeployUtil.standardPayment"})," method for creating ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n"})}),"\n",(0,s.jsx)(n.p,{children:"The last operation is creating the deploy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Redelegation"}),", occurs the same way as delegation, but with the introduction of a third public_key."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2a-sign-the-deploy-casper-signer",children:"2a. Sign the deploy (Casper Signer)"}),"\n",(0,s.jsxs)(n.p,{children:["To get the signature, you will need to use ",(0,s.jsx)(n.code,{children:"Signer.sign"})," from the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"}),". It will return ",(0,s.jsx)(n.code,{children:"Promise<{ deploy }>"}),", which is the signed object."]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"DeployUtil.deployFromJson"})," to convert the result and sent it to network with:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2b-sign-the-deploy-ledger",children:"2b. Sign the deploy (Ledger)"}),"\n",(0,s.jsxs)(n.p,{children:["You will need to connect with your ",(0,s.jsx)(n.code,{children:"Ledger"})," first to get the signature."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Signature will be in a property called ",(0,s.jsx)(n.code,{children:"res.signatureRS"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After that, we can create a signed deploy,"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can then send it to a network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"casperService.deploy(signedDeploy)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-minimums",children:"Costs and Minimums"}),"\n",(0,s.jsxs)(n.p,{children:["The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Transfer Cost: 100,000,000 motes or 0.1 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,s.jsx)(n.strong,{children:"CSPR"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"the-delegation-cap",children:"The Delegation Cap"}),"\n",(0,s.jsxs)(n.p,{children:["Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,s.jsx)(n.code,{children:"953"}),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."]}),"\n",(0,s.jsxs)(n.p,{children:["Validators with a delegator count at or above ",(0,s.jsx)(n.code,{children:"953"})," at the time of the ",(0,s.jsx)(n.strong,{children:"1.4.5"})," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,s.jsx)(n.code,{children:"953"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,s.jsx)(n.strong,{children:"CSPR"})," to that validator. However, no new delegators may join the validator until it drops below the ",(0,s.jsx)(n.code,{children:"953"})," limit."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/80e6044e.713e25c1.js b/assets/js/80e6044e.713e25c1.js deleted file mode 100644 index bde765cd5..000000000 --- a/assets/js/80e6044e.713e25c1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7915],{25377:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var o=t(74848),a=t(28453);const i={title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},r="Fee Elimination on Casper 2.0",s={permalink:"/blog/condor-fee-elimination",source:"@site/blog/2024-07-16-fee-elimination.md",title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",date:"2024-07-16T22:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"features",permalink:"/blog/tags/features"},{inline:!0,label:"tokenomics",permalink:"/blog/tags/tokenomics"}],readingTime:8.84,hasTruncateMarker:!0,authors:[{name:"Dylan Ireland",page:{permalink:"/blog/authors/dylanireland"},title:"Developer Advocate for Casper Association",url:"https://github.com/dylanireland",permalink:"/dylanireland",imageURL:"https://github.com/dylanireland.png",key:"dylanireland"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"},nextItem:{title:"Setting Up a Local Casper Condor Network for Development",permalink:"/blog/condor-local-setup"}},l={authorsImageUrls:[void 0,void 0]},d=[];function c(e){const n={p:"p",strong:"strong",...(0,a.R)(),...e.components};return(0,o.jsxs)(n.p,{children:["The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as ",(0,o.jsx)(n.strong,{children:"Fee Elimination"})," for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released."]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>s});var o=t(96540);const a={},i=o.createContext(a);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/80e6044e.be8973b1.js b/assets/js/80e6044e.be8973b1.js new file mode 100644 index 000000000..676788220 --- /dev/null +++ b/assets/js/80e6044e.be8973b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87915],{25377:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>p,frontMatter:()=>i,metadata:()=>s,toc:()=>d});var o=t(74848),a=t(28453);const i={title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},r="Fee Elimination on Casper 2.0",s={permalink:"/blog/condor-fee-elimination",source:"@site/blog/2024-07-16-fee-elimination.md",title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",date:"2024-07-16T22:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"features",permalink:"/blog/tags/features"},{inline:!0,label:"tokenomics",permalink:"/blog/tags/tokenomics"}],readingTime:8.84,hasTruncateMarker:!0,authors:[{name:"Dylan Ireland",page:{permalink:"/blog/authors/dylanireland"},title:"Developer Advocate for Casper Association",url:"https://github.com/dylanireland",permalink:"/dylanireland",imageURL:"https://github.com/dylanireland.png",key:"dylanireland"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Fee Elimination in Condor",description:"A discussion of the Fee Elimination feature in Casper 2.0",slug:"condor-fee-elimination",date:"2024-07-16T22:00",authors:["dylanireland","melpadden"],tags:["condor","features","tokenomics"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"},nextItem:{title:"Setting Up a Local Casper Condor Network for Development",permalink:"/blog/condor-local-setup"}},l={authorsImageUrls:[void 0,void 0]},d=[];function c(e){const n={p:"p",strong:"strong",...(0,a.R)(),...e.components};return(0,o.jsxs)(n.p,{children:["The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as ",(0,o.jsx)(n.strong,{children:"Fee Elimination"})," for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released."]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>s});var o=t(96540);const a={},i=o.createContext(a);function r(e){const n=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/814e64cc.3ab7cd73.js b/assets/js/814e64cc.3ab7cd73.js new file mode 100644 index 000000000..bf2271c85 --- /dev/null +++ b/assets/js/814e64cc.3ab7cd73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24439],{92683:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var i=n(74848),s=n(28453);const a={title:"Delegate with Ledger",slug:"/users/staking-ledger"},r="Delegating with Ledger Devices",o={id:"users/ledger/staking-ledger",title:"Delegate with Ledger",description:"Ledger Initialization",source:"@site/versioned_docs/version-2.0.0/users/ledger/staking-ledger.md",sourceDirName:"users/ledger",slug:"/users/staking-ledger",permalink:"/2.0.0/users/staking-ledger",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Delegate with Ledger",slug:"/users/staking-ledger"},sidebar:"users",previous:{title:"Ledger and CSPR.live",permalink:"/2.0.0/users/ledger/ledger-cspr-live"}},l={},d=[{value:"Ledger Initialization",id:"1-initialization",level:2},{value:"<strong>Important Notes</strong>",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-with-ledger-devices",children:"Delegating with Ledger Devices"})}),"\n",(0,i.jsx)(t.h2,{id:"1-initialization",children:"Ledger Initialization"}),"\n",(0,i.jsx)(t.p,{children:"Before getting started, you need to complete two prerequisite steps:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Set up your Ledger device using the ",(0,i.jsx)(t.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"official documentation"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect the Ledger to your ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," account by following the ",(0,i.jsx)(t.a,{href:"/2.0.0/workflow/ledger-setup/",children:"Ledger Setup"})," guide."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"important-notes",children:(0,i.jsx)(t.strong,{children:"Important Notes"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,i.jsxs)(t.li,{children:["When logging in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.jsx)(t.a,{href:"https://www.ledger.com/academy/crypto/where-are-my-coins",children:"more info here"}),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"2-staking",children:"Staking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"connect-and-login-with-ledger",children:"Connect and Login with Ledger"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger to your computer via USB and enter your PIN to unlock it."}),"\n",(0,i.jsx)(t.li,{children:'Open the Casper app on the Ledger (you will see the message "Casper Ready").'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready",src:n(17505).A+"",width:"1849",height:"1479"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Sign in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 2",src:n(60074).A+"",width:"1850",height:"726"})}),"\n",(0,i.jsxs)(t.ol,{start:"4",children:["\n",(0,i.jsx)(t.li,{children:"Select the public key connected to your Ledger account."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 3",src:n(91987).A+"",width:"1999",height:"1295"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsx)(t.li,{children:"View your account by clicking on your public key at the top right corner."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 4",src:n(94588).A+"",width:"1982",height:"1384"})}),"\n",(0,i.jsx)(t.h3,{id:"receive-tokens-from-an-external-source",children:"Receive Tokens from an External Source"}),"\n",(0,i.jsxs)(t.p,{children:["This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.jsx)(t.a,{href:"/2.0.0/workflow/ledger-setup/#receive-tokens",children:"documentation"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"staking-tokens",children:"Staking Tokens"}),"\n",(0,i.jsx)(t.p,{children:"Once you have tokens in your account, staking (delegating) with a validator is easy."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:['Go back to your account, but this time open the "delegate" tab located at: ',(0,i.jsx)(t.a,{href:"https://cspr.live/delegate-stake",children:"https://cspr.live/delegate-stake"})," (alternatively, click on ",(0,i.jsx)(t.code,{children:"Wallet \u21d2 Delegate Stake"})," to go there)."]}),"\n",(0,i.jsx)(t.li,{children:"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you."}),"\n",(0,i.jsxs)(t.li,{children:['Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:\n',(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."}),"\n",(0,i.jsx)(t.li,{children:"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.li,{children:'Click "Next" to continue, as shown below.'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 5",src:n(30501).A+"",width:"1255",height:"995"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.'}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.']}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 6",src:n(2670).A+"",width:"1190",height:"1778"})}),"\n",(0,i.jsxs)(t.ol,{start:"7",children:["\n",(0,i.jsxs)(t.li,{children:['On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 7",src:n(2167).A+"",width:"1999",height:"791"})}),"\n",(0,i.jsxs)(t.ol,{start:"8",children:["\n",(0,i.jsx)(t.li,{children:'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.img,{alt:"Casper Ready 8",src:n(85808).A+"",width:"1230",height:"370"}),"\n",(0,i.jsx)(t.img,{alt:"Casper Ready 9",src:n(92057).A+"",width:"1324",height:"427"})]}),"\n",(0,i.jsxs)(t.ol,{start:"9",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 10",src:n(31157).A+"",width:"1999",height:"1203"})}),"\n",(0,i.jsx)(t.h2,{id:"3-unstaking",children:"Unstaking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"initiate-the-undelegation",children:"Initiate the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 11",src:n(35884).A+"",width:"1211",height:"861"})}),"\n",(0,i.jsx)(t.p,{children:'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 12",src:n(86567).A+"",width:"1212",height:"958"})}),"\n",(0,i.jsx)(t.p,{children:'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'}),"\n",(0,i.jsx)(t.h3,{id:"sign-the-undelegation",children:"Sign the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:"You will have to sign the transaction to verify your account is initiating this action."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger device to your computer."}),"\n",(0,i.jsx)(t.li,{children:"Unlock your Ledger by entering your PIN."}),"\n",(0,i.jsx)(t.li,{children:'Open the "Casper" app and ensure you see "Casper Ready".'}),"\n",(0,i.jsxs)(t.li,{children:["Then back on ",(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),' click the "Sign with Ledger" button shown below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 13",src:n(10782).A+"",width:"1202",height:"1318"})}),"\n",(0,i.jsx)(t.p,{children:'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 14",src:n(55345).A+"",width:"1208",height:"921"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 15",src:n(6952).A+"",width:"1205",height:"736"})}),"\n",(0,i.jsx)(t.p,{children:"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},17505:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger1-39686f6ffc5ad108d8e08973a40103f5.png"},31157:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger10-ee4f4fd9d8bf12ad0f33c5e3b4ada52c.png"},35884:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger11-475f40691a8f46d17fdeb029786ac923.png"},86567:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger12-7fe9fa74a7040dcf0fdb703c2ad1464f.png"},10782:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger13-4e3e030cf508f30ff250d22230e7dec9.png"},55345:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger14-35808a8e588d4316a63c8c7c1b050dd2.png"},6952:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger15-5d758ba4698580290a72e3d4d564c9b1.png"},60074:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger2-f1e2691594ec0cdcc0bec706cd2aade5.png"},91987:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger3-9b464ab0befd3928a5c659c77cf9555c.png"},94588:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger4-9a921643c0431d1eac3009da497cb280.png"},30501:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger5-9853a9b9bebe07a3a24f1febfac4ca03.png"},2670:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger6-b50bdcc2ba945ebf349fc3396785adc0.png"},2167:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger7-2d020b9e8d2b40169e089bda6ff77dda.png"},85808:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger8-c3399bf73ccd1e844f6f5790c7ad1796.png"},92057:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger9-97001e377d0f7629626696f888dde09a.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var i=n(96540);const s={},a=i.createContext(s);function r(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/814f3328.42442acd.js b/assets/js/814f3328.42442acd.js new file mode 100644 index 000000000..996f37c55 --- /dev/null +++ b/assets/js/814f3328.42442acd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67472],{55513:e=>{e.exports=JSON.parse('{"title":"All posts","items":[{"title":"validator rewards in Casper 2.0","permalink":"/blog/condor-validator-rewards","unlisted":false,"date":"2024-08-20T18:00:00.000Z"},{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux","unlisted":false,"date":"2024-08-15T18:00:00.000Z"},{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity","unlisted":false,"date":"2024-07-17T18:00:00.000Z"},{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination","unlisted":false,"date":"2024-07-16T22:00:00.000Z"},{"title":"Setting Up a Local Casper Condor Network for Development","permalink":"/blog/condor-local-setup","unlisted":false,"date":"2024-07-16T18:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/assets/js/814f3328.f0c18ae2.js b/assets/js/814f3328.f0c18ae2.js deleted file mode 100644 index 7ea5eb780..000000000 --- a/assets/js/814f3328.f0c18ae2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7472],{55513:e=>{e.exports=JSON.parse('{"title":"All posts","items":[{"title":"validator rewards in Casper 2.0","permalink":"/blog/condor-validator-rewards","unlisted":false,"date":"2024-08-20T18:00:00.000Z"},{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux","unlisted":false,"date":"2024-08-15T18:00:00.000Z"},{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity","unlisted":false,"date":"2024-07-17T18:00:00.000Z"},{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination","unlisted":false,"date":"2024-07-16T22:00:00.000Z"},{"title":"Setting Up a Local Casper Condor Network for Development","permalink":"/blog/condor-local-setup","unlisted":false,"date":"2024-07-16T18:00:00.000Z"}]}')}}]); \ No newline at end of file diff --git a/assets/js/8154f86c.6126d122.js b/assets/js/8154f86c.6126d122.js new file mode 100644 index 000000000..33c01135e --- /dev/null +++ b/assets/js/8154f86c.6126d122.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94490],{63137:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(74848),o=s(28453);const r={title:"Configuration"},t="Basic Node Configuration",c={id:"operators/setup/basic-node-configuration",title:"Configuration",description:"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.",source:"@site/versioned_docs/version-2.0.0/operators/setup/basic-node-configuration.md",sourceDirName:"operators/setup",slug:"/operators/setup/basic-node-configuration",permalink:"/2.0.0/operators/setup/basic-node-configuration",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Configuration"},sidebar:"operators",previous:{title:"Hardware",permalink:"/2.0.0/operators/setup/hardware"},next:{title:"Endpoints",permalink:"/2.0.0/operators/setup/node-endpoints"}},l={},d=[{value:"The Casper Node Launcher",id:"casper-node-launcher",level:2},{value:"File Locations",id:"file-locations",level:2},{value:"<code>/usr/bin/</code>",id:"usrbin",level:3},{value:"<code>/etc/casper/</code>",id:"etccasper",level:3},{value:"<code>/var/lib/casper/</code>",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the <code>config.toml</code> file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-node-configuration",children:"Basic Node Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node",children:"Node Setup"})," guide."]}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-launcher",children:"The Casper Node Launcher"}),"\n",(0,i.jsxs)(n.p,{children:["A node is usually run by executing the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),", which executes the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process and also handles upgrades to bring the node to the latest version released."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," can be installed via a Debian package, which also creates the ",(0,i.jsx)(n.code,{children:"casper"})," user and directory structures and sets up a ",(0,i.jsx)(n.code,{children:"systemd"})," unit and logging."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian package can be obtained from ",(0,i.jsx)(n.a,{href:"https://repo.casperlabs.io",children:"https://repo.casperlabs.io"}),". You only need to run the steps detailed there once."]}),"\n",(0,i.jsxs)(n.p,{children:["Then, proceed to install the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," by running these commands:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install casper-node-launcher\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also build ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"from source"}),". However, all the setup and pull of casper-node releases will be manual."]}),"\n",(0,i.jsx)(n.h2,{id:"file-locations",children:"File Locations"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian installation creates the directories and files needed to run ",(0,i.jsx)(n.code,{children:"casper-node"})," versions and perform upgrades. A ",(0,i.jsx)(n.code,{children:"casper"})," user and ",(0,i.jsx)(n.code,{children:"casper"})," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,i.jsx)(n.code,{children:"/etc/casper"})," and ",(0,i.jsx)(n.code,{children:"/var/lib/casper"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"The casper-node install version"})}),"\n",(0,i.jsxs)(n.p,{children:["Each version of the ",(0,i.jsx)(n.code,{children:"casper-node"})," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,i.jsx)(n.code,{children:"1_0_3"}),". This convention applies to both binary and configuration file locations. Versioning with ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," represents the major, minor, and patch of a semantic version."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Multiple versioned folders will exist on a system when upgrades are set up."})}),"\n",(0,i.jsxs)(n.p,{children:["The following is the filesystem's state after installing the ",(0,i.jsx)(n.code,{children:"casper-client"})," and ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian packages, and after running the command ",(0,i.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf"})," (Use casper-test.conf if on Testnet)."]}),"\n",(0,i.jsx)(n.h3,{id:"usrbin",children:(0,i.jsx)(n.code,{children:"/usr/bin/"})}),"\n",(0,i.jsxs)(n.p,{children:["The default location for executables from the Debian package install is ",(0,i.jsx)(n.code,{children:"/usr/bin"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-client"})," - A client for interacting with a Casper network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher"})," - The launcher application which starts the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"etccasper",children:(0,i.jsx)(n.code,{children:"/etc/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the default location for configuration files. It can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_CONFIG_DIR"})," environment variable. The paths in this document assume the default configuration file location of ",(0,i.jsx)(n.code,{children:"/etc/casper"}),". The data is organized as follows:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"delete_local_db.sh"})," - Removes ",(0,i.jsx)(n.code,{children:"*.lmdb*"})," files from ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"})," - Pulls ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," from ",(0,i.jsx)(n.a,{href:"https://genesis.casperlabs.io/",children:"genesis.casperlabs.io"})," for a specified protocol version and extracts them into ",(0,i.jsx)(n.code,{children:"/var/lib/bin/<protocol_version>"})," and ",(0,i.jsx)(n.code,{children:"/etc/casper/<protocol_version>"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config_from_example.sh"})," - Gets external IP to replace and create the ",(0,i.jsx)(n.code,{children:"config.toml"})," from ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node_util.py"})," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"}),", ",(0,i.jsx)(n.code,{children:"config_from_example.sh"}),", and ",(0,i.jsx)(n.code,{children:"delete_local_db.sh"}),". Other scripts will be deprecated in future releases of ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher-state.toml"})," - The local state for the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," which is created during the first run"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_keys/"})," - The default folder for node keys, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Instructions on how to create validator keys using the ",(0,i.jsx)(n.code,{children:"casper-client"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret_key.pem"})," - Secret key used by the validator node to sign blocks and peer-to-peer messages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key.pem"})," - Public key associated with the secret key above, stored in PEM format"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key_hex"})," - Public key associated with the secret key above, stored in hex format"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"accounts.toml"})," - Contains the genesis validators and delegators"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," (network start time) as a timestamp"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - Example for creating a ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,i.jsx)(n.code,{children:"config_from_example.sh 1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package's configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," as an era ID (the era at which this protocol version of the node became or will become active)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config-example.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"varlibcasper",children:(0,i.jsx)(n.code,{children:"/var/lib/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the location for larger and variable data for the ",(0,i.jsx)(n.code,{children:"casper-node"}),", organized in the following folders and files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bin/"})," - The parent folder storing the versions of ",(0,i.jsx)(n.code,{children:"casper-node"})," executables. This location can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_BIN_DIR"})," environment variable. The paths in this document assume the default of ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis binary files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - The node executable - defaults to the Ubuntu 20.04 compatible binary"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/casper-node"}),", but the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/README.md"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"casper-node/<NETWORK NAME>"})," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,i.jsx)(n.code,{children:"casper"})," and for Testnet it is ",(0,i.jsx)(n.code,{children:"casper-test"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmdb"})," - Persistent global state store of the network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmbd-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"data.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb"})," - Persistent store of all other network data, primarily Blocks and transactions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"storage.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"unit_files/"})," - Folder containing transient caches of consensus information"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"node-version-installation",children:"Node Version Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is ",(0,i.jsx)(n.code,{children:"node_util.py"})," for installing ",(0,i.jsx)(n.code,{children:"casper-node"})," versions. This command will stage all current ",(0,i.jsx)(n.code,{children:"casper-node"})," versions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"<NETWORK_CONFIG>"}),", we use ",(0,i.jsx)(n.code,{children:"casper.conf"})," for Mainnet and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," for Testnet. This will install all currently released protocols in one step."]}),"\n",(0,i.jsx)(n.p,{children:"This command will do the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," containing at a minimum ",(0,i.jsx)(n.code,{children:"casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," containing ",(0,i.jsx)(n.code,{children:"chainspec.toml"}),", ",(0,i.jsx)(n.code,{children:"config-example.toml"}),", and possibly ",(0,i.jsx)(n.code,{children:"accounts.csv"})," and other files"]}),"\n",(0,i.jsxs)(n.li,{children:["Remove the archive files and run ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh 1_0_2"})," to create a ",(0,i.jsx)(n.code,{children:"config.toml"})," from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Release versions are invoked using the underscore format, such as:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-file",children:"The Node Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["One ",(0,i.jsx)(n.code,{children:"config.toml"})," file exists for each ",(0,i.jsx)(n.code,{children:"casper-node"})," version installed. It is located in the ",(0,i.jsx)(n.code,{children:"/etc/casper/[m_n_p]/"})," directory, where ",(0,i.jsx)(n.code,{children:"m_n_p"})," is the current semantic version. This can be created from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})," by using ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh [m_n_p]"})," where ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," is replaced with the current version, using underscores."]}),"\n",(0,i.jsxs)(n.p,{children:["Below are some fields in the ",(0,i.jsx)(n.code,{children:"config.toml"})," that you may need to adjust."]}),"\n",(0,i.jsx)(n.h3,{id:"trusted-hash-for-synchronizing",children:"The Trusted Hash for Synchronizing"}),"\n",(0,i.jsx)(n.p,{children:"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."}),"\n",(0,i.jsx)(n.p,{children:"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Find a list of trusted validators"}),"\n",(0,i.jsxs)(n.li,{children:["Query the status endpoint of a trusted validator (",(0,i.jsx)(n.code,{children:"http://<NODE_IP_ADDRESS>:8888/status"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Obtain the hash of a block from the status endpoint"}),"\n",(0,i.jsxs)(n.li,{children:["Update the ",(0,i.jsx)(n.code,{children:"config.toml"})," for the node to include the trusted hash. There is a field dedicated to this near the top of the file"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"known-addresses",children:"Known Addresses"}),"\n",(0,i.jsxs)(n.p,{children:["For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", these are listed in the ",(0,i.jsx)(n.code,{children:"config.toml"})," as ",(0,i.jsx)(n.code,{children:"known_addresses"}),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"example configuration"}),". The ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release",children:"casper-protocol-release"})," repository stores configurations for various environments, which you can also use as examples."]}),"\n",(0,i.jsxs)(n.h3,{id:"updating-config-file",children:["Updating the ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.p,{children:["At the top of a ",(0,i.jsx)(n.code,{children:"config.toml"})," file as shown here, enter the trusted block hash to replace the ",(0,i.jsx)(n.code,{children:"'HEX-FORMATTED BLOCK HASH'"})," and uncomment the line by deleting the leading '#'. See the ",(0,i.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#config-file",children:"Configuration File"})," for more details."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secret-keys",children:"Secret Keys"}),"\n",(0,i.jsxs)(n.p,{children:["Provide the path to the secret keys for the node. This path is set to ",(0,i.jsx)(n.code,{children:"etc/casper/validator_keys/"})," by default. See ",(0,i.jsx)(n.a,{href:"#create-fund-keys",children:"Creating Keys and Funding Accounts"})," for more details."]}),"\n",(0,i.jsx)(n.h3,{id:"networking--gossiping",children:"Networking and Gossiping"}),"\n",(0,i.jsxs)(n.p,{children:["The node requires a publicly accessible IP address. The ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," and ",(0,i.jsx)(n.code,{children:"node_util.py"})," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," external services are called to find your IP and this is inserted into the ",(0,i.jsx)(n.code,{children:"config.toml"})," created."]}),"\n",(0,i.jsx)(n.p,{children:"The following default values are specified in the file if you want to change them:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The port that will be used for status and transactions"}),"\n",(0,i.jsx)(n.li,{children:"The port used for networking"}),"\n",(0,i.jsx)(n.li,{children:"Known_addresses - these are the bootstrap nodes (there is no need to change these)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"enabling-speculative-execution",children:"Enabling Speculative Execution"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a transaction without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the transaction in question. By default, ",(0,i.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"speculative_exec"})," can be enabled within ",(0,i.jsx)(n.em,{children:"config.toml"})," by changing ",(0,i.jsx)(n.code,{children:"enable_server"})," to ",(0,i.jsx)(n.code,{children:"true"})," under the configuration options for the speculative execution JSON-RPC HTTP server."]}),"\n",(0,i.jsxs)(n.p,{children:["Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,i.jsx)(n.code,{children:"7778"}),". Further, you can choose to alter the ",(0,i.jsx)(n.code,{children:"qps_limit"})," and ",(0,i.jsx)(n.code,{children:"max_body_bytes"}),", which limit the amount and size of requests to the speculative execution server."]}),"\n",(0,i.jsx)(n.h4,{id:"example-configtoml-configuration-with-speculative-execution-enabled",children:"Example Config.toml configuration with speculative execution enabled"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client-installation",children:"Rust Client Installation"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Prerequisites"})," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."]}),"\n",(0,i.jsx)(n.h2,{id:"create-fund-keys",children:"Creating Keys and Funding Accounts"}),"\n",(0,i.jsxs)(n.p,{children:["The following command will create keys in the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys"})," folder."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To learn about other options for generating keys, see ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," or run the Rust client ",(0,i.jsx)(n.code,{children:"keygen"})," command with the ",(0,i.jsx)(n.code,{children:"--help"})," option."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More about keys and key generation can also be found in ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/README.md"})," if the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," was installed from the Debian package."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Save your keys in a secure location, preferably offline."})}),"\n",(0,i.jsxs)(n.p,{children:["To submit a bonding request, you will need to ",(0,i.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#fund-your-account",children:"fund your account"})," as well."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/821dc1e3.07ce4564.js b/assets/js/821dc1e3.07ce4564.js new file mode 100644 index 000000000..76047b872 --- /dev/null +++ b/assets/js/821dc1e3.07ce4564.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30898],{56752:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var a=n(74848),r=n(28453);const s={title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},o="Safely Transfer Tokens to a Contract",i={id:"resources/advanced/transfer-token-to-contract",title:"Token Transfers",description:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/transfer-token-to-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/transfer-token-to-contract",permalink:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},sidebar:"tutorials",previous:{title:"Authorization Keys",permalink:"/1.5.X/resources/advanced/list-auth-keys-tutorial"},next:{title:"Storage Workflow",permalink:"/1.5.X/resources/tutorials/advanced/storage-workflow"}},c={},h=[{value:"Scenario 1 - Creating a Throw-Away Purse",id:"scenario1",level:2},{value:"Scenario 1 - Advanced Variation",id:"scenario1-advanced",level:3},{value:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic",id:"scenario2",level:2},{value:"Scenario 2 - Advanced Variation",id:"scenario2-advanced",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"safely-transfer-tokens-to-a-contract",children:"Safely Transfer Tokens to a Contract"})}),"\n",(0,a.jsx)(t.p,{children:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs."}),"\n",(0,a.jsxs)(t.p,{children:["For increased security, token transfers from a main purse must be handled via session code (WASM), as shown ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code#transfers-using-session-code",children:"here"}),". Therefore, ",(0,a.jsx)(t.code,{children:"transfer-*"})," methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario1",children:"Scenario 1 - Creating a Throw-Away Purse"}),"\n",(0,a.jsx)(t.p,{children:"The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee."}),"\n",(0,a.jsx)(t.p,{children:"In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues."}),"\n",(0,a.jsx)(t.p,{children:"This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation."}),"\n",(0,a.jsx)(t.p,{children:"Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_name of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n let entry_point_name = runtime::get_named_arg("entry_point_name");\n\n // This creates a new empty purse that the caller will use just this one time.\n let new_purse = system::create_purse();\n \n // Transfer from the caller\'s main purse to the new purse that was just created.\n // Note that transfer is done safely by the host logic.\n system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)\n .unwrap_or_revert();\n \n // Pass the newly created purse to the smart contract with full access rights; \n // the called contract should receive the new purse, extract the token from it, and then do\n // whatever else it is meant to do if a valid amount was transferred to it. Note that the\n // caller\'s main purse is never exposed to the called contract; the newly created purse\n // is provided instead.\n runtime::call_contract(contract_hash, entry_point_name, runtime_args! {\n // The arg names are defined by the contract that you are calling,\n // there is no canonical name. The contract you are calling may have other\n // runtime args that it requires.\n "????" => new_purse\n });\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario1-advanced",children:"Scenario 1 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs",children:"This example"})," provides a framework for the idea, but will require modification to suit developer needs."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario2",children:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"}),"\n",(0,a.jsx)(t.p,{children:"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."}),"\n",(0,a.jsxs)(t.p,{children:["In ",(0,a.jsx)(t.a,{href:"#scenario1",children:"Scenario 1"}),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,a.jsx)(t.a,{href:"#scenario1-advanced",children:"Scenario 1's Advanced Variation"})," in that the purse in question is under the control of the contract rather than the caller."]}),"\n",(0,a.jsx)(t.p,{children:"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic. \n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments. \n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario2-advanced",children:"Scenario 2 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."}),"\n",(0,a.jsx)(t.p,{children:"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var a=n(96540);const r={},s=a.createContext(r);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/821dc1e3.484815c2.js b/assets/js/821dc1e3.484815c2.js deleted file mode 100644 index d580af344..000000000 --- a/assets/js/821dc1e3.484815c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[898],{56752:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var a=n(74848),r=n(28453);const s={title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},o="Safely Transfer Tokens to a Contract",i={id:"resources/advanced/transfer-token-to-contract",title:"Token Transfers",description:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/transfer-token-to-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/transfer-token-to-contract",permalink:"/resources/tutorials/advanced/transfer-token-to-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},sidebar:"tutorials",previous:{title:"Authorization Keys",permalink:"/resources/advanced/list-auth-keys-tutorial"},next:{title:"Storage Workflow",permalink:"/resources/tutorials/advanced/storage-workflow"}},c={},h=[{value:"Scenario 1 - Creating a Throw-Away Purse",id:"scenario1",level:2},{value:"Scenario 1 - Advanced Variation",id:"scenario1-advanced",level:3},{value:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic",id:"scenario2",level:2},{value:"Scenario 2 - Advanced Variation",id:"scenario2-advanced",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"safely-transfer-tokens-to-a-contract",children:"Safely Transfer Tokens to a Contract"})}),"\n",(0,a.jsx)(t.p,{children:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs."}),"\n",(0,a.jsxs)(t.p,{children:["For increased security, token transfers from a main purse must be handled via session code (WASM), as shown ",(0,a.jsx)(t.a,{href:"/developers/writing-onchain-code/writing-session-code#transfers-using-session-code",children:"here"}),". Therefore, ",(0,a.jsx)(t.code,{children:"transfer-*"})," methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario1",children:"Scenario 1 - Creating a Throw-Away Purse"}),"\n",(0,a.jsx)(t.p,{children:"The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee."}),"\n",(0,a.jsx)(t.p,{children:"In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues."}),"\n",(0,a.jsx)(t.p,{children:"This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation."}),"\n",(0,a.jsx)(t.p,{children:"Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_name of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n let entry_point_name = runtime::get_named_arg("entry_point_name");\n\n // This creates a new empty purse that the caller will use just this one time.\n let new_purse = system::create_purse();\n \n // Transfer from the caller\'s main purse to the new purse that was just created.\n // Note that transfer is done safely by the host logic.\n system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)\n .unwrap_or_revert();\n \n // Pass the newly created purse to the smart contract with full access rights; \n // the called contract should receive the new purse, extract the token from it, and then do\n // whatever else it is meant to do if a valid amount was transferred to it. Note that the\n // caller\'s main purse is never exposed to the called contract; the newly created purse\n // is provided instead.\n runtime::call_contract(contract_hash, entry_point_name, runtime_args! {\n // The arg names are defined by the contract that you are calling,\n // there is no canonical name. The contract you are calling may have other\n // runtime args that it requires.\n "????" => new_purse\n });\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario1-advanced",children:"Scenario 1 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs",children:"This example"})," provides a framework for the idea, but will require modification to suit developer needs."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario2",children:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"}),"\n",(0,a.jsx)(t.p,{children:"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."}),"\n",(0,a.jsxs)(t.p,{children:["In ",(0,a.jsx)(t.a,{href:"#scenario1",children:"Scenario 1"}),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,a.jsx)(t.a,{href:"#scenario1-advanced",children:"Scenario 1's Advanced Variation"})," in that the purse in question is under the control of the contract rather than the caller."]}),"\n",(0,a.jsx)(t.p,{children:"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic. \n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments. \n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario2-advanced",children:"Scenario 2 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."}),"\n",(0,a.jsx)(t.p,{children:"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var a=n(96540);const r={},s=a.createContext(r);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/82237.082e051d.js b/assets/js/82237.082e051d.js new file mode 100644 index 000000000..7e0b4c796 --- /dev/null +++ b/assets/js/82237.082e051d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82237],{23363:(e,t,n)=>{n.d(t,{A:()=>a});n(96540);var s=n(34164),i=n(21312),o=n(51107),r=n(74848);function a(e){let{className:t}=e;return(0,r.jsx)("main",{className:(0,s.A)("container margin-vert--xl",t),children:(0,r.jsx)("div",{className:"row",children:(0,r.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,r.jsx)(o.A,{as:"h1",className:"hero__title",children:(0,r.jsx)(i.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,r.jsx)("p",{children:(0,r.jsx)(i.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,r.jsx)("p",{children:(0,r.jsx)(i.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}},82237:(e,t,n)=>{n.r(t),n.d(t,{default:()=>c});n(96540);var s=n(21312),i=n(45500),o=n(79201),r=n(23363),a=n(74848);function c(){const e=(0,s.T)({id:"theme.NotFound.title",message:"Page Not Found"});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.be,{title:e}),(0,a.jsx)(o.A,{children:(0,a.jsx)(r.A,{})})]})}}}]); \ No newline at end of file diff --git a/assets/js/830e9e14.801017c6.js b/assets/js/830e9e14.801017c6.js new file mode 100644 index 000000000..b92fda394 --- /dev/null +++ b/assets/js/830e9e14.801017c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55732],{17703:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=n(74848),r=n(28453);const o={title:"Node Events"},a="The Node's Event Stream",i={id:"operators/setup/node-events",title:"Node Events",description:"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.",source:"@site/docs/operators/setup/node-events.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-events",permalink:"/operators/setup/node-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Node Events"},sidebar:"operators",previous:{title:"Non-Root Users",permalink:"/operators/setup/non-root-user"},next:{title:"Sidecar Setup",permalink:"/operators/setup/casper-sidecar"}},d={},c=[{value:"Monitoring a Node's Event Stream",id:"monitoring-a-nodes-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"the-nodes-event-stream",children:"The Node's Event Stream"})}),"\n",(0,s.jsxs)(t.p,{children:["Each Casper node streams events through the SSE (Server Sent Event) server via an ",(0,s.jsx)(t.code,{children:"/events"})," endpoint and the port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),". This port is by default ",(0,s.jsx)(t.code,{children:"9999"})," for nodes on ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet"})," and ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"Mainnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"monitoring-a-nodes-event-stream",children:"Monitoring a Node's Event Stream"}),"\n",(0,s.jsx)(t.p,{children:"As an operator, you can use cURL to monitor the event stream on a node."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -s http://HOST:PORT/events/\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"HOST"})," - The IP address of a node on the network."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"PORT"})," - The port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Another helpful tool is the ",(0,s.jsx)(t.a,{href:"/operators/setup/casper-sidecar",children:"Casper Sidecar"}),", which provides the recommended way to monitor events on a node. Visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md#the-sidecar-event-stream",children:"Casper Sidecar Usage Guide"})," for a detailed list of events and REST queries you can use to monitor the node and the state of the network."]}),"\n",(0,s.jsx)(t.h2,{id:"replaying-the-event-stream",children:"Replaying the Event Stream"}),"\n",(0,s.jsxs)(t.p,{children:["This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the ",(0,s.jsx)(t.code,{children:"HOST"}),", ",(0,s.jsx)(t.code,{children:"PORT"}),", and ",(0,s.jsx)(t.code,{children:"ID"})," fields with the needed values."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://HOST:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:9999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(t.admonition,{type:"note",children:[(0,s.jsxs)(t.p,{children:["The node stores only a limited number of events in its cache, which can be configured using the ",(0,s.jsx)(t.code,{children:"event_stream_buffer_length"})," in the ",(0,s.jsx)(t.em,{children:"config.toml"}),". The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected."]}),(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/operators/setup/casper-sidecar",children:"Casper Sidecar"})," may store additional events depending on how it was configured."]})]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},o=s.createContext(r);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/830e9e14.b215aae2.js b/assets/js/830e9e14.b215aae2.js deleted file mode 100644 index 80e50e3fd..000000000 --- a/assets/js/830e9e14.b215aae2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5732],{17703:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=n(74848),r=n(28453);const o={title:"Node Events"},a="The Node's Event Stream",i={id:"operators/setup/node-events",title:"Node Events",description:"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.",source:"@site/docs/operators/setup/node-events.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-events",permalink:"/next/operators/setup/node-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Node Events"},sidebar:"operators",previous:{title:"Non-Root Users",permalink:"/next/operators/setup/non-root-user"},next:{title:"Sidecar Setup",permalink:"/next/operators/setup/casper-sidecar"}},d={},c=[{value:"Monitoring a Node's Event Stream",id:"monitoring-a-nodes-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"the-nodes-event-stream",children:"The Node's Event Stream"})}),"\n",(0,s.jsxs)(t.p,{children:["Each Casper node streams events through the SSE (Server Sent Event) server via an ",(0,s.jsx)(t.code,{children:"/events"})," endpoint and the port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),". This port is by default ",(0,s.jsx)(t.code,{children:"9999"})," for nodes on ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet"})," and ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"Mainnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"monitoring-a-nodes-event-stream",children:"Monitoring a Node's Event Stream"}),"\n",(0,s.jsx)(t.p,{children:"As an operator, you can use cURL to monitor the event stream on a node."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -s http://HOST:PORT/events/\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"HOST"})," - The IP address of a node on the network."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"PORT"})," - The port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Another helpful tool is the ",(0,s.jsx)(t.a,{href:"/next/operators/setup/casper-sidecar",children:"Casper Sidecar"}),", which provides the recommended way to monitor events on a node. Visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md#the-sidecar-event-stream",children:"Casper Sidecar Usage Guide"})," for a detailed list of events and REST queries you can use to monitor the node and the state of the network."]}),"\n",(0,s.jsx)(t.h2,{id:"replaying-the-event-stream",children:"Replaying the Event Stream"}),"\n",(0,s.jsxs)(t.p,{children:["This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the ",(0,s.jsx)(t.code,{children:"HOST"}),", ",(0,s.jsx)(t.code,{children:"PORT"}),", and ",(0,s.jsx)(t.code,{children:"ID"})," fields with the needed values."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://HOST:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:9999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(t.admonition,{type:"note",children:[(0,s.jsxs)(t.p,{children:["The node stores only a limited number of events in its cache, which can be configured using the ",(0,s.jsx)(t.code,{children:"event_stream_buffer_length"})," in the ",(0,s.jsx)(t.em,{children:"config.toml"}),". The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected."]}),(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/next/operators/setup/casper-sidecar",children:"Casper Sidecar"})," may store additional events depending on how it was configured."]})]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},o=s.createContext(r);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8323e0f5.5f3557eb.js b/assets/js/8323e0f5.5f3557eb.js deleted file mode 100644 index dc2fa7a74..000000000 --- a/assets/js/8323e0f5.5f3557eb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9749],{30491:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});var a=s(74848),r=s(28453);const d={title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},c="Querying a Casper Node",t={id:"resources/beginner/querying-network",title:"Querying a Node",description:"The Casper node supports queries for users and developers to obtain information stored on the blockchain.",source:"@site/docs/resources/beginner/querying-network.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/querying-network",permalink:"/next/resources/tutorials/beginner/querying-network",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/next/resources/beginner/counter-testnet/walkthrough"},next:{title:"Contract Upgrades",permalink:"/next/resources/tutorials/beginner/upgrade-contract"}},i={},o=[{value:"Obtaining the Global State Root Hash",id:"obtaining-the-global-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying Blocks",id:"querying-blocks",level:2},{value:"Querying Deploys",id:"querying-deploys",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"querying-a-casper-node",children:"Querying a Casper Node"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper node supports queries for users and developers to obtain information stored on the blockchain."}),"\n",(0,a.jsx)(n.p,{children:"This document assumes:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["You have met the ",(0,a.jsx)(n.a,{href:"/next/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,a.jsxs)(n.li,{children:["You are familiar with the structure of the ",(0,a.jsx)(n.a,{href:"/next/design",children:"Global State and the Blockchain Design"})," to query data from the network"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Account details"}),"\n",(0,a.jsx)(n.li,{children:"Block information"}),"\n",(0,a.jsx)(n.li,{children:"Deploy information"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"obtaining-the-global-state-root-hash",children:"Obtaining the Global State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node."}),"\n",(0,a.jsxs)(n.p,{children:["All queries made to global state require the ",(0,a.jsx)(n.code,{children:"state-root-hash"}),", which you can obtain with this command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash \\\n --id 1 \\\n --node-address http://<node-ip-address>:7777\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Accounts"})," are stored in the global state and can be queried using the ",(0,a.jsx)(n.code,{children:"query-global-state"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --id 4 \\\n --node-address http://<node-ip-address>:7777 \\\n --state-root-hash <state-root-hash> \\\n --key <hex-encoded-source-account-public-key>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Account Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To query the account balance, use the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address http://<node-ip-address>:7777 \\\n--state-root-hash <state-root-hash> \\\n--purse-identifier <account>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Balance Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-blocks",children:"Querying Blocks"}),"\n",(0,a.jsx)(n.p,{children:"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-block \\\n --id 3 \\\n --node-address http://<node-ip-address>:7777 \\\n --block-identifier <block-hash> \\\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."block"."header"."state_root_hash"'})," - contains the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," for this block"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-deploys",children:"Querying Deploys"}),"\n",(0,a.jsxs)(n.p,{children:["Once you submit a deploy to the network, you can check its execution status using ",(0,a.jsx)(n.code,{children:"get-deploy"}),". If the ",(0,a.jsx)(n.code,{children:"execution_results"})," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --id 2 \\\n --node-address http://<node-ip-address>:7777 \\\n <deploy-hash>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"deploy-hash"})," - Hex-encoded hash of the deploy"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var a=s(96540);const r={},d=a.createContext(r);function c(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8323e0f5.8ddff4c3.js b/assets/js/8323e0f5.8ddff4c3.js new file mode 100644 index 000000000..e458dcb65 --- /dev/null +++ b/assets/js/8323e0f5.8ddff4c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[69749],{30491:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});var a=s(74848),r=s(28453);const d={title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},c="Querying a Casper Node",t={id:"resources/beginner/querying-network",title:"Querying a Node",description:"The Casper node supports queries for users and developers to obtain information stored on the blockchain.",source:"@site/docs/resources/beginner/querying-network.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/querying-network",permalink:"/resources/tutorials/beginner/querying-network",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough"},next:{title:"Contract Upgrades",permalink:"/resources/tutorials/beginner/upgrade-contract"}},i={},o=[{value:"Obtaining the Global State Root Hash",id:"obtaining-the-global-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying Blocks",id:"querying-blocks",level:2},{value:"Querying Deploys",id:"querying-deploys",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"querying-a-casper-node",children:"Querying a Casper Node"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper node supports queries for users and developers to obtain information stored on the blockchain."}),"\n",(0,a.jsx)(n.p,{children:"This document assumes:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["You have met the ",(0,a.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,a.jsxs)(n.li,{children:["You are familiar with the structure of the ",(0,a.jsx)(n.a,{href:"/design",children:"Global State and the Blockchain Design"})," to query data from the network"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Account details"}),"\n",(0,a.jsx)(n.li,{children:"Block information"}),"\n",(0,a.jsx)(n.li,{children:"Deploy information"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"obtaining-the-global-state-root-hash",children:"Obtaining the Global State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node."}),"\n",(0,a.jsxs)(n.p,{children:["All queries made to global state require the ",(0,a.jsx)(n.code,{children:"state-root-hash"}),", which you can obtain with this command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash \\\n --id 1 \\\n --node-address http://<node-ip-address>:7777\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Accounts"})," are stored in the global state and can be queried using the ",(0,a.jsx)(n.code,{children:"query-global-state"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --id 4 \\\n --node-address http://<node-ip-address>:7777 \\\n --state-root-hash <state-root-hash> \\\n --key <hex-encoded-source-account-public-key>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Account Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To query the account balance, use the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address http://<node-ip-address>:7777 \\\n--state-root-hash <state-root-hash> \\\n--purse-identifier <account>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Balance Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-blocks",children:"Querying Blocks"}),"\n",(0,a.jsx)(n.p,{children:"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-block \\\n --id 3 \\\n --node-address http://<node-ip-address>:7777 \\\n --block-identifier <block-hash> \\\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."block"."header"."state_root_hash"'})," - contains the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," for this block"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-deploys",children:"Querying Deploys"}),"\n",(0,a.jsxs)(n.p,{children:["Once you submit a deploy to the network, you can check its execution status using ",(0,a.jsx)(n.code,{children:"get-deploy"}),". If the ",(0,a.jsx)(n.code,{children:"execution_results"})," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --id 2 \\\n --node-address http://<node-ip-address>:7777 \\\n <deploy-hash>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"deploy-hash"})," - Hex-encoded hash of the deploy"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var a=s(96540);const r={},d=a.createContext(r);function c(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/85b8bb26.306e91f8.js b/assets/js/85b8bb26.306e91f8.js new file mode 100644 index 000000000..12ed54d8b --- /dev/null +++ b/assets/js/85b8bb26.306e91f8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75096],{29387:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var n=i(74848),r=i(28453);const s={title:"Dictionaries"},a="Understanding Dictionaries {#dictionaries}",o={id:"concepts/dictionaries",title:"Dictionaries",description:"dictionaries}",source:"@site/docs/concepts/dictionaries.md",sourceDirName:"concepts",slug:"/concepts/dictionaries",permalink:"/concepts/dictionaries",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Dictionaries"},sidebar:"concepts",previous:{title:"Call Stacks",permalink:"/concepts/callstack"}},c={},d=[{value:"Seed URefs",id:"seed-urefs",level:2},{value:"Using Dictionaries",id:"using-dictionaries",level:2},{value:"Practical Dictionary Examples",id:"practical-dictionary-examples",level:2},{value:"Creating Dictionaries in a Contract's Context",id:"creating-dictionaries-in-a-contracts-context",level:2},{value:"Writing Entries into a Dictionary",id:"writing-entries-into-a-dictionary",level:2},{value:"Reading Items from a Dictionary using the JSON-RPC",id:"reading-items-from-a-dictionary-using-the-json-rpc",level:2},{value:"<code>ContractNamedKey</code> lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"<code>URef</code> lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"<code>Dictionary</code> lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"dictionaries",children:"Understanding Dictionaries"})}),"\n",(0,n.jsxs)(t.p,{children:["In a Casper network, you can now store sets of data under ",(0,n.jsx)(t.a,{href:"/concepts/key-types#key-explanations",children:(0,n.jsx)(t.code,{children:"Keys"})}),". Previously, ",(0,n.jsx)(t.a,{href:"/concepts/glossary/U#uref",children:"URefs"})," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,n.jsx)(t.code,{children:"addressable entity"}),"'s context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,n.jsx)(t.a,{href:"/concepts/glossary/N#named-keys",children:"NamedKeys"})," structures."]}),"\n",(0,n.jsx)(t.p,{children:"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."}),"\n",(0,n.jsxs)(t.p,{children:["As a solution to this problem, the Casper platform provides the ",(0,n.jsx)(t.code,{children:"Dictionary"})," feature, which allows users a more efficient and scalable means to aggregate data over time."]}),"\n",(0,n.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,n.jsx)(t.code,{children:"NamedKeys"})," to a top-level key, removing this restriction and making them viable for data storage."]}),"\n",(0,n.jsx)(t.h2,{id:"seed-urefs",children:"Seed URefs"}),"\n",(0,n.jsxs)(t.p,{children:["Items within a dictionary exist as individual records stored underneath their unique ",(0,n.jsx)(t.a,{href:"/concepts/key-types#key-explanations",children:"dictionary address"})," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,n.jsx)(t.a,{href:"/concepts/design/casper-design#uref-head",children:(0,n.jsx)(t.code,{children:"URef"})})," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."]}),"\n",(0,n.jsx)(t.p,{children:"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."}),"\n",(0,n.jsx)(t.h2,{id:"using-dictionaries",children:"Using Dictionaries"}),"\n",(0,n.jsxs)(t.p,{children:["Creating a new dictionary is fairly simple and done within the context of a ",(0,n.jsx)(t.code,{children:"transaction"})," sent to a Casper network. The associated code is included within the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:(0,n.jsx)(t.code,{children:"casper_contract"})})," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."]}),"\n",(0,n.jsx)(t.p,{children:"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract entity."}),"\n",(0,n.jsxs)(t.p,{children:["While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,n.jsx)(t.code,{children:"transaction"})," removing those access rights, but it is better to create the dictionary within the context of the Contract."]}),"\n",(0,n.jsx)(t.p,{children:"A dictionary item key can be no longer than 64 bytes in length."}),"\n",(0,n.jsx)(t.h2,{id:"practical-dictionary-examples",children:"Practical Dictionary Examples"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"Casper CEP-78 Enhanced NFT Standard"})," includes several practical applications of dictionaries."]}),"\n",(0,n.jsxs)(t.p,{children:["Simple examples for dictionary use within CEP-78 include the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772",children:(0,n.jsx)(t.code,{children:"approve"})})," dictionary."]}),"\n",(0,n.jsxs)(t.p,{children:["More advanced dictionary functionality can be found in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft#the-cep-78-page-system",children:"CEP-78 Page System"}),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."]}),"\n",(0,n.jsx)(t.h2,{id:"creating-dictionaries-in-a-contracts-context",children:"Creating Dictionaries in a Contract's Context"}),"\n",(0,n.jsx)(t.p,{children:"The following code snippet shows the most basic example of creating a dictionary."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The following example includes the creation of a dictionary ",(0,n.jsx)(t.code,{children:'"ledger"'})," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,n.jsx)(t.code,{children:"init"})," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n'})}),"\n",(0,n.jsx)(t.h2,{id:"writing-entries-into-a-dictionary",children:"Writing Entries into a Dictionary"}),"\n",(0,n.jsx)(t.p,{children:"After the creation of a dictionary, you may then add entries through the use of the following code:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"dictionary_uref"})," refers to the seed URef established during the dictionary creation process. The ",(0,n.jsx)(t.code,{children:"key"})," is the unique identifier for this dictionary item, and the ",(0,n.jsx)(t.code,{children:"value"})," is the data to be stored within the dictionary."]}),"\n",(0,n.jsx)(t.p,{children:"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."}),"\n",(0,n.jsx)(t.p,{children:"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."}),"\n",(0,n.jsxs)(t.p,{children:["The first section acquiring the ",(0,n.jsx)(t.code,{children:"LEDGER"})," seed URef to assign the new dictionary item to the proper dictionary."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n'})}),"\n",(0,n.jsxs)(t.p,{children:["The second section uses ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:(0,n.jsx)(t.code,{children:"dictionary_get"})})," to read an entry within the ",(0,n.jsx)(t.code,{children:"LEDGER"})," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:(0,n.jsx)(t.code,{children:"dictionary_put"})})," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n"})}),"\n",(0,n.jsx)(t.h2,{id:"reading-items-from-a-dictionary-using-the-json-rpc",children:"Reading Items from a Dictionary using the JSON-RPC"}),"\n",(0,n.jsxs)(t.p,{children:["The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,n.jsx)(t.a,{href:"/developers/json-rpc/types_chain#dictionaryidentifier",children:(0,n.jsx)(t.code,{children:"DictionaryIdentifier"})})," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-client",children:"Casper client"}),"."]}),"\n",(0,n.jsxs)(t.h3,{id:"contractnamedkey-lookup-via-a-contracts-named-keys",children:[(0,n.jsx)(t.code,{children:"ContractNamedKey"})," lookup via a Contract's named keys."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," requires the following parameters:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Node Address"})," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"State Root Hash"})," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Contract Hash"})," - The hash of the contract that references the dictionary in its ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Name"})," - The name of the dictionary as a ",(0,n.jsx)(t.code,{children:"String"})," stored in the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," - The specific dictionary item key to be read, as a ",(0,n.jsx)(t.code,{children:"String"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name <String> \\\n --dictionary-item-key <String>\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"uref-lookup-via-the-dictionarys-seed-uref",children:[(0,n.jsx)(t.code,{children:"URef"})," lookup via the dictionary's seed URef."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the dictionary's seed URef requires the ",(0,n.jsx)(t.code,{children:"Node Address"}),", ",(0,n.jsx)(t.code,{children:"State Root Hash"})," and ",(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," as above. However, it does not require the ",(0,n.jsx)(t.code,{children:"Contract Hash"})," or ",(0,n.jsx)(t.code,{children:"Dictionary Name"}),". Instead, it requires:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"Seed URef"})," - The ",(0,n.jsx)(t.a,{href:"#seed-urefs",children:"Seed URef"})," of the dictionary to reference."]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key <String> \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"dictionary-lookup-via-the-unique-dictionary-item-key",children:[(0,n.jsx)(t.code,{children:"Dictionary"})," lookup via the unique dictionary item key."]}),"\n",(0,n.jsxs)(t.p,{children:["In the event that you know the ",(0,n.jsx)(t.code,{children:"dictionary address"})," of the dictionary item key you need to read, you can read it directly using the following Casper client command."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-<string>\n\n"})})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>a,x:()=>o});var n=i(96540);const r={},s=n.createContext(r);function a(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/85b8bb26.da81382e.js b/assets/js/85b8bb26.da81382e.js deleted file mode 100644 index 64fcc1234..000000000 --- a/assets/js/85b8bb26.da81382e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5096],{29387:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var i=n(74848),r=n(28453);const s={title:"Dictionaries"},a="Understanding Dictionaries {#dictionaries}",o={id:"concepts/dictionaries",title:"Dictionaries",description:"dictionaries}",source:"@site/docs/concepts/dictionaries.md",sourceDirName:"concepts",slug:"/concepts/dictionaries",permalink:"/next/concepts/dictionaries",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Dictionaries"},sidebar:"concepts",previous:{title:"Call Stacks",permalink:"/next/concepts/callstack"}},c={},d=[{value:"Seed URefs",id:"seed-urefs",level:2},{value:"Using Dictionaries",id:"using-dictionaries",level:2},{value:"Practical Dictionary Examples",id:"practical-dictionary-examples",level:2},{value:"Creating Dictionaries in a Contract's Context",id:"creating-dictionaries-in-a-contracts-context",level:2},{value:"Writing Entries into a Dictionary",id:"writing-entries-into-a-dictionary",level:2},{value:"Reading Items from a Dictionary using the JSON-RPC",id:"reading-items-from-a-dictionary-using-the-json-rpc",level:2},{value:"<code>ContractNamedKey</code> lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"<code>URef</code> lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"<code>Dictionary</code> lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"dictionaries",children:"Understanding Dictionaries"})}),"\n",(0,i.jsxs)(t.p,{children:["In a Casper network, you can now store sets of data under ",(0,i.jsx)(t.a,{href:"/next/concepts/key-types#key-explanations",children:(0,i.jsx)(t.code,{children:"Keys"})}),". Previously, ",(0,i.jsx)(t.a,{href:"/next/concepts/glossary/U#uref",children:"URefs"})," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,i.jsx)(t.code,{children:"addressable entity"}),"'s context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,i.jsx)(t.a,{href:"/next/concepts/glossary/N#named-keys",children:"NamedKeys"})," structures."]}),"\n",(0,i.jsx)(t.p,{children:"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."}),"\n",(0,i.jsxs)(t.p,{children:["As a solution to this problem, the Casper platform provides the ",(0,i.jsx)(t.code,{children:"Dictionary"})," feature, which allows users a more efficient and scalable means to aggregate data over time."]}),"\n",(0,i.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,i.jsx)(t.code,{children:"NamedKeys"})," to a top-level key, removing this restriction and making them viable for data storage."]}),"\n",(0,i.jsx)(t.h2,{id:"seed-urefs",children:"Seed URefs"}),"\n",(0,i.jsxs)(t.p,{children:["Items within a dictionary exist as individual records stored underneath their unique ",(0,i.jsx)(t.a,{href:"/next/concepts/key-types#key-explanations",children:"dictionary address"})," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,i.jsx)(t.a,{href:"/next/concepts/design/casper-design#uref-head",children:(0,i.jsx)(t.code,{children:"URef"})})," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."]}),"\n",(0,i.jsx)(t.p,{children:"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."}),"\n",(0,i.jsx)(t.h2,{id:"using-dictionaries",children:"Using Dictionaries"}),"\n",(0,i.jsxs)(t.p,{children:["Creating a new dictionary is fairly simple and done within the context of a ",(0,i.jsx)(t.code,{children:"transaction"})," sent to a Casper network. The associated code is included within the ",(0,i.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:(0,i.jsx)(t.code,{children:"casper_contract"})})," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."]}),"\n",(0,i.jsx)(t.p,{children:"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract entity."}),"\n",(0,i.jsxs)(t.p,{children:["While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,i.jsx)(t.code,{children:"transaction"})," removing those access rights, but it is better to create the dictionary within the context of the Contract."]}),"\n",(0,i.jsx)(t.p,{children:"A dictionary item key can be no longer than 64 bytes in length."}),"\n",(0,i.jsx)(t.h2,{id:"practical-dictionary-examples",children:"Practical Dictionary Examples"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"Casper CEP-78 Enhanced NFT Standard"})," includes several practical applications of dictionaries."]}),"\n",(0,i.jsxs)(t.p,{children:["Simple examples for dictionary use within CEP-78 include the ",(0,i.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772",children:(0,i.jsx)(t.code,{children:"approve"})})," dictionary."]}),"\n",(0,i.jsxs)(t.p,{children:["More advanced dictionary functionality can be found in the ",(0,i.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft#the-cep-78-page-system",children:"CEP-78 Page System"}),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."]}),"\n",(0,i.jsx)(t.h2,{id:"creating-dictionaries-in-a-contracts-context",children:"Creating Dictionaries in a Contract's Context"}),"\n",(0,i.jsx)(t.p,{children:"The following code snippet shows the most basic example of creating a dictionary."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-rust",children:"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n"})}),"\n",(0,i.jsxs)(t.p,{children:["The following example includes the creation of a dictionary ",(0,i.jsx)(t.code,{children:'"ledger"'})," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,i.jsx)(t.code,{children:"init"})," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n'})}),"\n",(0,i.jsx)(t.h2,{id:"writing-entries-into-a-dictionary",children:"Writing Entries into a Dictionary"}),"\n",(0,i.jsx)(t.p,{children:"After the creation of a dictionary, you may then add entries through the use of the following code:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-rust",children:"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n"})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"dictionary_uref"})," refers to the seed URef established during the dictionary creation process. The ",(0,i.jsx)(t.code,{children:"key"})," is the unique identifier for this dictionary item, and the ",(0,i.jsx)(t.code,{children:"value"})," is the data to be stored within the dictionary."]}),"\n",(0,i.jsx)(t.p,{children:"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."}),"\n",(0,i.jsx)(t.p,{children:"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."}),"\n",(0,i.jsxs)(t.p,{children:["The first section acquiring the ",(0,i.jsx)(t.code,{children:"LEDGER"})," seed URef to assign the new dictionary item to the proper dictionary."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-rust",children:'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n'})}),"\n",(0,i.jsxs)(t.p,{children:["The second section uses ",(0,i.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:(0,i.jsx)(t.code,{children:"dictionary_get"})})," to read an entry within the ",(0,i.jsx)(t.code,{children:"LEDGER"})," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,i.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:(0,i.jsx)(t.code,{children:"dictionary_put"})})," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-rust",children:"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n"})}),"\n",(0,i.jsx)(t.h2,{id:"reading-items-from-a-dictionary-using-the-json-rpc",children:"Reading Items from a Dictionary using the JSON-RPC"}),"\n",(0,i.jsxs)(t.p,{children:["The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,i.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#dictionaryidentifier",children:(0,i.jsx)(t.code,{children:"DictionaryIdentifier"})})," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,i.jsx)(t.a,{href:"https://crates.io/crates/casper-client",children:"Casper client"}),"."]}),"\n",(0,i.jsxs)(t.h3,{id:"contractnamedkey-lookup-via-a-contracts-named-keys",children:[(0,i.jsx)(t.code,{children:"ContractNamedKey"})," lookup via a Contract's named keys."]}),"\n",(0,i.jsxs)(t.p,{children:["Reading a dictionary item using the Contract's ",(0,i.jsx)(t.code,{children:"NamedKeys"})," requires the following parameters:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"Node Address"})," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"State Root Hash"})," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"Contract Hash"})," - The hash of the contract that references the dictionary in its ",(0,i.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"Dictionary Name"})," - The name of the dictionary as a ",(0,i.jsx)(t.code,{children:"String"})," stored in the Contract's ",(0,i.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"Dictionary Item Key"})," - The specific dictionary item key to be read, as a ",(0,i.jsx)(t.code,{children:"String"}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name <String> \\\n --dictionary-item-key <String>\n\n"})}),"\n",(0,i.jsxs)(t.h3,{id:"uref-lookup-via-the-dictionarys-seed-uref",children:[(0,i.jsx)(t.code,{children:"URef"})," lookup via the dictionary's seed URef."]}),"\n",(0,i.jsxs)(t.p,{children:["Reading a dictionary item using the dictionary's seed URef requires the ",(0,i.jsx)(t.code,{children:"Node Address"}),", ",(0,i.jsx)(t.code,{children:"State Root Hash"})," and ",(0,i.jsx)(t.code,{children:"Dictionary Item Key"})," as above. However, it does not require the ",(0,i.jsx)(t.code,{children:"Contract Hash"})," or ",(0,i.jsx)(t.code,{children:"Dictionary Name"}),". Instead, it requires:"]}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"Seed URef"})," - The ",(0,i.jsx)(t.a,{href:"#seed-urefs",children:"Seed URef"})," of the dictionary to reference."]}),"\n"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key <String> \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n"})}),"\n",(0,i.jsxs)(t.h3,{id:"dictionary-lookup-via-the-unique-dictionary-item-key",children:[(0,i.jsx)(t.code,{children:"Dictionary"})," lookup via the unique dictionary item key."]}),"\n",(0,i.jsxs)(t.p,{children:["In the event that you know the ",(0,i.jsx)(t.code,{children:"dictionary address"})," of the dictionary item key you need to read, you can read it directly using the following Casper client command."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-<string>\n\n"})})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const r={},s=i.createContext(r);function a(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/861e5e13.2a7daafb.js b/assets/js/861e5e13.2a7daafb.js deleted file mode 100644 index 40908ddc9..000000000 --- a/assets/js/861e5e13.2a7daafb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7837],{32858:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Build on Casper",slug:"build-on-casper/introduction"},o="Building on Casper",a={id:"resources/build-on-casper",title:"Build on Casper",description:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.",source:"@site/docs/resources/build-on-casper.md",sourceDirName:"resources",slug:"/resources/build-on-casper/introduction",permalink:"/next/resources/build-on-casper/introduction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Build on Casper",slug:"build-on-casper/introduction"},sidebar:"resources",previous:{title:"Resources Overview",permalink:"/next/resources/"},next:{title:"Move to Casper",permalink:"/next/resources/moving-to-casper"}},l={},c=[{value:"Thriving Ecosystem",id:"thriving-ecosystem",level:2},{value:"Wallets",id:"wallets",level:3},{value:"Block Explorers",id:"block-explorers",level:3},{value:"Developer Tools",id:"developer-tools",level:3},{value:"Open Source Software",id:"open-source-software",level:3},{value:"Developer-Friendly Language",id:"developer-friendly-language",level:2},{value:"Powerful Accounts",id:"powerful-accounts",level:2},{value:"Contract Upgrades",id:"contract-upgrades",level:2},{value:"Development Tools",id:"development-tools",level:2},{value:"IDE Integration",id:"ide-integration",level:3},{value:"CI/CD",id:"ci-cd",level:3},{value:"Local Network Testing",id:"local-network-testing",level:3},{value:"Public Mainnet and Testnet",id:"public-mainnet-and-testnet",level:3},{value:"AWS",id:"aws",level:3},{value:"SDK Client Libraries",id:"sdk-client-libraries",level:2},{value:"No Gas Fees",id:"no-gas-fees",level:2}];function d(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"building-on-casper",children:"Building on Casper"})}),"\n",(0,t.jsx)(n.p,{children:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#thriving-ecosystem",children:"Thriving Ecosystem"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#developer-friendly-language",children:"Developer-Friendly Language"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#powerful-accounts",children:"Powerful Accounts"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#contract-upgrades",children:"Contract Upgrades"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#development-tools",children:"Development Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#no-gas-fees",children:"No Gas Fees"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"thriving-ecosystem",children:"Thriving Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use."}),"\n",(0,t.jsx)(n.h3,{id:"wallets",children:"Wallets"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper.tor.us",children:"Tor.us"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://metamask.io/",children:"Metamask"})," with ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-manager",children:"Casper Snap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in/",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"developer-tools",children:"Developer Tools"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casperholders.io",children:"casperholders.io"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://nownodes.io/nodes/casper-cspr",children:"NOWNodes.io"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"open-source-software",children:"Open Source Software"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open Source Software"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"developer-friendly-language",children:"Developer-Friendly Language"}),"\n",(0,t.jsx)(n.p,{children:"Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.p,{children:["Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Open_standard",children:"open standard"})," for performance and portability of modern web applications."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available."})}),"\n",(0,t.jsx)(n.h2,{id:"powerful-accounts",children:"Powerful Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-permissions",children:"Casper Permissions Model"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-upgrades",children:"Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts."}),"\n",(0,t.jsx)(n.h2,{id:"development-tools",children:"Development Tools"}),"\n",(0,t.jsx)(n.h3,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,t.jsx)(n.p,{children:"The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started."}),"\n",(0,t.jsx)(n.h3,{id:"ci-cd",children:"CI/CD"}),"\n",(0,t.jsx)(n.p,{children:"Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline."}),"\n",(0,t.jsx)(n.h3,{id:"local-network-testing",children:"Local Network Testing"}),"\n",(0,t.jsxs)(n.p,{children:["We also offer a tool to run a ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/setup-nctl",children:"local Casper Network"})," Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface."]}),"\n",(0,t.jsx)(n.h3,{id:"public-mainnet-and-testnet",children:"Public Mainnet and Testnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"Mainnet"})," is a public, open-source, community-driven ecosystem. You can also explore the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live",children:"Testnet"})," to test drive your applications and estimate gas costs."]}),"\n",(0,t.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,t.jsx)(n.p,{children:"We also offer several tools to run AWS instances of Casper nodes."}),"\n",(0,t.jsx)(n.h2,{id:"sdk-client-libraries",children:"SDK Client Libraries"}),"\n",(0,t.jsxs)(n.p,{children:["In addition to the default ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"command-line Rust client"}),", the Casper community is building ",(0,t.jsx)(n.a,{href:"/sdk",children:"other clients"})," in JavaScript, Java, Golang, Python, C#, and other languages."]}),"\n",(0,t.jsx)(n.h2,{id:"no-gas-fees",children:"No Gas Fees"}),"\n",(0,t.jsxs)(n.p,{children:["Casper seeks to eliminate volatility and improve developer and enterprise experiences by ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"eliminating transaction fees"})," on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/861e5e13.e59049a7.js b/assets/js/861e5e13.e59049a7.js new file mode 100644 index 000000000..911cbf957 --- /dev/null +++ b/assets/js/861e5e13.e59049a7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27837],{32858:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Build on Casper",slug:"build-on-casper/introduction"},o="Building on Casper",a={id:"resources/build-on-casper",title:"Build on Casper",description:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.",source:"@site/docs/resources/build-on-casper.md",sourceDirName:"resources",slug:"/resources/build-on-casper/introduction",permalink:"/resources/build-on-casper/introduction",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Build on Casper",slug:"build-on-casper/introduction"},sidebar:"resources",previous:{title:"Resources Overview",permalink:"/resources/"},next:{title:"Move to Casper",permalink:"/resources/moving-to-casper"}},l={},c=[{value:"Thriving Ecosystem",id:"thriving-ecosystem",level:2},{value:"Wallets",id:"wallets",level:3},{value:"Block Explorers",id:"block-explorers",level:3},{value:"Developer Tools",id:"developer-tools",level:3},{value:"Open Source Software",id:"open-source-software",level:3},{value:"Developer-Friendly Language",id:"developer-friendly-language",level:2},{value:"Powerful Accounts",id:"powerful-accounts",level:2},{value:"Contract Upgrades",id:"contract-upgrades",level:2},{value:"Development Tools",id:"development-tools",level:2},{value:"IDE Integration",id:"ide-integration",level:3},{value:"CI/CD",id:"ci-cd",level:3},{value:"Local Network Testing",id:"local-network-testing",level:3},{value:"Public Mainnet and Testnet",id:"public-mainnet-and-testnet",level:3},{value:"AWS",id:"aws",level:3},{value:"SDK Client Libraries",id:"sdk-client-libraries",level:2},{value:"No Gas Fees",id:"no-gas-fees",level:2}];function d(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"building-on-casper",children:"Building on Casper"})}),"\n",(0,t.jsx)(n.p,{children:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#thriving-ecosystem",children:"Thriving Ecosystem"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#developer-friendly-language",children:"Developer-Friendly Language"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#powerful-accounts",children:"Powerful Accounts"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#contract-upgrades",children:"Contract Upgrades"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#development-tools",children:"Development Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#no-gas-fees",children:"No Gas Fees"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"thriving-ecosystem",children:"Thriving Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use."}),"\n",(0,t.jsx)(n.h3,{id:"wallets",children:"Wallets"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper.tor.us",children:"Tor.us"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://metamask.io/",children:"Metamask"})," with ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-manager",children:"Casper Snap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in/",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"developer-tools",children:"Developer Tools"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casperholders.io",children:"casperholders.io"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://nownodes.io/nodes/casper-cspr",children:"NOWNodes.io"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"open-source-software",children:"Open Source Software"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open Source Software"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"developer-friendly-language",children:"Developer-Friendly Language"}),"\n",(0,t.jsx)(n.p,{children:"Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.p,{children:["Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Open_standard",children:"open standard"})," for performance and portability of modern web applications."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available."})}),"\n",(0,t.jsx)(n.h2,{id:"powerful-accounts",children:"Powerful Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-permissions",children:"Casper Permissions Model"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-upgrades",children:"Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts."}),"\n",(0,t.jsx)(n.h2,{id:"development-tools",children:"Development Tools"}),"\n",(0,t.jsx)(n.h3,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,t.jsx)(n.p,{children:"The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started."}),"\n",(0,t.jsx)(n.h3,{id:"ci-cd",children:"CI/CD"}),"\n",(0,t.jsx)(n.p,{children:"Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline."}),"\n",(0,t.jsx)(n.h3,{id:"local-network-testing",children:"Local Network Testing"}),"\n",(0,t.jsxs)(n.p,{children:["We also offer a tool to run a ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"local Casper Network"})," Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface."]}),"\n",(0,t.jsx)(n.h3,{id:"public-mainnet-and-testnet",children:"Public Mainnet and Testnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"Mainnet"})," is a public, open-source, community-driven ecosystem. You can also explore the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live",children:"Testnet"})," to test drive your applications and estimate gas costs."]}),"\n",(0,t.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,t.jsx)(n.p,{children:"We also offer several tools to run AWS instances of Casper nodes."}),"\n",(0,t.jsx)(n.h2,{id:"sdk-client-libraries",children:"SDK Client Libraries"}),"\n",(0,t.jsxs)(n.p,{children:["In addition to the default ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"command-line Rust client"}),", the Casper community is building ",(0,t.jsx)(n.a,{href:"/sdk",children:"other clients"})," in JavaScript, Java, Golang, Python, C#, and other languages."]}),"\n",(0,t.jsx)(n.h2,{id:"no-gas-fees",children:"No Gas Fees"}),"\n",(0,t.jsxs)(n.p,{children:["Casper seeks to eliminate volatility and improve developer and enterprise experiences by ",(0,t.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"eliminating transaction fees"})," on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/862f9df3.ca8d966e.js b/assets/js/862f9df3.ca8d966e.js new file mode 100644 index 000000000..625d1da66 --- /dev/null +++ b/assets/js/862f9df3.ca8d966e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2119],{97568:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>i,metadata:()=>o,toc:()=>h});var s=t(74848),a=t(28453);const i={},r="Signing Transactions",o={id:"developers/dapps/signing-a-transaction",title:"Signing Transactions",description:"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/signing-a-transaction.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/signing-a-transaction",permalink:"/2.0.0/developers/dapps/signing-a-transaction",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"URef Access Rights",permalink:"/2.0.0/developers/dapps/uref-security"},next:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/2.0.0/developers/dapps/speculative-exec"}},c={},h=[{value:"Public Key Cryptography",id:"public-key-cryptography",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"signing-transactions",children:"Signing Transactions"})}),"\n",(0,s.jsxs)(n.p,{children:["When creating a ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:(0,s.jsx)(n.code,{children:"Transaction"})})," to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed."]}),"\n",(0,s.jsxs)(n.p,{children:["When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/types#approval",children:(0,s.jsx)(n.code,{children:"Approval"})}),". Every valid transaction has at least one approval."]}),"\n",(0,s.jsxs)(n.p,{children:["The signature creation process begins with the hashing of the payment and session of the transaction to create the ",(0,s.jsx)(n.code,{children:"BodyHash"}),". The ",(0,s.jsx)(n.code,{children:"BodyHash"})," becomes a component of the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," as outlined in the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"serialization standard"}),". From there, the ",(0,s.jsx)(n.code,{children:"TransactionV1Header"})," can be hashed to create the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"}),". As outlined above, the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," is then combined with the account's key-pair to create the transaction's signature."]}),"\n",(0,s.jsxs)(n.p,{children:["As the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the ",(0,s.jsx)(n.code,{children:"TransactionV1Hash"})," invalid."]}),"\n",(0,s.jsx)(n.h2,{id:"public-key-cryptography",children:"Public Key Cryptography"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks are compatible with both ",(0,s.jsx)(n.code,{children:"Ed25519"})," and ",(0,s.jsx)(n.code,{children:"Secp256k1"})," public key cryptography. When ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"serialized"}),", public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with ",(0,s.jsx)(n.code,{children:"1"}),", whereas Secp256k1 are prefixed with ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses ",(0,s.jsx)(n.code,{children:"blake2b"})," hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ed25519 signs over a SHA-512 digest."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Secp256k1 signs over a SHA-256 digest."}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var s=t(96540);const a={},i=s.createContext(a);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8675f5af.bfe5a528.js b/assets/js/8675f5af.bfe5a528.js new file mode 100644 index 000000000..27507f88c --- /dev/null +++ b/assets/js/8675f5af.bfe5a528.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24907],{93911:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var s=n(74848),r=n(28453);const c={title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},a="Testing Framework for CEP-18",i={id:"resources/tokens/cep18/tests",title:"Testing Guide",description:"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/tests.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/tests",permalink:"/2.0.0/resources/tokens/cep18/tests",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},sidebar:"resources",previous:{title:"CEP-18 Transfers",permalink:"/2.0.0/resources/tokens/cep18/transfer"},next:{title:"Introduction",permalink:"/2.0.0/resources/tokens/cep78/introduction"}},o={},l=[{value:"Configuring the Test Package",id:"configuring-the-test-package",level:2},{value:"Testing Logic",id:"testing-logic",level:2},{value:"Setting up the Testing Context",id:"setting-up-the-testing-context",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:3},{value:"Creating Helper Functions",id:"creating-helper-functions",level:3},{value:"Creating Unit Tests",id:"creating-unit-tests",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function _(e){const t={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-framework-for-cep-18",children:"Testing Framework for CEP-18"})}),"\n",(0,s.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,s.jsxs)(t.p,{children:["The following section reviews the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/tests",children:"GitHub testing folder"}),", which creates a testing framework for the Casper ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Fungible Token"})," project. You can find more details about testing Casper contracts ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a complete test expecting a failed transfer:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[should_panic(expected = "ApiError::User(65534) [131070]")]\n#[test]\nfn should_not_transfer_with_insufficient_balance() {\n let mut fixture = TestFixture::install_contract();\n\n let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();\n assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);\n\n fixture.transfer(\n Key::from(fixture.bob),\n initial_ali_balance + U256::one(),\n fixture.ali,\n );\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To build and run the tests, issue the following command in the project folder, ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The project contains a ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,s.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file to the ",(0,s.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,s.jsx)(t.code,{children:"make test"})," command during development."]}),"\n",(0,s.jsx)(t.h2,{id:"configuring-the-test-package",children:"Configuring the Test Package"}),"\n",(0,s.jsxs)(t.p,{children:["In this project, we define a ",(0,s.jsx)(t.code,{children:"tests"})," package using the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/Cargo.toml",children:"tests/Cargo.toml"})," file."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'[package]\nname = "tests"\nversion = "1.0.0"\n...\n\n[dependencies]\ncasper-types = "2.0.0"\ncasper-engine-test-support = "4.0.0"\ncasper-execution-engine = "4.0.0"\nonce_cell = "1.16.0"\n\n[lib]\nname = "tests"\n...\n'})}),"\n",(0,s.jsx)(t.h2,{id:"testing-logic",children:"Testing Logic"}),"\n",(0,s.jsxs)(t.p,{children:["In Github, you will find an ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/cep18",children:"example"})," containing a Casper Fungible Token ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/cep18/src/main.rs",children:"contract"})," implementation with the corresponding ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"tests"}),". The tests follow this sequence:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#setting-up-the-testing-context",children:"Step 1"})," - Specify the starting state of the blockchain."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"Step 2"})," - Deploy the compiled contract to the blockchain and query it."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#creating-helper-functions",children:"Step 3"})," - Create additional deploys for calling each of the entrypoints in the contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints."}),"\n",(0,s.jsx)(t.h3,{id:"setting-up-the-testing-context",children:"Setting up the Testing Context"}),"\n",(0,s.jsxs)(t.p,{children:["The code in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src/utility",children:"utility directory"})," initializes the blockchain's ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"})," with all the data and entrypoints the smart contract needs."]}),"\n",(0,s.jsxs)(t.p,{children:["Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/constants.rs",children:(0,s.jsx)(t.code,{children:"constants.rs"})})," file within the ",(0,s.jsx)(t.code,{children:"utility"})," directory. For the most up-to-date version of the code, visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of required constants"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\nuse casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,\n};\nuse casper_execution_engine::core::engine_state::ExecuteRequest;\nuse casper_types::{\n account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,\n};\n\nuse crate::utility::constants::{\n ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,\n};\n\nuse super::constants::{\n ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,\n};\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a ",(0,s.jsx)(t.code,{children:"TestContext"})," of its own. The ",(0,s.jsx)(t.em,{children:"contract_hash"})," and the ",(0,s.jsx)(t.em,{children:"session_code"})," won\u2019t change after the contract is deployed, so it is good to keep them handy."]}),"\n",(0,s.jsxs)(t.p,{children:["This code snippet builds the context and includes the compiled contract ",(0,s.jsx)(t.em,{children:".wasm"})," binary being tested. The ",(0,s.jsx)(t.code,{children:"TestContext"})," struct creates a new instance of the ",(0,s.jsx)(t.code,{children:"cep18_token"})," with several test accounts."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),": These accounts have a positive initial balance."]}),"\n",(0,s.jsxs)(t.p,{children:["The full and most recent code implementation is available on ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of a CEP-18 token in a test"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\n// Creating the `TestContext` struct.\n\npub(crate) struct TestContext {\npub(crate) cep18_token: ContractHash,\npub(crate) cep18_test_contract_package: ContractPackageHash,\n}\n\n// Setting up the test instance of CEP-18.\n\npub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option<u64> = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-helper-functions",children:"Creating Helper Functions"}),"\n",(0,s.jsxs)(t.p,{children:["The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.jsx)(t.code,{children:"installer_request_builders.rs"})," defines helper functions that will be used throughout the testing framework:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_total_supply"})," - A function for testing the total supply of the CEP-18 contract instance."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_balance_of"})," - A function for checking an account's balance of CEP-18 tokens."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_allowance_of"})," - A function for checking an account's spending allowance from another account's balance."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.jsx)(t.code,{children:"test_cep18_transfer"}),", ",(0,s.jsx)(t.code,{children:"make_cep18_approve_request"})," and ",(0,s.jsx)(t.code,{children:"test_approve_for"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"contract installation"}),":"]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example helper function"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"creating-unit-tests",children:"Creating Unit Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Within this testing context, the ",(0,s.jsxs)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:[(0,s.jsx)(t.code,{children:"tests"})," directory"]})," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"installer_request_builders.rs"})," file."]}),"\n",(0,s.jsxs)(t.p,{children:["The example below shows one of the tests. Visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"GitHub"})," to find all the available tests."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example test querying token properties"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs",children:"lib.rs"})," file is configured to run the example integration tests via the ",(0,s.jsx)(t.code,{children:"make test"})," command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, navigate to the parent ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18 directory"})," and run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["This example uses ",(0,s.jsx)(t.code,{children:"bash"}),". If you are using a Rust IDE, you need to configure it to run the tests."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function a(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/86ae953a.101fb2af.js b/assets/js/86ae953a.101fb2af.js new file mode 100644 index 000000000..e6ea7ef08 --- /dev/null +++ b/assets/js/86ae953a.101fb2af.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60173],{28874:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={},c="Best Practices for Casper Smart Contract Authors",a={id:"developers/writing-onchain-code/best-practices",title:"Best Practices for Casper Smart Contract Authors",description:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/best-practices.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/best-practices",permalink:"/2.0.0/developers/writing-onchain-code/best-practices",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Factory Contracts",permalink:"/2.0.0/developers/writing-onchain-code/factory-pattern"},next:{title:"Overview",permalink:"/2.0.0/developers/json-rpc/"}},o={},l=[{value:"Data Efficiency",id:"data-efficiency",level:2},{value:"Costs",id:"costs",level:2},{value:"Tips to reduce WASM size",id:"tips-to-reduce-wasm-size",level:3},{value:"Inlining",id:"inlining",level:2},{value:"Testing",id:"testing",level:2}];function d(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"best-practices-for-casper-smart-contract-authors",children:"Best Practices for Casper Smart Contract Authors"})}),"\n",(0,s.jsx)(n.p,{children:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources."}),"\n",(0,s.jsx)(n.h2,{id:"data-efficiency",children:"Data Efficiency"}),"\n",(0,s.jsxs)(n.p,{children:["When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"transactions"})," will drastically decrease the overall cost."]}),"\n",(0,s.jsxs)(n.p,{children:["When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent transaction of session code. This entry point creates the internal structure of the contract and cannot be called after the initial transaction. Below is an example of a self-initalizing entry point that can be used within the ",(0,s.jsx)(n.code,{children:"call"})," function."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example Self-initialization Entry Point"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'\n// This entry point initializes the donation system, setting up the fundraising purse\n// and creating a dictionary to track the account hashes and the number of donations\n// made.\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary(LEDGER).unwrap_or_revert();\n}\n\npub extern "C" fn call() {\n let init_entry_point = EntryPoint::new(\n ENTRY_POINT_INIT,\n vec![],\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n );\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial transaction."}),"\n",(0,s.jsx)(n.h2,{id:"costs",children:"Costs"}),"\n",(0,s.jsxs)(n.p,{children:["Computations occurring on-chain come with associated ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/gas-concepts",children:"gas costs"}),". Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical."]}),"\n",(0,s.jsxs)(n.p,{children:["Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract#scenario2",children:"reuse of purses"})," should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author."]}),"\n",(0,s.jsx)(n.h3,{id:"tips-to-reduce-wasm-size",children:"Tips to reduce WASM size"}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a maxim size specified in each network chainspec as ",(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576"}),". For example, networks running node version 2.0, have the following maximum transaction size in bytes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"max_transaction_size = 1_048_576\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here are a few tips to reduce the size of Wasm included in a transaction:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the smart contract in release mode. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L10",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run\xa0",(0,s.jsx)(n.code,{children:"wasm-strip"}),"\xa0on the compiled code (see\xa0",(0,s.jsx)(n.a,{href:"https://github.com/WebAssembly/wabt",children:"WABT"}),"). You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L12",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"wasm-strip target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Don't enable the\xa0",(0,s.jsx)(n.code,{children:"std"}),"\xa0feature when linking to the\xa0",(0,s.jsx)(n.code,{children:"casper-contract"}),"\xa0or\xa0",(0,s.jsx)(n.code,{children:"casper-types"}),"\xa0crates using the ",(0,s.jsx)(n.code,{children:"#![no_std]"})," attribute, which tells the program not to import the standard libraries. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/cep18/src/main.rs#L1",children:"here"})," and further details ",(0,s.jsx)(n.a,{href:"https://docs.rust-embedded.org/book/intro/no-std.html",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with ",(0,s.jsx)(n.code,{children:"codegen-units"})," set to 1 by adding ",(0,s.jsx)(n.code,{children:"codegen-units = 1"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release])"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L14",children:"here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with link-time optimizations enabled by adding ",(0,s.jsx)(n.code,{children:"lto = true"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release]"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L15",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"inlining",children:"Inlining"}),"\n",(0,s.jsxs)(n.p,{children:["As often as practicable, developers should inline functions by including the body of the function within their code rather than making ",(0,s.jsx)(n.code,{children:"call"})," or ",(0,s.jsx)(n.code,{children:"call_indirect"})," to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances."]}),"\n",(0,s.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(n.p,{children:["Testing all transactions prior to committing them to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending transactions to ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Information on these processes can be found at the following locations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter/",children:"A Counter On An NCTL Network"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter-testnet",children:"A Counter On The Testnet"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/86b0038a.ae57b7f1.js b/assets/js/86b0038a.ae57b7f1.js new file mode 100644 index 000000000..41ff78207 --- /dev/null +++ b/assets/js/86b0038a.ae57b7f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51625],{16232:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const c={},a="Writing a Basic Smart Contract in Rust",o={id:"developers/writing-onchain-code/simple-contract",title:"Writing a Basic Smart Contract in Rust",description:"What is a Smart Contract?",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/simple-contract.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/simple-contract",permalink:"/2.0.0/developers/writing-onchain-code/simple-contract",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with AssemblyScript",permalink:"/2.0.0/developers/writing-onchain-code/assembly-script"},next:{title:"Testing Smart Contracts",permalink:"/2.0.0/developers/writing-onchain-code/testing-contracts"}},i={},l=[{value:"What is a Smart Contract?",id:"what-is-a-smart-contract",level:2},{value:"Key Features of Casper Contracts",id:"key-features-of-casper-contracts",level:2},{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Automatically using <code>cargo casper</code>",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain <code>cargo</code>",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"step-4-defining-the-contract-entry-points",level:4},{value:"Defining the <code>call</code> function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-a-basic-smart-contract-in-rust",children:"Writing a Basic Smart Contract in Rust"})}),"\n",(0,r.jsx)(t.h2,{id:"what-is-a-smart-contract",children:"What is a Smart Contract?"}),"\n",(0,r.jsxs)(t.p,{children:["A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,r.jsx)(t.a,{href:"/2.0.0/transactions",children:"transaction"}),". Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic."]}),"\n",(0,r.jsx)(t.p,{children:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."}),"\n",(0,r.jsx)(t.h2,{id:"key-features-of-casper-contracts",children:"Key Features of Casper Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"sent to a node"})," on a Casper network using a transaction. Nodes within the network then ",(0,r.jsx)(t.a,{href:"/2.0.0/concepts/design/p2p#communications-gossiping",children:"gossip transactions"}),", include them within a block, and finalize them. After finalizing, the network executes the transactions within the block."]}),"\n",(0,r.jsxs)(t.p,{children:["Further, the Casper platform allows for ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts",children:"upgradable contracts"}),". A ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html",children:"ContractPackage"})," is created through the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," or ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,r.jsx)(t.a,{href:"/2.0.0/concepts/key-types#hash-and-key-explanations",children:(0,r.jsx)(t.code,{children:"ContractPackageHash"})}),". The new contract is added to this package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"ContractHash"})})," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"new_contract"})," and ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The contract contains required metadata, and it is primarily identified by its ",(0,r.jsx)(t.code,{children:"ContractHash"}),". While the contract hash identifies a specific ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"ContractVersion"}),", the ",(0,r.jsx)(t.code,{children:"ContractPackageHash"})," serves as an identifier for the most recent contract version in the contract package."]}),"\n",(0,r.jsx)(t.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,r.jsx)(t.p,{children:"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n"})}),"\n",(0,r.jsx)(t.p,{children:"The project structure would be different in a dApp with full-stack architecture. "}),"\n",(0,r.jsxs)(t.h3,{id:"automatic-project-setup",children:["Automatically using ",(0,r.jsx)(t.code,{children:"cargo casper"})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started#creating-a-project",children:"cargo casper command"})," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"cargo casper"})," command will generate an example contract in the contract directory and an example ",(0,r.jsx)(t.code,{children:"tests"})," crate with logic defined in the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file. The ",(0,r.jsx)(t.code,{children:"Makefile"})," includes commands to prepare and build the contract, and the ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," file specifies the target build version of Rust."]}),"\n",(0,r.jsxs)(t.h3,{id:"semi-automatic-project-setup",children:["Semi-automatically using plain ",(0,r.jsx)(t.code,{children:"cargo"})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory for the contract code and its corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the following command to create a new binary package called ",(0,r.jsx)(t.code,{children:"contract"}),". Use a different name instead of ",(0,r.jsx)(t.code,{children:"contract"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new contract\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"contract"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would contain the contract code."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This file would contain crate dependencies and other configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following sections explain how to update these files using example code."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,r.jsx)(t.code,{children:"tests"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new tests\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"tests"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," as shown in the example structure."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This is the file with test configurations."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," guide explains how to update the tests using example code."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Unlike ",(0,r.jsx)(t.code,{children:"cargo casper"}),", ",(0,r.jsx)(t.code,{children:"cargo"})," does not create a ",(0,r.jsx)(t.code,{children:"Makefile"})," and ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," configuration file. Therefore, you must manually add these files to the project's root folder."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example Makefile"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example rust-toolchain file"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"manual-project-setup",children:"Manually"}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended, and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory to store the contract code and corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"contract"}),". You can use a different folder name if you wish."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"contract"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the contract's dependencies."]}),"\n",(0,r.jsxs)(t.li,{children:["Add a Rust file with the contract code in the ",(0,r.jsx)(t.code,{children:"src"})," folder. In this example, we have the ",(0,r.jsx)(t.code,{children:"main.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"tests"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"tests"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the required dependencies to run the tests."]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"src"})," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Manually create Makefile and rust-toolchain as per ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"Semi-automatic setup (4.)"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file in the ",(0,r.jsx)(t.code,{children:"contract"})," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,r.jsxs)(t.p,{children:["If you followed the ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic setup"}),", the dependencies should be in the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file. For the ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic setup"})," and ",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual setup"}),", however, you'll need to manually add the dependencies to the crate's ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-toml",children:'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n'})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"writing-a-basic-smart-contract",children:"Writing a Basic Smart Contract"}),"\n",(0,r.jsxs)(t.p,{children:["At this point, you either have the default example contract defined in ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic"})," setup using cargo-casper), an empty ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," file (",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual"}),' project setup), or a Rust "hello world" program defined in the ',(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic"})," setup)."]}),"\n",(0,r.jsxs)(t.p,{children:["This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,r.jsx)(t.code,{children:"contract/main.rs"})," file if there are any."]}),"\n",(0,r.jsxs)(t.p,{children:["The example code comes from the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"counter contract"}),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"contract API"})," within the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:(0,r.jsx)(t.code,{children:"casper_contract"})})," crate."]}),"\n",(0,r.jsxs)(t.admonition,{type:"info",children:[(0,r.jsx)(t.p,{children:"Important syntax elements used frequently in Rust:"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html",children:"Match"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html",children:"Array"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html",children:"Loop"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/std/vec.html",children:"Vectors"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/fn.html",children:"Functions"}),(0,r.jsx)(t.br,{})]}),"\n"]}),(0,r.jsx)(t.p,{children:"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples."})]}),"\n",(0,r.jsxs)(t.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,r.jsx)(t.code,{children:"main.rs"})," File"]}),"\n",(0,r.jsxs)(t.p,{children:["To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,r.jsx)(t.code,{children:"main.rs"})," file, remove the auto-generated main function."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_main]"})," - This attribute tells the program not to use the standard main function as its entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_std]"})," - This attribute tells the program not to import the standard libraries."]}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"defining-required-dependencies",children:"Defining required dependencies"}),"\n",(0,r.jsx)(t.p,{children:"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n"})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-global-constants",children:"Defining the global constants"}),"\n",(0,r.jsx)(t.p,{children:"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n'})}),"\n",(0,r.jsx)(t.h4,{id:"step-4-defining-the-contract-entry-points",children:"Defining the contract entry points"}),"\n",(0,r.jsxs)(t.p,{children:["Entry points provide access to contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."]}),"\n",(0,r.jsx)(t.p,{children:"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the transaction. Note that another smart contract may access any of these entry points."}),"\n",(0,r.jsx)(t.p,{children:"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."}),"\n",(0,r.jsxs)(t.p,{children:["When defining entry points, begin with a ",(0,r.jsx)(t.code,{children:"#[no_mangle]"})," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"GitHub"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n'})}),"\n",(0,r.jsxs)(t.h4,{id:"defining-the-call-function",children:["Defining the ",(0,r.jsx)(t.code,{children:"call"})," function"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,r.jsx)(t.code,{children:"call"})," function. Review the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55",children:"call function"})," in the counter contract."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Define the runtime arguments."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."}),"\n",(0,r.jsxs)(t.p,{children:["Look at the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"CEP-78 contract"})," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."]}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Add the entry points into the ",(0,r.jsx)(t.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function replaces a traditional ",(0,r.jsx)(t.code,{children:"main"})," function and executes automatically when a caller interacts with the contract. Within the ",(0,r.jsx)(t.code,{children:"call"})," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."]}),"\n",(0,r.jsx)(t.p,{children:"Each entry point should have these arguments:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"name"})," - The entry point's name, which should be the same as the initial definition."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"arguments"})," - A list of runtime arguments declared as part of the definition of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"return type"})," - The CLType returned by the entry point. Use the type ",(0,r.jsx)(t.em,{children:"Unit"})," for empty return types."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"access level"})," - Access permissions of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry point type"})," - This can be ",(0,r.jsx)(t.code,{children:"contract"})," or ",(0,r.jsx)(t.code,{children:"session"})," code."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["This step adds the individual entry points to a ",(0,r.jsx)(t.code,{children:"counter_entry_points"})," object using the ",(0,r.jsx)(t.code,{children:"add_entry_point"})," method. This object will later be passed to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n'})}),"\n",(0,r.jsx)(t.p,{children:"In the following, we will add more content to this call function."}),"\n",(0,r.jsxs)(t.ol,{start:"3",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract's named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"})," are a collection of String-Key pairs used to identify some network data quickly."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, transaction information, purse balances, etc. The list of possible Key variants can be found ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"For the counter, we store the integer that we increment into a named key."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"4",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Use the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,r.jsx)(t.code,{children:"contractPackageHash"}),". Then, it adds the contract to the package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"contractHash"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Usually, these contracts are upgradeable with the ability to add new ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"}),". You ",(0,r.jsx)(t.strong,{children:"must have the access URef"})," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,r.jsx)(t.code,{children:"Some(CONTRACT_ACCESS_UREF.to_string())"})," argument to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method. To prevent any upgrades to a contract, use the ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," method described ",(0,r.jsx)(t.a,{href:"#locked-contracts",children:"below"}),"."]}),"\n",(0,r.jsxs)(t.ol,{start:"5",children:["\n",(0,r.jsx)(t.li,{children:"Create additional named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Generally, the ",(0,r.jsx)(t.code,{children:"Contract_Hash"})," and ",(0,r.jsx)(t.code,{children:"Contract_Version"})," are saved as ",(0,r.jsx)(t.code,{children:"NamedKeys"})," for later use."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,r.jsx)(t.p,{children:"The complete call function should look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"locked-contracts",children:"Locked Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Locked contracts cannot contain other contract ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"})," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option<NamedKeys>,\n hash_name: Option<String>,\n uref_name: Option<String>,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry_points"})," - The set of entry points defined inside the smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"named_keys"})," - Any ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"named-key"})," pairs for the contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"hash_name"})," - Contract hash value. Puts ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:"contractHash"})," in the current context's named keys under ",(0,r.jsx)(t.code,{children:"hash_name"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"uref_name"})," - Access URef value. Puts access_uref in the current context's named keys under ",(0,r.jsx)(t.code,{children:"uref_name"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Note"}),": The current context is the context of the person who initiated the ",(0,r.jsx)(t.code,{children:"call"})," function, usually an account entity."]}),"\n",(0,r.jsx)(t.p,{children:"The counter contract in our example would be locked if we created it this way:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n"})}),"\n",(0,r.jsx)(t.h2,{id:"compiling-contract-code",children:"Compiling Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["To compile the smart contract, run the following commands in the ",(0,r.jsx)(t.code,{children:"contract"})," folder in your project's directory, where the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file and ",(0,r.jsx)(t.code,{children:"src"})," folder are hosted."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For the counter example, in the project directory where the ",(0,r.jsx)(t.code,{children:"Makefile"})," is, run the following commands:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})}),"\n",(0,r.jsx)(t.h2,{id:"executing-contract-code",children:"Executing Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["Contract execution must be initiated through an outside call, usually via ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."]}),"\n",(0,r.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)(t.p,{children:"The following brief video accompanies this guide."}),"\n",(0,r.jsxs)(t.p,{align:"center",children:["\n",(0,r.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"test your contract"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Understand ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/870de909.24484384.js b/assets/js/870de909.24484384.js new file mode 100644 index 000000000..e3f3698d2 --- /dev/null +++ b/assets/js/870de909.24484384.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96755],{91820:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var a=n(74848),i=n(28453);const o={},s="Delegating Tokens",r={id:"users/delegating",title:"Delegating Tokens",description:"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.",source:"@site/docs/users/delegating.md",sourceDirName:"users",slug:"/users/delegating",permalink:"/users/delegating",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"users",previous:{title:"Funding Mainnet Accounts",permalink:"/users/funding-from-exchanges"},next:{title:"Using CSPR.live",permalink:"/users/csprlive/"}},l={},d=[{value:"Delegation Cost",id:"delegation-cost",level:2},{value:"Delegation Limits",id:"delegation-limits",level:2},{value:"Selecting a Node for Delegating",id:"selecting-a-node-for-delegating",level:2},{value:"First-time Delegation",id:"first-time-delegation",level:2},{value:"Monitoring Rewards",id:"monitoring-rewards",level:2},{value:"Tutorials",id:"tutorials",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"delegating-tokens",children:"Delegating Tokens"})}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as ",(0,a.jsx)(t.strong,{children:"delegating"})," or ",(0,a.jsx)(t.strong,{children:"staking"})," with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider."]}),"\n",(0,a.jsx)(t.p,{children:"Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network."}),"\n",(0,a.jsx)(t.p,{children:"Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate."}),"\n",(0,a.jsx)(t.p,{children:"Casper does not treat validator stake differently than delegator stake for security reasons."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-cost",children:"Delegation Cost"}),"\n",(0,a.jsx)(t.p,{children:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates to delegations, and where to find more details. Please note that the cost amounts are likely to change over time, and you may have to check the latest release details to get the most up-to-date and accurate delegation cost."}),"\n",(0,a.jsxs)(t.p,{children:["The delegation cost is defined in the chainspec.toml file of a Casper network. In this ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-2.0.0-rc1/resources/production/chainspec.toml",children:"example chainspec"}),", the delegation is set to cost 2.5 CSPR. However, ",(0,a.jsx)(t.code,{children:"when you perform the delegation, you see that it costs a little more"})," than what is specified in the chainspec. Let's discuss why this happens."]}),"\n",(0,a.jsx)(t.p,{children:"When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is added to the delegation cost defined in the chainspec file. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse."}),"\n",(0,a.jsxs)(t.p,{children:["For example, the chainspec file in release 2.0.0 contains the following information. Notice the delegation cost specified with ",(0,a.jsx)(t.code,{children:"delegate"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"[system_costs.auction_costs]\n...\ndelegate = 2_500_000_000\nundelegate = 2_500_000_000\n...\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Delegation fees may change over time, so it is essential to stay current. To do so, select the latest release in ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"Github"})," and navigate to the ",(0,a.jsx)(t.code,{children:"resources/production/chainspec.toml"})," file."]}),"\n",(0,a.jsxs)(t.p,{children:["For further questions, please join the ",(0,a.jsx)(t.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"delegation-limits",children:"Delegation Limits"}),"\n",(0,a.jsx)(t.p,{children:"The chainspec specifies delegation limits, such as the minimum and maximum amount allowed to be delegated. Also, each validator can have a maximum number of delegators."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"# Minimum allowed delegation amount in motes\nminimum_delegation_amount = 500_000_000_000\n# Maximum allowed delegation amount in motes\nmaximum_delegation_amount = 1_000_000_000_000_000_000\n# The maximum amount of delegators per validator.\nmax_delegators_per_validator = 1200\n"})}),"\n",(0,a.jsx)(t.h2,{id:"selecting-a-node-for-delegating",children:"Selecting a Node for Delegating"}),"\n",(0,a.jsxs)(t.p,{children:["As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," provide ",(0,a.jsx)(t.a,{href:"https://cspr.live/validators",children:"validator performance statistics"}),", including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Validators",src:n(17220).A+"",width:"2440",height:"1211"})}),"\n",(0,a.jsx)(t.h2,{id:"first-time-delegation",children:"First-time Delegation"}),"\n",(0,a.jsxs)(t.p,{children:["If you perform a delegation for the first time, the system charges some motes to create a purse to hold the delegated tokens. We recommend that you try out delegations on the ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Casper Testnet"})," before making transactions on the ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Casper Mainnet"}),". This will help you understand the costs involved in delegating tokens."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Example:"})," The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Mainnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"When you set up a delegation transaction, it is essential to have enough funds in your account's main purse. Otherwise, the transaction will fail, and you will lose the delegation cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer."}),"\n",(0,a.jsxs)(t.p,{children:["As a result, when performing a ",(0,a.jsx)(t.a,{href:"/developers/cli/delegate",children:"delegation using the command line"}),", we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.",src:n(31400).A+"",width:"1256",height:"1266"})}),"\n",(0,a.jsx)(t.p,{align:"center",children:"\n**Figure 2** : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.\n"}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Transaction costs depend on each Casper network and the cost tables defined in the chainspec. Most of these examples are from the Casper Mainnet or Testnet."})}),"\n",(0,a.jsx)(t.h2,{id:"monitoring-rewards",children:"Monitoring Rewards"}),"\n",(0,a.jsx)(t.p,{children:"It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations."}),"\n",(0,a.jsx)(t.p,{children:"Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,a.jsx)(t.p,{children:"Navigate to these pages for step-by-step tutorials on delegating and undelegating tokens."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/delegate-ui",children:"Delegating tokens using a block explorer"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/staking-ledger",children:"Delegating with Ledger devices"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper client"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/users/undelegate-ui",children:"Undelegating tokens using a block explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},17220:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/1.validators-e03196f06d8422ff744f2796db8db22f.png"},31400:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/economic-delegationDetails-39ff9fadcf1ff742716046d64ef6789e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(96540);const i={},o=a.createContext(i);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/870de909.59012146.js b/assets/js/870de909.59012146.js deleted file mode 100644 index d9f083fac..000000000 --- a/assets/js/870de909.59012146.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6755],{91820:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>r,toc:()=>d});var a=n(74848),i=n(28453);const o={},s="Delegating Tokens",r={id:"users/delegating",title:"Delegating Tokens",description:"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.",source:"@site/docs/users/delegating.md",sourceDirName:"users",slug:"/users/delegating",permalink:"/next/users/delegating",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"users",previous:{title:"Funding Mainnet Accounts",permalink:"/next/users/funding-from-exchanges"},next:{title:"Using CSPR.live",permalink:"/next/users/csprlive/"}},l={},d=[{value:"Delegation Cost",id:"delegation-cost",level:2},{value:"Delegation Limits",id:"delegation-limits",level:2},{value:"Selecting a Node for Delegating",id:"selecting-a-node-for-delegating",level:2},{value:"First-time Delegation",id:"first-time-delegation",level:2},{value:"Monitoring Rewards",id:"monitoring-rewards",level:2},{value:"Tutorials",id:"tutorials",level:2}];function c(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"delegating-tokens",children:"Delegating Tokens"})}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as ",(0,a.jsx)(t.strong,{children:"delegating"})," or ",(0,a.jsx)(t.strong,{children:"staking"})," with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider."]}),"\n",(0,a.jsx)(t.p,{children:"Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network."}),"\n",(0,a.jsx)(t.p,{children:"Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate."}),"\n",(0,a.jsx)(t.p,{children:"Casper does not treat validator stake differently than delegator stake for security reasons."}),"\n",(0,a.jsx)(t.h2,{id:"delegation-cost",children:"Delegation Cost"}),"\n",(0,a.jsx)(t.p,{children:"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates to delegations, and where to find more details. Please note that the cost amounts are likely to change over time, and you may have to check the latest release details to get the most up-to-date and accurate delegation cost."}),"\n",(0,a.jsxs)(t.p,{children:["The delegation cost is defined in the chainspec.toml file of a Casper network. In this ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-2.0.0-rc1/resources/production/chainspec.toml",children:"example chainspec"}),", the delegation is set to cost 2.5 CSPR. However, ",(0,a.jsx)(t.code,{children:"when you perform the delegation, you see that it costs a little more"})," than what is specified in the chainspec. Let's discuss why this happens."]}),"\n",(0,a.jsx)(t.p,{children:"When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is added to the delegation cost defined in the chainspec file. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse."}),"\n",(0,a.jsxs)(t.p,{children:["For example, the chainspec file in release 2.0.0 contains the following information. Notice the delegation cost specified with ",(0,a.jsx)(t.code,{children:"delegate"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"[system_costs.auction_costs]\n...\ndelegate = 2_500_000_000\nundelegate = 2_500_000_000\n...\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Delegation fees may change over time, so it is essential to stay current. To do so, select the latest release in ",(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node",children:"Github"})," and navigate to the ",(0,a.jsx)(t.code,{children:"resources/production/chainspec.toml"})," file."]}),"\n",(0,a.jsxs)(t.p,{children:["For further questions, please join the ",(0,a.jsx)(t.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"delegation-limits",children:"Delegation Limits"}),"\n",(0,a.jsx)(t.p,{children:"The chainspec specifies delegation limits, such as the minimum and maximum amount allowed to be delegated. Also, each validator can have a maximum number of delegators."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-toml",children:"# Minimum allowed delegation amount in motes\nminimum_delegation_amount = 500_000_000_000\n# Maximum allowed delegation amount in motes\nmaximum_delegation_amount = 1_000_000_000_000_000_000\n# The maximum amount of delegators per validator.\nmax_delegators_per_validator = 1200\n"})}),"\n",(0,a.jsx)(t.h2,{id:"selecting-a-node-for-delegating",children:"Selecting a Node for Delegating"}),"\n",(0,a.jsxs)(t.p,{children:["As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," provide ",(0,a.jsx)(t.a,{href:"https://cspr.live/validators",children:"validator performance statistics"}),", including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Validators",src:n(47886).A+"",width:"2440",height:"1211"})}),"\n",(0,a.jsx)(t.h2,{id:"first-time-delegation",children:"First-time Delegation"}),"\n",(0,a.jsxs)(t.p,{children:["If you perform a delegation for the first time, the system charges some motes to create a purse to hold the delegated tokens. We recommend that you try out delegations on the ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Casper Testnet"})," before making transactions on the ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Casper Mainnet"}),". This will help you understand the costs involved in delegating tokens."]}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.strong,{children:"Example:"})," The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on ",(0,a.jsx)(t.a,{href:"https://cspr.live/",children:"Mainnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"When you set up a delegation transaction, it is essential to have enough funds in your account's main purse. Otherwise, the transaction will fail, and you will lose the delegation cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer."}),"\n",(0,a.jsxs)(t.p,{children:["As a result, when performing a ",(0,a.jsx)(t.a,{href:"/next/developers/cli/delegate",children:"delegation using the command line"}),", we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure."]}),"\n",(0,a.jsx)(t.p,{children:(0,a.jsx)(t.img,{alt:"Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.",src:n(73026).A+"",width:"1256",height:"1266"})}),"\n",(0,a.jsx)(t.p,{align:"center",children:"\n**Figure 2** : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.\n"}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Transaction costs depend on each Casper network and the cost tables defined in the chainspec. Most of these examples are from the Casper Mainnet or Testnet."})}),"\n",(0,a.jsx)(t.h2,{id:"monitoring-rewards",children:"Monitoring Rewards"}),"\n",(0,a.jsx)(t.p,{children:"It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations."}),"\n",(0,a.jsx)(t.p,{children:"Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours."}),"\n",(0,a.jsx)(t.h2,{id:"tutorials",children:"Tutorials"}),"\n",(0,a.jsx)(t.p,{children:"Navigate to these pages for step-by-step tutorials on delegating and undelegating tokens."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/users/delegate-ui",children:"Delegating tokens using a block explorer"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/users/staking-ledger",children:"Delegating with Ledger devices"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/developers/cli/delegate",children:"Delegating with the Casper client"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/next/users/undelegate-ui",children:"Undelegating tokens using a block explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},47886:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/1.validators-e03196f06d8422ff744f2796db8db22f.png"},73026:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/economic-delegationDetails-39ff9fadcf1ff742716046d64ef6789e.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(96540);const i={},o=a.createContext(i);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/871da383.0bff42d1.js b/assets/js/871da383.0bff42d1.js new file mode 100644 index 000000000..491bba728 --- /dev/null +++ b/assets/js/871da383.0bff42d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50620],{74871:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var a=n(74848),c=n(28453);const r={title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},s="Upgrading a Contract",o={id:"resources/beginner/upgrade-contract",title:"Contract Upgrades",description:"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/upgrade-contract.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/upgrade-contract",permalink:"/2.0.0/resources/tutorials/beginner/upgrade-contract",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Contract Upgrades",slug:"/resources/tutorials/beginner/upgrade-contract"},sidebar:"tutorials",previous:{title:"Querying a Node",permalink:"/2.0.0/resources/tutorials/beginner/querying-network"},next:{title:"Fungible Tokens",permalink:"/2.0.0/resources/tutorials/beginner/cep18"}},i={},l=[{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Contract Versioning Flow",id:"contract-versioning-flow",level:2},{value:"Step 1. Create a new unlocked contract",id:"step-1-create-a-new-unlocked-contract",level:3},{value:"Step 2. Add a new contract to the package",id:"step-2-add-a-new-contract-to-the-package",level:3},{value:"Step 3. Build the contract Wasm",id:"step-3-build-the-contract-wasm",level:3},{value:"Step 4. Install the contract",id:"step-4-install-the-contract",level:3},{value:"Step 5. Verify your changes",id:"step-5-verify-your-changes",level:3},{value:"Disabling and Enabling Contract Versions",id:"disabling-and-enabling-contract-versions",level:2},{value:"Creating a Locked Contract Package",id:"locked-contract-package",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"upgrading-a-contract",children:"Upgrading a Contract"})}),"\n",(0,a.jsxs)(t.p,{children:["This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"contract package"})," by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," API. You can also create a ",(0,a.jsx)(t.a,{href:"#locked-contract-package",children:"locked contract package"})," that cannot be versioned and is therefore not upgradable."]}),"\n",(0,a.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,a.jsx)(t.p,{children:"Here is a video walkthrough of this tutorial."}),"\n",(0,a.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=Q4ZXNV8EVTk&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=4",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,a.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["The ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"})," referencing the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ContractPackage.html",children:"ContractPackage"})," where an unlocked contract is stored in global state."]}),"\n",(0,a.jsxs)(t.li,{children:["You should be familiar with ",(0,a.jsx)(t.a,{href:"/writing-contracts",children:"writing smart contracts"}),", ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"on-chain contracts"}),", and ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/calling-contracts",children:"calling contracts"})," on a Casper network."]}),"\n",(0,a.jsxs)(t.li,{children:["You have installed ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," that you will upgrade as part of this tutorial."]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract (contract-v1.wasm) as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"counter tutorial"})," is a prerequisite before installing the second version of the contract (contract-v2.wasm)."]})}),"\n",(0,a.jsxs)(t.p,{children:["If you explore ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"the code"}),", you will observe the different versions of the contract:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v1"})," is the counter contract you can see in the ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"})," tutorial."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract-v2"})," is the contract with the new ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n"]}),"\n",(0,a.jsx)(t.h2,{id:"contract-versioning-flow",children:"Contract Versioning Flow"}),"\n",(0,a.jsx)(t.p,{children:"The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash."}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["Create a contract in the most common way, using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Add a new version of the contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:["Build the new contract and generate the corresponding ",(0,a.jsx)(t.code,{children:".wasm"})," file."]}),"\n",(0,a.jsx)(t.li,{children:"Install the contract on the network via a deploy."}),"\n",(0,a.jsx)(t.li,{children:"Verify that your new contract version works as desired."}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["In this tutorial, you will use ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v2/src/main.rs",children:"the second version"})," of the counter contract to perform the upgrade."]}),"\n",(0,a.jsx)(t.h3,{id:"step-1-create-a-new-unlocked-contract",children:"Step 1. Create a new unlocked contract"}),"\n",(0,a.jsxs)(t.p,{children:["Create a new contract using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," function and store the ContractHash returned under a key in global state for later access. Under the hood, the execution engine will create a contract package (a container for the contract) that can be versioned."]}),"\n",(0,a.jsx)(t.p,{children:"When creating the contract, you can specify the package name and access URef for further modifications. Without the access key URef, you cannot add new contract versions for security reasons. Optionally, you can also save the latest version of the contract package under a named key."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Create a new contract and specify a package name and access URef for further modifications\n let (stored_contract_hash, contract_version) = storage::new_contract(\n contract_entry_points,\n Some(contract_named_keys),\n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n );\n\n // The hash of the installed contract will be reachable through a named key\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n\n // The current version of the contract will be reachable through a named key\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n'})}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L94",children:"first version of the counter"})," shows you a contract package that can be versioned. This step is covered in the tutorial for ",(0,a.jsx)(t.a,{href:"/counter-testnet/",children:"A Counter on the Testnet"}),"."]}),"\n",(0,a.jsx)(t.p,{children:"Additional details:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"We are versioning the contract package, not the contract. The contract is always at a set version, and the package specifies the contract version to be used."}),"\n",(0,a.jsx)(t.li,{children:"The Wasm file name of the new contract could differ from the old contract; after sending the deploy to the network, the contract package hash connects the different contract versions."}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-2-add-a-new-contract-to-the-package",children:"Step 2. Add a new contract to the package"}),"\n",(0,a.jsx)(t.p,{children:"There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract."}),"\n",(0,a.jsxs)(t.p,{children:["To add a new contract version in the package, invoke the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.add_contract_version.html",children:"add_contract_version"})," function and pass in the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackageHash.html",children:"ContractPackageHash"}),", ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.EntryPoints.html",children:"EntryPoints"}),", and ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"}),". In the counter example, you will find the ",(0,a.jsx)(t.code,{children:"add_contract_version"})," call ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v2/src/main.rs#L164",children:"here"}),"."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:" let (contract_hash, contract_version) = \n storage::add_contract_version(contract_package_hash, \n entry_points, \n named_keys);\n"})}),"\n",(0,a.jsx)(t.p,{children:"Explanation of arguments:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"contract_package_hash"})," - This hash directs you to the contract package. See ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/key-types#hash-and-key-explanations",children:"Hash and Key Explanations"}),"."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"entry_points"})," - Entry points of the contract, which can be modified or newly added."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.code,{children:"named_keys"})," - Named key pairs of the contract."]}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"The new contract version carries on named keys from the previous version. If you specify a new set of named keys, they will be combined with the old named keys in the new contract version. If the old and new contract versions use the same named keys, then the new values would be present in the new version of the contract."}),"\n",(0,a.jsx)(t.p,{children:"You will need to manage contract versioning, considering clients that may use older versions. Here are a few options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:"Pin your client contract to the contract hash of a specific version."}),"\n",(0,a.jsxs)(t.li,{children:["Use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"})," with a version number to pin your client contract to that version."]}),"\n",(0,a.jsxs)(t.li,{children:["Call a contract using ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),' and version "None", which uses the newest version of the contract.']}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"step-3-build-the-contract-wasm",children:"Step 3. Build the contract Wasm"}),"\n",(0,a.jsx)(t.p,{children:"Use these commands to prepare and build the newly added contract:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"make prepare\n\nmake build-contract\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-4-install-the-contract",children:"Step 4. Install the contract"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"Install the contract"})," on the network via a deploy and verify the deploy status. You can also ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions#monitoring-the-event-stream-for-transactions",children:"monitor the event stream"})," to see when your deploy is accepted."]}),"\n",(0,a.jsxs)(t.p,{children:["To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the ",(0,a.jsx)(t.code,{children:"counter_decrement"})," entry point."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Installing the first version of the contract, as shown in the ",(0,a.jsx)(t.a,{href:"/counter-testnet",children:"Counter tutorial"}),", is a prerequisite before installing the second version."]})}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm\n"})}),"\n",(0,a.jsx)(t.h3,{id:"step-5-verify-your-changes",children:"Step 5. Verify your changes"}),"\n",(0,a.jsxs)(t.p,{children:["You can write unit tests to verify the behavior of the new contract version with ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_contract.html",children:"call_contract"})," or ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.call_versioned_contract.html",children:"call_versioned_contract"}),". When you add a new contract to the package (which increments the highest enabled version), you will obtain a new contract hash, the primary identifier of the contract. You can use the contract hash with call_contract. Alternatively, you can use call_versioned_contract and specify the contract_package_hash and the newly added version."]}),"\n",(0,a.jsxs)(t.p,{children:["For the simple example counter above, here are the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"corresponding tests"}),". Notice how the tests store and verify the ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"contract's version"})," and entry points."]}),"\n",(0,a.jsxs)(t.p,{children:["You could store the latest version of the contract package under a NamedKey, as shown ",(0,a.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/57e3912735f93e1d0f667b936675964ecfdc6594/contract-v1/src/main.rs#L107",children:"here"}),". Then, you can query the NamedKey to check the latest version of the contract package."]}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example test function"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' // Verify the contract version is now 2.\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let version_key = *account\n .named_keys()\n .get(CONTRACT_VERSION_KEY)\n .expect("version uref should exist");\n\n let version = builder\n .query(None, version_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<u32>()\n .expect("should be u32.");\n\n assert_eq!(version, 2);\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"You can also test the new entry point by using the Rust command-line client."}),"\n",(0,a.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,a.jsxs)(t.p,{children:["Check the new contract entry points. You should see the ",(0,a.jsx)(t.em,{children:"counter_decrement"})," entry point now."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:' {\n "id": 5602352547578277096,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[54054 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasmc014187ccf3366cca70317d6d567cd56a05ecf1ee50ed3bd02727c2864e3d3a8",\n "contract_wasm_hash": "contract-wasm-64d252f1ab72c7295a85d15c3f456f8bdda586580b0b7106e203fa4fd83f05d7",\n "entry_points": [\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_decrement",\n "ret": "Unit"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_get",\n "ret": "I32"\n },\n {\n "access": "Public",\n "args": [],\n "entry_point_type": "Contract",\n "name": "counter_inc",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-ca980a2e4c08dc3f233b728b22b909cd4e894295155a7902bf88a59eac1531d1-007",\n "name": "count"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(t.p,{children:"Check the version and package details with the latest state root hash:"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "version"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 9084525900533244372,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[64874 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "02000000",\n "cl_type": "U32",\n "parsed": 2\n }\n }\n }\n\n'})}),"\n"]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter_package_name"\n'})}),"\n",(0,a.jsxs)(t.details,{children:["\n",(0,a.jsx)(t.summary,{children:"Example output"}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'{\n "id": 6933525663267881367,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[52174 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-101817ffd5aa47b08ca710649dbdc41edf0a20d7802c736d34053656c0a99eaf-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-4ee8a4cfbc0a183d189611b6a14c0f7b57e7635fa17a8acfc5c645fec4c36316",\n "contract_version": 1,\n "protocol_version_major": 1\n },\n {\n "contract_hash": "contract-2cd9f6485423ba846fae83729016b03df26d9babb939466906c8f1d168b40949",\n "contract_version": 2,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["Call the new entry point, ",(0,a.jsx)(t.em,{children:"counter_decrement"}),", using the package name and check the results."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter_decrement"\n'})}),"\n",(0,a.jsxs)(t.admonition,{type:"note",children:[(0,a.jsx)(t.p,{children:"There are two ways to call versioned contracts:"}),(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/calling-contracts#storedcontractbyhash",children:"Calling Contracts by Package Hash"})}),"\n",(0,a.jsx)(t.li,{children:(0,a.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/calling-contracts#storedcontractbyname",children:"Calling Contracts by Package Name"})}),"\n"]})]}),"\n",(0,a.jsx)(t.p,{children:"After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash."}),"\n",(0,a.jsx)(t.h2,{id:"disabling-and-enabling-contract-versions",children:"Disabling and Enabling Contract Versions"}),"\n",(0,a.jsxs)(t.p,{children:["You can disable a contract version within a contract package by using the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.disable_contract_version.html",children:"disable_contract_version"})," function."]}),"\n",(0,a.jsx)(t.p,{children:"Disabled contract versions can no longer be executed. As such, if there is only a single contract version within the package, you will no longer be able to use the contract."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.enable_contract_version.html",children:"Enable_contract_version"})," allows you to re-enable a previously disabled contract version."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsx)(t.p,{children:"Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so."})}),"\n",(0,a.jsx)(t.h2,{id:"locked-contract-package",children:"Creating a Locked Contract Package"}),"\n",(0,a.jsxs)(t.p,{children:["You can create a locked contract package with the ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," function. This contract can never be upgraded."]}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'let (stored_contract_hash, _) = storage::new_locked_contract(\n contract_entry_points, \n Some(contract_named_keys), \n Some("contract_package_name".to_string()),\n Some("contract_access_uref".to_string()),\n);\n'})}),"\n",(0,a.jsx)(t.p,{children:"Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1."}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Creating a locked contract package is an irreversible decision. To upgrade a contract, use ",(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," as Step 1 explains."]})})]})}function d(e={}){const{wrapper:t}={...(0,c.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>o});var a=n(96540);const c={},r=a.createContext(c);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8768801e.c7c6d258.js b/assets/js/8768801e.c7c6d258.js new file mode 100644 index 000000000..6ef3a8829 --- /dev/null +++ b/assets/js/8768801e.c7c6d258.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67840],{44006:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var c=t(74848),a=t(28453);const s={title:"Contract Hash vs. Package Hash"},r="Using the Contract Hash vs. the Package Hash",o={id:"developers/writing-onchain-code/contract-hash-vs-package-hash",title:"Contract Hash vs. Package Hash",description:"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-hash-vs-package-hash",permalink:"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Contract Hash vs. Package Hash"},sidebar:"developers",previous:{title:"Contract-Level Events",permalink:"/2.0.0/developers/writing-onchain-code/emitting-contract-events"},next:{title:"Factory Contracts",permalink:"/2.0.0/developers/writing-onchain-code/factory-pattern"}},h={},i=[{value:"The Casper Call Stack",id:"the-casper-call-stack",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"using-the-contract-hash-vs-the-package-hash",children:"Using the Contract Hash vs. the Package Hash"})}),"\n",(0,c.jsxs)(n.p,{children:["This page describes the possibilities of using the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html",children:"contract hash"})," vs. the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html",children:"contract package hash"})," (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 ",(0,c.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:"Upgrading and Maintaining Smart Contracts"}),", 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."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Package Representation",src:t(26133).A+"",width:"1170",height:"472"})}),"\n",(0,c.jsx)(n.p,{children:"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:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Want to identify specific versions of contracts within the same package and thus use a contract hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Need specific contract versions within the same package, and thus use both contract hash and contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need either hash for this use case"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers loosely at the package level?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers specifically at the contract level?"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Or a more fine-grained variation would be:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow or block callers at the package level but track by both package and contract hash?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow other combinations of these basic concepts?"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["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 ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/",children:"Casper External FFI"}),", versus use cases and interactions between two or more ecosystem entities such as accounts and contracts."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.h2,{id:"the-casper-call-stack",children:"The Casper Call Stack"}),"\n",(0,c.jsxs)(n.p,{children:["When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html",children:"casper_load_call_stack"}),", which provides a stack of one or more entries of this kind:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-rust",children:"/// Represents the origin of a sub-call.\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum CallStackElement {\n /// Session\n Session {\n /// The account hash of the caller\n account_hash: AccountHash,\n },\n /// Effectively an EntryPointType::Session - stored access to a session.\n StoredSession {\n /// The account hash of the caller\n account_hash: AccountHash,\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n /// contract\n StoredContract {\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["You can find the source code ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs",children:"here"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine."}),"\n",(0,c.jsxs)(n.p,{children:["Learn more about ",(0,c.jsx)(n.a,{href:"/2.0.0/concepts/callstack",children:"Call Stacks"})," and how Casper manages the calling of a contract."]}),"\n",(0,c.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,c.jsx)(n.p,{children:"Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash."}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only accounts to use the contract? If so, what kind of accounts are you considering?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify and track each account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Exactly one specific account"}),(0,c.jsx)(n.td,{children:"Use the account hash of a specific account to identify it."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts"}),(0,c.jsx)(n.td,{children:"There is no need to track the accounts by account hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only contracts to use it? If so, what kind of contracts?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions"}),(0,c.jsx)(n.td,{children:"Use the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the contract hash and the package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use only the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract version of any contract"}),(0,c.jsx)(n.td,{children:"There is no need to track by contract or package hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and contract versions"}),(0,c.jsx)(n.td,{children:"Use the account hash to track each account and the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and specific versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the contract hash and package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and any versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts and contracts"}),(0,c.jsx)(n.td,{children:"There is no need to track by account hash or contract hash."})]})]})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/cross-contract",children:"Cross-Contract Communication"})," - Variations of cross-contract communication for more complex scenarios"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," - Contract code returning a value to the immediate caller via ",(0,c.jsx)(n.code,{children:"runtime::ret()"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},26133:(e,n,t)=>{t.d(n,{A:()=>c});const c=t.p+"assets/images/package-representation-extended-a8ed26938de11cc769bc8fc6d8852b1b.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/87867a42.4e487d7d.js b/assets/js/87867a42.4e487d7d.js new file mode 100644 index 000000000..be1b6869a --- /dev/null +++ b/assets/js/87867a42.4e487d7d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29040],{57209:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),a=t(28453);const i={},o="Becoming a Validator",d={id:"operators/becoming-a-validator/index",title:"Becoming a Validator",description:"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/index.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/",permalink:"/2.0.0/operators/becoming-a-validator/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"operators",previous:{title:"Sidecar Setup",permalink:"/2.0.0/operators/setup/casper-sidecar"},next:{title:"Bonding",permalink:"/2.0.0/operators/becoming-a-validator/bonding"}},s={},c=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"becoming-a-validator",children:"Becoming a Validator"})}),"\n",(0,r.jsxs)(n.p,{children:["After ",(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/",children:"setting up a node"}),", the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/bonding",children:"Bonding as a Validator"})}),(0,r.jsx)(n.td,{children:"A guide about the bonding process and submitting a bid"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/unbonding",children:"Unbonding as a Validator"})}),(0,r.jsx)(n.td,{children:"The process to withdraw a bid and unbonding"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/recovering",children:"Recovering from Validator Eviction"})}),(0,r.jsx)(n.td,{children:"Steps a validator needs to take if it is evicted from the validator set"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Nodes"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/change-bid-public-key",children:"Change bid public key"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var r=t(96540);const a={},i=r.createContext(a);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/87f5bee7.11d7c141.js b/assets/js/87f5bee7.11d7c141.js new file mode 100644 index 000000000..47810172e --- /dev/null +++ b/assets/js/87f5bee7.11d7c141.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63144],{58116:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="X",a={id:"concepts/glossary/X",title:"X",description:"---",source:"@site/docs/concepts/glossary/X.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/X",permalink:"/concepts/glossary/X",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"W",permalink:"/concepts/glossary/W"},next:{title:"Y",permalink:"/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"x",children:"X"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/87f5bee7.c06abb9f.js b/assets/js/87f5bee7.c06abb9f.js deleted file mode 100644 index 4358f0cfb..000000000 --- a/assets/js/87f5bee7.c06abb9f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3144],{58116:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="X",a={id:"concepts/glossary/X",title:"X",description:"---",source:"@site/docs/concepts/glossary/X.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/X",permalink:"/next/concepts/glossary/X",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"W",permalink:"/next/concepts/glossary/W"},next:{title:"Y",permalink:"/next/concepts/glossary/Y"}},l={},h=[];function x(e){const s={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"x",children:"X"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/883310e5.f489e4cb.js b/assets/js/883310e5.f489e4cb.js new file mode 100644 index 000000000..1a4355530 --- /dev/null +++ b/assets/js/883310e5.f489e4cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3048],{57558:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var a=n(74848),r=n(28453);const s={title:"Reading and Writing Data"},i="Reading and Writing Data to Global State",o={id:"concepts/design/reading-and-writing-to-the-blockchain",title:"Reading and Writing Data",description:"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.",source:"@site/versioned_docs/version-1.5.X/concepts/design/reading-and-writing-to-the-blockchain.md",sourceDirName:"concepts/design",slug:"/concepts/design/reading-and-writing-to-the-blockchain",permalink:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Reading and Writing Data"},sidebar:"concepts",previous:{title:"Highway Consensus",permalink:"/1.5.X/concepts/design/highway"},next:{title:"Overview",permalink:"/1.5.X/economics"}},c={},d=[{value:"Using the Casper JSON-RPC",id:"using-the-casper-json-rpc",level:2},{value:"Using the Casper Rust API",id:"using-the-casper-rust-api",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"reading-and-writing-data-to-global-state",children:"Reading and Writing Data to Global State"})}),"\n",(0,a.jsxs)(t.p,{children:["Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/dictionaries",children:"Dictionaries"})," or ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#namedkey",children:(0,a.jsx)(t.code,{children:"NamedKeys"})}),"."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Due to the nature of Casper's serialization standard, ",(0,a.jsx)(t.code,{children:"NamedKeys"})," should be used sparingly and only for small data sets. Developers should use dictionaries for larger mapped structures."]})}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-json-rpc",children:"Using the Casper JSON-RPC"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational#query-global-state",children:(0,a.jsx)(t.code,{children:"query_global_state"})})," method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the ",(0,a.jsx)(t.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})," tutorial."]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-rust-api",children:"Using the Casper Rust API"}),"\n",(0,a.jsx)(t.p,{children:"The Casper API includes the following functions for reading and writing to global state:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:"put_key"})," - Stores the given ",(0,a.jsx)(t.code,{children:"Key"})," under the given ",(0,a.jsx)(t.code,{children:"name"})," in the current context's named keys"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:"get_key"})," - Returns the requested ",(0,a.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:"storage::new_uref"})," - Creates a new URef in the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:"storage::write"})," - Writes a given value under a previously created URef"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:"storage::read"})," - Reads the value from a URef in global state"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:"dictionary_put"})," - Writes the given value under the given ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:"dictionary_get"})," - Retrieves the value stored under a ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["For more details, see the ",(0,a.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})," tutorial."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var a=n(96540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/883310e5.f84c5342.js b/assets/js/883310e5.f84c5342.js deleted file mode 100644 index 0fee365e3..000000000 --- a/assets/js/883310e5.f84c5342.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3048],{57558:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var a=n(74848),r=n(28453);const s={title:"Reading and Writing Data"},i="Reading and Writing Data to Global State",o={id:"concepts/design/reading-and-writing-to-the-blockchain",title:"Reading and Writing Data",description:"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.",source:"@site/versioned_docs/version-1.5.X/concepts/design/reading-and-writing-to-the-blockchain.md",sourceDirName:"concepts/design",slug:"/concepts/design/reading-and-writing-to-the-blockchain",permalink:"/concepts/design/reading-and-writing-to-the-blockchain",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Reading and Writing Data"},sidebar:"concepts",previous:{title:"Highway Consensus",permalink:"/concepts/design/highway"},next:{title:"Overview",permalink:"/economics"}},c={},d=[{value:"Using the Casper JSON-RPC",id:"using-the-casper-json-rpc",level:2},{value:"Using the Casper Rust API",id:"using-the-casper-rust-api",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"reading-and-writing-data-to-global-state",children:"Reading and Writing Data to Global State"})}),"\n",(0,a.jsxs)(t.p,{children:["Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using ",(0,a.jsx)(t.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," or ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:(0,a.jsx)(t.code,{children:"NamedKeys"})}),"."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Due to the nature of Casper's serialization standard, ",(0,a.jsx)(t.code,{children:"NamedKeys"})," should be used sparingly and only for small data sets. Developers should use dictionaries for larger mapped structures."]})}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-json-rpc",children:"Using the Casper JSON-RPC"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-informational#query-global-state",children:(0,a.jsx)(t.code,{children:"query_global_state"})})," method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the ",(0,a.jsx)(t.a,{href:"/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})," tutorial."]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-rust-api",children:"Using the Casper Rust API"}),"\n",(0,a.jsx)(t.p,{children:"The Casper API includes the following functions for reading and writing to global state:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:"put_key"})," - Stores the given ",(0,a.jsx)(t.code,{children:"Key"})," under the given ",(0,a.jsx)(t.code,{children:"name"})," in the current context's named keys"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:"get_key"})," - Returns the requested ",(0,a.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:"storage::new_uref"})," - Creates a new URef in the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:"storage::write"})," - Writes a given value under a previously created URef"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:"storage::read"})," - Reads the value from a URef in global state"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:"dictionary_put"})," - Writes the given value under the given ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:"dictionary_get"})," - Retrieves the value stored under a ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["For more details, see the ",(0,a.jsx)(t.a,{href:"/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})," tutorial."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var a=n(96540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8833ab21.2f4414a2.js b/assets/js/8833ab21.2f4414a2.js new file mode 100644 index 000000000..a61fa952d --- /dev/null +++ b/assets/js/8833ab21.2f4414a2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28875],{66079:e=>{e.exports=JSON.parse('{"author":{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov","count":1},"listMetadata":{"permalink":"/blog/authors/alexanderlimonov","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/8833ab21.8e10ccb3.js b/assets/js/8833ab21.8e10ccb3.js deleted file mode 100644 index 80bb492fa..000000000 --- a/assets/js/8833ab21.8e10ccb3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8875],{66079:e=>{e.exports=JSON.parse('{"author":{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov","count":1},"listMetadata":{"permalink":"/blog/authors/alexanderlimonov","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/8941358f.b44c7608.js b/assets/js/8941358f.b44c7608.js deleted file mode 100644 index 74a506b2d..000000000 --- a/assets/js/8941358f.b44c7608.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5469],{33366:(e,a,o)=>{o.r(a),o.d(a,{assets:()=>i,contentTitle:()=>s,default:()=>p,frontMatter:()=>n,metadata:()=>d,toc:()=>l});var t=o(74848),r=o(28453);const n={title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},s="Validator rewards with Casper 2.0",d={permalink:"/blog/condor-validator-rewards",source:"@site/blog/2024-08-20-validator-rewards.md",title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",date:"2024-08-20T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"validators",permalink:"/blog/tags/validators"}],readingTime:6.96,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"},{name:"Alexander Limonov",page:{permalink:"/blog/authors/alexanderlimonov"},title:"Economist for Casper Labs",url:"https://github.com/AlexanderLimonov",permalink:"/alexanderlimonov",imageURL:"https://github.com/AlexanderLimonov.png",key:"alexanderlimonov"}],frontMatter:{title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"}},i={authorsImageUrls:[void 0,void 0]},l=[];function c(e){const a={p:"p",...(0,r.R)(),...e.components};return(0,t.jsx)(a.p,{children:"In this post we discuss the changes to validator rewards in Casper v2.0."})}function p(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,a,o)=>{o.d(a,{R:()=>s,x:()=>d});var t=o(96540);const r={},n=t.createContext(r);function s(e){const a=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function d(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),t.createElement(n.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8941358f.e38b3228.js b/assets/js/8941358f.e38b3228.js new file mode 100644 index 000000000..9d2c41ed3 --- /dev/null +++ b/assets/js/8941358f.e38b3228.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95469],{33366:(e,a,o)=>{o.r(a),o.d(a,{assets:()=>i,contentTitle:()=>s,default:()=>p,frontMatter:()=>n,metadata:()=>d,toc:()=>l});var t=o(74848),r=o(28453);const n={title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},s="Validator rewards with Casper 2.0",d={permalink:"/blog/condor-validator-rewards",source:"@site/blog/2024-08-20-validator-rewards.md",title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",date:"2024-08-20T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!1,label:"Validators",permalink:"/blog/tags/validators",description:"Validators"}],readingTime:6.96,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"},{name:"Alexander Limonov",page:{permalink:"/blog/authors/alexanderlimonov"},title:"Economist for Casper Labs",url:"https://github.com/AlexanderLimonov",permalink:"/alexanderlimonov",imageURL:"https://github.com/AlexanderLimonov.png",key:"alexanderlimonov"}],frontMatter:{title:"validator rewards in Casper 2.0",description:"A discussion of validator rewards under Casper 2.0",slug:"condor-validator-rewards",date:"2024-08-20T18:00",authors:["melpadden","alexanderlimonov"],tags:["condor","validators"],hide_table_of_contents:!1},unlisted:!1,nextItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"}},i={authorsImageUrls:[void 0,void 0]},l=[];function c(e){const a={p:"p",...(0,r.R)(),...e.components};return(0,t.jsx)(a.p,{children:"In this post we discuss the changes to validator rewards in Casper v2.0."})}function p(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,t.jsx)(a,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,a,o)=>{o.d(a,{R:()=>s,x:()=>d});var t=o(96540);const r={},n=t.createContext(r);function s(e){const a=t.useContext(n);return t.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function d(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),t.createElement(n.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/897e9cb3.4f6ab0e4.js b/assets/js/897e9cb3.4f6ab0e4.js new file mode 100644 index 000000000..43af31fee --- /dev/null +++ b/assets/js/897e9cb3.4f6ab0e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72035],{1368:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=s(74848),r=s(28453);const i={title:"Testing NFTs"},c="Testing NFT Contracts",o={id:"resources/tokens/cep78/using-casper-client/testing-NFTs",title:"Testing NFTs",description:"Prerequisites",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/testing-NFTs",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testing NFTs"},sidebar:"resources",previous:{title:"CEP-78 Contract Details",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs"},next:{title:"Ownership Lookup",permalink:"/1.5.X/resources/tokens/cep78/reverse-lookup"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Framework Description",id:"framework-description",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function u(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"testing-nft-contracts",children:"Testing NFT Contracts"})}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Install the contract using the ",(0,n.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,n.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"framework-description",children:"Framework Description"}),"\n",(0,n.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/tests/src",children:"tests"})," source folder contains over 150 tests covering a variety of scenarios, including contract installation, minting and burning tokens, sending transfers, upgrading the contract, and listening to events."]}),"\n",(0,n.jsxs)(t.p,{children:["For more details about the test framework and how each test is set up, visit the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," documentation page."]}),"\n",(0,n.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,n.jsx)(t.p,{children:"To build and run the tests, issue the following command in the project folder:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The project contains a ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,n.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,n.jsx)(t.code,{children:"contract.wasm"})," file to the corresponding version folder in a ",(0,n.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,n.jsx)(t.code,{children:"make test"})," command during development without building the contract separately."]}),"\n",(0,n.jsxs)(t.p,{children:["This example uses ",(0,n.jsx)(t.code,{children:"bash"}),". If you use a Rust IDE, you must configure it to run the tests."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/897e9cb3.7555ccf7.js b/assets/js/897e9cb3.7555ccf7.js deleted file mode 100644 index b9ecc65e8..000000000 --- a/assets/js/897e9cb3.7555ccf7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2035],{1368:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var n=s(74848),r=s(28453);const i={title:"Testing NFTs"},c="Testing NFT Contracts",o={id:"resources/tokens/cep78/using-casper-client/testing-NFTs",title:"Testing NFTs",description:"Prerequisites",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/testing-NFTs",permalink:"/resources/tokens/cep78/using-casper-client/testing-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testing NFTs"},sidebar:"resources",previous:{title:"CEP-78 Contract Details",permalink:"/resources/tokens/cep78/using-casper-client/querying-NFTs"},next:{title:"Ownership Lookup",permalink:"/resources/tokens/cep78/reverse-lookup"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Framework Description",id:"framework-description",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function u(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"testing-nft-contracts",children:"Testing NFT Contracts"})}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Install the contract using the ",(0,n.jsx)(t.a,{href:"/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,n.jsx)(t.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"framework-description",children:"Framework Description"}),"\n",(0,n.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/tests/src",children:"tests"})," source folder contains over 150 tests covering a variety of scenarios, including contract installation, minting and burning tokens, sending transfers, upgrading the contract, and listening to events."]}),"\n",(0,n.jsxs)(t.p,{children:["For more details about the test framework and how each test is set up, visit the ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," documentation page."]}),"\n",(0,n.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,n.jsx)(t.p,{children:"To build and run the tests, issue the following command in the project folder:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The project contains a ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,n.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,n.jsx)(t.code,{children:"contract.wasm"})," file to the corresponding version folder in a ",(0,n.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,n.jsx)(t.code,{children:"make test"})," command during development without building the contract separately."]}),"\n",(0,n.jsxs)(t.p,{children:["This example uses ",(0,n.jsx)(t.code,{children:"bash"}),". If you use a Rust IDE, you must configure it to run the tests."]})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>o});var n=s(96540);const r={},i=n.createContext(r);function c(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89c22482.8436b3a0.js b/assets/js/89c22482.8436b3a0.js deleted file mode 100644 index 5297a2c4e..000000000 --- a/assets/js/89c22482.8436b3a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3781],{40611:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Block Explorers"},i="Block Explorers",a={id:"users/block-explorer",title:"Block Explorers",description:"The Casper blockchain is available as the Mainnet and Testnet.",source:"@site/docs/users/block-explorer.md",sourceDirName:"users",slug:"/users/block-explorer",permalink:"/next/users/block-explorer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Block Explorers"},sidebar:"users",previous:{title:"Users Overview",permalink:"/next/users/"},next:{title:"Funding Mainnet Accounts",permalink:"/next/users/funding-from-exchanges"}},l={},c=[{value:"What is a Block Explorer",id:"what-is-a-block-explorer",level:2},{value:"Using a Block Explorer",id:"using-a-block-explorer",level:2}];function h(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"block-explorers",children:"Block Explorers"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper blockchain is available as the Mainnet and Testnet.\nThe Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR).\nThe Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet."}),"\n",(0,t.jsx)(n.p,{children:"You can use block explorers to explore the Casper blockchain such as :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"what-is-a-block-explorer",children:"What is a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history."}),"\n",(0,t.jsx)(n.h2,{id:"using-a-block-explorer",children:"Using a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator."}),"\n",(0,t.jsxs)(n.p,{children:["The following topics link you to detailed instructions on using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to access and work with your CSPR tokens."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn how to access your Casper account using the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the process of ",(0,t.jsx)(n.a,{href:"/next/users/token-transfer",children:"Transferring Tokens using a Block Explorer"})]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the concepts and the process of ",(0,t.jsx)(n.a,{href:"/next/users/delegate-ui",children:"Delegating"})," and ",(0,t.jsx)(n.a,{href:"/next/users/undelegate-ui",children:"Undelegating"})," CSPR tokens"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["To perform actions using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, you must sign in to your Casper account using one of the wallets provided."]})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89c22482.b950b66f.js b/assets/js/89c22482.b950b66f.js new file mode 100644 index 000000000..be20d8c41 --- /dev/null +++ b/assets/js/89c22482.b950b66f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63781],{40611:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Block Explorers"},i="Block Explorers",a={id:"users/block-explorer",title:"Block Explorers",description:"The Casper blockchain is available as the Mainnet and Testnet.",source:"@site/docs/users/block-explorer.md",sourceDirName:"users",slug:"/users/block-explorer",permalink:"/users/block-explorer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Block Explorers"},sidebar:"users",previous:{title:"Users Overview",permalink:"/users/"},next:{title:"Funding Mainnet Accounts",permalink:"/users/funding-from-exchanges"}},l={},c=[{value:"What is a Block Explorer",id:"what-is-a-block-explorer",level:2},{value:"Using a Block Explorer",id:"using-a-block-explorer",level:2}];function h(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"block-explorers",children:"Block Explorers"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper blockchain is available as the Mainnet and Testnet.\nThe Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR).\nThe Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet."}),"\n",(0,t.jsx)(n.p,{children:"You can use block explorers to explore the Casper blockchain such as :"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"what-is-a-block-explorer",children:"What is a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history."}),"\n",(0,t.jsx)(n.h2,{id:"using-a-block-explorer",children:"Using a Block Explorer"}),"\n",(0,t.jsx)(n.p,{children:"You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator."}),"\n",(0,t.jsxs)(n.p,{children:["The following topics link you to detailed instructions on using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to access and work with your CSPR tokens."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn how to access your Casper account using the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the process of ",(0,t.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens using a Block Explorer"})]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the concepts and the process of ",(0,t.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating"})," and ",(0,t.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating"})," CSPR tokens"]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["To perform actions using the ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, you must sign in to your Casper account using one of the wallets provided."]})})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89d896be.164f310b.js b/assets/js/89d896be.164f310b.js new file mode 100644 index 000000000..cdbe692e3 --- /dev/null +++ b/assets/js/89d896be.164f310b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43852],{18069:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=s(74848),c=s(28453);const t={title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},o="CEP-18 Token Transfers and Allowances",r={id:"resources/tokens/cep18/transfer",title:"CEP-18 Transfers",description:"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.",source:"@site/docs/resources/tokens/cep18/transfer.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/transfer",permalink:"/resources/tokens/cep18/transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},sidebar:"resources",previous:{title:"CEP-18 Contract Details",permalink:"/resources/tokens/cep18/query"},next:{title:"Testing Guide",permalink:"/resources/tokens/cep18/tests"}},i={},d=[{value:"Transferring CEP-18 Tokens to Another Account",id:"transferring-cep-18-tokens-to-another-account",level:2},{value:"Invoking the <code>check_balance_of</code> Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}];function h(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cep-18-token-transfers-and-allowances",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,a.jsxs)(n.p,{children:["This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."]}),"\n",(0,a.jsx)(n.h2,{id:"transferring-cep-18-tokens-to-another-account",children:"Transferring CEP-18 Tokens to Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The following command will invoke the ",(0,a.jsx)(n.code,{children:"transfer"})," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name <CHAIN NAME>\\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n--chain-name <CHAIN NAME>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,a.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the utility contract to verify the account's balance."]}),"\n",(0,a.jsxs)(n.h3,{id:"invoking-the-check_balance_of-entry-point",children:["Invoking the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," Entry Point"]}),"\n",(0,a.jsxs)(n.p,{children:["The following Casper client command invokes the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the ",(0,a.jsx)(n.code,{children:"cep18_test_contract"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["After sending this command, you will need to query the ",(0,a.jsx)(n.code,{children:"results"})," URef within the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," of your ",(0,a.jsx)(n.code,{children:"cep18_test_contract"})," utility contract instance. More information on finding this URef can be found in the ",(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/query#querying-the-utility-contract",children:"Exploring the CEP18 Contracts"})," document."]}),"\n",(0,a.jsxs)(n.p,{children:["You can use the following command to query global state for the ",(0,a.jsx)(n.code,{children:"results"})," URef."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command should show something similar to the following in response, with ",(0,a.jsx)(n.code,{children:"parsed"})," being the amount of CEP-18 tokens that the account holds."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approving-an-allowance-for-another-account",children:"Approving an Allowance for Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The Casper fungible token contract features an ",(0,a.jsx)(n.code,{children:"allowance"})," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."]}),"\n",(0,a.jsx)(n.h3,{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",children:"Approving an Account to Spend Tokens on Another Account's Behalf"}),"\n",(0,a.jsxs)(n.p,{children:["The following command approves a third-party account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"verifying-a-previously-issued-allowance",children:"Verifying a Previously Issued Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["After approving an account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,a.jsx)(n.code,{children:"allowance"})," of the spender's account to the ",(0,a.jsx)(n.code,{children:"result"})," URef of in the utility contract's ",(0,a.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following command queries global state to return the value stored under the ",(0,a.jsx)(n.code,{children:"result"})," URef:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You should get a response similar to the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"transferring-tokens-from-an-allowance",children:"Transferring Tokens from an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,a.jsx)(n.code,{children:"allowance"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"increasing-and-decreasing-an-allowance",children:"Increasing and Decreasing an Allowance"}),"\n",(0,a.jsx)(n.h4,{id:"increasing-an-allowance",children:"Increasing an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command increases the designated ",(0,a.jsx)(n.code,{children:"allowance"})," for the provided account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"decreasing-an-allowance",children:"Decreasing an Allowance"}),"\n",(0,a.jsx)(n.p,{children:"The following command decreases the designated allowance for the provided account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"minting-and-burning-additional-cep-18-tokens",children:"Minting and Burning Additional CEP-18 Tokens"}),"\n",(0,a.jsx)(n.h4,{id:"minting-additional-tokens",children:"Minting Additional Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"burning-tokens",children:"Burning Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"changing-account-security-permissions",children:"Changing Account Security Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"change_security"})," entrypoint can be used by an account with ",(0,a.jsx)(n.code,{children:"admin"})," access to alter the security level of other accounts."]}),"\n",(0,a.jsx)(n.p,{children:"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"None"})," - ",(0,a.jsx)(n.code,{children:"None"})," overrides other security levels and removes all admin, minting and burning access of an account."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Admin"})," - Allows the account full access and control over the CEP-18 contract."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"MintAndBurn"})," - Allows the account to mint new tokens and burn existing tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Burner"})," - The account can burn tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Minter"})," - The account can mint new tokens."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Here is an example of a ",(0,a.jsx)(n.code,{children:"session-arg"})," that provides a list of account hashes to be included on the ",(0,a.jsx)(n.code,{children:"mint_and_burn_list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Be aware that removing all admin accounts will lock out all admin functionality."})}),"\n",(0,a.jsx)(n.p,{children:"The following command can be supplied with any of the optional arguments above:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'<List of account hashes>\'" \\\n--session-arg "admin_list:string:\'<List of account hashes>\'" \\\n--session-arg "mint_and_burn_list:string:\'<List of account hashes>\'" \\\n--session-arg "burner_list:string:\'<List of account hashes>\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsx)(n.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var a=s(96540);const c={},t=a.createContext(c);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/89d896be.f7cb4e66.js b/assets/js/89d896be.f7cb4e66.js deleted file mode 100644 index 391bf813a..000000000 --- a/assets/js/89d896be.f7cb4e66.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3852],{18069:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=s(74848),c=s(28453);const t={title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},o="CEP-18 Token Transfers and Allowances",r={id:"resources/tokens/cep18/transfer",title:"CEP-18 Transfers",description:"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.",source:"@site/docs/resources/tokens/cep18/transfer.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/transfer",permalink:"/next/resources/tokens/cep18/transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},sidebar:"resources",previous:{title:"CEP-18 Contract Details",permalink:"/next/resources/tokens/cep18/query"},next:{title:"Testing Guide",permalink:"/next/resources/tokens/cep18/tests"}},i={},d=[{value:"Transferring CEP-18 Tokens to Another Account",id:"transferring-cep-18-tokens-to-another-account",level:2},{value:"Invoking the <code>check_balance_of</code> Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}];function h(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cep-18-token-transfers-and-allowances",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,a.jsxs)(n.p,{children:["This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,a.jsx)(n.a,{href:"/next/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."]}),"\n",(0,a.jsx)(n.h2,{id:"transferring-cep-18-tokens-to-another-account",children:"Transferring CEP-18 Tokens to Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The following command will invoke the ",(0,a.jsx)(n.code,{children:"transfer"})," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name <CHAIN NAME>\\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n--chain-name <CHAIN NAME>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,a.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the utility contract to verify the account's balance."]}),"\n",(0,a.jsxs)(n.h3,{id:"invoking-the-check_balance_of-entry-point",children:["Invoking the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," Entry Point"]}),"\n",(0,a.jsxs)(n.p,{children:["The following Casper client command invokes the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the ",(0,a.jsx)(n.code,{children:"cep18_test_contract"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["After sending this command, you will need to query the ",(0,a.jsx)(n.code,{children:"results"})," URef within the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," of your ",(0,a.jsx)(n.code,{children:"cep18_test_contract"})," utility contract instance. More information on finding this URef can be found in the ",(0,a.jsx)(n.a,{href:"/next/resources/tokens/cep18/query#querying-the-utility-contract",children:"Exploring the CEP18 Contracts"})," document."]}),"\n",(0,a.jsxs)(n.p,{children:["You can use the following command to query global state for the ",(0,a.jsx)(n.code,{children:"results"})," URef."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command should show something similar to the following in response, with ",(0,a.jsx)(n.code,{children:"parsed"})," being the amount of CEP-18 tokens that the account holds."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approving-an-allowance-for-another-account",children:"Approving an Allowance for Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The Casper fungible token contract features an ",(0,a.jsx)(n.code,{children:"allowance"})," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."]}),"\n",(0,a.jsx)(n.h3,{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",children:"Approving an Account to Spend Tokens on Another Account's Behalf"}),"\n",(0,a.jsxs)(n.p,{children:["The following command approves a third-party account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"verifying-a-previously-issued-allowance",children:"Verifying a Previously Issued Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["After approving an account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,a.jsx)(n.code,{children:"allowance"})," of the spender's account to the ",(0,a.jsx)(n.code,{children:"result"})," URef of in the utility contract's ",(0,a.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following command queries global state to return the value stored under the ",(0,a.jsx)(n.code,{children:"result"})," URef:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You should get a response similar to the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"transferring-tokens-from-an-allowance",children:"Transferring Tokens from an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,a.jsx)(n.code,{children:"allowance"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"increasing-and-decreasing-an-allowance",children:"Increasing and Decreasing an Allowance"}),"\n",(0,a.jsx)(n.h4,{id:"increasing-an-allowance",children:"Increasing an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command increases the designated ",(0,a.jsx)(n.code,{children:"allowance"})," for the provided account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"decreasing-an-allowance",children:"Decreasing an Allowance"}),"\n",(0,a.jsx)(n.p,{children:"The following command decreases the designated allowance for the provided account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"minting-and-burning-additional-cep-18-tokens",children:"Minting and Burning Additional CEP-18 Tokens"}),"\n",(0,a.jsx)(n.h4,{id:"minting-additional-tokens",children:"Minting Additional Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"burning-tokens",children:"Burning Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"changing-account-security-permissions",children:"Changing Account Security Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"change_security"})," entrypoint can be used by an account with ",(0,a.jsx)(n.code,{children:"admin"})," access to alter the security level of other accounts."]}),"\n",(0,a.jsx)(n.p,{children:"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"None"})," - ",(0,a.jsx)(n.code,{children:"None"})," overrides other security levels and removes all admin, minting and burning access of an account."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Admin"})," - Allows the account full access and control over the CEP-18 contract."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"MintAndBurn"})," - Allows the account to mint new tokens and burn existing tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Burner"})," - The account can burn tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Minter"})," - The account can mint new tokens."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Here is an example of a ",(0,a.jsx)(n.code,{children:"session-arg"})," that provides a list of account hashes to be included on the ",(0,a.jsx)(n.code,{children:"mint_and_burn_list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Be aware that removing all admin accounts will lock out all admin functionality."})}),"\n",(0,a.jsx)(n.p,{children:"The following command can be supplied with any of the optional arguments above:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'<List of account hashes>\'" \\\n--session-arg "admin_list:string:\'<List of account hashes>\'" \\\n--session-arg "mint_and_burn_list:string:\'<List of account hashes>\'" \\\n--session-arg "burner_list:string:\'<List of account hashes>\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsx)(n.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var a=s(96540);const c={},t=a.createContext(c);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8c0ead1f.9f40d963.js b/assets/js/8c0ead1f.9f40d963.js deleted file mode 100644 index 682fcd38a..000000000 --- a/assets/js/8c0ead1f.9f40d963.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6091],{63543:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const r={},i="JavaScript/TypeScript SDK",c={id:"developers/dapps/sdk/script-sdk",title:"JavaScript/TypeScript SDK",description:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.",source:"@site/docs/developers/dapps/sdk/script-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/script-sdk",permalink:"/next/developers/dapps/sdk/script-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Library Usage",permalink:"/next/developers/dapps/sdk/client-library-usage"},next:{title:".NET SDK",permalink:"/next/developers/dapps/sdk/csharp-sdk"}},o={},l=[{value:"Usage of JavaScript Clients",id:"usage-of-javascript-clients",level:2},{value:"Repository & Client Packages",id:"repository-7-client-packages",level:3},{value:"Casper SDK for JavaScript",id:"casper-sdk-for-javascript",level:2},{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Generating Account Keys",id:"generating-account-keys",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"javascripttypescript-sdk",children:"JavaScript/TypeScript SDK"})}),"\n",(0,t.jsx)(n.p,{children:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK."}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-javascript-clients",children:"Usage of JavaScript Clients"}),"\n",(0,t.jsx)(n.p,{children:"The Casper team has implemented specific JS clients to support interaction with the Casper contracts."}),"\n",(0,t.jsx)(n.h3,{id:"repository-7-client-packages",children:"Repository & Client Packages"}),"\n",(0,t.jsx)(n.p,{children:"We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/README.md",children:"Casper CEP-78 (NFT) Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/client-js#readme",children:"Casper CEP-18 Client"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These packages give you an easy way to install and interact with the corresponding Casper contract."}),"\n",(0,t.jsx)(n.h2,{id:"casper-sdk-for-javascript",children:"Casper SDK for JavaScript"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"TypeScript/JavaScript SDK"})," allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"To install this library using Node.js, run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk@next --save\n"})}),"\n",(0,t.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,t.jsxs)(n.p,{children:["You can find basic examples for how to use this library in the ",(0,t.jsx)(n.code,{children:"test"})," directory. To run the tests, use this command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,t.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating account keys"}),"\n",(0,t.jsx)(n.li,{children:"Sending a transfer"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"generating-account-keys",children:"Generating Account Keys"}),"\n",(0,t.jsx)(n.p,{children:"This example shows you how to use the SDK to generate account keys to sign your deploy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst { Keys } = require("casper-js-sdk");\n\nconst createAccountKeys = () => {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["After generating the keys with this code, you can add them to the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet Chrome extension"})," and use them to sign your transactions."]}),"\n",(0,t.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,t.jsx)(n.code,{children:"sender-public-key"})," and ",(0,t.jsx)(n.code,{children:"recipient-public-key"})," in the code below."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"sendTransfer"})," function below will return a ",(0,t.jsx)(n.code,{children:"transfer-hash"})," which you can check on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"https://testnet.cspr.live/"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "<sender-public-key>",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "<recipient-public-key>",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Here is the code you can use to serialize the deploy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you can reconstruct the deploy object using this function:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8c0ead1f.ef689526.js b/assets/js/8c0ead1f.ef689526.js new file mode 100644 index 000000000..0d177b681 --- /dev/null +++ b/assets/js/8c0ead1f.ef689526.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36091],{63543:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var t=s(74848),a=s(28453);const r={},i="JavaScript/TypeScript SDK",c={id:"developers/dapps/sdk/script-sdk",title:"JavaScript/TypeScript SDK",description:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.",source:"@site/docs/developers/dapps/sdk/script-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/script-sdk",permalink:"/developers/dapps/sdk/script-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Library Usage",permalink:"/developers/dapps/sdk/client-library-usage"},next:{title:".NET SDK",permalink:"/developers/dapps/sdk/csharp-sdk"}},o={},l=[{value:"Usage of JavaScript Clients",id:"usage-of-javascript-clients",level:2},{value:"Repository & Client Packages",id:"repository-7-client-packages",level:3},{value:"Casper SDK for JavaScript",id:"casper-sdk-for-javascript",level:2},{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Generating Account Keys",id:"generating-account-keys",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"javascripttypescript-sdk",children:"JavaScript/TypeScript SDK"})}),"\n",(0,t.jsx)(n.p,{children:"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK."}),"\n",(0,t.jsx)(n.h2,{id:"usage-of-javascript-clients",children:"Usage of JavaScript Clients"}),"\n",(0,t.jsx)(n.p,{children:"The Casper team has implemented specific JS clients to support interaction with the Casper contracts."}),"\n",(0,t.jsx)(n.h3,{id:"repository-7-client-packages",children:"Repository & Client Packages"}),"\n",(0,t.jsx)(n.p,{children:"We provide repositories to create clients for Casper contracts and usage examples of such clients dedicated to interacting with smart contracts on Casper:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/README.md",children:"Casper CEP-78 (NFT) Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/client-js#readme",children:"Casper CEP-18 Client"})]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"These packages give you an easy way to install and interact with the corresponding Casper contract."}),"\n",(0,t.jsx)(n.h2,{id:"casper-sdk-for-javascript",children:"Casper SDK for JavaScript"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"TypeScript/JavaScript SDK"})," allows developers to interact with a Casper network using TypeScript or JavaScript. This section covers different examples of using the Casper JS SDK."]}),"\n",(0,t.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,t.jsx)(n.p,{children:"To install this library using Node.js, run the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk@next --save\n"})}),"\n",(0,t.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,t.jsxs)(n.p,{children:["You can find basic examples for how to use this library in the ",(0,t.jsx)(n.code,{children:"test"})," directory. To run the tests, use this command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm run test\n"})}),"\n",(0,t.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,t.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the JavaScript SDK:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Generating account keys"}),"\n",(0,t.jsx)(n.li,{children:"Sending a transfer"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"generating-account-keys",children:"Generating Account Keys"}),"\n",(0,t.jsx)(n.p,{children:"This example shows you how to use the SDK to generate account keys to sign your deploy."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst { Keys } = require("casper-js-sdk");\n\nconst createAccountKeys = () => {\n // Generating keys\n const edKeyPair = Keys.Ed25519.new();\n const { publicKey, privateKey } = edKeyPair;\n\n // Create a hexadecimal representation of the public key\n const accountAddress = publicKey.toHex();\n\n // Get the account hash (Uint8Array) from the public key\n const accountHash = publicKey.toAccountHash();\n\n // Store keys as PEM files\n const publicKeyInPem = edKeyPair.exportPublicKeyInPem();\n const privateKeyInPem = edKeyPair.exportPrivateKeyInPem();\n\n const folder = path.join("./", "casper_keys");\n\n if (!fs.existsSync(folder)) {\n const tempDir = fs.mkdirSync(folder);\n }\n\n fs.writeFileSync(folder + "/" + accountAddress + "_public.pem", publicKeyInPem);\n fs.writeFileSync(folder + "/" + accountAddress + "_private.pem", privateKeyInPem);\n\n return accountAddress;\n};\n\nconst newAccountAddress = createAccountKeys();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["After generating the keys with this code, you can add them to the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet Chrome extension"})," and use them to sign your transactions."]}),"\n",(0,t.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This code block shows you how to define and send a transfer on a Casper network. Replace the ",(0,t.jsx)(n.code,{children:"sender-public-key"})," and ",(0,t.jsx)(n.code,{children:"recipient-public-key"})," in the code below."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"sendTransfer"})," function below will return a ",(0,t.jsx)(n.code,{children:"transfer-hash"})," which you can check on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"https://testnet.cspr.live/"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const fs = require("fs");\nconst path = require("path");\nconst axios = require("axios");\nconst casperClientSDK = require("casper-js-sdk");\n\nconst { Keys, CasperClient, CLPublicKey, DeployUtil } = require("casper-js-sdk");\n\nconst RPC_API = "http://159.65.203.12:7777/rpc";\nconst STATUS_API = "http://159.65.203.12:8888";\n\nconst sendTransfer = async ({ from, to, amount }) => {\n const casperClient = new CasperClient(RPC_API);\n\n const folder = path.join("./", "casper_keys");\n\n // Read keys from the structure created in #Generating keys\n const signKeyPair = Keys.Ed25519.parseKeyFiles(folder + "/" + from + "_public.pem", folder + "/" + from + "_private.pem");\n\n // networkName can be taken from the status api\n const response = await axios.get(STATUS_API + "/status");\n\n let networkName = null;\n\n if (response.status == 200) {\n networkName = response.data.chainspec_name;\n }\n\n // For native-transfers the payment price is fixed\n const paymentAmount = 100000000;\n\n // transfer_id field in the request to tag the transaction and to correlate it to your back-end storage\n const id = 187821;\n\n // gasPrice for native transfers can be set to 1\n const gasPrice = 1;\n\n // Time that the deploy will remain valid for, in milliseconds\n // The default value is 1800000 ms (30 minutes)\n const ttl = 1800000;\n\n let deployParams = new DeployUtil.DeployParams(signKeyPair.publicKey, networkName, gasPrice, ttl);\n\n // We create a hex representation of the public key with an added prefix\n const toPublicKey = CLPublicKey.fromHex(to);\n\n const session = DeployUtil.ExecutableDeployItem.newTransfer(amount, toPublicKey, null, id);\n\n const payment = DeployUtil.standardPayment(paymentAmount);\n const deploy = DeployUtil.makeDeploy(deployParams, session, payment);\n const signedDeploy = DeployUtil.signDeploy(deploy, signKeyPair);\n\n // Here we are sending the signed deploy\n return await casperClient.putDeploy(signedDeploy);\n};\n\nsendTransfer({\n // Put here the public key of the sender\'s main purse. Note that it needs to have a balance greater than 2.5 CSPR\n from: "<sender-public-key>",\n\n // Put here the public key of the recipient\'s main purse. This account doesn\'t need to exist. If the key is correctly formatted, the network will create the account when the deploy is sent\n to: "<recipient-public-key>",\n\n // Minimal amount is 2.5 CSPR (1 CSPR = 1,000,000,000 motes)\n amount: 25000000000,\n});\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": At any moment, you can serialize the deploy from this example to JSON to accomplish whatever you want (store it, send it, etc.)."]}),"\n",(0,t.jsx)(n.p,{children:"Here is the code you can use to serialize the deploy:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, you can reconstruct the deploy object using this function:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);\n"})})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d265689.94e8c769.js b/assets/js/8d265689.94e8c769.js deleted file mode 100644 index 523b7a250..000000000 --- a/assets/js/8d265689.94e8c769.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5631],{68814:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(74848),s=r(28453);const o={},i="Setting up Private Networks",a={id:"operators/setup-network/index",title:"Setting up Private Networks",description:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/index.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/",permalink:"/operators/setup-network/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Inactive and Faulty Nodes",permalink:"/operators/becoming-a-validator/inactive-vs-faulty"},next:{title:"Genesis",permalink:"/operators/setup-network/genesis"}},c={},d=[];function p(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"setting-up-private-networks",children:"Setting up Private Networks"})}),"\n",(0,n.jsx)(t.p,{children:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Title"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/genesis",children:"The Genesis Block"})}),(0,n.jsx)(t.td,{children:"Files needed to create a genesis block"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/chain-spec",children:"The Chain Specification"})}),(0,n.jsx)(t.td,{children:"Configuration settings describing the network state"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/create-private",children:"Setting up a Private Casper Network"})}),(0,n.jsx)(t.td,{children:"A step-by-step guide to establishing and configuring a private Casper network"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/operators/setup-network/staging-files-for-new-network",children:"Staging Files for a New Network"})}),(0,n.jsx)(t.td,{children:"A guide to hosting protocol files for a new Casper network"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const s={},o=n.createContext(s);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d265689.b6706ec9.js b/assets/js/8d265689.b6706ec9.js new file mode 100644 index 000000000..c3e0e2433 --- /dev/null +++ b/assets/js/8d265689.b6706ec9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75631],{68814:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(74848),s=r(28453);const o={},i="Setting up Private Networks",a={id:"operators/setup-network/index",title:"Setting up Private Networks",description:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/index.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/",permalink:"/1.5.X/operators/setup-network/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Inactive and Faulty Nodes",permalink:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty"},next:{title:"Genesis",permalink:"/1.5.X/operators/setup-network/genesis"}},c={},d=[];function p(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"setting-up-private-networks",children:"Setting up Private Networks"})}),"\n",(0,n.jsx)(t.p,{children:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Title"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/1.5.X/operators/setup-network/genesis",children:"The Genesis Block"})}),(0,n.jsx)(t.td,{children:"Files needed to create a genesis block"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/1.5.X/operators/setup-network/chain-spec",children:"The Chain Specification"})}),(0,n.jsx)(t.td,{children:"Configuration settings describing the network state"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/1.5.X/operators/setup-network/create-private",children:"Setting up a Private Casper Network"})}),(0,n.jsx)(t.td,{children:"A step-by-step guide to establishing and configuring a private Casper network"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/1.5.X/operators/setup-network/staging-files-for-new-network",children:"Staging Files for a New Network"})}),(0,n.jsx)(t.td,{children:"A guide to hosting protocol files for a new Casper network"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const s={},o=n.createContext(s);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d81394c.8dfe83fc.js b/assets/js/8d81394c.8dfe83fc.js new file mode 100644 index 000000000..abaaf34c0 --- /dev/null +++ b/assets/js/8d81394c.8dfe83fc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49529],{42706:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(74848),s=t(28453);const i={slug:"/resources/tutorials/beginner/"},a="Overview",o={id:"resources/beginner/index",title:"Overview",description:"Beginner Tutorials",source:"@site/docs/resources/beginner/index.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/",permalink:"/resources/tutorials/beginner/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{slug:"/resources/tutorials/beginner/"},sidebar:"tutorials",previous:{title:"Quickstart",permalink:"/resources/quick-start"},next:{title:"Getting Started",permalink:"/resources/tutorials/beginner/getting-started-tutorial"}},d={},c=[{value:"Beginner Tutorials",id:"beginner-tutorials",level:2},{value:"GitHub Tutorials",id:"github-tutorials",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"beginner-tutorials",children:"Beginner Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/counter",children:"A Counter on an NCTL Network"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on a local Casper Network with NCTL"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})}),(0,r.jsx)(n.td,{children:"Queries for users and developers to obtain information stored on the blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/cep18",children:"The Casper Fungible Token Standard (CEP-18)"})}),(0,r.jsx)(n.td,{children:"Fungible Token Standard (CEP-18) Implementation and Usage"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/aws-node",children:"Launching a Casper Node with AWS Marketplace"})}),(0,r.jsx)(n.td,{children:"Learn how to launch a Casper Node through the AWS Marketplace"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"github-tutorials",children:"GitHub Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d81394c.b71ef1fd.js b/assets/js/8d81394c.b71ef1fd.js deleted file mode 100644 index 0ab70e7b7..000000000 --- a/assets/js/8d81394c.b71ef1fd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9529],{42706:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(74848),s=t(28453);const i={slug:"/resources/tutorials/beginner/"},a="Overview",o={id:"resources/beginner/index",title:"Overview",description:"Beginner Tutorials",source:"@site/docs/resources/beginner/index.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/",permalink:"/next/resources/tutorials/beginner/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{slug:"/resources/tutorials/beginner/"},sidebar:"tutorials",previous:{title:"Quickstart",permalink:"/next/resources/quick-start"},next:{title:"Getting Started",permalink:"/next/resources/tutorials/beginner/getting-started-tutorial"}},d={},c=[{value:"Beginner Tutorials",id:"beginner-tutorials",level:2},{value:"GitHub Tutorials",id:"github-tutorials",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"beginner-tutorials",children:"Beginner Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tutorials/beginner/getting-started-tutorial",children:"Getting Started Video"})}),(0,r.jsx)(n.td,{children:"Step-by-step video tutorial for setting up the Casper development environment"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/counter",children:"A Counter on an NCTL Network"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on a local Casper Network with NCTL"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/counter-testnet",children:"A Counter on the Testnet"})}),(0,r.jsx)(n.td,{children:"An example contract that maintains a counter variable on the Casper Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})}),(0,r.jsx)(n.td,{children:"Queries for users and developers to obtain information stored on the blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrades"})}),(0,r.jsx)(n.td,{children:"Learn how to upgrade smart contracts"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tutorials/beginner/cep18",children:"The Casper Fungible Token Standard (CEP-18)"})}),(0,r.jsx)(n.td,{children:"Fungible Token Standard (CEP-18) Implementation and Usage"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/resources/tutorials/beginner/aws-node",children:"Launching a Casper Node with AWS Marketplace"})}),(0,r.jsx)(n.td,{children:"Learn how to launch a Casper Node through the AWS Marketplace"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"github-tutorials",children:"GitHub Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/README.md",children:"NFTs on Casper with the CEP-78 NFT Standard"})}),(0,r.jsx)(n.td,{children:"Implementing the Casper CEP-78 NFT standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/master/docs/full-tutorial.md",children:"Fungible Tokens on Casper"})}),(0,r.jsx)(n.td,{children:"Implement the Casper Fungible Token standard"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var r=t(96540);const s={},i=r.createContext(s);function a(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8d90c7e3.28b4caa2.js b/assets/js/8d90c7e3.28b4caa2.js new file mode 100644 index 000000000..b68108125 --- /dev/null +++ b/assets/js/8d90c7e3.28b4caa2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40414],{82887:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var t=s(74848),o=s(28453);const c={title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},a="Two-Party Multi-Signature Deploys",i={id:"resources/advanced/two-party-multi-sig",title:"Two-Party Multi-Sig",description:"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/two-party-multi-sig.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/two-party-multi-sig",permalink:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},sidebar:"tutorials",previous:{title:"Advanced Tutorials",permalink:"/2.0.0/resources/tutorials/advanced/"},next:{title:"Introduction",permalink:"/2.0.0/resources/advanced/multi-sig/"}},r={},d=[{value:"Configuring the Main Account",id:"configuring-the-main-account",level:2},{value:"Running session code to set up associated keys",id:"running-session-code-to-set-up-associated-keys",level:3},{value:"Confirming Processing and Account Status",id:"confirming-execution-and-account-status",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"two-party-multi-signature-deploys",children:"Two-Party Multi-Signature Deploys"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Accounts"})," on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys."]}),"\n",(0,t.jsx)(n.p,{children:"This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You meet the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"}),", including having the Casper command-line client and a valid node address"]}),"\n",(0,t.jsxs)(n.li,{children:["You have the main account's ",(0,t.jsx)(n.code,{children:"PublicKey"})," hex (",(0,t.jsx)(n.strong,{children:"MA"}),") and another ",(0,t.jsx)(n.code,{children:"PublicKey"})," hex to associate (",(0,t.jsx)(n.strong,{children:"AA"}),")"]}),"\n",(0,t.jsxs)(n.li,{children:["You have previously ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"sent deploys"})," to a Casper network"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"configuring-the-main-account",children:"Configuring the Main Account"}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet."})}),"\n",(0,t.jsxs)(n.p,{children:["Each Account has an ",(0,t.jsx)(n.code,{children:"associated_keys"})," field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the ",(0,t.jsx)(n.code,{children:"associated_keys"})," field."]}),"\n",(0,t.jsxs)(n.p,{children:["An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the ",(0,t.jsx)(n.code,{children:"action_thresholds"})," for the account."]}),"\n",(0,t.jsx)(n.p,{children:"Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Send a deploy to the network; determined by the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold"]}),"\n",(0,t.jsxs)(n.li,{children:["Edit the ",(0,t.jsx)(n.code,{children:"associated keys"})," and the ",(0,t.jsx)(n.code,{children:"action_thresholds"}),"; determined by the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the ",(0,t.jsx)(n.em,{children:"main key"})," and ",(0,t.jsx)(n.em,{children:"associated key"}),"'s combined weight must be greater than or equal to the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold. This can be achieved by having each key's weight equal to half of the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold."]}),"\n",(0,t.jsx)(n.h3,{id:"running-session-code-to-set-up-associated-keys",children:"Running session code to set up associated keys"}),"\n",(0,t.jsxs)(n.p,{children:["To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"GitHub"}),". Note that this session code is not a general-purpose program and needs to be modified for each use case."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/contract/src/main.rs",children:"session code"})," executes ",(0,t.jsx)(n.strong,{children:"3 crucial steps"})," to enforce the multi-sig scheme for the main account:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Adds an associated key to the account; we will refer to this key as ",(0,t.jsx)(n.strong,{children:"AA"})]}),"\n",(0,t.jsxs)(n.li,{children:["Raises the ",(0,t.jsx)(n.code,{children:"action"})," threshold to ",(0,t.jsx)(n.code,{children:"2"}),", because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to ",(0,t.jsx)(n.code,{children:"1"})]}),"\n",(0,t.jsxs)(n.li,{children:["Raises the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to ",(0,t.jsx)(n.code,{children:"2"}),", such that the weight required to send a deploy is split equally between the keys associated with the account"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The repository contains a ",(0,t.jsx)(n.em,{children:"Makefile"})," with the build commands necessary to compile the contract and generate the necessary Wasm."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd two-party-multi-sig\nmake build-contract\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The compiled Wasm will be saved on this path: ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The Casper command-line client can be used to send the compiled Wasm to the network for execution."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://<peer-ip-address>:7777 \\\n--secret-key <secret-key-MA>.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path <path-to-contract-wasm> \\\n--session-arg \"deployment-account:account_hash='account-hash-<hash-AA>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the main account"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - The contract takes the account hash of the associated account as an argument labeled ",(0,t.jsx)(n.code,{children:"deployment-account"}),". You can pass this argument using the ",(0,t.jsx)(n.code,{children:"--session-arg"})," flag in the command line client"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'"result"."deploy_hash"'})," - the address of the executed deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": Save the returned ",(0,t.jsx)(n.code,{children:"deploy_hash"})," from the output to query information about execution status."]}),"\n",(0,t.jsx)(n.h3,{id:"confirming-execution-and-account-status",children:"Confirming Processing and Account Status"}),"\n",(0,t.jsxs)(n.p,{children:["Account configuration on a Casper blockchain is stored in a ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/M#merkle-tree",children:"Merkle Tree"})," and is a snapshot of the blockchain's ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/global-state#global-state-head",children:"Global State"}),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," and is stored in every executed block."]}),"\n",(0,t.jsxs)(n.p,{children:["To check that the account was configured correctly, you need the ",(0,t.jsx)(n.code,{children:"state-root-hash"})," corresponding to the block that contains your deploy. To obtain the ",(0,t.jsx)(n.code,{children:"state-root-hash"}),", you need to:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"Confirm the execution status of the deploy"})," and obtain the hash of the block containing it"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-blocks",children:"Query the block containing the deploy"})," to obtain the corresponding ",(0,t.jsx)(n.code,{children:"state_root_hash"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"state_root_hash"})," and the ",(0,t.jsx)(n.code,{children:"hex-encoded-public-key"})," of the main account, query the network and check the account's configuration."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<peer-ip-address>:7777 \\\n--state-root-hash <state-root-hash-from-block> \\\n--key <hex-encoded-public-key-MA>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example output"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In the example output, you can see the account hashes listed within the ",(0,t.jsx)(n.code,{children:"associated_keys"})," section. Each key has weight ",(0,t.jsx)(n.code,{children:"1"}),"; since the action threshold for ",(0,t.jsx)(n.code,{children:"deployment"})," is ",(0,t.jsx)(n.code,{children:"2"}),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>i});var t=s(96540);const o={},c=t.createContext(o);function a(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8dd9adb4.f35c58e4.js b/assets/js/8dd9adb4.f35c58e4.js new file mode 100644 index 000000000..cbd4c2ce2 --- /dev/null +++ b/assets/js/8dd9adb4.f35c58e4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[42587],{71586:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=t(74848),i=t(28453);const r={},c="Testing Session Code",o={id:"developers/writing-onchain-code/testing-session-code",title:"Testing Session Code",description:"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/testing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-session-code",permalink:"/2.0.0/developers/writing-onchain-code/testing-session-code",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing Session Code",permalink:"/2.0.0/developers/writing-onchain-code/writing-session-code"},next:{title:"Contract-Level Events",permalink:"/2.0.0/developers/writing-onchain-code/emitting-contract-events"}},a={},d=[{value:"Specifying Dependencies in Cargo.toml",id:"specifying-dependencies",level:2},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Required Packages",id:"importing-required-packages",level:3},{value:"Defining The Constants",id:"defining-the-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Running the Test",id:"running-the-test",level:3},{value:"Other Examples",id:"other-examples",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testing-session-code",children:"Testing Session Code"})}),"\n",(0,n.jsxs)(s.p,{children:["This section describes how to test session code using the Casper unit-testing framework. The ",(0,n.jsx)(s.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code",children:"writing session code"})," section is a prerequisite for this tutorial, which uses the example code described ",(0,n.jsx)(s.a,{href:"/2.0.0/developers/writing-onchain-code/writing-session-code#writing-session-code",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"specifying-dependencies",children:"Specifying Dependencies in Cargo.toml"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/Cargo.toml",children:"Cargo.toml"})," sample file in the ",(0,n.jsx)(s.code,{children:"tests"})," directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'[dev-dependencies]\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-execution-engine = "2.0.0"\ncasper-types = "1.5.0"\n'})}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,n.jsxs)(s.p,{children:["Tests for this example session code reside in the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file."]}),"\n",(0,n.jsxs)(s.p,{children:["Notice that this file contains an empty ",(0,n.jsx)(s.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,n.jsx)(s.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/contract/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,n.jsx)(s.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,n.jsx)(s.code,{children:"mod tests"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"importing-required-packages",children:"Importing Required Packages"}),"\n",(0,n.jsx)(s.p,{children:"Next, import the packages required for the tests to run. The example tests use these packages:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n use casper_types::account::AccountHash;\n use casper_types::{runtime_args, RuntimeArgs};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"defining-the-constants",children:"Defining The Constants"}),"\n",(0,n.jsx)(s.p,{children:"The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account\nconst ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument\nconst CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE\n'})}),"\n",(0,n.jsx)(s.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,n.jsxs)(s.p,{children:["In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the ",(0,n.jsx)(s.code,{children:"#[test]"})," attribute."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[test]\nfn <unit-test-name>{\n // Test function implementation\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["This ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"unit test"})," is a good example of testing session code. At a high level, the test follows this process:"]}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["Initialize an instance of the execution engine and the ",(0,n.jsx)(s.code,{children:"InMemoryWasmTestBuilder"}),"."]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let mut builder = InMemoryWasmTestBuilder::default();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Execute the genesis process."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"GitHub"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsx)(s.p,{children:"Retrieve runtime arguments, which should be the same as defined in the contract."}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Create the execution request that sets up the session code to be processed. In this example, the ",(0,n.jsx)(s.code,{children:"CONTRACT_WASM"})," is the session code."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Invoke the execution engine to process the session code."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.exec(execute_request).expect_success().commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Verify that the results match the expected output. This example checks the associated keys."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n"})}),"\n",(0,n.jsx)(s.h3,{id:"running-the-test",children:"Running the Test"}),"\n",(0,n.jsxs)(s.p,{children:["This example uses a ",(0,n.jsx)(s.code,{children:"Makefile"})," to run the tests."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Under the hood, the ",(0,n.jsx)(s.code,{children:"Makefile"})," generates a ",(0,n.jsx)(s.code,{children:"tests/wasm"})," folder, copies the Wasm to the folder, and runs the tests with ",(0,n.jsx)(s.code,{children:"cargo test"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n"})}),"\n",(0,n.jsx)(s.h3,{id:"other-examples",children:"Other Examples"}),"\n",(0,n.jsxs)(s.p,{children:["In the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"counter unit tests"}),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,n.jsx)(s.p,{children:"The verification step looks like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,n.jsxs)(s.p,{children:["For many more examples, visit the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,n.jsx)(s.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,n.jsxs)(s.p,{children:["The following brief video describes testing the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,n.jsxs)(s.p,{align:"center",children:["\n",(0,n.jsx)(s.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Learn to ",(0,n.jsx)(s.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>o});var n=t(96540);const i={},r=n.createContext(i);function c(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8de9f24f.046ff0c7.js b/assets/js/8de9f24f.046ff0c7.js new file mode 100644 index 000000000..d5455cd14 --- /dev/null +++ b/assets/js/8de9f24f.046ff0c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[699],{56922:a=>{a.exports=JSON.parse('{"tag":{"label":"Validators","permalink":"/blog/tags/validators","description":"Validators","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/validators","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/8de9f24f.27e228f9.js b/assets/js/8de9f24f.27e228f9.js deleted file mode 100644 index f2a69fdb0..000000000 --- a/assets/js/8de9f24f.27e228f9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[699],{56922:a=>{a.exports=JSON.parse('{"tag":{"label":"validators","permalink":"/blog/tags/validators","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/validators","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/8e1fd569.89ba8087.js b/assets/js/8e1fd569.89ba8087.js new file mode 100644 index 000000000..161e233b8 --- /dev/null +++ b/assets/js/8e1fd569.89ba8087.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64097],{85936:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>i});var c=a(74848),s=a(28453);const r={},d="Direct Token Transfer",t={id:"developers/cli/transfers/direct-token-transfer",title:"Direct Token Transfer",description:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/direct-token-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/direct-token-transfer",permalink:"/1.5.X/developers/cli/transfers/direct-token-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens",permalink:"/1.5.X/developers/cli/transfers/"},next:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer"}},f={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Direct Transfer Example",id:"transfer",level:2},{value:"Verifying the Deploy",id:"verify-deploy",level:2},{value:"Verifying the Transfer",id:"verifying-the-transfer",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"direct-token-transfer",children:"Direct Token Transfer"})}),"\n",(0,c.jsx)(n.p,{children:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"This workflow assumes:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["You meet the general ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"development prerequisites"})]}),"\n",(0,c.jsx)(n.li,{children:"You are using the Casper command-line client"}),"\n",(0,c.jsxs)(n.li,{children:["You have a target ",(0,c.jsx)(n.em,{children:"public key"})]}),"\n",(0,c.jsxs)(n.li,{children:["You have a valid ",(0,c.jsx)(n.em,{children:"node address"})]}),"\n",(0,c.jsxs)(n.li,{children:["You must be able to sign a deploy for the source account using the source ",(0,c.jsx)(n.em,{children:"secret key"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transfer",children:"Direct Transfer Example"}),"\n",(0,c.jsxs)(n.p,{children:["The following ",(0,c.jsx)(n.code,{children:"transfer"})," command allows you to move CSPR from one account's purse to another as denominated in ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#tokens-divisibility",children:"Motes"}),". A ",(0,c.jsx)(n.em,{children:"Mote"})," is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id <ID> \\\n--transfer-id <TRANSFER_ID> \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"transfer-id"})," -64-BIT INTEGER The ",(0,c.jsx)(n.code,{children:"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,c.jsx)(n.code,{children:"0"})," or some ",(0,c.jsx)(n.code,{children:"u64"})," value that is meaningful to you"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint [default:<",(0,c.jsx)(n.a,{href:"http://localhost:7777%5C%3E%5C",children:"http://localhost:7777\\>\\"}),"]"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"amount"})," -512-BIT INTEGER The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.jsx)(n.code,{children:"Motes"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"secret-key"})," - Path to secret key file"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"chain-name"})," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Testnet is ",(0,c.jsx)(n.strong,{children:"casper-test"})]}),"\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Mainnet is ",(0,c.jsx)(n.strong,{children:"casper"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"target-account"})," - Hex-encoded public key of the account that will receive the funds in its main purse"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"payment-amount"})," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", you can specify 10^8 motes"]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."deploy_hash"'})," - The address of the deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Save the returned ",(0,c.jsx)(n.em,{children:"deploy_hash"})," from the output to query information about the transfer deploy later."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Transfer:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"verify-deploy",children:"Verifying the Deploy"}),"\n",(0,c.jsx)(n.p,{children:"A transfer on a Casper network is only executed after it has been included in a finalized block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"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"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."execution_results"[0]."block_hash"'})," - contains the block hash of the block that included the transfer. We will require the ",(0,c.jsx)(n.em,{children:"state_root_hash"})," of this block to look up information about the accounts and their purse balances"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Transfer addresses use a ",(0,c.jsx)(n.code,{children:"transfer-"})," string prefix."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \n--node-address https://rpc.testnet.casperlabs.io \n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["Refer to the Section on ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"querying deploys"})," for more information."]}),"\n",(0,c.jsx)(n.h2,{id:"verifying-the-transfer",children:"Verifying the Transfer"}),"\n",(0,c.jsxs)(n.p,{children:["In addition to verifying the deploy, you also need to ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/verify-transfer",children:"verify the transfer details"}),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>t});var c=a(96540);const s={},r=c.createContext(s);function d(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8e1fd569.c1e0d801.js b/assets/js/8e1fd569.c1e0d801.js deleted file mode 100644 index daf0c6227..000000000 --- a/assets/js/8e1fd569.c1e0d801.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4097],{85936:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>i});var c=a(74848),s=a(28453);const r={},d="Direct Token Transfer",t={id:"developers/cli/transfers/direct-token-transfer",title:"Direct Token Transfer",description:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/direct-token-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/direct-token-transfer",permalink:"/developers/cli/transfers/direct-token-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens",permalink:"/developers/cli/transfers/"},next:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/developers/cli/transfers/multisig-deploy-transfer"}},f={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Direct Transfer Example",id:"transfer",level:2},{value:"Verifying the Deploy",id:"verify-deploy",level:2},{value:"Verifying the Transfer",id:"verifying-the-transfer",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"direct-token-transfer",children:"Direct Token Transfer"})}),"\n",(0,c.jsx)(n.p,{children:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"This workflow assumes:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["You meet the general ",(0,c.jsx)(n.a,{href:"/developers/prerequisites",children:"development prerequisites"})]}),"\n",(0,c.jsx)(n.li,{children:"You are using the Casper command-line client"}),"\n",(0,c.jsxs)(n.li,{children:["You have a target ",(0,c.jsx)(n.em,{children:"public key"})]}),"\n",(0,c.jsxs)(n.li,{children:["You have a valid ",(0,c.jsx)(n.em,{children:"node address"})]}),"\n",(0,c.jsxs)(n.li,{children:["You must be able to sign a deploy for the source account using the source ",(0,c.jsx)(n.em,{children:"secret key"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transfer",children:"Direct Transfer Example"}),"\n",(0,c.jsxs)(n.p,{children:["The following ",(0,c.jsx)(n.code,{children:"transfer"})," command allows you to move CSPR from one account's purse to another as denominated in ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#tokens-divisibility",children:"Motes"}),". A ",(0,c.jsx)(n.em,{children:"Mote"})," is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id <ID> \\\n--transfer-id <TRANSFER_ID> \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"transfer-id"})," -64-BIT INTEGER The ",(0,c.jsx)(n.code,{children:"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,c.jsx)(n.code,{children:"0"})," or some ",(0,c.jsx)(n.code,{children:"u64"})," value that is meaningful to you"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint [default:<",(0,c.jsx)(n.a,{href:"http://localhost:7777%5C%3E%5C",children:"http://localhost:7777\\>\\"}),"]"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"amount"})," -512-BIT INTEGER The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.jsx)(n.code,{children:"Motes"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"secret-key"})," - Path to secret key file"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"chain-name"})," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Testnet is ",(0,c.jsx)(n.strong,{children:"casper-test"})]}),"\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Mainnet is ",(0,c.jsx)(n.strong,{children:"casper"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"target-account"})," - Hex-encoded public key of the account that will receive the funds in its main purse"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"payment-amount"})," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", you can specify 10^8 motes"]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."deploy_hash"'})," - The address of the deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Save the returned ",(0,c.jsx)(n.em,{children:"deploy_hash"})," from the output to query information about the transfer deploy later."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Transfer:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"verify-deploy",children:"Verifying the Deploy"}),"\n",(0,c.jsx)(n.p,{children:"A transfer on a Casper network is only executed after it has been included in a finalized block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"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"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."execution_results"[0]."block_hash"'})," - contains the block hash of the block that included the transfer. We will require the ",(0,c.jsx)(n.em,{children:"state_root_hash"})," of this block to look up information about the accounts and their purse balances"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Transfer addresses use a ",(0,c.jsx)(n.code,{children:"transfer-"})," string prefix."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \n--node-address https://rpc.testnet.casperlabs.io \n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["Refer to the Section on ",(0,c.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"querying deploys"})," for more information."]}),"\n",(0,c.jsx)(n.h2,{id:"verifying-the-transfer",children:"Verifying the Transfer"}),"\n",(0,c.jsxs)(n.p,{children:["In addition to verifying the deploy, you also need to ",(0,c.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"verify the transfer details"}),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>t});var c=a(96540);const s={},r=c.createContext(s);function d(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8f27be43.9c50069b.js b/assets/js/8f27be43.9c50069b.js deleted file mode 100644 index 35deafee2..000000000 --- a/assets/js/8f27be43.9c50069b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6088],{18277:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter-testnet/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/docs/resources/beginner/counter-testnet/walkthrough.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/walkthrough",permalink:"/next/resources/beginner/counter-testnet/walkthrough",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/next/resources/beginner/counter-testnet/commands"},next:{title:"Querying a Node",permalink:"/next/resources/tutorials/beginner/querying-network"}},i={},h=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"account hash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, you can check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]"})," - Get the account-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state-root-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-state"})," - Query the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first."}),"\n",(0,s.jsx)(t.p,{children:"Next, get the state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You need to use the IP address of one of the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to deploy the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on the Testnet!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8f27be43.ca74fdf7.js b/assets/js/8f27be43.ca74fdf7.js new file mode 100644 index 000000000..1c8290ee6 --- /dev/null +++ b/assets/js/8f27be43.ca74fdf7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46088],{18277:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>c,toc:()=>h});var s=n(74848),a=n(28453);const o={},r="Tutorial Walkthrough",c={id:"resources/beginner/counter-testnet/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/docs/resources/beginner/counter-testnet/walkthrough.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter-testnet/commands"},next:{title:"Querying a Node",permalink:"/resources/tutorials/beginner/querying-network"}},i={},h=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"account hash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, you can check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]"})," - Get the account-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state-root-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-state"})," - Query the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first."}),"\n",(0,s.jsx)(t.p,{children:"Next, get the state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You need to use the IP address of one of the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to deploy the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on the Testnet!"})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const a={},o=s.createContext(a);function r(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8fcee16d.27cfe3cc.js b/assets/js/8fcee16d.27cfe3cc.js new file mode 100644 index 000000000..7ac260269 --- /dev/null +++ b/assets/js/8fcee16d.27cfe3cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31725],{13297:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>f,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Transferring Tokens"},a="Transferring Tokens with the Casper CLI Client",o={id:"developers/cli/transfers/index",title:"Transferring Tokens",description:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.",source:"@site/versioned_docs/version-2.0.0/developers/cli/transfers/index.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/",permalink:"/2.0.0/developers/cli/transfers/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Transferring Tokens"},sidebar:"developers",previous:{title:"Interacting with the Blockchain",permalink:"/2.0.0/developers/cli/"},next:{title:"Direct Token Transfer",permalink:"/2.0.0/developers/cli/transfers/direct-token-transfer"}},c={},l=[];function d(e){const n={a:"a",h1:"h1",header:"header",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-with-the-casper-cli-client",children:"Transferring Tokens with the Casper CLI Client"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a direct transfer"})}),"\n",(0,t.jsxs)(n.p,{children:["Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/direct-token-transfer",children:"Transferring Tokens Using Direct Transfer"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Transferring tokens using a multi-sig tranasction"})}),"\n",(0,t.jsxs)(n.p,{children:["Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature transactions"})," workflow. To use a multi-sig transaction transfer, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer",children:"Transferring Tokens Using a Multi-sig Account"}),"."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verifying a transfer using the command-line client"})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the status of a transfer, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]})]})}function f(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>a,x:()=>o});var t=r(96540);const s={},i=t.createContext(s);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ff31131.13194bde.js b/assets/js/8ff31131.13194bde.js new file mode 100644 index 000000000..51ec67683 --- /dev/null +++ b/assets/js/8ff31131.13194bde.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6346],{9414:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var t=s(74848),a=s(28453);const c={title:"Calling Contracts"},r="Calling Smart Contracts with the Rust Client",i={id:"developers/cli/calling-contracts",title:"Calling Contracts",description:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.",source:"@site/docs/developers/cli/calling-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/calling-contracts",permalink:"/developers/cli/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Calling Contracts"},sidebar:"developers",previous:{title:"Querying Global State",permalink:"/developers/cli/querying-global-state"},next:{title:"OpCode Costs Tables",permalink:"/developers/cli/opcode-costs"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Calling Contracts by Contract Hash",id:"calling-contracts-by-hash",level:2},{value:"Calling Contracts with Session Arguments",id:"calling-contracts-with-session-args",level:2},{value:"Calling Contracts by Package Hash",id:"calling-contracts-by-package-hash",level:2},{value:"Calling Contracts by Contract Name",id:"calling-contracts-by-name",level:2},{value:"Calling Contracts by Package Name",id:"calling-contracts-by-package-name",level:2},{value:"Calling a Contract using Wasm",id:"calling-a-contract-using-wasm",level:2},{value:"Calling Contracts that Return a Value",id:"calling-contracts-that-return-a-value",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"calling-smart-contracts-with-the-rust-client",children:"Calling Smart Contracts with the Rust Client"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Each section below includes a short video demonstrating some example output."]}),"\n",(0,t.jsxs)(n.p,{children:["The following examples use two contracts on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," described while ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),". You will need to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"install this contract"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The Auction contract found in ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"this contract package"}),", already installed on Testnet as a system contract. The examples will call its ",(0,t.jsx)(n.code,{children:"delegate"})," entry point"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"install contracts and query global state"})," using the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," on Testnet if you have not done so already"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"system Auction contract"})," on Testnet"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-hash",children:"Calling Contracts by Contract Hash"}),"\n",(0,t.jsxs)(n.p,{children:["After ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installing a contract"})," in global state, you can use the contract's hash to call one of its entry points. The following usage of ",(0,t.jsx)(n.code,{children:"put-deploy"})," allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name of the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Counter contract by hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.code,{children:"--session-hash"}),' option identifies a stored contract with an entry-point called "counter-inc".']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \\\n --session-entry-point "counter-inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.code,{children:"put-deploy"})," command is nearly identical to the command used to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#installing-contract-code",children:"install the contract"}),". Here, instead of ",(0,t.jsx)(n.code,{children:"session-path"})," pointing to the Wasm binary, we have ",(0,t.jsx)(n.code,{children:"session-hash"})," and ",(0,t.jsx)(n.code,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn\u2019t return a value. If an entry point returns a value, use code to ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"interact with runtime return values"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The following sample response contains a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", needed to verify the changes in global state, as described ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'{\n "id": 1197172763279676268,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract by hash:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to query a previously installed Counter contract by hash."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=11",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-args",children:"Calling Contracts with Session Arguments"}),"\n",(0,t.jsxs)(n.p,{children:["When calling contract entry points, you may need to pass in information using session arguments. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command allows you to do this with the ",(0,t.jsx)(n.code,{children:"--session-arg"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-arg ["NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null"]...\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Auction contract using session arguments:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's entry point ",(0,t.jsx)(n.code,{children:"delegate"})," with three arguments:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"validator"})," is the public key of the validator to whom the tokens will be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"amount"})," is the number of tokens to be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"delegator"})," is the public key of the account delegating tokens to a validator"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To make the call, we use the contract hash, ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"}),", and the ",(0,t.jsx)(n.code,{children:"--session-hash"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract with session arguments:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to call a modified Counter contract using session arguments."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/XB_ojY1_0Uo",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-hash",children:"Calling Contracts by Package Hash"}),"\n",(0,t.jsxs)(n.p,{children:["You can also call an entry point in a contract that is part of a contract package (see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"contract upgrades"}),"). Call ",(0,t.jsx)(n.code,{children:"put-deploy"})," using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-hash"})," - Hex-encoded hash of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter using the package hash and version:"})}),"\n",(0,t.jsx)(n.p,{children:'In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:"To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction using the package hash and version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's ",(0,t.jsx)(n.code,{children:"delegate"})," entry point by specifying the package hash using the ",(0,t.jsx)(n.code,{children:"--session-package-hash"})," option. The call defaults to the highest enabled version since no version was specified with the ",(0,t.jsx)(n.code,{children:"--session-version"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package hash:"})}),"\n",(0,t.jsx)(n.p,{children:"The video shows how to query the previously installed Counter contract package."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=15",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-name",children:"Calling Contracts by Contract Name"}),"\n",(0,t.jsxs)(n.p,{children:["We can also reference a contract using a key as the contract name. When you write the contract, use the ",(0,t.jsx)(n.code,{children:"put_key"})," function to add the ContractHash under the contract's ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html#",children:"NamedKeys"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Having a key enables you to call a contract's entry-point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-name"})," - Name of the stored contract (associated with the executing account) to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on ',(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/934a452ccba8c5cf12f8bde706736400e047fba5/contract-v1/src/main.rs#L110",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,t.jsx)(n.p,{children:'The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The sample response will contain a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", which you need to use as described ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"here"})," to verify the changes in global state."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the system Auction contract stored in global state under the "auction" key and its ',(0,t.jsx)(n.code,{children:"delegate"})," entry point."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-name "auction" \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using a named key:"})}),"\n",(0,t.jsx)(n.p,{children:"This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=12",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-name",children:"Calling Contracts by Package Name"}),"\n",(0,t.jsxs)(n.p,{children:["To call an entry point in a contract by referencing the contract package name, you can use the ",(0,t.jsx)(n.code,{children:"session-package-name"}),", ",(0,t.jsx)(n.code,{children:"session-entry-point"}),", and ",(0,t.jsx)(n.code,{children:"session-version"})," arguments. This will enable you to access the entry point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name [NAMED_KEY_FOR_PACKAGE] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-name"})," - Name of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Specifying the package name and version number:"})}),"\n",(0,t.jsx)(n.p,{children:'This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.'}),"\n",(0,t.jsxs)(n.p,{children:["You should have previously created the contract by using ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),", and provided the contract package name as the ",(0,t.jsx)(n.code,{children:"hash_name"})," argument of ",(0,t.jsx)(n.code,{children:"new_contract"}),"."]}),"\n",(0,t.jsx)(n.p,{children:'This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' let (stored_contract_hash, contract_version) =\n storage::new_contract(counter_entry_points, \n Some(counter_named_keys), \n Some("counter_package_name".to_string()),\n Some("counter_access_uref".to_string())\n );\n'})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command to call the contract using the package name:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the package without specifying the version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call a contract that is part of the ",(0,t.jsx)(n.code,{children:"erc20_test_call"}),' package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper-client put-deploy \\\n --node-address http://3.143.158.19:7777 \\\n --chain-name integration-test \\\n --secret-key ~/casper/demo/user_a/secret_key.pem \\\n --payment-amount 1000000000 \\\n --session-package-name "erc20_test_call" \\\n --session-entry-point "check_balance_of" \\\n --session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n --session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package name:"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates how to call versioned contracts by package name."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=16",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-a-contract-using-wasm",children:"Calling a Contract using Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Session code or contract code (compiled to Wasm) can act on a contract and change its state. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command supports this mechanism as well:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/[FILE_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The argument of interest is:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Session code acting on a contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"})," shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"\ncasper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 25000000000 \\\n --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm\n\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using Wasm:"})}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=13",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-that-return-a-value",children:"Calling Contracts that Return a Value"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial to learn how to call a contract that returns a value using session code or contract code."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"})," takes you through a detailed walkthrough on how to query global state to verify a contract's state"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Look into the ",(0,t.jsx)(n.a,{href:"/resources/",children:"Resources for Smart Contract Authors"})]}),"\n",(0,t.jsxs)(n.li,{children:["See the ",(0,t.jsx)(n.a,{href:"/developers",children:"Developer How To Guides"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const a={},c=t.createContext(a);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8ff31131.5c0f2d85.js b/assets/js/8ff31131.5c0f2d85.js deleted file mode 100644 index 2e856e6c7..000000000 --- a/assets/js/8ff31131.5c0f2d85.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6346],{9414:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var t=s(74848),a=s(28453);const c={title:"Calling Contracts"},r="Calling Smart Contracts with the Rust Client",i={id:"developers/cli/calling-contracts",title:"Calling Contracts",description:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.",source:"@site/docs/developers/cli/calling-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/calling-contracts",permalink:"/next/developers/cli/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Calling Contracts"},sidebar:"developers",previous:{title:"Querying Global State",permalink:"/next/developers/cli/querying-global-state"},next:{title:"OpCode Costs Tables",permalink:"/next/developers/cli/opcode-costs"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Calling Contracts by Contract Hash",id:"calling-contracts-by-hash",level:2},{value:"Calling Contracts with Session Arguments",id:"calling-contracts-with-session-args",level:2},{value:"Calling Contracts by Package Hash",id:"calling-contracts-by-package-hash",level:2},{value:"Calling Contracts by Contract Name",id:"calling-contracts-by-name",level:2},{value:"Calling Contracts by Package Name",id:"calling-contracts-by-package-name",level:2},{value:"Calling a Contract using Wasm",id:"calling-a-contract-using-wasm",level:2},{value:"Calling Contracts that Return a Value",id:"calling-contracts-that-return-a-value",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"calling-smart-contracts-with-the-rust-client",children:"Calling Smart Contracts with the Rust Client"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Each section below includes a short video demonstrating some example output."]}),"\n",(0,t.jsxs)(n.p,{children:["The following examples use two contracts on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," described while ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),". You will need to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"install this contract"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The Auction contract found in ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"this contract package"}),", already installed on Testnet as a system contract. The examples will call its ",(0,t.jsx)(n.code,{children:"delegate"})," entry point"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"install contracts and query global state"})," using the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," on Testnet if you have not done so already"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"system Auction contract"})," on Testnet"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-hash",children:"Calling Contracts by Contract Hash"}),"\n",(0,t.jsxs)(n.p,{children:["After ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"installing a contract"})," in global state, you can use the contract's hash to call one of its entry points. The following usage of ",(0,t.jsx)(n.code,{children:"put-deploy"})," allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name of the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Counter contract by hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.code,{children:"--session-hash"}),' option identifies a stored contract with an entry-point called "counter-inc".']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \\\n --session-entry-point "counter-inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.code,{children:"put-deploy"})," command is nearly identical to the command used to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts#installing-contract-code",children:"install the contract"}),". Here, instead of ",(0,t.jsx)(n.code,{children:"session-path"})," pointing to the Wasm binary, we have ",(0,t.jsx)(n.code,{children:"session-hash"})," and ",(0,t.jsx)(n.code,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn\u2019t return a value. If an entry point returns a value, use code to ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"interact with runtime return values"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The following sample response contains a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", needed to verify the changes in global state, as described ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts#querying-global-state",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'{\n "id": 1197172763279676268,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract by hash:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to query a previously installed Counter contract by hash."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=11",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-args",children:"Calling Contracts with Session Arguments"}),"\n",(0,t.jsxs)(n.p,{children:["When calling contract entry points, you may need to pass in information using session arguments. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command allows you to do this with the ",(0,t.jsx)(n.code,{children:"--session-arg"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-arg ["NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null"]...\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Auction contract using session arguments:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's entry point ",(0,t.jsx)(n.code,{children:"delegate"})," with three arguments:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"validator"})," is the public key of the validator to whom the tokens will be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"amount"})," is the number of tokens to be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"delegator"})," is the public key of the account delegating tokens to a validator"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To make the call, we use the contract hash, ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"}),", and the ",(0,t.jsx)(n.code,{children:"--session-hash"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract with session arguments:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to call a modified Counter contract using session arguments."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/XB_ojY1_0Uo",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-hash",children:"Calling Contracts by Package Hash"}),"\n",(0,t.jsxs)(n.p,{children:["You can also call an entry point in a contract that is part of a contract package (see ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts",children:"contract upgrades"}),"). Call ",(0,t.jsx)(n.code,{children:"put-deploy"})," using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-hash"})," - Hex-encoded hash of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter using the package hash and version:"})}),"\n",(0,t.jsx)(n.p,{children:'In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:"To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction using the package hash and version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's ",(0,t.jsx)(n.code,{children:"delegate"})," entry point by specifying the package hash using the ",(0,t.jsx)(n.code,{children:"--session-package-hash"})," option. The call defaults to the highest enabled version since no version was specified with the ",(0,t.jsx)(n.code,{children:"--session-version"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package hash:"})}),"\n",(0,t.jsx)(n.p,{children:"The video shows how to query the previously installed Counter contract package."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=15",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-name",children:"Calling Contracts by Contract Name"}),"\n",(0,t.jsxs)(n.p,{children:["We can also reference a contract using a key as the contract name. When you write the contract, use the ",(0,t.jsx)(n.code,{children:"put_key"})," function to add the ContractHash under the contract's ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html#",children:"NamedKeys"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Having a key enables you to call a contract's entry-point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-name"})," - Name of the stored contract (associated with the executing account) to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on ',(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/934a452ccba8c5cf12f8bde706736400e047fba5/contract-v1/src/main.rs#L110",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,t.jsx)(n.p,{children:'The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The sample response will contain a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", which you need to use as described ",(0,t.jsx)(n.a,{href:"/next/developers/cli/installing-contracts#querying-global-state",children:"here"})," to verify the changes in global state."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the system Auction contract stored in global state under the "auction" key and its ',(0,t.jsx)(n.code,{children:"delegate"})," entry point."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-name "auction" \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using a named key:"})}),"\n",(0,t.jsx)(n.p,{children:"This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=12",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-name",children:"Calling Contracts by Package Name"}),"\n",(0,t.jsxs)(n.p,{children:["To call an entry point in a contract by referencing the contract package name, you can use the ",(0,t.jsx)(n.code,{children:"session-package-name"}),", ",(0,t.jsx)(n.code,{children:"session-entry-point"}),", and ",(0,t.jsx)(n.code,{children:"session-version"})," arguments. This will enable you to access the entry point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name [NAMED_KEY_FOR_PACKAGE] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-name"})," - Name of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Specifying the package name and version number:"})}),"\n",(0,t.jsx)(n.p,{children:'This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.'}),"\n",(0,t.jsxs)(n.p,{children:["You should have previously created the contract by using ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),", and provided the contract package name as the ",(0,t.jsx)(n.code,{children:"hash_name"})," argument of ",(0,t.jsx)(n.code,{children:"new_contract"}),"."]}),"\n",(0,t.jsx)(n.p,{children:'This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' let (stored_contract_hash, contract_version) =\n storage::new_contract(counter_entry_points, \n Some(counter_named_keys), \n Some("counter_package_name".to_string()),\n Some("counter_access_uref".to_string())\n );\n'})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command to call the contract using the package name:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the package without specifying the version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call a contract that is part of the ",(0,t.jsx)(n.code,{children:"erc20_test_call"}),' package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper-client put-deploy \\\n --node-address http://3.143.158.19:7777 \\\n --chain-name integration-test \\\n --secret-key ~/casper/demo/user_a/secret_key.pem \\\n --payment-amount 1000000000 \\\n --session-package-name "erc20_test_call" \\\n --session-entry-point "check_balance_of" \\\n --session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n --session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package name:"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates how to call versioned contracts by package name."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=16",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-a-contract-using-wasm",children:"Calling a Contract using Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Session code or contract code (compiled to Wasm) can act on a contract and change its state. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command supports this mechanism as well:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/[FILE_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The argument of interest is:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Session code acting on a contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/next/counter",children:"Counter Contract Tutorial"})," shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"\ncasper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 25000000000 \\\n --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm\n\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using Wasm:"})}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=13",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-that-return-a-value",children:"Calling Contracts that Return a Value"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial to learn how to call a contract that returns a value using session code or contract code."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/next/counter",children:"Counter Contract Tutorial"})," takes you through a detailed walkthrough on how to query global state to verify a contract's state"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"/next/developers/cli/delegate",children:"Delegating with the Casper Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Look into the ",(0,t.jsx)(n.a,{href:"/resources/",children:"Resources for Smart Contract Authors"})]}),"\n",(0,t.jsxs)(n.li,{children:["See the ",(0,t.jsx)(n.a,{href:"/developers",children:"Developer How To Guides"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const a={},c=t.createContext(a);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/8913.b6442bb9.js b/assets/js/90416.140f33a2.js similarity index 55% rename from assets/js/8913.b6442bb9.js rename to assets/js/90416.140f33a2.js index 8b0ed9340..244912022 100644 --- a/assets/js/8913.b6442bb9.js +++ b/assets/js/90416.140f33a2.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8913],{58913:(s,c,e)=>{e.r(c)}}]); \ No newline at end of file +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[90416],{90416:(s,c,e)=>{e.r(c)}}]); \ No newline at end of file diff --git a/assets/js/905c7445.20605116.js b/assets/js/905c7445.20605116.js new file mode 100644 index 000000000..57ab79d36 --- /dev/null +++ b/assets/js/905c7445.20605116.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94552],{98081:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=s(74848),t=s(28453);const c={},o="E",a={id:"concepts/glossary/E",title:"E",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/E.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/E",permalink:"/2.0.0/concepts/glossary/E",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"D",permalink:"/2.0.0/concepts/glossary/D"},next:{title:"F",permalink:"/2.0.0/concepts/glossary/F"}},i={},l=[{value:"Ecosystem",id:"ecosystem",level:2},{value:"Entry point",id:"entry-point",level:2},{value:"Equivocation",id:"equivocation",level:2},{value:"Era",id:"era",level:2},{value:"Eviction",id:"eviction",level:2},{value:"External client",id:"external-client",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"e",children:"E"})}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(n.hr,{}),"\n",(0,r.jsx)(n.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,r.jsx)(n.p,{children:"The ecosystem layer in Casper encompasses dApp design and operation."}),"\n",(0,r.jsx)(n.h2,{id:"entry-point",children:"Entry point"}),"\n",(0,r.jsxs)(n.p,{children:["See ",(0,r.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#entrypoint",children:"EntryPoint"})," and ",(0,r.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract#step-4-defining-the-contract-entry-points",children:"Defining the Contract Entry Points"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"equivocation",children:"Equivocation"}),"\n",(0,r.jsx)(n.p,{children:"A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive."}),"\n",(0,r.jsx)(n.h2,{id:"era",children:"Era"}),"\n",(0,r.jsx)(n.p,{children:"A period of time during which the validator set does not change."}),"\n",(0,r.jsxs)(n.p,{children:["In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A#auction",children:"auction"}),". At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/B#booking-block",children:"booking block"}),")."]}),"\n",(0,r.jsx)(n.h2,{id:"eviction",children:"Eviction"}),"\n",(0,r.jsxs)(n.p,{children:["Validators that fail to participate in ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/E#era",children:"era"})," will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the ",(0,r.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A#auction-contract",children:"auction contract"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"external-client",children:"External client"}),"\n",(0,r.jsx)(n.p,{children:"Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain."})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var r=s(96540);const t={},c=r.createContext(t);function o(e){const n=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90efbb16.0264317d.js b/assets/js/90efbb16.0264317d.js deleted file mode 100644 index 2a747660b..000000000 --- a/assets/js/90efbb16.0264317d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8132],{31352:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>r});var s=i(74848),t=i(28453);const o={},d="Network Communication {#communications-head}",a={id:"concepts/design/p2p",title:"Network Communication",description:"communications-head}",source:"@site/versioned_docs/version-1.5.X/concepts/design/p2p.md",sourceDirName:"concepts/design",slug:"/concepts/design/p2p",permalink:"/concepts/design/p2p",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Design",permalink:"/concepts/design/casper-design"},next:{title:"Highway Consensus",permalink:"/concepts/design/highway"}},c={},r=[{value:"Identity",id:"identity",level:2},{value:"Inter-node connections",id:"inter-node-connections",level:2},{value:"Network",id:"network",level:2},{value:"Gossiping",id:"communications-gossiping",level:2},{value:"Requesting missing data",id:"requesting-missing-data",level:2},{value:"Validation",id:"validation",level:3},{value:"Node Discovery",id:"node-discovery",level:2}];function l(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"communications-head",children:"Network Communication"})}),"\n",(0,s.jsx)(n.h2,{id:"identity",children:"Identity"}),"\n",(0,s.jsx)(n.p,{children:"Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID."}),"\n",(0,s.jsx)(n.p,{children:"Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint."}),"\n",(0,s.jsx)(n.h2,{id:"inter-node-connections",children:"Inter-node connections"}),"\n",(0,s.jsxs)(n.p,{children:["Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the ",(0,s.jsx)(n.em,{children:"client"})," and the remote node the ",(0,s.jsx)(n.em,{children:"server"})," for this connection."]}),"\n",(0,s.jsx)(n.p,{children:"During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks."}),"\n",(0,s.jsx)(n.p,{children:"Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected."}),"\n",(0,s.jsxs)(n.p,{children:["Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"})," on how the server finds endpoints)."]}),"\n",(0,s.jsx)(n.p,{children:"Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it."}),"\n",(0,s.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,s.jsxs)(n.p,{children:["As soon as a node has connected to one node in the network, it partakes in ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"}),". In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network."]}),"\n",(0,s.jsx)(n.p,{children:"Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below."}),"\n",(0,s.jsx)(n.p,{children:"In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped."}),"\n",(0,s.jsx)(n.h2,{id:"communications-gossiping",children:"Gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Multiple types of objects are gossipped, the most prominent ones being blocks, deploys, and endpoints (see ",(0,s.jsx)(n.a,{href:"#identity",children:"Identity"}),"). Each of these objects is immutable and can be identified by a unique hash."]}),"\n",(0,s.jsx)(n.p,{children:"Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed."}),"\n",(0,s.jsx)(n.p,{children:"The process can be summarized as follows:"}),"\n",(0,s.jsxs)(n.p,{children:["Given a message ",(0,s.jsx)(n.em,{children:"M"})," to gossip, the desired saturation ",(0,s.jsx)(n.em,{children:"S"}),", and an infection limit ",(0,s.jsx)(n.em,{children:"L"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Pick a subset ",(0,s.jsx)(n.em,{children:"T"})," of ",(0,s.jsx)(n.em,{children:"K"})," nodes from all currently connected nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["Send ",(0,s.jsx)(n.em,{children:"M"})," to each node in ",(0,s.jsx)(n.em,{children:"T"}),", noting which nodes were already infected (a node is considered infected if it already had received or known ",(0,s.jsx)(n.em,{children:"M"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["For every node shown as already infected, add another random node outside to ",(0,s.jsx)(n.em,{children:"T"})," and send it ",(0,s.jsx)(n.em,{children:"M"}),", again noting the response."]}),"\n",(0,s.jsxs)(n.li,{children:["End when we confirm infection of ",(0,s.jsx)(n.em,{children:"L"})," new nodes or encountered ",(0,s.jsx)(n.em,{children:"S"})," already infected nodes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Through this process, a message will spread to almost all nodes over time."}),"\n",(0,s.jsx)(n.h2,{id:"requesting-missing-data",children:"Requesting missing data"}),"\n",(0,s.jsx)(n.p,{children:"While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing deploy from a block."}),"\n",(0,s.jsx)(n.h3,{id:"validation",children:"Validation"}),"\n",(0,s.jsx)(n.p,{children:"Objects have a concept of dependencies. For example, a block depends on all the deploys whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node."}),"\n",(0,s.jsx)(n.p,{children:"Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved."}),"\n",(0,s.jsx)(n.p,{children:"Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so."}),"\n",(0,s.jsx)(n.h2,{id:"node-discovery",children:"Node Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function d(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90efbb16.eca6bbe3.js b/assets/js/90efbb16.eca6bbe3.js new file mode 100644 index 000000000..8c731dfbb --- /dev/null +++ b/assets/js/90efbb16.eca6bbe3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18132],{31352:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>r});var s=i(74848),t=i(28453);const o={},d="Network Communication {#communications-head}",a={id:"concepts/design/p2p",title:"Network Communication",description:"communications-head}",source:"@site/versioned_docs/version-1.5.X/concepts/design/p2p.md",sourceDirName:"concepts/design",slug:"/concepts/design/p2p",permalink:"/1.5.X/concepts/design/p2p",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Design",permalink:"/1.5.X/concepts/design/casper-design"},next:{title:"Highway Consensus",permalink:"/1.5.X/concepts/design/highway"}},c={},r=[{value:"Identity",id:"identity",level:2},{value:"Inter-node connections",id:"inter-node-connections",level:2},{value:"Network",id:"network",level:2},{value:"Gossiping",id:"communications-gossiping",level:2},{value:"Requesting missing data",id:"requesting-missing-data",level:2},{value:"Validation",id:"validation",level:3},{value:"Node Discovery",id:"node-discovery",level:2}];function l(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"communications-head",children:"Network Communication"})}),"\n",(0,s.jsx)(n.h2,{id:"identity",children:"Identity"}),"\n",(0,s.jsx)(n.p,{children:"Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID."}),"\n",(0,s.jsx)(n.p,{children:"Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint."}),"\n",(0,s.jsx)(n.h2,{id:"inter-node-connections",children:"Inter-node connections"}),"\n",(0,s.jsxs)(n.p,{children:["Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the ",(0,s.jsx)(n.em,{children:"client"})," and the remote node the ",(0,s.jsx)(n.em,{children:"server"})," for this connection."]}),"\n",(0,s.jsx)(n.p,{children:"During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks."}),"\n",(0,s.jsx)(n.p,{children:"Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected."}),"\n",(0,s.jsxs)(n.p,{children:["Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"})," on how the server finds endpoints)."]}),"\n",(0,s.jsx)(n.p,{children:"Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it."}),"\n",(0,s.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,s.jsxs)(n.p,{children:["As soon as a node has connected to one node in the network, it partakes in ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"}),". In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network."]}),"\n",(0,s.jsx)(n.p,{children:"Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below."}),"\n",(0,s.jsx)(n.p,{children:"In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped."}),"\n",(0,s.jsx)(n.h2,{id:"communications-gossiping",children:"Gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Multiple types of objects are gossipped, the most prominent ones being blocks, deploys, and endpoints (see ",(0,s.jsx)(n.a,{href:"#identity",children:"Identity"}),"). Each of these objects is immutable and can be identified by a unique hash."]}),"\n",(0,s.jsx)(n.p,{children:"Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed."}),"\n",(0,s.jsx)(n.p,{children:"The process can be summarized as follows:"}),"\n",(0,s.jsxs)(n.p,{children:["Given a message ",(0,s.jsx)(n.em,{children:"M"})," to gossip, the desired saturation ",(0,s.jsx)(n.em,{children:"S"}),", and an infection limit ",(0,s.jsx)(n.em,{children:"L"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Pick a subset ",(0,s.jsx)(n.em,{children:"T"})," of ",(0,s.jsx)(n.em,{children:"K"})," nodes from all currently connected nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["Send ",(0,s.jsx)(n.em,{children:"M"})," to each node in ",(0,s.jsx)(n.em,{children:"T"}),", noting which nodes were already infected (a node is considered infected if it already had received or known ",(0,s.jsx)(n.em,{children:"M"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["For every node shown as already infected, add another random node outside to ",(0,s.jsx)(n.em,{children:"T"})," and send it ",(0,s.jsx)(n.em,{children:"M"}),", again noting the response."]}),"\n",(0,s.jsxs)(n.li,{children:["End when we confirm infection of ",(0,s.jsx)(n.em,{children:"L"})," new nodes or encountered ",(0,s.jsx)(n.em,{children:"S"})," already infected nodes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Through this process, a message will spread to almost all nodes over time."}),"\n",(0,s.jsx)(n.h2,{id:"requesting-missing-data",children:"Requesting missing data"}),"\n",(0,s.jsx)(n.p,{children:"While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing deploy from a block."}),"\n",(0,s.jsx)(n.h3,{id:"validation",children:"Validation"}),"\n",(0,s.jsx)(n.p,{children:"Objects have a concept of dependencies. For example, a block depends on all the deploys whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node."}),"\n",(0,s.jsx)(n.p,{children:"Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved."}),"\n",(0,s.jsx)(n.p,{children:"Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so."}),"\n",(0,s.jsx)(n.h2,{id:"node-discovery",children:"Node Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function d(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/90f2be13.1d93cdbb.js b/assets/js/90f2be13.1d93cdbb.js new file mode 100644 index 000000000..27c5b6ebb --- /dev/null +++ b/assets/js/90f2be13.1d93cdbb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2407],{9008:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>d});var a=n(74848),o=n(28453);const r={title:"Inactive and Faulty Nodes"},i="Inactive vs. Faulty Validator Nodes",s={id:"operators/becoming-a-validator/inactive-vs-faulty",title:"Inactive and Faulty Nodes",description:"This page describes the differences between a validator node being considered inactive or faulty.",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/inactive-vs-faulty.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/inactive-vs-faulty",permalink:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Inactive and Faulty Nodes"},sidebar:"operators",previous:{title:"Recovery",permalink:"/2.0.0/operators/becoming-a-validator/recovering"},next:{title:"Setting up Private Networks",permalink:"/2.0.0/operators/setup-network/"}},l={},d=[];function c(e){const t={a:"a",code:"code",em:"em",h1:"h1",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"inactive-vs-faulty-validator-nodes",children:"Inactive vs. Faulty Validator Nodes"})}),"\n",(0,a.jsx)(t.p,{children:"This page describes the differences between a validator node being considered inactive or faulty."}),"\n",(0,a.jsxs)(t.p,{children:["In the last block of each era ",(0,a.jsx)(t.em,{children:"N"}),", the consensus algorithm checks whether there are ",(0,a.jsx)(t.em,{children:"any"})," messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as ",(0,a.jsx)(t.strong,{children:"inactive"})," in that block."]}),"\n",(0,a.jsxs)(t.p,{children:["Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as ",(0,a.jsx)(t.strong,{children:"faulty"})," in that block. Usually, that means:"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you got marked as ",(0,a.jsx)(t.strong,{children:"inactive"}),", your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed."]}),"\n",(0,a.jsxs)(t.li,{children:["If you got marked as ",(0,a.jsx)(t.strong,{children:"faulty"}),", you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file."]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era ",(0,a.jsx)(t.em,{children:"N"}),". The auction determines the validator set for the era after the next (because ",(0,a.jsx)(t.code,{children:"auction_delay"})," is set to ",(0,a.jsx)(t.code,{children:"1"})," on mainnet), i.e., for era ",(0,a.jsx)(t.em,{children:"N + 2"}),". That means you will still be a validator (with a weight proportional to your stake) in the next era, ",(0,a.jsx)(t.em,{children:"N + 1"}),", but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder."]}),"\n",(0,a.jsxs)(t.p,{children:["And even in the next era, ",(0,a.jsx)(t.em,{children:"N + 1"}),":"]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era ",(0,a.jsx)(t.em,{children:"N + 1"}),", it will get evicted for being offline in era ",(0,a.jsx)(t.em,{children:"N"}),"."]}),"\n",(0,a.jsx)(t.li,{children:"If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards."}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["In both cases, you remain evicted until you reactivate your bid, as described ",(0,a.jsx)(t.a,{href:"/2.0.0/operators/becoming-a-validator/recovering",children:"here"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(c,{...e})}):c(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var a=n(96540);const o={},r=a.createContext(o);function i(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9116852a.695b9cf3.js b/assets/js/9116852a.695b9cf3.js new file mode 100644 index 000000000..1e6f1d57f --- /dev/null +++ b/assets/js/9116852a.695b9cf3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[12418],{38646:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const i={},s="Overview",c={id:"resources/beginner/counter/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/docs/resources/beginner/counter/overview.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/overview",permalink:"/resources/beginner/counter/overview",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/counter"},next:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(12529).A+"",width:"1166",height:"614"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},12529:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-2f7c7ea9d18c57e4cd8b8d010eee38fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const o={},i=r.createContext(o);function s(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9116852a.95b23be5.js b/assets/js/9116852a.95b23be5.js deleted file mode 100644 index 09875321f..000000000 --- a/assets/js/9116852a.95b23be5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2418],{38646:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const i={},s="Overview",c={id:"resources/beginner/counter/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/docs/resources/beginner/counter/overview.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/overview",permalink:"/next/resources/beginner/counter/overview",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759742e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/next/counter"},next:{title:"Casper-Client Commands",permalink:"/next/resources/beginner/counter/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(27527).A+"",width:"1166",height:"614"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},27527:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-2f7c7ea9d18c57e4cd8b8d010eee38fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const o={},i=r.createContext(o);function s(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/915d90e1.21e8e7ff.js b/assets/js/915d90e1.21e8e7ff.js deleted file mode 100644 index 8c47e6850..000000000 --- a/assets/js/915d90e1.21e8e7ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2455],{67689:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var t=i(74848),s=i(28453);const a={title:"Change bid public key"},c="Changing the Public Key Associated with a Validator Bid",r={id:"operators/becoming-a-validator/change-bid-public-key",title:"Change bid public key",description:"The public key associated with a given validator bid can be changed through the auction contract's changebidpublic_key entry point.",source:"@site/docs/operators/becoming-a-validator/change-bid-public-key.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/change-bid-public-key",permalink:"/next/operators/becoming-a-validator/change-bid-public-key",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Change bid public key"}},o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Calling the system auction contract's <code>change_bid_public_key</code> entry point",id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",level:2},{value:"Method 2: Using compiled WASM",id:"method-2-using-compiled-wasm",level:2},{value:"Bridge records",id:"bridge-records",level:2},{value:"Limitations",id:"limitations",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"changing-the-public-key-associated-with-a-validator-bid",children:"Changing the Public Key Associated with a Validator Bid"})}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given validator bid can be changed through the auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point."]}),"\n",(0,t.jsx)(n.p,{children:'An example of this functionality would be to transfer ownership of a validator "slot" to a different party or to migrate a node to a backup server. By leveraging the system contract we can perform those operations more securely by making sure that no private key files need to be copied or transmitted between servers.'}),"\n",(0,t.jsx)(n.p,{children:"When the public key is changed all relevant delegations are also changed to be associated with the updated validator bid."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"For a public key change to be performed successfully there must not exist a validator bid associated with the target public key."}),"\n",(0,t.jsxs)(n.h2,{id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",children:["Method 1: Calling the system auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point"]}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given bid can be changed by calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point of the system auction contract. Using this method, you do not need to build any contracts, which reduces costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point change_bid_public_key \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Transaction in motes. This entry point call needs 5 CSPR."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point on the auction contract has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"method-2-using-compiled-wasm",children:"Method 2: Using compiled WASM"}),"\n",(0,t.jsxs)(n.p,{children:["You may also change the public key associated with a bid via a transaction containing the compiled ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," binary. For details, refer to ",(0,t.jsx)(n.a,{href:"/next/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following transaction is a template for sending a request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn session \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n--pricing-mode fixed \\\n--gas-price-tolerance <GAS_PRICE_TOLERANCE> \\\n--transaction-path $HOME/casper-node/target/wasm32-unknown-unknown/release/change_bid_public_key.wasm \\\n--session-entry-point call \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - Maximum payment for the Transaction in motes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the compiled Wasm on your computer."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entrypoint in the system auction contract, which has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"bridge-records",children:"Bridge records"}),"\n",(0,t.jsxs)(n.p,{children:["In order to continue handling pending unbonds and rewards distribution even if the public key associated with a validator bid has changed, we use dedicated ",(0,t.jsx)(n.code,{children:"Bridge"})," records. These records connect the original public key to the new public key. By following those records we are able to find the current bid even if the public key was changed multiple times."]}),"\n",(0,t.jsx)(n.h2,{id:"limitations",children:"Limitations"}),"\n",(0,t.jsxs)(n.p,{children:["Due to the way the ",(0,t.jsx)(n.code,{children:"Bridge"})," record mechanism works there are some limitations regarding changing public keys to keep in mind:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Because the ",(0,t.jsx)(n.code,{children:"Bridge"})," record replaces the original bid, it's not possible to then change the public key back to the original value, since it would create a loop"]}),"\n",(0,t.jsxs)(n.li,{children:["To avoid unbounded computation we also limit the number of ",(0,t.jsx)(n.code,{children:"Bridge"})," records that can be processed in sequence to 20, which means that:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"For unbonding or redelegation requests, if a validator bid public key is changed more than 20 times between the time a request is created and processed, the funds will be returned to a delegator's main purse"}),"\n",(0,t.jsx)(n.li,{children:"For rewards distribution if the public key changes more than 20 times between the point a validator was elected for a given era and when the rewards are distributed, those rewards will be skipped and not distributed"}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>r});var t=i(96540);const s={},a=t.createContext(s);function c(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/915d90e1.6837c1e2.js b/assets/js/915d90e1.6837c1e2.js new file mode 100644 index 000000000..21dd3ba54 --- /dev/null +++ b/assets/js/915d90e1.6837c1e2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[12455],{67689:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var t=i(74848),s=i(28453);const a={title:"Change bid public key"},c="Changing the Public Key Associated with a Validator Bid",r={id:"operators/becoming-a-validator/change-bid-public-key",title:"Change bid public key",description:"The public key associated with a given validator bid can be changed through the auction contract's changebidpublic_key entry point.",source:"@site/docs/operators/becoming-a-validator/change-bid-public-key.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/change-bid-public-key",permalink:"/operators/becoming-a-validator/change-bid-public-key",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Change bid public key"}},o={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Calling the system auction contract's <code>change_bid_public_key</code> entry point",id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",level:2},{value:"Method 2: Using compiled WASM",id:"method-2-using-compiled-wasm",level:2},{value:"Bridge records",id:"bridge-records",level:2},{value:"Limitations",id:"limitations",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"changing-the-public-key-associated-with-a-validator-bid",children:"Changing the Public Key Associated with a Validator Bid"})}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given validator bid can be changed through the auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point."]}),"\n",(0,t.jsx)(n.p,{children:'An example of this functionality would be to transfer ownership of a validator "slot" to a different party or to migrate a node to a backup server. By leveraging the system contract we can perform those operations more securely by making sure that no private key files need to be copied or transmitted between servers.'}),"\n",(0,t.jsx)(n.p,{children:"When the public key is changed all relevant delegations are also changed to be associated with the updated validator bid."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"For a public key change to be performed successfully there must not exist a validator bid associated with the target public key."}),"\n",(0,t.jsxs)(n.h2,{id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",children:["Method 1: Calling the system auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point"]}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given bid can be changed by calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point of the system auction contract. Using this method, you do not need to build any contracts, which reduces costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point change_bid_public_key \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Transaction in motes. This entry point call needs 5 CSPR."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point on the auction contract has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"method-2-using-compiled-wasm",children:"Method 2: Using compiled WASM"}),"\n",(0,t.jsxs)(n.p,{children:["You may also change the public key associated with a bid via a transaction containing the compiled ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," binary. For details, refer to ",(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following transaction is a template for sending a request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn session \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n--pricing-mode fixed \\\n--gas-price-tolerance <GAS_PRICE_TOLERANCE> \\\n--transaction-path $HOME/casper-node/target/wasm32-unknown-unknown/release/change_bid_public_key.wasm \\\n--session-entry-point call \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - Maximum payment for the Transaction in motes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the compiled Wasm on your computer."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entrypoint in the system auction contract, which has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"bridge-records",children:"Bridge records"}),"\n",(0,t.jsxs)(n.p,{children:["In order to continue handling pending unbonds and rewards distribution even if the public key associated with a validator bid has changed, we use dedicated ",(0,t.jsx)(n.code,{children:"Bridge"})," records. These records connect the original public key to the new public key. By following those records we are able to find the current bid even if the public key was changed multiple times."]}),"\n",(0,t.jsx)(n.h2,{id:"limitations",children:"Limitations"}),"\n",(0,t.jsxs)(n.p,{children:["Due to the way the ",(0,t.jsx)(n.code,{children:"Bridge"})," record mechanism works there are some limitations regarding changing public keys to keep in mind:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Because the ",(0,t.jsx)(n.code,{children:"Bridge"})," record replaces the original bid, it's not possible to then change the public key back to the original value, since it would create a loop"]}),"\n",(0,t.jsxs)(n.li,{children:["To avoid unbounded computation we also limit the number of ",(0,t.jsx)(n.code,{children:"Bridge"})," records that can be processed in sequence to 20, which means that:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"For unbonding or redelegation requests, if a validator bid public key is changed more than 20 times between the time a request is created and processed, the funds will be returned to a delegator's main purse"}),"\n",(0,t.jsx)(n.li,{children:"For rewards distribution if the public key changes more than 20 times between the point a validator was elected for a given era and when the rewards are distributed, those rewards will be skipped and not distributed"}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>r});var t=i(96540);const s={},a=t.createContext(s);function c(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/931ecaed.0c0278da.js b/assets/js/931ecaed.0c0278da.js deleted file mode 100644 index dfb2dcfd4..000000000 --- a/assets/js/931ecaed.0c0278da.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[558],{99247:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=s(74848),o=s(28453);const i={title:"Deploy Lifecycle",slug:"/deploy-and-deploy-lifecycle"},l="Deploys and the Deploy Lifecycle",c={id:"concepts/deploy-and-deploy-lifecycle",title:"Deploy Lifecycle",description:"Deploys",source:"@site/versioned_docs/version-1.5.X/concepts/deploy-and-deploy-lifecycle.md",sourceDirName:"concepts",slug:"/deploy-and-deploy-lifecycle",permalink:"/deploy-and-deploy-lifecycle",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Deploy Lifecycle",slug:"/deploy-and-deploy-lifecycle"},sidebar:"concepts",previous:{title:"Hash Types",permalink:"/concepts/hash-types"},next:{title:"Global State",permalink:"/concepts/global-state"}},d={},a=[{value:"Deploys",id:"execution-semantics-deploys",level:2},{value:"The Deploy Lifecycle",id:"execution-semantics-phases",level:2},{value:"Deploy Received",id:"deploy-received",level:3},{value:"Deploy Gossiped",id:"deploy-gossiped",level:3},{value:"Block Proposed",id:"block-proposed",level:3},{value:"Block Gossiped",id:"block-gossiped",level:3},{value:"Consensus Reached",id:"consensus-reached",level:3},{value:"Deploy Executed",id:"deploy-executed",level:3},{value:"Summary",id:"summary",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"deploys-and-the-deploy-lifecycle",children:"Deploys and the Deploy Lifecycle"})}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-deploys",children:"Deploys"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-deploy",children:"Deploy"})," is a data structure containing Wasm and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy\u2019s structure is as follows:"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Structure of a Deploy",src:s(17347).A+"",width:"900",height:"586"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Body: Containing payment code and session code (more details on these below)"}),"\n",(0,t.jsxs)(n.li,{children:["Header: containing\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#publickey",children:"Public Key"})," of the account in whose context the deploy will run"]}),"\n",(0,t.jsx)(n.li,{children:"The timestamp of the deploy\u2019s creation"}),"\n",(0,t.jsx)(n.li,{children:"A time-to-live, after which the deploy expires and cannot be included in a block"}),"\n",(0,t.jsxs)(n.li,{children:["the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the body"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Deploy hash: the ",(0,t.jsx)(n.code,{children:"blake2b"})," hash of the Header"]}),"\n",(0,t.jsxs)(n.li,{children:["Approvals: the set of signatures which have signed the deploy hash; these are used in the ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"account permissions model"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-phases",children:"The Deploy Lifecycle"}),"\n",(0,t.jsx)(n.p,{children:"A deploy goes through the following phases on Casper:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Deploy Received"}),"\n",(0,t.jsx)(n.li,{children:"Deploy Gossiped"}),"\n",(0,t.jsx)(n.li,{children:"Block Proposed"}),"\n",(0,t.jsx)(n.li,{children:"Block Gossiped"}),"\n",(0,t.jsx)(n.li,{children:"Consensus Reached"}),"\n",(0,t.jsx)(n.li,{children:"Deploy Executed"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-received",children:"Deploy Received"}),"\n",(0,t.jsxs)(n.p,{children:["A client sending the deploy will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given deploy matches configuration settings outlined in the network's chainspec. Deploy configuration for the Casper Mainnet can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L79",children:"here"}),". Once accepted, the system returns the deploy hash to the client to indicate it has been enqueued for execution. The deploy could expire while waiting to be gossiped; whenever this happens, a ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event is emitted by the event stream servers of all nodes which have the expired deploy."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-gossiped",children:"Deploy Gossiped"}),"\n",(0,t.jsxs)(n.p,{children:["After a node accepts a new deploy, it will gossip to all other nodes. A validator node will put the deploy into the block proposer buffer. The validator leader will pick the deploy from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given deploy. Each node that accepts a gossiped deploy also emits a ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," event on its event stream server. The deploy may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event."]}),"\n",(0,t.jsx)(n.h3,{id:"block-proposed",children:"Block Proposed"}),"\n",(0,t.jsx)(n.p,{children:"The validator leader for this round will propose a block that includes as many deploys from the block proposer buffer as can fit in a block."}),"\n",(0,t.jsx)(n.h3,{id:"block-gossiped",children:"Block Gossiped"}),"\n",(0,t.jsx)(n.p,{children:"The proposed block propagates to all other nodes."}),"\n",(0,t.jsx)(n.h3,{id:"consensus-reached",children:"Consensus Reached"}),"\n",(0,t.jsxs)(n.p,{children:["Once the other validators reach consensus that the proposed block is valid, all deploys in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a ",(0,t.jsx)(n.code,{children:"BlockAdded"}),". ",(0,t.jsx)(n.code,{children:"FinalitySignature"})," events emit shortly after that. Finality signatures for the new block arrive from the validators."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-executed",children:"Deploy Executed"}),"\n",(0,t.jsxs)(n.p,{children:["A deploy executes in distinct phases to accommodate flexibly paying for computation. The phases of a deploy are ",(0,t.jsx)(n.em,{children:"payment"}),", ",(0,t.jsx)(n.em,{children:"session"}),", and ",(0,t.jsx)(n.em,{children:"finalization"}),". Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the deploy is executed, a ",(0,t.jsx)(n.code,{children:"DeployProcessed"})," event is emitted by the event stream server."]}),"\n",(0,t.jsx)(n.p,{children:"In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty deploys."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Payment code"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.em,{children:"Payment code"})," determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a deploy. For example, the simplest payment code could use the account's ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#tokens-purses-and-accounts",children:"main purse"}),". In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only accounts with a balance in their main purse greater than or equal to ",(0,t.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," may execute deploys. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than ",(0,t.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," motes (a constant of the system.)\nIf the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending account's main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Session code"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.em,{children:"Session code"})," provides the main logic for the deploy. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Specifying payment code and session code"})}),"\n",(0,t.jsx)(n.p,{children:"The user-defined logic of a deploy can be specified in a number of ways:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the account the deploy is running in.)"}),"\n",(0,t.jsxs)(n.li,{children:["a 32-byte identifier representing the ",(0,t.jsx)(n.a,{href:"/concepts/serialization-standard#serialization-standard-hash-key",children:"hash"})," where a contract is already stored in the global state"]}),"\n",(0,t.jsx)(n.li,{children:"a name corresponding to a named key in the account, where a contract is stored under the key"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module)."}),"\n",(0,t.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,t.jsx)(n.p,{children:"The following diagram summarizes the deploy lifecycle."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Image showing the deploy lifecycle",src:s(34060).A+"",width:"7092",height:"4764"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},34060:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-lifecycle-14d60df99e73f40e4016635aad3c1c05.png"},17347:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-structure-658d8000fd6a573bafc1e7b8535b3c07.png"},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const o={},i=t.createContext(o);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/931ecaed.28170080.js b/assets/js/931ecaed.28170080.js new file mode 100644 index 000000000..12667a575 --- /dev/null +++ b/assets/js/931ecaed.28170080.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40558],{99247:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>a});var t=s(74848),o=s(28453);const i={title:"Deploy Lifecycle",slug:"/deploy-and-deploy-lifecycle"},l="Deploys and the Deploy Lifecycle",c={id:"concepts/deploy-and-deploy-lifecycle",title:"Deploy Lifecycle",description:"Deploys",source:"@site/versioned_docs/version-1.5.X/concepts/deploy-and-deploy-lifecycle.md",sourceDirName:"concepts",slug:"/deploy-and-deploy-lifecycle",permalink:"/1.5.X/deploy-and-deploy-lifecycle",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Deploy Lifecycle",slug:"/deploy-and-deploy-lifecycle"},sidebar:"concepts",previous:{title:"Hash Types",permalink:"/1.5.X/concepts/hash-types"},next:{title:"Global State",permalink:"/1.5.X/concepts/global-state"}},d={},a=[{value:"Deploys",id:"execution-semantics-deploys",level:2},{value:"The Deploy Lifecycle",id:"execution-semantics-phases",level:2},{value:"Deploy Received",id:"deploy-received",level:3},{value:"Deploy Gossiped",id:"deploy-gossiped",level:3},{value:"Block Proposed",id:"block-proposed",level:3},{value:"Block Gossiped",id:"block-gossiped",level:3},{value:"Consensus Reached",id:"consensus-reached",level:3},{value:"Deploy Executed",id:"deploy-executed",level:3},{value:"Summary",id:"summary",level:2}];function r(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"deploys-and-the-deploy-lifecycle",children:"Deploys and the Deploy Lifecycle"})}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-deploys",children:"Deploys"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-deploy",children:"Deploy"})," is a data structure containing Wasm and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy\u2019s structure is as follows:"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Structure of a Deploy",src:s(59629).A+"",width:"900",height:"586"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Body: Containing payment code and session code (more details on these below)"}),"\n",(0,t.jsxs)(n.li,{children:["Header: containing\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#publickey",children:"Public Key"})," of the account in whose context the deploy will run"]}),"\n",(0,t.jsx)(n.li,{children:"The timestamp of the deploy\u2019s creation"}),"\n",(0,t.jsx)(n.li,{children:"A time-to-live, after which the deploy expires and cannot be included in a block"}),"\n",(0,t.jsxs)(n.li,{children:["the ",(0,t.jsx)(n.code,{children:"blake2b256"})," hash of the body"]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Deploy hash: the ",(0,t.jsx)(n.code,{children:"blake2b"})," hash of the Header"]}),"\n",(0,t.jsxs)(n.li,{children:["Approvals: the set of signatures which have signed the deploy hash; these are used in the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-associated-keys-weights",children:"account permissions model"})]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"execution-semantics-phases",children:"The Deploy Lifecycle"}),"\n",(0,t.jsx)(n.p,{children:"A deploy goes through the following phases on Casper:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Deploy Received"}),"\n",(0,t.jsx)(n.li,{children:"Deploy Gossiped"}),"\n",(0,t.jsx)(n.li,{children:"Block Proposed"}),"\n",(0,t.jsx)(n.li,{children:"Block Gossiped"}),"\n",(0,t.jsx)(n.li,{children:"Consensus Reached"}),"\n",(0,t.jsx)(n.li,{children:"Deploy Executed"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-received",children:"Deploy Received"}),"\n",(0,t.jsxs)(n.p,{children:["A client sending the deploy will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given deploy matches configuration settings outlined in the network's chainspec. Deploy configuration for the Casper Mainnet can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L79",children:"here"}),". Once accepted, the system returns the deploy hash to the client to indicate it has been enqueued for execution. The deploy could expire while waiting to be gossiped; whenever this happens, a ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event is emitted by the event stream servers of all nodes which have the expired deploy."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-gossiped",children:"Deploy Gossiped"}),"\n",(0,t.jsxs)(n.p,{children:["After a node accepts a new deploy, it will gossip to all other nodes. A validator node will put the deploy into the block proposer buffer. The validator leader will pick the deploy from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given deploy. Each node that accepts a gossiped deploy also emits a ",(0,t.jsx)(n.code,{children:"DeployAccepted"})," event on its event stream server. The deploy may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a ",(0,t.jsx)(n.code,{children:"DeployExpired"})," event."]}),"\n",(0,t.jsx)(n.h3,{id:"block-proposed",children:"Block Proposed"}),"\n",(0,t.jsx)(n.p,{children:"The validator leader for this round will propose a block that includes as many deploys from the block proposer buffer as can fit in a block."}),"\n",(0,t.jsx)(n.h3,{id:"block-gossiped",children:"Block Gossiped"}),"\n",(0,t.jsx)(n.p,{children:"The proposed block propagates to all other nodes."}),"\n",(0,t.jsx)(n.h3,{id:"consensus-reached",children:"Consensus Reached"}),"\n",(0,t.jsxs)(n.p,{children:["Once the other validators reach consensus that the proposed block is valid, all deploys in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a ",(0,t.jsx)(n.code,{children:"BlockAdded"}),". ",(0,t.jsx)(n.code,{children:"FinalitySignature"})," events emit shortly after that. Finality signatures for the new block arrive from the validators."]}),"\n",(0,t.jsx)(n.h3,{id:"deploy-executed",children:"Deploy Executed"}),"\n",(0,t.jsxs)(n.p,{children:["A deploy executes in distinct phases to accommodate flexibly paying for computation. The phases of a deploy are ",(0,t.jsx)(n.em,{children:"payment"}),", ",(0,t.jsx)(n.em,{children:"session"}),", and ",(0,t.jsx)(n.em,{children:"finalization"}),". Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the deploy is executed, a ",(0,t.jsx)(n.code,{children:"DeployProcessed"})," event is emitted by the event stream server."]}),"\n",(0,t.jsx)(n.p,{children:"In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty deploys."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Payment code"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.em,{children:"Payment code"})," determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a deploy. For example, the simplest payment code could use the account's ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#tokens-purses-and-accounts",children:"main purse"}),". In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only accounts with a balance in their main purse greater than or equal to ",(0,t.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," may execute deploys. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than ",(0,t.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," motes (a constant of the system.)\nIf the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending account's main purse."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Session code"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.em,{children:"Session code"})," provides the main logic for the deploy. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself)."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Specifying payment code and session code"})}),"\n",(0,t.jsx)(n.p,{children:"The user-defined logic of a deploy can be specified in a number of ways:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the account the deploy is running in.)"}),"\n",(0,t.jsxs)(n.li,{children:["a 32-byte identifier representing the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-hash-key",children:"hash"})," where a contract is already stored in the global state"]}),"\n",(0,t.jsx)(n.li,{children:"a name corresponding to a named key in the account, where a contract is stored under the key"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module)."}),"\n",(0,t.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,t.jsx)(n.p,{children:"The following diagram summarizes the deploy lifecycle."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Image showing the deploy lifecycle",src:s(28834).A+"",width:"7092",height:"4764"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},28834:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-lifecycle-14d60df99e73f40e4016635aad3c1c05.png"},59629:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-structure-658d8000fd6a573bafc1e7b8535b3c07.png"},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const o={},i=t.createContext(o);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/947e950c.16603b98.js b/assets/js/947e950c.16603b98.js new file mode 100644 index 000000000..68483a33f --- /dev/null +++ b/assets/js/947e950c.16603b98.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83317],{85867:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var o=t(74848),s=t(28453);const r={},i="Required Methods for Minimal Compliance",a={id:"developers/json-rpc/minimal-compliance",title:"Required Methods for Minimal Compliance",description:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/minimal-compliance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/minimal-compliance",permalink:"/2.0.0/developers/json-rpc/minimal-compliance",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/2.0.0/developers/json-rpc/guidance"},next:{title:"Transactional JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-transactional"}},c={},l=[];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"required-methods-for-minimal-compliance",children:"Required Methods for Minimal Compliance"})}),"\n",(0,o.jsx)(n.p,{children:"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact."}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#chain_get_block",children:(0,o.jsx)(n.code,{children:"chain_get_block"})})," - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#info_get_deploy",children:(0,o.jsx)(n.code,{children:"info_get_deploy"})})," - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-transactional#account_put_deploy",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#chain_get_state_root_hash",children:(0,o.jsx)(n.code,{children:"chain_get_state_root_hash"})})," - The state root hash is one of the several ",(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#globalstateidentifier",children:"global state identifiers"})," used to query the network state after sending deploys."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#state_get_account_info",children:(0,o.jsx)(n.code,{children:"state_get_account_info"})})," - This method returns a JSON representation of an Account from the network. ",(0,o.jsx)(n.code,{children:"state_get_account_info"})," is required to view associated account information, including any associated keys, named keys, action thresholds and the main purse."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#query_balance",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#state_get_dictionary_item",children:(0,o.jsx)(n.code,{children:"state_get_dictionary_item"})})," - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:[(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,o.jsx)(n.code,{children:"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."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsxs)(n.p,{children:["The deprecated methods ",(0,o.jsx)(n.code,{children:"state_get_balance"})," and ",(0,o.jsx)(n.code,{children:"state_get_item"})," should not be used."]})}),"\n",(0,o.jsxs)(n.p,{children:["In addition to these methods, a minimally compliant Casper SDK must account for the ",(0,o.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain",children:"types"})," 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."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var o=t(96540);const s={},r=o.createContext(s);function i(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/94f643bb.0ffdacc0.js b/assets/js/94f643bb.0ffdacc0.js new file mode 100644 index 000000000..fb148976a --- /dev/null +++ b/assets/js/94f643bb.0ffdacc0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64643],{40867:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Q",a={id:"concepts/glossary/Q",title:"Q",description:"---",source:"@site/docs/concepts/glossary/Q.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Q",permalink:"/concepts/glossary/Q",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"P",permalink:"/concepts/glossary/P"},next:{title:"R",permalink:"/concepts/glossary/R"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"q",children:"Q"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/94f643bb.31c536d4.js b/assets/js/94f643bb.31c536d4.js deleted file mode 100644 index 18f2ed258..000000000 --- a/assets/js/94f643bb.31c536d4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7024],{40867:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="Q",a={id:"concepts/glossary/Q",title:"Q",description:"---",source:"@site/docs/concepts/glossary/Q.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Q",permalink:"/next/concepts/glossary/Q",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"P",permalink:"/next/concepts/glossary/P"},next:{title:"R",permalink:"/next/concepts/glossary/R"}},l={},h=[];function x(e){const s={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"q",children:"Q"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/95c53987.293de8d0.js b/assets/js/95c53987.293de8d0.js new file mode 100644 index 000000000..3a9cded5c --- /dev/null +++ b/assets/js/95c53987.293de8d0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6746],{72383:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=s(74848),n=s(28453);const r={},o="S",c={id:"concepts/glossary/S",title:"S",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/S.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/S",permalink:"/2.0.0/concepts/glossary/S",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"R",permalink:"/2.0.0/concepts/glossary/R"},next:{title:"T",permalink:"/2.0.0/concepts/glossary/T"}},i={},l=[{value:"Safe",id:"safe",level:2},{value:"Secret key",id:"secret-key",level:2},{value:"Seigniorage",id:"seigniorage",level:2},{value:"Session code",id:"session-code",level:2},{value:"Slashing",id:"slashing",level:2},{value:"Smart contract",id:"smart-contract",level:2},{value:"Smart-contract platform",id:"smart-contract-platform",level:2},{value:"Staker",id:"staker",level:2},{value:"Staking",id:"staking",level:2},{value:"State root hash",id:"state-root-hash",level:2},{value:"Stateful",id:"stateful",level:2},{value:"Stateless",id:"stateless",level:2},{value:"Switch Block",id:"switch-block",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"s",children:"S"})}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.h2,{id:"safe",children:"Safe"}),"\n",(0,a.jsxs)(t.p,{children:["When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"secret-key",children:"Secret key"}),"\n",(0,a.jsx)(t.p,{children:"A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations)."}),"\n",(0,a.jsx)(t.h2,{id:"seigniorage",children:"Seigniorage"}),"\n",(0,a.jsx)(t.p,{children:"The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators."}),"\n",(0,a.jsx)(t.h2,{id:"session-code",children:"Session code"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"Session code"})," is Wasm executed in the context of an account entity through sending a ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transaction"}),". The ",(0,a.jsx)(t.em,{children:"session code"})," contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state."]}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsxs)(t.p,{children:["In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets ",(0,a.jsx)(t.em,{children:"slashed"}),", i.e., a part of it is removed."]}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract",children:"Smart contract"}),"\n",(0,a.jsx)(t.p,{children:"Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party."}),"\n",(0,a.jsxs)(t.p,{children:["On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"}),". The execution of a smart contract causes changes to the global state."]}),"\n",(0,a.jsx)(t.p,{children:"A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values."}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract-platform",children:"Smart-contract platform"}),"\n",(0,a.jsx)(t.p,{children:"A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts."}),"\n",(0,a.jsx)(t.h2,{id:"staker",children:"Staker"}),"\n",(0,a.jsxs)(t.p,{children:["A staker is either a ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validator"})," or a ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/D#delegator",children:"delegator"}),". Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/T#token",children:"tokens"})," by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is ",(0,a.jsx)(t.a,{href:"#slashing",children:"slashed"}),", the staker will lose their tokens."]}),"\n",(0,a.jsx)(t.h2,{id:"staking",children:"Staking"}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/economics/staking",children:"Staking Guide"})," highlights the steps required to stake CSPR tokens on the Casper Mainnet."]}),"\n",(0,a.jsx)(t.h2,{id:"state-root-hash",children:"State root hash"}),"\n",(0,a.jsxs)(t.p,{children:["The state root hash is an identifier of the network's ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"})," at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras."]}),"\n",(0,a.jsx)(t.h2,{id:"stateful",children:"Stateful"}),"\n",(0,a.jsx)(t.p,{children:"Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions."}),"\n",(0,a.jsx)(t.h2,{id:"stateless",children:"Stateless"}),"\n",(0,a.jsx)(t.p,{children:"Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time."}),"\n",(0,a.jsx)(t.h2,{id:"switch-block",children:"Switch Block"}),"\n",(0,a.jsxs)(t.p,{children:["A ",(0,a.jsx)(t.code,{children:"Switch Block"})," is the final block in an era, which contains the ",(0,a.jsx)(t.code,{children:"era_summary"}),". See also ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/B#booking-block",children:"booking block"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var a=s(96540);const n={},r=a.createContext(n);function o(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/962c96ee.fd744aa5.js b/assets/js/962c96ee.fd744aa5.js new file mode 100644 index 000000000..19a4ac9ab --- /dev/null +++ b/assets/js/962c96ee.fd744aa5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80852],{82189:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var a=n(74848),o=n(28453);const r={},s="dApp Technology Stack",i={id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/2.0.0/developers/dapps/technology-stack",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/2.0.0/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/2.0.0/developers/dapps/template-frontend"}},c={},l=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"dapp-technology-stack",children:"dApp Technology Stack"})}),"\n",(0,a.jsx)(t.p,{children:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."}),"\n",(0,a.jsx)(t.h2,{id:"front-end",children:"Front-End"}),"\n",(0,a.jsxs)(t.p,{children:["The front-end, or ",(0,a.jsx)(t.em,{children:"client-side"})," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."]}),"\n",(0,a.jsxs)(t.p,{children:["You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS"})," requirements."]}),"\n",(0,a.jsx)(t.h3,{id:"signing-transactions",children:"Signing Transactions"}),"\n",(0,a.jsx)(t.p,{children:"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The Casper Wallet"}),"\n",(0,a.jsxs)(t.p,{children:["Use the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Casper Wallet"})," to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."]}),"\n",(0,a.jsx)(t.admonition,{type:"caution",children:(0,a.jsxs)(t.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Third-party signers"}),"\n",(0,a.jsx)(t.p,{children:"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,a.jsx)(t.p,{children:"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."}),"\n",(0,a.jsx)(t.h2,{id:"backend",children:"Backend"}),"\n",(0,a.jsxs)(t.p,{children:["The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS headers"})," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."]}),"\n",(0,a.jsx)(t.p,{children:"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."}),"\n",(0,a.jsxs)(t.tabs,{children:["\n",(0,a.jsxs)(t.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.tabitem,{value:"py",label:"Python",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"tip",children:(0,a.jsxs)(t.p,{children:["You can find online peers for Mainnet at ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," or testnet at ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live",children:"testnet.cspr.live"})]})}),"\n",(0,a.jsx)(t.p,{children:"There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end."}),"\n",(0,a.jsx)(t.p,{children:"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."}),"\n",(0,a.jsx)(t.p,{children:"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."}),"\n",(0,a.jsx)(t.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,a.jsxs)(t.p,{children:["The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/json-rpc-transactional",children:"transactional"}),", ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational",children:"informational"}),", and ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake"})," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."]}),"\n",(0,a.jsxs)(t.p,{children:["More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,a.jsx)(t.a,{href:"https://webassembly.org/",children:"WebAssembly"})," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,a.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"Rust"})," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."]}),"\n",(0,a.jsxs)(t.p,{children:["To learn how to write smart contracts for your dApp, read the ",(0,a.jsx)(t.a,{href:"/2.0.0/writing-contracts",children:"smart contract documentation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const o={},r=a.createContext(o);function s(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/96fcb421.99cb328e.js b/assets/js/96fcb421.99cb328e.js new file mode 100644 index 000000000..764a31a4b --- /dev/null +++ b/assets/js/96fcb421.99cb328e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87446],{39724:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>o,metadata:()=>a,toc:()=>d});var n=r(74848),s=r(28453);const o={},i="Setting up Private Networks",a={id:"operators/setup-network/index",title:"Setting up Private Networks",description:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.",source:"@site/versioned_docs/version-2.0.0/operators/setup-network/index.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/",permalink:"/2.0.0/operators/setup-network/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"operators",previous:{title:"Inactive and Faulty Nodes",permalink:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty"},next:{title:"Genesis",permalink:"/2.0.0/operators/setup-network/genesis"}},c={},d=[];function p(e){const t={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"setting-up-private-networks",children:"Setting up Private Networks"})}),"\n",(0,n.jsx)(t.p,{children:"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(t.table,{children:[(0,n.jsx)(t.thead,{children:(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.th,{children:"Title"}),(0,n.jsx)(t.th,{children:"Description"})]})}),(0,n.jsxs)(t.tbody,{children:[(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/2.0.0/operators/setup-network/genesis",children:"The Genesis Block"})}),(0,n.jsx)(t.td,{children:"Files needed to create a genesis block"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"The Chain Specification"})}),(0,n.jsx)(t.td,{children:"Configuration settings describing the network state"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/2.0.0/operators/setup-network/create-private",children:"Setting up a Private Casper Network"})}),(0,n.jsx)(t.td,{children:"A step-by-step guide to establishing and configuring a private Casper network"})]}),(0,n.jsxs)(t.tr,{children:[(0,n.jsx)(t.td,{children:(0,n.jsx)(t.a,{href:"/2.0.0/operators/setup-network/staging-files-for-new-network",children:"Staging Files for a New Network"})}),(0,n.jsx)(t.td,{children:"A guide to hosting protocol files for a new Casper network"})]})]})]})]})}function l(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const s={},o=n.createContext(s);function i(e){const t=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),n.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/977c8faa.143671f7.js b/assets/js/977c8faa.143671f7.js new file mode 100644 index 000000000..707fe2d0e --- /dev/null +++ b/assets/js/977c8faa.143671f7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66221],{63116:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>r});var s=i(74848),t=i(28453);const o={},d="Network Communication {#communications-head}",a={id:"concepts/design/p2p",title:"Network Communication",description:"communications-head}",source:"@site/docs/concepts/design/p2p.md",sourceDirName:"concepts/design",slug:"/concepts/design/p2p",permalink:"/concepts/design/p2p",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Design",permalink:"/concepts/design/casper-design"},next:{title:"Consensus in a Casper Network",permalink:"/concepts/design/consensus"}},c={},r=[{value:"Identity",id:"identity",level:2},{value:"Inter-node connections",id:"inter-node-connections",level:2},{value:"Network",id:"network",level:2},{value:"Gossiping",id:"communications-gossiping",level:2},{value:"Requesting missing data",id:"requesting-missing-data",level:2},{value:"Validation",id:"validation",level:3},{value:"Node Discovery",id:"node-discovery",level:2}];function l(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"communications-head",children:"Network Communication"})}),"\n",(0,s.jsx)(n.h2,{id:"identity",children:"Identity"}),"\n",(0,s.jsx)(n.p,{children:"Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID."}),"\n",(0,s.jsx)(n.p,{children:"Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint."}),"\n",(0,s.jsx)(n.h2,{id:"inter-node-connections",children:"Inter-node connections"}),"\n",(0,s.jsxs)(n.p,{children:["Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the ",(0,s.jsx)(n.em,{children:"client"})," and the remote node the ",(0,s.jsx)(n.em,{children:"server"})," for this connection."]}),"\n",(0,s.jsx)(n.p,{children:"During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks."}),"\n",(0,s.jsx)(n.p,{children:"Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected."}),"\n",(0,s.jsxs)(n.p,{children:["Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"})," on how the server finds endpoints)."]}),"\n",(0,s.jsx)(n.p,{children:"Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it."}),"\n",(0,s.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,s.jsxs)(n.p,{children:["As soon as a node has connected to one node in the network, it partakes in ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"}),". In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network."]}),"\n",(0,s.jsx)(n.p,{children:"Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below."}),"\n",(0,s.jsx)(n.p,{children:"In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped."}),"\n",(0,s.jsx)(n.h2,{id:"communications-gossiping",children:"Gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see ",(0,s.jsx)(n.a,{href:"#identity",children:"Identity"}),"). Each of these objects is immutable and can be identified by a unique hash."]}),"\n",(0,s.jsx)(n.p,{children:"Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed."}),"\n",(0,s.jsx)(n.p,{children:"The process can be summarized as follows:"}),"\n",(0,s.jsxs)(n.p,{children:["Given a message ",(0,s.jsx)(n.em,{children:"M"})," to gossip, the desired saturation ",(0,s.jsx)(n.em,{children:"S"}),", and an infection limit ",(0,s.jsx)(n.em,{children:"L"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Pick a subset ",(0,s.jsx)(n.em,{children:"T"})," of ",(0,s.jsx)(n.em,{children:"K"})," nodes from all currently connected nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["Send ",(0,s.jsx)(n.em,{children:"M"})," to each node in ",(0,s.jsx)(n.em,{children:"T"}),", noting which nodes were already infected (a node is considered infected if it already had received or known ",(0,s.jsx)(n.em,{children:"M"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["For every node shown as already infected, add another random node outside to ",(0,s.jsx)(n.em,{children:"T"})," and send it ",(0,s.jsx)(n.em,{children:"M"}),", again noting the response."]}),"\n",(0,s.jsxs)(n.li,{children:["End when we confirm infection of ",(0,s.jsx)(n.em,{children:"L"})," new nodes or encountered ",(0,s.jsx)(n.em,{children:"S"})," already infected nodes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Through this process, a message will spread to almost all nodes over time."}),"\n",(0,s.jsx)(n.h2,{id:"requesting-missing-data",children:"Requesting missing data"}),"\n",(0,s.jsx)(n.p,{children:"While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block."}),"\n",(0,s.jsx)(n.h3,{id:"validation",children:"Validation"}),"\n",(0,s.jsx)(n.p,{children:"Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node."}),"\n",(0,s.jsx)(n.p,{children:"Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved."}),"\n",(0,s.jsx)(n.p,{children:"Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so."}),"\n",(0,s.jsx)(n.h2,{id:"node-discovery",children:"Node Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function d(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/977c8faa.34237830.js b/assets/js/977c8faa.34237830.js deleted file mode 100644 index e893de235..000000000 --- a/assets/js/977c8faa.34237830.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6221],{63116:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>r});var s=i(74848),t=i(28453);const o={},d="Network Communication {#communications-head}",a={id:"concepts/design/p2p",title:"Network Communication",description:"communications-head}",source:"@site/docs/concepts/design/p2p.md",sourceDirName:"concepts/design",slug:"/concepts/design/p2p",permalink:"/next/concepts/design/p2p",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Design",permalink:"/next/concepts/design/casper-design"},next:{title:"Consensus in a Casper Network",permalink:"/next/concepts/design/consensus"}},c={},r=[{value:"Identity",id:"identity",level:2},{value:"Inter-node connections",id:"inter-node-connections",level:2},{value:"Network",id:"network",level:2},{value:"Gossiping",id:"communications-gossiping",level:2},{value:"Requesting missing data",id:"requesting-missing-data",level:2},{value:"Validation",id:"validation",level:3},{value:"Node Discovery",id:"node-discovery",level:2}];function l(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"communications-head",children:"Network Communication"})}),"\n",(0,s.jsx)(n.h2,{id:"identity",children:"Identity"}),"\n",(0,s.jsx)(n.p,{children:"Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID."}),"\n",(0,s.jsx)(n.p,{children:"Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint."}),"\n",(0,s.jsx)(n.h2,{id:"inter-node-connections",children:"Inter-node connections"}),"\n",(0,s.jsxs)(n.p,{children:["Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the ",(0,s.jsx)(n.em,{children:"client"})," and the remote node the ",(0,s.jsx)(n.em,{children:"server"})," for this connection."]}),"\n",(0,s.jsx)(n.p,{children:"During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks."}),"\n",(0,s.jsx)(n.p,{children:"Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected."}),"\n",(0,s.jsxs)(n.p,{children:["Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"})," on how the server finds endpoints)."]}),"\n",(0,s.jsx)(n.p,{children:"Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it."}),"\n",(0,s.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,s.jsxs)(n.p,{children:["As soon as a node has connected to one node in the network, it partakes in ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"}),". In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network."]}),"\n",(0,s.jsx)(n.p,{children:"Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below."}),"\n",(0,s.jsx)(n.p,{children:"In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped."}),"\n",(0,s.jsx)(n.h2,{id:"communications-gossiping",children:"Gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see ",(0,s.jsx)(n.a,{href:"#identity",children:"Identity"}),"). Each of these objects is immutable and can be identified by a unique hash."]}),"\n",(0,s.jsx)(n.p,{children:"Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed."}),"\n",(0,s.jsx)(n.p,{children:"The process can be summarized as follows:"}),"\n",(0,s.jsxs)(n.p,{children:["Given a message ",(0,s.jsx)(n.em,{children:"M"})," to gossip, the desired saturation ",(0,s.jsx)(n.em,{children:"S"}),", and an infection limit ",(0,s.jsx)(n.em,{children:"L"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Pick a subset ",(0,s.jsx)(n.em,{children:"T"})," of ",(0,s.jsx)(n.em,{children:"K"})," nodes from all currently connected nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["Send ",(0,s.jsx)(n.em,{children:"M"})," to each node in ",(0,s.jsx)(n.em,{children:"T"}),", noting which nodes were already infected (a node is considered infected if it already had received or known ",(0,s.jsx)(n.em,{children:"M"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["For every node shown as already infected, add another random node outside to ",(0,s.jsx)(n.em,{children:"T"})," and send it ",(0,s.jsx)(n.em,{children:"M"}),", again noting the response."]}),"\n",(0,s.jsxs)(n.li,{children:["End when we confirm infection of ",(0,s.jsx)(n.em,{children:"L"})," new nodes or encountered ",(0,s.jsx)(n.em,{children:"S"})," already infected nodes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Through this process, a message will spread to almost all nodes over time."}),"\n",(0,s.jsx)(n.h2,{id:"requesting-missing-data",children:"Requesting missing data"}),"\n",(0,s.jsx)(n.p,{children:"While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block."}),"\n",(0,s.jsx)(n.h3,{id:"validation",children:"Validation"}),"\n",(0,s.jsx)(n.p,{children:"Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node."}),"\n",(0,s.jsx)(n.p,{children:"Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved."}),"\n",(0,s.jsx)(n.p,{children:"Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so."}),"\n",(0,s.jsx)(n.h2,{id:"node-discovery",children:"Node Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function d(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/98d1a471.222d0cf9.js b/assets/js/98d1a471.222d0cf9.js new file mode 100644 index 000000000..3bc402021 --- /dev/null +++ b/assets/js/98d1a471.222d0cf9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13986],{5987:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>p,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const c={},i="Getting Started with AssemblyScript",a={id:"developers/writing-onchain-code/assembly-script",title:"Getting Started with AssemblyScript",description:"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/assembly-script.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/assembly-script",permalink:"/2.0.0/developers/writing-onchain-code/assembly-script",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with Rust",permalink:"/2.0.0/developers/writing-onchain-code/getting-started"},next:{title:"Writing a Basic Smart Contract in Rust",permalink:"/2.0.0/developers/writing-onchain-code/simple-contract"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing AssemblyScript",id:"installing-assemblyscript",level:3},{value:"Development Environment Setup",id:"development-environment-setup",level:2},{value:"Installing the Casper Package",id:"installing-the-casper-package",level:3},{value:"Creating a Project",id:"creating-a-project",level:3},{value:"Script Entries",id:"script-entries",level:3},{value:"Sample Smart Contract",id:"sample-smart-contract",level:3},{value:"Compile to Wasm",id:"compile-to-wasm",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"getting-started-with-assemblyscript",children:"Getting Started with AssemblyScript"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper Labs maintains the ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"casper-contract"})," to allow developers to create smart contracts using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"AssemblyScript"}),". The package source is hosted in the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/smart_contracts/contract_as/assembly",children:"main Casper Network repository"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(n.h3,{id:"installing-assemblyscript",children:"Installing AssemblyScript"}),"\n",(0,s.jsxs)(n.p,{children:["Installation of AssemblyScript requires ",(0,s.jsx)(n.a,{href:"https://nodejs.org/",children:"Node.js"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After installation of Node.js, the following command will install AssemblyScript:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i assemblyscript\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Full instructions and details for installing AssemblyScript can be found ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/assemblyscript",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"development-environment-setup",children:"Development Environment Setup"}),"\n",(0,s.jsx)(n.h3,{id:"installing-the-casper-package",children:"Installing the Casper Package"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-contract"})," package can be installed using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm i casper-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Assemblyscript contract API documentation can be found at ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-contract",children:"https://www.npmjs.com/package/casper-contract"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"creating-a-project",children:"Creating a Project"}),"\n",(0,s.jsx)(n.p,{children:"For each smart contract, it is necessary to create a project directory and initialize it."}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"npm init"})," process prompts for various details about the project. Answer as you see fit, but you may safely default everything except ",(0,s.jsx)(n.code,{children:"name"}),", which needs to be specified. In this guide, we will refer to the contract name as ",(0,s.jsx)(n.code,{children:"your-contract-name"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"mkdir project\ncd project\nnpm init\n"})}),"\n",(0,s.jsx)(n.p,{children:"Then install AssemblyScript and this package in the project directory."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"npm install --save-dev assemblyscript@0.9.1\nnpm install --save casper-contract\n"})}),"\n",(0,s.jsx)(n.h3,{id:"script-entries",children:"Script Entries"}),"\n",(0,s.jsxs)(n.p,{children:["Add script entries for AssemblyScript to your project's ",(0,s.jsx)(n.code,{children:"package.json"}),". Note that your contract name is used for the name of the Wasm file. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "name": "your-contract-name",\n ...\n "scripts": {\n "asbuild:optimized": "asc assembly/index.ts -b dist/your-contract-name.wasm --validate --optimize --use abort=",\n "asbuild": "npm run asbuild:optimized",\n ...\n },\n ...\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the project root, create an ",(0,s.jsx)(n.code,{children:"index.js"})," file with the following contents. Replace ",(0,s.jsx)(n.em,{children:"your-contract-name"})," with the name of your contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'const fs = require("fs");\n\nconst compiled = new WebAssembly.Module(fs.readFileSync(__dirname + "/dist/your-contract-name.wasm"));\n\nconst imports = {\n env: {\n abort(_msg, _file, line, column) {\n console.error("abort called at index.ts:" + line + ":" + column);\n },\n },\n};\n\nObject.defineProperty(module, "exports", {\n get: () => new WebAssembly.Instance(compiled, imports).exports,\n});\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, create a directory called ",(0,s.jsx)(n.code,{children:"assembly"}),", and in that directory, create a file called ",(0,s.jsx)(n.code,{children:"tsconfig.json"})," in the following way:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "extends": "../node_modules/assemblyscript/std/assembly.json",\n "include": ["./**/*.ts"]\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sample-smart-contract",children:"Sample Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["In the ",(0,s.jsx)(n.code,{children:"assembly"})," directory, also create an ",(0,s.jsx)(n.code,{children:"index.ts"})," file, where the code for the contract needs to go."]}),"\n",(0,s.jsx)(n.p,{children:"You can use the following sample snippet, which demonstrates a simple smart contract that immediately returns an error and writes a message to a block when executed on a Casper network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-typescript",children:'//@ts-nocheck\nimport { Error, ErrorCode } from "casper-contract/error";\n\n// simplest possible feedback loop\nexport function call(): void {\n Error.fromErrorCode(ErrorCode.None).revert(); // ErrorCode: 1\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you prefer a more complicated first contract, you can look at example contracts on the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem GitHub"})," repository for inspiration."]}),"\n",(0,s.jsx)(n.h3,{id:"compile-to-wasm",children:"Compile to Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["To compile the contract to Wasm, use ",(0,s.jsx)(n.em,{children:"npm"})," to run the ",(0,s.jsx)(n.em,{children:"asbuild"})," script from the project root:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"npm run asbuild\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the build is successful, there will be a ",(0,s.jsx)(n.code,{children:"dist"})," folder in the ",(0,s.jsx)(n.code,{children:"root"})," folder and in it should be ",(0,s.jsx)(n.code,{children:"your-contract-name.wasm"}),"."]})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},c=s.createContext(r);function i(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/98df448b.23f7a8f8.js b/assets/js/98df448b.23f7a8f8.js deleted file mode 100644 index 0547895b5..000000000 --- a/assets/js/98df448b.23f7a8f8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7772],{24120:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>i,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var n=t(74848),s=t(28453);const a={title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/welcome-docs-redux",source:"@site/blog/2024-08-15-hello-blogworld.md",title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",date:"2024-08-15T18:00:00.000Z",tags:[{inline:!0,label:"hello",permalink:"/blog/tags/hello"},{inline:!0,label:"new docs",permalink:"/blog/tags/new-docs"},{inline:!0,label:"docs-redux",permalink:"/blog/tags/docs-redux"}],readingTime:.595,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"validator rewards in Casper 2.0",permalink:"/blog/condor-validator-rewards"},nextItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"}},i={authorsImageUrls:[void 0]},d=[];function c(e){const o={a:"a",p:"p",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.p,{children:"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0."}),"\n",(0,n.jsxs)(o.p,{children:["Please enjoy and if you have any comments, suggestions or errata, please email ",(0,n.jsx)(o.a,{href:"mailto:devrel@casper.network",children:"devrel@casper.network"})," with your contribution or query."]})]})}function p(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>r,x:()=>l});var n=t(96540);const s={},a=n.createContext(s);function r(e){const o=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/98df448b.4dbc3804.js b/assets/js/98df448b.4dbc3804.js new file mode 100644 index 000000000..424b75739 --- /dev/null +++ b/assets/js/98df448b.4dbc3804.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[77772],{24120:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>i,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var n=t(74848),s=t(28453);const a={title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/welcome-docs-redux",source:"@site/blog/2024-08-15-hello-blogworld.md",title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",date:"2024-08-15T18:00:00.000Z",tags:[{inline:!0,label:"hello",permalink:"/blog/tags/hello"},{inline:!0,label:"new docs",permalink:"/blog/tags/new-docs"},{inline:!0,label:"docs-redux",permalink:"/blog/tags/docs-redux"}],readingTime:.595,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"validator rewards in Casper 2.0",permalink:"/blog/condor-validator-rewards"},nextItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"}},i={authorsImageUrls:[void 0]},d=[];function c(e){const o={a:"a",p:"p",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.p,{children:"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0."}),"\n",(0,n.jsxs)(o.p,{children:["Please enjoy and if you have any comments, suggestions or errata, please email ",(0,n.jsx)(o.a,{href:"mailto:devrel@casper.network",children:"devrel@casper.network"})," with your contribution or query."]})]})}function p(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>r,x:()=>l});var n=t(96540);const s={},a=n.createContext(s);function r(e){const o=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/99a13742.82691f99.js b/assets/js/99a13742.82691f99.js new file mode 100644 index 000000000..f2f5c701a --- /dev/null +++ b/assets/js/99a13742.82691f99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59895],{58591:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(74848),o=s(28453);const r={title:"Configuration"},t="Basic Node Configuration",c={id:"operators/setup/basic-node-configuration",title:"Configuration",description:"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.",source:"@site/docs/operators/setup/basic-node-configuration.md",sourceDirName:"operators/setup",slug:"/operators/setup/basic-node-configuration",permalink:"/operators/setup/basic-node-configuration",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Configuration"},sidebar:"operators",previous:{title:"Hardware",permalink:"/operators/setup/hardware"},next:{title:"Endpoints",permalink:"/operators/setup/node-endpoints"}},l={},d=[{value:"The Casper Node Launcher",id:"casper-node-launcher",level:2},{value:"File Locations",id:"file-locations",level:2},{value:"<code>/usr/bin/</code>",id:"usrbin",level:3},{value:"<code>/etc/casper/</code>",id:"etccasper",level:3},{value:"<code>/var/lib/casper/</code>",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the <code>config.toml</code> file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-node-configuration",children:"Basic Node Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,i.jsx)(n.a,{href:"/operators/setup/install-node",children:"Node Setup"})," guide."]}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-launcher",children:"The Casper Node Launcher"}),"\n",(0,i.jsxs)(n.p,{children:["A node is usually run by executing the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),", which executes the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process and also handles upgrades to bring the node to the latest version released."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," can be installed via a Debian package, which also creates the ",(0,i.jsx)(n.code,{children:"casper"})," user and directory structures and sets up a ",(0,i.jsx)(n.code,{children:"systemd"})," unit and logging."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian package can be obtained from ",(0,i.jsx)(n.a,{href:"https://repo.casperlabs.io",children:"https://repo.casperlabs.io"}),". You only need to run the steps detailed there once."]}),"\n",(0,i.jsxs)(n.p,{children:["Then, proceed to install the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," by running these commands:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install casper-node-launcher\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also build ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"from source"}),". However, all the setup and pull of casper-node releases will be manual."]}),"\n",(0,i.jsx)(n.h2,{id:"file-locations",children:"File Locations"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian installation creates the directories and files needed to run ",(0,i.jsx)(n.code,{children:"casper-node"})," versions and perform upgrades. A ",(0,i.jsx)(n.code,{children:"casper"})," user and ",(0,i.jsx)(n.code,{children:"casper"})," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,i.jsx)(n.code,{children:"/etc/casper"})," and ",(0,i.jsx)(n.code,{children:"/var/lib/casper"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"The casper-node install version"})}),"\n",(0,i.jsxs)(n.p,{children:["Each version of the ",(0,i.jsx)(n.code,{children:"casper-node"})," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,i.jsx)(n.code,{children:"1_0_3"}),". This convention applies to both binary and configuration file locations. Versioning with ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," represents the major, minor, and patch of a semantic version."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Multiple versioned folders will exist on a system when upgrades are set up."})}),"\n",(0,i.jsxs)(n.p,{children:["The following is the filesystem's state after installing the ",(0,i.jsx)(n.code,{children:"casper-client"})," and ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian packages, and after running the command ",(0,i.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf"})," (Use casper-test.conf if on Testnet)."]}),"\n",(0,i.jsx)(n.h3,{id:"usrbin",children:(0,i.jsx)(n.code,{children:"/usr/bin/"})}),"\n",(0,i.jsxs)(n.p,{children:["The default location for executables from the Debian package install is ",(0,i.jsx)(n.code,{children:"/usr/bin"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-client"})," - A client for interacting with a Casper network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher"})," - The launcher application which starts the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"etccasper",children:(0,i.jsx)(n.code,{children:"/etc/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the default location for configuration files. It can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_CONFIG_DIR"})," environment variable. The paths in this document assume the default configuration file location of ",(0,i.jsx)(n.code,{children:"/etc/casper"}),". The data is organized as follows:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"delete_local_db.sh"})," - Removes ",(0,i.jsx)(n.code,{children:"*.lmdb*"})," files from ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"})," - Pulls ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," from ",(0,i.jsx)(n.a,{href:"https://genesis.casperlabs.io/",children:"genesis.casperlabs.io"})," for a specified protocol version and extracts them into ",(0,i.jsx)(n.code,{children:"/var/lib/bin/<protocol_version>"})," and ",(0,i.jsx)(n.code,{children:"/etc/casper/<protocol_version>"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config_from_example.sh"})," - Gets external IP to replace and create the ",(0,i.jsx)(n.code,{children:"config.toml"})," from ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node_util.py"})," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"}),", ",(0,i.jsx)(n.code,{children:"config_from_example.sh"}),", and ",(0,i.jsx)(n.code,{children:"delete_local_db.sh"}),". Other scripts will be deprecated in future releases of ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher-state.toml"})," - The local state for the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," which is created during the first run"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_keys/"})," - The default folder for node keys, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Instructions on how to create validator keys using the ",(0,i.jsx)(n.code,{children:"casper-client"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret_key.pem"})," - Secret key used by the validator node to sign blocks and peer-to-peer messages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key.pem"})," - Public key associated with the secret key above, stored in PEM format"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key_hex"})," - Public key associated with the secret key above, stored in hex format"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"accounts.toml"})," - Contains the genesis validators and delegators"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," (network start time) as a timestamp"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - Example for creating a ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,i.jsx)(n.code,{children:"config_from_example.sh 1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package's configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," as an era ID (the era at which this protocol version of the node became or will become active)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config-example.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"varlibcasper",children:(0,i.jsx)(n.code,{children:"/var/lib/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the location for larger and variable data for the ",(0,i.jsx)(n.code,{children:"casper-node"}),", organized in the following folders and files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bin/"})," - The parent folder storing the versions of ",(0,i.jsx)(n.code,{children:"casper-node"})," executables. This location can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_BIN_DIR"})," environment variable. The paths in this document assume the default of ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis binary files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - The node executable - defaults to the Ubuntu 20.04 compatible binary"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/casper-node"}),", but the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/README.md"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"casper-node/<NETWORK NAME>"})," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,i.jsx)(n.code,{children:"casper"})," and for Testnet it is ",(0,i.jsx)(n.code,{children:"casper-test"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmdb"})," - Persistent global state store of the network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmbd-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"data.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb"})," - Persistent store of all other network data, primarily Blocks and transactions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"storage.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"unit_files/"})," - Folder containing transient caches of consensus information"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"node-version-installation",children:"Node Version Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is ",(0,i.jsx)(n.code,{children:"node_util.py"})," for installing ",(0,i.jsx)(n.code,{children:"casper-node"})," versions. This command will stage all current ",(0,i.jsx)(n.code,{children:"casper-node"})," versions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"<NETWORK_CONFIG>"}),", we use ",(0,i.jsx)(n.code,{children:"casper.conf"})," for Mainnet and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," for Testnet. This will install all currently released protocols in one step."]}),"\n",(0,i.jsx)(n.p,{children:"This command will do the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," containing at a minimum ",(0,i.jsx)(n.code,{children:"casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," containing ",(0,i.jsx)(n.code,{children:"chainspec.toml"}),", ",(0,i.jsx)(n.code,{children:"config-example.toml"}),", and possibly ",(0,i.jsx)(n.code,{children:"accounts.csv"})," and other files"]}),"\n",(0,i.jsxs)(n.li,{children:["Remove the archive files and run ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh 1_0_2"})," to create a ",(0,i.jsx)(n.code,{children:"config.toml"})," from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Release versions are invoked using the underscore format, such as:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-file",children:"The Node Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["One ",(0,i.jsx)(n.code,{children:"config.toml"})," file exists for each ",(0,i.jsx)(n.code,{children:"casper-node"})," version installed. It is located in the ",(0,i.jsx)(n.code,{children:"/etc/casper/[m_n_p]/"})," directory, where ",(0,i.jsx)(n.code,{children:"m_n_p"})," is the current semantic version. This can be created from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})," by using ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh [m_n_p]"})," where ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," is replaced with the current version, using underscores."]}),"\n",(0,i.jsxs)(n.p,{children:["Below are some fields in the ",(0,i.jsx)(n.code,{children:"config.toml"})," that you may need to adjust."]}),"\n",(0,i.jsx)(n.h3,{id:"trusted-hash-for-synchronizing",children:"The Trusted Hash for Synchronizing"}),"\n",(0,i.jsx)(n.p,{children:"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."}),"\n",(0,i.jsx)(n.p,{children:"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Find a list of trusted validators"}),"\n",(0,i.jsxs)(n.li,{children:["Query the status endpoint of a trusted validator (",(0,i.jsx)(n.code,{children:"http://<NODE_IP_ADDRESS>:8888/status"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Obtain the hash of a block from the status endpoint"}),"\n",(0,i.jsxs)(n.li,{children:["Update the ",(0,i.jsx)(n.code,{children:"config.toml"})," for the node to include the trusted hash. There is a field dedicated to this near the top of the file"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"known-addresses",children:"Known Addresses"}),"\n",(0,i.jsxs)(n.p,{children:["For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", these are listed in the ",(0,i.jsx)(n.code,{children:"config.toml"})," as ",(0,i.jsx)(n.code,{children:"known_addresses"}),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"example configuration"}),". The ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release",children:"casper-protocol-release"})," repository stores configurations for various environments, which you can also use as examples."]}),"\n",(0,i.jsxs)(n.h3,{id:"updating-config-file",children:["Updating the ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.p,{children:["At the top of a ",(0,i.jsx)(n.code,{children:"config.toml"})," file as shown here, enter the trusted block hash to replace the ",(0,i.jsx)(n.code,{children:"'HEX-FORMATTED BLOCK HASH'"})," and uncomment the line by deleting the leading '#'. See the ",(0,i.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"Configuration File"})," for more details."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secret-keys",children:"Secret Keys"}),"\n",(0,i.jsxs)(n.p,{children:["Provide the path to the secret keys for the node. This path is set to ",(0,i.jsx)(n.code,{children:"etc/casper/validator_keys/"})," by default. See ",(0,i.jsx)(n.a,{href:"#create-fund-keys",children:"Creating Keys and Funding Accounts"})," for more details."]}),"\n",(0,i.jsx)(n.h3,{id:"networking--gossiping",children:"Networking and Gossiping"}),"\n",(0,i.jsxs)(n.p,{children:["The node requires a publicly accessible IP address. The ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," and ",(0,i.jsx)(n.code,{children:"node_util.py"})," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," external services are called to find your IP and this is inserted into the ",(0,i.jsx)(n.code,{children:"config.toml"})," created."]}),"\n",(0,i.jsx)(n.p,{children:"The following default values are specified in the file if you want to change them:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The port that will be used for status and transactions"}),"\n",(0,i.jsx)(n.li,{children:"The port used for networking"}),"\n",(0,i.jsx)(n.li,{children:"Known_addresses - these are the bootstrap nodes (there is no need to change these)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"enabling-speculative-execution",children:"Enabling Speculative Execution"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a transaction without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the transaction in question. By default, ",(0,i.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"speculative_exec"})," can be enabled within ",(0,i.jsx)(n.em,{children:"config.toml"})," by changing ",(0,i.jsx)(n.code,{children:"enable_server"})," to ",(0,i.jsx)(n.code,{children:"true"})," under the configuration options for the speculative execution JSON-RPC HTTP server."]}),"\n",(0,i.jsxs)(n.p,{children:["Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,i.jsx)(n.code,{children:"7778"}),". Further, you can choose to alter the ",(0,i.jsx)(n.code,{children:"qps_limit"})," and ",(0,i.jsx)(n.code,{children:"max_body_bytes"}),", which limit the amount and size of requests to the speculative execution server."]}),"\n",(0,i.jsx)(n.h4,{id:"example-configtoml-configuration-with-speculative-execution-enabled",children:"Example Config.toml configuration with speculative execution enabled"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client-installation",children:"Rust Client Installation"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Prerequisites"})," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."]}),"\n",(0,i.jsx)(n.h2,{id:"create-fund-keys",children:"Creating Keys and Funding Accounts"}),"\n",(0,i.jsxs)(n.p,{children:["The following command will create keys in the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys"})," folder."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To learn about other options for generating keys, see ",(0,i.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," or run the Rust client ",(0,i.jsx)(n.code,{children:"keygen"})," command with the ",(0,i.jsx)(n.code,{children:"--help"})," option."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More about keys and key generation can also be found in ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/README.md"})," if the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," was installed from the Debian package."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Save your keys in a secure location, preferably offline."})}),"\n",(0,i.jsxs)(n.p,{children:["To submit a bonding request, you will need to ",(0,i.jsx)(n.a,{href:"/developers/prerequisites#fund-your-account",children:"fund your account"})," as well."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/99a13742.d3215e16.js b/assets/js/99a13742.d3215e16.js deleted file mode 100644 index 6ccccdcf8..000000000 --- a/assets/js/99a13742.d3215e16.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9895],{58591:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=s(74848),o=s(28453);const r={title:"Configuration"},t="Basic Node Configuration",c={id:"operators/setup/basic-node-configuration",title:"Configuration",description:"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.",source:"@site/docs/operators/setup/basic-node-configuration.md",sourceDirName:"operators/setup",slug:"/operators/setup/basic-node-configuration",permalink:"/next/operators/setup/basic-node-configuration",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Configuration"},sidebar:"operators",previous:{title:"Hardware",permalink:"/next/operators/setup/hardware"},next:{title:"Endpoints",permalink:"/next/operators/setup/node-endpoints"}},l={},d=[{value:"The Casper Node Launcher",id:"casper-node-launcher",level:2},{value:"File Locations",id:"file-locations",level:2},{value:"<code>/usr/bin/</code>",id:"usrbin",level:3},{value:"<code>/etc/casper/</code>",id:"etccasper",level:3},{value:"<code>/var/lib/casper/</code>",id:"varlibcasper",level:3},{value:"Node Version Installation",id:"node-version-installation",level:2},{value:"The Node Configuration File",id:"config-file",level:2},{value:"The Trusted Hash for Synchronizing",id:"trusted-hash-for-synchronizing",level:3},{value:"Known Addresses",id:"known-addresses",level:3},{value:"Updating the <code>config.toml</code> file",id:"updating-config-file",level:3},{value:"Secret Keys",id:"secret-keys",level:3},{value:"Networking and Gossiping",id:"networking--gossiping",level:3},{value:"Enabling Speculative Execution",id:"enabling-speculative-execution",level:3},{value:"Example Config.toml configuration with speculative execution enabled",id:"example-configtoml-configuration-with-speculative-execution-enabled",level:4},{value:"Rust Client Installation",id:"client-installation",level:2},{value:"Creating Keys and Funding Accounts",id:"create-fund-keys",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"basic-node-configuration",children:"Basic Node Configuration"})}),"\n",(0,i.jsxs)(n.p,{children:["This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the ",(0,i.jsx)(n.a,{href:"/next/operators/setup/install-node",children:"Node Setup"})," guide."]}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-launcher",children:"The Casper Node Launcher"}),"\n",(0,i.jsxs)(n.p,{children:["A node is usually run by executing the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),", which executes the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process and also handles upgrades to bring the node to the latest version released."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," can be installed via a Debian package, which also creates the ",(0,i.jsx)(n.code,{children:"casper"})," user and directory structures and sets up a ",(0,i.jsx)(n.code,{children:"systemd"})," unit and logging."]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian package can be obtained from ",(0,i.jsx)(n.a,{href:"https://repo.casperlabs.io",children:"https://repo.casperlabs.io"}),". You only need to run the steps detailed there once."]}),"\n",(0,i.jsxs)(n.p,{children:["Then, proceed to install the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," by running these commands:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo apt update\nsudo apt install casper-node-launcher\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You can also build ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"from source"}),". However, all the setup and pull of casper-node releases will be manual."]}),"\n",(0,i.jsx)(n.h2,{id:"file-locations",children:"File Locations"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian installation creates the directories and files needed to run ",(0,i.jsx)(n.code,{children:"casper-node"})," versions and perform upgrades. A ",(0,i.jsx)(n.code,{children:"casper"})," user and ",(0,i.jsx)(n.code,{children:"casper"})," group are created during installation and used to run the software. Two main folders are relevant for our software: ",(0,i.jsx)(n.code,{children:"/etc/casper"})," and ",(0,i.jsx)(n.code,{children:"/var/lib/casper"}),"."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"The casper-node install version"})}),"\n",(0,i.jsxs)(n.p,{children:["Each version of the ",(0,i.jsx)(n.code,{children:"casper-node"})," install is located based on the semantic version with underscores. For example, version 1.0.3 is represented by a directory named ",(0,i.jsx)(n.code,{children:"1_0_3"}),". This convention applies to both binary and configuration file locations. Versioning with ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," represents the major, minor, and patch of a semantic version."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Multiple versioned folders will exist on a system when upgrades are set up."})}),"\n",(0,i.jsxs)(n.p,{children:["The following is the filesystem's state after installing the ",(0,i.jsx)(n.code,{children:"casper-client"})," and ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," Debian packages, and after running the command ",(0,i.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf"})," (Use casper-test.conf if on Testnet)."]}),"\n",(0,i.jsx)(n.h3,{id:"usrbin",children:(0,i.jsx)(n.code,{children:"/usr/bin/"})}),"\n",(0,i.jsxs)(n.p,{children:["The default location for executables from the Debian package install is ",(0,i.jsx)(n.code,{children:"/usr/bin"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-client"})," - A client for interacting with a Casper network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher"})," - The launcher application which starts the ",(0,i.jsx)(n.code,{children:"casper-node"})," as a child process"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"etccasper",children:(0,i.jsx)(n.code,{children:"/etc/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the default location for configuration files. It can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_CONFIG_DIR"})," environment variable. The paths in this document assume the default configuration file location of ",(0,i.jsx)(n.code,{children:"/etc/casper"}),". The data is organized as follows:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"delete_local_db.sh"})," - Removes ",(0,i.jsx)(n.code,{children:"*.lmdb*"})," files from ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"})," - Pulls ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," from ",(0,i.jsx)(n.a,{href:"https://genesis.casperlabs.io/",children:"genesis.casperlabs.io"})," for a specified protocol version and extracts them into ",(0,i.jsx)(n.code,{children:"/var/lib/bin/<protocol_version>"})," and ",(0,i.jsx)(n.code,{children:"/etc/casper/<protocol_version>"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config_from_example.sh"})," - Gets external IP to replace and create the ",(0,i.jsx)(n.code,{children:"config.toml"})," from ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node_util.py"})," - A script that will be replacing other scripts and is the preferred method of performing the actions of ",(0,i.jsx)(n.code,{children:"pull_casper_node_version.sh"}),", ",(0,i.jsx)(n.code,{children:"config_from_example.sh"}),", and ",(0,i.jsx)(n.code,{children:"delete_local_db.sh"}),". Other scripts will be deprecated in future releases of ",(0,i.jsx)(n.code,{children:"casper-node-launcher"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node-launcher-state.toml"})," - The local state for the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," which is created during the first run"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_keys/"})," - The default folder for node keys, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Instructions on how to create validator keys using the ",(0,i.jsx)(n.code,{children:"casper-client"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret_key.pem"})," - Secret key used by the validator node to sign blocks and peer-to-peer messages"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key.pem"})," - Public key associated with the secret key above, stored in PEM format"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"public_key_hex"})," - Public key associated with the secret key above, stored in hex format"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"accounts.toml"})," - Contains the genesis validators and delegators"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," (network start time) as a timestamp"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - Example for creating a ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - Contains variable node configuration settings, created by a node operator manually or by running ",(0,i.jsx)(n.code,{children:"config_from_example.sh 1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package's configuration files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chainspec.toml"})," - Contains invariant network settings, with the ",(0,i.jsx)(n.code,{children:"activation_point"})," as an era ID (the era at which this protocol version of the node became or will become active)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config-example.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config-example.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.toml"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/config.toml"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"varlibcasper",children:(0,i.jsx)(n.code,{children:"/var/lib/casper/"})}),"\n",(0,i.jsxs)(n.p,{children:["This is the location for larger and variable data for the ",(0,i.jsx)(n.code,{children:"casper-node"}),", organized in the following folders and files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bin/"})," - The parent folder storing the versions of ",(0,i.jsx)(n.code,{children:"casper-node"})," executables. This location can be overwritten with the ",(0,i.jsx)(n.code,{children:"CASPER_BIN_DIR"})," environment variable. The paths in this document assume the default of ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0/"})," - Folder for genesis binary files, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - The node executable - defaults to the Ubuntu 20.04 compatible binary"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - Information about the repository location and the Git hash used for compilation to allow a rebuild on other platforms"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"m_n_p/"})," - Folder for each installed upgrade package, containing:\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper-node"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/casper-node"}),", but the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"README.md"})," - As per ",(0,i.jsx)(n.code,{children:"1_0_0/README.md"}),", but compatible with the ",(0,i.jsx)(n.code,{children:"m.n.p"})," version of the node"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"casper-node/<NETWORK NAME>"})," - Folder containing databases and related files produced by the node binary. For Mainnet, the network name is ",(0,i.jsx)(n.code,{children:"casper"})," and for Testnet it is ",(0,i.jsx)(n.code,{children:"casper-test"}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmdb"})," - Persistent global state store of the network"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"data.lmbd-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"data.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb"})," - Persistent store of all other network data, primarily Blocks and transactions"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"storage.lmdb-lock"})," - Lockfile for the ",(0,i.jsx)(n.code,{children:"storage.lmdb"})," database"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"unit_files/"})," - Folder containing transient caches of consensus information"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"node-version-installation",children:"Node Version Installation"}),"\n",(0,i.jsxs)(n.p,{children:["Included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is ",(0,i.jsx)(n.code,{children:"node_util.py"})," for installing ",(0,i.jsx)(n.code,{children:"casper-node"})," versions. This command will stage all current ",(0,i.jsx)(n.code,{children:"casper-node"})," versions:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <NETWORK_CONFIG>\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.code,{children:"<NETWORK_CONFIG>"}),", we use ",(0,i.jsx)(n.code,{children:"casper.conf"})," for Mainnet and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," for Testnet. This will install all currently released protocols in one step."]}),"\n",(0,i.jsx)(n.p,{children:"This command will do the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," containing at a minimum ",(0,i.jsx)(n.code,{children:"casper-node"})]}),"\n",(0,i.jsxs)(n.li,{children:["Create ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_2/"})," and expand the ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," containing ",(0,i.jsx)(n.code,{children:"chainspec.toml"}),", ",(0,i.jsx)(n.code,{children:"config-example.toml"}),", and possibly ",(0,i.jsx)(n.code,{children:"accounts.csv"})," and other files"]}),"\n",(0,i.jsxs)(n.li,{children:["Remove the archive files and run ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh 1_0_2"})," to create a ",(0,i.jsx)(n.code,{children:"config.toml"})," from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Release versions are invoked using the underscore format, such as:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/pull_casper_node_version.sh 1_0_2\n"})}),"\n",(0,i.jsx)(n.h2,{id:"config-file",children:"The Node Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["One ",(0,i.jsx)(n.code,{children:"config.toml"})," file exists for each ",(0,i.jsx)(n.code,{children:"casper-node"})," version installed. It is located in the ",(0,i.jsx)(n.code,{children:"/etc/casper/[m_n_p]/"})," directory, where ",(0,i.jsx)(n.code,{children:"m_n_p"})," is the current semantic version. This can be created from the ",(0,i.jsx)(n.code,{children:"config-example.toml"})," by using ",(0,i.jsx)(n.code,{children:"/etc/casper/config_from_example.sh [m_n_p]"})," where ",(0,i.jsx)(n.code,{children:"[m_n_p]"})," is replaced with the current version, using underscores."]}),"\n",(0,i.jsxs)(n.p,{children:["Below are some fields in the ",(0,i.jsx)(n.code,{children:"config.toml"})," that you may need to adjust."]}),"\n",(0,i.jsx)(n.h3,{id:"trusted-hash-for-synchronizing",children:"The Trusted Hash for Synchronizing"}),"\n",(0,i.jsx)(n.p,{children:"Each Casper network is a permissionless, Proof-of-Stake network, implying that nodes can join and leave the network. As a result, some nodes may not be synchronized or as secure as bonded validators. Ideally, all nodes will join the network using a trusted source, such as a bonded validator."}),"\n",(0,i.jsx)(n.p,{children:"When joining the network, the system will start from the hash of a recent block and then work backward to obtain the finalized blocks from the linear block store. Here is the process to get the trusted hash of a bonded validator:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Find a list of trusted validators"}),"\n",(0,i.jsxs)(n.li,{children:["Query the status endpoint of a trusted validator (",(0,i.jsx)(n.code,{children:"http://<NODE_IP_ADDRESS>:8888/status"}),")"]}),"\n",(0,i.jsx)(n.li,{children:"Obtain the hash of a block from the status endpoint"}),"\n",(0,i.jsxs)(n.li,{children:["Update the ",(0,i.jsx)(n.code,{children:"config.toml"})," for the node to include the trusted hash. There is a field dedicated to this near the top of the file"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Here is an example command for obtaining a trusted hash. Replace the node address with an updated address from a node on the network."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo sed -i \"/trusted_hash =/c\\trusted_hash = '$(casper-client get-block --node-address http://3.14.161.135:7777 -b 20 | jq -r .result.block.hash | tr -d '\\n')'\" /etc/casper/1_0_0/config.toml\n"})}),"\n",(0,i.jsx)(n.h3,{id:"known-addresses",children:"Known Addresses"}),"\n",(0,i.jsxs)(n.p,{children:["For the node to connect to a network, the node needs a set of trusted peers for that network. For ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", these are listed in the ",(0,i.jsx)(n.code,{children:"config.toml"})," as ",(0,i.jsx)(n.code,{children:"known_addresses"}),". For other networks, locate and update the list to include at least two trusted IP addresses for peers in that network. Here is an ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"example configuration"}),". The ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release",children:"casper-protocol-release"})," repository stores configurations for various environments, which you can also use as examples."]}),"\n",(0,i.jsxs)(n.h3,{id:"updating-config-file",children:["Updating the ",(0,i.jsx)(n.code,{children:"config.toml"})," file"]}),"\n",(0,i.jsxs)(n.p,{children:["At the top of a ",(0,i.jsx)(n.code,{children:"config.toml"})," file as shown here, enter the trusted block hash to replace the ",(0,i.jsx)(n.code,{children:"'HEX-FORMATTED BLOCK HASH'"})," and uncomment the line by deleting the leading '#'. See the ",(0,i.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#config-file",children:"Configuration File"})," for more details."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ================================\n# Configuration options for a node\n# ================================\n[node]\n\n# If set, use this hash as a trust anchor when joining an existing network.\n#trusted_hash = 'HEX-FORMATTED BLOCK HASH'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"secret-keys",children:"Secret Keys"}),"\n",(0,i.jsxs)(n.p,{children:["Provide the path to the secret keys for the node. This path is set to ",(0,i.jsx)(n.code,{children:"etc/casper/validator_keys/"})," by default. See ",(0,i.jsx)(n.a,{href:"#create-fund-keys",children:"Creating Keys and Funding Accounts"})," for more details."]}),"\n",(0,i.jsx)(n.h3,{id:"networking--gossiping",children:"Networking and Gossiping"}),"\n",(0,i.jsxs)(n.p,{children:["The node requires a publicly accessible IP address. The ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," and ",(0,i.jsx)(n.code,{children:"node_util.py"})," both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the ",(0,i.jsx)(n.code,{children:"config_from_example.sh"})," external services are called to find your IP and this is inserted into the ",(0,i.jsx)(n.code,{children:"config.toml"})," created."]}),"\n",(0,i.jsx)(n.p,{children:"The following default values are specified in the file if you want to change them:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"The port that will be used for status and transactions"}),"\n",(0,i.jsx)(n.li,{children:"The port used for networking"}),"\n",(0,i.jsx)(n.li,{children:"Known_addresses - these are the bootstrap nodes (there is no need to change these)"}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"enabling-speculative-execution",children:"Enabling Speculative Execution"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"speculative_exec"})," endpoint provides a method to execute a transaction without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the transaction in question. By default, ",(0,i.jsx)(n.code,{children:"speculative_exec"})," is disabled on a node."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"speculative_exec"})," can be enabled within ",(0,i.jsx)(n.em,{children:"config.toml"})," by changing ",(0,i.jsx)(n.code,{children:"enable_server"})," to ",(0,i.jsx)(n.code,{children:"true"})," under the configuration options for the speculative execution JSON-RPC HTTP server."]}),"\n",(0,i.jsxs)(n.p,{children:["Node operators may also change the incoming request port for speculative execution, which defaults to ",(0,i.jsx)(n.code,{children:"7778"}),". Further, you can choose to alter the ",(0,i.jsx)(n.code,{children:"qps_limit"})," and ",(0,i.jsx)(n.code,{children:"max_body_bytes"}),", which limit the amount and size of requests to the speculative execution server."]}),"\n",(0,i.jsx)(n.h4,{id:"example-configtoml-configuration-with-speculative-execution-enabled",children:"Example Config.toml configuration with speculative execution enabled"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"# ========================================================================\n# Configuration options for the speculative execution JSON-RPC HTTP server\n# ========================================================================\n[speculative_exec_server]\n\n# Flag which enables the speculative execution JSON-RPC HTTP server.\nenable_server = true\n\n# Listening address for speculative execution JSON-RPC HTTP server. If the port\n# is set to 0, a random port will be used.\n#\n# If the specified port cannot be bound to, a random port will be tried instead.\n# If binding fails, the speculative execution JSON-RPC HTTP server will not run,\n# but the node will be otherwise unaffected.\n#\n# The actual bound address will be reported via a log line if logging is enabled.\naddress = '0.0.0.0:7778'\n\n# The global max rate of requests (per second) before they are limited.\n# Request will be delayed to the next 1 second bucket once limited.\nqps_limit = 1\n\n# Maximum number of bytes to accept in a single request body.\nmax_body_bytes = 2_621_440\n\n# Specifies which origin will be reported as allowed by speculative execution server.\n#\n# If left empty, CORS will be disabled.\n# If set to '*', any origin is allowed.\n# Otherwise, only a specified origin is allowed. The given string must conform to the [origin scheme](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).\ncors_origin = ''\n\n"})}),"\n",(0,i.jsx)(n.h2,{id:"client-installation",children:"Rust Client Installation"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Prerequisites"})," page lists installation instructions for the Casper client, which is useful for generating keys and retrieving information from the network."]}),"\n",(0,i.jsx)(n.h2,{id:"create-fund-keys",children:"Creating Keys and Funding Accounts"}),"\n",(0,i.jsxs)(n.p,{children:["The following command will create keys in the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys"})," folder."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen /etc/casper/validator_keys\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To learn about other options for generating keys, see ",(0,i.jsx)(n.a,{href:"/next/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," or run the Rust client ",(0,i.jsx)(n.code,{children:"keygen"})," command with the ",(0,i.jsx)(n.code,{children:"--help"})," option."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client keygen --help\n"})}),"\n",(0,i.jsxs)(n.p,{children:["More about keys and key generation can also be found in ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/README.md"})," if the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," was installed from the Debian package."]}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"Save your keys in a secure location, preferably offline."})}),"\n",(0,i.jsxs)(n.p,{children:["To submit a bonding request, you will need to ",(0,i.jsx)(n.a,{href:"/next/developers/prerequisites#fund-your-account",children:"fund your account"})," as well."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>t,x:()=>c});var i=s(96540);const o={},r=i.createContext(o);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9a38f23f.5bb7b4cd.js b/assets/js/9a38f23f.5bb7b4cd.js new file mode 100644 index 000000000..9a1b2ce22 --- /dev/null +++ b/assets/js/9a38f23f.5bb7b4cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[44771],{5132:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var n=i(74848),a=i(28453);const s={id:"disclaimer",title:"Disclaimer"},r="Disclaimer {#disclaimer}",o={id:"disclaimer",title:"Disclaimer",description:"disclaimer}",source:"@site/versioned_docs/version-2.0.0/disclaimer.md",sourceDirName:".",slug:"/disclaimer",permalink:"/2.0.0/disclaimer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{id:"disclaimer",title:"Disclaimer"}},c={},h=[{value:"Preliminary Nature of this Whitepaper",id:"preliminary-nature-of-this-whitepaper",level:4},{value:"Forward-Looking Statements",id:"forward-looking-statements",level:4},{value:"Risk Factors",id:"risk-factors",level:4}];function d(e){const t={h1:"h1",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"disclaimer",children:"Disclaimer"})}),"\n",(0,n.jsx)(t.p,{children:'By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR\u201d). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO\u201d) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA\u201d) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA\u201d) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.'}),"\n",(0,n.jsx)(t.p,{children:'The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC\u201d). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.'}),"\n",(0,n.jsx)(t.p,{children:"The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required."}),"\n",(0,n.jsx)(t.p,{children:"No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient\u2019s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature."}),"\n",(0,n.jsx)(t.h4,{id:"preliminary-nature-of-this-whitepaper",children:"Preliminary Nature of this Whitepaper"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA\u201d). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.'}),"\n",(0,n.jsx)(t.h4,{id:"forward-looking-statements",children:"Forward-Looking Statements"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper includes "forward-looking statements\u201d, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe\u201d, "anticipate\u201d, "expect\u201d, "project\u201d, "estimate\u201d, "predict\u201d, "intend\u201d, "target\u201d, "assume\u201d, "may\u201d, "might\u201d, "could\u201d, "should\u201d, "will\u201d and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 present and future expectations regarding the development of the Casper blockchain and the associated software.'}),"\n",(0,n.jsx)(t.p,{children:"These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based."}),"\n",(0,n.jsx)(t.h4,{id:"risk-factors",children:"Risk Factors"}),"\n",(0,n.jsx)(t.p,{children:'Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient\u201d) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.'}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CasperLabs Networks AG\u2019s experience"}),": the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CSPR relative value"}),": the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with (intellectual) property rights"}),": the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with blockchain"}),": the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risk of weaknesses in the field of cryptography"}),": the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Regulatory risks"}),": the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with abandonment / lack of success"}),": the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a loss of private key"}),": the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient\u2019s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient\u2019s account (address) will be unrecoverable and will be permanently lost."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with wallets"}),": the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with theft/hacks"}),": the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with mining attacks"}),": the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a lack of consensus"}),": the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with liquidity of CSPR"}),": the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with forking"}),": the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient\u2019s CSPR (if and when created and/or issued)."]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>o});var n=i(96540);const a={},s=n.createContext(a);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9a508619.234da57e.js b/assets/js/9a508619.234da57e.js new file mode 100644 index 000000000..3179a3c60 --- /dev/null +++ b/assets/js/9a508619.234da57e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95882],{63629:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={},o="Casper Node Networking Protocol",d={id:"concepts/design/networking-protocol",title:"Casper Node Networking Protocol",description:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",source:"@site/versioned_docs/version-2.0.0/concepts/design/networking-protocol.md",sourceDirName:"concepts/design",slug:"/concepts/design/networking-protocol",permalink:"/2.0.0/concepts/design/networking-protocol",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{}},a={},c=[{value:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",id:"casper-node-networking-protocol-mainnet-protocol-version-150",level:2},{value:"Connection Level",id:"connection-level",level:2},{value:"Reciprocity, retries and data direction",id:"reciprocity-retries-and-data-direction",level:3},{value:"TLS parameters",id:"tls-parameters",level:3},{value:"Discovery",id:"discovery",level:3},{value:"Framing",id:"framing",level:2},{value:"Encoding",id:"encoding",level:2},{value:"The <code>Message</code> Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The <code>Payload</code> Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"casper-node-networking-protocol",children:"Casper Node Networking Protocol"})}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-networking-protocol-mainnet-protocol-version-150",children:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of the ",(0,i.jsx)(n.code,{children:"casper-node"}),"'s networking protocol. This document follows the conventions laid out in ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"connection-level",children:"Connection Level"}),"\n",(0,i.jsxs)(n.p,{children:["Any ",(0,i.jsx)(n.code,{children:"casper-node"})," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."]}),"\n",(0,i.jsx)(n.h3,{id:"reciprocity-retries-and-data-direction",children:"Reciprocity, retries and data direction"}),"\n",(0,i.jsxs)(n.p,{children:["A connection that was initiated by a node is considered an ",(0,i.jsx)(n.em,{children:"outgoing"})," connection by the node itself, but an ",(0,i.jsx)(n.em,{children:"incoming"})," connection by all other peers."]}),"\n",(0,i.jsx)(n.p,{children:"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."}),"\n",(0,i.jsx)(n.p,{children:"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."}),"\n",(0,i.jsx)(n.p,{children:"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."}),"\n",(0,i.jsx)(n.p,{children:"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."}),"\n",(0,i.jsx)(n.h3,{id:"tls-parameters",children:"TLS parameters"}),"\n",(0,i.jsx)(n.p,{children:"Any node creating a connection to a node MUST present a client certificate with the following properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Signature algorithm: ",(0,i.jsx)(n.code,{children:"ECDSA_WITH_SHA512"})]}),"\n",(0,i.jsx)(n.li,{children:"Subject name: Same as issuer name (self-signed certificate!)"}),"\n",(0,i.jsx)(n.li,{children:"Serial number: 1"}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not before"): Must be earlier than current time.'}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not after"): Must be later than current time.'}),"\n",(0,i.jsxs)(n.li,{children:["Signature: Must be using ",(0,i.jsx)(n.code,{children:"SECP521R1"})," with ",(0,i.jsx)(n.code,{children:"SHA512"})," and valid."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The SHA512 fingerprint of the ",(0,i.jsx)(n.em,{children:"public key"})," is considered the ",(0,i.jsx)(n.strong,{children:"NodeID"})," of the node."]}),"\n",(0,i.jsx)(n.p,{children:"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."}),"\n",(0,i.jsx)(n.p,{children:"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."}),"\n",(0,i.jsx)(n.h3,{id:"discovery",children:"Discovery"}),"\n",(0,i.jsx)(n.p,{children:"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."}),"\n",(0,i.jsxs)(n.p,{children:["Every node SHOULD have one or more so-called ",(0,i.jsx)(n.em,{children:"known node addresses"})," of other nodes configured."]}),"\n",(0,i.jsx)(n.p,{children:"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."}),"\n",(0,i.jsx)(n.p,{children:"Every node MUST periodically gossip its own node address to the network (see gossiping below)."}),"\n",(0,i.jsxs)(n.p,{children:["A node ",(0,i.jsx)(n.em,{children:"learns"})," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."]}),"\n",(0,i.jsx)(n.p,{children:"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."}),"\n",(0,i.jsxs)(n.p,{children:["After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,i.jsx)(n.em,{children:"forgetting"})," a node. An address that has been forgotten will be considered new the next time it is learned."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT forget the known addresses it was configured with initially."}),"\n",(0,i.jsx)(n.h2,{id:"framing",children:"Framing"}),"\n",(0,i.jsx)(n.p,{children:"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."}),"\n",(0,i.jsx)(n.p,{children:"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."}),"\n",(0,i.jsx)(n.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsxs)(n.p,{children:["The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,i.jsx)(n.a,{href:"https://msgpack.org",children:"MessagePack"}),", while regular messages are encoded using ",(0,i.jsx)(n.a,{href:"https://docs.rs/bincode",children:"bincode"}),". Many (but not all) data objects use ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html",children:(0,i.jsx)(n.code,{children:"bytesrepr"})})," for serialization."]}),"\n",(0,i.jsxs)(n.p,{children:["The node uses the ",(0,i.jsx)(n.a,{href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html",children:(0,i.jsx)(n.code,{children:"rmp-serde"})})," crate, version ",(0,i.jsx)(n.code,{children:"0.14.4"}),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."]}),"\n",(0,i.jsxs)(n.p,{children:["All nodes MUST use the following settings for ",(0,i.jsx)(n.code,{children:"bincode"})," encoding of network messages:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Varint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Not allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Any other use of ",(0,i.jsx)(n.code,{children:"bincode"})," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,i.jsx)(n.code,{children:"bincode"})," encoding settings:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Fixint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,i.jsx)(n.a,{href:"https://serde.rs",children:(0,i.jsx)(n.code,{children:"serde"})}),"-derived encoding. For ",(0,i.jsx)(n.code,{children:"bytesrepr"})," serialization refer to the specific implementations in the ",(0,i.jsx)(n.code,{children:"bytesrepr"})," crate."]}),"\n",(0,i.jsxs)(n.p,{children:["Any data types given from here on out are described using simplified ",(0,i.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," structure definitions."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-message-type",children:["The ",(0,i.jsx)(n.code,{children:"Message"})," Type"]}),"\n",(0,i.jsx)(n.p,{children:"The following data types make up the networking protocol:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option<ConsensusCertificate>,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option<Digest>,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/string/struct.String.html",children:(0,i.jsx)(n.code,{children:"String"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html",children:(0,i.jsx)(n.code,{children:"SocketAddr"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html",children:(0,i.jsx)(n.code,{children:"ProtocolVersion"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/option/enum.Option.html",children:(0,i.jsx)(n.code,{children:"Option"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html",children:(0,i.jsx)(n.code,{children:"Signature"})})," see the respective docs and details below."]}),"\n",(0,i.jsx)(n.h2,{id:"handshake-behavior",children:"Handshake Behavior"}),"\n",(0,i.jsx)(n.p,{children:"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."}),"\n",(0,i.jsxs)(n.p,{children:["A handshake MUST be encoded using the ",(0,i.jsx)(n.code,{children:"Message::Handshake"})," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,i.jsx)(n.code,{children:"protocol_version"}),", ",(0,i.jsx)(n.code,{children:"consensus_certificate"}),", ",(0,i.jsx)(n.code,{children:"is_syncing"}),", ",(0,i.jsx)(n.code,{children:"chainspec_hash"}),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."]}),"\n",(0,i.jsxs)(n.p,{children:["After receiving a handshake, a node MUST compare the ",(0,i.jsx)(n.code,{children:"network_name"}),", ",(0,i.jsx)(n.code,{children:"protocol_version"})," and ",(0,i.jsx)(n.code,{children:"chainspec_hash"})," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,i.jsx)(n.code,{children:"is_syncing"})," set to ",(0,i.jsx)(n.code,{children:"true"}),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.']}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY compare peers that provide a ",(0,i.jsx)(n.code,{children:"consensus_certificate"})," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon handshake completion, the node SHOULD learn the provided ",(0,i.jsx)(n.code,{children:"public_addr"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blocking-nodes",children:"Blocking Nodes"}),"\n",(0,i.jsx)(n.p,{children:"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."}),"\n",(0,i.jsxs)(n.p,{children:["After a block on a node is expired, the node SHOULD ",(0,i.jsx)(n.em,{children:"forget"})," the nodes IP address, allowing a later ",(0,i.jsx)(n.em,{children:"learning"})," of said address again."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-payload-type",children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," Type"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," (found in the node sources as ",(0,i.jsx)(n.code,{children:"Message"})," in ",(0,i.jsx)(n.code,{children:"payload.rs"}),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,i.jsx)(n.code,{children:"bincode"})," encoding, this should have no effect on implementations."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec<u8>,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:"Consensus"}),"\n",(0,i.jsxs)(n.p,{children:["A ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/design/consensus",children:"consensus"})," message is sent exclusively between instances of the consensus component, from one peer to another."]}),"\n",(0,i.jsx)(n.h3,{id:"gossiping",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."}),"\n",(0,i.jsxs)(n.p,{children:["A node must support a gossiper for deploys and one for ",(0,i.jsx)(n.code,{children:"GossippedAddress"}),", which is an alias for the regular Rust standard library's ",(0,i.jsx)(n.code,{children:"SocketAddr"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,i.jsx)(n.code,{children:"AddressGossiperMessage::Gossip"})," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."]}),"\n",(0,i.jsx)(n.h3,{id:"unsafe-for-syncing",children:"Unsafe-for-syncing"}),"\n",(0,i.jsxs)(n.p,{children:["A node that is syncing MUST indicate this by setting ",(0,i.jsx)(n.code,{children:"is_syncing"})," to ",(0,i.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s that can cause issues with peers that are also sending GetRequests."]}),"\n",(0,i.jsxs)(n.p,{children:["A node that succeeds in a handshake with a peer that has set ",(0,i.jsx)(n.code,{children:"is_syncing"})," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s."]}),"\n",(0,i.jsx)(n.h2,{id:"gossiping-1",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."}),"\n",(0,i.jsx)(n.p,{children:"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."}),"\n",(0,i.jsx)(n.p,{children:"Gossiper messages have the following structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To gossip, a node MAY send a ",(0,i.jsx)(n.code,{children:"GossiperMessage::Gossip"})," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,i.jsx)(n.code,{children:"GossiperMessage:GossipResponse"}),", citing the given id and using ",(0,i.jsx)(n.code,{children:"is_already_held"})," to indicate whether it already possessed the given item."]}),"\n",(0,i.jsx)(n.p,{children:"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."}),"\n",(0,i.jsxs)(n.p,{children:["The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"true"}),") response and MUST NOT send another ",(0,i.jsx)(n.code,{children:"Gossip"})," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."]}),"\n",(0,i.jsxs)(n.p,{children:["If a node receives a negative ",(0,i.jsx)(n.code,{children:"GossiperMessage::GossipResponse"})," (i.e. ",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"false"}),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,i.jsx)(n.code,{children:"GetRequest"})," for the item (see GetRequests section below)."]}),"\n",(0,i.jsx)(n.h2,{id:"getrequests",children:"GetRequests"}),"\n",(0,i.jsx)(n.p,{children:'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'}),"\n",(0,i.jsxs)(n.p,{children:["A peer MAY send a ",(0,i.jsx)(n.code,{children:"GetRequest"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetRequest"}),") with a ",(0,i.jsx)(n.code,{children:"Tag"})," and ",(0,i.jsx)(n.code,{children:"serialized_id"})," payload. Both ",(0,i.jsx)(n.code,{children:"serialized_id"})," and ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST be encoded using ",(0,i.jsx)(n.code,{children:"bincode"}),' (see "Encoding" section for details).']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"The tag dictates which item is being retrieved, and which key (ID type) is being used."}),"\n",(0,i.jsxs)(n.p,{children:["A node that receives a ",(0,i.jsx)(n.code,{children:"GetRequest"})," from a peer SHOULD return a ",(0,i.jsx)(n.code,{children:"GetResponse"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetResponse"}),"). The ",(0,i.jsx)(n.code,{children:"GetResponse"})," MUST use the same ",(0,i.jsx)(n.code,{children:"Tag"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum FetchedOrNotFound<T, Id> {\n Fetched(T),\n NotFound(Id),\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the item was found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a serialized ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::Fetched"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"T"})," being the item."]}),"\n",(0,i.jsxs)(n.p,{children:["If the item was not found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::NotFound"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"Id"})," being the ID found in the originating ",(0,i.jsx)(n.code,{children:"GetRequest"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST not send any items to a peer that it itself has not verified."}),"\n",(0,i.jsxs)(n.p,{children:["The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,i.jsx)(n.code,{children:"DeployHash"})," and ",(0,i.jsx)(n.code,{children:"GossippedAddress"})," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization Standard"}),", but be aware that those docs describe serializing using bytesrepr rather than bincode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Tag"}),(0,i.jsx)(n.th,{children:"ID type"}),(0,i.jsx)(n.th,{children:"Payload (item) type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Deploy"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Deploy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalizedApprovals"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"FinalizedApprovalsWithId"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Block"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Block"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"GossipedAddress"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndMetadataByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeader"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderAndFinalitySignaturesByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeaderWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TrieOrChunk"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunkId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunk"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndDeploysByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockAndDeploys"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderBatch"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatch"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalitySignaturesByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockSignatures"})})]})]})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet<Approval>,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec<DeployHash>,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec<u8>,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec<NamedArg>);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec<u8>);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box<CLType>),\n List(Box<CLType>),\n ByteArray(u32),\n Result { ok: Box<CLType>, err: Box<CLType> },\n Map { key: Box<CLType>, value: Box<CLType> },\n Tuple1([Box<CLType>; 1]),\n Tuple2([Box<CLType>; 2]),\n Tuple3([Box<CLType>; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet<Approval>);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option<EraEnd>,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap<PublicKey, U512>,\n}\n\nstruct EraReport<VID> {\n equivocators: Vec<PublicKey>,\n rewards: BTreeMap<PublicKey, u64>,\n inactive_validators: Vec<PublicKey>,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec<DeployHash>,\n transfer_hashes: Vec<DeployHash>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Custom variable length encoding is used when serializing ",(0,i.jsx)(n.code,{children:"U512"}),", ",(0,i.jsx)(n.code,{children:"U256"})," and ",(0,i.jsx)(n.code,{children:"U128"})," types. They are encoded in a way equivalent to encoding the following pseudo struct:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"In other words, the following steps are taken:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"convert the bigint to an array of bytes in little-endian form"}),"\n",(0,i.jsxs)(n.li,{children:["strip the contiguous range of irrelevant padding ",(0,i.jsx)(n.code,{children:"0"})," bytes from the right hand end, if any"]}),"\n",(0,i.jsx)(n.li,{children:"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For a description explaining the use of ",(0,i.jsx)(n.code,{children:"TrieOrChunk"}),' and related types, see the "Trie chunking" section. The relevant types are:']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec<Digest>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})," is used to request multiple ",(0,i.jsx)(n.code,{children:"BlockHeader"}),"s with a single request."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap<PublicKey, Signature>,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec<Deploy>,\n}\n\nstruct BlockHeadersBatch(Vec<BlockHeader>);\n"})}),"\n",(0,i.jsx)(n.h2,{id:"finality-signatures",children:"Finality Signatures"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload::FinalitySignature"})," variant is used when broadcasting finality signatures."]}),"\n",(0,i.jsx)(n.p,{children:"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."}),"\n",(0,i.jsx)(n.h2,{id:"trie-chunking",children:"Trie Chunking"}),"\n",(0,i.jsxs)(n.p,{children:["Large trie nodes are split when transferred across the network, according to ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"}),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,i.jsx)(n.code,{children:"TrieOrChunk::Trie"})," instance."]}),"\n",(0,i.jsxs)(n.p,{children:["Should a trie node be larger than this, a Merkle tree is constructed with ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"})," sized chunks and is identified by the root hash of the resulting tree instead."]}),"\n",(0,i.jsxs)(n.p,{children:["Peers MUST only request chunks. The ",(0,i.jsx)(n.code,{children:"TrieOrChunkId"})," type allows for requesting the n-th chunk of a given trie node. See the ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-hashing",children:"casper-hashing"})," crate for details."]}),"\n",(0,i.jsxs)(n.p,{children:["A node receiving a ",(0,i.jsx)(n.code,{children:"TrieOrChunk"})," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9acc619b.a5bfebce.js b/assets/js/9acc619b.a5bfebce.js deleted file mode 100644 index 9e31a598a..000000000 --- a/assets/js/9acc619b.a5bfebce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5465],{31662:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=s(74848),t=s(28453);const a={title:"Archive and Restore a DB"},o="Archiving and Restoring a Database",i={id:"operators/maintenance/archiving-and-restoring",title:"Archive and Restore a DB",description:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/archiving-and-restoring.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/archiving-and-restoring",permalink:"/operators/maintenance/archiving-and-restoring",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Archive and Restore a DB"},sidebar:"operators",previous:{title:"Node Maintenance",permalink:"/operators/maintenance/"},next:{title:"Move a Node",permalink:"/operators/maintenance/moving-node"}},d={},c=[{value:"Zstandard Limitations",id:"zstandard-limitations",level:2},{value:"Zstandard Installation",id:"zstandard-installation",level:2},{value:"Initial Warnings",id:"initial-warnings",level:2},{value:"Compression",id:"compression",level:2},{value:"Compression level",id:"compression-level",level:3},{value:"Thread count",id:"thread-count",level:3},{value:"Long-distance matching",id:"long-distance-matching",level:3},{value:"Summary of commands",id:"summary-of-commands",level:3},{value:"Decompression",id:"decompression",level:2},{value:"Streamed Decompression",id:"streamed-decompression",level:2},{value:"Starting a New Node with a Decompressed DB",id:"starting-a-new-node-with-a-decompressed-db",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"archiving-and-restoring-a-database",children:"Archiving and Restoring a Database"})}),"\n",(0,r.jsx)(n.p,{children:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"http://facebook.github.io/zstd/",children:"Zstandard"})," is the best method for compression speed and space for the current LMDB-based database system that the ",(0,r.jsx)(n.code,{children:"casper-node"})," uses."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The values presented in this document assume that the ",(0,r.jsx)(n.code,{children:"trie-compact"})," tool was run on a Mainnet database for compression. Contact the ",(0,r.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb",children:"support team"})," if you have questions."]})}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-limitations",children:"Zstandard Limitations"}),"\n",(0,r.jsxs)(n.p,{children:["The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use ",(0,r.jsx)(n.code,{children:"tar"})," as a pre-filter for stripping sparse data, as shown ",(0,r.jsx)(n.a,{href:"#compression",children:"here"}),", thus eliminating the need to read the full DB size and improving processing."]}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-installation",children:"Zstandard Installation"}),"\n",(0,r.jsx)(n.p,{children:"To install Zstandard, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo apt install zstd\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation."}),"\n",(0,r.jsx)(n.h2,{id:"initial-warnings",children:"Initial Warnings"}),"\n",(0,r.jsxs)(n.p,{children:["You need to stop the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," process of the node (and, therefore, the ",(0,r.jsx)(n.code,{children:"casper-node"})," process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur."]}),"\n",(0,r.jsx)(n.h2,{id:"compression",children:"Compression"}),"\n",(0,r.jsxs)(n.p,{children:["Run the following basic ",(0,r.jsx)(n.code,{children:"tar"})," command from the DB directory. For Mainnet, the directory would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper"}),", and for Testnet it would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper-test"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -cv --sparse .\n"})}),"\n",(0,r.jsx)(n.p,{children:"On some systems, you may get better performance if you specify the block number as an argument:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse .\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then stream the result into ",(0,r.jsx)(n.code,{children:"zstd"}),". The sections below discuss the ",(0,r.jsx)(n.a,{href:"#compression-level",children:"level"}),", ",(0,r.jsx)(n.a,{href:"#thread-count",children:"thread count"}),", and ",(0,r.jsx)(n.a,{href:"#long-distance-matching",children:"long"})," arguments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compression-level",children:"Compression level"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-[level]"})," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."]}),"\n",(0,r.jsx)(n.p,{children:"Here are some examples of a Mainnet DB compression at block 741160:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Level"}),(0,r.jsx)(n.th,{children:"Time (min:sec)"}),(0,r.jsx)(n.th,{children:"Size"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"12"}),(0,r.jsx)(n.td,{children:"29:20"}),(0,r.jsx)(n.td,{children:"15.8 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"15"}),(0,r.jsx)(n.td,{children:"46:15"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"17"}),(0,r.jsx)(n.td,{children:"87:42"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"19"}),(0,r.jsx)(n.td,{children:"197:08"}),(0,r.jsx)(n.td,{children:"12.9 GB"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For local backups, using 1-5 is a great compression speed-to-size trade-off."}),"\n",(0,r.jsx)(n.h3,{id:"thread-count",children:"Thread count"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-T[thread count]"})," is the number of threads that ",(0,r.jsx)(n.code,{children:"zstd"})," should use for compression. If running a script or command on varying machines, use ",(0,r.jsx)(n.code,{children:"T0"})," to allow ",(0,r.jsx)(n.code,{children:"zstd"})," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,r.jsx)(n.code,{children:"-T0"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"long-distance-matching",children:"Long-distance matching"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"--long=31"})," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."]}),"\n",(0,r.jsxs)(n.p,{children:["At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,r.jsx)(n.code,{children:"--long=31"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."}),"\n",(0,r.jsx)(n.h3,{id:"summary-of-commands",children:"Summary of commands"}),"\n",(0,r.jsx)(n.p,{children:"The general command for compression is:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.p,{children:"For local backups, use a lower compression level:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h2,{id:"decompression",children:"Decompression"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zstd -d"})," is the command for decompression; however, the same ",(0,r.jsx)(n.code,{children:"--long"})," value used for compression must be specified. For all ",(0,r.jsx)(n.code,{children:"casper-node"})," DB-related decompression, you will likely use this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"--long=31"})," is omitted, you might see an error such as this, which also gives you the solution:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding \n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then use the ",(0,r.jsx)(n.code,{children:"zstd"})," result to populate a ",(0,r.jsx)(n.code,{children:"tar -xv"})," command. Also, create the decompressed files using ",(0,r.jsx)(n.code,{children:"sudo -u casper"}),", because the files will be used by the ",(0,r.jsx)(n.code,{children:"casper-node"}),". Run the following command inside an empty DB location:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.p,{children:"To fix ownership, use this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py fix_permissions\n"})}),"\n",(0,r.jsx)(n.h2,{id:"streamed-decompression",children:"Streamed Decompression"}),"\n",(0,r.jsxs)(n.p,{children:["If a ",(0,r.jsx)(n.code,{children:".tar.zst"})," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,r.jsx)(n.code,{children:"curl"}),", which can output to stdout with ",(0,r.jsx)(n.code,{children:"--output"})," and stream binary to your terminal."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <URL for tar.zstd file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you use the output along with the previous process, you can decompress the files from ",(0,r.jsx)(n.code,{children:"curl"})," directly into a local directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <tar.zst URL> | zstd -d --long=31 | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"starting-a-new-node-with-a-decompressed-db",children:"Starting a New Node with a Decompressed DB"}),"\n",(0,r.jsxs)(n.p,{children:["If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,r.jsx)(n.code,{children:"node_util.py"})," script included in the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," installation."]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py force_run_version 1_4_5\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9acc619b.fdbf2c17.js b/assets/js/9acc619b.fdbf2c17.js new file mode 100644 index 000000000..808586b51 --- /dev/null +++ b/assets/js/9acc619b.fdbf2c17.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25465],{31662:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=s(74848),t=s(28453);const a={title:"Archive and Restore a DB"},o="Archiving and Restoring a Database",i={id:"operators/maintenance/archiving-and-restoring",title:"Archive and Restore a DB",description:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.",source:"@site/versioned_docs/version-1.5.X/operators/maintenance/archiving-and-restoring.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/archiving-and-restoring",permalink:"/1.5.X/operators/maintenance/archiving-and-restoring",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Archive and Restore a DB"},sidebar:"operators",previous:{title:"Node Maintenance",permalink:"/1.5.X/operators/maintenance/"},next:{title:"Move a Node",permalink:"/1.5.X/operators/maintenance/moving-node"}},d={},c=[{value:"Zstandard Limitations",id:"zstandard-limitations",level:2},{value:"Zstandard Installation",id:"zstandard-installation",level:2},{value:"Initial Warnings",id:"initial-warnings",level:2},{value:"Compression",id:"compression",level:2},{value:"Compression level",id:"compression-level",level:3},{value:"Thread count",id:"thread-count",level:3},{value:"Long-distance matching",id:"long-distance-matching",level:3},{value:"Summary of commands",id:"summary-of-commands",level:3},{value:"Decompression",id:"decompression",level:2},{value:"Streamed Decompression",id:"streamed-decompression",level:2},{value:"Starting a New Node with a Decompressed DB",id:"starting-a-new-node-with-a-decompressed-db",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"archiving-and-restoring-a-database",children:"Archiving and Restoring a Database"})}),"\n",(0,r.jsx)(n.p,{children:"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"http://facebook.github.io/zstd/",children:"Zstandard"})," is the best method for compression speed and space for the current LMDB-based database system that the ",(0,r.jsx)(n.code,{children:"casper-node"})," uses."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["The values presented in this document assume that the ",(0,r.jsx)(n.code,{children:"trie-compact"})," tool was run on a Mainnet database for compression. Contact the ",(0,r.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb",children:"support team"})," if you have questions."]})}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-limitations",children:"Zstandard Limitations"}),"\n",(0,r.jsxs)(n.p,{children:["The current DB implementation uses sparse files, which can be partially empty, thus not being processed efficiently. You can use ",(0,r.jsx)(n.code,{children:"tar"})," as a pre-filter for stripping sparse data, as shown ",(0,r.jsx)(n.a,{href:"#compression",children:"here"}),", thus eliminating the need to read the full DB size and improving processing."]}),"\n",(0,r.jsx)(n.h2,{id:"zstandard-installation",children:"Zstandard Installation"}),"\n",(0,r.jsx)(n.p,{children:"To install Zstandard, run the following command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo apt install zstd\n"})}),"\n",(0,r.jsx)(n.p,{children:"Note that Zstandard version 1.4.4 is distributed with Ubuntu 20.04, while version 1.3.3 is distributed with Ubuntu 18.04. Later versions have more documentation."}),"\n",(0,r.jsx)(n.h2,{id:"initial-warnings",children:"Initial Warnings"}),"\n",(0,r.jsxs)(n.p,{children:["You need to stop the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," process of the node (and, therefore, the ",(0,r.jsx)(n.code,{children:"casper-node"})," process using the DB) before any compression or decompression into a location. Otherwise, strange things can and will occur."]}),"\n",(0,r.jsx)(n.h2,{id:"compression",children:"Compression"}),"\n",(0,r.jsxs)(n.p,{children:["Run the following basic ",(0,r.jsx)(n.code,{children:"tar"})," command from the DB directory. For Mainnet, the directory would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper"}),", and for Testnet it would be ",(0,r.jsx)(n.code,{children:"/var/lib/casper/casper-node/casper-test"}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -cv --sparse .\n"})}),"\n",(0,r.jsx)(n.p,{children:"On some systems, you may get better performance if you specify the block number as an argument:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse .\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then stream the result into ",(0,r.jsx)(n.code,{children:"zstd"}),". The sections below discuss the ",(0,r.jsx)(n.a,{href:"#compression-level",children:"level"}),", ",(0,r.jsx)(n.a,{href:"#thread-count",children:"thread count"}),", and ",(0,r.jsx)(n.a,{href:"#long-distance-matching",children:"long"})," arguments."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -[level] -cv -T[thread count] --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h3,{id:"compression-level",children:"Compression level"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-[level]"})," argument is the compression level from 1 to 19 (and 20-22 with expansion). In testing, we found 15 to be the sweet spot in compression time vs. size. We recommend lower compression if you plan to transfer the archive only once. If you are creating an archive to be downloaded by many, then the extra time for higher compression may be helpful."]}),"\n",(0,r.jsx)(n.p,{children:"Here are some examples of a Mainnet DB compression at block 741160:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Level"}),(0,r.jsx)(n.th,{children:"Time (min:sec)"}),(0,r.jsx)(n.th,{children:"Size"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"12"}),(0,r.jsx)(n.td,{children:"29:20"}),(0,r.jsx)(n.td,{children:"15.8 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"15"}),(0,r.jsx)(n.td,{children:"46:15"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"17"}),(0,r.jsx)(n.td,{children:"87:42"}),(0,r.jsx)(n.td,{children:"13.0 GB"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:"19"}),(0,r.jsx)(n.td,{children:"197:08"}),(0,r.jsx)(n.td,{children:"12.9 GB"})]})]})]}),"\n",(0,r.jsx)(n.p,{children:"For local backups, using 1-5 is a great compression speed-to-size trade-off."}),"\n",(0,r.jsx)(n.h3,{id:"thread-count",children:"Thread count"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"-T[thread count]"})," is the number of threads that ",(0,r.jsx)(n.code,{children:"zstd"})," should use for compression. If running a script or command on varying machines, use ",(0,r.jsx)(n.code,{children:"T0"})," to allow ",(0,r.jsx)(n.code,{children:"zstd"})," to detect the number of cores and run with the same number of threads as the detected cores. A speed-up can be obtained for machines with multiple threads per core by configuring a thread count near the number of threads. It is advisable to stay within the number of CPU threads. The recommendations in this article will use ",(0,r.jsx)(n.code,{children:"-T0"}),"."]}),"\n",(0,r.jsx)(n.h3,{id:"long-distance-matching",children:"Long-distance matching"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.code,{children:"--long=31"})," argument is where we see the most space gained by the algorithm because it controls the size of the matching window in powers of 2 (2**31 is 2 GB). The downside is that it requires 2.0 GB memory during compression and decompression as it looks and rebuilds ahead. The default is 27 or 128 MB."]}),"\n",(0,r.jsxs)(n.p,{children:["At compression 19, we see a 30 GB file using the default 128 MB look ahead, and a 13 GB file using 2 GB look ahead. Since all validators should have 16-32 GB of memory, we keep this at ",(0,r.jsx)(n.code,{children:"--long=31"}),"."]}),"\n",(0,r.jsx)(n.p,{children:"An important note is that decompression requires a compatible argument. Trying with a different long-distance matching value will result in an error. However, it will also return the necessary value to provide."}),"\n",(0,r.jsx)(n.h3,{id:"summary-of-commands",children:"Summary of commands"}),"\n",(0,r.jsx)(n.p,{children:"The general command for compression is:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -15 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.p,{children:"For local backups, use a lower compression level:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"tar -b 4096 -cv --sparse . | zstd -5 -cv -T0 --long=31 > [path_to]/file.tar.zst\n"})}),"\n",(0,r.jsx)(n.h2,{id:"decompression",children:"Decompression"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"zstd -d"})," is the command for decompression; however, the same ",(0,r.jsx)(n.code,{children:"--long"})," value used for compression must be specified. For all ",(0,r.jsx)(n.code,{children:"casper-node"})," DB-related decompression, you will likely use this command:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If ",(0,r.jsx)(n.code,{children:"--long=31"})," is omitted, you might see an error such as this, which also gives you the solution:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"./casper.tar.zst : Decoding error (36) : Frame requires too much memory for decoding \n./casper.tar.zst : Window size larger than maximum : 2147483648 > 134217728\n./casper.tar.zst : Use --long=31 or --memory=2048MB\n"})}),"\n",(0,r.jsxs)(n.p,{children:["You can then use the ",(0,r.jsx)(n.code,{children:"zstd"})," result to populate a ",(0,r.jsx)(n.code,{children:"tar -xv"})," command. Also, create the decompressed files using ",(0,r.jsx)(n.code,{children:"sudo -u casper"}),", because the files will be used by the ",(0,r.jsx)(n.code,{children:"casper-node"}),". Run the following command inside an empty DB location:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"zstd -cd --long=31 <.tar.zst file> | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.p,{children:"To fix ownership, use this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py fix_permissions\n"})}),"\n",(0,r.jsx)(n.h2,{id:"streamed-decompression",children:"Streamed Decompression"}),"\n",(0,r.jsxs)(n.p,{children:["If a ",(0,r.jsx)(n.code,{children:".tar.zst"})," archive is hosted on a website and you will not need the file after decompressing, you can stream it into the process using ",(0,r.jsx)(n.code,{children:"curl"}),", which can output to stdout with ",(0,r.jsx)(n.code,{children:"--output"})," and stream binary to your terminal."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <URL for tar.zstd file>\n"})}),"\n",(0,r.jsxs)(n.p,{children:["If you use the output along with the previous process, you can decompress the files from ",(0,r.jsx)(n.code,{children:"curl"})," directly into a local directory:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"curl -s --output - <tar.zst URL> | zstd -d --long=31 | sudo -u casper tar -xv\n"})}),"\n",(0,r.jsx)(n.h2,{id:"starting-a-new-node-with-a-decompressed-db",children:"Starting a New Node with a Decompressed DB"}),"\n",(0,r.jsxs)(n.p,{children:["If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the ",(0,r.jsx)(n.code,{children:"node_util.py"})," script included in the ",(0,r.jsx)(n.code,{children:"casper-node-launcher"})," installation."]}),"\n",(0,r.jsx)(n.p,{children:"For example, if you are using a DB archive from node version 1.4.5, you would run this command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"sudo /etc/casper/node_util.py force_run_version 1_4_5\n"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>i});var r=s(96540);const t={},a=r.createContext(t);function o(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9afe1d3d.115a3c11.js b/assets/js/9afe1d3d.115a3c11.js new file mode 100644 index 000000000..101c90aa0 --- /dev/null +++ b/assets/js/9afe1d3d.115a3c11.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[240],{63131:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter-testnet"},i="A Counter on the Testnet",a={id:"resources/beginner/counter-testnet/index",title:"Introduction",description:"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/index.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/counter-testnet",permalink:"/1.5.X/counter-testnet",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/counter-testnet"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/1.5.X/resources/beginner/counter/walkthrough"},next:{title:"Overview",permalink:"/1.5.X/resources/beginner/counter-testnet/overview"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-the-testnet",children:"A Counter on the Testnet"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a ",(0,n.jsx)(t.a,{href:"/1.5.X/counter",children:"similar tutorial"})," and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter-testnet/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter-testnet/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter-testnet/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper client"})," to send deploys to the chain."]}),"\n",(0,n.jsxs)(t.li,{children:["You were able to ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"set up and fund an account"})," on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The location of your account\u2019s ",(0,n.jsx)(t.strong,{children:"secret_key.pem"})," file"]}),"\n",(0,n.jsxs)(t.li,{children:["Your ",(0,n.jsx)(t.strong,{children:"account hash"})," identifier"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["You ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"selected a node"})," whose RPC port will be receiving the deploys coming from your account."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,n.jsx)(t.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rWaUiFFEyaY&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=3",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9afe1d3d.e763479c.js b/assets/js/9afe1d3d.e763479c.js deleted file mode 100644 index 41a7cc7b3..000000000 --- a/assets/js/9afe1d3d.e763479c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[240],{63131:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter-testnet"},i="A Counter on the Testnet",a={id:"resources/beginner/counter-testnet/index",title:"Introduction",description:"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/index.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/counter-testnet",permalink:"/counter-testnet",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/counter-testnet"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter/walkthrough"},next:{title:"Overview",permalink:"/resources/beginner/counter-testnet/overview"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-the-testnet",children:"A Counter on the Testnet"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a ",(0,n.jsx)(t.a,{href:"/counter",children:"similar tutorial"})," and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})," to send deploys to the chain."]}),"\n",(0,n.jsxs)(t.li,{children:["You were able to ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#setting-up-an-account",children:"set up and fund an account"})," on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The location of your account\u2019s ",(0,n.jsx)(t.strong,{children:"secret_key.pem"})," file"]}),"\n",(0,n.jsxs)(t.li,{children:["Your ",(0,n.jsx)(t.strong,{children:"account hash"})," identifier"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["You ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"selected a node"})," whose RPC port will be receiving the deploys coming from your account."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,n.jsx)(t.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rWaUiFFEyaY&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=3",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b0d9b67.bbbfb3bf.js b/assets/js/9b0d9b67.bbbfb3bf.js deleted file mode 100644 index ff79ca489..000000000 --- a/assets/js/9b0d9b67.bbbfb3bf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9078],{10158:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>a});var t=r(74848),s=r(28453);const d={title:"Casper on Ledger"},i="Using Ledger with Casper",l={id:"users/ledger/index",title:"Casper on Ledger",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/users/ledger/index.md",sourceDirName:"users/ledger",slug:"/users/ledger/",permalink:"/users/ledger/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Casper on Ledger"},sidebar:"users",previous:{title:"Transfer Tokens",permalink:"/users/token-transfer"},next:{title:"Set up Ledger",permalink:"/workflow/ledger-setup/"}},c={},a=[];function o(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-with-casper",children:"Using Ledger with Casper"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup with Casper"})}),(0,t.jsx)(n.td,{children:"Connect a Ledger device to the Casper application"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/ledger/ledger-live",children:"Using Ledger and Ledger Live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and Ledger Live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/ledger/ledger-cspr-live",children:"Using Ledger and CSPR.live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and CSPR.live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,t.jsx)(n.td,{children:"Delegate tokens using a Ledger device and CSPR.live"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>l});var t=r(96540);const s={},d=t.createContext(s);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b0d9b67.d0cc04c6.js b/assets/js/9b0d9b67.d0cc04c6.js new file mode 100644 index 000000000..561e0611a --- /dev/null +++ b/assets/js/9b0d9b67.d0cc04c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[89078],{10158:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>l,toc:()=>a});var t=r(74848),s=r(28453);const d={title:"Casper on Ledger"},i="Using Ledger with Casper",l={id:"users/ledger/index",title:"Casper on Ledger",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/users/ledger/index.md",sourceDirName:"users/ledger",slug:"/users/ledger/",permalink:"/1.5.X/users/ledger/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Casper on Ledger"},sidebar:"users",previous:{title:"Transfer Tokens",permalink:"/1.5.X/users/token-transfer"},next:{title:"Set up Ledger",permalink:"/1.5.X/workflow/ledger-setup/"}},c={},a=[];function o(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-with-casper",children:"Using Ledger with Casper"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/workflow/ledger-setup/",children:"Ledger Setup with Casper"})}),(0,t.jsx)(n.td,{children:"Connect a Ledger device to the Casper application"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/users/ledger/ledger-live",children:"Using Ledger and Ledger Live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and Ledger Live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/users/ledger/ledger-cspr-live",children:"Using Ledger and CSPR.live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and CSPR.live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,t.jsx)(n.td,{children:"Delegate tokens using a Ledger device and CSPR.live"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>l});var t=r(96540);const s={},d=t.createContext(s);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9b70ce79.bc96c9f0.js b/assets/js/9b70ce79.bc96c9f0.js new file mode 100644 index 000000000..24c2b191b --- /dev/null +++ b/assets/js/9b70ce79.bc96c9f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[20367],{23943:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var t=n(74848),s=n(28453);const a={title:"Consensus"},r="Consensus Economics",o={id:"concepts/economics/consensus",title:"Consensus",description:"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.",source:"@site/versioned_docs/version-2.0.0/concepts/economics/consensus.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/consensus",permalink:"/2.0.0/concepts/economics/consensus",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Consensus"},sidebar:"concepts",previous:{title:"Overview",permalink:"/2.0.0/economics"},next:{title:"Runtime",permalink:"/2.0.0/runtime"}},c={},d=[{value:"Validator Selection",id:"selection",level:2},{value:"Bids",id:"bids",level:3},{value:"Delegation",id:"delegation",level:3},{value:"Incentives",id:"incentives",level:2},{value:"Validator Participation",id:"participation",level:3},{value:"Rewards Distribution",id:"distribution",level:3},{value:"Validator Inactivity",id:"inactivity",level:3},{value:"Founding Validators",id:"founding-validators",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"consensus-economics",children:"Consensus Economics"})}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.a,{href:"/2.0.0/concepts/design/consensus",children:"Casper consensus"})," is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule."]}),"\n",(0,t.jsx)(i.h2,{id:"selection",children:"Validator Selection"}),"\n",(0,t.jsxs)(i.p,{children:["After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a ",(0,t.jsx)(i.em,{children:"chainspec"})," configuration file specifies a few key parameters:"]}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"auction_delay"})," specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the ",(0,t.jsx)(i.em,{children:"auction_delay"})," is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era."]}),"\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"validator_slots"})," parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids."]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"bids",children:"Bids"}),"\n",(0,t.jsxs)(i.p,{children:["Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the ",(0,t.jsx)(i.code,{children:"unbonding_delay"})," chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners."]}),"\n",(0,t.jsx)(i.p,{children:"Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document."}),"\n",(0,t.jsx)(i.h3,{id:"delegation",children:"Delegation"}),"\n",(0,t.jsx)(i.p,{children:"Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate."}),"\n",(0,t.jsxs)(i.p,{children:["Currently, there are delegation limits in the chainspec. Visit the ",(0,t.jsx)(i.a,{href:"/2.0.0/users/delegating",children:"Delegating Tokens"})," page for more details."]}),"\n",(0,t.jsx)(i.h2,{id:"incentives",children:"Incentives"}),"\n",(0,t.jsx)(i.p,{children:"The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals."}),"\n",(0,t.jsx)(i.p,{children:"Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future."}),"\n",(0,t.jsxs)(i.p,{children:["The network incentivizes participation by issuing ",(0,t.jsx)(i.a,{href:"/2.0.0/concepts/design/rewards",children:"rewards"})," to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by ",(0,t.jsx)(i.a,{href:"/2.0.0/concepts/economics/staking",children:"staking"})," with a validator. All rewards are added directly to the corresponding bids and delegations."]}),"\n",(0,t.jsx)(i.h3,{id:"participation",children:"Validator Participation"}),"\n",(0,t.jsx)(i.p,{children:"The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load."}),"\n",(0,t.jsx)(i.p,{children:"CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"The growth of CSPR supply is exponential"}),"\n",(0,t.jsx)(i.li,{children:"Issuance takes into account slashed CSPR"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"i"})," - the era's index as a positive integer [0, 1, 2, ..., n]"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"initial_supply"})," - the number of CSPR at genesis"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"issuance_rate"})," - the annual rate at which new CSPR tokens are minted"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"ticks_per_year"})," - the number of milliseconds in a year equal to 31,536,000,000"]}),"\n"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)\n"})}),"\n",(0,t.jsxs)(i.p,{children:["We introduce the ",(0,t.jsx)(i.em,{children:"round issuance rate"})," (corresponding to the chainspec parameter ",(0,t.jsx)(i.code,{children:"round_seigniorage_rate"}),") with this formula:"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1\n"})}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.em,{children:"round issuance rate"})," is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter ",(0,t.jsx)(i.code,{children:"minimum_round_exponent"}),". For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds."]}),"\n",(0,t.jsx)(i.p,{children:"Finally, the base round reward is computed as:"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"base_round_reward(i) = round_issuance_rate * supply(i)\n"})}),"\n",(0,t.jsx)(i.p,{children:"This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block."}),"\n",(0,t.jsx)(i.h3,{id:"distribution",children:"Rewards Distribution"}),"\n",(0,t.jsx)(i.p,{children:"Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals."}),"\n",(0,t.jsx)(i.p,{children:"The concept of validator weight is crucial in understanding the distribution scheme:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Weight:"})," A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Assigned weight of a round:"})," The total weight of validators scheduled to participate in a round"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Participated weight of a round:"})," The total weight of validators that participated or sent messages before the end of the round"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Relative weight"}),": A validator's weight relative to the total validator weight that participated in a round"]}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"For each finalized block, there is a fraction of rewards due for signature creation and collection"}),"\n",(0,t.jsx)(i.li,{children:"Signature rewards are split between the finder (block proposer) and the signature creators"}),"\n",(0,t.jsxs)(i.li,{children:["The signature creators get a part of the signature reward pot due for the block: ",(0,t.jsx)(i.code,{children:"(1 - finder's fee) * relative weight"})]}),"\n",(0,t.jsxs)(i.li,{children:["The finder gets a small reward as well to incentivize collecting and reporting all the signatures: ",(0,t.jsx)(i.code,{children:"finder's fee * total relative weight of signatures collected"})]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the ",(0,t.jsx)(i.a,{href:"/2.0.0/concepts/design/rewards",children:"Rewards Design"})," page for more details."]}),"\n",(0,t.jsx)(i.h3,{id:"inactivity",children:"Validator Inactivity"}),"\n",(0,t.jsx)(i.p,{children:"Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid."}),"\n",(0,t.jsx)(i.h2,{id:"founding-validators",children:"Founding Validators"}),"\n",(0,t.jsx)(i.p,{children:"When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days."})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>o});var t=n(96540);const s={},a=t.createContext(s);function r(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c5b6467.3d86687a.js b/assets/js/9c5b6467.3d86687a.js new file mode 100644 index 000000000..3cbf85f2e --- /dev/null +++ b/assets/js/9c5b6467.3d86687a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53265],{72675:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),a=t(28453);const i={},o="Becoming a Validator",d={id:"operators/becoming-a-validator/index",title:"Becoming a Validator",description:"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.",source:"@site/docs/operators/becoming-a-validator/index.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/",permalink:"/operators/becoming-a-validator/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"operators",previous:{title:"Sidecar Setup",permalink:"/operators/setup/casper-sidecar"},next:{title:"Bonding",permalink:"/operators/becoming-a-validator/bonding"}},s={},c=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"becoming-a-validator",children:"Becoming a Validator"})}),"\n",(0,r.jsxs)(n.p,{children:["After ",(0,r.jsx)(n.a,{href:"/operators/setup/",children:"setting up a node"}),", the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding",children:"Bonding as a Validator"})}),(0,r.jsx)(n.td,{children:"A guide about the bonding process and submitting a bid"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"Unbonding as a Validator"})}),(0,r.jsx)(n.td,{children:"The process to withdraw a bid and unbonding"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering",children:"Recovering from Validator Eviction"})}),(0,r.jsx)(n.td,{children:"Steps a validator needs to take if it is evicted from the validator set"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Nodes"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/becoming-a-validator/change-bid-public-key",children:"Change bid public key"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var r=t(96540);const a={},i=r.createContext(a);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c5b6467.3db5c71f.js b/assets/js/9c5b6467.3db5c71f.js deleted file mode 100644 index ad1a4170b..000000000 --- a/assets/js/9c5b6467.3db5c71f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3265],{72675:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>c});var r=t(74848),a=t(28453);const i={},o="Becoming a Validator",d={id:"operators/becoming-a-validator/index",title:"Becoming a Validator",description:"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.",source:"@site/docs/operators/becoming-a-validator/index.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/",permalink:"/next/operators/becoming-a-validator/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"operators",previous:{title:"Sidecar Setup",permalink:"/next/operators/setup/casper-sidecar"},next:{title:"Bonding",permalink:"/next/operators/becoming-a-validator/bonding"}},s={},c=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"becoming-a-validator",children:"Becoming a Validator"})}),"\n",(0,r.jsxs)(n.p,{children:["After ",(0,r.jsx)(n.a,{href:"/next/operators/setup/",children:"setting up a node"}),", the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/becoming-a-validator/bonding",children:"Bonding as a Validator"})}),(0,r.jsx)(n.td,{children:"A guide about the bonding process and submitting a bid"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/becoming-a-validator/unbonding",children:"Unbonding as a Validator"})}),(0,r.jsx)(n.td,{children:"The process to withdraw a bid and unbonding"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/becoming-a-validator/recovering",children:"Recovering from Validator Eviction"})}),(0,r.jsx)(n.td,{children:"Steps a validator needs to take if it is evicted from the validator set"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Nodes"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/becoming-a-validator/change-bid-public-key",children:"Change bid public key"})}),(0,r.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var r=t(96540);const a={},i=r.createContext(a);function o(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c6aa8d2.87f1ae35.js b/assets/js/9c6aa8d2.87f1ae35.js deleted file mode 100644 index 9b75b2c46..000000000 --- a/assets/js/9c6aa8d2.87f1ae35.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2381],{55711:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Y",a={id:"concepts/glossary/Y",title:"Y",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Y.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Y",permalink:"/concepts/glossary/Y",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"X",permalink:"/concepts/glossary/X"},next:{title:"Z",permalink:"/concepts/glossary/Z"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"y",children:"Y"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c6aa8d2.a5007e66.js b/assets/js/9c6aa8d2.a5007e66.js new file mode 100644 index 000000000..c6b974bba --- /dev/null +++ b/assets/js/9c6aa8d2.a5007e66.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92381],{55711:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Y",a={id:"concepts/glossary/Y",title:"Y",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Y.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Y",permalink:"/1.5.X/concepts/glossary/Y",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"X",permalink:"/1.5.X/concepts/glossary/X"},next:{title:"Z",permalink:"/1.5.X/concepts/glossary/Z"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"y",children:"Y"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c780b1a.134169a6.js b/assets/js/9c780b1a.134169a6.js deleted file mode 100644 index 260fac3cc..000000000 --- a/assets/js/9c780b1a.134169a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7438],{20621:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var n=t(74848),r=t(28453);const a={title:"SDK Client Libraries",slug:"/sdk"},i="SDK Client Libraries",d={id:"developers/dapps/sdk/index",title:"SDK Client Libraries",description:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.",source:"@site/docs/developers/dapps/sdk/index.md",sourceDirName:"developers/dapps/sdk",slug:"/sdk",permalink:"/next/sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"SDK Client Libraries",slug:"/sdk"},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/next/developers/dapps/prerequisites"},next:{title:"SDK Client Library Usage",permalink:"/next/developers/dapps/sdk/client-library-usage"}},o={},c=[{value:"Serialization Standard",id:"serialization-standard",level:2},{value:"JSON-RPC API",id:"json-rpc-api",level:2},{value:"Table of Contents",id:"table-of-contents",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,n.jsx)(s.p,{children:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions."}),"\n",(0,n.jsx)(s.p,{children:"Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories."}),"\n",(0,n.jsx)(s.p,{children:"Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories."}),"\n",(0,n.jsx)(s.h2,{id:"serialization-standard",children:"Serialization Standard"}),"\n",(0,n.jsxs)(s.p,{children:["The Casper platform uses a custom serialization format. To this end, we've established a ",(0,n.jsx)(s.a,{href:"/next/concepts/serialization/",children:"Serialization Standard"}),", which must be followed when building a Casper SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"json-rpc-api",children:"JSON-RPC API"}),"\n",(0,n.jsxs)(s.p,{children:["Developers can interact directly with the ",(0,n.jsx)(s.a,{href:"/next/developers/json-rpc/",children:"Casper JSON-RPC API"})," instead of using an SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"SDK Documentation"}),(0,n.jsx)(s.th,{children:"GitHub Location"}),(0,n.jsx)(s.th,{children:"Organization"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/next/developers/dapps/sdk/script-sdk",children:"JavaScript/TypeScript"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"casper-js-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Java SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-java-sdk/",children:"casper-java-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/next/developers/dapps/sdk/csharp-sdk",children:"C# SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-net-sdk",children:"casper-net-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/next/developers/dapps/sdk/go-sdk",children:"Go SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-go-sdk",children:"casper-go-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/next/developers/dapps/sdk/python-sdk",children:"Python SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/",children:"casper-python-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PHP SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-php-sdk",children:"casper-php-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Scala SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"casper-scala-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem",children:"M. Abahmane"})})]})]})]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function i(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9c780b1a.7540caa7.js b/assets/js/9c780b1a.7540caa7.js new file mode 100644 index 000000000..d42f927cd --- /dev/null +++ b/assets/js/9c780b1a.7540caa7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[17438],{20621:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var n=t(74848),r=t(28453);const a={title:"SDK Client Libraries",slug:"/sdk"},i="SDK Client Libraries",d={id:"developers/dapps/sdk/index",title:"SDK Client Libraries",description:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.",source:"@site/docs/developers/dapps/sdk/index.md",sourceDirName:"developers/dapps/sdk",slug:"/sdk",permalink:"/sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"SDK Client Libraries",slug:"/sdk"},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/developers/dapps/prerequisites"},next:{title:"SDK Client Library Usage",permalink:"/developers/dapps/sdk/client-library-usage"}},o={},c=[{value:"Serialization Standard",id:"serialization-standard",level:2},{value:"JSON-RPC API",id:"json-rpc-api",level:2},{value:"Table of Contents",id:"table-of-contents",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,n.jsx)(s.p,{children:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions."}),"\n",(0,n.jsx)(s.p,{children:"Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories."}),"\n",(0,n.jsx)(s.p,{children:"Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories."}),"\n",(0,n.jsx)(s.h2,{id:"serialization-standard",children:"Serialization Standard"}),"\n",(0,n.jsxs)(s.p,{children:["The Casper platform uses a custom serialization format. To this end, we've established a ",(0,n.jsx)(s.a,{href:"/concepts/serialization/",children:"Serialization Standard"}),", which must be followed when building a Casper SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"json-rpc-api",children:"JSON-RPC API"}),"\n",(0,n.jsxs)(s.p,{children:["Developers can interact directly with the ",(0,n.jsx)(s.a,{href:"/developers/json-rpc/",children:"Casper JSON-RPC API"})," instead of using an SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"SDK Documentation"}),(0,n.jsx)(s.th,{children:"GitHub Location"}),(0,n.jsx)(s.th,{children:"Organization"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/script-sdk",children:"JavaScript/TypeScript"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"casper-js-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Java SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-java-sdk/",children:"casper-java-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/csharp-sdk",children:"C# SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-net-sdk",children:"casper-net-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/go-sdk",children:"Go SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-go-sdk",children:"casper-go-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/python-sdk",children:"Python SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/",children:"casper-python-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PHP SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-php-sdk",children:"casper-php-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Scala SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"casper-scala-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem",children:"M. Abahmane"})})]})]})]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function i(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9cb749bd.a84526b3.js b/assets/js/9cb749bd.a84526b3.js new file mode 100644 index 000000000..a4651c1f4 --- /dev/null +++ b/assets/js/9cb749bd.a84526b3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39457],{53086:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Local Network Testing"},o="Testing Smart Contracts with NCTL",a={id:"developers/dapps/nctl-test",title:"Local Network Testing",description:"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/nctl-test.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/nctl-test",permalink:"/2.0.0/developers/dapps/nctl-test",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Local Network Testing"},sidebar:"developers",previous:{title:"Local Network Setup",permalink:"/2.0.0/developers/dapps/setup-nctl"},next:{title:"Monitoring Events with the Casper Sidecar",permalink:"/2.0.0/developers/dapps/monitor-and-consume-events"}},c={},l=[{value:"Getting Started with NCTL",id:"getting-started-with-nctl",level:2},{value:"NCTL Verification Prior to Testing",id:"nctl-verification-prior-to-testing",level:2},{value:"Installing the Smart Contract",id:"installing-the-smart-contract",level:2},{value:"Verifying Transaction Execution",id:"verifying-transaction-execution",level:2},{value:"Interacting with the Installed Contract",id:"interacting-with-the-installed-contract",level:2},{value:"Verifying Correct Contract Behavior",id:"verifying-correct-contract-behavior",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"testing-smart-contracts-with-nctl",children:"Testing Smart Contracts with NCTL"})}),"\n",(0,s.jsxs)(n.p,{children:["NCTL effectively simulates a live Casper network. The process for sending a ",(0,s.jsx)(n.code,{children:"Transaction"})," to an NCTL-based network is therefore similar to doing so on a live network."]}),"\n",(0,s.jsxs)(n.p,{children:["Testing ",(0,s.jsx)(n.code,{children:"Transactions"})," prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"writing your smart contract"})," and testing it ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"using the provided framework"}),", NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code."]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started-with-nctl",children:"Getting Started with NCTL"}),"\n",(0,s.jsxs)(n.p,{children:["Prior to testing a ",(0,s.jsx)(n.code,{children:"Transaction"})," through NCTL, you should have the following steps accomplished:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Completed writing a Transaction"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/testing-contracts",children:"Tested the Transaction"})," using the Casper testing framework"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"Setup NCTL"})," on your system"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nctl-verification-prior-to-testing",children:"NCTL Verification Prior to Testing"}),"\n",(0,s.jsx)(n.p,{children:"Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-status\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You should see five nodes and instances of sidecar ",(0,s.jsx)(n.code,{children:"RUNNING"})," and five ",(0,s.jsx)(n.code,{children:"STOPPED"}),". Further, verify that the node and user information propagated within the ",(0,s.jsx)(n.em,{children:"casper-node/utils/assets"})," directory. Each node and user should have the associated ",(0,s.jsx)(n.code,{children:"Keys"})," necessary to interact with the network. Run the following command to view first user details:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-view-user-account user=1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-smart-contract",children:"Installing the Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This document assumes that you setup your NCTL network using the standard settings in a directory called ",(0,s.jsx)(n.em,{children:"/casper/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will need the following information to use the ",(0,s.jsx)(n.code,{children:"put-transaction session"})," command:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", in this case ",(0,s.jsx)(n.code,{children:"casper-net-1"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"secret key"})," of the account sending the ",(0,s.jsx)(n.code,{children:"Transaction"}),". For this example, we are using node-1 as the sender. The secret key file can be found at ",(0,s.jsx)(n.em,{children:"casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". In our example put-transaction, this will appear as ",(0,s.jsx)(n.code,{children:"--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". If your Transaction is more complex and requires multiple accounts, NCTL also establishes multiple users for testing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"pricing mode"})," for this transaction. In this case, we are using the ",(0,s.jsx)(n.code,{children:"fixed"})," pricing mode."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--gas-price-tolerance 10"}),". ",(0,s.jsxs)(n.strong,{children:["NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions#a-note-about-gas-price",children:"note about gas prices"}),"."]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"path"})," to your ",(0,s.jsx)(n.code,{children:"Transaction"})," that you wish to send to the NCTL network. This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--transaction-path <PATH>"})," and will require you to define the path to your specific ",(0,s.jsx)(n.code,{children:"Transaction"})," Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"category"})," of the transaction, based on the size of the Wasm included. ",(0,s.jsx)(n.code,{children:"install-upgrade"})," being the largest, descending in size through ",(0,s.jsx)(n.code,{children:"large"}),", ",(0,s.jsx)(n.code,{children:"medium"}),", and ",(0,s.jsx)(n.code,{children:"small"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--category 'install-upgrade'"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"session entry point"}),", which at installation time is usually ",(0,s.jsx)(n.code,{children:"call"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"})," for a node on your NCTL network. In this example, we are using the node at ",(0,s.jsx)(n.code,{children:"http://localhost:11101"}),". On the Casper Mainnet or Testnet, nodes will use port ",(0,s.jsx)(n.code,{children:"7777"}),". This will appear in our example put-transaction as ",(0,s.jsx)(n.code,{children:"--node-address http://<HOST>:7777"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command to send your ",(0,s.jsx)(n.code,{children:"Transaction"})," should look similar to the following code snippet:"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Use of the ",(0,s.jsx)(n.code,{children:"$(get_path_to_client)"})," command assumes that you are operating in an activated NCTL environment."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) put-transaction session \\\n--chain-name \"casper-net-1\" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path <PATH> \\\n--category 'install-upgrade' \\\n--session-entry-point call \\\n--node-address http://localhost:11101\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The response will return something similar to the following information. Note the ",(0,s.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1294011212530641270,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-transaction-execution",children:"Verifying Transaction Execution"}),"\n",(0,s.jsxs)(n.p,{children:["The previous command sent the ",(0,s.jsx)(n.code,{children:"Transaction"})," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,s.jsx)(n.code,{children:"transaction_hash"})," received in the response allows you to query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status."]}),"\n",(0,s.jsxs)(n.p,{children:["To query the ",(0,s.jsx)(n.code,{children:"Transaction"}),"'s status, you will pass both the ",(0,s.jsx)(n.code,{children:"transaction_hash"})," and the same ",(0,s.jsx)(n.code,{children:"node-address"})," from above using the following command. This will return either an error message in the event of failure or the ",(0,s.jsx)(n.code,{children:"Transaction"})," details if it succeeds."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-transaction efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e -n http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interacting-with-the-installed-contract",children:"Interacting with the Installed Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Once your NCTL network executes your ",(0,s.jsx)(n.code,{children:"Transaction"}),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,s.jsx)(n.code,{children:"PackageHash"})," itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,s.jsxs)(n.a,{href:"/2.0.0/developers/cli/sending-transactions",children:["send the ",(0,s.jsx)(n.code,{children:"Transaction"})]}),", we can retrieve the ",(0,s.jsx)(n.code,{children:"PackageHash"})," from the node-1 account information. To do so, we will use the following NCTL command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"nctl-view-faucet-account\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This will return the NCTL faucet account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"AccountHash"}),". We can then query the ",(0,s.jsx)(n.code,{children:"PublicKey"})," using the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) query-global-state \\\n--node-address http://localhost:11101 \\\n--key <PUBLIC KEY> \\\n--state-root-hash <STATE ROOT HASH>\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["You can retrieve the current state root hash using the command ",(0,s.jsx)(n.code,{children:"casper client get-state-root-hash"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return an ",(0,s.jsx)(n.code,{children:"entity-account-"})," value that you can use as an entity identifier in the following command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"$(get_path_to_client) get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier <ENTITY IDENTIFIER>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return information pertaining to the account, including the ",(0,s.jsx)(n.code,{children:"NamedKeys"}),". The ",(0,s.jsx)(n.code,{children:"PackageHash"})," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,s.jsx)(n.code,{children:"Transaction"}),". In this instance, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--node-address http://localhost:11101"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"package hash"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"gas price tolerance"})," in CSPR, which is the maximum amount of gas you are willing to pay for execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})," on the contract that you wish to invoke."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.strong,{children:"session arguments"})," specific to the contract that you are testing. Multiple instances of ",(0,s.jsx)(n.code,{children:"--session-arg"})," may be used as necessary to provide values to the contract. In the example below, you will see a demonstration of a session arg of ",(0,s.jsx)(n.code,{children:"amount"})," as ",(0,s.jsx)(n.code,{children:"--session-arg \"amount:u256='100'\""}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$(get_path_to_client) put-transaction package \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4 \\ \n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--session-arg "amount:u256=\'100\'"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-correct-contract-behavior",children:"Verifying Correct Contract Behavior"}),"\n",(0,s.jsxs)(n.p,{children:["After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts#querying-global-state",children:"global state"}),". Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/beginner/counter/walkthrough",children:"basic counter contract tutorial"}),", the NCTL process would have the following flow:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Send a ",(0,s.jsx)(n.code,{children:"Transaction"}),' to install the "Counter" smart contract.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Verify the execution of the ",(0,s.jsx)(n.code,{children:"Transaction"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Interact with the installed contract package using an additional ",(0,s.jsx)(n.code,{children:"Transaction"})," that calls one or several of the entry points. For example, calling the ",(0,s.jsx)(n.code,{children:"increment"})," entry point to increase the counter by one."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify the associated change in global state. Namely, an increase in the counter."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9cd0819b.14619139.js b/assets/js/9cd0819b.14619139.js deleted file mode 100644 index c5ab2b5a9..000000000 --- a/assets/js/9cd0819b.14619139.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[247],{92367:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var i=t(74848),s=t(28453);const a={title:"Recovery"},o="Recovering from Validator Eviction",c={id:"operators/becoming-a-validator/recovering",title:"Recovery",description:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:",source:"@site/docs/operators/becoming-a-validator/recovering.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/recovering",permalink:"/next/operators/becoming-a-validator/recovering",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Recovery"},sidebar:"operators",previous:{title:"Unbonding",permalink:"/next/operators/becoming-a-validator/unbonding"},next:{title:"Inactive and Faulty Nodes",permalink:"/next/operators/becoming-a-validator/inactive-vs-faulty"}},r={},d=[{value:"Detecting the Eviction",id:"detecting-the-eviction",level:2},{value:"Detection using CSPR.live",id:"detection-using-csprlive",level:3},{value:"Detection using the Casper Client",id:"detection-using-the-casper-client",level:3},{value:"Correcting any Underlying Node Issues",id:"correcting-any-underlying-node-issues",level:2},{value:"Activating the Bid",id:"activating-the-bid",level:2},{value:"Method 1: Activating the Bid with the System Auction Contract",id:"activating-system-auction",level:3},{value:"Method 2: Activating the Bid with Compiled Wasm",id:"activating-compiled-wasm",level:3},{value:"Checking the Bid Activation",id:"checking-the-bid-activation",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"recovering-from-validator-eviction",children:"Recovering from Validator Eviction"})}),"\n",(0,i.jsx)(n.p,{children:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Detecting the eviction"}),"\n",(0,i.jsx)(n.li,{children:"Correcting any underlying node issues"}),"\n",(0,i.jsx)(n.li,{children:"Re-building the contracts for bonding"}),"\n",(0,i.jsx)(n.li,{children:"Activating the bid"}),"\n",(0,i.jsx)(n.li,{children:"Checking the bid"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/next/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," topic explains why a node would be evicted."]}),"\n",(0,i.jsx)(n.h2,{id:"detecting-the-eviction",children:"Detecting the Eviction"}),"\n",(0,i.jsx)(n.p,{children:"The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era."}),"\n",(0,i.jsx)(n.p,{children:"For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era."}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-csprlive",children:"Detection using CSPR.live"}),"\n",(0,i.jsxs)(n.p,{children:["If you were a previous validator and still exist on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators-auction",children:"Validators Auction"})," tab but not in ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"}),", you may have been evicted or outbid."]}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-the-casper-client",children:"Detection using the Casper Client"}),"\n",(0,i.jsxs)(n.p,{children:["All auction information is returned with the ",(0,i.jsx)(n.code,{children:"casper-client get-auction-info"})," command. It would help if you filtered this down to your public key."]}),"\n",(0,i.jsxs)(n.p,{children:["You can replace the ",(0,i.jsx)(n.code,{children:"public_key"})," with your public key manually and run this command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"<public_key>\")'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You know you were evicted if the ",(0,i.jsx)(n.code,{children:"get-auction-info"})," command returned your bid showing an ",(0,i.jsx)(n.strong,{children:"inactive"})," field. See the ",(0,i.jsx)(n.a,{href:"/next/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," page for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive a ",(0,i.jsx)(n.code,{children:"parse error: Invalid numeric literal at"}),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info\n"})}),"\n",(0,i.jsx)(n.h2,{id:"correcting-any-underlying-node-issues",children:"Correcting any Underlying Node Issues"}),"\n",(0,i.jsx)(n.p,{children:"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."}),"\n",(0,i.jsxs)(n.p,{children:["To check if your node is in sync, compare the current block height at ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," with the height from your node with:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl -s localhost:8888/status | jq .last_added_block_info\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you cannot figure out the issue, ask for help in the ",(0,i.jsx)(n.em,{children:"node-tech-support"})," channel on ",(0,i.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"activating-the-bid",children:"Activating the Bid"}),"\n",(0,i.jsxs)(n.p,{children:["Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. The second method involves building the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," contract as explained in ",(0,i.jsx)(n.a,{href:"/next/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,i.jsx)(n.h3,{id:"activating-system-auction",children:"Method 1: Activating the Bid with the System Auction Contract"}),"\n",(0,i.jsxs)(n.p,{children:["This method calls the existing ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:"]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Testnet"}),": ",(0,i.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mainnet"}),": ",(0,i.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,i.jsx)(n.code,{children:"activate_bid"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,i.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point on the auction contract has a fixed cost of 10,000 motes."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.p,{children:"This example uses the Casper Testnet to reactivate a bid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, ",(0,i.jsx)(n.a,{href:"#checking-the-bid-activation",children:"check the bid activation"})," status."]}),"\n",(0,i.jsx)(n.h3,{id:"activating-compiled-wasm",children:"Method 2: Activating the Bid with Compiled Wasm"}),"\n",(0,i.jsxs)(n.p,{children:["The second method to rejoin the network is to reactivate your bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["As described above, this method is much more expensive than calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example that reactivates a bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,i.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"}),". For example, if you use the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," on a network with node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml",children:"1.4.9"}),", you will require a balance of at least 5 CSPR for this contract."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Check that the deploy was successful with the ",(0,i.jsx)(n.code,{children:"casper-client get-deploy <deploy_hash>"})," or by searching for the deploy hash on ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),". Also, check the bid activation status as shown below."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-the-bid-activation",children:"Checking the Bid Activation"}),"\n",(0,i.jsxs)(n.p,{children:["Once your deploy processes, you can ",(0,i.jsx)(n.a,{href:"/next/operators/becoming-a-validator/recovering#detecting-the-eviction-using-the-casper-client",children:"check your bid"})," again. You should now see ",(0,i.jsx)(n.code,{children:'"inactive": false'})," in the output."]}),"\n",(0,i.jsxs)(n.p,{children:["If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"})," tab."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9cd0819b.647896eb.js b/assets/js/9cd0819b.647896eb.js new file mode 100644 index 000000000..e057e28f9 --- /dev/null +++ b/assets/js/9cd0819b.647896eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30247],{92367:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var i=t(74848),s=t(28453);const a={title:"Recovery"},o="Recovering from Validator Eviction",c={id:"operators/becoming-a-validator/recovering",title:"Recovery",description:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:",source:"@site/docs/operators/becoming-a-validator/recovering.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/recovering",permalink:"/operators/becoming-a-validator/recovering",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Recovery"},sidebar:"operators",previous:{title:"Unbonding",permalink:"/operators/becoming-a-validator/unbonding"},next:{title:"Inactive and Faulty Nodes",permalink:"/operators/becoming-a-validator/inactive-vs-faulty"}},r={},d=[{value:"Detecting the Eviction",id:"detecting-the-eviction",level:2},{value:"Detection using CSPR.live",id:"detection-using-csprlive",level:3},{value:"Detection using the Casper Client",id:"detection-using-the-casper-client",level:3},{value:"Correcting any Underlying Node Issues",id:"correcting-any-underlying-node-issues",level:2},{value:"Activating the Bid",id:"activating-the-bid",level:2},{value:"Method 1: Activating the Bid with the System Auction Contract",id:"activating-system-auction",level:3},{value:"Method 2: Activating the Bid with Compiled Wasm",id:"activating-compiled-wasm",level:3},{value:"Checking the Bid Activation",id:"checking-the-bid-activation",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"recovering-from-validator-eviction",children:"Recovering from Validator Eviction"})}),"\n",(0,i.jsx)(n.p,{children:"This topic discusses the steps a validator needs to take if it is evicted from the validator set:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsx)(n.li,{children:"Detecting the eviction"}),"\n",(0,i.jsx)(n.li,{children:"Correcting any underlying node issues"}),"\n",(0,i.jsx)(n.li,{children:"Re-building the contracts for bonding"}),"\n",(0,i.jsx)(n.li,{children:"Activating the bid"}),"\n",(0,i.jsx)(n.li,{children:"Checking the bid"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," topic explains why a node would be evicted."]}),"\n",(0,i.jsx)(n.h2,{id:"detecting-the-eviction",children:"Detecting the Eviction"}),"\n",(0,i.jsx)(n.p,{children:"The validator selection occurs at the end of an Era. Due to the bonding delay, this determines the Validators for the Era after the Era is about to start. When a validating node does not participate in consensus for some time, it will be marked invalid and evicted at the end of the next Era."}),"\n",(0,i.jsx)(n.p,{children:"For example, if we are in Era 100 and your node is invalid, your node will be marked for eviction to be removed at the start of Era 102. This is due to the bonding delay of 1 Era."}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-csprlive",children:"Detection using CSPR.live"}),"\n",(0,i.jsxs)(n.p,{children:["If you were a previous validator and still exist on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators-auction",children:"Validators Auction"})," tab but not in ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"}),", you may have been evicted or outbid."]}),"\n",(0,i.jsx)(n.h3,{id:"detection-using-the-casper-client",children:"Detection using the Casper Client"}),"\n",(0,i.jsxs)(n.p,{children:["All auction information is returned with the ",(0,i.jsx)(n.code,{children:"casper-client get-auction-info"})," command. It would help if you filtered this down to your public key."]}),"\n",(0,i.jsxs)(n.p,{children:["You can replace the ",(0,i.jsx)(n.code,{children:"public_key"})," with your public key manually and run this command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == \"<public_key>\")'\n"})}),"\n",(0,i.jsx)(n.p,{children:"Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info | jq --arg pk \"$(cat /etc/casper/validator_keys/public_key_hex)\" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'\n"})}),"\n",(0,i.jsxs)(n.p,{children:["You know you were evicted if the ",(0,i.jsx)(n.code,{children:"get-auction-info"})," command returned your bid showing an ",(0,i.jsx)(n.strong,{children:"inactive"})," field. See the ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Validator Nodes"})," page for more information."]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive a ",(0,i.jsx)(n.code,{children:"parse error: Invalid numeric literal at"}),", this usually means that your RPC port is not up yet. Get your node in sync, and the RPC will come up. This should be working before you try to recover. Try running the following command to check the status of your RPC port:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info\n"})}),"\n",(0,i.jsx)(n.h2,{id:"correcting-any-underlying-node-issues",children:"Correcting any Underlying Node Issues"}),"\n",(0,i.jsx)(n.p,{children:"Before fixing the eviction, you need to correct the problem that caused your node to be evicted. Stage missed upgrades, correct any node issues, and get your node in sync."}),"\n",(0,i.jsxs)(n.p,{children:["To check if your node is in sync, compare the current block height at ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," with the height from your node with:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"curl -s localhost:8888/status | jq .last_added_block_info\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If you cannot figure out the issue, ask for help in the ",(0,i.jsx)(n.em,{children:"node-tech-support"})," channel on ",(0,i.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"activating-the-bid",children:"Activating the Bid"}),"\n",(0,i.jsxs)(n.p,{children:["Once your node is in sync and ready to validate again, you must activate your invalid bid. There are two ways to reactivate your bid. The recommended and cheaper method is to call the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. The second method involves building the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," contract as explained in ",(0,i.jsx)(n.a,{href:"/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,i.jsx)(n.h3,{id:"activating-system-auction",children:"Method 1: Activating the Bid with the System Auction Contract"}),"\n",(0,i.jsxs)(n.p,{children:["This method calls the existing ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. You must check the network's chainspec. For example, this entry point call needs 10,000 motes for node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are:"]}),"\n"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Testnet"}),": ",(0,i.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.strong,{children:"Mainnet"}),": ",(0,i.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the system auction contract. In this case, it is ",(0,i.jsx)(n.code,{children:"activate_bid"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"7",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,i.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsxs)(n.p,{children:["Calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point on the auction contract has a fixed cost of 10,000 motes."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsx)(n.p,{children:"This example uses the Casper Testnet to reactivate a bid:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 10000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point activate_bid \\\n--session-arg \"validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'\"\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Next, ",(0,i.jsx)(n.a,{href:"#checking-the-bid-activation",children:"check the bid activation"})," status."]}),"\n",(0,i.jsx)(n.h3,{id:"activating-compiled-wasm",children:"Method 2: Activating the Bid with Compiled Wasm"}),"\n",(0,i.jsxs)(n.p,{children:["The second method to rejoin the network is to reactivate your bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,i.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,i.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," expects one argument:"]}),"\n",(0,i.jsxs)(n.ol,{start:"6",children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"validator_public_key"}),": The hexadecimal public key of the validator reactivating its bid. ",(0,i.jsx)(n.strong,{children:"This key must match the secret key that signs the bid activation request"})]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["As described above, this method is much more expensive than calling the ",(0,i.jsx)(n.code,{children:"activate_bid"})," entry point."]})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.strong,{children:"Example:"})}),"\n",(0,i.jsxs)(n.p,{children:["Here is an example that reactivates a bid using the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"}),". You must modify the payment and other values in the deploy based on your environment and the network's ",(0,i.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),". For example, if you use the ",(0,i.jsx)(n.code,{children:"activate_bid.wasm"})," on a network with node version ",(0,i.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.9/resources/production/chainspec.toml",children:"1.4.9"}),", you will require a balance of at least 5 CSPR for this contract."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 5000000000 \\\n--session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \\\n--session-arg "validator_public_key:public_key=\'$(cat /etc/casper/validator_keys/public_key_hex)\'"\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Check that the deploy was successful with the ",(0,i.jsx)(n.code,{children:"casper-client get-deploy <deploy_hash>"})," or by searching for the deploy hash on ",(0,i.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),". Also, check the bid activation status as shown below."]}),"\n",(0,i.jsx)(n.h2,{id:"checking-the-bid-activation",children:"Checking the Bid Activation"}),"\n",(0,i.jsxs)(n.p,{children:["Once your deploy processes, you can ",(0,i.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering#detecting-the-eviction-using-the-casper-client",children:"check your bid"})," again. You should now see ",(0,i.jsx)(n.code,{children:'"inactive": false'})," in the output."]}),"\n",(0,i.jsxs)(n.p,{children:["If you wait until the next Era starts, you should also see your public key as a future validator on the ",(0,i.jsx)(n.a,{href:"https://cspr.live/validators",children:"Validators"})," tab."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var i=t(96540);const s={},a=i.createContext(s);function o(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d275d72.0b08718a.js b/assets/js/9d275d72.0b08718a.js new file mode 100644 index 000000000..42df7721d --- /dev/null +++ b/assets/js/9d275d72.0b08718a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53829],{42877:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter"},i="A Counter on an NCTL Network",a={id:"resources/beginner/counter/index",title:"Introduction",description:"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/index.md",sourceDirName:"resources/beginner/counter",slug:"/counter",permalink:"/1.5.X/counter",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/counter"},sidebar:"tutorials",previous:{title:"Getting Started",permalink:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial"},next:{title:"Overview",permalink:"/1.5.X/resources/beginner/counter/overview"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-an-nctl-network",children:"A Counter on an NCTL Network"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a ",(0,n.jsx)(t.a,{href:"/1.5.X/counter-testnet",children:"similar tutorial"}),". Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/1.5.X/resources/beginner/counter/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"NCTL tutorial"}),", which introduces you to the CLI tool to set up and control local Casper networks for development."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper client"})," to send deploys to the chain."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9d275d72.668b0bc7.js b/assets/js/9d275d72.668b0bc7.js deleted file mode 100644 index 16e3b6aef..000000000 --- a/assets/js/9d275d72.668b0bc7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3829],{42877:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter"},i="A Counter on an NCTL Network",a={id:"resources/beginner/counter/index",title:"Introduction",description:"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/index.md",sourceDirName:"resources/beginner/counter",slug:"/counter",permalink:"/counter",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction",slug:"/counter"},sidebar:"tutorials",previous:{title:"Getting Started",permalink:"/resources/tutorials/beginner/getting-started-tutorial"},next:{title:"Overview",permalink:"/resources/beginner/counter/overview"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-an-nctl-network",children:"A Counter on an NCTL Network"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a ",(0,n.jsx)(t.a,{href:"/counter-testnet",children:"similar tutorial"}),". Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"NCTL tutorial"}),", which introduces you to the CLI tool to set up and control local Casper networks for development."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})," to send deploys to the chain."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9dd9d4ea.3a5f592e.js b/assets/js/9dd9d4ea.3a5f592e.js new file mode 100644 index 000000000..4bfb09005 --- /dev/null +++ b/assets/js/9dd9d4ea.3a5f592e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19751],{41672:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>r,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>l,toc:()=>i});var n=s(74848),c=s(28453);const t={},a="B",l={id:"concepts/glossary/B",title:"B",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/B.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/B",permalink:"/2.0.0/concepts/glossary/B",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"A",permalink:"/2.0.0/concepts/glossary/A"},next:{title:"C",permalink:"/2.0.0/concepts/glossary/C"}},r={},i=[{value:"Blake2b",id:"blake2b",level:2},{value:"Block",id:"block",level:2},{value:"Block creation",id:"block-creation",level:2},{value:"Block finality",id:"block-finality",level:2},{value:"Block gossiping",id:"block-gossiping",level:2},{value:"Block height",id:"block-height",level:2},{value:"Block passing",id:"block-passing",level:2},{value:"Block processing",id:"block-processing",level:2},{value:"Block proposal",id:"block-proposal",level:2},{value:"Block validation",id:"block-validation",level:2},{value:"Blockchain",id:"blockchain",level:2},{value:"Block store",id:"block-store",level:2},{value:"Bond",id:"bond",level:2},{value:"Bonding",id:"bonding",level:2},{value:"Booking block",id:"booking-block",level:2}];function h(e){const o={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"b",children:"B"})}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsxs)(o.p,{children:[(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsx)(o.h2,{id:"blake2b",children:"Blake2b"}),"\n",(0,n.jsxs)(o.p,{children:["A function used within the Casper platform to create cryptographic ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/H#hash",children:"hashes"}),". More information can be found ",(0,n.jsx)(o.a,{href:"https://www.blake2.net/",children:"here"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block",children:"Block"}),"\n",(0,n.jsx)(o.p,{children:"Used in two contexts:"}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,n.jsx)(o.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,n.jsx)(o.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,n.jsx)(o.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,n.jsx)(o.h2,{id:"block-creation",children:"Block creation"}),"\n",(0,n.jsxs)(o.p,{children:["Block creation means computing the transaction results and collecting the results into a block. We follow a process called ",(0,n.jsx)(o.em,{children:"execution after consensus"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["The ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/B#block-proposal",children:"block proposal"})," happens first, and the proposed ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/P#proto-block",children:"proto block"})," contains a set of transactions that have not been executed yet."]}),"\n",(0,n.jsxs)(o.p,{children:["Only after consensus on a ",(0,n.jsx)(o.em,{children:"proto block"})," has been reached, the transactions are executed. The resulting new global state ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/R#root-hash",children:"root hash"})," is put into an actual block, together with the executed transactions."]}),"\n",(0,n.jsx)(o.p,{children:"Note that only validators can create valid blocks."}),"\n",(0,n.jsx)(o.h2,{id:"block-finality",children:"Block finality"}),"\n",(0,n.jsx)(o.p,{children:'A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.'}),"\n",(0,n.jsxs)(o.p,{children:["For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/E#eviction",children:"eviction"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"block-gossiping",children:"Block gossiping"}),"\n",(0,n.jsxs)(o.p,{children:["Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms ",(0,n.jsx)(o.em,{children:"block gossiping"})," and ",(0,n.jsx)(o.a,{href:"#block-passing",children:"block passing"})," are interchangeable."]}),"\n",(0,n.jsx)(o.h2,{id:"block-height",children:"Block height"}),"\n",(0,n.jsx)(o.p,{children:"Block height is an identifier for a given block based on the number of blocks completed prior to that block."}),"\n",(0,n.jsx)(o.h2,{id:"block-passing",children:"Block passing"}),"\n",(0,n.jsxs)(o.p,{children:["See ",(0,n.jsx)(o.a,{href:"#block-gossiping",children:"block gossiping"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-processing",children:"Block processing"}),"\n",(0,n.jsxs)(o.p,{children:["Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of ",(0,n.jsx)(o.a,{href:"#block-validation",children:"validating blocks"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-proposal",children:"Block proposal"}),"\n",(0,n.jsx)(o.p,{children:"Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only."}),"\n",(0,n.jsx)(o.h2,{id:"block-validation",children:"Block validation"}),"\n",(0,n.jsx)(o.p,{children:"The process of determining the validity of a block obtained from another node on the network."}),"\n",(0,n.jsx)(o.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,n.jsxs)(o.p,{children:["Blockchain is a P2P network where the collection of nodes (",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validators"}),") concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transactions"}),". For performance reasons, transactions are bundled in ",(0,n.jsx)(o.a,{href:"#block",children:"blocks"}),". According to a particular cooperation protocol (consensus protocol), the collection of ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/N#node",children:"nodes"})," connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"})," and has a sizeable map-like collection."]}),"\n",(0,n.jsx)(o.h2,{id:"block-store",children:"Block store"}),"\n",(0,n.jsx)(o.p,{children:"The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash."}),"\n",(0,n.jsx)(o.h2,{id:"bond",children:"Bond"}),"\n",(0,n.jsxs)(o.p,{children:["The amount of money (in crypto-currency) that is allocated by a node in order to participate in ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/C#consensus",children:"consensus"})," (and to be a ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validator"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"bonding",children:"Bonding"}),"\n",(0,n.jsxs)(o.p,{children:["Depositing money in the ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/A#auction-contract",children:"auction contract"})," and try to become a ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/S#staker",children:"staker"}),". The bonding request is a transaction that transfers tokens to the auction contract. In the next ",(0,n.jsx)(o.a,{href:"#booking-block",children:"booking block"}),", a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block."]}),"\n",(0,n.jsx)(o.h2,{id:"booking-block",children:"Booking block"}),"\n",(0,n.jsxs)(o.p,{children:["The booking block for an era is the block that determines the era's validator set. In it, the ",(0,n.jsx)(o.a,{href:"/2.0.0/concepts/glossary/A#auction-contract",children:"auction contract"})," selects the highest bidders to be the future era's validators. There is a configurable delay, the ",(0,n.jsx)(o.em,{children:"auction_delay"}),", which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era ",(0,n.jsx)(o.em,{children:"N + auction_delay + 1"})," is the last block of era ",(0,n.jsx)(o.em,{children:"N"}),"."]})]})}function d(e={}){const{wrapper:o}={...(0,c.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>a,x:()=>l});var n=s(96540);const c={},t=n.createContext(c);function a(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.426382ea.js b/assets/js/9e4087bc.426382ea.js new file mode 100644 index 000000000..36d7034f2 --- /dev/null +++ b/assets/js/9e4087bc.426382ea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52711],{89331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(96540);var a=t(28774),s=t(21312),n=t(45500),i=t(36266),c=t(79201),l=t(51107),o=t(74848);function d(e){let{year:r,posts:t}=e;const s=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,s.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,s.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,s.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},36266:(e,r,t)=>{t.d(r,{i:()=>s});var a=t(44586);function s(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/assets/js/9e4087bc.c84286d7.js b/assets/js/9e4087bc.c84286d7.js deleted file mode 100644 index 8c839655d..000000000 --- a/assets/js/9e4087bc.c84286d7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2711],{89331:(e,r,t)=>{t.r(r),t.d(r,{default:()=>m});t(96540);var a=t(28774),s=t(21312),n=t(45500),i=t(36266),c=t(79201),l=t(51107),o=t(74848);function d(e){let{year:r,posts:t}=e;const s=(0,i.i)({day:"numeric",month:"long",timeZone:"UTC"});return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(l.A,{as:"h3",id:r,children:r}),(0,o.jsx)("ul",{children:t.map((e=>{return(0,o.jsx)("li",{children:(0,o.jsxs)(a.A,{to:e.metadata.permalink,children:[(r=e.metadata.date,s.format(new Date(r)))," - ",e.metadata.title]})},e.metadata.date);var r}))})]})}function h(e){let{years:r}=e;return(0,o.jsx)("section",{className:"margin-vert--lg",children:(0,o.jsx)("div",{className:"container",children:(0,o.jsx)("div",{className:"row",children:r.map(((e,r)=>(0,o.jsx)("div",{className:"col col--4 margin-vert--lg",children:(0,o.jsx)(d,{...e})},r)))})})})}function m(e){let{archive:r}=e;const t=(0,s.T)({id:"theme.blog.archive.title",message:"Archive",description:"The page & hero title of the blog archive page"}),a=(0,s.T)({id:"theme.blog.archive.description",message:"Archive",description:"The page & hero description of the blog archive page"}),i=function(e){const r=e.reduce(((e,r)=>{const t=r.metadata.date.split("-")[0],a=e.get(t)??[];return e.set(t,[r,...a])}),new Map);return Array.from(r,(e=>{let[r,t]=e;return{year:r,posts:t}}))}(r.blogPosts);return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.be,{title:t,description:a}),(0,o.jsxs)(c.A,{children:[(0,o.jsx)("header",{className:"hero hero--primary",children:(0,o.jsxs)("div",{className:"container",children:[(0,o.jsx)(l.A,{as:"h1",className:"hero__title",children:t}),(0,o.jsx)("p",{className:"hero__subtitle",children:a})]})}),(0,o.jsx)("main",{children:i.length>0&&(0,o.jsx)(h,{years:i})})]})]})}},36266:(e,r,t)=>{t.d(r,{i:()=>s});var a=t(44586);function s(e){void 0===e&&(e={});const{i18n:{currentLocale:r}}=(0,a.A)(),t=function(){const{i18n:{currentLocale:e,localeConfigs:r}}=(0,a.A)();return r[e].calendar}();return new Intl.DateTimeFormat(r,{calendar:t,...e})}}}]); \ No newline at end of file diff --git a/assets/js/9ec4e3de.88035139.js b/assets/js/9ec4e3de.88035139.js new file mode 100644 index 000000000..eb695d382 --- /dev/null +++ b/assets/js/9ec4e3de.88035139.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[41865],{40848:e=>{e.exports=JSON.parse('{"tag":{"label":"docs-redux","permalink":"/blog/tags/docs-redux","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/docs-redux","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/9ed00072.851b8b22.js b/assets/js/9ed00072.851b8b22.js new file mode 100644 index 000000000..6fc52a798 --- /dev/null +++ b/assets/js/9ed00072.851b8b22.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60642],{29274:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Transfer Tokens",slug:"/users/token-transfer"},o="Transferring Tokens",a={id:"users/csprlive/token-transfer",title:"Transfer Tokens",description:"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.",source:"@site/docs/users/csprlive/token-transfer.md",sourceDirName:"users/csprlive",slug:"/users/token-transfer",permalink:"/users/token-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Transfer Tokens",slug:"/users/token-transfer"},sidebar:"users",previous:{title:"Undelegate Tokens",permalink:"/users/undelegate-ui"},next:{title:"Casper on Ledger",permalink:"/users/ledger/"}},l={},c=[{value:"Transferring Tokens",id:"transferring-tokens-1",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens",children:"Transferring Tokens"})}),"\n",(0,t.jsxs)(n.p,{children:["You can transfer Casper tokens (CSPR) using any ",(0,t.jsx)(n.a,{href:"/users/block-explorer",children:"block explorer"})," built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-tokens-1",children:"Transferring Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To transfer tokens, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Sign in to your account with the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Wallet"})," on the top menu bar and select ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"})," from the drop-down menu."]}),"\n",(0,t.jsx)(n.li,{children:"Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one."}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Next"})," to proceed."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transfer details",src:s(71728).A+"",width:"1248",height:"1698"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["A confirmation window appears to verify the details entered. Click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"})," to proceed to the next step."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirm transfer",src:s(96785).A+"",width:"1178",height:"1332"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Review the following important fields:"}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The Deploy hash, which uniquely identifies your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient public key of the person receiving your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient account hash used by the system to track the transaction"}),"\n",(0,t.jsx)(n.li,{children:"The Transfer Amount containing the value of the transfer"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Sign the transaction by selecting the ",(0,t.jsx)(n.strong,{children:"Sign with Casper Wallet"})," button to proceed to the next step."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Sign the transfer",src:s(13865).A+"",width:"1212",height:"1734"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,t.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click ',(0,t.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to complete the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transaction",src:s(21939).A+"",width:"2018",height:"1704"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"You completed the transaction and successfully transferred tokens."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transfer completed window",src:s(85197).A+"",width:"1210",height:"1396"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"View the updated CSPR balance in the account's main purse next."}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},71728:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1.transfer-details-52f3e9784bb7cdea4de42d410d030a7f.png"},96785:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2.confirm-transfer-a8905cf1c517bda6dca65fd328d32359.png"},13865:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3.sign-transfer-c9f0f40bb26b346cfe8cf2f6db848c4e.png"},21939:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4.wallet-window-34d341c968c49554406e732382b5f597.png"},85197:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5.transfer-completed-c913311be299c8d18915f0cbc5b447b0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9ed00072.861eaae3.js b/assets/js/9ed00072.861eaae3.js deleted file mode 100644 index 67f9cd468..000000000 --- a/assets/js/9ed00072.861eaae3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[642],{29274:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var s=t(74848),r=t(28453);const i={title:"Transfer Tokens",slug:"/users/token-transfer"},o="Transferring Tokens",a={id:"users/csprlive/token-transfer",title:"Transfer Tokens",description:"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.",source:"@site/docs/users/csprlive/token-transfer.md",sourceDirName:"users/csprlive",slug:"/users/token-transfer",permalink:"/next/users/token-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Transfer Tokens",slug:"/users/token-transfer"},sidebar:"users",previous:{title:"Undelegate Tokens",permalink:"/next/users/undelegate-ui"},next:{title:"Casper on Ledger",permalink:"/next/users/ledger/"}},l={},c=[{value:"Transferring Tokens",id:"transferring-tokens-1",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"transferring-tokens",children:"Transferring Tokens"})}),"\n",(0,s.jsxs)(n.p,{children:["You can transfer Casper tokens (CSPR) using any ",(0,s.jsx)(n.a,{href:"/next/users/block-explorer",children:"block explorer"})," built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens."]}),"\n",(0,s.jsx)(n.h2,{id:"transferring-tokens-1",children:"Transferring Tokens"}),"\n",(0,s.jsx)(n.p,{children:"To transfer tokens, follow these steps:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Sign in to your account with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Wallet"})," on the top menu bar and select ",(0,s.jsx)(n.strong,{children:"Transfer CSPR"})," from the drop-down menu."]}),"\n",(0,s.jsx)(n.li,{children:"Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one."}),"\n",(0,s.jsxs)(n.li,{children:["Click ",(0,s.jsx)(n.strong,{children:"Next"})," to proceed."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Transfer details",src:t(49102).A+"",width:"1248",height:"1698"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsxs)(n.li,{children:["A confirmation window appears to verify the details entered. Click ",(0,s.jsx)(n.strong,{children:"Confirm and transfer"})," to proceed to the next step."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Confirm transfer",src:t(52619).A+"",width:"1178",height:"1332"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsx)(n.li,{children:"Review the following important fields:"}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The Deploy hash, which uniquely identifies your transfer"}),"\n",(0,s.jsx)(n.li,{children:"The Recipient public key of the person receiving your transfer"}),"\n",(0,s.jsx)(n.li,{children:"The Recipient account hash used by the system to track the transaction"}),"\n",(0,s.jsx)(n.li,{children:"The Transfer Amount containing the value of the transfer"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Sign the transaction by selecting the ",(0,s.jsx)(n.strong,{children:"Sign with Casper Wallet"})," button to proceed to the next step."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sign the transfer",src:t(37495).A+"",width:"1212",height:"1734"})}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,s.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click ',(0,s.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to complete the transaction."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Review the transaction",src:t(39041).A+"",width:"2018",height:"1704"})}),"\n",(0,s.jsxs)(n.ol,{start:"8",children:["\n",(0,s.jsx)(n.li,{children:"You completed the transaction and successfully transferred tokens."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Transfer completed window",src:t(22159).A+"",width:"1210",height:"1396"})}),"\n",(0,s.jsxs)(n.ol,{start:"9",children:["\n",(0,s.jsx)(n.li,{children:"View the updated CSPR balance in the account's main purse next."}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},49102:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.transfer-details-52f3e9784bb7cdea4de42d410d030a7f.png"},52619:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.confirm-transfer-a8905cf1c517bda6dca65fd328d32359.png"},37495:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.sign-transfer-c9f0f40bb26b346cfe8cf2f6db848c4e.png"},39041:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.wallet-window-34d341c968c49554406e732382b5f597.png"},22159:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.transfer-completed-c913311be299c8d18915f0cbc5b447b0.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9ee7887a.3c988df8.js b/assets/js/9ee7887a.3c988df8.js new file mode 100644 index 000000000..e6355afd5 --- /dev/null +++ b/assets/js/9ee7887a.3c988df8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22473],{80156:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var r=s(74848),i=s(28453);const n={title:"Introduction"},o="The Native Multi-Signature Feature",a={id:"resources/advanced/multi-sig/index",title:"Introduction",description:"In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/index.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/",permalink:"/1.5.X/resources/advanced/multi-sig/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction"},sidebar:"tutorials",previous:{title:"Two-Party Multi-Sig",permalink:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig"},next:{title:"Multi-Sig Workflow",permalink:"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow"}},u={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-native-multi-signature-feature",children:"The Native Multi-Signature Feature"})}),"\n",(0,r.jsxs)(t.p,{children:["In this ",(0,r.jsx)(t.a,{href:"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow",children:"tutorial"}),", you will use ",(0,r.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#accounts-permissions",children:"Casper's permissions model"})," to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/1.5.X/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," present use cases where Casper's multi-signature feature would be helpful."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var r=s(96540);const i={},n=r.createContext(i);function o(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9ee7887a.a80b72fc.js b/assets/js/9ee7887a.a80b72fc.js deleted file mode 100644 index 2ba5845ef..000000000 --- a/assets/js/9ee7887a.a80b72fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2473],{80156:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var r=s(74848),i=s(28453);const n={title:"Introduction"},o="The Native Multi-Signature Feature",a={id:"resources/advanced/multi-sig/index",title:"Introduction",description:"In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/index.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/",permalink:"/resources/advanced/multi-sig/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Introduction"},sidebar:"tutorials",previous:{title:"Two-Party Multi-Sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig"},next:{title:"Multi-Sig Workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow"}},u={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-native-multi-signature-feature",children:"The Native Multi-Signature Feature"})}),"\n",(0,r.jsxs)(t.p,{children:["In this ",(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/multi-sig-workflow",children:"tutorial"}),", you will use ",(0,r.jsx)(t.a,{href:"/concepts/design/casper-design#accounts-permissions",children:"Casper's permissions model"})," to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," present use cases where Casper's multi-signature feature would be helpful."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var r=s(96540);const i={},n=r.createContext(i);function o(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a024ab51.21c9b95c.js b/assets/js/a024ab51.21c9b95c.js new file mode 100644 index 000000000..aa2fa3b35 --- /dev/null +++ b/assets/js/a024ab51.21c9b95c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[90613],{26773:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>a,toc:()=>h});var t=n(74848),i=n(28453);const r={title:"URef Access Rights"},c="URef Access Rights and Security Considerations",a={id:"developers/dapps/uref-security",title:"URef Access Rights",description:"Understanding Access Rights",source:"@site/versioned_docs/version-2.0.0/developers/dapps/uref-security.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/uref-security",permalink:"/2.0.0/developers/dapps/uref-security",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"URef Access Rights"},sidebar:"developers",previous:{title:"Front-end in React",permalink:"/2.0.0/developers/dapps/template-frontend"},next:{title:"Signing Transactions",permalink:"/2.0.0/developers/dapps/signing-a-transaction"}},d={},h=[{value:"Understanding Access Rights",id:"understanding-access-rights",level:2},{value:"AccessRights and Purses",id:"accessrights-and-purses",level:2},{value:"Security Considerations for dApp Developers",id:"security-considerations-for-dapp-developers",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"uref-access-rights-and-security-considerations",children:"URef Access Rights and Security Considerations"})}),"\n",(0,t.jsx)(s.h2,{id:"understanding-access-rights",children:"Understanding Access Rights"}),"\n",(0,t.jsxs)(s.p,{children:["An ",(0,t.jsx)(s.a,{href:"/concepts/design/casper-design/#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(s.strong,{children:"URef"})," is a key type used for storage on a Casper network. They can store any value other than ",(0,t.jsx)(s.code,{children:"Account"})," and exist as a top-level entity. As such, no individual entity may ",(0,t.jsx)(s.em,{children:"own"})," a URef, they can only hold the necessary ",(0,t.jsx)(s.code,{children:"AccessRights"})," to interact with a given URef."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,t.jsx)(s.code,{children:"AccessRights"})})," determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And this is the same URef with ",(0,t.jsx)(s.code,{children:"READ"})," and ",(0,t.jsx)(s.code,{children:"ADD"})," access rights."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The following table outlines all possible ",(0,t.jsx)(s.code,{children:"AccessRights"})," settings:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Access Rights"}),(0,t.jsx)(s.th,{children:"Serialization"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"NONE"})}),(0,t.jsx)(s.td,{children:"0"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ"})}),(0,t.jsx)(s.td,{children:"1"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"WRITE"})}),(0,t.jsx)(s.td,{children:"2"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_WRITE"})}),(0,t.jsx)(s.td,{children:"3"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD"})}),(0,t.jsx)(s.td,{children:"4"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD"})}),(0,t.jsx)(s.td,{children:"5"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"6"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"7"})]})]})]}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["Any access rights granted alongside a passed URef are ",(0,t.jsx)(s.em,{children:(0,t.jsx)(s.strong,{children:"irrevocable"})}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"accessrights-and-purses",children:"AccessRights and Purses"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"Purse"})," is a unique type of ",(0,t.jsx)(s.code,{children:"URef"})," representing a token balance. Each ",(0,t.jsx)(s.code,{children:"Addressable Entity"})," will have an associated URef that represents its main purse. Account and contract entities may have additional purses."]}),"\n",(0,t.jsx)(s.p,{children:"For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Global State"}),(0,t.jsx)(s.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Add"}),(0,t.jsx)(s.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Write"}),(0,t.jsx)(s.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Read"}),(0,t.jsx)(s.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"security-considerations-for-dapp-developers",children:"Security Considerations for dApp Developers"}),"\n",(0,t.jsxs)(s.p,{children:["When developing a ",(0,t.jsx)(s.a,{href:"/developers/dapps/dapp/",children:"dApp"})," that interacts with tokens in any way, it will be necessary to work with various URef ",(0,t.jsx)(s.code,{children:"AccessRights"})," for associated purse URefs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract/",children:"This tutorial outlines our recommendations when transferring tokens to a contract."})}),"\n",(0,t.jsxs)(s.p,{children:["When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate ",(0,t.jsx)(s.code,{children:"AccessRights"}),". The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the ",(0,t.jsx)(s.code,{children:"new_uref"})," should be passed to another entity."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-js",children:"// This example will create a version of the original URef with access rights stripped entirely.\nlet new_uref = uref.with_access_rights(AccessRights::NONE);\n// This example will create a version of the original URef with only READ access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ);\n// This example will create a version of the original URef with only WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::WRITE);\n// This example will create a version of the original URef with both READ and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_WRITE);\n// This example will create a version of the original URef with only ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD);\n// This example will create a version of the original URef with both READ and ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD);\n// This example will create a version of the original URef with both ADD and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);\n// This example will create a version of the original URef with full access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function c(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a03c4947.715ecbfc.js b/assets/js/a03c4947.715ecbfc.js deleted file mode 100644 index 8fe4187e9..000000000 --- a/assets/js/a03c4947.715ecbfc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1368],{24311:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=i(74848),a=i(28453);const r={title:"Dictionaries"},s="Understanding Dictionaries {#dictionaries}",o={id:"concepts/dictionaries",title:"Dictionaries",description:"dictionaries}",source:"@site/versioned_docs/version-1.5.X/concepts/dictionaries.md",sourceDirName:"concepts",slug:"/concepts/dictionaries",permalink:"/concepts/dictionaries",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Dictionaries"},sidebar:"concepts",previous:{title:"Call Stacks",permalink:"/concepts/callstack"},next:{title:"Serialization Standard",permalink:"/concepts/serialization-standard"}},c={},d=[{value:"Seed URefs",id:"seed-urefs",level:2},{value:"Using Dictionaries",id:"using-dictionaries",level:2},{value:"Practical Dictionary Examples",id:"practical-dictionary-examples",level:2},{value:"Creating Dictionaries in a Contract's Context",id:"creating-dictionaries-in-a-contracts-context",level:2},{value:"Writing Entries into a Dictionary",id:"writing-entries-into-a-dictionary",level:2},{value:"Reading Items from a Dictionary using the JSON-RPC",id:"reading-items-from-a-dictionary-using-the-json-rpc",level:2},{value:"<code>ContractNamedKey</code> lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"<code>URef</code> lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"<code>Dictionary</code> lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"dictionaries",children:"Understanding Dictionaries"})}),"\n",(0,n.jsxs)(t.p,{children:["In a Casper network, you can now store sets of data under ",(0,n.jsx)(t.a,{href:"/concepts/hash-types#hash-and-key-explanations",children:(0,n.jsx)(t.code,{children:"Keys"})}),". Previously, ",(0,n.jsx)(t.a,{href:"/concepts/glossary/U#uref",children:"URefs"})," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,n.jsx)(t.code,{children:"Account"})," or ",(0,n.jsx)(t.code,{children:"Contract"})," context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,n.jsx)(t.a,{href:"/concepts/glossary/N#named-keys",children:"NamedKeys"})," structures."]}),"\n",(0,n.jsx)(t.p,{children:"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."}),"\n",(0,n.jsxs)(t.p,{children:["As a solution to this problem, the Casper platform provides the ",(0,n.jsx)(t.code,{children:"Dictionary"})," feature, which allows users a more efficient and scalable means to aggregate data over time."]}),"\n",(0,n.jsx)(t.p,{children:"In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost."}),"\n",(0,n.jsx)(t.h2,{id:"seed-urefs",children:"Seed URefs"}),"\n",(0,n.jsxs)(t.p,{children:["Items within a dictionary exist as individual records stored underneath their unique ",(0,n.jsx)(t.a,{href:"/concepts/hash-types#hash-and-key-explanations",children:"dictionary address"})," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,n.jsx)(t.a,{href:"/concepts/design/casper-design#uref-head",children:(0,n.jsx)(t.code,{children:"URef"})})," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."]}),"\n",(0,n.jsx)(t.p,{children:"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."}),"\n",(0,n.jsx)(t.h2,{id:"using-dictionaries",children:"Using Dictionaries"}),"\n",(0,n.jsxs)(t.p,{children:["Dictionaries are ideal for storing larger volumes of data for which ",(0,n.jsx)(t.code,{children:"NamedKeys"})," would be less suitable."]}),"\n",(0,n.jsxs)(t.p,{children:["Creating a new dictionary is fairly simple and done within the context of a ",(0,n.jsx)(t.code,{children:"Deploy"})," sent to a Casper network. The associated code is included within the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:(0,n.jsx)(t.code,{children:"casper_contract"})})," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."]}),"\n",(0,n.jsx)(t.p,{children:"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract."}),"\n",(0,n.jsxs)(t.p,{children:["While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,n.jsx)(t.code,{children:"Deploy"})," removing those access rights, but it is better to create the dictionary within the context of the Contract."]}),"\n",(0,n.jsxs)(t.p,{children:["Dictionaries allow a contract to store additional data without drastically expanding the size of the ",(0,n.jsx)(t.code,{children:"NamedKeys"})," within their context. If a contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," expand too far, they may run into system limitations that would unintentionally disable the contract's functionality."]}),"\n",(0,n.jsx)(t.p,{children:"A dictionary item key can be no longer than 64 bytes in length."}),"\n",(0,n.jsx)(t.h2,{id:"practical-dictionary-examples",children:"Practical Dictionary Examples"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"Casper CEP-78 Enhanced NFT Standard"})," includes several practical applications of dictionaries."]}),"\n",(0,n.jsxs)(t.p,{children:["Simple examples for dictionary use within CEP-78 include the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772",children:(0,n.jsx)(t.code,{children:"approve"})})," dictionary."]}),"\n",(0,n.jsxs)(t.p,{children:["More advanced dictionary functionality can be found in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/reverse-lookup.md#the-cep-78-page-system",children:"CEP-78 Page System"}),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."]}),"\n",(0,n.jsx)(t.h2,{id:"creating-dictionaries-in-a-contracts-context",children:"Creating Dictionaries in a Contract's Context"}),"\n",(0,n.jsx)(t.p,{children:"The following code snippet shows the most basic example of creating a dictionary."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The following example includes the creation of a dictionary ",(0,n.jsx)(t.code,{children:'"ledger"'})," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,n.jsx)(t.code,{children:"init"})," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n'})}),"\n",(0,n.jsx)(t.h2,{id:"writing-entries-into-a-dictionary",children:"Writing Entries into a Dictionary"}),"\n",(0,n.jsx)(t.p,{children:"After the creation of a dictionary, you may then add entries through the use of the following code:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"dictionary_uref"})," refers to the seed URef established during the dictionary creation process. The ",(0,n.jsx)(t.code,{children:"key"})," is the unique identifier for this dictionary item, and the ",(0,n.jsx)(t.code,{children:"value"})," is the data to be stored within the dictionary."]}),"\n",(0,n.jsx)(t.p,{children:"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."}),"\n",(0,n.jsx)(t.p,{children:"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."}),"\n",(0,n.jsxs)(t.p,{children:["The first section acquiring the ",(0,n.jsx)(t.code,{children:"LEDGER"})," seed URef to assign the new dictionary item to the proper dictionary."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n'})}),"\n",(0,n.jsxs)(t.p,{children:["The second section uses ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:(0,n.jsx)(t.code,{children:"dictionary_get"})})," to read an entry within the ",(0,n.jsx)(t.code,{children:"LEDGER"})," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:(0,n.jsx)(t.code,{children:"dictionary_put"})})," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n"})}),"\n",(0,n.jsx)(t.h2,{id:"reading-items-from-a-dictionary-using-the-json-rpc",children:"Reading Items from a Dictionary using the JSON-RPC"}),"\n",(0,n.jsxs)(t.p,{children:["The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,n.jsx)(t.a,{href:"/developers/json-rpc/types_chain#dictionaryidentifier",children:(0,n.jsx)(t.code,{children:"DictionaryIdentifier"})})," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-client",children:"Casper client"}),"."]}),"\n",(0,n.jsxs)(t.h3,{id:"contractnamedkey-lookup-via-a-contracts-named-keys",children:[(0,n.jsx)(t.code,{children:"ContractNamedKey"})," lookup via a Contract's named keys."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," requires the following parameters:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Node Address"})," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"State Root Hash"})," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Contract Hash"})," - The hash of the contract that references the dictionary in its ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Name"})," - The name of the dictionary as a ",(0,n.jsx)(t.code,{children:"String"})," stored in the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," - The specific dictionary item key to be read, as a ",(0,n.jsx)(t.code,{children:"String"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name <String> \\\n --dictionary-item-key <String>\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"uref-lookup-via-the-dictionarys-seed-uref",children:[(0,n.jsx)(t.code,{children:"URef"})," lookup via the dictionary's seed URef."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the dictionary's seed URef requires the ",(0,n.jsx)(t.code,{children:"Node Address"}),", ",(0,n.jsx)(t.code,{children:"State Root Hash"})," and ",(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," as above. However, it does not require the ",(0,n.jsx)(t.code,{children:"Contract Hash"})," or ",(0,n.jsx)(t.code,{children:"Dictionary Name"}),". Instead, it requires:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"Seed URef"})," - The ",(0,n.jsx)(t.a,{href:"#seed-urefs",children:"Seed URef"})," of the dictionary to reference."]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key <String> \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"dictionary-lookup-via-the-unique-dictionary-item-key",children:[(0,n.jsx)(t.code,{children:"Dictionary"})," lookup via the unique dictionary item key."]}),"\n",(0,n.jsxs)(t.p,{children:["In the event that you know the ",(0,n.jsx)(t.code,{children:"dictionary address"})," of the dictionary item key you need to read, you can read it directly using the following Casper client command."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-<string>\n\n"})})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var n=i(96540);const a={},r=n.createContext(a);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a03c4947.b024c0ac.js b/assets/js/a03c4947.b024c0ac.js new file mode 100644 index 000000000..62031a122 --- /dev/null +++ b/assets/js/a03c4947.b024c0ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61368],{24311:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=i(74848),a=i(28453);const r={title:"Dictionaries"},s="Understanding Dictionaries {#dictionaries}",o={id:"concepts/dictionaries",title:"Dictionaries",description:"dictionaries}",source:"@site/versioned_docs/version-1.5.X/concepts/dictionaries.md",sourceDirName:"concepts",slug:"/concepts/dictionaries",permalink:"/1.5.X/concepts/dictionaries",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Dictionaries"},sidebar:"concepts",previous:{title:"Call Stacks",permalink:"/1.5.X/concepts/callstack"},next:{title:"Serialization Standard",permalink:"/1.5.X/concepts/serialization-standard"}},c={},d=[{value:"Seed URefs",id:"seed-urefs",level:2},{value:"Using Dictionaries",id:"using-dictionaries",level:2},{value:"Practical Dictionary Examples",id:"practical-dictionary-examples",level:2},{value:"Creating Dictionaries in a Contract's Context",id:"creating-dictionaries-in-a-contracts-context",level:2},{value:"Writing Entries into a Dictionary",id:"writing-entries-into-a-dictionary",level:2},{value:"Reading Items from a Dictionary using the JSON-RPC",id:"reading-items-from-a-dictionary-using-the-json-rpc",level:2},{value:"<code>ContractNamedKey</code> lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"<code>URef</code> lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"<code>Dictionary</code> lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"dictionaries",children:"Understanding Dictionaries"})}),"\n",(0,n.jsxs)(t.p,{children:["In a Casper network, you can now store sets of data under ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/hash-types#hash-and-key-explanations",children:(0,n.jsx)(t.code,{children:"Keys"})}),". Previously, ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/glossary/U#uref",children:"URefs"})," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,n.jsx)(t.code,{children:"Account"})," or ",(0,n.jsx)(t.code,{children:"Contract"})," context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/glossary/N#named-keys",children:"NamedKeys"})," structures."]}),"\n",(0,n.jsx)(t.p,{children:"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."}),"\n",(0,n.jsxs)(t.p,{children:["As a solution to this problem, the Casper platform provides the ",(0,n.jsx)(t.code,{children:"Dictionary"})," feature, which allows users a more efficient and scalable means to aggregate data over time."]}),"\n",(0,n.jsx)(t.p,{children:"In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost."}),"\n",(0,n.jsx)(t.h2,{id:"seed-urefs",children:"Seed URefs"}),"\n",(0,n.jsxs)(t.p,{children:["Items within a dictionary exist as individual records stored underneath their unique ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/hash-types#hash-and-key-explanations",children:"dictionary address"})," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#uref-head",children:(0,n.jsx)(t.code,{children:"URef"})})," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."]}),"\n",(0,n.jsx)(t.p,{children:"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."}),"\n",(0,n.jsx)(t.h2,{id:"using-dictionaries",children:"Using Dictionaries"}),"\n",(0,n.jsxs)(t.p,{children:["Dictionaries are ideal for storing larger volumes of data for which ",(0,n.jsx)(t.code,{children:"NamedKeys"})," would be less suitable."]}),"\n",(0,n.jsxs)(t.p,{children:["Creating a new dictionary is fairly simple and done within the context of a ",(0,n.jsx)(t.code,{children:"Deploy"})," sent to a Casper network. The associated code is included within the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:(0,n.jsx)(t.code,{children:"casper_contract"})})," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."]}),"\n",(0,n.jsx)(t.p,{children:"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract."}),"\n",(0,n.jsxs)(t.p,{children:["While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,n.jsx)(t.code,{children:"Deploy"})," removing those access rights, but it is better to create the dictionary within the context of the Contract."]}),"\n",(0,n.jsxs)(t.p,{children:["Dictionaries allow a contract to store additional data without drastically expanding the size of the ",(0,n.jsx)(t.code,{children:"NamedKeys"})," within their context. If a contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," expand too far, they may run into system limitations that would unintentionally disable the contract's functionality."]}),"\n",(0,n.jsx)(t.p,{children:"A dictionary item key can be no longer than 64 bytes in length."}),"\n",(0,n.jsx)(t.h2,{id:"practical-dictionary-examples",children:"Practical Dictionary Examples"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"Casper CEP-78 Enhanced NFT Standard"})," includes several practical applications of dictionaries."]}),"\n",(0,n.jsxs)(t.p,{children:["Simple examples for dictionary use within CEP-78 include the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772",children:(0,n.jsx)(t.code,{children:"approve"})})," dictionary."]}),"\n",(0,n.jsxs)(t.p,{children:["More advanced dictionary functionality can be found in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/reverse-lookup.md#the-cep-78-page-system",children:"CEP-78 Page System"}),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."]}),"\n",(0,n.jsx)(t.h2,{id:"creating-dictionaries-in-a-contracts-context",children:"Creating Dictionaries in a Contract's Context"}),"\n",(0,n.jsx)(t.p,{children:"The following code snippet shows the most basic example of creating a dictionary."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The following example includes the creation of a dictionary ",(0,n.jsx)(t.code,{children:'"ledger"'})," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,n.jsx)(t.code,{children:"init"})," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n'})}),"\n",(0,n.jsx)(t.h2,{id:"writing-entries-into-a-dictionary",children:"Writing Entries into a Dictionary"}),"\n",(0,n.jsx)(t.p,{children:"After the creation of a dictionary, you may then add entries through the use of the following code:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"dictionary_uref"})," refers to the seed URef established during the dictionary creation process. The ",(0,n.jsx)(t.code,{children:"key"})," is the unique identifier for this dictionary item, and the ",(0,n.jsx)(t.code,{children:"value"})," is the data to be stored within the dictionary."]}),"\n",(0,n.jsx)(t.p,{children:"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."}),"\n",(0,n.jsx)(t.p,{children:"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."}),"\n",(0,n.jsxs)(t.p,{children:["The first section acquiring the ",(0,n.jsx)(t.code,{children:"LEDGER"})," seed URef to assign the new dictionary item to the proper dictionary."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n'})}),"\n",(0,n.jsxs)(t.p,{children:["The second section uses ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:(0,n.jsx)(t.code,{children:"dictionary_get"})})," to read an entry within the ",(0,n.jsx)(t.code,{children:"LEDGER"})," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:(0,n.jsx)(t.code,{children:"dictionary_put"})})," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n"})}),"\n",(0,n.jsx)(t.h2,{id:"reading-items-from-a-dictionary-using-the-json-rpc",children:"Reading Items from a Dictionary using the JSON-RPC"}),"\n",(0,n.jsxs)(t.p,{children:["The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,n.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_chain#dictionaryidentifier",children:(0,n.jsx)(t.code,{children:"DictionaryIdentifier"})})," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-client",children:"Casper client"}),"."]}),"\n",(0,n.jsxs)(t.h3,{id:"contractnamedkey-lookup-via-a-contracts-named-keys",children:[(0,n.jsx)(t.code,{children:"ContractNamedKey"})," lookup via a Contract's named keys."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," requires the following parameters:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Node Address"})," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"State Root Hash"})," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Contract Hash"})," - The hash of the contract that references the dictionary in its ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Name"})," - The name of the dictionary as a ",(0,n.jsx)(t.code,{children:"String"})," stored in the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," - The specific dictionary item key to be read, as a ",(0,n.jsx)(t.code,{children:"String"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name <String> \\\n --dictionary-item-key <String>\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"uref-lookup-via-the-dictionarys-seed-uref",children:[(0,n.jsx)(t.code,{children:"URef"})," lookup via the dictionary's seed URef."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the dictionary's seed URef requires the ",(0,n.jsx)(t.code,{children:"Node Address"}),", ",(0,n.jsx)(t.code,{children:"State Root Hash"})," and ",(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," as above. However, it does not require the ",(0,n.jsx)(t.code,{children:"Contract Hash"})," or ",(0,n.jsx)(t.code,{children:"Dictionary Name"}),". Instead, it requires:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"Seed URef"})," - The ",(0,n.jsx)(t.a,{href:"#seed-urefs",children:"Seed URef"})," of the dictionary to reference."]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key <String> \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"dictionary-lookup-via-the-unique-dictionary-item-key",children:[(0,n.jsx)(t.code,{children:"Dictionary"})," lookup via the unique dictionary item key."]}),"\n",(0,n.jsxs)(t.p,{children:["In the event that you know the ",(0,n.jsx)(t.code,{children:"dictionary address"})," of the dictionary item key you need to read, you can read it directly using the following Casper client command."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-<string>\n\n"})})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>s,x:()=>o});var n=i(96540);const a={},r=n.createContext(a);function s(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a0ccdbb2.9cb4eb73.js b/assets/js/a0ccdbb2.9cb4eb73.js new file mode 100644 index 000000000..94bd21c4e --- /dev/null +++ b/assets/js/a0ccdbb2.9cb4eb73.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9460],{72407:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>d,metadata:()=>c,toc:()=>h});var s=t(74848),r=t(28453);const d={title:"The Chainspec"},i="The Blockchain Specification {#the-chain-specification}",c={id:"operators/setup-network/chain-spec",title:"The Chainspec",description:"the-chain-specification}",source:"@site/docs/operators/setup-network/chain-spec.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/chain-spec",permalink:"/operators/setup-network/chain-spec",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"The Chainspec"},sidebar:"operators",previous:{title:"Genesis",permalink:"/operators/setup-network/genesis"},next:{title:"Private Network Setup",permalink:"/operators/setup-network/create-private"}},l={},h=[{value:"protocol",id:"protocol",level:2},{value:"network",id:"network",level:2},{value:"core",id:"core",level:2},{value:"highway",id:"highway",level:2},{value:"transactions",id:"transactions",level:2},{value:"transactions.v1",id:"transactionsv1",level:3},{value:"transactions.deploy",id:"transactionsdeploy",level:3},{value:"wasm",id:"wasm",level:2},{value:"wasm.storage_costs",id:"wasmstorage_costs",level:3},{value:"wasm.opcode_costs",id:"wasmopcode_costs",level:3},{value:"wasm.opcode_costs.control_flow",id:"wasmopcode_costscontrol_flow",level:3},{value:"wasm.opcode_costs.control_flow.br_table",id:"wasmopcode_costscontrol_flowbr_table",level:3},{value:"wasm.messages_limits",id:"wasmmessages_limits",level:2},{value:"wasm.host_function_costs",id:"wasmhost_function_costs",level:3},{value:"system_costs",id:"system_costs",level:2},{value:"system_costs.auction_costs",id:"system_costsauction_costs",level:3},{value:"system_costs.mint_costs",id:"system_costsmint_costs",level:3},{value:"system_costs.handle_payment_costs",id:"system_costshandle_payment_costs",level:3},{value:"system_costs.standard_payment_costs",id:"system_costsstandard_payment_costs",level:3}];function o(n){const e={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"the-chain-specification",children:"The Blockchain Specification"})}),"\n",(0,s.jsxs)(e.p,{children:["The blockchain specification, or ",(0,s.jsx)(e.code,{children:"chainspec"}),", is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 2.0.0 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring. "]}),"\n",(0,s.jsx)(e.h2,{id:"protocol",children:"protocol"}),"\n",(0,s.jsx)(e.p,{children:"These settings describe the active protocol version."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"version"}),(0,s.jsx)(e.td,{children:"The Casper node protocol version."}),(0,s.jsx)(e.td,{children:"'2.0.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"hard_reset"}),(0,s.jsx)(e.td,{children:"When set to true, clear blocks and transactions back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activation_point"}),(0,s.jsxs)(e.td,{children:["The protocol version that should become active. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 \u2014 see the ",(0,s.jsx)(e.code,{children:"finality_threshold_fraction"})," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."]}),(0,s.jsx)(e.td,{children:"11100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"network",children:"network"}),"\n",(0,s.jsx)(e.p,{children:"The following settings configure the networking layer."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"name"}),(0,s.jsx)(e.td,{children:"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."}),(0,s.jsx)(e.td,{children:"'casper'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_net_message_size"}),(0,s.jsx)(e.td,{children:"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."}),(0,s.jsx)(e.td,{children:"25_165_824"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"core",children:"core"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage the core protocol behavior."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"era_duration"}),(0,s.jsx)(e.td,{children:"Era duration."}),(0,s.jsx)(e.td,{children:"'120 minutes'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_era_height"}),(0,s.jsxs)(e.td,{children:["Minimum number of blocks per era. An era will take longer than ",(0,s.jsx)(e.code,{children:"era_duration"})," if that is necessary to reach the minimum height."]}),(0,s.jsx)(e.td,{children:"20"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_block_time"}),(0,s.jsx)(e.td,{children:"Minimum difference between a block's and its child's timestamp."}),(0,s.jsx)(e.td,{children:"'16384 ms'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_slots"}),(0,s.jsx)(e.td,{children:"Number of slots available in the validator auction."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_threshold_fraction"}),(0,s.jsxs)(e.td,{children:["A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,s.jsx)(e.br,{}),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,s.jsx)(e.br,{}),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."]}),(0,s.jsx)(e.td,{children:"[1, 3]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsxs)(e.td,{children:["start_protocol_version_with_strict",(0,s.jsx)(e.br,{}),"_finality_signatures_required"]}),(0,s.jsx)(e.td,{children:"Protocol version from which nodes are required to hold strict finality signatures."}),(0,s.jsx)(e.td,{children:"'1.5.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"legacy_required_finality"}),(0,s.jsxs)(e.td,{children:["The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,s.jsx)(e.br,{}),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."]}),(0,s.jsx)(e.td,{children:"'Strict'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_accounts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user accounts to addressable entity. If false, user accounts will be left as they are and will be lazily migrated on a per-account basis if / when that account is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_contracts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user contracts to addressable entity. If false, user contracts will be left as they are and will be lazily migrated on a per-contract basis if / when that contract is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"auction_delay"}),(0,s.jsx)(e.td,{children:"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."}),(0,s.jsx)(e.td,{children:"1"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"locked_funds_period"}),(0,s.jsx)(e.td,{children:"The period after genesis during which a genesis validator's bid is locked."}),(0,s.jsx)(e.td,{children:"'0 days'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"vesting_schedule_period"}),(0,s.jsx)(e.td,{children:"The period in which the genesis validator's bid is released over time after it is unlocked."}),(0,s.jsx)(e.td,{children:"'0 weeks'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unbonding_delay"}),(0,s.jsx)(e.td,{children:"Default number of eras that need to pass to be able to withdraw unbonded funds."}),(0,s.jsx)(e.td,{children:"7"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"round_seigniorage_rate"}),(0,s.jsxs)(e.td,{children:["Round seigniorage rate represented as a fraction of the total supply.",(0,s.jsx)(e.br,{}),"- Annual issuance: 8%.",(0,s.jsx)(e.br,{}),"- Minimum block time: 2^15 milliseconds.",(0,s.jsx)(e.br,{}),"- Ticks per year: 31536000000.",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.code,{children:"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)"})]}),(0,s.jsx)(e.td,{children:"[7, 175070816]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_associated_keys"}),(0,s.jsx)(e.td,{children:"Maximum number of associated keys for a single account."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_runtime_call_stack_height"}),(0,s.jsx)(e.td,{children:"Maximum height of the contract runtime call stack."}),(0,s.jsx)(e.td,{children:"12"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Minimum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"500_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Maximum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"1_000_000_000_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"prune_batch_size"}),(0,s.jsxs)(e.td,{children:["Global state prune batch size for tip pruning. Possible values:",(0,s.jsx)(e.br,{}),"- 0 when the feature is OFF",(0,s.jsx)(e.br,{}),"- Integer if the feature is ON, representing the number of eras to process per block."]}),(0,s.jsx)(e.td,{children:"0"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"strict_argument_checking"}),(0,s.jsxs)(e.td,{children:["Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,s.jsx)(e.code,{children:"CLType"}),"."]}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"simultaneous_peer_requests"}),(0,s.jsx)(e.td,{children:"Number of simultaneous peer requests."}),(0,s.jsx)(e.td,{children:"5"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"consensus_protocol"}),(0,s.jsx)(e.td,{children:"The consensus protocol to use. Options are 'Zug' or 'Highway'."}),(0,s.jsx)(e.td,{children:"'Zug'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_delegators_per_validator"}),(0,s.jsx)(e.td,{children:"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."}),(0,s.jsx)(e.td,{children:"1200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finders_fee"}),(0,s.jsx)(e.td,{children:"The split in finality signature rewards between block producer and participating signers."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_signature_proportion"}),(0,s.jsx)(e.td,{children:"The proportion of baseline rewards going to reward finality signatures specifically."}),(0,s.jsx)(e.td,{children:"[1, 2]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"signature_rewards_max_delay"}),(0,s.jsx)(e.td,{children:"Lookback interval indicating how many past blocks we are looking at to reward."}),(0,s.jsx)(e.td,{children:"3"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_unrestricted_transfers"}),(0,s.jsx)(e.td,{children:"Allows peer to peer transfers between users. Setting this to false makes sense only for private chains."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_auction_bids"}),(0,s.jsx)(e.td,{children:"Enables the auction entry points 'delegate' and 'add_bid'. Setting this to false makes sense only for private chains that don't need to auction new validator slots. These auction entry points will return an error if called, when this option is set to false."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"compute_rewards"}),(0,s.jsx)(e.td,{children:"If set to false, then consensus doesn't compute rewards and always uses 0."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"refund_handling"}),(0,s.jsx)(e.td,{children:"Defines how refunds of the unused portion of payment amounts are calculated and handled. Valid options are: refund (a ratio of the unspent token is returned to the spender); burn (a ratio of the unspent token is burned); no_refund (no refunds are paid out)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_refund' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"fee_handling"}),(0,s.jsx)(e.td,{children:"Defines how fees are handled. Valid options are: no_fee (fees are eliminated); pay_to_proposer (fees are paid to the block proposer); accumulate (fees are accumulated in a special purse and distributed at the end of each era evenly among all administrator accounts); burn (fees are burned)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_fee' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_credit_cap"}),(0,s.jsx)(e.td,{children:"If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pricing_handling"}),(0,s.jsx)(e.td,{children:"Defines how pricing is handled. Valid options are: classic (senders of transaction self-specify how much they pay); fixed (costs are fixed, per the cost table); reserved (prepaid transaction, currently not supported)"}),(0,s.jsx)(e.td,{children:"{ type = 'fixed' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_reservations"}),(0,s.jsx)(e.td,{children:"Does the network allow pre-payment / reservations for future execution? Currently not supported."}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_balance_handling"}),(0,s.jsx)(e.td,{children:"Defines how gas holds affect available balance calculations. Valid options are: accrued (sum of full value of all non-expired holds) and amortized (sum of each hold is amortized over the time remaining until expiry)."}),(0,s.jsx)(e.td,{children:"{ type = 'accrued' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_interval"}),(0,s.jsx)(e.td,{children:"Defines how long gas holds last."}),(0,s.jsx)(e.td,{children:"'24 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"administrators"}),(0,s.jsx)(e.td,{children:"List of public keys of administrator accounts. Setting this option makes only on private chains which require administrator accounts for regulatory reasons."}),(0,s.jsx)(e.td,{children:"[]"})]})]})]}),"\n",(0,s.jsxs)(e.p,{children:["See the ",(0,s.jsx)(e.a,{href:"/concepts/economics/fee-elimination",children:"Fee Elimination"})," page for more details regarding ",(0,s.jsx)(e.code,{children:"refund_handling"}),", ",(0,s.jsx)(e.code,{children:"fee_handling"}),", ",(0,s.jsx)(e.code,{children:"validator_credit_cap"}),", ",(0,s.jsx)(e.code,{children:"pricing_handling"}),", ",(0,s.jsx)(e.code,{children:"gas_hold_balance_handling"}),", and ",(0,s.jsx)(e.code,{children:"gas_hold_interval"}),"."]}),"\n",(0,s.jsx)(e.h2,{id:"highway",children:"highway"}),"\n",(0,s.jsx)(e.p,{children:"These settings configure the Highway Consensus protocol."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_round_length"}),(0,s.jsxs)(e.td,{children:["Highway dynamically chooses its round length between ",(0,s.jsx)(e.code,{children:"minimum_block_time"})," and ",(0,s.jsx)(e.code,{children:"maximum_round_length"}),"."]}),(0,s.jsx)(e.td,{children:"'66 seconds'"})]})})]}),"\n",(0,s.jsx)(e.h2,{id:"transactions",children:"transactions"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage transactions and their lifecycle."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_ttl"}),(0,s.jsx)(e.td,{children:"The duration after the transaction timestamp during which the transaction can be included in a block."}),(0,s.jsx)(e.td,{children:"'2 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_approval_count"}),(0,s.jsx)(e.td,{children:"The maximum number of approvals permitted in a single block."}),(0,s.jsx)(e.td,{children:"2600"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_block_size"}),(0,s.jsx)(e.td,{children:"Maximum block size in bytes, including transactions contained by the block. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"5_242_880"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_gas_limit"}),(0,s.jsx)(e.td,{children:"The upper limit of the total gas of all transactions in a block."}),(0,s.jsx)(e.td,{children:"3_300_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_transfer_minimum_motes"}),(0,s.jsx)(e.td,{children:"The minimum amount in motes for a valid native transfer."}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_timestamp_leeway"}),(0,s.jsxs)(e.td,{children:["The maximum value to which ",(0,s.jsx)(e.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the config.toml file."]}),(0,s.jsx)(e.td,{children:"'5 seconds'"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsv1",children:"transactions.v1"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the transaction lanes including both native and Wasm based interactions. See ",(0,s.jsx)(e.a,{href:"/runtime#lanes-and-gas-costs-lanes",children:"Lanes and gas costs"})," for details."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_mint_lane"}),(0,s.jsx)(e.td,{children:"[0, 1024, 1024, 65_000_000_000, 650]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_auction_lane"}),(0,s.jsx)(e.td,{children:"[1, 2048, 2048, 362_500_000_000, 145]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"wasm_lanes"}),(0,s.jsx)(e.td,{children:"[[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsdeploy",children:"transactions.deploy"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_payment_cost"}),(0,s.jsx)(e.td,{children:"The maximum number of motes allowed to be spent during payment. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"'0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_dependencies"}),(0,s.jsx)(e.td,{children:"The maximum number of other transactions a transaction can depend on (requiring them to have been executed before it can execute)."}),(0,s.jsx)(e.td,{children:"10"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"payment_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized payment code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"session_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized session code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasm",children:"wasm"}),"\n",(0,s.jsx)(e.p,{children:"The following are Wasm-related settings."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_memory"}),(0,s.jsx)(e.td,{children:"Amount of free memory (in 64 kB pages) each contract can use for its stack."}),(0,s.jsx)(e.td,{children:"64"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_stack_height"}),(0,s.jsx)(e.td,{children:"Max stack height (native WebAssembly stack limiter)."}),(0,s.jsx)(e.td,{children:"500"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmstorage_costs",children:"wasm.storage_costs"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage Wasm storage costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costs",children:"wasm.opcode_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage the cost table for Wasm opcodes."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flow",children:"wasm.opcode_costs.control_flow"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage costs for control flow operations."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flowbr_table",children:"wasm.opcode_costs.control_flow.br_table"}),"\n",(0,s.jsxs)(e.p,{children:["The following settings manage ",(0,s.jsx)(e.code,{children:"br_table"})," Wasm opcodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasmmessages_limits",children:"wasm.messages_limits"}),"\n",(0,s.jsx)(e.p,{children:"The following chainspec settings manage the cost of contract-level messages."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topic_name_size"}),(0,s.jsx)(e.td,{children:"Maximum size of the topic name."}),(0,s.jsx)(e.td,{children:"256"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topics_per_contract"}),(0,s.jsx)(e.td,{children:"Maximum number of topics that can be added for each contract."}),(0,s.jsx)(e.td,{children:"128"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_message_size"}),(0,s.jsx)(e.td,{children:"Maximum size in bytes of the serialized message payload."}),(0,s.jsx)(e.td,{children:"1_024"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmhost_function_costs",children:"wasm.host_function_costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs",children:"smart_contracts/contract/src/ext_ffi.rs"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Host-Side Function"}),(0,s.jsx)(e.th,{children:"Cost"}),(0,s.jsx)(e.th,{children:"Arguments"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"5_800"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_associated_key"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"blake2b"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_versioned_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_purse"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"disable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_balance"}),(0,s.jsx)(e.td,{children:"3_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_blocktime"}),(0,s.jsx)(e.td,{children:"330"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_caller"}),(0,s.jsx)(e.td,{children:"380"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_key"}),(0,s.jsx)(e.td,{children:"2_000"}),(0,s.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_main_purse"}),(0,s.jsx)(e.td,{children:"1_300"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg_size"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_phase"}),(0,s.jsx)(e.td,{children:"710"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_system_contract"}),(0,s.jsx)(e.td,{children:"1_100"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"has_key"}),(0,s.jsx)(e.td,{children:"1_500"}),(0,s.jsx)(e.td,{children:"[0, 840]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"is_valid_uref"}),(0,s.jsx)(e.td,{children:"760"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load_named_keys"}),(0,s.jsx)(e.td,{children:"42_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"new_uref"}),(0,s.jsx)(e.td,{children:"17_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"random_bytes"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"print"}),(0,s.jsx)(e.td,{children:"20_000"}),(0,s.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"put_key"}),(0,s.jsx)(e.td,{children:"100_000_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_host_buffer"}),(0,s.jsx)(e.td,{children:"3_500"}),(0,s.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value"}),(0,s.jsx)(e.td,{children:"60_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value_local"}),(0,s.jsx)(e.td,{children:"5_500"}),(0,s.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_key"}),(0,s.jsx)(e.td,{children:"61_000"}),(0,s.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"ret"}),(0,s.jsx)(e.td,{children:"23_000"}),(0,s.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"revert"}),(0,s.jsx)(e.td,{children:"500"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_action_threshold"}),(0,s.jsx)(e.td,{children:"74_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,s.jsx)(e.td,{children:"82_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"update_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"write"}),(0,s.jsx)(e.td,{children:"14_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"dictionary_put"}),(0,s.jsx)(e.td,{children:"9_500"}),(0,s.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"enable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"manage_message_topic"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"emit_message"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost_increase_per_message"}),(0,s.jsx)(e.td,{children:"50"}),(0,s.jsx)(e.td,{})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"system_costs",children:"system_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage protocol operating costs."}),"\n",(0,s.jsx)(e.h3,{id:"system_costsauction_costs",children:"system_costs.auction_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"change_bid_public_key"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsmint_costs",children:"system_costs.mint_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"burn"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costshandle_payment_costs",children:"system_costs.handle_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsstandard_payment_costs",children:"system_costs.standard_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function a(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>i,x:()=>c});var s=t(96540);const r={},d=s.createContext(r);function i(n){const e=s.useContext(d);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:i(n.components),s.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/a0ccdbb2.cf1b6b50.js b/assets/js/a0ccdbb2.cf1b6b50.js deleted file mode 100644 index e0d5ab652..000000000 --- a/assets/js/a0ccdbb2.cf1b6b50.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9460],{72407:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>d,metadata:()=>c,toc:()=>h});var s=t(74848),r=t(28453);const d={title:"The Chainspec"},i="The Blockchain Specification {#the-chain-specification}",c={id:"operators/setup-network/chain-spec",title:"The Chainspec",description:"the-chain-specification}",source:"@site/docs/operators/setup-network/chain-spec.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/chain-spec",permalink:"/next/operators/setup-network/chain-spec",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"The Chainspec"},sidebar:"operators",previous:{title:"Genesis",permalink:"/next/operators/setup-network/genesis"},next:{title:"Private Network Setup",permalink:"/next/operators/setup-network/create-private"}},l={},h=[{value:"protocol",id:"protocol",level:2},{value:"network",id:"network",level:2},{value:"core",id:"core",level:2},{value:"highway",id:"highway",level:2},{value:"transactions",id:"transactions",level:2},{value:"transactions.v1",id:"transactionsv1",level:3},{value:"transactions.deploy",id:"transactionsdeploy",level:3},{value:"wasm",id:"wasm",level:2},{value:"wasm.storage_costs",id:"wasmstorage_costs",level:3},{value:"wasm.opcode_costs",id:"wasmopcode_costs",level:3},{value:"wasm.opcode_costs.control_flow",id:"wasmopcode_costscontrol_flow",level:3},{value:"wasm.opcode_costs.control_flow.br_table",id:"wasmopcode_costscontrol_flowbr_table",level:3},{value:"wasm.messages_limits",id:"wasmmessages_limits",level:2},{value:"wasm.host_function_costs",id:"wasmhost_function_costs",level:3},{value:"system_costs",id:"system_costs",level:2},{value:"system_costs.auction_costs",id:"system_costsauction_costs",level:3},{value:"system_costs.mint_costs",id:"system_costsmint_costs",level:3},{value:"system_costs.handle_payment_costs",id:"system_costshandle_payment_costs",level:3},{value:"system_costs.standard_payment_costs",id:"system_costsstandard_payment_costs",level:3}];function o(n){const e={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"the-chain-specification",children:"The Blockchain Specification"})}),"\n",(0,s.jsxs)(e.p,{children:["The blockchain specification, or ",(0,s.jsx)(e.code,{children:"chainspec"}),", is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 2.0.0 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring. "]}),"\n",(0,s.jsx)(e.h2,{id:"protocol",children:"protocol"}),"\n",(0,s.jsx)(e.p,{children:"These settings describe the active protocol version."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"version"}),(0,s.jsx)(e.td,{children:"The Casper node protocol version."}),(0,s.jsx)(e.td,{children:"'2.0.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"hard_reset"}),(0,s.jsx)(e.td,{children:"When set to true, clear blocks and transactions back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activation_point"}),(0,s.jsxs)(e.td,{children:["The protocol version that should become active. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 \u2014 see the ",(0,s.jsx)(e.code,{children:"finality_threshold_fraction"})," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."]}),(0,s.jsx)(e.td,{children:"11100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"network",children:"network"}),"\n",(0,s.jsx)(e.p,{children:"The following settings configure the networking layer."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"name"}),(0,s.jsx)(e.td,{children:"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."}),(0,s.jsx)(e.td,{children:"'casper'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_net_message_size"}),(0,s.jsx)(e.td,{children:"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."}),(0,s.jsx)(e.td,{children:"25_165_824"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"core",children:"core"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage the core protocol behavior."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"era_duration"}),(0,s.jsx)(e.td,{children:"Era duration."}),(0,s.jsx)(e.td,{children:"'120 minutes'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_era_height"}),(0,s.jsxs)(e.td,{children:["Minimum number of blocks per era. An era will take longer than ",(0,s.jsx)(e.code,{children:"era_duration"})," if that is necessary to reach the minimum height."]}),(0,s.jsx)(e.td,{children:"20"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_block_time"}),(0,s.jsx)(e.td,{children:"Minimum difference between a block's and its child's timestamp."}),(0,s.jsx)(e.td,{children:"'16384 ms'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_slots"}),(0,s.jsx)(e.td,{children:"Number of slots available in the validator auction."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_threshold_fraction"}),(0,s.jsxs)(e.td,{children:["A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,s.jsx)(e.br,{}),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,s.jsx)(e.br,{}),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."]}),(0,s.jsx)(e.td,{children:"[1, 3]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsxs)(e.td,{children:["start_protocol_version_with_strict",(0,s.jsx)(e.br,{}),"_finality_signatures_required"]}),(0,s.jsx)(e.td,{children:"Protocol version from which nodes are required to hold strict finality signatures."}),(0,s.jsx)(e.td,{children:"'1.5.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"legacy_required_finality"}),(0,s.jsxs)(e.td,{children:["The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,s.jsx)(e.br,{}),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."]}),(0,s.jsx)(e.td,{children:"'Strict'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_accounts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user accounts to addressable entity. If false, user accounts will be left as they are and will be lazily migrated on a per-account basis if / when that account is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_contracts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user contracts to addressable entity. If false, user contracts will be left as they are and will be lazily migrated on a per-contract basis if / when that contract is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"auction_delay"}),(0,s.jsx)(e.td,{children:"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."}),(0,s.jsx)(e.td,{children:"1"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"locked_funds_period"}),(0,s.jsx)(e.td,{children:"The period after genesis during which a genesis validator's bid is locked."}),(0,s.jsx)(e.td,{children:"'0 days'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"vesting_schedule_period"}),(0,s.jsx)(e.td,{children:"The period in which the genesis validator's bid is released over time after it is unlocked."}),(0,s.jsx)(e.td,{children:"'0 weeks'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unbonding_delay"}),(0,s.jsx)(e.td,{children:"Default number of eras that need to pass to be able to withdraw unbonded funds."}),(0,s.jsx)(e.td,{children:"7"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"round_seigniorage_rate"}),(0,s.jsxs)(e.td,{children:["Round seigniorage rate represented as a fraction of the total supply.",(0,s.jsx)(e.br,{}),"- Annual issuance: 8%.",(0,s.jsx)(e.br,{}),"- Minimum block time: 2^15 milliseconds.",(0,s.jsx)(e.br,{}),"- Ticks per year: 31536000000.",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.code,{children:"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)"})]}),(0,s.jsx)(e.td,{children:"[7, 175070816]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_associated_keys"}),(0,s.jsx)(e.td,{children:"Maximum number of associated keys for a single account."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_runtime_call_stack_height"}),(0,s.jsx)(e.td,{children:"Maximum height of the contract runtime call stack."}),(0,s.jsx)(e.td,{children:"12"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Minimum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"500_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Maximum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"1_000_000_000_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"prune_batch_size"}),(0,s.jsxs)(e.td,{children:["Global state prune batch size for tip pruning. Possible values:",(0,s.jsx)(e.br,{}),"- 0 when the feature is OFF",(0,s.jsx)(e.br,{}),"- Integer if the feature is ON, representing the number of eras to process per block."]}),(0,s.jsx)(e.td,{children:"0"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"strict_argument_checking"}),(0,s.jsxs)(e.td,{children:["Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,s.jsx)(e.code,{children:"CLType"}),"."]}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"simultaneous_peer_requests"}),(0,s.jsx)(e.td,{children:"Number of simultaneous peer requests."}),(0,s.jsx)(e.td,{children:"5"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"consensus_protocol"}),(0,s.jsx)(e.td,{children:"The consensus protocol to use. Options are 'Zug' or 'Highway'."}),(0,s.jsx)(e.td,{children:"'Zug'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_delegators_per_validator"}),(0,s.jsx)(e.td,{children:"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."}),(0,s.jsx)(e.td,{children:"1200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finders_fee"}),(0,s.jsx)(e.td,{children:"The split in finality signature rewards between block producer and participating signers."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_signature_proportion"}),(0,s.jsx)(e.td,{children:"The proportion of baseline rewards going to reward finality signatures specifically."}),(0,s.jsx)(e.td,{children:"[1, 2]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"signature_rewards_max_delay"}),(0,s.jsx)(e.td,{children:"Lookback interval indicating how many past blocks we are looking at to reward."}),(0,s.jsx)(e.td,{children:"3"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_unrestricted_transfers"}),(0,s.jsx)(e.td,{children:"Allows peer to peer transfers between users. Setting this to false makes sense only for private chains."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_auction_bids"}),(0,s.jsx)(e.td,{children:"Enables the auction entry points 'delegate' and 'add_bid'. Setting this to false makes sense only for private chains that don't need to auction new validator slots. These auction entry points will return an error if called, when this option is set to false."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"compute_rewards"}),(0,s.jsx)(e.td,{children:"If set to false, then consensus doesn't compute rewards and always uses 0."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"refund_handling"}),(0,s.jsx)(e.td,{children:"Defines how refunds of the unused portion of payment amounts are calculated and handled. Valid options are: refund (a ratio of the unspent token is returned to the spender); burn (a ratio of the unspent token is burned); no_refund (no refunds are paid out)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_refund' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"fee_handling"}),(0,s.jsx)(e.td,{children:"Defines how fees are handled. Valid options are: no_fee (fees are eliminated); pay_to_proposer (fees are paid to the block proposer); accumulate (fees are accumulated in a special purse and distributed at the end of each era evenly among all administrator accounts); burn (fees are burned)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_fee' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_credit_cap"}),(0,s.jsx)(e.td,{children:"If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pricing_handling"}),(0,s.jsx)(e.td,{children:"Defines how pricing is handled. Valid options are: classic (senders of transaction self-specify how much they pay); fixed (costs are fixed, per the cost table); reserved (prepaid transaction, currently not supported)"}),(0,s.jsx)(e.td,{children:"{ type = 'fixed' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_reservations"}),(0,s.jsx)(e.td,{children:"Does the network allow pre-payment / reservations for future execution? Currently not supported."}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_balance_handling"}),(0,s.jsx)(e.td,{children:"Defines how gas holds affect available balance calculations. Valid options are: accrued (sum of full value of all non-expired holds) and amortized (sum of each hold is amortized over the time remaining until expiry)."}),(0,s.jsx)(e.td,{children:"{ type = 'accrued' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_interval"}),(0,s.jsx)(e.td,{children:"Defines how long gas holds last."}),(0,s.jsx)(e.td,{children:"'24 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"administrators"}),(0,s.jsx)(e.td,{children:"List of public keys of administrator accounts. Setting this option makes only on private chains which require administrator accounts for regulatory reasons."}),(0,s.jsx)(e.td,{children:"[]"})]})]})]}),"\n",(0,s.jsxs)(e.p,{children:["See the ",(0,s.jsx)(e.a,{href:"/next/concepts/economics/fee-elimination",children:"Fee Elimination"})," page for more details regarding ",(0,s.jsx)(e.code,{children:"refund_handling"}),", ",(0,s.jsx)(e.code,{children:"fee_handling"}),", ",(0,s.jsx)(e.code,{children:"validator_credit_cap"}),", ",(0,s.jsx)(e.code,{children:"pricing_handling"}),", ",(0,s.jsx)(e.code,{children:"gas_hold_balance_handling"}),", and ",(0,s.jsx)(e.code,{children:"gas_hold_interval"}),"."]}),"\n",(0,s.jsx)(e.h2,{id:"highway",children:"highway"}),"\n",(0,s.jsx)(e.p,{children:"These settings configure the Highway Consensus protocol."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_round_length"}),(0,s.jsxs)(e.td,{children:["Highway dynamically chooses its round length between ",(0,s.jsx)(e.code,{children:"minimum_block_time"})," and ",(0,s.jsx)(e.code,{children:"maximum_round_length"}),"."]}),(0,s.jsx)(e.td,{children:"'66 seconds'"})]})})]}),"\n",(0,s.jsx)(e.h2,{id:"transactions",children:"transactions"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage transactions and their lifecycle."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_ttl"}),(0,s.jsx)(e.td,{children:"The duration after the transaction timestamp during which the transaction can be included in a block."}),(0,s.jsx)(e.td,{children:"'2 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_approval_count"}),(0,s.jsx)(e.td,{children:"The maximum number of approvals permitted in a single block."}),(0,s.jsx)(e.td,{children:"2600"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_block_size"}),(0,s.jsx)(e.td,{children:"Maximum block size in bytes, including transactions contained by the block. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"5_242_880"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_gas_limit"}),(0,s.jsx)(e.td,{children:"The upper limit of the total gas of all transactions in a block."}),(0,s.jsx)(e.td,{children:"3_300_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_transfer_minimum_motes"}),(0,s.jsx)(e.td,{children:"The minimum amount in motes for a valid native transfer."}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_timestamp_leeway"}),(0,s.jsxs)(e.td,{children:["The maximum value to which ",(0,s.jsx)(e.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the config.toml file."]}),(0,s.jsx)(e.td,{children:"'5 seconds'"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsv1",children:"transactions.v1"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the transaction lanes including both native and Wasm based interactions. See ",(0,s.jsx)(e.a,{href:"/next/runtime#lanes-and-gas-costs-lanes",children:"Lanes and gas costs"})," for details."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_mint_lane"}),(0,s.jsx)(e.td,{children:"[0, 1024, 1024, 65_000_000_000, 650]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_auction_lane"}),(0,s.jsx)(e.td,{children:"[1, 2048, 2048, 362_500_000_000, 145]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"wasm_lanes"}),(0,s.jsx)(e.td,{children:"[[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsdeploy",children:"transactions.deploy"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_payment_cost"}),(0,s.jsx)(e.td,{children:"The maximum number of motes allowed to be spent during payment. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"'0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_dependencies"}),(0,s.jsx)(e.td,{children:"The maximum number of other transactions a transaction can depend on (requiring them to have been executed before it can execute)."}),(0,s.jsx)(e.td,{children:"10"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"payment_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized payment code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"session_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized session code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasm",children:"wasm"}),"\n",(0,s.jsx)(e.p,{children:"The following are Wasm-related settings."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_memory"}),(0,s.jsx)(e.td,{children:"Amount of free memory (in 64 kB pages) each contract can use for its stack."}),(0,s.jsx)(e.td,{children:"64"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_stack_height"}),(0,s.jsx)(e.td,{children:"Max stack height (native WebAssembly stack limiter)."}),(0,s.jsx)(e.td,{children:"500"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmstorage_costs",children:"wasm.storage_costs"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage Wasm storage costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costs",children:"wasm.opcode_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage the cost table for Wasm opcodes."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flow",children:"wasm.opcode_costs.control_flow"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage costs for control flow operations."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flowbr_table",children:"wasm.opcode_costs.control_flow.br_table"}),"\n",(0,s.jsxs)(e.p,{children:["The following settings manage ",(0,s.jsx)(e.code,{children:"br_table"})," Wasm opcodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasmmessages_limits",children:"wasm.messages_limits"}),"\n",(0,s.jsx)(e.p,{children:"The following chainspec settings manage the cost of contract-level messages."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topic_name_size"}),(0,s.jsx)(e.td,{children:"Maximum size of the topic name."}),(0,s.jsx)(e.td,{children:"256"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topics_per_contract"}),(0,s.jsx)(e.td,{children:"Maximum number of topics that can be added for each contract."}),(0,s.jsx)(e.td,{children:"128"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_message_size"}),(0,s.jsx)(e.td,{children:"Maximum size in bytes of the serialized message payload."}),(0,s.jsx)(e.td,{children:"1_024"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmhost_function_costs",children:"wasm.host_function_costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs",children:"smart_contracts/contract/src/ext_ffi.rs"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Host-Side Function"}),(0,s.jsx)(e.th,{children:"Cost"}),(0,s.jsx)(e.th,{children:"Arguments"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"5_800"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_associated_key"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"blake2b"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_versioned_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_purse"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"disable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_balance"}),(0,s.jsx)(e.td,{children:"3_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_blocktime"}),(0,s.jsx)(e.td,{children:"330"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_caller"}),(0,s.jsx)(e.td,{children:"380"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_key"}),(0,s.jsx)(e.td,{children:"2_000"}),(0,s.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_main_purse"}),(0,s.jsx)(e.td,{children:"1_300"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg_size"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_phase"}),(0,s.jsx)(e.td,{children:"710"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_system_contract"}),(0,s.jsx)(e.td,{children:"1_100"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"has_key"}),(0,s.jsx)(e.td,{children:"1_500"}),(0,s.jsx)(e.td,{children:"[0, 840]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"is_valid_uref"}),(0,s.jsx)(e.td,{children:"760"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load_named_keys"}),(0,s.jsx)(e.td,{children:"42_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"new_uref"}),(0,s.jsx)(e.td,{children:"17_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"random_bytes"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"print"}),(0,s.jsx)(e.td,{children:"20_000"}),(0,s.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"put_key"}),(0,s.jsx)(e.td,{children:"100_000_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_host_buffer"}),(0,s.jsx)(e.td,{children:"3_500"}),(0,s.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value"}),(0,s.jsx)(e.td,{children:"60_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value_local"}),(0,s.jsx)(e.td,{children:"5_500"}),(0,s.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_key"}),(0,s.jsx)(e.td,{children:"61_000"}),(0,s.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"ret"}),(0,s.jsx)(e.td,{children:"23_000"}),(0,s.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"revert"}),(0,s.jsx)(e.td,{children:"500"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_action_threshold"}),(0,s.jsx)(e.td,{children:"74_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,s.jsx)(e.td,{children:"82_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"update_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"write"}),(0,s.jsx)(e.td,{children:"14_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"dictionary_put"}),(0,s.jsx)(e.td,{children:"9_500"}),(0,s.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"enable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"manage_message_topic"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"emit_message"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost_increase_per_message"}),(0,s.jsx)(e.td,{children:"50"}),(0,s.jsx)(e.td,{})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"system_costs",children:"system_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage protocol operating costs."}),"\n",(0,s.jsx)(e.h3,{id:"system_costsauction_costs",children:"system_costs.auction_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"change_bid_public_key"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsmint_costs",children:"system_costs.mint_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"burn"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costshandle_payment_costs",children:"system_costs.handle_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsstandard_payment_costs",children:"system_costs.standard_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function a(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>i,x:()=>c});var s=t(96540);const r={},d=s.createContext(r);function i(n){const e=s.useContext(d);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:i(n.components),s.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/a1868598.bd404523.js b/assets/js/a1868598.bd404523.js deleted file mode 100644 index 1a7e6cd29..000000000 --- a/assets/js/a1868598.bd404523.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6265],{41214:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>c,frontMatter:()=>d,metadata:()=>a,toc:()=>p});var s=t(74848),r=t(28453);const d={},i="Overview of Casper dApps",a={id:"developers/dapps/index",title:"Overview of Casper dApps",description:"The following topics are essential for developers building decentralized applications on a Casper network.",source:"@site/docs/developers/dapps/index.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/",permalink:"/next/developers/dapps/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"CLType",permalink:"/next/developers/json-rpc/types_cl"},next:{title:"What is a dApp?",permalink:"/next/developers/dapps/dapp"}},o={},p=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"overview-of-casper-dapps",children:"Overview of Casper dApps"})}),"\n",(0,s.jsx)(n.p,{children:"The following topics are essential for developers building decentralized applications on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/dapp",children:"Introducing dApps"})}),(0,s.jsx)(n.td,{children:"Introducing dApps on a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/prerequisites",children:"Prerequisites for Building dApps"})}),(0,s.jsx)(n.td,{children:"Recommended setup for building dApps on Casper"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/sdk",children:"SDK Client Libraries"})}),(0,s.jsx)(n.td,{children:"Client-side libraries providing ways to interact with a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/technology-stack",children:"dApp Technology Stack"})}),(0,s.jsx)(n.td,{children:"Building the front-end, backend, and on-chain logic of a dApp"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/template-frontend",children:"Front-end Template with React"})}),(0,s.jsx)(n.td,{children:"Use the Casper JS SDK with React to build a dApp frontend"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/signing-a-transaction",children:"Signing Transactions"})}),(0,s.jsx)(n.td,{children:"Details about the signatures required for transactions"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/setup-nctl",children:"Setting up a Local Network with NCTL"})}),(0,s.jsx)(n.td,{children:"Learn to set up a local test network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),(0,s.jsx)(n.td,{children:"Test transactions locally before sending them to a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"})}),(0,s.jsx)(n.td,{children:"How dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data"})]})]})]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},d=s.createContext(r);function i(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a1868598.e4c98816.js b/assets/js/a1868598.e4c98816.js new file mode 100644 index 000000000..7cb46b29f --- /dev/null +++ b/assets/js/a1868598.e4c98816.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16265],{41214:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>c,frontMatter:()=>d,metadata:()=>a,toc:()=>p});var t=s(74848),r=s(28453);const d={},i="Overview of Casper dApps",a={id:"developers/dapps/index",title:"Overview of Casper dApps",description:"The following topics are essential for developers building decentralized applications on a Casper network.",source:"@site/docs/developers/dapps/index.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/",permalink:"/developers/dapps/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"CLType",permalink:"/developers/json-rpc/types_cl"},next:{title:"What is a dApp?",permalink:"/developers/dapps/dapp"}},o={},p=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"overview-of-casper-dapps",children:"Overview of Casper dApps"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics are essential for developers building decentralized applications on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/dapp",children:"Introducing dApps"})}),(0,t.jsx)(n.td,{children:"Introducing dApps on a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/prerequisites",children:"Prerequisites for Building dApps"})}),(0,t.jsx)(n.td,{children:"Recommended setup for building dApps on Casper"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/sdk",children:"SDK Client Libraries"})}),(0,t.jsx)(n.td,{children:"Client-side libraries providing ways to interact with a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/technology-stack",children:"dApp Technology Stack"})}),(0,t.jsx)(n.td,{children:"Building the front-end, backend, and on-chain logic of a dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/template-frontend",children:"Front-end Template with React"})}),(0,t.jsx)(n.td,{children:"Use the Casper JS SDK with React to build a dApp frontend"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/signing-a-transaction",children:"Signing Transactions"})}),(0,t.jsx)(n.td,{children:"Details about the signatures required for transactions"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"Setting up a Local Network with NCTL"})}),(0,t.jsx)(n.td,{children:"Learn to set up a local test network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),(0,t.jsx)(n.td,{children:"Test transactions locally before sending them to a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"})}),(0,t.jsx)(n.td,{children:"How dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data"})]})]})]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},d=t.createContext(r);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2874f18.02b183f5.js b/assets/js/a2874f18.02b183f5.js new file mode 100644 index 000000000..7a1c7df89 --- /dev/null +++ b/assets/js/a2874f18.02b183f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16512],{71968:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var c=t(74848),a=t(28453);const s={title:"Contract Hash vs. Package Hash"},r="Using the Contract Hash vs. the Package Hash",o={id:"developers/writing-onchain-code/contract-hash-vs-package-hash",title:"Contract Hash vs. Package Hash",description:"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-hash-vs-package-hash",permalink:"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Contract Hash vs. Package Hash"},sidebar:"developers",previous:{title:"Testing Session Code",permalink:"/1.5.X/developers/writing-onchain-code/testing-session-code"},next:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/1.5.X/developers/writing-onchain-code/best-practices"}},i={},h=[{value:"The Casper Call Stack",id:"the-casper-call-stack",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"using-the-contract-hash-vs-the-package-hash",children:"Using the Contract Hash vs. the Package Hash"})}),"\n",(0,c.jsxs)(n.p,{children:["This page describes the possibilities of using the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html",children:"contract hash"})," vs. the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html",children:"contract package hash"})," (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 ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:"Upgrading and Maintaining Smart Contracts"}),", 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."]}),"\n",(0,c.jsx)(n.p,{align:"center",children:(0,c.jsx)(n.img,{src:'{useBaseUrl("/image/package-representation-extended.png")}',alt:"package-representation",width:"400"})}),"\n",(0,c.jsx)(n.p,{children:"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:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Want to identify specific versions of contracts within the same package and thus use a contract hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Need specific contract versions within the same package, and thus use both contract hash and contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need either hash for this use case"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers loosely at the package level?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers specifically at the contract level?"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Or a more fine-grained variation would be:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow or block callers at the package level but track by both package and contract hash?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow other combinations of these basic concepts?"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["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 ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/",children:"Casper External FFI"}),", versus use cases and interactions between two or more ecosystem entities such as accounts and contracts."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.h2,{id:"the-casper-call-stack",children:"The Casper Call Stack"}),"\n",(0,c.jsxs)(n.p,{children:["When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html",children:"casper_load_call_stack"}),", which provides a stack of one or more entries of this kind:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-rust",children:"/// Represents the origin of a sub-call.\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum CallStackElement {\n /// Session\n Session {\n /// The account hash of the caller\n account_hash: AccountHash,\n },\n /// Effectively an EntryPointType::Session - stored access to a session.\n StoredSession {\n /// The account hash of the caller\n account_hash: AccountHash,\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n /// contract\n StoredContract {\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["You can find the source code ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs",children:"here"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine."}),"\n",(0,c.jsxs)(n.p,{children:["Learn more about ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/callstack",children:"Call Stacks"})," and how Casper manages the calling of a contract."]}),"\n",(0,c.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,c.jsx)(n.p,{children:"Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash."}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only accounts to use the contract? If so, what kind of accounts are you considering?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify and track each account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Exactly one specific account"}),(0,c.jsx)(n.td,{children:"Use the account hash of a specific account to identify it."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts"}),(0,c.jsx)(n.td,{children:"There is no need to track the accounts by account hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only contracts to use it? If so, what kind of contracts?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions"}),(0,c.jsx)(n.td,{children:"Use the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the contract hash and the package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use only the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract version of any contract"}),(0,c.jsx)(n.td,{children:"There is no need to track by contract or package hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and contract versions"}),(0,c.jsx)(n.td,{children:"Use the account hash to track each account and the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and specific versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the contract hash and package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and any versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts and contracts"}),(0,c.jsx)(n.td,{children:"There is no need to track by account hash or contract hash."})]})]})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/cross-contract",children:"Cross-Contract Communication"})," - Variations of cross-contract communication for more complex scenarios"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," - Contract code returning a value to the immediate caller via ",(0,c.jsx)(n.code,{children:"runtime::ret()"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2874f18.d9627a72.js b/assets/js/a2874f18.d9627a72.js deleted file mode 100644 index a9442b527..000000000 --- a/assets/js/a2874f18.d9627a72.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6512],{71968:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var c=t(74848),a=t(28453);const s={title:"Contract Hash vs. Package Hash"},r="Using the Contract Hash vs. the Package Hash",o={id:"developers/writing-onchain-code/contract-hash-vs-package-hash",title:"Contract Hash vs. Package Hash",description:"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-hash-vs-package-hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Contract Hash vs. Package Hash"},sidebar:"developers",previous:{title:"Testing Session Code",permalink:"/developers/writing-onchain-code/testing-session-code"},next:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/developers/writing-onchain-code/best-practices"}},i={},h=[{value:"The Casper Call Stack",id:"the-casper-call-stack",level:2},{value:"Recommendations",id:"recommendations",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"using-the-contract-hash-vs-the-package-hash",children:"Using the Contract Hash vs. the Package Hash"})}),"\n",(0,c.jsxs)(n.p,{children:["This page describes the possibilities of using the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractHash.html",children:"contract hash"})," vs. the ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/3.0.0/casper_types/contracts/struct.ContractPackageHash.html",children:"contract package hash"})," (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 ",(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:"Upgrading and Maintaining Smart Contracts"}),", 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."]}),"\n",(0,c.jsx)(n.p,{align:"center",children:(0,c.jsx)(n.img,{src:'{useBaseUrl("/image/package-representation-extended.png")}',alt:"package-representation",width:"400"})}),"\n",(0,c.jsx)(n.p,{children:"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:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Want to identify specific versions of contracts within the same package and thus use a contract hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need specific contract versions and allow or block all versions in the same package, thus using the contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Need specific contract versions within the same package, and thus use both contract hash and contract package hash"}),"\n",(0,c.jsx)(n.li,{children:"Not need either hash for this use case"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"A given contract, i.e., CEP-18, which wants to allow or block or track calls from other contracts, should then decide:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers loosely at the package level?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow, block, or track contract callers specifically at the contract level?"}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Or a more fine-grained variation would be:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:"Will the contract allow or block callers at the package level but track by both package and contract hash?"}),"\n",(0,c.jsx)(n.li,{children:"Will the contract allow other combinations of these basic concepts?"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["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 ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/",children:"Casper External FFI"}),", versus use cases and interactions between two or more ecosystem entities such as accounts and contracts."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.h2,{id:"the-casper-call-stack",children:"The Casper Call Stack"}),"\n",(0,c.jsxs)(n.p,{children:["When identifying who called a contract or initiated a call chain, the execution engine offers the FFI method ",(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/fn.casper_load_call_stack.html",children:"casper_load_call_stack"}),", which provides a stack of one or more entries of this kind:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-rust",children:"/// Represents the origin of a sub-call.\n#[derive(Clone, Debug, PartialEq, Eq)]\npub enum CallStackElement {\n /// Session\n Session {\n /// The account hash of the caller\n account_hash: AccountHash,\n },\n /// Effectively an EntryPointType::Session - stored access to a session.\n StoredSession {\n /// The account hash of the caller\n account_hash: AccountHash,\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n /// contract\n StoredContract {\n /// The contract package hash\n contract_package_hash: ContractPackageHash,\n /// The contract hash\n contract_hash: ContractHash,\n },\n}\n"})}),"\n",(0,c.jsxs)(n.p,{children:["You can find the source code ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/types/src/system/call_stack_element.rs",children:"here"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"After retrieving the required information, the contract must manage its internal logic and data storage, actions entirely opaque to the execution engine."}),"\n",(0,c.jsxs)(n.p,{children:["Learn more about ",(0,c.jsx)(n.a,{href:"/concepts/callstack",children:"Call Stacks"})," and how Casper manages the calling of a contract."]}),"\n",(0,c.jsx)(n.h2,{id:"recommendations",children:"Recommendations"}),"\n",(0,c.jsx)(n.p,{children:"Consider the following questions when designing the contract and choosing whether to use the contract hash or package hash."}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only accounts to use the contract? If so, what kind of accounts are you considering?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify and track each account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Exactly one specific account"}),(0,c.jsx)(n.td,{children:"Use the account hash of a specific account to identify it."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts"}),(0,c.jsx)(n.td,{children:"There is no need to track the accounts by account hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow only contracts to use it? If so, what kind of contracts?"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions"}),(0,c.jsx)(n.td,{children:"Use the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the contract hash and the package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use only the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any contract version of any contract"}),(0,c.jsx)(n.td,{children:"There is no need to track by contract or package hash."})]})]})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"Will you allow both accounts and contracts to use it? If so, will these accounts and contracts be:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Answer"}),(0,c.jsx)(n.th,{children:"Recommendation"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and contract versions"}),(0,c.jsx)(n.td,{children:"Use the account hash to track each account and the contract hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and specific versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the contract hash and package hash to identify each contract version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Specific accounts and any versions of specific packages"}),(0,c.jsx)(n.td,{children:"Use the account hash to identify each account and the package hash to identify each contract package."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"Any accounts and contracts"}),(0,c.jsx)(n.td,{children:"There is no need to track by account hash or contract hash."})]})]})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/best-practices",children:"Best Practices for Casper Smart Contract Authors"})," - An outline of best practices when developing smart contracts on a Casper network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/resources/tutorials/advanced/cross-contract",children:"Cross-Contract Communication"})," - Variations of cross-contract communication for more complex scenarios"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," - Contract code returning a value to the immediate caller via ",(0,c.jsx)(n.code,{children:"runtime::ret()"})]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a2ea0fe7.f73f7874.js b/assets/js/a2ea0fe7.f73f7874.js new file mode 100644 index 000000000..6dfa2ff71 --- /dev/null +++ b/assets/js/a2ea0fe7.f73f7874.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70246],{69999:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>c,default:()=>l,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var t=i(74848),s=i(28453);const a={title:"Change bid public key"},c="Changing the Public Key Associated with a Validator Bid",o={id:"operators/becoming-a-validator/change-bid-public-key",title:"Change bid public key",description:"The public key associated with a given validator bid can be changed through the auction contract's changebidpublic_key entry point.",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/change-bid-public-key.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/change-bid-public-key",permalink:"/2.0.0/operators/becoming-a-validator/change-bid-public-key",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Change bid public key"}},r={},d=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Calling the system auction contract's <code>change_bid_public_key</code> entry point",id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",level:2},{value:"Method 2: Using compiled WASM",id:"method-2-using-compiled-wasm",level:2},{value:"Bridge records",id:"bridge-records",level:2},{value:"Limitations",id:"limitations",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"changing-the-public-key-associated-with-a-validator-bid",children:"Changing the Public Key Associated with a Validator Bid"})}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given validator bid can be changed through the auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point."]}),"\n",(0,t.jsx)(n.p,{children:'An example of this functionality would be to transfer ownership of a validator "slot" to a different party or to migrate a node to a backup server. By leveraging the system contract we can perform those operations more securely by making sure that no private key files need to be copied or transmitted between servers.'}),"\n",(0,t.jsx)(n.p,{children:"When the public key is changed all relevant delegations are also changed to be associated with the updated validator bid."}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"For a public key change to be performed successfully there must not exist a validator bid associated with the target public key."}),"\n",(0,t.jsxs)(n.h2,{id:"method-1-calling-the-system-auction-contracts-change_bid_public_key-entry-point",children:["Method 1: Calling the system auction contract's ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point"]}),"\n",(0,t.jsxs)(n.p,{children:["The public key associated with a given bid can be changed by calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point of the system auction contract. Using this method, you do not need to build any contracts, which reduces costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point change_bid_public_key \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Transaction in motes. This entry point call needs 5 CSPR."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entry point on the auction contract has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"method-2-using-compiled-wasm",children:"Method 2: Using compiled WASM"}),"\n",(0,t.jsxs)(n.p,{children:["You may also change the public key associated with a bid via a transaction containing the compiled ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," binary. For details, refer to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following transaction is a template for sending a request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-txn session \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \\\n--pricing-mode fixed \\\n--gas-price-tolerance <GAS_PRICE_TOLERANCE> \\\n--transaction-path $HOME/casper-node/target/wasm32-unknown-unknown/release/change_bid_public_key.wasm \\\n--session-entry-point call \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"new_public_key:public_key='<PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - Maximum payment for the Transaction in motes."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the compiled Wasm on your computer."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"change_bid_public_key.wasm"})," expects two arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key associated with a validator bid to be changed. This key must match the secret key that signs the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"new_public key"}),": The hexadecimal public key intended to replace the original key associated with the bid."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a transaction hash, which is needed to verify the transaction's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"change_bid_public_key"})," entrypoint in the system auction contract, which has a fixed cost of 5 CSPR."]})}),"\n",(0,t.jsx)(n.h2,{id:"bridge-records",children:"Bridge records"}),"\n",(0,t.jsxs)(n.p,{children:["In order to continue handling pending unbonds and rewards distribution even if the public key associated with a validator bid has changed, we use dedicated ",(0,t.jsx)(n.code,{children:"Bridge"})," records. These records connect the original public key to the new public key. By following those records we are able to find the current bid even if the public key was changed multiple times."]}),"\n",(0,t.jsx)(n.h2,{id:"limitations",children:"Limitations"}),"\n",(0,t.jsxs)(n.p,{children:["Due to the way the ",(0,t.jsx)(n.code,{children:"Bridge"})," record mechanism works there are some limitations regarding changing public keys to keep in mind:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Because the ",(0,t.jsx)(n.code,{children:"Bridge"})," record replaces the original bid, it's not possible to then change the public key back to the original value, since it would create a loop"]}),"\n",(0,t.jsxs)(n.li,{children:["To avoid unbounded computation we also limit the number of ",(0,t.jsx)(n.code,{children:"Bridge"})," records that can be processed in sequence to 20, which means that:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"For unbonding or redelegation requests, if a validator bid public key is changed more than 20 times between the time a request is created and processed, the funds will be returned to a delegator's main purse"}),"\n",(0,t.jsx)(n.li,{children:"For rewards distribution if the public key changes more than 20 times between the point a validator was elected for a given era and when the rewards are distributed, those rewards will be skipped and not distributed"}),"\n"]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>c,x:()=>o});var t=i(96540);const s={},a=t.createContext(s);function c(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a30e2bb0.89267903.js b/assets/js/a30e2bb0.89267903.js deleted file mode 100644 index b4c1f3209..000000000 --- a/assets/js/a30e2bb0.89267903.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5496],{38440:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Dynamic Gas Pricing"},o="Dynamic Gas Pricing on Mainnet",c={id:"concepts/economics/dynamic-gas-pricing",title:"Dynamic Gas Pricing",description:"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.",source:"@site/docs/concepts/economics/dynamic-gas-pricing.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/dynamic-gas-pricing",permalink:"/next/concepts/economics/dynamic-gas-pricing",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Dynamic Gas Pricing"},sidebar:"concepts",previous:{title:"Gas Cost",permalink:"/next/concepts/economics/gas-concepts"},next:{title:"Fee Elimination",permalink:"/next/concepts/economics/fee-elimination"}},r={},l=[{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Fixed Transaction Costs vs. Dynamic Gas Prices",id:"fixed-transaction-costs-vs-dynamic-gas-prices",level:2},{value:"Gas Tolerance",id:"gas-tolerance",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"dynamic-gas-pricing-on-mainnet",children:"Dynamic Gas Pricing on Mainnet"})}),"\n",(0,s.jsxs)(n.p,{children:["The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the ",(0,s.jsx)(n.code,{children:"vacancy"}),", as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity."]}),"\n",(0,s.jsx)(n.p,{children:"When dynamic gas pricing is enabled, a calculation runs at the end of each era to average block usage within that era. This calculation determines the gas price the network will use for the next era. If overall consumption rises above a threshold, the gas price increases by 1. If consumption falls below a threshold, the gas price decreases by 1. The gas price remains the same if overall consumption remains within those thresholds. The gas price will not go up or down by more than 1 in a given era and will not go above the maximum or below the minimum threshold."}),"\n",(0,s.jsx)(n.p,{children:"The gas price is recorded in the block header and is easily discoverable for current and historical purposes. The current gas price is a multiplier that determines the actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1 but would cost 2 CSPR if the current gas price is 2. As blocks become congested, the amount of CSPR required to obtain a slot for executing transactions will increase by a multiple. The following configuration settings control this behavior:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"upper_threshold"})," - The threshold to decrease gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"lower_threshold"})," - The threshold to increase gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"max_gas_price"})," - The maximum gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"min_gas_price"})," - The minimum gas price"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,s.jsx)(n.p,{children:"These are the block vacancy (dynamic gas pricing) settings for the Condor release on Mainnet. Before Condor, the gas price was 1, meaning 1 unit of gas cost 1 mote. With Condor, the multiple is configured to adjust between 1 and 3."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[vacancy]\n# The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network.\n#\n# The network starts with a current_gas_price of min_gas_price.\n#\n# Each block has multiple limits (bytes, transactions, transfers, gas, etc.)\n# The utilization for a block is determined by the highest percentage utilization of each these limits.\n#\n# Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here)\n# 19 transactons -> 19/20 or 95%\n# 600 transfers -> 600/650 or 92.3%\n# resulting block utilization is 95\n#\n# The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is\n# adjusted with the following:\n#\n# If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price.\n# If utilization falls between the thresholds, current_gas_price is not changed.\n# If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price.\n#\n# The cost charged for the transaction is simply the gas_used * current_gas_price.\nupper_threshold = 90\nlower_threshold = 50\nmax_gas_price = 3\nmin_gas_price = 1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"fixed-transaction-costs-vs-dynamic-gas-prices",children:"Fixed Transaction Costs vs. Dynamic Gas Prices"}),"\n",(0,s.jsxs)(n.p,{children:["The current gas price and the slot\u2019s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it\u2019s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost ",(0,s.jsx)(n.a,{href:"/next/runtime#lanes-and-gas-costs-lanes",children:"here"}),". Also, the ",(0,s.jsx)(n.code,{children:"pricing_handling = { type = 'fixed' }"})," setting is described ",(0,s.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"gas-tolerance",children:"Gas Tolerance"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"The cost of interacting with the blockchain increases during high network usage. Plan accordingly for any transactions and use the gas_tolerance field described below."})}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a ",(0,s.jsx)(n.code,{children:"gas_tolerance"})," field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with ",(0,s.jsx)(n.code,{children:"gas_tolerance = 2"})," and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block."]})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>c});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a30e2bb0.db4101ac.js b/assets/js/a30e2bb0.db4101ac.js new file mode 100644 index 000000000..e491cbda4 --- /dev/null +++ b/assets/js/a30e2bb0.db4101ac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35496],{38440:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Dynamic Gas Pricing"},o="Dynamic Gas Pricing on Mainnet",c={id:"concepts/economics/dynamic-gas-pricing",title:"Dynamic Gas Pricing",description:"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.",source:"@site/docs/concepts/economics/dynamic-gas-pricing.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/dynamic-gas-pricing",permalink:"/concepts/economics/dynamic-gas-pricing",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Dynamic Gas Pricing"},sidebar:"concepts",previous:{title:"Gas Cost",permalink:"/concepts/economics/gas-concepts"},next:{title:"Fee Elimination",permalink:"/concepts/economics/fee-elimination"}},r={},l=[{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Fixed Transaction Costs vs. Dynamic Gas Prices",id:"fixed-transaction-costs-vs-dynamic-gas-prices",level:2},{value:"Gas Tolerance",id:"gas-tolerance",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"dynamic-gas-pricing-on-mainnet",children:"Dynamic Gas Pricing on Mainnet"})}),"\n",(0,s.jsxs)(n.p,{children:["The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the ",(0,s.jsx)(n.code,{children:"vacancy"}),", as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity."]}),"\n",(0,s.jsx)(n.p,{children:"When dynamic gas pricing is enabled, a calculation runs at the end of each era to average block usage within that era. This calculation determines the gas price the network will use for the next era. If overall consumption rises above a threshold, the gas price increases by 1. If consumption falls below a threshold, the gas price decreases by 1. The gas price remains the same if overall consumption remains within those thresholds. The gas price will not go up or down by more than 1 in a given era and will not go above the maximum or below the minimum threshold."}),"\n",(0,s.jsx)(n.p,{children:"The gas price is recorded in the block header and is easily discoverable for current and historical purposes. The current gas price is a multiplier that determines the actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1 but would cost 2 CSPR if the current gas price is 2. As blocks become congested, the amount of CSPR required to obtain a slot for executing transactions will increase by a multiple. The following configuration settings control this behavior:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"upper_threshold"})," - The threshold to decrease gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"lower_threshold"})," - The threshold to increase gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"max_gas_price"})," - The maximum gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"min_gas_price"})," - The minimum gas price"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,s.jsx)(n.p,{children:"These are the block vacancy (dynamic gas pricing) settings for the Condor release on Mainnet. Before Condor, the gas price was 1, meaning 1 unit of gas cost 1 mote. With Condor, the multiple is configured to adjust between 1 and 3."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[vacancy]\n# The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network.\n#\n# The network starts with a current_gas_price of min_gas_price.\n#\n# Each block has multiple limits (bytes, transactions, transfers, gas, etc.)\n# The utilization for a block is determined by the highest percentage utilization of each these limits.\n#\n# Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here)\n# 19 transactons -> 19/20 or 95%\n# 600 transfers -> 600/650 or 92.3%\n# resulting block utilization is 95\n#\n# The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is\n# adjusted with the following:\n#\n# If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price.\n# If utilization falls between the thresholds, current_gas_price is not changed.\n# If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price.\n#\n# The cost charged for the transaction is simply the gas_used * current_gas_price.\nupper_threshold = 90\nlower_threshold = 50\nmax_gas_price = 3\nmin_gas_price = 1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"fixed-transaction-costs-vs-dynamic-gas-prices",children:"Fixed Transaction Costs vs. Dynamic Gas Prices"}),"\n",(0,s.jsxs)(n.p,{children:["The current gas price and the slot\u2019s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it\u2019s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost ",(0,s.jsx)(n.a,{href:"/runtime#lanes-and-gas-costs-lanes",children:"here"}),". Also, the ",(0,s.jsx)(n.code,{children:"pricing_handling = { type = 'fixed' }"})," setting is described ",(0,s.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"gas-tolerance",children:"Gas Tolerance"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"The cost of interacting with the blockchain increases during high network usage. Plan accordingly for any transactions and use the gas_tolerance field described below."})}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a ",(0,s.jsx)(n.code,{children:"gas_tolerance"})," field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with ",(0,s.jsx)(n.code,{children:"gas_tolerance = 2"})," and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block."]})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>c});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a35afcc3.76af9ebf.js b/assets/js/a35afcc3.76af9ebf.js new file mode 100644 index 000000000..f79a0a459 --- /dev/null +++ b/assets/js/a35afcc3.76af9ebf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[90398],{15739:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>s,metadata:()=>r,toc:()=>o});var c=a(74848),t=a(28453);const s={title:"Installation Workflow"},d="Installing an NFT Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client/full-installation-tutorial",title:"Installation Workflow",description:"This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of 1.63.0. The code for this tutorial is available in GitHub. A portion of this tutorial reviews the contract.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installation Workflow"},sidebar:"resources",previous:{title:"Quick Installation",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide"},next:{title:"Interaction Workflow",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs"}},i={},o=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Environment Setup",id:"environment-setup",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Building the Contract and Tests",id:"building-the-contract-and-tests",level:3},{value:"Reviewing the Contract Implementation",id:"reviewing-the-contract-implementation",level:2},{value:"Included Crates and Modules",id:"included-crates-and-modules",level:3},{value:"Initialization Flow",id:"initialization-flow",level:3},{value:"Contract Entrypoints",id:"contract-entrypoints",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Querying the Account State",id:"querying-the-account-state",level:3},{value:"Sending the Installation Deploy",id:"sending-the-installation-deploy",level:3},{value:"Verifying the Installation",id:"verifying-the-installation",level:3},{value:"Next Steps",id:"next-steps",level:2}];function f(e){const n={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"installing-an-nft-contract-using-the-rust-casper-client",children:"Installing an NFT Contract using the Rust Casper Client"})}),"\n",(0,c.jsxs)(n.p,{children:["This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of ",(0,c.jsx)(n.code,{children:"1.63.0"}),". The code for this tutorial is available in ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/",children:"GitHub"}),". A portion of this tutorial reviews the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/contract",children:"contract"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["Information on the modalities used throughout this installation process can be found in the ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/modalities",children:"modalities documentation"}),"."]}),"\n",(0,c.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#environment-setup",children:"Environment Setup"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#building-the-contract-and-tests",children:"Building the Contract and Tests"})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#reviewing-the-contract-implementation",children:"Reviewing the Contract Implementation"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#included-crates-and-modules",children:"Included Crates and Modules"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#initialization-flow",children:"Initialization Flow"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#contract-entrypoints",children:"Contract Entrypoints"})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#installing-the-contract",children:"Installing the Contract"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#querying-global-state",children:"Querying Global State"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#sending-the-installation-deploy",children:"Sending the Installation Deploy"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#verifying-the-installation",children:"Verifying the Installation"})}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#next-steps",children:"Next Steps"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"environment-setup",children:"Environment Setup"}),"\n",(0,c.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Set up the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"development prerequisites"}),", including the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper client"})]}),"\n",(0,c.jsxs)(n.li,{children:["Get a valid ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"node address"})," from the network"]}),"\n",(0,c.jsxs)(n.li,{children:["Know how to install a ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"smart contract"})," on a Casper network"]}),"\n",(0,c.jsx)(n.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read as a prerequisite."]}),"\n",(0,c.jsx)(n.h3,{id:"building-the-contract-and-tests",children:"Building the Contract and Tests"}),"\n",(0,c.jsx)(n.p,{children:"First, clone the contract from GitHub:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft\n"})}),"\n",(0,c.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,c.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,c.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["The contract code can be compiled to Wasm by running the ",(0,c.jsx)(n.code,{children:"make build-contract"})," command provided in the Makefile at the top level. The Wasm will be found in the ",(0,c.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory as ",(0,c.jsx)(n.code,{children:"contract.wasm"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"You can also compile your contract and run the contract unit tests with this command:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,c.jsx)(n.h2,{id:"reviewing-the-contract-implementation",children:"Reviewing the Contract Implementation"}),"\n",(0,c.jsxs)(n.p,{children:["In this repository, you will find a library and an ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/contract",children:"example NFT implementation"})," for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,c.jsx)(n.p,{children:"There are four steps to follow when you intend to create your implementation of the NFT contract, as follows:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,c.jsx)(n.li,{children:"Perform any necessary customization changes on your fork of the example contract."}),"\n",(0,c.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,c.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"included-crates-and-modules",children:"Included Crates and Modules"}),"\n",(0,c.jsx)(n.p,{children:"The contract implementation starts by importing the following essential Casper crates:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow the creation of Wasm contracts and tests for use on Casper networks"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The contract code defines additional modules in the ",(0,c.jsx)(n.code,{children:"contract/src"})," folder:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"constants"})," - Constant values required to run the contract code"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"error"})," - Errors related to the NFT contract"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"events"})," - A library for contract-emitted events"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"metadata"})," - A module handling the contract's metadata and corresponding dictionary"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"modalities"})," - Common expectations around contract usage and behavior"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"utils"})," - Utility and helper functions to run the contract code"]}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"initialization-flow",children:"Initialization Flow"}),"\n",(0,c.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,c.jsx)(n.code,{children:"call() -> install_contract() -> init()"})," functions inside the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"main.rs"})," contract file. The ",(0,c.jsx)(n.code,{children:"init()"})," function reads the runtime arguments and defines parameters such as ",(0,c.jsx)(n.code,{children:"collection_name"}),", ",(0,c.jsx)(n.code,{children:"collection_symbol"}),", and ",(0,c.jsx)(n.code,{children:"total_token_supply"}),", among the other required and optional arguments described ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/introduction#required-runtime-arguments",children:"here"}),"."]}),"\n",(0,c.jsx)(n.h3,{id:"contract-entrypoints",children:"Contract Entrypoints"}),"\n",(0,c.jsxs)(n.p,{children:["This section briefly explains the essential entrypoints used in the Casper NFT contract. To see their full implementation, refer to the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"main.rs"})," contract file. For further questions, contact the Casper support team via the ",(0,c.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1002",children:(0,c.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the owners\u2019s tokens"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1616",children:(0,c.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L874",children:(0,c.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1728",children:(0,c.jsx)(n.strong,{children:"get_approved"})})," - Returns the hash of the approved account for a specified token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L81",children:(0,c.jsx)(n.strong,{children:"init"})})," - Sets the collection name, symbol, and total token supply; initializes the allow minting setting, minting mode, ownership mode, NFT kind, holder mode, whitelist mode and contract whitelist, JSON schema, receipt name, identifier mode, and burn mode. This entrypoint can only be called once when the contract is installed on the network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1328",children:(0,c.jsx)(n.strong,{children:"is_approved_for_all"})})," - Returns yes if an account is approved as an operator for a token owner"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1675",children:(0,c.jsx)(n.strong,{children:"metadata"})})," - Returns the metadata associated with a token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L619",children:(0,c.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens if minting is allowed, increasing the total supply"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1636",children:(0,c.jsx)(n.strong,{children:"owner_of"})})," - Returns the owner for a specified token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2159",children:(0,c.jsx)(n.strong,{children:"register_owner"})})," - Register an owner for a specified token identifier. Works when the ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," is set to ",(0,c.jsx)(n.em,{children:"Complete"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1138",children:(0,c.jsx)(n.strong,{children:"revoke"})})," - Revokes an account that was approved for an identified token transfer. The ",(0,c.jsx)(n.em,{children:"OwnershipMode"})," must be set to ",(0,c.jsx)(n.em,{children:"Transferable"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1254",children:(0,c.jsx)(n.strong,{children:"set_approval_for_all"})})," - Allows a spender to transfer all of the owner's tokens"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1773",children:(0,c.jsx)(n.strong,{children:"set_token_metadata"})})," - Sets the metadata associated with a token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L496",children:(0,c.jsx)(n.strong,{children:"set_variables"})})," - Allows the user to set any combination of variables simultaneously, defining which variables are mutable or immutable"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1359",children:(0,c.jsx)(n.strong,{children:"transfer"})})," - Transfers tokens from the token owner to a specified account. The transfer will succeed if the caller is the token owner or an approved operator. The ",(0,c.jsx)(n.em,{children:"OwnershipMode"})," must be set to ",(0,c.jsx)(n.em,{children:"Transferable"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2111",children:(0,c.jsx)(n.strong,{children:"updated_receipts"})})," - Allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own. Works when the ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," is set to ",(0,c.jsx)(n.em,{children:"Complete"})]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["There is also the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1975",children:(0,c.jsx)(n.strong,{children:"migrate"})})," entrypoint, which was needed only for migrating a 1.0 version of the NFT contract to version 1.1."]}),"\n",(0,c.jsxs)(n.admonition,{type:"important",children:[(0,c.jsxs)(n.p,{children:["The following entrypoints return data using ",(0,c.jsx)(n.code,{children:"runtime::ret"}),", which is useful mainly if the entrypoint caller is a contract:"]}),(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"mint"})," (with ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," set to ",(0,c.jsx)(n.em,{children:"Complete"}),")"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"transfer"})," (with ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," set to ",(0,c.jsx)(n.em,{children:"TransfersOnly"}),")"]}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"balance_of"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"is_approved_for_all"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"owner_of"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"metadata"})}),"\n"]})]}),"\n",(0,c.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,c.jsxs)(n.p,{children:["Installing the enhanced NFT contract to global state requires using a ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Deploy"}),". But before proceeding with the installation, verify the network state and the status of the account that will send the installation deploy."]}),"\n",(0,c.jsx)(n.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,c.jsxs)(n.p,{children:["This step queries information about the network state given the latest state root hash. You will also need the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"IP address"})," from a Testnet peer node."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101/rpc/\n"})}),"\n",(0,c.jsx)(n.h3,{id:"querying-the-account-state",children:"Querying the Account State"}),"\n",(0,c.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash if you don't have it already."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY_HEX]\n"})}),"\n",(0,c.jsx)(n.p,{children:"Use the command below to query the state of your account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for a sample query and response"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101/rpc/ \\\n--state-root-hash 376b18e95312328f212f9966200fa40734e66118cbd34ace0a1ec14eacaea6e6 \\\n--key account-hash-82729ae3b368bb2c45d23c05c872c446cbcf32b694f1d9efd3d1ea46cf227a11\n"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -6733022256306802125,\n "result": {\n "api_version": "1.5.6",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[32706 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"sending-the-installation-deploy",children:"Sending the Installation Deploy"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state."]}),"\n",(0,c.jsxs)(n.p,{children:["Use the Testnet to understand the exact gas amount required for installation. Refer to the ",(0,c.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys#a-note-about-gas-price",children:"note about gas prices"})," to understand payment amounts and gas price adjustments."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc/ --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_name:string='CEP-78-collection'\""})}),"\n",(0,c.jsx)(n.p,{children:'The name of the NFT collection as a string. In this instance, "CEP-78-collection".'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_symbol:string='CEP78'\""})}),"\n",(0,c.jsx)(n.p,{children:'The symbol representing the NFT collection as a string. In this instance, "CEP78".'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"total_token_supply:u64='100'\""})}),"\n",(0,c.jsx)(n.p,{children:"The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"ownership_mode:u8='2'\""})}),"\n",(0,c.jsx)(n.p,{children:'The ownership mode for this contract. In this instance, the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_kind:u8='1'\""})}),"\n",(0,c.jsx)(n.p,{children:"The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_metadata_kind:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"json_schema:string=''\""})}),"\n",(0,c.jsx)(n.p,{children:"An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom-validated modality would require passing through a valid JSON schema for your custom metadata."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"identifier_mode:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"metadata_mutability:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The session arguments match the available ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/modalities",children:"modalities"}),"."]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for a sample query and response"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n",(0,c.jsxs)(n.p,{children:["This command will output the ",(0,c.jsx)(n.code,{children:"deploy_hash"}),", which can be used in the next step to verify the installation."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "jsonrpc": "2.0",\n "id": 3104428017957320684,\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "2b084bdccbaaae2b9c6e4de2f5a6cdf06c72f0d02eaeb7d681a29ebdbe3c92b7"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"verifying-the-installation",children:"Verifying the Installation"}),"\n",(0,c.jsxs)(n.p,{children:["Verify the sent deploy using the ",(0,c.jsx)(n.code,{children:"get-deploy"})," command."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://localhost:11101/rpc/ [DEPLOY_HASH]\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for sample deploy details"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -7282936875867676694,\n "result": {\n "api_version": "1.5.6",\n "deploy": {\n "hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2024-02-29T18:28:16.104Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "90866126c3dbb9a27f672307102bf651663934ee34715d46f9f02caa70226743",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "050088526a74",\n "parsed": "500000000000"\n }\n ]\n ]\n }\n },\n "session": {\n "ModuleBytes": {\n "module_bytes": "[621680 hex chars]",\n "args": [\n [\n "collection_name",\n {\n "cl_type": "String",\n "bytes": "120000004345502d37382d636f6c6c656374696f6e32",\n "parsed": "CEP-78-collection"\n }\n ],\n [\n "collection_symbol",\n {\n "cl_type": "String",\n "bytes": "050000004345503738",\n "parsed": "CEP78"\n }\n ],\n [\n "total_token_supply",\n {\n "cl_type": "U64",\n "bytes": "6400000000000000",\n "parsed": 100\n }\n ],\n [\n "ownership_mode",\n {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n ],\n [\n "nft_kind",\n {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n ],\n [\n "nft_metadata_kind",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ],\n [\n "json_schema",\n {\n "cl_type": "String",\n "bytes": "0a0000006e66742d736368656d61",\n "parsed": "nft-schema"\n }\n ],\n [\n "identifier_mode",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ],\n [\n "metadata_mutability",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01f866dd88fd179fd214262d0451a92be2673e6d4095eb79beef9e5b8bbbc18862e76c3085dcb1b1ae669a185cb80d94c5084325913b8118338645952bb5ee2200"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "dca9ff6e9ad7baeead715504dee098069f30dbb9975730be3d3926ab1c58f332",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-6174cf2e6f8fed1715c9a3bace9c50bfe572eecb763b0ed3f644532616452008",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05c2d627778f",\n "parsed": "616179422914"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "500000000000"\n }\n },\n {\n "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_package_CEP-78-collection",\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"\n }\n ]\n }\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_package_access_CEP-78-collection",\n "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-007"\n }\n ]\n }\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "Identity"\n },\n {\n "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": "WriteContract"\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_hash_CEP-78-collection",\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796"\n }\n ]\n }\n },\n {\n "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_version_CEP-78-collection",\n "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-007"\n }\n ]\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": "Identity"\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "Identity"\n },\n {\n "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "transform": "Identity"\n },\n {\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "120000004345502d37382d636f6c6c656374696f6e32",\n "parsed": "CEP-78-collection"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "collection_name",\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007"\n }\n ]\n }\n },\n {\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "050000004345503738",\n "parsed": "CEP78"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "collection_symbol",\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007"\n }\n ]\n }\n },\n {\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U64",\n "bytes": "6400000000000000",\n "parsed": 100\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "total_token_supply",\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007"\n }\n ]\n }\n },\n {\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "ownership_mode",\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007"\n }\n ]\n }\n },\n {\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_kind",\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007"\n }\n ]\n }\n },\n {\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "0a0000006e66742d736368656d61",\n "parsed": "nft-schema"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "json_schema",\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007"\n }\n ]\n }\n },\n {\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "minting_mode",\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007"\n }\n ]\n }\n },\n {\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "holder_mode",\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007"\n }\n ]\n }\n },\n {\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "whitelist_mode",\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007"\n }\n ]\n }\n },\n {\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "1800000063657037385f4345502d37382d636f6c6c656374696f6e32",\n "parsed": "cep78_CEP-78-collection"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "receipt_name",\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007"\n }\n ]\n }\n },\n {\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "[170 hex chars]",\n "parsed": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_CEP-78-collection",\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007"\n }\n ]\n }\n },\n {\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_metadata_kind",\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007"\n }\n ]\n }\n },\n {\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": {\n "Map": {\n "key": "U8",\n "value": "U8"\n }\n },\n "bytes": "010000000000",\n "parsed": [\n {\n "key": 0,\n "value": 0\n }\n ]\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_metadata_kinds",\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007"\n }\n ]\n }\n },\n {\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "identifier_mode",\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007"\n }\n ]\n }\n },\n {\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_mutability",\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007"\n }\n ]\n }\n },\n {\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "burn_mode",\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007"\n }\n ]\n }\n },\n {\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "operator_burn_mode",\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007"\n }\n ]\n }\n },\n {\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "events_mode",\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007"\n }\n ]\n }\n },\n {\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "01",\n "parsed": true\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "allow_minting",\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007"\n }\n ]\n }\n },\n {\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U64",\n "bytes": "0000000000000000",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "number_of_minted_tokens",\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007"\n }\n ]\n }\n },\n {\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "token_owners",\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007"\n }\n ]\n }\n },\n {\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "token_issuers",\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007"\n }\n ]\n }\n },\n {\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "approved",\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007"\n }\n ]\n }\n },\n {\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "operators",\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007"\n }\n ]\n }\n },\n {\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "burnt_tokens",\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007"\n }\n ]\n }\n },\n {\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "balances",\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007"\n }\n ]\n }\n },\n {\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_custom_validated",\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007"\n }\n ]\n }\n },\n {\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_cep78",\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007"\n }\n ]\n }\n },\n {\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_nft721",\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007"\n }\n ]\n }\n },\n {\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_raw",\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007"\n }\n ]\n }\n },\n {\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "hash_by_index",\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007"\n }\n ]\n }\n },\n {\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "index_by_hash",\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007"\n }\n ]\n }\n },\n {\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "page_table",\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007"\n }\n ]\n }\n },\n {\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "acl_whitelist",\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007"\n }\n ]\n }\n },\n {\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "acl_package_mode",\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007"\n }\n ]\n }\n },\n {\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "package_operator_mode",\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007"\n }\n ]\n }\n },\n {\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "reporting_mode",\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007"\n }\n ]\n }\n },\n {\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "rlo_mflag",\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007"\n }\n ]\n }\n },\n {\n "key": "deploy-1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "transfers": [],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "443359442322"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "055bdf0a5c67",\n "parsed": "443925847899"\n }\n }\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "AddUInt512": "56074152101"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85",\n "transform": {\n "AddUInt512": "443925847899"\n }\n }\n ]\n },\n "transfers": [],\n "cost": "443359442322"\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query"})," the NFT contract"]}),"\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(f,{...e})}):f(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>r});var c=a(96540);const t={},s=c.createContext(t);function d(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a35afcc3.c8f608cb.js b/assets/js/a35afcc3.c8f608cb.js deleted file mode 100644 index 5e5a91372..000000000 --- a/assets/js/a35afcc3.c8f608cb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[398],{15739:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>s,metadata:()=>r,toc:()=>o});var c=a(74848),t=a(28453);const s={title:"Installation Workflow"},d="Installing an NFT Contract using the Rust Casper Client",r={id:"resources/tokens/cep78/using-casper-client/full-installation-tutorial",title:"Installation Workflow",description:"This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of 1.63.0. The code for this tutorial is available in GitHub. A portion of this tutorial reviews the contract.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",permalink:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Installation Workflow"},sidebar:"resources",previous:{title:"Quick Installation",permalink:"/resources/tokens/cep78/using-casper-client/quickstart-guide"},next:{title:"Interaction Workflow",permalink:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs"}},i={},o=[{value:"Table of Contents",id:"table-of-contents",level:2},{value:"Environment Setup",id:"environment-setup",level:2},{value:"Prerequisites",id:"prerequisites",level:3},{value:"Building the Contract and Tests",id:"building-the-contract-and-tests",level:3},{value:"Reviewing the Contract Implementation",id:"reviewing-the-contract-implementation",level:2},{value:"Included Crates and Modules",id:"included-crates-and-modules",level:3},{value:"Initialization Flow",id:"initialization-flow",level:3},{value:"Contract Entrypoints",id:"contract-entrypoints",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:2},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Querying the Account State",id:"querying-the-account-state",level:3},{value:"Sending the Installation Deploy",id:"sending-the-installation-deploy",level:3},{value:"Verifying the Installation",id:"verifying-the-installation",level:3},{value:"Next Steps",id:"next-steps",level:2}];function f(e){const n={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"installing-an-nft-contract-using-the-rust-casper-client",children:"Installing an NFT Contract using the Rust Casper Client"})}),"\n",(0,c.jsxs)(n.p,{children:["This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of ",(0,c.jsx)(n.code,{children:"1.63.0"}),". The code for this tutorial is available in ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/",children:"GitHub"}),". A portion of this tutorial reviews the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/contract",children:"contract"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["Information on the modalities used throughout this installation process can be found in the ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"modalities documentation"}),"."]}),"\n",(0,c.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#environment-setup",children:"Environment Setup"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#building-the-contract-and-tests",children:"Building the Contract and Tests"})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#reviewing-the-contract-implementation",children:"Reviewing the Contract Implementation"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#included-crates-and-modules",children:"Included Crates and Modules"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#initialization-flow",children:"Initialization Flow"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#contract-entrypoints",children:"Contract Entrypoints"})}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#installing-the-contract",children:"Installing the Contract"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#querying-global-state",children:"Querying Global State"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#sending-the-installation-deploy",children:"Sending the Installation Deploy"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#verifying-the-installation",children:"Verifying the Installation"})}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"#next-steps",children:"Next Steps"})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"environment-setup",children:"Environment Setup"}),"\n",(0,c.jsx)(n.h3,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Set up the ",(0,c.jsx)(n.a,{href:"/developers/prerequisites",children:"development prerequisites"}),", including the ",(0,c.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})]}),"\n",(0,c.jsxs)(n.li,{children:["Get a valid ",(0,c.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"node address"})," from the network"]}),"\n",(0,c.jsxs)(n.li,{children:["Know how to install a ",(0,c.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"smart contract"})," on a Casper network"]}),"\n",(0,c.jsx)(n.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The ",(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing Rust Contracts on Casper"})," document outlines many aspects of this tutorial and should be read as a prerequisite."]}),"\n",(0,c.jsx)(n.h3,{id:"building-the-contract-and-tests",children:"Building the Contract and Tests"}),"\n",(0,c.jsx)(n.p,{children:"First, clone the contract from GitHub:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft\n"})}),"\n",(0,c.jsx)(n.p,{children:"Prepare your environment with the following command:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"make prepare\n"})}),"\n",(0,c.jsx)(n.p,{children:"If your environment is set up correctly, you will see this output:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ninfo: component 'rust-std' for target 'wasm32-unknown-unknown' is up to date\n"})}),"\n",(0,c.jsxs)(n.p,{children:["If you do not see this message, check the ",(0,c.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started Guide"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["The contract code can be compiled to Wasm by running the ",(0,c.jsx)(n.code,{children:"make build-contract"})," command provided in the Makefile at the top level. The Wasm will be found in the ",(0,c.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory as ",(0,c.jsx)(n.code,{children:"contract.wasm"}),"."]}),"\n",(0,c.jsx)(n.p,{children:"You can also compile your contract and run the contract unit tests with this command:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,c.jsx)(n.h2,{id:"reviewing-the-contract-implementation",children:"Reviewing the Contract Implementation"}),"\n",(0,c.jsxs)(n.p,{children:["In this repository, you will find a library and an ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/tree/dev/contract",children:"example NFT implementation"})," for Casper networks. This section explains the example contract in more detail."]}),"\n",(0,c.jsx)(n.p,{children:"There are four steps to follow when you intend to create your implementation of the NFT contract, as follows:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsx)(n.li,{children:"Fork the code from the example repository listed above."}),"\n",(0,c.jsx)(n.li,{children:"Perform any necessary customization changes on your fork of the example contract."}),"\n",(0,c.jsx)(n.li,{children:"Compile the customized code to Wasm."}),"\n",(0,c.jsx)(n.li,{children:"Send the customized Wasm as a deploy to a Casper network."}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"included-crates-and-modules",children:"Included Crates and Modules"}),"\n",(0,c.jsx)(n.p,{children:"The contract implementation starts by importing the following essential Casper crates:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:"casper_contract"})," - A Rust library for writing smart contracts on Casper networks"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper_types"})," - Types used to allow the creation of Wasm contracts and tests for use on Casper networks"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The contract code defines additional modules in the ",(0,c.jsx)(n.code,{children:"contract/src"})," folder:"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"constants"})," - Constant values required to run the contract code"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"error"})," - Errors related to the NFT contract"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"events"})," - A library for contract-emitted events"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"metadata"})," - A module handling the contract's metadata and corresponding dictionary"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"modalities"})," - Common expectations around contract usage and behavior"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"utils"})," - Utility and helper functions to run the contract code"]}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"initialization-flow",children:"Initialization Flow"}),"\n",(0,c.jsxs)(n.p,{children:["Initializing the contract happens through the ",(0,c.jsx)(n.code,{children:"call() -> install_contract() -> init()"})," functions inside the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"main.rs"})," contract file. The ",(0,c.jsx)(n.code,{children:"init()"})," function reads the runtime arguments and defines parameters such as ",(0,c.jsx)(n.code,{children:"collection_name"}),", ",(0,c.jsx)(n.code,{children:"collection_symbol"}),", and ",(0,c.jsx)(n.code,{children:"total_token_supply"}),", among the other required and optional arguments described ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/introduction#required-runtime-arguments",children:"here"}),"."]}),"\n",(0,c.jsx)(n.h3,{id:"contract-entrypoints",children:"Contract Entrypoints"}),"\n",(0,c.jsxs)(n.p,{children:["This section briefly explains the essential entrypoints used in the Casper NFT contract. To see their full implementation, refer to the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"main.rs"})," contract file. For further questions, contact the Casper support team via the ",(0,c.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord channel"}),"."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1002",children:(0,c.jsx)(n.strong,{children:"approve"})})," - Allows a spender to transfer up to an amount of the owners\u2019s tokens"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1616",children:(0,c.jsx)(n.strong,{children:"balance_of"})})," - Returns the token balance of the owner"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L874",children:(0,c.jsx)(n.strong,{children:"burn"})})," - Burns tokens, reducing the total supply"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1728",children:(0,c.jsx)(n.strong,{children:"get_approved"})})," - Returns the hash of the approved account for a specified token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L81",children:(0,c.jsx)(n.strong,{children:"init"})})," - Sets the collection name, symbol, and total token supply; initializes the allow minting setting, minting mode, ownership mode, NFT kind, holder mode, whitelist mode and contract whitelist, JSON schema, receipt name, identifier mode, and burn mode. This entrypoint can only be called once when the contract is installed on the network"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1328",children:(0,c.jsx)(n.strong,{children:"is_approved_for_all"})})," - Returns yes if an account is approved as an operator for a token owner"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1675",children:(0,c.jsx)(n.strong,{children:"metadata"})})," - Returns the metadata associated with a token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L619",children:(0,c.jsx)(n.strong,{children:"mint"})})," - Mints additional tokens if minting is allowed, increasing the total supply"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1636",children:(0,c.jsx)(n.strong,{children:"owner_of"})})," - Returns the owner for a specified token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2159",children:(0,c.jsx)(n.strong,{children:"register_owner"})})," - Register an owner for a specified token identifier. Works when the ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," is set to ",(0,c.jsx)(n.em,{children:"Complete"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1138",children:(0,c.jsx)(n.strong,{children:"revoke"})})," - Revokes an account that was approved for an identified token transfer. The ",(0,c.jsx)(n.em,{children:"OwnershipMode"})," must be set to ",(0,c.jsx)(n.em,{children:"Transferable"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1254",children:(0,c.jsx)(n.strong,{children:"set_approval_for_all"})})," - Allows a spender to transfer all of the owner's tokens"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1773",children:(0,c.jsx)(n.strong,{children:"set_token_metadata"})})," - Sets the metadata associated with a token identifier"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L496",children:(0,c.jsx)(n.strong,{children:"set_variables"})})," - Allows the user to set any combination of variables simultaneously, defining which variables are mutable or immutable"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1359",children:(0,c.jsx)(n.strong,{children:"transfer"})})," - Transfers tokens from the token owner to a specified account. The transfer will succeed if the caller is the token owner or an approved operator. The ",(0,c.jsx)(n.em,{children:"OwnershipMode"})," must be set to ",(0,c.jsx)(n.em,{children:"Transferable"})]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L2111",children:(0,c.jsx)(n.strong,{children:"updated_receipts"})})," - Allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own. Works when the ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," is set to ",(0,c.jsx)(n.em,{children:"Complete"})]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["There is also the ",(0,c.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/440bff44277ab5fd295f37229fe92278339d3753/contract/src/main.rs#L1975",children:(0,c.jsx)(n.strong,{children:"migrate"})})," entrypoint, which was needed only for migrating a 1.0 version of the NFT contract to version 1.1."]}),"\n",(0,c.jsxs)(n.admonition,{type:"important",children:[(0,c.jsxs)(n.p,{children:["The following entrypoints return data using ",(0,c.jsx)(n.code,{children:"runtime::ret"}),", which is useful mainly if the entrypoint caller is a contract:"]}),(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"mint"})," (with ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," set to ",(0,c.jsx)(n.em,{children:"Complete"}),")"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"transfer"})," (with ",(0,c.jsx)(n.em,{children:"OwnerReverseLookupMode"})," set to ",(0,c.jsx)(n.em,{children:"TransfersOnly"}),")"]}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"balance_of"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"is_approved_for_all"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"owner_of"})}),"\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:"metadata"})}),"\n"]})]}),"\n",(0,c.jsx)(n.h2,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,c.jsxs)(n.p,{children:["Installing the enhanced NFT contract to global state requires using a ",(0,c.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"Deploy"}),". But before proceeding with the installation, verify the network state and the status of the account that will send the installation deploy."]}),"\n",(0,c.jsx)(n.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,c.jsxs)(n.p,{children:["This step queries information about the network state given the latest state root hash. You will also need the ",(0,c.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"IP address"})," from a Testnet peer node."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101/rpc/\n"})}),"\n",(0,c.jsx)(n.h3,{id:"querying-the-account-state",children:"Querying the Account State"}),"\n",(0,c.jsx)(n.p,{children:"Run the following command and supply the path to your public key in hexadecimal format to get the account hash if you don't have it already."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY_HEX]\n"})}),"\n",(0,c.jsx)(n.p,{children:"Use the command below to query the state of your account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://<HOST:PORT> \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for a sample query and response"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://localhost:11101/rpc/ \\\n--state-root-hash 376b18e95312328f212f9966200fa40734e66118cbd34ace0a1ec14eacaea6e6 \\\n--key account-hash-82729ae3b368bb2c45d23c05c872c446cbcf32b694f1d9efd3d1ea46cf227a11\n"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -6733022256306802125,\n "result": {\n "api_version": "1.5.6",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "named_keys": [],\n "main_purse": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "[32706 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"sending-the-installation-deploy",children:"Sending the Installation Deploy"}),"\n",(0,c.jsxs)(n.p,{children:["Below is an example of a ",(0,c.jsx)(n.code,{children:"casper-client"})," command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state."]}),"\n",(0,c.jsxs)(n.p,{children:["Use the Testnet to understand the exact gas amount required for installation. Refer to the ",(0,c.jsx)(n.a,{href:"/developers/cli/sending-deploys#a-note-about-gas-price",children:"note about gas prices"})," to understand payment amounts and gas price adjustments."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.code,{children:'casper-client put-deploy -n http://localhost:11101/rpc/ --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-2/keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm'})}),"\n"]}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_name:string='CEP-78-collection'\""})}),"\n",(0,c.jsx)(n.p,{children:'The name of the NFT collection as a string. In this instance, "CEP-78-collection".'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"collection_symbol:string='CEP78'\""})}),"\n",(0,c.jsx)(n.p,{children:'The symbol representing the NFT collection as a string. In this instance, "CEP78".'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"total_token_supply:u64='100'\""})}),"\n",(0,c.jsx)(n.p,{children:"The total supply of tokens to be minted. In this instance, 100. If the contract owner is unsure of the total number of NFTs they will require, they should err on the side of caution."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"ownership_mode:u8='2'\""})}),"\n",(0,c.jsx)(n.p,{children:'The ownership mode for this contract. In this instance, the 2 represents "Transferable" mode. Under these conditions, users can freely transfer their NFTs between one another.'}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_kind:u8='1'\""})}),"\n",(0,c.jsx)(n.p,{children:"The type of commodity represented by these NFTs. In this instance, the 1 represents a digital collection."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"nft_metadata_kind:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"The type of metadata used by this contract. In this instance, the 0 represents CEP-78 standard for metadata."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"json_schema:string=''\""})}),"\n",(0,c.jsx)(n.p,{children:"An empty JSON string, as the contract has awareness of the CEP-78 JSON schema. Using the custom-validated modality would require passing through a valid JSON schema for your custom metadata."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"identifier_mode:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"The mode used to identify individual NFTs. For 0, this means an ordinal identification sequence rather than by hash."}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.code,{children:"--session-arg \"metadata_mutability:u8='0'\""})}),"\n",(0,c.jsx)(n.p,{children:"A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata."}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The session arguments match the available ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"modalities"}),"."]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for a sample query and response"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n",(0,c.jsxs)(n.p,{children:["This command will output the ",(0,c.jsx)(n.code,{children:"deploy_hash"}),", which can be used in the next step to verify the installation."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "jsonrpc": "2.0",\n "id": 3104428017957320684,\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "2b084bdccbaaae2b9c6e4de2f5a6cdf06c72f0d02eaeb7d681a29ebdbe3c92b7"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"verifying-the-installation",children:"Verifying the Installation"}),"\n",(0,c.jsxs)(n.p,{children:["Verify the sent deploy using the ",(0,c.jsx)(n.code,{children:"get-deploy"})," command."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://localhost:11101/rpc/ [DEPLOY_HASH]\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Expand for sample deploy details"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -7282936875867676694,\n "result": {\n "api_version": "1.5.6",\n "deploy": {\n "hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2024-02-29T18:28:16.104Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "90866126c3dbb9a27f672307102bf651663934ee34715d46f9f02caa70226743",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "050088526a74",\n "parsed": "500000000000"\n }\n ]\n ]\n }\n },\n "session": {\n "ModuleBytes": {\n "module_bytes": "[621680 hex chars]",\n "args": [\n [\n "collection_name",\n {\n "cl_type": "String",\n "bytes": "120000004345502d37382d636f6c6c656374696f6e32",\n "parsed": "CEP-78-collection"\n }\n ],\n [\n "collection_symbol",\n {\n "cl_type": "String",\n "bytes": "050000004345503738",\n "parsed": "CEP78"\n }\n ],\n [\n "total_token_supply",\n {\n "cl_type": "U64",\n "bytes": "6400000000000000",\n "parsed": 100\n }\n ],\n [\n "ownership_mode",\n {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n ],\n [\n "nft_kind",\n {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n ],\n [\n "nft_metadata_kind",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ],\n [\n "json_schema",\n {\n "cl_type": "String",\n "bytes": "0a0000006e66742d736368656d61",\n "parsed": "nft-schema"\n }\n ],\n [\n "identifier_mode",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ],\n [\n "metadata_mutability",\n {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01f866dd88fd179fd214262d0451a92be2673e6d4095eb79beef9e5b8bbbc18862e76c3085dcb1b1ae669a185cb80d94c5084325913b8118338645952bb5ee2200"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "dca9ff6e9ad7baeead715504dee098069f30dbb9975730be3d3926ab1c58f332",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "account-hash-6174cf2e6f8fed1715c9a3bace9c50bfe572eecb763b0ed3f644532616452008",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "05c2d627778f",\n "parsed": "616179422914"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "500000000000"\n }\n },\n {\n "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_package_CEP-78-collection",\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"\n }\n ]\n }\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_package_access_CEP-78-collection",\n "key": "uref-e42cd3ae8b4bd60306a72f0f4e9faa4e114e2e2cce5db03bfdd109a8db888e14-007"\n }\n ]\n }\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "Identity"\n },\n {\n "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": "WriteContract"\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_hash_CEP-78-collection",\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796"\n }\n ]\n }\n },\n {\n "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_contract_version_CEP-78-collection",\n "key": "uref-0545c60c0a55e4d8a10fe0c3b2d356150b082e2243b6795b34f67643e4ca13d0-007"\n }\n ]\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": "Identity"\n },\n {\n "key": "hash-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "transform": "Identity"\n },\n {\n "key": "hash-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "transform": "Identity"\n },\n {\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "120000004345502d37382d636f6c6c656374696f6e32",\n "parsed": "CEP-78-collection"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "collection_name",\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007"\n }\n ]\n }\n },\n {\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "050000004345503738",\n "parsed": "CEP78"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "collection_symbol",\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007"\n }\n ]\n }\n },\n {\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U64",\n "bytes": "6400000000000000",\n "parsed": 100\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "total_token_supply",\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007"\n }\n ]\n }\n },\n {\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "ownership_mode",\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007"\n }\n ]\n }\n },\n {\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "01",\n "parsed": 1\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_kind",\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007"\n }\n ]\n }\n },\n {\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "0a0000006e66742d736368656d61",\n "parsed": "nft-schema"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "json_schema",\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007"\n }\n ]\n }\n },\n {\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "minting_mode",\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007"\n }\n ]\n }\n },\n {\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "02",\n "parsed": 2\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "holder_mode",\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007"\n }\n ]\n }\n },\n {\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "whitelist_mode",\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007"\n }\n ]\n }\n },\n {\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "1800000063657037385f4345502d37382d636f6c6c656374696f6e32",\n "parsed": "cep78_CEP-78-collection"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "receipt_name",\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007"\n }\n ]\n }\n },\n {\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "String",\n "bytes": "[170 hex chars]",\n "parsed": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30"\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "cep78_CEP-78-collection",\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007"\n }\n ]\n }\n },\n {\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_metadata_kind",\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007"\n }\n ]\n }\n },\n {\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": {\n "Map": {\n "key": "U8",\n "value": "U8"\n }\n },\n "bytes": "010000000000",\n "parsed": [\n {\n "key": 0,\n "value": 0\n }\n ]\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "nft_metadata_kinds",\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007"\n }\n ]\n }\n },\n {\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "identifier_mode",\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007"\n }\n ]\n }\n },\n {\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_mutability",\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007"\n }\n ]\n }\n },\n {\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "burn_mode",\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007"\n }\n ]\n }\n },\n {\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "operator_burn_mode",\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007"\n }\n ]\n }\n },\n {\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "events_mode",\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007"\n }\n ]\n }\n },\n {\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "01",\n "parsed": true\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "allow_minting",\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007"\n }\n ]\n }\n },\n {\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U64",\n "bytes": "0000000000000000",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "number_of_minted_tokens",\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007"\n }\n ]\n }\n },\n {\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "token_owners",\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007"\n }\n ]\n }\n },\n {\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "token_issuers",\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007"\n }\n ]\n }\n },\n {\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "approved",\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007"\n }\n ]\n }\n },\n {\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "operators",\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007"\n }\n ]\n }\n },\n {\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "burnt_tokens",\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007"\n }\n ]\n }\n },\n {\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "balances",\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007"\n }\n ]\n }\n },\n {\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_custom_validated",\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007"\n }\n ]\n }\n },\n {\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_cep78",\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007"\n }\n ]\n }\n },\n {\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_nft721",\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007"\n }\n ]\n }\n },\n {\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "metadata_raw",\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007"\n }\n ]\n }\n },\n {\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "hash_by_index",\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007"\n }\n ]\n }\n },\n {\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "index_by_hash",\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007"\n }\n ]\n }\n },\n {\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "page_table",\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007"\n }\n ]\n }\n },\n {\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "acl_whitelist",\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007"\n }\n ]\n }\n },\n {\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "acl_package_mode",\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007"\n }\n ]\n }\n },\n {\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "package_operator_mode",\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007"\n }\n ]\n }\n },\n {\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U8",\n "bytes": "00",\n "parsed": 0\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "reporting_mode",\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007"\n }\n ]\n }\n },\n {\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-000",\n "transform": {\n "WriteCLValue": {\n "cl_type": "Bool",\n "bytes": "00",\n "parsed": false\n }\n }\n },\n {\n "key": "hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796",\n "transform": {\n "AddKeys": [\n {\n "name": "rlo_mflag",\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007"\n }\n ]\n }\n },\n {\n "key": "deploy-1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1d1f66b26eb648b5f15bc958a552036e8521b508706056817b0d41c71f6d7afe",\n "transfers": [],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "443359442322"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "055bdf0a5c67",\n "parsed": "443925847899"\n }\n }\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "AddUInt512": "56074152101"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-dcf5abbbe00715e9a05f7449109b1d297cb1584560ec4f3f5a86401452e40d85",\n "transform": {\n "AddUInt512": "443925847899"\n }\n }\n ]\n },\n "transfers": [],\n "cost": "443359442322"\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query"})," the NFT contract"]}),"\n",(0,c.jsxs)(n.li,{children:["Learn to ",(0,c.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(f,{...e})}):f(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>r});var c=a(96540);const t={},s=c.createContext(t);function d(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a36dca7d.ea67c2e6.js b/assets/js/a36dca7d.ea67c2e6.js new file mode 100644 index 000000000..2110e64b5 --- /dev/null +++ b/assets/js/a36dca7d.ea67c2e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55740],{48553:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});var a=s(74848),r=s(28453);const d={title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},c="Querying a Casper Node",t={id:"resources/beginner/querying-network",title:"Querying a Node",description:"The Casper node supports queries for users and developers to obtain information stored on the blockchain.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/querying-network.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/querying-network",permalink:"/2.0.0/resources/tutorials/beginner/querying-network",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/2.0.0/resources/beginner/counter-testnet/walkthrough"},next:{title:"Contract Upgrades",permalink:"/2.0.0/resources/tutorials/beginner/upgrade-contract"}},i={},o=[{value:"Obtaining the Global State Root Hash",id:"obtaining-the-global-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying Blocks",id:"querying-blocks",level:2},{value:"Querying Deploys",id:"querying-deploys",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"querying-a-casper-node",children:"Querying a Casper Node"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper node supports queries for users and developers to obtain information stored on the blockchain."}),"\n",(0,a.jsx)(n.p,{children:"This document assumes:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["You have met the ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,a.jsxs)(n.li,{children:["You are familiar with the structure of the ",(0,a.jsx)(n.a,{href:"/2.0.0/design",children:"Global State and the Blockchain Design"})," to query data from the network"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Account details"}),"\n",(0,a.jsx)(n.li,{children:"Block information"}),"\n",(0,a.jsx)(n.li,{children:"Deploy information"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"obtaining-the-global-state-root-hash",children:"Obtaining the Global State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node."}),"\n",(0,a.jsxs)(n.p,{children:["All queries made to global state require the ",(0,a.jsx)(n.code,{children:"state-root-hash"}),", which you can obtain with this command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash \\\n --id 1 \\\n --node-address http://<node-ip-address>:7777\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"Accounts"})," are stored in the global state and can be queried using the ",(0,a.jsx)(n.code,{children:"query-global-state"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --id 4 \\\n --node-address http://<node-ip-address>:7777 \\\n --state-root-hash <state-root-hash> \\\n --key <hex-encoded-source-account-public-key>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Account Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To query the account balance, use the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address http://<node-ip-address>:7777 \\\n--state-root-hash <state-root-hash> \\\n--purse-identifier <account>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Balance Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-blocks",children:"Querying Blocks"}),"\n",(0,a.jsx)(n.p,{children:"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-block \\\n --id 3 \\\n --node-address http://<node-ip-address>:7777 \\\n --block-identifier <block-hash> \\\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."block"."header"."state_root_hash"'})," - contains the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," for this block"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-deploys",children:"Querying Deploys"}),"\n",(0,a.jsxs)(n.p,{children:["Once you submit a deploy to the network, you can check its execution status using ",(0,a.jsx)(n.code,{children:"get-deploy"}),". If the ",(0,a.jsx)(n.code,{children:"execution_results"})," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --id 2 \\\n --node-address http://<node-ip-address>:7777 \\\n <deploy-hash>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"deploy-hash"})," - Hex-encoded hash of the deploy"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var a=s(96540);const r={},d=a.createContext(r);function c(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3c7ece8.5621f945.js b/assets/js/a3c7ece8.5621f945.js new file mode 100644 index 000000000..071007f15 --- /dev/null +++ b/assets/js/a3c7ece8.5621f945.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76214],{55405:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>o});var t=a(74848),s=a(28453);const r={},i="Proof-of-Stake JSON-RPC Methods",c={id:"developers/json-rpc/json-rpc-pos",title:"Proof-of-Stake JSON-RPC Methods",description:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-pos.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-pos",permalink:"/2.0.0/developers/json-rpc/json-rpc-pos",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Informational JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-informational"},next:{title:"Types",permalink:"/2.0.0/developers/json-rpc/types_chain"}},d={},o=[{value:"state_get_auction_info",id:"state_get_auction_info",level:2},{value:"<code>state_get_auction_info_result</code>",id:"state_get_auction_info_result",level:3},{value:"info_get_validator_changes",id:"info_get_validator_changes",level:2},{value:"<code>info_get_validator_changes_result</code>",id:"info_get_validator_changes_result",level:3},{value:"chain_get_era_info_by_switch_block",id:"chain_get_era_info_by_switch_block",level:2},{value:"<code>chain_get_era_info_by_switch_block_result</code>",id:"chain_get_era_info_by_switch_block_result",level:3}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"proof-of-stake-json-rpc-methods",children:"Proof-of-Stake JSON-RPC Methods"})}),"\n",(0,t.jsx)(n.p,{children:"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"state_get_auction_info",children:"state_get_auction_info"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/consensus#bids",children:"bids"})," and ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validators"})," from a specific Block (by height or hash). If you do not provide a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", ",(0,t.jsx)(n.code,{children:"state_get_auction_info"})," will return information from the most recent Block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The Block identifier. (Optional)"})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_auction_info",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"state_get_auction_info_result",children:(0,t.jsx)(n.code,{children:"state_get_auction_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#auctionstate",children:"auction_state"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The auction state."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example state_get_auction_info result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_auction_info_result",\n "value": {\n "api_version": "2.0.0",\n "auction_state": {\n "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",\n "block_height": 10,\n "era_validators": [\n {\n "era_id": 10,\n "validator_weights": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "weight": "10"\n }\n ]\n }\n ],\n "bids": [\n {\n "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bid": {\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",\n "staked_amount": "20",\n "delegation_rate": 0,\n "vesting_schedule": null,\n "delegators": [\n {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "delegator": {\n "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",\n "staked_amount": "10",\n "bonding_purse": "uref-fbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb-007",\n "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",\n "vesting_schedule": null\n }\n }\n ],\n "inactive": false\n }\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"info_get_validator_changes",children:"info_get_validator_changes"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns status changes of active validators. Listed changes occurred during the ",(0,t.jsx)(n.code,{children:"EraId"})," contained within the response itself. A validator may show more than one change in a single era."]}),"\n",(0,t.jsx)(n.p,{children:"Potential change types:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Change Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Added"}),(0,t.jsx)(n.td,{children:"The validator has been added to the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Removed"}),(0,t.jsx)(n.td,{children:"The validator has been removed from the set."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Banned"}),(0,t.jsx)(n.td,{children:"The validator has been banned in the current era."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"CannotPropose"}),(0,t.jsx)(n.td,{children:"The validator cannot propose a Block."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"SeenAsFaulty"}),(0,t.jsx)(n.td,{children:"The validator has performed questionable activity."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_validator_changes",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"info_get_validator_changes_result",children:(0,t.jsx)(n.code,{children:"info_get_validator_changes_result"})}),"\n",(0,t.jsxs)(n.p,{children:["If no changes occurred in the current era, ",(0,t.jsx)(n.code,{children:"info_get_validator_changes"})," will return empty."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#jsonvalidatorchanges",children:"changes"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The validators' status changes."})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example info_get_validator_changes result"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_validator_changes_result",\n "value": {\n "api_version": "2.0.0",\n "changes": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "status_changes": [\n {\n "era_id": 1,\n "validator_change": "Added"\n }\n ]\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chain_get_era_info_by_switch_block",children:"chain_get_era_info_by_switch_block"}),"\n",(0,t.jsxs)(n.p,{children:["This method returns an EraInfo from the network. Only the last Block in an ",(0,t.jsx)(n.code,{children:"era"}),", known as a switch block, will contain an ",(0,t.jsx)(n.code,{children:"era_summary"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsx)(n.tbody,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsxs)(n.td,{children:["The Block identifier. If you do not supply a ",(0,t.jsx)(n.code,{children:"block_identifier"}),", the returned information will be the most recent Block. (Optional)"]})]})})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block request"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_era_info_by_switch_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"chain_get_era_info_by_switch_block_result",children:(0,t.jsx)(n.code,{children:"chain_get_era_info_by_switch_block_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Type"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"api_version"}),(0,t.jsx)(n.td,{children:"String"}),(0,t.jsx)(n.td,{children:"The RPC API version."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,t.jsx)(n.td,{children:"Object"}),(0,t.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example chain_get_era_info_by_switch_block"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_era_info_by_switch_block_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>i,x:()=>c});var t=a(96540);const s={},r=t.createContext(s);function i(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3dc4ae2.0aa14bc4.js b/assets/js/a3dc4ae2.0aa14bc4.js deleted file mode 100644 index c3127354f..000000000 --- a/assets/js/a3dc4ae2.0aa14bc4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3100],{43322:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var s=t(74848),r=t(28453);const a={},o="Go SDK",d={id:"developers/dapps/sdk/go-sdk",title:"Go SDK",description:"Usage Examples",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/go-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/go-sdk",permalink:"/developers/dapps/sdk/go-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:".NET SDK",permalink:"/developers/dapps/sdk/csharp-sdk"},next:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"}},l={},c=[{value:"Usage Examples",id:"usage-examples",level:2},{value:"Get a Deploy from the Network",id:"get-a-deploy-from-the-network",level:3},{value:"Handle the Deploy Processed Event",id:"handle-the-deploy-processed-event",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"go-sdk",children:"Go SDK"})}),"\n",(0,s.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,s.jsx)(n.p,{children:"This section includes some examples of how to use Go SDK:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"#get-a-deploy-from-the-network",children:["Get a ",(0,s.jsx)(n.em,{children:"Deploy"})," from the Network"]})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a Transfer"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"get-a-deploy-from-the-network",children:"Get a Deploy from the Network"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "fmt"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n)\n\nfunc main() {\n handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https://<Node Address and Port>/events/main")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n'})})]})}function i(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3dc4ae2.ee951085.js b/assets/js/a3dc4ae2.ee951085.js new file mode 100644 index 000000000..28102c119 --- /dev/null +++ b/assets/js/a3dc4ae2.ee951085.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93100],{43322:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var s=t(74848),r=t(28453);const a={},o="Go SDK",d={id:"developers/dapps/sdk/go-sdk",title:"Go SDK",description:"Usage Examples",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/go-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/go-sdk",permalink:"/1.5.X/developers/dapps/sdk/go-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:".NET SDK",permalink:"/1.5.X/developers/dapps/sdk/csharp-sdk"},next:{title:"Python SDK",permalink:"/1.5.X/developers/dapps/sdk/python-sdk"}},l={},c=[{value:"Usage Examples",id:"usage-examples",level:2},{value:"Get a Deploy from the Network",id:"get-a-deploy-from-the-network",level:3},{value:"Handle the Deploy Processed Event",id:"handle-the-deploy-processed-event",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"go-sdk",children:"Go SDK"})}),"\n",(0,s.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,s.jsx)(n.p,{children:"This section includes some examples of how to use Go SDK:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"#get-a-deploy-from-the-network",children:["Get a ",(0,s.jsx)(n.em,{children:"Deploy"})," from the Network"]})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a Transfer"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"get-a-deploy-from-the-network",children:"Get a Deploy from the Network"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "fmt"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n)\n\nfunc main() {\n handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https://<Node Address and Port>/events/main")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n'})})]})}function i(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a3e473b3.b3680e8e.js b/assets/js/a3e473b3.b3680e8e.js new file mode 100644 index 000000000..74820b914 --- /dev/null +++ b/assets/js/a3e473b3.b3680e8e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[44479],{61441:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const o={title:"Front-end in React"},i="Front-end Template with React",a={id:"developers/dapps/template-frontend",title:"Front-end in React",description:"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/template-frontend.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/template-frontend",permalink:"/2.0.0/developers/dapps/template-frontend",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Front-end in React"},sidebar:"developers",previous:{title:"dApp Technology Stack",permalink:"/2.0.0/developers/dapps/technology-stack"},next:{title:"URef Access Rights",permalink:"/2.0.0/developers/dapps/uref-security"}},c={},l=[{value:"Get Started",id:"get-started",level:2},{value:"Casper Wallet Integration",id:"casper-wallet-integration",level:2},{value:"Disconnect the Casper Wallet",id:"disconnect-the-casper-wallet",level:3},{value:"Call a Smart Contract",id:"call-a-smart-contract",level:2},{value:"Query a Smart Contract",id:"query-a-smart-contract",level:2},{value:"Test Application",id:"test-application",level:2},{value:"Build for Production",id:"build-for-production",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"front-end-template-with-react",children:"Front-end Template with React"})}),"\n",(0,s.jsxs)(n.p,{children:["For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide will walk you through setting up and developing a React application with ",(0,s.jsx)(n.a,{href:"https://vitejs.dev/",children:"Vite"})," that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by ",(0,s.jsx)(n.a,{href:"https://reactjs.org/docs/getting-started.html",children:"reading the React documentation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"get-started",children:"Get Started"}),"\n",(0,s.jsx)(n.p,{children:"Begin by opening a terminal and running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"node -v\n"})}),"\n",(0,s.jsx)(n.p,{children:"To get your Node.js version."}),"\n",(0,s.jsxs)(n.p,{children:["To ensure compatibility, you should be running Node.js version 18 or above. Upgrade to version 18 using the ",(0,s.jsx)(n.a,{href:"https://github.com/nvm-sh/nvm",children:"Node Version Manager"})," or another tool if you are running an earlier version."]}),"\n",(0,s.jsxs)(n.p,{children:["Using ",(0,s.jsx)(n.a,{href:"https://www.npmjs.com/",children:"npm"}),", create a new Vite project by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install -g vite\nnpm create vite@latest\n"})}),"\n",(0,s.jsx)(n.p,{children:'Name your project, select "React", then choose your preferred language. In this example, we will use JavaScript.'}),"\n",(0,s.jsxs)(n.p,{children:["Head into your new project directory, replacing ",(0,s.jsx)(n.code,{children:"vite-project"})," with your project name:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd vite-project/\n"})}),"\n",(0,s.jsx)(n.p,{children:"Run the following command to test the server:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install\nvite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Quit the server by pressing ",(0,s.jsx)(n.code,{children:"q"}),". Install the Casper JS SDK by running the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This guide will use ",(0,s.jsx)(n.a,{href:"https://axios-http.com/",children:"axios"})," to communicate with the backend; install it by running:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"npm install axios\n"})}),"\n",(0,s.jsx)(n.h2,{id:"casper-wallet-integration",children:"Casper Wallet Integration"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Wallet extension content script injects the SDK into your website's global scope. Provider class and event types can be accessed with ",(0,s.jsx)(n.code,{children:"window.CasperWalletProvider"})," and ",(0,s.jsx)(n.code,{children:"window.CasperWalletEventTypes"}),". If the value of these variables is ",(0,s.jsx)(n.code,{children:"undefined"})," the Casper Wallet is not installed."]}),"\n",(0,s.jsx)(n.p,{children:"Start with a helper for getting the provider instance:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/casper-wallet.js\n"})}),"\n",(0,s.jsx)(n.p,{children:"Fill the file with the following content:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-js",children:'// Timeout (in ms) for requests to the extension [DEFAULT: 30 min]\nconst REQUESTS_TIMEOUT_MS = 30 * 60 * 1000;\n\nexport const getProvider = () => {\n let providerConstructor = window.CasperWalletProvider;\n if (providerConstructor === undefined) {\n alert("Casper Wallet extension is not installed!");\n return;\n }\n let provider = providerConstructor({\n timeout: REQUESTS_TIMEOUT_MS\n });\n return provider;\n}\n\n'})}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["For complete integration details, refer to ",(0,s.jsx)(n.a,{href:"https://github.com/make-software/casper-wallet-sdk/#readme",children:"README of Casper Wallet SDK"}),"."]})}),"\n",(0,s.jsxs)(n.p,{children:["To ensure that a user's public key will be available to all necessary components, create a React state variable in ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," or another parent component that encapsulates the components that should have access to this public key:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n </>)}\n </div>\n </>\n );\n}\n\nexport default App;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["This is an example of ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," that imports and displays the ",(0,s.jsx)(n.code,{children:"Connect"})," component that is described next. The ",(0,s.jsx)(n.code,{children:"setPublicKey"})," function is passed to the ",(0,s.jsx)(n.code,{children:"Connect"})," component as a ",(0,s.jsx)(n.a,{href:"https://legacy.reactjs.org/docs/components-and-props.html",children:"prop"})," so that it may set the public key and make it available to all of ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),". This way, when more components are added to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", they may utilize the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable."]}),"\n",(0,s.jsxs)(n.p,{children:["To connect to the Casper Wallet within your React app, create the ",(0,s.jsx)(n.code,{children:"Connect"})," component and import the ",(0,s.jsx)(n.code,{children:"getProvider"})," helper."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Connect.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n {/* Place for disconnect button */}\n </>\n );\n}\n\nexport default Connect;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Notice that ",(0,s.jsx)(n.code,{children:"Connect"})," accepts props, and forwards them to the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function described below. This function is called when the button is clicked, allowing it to set the public key within ",(0,s.jsx)(n.em,{children:"src/App.jsx"})," using ",(0,s.jsx)(n.code,{children:"props.setPublicKey()"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Write the ",(0,s.jsx)(n.code,{children:"connectToWallet"})," function under the ",(0,s.jsx)(n.code,{children:"Connect"})," function component:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const connectToWallet = (props) => {\n provider.requestConnection().then(connected => {\n if (!connected) {\n alert("Couldn\'t connect to wallet");\n } else {\n provider.getActivePublicKey().then(publicKey => {\n props.setPublicKey(publicKey);\n }).catch(error => {\n alert(error.message);\n });\n }\n })\n .catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"connectToWallet()"})," function calls ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," to check if the Casper Wallet is already connected. If it is, it gets the public key of the selected account; if it's not, it opens up a connection request within the Wallet. ",(0,s.jsx)(n.code,{children:"provider.isConnected()"})," will throw an error if the Wallet is not installed as an extension or if it is locked."]}),"\n",(0,s.jsx)(n.h3,{id:"disconnect-the-casper-wallet",children:"Disconnect the Casper Wallet"}),"\n",(0,s.jsxs)(n.p,{children:["To request that the Casper Wallet disconnect from a website, add the following function call to ",(0,s.jsx)(n.em,{children:"src/Connect.jsx"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const disconnect = (props) => {\n provider.disconnectFromSite().then(disconnected => {\n if (disconnected) {\n props.setPublicKey(null);\n alert("Disconnected");\n } \n }).catch(error => {\n alert(error.message);\n });\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Then connect it to a button:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:"const Connect = (props) => {\n return (\n <>\n <button onClick={ () => connectToWallet(props) }>Connect Wallet</button>\n // highlight-next-line-green\n <button onClick={ () => disconnect(props) }>Disconnect</button>\n </>\n );\n}\n"})}),"\n",(0,s.jsx)(n.h2,{id:"call-a-smart-contract",children:"Call a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:['For this example, we\'ll call a hypothetical "hello world" contract containing a single entrypoint "update_message". We\'ll call the "update_message" entrypoint with text entered by the user in an HTML ',(0,s.jsx)(n.code,{children:"input"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["When calling smart contracts from React, you'll need to implement the logic within a function accessible from a React component. You can obtain user-entered data from the DOM using elements like ",(0,s.jsx)(n.code,{children:"input"}),", then grab the value within the smart-contract-calling function."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/UpdateMessage.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import { useState } from \'react\';\nimport { Contracts, CasperClient, RuntimeArgs, CLValueBuilder, CLPublicKey, DeployUtil } from "casper-js-sdk";\nimport axios from "axios";\nimport { getProvider } from "./casper-wallet";\n\nconst provider = getProvider();\n\nconst UpdateMessage = (props) => {\n const [message, setMessage] = useState("");\n\n return (\n <>\n <input id="message" type="text" value={message} onChange={(e) => {setMessage(e.target.value)}} />\n <button onClick={ () => updateMessage(props, message) }>Update Message</button>\n </>\n );\n}\n\nexport default UpdateMessage;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["On the front-end you'll need to build the deploy and forward it to the Casper Wallet to be signed. In most cases, you will be calling smart contract entrypoints. This example deploy shows the calling of entrypoint \"update_message\" which will update the chain's global state to reflect the new data. You'll need the user's active public key to prepare the deploy, and you may retrieve this from the ",(0,s.jsx)(n.code,{children:"publicKey"})," variable passed in as a prop from ",(0,s.jsx)(n.code,{children:"src/App.jsx"}),". Write this function under your ",(0,s.jsx)(n.code,{children:"UpdateMessage"})," component function."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const NODE_URL = "http://65.108.127.242:7777/rpc";\nconst NETWORK_NAME = "casper-test"; // "casper" for mainnet\nconst CONTRACT_HASH = "hash-75143aa708275b7dead20ac2cc06c1c3eccff4ffcf1eb9aebb8cce7c35cea041";\n\nconst updateMessage = (props, message) => {\n const casperClient = new CasperClient(NODE_URL);\n const contract = new Contracts.Contract(casperClient);\n contract.setContractHash(CONTRACT_HASH);\n const runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string(message)\n });\n const deploy = contract.callEntrypoint(\n "update_message",\n runtimeArguments,\n CLPublicKey.fromHex(props.publicKey),\n NETWORK_NAME,\n "1000000000", // 1 CSPR (10^9 Motes)\n );\n const deployJSON = DeployUtil.deployToJson(deploy);\n provider.sign(JSON.stringify(deployJSON), props.publicKey).then((signedDeploy) => { // Initiates sign request\n axios.post("/sendDeploy", signedDeploy, {\n headers: {\n \'Content-Type\': \'application/json\'\n }\n }).then((response) => {\n alert(response.data);\n }).catch((error) => {\n console.error(error.message);\n });\n }).catch((error) => {\n console.error(error.message);\n });\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In this example, ",(0,s.jsx)(n.code,{children:"updateMessage"})," builds a deploy and forwards it to the Casper Wallet to be signed by the user. Once it's been signed, ",(0,s.jsx)(n.code,{children:"signedDeploy"})," is forwarded to the backend at the ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," endpoint using ",(0,s.jsx)(n.code,{children:"axios.post"})," before being sent off to a Casper node. If an error occurs, or the user rejects the signature request, it will be logged to ",(0,s.jsx)(n.code,{children:"stderr"}),". In this particular example, the result of this deployment will be presented to the user in the form of a JavaScript ",(0,s.jsx)(n.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/Window/alert",children:"alert"}),"; however, you may do with the response data as you wish."]}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["The backend endpoint ",(0,s.jsx)(n.code,{children:"/sendDeploy"})," should handle signed deployment by simply passing it to a Casper node."]}),(0,s.jsxs)(n.p,{children:["In Casper node ",(0,s.jsx)(n.code,{children:"v1.5.0"}),", which sets up appropriate CORS headers, it will also be possible to send deployments directly from the browser, without relying on a backend server. This is useful for prototyping, however it is advised that you operate your own node."]})]}),"\n",(0,s.jsxs)(n.p,{children:["Now that this component is created, render it to the user interface in ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", passing along the ",(0,s.jsx)(n.code,{children:"publicKey"})," as a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\n// highlight-next-line-green\nimport UpdateMessage from "./UpdateMessage";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n // highlight-next-line-green\n <UpdateMessage publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"query-a-smart-contract",children:"Query a Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Consider that the message written to the chain during the ",(0,s.jsx)(n.code,{children:"update_message"})," entrypoint invocation is stored in the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/D#dictionary",children:"dictionary"})," ",(0,s.jsx)(n.code,{children:"messages"})," in the contract. Further consider that each account may write its own message and that the messages are stored under the account's ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/A#account-hash",children:"account hash"})," as the dictionary key. Querying this kind of data is essential in any dApp; here is how to communicate contract data to and from the front-end."]}),"\n",(0,s.jsx)(n.p,{children:"Create a new component:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"touch src/Query.jsx\n"})}),"\n",(0,s.jsx)(n.p,{children:"Open the file and write:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import axios from "axios";\nimport { CLPublicKey } from "casper-js-sdk";\n\nconst Query = (props) => {\n return <button onClick={ () => query(props) }>Query</button>;\n}\n\nconst query = (props) => {\n const accountHash = CLPublicKey.fromHex(props.publicKey).toAccountHashStr().substring(13);\n axios.get("/queryMessage?accountHash=" + accountHash).then((response) => {\n alert(response.data)\n }).catch((error) => {\n console.error(error.message);\n });\n}\n\nexport default Query;\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All this component does is render an HTML ",(0,s.jsx)(n.code,{children:"button"})," element that, when pressed, performs a ",(0,s.jsx)(n.code,{children:"GET"})," request to the backend that includes the user's active account hash. The account hash is derived from the active public key, and is used to look up the message stored by the current user."]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"toAccountHashStr"}),' method produces a string that is prepended by the text "account-hash-". In this case, this text is not needed, so it is discarded by chaining on the ',(0,s.jsx)(n.code,{children:"substring(13)"})," method."]})}),"\n",(0,s.jsx)(n.admonition,{type:"info",children:(0,s.jsxs)(n.p,{children:["This functionality relies on the ",(0,s.jsx)(n.code,{children:"/queryMessage"})," endpoint, which should be implemented in your backend."]})}),"\n",(0,s.jsxs)(n.p,{children:["Now add this component to ",(0,s.jsx)(n.em,{children:"src/App.jsx"}),", making available the ",(0,s.jsx)(n.code,{children:"publicKey"})," state variable via a prop:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-jsx",children:'import React from "react";\nimport Connect from "./Connect";\nimport UpdateMessage from "./UpdateMessage";\n// highlight-next-line-green\nimport Query from "./Query";\nimport \'./App.css\'\n\nfunction App() {\n const [publicKey, setPublicKey] = React.useState(null);\n return (\n <>\n <Connect setPublicKey={ setPublicKey } />\n <div>\n {publicKey !== null && (<>\n Wallet connected: {publicKey}<br/>\n <UpdateMessage publicKey={ publicKey } />\n // highlight-next-line-green\n <Query publicKey={ publicKey } />\n </>)}\n </div>\n </>\n );\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"test-application",children:"Test Application"}),"\n",(0,s.jsx)(n.p,{children:"Test your application by running the following:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite dev\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Your application will start locally, and a URL will be shown where you can visit your application. Alternatively, press ",(0,s.jsx)(n.code,{children:"h"}),", then ",(0,s.jsx)(n.code,{children:"o"})," to open the app in a browser."]}),"\n",(0,s.jsx)(n.h2,{id:"build-for-production",children:"Build for Production"}),"\n",(0,s.jsx)(n.p,{children:"When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite build\n"})}),"\n",(0,s.jsx)(n.p,{children:"Once this is complete, you can preview your production build by running:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"vite preview\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>a});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4046515.82e9c056.js b/assets/js/a4046515.82e9c056.js deleted file mode 100644 index 480148f36..000000000 --- a/assets/js/a4046515.82e9c056.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[453],{48724:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var n=a(74848),o=a(28453);const s={},i="Global State {#global-state-head}",r={id:"concepts/global-state",title:"Global State",description:"global-state-head}",source:"@site/versioned_docs/version-1.5.X/concepts/global-state.md",sourceDirName:"concepts",slug:"/concepts/global-state",permalink:"/concepts/global-state",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Deploy Lifecycle",permalink:"/deploy-and-deploy-lifecycle"},next:{title:"Smart Contracts",permalink:"/concepts/smart-contracts"}},l={},c=[{value:"Introduction",id:"global-state-intro",level:2},{value:"Merkle Trie Structure",id:"global-state-trie",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"global-state-head",children:"Global State"})}),"\n",(0,n.jsx)(t.h2,{id:"global-state-intro",children:"Introduction"}),"\n",(0,n.jsxs)(t.p,{children:["The storage layer for the Casper blockchain is called ",(0,n.jsx)(t.em,{children:"global state"})," and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly."]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Refer to ",(0,n.jsx)(t.a,{href:"/concepts/serialization-standard#serialization-standard-state-keys",children:"Keys and Permissions"})," for further information on keys."]})}),"\n",(0,n.jsxs)(t.p,{children:["Each finalized block causes changes to the network's global state because of the execution of the deploys it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a ",(0,n.jsx)(t.a,{href:"#global-state-trie",children:"Merkle trie"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"global-state-trie",children:"Merkle Trie Structure"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Global State",src:a(68500).A+"",width:"5344",height:"4496"})}),"\n",(0,n.jsx)(t.p,{children:"At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes."}),"\n",(0,n.jsx)(t.p,{children:"Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value."}),"\n",(0,n.jsx)(t.p,{children:"Formally, a trie node is one of the following:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"a leaf, which includes a key and a value"}),"\n",(0,n.jsxs)(t.li,{children:["a branch, which has up to 256 ",(0,n.jsx)(t.code,{children:"blake2b256"})," hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)"]}),"\n",(0,n.jsxs)(t.li,{children:["an extension node, which includes a byte array (called the affix) and a ",(0,n.jsx)(t.code,{children:"blake2b256"})," hash pointing to another node in the trie"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node."}),"\n",(0,n.jsx)(t.p,{children:"The Rust implementation of Casper's trie can be found on GitHub:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie/mod.rs#L340",children:"Definition of the trie data structure"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L44",children:"Reading from the trie"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L845",children:"Writing to the trie"})}),"\n"]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Conceptually, each block has its trie because the state changes based on the deploys it contains. For this reason, Casper's implementation has a notion of a ",(0,n.jsx)(t.code,{children:"TrieStore"}),", which allows us to look up the root node for each trie."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},68500:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/global-state-6ff422f087f093966968318f641d26fc.png"},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>r});var n=a(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4046515.c01a629a.js b/assets/js/a4046515.c01a629a.js new file mode 100644 index 000000000..aa2f7374f --- /dev/null +++ b/assets/js/a4046515.c01a629a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50453],{48724:(e,t,a)=>{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>r,toc:()=>c});var n=a(74848),o=a(28453);const s={},i="Global State {#global-state-head}",r={id:"concepts/global-state",title:"Global State",description:"global-state-head}",source:"@site/versioned_docs/version-1.5.X/concepts/global-state.md",sourceDirName:"concepts",slug:"/concepts/global-state",permalink:"/1.5.X/concepts/global-state",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Deploy Lifecycle",permalink:"/1.5.X/deploy-and-deploy-lifecycle"},next:{title:"Smart Contracts",permalink:"/1.5.X/concepts/smart-contracts"}},l={},c=[{value:"Introduction",id:"global-state-intro",level:2},{value:"Merkle Trie Structure",id:"global-state-trie",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"global-state-head",children:"Global State"})}),"\n",(0,n.jsx)(t.h2,{id:"global-state-intro",children:"Introduction"}),"\n",(0,n.jsxs)(t.p,{children:["The storage layer for the Casper blockchain is called ",(0,n.jsx)(t.em,{children:"global state"})," and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly."]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Refer to ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/serialization-standard#serialization-standard-state-keys",children:"Keys and Permissions"})," for further information on keys."]})}),"\n",(0,n.jsxs)(t.p,{children:["Each finalized block causes changes to the network's global state because of the execution of the deploys it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a ",(0,n.jsx)(t.a,{href:"#global-state-trie",children:"Merkle trie"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"global-state-trie",children:"Merkle Trie Structure"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Global State",src:a(22982).A+"",width:"5344",height:"4496"})}),"\n",(0,n.jsx)(t.p,{children:"At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes."}),"\n",(0,n.jsx)(t.p,{children:"Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value."}),"\n",(0,n.jsx)(t.p,{children:"Formally, a trie node is one of the following:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"a leaf, which includes a key and a value"}),"\n",(0,n.jsxs)(t.li,{children:["a branch, which has up to 256 ",(0,n.jsx)(t.code,{children:"blake2b256"})," hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)"]}),"\n",(0,n.jsxs)(t.li,{children:["an extension node, which includes a byte array (called the affix) and a ",(0,n.jsx)(t.code,{children:"blake2b256"})," hash pointing to another node in the trie"]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node."}),"\n",(0,n.jsx)(t.p,{children:"The Rust implementation of Casper's trie can be found on GitHub:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie/mod.rs#L340",children:"Definition of the trie data structure"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L44",children:"Reading from the trie"})}),"\n",(0,n.jsx)(t.li,{children:(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/c8db6a737c41dcdfb86ed6bed16d24284cf5c3b9/execution_engine/src/storage/trie_store/operations/mod.rs#L845",children:"Writing to the trie"})}),"\n"]}),"\n",(0,n.jsx)(t.admonition,{type:"note",children:(0,n.jsxs)(t.p,{children:["Conceptually, each block has its trie because the state changes based on the deploys it contains. For this reason, Casper's implementation has a notion of a ",(0,n.jsx)(t.code,{children:"TrieStore"}),", which allows us to look up the root node for each trie."]})})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},22982:(e,t,a)=>{a.d(t,{A:()=>n});const n=a.p+"assets/images/global-state-6ff422f087f093966968318f641d26fc.png"},28453:(e,t,a)=>{a.d(t,{R:()=>i,x:()=>r});var n=a(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a40a2cf8.5c89beea.js b/assets/js/a40a2cf8.5c89beea.js deleted file mode 100644 index 9bf0178ac..000000000 --- a/assets/js/a40a2cf8.5c89beea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5458],{21814:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Endpoints"},o="Node Endpoints",a={id:"operators/setup/node-endpoints",title:"Endpoints",description:"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.",source:"@site/versioned_docs/version-1.5.X/operators/setup/node-endpoints.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-endpoints",permalink:"/operators/setup/node-endpoints",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Endpoints"},sidebar:"operators",previous:{title:"Configuration",permalink:"/operators/setup/basic-node-configuration"},next:{title:"Installation",permalink:"/operators/setup/install-node"}},d={},c=[{value:"Default Networking Port: 35000",id:"35000",level:2},{value:"Default JSON-RPC HTTP Server Port: 7777",id:"7777",level:2},{value:"Default REST HTTP Server Port: 8888",id:"8888",level:2},{value:"Example usage",id:"example-usage",level:3},{value:"Default SSE HTTP Event Stream Server Port: 9999",id:"9999",level:2},{value:"Setting up Firewall Rules",id:"setting-up-firewall-rules",level:2},{value:"Restricting Access for Private Networks",id:"restricting-access-for-private-networks",level:2},{value:"Summary of Related Links",id:"summary-of-related-links",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"node-endpoints",children:"Node Endpoints"})}),"\n",(0,t.jsxs)(n.p,{children:["As specified in the ",(0,t.jsx)(n.a,{href:"/operators/setup/install-node#network-requirements",children:"Network Requirements"}),", a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The ",(0,t.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network Communication"})," page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication."]}),"\n",(0,t.jsx)(n.p,{children:"This document describes in more detail a Casper node's default endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#35000",children:"Networking port: 35000"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#7777",children:"JSON-RPC HTTP server port: 7777"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#8888",children:"REST HTTP server port: 8888"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#9999",children:"SSE HTTP event stream server port: 9999"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Node operators can modify a node's configuration options, including the port settings, by updating the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"node's config.toml"})," file. An example configuration file can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up."}),"\n",(0,t.jsx)(n.h2,{id:"35000",children:"Default Networking Port: 35000"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for networking are under the ",(0,t.jsx)(n.code,{children:"network"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"bind_address"})," using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the ",(0,t.jsx)(n.code,{children:"config.toml"})," file, the setting is:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"bind_address = '0.0.0.0:35000'\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline."}),"\n",(0,t.jsx)(n.h2,{id:"7777",children:"Default JSON-RPC HTTP Server Port: 7777"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rpc_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," using port 7777 is the listening address for JSON-RPC HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:7777'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["DApps would use this address to ",(0,t.jsx)(n.a,{href:"/developers/json-rpc/",children:"interact with the Casper JSON-RPC API"}),". Users would use this address to ",(0,t.jsx)(n.a,{href:"/developers/cli/",children:"interact with the network using CLI"}),". Validators would use this address to ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding#bonding-system-auction",children:"bond"})," or ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"unbond"}),". If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."]}),"\n",(0,t.jsx)(n.h2,{id:"8888",children:"Default REST HTTP Server Port: 8888"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rest_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 8888 is the listening address for the REST HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:8888'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."}),"\n",(0,t.jsxs)(n.p,{children:["One may use this port to ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"get a trusted hash"}),", ",(0,t.jsx)(n.a,{href:"/operators/setup/upgrade#verifying-successful-staging",children:"verify successful staging"})," during an upgrade, or to ",(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"confirm that the node is synchronized"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"example-usage",children:"Example usage"}),"\n",(0,t.jsx)(n.p,{children:"For general health metrics, use this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/metrics\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can check the node's status using this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The status endpoint provides a JSON response that can be parsed with ",(0,t.jsx)(n.code,{children:"jq"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...\n {\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can filter the result with dot notation, specifying one of the following parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"api_version"})," - The RPC API version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chainspec_name"})," - The chainspec name, used to identify the currently connected network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"starting_state_root_hash"})," - The state root hash used at the start of the current session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"peers"})," - The node ID and network address of each connected peer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"last_added_block_info"})," - The minimal info of the last Block from the linear chain"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"our_public_signing_key"})," - Our public signing key"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"round_length"})," - The next round length if this node is a validator."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"next_upgrade"})," - Information about the next scheduled upgrade"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"build_version"})," - The compiled node version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"uptime"})," - Time that has passed since the node has started."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is an example command for retrieving general network information:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To get information about the next upgrade, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .next_upgrade\n"})}),"\n",(0,t.jsx)(n.p,{children:"To get information about the last added block, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .last_added_block_info\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor the downloading of blocks to your node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor local block height as well as RPC port status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"9999",children:"Default SSE HTTP Event Stream Server Port: 9999"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the SSE HTTP event stream server are listed under the ",(0,t.jsx)(n.code,{children:"event_stream_server"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 9999 is the listening address for the SSE HTTP event stream server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:9999'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-firewall-rules",children:"Setting up Firewall Rules"}),"\n",(0,t.jsxs)(n.p,{children:["To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,t.jsx)(n.code,{children:"ufw"})," commands below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."}),"\n",(0,t.jsxs)(n.p,{children:["If you have any concerns, questions, or issues, please ",(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/requests/new",children:"submit a request"})," to the Casper support team."]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-access-for-private-networks",children:"Restricting Access for Private Networks"}),"\n",(0,t.jsxs)(n.p,{children:["Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,t.jsx)(n.a,{href:"/operators/setup-network/create-private#network-access-control",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"summary-of-related-links",children:"Summary of Related Links"}),"\n",(0,t.jsx)(n.p,{children:"Here is a summary of the links mentioned on this page:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/install-node#network-requirements",children:"Network requirements"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network communication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"The node configuration file"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/cli/",children:"Interacting with the network using CLI"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding#bonding-system-auction",children:"Bonding"})," or ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"unbonding"})," as a validator"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Getting a trusted node hash"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/upgrade#verifying-successful-staging",children:"Verifying successful staging"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"Confirming that the node is synchronized"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and consuming events"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup-network/create-private#network-access-control",children:"Private network access control"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a40a2cf8.a2747ba0.js b/assets/js/a40a2cf8.a2747ba0.js new file mode 100644 index 000000000..8363af1d7 --- /dev/null +++ b/assets/js/a40a2cf8.a2747ba0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25458],{21814:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Endpoints"},o="Node Endpoints",a={id:"operators/setup/node-endpoints",title:"Endpoints",description:"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.",source:"@site/versioned_docs/version-1.5.X/operators/setup/node-endpoints.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-endpoints",permalink:"/1.5.X/operators/setup/node-endpoints",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Endpoints"},sidebar:"operators",previous:{title:"Configuration",permalink:"/1.5.X/operators/setup/basic-node-configuration"},next:{title:"Installation",permalink:"/1.5.X/operators/setup/install-node"}},d={},c=[{value:"Default Networking Port: 35000",id:"35000",level:2},{value:"Default JSON-RPC HTTP Server Port: 7777",id:"7777",level:2},{value:"Default REST HTTP Server Port: 8888",id:"8888",level:2},{value:"Example usage",id:"example-usage",level:3},{value:"Default SSE HTTP Event Stream Server Port: 9999",id:"9999",level:2},{value:"Setting up Firewall Rules",id:"setting-up-firewall-rules",level:2},{value:"Restricting Access for Private Networks",id:"restricting-access-for-private-networks",level:2},{value:"Summary of Related Links",id:"summary-of-related-links",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"node-endpoints",children:"Node Endpoints"})}),"\n",(0,t.jsxs)(n.p,{children:["As specified in the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node#network-requirements",children:"Network Requirements"}),", a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/p2p",children:"Network Communication"})," page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication."]}),"\n",(0,t.jsx)(n.p,{children:"This document describes in more detail a Casper node's default endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#35000",children:"Networking port: 35000"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#7777",children:"JSON-RPC HTTP server port: 7777"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#8888",children:"REST HTTP server port: 8888"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#9999",children:"SSE HTTP event stream server port: 9999"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Node operators can modify a node's configuration options, including the port settings, by updating the ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#config-file",children:"node's config.toml"})," file. An example configuration file can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up."}),"\n",(0,t.jsx)(n.h2,{id:"35000",children:"Default Networking Port: 35000"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for networking are under the ",(0,t.jsx)(n.code,{children:"network"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"bind_address"})," using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the ",(0,t.jsx)(n.code,{children:"config.toml"})," file, the setting is:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"bind_address = '0.0.0.0:35000'\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline."}),"\n",(0,t.jsx)(n.h2,{id:"7777",children:"Default JSON-RPC HTTP Server Port: 7777"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rpc_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," using port 7777 is the listening address for JSON-RPC HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:7777'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["DApps would use this address to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/",children:"interact with the Casper JSON-RPC API"}),". Users would use this address to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/",children:"interact with the network using CLI"}),". Validators would use this address to ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/bonding#bonding-system-auction",children:"bond"})," or ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/unbonding",children:"unbond"}),". If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."]}),"\n",(0,t.jsx)(n.h2,{id:"8888",children:"Default REST HTTP Server Port: 8888"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rest_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 8888 is the listening address for the REST HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:8888'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."}),"\n",(0,t.jsxs)(n.p,{children:["One may use this port to ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"get a trusted hash"}),", ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/upgrade#verifying-successful-staging",children:"verify successful staging"})," during an upgrade, or to ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"confirm that the node is synchronized"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"example-usage",children:"Example usage"}),"\n",(0,t.jsx)(n.p,{children:"For general health metrics, use this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/metrics\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can check the node's status using this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The status endpoint provides a JSON response that can be parsed with ",(0,t.jsx)(n.code,{children:"jq"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...\n {\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can filter the result with dot notation, specifying one of the following parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"api_version"})," - The RPC API version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chainspec_name"})," - The chainspec name, used to identify the currently connected network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"starting_state_root_hash"})," - The state root hash used at the start of the current session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"peers"})," - The node ID and network address of each connected peer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"last_added_block_info"})," - The minimal info of the last Block from the linear chain"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"our_public_signing_key"})," - Our public signing key"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"round_length"})," - The next round length if this node is a validator."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"next_upgrade"})," - Information about the next scheduled upgrade"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"build_version"})," - The compiled node version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"uptime"})," - Time that has passed since the node has started."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is an example command for retrieving general network information:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To get information about the next upgrade, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .next_upgrade\n"})}),"\n",(0,t.jsx)(n.p,{children:"To get information about the last added block, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .last_added_block_info\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor the downloading of blocks to your node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor local block height as well as RPC port status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"9999",children:"Default SSE HTTP Event Stream Server Port: 9999"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the SSE HTTP event stream server are listed under the ",(0,t.jsx)(n.code,{children:"event_stream_server"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 9999 is the listening address for the SSE HTTP event stream server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:9999'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-firewall-rules",children:"Setting up Firewall Rules"}),"\n",(0,t.jsxs)(n.p,{children:["To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,t.jsx)(n.code,{children:"ufw"})," commands below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."}),"\n",(0,t.jsxs)(n.p,{children:["If you have any concerns, questions, or issues, please ",(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/requests/new",children:"submit a request"})," to the Casper support team."]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-access-for-private-networks",children:"Restricting Access for Private Networks"}),"\n",(0,t.jsxs)(n.p,{children:["Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup-network/create-private#network-access-control",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"summary-of-related-links",children:"Summary of Related Links"}),"\n",(0,t.jsx)(n.p,{children:"Here is a summary of the links mentioned on this page:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node#network-requirements",children:"Network requirements"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/p2p",children:"Network communication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#config-file",children:"The node configuration file"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/",children:"Interacting with the network using CLI"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/bonding#bonding-system-auction",children:"Bonding"})," or ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/unbonding",children:"unbonding"})," as a validator"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Getting a trusted node hash"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/upgrade#verifying-successful-staging",children:"Verifying successful staging"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"Confirming that the node is synchronized"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"Monitoring and consuming events"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup-network/create-private#network-access-control",children:"Private network access control"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a434b528.63eb51ca.js b/assets/js/a434b528.63eb51ca.js deleted file mode 100644 index ec00433c9..000000000 --- a/assets/js/a434b528.63eb51ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[884],{77875:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var s=t(74848),a=t(28453);const o={title:"Sending Deploys"},r="Sending Deploys using the Casper Client",c={id:"developers/cli/sending-deploys",title:"Sending Deploys",description:"To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:",source:"@site/versioned_docs/version-1.5.X/developers/cli/sending-deploys.md",sourceDirName:"developers/cli",slug:"/developers/cli/sending-deploys",permalink:"/developers/cli/sending-deploys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Sending Deploys"},sidebar:"developers",previous:{title:"Undelegating Tokens",permalink:"/developers/cli/undelegate"},next:{title:"Installing Contracts",permalink:"/developers/cli/installing-contracts"}},d={},i=[{value:"Paying for Deploys",id:"paying-for-deploys",level:2},{value:"Monitoring the Event Stream for Deploys",id:"monitoring-the-event-stream-for-deploys",level:2},{value:"Sending a Deploy to the Network",id:"sending-the-deploy",level:2},{value:"Time-to-live",id:"ttl",level:3},{value:"Deploy Payments",id:"deploy-payments",level:3},{value:"Using Arguments with Deploys",id:"using-arguments-with-deploys",level:2},{value:"Advanced Features",id:"advanced-features",level:2},{value:"A Note about Gas Price",id:"a-note-about-gas-price",level:2}];function l(e){const n={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"sending-deploys-using-the-casper-client",children:"Sending Deploys using the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["To install smart contracts on the blockchain, you can send your Wasm to the network via a ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy"}),". To do this, you will need to meet a few prerequisites:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You will need a client to interact with the network, such as the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have an ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Account"})," and its associated ",(0,s.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"keys"})," This account will pay for the Deploy, and its secret key will sign the Deploy"]}),"\n",(0,s.jsx)(n.li,{children:"Ensure this account has enough CSPR tokens to pay for the Deploy"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"paying-for-deploys",children:"Paying for Deploys"}),"\n",(0,s.jsx)(n.p,{children:"CSPR tokens are used to pay for deploys on the Casper Mainnet and Testnet. There are several ways to fund your account:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You may want to ",(0,s.jsx)(n.a,{href:"/users/funding-from-exchanges",children:"transfer tokens from an exchange"})]}),"\n",(0,s.jsxs)(n.li,{children:["You can use a ",(0,s.jsx)(n.a,{href:"/users/token-transfer",children:"block explorer to transfer tokens"})," between accounts' purses"]}),"\n",(0,s.jsxs)(n.li,{children:["You can also ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/",children:"transfer tokens using the default Casper client"})]}),"\n",(0,s.jsxs)(n.li,{children:["On the Testnet, you can use the ",(0,s.jsx)(n.a,{href:"/users/testnet-faucet",children:"faucet functionality"})," for testing your smart contracts"]}),"\n",(0,s.jsxs)(n.li,{children:["If running a network locally using ",(0,s.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"NCTL"}),", the tool provides several funded accounts"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"monitoring-the-event-stream-for-deploys",children:"Monitoring the Event Stream for Deploys"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to follow the ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"lifecycle"})," of the Deploy, you can start monitoring a node's event stream. This section will focus only on DeployAccepted events, but there are other event types described ",(0,s.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"here"}),". You need the following information to proceed:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The IP address of a ",(0,s.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"peer"})," on the network"]}),"\n",(0,s.jsxs)(n.li,{children:["The port specified as the ",(0,s.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(n.em,{children:"config.toml"}),", which is by default 9999 on Mainnet and Testnet"]}),"\n",(0,s.jsxs)(n.li,{children:["The URL for DeployAccepted events, which is ",(0,s.jsx)(n.code,{children:"HOST:PORT"}),"/events/deploys"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"With the following command, you can start watching the event stream for DeployAccepted events. Note the event ID recorded when you send the Deploy in the next section."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://65.21.235.219:9999/events/deploys\n"})}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-deploy",children:"Sending a Deploy to the Network"}),"\n",(0,s.jsxs)(n.p,{children:["You can call the Casper client's ",(0,s.jsx)(n.code,{children:"put-deploy"})," command to put the compiled contract on the chain. In this example, the Deploy will execute in the account's context. See the ",(0,s.jsx)(n.a,{href:"#advanced-features",children:"advanced features"})," section for key delegation."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name casper-test \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH>\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,s.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example"}),". You may send deploys to one of the trusted nodes or use them to query other online nodes."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"}),". As you can see, this example uses the Testnet"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This example uses 2.5 CSPR, but you need to modify this for your contract. See the ",(0,s.jsx)(n.a,{href:"#a-note-about-gas-price",children:"note"})," below"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's execution results. Sending the deploy and receiving the deploy hash does not mean the deploy was processed successfully. Therefore, you must check the deploy execution using the deploy hash. See the deploy lifecycle for more details."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Each Deploy gets a unique hash, which is part of the cryptographic security of blockchain technology. No two deploys will ever return the same hash."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Sample put-deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": -6958186952964949950,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Verify the deploy details with the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," received above."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address <HOST:PORT> <DEPLOY-HASH>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the Deploy succeeded, the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command would return a JSON object with the full deploy details."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Sample get-deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": -3532286620275982221,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy": {\n "approvals": [\n {\n "signature": "015a7b0178e144fbf5ce52147c44a3e6bd6aae898ec6bb47c97b5802f3bcb6cd26331f7db18464cd1e51764c14ceb24b7ab9c4e3595505c32465fc0702e8d5510b",\n "signer": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d"\n }\n ],\n "hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "header": {\n "account": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d",\n "body_hash": "b1956600be3c11d7555ada11426ab1a8bdf36102f59838d6bf69cec321111a22",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-03-24T12:05:57.579Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "05000c774203",\n "cl_type": "U512",\n "parsed": "14000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[94478 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "098b618878a2413393925e1fbf6d3cf92f1208f4f8662a904e86b49b0c4ab9f0",\n "result": {\n "Success": {\n "cost": "13327900740",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": {\n "WriteCLValue": {\n "bytes": "0500279bd1ca",\n "cl_type": "U512",\n "parsed": "871100000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "14000000000"\n }\n },\n {\n "key": "uref-82a7b5713f2b9b3f9e1b4f2d1f312a5fec7c3a0bed6fa897501913951729dbbf-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n },\n {\n "key": "uref-ea022d75ff618533baf46040cc57692fb7f7840774c979c9dec0b5c3ddcec7e9-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "Identity"\n },\n {\n "key": "hash-3b69bafcc13b4541dddd7d5492e4754feee41c636990aeb6bf78d58fdd39fc43",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "transform": "WriteContract"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "name": "counter"\n }\n ]\n }\n },\n {\n "key": "deploy-34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "from": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "gas": "13327900740",\n "source": "uref-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": {\n "AddUInt512": "14000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"We want to draw your attention to a few properties in the example output:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Execution cost 13327900740 motes, yet we paid 14000000000 motes. See the ",(0,s.jsx)(n.a,{href:"#a-note-about-gas-price",children:"note about gas price"})]}),"\n",(0,s.jsxs)(n.li,{children:['The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,s.jsx)(n.code,{children:"--payment-amount"})," arg"]}),"\n",(0,s.jsx)(n.li,{children:"The time-to-live was 30 minutes"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["It is also possible to get a summary of the deploy's information by performing a ",(0,s.jsx)(n.code,{children:"query-global-state"})," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address <HOST:PORT>\n\ncasper-client query-global-state --node-address <HOST:PORT> \\\n --key deploy-<DEPLOY-HASH-HEX-STRING> \\\n --state-root-hash <STATE-ROOT-HASH-HEX-STRING>\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address <HOST:PORT> \\\n --key deploy-<DEPLOY-HASH-HEX STRING>\n --block-hash <BLOCK-HASH-HEX-STRING>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Run the help command for ",(0,s.jsx)(n.code,{children:"query-global-state"})," to see its usage."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --help\n"})}),"\n",(0,s.jsx)(n.h3,{id:"ttl",children:"Time-to-live"}),"\n",(0,s.jsxs)(n.p,{children:["Time-to-live is the parameter that determines how long a deploy will wait for execution. The acceptable maximum ",(0,s.jsx)(n.code,{children:"ttl"})," is configurable by chain, with the Casper Mainnet maximum set to ",(0,s.jsx)(n.code,{children:"18hours"}),". If you are sending a deploy to a different network, you will need to check ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid deploy."]}),"\n",(0,s.jsxs)(n.p,{children:["In the event of a network outage or other event that prevents execution within the ",(0,s.jsx)(n.code,{children:"ttl"}),", the solution is to resend the deploy in question."]}),"\n",(0,s.jsxs)(n.p,{children:["Should the deploy's ",(0,s.jsx)(n.code,{children:"ttl"})," exceed the allowable limit, or if the deploy expires, the network's deploy acceptor will find the deploy invalid and return a warning."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-payments",children:"Deploy Payments"}),"\n",(0,s.jsx)(n.p,{children:"Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution."}),"\n",(0,s.jsxs)(n.p,{children:["The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,s.jsx)(n.strong,{children:"empty"})," ",(0,s.jsx)(n.code,{children:"ModuleBytes"})," as your payment code. However, you must specify the amount within a runtime argument. ",(0,s.jsx)(n.code,{children:"ModuleBytes"})," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."]}),"\n",(0,s.jsx)(n.p,{children:"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredContractByHash"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredContractByName"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredVersionContractByHash"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredVersionContractByName"})]}),"\n",(0,s.jsx)(n.h2,{id:"using-arguments-with-deploys",children:"Using Arguments with Deploys"}),"\n",(0,s.jsxs)(n.p,{children:["The session Wasm (or payment Wasm if you choose to ",(0,s.jsx)(n.em,{children:"not"}),' use the standard payment) of a Deploy often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,s.jsx)(n.code,{children:"--session-arg"})," or ",(0,s.jsx)(n.code,{children:"--payment-arg"})," options, once for each arg required. The Casper client provides some examples of how to do this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --show-arg-examples\n"})}),"\n",(0,s.jsx)(n.h2,{id:"advanced-features",children:"Advanced Features"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks support complex deploys using multiple signatures. ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Casper Accounts"})," use a powerful permissions model that enables a multi-signature scheme for deploys."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"put-deploy"})," command performs multiple actions under the hood, optimizing the typical use case. It creates a deploy, signs it, and sends the Deploy to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"make-deploy"})," - Creates a Deploy and outputs it to a file or stdout. As a file, the deploy can subsequently be signed by other parties using the ",(0,s.jsx)(n.code,{children:"sign-deploy"})," subcommand and then sent to the network for execution using the ",(0,s.jsx)(n.code,{children:"send-deploy"})," subcommand"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"sign-deploy"})," - Reads a previously-saved Deploy from a file, cryptographically signs it, and outputs it to a file or stdout"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"send-deploy"})," - Reads a previously-saved Deploy from a file and sends it to the network for execution"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To sign a Deploy with multiple keys, create the Deploy with the ",(0,s.jsx)(n.code,{children:"make-deploy"})," command. The generated deploy file can be sent to the other signers, who then sign it with their keys by calling the ",(0,s.jsx)(n.code,{children:"sign-deploy"})," for each key. Signatures need to be gathered on the Deploy one after another until all required parties have signed the Deploy. Finally, the signed Deploy is sent to the network with the ",(0,s.jsx)(n.code,{children:"send-deploy"})," command for processing."]}),"\n",(0,s.jsxs)(n.p,{children:["For a step-by-step workflow, visit the ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"Two-Party Multi-Signature Deploy"})," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network."]}),"\n",(0,s.jsx)(n.h2,{id:"a-note-about-gas-price",children:"A Note about Gas Price"}),"\n",(0,s.jsx)(n.p,{children:'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'}),"\n",(0,s.jsxs)(n.p,{children:["We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the deploy. If you plan on sending a deploy to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", you can use the ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to estimate the payment amount needed for the deploy."]}),"\n",(0,s.jsxs)(n.p,{children:["If your test configuration matches your production ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),", you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,s.jsx)(n.a,{href:"/runtime#gas-allocation",children:"runtime economics"})," section for more details about gas usage and fees."]}),"\n",(0,s.jsx)(n.p,{children:"Please be aware that sending a deploy always requires payment. This is true regardless of the validity of included Wasm."}),"\n",(0,s.jsxs)(n.p,{children:["If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,s.jsx)(n.a,{href:"/concepts/serialization-standard#executionresult",children:"failed execution"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a434b528.8590c09f.js b/assets/js/a434b528.8590c09f.js new file mode 100644 index 000000000..6e4104569 --- /dev/null +++ b/assets/js/a434b528.8590c09f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[20884],{77875:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>i});var s=t(74848),a=t(28453);const o={title:"Sending Deploys"},r="Sending Deploys using the Casper Client",c={id:"developers/cli/sending-deploys",title:"Sending Deploys",description:"To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:",source:"@site/versioned_docs/version-1.5.X/developers/cli/sending-deploys.md",sourceDirName:"developers/cli",slug:"/developers/cli/sending-deploys",permalink:"/1.5.X/developers/cli/sending-deploys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Sending Deploys"},sidebar:"developers",previous:{title:"Undelegating Tokens",permalink:"/1.5.X/developers/cli/undelegate"},next:{title:"Installing Contracts",permalink:"/1.5.X/developers/cli/installing-contracts"}},d={},i=[{value:"Paying for Deploys",id:"paying-for-deploys",level:2},{value:"Monitoring the Event Stream for Deploys",id:"monitoring-the-event-stream-for-deploys",level:2},{value:"Sending a Deploy to the Network",id:"sending-the-deploy",level:2},{value:"Time-to-live",id:"ttl",level:3},{value:"Deploy Payments",id:"deploy-payments",level:3},{value:"Using Arguments with Deploys",id:"using-arguments-with-deploys",level:2},{value:"Advanced Features",id:"advanced-features",level:2},{value:"A Note about Gas Price",id:"a-note-about-gas-price",level:2}];function l(e){const n={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"sending-deploys-using-the-casper-client",children:"Sending Deploys using the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["To install smart contracts on the blockchain, you can send your Wasm to the network via a ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy"}),". To do this, you will need to meet a few prerequisites:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You will need a client to interact with the network, such as the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,s.jsxs)(n.li,{children:["Ensure you have an ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"Account"})," and its associated ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys",children:"keys"})," This account will pay for the Deploy, and its secret key will sign the Deploy"]}),"\n",(0,s.jsx)(n.li,{children:"Ensure this account has enough CSPR tokens to pay for the Deploy"}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"paying-for-deploys",children:"Paying for Deploys"}),"\n",(0,s.jsx)(n.p,{children:"CSPR tokens are used to pay for deploys on the Casper Mainnet and Testnet. There are several ways to fund your account:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You may want to ",(0,s.jsx)(n.a,{href:"/1.5.X/users/funding-from-exchanges",children:"transfer tokens from an exchange"})]}),"\n",(0,s.jsxs)(n.li,{children:["You can use a ",(0,s.jsx)(n.a,{href:"/1.5.X/users/token-transfer",children:"block explorer to transfer tokens"})," between accounts' purses"]}),"\n",(0,s.jsxs)(n.li,{children:["You can also ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/",children:"transfer tokens using the default Casper client"})]}),"\n",(0,s.jsxs)(n.li,{children:["On the Testnet, you can use the ",(0,s.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"faucet functionality"})," for testing your smart contracts"]}),"\n",(0,s.jsxs)(n.li,{children:["If running a network locally using ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/nctl-test",children:"NCTL"}),", the tool provides several funded accounts"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"monitoring-the-event-stream-for-deploys",children:"Monitoring the Event Stream for Deploys"}),"\n",(0,s.jsxs)(n.p,{children:["If you want to follow the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"lifecycle"})," of the Deploy, you can start monitoring a node's event stream. This section will focus only on DeployAccepted events, but there are other event types described ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/monitor-and-consume-events",children:"here"}),". You need the following information to proceed:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The IP address of a ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"peer"})," on the network"]}),"\n",(0,s.jsxs)(n.li,{children:["The port specified as the ",(0,s.jsx)(n.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(n.em,{children:"config.toml"}),", which is by default 9999 on Mainnet and Testnet"]}),"\n",(0,s.jsxs)(n.li,{children:["The URL for DeployAccepted events, which is ",(0,s.jsx)(n.code,{children:"HOST:PORT"}),"/events/deploys"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"With the following command, you can start watching the event stream for DeployAccepted events. Note the event ID recorded when you send the Deploy in the next section."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://65.21.235.219:9999/events/deploys\n"})}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-deploy",children:"Sending a Deploy to the Network"}),"\n",(0,s.jsxs)(n.p,{children:["You can call the Casper client's ",(0,s.jsx)(n.code,{children:"put-deploy"})," command to put the compiled contract on the chain. In this example, the Deploy will execute in the account's context. See the ",(0,s.jsx)(n.a,{href:"#advanced-features",children:"advanced features"})," section for key delegation."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name casper-test \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH>\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777. You can find a list of trusted peers in network's configuration file, ",(0,s.jsx)(n.code,{children:"config.toml"}),". Here is an ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/config-example.toml#L131",children:"example"}),". You may send deploys to one of the trusted nodes or use them to query other online nodes."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"}),". As you can see, this example uses the Testnet"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This example uses 2.5 CSPR, but you need to modify this for your contract. See the ",(0,s.jsx)(n.a,{href:"#a-note-about-gas-price",children:"note"})," below"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's execution results. Sending the deploy and receiving the deploy hash does not mean the deploy was processed successfully. Therefore, you must check the deploy execution using the deploy hash. See the deploy lifecycle for more details."}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Each Deploy gets a unique hash, which is part of the cryptographic security of blockchain technology. No two deploys will ever return the same hash."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Sample put-deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": -6958186952964949950,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Verify the deploy details with the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command and the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," received above."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address <HOST:PORT> <DEPLOY-HASH>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["If the Deploy succeeded, the ",(0,s.jsx)(n.code,{children:"get-deploy"})," command would return a JSON object with the full deploy details."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Sample get-deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": -3532286620275982221,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy": {\n "approvals": [\n {\n "signature": "015a7b0178e144fbf5ce52147c44a3e6bd6aae898ec6bb47c97b5802f3bcb6cd26331f7db18464cd1e51764c14ceb24b7ab9c4e3595505c32465fc0702e8d5510b",\n "signer": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d"\n }\n ],\n "hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "header": {\n "account": "01e76e0279a08b96d9d68e6b86c618de24a0c324d7d0c1fa8c035f0bc2af1a396d",\n "body_hash": "b1956600be3c11d7555ada11426ab1a8bdf36102f59838d6bf69cec321111a22",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2022-03-24T12:05:57.579Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "05000c774203",\n "cl_type": "U512",\n "parsed": "14000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "ModuleBytes": {\n "args": [],\n "module_bytes": "[94478 hex chars]"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "098b618878a2413393925e1fbf6d3cf92f1208f4f8662a904e86b49b0c4ab9f0",\n "result": {\n "Success": {\n "cost": "13327900740",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474",\n "transform": {\n "WriteCLValue": {\n "bytes": "0500279bd1ca",\n "cl_type": "U512",\n "parsed": "871100000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "14000000000"\n }\n },\n {\n "key": "uref-82a7b5713f2b9b3f9e1b4f2d1f312a5fec7c3a0bed6fa897501913951729dbbf-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "00000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n },\n {\n "key": "uref-ea022d75ff618533baf46040cc57692fb7f7840774c979c9dec0b5c3ddcec7e9-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "",\n "cl_type": "Unit",\n "parsed": null\n }\n }\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "Identity"\n },\n {\n "key": "hash-3b69bafcc13b4541dddd7d5492e4754feee41c636990aeb6bf78d58fdd39fc43",\n "transform": "WriteContractWasm"\n },\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "transform": "WriteContract"\n },\n {\n "key": "hash-4d0e2bfb5d243ea567e9b37aa8229d2b8b01de838c4bd7ca570a178e012d6b82",\n "transform": "WriteContractPackage"\n },\n {\n "key": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "transform": {\n "AddKeys": [\n {\n "key": "hash-c39dd923df84c637e46e46a8a3326fcf85e43c60814878f44a08efd0074cb523",\n "name": "counter"\n }\n ]\n }\n },\n {\n "key": "deploy-34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "34550c8b86d5e38260882466e98427c62a27a96d85c13f49041a1579ebf84496",\n "from": "account-hash-f407926760b91c2ce3af8bda7448841b3aa68c6e98053331d10819ef2d0a808e",\n "gas": "13327900740",\n "source": "uref-3a61ed9a3b472f35f4cf1e241d674fad8a5f9509c97a56d62bb03f7bcc4b8474-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-0a24ef56971d46bfefbd5590afe20e5f3482299aba74e1a0fc33a55008cf9453",\n "transform": {\n "AddUInt512": "14000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"We want to draw your attention to a few properties in the example output:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Execution cost 13327900740 motes, yet we paid 14000000000 motes. See the ",(0,s.jsx)(n.a,{href:"#a-note-about-gas-price",children:"note about gas price"})]}),"\n",(0,s.jsxs)(n.li,{children:['The contract returned no errors. If you see an "Out of gas error", you did not specify a high enough value in the ',(0,s.jsx)(n.code,{children:"--payment-amount"})," arg"]}),"\n",(0,s.jsx)(n.li,{children:"The time-to-live was 30 minutes"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["It is also possible to get a summary of the deploy's information by performing a ",(0,s.jsx)(n.code,{children:"query-global-state"})," command using the Casper client and providing a state root hash or a block hash from a block at or after the one in which the deploy was executed."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address <HOST:PORT>\n\ncasper-client query-global-state --node-address <HOST:PORT> \\\n --key deploy-<DEPLOY-HASH-HEX-STRING> \\\n --state-root-hash <STATE-ROOT-HASH-HEX-STRING>\n"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --node-address <HOST:PORT> \\\n --key deploy-<DEPLOY-HASH-HEX STRING>\n --block-hash <BLOCK-HASH-HEX-STRING>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Run the help command for ",(0,s.jsx)(n.code,{children:"query-global-state"})," to see its usage."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state --help\n"})}),"\n",(0,s.jsx)(n.h3,{id:"ttl",children:"Time-to-live"}),"\n",(0,s.jsxs)(n.p,{children:["Time-to-live is the parameter that determines how long a deploy will wait for execution. The acceptable maximum ",(0,s.jsx)(n.code,{children:"ttl"})," is configurable by chain, with the Casper Mainnet maximum set to ",(0,s.jsx)(n.code,{children:"18hours"}),". If you are sending a deploy to a different network, you will need to check ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," for that network to determine the acceptable maximum. The minimum is theoretically zero, but this will result in an immediate expiration and an invalid deploy."]}),"\n",(0,s.jsxs)(n.p,{children:["In the event of a network outage or other event that prevents execution within the ",(0,s.jsx)(n.code,{children:"ttl"}),", the solution is to resend the deploy in question."]}),"\n",(0,s.jsxs)(n.p,{children:["Should the deploy's ",(0,s.jsx)(n.code,{children:"ttl"})," exceed the allowable limit, or if the deploy expires, the network's deploy acceptor will find the deploy invalid and return a warning."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-payments",children:"Deploy Payments"}),"\n",(0,s.jsx)(n.p,{children:"Dependent upon the complexity and needs of the Deploy in question, several options exist to allow users to pay for smart contract execution."}),"\n",(0,s.jsxs)(n.p,{children:["The simplest way to pay for a Deploy on the Casper blockchain is to use the host side standard payment functionality. This can be done using an ",(0,s.jsx)(n.strong,{children:"empty"})," ",(0,s.jsx)(n.code,{children:"ModuleBytes"})," as your payment code. However, you must specify the amount within a runtime argument. ",(0,s.jsx)(n.code,{children:"ModuleBytes"})," can also serve as a custom payment contract if it is not empty, but any additional Wasm ran within will come at an additional cost on top of the payment. This includes invalid Wasm, which will still result in additional cost."]}),"\n",(0,s.jsx)(n.p,{children:"You may find the host side functionality of standard payment insufficient for your purposes. In this event, Casper provides the following options for custom payment code:"}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredContractByHash"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredContractByName"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredVersionContractByHash"})]}),"\n",(0,s.jsxs)(n.p,{children:["\u2022\t",(0,s.jsx)(n.code,{children:"StoredVersionContractByName"})]}),"\n",(0,s.jsx)(n.h2,{id:"using-arguments-with-deploys",children:"Using Arguments with Deploys"}),"\n",(0,s.jsxs)(n.p,{children:["The session Wasm (or payment Wasm if you choose to ",(0,s.jsx)(n.em,{children:"not"}),' use the standard payment) of a Deploy often requires arguments to be passed to it when executed. These "runtime args" should be provided by using the ',(0,s.jsx)(n.code,{children:"--session-arg"})," or ",(0,s.jsx)(n.code,{children:"--payment-arg"})," options, once for each arg required. The Casper client provides some examples of how to do this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --show-arg-examples\n"})}),"\n",(0,s.jsx)(n.h2,{id:"advanced-features",children:"Advanced Features"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks support complex deploys using multiple signatures. ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Casper Accounts"})," use a powerful permissions model that enables a multi-signature scheme for deploys."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"put-deploy"})," command performs multiple actions under the hood, optimizing the typical use case. It creates a deploy, signs it, and sends the Deploy to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"make-deploy"})," - Creates a Deploy and outputs it to a file or stdout. As a file, the deploy can subsequently be signed by other parties using the ",(0,s.jsx)(n.code,{children:"sign-deploy"})," subcommand and then sent to the network for execution using the ",(0,s.jsx)(n.code,{children:"send-deploy"})," subcommand"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"sign-deploy"})," - Reads a previously-saved Deploy from a file, cryptographically signs it, and outputs it to a file or stdout"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"send-deploy"})," - Reads a previously-saved Deploy from a file and sends it to the network for execution"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To sign a Deploy with multiple keys, create the Deploy with the ",(0,s.jsx)(n.code,{children:"make-deploy"})," command. The generated deploy file can be sent to the other signers, who then sign it with their keys by calling the ",(0,s.jsx)(n.code,{children:"sign-deploy"})," for each key. Signatures need to be gathered on the Deploy one after another until all required parties have signed the Deploy. Finally, the signed Deploy is sent to the network with the ",(0,s.jsx)(n.code,{children:"send-deploy"})," command for processing."]}),"\n",(0,s.jsxs)(n.p,{children:["For a step-by-step workflow, visit the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer",children:"Two-Party Multi-Signature Deploy"})," guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network."]}),"\n",(0,s.jsx)(n.h2,{id:"a-note-about-gas-price",children:"A Note about Gas Price"}),"\n",(0,s.jsx)(n.p,{children:'A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"'}),"\n",(0,s.jsxs)(n.p,{children:["We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the deploy. If you plan on sending a deploy to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", you can use the ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to estimate the payment amount needed for the deploy."]}),"\n",(0,s.jsxs)(n.p,{children:["If your test configuration matches your production ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),", you can check the deploy status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/runtime#gas-allocation",children:"runtime economics"})," section for more details about gas usage and fees."]}),"\n",(0,s.jsx)(n.p,{children:"Please be aware that sending a deploy always requires payment. This is true regardless of the validity of included Wasm."}),"\n",(0,s.jsxs)(n.p,{children:["If the deploy failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard#executionresult",children:"failed execution"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"However, if the failure occurs prior to session execution, the penalty payment will not appear within the gas cost of the deploy. Instead, the system automatically deducts the 2.5 CSPR from the sending account's main purse."})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4ae8417.5511ae65.js b/assets/js/a4ae8417.5511ae65.js new file mode 100644 index 000000000..4b03e1764 --- /dev/null +++ b/assets/js/a4ae8417.5511ae65.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49314],{40347:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Local Network Setup"},i="Setting up a Local Network with NCTL",l={id:"developers/dapps/setup-nctl",title:"Local Network Setup",description:"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.",source:"@site/docs/developers/dapps/setup-nctl.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/setup-nctl",permalink:"/developers/dapps/setup-nctl",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Local Network Setup"},sidebar:"developers",previous:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/developers/dapps/speculative-exec"},next:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Virtual Environment",id:"installing-a-virtual-environment",level:2},{value:"Setting up the Network",id:"setting-up-the-network",level:2},{value:"Stopping the Network",id:"stopping-the-network",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-up-a-local-network-with-nctl",children:"Setting up a Local Network with NCTL"})}),"\n",(0,t.jsxs)(n.p,{children:["NCTL stands for network/node control. ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/utils/nctl",children:"NCTL"})," is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have completed the ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started section"}),", which shows you how to install your development environment, including tools like ",(0,t.jsx)(n.em,{children:"CMake"})," (version 3.1.4+), ",(0,t.jsx)(n.em,{children:"Cargo"}),", and ",(0,t.jsx)(n.em,{children:"Rust"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Make sure you have ",(0,t.jsx)(n.a,{href:"https://www.python.org/downloads/",children:"Python 3 installed"})," if your operating system does not include Python."]}),"\n",(0,t.jsxs)(n.li,{children:["To run NCTL, you will also need ",(0,t.jsx)(n.a,{href:"https://www.gnu.org/savannah-checkouts/gnu/bash/bash.html",children:"the bash shell"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-virtual-environment",children:"Installing a Virtual Environment"}),"\n",(0,t.jsx)(n.p,{children:"We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing."}),"\n",(0,t.jsx)(n.p,{children:"First, you will need to install a set of tools required for running NCTL."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 1."})," The first tool you will need is ",(0,t.jsx)(n.strong,{children:"pip"}),", a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or ",(0,t.jsx)(n.a,{href:"https://pip.pypa.io/en/stable/installing/",children:"the full installation instructions"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\n$ python3 get-pip.py\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install python3-pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 2."})," Install ",(0,t.jsx)(n.strong,{children:"pkg-config"}),", a program used to compile and link against one or more libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install pkg-config\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install pkg-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 3."})," Install either ",(0,t.jsx)(n.strong,{children:"libssl-dev"})," (Linux) or ",(0,t.jsx)(n.strong,{children:"openssl"})," (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install openssl\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 4."})," You will also need the ",(0,t.jsx)(n.strong,{children:"gcc"})," and ",(0,t.jsx)(n.strong,{children:"g++"})," compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing)."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ xcode-select --install\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install build-essential\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 5."})," Create and activate a new virtual environment. ",(0,t.jsx)(n.strong,{children:"Commands applicable to the virtual environment will be prefixed with (env)"}),". Run the following commands to set it up."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ python3 -m venv env\n$ source env/bin/activate\n(env) $\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 6."})," Inside the virtual environment, upgrade ",(0,t.jsx)(n.strong,{children:"pip"})," to the latest version."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install --upgrade pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 7."})," Install ",(0,t.jsx)(n.strong,{children:"jq"}),", a command-line JSON processor."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 8."})," Install ",(0,t.jsx)(n.strong,{children:"supervisor"}),", a cross-platform process manager."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install supervisor\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 9."})," Install ",(0,t.jsx)(n.strong,{children:"toml"}),", a configuration file parser."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-the-network",children:"Setting up the Network"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to set up and run your local network of Casper nodes."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["NCTL will not work properly if the following repositories are downloaded via Github's web GUI. To ensure functionality, use the CLI ",(0,t.jsx)(n.code,{children:"git clone"})," command."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 10."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-nctl"})," software in your working directory, referenced here as ",(0,t.jsx)(n.em,{children:"WORKING_DIRECTORY"}),". ",(0,t.jsx)(n.strong,{children:"Very Important!!! Choose a short path for your working directory"}),"; otherwise, the NCTL tool will report that the path is too long."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ cd <WORKING_DIRECTORY>\n$ git clone https://github.com/casper-network/casper-nctl\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 11."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 12."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-client-rs"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-ecosystem/casper-client-rs\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 13."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node-launcher"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,t.jsx)(n.code,{children:"deploy_delay"})," in your ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390",children:"local config.toml"})," before running ",(0,t.jsx)(n.code,{children:"nctl-assets-setup"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 14."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-sidecar"})," software in your working directory. As part of Casper's Condor release, the sidecar is now necessary to interact with a Casper network and will handle any API requests."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-sidecar\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 15."})," You may need to extend your ",(0,t.jsx)(n.code,{children:".bashrc"})," file to make NCTL commands available from the terminal session. You can do so using the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd YOUR_WORKING_DIRECTORY/casper-nctl\n\ncat >> $HOME/.bashrc <<- EOM\n\n# ----------------------------------------------------------------------\n# CASPER - NCTL\n# ----------------------------------------------------------------------\n\n# Activate NCTL shell.\n. $(pwd)/activate\n\nEOM\n"})}),"\n",(0,t.jsx)(n.p,{children:"Followed by refreshing the bash session:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:". $HOME/.bashrc\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 16."})," Activate the NCTL environment with the following command."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ source casper-node/utils/nctl/activate\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 17."})," Compile the NCTL binary scripts. The following command compiles both the ",(0,t.jsx)(n.em,{children:"casper-node"})," and the ",(0,t.jsx)(n.em,{children:"casper-client"})," in release mode."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-compile\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The compilation takes some time, so it might be a perfect moment to get some coffee."})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 18."})," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes and 10 instances of the sidecar, with 5 active nodes and sidecars and 5 inactive nodes and sidecars."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-assets-setup && nctl-start\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once a network is up and running, you can control each node within the network and add new nodes to the network."}),"\n",(0,t.jsxs)(n.p,{children:["Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,t.jsx)(n.em,{children:"nctl-"})," and allow you to perform various tasks."]}),"\n",(0,t.jsxs)(n.p,{children:["You should see the new directory ",(0,t.jsx)(n.em,{children:"utils/nctl/assets"}),", with the following structure."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Assets Setup",src:s(6649).A+"",width:"391",height:"706"})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command line output you would expect."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"NCTL Output",src:s(60017).A+"",width:"795",height:"258"})}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-network",children:"Stopping the Network"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 19."})," Although not necessary, you can stop and clean the NCTL setup with the following commands."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-stop\n$ nctl-clean\n"})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md",children:"various NCTL commands"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md",children:"NCTL usage guide"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},6649:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/assets_setup-193e704630a056cb0dbb8e86dfac0366.png"},60017:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/nctl_output-8acd66f819f302adcb1d34cc0ff03fe0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>l});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4ae8417.97847ea7.js b/assets/js/a4ae8417.97847ea7.js deleted file mode 100644 index 6d52ff0d6..000000000 --- a/assets/js/a4ae8417.97847ea7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9314],{40347:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Local Network Setup"},i="Setting up a Local Network with NCTL",l={id:"developers/dapps/setup-nctl",title:"Local Network Setup",description:"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.",source:"@site/docs/developers/dapps/setup-nctl.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/setup-nctl",permalink:"/next/developers/dapps/setup-nctl",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Local Network Setup"},sidebar:"developers",previous:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/next/developers/dapps/speculative-exec"},next:{title:"Local Network Testing",permalink:"/next/developers/dapps/nctl-test"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Virtual Environment",id:"installing-a-virtual-environment",level:2},{value:"Setting up the Network",id:"setting-up-the-network",level:2},{value:"Stopping the Network",id:"stopping-the-network",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-up-a-local-network-with-nctl",children:"Setting up a Local Network with NCTL"})}),"\n",(0,t.jsxs)(n.p,{children:["NCTL stands for network/node control. ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/utils/nctl",children:"NCTL"})," is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have completed the ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started section"}),", which shows you how to install your development environment, including tools like ",(0,t.jsx)(n.em,{children:"CMake"})," (version 3.1.4+), ",(0,t.jsx)(n.em,{children:"Cargo"}),", and ",(0,t.jsx)(n.em,{children:"Rust"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Make sure you have ",(0,t.jsx)(n.a,{href:"https://www.python.org/downloads/",children:"Python 3 installed"})," if your operating system does not include Python."]}),"\n",(0,t.jsxs)(n.li,{children:["To run NCTL, you will also need ",(0,t.jsx)(n.a,{href:"https://www.gnu.org/savannah-checkouts/gnu/bash/bash.html",children:"the bash shell"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-virtual-environment",children:"Installing a Virtual Environment"}),"\n",(0,t.jsx)(n.p,{children:"We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing."}),"\n",(0,t.jsx)(n.p,{children:"First, you will need to install a set of tools required for running NCTL."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 1."})," The first tool you will need is ",(0,t.jsx)(n.strong,{children:"pip"}),", a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or ",(0,t.jsx)(n.a,{href:"https://pip.pypa.io/en/stable/installing/",children:"the full installation instructions"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\n$ python3 get-pip.py\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install python3-pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 2."})," Install ",(0,t.jsx)(n.strong,{children:"pkg-config"}),", a program used to compile and link against one or more libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install pkg-config\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install pkg-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 3."})," Install either ",(0,t.jsx)(n.strong,{children:"libssl-dev"})," (Linux) or ",(0,t.jsx)(n.strong,{children:"openssl"})," (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install openssl\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 4."})," You will also need the ",(0,t.jsx)(n.strong,{children:"gcc"})," and ",(0,t.jsx)(n.strong,{children:"g++"})," compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing)."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ xcode-select --install\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install build-essential\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 5."})," Create and activate a new virtual environment. ",(0,t.jsx)(n.strong,{children:"Commands applicable to the virtual environment will be prefixed with (env)"}),". Run the following commands to set it up."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ python3 -m venv env\n$ source env/bin/activate\n(env) $\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 6."})," Inside the virtual environment, upgrade ",(0,t.jsx)(n.strong,{children:"pip"})," to the latest version."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install --upgrade pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 7."})," Install ",(0,t.jsx)(n.strong,{children:"jq"}),", a command-line JSON processor."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 8."})," Install ",(0,t.jsx)(n.strong,{children:"supervisor"}),", a cross-platform process manager."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install supervisor\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 9."})," Install ",(0,t.jsx)(n.strong,{children:"toml"}),", a configuration file parser."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-the-network",children:"Setting up the Network"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to set up and run your local network of Casper nodes."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["NCTL will not work properly if the following repositories are downloaded via Github's web GUI. To ensure functionality, use the CLI ",(0,t.jsx)(n.code,{children:"git clone"})," command."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 10."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-nctl"})," software in your working directory, referenced here as ",(0,t.jsx)(n.em,{children:"WORKING_DIRECTORY"}),". ",(0,t.jsx)(n.strong,{children:"Very Important!!! Choose a short path for your working directory"}),"; otherwise, the NCTL tool will report that the path is too long."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ cd <WORKING_DIRECTORY>\n$ git clone https://github.com/casper-network/casper-nctl\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 11."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 12."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-client-rs"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-ecosystem/casper-client-rs\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 13."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node-launcher"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,t.jsx)(n.code,{children:"deploy_delay"})," in your ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390",children:"local config.toml"})," before running ",(0,t.jsx)(n.code,{children:"nctl-assets-setup"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 14."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-sidecar"})," software in your working directory. As part of Casper's Condor release, the sidecar is now necessary to interact with a Casper network and will handle any API requests."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-sidecar\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 15."})," You may need to extend your ",(0,t.jsx)(n.code,{children:".bashrc"})," file to make NCTL commands available from the terminal session. You can do so using the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd YOUR_WORKING_DIRECTORY/casper-nctl\n\ncat >> $HOME/.bashrc <<- EOM\n\n# ----------------------------------------------------------------------\n# CASPER - NCTL\n# ----------------------------------------------------------------------\n\n# Activate NCTL shell.\n. $(pwd)/activate\n\nEOM\n"})}),"\n",(0,t.jsx)(n.p,{children:"Followed by refreshing the bash session:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:". $HOME/.bashrc\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 16."})," Activate the NCTL environment with the following command."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ source casper-node/utils/nctl/activate\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 17."})," Compile the NCTL binary scripts. The following command compiles both the ",(0,t.jsx)(n.em,{children:"casper-node"})," and the ",(0,t.jsx)(n.em,{children:"casper-client"})," in release mode."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-compile\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The compilation takes some time, so it might be a perfect moment to get some coffee."})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 18."})," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes and 10 instances of the sidecar, with 5 active nodes and sidecars and 5 inactive nodes and sidecars."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-assets-setup && nctl-start\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once a network is up and running, you can control each node within the network and add new nodes to the network."}),"\n",(0,t.jsxs)(n.p,{children:["Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,t.jsx)(n.em,{children:"nctl-"})," and allow you to perform various tasks."]}),"\n",(0,t.jsxs)(n.p,{children:["You should see the new directory ",(0,t.jsx)(n.em,{children:"utils/nctl/assets"}),", with the following structure."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Assets Setup",src:s(66883).A+"",width:"391",height:"706"})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command line output you would expect."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"NCTL Output",src:s(76427).A+"",width:"795",height:"258"})}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-network",children:"Stopping the Network"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 19."})," Although not necessary, you can stop and clean the NCTL setup with the following commands."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-stop\n$ nctl-clean\n"})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md",children:"various NCTL commands"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md",children:"NCTL usage guide"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},66883:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/assets_setup-193e704630a056cb0dbb8e86dfac0366.png"},76427:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/nctl_output-8acd66f819f302adcb1d34cc0ff03fe0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>l});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4b0daeb.2b9391ae.js b/assets/js/a4b0daeb.2b9391ae.js new file mode 100644 index 000000000..8c4bf9605 --- /dev/null +++ b/assets/js/a4b0daeb.2b9391ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72305],{36539:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={},t="M",a={id:"concepts/glossary/M",title:"M",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/M.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/M",permalink:"/1.5.X/concepts/glossary/M",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"L",permalink:"/1.5.X/concepts/glossary/L"},next:{title:"N",permalink:"/1.5.X/concepts/glossary/N"}},l={},i=[{value:"Mainnet",id:"mainnet",level:2},{value:"Merkle tree",id:"merkle-tree",level:2},{value:"Motes",id:"motes",level:2},{value:"Multi-Sig",id:"multisig",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"m",children:"M"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"mainnet",children:"Mainnet"}),"\n",(0,n.jsx)(s.p,{children:"The live, decentralized, and public Casper platform, with version 1.0."}),"\n",(0,n.jsx)(s.h2,{id:"merkle-tree",children:"Merkle tree"}),"\n",(0,n.jsx)(s.p,{children:"A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes."}),"\n",(0,n.jsx)(s.h2,{id:"motes",children:"Motes"}),"\n",(0,n.jsxs)(s.p,{children:["A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#cspr",children:"CSPR"})," token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes."]}),"\n",(0,n.jsx)(s.h2,{id:"multisig",children:"Multi-Sig"}),"\n",(0,n.jsxs)(s.p,{children:["Short for ",(0,n.jsx)(s.code,{children:"Multi-Signature"}),". Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for deploys. More information on the use of Multi-Sig can be found ",(0,n.jsx)(s.a,{href:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4b0daeb.ca90cf11.js b/assets/js/a4b0daeb.ca90cf11.js deleted file mode 100644 index 52d81a88c..000000000 --- a/assets/js/a4b0daeb.ca90cf11.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4686],{36539:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={},t="M",a={id:"concepts/glossary/M",title:"M",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/M.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/M",permalink:"/concepts/glossary/M",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"L",permalink:"/concepts/glossary/L"},next:{title:"N",permalink:"/concepts/glossary/N"}},l={},i=[{value:"Mainnet",id:"mainnet",level:2},{value:"Merkle tree",id:"merkle-tree",level:2},{value:"Motes",id:"motes",level:2},{value:"Multi-Sig",id:"multisig",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"m",children:"M"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"mainnet",children:"Mainnet"}),"\n",(0,n.jsx)(s.p,{children:"The live, decentralized, and public Casper platform, with version 1.0."}),"\n",(0,n.jsx)(s.h2,{id:"merkle-tree",children:"Merkle tree"}),"\n",(0,n.jsx)(s.p,{children:"A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes."}),"\n",(0,n.jsx)(s.h2,{id:"motes",children:"Motes"}),"\n",(0,n.jsxs)(s.p,{children:["A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C#cspr",children:"CSPR"})," token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes."]}),"\n",(0,n.jsx)(s.h2,{id:"multisig",children:"Multi-Sig"}),"\n",(0,n.jsxs)(s.p,{children:["Short for ",(0,n.jsx)(s.code,{children:"Multi-Signature"}),". Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for deploys. More information on the use of Multi-Sig can be found ",(0,n.jsx)(s.a,{href:"/developers/cli/transfers/multisig-deploy-transfer",children:"here"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4cd78b5.cbc7d4a6.js b/assets/js/a4cd78b5.cbc7d4a6.js deleted file mode 100644 index 31f518269..000000000 --- a/assets/js/a4cd78b5.cbc7d4a6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7403],{37340:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const s={},i="Overview",c={id:"resources/beginner/counter-testnet/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/overview.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/overview",permalink:"/resources/beginner/counter-testnet/overview",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/counter-testnet"},next:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter-testnet/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(41304).A+"",width:"977",height:"368"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},41304:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-testnet-40880f888b79830685dee11e2093091d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4cd78b5.e215ea72.js b/assets/js/a4cd78b5.e215ea72.js new file mode 100644 index 000000000..e131d1b1b --- /dev/null +++ b/assets/js/a4cd78b5.e215ea72.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7403],{37340:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const s={},i="Overview",c={id:"resources/beginner/counter-testnet/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/overview.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/overview",permalink:"/1.5.X/resources/beginner/counter-testnet/overview",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/1.5.X/counter-testnet"},next:{title:"Casper-Client Commands",permalink:"/1.5.X/resources/beginner/counter-testnet/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(87109).A+"",width:"977",height:"368"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},87109:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-testnet-40880f888b79830685dee11e2093091d.png"},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4f8fe7e.83f1a268.js b/assets/js/a4f8fe7e.83f1a268.js new file mode 100644 index 000000000..1ebe88b37 --- /dev/null +++ b/assets/js/a4f8fe7e.83f1a268.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67205],{34777:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var t=n(74848),s=n(28453);const a={title:"Consensus"},r="Consensus Economics",o={id:"concepts/economics/consensus",title:"Consensus",description:"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.",source:"@site/docs/concepts/economics/consensus.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/consensus",permalink:"/concepts/economics/consensus",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Consensus"},sidebar:"concepts",previous:{title:"Overview",permalink:"/economics"},next:{title:"Runtime",permalink:"/runtime"}},c={},d=[{value:"Validator Selection",id:"selection",level:2},{value:"Bids",id:"bids",level:3},{value:"Delegation",id:"delegation",level:3},{value:"Incentives",id:"incentives",level:2},{value:"Validator Participation",id:"participation",level:3},{value:"Rewards Distribution",id:"distribution",level:3},{value:"Validator Inactivity",id:"inactivity",level:3},{value:"Founding Validators",id:"founding-validators",level:2}];function l(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(i.header,{children:(0,t.jsx)(i.h1,{id:"consensus-economics",children:"Consensus Economics"})}),"\n",(0,t.jsxs)(i.p,{children:[(0,t.jsx)(i.a,{href:"/concepts/design/consensus",children:"Casper consensus"})," is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule."]}),"\n",(0,t.jsx)(i.h2,{id:"selection",children:"Validator Selection"}),"\n",(0,t.jsxs)(i.p,{children:["After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a ",(0,t.jsx)(i.em,{children:"chainspec"})," configuration file specifies a few key parameters:"]}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"auction_delay"})," specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the ",(0,t.jsx)(i.em,{children:"auction_delay"})," is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era."]}),"\n",(0,t.jsxs)(i.li,{children:["The ",(0,t.jsx)(i.code,{children:"validator_slots"})," parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids."]}),"\n"]}),"\n",(0,t.jsx)(i.h3,{id:"bids",children:"Bids"}),"\n",(0,t.jsxs)(i.p,{children:["Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the ",(0,t.jsx)(i.code,{children:"unbonding_delay"})," chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners."]}),"\n",(0,t.jsx)(i.p,{children:"Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document."}),"\n",(0,t.jsx)(i.h3,{id:"delegation",children:"Delegation"}),"\n",(0,t.jsx)(i.p,{children:"Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate."}),"\n",(0,t.jsxs)(i.p,{children:["Currently, there are delegation limits in the chainspec. Visit the ",(0,t.jsx)(i.a,{href:"/users/delegating",children:"Delegating Tokens"})," page for more details."]}),"\n",(0,t.jsx)(i.h2,{id:"incentives",children:"Incentives"}),"\n",(0,t.jsx)(i.p,{children:"The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals."}),"\n",(0,t.jsx)(i.p,{children:"Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future."}),"\n",(0,t.jsxs)(i.p,{children:["The network incentivizes participation by issuing ",(0,t.jsx)(i.a,{href:"/concepts/design/rewards",children:"rewards"})," to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by ",(0,t.jsx)(i.a,{href:"/concepts/economics/staking",children:"staking"})," with a validator. All rewards are added directly to the corresponding bids and delegations."]}),"\n",(0,t.jsx)(i.h3,{id:"participation",children:"Validator Participation"}),"\n",(0,t.jsx)(i.p,{children:"The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load."}),"\n",(0,t.jsx)(i.p,{children:"CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"The growth of CSPR supply is exponential"}),"\n",(0,t.jsx)(i.li,{children:"Issuance takes into account slashed CSPR"}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"i"})," - the era's index as a positive integer [0, 1, 2, ..., n]"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"initial_supply"})," - the number of CSPR at genesis"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"issuance_rate"})," - the annual rate at which new CSPR tokens are minted"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.code,{children:"ticks_per_year"})," - the number of milliseconds in a year equal to 31,536,000,000"]}),"\n"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)\n"})}),"\n",(0,t.jsxs)(i.p,{children:["We introduce the ",(0,t.jsx)(i.em,{children:"round issuance rate"})," (corresponding to the chainspec parameter ",(0,t.jsx)(i.code,{children:"round_seigniorage_rate"}),") with this formula:"]}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1\n"})}),"\n",(0,t.jsxs)(i.p,{children:["The ",(0,t.jsx)(i.em,{children:"round issuance rate"})," is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter ",(0,t.jsx)(i.code,{children:"minimum_round_exponent"}),". For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds."]}),"\n",(0,t.jsx)(i.p,{children:"Finally, the base round reward is computed as:"}),"\n",(0,t.jsx)(i.pre,{children:(0,t.jsx)(i.code,{children:"base_round_reward(i) = round_issuance_rate * supply(i)\n"})}),"\n",(0,t.jsx)(i.p,{children:"This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block."}),"\n",(0,t.jsx)(i.h3,{id:"distribution",children:"Rewards Distribution"}),"\n",(0,t.jsx)(i.p,{children:"Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals."}),"\n",(0,t.jsx)(i.p,{children:"The concept of validator weight is crucial in understanding the distribution scheme:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Weight:"})," A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Assigned weight of a round:"})," The total weight of validators scheduled to participate in a round"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Participated weight of a round:"})," The total weight of validators that participated or sent messages before the end of the round"]}),"\n",(0,t.jsxs)(i.li,{children:[(0,t.jsx)(i.strong,{children:"Relative weight"}),": A validator's weight relative to the total validator weight that participated in a round"]}),"\n"]}),"\n",(0,t.jsx)(i.p,{children:"The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:"}),"\n",(0,t.jsxs)(i.ul,{children:["\n",(0,t.jsx)(i.li,{children:"For each finalized block, there is a fraction of rewards due for signature creation and collection"}),"\n",(0,t.jsx)(i.li,{children:"Signature rewards are split between the finder (block proposer) and the signature creators"}),"\n",(0,t.jsxs)(i.li,{children:["The signature creators get a part of the signature reward pot due for the block: ",(0,t.jsx)(i.code,{children:"(1 - finder's fee) * relative weight"})]}),"\n",(0,t.jsxs)(i.li,{children:["The finder gets a small reward as well to incentivize collecting and reporting all the signatures: ",(0,t.jsx)(i.code,{children:"finder's fee * total relative weight of signatures collected"})]}),"\n"]}),"\n",(0,t.jsxs)(i.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the ",(0,t.jsx)(i.a,{href:"/concepts/design/rewards",children:"Rewards Design"})," page for more details."]}),"\n",(0,t.jsx)(i.h3,{id:"inactivity",children:"Validator Inactivity"}),"\n",(0,t.jsx)(i.p,{children:"Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid."}),"\n",(0,t.jsx)(i.h2,{id:"founding-validators",children:"Founding Validators"}),"\n",(0,t.jsx)(i.p,{children:"When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days."})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,t.jsx)(i,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>r,x:()=>o});var t=n(96540);const s={},a=t.createContext(s);function r(e){const i=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a4f8fe7e.b982673b.js b/assets/js/a4f8fe7e.b982673b.js deleted file mode 100644 index 5a986a271..000000000 --- a/assets/js/a4f8fe7e.b982673b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7205],{34777:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var t=i(74848),s=i(28453);const a={title:"Consensus"},r="Consensus Economics",o={id:"concepts/economics/consensus",title:"Consensus",description:"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.",source:"@site/docs/concepts/economics/consensus.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/consensus",permalink:"/next/concepts/economics/consensus",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Consensus"},sidebar:"concepts",previous:{title:"Overview",permalink:"/next/economics"},next:{title:"Runtime",permalink:"/next/runtime"}},c={},d=[{value:"Validator Selection",id:"selection",level:2},{value:"Bids",id:"bids",level:3},{value:"Delegation",id:"delegation",level:3},{value:"Incentives",id:"incentives",level:2},{value:"Validator Participation",id:"participation",level:3},{value:"Rewards Distribution",id:"distribution",level:3},{value:"Validator Inactivity",id:"inactivity",level:3},{value:"Founding Validators",id:"founding-validators",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"consensus-economics",children:"Consensus Economics"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/design/consensus",children:"Casper consensus"})," is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule."]}),"\n",(0,t.jsx)(n.h2,{id:"selection",children:"Validator Selection"}),"\n",(0,t.jsxs)(n.p,{children:["After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a ",(0,t.jsx)(n.em,{children:"chainspec"})," configuration file specifies a few key parameters:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"auction_delay"})," specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the ",(0,t.jsx)(n.em,{children:"auction_delay"})," is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era."]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"validator_slots"})," parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bids",children:"Bids"}),"\n",(0,t.jsxs)(n.p,{children:["Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the ",(0,t.jsx)(n.code,{children:"unbonding_delay"})," chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners."]}),"\n",(0,t.jsx)(n.p,{children:"Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document."}),"\n",(0,t.jsx)(n.h3,{id:"delegation",children:"Delegation"}),"\n",(0,t.jsx)(n.p,{children:"Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate."}),"\n",(0,t.jsxs)(n.p,{children:["Currently, there are delegation limits in the chainspec. Visit the ",(0,t.jsx)(n.a,{href:"/next/users/delegating",children:"Delegating Tokens"})," page for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"incentives",children:"Incentives"}),"\n",(0,t.jsx)(n.p,{children:"The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals."}),"\n",(0,t.jsx)(n.p,{children:"Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future."}),"\n",(0,t.jsxs)(n.p,{children:["The network incentivizes participation by issuing ",(0,t.jsx)(n.a,{href:"/next/concepts/design/rewards",children:"rewards"})," to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/staking",children:"staking"})," with a validator. All rewards are added directly to the corresponding bids and delegations."]}),"\n",(0,t.jsx)(n.h3,{id:"participation",children:"Validator Participation"}),"\n",(0,t.jsx)(n.p,{children:"The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load."}),"\n",(0,t.jsx)(n.p,{children:"CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The growth of CSPR supply is exponential"}),"\n",(0,t.jsx)(n.li,{children:"Issuance takes into account slashed CSPR"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"i"})," - the era's index as a positive integer [0, 1, 2, ..., n]"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"initial_supply"})," - the number of CSPR at genesis"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"issuance_rate"})," - the annual rate at which new CSPR tokens are minted"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"ticks_per_year"})," - the number of milliseconds in a year equal to 31,536,000,000"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["We introduce the ",(0,t.jsx)(n.em,{children:"round issuance rate"})," (corresponding to the chainspec parameter ",(0,t.jsx)(n.code,{children:"round_seigniorage_rate"}),") with this formula:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.em,{children:"round issuance rate"})," is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter ",(0,t.jsx)(n.code,{children:"minimum_round_exponent"}),". For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds."]}),"\n",(0,t.jsx)(n.p,{children:"Finally, the base round reward is computed as:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:"base_round_reward(i) = round_issuance_rate * supply(i)\n"})}),"\n",(0,t.jsx)(n.p,{children:"This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block."}),"\n",(0,t.jsx)(n.h3,{id:"distribution",children:"Rewards Distribution"}),"\n",(0,t.jsx)(n.p,{children:"Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals."}),"\n",(0,t.jsx)(n.p,{children:"The concept of validator weight is crucial in understanding the distribution scheme:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Weight:"})," A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Assigned weight of a round:"})," The total weight of validators scheduled to participate in a round"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Participated weight of a round:"})," The total weight of validators that participated or sent messages before the end of the round"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Relative weight"}),": A validator's weight relative to the total validator weight that participated in a round"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"For each finalized block, there is a fraction of rewards due for signature creation and collection"}),"\n",(0,t.jsx)(n.li,{children:"Signature rewards are split between the finder (block proposer) and the signature creators"}),"\n",(0,t.jsxs)(n.li,{children:["The signature creators get a part of the signature reward pot due for the block: ",(0,t.jsx)(n.code,{children:"(1 - finder's fee) * relative weight"})]}),"\n",(0,t.jsxs)(n.li,{children:["The finder gets a small reward as well to incentivize collecting and reporting all the signatures: ",(0,t.jsx)(n.code,{children:"finder's fee * total relative weight of signatures collected"})]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the ",(0,t.jsx)(n.a,{href:"/next/concepts/design/rewards",children:"Rewards Design"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"inactivity",children:"Validator Inactivity"}),"\n",(0,t.jsx)(n.p,{children:"Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid."}),"\n",(0,t.jsx)(n.h2,{id:"founding-validators",children:"Founding Validators"}),"\n",(0,t.jsx)(n.p,{children:"When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days."})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>o});var t=i(96540);const s={},a=t.createContext(s);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a53bd891.07818a14.js b/assets/js/a53bd891.07818a14.js new file mode 100644 index 000000000..cdcc354e4 --- /dev/null +++ b/assets/js/a53bd891.07818a14.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55664],{47150:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>o,toc:()=>i});var r=n(74848),c=n(28453);const t={},a="F",o={id:"concepts/glossary/F",title:"F",description:"---",source:"@site/docs/concepts/glossary/F.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/F",permalink:"/concepts/glossary/F",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"E",permalink:"/concepts/glossary/E"},next:{title:"G",permalink:"/concepts/glossary/G"}},l={},i=[{value:"Finality",id:"finality",level:2},{value:"Fungible",id:"fungible",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"f",children:"F"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"finality",children:"Finality"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B#block-finality",children:"block finality"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"fungible",children:"Fungible"}),"\n",(0,r.jsxs)(s.p,{children:["A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N#non-fungible-token",children:"non-fungible token"}),", where each token is unique and not interchangeable."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var r=n(96540);const c={},t=r.createContext(c);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a53bd891.34baf369.js b/assets/js/a53bd891.34baf369.js deleted file mode 100644 index 6cdd8b4e4..000000000 --- a/assets/js/a53bd891.34baf369.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5664],{47150:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>x,frontMatter:()=>c,metadata:()=>o,toc:()=>i});var t=s(74848),r=s(28453);const c={},a="F",o={id:"concepts/glossary/F",title:"F",description:"---",source:"@site/docs/concepts/glossary/F.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/F",permalink:"/next/concepts/glossary/F",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"E",permalink:"/next/concepts/glossary/E"},next:{title:"G",permalink:"/next/concepts/glossary/G"}},l={},i=[{value:"Finality",id:"finality",level:2},{value:"Fungible",id:"fungible",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"f",children:"F"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"finality",children:"Finality"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B#block-finality",children:"block finality"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"fungible",children:"Fungible"}),"\n",(0,t.jsxs)(n.p,{children:["A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N#non-fungible-token",children:"non-fungible token"}),", where each token is unique and not interchangeable."]})]})}function x(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},c=t.createContext(r);function a(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a55b9639.792f74b1.js b/assets/js/a55b9639.792f74b1.js deleted file mode 100644 index 4de6469a0..000000000 --- a/assets/js/a55b9639.792f74b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6453],{46557:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var s=t(74848),r=t(28453);const a={title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"},o="Listing CSPR on an Exchange",i={id:"resources/advanced/list-cspr",title:"Listing CSPR",description:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.",source:"@site/docs/resources/advanced/list-cspr.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/list-cspr",permalink:"/next/resources/tutorials/advanced/list-cspr",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"}},c={},l=[{value:"Setting up a Node",id:"setting-up-a-node",level:2},{value:"Casper Account",id:"casper-account",level:2},{value:"Understanding Basic Transactions",id:"understanding-basic-transactions",level:2},{value:"Native transfer",id:"native-transfer",level:3},{value:"Bulk or batched Wasm transfer",id:"bulk-or-batched-wasm-transfer",level:3},{value:"Integrating CSPR",id:"integrating-cspr",level:2},{value:"Testing the Integration",id:"testing-the-integration",level:2},{value:"The Casper Protocol",id:"the-casper-protocol",level:2},{value:"Staking Integration for Exchanges",id:"staking-integration-for-exchanges",level:2},{value:"Deploy Structures and Parameters",id:"deploy-structures-and-parameters",level:3},{value:"1. Creating a deploy object",id:"1-creating-a-deploy-object",level:4},{value:"2a. Sign the deploy (Casper Signer)",id:"2a-sign-the-deploy-casper-signer",level:4},{value:"2b. Sign the deploy (Ledger)",id:"2b-sign-the-deploy-ledger",level:4},{value:"Costs and Minimums",id:"costs-and-minimums",level:3},{value:"The Delegation Cap",id:"the-delegation-cap",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"listing-cspr-on-an-exchange",children:"Listing CSPR on an Exchange"})}),"\n",(0,s.jsx)(n.p,{children:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-a-node",children:"Setting up a Node"}),"\n",(0,s.jsxs)(n.p,{children:["While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see ",(0,s.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration",children:"Basic Node Setup"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions."}),"\n",(0,s.jsx)(n.h2,{id:"casper-account",children:"Casper Account"}),"\n",(0,s.jsxs)(n.p,{children:["You will need a Casper Account to handle the transactions on an exchange. Casper has an ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Account model"})," and instructions on how to ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-creating",children:"create an Account"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users."}),"\n",(0,s.jsx)(n.h2,{id:"understanding-basic-transactions",children:"Understanding Basic Transactions"}),"\n",(0,s.jsx)(n.p,{children:"We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice."}),"\n",(0,s.jsx)(n.p,{children:"Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others."}),"\n",(0,s.jsx)(n.h3,{id:"native-transfer",children:"Native transfer"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"payment"})," field describes how we are paying for the deploy, in this case a native transfer, while the ",(0,s.jsx)(n.code,{children:"session"})," field describes the actual transfer."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Native Transfer Deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n"id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "approvals": [\n {\n "signature": "130 chars",\n "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"\n }\n ],\n "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713",\n "header": {\n "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e",\n "chain_name": "casper-net-1",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2021-04-20T18:04:40.333Z",\n "ttl": "1h"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "021027",\n "cl_type": "U512",\n "parsed": "10000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668",\n "cl_type": {\n "ByteArray": 32\n },\n "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668"\n }\n ],\n [\n "id",\n {\n "bytes": "00",\n "cl_type": {\n "Option": "U64"\n },\n "parsed": null\n }\n ]\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see ",(0,s.jsx)(n.a,{href:"/next/developers/cli/transfers/direct-token-transfer",children:"Direct Token Transfer"}),". The following command transfers 10 CSPR from ",(0,s.jsx)(n.em,{children:"account A's main purse"})," to ",(0,s.jsx)(n.em,{children:"account B's main purse"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id 1 \\\n--transfer-id 123456 \\\n--node-address http://<node-ip-address>:7777 \\\n--amount 10000000000 \\\n--secret-key <accountA-secret-key>.pem \\\n--chain-name casper \\\n--target-account <accountB-hex-encoded-public-key> \\\n--payment-amount <payment-in-motes>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The payment amount varies based on the deploy and network ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),". For node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes."]}),"\n",(0,s.jsx)(n.h3,{id:"bulk-or-batched-wasm-transfer",children:"Bulk or batched Wasm transfer"}),"\n",(0,s.jsxs)(n.p,{children:["Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html",children:"Rust contract API"}),", which can be used in session code to achieve batched Wasm transfer:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_account"}),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_public_key"}),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_purse"}),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_public_key"}),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_account"}),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on how to write session code, see ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),". There are equivalent ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305",children:"assembly script"})," methods available. Alternatively, you can program directly against the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370",children:"ext-FFI"})," methods."]}),"\n",(0,s.jsx)(n.h2,{id:"integrating-cspr",children:"Integrating CSPR"}),"\n",(0,s.jsxs)(n.p,{children:["You can integrate with the ",(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/",children:"JSON-RPC API"})," of a node on the Casper Mainnet.\nYou can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,s.jsx)(n.a,{href:"/next/sdk",children:"SDK Libraries"}),".\nCasper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-integration",children:"Testing the Integration"}),"\n",(0,s.jsxs)(n.p,{children:["Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", then you can do so with your own test accounts."]}),"\n",(0,s.jsx)(n.p,{children:"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-protocol",children:"The Casper Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."}),"\n",(0,s.jsxs)(n.li,{children:["Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#execution-semantics-head",children:"Execution Semantics"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"staking-integration-for-exchanges",children:"Staking Integration for Exchanges"}),"\n",(0,s.jsxs)(n.p,{children:["Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"})," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,s.jsx)(n.a,{href:"/next/users/delegating",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-structures-and-parameters",children:"Deploy Structures and Parameters"}),"\n",(0,s.jsx)(n.p,{children:"Staking operations consists of two parts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Creating a deploy object"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/next/developers/dapps/signing-a-transaction",children:"Signing the deploy"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The staking deploy requires the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The delegator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The validator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The new validator's public key (For redelegation only)"}),"\n",(0,s.jsx)(n.li,{children:"The amount to be delegated"}),"\n",(0,s.jsx)(n.li,{children:"The gas cost"}),"\n",(0,s.jsx)(n.li,{children:"The auction manager contract's hash"}),"\n",(0,s.jsx)(n.li,{children:"The appropriate entry point"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate",children:"Delegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate",children:"Undelegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate",children:"Redelegate"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-creating-a-deploy-object",children:"1. Creating a deploy object"}),"\n",(0,s.jsxs)(n.p,{children:["To create a deploy using the JavaScript SDK, we will need ",(0,s.jsx)(n.code,{children:"deployParams"}),", ",(0,s.jsx)(n.code,{children:"session"})," and a ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Deploy params is a ",(0,s.jsx)(n.code,{children:"DeployUtil.DeployParams"})," object created from the delegator's ",(0,s.jsx)(n.code,{children:"publicKey"})," and the network name as shown in the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For creating a ",(0,s.jsx)(n.code,{children:"session"})," object, which is ",(0,s.jsx)(n.code,{children:"DeployUtil.ExecutableDeployItem"}),", we need"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"delegator"})," and ",(0,s.jsx)(n.strong,{children:"validator's public keys"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"amount"})," of tokens to delegate/undelegate/redelgate"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"auction manager contract's hash"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["First, create a variable ",(0,s.jsx)(n.code,{children:"RuntimeArgs"})," from the public keys and the amount. We will need to use it below in ",(0,s.jsx)(n.code,{children:"session"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Second, create a ",(0,s.jsx)(n.code,{children:"session"})," parameter. It is a ",(0,s.jsx)(n.code,{children:"Uint8Array"})," consisting of the ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"}),", the ",(0,s.jsx)(n.code,{children:"entry points"})," and ",(0,s.jsx)(n.code,{children:"runtime arguments"}),", which we previously created."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"})," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Mainnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Testnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Your ",(0,s.jsx)(n.code,{children:"entry point"})," will depend on which action you are performing, with the following three available:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegate"})," - Initial delegation to a validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"undelegate"})," - Undelegating tokens from a validator back to the delegator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"redelegate"})," - Redelegating tokens to a new validator"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the ",(0,s.jsx)(n.code,{children:"payment"})," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml",children:(0,s.jsx)(n.code,{children:"chainspec for version 1.4.8"})}),". You will need the chainspec for the network version you are using."]}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"DeployUtil.standardPayment"})," method for creating ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n"})}),"\n",(0,s.jsx)(n.p,{children:"The last operation is creating the deploy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Redelegation"}),", occurs the same way as delegation, but with the introduction of a third public_key."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2a-sign-the-deploy-casper-signer",children:"2a. Sign the deploy (Casper Signer)"}),"\n",(0,s.jsxs)(n.p,{children:["To get the signature, you will need to use ",(0,s.jsx)(n.code,{children:"Signer.sign"})," from the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"}),". It will return ",(0,s.jsx)(n.code,{children:"Promise<{ deploy }>"}),", which is the signed object."]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"DeployUtil.deployFromJson"})," to convert the result and sent it to network with:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2b-sign-the-deploy-ledger",children:"2b. Sign the deploy (Ledger)"}),"\n",(0,s.jsxs)(n.p,{children:["You will need to connect with your ",(0,s.jsx)(n.code,{children:"Ledger"})," first to get the signature."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Signature will be in a property called ",(0,s.jsx)(n.code,{children:"res.signatureRS"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After that, we can create a signed deploy,"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can then send it to a network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"casperService.deploy(signedDeploy)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-minimums",children:"Costs and Minimums"}),"\n",(0,s.jsxs)(n.p,{children:["The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Transfer Cost: 100,000,000 motes or 0.1 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,s.jsx)(n.strong,{children:"CSPR"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"the-delegation-cap",children:"The Delegation Cap"}),"\n",(0,s.jsxs)(n.p,{children:["Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,s.jsx)(n.code,{children:"953"}),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."]}),"\n",(0,s.jsxs)(n.p,{children:["Validators with a delegator count at or above ",(0,s.jsx)(n.code,{children:"953"})," at the time of the ",(0,s.jsx)(n.strong,{children:"1.4.5"})," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,s.jsx)(n.code,{children:"953"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,s.jsx)(n.strong,{children:"CSPR"})," to that validator. However, no new delegators may join the validator until it drops below the ",(0,s.jsx)(n.code,{children:"953"})," limit."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a55b9639.bcfdb692.js b/assets/js/a55b9639.bcfdb692.js new file mode 100644 index 000000000..dd8deafe3 --- /dev/null +++ b/assets/js/a55b9639.bcfdb692.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46453],{46557:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var s=t(74848),r=t(28453);const a={title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"},o="Listing CSPR on an Exchange",i={id:"resources/advanced/list-cspr",title:"Listing CSPR",description:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.",source:"@site/docs/resources/advanced/list-cspr.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/list-cspr",permalink:"/resources/tutorials/advanced/list-cspr",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Listing CSPR",slug:"/resources/tutorials/advanced/list-cspr"}},c={},l=[{value:"Setting up a Node",id:"setting-up-a-node",level:2},{value:"Casper Account",id:"casper-account",level:2},{value:"Understanding Basic Transactions",id:"understanding-basic-transactions",level:2},{value:"Native transfer",id:"native-transfer",level:3},{value:"Bulk or batched Wasm transfer",id:"bulk-or-batched-wasm-transfer",level:3},{value:"Integrating CSPR",id:"integrating-cspr",level:2},{value:"Testing the Integration",id:"testing-the-integration",level:2},{value:"The Casper Protocol",id:"the-casper-protocol",level:2},{value:"Staking Integration for Exchanges",id:"staking-integration-for-exchanges",level:2},{value:"Deploy Structures and Parameters",id:"deploy-structures-and-parameters",level:3},{value:"1. Creating a deploy object",id:"1-creating-a-deploy-object",level:4},{value:"2a. Sign the deploy (Casper Signer)",id:"2a-sign-the-deploy-casper-signer",level:4},{value:"2b. Sign the deploy (Ledger)",id:"2b-sign-the-deploy-ledger",level:4},{value:"Costs and Minimums",id:"costs-and-minimums",level:3},{value:"The Delegation Cap",id:"the-delegation-cap",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"listing-cspr-on-an-exchange",children:"Listing CSPR on an Exchange"})}),"\n",(0,s.jsx)(n.p,{children:"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,s.jsx)(n.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n",(0,s.jsx)(n.h2,{id:"setting-up-a-node",children:"Setting up a Node"}),"\n",(0,s.jsxs)(n.p,{children:["While it is not necessary for an exchange to operate their own node on the Casper Mainnet, we recommend that they do so if they expect to handle moderate to high volumes of transaction activity. A node operated by an exchange does not have to be a validating node, it can be read-only. For setup instructions, see ",(0,s.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic Node Setup"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"This setup enables you to have a self-administered gateway to the Casper Mainnet to get data and submit transactions."}),"\n",(0,s.jsx)(n.h2,{id:"casper-account",children:"Casper Account"}),"\n",(0,s.jsxs)(n.p,{children:["You will need a Casper Account to handle the transactions on an exchange. Casper has an ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account model"})," and instructions on how to ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-creating",children:"create an Account"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"For your exchange, you need at least one Account. Each Casper network uses an Account model that holds onto general resources and purses with tokens and provides an on-chain identity. As an exchange, if you are dealing with high volumes of transaction activity, you might need a main account for the exchange platform and sub-accounts for other users."}),"\n",(0,s.jsx)(n.h2,{id:"understanding-basic-transactions",children:"Understanding Basic Transactions"}),"\n",(0,s.jsx)(n.p,{children:"We have a token and transaction model that features different levels of support that range from convenient to robust. Usually, when you are transferring Casper tokens between two parties, the native two-party transfer will suffice."}),"\n",(0,s.jsx)(n.p,{children:"Casper supports native two-party transfers as well as bulk transfers using custom Wasm. The native transfer is ideal when you need to perform a one-to-one transfer between two purses. Whereas the batched Wasm transfer is better suited for making bulk transfers. A batched Wasm transfer allows you to do multiple transfers in a single deploy, making it more cost-effective when sending tokens from one purse to several others."}),"\n",(0,s.jsx)(n.h3,{id:"native-transfer",children:"Native transfer"}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"payment"})," field describes how we are paying for the deploy, in this case a native transfer, while the ",(0,s.jsx)(n.code,{children:"session"})," field describes the actual transfer."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Native Transfer Deploy"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n"id": 1,\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "approvals": [\n {\n "signature": "130 chars",\n "signer": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150"\n }\n ],\n "hash": "ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713",\n "header": {\n "account": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "body_hash": "da35b095640a403324306c59ac6f18a446dfcc28faf753ce58b96b635587dd8e",\n "chain_name": "casper-net-1",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2021-04-20T18:04:40.333Z",\n "ttl": "1h"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "021027",\n "cl_type": "U512",\n "parsed": "10000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "0400f90295",\n "cl_type": "U512",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "bytes": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668",\n "cl_type": {\n "ByteArray": 32\n },\n "parsed": "8ae68a6902ff3c029cea32bb67ae76b25d26329219e4c9ceb676745981fd3668"\n }\n ],\n [\n "id",\n {\n "bytes": "00",\n "cl_type": {\n "Option": "U64"\n },\n "parsed": null\n }\n ]\n ]\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Native transfers are the simplest method to transfer tokens between two purses. For details about the native transfer command, see ",(0,s.jsx)(n.a,{href:"/developers/cli/transfers/direct-token-transfer",children:"Direct Token Transfer"}),". The following command transfers 10 CSPR from ",(0,s.jsx)(n.em,{children:"account A's main purse"})," to ",(0,s.jsx)(n.em,{children:"account B's main purse"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id 1 \\\n--transfer-id 123456 \\\n--node-address http://<node-ip-address>:7777 \\\n--amount 10000000000 \\\n--secret-key <accountA-secret-key>.pem \\\n--chain-name casper \\\n--target-account <accountB-hex-encoded-public-key> \\\n--payment-amount <payment-in-motes>\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The payment amount varies based on the deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes."]}),"\n",(0,s.jsx)(n.h3,{id:"bulk-or-batched-wasm-transfer",children:"Bulk or batched Wasm transfer"}),"\n",(0,s.jsxs)(n.p,{children:["Bulk or batched Wasm transfers allow you to apply some logic before or after the transfer. They also allow for conditional transfers. You may also use them if you are doing a series of transfers between multiple purses. Listed below are five methods for the ",(0,s.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/index.html",children:"Rust contract API"}),", which can be used in session code to achieve batched Wasm transfer:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_account"}),": Transfers amount of motes from the main purse of the account to the purse of a target account. If the target purse does not exist, the transfer process will create one. Can be called from session code only and not a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_to_public_key"}),": Transfers amount of motes from the main purse of the caller\u2019s account to the main purse of the target. If the account referenced by the target does not exist, the transfer will create a new account. Can be called from session code only and not from a contract as a contract doesn't have a main purse."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_purse"}),": Transfers amount of motes from source purse to target purse. If the target does not exist, the transfer fails."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_public_key"}),": Transfers amount of motes from source to the main purse of target. If the account referenced by the target does not exist, the transfer will create it."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from_purse_to_account"}),": Transfers amount of motes from source purse to target account's purse. If the target account does not exist, the transfer creates a new account."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more information on how to write session code, see ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),". There are equivalent ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract_as/assembly/purse.ts#L135-L305",children:"assembly script"})," methods available. Alternatively, you can program directly against the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/e01b528db64f96fc1d3eac8b3b8e58e1337b398d/smart_contracts/contract/src/ext_ffi.rs#L283-L370",children:"ext-FFI"})," methods."]}),"\n",(0,s.jsx)(n.h2,{id:"integrating-cspr",children:"Integrating CSPR"}),"\n",(0,s.jsxs)(n.p,{children:["You can integrate with the ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/",children:"JSON-RPC API"})," of a node on the Casper Mainnet.\nYou can program directly against the RPC or if you prefer you can choose from the variety of SDK libraries that are available to use on a Casper network see ",(0,s.jsx)(n.a,{href:"/sdk",children:"SDK Libraries"}),".\nCasper also provides a stream server that gives you real-time information about a variety of events occurring on a node. Use of the stream is optional. You might want to use this feature as it notifies you of events instead of requiring you to ask periodically. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"testing-the-integration",children:"Testing the Integration"}),"\n",(0,s.jsxs)(n.p,{children:["Our recommended testing mechanism is to have a test environment that points at the official Casper ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Through this, you may run production like operations of your test exchange against the test environment. However, if you are not doing this and you just want to integrate with the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"}),", then you can do so with your own test accounts."]}),"\n",(0,s.jsx)(n.p,{children:"If you are not going to do a Testnet integration, then we suggest you create some additional test accounts and test the transactions on the Mainnet through your software prior to moving to the general public."}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-protocol",children:"The Casper Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Casper is integrated with BitGo for enterprise grade custody. If your exchange uses BitGo, support for Casper is available already."}),"\n",(0,s.jsxs)(n.li,{children:["Casper has an execution after consensus model, which means that transactions are executed after they are finalized. Transactions are not orphaned or uncle\u2019d on Casper and neither does chain reorganization happen on it. For more information on the execution process, see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Execution Semantics"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:["Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see ",(0,s.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"staking-integration-for-exchanges",children:"Staking Integration for Exchanges"}),"\n",(0,s.jsxs)(n.p,{children:["Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"})," to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found ",(0,s.jsx)(n.a,{href:"/users/delegating",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-structures-and-parameters",children:"Deploy Structures and Parameters"}),"\n",(0,s.jsx)(n.p,{children:"Staking operations consists of two parts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Creating a deploy object"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/dapps/signing-a-transaction",children:"Signing the deploy"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The staking deploy requires the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The delegator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The validator's public key"}),"\n",(0,s.jsx)(n.li,{children:"The new validator's public key (For redelegation only)"}),"\n",(0,s.jsx)(n.li,{children:"The amount to be delegated"}),"\n",(0,s.jsx)(n.li,{children:"The gas cost"}),"\n",(0,s.jsx)(n.li,{children:"The auction manager contract's hash"}),"\n",(0,s.jsx)(n.li,{children:"The appropriate entry point"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Casper provides a series of prebuilt Wasm files for use in these operations. They are provided for convenience, and you are free to create your own custom deploys. You can find them in our ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, in the following locations:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/delegate",children:"Delegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/undelegate",children:"Undelegate"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/client/redelegate",children:"Redelegate"})}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"1-creating-a-deploy-object",children:"1. Creating a deploy object"}),"\n",(0,s.jsxs)(n.p,{children:["To create a deploy using the JavaScript SDK, we will need ",(0,s.jsx)(n.code,{children:"deployParams"}),", ",(0,s.jsx)(n.code,{children:"session"})," and a ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Deploy params is a ",(0,s.jsx)(n.code,{children:"DeployUtil.DeployParams"})," object created from the delegator's ",(0,s.jsx)(n.code,{children:"publicKey"})," and the network name as shown in the following:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst deployParams = new DeployUtil.DeployParams(\n CLPublicKey.fromHex(publicKeyHex),\n network_name // 'testnet' | 'mainnet'\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["For creating a ",(0,s.jsx)(n.code,{children:"session"})," object, which is ",(0,s.jsx)(n.code,{children:"DeployUtil.ExecutableDeployItem"}),", we need"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"delegator"})," and ",(0,s.jsx)(n.strong,{children:"validator's public keys"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"amount"})," of tokens to delegate/undelegate/redelgate"]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"auction manager contract's hash"})]}),"\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.strong,{children:"entry point"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["First, create a variable ",(0,s.jsx)(n.code,{children:"RuntimeArgs"})," from the public keys and the amount. We will need to use it below in ",(0,s.jsx)(n.code,{children:"session"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLValueBuilder, CLPublicKey } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes) // in motes\n});\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Second, create a ",(0,s.jsx)(n.code,{children:"session"})," parameter. It is a ",(0,s.jsx)(n.code,{children:"Uint8Array"})," consisting of the ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"}),", the ",(0,s.jsx)(n.code,{children:"entry points"})," and ",(0,s.jsx)(n.code,{children:"runtime arguments"}),", which we previously created."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"auction manager contract's hash"})," will depend on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Mainnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Testnet"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Your ",(0,s.jsx)(n.code,{children:"entry point"})," will depend on which action you are performing, with the following three available:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegate"})," - Initial delegation to a validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"undelegate"})," - Undelegating tokens from a validator back to the delegator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"redelegate"})," - Redelegating tokens to a new validator"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { decodeBase16, DeployUtil } from 'casper-js-sdk';\n\nconst session = DeployUtil.ExecutableDeployItem.newStoredContractByHash(\n decodeBase16(auction_manager_contract_hash), // auction manager contract hash\n contractEntryPoint, // auction manager entry point\n args\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["To create the ",(0,s.jsx)(n.code,{children:"payment"})," parameter for the deploy, we need a deploy cost. The actual costs can be pulled from the network chainspec. Here is the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.8/resources/production/chainspec.toml",children:(0,s.jsx)(n.code,{children:"chainspec for version 1.4.8"})}),". You will need the chainspec for the network version you are using."]}),"\n",(0,s.jsxs)(n.p,{children:["Use the ",(0,s.jsx)(n.code,{children:"DeployUtil.standardPayment"})," method for creating ",(0,s.jsx)(n.code,{children:"payment"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nconst payment = DeployUtil.standardPayment(deployCost);\n"})}),"\n",(0,s.jsx)(n.p,{children:"The last operation is creating the deploy:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil } from 'casper-js-sdk';\n\nDeployUtil.makeDeploy(deployParams, session, payment);\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Redelegation"}),", occurs the same way as delegation, but with the introduction of a third public_key."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { RuntimeArgs, CLPublicKey, CLValueBuilder } from 'casper-js-sdk';\n\nconst args = RuntimeArgs.fromMap({\n delegator: CLPublicKey.fromHex(delegatorPublicKeyHex),\n validator: CLPublicKey.fromHex(validatorPublicKeyHex),\n new_validator: CLPublicKey.fromHex(redelegateValidatorPublicKeyHex),\n amount: CLValueBuilder.u512(amountMotes)\n})\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2a-sign-the-deploy-casper-signer",children:"2a. Sign the deploy (Casper Signer)"}),"\n",(0,s.jsxs)(n.p,{children:["To get the signature, you will need to use ",(0,s.jsx)(n.code,{children:"Signer.sign"})," from the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"JavaScript SDK"}),". It will return ",(0,s.jsx)(n.code,{children:"Promise<{ deploy }>"}),", which is the signed object."]}),"\n",(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.code,{children:"DeployUtil.deployFromJson"})," to convert the result and sent it to network with:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { Signer, CasperServiceByJsonRPC, DeployUtil } from 'casper-js-sdk';\n\nconst casperService = new CasperServiceByJsonRPC(GRPC_URL);\nconst deployJson = DeployUtil.deployToJson(deploy);\nSigner.sign(\n deployJson,\n accountPublicKey,\n recipientPublicKey\n).then((signedDeployJson) => {\n const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);\n if (signedDeploy.ok) {\n casperService.deploy(signedDeploy.val! as DeployUtil.Deploy); // sent deploy\n }\n}\n"})}),"\n",(0,s.jsx)(n.h4,{id:"2b-sign-the-deploy-ledger",children:"2b. Sign the deploy (Ledger)"}),"\n",(0,s.jsxs)(n.p,{children:["You will need to connect with your ",(0,s.jsx)(n.code,{children:"Ledger"})," first to get the signature."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import TransportWebUSB from '@ledgerhq/hw-transport-webusb';\nimport LedgerApp, { ResponseBase } from '@zondax/ledger-casper';\nimport { DeployUtil } from 'casper-js-sdk';\n\nconst getBipPath = (index: number) => {\n const idx = index.toString();\n return `m/44'/506'/0'/0/${idx}`;\n};\n\nconst deployBytes = DeployUtil.deployToBytes(deploy) as Buffer;\nconst transport = await TransportWebUSB.create();\nconst ledgerApp = new LedgerApp(transport);\nconst res = await ledgerApp.sign(\n getBipPath(selectedAccountIndex),\n deployBytes\n);\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The Signature will be in a property called ",(0,s.jsx)(n.code,{children:"res.signatureRS"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"After that, we can create a signed deploy,"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"import { DeployUtil, CLPublicKey } from 'casper-js-sdk';\n\nconst signedDeploy = DeployUtil.setSignature(\n deploy,\n signatureRS,\n CLPublicKey.fromHex(accountPublicKey)\n);\n"})}),"\n",(0,s.jsx)(n.p,{children:"We can then send it to a network."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"casperService.deploy(signedDeploy)\n"})}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-minimums",children:"Costs and Minimums"}),"\n",(0,s.jsxs)(n.p,{children:["The following are costs and minimum amounts for version 1.5.1, but up-to-date values should be pulled from the network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Transfer Cost: 100,000,000 motes or 0.1 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Delegation Cost: 2,500,000,000 motes or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum transfer amount: 2,500,000,000 motes, or 2.5 ",(0,s.jsx)(n.strong,{children:"CSPR"})]}),"\n",(0,s.jsxs)(n.p,{children:["Minimum amount required for delegation: 500,000,000,000 motes, or 500 ",(0,s.jsx)(n.strong,{children:"CSPR"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"the-delegation-cap",children:"The Delegation Cap"}),"\n",(0,s.jsxs)(n.p,{children:["Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at ",(0,s.jsx)(n.code,{children:"953"}),". This is a temporary solution to prevent complications with Casper\u2019s fast sync mechanism - in which high bond counts could break fast sync."]}),"\n",(0,s.jsxs)(n.p,{children:["Validators with a delegator count at or above ",(0,s.jsx)(n.code,{children:"953"})," at the time of the ",(0,s.jsx)(n.strong,{children:"1.4.5"})," upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below ",(0,s.jsx)(n.code,{children:"953"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their ",(0,s.jsx)(n.strong,{children:"CSPR"})," to that validator. However, no new delegators may join the validator until it drops below the ",(0,s.jsx)(n.code,{children:"953"})," limit."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6957975.4b06c94e.js b/assets/js/a6957975.4b06c94e.js new file mode 100644 index 000000000..96e6a7406 --- /dev/null +++ b/assets/js/a6957975.4b06c94e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[78540],{3930:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var i=t(74848),s=t(28453);const o={title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},r="Launching a Casper Node with AWS Marketplace",a={id:"resources/beginner/aws-node",title:"AWS Casper Nodes",description:"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/aws-node.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/aws-node",permalink:"/2.0.0/resources/tutorials/beginner/aws-node",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"AWS Casper Nodes",slug:"/resources/tutorials/beginner/aws-node"},sidebar:"tutorials",previous:{title:"Fungible Tokens",permalink:"/2.0.0/resources/tutorials/beginner/cep18"},next:{title:"Advanced Tutorials",permalink:"/2.0.0/resources/tutorials/advanced/"}},c={},h=[{value:"Step 1 - Subscribing",id:"step-1---subscribing",level:2},{value:"Step 2 - Initial Configuration",id:"step-2---initial-configuration",level:2},{value:"Step 3 - Launch Configuration",id:"step-3---launch-configuration",level:2},{value:"EC2 Key Pair Settings",id:"ec2-key-pair-settings",level:3},{value:"Launching Your Node",id:"launching-your-node",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"launching-a-casper-node-with-aws-marketplace",children:"Launching a Casper Node with AWS Marketplace"})}),"\n",(0,i.jsxs)(n.p,{children:["The following tutorial outlines the process for launching a ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/marketplace/pp/prodview-d7xpciuetjq5u",children:"Casper Node through the Amazon AWS Marketplace"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"step-1---subscribing",children:"Step 1 - Subscribing"}),"\n",(0,i.jsx)(n.p,{children:"You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 01",src:t(37758).A+"",width:"900",height:"214"})}),"\n",(0,i.jsx)(n.p,{children:"If you are not currently signed in to an AWS account, you will need to either sign in or create an account to subscribe."}),"\n",(0,i.jsxs)(n.p,{children:["You need to accept the terms and conditions listed to continue with the subscription. You may also choose a different ",(0,i.jsx)(n.a,{href:"https://aws.amazon.com/ec2/instance-types/",children:"Amazon EC2 (Amazon Elastic Compute Cloud) instance type"})," if you prefer."]}),"\n",(0,i.jsxs)(n.p,{children:["After accepting the terms, it may take a few moments for AWS to process your request. In this event, you will see the ",(0,i.jsx)(n.code,{children:"Continue to Configuration"})," button grayed out, as shown below:"]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 04",src:t(5109).A+"",width:"259",height:"60"})}),"\n",(0,i.jsx)(n.p,{children:"Once the system processes your request, the button will light orange, and you may continue to the configuration options."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 05",src:t(36012).A+"",width:"266",height:"68"})}),"\n",(0,i.jsx)(n.h2,{id:"step-2---initial-configuration",children:"Step 2 - Initial Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Configuration"})," page allows you to choose your fulfillment option, software version, and the region in which your node will be hosted. Unless you intend to run your Casper node with a specific legacy version of the software, we suggest using the most current release."]}),"\n",(0,i.jsx)(n.p,{children:"The window on the right will show an estimation of the infrastructure costs from AWS for operating the Casper node, given the EC2 instance type you previously chose."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 06",src:t(66179).A+"",width:"1138",height:"713"})}),"\n",(0,i.jsx)(n.h2,{id:"step-3---launch-configuration",children:"Step 3 - Launch Configuration"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Launch"})," page will show your previously selected configuration details and a ",(0,i.jsx)(n.code,{children:"Usage instructions"})," button that leads to the most recent instructions based on your chosen software version."]}),"\n",(0,i.jsx)(n.p,{children:'Below this, you will see a drop-down menu with the title "Choose Action":'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 08",src:t(48602).A+"",width:"834",height:"189"})}),"\n",(0,i.jsx)(n.p,{children:"This drop-down menu includes the following options:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Launch through EC2 - This option launches your configuration through the ",(0,i.jsx)(n.a,{href:"https://console.aws.amazon.com/ec2/",children:"Amazon EC2 Console"})]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Launch from Website - This option will launch directly from the current page, using further configuration options outlined below."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Copy to Service Catalog - Copy your configuration of the software to the ",(0,i.jsx)(n.code,{children:"Service Catalog"})," console, where you can manage your company's cloud resources."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional drop-down menus include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"EC2 Instance Type - This option determines the machine's specifications that will run your instance of the Casper node software."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"VPC Settings - This option selects the Virtual Private Cloud you will use for your Casper node. This should be auto-populated, but you can create a new VPC through the EC2 console by clicking the option below the drop-down box."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Subnet Settings - This option selects the subnet for your node under the listed VPC above. Again, it should be auto-populated, but you can create a new subnet."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:'Security Group Settings - This option determines the flow of traffic connecting to your Casper node. By clicking on "Create New Based on Seller Settings", you can create a new security group using the suggested default Casper settings.'}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"ec2-key-pair-settings",children:"EC2 Key Pair Settings"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 11",src:t(78769).A+"",width:"830",height:"245"})}),"\n",(0,i.jsx)(n.p,{children:'You will need an EC2 key pair to launch your Casper node. If you do not already have an EC2 key pair, you can create one directly from this page by clicking "Create a key pair in EC2". This will bring you to the EC2 console, where you can click "Create key pair". This will automatically download your keys in the selected file type, and you can choose the new key pair on the previous page.'}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 12",src:t(64552).A+"",width:"339",height:"43"})}),"\n",(0,i.jsx)(n.h3,{id:"launching-your-node",children:"Launching Your Node"}),"\n",(0,i.jsxs)(n.p,{children:["If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange ",(0,i.jsx)(n.code,{children:"Launch"})," button to launch your AWS-hosted Casper node."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.img,{alt:"Step 13",src:t(46815).A+"",width:"137",height:"58"})})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},37758:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS01-26219ce99c140282c6ad9137863a954a.png"},5109:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQMAAAA8CAIAAADt6EhQAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAiFSURBVHhe7ZyJchpJEobpbu7TgCWhA+uwxp6dHUfMW+y8086DzT7IHjFrW7JBB4izgeZs2K+ohmCEhCXNWIus/IKQu6u7qrKq8s/KQgobTrfrE4Rnj+n9KwjPG1GCIChECYKgECUIgkKUIAgKUYIgKEQJgqAQJQiCYtVv1k6KRe9KEL4JDvf2vKslZE8QBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEASFKEEQFKIEQVCIEgRBIUoQBIUo4VtgMplUGo0PxeJZ+Wrkul6pcB/W8a+y7U7nslLtDwZc+/3+7ZfZF4mEfvRgmu3254vLTCq5u7npFa0BeO1lpdJsd8bjsWGa8Ugkn9uyzHuHp4tKpVyrR0KhgN+fTiYKpXIiGjnY2fEef2UKpVKj1T7YziViMa9oXXlKf5VdLJVPzs7HrovXbqTT4VBwPJ54z+7DcDT698lpuVbTt6FAMBGLxiIRffung8z++7ng3dyNbr//2+mnWtOOhMOMNJ2IG4YxGY+9x/fB6fWCgcDh7g4fxpiIRr+qU2L5Pz98bLRa+jYWjiRjsVAopG+fKOulBLvdqdv2i0T87eEBwTv3Mnu4s4Mk9FN3PCa08+FCl8whPWB5arY9GI10CVEWOelrQFHEyGt7S384xBF7vb53vxKkVbdbLcehYa9ogaHr9TtnhbWAwedXlfFkcpTfO9rdYaSMd387xx6on+rh8JNrXWXOstmLwYJt4WBnO5tK6Vuqtx2n2encaMZtMFh64YLBdnu9SqOJ2OaWMMmLVrFAWB6cWg484mUs1C0swqNry7Q+rFd2VCyX602bwBaPRr2iGeTBF1eViU8tAKuwlc3kslmuicQsmzHNNPTi7G5suGMXP5veKTLJ5EYm/aFQ2Mxk+BC/bcchCRmxomp1fITknY2XlHd6veP8Hs5Em+8LxVg4/Go7xxtn5TJLSwIzmYwt08LCaDisG2dpaXnken4WCgZpAQHcaO0ccr/3nwvRaASpe0Uzhq57en7uOF3TslzXJec53NvFz240m1xosfc5DBnLcbiT4hkWWpZFIbNE8Kb8tpGq8m6Xl3Fl9pbNTJoS1ZxhaEuO9nYZF66sCqcwb/xk732dz/MCfZ2eXwyGQ9M0URGNoHOub1ym7AtPro/Gk8mOmCzTMFge734G81uqVpHHu+NjPiz/Va3enmkY78xv5959d/wmn2fSWUvc/e3Bvt8yWaef3r5hjfWbc9guCMNU+eHoKBQMUMV7cBOcW8gEdjY33h2/fru/z3JWGw3vmc/H8v94fMyS86GvvxwesNgrrNUwUjaE5ZFCqVLt9QeHu7t0992rPMI4L5f1o2Wz572jwL++PsIAPXD9PhXp6PhVnqbwe7IvXb4CxBOPRhgFGwtZ1g+vj+iO6ntbm/g3PTKZPEKQ/KQ7ptqrOQ35BCB+MktUeZXbcnrd0ixBXV4mXb4mrJcS3JFrMsdLR0bcyHXH5DasJRDwVKHj6KemaYUCAS4sv3XH46ZpGuFgkAtqEON14W2QEdFp0B9AkLiv5ff3Btf3/UVWW6shihMa6d27n0EOg4uEAwFONdxOBRamXxya23uZTVP9wRCFcBDndjo3X54cyzTSySS1UCnvU4eu2cH0rrIapNJjMwmHyUW5TcXj4WCo3XHU/vWgZXpM1ssgjn24iF71RdQ5UjmVd8uqcD1Y6Y5/ImNlkvvp8pJ8hs9gMAivPB3exVoiumn4+n31/dgi6niD36jqXn3LMMlMHvDdqNfUH4D94T+nn/718eS3T58Ll6UvtkV3pG1zyxES16Px+AHGPz7rpYRIJMzykY149zOIf8zufFnxDK4JW979V8bvtwKW9YYcgzxh+slvrfoq9i7WovmAP+DMgv0cgqWKl7jUrL7LycRSYVTf3h2qENU5Mj3YEUuVCsZ/f7DPkEl1ZtK+FbXpmNbc8qkSJ9jwAOMfn/VSQjqRYPcvV2sXV1f94VCnCuQViXiM2SQ7V+etyaTatImay6fqRQy1HAbpAe+zJLpwNcQy2idHp0rbIcPxfDQeibKk5XpDrzGt6d91LIKXUBe35p14LPpFa3GaTCpFOvGxeGa3OzgcbTZbbToiL+oO+nVbfUdJYtZx1GHgxhPFaojHyXh8MBwVS2XaIYOfq+62kV5jLmZe6/5u+1KiwHjKQRcB8o6GQ61ut9VRqWC91eoNBszGfJdYZ6y///KLd7lEY+ErgseBkJJKJEiLa7ZdqTfKtRoOwRZL5oorUHhZrZaqNfKTXDZDIVVqTRvvyaSS+BY+yjtBvz+ViBNHaYeTLlVG7igaidRtW59rm+12fzjAEbV70QI/1deOhtFstarNZrlWn/q6wdLSFEkzS1mp12kKky6rNbb9a1/Y4w4Nu0XFRqv9MpWiyo3WLsIBwG/52QB1j5VGo9N1yK35OP3BFd1VqthMJsZBk9HdavbvJwEXpxYGYDldkLI0Oh3qMi1EFj2i20Z6rQuGyXCupgvB3NJFMhbDHjZJzkJ0yujokTcJWLoW89zqdKazVEUPzNLe5gZKuG2ZqPuYLK/CnDX9n7+INIQT4jpJBfKYFxKHmFD2ja8UZlgkEnpyEe0Ki9xo0grubi2hGvelTX2g1OC1VGdvWbbkYdDL+0Jh+mts9U3aipEuol8LBAPa4++IHhHquletR2DFt6jyf+B9y5BYjtwxOwMyu6hU6k07n9v643+68nQRJTxTOHgUy6XhSJ2Y2V42s5nNdFo/ep6IEgRB8ZT+Ak8Q/i+IEgRBIUoQBIUoQRAUogRBUIgSBEEhShAEhShBEBSiBEFQiBIEQSFKEATFqr87+sevv3pXgvBN8Leff/aulpA9QRAUq/YEQXg+yJ4gCApRgiAoRAmCoBAlCIJClCAIClGCIChECYKgECUIgs/n8/0Ps5JgKFFEE0IAAAAASUVORK5CYII="},36012:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQoAAABECAIAAAD2jOw2AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAoZSURBVHhe7Zx3cFTXFca3F+2uCuqsGkKWEDIWEiOaKDYgAsKywLaCnTY2EOwkkzaMJ4ntTDITx+SP2CmT8XhsQ4zHYwwulNASQEh0iSK6wepCfbXqW7Q1n/ZdrRl2r7RgjBc4v3mzere8984t37nnvlmt2GyxiAiC8IeE/SUIwgeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBBeSB0FwIXkQBJexv7Gr3q1mZwRxX2BZFui31Gn1IAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJA+C4ELyIAguJI/7B7dbdNoQ/peq9J2NcUNOGtk7QPB2Yn2/5qUTD+dvm4dj1aHcL/u0rOBrUN2rnfrJgh318SwdHGAqf1KrL943Ey1dvCv/vS9SbK7bGZf/Nccs3zezw6Js6Nc0DITM2jb/7SsTWNk3z8c1CdM/f7RxIISl7wukr7z6KjvlIK/+Mzu7i3xap1+5Py9WPbQms/E7SZ0ysTtZa4lRD7HigDE7pKvLciNVtmTd8Ff8JRK3WuaaGds9TmUXKtxZ3r+WhIm+MMHA0gHQZVWsLs/dUpNQMrFlZVrL1Mg+aCNrXL9M4mY1AgadppU7/jb74px4Y4jMKRG7Z8T0xIfccqcFCCx/9kBeTmRflNqGpFgkwgBNj+lRSF1ChaDFkT7GnPcSjKtHXb/mtTMZf8r74v3HzhRPaFuoN/x8Sh1mjFCK2YMKOHxdLKKL7iHFxe7QQbtMyLE5JV1WpXAOIhT2FyfXp4WZWNrDgF2GS3AhS48K9HatV9s8qHa4MB9upt2sYmcjjGItgMEbryYbLMqDRUd/OaUWLUV7n8toUnlmmLc5+MT5TfiaPWBjrQaQxwuTG3Ki+oSkyy1uNqmxpPg1gwcai6fgBI01WBVnu8I7zErcSihFJ3v7GWCAfpzZAH0KSVRDZVgo3OFGfIcpaAnG/xb8vG78+qr07UtO6jVWljUCYus1ZblOzwj1Dsk3LTizQD/sql+pmFw3oHG6xDX9GnS6yy36dHFlv1226D9zPNcN8878qseT2xF+vD7j8rx4Izz9R9WJSTrz6c4I3BBRwZaCyqVJHcgvbYl+e945zDDMjxcPT8UjMGUxqHDPv6nIilLZLA5pis684dGz3gUNrhR3ruyMEJLPpDXjDld6dH6t9YLM7x3MW5rYDv2zrBHwiNer0hFoJWvNiDOXp7a+MesSJp9fs/Niem58uhc0GZajQ9adeHh73fgJoSaxWKSUup7LaEQ+r6XI39MYh8r/upT6qym1yCnZPx1rES6s69OsSG19c/bFrbX6teU57DEi0YGio/h8uSILo4b+MVoVCIz3N8fEa6y1fZpfZ9f8duqXWA/9DtPUEQ3fNe7t/xZsMami1TaNzMnSI8Dl/OFU5qpJjedLSi+UHHxtxpXfV2a2mpjD7rfJ/p5/4ezTh04+WT4xzHzOGAYNtP5o7/SYHgyebe0ODLNQ00uLWbUuu+ZcSenppw5hQh9ti2QF/qgf0Pzj4sStBZWVT5YdXX5YKXVi+FmZSIQ5gcyXsqtx4FkfLDhjdUpHsVbA5JAaLApfLwD2NMUeaI45uaIczTn33VJMsg+rE4UiX7O9T0eyd9UuGCA0XKiPC6/16qpKSnGr3YUnwhRjB5YVhog5ccaWH+57edo16OTUU4fQsSdWlO9edvxUZ0TTQAg680JJaV50Dz7xOHQ1u9KzOGy4mtxnk11YeRB9dWT5YYSOB1uihVLfYRLyg5NglIdxSBmhtMl9QtiaPk3DYMiihE54MnjBRfpOhApXe3VCKTYY4crhgVdJnbFqPxPOF8Ra0aph9w+/KJyMwrmuMEysaJUNC4XdJU7SWq50s0f7ZXRrBcx2GWIPwewbQU1oY358V5LWjGR8iLU4pe1IWyTkhOQtmY1bne8Ky481jveIEJ0TiDwSNZZZcd0wDE4KXl8ucWN5wVqnkTtxB1aJQ59NXtYaXZjcATuRTA8bRCccaokW4sPbGKZvkWCUR4rOhGDd5BOYWp2SIYfEazEmB46mwbsU+yFUQzzzzIG84r0zcVR0RDwSybZDfgnE2giVDY6/3udtD2J9KEHq0ZWATuFAHIWIi6UDRrgVS9wWiIJ+eiQ7c8uiZXtmoeEdlq/2cn5xuMVYImC8kIS6QqTOVrPK4vxaZnwrBKM8JkcMYO97qTuUpUcIlTtCFQ7vmjKE+eeUwIuz9DcMthnTYnr3Fh4/tuKwcKxMa2Zl/gjEWlSYMq6/vDUKvplleVBIXPCy2Fp4d+TYdifrzGqfgHNM1FLn+BCrwarE01nWLbKjIR4x4fmnS9HknUtOxo71/hBeAMuCsOMC0KfZKYUNsETIuYcIRnlkR/Y9kdL2syPZiL8ReyA8aDOrsCFJCzOlhZq21iZgpF1u8Z6mOHimSeED7DJ/SMTD3qvFpMY88/uuyRcEEgiBuq3DL4uuD6qxjgn5k8IHO8zK/16PFV7d4G4INoQiL3Kpu8OqxFxHnYmhY1sLGWCXjP3x7yqysDigpbhnbb8Gc2tJYsfuprhLPcM+As7is3r93Hij735sTLD+FCa3l7ZEYcON5mBLfbx9nFDEa+lNIJIUTtCKZpMKeyohifXB5JAZPJcLfSKgkzsKEg2bqxNgNpKXe0L3NsU+pjd4V8J7iGCUB9zPX2dden5S4/Ol0yL/vUz7XlHG5oJj7ZFauQMb3MOtkboNRap3n3jzfBqqCSE1jwiF7dm06y+U5yjfLd5Sm8ByRyU/zojxTv1ocdjGorcup+o1zN+nhpr+OefCH09Pit+0FKX6D5ZiMyAUeVkxofVYW2T4xsfXlOVg7xSItTNie3YuPYlp+tDmArQ0ZlPhL44+gmm3UG9Yk9mQv22+4p3ijI8XYRP8g4eus2tukblxxrfmnv+sTr+6LNfhksD7CPm8lt7EgvFdPUOKKVsXpm0u2N8cg2VNyE/SmYtS2pbsnq3dUHSig0lOAKbmRPXBbBg/d/u8n2TVozms7J4iqH8GDj6p1zbsoUPldrheIRMjis2fSyQOV9ix6xUy7yxYGfrtcuwdQ3y8tV+TRiFwa7Hm4IBrgPdlWZ6NNeJ4mOFrye2Bfcja8pzCpI7ve8Q2SktvRKgG94TljmUFgNAiBJC3dNVdIPAXu/Qrifc/iEvNdplea4GedzXEra9K/3Dh6YzwQVb84EHyIL4CmxkEbGWtUXaXZE6ccf2My4joWNkDCcmDILjQb+wSxB2A5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMGF5EEQXEgeBMFl7O9cnV2Xxc4I4r4g943L7GwsaPUgCC5jrx4E8cBCqwdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcCF5EAQXkgdBcBCJ/g+JpAip6TfCDgAAAABJRU5ErkJggg=="},66179:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS04-f0a5f08295ac98ac10216dda2c6ac467.png"},48602:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS05-ef5cc7abd1f5093685ce82cb5794a2aa.png"},78769:(e,n,t)=>{t.d(n,{A:()=>i});const i=t.p+"assets/images/CasperAWS06-fa837b0e61647fe37340261a3ae8fde3.png"},64552:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAVMAAAArCAIAAABKL/w7AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAC3hJREFUeF7tnV9IW1kex2tq/f+n1dbqVOiTT/pSaFkYH+ZhfWj70AWRUp1i7SozVtBm65QGsVhlm+K4EkJrBmmV8aE+uJXCECglOIuEHQTJS9xuW3TdBpnS6A4GsTQEIfs75/xyc++5N7fJNXE0OR++DPeef/d47/ne8zvndsihkEAgyDyE8wWCTEQ4XyDIRITzBYJMRDhfIMhEhPMFgkxEOF8gyESE8wWCTETP+a65+T/f+EvT1x37RNAZ6BJ2TsV+6+2Blv6t3nn1ODxZFB4/JLTfNVkEDwsfmxI958PjX/7Pf8P7BugMdAk7p2K/9fZAo3+rhe0PkiaL8LEp0XM+vPtxIOwboEvYORX7sLcHGp1bzY8tof0tfGxKhPMF2gjnp43wsSkRzhdoI5yfNsLHpkQ4X6CNcH7aCB+bkhQ6f339fzOzPw38dQTauWG+A3o0Pvmvf79huZBooH2d4bjL3go4dG41N7CE9rnwsSlJlfPB81BdU/AugALsmBWOH6iCnVNhoDWBDjq3mhtYQvtc+NiUpMT5bJ4Hgf/ZJA/zPwsBWDrM/+yAlY8fqIKdU2GgteSz5VvyvPbv4NmBRudWcwProCs4kuO25HlHsrj0PZZ/MG/RauISkyJ8bEqS73xmb/C2FNjLAf9LtjfQPlTBzqkw0JoWIc9Ub9et3q6phRCmxE/A/T35o/pevseEg4zOreYGljEFh/OfNpU31p8kaiib6E/JoI9H/u4TFVWnr3cf5tL3VIMlf6w6XVFVusilJ0P42JQk2flgbKgF0rQ9y5ILM+IGqmDnVBhoTYOtn63YN/vCJ0yLjecJlBxw+vE0vLn04737joUPeLo3SBGWWo/GJ7FQ4kB1vLMquIFlQL7esotkoINOXayvPJs84zEb2/r5dB3tC+ePZTubyi2dOUEuPRnCx6Ykyc6HoQa1YNrHcyVsOMqFGXEDVbBzKgy0pmZzfgja6Ru6C/+1ugOYKvEpsLb8em3rI55+eH4b/oq+mdWtwPYnGiJ8CmxvBULyaD+0sfpqwfNqZVMeQpBitBGau/ROdqGd0OY7r8fjXV2PXOVzyGMoTpCFhRIHquOdVcENrIRly7fUgOcrLeZsfqCPmQJ2E03MihwQBYchIM99a1ME5EG7yTeYx6UvXiEvFOt3UjtUY6a3/XnuwezgD5EUmTjnQ7NQNzCGuUHbkUVYCwxHLvFQkRv+gfQzYOdXCqSRh3CQFbify18XqoySNpXpinYi1enl2MEuhI9NSUqc/4/5f+J5stEZjgZ6qyIw9wAMY19Yc/aBc77/eRvTwZAbC+O9zRFHNU95w0sOdoya9ECppUly/GSJ1Qn73X/riJbpGXHjKoAWs4w8uis12DHlJW+Gj54nZkwBxblqgPDq257bUi25NCOvOIHqeGdVcAMrUQV6y8hsf6EgoMqiJqy2dhWaa8HAJ2ZHYOjn2r6sJuWJqhuv5jI/e1tPRRJpentOePzwbIOUAqLVIb7oKYeYAhNry53D0csxyZ3v6z5eV3W67nyhj2RlOy9Er3L2QgEkBi1HoUBFUx7rBqvb0pkttUaVa4My5ypayF9Bda7MRTsTHi0wk7deRLVlLhtNHym8DqcNhX6pekPx7NWT5FotubKWjQgfm5IkO5/NPxDz43my0RmOBnrLE3h5DwxDDL/y7BY4Z2guMhn7X5IooLnv8dyyb/vX1+4378OBFc/zB5DYdMsx51nw0Hlb4fxfZ25CbtvQs+UN//JMXxtk3X2xTnJYsZuT7tX1wJrbfo0UewyVNl0k4rjn8kHgsL2+svoh3q0GaetUrliRV5xAC3hnVXADK1F5rxInN37DuYWIGamittLcVOJoLXaPZrkvQ+EKx4ApPG5yX6mK+rm/wDtMp9/R/AHwUk2pdzzLP1BgrSeOMndALJDjh5nZWtQCTr5U4IfZdbgI3FWnMpLk/GB/KVmDnCtdpNOsr7MC3imWHvpG6CSvJLqIyHGcgUscc5Np3+S6BMfYJZmodatOTAweDtizXZcrof26y/RlYYfg5YifTO8mbwe0f7qTtq/h/Krq+q/KrK0l1p4jysYTFj42Jb+b89noxJO40RmOBlrjYPZmQf7a8144vjfPrL/xYgh62zO1TM8k2LQvW+fLnc9sfG36Nc0JL02RrD7XBjmWvyDWaXzxtQPOQot2iAKazQ+mf1nZTPADARfz7ybOZ0AjeGdVcAMrUS22EHNqrqvl0y9Vjg1c/YejsxAbW/KcV05CbnQNj5F2Np3q2d4YTvtSGX/PcTg1t5PqbkuxOequqPCiV0o7yRvk+CwGBYed56Gp8gl6aXdHudQx9kYgl7DnW6BBjeCFWTeyXTdMXU3eTViALSiCllKpTS3nJ223Dx+bkiQ7n+02fTbIhOUAFDOw/6QzHA30VonvpzvEM81ddG+/6wYcR1z9/sUAZOGMHUXX+ew9IkXs8tNYzodwf/Wl/WY7yW1qvzv9Jt6lPsDF/LuJ8xnQCN5ZFdzASlS+b4iBK65oBLEq5zMPyFXlGCRZvt5jjfKwOZbzWRAh16V8zqisTF0NiUTq2cxMxK0diCy99AMEiyNacoN3jkUTFVJa9yF9QbDThzkTDfJ1Sro4n4Wdn7V0nMXU6AxHA71VwILz9h5ie6pr0ficzfkRr0roOn/bTdYCzXT9D7AsFlDEdj5lJ+T3OEhnhpybmBQXUsy/yzifAe3gnVXBDayExb5gRWfXqLTn/DMl0myJGssbgBbqi9+SHTJm0RjOZ3O+We+TIV60K3f2PJi/urObLUNwzneydbhCJucF0itHS3VFzVEa9nNSWtda1Eh6W+SLvPXwZdGfRnO+/lc9BmR9tkwsoBZ2TgVkYSFDsPC+6/kKnkf8edPpg+NN9wOyG9c9ND2/4PG8fOYmieG1mS5IbLM8mV+YWyIpCksHfrbCu4PmeuYf3ybHD9jngljO3/Q8f/HLwtK7jbWlH0ligs4HIMhn/0Ry90AP8c6q4AZW4oLlMd20q/mik6znSxxN5Y1tOZClcv4hbxsskqsbG4tcNOp2dRcu2iNh9pmj7lGTf7DQQhbezCdZ7ibi/It/KnJ9l+eFkuw7Qu0Jh5kF/AVPe/n9hehFH+bazkH1Sls/2WMP9JbVVZ0+21DiZAG/uchlxSq4zyet3nkx61aa2wvgiravyB/LdgG9bVXkWp1HYJHibiHr/DRxPsAieRiCmsaWbG9sXtIZjsZ6i+ysTJMtPcVKPrRgJ129M7NGzj6+/Xt0K/7atJcWCUgb/mS3n7M0TPtvnt5moTtIFr3HdP48fb9g+aEXe/vvAjigD3hnVXADy5BMi63H66PhenV9DOeHx7NdjXSLm6m23DUKiVneVkys+/KYJTrnHwrfL7qOO+rHnaTkoeBgcSQFhBeSS3FRGslH4pEsb/uJ6HeBmi8cA5FaY3lW0nlceqjErFtxHQN7eHPl048F4PAC+tkCdOp6YxnEAunjfJj22bc9ENib+R8S4UAKRw3PS1AXO6cCsrBQ6tgJ8Z/rgZ0Qn6IgFNqKfL2PB3qJBMqnDJ1bzQ2s3Qj3urQ+sytEv/Pzn83Jp3X+QzpqTOsDezwXUkv7i/2RiXqtZQhKZl3oJL8coA1qrBFSJXxsSpLvfAB8Lplcrd2sQqE6dk4FZGEhQTLQudXcwMowZbtaS6wXyIc61Wd8SUmetHcpfGxKUuJ8Bpv82W4/W3+C5yERsw0hnL9nCOfHEN10lAfwGsqZIP8/QnGMiGCvhY9NSQqdnwqE8/cM4fy0ET42JcL5Am2E89NG+NiUCOcLtBHOTxvhY1MinC/QRjg/bYSPTYme88UvbWQs4pc20kcGfmlD/LpWxkr/Votf1zowMvbrWgKBIF0RzhcIMhHhfIEgExHOFwgyEeF8gSATEc4XCDIR4XyB4Pdh/bff8GjvCYX+DxMofqYM+5EQAAAAAElFTkSuQmCC"},46815:(e,n,t)=>{t.d(n,{A:()=>i});const i="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIkAAAA6CAIAAAALGO1FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAMmSURBVHhe7ZxRSFNRGMev1+6cF2pr2NRYoRU+pEhgWSTGQERTxpAg7cGgp7AeevTRx/BpTyFEMLUgsdIksk3FXpIEg8okJSqFzBRUrgruzMtm5+4ehYZL9qD8h9+Py/adb2eXc/ntfDuHXZa2ubkpEZDI4pnAg9zgQm5wITe4kBtcyA0u5AaXBPubF2kiIPaBaztvMWne4EJucCE3uJAbXMgNLuQGF3KDC7nBhdzgQm5wITe4kBtcyA0uB9eNtpT9dk5looUIjhtHW1dl87cM0dp7piYvVY1la6KFCI4bWVtVpzfSRYtIjZqmK5rmGF1StYhI7I6uzCw4ZnTREkRljSkai79kFlanFmxJnHy/QHfz6b3H8qSiPlDS0l/hbK/0zRkDnp8ot/Tlz5s9JLWrz3t9QuWRkX9e4huqLO5y3x4oK/B7WqYVsxObLfR2eJxPK+qf1VreZZlJKZTt660p7Sm7F7jibHf7l0UaBHQ350pfb9wKBBsGg42BvpNq80+HeCERy9bci4Pjjbz/QLdLvv/bZiRDrubgKdv5YeNUja82Li/GunLW6672j9/gnUdaD9nezBmCcYCvaelR/sCYwqL60Uwz9X/W8g6bQTjniBlI2qyrLfLrTuGaaG9fdOZanjUWyCzXHguQQHdj1CK/p7TX7e2uvvlVJJOFhXlli+J/DuMAH2+WL3gmrzxglJ2GQOdZkU0Wu7ouSUoobmkAD5gbviQzllLmERvb9vIpos6sitAY9aJjMmyEbNXxcbdNijV3oSn9uP+LTTMKpMT01JhBWKN8OeZ2dtZsHUWj0mLdhZWe4erixzUF3UV/1BWzW07+dJPsqurwWh566j9Yc46Z6cRkzrbWfmef3c5H/C3e4qETW2s8aFLh3kE+maIRe0bsM78N36zwjaqi25PZrfIvHibrdrGuhiGF7x3kAuLEcOSo3ZqcGI41A09MYlKj8h5MyA0u5AYXcoMLucGF3OBCbnAhN7iQG1zIDS7kBhdygwu5wWXn3whG7p4WEbH3lD34IaJ/oXmDC/3vIC40b3AhN7iQG1zIDS7kBhdygwu5QUWS/gKbZ/EkaoCEzgAAAABJRU5ErkJggg=="},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>a});var i=t(96540);const s={},o=i.createContext(s);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.43025aa7.js b/assets/js/a6aa9e1f.43025aa7.js deleted file mode 100644 index 7ac206bdf..000000000 --- a/assets/js/a6aa9e1f.43025aa7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7643],{35124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>j});a(96540);var s=a(34164),r=a(44586),n=a(45500),i=a(17559),l=a(28027),o=a(47713),c=a(41463),d=a(33892),m=a(5260),g=a(44096),u=a(74848);function h(e){const t=(0,g.kJ)(e);return(0,u.jsx)(m.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,r.A)(),{blogDescription:s,blogTitle:i,permalink:l}=t,o="/"===l?a:i;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(n.be,{title:o,description:s}),(0,u.jsx)(c.A,{tag:"blog_posts_list"})]})}function x(e){const{metadata:t,items:a,sidebar:s}=e;return(0,u.jsxs)(l.A,{sidebar:s,children:[(0,u.jsx)(d.A,{items:a}),(0,u.jsx)(o.A,{metadata:t})]})}function j(e){return(0,u.jsxs)(n.e3,{className:(0,s.A)(i.G.wrapper.blogPages,i.G.page.blogListPage),children:[(0,u.jsx)(p,{...e}),(0,u.jsx)(h,{...e}),(0,u.jsx)(x,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(21312),r=a(39022),n=a(74848);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return(0,n.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,n.jsx)(r.A,{permalink:a,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,n.jsx)(r.A,{permalink:i,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,a)=>{a.d(t,{A:()=>C});a(96540);var s=a(34164),r=a(44096),n=a(74848);function i(e){let{children:t,className:a}=e;return(0,n.jsx)("article",{className:a,children:t})}var l=a(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:i}=(0,r.e7)(),{permalink:c,title:d}=a,m=i?"h1":"h2";return(0,n.jsx)(m,{className:(0,s.A)(o.title,t),children:i?d:(0,n.jsx)(l.A,{to:c,children:d})})}var d=a(21312),m=a(53465),g=a(36266);const u={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,m.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,n.jsx)(n.Fragment,{children:a(t)})}function p(e){let{date:t,formattedDate:a}=e;return(0,n.jsx)("time",{dateTime:t,children:a})}function x(){return(0,n.jsx)(n.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:a}=(0,r.e7)(),{date:i,readingTime:l}=a,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,n.jsxs)("div",{className:(0,s.A)(u.container,"margin-vert--md",t),children:[(0,n.jsx)(p,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(x,{}),(0,n.jsx)(h,{readingTime:l})]})]});var c}var A=a(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f(e){let{className:t}=e;const{metadata:{authors:a},assets:i}=(0,r.e7)();if(0===a.length)return null;const l=a.every((e=>{let{name:t}=e;return!t})),o=1===a.length;return(0,n.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:a.map(((e,t)=>(0,n.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,n.jsx)(A.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,n.jsxs)("header",{children:[(0,n.jsx)(c,{}),(0,n.jsx)(j,{}),(0,n.jsx)(f,{})]})}var N=a(70440),T=a(88509);function w(e){let{children:t,className:a}=e;const{isBlogPostPage:i}=(0,r.e7)();return(0,n.jsx)("div",{id:i?N.LU:void 0,className:(0,s.A)("markdown",a),children:(0,n.jsx)(T.A,{children:t})})}var y=a(17559),k=a(4336),P=a(62053);function U(){return(0,n.jsx)("b",{children:(0,n.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function _(e){const{blogPostTitle:t,...a}=e;return(0,n.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,n.jsx)(U,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,r.e7)(),{tags:a,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,g=a.length>0;if(!(g||m||l))return null;if(t){const e=!!(l||d||c);return(0,n.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,n.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,n.jsx)("div",{className:"col",children:(0,n.jsx)(P.A,{tags:a})})}),e&&(0,n.jsx)(k.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,n.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,n.jsx)("div",{className:(0,s.A)("col",{"col--9":m}),children:(0,n.jsx)(P.A,{tags:a})}),m&&(0,n.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,n.jsx)(_,{blogPostTitle:i,to:e.permalink})})]})}function C(e){let{children:t,className:a}=e;const l=function(){const{isBlogPostPage:e}=(0,r.e7)();return e?void 0:"margin-bottom--xl"}();return(0,n.jsxs)(i,{className:(0,s.A)(l,a),children:[(0,n.jsx)(v,{}),(0,n.jsx)(w,{children:t}),(0,n.jsx)(R,{})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(44096),r=a(82907),n=a(74848);function i(e){let{items:t,component:a=r.A}=e;return(0,n.jsx)(n.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,n.jsx)(s.in,{content:t,children:(0,n.jsx)(a,{children:(0,n.jsx)(t,{})})},t.metadata.permalink)}))})}}}]); \ No newline at end of file diff --git a/assets/js/a6aa9e1f.4977cbdf.js b/assets/js/a6aa9e1f.4977cbdf.js new file mode 100644 index 000000000..eeaa35f1b --- /dev/null +++ b/assets/js/a6aa9e1f.4977cbdf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37643],{35124:(e,t,a)=>{a.r(t),a.d(t,{default:()=>j});a(96540);var s=a(34164),r=a(44586),n=a(45500),i=a(17559),l=a(28027),o=a(47713),c=a(41463),d=a(33892),m=a(5260),g=a(44096),u=a(74848);function h(e){const t=(0,g.kJ)(e);return(0,u.jsx)(m.A,{children:(0,u.jsx)("script",{type:"application/ld+json",children:JSON.stringify(t)})})}function p(e){const{metadata:t}=e,{siteConfig:{title:a}}=(0,r.A)(),{blogDescription:s,blogTitle:i,permalink:l}=t,o="/"===l?a:i;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(n.be,{title:o,description:s}),(0,u.jsx)(c.A,{tag:"blog_posts_list"})]})}function x(e){const{metadata:t,items:a,sidebar:s}=e;return(0,u.jsxs)(l.A,{sidebar:s,children:[(0,u.jsx)(d.A,{items:a}),(0,u.jsx)(o.A,{metadata:t})]})}function j(e){return(0,u.jsxs)(n.e3,{className:(0,s.A)(i.G.wrapper.blogPages,i.G.page.blogListPage),children:[(0,u.jsx)(p,{...e}),(0,u.jsx)(h,{...e}),(0,u.jsx)(x,{...e})]})}},47713:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(21312),r=a(39022),n=a(74848);function i(e){const{metadata:t}=e,{previousPage:a,nextPage:i}=t;return(0,n.jsxs)("nav",{className:"pagination-nav","aria-label":(0,s.T)({id:"theme.blog.paginator.navAriaLabel",message:"Blog list page navigation",description:"The ARIA label for the blog pagination"}),children:[a&&(0,n.jsx)(r.A,{permalink:a,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.newerEntries",description:"The label used to navigate to the newer blog posts page (previous page)",children:"Newer entries"})}),i&&(0,n.jsx)(r.A,{permalink:i,title:(0,n.jsx)(s.A,{id:"theme.blog.paginator.olderEntries",description:"The label used to navigate to the older blog posts page (next page)",children:"Older entries"}),isNext:!0})]})}},82907:(e,t,a)=>{a.d(t,{A:()=>C});a(96540);var s=a(34164),r=a(44096),n=a(74848);function i(e){let{children:t,className:a}=e;return(0,n.jsx)("article",{className:a,children:t})}var l=a(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:a,isBlogPostPage:i}=(0,r.e7)(),{permalink:c,title:d}=a,m=i?"h1":"h2";return(0,n.jsx)(m,{className:(0,s.A)(o.title,t),children:i?d:(0,n.jsx)(l.A,{to:c,children:d})})}var d=a(21312),m=a(53465),g=a(36266);const u={container:"container_mt6G"};function h(e){let{readingTime:t}=e;const a=function(){const{selectMessage:e}=(0,m.W)();return t=>{const a=Math.ceil(t);return e(a,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:a}))}}();return(0,n.jsx)(n.Fragment,{children:a(t)})}function p(e){let{date:t,formattedDate:a}=e;return(0,n.jsx)("time",{dateTime:t,children:a})}function x(){return(0,n.jsx)(n.Fragment,{children:" \xb7 "})}function j(e){let{className:t}=e;const{metadata:a}=(0,r.e7)(),{date:i,readingTime:l}=a,o=(0,g.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,n.jsxs)("div",{className:(0,s.A)(u.container,"margin-vert--md",t),children:[(0,n.jsx)(p,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(x,{}),(0,n.jsx)(h,{readingTime:l})]})]});var c}var A=a(56913);const b={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function f(e){let{className:t}=e;const{metadata:{authors:a},assets:i}=(0,r.e7)();if(0===a.length)return null;const l=a.every((e=>{let{name:t}=e;return!t})),o=1===a.length;return(0,n.jsx)("div",{className:(0,s.A)("margin-top--md margin-bottom--sm",l?b.imageOnlyAuthorRow:"row",t),children:a.map(((e,t)=>(0,n.jsx)("div",{className:(0,s.A)(!l&&(o?"col col--12":"col col--6"),l?b.imageOnlyAuthorCol:b.authorCol),children:(0,n.jsx)(A.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function v(){return(0,n.jsxs)("header",{children:[(0,n.jsx)(c,{}),(0,n.jsx)(j,{}),(0,n.jsx)(f,{})]})}var N=a(70440),T=a(88509);function w(e){let{children:t,className:a}=e;const{isBlogPostPage:i}=(0,r.e7)();return(0,n.jsx)("div",{id:i?N.LU:void 0,className:(0,s.A)("markdown",a),children:(0,n.jsx)(T.A,{children:t})})}var y=a(17559),k=a(4336),P=a(62053);function U(){return(0,n.jsx)("b",{children:(0,n.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function _(e){const{blogPostTitle:t,...a}=e;return(0,n.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...a,children:(0,n.jsx)(U,{})})}function R(){const{metadata:e,isBlogPostPage:t}=(0,r.e7)(),{tags:a,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,g=a.length>0;if(!(g||m||l))return null;if(t){const e=!!(l||d||c);return(0,n.jsxs)("footer",{className:"docusaurus-mt-lg",children:[g&&(0,n.jsx)("div",{className:(0,s.A)("row","margin-top--sm",y.G.blog.blogFooterEditMetaRow),children:(0,n.jsx)("div",{className:"col",children:(0,n.jsx)(P.A,{tags:a})})}),e&&(0,n.jsx)(k.A,{className:(0,s.A)("margin-top--sm",y.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,n.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[g&&(0,n.jsx)("div",{className:(0,s.A)("col",{"col--9":m}),children:(0,n.jsx)(P.A,{tags:a})}),m&&(0,n.jsx)("div",{className:(0,s.A)("col text--right",{"col--3":g}),children:(0,n.jsx)(_,{blogPostTitle:i,to:e.permalink})})]})}function C(e){let{children:t,className:a}=e;const l=function(){const{isBlogPostPage:e}=(0,r.e7)();return e?void 0:"margin-bottom--xl"}();return(0,n.jsxs)(i,{className:(0,s.A)(l,a),children:[(0,n.jsx)(v,{}),(0,n.jsx)(w,{children:t}),(0,n.jsx)(R,{})]})}},33892:(e,t,a)=>{a.d(t,{A:()=>i});a(96540);var s=a(44096),r=a(82907),n=a(74848);function i(e){let{items:t,component:a=r.A}=e;return(0,n.jsx)(n.Fragment,{children:t.map((e=>{let{content:t}=e;return(0,n.jsx)(s.in,{content:t,children:(0,n.jsx)(a,{children:(0,n.jsx)(t,{})})},t.metadata.permalink)}))})}}}]); \ No newline at end of file diff --git a/assets/js/a6c56441.56418c50.js b/assets/js/a6c56441.56418c50.js new file mode 100644 index 000000000..5ef2df905 --- /dev/null +++ b/assets/js/a6c56441.56418c50.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36337],{95250:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>u,contentTitle:()=>o,default:()=>d,frontMatter:()=>n,metadata:()=>a,toc:()=>c});var r=s(74848),i=s(28453);const n={title:"Introduction"},o="The Native Multi-Signature Feature",a={id:"resources/advanced/multi-sig/index",title:"Introduction",description:"In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/index.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/",permalink:"/2.0.0/resources/advanced/multi-sig/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Introduction"},sidebar:"tutorials",previous:{title:"Two-Party Multi-Sig",permalink:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig"},next:{title:"Multi-Sig Workflow",permalink:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow"}},u={},c=[];function l(e){const t={a:"a",h1:"h1",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"the-native-multi-signature-feature",children:"The Native Multi-Signature Feature"})}),"\n",(0,r.jsxs)(t.p,{children:["In this ",(0,r.jsx)(t.a,{href:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow",children:"tutorial"}),", you will use ",(0,r.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#accounts-permissions",children:"Casper's permissions model"})," to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/2.0.0/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," present use cases where Casper's multi-signature feature would be helpful."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>a});var r=s(96540);const i={},n=r.createContext(i);function o(e){const t=r.useContext(n);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),r.createElement(n.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6efe0e1.17fb2b9f.js b/assets/js/a6efe0e1.17fb2b9f.js deleted file mode 100644 index 9ea368b78..000000000 --- a/assets/js/a6efe0e1.17fb2b9f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4766],{62409:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"Using CSPR.live"},c="Using the CSPR.live block explorer",d={id:"users/csprlive/index",title:"Using CSPR.live",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/users/csprlive/index.md",sourceDirName:"users/csprlive",slug:"/users/csprlive/",permalink:"/users/csprlive/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Using CSPR.live"},sidebar:"users",previous:{title:"Funding Mainnet Accounts",permalink:"/users/funding-from-exchanges"},next:{title:"Testnet Funding",permalink:"/users/testnet-faucet"}},l={},o=[];function a(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-the-csprlive-block-explorer",children:"Using the CSPR.live block explorer"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,s.jsx)(n.td,{children:"Fund a Testnet account for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens"})}),(0,s.jsx)(n.td,{children:"Transfer tokens using the CSPR.live block explorer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating Tokens"})}),(0,s.jsx)(n.td,{children:"Delegate tokens to a validator"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,s.jsx)(n.td,{children:"Undelegate tokens from a validator"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>d});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a6efe0e1.f66fc475.js b/assets/js/a6efe0e1.f66fc475.js new file mode 100644 index 000000000..4411f15e0 --- /dev/null +++ b/assets/js/a6efe0e1.f66fc475.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[54766],{62409:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"Using CSPR.live"},c="Using the CSPR.live block explorer",d={id:"users/csprlive/index",title:"Using CSPR.live",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/users/csprlive/index.md",sourceDirName:"users/csprlive",slug:"/users/csprlive/",permalink:"/1.5.X/users/csprlive/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Using CSPR.live"},sidebar:"users",previous:{title:"Funding Mainnet Accounts",permalink:"/1.5.X/users/funding-from-exchanges"},next:{title:"Testnet Funding",permalink:"/1.5.X/users/testnet-faucet"}},l={},o=[];function a(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-the-csprlive-block-explorer",children:"Using the CSPR.live block explorer"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,s.jsx)(n.td,{children:"Fund a Testnet account for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/users/token-transfer",children:"Transferring Tokens"})}),(0,s.jsx)(n.td,{children:"Transfer tokens using the CSPR.live block explorer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/users/delegate-ui",children:"Delegating Tokens"})}),(0,s.jsx)(n.td,{children:"Delegate tokens to a validator"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,s.jsx)(n.td,{children:"Undelegate tokens from a validator"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>d});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a72bcf22.d7ffd90c.js b/assets/js/a72bcf22.d7ffd90c.js deleted file mode 100644 index a74d567d4..000000000 --- a/assets/js/a72bcf22.d7ffd90c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3828],{21980:e=>{e.exports=JSON.parse('{"tag":{"label":"setup","permalink":"/blog/tags/setup","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/setup","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/a72bcf22.e9c31f44.js b/assets/js/a72bcf22.e9c31f44.js new file mode 100644 index 000000000..1d058ae0c --- /dev/null +++ b/assets/js/a72bcf22.e9c31f44.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[13828],{21980:e=>{e.exports=JSON.parse('{"tag":{"label":"Set-up","permalink":"/blog/tags/setup","description":"Getting set up on Casper","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/setup","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.951f72a9.js b/assets/js/a7bd4aaa.951f72a9.js deleted file mode 100644 index fa69d7712..000000000 --- a/assets/js/a7bd4aaa.951f72a9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7098],{74532:(n,s,e)=>{e.r(s),e.d(s,{default:()=>d});e(96540);var r=e(45500),o=e(82565),c=e(23025),t=e(22831),i=e(41463),u=e(74848);function a(n){const{version:s}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(i.A,{version:s.version,tag:(0,o.k)(s.pluginId,s.version)}),(0,u.jsx)(r.be,{children:s.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:s,route:e}=n;return(0,u.jsx)(r.e3,{className:s.className,children:(0,u.jsx)(c.n,{version:s,children:(0,t.v)(e.routes)})})}function d(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a7bd4aaa.f6bd7d37.js b/assets/js/a7bd4aaa.f6bd7d37.js new file mode 100644 index 000000000..1a3eaf17f --- /dev/null +++ b/assets/js/a7bd4aaa.f6bd7d37.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67098],{74532:(n,s,e)=>{e.r(s),e.d(s,{default:()=>d});e(96540);var r=e(45500),o=e(82565),c=e(23025),t=e(22831),i=e(41463),u=e(74848);function a(n){const{version:s}=n;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(i.A,{version:s.version,tag:(0,o.k)(s.pluginId,s.version)}),(0,u.jsx)(r.be,{children:s.noIndex&&(0,u.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})]})}function l(n){const{version:s,route:e}=n;return(0,u.jsx)(r.e3,{className:s.className,children:(0,u.jsx)(c.n,{version:s,children:(0,t.v)(e.routes)})})}function d(n){return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(a,{...n}),(0,u.jsx)(l,{...n})]})}}}]); \ No newline at end of file diff --git a/assets/js/a7e0ea76.d1f0fa4d.js b/assets/js/a7e0ea76.d1f0fa4d.js new file mode 100644 index 000000000..94397aa2f --- /dev/null +++ b/assets/js/a7e0ea76.d1f0fa4d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[21421],{89780:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>o,frontMatter:()=>i,metadata:()=>c,toc:()=>h});var r=s(74848),t=s(28453);const i={},d="Users Overview",c={id:"users/index",title:"Users Overview",description:"General Topics",source:"@site/versioned_docs/version-2.0.0/users/index.md",sourceDirName:"users",slug:"/users/",permalink:"/2.0.0/users/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"users",next:{title:"Block Explorers",permalink:"/2.0.0/users/block-explorer"}},l={},h=[{value:"General Topics",id:"general-topics",level:2},{value:"Using CSPR.live",id:"using-csprlive",level:2},{value:"Using Ledger Devices",id:"using-ledger-devices",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"users-overview",children:"Users Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"general-topics",children:"General Topics"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/block-explorer",children:"Block Explorers"})}),(0,r.jsx)(n.td,{children:"A guide to understanding block explorers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/funding-from-exchanges",children:"Funding Mainnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding Mainnet accounts from an exchange"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/delegating",children:"Delegating Tokens"})}),(0,r.jsx)(n.td,{children:"Delegating tokens to a validator (a.k.a. staking with a validator)"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-csprlive",children:"Using CSPR.live"}),"\n",(0,r.jsxs)(n.p,{children:["Interact with the Casper blockchain using the ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding your Testnet account using the Faucet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/delegate-ui",children:"Delegating Tokens"})}),(0,r.jsxs)(n.td,{children:["Staking your Casper tokens with ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,r.jsx)(n.td,{children:"Un-staking your Casper tokens"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/token-transfer",children:"Transferring Tokens"})}),(0,r.jsxs)(n.td,{children:["Transferring your Casper tokens using ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-ledger-devices",children:"Using Ledger Devices"}),"\n",(0,r.jsx)(n.p,{children:"Interact with the Casper blockchain using a Ledger device."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/workflow/ledger-setup/",children:"Ledger Setup"})}),(0,r.jsx)(n.td,{children:"A guide to setting up your Ledger device"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,r.jsx)(n.td,{children:"Delegating tokens using your Ledger device"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a80f26d4.7206c3fd.js b/assets/js/a80f26d4.7206c3fd.js deleted file mode 100644 index 2e7829ab0..000000000 --- a/assets/js/a80f26d4.7206c3fd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2218],{54801:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>h});var o=s(74848),n=s(28453);const a={title:"Gas Cost"},i="Gas and Resources",r={id:"concepts/economics/gas-concepts",title:"Gas Cost",description:"What is gas?",source:"@site/versioned_docs/version-1.5.X/concepts/economics/gas-concepts.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/gas-concepts",permalink:"/concepts/economics/gas-concepts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Gas Cost"},sidebar:"concepts",previous:{title:"Runtime",permalink:"/runtime"},next:{title:"Staking Concepts",permalink:"/concepts/economics/concepts"}},c={},h=[{value:"What is gas?",id:"what-is-gas",level:2},{value:"How is gas cost determined?",id:"how-is-gas-cost-determined",level:2},{value:"Why do we need gas cost?",id:"why-do-we-need-gas-cost",level:2},{value:"Why do I see an \u2018Out of gas error\u2019?",id:"why-do-i-see-an-out-of-gas-error",level:2},{value:"How do I determine the gas cost for a transaction?",id:"how-do-i-determine-the-gas-cost-for-a-transaction",level:2},{value:"Why do I see a gas limit error?",id:"why-do-i-see-a-gas-limit-error",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"gas-and-resources",children:"Gas and Resources"})}),"\n",(0,o.jsx)(t.h2,{id:"what-is-gas",children:"What is gas?"}),"\n",(0,o.jsx)(t.p,{children:"Gas is a conceptual measure of resources utilized when executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide in order to execute a transaction."}),"\n",(0,o.jsx)(t.p,{children:"Gas fees are consumed on the network irrespective of whether your transaction was successful or not. Even when a transaction fails, you have to pay the transaction fee because your deploy consumed resources and space on the block as the validator attempted to execute it on your behalf."}),"\n",(0,o.jsx)(t.h2,{id:"how-is-gas-cost-determined",children:"How is gas cost determined?"}),"\n",(0,o.jsx)(t.p,{children:"The amount of gas required for a transaction is determined by how much code is executed on the blockchain. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. The gas charged for a transaction on the blockchain is paid to the network's validators."}),"\n",(0,o.jsx)(t.h2,{id:"why-do-we-need-gas-cost",children:"Why do we need gas cost?"}),"\n",(0,o.jsx)(t.p,{children:"Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Rate-limiting is used to ensure a secure and live network:\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting is used to control the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves in a similar fashion, because each block permits only a fixed amount of transactions (gas) to be included in the era."}),"\n",(0,o.jsx)(t.li,{children:"It explicitly quantifies the system load. The gas cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["Pricing leads to more meaningful transactions:\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each deploy."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"why-do-i-see-an-out-of-gas-error",children:"Why do I see an \u2018Out of gas error\u2019?"}),"\n",(0,o.jsx)(t.p,{children:"You might encounter an \u2018Out of gas error\u2019 when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized."}),"\n",(0,o.jsxs)(t.p,{children:["Here is an ",(0,o.jsx)(t.a,{href:"https://cspr.live/deploy/afeb43036c41e667af8bc34782c48a66cf4da3818defe9f761291fa515cc38b9",children:"example"})," of a transaction resulting in an \u2018Out of gas error\u2019 on the Mainnet."]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 1"}),": In the Deploys tab of an account on ",(0,o.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),", a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an 'Out of gas error'."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(59079).A+"",width:"2048",height:"1118"})}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 2"}),": Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(17530).A+"",width:"1698",height:"824"})}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 3"}),": Click the ",(0,o.jsx)(t.strong,{children:"Show raw data"})," button, to see more details about the deploy. Towards the end of the raw data, you can see the error message."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(60981).A+"",width:"1472",height:"424"})}),"\n",(0,o.jsx)(t.h2,{id:"how-do-i-determine-the-gas-cost-for-a-transaction",children:"How do I determine the gas cost for a transaction?"}),"\n",(0,o.jsxs)(t.p,{children:["Currently, we are hard at work to create tools to help you estimate gas costs. Meanwhile, we recommend using the NCTL tool on your local machine or the ",(0,o.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to ",(0,o.jsx)(t.a,{href:"/developers/cli/sending-deploys",children:"deploy your contracts"})," in a test environment. You can check a deploy status and roughly see how much it would actually cost when deployed. You can estimate the costs in this way and then add a small buffer if the network state has changed. Note that when estimating gas cost locally or on the Testnet, the blockchain specification needs to match the specification of the Mainnet, where you will need to pay for the transaction with actual Casper (CSPR) tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"why-do-i-see-a-gas-limit-error",children:"Why do I see a gas limit error?"}),"\n",(0,o.jsxs)(t.p,{children:["You may sometimes see an error such as ",(0,o.jsx)(t.em,{children:"\u2018payment: 2.5, cost: 2.5, Error::GasLimit\u2019"}),", This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error. Let\u2019s explore this error message a little further."]}),"\n",(0,o.jsx)(t.p,{children:"When a smart contract hits its gas limit (the payment amount), execution stops. If your limit is 2.5 CSPR, execution stops and that is the computation cost even if the smart contract did not run to completion. So, the error message tries to communicate to you that execution stopped at 2.5 CSPR. The computation resulted in an error because there were not enough funds to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution there and charged you that much, even though it was a failed transaction. The execution engine does not actually know how much it would have cost if allowed to run to completion, because it did not allow the contract to finish since the contract would have run over its gas limit."})]})}function l(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},17530:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-account-75086cfae6160dfca8cce66fc2b80f44.png"},59079:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-deploys-82cd87f7fc9013f4a7da13e4dd6123e3.png"},60981:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-raw-5b014abd0817fd1c15b225a083a68e3a.png"},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>r});var o=s(96540);const n={},a=o.createContext(n);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a80f26d4.8ef94877.js b/assets/js/a80f26d4.8ef94877.js new file mode 100644 index 000000000..c24852dda --- /dev/null +++ b/assets/js/a80f26d4.8ef94877.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92218],{54801:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>h});var o=s(74848),n=s(28453);const a={title:"Gas Cost"},i="Gas and Resources",r={id:"concepts/economics/gas-concepts",title:"Gas Cost",description:"What is gas?",source:"@site/versioned_docs/version-1.5.X/concepts/economics/gas-concepts.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/gas-concepts",permalink:"/1.5.X/concepts/economics/gas-concepts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Gas Cost"},sidebar:"concepts",previous:{title:"Runtime",permalink:"/1.5.X/runtime"},next:{title:"Staking Concepts",permalink:"/1.5.X/concepts/economics/concepts"}},c={},h=[{value:"What is gas?",id:"what-is-gas",level:2},{value:"How is gas cost determined?",id:"how-is-gas-cost-determined",level:2},{value:"Why do we need gas cost?",id:"why-do-we-need-gas-cost",level:2},{value:"Why do I see an \u2018Out of gas error\u2019?",id:"why-do-i-see-an-out-of-gas-error",level:2},{value:"How do I determine the gas cost for a transaction?",id:"how-do-i-determine-the-gas-cost-for-a-transaction",level:2},{value:"Why do I see a gas limit error?",id:"why-do-i-see-a-gas-limit-error",level:2}];function d(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,n.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"gas-and-resources",children:"Gas and Resources"})}),"\n",(0,o.jsx)(t.h2,{id:"what-is-gas",children:"What is gas?"}),"\n",(0,o.jsx)(t.p,{children:"Gas is a conceptual measure of resources utilized when executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide in order to execute a transaction."}),"\n",(0,o.jsx)(t.p,{children:"Gas fees are consumed on the network irrespective of whether your transaction was successful or not. Even when a transaction fails, you have to pay the transaction fee because your deploy consumed resources and space on the block as the validator attempted to execute it on your behalf."}),"\n",(0,o.jsx)(t.h2,{id:"how-is-gas-cost-determined",children:"How is gas cost determined?"}),"\n",(0,o.jsx)(t.p,{children:"The amount of gas required for a transaction is determined by how much code is executed on the blockchain. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. The gas charged for a transaction on the blockchain is paid to the network's validators."}),"\n",(0,o.jsx)(t.h2,{id:"why-do-we-need-gas-cost",children:"Why do we need gas cost?"}),"\n",(0,o.jsx)(t.p,{children:"Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:"}),"\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsxs)(t.li,{children:["Rate-limiting is used to ensure a secure and live network:\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting is used to control the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves in a similar fashion, because each block permits only a fixed amount of transactions (gas) to be included in the era."}),"\n",(0,o.jsx)(t.li,{children:"It explicitly quantifies the system load. The gas cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators."}),"\n"]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["Pricing leads to more meaningful transactions:\n",(0,o.jsxs)(t.ul,{children:["\n",(0,o.jsx)(t.li,{children:"Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each deploy."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.h2,{id:"why-do-i-see-an-out-of-gas-error",children:"Why do I see an \u2018Out of gas error\u2019?"}),"\n",(0,o.jsx)(t.p,{children:"You might encounter an \u2018Out of gas error\u2019 when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized."}),"\n",(0,o.jsxs)(t.p,{children:["Here is an ",(0,o.jsx)(t.a,{href:"https://cspr.live/deploy/afeb43036c41e667af8bc34782c48a66cf4da3818defe9f761291fa515cc38b9",children:"example"})," of a transaction resulting in an \u2018Out of gas error\u2019 on the Mainnet."]}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 1"}),": In the Deploys tab of an account on ",(0,o.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),", a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an 'Out of gas error'."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(77813).A+"",width:"2048",height:"1118"})}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 2"}),": Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(41296).A+"",width:"1698",height:"824"})}),"\n",(0,o.jsxs)(t.p,{children:[(0,o.jsx)(t.strong,{children:"Figure 3"}),": Click the ",(0,o.jsx)(t.strong,{children:"Show raw data"})," button, to see more details about the deploy. Towards the end of the raw data, you can see the error message."]}),"\n",(0,o.jsx)(t.p,{children:(0,o.jsx)(t.img,{src:s(79459).A+"",width:"1472",height:"424"})}),"\n",(0,o.jsx)(t.h2,{id:"how-do-i-determine-the-gas-cost-for-a-transaction",children:"How do I determine the gas cost for a transaction?"}),"\n",(0,o.jsxs)(t.p,{children:["Currently, we are hard at work to create tools to help you estimate gas costs. Meanwhile, we recommend using the NCTL tool on your local machine or the ",(0,o.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"Testnet"})," to ",(0,o.jsx)(t.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"deploy your contracts"})," in a test environment. You can check a deploy status and roughly see how much it would actually cost when deployed. You can estimate the costs in this way and then add a small buffer if the network state has changed. Note that when estimating gas cost locally or on the Testnet, the blockchain specification needs to match the specification of the Mainnet, where you will need to pay for the transaction with actual Casper (CSPR) tokens."]}),"\n",(0,o.jsx)(t.h2,{id:"why-do-i-see-a-gas-limit-error",children:"Why do I see a gas limit error?"}),"\n",(0,o.jsxs)(t.p,{children:["You may sometimes see an error such as ",(0,o.jsx)(t.em,{children:"\u2018payment: 2.5, cost: 2.5, Error::GasLimit\u2019"}),", This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error. Let\u2019s explore this error message a little further."]}),"\n",(0,o.jsx)(t.p,{children:"When a smart contract hits its gas limit (the payment amount), execution stops. If your limit is 2.5 CSPR, execution stops and that is the computation cost even if the smart contract did not run to completion. So, the error message tries to communicate to you that execution stopped at 2.5 CSPR. The computation resulted in an error because there were not enough funds to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution there and charged you that much, even though it was a failed transaction. The execution engine does not actually know how much it would have cost if allowed to run to completion, because it did not allow the contract to finish since the contract would have run over its gas limit."})]})}function l(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},41296:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-account-75086cfae6160dfca8cce66fc2b80f44.png"},77813:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-deploys-82cd87f7fc9013f4a7da13e4dd6123e3.png"},79459:(e,t,s)=>{s.d(t,{A:()=>o});const o=s.p+"assets/images/error-raw-5b014abd0817fd1c15b225a083a68e3a.png"},28453:(e,t,s)=>{s.d(t,{R:()=>i,x:()=>r});var o=s(96540);const n={},a=o.createContext(n);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a811e42c.6d7c6526.js b/assets/js/a811e42c.6d7c6526.js new file mode 100644 index 000000000..4552ec7e0 --- /dev/null +++ b/assets/js/a811e42c.6d7c6526.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[41408],{97681:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var s=n(74848),r=n(28453);const c={title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},a="Testing Framework for CEP-18",i={id:"resources/tokens/cep18/tests",title:"Testing Guide",description:"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.",source:"@site/docs/resources/tokens/cep18/tests.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/tests",permalink:"/resources/tokens/cep18/tests",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},sidebar:"resources",previous:{title:"CEP-18 Transfers",permalink:"/resources/tokens/cep18/transfer"},next:{title:"Introduction",permalink:"/resources/tokens/cep78/introduction"}},o={},l=[{value:"Configuring the Test Package",id:"configuring-the-test-package",level:2},{value:"Testing Logic",id:"testing-logic",level:2},{value:"Setting up the Testing Context",id:"setting-up-the-testing-context",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:3},{value:"Creating Helper Functions",id:"creating-helper-functions",level:3},{value:"Creating Unit Tests",id:"creating-unit-tests",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function _(e){const t={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-framework-for-cep-18",children:"Testing Framework for CEP-18"})}),"\n",(0,s.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,s.jsxs)(t.p,{children:["The following section reviews the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/tests",children:"GitHub testing folder"}),", which creates a testing framework for the Casper ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Fungible Token"})," project. You can find more details about testing Casper contracts ",(0,s.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a complete test expecting a failed transfer:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[should_panic(expected = "ApiError::User(65534) [131070]")]\n#[test]\nfn should_not_transfer_with_insufficient_balance() {\n let mut fixture = TestFixture::install_contract();\n\n let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();\n assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);\n\n fixture.transfer(\n Key::from(fixture.bob),\n initial_ali_balance + U256::one(),\n fixture.ali,\n );\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To build and run the tests, issue the following command in the project folder, ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The project contains a ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,s.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file to the ",(0,s.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,s.jsx)(t.code,{children:"make test"})," command during development."]}),"\n",(0,s.jsx)(t.h2,{id:"configuring-the-test-package",children:"Configuring the Test Package"}),"\n",(0,s.jsxs)(t.p,{children:["In this project, we define a ",(0,s.jsx)(t.code,{children:"tests"})," package using the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/Cargo.toml",children:"tests/Cargo.toml"})," file."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'[package]\nname = "tests"\nversion = "1.0.0"\n...\n\n[dependencies]\ncasper-types = "2.0.0"\ncasper-engine-test-support = "4.0.0"\ncasper-execution-engine = "4.0.0"\nonce_cell = "1.16.0"\n\n[lib]\nname = "tests"\n...\n'})}),"\n",(0,s.jsx)(t.h2,{id:"testing-logic",children:"Testing Logic"}),"\n",(0,s.jsxs)(t.p,{children:["In Github, you will find an ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/cep18",children:"example"})," containing a Casper Fungible Token ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/cep18/src/main.rs",children:"contract"})," implementation with the corresponding ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"tests"}),". The tests follow this sequence:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#setting-up-the-testing-context",children:"Step 1"})," - Specify the starting state of the blockchain."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"Step 2"})," - Deploy the compiled contract to the blockchain and query it."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#creating-helper-functions",children:"Step 3"})," - Create additional deploys for calling each of the entrypoints in the contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints."}),"\n",(0,s.jsx)(t.h3,{id:"setting-up-the-testing-context",children:"Setting up the Testing Context"}),"\n",(0,s.jsxs)(t.p,{children:["The code in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src/utility",children:"utility directory"})," initializes the blockchain's ",(0,s.jsx)(t.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," with all the data and entrypoints the smart contract needs."]}),"\n",(0,s.jsxs)(t.p,{children:["Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/constants.rs",children:(0,s.jsx)(t.code,{children:"constants.rs"})})," file within the ",(0,s.jsx)(t.code,{children:"utility"})," directory. For the most up-to-date version of the code, visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of required constants"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\nuse casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,\n};\nuse casper_execution_engine::core::engine_state::ExecuteRequest;\nuse casper_types::{\n account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,\n};\n\nuse crate::utility::constants::{\n ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,\n};\n\nuse super::constants::{\n ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,\n};\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a ",(0,s.jsx)(t.code,{children:"TestContext"})," of its own. The ",(0,s.jsx)(t.em,{children:"contract_hash"})," and the ",(0,s.jsx)(t.em,{children:"session_code"})," won\u2019t change after the contract is deployed, so it is good to keep them handy."]}),"\n",(0,s.jsxs)(t.p,{children:["This code snippet builds the context and includes the compiled contract ",(0,s.jsx)(t.em,{children:".wasm"})," binary being tested. The ",(0,s.jsx)(t.code,{children:"TestContext"})," struct creates a new instance of the ",(0,s.jsx)(t.code,{children:"cep18_token"})," with several test accounts."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),": These accounts have a positive initial balance."]}),"\n",(0,s.jsxs)(t.p,{children:["The full and most recent code implementation is available on ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of a CEP-18 token in a test"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\n// Creating the `TestContext` struct.\n\npub(crate) struct TestContext {\npub(crate) cep18_token: ContractHash,\npub(crate) cep18_test_contract_package: ContractPackageHash,\n}\n\n// Setting up the test instance of CEP-18.\n\npub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option<u64> = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-helper-functions",children:"Creating Helper Functions"}),"\n",(0,s.jsxs)(t.p,{children:["The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.jsx)(t.code,{children:"installer_request_builders.rs"})," defines helper functions that will be used throughout the testing framework:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_total_supply"})," - A function for testing the total supply of the CEP-18 contract instance."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_balance_of"})," - A function for checking an account's balance of CEP-18 tokens."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_allowance_of"})," - A function for checking an account's spending allowance from another account's balance."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.jsx)(t.code,{children:"test_cep18_transfer"}),", ",(0,s.jsx)(t.code,{children:"make_cep18_approve_request"})," and ",(0,s.jsx)(t.code,{children:"test_approve_for"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"contract installation"}),":"]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example helper function"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"creating-unit-tests",children:"Creating Unit Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Within this testing context, the ",(0,s.jsxs)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:[(0,s.jsx)(t.code,{children:"tests"})," directory"]})," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"installer_request_builders.rs"})," file."]}),"\n",(0,s.jsxs)(t.p,{children:["The example below shows one of the tests. Visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"GitHub"})," to find all the available tests."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example test querying token properties"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs",children:"lib.rs"})," file is configured to run the example integration tests via the ",(0,s.jsx)(t.code,{children:"make test"})," command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, navigate to the parent ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18 directory"})," and run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["This example uses ",(0,s.jsx)(t.code,{children:"bash"}),". If you are using a Rust IDE, you need to configure it to run the tests."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function a(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a811e42c.b14b4cad.js b/assets/js/a811e42c.b14b4cad.js deleted file mode 100644 index f5a423725..000000000 --- a/assets/js/a811e42c.b14b4cad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1408],{97681:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var s=n(74848),r=n(28453);const c={title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},a="Testing Framework for CEP-18",i={id:"resources/tokens/cep18/tests",title:"Testing Guide",description:"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.",source:"@site/docs/resources/tokens/cep18/tests.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/tests",permalink:"/next/resources/tokens/cep18/tests",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Testing Guide",slug:"/resources/tokens/cep18/tests"},sidebar:"resources",previous:{title:"CEP-18 Transfers",permalink:"/next/resources/tokens/cep18/transfer"},next:{title:"Introduction",permalink:"/next/resources/tokens/cep78/introduction"}},o={},l=[{value:"Configuring the Test Package",id:"configuring-the-test-package",level:2},{value:"Testing Logic",id:"testing-logic",level:2},{value:"Setting up the Testing Context",id:"setting-up-the-testing-context",level:3},{value:"Installing the Contract",id:"installing-the-contract",level:3},{value:"Creating Helper Functions",id:"creating-helper-functions",level:3},{value:"Creating Unit Tests",id:"creating-unit-tests",level:2},{value:"Running the Tests",id:"running-the-tests",level:2}];function _(e){const t={a:"a",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"testing-framework-for-cep-18",children:"Testing Framework for CEP-18"})}),"\n",(0,s.jsxs)(t.p,{children:["The testing framework in this tutorial uses the ",(0,s.jsx)(t.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"Casper engine test support"})," crate for testing the contract implementation against the Casper execution environment."]}),"\n",(0,s.jsxs)(t.p,{children:["The following section reviews the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/master/tests",children:"GitHub testing folder"}),", which creates a testing framework for the Casper ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Fungible Token"})," project. You can find more details about testing Casper contracts ",(0,s.jsx)(t.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"The following is an example of a complete test expecting a failed transfer:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[should_panic(expected = "ApiError::User(65534) [131070]")]\n#[test]\nfn should_not_transfer_with_insufficient_balance() {\n let mut fixture = TestFixture::install_contract();\n\n let initial_ali_balance = fixture.balance_of(Key::from(fixture.ali)).unwrap();\n assert_eq!(fixture.balance_of(Key::from(fixture.bob)), None);\n\n fixture.transfer(\n Key::from(fixture.bob),\n initial_ali_balance + U256::one(),\n fixture.ali,\n );\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["To build and run the tests, issue the following command in the project folder, ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The project contains a ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/Makefile",children:"Makefile"}),", which is a custom build script that compiles the contract before running tests in ",(0,s.jsx)(t.em,{children:"release"})," mode. Then, the script copies the ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file to the ",(0,s.jsx)(t.code,{children:"tests/wasm"})," directory. In practice, you only need to run the ",(0,s.jsx)(t.code,{children:"make test"})," command during development."]}),"\n",(0,s.jsx)(t.h2,{id:"configuring-the-test-package",children:"Configuring the Test Package"}),"\n",(0,s.jsxs)(t.p,{children:["In this project, we define a ",(0,s.jsx)(t.code,{children:"tests"})," package using the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/Cargo.toml",children:"tests/Cargo.toml"})," file."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'[package]\nname = "tests"\nversion = "1.0.0"\n...\n\n[dependencies]\ncasper-types = "2.0.0"\ncasper-engine-test-support = "4.0.0"\ncasper-execution-engine = "4.0.0"\nonce_cell = "1.16.0"\n\n[lib]\nname = "tests"\n...\n'})}),"\n",(0,s.jsx)(t.h2,{id:"testing-logic",children:"Testing Logic"}),"\n",(0,s.jsxs)(t.p,{children:["In Github, you will find an ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/cep18",children:"example"})," containing a Casper Fungible Token ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/cep18/src/main.rs",children:"contract"})," implementation with the corresponding ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"tests"}),". The tests follow this sequence:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#setting-up-the-testing-context",children:"Step 1"})," - Specify the starting state of the blockchain."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"Step 2"})," - Deploy the compiled contract to the blockchain and query it."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"#creating-helper-functions",children:"Step 3"})," - Create additional deploys for calling each of the entrypoints in the contract."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints."}),"\n",(0,s.jsx)(t.h3,{id:"setting-up-the-testing-context",children:"Setting up the Testing Context"}),"\n",(0,s.jsxs)(t.p,{children:["The code in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src/utility",children:"utility directory"})," initializes the blockchain's ",(0,s.jsx)(t.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"})," with all the data and entrypoints the smart contract needs."]}),"\n",(0,s.jsxs)(t.p,{children:["Expand the example below to see a subset of the required constants for this project. The testing framework defines constants via the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/constants.rs",children:(0,s.jsx)(t.code,{children:"constants.rs"})})," file within the ",(0,s.jsx)(t.code,{children:"utility"})," directory. For the most up-to-date version of the code, visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of required constants"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\nuse casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n MINIMUM_ACCOUNT_CREATION_BALANCE, PRODUCTION_RUN_GENESIS_REQUEST,\n};\nuse casper_execution_engine::core::engine_state::ExecuteRequest;\nuse casper_types::{\n account::AccountHash, bytesrepr::FromBytes, runtime_args, system::mint, CLTyped, ContractHash, ContractPackageHash, Key, RuntimeArgs, U256,\n};\n\nuse crate::utility::constants::{\n ALLOWANCE_AMOUNT_1, ALLOWANCE_AMOUNT_2, TOTAL_SUPPLY_KEY, TRANSFER_AMOUNT_1, TRANSFER_AMOUNT_2,\n};\n\nuse super::constants::{\n ACCOUNT_1_ADDR, ACCOUNT_2_ADDR, ARG_ADDRESS, ARG_AMOUNT, ARG_DECIMALS, ARG_NAME, ARG_OWNER, ARG_RECIPIENT, ARG_SPENDER, ARG_SYMBOL, ARG_TOKEN_CONTRACT, ARG_TOTAL_SUPPLY, CEP18_CONTRACT_WASM, CEP18_TEST_CONTRACT_KEY, CEP18_TEST_CONTRACT_WASM, CEP18_TOKEN_CONTRACT_KEY, CHECK_ALLOWANCE_OF_ENTRYPOINT, CHECK_BALANCE_OF_ENTRYPOINT,CHECK_TOTAL_SUPPLY_ENTRYPOINT, METHOD_APPROVE, METHOD_APPROVE_AS_STORED_CONTRACT,METHOD_TRANSFER, METHOD_TRANSFER_AS_STORED_CONTRACT, RESULT_KEY, TOKEN_DECIMALS, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY,\n};\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"installing-the-contract",children:"Installing the Contract"}),"\n",(0,s.jsxs)(t.p,{children:["The next step is to define a struct that has its own virtual machine (VM) instance and implements the Fungible Token entrypoints. This struct holds a ",(0,s.jsx)(t.code,{children:"TestContext"})," of its own. The ",(0,s.jsx)(t.em,{children:"contract_hash"})," and the ",(0,s.jsx)(t.em,{children:"session_code"})," won\u2019t change after the contract is deployed, so it is good to keep them handy."]}),"\n",(0,s.jsxs)(t.p,{children:["This code snippet builds the context and includes the compiled contract ",(0,s.jsx)(t.em,{children:".wasm"})," binary being tested. The ",(0,s.jsx)(t.code,{children:"TestContext"})," struct creates a new instance of the ",(0,s.jsx)(t.code,{children:"cep18_token"})," with several test accounts."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.strong,{children:"Note"}),": These accounts have a positive initial balance."]}),"\n",(0,s.jsxs)(t.p,{children:["The full and most recent code implementation is available on ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"GitHub"}),"."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example of a CEP-18 token in a test"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\n// Creating the `TestContext` struct.\n\npub(crate) struct TestContext {\npub(crate) cep18_token: ContractHash,\npub(crate) cep18_test_contract_package: ContractPackageHash,\n}\n\n// Setting up the test instance of CEP-18.\n\npub(crate) fn setup() -> (InMemoryWasmTestBuilder, TestContext) {\n setup_with_args(runtime_args! {\n ARG_NAME => TOKEN_NAME,\n ARG_SYMBOL => TOKEN_SYMBOL,\n ARG_DECIMALS => TOKEN_DECIMALS,\n ARG_TOTAL_SUPPLY => U256::from(TOKEN_TOTAL_SUPPLY),\n })\n}\n\n// Establishing test accounts.\n\npub(crate) fn setup_with_args(install_args: RuntimeArgs) -> (InMemoryWasmTestBuilder, TestContext) {\n let mut builder = InMemoryWasmTestBuilder::default();\n builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST);\n\n let id: Option<u64> = None;\n let transfer_1_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_1_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n let transfer_2_args = runtime_args! {\n mint::ARG_TARGET => *ACCOUNT_2_ADDR,\n mint::ARG_AMOUNT => MINIMUM_ACCOUNT_CREATION_BALANCE,\n mint::ARG_ID => id,\n };\n\n let transfer_request_1 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_1_args).build();\n let transfer_request_2 =\n ExecuteRequestBuilder::transfer(*DEFAULT_ACCOUNT_ADDR, transfer_2_args).build();\n\n // Installing the test version of CEP-18 with the default account.\n\n let install_request_1 =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CEP18_CONTRACT_WASM, install_args)\n .build();\n\n let install_request_2 = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n CEP18_TEST_CONTRACT_WASM,\n RuntimeArgs::default(),\n )\n .build();\n\n builder.exec(transfer_request_1).expect_success().commit();\n builder.exec(transfer_request_2).expect_success().commit();\n builder.exec(install_request_1).expect_success().commit();\n builder.exec(install_request_2).expect_success().commit();\n\n let account = builder\n .get_account(*DEFAULT_ACCOUNT_ADDR)\n .expect("should have account");\n\n let cep18_token = account\n .named_keys()\n .get(CEP18_TOKEN_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractHash::new)\n .expect("should have contract hash");\n\n let cep18_test_contract_package = account\n .named_keys()\n .get(CEP18_TEST_CONTRACT_KEY)\n .and_then(|key| key.into_hash())\n .map(ContractPackageHash::new)\n .expect("should have contract package hash");\n\n let test_context = TestContext {\n cep18_token,\n cep18_test_contract_package,\n };\n\n (builder, test_context)\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"creating-helper-functions",children:"Creating Helper Functions"}),"\n",(0,s.jsxs)(t.p,{children:["The previous step has simulated sending a real deploy on the network. The next code snippet in ",(0,s.jsx)(t.code,{children:"installer_request_builders.rs"})," defines helper functions that will be used throughout the testing framework:"]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_total_supply"})," - A function for testing the total supply of the CEP-18 contract instance."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_balance_of"})," - A function for checking an account's balance of CEP-18 tokens."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_check_allowance_of"})," - A function for checking an account's spending allowance from another account's balance."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["These are followed by functions that check specific aspects of the CEP-18 contract. These include ",(0,s.jsx)(t.code,{children:"test_cep18_transfer"}),", ",(0,s.jsx)(t.code,{children:"make_cep18_approve_request"})," and ",(0,s.jsx)(t.code,{children:"test_approve_for"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The following code snippet is an example function that tests the ability to transfer CEP-18 tokens from the default address to the two other addresses established in ",(0,s.jsx)(t.a,{href:"#installing-the-contract",children:"contract installation"}),":"]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example helper function"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs\n\npub(crate) fn test_cep18_transfer(\n builder: &mut InMemoryWasmTestBuilder,\n test_context: &TestContext,\n sender1: Key,\n recipient1: Key,\n sender2: Key,\n recipient2: Key) {\n let TestContext { cep18_token, .. } = test_context;\n\n // Defining the amount to be transferred to each account.\n\n let transfer_amount_1 = U256::from(TRANSFER_AMOUNT_1);\n let transfer_amount_2 = U256::from(TRANSFER_AMOUNT_2);\n\n // Checking the pre-existing balances of the default address and the two receiving addresses.\n\n let sender_balance_before = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_ne!(sender_balance_before, U256::zero());\n\n let account_1_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_before, U256::zero());\n\n let account_2_balance_before = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_2_balance_before, U256::zero());\n\n // Creating the first transfer request.\n\n let token_transfer_request_1 =\n make_cep18_transfer_request(sender1, cep18_token, recipient1, transfer_amount_1);\n\n builder\n .exec(token_transfer_request_1)\n .expect_success()\n .commit();\n\n // Checking the prior balance against the new balance to ensure the transfer occurred correctly.\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert_eq!(account_1_balance_after, transfer_amount_1);\n let account_1_balance_before = account_1_balance_after;\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(\n sender_balance_after,\n sender_balance_before - transfer_amount_1\n );\n let sender_balance_before = sender_balance_after;\n\n // Creating the second transfer request.\n\n let token_transfer_request_2 =\n make_cep18_transfer_request(sender2, cep18_token, recipient2, transfer_amount_2);\n\n builder\n .exec(token_transfer_request_2)\n .expect_success()\n .commit();\n\n // Checking prior balances against new balances.\n\n let sender_balance_after = cep18_check_balance_of(builder, cep18_token, sender1);\n assert_eq!(sender_balance_after, sender_balance_before);\n\n let account_1_balance_after = cep18_check_balance_of(builder, cep18_token, recipient1);\n assert!(account_1_balance_after < account_1_balance_before);\n assert_eq!(\n account_1_balance_after,\n transfer_amount_1 - transfer_amount_2\n );\n\n let account_2_balance_after = cep18_check_balance_of(builder, cep18_token, recipient2);\n assert_eq!(account_2_balance_after, transfer_amount_2);\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"creating-unit-tests",children:"Creating Unit Tests"}),"\n",(0,s.jsxs)(t.p,{children:["Within this testing context, the ",(0,s.jsxs)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:[(0,s.jsx)(t.code,{children:"tests"})," directory"]})," includes a variety of unit tests, which verify the contract code by invoking the functions defined in the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/utility/installer_request_builders.rs",children:"installer_request_builders.rs"})," file."]}),"\n",(0,s.jsxs)(t.p,{children:["The example below shows one of the tests. Visit ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/tree/dev/tests/src",children:"GitHub"})," to find all the available tests."]}),"\n",(0,s.jsxs)(t.details,{children:["\n",(0,s.jsx)(t.summary,{children:"Example test querying token properties"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// File https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/install.rs\n\nuse casper_engine_test_support::DEFAULT_ACCOUNT_ADDR;\nuse casper_types::{Key, U256};\n\nuse crate::utility::{\n constants::{\n ALLOWANCES_KEY, BALANCES_KEY, DECIMALS_KEY, NAME_KEY, SYMBOL_KEY, TOKEN_DECIMALS,\n TOKEN_NAME, TOKEN_SYMBOL, TOKEN_TOTAL_SUPPLY, TOTAL_SUPPLY_KEY,\n },\n installer_request_builders::{\n cep18_check_balance_of, invert_cep18_address, setup, TestContext,\n },\n};\n\n#[test]\nfn should_have_queryable_properties() {\n let (mut builder, TestContext { cep18_token, .. }) = setup();\n\n let name: String = builder.get_value(cep18_token, NAME_KEY);\n assert_eq!(name, TOKEN_NAME);\n\n let symbol: String = builder.get_value(cep18_token, SYMBOL_KEY);\n assert_eq!(symbol, TOKEN_SYMBOL);\n\n let decimals: u8 = builder.get_value(cep18_token, DECIMALS_KEY);\n assert_eq!(decimals, TOKEN_DECIMALS);\n\n let total_supply: U256 = builder.get_value(cep18_token, TOTAL_SUPPLY_KEY);\n assert_eq!(total_supply, U256::from(TOKEN_TOTAL_SUPPLY));\n\n let owner_key = Key::Account(*DEFAULT_ACCOUNT_ADDR);\n\n let owner_balance = cep18_check_balance_of(&mut builder, &cep18_token, owner_key);\n assert_eq!(owner_balance, total_supply);\n\n let contract_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, Key::Hash(cep18_token.value()));\n assert_eq!(contract_balance, U256::zero());\n\n // Ensures that Account and Contract ownership is respected and we're not keying ownership under\n // the raw bytes regardless of variant.\n let inverted_owner_key = invert_cep18_address(owner_key);\n let inverted_owner_balance =\n cep18_check_balance_of(&mut builder, &cep18_token, inverted_owner_key);\n assert_eq!(inverted_owner_balance, U256::zero());\n}\n"})}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"running-the-tests",children:"Running the Tests"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18/blob/dev/tests/src/lib.rs",children:"lib.rs"})," file is configured to run the example integration tests via the ",(0,s.jsx)(t.code,{children:"make test"})," command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"#[cfg(test)]\nmod allowance;\n#[cfg(test)]\nmod install;\n#[cfg(test)]\nmod mint_and_burn;\n#[cfg(test)]\nmod transfer;\n#[cfg(test)]\nmod utility;\n"})}),"\n",(0,s.jsxs)(t.p,{children:["To run the tests, navigate to the parent ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"cep18 directory"})," and run the command:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["This example uses ",(0,s.jsx)(t.code,{children:"bash"}),". If you are using a Rust IDE, you need to configure it to run the tests."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(_,{...e})}):_(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},c=s.createContext(r);function a(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a81b7004.614649de.js b/assets/js/a81b7004.614649de.js new file mode 100644 index 000000000..58e10ecf3 --- /dev/null +++ b/assets/js/a81b7004.614649de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16044],{14086:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),o=s(28453);const i={},c="Contracts and Session Code",r={id:"developers/writing-onchain-code/contract-vs-session",title:"Contracts and Session Code",description:"What is Session Code?",source:"@site/docs/developers/writing-onchain-code/contract-vs-session.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-vs-session",permalink:"/developers/writing-onchain-code/contract-vs-session",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/developers/writing-onchain-code/calling-contracts"},next:{title:"Writing Session Code",permalink:"/developers/writing-onchain-code/writing-session-code"}},a={},d=[{value:"What is Session Code?",id:"what-is-session-code",level:2},{value:"Comparing Session and Contract Code",id:"comparing-session-and-contract",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"contracts-and-session-code",children:"Contracts and Session Code"})}),"\n",(0,t.jsx)(n.h2,{id:"what-is-session-code",children:"What is Session Code?"}),"\n",(0,t.jsxs)(n.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the ",(0,t.jsx)(n.code,{children:"call"})," function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse."]}),"\n",(0,t.jsxs)(n.p,{children:["The best use of session code is when the situation calls for ",(0,t.jsx)(n.a,{href:"/concepts/glossary/S#stateless",children:"stateless"})," execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary."]}),"\n",(0,t.jsx)(n.h2,{id:"comparing-session-and-contract",children:"Comparing Session and Contract Code"}),"\n",(0,t.jsx)(n.p,{children:"The following table summarizes the key differences between session code and contract code on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Session Code"}),(0,t.jsx)(n.th,{children:"Contract Code"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Session code always executes in the context of the account that signed the transaction containing the session code."}),(0,t.jsx)(n.td,{children:"A smart contract, which is stored on-chain logic, executes within its own context."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Session code has only one entry point, ",(0,t.jsx)(n.code,{children:"call"}),", which can be used to interact with the session code."]}),(0,t.jsx)(n.td,{children:"A smart contract can have multiple entry points that can be invoked."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," entry point initiates any action the session code takes."]}),(0,t.jsx)(n.td,{children:"Any action undertaken by a contract must initiate through an outside call, usually via session code."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the body of the session code, the key is added to the account's named keys."]}),(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the smart contract's context, the contract's record is modified to have a new named_key entry."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["For more information on how to write session code, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),"."]}),(0,t.jsxs)(n.td,{children:["For more information on writing contracts, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"The following image depicts the comparison presented in the table."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Comparing Session and Contract Code",src:s(33944).A+"",width:"3716",height:"2652"})}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"write session code"})]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"test session code"})]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},33944:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/session-contract-context-eeb5191bad40f018d30b138e5fb2f964.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a81b7004.8421c8ce.js b/assets/js/a81b7004.8421c8ce.js deleted file mode 100644 index 445d592be..000000000 --- a/assets/js/a81b7004.8421c8ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6044],{14086:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var t=s(74848),o=s(28453);const i={},c="Contracts and Session Code",r={id:"developers/writing-onchain-code/contract-vs-session",title:"Contracts and Session Code",description:"What is Session Code?",source:"@site/docs/developers/writing-onchain-code/contract-vs-session.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/contract-vs-session",permalink:"/next/developers/writing-onchain-code/contract-vs-session",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/next/developers/writing-onchain-code/calling-contracts"},next:{title:"Writing Session Code",permalink:"/next/developers/writing-onchain-code/writing-session-code"}},a={},d=[{value:"What is Session Code?",id:"what-is-session-code",level:2},{value:"Comparing Session and Contract Code",id:"comparing-session-and-contract",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"contracts-and-session-code",children:"Contracts and Session Code"})}),"\n",(0,t.jsx)(n.h2,{id:"what-is-session-code",children:"What is Session Code?"}),"\n",(0,t.jsxs)(n.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the ",(0,t.jsx)(n.code,{children:"call"})," function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse."]}),"\n",(0,t.jsxs)(n.p,{children:["The best use of session code is when the situation calls for ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S#stateless",children:"stateless"})," execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary."]}),"\n",(0,t.jsx)(n.h2,{id:"comparing-session-and-contract",children:"Comparing Session and Contract Code"}),"\n",(0,t.jsx)(n.p,{children:"The following table summarizes the key differences between session code and contract code on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Session Code"}),(0,t.jsx)(n.th,{children:"Contract Code"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"Session code always executes in the context of the account that signed the transaction containing the session code."}),(0,t.jsx)(n.td,{children:"A smart contract, which is stored on-chain logic, executes within its own context."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Session code has only one entry point, ",(0,t.jsx)(n.code,{children:"call"}),", which can be used to interact with the session code."]}),(0,t.jsx)(n.td,{children:"A smart contract can have multiple entry points that can be invoked."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," entry point initiates any action the session code takes."]}),(0,t.jsx)(n.td,{children:"Any action undertaken by a contract must initiate through an outside call, usually via session code."})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the body of the session code, the key is added to the account's named keys."]}),(0,t.jsxs)(n.td,{children:["When a ",(0,t.jsx)(n.code,{children:"put_key"})," call is made within the smart contract's context, the contract's record is modified to have a new named_key entry."]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["For more information on how to write session code, see ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"Writing Session Code"}),"."]}),(0,t.jsxs)(n.td,{children:["For more information on writing contracts, see ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]})]})]})]}),"\n",(0,t.jsx)(n.p,{children:"The following image depicts the comparison presented in the table."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Comparing Session and Contract Code",src:s(56170).A+"",width:"3716",height:"2652"})}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/writing-session-code",children:"write session code"})]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/testing-session-code",children:"test session code"})]}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},56170:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/session-contract-context-eeb5191bad40f018d30b138e5fb2f964.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a833d846.fbb45413.js b/assets/js/a833d846.fbb45413.js new file mode 100644 index 000000000..dbd5afd01 --- /dev/null +++ b/assets/js/a833d846.fbb45413.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[78848],{86896:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="J",a={id:"concepts/glossary/J",title:"J",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/J.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/J",permalink:"/2.0.0/concepts/glossary/J",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"I",permalink:"/2.0.0/concepts/glossary/I"},next:{title:"K",permalink:"/2.0.0/concepts/glossary/K"}},l={},h=[{value:"JSON",id:"json",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"j",children:"J"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"json",children:"JSON"}),"\n",(0,n.jsxs)(e.p,{children:["JSON (",(0,n.jsx)(e.strong,{children:"J"}),"ava",(0,n.jsx)(e.strong,{children:"S"}),"cript ",(0,n.jsx)(e.strong,{children:"O"}),"bject ",(0,n.jsx)(e.strong,{children:"N"}),"otation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found ",(0,n.jsx)(e.a,{href:"https://www.json.org/json-en.html",children:"here"}),"."]})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.1cba57a1.js b/assets/js/a94703ab.1cba57a1.js deleted file mode 100644 index ab25fea77..000000000 --- a/assets/js/a94703ab.1cba57a1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9048],{11377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(96540),o=n(34164),i=n(45500),s=n(17559),l=n(26972),r=n(60609),c=n(21312),d=n(23104),u=n(75062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(53109),x=n(56347),f=n(24581),j=n(6342),v=n(23465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(65041),C=n(89532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(41422),B=n(99169),y=n(28774),w=n(92303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(16654),H=n(43186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const K="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(K,s&&z,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(Y,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(75600),Z=n(22069);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(23363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},23363:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(34164),o=n(21312),i=n(51107),s=n(74848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/a94703ab.6d07f677.js b/assets/js/a94703ab.6d07f677.js new file mode 100644 index 000000000..d1ed87f1e --- /dev/null +++ b/assets/js/a94703ab.6d07f677.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79048],{11377:(e,t,n)=>{n.r(t),n.d(t,{default:()=>be});var a=n(96540),o=n(34164),i=n(45500),s=n(17559),l=n(26972),r=n(60609),c=n(21312),d=n(23104),u=n(75062);const m={backToTopButton:"backToTopButton_sjWU",backToTopButtonShow:"backToTopButtonShow_xfvO"};var b=n(74848);function h(){const{shown:e,scrollToTop:t}=function(e){let{threshold:t}=e;const[n,o]=(0,a.useState)(!1),i=(0,a.useRef)(!1),{startScroll:s,cancelScroll:l}=(0,d.gk)();return(0,d.Mq)(((e,n)=>{let{scrollY:a}=e;const s=n?.scrollY;s&&(i.current?i.current=!1:a>=s?(l(),o(!1)):a<t?o(!1):a+window.innerHeight<document.documentElement.scrollHeight&&o(!0))})),(0,u.$)((e=>{e.location.hash&&(i.current=!0,o(!1))})),{shown:n,scrollToTop:()=>s(0)}}({threshold:300});return(0,b.jsx)("button",{"aria-label":(0,c.T)({id:"theme.BackToTopButton.buttonAriaLabel",message:"Scroll back to top",description:"The ARIA label for the back to top button"}),className:(0,o.A)("clean-btn",s.G.common.backToTopButton,m.backToTopButton,e&&m.backToTopButtonShow),type:"button",onClick:t})}var p=n(53109),x=n(56347),f=n(24581),j=n(6342),v=n(23465);function _(e){return(0,b.jsx)("svg",{width:"20",height:"20","aria-hidden":"true",...e,children:(0,b.jsxs)("g",{fill:"#7a7a7a",children:[(0,b.jsx)("path",{d:"M9.992 10.023c0 .2-.062.399-.172.547l-4.996 7.492a.982.982 0 01-.828.454H1c-.55 0-1-.453-1-1 0-.2.059-.403.168-.551l4.629-6.942L.168 3.078A.939.939 0 010 2.528c0-.548.45-.997 1-.997h2.996c.352 0 .649.18.828.45L9.82 9.472c.11.148.172.347.172.55zm0 0"}),(0,b.jsx)("path",{d:"M19.98 10.023c0 .2-.058.399-.168.547l-4.996 7.492a.987.987 0 01-.828.454h-3c-.547 0-.996-.453-.996-1 0-.2.059-.403.168-.551l4.625-6.942-4.625-6.945a.939.939 0 01-.168-.55 1 1 0 01.996-.997h3c.348 0 .649.18.828.45l4.996 7.492c.11.148.168.347.168.55zm0 0"})]})})}const A={collapseSidebarButton:"collapseSidebarButton_PEFL",collapseSidebarButtonIcon:"collapseSidebarButtonIcon_kv0_"};function g(e){let{onClick:t}=e;return(0,b.jsx)("button",{type:"button",title:(0,c.T)({id:"theme.docs.sidebar.collapseButtonTitle",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.collapseButtonAriaLabel",message:"Collapse sidebar",description:"The title attribute for collapse button of doc sidebar"}),className:(0,o.A)("button button--secondary button--outline",A.collapseSidebarButton),onClick:t,children:(0,b.jsx)(_,{className:A.collapseSidebarButtonIcon})})}var k=n(65041),C=n(89532);const S=Symbol("EmptyContext"),T=a.createContext(S);function N(e){let{children:t}=e;const[n,o]=(0,a.useState)(null),i=(0,a.useMemo)((()=>({expandedItem:n,setExpandedItem:o})),[n]);return(0,b.jsx)(T.Provider,{value:i,children:t})}var I=n(41422),B=n(99169),y=n(28774),w=n(92303);function L(e){let{collapsed:t,categoryLabel:n,onClick:a}=e;return(0,b.jsx)("button",{"aria-label":t?(0,c.T)({id:"theme.DocSidebarItem.expandCategoryAriaLabel",message:"Expand sidebar category '{label}'",description:"The ARIA label to expand the sidebar category"},{label:n}):(0,c.T)({id:"theme.DocSidebarItem.collapseCategoryAriaLabel",message:"Collapse sidebar category '{label}'",description:"The ARIA label to collapse the sidebar category"},{label:n}),"aria-expanded":!t,type:"button",className:"clean-btn menu__caret",onClick:a})}function E(e){let{item:t,onItemClick:n,activePath:i,level:r,index:c,...d}=e;const{items:u,label:m,collapsible:h,className:p,href:x}=t,{docs:{sidebar:{autoCollapseCategories:f}}}=(0,j.p)(),v=function(e){const t=(0,w.A)();return(0,a.useMemo)((()=>e.href&&!e.linkUnlisted?e.href:!t&&e.collapsible?(0,l.Nr)(e):void 0),[e,t])}(t),_=(0,l.w8)(t,i),A=(0,B.ys)(x,i),{collapsed:g,setCollapsed:k}=(0,I.u)({initialState:()=>!!h&&(!_&&t.collapsed)}),{expandedItem:N,setExpandedItem:E}=function(){const e=(0,a.useContext)(T);if(e===S)throw new C.dV("DocSidebarItemsExpandedStateProvider");return e}(),M=function(e){void 0===e&&(e=!g),E(e?null:c),k(e)};return function(e){let{isActive:t,collapsed:n,updateCollapsed:o}=e;const i=(0,C.ZC)(t);(0,a.useEffect)((()=>{t&&!i&&n&&o(!1)}),[t,i,n,o])}({isActive:_,collapsed:g,updateCollapsed:M}),(0,a.useEffect)((()=>{h&&null!=N&&N!==c&&f&&k(!0)}),[h,N,c,k,f]),(0,b.jsxs)("li",{className:(0,o.A)(s.G.docs.docSidebarItemCategory,s.G.docs.docSidebarItemCategoryLevel(r),"menu__list-item",{"menu__list-item--collapsed":g},p),children:[(0,b.jsxs)("div",{className:(0,o.A)("menu__list-item-collapsible",{"menu__list-item-collapsible--active":A}),children:[(0,b.jsx)(y.A,{className:(0,o.A)("menu__link",{"menu__link--sublist":h,"menu__link--sublist-caret":!x&&h,"menu__link--active":_}),onClick:h?e=>{n?.(t),x?M(!1):(e.preventDefault(),M())}:()=>{n?.(t)},"aria-current":A?"page":void 0,role:h&&!x?"button":void 0,"aria-expanded":h&&!x?!g:void 0,href:h?v??"#":v,...d,children:m}),x&&h&&(0,b.jsx)(L,{collapsed:g,categoryLabel:m,onClick:e=>{e.preventDefault(),M()}})]}),(0,b.jsx)(I.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:g,children:(0,b.jsx)(U,{items:u,tabIndex:g?-1:0,onItemClick:n,activePath:i,level:r+1})})]})}var M=n(16654),H=n(43186);const G={menuExternalLink:"menuExternalLink_NmtK"};function W(e){let{item:t,onItemClick:n,activePath:a,level:i,index:r,...c}=e;const{href:d,label:u,className:m,autoAddBaseUrl:h}=t,p=(0,l.w8)(t,a),x=(0,M.A)(d);return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(i),"menu__list-item",m),children:(0,b.jsxs)(y.A,{className:(0,o.A)("menu__link",!x&&G.menuExternalLink,{"menu__link--active":p}),autoAddBaseUrl:h,"aria-current":p?"page":void 0,to:d,...x&&{onClick:n?()=>n(t):void 0},...c,children:[u,!x&&(0,b.jsx)(H.A,{})]})},u)}const P={menuHtmlItem:"menuHtmlItem_M9Kj"};function R(e){let{item:t,level:n,index:a}=e;const{value:i,defaultStyle:l,className:r}=t;return(0,b.jsx)("li",{className:(0,o.A)(s.G.docs.docSidebarItemLink,s.G.docs.docSidebarItemLinkLevel(n),l&&[P.menuHtmlItem,"menu__list-item"],r),dangerouslySetInnerHTML:{__html:i}},a)}function D(e){let{item:t,...n}=e;switch(t.type){case"category":return(0,b.jsx)(E,{item:t,...n});case"html":return(0,b.jsx)(R,{item:t,...n});default:return(0,b.jsx)(W,{item:t,...n})}}function F(e){let{items:t,...n}=e;const a=(0,l.Y)(t,n.activePath);return(0,b.jsx)(N,{children:a.map(((e,t)=>(0,b.jsx)(D,{item:e,index:t,...n},t)))})}const U=(0,a.memo)(F),V={menu:"menu_SIkG",menuWithAnnouncementBar:"menuWithAnnouncementBar_GW3s"};function Y(e){let{path:t,sidebar:n,className:i}=e;const l=function(){const{isActive:e}=(0,k.M)(),[t,n]=(0,a.useState)(e);return(0,d.Mq)((t=>{let{scrollY:a}=t;e&&n(0===a)}),[e]),e&&t}();return(0,b.jsx)("nav",{"aria-label":(0,c.T)({id:"theme.docs.sidebar.navAriaLabel",message:"Docs sidebar",description:"The ARIA label for the sidebar navigation"}),className:(0,o.A)("menu thin-scrollbar",V.menu,l&&V.menuWithAnnouncementBar,i),children:(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:n,activePath:t,level:1})})})}const K="sidebar_njMd",z="sidebarWithHideableNavbar_wUlq",q="sidebarHidden_VK0M",O="sidebarLogo_isFc";function J(e){let{path:t,sidebar:n,onCollapse:a,isHidden:i}=e;const{navbar:{hideOnScroll:s},docs:{sidebar:{hideable:l}}}=(0,j.p)();return(0,b.jsxs)("div",{className:(0,o.A)(K,s&&z,i&&q),children:[s&&(0,b.jsx)(v.A,{tabIndex:-1,className:O}),(0,b.jsx)(Y,{path:t,sidebar:n}),l&&(0,b.jsx)(g,{onClick:a})]})}const Q=a.memo(J);var X=n(75600),Z=n(22069);const $=e=>{let{sidebar:t,path:n}=e;const a=(0,Z.M)();return(0,b.jsx)("ul",{className:(0,o.A)(s.G.docs.docSidebarMenu,"menu__list"),children:(0,b.jsx)(U,{items:t,activePath:n,onItemClick:e=>{"category"===e.type&&e.href&&a.toggle(),"link"===e.type&&a.toggle()},level:1})})};function ee(e){return(0,b.jsx)(X.GX,{component:$,props:e})}const te=a.memo(ee);function ne(e){const t=(0,f.l)(),n="desktop"===t||"ssr"===t,a="mobile"===t;return(0,b.jsxs)(b.Fragment,{children:[n&&(0,b.jsx)(Q,{...e}),a&&(0,b.jsx)(te,{...e})]})}const ae={expandButton:"expandButton_TmdG",expandButtonIcon:"expandButtonIcon_i1dp"};function oe(e){let{toggleSidebar:t}=e;return(0,b.jsx)("div",{className:ae.expandButton,title:(0,c.T)({id:"theme.docs.sidebar.expandButtonTitle",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),"aria-label":(0,c.T)({id:"theme.docs.sidebar.expandButtonAriaLabel",message:"Expand sidebar",description:"The ARIA label and title attribute for expand button of doc sidebar"}),tabIndex:0,role:"button",onKeyDown:t,onClick:t,children:(0,b.jsx)(_,{className:ae.expandButtonIcon})})}const ie={docSidebarContainer:"docSidebarContainer_YfHR",docSidebarContainerHidden:"docSidebarContainerHidden_DPk8",sidebarViewport:"sidebarViewport_aRkj"};function se(e){let{children:t}=e;const n=(0,r.t)();return(0,b.jsx)(a.Fragment,{children:t},n?.name??"noSidebar")}function le(e){let{sidebar:t,hiddenSidebarContainer:n,setHiddenSidebarContainer:i}=e;const{pathname:l}=(0,x.zy)(),[r,c]=(0,a.useState)(!1),d=(0,a.useCallback)((()=>{r&&c(!1),!r&&(0,p.O)()&&c(!0),i((e=>!e))}),[i,r]);return(0,b.jsx)("aside",{className:(0,o.A)(s.G.docs.docSidebarContainer,ie.docSidebarContainer,n&&ie.docSidebarContainerHidden),onTransitionEnd:e=>{e.currentTarget.classList.contains(ie.docSidebarContainer)&&n&&c(!0)},children:(0,b.jsx)(se,{children:(0,b.jsxs)("div",{className:(0,o.A)(ie.sidebarViewport,r&&ie.sidebarViewportHidden),children:[(0,b.jsx)(ne,{sidebar:t,path:l,onCollapse:d,isHidden:r}),r&&(0,b.jsx)(oe,{toggleSidebar:d})]})})})}const re={docMainContainer:"docMainContainer_TBSr",docMainContainerEnhanced:"docMainContainerEnhanced_lQrH",docItemWrapperEnhanced:"docItemWrapperEnhanced_JWYK"};function ce(e){let{hiddenSidebarContainer:t,children:n}=e;const a=(0,r.t)();return(0,b.jsx)("main",{className:(0,o.A)(re.docMainContainer,(t||!a)&&re.docMainContainerEnhanced),children:(0,b.jsx)("div",{className:(0,o.A)("container padding-top--md padding-bottom--lg",re.docItemWrapper,t&&re.docItemWrapperEnhanced),children:n})})}const de={docRoot:"docRoot_UBD9",docsWrapper:"docsWrapper_hBAB"};function ue(e){let{children:t}=e;const n=(0,r.t)(),[o,i]=(0,a.useState)(!1);return(0,b.jsxs)("div",{className:de.docsWrapper,children:[(0,b.jsx)(h,{}),(0,b.jsxs)("div",{className:de.docRoot,children:[n&&(0,b.jsx)(le,{sidebar:n.items,hiddenSidebarContainer:o,setHiddenSidebarContainer:i}),(0,b.jsx)(ce,{hiddenSidebarContainer:o,children:t})]})]})}var me=n(23363);function be(e){const t=(0,l.B5)(e);if(!t)return(0,b.jsx)(me.A,{});const{docElement:n,sidebarName:a,sidebarItems:c}=t;return(0,b.jsx)(i.e3,{className:(0,o.A)(s.G.page.docsDocPage),children:(0,b.jsx)(r.V,{name:a,items:c,children:(0,b.jsx)(ue,{children:n})})})}},23363:(e,t,n)=>{n.d(t,{A:()=>l});n(96540);var a=n(34164),o=n(21312),i=n(51107),s=n(74848);function l(e){let{className:t}=e;return(0,s.jsx)("main",{className:(0,a.A)("container margin-vert--xl",t),children:(0,s.jsx)("div",{className:"row",children:(0,s.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,s.jsx)(i.A,{as:"h1",className:"hero__title",children:(0,s.jsx)(o.A,{id:"theme.NotFound.title",description:"The title of the 404 page",children:"Page Not Found"})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p1",description:"The first paragraph of the 404 page",children:"We could not find what you were looking for."})}),(0,s.jsx)("p",{children:(0,s.jsx)(o.A,{id:"theme.NotFound.p2",description:"The 2nd paragraph of the 404 page",children:"Please contact the owner of the site that linked you to the original URL and let them know their link is broken."})})]})})})}}}]); \ No newline at end of file diff --git a/assets/js/a9707311.4c91be6f.js b/assets/js/a9707311.4c91be6f.js new file mode 100644 index 000000000..7482d4cbb --- /dev/null +++ b/assets/js/a9707311.4c91be6f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8816],{72514:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>d,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Dynamic Gas Pricing"},o="Dynamic Gas Pricing on Mainnet",c={id:"concepts/economics/dynamic-gas-pricing",title:"Dynamic Gas Pricing",description:"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.",source:"@site/versioned_docs/version-2.0.0/concepts/economics/dynamic-gas-pricing.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/dynamic-gas-pricing",permalink:"/2.0.0/concepts/economics/dynamic-gas-pricing",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Dynamic Gas Pricing"},sidebar:"concepts",previous:{title:"Gas Cost",permalink:"/2.0.0/concepts/economics/gas-concepts"},next:{title:"Fee Elimination",permalink:"/2.0.0/concepts/economics/fee-elimination"}},r={},l=[{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Fixed Transaction Costs vs. Dynamic Gas Prices",id:"fixed-transaction-costs-vs-dynamic-gas-prices",level:2},{value:"Gas Tolerance",id:"gas-tolerance",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"dynamic-gas-pricing-on-mainnet",children:"Dynamic Gas Pricing on Mainnet"})}),"\n",(0,s.jsxs)(n.p,{children:["The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the ",(0,s.jsx)(n.code,{children:"vacancy"}),", as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity."]}),"\n",(0,s.jsx)(n.p,{children:"When dynamic gas pricing is enabled, a calculation runs at the end of each era to average block usage within that era. This calculation determines the gas price the network will use for the next era. If overall consumption rises above a threshold, the gas price increases by 1. If consumption falls below a threshold, the gas price decreases by 1. The gas price remains the same if overall consumption remains within those thresholds. The gas price will not go up or down by more than 1 in a given era and will not go above the maximum or below the minimum threshold."}),"\n",(0,s.jsx)(n.p,{children:"The gas price is recorded in the block header and is easily discoverable for current and historical purposes. The current gas price is a multiplier that determines the actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1 but would cost 2 CSPR if the current gas price is 2. As blocks become congested, the amount of CSPR required to obtain a slot for executing transactions will increase by a multiple. The following configuration settings control this behavior:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"upper_threshold"})," - The threshold to decrease gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"lower_threshold"})," - The threshold to increase gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"max_gas_price"})," - The maximum gas price"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"min_gas_price"})," - The minimum gas price"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,s.jsx)(n.p,{children:"These are the block vacancy (dynamic gas pricing) settings for the Condor release on Mainnet. Before Condor, the gas price was 1, meaning 1 unit of gas cost 1 mote. With Condor, the multiple is configured to adjust between 1 and 3."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[vacancy]\n# The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network.\n#\n# The network starts with a current_gas_price of min_gas_price.\n#\n# Each block has multiple limits (bytes, transactions, transfers, gas, etc.)\n# The utilization for a block is determined by the highest percentage utilization of each these limits.\n#\n# Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here)\n# 19 transactons -> 19/20 or 95%\n# 600 transfers -> 600/650 or 92.3%\n# resulting block utilization is 95\n#\n# The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is\n# adjusted with the following:\n#\n# If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price.\n# If utilization falls between the thresholds, current_gas_price is not changed.\n# If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price.\n#\n# The cost charged for the transaction is simply the gas_used * current_gas_price.\nupper_threshold = 90\nlower_threshold = 50\nmax_gas_price = 3\nmin_gas_price = 1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"fixed-transaction-costs-vs-dynamic-gas-prices",children:"Fixed Transaction Costs vs. Dynamic Gas Prices"}),"\n",(0,s.jsxs)(n.p,{children:["The current gas price and the slot\u2019s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it\u2019s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost ",(0,s.jsx)(n.a,{href:"/2.0.0/runtime#lanes-and-gas-costs-lanes",children:"here"}),". Also, the ",(0,s.jsx)(n.code,{children:"pricing_handling = { type = 'fixed' }"})," setting is described ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"gas-tolerance",children:"Gas Tolerance"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"The cost of interacting with the blockchain increases during high network usage. Plan accordingly for any transactions and use the gas_tolerance field described below."})}),"\n",(0,s.jsxs)(n.p,{children:["Transactions have a ",(0,s.jsx)(n.code,{children:"gas_tolerance"})," field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with ",(0,s.jsx)(n.code,{children:"gas_tolerance = 2"})," and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block."]})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>c});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9deb425.39296314.js b/assets/js/a9deb425.39296314.js deleted file mode 100644 index 476452298..000000000 --- a/assets/js/a9deb425.39296314.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5157],{25943:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var a=n(74848),r=n(28453);const o={},s="dApp Technology Stack",i={id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/docs/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/next/developers/dapps/technology-stack",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/next/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/next/developers/dapps/template-frontend"}},c={},l=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"dapp-technology-stack",children:"dApp Technology Stack"})}),"\n",(0,a.jsx)(t.p,{children:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."}),"\n",(0,a.jsx)(t.h2,{id:"front-end",children:"Front-End"}),"\n",(0,a.jsxs)(t.p,{children:["The front-end, or ",(0,a.jsx)(t.em,{children:"client-side"})," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."]}),"\n",(0,a.jsxs)(t.p,{children:["You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS"})," requirements."]}),"\n",(0,a.jsx)(t.h3,{id:"signing-transactions",children:"Signing Transactions"}),"\n",(0,a.jsx)(t.p,{children:"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The Casper Wallet"}),"\n",(0,a.jsxs)(t.p,{children:["Use the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Casper Wallet"})," to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."]}),"\n",(0,a.jsx)(t.admonition,{type:"caution",children:(0,a.jsxs)(t.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Third-party signers"}),"\n",(0,a.jsx)(t.p,{children:"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,a.jsx)(t.p,{children:"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."}),"\n",(0,a.jsx)(t.h2,{id:"backend",children:"Backend"}),"\n",(0,a.jsxs)(t.p,{children:["The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS headers"})," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."]}),"\n",(0,a.jsx)(t.p,{children:"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."}),"\n",(0,a.jsxs)(t.tabs,{children:["\n",(0,a.jsxs)(t.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.tabitem,{value:"py",label:"Python",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"tip",children:(0,a.jsxs)(t.p,{children:["You can find online peers for Mainnet at ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," or testnet at ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live",children:"testnet.cspr.live"})]})}),"\n",(0,a.jsx)(t.p,{children:"There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end."}),"\n",(0,a.jsx)(t.p,{children:"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."}),"\n",(0,a.jsx)(t.p,{children:"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."}),"\n",(0,a.jsx)(t.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,a.jsxs)(t.p,{children:["The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,a.jsx)(t.a,{href:"/next/developers/json-rpc/json-rpc-transactional",children:"transactional"}),", ",(0,a.jsx)(t.a,{href:"/next/developers/json-rpc/json-rpc-informational",children:"informational"}),", and ",(0,a.jsx)(t.a,{href:"/next/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake"})," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."]}),"\n",(0,a.jsxs)(t.p,{children:["More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,a.jsx)(t.a,{href:"https://webassembly.org/",children:"WebAssembly"})," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,a.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"Rust"})," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."]}),"\n",(0,a.jsxs)(t.p,{children:["To learn how to write smart contracts for your dApp, read the ",(0,a.jsx)(t.a,{href:"/next/writing-contracts",children:"smart contract documentation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const r={},o=a.createContext(r);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9deb425.4b3ac4cb.js b/assets/js/a9deb425.4b3ac4cb.js new file mode 100644 index 000000000..35028db41 --- /dev/null +++ b/assets/js/a9deb425.4b3ac4cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55157],{25943:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>l});var a=n(74848),r=n(28453);const o={},s="dApp Technology Stack",i={id:"developers/dapps/technology-stack",title:"dApp Technology Stack",description:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.",source:"@site/docs/developers/dapps/technology-stack.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/technology-stack",permalink:"/developers/dapps/technology-stack",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"},next:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"}},c={},l=[{value:"Front-End",id:"front-end",level:2},{value:"Signing Transactions",id:"signing-transactions",level:3},{value:"Querying Global State",id:"querying-global-state",level:3},{value:"Backend",id:"backend",level:2},{value:"Blockchain",id:"blockchain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"dapp-technology-stack",children:"dApp Technology Stack"})}),"\n",(0,a.jsx)(t.p,{children:"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each."}),"\n",(0,a.jsx)(t.h2,{id:"front-end",children:"Front-End"}),"\n",(0,a.jsxs)(t.p,{children:["The front-end, or ",(0,a.jsx)(t.em,{children:"client-side"})," of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried."]}),"\n",(0,a.jsxs)(t.p,{children:["You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS"})," requirements."]}),"\n",(0,a.jsx)(t.h3,{id:"signing-transactions",children:"Signing Transactions"}),"\n",(0,a.jsx)(t.p,{children:"The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:"}),"\n",(0,a.jsxs)(t.ol,{children:["\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"The Casper Wallet"}),"\n",(0,a.jsxs)(t.p,{children:["Use the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Casper Wallet"})," to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node."]}),"\n",(0,a.jsx)(t.admonition,{type:"caution",children:(0,a.jsxs)(t.p,{children:["The Casper Signer has been deprecated and replaced with the ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"}),". We are in the process of updating this page. Meanwhile, visit the guide on ",(0,a.jsx)(t.a,{href:"https://www.casperwallet.io/develop",children:"Building with the Casper Wallet"}),"."]})}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["\n",(0,a.jsx)(t.p,{children:"Third-party signers"}),"\n",(0,a.jsx)(t.p,{children:"Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object."}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.h3,{id:"querying-global-state",children:"Querying Global State"}),"\n",(0,a.jsx)(t.p,{children:"To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query."}),"\n",(0,a.jsx)(t.h2,{id:"backend",children:"Backend"}),"\n",(0,a.jsxs)(t.p,{children:["The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect ",(0,a.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS",children:"CORS headers"})," from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain."]}),"\n",(0,a.jsx)(t.p,{children:"As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to."}),"\n",(0,a.jsxs)(t.tabs,{children:["\n",(0,a.jsxs)(t.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");\n'})}),"\n"]}),"\n",(0,a.jsxs)(t.tabitem,{value:"py",label:"Python",children:["\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-javascript",children:'client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n'})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(t.admonition,{type:"tip",children:(0,a.jsxs)(t.p,{children:["You can find online peers for Mainnet at ",(0,a.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"})," or testnet at ",(0,a.jsx)(t.a,{href:"https://testnet.cspr.live",children:"testnet.cspr.live"})]})}),"\n",(0,a.jsx)(t.p,{children:"There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end."}),"\n",(0,a.jsx)(t.p,{children:"Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end."}),"\n",(0,a.jsx)(t.p,{children:"In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along."}),"\n",(0,a.jsx)(t.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,a.jsxs)(t.p,{children:["The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-transactional",children:"transactional"}),", ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-informational",children:"informational"}),", and ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake"})," endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods."]}),"\n",(0,a.jsxs)(t.p,{children:["More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as ",(0,a.jsx)(t.a,{href:"https://webassembly.org/",children:"WebAssembly"})," binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in ",(0,a.jsx)(t.a,{href:"https://www.rust-lang.org/",children:"Rust"})," for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust."]}),"\n",(0,a.jsxs)(t.p,{children:["To learn how to write smart contracts for your dApp, read the ",(0,a.jsx)(t.a,{href:"/writing-contracts",children:"smart contract documentation"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>i});var a=n(96540);const r={},o=a.createContext(r);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9f5564d.2e90b9b1.js b/assets/js/a9f5564d.2e90b9b1.js deleted file mode 100644 index 1805f0672..000000000 --- a/assets/js/a9f5564d.2e90b9b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9235],{66428:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),o=t(28453);const i={title:"Genesis"},c="The Genesis Block {#the-genesis-block}",r={id:"operators/setup-network/genesis",title:"Genesis",description:"the-genesis-block}",source:"@site/docs/operators/setup-network/genesis.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/genesis",permalink:"/next/operators/setup-network/genesis",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Genesis"},sidebar:"operators",previous:{title:"Setting up Private Networks",permalink:"/next/operators/setup-network/"},next:{title:"The Chainspec",permalink:"/next/operators/setup-network/chain-spec"}},a={},l=[{value:"chainspec.toml",id:"chainspectoml",level:2},{value:"accounts.toml",id:"accountstoml",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"the-genesis-block",children:"The Genesis Block"})}),"\n",(0,s.jsx)(n.p,{children:"The Casper node software creates a genesis block from the following input files:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"chainspec.toml"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"accounts.toml"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,s.jsxs)(n.p,{children:["A version of the ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"})," is downloaded by the ",(0,s.jsx)(n.code,{children:"pull_casper_node_version.sh"})," script installed with the casper-node-launcher debian package. This script pulls the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file from the appropriate path defined in the network config file used (",(0,s.jsx)(n.code,{children:"casper.conf"})," for MainNet and ",(0,s.jsx)(n.code,{children:"casper-test.conf"})," for TestNet)."]}),"\n",(0,s.jsxs)(n.p,{children:["The production version of the file from which this is based on can be found at ",(0,s.jsx)(n.code,{children:"casper-node/resources/production/chainspec.toml"})," in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to ",(0,s.jsx)(n.a,{href:"/next/operators/setup-network/chain-spec",children:"this page"})," for detailed documentation on each of the variables in the file."]}),"\n",(0,s.jsx)(n.h2,{id:"accountstoml",children:"accounts.toml"}),"\n",(0,s.jsx)(n.p,{children:"This file contains the genesis validator set information, starting accounts and associated balances and bond amounts."}),"\n",(0,s.jsxs)(n.p,{children:["If an account is not bonded at genesis, specify a ",(0,s.jsx)(n.code,{children:"0"})," for the bond amount."]}),"\n",(0,s.jsxs)(n.p,{children:["Similar to the ",(0,s.jsx)(n.code,{children:"chainspec.toml"}),", this is pulled from the appropriate path defined in the network config file used."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>r});var s=t(96540);const o={},i=s.createContext(o);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/a9f5564d.7ae89e3b.js b/assets/js/a9f5564d.7ae89e3b.js new file mode 100644 index 000000000..e84d797d7 --- /dev/null +++ b/assets/js/a9f5564d.7ae89e3b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79235],{66428:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=s(74848),o=s(28453);const i={title:"Genesis"},c="The Genesis Block {#the-genesis-block}",r={id:"operators/setup-network/genesis",title:"Genesis",description:"the-genesis-block}",source:"@site/docs/operators/setup-network/genesis.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/genesis",permalink:"/operators/setup-network/genesis",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Genesis"},sidebar:"operators",previous:{title:"Setting up Private Networks",permalink:"/operators/setup-network/"},next:{title:"The Chainspec",permalink:"/operators/setup-network/chain-spec"}},a={},l=[{value:"chainspec.toml",id:"chainspectoml",level:2},{value:"accounts.toml",id:"accountstoml",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"the-genesis-block",children:"The Genesis Block"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper node software creates a genesis block from the following input files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"chainspec.toml"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"accounts.toml"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,t.jsxs)(n.p,{children:["A version of the ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"})," is downloaded by the ",(0,t.jsx)(n.code,{children:"pull_casper_node_version.sh"})," script installed with the casper-node-launcher debian package. This script pulls the ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," file from the appropriate path defined in the network config file used (",(0,t.jsx)(n.code,{children:"casper.conf"})," for MainNet and ",(0,t.jsx)(n.code,{children:"casper-test.conf"})," for TestNet)."]}),"\n",(0,t.jsxs)(n.p,{children:["The production version of the file from which this is based on can be found at ",(0,t.jsx)(n.code,{children:"casper-node/resources/production/chainspec.toml"})," in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to ",(0,t.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"this page"})," for detailed documentation on each of the variables in the file."]}),"\n",(0,t.jsx)(n.h2,{id:"accountstoml",children:"accounts.toml"}),"\n",(0,t.jsx)(n.p,{children:"This file contains the genesis validator set information, starting accounts and associated balances and bond amounts."}),"\n",(0,t.jsxs)(n.p,{children:["If an account is not bonded at genesis, specify a ",(0,t.jsx)(n.code,{children:"0"})," for the bond amount."]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the ",(0,t.jsx)(n.code,{children:"chainspec.toml"}),", this is pulled from the appropriate path defined in the network config file used."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aa162190.1c22b5a0.js b/assets/js/aa162190.1c22b5a0.js deleted file mode 100644 index 303d978aa..000000000 --- a/assets/js/aa162190.1c22b5a0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1512],{93573:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const o={},c="O",a={id:"concepts/glossary/O",title:"O",description:"---",source:"@site/docs/concepts/glossary/O.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/O",permalink:"/next/concepts/glossary/O",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"N",permalink:"/next/concepts/glossary/N"},next:{title:"P",permalink:"/next/concepts/glossary/P"}},l={},h=[{value:"Operator",id:"operator",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"o",children:"O"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"operator",children:"Operator"}),"\n",(0,r.jsx)(s.p,{children:"Anyone running a node is an\xa0operator."}),"\n",(0,r.jsx)(s.p,{children:"An operator that has staked a bid but does not currently have a validator slot is a\xa0*staked operator*."}),"\n",(0,r.jsxs)(s.p,{children:["An operator whose bid has won a validator slot in the auction for a specific era is a\xa0",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V#validator",children:"validator"}),"\xa0in that era."]}),"\n",(0,r.jsxs)(s.p,{children:["It is common for a ",(0,r.jsx)(s.em,{children:"staked operator"})," to win an auction slot for many eras in a row and thus be a validator for a range of eras."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var r=n(96540);const t={},o=r.createContext(t);function c(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aa162190.42fe6ae5.js b/assets/js/aa162190.42fe6ae5.js new file mode 100644 index 000000000..29c15f1c9 --- /dev/null +++ b/assets/js/aa162190.42fe6ae5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[71512],{93573:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>t,toc:()=>h});var n=r(74848),o=r(28453);const c={},a="O",t={id:"concepts/glossary/O",title:"O",description:"---",source:"@site/docs/concepts/glossary/O.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/O",permalink:"/concepts/glossary/O",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"N",permalink:"/concepts/glossary/N"},next:{title:"P",permalink:"/concepts/glossary/P"}},l={},h=[{value:"Operator",id:"operator",level:2}];function i(s){const e={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"o",children:"O"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"operator",children:"Operator"}),"\n",(0,n.jsx)(e.p,{children:"Anyone running a node is an\xa0operator."}),"\n",(0,n.jsx)(e.p,{children:"An operator that has staked a bid but does not currently have a validator slot is a\xa0*staked operator*."}),"\n",(0,n.jsxs)(e.p,{children:["An operator whose bid has won a validator slot in the auction for a specific era is a\xa0",(0,n.jsx)(e.a,{href:"/concepts/glossary/V#validator",children:"validator"}),"\xa0in that era."]}),"\n",(0,n.jsxs)(e.p,{children:["It is common for a ",(0,n.jsx)(e.em,{children:"staked operator"})," to win an auction slot for many eras in a row and thus be a validator for a range of eras."]})]})}function d(s={}){const{wrapper:e}={...(0,o.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>a,x:()=>t});var n=r(96540);const o={},c=n.createContext(o);function a(s){const e=n.useContext(c);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function t(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(o):s.components||o:a(s.components),n.createElement(c.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/aafbba97.658201c7.js b/assets/js/aafbba97.658201c7.js deleted file mode 100644 index 3f94b0faf..000000000 --- a/assets/js/aafbba97.658201c7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2986],{40261:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"Using CSPR.live"},c="Using the CSPR.live block explorer",l={id:"users/csprlive/index",title:"Using CSPR.live",description:"| Topic | Description |",source:"@site/docs/users/csprlive/index.md",sourceDirName:"users/csprlive",slug:"/users/csprlive/",permalink:"/next/users/csprlive/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Using CSPR.live"},sidebar:"users",previous:{title:"Delegating Tokens",permalink:"/next/users/delegating"},next:{title:"Testnet Funding",permalink:"/next/users/testnet-faucet"}},d={},o=[];function a(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-the-csprlive-block-explorer",children:"Using the CSPR.live block explorer"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,s.jsx)(n.td,{children:"Fund a Testnet account for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/users/token-transfer",children:"Transferring Tokens"})}),(0,s.jsx)(n.td,{children:"Transfer tokens using the CSPR.live block explorer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/users/delegate-ui",children:"Delegating Tokens"})}),(0,s.jsx)(n.td,{children:"Delegate tokens to a validator"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,s.jsx)(n.td,{children:"Undelegate tokens from a validator"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aafbba97.d6419f85.js b/assets/js/aafbba97.d6419f85.js new file mode 100644 index 000000000..8d25788ee --- /dev/null +++ b/assets/js/aafbba97.d6419f85.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92986],{40261:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>o});var s=t(74848),r=t(28453);const i={title:"Using CSPR.live"},c="Using the CSPR.live block explorer",l={id:"users/csprlive/index",title:"Using CSPR.live",description:"| Topic | Description |",source:"@site/docs/users/csprlive/index.md",sourceDirName:"users/csprlive",slug:"/users/csprlive/",permalink:"/users/csprlive/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Using CSPR.live"},sidebar:"users",previous:{title:"Delegating Tokens",permalink:"/users/delegating"},next:{title:"Testnet Funding",permalink:"/users/testnet-faucet"}},d={},o=[];function a(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"using-the-csprlive-block-explorer",children:"Using the CSPR.live block explorer"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,s.jsx)(n.td,{children:"Fund a Testnet account for testing"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens"})}),(0,s.jsx)(n.td,{children:"Transfer tokens using the CSPR.live block explorer"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating Tokens"})}),(0,s.jsx)(n.td,{children:"Delegate tokens to a validator"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,s.jsx)(n.td,{children:"Undelegate tokens from a validator"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>l});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ab246697.680665e7.js b/assets/js/ab246697.680665e7.js deleted file mode 100644 index 1931c4a70..000000000 --- a/assets/js/ab246697.680665e7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9756],{884:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>h,contentTitle:()=>o,default:()=>x,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=n(74848),r=n(28453);const c={},o="H",a={id:"concepts/glossary/H",title:"H",description:"---",source:"@site/docs/concepts/glossary/H.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/H",permalink:"/next/concepts/glossary/H",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"G",permalink:"/next/concepts/glossary/G"},next:{title:"I",permalink:"/next/concepts/glossary/I"}},h={},l=[{value:"Hash",id:"hash",level:2},{value:"Highway",id:"highway",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"h",children:"H"})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.h2,{id:"hash",children:"Hash"}),"\n",(0,t.jsxs)(s.p,{children:["A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#blake2b",children:"blake2b"})," function."]}),"\n",(0,t.jsx)(s.h2,{id:"highway",children:"Highway"}),"\n",(0,t.jsxs)(s.p,{children:["A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is ",(0,t.jsx)(s.em,{children:"finalized"}),". The full paper is found in GitHub: ",(0,t.jsx)(s.a,{href:"https://github.com/casper-network/highway",children:"https://github.com/casper-network/highway"}),"."]})]})}function x(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var t=n(96540);const r={},c=t.createContext(r);function o(e){const s=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ab246697.e9ff96c3.js b/assets/js/ab246697.e9ff96c3.js new file mode 100644 index 000000000..3892c1b43 --- /dev/null +++ b/assets/js/ab246697.e9ff96c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59756],{884:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>h,contentTitle:()=>o,default:()=>p,frontMatter:()=>t,metadata:()=>a,toc:()=>l});var n=r(74848),c=r(28453);const t={},o="H",a={id:"concepts/glossary/H",title:"H",description:"---",source:"@site/docs/concepts/glossary/H.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/H",permalink:"/concepts/glossary/H",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"G",permalink:"/concepts/glossary/G"},next:{title:"I",permalink:"/concepts/glossary/I"}},h={},l=[{value:"Hash",id:"hash",level:2},{value:"Highway",id:"highway",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"h",children:"H"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"hash",children:"Hash"}),"\n",(0,n.jsxs)(s.p,{children:["A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B#blake2b",children:"blake2b"})," function."]}),"\n",(0,n.jsx)(s.h2,{id:"highway",children:"Highway"}),"\n",(0,n.jsxs)(s.p,{children:["A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is ",(0,n.jsx)(s.em,{children:"finalized"}),". The full paper is found in GitHub: ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/highway",children:"https://github.com/casper-network/highway"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>a});var n=r(96540);const c={},t=n.createContext(c);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ab991e0e.54fa42af.js b/assets/js/ab991e0e.54fa42af.js deleted file mode 100644 index d79e6b703..000000000 --- a/assets/js/ab991e0e.54fa42af.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[56],{71353:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(74848),o=n(28453);const s={title:"Introduction",slug:"/counter"},i="A Counter on an NCTL Network",a={id:"resources/beginner/counter/index",title:"Introduction",description:"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/docs/resources/beginner/counter/index.md",sourceDirName:"resources/beginner/counter",slug:"/counter",permalink:"/next/counter",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Introduction",slug:"/counter"},sidebar:"tutorials",previous:{title:"Getting Started",permalink:"/next/resources/tutorials/beginner/getting-started-tutorial"},next:{title:"Overview",permalink:"/next/resources/beginner/counter/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"a-counter-on-an-nctl-network",children:"A Counter on an NCTL Network"})}),"\n",(0,r.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a ",(0,r.jsx)(t.a,{href:"/next/counter-testnet",children:"similar tutorial"}),". Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,r.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["You have completed the ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,r.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,r.jsx)(t.em,{children:"cargo"}),", and ",(0,r.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["You have completed the ",(0,r.jsx)(t.a,{href:"/next/developers/dapps/setup-nctl",children:"NCTL tutorial"}),", which introduces you to the CLI tool to set up and control local Casper networks for development."]}),"\n",(0,r.jsxs)(t.li,{children:["You have installed the ",(0,r.jsx)(t.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ab991e0e.afb1898b.js b/assets/js/ab991e0e.afb1898b.js new file mode 100644 index 000000000..d6c41cac1 --- /dev/null +++ b/assets/js/ab991e0e.afb1898b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27675],{71353:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter"},i="A Counter on an NCTL Network",a={id:"resources/beginner/counter/index",title:"Introduction",description:"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/docs/resources/beginner/counter/index.md",sourceDirName:"resources/beginner/counter",slug:"/counter",permalink:"/counter",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Introduction",slug:"/counter"},sidebar:"tutorials",previous:{title:"Getting Started",permalink:"/resources/tutorials/beginner/getting-started-tutorial"},next:{title:"Overview",permalink:"/resources/beginner/counter/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-an-nctl-network",children:"A Counter on an NCTL Network"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a ",(0,n.jsx)(t.a,{href:"/counter-testnet",children:"similar tutorial"}),". Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/dapps/setup-nctl",children:"NCTL tutorial"}),", which introduces you to the CLI tool to set up and control local Casper networks for development."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aba21aa0.1ae003ba.js b/assets/js/aba21aa0.1ae003ba.js new file mode 100644 index 000000000..ac434f7c8 --- /dev/null +++ b/assets/js/aba21aa0.1ae003ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35742],{27093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/aba21aa0.9fadd1f0.js b/assets/js/aba21aa0.9fadd1f0.js deleted file mode 100644 index b11ada0c7..000000000 --- a/assets/js/aba21aa0.9fadd1f0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5742],{27093:s=>{s.exports=JSON.parse('{"name":"docusaurus-plugin-content-docs","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/abd56c27.10b1808e.js b/assets/js/abd56c27.10b1808e.js new file mode 100644 index 000000000..e1f1f2e1b --- /dev/null +++ b/assets/js/abd56c27.10b1808e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97267],{5804:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(74848),a=n(28453);const o={title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},i="Interacting with Runtime Return Values",s={id:"resources/advanced/return-values-tutorial",title:"Runtime Return Values",description:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/return-values-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/return-values-tutorial",permalink:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},sidebar:"tutorials",previous:{title:"Additional Examples",permalink:"/1.5.X/resources/advanced/multi-sig/other-scenarios"},next:{title:"Authorization Keys",permalink:"/1.5.X/resources/advanced/list-auth-keys-tutorial"}},c={},d=[{value:"Contract Code",id:"return-contract-code",level:2},{value:"Session Code",id:"return-session-code",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"interacting-with-runtime-return-values",children:"Interacting with Runtime Return Values"})}),"\n",(0,r.jsx)(t.p,{children:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code."}),"\n",(0,r.jsx)(t.p,{children:"Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers."}),"\n",(0,r.jsxs)(t.p,{children:["Contract code can optionally return a value to their immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"}),", whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance."]}),"\n",(0,r.jsx)(t.p,{children:"Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything."}),"\n",(0,r.jsx)(t.h2,{id:"return-contract-code",children:"Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["For example, if we create a contract to accept and keep a record of donations, we would use ",(0,r.jsx)(t.code,{children:"runtime::ret()"})," to define the results that should be passed to the caller as per the following:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn donate() {\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n if let Key::Account(donating_account_hash) = donating_account_key {\n update_ledger_record(donating_account_hash.to_string())\n } else {\n runtime::revert(FundRaisingError::InvalidKeyVariant)\n }\n let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)\n .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)\n .as_uref()\n .unwrap_or_revert();\n let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();\n runtime::ret(value)\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["In this example, the return value is the URef corresponding to the purse used to raise funds, with ",(0,r.jsx)(t.code,{children:"add"})," permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the ",(0,r.jsx)(t.code,{children:"donate"})," entry point."]}),"\n",(0,r.jsxs)(t.p,{children:["Without the addition of the ",(0,r.jsx)(t.code,{children:"runtime::ret"}),", the purse would not be returned to the caller."]}),"\n",(0,r.jsx)(t.h2,{id:"return-session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["The following is an example of session code calling the ",(0,r.jsx)(t.a,{href:"#return-contract-code",children:"specified entry point"}),". Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);\n\n let donating_purse_uref: URef = runtime::call_contract(\n fundraiser_contract_hash,\n ENTRY_POINT_DONATE,\n runtime_args! {\n DONATING_ACCOUNT_KEY => donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["This session code calls into a contract's entry point by using ",(0,r.jsx)(t.code,{children:"runtime::call_contract"}),", supplying the ",(0,r.jsx)(t.code,{children:"contract_hash"})," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,r.jsx)(t.code,{children:"donate"}),". It supplies the ",(0,r.jsx)(t.code,{children:"donating_account_key"}),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,r.jsx)(t.code,{children:"donating_purse_uref"}),". To call an entry point, you will need to know the ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:"CLType"})," of the return value and identify it within the code."]}),"\n",(0,r.jsxs)(t.p,{children:["You can determine the type of the return value by ",(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-an-account",children:"querying the contract object"})," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."]}),"\n",(0,r.jsxs)(t.p,{children:["This example code takes that returned value and transfers a ",(0,r.jsx)(t.code,{children:"donation_amount"})," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const a={},o=r.createContext(a);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/abd56c27.bf3ed5c3.js b/assets/js/abd56c27.bf3ed5c3.js deleted file mode 100644 index 7f2d6813e..000000000 --- a/assets/js/abd56c27.bf3ed5c3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7267],{5804:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(74848),a=n(28453);const o={title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},i="Interacting with Runtime Return Values",s={id:"resources/advanced/return-values-tutorial",title:"Runtime Return Values",description:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/return-values-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/return-values-tutorial",permalink:"/resources/tutorials/advanced/return-values-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},sidebar:"tutorials",previous:{title:"Additional Examples",permalink:"/resources/advanced/multi-sig/other-scenarios"},next:{title:"Authorization Keys",permalink:"/resources/advanced/list-auth-keys-tutorial"}},c={},d=[{value:"Contract Code",id:"return-contract-code",level:2},{value:"Session Code",id:"return-session-code",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"interacting-with-runtime-return-values",children:"Interacting with Runtime Return Values"})}),"\n",(0,r.jsx)(t.p,{children:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code."}),"\n",(0,r.jsx)(t.p,{children:"Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers."}),"\n",(0,r.jsxs)(t.p,{children:["Contract code can optionally return a value to their immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"}),", whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance."]}),"\n",(0,r.jsx)(t.p,{children:"Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything."}),"\n",(0,r.jsx)(t.h2,{id:"return-contract-code",children:"Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["For example, if we create a contract to accept and keep a record of donations, we would use ",(0,r.jsx)(t.code,{children:"runtime::ret()"})," to define the results that should be passed to the caller as per the following:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn donate() {\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n if let Key::Account(donating_account_hash) = donating_account_key {\n update_ledger_record(donating_account_hash.to_string())\n } else {\n runtime::revert(FundRaisingError::InvalidKeyVariant)\n }\n let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)\n .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)\n .as_uref()\n .unwrap_or_revert();\n let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();\n runtime::ret(value)\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["In this example, the return value is the URef corresponding to the purse used to raise funds, with ",(0,r.jsx)(t.code,{children:"add"})," permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the ",(0,r.jsx)(t.code,{children:"donate"})," entry point."]}),"\n",(0,r.jsxs)(t.p,{children:["Without the addition of the ",(0,r.jsx)(t.code,{children:"runtime::ret"}),", the purse would not be returned to the caller."]}),"\n",(0,r.jsx)(t.h2,{id:"return-session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["The following is an example of session code calling the ",(0,r.jsx)(t.a,{href:"#return-contract-code",children:"specified entry point"}),". Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);\n\n let donating_purse_uref: URef = runtime::call_contract(\n fundraiser_contract_hash,\n ENTRY_POINT_DONATE,\n runtime_args! {\n DONATING_ACCOUNT_KEY => donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["This session code calls into a contract's entry point by using ",(0,r.jsx)(t.code,{children:"runtime::call_contract"}),", supplying the ",(0,r.jsx)(t.code,{children:"contract_hash"})," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,r.jsx)(t.code,{children:"donate"}),". It supplies the ",(0,r.jsx)(t.code,{children:"donating_account_key"}),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,r.jsx)(t.code,{children:"donating_purse_uref"}),". To call an entry point, you will need to know the ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_cl",children:"CLType"})," of the return value and identify it within the code."]}),"\n",(0,r.jsxs)(t.p,{children:["You can determine the type of the return value by ",(0,r.jsx)(t.a,{href:"/resources/tutorials/beginner/querying-network#querying-an-account",children:"querying the contract object"})," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."]}),"\n",(0,r.jsxs)(t.p,{children:["This example code takes that returned value and transfers a ",(0,r.jsx)(t.code,{children:"donation_amount"})," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const a={},o=r.createContext(a);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac16ac20.7b905f4c.js b/assets/js/ac16ac20.7b905f4c.js new file mode 100644 index 000000000..7a910d112 --- /dev/null +++ b/assets/js/ac16ac20.7b905f4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67280],{7737:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>d,toc:()=>a});var o=s(74848),r=s(28453);const t={title:"Non-Root Users"},i="Setting up a Non-Root User",d={id:"operators/setup/non-root-user",title:"Non-Root Users",description:"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.",source:"@site/versioned_docs/version-2.0.0/operators/setup/non-root-user.md",sourceDirName:"operators/setup",slug:"/operators/setup/non-root-user",permalink:"/2.0.0/operators/setup/non-root-user",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Non-Root Users"},sidebar:"operators",previous:{title:"Join a Network",permalink:"/2.0.0/operators/setup/joining"},next:{title:"Node Events",permalink:"/2.0.0/operators/setup/node-events"}},c={},a=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"setting-up-a-non-root-user",children:"Setting up a Non-Root User"})}),"\n",(0,o.jsxs)(n.p,{children:["Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace ",(0,o.jsx)(n.code,{children:"<username>"})," in the instructions below with your username."]}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use ",(0,o.jsx)(n.a,{href:"https://www.ssh.com/academy/ssh/keygen",children:"ssh-keygen"})," to generate a new SSH key."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsx)(n.p,{children:"Create the user with no password, as the key is your password."}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo adduser <username> --disabled-password\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"3",children:["\n",(0,o.jsx)(n.li,{children:"Create authorized_keys with your key to log in."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo su - <username>\nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"4",children:["\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Use the editor of your choice and paste your .ssh public key i the ",(0,o.jsx)(n.code,{children:".ssh/authorized_keys"})," file."]}),"\n"]}),"\n",(0,o.jsxs)(n.li,{children:["\n",(0,o.jsxs)(n.p,{children:["Exit out of the ",(0,o.jsx)(n.code,{children:"<username>"})," account and log into the root or previous sudo-er account."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"exit\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"6",children:["\n",(0,o.jsx)(n.li,{children:"Add your user to sudo-ers under the root account or your previous sudo-er account."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo visudo\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"7",children:["\n",(0,o.jsxs)(n.li,{children:["Type ",(0,o.jsx)(n.code,{children:"<username> ALL=(ALL:ALL) NOPASSWD:ALL"})," below the row containing ",(0,o.jsx)(n.code,{children:"root ALL=(ALL:ALL) ALL"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n<username> ALL=(ALL:ALL) NOPASSWD:ALL\n"})}),"\n",(0,o.jsxs)(n.ol,{start:"8",children:["\n",(0,o.jsx)(n.li,{children:"You should be able to log in with the key and not use the root user."}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i <your ssh private key> <username>@<server ip>\n"})}),"\n",(0,o.jsx)(n.p,{children:"Here is an example command:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n"})})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var o=s(96540);const r={},t=o.createContext(r);function i(e){const n=o.useContext(t);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac361b55.023b05ee.js b/assets/js/ac361b55.023b05ee.js new file mode 100644 index 000000000..077d00e7f --- /dev/null +++ b/assets/js/ac361b55.023b05ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43019],{70:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>o,frontMatter:()=>a,metadata:()=>t,toc:()=>l});var c=d(74848),s=d(28453);const a={},r="Informational JSON-RPC Methods {#informational}",t={id:"developers/json-rpc/json-rpc-informational",title:"Informational JSON-RPC Methods",description:"informational}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-informational.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-informational",permalink:"/1.5.X/developers/json-rpc/json-rpc-informational",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Transactional JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-transactional"},next:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-pos"}},i={},l=[{value:"chain_get_block",id:"chain-get-block",level:2},{value:"<code>chain_get_block_result</code>",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain-get-block-transfers",level:2},{value:"<code>chain_get_block_transfers_result</code>",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain-get-era-summary",level:2},{value:"<code>chain_get_era_summary_result</code>",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain-get-state-root-hash",level:2},{value:"<code>chain_get_state_root_hash_result</code>",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info-get-chainspec",level:2},{value:"<code>info_get_chainspec_result</code>",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info-get-deploy",level:2},{value:"<code>info_get_deploy_result</code>",id:"info_get_deploy_result",level:3},{value:"query_balance",id:"query-balance",level:2},{value:"<code>query_balance_result</code>",id:"query_balance_result",level:3},{value:"query_global_state",id:"query-global-state",level:2},{value:"<code>query_global_state_result</code>",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state-get-account-info",level:2},{value:"<code>state_get_account_info_result</code>",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state-get-dictionary-item",level:2},{value:"<code>state_get_dictionary_item_result</code>",id:"state_get_dictionary_item_result",level:3},{value:"info_get_peers",id:"info-get-peers",level:2},{value:"<code>info_get_peers_result</code>",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info-get-status",level:2},{value:"<code>info_get_status_result</code>",id:"info_get_status_result",level:3}];function h(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"informational",children:"Informational JSON-RPC Methods"})}),"\n",(0,c.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-block",children:"chain_get_block"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns the JSON representation of a ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block-structure-head",children:"Block"})," from the network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash or the Block height."})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_block_result",children:(0,c.jsx)(n.code,{children:"chain_get_block_result"})}),"\n",(0,c.jsxs)(n.p,{children:["The result from ",(0,c.jsx)(n.code,{children:"chain_get_block"})," depends on block availability from a given node. If ",(0,c.jsx)(n.code,{children:"chain_get_block"})," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#jsonblock",children:"block"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block, if found. (Not required)"})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "transfer_hashes": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n ]\n },\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-block-transfers",children:"chain_get_block_transfers"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns all ",(0,c.jsx)(n.strong,{children:"successful"})," native transfers within a given ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block-structure-head",children:"Block"})," from a network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash."})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block_transfers request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_block_transfers_result",children:(0,c.jsx)(n.code,{children:"chain_get_block_transfers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash, if found."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#transfer",children:"transfers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The Block's successful transfers, if found."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block_transfers result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "transfers": [\n {\n "amount": "0",\n "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",\n "gas": "0",\n "id": null,\n "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "to": null\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-era-summary",children:"chain_get_era_summary"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns the era summary at a given ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,c.jsx)(n.code,{children:"block_identifier"}),", you will receive the era summary at the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_era_summary request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_era_summary_result",children:(0,c.jsx)(n.code,{children:"chain_get_era_summary_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The era summary (if found)."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_era_summary result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "api_version": "1.0.0",\n "era_summary": {\n "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",\n "era_id": 1,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "53472520551166781393617756"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "54552773491594393138943367"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "51312014670568117976319374"\n }\n },\n {\n "Validator": {\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "56713279372733183026458256"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "51852141140784624481333262"\n }\n },\n {\n "Validator": {\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "56173152902516676521444368"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "52392267611001130986347150"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "55633026432300170016430480"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "52932394080952975520954950"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "55092899961808199011606173"\n }\n }\n ]\n }\n },\n "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",\n "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-state-root-hash",children:"chain_get_state_root_hash"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns a state root hash at a given ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,c.jsx)(n.code,{children:"block_identifier"}),", you will receive the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_state_root_hash request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "Height": 10\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_state_root_hash_result",children:(0,c.jsx)(n.code,{children:"chain_get_state_root_hash_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Hex-encoded hash of the state root."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_state_root_hash result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-chainspec",children:"info_get_chainspec"}),"\n",(0,c.jsx)(n.p,{children:"This method returns raw bytes for chainspec files."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_chainspec request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_chainspec_result",children:(0,c.jsx)(n.code,{children:"info_get_chainspec_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#chainspecrawbytes",children:"chainspec_bytes"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_chainspec result"}),"\n",(0,c.jsxs)(n.p,{children:["Please note that adding a ",(0,c.jsx)(n.code,{children:"--vv"})," flag will return the full chainspec bytes."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n },\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-deploy",children:"info_get_deploy"}),"\n",(0,c.jsxs)(n.p,{children:["This method retrieves a ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy"})," from a network. It requires a ",(0,c.jsx)(n.code,{children:"deploy_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The Deploy hash."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,c.jsx)(n.td,{children:"Boolean"}),(0,c.jsx)(n.td,{children:"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_deploy request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n true\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_deploy_result",children:(0,c.jsx)(n.code,{children:"info_get_deploy_result"})}),"\n",(0,c.jsx)(n.p,{children:"The response contains the Deploy and the results of executing the Deploy."}),"\n",(0,c.jsxs)(n.p,{children:["If the ",(0,c.jsx)(n.code,{children:"execution_results"})," field is empty, it means that the network processed the ",(0,c.jsx)(n.code,{children:"Deploy"}),", but has yet to execute it. If the network executed the ",(0,c.jsx)(n.code,{children:"Deploy"}),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Deploy."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#jsonexecutionresult",children:"execution_results"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"An array of execution results with Block hashes."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_deploy result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "chain_name": "casper-example",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ]\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "result": {\n "Success": {\n "cost": "123456",\n "effect": {\n "operations": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": "Write"\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Read"\n }\n ],\n "transforms": [\n {\n "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",\n "transform": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "transform": "Identity"\n }\n ]\n },\n "transfers": [\n "transfer-5959595959595959595959595959595959595959595959595959595959595959",\n "transfer-8282828282828282828282828282828282828282828282828282828282828282"\n ]\n }\n }\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"query-balance",children:"query_balance"}),"\n",(0,c.jsxs)(n.p,{children:["This method allows you to query for the balance of a purse using a ",(0,c.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,c.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_balance request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"query_balance_result",children:(0,c.jsx)(n.code,{children:"query_balance_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#u512",children:"balance"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The balance represented in motes."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_balance result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "api_version": "1.0.0",\n "balance": "1000000000000000000000000000000000"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"query-global-state",children:"query_global_state"}),"\n",(0,c.jsxs)(n.p,{children:["This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block_hash",children:"Block hash"})," or state root hash."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note: Querying a purse's balance requires the use of ",(0,c.jsx)(n.code,{children:"query_balance"}),", rather than any iteration of ",(0,c.jsx)(n.code,{children:"query_global_state"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The identifier used for the query."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"key"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsxs)(n.td,{children:[(0,c.jsx)(n.code,{children:"casper_types::Key"})," as a formatted string."]})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"path"}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The path components starting from the key as base."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_global_state request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n [],\n {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"query_global_state_result",children:(0,c.jsx)(n.code,{children:"query_global_state_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#jsonblockheader",children:"block_header"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block header if a Block hash was provided. (Not required)"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The stored value."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_global_state result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"state-get-account-info",children:"state_get_account_info"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,c.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Account"})," from the network. The ",(0,c.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the Account's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#publickey",children:"public_key"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The public key of the Account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block identifier."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_account_info request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n },\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"state_get_account_info_result",children:(0,c.jsx)(n.code,{children:"state_get_account_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#account",children:"account"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A JSON representation of the Account structure."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_account_info result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n },\n "api_version": "1.4.13",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"state-get-dictionary-item",children:"state_get_dictionary_item"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,c.jsx)(n.code,{children:"dictionary_identifier"}),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."]}),"\n",(0,c.jsx)(n.p,{children:"You may query a stored value directly using the dictionary address."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Hash of the state root."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#dictionaryidentifier",children:"dictionary_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Dictionary query identifier."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_dictionary_item request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "URef": {\n "dictionary_item_key": "a_unique_entry_identifier",\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n },\n "0808080808080808080808080808080808080808080808080808080808080808"\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"state_get_dictionary_item_result",children:(0,c.jsx)(n.code,{children:"state_get_dictionary_item_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"dictionary_key"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The key under which the value is stored."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The stored value."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_dictionary_item result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "CLValue": {\n "bytes": "0100000000000000",\n "cl_type": "U64",\n "parsed": 1\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h1,{id:"node-informational",children:"Node Informational JSON-RPC Methods"}),"\n",(0,c.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"info-get-peers",children:"info_get_peers"}),"\n",(0,c.jsx)(n.p,{children:"This method returns a list of peers connected to the node."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_peers request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_peers_result",children:(0,c.jsx)(n.code,{children:"info_get_peers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_peers result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "peers": [\n {\n "address": "127.0.0.1:54321",\n "node_id": "tls:0101..0101"\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-status",children:"info_get_status"}),"\n",(0,c.jsx)(n.p,{children:"This method returns the current status of a node."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_status request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_status_result",children:(0,c.jsx)(n.code,{children:"info_get_status_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#availableblockrange",children:"available_block_range"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The available block range in storage."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#blocksynchronizerstatus",children:"block_sync"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The status of the block synchronizer builders."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"build_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The compiled node version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"chainspec_name"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The chainspec name, used to identify the currently connected network."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#minimalblockinfo",children:"last_added_block_info"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The minimal info of the last Block from the linear chain."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#timestamp",children:"last_progress"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Timestamp of the last recorded progress in the reactor."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#nextupgrade",children:"next_upgrade"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"Information about the next scheduled upgrade."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#publickey",children:"our_public_signing_key"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Our public signing key."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#reactorstate",children:"reactor_state"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The current state of the node reactor."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#timediff",children:"round_length"})}),(0,c.jsx)(n.td,{children:"Integer"}),(0,c.jsx)(n.td,{children:"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#digest",children:"starting_state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The state root hash used at the start of the current session."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#timediff",children:"uptime"})}),(0,c.jsx)(n.td,{children:"Integer"}),(0,c.jsx)(n.td,{children:"Time that passed since the node has started."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_status result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "api_version": "1.4.8",\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": null,\n "last_added_block_info": {\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>r,x:()=>t});var c=d(96540);const s={},a=c.createContext(s);function r(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac361b55.a49eb8bd.js b/assets/js/ac361b55.a49eb8bd.js deleted file mode 100644 index e17f9ed6c..000000000 --- a/assets/js/ac361b55.a49eb8bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3019],{70:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>o,frontMatter:()=>a,metadata:()=>t,toc:()=>l});var c=d(74848),s=d(28453);const a={},r="Informational JSON-RPC Methods {#informational}",t={id:"developers/json-rpc/json-rpc-informational",title:"Informational JSON-RPC Methods",description:"informational}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-informational.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-informational",permalink:"/developers/json-rpc/json-rpc-informational",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Transactional JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-transactional"},next:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-pos"}},i={},l=[{value:"chain_get_block",id:"chain-get-block",level:2},{value:"<code>chain_get_block_result</code>",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain-get-block-transfers",level:2},{value:"<code>chain_get_block_transfers_result</code>",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain-get-era-summary",level:2},{value:"<code>chain_get_era_summary_result</code>",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain-get-state-root-hash",level:2},{value:"<code>chain_get_state_root_hash_result</code>",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info-get-chainspec",level:2},{value:"<code>info_get_chainspec_result</code>",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info-get-deploy",level:2},{value:"<code>info_get_deploy_result</code>",id:"info_get_deploy_result",level:3},{value:"query_balance",id:"query-balance",level:2},{value:"<code>query_balance_result</code>",id:"query_balance_result",level:3},{value:"query_global_state",id:"query-global-state",level:2},{value:"<code>query_global_state_result</code>",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state-get-account-info",level:2},{value:"<code>state_get_account_info_result</code>",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state-get-dictionary-item",level:2},{value:"<code>state_get_dictionary_item_result</code>",id:"state_get_dictionary_item_result",level:3},{value:"info_get_peers",id:"info-get-peers",level:2},{value:"<code>info_get_peers_result</code>",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info-get-status",level:2},{value:"<code>info_get_status_result</code>",id:"info_get_status_result",level:3}];function h(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"informational",children:"Informational JSON-RPC Methods"})}),"\n",(0,c.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-block",children:"chain_get_block"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns the JSON representation of a ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"})," from the network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash or the Block height."})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_block_result",children:(0,c.jsx)(n.code,{children:"chain_get_block_result"})}),"\n",(0,c.jsxs)(n.p,{children:["The result from ",(0,c.jsx)(n.code,{children:"chain_get_block"})," depends on block availability from a given node. If ",(0,c.jsx)(n.code,{children:"chain_get_block"})," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonblock",children:"block"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block, if found. (Not required)"})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "transfer_hashes": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n ]\n },\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-block-transfers",children:"chain_get_block_transfers"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns all ",(0,c.jsx)(n.strong,{children:"successful"})," native transfers within a given ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"})," from a network."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash."})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block_transfers request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_block_transfers_result",children:(0,c.jsx)(n.code,{children:"chain_get_block_transfers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash, if found."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#transfer",children:"transfers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The Block's successful transfers, if found."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_block_transfers result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "transfers": [\n {\n "amount": "0",\n "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",\n "gas": "0",\n "id": null,\n "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",\n "to": null\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-era-summary",children:"chain_get_era_summary"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns the era summary at a given ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,c.jsx)(n.code,{children:"block_identifier"}),", you will receive the era summary at the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_era_summary request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_era_summary_result",children:(0,c.jsx)(n.code,{children:"chain_get_era_summary_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The era summary (if found)."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_era_summary result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "api_version": "1.0.0",\n "era_summary": {\n "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",\n "era_id": 1,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "53472520551166781393617756"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",\n "amount": "54552773491594393138943367"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "51312014670568117976319374"\n }\n },\n {\n "Validator": {\n "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",\n "amount": "56713279372733183026458256"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "51852141140784624481333262"\n }\n },\n {\n "Validator": {\n "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",\n "amount": "56173152902516676521444368"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "52392267611001130986347150"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",\n "amount": "55633026432300170016430480"\n }\n },\n {\n "Delegator": {\n "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "52932394080952975520954950"\n }\n },\n {\n "Validator": {\n "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",\n "amount": "55092899961808199011606173"\n }\n }\n ]\n }\n },\n "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",\n "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"chain-get-state-root-hash",children:"chain_get_state_root_hash"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns a state root hash at a given ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,c.jsx)(n.code,{children:"block_identifier"}),", you will receive the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsx)(n.tbody,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_state_root_hash request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "Height": 10\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"chain_get_state_root_hash_result",children:(0,c.jsx)(n.code,{children:"chain_get_state_root_hash_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Hex-encoded hash of the state root."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example chain_get_state_root_hash result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-chainspec",children:"info_get_chainspec"}),"\n",(0,c.jsx)(n.p,{children:"This method returns raw bytes for chainspec files."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_chainspec request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_chainspec_result",children:(0,c.jsx)(n.code,{children:"info_get_chainspec_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#chainspecrawbytes",children:"chainspec_bytes"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_chainspec result"}),"\n",(0,c.jsxs)(n.p,{children:["Please note that adding a ",(0,c.jsx)(n.code,{children:"--vv"})," flag will return the full chainspec bytes."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n },\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-deploy",children:"info_get_deploy"}),"\n",(0,c.jsxs)(n.p,{children:["This method retrieves a ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy"})," from a network. It requires a ",(0,c.jsx)(n.code,{children:"deploy_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The Deploy hash."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,c.jsx)(n.td,{children:"Boolean"}),(0,c.jsx)(n.td,{children:"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_deploy request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n true\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_deploy_result",children:(0,c.jsx)(n.code,{children:"info_get_deploy_result"})}),"\n",(0,c.jsx)(n.p,{children:"The response contains the Deploy and the results of executing the Deploy."}),"\n",(0,c.jsxs)(n.p,{children:["If the ",(0,c.jsx)(n.code,{children:"execution_results"})," field is empty, it means that the network processed the ",(0,c.jsx)(n.code,{children:"Deploy"}),", but has yet to execute it. If the network executed the ",(0,c.jsx)(n.code,{children:"Deploy"}),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Deploy."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonexecutionresult",children:"execution_results"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"An array of execution results with Block hashes."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_deploy result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "chain_name": "casper-example",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "gas_price": 1,\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h"\n },\n "payment": {\n "StoredContractByName": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ],\n "entry_point": "example-entry-point",\n "name": "casper-example"\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "bytes": "e8030000",\n "cl_type": "I32",\n "parsed": 1000\n }\n ]\n ]\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "result": {\n "Success": {\n "cost": "123456",\n "effect": {\n "operations": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": "Write"\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Read"\n }\n ],\n "transforms": [\n {\n "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",\n "transform": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "transform": "Identity"\n }\n ]\n },\n "transfers": [\n "transfer-5959595959595959595959595959595959595959595959595959595959595959",\n "transfer-8282828282828282828282828282828282828282828282828282828282828282"\n ]\n }\n }\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"query-balance",children:"query_balance"}),"\n",(0,c.jsxs)(n.p,{children:["This method allows you to query for the balance of a purse using a ",(0,c.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,c.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_balance request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"query_balance_result",children:(0,c.jsx)(n.code,{children:"query_balance_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#u512",children:"balance"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The balance represented in motes."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_balance result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "api_version": "1.0.0",\n "balance": "1000000000000000000000000000000000"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"query-global-state",children:"query_global_state"}),"\n",(0,c.jsxs)(n.p,{children:["This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#block_hash",children:"Block hash"})," or state root hash."]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note: Querying a purse's balance requires the use of ",(0,c.jsx)(n.code,{children:"query_balance"}),", rather than any iteration of ",(0,c.jsx)(n.code,{children:"query_global_state"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The identifier used for the query."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"key"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsxs)(n.td,{children:[(0,c.jsx)(n.code,{children:"casper_types::Key"})," as a formatted string."]})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"path"}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The path components starting from the key as base."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_global_state request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n [],\n {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"query_global_state_result",children:(0,c.jsx)(n.code,{children:"query_global_state_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonblockheader",children:"block_header"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block header if a Block hash was provided. (Not required)"})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The stored value."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example query_global_state result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": {\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",\n "era_end": {\n "era_report": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "rewards": [\n {\n "amount": 1000,\n "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"\n }\n ]\n },\n "next_era_validator_weights": [\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n },\n {\n "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "weight": "123"\n }\n ]\n },\n "era_id": 1,\n "height": 10,\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "timestamp": "2020-11-17T00:39:24.072Z"\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"state-get-account-info",children:"state_get_account_info"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," from the network. The ",(0,c.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the Account's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:"public_key"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The public key of the Account."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Block identifier."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_account_info request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n },\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"state_get_account_info_result",children:(0,c.jsx)(n.code,{children:"state_get_account_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#account",children:"account"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"A JSON representation of the Account structure."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_account_info result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "named_keys": []\n },\n "api_version": "1.4.13",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"state-get-dictionary-item",children:"state_get_dictionary_item"}),"\n",(0,c.jsxs)(n.p,{children:["This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,c.jsx)(n.code,{children:"dictionary_identifier"}),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."]}),"\n",(0,c.jsx)(n.p,{children:"You may query a stored value directly using the dictionary address."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Hash of the state root."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#dictionaryidentifier",children:"dictionary_identifier"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The Dictionary query identifier."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_dictionary_item request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "URef": {\n "dictionary_item_key": "a_unique_entry_identifier",\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n },\n "0808080808080808080808080808080808080808080808080808080808080808"\n ]\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"state_get_dictionary_item_result",children:(0,c.jsx)(n.code,{children:"state_get_dictionary_item_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"dictionary_key"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The key under which the value is stored."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The stored value."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example state_get_dictionary_item result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "stored_value": {\n "CLValue": {\n "bytes": "0100000000000000",\n "cl_type": "U64",\n "parsed": 1\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h1,{id:"node-informational",children:"Node Informational JSON-RPC Methods"}),"\n",(0,c.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."}),"\n",(0,c.jsx)(n.hr,{}),"\n",(0,c.jsx)(n.h2,{id:"info-get-peers",children:"info_get_peers"}),"\n",(0,c.jsx)(n.p,{children:"This method returns a list of peers connected to the node."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_peers request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_peers_result",children:(0,c.jsx)(n.code,{children:"info_get_peers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_peers result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "peers": [\n {\n "address": "127.0.0.1:54321",\n "node_id": "tls:0101..0101"\n }\n ]\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"info-get-status",children:"info_get_status"}),"\n",(0,c.jsx)(n.p,{children:"This method returns the current status of a node."}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_status request"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h3,{id:"info_get_status_result",children:(0,c.jsx)(n.code,{children:"info_get_status_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,c.jsxs)(n.table,{children:[(0,c.jsx)(n.thead,{children:(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.th,{children:"Parameter"}),(0,c.jsx)(n.th,{children:"Type"}),(0,c.jsx)(n.th,{children:"Description"})]})}),(0,c.jsxs)(n.tbody,{children:[(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"api_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The RPC API version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#availableblockrange",children:"available_block_range"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The available block range in storage."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blocksynchronizerstatus",children:"block_sync"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The status of the block synchronizer builders."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"build_version"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The compiled node version."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:"chainspec_name"}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The chainspec name, used to identify the currently connected network."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#minimalblockinfo",children:"last_added_block_info"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"The minimal info of the last Block from the linear chain."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timestamp",children:"last_progress"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Timestamp of the last recorded progress in the reactor."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#nextupgrade",children:"next_upgrade"})}),(0,c.jsx)(n.td,{children:"Object"}),(0,c.jsx)(n.td,{children:"Information about the next scheduled upgrade."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:"our_public_signing_key"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"Our public signing key."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,c.jsx)(n.td,{children:"Array"}),(0,c.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#reactorstate",children:"reactor_state"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The current state of the node reactor."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timediff",children:"round_length"})}),(0,c.jsx)(n.td,{children:"Integer"}),(0,c.jsx)(n.td,{children:"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"starting_state_root_hash"})}),(0,c.jsx)(n.td,{children:"String"}),(0,c.jsx)(n.td,{children:"The state root hash used at the start of the current session."})]}),(0,c.jsxs)(n.tr,{children:[(0,c.jsx)(n.td,{children:(0,c.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timediff",children:"uptime"})}),(0,c.jsx)(n.td,{children:"Integer"}),(0,c.jsx)(n.td,{children:"Time that passed since the node has started."})]})]})]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Example info_get_status result"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "api_version": "1.4.8",\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": null,\n "last_added_block_info": {\n "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n }\n }\n}\n\n'})}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>r,x:()=>t});var c=d(96540);const s={},a=c.createContext(s);function r(e){const n=c.useContext(a);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),c.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac9a16c0.8245bc52.js b/assets/js/ac9a16c0.8245bc52.js new file mode 100644 index 000000000..2579c24b9 --- /dev/null +++ b/assets/js/ac9a16c0.8245bc52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[87013],{58043:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const i={title:"Monitoring Events with the Casper Sidecar"},a="Monitoring and Consuming Events",c={id:"developers/dapps/monitor-and-consume-events",title:"Monitoring Events with the Casper Sidecar",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/2.0.0/developers/dapps/monitor-and-consume-events",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Monitoring Events with the Casper Sidecar"},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/2.0.0/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/2.0.0/developers/cli/"}},o={},d=[{value:"The Casper Sidecar",id:"the-casper-sidecar",level:2},{value:"The Event Stream",id:"the-event-stream",level:2},{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:3},{value:"Detecting Contract-Level Events",id:"contract-level-events",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:3},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:3},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:3},{value:"Replaying the Sidecar Event Stream",id:"replaying-the-sidecar-event-stream",level:3},{value:"The JSON-RPC API",id:"the-json-rpc-api",level:2},{value:"The REST API",id:"the-rest-api",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"monitoring-and-consuming-events",children:"Monitoring and Consuming Events"})}),"\n",(0,s.jsxs)(n.p,{children:["The Casper platform uses ",(0,s.jsx)(n.a,{href:"/2.0.0/operators/setup/node-events",children:"event streaming"})," to signal state changes in smart contracts and nodes. Using the ",(0,s.jsx)(n.a,{href:"#the-casper-sidecar",children:"Casper Sidecar"})," service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data."]}),"\n",(0,s.jsxs)(n.p,{children:["Smart contracts can also emit contract-level events, as explained ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/emitting-contract-events",children:"here"}),". DApps can consume these events by listening to the event stream, detecting ",(0,s.jsx)(n.a,{href:"#contract-level-events",children:"TransactionProcessed"})," events, and parsing the ",(0,s.jsx)(n.code,{children:"messages"})," array storing String-representations of the emitted events."]}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-sidecar",children:"The Casper Sidecar"}),"\n",(0,s.jsx)(n.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar supports the following functionalities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,s.jsx)(n.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture",src:t(93247).A+"",width:"1416",height:"978"})}),"\n",(0,s.jsxs)(n.p,{children:["Visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/",children:"GitHub"})," for the latest source code and information on:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"System architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"Configuring the Sidecar"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"Running and testing"})," the Sidecar"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#swagger-documentation",children:"Swagger documentation"})," for its REST API"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#openapi-specification",children:"OpenAPI schema"})," for the JSON-RPC API"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Troubleshooting tips"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-event-stream",children:"The Event Stream"}),"\n",(0,s.jsx)(n.p,{children:"Casper nodes offer an event stream API that returns server-sent events (SSEs) with JSON-encoded data. The Sidecar reads the event stream of all connected nodes, acting as a passthrough and replicating the SSE interface of the connected nodes."}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Republish the current events from the node to clients listening to Sidecar's SSE API."}),"\n",(0,s.jsxs)(n.li,{children:["Publish a configurable number of previous events to clients connecting to the Sidecar's SSE API with ",(0,s.jsx)(n.code,{children:"?start_from="})," query (similar to the node's SSE API)."]}),"\n",(0,s.jsx)(n.li,{children:"Store the events in external storage so clients can query them via the REST API."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar also provides an endpoint for Sidecar-generated events that can be useful, although the node did not emit them."}),"\n",(0,s.jsx)(n.p,{children:"To summarize, events are divided into two categories and emitted on their respective endpoints:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Node-generated events"})," - All events coming from connected node(s) are emitted on the ",(0,s.jsx)(n.code,{children:"events"})," endpoint. The default URL to consume these events on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Sidecar-generated events"})," - The Sidecar also emits events on the ",(0,s.jsx)(n.code,{children:"events/sidecar"})," endpoint, designated for events originating solely from the Sidecar service. The URL to consume these events using Sidecar on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/sidecar/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes each event type in detail."]}),"\n",(0,s.jsx)(n.h3,{id:"listening-to-the-event-stream",children:"Listening to the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["Set up an event listener in your dApp using the following code to consume the event stream. The ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"})," is the address of the node where the Sidecar was installed. The ",(0,s.jsx)(n.code,{children:"PORT"})," is the address where the Sidecar streams events. It is ",(0,s.jsx)(n.code,{children:"19999"})," by default, but you must find out how the Sidecar was configured."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const { EventStream, EventName } = require("casper-js-sdk")\n\nconst es = new EventStream("http://NODE_ADDRESS:PORT/events/")\nes.start()\nes.subscribe(EventName.EVENT_NAME, eventHandler)\n\nconst eventHandler = (event) => {\n console.log(event)\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'from pycspr import NodeClient, NodeConnection, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = "PORT"))\nclient.get_events(eventHandler, NodeEventType.EVENT_NAME)\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You can find node addresses of active online peers to replace ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", by navigating to ",(0,s.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," for Mainnet and ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"})," for Testnet."]}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"EVENT_NAME"})," with one of the event types listed ",(0,s.jsx)(n.a,{href:"#event-types",children:"below"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"contract-level-events",children:"Detecting Contract-Level Events"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. For more details, see ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/emitting-contract-events#verifying-a-topic",children:"Verifying a Topic"})," and ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/emitting-contract-events#verifying-a-message",children:"Verifying a Message"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"reacting-to-events",children:"Reacting to Events"}),"\n",(0,s.jsxs)(n.p,{children:["An application may parse each event needed for its use case and respond accordingly. Each event type contains additional data that might help decide whether to take action. For example, ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," events contain the account's public key that submitted the transaction, the contract address, and more. This information can help determine how to proceed."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const eventHandler = (event) => {\n if (event.body.TransactionAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'def eventHandler(event):\n if event["TransactionAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"unsubscribing-from-events",children:"Unsubscribing from Events"}),"\n",(0,s.jsxs)(n.p,{children:["In many cases, an application may need to unsubscribe after a particular time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,s.jsx)(n.code,{children:"unsubscribe"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.unsubscribe(EventName.EVENT_NAME)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"EVENT_NAME"})," - One of the different ",(0,s.jsx)(n.a,{href:"#event-types",children:"event types"})," emitted by a Casper node."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"stopping-the-event-stream",children:"Stopping the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["A dApp may cease listening to all events using the ",(0,s.jsx)(n.code,{children:"stop"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.stop()\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"replaying-the-sidecar-event-stream",children:"Replaying the Sidecar Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["This command will replay the event stream from an old event onward. Replace the ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", ",(0,s.jsx)(n.code,{children:"PORT"}),", and ",(0,s.jsx)(n.code,{children:"ID"})," fields with the values of your scenario."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Note that certain shells like ",(0,s.jsx)(n.code,{children:"zsh"})," may require an escape character before the question mark:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The server will replay all the cached events if the ID is 0 or if you specify an event ID already purged from the cache."}),"\n",(0,s.jsx)(n.h2,{id:"the-json-rpc-api",children:"The JSON-RPC API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar also offers a JSON-RPC API server for clients to interact with a Casper network. It is a JSON bridge between end users and a Casper node's binary port, forwarding requests to the Casper node's binary port. For more details on how the JSON-RPC API works, see the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"the-rest-api",children:"The REST API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar offers a REST API to query stored events. You can discover the specific endpoints of the REST API using ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#openapi-specification",children:"OpenAPI"})," and ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#swagger-documentation",children:"Swagger"}),". The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"usage instructions"})," in the repository provide more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 1",src:t(14654).A+"",width:"2236",height:"1332"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 2",src:t(405).A+"",width:"2174",height:"1512"})}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,s.jsxs)(n.p,{children:["For troubleshooting tips, visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},93247:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},14654:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-1-a36838588d0ad1e623d89de2acb93e87.png"},405:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-2-7d8a480884403e1f40c31b6e901976a7.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/acecf23e.1d924b0f.js b/assets/js/acecf23e.1d924b0f.js new file mode 100644 index 000000000..af0ce7acb --- /dev/null +++ b/assets/js/acecf23e.1d924b0f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[81903],{1912:s=>{s.exports=JSON.parse('{"blogBasePath":"/blog","blogTitle":"Casper Developer Relations Blog","authorsListPath":"/blog/authors"}')}}]); \ No newline at end of file diff --git a/assets/js/acecf23e.77fdf311.js b/assets/js/acecf23e.77fdf311.js deleted file mode 100644 index aecc3bb5b..000000000 --- a/assets/js/acecf23e.77fdf311.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1903],{1912:s=>{s.exports=JSON.parse('{"blogBasePath":"/blog","blogTitle":"Casper Developer Relations Blog","authorsListPath":"/blog/authors"}')}}]); \ No newline at end of file diff --git a/assets/js/acee0a96.3b8121a3.js b/assets/js/acee0a96.3b8121a3.js new file mode 100644 index 000000000..49feedb59 --- /dev/null +++ b/assets/js/acee0a96.3b8121a3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35569],{63516:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>p,toc:()=>c});var o=t(74848),a=t(28453);const s={},r="Python SDK",p={id:"developers/dapps/sdk/python-sdk",title:"Python SDK",description:"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/python-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/python-sdk",permalink:"/2.0.0/developers/dapps/sdk/python-sdk",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Go SDK",permalink:"/2.0.0/developers/dapps/sdk/go-sdk"},next:{title:"dApp Technology Stack",permalink:"/2.0.0/developers/dapps/technology-stack"}},i={},c=[{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Sending a transfer",id:"sending-a-transfer",level:3},{value:"Staking",id:"staking",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"python-sdk",children:"Python SDK"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk",children:"Python SDK"})," allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK."]}),"\n",(0,o.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(n.p,{children:"To install the library, run:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"\n pip3 install pycspr\n"})}),"\n",(0,o.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,o.jsxs)(n.p,{children:["You can find examples of testing this library with python scripts in the ",(0,o.jsx)(n.code,{children:"test"})," directory. To run the tests, we recommend the ",(0,o.jsx)(n.em,{children:"pytest"})," library:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:" pytest ./tests\n"})}),"\n",(0,o.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,o.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the Python SDK:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a transfer"})," between two purses"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#staking",children:"Staking"})," tokens with a validator"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["For further examples, take a look at the ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk/tree/main/how_tos",children:"How-tos"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a transfer"}),"\n",(0,o.jsxs)(n.p,{children:["This example shows you how to define and transfer funds between purses on a Casper network. Replace the ",(0,o.jsx)(n.em,{children:"path_to_cp2_account_key"})," in the code below with the receiver's account public key."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:' import os\n import pathlib\n import random\n import typing\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import PrivateKey\n from pycspr.types import Deploy\n from pycspr.types import PublicKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_cp1_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_cp1_secret_key = KeyAlgorithm.ED25519.name,\n\n # path to cp2 account key - defaults to NCTL user 2.\n path_to_cp2_account_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-2" / "public_key_hex"\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key, chain_name):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client = _get_client(node_host, node_port_rpc)\n\n # Set counter-parties.\n cp1, cp2 = _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key)\n\n # Set deploy.\n deploy: Deploy = _get_deploy(chain_name, cp1, cp2)\n\n # Approve deploy.\n deploy.approve(cp1)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n #If deploy is successful send the indication\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host=node_host,\n port_rpc=node_port_rpc,\n ))\n\n\n def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:\n """Returns the 2 counter-parties participating in the transfer.\n """\n cp1 = pycspr.parse_private_key(\n path_to_cp1_secret_key,\n type_of_cp1_secret_key,\n )\n cp2 = pycspr.parse_public_key(\n path_to_cp2_account_key\n ) \n\n return cp1, cp2\n\n\n def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:\n """Returns transfer deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = cp1,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_native_transfer(\n params = deploy_params,\n amount = int(2.5e9),\n target = cp2.account_hash,\n correlation_id = random.randint(1, 1e6)\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)\n'})}),"\n",(0,o.jsx)(n.h3,{id:"staking",children:"Staking"}),"\n",(0,o.jsx)(n.p,{children:"This example shows you how to define and stake funds with a validator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'\n import os\n import pathlib\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import Deploy\n from pycspr.types import PrivateKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_validator_secret_key = KeyAlgorithm.ED25519.name\n\n # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.\n path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"\n\n # amount to stake, i.e. bond, into the network.\n amount = int(2.5e9)\n\n # amount to charge delegators for service provision.\n delegation_rate = 2\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client: NodeClient = _get_client(node_host, node_port_rpc)\n\n # Set validator key.\n validator: PrivateKey = pycspr.parse_private_key(\n path_to_validator_secret_key,\n type_of_validator_secret_key,\n )\n\n # Set deploy.\n deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)\n\n # Approve deploy.\n deploy.approve(validator)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host = node_host,\n port_rpc = node_port_rpc,\n ))\n\n\n def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:\n """Returns delegation deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = validator,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_validator_auction_bid(\n params = deploy_params,\n amount = amount,\n delegation_rate = delegation_rate,\n public_key = validator.as_public_key(),\n path_to_wasm = path_to_wasm\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)\n'})})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>p});var o=t(96540);const a={},s=o.createContext(a);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function p(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad0b296a.459bbd0d.js b/assets/js/ad0b296a.459bbd0d.js new file mode 100644 index 000000000..da21e926e --- /dev/null +++ b/assets/js/ad0b296a.459bbd0d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35378],{64336:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var c=t(74848),a=t(28453);const s={title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},r="Exploring the CEP-18 Contracts",o={id:"resources/tokens/cep18/query",title:"CEP-18 Contract Details",description:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:",source:"@site/docs/resources/tokens/cep18/query.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/query",permalink:"/resources/tokens/cep18/query",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/resources/tokens/cep18/quickstart-guide"},next:{title:"CEP-18 Transfers",permalink:"/resources/tokens/cep18/transfer"}},i={},d=[{value:"Querying the Contract Package",id:"querying-the-contract-package",level:2},{value:"Querying the Utility Contract",id:"querying-the-utility-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"exploring-the-cep-18-contracts",children:"Exploring the CEP-18 Contracts"})}),"\n",(0,c.jsx)(n.p,{children:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The Casper fungible token contract"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["The CEP-18 utility contract, which should appear in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the account that sent the transaction as ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-contract-package",children:"Querying the Contract Package"}),"\n",(0,c.jsxs)(n.p,{children:["We will need the contract package's ",(0,c.jsx)(n.code,{children:"contract_hash"})," to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", under the name given during the installation process."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing transaction.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This will return the ",(0,c.jsx)(n.code,{children:"Contract Package"})," object:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note - In the ",(0,c.jsx)(n.code,{children:"contract_hash"})," field, the hash value represents the stored contract which we will invoke later."]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-utility-contract",children:"Querying the Utility Contract"}),"\n",(0,c.jsxs)(n.p,{children:["In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.jsx)(n.code,{children:"result"}),". You can find this URef in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the utility contract."]}),"\n",(0,c.jsxs)(n.p,{children:["First, you will need to query the ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," hash found within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Which should return information similar to the following:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsxs)(n.p,{children:["You will need to take the ",(0,c.jsx)(n.code,{children:"contract_hash"})," value and replace ",(0,c.jsx)(n.code,{children:"contract"})," with ",(0,c.jsx)(n.code,{children:"hash"})," to run another `query-global-state:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Which will return the full ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," information. The following snippet is condensed to show only the ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", but you should also see the ",(0,c.jsx)(n.code,{children:"entry_points"})," when you run the command. You should see the URef ",(0,c.jsx)(n.code,{children:"result"}),", which will be used to view the results of any checks run through the utility contract."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad0b296a.ec564b7f.js b/assets/js/ad0b296a.ec564b7f.js deleted file mode 100644 index 4c96ffcb4..000000000 --- a/assets/js/ad0b296a.ec564b7f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5378],{64336:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var c=t(74848),a=t(28453);const s={title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},r="Exploring the CEP-18 Contracts",o={id:"resources/tokens/cep18/query",title:"CEP-18 Contract Details",description:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:",source:"@site/docs/resources/tokens/cep18/query.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/query",permalink:"/next/resources/tokens/cep18/query",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/next/resources/tokens/cep18/quickstart-guide"},next:{title:"CEP-18 Transfers",permalink:"/next/resources/tokens/cep18/transfer"}},i={},d=[{value:"Querying the Contract Package",id:"querying-the-contract-package",level:2},{value:"Querying the Utility Contract",id:"querying-the-utility-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"exploring-the-cep-18-contracts",children:"Exploring the CEP-18 Contracts"})}),"\n",(0,c.jsx)(n.p,{children:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The Casper fungible token contract"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["The CEP-18 utility contract, which should appear in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the account that sent the transaction as ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-contract-package",children:"Querying the Contract Package"}),"\n",(0,c.jsxs)(n.p,{children:["We will need the contract package's ",(0,c.jsx)(n.code,{children:"contract_hash"})," to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", under the name given during the installation process."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing transaction.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This will return the ",(0,c.jsx)(n.code,{children:"Contract Package"})," object:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note - In the ",(0,c.jsx)(n.code,{children:"contract_hash"})," field, the hash value represents the stored contract which we will invoke later."]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-utility-contract",children:"Querying the Utility Contract"}),"\n",(0,c.jsxs)(n.p,{children:["In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.jsx)(n.code,{children:"result"}),". You can find this URef in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the utility contract."]}),"\n",(0,c.jsxs)(n.p,{children:["First, you will need to query the ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," hash found within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Which should return information similar to the following:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsxs)(n.p,{children:["You will need to take the ",(0,c.jsx)(n.code,{children:"contract_hash"})," value and replace ",(0,c.jsx)(n.code,{children:"contract"})," with ",(0,c.jsx)(n.code,{children:"hash"})," to run another `query-global-state:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Which will return the full ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," information. The following snippet is condensed to show only the ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", but you should also see the ",(0,c.jsx)(n.code,{children:"entry_points"})," when you run the command. You should see the URef ",(0,c.jsx)(n.code,{children:"result"}),", which will be used to view the results of any checks run through the utility contract."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/next/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad15c07f.89ebc550.js b/assets/js/ad15c07f.89ebc550.js new file mode 100644 index 000000000..475aecde2 --- /dev/null +++ b/assets/js/ad15c07f.89ebc550.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19044],{84798:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const a={title:"Overview",slug:"/economics"},o="Overview of Casper Economics",r={id:"concepts/economics/index",title:"Overview",description:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.",source:"@site/docs/concepts/economics/index.md",sourceDirName:"concepts/economics",slug:"/economics",permalink:"/economics",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Overview",slug:"/economics"},sidebar:"concepts",previous:{title:"Reading and Writing Data",permalink:"/concepts/design/reading-and-writing-to-the-blockchain"},next:{title:"Consensus",permalink:"/concepts/economics/consensus"}},c={},l=[{value:"Consensus",id:"consensus",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer",level:3},{value:"Runtime",id:"runtime",level:2},{value:"Agents (runtime layer)",id:"agents-runtime-layer",level:3},{value:"Incentives (runtime layer)",id:"incentives-runtime-layer",level:3},{value:"Ecosystem",id:"ecosystem",level:2},{value:"Macroeconomy",id:"macroeconomy",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview-of-casper-economics",children:"Overview of Casper Economics"})}),"\n",(0,s.jsx)(t.p,{children:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value."}),"\n",(0,s.jsx)(t.p,{children:"This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active."}),"\n",(0,s.jsx)(t.h2,{id:"consensus",children:"Consensus"}),"\n",(0,s.jsxs)(t.p,{children:["The consensus layer of the Casper Mainnet runs the ",(0,s.jsx)(t.a,{href:"/concepts/design/zug",children:"Zug"})," consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: ",(0,s.jsx)(t.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,s.jsx)(t.p,{children:'When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.'}),"\n",(0,s.jsx)(t.h3,{id:"agents-consensus-layer",children:"Agents (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"}),' are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain\'s security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Delegators"}),' are users who participate in the platform\'s security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.']}),"\n",(0,s.jsx)(t.h3,{id:"incentives-consensus-layer",children:"Incentives (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"auction"}),' determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Rewards"})," (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Evictions"})," deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract."]}),"\n",(0,s.jsx)(t.h2,{id:"runtime",children:"Runtime"}),"\n",(0,s.jsxs)(t.p,{children:["The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to ",(0,s.jsx)(t.a,{href:"/concepts/design/casper-design#execution-semantics-gas",children:"metering computing time"}),", measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost."]}),"\n",(0,s.jsx)(t.p,{children:"The Mainnet transaction selection mechanism is based on FIFO."}),"\n",(0,s.jsx)(t.p,{children:"We expect to continue to work on runtime resource markets."}),"\n",(0,s.jsx)(t.h3,{id:"agents-runtime-layer",children:"Agents (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"})," again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Users"})," execute session and contract code using the platform's computational resources"]}),"\n",(0,s.jsx)(t.h3,{id:"incentives-runtime-layer",children:"Incentives (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a ",(0,s.jsx)(t.a,{href:"/concepts/economics/fee-elimination",children:"fee elimination"})," model by default, setting the ",(0,s.jsx)(t.code,{children:"no_fee"}),",",(0,s.jsx)(t.code,{children:"no_refund"}),", and ",(0,s.jsx)(t.code,{children:"fixed"})," pricing configurations in the network's chainspec."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_fee"}),' mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.']}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_refund"})," mode means no refund is handled when fees are eliminated."]}),"\n",(0,s.jsxs)(t.p,{children:["Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes ",(0,s.jsx)(t.a,{href:"/runtime#lanes-lanes",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations."}),"\n",(0,s.jsxs)(t.p,{children:["The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, ",(0,s.jsx)(t.a,{href:"/operators/setup-network/create-private",children:"private networks"})," can set their fee, refund, and pricing strategies."]}),"\n",(0,s.jsx)(t.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,s.jsx)(t.p,{children:"The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps."}),"\n",(0,s.jsx)(t.h2,{id:"macroeconomy",children:"Macroeconomy"}),"\n",(0,s.jsx)(t.p,{children:'Casper\'s macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.'}),"\n",(0,s.jsx)(t.p,{children:"The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var s=n(96540);const i={},a=s.createContext(i);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad15c07f.9bfac3bd.js b/assets/js/ad15c07f.9bfac3bd.js deleted file mode 100644 index 5817f357f..000000000 --- a/assets/js/ad15c07f.9bfac3bd.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9044],{84798:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=n(74848),i=n(28453);const a={title:"Overview",slug:"/economics"},o="Overview of Casper Economics",r={id:"concepts/economics/index",title:"Overview",description:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.",source:"@site/docs/concepts/economics/index.md",sourceDirName:"concepts/economics",slug:"/economics",permalink:"/next/economics",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{title:"Overview",slug:"/economics"},sidebar:"concepts",previous:{title:"Reading and Writing Data",permalink:"/next/concepts/design/reading-and-writing-to-the-blockchain"},next:{title:"Consensus",permalink:"/next/concepts/economics/consensus"}},c={},l=[{value:"Consensus",id:"consensus",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer",level:3},{value:"Runtime",id:"runtime",level:2},{value:"Agents (runtime layer)",id:"agents-runtime-layer",level:3},{value:"Incentives (runtime layer)",id:"incentives-runtime-layer",level:3},{value:"Ecosystem",id:"ecosystem",level:2},{value:"Macroeconomy",id:"macroeconomy",level:2}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"overview-of-casper-economics",children:"Overview of Casper Economics"})}),"\n",(0,s.jsx)(t.p,{children:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value."}),"\n",(0,s.jsx)(t.p,{children:"This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active."}),"\n",(0,s.jsx)(t.h2,{id:"consensus",children:"Consensus"}),"\n",(0,s.jsxs)(t.p,{children:["The consensus layer of the Casper Mainnet runs the ",(0,s.jsx)(t.a,{href:"/next/concepts/design/zug",children:"Zug"})," consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: ",(0,s.jsx)(t.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,s.jsx)(t.p,{children:'When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.'}),"\n",(0,s.jsx)(t.h3,{id:"agents-consensus-layer",children:"Agents (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"}),' are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain\'s security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Delegators"}),' are users who participate in the platform\'s security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.']}),"\n",(0,s.jsx)(t.h3,{id:"incentives-consensus-layer",children:"Incentives (consensus layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"auction"}),' determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.']}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Rewards"})," (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Evictions"})," deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract."]}),"\n",(0,s.jsx)(t.h2,{id:"runtime",children:"Runtime"}),"\n",(0,s.jsxs)(t.p,{children:["The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to ",(0,s.jsx)(t.a,{href:"/next/concepts/design/casper-design#execution-semantics-gas",children:"metering computing time"}),", measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost."]}),"\n",(0,s.jsx)(t.p,{children:"The Mainnet transaction selection mechanism is based on FIFO."}),"\n",(0,s.jsx)(t.p,{children:"We expect to continue to work on runtime resource markets."}),"\n",(0,s.jsx)(t.h3,{id:"agents-runtime-layer",children:"Agents (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Validators"})," again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Users"})," execute session and contract code using the platform's computational resources"]}),"\n",(0,s.jsx)(t.h3,{id:"incentives-runtime-layer",children:"Incentives (runtime layer)"}),"\n",(0,s.jsxs)(t.p,{children:["The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a ",(0,s.jsx)(t.a,{href:"/next/concepts/economics/fee-elimination",children:"fee elimination"})," model by default, setting the ",(0,s.jsx)(t.code,{children:"no_fee"}),",",(0,s.jsx)(t.code,{children:"no_refund"}),", and ",(0,s.jsx)(t.code,{children:"fixed"})," pricing configurations in the network's chainspec."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_fee"}),' mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.']}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"no_refund"})," mode means no refund is handled when fees are eliminated."]}),"\n",(0,s.jsxs)(t.p,{children:["Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes ",(0,s.jsx)(t.a,{href:"/next/runtime#lanes-lanes",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations."}),"\n",(0,s.jsxs)(t.p,{children:["The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, ",(0,s.jsx)(t.a,{href:"/next/operators/setup-network/create-private",children:"private networks"})," can set their fee, refund, and pricing strategies."]}),"\n",(0,s.jsx)(t.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,s.jsx)(t.p,{children:"The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps."}),"\n",(0,s.jsx)(t.h2,{id:"macroeconomy",children:"Macroeconomy"}),"\n",(0,s.jsx)(t.p,{children:'Casper\'s macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.'}),"\n",(0,s.jsx)(t.p,{children:"The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain."})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var s=n(96540);const i={},a=s.createContext(i);function o(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad591877.cf7047e7.js b/assets/js/ad591877.cf7047e7.js new file mode 100644 index 000000000..53f96761a --- /dev/null +++ b/assets/js/ad591877.cf7047e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[91035],{80884:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>c,frontMatter:()=>d,metadata:()=>a,toc:()=>p});var t=s(74848),r=s(28453);const d={},i="Overview of Casper dApps",a={id:"developers/dapps/index",title:"Overview of Casper dApps",description:"The following topics are essential for developers building decentralized applications on a Casper network.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/index.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/",permalink:"/2.0.0/developers/dapps/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"CLType",permalink:"/2.0.0/developers/json-rpc/types_cl"},next:{title:"What is a dApp?",permalink:"/2.0.0/developers/dapps/dapp"}},o={},p=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"overview-of-casper-dapps",children:"Overview of Casper dApps"})}),"\n",(0,t.jsx)(n.p,{children:"The following topics are essential for developers building decentralized applications on a Casper network."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/dapp",children:"Introducing dApps"})}),(0,t.jsx)(n.td,{children:"Introducing dApps on a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/prerequisites",children:"Prerequisites for Building dApps"})}),(0,t.jsx)(n.td,{children:"Recommended setup for building dApps on Casper"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/sdk",children:"SDK Client Libraries"})}),(0,t.jsx)(n.td,{children:"Client-side libraries providing ways to interact with a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/technology-stack",children:"dApp Technology Stack"})}),(0,t.jsx)(n.td,{children:"Building the front-end, backend, and on-chain logic of a dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/template-frontend",children:"Front-end Template with React"})}),(0,t.jsx)(n.td,{children:"Use the Casper JS SDK with React to build a dApp frontend"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/signing-a-transaction",children:"Signing Transactions"})}),(0,t.jsx)(n.td,{children:"Details about the signatures required for transactions"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"Setting up a Local Network with NCTL"})}),(0,t.jsx)(n.td,{children:"Learn to set up a local test network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),(0,t.jsx)(n.td,{children:"Test transactions locally before sending them to a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"})}),(0,t.jsx)(n.td,{children:"How dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data"})]})]})]})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>a});var t=s(96540);const r={},d=t.createContext(r);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad727d36.001c91d8.js b/assets/js/ad727d36.001c91d8.js new file mode 100644 index 000000000..a1e82b2e2 --- /dev/null +++ b/assets/js/ad727d36.001c91d8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84457],{88030:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>i});var n=r(74848),o=r(28453);const c={},t="V",a={id:"concepts/glossary/V",title:"V",description:"---",source:"@site/docs/concepts/glossary/V.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/V",permalink:"/concepts/glossary/V",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"U",permalink:"/concepts/glossary/U"},next:{title:"W",permalink:"/concepts/glossary/W"}},l={},i=[{value:"Validator",id:"validator",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"v",children:"V"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"validator",children:"Validator"}),"\n",(0,n.jsx)(s.p,{children:'Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.'}),"\n",(0,n.jsx)(s.p,{children:"The responsibilities of a validator include:"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-creation",children:"block creation"})," and ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-proposal",children:"block proposal"})]}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-validation",children:"block validation"})}),"\n",(0,n.jsx)(s.li,{children:(0,n.jsx)(s.a,{href:"/concepts/glossary/B#block-gossiping",children:"block gossiping"})}),"\n"]}),"\n",(0,n.jsxs)(s.p,{children:["Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S#staker",children:"stakers"})," can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const o={},c=n.createContext(o);function t(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:t(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad727d36.f0083a21.js b/assets/js/ad727d36.f0083a21.js deleted file mode 100644 index ddb58b533..000000000 --- a/assets/js/ad727d36.f0083a21.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4457],{88030:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var r=n(74848),t=n(28453);const o={},c="V",a={id:"concepts/glossary/V",title:"V",description:"---",source:"@site/docs/concepts/glossary/V.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/V",permalink:"/next/concepts/glossary/V",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"U",permalink:"/next/concepts/glossary/U"},next:{title:"W",permalink:"/next/concepts/glossary/W"}},l={},i=[{value:"Validator",id:"validator",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"v",children:"V"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"validator",children:"Validator"}),"\n",(0,r.jsx)(s.p,{children:'Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.'}),"\n",(0,r.jsx)(s.p,{children:"The responsibilities of a validator include:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsxs)(s.li,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B#block-creation",children:"block creation"})," and ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B#block-proposal",children:"block proposal"})]}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B#block-validation",children:"block validation"})}),"\n",(0,r.jsx)(s.li,{children:(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B#block-gossiping",children:"block gossiping"})}),"\n"]}),"\n",(0,r.jsxs)(s.p,{children:["Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S#staker",children:"stakers"})," can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var r=n(96540);const t={},o=r.createContext(t);function c(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad7eda35.6b9ae2e7.js b/assets/js/ad7eda35.6b9ae2e7.js new file mode 100644 index 000000000..35677b16f --- /dev/null +++ b/assets/js/ad7eda35.6b9ae2e7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75721],{47501:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>t,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var i=s(74848),r=s(28453);const d={},l="Types {#types}",c={id:"developers/json-rpc/types_chain",title:"Types",description:"types}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_chain.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_chain",permalink:"/1.5.X/developers/json-rpc/types_chain",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/1.5.X/developers/json-rpc/json-rpc-pos"},next:{title:"CLType",permalink:"/1.5.X/developers/json-rpc/types_cl"}},h={},a=[{value:"Account",id:"account",level:2},{value:"AccountHash",id:"accounthash",level:2},{value:"ActionThresholds",id:"actionthresholds",level:2},{value:"ActivationPoint",id:"activationpoint",level:2},{value:"Approval",id:"approval",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AuctionState",id:"auctionstate",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"Bid",id:"bid",level:2},{value:"BlockHash",id:"blockhash",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockSynchronizerStatus",id:"blocksynchronizerstatus",level:2},{value:"ChainspecRawBytes",id:"chainspecrawbytes",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackage",id:"contractpackage",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"DeployHash",id:"deployhash",level:2},{value:"DeployHeader",id:"deployheader",level:2},{value:"DeployInfo",id:"deployinfo",level:2},{value:"DictionaryIdentifier",id:"dictionaryidentifier",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EntryPointAccess",id:"entrypointaccess",level:2},{value:"EntryPointType",id:"entrypointtype",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"EraSummary",id:"erasummary",level:2},{value:"ExecutableDeployItem",id:"executabledeployitem",level:2},{value:"<code>ModuleBytes</code>",id:"modulebytes",level:3},{value:"<code>StoredContractByHash</code>",id:"storedcontractbyhash",level:3},{value:"<code>StoredContractByName</code>",id:"storedcontractbyname",level:3},{value:"<code>StoredVersionContractByHash</code>",id:"storedversioncontractbyhash",level:3},{value:"<code>StoredVersionContractByName</code>",id:"storedversioncontractbyname",level:3},{value:"<code>Transfer</code>",id:"transfer",level:3},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"FinalizedApprovals",id:"finalizedapprovals",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:3},{value:"JsonBid",id:"jsonbid",level:2},{value:"JsonBids",id:"jsonbids",level:2},{value:"JsonBlock",id:"jsonblock",level:2},{value:"JsonBlockBody",id:"jsonblockbody",level:2},{value:"JsonBlockHeader",id:"jsonblockheader",level:2},{value:"JsonDelegator",id:"jsondelegator",level:2},{value:"JsonEraEnd",id:"jsoneraend",level:2},{value:"JsonEraReport",id:"jsonerareport",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonExecutionResult",id:"jsonexecutionresult",level:2},{value:"JsonProof",id:"jsonproof",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorweights",level:2},{value:"Merkle_Proof",id:"merkle-proof",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"NewValidator",id:"newvalidator",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"PeersMap",id:"peersmap",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReactorState",id:"reactorstate",level:2},{value:"Reward",id:"reward",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"types",children:"Types"})}),"\n",(0,i.jsx)(n.p,{children:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."}),"\n",(0,i.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,i.jsx)(n.p,{children:"Structure representing a user's Account, stored in global state."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#actionthresholds",children:(0,i.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#associatedkey",children:(0,i.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#namedkey",children:(0,i.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"accounthash",children:"AccountHash"}),"\n",(0,i.jsx)(n.p,{children:"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."}),"\n",(0,i.jsx)(n.h2,{id:"actionthresholds",children:"ActionThresholds"}),"\n",(0,i.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"deployment"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"key_management"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"activationpoint",children:"ActivationPoint"}),"\n",(0,i.jsx)(n.p,{children:"The first era to which the associated protocol version applies."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,i.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#signature",children:(0,i.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"signer"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,i.jsx)(n.p,{children:"A key granted limited permissions to an Account, for purposes such as multisig."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"weight"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auctionstate",children:"AuctionState"}),"\n",(0,i.jsx)(n.p,{children:"Data structure summarizing auction contract data."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonbids",children:(0,i.jsx)(n.code,{children:"bids"})})," All bids contained within a vector."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," Block height."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsoneravalidators",children:(0,i.jsx)(n.code,{children:"era_validators"})})," Era validators."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," Global state hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"high"})," The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,i.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#delegator",children:(0,i.jsx)(n.code,{children:"delegators"})})," The validator's delegators, indexed by their public keys."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"inactive"})," ",(0,i.jsx)(n.code,{children:"true"}),' if validator has been "evicted".']}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#vestingschedule",children:(0,i.jsx)(n.code,{children:"vesting_schedule"})})," Vesting schedule for a genesis validator. ",(0,i.jsx)(n.code,{children:"None"})," if non-genesis validator."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"blockhash",children:"BlockHash"}),"\n",(0,i.jsxs)(n.p,{children:["A cryptographic hash identifying a ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"Hash"})})," Identify and retrieve the Block with its hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Height"})," Identify and retrieve the Block with its height."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"blocksynchronizerstatus",children:"BlockSynchronizerStatus"}),"\n",(0,i.jsx)(n.p,{children:"The status of the block synchronizer."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Historical"})," The status of syncing a historical block, if any."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Forward"})," The status of syncing a forward block, if any."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"chainspecrawbytes",children:"ChainspecRawBytes"}),"\n",(0,i.jsx)(n.p,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"chainspec_bytes"})," Hex-encoded raw bytes of the current chainspec.toml file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"maybe_genesis_accounts_bytes"})," Hex-encoded raw bytes of the current genesis accounts.toml file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"maybe_global_state_bytes"})," Hex-encoded raw bytes of the current global_state.toml file."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,i.jsx)(n.p,{children:"A contract struct that can be serialized as a JSON object."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractpackagehash",children:(0,i.jsx)(n.code,{children:"contract_package_hash"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractwasmhash",children:(0,i.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypoint",children:(0,i.jsx)(n.code,{children:"entry_points"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#namedkey",children:(0,i.jsx)(n.code,{children:"named_keys"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,i.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract."}),"\n",(0,i.jsx)(n.h2,{id:"contractpackage",children:"ContractPackage"}),"\n",(0,i.jsx)(n.p,{children:"Contract definition, metadata and security container."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"access_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#disabledversions",children:(0,i.jsx)(n.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#groups",children:(0,i.jsx)(n.code,{children:"groups"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractversion",children:(0,i.jsx)(n.code,{children:"versions"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract package."}),"\n",(0,i.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,i.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contracthash",children:(0,i.jsx)(n.code,{children:"contract_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract Wasm."}),"\n",(0,i.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,i.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee").'}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#vestingschedule",children:(0,i.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,i.jsx)(n.p,{children:"A Deploy; an item containing a smart contract along with the requester's signature(s)."}),"\n",(0,i.jsx)(n.p,{children:"Required properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#approval",children:(0,i.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployheader",children:(0,i.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executabledeployitem",children:(0,i.jsx)(n.code,{children:"payment"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executabledeployitem",children:(0,i.jsx)(n.code,{children:"sessions"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deployhash",children:"DeployHash"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded Deploy hash."}),"\n",(0,i.jsx)(n.h2,{id:"deployheader",children:"DeployHeader"}),"\n",(0,i.jsx)(n.p,{children:"The header portion of a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"account"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"chain_name"})," A user defined string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"dependencies"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"gas_price"})," Defined as an integer in UInt64 format."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timediff",children:(0,i.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,i.jsx)(n.p,{children:"Information relating to the given Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hash"})})," The relevant Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"from"})})," Account identifier of the creator of the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"gas"})})," Gas cost of executing the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"source"})})," Source purse used for payment of the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})," Transfers performed by the Deploy."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"dictionaryidentifier",children:"DictionaryIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Options for dictionary item lookups."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AccountNamedKey"})," Lookup a dictionary item via an Account's named keys."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The Account key as a formatted string whose named keys contain dictionary_name."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ContractNamedKey"})," Lookup a dictionary item via a Contract's named keys."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The contract key as a formatted string whose named keys contains dictionary_name."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"URef"})," Lookup a dictionary item via its seed URef."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"seed_uref"})," The dictionary's seed URef."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Dictionary"})," Lookup a dictionary item via its unique key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded hash digest."}),"\n",(0,i.jsx)(n.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,i.jsx)(n.p,{children:"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypointaccess",children:(0,i.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#parameter",children:(0,i.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypointtype",children:(0,i.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"name"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypointaccess",children:"EntryPointAccess"}),"\n",(0,i.jsx)(n.p,{children:"Enum describing the possible access control options for a contract entry point."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Public"})," A public entry point is callable by any caller."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#group",children:(0,i.jsx)(n.code,{children:"Groups"})})," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypointtype",children:"EntryPointType"}),"\n",(0,i.jsx)(n.p,{children:"Context of an entry point execution."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"session"})," Executes in the caller's context."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"contract"})," Executes in the callee's context."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,i.jsx)(n.p,{children:"Era ID newtype."}),"\n",(0,i.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,i.jsx)(n.p,{children:"Auction metadata. Intended to be recorded at each era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#seigniorageallocation",children:(0,i.jsx)(n.code,{children:"seigniorage_allocation"})})," Information about a seigniorage allocation."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"erasummary",children:"EraSummary"}),"\n",(0,i.jsx)(n.p,{children:"The summary of an era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The Block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The era id."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#merkle-proof",children:(0,i.jsx)(n.code,{children:"merkle_proof"})})," The merkle proof."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," Hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#storedvalue",children:(0,i.jsx)(n.code,{children:"stored_value"})})," The StoredValue containing era information."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executabledeployitem",children:"ExecutableDeployItem"}),"\n",(0,i.jsx)(n.p,{children:"Represents possible variants of an executable Deploy."}),"\n",(0,i.jsx)(n.h3,{id:"modulebytes",children:(0,i.jsx)(n.code,{children:"ModuleBytes"})}),"\n",(0,i.jsxs)(n.p,{children:["Executable specified as raw bytes that represent Wasm code and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"module_bytes"})," Hex-encoded raw Wasm bytes. There are some special cases around passing ",(0,i.jsx)(n.code,{children:"module_bytes"})," for payment code."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedcontractbyhash",children:(0,i.jsx)(n.code,{children:"StoredContractByHash"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored contract referenced by its ",(0,i.jsx)(n.code,{children:"ContractHash"}),", entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"hash"})," A hex-encoded hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedcontractbyname",children:(0,i.jsx)(n.code,{children:"StoredContractByName"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," A named key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedversioncontractbyhash",children:(0,i.jsx)(n.code,{children:"StoredVersionContractByHash"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored versioned contract referenced by its ",(0,i.jsx)(n.code,{children:"ContractPackageHash"}),", entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"hash"})," A hex-encoded hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"version"})," An optional version of the contract to call. It will default to the highest enabled version if no value is specified."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedversioncontractbyname",children:(0,i.jsx)(n.code,{children:"StoredVersionContractByName"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," A named key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"version"})," An optional version of the contract to call. It will default to the highest enabled version if no value is specified."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"transfer",children:(0,i.jsx)(n.code,{children:"Transfer"})}),"\n",(0,i.jsx)(n.p,{children:"A native transfer which does not contain or reference a Wasm code."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,i.jsx)(n.p,{children:"The journal of execution transforms from a single Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#operation",children:(0,i.jsx)(n.code,{children:"operations"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transformentry",children:(0,i.jsx)(n.code,{children:"transforms"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,i.jsx)(n.p,{children:"The result of executing a single Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Failure"})," The result of a failed execution`"]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executioneffect",children:(0,i.jsx)(n.code,{children:"effect"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"cost"})})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"error_message"})," The error message associated with executing the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Success"})," The result of a successful execution."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executioneffect",children:(0,i.jsx)(n.code,{children:"effect"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"cost"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"finalizedapprovals",children:"FinalizedApprovals"}),"\n",(0,i.jsxs)(n.p,{children:["A boolean value that determines whether to return the deploy with the finalized approvals substituted. If ",(0,i.jsx)(n.code,{children:"false"})," or omitted, returns the deploy with the approvals that were originally received by the node."]}),"\n",(0,i.jsx)(n.h2,{id:"globalstateidentifier",children:"GlobalStateIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Identifier for possible ways to query global state."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"BlockHash"})})," Query using a Block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"StateRootHash"})})," Query using the state root hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,i.jsx)(n.p,{children:'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'}),"\n",(0,i.jsx)(n.h3,{id:"groups",children:"Groups"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"group"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"keys"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonbid",children:"JsonBid"}),"\n",(0,i.jsx)(n.p,{children:"An entry in a founding validator map representing a bid."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsondelegator",children:(0,i.jsx)(n.code,{children:"delegators"})})," The delegators."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"inactive"})," Is this an inactive validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonbids",children:"JsonBids"}),"\n",(0,i.jsx)(n.p,{children:"A Json representation of a single bid."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonbid",children:(0,i.jsx)(n.code,{children:"bid"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblock",children:"JsonBlock"}),"\n",(0,i.jsxs)(n.p,{children:["A JSON-friendly representation of ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonblockbody",children:(0,i.jsx)(n.code,{children:"body"})})," JSON-friendly Block body."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"hash"})})," BlockHash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonblockheader",children:(0,i.jsx)(n.code,{children:"header"})})," JSON-friendly Block header."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonproof",children:(0,i.jsx)(n.code,{children:"proofs"})})," JSON-friendly list of proofs for this Block."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblockbody",children:"JsonBlockBody"}),"\n",(0,i.jsxs)(n.p,{children:["A JSON-friendly representation of ",(0,i.jsx)(n.code,{children:"Body"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hashes"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"proposer"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"transfer_hashes"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblockheader",children:"JsonBlockHeader"}),"\n",(0,i.jsx)(n.p,{children:"JSON representation of a Block header."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"accumulated_seed"})})," Accumulated seed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"body_hash"})})," The body hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The Block era id."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"height"})," The Block height."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"parent_hash"})})," The parent hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#protocolversion",children:(0,i.jsx)(n.code,{children:"protocol_version"})})," The protocol version."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"random_bit"})," Randomness bit."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," The state root hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})," The Block timestamp."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#jsoneraend",children:(0,i.jsx)(n.code,{children:"era_end"})})," The era end."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsondelegator",children:"JsonDelegator"}),"\n",(0,i.jsx)(n.p,{children:"A delegator associated with the given validator."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegatee"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsoneraend",children:"JsonEraEnd"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonerareport",children:"`era_report"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#validatorweight",children:(0,i.jsx)(n.code,{children:"next_era_validator_weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonerareport",children:"JsonEraReport"}),"\n",(0,i.jsx)(n.p,{children:"Equivocation and reward information to be included in the terminal Block."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"equivocators"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"inactive_validators"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#reward",children:(0,i.jsx)(n.code,{children:"rewards"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsoneravalidators",children:"JsonEraValidators"}),"\n",(0,i.jsx)(n.p,{children:"The validators for the given era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonvalidatorweights",children:(0,i.jsx)(n.code,{children:"validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonexecutionresult",children:"JsonExecutionResult"}),"\n",(0,i.jsx)(n.p,{children:"The execution result of a single Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executionresult",children:(0,i.jsx)(n.code,{children:"result"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonproof",children:"JsonProof"}),"\n",(0,i.jsx)(n.p,{children:"A JSON-friendly representation of a proof, i.e. a Block's finality signature."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#signature",children:(0,i.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorchanges",children:"JsonValidatorChanges"}),"\n",(0,i.jsx)(n.p,{children:"The changes in a validator's status."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})," The public key of the validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonvalidatorstatuschange",children:(0,i.jsx)(n.code,{children:"status_changes"})})," The set of changes to the validator's status."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorstatuschange",children:"JsonValidatorStatusChange"}),"\n",(0,i.jsx)(n.p,{children:"A single change to a validator's status in the given era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The era in which the change occurred."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#validatorchange",children:(0,i.jsx)(n.code,{children:"validator_change"})})," The change in validator status."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorweights",children:"JsonValidatorsWeights"}),"\n",(0,i.jsx)(n.p,{children:"A validator's weight."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"merkle-proof",children:"Merkle_Proof"}),"\n",(0,i.jsx)(n.p,{children:"A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes."}),"\n",(0,i.jsx)(n.h2,{id:"minimalblockinfo",children:"MinimalBlockInfo"}),"\n",(0,i.jsxs)(n.p,{children:["Minimal info of a ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"creator"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"height"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,i.jsx)(n.p,{children:"Named arguments to a contract."}),"\n",(0,i.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,i.jsx)(n.p,{children:"A named key."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The value of the entry: a casper ",(0,i.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," The name of the entry."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"nextupgrade",children:"NextUpgrade"}),"\n",(0,i.jsx)(n.p,{children:"Information about the next protocol upgrade."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#activationpoint",children:(0,i.jsx)(n.code,{children:"activation_point"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"newvalidator",children:"NewValidator"}),"\n",(0,i.jsxs)(n.p,{children:["The public key for the new validator in a redelegation using ",(0,i.jsx)(n.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,i.jsx)(n.p,{children:"An operation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,i.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#opkind",children:(0,i.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"opkind",children:"OpKind"}),"\n",(0,i.jsx)(n.p,{children:"The type of operation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,i.jsx)(n.p,{children:"Parameter to an entry point."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"name"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"peerentry",children:"PeerEntry"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"address"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"node_id"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"peersmap",children:"PeersMap"}),"\n",(0,i.jsx)(n.p,{children:"Map of peer IDs to network addresses."}),"\n",(0,i.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,i.jsx)(n.p,{children:"Casper Platform protocol version."}),"\n",(0,i.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded cryptographic public key, including the algorithm tag prefix."}),"\n",(0,i.jsx)(n.h2,{id:"purseidentifier",children:"PurseIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"main_purse_under_public_key"})," The main purse under a provided ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#publickey",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"main_purse_under_account_hash"})," The main purse under a provided ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#accounthash",children:(0,i.jsx)(n.code,{children:"AccountHash"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"purse_uref"})," A specific purse identified by the associated ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain#uref",children:(0,i.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"reactorstate",children:"ReactorState"}),"\n",(0,i.jsx)(n.p,{children:"The state of the reactor, which will return one of the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Initialize"})," Get all components and reactor state set up on start."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CatchUp"})," Orient to the network and attempt to catch up to tip."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Upgrading"})," Running commit upgrade and creating immediate switch block."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"KeepUp"})," Stay caught up with tip."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Validate"})," Node is currently caught up and is an active validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ShutdownForUpgrade"})," Node should be shut down for upgrade."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"reward",children:"Reward"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"amount"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,i.jsx)(n.p,{children:"Represents a collection of arguments passed to a smart contract."}),"\n",(0,i.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,i.jsx)(n.p,{children:"Information about a seigniorage allocation."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Validator"})," Info about a seigniorage allocation for a validator."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Delegator"})," Info about a seigniorage allocation for a delegator."]}),"\n",(0,i.jsx)(n.p,{children:"Require Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegator_public_key"})})," Delegator's public key."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded cryptographic signature, including the algorithm tag prefix."}),"\n",(0,i.jsx)(n.h2,{id:"storedvalue",children:"StoredValue"}),"\n",(0,i.jsxs)(n.p,{children:["Representation of a value stored in global state. ",(0,i.jsx)(n.code,{children:"Account"}),", ",(0,i.jsx)(n.code,{children:"Contract"})," and ",(0,i.jsx)(n.code,{children:"ContractPackage"})," have their own ",(0,i.jsx)(n.code,{children:"json_compatibility"})," representation (see their docs for further info)."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"CLValue"})})," A Casper-specific value."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#account",children:(0,i.jsx)(n.code,{children:"Account"})})," An Account."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ContractWasm"})," A contract's Wasm."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#contract",children:(0,i.jsx)(n.code,{children:"Contract"})})," Entry points supported by a contract."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#contractpackage",children:(0,i.jsx)(n.code,{children:"ContractPackage"})})," A contract definition, metadata, and security container."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transfer",children:(0,i.jsx)(n.code,{children:"Transfer"})})," A record of a transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployinfo",children:(0,i.jsx)(n.code,{children:"DeployInfo"})})," A record of a Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#erainfo",children:(0,i.jsx)(n.code,{children:"EraInfo"})})," Auction metadata."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#bid",children:(0,i.jsx)(n.code,{children:"Bid"})})," A bid."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#unbondingpurse",children:(0,i.jsx)(n.code,{children:"Withdraw"})})," A withdraw."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,i.jsx)(n.p,{children:"Human-readable duration."}),"\n",(0,i.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,i.jsx)(n.p,{children:"Timestamp formatted as per RFC 3339."}),"\n",(0,i.jsx)(n.h2,{id:"transfer",children:"Transfer"}),"\n",(0,i.jsx)(n.p,{children:"Represents a transfer from one purse to another."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hash"})})," Deploy that created the transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"from"})})," Account from which transfer was executed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded transfer address."}),"\n",(0,i.jsx)(n.h2,{id:"transform",children:"Transform"}),"\n",(0,i.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteCLValue"})," Write the given ",(0,i.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_cl#clvalue",children:"CLValue"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteAccount"})," Writes the given ",(0,i.jsx)(n.a,{href:"#accounthash",children:"Account"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteDeployInfo"})," Writes the given ",(0,i.jsx)(n.a,{href:"#deployinfo",children:"DeployInfo"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteEraInfo"})," Writes the given ",(0,i.jsx)(n.a,{href:"#erainfo",children:"EraInfo"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteTransfer"})," Writes the given ",(0,i.jsx)(n.a,{href:"#transfer",children:"Transfer"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteBid"})," Writes the given ",(0,i.jsx)(n.a,{href:"#bid",children:"Bid"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteWithdraw"})," Writes the given ",(0,i.jsx)(n.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,i.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,i.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u128",children:(0,i.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u256",children:(0,i.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,i.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Failure"})," A failed transformation, containing an error message."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,i.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,i.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transform",children:(0,i.jsx)(n.code,{children:"transforms"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"u128",children:"U128"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 128-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"u256",children:"U256"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 256-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"u512",children:"U512"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 512-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,i.jsx)(n.p,{children:"Unbonding purse."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#newvalidator",children:(0,i.jsx)(n.code,{children:"new_validator"})})," The redelegated validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded, formatted URef."}),"\n",(0,i.jsx)(n.h2,{id:"validatorchange",children:"ValidatorChange"}),"\n",(0,i.jsx)(n.p,{children:"A change to a validator's status between two eras."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Added"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Removed"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Banned"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"CannotPropose"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"SeenAsFaulty"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"validatorweight",children:"ValidatorWeight"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"vestingschedule",children:"VestingSchedule"}),"\n",(0,i.jsx)(n.p,{children:"Vesting schedule for a genesis validator."}),"\n",(0,i.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,i.jsx)(n.p,{children:"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]})]})}function t(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var i=s(96540);const r={},d=i.createContext(r);function l(e){const n=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),i.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ad7eda35.de731ba0.js b/assets/js/ad7eda35.de731ba0.js deleted file mode 100644 index 9eba73386..000000000 --- a/assets/js/ad7eda35.de731ba0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5721],{47501:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>t,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var i=s(74848),r=s(28453);const d={},l="Types {#types}",c={id:"developers/json-rpc/types_chain",title:"Types",description:"types}",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_chain.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_chain",permalink:"/developers/json-rpc/types_chain",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-pos"},next:{title:"CLType",permalink:"/developers/json-rpc/types_cl"}},h={},a=[{value:"Account",id:"account",level:2},{value:"AccountHash",id:"accounthash",level:2},{value:"ActionThresholds",id:"actionthresholds",level:2},{value:"ActivationPoint",id:"activationpoint",level:2},{value:"Approval",id:"approval",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AuctionState",id:"auctionstate",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"Bid",id:"bid",level:2},{value:"BlockHash",id:"blockhash",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockSynchronizerStatus",id:"blocksynchronizerstatus",level:2},{value:"ChainspecRawBytes",id:"chainspecrawbytes",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackage",id:"contractpackage",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"DeployHash",id:"deployhash",level:2},{value:"DeployHeader",id:"deployheader",level:2},{value:"DeployInfo",id:"deployinfo",level:2},{value:"DictionaryIdentifier",id:"dictionaryidentifier",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EntryPointAccess",id:"entrypointaccess",level:2},{value:"EntryPointType",id:"entrypointtype",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"EraSummary",id:"erasummary",level:2},{value:"ExecutableDeployItem",id:"executabledeployitem",level:2},{value:"<code>ModuleBytes</code>",id:"modulebytes",level:3},{value:"<code>StoredContractByHash</code>",id:"storedcontractbyhash",level:3},{value:"<code>StoredContractByName</code>",id:"storedcontractbyname",level:3},{value:"<code>StoredVersionContractByHash</code>",id:"storedversioncontractbyhash",level:3},{value:"<code>StoredVersionContractByName</code>",id:"storedversioncontractbyname",level:3},{value:"<code>Transfer</code>",id:"transfer",level:3},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"FinalizedApprovals",id:"finalizedapprovals",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:3},{value:"JsonBid",id:"jsonbid",level:2},{value:"JsonBids",id:"jsonbids",level:2},{value:"JsonBlock",id:"jsonblock",level:2},{value:"JsonBlockBody",id:"jsonblockbody",level:2},{value:"JsonBlockHeader",id:"jsonblockheader",level:2},{value:"JsonDelegator",id:"jsondelegator",level:2},{value:"JsonEraEnd",id:"jsoneraend",level:2},{value:"JsonEraReport",id:"jsonerareport",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonExecutionResult",id:"jsonexecutionresult",level:2},{value:"JsonProof",id:"jsonproof",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorweights",level:2},{value:"Merkle_Proof",id:"merkle-proof",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"NewValidator",id:"newvalidator",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"PeersMap",id:"peersmap",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReactorState",id:"reactorstate",level:2},{value:"Reward",id:"reward",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function o(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"types",children:"Types"})}),"\n",(0,i.jsx)(n.p,{children:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."}),"\n",(0,i.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,i.jsx)(n.p,{children:"Structure representing a user's Account, stored in global state."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#actionthresholds",children:(0,i.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#associatedkey",children:(0,i.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#namedkey",children:(0,i.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"accounthash",children:"AccountHash"}),"\n",(0,i.jsx)(n.p,{children:"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."}),"\n",(0,i.jsx)(n.h2,{id:"actionthresholds",children:"ActionThresholds"}),"\n",(0,i.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"deployment"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"key_management"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"activationpoint",children:"ActivationPoint"}),"\n",(0,i.jsx)(n.p,{children:"The first era to which the associated protocol version applies."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,i.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#signature",children:(0,i.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"signer"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,i.jsx)(n.p,{children:"A key granted limited permissions to an Account, for purposes such as multisig."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"weight"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"auctionstate",children:"AuctionState"}),"\n",(0,i.jsx)(n.p,{children:"Data structure summarizing auction contract data."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonbids",children:(0,i.jsx)(n.code,{children:"bids"})})," All bids contained within a vector."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," Block height."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsoneravalidators",children:(0,i.jsx)(n.code,{children:"era_validators"})})," Era validators."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," Global state hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"high"})," The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,i.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#delegator",children:(0,i.jsx)(n.code,{children:"delegators"})})," The validator's delegators, indexed by their public keys."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"inactive"})," ",(0,i.jsx)(n.code,{children:"true"}),' if validator has been "evicted".']}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#vestingschedule",children:(0,i.jsx)(n.code,{children:"vesting_schedule"})})," Vesting schedule for a genesis validator. ",(0,i.jsx)(n.code,{children:"None"})," if non-genesis validator."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"blockhash",children:"BlockHash"}),"\n",(0,i.jsxs)(n.p,{children:["A cryptographic hash identifying a ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"Hash"})})," Identify and retrieve the Block with its hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Height"})," Identify and retrieve the Block with its height."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"blocksynchronizerstatus",children:"BlockSynchronizerStatus"}),"\n",(0,i.jsx)(n.p,{children:"The status of the block synchronizer."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Historical"})," The status of syncing a historical block, if any."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Forward"})," The status of syncing a forward block, if any."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block."]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"chainspecrawbytes",children:"ChainspecRawBytes"}),"\n",(0,i.jsx)(n.p,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"chainspec_bytes"})," Hex-encoded raw bytes of the current chainspec.toml file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"maybe_genesis_accounts_bytes"})," Hex-encoded raw bytes of the current genesis accounts.toml file."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"maybe_global_state_bytes"})," Hex-encoded raw bytes of the current global_state.toml file."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,i.jsx)(n.p,{children:"A contract struct that can be serialized as a JSON object."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractpackagehash",children:(0,i.jsx)(n.code,{children:"contract_package_hash"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractwasmhash",children:(0,i.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypoint",children:(0,i.jsx)(n.code,{children:"entry_points"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#namedkey",children:(0,i.jsx)(n.code,{children:"named_keys"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version"})}),"\n",(0,i.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract."}),"\n",(0,i.jsx)(n.h2,{id:"contractpackage",children:"ContractPackage"}),"\n",(0,i.jsx)(n.p,{children:"Contract definition, metadata and security container."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"access_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#disabledversions",children:(0,i.jsx)(n.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#groups",children:(0,i.jsx)(n.code,{children:"groups"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contractversion",children:(0,i.jsx)(n.code,{children:"versions"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract package."}),"\n",(0,i.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,i.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#contracthash",children:(0,i.jsx)(n.code,{children:"contract_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,i.jsx)(n.p,{children:"The hash address of the contract Wasm."}),"\n",(0,i.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,i.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee").'}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#vestingschedule",children:(0,i.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,i.jsx)(n.p,{children:"A Deploy; an item containing a smart contract along with the requester's signature(s)."}),"\n",(0,i.jsx)(n.p,{children:"Required properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#approval",children:(0,i.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployheader",children:(0,i.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executabledeployitem",children:(0,i.jsx)(n.code,{children:"payment"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executabledeployitem",children:(0,i.jsx)(n.code,{children:"sessions"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deployhash",children:"DeployHash"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded Deploy hash."}),"\n",(0,i.jsx)(n.h2,{id:"deployheader",children:"DeployHeader"}),"\n",(0,i.jsx)(n.p,{children:"The header portion of a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"account"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"chain_name"})," A user defined string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"dependencies"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"gas_price"})," Defined as an integer in UInt64 format."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timediff",children:(0,i.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,i.jsx)(n.p,{children:"Information relating to the given Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hash"})})," The relevant Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"from"})})," Account identifier of the creator of the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"gas"})})," Gas cost of executing the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"source"})})," Source purse used for payment of the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})," Transfers performed by the Deploy."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"dictionaryidentifier",children:"DictionaryIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Options for dictionary item lookups."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AccountNamedKey"})," Lookup a dictionary item via an Account's named keys."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The Account key as a formatted string whose named keys contain dictionary_name."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ContractNamedKey"})," Lookup a dictionary item via a Contract's named keys."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The contract key as a formatted string whose named keys contains dictionary_name."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"URef"})," Lookup a dictionary item via its seed URef."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"seed_uref"})," The dictionary's seed URef."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Dictionary"})," Lookup a dictionary item via its unique key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded hash digest."}),"\n",(0,i.jsx)(n.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,i.jsx)(n.p,{children:"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypointaccess",children:(0,i.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#parameter",children:(0,i.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#entrypointtype",children:(0,i.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"name"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypointaccess",children:"EntryPointAccess"}),"\n",(0,i.jsx)(n.p,{children:"Enum describing the possible access control options for a contract entry point."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Public"})," A public entry point is callable by any caller."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#group",children:(0,i.jsx)(n.code,{children:"Groups"})})," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"entrypointtype",children:"EntryPointType"}),"\n",(0,i.jsx)(n.p,{children:"Context of an entry point execution."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"session"})," Executes in the caller's context."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"contract"})," Executes in the callee's context."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,i.jsx)(n.p,{children:"Era ID newtype."}),"\n",(0,i.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,i.jsx)(n.p,{children:"Auction metadata. Intended to be recorded at each era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#seigniorageallocation",children:(0,i.jsx)(n.code,{children:"seigniorage_allocation"})})," Information about a seigniorage allocation."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"erasummary",children:"EraSummary"}),"\n",(0,i.jsx)(n.p,{children:"The summary of an era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})," The Block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The era id."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#merkle-proof",children:(0,i.jsx)(n.code,{children:"merkle_proof"})})," The merkle proof."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," Hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#storedvalue",children:(0,i.jsx)(n.code,{children:"stored_value"})})," The StoredValue containing era information."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executabledeployitem",children:"ExecutableDeployItem"}),"\n",(0,i.jsx)(n.p,{children:"Represents possible variants of an executable Deploy."}),"\n",(0,i.jsx)(n.h3,{id:"modulebytes",children:(0,i.jsx)(n.code,{children:"ModuleBytes"})}),"\n",(0,i.jsxs)(n.p,{children:["Executable specified as raw bytes that represent Wasm code and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"module_bytes"})," Hex-encoded raw Wasm bytes. There are some special cases around passing ",(0,i.jsx)(n.code,{children:"module_bytes"})," for payment code."]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedcontractbyhash",children:(0,i.jsx)(n.code,{children:"StoredContractByHash"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored contract referenced by its ",(0,i.jsx)(n.code,{children:"ContractHash"}),", entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"hash"})," A hex-encoded hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedcontractbyname",children:(0,i.jsx)(n.code,{children:"StoredContractByName"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," A named key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedversioncontractbyhash",children:(0,i.jsx)(n.code,{children:"StoredVersionContractByHash"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored versioned contract referenced by its ",(0,i.jsx)(n.code,{children:"ContractPackageHash"}),", entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"hash"})," A hex-encoded hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"version"})," An optional version of the contract to call. It will default to the highest enabled version if no value is specified."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"storedversioncontractbyname",children:(0,i.jsx)(n.code,{children:"StoredVersionContractByName"})}),"\n",(0,i.jsxs)(n.p,{children:["Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of ",(0,i.jsx)(n.code,{children:"RuntimeArgs"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})," Runtime arguments."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"entry_point"})," The name of an entry point."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," A named key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"version"})," An optional version of the contract to call. It will default to the highest enabled version if no value is specified."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"transfer",children:(0,i.jsx)(n.code,{children:"Transfer"})}),"\n",(0,i.jsx)(n.p,{children:"A native transfer which does not contain or reference a Wasm code."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.a,{href:"#runtimeargs",children:(0,i.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,i.jsx)(n.p,{children:"The journal of execution transforms from a single Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#operation",children:(0,i.jsx)(n.code,{children:"operations"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transformentry",children:(0,i.jsx)(n.code,{children:"transforms"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,i.jsx)(n.p,{children:"The result of executing a single Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Failure"})," The result of a failed execution`"]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executioneffect",children:(0,i.jsx)(n.code,{children:"effect"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"cost"})})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"error_message"})," The error message associated with executing the Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Success"})," The result of a successful execution."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executioneffect",children:(0,i.jsx)(n.code,{children:"effect"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#transferaddr",children:(0,i.jsx)(n.code,{children:"transfers"})})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"cost"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"finalizedapprovals",children:"FinalizedApprovals"}),"\n",(0,i.jsxs)(n.p,{children:["A boolean value that determines whether to return the deploy with the finalized approvals substituted. If ",(0,i.jsx)(n.code,{children:"false"})," or omitted, returns the deploy with the approvals that were originally received by the node."]}),"\n",(0,i.jsx)(n.h2,{id:"globalstateidentifier",children:"GlobalStateIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"Identifier for possible ways to query global state."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"BlockHash"})})," Query using a Block hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"StateRootHash"})})," Query using the state root hash."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,i.jsx)(n.p,{children:'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'}),"\n",(0,i.jsx)(n.h3,{id:"groups",children:"Groups"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"group"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"keys"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonbid",children:"JsonBid"}),"\n",(0,i.jsx)(n.p,{children:"An entry in a founding validator map representing a bid."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsondelegator",children:(0,i.jsx)(n.code,{children:"delegators"})})," The delegators."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"inactive"})," Is this an inactive validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonbids",children:"JsonBids"}),"\n",(0,i.jsx)(n.p,{children:"A Json representation of a single bid."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonbid",children:(0,i.jsx)(n.code,{children:"bid"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblock",children:"JsonBlock"}),"\n",(0,i.jsxs)(n.p,{children:["A JSON-friendly representation of ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonblockbody",children:(0,i.jsx)(n.code,{children:"body"})})," JSON-friendly Block body."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"hash"})})," BlockHash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonblockheader",children:(0,i.jsx)(n.code,{children:"header"})})," JSON-friendly Block header."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonproof",children:(0,i.jsx)(n.code,{children:"proofs"})})," JSON-friendly list of proofs for this Block."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblockbody",children:"JsonBlockBody"}),"\n",(0,i.jsxs)(n.p,{children:["A JSON-friendly representation of ",(0,i.jsx)(n.code,{children:"Body"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hashes"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"proposer"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"transfer_hashes"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonblockheader",children:"JsonBlockHeader"}),"\n",(0,i.jsx)(n.p,{children:"JSON representation of a Block header."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"accumulated_seed"})})," Accumulated seed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"body_hash"})})," The body hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The Block era id."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"height"})," The Block height."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"parent_hash"})})," The parent hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#protocolversion",children:(0,i.jsx)(n.code,{children:"protocol_version"})})," The protocol version."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"random_bit"})," Randomness bit."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})," The state root hash."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})," The Block timestamp."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.a,{href:"#jsoneraend",children:(0,i.jsx)(n.code,{children:"era_end"})})," The era end."]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsondelegator",children:"JsonDelegator"}),"\n",(0,i.jsx)(n.p,{children:"A delegator associated with the given validator."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegatee"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsoneraend",children:"JsonEraEnd"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonerareport",children:"`era_report"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#validatorweight",children:(0,i.jsx)(n.code,{children:"next_era_validator_weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonerareport",children:"JsonEraReport"}),"\n",(0,i.jsx)(n.p,{children:"Equivocation and reward information to be included in the terminal Block."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"equivocators"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"inactive_validators"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#reward",children:(0,i.jsx)(n.code,{children:"rewards"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsoneravalidators",children:"JsonEraValidators"}),"\n",(0,i.jsx)(n.p,{children:"The validators for the given era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#jsonvalidatorweights",children:(0,i.jsx)(n.code,{children:"validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonexecutionresult",children:"JsonExecutionResult"}),"\n",(0,i.jsx)(n.p,{children:"The execution result of a single Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"block_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#executionresult",children:(0,i.jsx)(n.code,{children:"result"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonproof",children:"JsonProof"}),"\n",(0,i.jsx)(n.p,{children:"A JSON-friendly representation of a proof, i.e. a Block's finality signature."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#signature",children:(0,i.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorchanges",children:"JsonValidatorChanges"}),"\n",(0,i.jsx)(n.p,{children:"The changes in a validator's status."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})," The public key of the validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#jsonvalidatorstatuschange",children:(0,i.jsx)(n.code,{children:"status_changes"})})," The set of changes to the validator's status."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorstatuschange",children:"JsonValidatorStatusChange"}),"\n",(0,i.jsx)(n.p,{children:"A single change to a validator's status in the given era."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})," The era in which the change occurred."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#validatorchange",children:(0,i.jsx)(n.code,{children:"validator_change"})})," The change in validator status."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"jsonvalidatorweights",children:"JsonValidatorsWeights"}),"\n",(0,i.jsx)(n.p,{children:"A validator's weight."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"merkle-proof",children:"Merkle_Proof"}),"\n",(0,i.jsx)(n.p,{children:"A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes."}),"\n",(0,i.jsx)(n.h2,{id:"minimalblockinfo",children:"MinimalBlockInfo"}),"\n",(0,i.jsxs)(n.p,{children:["Minimal info of a ",(0,i.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"creator"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#blockhash",children:(0,i.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"height"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#digest",children:(0,i.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#timestamp",children:(0,i.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,i.jsx)(n.p,{children:"Named arguments to a contract."}),"\n",(0,i.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,i.jsx)(n.p,{children:"A named key."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The value of the entry: a casper ",(0,i.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"name"})," The name of the entry."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"nextupgrade",children:"NextUpgrade"}),"\n",(0,i.jsx)(n.p,{children:"Information about the next protocol upgrade."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#activationpoint",children:(0,i.jsx)(n.code,{children:"activation_point"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"protocol_version"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"newvalidator",children:"NewValidator"}),"\n",(0,i.jsxs)(n.p,{children:["The public key for the new validator in a redelegation using ",(0,i.jsx)(n.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,i.jsx)(n.p,{children:"An operation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,i.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#opkind",children:(0,i.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"opkind",children:"OpKind"}),"\n",(0,i.jsx)(n.p,{children:"The type of operation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,i.jsx)(n.p,{children:"Parameter to an entry point."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"name"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"peerentry",children:"PeerEntry"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"address"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"node_id"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"peersmap",children:"PeersMap"}),"\n",(0,i.jsx)(n.p,{children:"Map of peer IDs to network addresses."}),"\n",(0,i.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,i.jsx)(n.p,{children:"Casper Platform protocol version."}),"\n",(0,i.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded cryptographic public key, including the algorithm tag prefix."}),"\n",(0,i.jsx)(n.h2,{id:"purseidentifier",children:"PurseIdentifier"}),"\n",(0,i.jsx)(n.p,{children:"The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"main_purse_under_public_key"})," The main purse under a provided ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"main_purse_under_account_hash"})," The main purse under a provided ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_chain#accounthash",children:(0,i.jsx)(n.code,{children:"AccountHash"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"purse_uref"})," A specific purse identified by the associated ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_chain#uref",children:(0,i.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"reactorstate",children:"ReactorState"}),"\n",(0,i.jsx)(n.p,{children:"The state of the reactor, which will return one of the following:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Initialize"})," Get all components and reactor state set up on start."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CatchUp"})," Orient to the network and attempt to catch up to tip."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Upgrading"})," Running commit upgrade and creating immediate switch block."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"KeepUp"})," Stay caught up with tip."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Validate"})," Node is currently caught up and is an active validator."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ShutdownForUpgrade"})," Node should be shut down for upgrade."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"reward",children:"Reward"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"amount"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,i.jsx)(n.p,{children:"Represents a collection of arguments passed to a smart contract."}),"\n",(0,i.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,i.jsx)(n.p,{children:"Information about a seigniorage allocation."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Validator"})," Info about a seigniorage allocation for a validator."]}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Delegator"})," Info about a seigniorage allocation for a delegator."]}),"\n",(0,i.jsx)(n.p,{children:"Require Parameters:"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"delegator_public_key"})})," Delegator's public key."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded cryptographic signature, including the algorithm tag prefix."}),"\n",(0,i.jsx)(n.h2,{id:"storedvalue",children:"StoredValue"}),"\n",(0,i.jsxs)(n.p,{children:["Representation of a value stored in global state. ",(0,i.jsx)(n.code,{children:"Account"}),", ",(0,i.jsx)(n.code,{children:"Contract"})," and ",(0,i.jsx)(n.code,{children:"ContractPackage"})," have their own ",(0,i.jsx)(n.code,{children:"json_compatibility"})," representation (see their docs for further info)."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_cl",children:(0,i.jsx)(n.code,{children:"CLValue"})})," A Casper-specific value."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#account",children:(0,i.jsx)(n.code,{children:"Account"})})," An Account."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"ContractWasm"})," A contract's Wasm."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#contract",children:(0,i.jsx)(n.code,{children:"Contract"})})," Entry points supported by a contract."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#contractpackage",children:(0,i.jsx)(n.code,{children:"ContractPackage"})})," A contract definition, metadata, and security container."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transfer",children:(0,i.jsx)(n.code,{children:"Transfer"})})," A record of a transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployinfo",children:(0,i.jsx)(n.code,{children:"DeployInfo"})})," A record of a Deploy."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#erainfo",children:(0,i.jsx)(n.code,{children:"EraInfo"})})," Auction metadata."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#bid",children:(0,i.jsx)(n.code,{children:"Bid"})})," A bid."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#unbondingpurse",children:(0,i.jsx)(n.code,{children:"Withdraw"})})," A withdraw."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,i.jsx)(n.p,{children:"Human-readable duration."}),"\n",(0,i.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,i.jsx)(n.p,{children:"Timestamp formatted as per RFC 3339."}),"\n",(0,i.jsx)(n.h2,{id:"transfer",children:"Transfer"}),"\n",(0,i.jsx)(n.p,{children:"Represents a transfer from one purse to another."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#deployhash",children:(0,i.jsx)(n.code,{children:"deploy_hash"})})," Deploy that created the transfer."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"from"})})," Account from which transfer was executed."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#accounthash",children:(0,i.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded transfer address."}),"\n",(0,i.jsx)(n.h2,{id:"transform",children:"Transform"}),"\n",(0,i.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteCLValue"})," Write the given ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/types_cl#clvalue",children:"CLValue"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteAccount"})," Writes the given ",(0,i.jsx)(n.a,{href:"#accounthash",children:"Account"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteDeployInfo"})," Writes the given ",(0,i.jsx)(n.a,{href:"#deployinfo",children:"DeployInfo"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteEraInfo"})," Writes the given ",(0,i.jsx)(n.a,{href:"#erainfo",children:"EraInfo"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteTransfer"})," Writes the given ",(0,i.jsx)(n.a,{href:"#transfer",children:"Transfer"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteBid"})," Writes the given ",(0,i.jsx)(n.a,{href:"#bid",children:"Bid"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"WriteWithdraw"})," Writes the given ",(0,i.jsx)(n.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,i.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,i.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u128",children:(0,i.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u256",children:(0,i.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,i.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"Failure"})," A failed transformation, containing an error message."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,i.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,i.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#transform",children:(0,i.jsx)(n.code,{children:"transforms"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"u128",children:"U128"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 128-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"u256",children:"U256"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 256-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"u512",children:"U512"}),"\n",(0,i.jsx)(n.p,{children:"Decimal representation of a 512-bit integer."}),"\n",(0,i.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,i.jsx)(n.p,{children:"Unbonding purse."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#newvalidator",children:(0,i.jsx)(n.code,{children:"new_validator"})})," The redelegated validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,i.jsx)(n.p,{children:"Hex-encoded, formatted URef."}),"\n",(0,i.jsx)(n.h2,{id:"validatorchange",children:"ValidatorChange"}),"\n",(0,i.jsx)(n.p,{children:"A change to a validator's status between two eras."}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Added"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Removed"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"Banned"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"CannotPropose"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.code,{children:"SeenAsFaulty"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"validatorweight",children:"ValidatorWeight"}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"vestingschedule",children:"VestingSchedule"}),"\n",(0,i.jsx)(n.p,{children:"Vesting schedule for a genesis validator."}),"\n",(0,i.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,i.jsx)(n.p,{children:"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."}),"\n",(0,i.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#u512",children:(0,i.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#uref",children:(0,i.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#eraid",children:(0,i.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"#publickey",children:(0,i.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]})]})}function t(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var i=s(96540);const r={},d=i.createContext(r);function l(e){const n=i.useContext(d);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),i.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae470ddc.47363dbf.js b/assets/js/ae470ddc.47363dbf.js new file mode 100644 index 000000000..71327c4b5 --- /dev/null +++ b/assets/js/ae470ddc.47363dbf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31089],{5029:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var i=n(74848),s=n(28453);const a={title:"Delegate with Ledger",slug:"/users/staking-ledger"},r="Delegating with Ledger Devices",o={id:"users/ledger/staking-ledger",title:"Delegate with Ledger",description:"Ledger Initialization",source:"@site/docs/users/ledger/staking-ledger.md",sourceDirName:"users/ledger",slug:"/users/staking-ledger",permalink:"/users/staking-ledger",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Delegate with Ledger",slug:"/users/staking-ledger"},sidebar:"users",previous:{title:"Ledger and CSPR.live",permalink:"/users/ledger/ledger-cspr-live"}},l={},d=[{value:"Ledger Initialization",id:"1-initialization",level:2},{value:"<strong>Important Notes</strong>",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-with-ledger-devices",children:"Delegating with Ledger Devices"})}),"\n",(0,i.jsx)(t.h2,{id:"1-initialization",children:"Ledger Initialization"}),"\n",(0,i.jsx)(t.p,{children:"Before getting started, you need to complete two prerequisite steps:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Set up your Ledger device using the ",(0,i.jsx)(t.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"official documentation"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect the Ledger to your ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," account by following the ",(0,i.jsx)(t.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup"})," guide."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"important-notes",children:(0,i.jsx)(t.strong,{children:"Important Notes"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,i.jsxs)(t.li,{children:["When logging in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.jsx)(t.a,{href:"https://www.ledger.com/academy/crypto/where-are-my-coins",children:"more info here"}),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"2-staking",children:"Staking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"connect-and-login-with-ledger",children:"Connect and Login with Ledger"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger to your computer via USB and enter your PIN to unlock it."}),"\n",(0,i.jsx)(t.li,{children:'Open the Casper app on the Ledger (you will see the message "Casper Ready").'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready",src:n(92859).A+"",width:"1849",height:"1479"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Sign in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 2",src:n(37824).A+"",width:"1850",height:"726"})}),"\n",(0,i.jsxs)(t.ol,{start:"4",children:["\n",(0,i.jsx)(t.li,{children:"Select the public key connected to your Ledger account."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 3",src:n(92649).A+"",width:"1999",height:"1295"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsx)(t.li,{children:"View your account by clicking on your public key at the top right corner."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 4",src:n(18390).A+"",width:"1982",height:"1384"})}),"\n",(0,i.jsx)(t.h3,{id:"receive-tokens-from-an-external-source",children:"Receive Tokens from an External Source"}),"\n",(0,i.jsxs)(t.p,{children:["This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.jsx)(t.a,{href:"/workflow/ledger-setup/#receive-tokens",children:"documentation"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"staking-tokens",children:"Staking Tokens"}),"\n",(0,i.jsx)(t.p,{children:"Once you have tokens in your account, staking (delegating) with a validator is easy."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:['Go back to your account, but this time open the "delegate" tab located at: ',(0,i.jsx)(t.a,{href:"https://cspr.live/delegate-stake",children:"https://cspr.live/delegate-stake"})," (alternatively, click on ",(0,i.jsx)(t.code,{children:"Wallet \u21d2 Delegate Stake"})," to go there)."]}),"\n",(0,i.jsx)(t.li,{children:"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you."}),"\n",(0,i.jsxs)(t.li,{children:['Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:\n',(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."}),"\n",(0,i.jsx)(t.li,{children:"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.li,{children:'Click "Next" to continue, as shown below.'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 5",src:n(96479).A+"",width:"1255",height:"995"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.'}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.']}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 6",src:n(82916).A+"",width:"1190",height:"1778"})}),"\n",(0,i.jsxs)(t.ol,{start:"7",children:["\n",(0,i.jsxs)(t.li,{children:['On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 7",src:n(9069).A+"",width:"1999",height:"791"})}),"\n",(0,i.jsxs)(t.ol,{start:"8",children:["\n",(0,i.jsx)(t.li,{children:'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.img,{alt:"Casper Ready 8",src:n(21562).A+"",width:"1230",height:"370"}),"\n",(0,i.jsx)(t.img,{alt:"Casper Ready 9",src:n(26787).A+"",width:"1324",height:"427"})]}),"\n",(0,i.jsxs)(t.ol,{start:"9",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 10",src:n(20435).A+"",width:"1999",height:"1203"})}),"\n",(0,i.jsx)(t.h2,{id:"3-unstaking",children:"Unstaking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"initiate-the-undelegation",children:"Initiate the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 11",src:n(88522).A+"",width:"1211",height:"861"})}),"\n",(0,i.jsx)(t.p,{children:'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 12",src:n(45953).A+"",width:"1212",height:"958"})}),"\n",(0,i.jsx)(t.p,{children:'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'}),"\n",(0,i.jsx)(t.h3,{id:"sign-the-undelegation",children:"Sign the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:"You will have to sign the transaction to verify your account is initiating this action."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger device to your computer."}),"\n",(0,i.jsx)(t.li,{children:"Unlock your Ledger by entering your PIN."}),"\n",(0,i.jsx)(t.li,{children:'Open the "Casper" app and ensure you see "Casper Ready".'}),"\n",(0,i.jsxs)(t.li,{children:["Then back on ",(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),' click the "Sign with Ledger" button shown below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 13",src:n(24824).A+"",width:"1202",height:"1318"})}),"\n",(0,i.jsx)(t.p,{children:'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 14",src:n(46967).A+"",width:"1208",height:"921"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 15",src:n(47470).A+"",width:"1205",height:"736"})}),"\n",(0,i.jsx)(t.p,{children:"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},92859:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger1-39686f6ffc5ad108d8e08973a40103f5.png"},20435:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger10-ee4f4fd9d8bf12ad0f33c5e3b4ada52c.png"},88522:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger11-475f40691a8f46d17fdeb029786ac923.png"},45953:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger12-7fe9fa74a7040dcf0fdb703c2ad1464f.png"},24824:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger13-4e3e030cf508f30ff250d22230e7dec9.png"},46967:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger14-35808a8e588d4316a63c8c7c1b050dd2.png"},47470:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger15-5d758ba4698580290a72e3d4d564c9b1.png"},37824:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger2-f1e2691594ec0cdcc0bec706cd2aade5.png"},92649:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger3-9b464ab0befd3928a5c659c77cf9555c.png"},18390:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger4-9a921643c0431d1eac3009da497cb280.png"},96479:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger5-9853a9b9bebe07a3a24f1febfac4ca03.png"},82916:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger6-b50bdcc2ba945ebf349fc3396785adc0.png"},9069:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger7-2d020b9e8d2b40169e089bda6ff77dda.png"},21562:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger8-c3399bf73ccd1e844f6f5790c7ad1796.png"},26787:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger9-97001e377d0f7629626696f888dde09a.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var i=n(96540);const s={},a=i.createContext(s);function r(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae470ddc.f89950ff.js b/assets/js/ae470ddc.f89950ff.js deleted file mode 100644 index 8cab6c35e..000000000 --- a/assets/js/ae470ddc.f89950ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1089],{5029:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var i=n(74848),s=n(28453);const a={title:"Delegate with Ledger",slug:"/users/staking-ledger"},r="Delegating with Ledger Devices",o={id:"users/ledger/staking-ledger",title:"Delegate with Ledger",description:"Ledger Initialization",source:"@site/docs/users/ledger/staking-ledger.md",sourceDirName:"users/ledger",slug:"/users/staking-ledger",permalink:"/next/users/staking-ledger",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Delegate with Ledger",slug:"/users/staking-ledger"},sidebar:"users",previous:{title:"Ledger and CSPR.live",permalink:"/next/users/ledger/ledger-cspr-live"}},l={},d=[{value:"Ledger Initialization",id:"1-initialization",level:2},{value:"<strong>Important Notes</strong>",id:"important-notes",level:3},{value:"Staking with a Validator",id:"2-staking",level:2},{value:"Connect and Login with Ledger",id:"connect-and-login-with-ledger",level:3},{value:"Receive Tokens from an External Source",id:"receive-tokens-from-an-external-source",level:3},{value:"Staking Tokens",id:"staking-tokens",level:3},{value:"Unstaking with a Validator",id:"3-unstaking",level:2},{value:"Initiate the Undelegation",id:"initiate-the-undelegation",level:3},{value:"Sign the Undelegation",id:"sign-the-undelegation",level:3}];function c(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"delegating-with-ledger-devices",children:"Delegating with Ledger Devices"})}),"\n",(0,i.jsx)(t.h2,{id:"1-initialization",children:"Ledger Initialization"}),"\n",(0,i.jsx)(t.p,{children:"Before getting started, you need to complete two prerequisite steps:"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:["Set up your Ledger device using the ",(0,i.jsx)(t.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"official documentation"}),"."]}),"\n",(0,i.jsxs)(t.li,{children:["Connect the Ledger to your ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"})," account by following the ",(0,i.jsx)(t.a,{href:"/next/workflow/ledger-setup/",children:"Ledger Setup"})," guide."]}),"\n"]}),"\n",(0,i.jsx)(t.h3,{id:"important-notes",children:(0,i.jsx)(t.strong,{children:"Important Notes"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.strong,{children:'<span style={{color:"#ee5945"}}>CRITICAL'}),": Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key."]}),"\n",(0,i.jsxs)(t.li,{children:["When logging in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),", the UI will offer numerous public keys. Choose any of them. They are all derived from the Master Seed that is secured in the Ledger key (",(0,i.jsx)(t.a,{href:"https://www.ledger.com/academy/crypto/where-are-my-coins",children:"more info here"}),"). Make sure you write down whichever public key(s) you end up using so that you have no confusion when trying to log in."]}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"2-staking",children:"Staking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"connect-and-login-with-ledger",children:"Connect and Login with Ledger"}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger to your computer via USB and enter your PIN to unlock it."}),"\n",(0,i.jsx)(t.li,{children:'Open the Casper app on the Ledger (you will see the message "Casper Ready").'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready",src:n(39021).A+"",width:"1849",height:"1479"})}),"\n",(0,i.jsxs)(t.ol,{start:"3",children:["\n",(0,i.jsxs)(t.li,{children:["Sign in to ",(0,i.jsx)(t.a,{href:"https://cspr.live/",children:"cspr.live"}),' with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 2",src:n(57398).A+"",width:"1850",height:"726"})}),"\n",(0,i.jsxs)(t.ol,{start:"4",children:["\n",(0,i.jsx)(t.li,{children:"Select the public key connected to your Ledger account."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 3",src:n(53727).A+"",width:"1999",height:"1295"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsx)(t.li,{children:"View your account by clicking on your public key at the top right corner."}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 4",src:n(2400).A+"",width:"1982",height:"1384"})}),"\n",(0,i.jsx)(t.h3,{id:"receive-tokens-from-an-external-source",children:"Receive Tokens from an External Source"}),"\n",(0,i.jsxs)(t.p,{children:["This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the ",(0,i.jsx)(t.a,{href:"/next/workflow/ledger-setup/#receive-tokens",children:"documentation"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"staking-tokens",children:"Staking Tokens"}),"\n",(0,i.jsx)(t.p,{children:"Once you have tokens in your account, staking (delegating) with a validator is easy."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:['Go back to your account, but this time open the "delegate" tab located at: ',(0,i.jsx)(t.a,{href:"https://cspr.live/delegate-stake",children:"https://cspr.live/delegate-stake"})," (alternatively, click on ",(0,i.jsx)(t.code,{children:"Wallet \u21d2 Delegate Stake"})," to go there)."]}),"\n",(0,i.jsx)(t.li,{children:"From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you."}),"\n",(0,i.jsxs)(t.li,{children:['Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:\n',(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Remember that the total delegation amount to one validator cannot be less than 500 CSPR."}),"\n",(0,i.jsx)(t.li,{children:"Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later."}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.li,{children:'Click "Next" to continue, as shown below.'}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 5",src:n(73577).A+"",width:"1255",height:"995"})}),"\n",(0,i.jsxs)(t.ol,{start:"5",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.'}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.']}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 6",src:n(82866).A+"",width:"1190",height:"1778"})}),"\n",(0,i.jsxs)(t.ol,{start:"7",children:["\n",(0,i.jsxs)(t.li,{children:['On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on ',(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 7",src:n(80731).A+"",width:"1999",height:"791"})}),"\n",(0,i.jsxs)(t.ol,{start:"8",children:["\n",(0,i.jsx)(t.li,{children:'Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.'}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.img,{alt:"Casper Ready 8",src:n(26572).A+"",width:"1230",height:"370"}),"\n",(0,i.jsx)(t.img,{alt:"Casper Ready 9",src:n(12021).A+"",width:"1324",height:"427"})]}),"\n",(0,i.jsxs)(t.ol,{start:"9",children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.'}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),": If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens."]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 10",src:n(73721).A+"",width:"1999",height:"1203"})}),"\n",(0,i.jsx)(t.h2,{id:"3-unstaking",children:"Unstaking with a Validator"}),"\n",(0,i.jsx)(t.h3,{id:"initiate-the-undelegation",children:"Initiate the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:'Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account\'s profile page, click "Undelegate" to get started.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 11",src:n(67472).A+"",width:"1211",height:"861"})}),"\n",(0,i.jsx)(t.p,{children:'The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 12",src:n(38763).A+"",width:"1212",height:"958"})}),"\n",(0,i.jsx)(t.p,{children:'You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.'}),"\n",(0,i.jsx)(t.h3,{id:"sign-the-undelegation",children:"Sign the Undelegation"}),"\n",(0,i.jsx)(t.p,{children:"You will have to sign the transaction to verify your account is initiating this action."}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsx)(t.li,{children:"Connect your Ledger device to your computer."}),"\n",(0,i.jsx)(t.li,{children:"Unlock your Ledger by entering your PIN."}),"\n",(0,i.jsx)(t.li,{children:'Open the "Casper" app and ensure you see "Casper Ready".'}),"\n",(0,i.jsxs)(t.li,{children:["Then back on ",(0,i.jsx)(t.a,{href:"https://cspr.live",children:"cspr.live"}),' click the "Sign with Ledger" button shown below.']}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 13",src:n(17634).A+"",width:"1202",height:"1318"})}),"\n",(0,i.jsx)(t.p,{children:'On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.'}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 14",src:n(21885).A+"",width:"1208",height:"921"})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.']}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{alt:"Casper Ready 15",src:n(88852).A+"",width:"1205",height:"736"})}),"\n",(0,i.jsx)(t.p,{children:"After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},39021:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger1-39686f6ffc5ad108d8e08973a40103f5.png"},73721:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger10-ee4f4fd9d8bf12ad0f33c5e3b4ada52c.png"},67472:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger11-475f40691a8f46d17fdeb029786ac923.png"},38763:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger12-7fe9fa74a7040dcf0fdb703c2ad1464f.png"},17634:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger13-4e3e030cf508f30ff250d22230e7dec9.png"},21885:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger14-35808a8e588d4316a63c8c7c1b050dd2.png"},88852:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger15-5d758ba4698580290a72e3d4d564c9b1.png"},57398:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger2-f1e2691594ec0cdcc0bec706cd2aade5.png"},53727:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger3-9b464ab0befd3928a5c659c77cf9555c.png"},2400:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger4-9a921643c0431d1eac3009da497cb280.png"},73577:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger5-9853a9b9bebe07a3a24f1febfac4ca03.png"},82866:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger6-b50bdcc2ba945ebf349fc3396785adc0.png"},80731:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger7-2d020b9e8d2b40169e089bda6ff77dda.png"},26572:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger8-c3399bf73ccd1e844f6f5790c7ad1796.png"},12021:(e,t,n)=>{n.d(t,{A:()=>i});const i=n.p+"assets/images/ledger9-97001e377d0f7629626696f888dde09a.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var i=n(96540);const s={},a=i.createContext(s);function r(e){const t=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ae5d26cf.38358f39.js b/assets/js/ae5d26cf.38358f39.js new file mode 100644 index 000000000..c1721554c --- /dev/null +++ b/assets/js/ae5d26cf.38358f39.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67461],{14377:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(74848),s=n(28453);const i={title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},r="Owner Reverse Lookup Functionality",a={id:"resources/tokens/cep78/reverse-lookup",title:"Ownership Lookup",description:"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/reverse-lookup.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/reverse-lookup",permalink:"/2.0.0/resources/tokens/cep78/reverse-lookup",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/2.0.0/resources/tokens/using-casper-client"},next:{title:"CEP-78 JavaScript Client",permalink:"/2.0.0/resources/tokens/cep78/js-tutorial"}},c={},l=[{value:"The CEP-78 Page System",id:"the-cep-78-page-system",level:2},{value:"Updated Receipts",id:"updated-receipts",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"owner-reverse-lookup-functionality",children:"Owner Reverse Lookup Functionality"})}),"\n",(0,o.jsxs)(t.p,{children:["In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found ",(0,o.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"here"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract."}),"\n",(0,o.jsx)(t.p,{children:"This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page."}),"\n",(0,o.jsx)(t.h2,{id:"the-cep-78-page-system",children:"The CEP-78 Page System"}),"\n",(0,o.jsxs)(t.p,{children:["Ownership of NFTs within a CEP-78 contract is now tracked with a series of ",(0,o.jsx)(t.code,{children:"pages"}),", with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs."]}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"page_table"})," tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the ",(0,o.jsx)(t.code,{children:"register_owner"})," entrypoint."]}),"\n",(0,o.jsxs)(t.p,{children:["After registering as an owner, the contract creates an entry within the ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for the minting account or contract. This dictionary entry consists of a series of ",(0,o.jsx)(t.code,{children:"boolean"})," values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false."]}),"\n",(0,o.jsxs)(t.p,{children:["Upon minting the token, the user will pay for a page allocation. This adds them to the ",(0,o.jsx)(t.code,{children:"page"})," dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the ",(0,o.jsx)(t.code,{children:"page"})," dictionary will consist of 1,000 ",(0,o.jsx)(t.code,{children:"page_address"})," bits set to ",(0,o.jsx)(t.code,{children:"False"})," upon allocation, and the minting of any given token in that page will set the ",(0,o.jsx)(t.code,{children:"page_address"})," bit to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, that account or contract's ",(0,o.jsx)(t.code,{children:"page_table"})," will be updated by marking the corresponding page number's bit as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"The contract registers their account as an owner."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The contract creates a ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for that account, with 10 boolean values. As the numbering system begins with ",(0,o.jsx)(t.code,{children:"0"}),", the third boolean value corresponding with page ",(0,o.jsx)(t.code,{children:"2"})," is set to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The account pays for allocation of page 2, creating an entry in the ",(0,o.jsx)(t.code,{children:"Page 2"})," dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 350 as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for ",(0,o.jsx)(t.code,{children:"page 5"})," to be allocated to them. They would then be added to the ",(0,o.jsx)(t.code,{children:"page 5"})," dictionary with the ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 125 set as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"This system binds the data writing costs to a maximum size of any given page dictionary."}),"\n",(0,o.jsx)(t.h2,{id:"updated-receipts",children:"Updated Receipts"}),"\n",(0,o.jsxs)(t.p,{children:["If the contract enables ",(0,o.jsx)(t.code,{children:"OwnerReverseLookupMode"}),", calling the ",(0,o.jsx)(t.code,{children:"updated_receipts"})," entrypoint will return a list of receipt names alongside the dictionary for the relevant pages."]}),"\n",(0,o.jsxs)(t.p,{children:["Updated receipts come in the format of ",(0,o.jsx)(t.code,{children:'"{<collection name>}\\_m{modulo}\\_p{<page number>}"'}),". Once again using the 2,350th token as an example, the receipt would read:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"cep78_collection_m_350_p_2\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can determine the token number by multiplying the ",(0,o.jsx)(t.code,{children:"page_number"})," by the ",(0,o.jsx)(t.code,{children:"page_size"}),"(1,000) and adding the ",(0,o.jsx)(t.code,{children:"modulo"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["If the ",(0,o.jsx)(t.code,{children:"NFTIdentifierMode"})," is set to ",(0,o.jsx)(t.code,{children:"Ordinal"}),", this number corresponds directly to the token ID."]}),"\n",(0,o.jsxs)(t.p,{children:["If it is set to ",(0,o.jsx)(t.code,{children:"Hash"}),", you will need to reference the ",(0,o.jsx)(t.code,{children:"HASH_BY_INDEX"})," dictionary to determine the mapping of token numbers to token hashes."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aee0fe92.50fa9bd5.js b/assets/js/aee0fe92.50fa9bd5.js new file mode 100644 index 000000000..a219959f3 --- /dev/null +++ b/assets/js/aee0fe92.50fa9bd5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27832],{32330:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const o={title:"Overview"},i="Interacting with the Casper JSON-RPC API",c={id:"developers/json-rpc/index",title:"Overview",description:"Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/index.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/",permalink:"/1.5.X/developers/json-rpc/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview"},sidebar:"developers",previous:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/1.5.X/developers/writing-onchain-code/best-practices"},next:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/1.5.X/developers/json-rpc/guidance"}},a={},d=[{value:"Table of Contents",id:"table-of-contents",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"interacting-with-the-casper-json-rpc-api",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses a custom JSON-RPC implementation known as ",(0,s.jsx)(n.code,{children:"casper-json-rpc"})," that is compliant with the ",(0,s.jsx)(n.a,{href:"https://www.jsonrpc.org/specification",children:"JSON-RPC 2.0 specification"}),". If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use ",(0,s.jsx)(n.a,{href:"https://www.postman.com/",children:"Postman"})," or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification."]}),"\n",(0,s.jsxs)(n.p,{children:["Casper nodes provide the RPC schema on port ",(0,s.jsx)(n.code,{children:"8888"}),", followed by ",(0,s.jsx)(n.code,{children:"rpc-schema"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"<HOST:8888>/rpc-schema \n"})}),"\n",(0,s.jsx)(n.p,{children:"To see an example, navigate to a node's RPC schema using a browser."}),"\n",(0,s.jsxs)(n.p,{children:["The Casper client subcommand ",(0,s.jsx)(n.code,{children:"list-rpcs"})," provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"casper-client list-rpcs --node-address <HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Page"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/guidance",children:"Guidance for JSON-RPC SDK Compliance"})}),(0,s.jsx)(n.td,{children:"Requirements for a compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/minimal-compliance",children:"Required JSON-RPC Methods for Minimal Compliance"})}),(0,s.jsx)(n.td,{children:"Methods required for a minimally compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-transactional",children:"Transactional JSON-RPC Method"})}),(0,s.jsx)(n.td,{children:"Methods allowing interaction with a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-informational",children:"Informational JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods returning information about the network from a Casper node"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods pertaining to Proof-of-Stake functionality on a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_chain",children:"Types"})}),(0,s.jsx)(n.td,{children:"Information on types used within JSON-RPC methods"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/types_cl",children:"CL Types"})}),(0,s.jsx)(n.td,{children:"Information related to CL Types"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aee0fe92.cc892c71.js b/assets/js/aee0fe92.cc892c71.js deleted file mode 100644 index b8e0aa3da..000000000 --- a/assets/js/aee0fe92.cc892c71.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7832],{32330:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const o={title:"Overview"},i="Interacting with the Casper JSON-RPC API",c={id:"developers/json-rpc/index",title:"Overview",description:"Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.",source:"@site/versioned_docs/version-1.5.X/developers/json-rpc/index.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/",permalink:"/developers/json-rpc/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview"},sidebar:"developers",previous:{title:"Best Practices for Casper Smart Contract Authors",permalink:"/developers/writing-onchain-code/best-practices"},next:{title:"Guidance for JSON-RPC SDK Compliance",permalink:"/developers/json-rpc/guidance"}},a={},d=[{value:"Table of Contents",id:"table-of-contents",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"interacting-with-the-casper-json-rpc-api",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,s.jsxs)(n.p,{children:["Casper uses a custom JSON-RPC implementation known as ",(0,s.jsx)(n.code,{children:"casper-json-rpc"})," that is compliant with the ",(0,s.jsx)(n.a,{href:"https://www.jsonrpc.org/specification",children:"JSON-RPC 2.0 specification"}),". If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use ",(0,s.jsx)(n.a,{href:"https://www.postman.com/",children:"Postman"})," or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification."]}),"\n",(0,s.jsxs)(n.p,{children:["Casper nodes provide the RPC schema on port ",(0,s.jsx)(n.code,{children:"8888"}),", followed by ",(0,s.jsx)(n.code,{children:"rpc-schema"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"<HOST:8888>/rpc-schema \n"})}),"\n",(0,s.jsx)(n.p,{children:"To see an example, navigate to a node's RPC schema using a browser."}),"\n",(0,s.jsxs)(n.p,{children:["The Casper client subcommand ",(0,s.jsx)(n.code,{children:"list-rpcs"})," provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-sh",children:"casper-client list-rpcs --node-address <HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Page"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/guidance",children:"Guidance for JSON-RPC SDK Compliance"})}),(0,s.jsx)(n.td,{children:"Requirements for a compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/minimal-compliance",children:"Required JSON-RPC Methods for Minimal Compliance"})}),(0,s.jsx)(n.td,{children:"Methods required for a minimally compliant Casper SDK"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-transactional",children:"Transactional JSON-RPC Method"})}),(0,s.jsx)(n.td,{children:"Methods allowing interaction with a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational",children:"Informational JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods returning information about the network from a Casper node"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-pos",children:"Proof-of-Stake JSON-RPC Methods"})}),(0,s.jsx)(n.td,{children:"Methods pertaining to Proof-of-Stake functionality on a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"Types"})}),(0,s.jsx)(n.td,{children:"Information on types used within JSON-RPC methods"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_cl",children:"CL Types"})}),(0,s.jsx)(n.td,{children:"Information related to CL Types"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var s=t(96540);const r={},o=s.createContext(r);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aefd42fa.03d773c1.js b/assets/js/aefd42fa.03d773c1.js deleted file mode 100644 index 74c502c62..000000000 --- a/assets/js/aefd42fa.03d773c1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1418],{90171:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var i=s(74848),t=s(28453);const r={title:"Open Files Limit"},o="Setting the Open Files Limit",l={id:"operators/setup/open-files",title:"Open Files Limit",description:"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.",source:"@site/versioned_docs/version-1.5.X/operators/setup/open-files.md",sourceDirName:"operators/setup",slug:"/operators/setup/open-files",permalink:"/operators/setup/open-files",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Open Files Limit"},sidebar:"operators",previous:{title:"Fast Sync",permalink:"/operators/setup/fast-sync"},next:{title:"Upgrades",permalink:"/operators/setup/upgrade"}},c={},a=[{value:"Setting the Limit Manually",id:"updating-manually",level:2},{value:"Updating the <code>limits.conf</code> File",id:"updating-limits-conf",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",summary:"summary",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"setting-the-open-files-limit",children:"Setting the Open Files Limit"})}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node"})," launches, it tries to set the maximum open files limit (",(0,i.jsx)(n.code,{children:"nofile"}),") for the process to ",(0,i.jsx)(n.code,{children:"64000"}),". With some systems, this limit will be larger than the default hard limit of ",(0,i.jsx)(n.code,{children:"4096"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.jsx)(n.code,{children:"nofile"})," limit needs to be increased."]}),"\n",(0,i.jsxs)(n.p,{children:["With the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.jsx)(n.code,{children:"casper-node"})," with the following command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'pgrep "casper-node$"\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ pgrep "casper-node$"\n275928\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.jsx)(n.code,{children:"275928"})," each time."]})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you do not get a value in return, you do not have the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running correctly."]}),"\n",(0,i.jsxs)(n.p,{children:["To find the current ",(0,i.jsx)(n.code,{children:"nofile"})," (number of open files) hard limit, run ",(0,i.jsx)(n.code,{children:"prlimit"})," with the PID from the previous command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo prlimit -n -p <PID>\n"})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can also embed both commands as shown here:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive ",(0,i.jsx)(n.code,{children:"prlimit: option requires an argument -- 'p'"}),", then ",(0,i.jsx)(n.code,{children:'pgrep "casper-node$"'})," is not returning anything because the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is no longer running."]}),"\n",(0,i.jsx)(n.h2,{id:"updating-manually",children:"Setting the Limit Manually"}),"\n",(0,i.jsxs)(n.p,{children:["Run the command below to set the ",(0,i.jsx)(n.code,{children:"nofile"})," limit for an active process without restarting the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," and ",(0,i.jsx)(n.code,{children:"casper-node"})," processes. Note that this setting is active only while the ",(0,i.jsx)(n.code,{children:"casper-node"})," process runs. To make this setting permanent, ",(0,i.jsxs)(n.a,{href:"#updating-limits-conf",children:["update the ",(0,i.jsx)(n.code,{children:"limits.conf"})]})," file instead."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Next, check that the ",(0,i.jsx)(n.code,{children:"prlimit"})," has changed:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"updating-limits-conf",children:["Updating the ",(0,i.jsx)(n.code,{children:"limits.conf"})," File"]}),"\n",(0,i.jsxs)(n.p,{children:["It is possible to persist the ",(0,i.jsx)(n.code,{children:"nofile"})," limit across server reboots, ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," restarts, and protocol upgrades, by adding the ",(0,i.jsx)(n.code,{children:"nofile"})," setting for the ",(0,i.jsx)(n.code,{children:"casper"})," user in ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Add the following row to the bottom of the ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper hard nofile 64000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.jsx)(n.code,{children:"nofile"})," setting."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/aefd42fa.55d4578e.js b/assets/js/aefd42fa.55d4578e.js new file mode 100644 index 000000000..c9ef8003c --- /dev/null +++ b/assets/js/aefd42fa.55d4578e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[21418],{90171:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var i=s(74848),t=s(28453);const r={title:"Open Files Limit"},o="Setting the Open Files Limit",l={id:"operators/setup/open-files",title:"Open Files Limit",description:"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.",source:"@site/versioned_docs/version-1.5.X/operators/setup/open-files.md",sourceDirName:"operators/setup",slug:"/operators/setup/open-files",permalink:"/1.5.X/operators/setup/open-files",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Open Files Limit"},sidebar:"operators",previous:{title:"Fast Sync",permalink:"/1.5.X/operators/setup/fast-sync"},next:{title:"Upgrades",permalink:"/1.5.X/operators/setup/upgrade"}},c={},a=[{value:"Setting the Limit Manually",id:"updating-manually",level:2},{value:"Updating the <code>limits.conf</code> File",id:"updating-limits-conf",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",summary:"summary",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"setting-the-open-files-limit",children:"Setting the Open Files Limit"})}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node"})," launches, it tries to set the maximum open files limit (",(0,i.jsx)(n.code,{children:"nofile"}),") for the process to ",(0,i.jsx)(n.code,{children:"64000"}),". With some systems, this limit will be larger than the default hard limit of ",(0,i.jsx)(n.code,{children:"4096"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default ",(0,i.jsx)(n.code,{children:"nofile"})," limit needs to be increased."]}),"\n",(0,i.jsxs)(n.p,{children:["With the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running, you can see what the system allocated by finding the process ID (PID) for the ",(0,i.jsx)(n.code,{children:"casper-node"})," with the following command."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'pgrep "casper-node$"\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ pgrep "casper-node$"\n275928\n'})}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsxs)(n.p,{children:["This PID will change, so you need to run the above command to get the current version with your system. Also, it will not be ",(0,i.jsx)(n.code,{children:"275928"})," each time."]})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you do not get a value in return, you do not have the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," running correctly."]}),"\n",(0,i.jsxs)(n.p,{children:["To find the current ",(0,i.jsx)(n.code,{children:"nofile"})," (number of open files) hard limit, run ",(0,i.jsx)(n.code,{children:"prlimit"})," with the PID from the previous command:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo prlimit -n -p <PID>\n"})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"$ sudo prlimit -n -p 275928\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n"})}),"\n"]}),"\n",(0,i.jsx)(n.p,{children:"You can also embed both commands as shown here:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 1024 4096 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you receive ",(0,i.jsx)(n.code,{children:"prlimit: option requires an argument -- 'p'"}),", then ",(0,i.jsx)(n.code,{children:'pgrep "casper-node$"'})," is not returning anything because the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," is no longer running."]}),"\n",(0,i.jsx)(n.h2,{id:"updating-manually",children:"Setting the Limit Manually"}),"\n",(0,i.jsxs)(n.p,{children:["Run the command below to set the ",(0,i.jsx)(n.code,{children:"nofile"})," limit for an active process without restarting the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," and ",(0,i.jsx)(n.code,{children:"casper-node"})," processes. Note that this setting is active only while the ",(0,i.jsx)(n.code,{children:"casper-node"})," process runs. To make this setting permanent, ",(0,i.jsxs)(n.a,{href:"#updating-limits-conf",children:["update the ",(0,i.jsx)(n.code,{children:"limits.conf"})]})," file instead."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit --nofile=64000 --pid=$(pgrep "casper-node$")`\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Next, check that the ",(0,i.jsx)(n.code,{children:"prlimit"})," has changed:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'sudo prlimit -n -p $(pgrep "casper-node$")\n'})}),"\n",(0,i.jsxs)(n.details,{children:["\n",(0,i.jsx)(n.summary,{children:"Sample output"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:'$ sudo prlimit -n -p $(pgrep "casper-node$")\nRESOURCE DESCRIPTION SOFT HARD UNITS\nNOFILE max number of open files 64000 64000 files\n'})}),"\n"]}),"\n",(0,i.jsxs)(n.h2,{id:"updating-limits-conf",children:["Updating the ",(0,i.jsx)(n.code,{children:"limits.conf"})," File"]}),"\n",(0,i.jsxs)(n.p,{children:["It is possible to persist the ",(0,i.jsx)(n.code,{children:"nofile"})," limit across server reboots, ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," restarts, and protocol upgrades, by adding the ",(0,i.jsx)(n.code,{children:"nofile"})," setting for the ",(0,i.jsx)(n.code,{children:"casper"})," user in ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Add the following row to the bottom of the ",(0,i.jsx)(n.code,{children:"/etc/security/limits.conf"})," file:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"casper hard nofile 64000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct ",(0,i.jsx)(n.code,{children:"nofile"})," setting."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>l});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/af050a36.9b90e62b.js b/assets/js/af050a36.9b90e62b.js deleted file mode 100644 index fc1acb40d..000000000 --- a/assets/js/af050a36.9b90e62b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9293],{87614:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>o});var t=s(74848),i=s(28453);const a={title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},l="CEP-78 JavaScript Client Tutorial",r={id:"resources/tokens/cep78/js-tutorial",title:"CEP-78 JavaScript Client",description:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/js-tutorial.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/js-tutorial",permalink:"/resources/tokens/cep78/js-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},sidebar:"resources",previous:{title:"Ownership Lookup",permalink:"/resources/tokens/cep78/reverse-lookup"},next:{title:"Open-Source Software",permalink:"/resources/build-on-casper/casper-open-source-software"}},c={},o=[{value:"Client Installation",id:"client-installation",level:2},{value:"Installing a CEP-78 Contract using the JavaScript Client",id:"installing-a-cep-78-contract-using-the-javascript-client",level:2},{value:"Minting a Token",id:"minting-a-token",level:2},{value:"Register Recipient",id:"register-recipient",level:2},{value:"Transferring a Token",id:"transferring-a-token",level:2},{value:"Burning a Token",id:"burning-a-token",level:2},{value:"Example Usages",id:"example-usages",level:2},{value:"Running an Install Example",id:"running-an-install-example",level:3},{value:"Running a Usage Example",id:"running-a-usage-example",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"cep-78-javascript-client-tutorial",children:"CEP-78 JavaScript Client Tutorial"})}),"\n",(0,t.jsx)(n.p,{children:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on the CEP-78 Enhanced NFT Standard can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The client is available in ",(0,t.jsx)(n.em,{children:"npm"})," as ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-cep78-js-client",children:"casper-cep78-js-client"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"client-installation",children:"Client Installation"}),"\n",(0,t.jsx)(n.p,{children:"The client can be installed in a project you have built using TypeScript / Javascript."}),"\n",(0,t.jsx)(n.p,{children:"To install run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm install casper-cep78-js-client\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-cep-78-contract-using-the-javascript-client",children:"Installing a CEP-78 Contract using the JavaScript Client"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"install"})," method crafts a ",(0,t.jsx)(n.a,{href:"/deploy-and-deploy-lifecycle",children:"Deploy"})," using ",(0,t.jsx)(n.code,{children:"InstallArgs"}),".\nAs with every deploy created by the SDK, you can send it using the ",(0,t.jsx)(n.code,{children:".send(rpcUrl)"})," method providing the RPC URL that you want to use. It will return deployHash."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);\n\n const installDeploy = await cc.install(\n {\n collectionName: "my-collection",\n collectionSymbol: "MY-NFTS",\n totalTokenSupply: "1000",\n ownershipMode: NFTOwnershipMode.Transferable,\n nftKind: NFTKind.Physical,\n jsonSchema: {\n properties: {\n color: { name: "color", description: "", required: true },\n size: { name: "size", description: "", required: true },\n material: { name: "material", description: "", required: true },\n condition: { name: "condition", description: "", required: false },\n },\n },\n nftMetadataKind: NFTMetadataKind.CustomValidated,\n identifierMode: NFTIdentifierMode.Ordinal,\n metadataMutability: MetadataMutability.Immutable,\n mintingMode: MintingMode.Installer,\n ownerReverseLookupMode: OwnerReverseLookupMode.Complete\n },\n "250000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"InstallArgs"})," are specified as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionName"})," - The name of the NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionSymbol"})," - The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"totalTokenSupply"})," - The total number of NFTs that a specific contract instance will mint passed in as a ",(0,t.jsx)(n.code,{children:"U64"})," value. ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownershipMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnershipMode"})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftKind"})," - The ",(0,t.jsx)(n.code,{children:"NFTKind"})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"jsonSchema"})," - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". More information on ",(0,t.jsx)(n.code,{children:"NFTMetadataKind"})," can be found ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities#nftmetadatakind",children:"here"}),". This parameter may be left empty if metadata kind is set to ",(0,t.jsx)(n.code,{children:"Raw(3)"}),". If the metadata kind is set to ",(0,t.jsx)(n.code,{children:"CustomValidated(4)"}),", it will require a specifically formatted custom schema. This parameter ",(0,t.jsx)(n.strong,{children:"cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftMetadataKind"})," - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"identifierMode"})," - The ",(0,t.jsx)(n.code,{children:"NFTIdentifierMode"})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"metadataMutability"})," - The ",(0,t.jsx)(n.code,{children:"MetadataMutability"})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"mintingmode"})," - The ",(0,t.jsx)(n.code,{children:"MintingMode"})," modality dictates the access to the ",(0,t.jsx)(n.code,{children:"mint()"})," entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"holdermode"})," - The ",(0,t.jsx)(n.code,{children:"NFTHolderMode"})," modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either ",(0,t.jsx)(n.code,{children:"Accounts"})," or ",(0,t.jsx)(n.code,{children:"Contracts"})," to hold NFTs. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"burnMode"})," - The ",(0,t.jsx)(n.code,{children:"BurnMode"})," modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownerReverseLookupMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," dictates whether the contract will index ownership of tokens as outlined ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup#the-cep-78-page-system",children:"here"})," to allow lookup of owned tokens by account. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Further information on CEP-78 modality options can be found ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"minting-a-token",children:"Minting a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The CEP-78 JS Client includes code to construct a deploy that will ",(0,t.jsx)(n.code,{children:"Mint"})," a token, as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const mintDeploy = cc.mint(\n {\n owner: FAUCET_KEYS.publicKey,\n meta: {\n color: "Blue",\n size: "Medium",\n material: "Aluminum",\n condition: "Used",\n },\n },\n { useSessionCode: true },\n "2000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The arguments adhere to those provided in the original installation, with the ",(0,t.jsx)(n.code,{children:".send()"})," pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL."]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L86-L88",children:(0,t.jsx)(n.code,{children:"useSessionCode"})})," variable decides if the user will call ",(0,t.jsx)(n.code,{children:"mint"})," using session code, or not. It will be set to ",(0,t.jsx)(n.code,{children:"true"})," if the ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"Complete"}),". ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L116-L130",children:"It then registers the recipient with the contract"})," and mints the token."]}),"\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"NoLookup"}),", ",(0,t.jsx)(n.code,{children:"useSessionCode"})," will be set to ",(0,t.jsx)(n.code,{children:"false"})," and it will simply mint the token as it does not need to register the recipient."]}),"\n",(0,t.jsx)(n.h2,{id:"register-recipient",children:"Register Recipient"}),"\n",(0,t.jsxs)(n.p,{children:["As we used ",(0,t.jsx)(n.code,{children:"ownerReverseLookupMode: OwnerReverseLookupMode.Complete"})," in this contract installation, we must register the recipient. To do this, we construct a ",(0,t.jsx)(n.code,{children:"register"})," deploy:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const registerDeploy = cc.register(\n {\n tokenOwner: USER1_KEYS.publicKey,\n },\n "1000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");\n \n'})}),"\n",(0,t.jsx)(n.h2,{id:"transferring-a-token",children:"Transferring a Token"}),"\n",(0,t.jsx)(n.p,{children:"After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const transferDeploy = cc.transfer(\n {\n tokenId: "0",\n source: FAUCET_KEYS.publicKey,\n target: USER1_KEYS.publicKey,\n },\n { useSessionCode: true },\n "13000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"Transferring accepts the following arguments:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"tokenId"})," - The sequential ID assigned to a token in mint order."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"source"})," - The account sending the token in question."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"target"})," - The account receiving the transferred token."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["As above, the ",(0,t.jsx)(n.code,{children:"useSessionCode"})," variable determines if the user will call ",(0,t.jsx)(n.code,{children:"transfer"})," using session code based on the setting of ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"burning-a-token",children:"Burning a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the ",(0,t.jsx)(n.code,{children:"tokenId"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const burnDeploy = await contractClient.burn(\n { tokenId: "0" },\n "13000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.h2,{id:"example-usages",children:"Example Usages"}),"\n",(0,t.jsx)(n.h3,{id:"running-an-install-example",children:"Running an Install Example"}),"\n",(0,t.jsx)(n.p,{children:"This repository includes an example script for installing a CEP-78 contract instance."}),"\n",(0,t.jsxs)(n.p,{children:["You will need to define the following variables in the ",(0,t.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NODE_URL"})," - The address of a node. If you are testing using ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"NCTL"}),", this will be ",(0,t.jsx)(n.code,{children:"http://localhost:11101/rpc"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NETWORK_NAME"})," - The name of the Casper network you are operating on, ",(0,t.jsx)(n.code,{children:"casper-net-1"})," when testing using a local network with NCTL."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MASTER_KEY_PAIR_PATH"})," - The path to the key pair of the minting account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"USER1_KEY_PAIR_PATH"})," - The path to an additional account's key pair for use in testing transfer features."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You may also need to install associated dependencies using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm i\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:install\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The example will then return the installation's ",(0,t.jsx)(n.code,{children:"deployHash"}),", and inform you when the installation is successful."]}),"\n",(0,t.jsx)(n.p,{children:"The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash."}),"\n",(0,t.jsx)(n.h3,{id:"running-a-usage-example",children:"Running a Usage Example"}),"\n",(0,t.jsx)(n.p,{children:"A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation."}),"\n",(0,t.jsx)(n.p,{children:"The usage example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:usage\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Mint"})," - The example will attempt to mint an NFT using the installation account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Transfer"})," - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Burn"})," - The example will burn the minted NFT."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The associated code for these deploys may be found in the ",(0,t.jsx)(n.code,{children:"client-js/examples"})," directory."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const i={},a=t.createContext(i);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/af050a36.f22df805.js b/assets/js/af050a36.f22df805.js new file mode 100644 index 000000000..c1eb4ecb7 --- /dev/null +++ b/assets/js/af050a36.f22df805.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79293],{87614:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>o});var t=s(74848),i=s(28453);const a={title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},l="CEP-78 JavaScript Client Tutorial",r={id:"resources/tokens/cep78/js-tutorial",title:"CEP-78 JavaScript Client",description:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/js-tutorial.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/js-tutorial",permalink:"/1.5.X/resources/tokens/cep78/js-tutorial",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},sidebar:"resources",previous:{title:"Ownership Lookup",permalink:"/1.5.X/resources/tokens/cep78/reverse-lookup"},next:{title:"Open-Source Software",permalink:"/1.5.X/resources/build-on-casper/casper-open-source-software"}},c={},o=[{value:"Client Installation",id:"client-installation",level:2},{value:"Installing a CEP-78 Contract using the JavaScript Client",id:"installing-a-cep-78-contract-using-the-javascript-client",level:2},{value:"Minting a Token",id:"minting-a-token",level:2},{value:"Register Recipient",id:"register-recipient",level:2},{value:"Transferring a Token",id:"transferring-a-token",level:2},{value:"Burning a Token",id:"burning-a-token",level:2},{value:"Example Usages",id:"example-usages",level:2},{value:"Running an Install Example",id:"running-an-install-example",level:3},{value:"Running a Usage Example",id:"running-a-usage-example",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"cep-78-javascript-client-tutorial",children:"CEP-78 JavaScript Client Tutorial"})}),"\n",(0,t.jsx)(n.p,{children:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on the CEP-78 Enhanced NFT Standard can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The client is available in ",(0,t.jsx)(n.em,{children:"npm"})," as ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-cep78-js-client",children:"casper-cep78-js-client"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"client-installation",children:"Client Installation"}),"\n",(0,t.jsx)(n.p,{children:"The client can be installed in a project you have built using TypeScript / Javascript."}),"\n",(0,t.jsx)(n.p,{children:"To install run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm install casper-cep78-js-client\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-cep-78-contract-using-the-javascript-client",children:"Installing a CEP-78 Contract using the JavaScript Client"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"install"})," method crafts a ",(0,t.jsx)(n.a,{href:"/1.5.X/deploy-and-deploy-lifecycle",children:"Deploy"})," using ",(0,t.jsx)(n.code,{children:"InstallArgs"}),".\nAs with every deploy created by the SDK, you can send it using the ",(0,t.jsx)(n.code,{children:".send(rpcUrl)"})," method providing the RPC URL that you want to use. It will return deployHash."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);\n\n const installDeploy = await cc.install(\n {\n collectionName: "my-collection",\n collectionSymbol: "MY-NFTS",\n totalTokenSupply: "1000",\n ownershipMode: NFTOwnershipMode.Transferable,\n nftKind: NFTKind.Physical,\n jsonSchema: {\n properties: {\n color: { name: "color", description: "", required: true },\n size: { name: "size", description: "", required: true },\n material: { name: "material", description: "", required: true },\n condition: { name: "condition", description: "", required: false },\n },\n },\n nftMetadataKind: NFTMetadataKind.CustomValidated,\n identifierMode: NFTIdentifierMode.Ordinal,\n metadataMutability: MetadataMutability.Immutable,\n mintingMode: MintingMode.Installer,\n ownerReverseLookupMode: OwnerReverseLookupMode.Complete\n },\n "250000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"InstallArgs"})," are specified as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionName"})," - The name of the NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionSymbol"})," - The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"totalTokenSupply"})," - The total number of NFTs that a specific contract instance will mint passed in as a ",(0,t.jsx)(n.code,{children:"U64"})," value. ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownershipMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnershipMode"})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftKind"})," - The ",(0,t.jsx)(n.code,{children:"NFTKind"})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"jsonSchema"})," - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". More information on ",(0,t.jsx)(n.code,{children:"NFTMetadataKind"})," can be found ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/modalities#nftmetadatakind",children:"here"}),". This parameter may be left empty if metadata kind is set to ",(0,t.jsx)(n.code,{children:"Raw(3)"}),". If the metadata kind is set to ",(0,t.jsx)(n.code,{children:"CustomValidated(4)"}),", it will require a specifically formatted custom schema. This parameter ",(0,t.jsx)(n.strong,{children:"cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftMetadataKind"})," - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"identifierMode"})," - The ",(0,t.jsx)(n.code,{children:"NFTIdentifierMode"})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"metadataMutability"})," - The ",(0,t.jsx)(n.code,{children:"MetadataMutability"})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"mintingmode"})," - The ",(0,t.jsx)(n.code,{children:"MintingMode"})," modality dictates the access to the ",(0,t.jsx)(n.code,{children:"mint()"})," entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"holdermode"})," - The ",(0,t.jsx)(n.code,{children:"NFTHolderMode"})," modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either ",(0,t.jsx)(n.code,{children:"Accounts"})," or ",(0,t.jsx)(n.code,{children:"Contracts"})," to hold NFTs. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"burnMode"})," - The ",(0,t.jsx)(n.code,{children:"BurnMode"})," modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownerReverseLookupMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," dictates whether the contract will index ownership of tokens as outlined ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/reverse-lookup#the-cep-78-page-system",children:"here"})," to allow lookup of owned tokens by account. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Further information on CEP-78 modality options can be found ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"minting-a-token",children:"Minting a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The CEP-78 JS Client includes code to construct a deploy that will ",(0,t.jsx)(n.code,{children:"Mint"})," a token, as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const mintDeploy = cc.mint(\n {\n owner: FAUCET_KEYS.publicKey,\n meta: {\n color: "Blue",\n size: "Medium",\n material: "Aluminum",\n condition: "Used",\n },\n },\n { useSessionCode: true },\n "2000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The arguments adhere to those provided in the original installation, with the ",(0,t.jsx)(n.code,{children:".send()"})," pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL."]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L86-L88",children:(0,t.jsx)(n.code,{children:"useSessionCode"})})," variable decides if the user will call ",(0,t.jsx)(n.code,{children:"mint"})," using session code, or not. It will be set to ",(0,t.jsx)(n.code,{children:"true"})," if the ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"Complete"}),". ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L116-L130",children:"It then registers the recipient with the contract"})," and mints the token."]}),"\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"NoLookup"}),", ",(0,t.jsx)(n.code,{children:"useSessionCode"})," will be set to ",(0,t.jsx)(n.code,{children:"false"})," and it will simply mint the token as it does not need to register the recipient."]}),"\n",(0,t.jsx)(n.h2,{id:"register-recipient",children:"Register Recipient"}),"\n",(0,t.jsxs)(n.p,{children:["As we used ",(0,t.jsx)(n.code,{children:"ownerReverseLookupMode: OwnerReverseLookupMode.Complete"})," in this contract installation, we must register the recipient. To do this, we construct a ",(0,t.jsx)(n.code,{children:"register"})," deploy:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const registerDeploy = cc.register(\n {\n tokenOwner: USER1_KEYS.publicKey,\n },\n "1000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");\n \n'})}),"\n",(0,t.jsx)(n.h2,{id:"transferring-a-token",children:"Transferring a Token"}),"\n",(0,t.jsx)(n.p,{children:"After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const transferDeploy = cc.transfer(\n {\n tokenId: "0",\n source: FAUCET_KEYS.publicKey,\n target: USER1_KEYS.publicKey,\n },\n { useSessionCode: true },\n "13000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"Transferring accepts the following arguments:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"tokenId"})," - The sequential ID assigned to a token in mint order."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"source"})," - The account sending the token in question."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"target"})," - The account receiving the transferred token."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["As above, the ",(0,t.jsx)(n.code,{children:"useSessionCode"})," variable determines if the user will call ",(0,t.jsx)(n.code,{children:"transfer"})," using session code based on the setting of ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"burning-a-token",children:"Burning a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the ",(0,t.jsx)(n.code,{children:"tokenId"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const burnDeploy = await contractClient.burn(\n { tokenId: "0" },\n "13000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.h2,{id:"example-usages",children:"Example Usages"}),"\n",(0,t.jsx)(n.h3,{id:"running-an-install-example",children:"Running an Install Example"}),"\n",(0,t.jsx)(n.p,{children:"This repository includes an example script for installing a CEP-78 contract instance."}),"\n",(0,t.jsxs)(n.p,{children:["You will need to define the following variables in the ",(0,t.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NODE_URL"})," - The address of a node. If you are testing using ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"NCTL"}),", this will be ",(0,t.jsx)(n.code,{children:"http://localhost:11101/rpc"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NETWORK_NAME"})," - The name of the Casper network you are operating on, ",(0,t.jsx)(n.code,{children:"casper-net-1"})," when testing using a local network with NCTL."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MASTER_KEY_PAIR_PATH"})," - The path to the key pair of the minting account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"USER1_KEY_PAIR_PATH"})," - The path to an additional account's key pair for use in testing transfer features."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You may also need to install associated dependencies using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm i\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:install\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The example will then return the installation's ",(0,t.jsx)(n.code,{children:"deployHash"}),", and inform you when the installation is successful."]}),"\n",(0,t.jsx)(n.p,{children:"The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash."}),"\n",(0,t.jsx)(n.h3,{id:"running-a-usage-example",children:"Running a Usage Example"}),"\n",(0,t.jsx)(n.p,{children:"A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation."}),"\n",(0,t.jsx)(n.p,{children:"The usage example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:usage\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Mint"})," - The example will attempt to mint an NFT using the installation account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Transfer"})," - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Burn"})," - The example will burn the minted NFT."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The associated code for these deploys may be found in the ",(0,t.jsx)(n.code,{children:"client-js/examples"})," directory."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const i={},a=t.createContext(i);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/af1112c6.45aa0929.js b/assets/js/af1112c6.45aa0929.js new file mode 100644 index 000000000..520e5705d --- /dev/null +++ b/assets/js/af1112c6.45aa0929.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25210],{55679:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var t=s(74848),o=s(28453);const i={title:"Local Network Setup"},r="Setting up a Local Network with NCTL",l={id:"developers/dapps/setup-nctl",title:"Local Network Setup",description:"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/setup-nctl.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/setup-nctl",permalink:"/1.5.X/developers/dapps/setup-nctl",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Local Network Setup"},sidebar:"developers",previous:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/1.5.X/developers/dapps/speculative-exec"},next:{title:"Local Network Testing",permalink:"/1.5.X/developers/dapps/nctl-test"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Installing a Virtual Environment",id:"installing-a-virtual-environment",level:2},{value:"Setting up the Network",id:"setting-up-the-network",level:2},{value:"Stopping the Network",id:"stopping-the-network",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-up-a-local-network-with-nctl",children:"Setting up a Local Network with NCTL"})}),"\n",(0,t.jsxs)(n.p,{children:["NCTL stands for network/node control. ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/utils/nctl",children:"NCTL"})," is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have completed the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started section"}),", which shows you how to install your development environment, including tools like ",(0,t.jsx)(n.em,{children:"CMake"})," (version 3.1.4+), ",(0,t.jsx)(n.em,{children:"Cargo"}),", and ",(0,t.jsx)(n.em,{children:"Rust"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Make sure you have ",(0,t.jsx)(n.a,{href:"https://www.python.org/downloads/",children:"Python 3 installed"})," if your operating system does not include Python."]}),"\n",(0,t.jsxs)(n.li,{children:["To run NCTL, you will also need ",(0,t.jsx)(n.a,{href:"https://www.gnu.org/savannah-checkouts/gnu/bash/bash.html",children:"the bash shell"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,t.jsx)(n.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,t.jsx)(n.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rE_saHopXXU&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=2",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-virtual-environment",children:"Installing a Virtual Environment"}),"\n",(0,t.jsx)(n.p,{children:"We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing."}),"\n",(0,t.jsx)(n.p,{children:"First, you will need to install a set of tools required for running NCTL."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 1."})," The first tool you will need is ",(0,t.jsx)(n.strong,{children:"pip"}),", a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or ",(0,t.jsx)(n.a,{href:"https://pip.pypa.io/en/stable/installing/",children:"the full installation instructions"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\npython3 get-pip.py\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 2."})," Install ",(0,t.jsx)(n.strong,{children:"pkg-config"}),", a program used to compile and link against one or more libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install pkg-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 3."})," Install either ",(0,t.jsx)(n.strong,{children:"libssl-dev"})," (Linux) or ",(0,t.jsx)(n.strong,{children:"openssl"})," (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install openssl\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 4."})," You will also need the ",(0,t.jsx)(n.strong,{children:"gcc"})," and ",(0,t.jsx)(n.strong,{children:"g++"})," compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing)."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\ngcc --version\ng++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\ngcc --version\ng++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Important Note:"})}),"\n",(0,t.jsx)(n.p,{children:"The following commands need to be executed within the Bash shell. While MacOS and some Linux distributions use Zsh by default, they also include Bash. To ensure proper execution of the subsequent commands, switching to Bash is recommended. If the command does not work, please refer to the Bash documentation on how to install it on your system."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 5."})," Switching to Bash Shell:"]}),"\n",(0,t.jsx)(n.p,{children:"Type the following command in your terminal:"}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bash\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will launch a new Bash shell session. You can then proceed with the tutorial."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 6."})," Create and activate a new virtual environment. ",(0,t.jsx)(n.strong,{children:"Commands applicable to the virtual environment will be prefixed with (env)"}),". Run the following commands to set it up."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"python3 -m venv env\nsource env/bin/activate\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once you have activated the virtual environment, your terminal prompt will change to indicate you're working within it. It will usually look something like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ // This line is for visual representation only, not to be copied\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 7."})," Inside the virtual environment, upgrade ",(0,t.jsx)(n.strong,{children:"pip"})," to the latest version."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install --upgrade pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 8."})," Install ",(0,t.jsx)(n.strong,{children:"jq"}),", a command-line JSON processor."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 9."})," Install ",(0,t.jsx)(n.strong,{children:"supervisor"}),", a cross-platform process manager."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install supervisor\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 10."})," Install ",(0,t.jsx)(n.strong,{children:"toml"}),", a configuration file parser."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-the-network",children:"Setting up the Network"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to set up and run your local network of Casper nodes."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 11."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node-launcher"})," software in your working directory, which we will call ",(0,t.jsx)(n.em,{children:"WORKING_DIRECTORY"}),". ",(0,t.jsx)(n.strong,{children:"Very Important!!! Choose a short path for your working directory"}),"; otherwise, the NCTL tool will report that the path is too long."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd <WORKING_DIRECTORY>\ngit clone https://github.com/casper-network/casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,t.jsx)(n.code,{children:"deploy_delay"})," in your ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390",children:"local config.toml"})," before running ",(0,t.jsx)(n.code,{children:"nctl-assets-setup"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 12."})," Next, clone the ",(0,t.jsx)(n.em,{children:"casper-node"})," software, also in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 13."})," Finally, clone the ",(0,t.jsx)(n.em,{children:"casper-client-rs"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/casper-client-rs\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 14."})," Activate the NCTL environment with the following command."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source casper-node/utils/nctl/activate\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 15."})," Compile the NCTL binary scripts. The following command compiles both the ",(0,t.jsx)(n.em,{children:"casper-node"})," and the ",(0,t.jsx)(n.em,{children:"casper-client"})," in release mode."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-compile\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The compilation takes some time, so it might be a perfect moment to get some coffee."})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 16."})," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once a network is up and running, you can control each node within the network and add new nodes to the network."}),"\n",(0,t.jsxs)(n.p,{children:["Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,t.jsx)(n.em,{children:"nctl-"})," and allow you to perform various tasks."]}),"\n",(0,t.jsxs)(n.p,{children:["You should see the new directory ",(0,t.jsx)(n.em,{children:"utils/nctl/assets"}),", with the following structure."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(17021).A+"",width:"391",height:"706"})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command line output you would expect."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(43397).A+"",width:"795",height:"258"})}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-network",children:"Stopping the Network"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 17."})," Although not necessary, you can stop and clean the NCTL setup with the following commands."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-stop\nnctl-clean\n"})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md",children:"various NCTL commands"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md",children:"NCTL usage guide"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},17021:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/assets_setup-193e704630a056cb0dbb8e86dfac0366.png"},43397:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/nctl_output-8acd66f819f302adcb1d34cc0ff03fe0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/af1112c6.4e044cf1.js b/assets/js/af1112c6.4e044cf1.js deleted file mode 100644 index 36dfc59da..000000000 --- a/assets/js/af1112c6.4e044cf1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5210],{55679:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>l,toc:()=>c});var t=s(74848),o=s(28453);const i={title:"Local Network Setup"},r="Setting up a Local Network with NCTL",l={id:"developers/dapps/setup-nctl",title:"Local Network Setup",description:"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/setup-nctl.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/setup-nctl",permalink:"/developers/dapps/setup-nctl",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Local Network Setup"},sidebar:"developers",previous:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/developers/dapps/speculative-exec"},next:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2},{value:"Installing a Virtual Environment",id:"installing-a-virtual-environment",level:2},{value:"Setting up the Network",id:"setting-up-the-network",level:2},{value:"Stopping the Network",id:"stopping-the-network",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-up-a-local-network-with-nctl",children:"Setting up a Local Network with NCTL"})}),"\n",(0,t.jsxs)(n.p,{children:["NCTL stands for network/node control. ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/utils/nctl",children:"NCTL"})," is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have completed the ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started section"}),", which shows you how to install your development environment, including tools like ",(0,t.jsx)(n.em,{children:"CMake"})," (version 3.1.4+), ",(0,t.jsx)(n.em,{children:"Cargo"}),", and ",(0,t.jsx)(n.em,{children:"Rust"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Make sure you have ",(0,t.jsx)(n.a,{href:"https://www.python.org/downloads/",children:"Python 3 installed"})," if your operating system does not include Python."]}),"\n",(0,t.jsxs)(n.li,{children:["To run NCTL, you will also need ",(0,t.jsx)(n.a,{href:"https://www.gnu.org/savannah-checkouts/gnu/bash/bash.html",children:"the bash shell"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,t.jsx)(n.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,t.jsx)(n.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rE_saHopXXU&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=2",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-virtual-environment",children:"Installing a Virtual Environment"}),"\n",(0,t.jsx)(n.p,{children:"We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing."}),"\n",(0,t.jsx)(n.p,{children:"First, you will need to install a set of tools required for running NCTL."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 1."})," The first tool you will need is ",(0,t.jsx)(n.strong,{children:"pip"}),", a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or ",(0,t.jsx)(n.a,{href:"https://pip.pypa.io/en/stable/installing/",children:"the full installation instructions"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\npython3 get-pip.py\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install python3-pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 2."})," Install ",(0,t.jsx)(n.strong,{children:"pkg-config"}),", a program used to compile and link against one or more libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install pkg-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 3."})," Install either ",(0,t.jsx)(n.strong,{children:"libssl-dev"})," (Linux) or ",(0,t.jsx)(n.strong,{children:"openssl"})," (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install openssl\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 4."})," You will also need the ",(0,t.jsx)(n.strong,{children:"gcc"})," and ",(0,t.jsx)(n.strong,{children:"g++"})," compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing)."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\ngcc --version\ng++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\ngcc --version\ng++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Important Note:"})}),"\n",(0,t.jsx)(n.p,{children:"The following commands need to be executed within the Bash shell. While MacOS and some Linux distributions use Zsh by default, they also include Bash. To ensure proper execution of the subsequent commands, switching to Bash is recommended. If the command does not work, please refer to the Bash documentation on how to install it on your system."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 5."})," Switching to Bash Shell:"]}),"\n",(0,t.jsx)(n.p,{children:"Type the following command in your terminal:"}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"bash\n"})}),"\n",(0,t.jsx)(n.p,{children:"This will launch a new Bash shell session. You can then proceed with the tutorial."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 6."})," Create and activate a new virtual environment. ",(0,t.jsx)(n.strong,{children:"Commands applicable to the virtual environment will be prefixed with (env)"}),". Run the following commands to set it up."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"python3 -m venv env\nsource env/bin/activate\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once you have activated the virtual environment, your terminal prompt will change to indicate you're working within it. It will usually look something like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ // This line is for visual representation only, not to be copied\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 7."})," Inside the virtual environment, upgrade ",(0,t.jsx)(n.strong,{children:"pip"})," to the latest version."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install --upgrade pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 8."})," Install ",(0,t.jsx)(n.strong,{children:"jq"}),", a command-line JSON processor."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 9."})," Install ",(0,t.jsx)(n.strong,{children:"supervisor"}),", a cross-platform process manager."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install supervisor\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 10."})," Install ",(0,t.jsx)(n.strong,{children:"toml"}),", a configuration file parser."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-the-network",children:"Setting up the Network"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to set up and run your local network of Casper nodes."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 11."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node-launcher"})," software in your working directory, which we will call ",(0,t.jsx)(n.em,{children:"WORKING_DIRECTORY"}),". ",(0,t.jsx)(n.strong,{children:"Very Important!!! Choose a short path for your working directory"}),"; otherwise, the NCTL tool will report that the path is too long."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd <WORKING_DIRECTORY>\ngit clone https://github.com/casper-network/casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,t.jsx)(n.code,{children:"deploy_delay"})," in your ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390",children:"local config.toml"})," before running ",(0,t.jsx)(n.code,{children:"nctl-assets-setup"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 12."})," Next, clone the ",(0,t.jsx)(n.em,{children:"casper-node"})," software, also in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 13."})," Finally, clone the ",(0,t.jsx)(n.em,{children:"casper-client-rs"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/casper-client-rs\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 14."})," Activate the NCTL environment with the following command."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source casper-node/utils/nctl/activate\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 15."})," Compile the NCTL binary scripts. The following command compiles both the ",(0,t.jsx)(n.em,{children:"casper-node"})," and the ",(0,t.jsx)(n.em,{children:"casper-client"})," in release mode."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-compile\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The compilation takes some time, so it might be a perfect moment to get some coffee."})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 16."})," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-assets-setup && nctl-start\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once a network is up and running, you can control each node within the network and add new nodes to the network."}),"\n",(0,t.jsxs)(n.p,{children:["Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,t.jsx)(n.em,{children:"nctl-"})," and allow you to perform various tasks."]}),"\n",(0,t.jsxs)(n.p,{children:["You should see the new directory ",(0,t.jsx)(n.em,{children:"utils/nctl/assets"}),", with the following structure."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(18335).A+"",width:"391",height:"706"})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command line output you would expect."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(30391).A+"",width:"795",height:"258"})}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-network",children:"Stopping the Network"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 17."})," Although not necessary, you can stop and clean the NCTL setup with the following commands."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"nctl-stop\nnctl-clean\n"})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md",children:"various NCTL commands"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md",children:"NCTL usage guide"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},18335:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/assets_setup-193e704630a056cb0dbb8e86dfac0366.png"},30391:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/nctl_output-8acd66f819f302adcb1d34cc0ff03fe0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const o={},i=t.createContext(o);function r(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/afa6d836.e95ff699.js b/assets/js/afa6d836.e95ff699.js new file mode 100644 index 000000000..6fd4a59f2 --- /dev/null +++ b/assets/js/afa6d836.e95ff699.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46724],{96186:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>t,metadata:()=>r,toc:()=>i});var n=s(74848),c=s(28453);const t={},a="B",r={id:"concepts/glossary/B",title:"B",description:"---",source:"@site/docs/concepts/glossary/B.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/B",permalink:"/concepts/glossary/B",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"concepts",previous:{title:"A",permalink:"/concepts/glossary/A"},next:{title:"C",permalink:"/concepts/glossary/C"}},l={},i=[{value:"Blake2b",id:"blake2b",level:2},{value:"Block",id:"block",level:2},{value:"Block creation",id:"block-creation",level:2},{value:"Block finality",id:"block-finality",level:2},{value:"Block gossiping",id:"block-gossiping",level:2},{value:"Block height",id:"block-height",level:2},{value:"Block passing",id:"block-passing",level:2},{value:"Block processing",id:"block-processing",level:2},{value:"Block proposal",id:"block-proposal",level:2},{value:"Block validation",id:"block-validation",level:2},{value:"Blockchain",id:"blockchain",level:2},{value:"Block store",id:"block-store",level:2},{value:"Bond",id:"bond",level:2},{value:"Bonding",id:"bonding",level:2},{value:"Booking block",id:"booking-block",level:2}];function h(e){const o={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"b",children:"B"})}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsxs)(o.p,{children:[(0,n.jsx)(o.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(o.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(o.hr,{}),"\n",(0,n.jsx)(o.h2,{id:"blake2b",children:"Blake2b"}),"\n",(0,n.jsxs)(o.p,{children:["A function used within the Casper platform to create cryptographic ",(0,n.jsx)(o.a,{href:"/concepts/glossary/H#hash",children:"hashes"}),". More information can be found ",(0,n.jsx)(o.a,{href:"https://www.blake2.net/",children:"here"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block",children:"Block"}),"\n",(0,n.jsx)(o.p,{children:"Used in two contexts:"}),"\n",(0,n.jsxs)(o.ol,{children:["\n",(0,n.jsx)(o.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,n.jsx)(o.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,n.jsx)(o.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,n.jsx)(o.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,n.jsx)(o.h2,{id:"block-creation",children:"Block creation"}),"\n",(0,n.jsxs)(o.p,{children:["Block creation means computing the transaction results and collecting the results into a block. We follow a process called ",(0,n.jsx)(o.em,{children:"execution after consensus"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["The ",(0,n.jsx)(o.a,{href:"/concepts/glossary/B#block-proposal",children:"block proposal"})," happens first, and the proposed ",(0,n.jsx)(o.a,{href:"/concepts/glossary/P#proto-block",children:"proto block"})," contains a set of transactions that have not been executed yet."]}),"\n",(0,n.jsxs)(o.p,{children:["Only after consensus on a ",(0,n.jsx)(o.em,{children:"proto block"})," has been reached, the transactions are executed. The resulting new global state ",(0,n.jsx)(o.a,{href:"/concepts/glossary/R#root-hash",children:"root hash"})," is put into an actual block, together with the executed transactions."]}),"\n",(0,n.jsx)(o.p,{children:"Note that only validators can create valid blocks."}),"\n",(0,n.jsx)(o.h2,{id:"block-finality",children:"Block finality"}),"\n",(0,n.jsx)(o.p,{children:'A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.'}),"\n",(0,n.jsxs)(o.p,{children:["For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see ",(0,n.jsx)(o.a,{href:"/concepts/glossary/E#eviction",children:"eviction"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"block-gossiping",children:"Block gossiping"}),"\n",(0,n.jsxs)(o.p,{children:["Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms ",(0,n.jsx)(o.em,{children:"block gossiping"})," and ",(0,n.jsx)(o.a,{href:"#block-passing",children:"block passing"})," are interchangeable."]}),"\n",(0,n.jsx)(o.h2,{id:"block-height",children:"Block height"}),"\n",(0,n.jsx)(o.p,{children:"Block height is an identifier for a given block based on the number of blocks completed prior to that block."}),"\n",(0,n.jsx)(o.h2,{id:"block-passing",children:"Block passing"}),"\n",(0,n.jsxs)(o.p,{children:["See ",(0,n.jsx)(o.a,{href:"#block-gossiping",children:"block gossiping"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-processing",children:"Block processing"}),"\n",(0,n.jsxs)(o.p,{children:["Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of ",(0,n.jsx)(o.a,{href:"#block-validation",children:"validating blocks"}),"."]}),"\n",(0,n.jsx)(o.h2,{id:"block-proposal",children:"Block proposal"}),"\n",(0,n.jsx)(o.p,{children:"Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only."}),"\n",(0,n.jsx)(o.h2,{id:"block-validation",children:"Block validation"}),"\n",(0,n.jsx)(o.p,{children:"The process of determining the validity of a block obtained from another node on the network."}),"\n",(0,n.jsx)(o.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,n.jsxs)(o.p,{children:["Blockchain is a P2P network where the collection of nodes (",(0,n.jsx)(o.a,{href:"/concepts/glossary/V#validator",children:"validators"}),") concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of ",(0,n.jsx)(o.a,{href:"/concepts/glossary/T#transaction",children:"transactions"}),". For performance reasons, transactions are bundled in ",(0,n.jsx)(o.a,{href:"#block",children:"blocks"}),". According to a particular cooperation protocol (consensus protocol), the collection of ",(0,n.jsx)(o.a,{href:"/concepts/glossary/N#node",children:"nodes"})," connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," and has a sizeable map-like collection."]}),"\n",(0,n.jsx)(o.h2,{id:"block-store",children:"Block store"}),"\n",(0,n.jsx)(o.p,{children:"The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash."}),"\n",(0,n.jsx)(o.h2,{id:"bond",children:"Bond"}),"\n",(0,n.jsxs)(o.p,{children:["The amount of money (in crypto-currency) that is allocated by a node in order to participate in ",(0,n.jsx)(o.a,{href:"/concepts/glossary/C#consensus",children:"consensus"})," (and to be a ",(0,n.jsx)(o.a,{href:"/concepts/glossary/V#validator",children:"validator"}),")."]}),"\n",(0,n.jsx)(o.h2,{id:"bonding",children:"Bonding"}),"\n",(0,n.jsxs)(o.p,{children:["Depositing money in the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"})," and try to become a ",(0,n.jsx)(o.a,{href:"/concepts/glossary/S#staker",children:"staker"}),". The bonding request is a transaction that transfers tokens to the auction contract. In the next ",(0,n.jsx)(o.a,{href:"#booking-block",children:"booking block"}),", a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block."]}),"\n",(0,n.jsx)(o.h2,{id:"booking-block",children:"Booking block"}),"\n",(0,n.jsxs)(o.p,{children:["The booking block for an era is the block that determines the era's validator set. In it, the ",(0,n.jsx)(o.a,{href:"/concepts/glossary/A#auction-contract",children:"auction contract"})," selects the highest bidders to be the future era's validators. There is a configurable delay, the ",(0,n.jsx)(o.em,{children:"auction_delay"}),", which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era ",(0,n.jsx)(o.em,{children:"N + auction_delay + 1"})," is the last block of era ",(0,n.jsx)(o.em,{children:"N"}),"."]})]})}function d(e={}){const{wrapper:o}={...(0,c.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,o,s)=>{s.d(o,{R:()=>a,x:()=>r});var n=s(96540);const c={},t=n.createContext(c);function a(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function r(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/afa6d836.ec61673a.js b/assets/js/afa6d836.ec61673a.js deleted file mode 100644 index 79ec9eb85..000000000 --- a/assets/js/afa6d836.ec61673a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6724],{96186:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>r,toc:()=>i});var s=o(74848),t=o(28453);const c={},a="B",r={id:"concepts/glossary/B",title:"B",description:"---",source:"@site/docs/concepts/glossary/B.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/B",permalink:"/next/concepts/glossary/B",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"concepts",previous:{title:"A",permalink:"/next/concepts/glossary/A"},next:{title:"C",permalink:"/next/concepts/glossary/C"}},l={},i=[{value:"Blake2b",id:"blake2b",level:2},{value:"Block",id:"block",level:2},{value:"Block creation",id:"block-creation",level:2},{value:"Block finality",id:"block-finality",level:2},{value:"Block gossiping",id:"block-gossiping",level:2},{value:"Block height",id:"block-height",level:2},{value:"Block passing",id:"block-passing",level:2},{value:"Block processing",id:"block-processing",level:2},{value:"Block proposal",id:"block-proposal",level:2},{value:"Block validation",id:"block-validation",level:2},{value:"Blockchain",id:"blockchain",level:2},{value:"Block store",id:"block-store",level:2},{value:"Bond",id:"bond",level:2},{value:"Bonding",id:"bonding",level:2},{value:"Booking block",id:"booking-block",level:2}];function h(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"b",children:"B"})}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"blake2b",children:"Blake2b"}),"\n",(0,s.jsxs)(n.p,{children:["A function used within the Casper platform to create cryptographic ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/H#hash",children:"hashes"}),". More information can be found ",(0,s.jsx)(n.a,{href:"https://www.blake2.net/",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"Used in two contexts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(n.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(n.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(n.h2,{id:"block-creation",children:"Block creation"}),"\n",(0,s.jsxs)(n.p,{children:["Block creation means computing the transaction results and collecting the results into a block. We follow a process called ",(0,s.jsx)(n.em,{children:"execution after consensus"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/B#block-proposal",children:"block proposal"})," happens first, and the proposed ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/P#proto-block",children:"proto block"})," contains a set of transactions that have not been executed yet."]}),"\n",(0,s.jsxs)(n.p,{children:["Only after consensus on a ",(0,s.jsx)(n.em,{children:"proto block"})," has been reached, the transactions are executed. The resulting new global state ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/R#root-hash",children:"root hash"})," is put into an actual block, together with the executed transactions."]}),"\n",(0,s.jsx)(n.p,{children:"Note that only validators can create valid blocks."}),"\n",(0,s.jsx)(n.h2,{id:"block-finality",children:"Block finality"}),"\n",(0,s.jsx)(n.p,{children:'A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.'}),"\n",(0,s.jsxs)(n.p,{children:["For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/E#eviction",children:"eviction"}),")."]}),"\n",(0,s.jsx)(n.h2,{id:"block-gossiping",children:"Block gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms ",(0,s.jsx)(n.em,{children:"block gossiping"})," and ",(0,s.jsx)(n.a,{href:"#block-passing",children:"block passing"})," are interchangeable."]}),"\n",(0,s.jsx)(n.h2,{id:"block-height",children:"Block height"}),"\n",(0,s.jsx)(n.p,{children:"Block height is an identifier for a given block based on the number of blocks completed prior to that block."}),"\n",(0,s.jsx)(n.h2,{id:"block-passing",children:"Block passing"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"#block-gossiping",children:"block gossiping"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"block-processing",children:"Block processing"}),"\n",(0,s.jsxs)(n.p,{children:["Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of ",(0,s.jsx)(n.a,{href:"#block-validation",children:"validating blocks"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"block-proposal",children:"Block proposal"}),"\n",(0,s.jsx)(n.p,{children:"Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only."}),"\n",(0,s.jsx)(n.h2,{id:"block-validation",children:"Block validation"}),"\n",(0,s.jsx)(n.p,{children:"The process of determining the validity of a block obtained from another node on the network."}),"\n",(0,s.jsx)(n.h2,{id:"blockchain",children:"Blockchain"}),"\n",(0,s.jsxs)(n.p,{children:["Blockchain is a P2P network where the collection of nodes (",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validators"}),") concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"transactions"}),". For performance reasons, transactions are bundled in ",(0,s.jsx)(n.a,{href:"#block",children:"blocks"}),". According to a particular cooperation protocol (consensus protocol), the collection of ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/N#node",children:"nodes"})," connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"})," and has a sizeable map-like collection."]}),"\n",(0,s.jsx)(n.h2,{id:"block-store",children:"Block store"}),"\n",(0,s.jsx)(n.p,{children:"The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash."}),"\n",(0,s.jsx)(n.h2,{id:"bond",children:"Bond"}),"\n",(0,s.jsxs)(n.p,{children:["The amount of money (in crypto-currency) that is allocated by a node in order to participate in ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#consensus",children:"consensus"})," (and to be a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validator"}),")."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding",children:"Bonding"}),"\n",(0,s.jsxs)(n.p,{children:["Depositing money in the ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/A#auction-contract",children:"auction contract"})," and try to become a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/S#staker",children:"staker"}),". The bonding request is a transaction that transfers tokens to the auction contract. In the next ",(0,s.jsx)(n.a,{href:"#booking-block",children:"booking block"}),", a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block."]}),"\n",(0,s.jsx)(n.h2,{id:"booking-block",children:"Booking block"}),"\n",(0,s.jsxs)(n.p,{children:["The booking block for an era is the block that determines the era's validator set. In it, the ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/A#auction-contract",children:"auction contract"})," selects the highest bidders to be the future era's validators. There is a configurable delay, the ",(0,s.jsx)(n.em,{children:"auction_delay"}),", which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era ",(0,s.jsx)(n.em,{children:"N + auction_delay + 1"})," is the last block of era ",(0,s.jsx)(n.em,{children:"N"}),"."]})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>a,x:()=>r});var s=o(96540);const t={},c=s.createContext(t);function a(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0b03333.557020ef.js b/assets/js/b0b03333.557020ef.js new file mode 100644 index 000000000..4f6d7be58 --- /dev/null +++ b/assets/js/b0b03333.557020ef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30123],{30931:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>h,contentTitle:()=>l,default:()=>o,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var s=i(74848),r=i(28453);const d={},l="Types",c={id:"developers/json-rpc/types_chain",title:"Types",description:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_chain",permalink:"/2.0.0/developers/json-rpc/types_chain",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/2.0.0/developers/json-rpc/json-rpc-pos"},next:{title:"CLType",permalink:"/2.0.0/developers/json-rpc/types_cl"}},h={},a=[{value:"Account",id:"account",level:2},{value:"AccountActionThresholds",id:"accountactionthresholds",level:2},{value:"AccountAssociatedKeys",id:"accountassociatedkeys",level:2},{value:"AccountAssociatedKeyWeight",id:"accountassociatedkeyweight",level:2},{value:"AccountHash",id:"accounthash",level:2},{value:"AccountIdentifier",id:"accountidentifier",level:2},{value:"ActivationPoint",id:"activationpoint",level:2},{value:"AddressableEntity",id:"addressableentity",level:2},{value:"AddressableEntityHash",id:"addressableentityhash",level:2},{value:"Approval",id:"approval",level:2},{value:"Array_of_AssociatedKey",id:"array_of_associatedkey",level:2},{value:"Array_of_BlockProof",id:"array_of_blockproof",level:2},{value:"Array_of_EntityVersionAndHash",id:"array_of_entityversionandhash",level:2},{value:"Array_of_EraReward",id:"array_of_erareward",level:2},{value:"Array_of_MessageTopic",id:"array_of_messagetopic",level:2},{value:"Array_of_NamedEntryPoint",id:"array_of_namedentrypoint",level:2},{value:"Array_of_NamedUserGroup",id:"array_of_namedusergroup",level:2},{value:"Array_of_PublicKeyAndBid",id:"array_of_publickeyandbid",level:2},{value:"Array_of_PublicKeyAndDelegator",id:"array_of_publickeyanddelegator",level:2},{value:"Array_of_ValidatorWeight",id:"array_of_validatorweight",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AuctionState",id:"auctionstate",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"BalanceHoldWithProof",id:"balanceholdwithproof",level:2},{value:"Bid",id:"bid",level:2},{value:"BidKind",id:"bidkind",level:2},{value:"Block",id:"block",level:2},{value:"BlockBodyV1",id:"blockbodyv1",level:2},{value:"BlockBodyV2",id:"blockbodyv2",level:2},{value:"BlockHash",id:"blockhash",level:2},{value:"BlockHeader",id:"blockheader",level:2},{value:"BlockHeaderV1",id:"blockheaderv1",level:2},{value:"BlockHeaderV2",id:"blockheaderv2",level:2},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"BlockProof",id:"blockproof",level:2},{value:"BlockSynchronizerStatus",id:"blocksynchronizerstatus",level:2},{value:"BlockSyncStatus",id:"blocksyncstatus",level:2},{value:"BlockTime",id:"blocktime",level:2},{value:"BlockV1",id:"blockv1",level:2},{value:"BlockV2",id:"blockv2",level:2},{value:"Bridge",id:"bridge",level:2},{value:"Bytes",id:"bytes",level:2},{value:"ByteCode",id:"bytecode",level:2},{value:"ByteCodeHash",id:"bytecodehash",level:2},{value:"ByteCodeKind",id:"bytecodekind",level:2},{value:"BytesreprError",id:"bytesreprerror",level:2},{value:"ChainspecRawBytes",id:"chainspecrawbytes",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackage",id:"contractpackage",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractPackageStatus",id:"contractpackagestatus",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractVersionKey",id:"contractversionkey",level:2},{value:"ContractWasm",id:"contractwasm",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"DeployHash",id:"deployhash",level:2},{value:"DeployHeader",id:"deployheader",level:2},{value:"DeployInfo",id:"deployinfo",level:2},{value:"DictionaryIdentifier",id:"dictionaryidentifier",level:2},{value:"Digest",id:"digest",level:2},{value:"Effects",id:"effects",level:2},{value:"EntityActionThresholds",id:"entityactionthresholds",level:2},{value:"EntityAddr",id:"entityaddr",level:2},{value:"EntityAssociatedKeys",id:"entityassociatedkeys",level:2},{value:"EntityAssociatedKeyWeight",id:"entityassociatedkeyweight",level:2},{value:"EntityIdentifier",id:"entityidentifier",level:2},{value:"EntityKind",id:"entitykind",level:2},{value:"EntityOrAccount",id:"entityoraccount",level:2},{value:"EntityVersionAndHash",id:"entityversionandhash",level:2},{value:"EntityVersionKey",id:"entityversionkey",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EntryPoint2",id:"entrypoint2",level:2},{value:"EntryPointAccess",id:"entrypointaccess",level:2},{value:"EntryPointPayment",id:"entrypointpayment",level:2},{value:"EntryPointType",id:"entrypointtype",level:2},{value:"EntryPointValue",id:"entrypointvalue",level:2},{value:"EntryPointV2",id:"entrypointv2",level:2},{value:"EraEndV1",id:"eraendv1",level:2},{value:"EraEndV2",id:"eraendv2",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraIdentifier",id:"eraidentifier",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"EraReport_for_PublicKey",id:"erareport_for_publickey",level:2},{value:"EraReward",id:"erareward",level:2},{value:"EraSummary",id:"erasummary",level:2},{value:"ExecutableDeployItem",id:"executabledeployitem",level:2},{value:"ExecutionInfo",id:"executioninfo",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"ExecutionResultV1",id:"executionresultv1",level:2},{value:"ExecutionResultV2",id:"executionresultv2",level:2},{value:"Gas",id:"gas",level:2},{value:"GlobalStateIdentifier",id:"globalstateidentifier",level:2},{value:"Group",id:"group",level:2},{value:"InitiatorAddr",id:"initiatoraddr",level:2},{value:"JsonBlockWithSignatures",id:"jsonblockwithsignatures",level:2},{value:"JsonEraValidators",id:"jsoneravalidators",level:2},{value:"JsonValidatorChanges",id:"jsonvalidatorchanges",level:2},{value:"JsonValidatorStatusChange",id:"jsonvalidatorstatuschange",level:2},{value:"JsonValidatorsWeights",id:"jsonvalidatorsweights",level:2},{value:"Key",id:"key",level:2},{value:"MessageChecksum",id:"messagechecksum",level:2},{value:"MessageTopic",id:"messagetopic",level:2},{value:"MessageTopicSummary",id:"messagetopicsummary",level:2},{value:"MinimalBlockInfo",id:"minimalblockinfo",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedEntryPoint",id:"namedentrypoint",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"NamedKeys",id:"namedkeys",level:2},{value:"NamedKeyValue",id:"namedkeyvalue",level:2},{value:"NamedUserGroup",id:"namedusergroup",level:2},{value:"NextUpgrade",id:"nextupgrade",level:2},{value:"Operation",id:"operation",level:2},{value:"OpKind",id:"opkind",level:2},{value:"Package",id:"package",level:2},{value:"Parameter",id:"parameter",level:2},{value:"PackageHash",id:"packagehash",level:2},{value:"PackageStatus",id:"packagestatus",level:2},{value:"PaymentInfo",id:"paymentinfo",level:2},{value:"PeerEntry",id:"peerentry",level:2},{value:"Peers",id:"peers",level:2},{value:"PricingMode",id:"pricingmode",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"PublicKeyAndBid",id:"publickeyandbid",level:2},{value:"PublicKeyAndDelegator",id:"publickeyanddelegator",level:2},{value:"PurseIdentifier",id:"purseidentifier",level:2},{value:"ReservationKind",id:"reservationkind",level:2},{value:"RewardedSignatures",id:"rewardedsignatures",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SingleBlockRewardedSignatures",id:"singleblockrewardedsignatures",level:2},{value:"StoredValue",id:"storedvalue",level:2},{value:"SystemEntityType",id:"systementitytype",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TopicNameHash",id:"topicnamehash",level:2},{value:"Transaction",id:"transaction",level:2},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:2},{value:"TransactionHash",id:"transactionhash",level:2},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:2},{value:"TransactionRuntime",id:"transactionruntime",level:2},{value:"TransactionScheduling",id:"transactionscheduling",level:2},{value:"TransactionTarget",id:"transactiontarget",level:2},{value:"TransactionV1",id:"transactionv1",level:2},{value:"TransactionV1Body",id:"transactionv1body",level:2},{value:"TransactionV1Hash",id:"transactionv1hash",level:2},{value:"TransactionV1Header",id:"transactionv1header",level:2},{value:"Transfer",id:"transfer",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"TransferV1",id:"transferv1",level:2},{value:"TransferV2",id:"transferv2",level:2},{value:"TransformError",id:"transformerror",level:2},{value:"TransformV1",id:"transformv1",level:2},{value:"TransformV2",id:"transformv2",level:2},{value:"TransformKindV1",id:"transformkindv1",level:2},{value:"TransformKindV2",id:"transformkindv2",level:2},{value:"TypeMismatch",id:"typemismatch",level:2},{value:"U128",id:"u128",level:2},{value:"U256",id:"u256",level:2},{value:"U512",id:"u512",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"URef",id:"uref",level:2},{value:"ValidatorBid",id:"validatorbid",level:2},{value:"ValidatorChange",id:"validatorchange",level:2},{value:"ValidatorCredit",id:"validatorcredit",level:2},{value:"ValidatorWeight",id:"validatorweight",level:2},{value:"VestingSchedule",id:"vestingschedule",level:2},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function t(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"types",children:"Types"})}),"\n",(0,s.jsx)(n.p,{children:"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness."}),"\n",(0,s.jsx)(n.h2,{id:"account",children:"Account"}),"\n",(0,s.jsx)(n.p,{children:"Structure representing a user's Account, stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accountactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountactionthresholds",children:"AccountActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accountassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeys",children:"AccountAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"collection of weighted public keys"})," (represented as account hashes) associated with an account."]}),"\n",(0,s.jsx)(n.h2,{id:"accountassociatedkeyweight",children:"AccountAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an account's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"accounthash",children:"AccountHash"}),"\n",(0,s.jsx)(n.p,{children:"The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length."}),"\n",(0,s.jsx)(n.h2,{id:"accountidentifier",children:"AccountIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an account."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"activationpoint",children:"ActivationPoint"}),"\n",(0,s.jsx)(n.p,{children:"The first era to which the associated protocol version applies."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," Genesis timestamp."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityactionthresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityassociatedkeys",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodehash",children:(0,s.jsx)(n.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entitykind",children:(0,s.jsx)(n.code,{children:"entity_kind"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"main_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_messagetopic",children:(0,s.jsx)(n.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#packagehash",children:(0,s.jsx)(n.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"addressableentityhash",children:"AddressableEntityHash"}),"\n",(0,s.jsx)(n.p,{children:"The hex-encoded address of the addressable entity."}),"\n",(0,s.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"signer"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_associatedkey",children:"Array_of_AssociatedKey"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#associatedkey",children:"AssociatedKeys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_blockproof",children:"Array_of_BlockProof"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#blockproof",children:(0,s.jsx)(n.code,{children:"BlockProofs"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_entityversionandhash",children:"Array_of_EntityVersionAndHash"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#entityversionandhash",children:"EntityVersionAndHashes"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_erareward",children:"Array_of_EraReward"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#erareward",children:"EraRewards"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_messagetopic",children:"Array_of_MessageTopic"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"MessageTopics"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedentrypoint",children:"Array_of_NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedentrypoint",children:"named entry points"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_namedusergroup",children:"Array_of_NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#namedusergroup",children:"NamedUserGroups"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyandbid",children:"Array_of_PublicKeyAndBid"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#publickeyandbid",children:"bids associated with given public keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_publickeyanddelegator",children:"Array_of_PublicKeyAndDelegator"}),"\n",(0,s.jsxs)(n.p,{children:["An array consisting of ",(0,s.jsx)(n.a,{href:"#publickeyanddelegator",children:"PublicKeyAndDelegators"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"array_of_validatorweight",children:"Array_of_ValidatorWeight"}),"\n",(0,s.jsxs)(n.p,{children:["An array of ",(0,s.jsx)(n.a,{href:"#validatorweight",children:(0,s.jsx)(n.code,{children:"ValidatorWeights"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsx)(n.p,{children:"A key granted limited permissions to an Account, for purposes such as multisig."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#weight",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"auctionstate",children:"AuctionState"}),"\n",(0,s.jsx)(n.p,{children:"Data structure summarizing auction contract data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_publickeyandbid",children:(0,s.jsx)(n.code,{children:"bids"})})," All bids contained within a vector."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," Block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsoneravalidators",children:(0,s.jsx)(n.code,{children:"era_validators"})})," Era validators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Global state hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsx)(n.p,{children:"An unbroken, inclusive range of blocks."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"high"})," The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"balanceholdwithproof",children:"BalanceHoldWithProof"}),"\n",(0,s.jsx)(n.p,{children:"Hold amount at a given block time."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The amount in the hold."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"proof"})," A string proof that the given value is present in the Merkle trie."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"time"})})," The block time at which the hold was created."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," The purse that was used for bonding."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegators"})})," The validator's delegators, indexed by their public keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator (not including delegators)."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})," Vesting schedule for a genesis validator. ",(0,s.jsx)(n.code,{children:"None"})," if non-genesis validator."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bidkind",children:"BidKind"}),"\n",(0,s.jsx)(n.p,{children:"Auction bid variants."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unified"})," A unified record indexed on validator data, with an embedded collection of all delegator bids assigned to that validator. The `Unified`` variant is for legacy retrograde support; new instances will not be created going forward."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," A bid record containing only validator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," A bid record containing only delegator data."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Bridge"})," A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Credit"})," Credited amount."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockv2",children:(0,s.jsx)(n.code,{children:"Version2"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hashes"})})," The deploy hashes of the non-transfer deploys within the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator that proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"transfer_hashes"})})," The deploy hashes of the transfers within the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockbodyv2",children:"BlockBodyV2"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#rewardedsignatures",children:(0,s.jsx)(n.code,{children:"rewarded_signatures"})})," List of identifiers for finality signatures for a particular past block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transactions"})})," Map of transactions mapping categories to a list of transaction hashes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockhash",children:"BlockHash"}),"\n",(0,s.jsxs)(n.p,{children:["A cryptographic hash identifying a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"blockheader",children:"BlockHeader"}),"\n",(0,s.jsxs)(n.p,{children:["The versioned header portion of a block. It encapsulates different variants of the ",(0,s.jsx)(n.code,{children:"BlockHeader"})," struct."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," The legacy, initial version of the header portion of a block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," The version 2 of the header portion of a block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv1",children:"BlockHeaderV1"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraendv1",children:(0,s.jsx)(n.code,{children:"era_end"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockheaderv2",children:"BlockHeaderV2"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"accumulated_seed"})})," A seed needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})," The hash of the block's body."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"current_gas_price"})," The gas price of the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The height of this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"parent_hash"})})," The parent block's hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"proposer"})})," The public key of the validator which proposed the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})," The protocol version of the network from when this block was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"random_bit"})," A random bit needed for initializing a future era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," The root hash of global state after the deploys in this block have been executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})," The timestamp from when the block was proposed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraendv2",children:(0,s.jsx)(n.code,{children:"era_end"})})," The ",(0,s.jsx)(n.code,{children:"EraEnd"})," of a block if it is a switch block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"last_switch_block_hash"})})," The most recent switch block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"Hash"})})," Identify and retrieve the Block with its hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Height"})," Identify and retrieve the Block with its height."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockproof",children:"BlockProof"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a corresponding signature of a given block hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"signature"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksynchronizerstatus",children:"BlockSynchronizerStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of the block synchronizer."}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Historical"})})," The status of syncing a historical block, if any."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blocksyncstatus",children:(0,s.jsx)(n.code,{children:"Forward"})})," The status of syncing a forward block, if any."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocksyncstatus",children:"BlockSyncStatus"}),"\n",(0,s.jsx)(n.p,{children:"The status of syncing an individual block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"acquisition_state"})," The state of acquisition of the data associated with the block as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block, if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blocktime",children:"BlockTime"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype wrapping a ",(0,s.jsx)(n.code,{children:"u64"}),", which represents the block time."]}),"\n",(0,s.jsx)(n.h2,{id:"blockv1",children:"BlockV1"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution with the resulting global state root hash prior to Casper 2.0. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv1",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv1",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockv2",children:"BlockV2"}),"\n",(0,s.jsx)(n.p,{children:"A block after execution, with the resulting global state root hash. This is the core component of the Casper linear blockchain."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockbodyv2",children:(0,s.jsx)(n.code,{children:"body"})})," The body portion of the block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})," The block hash identifying this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockheaderv2",children:(0,s.jsx)(n.code,{children:"header"})})," The header portion of the block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bridge",children:"Bridge"}),"\n",(0,s.jsxs)(n.p,{children:["A bridge record pointing to a new ",(0,s.jsx)(n.code,{children:"ValidatorBid"})," after the public key was changed."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," Era when bridge record was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"old_validator_public_key"})})," Previous validator public key associated with the bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator_public_key"})})," New validator public key associated with the bid."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytes",children:"Bytes"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded bytes."}),"\n",(0,s.jsx)(n.h2,{id:"bytecode",children:"ByteCode"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytecodekind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodehash",children:"ByteCodeHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a smart contract ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bytecodekind",children:"ByteCodeKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of byte code."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Empty"})," Empty byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"V1CasperWasm"})," Byte code to be executed with the version 1 Casper execution engine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bytesreprerror",children:"BytesreprError"}),"\n",(0,s.jsx)(n.p,{children:"Serialization and deserialization errors."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EarlyEndOfStream"})," Early end of stream while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Formatting"})," Formatting error while deserializing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"LeftOverBytes"})," Not all input bytes were consumed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"OutOfMemory"})," Out of memory error."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NotRepresentable"})," No serialized representation is available for a value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ExceededRecursionDepth"})," Exceeded a recursion depth limit."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspecrawbytes",children:"ChainspecRawBytes"}),"\n",(0,s.jsx)(n.p,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"chainspec_bytes"})})," Hex-encoded raw bytes of the current chainspec.toml file."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_genesis_accounts_bytes"})})," Hex-encoded raw bytes of the current genesis accounts.toml file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"maybe_global_state_bytes"})})," Hex-encoded raw bytes of the current global_state.toml file."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct that can be serialized as a JSON object."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackage",children:"ContractPackage"}),"\n",(0,s.jsx)(n.p,{children:"Contract definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"access_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"versions"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract package."}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the contract package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"contract_version"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"protocol_version_major"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"ContractVersion"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(n.p,{children:"A container for a contract's Wasm bytes."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameter:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"bytes"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsx)(n.p,{children:"The hash address of the contract Wasm."}),"\n",(0,s.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee").'}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A Deploy; an item containing a smart contract along with the requester's signature(s)."}),"\n",(0,s.jsx)(n.p,{children:"Required properties:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployheader",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executabledeployitem",children:(0,s.jsx)(n.code,{children:"session"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployhash",children:"DeployHash"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded Deploy hash."}),"\n",(0,s.jsx)(n.h2,{id:"deployheader",children:"DeployHeader"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"account"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"chain_name"})," A user defined string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"dependencies"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas_price"})," Defined as an integer in UInt64 format."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to the given Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," The relevant Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account identifier of the creator of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"gas"})})," Gas cost of executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse used for payment of the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})," Transfers performed by the Deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"dictionaryidentifier",children:"DictionaryIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Options for dictionary item lookups."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AccountNamedKey"})," Lookup a dictionary item via an Account's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The Account key as a formatted string whose named keys contain dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractNamedKey"})," Lookup a dictionary item via a Contract's named keys."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The contract key as a formatted string whose named keys contains dictionary_name."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"EntityNamedKey"})}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The entity address formatted as a string."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_name"})," The named key under which the dictionary seed URef is stored."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," Lookup a dictionary item via its seed URef."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"seed_uref"})," The dictionary's seed URef."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"dictionary_item_key"})," The dictionary item key formatted as a string."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Dictionary"})," Lookup a dictionary item via its unique key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded hash digest."}),"\n",(0,s.jsx)(n.h2,{id:"effects",children:"Effects"}),"\n",(0,s.jsxs)(n.p,{children:["A log of all ",(0,s.jsx)(n.a,{href:"#transformv2",children:"transforms"})," produced during execution."]}),"\n",(0,s.jsx)(n.h2,{id:"entityactionthresholds",children:"EntityActionThresholds"}),"\n",(0,s.jsx)(n.p,{children:"Thresholds that have to be met when executing an action of a certain type."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"deployment"})})," Threshold for deploy execution."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"key_management"})})," Threshold for managing account keys."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityassociatedkeyweight",children:(0,s.jsx)(n.code,{children:"upgrade_management"})})," Threshold for upgrading contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityaddr",children:"EntityAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address for an AddressableEntity which contains the 32 bytes and tagging information."}),"\n",(0,s.jsx)(n.p,{children:"Any of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address for a system entity account or contract."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to an Account."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The address of an entity that corresponds to a user (non-system) smart contract."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeys",children:"EntityAssociatedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A collection of weighted public keys (represented as account hashes) associated with an account. See ",(0,s.jsx)(n.a,{href:"#array_of_associatedkey",children:"Array_of_AssociatedKey"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"entityassociatedkeyweight",children:"EntityAssociatedKeyWeight"}),"\n",(0,s.jsx)(n.p,{children:"The weight associated with public keys in an entity's associated keys."}),"\n",(0,s.jsx)(n.h2,{id:"entityidentifier",children:"EntityIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier of an addressable entity."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entitykind",children:"EntityKind"}),"\n",(0,s.jsxs)(n.p,{children:["The type of ",(0,s.jsx)(n.a,{href:"#package",children:(0,s.jsx)(n.code,{children:"Package"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#systementitytype",children:(0,s.jsx)(n.code,{children:"System"})})," Package associated with a native contract implementation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"Account"})})," Package associated with an Account hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"SmartContract"})})," Packages associated with Wasm stored on chain."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityoraccount",children:"EntityOrAccount"}),"\n",(0,s.jsx)(n.p,{children:"An addressable entity or a legacy account."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An addressable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," A legacy account."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionandhash",children:"EntityVersionAndHash"}),"\n",(0,s.jsx)(n.p,{children:"An entity version associated with the given hash."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#addressableentityhash",children:(0,s.jsx)(n.code,{children:"addressable_entity_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"entity_version_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entityversionkey",children:"EntityVersionKey"}),"\n",(0,s.jsxs)(n.p,{children:["Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(n.code,{children:"EntityVersion"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entity_version"})," Automatically incremented value for a contract version within a major ",(0,s.jsx)(n.code,{children:"ProtocolVersion"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," Major element of ",(0,s.jsx)(n.code,{children:"ProtocolVersion"})," with which a ",(0,s.jsx)(n.code,{children:"ContractVersion"})," is compatible."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint2",children:"EntryPoint2"}),"\n",(0,s.jsx)(n.p,{children:"Type signature of a method. Order of arguments matters since they can be referenced by index as well as their name."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointaccess",children:(0,s.jsx)(n.code,{children:"access"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointpayment",children:(0,s.jsx)(n.code,{children:"entry_point_payment"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypointtype",children:(0,s.jsx)(n.code,{children:"entry_point_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The string name of the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"ret"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointaccess",children:"EntryPointAccess"}),"\n",(0,s.jsx)(n.p,{children:"Enum describing the possible access control options for a contract entry point."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Public"})," A public entry point is callable by any caller."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"Groups"})})," Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Template"})," A string type that can't be accessed directly but is kept in the derived Wasm bytes."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointpayment",children:"EntryPointPayment"}),"\n",(0,s.jsx)(n.p,{children:"An enum specifying who pays for the invocation and execution of the entrypoint."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," The caller must cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnly"})," The current execution will cover the cost to execute self but not the cost of any subsequently invoked contracts."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SelfOnward"})," The current execution will cover the cost to execute self and the cost of any subsequently invoked contracts."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointtype",children:"EntryPointType"}),"\n",(0,s.jsxs)(n.p,{children:["Context of an entry point execution. The most significant bit represents the version. For example, ",(0,s.jsx)(n.code,{children:"0b0"})," represents session and contract entry points up to version 2.0. And, ",(0,s.jsx)(n.code,{children:"0b1"})," is for versions 2.x and later (i.e. installer and utility entry points)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Caller"})," Runs using the calling entity's context. In v1.x, this was used for both session code that ran using the originating account's context and stored session code that ran in the caller's context. In v2.x, the renamed Caller variant is exclusively used for Wasm running using the initiating account entity's context. Previously installed 1.x stored session code should continue to work as the binary value matches, but we no longer allow such logic to be upgraded, nor do we allow new stored session code to be installed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Called"})," Runs within the called entity's context."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Factory"})," This entry point is intended to extract a subset of bytecode. Runs within the called entity's context."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointvalue",children:"EntryPointValue"}),"\n",(0,s.jsx)(n.p,{children:"The encaspulated representation of entrypoints."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint2",children:(0,s.jsx)(n.code,{children:"V1CasperVm"})})," Entrypoints to be executed against the V1 Casper VM."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypointv2",children:(0,s.jsx)(n.code,{children:"V2CasperVm"})})," Entrypoints to be executed against the V2 Casper VM."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypointv2",children:"EntryPointV2"}),"\n",(0,s.jsx)(n.p,{children:"The entry point for the V2 Casper VM."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"flags"})," The flags as a uint32 integer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"function_index"})," The selector as a uint32 integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv1",children:"EraEndV1"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#erareport_for_publickey",children:(0,s.jsx)(n.code,{children:"era_report"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraendv2",children:"EraEndV2"}),"\n",(0,s.jsx)(n.p,{children:"Information related to the end of an era and validator weights for the following era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any units during the era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"next_era_gas_price"})," The gas price for the next era as a ",(0,s.jsx)(n.code,{children:"uint8"})," integer. Minimum 0.0 motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_validatorweight",children:(0,s.jsx)(n.code,{children:"next_era_validator_weights"})})," The validators for the upcoming era and their respective weights."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"rewards"})})," The rewards distributed to the validators."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsx)(n.p,{children:"Era ID newtype."}),"\n",(0,s.jsx)(n.h2,{id:"eraidentifier",children:"EraIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for an era."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"Era"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockidentifier",children:(0,s.jsx)(n.code,{children:"Block"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsx)(n.p,{children:"Auction metadata. Intended to be recorded at each era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#seigniorageallocation",children:(0,s.jsx)(n.code,{children:"seigniorage_allocation"})})," Information about a seigniorage allocation."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareport_for_publickey",children:"EraReport_for_PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Equivocation, reward and validator inactivity information."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"equivocators"})})," The set of equivocators."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_erareward",children:(0,s.jsx)(n.code,{children:"rewards"})})," Rewards for finalization of earlier blocks."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"inactive_validators"})})," Validators that haven't produced any unit during the era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erareward",children:"EraReward"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with a measure of the value of its contribution to consensus, as a fraction of the configured maximum block reward."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The reward amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erasummary",children:"EraSummary"}),"\n",(0,s.jsx)(n.p,{children:"The summary of an era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The Block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#merkle-proof",children:(0,s.jsx)(n.code,{children:"merkle_proof"})})," The merkle proof."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})," Hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"stored_value"})})," The StoredValue containing era information."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executabledeployitem",children:"ExecutableDeployItem"}),"\n",(0,s.jsx)(n.p,{children:"Represents possible variants of an executable Deploy."}),"\n",(0,s.jsx)(n.h2,{id:"executioninfo",children:"ExecutionInfo"}),"\n",(0,s.jsx)(n.p,{children:"The block hash and height in which a given deploy was executed, along with the execution result if known."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"block_hash"})})," The hash of the block in which the deploy was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"block_height"})," The height of the block in which the deploy was executed."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#executionresult",children:(0,s.jsx)(n.code,{children:"execution_result"})})," The execution result if known."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(n.p,{children:"The journal of execution transforms from a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#operation",children:(0,s.jsx)(n.code,{children:"operations"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transformentry",children:(0,s.jsx)(n.code,{children:"transforms"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,s.jsx)(n.p,{children:"The versioned result of executing a single Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," Version 1 of execution result type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#executionresultv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," Version 2 of execution result type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv1",children:"ExecutionResultV1"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single deploy prior to Casper 2.0."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," The result of a failed execution"]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"error_message"})," The error message associated with executing the Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Success"})," The result of a successful execution."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#executioneffect",children:(0,s.jsx)(n.code,{children:"effect"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transferaddr",children:(0,s.jsx)(n.code,{children:"transfers"})})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresultv2",children:"ExecutionResultV2"}),"\n",(0,s.jsx)(n.p,{children:"The result of executing a single transaction."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"consumed"})})," How much gas was consumed executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"cost"})})," How much was paid for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#effects",children:(0,s.jsx)(n.code,{children:"effects"})})," The effects of executing this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator"})})," Who initiated this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"limit"})})," The maximum allowed gas limit for this transaction."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#paymentinfo",children:(0,s.jsx)(n.code,{children:"payment"})})," Breakdown of payments made to cover the cost."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"size_estimate"})," The size estimate of the transaction"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"transfers"})})," A record of transfers performed while executing this transaction."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"error_message"})," If there is no error message, this execution was processed successfully. If there is an error message, this execution failed to fully process for the stated reason."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"gas",children:"Gas"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"Gas"})," struct represents a ",(0,s.jsx)(n.code,{children:"U512"})," amount of gas."]}),"\n",(0,s.jsx)(n.h2,{id:"globalstateidentifier",children:"GlobalStateIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to query global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"BlockHash"})})," Query using a block hash."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"BlockHeight"})," Query using a block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"StateRootHash"})})," Query using the state root hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,s.jsx)(n.p,{children:'A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.'}),"\n",(0,s.jsx)(n.h2,{id:"initiatoraddr",children:"InitiatorAddr"}),"\n",(0,s.jsx)(n.p,{children:"The address of the initiator of a transaction"}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"publickey"})})," The public key of the initiator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"accounthash"})})," The account hash derived from the public key of the initiator."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonblockwithsignatures",children:"JsonBlockWithSignatures"}),"\n",(0,s.jsx)(n.p,{children:"A JSON-friendly representation of a block and the signatures for that block."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#block",children:(0,s.jsx)(n.code,{children:"block"})})," The block."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_blockproof",children:(0,s.jsx)(n.code,{children:"proofs"})})," The proofs of the block, i.e. a collection of validators' signatures of the block hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsoneravalidators",children:"JsonEraValidators"}),"\n",(0,s.jsx)(n.p,{children:"The validators for the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#jsonvalidatorsweights",children:(0,s.jsx)(n.code,{children:"validator_weights"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorchanges",children:"JsonValidatorChanges"}),"\n",(0,s.jsx)(n.p,{children:"The changes in a validator's status."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})," The public key of the validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#jsonvalidatorstatuschange",children:(0,s.jsx)(n.code,{children:"status_changes"})})," The set of changes to the validator's status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorstatuschange",children:"JsonValidatorStatusChange"}),"\n",(0,s.jsx)(n.p,{children:"A single change to a validator's status in the given era."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era in which the change occurred."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#validatorchange",children:(0,s.jsx)(n.code,{children:"validator_change"})})," The change in validator status."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"jsonvalidatorsweights",children:"JsonValidatorsWeights"}),"\n",(0,s.jsx)(n.p,{children:"A validator's weight."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"key",children:"Key"}),"\n",(0,s.jsx)(n.p,{children:"The key as a formatted string, under which data can be stored in global state."}),"\n",(0,s.jsx)(n.h2,{id:"messagechecksum",children:"MessageChecksum"}),"\n",(0,s.jsx)(n.p,{children:"Message checksum as a formatted string."}),"\n",(0,s.jsx)(n.h2,{id:"messagetopic",children:"MessageTopic"}),"\n",(0,s.jsx)(n.p,{children:"A topic for contract-level messages."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"topic_name"})," A string used to identify the message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#topicnamehash",children:(0,s.jsx)(n.code,{children:"topic_name_hash"})})," The hash of the name of the message topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"messagetopicsummary",children:"MessageTopicSummary"}),"\n",(0,s.jsx)(n.p,{children:"Summary of a message topic that will be stored in global state."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blocktime",children:(0,s.jsx)(n.code,{children:"blocktime"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"message_count"})," The number of messages in this topic."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"minimalblockinfo",children:"MinimalBlockInfo"}),"\n",(0,s.jsxs)(n.p,{children:["Minimal info of a ",(0,s.jsx)(n.code,{children:"Block"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"creator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#blockhash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," The block height."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"state_root_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsx)(n.p,{children:"Named arguments to a contract."}),"\n",(0,s.jsx)(n.h2,{id:"namedentrypoint",children:"NamedEntryPoint"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#entrypoint",children:"entry point"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," A string identifying the entry point."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsx)(n.p,{children:"A named key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The value of the entry: a casper ",(0,s.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeys",children:"NamedKeys"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"#namedkey",children:"collection of named keys"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"namedkeyvalue",children:"NamedKeyValue"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"NamedKey"})," value."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"named_key"})," The actual ",(0,s.jsx)(n.code,{children:"Key"})," encoded as a ",(0,s.jsx)(n.code,{children:"CLValue"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"namedusergroup",children:"NamedUserGroup"}),"\n",(0,s.jsxs)(n.p,{children:["A named ",(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group"})}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#group",children:(0,s.jsx)(n.code,{children:"group_name"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"group_users"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nextupgrade",children:"NextUpgrade"}),"\n",(0,s.jsx)(n.p,{children:"Information about the next protocol upgrade."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#activationpoint",children:(0,s.jsx)(n.code,{children:"activation_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(n.p,{children:"An operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#opkind",children:(0,s.jsx)(n.code,{children:"kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"opkind",children:"OpKind"}),"\n",(0,s.jsx)(n.p,{children:"The type of operation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Read"})," A read operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," A write operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Add"})," An addition."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"NoOp"})," An operation which has no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," A prune operation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"package",children:"Package"}),"\n",(0,s.jsx)(n.p,{children:"Entity definition, metadata and security container."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entityversionkey",children:(0,s.jsx)(n.code,{children:"disabled_versions"})})," Collection of disabled entity versions. The runtime will not permit disabled entity versions to be executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_namedusergroup",children:(0,s.jsx)(n.code,{children:"groups"})})," Mapping maintaining the set of URefs associated with each user group, used to control access to methods in a particular version of the entity. A method is callable by any context which knows any of the URefs associated with the method's user group."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#packagestatus",children:(0,s.jsx)(n.code,{children:"lock_status"})})," A flag that determines whether a entity is locked."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#array_of_entityversionandhash",children:(0,s.jsx)(n.code,{children:"versions"})})," All versions (enabled & disabled)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsx)(n.p,{children:"Parameter to an entry point."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"name"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"packagehash",children:"PackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hex-encoded address of a package associated with an ",(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"packagestatus",children:"PackageStatus"}),"\n",(0,s.jsx)(n.p,{children:"An enum to determine the lock status of the package."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Locked"})," The package is locked and cannot be versioned."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Unlocked"})," The package is unlocked and can be versioned."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"paymentinfo",children:"PaymentInfo"}),"\n",(0,s.jsx)(n.p,{children:"Breakdown of payments made to cover the cost."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"source"})," Source purse used for payment of the transaction."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peerentry",children:"PeerEntry"}),"\n",(0,s.jsx)(n.p,{children:"Node peer entry."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"address"})," Node address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"node_id"})," Node ID."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"peers",children:"Peers"}),"\n",(0,s.jsx)(n.p,{children:"Map of peer IDs to network addresses."}),"\n",(0,s.jsx)(n.h2,{id:"pricingmode",children:"PricingMode"}),"\n",(0,s.jsx)(n.p,{children:"The pricing mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Classic"})," The original payment model, where the creator of the transaction specifies how much they will pay, at what gas price."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Fixed"})," The cost of the transaction is determined by the cost table, per the transaction category."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Reserved"})," The payment for this transaction was previously reserved (Not currently implemented)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsx)(n.p,{children:"Casper Platform protocol version."}),"\n",(0,s.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic public key, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"publickeyandbid",children:"PublicKeyAndBid"}),"\n",(0,s.jsx)(n.p,{children:"A bid associated with the given public key."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"bid"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"public_key"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"publickeyanddelegator",children:"PublicKeyAndDelegator"}),"\n",(0,s.jsx)(n.p,{children:"A delegator associated with the given validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#delegator",children:(0,s.jsx)(n.code,{children:"delegator"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"purseidentifier",children:"PurseIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"The identifier of a purse."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_public_key"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_account_hash"})," The main purse under a provided ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#accounthash",children:(0,s.jsx)(n.code,{children:"AccountHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"main_purse_under_entity_addr"})," The main purse of the account identified by this ",(0,s.jsx)(n.a,{href:"#entityaddr",children:(0,s.jsx)(n.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"purse_uref"})," A specific purse identified by the associated ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"reservationkind",children:"ReservationKind"}),"\n",(0,s.jsx)(n.p,{children:"Container for bytes recording location, type and data for a gas reservation."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"receipt"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"reservation_data"})})," Hex-encoded bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"reservation_kind"})," A ",(0,s.jsx)(n.code,{children:"uint8"})," integer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"rewardedsignatures",children:"RewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["Describes finality signatures that will be rewarded in a block. Consists of a vector of ",(0,s.jsx)(n.a,{href:"#singleblockrewardedsignatures",children:(0,s.jsx)(n.code,{children:"SingleBlockRewardedSignatures"})}),", each of which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n",(0,s.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsx)(n.p,{children:"Represents a collection of arguments passed to a smart contract."}),"\n",(0,s.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(n.p,{children:"Information about a seigniorage allocation."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Validator"})," Info about a seigniorage allocation for a validator."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegator"})," Info about a seigniorage allocation for a delegator."]}),"\n",(0,s.jsx)(n.p,{children:"Require Parameters:"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Allocated amount."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"delegator_public_key"})})," Delegator's public key."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," Validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded cryptographic signature, including the algorithm tag prefix."}),"\n",(0,s.jsx)(n.h2,{id:"singleblockrewardedsignatures",children:"SingleBlockRewardedSignatures"}),"\n",(0,s.jsxs)(n.p,{children:["List of identifiers for finality signatures for a particular past block. That past block height is equal to ",(0,s.jsx)(n.code,{children:"current_height"})," minus ",(0,s.jsx)(n.code,{children:"signature_rewards_max_delay"}),", the latter being defined in the chainspec."]}),"\n",(0,s.jsx)(n.h2,{id:"storedvalue",children:"StoredValue"}),"\n",(0,s.jsx)(n.p,{children:"Representation of a value stored in global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})})," A Casper-specific value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#account",children:(0,s.jsx)(n.code,{children:"Account"})})," An Account."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ContractWasm"})," A contract's Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contract",children:(0,s.jsx)(n.code,{children:"Contract"})})," Entry points supported by a contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contractpackage",children:(0,s.jsx)(n.code,{children:"ContractPackage"})})," A contract definition, metadata, and security container."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transfer",children:(0,s.jsx)(n.code,{children:"LegacyTransfer"})})," A version 1 (legacy) transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployinfo",children:(0,s.jsx)(n.code,{children:"DeployInfo"})})," A record of a Deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})})," Information about an era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"Bid"})})," A bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Withdraw"})})," A withdraw."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#unbondingpurse",children:(0,s.jsx)(n.code,{children:"Unbonding"})})," Unbonding information."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#addressableentity",children:(0,s.jsx)(n.code,{children:"AddressableEntity"})})," An AddressableEntity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#bidkind",children:(0,s.jsx)(n.code,{children:"BidKind"})})," A variant that stored ",(0,s.jsx)(n.code,{children:"BidKind"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"Package"}),"] A ",(0,s.jsx)(n.code,{children:"Package"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["[",(0,s.jsx)(n.code,{children:"ByteCode"}),"] A record of byte code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagetopic",children:(0,s.jsx)(n.code,{children:"MessageTopic"})})," A variant that stores a message topic."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#messagechecksum",children:(0,s.jsx)(n.code,{children:"Message"})})," A variant that stores a message digest."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"NamedKey"})})," A NamedKey record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#reservationkind",children:(0,s.jsx)(n.code,{children:"Reservation"})})," A reservation record."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"EntryPoint"})})," An entrypoint record."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"systementitytype",children:"SystemEntityType"}),"\n",(0,s.jsx)(n.p,{children:"System contract types."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Mint"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"HandlePayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"StandardPayment"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"Auction"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsx)(n.p,{children:"Human-readable duration."}),"\n",(0,s.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsx)(n.p,{children:"Timestamp formatted as per RFC 3339."}),"\n",(0,s.jsx)(n.h2,{id:"topicnamehash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(n.p,{children:["The hash of the name of the ",(0,s.jsx)(n.a,{href:"#messagetopic",children:"message topic"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction or deploy."}),"\n",(0,s.jsx)(n.p,{children:"Contains one of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#deploy",children:(0,s.jsx)(n.code,{children:"deploy"})})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"or"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#transactionv1",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"An entry point of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Call"})," The standard ",(0,s.jsx)(n.code,{children:"call"})," entry point used in session code."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Custom"})," A non-native, arbitrary entry point."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Transfer"})," The ",(0,s.jsx)(n.code,{children:"transfer"})," native entry point, used to reference motes from a source purse to a target purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddBid"})," The ",(0,s.jsx)(n.code,{children:"add_bid"})," native entry point, used to create or top off a bid purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WithdrawBid"})," The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," native entry point, used to decrease a validator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Delegate"})," The ",(0,s.jsx)(n.code,{children:"delegate"})," native entry point, used to add a new delegator or increase an existing delegator's stake."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Undelegate"})," The ",(0,s.jsx)(n.code,{children:"undelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Redelegate"})," The ",(0,s.jsx)(n.code,{children:"redelegate"})," native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero. After the unbonding delay, it will automatically delegate to a new validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ActivateBid"})," The ",(0,s.jsx)(n.code,{children:"activate_bid"})," native entry point, used to used to reactivate an inactive bid."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ChangeBidPublicKey"})," The ",(0,s.jsx)(n.code,{children:"change_bid_public_key"})," native entry point, used to change a bid's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transaction hash or deploy hash."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"Deploy"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionv1hash",children:(0,s.jsx)(n.code,{children:"Version1"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(n.p,{children:["The identifier of a ",(0,s.jsx)(n.code,{children:"stored"})," transaction target."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByHash"})," The hex-encoded entity address identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByName"})," The alias identifying the invocable entity."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageHash"})," The address and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"addr"})," The hex-encoded address of the package."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ByPackageName"})," The alias and optional version identifying the package."]}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," The package name."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"version"})," The package version. If ",(0,s.jsx)(n.code,{children:"None"}),", the latest enabled version is implied."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsx)(n.p,{children:"Runtime used to execute a transaction."}),"\n",(0,s.jsx)(n.p,{children:"Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV1"})," The Casper Version 1 Virtual Machine."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"VmCasperV2"})," The Casper Version 2 Virtual Machine."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsx)(n.p,{children:"The scheduling mode of a transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Standard"})," No special scheduling applied."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureEra"})," Execution should be scheduled for the specific era."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureEra"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"FutureEra"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"FutureTimestamp"})," Execution should be scheduled for the specific timestamp or later."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for ",(0,s.jsx)(n.code,{children:"FutureTimestamp"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"FutureTimestamp"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsx)(n.p,{children:"The execution target of a Transaction."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"native"})," The execution target is a native operation."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"stored"})," The execution target is a stored entity or package."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"stored"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(n.code,{children:"id"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"session"})," The execution target is the included module bytes."]}),"\n",(0,s.jsxs)(n.p,{children:["Required parameters for a ",(0,s.jsx)(n.code,{children:"session"})," target:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytes",children:(0,s.jsx)(n.code,{children:"module_bytes"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionruntime",children:(0,s.jsx)(n.code,{children:"runtime"})})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1",children:"TransactionV1"}),"\n",(0,s.jsx)(n.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#approval",children:(0,s.jsx)(n.code,{children:"approvals"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1body",children:(0,s.jsx)(n.code,{children:"body"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1hash",children:(0,s.jsx)(n.code,{children:"hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionV1header",children:(0,s.jsx)(n.code,{children:"header"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsx)(n.p,{children:"The body of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#runtimeargs",children:(0,s.jsx)(n.code,{children:"args"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_point"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactionscheduling",children:(0,s.jsx)(n.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#transactiontarget",children:(0,s.jsx)(n.code,{children:"target"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(n.p,{children:"A hex-encoded TransactionV1 hash."}),"\n",(0,s.jsx)(n.h2,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a TransactionV1."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#digest",children:(0,s.jsx)(n.code,{children:"body_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"chain_name"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"initiator_addr"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#pricingmode",children:(0,s.jsx)(n.code,{children:"pricing_mode"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timestamp",children:(0,s.jsx)(n.code,{children:"timestamp"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#timediff",children:(0,s.jsx)(n.code,{children:"ttl"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transfer",children:"Transfer"}),"\n",(0,s.jsx)(n.p,{children:"A versioned wrapper for a transfer."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv1",children:(0,s.jsx)(n.code,{children:"Version1"})})," A version 1 transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transferv2",children:(0,s.jsx)(n.code,{children:"Version2"})})," A version 2 transfer."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded version 1 transfer address."}),"\n",(0,s.jsx)(n.h2,{id:"transferv1",children:"TransferV1"}),"\n",(0,s.jsx)(n.p,{children:"Represents a transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#deployhash",children:(0,s.jsx)(n.code,{children:"deploy_hash"})})," Deploy that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"from"})})," Account from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transferv2",children:"TransferV2"}),"\n",(0,s.jsx)(n.p,{children:"Represents a version 2 transfer from one purse to another."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Transfer amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transactionhash",children:(0,s.jsx)(n.code,{children:"transaction_hash"})})," Transaction that created the transfer."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#initiatoraddr",children:(0,s.jsx)(n.code,{children:"from"})})," Entity from which transfer was executed."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#gas",children:(0,s.jsx)(n.code,{children:"gas"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"source"})})," Source purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"target"})})," Target purse."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"id"})," User-defined ID."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#accounthash",children:(0,s.jsx)(n.code,{children:"to"})})," Account to which funds are transferred."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformerror",children:"TransformError"}),"\n",(0,s.jsxs)(n.p,{children:["Error type for applying and combining transforms. A ",(0,s.jsx)(n.code,{children:"TypeMismatch"})," occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string)."]}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#bytesreprerror",children:(0,s.jsx)(n.code,{children:"serialization"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#typemismatch",children:(0,s.jsx)(n.code,{children:"typemismatch"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deprecated"})," Type no longer supported."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv1",children:"TransformV1"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv1",children:(0,s.jsx)(n.code,{children:"transforms"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformv2",children:"TransformV2"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the ",(0,s.jsx)(n.code,{children:"Key"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#transformkindv2",children:(0,s.jsx)(n.code,{children:"kind"})})," The transformation."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv1",children:"TransformKindV1"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 1."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteCLValue"})," Writes the given CLValue to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAccount"})," Writes the given Account to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractWasm"})," Writes a smart contract as Wasm to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContract"})," Writes a smart contract to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteContractPackage"})," Writes a smart contract package to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteDeployInfo"})," Writes the given DeployInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteEraInfo"})," Writes the given EraInfo to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteTransfer"})," Writes the given Transfer to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBid"})," Writes the given Bid to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteWithdraw"})," Writes the given Withdraw to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteUnbonding"})," Writes the given Unbonding to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteAddressableEntity"})," Writes the addressable entity to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"WriteBidKind"})," Writes the given BidKind to global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transformkindv2",children:"TransformKindV2"}),"\n",(0,s.jsx)(n.p,{children:"The actual transformation performed while executing a Deploy in version 2."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Identity"})," A transform having no effect."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Write"})," Writes the new value in global state."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddInt32"})," Adds the given ",(0,s.jsx)(n.code,{children:"i32"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt64"})," Adds the given ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt128"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u128",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt256"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u256",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddUInt512"})," Adds the given ",(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"AddKeys"})," Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Prune"})," Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Failure"})," Represents the case where applying a transform would cause an error."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"typemismatch",children:"TypeMismatch"}),"\n",(0,s.jsxs)(n.p,{children:["An error struct representing a type mismatch in ",(0,s.jsx)(n.a,{href:"#storedvalue",children:(0,s.jsx)(n.code,{children:"StoredValue"})})," operations."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"expected"})," The name of the expected type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"found"})," The actual type found."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"u128",children:"U128"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 128-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u256",children:"U256"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 256-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"u512",children:"U512"}),"\n",(0,s.jsx)(n.p,{children:"Decimal representation of a 512-bit integer."}),"\n",(0,s.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(n.p,{children:"Unbonding purse."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"new_validator"})})," The redelegated validator's public key."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"uref",children:"URef"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded, formatted URef."}),"\n",(0,s.jsx)(n.h2,{id:"validatorbid",children:"ValidatorBid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," ",(0,s.jsx)(n.code,{children:"true"}),' if the validator has been "evicted".']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"maximum_delegation_amount"})," Minimum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"minimum_delegation_amount"})," Maximum allowed delegation amount in motes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"staked_amount"})})," The amount of tokens staked by a validator."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#vestingschedule",children:(0,s.jsx)(n.code,{children:"vesting_schedule"})})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorchange",children:"ValidatorChange"}),"\n",(0,s.jsx)(n.p,{children:"A change to a validator's status between two eras."}),"\n",(0,s.jsx)(n.p,{children:"One of:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Added"})," The validator was just added to the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Removed"})," The validator was removed from the validator set."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Banned"})," The validator was banned from this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CannotPropose"})," The validator was excluded from proposing new blocks in this era."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"SeenAsFaulty"})," We saw the validator misbehave in this era."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorcredit",children:"ValidatorCredit"}),"\n",(0,s.jsx)(n.p,{children:"Validator credit record."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," The credit amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_id"})})," The era id the credit was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The validator's public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"validatorweight",children:"ValidatorWeight"}),"\n",(0,s.jsx)(n.p,{children:"A validator's public key paired with its weight, i.e. the total number of motes it staked together with its delegators."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"weight"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"vestingschedule",children:"VestingSchedule"}),"\n",(0,s.jsx)(n.p,{children:"Vesting schedule for a genesis validator."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"initial_release_timestamp_millies"})," Timestamp of the initial release."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Optional Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"locked_amounts"})})," The amount of locked motes."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsx)(n.p,{children:"Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data."}),"\n",(0,s.jsx)(n.p,{children:"Required Parameters:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#u512",children:(0,s.jsx)(n.code,{children:"amount"})})," Unbonding amount."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#uref",children:(0,s.jsx)(n.code,{children:"bonding_purse"})})," Bonding purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"era_of_creation"})})," Era in which the unbonding request was created."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"unbonder_public_key"})})," Unbonder's public key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#publickey",children:(0,s.jsx)(n.code,{children:"validator_public_key"})})," The original validator's public key."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(t,{...e})}):t(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>l,x:()=>c});var s=i(96540);const r={},d=s.createContext(r);function l(e){const n=s.useContext(d);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),s.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b0e8b9d5.48be246d.js b/assets/js/b0e8b9d5.48be246d.js new file mode 100644 index 000000000..5e510282f --- /dev/null +++ b/assets/js/b0e8b9d5.48be246d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[90616],{7278:(n,e,s)=>{s.r(e),s.d(e,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>d,metadata:()=>l,toc:()=>h});var t=s(74848),i=s(28453);const d={title:"Introduction",slug:"/resources/tokens/cep78/introduction"},r="CEP-78 Enhanced NFT Standard Introduction",l={id:"resources/tokens/cep78/introduction",title:"Introduction",description:"Usage",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/introduction.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/introduction",permalink:"/2.0.0/resources/tokens/cep78/introduction",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Introduction",slug:"/resources/tokens/cep78/introduction"},sidebar:"resources",previous:{title:"Testing Guide",permalink:"/2.0.0/resources/tokens/cep18/tests"},next:{title:"CEP-78 Modalities",permalink:"/2.0.0/resources/tokens/cep78/modalities"}},c={},h=[{value:"Usage",id:"usage",level:2},{value:"Building the Contract",id:"building-the-contract",level:3},{value:"Required Runtime Arguments",id:"required-runtime-arguments",level:3},{value:"Example deploy",id:"example-deploy",level:4},{value:"Utility Session Code",id:"utility-session-code",level:3},{value:"Checking Token Ownership",id:"checking-token-ownership",level:3},{value:"Upgrading to Version 1.1.1",id:"upgrading-to-version-111",level:3},{value:"Installing and Interacting with the Contract using the Rust Casper Client",id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",level:2},{value:"Test Suite and Specification",id:"test-suite-and-specification",level:2},{value:"Error Codes",id:"error-codes",level:2}];function a(n){const e={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"cep-78-enhanced-nft-standard-introduction",children:"CEP-78 Enhanced NFT Standard Introduction"})}),"\n",(0,t.jsx)(e.h2,{id:"usage",children:"Usage"}),"\n",(0,t.jsx)(e.h3,{id:"building-the-contract",children:"Building the Contract"}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"main.rs"})," file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command from the Makefile provided."]}),"\n",(0,t.jsxs)(e.p,{children:["The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the ",(0,t.jsx)(e.code,{children:"make build-contract"})," command provided in the Makefile. Please note, however, that you must install ",(0,t.jsx)(e.code,{children:"wasm-strip"})," to build the contract."]}),"\n",(0,t.jsxs)(e.p,{children:["The ",(0,t.jsx)(e.code,{children:"call"})," method will install the contract with the necessary entrypoints and call the ",(0,t.jsx)(e.code,{children:"init()"})," entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation."]}),"\n",(0,t.jsx)(e.h3,{id:"required-runtime-arguments",children:"Required Runtime Arguments"}),"\n",(0,t.jsxs)(e.p,{children:["The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities",children:"Modalities"})," documentation."]}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_name":'})," The name of the NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"collection_symbol"'}),": The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"total_token_supply"'}),": The total number of NFTs that a specific instance of a contract will mint passed in as a ",(0,t.jsx)(e.code,{children:"U64"})," value. This parameter is required."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"ownership_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#ownership",children:(0,t.jsx)(e.code,{children:"OwnershipMode"})})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_kind"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#nftkind",children:(0,t.jsx)(e.code,{children:"NFTKind"})})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"json_schema"'}),": The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(e.code,{children:"String"}),". This parameter is required if the metadata kind is set to ",(0,t.jsx)(e.code,{children:"CustomValidated(3)"})," and cannot be changed post installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"nft_metadata_kind"'}),": The base metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"identifier_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#nftidentifiermode",children:(0,t.jsx)(e.code,{children:"NFTIdentifierMode"})})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n",(0,t.jsxs)(e.li,{children:[(0,t.jsx)(e.code,{children:'"metadata_mutability"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#metadata-mutability",children:(0,t.jsx)(e.code,{children:"MetadataMutability"})})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsx)(e.p,{children:"The following are the optional parameters that can be passed in at the time of installation."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"minting_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#minting",children:(0,t.jsx)(e.code,{children:"MintingMode"})})," modality that dictates the access to the ",(0,t.jsx)(e.code,{children:"mint()"})," entry-point in the NFT contract. This is an optional parameter that will default to restricting access to the installer of the contract. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"allow_minting"'}),": The ",(0,t.jsx)(e.code,{children:'"allow_minting"'})," flag allows the installer of the contract to pause the minting of new NFTs. The ",(0,t.jsx)(e.code,{children:"allow_minting"})," is a boolean toggle that allows minting when ",(0,t.jsx)(e.code,{children:"true"}),". If not provided at install the toggle will default to ",(0,t.jsx)(e.code,{children:"true"}),". This value can be changed by the installer by calling the ",(0,t.jsx)(e.code,{children:"set_variables()"})," entrypoint."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"whitelist_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#whitelistmode",children:(0,t.jsx)(e.code,{children:"WhitelistMode"})})," modality dictates whether the contract whitelist can be updated. This optional parameter will default to an unlocked whitelist that can be updated post installation. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"holder_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#nftholdermode",children:(0,t.jsx)(e.code,{children:"NFTHolderMode"})})," modality dictates which entities can hold NFTs. This is an optional parameter and will default to a mixed mode allowing either ",(0,t.jsx)(e.code,{children:"Accounts"})," or ",(0,t.jsx)(e.code,{children:"Contracts"})," to hold NFTs. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"contract_whitelist"'}),": The contract whitelist is a list of contract hashes that specifies which contracts can call the ",(0,t.jsx)(e.code,{children:"mint()"})," entrypoint to mint NFTs. This is an optional parameter which will default to an empty whitelist. This value can be changed via the ",(0,t.jsx)(e.code,{children:"set_variables"})," post installation. If the whitelist mode is set to locked, a non-empty whitelist must be passed; else, installation of the contract will fail."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"burn_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#burnmode",children:(0,t.jsx)(e.code,{children:"BurnMode"})})," modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"owner_reverse_lookup_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#reportingmode",children:(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})})," modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"events_mode"'}),": The ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/modalities#eventsmode",children:(0,t.jsx)(e.code,{children:"EventsMode"})})," modality selects the event schema used to record any changes that occur to tokens issued by the contract instance."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"additional_required_metdata"'}),": An additional metadata schema that must be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.code,{children:'"optional_metdata"'}),": An optional metadata schema that may be included. This argument is passed in as a ",(0,t.jsx)(e.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(e.h4,{id:"example-deploy",children:"Example deploy"}),"\n",(0,t.jsxs)(e.p,{children:["The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:'casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'enhanced-nft-1\'" \\\n--session-arg "collection_symbol:string=\'ENFT-1\'" \\\n--session-arg "total_token_supply:u64=\'10\'" \\\n--session-arg "ownership_mode:u8=\'0\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "allow_minting:bool=\'true\'" \\\n--session-arg "owner_reverse_lookup_mode:u8=\'0\'" \\\n--session-arg "nft_metadata_kind:u8=\'2\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(e.h3,{id:"utility-session-code",children:"Utility Session Code"}),"\n",(0,t.jsxs)(e.p,{children:["Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary.\nIn order to help with the installation and use of the NFT contract, session code for such entrypoints has been provided. It is recommended that\nusers and DApp developers attempting to engage with the NFT contract do so with the help of the provided utility session code. The session code can be found in the ",(0,t.jsx)(e.code,{children:"client"}),"\nfolder within the project folder."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Entrypoint name"}),(0,t.jsx)(e.th,{children:"Session code"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"mint"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/mint_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"balance_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/balance_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"get_approved'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/get_approved_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"owner_of"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/owner_of_session"})})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:'"transfer"'})}),(0,t.jsx)(e.td,{children:(0,t.jsx)(e.code,{children:"client/transfer_session"})})]})]})]}),"\n",(0,t.jsx)(e.h3,{id:"checking-token-ownership",children:"Checking Token Ownership"}),"\n",(0,t.jsxs)(e.p,{children:[(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/tutorials/token-ownership-tutorial.md",children:"Learn to check token ownership"})," starting with version ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/releases/tag/v1.1.1",children:"v1.1.1"}),". The ",(0,t.jsx)(e.code,{children:"OwnerReverseLookupMode"})," modality must be set to ",(0,t.jsx)(e.code,{children:"Complete"})," as described ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h3,{id:"upgrading-to-version-111",children:"Upgrading to Version 1.1.1"}),"\n",(0,t.jsxs)(e.p,{children:["Upgrade to v1.1.1 using a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/standard-migration-tutorial.md",children:"Standard NamedKey Convention"})," or a ",(0,t.jsx)(e.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/custom-migration-tutorial.md",children:"Custom NamedKey Convention"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"installing-and-interacting-with-the-contract-using-the-rust-casper-client",children:"Installing and Interacting with the Contract using the Rust Casper Client"}),"\n",(0,t.jsxs)(e.p,{children:["You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client ",(0,t.jsx)(e.a,{href:"/2.0.0/resources/tokens/using-casper-client",children:"here"}),"."]}),"\n",(0,t.jsx)(e.h2,{id:"test-suite-and-specification",children:"Test Suite and Specification"}),"\n",(0,t.jsxs)(e.p,{children:["The expected behavior of the NFT contract implementation is asserted by its test suite found in the ",(0,t.jsx)(e.code,{children:"tests"})," folder.\nThe test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors\nof the NFT contract across the entire range of possible configurations (i.e modalities and toggles like allow minting). The test suite\nensures that as new modalities are added, and current modalities are extended, no regressions and conflicting behaviors are introduced.\nThe test suite also asserts the correct working behavior of the utility session code provided in the client folder. The tests can be run\nby using the provided ",(0,t.jsx)(e.code,{children:"Makefile"})," and running the ",(0,t.jsx)(e.code,{children:"make test"})," command."]}),"\n",(0,t.jsx)(e.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(e.table,{children:[(0,t.jsx)(e.thead,{children:(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.th,{children:"Code"}),(0,t.jsx)(e.th,{children:"Error"})]})}),(0,t.jsxs)(e.tbody,{children:[(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"1"}),(0,t.jsx)(e.td,{children:"InvalidAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"2"}),(0,t.jsx)(e.td,{children:"MissingInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"3"}),(0,t.jsx)(e.td,{children:"InvalidInstaller"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"4"}),(0,t.jsx)(e.td,{children:"UnexpectedKeyVariant"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"5"}),(0,t.jsx)(e.td,{children:"MissingTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"6"}),(0,t.jsx)(e.td,{children:"InvalidTokenOwner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"7"}),(0,t.jsx)(e.td,{children:"FailedToGetArgBytes"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"8"}),(0,t.jsx)(e.td,{children:"FailedToCreateDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"9"}),(0,t.jsx)(e.td,{children:"MissingStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"10"}),(0,t.jsx)(e.td,{children:"InvalidStorageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"11"}),(0,t.jsx)(e.td,{children:"MissingOwnerUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"12"}),(0,t.jsx)(e.td,{children:"InvalidOwnersUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"13"}),(0,t.jsx)(e.td,{children:"FailedToAccessStorageDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"14"}),(0,t.jsx)(e.td,{children:"FailedToAccessOwnershipDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"15"}),(0,t.jsx)(e.td,{children:"DuplicateMinted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"16"}),(0,t.jsx)(e.td,{children:"FailedToConvertCLValue"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"17"}),(0,t.jsx)(e.td,{children:"MissingCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"18"}),(0,t.jsx)(e.td,{children:"InvalidCollectionName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"19"}),(0,t.jsx)(e.td,{children:"FailedToSerializeMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"20"}),(0,t.jsx)(e.td,{children:"MissingAccount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"21"}),(0,t.jsx)(e.td,{children:"MissingMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"22"}),(0,t.jsx)(e.td,{children:"InvalidMintingStatus"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"23"}),(0,t.jsx)(e.td,{children:"MissingCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"24"}),(0,t.jsx)(e.td,{children:"InvalidCollectionSymbol"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"25"}),(0,t.jsx)(e.td,{children:"MissingTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"26"}),(0,t.jsx)(e.td,{children:"InvalidTotalTokenSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"27"}),(0,t.jsx)(e.td,{children:"MissingTokenID"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"28"}),(0,t.jsx)(e.td,{children:"InvalidTokenIdentifier"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"29"}),(0,t.jsx)(e.td,{children:"MissingTokenOwners"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"30"}),(0,t.jsx)(e.td,{children:"MissingAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"31"}),(0,t.jsx)(e.td,{children:"InvalidAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"32"}),(0,t.jsx)(e.td,{children:"TokenSupplyDepleted"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"33"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"34"}),(0,t.jsx)(e.td,{children:"TokenAlreadyBelongsToMinterFatal"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"35"}),(0,t.jsx)(e.td,{children:"FatalTokenIdDuplication"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"36"}),(0,t.jsx)(e.td,{children:"InvalidMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"37"}),(0,t.jsx)(e.td,{children:"MissingMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"38"}),(0,t.jsx)(e.td,{children:"InvalidMintingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"39"}),(0,t.jsx)(e.td,{children:"MissingInstallerKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"40"}),(0,t.jsx)(e.td,{children:"FailedToConvertToAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"41"}),(0,t.jsx)(e.td,{children:"InvalidBurner"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"42"}),(0,t.jsx)(e.td,{children:"PreviouslyBurntToken"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"43"}),(0,t.jsx)(e.td,{children:"MissingAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"44"}),(0,t.jsx)(e.td,{children:"InvalidAllowMinting"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"45"}),(0,t.jsx)(e.td,{children:"MissingNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"46"}),(0,t.jsx)(e.td,{children:"InvalidNumberOfMintedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"47"}),(0,t.jsx)(e.td,{children:"MissingTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"48"}),(0,t.jsx)(e.td,{children:"InvalidTokenMetaData"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"49"}),(0,t.jsx)(e.td,{children:"MissingApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"50"}),(0,t.jsx)(e.td,{children:"InvalidApprovedAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"51"}),(0,t.jsx)(e.td,{children:"MissingApprovedTokensDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"52"}),(0,t.jsx)(e.td,{children:"TokenAlreadyApproved"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"53"}),(0,t.jsx)(e.td,{children:"MissingApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"54"}),(0,t.jsx)(e.td,{children:"InvalidApproveAll"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"55"}),(0,t.jsx)(e.td,{children:"MissingOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"56"}),(0,t.jsx)(e.td,{children:"InvalidOperator"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"57"}),(0,t.jsx)(e.td,{children:"Phantom"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"58"}),(0,t.jsx)(e.td,{children:"ContractAlreadyInitialized"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"59"}),(0,t.jsx)(e.td,{children:"MintingIsPaused"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"60"}),(0,t.jsx)(e.td,{children:"FailureToParseAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"61"}),(0,t.jsx)(e.td,{children:"VacantValueInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"62"}),(0,t.jsx)(e.td,{children:"MissingOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"63"}),(0,t.jsx)(e.td,{children:"InvalidOwnershipMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"64"}),(0,t.jsx)(e.td,{children:"InvalidTokenMinter"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"65"}),(0,t.jsx)(e.td,{children:"MissingOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"66"}),(0,t.jsx)(e.td,{children:"InvalidAccountKeyInDictionary"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"67"}),(0,t.jsx)(e.td,{children:"MissingJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"68"}),(0,t.jsx)(e.td,{children:"InvalidJsonSchema"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"69"}),(0,t.jsx)(e.td,{children:"InvalidKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"70"}),(0,t.jsx)(e.td,{children:"InvalidOwnedTokens"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"71"}),(0,t.jsx)(e.td,{children:"MissingTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"72"}),(0,t.jsx)(e.td,{children:"InvalidTokenURI"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"73"}),(0,t.jsx)(e.td,{children:"MissingNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"74"}),(0,t.jsx)(e.td,{children:"InvalidNftKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"75"}),(0,t.jsx)(e.td,{children:"MissingHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"76"}),(0,t.jsx)(e.td,{children:"InvalidHolderMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"77"}),(0,t.jsx)(e.td,{children:"MissingWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"78"}),(0,t.jsx)(e.td,{children:"InvalidWhitelistMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"79"}),(0,t.jsx)(e.td,{children:"MissingContractWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"80"}),(0,t.jsx)(e.td,{children:"InvalidContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"81"}),(0,t.jsx)(e.td,{children:"UnlistedContractHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"82"}),(0,t.jsx)(e.td,{children:"InvalidContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"83"}),(0,t.jsx)(e.td,{children:"EmptyContractWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"84"}),(0,t.jsx)(e.td,{children:"MissingReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"85"}),(0,t.jsx)(e.td,{children:"InvalidReceiptName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"86"}),(0,t.jsx)(e.td,{children:"InvalidJsonMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"87"}),(0,t.jsx)(e.td,{children:"InvalidJsonFormat"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"88"}),(0,t.jsx)(e.td,{children:"FailedToParseCep78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"89"}),(0,t.jsx)(e.td,{children:"FailedToParse721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"90"}),(0,t.jsx)(e.td,{children:"FailedToParseCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"91"}),(0,t.jsx)(e.td,{children:"InvalidCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"92"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCEP78Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"93"}),(0,t.jsx)(e.td,{children:"InvalidNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"94"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyNFT721Metadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"95"}),(0,t.jsx)(e.td,{children:"InvalidCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"96"}),(0,t.jsx)(e.td,{children:"MissingNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"97"}),(0,t.jsx)(e.td,{children:"InvalidNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"98"}),(0,t.jsx)(e.td,{children:"MissingIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"99"}),(0,t.jsx)(e.td,{children:"InvalidIdentifierMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"100"}),(0,t.jsx)(e.td,{children:"FailedToParseTokenId"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"101"}),(0,t.jsx)(e.td,{children:"MissingMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"102"}),(0,t.jsx)(e.td,{children:"InvalidMetadataMutability"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"103"}),(0,t.jsx)(e.td,{children:"FailedToJsonifyCustomMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"104"}),(0,t.jsx)(e.td,{children:"ForbiddenMetadataUpdate"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"105"}),(0,t.jsx)(e.td,{children:"MissingBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"106"}),(0,t.jsx)(e.td,{children:"InvalidBurnMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"107"}),(0,t.jsx)(e.td,{children:"MissingHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"108"}),(0,t.jsx)(e.td,{children:"InvalidHashByIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"109"}),(0,t.jsx)(e.td,{children:"MissingIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"110"}),(0,t.jsx)(e.td,{children:"InvalidIndexByHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"111"}),(0,t.jsx)(e.td,{children:"MissingPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"112"}),(0,t.jsx)(e.td,{children:"InvalidPageTableURef"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"113"}),(0,t.jsx)(e.td,{children:"MissingPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"114"}),(0,t.jsx)(e.td,{children:"InvalidPageLimit"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"115"}),(0,t.jsx)(e.td,{children:"InvalidPageNumber"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"116"}),(0,t.jsx)(e.td,{children:"InvalidPageIndex"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"117"}),(0,t.jsx)(e.td,{children:"MissingUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"118"}),(0,t.jsx)(e.td,{children:"InvalidUnmatchedHashCount"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"119"}),(0,t.jsx)(e.td,{children:"MissingPackageHashForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"120"}),(0,t.jsx)(e.td,{children:"MissingPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"121"}),(0,t.jsx)(e.td,{children:"InvalidPageUref"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"122"}),(0,t.jsx)(e.td,{children:"CannotUpgradeWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"123"}),(0,t.jsx)(e.td,{children:"CannotInstallWithZeroSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"124"}),(0,t.jsx)(e.td,{children:"MissingMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"125"}),(0,t.jsx)(e.td,{children:"InvalidMigrationFlag"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"126"}),(0,t.jsx)(e.td,{children:"ContractAlreadyMigrated"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"127"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInMint"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"128"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerInTransfer"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"129"}),(0,t.jsx)(e.td,{children:"MissingReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"130"}),(0,t.jsx)(e.td,{children:"InvalidReportingMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"131"}),(0,t.jsx)(e.td,{children:"MissingPage"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"132"}),(0,t.jsx)(e.td,{children:"UnregisteredOwnerFromMigration"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"133"}),(0,t.jsx)(e.td,{children:"ExceededMaxTotalSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"134"}),(0,t.jsx)(e.td,{children:"MissingCep78PackageHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"135"}),(0,t.jsx)(e.td,{children:"InvalidCep78InvalidHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"136"}),(0,t.jsx)(e.td,{children:"InvalidPackageHashName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"137"}),(0,t.jsx)(e.td,{children:"InvalidAccessKeyName"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"138"}),(0,t.jsx)(e.td,{children:"InvalidCheckForUpgrade"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"139"}),(0,t.jsx)(e.td,{children:"InvalidNamedKeyConvention"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"140"}),(0,t.jsx)(e.td,{children:"OwnerReverseLookupModeNotTransferable"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"141"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalRequiredMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"142"}),(0,t.jsx)(e.td,{children:"InvalidOptionalMetadata"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"143"}),(0,t.jsx)(e.td,{children:"MissingOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"144"}),(0,t.jsx)(e.td,{children:"InvalidOptionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"145"}),(0,t.jsx)(e.td,{children:"MissingAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"146"}),(0,t.jsx)(e.td,{children:"InvalidAdditionalNFTMetadataKind"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"147"}),(0,t.jsx)(e.td,{children:"InvalidRequirement"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"148"}),(0,t.jsx)(e.td,{children:"MissingEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"149"}),(0,t.jsx)(e.td,{children:"InvalidEventsMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"150"}),(0,t.jsx)(e.td,{children:"CannotUpgradeToMoreSupply"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"151"}),(0,t.jsx)(e.td,{children:"MissingOperatorDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"152"}),(0,t.jsx)(e.td,{children:"MissingApprovedDict"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"153"}),(0,t.jsx)(e.td,{children:"MissingSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"154"}),(0,t.jsx)(e.td,{children:"InvalidSpenderAccountHash"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"155"}),(0,t.jsx)(e.td,{children:"MissingOwnerTokenIdentifierKey"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"156"}),(0,t.jsx)(e.td,{children:"InvalidTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"157"}),(0,t.jsx)(e.td,{children:"MissingTransferFilterContract"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"158"}),(0,t.jsx)(e.td,{children:"TransferFilterContractNeedsTransferableMode"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"159"}),(0,t.jsx)(e.td,{children:"TransferFilterContractDenied"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"160"}),(0,t.jsx)(e.td,{children:"MissingACLWhiteList"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"161"}),(0,t.jsx)(e.td,{children:"InvalidACLWhitelist"})]}),(0,t.jsxs)(e.tr,{children:[(0,t.jsx)(e.td,{children:"162"}),(0,t.jsx)(e.td,{children:"EmptyACLWhitelist"})]})]})]})]})}function o(n={}){const{wrapper:e}={...(0,i.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(a,{...n})}):a(n)}},28453:(n,e,s)=>{s.d(e,{R:()=>r,x:()=>l});var t=s(96540);const i={},d=t.createContext(i);function r(n){const e=t.useContext(d);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function l(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(i):n.components||i:r(n.components),t.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/b114f501.3335785a.js b/assets/js/b114f501.3335785a.js new file mode 100644 index 000000000..99dcc0043 --- /dev/null +++ b/assets/js/b114f501.3335785a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7089],{9877:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var s=t(74848),i=t(28453);const r={title:"Funding Mainnet Accounts"},a="Funding Mainnet Accounts from an Exchange",o={id:"users/funding-from-exchanges",title:"Funding Mainnet Accounts",description:"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.",source:"@site/versioned_docs/version-2.0.0/users/funding-from-exchanges.md",sourceDirName:"users",slug:"/users/funding-from-exchanges",permalink:"/2.0.0/users/funding-from-exchanges",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Funding Mainnet Accounts"},sidebar:"users",previous:{title:"Block Explorers",permalink:"/2.0.0/users/block-explorer"},next:{title:"Delegating Tokens",permalink:"/2.0.0/users/delegating"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Transfers from Coinlist to Casper Mainnet",id:"transfers-from-coinlist-to-casper-mainnet",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"funding-mainnet-accounts-from-an-exchange",children:"Funding Mainnet Accounts from an Exchange"})}),"\n",(0,s.jsxs)(n.p,{children:["To send CSPR tokens from an exchange to a Mainnet account, you need the ",(0,s.jsx)(n.strong,{children:"Mainnet account's public key"}),". Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes."]}),"\n",(0,s.jsxs)(n.p,{children:["This guide demonstrates a withdrawal from ",(0,s.jsx)(n.a,{href:"https://coinlist.co/",children:"Coinlist"})," to the Casper Mainnet using the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer. You need to contact the exchange for instructions if you are working with a different exchange."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.p,{children:["Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"})," and the field you need to specify in the withdrawal request from Coinlist."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Account public key from CSPR.Live",src:t(49887).A+"",width:"2412",height:"1008"})}),"\n",(0,s.jsx)(n.h2,{id:"transfers-from-coinlist-to-casper-mainnet",children:"Transfers from Coinlist to Casper Mainnet"}),"\n",(0,s.jsx)(n.p,{children:"Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Log into your ",(0,s.jsx)(n.a,{href:"https://coinlist.co",children:"https://coinlist.co"})," account."]}),"\n",(0,s.jsx)(n.li,{children:'Go to the "Wallet" tab.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Coinlist Wallet tab",src:t(51038).A+"",width:"208",height:"385"})}),"\n",(0,s.jsxs)(n.ol,{start:"3",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "CSPR" section.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"CSPR on Coinlist",src:t(57888).A+"",width:"224",height:"241"})}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:'Click on the "Withdraw" button.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdraw on Coinlist",src:t(52823).A+"",width:"977",height:"389"})}),"\n",(0,s.jsxs)(n.ol,{start:"5",children:["\n",(0,s.jsx)(n.li,{children:'Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.'}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Withdrawal fields on Coinlist",src:t(77970).A+"",width:"433",height:"537"})}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:['Enter 0 in the "Transfer ID" field or another value that is meaningful to you. ',(0,s.jsx)(n.strong,{children:"You MUST enter a value, or the transfer will fail!"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Enter the CSPR amount you wish to transfer."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:'Click "Review".'}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Submit the transfer request. Wait approximately 5 minutes, and then go to the ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"https://cspr.live/"}),' site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.']}),"\n"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},49887:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/1.account-public-key-bc632beb571934137e88fe4669e3fb2d.png"},51038:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/2.coinlist-wallet-cad5dafdacd2765f28866b9873302238.png"},57888:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/3.cspr-section-coinlist-0d627442f8f9412464d23060184c98b4.png"},52823:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/4.withdraw-coinlist-7823f45f8471dcfa637fc6e803b157ac.png"},77970:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/5.withdraw-fields-coinlist-e701e55f389ca38a109a393565234c56.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b15d29cb.755d6cd9.js b/assets/js/b15d29cb.755d6cd9.js new file mode 100644 index 000000000..40a54452a --- /dev/null +++ b/assets/js/b15d29cb.755d6cd9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61767],{96409:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const o={},t="C",a={id:"concepts/glossary/C",title:"C",description:"---",source:"@site/docs/concepts/glossary/C.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/C",permalink:"/concepts/glossary/C",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"B",permalink:"/concepts/glossary/B"},next:{title:"D",permalink:"/concepts/glossary/D"}},i={},l=[{value:"Cargo",id:"cargo",level:2},{value:"Casper network",id:"casper-network",level:2},{value:"CBC",id:"cbc",level:2},{value:"Chainspec",id:"chainspec",level:2},{value:"Consensus",id:"consensus",level:2},{value:"Contract runtime",id:"contract-runtime",level:2},{value:"Correct by construction",id:"correct-by-construction",level:2},{value:"Crate",id:"crate",level:2},{value:"CSPR",id:"cspr",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"c",children:"C"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"cargo",children:"Cargo"}),"\n",(0,r.jsx)(s.p,{children:"Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies."}),"\n",(0,r.jsx)(s.h2,{id:"casper-network",children:"Casper network"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"cbc",children:"CBC"}),"\n",(0,r.jsx)(s.p,{children:"Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval."}),"\n",(0,r.jsx)(s.li,{children:"The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted."}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"chainspec",children:"Chainspec"}),"\n",(0,r.jsxs)(s.p,{children:["A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G#genesis",children:"genesis"}),". Here is an example ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"chainspec"}),", which will change with newer releases."]}),"\n",(0,r.jsx)(s.h2,{id:"consensus",children:"Consensus"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/design/consensus",children:"Consensus"})," is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as ",(0,r.jsx)(s.em,{children:"consensus"}),". The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer."]}),"\n",(0,r.jsx)(s.h2,{id:"contract-runtime",children:"Contract runtime"}),"\n",(0,r.jsxs)(s.p,{children:["Enables developers to use a seamless workflow for authoring and testing their ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S#smart-contract",children:"smart contracts"}),". This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices."]}),"\n",(0,r.jsx)(s.h2,{id:"correct-by-construction",children:"Correct by construction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"crate",children:"Crate"}),"\n",(0,r.jsxs)(s.p,{children:["A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, ",(0,r.jsx)(s.em,{children:"rustc"}),", the compiler for the Rust programming language, will produce a binary from a crate."]}),"\n",(0,r.jsx)(s.h2,{id:"cspr",children:"CSPR"}),"\n",(0,r.jsxs)(s.p,{children:["CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S#staking",children:"staking"})," (securing the network)."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b15d29cb.801818ce.js b/assets/js/b15d29cb.801818ce.js deleted file mode 100644 index 17def0aba..000000000 --- a/assets/js/b15d29cb.801818ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1767],{96409:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var t=s(74848),r=s(28453);const c={},o="C",a={id:"concepts/glossary/C",title:"C",description:"---",source:"@site/docs/concepts/glossary/C.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/C",permalink:"/next/concepts/glossary/C",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"B",permalink:"/next/concepts/glossary/B"},next:{title:"D",permalink:"/next/concepts/glossary/D"}},i={},l=[{value:"Cargo",id:"cargo",level:2},{value:"Casper network",id:"casper-network",level:2},{value:"CBC",id:"cbc",level:2},{value:"Chainspec",id:"chainspec",level:2},{value:"Consensus",id:"consensus",level:2},{value:"Contract runtime",id:"contract-runtime",level:2},{value:"Correct by construction",id:"correct-by-construction",level:2},{value:"Crate",id:"crate",level:2},{value:"CSPR",id:"cspr",level:2}];function h(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"c",children:"C"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"cargo",children:"Cargo"}),"\n",(0,t.jsx)(n.p,{children:"Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies."}),"\n",(0,t.jsx)(n.h2,{id:"casper-network",children:"Casper network"}),"\n",(0,t.jsxs)(n.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"cbc",children:"CBC"}),"\n",(0,t.jsx)(n.p,{children:"Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval."}),"\n",(0,t.jsx)(n.li,{children:"The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted."}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chainspec",children:"Chainspec"}),"\n",(0,t.jsxs)(n.p,{children:["A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G#genesis",children:"genesis"}),". Here is an example ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"chainspec"}),", which will change with newer releases."]}),"\n",(0,t.jsx)(n.h2,{id:"consensus",children:"Consensus"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/design/consensus",children:"Consensus"})," is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as ",(0,t.jsx)(n.em,{children:"consensus"}),". The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-runtime",children:"Contract runtime"}),"\n",(0,t.jsxs)(n.p,{children:["Enables developers to use a seamless workflow for authoring and testing their ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S#smart-contract",children:"smart contracts"}),". This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices."]}),"\n",(0,t.jsx)(n.h2,{id:"correct-by-construction",children:"Correct by construction"}),"\n",(0,t.jsxs)(n.p,{children:["See ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"crate",children:"Crate"}),"\n",(0,t.jsxs)(n.p,{children:["A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, ",(0,t.jsx)(n.em,{children:"rustc"}),", the compiler for the Rust programming language, will produce a binary from a crate."]}),"\n",(0,t.jsx)(n.h2,{id:"cspr",children:"CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S#staking",children:"staking"})," (securing the network)."]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},c=t.createContext(r);function o(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b192e983.9d48f4fd.js b/assets/js/b192e983.9d48f4fd.js new file mode 100644 index 000000000..fba94c24e --- /dev/null +++ b/assets/js/b192e983.9d48f4fd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74428],{2473:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>b,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Contract-Level Events"},s="Enabling Contracts to Emit Events",i={id:"developers/writing-onchain-code/emitting-contract-events",title:"Contract-Level Events",description:"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/emitting-contract-events.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/emitting-contract-events",permalink:"/2.0.0/developers/writing-onchain-code/emitting-contract-events",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Contract-Level Events"},sidebar:"developers",previous:{title:"Testing Session Code",permalink:"/2.0.0/developers/writing-onchain-code/testing-session-code"},next:{title:"Contract Hash vs. Package Hash",permalink:"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash"}},r={},o=[{value:"Creating a Topic",id:"creating-a-topic",level:2},{value:"Verifying a Topic",id:"verifying-a-topic",level:2},{value:"Emitting a Message",id:"emitting-a-message",level:2},{value:"Verifying a Message",id:"verifying-a-message",level:2},{value:"Querying global state",id:"querying-global-state",level:3},{value:"Costs and Chainspec Settings",id:"costs-and-chainspec-settings",level:2},{value:"Topic Management during Contract Upgrades",id:"topic-management-during-contract-upgrades",level:2},{value:"What's Next?",id:"whats-next",level:2}];function f(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"enabling-contracts-to-emit-events",children:"Enabling Contracts to Emit Events"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Messages produced by smart contracts are visible on a node's SSE event stream in human-readable format, and they contain the following information:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The address of the entity that produced the message, i.e., the contract hash"}),"\n",(0,t.jsx)(n.li,{children:"The message topic used to categorize the message"}),"\n",(0,t.jsx)(n.li,{children:"The human-readable message string"}),"\n",(0,t.jsx)(n.li,{children:"The index identifying the message in a message array"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["A checksum of the message is permanently stored in global state to protect against message spoofing and repudiation. For more details regarding the design and implementation of this feature, read the corresponding ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/ceps/pull/88",children:"CEP-88 documentation"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"Casper External FFI"})," provides the following two runtime functions to manage and emit messages:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"manage_message_topic"})," - Creates a topic to help categorize messages. When used for the first time, this function registers the contract's intent to emit messages. The maximum number of topics is specified in the chainspec. "]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"emit_message"})," - Emits a human-readable string message under a pre-registered topic."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following sections contain more details about using these functions."}),"\n",(0,t.jsx)(n.h2,{id:"creating-a-topic",children:"Creating a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["To create a new topic, call the ",(0,t.jsx)(n.code,{children:"manage_message_topic"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code adds a new message topic called ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),", on which the contract can emit messages:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::manage_message_topic(EVENTS_TOPIC, MessageTopicOperation::Add).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-topic",children:"Verifying a Topic"}),"\n",(0,t.jsxs)(n.p,{children:["No SSE event is emitted when a contract creates a new message topic. However, some applications need to determine which message topics are available to listen to messages on those topics. In global state, each contract entity contains a field called ",(0,t.jsx)(n.code,{children:"message_topics"}),", which stores a map of registered topic names by topic name hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsxs)(n.p,{children:["You can view the contract using the Casper CLI client and the ",(0,t.jsx)(n.code,{children:"query-global-state"})," command using the block identifier or the state root hash:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the key that identifies the contract, e.g., addressable-entity-contract-HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://127.0.0.1:11101 \\\n--key "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5" \\\n--block-identifier 58d26bf0eeeefb698d76b319014efd2eaa2198ad754a489a23131948ef41fdd2\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample contract"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4994937296370433409,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "deafd8e5c1aff47ae8528fa2d343b711c2f5cb18ee29527961b37d4d173ad42a",\n "state_root_hash": "96d8962c03899277f9a4bd667c0510c0eab490dd6253ae0b8cee4ebfbcd52be6",\n "body_hash": "28812ec460ab82f94f3c658e946bb4779c6b76dea9c55d18beaf1e47fe8dd9c9",\n "random_bit": false,\n "accumulated_seed": "96a09ea136bb7e4e99b039ee0f1f6d9dd88d663927faffc7eb5c60804056354c",\n "era_end": null,\n "timestamp": "2023-11-28T23:59:53.856Z",\n "era_id": 112,\n "height": 1066,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "AddressableEntity": {\n "package_hash": "contract-package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "byte_code_hash": "contract-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "named_keys": [\n {\n "name": "acl_package_mode",\n "key": "uref-2a088bc6c30d1499cd9348d388a03c8162ab26d09b0484f634e6f4022581fe99-007"\n },\n {\n "name": "acl_whitelist",\n "key": "uref-d17ecf3fe6e46f9a6063cfb31cdb03cdd6b99d095b71d2247319c293f864c4d1-007"\n },\n {\n "name": "allow_minting",\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-007"\n },\n {\n "name": "approved",\n "key": "uref-87a0de173fd6a56fb867bab46d8a508a43259a244ffdd8b0d98e5c286261f9af-007"\n },\n {\n "name": "balances",\n "key": "uref-0c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f-007"\n },\n {\n "name": "burn_mode",\n "key": "uref-e507551382a6217b9165dd222854e6c877d33eab9845c4b7e8444559303e5b8a-007"\n },\n {\n "name": "burnt_tokens",\n "key": "uref-4711c3ee36ac9639af509f45164fdb5a88692b109c3b2360e57d09fcdd702f63-007"\n },\n {\n "name": "cep78_CEP-78",\n "key": "uref-a02fc32366a7187448afb8263a8f3716e933d28d84db6c6403893d94917cf98d-007"\n },\n {\n "name": "collection_name",\n "key": "uref-89e904724d79a9f6d41958a3621b437c9e220ad081805f39040ff51c79a8d67c-007"\n },\n {\n "name": "collection_symbol",\n "key": "uref-d41a40789a84cc8e0314135695acc279875d6c7455daafe517cc4ae5329d95de-007"\n },\n {\n "name": "events_mode",\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-007"\n },\n {\n "name": "hash_by_index",\n "key": "uref-7c9751097762ad778a6a11151780d377cbc57e0807e289d278831ca9263aa844-007"\n },\n {\n "name": "holder_mode",\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-007"\n },\n {\n "name": "identifier_mode",\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-007"\n },\n {\n "name": "index_by_hash",\n "key": "uref-e67fecb85654def8b1440907728491f4f1ae125a97f3fed93872c075e6fb4ad5-007"\n },\n {\n "name": "installer",\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c"\n },\n {\n "name": "json_schema",\n "key": "uref-f8b2f63a4c69a84c795908e9abd0f66b857790b8df627a21336d6d1e07bf7103-007"\n },\n {\n "name": "metadata_cep78",\n "key": "uref-5cf8084639c2b7b8f54ab78700e0a82107c0bb28966cdc3ffdd4bd0877a47f64-007"\n },\n {\n "name": "metadata_custom_validated",\n "key": "uref-f5ce01c02a1942a4833159d72414c014b0838b607b4f419af9e19cd2fb123658-007"\n },\n {\n "name": "metadata_mutability",\n "key": "uref-c11c8e99c52477efaae636890a49625f54e32b832e23e288e00952c8bf34610a-007"\n },\n {\n "name": "metadata_nft721",\n "key": "uref-d39ee0c77f9864b05297ac504ee5919d60dddb6c8c0d6ccce8225801885f8972-007"\n },\n {\n "name": "metadata_raw",\n "key": "uref-dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a-007"\n },\n {\n "name": "minting_mode",\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-007"\n },\n {\n "name": "nft_kind",\n "key": "uref-001ffa305e021b5d411a3e04707b3c17f0d31ee400e6c5faa9b8f66e0ebfdc99-007"\n },\n {\n "name": "nft_metadata_kind",\n "key": "uref-8dfb98ccdd030aae1e0dcda03dc728dd4332eb18c945fd25a55b43f9e487141e-007"\n },\n {\n "name": "nft_metadata_kinds",\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-007"\n },\n {\n "name": "number_of_minted_tokens",\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-007"\n },\n {\n "name": "operator_burn_mode",\n "key": "uref-40977d32bbfb85454c9e7b5ca03192efcd406f228d5c2e593210b3960e05604e-007"\n },\n {\n "name": "operators",\n "key": "uref-cbcb06403fbd8cb9f397029718f1f7e66bf5ec4e33aa58315dd3d5ecf5d078a7-007"\n },\n {\n "name": "ownership_mode",\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-007"\n },\n {\n "name": "package_operator_mode",\n "key": "uref-c05e3e87f5a64fbc20615afffaa6e4c81d98431b698f681322f5d8730ff40590-007"\n },\n {\n "name": "page_table",\n "key": "uref-4c545e6e4860629fd138fcb91f24d21498e69b076d472660ff769dfc2a994301-007"\n },\n {\n "name": "receipt_name",\n "key": "uref-6ddba59f56a5d52df5b8f85d03d19003feec3307a9d9ac6b420486d1a440a586-007"\n },\n {\n "name": "reporting_mode",\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-007"\n },\n {\n "name": "rlo_mflag",\n "key": "uref-d520d8cbca2b28a42f0db9493e94bdbb93f74702e20eac1a77b48dda39367afe-007"\n },\n {\n "name": "token_issuers",\n "key": "uref-c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a-007"\n },\n {\n "name": "token_owners",\n "key": "uref-1cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d-007"\n },\n {\n "name": "total_token_supply",\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-007"\n },\n {\n "name": "whitelist_mode",\n "key": "uref-af7ba884bbddf91530279c0ea005c56a4951f5330ebe5395528471302b791b3e-007"\n }\n ],\n "entry_points": [\n {\n "name": "approve",\n "entry_point": {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "balance_of",\n "entry_point": {\n "name": "balance_of",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n }\n ],\n "ret": "U64",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "burn",\n "entry_point": {\n "name": "burn",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "get_approved",\n "entry_point": {\n "name": "get_approved",\n "args": [],\n "ret": {\n "Option": "Key"\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "init",\n "entry_point": {\n "name": "init",\n "args": [\n {\n "name": "collection_name",\n "cl_type": "String"\n },\n {\n "name": "collection_symbol",\n "cl_type": "String"\n },\n {\n "name": "total_token_supply",\n "cl_type": "U64"\n },\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "minting_mode",\n "cl_type": "U8"\n },\n {\n "name": "ownership_mode",\n "cl_type": "U8"\n },\n {\n "name": "nft_kind",\n "cl_type": "U8"\n },\n {\n "name": "holder_mode",\n "cl_type": "U8"\n },\n {\n "name": "whitelist_mode",\n "cl_type": "U8"\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "json_schema",\n "cl_type": "String"\n },\n {\n "name": "receipt_name",\n "cl_type": "String"\n },\n {\n "name": "identifier_mode",\n "cl_type": "U8"\n },\n {\n "name": "burn_mode",\n "cl_type": "U8"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n },\n {\n "name": "nft_metadata_kind",\n "cl_type": "U8"\n },\n {\n "name": "metadata_mutability",\n "cl_type": "U8"\n },\n {\n "name": "owner_reverse_lookup_mode",\n "cl_type": "U8"\n },\n {\n "name": "events_mode",\n "cl_type": "U8"\n },\n {\n "name": "transfer_filter_contract",\n "cl_type": {\n "Option": "Key"\n }\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "is_approved_for_all",\n "entry_point": {\n "name": "is_approved_for_all",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Bool",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "metadata",\n "entry_point": {\n "name": "metadata",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "migrate",\n "entry_point": {\n "name": "migrate",\n "args": [\n {\n "name": "cep78_package_key",\n "cl_type": "Any"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "mint",\n "entry_point": {\n "name": "mint",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": {\n "Tuple3": [\n "String",\n "Key",\n "String"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "owner_of",\n "entry_point": {\n "name": "owner_of",\n "args": [],\n "ret": "Key",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "register_owner",\n "entry_point": {\n "name": "register_owner",\n "args": [],\n "ret": {\n "Tuple2": [\n "String",\n "URef"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "revoke",\n "entry_point": {\n "name": "revoke",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_approval_for_all",\n "entry_point": {\n "name": "set_approval_for_all",\n "args": [\n {\n "name": "approve_all",\n "cl_type": "Bool"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_token_metadata",\n "entry_point": {\n "name": "set_token_metadata",\n "args": [\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "set_variables",\n "entry_point": {\n "name": "set_variables",\n "args": [\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "contract_whitelist",\n "cl_type": {\n "List": {\n "ByteArray": 32\n }\n }\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "transfer",\n "entry_point": {\n "name": "transfer",\n "args": [\n {\n "name": "source_key",\n "cl_type": "Key"\n },\n {\n "name": "target_key",\n "cl_type": "Key"\n }\n ],\n "ret": {\n "Tuple2": [\n "String",\n "Key"\n ]\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n },\n {\n "name": "updated_receipts",\n "entry_point": {\n "name": "updated_receipts",\n "args": [],\n "ret": {\n "List": {\n "Tuple2": [\n "String",\n "Key"\n ]\n }\n },\n "access": "Public",\n "entry_point_type": "AddressableEntity"\n }\n }\n ],\n "protocol_version": "1.0.0",\n "main_purse": "uref-596d134ad1078315a5e0cd2f40802b65cf53b6c789f0a38ba04157d04e15ab2b-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n ]\n }\n },\n "merkle_proof": "[8288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Under ",(0,t.jsx)(n.code,{children:"message_topics"}),", you will find the control record for that topic, which has a composite key derived from the caller's entity address and the hash of the topic name:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"message_topics": [\n {\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h2,{id:"emitting-a-message",children:"Emitting a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To emit a message on a previously-created topic, call the ",(0,t.jsx)(n.code,{children:"emit_message"})," runtime function. "]}),"\n",(0,t.jsxs)(n.p,{children:["This sample code sends a new message on the topic ",(0,t.jsx)(n.code,{children:"EVENTS_TOPIC"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::emit_message(EVENTS_TOPIC, &message.try_into().unwrap()).unwrap_or_revert();\n"})}),"\n",(0,t.jsx)(n.h2,{id:"verifying-a-message",children:"Verifying a Message"}),"\n",(0,t.jsxs)(n.p,{children:["To verify a message, check a node's SSE endpoint, which streams messages in a human-readable format. Messages are visible as part of the ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. The messages sent out on the event stream contain the following:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The identity of the entity that produced the message"}),"\n",(0,t.jsx)(n.li,{children:"The payload of the message"}),"\n",(0,t.jsx)(n.li,{children:"The name of the topic on which the message was emitted"}),"\n",(0,t.jsx)(n.li,{children:"The blake2b hash of the topic name"}),"\n",(0,t.jsx)(n.li,{children:"The message index in the topic"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The following is a sample message logged inside a ",(0,t.jsx)(n.code,{children:"TransactionProcessed"})," event:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n]\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the full TransactionProcessed message"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'data: {\n "TransactionProcessed": {\n "transaction_hash": {\n "Deploy": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26"\n },\n "account": "0130a16c8b0918cbfa8da00b6c0910ae0f2799dfd5ef7f092d0c4c1688031d60ac",\n "timestamp": "2023-11-29T01:35:41.522Z",\n "ttl": "30m",\n "block_hash": "b90c61cd1e3bc3be36110f04a7aec97b22bcfe9f36291cb011a14c4a663753bd",\n "execution_result": {\n "Version2": {\n "Success": {\n "effects": [\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "package-c092060112b445d1706f6962d7ad2da72a2e8312000e99d2b58f6a3e1624649a",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "0e9a6a8aff995ac138938d44c64d31",\n "parsed": "999999999999999999999518955956890"\n }\n }\n }\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "AddUInt512": "7500000000"\n }\n },\n {\n "key": "addressable-entity-contract-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "kind": "Identity"\n },\n {\n "key": "package-66cf48b3ccf32269ccc5d93059eef461bcf2c8b2460309ff3a442190688d5275",\n "kind": "Identity"\n },\n {\n "key": "byte-code-v1-wasm-23e042b941e45ea7fe4f81496fd778349f2002b2f786f9fddbdd1298450b60ad",\n "kind": "Identity"\n },\n {\n "key": "uref-c737324d1caa1885ad0f22f628933cfce91400ea259147186d330cf167eb6843-000",\n "kind": "Identity"\n },\n {\n "key": "uref-09b6f0901eb8cd9c6272be8199aeff4c6f5d2e3989980b548dbd595b40c033bf-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": "Identity"\n },\n {\n "key": "uref-962f6e020971031eb1bdd37f705df498cd4ee90c15aae901df9654a10461184d-000",\n "kind": "Identity"\n },\n {\n "key": "uref-e7acd748f4f82e609aa49f577e78e1ce6b1ab1dad5b5b1b59c8ff965598a6f34-000",\n "kind": "Identity"\n },\n {\n "key": "uref-cb9799861587032b55d391604c8a9f016d1237b0b600413d6c050da3e0fc81d1-000",\n "kind": "Identity"\n },\n {\n "key": "uref-bf32824dddf12dd16668581211ed22bef4b36c22db0165bde4986508f363940e-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-79bb2f90d7ab9cef266efe53e70722dc6e4fa56372ce8cd859b89cec3ff05307",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "8f0000008b0000007b226e616d65223a20224a6f686e20446f65222c22746f6b656e5f757269223a202268747470733a5c2f5c2f7777772e626172666f6f2e636f6d222c22636865636b73756d223a202239343062666662336632626261333566383433313361613236646130396563653361643437303435633661313239326332626264326466346162316135356662227d0a20000000dc660363cb2b4dfea2c01d8c3bf2258a3700fb6c830d13972ff206e330fd791a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-bba9996be36b1526113a0aaa030db658edd3c8719a60d55b35b7312f01f2e6da-000",\n "kind": "Identity"\n },\n {\n "key": "dictionary-203953bdea81a8373a987786d74eb94d8626c401a28625bb66c006079fd2bde7",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b200000001cabd90eac707493056418a62d8b82057af0d7c1e1b90d6139a46120fff4187d0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-453603548bb0d677edaa9bbc014bff6e30801a8d86eb85f884ad08e874fdc0f1",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "2100000000212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c0b20000000c1993c045f9e656b4bcb40639705d232cb6ecb4a2c6a04aeb33baffe9869cb9a0100000030",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "dictionary-3344eae47d44ef595de8219a32c69e9ac51ee14f020bd5da24f899fd49d12abf",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Any",\n "bytes": "08000000010000000000000005200000000c08f3df6e05e509000cd57646b98983481b8bcd46b98f0aae1a5abccc1e114f4000000032313266666464303430623635343935343139663430353763383339323933306534313066376266323462616565633864653539613631313762363365343563",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "uref-cd0871a7e69b91a05dbf81068115e45380de3a35bd2258369e3a24b7958cd77f-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "uref-d950666b546fe7afcf123f833ba4166b395c03bdbfd5de86dab051af3c1cdac0-000",\n "kind": "Identity"\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": "Identity"\n },\n {\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n },\n {\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n },\n {\n "key": "uref-b6c48cfa2fa090b71912b209638b33bbf8b670a8d8a1065d73b54c70f5cc414c-000",\n "kind": "Identity"\n },\n {\n "key": "deploy-09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "kind": {\n "Write": {\n "DeployInfo": {\n "deploy_hash": "09b90ada8b456e342f3209b3330c1d3bba0452d453c7f37106fed9799b280e26",\n "transfers": [],\n "from": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "source": "uref-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861-007",\n "gas": "610139570"\n }\n }\n }\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "package-42c6bbc82e3fc9dc4f890f507812a49c19aa998ed09b9d97996d9257e3c8c1c1",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f4952351cd81d38e205cd31a938b802241b70ac539d0fba5c5d2e0dc825f8944",\n "kind": "Identity"\n },\n {\n "key": "account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-account-a4cb74407b8da22b5dbf8cec4b2280fd2f2276bfeaa34ec64753071adf8960f5",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "04df4c7928",\n "parsed": "679038175"\n }\n }\n }\n },\n {\n "key": "balance-cfe2039aa5f3eca8a00d3444c4421e2034b77330d614b0c47c47d6af09113861",\n "kind": {\n "AddUInt512": "6820961825"\n }\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "package-aabcd5869e1e47a6e66ca2430fcabbe9687241e55e0a070204b150771f7aef74",\n "kind": "Identity"\n },\n {\n "key": "addressable-entity-system-f5a58fd26fb2200445eb04363affcc1240cb9e1882c6a86612de41e06e1082d1",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": "Identity"\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": "Identity"\n },\n {\n "key": "balance-278862691b1d6698c02c82b302aa391f1cd10a3637e4a8c633b4560917bc607b",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "balance-a3fceeee68671ef97338bbe16a31782a8e262b23c52116e0c73f02a1f25d14ac",\n "kind": {\n "AddUInt512": "679038175"\n }\n }\n ],\n "transfers": [],\n "cost": "610139570"\n }\n }\n },\n "messages": [\n {\n "entity_addr": "addressable-entity-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5",\n "message": {\n "String": "{\\"Mint\\":{\\"recipient\\":\\"account-hash-212ffdd040b65495419f4057c8392930e410f7bf24baeec8de59a6117b63e45c\\",\\"token_id\\":{\\"Index\\":0}}}"\n },\n "topic_name": "events",\n "topic_name_hash": "topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "index": 0\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.h3,{id:"querying-global-state",children:"Querying global state"}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are not stored in global state. However, global state stores a checksum of each message, allowing users to verify the origin and integrity of the message. The checksums in global state are unique and can be identified by the hash of the entity that emitted the message, the hash of the topic name, and the index of the message."}),"\n",(0,t.jsx)(n.p,{children:"You will find two types of stored values in global state:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The checksum of the message payload, as a 32-byte BLAKE2b hash of the serialized ",(0,t.jsx)(n.code,{children:"MessagePayload"})]}),"\n",(0,t.jsx)(n.li,{children:"The topic control record containing the number of messages sent on the topic and the timestamp of the block in which the messages were emitted"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Message key structure",src:a(50818).A+"",width:"2636",height:"730"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample keys"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "message-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0",\n "kind": {\n "Write": {\n "Message": "message-checksum-d4854042c69aac1bc64e6f9cb2e41f306fc106f79951429d1dfef56d638be3c0"\n }\n }\n},\n{\n "key": "message-topic-b51b0f9d94e5744af4dce6b4a9990c5f3e652c1a0a946e680e83f97d8846eff5-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1",\n "kind": {\n "Write": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701221761024\n }\n }\n }\n},\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can query global state to get the message checksum, given the block identifier and the composite key of the message. The message key includes the message hash, the topic name hash, and the message index."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message, i.e., message-CONTRACT_HASH-topic-name-TOPIC_HASH-MESSAGE_INDEX."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message checksum:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1-0" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3085511981091403408,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "Message": "message-checksum-56098444c4f0dff8f321cfa3769d400f4b5bfa9e01e6ad6b147d81b87130bfb9"\n },\n "merkle_proof": "[1336 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:"Emitted messages are temporary by design. Sometimes, message checksums are pruned from global state to manage storage. Pruning of old message records for a particular contract only happens if the contract emits messages again in a new block. Otherwise, the last entries from the time the contract was last executed are still retained in global state. Applications can query old checksums using the state root hash of the block that contains them."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view an example"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"Let's assume we have a contract that executes in a block with block time 1 and emits 100 messages."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block with block time 1, then we will see a control struct for the topic indicating message count 100 and block time 1."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume the contract executes in another block with block time 2 and emits 50 messages."}),"\n",(0,t.jsx)(n.li,{children:"Then, if we query the global state at the root hash of the block at block time 2, we will see message count 50 and block time 2."}),"\n",(0,t.jsx)(n.li,{children:"Let's assume 3 blocks go by, and the contract doesn't execute in those blocks (block time 3, 4, 5)."}),"\n",(0,t.jsx)(n.li,{children:"If we query the global state at the root hash of the block at block time 5, we will see message count 50 and block time 2."}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is how you can determine the number of messages emitted in a particular block:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address <HOST:PORT> \\\n--key [HASH_STRING] \\\n--block-identifier <BLOCK_HASH> \\\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"key"})," - The identifier for the query. Use the composite key that identifies the message topic, e.g., message-topic-CONTRACT_HASH-topic-name-TOPIC_HASH."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is a sample query to view the message topic:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://127.0.0.1:11101 \\\n--key "message-topic-803c759a466a84a0ab12147857f49e269369796a66ad37e94ab8343ddddb7823-topic-name-5721a6d9d7a9afe5dfdb35276fb823bed0f825350e4d865a5ec0110c380de4e1" \\\n--block-identifier d9642c5d90c7fc05a23d83a3abcf56d63cb71316402ecefe0962fdeccad2c99c\n'})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 1227453659579324378,\n "result": {\n "api_version": "1.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "e55e5127ec6ed5ac03767f9d8b0d0dbd434df81c03658dcc5d9f17b780de980a",\n "state_root_hash": "e033c27db66a4542b53477c97c4f9176ffce72ab6edebd6fdb25b2fe0aa70fe8",\n "body_hash": "ba26e345470f6322f39810e8408fff666026276dee72cbb9fa85ec55657070fb",\n "random_bit": false,\n "accumulated_seed": "caf392ee00d60d9729c8e042acbd851ff70be47b0e8a317cc728b3be47a815ce",\n "era_end": null,\n "timestamp": "2023-12-02T01:19:12.384Z",\n "era_id": 84,\n "height": 890,\n "protocol_version": "1.0.0"\n }\n },\n "stored_value": {\n "MessageTopic": {\n "message_count": 1,\n "blocktime": 1701479952384\n }\n },\n "merkle_proof": "[1288 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The message payload cannot be reconstructed by reading the entry from global state since that entry contains only the checksum of the messages sent."})}),"\n",(0,t.jsx)(n.h2,{id:"costs-and-chainspec-settings",children:"Costs and Chainspec Settings"}),"\n",(0,t.jsxs)(n.p,{children:["The following chainspec settings manage the cost of contract-level messages. These limits are bundled into the Wasm configuration settings under the ",(0,t.jsx)(n.code,{children:"wasm.messages_limits"}),". Consult the chainspec of the network you are working with, as the following are only examples."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.messages_limits]\n# Maximum size of the topic name.\nmax_topic_name_size = 256\n# Maximum number of topics that can be added for each contract.\nmax_topics_per_contract = 128\n# Maximum size in bytes of the serialized message payload.\nmax_message_size = 1_024\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Since contract-level messages are handled through FFIs, the gas cost related to using the new interface is captured in the ",(0,t.jsx)(n.code,{children:"wasm.host_function_costs"})," chainspec settings:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:"[wasm.host_function_costs]\nmanage_message_topic = { cost = 200, arguments = [0, 0, 0, 0] }\nemit_message = { cost = 200, arguments = [0, 0, 0, 0] }\ncost_increase_per_message = 50\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting increases the gas cost for each subsequent message when emitting multiple messages within a single execution. In the example above, within a single execution, the first message will cost 200 motes, the second will cost 250 motes, and so on. Each subsequent call will increase the gas cost by the value specified under the ",(0,t.jsx)(n.code,{children:"cost_increase_per_message"})," setting. The subsequent execution will start from the base cost specified in the ",(0,t.jsx)(n.code,{children:"emit_message"})," setting; in this case, the following execution will start at 200 motes."]}),"\n",(0,t.jsxs)(n.p,{children:["Storage is charged based on the ",(0,t.jsx)(n.code,{children:"wasm.storage_costs.gas_per_byte"})," chainspec parameter.\nWhen a new topic is added, two records are written in global state: the topic control record and the addressable entity record extended with the new topic name and topic name hash. Because the topic name is variable, the cost depends on the length of the topic name.\nWhen a message is emitted, two records are written in global state: the topic control record and the message checksum. Writing these records incurs a fixed cost based on ",(0,t.jsx)(n.code,{children:"gas_per_byte"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"topic-management-during-contract-upgrades",children:"Topic Management during Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"When a new contract version is added to the contract package, the message topics registered from the previous version are automatically carried over to the new contract. A new control record will be written for each topic for the new contract version."}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"monitor and consume the event stream"}),"."]}),"\n"]})]})}function b(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(f,{...e})}):f(e)}},50818:(e,n,a)=>{a.d(n,{A:()=>t});const t=a.p+"assets/images/message_keys-f4d30d684fcb186bbc91625a10f2870a.png"},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1eae65b.5f062bf3.js b/assets/js/b1eae65b.5f062bf3.js deleted file mode 100644 index 52ab42295..000000000 --- a/assets/js/b1eae65b.5f062bf3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9218],{56358:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var o=n(74848),s=n(28453);const a={title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},r="AddressableEntity in Casper 2.0",i={permalink:"/blog/addressable-entity",source:"@site/blog/2024-07-17-addressable-entity.md",title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",date:"2024-07-17T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"}],readingTime:3.665,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"},nextItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},c={authorsImageUrls:[void 0,void 0]},d=[];function l(e){const t={code:"code",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the ",(0,o.jsx)(t.code,{children:"AddressableEntity"})," type. This new structure replaces the separate ",(0,o.jsx)(t.code,{children:"AccountHash"})," and ",(0,o.jsx)(t.code,{children:"ContractHash"})," used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control."]}),"\n",(0,o.jsxs)(t.p,{children:["In this article, we'll dive into the details of ",(0,o.jsx)(t.code,{children:"AddressableEntity"}),", exploring its structure and functionalities."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b1eae65b.e24179ba.js b/assets/js/b1eae65b.e24179ba.js new file mode 100644 index 000000000..34dcc1018 --- /dev/null +++ b/assets/js/b1eae65b.e24179ba.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[99218],{56358:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var o=n(74848),s=n(28453);const a={title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},r="AddressableEntity in Casper 2.0",i={permalink:"/blog/addressable-entity",source:"@site/blog/2024-07-17-addressable-entity.md",title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",date:"2024-07-17T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"}],readingTime:3.665,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"},{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Addressable Entity in Casper 2.0",description:"An introduction to the Addressable Entity concept.",slug:"addressable-entity",date:"2024-07-17T18:00",authors:["sczembor","melpadden"],tags:["condor"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Casper Docs Redux!",permalink:"/blog/welcome-docs-redux"},nextItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},c={authorsImageUrls:[void 0,void 0]},d=[];function l(e){const t={code:"code",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsxs)(t.p,{children:["Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the ",(0,o.jsx)(t.code,{children:"AddressableEntity"})," type. This new structure replaces the separate ",(0,o.jsx)(t.code,{children:"AccountHash"})," and ",(0,o.jsx)(t.code,{children:"ContractHash"})," used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control."]}),"\n",(0,o.jsxs)(t.p,{children:["In this article, we'll dive into the details of ",(0,o.jsx)(t.code,{children:"AddressableEntity"}),", exploring its structure and functionalities."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>i});var o=n(96540);const s={},a=o.createContext(s);function r(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b36f50d3.b825a751.js b/assets/js/b36f50d3.b825a751.js deleted file mode 100644 index ff7ede706..000000000 --- a/assets/js/b36f50d3.b825a751.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3990],{29337:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=t(74848),s=t(28453);const o={},d="Setting up a Node",i={id:"operators/setup/index",title:"Setting up a Node",description:"The prerequisite for becoming a validator is to set up a node and join a network as described here.",source:"@site/docs/operators/setup/index.md",sourceDirName:"operators/setup",slug:"/operators/setup/",permalink:"/next/operators/setup/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"operators",previous:{title:"Overview",permalink:"/next/operators"},next:{title:"Hardware",permalink:"/next/operators/setup/hardware"}},a={},c=[];function h(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-node",children:"Setting up a Node"})}),"\n",(0,r.jsx)(n.p,{children:"The prerequisite for becoming a validator is to set up a node and join a network as described here."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/hardware",children:"Recommended Hardware Specifications"})}),(0,r.jsx)(n.td,{children:"System requirements for the Casper Mainnet and Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration",children:"Basic Node Configuration"})}),(0,r.jsx)(n.td,{children:"Processes and files involved in setting up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/node-endpoints",children:"Node Endpoints"})}),(0,r.jsx)(n.td,{children:"Ports for communicating with other nodes and dApps"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/install-node",children:"Installing a Node"})}),(0,r.jsx)(n.td,{children:"Step-by-step instructions to install a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/open-files",children:"Setting the Open Files Limit"})}),(0,r.jsx)(n.td,{children:"Required setting for the Casper node to run correctly"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/upgrade",children:"Upgrading the Node"})}),(0,r.jsx)(n.td,{children:"Before joining the network, the node needs to be upgraded"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/joining",children:"Joining a Running Network"})}),(0,r.jsx)(n.td,{children:"Steps to join an existing Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/non-root-user",children:"Setting up a Non-Root User"})}),(0,r.jsx)(n.td,{children:"Logging into the node remotely using a key"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/node-events",children:"Node Events"})}),(0,r.jsx)(n.td,{children:"Information on a node's events stream"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/next/operators/setup/casper-sidecar",children:"Sidecar Setup"})}),(0,r.jsx)(n.td,{children:"An application allowing subscribers to monitor a node's event stream, query stored events, and query a node\u2019s JSON-RPC API"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>i});var r=t(96540);const s={},o=r.createContext(s);function d(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b36f50d3.ce29c971.js b/assets/js/b36f50d3.ce29c971.js new file mode 100644 index 000000000..12adb669d --- /dev/null +++ b/assets/js/b36f50d3.ce29c971.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43990],{29337:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=t(74848),s=t(28453);const o={},d="Setting up a Node",i={id:"operators/setup/index",title:"Setting up a Node",description:"The prerequisite for becoming a validator is to set up a node and join a network as described here.",source:"@site/docs/operators/setup/index.md",sourceDirName:"operators/setup",slug:"/operators/setup/",permalink:"/operators/setup/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"operators",previous:{title:"Overview",permalink:"/operators"},next:{title:"Hardware",permalink:"/operators/setup/hardware"}},a={},c=[];function h(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-node",children:"Setting up a Node"})}),"\n",(0,r.jsx)(n.p,{children:"The prerequisite for becoming a validator is to set up a node and join a network as described here."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/hardware",children:"Recommended Hardware Specifications"})}),(0,r.jsx)(n.td,{children:"System requirements for the Casper Mainnet and Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic Node Configuration"})}),(0,r.jsx)(n.td,{children:"Processes and files involved in setting up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/node-endpoints",children:"Node Endpoints"})}),(0,r.jsx)(n.td,{children:"Ports for communicating with other nodes and dApps"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/install-node",children:"Installing a Node"})}),(0,r.jsx)(n.td,{children:"Step-by-step instructions to install a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/open-files",children:"Setting the Open Files Limit"})}),(0,r.jsx)(n.td,{children:"Required setting for the Casper node to run correctly"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/upgrade",children:"Upgrading the Node"})}),(0,r.jsx)(n.td,{children:"Before joining the network, the node needs to be upgraded"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/joining",children:"Joining a Running Network"})}),(0,r.jsx)(n.td,{children:"Steps to join an existing Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/non-root-user",children:"Setting up a Non-Root User"})}),(0,r.jsx)(n.td,{children:"Logging into the node remotely using a key"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/node-events",children:"Node Events"})}),(0,r.jsx)(n.td,{children:"Information on a node's events stream"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/casper-sidecar",children:"Sidecar Setup"})}),(0,r.jsx)(n.td,{children:"An application allowing subscribers to monitor a node's event stream, query stored events, and query a node\u2019s JSON-RPC API"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>i});var r=t(96540);const s={},o=r.createContext(s);function d(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b3a49b92.abfa439b.js b/assets/js/b3a49b92.abfa439b.js deleted file mode 100644 index 5f2eb3171..000000000 --- a/assets/js/b3a49b92.abfa439b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9113],{48258:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>x,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="Z",a={id:"concepts/glossary/Z",title:"Z",description:"---",source:"@site/docs/concepts/glossary/Z.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Z",permalink:"/next/concepts/glossary/Z",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Y",permalink:"/next/concepts/glossary/Y"},next:{title:"Binary Serialization Standard",permalink:"/next/concepts/serialization/"}},l={},h=[{value:"Zug",id:"zug",level:2}];function i(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"z",children:"Z"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"zug",children:"Zug"}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/design/zug",children:"Zug"})," is a simple, fast, and secure consensus protocol used on the Casper Mainnet. Read the paper: ",(0,r.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]})]})}function x(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(i,{...e})}):i(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b3a49b92.cbe25f10.js b/assets/js/b3a49b92.cbe25f10.js new file mode 100644 index 000000000..32f90d740 --- /dev/null +++ b/assets/js/b3a49b92.cbe25f10.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9113],{48258:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="Z",a={id:"concepts/glossary/Z",title:"Z",description:"---",source:"@site/docs/concepts/glossary/Z.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Z",permalink:"/concepts/glossary/Z",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Y",permalink:"/concepts/glossary/Y"},next:{title:"Binary Serialization Standard",permalink:"/concepts/serialization/"}},l={},h=[{value:"Zug",id:"zug",level:2}];function i(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"z",children:"Z"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"zug",children:"Zug"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/design/zug",children:"Zug"})," is a simple, fast, and secure consensus protocol used on the Casper Mainnet. Read the paper: ",(0,n.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b3b8c5cb.66ba977e.js b/assets/js/b3b8c5cb.66ba977e.js new file mode 100644 index 000000000..67a95a6b3 --- /dev/null +++ b/assets/js/b3b8c5cb.66ba977e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[39687],{72781:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=s(74848),n=s(28453);const r={},o="S",c={id:"concepts/glossary/S",title:"S",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/S.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/S",permalink:"/1.5.X/concepts/glossary/S",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"R",permalink:"/1.5.X/concepts/glossary/R"},next:{title:"T",permalink:"/1.5.X/concepts/glossary/T"}},i={},l=[{value:"Safe",id:"safe",level:2},{value:"Secret key",id:"secret-key",level:2},{value:"Seigniorage",id:"seigniorage",level:2},{value:"Session code",id:"session-code",level:2},{value:"Slashing",id:"slashing",level:2},{value:"Smart contract",id:"smart-contract",level:2},{value:"Smart-contract platform",id:"smart-contract-platform",level:2},{value:"Staker",id:"staker",level:2},{value:"Staking",id:"staking",level:2},{value:"State root hash",id:"state-root-hash",level:2},{value:"Stateful",id:"stateful",level:2},{value:"Stateless",id:"stateless",level:2},{value:"Switch Block",id:"switch-block",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"s",children:"S"})}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.h2,{id:"safe",children:"Safe"}),"\n",(0,a.jsxs)(t.p,{children:["When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"secret-key",children:"Secret key"}),"\n",(0,a.jsx)(t.p,{children:"A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations)."}),"\n",(0,a.jsx)(t.h2,{id:"seigniorage",children:"Seigniorage"}),"\n",(0,a.jsx)(t.p,{children:"The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators."}),"\n",(0,a.jsx)(t.h2,{id:"session-code",children:"Session code"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"Session code"})," is Wasm executed in the context of an account through sending a ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploy"}),". The ",(0,a.jsx)(t.em,{children:"session code"})," contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state."]}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsxs)(t.p,{children:["In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets ",(0,a.jsx)(t.em,{children:"slashed"}),", i.e., a part of it is removed."]}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract",children:"Smart contract"}),"\n",(0,a.jsx)(t.p,{children:"Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party."}),"\n",(0,a.jsxs)(t.p,{children:["On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"}),". The execution of a smart contract causes changes to the global state."]}),"\n",(0,a.jsx)(t.p,{children:"A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values."}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract-platform",children:"Smart-contract platform"}),"\n",(0,a.jsx)(t.p,{children:"A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts."}),"\n",(0,a.jsx)(t.h2,{id:"staker",children:"Staker"}),"\n",(0,a.jsxs)(t.p,{children:["A person that deposits tokens in the ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/P#proof-of-stake",children:"proof-of-stake"})," contract. A staker is either a ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validator"})," or a ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D#delegator",children:"delegator"}),". Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/T#token",children:"tokens"})," by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is ",(0,a.jsx)(t.a,{href:"#slashing",children:"slashed"}),", the staker will lose their tokens."]}),"\n",(0,a.jsx)(t.h2,{id:"staking",children:"Staking"}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The ",(0,a.jsx)(t.a,{href:"/1.5.X/staking",children:"Staking Guide"})," highlights the steps required to stake CSPR tokens on the Casper Mainnet."]}),"\n",(0,a.jsx)(t.h2,{id:"state-root-hash",children:"State root hash"}),"\n",(0,a.jsxs)(t.p,{children:["The state root hash is an identifier of the network's ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"})," at a moment in time. The state root hash changes with each block executed, containing deploys. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras."]}),"\n",(0,a.jsx)(t.h2,{id:"stateful",children:"Stateful"}),"\n",(0,a.jsx)(t.p,{children:"Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions."}),"\n",(0,a.jsx)(t.h2,{id:"stateless",children:"Stateless"}),"\n",(0,a.jsx)(t.p,{children:"Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time."}),"\n",(0,a.jsx)(t.h2,{id:"switch-block",children:"Switch Block"}),"\n",(0,a.jsxs)(t.p,{children:["A ",(0,a.jsx)(t.code,{children:"Switch Block"})," is the final block in an era, which contains the ",(0,a.jsx)(t.code,{children:"era_summary"}),". See also ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/B#booking-block",children:"booking block"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var a=s(96540);const n={},r=a.createContext(n);function o(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b3b8c5cb.d5f88718.js b/assets/js/b3b8c5cb.d5f88718.js deleted file mode 100644 index a87f50455..000000000 --- a/assets/js/b3b8c5cb.d5f88718.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9687],{72781:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=s(74848),n=s(28453);const r={},o="S",c={id:"concepts/glossary/S",title:"S",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/S.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/S",permalink:"/concepts/glossary/S",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"R",permalink:"/concepts/glossary/R"},next:{title:"T",permalink:"/concepts/glossary/T"}},i={},l=[{value:"Safe",id:"safe",level:2},{value:"Secret key",id:"secret-key",level:2},{value:"Seigniorage",id:"seigniorage",level:2},{value:"Session code",id:"session-code",level:2},{value:"Slashing",id:"slashing",level:2},{value:"Smart contract",id:"smart-contract",level:2},{value:"Smart-contract platform",id:"smart-contract-platform",level:2},{value:"Staker",id:"staker",level:2},{value:"Staking",id:"staking",level:2},{value:"State root hash",id:"state-root-hash",level:2},{value:"Stateful",id:"stateful",level:2},{value:"Stateless",id:"stateless",level:2},{value:"Switch Block",id:"switch-block",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"s",children:"S"})}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.h2,{id:"safe",children:"Safe"}),"\n",(0,a.jsxs)(t.p,{children:["When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see ",(0,a.jsx)(t.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"secret-key",children:"Secret key"}),"\n",(0,a.jsx)(t.p,{children:"A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations)."}),"\n",(0,a.jsx)(t.h2,{id:"seigniorage",children:"Seigniorage"}),"\n",(0,a.jsx)(t.p,{children:"The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators."}),"\n",(0,a.jsx)(t.h2,{id:"session-code",children:"Session code"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"Session code"})," is Wasm executed in the context of an account through sending a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"}),". The ",(0,a.jsx)(t.em,{children:"session code"})," contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state."]}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsxs)(t.p,{children:["In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets ",(0,a.jsx)(t.em,{children:"slashed"}),", i.e., a part of it is removed."]}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract",children:"Smart contract"}),"\n",(0,a.jsx)(t.p,{children:"Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party."}),"\n",(0,a.jsxs)(t.p,{children:["On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),". The execution of a smart contract causes changes to the global state."]}),"\n",(0,a.jsx)(t.p,{children:"A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values."}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract-platform",children:"Smart-contract platform"}),"\n",(0,a.jsx)(t.p,{children:"A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts."}),"\n",(0,a.jsx)(t.h2,{id:"staker",children:"Staker"}),"\n",(0,a.jsxs)(t.p,{children:["A person that deposits tokens in the ",(0,a.jsx)(t.a,{href:"/concepts/glossary/P#proof-of-stake",children:"proof-of-stake"})," contract. A staker is either a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/V#validator",children:"validator"})," or a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D#delegator",children:"delegator"}),". Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T#token",children:"tokens"})," by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is ",(0,a.jsx)(t.a,{href:"#slashing",children:"slashed"}),", the staker will lose their tokens."]}),"\n",(0,a.jsx)(t.h2,{id:"staking",children:"Staking"}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The ",(0,a.jsx)(t.a,{href:"/staking",children:"Staking Guide"})," highlights the steps required to stake CSPR tokens on the Casper Mainnet."]}),"\n",(0,a.jsx)(t.h2,{id:"state-root-hash",children:"State root hash"}),"\n",(0,a.jsxs)(t.p,{children:["The state root hash is an identifier of the network's ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," at a moment in time. The state root hash changes with each block executed, containing deploys. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras."]}),"\n",(0,a.jsx)(t.h2,{id:"stateful",children:"Stateful"}),"\n",(0,a.jsx)(t.p,{children:"Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions."}),"\n",(0,a.jsx)(t.h2,{id:"stateless",children:"Stateless"}),"\n",(0,a.jsx)(t.p,{children:"Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time."}),"\n",(0,a.jsx)(t.h2,{id:"switch-block",children:"Switch Block"}),"\n",(0,a.jsxs)(t.p,{children:["A ",(0,a.jsx)(t.code,{children:"Switch Block"})," is the final block in an era, which contains the ",(0,a.jsx)(t.code,{children:"era_summary"}),". See also ",(0,a.jsx)(t.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var a=s(96540);const n={},r=a.createContext(n);function o(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b415f00a.bd7e11c9.js b/assets/js/b415f00a.bd7e11c9.js new file mode 100644 index 000000000..91c0853f6 --- /dev/null +++ b/assets/js/b415f00a.bd7e11c9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3428],{58278:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>p,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var r=n(74848),o=n(28453);const t={},a="P",c={id:"concepts/glossary/P",title:"P",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/P.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/P",permalink:"/2.0.0/concepts/glossary/P",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"O",permalink:"/2.0.0/concepts/glossary/O"},next:{title:"Q",permalink:"/2.0.0/concepts/glossary/Q"}},i={},l=[{value:"Partial synchrony",id:"partial-synchrony",level:2},{value:"Participate in consensus",id:"participate-in-consensus",level:2},{value:"Payment code",id:"payment-code",level:2},{value:"Peer node",id:"peer-node",level:2},{value:"Permissionless",id:"permissionless",level:2},{value:"Primary token",id:"primary-token",level:2},{value:"Private key",id:"private-key",level:2},{value:"Proof-of-Stake",id:"proof-of-stake",level:2},{value:"Proof-of-Work",id:"proof-of-work",level:2},{value:"Proposer",id:"proposer",level:2},{value:"Proto block",id:"proto-block",level:2},{value:"Purse",id:"purse",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"p",children:"P"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"partial-synchrony",children:"Partial synchrony"}),"\n",(0,r.jsxs)(s.p,{children:["Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"participate-in-consensus",children:"Participate in consensus"}),"\n",(0,r.jsxs)(s.p,{children:["The process of following the ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#consensus",children:"consensus"})," algorithm. The primary participants are ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V#validator",children:"validators"}),", bonded with their stake and part of the validator set for that particular era. ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D#delegator",children:"Delegators"})," participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network."]}),"\n",(0,r.jsx)(s.h2,{id:"payment-code",children:"Payment code"}),"\n",(0,r.jsxs)(s.p,{children:["The ",(0,r.jsx)(s.em,{children:"payment code"})," is the ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W#webassembly",children:"Wasm"})," program that pays the transaction execution fee."]}),"\n",(0,r.jsx)(s.h2,{id:"peer-node",children:"Peer node"}),"\n",(0,r.jsx)(s.p,{children:"A node on a peer-to-peer (P2P) network."}),"\n",(0,r.jsx)(s.h2,{id:"permissionless",children:"Permissionless"}),"\n",(0,r.jsx)(s.p,{children:"A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants."}),"\n",(0,r.jsx)(s.h2,{id:"primary-token",children:"Primary token"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"private-key",children:"Private key"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S#secret-key",children:"secret key"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-stake",children:"Proof-of-Stake"}),"\n",(0,r.jsx)(s.p,{children:"Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proof-of-work",children:"Proof-of-Work"}),"\n",(0,r.jsx)(s.p,{children:"A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed."}),"\n",(0,r.jsx)(s.h2,{id:"proposer",children:"Proposer"}),"\n",(0,r.jsx)(s.p,{children:"The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain."}),"\n",(0,r.jsx)(s.h2,{id:"proto-block",children:"Proto block"}),"\n",(0,r.jsx)(s.p,{children:"The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated."}),"\n",(0,r.jsx)(s.p,{children:"A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era."}),"\n",(0,r.jsx)(s.h2,{id:"purse",children:"Purse"}),"\n",(0,r.jsxs)(s.p,{children:["A ",(0,r.jsx)(s.code,{children:"purse"})," is a unique type of ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U#uref",children:"URef"})," representing a token balance. An entity's ",(0,r.jsx)(s.em,{children:"main purse"})," represents the balance of CSPR tokens (in ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M#motes",children:"motes"}),") the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/design/casper-design#urefs-and-purses",children:"here"}),"."]})]})}function p(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>c});var r=n(96540);const o={},t=r.createContext(o);function a(e){const s=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),r.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b46ec474.0abc05a8.js b/assets/js/b46ec474.0abc05a8.js deleted file mode 100644 index 309ea2825..000000000 --- a/assets/js/b46ec474.0abc05a8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2958],{2945:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const r={title:"Upgrades"},a="Upgrading the Node",i={id:"operators/setup/upgrade",title:"Upgrades",description:"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.",source:"@site/docs/operators/setup/upgrade.md",sourceDirName:"operators/setup",slug:"/operators/setup/upgrade",permalink:"/next/operators/setup/upgrade",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Upgrades"},sidebar:"operators",previous:{title:"Open Files Limit",permalink:"/next/operators/setup/open-files"},next:{title:"Join a Network",permalink:"/next/operators/setup/joining"}},c={},d=[{value:"Upgrading Protocol Versions",id:"upgrading-protocol-versions",level:2},{value:"Upgrade Staging Instructions",id:"upgrade-staging-instructions",level:3},{value:"Verifying Successful Staging",id:"verifying-successful-staging",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"upgrading-the-node",children:"Upgrading the Node"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:(0,s.jsx)(n.code,{children:"chainspec.toml"})})," contains a section to indicate from which era the given ",(0,s.jsx)(n.code,{children:"casper-node"})," version should start running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[protocol]\n# This protocol version becomes active at the start of this era.\nactivation_point = 100\n"})}),"\n",(0,s.jsxs)(n.p,{children:["At every block finalization, the ",(0,s.jsx)(n.code,{children:"casper-node"})," looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file. This will be the era before where the current casper-node will cleanly shut down."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-node-launcher"})," will detect a clean exit 0 condition and start the next version of the ",(0,s.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"upgrading-protocol-versions",children:"Upgrading Protocol Versions"}),"\n",(0,s.jsxs)(n.p,{children:["All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of ",(0,s.jsx)(n.code,{children:"casper-node"})," immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point."]}),"\n",(0,s.jsx)(n.p,{children:"Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point."}),"\n",(0,s.jsx)(n.h3,{id:"upgrade-staging-instructions",children:"Upgrade Staging Instructions"}),"\n",(0,s.jsx)(n.p,{children:"The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On Testnet, use ",(0,s.jsx)(n.code,{children:"casper-test.conf"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": To only view the list of staged and unstaged protocols, use this command: ",(0,s.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py check_protocols casper.conf"})]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-successful-staging",children:"Verifying Successful Staging"}),"\n",(0,s.jsx)(n.p,{children:"After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://127.0.0.1:8888/status | jq .next_upgrade\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should expect this output if properly staged, prior to upgrading:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ curl -s localhost:8888/status | jq .next_upgrade\n{\n "activation_point": 4968,\n "protocol_version": "1.4.6"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you see ",(0,s.jsx)(n.code,{children:"null"})," after waiting for a few minutes, then your upgrade staging was not executed successfully."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": The protocol version will change as per the next upgrade available."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b46ec474.8b17c0c3.js b/assets/js/b46ec474.8b17c0c3.js new file mode 100644 index 000000000..7c0f9ae47 --- /dev/null +++ b/assets/js/b46ec474.8b17c0c3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62958],{2945:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const r={title:"Upgrades"},a="Upgrading the Node",i={id:"operators/setup/upgrade",title:"Upgrades",description:"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.",source:"@site/docs/operators/setup/upgrade.md",sourceDirName:"operators/setup",slug:"/operators/setup/upgrade",permalink:"/operators/setup/upgrade",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Upgrades"},sidebar:"operators",previous:{title:"Open Files Limit",permalink:"/operators/setup/open-files"},next:{title:"Join a Network",permalink:"/operators/setup/joining"}},c={},d=[{value:"Upgrading Protocol Versions",id:"upgrading-protocol-versions",level:2},{value:"Upgrade Staging Instructions",id:"upgrade-staging-instructions",level:3},{value:"Verifying Successful Staging",id:"verifying-successful-staging",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"upgrading-the-node",children:"Upgrading the Node"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:(0,s.jsx)(n.code,{children:"chainspec.toml"})})," contains a section to indicate from which era the given ",(0,s.jsx)(n.code,{children:"casper-node"})," version should start running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[protocol]\n# This protocol version becomes active at the start of this era.\nactivation_point = 100\n"})}),"\n",(0,s.jsxs)(n.p,{children:["At every block finalization, the ",(0,s.jsx)(n.code,{children:"casper-node"})," looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file. This will be the era before where the current casper-node will cleanly shut down."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-node-launcher"})," will detect a clean exit 0 condition and start the next version of the ",(0,s.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"upgrading-protocol-versions",children:"Upgrading Protocol Versions"}),"\n",(0,s.jsxs)(n.p,{children:["All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of ",(0,s.jsx)(n.code,{children:"casper-node"})," immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point."]}),"\n",(0,s.jsx)(n.p,{children:"Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point."}),"\n",(0,s.jsx)(n.h3,{id:"upgrade-staging-instructions",children:"Upgrade Staging Instructions"}),"\n",(0,s.jsx)(n.p,{children:"The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On Testnet, use ",(0,s.jsx)(n.code,{children:"casper-test.conf"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": To only view the list of staged and unstaged protocols, use this command: ",(0,s.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py check_protocols casper.conf"})]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-successful-staging",children:"Verifying Successful Staging"}),"\n",(0,s.jsx)(n.p,{children:"After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://127.0.0.1:8888/status | jq .next_upgrade\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should expect this output if properly staged, prior to upgrading:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ curl -s localhost:8888/status | jq .next_upgrade\n{\n "activation_point": 4968,\n "protocol_version": "1.4.6"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you see ",(0,s.jsx)(n.code,{children:"null"})," after waiting for a few minutes, then your upgrade staging was not executed successfully."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": The protocol version will change as per the next upgrade available."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b67f60dc.7656748c.js b/assets/js/b67f60dc.7656748c.js deleted file mode 100644 index 8c18ef936..000000000 --- a/assets/js/b67f60dc.7656748c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1801],{36889:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>i});var r=n(74848),c=n(28453);const o={},a="W",t={id:"concepts/glossary/W",title:"W",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/W.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/W",permalink:"/concepts/glossary/W",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"V",permalink:"/concepts/glossary/V"},next:{title:"X",permalink:"/concepts/glossary/X"}},l={},i=[{value:"Web3",id:"web3",level:2},{value:"WebAssembly",id:"webassembly",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"w",children:"W"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"web3",children:"Web3"}),"\n",(0,r.jsx)(s.p,{children:"An advanced version of the internet based on decentralization and trustless interactions."}),"\n",(0,r.jsx)(s.h2,{id:"webassembly",children:"WebAssembly"}),"\n",(0,r.jsx)(s.p,{children:"WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>t});var r=n(96540);const c={},o=r.createContext(c);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b67f60dc.9c1e5109.js b/assets/js/b67f60dc.9c1e5109.js new file mode 100644 index 000000000..1c664e61e --- /dev/null +++ b/assets/js/b67f60dc.9c1e5109.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[81801],{36889:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>t,toc:()=>i});var r=n(74848),c=n(28453);const o={},a="W",t={id:"concepts/glossary/W",title:"W",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/W.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/W",permalink:"/1.5.X/concepts/glossary/W",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"V",permalink:"/1.5.X/concepts/glossary/V"},next:{title:"X",permalink:"/1.5.X/concepts/glossary/X"}},l={},i=[{value:"Web3",id:"web3",level:2},{value:"WebAssembly",id:"webassembly",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"w",children:"W"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"web3",children:"Web3"}),"\n",(0,r.jsx)(s.p,{children:"An advanced version of the internet based on decentralization and trustless interactions."}),"\n",(0,r.jsx)(s.h2,{id:"webassembly",children:"WebAssembly"}),"\n",(0,r.jsx)(s.p,{children:"WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>t});var r=n(96540);const c={},o=r.createContext(c);function a(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b687a817.0ec13cad.js b/assets/js/b687a817.0ec13cad.js deleted file mode 100644 index c3f9e3794..000000000 --- a/assets/js/b687a817.0ec13cad.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1627],{13663:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const o={},r="Casper Node Networking Protocol",d={id:"concepts/design/networking-protocol",title:"Casper Node Networking Protocol",description:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",source:"@site/versioned_docs/version-1.5.X/concepts/design/networking-protocol.md",sourceDirName:"concepts/design",slug:"/concepts/design/networking-protocol",permalink:"/concepts/design/networking-protocol",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},a={},c=[{value:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",id:"casper-node-networking-protocol-mainnet-protocol-version-150",level:2},{value:"Connection Level",id:"connection-level",level:2},{value:"Reciprocity, retries and data direction",id:"reciprocity-retries-and-data-direction",level:3},{value:"TLS parameters",id:"tls-parameters",level:3},{value:"Discovery",id:"discovery",level:3},{value:"Framing",id:"framing",level:2},{value:"Encoding",id:"encoding",level:2},{value:"The <code>Message</code> Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The <code>Payload</code> Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"casper-node-networking-protocol",children:"Casper Node Networking Protocol"})}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-networking-protocol-mainnet-protocol-version-150",children:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of the ",(0,i.jsx)(n.code,{children:"casper-node"}),"'s networking protocol. This document follows the conventions laid out in ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"connection-level",children:"Connection Level"}),"\n",(0,i.jsxs)(n.p,{children:["Any ",(0,i.jsx)(n.code,{children:"casper-node"})," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."]}),"\n",(0,i.jsx)(n.h3,{id:"reciprocity-retries-and-data-direction",children:"Reciprocity, retries and data direction"}),"\n",(0,i.jsxs)(n.p,{children:["A connection that was initiated by a node is considered an ",(0,i.jsx)(n.em,{children:"outgoing"})," connection by the node itself, but an ",(0,i.jsx)(n.em,{children:"incoming"})," connection by all other peers."]}),"\n",(0,i.jsx)(n.p,{children:"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."}),"\n",(0,i.jsx)(n.p,{children:"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."}),"\n",(0,i.jsx)(n.p,{children:"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."}),"\n",(0,i.jsx)(n.p,{children:"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."}),"\n",(0,i.jsx)(n.h3,{id:"tls-parameters",children:"TLS parameters"}),"\n",(0,i.jsx)(n.p,{children:"Any node creating a connection to a node MUST present a client certificate with the following properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Signature algorithm: ",(0,i.jsx)(n.code,{children:"ECDSA_WITH_SHA512"})]}),"\n",(0,i.jsx)(n.li,{children:"Subject name: Same as issuer name (self-signed certificate!)"}),"\n",(0,i.jsx)(n.li,{children:"Serial number: 1"}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not before"): Must be earlier than current time.'}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not after"): Must be later than current time.'}),"\n",(0,i.jsxs)(n.li,{children:["Signature: Must be using ",(0,i.jsx)(n.code,{children:"SECP521R1"})," with ",(0,i.jsx)(n.code,{children:"SHA512"})," and valid."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The SHA512 fingerprint of the ",(0,i.jsx)(n.em,{children:"public key"})," is considered the ",(0,i.jsx)(n.strong,{children:"NodeID"})," of the node."]}),"\n",(0,i.jsx)(n.p,{children:"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."}),"\n",(0,i.jsx)(n.p,{children:"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."}),"\n",(0,i.jsx)(n.h3,{id:"discovery",children:"Discovery"}),"\n",(0,i.jsx)(n.p,{children:"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."}),"\n",(0,i.jsxs)(n.p,{children:["Every node SHOULD have one or more so-called ",(0,i.jsx)(n.em,{children:"known node addresses"})," of other nodes configured."]}),"\n",(0,i.jsx)(n.p,{children:"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."}),"\n",(0,i.jsx)(n.p,{children:"Every node MUST periodically gossip its own node address to the network (see gossiping below)."}),"\n",(0,i.jsxs)(n.p,{children:["A node ",(0,i.jsx)(n.em,{children:"learns"})," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."]}),"\n",(0,i.jsx)(n.p,{children:"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."}),"\n",(0,i.jsxs)(n.p,{children:["After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,i.jsx)(n.em,{children:"forgetting"})," a node. An address that has been forgotten will be considered new the next time it is learned."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT forget the known addresses it was configured with initially."}),"\n",(0,i.jsx)(n.h2,{id:"framing",children:"Framing"}),"\n",(0,i.jsx)(n.p,{children:"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."}),"\n",(0,i.jsx)(n.p,{children:"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."}),"\n",(0,i.jsx)(n.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsxs)(n.p,{children:["The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,i.jsx)(n.a,{href:"https://msgpack.org",children:"MessagePack"}),", while regular messages are encoded using ",(0,i.jsx)(n.a,{href:"https://docs.rs/bincode",children:"bincode"}),". Many (but not all) data objects use ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html",children:(0,i.jsx)(n.code,{children:"bytesrepr"})})," for serialization."]}),"\n",(0,i.jsxs)(n.p,{children:["The node uses the ",(0,i.jsx)(n.a,{href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html",children:(0,i.jsx)(n.code,{children:"rmp-serde"})})," crate, version ",(0,i.jsx)(n.code,{children:"0.14.4"}),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."]}),"\n",(0,i.jsxs)(n.p,{children:["All nodes MUST use the following settings for ",(0,i.jsx)(n.code,{children:"bincode"})," encoding of network messages:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Varint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Not allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Any other use of ",(0,i.jsx)(n.code,{children:"bincode"})," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,i.jsx)(n.code,{children:"bincode"})," encoding settings:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Fixint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,i.jsx)(n.a,{href:"https://serde.rs",children:(0,i.jsx)(n.code,{children:"serde"})}),"-derived encoding. For ",(0,i.jsx)(n.code,{children:"bytesrepr"})," serialization refer to the specific implementations in the ",(0,i.jsx)(n.code,{children:"bytesrepr"})," crate."]}),"\n",(0,i.jsxs)(n.p,{children:["Any data types given from here on out are described using simplified ",(0,i.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," structure definitions."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-message-type",children:["The ",(0,i.jsx)(n.code,{children:"Message"})," Type"]}),"\n",(0,i.jsx)(n.p,{children:"The following data types make up the networking protocol:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option<ConsensusCertificate>,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option<Digest>,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/string/struct.String.html",children:(0,i.jsx)(n.code,{children:"String"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html",children:(0,i.jsx)(n.code,{children:"SocketAddr"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html",children:(0,i.jsx)(n.code,{children:"ProtocolVersion"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/option/enum.Option.html",children:(0,i.jsx)(n.code,{children:"Option"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html",children:(0,i.jsx)(n.code,{children:"Signature"})})," see the respective docs and details below."]}),"\n",(0,i.jsx)(n.h2,{id:"handshake-behavior",children:"Handshake Behavior"}),"\n",(0,i.jsx)(n.p,{children:"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."}),"\n",(0,i.jsxs)(n.p,{children:["A handshake MUST be encoded using the ",(0,i.jsx)(n.code,{children:"Message::Handshake"})," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,i.jsx)(n.code,{children:"protocol_version"}),", ",(0,i.jsx)(n.code,{children:"consensus_certificate"}),", ",(0,i.jsx)(n.code,{children:"is_syncing"}),", ",(0,i.jsx)(n.code,{children:"chainspec_hash"}),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."]}),"\n",(0,i.jsxs)(n.p,{children:["After receiving a handshake, a node MUST compare the ",(0,i.jsx)(n.code,{children:"network_name"}),", ",(0,i.jsx)(n.code,{children:"protocol_version"})," and ",(0,i.jsx)(n.code,{children:"chainspec_hash"})," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,i.jsx)(n.code,{children:"is_syncing"})," set to ",(0,i.jsx)(n.code,{children:"true"}),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.']}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY compare peers that provide a ",(0,i.jsx)(n.code,{children:"consensus_certificate"})," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon handshake completion, the node SHOULD learn the provided ",(0,i.jsx)(n.code,{children:"public_addr"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blocking-nodes",children:"Blocking Nodes"}),"\n",(0,i.jsx)(n.p,{children:"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."}),"\n",(0,i.jsxs)(n.p,{children:["After a block on a node is expired, the node SHOULD ",(0,i.jsx)(n.em,{children:"forget"})," the nodes IP address, allowing a later ",(0,i.jsx)(n.em,{children:"learning"})," of said address again."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-payload-type",children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," Type"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," (found in the node sources as ",(0,i.jsx)(n.code,{children:"Message"})," in ",(0,i.jsx)(n.code,{children:"payload.rs"}),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,i.jsx)(n.code,{children:"bincode"})," encoding, this should have no effect on implementations."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec<u8>,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:"Consensus"}),"\n",(0,i.jsxs)(n.p,{children:["A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the ",(0,i.jsx)(n.code,{children:"consensus::Message"})," type or an appropriate description of the underlying protocol for details."]}),"\n",(0,i.jsx)(n.h3,{id:"gossiping",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."}),"\n",(0,i.jsxs)(n.p,{children:["A node must support a gossiper for deploys and one for ",(0,i.jsx)(n.code,{children:"GossippedAddress"}),", which is an alias for the regular Rust standard library's ",(0,i.jsx)(n.code,{children:"SocketAddr"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,i.jsx)(n.code,{children:"AddressGossiperMessage::Gossip"})," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."]}),"\n",(0,i.jsx)(n.h3,{id:"unsafe-for-syncing",children:"Unsafe-for-syncing"}),"\n",(0,i.jsxs)(n.p,{children:["A node that is syncing MUST indicate this by setting ",(0,i.jsx)(n.code,{children:"is_syncing"})," to ",(0,i.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s that can cause issues with peers that are also sending GetRequests."]}),"\n",(0,i.jsxs)(n.p,{children:["A node that succeeds in a handshake with a peer that has set ",(0,i.jsx)(n.code,{children:"is_syncing"})," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s."]}),"\n",(0,i.jsx)(n.h2,{id:"gossiping-1",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."}),"\n",(0,i.jsx)(n.p,{children:"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."}),"\n",(0,i.jsx)(n.p,{children:"Gossiper messages have the following structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To gossip, a node MAY send a ",(0,i.jsx)(n.code,{children:"GossiperMessage::Gossip"})," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,i.jsx)(n.code,{children:"GossiperMessage:GossipResponse"}),", citing the given id and using ",(0,i.jsx)(n.code,{children:"is_already_held"})," to indicate whether it already possessed the given item."]}),"\n",(0,i.jsx)(n.p,{children:"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."}),"\n",(0,i.jsxs)(n.p,{children:["The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"true"}),") response and MUST NOT send another ",(0,i.jsx)(n.code,{children:"Gossip"})," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."]}),"\n",(0,i.jsxs)(n.p,{children:["If a node receives a negative ",(0,i.jsx)(n.code,{children:"GossiperMessage::GossipResponse"})," (i.e. ",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"false"}),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,i.jsx)(n.code,{children:"GetRequest"})," for the item (see GetRequests section below)."]}),"\n",(0,i.jsx)(n.h2,{id:"getrequests",children:"GetRequests"}),"\n",(0,i.jsx)(n.p,{children:'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'}),"\n",(0,i.jsxs)(n.p,{children:["A peer MAY send a ",(0,i.jsx)(n.code,{children:"GetRequest"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetRequest"}),") with a ",(0,i.jsx)(n.code,{children:"Tag"})," and ",(0,i.jsx)(n.code,{children:"serialized_id"})," payload. Both ",(0,i.jsx)(n.code,{children:"serialized_id"})," and ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST be encoded using ",(0,i.jsx)(n.code,{children:"bincode"}),' (see "Encoding" section for details).']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"The tag dictates which item is being retrieved, and which key (ID type) is being used."}),"\n",(0,i.jsxs)(n.p,{children:["A node that receives a ",(0,i.jsx)(n.code,{children:"GetRequest"})," from a peer SHOULD return a ",(0,i.jsx)(n.code,{children:"GetResponse"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetResponse"}),"). The ",(0,i.jsx)(n.code,{children:"GetResponse"})," MUST use the same ",(0,i.jsx)(n.code,{children:"Tag"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum FetchedOrNotFound<T, Id> {\n Fetched(T),\n NotFound(Id),\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the item was found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a serialized ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::Fetched"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"T"})," being the item."]}),"\n",(0,i.jsxs)(n.p,{children:["If the item was not found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::NotFound"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"Id"})," being the ID found in the originating ",(0,i.jsx)(n.code,{children:"GetRequest"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST not send any items to a peer that it itself has not verified."}),"\n",(0,i.jsxs)(n.p,{children:["The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,i.jsx)(n.code,{children:"DeployHash"})," and ",(0,i.jsx)(n.code,{children:"GossippedAddress"})," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,i.jsx)(n.a,{href:"/concepts/serialization-standard",children:"Serialization Standard"}),", but be aware that those docs describe serializing using bytesrepr rather than bincode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Tag"}),(0,i.jsx)(n.th,{children:"ID type"}),(0,i.jsx)(n.th,{children:"Payload (item) type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Deploy"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Deploy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalizedApprovals"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"FinalizedApprovalsWithId"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Block"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Block"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"GossipedAddress"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndMetadataByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeader"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderAndFinalitySignaturesByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeaderWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TrieOrChunk"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunkId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunk"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndDeploysByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockAndDeploys"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderBatch"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatch"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalitySignaturesByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockSignatures"})})]})]})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet<Approval>,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec<DeployHash>,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec<u8>,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec<NamedArg>);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec<u8>);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box<CLType>),\n List(Box<CLType>),\n ByteArray(u32),\n Result { ok: Box<CLType>, err: Box<CLType> },\n Map { key: Box<CLType>, value: Box<CLType> },\n Tuple1([Box<CLType>; 1]),\n Tuple2([Box<CLType>; 2]),\n Tuple3([Box<CLType>; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet<Approval>);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option<EraEnd>,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap<PublicKey, U512>,\n}\n\nstruct EraReport<VID> {\n equivocators: Vec<PublicKey>,\n rewards: BTreeMap<PublicKey, u64>,\n inactive_validators: Vec<PublicKey>,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec<DeployHash>,\n transfer_hashes: Vec<DeployHash>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Custom variable length encoding is used when serializing ",(0,i.jsx)(n.code,{children:"U512"}),", ",(0,i.jsx)(n.code,{children:"U256"})," and ",(0,i.jsx)(n.code,{children:"U128"})," types. They are encoded in a way equivalent to encoding the following pseudo struct:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"In other words, the following steps are taken:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"convert the bigint to an array of bytes in little-endian form"}),"\n",(0,i.jsxs)(n.li,{children:["strip the contiguous range of irrelevant padding ",(0,i.jsx)(n.code,{children:"0"})," bytes from the right hand end, if any"]}),"\n",(0,i.jsx)(n.li,{children:"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For a description explaining the use of ",(0,i.jsx)(n.code,{children:"TrieOrChunk"}),' and related types, see the "Trie chunking" section. The relevant types are:']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec<Digest>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})," is used to request multiple ",(0,i.jsx)(n.code,{children:"BlockHeader"}),"s with a single request."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap<PublicKey, Signature>,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec<Deploy>,\n}\n\nstruct BlockHeadersBatch(Vec<BlockHeader>);\n"})}),"\n",(0,i.jsx)(n.h2,{id:"finality-signatures",children:"Finality Signatures"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload::FinalitySignature"})," variant is used when broadcasting finality signatures."]}),"\n",(0,i.jsx)(n.p,{children:"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."}),"\n",(0,i.jsx)(n.h2,{id:"trie-chunking",children:"Trie Chunking"}),"\n",(0,i.jsxs)(n.p,{children:["Large trie nodes are split when transferred across the network, according to ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"}),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,i.jsx)(n.code,{children:"TrieOrChunk::Trie"})," instance."]}),"\n",(0,i.jsxs)(n.p,{children:["Should a trie node be larger than this, a Merkle tree is constructed with ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"})," sized chunks and is identified by the root hash of the resulting tree instead."]}),"\n",(0,i.jsxs)(n.p,{children:["Peers MUST only request chunks. The ",(0,i.jsx)(n.code,{children:"TrieOrChunkId"})," type allows for requesting the n-th chunk of a given trie node. See the ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-hashing",children:"casper-hashing"})," crate for details."]}),"\n",(0,i.jsxs)(n.p,{children:["A node receiving a ",(0,i.jsx)(n.code,{children:"TrieOrChunk"})," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(96540);const t={},o=i.createContext(t);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b687a817.353ec7bd.js b/assets/js/b687a817.353ec7bd.js new file mode 100644 index 000000000..b822e7769 --- /dev/null +++ b/assets/js/b687a817.353ec7bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51627],{36044:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const o={},r="Casper Node Networking Protocol",d={id:"concepts/design/networking-protocol",title:"Casper Node Networking Protocol",description:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",source:"@site/versioned_docs/version-1.5.X/concepts/design/networking-protocol.md",sourceDirName:"concepts/design",slug:"/concepts/design/networking-protocol",permalink:"/1.5.X/concepts/design/networking-protocol",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},a={},c=[{value:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)",id:"casper-node-networking-protocol-mainnet-protocol-version-150",level:2},{value:"Connection Level",id:"connection-level",level:2},{value:"Reciprocity, retries and data direction",id:"reciprocity-retries-and-data-direction",level:3},{value:"TLS parameters",id:"tls-parameters",level:3},{value:"Discovery",id:"discovery",level:3},{value:"Framing",id:"framing",level:2},{value:"Encoding",id:"encoding",level:2},{value:"The <code>Message</code> Type",id:"the-message-type",level:2},{value:"Handshake Behavior",id:"handshake-behavior",level:2},{value:"Blocking Nodes",id:"blocking-nodes",level:2},{value:"The <code>Payload</code> Type",id:"the-payload-type",level:2},{value:"Consensus",id:"consensus",level:3},{value:"Gossiping",id:"gossiping",level:3},{value:"Unsafe-for-syncing",id:"unsafe-for-syncing",level:3},{value:"Gossiping",id:"gossiping-1",level:2},{value:"GetRequests",id:"getrequests",level:2},{value:"Finality Signatures",id:"finality-signatures",level:2},{value:"Trie Chunking",id:"trie-chunking",level:2}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"casper-node-networking-protocol",children:"Casper Node Networking Protocol"})}),"\n",(0,i.jsx)(n.h2,{id:"casper-node-networking-protocol-mainnet-protocol-version-150",children:"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of the ",(0,i.jsx)(n.code,{children:"casper-node"}),"'s networking protocol. This document follows the conventions laid out in ",(0,i.jsx)(n.a,{href:"https://datatracker.ietf.org/doc/html/rfc2119",children:"RFC2119"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"connection-level",children:"Connection Level"}),"\n",(0,i.jsxs)(n.p,{children:["Any ",(0,i.jsx)(n.code,{children:"casper-node"})," taking part in the Casper network SHOULD open connections to every other casper-node it is aware of and has not blocked. These connections are established using TLS, presenting a client certificate."]}),"\n",(0,i.jsx)(n.h3,{id:"reciprocity-retries-and-data-direction",children:"Reciprocity, retries and data direction"}),"\n",(0,i.jsxs)(n.p,{children:["A connection that was initiated by a node is considered an ",(0,i.jsx)(n.em,{children:"outgoing"})," connection by the node itself, but an ",(0,i.jsx)(n.em,{children:"incoming"})," connection by all other peers."]}),"\n",(0,i.jsx)(n.p,{children:"A node that created an outgoing connection SHOULD terminate the connection if it does not detect an incoming connection from the connected-to node within a short amount of time."}),"\n",(0,i.jsx)(n.p,{children:"A node that receives an incoming connection MUST eventually establish an outgoing connection to the node."}),"\n",(0,i.jsx)(n.p,{children:"A node SHOULD retry any failed outgoing connection periodically with exponential backoff. A node MUST NOT attempt to reconnect more than once per second."}),"\n",(0,i.jsx)(n.p,{children:"Nodes MUST NOT send data through incoming connections, other than handshakes. Nodes MUST NOT accept any data coming through outgoing connections, other than handshakes."}),"\n",(0,i.jsx)(n.h3,{id:"tls-parameters",children:"TLS parameters"}),"\n",(0,i.jsx)(n.p,{children:"Any node creating a connection to a node MUST present a client certificate with the following properties:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Signature algorithm: ",(0,i.jsx)(n.code,{children:"ECDSA_WITH_SHA512"})]}),"\n",(0,i.jsx)(n.li,{children:"Subject name: Same as issuer name (self-signed certificate!)"}),"\n",(0,i.jsx)(n.li,{children:"Serial number: 1"}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not before"): Must be earlier than current time.'}),"\n",(0,i.jsx)(n.li,{children:'Expiration ("not after"): Must be later than current time.'}),"\n",(0,i.jsxs)(n.li,{children:["Signature: Must be using ",(0,i.jsx)(n.code,{children:"SECP521R1"})," with ",(0,i.jsx)(n.code,{children:"SHA512"})," and valid."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The SHA512 fingerprint of the ",(0,i.jsx)(n.em,{children:"public key"})," is considered the ",(0,i.jsx)(n.strong,{children:"NodeID"})," of the node."]}),"\n",(0,i.jsx)(n.p,{children:"Any node MUST immediately terminate a connection if it does not match the given parameters. The same certificate MUST be used as a server certificate for other clients connecting to this node."}),"\n",(0,i.jsx)(n.p,{children:"An incoming connection with a valid TLS certificate SHOULD be accepted. As all certificates are self-signed, no further checking is done."}),"\n",(0,i.jsx)(n.h3,{id:"discovery",children:"Discovery"}),"\n",(0,i.jsx)(n.p,{children:"A node address is defined as an IPv4 address and a port. A node's address is the publicly reachable IP address and port that it is listening on for node-to-node-communication."}),"\n",(0,i.jsxs)(n.p,{children:["Every node SHOULD have one or more so-called ",(0,i.jsx)(n.em,{children:"known node addresses"})," of other nodes configured."]}),"\n",(0,i.jsx)(n.p,{children:"On start-up, a node SHOULD attempt to connect to all known nodes. A node SHOULD never forget a known node address."}),"\n",(0,i.jsx)(n.p,{children:"Every node MUST periodically gossip its own node address to the network (see gossiping below)."}),"\n",(0,i.jsxs)(n.p,{children:["A node ",(0,i.jsx)(n.em,{children:"learns"})," new node addresses through receiving a gossiped node address, or being told of an address through the handshake."]}),"\n",(0,i.jsx)(n.p,{children:"Upon learning of a previously unknown node address, a node SHOULD attempt to connect to it."}),"\n",(0,i.jsxs)(n.p,{children:["After failing to connect to a node address, a node MAY forget it after a certain amount of retries, this process is called ",(0,i.jsx)(n.em,{children:"forgetting"})," a node. An address that has been forgotten will be considered new the next time it is learned."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT forget the known addresses it was configured with initially."}),"\n",(0,i.jsx)(n.h2,{id:"framing",children:"Framing"}),"\n",(0,i.jsx)(n.p,{children:"To send a message to a peer across an established TLS connection, a node MUST send a message length header consisting of a 32 byte big endian integer with the message length first."}),"\n",(0,i.jsx)(n.p,{children:"A node receiving a message length header that exceeds the maximum message size specified in the chainspec MUST immediately terminate the connection."}),"\n",(0,i.jsx)(n.h2,{id:"encoding",children:"Encoding"}),"\n",(0,i.jsxs)(n.p,{children:["The node uses three encoding schemes: Handshakes (see below) are encoded using ",(0,i.jsx)(n.a,{href:"https://msgpack.org",children:"MessagePack"}),", while regular messages are encoded using ",(0,i.jsx)(n.a,{href:"https://docs.rs/bincode",children:"bincode"}),". Many (but not all) data objects use ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/bytesrepr/index.html",children:(0,i.jsx)(n.code,{children:"bytesrepr"})})," for serialization."]}),"\n",(0,i.jsxs)(n.p,{children:["The node uses the ",(0,i.jsx)(n.a,{href:"https://docs.rs/rmp-serde/0.14.4/rmp_serde/index.html",children:(0,i.jsx)(n.code,{children:"rmp-serde"})})," crate, version ",(0,i.jsx)(n.code,{children:"0.14.4"}),", which is kept fixed to ensure handshake compatibility with protocol version 1.0 of the node."]}),"\n",(0,i.jsxs)(n.p,{children:["All nodes MUST use the following settings for ",(0,i.jsx)(n.code,{children:"bincode"})," encoding of network messages:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Varint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Not allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Any other use of ",(0,i.jsx)(n.code,{children:"bincode"})," encoding (e.g. for GetRequest payloads, see below) MUST use the following ",(0,i.jsx)(n.code,{children:"bincode"})," encoding settings:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"Byte limit: Unlimited"}),"\n",(0,i.jsx)(n.li,{children:"Endianness: Little Endian"}),"\n",(0,i.jsx)(n.li,{children:"Integer Encoding: Fixint"}),"\n",(0,i.jsx)(n.li,{children:"Trailing Bytes: Allowed"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Unless noted otherwise, any structure encoded as MessagePack or bincode is serialized using the standard ",(0,i.jsx)(n.a,{href:"https://serde.rs",children:(0,i.jsx)(n.code,{children:"serde"})}),"-derived encoding. For ",(0,i.jsx)(n.code,{children:"bytesrepr"})," serialization refer to the specific implementations in the ",(0,i.jsx)(n.code,{children:"bytesrepr"})," crate."]}),"\n",(0,i.jsxs)(n.p,{children:["Any data types given from here on out are described using simplified ",(0,i.jsx)(n.a,{href:"https://www.rust-lang.org/",children:"Rust"})," structure definitions."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-message-type",children:["The ",(0,i.jsx)(n.code,{children:"Message"})," Type"]}),"\n",(0,i.jsx)(n.p,{children:"The following data types make up the networking protocol:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Message {\n Handshake {\n network_name: String,\n public_addr: SocketAddr,\n // default: 1.0\n protocol_version: ProtocolVersion,\n // default: `None`\n consensus_certificate: Option<ConsensusCertificate>,\n // default: false\n is_syncing: bool,\n // default: `None`\n chainspec_hash: Option<Digest>,\n },\n Payload(Payload),\n}\n\nstruct ConsensusCertificate {\n public_key: PublicKey,\n signature: Signature,\n}\n\nstruct Digest([u8; 32]);\n"})}),"\n",(0,i.jsxs)(n.p,{children:["For ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/string/struct.String.html",children:(0,i.jsx)(n.code,{children:"String"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/net/enum.SocketAddr.html",children:(0,i.jsx)(n.code,{children:"SocketAddr"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/struct.ProtocolVersion.html",children:(0,i.jsx)(n.code,{children:"ProtocolVersion"})}),", ",(0,i.jsx)(n.a,{href:"https://doc.rust-lang.org/std/option/enum.Option.html",children:(0,i.jsx)(n.code,{children:"Option"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.PublicKey.html",children:(0,i.jsx)(n.code,{children:"PublicKey"})}),", ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/crypto/enum.Signature.html",children:(0,i.jsx)(n.code,{children:"Signature"})})," see the respective docs and details below."]}),"\n",(0,i.jsx)(n.h2,{id:"handshake-behavior",children:"Handshake Behavior"}),"\n",(0,i.jsx)(n.p,{children:"A node establishing a new connection MUST immediately send a handshake through said connection to the peer, regardless of whether an incoming or outgoing connection was established (this is an exception to the restriction of only sending data through outgoing connections)."}),"\n",(0,i.jsxs)(n.p,{children:["A handshake MUST be encoded using the ",(0,i.jsx)(n.code,{children:"Message::Handshake"})," structure. A node running version 1.5 SHOULD NOT omit any of the fields for which default values are available (",(0,i.jsx)(n.code,{children:"protocol_version"}),", ",(0,i.jsx)(n.code,{children:"consensus_certificate"}),", ",(0,i.jsx)(n.code,{children:"is_syncing"}),", ",(0,i.jsx)(n.code,{children:"chainspec_hash"}),"). A node MUST accept any handshake that omits one or more of these fields and fill them with defaults."]}),"\n",(0,i.jsxs)(n.p,{children:["After receiving a handshake, a node MUST compare the ",(0,i.jsx)(n.code,{children:"network_name"}),", ",(0,i.jsx)(n.code,{children:"protocol_version"})," and ",(0,i.jsx)(n.code,{children:"chainspec_hash"})," fields against its own configuration: If any of these do not match, it MUST disconnect from the node and SHOULD block it."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MUST mark any peer that connects to it (thus is an incoming connection from the perspective of the node) with a value of ",(0,i.jsx)(n.code,{children:"is_syncing"})," set to ",(0,i.jsx)(n.code,{children:"true"}),' as "syncing" and MUST NOT allow any of its own messages that are marked unsafe-for-syncing to be sent to that node, by silently dropping them instead.']}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY compare peers that provide a ",(0,i.jsx)(n.code,{children:"consensus_certificate"})," to the currently active set of validators and mark it as an active validator to give it preferential treatment when outgoing bandwidth is limited."]}),"\n",(0,i.jsxs)(n.p,{children:["Upon handshake completion, the node SHOULD learn the provided ",(0,i.jsx)(n.code,{children:"public_addr"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"blocking-nodes",children:"Blocking Nodes"}),"\n",(0,i.jsx)(n.p,{children:"If a node blocks a peer, it MUST sever all incoming and outgoing connections to said node. It MUST take note of the NodeId of the node, marking it as blocked and MUST not allow any new connection to proceed past the handshake."}),"\n",(0,i.jsx)(n.p,{children:"A node MUST NOT block peers based on IP address or port. Nodes MUST NOT block peers for more than an hour."}),"\n",(0,i.jsxs)(n.p,{children:["After a block on a node is expired, the node SHOULD ",(0,i.jsx)(n.em,{children:"forget"})," the nodes IP address, allowing a later ",(0,i.jsx)(n.em,{children:"learning"})," of said address again."]}),"\n",(0,i.jsxs)(n.h2,{id:"the-payload-type",children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," Type"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload"})," (found in the node sources as ",(0,i.jsx)(n.code,{children:"Message"})," in ",(0,i.jsx)(n.code,{children:"payload.rs"}),") contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in ",(0,i.jsx)(n.code,{children:"bincode"})," encoding, this should have no effect on implementations."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum Payload {\n Consensus(ConsensusMessage),\n DeployGossiper(DeployGossiperMessage),\n AddressGossiper(AddressGossiperMessage),\n GetRequest {\n tag: Tag,\n serialized_id: Vec<u8>,\n },\n GetResponse {\n tag: Tag,\n serialized_item: Vec<[u8]>,\n },\n FinalitySignature(FinalitySignature),\n}\n\nenum DeployGossiperMessage {\n Gossip(DeployHash),\n GossipResponse {\n item_id: DeployHash,\n is_already_held: bool,\n },\n}\n\nenum AddressGossiperMessage {\n Gossip(GossippedAddress),\n GossipResponse {\n item_id: GossippedAddress,\n is_already_held: bool,\n },\n}\n\nstruct DeployHash(Digest);\nstruct GossipedAddress(SocketAddr);\n"})}),"\n",(0,i.jsx)(n.h3,{id:"consensus",children:"Consensus"}),"\n",(0,i.jsxs)(n.p,{children:["A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the ",(0,i.jsx)(n.code,{children:"consensus::Message"})," type or an appropriate description of the underlying protocol for details."]}),"\n",(0,i.jsx)(n.h3,{id:"gossiping",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address."}),"\n",(0,i.jsxs)(n.p,{children:["A node must support a gossiper for deploys and one for ",(0,i.jsx)(n.code,{children:"GossippedAddress"}),", which is an alias for the regular Rust standard library's ",(0,i.jsx)(n.code,{children:"SocketAddr"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node SHOULD begin a gossiping process for all deploys previously unknown to it. A node MUST periodically send an ",(0,i.jsx)(n.code,{children:"AddressGossiperMessage::Gossip"})," message to a random subset selected in a similar manner as the one for deploy gossip to make its own address known, see the gossiping process section below for details."]}),"\n",(0,i.jsx)(n.h3,{id:"unsafe-for-syncing",children:"Unsafe-for-syncing"}),"\n",(0,i.jsxs)(n.p,{children:["A node that is syncing MUST indicate this by setting ",(0,i.jsx)(n.code,{children:"is_syncing"})," to ",(0,i.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["A node MAY implement a scheme for request throttling/backpressure for GetRequests (see below) of ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s that can cause issues with peers that are also sending GetRequests."]}),"\n",(0,i.jsxs)(n.p,{children:["A node that succeeds in a handshake with a peer that has set ",(0,i.jsx)(n.code,{children:"is_syncing"})," MUST make note of this flag. If the node itself is implementing the feature described above, it MUST NOT make any GetRequests directed at this peer for ",(0,i.jsx)(n.code,{children:"TrieNode"}),"s."]}),"\n",(0,i.jsx)(n.h2,{id:"gossiping-1",children:"Gossiping"}),"\n",(0,i.jsx)(n.p,{children:"Gossiping is distributing items across the network by sending it to a subset of known peers that do not have the item already, and having them repeat this process until a certain degree of saturation is observed."}),"\n",(0,i.jsx)(n.p,{children:"Any item has an associated ID type which denotes what is used to uniquely identify it when gossiping. If an item is small enough, the ID may just be the item itself."}),"\n",(0,i.jsx)(n.p,{children:"Gossiper messages have the following structure:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"enum GossiperMessage {\n Gossip(Id),\n GossipResponse {\n item_id: Id,\n is_already_held: bool,\n },\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["To gossip, a node MAY send a ",(0,i.jsx)(n.code,{children:"GossiperMessage::Gossip"})," message to a random subset of configurable size of peers to announce that it has received and validated a new item. Any peer receiving such a message SHOULD answer with a ",(0,i.jsx)(n.code,{children:"GossiperMessage:GossipResponse"}),", citing the given id and using ",(0,i.jsx)(n.code,{children:"is_already_held"})," to indicate whether it already possessed the given item."]}),"\n",(0,i.jsx)(n.p,{children:"The node SHOULD attempt to continue to find peers with a negative response, up to a configurable limit of attempts and/or success rate, or until running out of valid peers."}),"\n",(0,i.jsxs)(n.p,{children:["The node that initiated the gossip MUST keep track of which peer replied with a positive (",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"true"}),") response and MUST NOT send another ",(0,i.jsx)(n.code,{children:"Gossip"})," message for same ID to any of these peers during this gossip process. However, it MAY restart gossiping the same item at a later time, considering these peers again."]}),"\n",(0,i.jsxs)(n.p,{children:["If a node receives a negative ",(0,i.jsx)(n.code,{children:"GossiperMessage::GossipResponse"})," (i.e. ",(0,i.jsx)(n.code,{children:"is_already_held"})," being ",(0,i.jsx)(n.code,{children:"false"}),"), and the item's ID is not the item itself, it MUST handle that repsponse as if the peer had sent a ",(0,i.jsx)(n.code,{children:"GetRequest"})," for the item (see GetRequests section below)."]}),"\n",(0,i.jsx)(n.h2,{id:"getrequests",children:"GetRequests"}),"\n",(0,i.jsx)(n.p,{children:'The "GetRequests" mechanism allows retrieving various items through primary or derived keys from peers.'}),"\n",(0,i.jsxs)(n.p,{children:["A peer MAY send a ",(0,i.jsx)(n.code,{children:"GetRequest"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetRequest"}),") with a ",(0,i.jsx)(n.code,{children:"Tag"})," and ",(0,i.jsx)(n.code,{children:"serialized_id"})," payload. Both ",(0,i.jsx)(n.code,{children:"serialized_id"})," and ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST be encoded using ",(0,i.jsx)(n.code,{children:"bincode"}),' (see "Encoding" section for details).']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum Tag {\n Deploy,\n FinalizedApprovals,\n Block,\n GossipedAddress,\n BlockAndMetadataByHeight,\n BlockHeaderByHash,\n BlockHeaderAndFinalitySignaturesByHeight,\n TrieOrChunk,\n BlockAndDeploysByHash,\n BlockHeaderBatch,\n FinalitySignaturesByHash,\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"The tag dictates which item is being retrieved, and which key (ID type) is being used."}),"\n",(0,i.jsxs)(n.p,{children:["A node that receives a ",(0,i.jsx)(n.code,{children:"GetRequest"})," from a peer SHOULD return a ",(0,i.jsx)(n.code,{children:"GetResponse"})," (see ",(0,i.jsx)(n.code,{children:"Payload::GetResponse"}),"). The ",(0,i.jsx)(n.code,{children:"GetResponse"})," MUST use the same ",(0,i.jsx)(n.code,{children:"Tag"}),"."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub enum FetchedOrNotFound<T, Id> {\n Fetched(T),\n NotFound(Id),\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["If the item was found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a serialized ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::Fetched"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"T"})," being the item."]}),"\n",(0,i.jsxs)(n.p,{children:["If the item was not found, ",(0,i.jsx)(n.code,{children:"serialized_item"})," MUST contain a ",(0,i.jsx)(n.code,{children:"FetchedOrNotFound::NotFound"})," instance, with the inner value ",(0,i.jsx)(n.code,{children:"Id"})," being the ID found in the originating ",(0,i.jsx)(n.code,{children:"GetRequest"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"A node MUST not send any items to a peer that it itself has not verified."}),"\n",(0,i.jsxs)(n.p,{children:["The following table shows which tag corresponds to which ID and item type. Type definitions for ",(0,i.jsx)(n.code,{children:"DeployHash"})," and ",(0,i.jsx)(n.code,{children:"GossippedAddress"})," can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the ",(0,i.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization Standard"}),", but be aware that those docs describe serializing using bytesrepr rather than bincode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Tag"}),(0,i.jsx)(n.th,{children:"ID type"}),(0,i.jsx)(n.th,{children:"Payload (item) type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Deploy"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Deploy"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalizedApprovals"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"DeployHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"FinalizedApprovalsWithId"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Block"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"Block"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"GossipedAddress"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"GossipedAddress"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndMetadataByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeader"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderAndFinalitySignaturesByHeight"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"u64"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeaderWithMetadata"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TrieOrChunk"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunkId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"TrieOrChunk"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockAndDeploysByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockAndDeploys"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"BlockHeaderBatch"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHeadersBatch"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"FinalitySignaturesByHash"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockHash"})}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"BlockSignatures"})})]})]})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"pub struct Deploy {\n hash: DeployHash,\n header: DeployHeader,\n payment: ExecutableDeployItem,\n session: ExecutableDeployItem,\n approvals: BTreeSet<Approval>,\n}\n\nstruct DeployHeader {\n account: PublicKey,\n timestamp: u64,\n ttl: u64,\n gas_price: u64,\n body_hash: Digest,\n dependencies: Vec<DeployHash>,\n chain_name: String,\n}\n\nenum PublicKey {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nenum ExecutableDeployItem {\n ModuleBytes {\n module_bytes: Vec<u8>,\n args: RuntimeArgs,\n },\n StoredContractByHash {\n hash: [u8; 32],\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredContractByName {\n name: String,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByHash {\n hash: [u8; 32],\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n StoredVersionedContractByName {\n name: String,\n version: Option<u32>,\n entry_point: String,\n args: RuntimeArgs,\n },\n Transfer { args: RuntimeArgs },\n}\n\nstruct RuntimeArgs(Vec<NamedArg>);\n\nstruct NamedArg(String, CLValue);\n\nstruct CLValue(CLType, Vec<u8>);\n\nenum CLType {\n Bool,\n I32,\n I64,\n U8,\n U32,\n U64,\n U128,\n U256,\n U512,\n Unit,\n String,\n Key,\n URef,\n PublicKey,\n Option(Box<CLType>),\n List(Box<CLType>),\n ByteArray(u32),\n Result { ok: Box<CLType>, err: Box<CLType> },\n Map { key: Box<CLType>, value: Box<CLType> },\n Tuple1([Box<CLType>; 1]),\n Tuple2([Box<CLType>; 2]),\n Tuple3([Box<CLType>; 3]),\n Any,\n}\n\nstruct Approval {\n signer: PublicKey,\n signature: Signature,\n}\n\nenum Signature {\n System,\n Ed25519(Vec<u8>),\n Secp256k1(Vec<u8>),\n}\n\nstruct FinalizedApprovalsWithId {\n id: DeployHash,\n approvals: FinalizedApprovals,\n}\n\nstruct FinalizedApprovals(BTreeSet<Approval>);\n\nstruct Block {\n hash: BlockHash,\n header: BlockHeader,\n body: BlockBody,\n}\n\nstruct BlockHash(Digest);\n\nstruct BlockHeader {\n parent_hash: BlockHash,\n state_root_hash: Digest,\n body_hash: Digest,\n random_bit: bool,\n accumulated_seed: Digest,\n era_end: Option<EraEnd>,\n timestamp: u64,\n era_id: u64,\n height: u64,\n protocol_version: ProtocolVersion,\n}\n\nstruct EraEnd {\n era_report: EraReport,\n next_era_validator_weights: BTreeMap<PublicKey, U512>,\n}\n\nstruct EraReport<VID> {\n equivocators: Vec<PublicKey>,\n rewards: BTreeMap<PublicKey, u64>,\n inactive_validators: Vec<PublicKey>,\n}\n\nstruct ProtocolVersion {\n major: u32,\n minor: u32,\n patch: u32,\n}\n\nstruct BlockBody {\n proposer: PublicKey,\n deploy_hashes: Vec<DeployHash>,\n transfer_hashes: Vec<DeployHash>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Custom variable length encoding is used when serializing ",(0,i.jsx)(n.code,{children:"U512"}),", ",(0,i.jsx)(n.code,{children:"U256"})," and ",(0,i.jsx)(n.code,{children:"U128"})," types. They are encoded in a way equivalent to encoding the following pseudo struct:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct Bigint {\n serialized_length: u8,\n little_endian_unpadded_bytes: [u8, serialized_length - 1],\n}\n"})}),"\n",(0,i.jsx)(n.p,{children:"In other words, the following steps are taken:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:"convert the bigint to an array of bytes in little-endian form"}),"\n",(0,i.jsxs)(n.li,{children:["strip the contiguous range of irrelevant padding ",(0,i.jsx)(n.code,{children:"0"})," bytes from the right hand end, if any"]}),"\n",(0,i.jsx)(n.li,{children:"prefix this remaining array with a byte holding the number of remaining bytes + 1, to indicate the length of the final byte array including the length byte itself"}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["For a description explaining the use of ",(0,i.jsx)(n.code,{children:"TrieOrChunk"}),' and related types, see the "Trie chunking" section. The relevant types are:']}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct TrieOrChunkId(u64, Digest);\n\nenum TrieOrChunk {\n Trie(Bytes),\n ChunkWithProof(ChunkWithProof),\n}\n\nstruct ChunkWithProof {\n proof: IndexedMerkleProof,\n chunk: Bytes,\n}\n\nstruct IndexedMerkleProof {\n index: u64,\n count: u64,\n merkle_proof: Vec<Digest>,\n}\n"})}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"BlockHeadersBatchId"})," is used to request multiple ",(0,i.jsx)(n.code,{children:"BlockHeader"}),"s with a single request."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-rust",children:"struct BlockHeadersBatchId {\n highest: u64,\n lowest: u64,\n}\n\nstruct BlockWithMetadata {\n block: Block,\n finality_signatures: BlockSignatures,\n}\n\nstruct BlockHeaderWithMetadata {\n block_header: BlockHeader,\n block_signatures: BlockSignatures,\n}\n\nstruct BlockSignatures {\n block_hash: BlockHash,\n era_id: u64,\n proofs: BTreeMap<PublicKey, Signature>,\n}\n\nstruct BlockAndDeploys {\n block: Block,\n deploys: Vec<Deploy>,\n}\n\nstruct BlockHeadersBatch(Vec<BlockHeader>);\n"})}),"\n",(0,i.jsx)(n.h2,{id:"finality-signatures",children:"Finality Signatures"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Payload::FinalitySignature"})," variant is used when broadcasting finality signatures."]}),"\n",(0,i.jsx)(n.p,{children:"A node that is an active validator MUST create and broadcast, i.e. send to all connected peers, a finality signature for every valid block it receives or creates."}),"\n",(0,i.jsx)(n.h2,{id:"trie-chunking",children:"Trie Chunking"}),"\n",(0,i.jsxs)(n.p,{children:["Large trie nodes are split when transferred across the network, according to ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"}),", which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a ",(0,i.jsx)(n.code,{children:"TrieOrChunk::Trie"})," instance."]}),"\n",(0,i.jsxs)(n.p,{children:["Should a trie node be larger than this, a Merkle tree is constructed with ",(0,i.jsx)(n.code,{children:"CHUNK_SIZE_BYTES"})," sized chunks and is identified by the root hash of the resulting tree instead."]}),"\n",(0,i.jsxs)(n.p,{children:["Peers MUST only request chunks. The ",(0,i.jsx)(n.code,{children:"TrieOrChunkId"})," type allows for requesting the n-th chunk of a given trie node. See the ",(0,i.jsx)(n.a,{href:"https://docs.rs/casper-hashing",children:"casper-hashing"})," crate for details."]}),"\n",(0,i.jsxs)(n.p,{children:["A node receiving a ",(0,i.jsx)(n.code,{children:"TrieOrChunk"})," item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>d});var i=s(96540);const t={},o=i.createContext(t);function r(e){const n=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),i.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b70225e0.6b9ec728.js b/assets/js/b70225e0.6b9ec728.js new file mode 100644 index 000000000..088c78deb --- /dev/null +++ b/assets/js/b70225e0.6b9ec728.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80372],{21013:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=n(74848),r=n(28453);const o={title:"Node Events"},a="The Node's Event Stream",i={id:"operators/setup/node-events",title:"Node Events",description:"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.",source:"@site/versioned_docs/version-2.0.0/operators/setup/node-events.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-events",permalink:"/2.0.0/operators/setup/node-events",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Node Events"},sidebar:"operators",previous:{title:"Non-Root Users",permalink:"/2.0.0/operators/setup/non-root-user"},next:{title:"Sidecar Setup",permalink:"/2.0.0/operators/setup/casper-sidecar"}},d={},c=[{value:"Monitoring a Node's Event Stream",id:"monitoring-a-nodes-event-stream",level:2},{value:"Replaying the Event Stream",id:"replaying-the-event-stream",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"the-nodes-event-stream",children:"The Node's Event Stream"})}),"\n",(0,s.jsxs)(t.p,{children:["Each Casper node streams events through the SSE (Server Sent Event) server via an ",(0,s.jsx)(t.code,{children:"/events"})," endpoint and the port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),". This port is by default ",(0,s.jsx)(t.code,{children:"9999"})," for nodes on ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet"})," and ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"Mainnet"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"monitoring-a-nodes-event-stream",children:"Monitoring a Node's Event Stream"}),"\n",(0,s.jsx)(t.p,{children:"As an operator, you can use cURL to monitor the event stream on a node."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -s http://HOST:PORT/events/\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"HOST"})," - The IP address of a node on the network."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"PORT"})," - The port specified as the ",(0,s.jsx)(t.code,{children:"event_stream_server.address"})," in the node's ",(0,s.jsx)(t.em,{children:"config.toml"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Another helpful tool is the ",(0,s.jsx)(t.a,{href:"/2.0.0/operators/setup/casper-sidecar",children:"Casper Sidecar"}),", which provides the recommended way to monitor events on a node. Visit the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md#the-sidecar-event-stream",children:"Casper Sidecar Usage Guide"})," for a detailed list of events and REST queries you can use to monitor the node and the state of the network."]}),"\n",(0,s.jsx)(t.h2,{id:"replaying-the-event-stream",children:"Replaying the Event Stream"}),"\n",(0,s.jsxs)(t.p,{children:["This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the ",(0,s.jsx)(t.code,{children:"HOST"}),", ",(0,s.jsx)(t.code,{children:"PORT"}),", and ",(0,s.jsx)(t.code,{children:"ID"})," fields with the needed values."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://HOST:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Example:"})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:9999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(t.admonition,{type:"note",children:[(0,s.jsxs)(t.p,{children:["The node stores only a limited number of events in its cache, which can be configured using the ",(0,s.jsx)(t.code,{children:"event_stream_buffer_length"})," in the ",(0,s.jsx)(t.em,{children:"config.toml"}),". The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected."]}),(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/2.0.0/operators/setup/casper-sidecar",children:"Casper Sidecar"})," may store additional events depending on how it was configured."]})]})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const r={},o=s.createContext(r);function a(e){const t=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b70624a2.df42b3c0.js b/assets/js/b70624a2.df42b3c0.js new file mode 100644 index 000000000..78b03c0e9 --- /dev/null +++ b/assets/js/b70624a2.df42b3c0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15211],{68066:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>o,metadata:()=>a,toc:()=>r});var s=i(74848),t=i(28453);const o={},d="Network Communication {#communications-head}",a={id:"concepts/design/p2p",title:"Network Communication",description:"communications-head}",source:"@site/versioned_docs/version-2.0.0/concepts/design/p2p.md",sourceDirName:"concepts/design",slug:"/concepts/design/p2p",permalink:"/2.0.0/concepts/design/p2p",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Design",permalink:"/2.0.0/concepts/design/casper-design"},next:{title:"Consensus in a Casper Network",permalink:"/2.0.0/concepts/design/consensus"}},c={},r=[{value:"Identity",id:"identity",level:2},{value:"Inter-node connections",id:"inter-node-connections",level:2},{value:"Network",id:"network",level:2},{value:"Gossiping",id:"communications-gossiping",level:2},{value:"Requesting missing data",id:"requesting-missing-data",level:2},{value:"Validation",id:"validation",level:3},{value:"Node Discovery",id:"node-discovery",level:2}];function l(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"communications-head",children:"Network Communication"})}),"\n",(0,s.jsx)(n.h2,{id:"identity",children:"Identity"}),"\n",(0,s.jsx)(n.p,{children:"Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID."}),"\n",(0,s.jsx)(n.p,{children:"Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint."}),"\n",(0,s.jsx)(n.h2,{id:"inter-node-connections",children:"Inter-node connections"}),"\n",(0,s.jsxs)(n.p,{children:["Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the ",(0,s.jsx)(n.em,{children:"client"})," and the remote node the ",(0,s.jsx)(n.em,{children:"server"})," for this connection."]}),"\n",(0,s.jsx)(n.p,{children:"During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks."}),"\n",(0,s.jsx)(n.p,{children:"Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected."}),"\n",(0,s.jsxs)(n.p,{children:["Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"})," on how the server finds endpoints)."]}),"\n",(0,s.jsx)(n.p,{children:"Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it."}),"\n",(0,s.jsx)(n.h2,{id:"network",children:"Network"}),"\n",(0,s.jsxs)(n.p,{children:["As soon as a node has connected to one node in the network, it partakes in ",(0,s.jsx)(n.a,{href:"#node-discovery",children:"Node Discovery"}),". In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network."]}),"\n",(0,s.jsx)(n.p,{children:"Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below."}),"\n",(0,s.jsx)(n.p,{children:"In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped."}),"\n",(0,s.jsx)(n.h2,{id:"communications-gossiping",children:"Gossiping"}),"\n",(0,s.jsxs)(n.p,{children:["Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see ",(0,s.jsx)(n.a,{href:"#identity",children:"Identity"}),"). Each of these objects is immutable and can be identified by a unique hash."]}),"\n",(0,s.jsx)(n.p,{children:"Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed."}),"\n",(0,s.jsx)(n.p,{children:"The process can be summarized as follows:"}),"\n",(0,s.jsxs)(n.p,{children:["Given a message ",(0,s.jsx)(n.em,{children:"M"})," to gossip, the desired saturation ",(0,s.jsx)(n.em,{children:"S"}),", and an infection limit ",(0,s.jsx)(n.em,{children:"L"}),":"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Pick a subset ",(0,s.jsx)(n.em,{children:"T"})," of ",(0,s.jsx)(n.em,{children:"K"})," nodes from all currently connected nodes."]}),"\n",(0,s.jsxs)(n.li,{children:["Send ",(0,s.jsx)(n.em,{children:"M"})," to each node in ",(0,s.jsx)(n.em,{children:"T"}),", noting which nodes were already infected (a node is considered infected if it already had received or known ",(0,s.jsx)(n.em,{children:"M"}),")."]}),"\n",(0,s.jsxs)(n.li,{children:["For every node shown as already infected, add another random node outside to ",(0,s.jsx)(n.em,{children:"T"})," and send it ",(0,s.jsx)(n.em,{children:"M"}),", again noting the response."]}),"\n",(0,s.jsxs)(n.li,{children:["End when we confirm infection of ",(0,s.jsx)(n.em,{children:"L"})," new nodes or encountered ",(0,s.jsx)(n.em,{children:"S"})," already infected nodes."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Through this process, a message will spread to almost all nodes over time."}),"\n",(0,s.jsx)(n.h2,{id:"requesting-missing-data",children:"Requesting missing data"}),"\n",(0,s.jsx)(n.p,{children:"While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block."}),"\n",(0,s.jsx)(n.h3,{id:"validation",children:"Validation"}),"\n",(0,s.jsx)(n.p,{children:"Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node."}),"\n",(0,s.jsx)(n.p,{children:"Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved."}),"\n",(0,s.jsx)(n.p,{children:"Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so."}),"\n",(0,s.jsx)(n.h2,{id:"node-discovery",children:"Node Discovery"}),"\n",(0,s.jsx)(n.p,{children:"Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful."})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>a});var s=i(96540);const t={},o=s.createContext(t);function d(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b71ecf14.1d11eac0.js b/assets/js/b71ecf14.1d11eac0.js new file mode 100644 index 000000000..077cc247c --- /dev/null +++ b/assets/js/b71ecf14.1d11eac0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46736],{70255:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>l,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var n=t(74848),r=t(28453);const s={title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},a="Setting Up a Local Casper Condor Network for Development",i={permalink:"/blog/condor-local-setup",source:"@site/blog/2024-07-16-setting-up-condor-local.md",title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",date:"2024-07-16T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!1,label:"Set-up",permalink:"/blog/tags/setup",description:"Getting set up on Casper"}],readingTime:4.08,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"}],frontMatter:{title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},l={authorsImageUrls:[void 0]},c=[];function p(e){const o={p:"p",...(0,r.R)(),...e.components};return(0,n.jsx)(o.p,{children:"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client."})}function u(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>a,x:()=>i});var n=t(96540);const r={},s=n.createContext(r);function a(e){const o=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function i(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b71ecf14.1f26aa20.js b/assets/js/b71ecf14.1f26aa20.js deleted file mode 100644 index 7a2351ca7..000000000 --- a/assets/js/b71ecf14.1f26aa20.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6736],{70255:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>i,contentTitle:()=>a,default:()=>u,frontMatter:()=>s,metadata:()=>l,toc:()=>c});var n=t(74848),r=t(28453);const s={title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},a="Setting Up a Local Casper Condor Network for Development",l={permalink:"/blog/condor-local-setup",source:"@site/blog/2024-07-16-setting-up-condor-local.md",title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",date:"2024-07-16T18:00:00.000Z",tags:[{inline:!1,label:"Condor",permalink:"/blog/tags/condor",description:"Blog posts related to the Condor upgrade"},{inline:!0,label:"setup",permalink:"/blog/tags/setup"}],readingTime:4.08,hasTruncateMarker:!0,authors:[{name:"Stanislaw Czembor",page:{permalink:"/blog/authors/sczembor"},title:"Developer Advocate for Casper Association",url:"https://github.com/sczembor",permalink:"/sczembor",imageURL:"https://github.com/sczembor.png",key:"sczembor"}],frontMatter:{title:"Setting Up a Local Casper Condor Network for Development",description:"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.",slug:"condor-local-setup",date:"2024-07-16T18:00",authors:["sczembor"],tags:["condor","setup"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"Fee Elimination in Condor",permalink:"/blog/condor-fee-elimination"}},i={authorsImageUrls:[void 0]},c=[];function p(e){const o={p:"p",...(0,r.R)(),...e.components};return(0,n.jsx)(o.p,{children:"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client."})}function u(e={}){const{wrapper:o}={...(0,r.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>a,x:()=>l});var n=t(96540);const r={},s=n.createContext(r);function a(e){const o=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7708f1e.2b3f2d3b.js b/assets/js/b7708f1e.2b3f2d3b.js new file mode 100644 index 000000000..cb560742b --- /dev/null +++ b/assets/js/b7708f1e.2b3f2d3b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96167],{69094:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="SDK Client Library Usage",i={id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/1.5.X/developers/dapps/sdk/client-library-usage",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/1.5.X/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/1.5.X/developers/dapps/sdk/script-sdk"}},l={},o=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sdk-client-library-usage",children:"SDK Client Library Usage"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-sdks",children:"Installing the SDKs"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"npm"})," or ",(0,t.jsx)(n.code,{children:"yarn"})," to install the ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-js-sdk",children:"casper-js-sdk"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn install casper-js-sdk\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:(0,t.jsx)(n.code,{children:"pip"})})," to install the ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pycspr/",children:"pycspr"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install pycspr\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Include the casper-client dependency to your ",(0,t.jsx)(n.code,{children:"Cargo.toml"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ncasper-client="1.5.1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["and add it to your ",(0,t.jsx)(n.code,{children:"main.rs"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"extern crate casper_client;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Use types and methods from casper_client:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n"})}),"\n",(0,t.jsx)(n.p,{children:"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"creating-accounts",children:"Creating Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-account-keys",children:"Creating new account keys"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Create a keypair and write the files to a specified ",(0,t.jsx)(n.code,{children:"PATH"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"exporting-the-public-key-and-account-hash",children:"Exporting the public key and account hash"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"keypair"})," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"accountHashHex"}),' will be prefixed with the text "account-hash-".']}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"uploading-the-secret-key-from-a-file",children:"Uploading the secret key from a file"}),"\n",(0,t.jsx)(n.p,{children:"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.p,{children:"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"transferring-cspr",children:"Transferring CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"keypair"})," created ",(0,t.jsx)(n.a,{href:"#creating-accounts",children:"above"}),", you can sign a deploy that transfers CSPR."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\n\nconst amount = 2.5e9 // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper" // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(\n amount,\n recipientPublicKeyHex\n);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installing-contracts",children:"Installing Contracts"}),"\n",(0,t.jsx)(n.p,{children:"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")\nconst fs = require("fs")\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "argument": CLValueBuilder.string("Hello world!")\n})\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair]\n)\n\nconsole.log(await casperClient.putDeploy(deploy))\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, assuming that you cloned ",(0,t.jsx)(n.code,{children:"casper-node"})," from your project's root directory, ",(0,t.jsx)(n.code,{children:"cd"})," back into it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ../\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now in your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n \n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n \n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts",children:"Calling Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash(\n\t"hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"\n);\nconst runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string("Hello world!")\n})\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair]\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy))\n})();\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"staking-1",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7708f1e.99acd00d.js b/assets/js/b7708f1e.99acd00d.js deleted file mode 100644 index 9919fba79..000000000 --- a/assets/js/b7708f1e.99acd00d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6167],{69094:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>l,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>i,toc:()=>o});var t=a(74848),s=a(28453);const r={},c="SDK Client Library Usage",i={id:"developers/dapps/sdk/client-library-usage",title:"SDK Client Library Usage",description:"Installing the SDKs",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/client-library-usage.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/client-library-usage",permalink:"/developers/dapps/sdk/client-library-usage",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"SDK Client Libraries",permalink:"/sdk"},next:{title:"JavaScript/TypeScript SDK",permalink:"/developers/dapps/sdk/script-sdk"}},l={},o=[{value:"Installing the SDKs",id:"installing-the-sdks",level:2},{value:"Creating Accounts",id:"creating-accounts",level:2},{value:"Creating new account keys",id:"creating-new-account-keys",level:3},{value:"Exporting the public key and account hash",id:"exporting-the-public-key-and-account-hash",level:3},{value:"Uploading the secret key from a file",id:"uploading-the-secret-key-from-a-file",level:3},{value:"Transferring CSPR",id:"transferring-cspr",level:2},{value:"Installing Contracts",id:"installing-contracts",level:2},{value:"Staking",id:"staking",level:2},{value:"Calling Contracts",id:"calling-contracts",level:2},{value:"Staking",id:"staking-1",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",p:"p",pre:"pre",tabitem:"tabitem",tabs:"tabs",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"sdk-client-library-usage",children:"SDK Client Library Usage"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-sdks",children:"Installing the SDKs"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.code,{children:"npm"})," or ",(0,t.jsx)(n.code,{children:"yarn"})," to install the ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-js-sdk",children:"casper-js-sdk"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"npm install casper-js-sdk\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"yarn install casper-js-sdk\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsxs)(n.p,{children:["Use ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pip/",children:(0,t.jsx)(n.code,{children:"pip"})})," to install the ",(0,t.jsx)(n.a,{href:"https://pypi.org/project/pycspr/",children:"pycspr"})," package:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"pip install pycspr\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Include the casper-client dependency to your ",(0,t.jsx)(n.code,{children:"Cargo.toml"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ncasper-client="1.5.1"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["and add it to your ",(0,t.jsx)(n.code,{children:"main.rs"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"extern crate casper_client;\n"})}),"\n",(0,t.jsx)(n.p,{children:"Use types and methods from casper_client:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"use casper_client::transfer;\nuse casper_client::put_deploy;\n//...\n"})}),"\n",(0,t.jsx)(n.p,{children:"as casper_client functions are asynchronous, a tokyo runtime is necessary for testing:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'[dependencies]\ntokio = { version = "^1.27.0", features = ["full"] }\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"creating-accounts",children:"Creating Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["You may use the SDKs to interact with accounts on a Casper network. Accounts can use either an Ed25519 or Secp256k1 digital signature scheme. See the ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})," page for more details."]}),"\n",(0,t.jsx)(n.h3,{id:"creating-new-account-keys",children:"Creating new account keys"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.new();\nconst { publicKey, privateKey } = keypair;\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"from pycspr.crypto import KeyAlgorithm, get_key_pair\nkeypair = get_key_pair(KeyAlgorithm.ED25519)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsxs)(n.p,{children:["Create a keypair and write the files to a specified ",(0,t.jsx)(n.code,{children:"PATH"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper_client::keygen::generate_files("PATH", "ED25519", false).unwrap();\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"exporting-the-public-key-and-account-hash",children:"Exporting the public key and account hash"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"keypair"})," variable contains the private and public key pair for the account. You can use, read, or export the public key. You may also want access to the account hash, often used within smart contracts on a Casper network. The following methods show how to extract the public key and account hash."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:"// Create a hexadecimal representation of the public key and account hash.\nconst publicKeyHex = publicKey.toHex();\nconst accountHashHex = publicKey.toAccountHashStr();\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note that ",(0,t.jsx)(n.code,{children:"accountHashHex"}),' will be prefixed with the text "account-hash-".']}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:"import pycspr.crypto\n\npublicKeyBytes = keypair.account_key\npublicKeyHex = pycspr.crypto.cl_checksum.encode(publicKeyBytes)\naccountHashBytes = pycspr.crypto.cl_operations.get_account_hash(publicKeyBytes)\naccountHashHex = pycspr.crypto.cl_checksum.encode(accountHashBytes)\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"uploading-the-secret-key-from-a-file",children:"Uploading the secret key from a file"}),"\n",(0,t.jsx)(n.p,{children:"To use a specific account, you should not include the private key in the source code; instead, upload the account's secret key from a local file. Update the path to the file in the example below."}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { Keys } = require("casper-js-sdk");\nconst keypair = Keys.Ed25519.loadKeyPairFromPrivateFile("./secret_key.pem");\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"Ed25519"})," with ",(0,t.jsx)(n.code,{children:"Secp256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nkeypair = pycspr.parse_private_key(\n "./secret_key.pem",\n pycspr.crypto.KeyAlgorithm.ED25519\n)\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Replace ",(0,t.jsx)(n.code,{children:"ED25519"})," with ",(0,t.jsx)(n.code,{children:"SECP256K1"})," if you wish."]}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.p,{children:"In Rust, we don't explicitly import the private key as an object, but instead supply its path as an argument when calling functions:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./secret_key.pem",\n timestamp:"",\n ...\n};\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"transferring-cspr",children:"Transferring CSPR"}),"\n",(0,t.jsxs)(n.p,{children:["Using the ",(0,t.jsx)(n.code,{children:"keypair"})," created ",(0,t.jsx)(n.a,{href:"#creating-accounts",children:"above"}),", you can sign a deploy that transfers CSPR."]}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, DeployUtil } = require("casper-js-sdk");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst receipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\n\nconst amount = 2.5e9 // Minimum transfer: 2.5 CSPR\nlet deployParams = new DeployUtil.DeployParams(\n keypair.publicKey,\n "casper" // or "casper-test" for Testnet\n);\n\nconst session = DeployUtil.ExecutableDeployItem.newTransferWithOptionalTransferId(\n amount,\n recipientPublicKeyHex\n);\n\nconst payment = DeployUtil.standardPayment(0.1e9); // Gas payment in motes: 0.1 CSPR\nconst deploy = DeployUtil.makeDeploy(deployParams, session, payment);\nconst signedDeploy = DeployUtil.signDeploy(deploy, keypair);\n\nconsole.log(await casperClient.putDeploy(signedDeploy));\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\nrecipientPublicKeyHex = "01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c"\nrecipientPublicKeyBytes = pycspr.crypto.cl_checksum.decode(recipientPublicKeyHex)\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\n\ndeploy = pycspr.create_transfer(\n params = deployParams,\n amount = int(2.5e9), # Minimum transfer: 2.5 CSPR\n target = recipientPublicKeyBytes\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn send_transfer(){\n let maybe_rpc_id: &str = "";\n let node_address: &str = "http://135.181.216.142:7777";\n let verbosity_level: u64 = 1;\n let amount: &str = "2500000000";\n let target_account: &str = recipient;\n let transfer_id: &str = "1";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let recipient: &str = "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca";\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount(amount);\n let result = casper_client::transfer(maybe_rpc_id, node_address, verbosity_level, amount, target_account, transfer_id, deploy_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"installing-contracts",children:"Installing Contracts"}),"\n",(0,t.jsx)(n.p,{children:"To install a contract on the network, you need to sign and send a deploy containing the compiled Wasm."}),"\n",(0,t.jsxs)(n.p,{children:["Replace the ",(0,t.jsx)(n.code,{children:"NODE_ADDRESS"})," and corresponding RPC port with an active node on the network. You can find active online peers for Mainnet on ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," and for Testnet on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"}),". The RPC port is usually ",(0,t.jsx)(n.code,{children:"7777"}),", but it depends on the network's configuration settings."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder } = require("casper-js-sdk")\nconst fs = require("fs")\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("/path/to/contract.wasm").buffer)\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "argument": CLValueBuilder.string("Hello world!")\n})\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "10000000000", // Gas payment (10 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n [keypair]\n)\n\nconsole.log(await casperClient.putDeploy(deploy))\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nfrom pycspr.types import ModuleBytes, CL_String\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\n\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper" # or "casper-test" for Testnet\n)\npayment = pycspr.create_standard_payment(10000000000) # 10 CSPR\nsession = ModuleBytes(\n module_bytes = pycspr.read_wasm("/path/to/contract.wasm"),\n args = {\n "message": CL_String("Hello world!"),\n }\n)\n\ndeploy = pycspr.create_deploy(deployParams, payment, session)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test"\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n // Without session args:\n // let session_args: Vec<&str> = Vec::new();\n // With session args:\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("argument:String=\'hello world\'");\n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./contract.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("10000000000");\n let result = casper_client::put_deploy(maybe_rpc_id, node_address, verbosity_level, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy response: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n send_transfer().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.h2,{id:"staking",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of the Casper Network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, assuming that you cloned ",(0,t.jsx)(n.code,{children:"casper-node"})," from your project's root directory, ",(0,t.jsx)(n.code,{children:"cd"})," back into it:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd ../\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now in your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"rust",label:"Rust",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'extern crate casper_client;\nasync fn put_deploy(){\n let maybe_rpc: &str = "";\n let verbosity: u64 = 1;\n let node_address: &str = "http://135.181.216.142:7777";\n let deploy_params: casper_client::DeployStrParams = casper_client::DeployStrParams{\n secret_key:"./sk_testnet.pem",\n timestamp:"",\n ttl:"50s",\n gas_price:"1000000000",\n chain_name:"casper", // or "casper-test" for testnet\n dependencies: Vec::new(),\n session_account: "01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a"\n\n };\n let mut session_args: Vec<&str> = Vec::new();\n session_args.push("amount:U512=\'500000000000\'");\n \n session_args.push("delegator:public_key=\'01daad67ebbcb725e02a1955a6617512b311435a21ca6d523085aa015d2d1b473a\'");\n session_args.push("validator:public_key=\'validator_public_key\'");\n \n let session_params: casper_client::SessionStrParams = casper_client::SessionStrParams::with_path("./delegate.wasm", session_args, "");\n let payment_params: casper_client::PaymentStrParams = casper_client::PaymentStrParams::with_amount("5000000000");\n let result = casper_client::put_deploy(maybe_rpc, node_address, verbosity, deploy_params, session_params, payment_params).await.unwrap();\n println!("Deploy result: {:?}", result);\n}\n\n#[tokio::main]\nasync fn main(){\n put_deploy().await;\n}\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts",children:"Calling Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Smart contracts on a Casper network are invoked by calling entry points. See below how to use Casper's SDKs to interact with these entry points and update the global state from a dApp:"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc");\nconst contract = new Contracts.Contract(casperClient);\ncontract.setContractHash(\n\t"hash-a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"\n);\nconst runtimeArguments = RuntimeArgs.fromMap({\n "message": CLValueBuilder.string("Hello world!")\n})\nconst deploy = contract.callEntrypoint(\n "update_msg",\n runtimeArguments,\n keypair.publicKey,\n "casper", // or "casper-test" for Testnet\n "1000000000", // 1 CSPR (10^9 Motes)\n [keypair]\n);\n(async () => {\n console.log(await casperClient.putDeploy(deploy))\n})();\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))\ndeployParams = pycspr.create_deploy_parameters(\n account = keypair,\n chain_name = "casper-test"\n)\npayment = pycspr.create_standard_payment(10_000_000_000)\nsession = pycspr.types.StoredContractByHash(\n entry_point = "update_msg",\n hash = bytes.fromhex("a3cac24aec9de1bbdb87083587b14d8aeffba5dfed27686512b7bb5dee60445d"),\n args = {\n "message": pycspr.types.CL_String("Hello world!"),\n }\n)\ndeploy = pycspr.create_deploy(deployParams, payment, session)\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"staking-1",children:"Staking"}),"\n",(0,t.jsx)(n.p,{children:"Token staking is a fundamental aspect of a Casper network, whereby users lock up tokens as collateral in exchange for the ability to participate in the blockchain's consensus mechanism and earn rewards. This delegated Proof-of-Stake consensus mechanism is crucial for the network's effective operation. With the aid of any of the Casper SDKs, you can delegate your tokens to validators and participate in staking on the network."}),"\n",(0,t.jsxs)(n.p,{children:["The delegation functionality is available as a smart contract, which can be found in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository. To delegate tokens, first clone the repository:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node.git\ncd casper-node/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Then compile the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/smart_contracts/contracts/client/delegate/src/main.rs",children:"delegate contract"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make setup-rs\nmake build-contract-rs/delegate\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, navigate back to your project's root directory. In your dApp's backend (or standalone script), load the ",(0,t.jsx)(n.em,{children:"delegate.wasm"}),' file into memory and deploy it with the arguments "amount", "delegator", and "validator" included.']}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-javascript",children:'const { CasperClient, Contracts, RuntimeArgs, CLValueBuilder, CLPublicKey } = require("casper-js-sdk");\nconst fs = require("fs");\n\nconst casperClient = new CasperClient("http://NODE_ADDRESS:7777/rpc")\nconst contract = new Contracts.Contract(casperClient)\n\nconst contractWasm = new Uint8Array(fs.readFileSync("./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm").buffer);\n\nconst runtimeArguments = RuntimeArgs.fromMap({\n "amount": CLValueBuilder.u512(500e9), // Minimum delegation amount: 500 CSPR\n "delegator": keypair.publicKey,\n "validator": CLPublicKey.fromHex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n});\n\nconst deploy = contract.install(\n contractWasm,\n runtimeArguments,\n "5000000000", // Gas payment (5 CSPR)\n keypair.publicKey,\n "casper", // or "casper-test" for testnet\n [keypair]\n);\n\n(async () => {\n console.log(await casperClient.putDeploy(deploy));\n})(); \n'})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-python",children:'import pycspr\n\nvalidator_public_key = pycspr.factory.accounts.create_public_key_from_account_key(\n bytes.fromhex("01e8c84f4fbb58d37991ef373c08043a45c44cd7f499453fa2bd3e141cc0113b3c")\n)\n\ndeploy_params = pycspr.create_deploy_parameters(\n account = keypair, # Only the public key is used, see `create_deploy_parameters`\n chain_name = "casper" # or "casper-test" for testnet\n)\n\ndeploy = pycspr.create_validator_delegation(\n params = deploy_params,\n amount = int(500e9), # Minimum delegation amount: 500 CSPR\n public_key_of_delegator = keypair,\n public_key_of_validator = validator_public_key,\n path_to_wasm = "./casper-node/target/wasm32-unknown-unknown/release/delegate.wasm"\n)\n\ndeploy.approve(keypair)\nclient.send_deploy(deploy)\nprint(deploy.hash.hex())\n'})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Once submitted, the above snippet will print the deploy hash in the console."})]})}function d(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>i});var t=a(96540);const s={},r=t.createContext(s);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7a2b993.47bcf617.js b/assets/js/b7a2b993.47bcf617.js new file mode 100644 index 000000000..6d4cf9f82 --- /dev/null +++ b/assets/js/b7a2b993.47bcf617.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9396],{74200:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Transfer Tokens",slug:"/users/token-transfer"},o="Transferring Tokens",a={id:"users/csprlive/token-transfer",title:"Transfer Tokens",description:"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.",source:"@site/versioned_docs/version-2.0.0/users/csprlive/token-transfer.md",sourceDirName:"users/csprlive",slug:"/users/token-transfer",permalink:"/2.0.0/users/token-transfer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Transfer Tokens",slug:"/users/token-transfer"},sidebar:"users",previous:{title:"Undelegate Tokens",permalink:"/2.0.0/users/undelegate-ui"},next:{title:"Casper on Ledger",permalink:"/2.0.0/users/ledger/"}},l={},c=[{value:"Transferring Tokens",id:"transferring-tokens-1",level:2}];function h(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens",children:"Transferring Tokens"})}),"\n",(0,t.jsxs)(n.p,{children:["You can transfer Casper tokens (CSPR) using any ",(0,t.jsx)(n.a,{href:"/2.0.0/users/block-explorer",children:"block explorer"})," built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens."]}),"\n",(0,t.jsx)(n.h2,{id:"transferring-tokens-1",children:"Transferring Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To transfer tokens, follow these steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Sign in to your account with the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Wallet"})," on the top menu bar and select ",(0,t.jsx)(n.strong,{children:"Transfer CSPR"})," from the drop-down menu."]}),"\n",(0,t.jsx)(n.li,{children:"Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one."}),"\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"Next"})," to proceed."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transfer details",src:s(93354).A+"",width:"1248",height:"1698"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["A confirmation window appears to verify the details entered. Click ",(0,t.jsx)(n.strong,{children:"Confirm and transfer"})," to proceed to the next step."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirm transfer",src:s(87607).A+"",width:"1178",height:"1332"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Review the following important fields:"}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"The Deploy hash, which uniquely identifies your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient public key of the person receiving your transfer"}),"\n",(0,t.jsx)(n.li,{children:"The Recipient account hash used by the system to track the transaction"}),"\n",(0,t.jsx)(n.li,{children:"The Transfer Amount containing the value of the transfer"}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Sign the transaction by selecting the ",(0,t.jsx)(n.strong,{children:"Sign with Casper Wallet"})," button to proceed to the next step."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Sign the transfer",src:s(12843).A+"",width:"1212",height:"1734"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["Once the Casper Wallet opens, ",(0,t.jsx)(n.strong,{children:"check the deploy hash"}),'. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click ',(0,t.jsx)(n.strong,{children:"Sign"})," in the Signature Request window to complete the transaction."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transaction",src:s(3197).A+"",width:"2018",height:"1704"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"You completed the transaction and successfully transferred tokens."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transfer completed window",src:s(29355).A+"",width:"1210",height:"1396"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"View the updated CSPR balance in the account's main purse next."}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},93354:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1.transfer-details-52f3e9784bb7cdea4de42d410d030a7f.png"},87607:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2.confirm-transfer-a8905cf1c517bda6dca65fd328d32359.png"},12843:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3.sign-transfer-c9f0f40bb26b346cfe8cf2f6db848c4e.png"},3197:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4.wallet-window-34d341c968c49554406e732382b5f597.png"},29355:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5.transfer-completed-c913311be299c8d18915f0cbc5b447b0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b7cc26e1.2bfdb498.js b/assets/js/b7cc26e1.2bfdb498.js new file mode 100644 index 000000000..2d79a3aa7 --- /dev/null +++ b/assets/js/b7cc26e1.2bfdb498.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[63530],{69710:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var a=t(74848),r=t(28453);const i={},o="Upgrading and Maintaining Smart Contracts",c={id:"developers/writing-onchain-code/upgrading-contracts",title:"Upgrading and Maintaining Smart Contracts",description:"Our smart contract packaging tools enable you to:",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/upgrading-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/upgrading-contracts",permalink:"/2.0.0/developers/writing-onchain-code/upgrading-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Testing Smart Contracts",permalink:"/2.0.0/developers/writing-onchain-code/testing-contracts"},next:{title:"Calling Contracts",permalink:"/2.0.0/developers/writing-onchain-code/calling-contracts"}},s={},d=[{value:"The Contract Package",id:"the-contract-package",level:2},{value:"Videos and Tutorials",id:"videos-and-tutorials",level:2},{value:"Maintaining a Contract",id:"maintaining-a-contract",level:2}];function l(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",iframe:"iframe",img:"img",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"upgrading-and-maintaining-smart-contracts",children:"Upgrading and Maintaining Smart Contracts"})}),"\n",(0,a.jsx)(n.p,{children:"Our smart contract packaging tools enable you to:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Upgrade your contracts and specify how the state of the contract is managed"}),"\n",(0,a.jsx)(n.li,{children:"Specify whether a contract is upgradable or immutable"}),"\n",(0,a.jsx)(n.li,{children:"Version your contracts and deprecate old versions"}),"\n",(0,a.jsx)(n.li,{children:"Set permissions around who can perform contract upgrades"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"the-contract-package",children:"The Contract Package"}),"\n",(0,a.jsx)(n.p,{children:"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. If you find that you need to use a disabled contract version, you may also re-enable it."}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"Package Representation",src:t(79551).A+"",width:"1170",height:"472"})}),"\n",(0,a.jsx)(n.p,{children:"The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain."}),"\n",(0,a.jsx)(n.h2,{id:"videos-and-tutorials",children:"Videos and Tutorials"}),"\n",(0,a.jsxs)(n.p,{children:["To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the ",(0,a.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})," documentation."]}),"\n",(0,a.jsxs)(n.p,{align:"center",children:["\n",(0,a.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=10",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Or, for a different perspective, consult the ",(0,a.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/upgrade-contract",children:"Smart Contract Upgrade Tutorial"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"maintaining-a-contract",children:"Maintaining a Contract"}),"\n",(0,a.jsx)(n.p,{children:"The contract maintenance process is generally covered through the contract upgrade process."}),"\n",(0,a.jsx)(n.p,{children:"Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance."}),"\n",(0,a.jsx)(n.p,{children:"On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},79551:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/package-representation-5e72ef8539f89dbe682c86c52d9536c8.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var a=t(96540);const r={},i=a.createContext(r);function o(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8c8445c.2da23794.js b/assets/js/b8c8445c.2da23794.js new file mode 100644 index 000000000..77ec8f8c2 --- /dev/null +++ b/assets/js/b8c8445c.2da23794.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84336],{674:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var n=t(74848),r=t(28453);const o={title:"What is Casper?"},i=void 0,a={id:"concepts/about",title:"What is Casper?",description:"What is Casper?",source:"@site/docs/concepts/about.md",sourceDirName:"concepts",slug:"/concepts/about",permalink:"/concepts/about",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"What is Casper?"},sidebar:"concepts",previous:{title:"Overview",permalink:"/concepts/"},next:{title:"Design Overview",permalink:"/design"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How does Casper work?",id:"how-does-casper-work",level:2},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const s={a:"a",em:"em",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,n.jsxs)(s.p,{children:["Casper is a ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,n.jsxs)(s.p,{children:["The network's consensus protocol is called ",(0,n.jsx)(s.a,{href:"/concepts/design/zug",children:"Zug"}),", and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of ",(0,n.jsx)(s.em,{children:"finality"}),", meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: ",(0,n.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's ",(0,n.jsx)(s.a,{href:"/resources/build-on-casper/introduction",children:"core features and strengths"})," enable developers and enterprises to reap the benefits of blockchain technology."]}),"\n",(0,n.jsx)(s.p,{children:"Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises."}),"\n",(0,n.jsx)(s.h2,{id:"how-does-casper-work",children:"How does Casper work?"}),"\n",(0,n.jsx)(s.p,{children:"Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network."}),"\n",(0,n.jsxs)(s.p,{children:["To understand the design further, read ",(0,n.jsx)(s.a,{href:"/concepts/design/casper-design",children:"this article"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,n.jsxs)(s.p,{children:["Read the ",(0,n.jsx)(s.a,{href:"/disclaimer",children:"Legal Disclaimer"}),' regarding this CasperLabs Tech Spec (this "Whitepaper").']})]})}function p(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var n=t(96540);const r={},o=n.createContext(r);function i(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8c8445c.ff0cc91b.js b/assets/js/b8c8445c.ff0cc91b.js deleted file mode 100644 index 016cbdabd..000000000 --- a/assets/js/b8c8445c.ff0cc91b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4336],{674:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var n=t(74848),r=t(28453);const i={title:"What is Casper?",slug:"/"},o=void 0,a={id:"concepts/about",title:"What is Casper?",description:"What is Casper?",source:"@site/docs/concepts/about.md",sourceDirName:"concepts",slug:"/",permalink:"/next/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"What is Casper?",slug:"/"},sidebar:"concepts",previous:{title:"Overview",permalink:"/next/concepts/"},next:{title:"Design Overview",permalink:"/next/design"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How does Casper work?",id:"how-does-casper-work",level:2},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const s={a:"a",em:"em",h2:"h2",p:"p",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,n.jsxs)(s.p,{children:["Casper is a ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,n.jsx)(s.a,{href:"/next/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,n.jsxs)(s.p,{children:["The network's consensus protocol is called ",(0,n.jsx)(s.a,{href:"/next/concepts/design/zug",children:"Zug"}),", and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of ",(0,n.jsx)(s.em,{children:"finality"}),", meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: ",(0,n.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's ",(0,n.jsx)(s.a,{href:"/next/resources/build-on-casper/introduction",children:"core features and strengths"})," enable developers and enterprises to reap the benefits of blockchain technology."]}),"\n",(0,n.jsx)(s.p,{children:"Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises."}),"\n",(0,n.jsx)(s.h2,{id:"how-does-casper-work",children:"How does Casper work?"}),"\n",(0,n.jsx)(s.p,{children:"Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network."}),"\n",(0,n.jsxs)(s.p,{children:["To understand the design further, read ",(0,n.jsx)(s.a,{href:"/next/concepts/design/casper-design",children:"this article"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,n.jsxs)(s.p,{children:["Read the ",(0,n.jsx)(s.a,{href:"/next/disclaimer",children:"Legal Disclaimer"}),' regarding this CasperLabs Tech Spec (this "Whitepaper").']})]})}function h(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>o,x:()=>a});var n=t(96540);const r={},i=n.createContext(r);function o(e){const s=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),n.createElement(i.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8ef17b7.802d36c5.js b/assets/js/b8ef17b7.802d36c5.js new file mode 100644 index 000000000..a29955b3d --- /dev/null +++ b/assets/js/b8ef17b7.802d36c5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57797],{20112:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var a=n(74848),r=n(28453);const s={title:"Reading and Writing Data"},i="Reading and Writing Data to Global State",o={id:"concepts/design/reading-and-writing-to-the-blockchain",title:"Reading and Writing Data",description:"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.",source:"@site/versioned_docs/version-2.0.0/concepts/design/reading-and-writing-to-the-blockchain.md",sourceDirName:"concepts/design",slug:"/concepts/design/reading-and-writing-to-the-blockchain",permalink:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Reading and Writing Data"},sidebar:"concepts",previous:{title:"Rewards Design",permalink:"/2.0.0/concepts/design/rewards"},next:{title:"Overview",permalink:"/2.0.0/economics"}},c={},d=[{value:"Using the Casper JSON-RPC",id:"using-the-casper-json-rpc",level:2},{value:"Using the Casper Rust API",id:"using-the-casper-rust-api",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"reading-and-writing-data-to-global-state",children:"Reading and Writing Data to Global State"})}),"\n",(0,a.jsxs)(t.p,{children:["Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/dictionaries",children:"Dictionaries"})," or ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#namedkey",children:(0,a.jsx)(t.code,{children:"NamedKeys"})}),"."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,a.jsx)(t.code,{children:"NamedKeys"})," to a top-level key type, making them more viable for larger data sets."]})}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-json-rpc",children:"Using the Casper JSON-RPC"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,a.jsx)(t.code,{children:"query_global_state"})})," method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the ",(0,a.jsx)(t.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})," tutorial."]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-rust-api",children:"Using the Casper Rust API"}),"\n",(0,a.jsx)(t.p,{children:"The Casper API includes the following functions for reading and writing to global state:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:"put_key"})," - Stores the given ",(0,a.jsx)(t.code,{children:"Key"})," under the given ",(0,a.jsx)(t.code,{children:"name"})," in the current context's named keys"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:"get_key"})," - Returns the requested ",(0,a.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:"storage::new_uref"})," - Creates a new URef in the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:"storage::write"})," - Writes a given value under a previously created URef"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:"storage::read"})," - Reads the value from a URef in global state"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:"dictionary_put"})," - Writes the given value under the given ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:"dictionary_get"})," - Retrieves the value stored under a ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["For more details, see the ",(0,a.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})," tutorial."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>o});var a=n(96540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b8f04a6b.619e6ba5.js b/assets/js/b8f04a6b.619e6ba5.js new file mode 100644 index 000000000..95293260e --- /dev/null +++ b/assets/js/b8f04a6b.619e6ba5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[14910],{98478:(e,n,d)=>{d.r(n),d.d(n,{assets:()=>t,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=d(74848),s=d(28453);const r={title:"Key Types"},i="Understanding Key Types",c={id:"concepts/key-types",title:"Key Types",description:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.",source:"@site/versioned_docs/version-2.0.0/concepts/key-types.md",sourceDirName:"concepts",slug:"/concepts/key-types",permalink:"/2.0.0/concepts/key-types",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Key Types"},sidebar:"concepts",previous:{title:"Accounts and Keys",permalink:"/2.0.0/concepts/accounts-and-keys"},next:{title:"Transaction Lifecycle",permalink:"/2.0.0/transactions-and-transaction-lifecycle"}},t={},l=[{value:"Key Explanations",id:"key-explanations",level:2},{value:"Account",id:"account",level:3},{value:"Hash",id:"hash",level:3},{value:"URef",id:"uref",level:3},{value:"Transfer",id:"transfer",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"EraInfo",id:"erainfo",level:3},{value:"Balance",id:"balance",level:3},{value:"BalanceHold",id:"balancehold",level:3},{value:"Bid",id:"bid",level:3},{value:"Withdraw",id:"withdraw",level:3},{value:"Dictionary",id:"dictionary",level:3},{value:"SystemContractRegistry",id:"systemcontractregistry",level:3},{value:"EraSummary",id:"erasummary",level:3},{value:"Unbond",id:"unbond",level:3},{value:"ChainspecRegistry",id:"chainspecregistry",level:3},{value:"ChecksumRegistry",id:"checksumregistry",level:3},{value:"BidAddr",id:"bidaddr",level:3},{value:"Package",id:"package",level:3},{value:"AddressableEntity",id:"addressableentity",level:3},{value:"ByteCode",id:"bytecode",level:3},{value:"Message",id:"message",level:3},{value:"NamedKey",id:"namedkey",level:3},{value:"BlockGlobal",id:"blockglobal",level:3},{value:"EntryPoint",id:"entrypoint",level:3}];function h(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"understanding-key-types",children:"Understanding Key Types"})}),"\n",(0,a.jsx)(n.p,{children:"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used."}),"\n",(0,a.jsx)(n.h2,{id:"key-explanations",children:"Key Explanations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key"})," is a wrapper type that may contain one of several possible sets of data."]}),"\n",(0,a.jsx)(n.h3,{id:"account",children:"Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Account"})," contains an AccountHash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Account"}),(0,a.jsx)(n.td,{children:"account-hash-"}),(0,a.jsx)(n.td,{children:"account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"hash",children:"Hash"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Hash"})," contains a byte array with a length of 32, which can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for the implementation of any checks necessary on the receiving side."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Hash"}),(0,a.jsx)(n.td,{children:"hash-"}),(0,a.jsx)(n.td,{children:"hash-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"uref",children:"URef"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::URef"})," contains an URef suffixed by ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/dapps/uref-security",children:"access rights"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::URef"}),(0,a.jsx)(n.td,{children:"uref-"}),(0,a.jsx)(n.td,{children:"uref-0101010101010101010101010101010101010101010101010101010101010101-001"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Transfer"})," should contain the address hash for a transfer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Transfer"}),(0,a.jsx)(n.td,{children:"transfer-"}),(0,a.jsx)(n.td,{children:"transfer-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::DeployInfo"})," retains the address hash of deploy information."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::DeployInfo"}),(0,a.jsx)(n.td,{children:"deploy-"}),(0,a.jsx)(n.td,{children:"deploy-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erainfo",children:"EraInfo"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraInfo"})," is the integer number of the associated era."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraInfo"}),(0,a.jsx)(n.td,{children:"era-"}),(0,a.jsx)(n.td,{children:"era-1"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balance",children:"Balance"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Balance"})," is the balance of a purse."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Balance"}),(0,a.jsx)(n.td,{children:"balance-"}),(0,a.jsx)(n.td,{children:"balance-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"balancehold",children:"BalanceHold"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BalanceHold"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a hold on a purse balance is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::BalanceHold"}),(0,a.jsx)(n.td,{children:"balance-hold-"}),(0,a.jsx)(n.td,{children:"balance-hold-002a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a6400000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"bid",children:"Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Bid"})," is used to keep track of bids for the auction contract. It is not generally used by users."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Bid"}),(0,a.jsx)(n.td,{children:"bid-"}),(0,a.jsx)(n.td,{children:"bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw",children:"Withdraw"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Withdraw"})," is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Withdraw"}),(0,a.jsx)(n.td,{children:"withdraw-"}),(0,a.jsx)(n.td,{children:"withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"dictionary",children:"Dictionary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Dictionary"})," is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Dictionary"}),(0,a.jsx)(n.td,{children:"dictionary-"}),(0,a.jsx)(n.td,{children:"dictionary-0101010101010101010101010101010101010101010101010101010101010101"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::SystemContractRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ContractHashes for system contracts, including ",(0,a.jsx)(n.code,{children:"Mint"}),", ",(0,a.jsx)(n.code,{children:"Auction"}),", ",(0,a.jsx)(n.code,{children:"HandlePayment"})," and ",(0,a.jsx)(n.code,{children:"StandardPayment"}),", is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::SystemContractRegistry"}),(0,a.jsx)(n.td,{children:"system-entity-registry-"}),(0,a.jsx)(n.td,{children:"system-entity-registry-0000000000000000000000000000000000000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"erasummary",children:"EraSummary"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EraSummary"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which we store current era info."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::EraSummary"}),(0,a.jsx)(n.td,{children:"era-summary-"}),(0,a.jsx)(n.td,{children:"era-summary-00000000000000000000000000000000"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"unbond",children:"Unbond"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Unbond"})," is a variant of the key type that tracks unbonding purses."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Unbond"}),(0,a.jsx)(n.td,{children:"unbond-"}),(0,a.jsx)(n.td,{children:"unbond-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChainspecRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"Key"})," which contains a mapping of file names to the hash of the file itself. These files include ",(0,a.jsx)(n.em,{children:"Chainspec.toml"})," and may also include ",(0,a.jsx)(n.em,{children:"Accounts.toml"})," and ",(0,a.jsx)(n.em,{children:"GlobalState.toml"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::ChainspecRegistry"}),(0,a.jsx)(n.td,{children:"chainspec-registry-"}),(0,a.jsx)(n.td,{children:"chainspec-registry-11111111111111111111111111111111"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"checksumregistry",children:"ChecksumRegistry"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ChecksumRegistry"})," is a unique ",(0,a.jsx)(n.code,{children:"key"})," variant under which we write a registry of checksums for a given block. There are two checksums in the registry, one for the execution results and the other for the approvals of all transactions in the block."]}),"\n",(0,a.jsx)(n.p,{children:"|Key::ChecksumRegistry | checksum-registry- | checksum-registry-00000000000000000000000000000000 |"}),"\n",(0,a.jsx)(n.h3,{id:"bidaddr",children:"BidAddr"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BidAddr"})," manages data associated with bids for the ",(0,a.jsx)(n.code,{children:"Auction"})," contract. It may be any one of three variants: ",(0,a.jsx)(n.code,{children:"unified"}),", ",(0,a.jsx)(n.code,{children:"validator"}),", or ",(0,a.jsx)(n.code,{children:"delegator"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Unified"})}),(0,a.jsx)(n.td,{children:"bid-addr-00"}),(0,a.jsx)(n.td,{children:"bid-addr-00ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Validator"})}),(0,a.jsx)(n.td,{children:"bid-addr-01"}),(0,a.jsx)(n.td,{children:"bid-addr-01ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Delegator"})}),(0,a.jsx)(n.td,{children:"bid-addr-02"}),(0,a.jsx)(n.td,{children:"bid-addr-02ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Package"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which package information is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsx)(n.tbody,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Key::Package"}),(0,a.jsx)(n.td,{children:"package-"}),(0,a.jsx)(n.td,{children:"package-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})})]}),"\n",(0,a.jsx)(n.h3,{id:"addressableentity",children:"AddressableEntity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::AddressableEntity"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain#addressableentity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," is stored. It may be one of three variants: ",(0,a.jsx)(n.code,{children:"Account"}),", ",(0,a.jsx)(n.code,{children:"System"})," or ",(0,a.jsx)(n.code,{children:"SmartContract"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"Account"})}),(0,a.jsx)(n.td,{children:"addressable-entity-account-"}),(0,a.jsx)(n.td,{children:"addressable-entity-account-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"System"})}),(0,a.jsx)(n.td,{children:"addressable-entity-system-"}),(0,a.jsx)(n.td,{children:"addressable-entity-system-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"SmartContract"})}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-"}),(0,a.jsx)(n.td,{children:"addressable-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"bytecode",children:"ByteCode"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::ByteCode"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a byte code record is stored. It may be one of two variants: ",(0,a.jsx)(n.code,{children:"v1-wasm"})," or ",(0,a.jsx)(n.code,{children:"empty"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"v1-wasm"})}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-"}),(0,a.jsx)(n.td,{children:"byte-code-v1-wasm-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:(0,a.jsx)(n.code,{children:"empty"})}),(0,a.jsx)(n.td,{children:"byte-code-empty-"}),(0,a.jsx)(n.td,{children:"byte-code-empty-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"message",children:"Message"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::Message"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a message is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message Topic"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-topic-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Message"}),(0,a.jsx)(n.td,{children:"message-entity-contract-"}),(0,a.jsx)(n.td,{children:"message-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-0202020202020202020202020202020202020202020202020202020202020202-f"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"namedkey",children:"NamedKey"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::NamedKey"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which a single named key entry is stored."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Account Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-"}),(0,a.jsx)(n.td,{children:"named-key-entity-account-928d914bdcad3ca269e750f63ed3615c5d3f615cf97dba87006fd9f979dacb3c-dde6f264c89fe385a5b07c26d77284d6fddabe79653c5ca25cec39a6363e6ec7"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Contract Named Key"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-"}),(0,a.jsx)(n.td,{children:"named-key-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"blockglobal",children:"BlockGlobal"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::BlockGlobal"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which per-block details are stored to global state."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Time"}),(0,a.jsx)(n.td,{children:"block-time-"}),(0,a.jsx)(n.td,{children:"block-time-00000000000000000000000000000000000000000000000000000000000000"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"Block Message Count"}),(0,a.jsx)(n.td,{children:"block-message-count-"}),(0,a.jsx)(n.td,{children:"block-message-count-00000000000000000000000000000000000000000000000000000000000000"})]})]})]}),"\n",(0,a.jsx)(n.h3,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Key::EntryPoint"})," is a ",(0,a.jsx)(n.code,{children:"Key"})," under which an entrypoint record is written."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,a.jsxs)(n.table,{children:[(0,a.jsx)(n.thead,{children:(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.th,{children:"Type"}),(0,a.jsx)(n.th,{children:"Prefix"}),(0,a.jsx)(n.th,{children:"Example"})]})}),(0,a.jsxs)(n.tbody,{children:[(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V1 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481"})]}),(0,a.jsxs)(n.tr,{children:[(0,a.jsx)(n.td,{children:"V2 Entry Point"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-"}),(0,a.jsx)(n.td,{children:"entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1"})]})]})]})]})}function x(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,d)=>{d.d(n,{R:()=>i,x:()=>c});var a=d(96540);const s={},r=a.createContext(s);function i(e){const n=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),a.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b9ffcd07.a7d11053.js b/assets/js/b9ffcd07.a7d11053.js new file mode 100644 index 000000000..ced844eb6 --- /dev/null +++ b/assets/js/b9ffcd07.a7d11053.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[44690],{17921:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const c={title:"Multi-Sig Workflow"},d="Multi-Signature Workflow",r={id:"resources/advanced/multi-sig/multi-sig-workflow",title:"Multi-Sig Workflow",description:"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/multi-sig-workflow.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/multi-sig-workflow",permalink:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Multi-Sig Workflow"},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/2.0.0/resources/advanced/multi-sig/"},next:{title:"Additional Examples",permalink:"/2.0.0/resources/advanced/multi-sig/other-scenarios"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Session Code Required for Key Management",id:"session-code-required-for-key-management",level:2},{value:"Tutorial Workflow",id:"tutorial-workflow",level:2},{value:"Step 1: Clone the example Wasm for this workflow",id:"step-1-clone-the-example-wasm-for-this-workflow",level:3},{value:"Step 2: Build the sample Wasm provided",id:"step-2-build-the-sample-wasm-provided",level:3},{value:"Step 3: Increase the primary key's weight to set thresholds",id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",level:3},{value:"Step 4: Update the account's action thresholds",id:"step-4-update-the-accounts-action-thresholds",level:3},{value:"Step 5: Add associated keys to the primary account",id:"step-5-add-associated-keys-to-the-primary-account",level:3},{value:"Step 6: Send a deploy from the primary account",id:"step-6-send-a-deploy-from-the-primary-account",level:3},{value:"Step 7: Send a multi-signature deploy from an associated key",id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",level:3},{value:"Removing a Compromised Key",id:"removing-a-compromised-key",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"multi-signature-workflow",children:"Multi-Signature Workflow"})}),"\n",(0,t.jsxs)(n.p,{children:["The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," tutorial, among other prerequisites. You will also need the Casper CLI client to use the ",(0,t.jsx)(n.code,{children:"make-deploy"}),", ",(0,t.jsx)(n.code,{children:"sign-deploy"}),", and ",(0,t.jsx)(n.code,{children:"send-deploy"})," Casper CLI client commands."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"The following prerequisites are required for this workflow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"development environment prerequisites"}),", including a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"funded account"})," and the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper CLI client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Complete the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow and set up the source account for multi-signature deploys"]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the Casper ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"account-based model"})," before proceeding"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"session-code-required-for-key-management",children:"Session Code Required for Key Management"}),"\n",(0,t.jsx)(n.p,{children:"To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Do not run these examples on Mainnet. Update each command for your environment."})}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-workflow",children:"Tutorial Workflow"}),"\n",(0,t.jsx)(n.h3,{id:"step-1-clone-the-example-wasm-for-this-workflow",children:"Step 1: Clone the example Wasm for this workflow"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"multi-sig GitHub repository"})," contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you take a look at the repository structure and open the ",(0,t.jsx)(n.code,{children:"contracts"})," folder, you will see session code with different functionality:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_account.wasm"})," - adds an associated account with a specified weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"})," - updates a key\u2019s weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," - updates the account's action thresholds for deployment and account management"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"remove_account.wasm"})," - removes an associated account from the primary account"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-2-build-the-sample-wasm-provided",children:"Step 2: Build the sample Wasm provided"}),"\n",(0,t.jsx)(n.p,{children:"Prepare your environment, build and test the session code provided with the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\nmake prepare\nmake test\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rustup update"})," - checks and updates your Rust installation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make prepare"})," - sets the Wasm target"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make test"})," - builds and verifies the session code"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that in the test folder there is a ",(0,t.jsx)(n.code,{children:"contract.wasm"})," that is needed for the tests to pass. If you run ",(0,t.jsx)(n.code,{children:"make clean"})," that file will be deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",children:"Step 3: Increase the primary key's weight to set thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.code,{children:"key_management"})," threshold. In a later step, you will add the associated accounts that will participate in signing deploys."]}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update the weight of the primary key to 3 by calling the ",(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-<ACCOUNT_HASH>\'" \\\n--session-arg "new_weight:u8=\'3\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The primary key in this account should now have weight 3."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-update-the-accounts-action-thresholds",children:"Step 4: Update the account's action thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["Set up a multi-signature scheme for the account by updating the ",(0,t.jsx)(n.code,{children:"deployment"})," and ",(0,t.jsx)(n.code,{children:"key_management"})," thresholds. The ",(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," will take two arguments and set the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to 2 and the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold to 3."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The account's action thresholds should look like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n'})}),"\n",(0,t.jsx)(n.p,{children:"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-add-associated-keys-to-the-primary-account",children:"Step 5: Add associated keys to the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["To add an associated key to the primary account, use the ",(0,t.jsx)(n.code,{children:"add_account.wasm"})," provided. This example adds two keys to the primary account (",(0,t.jsx)(n.code,{children:"account-hash-d89c*"}),"): ",(0,t.jsx)(n.code,{children:"user_1"})," with ",(0,t.jsx)(n.code,{children:"account-hash-e2d0*"}),", and ",(0,t.jsx)(n.code,{children:"user_2"})," with ",(0,t.jsx)(n.code,{children:"account-hash-04a9*"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."}),"\n",(0,t.jsx)(n.li,{children:"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."}),"\n"]})}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-6-send-a-deploy-from-the-primary-account",children:"Step 6: Send a deploy from the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["This step sends a deploy containing Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"hello-world"})," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h3,{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",children:"Step 7: Send a multi-signature deploy from an associated key"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-deploy"})," - creates and signs a deploy, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-deploy"})," - adds additional signatures for a multi-signature deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-deploy"})," - sends the deploy to the network"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to step 6, this example uses Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument. The deploy needs two signatures to meet the ",(0,t.jsx)(n.code,{children:"deployment"})," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."]}),"\n",(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."]}),"\n",(0,t.jsxs)(n.p,{children:["One associated key creates and signs the deploy with the ",(0,t.jsx)(n.code,{children:"make-deploy"})," command, indicating the account context under which the session code will be executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The second associated key signs the deploy with ",(0,t.jsx)(n.code,{children:"sign-deploy"})," to meet the deployment threshold for the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The deploy can be sent to the network using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.h2,{id:"removing-a-compromised-key",children:"Removing a Compromised Key"}),"\n",(0,t.jsxs)(n.p,{children:["This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," session code."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Remove keys with caution! Do not run this example on Mainnet."}),(0,t.jsx)(n.p,{children:"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution."})]}),"\n",(0,t.jsx)(n.p,{children:"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"add_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The resulting account should not contain the associated key that was just removed."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"N/A (Removed)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.p,{children:["The next section contains ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," where Casper's multi-signature feature would be helpful."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(96540);const a={},c=t.createContext(a);function d(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ba0fa3fe.2c38bb2c.js b/assets/js/ba0fa3fe.2c38bb2c.js deleted file mode 100644 index 543f367ee..000000000 --- a/assets/js/ba0fa3fe.2c38bb2c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4225],{64287:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var s=n(74848),i=n(28453);const a={title:"Authorization Keys"},r="Working with Authorization Keys",o={id:"resources/advanced/list-auth-keys-tutorial",title:"Authorization Keys",description:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.",source:"@site/docs/resources/advanced/list-auth-keys-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/advanced/list-auth-keys-tutorial",permalink:"/next/resources/advanced/list-auth-keys-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Authorization Keys"},sidebar:"tutorials",previous:{title:"Runtime Return Values",permalink:"/next/resources/tutorials/advanced/return-values-tutorial"},next:{title:"Token Transfers",permalink:"/next/resources/tutorials/advanced/transfer-token-to-contract"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Workflow",id:"workflow",level:2},{value:"The example contract",id:"the-example-contract",level:3},{value:"Client Wasm files",id:"client-wasm-files",level:3},{value:"<code>add_keys.wasm</code>",id:"add_keyswasm",level:4},{value:"<code>contract_call.wasm</code>",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: <code>should_allow_install_contract_with_default_account</code>",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: <code>should_disallow_install_with_non_added_authorization_key</code>",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: <code>should_allow_install_with_added_authorization_key</code>",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: <code>should_allow_entry_point_with_installer_authorization_key</code>",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: <code>should_allow_entry_point_with_account_authorization_key</code>",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: <code>should_disallow_entry_point_without_authorization_key</code>",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: <code>should_allow_entry_point_through_contract_call_with_authorization_key</code>",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: <code>should_disallow_entry_point_through_contract_call_without_authorization_key</code>",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-authorization-keys",children:"Working with Authorization Keys"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use."})}),"\n",(0,s.jsxs)(t.p,{children:["This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"list_authorization_keys"})," function."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys = runtime::list_authorization_keys();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember that authorization keys are listed under a Deploy's ",(0,s.jsx)(t.a,{href:"/next/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"approvals"})," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," function. In other words, ",(0,s.jsx)(t.code,{children:"list_authorization_keys"})," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["You meet the ",(0,s.jsx)(t.a,{href:"/next/developers/prerequisites",children:"development prerequisites"})," and are familiar with ",(0,s.jsx)(t.a,{href:"/next/writing-contracts",children:"writing and testing on-chain code"})]}),"\n",(0,s.jsxs)(t.li,{children:["You know how to ",(0,s.jsx)(t.a,{href:"/next/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,s.jsxs)(t.li,{children:["You are familiar with these concepts:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/serialization/structures#account-serialization-standard-account",children:"Casper Accounts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"Deploys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/next/concepts/serialization/types#associatedkey",children:"Associated Keys"})}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/next/concepts/serialization/types#approval",children:"Approvals"}),", also known as authorization keys"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"workflow",children:"Workflow"}),"\n",(0,s.jsxs)(t.p,{children:["To start, clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm",children:"tutorials-example-wasm"})," repository. Then, open the ",(0,s.jsx)(t.code,{children:"authorization-keys-example"})," directory, prepare your Rust environment, and build the tests with the following commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n"})}),"\n",(0,s.jsx)(t.p,{children:"Review the repository's structure:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client",children:"client"})," - A client folder containing two Wasm files\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"add_keys.wasm"})," - Session code that adds an associated key to the calling account"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call.wasm"})," - Session code that calls the contract's entry point and stores the result into a named key"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract",children:"contract"})," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests",children:"tests"})," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior"]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This tutorial highlights certain lines of code found in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example",children:"GitHub"}),"."]})}),"\n",(0,s.jsx)(t.h3,{id:"the-example-contract",children:"The example contract"}),"\n",(0,s.jsxs)(t.p,{children:["Upon ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75",children:"installation"}),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52",children:"usage"})," of ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," retrieves the set of account hashes representing the keys signing the caller deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys_caller: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n"})}),"\n",(0,s.jsx)(t.h3,{id:"client-wasm-files",children:"Client Wasm files"}),"\n",(0,s.jsx)(t.h4,{id:"add_keyswasm",children:(0,s.jsx)(t.code,{children:"add_keys.wasm"})}),"\n",(0,s.jsxs)(t.p,{children:["This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,s.jsx)(t.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,s.jsx)(t.h4,{id:"contract_callwasm",children:(0,s.jsx)(t.code,{children:"contract_call.wasm"})}),"\n",(0,s.jsx)(t.p,{children:"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"}),"\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy)."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The intersection result is a list stored under a named key of the account calling the ",(0,s.jsx)(t.code,{children:"contract_call.wasm"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"testing-this-example",children:"Testing this example"}),"\n",(0,s.jsx)(t.p,{children:"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Testing the contract installation"}),"\n",(0,s.jsx)(t.li,{children:"Testing the contract's unique entry point"}),"\n",(0,s.jsx)(t.li,{children:"Testing the entry point using a client contract call"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"These tests focus on testing the contract installation."}),"\n",(0,s.jsxs)(t.h4,{id:"test-1-should_allow_install_contract_with_default_account",children:["Test 1: ",(0,s.jsx)(t.code,{children:"should_allow_install_contract_with_default_account"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28",children:"test"})," signs the installer deploy with an authorization key ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," can be used to sign the deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-2-should_disallow_install_with_non_added_authorization_key",children:["Test 2: ",(0,s.jsx)(t.code,{children:"should_disallow_install_with_non_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Failed contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57",children:"test"})," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-3-should_allow_install_with_added_authorization_key",children:["Test 3: ",(0,s.jsx)(t.code,{children:"should_allow_install_with_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83",children:"test"})," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,s.jsx)(t.code,{children:"account_addr_1"})," to the default account's associated keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". See ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n"})}),"\n",(0,s.jsx)(t.p,{children:"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."}),"\n",(0,s.jsxs)(t.h4,{id:"test-4-should_allow_entry_point_with_installer_authorization_key",children:["Test 4: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_installer_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_1"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144",children:"test"})," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," signed only with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". This is possible because the deploy action threshold for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," is 1 as you can see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". Thus, the caller deploy is expected to succeed and return a result."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-5-should_allow_entry_point_with_account_authorization_key",children:["Test 5: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_account_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This is the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224",children:"main test"})," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," as an associated key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," and has two authorization keys, ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-6-should_disallow_entry_point_without_authorization_key",children:["Test 6: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_2"})}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304",children:"test"})," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."]}),"\n",(0,s.jsx)(t.p,{children:"The default account hash is used to sign the installer deploy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["In the test, a new account, ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_2"}),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,s.jsx)(t.code,{children:"account_addr_2"}),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The following tests exercise the entry point using a ",(0,s.jsx)(t.a,{href:"#contract_callwasm",children:"contract call"})," and verifying the result returned."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",children:["Test 7: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_through_contract_call_with_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403",children:"test"})," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The caller deploy is signed by ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The test then verifies that the result returned was saved in the named keys for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"}),", containing the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",children:["Test 8: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_through_contract_call_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"})]}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509",children:"final test"})," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"}),") and the installer deploy's authorization keys (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the entry point returns an error."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ba0fa3fe.45f877c7.js b/assets/js/ba0fa3fe.45f877c7.js new file mode 100644 index 000000000..01723593a --- /dev/null +++ b/assets/js/ba0fa3fe.45f877c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94225],{64287:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var s=n(74848),i=n(28453);const a={title:"Authorization Keys"},r="Working with Authorization Keys",o={id:"resources/advanced/list-auth-keys-tutorial",title:"Authorization Keys",description:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.",source:"@site/docs/resources/advanced/list-auth-keys-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/advanced/list-auth-keys-tutorial",permalink:"/resources/advanced/list-auth-keys-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Authorization Keys"},sidebar:"tutorials",previous:{title:"Runtime Return Values",permalink:"/resources/tutorials/advanced/return-values-tutorial"},next:{title:"Token Transfers",permalink:"/resources/tutorials/advanced/transfer-token-to-contract"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Workflow",id:"workflow",level:2},{value:"The example contract",id:"the-example-contract",level:3},{value:"Client Wasm files",id:"client-wasm-files",level:3},{value:"<code>add_keys.wasm</code>",id:"add_keyswasm",level:4},{value:"<code>contract_call.wasm</code>",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: <code>should_allow_install_contract_with_default_account</code>",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: <code>should_disallow_install_with_non_added_authorization_key</code>",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: <code>should_allow_install_with_added_authorization_key</code>",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: <code>should_allow_entry_point_with_installer_authorization_key</code>",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: <code>should_allow_entry_point_with_account_authorization_key</code>",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: <code>should_disallow_entry_point_without_authorization_key</code>",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: <code>should_allow_entry_point_through_contract_call_with_authorization_key</code>",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: <code>should_disallow_entry_point_through_contract_call_without_authorization_key</code>",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-authorization-keys",children:"Working with Authorization Keys"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use."})}),"\n",(0,s.jsxs)(t.p,{children:["This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"list_authorization_keys"})," function."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys = runtime::list_authorization_keys();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember that authorization keys are listed under a Deploy's ",(0,s.jsx)(t.a,{href:"/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"approvals"})," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," function. In other words, ",(0,s.jsx)(t.code,{children:"list_authorization_keys"})," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["You meet the ",(0,s.jsx)(t.a,{href:"/developers/prerequisites",children:"development prerequisites"})," and are familiar with ",(0,s.jsx)(t.a,{href:"/writing-contracts",children:"writing and testing on-chain code"})]}),"\n",(0,s.jsxs)(t.li,{children:["You know how to ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,s.jsxs)(t.li,{children:["You are familiar with these concepts:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization/structures#account-serialization-standard-account",children:"Casper Accounts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"Deploys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/concepts/serialization/types#associatedkey",children:"Associated Keys"})}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/concepts/serialization/types#approval",children:"Approvals"}),", also known as authorization keys"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"workflow",children:"Workflow"}),"\n",(0,s.jsxs)(t.p,{children:["To start, clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm",children:"tutorials-example-wasm"})," repository. Then, open the ",(0,s.jsx)(t.code,{children:"authorization-keys-example"})," directory, prepare your Rust environment, and build the tests with the following commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n"})}),"\n",(0,s.jsx)(t.p,{children:"Review the repository's structure:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client",children:"client"})," - A client folder containing two Wasm files\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"add_keys.wasm"})," - Session code that adds an associated key to the calling account"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call.wasm"})," - Session code that calls the contract's entry point and stores the result into a named key"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract",children:"contract"})," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests",children:"tests"})," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior"]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This tutorial highlights certain lines of code found in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example",children:"GitHub"}),"."]})}),"\n",(0,s.jsx)(t.h3,{id:"the-example-contract",children:"The example contract"}),"\n",(0,s.jsxs)(t.p,{children:["Upon ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75",children:"installation"}),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52",children:"usage"})," of ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," retrieves the set of account hashes representing the keys signing the caller deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys_caller: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n"})}),"\n",(0,s.jsx)(t.h3,{id:"client-wasm-files",children:"Client Wasm files"}),"\n",(0,s.jsx)(t.h4,{id:"add_keyswasm",children:(0,s.jsx)(t.code,{children:"add_keys.wasm"})}),"\n",(0,s.jsxs)(t.p,{children:["This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,s.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,s.jsx)(t.h4,{id:"contract_callwasm",children:(0,s.jsx)(t.code,{children:"contract_call.wasm"})}),"\n",(0,s.jsx)(t.p,{children:"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"}),"\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy)."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The intersection result is a list stored under a named key of the account calling the ",(0,s.jsx)(t.code,{children:"contract_call.wasm"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"testing-this-example",children:"Testing this example"}),"\n",(0,s.jsx)(t.p,{children:"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Testing the contract installation"}),"\n",(0,s.jsx)(t.li,{children:"Testing the contract's unique entry point"}),"\n",(0,s.jsx)(t.li,{children:"Testing the entry point using a client contract call"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"These tests focus on testing the contract installation."}),"\n",(0,s.jsxs)(t.h4,{id:"test-1-should_allow_install_contract_with_default_account",children:["Test 1: ",(0,s.jsx)(t.code,{children:"should_allow_install_contract_with_default_account"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28",children:"test"})," signs the installer deploy with an authorization key ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," can be used to sign the deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-2-should_disallow_install_with_non_added_authorization_key",children:["Test 2: ",(0,s.jsx)(t.code,{children:"should_disallow_install_with_non_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Failed contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57",children:"test"})," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-3-should_allow_install_with_added_authorization_key",children:["Test 3: ",(0,s.jsx)(t.code,{children:"should_allow_install_with_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83",children:"test"})," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,s.jsx)(t.code,{children:"account_addr_1"})," to the default account's associated keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". See ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n"})}),"\n",(0,s.jsx)(t.p,{children:"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."}),"\n",(0,s.jsxs)(t.h4,{id:"test-4-should_allow_entry_point_with_installer_authorization_key",children:["Test 4: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_installer_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_1"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144",children:"test"})," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," signed only with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". This is possible because the deploy action threshold for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," is 1 as you can see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". Thus, the caller deploy is expected to succeed and return a result."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-5-should_allow_entry_point_with_account_authorization_key",children:["Test 5: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_account_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This is the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224",children:"main test"})," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," as an associated key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," and has two authorization keys, ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-6-should_disallow_entry_point_without_authorization_key",children:["Test 6: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_2"})}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304",children:"test"})," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."]}),"\n",(0,s.jsx)(t.p,{children:"The default account hash is used to sign the installer deploy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["In the test, a new account, ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_2"}),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,s.jsx)(t.code,{children:"account_addr_2"}),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The following tests exercise the entry point using a ",(0,s.jsx)(t.a,{href:"#contract_callwasm",children:"contract call"})," and verifying the result returned."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",children:["Test 7: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_through_contract_call_with_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403",children:"test"})," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The caller deploy is signed by ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The test then verifies that the result returned was saved in the named keys for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"}),", containing the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",children:["Test 8: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_through_contract_call_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"})]}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509",children:"final test"})," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"}),") and the installer deploy's authorization keys (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the entry point returns an error."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/baabe181.1d890051.js b/assets/js/baabe181.1d890051.js new file mode 100644 index 000000000..e1e4928b1 --- /dev/null +++ b/assets/js/baabe181.1d890051.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22510],{37324:e=>{e.exports=JSON.parse('{"author":{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden","count":4},"listMetadata":{"permalink":"/blog/authors/melpadden","page":1,"postsPerPage":4,"totalPages":1,"totalCount":4,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/baabe181.5c403d89.js b/assets/js/baabe181.5c403d89.js deleted file mode 100644 index eab4821c1..000000000 --- a/assets/js/baabe181.5c403d89.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2510],{37324:e=>{e.exports=JSON.parse('{"author":{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden","count":4},"listMetadata":{"permalink":"/blog/authors/melpadden","page":1,"postsPerPage":4,"totalPages":1,"totalCount":4,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/baf71301.8c98a771.js b/assets/js/baf71301.8c98a771.js deleted file mode 100644 index ebd30531c..000000000 --- a/assets/js/baf71301.8c98a771.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2996],{28646:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=t(74848),n=t(28453);const o={title:"What is Casper?",slug:"/"},i=void 0,a={id:"concepts/about",title:"What is Casper?",description:"What is Casper?",source:"@site/versioned_docs/version-1.5.X/concepts/about.md",sourceDirName:"concepts",slug:"/",permalink:"/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"What is Casper?",slug:"/"},sidebar:"concepts",previous:{title:"Overview",permalink:"/concepts/"},next:{title:"dApps",permalink:"/concepts/intro-to-dapps"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How does Casper work?",id:"how-does-casper-work",level:2},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const s={a:"a",em:"em",h2:"h2",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a new ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,r.jsxs)(s.p,{children:["The network's consensus protocol is called ",(0,r.jsx)(s.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"}),", and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Highway allows networks to reach higher thresholds of ",(0,r.jsx)(s.em,{children:"finality"}),", meaning that more blocks are finalized, and validators agree to add them to the blockchain. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the ",(0,r.jsx)(s.a,{href:"https://github.com/cbc-casper/cbc-casper-paper",children:"correct-by-construction (CBC) Casper"})," research."]}),"\n",(0,r.jsxs)(s.p,{children:["Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's ",(0,r.jsx)(s.a,{href:"/resources/build-on-casper/introduction",children:"core features and strengths"})," enable developers and enterprises to reap the benefits of blockchain technology."]}),"\n",(0,r.jsx)(s.p,{children:"Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises."}),"\n",(0,r.jsx)(s.h2,{id:"how-does-casper-work",children:"How does Casper work?"}),"\n",(0,r.jsx)(s.p,{children:"Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network."}),"\n",(0,r.jsxs)(s.p,{children:["To understand the design further, read ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design",children:"this article"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,r.jsxs)(s.p,{children:["Read the ",(0,r.jsx)(s.a,{href:"/disclaimer",children:"Legal Disclaimer"}),' regarding this CasperLabs Tech Spec (this "Whitepaper").']})]})}function p(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var r=t(96540);const n={},o=r.createContext(n);function i(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/baf71301.b7c5f244.js b/assets/js/baf71301.b7c5f244.js new file mode 100644 index 000000000..da6625ec7 --- /dev/null +++ b/assets/js/baf71301.b7c5f244.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2996],{28646:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=t(74848),n=t(28453);const o={title:"What is Casper?",slug:"/"},i=void 0,a={id:"concepts/about",title:"What is Casper?",description:"What is Casper?",source:"@site/versioned_docs/version-1.5.X/concepts/about.md",sourceDirName:"concepts",slug:"/",permalink:"/1.5.X/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"What is Casper?",slug:"/"},sidebar:"concepts",previous:{title:"Overview",permalink:"/1.5.X/concepts/"},next:{title:"dApps",permalink:"/1.5.X/concepts/intro-to-dapps"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How does Casper work?",id:"how-does-casper-work",level:2},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const s={a:"a",em:"em",h2:"h2",p:"p",...(0,n.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a new ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,r.jsxs)(s.p,{children:["The network's consensus protocol is called ",(0,r.jsx)(s.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"}),", and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Highway allows networks to reach higher thresholds of ",(0,r.jsx)(s.em,{children:"finality"}),", meaning that more blocks are finalized, and validators agree to add them to the blockchain. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the ",(0,r.jsx)(s.a,{href:"https://github.com/cbc-casper/cbc-casper-paper",children:"correct-by-construction (CBC) Casper"})," research."]}),"\n",(0,r.jsxs)(s.p,{children:["Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's ",(0,r.jsx)(s.a,{href:"/1.5.X/resources/build-on-casper/introduction",children:"core features and strengths"})," enable developers and enterprises to reap the benefits of blockchain technology."]}),"\n",(0,r.jsx)(s.p,{children:"Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises."}),"\n",(0,r.jsx)(s.h2,{id:"how-does-casper-work",children:"How does Casper work?"}),"\n",(0,r.jsx)(s.p,{children:"Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network."}),"\n",(0,r.jsxs)(s.p,{children:["To understand the design further, read ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/design/casper-design",children:"this article"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,r.jsxs)(s.p,{children:["Read the ",(0,r.jsx)(s.a,{href:"/1.5.X/disclaimer",children:"Legal Disclaimer"}),' regarding this CasperLabs Tech Spec (this "Whitepaper").']})]})}function p(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>a});var r=t(96540);const n={},o=r.createContext(n);function i(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:i(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bafead24.1578a574.js b/assets/js/bafead24.1578a574.js deleted file mode 100644 index 15855213f..000000000 --- a/assets/js/bafead24.1578a574.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[286],{70269:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const o={},t="C",a={id:"concepts/glossary/C",title:"C",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/C.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/C",permalink:"/concepts/glossary/C",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"B",permalink:"/concepts/glossary/B"},next:{title:"D",permalink:"/concepts/glossary/D"}},i={},l=[{value:"Cargo",id:"cargo",level:2},{value:"Casper network",id:"casper-network",level:2},{value:"CBC",id:"cbc",level:2},{value:"Chainspec",id:"chainspec",level:2},{value:"Consensus",id:"consensus",level:2},{value:"Contract runtime",id:"contract-runtime",level:2},{value:"Correct by construction",id:"correct-by-construction",level:2},{value:"Crate",id:"crate",level:2},{value:"CSPR",id:"cspr",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"c",children:"C"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"cargo",children:"Cargo"}),"\n",(0,r.jsx)(s.p,{children:"Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies."}),"\n",(0,r.jsx)(s.h2,{id:"casper-network",children:"Casper network"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"cbc",children:"CBC"}),"\n",(0,r.jsx)(s.p,{children:"Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval."}),"\n",(0,r.jsx)(s.li,{children:"The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted."}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"chainspec",children:"Chainspec"}),"\n",(0,r.jsxs)(s.p,{children:["A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G#genesis",children:"genesis"}),". Here is an example ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"chainspec"}),", which will change with newer releases."]}),"\n",(0,r.jsx)(s.h2,{id:"consensus",children:"Consensus"}),"\n",(0,r.jsxs)(s.p,{children:["An algorithm used to mandate agreement on the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"})," between all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not."]}),"\n",(0,r.jsxs)(s.p,{children:["Casper uses the Highway algorithm in the ",(0,r.jsx)(s.em,{children:"CBC Casper"})," family of consensus algorithms. The algorithm for securing an agreement is what is known as ",(0,r.jsx)(s.em,{children:"consensus"}),". The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer."]}),"\n",(0,r.jsx)(s.h2,{id:"contract-runtime",children:"Contract runtime"}),"\n",(0,r.jsxs)(s.p,{children:["Enables developers to use a seamless workflow for authoring and testing their ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S#smart-contract",children:"smart contracts"}),". This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices."]}),"\n",(0,r.jsx)(s.h2,{id:"correct-by-construction",children:"Correct by construction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"crate",children:"Crate"}),"\n",(0,r.jsxs)(s.p,{children:["A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, ",(0,r.jsx)(s.em,{children:"rustc"}),", the compiler for the Rust programming language, will produce a binary from a crate."]}),"\n",(0,r.jsx)(s.h2,{id:"cspr",children:"CSPR"}),"\n",(0,r.jsxs)(s.p,{children:["CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S#staking",children:"staking"})," (securing the network)."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bafead24.e60d55cc.js b/assets/js/bafead24.e60d55cc.js new file mode 100644 index 000000000..0ea009cd9 --- /dev/null +++ b/assets/js/bafead24.e60d55cc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30286],{70269:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const o={},t="C",a={id:"concepts/glossary/C",title:"C",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/C.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/C",permalink:"/1.5.X/concepts/glossary/C",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"B",permalink:"/1.5.X/concepts/glossary/B"},next:{title:"D",permalink:"/1.5.X/concepts/glossary/D"}},i={},l=[{value:"Cargo",id:"cargo",level:2},{value:"Casper network",id:"casper-network",level:2},{value:"CBC",id:"cbc",level:2},{value:"Chainspec",id:"chainspec",level:2},{value:"Consensus",id:"consensus",level:2},{value:"Contract runtime",id:"contract-runtime",level:2},{value:"Correct by construction",id:"correct-by-construction",level:2},{value:"Crate",id:"crate",level:2},{value:"CSPR",id:"cspr",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"c",children:"C"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"cargo",children:"Cargo"}),"\n",(0,r.jsx)(s.p,{children:"Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies."}),"\n",(0,r.jsx)(s.h2,{id:"casper-network",children:"Casper network"}),"\n",(0,r.jsxs)(s.p,{children:["Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/design/casper-design",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"cbc",children:"CBC"}),"\n",(0,r.jsx)(s.p,{children:"Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:"}),"\n",(0,r.jsxs)(s.ul,{children:["\n",(0,r.jsx)(s.li,{children:"All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval."}),"\n",(0,r.jsx)(s.li,{children:"The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted."}),"\n"]}),"\n",(0,r.jsx)(s.h2,{id:"chainspec",children:"Chainspec"}),"\n",(0,r.jsxs)(s.p,{children:["A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G#genesis",children:"genesis"}),". Here is an example ",(0,r.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/resources/production/chainspec.toml",children:"chainspec"}),", which will change with newer releases."]}),"\n",(0,r.jsx)(s.h2,{id:"consensus",children:"Consensus"}),"\n",(0,r.jsxs)(s.p,{children:["An algorithm used to mandate agreement on the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B#blockchain",children:"blockchain"})," between all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not."]}),"\n",(0,r.jsxs)(s.p,{children:["Casper uses the Highway algorithm in the ",(0,r.jsx)(s.em,{children:"CBC Casper"})," family of consensus algorithms. The algorithm for securing an agreement is what is known as ",(0,r.jsx)(s.em,{children:"consensus"}),". The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer."]}),"\n",(0,r.jsx)(s.h2,{id:"contract-runtime",children:"Contract runtime"}),"\n",(0,r.jsxs)(s.p,{children:["Enables developers to use a seamless workflow for authoring and testing their ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S#smart-contract",children:"smart contracts"}),". This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices."]}),"\n",(0,r.jsx)(s.h2,{id:"correct-by-construction",children:"Correct by construction"}),"\n",(0,r.jsxs)(s.p,{children:["See ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"crate",children:"Crate"}),"\n",(0,r.jsxs)(s.p,{children:["A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, ",(0,r.jsx)(s.em,{children:"rustc"}),", the compiler for the Rust programming language, will produce a binary from a crate."]}),"\n",(0,r.jsx)(s.h2,{id:"cspr",children:"CSPR"}),"\n",(0,r.jsxs)(s.p,{children:["CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S#staking",children:"staking"})," (securing the network)."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bb037852.08cf4bca.js b/assets/js/bb037852.08cf4bca.js new file mode 100644 index 000000000..123e57201 --- /dev/null +++ b/assets/js/bb037852.08cf4bca.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74096],{90282:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var a=n(74848),r=n(28453);const s={title:"Reading and Writing Data"},i="Reading and Writing Data to Global State",c={id:"concepts/design/reading-and-writing-to-the-blockchain",title:"Reading and Writing Data",description:"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.",source:"@site/docs/concepts/design/reading-and-writing-to-the-blockchain.md",sourceDirName:"concepts/design",slug:"/concepts/design/reading-and-writing-to-the-blockchain",permalink:"/concepts/design/reading-and-writing-to-the-blockchain",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Reading and Writing Data"},sidebar:"concepts",previous:{title:"Rewards Design",permalink:"/concepts/design/rewards"},next:{title:"Overview",permalink:"/economics"}},o={},d=[{value:"Using the Casper JSON-RPC",id:"using-the-casper-json-rpc",level:2},{value:"Using the Casper Rust API",id:"using-the-casper-rust-api",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"reading-and-writing-data-to-global-state",children:"Reading and Writing Data to Global State"})}),"\n",(0,a.jsxs)(t.p,{children:["Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using ",(0,a.jsx)(t.a,{href:"/concepts/dictionaries",children:"Dictionaries"})," or ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/types_chain#namedkey",children:(0,a.jsx)(t.code,{children:"NamedKeys"})}),"."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,a.jsx)(t.code,{children:"NamedKeys"})," to a top-level key type, making them more viable for larger data sets."]})}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-json-rpc",children:"Using the Casper JSON-RPC"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,a.jsx)(t.code,{children:"query_global_state"})})," method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the ",(0,a.jsx)(t.a,{href:"/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})," tutorial."]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-rust-api",children:"Using the Casper Rust API"}),"\n",(0,a.jsx)(t.p,{children:"The Casper API includes the following functions for reading and writing to global state:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:"put_key"})," - Stores the given ",(0,a.jsx)(t.code,{children:"Key"})," under the given ",(0,a.jsx)(t.code,{children:"name"})," in the current context's named keys"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:"get_key"})," - Returns the requested ",(0,a.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:"storage::new_uref"})," - Creates a new URef in the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:"storage::write"})," - Writes a given value under a previously created URef"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:"storage::read"})," - Reads the value from a URef in global state"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:"dictionary_put"})," - Writes the given value under the given ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:"dictionary_get"})," - Retrieves the value stored under a ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["For more details, see the ",(0,a.jsx)(t.a,{href:"/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})," tutorial."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var a=n(96540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bb037852.a0493efc.js b/assets/js/bb037852.a0493efc.js deleted file mode 100644 index 03919bcf0..000000000 --- a/assets/js/bb037852.a0493efc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4096],{90282:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>s,metadata:()=>c,toc:()=>d});var a=n(74848),r=n(28453);const s={title:"Reading and Writing Data"},i="Reading and Writing Data to Global State",c={id:"concepts/design/reading-and-writing-to-the-blockchain",title:"Reading and Writing Data",description:"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.",source:"@site/docs/concepts/design/reading-and-writing-to-the-blockchain.md",sourceDirName:"concepts/design",slug:"/concepts/design/reading-and-writing-to-the-blockchain",permalink:"/next/concepts/design/reading-and-writing-to-the-blockchain",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Reading and Writing Data"},sidebar:"concepts",previous:{title:"Rewards Design",permalink:"/next/concepts/design/rewards"},next:{title:"Overview",permalink:"/next/economics"}},o={},d=[{value:"Using the Casper JSON-RPC",id:"using-the-casper-json-rpc",level:2},{value:"Using the Casper Rust API",id:"using-the-casper-rust-api",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"reading-and-writing-data-to-global-state",children:"Reading and Writing Data to Global State"})}),"\n",(0,a.jsxs)(t.p,{children:["Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using ",(0,a.jsx)(t.a,{href:"/next/concepts/dictionaries",children:"Dictionaries"})," or ",(0,a.jsx)(t.a,{href:"/next/developers/json-rpc/types_chain#namedkey",children:(0,a.jsx)(t.code,{children:"NamedKeys"})}),"."]}),"\n",(0,a.jsx)(t.admonition,{type:"note",children:(0,a.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,a.jsx)(t.code,{children:"NamedKeys"})," to a top-level key type, making them more viable for larger data sets."]})}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-json-rpc",children:"Using the Casper JSON-RPC"}),"\n",(0,a.jsxs)(t.p,{children:["The ",(0,a.jsx)(t.a,{href:"/next/developers/json-rpc/json-rpc-informational#query_global_state",children:(0,a.jsx)(t.code,{children:"query_global_state"})})," method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the ",(0,a.jsx)(t.a,{href:"/next/resources/tutorials/beginner/querying-network",children:"Querying a Casper Network"})," tutorial."]}),"\n",(0,a.jsx)(t.h2,{id:"using-the-casper-rust-api",children:"Using the Casper Rust API"}),"\n",(0,a.jsx)(t.p,{children:"The Casper API includes the following functions for reading and writing to global state:"}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:"put_key"})," - Stores the given ",(0,a.jsx)(t.code,{children:"Key"})," under the given ",(0,a.jsx)(t.code,{children:"name"})," in the current context's named keys"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:"get_key"})," - Returns the requested ",(0,a.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:"storage::new_uref"})," - Creates a new URef in the current context"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:"storage::write"})," - Writes a given value under a previously created URef"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:"storage::read"})," - Reads the value from a URef in global state"]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:"dictionary_put"})," - Writes the given value under the given ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:"dictionary_get"})," - Retrieves the value stored under a ",(0,a.jsx)(t.code,{children:"dictionary_item_key"})]}),"\n"]}),"\n",(0,a.jsxs)(t.p,{children:["For more details, see the ",(0,a.jsx)(t.a,{href:"/next/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})," tutorial."]})]})}function h(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>c});var a=n(96540);const r={},s=a.createContext(r);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bb9db0dd.0b2c5312.js b/assets/js/bb9db0dd.0b2c5312.js deleted file mode 100644 index 3a75dfbc9..000000000 --- a/assets/js/bb9db0dd.0b2c5312.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4198],{72876:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=t(74848),o=t(28453);const i={title:"Local Network Testing"},r="Testing Smart Contracts with NCTL",c={id:"developers/dapps/nctl-test",title:"Local Network Testing",description:"NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/nctl-test.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/nctl-test",permalink:"/developers/dapps/nctl-test",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Local Network Testing"},sidebar:"developers",previous:{title:"Local Network Setup",permalink:"/developers/dapps/setup-nctl"},next:{title:"Monitoring and Consuming Events",permalink:"/developers/dapps/monitor-and-consume-events"}},a={},l=[{value:"Getting Started with NCTL",id:"getting-started-with-nctl",level:2},{value:"NCTL Verification Prior to Testing",id:"nctl-verification-prior-to-testing",level:2},{value:"Installing the Smart Contract",id:"installing-the-smart-contract",level:2},{value:"Verifying Deploy Execution",id:"verifying-deploy-execution",level:2},{value:"Interacting with the Installed Contract",id:"interacting-with-the-installed-contract",level:2},{value:"Verifying Correct Contract Behavior",id:"verifying-correct-contract-behavior",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"testing-smart-contracts-with-nctl",children:"Testing Smart Contracts with NCTL"})}),"\n",(0,s.jsxs)(n.p,{children:["NCTL effectively simulates a live Casper network. The process for sending a ",(0,s.jsx)(n.code,{children:"Deploy"})," to an NCTL-based network is therefore similar to doing so on a live network."]}),"\n",(0,s.jsxs)(n.p,{children:["Testing ",(0,s.jsx)(n.code,{children:"Deploys"})," prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"writing your smart contract"})," and testing it ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"using the provided framework"}),", NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code."]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started-with-nctl",children:"Getting Started with NCTL"}),"\n",(0,s.jsxs)(n.p,{children:["Prior to testing a ",(0,s.jsx)(n.code,{children:"Deploy"})," through NCTL, you should have the following steps accomplished:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Completed writing a Deploy"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Tested the Deploy"})," using the Casper testing framework"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"Setup NCTL"})," on your system"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nctl-verification-prior-to-testing",children:"NCTL Verification Prior to Testing"}),"\n",(0,s.jsx)(n.p,{children:"Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-status\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You should see five nodes ",(0,s.jsx)(n.code,{children:"RUNNING"})," and five ",(0,s.jsx)(n.code,{children:"STOPPED"}),". Further, verify that the node and user information propagated within the ",(0,s.jsx)(n.em,{children:"casper-node/utils/assets"})," directory. Each node and user should have the associated ",(0,s.jsx)(n.code,{children:"Keys"})," necessary to interact with the network. Run the following command to view first user details:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-view-user-account user=1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-smart-contract",children:"Installing the Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This document assumes that you setup your NCTL network using the standard settings in a directory called ",(0,s.jsx)(n.em,{children:"/casper/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will need the following information to use the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", in this case ",(0,s.jsx)(n.code,{children:"casper-net-1"}),". This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"secret key"})," of the account sending the ",(0,s.jsx)(n.code,{children:"Deploy"}),". For this example, we are using node-1 as the sender. The secret key file can be found at ",(0,s.jsx)(n.em,{children:"casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". In our example put-deploy, this will appear as ",(0,s.jsx)(n.code,{children:"--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". If your Deploy is more complex and requires multiple accounts, NCTL also establishes multiple users for testing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"payment amount"})," in motes, which should be sufficient to avoid an 'Out of Gas' error. The payment amount will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--payment-amount 2500000000"}),". ",(0,s.jsxs)(n.strong,{children:["NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys#a-note-about-gas-price",children:"note about gas prices"}),"."]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"path"})," to your ",(0,s.jsx)(n.code,{children:"Deploy"})," that you wish to send to the NCTL network. This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--session-path <PATH>"})," and will require you to define the path to your specific ",(0,s.jsx)(n.code,{children:"Deploy"})," Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"})," for a node on your NCTL network. In this example, we are using the node at ",(0,s.jsx)(n.code,{children:"http://localhost:11101"}),". On the Casper Mainnet or Testnet, nodes will use port ",(0,s.jsx)(n.code,{children:"7777"}),". This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--node-address http://<HOST>:7777"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command to send your ",(0,s.jsx)(n.code,{children:"Deploy"})," should look similar to the following code snippet:"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Use of the ",(0,s.jsx)(n.code,{children:"$(get_path_to_client)"})," command assumes that you are operating in an activated NCTL envrionment."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$(get_path_to_client) put-deploy \\\n--chain-name "casper-net-1" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-path <PATH> \\\n--node-address http://localhost:11101\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The response will return something similar to the following information. Note the ",(0,s.jsx)(n.code,{children:"deploy_hash"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'{\n "id": 4824893960188648146,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-deploy-execution",children:"Verifying Deploy Execution"}),"\n",(0,s.jsxs)(n.p,{children:["The previous command sent the ",(0,s.jsx)(n.code,{children:"Deploy"})," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,s.jsx)(n.code,{children:"deploy_hash"})," received in the response allows you to query the ",(0,s.jsx)(n.code,{children:"Deploy"}),"'s status."]}),"\n",(0,s.jsxs)(n.p,{children:["To query the ",(0,s.jsx)(n.code,{children:"Deploy"}),"'s status, you will pass both the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," and the same ",(0,s.jsx)(n.code,{children:"node-address"})," from above using the following command. This will return either an error message in the event of failure or the ",(0,s.jsx)(n.code,{children:"Deploy"})," details if it succeeds."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interacting-with-the-installed-contract",children:"Interacting with the Installed Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Once your NCTL network executes your ",(0,s.jsx)(n.code,{children:"Deploy"}),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,s.jsx)(n.code,{children:"ContractHash"})," itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,s.jsxs)(n.a,{href:"/developers/cli/sending-deploys",children:["send the ",(0,s.jsx)(n.code,{children:"Deploy"})]}),", we can retrieve the ",(0,s.jsx)(n.code,{children:"ContractHash"})," from the node-1 account information. To do so, we will use the following command with a node address and the ",(0,s.jsx)(n.code,{children:"PublicKey"})," of the node in question."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-account-info \\\n--node-address http://localhost:11101 \\\n--public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return information pertaining to the account, including the ",(0,s.jsx)(n.code,{children:"NamedKeys"}),". The ",(0,s.jsx)(n.code,{children:"ContractHash"})," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,s.jsx)(n.code,{children:"Deploy"}),". In this instance, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--node-address http://localhost:11101"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"payment amount"})," for this ",(0,s.jsx)(n.code,{children:"Deploy"})," in motes, which may need to be adjusted depending on cost and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". In this instance, we will use ",(0,s.jsx)(n.code,{children:"--payment-amount 500000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"session path"}),", defining the location of the Wasm bearing file for the ",(0,s.jsx)(n.code,{children:"Deploy"}),". It appears in our example as ",(0,s.jsx)(n.code,{children:"--session-path <PATH>"})," but you must define the path to your specific file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.strong,{children:"session arguments"})," specific to the contract that you are testing. Multiple instances of ",(0,s.jsx)(n.code,{children:"--session-arg"})," may be used as necessary to provide values to the contract, including the ",(0,s.jsx)(n.code,{children:"ContractHash"})," you acquired above. In the example below, you will see a demonstration of the ",(0,s.jsx)(n.code,{children:"ContractHash"})," as a session argument as ",(0,s.jsx)(n.code,{children:"--session-arg \"contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'\""})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$(get_path_to_client) put-deploy \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000 \\\n--session-path <PATH> \\\n--session-arg "contract_key:key=\'hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a\'"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-correct-contract-behavior",children:"Verifying Correct Contract Behavior"}),"\n",(0,s.jsxs)(n.p,{children:["After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,s.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"global state"}),". Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"basic smart contract tutorial"}),", the NCTL process would have the following flow:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Send a ",(0,s.jsx)(n.code,{children:"Deploy"}),' to install the "Donation" smart contract.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Verify the execution of the ",(0,s.jsx)(n.code,{children:"Deploy"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Interact with the installed contract using an additional ",(0,s.jsx)(n.code,{children:"Deploy"})," that calls one or several of the entry points. For example, calling the ",(0,s.jsx)(n.code,{children:"donate"})," entry point to donate an amount to the fundraising purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bb9db0dd.83c0a3cb.js b/assets/js/bb9db0dd.83c0a3cb.js new file mode 100644 index 000000000..fb93adf6d --- /dev/null +++ b/assets/js/bb9db0dd.83c0a3cb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24198],{72876:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var s=t(74848),o=t(28453);const i={title:"Local Network Testing"},r="Testing Smart Contracts with NCTL",c={id:"developers/dapps/nctl-test",title:"Local Network Testing",description:"NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/nctl-test.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/nctl-test",permalink:"/1.5.X/developers/dapps/nctl-test",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Local Network Testing"},sidebar:"developers",previous:{title:"Local Network Setup",permalink:"/1.5.X/developers/dapps/setup-nctl"},next:{title:"Monitoring and Consuming Events",permalink:"/1.5.X/developers/dapps/monitor-and-consume-events"}},a={},l=[{value:"Getting Started with NCTL",id:"getting-started-with-nctl",level:2},{value:"NCTL Verification Prior to Testing",id:"nctl-verification-prior-to-testing",level:2},{value:"Installing the Smart Contract",id:"installing-the-smart-contract",level:2},{value:"Verifying Deploy Execution",id:"verifying-deploy-execution",level:2},{value:"Interacting with the Installed Contract",id:"interacting-with-the-installed-contract",level:2},{value:"Verifying Correct Contract Behavior",id:"verifying-correct-contract-behavior",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"testing-smart-contracts-with-nctl",children:"Testing Smart Contracts with NCTL"})}),"\n",(0,s.jsxs)(n.p,{children:["NCTL effectively simulates a live Casper network. The process for sending a ",(0,s.jsx)(n.code,{children:"Deploy"})," to an NCTL-based network is therefore similar to doing so on a live network."]}),"\n",(0,s.jsxs)(n.p,{children:["Testing ",(0,s.jsx)(n.code,{children:"Deploys"})," prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"writing your smart contract"})," and testing it ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"using the provided framework"}),", NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code."]}),"\n",(0,s.jsx)(n.h2,{id:"getting-started-with-nctl",children:"Getting Started with NCTL"}),"\n",(0,s.jsxs)(n.p,{children:["Prior to testing a ",(0,s.jsx)(n.code,{children:"Deploy"})," through NCTL, you should have the following steps accomplished:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Completed writing a Deploy"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"Tested the Deploy"})," using the Casper testing framework"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"Setup NCTL"})," on your system"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"nctl-verification-prior-to-testing",children:"NCTL Verification Prior to Testing"}),"\n",(0,s.jsx)(n.p,{children:"Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-status\n"})}),"\n",(0,s.jsxs)(n.p,{children:["You should see five nodes ",(0,s.jsx)(n.code,{children:"RUNNING"})," and five ",(0,s.jsx)(n.code,{children:"STOPPED"}),". Further, verify that the node and user information propagated within the ",(0,s.jsx)(n.em,{children:"casper-node/utils/assets"})," directory. Each node and user should have the associated ",(0,s.jsx)(n.code,{children:"Keys"})," necessary to interact with the network. Run the following command to view first user details:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"nctl-view-user-account user=1\n"})}),"\n",(0,s.jsx)(n.h2,{id:"installing-the-smart-contract",children:"Installing the Smart Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This document assumes that you setup your NCTL network using the standard settings in a directory called ",(0,s.jsx)(n.em,{children:"/casper/"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["You will need the following information to use the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", in this case ",(0,s.jsx)(n.code,{children:"casper-net-1"}),". This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"secret key"})," of the account sending the ",(0,s.jsx)(n.code,{children:"Deploy"}),". For this example, we are using node-1 as the sender. The secret key file can be found at ",(0,s.jsx)(n.em,{children:"casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". In our example put-deploy, this will appear as ",(0,s.jsx)(n.code,{children:"--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem"}),". If your Deploy is more complex and requires multiple accounts, NCTL also establishes multiple users for testing."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"payment amount"})," in motes, which should be sufficient to avoid an 'Out of Gas' error. The payment amount will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--payment-amount 2500000000"}),". ",(0,s.jsxs)(n.strong,{children:["NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys#a-note-about-gas-price",children:"note about gas prices"}),"."]})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"path"})," to your ",(0,s.jsx)(n.code,{children:"Deploy"})," that you wish to send to the NCTL network. This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--session-path <PATH>"})," and will require you to define the path to your specific ",(0,s.jsx)(n.code,{children:"Deploy"})," Wasm."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"})," for a node on your NCTL network. In this example, we are using the node at ",(0,s.jsx)(n.code,{children:"http://localhost:11101"}),". On the Casper Mainnet or Testnet, nodes will use port ",(0,s.jsx)(n.code,{children:"7777"}),". This will appear in our example put-deploy as ",(0,s.jsx)(n.code,{children:"--node-address http://<HOST>:7777"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command to send your ",(0,s.jsx)(n.code,{children:"Deploy"})," should look similar to the following code snippet:"]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Use of the ",(0,s.jsx)(n.code,{children:"$(get_path_to_client)"})," command assumes that you are operating in an activated NCTL envrionment."]})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$(get_path_to_client) put-deploy \\\n--chain-name "casper-net-1" \\\n--secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-path <PATH> \\\n--node-address http://localhost:11101\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The response will return something similar to the following information. Note the ",(0,s.jsx)(n.code,{children:"deploy_hash"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'{\n "id": 4824893960188648146,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-deploy-execution",children:"Verifying Deploy Execution"}),"\n",(0,s.jsxs)(n.p,{children:["The previous command sent the ",(0,s.jsx)(n.code,{children:"Deploy"})," to the NCTL network, but we recommend verifying deploy execution before continuing. The ",(0,s.jsx)(n.code,{children:"deploy_hash"})," received in the response allows you to query the ",(0,s.jsx)(n.code,{children:"Deploy"}),"'s status."]}),"\n",(0,s.jsxs)(n.p,{children:["To query the ",(0,s.jsx)(n.code,{children:"Deploy"}),"'s status, you will pass both the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," and the same ",(0,s.jsx)(n.code,{children:"node-address"})," from above using the following command. This will return either an error message in the event of failure or the ",(0,s.jsx)(n.code,{children:"Deploy"})," details if it succeeds."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.h2,{id:"interacting-with-the-installed-contract",children:"Interacting with the Installed Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Once your NCTL network executes your ",(0,s.jsx)(n.code,{children:"Deploy"}),", you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ",(0,s.jsx)(n.code,{children:"ContractHash"})," itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to ",(0,s.jsxs)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:["send the ",(0,s.jsx)(n.code,{children:"Deploy"})]}),", we can retrieve the ",(0,s.jsx)(n.code,{children:"ContractHash"})," from the node-1 account information. To do so, we will use the following command with a node address and the ",(0,s.jsx)(n.code,{children:"PublicKey"})," of the node in question."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"$(get_path_to_client) get-account-info \\\n--node-address http://localhost:11101 \\\n--public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem\n"})}),"\n",(0,s.jsxs)(n.p,{children:["This command will return information pertaining to the account, including the ",(0,s.jsx)(n.code,{children:"NamedKeys"}),". The ",(0,s.jsx)(n.code,{children:"ContractHash"})," of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a ",(0,s.jsx)(n.code,{children:"Deploy"}),". In this instance, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:"--node-address http://localhost:11101"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"chain name"}),", entered in this instance using ",(0,s.jsx)(n.code,{children:'--chain-name "casper-net-1"'})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"payment amount"})," for this ",(0,s.jsx)(n.code,{children:"Deploy"})," in motes, which may need to be adjusted depending on cost and network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". In this instance, we will use ",(0,s.jsx)(n.code,{children:"--payment-amount 500000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"session path"}),", defining the location of the Wasm bearing file for the ",(0,s.jsx)(n.code,{children:"Deploy"}),". It appears in our example as ",(0,s.jsx)(n.code,{children:"--session-path <PATH>"})," but you must define the path to your specific file."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Any ",(0,s.jsx)(n.strong,{children:"session arguments"})," specific to the contract that you are testing. Multiple instances of ",(0,s.jsx)(n.code,{children:"--session-arg"})," may be used as necessary to provide values to the contract, including the ",(0,s.jsx)(n.code,{children:"ContractHash"})," you acquired above. In the example below, you will see a demonstration of the ",(0,s.jsx)(n.code,{children:"ContractHash"})," as a session argument as ",(0,s.jsx)(n.code,{children:"--session-arg \"contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'\""})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'$(get_path_to_client) put-deploy \\\n--node-address http://localhost:11101 \\\n--chain-name "casper-net-1" \\\n--payment-amount 500000000 \\\n--session-path <PATH> \\\n--session-arg "contract_key:key=\'hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a\'"\n'})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-correct-contract-behavior",children:"Verifying Correct Contract Behavior"}),"\n",(0,s.jsxs)(n.p,{children:["After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts#querying-global-state",children:"global state"}),". Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"basic smart contract tutorial"}),", the NCTL process would have the following flow:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Send a ",(0,s.jsx)(n.code,{children:"Deploy"}),' to install the "Donation" smart contract.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Verify the execution of the ",(0,s.jsx)(n.code,{children:"Deploy"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Interact with the installed contract using an additional ",(0,s.jsx)(n.code,{children:"Deploy"})," that calls one or several of the entry points. For example, calling the ",(0,s.jsx)(n.code,{children:"donate"})," entry point to donate an amount to the fundraising purse."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse."}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>c});var s=t(96540);const o={},i=s.createContext(o);function r(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bc4bfdf0.65012c91.js b/assets/js/bc4bfdf0.65012c91.js deleted file mode 100644 index 83ea835e5..000000000 --- a/assets/js/bc4bfdf0.65012c91.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6476],{82008:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="X",a={id:"concepts/glossary/X",title:"X",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/X.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/X",permalink:"/concepts/glossary/X",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"W",permalink:"/concepts/glossary/W"},next:{title:"Y",permalink:"/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"x",children:"X"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/bc4bfdf0.6b70cee0.js b/assets/js/bc4bfdf0.6b70cee0.js new file mode 100644 index 000000000..68359be65 --- /dev/null +++ b/assets/js/bc4bfdf0.6b70cee0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36476],{82008:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="X",a={id:"concepts/glossary/X",title:"X",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/X.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/X",permalink:"/1.5.X/concepts/glossary/X",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"W",permalink:"/1.5.X/concepts/glossary/W"},next:{title:"Y",permalink:"/1.5.X/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"x",children:"X"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/bcd2587d.f268cb4c.js b/assets/js/bcd2587d.f268cb4c.js new file mode 100644 index 000000000..1c21d0a24 --- /dev/null +++ b/assets/js/bcd2587d.f268cb4c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11378],{15569:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>t,metadata:()=>c,toc:()=>o});var d=r(74848),s=r(28453);const t={},i="Casper JSON-RPC Error Codes",c={id:"developers/json-rpc/errors",title:"Casper JSON-RPC Error Codes",description:"The following document expands on custom error codes provided by casper-json-rpc crate.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/errors.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/errors",permalink:"/2.0.0/developers/json-rpc/errors",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{}},l={},o=[{value:"Error Codes",id:"error-codes",level:2},{value:"Invalid <code>Params</code>",id:"invalid-params",level:2}];function h(e){const n={code:"code",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(n.header,{children:(0,d.jsx)(n.h1,{id:"casper-json-rpc-error-codes",children:"Casper JSON-RPC Error Codes"})}),"\n",(0,d.jsxs)(n.p,{children:["The following document expands on custom error codes provided by ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," crate."]}),"\n",(0,d.jsx)(n.h2,{id:"error-codes",children:"Error Codes"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,d.jsxs)(n.table,{children:[(0,d.jsx)(n.thead,{children:(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.th,{children:"Code"}),(0,d.jsx)(n.th,{children:"Error"}),(0,d.jsx)(n.th,{children:"Description"})]})}),(0,d.jsxs)(n.tbody,{children:[(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-1"}),(0,d.jsx)(n.td,{children:"NoSuchDeploy"}),(0,d.jsx)(n.td,{children:"The requested Deploy was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-2"}),(0,d.jsx)(n.td,{children:"NoSuchBlock"}),(0,d.jsx)(n.td,{children:"The requested Block was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-3"}),(0,d.jsx)(n.td,{children:"FailedToParseQueryKey"}),(0,d.jsx)(n.td,{children:"Parsing the Key from a query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-4"}),(0,d.jsx)(n.td,{children:"QueryFailed"}),(0,d.jsx)(n.td,{children:"The query failed to find a result."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-5"}),(0,d.jsx)(n.td,{children:"QueryFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-6"}),(0,d.jsx)(n.td,{children:"FailedToParseGetBalanceURef"}),(0,d.jsx)(n.td,{children:"Parsing the URef while getting a balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-7"}),(0,d.jsx)(n.td,{children:"FailedToGetBalance"}),(0,d.jsx)(n.td,{children:"Failed to get the requested balance."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-8"}),(0,d.jsx)(n.td,{children:"GetBalanceFailedToExecute"}),(0,d.jsx)(n.td,{children:"Executing the query to retrieve the balance failed."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-9"}),(0,d.jsx)(n.td,{children:"InvalidDeploy"}),(0,d.jsx)(n.td,{children:"The given Deploy cannot be executed as it is invalid."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-10"}),(0,d.jsx)(n.td,{children:"NoSuchAccount"}),(0,d.jsx)(n.td,{children:"The given account was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-11"}),(0,d.jsx)(n.td,{children:"FailedToGetDictionaryURef"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary URef."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-12"}),(0,d.jsx)(n.td,{children:"FailedToGetTrie"}),(0,d.jsx)(n.td,{children:"Failed to get the requested dictionary trie."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-13"}),(0,d.jsx)(n.td,{children:"NoSuchStateRoot"}),(0,d.jsx)(n.td,{children:"The requested state root hash was not found."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32600"}),(0,d.jsx)(n.td,{children:"InvalidRequest"}),(0,d.jsx)(n.td,{children:"The JSON sent is not a valid Request object."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32601"}),(0,d.jsx)(n.td,{children:"MethodNotFound"}),(0,d.jsx)(n.td,{children:"The method does not exist or is not available."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32602"}),(0,d.jsx)(n.td,{children:"InvalidParams"}),(0,d.jsx)(n.td,{children:"Invalid method parameter(s)"})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32603"}),(0,d.jsx)(n.td,{children:"InternalError"}),(0,d.jsx)(n.td,{children:"Internal JSON-RPC error."})]}),(0,d.jsxs)(n.tr,{children:[(0,d.jsx)(n.td,{children:"-32700"}),(0,d.jsx)(n.td,{children:"ParseError"}),(0,d.jsx)(n.td,{children:"Invalid JSON was received by the server."})]})]})]}),"\n",(0,d.jsxs)(n.h2,{id:"invalid-params",children:["Invalid ",(0,d.jsx)(n.code,{children:"Params"})]}),"\n",(0,d.jsxs)(n.p,{children:["The ",(0,d.jsx)(n.code,{children:"casper-json-rpc"})," no longer ignores invalid ",(0,d.jsx)(n.code,{children:"params"})," fields. ",(0,d.jsx)(n.code,{children:"Params"})," fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent."]}),"\n",(0,d.jsxs)(n.p,{children:["Failing to adhere to this will result in an ",(0,d.jsx)(n.code,{children:"InvalidParams"})," error."]})]})}function a(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,d.jsx)(n,{...e,children:(0,d.jsx)(h,{...e})}):h(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var d=r(96540);const s={},t=d.createContext(s);function i(e){const n=d.useContext(t);return d.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),d.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd7d26b2.4f702e53.js b/assets/js/bd7d26b2.4f702e53.js new file mode 100644 index 000000000..5581aa130 --- /dev/null +++ b/assets/js/bd7d26b2.4f702e53.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93708],{2509:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Unbonding"},o="Unbonding as a Validator",r={id:"operators/becoming-a-validator/unbonding",title:"Unbonding",description:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/unbonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/unbonding",permalink:"/1.5.X/operators/becoming-a-validator/unbonding",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Unbonding"},sidebar:"operators",previous:{title:"Bonding",permalink:"/1.5.X/operators/becoming-a-validator/bonding"},next:{title:"Recovery",permalink:"/1.5.X/operators/becoming-a-validator/recovering"}},c={},d=[{value:"Method 1: Unbonding with the System Auction Contract",id:"withdraw-system-auction",level:2},{value:"Method 2: Unbonding with Compiled Wasm",id:"withdraw-compiled-wasm",level:2},{value:"Check the Auction Contract",id:"check-the-auction-contract",level:2},{value:"Unbonding Wait Period",id:"unbonding-wait-period",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"unbonding-as-a-validator",children:"Unbonding as a Validator"})}),"\n",(0,s.jsx)(n.p,{children:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction."}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-system-auction",children:"Method 1: Unbonding with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method withdraws a bid using the system auction contract. Call the existing ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,s.jsx)(n.strong,{children:"Adjust all the values to your use case."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-compiled-wasm",children:"Method 2: Unbonding with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["There is a second way to withdraw a bid, using the compiled Wasm ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The process is the same as bonding but uses a different contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes estimated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"})," expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["Here is an example request to unbond stake using the ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"check-the-auction-contract",children:"Check the Auction Contract"}),"\n",(0,s.jsx)(n.p,{children:"Check the auction contract for updates to the bid amounts."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"unbonding-wait-period",children:"Unbonding Wait Period"}),"\n",(0,s.jsx)(n.p,{children:"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bd7d26b2.6860a437.js b/assets/js/bd7d26b2.6860a437.js deleted file mode 100644 index 976c27afc..000000000 --- a/assets/js/bd7d26b2.6860a437.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3708],{2509:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>a,metadata:()=>r,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Unbonding"},o="Unbonding as a Validator",r={id:"operators/becoming-a-validator/unbonding",title:"Unbonding",description:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/unbonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/unbonding",permalink:"/operators/becoming-a-validator/unbonding",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Unbonding"},sidebar:"operators",previous:{title:"Bonding",permalink:"/operators/becoming-a-validator/bonding"},next:{title:"Recovery",permalink:"/operators/becoming-a-validator/recovering"}},c={},d=[{value:"Method 1: Unbonding with the System Auction Contract",id:"withdraw-system-auction",level:2},{value:"Method 2: Unbonding with Compiled Wasm",id:"withdraw-compiled-wasm",level:2},{value:"Check the Auction Contract",id:"check-the-auction-contract",level:2},{value:"Unbonding Wait Period",id:"unbonding-wait-period",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"unbonding-as-a-validator",children:"Unbonding as a Validator"})}),"\n",(0,s.jsx)(n.p,{children:"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction."}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-system-auction",children:"Method 1: Unbonding with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method withdraws a bid using the system auction contract. Call the existing ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point withdraw_bid \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example command uses the Casper Testnet to withdraw 5 CSPR from the bid:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Below is the same command with the optional purse set to a different purse where the amount will be returned. ",(0,s.jsx)(n.strong,{children:"Adjust all the values to your use case."})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point withdraw_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[5 * 1000000000]'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"withdraw-compiled-wasm",children:"Method 2: Unbonding with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["There is a second way to withdraw a bid, using the compiled Wasm ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The process is the same as bonding but uses a different contract."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH>/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--session-arg=\"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg=\"amount:u512='<AMOUNT_TO_WITHDRAW>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes estimated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"})," expects two arguments, while the third one is optional:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse to withdraw. This key must match the secret key that signs the deploy and has to match the public key of a bid in the auction contract"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount being withdrawn"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,s.jsx)(n.code,{children:"withdraw_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["Here is an example request to unbond stake using the ",(0,s.jsx)(n.code,{children:"withdraw_bid.wasm"}),". The payment amount specified is 4 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/withdraw_bid.wasm \\\n--payment-amount 4000000000 \\\n--session-arg=\"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg=\"amount:u512='1000000000000'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"check-the-auction-contract",children:"Check the Auction Contract"}),"\n",(0,s.jsx)(n.p,{children:"Check the auction contract for updates to the bid amounts."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,s.jsx)(n.h2,{id:"unbonding-wait-period",children:"Unbonding Wait Period"}),"\n",(0,s.jsx)(n.p,{children:"To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours."})]})}function l(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/be0df356.4be5fb84.js b/assets/js/be0df356.4be5fb84.js new file mode 100644 index 000000000..23066c813 --- /dev/null +++ b/assets/js/be0df356.4be5fb84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52048],{97636:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>r});var t=a(74848),i=a(28453);const s={title:"Bonding"},d="Bonding as a Validator",o={id:"operators/becoming-a-validator/bonding",title:"Bonding",description:"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.",source:"@site/docs/operators/becoming-a-validator/bonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/bonding",permalink:"/operators/becoming-a-validator/bonding",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Bonding"},sidebar:"operators",previous:{title:"Becoming a Validator",permalink:"/operators/becoming-a-validator/"},next:{title:"Unbonding",permalink:"/operators/becoming-a-validator/unbonding"}},c={},r=[{value:"Method 1: Bonding with the System Auction Contract",id:"bonding-system-auction",level:2},{value:"Method 2: Bonding with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Checking the Bid Status",id:"check-the-status-of-the-bid-in-the-auction",level:2},{value:"A Losing Bid",id:"losing-bid",level:2},{value:"Avoiding Ejection",id:"avoiding-ejection",level:2},{value:"Withdrawing a Bid",id:"withdrawing-a-bid",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bonding-as-a-validator",children:"Bonding as a Validator"})}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," contract. The auction runs for a future era, every era. The ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era."]}),"\n",(0,t.jsxs)(n.p,{children:["In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, ",(0,t.jsx)(n.strong,{children:"the time for bid submission to inclusion in the validator set is a minimum of six hours"}),". Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-system-auction",children:"Method 1: Bonding with the System Auction Contract"}),"\n",(0,t.jsxs)(n.p,{children:["This method submits a bid using the system auction contract. Call the existing ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID_AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.p,{children:"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"#check-the-status-of-the-bid-in-the-auction",children:"check the status of the auction"})," to see if you have won a validator slot."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Bonding with Compiled Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". For details, refer to ",(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following deploy is a template for sending a bonding request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID-AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public_key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example request to bond using the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Next, check the bid status to see if you have won a validator slot."}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status-of-the-bid-in-the-auction",children:"Checking the Bid Status"}),"\n",(0,t.jsxs)(n.p,{children:["Since the bid was submitted using a deploy like any other, perform ",(0,t.jsx)(n.code,{children:"get-deploy"})," using the ",(0,t.jsx)(n.code,{children:"casper-client"}),", to see the execution status."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example auction info response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Note the ",(0,t.jsx)(n.code,{children:"era_id"})," and the ",(0,t.jsx)(n.code,{children:"validator_weights"})," in the response above. The current era is the one with the lowest ID in the ",(0,t.jsx)(n.code,{children:"era_validators"})," array. For a given ",(0,t.jsx)(n.code,{children:"era_id"}),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,t.jsx)(n.code,{children:"validator_weights"})," structure for an era, then the account is bonded in that era."]}),"\n",(0,t.jsx)(n.h2,{id:"losing-bid",children:"A Losing Bid"}),"\n",(0,t.jsx)(n.p,{children:"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-ejection",children:"Avoiding Ejection"}),"\n",(0,t.jsxs)(n.p,{children:["To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"withdrawing-a-bid",children:"Withdrawing a Bid"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the steps in ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"Unbonding"})," to withdraw a bid."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>o});var t=a(96540);const i={},s=t.createContext(i);function d(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/be0df356.811aeaeb.js b/assets/js/be0df356.811aeaeb.js deleted file mode 100644 index 1eeec33e2..000000000 --- a/assets/js/be0df356.811aeaeb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2048],{97636:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>r});var t=a(74848),i=a(28453);const s={title:"Bonding"},d="Bonding as a Validator",o={id:"operators/becoming-a-validator/bonding",title:"Bonding",description:"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.",source:"@site/docs/operators/becoming-a-validator/bonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/bonding",permalink:"/next/operators/becoming-a-validator/bonding",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Bonding"},sidebar:"operators",previous:{title:"Becoming a Validator",permalink:"/next/operators/becoming-a-validator/"},next:{title:"Unbonding",permalink:"/next/operators/becoming-a-validator/unbonding"}},c={},r=[{value:"Method 1: Bonding with the System Auction Contract",id:"bonding-system-auction",level:2},{value:"Method 2: Bonding with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Checking the Bid Status",id:"check-the-status-of-the-bid-in-the-auction",level:2},{value:"A Losing Bid",id:"losing-bid",level:2},{value:"Avoiding Ejection",id:"avoiding-ejection",level:2},{value:"Withdrawing a Bid",id:"withdrawing-a-bid",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bonding-as-a-validator",children:"Bonding as a Validator"})}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," contract. The auction runs for a future era, every era. The ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era."]}),"\n",(0,t.jsxs)(n.p,{children:["In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, ",(0,t.jsx)(n.strong,{children:"the time for bid submission to inclusion in the validator set is a minimum of six hours"}),". Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-system-auction",children:"Method 1: Bonding with the System Auction Contract"}),"\n",(0,t.jsxs)(n.p,{children:["This method submits a bid using the system auction contract. Call the existing ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID_AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.p,{children:"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"#check-the-status-of-the-bid-in-the-auction",children:"check the status of the auction"})," to see if you have won a validator slot."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Bonding with Compiled Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". For details, refer to ",(0,t.jsx)(n.a,{href:"/next/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following deploy is a template for sending a bonding request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID-AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public_key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example request to bond using the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Next, check the bid status to see if you have won a validator slot."}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status-of-the-bid-in-the-auction",children:"Checking the Bid Status"}),"\n",(0,t.jsxs)(n.p,{children:["Since the bid was submitted using a deploy like any other, perform ",(0,t.jsx)(n.code,{children:"get-deploy"})," using the ",(0,t.jsx)(n.code,{children:"casper-client"}),", to see the execution status."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example auction info response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Note the ",(0,t.jsx)(n.code,{children:"era_id"})," and the ",(0,t.jsx)(n.code,{children:"validator_weights"})," in the response above. The current era is the one with the lowest ID in the ",(0,t.jsx)(n.code,{children:"era_validators"})," array. For a given ",(0,t.jsx)(n.code,{children:"era_id"}),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,t.jsx)(n.code,{children:"validator_weights"})," structure for an era, then the account is bonded in that era."]}),"\n",(0,t.jsx)(n.h2,{id:"losing-bid",children:"A Losing Bid"}),"\n",(0,t.jsx)(n.p,{children:"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-ejection",children:"Avoiding Ejection"}),"\n",(0,t.jsxs)(n.p,{children:["To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/recovering",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"withdrawing-a-bid",children:"Withdrawing a Bid"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the steps in ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/unbonding",children:"Unbonding"})," to withdraw a bid."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>o});var t=a(96540);const i={},s=t.createContext(i);function d(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/be5e85f4.e6fa4137.js b/assets/js/be5e85f4.e6fa4137.js new file mode 100644 index 000000000..c99f9b7b7 --- /dev/null +++ b/assets/js/be5e85f4.e6fa4137.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64325],{52133:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},l="Quickstart",c={id:"resources/quick-start",title:"Quickstart",description:"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.",source:"@site/docs/resources/quick-start.md",sourceDirName:"resources",slug:"/resources/quick-start",permalink:"/resources/quick-start",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"tutorials",next:{title:"Overview",permalink:"/resources/tutorials/beginner/"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps",id:"steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Consult the ",(0,t.jsx)(n.a,{href:"/writing-contracts",children:"complete documentation"})," for context and additional help."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"rustup --version"}),". Restart the shell if needed."]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"cmake"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"cmake --version"}),".\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["On Ubuntu, you can follow ",(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"this guide"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["On MacOS, use this command: ",(0,t.jsx)(n.code,{children:"brew install cmake"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install ",(0,t.jsx)(n.code,{children:"cargo-casper"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["You have download ",(0,t.jsx)(n.a,{href:"https://git-scm.com/download/",children:"Git"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Install Cargo Casper with this command:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install cargo-casper"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"}),":"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install casper-client"})}),"\n",(0,t.jsx)(n.p,{children:"If you have issues installing the casper-client, you may need additional libraries."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On Ubuntu:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Make sure you also have the development packages of ",(0,t.jsx)(n.code,{children:"openssl"})," installed. For example, ",(0,t.jsx)(n.code,{children:"libssl-dev"})," on Ubuntu or ",(0,t.jsx)(n.code,{children:"openssl-devel"})," on Fedora."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Test the ",(0,t.jsx)(n.code,{children:"casper-client"})," by ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," on the network and getting the latest ",(0,t.jsx)(n.a,{href:"/concepts/glossary/S#state-root-hash",children:"state root hash"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://65.21.235.219:7777\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Casper Account"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clone a simple counter contract or download it from GitHub:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/casper-ecosystem/counter"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the folder and prepare the dependencies to build the contract:"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd counter\nmake prepare\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsx)(n.li,{children:"Build the contract and tests:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make test"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Install the contract on Testnet using the ",(0,t.jsx)(n.code,{children:"casper-client"}),"'s ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name casper-test \\\n--secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \\\n--payment-amount 30000000000 \\\n--session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsx)(n.li,{children:"Check the deploy status given the deploy hash from the previous command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"Get the latest state root hash:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsx)(n.li,{children:"Open the deploy tab of the account on the Testnet to see the deploy details."}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"As an alternative to step 15, check your account using the command line:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["As another alternative, use the account hash for the ",(0,t.jsx)(n.code,{children:"--key"})," argument. To get the account hash, look at the account details on the block explorer, or run this command:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, query the blockchain using the account hash:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsx)(n.li,{children:'Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let\'s make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example output:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"17",children:["\n",(0,t.jsxs)(n.li,{children:["Now increment the count value by calling the entry point ",(0,t.jsx)(n.code,{children:"counter_inc"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [PATH_TO_YOUR_KEY] \\\n--payment-amount 100000000 \\\n--session-name "counter" \\\n--session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"18",children:["\n",(0,t.jsxs)(n.li,{children:["Get the NEW ",(0,t.jsx)(n.code,{children:"state root hash"}),", to get the latest snapshot of the blockchain state \u2013 this is EXTREMELY IMPORTANT!"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"19",children:["\n",(0,t.jsx)(n.li,{children:"Query the state of the network."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:'If everything went according to plan, the value should be 1. Look at the "parsed" value below.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 1\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/be5e85f4.f95550ce.js b/assets/js/be5e85f4.f95550ce.js deleted file mode 100644 index c898d11e2..000000000 --- a/assets/js/be5e85f4.f95550ce.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4325],{52133:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>i});var t=s(74848),r=s(28453);const a={},l="Quickstart",c={id:"resources/quick-start",title:"Quickstart",description:"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.",source:"@site/docs/resources/quick-start.md",sourceDirName:"resources",slug:"/resources/quick-start",permalink:"/next/resources/quick-start",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"tutorials",next:{title:"Overview",permalink:"/next/resources/tutorials/beginner/"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Steps",id:"steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"quickstart",children:"Quickstart"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),". Consult the ",(0,t.jsx)(n.a,{href:"/writing-contracts",children:"complete documentation"})," for context and additional help."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"Rust"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"rustup --version"}),". Restart the shell if needed."]}),"\n",(0,t.jsxs)(n.li,{children:["You have installed ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"cmake"}),". Verify the installation with this command: ",(0,t.jsx)(n.code,{children:"cmake --version"}),".\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["On Ubuntu, you can follow ",(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"this guide"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["On MacOS, use this command: ",(0,t.jsx)(n.code,{children:"brew install cmake"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["You have an integrated development environment (IDE). On Windows, you will need to download the C++ build developer tools, without which you cannot install ",(0,t.jsx)(n.code,{children:"cargo-casper"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["You have download ",(0,t.jsx)(n.a,{href:"https://git-scm.com/download/",children:"Git"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"steps",children:"Steps"}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Install Cargo Casper with this command:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install cargo-casper"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper client"}),":"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"cargo install casper-client"})}),"\n",(0,t.jsx)(n.p,{children:"If you have issues installing the casper-client, you may need additional libraries."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"On Ubuntu:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note:"})," Make sure you also have the development packages of ",(0,t.jsx)(n.code,{children:"openssl"})," installed. For example, ",(0,t.jsx)(n.code,{children:"libssl-dev"})," on Ubuntu or ",(0,t.jsx)(n.code,{children:"openssl-devel"})," on Fedora."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Test the ",(0,t.jsx)(n.code,{children:"casper-client"})," by ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," on the network and getting the latest ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S#state-root-hash",children:"state root hash"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://65.21.235.219:7777\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up a ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"Casper Account"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Clone a simple counter contract or download it from GitHub:"}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"git clone https://github.com/casper-ecosystem/counter"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Navigate to the folder and prepare the dependencies to build the contract:"}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd counter\nmake prepare\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsx)(n.li,{children:"Build the contract and tests:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.code,{children:"make test"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Install the contract on Testnet using the ",(0,t.jsx)(n.code,{children:"casper-client"}),"'s ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Replace the secret key with your path. Record the deploy hash from the output. This example uses 30 CSPR to pay for contract installation on chain. You may need to adjust this value based on the latest Testnet ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name casper-test \\\n--secret-key [YOUR_PATH_TO_SECRET_KEY_FILE] \\\n--payment-amount 30000000000 \\\n--session-path contracts/counter-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsx)(n.li,{children:"Check the deploy status given the deploy hash from the previous command:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address [NODE_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"Get the latest state root hash:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsx)(n.li,{children:"Open the deploy tab of the account on the Testnet to see the deploy details."}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"As an alternative to step 15, check your account using the command line:"}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["As another alternative, use the account hash for the ",(0,t.jsx)(n.code,{children:"--key"})," argument. To get the account hash, look at the account details on the block explorer, or run this command:"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, query the blockchain using the account hash:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsx)(n.li,{children:'Now, you can play with the smart contract and increment the value it manages from 0 to 1. First, let\'s make sure the value is 0. Look at the "parsed" value returned in the output. An expected example output is shown below.'}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example output:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 0\n }\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"17",children:["\n",(0,t.jsxs)(n.li,{children:["Now increment the count value by calling the entry point ",(0,t.jsx)(n.code,{children:"counter_inc"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n--node-address [NODE_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [PATH_TO_YOUR_KEY] \\\n--payment-amount 100000000 \\\n--session-name "counter" \\\n--session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.ol,{start:"18",children:["\n",(0,t.jsxs)(n.li,{children:["Get the NEW ",(0,t.jsx)(n.code,{children:"state root hash"}),", to get the latest snapshot of the blockchain state \u2013 this is EXTREMELY IMPORTANT!"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_ADDRESS]\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"19",children:["\n",(0,t.jsx)(n.li,{children:"Query the state of the network."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client query-state \\\n--node-address [NODE_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH] \\\n-q "counter/count"\n'})}),"\n",(0,t.jsx)(n.p,{children:'If everything went according to plan, the value should be 1. Look at the "parsed" value below.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n"id": 8523290678829319485,\n"jsonrpc": "2.0",\n"result": {\n "api_version": "1.4.6",\n "block_header": null,\n "merkle_proof": "[85716 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "01000000",\n "cl_type": "I32",\n "parsed": 1\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts."})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function l(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:l(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/befad559.50157083.js b/assets/js/befad559.50157083.js new file mode 100644 index 000000000..b42231dd2 --- /dev/null +++ b/assets/js/befad559.50157083.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51968],{16247:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var r=s(74848),t=s(28453);const a={title:"Overview"},i="Concepts Overview",o={id:"concepts/index",title:"Overview",description:"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.",source:"@site/versioned_docs/version-1.5.X/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/1.5.X/concepts/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview"},sidebar:"concepts",next:{title:"What is Casper?",permalink:"/1.5.X/"}},c={},d=[{value:"Concepts",id:"concepts",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3},{value:"Users",id:"users",level:3},{value:"Resources",id:"resources",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"concepts-overview",children:"Concepts Overview"})}),"\n",(0,r.jsxs)(n.p,{children:["The Casper blockchain is a ",(0,r.jsx)(n.a,{href:"/1.5.X/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"Casper Mainnet"})," is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described ",(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup-network/",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/",children:"Introduction to the Casper Blockchain"})}),(0,r.jsx)(n.td,{children:"High-level details about the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/intro-to-dapps",children:"Introduction to dApps"})}),(0,r.jsx)(n.td,{children:"Developing distributed applications on the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})}),(0,r.jsx)(n.td,{children:"The Casper programming model is account-based. Learn how Casper accounts work and how they are secured"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/hash-types",children:"Hash Types"})}),(0,r.jsx)(n.td,{children:"Hashes are used throughout the Casper ecosystem for keys, addresses, packaging data, and more"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Global State"})}),(0,r.jsx)(n.td,{children:"Learn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/callstack",children:"Call Stacks"})}),(0,r.jsx)(n.td,{children:"Learn how Casper manages the calling of a contract"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/deploy-and-deploy-lifecycle",children:"Deploys and the Deploy Lifecycle"})}),(0,r.jsx)(n.td,{children:"Deploys are a concept fundamental to the Casper blockchain. Learn about deploys, what they are for, how to create and send them"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/smart-contracts",children:"Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Learn how to develop smart contracts on Casper"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/dictionaries",children:"Dictionaries"})}),(0,r.jsx)(n.td,{children:"Learn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization"})}),(0,r.jsx)(n.td,{children:"Learn about serializing data types and the Casper Serialization Standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/design",children:"Design"})}),(0,r.jsx)(n.td,{children:"The high-level design of a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/economics",children:"Economics"})}),(0,r.jsx)(n.td,{children:"Learn about the Casper on-chain economics"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/glossary",children:"Glossary"})}),(0,r.jsx)(n.td,{children:"A compendium of all the terms used in Casper, in alphabetical order"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,r.jsx)(n.p,{children:"After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories."}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/1.5.X/developers",children:"Developers"})," area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/1.5.X/operators",children:"Operators"})," section caters to those who want to run and administrate a Casper node or network."]}),"\n",(0,r.jsx)(n.h3,{id:"users",children:"Users"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/1.5.X/users/",children:"Users"})," section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device."]}),"\n",(0,r.jsx)(n.h3,{id:"resources",children:"Resources"}),"\n",(0,r.jsxs)(n.p,{children:["Navigate to ",(0,r.jsx)(n.a,{href:"/1.5.X/resources/",children:"Resources"})," to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the ",(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/",children:"beginner tutorials"}),". Afterward, continue with more ",(0,r.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/",children:"advanced tutorials"})," to explore the multi-signature feature, runtime return values, and other essential features."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var r=s(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/befad559.b54dfbe5.js b/assets/js/befad559.b54dfbe5.js deleted file mode 100644 index 9b4c937ac..000000000 --- a/assets/js/befad559.b54dfbe5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1968],{16247:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>d});var r=s(74848),t=s(28453);const a={title:"Overview"},i="Concepts Overview",o={id:"concepts/index",title:"Overview",description:"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.",source:"@site/versioned_docs/version-1.5.X/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/concepts/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview"},sidebar:"concepts",next:{title:"What is Casper?",permalink:"/"}},c={},d=[{value:"Concepts",id:"concepts",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3},{value:"Users",id:"users",level:3},{value:"Resources",id:"resources",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"concepts-overview",children:"Concepts Overview"})}),"\n",(0,r.jsxs)(n.p,{children:["The Casper blockchain is a ",(0,r.jsx)(n.a,{href:"/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"Casper Mainnet"})," is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described ",(0,r.jsx)(n.a,{href:"/operators/setup-network/",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/",children:"Introduction to the Casper Blockchain"})}),(0,r.jsx)(n.td,{children:"High-level details about the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/intro-to-dapps",children:"Introduction to dApps"})}),(0,r.jsx)(n.td,{children:"Developing distributed applications on the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})}),(0,r.jsx)(n.td,{children:"The Casper programming model is account-based. Learn how Casper accounts work and how they are secured"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/hash-types",children:"Hash Types"})}),(0,r.jsx)(n.td,{children:"Hashes are used throughout the Casper ecosystem for keys, addresses, packaging data, and more"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"})}),(0,r.jsx)(n.td,{children:"Learn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/callstack",children:"Call Stacks"})}),(0,r.jsx)(n.td,{children:"Learn how Casper manages the calling of a contract"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/deploy-and-deploy-lifecycle",children:"Deploys and the Deploy Lifecycle"})}),(0,r.jsx)(n.td,{children:"Deploys are a concept fundamental to the Casper blockchain. Learn about deploys, what they are for, how to create and send them"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Learn how to develop smart contracts on Casper"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/dictionaries",children:"Dictionaries"})}),(0,r.jsx)(n.td,{children:"Learn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/serialization-standard",children:"Serialization"})}),(0,r.jsx)(n.td,{children:"Learn about serializing data types and the Casper Serialization Standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/design",children:"Design"})}),(0,r.jsx)(n.td,{children:"The high-level design of a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/economics",children:"Economics"})}),(0,r.jsx)(n.td,{children:"Learn about the Casper on-chain economics"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/glossary",children:"Glossary"})}),(0,r.jsx)(n.td,{children:"A compendium of all the terms used in Casper, in alphabetical order"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,r.jsx)(n.p,{children:"After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories."}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/developers",children:"Developers"})," area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/operators",children:"Operators"})," section caters to those who want to run and administrate a Casper node or network."]}),"\n",(0,r.jsx)(n.h3,{id:"users",children:"Users"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/users/",children:"Users"})," section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device."]}),"\n",(0,r.jsx)(n.h3,{id:"resources",children:"Resources"}),"\n",(0,r.jsxs)(n.p,{children:["Navigate to ",(0,r.jsx)(n.a,{href:"/resources/",children:"Resources"})," to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the ",(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/",children:"beginner tutorials"}),". Afterward, continue with more ",(0,r.jsx)(n.a,{href:"/resources/tutorials/advanced/",children:"advanced tutorials"})," to explore the multi-signature feature, runtime return values, and other essential features."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>o});var r=s(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bf5bbaf8.13f23cdc.js b/assets/js/bf5bbaf8.13f23cdc.js new file mode 100644 index 000000000..ca5df1b38 --- /dev/null +++ b/assets/js/bf5bbaf8.13f23cdc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66607],{19903:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var n=r(74848),o=r(28453);const s={title:"Introduction",slug:"/counter-testnet"},i="A Counter on the Testnet",a={id:"resources/beginner/counter-testnet/index",title:"Introduction",description:"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/docs/resources/beginner/counter-testnet/index.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/counter-testnet",permalink:"/counter-testnet",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Introduction",slug:"/counter-testnet"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter/walkthrough"},next:{title:"Overview",permalink:"/resources/beginner/counter-testnet/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"a-counter-on-the-testnet",children:"A Counter on the Testnet"})}),"\n",(0,n.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a ",(0,n.jsx)(t.a,{href:"/counter",children:"similar tutorial"})," and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,n.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"/resources/beginner/counter-testnet/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:["You have completed the ",(0,n.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,n.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,n.jsx)(t.em,{children:"cargo"}),", and ",(0,n.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,n.jsxs)(t.li,{children:["You have installed the ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n",(0,n.jsxs)(t.li,{children:["You were able to ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#setting-up-an-account",children:"set up and fund an account"})," on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["The location of your account\u2019s ",(0,n.jsx)(t.strong,{children:"secret_key.pem"})," file"]}),"\n",(0,n.jsxs)(t.li,{children:["Your ",(0,n.jsx)(t.strong,{children:"account hash"})," identifier"]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["You ",(0,n.jsx)(t.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"selected a node"})," whose RPC port will be receiving the transactions coming from your account."]}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,n.jsx)(t.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,n.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rWaUiFFEyaY&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=3",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(u,{...e})}):u(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>i,x:()=>a});var n=r(96540);const o={},s=n.createContext(o);function i(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bf5bbaf8.79578d9c.js b/assets/js/bf5bbaf8.79578d9c.js deleted file mode 100644 index 1fd3e4679..000000000 --- a/assets/js/bf5bbaf8.79578d9c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6607],{19903:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(74848),o=n(28453);const s={title:"Introduction",slug:"/counter-testnet"},i="A Counter on the Testnet",a={id:"resources/beginner/counter-testnet/index",title:"Introduction",description:"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/docs/resources/beginner/counter-testnet/index.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/counter-testnet",permalink:"/next/counter-testnet",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Introduction",slug:"/counter-testnet"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/next/resources/beginner/counter/walkthrough"},next:{title:"Overview",permalink:"/next/resources/beginner/counter-testnet/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Video Tutorial",id:"video-tutorial",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"a-counter-on-the-testnet",children:"A Counter on the Testnet"})}),"\n",(0,r.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a ",(0,r.jsx)(t.a,{href:"/next/counter",children:"similar tutorial"})," and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,r.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/next/resources/beginner/counter-testnet/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["You have completed the ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,r.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,r.jsx)(t.em,{children:"cargo"}),", and ",(0,r.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["You have installed the ",(0,r.jsx)(t.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n",(0,r.jsxs)(t.li,{children:["You were able to ",(0,r.jsx)(t.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"set up and fund an account"})," on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The location of your account\u2019s ",(0,r.jsx)(t.strong,{children:"secret_key.pem"})," file"]}),"\n",(0,r.jsxs)(t.li,{children:["Your ",(0,r.jsx)(t.strong,{children:"account hash"})," identifier"]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["You ",(0,r.jsx)(t.a,{href:"/next/developers/prerequisites#acquire-node-address-from-network-peers",children:"selected a node"})," whose RPC port will be receiving the transactions coming from your account."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"video-tutorial",children:"Video Tutorial"}),"\n",(0,r.jsx)(t.p,{children:"If you prefer a video walkthrough of this guide, you can check out this video."}),"\n",(0,r.jsx)(t.iframe,{width:"560",height:"315",src:"https://www.youtube.com/embed?v=rWaUiFFEyaY&list=PL8oWxbJ-csEogSV-M0IPiofWP5I_dLji6&index=3",frameBorder:"0",allow:"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bfb3244a.0a60faf8.js b/assets/js/bfb3244a.0a60faf8.js new file mode 100644 index 000000000..50a8c0392 --- /dev/null +++ b/assets/js/bfb3244a.0a60faf8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[78445],{14966:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>i,frontMatter:()=>r,metadata:()=>h,toc:()=>c});var o=n(74848),t=n(28453);const r={},a="Python SDK",h={id:"developers/dapps/sdk/python-sdk",title:"Python SDK",description:"The Python SDK allows developers to interact with the Casper platform using Python 3.12+.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/python-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/python-sdk",permalink:"/1.5.X/developers/dapps/sdk/python-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Go SDK",permalink:"/1.5.X/developers/dapps/sdk/go-sdk"},next:{title:"dApp Technology Stack",permalink:"/1.5.X/developers/dapps/technology-stack"}},l={},c=[{value:"Installation",id:"installation",level:2},{value:"How To's",id:"how-tos",level:2},{value:"Cryptography",id:"cryptography",level:3},{value:"Deploys",id:"deploys",level:3},{value:"Smart Contracts",id:"smart-contracts",level:3},{value:"Node APIs",id:"node-apis",level:3}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"python-sdk",children:"Python SDK"})}),"\n",(0,o.jsxs)(s.p,{children:["The ",(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk",children:"Python SDK"})," allows developers to interact with the Casper platform using Python 3.12+."]}),"\n",(0,o.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"pip3 install pycspr\n"})}),"\n",(0,o.jsx)(s.h2,{id:"how-tos",children:"How To's"}),"\n",(0,o.jsxs)(s.p,{children:["The following set of How To's cover the full SDK feature set and are designed to be run against a ",(0,o.jsx)(s.a,{href:"https://github.com/casper-network/cctl",children:"CCTL"})," network."]}),"\n",(0,o.jsx)(s.h3,{id:"cryptography",children:"Cryptography"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_apply_a_checksum.py",children:"How To: Apply a checksum"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_create_key_pairs.py",children:"How To: Create Key Pairs"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_hash_data.py",children:"How To: Hash data"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_sign_data.py",children:"How To: Sign data"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"deploys",children:"Deploys"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_transfer.py",children:"How To: Transfer funds between 2 accounts"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_delegate.py",children:"How To: Delegate funds to a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_undelegate.py",children:"How To: Undelegate funds from a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_stake.py",children:"How To: Stake funds as a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_unstake.py",children:"How To: Unstake funds as a validator"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"smart-contracts",children:"Smart Contracts"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_install.py",children:"How To: Install a smart contract"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_invoke.py",children:"How To: Invoke a smart contract"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_query.py",children:"How To: Query a smart contract"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"node-apis",children:"Node APIs"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_rest_client.py",children:"How To: Use REST API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_rpc_client.py",children:"How To: Use RPC API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_speculative_rpc_client.py",children:"How To: Use Speculative RPC API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_sse_client.py",children:"How To: Use SSE API"})}),"\n"]}),"\n"]})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>h});var o=n(96540);const t={},r=o.createContext(t);function a(e){const s=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function h(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),o.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bfb3244a.40640614.js b/assets/js/bfb3244a.40640614.js deleted file mode 100644 index 67a17d262..000000000 --- a/assets/js/bfb3244a.40640614.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8445],{14966:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>i,frontMatter:()=>r,metadata:()=>h,toc:()=>c});var o=n(74848),t=n(28453);const r={},a="Python SDK",h={id:"developers/dapps/sdk/python-sdk",title:"Python SDK",description:"The Python SDK allows developers to interact with the Casper platform using Python 3.12+.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/python-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/python-sdk",permalink:"/developers/dapps/sdk/python-sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Go SDK",permalink:"/developers/dapps/sdk/go-sdk"},next:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"}},l={},c=[{value:"Installation",id:"installation",level:2},{value:"How To's",id:"how-tos",level:2},{value:"Cryptography",id:"cryptography",level:3},{value:"Deploys",id:"deploys",level:3},{value:"Smart Contracts",id:"smart-contracts",level:3},{value:"Node APIs",id:"node-apis",level:3}];function p(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(s.header,{children:(0,o.jsx)(s.h1,{id:"python-sdk",children:"Python SDK"})}),"\n",(0,o.jsxs)(s.p,{children:["The ",(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk",children:"Python SDK"})," allows developers to interact with the Casper platform using Python 3.12+."]}),"\n",(0,o.jsx)(s.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(s.pre,{children:(0,o.jsx)(s.code,{className:"language-bash",children:"pip3 install pycspr\n"})}),"\n",(0,o.jsx)(s.h2,{id:"how-tos",children:"How To's"}),"\n",(0,o.jsxs)(s.p,{children:["The following set of How To's cover the full SDK feature set and are designed to be run against a ",(0,o.jsx)(s.a,{href:"https://github.com/casper-network/cctl",children:"CCTL"})," network."]}),"\n",(0,o.jsx)(s.h3,{id:"cryptography",children:"Cryptography"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_apply_a_checksum.py",children:"How To: Apply a checksum"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_create_key_pairs.py",children:"How To: Create Key Pairs"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_hash_data.py",children:"How To: Hash data"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/crypto/how_to_sign_data.py",children:"How To: Sign data"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"deploys",children:"Deploys"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_transfer.py",children:"How To: Transfer funds between 2 accounts"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_delegate.py",children:"How To: Delegate funds to a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_undelegate.py",children:"How To: Undelegate funds from a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_stake.py",children:"How To: Stake funds as a validator"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/deploys/how_to_unstake.py",children:"How To: Unstake funds as a validator"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"smart-contracts",children:"Smart Contracts"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_install.py",children:"How To: Install a smart contract"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_invoke.py",children:"How To: Invoke a smart contract"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/smart_contracts/how_to_query.py",children:"How To: Query a smart contract"})}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(s.h3,{id:"node-apis",children:"Node APIs"}),"\n",(0,o.jsxs)(s.ul,{children:["\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_rest_client.py",children:"How To: Use REST API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_rpc_client.py",children:"How To: Use RPC API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_speculative_rpc_client.py",children:"How To: Use Speculative RPC API"})}),"\n"]}),"\n",(0,o.jsxs)(s.li,{children:["\n",(0,o.jsx)(s.p,{children:(0,o.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/blob/main/how_tos/node_apis/how_to_use_sse_client.py",children:"How To: Use SSE API"})}),"\n"]}),"\n"]})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,o.jsx)(s,{...e,children:(0,o.jsx)(p,{...e})}):p(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>h});var o=n(96540);const t={},r=o.createContext(t);function a(e){const s=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function h(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),o.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c00ffc57.c6e16365.js b/assets/js/c00ffc57.c6e16365.js new file mode 100644 index 000000000..60b71945f --- /dev/null +++ b/assets/js/c00ffc57.c6e16365.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32985],{97554:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>l});var r=n(74848),c=n(28453);const o={},t="T",a={id:"concepts/glossary/T",title:"T",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/T.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/T",permalink:"/2.0.0/concepts/glossary/T",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"S",permalink:"/2.0.0/concepts/glossary/S"},next:{title:"U",permalink:"/2.0.0/concepts/glossary/U"}},i={},l=[{value:"Token",id:"token",level:2},{value:"Transaction",id:"transaction",level:2},{value:"Turing-complete blockchain",id:"turing-complete-blockchain",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"t",children:"T"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"token",children:"Token"}),"\n",(0,r.jsxs)(s.p,{children:["A type of cryptocurrency that represents an asset. See ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C#cspr",children:"CSPR"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"transaction",children:"Transaction"}),"\n",(0,r.jsxs)(s.p,{children:["Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a ",(0,r.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D#deploy",children:"Deploy"}),". Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found ",(0,r.jsx)(s.a,{href:"/2.0.0/transactions",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"turing-complete-blockchain",children:"Turing-complete blockchain"}),"\n",(0,r.jsx)(s.p,{children:"Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets."}),"\n",(0,r.jsx)(s.p,{children:"For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference."})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>t,x:()=>a});var r=n(96540);const c={},o=r.createContext(c);function t(e){const s=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),r.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0299000.60ccb8d1.js b/assets/js/c0299000.60ccb8d1.js new file mode 100644 index 000000000..520ad72c9 --- /dev/null +++ b/assets/js/c0299000.60ccb8d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35890],{8077:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const i={title:"Monitoring Events with the Casper Sidecar"},a="Monitoring and Consuming Events",c={id:"developers/dapps/monitor-and-consume-events",title:"Monitoring Events with the Casper Sidecar",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.",source:"@site/docs/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/developers/dapps/monitor-and-consume-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Monitoring Events with the Casper Sidecar"},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/developers/cli/"}},o={},d=[{value:"The Casper Sidecar",id:"the-casper-sidecar",level:2},{value:"The Event Stream",id:"the-event-stream",level:2},{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:3},{value:"Detecting Contract-Level Events",id:"contract-level-events",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:3},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:3},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:3},{value:"Replaying the Sidecar Event Stream",id:"replaying-the-sidecar-event-stream",level:3},{value:"The JSON-RPC API",id:"the-json-rpc-api",level:2},{value:"The REST API",id:"the-rest-api",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"monitoring-and-consuming-events",children:"Monitoring and Consuming Events"})}),"\n",(0,s.jsxs)(n.p,{children:["The Casper platform uses ",(0,s.jsx)(n.a,{href:"/operators/setup/node-events",children:"event streaming"})," to signal state changes in smart contracts and nodes. Using the ",(0,s.jsx)(n.a,{href:"#the-casper-sidecar",children:"Casper Sidecar"})," service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data."]}),"\n",(0,s.jsxs)(n.p,{children:["Smart contracts can also emit contract-level events, as explained ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/emitting-contract-events",children:"here"}),". DApps can consume these events by listening to the event stream, detecting ",(0,s.jsx)(n.a,{href:"#contract-level-events",children:"TransactionProcessed"})," events, and parsing the ",(0,s.jsx)(n.code,{children:"messages"})," array storing String-representations of the emitted events."]}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-sidecar",children:"The Casper Sidecar"}),"\n",(0,s.jsx)(n.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar supports the following functionalities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,s.jsx)(n.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture",src:t(52321).A+"",width:"1416",height:"978"})}),"\n",(0,s.jsxs)(n.p,{children:["Visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/",children:"GitHub"})," for the latest source code and information on:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"System architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"Configuring the Sidecar"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"Running and testing"})," the Sidecar"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#swagger-documentation",children:"Swagger documentation"})," for its REST API"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#openapi-specification",children:"OpenAPI schema"})," for the JSON-RPC API"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Troubleshooting tips"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-event-stream",children:"The Event Stream"}),"\n",(0,s.jsx)(n.p,{children:"Casper nodes offer an event stream API that returns server-sent events (SSEs) with JSON-encoded data. The Sidecar reads the event stream of all connected nodes, acting as a passthrough and replicating the SSE interface of the connected nodes."}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Republish the current events from the node to clients listening to Sidecar's SSE API."}),"\n",(0,s.jsxs)(n.li,{children:["Publish a configurable number of previous events to clients connecting to the Sidecar's SSE API with ",(0,s.jsx)(n.code,{children:"?start_from="})," query (similar to the node's SSE API)."]}),"\n",(0,s.jsx)(n.li,{children:"Store the events in external storage so clients can query them via the REST API."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar also provides an endpoint for Sidecar-generated events that can be useful, although the node did not emit them."}),"\n",(0,s.jsx)(n.p,{children:"To summarize, events are divided into two categories and emitted on their respective endpoints:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Node-generated events"})," - All events coming from connected node(s) are emitted on the ",(0,s.jsx)(n.code,{children:"events"})," endpoint. The default URL to consume these events on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Sidecar-generated events"})," - The Sidecar also emits events on the ",(0,s.jsx)(n.code,{children:"events/sidecar"})," endpoint, designated for events originating solely from the Sidecar service. The URL to consume these events using Sidecar on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/sidecar/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes each event type in detail."]}),"\n",(0,s.jsx)(n.h3,{id:"listening-to-the-event-stream",children:"Listening to the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["Set up an event listener in your dApp using the following code to consume the event stream. The ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"})," is the address of the node where the Sidecar was installed. The ",(0,s.jsx)(n.code,{children:"PORT"})," is the address where the Sidecar streams events. It is ",(0,s.jsx)(n.code,{children:"19999"})," by default, but you must find out how the Sidecar was configured."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const { EventStream, EventName } = require("casper-js-sdk")\n\nconst es = new EventStream("http://NODE_ADDRESS:PORT/events/")\nes.start()\nes.subscribe(EventName.EVENT_NAME, eventHandler)\n\nconst eventHandler = (event) => {\n console.log(event)\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'from pycspr import NodeClient, NodeConnection, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = "PORT"))\nclient.get_events(eventHandler, NodeEventType.EVENT_NAME)\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You can find node addresses of active online peers to replace ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", by navigating to ",(0,s.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," for Mainnet and ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"})," for Testnet."]}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"EVENT_NAME"})," with one of the event types listed ",(0,s.jsx)(n.a,{href:"#event-types",children:"below"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"contract-level-events",children:"Detecting Contract-Level Events"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. For more details, see ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/emitting-contract-events#verifying-a-topic",children:"Verifying a Topic"})," and ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/emitting-contract-events#verifying-a-message",children:"Verifying a Message"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"reacting-to-events",children:"Reacting to Events"}),"\n",(0,s.jsxs)(n.p,{children:["An application may parse each event needed for its use case and respond accordingly. Each event type contains additional data that might help decide whether to take action. For example, ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," events contain the account's public key that submitted the transaction, the contract address, and more. This information can help determine how to proceed."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const eventHandler = (event) => {\n if (event.body.TransactionAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'def eventHandler(event):\n if event["TransactionAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"unsubscribing-from-events",children:"Unsubscribing from Events"}),"\n",(0,s.jsxs)(n.p,{children:["In many cases, an application may need to unsubscribe after a particular time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,s.jsx)(n.code,{children:"unsubscribe"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.unsubscribe(EventName.EVENT_NAME)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"EVENT_NAME"})," - One of the different ",(0,s.jsx)(n.a,{href:"#event-types",children:"event types"})," emitted by a Casper node."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"stopping-the-event-stream",children:"Stopping the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["A dApp may cease listening to all events using the ",(0,s.jsx)(n.code,{children:"stop"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.stop()\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"replaying-the-sidecar-event-stream",children:"Replaying the Sidecar Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["This command will replay the event stream from an old event onward. Replace the ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", ",(0,s.jsx)(n.code,{children:"PORT"}),", and ",(0,s.jsx)(n.code,{children:"ID"})," fields with the values of your scenario."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Note that certain shells like ",(0,s.jsx)(n.code,{children:"zsh"})," may require an escape character before the question mark:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The server will replay all the cached events if the ID is 0 or if you specify an event ID already purged from the cache."}),"\n",(0,s.jsx)(n.h2,{id:"the-json-rpc-api",children:"The JSON-RPC API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar also offers a JSON-RPC API server for clients to interact with a Casper network. It is a JSON bridge between end users and a Casper node's binary port, forwarding requests to the Casper node's binary port. For more details on how the JSON-RPC API works, see the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"the-rest-api",children:"The REST API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar offers a REST API to query stored events. You can discover the specific endpoints of the REST API using ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#openapi-specification",children:"OpenAPI"})," and ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#swagger-documentation",children:"Swagger"}),". The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"usage instructions"})," in the repository provide more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 1",src:t(3980).A+"",width:"2236",height:"1332"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 2",src:t(72455).A+"",width:"2174",height:"1512"})}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,s.jsxs)(n.p,{children:["For troubleshooting tips, visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},52321:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},3980:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-1-a36838588d0ad1e623d89de2acb93e87.png"},72455:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-2-7d8a480884403e1f40c31b6e901976a7.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0299000.a0ce979e.js b/assets/js/c0299000.a0ce979e.js deleted file mode 100644 index a437e9198..000000000 --- a/assets/js/c0299000.a0ce979e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5890],{8077:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>l,frontMatter:()=>i,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const i={title:"Monitoring Events with the Casper Sidecar"},a="Monitoring and Consuming Events",c={id:"developers/dapps/monitor-and-consume-events",title:"Monitoring Events with the Casper Sidecar",description:"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.",source:"@site/docs/developers/dapps/monitor-and-consume-events.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/monitor-and-consume-events",permalink:"/next/developers/dapps/monitor-and-consume-events",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Monitoring Events with the Casper Sidecar"},sidebar:"developers",previous:{title:"Local Network Testing",permalink:"/next/developers/dapps/nctl-test"},next:{title:"Interacting with the Blockchain",permalink:"/next/developers/cli/"}},o={},d=[{value:"The Casper Sidecar",id:"the-casper-sidecar",level:2},{value:"The Event Stream",id:"the-event-stream",level:2},{value:"Listening to the Event Stream",id:"listening-to-the-event-stream",level:3},{value:"Detecting Contract-Level Events",id:"contract-level-events",level:3},{value:"Reacting to Events",id:"reacting-to-events",level:3},{value:"Unsubscribing from Events",id:"unsubscribing-from-events",level:3},{value:"Stopping the Event Stream",id:"stopping-the-event-stream",level:3},{value:"Replaying the Sidecar Event Stream",id:"replaying-the-sidecar-event-stream",level:3},{value:"The JSON-RPC API",id:"the-json-rpc-api",level:2},{value:"The REST API",id:"the-rest-api",level:2},{value:"Troubleshooting Tips",id:"troubleshooting-tips",level:2}];function h(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"monitoring-and-consuming-events",children:"Monitoring and Consuming Events"})}),"\n",(0,s.jsxs)(n.p,{children:["The Casper platform uses ",(0,s.jsx)(n.a,{href:"/next/operators/setup/node-events",children:"event streaming"})," to signal state changes in smart contracts and nodes. Using the ",(0,s.jsx)(n.a,{href:"#the-casper-sidecar",children:"Casper Sidecar"})," service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data."]}),"\n",(0,s.jsxs)(n.p,{children:["Smart contracts can also emit contract-level events, as explained ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/emitting-contract-events",children:"here"}),". DApps can consume these events by listening to the event stream, detecting ",(0,s.jsx)(n.a,{href:"#contract-level-events",children:"TransactionProcessed"})," events, and parsing the ",(0,s.jsx)(n.code,{children:"messages"})," array storing String-representations of the emitted events."]}),"\n",(0,s.jsx)(n.h2,{id:"the-casper-sidecar",children:"The Casper Sidecar"}),"\n",(0,s.jsx)(n.p,{children:"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar supports the following functionalities:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-sse-server",children:"server-sent events (SSE) endpoint"})," with an ",(0,s.jsx)(n.code,{children:"/events"})," endpoint streaming events from all the connected nodes. The Sidecar also stores these events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rest-api-server",children:"REST API server"})," that allows clients to query stored events."]}),"\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#the-rpc-api-server",children:"JSON-RPC API"})," to interact with a Casper node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/LEGACY_SSE_EMULATION.md",children:"Legacy emulation"})," for clients using older versions of the SSE API."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture",src:t(85627).A+"",width:"1416",height:"978"})}),"\n",(0,s.jsxs)(n.p,{children:["Visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/",children:"GitHub"})," for the latest source code and information on:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#system-components--architecture",children:"System architecture"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#configuring-the-sidecar",children:"Configuring the Sidecar"})}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#running-and-testing-the-sidecar",children:"Running and testing"})," the Sidecar"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#swagger-documentation",children:"Swagger documentation"})," for its REST API"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#openapi-specification",children:"OpenAPI schema"})," for the JSON-RPC API"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Troubleshooting tips"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"the-event-stream",children:"The Event Stream"}),"\n",(0,s.jsx)(n.p,{children:"Casper nodes offer an event stream API that returns server-sent events (SSEs) with JSON-encoded data. The Sidecar reads the event stream of all connected nodes, acting as a passthrough and replicating the SSE interface of the connected nodes."}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar can:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Republish the current events from the node to clients listening to Sidecar's SSE API."}),"\n",(0,s.jsxs)(n.li,{children:["Publish a configurable number of previous events to clients connecting to the Sidecar's SSE API with ",(0,s.jsx)(n.code,{children:"?start_from="})," query (similar to the node's SSE API)."]}),"\n",(0,s.jsx)(n.li,{children:"Store the events in external storage so clients can query them via the REST API."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The Sidecar also provides an endpoint for Sidecar-generated events that can be useful, although the node did not emit them."}),"\n",(0,s.jsx)(n.p,{children:"To summarize, events are divided into two categories and emitted on their respective endpoints:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Node-generated events"})," - All events coming from connected node(s) are emitted on the ",(0,s.jsx)(n.code,{children:"events"})," endpoint. The default URL to consume these events on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Sidecar-generated events"})," - The Sidecar also emits events on the ",(0,s.jsx)(n.code,{children:"events/sidecar"})," endpoint, designated for events originating solely from the Sidecar service. The URL to consume these events using Sidecar on a Mainnet or Testnet node is usually ",(0,s.jsx)(n.code,{children:"http://HOST:19999/events/sidecar/"}),". This URL depends on how the Sidecar was configured on the node."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"Casper Sidecar Usage Guide"})," describes each event type in detail."]}),"\n",(0,s.jsx)(n.h3,{id:"listening-to-the-event-stream",children:"Listening to the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["Set up an event listener in your dApp using the following code to consume the event stream. The ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"})," is the address of the node where the Sidecar was installed. The ",(0,s.jsx)(n.code,{children:"PORT"})," is the address where the Sidecar streams events. It is ",(0,s.jsx)(n.code,{children:"19999"})," by default, but you must find out how the Sidecar was configured."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const { EventStream, EventName } = require("casper-js-sdk")\n\nconst es = new EventStream("http://NODE_ADDRESS:PORT/events/")\nes.start()\nes.subscribe(EventName.EVENT_NAME, eventHandler)\n\nconst eventHandler = (event) => {\n console.log(event)\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'from pycspr import NodeClient, NodeConnection, NodeEventType\n\ndef eventHandler(event):\n print(event)\n\nclient = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = "PORT"))\nclient.get_events(eventHandler, NodeEventType.EVENT_NAME)\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events/\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["You can find node addresses of active online peers to replace ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", by navigating to ",(0,s.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"cspr.live"})," for Mainnet and ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"testnet.cspr.live"})," for Testnet."]}),"\n",(0,s.jsxs)(n.p,{children:["Replace ",(0,s.jsx)(n.code,{children:"EVENT_NAME"})," with one of the event types listed ",(0,s.jsx)(n.a,{href:"#event-types",children:"below"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"contract-level-events",children:"Detecting Contract-Level Events"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event after the corresponding block is processed and added to the blockchain. For more details, see ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/emitting-contract-events#verifying-a-topic",children:"Verifying a Topic"})," and ",(0,s.jsx)(n.a,{href:"/next/developers/writing-onchain-code/emitting-contract-events#verifying-a-message",children:"Verifying a Message"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"reacting-to-events",children:"Reacting to Events"}),"\n",(0,s.jsxs)(n.p,{children:["An application may parse each event needed for its use case and respond accordingly. Each event type contains additional data that might help decide whether to take action. For example, ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," events contain the account's public key that submitted the transaction, the contract address, and more. This information can help determine how to proceed."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:'const eventHandler = (event) => {\n if (event.body.TransactionAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {\n // Perform an action\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.tabitem,{value:"python",label:"Python",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-python",children:'def eventHandler(event):\n if event["TransactionAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":\n # Perform an action\n'})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"unsubscribing-from-events",children:"Unsubscribing from Events"}),"\n",(0,s.jsxs)(n.p,{children:["In many cases, an application may need to unsubscribe after a particular time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the ",(0,s.jsx)(n.code,{children:"unsubscribe"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.unsubscribe(EventName.EVENT_NAME)\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"EVENT_NAME"})," - One of the different ",(0,s.jsx)(n.a,{href:"#event-types",children:"event types"})," emitted by a Casper node."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"stopping-the-event-stream",children:"Stopping the Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["A dApp may cease listening to all events using the ",(0,s.jsx)(n.code,{children:"stop"})," function:"]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"js",label:"JavaScript",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-javascript",children:"es.stop()\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"replaying-the-sidecar-event-stream",children:"Replaying the Sidecar Event Stream"}),"\n",(0,s.jsxs)(n.p,{children:["This command will replay the event stream from an old event onward. Replace the ",(0,s.jsx)(n.code,{children:"NODE_ADDRESS"}),", ",(0,s.jsx)(n.code,{children:"PORT"}),", and ",(0,s.jsx)(n.code,{children:"ID"})," fields with the values of your scenario."]}),"\n",(0,s.jsxs)(n.tabs,{children:["\n",(0,s.jsxs)(n.tabitem,{value:"curl",label:"cURL",children:["\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://NODE_ADDRESS:PORT/events?start_from=ID\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Note that certain shells like ",(0,s.jsx)(n.code,{children:"zsh"})," may require an escape character before the question mark:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -sN http://65.21.235.219:19999/events?start_from=29267508\n"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The server will replay all the cached events if the ID is 0 or if you specify an event ID already purged from the cache."}),"\n",(0,s.jsx)(n.h2,{id:"the-json-rpc-api",children:"The JSON-RPC API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar also offers a JSON-RPC API server for clients to interact with a Casper network. It is a JSON bridge between end users and a Casper node's binary port, forwarding requests to the Casper node's binary port. For more details on how the JSON-RPC API works, see the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/json_rpc/README.md",children:"JSON-RPC README"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"the-rest-api",children:"The REST API"}),"\n",(0,s.jsxs)(n.p,{children:["The Sidecar offers a REST API to query stored events. You can discover the specific endpoints of the REST API using ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#openapi-specification",children:"OpenAPI"})," and ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/tree/feat-2.0?tab=readme-ov-file#swagger-documentation",children:"Swagger"}),". The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/USAGE.md",children:"usage instructions"})," in the repository provide more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 1",src:t(98730).A+"",width:"2236",height:"1332"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Sidecar components and architecture diagram 2",src:t(70094).A+"",width:"2174",height:"1512"})}),"\n",(0,s.jsx)(n.h2,{id:"troubleshooting-tips",children:"Troubleshooting Tips"}),"\n",(0,s.jsxs)(n.p,{children:["For troubleshooting tips, visit ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-sidecar/blob/feat-2.0/README.md#troubleshooting-tips",children:"Github"}),"."]})]})}function l(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},85627:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-diagram-92779ddba3ccba102b935c8144e6e6a8.png"},98730:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-1-a36838588d0ad1e623d89de2acb93e87.png"},70094:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/sidecar-swagger-2-7d8a480884403e1f40c31b6e901976a7.png"},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>c});var s=t(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c0def98a.5774eed0.js b/assets/js/c0def98a.5774eed0.js new file mode 100644 index 000000000..de7b9060d --- /dev/null +++ b/assets/js/c0def98a.5774eed0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61669],{79173:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>s,default:()=>l,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var r=n(74848),a=n(28453);const o={},s="Calling Contracts",c={id:"developers/writing-onchain-code/calling-contracts",title:"Calling Contracts",description:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.",source:"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/calling-contracts.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/calling-contracts",permalink:"/2.0.0/developers/writing-onchain-code/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Upgrading and Maintaining Smart Contracts",permalink:"/2.0.0/developers/writing-onchain-code/upgrading-contracts"},next:{title:"Contracts and Session Code",permalink:"/2.0.0/developers/writing-onchain-code/contract-vs-session"}},i={},d=[{value:"Using Legacy Deploy Variants",id:"using-legacy-deploy-variants",level:2},{value:"ModuleBytes",id:"modulebytes",level:3},{value:"StoredContractByHash",id:"storedcontractbyhash",level:3},{value:"StoredContractByName",id:"storedcontractbyname",level:3},{value:"StoredVersionedContractByHash",id:"storedversionedcontractbyhash",level:3},{value:"StoredVersionedContractByName",id:"storedversionedcontractbyname",level:3},{value:"Transfer",id:"transfer",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"calling-contracts",children:"Calling Contracts"})}),"\n",(0,r.jsx)(t.p,{children:"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm."}),"\n",(0,r.jsx)(t.h2,{id:"using-legacy-deploy-variants",children:"Using Legacy Deploy Variants"}),"\n",(0,r.jsx)(t.h3,{id:"modulebytes",children:"ModuleBytes"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"ModuleBytes"})," is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm."]}),"\n",(0,r.jsxs)(t.p,{children:["However, you can also use ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," to deploy session code that calls a contract."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"ModuleBytes"})," can be found in ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#modulebytes",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyhash",children:"StoredContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByHash"})," is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question."]}),"\n",(0,r.jsx)(t.p,{children:"While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract."}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#storedcontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedcontractbyname",children:"StoredContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredContractByName"})," is similar to ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", with the main difference being the reference used to invoke on-chain Wasm. Where ",(0,r.jsx)(t.code,{children:"StoredContractByHash"})," requires the contract hash, ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," uses a string stored as a ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#namedkey",children:(0,r.jsx)(t.code,{children:"NamedKey"})})," in the caller's account."]}),"\n",(0,r.jsxs)(t.p,{children:["This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's ",(0,r.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyhash",children:"StoredVersionedContractByHash"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package."]}),"\n",(0,r.jsxs)(t.p,{children:["This makes ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," more stable than ",(0,r.jsx)(t.code,{children:"StoredContractByHash"}),", as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version."]}),"\n",(0,r.jsxs)(t.p,{children:["DApp developers that use contracts developed by other parties can use ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," to avoid interruptions from contract version changes."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"})," can be found ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#storedversioncontractbyhash",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"storedversionedcontractbyname",children:"StoredVersionedContractByName"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," combines the functionality of ",(0,r.jsx)(t.code,{children:"StoredContractByName"})," and ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByHash"}),". It allows a developer to store a reference string as a ",(0,r.jsx)(t.code,{children:"NamedKey"})," within their account context that references a contract by its contract package hash."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of ",(0,r.jsx)(t.code,{children:"StoredVersionedContractByName"})," can be found ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#storedversioncontractbyname",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"transfer",children:"Transfer"}),"\n",(0,r.jsxs)(t.p,{children:["Native ",(0,r.jsx)(t.code,{children:"Transfer"}),"s are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network."]}),"\n",(0,r.jsxs)(t.p,{children:["Further information on the structure of a native ",(0,r.jsx)(t.code,{children:"Transfer"})," can be found ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#transfer",children:"here"}),"."]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const a={},o=r.createContext(a);function s(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c10b8a9f.7b6997c1.js b/assets/js/c10b8a9f.7b6997c1.js deleted file mode 100644 index 84d039341..000000000 --- a/assets/js/c10b8a9f.7b6997c1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[781],{58107:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const r={title:"Testnet Funding",slug:"/users/testnet-faucet"},o="Funding Testnet Accounts",a={id:"users/csprlive/testnet-faucet",title:"Testnet Funding",description:"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/testnet-faucet.md",sourceDirName:"users/csprlive",slug:"/users/testnet-faucet",permalink:"/users/testnet-faucet",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testnet Funding",slug:"/users/testnet-faucet"},sidebar:"users",previous:{title:"Using CSPR.live",permalink:"/users/csprlive/"},next:{title:"Delegate Tokens",permalink:"/users/delegate-ui"}},c={},l=[{value:"Requesting Testnet Tokens",id:"requesting-testnet-tokens",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"funding-testnet-accounts",children:"Funding Testnet Accounts"})}),"\n",(0,s.jsxs)(t.p,{children:["The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"cspr.live"})," block explorer."]}),"\n",(0,s.jsx)(t.p,{children:"Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below."}),"\n",(0,s.jsx)(t.h3,{id:"requesting-testnet-tokens",children:"Requesting Testnet Tokens"}),"\n",(0,s.jsx)(t.p,{children:"To request test tokens, follow these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Log into the Casper Testnet with the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Click ",(0,s.jsx)(t.strong,{children:"Tools"})," on the top menu bar and select ",(0,s.jsx)(t.strong,{children:"Faucet"})," from the drop-down menu. Or, navigate to the Faucet using this link: ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/faucet",children:"https://testnet.cspr.live/tools/faucet"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Click ",(0,s.jsx)(t.strong,{children:"Request tokens"})," on the Faucet page:"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{src:n(16993).A+"",width:"1379",height:"617"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.admonition,{type:"caution",children:[(0,s.jsxs)(t.p,{children:["Tokens can be requested ",(0,s.jsx)(t.strong,{children:"only once per account"}),". Otherwise, the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/deploy/f0f6b25db767d1a6c2244324661d853ad7d4766f8489d81c36b5e2c9d982891e",children:"deploy will fail"})," with status ",(0,s.jsx)(t.code,{children:"User error: 1"}),"."]}),(0,s.jsxs)(t.p,{children:["If you have already exhausted your test funds, you can always ",(0,s.jsx)(t.a,{href:"/developers/prerequisites#creating-an-account",children:"create a new account"}),"."]})]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:"The Testnet will credit your account with test tokens."}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},16993:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/faucet-function-f3c2d05a9fd17287ec2fb304731a0197.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c10b8a9f.f9001f93.js b/assets/js/c10b8a9f.f9001f93.js new file mode 100644 index 000000000..691a24cbe --- /dev/null +++ b/assets/js/c10b8a9f.f9001f93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60781],{58107:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>l});var s=n(74848),i=n(28453);const r={title:"Testnet Funding",slug:"/users/testnet-faucet"},o="Funding Testnet Accounts",a={id:"users/csprlive/testnet-faucet",title:"Testnet Funding",description:"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.",source:"@site/versioned_docs/version-1.5.X/users/csprlive/testnet-faucet.md",sourceDirName:"users/csprlive",slug:"/users/testnet-faucet",permalink:"/1.5.X/users/testnet-faucet",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Testnet Funding",slug:"/users/testnet-faucet"},sidebar:"users",previous:{title:"Using CSPR.live",permalink:"/1.5.X/users/csprlive/"},next:{title:"Delegate Tokens",permalink:"/1.5.X/users/delegate-ui"}},c={},l=[{value:"Requesting Testnet Tokens",id:"requesting-testnet-tokens",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"funding-testnet-accounts",children:"Funding Testnet Accounts"})}),"\n",(0,s.jsxs)(t.p,{children:["The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"cspr.live"})," block explorer."]}),"\n",(0,s.jsx)(t.p,{children:"Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below."}),"\n",(0,s.jsx)(t.h3,{id:"requesting-testnet-tokens",children:"Requesting Testnet Tokens"}),"\n",(0,s.jsx)(t.p,{children:"To request test tokens, follow these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Log into the Casper Testnet with the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Click ",(0,s.jsx)(t.strong,{children:"Tools"})," on the top menu bar and select ",(0,s.jsx)(t.strong,{children:"Faucet"})," from the drop-down menu. Or, navigate to the Faucet using this link: ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/faucet",children:"https://testnet.cspr.live/tools/faucet"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Click ",(0,s.jsx)(t.strong,{children:"Request tokens"})," on the Faucet page:"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{src:n(58159).A+"",width:"1379",height:"617"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.admonition,{type:"caution",children:[(0,s.jsxs)(t.p,{children:["Tokens can be requested ",(0,s.jsx)(t.strong,{children:"only once per account"}),". Otherwise, the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/deploy/f0f6b25db767d1a6c2244324661d853ad7d4766f8489d81c36b5e2c9d982891e",children:"deploy will fail"})," with status ",(0,s.jsx)(t.code,{children:"User error: 1"}),"."]}),(0,s.jsxs)(t.p,{children:["If you have already exhausted your test funds, you can always ",(0,s.jsx)(t.a,{href:"/1.5.X/developers/prerequisites#creating-an-account",children:"create a new account"}),"."]})]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:"The Testnet will credit your account with test tokens."}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},58159:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/faucet-function-f3c2d05a9fd17287ec2fb304731a0197.png"},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>a});var s=n(96540);const i={},r=s.createContext(i);function o(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c10cfbfe.2a9f53c2.js b/assets/js/c10cfbfe.2a9f53c2.js new file mode 100644 index 000000000..969babd46 --- /dev/null +++ b/assets/js/c10cfbfe.2a9f53c2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[98455],{40260:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var c=s(74848),t=s(28453);const i={title:"Accounts and Keys"},a="Accounts and Cryptographic Keys",r={id:"concepts/accounts-and-keys",title:"Accounts and Keys",description:"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.",source:"@site/docs/concepts/accounts-and-keys.md",sourceDirName:"concepts",slug:"/concepts/accounts-and-keys",permalink:"/concepts/accounts-and-keys",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Accounts and Keys"},sidebar:"concepts",previous:{title:"Addressable Entities",permalink:"/concepts/addressable-entity"},next:{title:"Key Types",permalink:"/concepts/key-types"}},o={},d=[{value:"Creating Accounts and Keys",id:"creating-accounts-and-keys",level:2},{value:"Option 1: Generating keys using the Casper Client",id:"option-1-key-generation-using-the-casper-client",level:3},{value:"EdDSA Keys",id:"eddsa-keys",level:4},{value:"ECDSA Keys",id:"ecdsa-keys",level:4},{value:"Option 2: Generating keys using a block explorer",id:"option-2-key-generation-using-a-block-explorer",level:3},{value:"Funding your Account",id:"funding-your-account",level:2},{value:"Working with Existing Ethereum Keys",id:"working-with-existing-ethereum-keys",level:2},{value:"Option 3: Generating keys using OpenSSL",id:"option-3-generating-keys-using-openssl",level:3},{value:"Generating the <code>secret_key.pem</code> file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the <code>secret_key.pem</code> file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"accounts-and-cryptographic-keys",children:"Accounts and Cryptographic Keys"})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"account-based model"}),", uniquely identified by an ",(0,c.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,c.jsx)(n.code,{children:"PublicKey"}),". The ",(0,c.jsx)(n.code,{children:"AccountHash"})," is a 32-byte hash derived from any of the supported ",(0,c.jsx)(n.code,{children:"PublicKey"})," variants below to standardize keys that can vary in length."]}),"\n",(0,c.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,c.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,c.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#ecdsa-keys",children:"Secp256k1"})," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys using both formats, and it is also possible to ",(0,c.jsx)(n.a,{href:"#working-with-existing-ethereum-keys",children:"work with existing Ethereum keys"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["You can also ",(0,c.jsx)(n.a,{href:"#generating-an-account-hash",children:"generate an account hash"})," from a public key with the Casper command-line client."]}),"\n",(0,c.jsx)(n.h2,{id:"creating-accounts-and-keys",children:"Creating Accounts and Keys"}),"\n",(0,c.jsxs)(n.p,{children:["When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," or a block explorer."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"SAVE your keys to a safe place, preferably offline."})}),"\n",(0,c.jsx)(n.h3,{id:"option-1-key-generation-using-the-casper-client",children:"Option 1: Generating keys using the Casper Client"}),"\n",(0,c.jsx)(n.p,{children:"This option describes how you can use the Casper command-line client to set up an account using either key type."}),"\n",(0,c.jsx)(n.h4,{id:"eddsa-keys",children:"EdDSA Keys"}),"\n",(0,c.jsx)(n.p,{children:"The command-line client generates EdDSA keys by default. Use the command below to create the account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"ed25519-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsx)(n.p,{children:"Here are some details about the files generated:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key.pem"})," is a ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key_hex"})," is a hexadecimal-encoded string of the public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"secret_key.pem"})," is the ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded secret key"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Ed25519"})," keys starts with 01 and is 66 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n"})}),"\n",(0,c.jsx)(n.h4,{id:"ecdsa-keys",children:"ECDSA Keys"}),"\n",(0,c.jsxs)(n.p,{children:["To create ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"secp256k1-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys starts with 02 and is 68 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"After generating keys for the account, you may add funds to the account's purse to finish the account creation process."})}),"\n",(0,c.jsx)(n.h3,{id:"option-2-key-generation-using-a-block-explorer",children:"Option 2: Generating keys using a block explorer"}),"\n",(0,c.jsx)(n.p,{children:"This option is available on networks that have a block explorer."}),"\n",(0,c.jsxs)(n.p,{children:["For instance, on the official Testnet, the ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"CSPR.live"})," block explorer is available, and the following instructions assume you are using it."]}),"\n",(0,c.jsxs)(n.p,{children:["Start by creating an account using the ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),", ",(0,c.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true",children:"Ledger"}),", or ",(0,c.jsx)(n.a,{href:"https://casper.tor.us/",children:"Torus Wallet"}),"."]}),"\n",(0,c.jsx)(n.admonition,{type:"caution",children:(0,c.jsxs)(n.p,{children:["The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/signer-user-start-here",children:"here"}),"."]})}),"\n",(0,c.jsx)(n.h2,{id:"funding-your-account",children:"Funding your Account"}),"\n",(0,c.jsxs)(n.p,{children:["Once you create your account, you can ",(0,c.jsx)(n.a,{href:"/developers/prerequisites#fund-your-account",children:"fund the account's main purse"})," to finish the process of setting it up."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"Until you fund your account's main purse, it does not exist on the blockchain."})}),"\n",(0,c.jsx)(n.h2,{id:"working-with-existing-ethereum-keys",children:"Working with Existing Ethereum Keys"}),"\n",(0,c.jsx)(n.p,{children:"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,c.jsx)(n.code,{children:"Secp256k1"})," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper command-line client provides an example of how this works."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,c.jsx)(n.p,{children:"The following transaction sends 10 CSPR."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key <path-to-secret_key.pem> \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"tip",children:(0,c.jsxs)(n.p,{children:["The payment amount varies based on each transaction and network ",(0,c.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper command-line client requires the secret key in ",(0,c.jsx)(n.em,{children:"PEM"})," format to send a transaction from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,c.jsx)(n.em,{children:"PEM"})," format is needed."]}),"\n",(0,c.jsxs)(n.p,{children:["The following example is a JS script that generates a ",(0,c.jsx)(n.em,{children:"PEM"})," file, using a ",(0,c.jsx)(n.a,{href:"https://github.com/stacks-network/key-encoder-js",children:"key encoder"})," and Node.js. To install these components, do the following:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"sudo apt install nodejs\nnpm install key-encoder\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Then create the JS script ",(0,c.jsx)(n.em,{children:"convert-to-pem.js"})," using ",(0,c.jsx)(n.em,{children:"vi"})," or ",(0,c.jsx)(n.em,{children:"nano"}),", and include this content:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:'var KeyEncoder = require(\'key-encoder\'),\nkeyEncoder = new KeyEncoder.default(\'secp256k1\');\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n'})}),"\n",(0,c.jsx)(n.p,{children:"Then run the script using Node.js and name the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"node convert-to-pem.js > eth-secret.pem\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To view the secret key, use ",(0,c.jsx)(n.code,{children:"cat <filename>"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat eth-secret.pem\n"})}),"\n",(0,c.jsx)(n.p,{children:"Below is the sample output showing the contents of the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n"})}),"\n",(0,c.jsx)(n.h3,{id:"option-3-generating-keys-using-openssl",children:"Option 3: Generating keys using OpenSSL"}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys without the Casper client using the ",(0,c.jsx)(n.a,{href:"https://www.openssl.org/",children:"openssl"})," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."]}),"\n",(0,c.jsxs)(n.h4,{id:"generating-the-secret_keypem-file",children:["Generating the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"openssl genpkey -algorithm ed25519 -out secret_key.pem\n"})}),"\n",(0,c.jsxs)(n.h4,{id:"generating-public-keys-from-the-secret_keypem-file",children:["Generating public keys from the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsxs)(n.p,{children:["For default Ed25519 keys, you can generate the ",(0,c.jsx)(n.code,{children:"public_key.pem"})," and ",(0,c.jsx)(n.code,{children:"public_key_hex"})," using these commands:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n'})}),"\n",(0,c.jsx)(n.h2,{id:"generating-an-account-hash",children:"Generating an Account Hash"}),"\n",(0,c.jsxs)(n.p,{children:["To generate the account hash for a public key, use the ",(0,c.jsx)(n.em,{children:"account-address"})," option of the Casper client. The argument for the ",(0,c.jsx)(n.em,{children:"public-key"})," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,c.jsx)(n.em,{children:"keygen"})," command: ",(0,c.jsx)(n.em,{children:"public_key_hex"})," or ",(0,c.jsx)(n.em,{children:"public_key.pem"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsx)(n.h2,{id:"purse-uref",children:"Finding the Main Purse URef"}),"\n",(0,c.jsx)(n.p,{children:"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."}),"\n",(0,c.jsx)(n.h3,{id:"using-the-casper-cli-client",children:"Using the Casper CLI client"}),"\n",(0,c.jsxs)(n.p,{children:["With the ",(0,c.jsx)(n.code,{children:"casper-client"}),", use the ",(0,c.jsx)(n.code,{children:"get-account-info"})," subcommand."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info \\\n--node-address <HOST:PORT> \\\n--public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public-key"})," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,c.jsx)(n.code,{children:"keygen"}),' subcommand; "public_key_hex" or "public_key.pem"']}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Sample command and output"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Run the following help command for more details:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info --help\n"})}),"\n",(0,c.jsx)(n.h3,{id:"using-a-block-explorer",children:"Using a block explorer"}),"\n",(0,c.jsxs)(n.p,{children:["Using the block explorer for ",(0,c.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," or ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),", open the Account in question, and expand the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section. Look for the ",(0,c.jsx)(n.code,{children:"main_purse"})," field and find the corresponding URef. If you do not see data in the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section, then the account has not been funded yet."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Main purse",src:s(62049).A+"",width:"1576",height:"1494"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},62049:(e,n,s)=>{s.d(n,{A:()=>c});const c=s.p+"assets/images/main_purse_uref-96cffa61cd6ab63f2fb996efe8fc4197.png"},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var c=s(96540);const t={},i=c.createContext(t);function a(e){const n=c.useContext(i);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c10cfbfe.9a85001f.js b/assets/js/c10cfbfe.9a85001f.js deleted file mode 100644 index 182ae5b43..000000000 --- a/assets/js/c10cfbfe.9a85001f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8455],{40260:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var c=s(74848),t=s(28453);const i={title:"Accounts and Keys"},a="Accounts and Cryptographic Keys",r={id:"concepts/accounts-and-keys",title:"Accounts and Keys",description:"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.",source:"@site/docs/concepts/accounts-and-keys.md",sourceDirName:"concepts",slug:"/concepts/accounts-and-keys",permalink:"/next/concepts/accounts-and-keys",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Accounts and Keys"},sidebar:"concepts",previous:{title:"Addressable Entities",permalink:"/next/concepts/addressable-entity"},next:{title:"Key Types",permalink:"/next/concepts/key-types"}},o={},d=[{value:"Creating Accounts and Keys",id:"creating-accounts-and-keys",level:2},{value:"Option 1: Generating keys using the Casper Client",id:"option-1-key-generation-using-the-casper-client",level:3},{value:"EdDSA Keys",id:"eddsa-keys",level:4},{value:"ECDSA Keys",id:"ecdsa-keys",level:4},{value:"Option 2: Generating keys using a block explorer",id:"option-2-key-generation-using-a-block-explorer",level:3},{value:"Funding your Account",id:"funding-your-account",level:2},{value:"Working with Existing Ethereum Keys",id:"working-with-existing-ethereum-keys",level:2},{value:"Option 3: Generating keys using OpenSSL",id:"option-3-generating-keys-using-openssl",level:3},{value:"Generating the <code>secret_key.pem</code> file",id:"generating-the-secret_keypem-file",level:4},{value:"Generating public keys from the <code>secret_key.pem</code> file",id:"generating-public-keys-from-the-secret_keypem-file",level:4},{value:"Generating an Account Hash",id:"generating-an-account-hash",level:2},{value:"Finding the Main Purse URef",id:"purse-uref",level:2},{value:"Using the Casper CLI client",id:"using-the-casper-cli-client",level:3},{value:"Using a block explorer",id:"using-a-block-explorer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"accounts-and-cryptographic-keys",children:"Accounts and Cryptographic Keys"})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain ",(0,c.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"account-based model"}),", uniquely identified by an ",(0,c.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,c.jsx)(n.code,{children:"PublicKey"}),". The ",(0,c.jsx)(n.code,{children:"AccountHash"})," is a 32-byte hash derived from any of the supported ",(0,c.jsx)(n.code,{children:"PublicKey"})," variants below to standardize keys that can vary in length."]}),"\n",(0,c.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,c.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,c.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper platform supports two types of keys for creating accounts and signing transactions:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#eddsa-keys",children:"Ed25519"})," keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.a,{href:"#ecdsa-keys",children:"Secp256k1"})," keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys using both formats, and it is also possible to ",(0,c.jsx)(n.a,{href:"#working-with-existing-ethereum-keys",children:"work with existing Ethereum keys"}),"."]}),"\n",(0,c.jsxs)(n.p,{children:["You can also ",(0,c.jsx)(n.a,{href:"#generating-an-account-hash",children:"generate an account hash"})," from a public key with the Casper command-line client."]}),"\n",(0,c.jsx)(n.h2,{id:"creating-accounts-and-keys",children:"Creating Accounts and Keys"}),"\n",(0,c.jsxs)(n.p,{children:["When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the ",(0,c.jsx)(n.a,{href:"#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"})," or a block explorer."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"SAVE your keys to a safe place, preferably offline."})}),"\n",(0,c.jsx)(n.h3,{id:"option-1-key-generation-using-the-casper-client",children:"Option 1: Generating keys using the Casper Client"}),"\n",(0,c.jsx)(n.p,{children:"This option describes how you can use the Casper command-line client to set up an account using either key type."}),"\n",(0,c.jsx)(n.h4,{id:"eddsa-keys",children:"EdDSA Keys"}),"\n",(0,c.jsx)(n.p,{children:"The command-line client generates EdDSA keys by default. Use the command below to create the account."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir ed25519-keys\ncasper-client keygen ed25519-keys/\ntree ed25519-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"ed25519-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"ed25519-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsx)(n.p,{children:"Here are some details about the files generated:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key.pem"})," is a ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public_key_hex"})," is a hexadecimal-encoded string of the public key"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"secret_key.pem"})," is the ",(0,c.jsx)(n.em,{children:"PEM"}),"-encoded secret key"]}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Ed25519"})," keys starts with 01 and is 66 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat ed25519-keys/public_key_hex\n011724c5c8e2404ca01c872e1bbd9202a0114e5d143760f685086a5cffe261dabd\n"})}),"\n",(0,c.jsx)(n.h4,{id:"ecdsa-keys",children:"ECDSA Keys"}),"\n",(0,c.jsxs)(n.p,{children:["To create ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys, which use the ECDSA algorithm with the P-256 curve, follow these steps:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"mkdir secp256k1-keys\ncasper-client keygen -a secp256k1 secp256k1-keys/\ntree secp256k1-keys/\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Sample output of the ",(0,c.jsx)(n.code,{children:"tree"})," command shows the contents of the ",(0,c.jsx)(n.em,{children:"secp256k1-keys"})," folder:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"secp256k1-keys/\n\u251c\u2500\u2500 public_key.pem\n\u251c\u2500\u2500 public_key_hex\n\u2514\u2500\u2500 secret_key.pem\n\n0 directories, 3 files\n"})}),"\n",(0,c.jsxs)(n.p,{children:["The public-key-hex for ",(0,c.jsx)(n.code,{children:"Secp256k1"})," keys starts with 02 and is 68 bytes long:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat secp256k1-keys/public_key_hex\n020287e1a79d0d9f3196391808a8b3e5007895f43cde679e4c960e7e9b92841bb98d\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"After generating keys for the account, you may add funds to the account's purse to finish the account creation process."})}),"\n",(0,c.jsx)(n.h3,{id:"option-2-key-generation-using-a-block-explorer",children:"Option 2: Generating keys using a block explorer"}),"\n",(0,c.jsx)(n.p,{children:"This option is available on networks that have a block explorer."}),"\n",(0,c.jsxs)(n.p,{children:["For instance, on the official Testnet, the ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"CSPR.live"})," block explorer is available, and the following instructions assume you are using it."]}),"\n",(0,c.jsxs)(n.p,{children:["Start by creating an account using the ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),", ",(0,c.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?support=true",children:"Ledger"}),", or ",(0,c.jsx)(n.a,{href:"https://casper.tor.us/",children:"Torus Wallet"}),"."]}),"\n",(0,c.jsx)(n.admonition,{type:"caution",children:(0,c.jsxs)(n.p,{children:["The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined ",(0,c.jsx)(n.a,{href:"https://www.casperwallet.io/user-guide/signer-user-start-here",children:"here"}),"."]})}),"\n",(0,c.jsx)(n.h2,{id:"funding-your-account",children:"Funding your Account"}),"\n",(0,c.jsxs)(n.p,{children:["Once you create your account, you can ",(0,c.jsx)(n.a,{href:"/next/developers/prerequisites#fund-your-account",children:"fund the account's main purse"})," to finish the process of setting it up."]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsx)(n.p,{children:"Until you fund your account's main purse, it does not exist on the blockchain."})}),"\n",(0,c.jsx)(n.h2,{id:"working-with-existing-ethereum-keys",children:"Working with Existing Ethereum Keys"}),"\n",(0,c.jsx)(n.p,{children:"You can also use existing Ethereum keys in Casper. Here is an example set of Ethereum keys and their corresponding address:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"Address:0x7863B6F7232D99FF80B74E4C8BB3BEE3BDE0291F\nPublic key:0470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66\nPrivate key:29773906aef3ee1f5868371fd7c50f9092205df26f60e660cafacbf2b95fe086\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To use existing Ethereum keys, the Casper virtual machine (VM) needs to know that the key is a ",(0,c.jsx)(n.code,{children:"Secp256k1"})," type. To achieve this, we will prefix the public key hex with 02, as shown in the example below."]}),"\n",(0,c.jsx)(n.p,{children:"The Casper command-line client provides an example of how this works."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"Example"}),":"]}),"\n",(0,c.jsx)(n.p,{children:"The following transaction sends 10 CSPR."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--transfer-id 1234567 \\\n--node-address http://localhost:7777 \\\n--chain-name casper \\\n--target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \\\n--amount 10000000000 \\\n--secret-key <path-to-secret_key.pem> \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsx)(n.admonition,{type:"tip",children:(0,c.jsxs)(n.p,{children:["The payment amount varies based on each transaction and network ",(0,c.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,c.jsxs)(n.p,{children:["The Casper command-line client requires the secret key in ",(0,c.jsx)(n.em,{children:"PEM"})," format to send a transaction from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to ",(0,c.jsx)(n.em,{children:"PEM"})," format is needed."]}),"\n",(0,c.jsxs)(n.p,{children:["The following example is a JS script that generates a ",(0,c.jsx)(n.em,{children:"PEM"})," file, using a ",(0,c.jsx)(n.a,{href:"https://github.com/stacks-network/key-encoder-js",children:"key encoder"})," and Node.js. To install these components, do the following:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"sudo apt install nodejs\nnpm install key-encoder\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Then create the JS script ",(0,c.jsx)(n.em,{children:"convert-to-pem.js"})," using ",(0,c.jsx)(n.em,{children:"vi"})," or ",(0,c.jsx)(n.em,{children:"nano"}),", and include this content:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-javascript",children:'var KeyEncoder = require(\'key-encoder\'),\nkeyEncoder = new KeyEncoder.default(\'secp256k1\');\nlet priv_hex = "THE SECRET KEY TO ENCODE";\nlet priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");\nconsole.log(priv_pem);\n'})}),"\n",(0,c.jsx)(n.p,{children:"Then run the script using Node.js and name the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"node convert-to-pem.js > eth-secret.pem\n"})}),"\n",(0,c.jsxs)(n.p,{children:["To view the secret key, use ",(0,c.jsx)(n.code,{children:"cat <filename>"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"cat eth-secret.pem\n"})}),"\n",(0,c.jsx)(n.p,{children:"Below is the sample output showing the contents of the secret key."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"-----BEGIN EC PRIVATE KEY-----\nMHQCAQEEIBjXY+7xZagzTjL4p8bGWS8FPRcW13mgytdu5c3e556MoAcGBSuBBAAK\noUQDQgAEpV4dVaPeAEaH0VXrQtLzjpGt1pui1q08311em6wDCchGNjzsnOY7stGF\ntlKF2V5RFQn4rzkwipSYnrqaPf1pTA==\n-----END EC PRIVATE KEY-----\n"})}),"\n",(0,c.jsx)(n.h3,{id:"option-3-generating-keys-using-openssl",children:"Option 3: Generating keys using OpenSSL"}),"\n",(0,c.jsxs)(n.p,{children:["You can generate keys without the Casper client using the ",(0,c.jsx)(n.a,{href:"https://www.openssl.org/",children:"openssl"})," cryptography toolkit. The commands below are valid only for generating Ed25519 keys on a Linux operating system."]}),"\n",(0,c.jsxs)(n.h4,{id:"generating-the-secret_keypem-file",children:["Generating the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{children:"openssl genpkey -algorithm ed25519 -out secret_key.pem\n"})}),"\n",(0,c.jsxs)(n.h4,{id:"generating-public-keys-from-the-secret_keypem-file",children:["Generating public keys from the ",(0,c.jsx)(n.code,{children:"secret_key.pem"})," file"]}),"\n",(0,c.jsxs)(n.p,{children:["For default Ed25519 keys, you can generate the ",(0,c.jsx)(n.code,{children:"public_key.pem"})," and ",(0,c.jsx)(n.code,{children:"public_key_hex"})," using these commands:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'openssl pkey -in secret_key.pem -pubout -out public_key.pem\n\n{ echo -n 01; openssl pkey -outform DER -pubout -in "secret_key.pem" | tail -c +13 | openssl base64 | openssl base64 -d | hexdump -ve \'/1 "%02x" \' | tr -d "/n"; } > public_key_hex\n'})}),"\n",(0,c.jsx)(n.h2,{id:"generating-an-account-hash",children:"Generating an Account Hash"}),"\n",(0,c.jsxs)(n.p,{children:["To generate the account hash for a public key, use the ",(0,c.jsx)(n.em,{children:"account-address"})," option of the Casper client. The argument for the ",(0,c.jsx)(n.em,{children:"public-key"})," must be a properly formatted public key. The public key may also be read from a file, which should be one of the two files generated via the ",(0,c.jsx)(n.em,{children:"keygen"})," command: ",(0,c.jsx)(n.em,{children:"public_key_hex"})," or ",(0,c.jsx)(n.em,{children:"public_key.pem"}),"."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsx)(n.h2,{id:"purse-uref",children:"Finding the Main Purse URef"}),"\n",(0,c.jsx)(n.p,{children:"You can use the Casper CLI client or a block explorer to find the URef identifying an account's main purse."}),"\n",(0,c.jsx)(n.h3,{id:"using-the-casper-cli-client",children:"Using the Casper CLI client"}),"\n",(0,c.jsxs)(n.p,{children:["With the ",(0,c.jsx)(n.code,{children:"casper-client"}),", use the ",(0,c.jsx)(n.code,{children:"get-account-info"})," subcommand."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info \\\n--node-address <HOST:PORT> \\\n--public-key <FORMATTED STRING or PATH>\n"})}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:"public-key"})," - This must be a properly formatted public key. The public key may instead be read in from a file, in which case, enter the path to the file as the argument. The file should be one of the two public key files generated via the ",(0,c.jsx)(n.code,{children:"keygen"}),' subcommand; "public_key_hex" or "public_key.pem"']}),"\n"]}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Sample command and output"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'casper-client get-account-info --node-address http://65.21.75.254:7777 --public-key 0202ceafc0aa35f5a7bdda22f65c046b9b30b858459e18d3670f035839ad887fe5db\n{\n "id": -2018234245556346849,\n "jsonrpc": "2.0",\n "result": {\n "account": {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n }\n ],\n "main_purse": "uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007",\n "named_keys": []\n },\n "api_version": "1.4.15",\n "merkle_proof": "[29712 hex chars]"\n }\n}\n\n'})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Run the following help command for more details:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-account-info --help\n"})}),"\n",(0,c.jsx)(n.h3,{id:"using-a-block-explorer",children:"Using a block explorer"}),"\n",(0,c.jsxs)(n.p,{children:["Using the block explorer for ",(0,c.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," or ",(0,c.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),", open the Account in question, and expand the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section. Look for the ",(0,c.jsx)(n.code,{children:"main_purse"})," field and find the corresponding URef. If you do not see data in the ",(0,c.jsx)(n.code,{children:"Raw Data"})," section, then the account has not been funded yet."]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.img,{alt:"Main purse",src:s(34995).A+"",width:"1576",height:"1494"})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},34995:(e,n,s)=>{s.d(n,{A:()=>c});const c=s.p+"assets/images/main_purse_uref-96cffa61cd6ab63f2fb996efe8fc4197.png"},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var c=s(96540);const t={},i=c.createContext(t);function a(e){const n=c.useContext(i);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c141421f.4ae5844e.js b/assets/js/c141421f.4ae5844e.js new file mode 100644 index 000000000..ff82fcaa6 --- /dev/null +++ b/assets/js/c141421f.4ae5844e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80957],{40936:s=>{s.exports=JSON.parse('{"name":"docusaurus-theme-search-algolia","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/c141421f.80b09241.js b/assets/js/c141421f.80b09241.js deleted file mode 100644 index 6d1180dc6..000000000 --- a/assets/js/c141421f.80b09241.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[957],{40936:s=>{s.exports=JSON.parse('{"name":"docusaurus-theme-search-algolia","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/c19e69a7.2fc7560a.js b/assets/js/c19e69a7.2fc7560a.js deleted file mode 100644 index aae1d2294..000000000 --- a/assets/js/c19e69a7.2fc7560a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6962],{75574:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var s=t(74848),i=t(28453);const a={title:"Undelegating Tokens"},o="Undelegating Tokens with the Casper Client",d={id:"developers/cli/undelegate",title:"Undelegating Tokens",description:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.",source:"@site/docs/developers/cli/undelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/undelegate",permalink:"/next/developers/cli/undelegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Undelegating Tokens"},sidebar:"developers",previous:{title:"Redelegating Tokens with the Casper Client",permalink:"/next/developers/cli/redelegate"},next:{title:"Sending Transactions",permalink:"/next/developers/cli/sending-transactions"}},r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sending the Undelegation Request",id:"sending-the-undelegation-deploy",level:2},{value:"Method 1: Undelegating with the System Auction Contract",id:"undelegating-system-auction",level:3},{value:"Method 2: Undelegating with Compiled Wasm",id:"undelegating-compiled-wasm",level:3},{value:"Verifying the Undelegation",id:"verifying-the-undelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens-with-the-casper-client",children:"Undelegating Tokens with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network and you have the validator's public key"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-undelegation-deploy",children:"Sending the Undelegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-system-auction",children:"Method 1: Undelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 100 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-compiled-wasm",children:"Method 2: Undelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["As part of this process, you need to ",(0,s.jsx)(n.a,{href:"/next/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that produce the undelegation Wasm."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, use the Casper CLI client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," to the network to initiate the undelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/undelegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-undelegation",children:"Verifying the Undelegation"}),"\n",(0,s.jsx)(n.p,{children:"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."}),"\n",(0,s.jsx)(n.p,{children:"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the public key and the amount are absent from the ",(0,s.jsx)(n.code,{children:"bids"})," structure, we can safely conclude that we have indeed undelegated from the validator."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Important Note"}),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c19e69a7.9d2442b7.js b/assets/js/c19e69a7.9d2442b7.js new file mode 100644 index 000000000..c9213b877 --- /dev/null +++ b/assets/js/c19e69a7.9d2442b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96962],{75574:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>l});var s=t(74848),i=t(28453);const a={title:"Undelegating Tokens"},o="Undelegating Tokens with the Casper Client",d={id:"developers/cli/undelegate",title:"Undelegating Tokens",description:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.",source:"@site/docs/developers/cli/undelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/undelegate",permalink:"/developers/cli/undelegate",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Undelegating Tokens"},sidebar:"developers",previous:{title:"Redelegating Tokens with the Casper Client",permalink:"/developers/cli/redelegate"},next:{title:"Sending Transactions",permalink:"/developers/cli/sending-transactions"}},r={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Sending the Undelegation Request",id:"sending-the-undelegation-deploy",level:2},{value:"Method 1: Undelegating with the System Auction Contract",id:"undelegating-system-auction",level:3},{value:"Method 2: Undelegating with Compiled Wasm",id:"undelegating-compiled-wasm",level:3},{value:"Verifying the Undelegation",id:"verifying-the-undelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"undelegating-tokens-with-the-casper-client",children:"Undelegating Tokens with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network and you have the validator's public key"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-undelegation-deploy",children:"Sending the Undelegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to undelegate CSPR from a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-system-auction",children:"Method 1: Undelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR. There is no minimum amount required for the undelegation call."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 100 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point undelegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"undelegating-compiled-wasm",children:"Method 2: Undelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["As part of this process, you need to ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that produce the undelegation Wasm."]}),"\n",(0,s.jsxs)(n.p,{children:["Next, use the Casper CLI client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"undelegate.wasm"})," to the network to initiate the undelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/undelegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_UNDELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"undelegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account undelegating tokens from a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to undelegate 100 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the undelegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 6000000000 \\\n--session-path ~/undelegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='100000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-undelegation",children:"confirm the undelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-undelegation",children:"Verifying the Undelegation"}),"\n",(0,s.jsx)(n.p,{children:"To verify that the undelegation succeeded, you can use the Casper command-line client to generate an RPC request to query the auction state. The subsequent RPC response will confirm that the undelegation request was successfully processed."}),"\n",(0,s.jsx)(n.p,{children:"Here is how you can check the status of the auction to confirm that your bid was withdrawn:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["If the public key and the amount are absent from the ",(0,s.jsx)(n.code,{children:"bids"})," structure, we can safely conclude that we have indeed undelegated from the validator."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been added to your balance:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Important Note"}),": After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c2728190.0a5a894f.js b/assets/js/c2728190.0a5a894f.js deleted file mode 100644 index 1988b9564..000000000 --- a/assets/js/c2728190.0a5a894f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6121],{31011:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=t(74848),r=t(28453);const a={title:"Overview"},i="Concepts Overview",c={id:"concepts/index",title:"Overview",description:"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.",source:"@site/docs/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/next/concepts/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Overview"},sidebar:"concepts",next:{title:"What is Casper?",permalink:"/next/"}},o={},d=[{value:"Concepts",id:"concepts",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3},{value:"Users",id:"users",level:3},{value:"Resources",id:"resources",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"concepts-overview",children:"Concepts Overview"})}),"\n",(0,s.jsxs)(n.p,{children:["The Casper blockchain is a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Casper Mainnet"})," is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described ",(0,s.jsx)(n.a,{href:"/next/operators/setup-network/",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,s.jsx)(n.p,{children:"This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/",children:"Introduction to the Casper Blockchain"})}),(0,s.jsx)(n.td,{children:"High-level details about the Casper blockchain"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/intro-to-dapps",children:"Introduction to dApps"})}),(0,s.jsx)(n.td,{children:"Developing distributed applications on the Casper blockchain"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/addressable-entity",children:"Addressable Entities"})}),(0,s.jsx)(n.td,{children:"Learn about addressable entities and how they relate to accounts and smart contracts."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})}),(0,s.jsx)(n.td,{children:"The Casper programming model is account-based. Learn how Casper accounts work and how they are secured"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/key-types",children:"Key Types"})}),(0,s.jsx)(n.td,{children:"Hashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/global-state",children:"Global State"})}),(0,s.jsx)(n.td,{children:"Learn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/callstack",children:"Call Stacks"})}),(0,s.jsx)(n.td,{children:"Learn how Casper manages the calling of a contract"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),(0,s.jsx)(n.td,{children:"Transactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/smart-contracts",children:"Smart Contracts"})}),(0,s.jsx)(n.td,{children:"Learn how to develop smart contracts on Casper"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/dictionaries",children:"Dictionaries"})}),(0,s.jsx)(n.td,{children:"Learn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/serialization/",children:"Serialization"})}),(0,s.jsx)(n.td,{children:"Learn about serializing data types and the Casper Serialization Standard"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/design",children:"Design"})}),(0,s.jsx)(n.td,{children:"The high-level design of a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/economics",children:"Economics"})}),(0,s.jsx)(n.td,{children:"Learn about the Casper on-chain economics"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/glossary",children:"Glossary"})}),(0,s.jsx)(n.td,{children:"A compendium of all the terms used in Casper, in alphabetical order"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(n.p,{children:"After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories."}),"\n",(0,s.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/developers",children:"Developers"})," area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs."]}),"\n",(0,s.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/operators",children:"Operators"})," section caters to those who want to run and administrate a Casper node or network."]}),"\n",(0,s.jsx)(n.h3,{id:"users",children:"Users"}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/next/users/",children:"Users"})," section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device."]}),"\n",(0,s.jsx)(n.h3,{id:"resources",children:"Resources"}),"\n",(0,s.jsxs)(n.p,{children:["Navigate to ",(0,s.jsx)(n.a,{href:"/next/resources/",children:"Resources"})," to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/",children:"beginner tutorials"}),". Afterward, continue with more ",(0,s.jsx)(n.a,{href:"/next/resources/tutorials/advanced/",children:"advanced tutorials"})," to explore the multi-signature feature, runtime return values, and other essential features."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var s=t(96540);const r={},a=s.createContext(r);function i(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c2728190.c9436c76.js b/assets/js/c2728190.c9436c76.js new file mode 100644 index 000000000..6b64f7cb9 --- /dev/null +++ b/assets/js/c2728190.c9436c76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86121],{31011:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var r=s(74848),t=s(28453);const a={title:"Overview"},i="Concepts Overview",c={id:"concepts/index",title:"Overview",description:"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.",source:"@site/docs/concepts/index.md",sourceDirName:"concepts",slug:"/concepts/",permalink:"/concepts/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Overview"},sidebar:"concepts",next:{title:"What is Casper?",permalink:"/concepts/about"}},o={},d=[{value:"Concepts",id:"concepts",level:2},{value:"Next Steps",id:"next-steps",level:2},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3},{value:"Users",id:"users",level:3},{value:"Resources",id:"resources",level:3}];function l(e){const n={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"concepts-overview",children:"Concepts Overview"})}),"\n",(0,r.jsxs)(n.p,{children:["The Casper blockchain is a ",(0,r.jsx)(n.a,{href:"/concepts/glossary/T#turing-complete-blockchain",children:"Turing-complete"})," smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"Casper Mainnet"})," is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described ",(0,r.jsx)(n.a,{href:"/operators/setup-network/",children:"here"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/about",children:"Introduction to the Casper Blockchain"})}),(0,r.jsx)(n.td,{children:"High-level details about the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/intro-to-dapps",children:"Introduction to dApps"})}),(0,r.jsx)(n.td,{children:"Developing distributed applications on the Casper blockchain"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/addressable-entity",children:"Addressable Entities"})}),(0,r.jsx)(n.td,{children:"Learn about addressable entities and how they relate to accounts and smart contracts."})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/accounts-and-keys",children:"Accounts and Cryptographic Keys"})}),(0,r.jsx)(n.td,{children:"The Casper programming model is account-based. Learn how Casper accounts work and how they are secured"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/key-types",children:"Key Types"})}),(0,r.jsx)(n.td,{children:"Hashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"})}),(0,r.jsx)(n.td,{children:"Learn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/callstack",children:"Call Stacks"})}),(0,r.jsx)(n.td,{children:"Learn how Casper manages the calling of a contract"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),(0,r.jsx)(n.td,{children:"Transactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})}),(0,r.jsx)(n.td,{children:"Learn how to develop smart contracts on Casper"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/dictionaries",children:"Dictionaries"})}),(0,r.jsx)(n.td,{children:"Learn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/concepts/serialization/",children:"Serialization"})}),(0,r.jsx)(n.td,{children:"Learn about serializing data types and the Casper Serialization Standard"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/design",children:"Design"})}),(0,r.jsx)(n.td,{children:"The high-level design of a Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/economics",children:"Economics"})}),(0,r.jsx)(n.td,{children:"Learn about the Casper on-chain economics"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/glossary",children:"Glossary"})}),(0,r.jsx)(n.td,{children:"A compendium of all the terms used in Casper, in alphabetical order"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,r.jsx)(n.p,{children:"After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories."}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/developers",children:"Developers"})," area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/operators",children:"Operators"})," section caters to those who want to run and administrate a Casper node or network."]}),"\n",(0,r.jsx)(n.h3,{id:"users",children:"Users"}),"\n",(0,r.jsxs)(n.p,{children:["The ",(0,r.jsx)(n.a,{href:"/users/",children:"Users"})," section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device."]}),"\n",(0,r.jsx)(n.h3,{id:"resources",children:"Resources"}),"\n",(0,r.jsxs)(n.p,{children:["Navigate to ",(0,r.jsx)(n.a,{href:"/resources/",children:"Resources"})," to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the ",(0,r.jsx)(n.a,{href:"/resources/tutorials/beginner/",children:"beginner tutorials"}),". Afterward, continue with more ",(0,r.jsx)(n.a,{href:"/resources/tutorials/advanced/",children:"advanced tutorials"})," to explore the multi-signature feature, runtime return values, and other essential features."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var r=s(96540);const t={},a=r.createContext(t);function i(e){const n=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:i(e.components),r.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c2a48fdb.aa595378.js b/assets/js/c2a48fdb.aa595378.js new file mode 100644 index 000000000..b0942a10f --- /dev/null +++ b/assets/js/c2a48fdb.aa595378.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66623],{30919:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=s(74848),o=s(28453);const a={title:"Fast Sync"},r="Introducing Fast Sync",c={id:"operators/setup/fast-sync",title:"Fast Sync",description:"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 transaction 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.",source:"@site/docs/operators/setup/fast-sync.md",sourceDirName:"operators/setup",slug:"/operators/setup/fast-sync",permalink:"/operators/setup/fast-sync",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Fast Sync"},sidebar:"operators",previous:{title:"Installation",permalink:"/operators/setup/install-node"},next:{title:"Open Files Limit",permalink:"/operators/setup/open-files"}},i={},l=[{value:"How Fast Sync Works",id:"how-fast-sync-works",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"introducing-fast-sync",children:"Introducing Fast Sync"})}),"\n",(0,n.jsx)(t.p,{children:"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 transaction 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."}),"\n",(0,n.jsxs)(t.p,{children:["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 ",(0,n.jsx)(t.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"trusted hash"})," 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."]}),"\n",(0,n.jsx)(t.h2,{id:"how-fast-sync-works",children:"How Fast Sync Works"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Fast-sync process",src:s(43977).A+"",width:"661",height:"81"})}),"\n",(0,n.jsxs)(t.p,{children:["For fast sync, operators must provide the trusted hash of a block in the ",(0,n.jsx)(t.code,{children:"config.toml"})," file. An example can be found ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},43977:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/fast-sync-process-b20a3732a0c1a20e1ff682568f6a8390.png"},28453:(e,t,s)=>{s.d(t,{R:()=>r,x:()=>c});var n=s(96540);const o={},a=n.createContext(o);function r(e){const t=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),n.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c2a48fdb.c860eb25.js b/assets/js/c2a48fdb.c860eb25.js deleted file mode 100644 index 55529f82f..000000000 --- a/assets/js/c2a48fdb.c860eb25.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6623],{30919:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var s=n(74848),o=n(28453);const a={title:"Fast Sync"},r="Introducing Fast Sync",c={id:"operators/setup/fast-sync",title:"Fast Sync",description:"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 transaction 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.",source:"@site/docs/operators/setup/fast-sync.md",sourceDirName:"operators/setup",slug:"/operators/setup/fast-sync",permalink:"/next/operators/setup/fast-sync",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Fast Sync"},sidebar:"operators",previous:{title:"Installation",permalink:"/next/operators/setup/install-node"},next:{title:"Open Files Limit",permalink:"/next/operators/setup/open-files"}},i={},l=[{value:"How Fast Sync Works",id:"how-fast-sync-works",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"introducing-fast-sync",children:"Introducing Fast Sync"})}),"\n",(0,s.jsx)(t.p,{children:"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 transaction 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."}),"\n",(0,s.jsxs)(t.p,{children:["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 ",(0,s.jsx)(t.a,{href:"/next/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"trusted hash"})," 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."]}),"\n",(0,s.jsx)(t.h2,{id:"how-fast-sync-works",children:"How Fast Sync Works"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Fast-sync process",src:n(21063).A+"",width:"661",height:"81"})}),"\n",(0,s.jsxs)(t.p,{children:["For fast sync, operators must provide the trusted hash of a block in the ",(0,s.jsx)(t.code,{children:"config.toml"})," file. An example can be found ",(0,s.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7",children:"here"}),"."]}),"\n",(0,s.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},21063:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/fast-sync-process-b20a3732a0c1a20e1ff682568f6a8390.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>c});var s=n(96540);const o={},a=s.createContext(o);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3308ba6.425334c7.js b/assets/js/c3308ba6.425334c7.js new file mode 100644 index 000000000..41fe502d3 --- /dev/null +++ b/assets/js/c3308ba6.425334c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86547],{5571:o=>{o.exports=JSON.parse('{"tag":{"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade","allTagsPath":"/blog/tags","count":4,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/condor","page":1,"postsPerPage":4,"totalPages":1,"totalCount":4,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/c3308ba6.dabf8cd8.js b/assets/js/c3308ba6.dabf8cd8.js deleted file mode 100644 index 59a09fddf..000000000 --- a/assets/js/c3308ba6.dabf8cd8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6547],{5571:o=>{o.exports=JSON.parse('{"tag":{"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade","allTagsPath":"/blog/tags","count":4,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/condor","page":1,"postsPerPage":4,"totalPages":1,"totalCount":4,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/c34be5c7.a0d52e84.js b/assets/js/c34be5c7.a0d52e84.js new file mode 100644 index 000000000..2e9960bf0 --- /dev/null +++ b/assets/js/c34be5c7.a0d52e84.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[44123],{49196:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const i={},s="Overview",c={id:"resources/beginner/counter/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter/overview.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/overview",permalink:"/2.0.0/resources/beginner/counter/overview",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/2.0.0/counter"},next:{title:"Casper-Client Commands",permalink:"/2.0.0/resources/beginner/counter/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(5387).A+"",width:"1166",height:"614"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},5387:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-2f7c7ea9d18c57e4cd8b8d010eee38fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const o={},i=r.createContext(o);function s(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c377a04b.d0facf52.js b/assets/js/c377a04b.d0facf52.js new file mode 100644 index 000000000..4b8c77b6a --- /dev/null +++ b/assets/js/c377a04b.d0facf52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[45742],{48321:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var a=n(74848),o=n(28453);const i={title:"Welcome to the official Casper documentation",slug:"/"},s=void 0,r={id:"index",title:"Welcome to the official Casper documentation",description:"What is Casper?",source:"@site/docs/index.md",sourceDirName:".",slug:"/",permalink:"/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Welcome to the official Casper documentation",slug:"/"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How to use this documentation portal",id:"how-to-use-this-documentation-portal",level:2},{value:"Navigation/Layout",id:"navigationlayout",level:3},{value:"Nav bar and Sidebar",id:"nav-bar-and-sidebar",level:4},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,a.jsxs)(t.p,{children:["Casper is a smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,a.jsx)(t.h2,{id:"how-to-use-this-documentation-portal",children:"How to use this documentation portal"}),"\n",(0,a.jsx)(t.h3,{id:"navigationlayout",children:"Navigation/Layout"}),"\n",(0,a.jsx)(t.h4,{id:"nav-bar-and-sidebar",children:"Nav bar and Sidebar"}),"\n",(0,a.jsx)(t.p,{children:"The Nav bar is arranged along the top of your browser window, and may be broken down into left and right. On the left hand side, you will see 5 links, each of which corresponds to a sidebar. There are 5 Sidebars, each of which contains links to content broken down by subject area within the documentation."}),"\n",(0,a.jsx)(t.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/disclaimer",children:"Legal Disclaimer"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(96540);const o={},i=a.createContext(o);function s(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c377dc4a.607514a8.js b/assets/js/c377dc4a.607514a8.js new file mode 100644 index 000000000..f483899e9 --- /dev/null +++ b/assets/js/c377dc4a.607514a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[14425],{48188:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>i,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var n=t(74848),s=t(28453);const a={title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/welcome-docs-redux",source:"@site/blog/2024-08-15-hello-blogworld.md",title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",date:"2024-08-15T18:00:00.000Z",tags:[{inline:!0,label:"hello",permalink:"/blog/tags/hello"},{inline:!0,label:"new docs",permalink:"/blog/tags/new-docs"},{inline:!0,label:"docs-redux",permalink:"/blog/tags/docs-redux"}],readingTime:.595,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"validator rewards in Casper 2.0",permalink:"/blog/condor-validator-rewards"},nextItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"}},i={authorsImageUrls:[void 0]},d=[];function c(e){const o={a:"a",p:"p",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.p,{children:"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0."}),"\n",(0,n.jsxs)(o.p,{children:["Please enjoy and if you have any comments, suggestions or errata, please email ",(0,n.jsx)(o.a,{href:"mailto:devrel@casper.network",children:"devrel@casper.network"})," with your contribution or query."]})]})}function p(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>r,x:()=>l});var n=t(96540);const s={},a=n.createContext(s);function r(e){const o=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c377dc4a.bac70803.js b/assets/js/c377dc4a.bac70803.js deleted file mode 100644 index 1dd5ffe15..000000000 --- a/assets/js/c377dc4a.bac70803.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4425],{48188:(e,o,t)=>{t.r(o),t.d(o,{assets:()=>i,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var n=t(74848),s=t(28453);const a={title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},r=void 0,l={permalink:"/blog/welcome-docs-redux",source:"@site/blog/2024-08-15-hello-blogworld.md",title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",date:"2024-08-15T18:00:00.000Z",tags:[{inline:!0,label:"hello",permalink:"/blog/tags/hello"},{inline:!0,label:"new docs",permalink:"/blog/tags/new-docs"},{inline:!0,label:"docs-redux",permalink:"/blog/tags/docs-redux"}],readingTime:.595,hasTruncateMarker:!0,authors:[{name:"Mel Padden",page:{permalink:"/blog/authors/melpadden"},title:"Head of Developer Relations for Casper Association",url:"https://github.com/melpadden",socials:{x:"https://x.com/mel_casper"},permalink:"/melpadden",imageURL:"https://github.com/melpadden.png",key:"melpadden"}],frontMatter:{title:"Casper Docs Redux!",description:"The first blog post using the new Docs portal.",slug:"welcome-docs-redux",date:"2024-08-15T18:00",authors:["melpadden"],tags:["hello","new docs","docs-redux"],hide_table_of_contents:!1},unlisted:!1,prevItem:{title:"validator rewards in Casper 2.0",permalink:"/blog/condor-validator-rewards"},nextItem:{title:"Addressable Entity in Casper 2.0",permalink:"/blog/addressable-entity"}},i={authorsImageUrls:[void 0]},d=[];function c(e){const o={a:"a",p:"p",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.p,{children:"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0."}),"\n",(0,n.jsxs)(o.p,{children:["Please enjoy and if you have any comments, suggestions or errata, please email ",(0,n.jsx)(o.a,{href:"mailto:devrel@casper.network",children:"devrel@casper.network"})," with your contribution or query."]})]})}function p(e={}){const{wrapper:o}={...(0,s.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},28453:(e,o,t)=>{t.d(o,{R:()=>r,x:()=>l});var n=t(96540);const s={},a=n.createContext(s);function r(e){const o=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function l(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),n.createElement(a.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c37f176d.38ea646e.js b/assets/js/c37f176d.38ea646e.js new file mode 100644 index 000000000..706a56578 --- /dev/null +++ b/assets/js/c37f176d.38ea646e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79596],{6910:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const c={title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},r="Installing and Interacting with a CEP-18 Contract",o={id:"resources/tokens/cep18/quickstart-guide",title:"On-chain Installation",description:"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/quickstart-guide.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/quickstart-guide",permalink:"/1.5.X/resources/tokens/cep18/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726495933e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},sidebar:"resources",previous:{title:"Fungible Token Workflow",permalink:"/1.5.X/resources/tokens/cep18/full-tutorial"},next:{title:"CEP-18 Contract Details",permalink:"/1.5.X/resources/tokens/cep18/query"}},i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Main Fungible Token Contract",id:"install-the-main-fungible-token-contract",level:2},{value:"Install the <code>cep18_test_contract</code> Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"installing-and-interacting-with-a-cep-18-contract",children:"Installing and Interacting with a CEP-18 Contract"})}),"\n",(0,s.jsxs)(t.p,{children:["This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,s.jsx)(t.a,{href:"https://cspr.live",children:"Casper network"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(t.p,{children:"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."}),"\n",(0,s.jsxs)(t.p,{children:["For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,s.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep18/full-tutorial",children:"Casper Fungible Token Tutorial"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(t.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Set up your machine as per the ",(0,s.jsx)(t.a,{href:"../../../developers/prerequisites/",children:"prerequisites"})]}),"\n",(0,s.jsx)(t.li,{children:"Use the [Casper command-line client]"}),"\n",(0,s.jsxs)(t.li,{children:["Get a valid ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:(0,s.jsx)(t.code,{children:"node-address"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Know how to deploy a ",(0,s.jsx)(t.a,{href:"../../../developers/cli/sending-deploys/",children:"smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(t.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,s.jsx)(t.h1,{id:"setup",children:"Setup"}),"\n",(0,s.jsxs)(t.p,{children:["Clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"fungible token (CEP-18) contract repository"})," and run the ",(0,s.jsx)(t.code,{children:"make build-contract"})," command. This will create the ",(0,s.jsx)(t.code,{children:"cep18.wasm"})," and the ",(0,s.jsx)(t.code,{children:"cep18_test_contract.wasm"}),". The token Wasm is the main contract. We will use the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."]}),"\n",(0,s.jsx)(t.h2,{id:"install-the-main-fungible-token-contract",children:"Install the Main Fungible Token Contract"}),"\n",(0,s.jsx)(t.p,{children:"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Name"})," - The name of your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Symbol"})," - The symbol used to refer to your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Total_supply"})," - The total supply of the CEP-18 token to be minted"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Decimals"})," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,s.jsx)(t.code,{children:"decimals"})," setting of 3 would be 1,000.000 tokens)"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n"})}),"\n",(0,s.jsxs)(t.h2,{id:"install-the-cep18_test_contract-contract-package",children:["Install the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Contract Package"]}),"\n",(0,s.jsx)(t.p,{children:"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n"})}),"\n",(0,s.jsx)(t.p,{children:"At this point, the account that installed both the main contract and the helper contract will look like this."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'{\n\t"src": {\n\t"Account": {\n\t"_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t"namedKeys": [\n\t\t{\n\t\t"name": "cep18_test_contract",\n\t\t"key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n\t\t},\n\t\t{\n\t\t"name": "cep18_token_contract",\n\t\t"key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n\t\t},\n\t],\n\t"mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n\t"associatedKeys": [\n\t\t{\n\t\t"accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t\t"weight": 1\n\t\t}\n\t],\n\t"actionThresholds": {\n\t\t"deployment": 1,\n\t\t"keyManagement": 1\n\t\t}\n\t\t}\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"Note:"})})}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_token_contract"})," is the main contract, and is a stored contract, record its hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_test_call"})," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(t.p,{children:"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/1.5.X/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c37f176d.df6ecd7f.js b/assets/js/c37f176d.df6ecd7f.js deleted file mode 100644 index e13d2e5a9..000000000 --- a/assets/js/c37f176d.df6ecd7f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9596],{6910:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const c={title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},r="Installing and Interacting with a CEP-18 Contract",o={id:"resources/tokens/cep18/quickstart-guide",title:"On-chain Installation",description:"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/quickstart-guide.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/quickstart-guide",permalink:"/resources/tokens/cep18/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},sidebar:"resources",previous:{title:"Fungible Token Workflow",permalink:"/resources/tokens/cep18/full-tutorial"},next:{title:"CEP-18 Contract Details",permalink:"/resources/tokens/cep18/query"}},i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Main Fungible Token Contract",id:"install-the-main-fungible-token-contract",level:2},{value:"Install the <code>cep18_test_contract</code> Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"installing-and-interacting-with-a-cep-18-contract",children:"Installing and Interacting with a CEP-18 Contract"})}),"\n",(0,s.jsxs)(t.p,{children:["This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,s.jsx)(t.a,{href:"https://cspr.live",children:"Casper network"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(t.p,{children:"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."}),"\n",(0,s.jsxs)(t.p,{children:["For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/full-tutorial",children:"Casper Fungible Token Tutorial"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(t.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Set up your machine as per the ",(0,s.jsx)(t.a,{href:"/developers/prerequisites/",children:"prerequisites"})]}),"\n",(0,s.jsx)(t.li,{children:"Use the [Casper command-line client]"}),"\n",(0,s.jsxs)(t.li,{children:["Get a valid ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:(0,s.jsx)(t.code,{children:"node-address"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Know how to deploy a ",(0,s.jsx)(t.a,{href:"/developers/cli/sending-deploys/",children:"smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(t.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,s.jsx)(t.h1,{id:"setup",children:"Setup"}),"\n",(0,s.jsxs)(t.p,{children:["Clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"fungible token (CEP-18) contract repository"})," and run the ",(0,s.jsx)(t.code,{children:"make build-contract"})," command. This will create the ",(0,s.jsx)(t.code,{children:"cep18.wasm"})," and the ",(0,s.jsx)(t.code,{children:"cep18_test_contract.wasm"}),". The token Wasm is the main contract. We will use the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."]}),"\n",(0,s.jsx)(t.h2,{id:"install-the-main-fungible-token-contract",children:"Install the Main Fungible Token Contract"}),"\n",(0,s.jsx)(t.p,{children:"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Name"})," - The name of your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Symbol"})," - The symbol used to refer to your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Total_supply"})," - The total supply of the CEP-18 token to be minted"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Decimals"})," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,s.jsx)(t.code,{children:"decimals"})," setting of 3 would be 1,000.000 tokens)"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n"})}),"\n",(0,s.jsxs)(t.h2,{id:"install-the-cep18_test_contract-contract-package",children:["Install the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Contract Package"]}),"\n",(0,s.jsx)(t.p,{children:"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n"})}),"\n",(0,s.jsx)(t.p,{children:"At this point, the account that installed both the main contract and the helper contract will look like this."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'{\n\t"src": {\n\t"Account": {\n\t"_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t"namedKeys": [\n\t\t{\n\t\t"name": "cep18_test_contract",\n\t\t"key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n\t\t},\n\t\t{\n\t\t"name": "cep18_token_contract",\n\t\t"key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n\t\t},\n\t],\n\t"mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n\t"associatedKeys": [\n\t\t{\n\t\t"accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t\t"weight": 1\n\t\t}\n\t],\n\t"actionThresholds": {\n\t\t"deployment": 1,\n\t\t"keyManagement": 1\n\t\t}\n\t\t}\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"Note:"})})}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_token_contract"})," is the main contract, and is a stored contract, record its hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_test_call"})," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(t.p,{children:"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c380abc4.9161c3a0.js b/assets/js/c380abc4.9161c3a0.js new file mode 100644 index 000000000..cc3583065 --- /dev/null +++ b/assets/js/c380abc4.9161c3a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80529],{72028:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=s(74848),r=s(28453);const o={},i="Writing Session Code",c={id:"developers/writing-onchain-code/writing-session-code",title:"Writing Session Code",description:"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/writing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/writing-session-code",permalink:"/1.5.X/developers/writing-onchain-code/writing-session-code",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Contracts and Session Code",permalink:"/1.5.X/developers/writing-onchain-code/contract-vs-session"},next:{title:"Testing Session Code",permalink:"/1.5.X/developers/writing-onchain-code/testing-session-code"}},a={},d=[{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Example 1: Writing Session Code",id:"writing-session-code",level:2},{value:"Dependencies in <code>Cargo.toml</code>",id:"dependencies-in-cargotoml",level:3},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"writing-session-code",children:"Writing Session Code"})}),"\n",(0,t.jsxs)(n.p,{children:["This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Comparing Session Code and Contract Code"}),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,t.jsxs)(n.p,{children:["For writing session code, we use the same project structure used for writing contracts, described ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"writing-session-code",children:"Example 1: Writing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"https://github.com/casper-ecosystem/two-party-multi-sig/"}),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Account"})," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious."})}),"\n",(0,t.jsxs)(n.h3,{id:"dependencies-in-cargotoml",children:["Dependencies in ",(0,t.jsx)(n.code,{children:"Cargo.toml"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,t.jsx)(n.code,{children:"main.rs"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["Open the ",(0,t.jsx)(n.code,{children:"contract/src/main.rs"})," file that contains the sample session code. Notice these directives at the top of the file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_std]"})," - Specifies not to import the standard library."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_main]"})," - Indicates the ",(0,t.jsx)(n.code,{children:"main"})," function is not required since the session code has only one entry point as the ",(0,t.jsx)(n.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Next, review the imported crates and other required libraries."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the imported libraries, we usually find the constants."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, we see the ",(0,t.jsx)(n.code,{children:"call"})," function, the only entry point in this example session code. The ",(0,t.jsx)(n.code,{children:"#[no_mangle]"})," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,t.jsx)(n.code,{children:"call"})," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When compiled, the ",(0,t.jsx)(n.code,{children:"call"})," function could be used from another library. For example, a C library could link to the resulting Wasm."]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-code",children:"Example 2: Calling a Contract with Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Another example of session code is the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call/src/main.rs"})," file, in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter",children:"counter"})," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Observe how the project is set up and review the dependencies in the ",(0,t.jsx)(n.code,{children:"counter/counter-call/Cargo.toml"})," file. Then, open the ",(0,t.jsx)(n.code,{children:"counter/counter-call/src/main.rs"})," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," function interacts with the contract's ",(0,t.jsx)(n.code,{children:"counter_inc"})," and ",(0,t.jsx)(n.code,{children:"counter_get"})," entry points. This is how the session's ",(0,t.jsx)(n.code,{children:"call"})," entry point triggers the logic stored inside the counter contract."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:" // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n"})}),"\n",(0,t.jsx)(n.h2,{id:"transfers-using-session-code",children:"Example 3: Transfers using Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, we use session code to perform a transfer using the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html",children:"transfer_from_purse_to_purse"})," system function. The entire session code is available in ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14",children:"GitHub"}),", but this is the ",(0,t.jsx)(n.code,{children:"call"})," function:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Another system function is ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html",children:"transfer_to_public_key"}),". The full session code example is on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Other transfer functions are available here:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html",children:"transfer_from_purse_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html",children:"transfer_from_purse_to_public_key"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"compiling-session-code",children:"Compiling Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file and ",(0,t.jsx)(n.code,{children:"src"})," folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the examples above, you may use the Makefiles provided:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make build-contract\n"})}),"\n",(0,t.jsx)(n.h2,{id:"executing-session-code",children:"Executing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code on a live Casper network, test it as described ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-session-code",children:"here"}),". You can also set up a local network using ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/setup-nctl",children:"NCTL"})," for additional tests."]}),"\n",(0,t.jsxs)(n.p,{children:["Session code can execute on a Casper network via a ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploy"}),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and its ",(0,t.jsx)(n.code,{children:"put-deploy"})," command provide one way to execute session code."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name <NETWORK-NAME> \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH> \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where the deploy should be sent. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - Path to the contract Wasm, pointing to the compiled contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - A named and typed argument passed to the Wasm code."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"--help"})," option to view an updated list of supported arguments."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsxs)(n.p,{children:["The following brief video describes ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-session-code",children:"test session code"})," using the Casper testing framework."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c380abc4.bac3fe3d.js b/assets/js/c380abc4.bac3fe3d.js deleted file mode 100644 index e2f4ac506..000000000 --- a/assets/js/c380abc4.bac3fe3d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2910],{72028:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>c,toc:()=>d});var t=s(74848),r=s(28453);const o={},i="Writing Session Code",c={id:"developers/writing-onchain-code/writing-session-code",title:"Writing Session Code",description:"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/writing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/writing-session-code",permalink:"/developers/writing-onchain-code/writing-session-code",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Contracts and Session Code",permalink:"/developers/writing-onchain-code/contract-vs-session"},next:{title:"Testing Session Code",permalink:"/developers/writing-onchain-code/testing-session-code"}},a={},d=[{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Example 1: Writing Session Code",id:"writing-session-code",level:2},{value:"Dependencies in <code>Cargo.toml</code>",id:"dependencies-in-cargotoml",level:3},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Example 2: Calling a Contract with Session Code",id:"calling-contracts-with-session-code",level:2},{value:"Example 3: Transfers using Session Code",id:"transfers-using-session-code",level:2},{value:"Compiling Session Code",id:"compiling-session-code",level:2},{value:"Executing Session Code",id:"executing-session-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"writing-session-code",children:"Writing Session Code"})}),"\n",(0,t.jsxs)(n.p,{children:["This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Comparing Session Code and Contract Code"}),". Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,t.jsxs)(n.p,{children:["For writing session code, we use the same project structure used for writing contracts, described ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract#directory-structure",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"writing-session-code",children:"Example 1: Writing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["The following steps illustrate the process of writing session code using an example repository containing sample session code for configuring an account: ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"https://github.com/casper-ecosystem/two-party-multi-sig/"}),". The sample code adds an associated key to the account and updates the action thresholds. Remember that an ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," on a Casper network can add associated accounts and set up a multi-signature scheme for deploys. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig/\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Before executing session code, ensure that you know exactly what the session code is doing. If you don't know what it is meant for, it could be doing something malicious."})}),"\n",(0,t.jsxs)(n.h3,{id:"dependencies-in-cargotoml",children:["Dependencies in ",(0,t.jsx)(n.code,{children:"Cargo.toml"})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file includes the dependencies and versions the session code requires. At a minimum, you need to import the latest versions of the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,t.jsx)(n.code,{children:"main.rs"})," File"]}),"\n",(0,t.jsxs)(n.p,{children:["Open the ",(0,t.jsx)(n.code,{children:"contract/src/main.rs"})," file that contains the sample session code. Notice these directives at the top of the file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_std]"})," - Specifies not to import the standard library."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"#![no_main]"})," - Indicates the ",(0,t.jsx)(n.code,{children:"main"})," function is not required since the session code has only one entry point as the ",(0,t.jsx)(n.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Next, review the imported crates and other required libraries."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n\nuse casper_contract::contract_api::{account, runtime};\nuse casper_contract::unwrap_or_revert::UnwrapOrRevert;\nuse casper_types::account::{AccountHash, ActionType, Weight};\n"})}),"\n",(0,t.jsx)(n.p,{children:"After the imported libraries, we usually find the constants."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT: &str = "deployment-account";\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Next, we see the ",(0,t.jsx)(n.code,{children:"call"})," function, the only entry point in this example session code. The ",(0,t.jsx)(n.code,{children:"#[no_mangle]"})," flag ensures that the function name is retained as a string in the Wasm binary. For session code, this flag retains the ",(0,t.jsx)(n.code,{children:"call"})," string and marks the entry point for the execution engine. Explore the call function details by opening the cloned project."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Open the repository for details\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["When compiled, the ",(0,t.jsx)(n.code,{children:"call"})," function could be used from another library. For example, a C library could link to the resulting Wasm."]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-code",children:"Example 2: Calling a Contract with Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Another example of session code is the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/counter-call/src/main.rs",children:"counter-call/src/main.rs"})," file, in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter",children:"counter"})," repository. This example shows how we commonly use session code to invoke logic stored within a smart contract. To follow along, clone the repository."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter/\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Observe how the project is set up and review the dependencies in the ",(0,t.jsx)(n.code,{children:"counter/counter-call/Cargo.toml"})," file. Then, open the ",(0,t.jsx)(n.code,{children:"counter/counter-call/src/main.rs"})," file containing the session code. Notice the directives at the top of the file, the required dependencies, and the declared constants."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"call"})," function interacts with the contract's ",(0,t.jsx)(n.code,{children:"counter_inc"})," and ",(0,t.jsx)(n.code,{children:"counter_get"})," entry points. This is how the session's ",(0,t.jsx)(n.code,{children:"call"})," entry point triggers the logic stored inside the counter contract."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:" // Call the counter to get the current value.\n let current_counter_value: u32 =\n runtime::call_contract(contract_hash, COUNTER_GET, RuntimeArgs::new());\n\n // Call the counter to increment the value.\n let _: () = runtime::call_contract(contract_hash, COUNTER_INC, RuntimeArgs::new());\n"})}),"\n",(0,t.jsx)(n.h2,{id:"transfers-using-session-code",children:"Example 3: Transfers using Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["In this example, we use session code to perform a transfer using the ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_purse.html",children:"transfer_from_purse_to_purse"})," system function. The entire session code is available in ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/bench/transfer-to-purse/src/main.rs#L14",children:"GitHub"}),", but this is the ",(0,t.jsx)(n.code,{children:"call"})," function:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let target_purse: URef = runtime::get_named_arg(ARG_TARGET_PURSE);\n let amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n\n let source_purse = account::get_main_purse();\n\n system::transfer_from_purse_to_purse(source_purse, target_purse, amount, None)\n .unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["Another system function is ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_public_key.html",children:"transfer_to_public_key"}),". The full session code example is on ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/67c9c9bb84fdfc3f2d12103e25f0058104342bc0/smart_contracts/contracts/client/transfer-to-public-key/src/main.rs#L16",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let account_hash: PublicKey = runtime::get_named_arg(ARG_TARGET);\n let transfer_amount: U512 = runtime::get_named_arg(ARG_AMOUNT);\n system::transfer_to_public_key(account_hash, transfer_amount, None).unwrap_or_revert();\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Other transfer functions are available here:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_to_account.html",children:"transfer_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_account.html",children:"transfer_from_purse_to_account"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/system/fn.transfer_from_purse_to_public_key.html",children:"transfer_from_purse_to_public_key"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"compiling-session-code",children:"Compiling Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code to interact with a contract or other entities on the network, you must compile it to Wasm. Run the following command in the directory hosting the ",(0,t.jsx)(n.code,{children:"Cargo.toml"})," file and ",(0,t.jsx)(n.code,{children:"src"})," folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,t.jsx)(n.p,{children:"For the examples above, you may use the Makefiles provided:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make build-contract\n"})}),"\n",(0,t.jsx)(n.h2,{id:"executing-session-code",children:"Executing Session Code"}),"\n",(0,t.jsxs)(n.p,{children:["Before running session code on a live Casper network, test it as described ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"here"}),". You can also set up a local network using ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"NCTL"})," for additional tests."]}),"\n",(0,t.jsxs)(n.p,{children:["Session code can execute on a Casper network via a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/D#deploy",children:"Deploy"}),". All deploys can be broadly categorized as some unit of work that, when executed and committed, affects change to the network's global state."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and its ",(0,t.jsx)(n.code,{children:"put-deploy"})," command provide one way to execute session code."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address <HOST:PORT> \\\n --chain-name <NETWORK-NAME> \\\n --secret-key <PATH> \\\n --payment-amount <PAYMENT-AMOUNT> \\\n --session-path <SESSION-PATH> \\\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n'})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where the deploy should be sent. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - Payment for the deploy in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - Path to the contract Wasm, pointing to the compiled contract."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - A named and typed argument passed to the Wasm code."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Use the ",(0,t.jsx)(n.code,{children:"--help"})," option to view an updated list of supported arguments."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --help\n"})}),"\n",(0,t.jsx)(n.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,t.jsxs)(n.p,{children:["The following brief video describes ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=4",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"test session code"})," using the Casper testing framework."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c4561df8.dd6655af.js b/assets/js/c4561df8.dd6655af.js deleted file mode 100644 index 5e24ba9a1..000000000 --- a/assets/js/c4561df8.dd6655af.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4846],{72353:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>t,toc:()=>h});var n=r(74848),o=r(28453);const c={},a="O",t={id:"concepts/glossary/O",title:"O",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/O.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/O",permalink:"/concepts/glossary/O",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"N",permalink:"/concepts/glossary/N"},next:{title:"P",permalink:"/concepts/glossary/P"}},l={},h=[{value:"Operator",id:"operator",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"o",children:"O"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"operator",children:"Operator"}),"\n",(0,n.jsx)(s.p,{children:"Anyone running a node is an\xa0operator."}),"\n",(0,n.jsx)(s.p,{children:"An operator that has staked a bid but does not currently have a validator slot is a\xa0*staked operator*."}),"\n",(0,n.jsxs)(s.p,{children:["An operator whose bid has won a validator slot in the auction for a specific era is a\xa0",(0,n.jsx)(s.a,{href:"/concepts/glossary/V#validator",children:"validator"}),"\xa0in that era."]}),"\n",(0,n.jsxs)(s.p,{children:["It is common for a ",(0,n.jsx)(s.em,{children:"staked operator"})," to win an auction slot for many eras in a row and thus be a validator for a range of eras."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>a,x:()=>t});var n=r(96540);const o={},c=n.createContext(o);function a(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c4561df8.e426f1f3.js b/assets/js/c4561df8.e426f1f3.js new file mode 100644 index 000000000..9e468cbf0 --- /dev/null +++ b/assets/js/c4561df8.e426f1f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34846],{72353:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>c,metadata:()=>t,toc:()=>h});var n=r(74848),o=r(28453);const c={},a="O",t={id:"concepts/glossary/O",title:"O",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/O.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/O",permalink:"/1.5.X/concepts/glossary/O",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"N",permalink:"/1.5.X/concepts/glossary/N"},next:{title:"P",permalink:"/1.5.X/concepts/glossary/P"}},l={},h=[{value:"Operator",id:"operator",level:2}];function i(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"o",children:"O"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"operator",children:"Operator"}),"\n",(0,n.jsx)(s.p,{children:"Anyone running a node is an\xa0operator."}),"\n",(0,n.jsx)(s.p,{children:"An operator that has staked a bid but does not currently have a validator slot is a\xa0*staked operator*."}),"\n",(0,n.jsxs)(s.p,{children:["An operator whose bid has won a validator slot in the auction for a specific era is a\xa0",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"validator"}),"\xa0in that era."]}),"\n",(0,n.jsxs)(s.p,{children:["It is common for a ",(0,n.jsx)(s.em,{children:"staked operator"})," to win an auction slot for many eras in a row and thus be a validator for a range of eras."]})]})}function d(e={}){const{wrapper:s}={...(0,o.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(i,{...e})}):i(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>a,x:()=>t});var n=r(96540);const o={},c=n.createContext(o);function a(e){const s=n.useContext(c);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function t(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c45e62e7.265d09b1.js b/assets/js/c45e62e7.265d09b1.js new file mode 100644 index 000000000..342a60b62 --- /dev/null +++ b/assets/js/c45e62e7.265d09b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52296],{89157:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>o,toc:()=>c});var s=n(74848),i=n(28453);const a={title:"Authorization Keys"},r="Working with Authorization Keys",o={id:"resources/advanced/list-auth-keys-tutorial",title:"Authorization Keys",description:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/list-auth-keys-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/advanced/list-auth-keys-tutorial",permalink:"/2.0.0/resources/advanced/list-auth-keys-tutorial",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Authorization Keys"},sidebar:"tutorials",previous:{title:"Runtime Return Values",permalink:"/2.0.0/resources/tutorials/advanced/return-values-tutorial"},next:{title:"Token Transfers",permalink:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract"}},l={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Workflow",id:"workflow",level:2},{value:"The example contract",id:"the-example-contract",level:3},{value:"Client Wasm files",id:"client-wasm-files",level:3},{value:"<code>add_keys.wasm</code>",id:"add_keyswasm",level:4},{value:"<code>contract_call.wasm</code>",id:"contract_callwasm",level:4},{value:"Testing this example",id:"testing-this-example",level:3},{value:"Test 1: <code>should_allow_install_contract_with_default_account</code>",id:"test-1-should_allow_install_contract_with_default_account",level:4},{value:"Test 2: <code>should_disallow_install_with_non_added_authorization_key</code>",id:"test-2-should_disallow_install_with_non_added_authorization_key",level:4},{value:"Test 3: <code>should_allow_install_with_added_authorization_key</code>",id:"test-3-should_allow_install_with_added_authorization_key",level:4},{value:"Test 4: <code>should_allow_entry_point_with_installer_authorization_key</code>",id:"test-4-should_allow_entry_point_with_installer_authorization_key",level:4},{value:"Test 5: <code>should_allow_entry_point_with_account_authorization_key</code>",id:"test-5-should_allow_entry_point_with_account_authorization_key",level:4},{value:"Test 6: <code>should_disallow_entry_point_without_authorization_key</code>",id:"test-6-should_disallow_entry_point_without_authorization_key",level:4},{value:"Test 7: <code>should_allow_entry_point_through_contract_call_with_authorization_key</code>",id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",level:4},{value:"Test 8: <code>should_disallow_entry_point_through_contract_call_without_authorization_key</code>",id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",level:4}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"working-with-authorization-keys",children:"Working with Authorization Keys"})}),"\n",(0,s.jsx)(t.admonition,{type:"caution",children:(0,s.jsx)(t.p,{children:"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use."})}),"\n",(0,s.jsxs)(t.p,{children:["This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the ",(0,s.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"list_authorization_keys"})," function."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys = runtime::list_authorization_keys();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember that authorization keys are listed under a Deploy's ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"approvals"})," section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-json",children:'"approvals": [\n {\n "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",\n "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"\n }\n]\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract code in this example retrieves the set of authorization keys for a given deploy by calling the ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," function. In other words, ",(0,s.jsx)(t.code,{children:"list_authorization_keys"})," returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["You meet the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/prerequisites",children:"development prerequisites"})," and are familiar with ",(0,s.jsx)(t.a,{href:"/2.0.0/writing-contracts",children:"writing and testing on-chain code"})]}),"\n",(0,s.jsxs)(t.li,{children:["You know how to ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"send and verify deploys"})]}),"\n",(0,s.jsxs)(t.li,{children:["You are familiar with these concepts:\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/serialization/structures#account-serialization-standard-account",children:"Casper Accounts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/serialization/structures#deploy-serialization-standard-deploy",children:"Deploys"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/concepts/serialization/types#associatedkey",children:"Associated Keys"})}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"/2.0.0/concepts/serialization/types#approval",children:"Approvals"}),", also known as authorization keys"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"workflow",children:"Workflow"}),"\n",(0,s.jsxs)(t.p,{children:["To start, clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm",children:"tutorials-example-wasm"})," repository. Then, open the ",(0,s.jsx)(t.code,{children:"authorization-keys-example"})," directory, prepare your Rust environment, and build the tests with the following commands."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm\ncd tutorials-example-wasm/authorization-keys-example\nmake prepare\nmake test\n"})}),"\n",(0,s.jsx)(t.p,{children:"Review the repository's structure:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/client",children:"client"})," - A client folder containing two Wasm files\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"add_keys.wasm"})," - Session code that adds an associated key to the calling account"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"contract_call.wasm"})," - Session code that calls the contract's entry point and stores the result into a named key"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/contract",children:"contract"})," - A simple contract that demonstrates the usage of authorization keys and compiles into a ",(0,s.jsx)(t.code,{children:"contract.wasm"})," file"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example/tests",children:"tests"})," - Tests and supporting utilities to verify and demonstrate the contract's expected behavior"]}),"\n"]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["This tutorial highlights certain lines of code found in ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/authorization-keys-example",children:"GitHub"}),"."]})}),"\n",(0,s.jsx)(t.h3,{id:"the-example-contract",children:"The example contract"}),"\n",(0,s.jsxs)(t.p,{children:["Upon ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L75",children:"installation"}),", the contract in this example stores the authorization keys that signed the installer deploy into a named key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn init() {\n if runtime::get_key(AUTHORIZATION_KEYS_INSTALLER).is_none() {\n let authorization_keys: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n\n let authorization_keys: Key = storage::new_uref(authorization_keys).into();\n runtime::put_key(AUTHORIZATION_KEYS_INSTALLER, authorization_keys);\n }\n}\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The contract contains an entry point that returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys saved during contract installation. The following ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/contract/src/main.rs#L52",children:"usage"})," of ",(0,s.jsx)(t.code,{children:"runtime::list_authorization_keys"})," retrieves the set of account hashes representing the keys signing the caller deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let authorization_keys_caller: Vec<AccountHash> =\n runtime::list_authorization_keys().iter().cloned().collect();\n"})}),"\n",(0,s.jsx)(t.h3,{id:"client-wasm-files",children:"Client Wasm files"}),"\n",(0,s.jsx)(t.h4,{id:"add_keyswasm",children:(0,s.jsx)(t.code,{children:"add_keys.wasm"})}),"\n",(0,s.jsxs)(t.p,{children:["This file contains session code that adds an associated key to the calling account. For more details and a similar example, visit the ",(0,s.jsx)(t.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,s.jsx)(t.h4,{id:"contract_callwasm",children:(0,s.jsx)(t.code,{children:"contract_call.wasm"})}),"\n",(0,s.jsx)(t.p,{children:"This session code calls the contract's entry point, which returns the intersection between two sets of keys:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy that installed the contract (referred to in this tutorial as the installer deploy)"}),"\n",(0,s.jsx)(t.li,{children:"The authorization keys that signed the deploy calling the entry point (referred to in this tutorial as the caller deploy)."}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["The intersection result is a list stored under a named key of the account calling the ",(0,s.jsx)(t.code,{children:"contract_call.wasm"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);\nlet intersection =\n runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});\nruntime::put_key(&key_name, storage::new_uref(intersection).into());\n}\n"})}),"\n",(0,s.jsx)(t.h3,{id:"testing-this-example",children:"Testing this example"}),"\n",(0,s.jsx)(t.p,{children:"This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"Testing the contract installation"}),"\n",(0,s.jsx)(t.li,{children:"Testing the contract's unique entry point"}),"\n",(0,s.jsx)(t.li,{children:"Testing the entry point using a client contract call"}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"These tests focus on testing the contract installation."}),"\n",(0,s.jsxs)(t.h4,{id:"test-1-should_allow_install_contract_with_default_account",children:["Test 1: ",(0,s.jsx)(t.code,{children:"should_allow_install_contract_with_default_account"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L28",children:"test"})," signs the installer deploy with an authorization key ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," that belongs to the calling accounts's associated keys. In other words, since the caller is the default account, ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})," can be used to sign the deploy."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-2-should_disallow_install_with_non_added_authorization_key",children:["Test 2: ",(0,s.jsx)(t.code,{children:"should_disallow_install_with_non_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Failed contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L57",children:"test"})," tries to sign the installer deploy with an authorization key that is not part of the caller's associated keys. This is not allowed because the authorization keys used to sign a deploy need to be a subset of the caller's associated keys. So, the installer deploy fails as expected."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let session_code = PathBuf::from(CONTRACT_WASM);\nlet session_args = RuntimeArgs::new();\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_failure();\nlet error = builder.get_error().expect("must have error");\nassert_eq!(error.to_string(), "Authorization failure: not authorized.");\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-3-should_allow_install_with_added_authorization_key",children:["Test 3: ",(0,s.jsx)(t.code,{children:"should_allow_install_with_added_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Expected outcome"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),", ",(0,s.jsx)(t.code,{children:"account_addr_1"})]}),(0,s.jsx)(t.td,{children:"Successful contract installation"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L83",children:"test"})," demonstrates a successful installer deploy using an added authorization key. After the initial test framework setup, the test calls session code to add the associated account ",(0,s.jsx)(t.code,{children:"account_addr_1"})," to the default account's associated keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"// Add account_addr_1 to the default account's associated keys\nlet session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => account_addr_1\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet add_keys_execute_request =\n ExecuteRequestBuilder::from_deploy_item(add_keys_deploy_item).build();\n\nbuilder\n .exec(add_keys_execute_request)\n .commit()\n .expect_success();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Since the deploy threshold is now 2, the installer deploy is signed with the default account hash and with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". See ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L191",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR, account_addr_1])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, session_args)\n .build();\n\nlet execute_request = ExecuteRequestBuilder::from_deploy_item(deploy_item).build();\nbuilder.exec(execute_request).commit().expect_success();\n"})}),"\n",(0,s.jsx)(t.p,{children:"The next tests exercise the contract's unique entry point to calculate the intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."}),"\n",(0,s.jsxs)(t.h4,{id:"test-4-should_allow_entry_point_with_installer_authorization_key",children:["Test 4: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_installer_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_1"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L144",children:"test"})," builds upon the previous test, which adds an associated account to the default account's associated keys and installs the contract using these two keys. Additionally, on line 201, the test invokes the contract's entry point using a deploy that runs under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," signed only with ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". This is possible because the deploy action threshold for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," is 1 as you can see ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L201",children:"here"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let contract_hash = builder\n .get_expected_account(*DEFAULT_ACCOUNT_ADDR)\n .named_keys()\n .get(CONTRACT_HASH)\n .expect("must have this entry in named keys")\n .into_hash()\n .map(ContractHash::new)\n .unwrap();\n\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The entry point returns the intersection of the caller deploy's authorization keys and the installer deploy's authorization keys. The intersection is a list containing the key ",(0,s.jsx)(t.code,{children:"account_addr_1"}),". Thus, the caller deploy is expected to succeed and return a result."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-5-should_allow_entry_point_with_account_authorization_key",children:["Test 5: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_with_account_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This is the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L224",children:"main test"})," in this example repository. After installing the contract using the default account, the test adds the default account hash to ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," as an associated key."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(ADD_KEYS_WASM);\nlet session_args = runtime_args! {\n ASSOCIATED_ACCOUNT => *DEFAULT_ACCOUNT_ADDR\n};\n\nlet add_keys_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Then, the test creates a deploy to invoke the contract's entry point. This deploy executes under ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"})," and has two authorization keys, ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and the default account hash. Note that both authorization keys must sign the deploy to meet the deploy's action threshold, which is set to 2. The deploy should be executed successfully because the resulting intersection should contain the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.h4,{id:"test-6-should_disallow_entry_point_without_authorization_key",children:["Test 6: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"account_addr_2"})}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L304",children:"test"})," verifies that the entry point returns an error when there is no intersection between the caller deploy's authorization keys and the installer deploy's authorization keys."]}),"\n",(0,s.jsx)(t.p,{children:"The default account hash is used to sign the installer deploy."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["In the test, a new account, ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_2"}),", creates a deploy invoking the contract's entry point and signs the deploy with ",(0,s.jsx)(t.code,{children:"account_addr_2"}),". When calling the entry point, an error is returned because the caller and the installer deploys do not have any authorization keys in common."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' // Here ACCOUNT_USER_2 does not have DEFAULT_ACCOUNT_ADDR (from the contract installer) in its associated keys\n // The deploy will therefore revert with PermissionDenied\n let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_2])\n .with_address(account_addr_2)\n .with_stored_session_hash(contract_hash, ENTRYPOINT, runtime_args! {})\n .build();\n\n let entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\n builder.exec(entry_point_request).commit().expect_failure();\n let error = builder.get_error().expect("must have User error: 0");\n assert_expected_error(\n error,\n 0,\n "should fail execution since DEFAULT_ACCOUNT_ADDR is not in ACCOUNT_USER_2 associated keys",\n );\n'})}),"\n",(0,s.jsxs)(t.p,{children:["The following tests exercise the entry point using a ",(0,s.jsx)(t.a,{href:"#contract_callwasm",children:"contract call"})," and verifying the result returned."]}),"\n",(0,s.jsxs)(t.h4,{id:"test-7-should_allow_entry_point_through_contract_call_with_authorization_key",children:["Test 7: ",(0,s.jsx)(t.code,{children:"should_allow_entry_point_through_contract_call_with_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})]}),(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["This ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L403",children:"test"})," validates the contract's entry point using a client contract call. The contract is installed using the default account hash in the deploy's authorization keys."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let session_code = PathBuf::from(CONTRACT_WASM);\n\nlet deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[*DEFAULT_ACCOUNT_ADDR])\n .with_address(*DEFAULT_ACCOUNT_ADDR)\n .with_session_code(session_code, runtime_args! {})\n .build();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The caller deploy is signed by ",(0,s.jsx)(t.code,{children:"account_addr_1"})," and ",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),":"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"let entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, *DEFAULT_ACCOUNT_ADDR])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\nbuilder.exec(entry_point_request).expect_success().commit();\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The test then verifies that the result returned was saved in the named keys for ",(0,s.jsx)(t.code,{children:"ACCOUNT_USER_1"}),", containing the default account hash."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'let intersection_receipt: Key = *builder\n .get_expected_account(account_addr_1)\n .named_keys()\n .get(INTERSECTION_RECEIPT)\n .expect("must have this entry in named keys");\n\nlet actual_intersection = builder\n .query(None, intersection_receipt, &[])\n .expect("must have stored_value")\n .as_cl_value()\n .map(|intersection_cl_value| {\n CLValue::into_t::<Vec<AccountHash>>(intersection_cl_value.clone())\n })\n .unwrap()\n .unwrap();\n\nlet expected_intersection = vec![*DEFAULT_ACCOUNT_ADDR];\n\nassert_eq!(actual_intersection, expected_intersection);\n'})}),"\n",(0,s.jsxs)(t.h4,{id:"test-8-should_disallow_entry_point_through_contract_call_without_authorization_key",children:["Test 8: ",(0,s.jsx)(t.code,{children:"should_disallow_entry_point_through_contract_call_without_authorization_key"})]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(t.table,{children:[(0,s.jsx)(t.thead,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.th,{children:"Installer deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Caller deploy authorization keys"}),(0,s.jsx)(t.th,{children:"Intersection returned by the entry point"})]})}),(0,s.jsx)(t.tbody,{children:(0,s.jsxs)(t.tr,{children:[(0,s.jsx)(t.td,{children:(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"})}),(0,s.jsxs)(t.td,{children:[(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"})]}),(0,s.jsx)(t.td,{children:"None"})]})})]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/blob/6810ac3d6d65e252770561ddac9b33bf40aadc03/authorization-keys-example/tests/src/integration_tests.rs#L509",children:"final test"})," in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (",(0,s.jsx)(t.code,{children:"account_addr_1"}),", ",(0,s.jsx)(t.code,{children:"account_addr_2"}),") and the installer deploy's authorization keys (",(0,s.jsx)(t.code,{children:"DEFAULT_ACCOUNT_ADDR"}),"), the entry point returns an error."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:' let session_code = PathBuf::from(CONTRACT_CALL_WASM);\n\nlet session_args = runtime_args! {\n ARG_CONTRACT_HASH => Key::from(contract_hash),\n ARG_KEY_NAME => INTERSECTION_RECEIPT\n};\n\n// account_addr_2 as an associated key is not among the default account\'s associated keys\n// The deploy will therefore revert with PermissionDenied\nlet entry_point_deploy_item = DeployItemBuilder::new()\n .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})\n .with_authorization_keys(&[account_addr_1, account_addr_2])\n .with_address(account_addr_1)\n .with_session_code(session_code, session_args)\n .build();\n\nlet entry_point_request =\n ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();\n\nbuilder.exec(entry_point_request).commit().expect_failure();\n\nlet error = builder.get_error().expect("must have User error: 0");\nassert_expected_error(\n error,\n 0,\n "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",\n);\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const i={},a=s.createContext(i);function r(e){const t=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),s.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c474c2b1.b1dce14d.js b/assets/js/c474c2b1.b1dce14d.js new file mode 100644 index 000000000..3de276623 --- /dev/null +++ b/assets/js/c474c2b1.b1dce14d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9603],{87771:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>p,frontMatter:()=>r,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const r={title:"Upgrades"},a="Upgrading the Node",i={id:"operators/setup/upgrade",title:"Upgrades",description:"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.",source:"@site/versioned_docs/version-2.0.0/operators/setup/upgrade.md",sourceDirName:"operators/setup",slug:"/operators/setup/upgrade",permalink:"/2.0.0/operators/setup/upgrade",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Upgrades"},sidebar:"operators",previous:{title:"Open Files Limit",permalink:"/2.0.0/operators/setup/open-files"},next:{title:"Join a Network",permalink:"/2.0.0/operators/setup/joining"}},c={},d=[{value:"Upgrading Protocol Versions",id:"upgrading-protocol-versions",level:2},{value:"Upgrade Staging Instructions",id:"upgrade-staging-instructions",level:3},{value:"Verifying Successful Staging",id:"verifying-successful-staging",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"upgrading-the-node",children:"Upgrading the Node"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:(0,s.jsx)(n.code,{children:"chainspec.toml"})})," contains a section to indicate from which era the given ",(0,s.jsx)(n.code,{children:"casper-node"})," version should start running."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"[protocol]\n# This protocol version becomes active at the start of this era.\nactivation_point = 100\n"})}),"\n",(0,s.jsxs)(n.p,{children:["At every block finalization, the ",(0,s.jsx)(n.code,{children:"casper-node"})," looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the ",(0,s.jsx)(n.code,{children:"chainspec.toml"})," file. This will be the era before where the current casper-node will cleanly shut down."]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"casper-node-launcher"})," will detect a clean exit 0 condition and start the next version of the ",(0,s.jsx)(n.code,{children:"casper-node"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"upgrading-protocol-versions",children:"Upgrading Protocol Versions"}),"\n",(0,s.jsxs)(n.p,{children:["All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of ",(0,s.jsx)(n.code,{children:"casper-node"})," immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point."]}),"\n",(0,s.jsx)(n.p,{children:"Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point."}),"\n",(0,s.jsx)(n.h3,{id:"upgrade-staging-instructions",children:"Upgrade Staging Instructions"}),"\n",(0,s.jsx)(n.p,{children:"The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:["On Testnet, use ",(0,s.jsx)(n.code,{children:"casper-test.conf"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": To only view the list of staged and unstaged protocols, use this command: ",(0,s.jsx)(n.code,{children:"sudo -u casper /etc/casper/node_util.py check_protocols casper.conf"})]}),"\n",(0,s.jsx)(n.h3,{id:"verifying-successful-staging",children:"Verifying Successful Staging"}),"\n",(0,s.jsx)(n.p,{children:"After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"curl -s http://127.0.0.1:8888/status | jq .next_upgrade\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should expect this output if properly staged, prior to upgrading:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'$ curl -s localhost:8888/status | jq .next_upgrade\n{\n "activation_point": 4968,\n "protocol_version": "1.4.6"\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["If you see ",(0,s.jsx)(n.code,{children:"null"})," after waiting for a few minutes, then your upgrade staging was not executed successfully."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": The protocol version will change as per the next upgrade available."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},r=s.createContext(o);function a(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c52eaa26.32d71864.js b/assets/js/c52eaa26.32d71864.js deleted file mode 100644 index 96b59228a..000000000 --- a/assets/js/c52eaa26.32d71864.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6938],{83106:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"Private Network Setup"},r="Setting Up a Private Casper Network",o={id:"operators/setup-network/create-private",title:"Private Network Setup",description:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.",source:"@site/docs/operators/setup-network/create-private.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/create-private",permalink:"/next/operators/setup-network/create-private",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{title:"Private Network Setup"},sidebar:"operators",previous:{title:"The Chainspec",permalink:"/next/operators/setup-network/chain-spec"},next:{title:"Staging Files",permalink:"/next/operators/setup-network/staging-files-for-new-network"}},c={},d=[{value:"Contents",id:"contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1. Setting up a Validator Node",id:"step-1-setting-up-a-validator-node",level:2},{value:"Step 2. Setting up the Directory",id:"step-2-setting-up-the-directory",level:2},{value:"Step 3. Configuring the Genesis Block",id:"step-3-configuring-the-genesis-block",level:2},{value:"Unrestricted transfers configuration",id:"unrestricted-transfers-configuration",level:3},{value:"Refund handling configuration",id:"refund-handling-configuration",level:3},{value:"Fee handling configuration",id:"fee-handling-configuration",level:3},{value:"Auction behavior configuration",id:"auction-behavior-configuration",level:3},{value:"Step 4. Configuring the Administrator Accounts",id:"step-4-configuring-the-administrator-accounts",level:2},{value:"Configuring administrator accounts",id:"configuring-administrator-accounts",level:3},{value:"Generating new administrator accounts",id:"generating-new-administrator-accounts",level:3},{value:"Managing accounts and smart contracts",id:"managing-accounts-and-smart-contracts",level:3},{value:"Step 5. Starting the Casper Node",id:"step-5-starting-the-casper-node",level:2},{value:"Step 6. Rotating the Validator Accounts",id:"step-6-rotating-the-validator-accounts",level:2},{value:"Step 7. Testing the Private Network",id:"step-7-testing-the-private-network",level:2},{value:"Sample configuration files",id:"sample-configuration-files",level:3},{value:"Specifying IP addresses",id:"specifying-ip-addresses",level:3},{value:"Setting up the node",id:"setting-up-the-node",level:3},{value:"Network access control",id:"network-access-control",level:3},{value:"Funding Alice's account",id:"funding-alices-account",level:3},{value:"Adding a bid as Alice",id:"adding-a-bid-as-alice",level:3},{value:"Disabling Alice's account",id:"disabling-alices-account",level:3},{value:"Enabling Alice's account",id:"enabling-alices-account",level:3},{value:"Enabling a contract",id:"enabling-a-contract",level:3},{value:"Disabling a contract",id:"disabling-a-contract",level:3},{value:"Verifying seigniorage allocations",id:"verifying-seigniorage-allocations",level:3},{value:"Operating guide",id:"operating-guide",level:3},{value:"Rotating validators",id:"rotating-validators",level:3},{value:"Adding new administrators",id:"adding-new-administrators",level:3},{value:"Setting up a Block Explorer",id:"setting-up-a-block-explorer",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"setting-up-a-private-casper-network",children:"Setting Up a Private Casper Network"})}),"\n",(0,a.jsx)(n.p,{children:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network."}),"\n",(0,a.jsx)(n.h2,{id:"contents",children:"Contents"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"Setting up a Validator Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-2-setting-up-the-directory",children:"Setting up the Directory"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-3-configuring-the-genesis-block",children:"Configuring the Genesis Block"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-4-configuring-the-administrator-accounts",children:"Configuring the Administrator Accounts"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-5-starting-the-casper-node",children:"Starting the Casper Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-7-testing-the-private-network",children:"Testing the Private Network"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#setting-up-a-block-explorer",children:"Setting up a Block Explorer"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Follow these guides to set up the required environment and user accounts."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Setting up the Casper client"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/blob/dev/README.md#casper-client",children:"Setting up the client for interacting with the network"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"Setting up an Account"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-1-setting-up-a-validator-node",children:"Step 1. Setting up a Validator Node"}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/N#node",children:"Casper node"})," is a physical or virtual device participating in a Casper network. You need to set up several ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validator"})," nodes on your private network. An ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/O#operator",children:"operator"})," who has won an ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/A#auction",children:"auction"})," bid will be a validator for the private network."]}),"\n",(0,a.jsx)(n.p,{children:"Use the below guides to set up and manage validator nodes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup - GitHub guide"}),": A guide to configuring a system with the new Rust node to operate within a network."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration",children:"Basic node setup tutorial"}),": A guide on using the ",(0,a.jsx)(n.code,{children:"casper-node-launcher"}),", generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://docs.cspr.community/",children:"Set up Mainnet and Testnet validator nodes"}),": A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use these FAQ collections for tips and details for validators."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-2-setting-up-the-directory",children:"Step 2. Setting up the Directory"}),"\n",(0,a.jsx)(n.p,{children:"Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Go through the ",(0,a.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#file-locations",children:"file location"})," section to understand how directories are created and managed in a Casper private network."]}),"\n",(0,a.jsxs)(n.li,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"/next/operators/setup-network/chain-spec",children:"setting up a new network"})," guide to identify the required configuration files to set up a genesis block."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-3-configuring-the-genesis-block",children:"Step 3. Configuring the Genesis Block"}),"\n",(0,a.jsxs)(n.p,{children:["A Casper private network contains a different set of configurations when compared to the public network. The ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:(0,a.jsx)(n.code,{children:"chainspec.toml"})})," file contains the required configurations for the genesis process in a private network."]}),"\n",(0,a.jsxs)(n.p,{children:["You should add the configuration options below to the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file inside the ",(0,a.jsx)(n.a,{href:"/next/operators/setup-network/create-private#step-2-setting-up-the-directory",children:"private network directory"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"unrestricted-transfers-configuration",children:"Unrestricted transfers configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"In contrast, users in the public network can freely transfer funds to different accounts."}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nallow_unrestricted_transfers = false\ncompute_rewards = false\nallow_auction_bids = false\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\nfee_handling = { type = "accumulate" }\nadministrators = ["ADMIN_PUBLIC_KEY"]\n'})}),(0,a.jsxs)(n.p,{children:["The Casper Mainnet has different refund and fee handling configurations explained in more detail ",(0,a.jsx)(n.a,{href:"/next/concepts/economics/fee-elimination",children:"here"}),"."]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = true\ncompute_rewards = true\nallow_auction_bids = true\nrefund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\nadministrators = []\n"})})]}),"\n",(0,a.jsx)(n.h3,{id:"refund-handling-configuration",children:"Refund handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user."}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Another example: a refund variant with ",(0,a.jsx)(n.code,{children:"refund_ratio"})," of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return."]}),"\n",(0,a.jsxs)(n.p,{children:["After deducting the gas fee, the distribution of the remaining payment amount is handled based on the ",(0,a.jsx)(n.a,{href:"/next/operators/setup-network/create-private#fee-handling-config",children:"fee_handling"})," configuration."]}),"\n",(0,a.jsx)(n.p,{children:"Starting with the Condor release, a Casper private network can eliminate fees and, thus, not require refunds, similar to the Casper Mainnet:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"refund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\n"})}),"\n",(0,a.jsx)(n.h3,{id:"fee-handling-configuration",children:"Fee handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed."}),"\n",(0,a.jsx)(n.p,{children:"Set up the configuration as below:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nfee_handling = { type = "pay_to_proposer" }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"fee_handling"})," configuration has four variations:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"no_fee"}),": Fees are eliminated. No refunds are necessary."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"pay_to_proposer"}),": The rest of the payment amount after deducing the gas fee from a refund is paid to the block's ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/P#proposer",children:"proposer"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"burn"}),": The tokens paid are burned, and the total supply is reduced."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"accumulate"}),": The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"auction-behavior-configuration",children:"Auction behavior configuration"}),"\n",(0,a.jsx)(n.p,{children:"A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set."}),"\n",(0,a.jsx)(n.p,{children:"Use the configuration below to limit the auction validators:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_auction_bids = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Other configurations related to the auction:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"allow_auction_bids"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"})," then ",(0,a.jsx)(n.code,{children:"add_bid"})," and ",(0,a.jsx)(n.code,{children:"delegate"})," options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an ",(0,a.jsx)(n.code,{children:"AuctionBidsDisabled"})," error."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"core.compute_rewards"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"}),", then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In a public network, ",(0,a.jsx)(n.code,{children:"allow_auction_bid"})," is set to ",(0,a.jsx)(n.em,{children:"true"}),", which allows bidding for new entries and validator nodes."]}),"\n",(0,a.jsx)(n.h2,{id:"step-4-configuring-the-administrator-accounts",children:"Step 4. Configuring the Administrator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["An administrator is mandatory for a private network since it manages all the other ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validator"})," accounts. There should be at least one administrator account configured within a network to operate it as a ",(0,a.jsx)(n.code,{children:"private network"}),". You can create new administrators and ",(0,a.jsx)(n.a,{href:"/next/operators/setup-network/create-private#step-6-rotating-the-validator-accounts",children:"rotate the validator set"})," in a single configuration update. The operator must first ensure the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances."]}),"\n",(0,a.jsx)(n.h3,{id:"configuring-administrator-accounts",children:"Configuring administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use this configuration option in the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," to add administrator accounts to the private network:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_ACCOUNT_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note"}),": Regular accounts are not allowed to manage their associated keys on a private network."]}),"\n",(0,a.jsx)(n.h3,{id:"generating-new-administrator-accounts",children:"Generating new administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use the command below to generate new administrator accounts in your private network. This generates the contents of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the entries required to create new administrator accounts at the upgrade point."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen \\\n generate-admins --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n --admin $PUBLIC_KEY_HEX, $BALANCE\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_PUBLIC_KEY"})," - Public key of the administrator in a hex format."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_BALANCE"})," - Balance for the administrator\u2019s main purse."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"DATA_DIR"})," - Path to the global state directory."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"STATE_ROOT_HASH"})," - State root hash, taken from the latest block before an upgrade."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"managing-accounts-and-smart-contracts",children:"Managing accounts and smart contracts"}),"\n",(0,a.jsxs)(n.p,{children:["Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/c8023736786b2c2b0fd17250fcfd50502ff4151f/smart_contracts/contracts/private_chain/control-management/src/main.rs",children:"Casper node's private chain control management"})," file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key."]}),"\n",(0,a.jsx)(n.p,{children:"Use this command to generate these contracts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"make build-contracts-rs\n"})}),"\n",(0,a.jsx)(n.p,{children:"Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"disable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"enable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with argument ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='255'"})," and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='255'"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='1'"})," set to 1 and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='0'"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-5-starting-the-casper-node",children:"Step 5. Starting the Casper Node"}),"\n",(0,a.jsx)(n.p,{children:"After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup GitHub"})," guide to know more details about configuring a new node to operate within a network."]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally, refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"casper-node-launcher"})," to check whether the installed node binaries match the installed configurations by comparing the version numbers."]}),"\n",(0,a.jsx)(n.h2,{id:"step-6-rotating-the-validator-accounts",children:"Step 6. Rotating the Validator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["You need to go through ",(0,a.jsx)(n.a,{href:"#step-1-setting-up-the-validator-nodes",children:"setting up a validator node "})," guide before starting this section."]}),"\n",(0,a.jsxs)(n.p,{children:["To rotate the validators set, you must perform a network upgrade using a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.p,{children:"When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block."}),"\n",(0,a.jsxs)(n.p,{children:["After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"\nglobal-state-update-gen validators \\\n --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE\n\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Each use of the ",(0,a.jsx)(n.code,{children:"--validator"})," parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter."]}),"\n",(0,a.jsxs)(n.p,{children:["After designating the next era's validators, you must set the chainspec activation point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to ",(0,a.jsx)(n.code,{children:"X"}),", where ",(0,a.jsx)(n.code,{children:"X"})," is equal to the new era after the switch block from above. Finally, set ",(0,a.jsx)(n.code,{children:"hard_reset = true"}),". This makes the network revert to the end of the previous era when restarted with the upgrade."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),", set the activaction point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to 10 and ",(0,a.jsx)(n.code,{children:"hard_reset"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Please make sure you are running this tool as the same user that owns ",(0,a.jsx)(n.code,{children:"$DATA_DIR"}),". Otherwise, you may receive a permission denied error."]})}),"\n",(0,a.jsxs)(n.p,{children:["You can find more details on enabling new validators in the ",(0,a.jsx)(n.a,{href:"/next/operators/setup/joining",children:"joining a running network"})," guide. The guide explains how to join the network and provide additional security to the system."]}),"\n",(0,a.jsx)(n.h2,{id:"step-7-testing-the-private-network",children:"Step 7. Testing the Private Network"}),"\n",(0,a.jsx)(n.p,{children:"We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer."}),"\n",(0,a.jsx)(n.h3,{id:"sample-configuration-files",children:"Sample configuration files"}),"\n",(0,a.jsx)(n.p,{children:"Here are sample configurations that can be adapted for testing:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["A ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/chainspec.toml.in",children:"chainspec template"})," that is specific to the customer's private chain."]}),"\n",(0,a.jsxs)(n.li,{children:["An ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/accounts.toml.in",children:"accounts template"})," with one administrator in the ",(0,a.jsx)(n.code,{children:"administrators"})," settings."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"specifying-ip-addresses",children:"Specifying IP addresses"}),"\n",(0,a.jsx)(n.p,{children:"Here is an example set of IP addresses in use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"http://18.224.190.213:7777\nhttp://18.188.11.97:7777\nhttp://18.188.206.170:7777\nhttp://18.116.201.114:7777\n"})}),"\n",(0,a.jsx)(n.h3,{id:"setting-up-the-node",children:"Setting up the node"}),"\n",(0,a.jsx)(n.p,{children:"Set up the node address, chain name, and the administrator's secret key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'export NODE_ADDR=http://18.224.190.213:7777\nexport CHAIN_NAME="private-test"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This testing example will also use an ",(0,a.jsx)(n.code,{children:"alice/secret_key.pem"})," file, a secret key generated through the ",(0,a.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#creating-accounts-and-keys",children:"keys generation process"}),". Alice is a regular user in this testing example."]}),"\n",(0,a.jsx)(n.h3,{id:"network-access-control",children:"Network access control"}),"\n",(0,a.jsx)(n.p,{children:"With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed."}),"\n",(0,a.jsx)(n.p,{children:"To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "local_node_cert.pem"\nsecret_key = "local_node.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"tls_certificate"})," is the certificate signed by a ",(0,a.jsx)(n.code,{children:"ca_cert.pem"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secret_key"})," refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ca_certificate"})," is the network CA that should be the same on each of the nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'# Recommended EC curve algorithm to use\nexport CURVE="secp521r1"\n\n# Generate secret key for CA and save it to ca_key.pem\nopenssl ecparam -out ca_key.pem -name $CURVE -genkey\n# Create ca_cert.pem signed by ca_key.pem\nopenssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem\n\n# Generate secret key for a node and a certificate signed by the CA\nopenssl ecparam -out node_1.pem -name $CURVE -genkey\nopenssl req -new -key node_1.pem -out node_1.csr -sha256\nopenssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem\n'})}),"\n",(0,a.jsx)(n.p,{children:"And then configure the node with the following settings:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "node_1_cert.pem"\nsecret_key = "node_1.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Every node in the private chain network has to be configured with the same CA certificate, and each ",(0,a.jsx)(n.code,{children:"tls_certificate"})," and ",(0,a.jsx)(n.code,{children:"secret_key"})," pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Keep in mind that for security reasons ",(0,a.jsx)(n.code,{children:"ca_key.pem"})," should be stored securely and never present on each of participating machines."]}),"\n",(0,a.jsx)(n.h3,{id:"funding-alices-account",children:"Funding Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command transfers tokens to Alice's main purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n transfer \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<admin/public_key_hex) \\\n --target-account=$(<alice/public_key_hex) \\\n --amount=100000000000 \\\n --payment-amount=3000000000 \\\n --transfer-id=123\n"})}),"\n",(0,a.jsx)(n.p,{children:"To check the account information, use this command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-account-info -n $NODE_ADDR\n --public-key alice/public_key.pem\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-a-bid-as-alice",children:"Adding a bid as Alice"}),"\n",(0,a.jsxs)(n.p,{children:["The following command attempts to add an auction bid on the network. It should return ",(0,a.jsx)(n.code,{children:"ApiError::AuctionError(AuctionBidsDisabled) [64559]"}),"."]}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["All payment amounts in these examples must be adjusted based on the network ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key alice/secret_key.pem \\\n --session-path add_bid.wasm \\\n --payment-amount 5000000000 \\\n --session-arg "public_key:public_key=\'$(<alice/public_key_hex)\'" \\\n --session-arg "amount:u512=\'10000\'" \\\n --session-arg "delegation_rate:u8=\'5\'"\n\n# Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"\n'})}),"\n",(0,a.jsx)(n.p,{children:"We should get a similar error for the delegate entry point."}),"\n",(0,a.jsx)(n.h3,{id:"disabling-alices-account",children:"Disabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='255'\" \\\n --session-arg \"deploy_threshold:u8='255'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-alices-account",children:"Enabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='0'\" \\\n --session-arg \"deploy_threshold:u8='1'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-a-contract",children:"Enabling a contract"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables a contract using its hash."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path enable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"disabling-a-contract",children:"Disabling a contract"}),"\n",(0,a.jsxs)(n.p,{children:["The following command disables a contract using its hash. Executing this contract using ",(0,a.jsx)(n.code,{children:"CONTRACT_HASH"})," again should fail."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path disable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:"Alice needs a container access key for the contract package in her named keys."}),"\n",(0,a.jsx)(n.h3,{id:"verifying-seigniorage-allocations",children:"Verifying seigniorage allocations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://www.investopedia.com/terms/s/seigniorage.asp",children:"Seigniorage"})," allocations should be zero at each switch block. This is the related configuration:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\ncompute_rewards = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Validator stakes should not increase on each switch block. Run this command to verify this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-era-info -n $NODE_ADDR -b 153\n"})}),"\n",(0,a.jsx)(n.p,{children:"The total supply shouldn't increase, and the validator's stakes should remain the same."}),"\n",(0,a.jsx)(n.h3,{id:"operating-guide",children:"Operating guide"}),"\n",(0,a.jsxs)(n.p,{children:["Some configuration options such as ",(0,a.jsx)(n.code,{children:"allow_auction_bids"})," require a private chain operator to perform specific tasks manually through a network upgrade with chainspec and contents of ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file generated by a provided tool ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can find this tool by either downloading a package or by installing it manually from the sources:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ cargo install --git https://github.com/casper-network/casper-node/ --tag private-1.4.6 global-state-update-gen\n$ global-state-update-gen --help\nGlobal State Update Generator 0.2.0\nGenerates a global state update file based on the supplied parameters\n\nUSAGE:\n global-state-update-gen [SUBCOMMAND]\n\nFLAGS:\n -h, --help Prints help information\n -V, --version Prints version information\n\nSUBCOMMANDS:\n balances Generates an update changing account balances\n generate-admins Generates entries to create new admin accounts on a private chain\n help Prints this message or the help of the given subcommand(s)\n system-contract-registry Generates an update creating the system contract registry\n validators Generates an update changing the validators set\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The standard output of running commands listed above is the content of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file, which contains a list of direct global state modifications."]}),"\n",(0,a.jsxs)(n.p,{children:["Example output of running a ",(0,a.jsx)(n.code,{children:"generate-admins"})," subcommand:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[[entries]]\nkey = "balance-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13"\nvalue = "AAIAAAABCgg="\n\n[[entries]]\nkey = "uref-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13-007"\nvalue = "AAAAAAAJ"\n\n[[entries]]\nkey = "account-hash-ac2f4caa3e3ce1cd1dfb3d089854020b18a50cac49977d0a4c873c4d3d5a2409"\nvalue = "AawvTKo+POHNHfs9CJhUAgsYpQysSZd9CkyHPE09WiQJAAAAAJe7zCQls+2lFJqJPGGAti8UctUUO7FFDQHI4elr4J8TBwEAAACsL0yqPjzhzR37PQiYVAILGKUMrEmXfQpMhzxNPVokCQEBAQ=="\n\n# total supply increases from 200000000000000000 to 200000000000000010\n[[entries]]\nkey = "uref-f8475fd4125484be39a0793530f09a29d220ffda8e48387b3d2194ddfc22894e-007"\nvalue = "AAkAAAAICgAUu/CKxgII"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Currently, this tool outputs contents into standard output. You should redirect standard output to a file named ",(0,a.jsx)(n.code,{children:"global_state.toml"})," and place this file in the same directory as ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," before performing a network upgrade."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ global-state-update-gen generate-admins --data-dir $DATA_DIR --state-hash $STATE_HASH --admin NEW_PUBLIC_KEY,BALANCE >> global_state.toml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By using ",(0,a.jsx)(n.code,{children:">>"})," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."]}),"\n",(0,a.jsx)(n.p,{children:"Common options:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--data-dir"})," path to a global state directory where ",(0,a.jsx)(n.code,{children:"data.lmdb"})," can be found"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--state-hash"})," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"rotating-validators",children:"Rotating validators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command rotates the validator set. Perform a network upgrade with a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-new-administrators",children:"Adding new administrators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command produces the administrator content in the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n"})}),"\n",(0,a.jsx)(n.p,{children:"Remember that new administrators can be created, and the validator set can also be rotated in a single update."}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"After this step, the private network would be ready for use."}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-a-block-explorer",children:"Setting up a Block Explorer"}),"\n",(0,a.jsxs)(n.p,{children:["Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-blockexplorer-frontend",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c52eaa26.dc4744b9.js b/assets/js/c52eaa26.dc4744b9.js new file mode 100644 index 000000000..718ace3e7 --- /dev/null +++ b/assets/js/c52eaa26.dc4744b9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16938],{83106:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>d});var a=t(74848),s=t(28453);const i={title:"Private Network Setup"},r="Setting Up a Private Casper Network",o={id:"operators/setup-network/create-private",title:"Private Network Setup",description:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.",source:"@site/docs/operators/setup-network/create-private.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/create-private",permalink:"/operators/setup-network/create-private",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{title:"Private Network Setup"},sidebar:"operators",previous:{title:"The Chainspec",permalink:"/operators/setup-network/chain-spec"},next:{title:"Staging Files",permalink:"/operators/setup-network/staging-files-for-new-network"}},c={},d=[{value:"Contents",id:"contents",level:2},{value:"Prerequisites",id:"prerequisites",level:2},{value:"Step 1. Setting up a Validator Node",id:"step-1-setting-up-a-validator-node",level:2},{value:"Step 2. Setting up the Directory",id:"step-2-setting-up-the-directory",level:2},{value:"Step 3. Configuring the Genesis Block",id:"step-3-configuring-the-genesis-block",level:2},{value:"Unrestricted transfers configuration",id:"unrestricted-transfers-configuration",level:3},{value:"Refund handling configuration",id:"refund-handling-configuration",level:3},{value:"Fee handling configuration",id:"fee-handling-configuration",level:3},{value:"Auction behavior configuration",id:"auction-behavior-configuration",level:3},{value:"Step 4. Configuring the Administrator Accounts",id:"step-4-configuring-the-administrator-accounts",level:2},{value:"Configuring administrator accounts",id:"configuring-administrator-accounts",level:3},{value:"Generating new administrator accounts",id:"generating-new-administrator-accounts",level:3},{value:"Managing accounts and smart contracts",id:"managing-accounts-and-smart-contracts",level:3},{value:"Step 5. Starting the Casper Node",id:"step-5-starting-the-casper-node",level:2},{value:"Step 6. Rotating the Validator Accounts",id:"step-6-rotating-the-validator-accounts",level:2},{value:"Step 7. Testing the Private Network",id:"step-7-testing-the-private-network",level:2},{value:"Sample configuration files",id:"sample-configuration-files",level:3},{value:"Specifying IP addresses",id:"specifying-ip-addresses",level:3},{value:"Setting up the node",id:"setting-up-the-node",level:3},{value:"Network access control",id:"network-access-control",level:3},{value:"Funding Alice's account",id:"funding-alices-account",level:3},{value:"Adding a bid as Alice",id:"adding-a-bid-as-alice",level:3},{value:"Disabling Alice's account",id:"disabling-alices-account",level:3},{value:"Enabling Alice's account",id:"enabling-alices-account",level:3},{value:"Enabling a contract",id:"enabling-a-contract",level:3},{value:"Disabling a contract",id:"disabling-a-contract",level:3},{value:"Verifying seigniorage allocations",id:"verifying-seigniorage-allocations",level:3},{value:"Operating guide",id:"operating-guide",level:3},{value:"Rotating validators",id:"rotating-validators",level:3},{value:"Adding new administrators",id:"adding-new-administrators",level:3},{value:"Setting up a Block Explorer",id:"setting-up-a-block-explorer",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"setting-up-a-private-casper-network",children:"Setting Up a Private Casper Network"})}),"\n",(0,a.jsx)(n.p,{children:"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network."}),"\n",(0,a.jsx)(n.h2,{id:"contents",children:"Contents"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-1-setting-up-a-validator-node",children:"Setting up a Validator Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-2-setting-up-the-directory",children:"Setting up the Directory"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-3-configuring-the-genesis-block",children:"Configuring the Genesis Block"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-4-configuring-the-administrator-accounts",children:"Configuring the Administrator Accounts"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-5-starting-the-casper-node",children:"Starting the Casper Node"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#step-7-testing-the-private-network",children:"Testing the Private Network"})}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.a,{href:"#setting-up-a-block-explorer",children:"Setting up a Block Explorer"})}),"\n"]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,a.jsx)(n.p,{children:"Follow these guides to set up the required environment and user accounts."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Setting up the Casper client"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/blob/dev/README.md#casper-client",children:"Setting up the client for interacting with the network"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Setting up an Account"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-1-setting-up-a-validator-node",children:"Step 1. Setting up a Validator Node"}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"Casper node"})," is a physical or virtual device participating in a Casper network. You need to set up several ",(0,a.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validator"})," nodes on your private network. An ",(0,a.jsx)(n.a,{href:"/concepts/glossary/O#operator",children:"operator"})," who has won an ",(0,a.jsx)(n.a,{href:"/concepts/glossary/A#auction",children:"auction"})," bid will be a validator for the private network."]}),"\n",(0,a.jsx)(n.p,{children:"Use the below guides to set up and manage validator nodes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup - GitHub guide"}),": A guide to configuring a system with the new Rust node to operate within a network."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic node setup tutorial"}),": A guide on using the ",(0,a.jsx)(n.code,{children:"casper-node-launcher"}),", generating directories and files needed for running casper-node versions and performing upgrades, generating keys, and setting up the configuration file for nodes."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://docs.cspr.community/",children:"Set up Mainnet and Testnet validator nodes"}),": A set of guides for Mainnet and Testnet node-operators on setting up and configuring their Casper network validator nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"Use these FAQ collections for tips and details for validators."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-2-setting-up-the-directory",children:"Step 2. Setting up the Directory"}),"\n",(0,a.jsx)(n.p,{children:"Use these guides to set up your private network directories. You will find several main directories dedicated to different purposes."}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["Go through the ",(0,a.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#file-locations",children:"file location"})," section to understand how directories are created and managed in a Casper private network."]}),"\n",(0,a.jsxs)(n.li,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"setting up a new network"})," guide to identify the required configuration files to set up a genesis block."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-3-configuring-the-genesis-block",children:"Step 3. Configuring the Genesis Block"}),"\n",(0,a.jsxs)(n.p,{children:["A Casper private network contains a different set of configurations when compared to the public network. The ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:(0,a.jsx)(n.code,{children:"chainspec.toml"})})," file contains the required configurations for the genesis process in a private network."]}),"\n",(0,a.jsxs)(n.p,{children:["You should add the configuration options below to the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file inside the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private#step-2-setting-up-the-directory",children:"private network directory"}),"."]}),"\n",(0,a.jsx)(n.h3,{id:"unrestricted-transfers-configuration",children:"Unrestricted transfers configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option disables unrestricted transfers between regular account purses. A regular account user cannot do a fund transfer when this attribute is set to false. Only administrators can transfer tokens freely between users and other administrators."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"In contrast, users in the public network can freely transfer funds to different accounts."}),"\n",(0,a.jsxs)(n.admonition,{type:"note",children:[(0,a.jsx)(n.p,{children:"A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nallow_unrestricted_transfers = false\ncompute_rewards = false\nallow_auction_bids = false\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\nfee_handling = { type = "accumulate" }\nadministrators = ["ADMIN_PUBLIC_KEY"]\n'})}),(0,a.jsxs)(n.p,{children:["The Casper Mainnet has different refund and fee handling configurations explained in more detail ",(0,a.jsx)(n.a,{href:"/concepts/economics/fee-elimination",children:"here"}),"."]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_unrestricted_transfers = true\ncompute_rewards = true\nallow_auction_bids = true\nrefund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\nadministrators = []\n"})})]}),"\n",(0,a.jsx)(n.h3,{id:"refund-handling-configuration",children:"Refund handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user."}),"\n",(0,a.jsxs)(n.p,{children:["A ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the ",(0,a.jsx)(n.code,{children:"refund_ratio"})," is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nrefund_handling = { type = "refund", refund_ratio = [1, 1] }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Another example: a refund variant with ",(0,a.jsx)(n.code,{children:"refund_ratio"})," of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return."]}),"\n",(0,a.jsxs)(n.p,{children:["After deducting the gas fee, the distribution of the remaining payment amount is handled based on the ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private#fee-handling-config",children:"fee_handling"})," configuration."]}),"\n",(0,a.jsx)(n.p,{children:"Starting with the Condor release, a Casper private network can eliminate fees and, thus, not require refunds, similar to the Casper Mainnet:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"refund_handling = { type = 'no_refund' }\nfee_handling = { type = 'no_fee' }\n"})}),"\n",(0,a.jsx)(n.h3,{id:"fee-handling-configuration",children:"Fee handling configuration"}),"\n",(0,a.jsx)(n.p,{children:"This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed."}),"\n",(0,a.jsx)(n.p,{children:"Set up the configuration as below:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nfee_handling = { type = "pay_to_proposer" }\n'})}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"fee_handling"})," configuration has four variations:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"no_fee"}),": Fees are eliminated. No refunds are necessary."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"pay_to_proposer"}),": The rest of the payment amount after deducing the gas fee from a refund is paid to the block's ",(0,a.jsx)(n.a,{href:"/concepts/glossary/P#proposer",children:"proposer"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"burn"}),": The tokens paid are burned, and the total supply is reduced."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"accumulate"}),": The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"auction-behavior-configuration",children:"Auction behavior configuration"}),"\n",(0,a.jsx)(n.p,{children:"A private network requires to have a fixed set of validators. This configuration restricts the addition of new validators to the private network. Hence, you are not allowed to bid new entries into the validator set."}),"\n",(0,a.jsx)(n.p,{children:"Use the configuration below to limit the auction validators:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\nallow_auction_bids = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Other configurations related to the auction:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"allow_auction_bids"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"})," then ",(0,a.jsx)(n.code,{children:"add_bid"})," and ",(0,a.jsx)(n.code,{children:"delegate"})," options are disabled. It also disables adding new validators to the system. Invoking those entry points leads to an ",(0,a.jsx)(n.code,{children:"AuctionBidsDisabled"})," error."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"core.compute_rewards"})," - if this option is set to ",(0,a.jsx)(n.em,{children:"false"}),", then all the rewards on a switch block will be set to 0. The auction contract wouldn't process rewards distribution that would increase validator bids."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["In a public network, ",(0,a.jsx)(n.code,{children:"allow_auction_bid"})," is set to ",(0,a.jsx)(n.em,{children:"true"}),", which allows bidding for new entries and validator nodes."]}),"\n",(0,a.jsx)(n.h2,{id:"step-4-configuring-the-administrator-accounts",children:"Step 4. Configuring the Administrator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["An administrator is mandatory for a private network since it manages all the other ",(0,a.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validator"})," accounts. There should be at least one administrator account configured within a network to operate it as a ",(0,a.jsx)(n.code,{children:"private network"}),". You can create new administrators and ",(0,a.jsx)(n.a,{href:"/operators/setup-network/create-private#step-6-rotating-the-validator-accounts",children:"rotate the validator set"})," in a single configuration update. The operator must first ensure the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file contains new administrators. The validator set is updated after if an administrator is also a validator. Also, only purses of administrator accounts can hold and distribute token balances."]}),"\n",(0,a.jsx)(n.h3,{id:"configuring-administrator-accounts",children:"Configuring administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use this configuration option in the ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," to add administrator accounts to the private network:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_ACCOUNT_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"Note"}),": Regular accounts are not allowed to manage their associated keys on a private network."]}),"\n",(0,a.jsx)(n.h3,{id:"generating-new-administrator-accounts",children:"Generating new administrator accounts"}),"\n",(0,a.jsxs)(n.p,{children:["Use the command below to generate new administrator accounts in your private network. This generates the contents of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the entries required to create new administrator accounts at the upgrade point."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen \\\n generate-admins --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n --admin $PUBLIC_KEY_HEX, $BALANCE\n"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_PUBLIC_KEY"})," - Public key of the administrator in a hex format."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"NEW_BALANCE"})," - Balance for the administrator\u2019s main purse."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"DATA_DIR"})," - Path to the global state directory."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"STATE_ROOT_HASH"})," - State root hash, taken from the latest block before an upgrade."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"managing-accounts-and-smart-contracts",children:"Managing accounts and smart contracts"}),"\n",(0,a.jsxs)(n.p,{children:["Only administrators have permission to control accounts and manage smart contracts in a private network. An example implementation can be found in ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/c8023736786b2c2b0fd17250fcfd50502ff4151f/smart_contracts/contracts/private_chain/control-management/src/main.rs",children:"Casper node's private chain control management"})," file. This is not an existing contract. You can use the existing client contracts as an administrator to perform actions as a user. This is done by sending a deploy under a regular user's public key but signed using the administrator's secret key."]}),"\n",(0,a.jsx)(n.p,{children:"Use this command to generate these contracts:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"make build-contracts-rs\n"})}),"\n",(0,a.jsx)(n.p,{children:"Only the administrator can use the related Wasm to send the deploy to the network and then use it to manage, enable, and disable contracts. This is achieved through entry points that handle enabling and disabling options for account and smart contracts:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"disable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable a contract"}),": Execute the ",(0,a.jsx)(n.code,{children:"enable_contract.wasm"})," with ",(0,a.jsx)(n.code,{children:"contract_hash"}),"and ",(0,a.jsx)(n.code,{children:"contract_package_hash"})," as parameters."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To disable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with argument ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='255'"})," and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='255'"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.strong,{children:"To enable an account"}),": Execute ",(0,a.jsx)(n.code,{children:"set_action_thresholds.wasm"})," with ",(0,a.jsx)(n.code,{children:"deploy_threshold:u8='1'"})," set to 1 and ",(0,a.jsx)(n.code,{children:"key_management_threshold:u8='0'"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"step-5-starting-the-casper-node",children:"Step 5. Starting the Casper Node"}),"\n",(0,a.jsx)(n.p,{children:"After preparing the administrator accounts and validator nodes, you should start and run the Casper node to see the changes. Use this command to start the node:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/resources/production#casper-node-setup",children:"Casper node setup GitHub"})," guide to know more details about configuring a new node to operate within a network."]}),"\n",(0,a.jsxs)(n.p,{children:["Additionally, refer to the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node-launcher",children:"casper-node-launcher"})," to check whether the installed node binaries match the installed configurations by comparing the version numbers."]}),"\n",(0,a.jsx)(n.h2,{id:"step-6-rotating-the-validator-accounts",children:"Step 6. Rotating the Validator Accounts"}),"\n",(0,a.jsxs)(n.p,{children:["You need to go through ",(0,a.jsx)(n.a,{href:"#step-1-setting-up-the-validator-nodes",children:"setting up a validator node "})," guide before starting this section."]}),"\n",(0,a.jsxs)(n.p,{children:["To rotate the validators set, you must perform a network upgrade using a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.p,{children:"When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block."}),"\n",(0,a.jsxs)(n.p,{children:["After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"\nglobal-state-update-gen validators \\\n --data-dir $DATA_DIR/global_state \\\n --state-hash $STATE_ROOT_HASH \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE \\\n \u2013-validator $PUBLIC_KEY_HEX,$STAKE\n\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Each use of the ",(0,a.jsx)(n.code,{children:"--validator"})," parameter designates a validator for the next era. Only validators added using this parameter will be included in the new era, hence removing a validator only requires you to not add them with this parameter."]}),"\n",(0,a.jsxs)(n.p,{children:["After designating the next era's validators, you must set the chainspec activation point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to ",(0,a.jsx)(n.code,{children:"X"}),", where ",(0,a.jsx)(n.code,{children:"X"})," is equal to the new era after the switch block from above. Finally, set ",(0,a.jsx)(n.code,{children:"hard_reset = true"}),". This makes the network revert to the end of the previous era when restarted with the upgrade."]}),"\n",(0,a.jsxs)(n.p,{children:["For example, to rotate the validators in era 10, one would need to wait for the end of era 9. After acquiring the state root hash from the final block of era 9, you would stop the network, run ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),", set the activaction point and ",(0,a.jsx)(n.code,{children:"last_emergency_restart"})," to 10 and ",(0,a.jsx)(n.code,{children:"hard_reset"})," to ",(0,a.jsx)(n.code,{children:"true"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can now stage the upgrade by copying the chainspecs, configs and binaries where they should be while the network is still down. Once these are in place, you can restart the network with rotated validators."}),"\n",(0,a.jsx)(n.admonition,{type:"note",children:(0,a.jsxs)(n.p,{children:["Please make sure you are running this tool as the same user that owns ",(0,a.jsx)(n.code,{children:"$DATA_DIR"}),". Otherwise, you may receive a permission denied error."]})}),"\n",(0,a.jsxs)(n.p,{children:["You can find more details on enabling new validators in the ",(0,a.jsx)(n.a,{href:"/operators/setup/joining",children:"joining a running network"})," guide. The guide explains how to join the network and provide additional security to the system."]}),"\n",(0,a.jsx)(n.h2,{id:"step-7-testing-the-private-network",children:"Step 7. Testing the Private Network"}),"\n",(0,a.jsx)(n.p,{children:"We will describe the testing flow using an example customer and the configuration below. These options are relative to this example customer."}),"\n",(0,a.jsx)(n.h3,{id:"sample-configuration-files",children:"Sample configuration files"}),"\n",(0,a.jsx)(n.p,{children:"Here are sample configurations that can be adapted for testing:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:["A ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/chainspec.toml.in",children:"chainspec template"})," that is specific to the customer's private chain."]}),"\n",(0,a.jsxs)(n.li,{children:["An ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/0b4eead8ea1adffaea98260fe2e69dfc8b71c092/resources/private/accounts.toml.in",children:"accounts template"})," with one administrator in the ",(0,a.jsx)(n.code,{children:"administrators"})," settings."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"specifying-ip-addresses",children:"Specifying IP addresses"}),"\n",(0,a.jsx)(n.p,{children:"Here is an example set of IP addresses in use:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"http://18.224.190.213:7777\nhttp://18.188.11.97:7777\nhttp://18.188.206.170:7777\nhttp://18.116.201.114:7777\n"})}),"\n",(0,a.jsx)(n.h3,{id:"setting-up-the-node",children:"Setting up the node"}),"\n",(0,a.jsx)(n.p,{children:"Set up the node address, chain name, and the administrator's secret key."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'export NODE_ADDR=http://18.224.190.213:7777\nexport CHAIN_NAME="private-test"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This testing example will also use an ",(0,a.jsx)(n.code,{children:"alice/secret_key.pem"})," file, a secret key generated through the ",(0,a.jsx)(n.a,{href:"/concepts/accounts-and-keys#creating-accounts-and-keys",children:"keys generation process"}),". Alice is a regular user in this testing example."]}),"\n",(0,a.jsx)(n.h3,{id:"network-access-control",children:"Network access control"}),"\n",(0,a.jsx)(n.p,{children:"With a default configuration each node generates a self-signed certificate to encrypt peer-to-peer communication. This means any person can join an existing network, and sync with the network, which in private chains may not be allowed."}),"\n",(0,a.jsx)(n.p,{children:"To restrict access for new nodes joining an existing private chain network, the node software supports loading signed client certificates by a certificate authority (CA)."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "local_node_cert.pem"\nsecret_key = "local_node.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"tls_certificate"})," is the certificate signed by a ",(0,a.jsx)(n.code,{children:"ca_cert.pem"}),"."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"secret_key"})," refers to a secret key that should be unique to a specific node in the network. All peer-to-peer communication coming from this node will be signed by this key."]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"ca_certificate"})," is the network CA that should be the same on each of the nodes."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"To set up CA and sign client certificates for a network here are the steps to follow using an openssl command line:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'# Recommended EC curve algorithm to use\nexport CURVE="secp521r1"\n\n# Generate secret key for CA and save it to ca_key.pem\nopenssl ecparam -out ca_key.pem -name $CURVE -genkey\n# Create ca_cert.pem signed by ca_key.pem\nopenssl req -new -x509 -days 3650 -extensions v3_ca -key ca_key.pem -out ca_cert.pem\n\n# Generate secret key for a node and a certificate signed by the CA\nopenssl ecparam -out node_1.pem -name $CURVE -genkey\nopenssl req -new -key node_1.pem -out node_1.csr -sha256\nopenssl x509 -req -days 3650 -CA ca_cert.pem -CAkey ca_key.pem -CAcreateserial -in node_1.csr -out node_1_cert.pem\n'})}),"\n",(0,a.jsx)(n.p,{children:"And then configure the node with the following settings:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[network.identity]\ntls_certificate = "node_1_cert.pem"\nsecret_key = "node_1.pem"\nca_certificate = "ca_cert.pem"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Every node in the private chain network has to be configured with the same CA certificate, and each ",(0,a.jsx)(n.code,{children:"tls_certificate"})," and ",(0,a.jsx)(n.code,{children:"secret_key"})," pair has to be signed by it. Any node trying to join with a certificate signed by an incorrect CA ends up with the following log message:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{children:"2022-09-01T12:08:53.031417Z DEBUG init:incoming{; peer_addr=127.0.0.1:50998}: [casper_node::components::small_network small_network.rs:501] incoming connection failed early; err=TLS validation error of peer certificate: the certificate is not signed by provided certificate authority\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Keep in mind that for security reasons ",(0,a.jsx)(n.code,{children:"ca_key.pem"})," should be stored securely and never present on each of participating machines."]}),"\n",(0,a.jsx)(n.h3,{id:"funding-alices-account",children:"Funding Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command transfers tokens to Alice's main purse."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n transfer \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<admin/public_key_hex) \\\n --target-account=$(<alice/public_key_hex) \\\n --amount=100000000000 \\\n --payment-amount=3000000000 \\\n --transfer-id=123\n"})}),"\n",(0,a.jsx)(n.p,{children:"To check the account information, use this command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-account-info -n $NODE_ADDR\n --public-key alice/public_key.pem\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-a-bid-as-alice",children:"Adding a bid as Alice"}),"\n",(0,a.jsxs)(n.p,{children:["The following command attempts to add an auction bid on the network. It should return ",(0,a.jsx)(n.code,{children:"ApiError::AuctionError(AuctionBidsDisabled) [64559]"}),"."]}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["All payment amounts in these examples must be adjusted based on the network ",(0,a.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:'casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key alice/secret_key.pem \\\n --session-path add_bid.wasm \\\n --payment-amount 5000000000 \\\n --session-arg "public_key:public_key=\'$(<alice/public_key_hex)\'" \\\n --session-arg "amount:u512=\'10000\'" \\\n --session-arg "delegation_rate:u8=\'5\'"\n\n# Error: ApiError::AuctionError(AuctionBidsDisabled) [64559]"\n'})}),"\n",(0,a.jsx)(n.p,{children:"We should get a similar error for the delegate entry point."}),"\n",(0,a.jsx)(n.h3,{id:"disabling-alices-account",children:"Disabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command disables Alice's account. In this case, executing deploys with Alice's account will not be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='255'\" \\\n --session-arg \"deploy_threshold:u8='255'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-alices-account",children:"Enabling Alice's account"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables Alice's account. In this case, executing deploys with Alice's account will be successful."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=alice/public_key_hex\n --session-path set_action_thresholds.wasm \\\n --payment-amount=2500000000 \\\n --session-arg \"key_management_threshold:u8='0'\" \\\n --session-arg \"deploy_threshold:u8='1'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"enabling-a-contract",children:"Enabling a contract"}),"\n",(0,a.jsx)(n.p,{children:"The following command enables a contract using its hash."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path enable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.h3,{id:"disabling-a-contract",children:"Disabling a contract"}),"\n",(0,a.jsxs)(n.p,{children:["The following command disables a contract using its hash. Executing this contract using ",(0,a.jsx)(n.code,{children:"CONTRACT_HASH"})," again should fail."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client \\\n put-deploy \\\n -n $NODE_ADDR \\\n --chain-name $CHAIN_NAME \\\n --secret-key admin/secret_key.pem \\\n --session-account=$(<alice/public_key_hex) \\\n --session-path disable_contract.wasm \\\n --payment-amount 3000000000 \\\n --session-arg \"contract_package_hash:account_hash='account-hash-$CONTRACT_PACKAGE_HASH'\" \\\n --session-arg \"contract_hash:account_hash='account-hash-$CONTRACT_HASH'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:"Alice needs a container access key for the contract package in her named keys."}),"\n",(0,a.jsx)(n.h3,{id:"verifying-seigniorage-allocations",children:"Verifying seigniorage allocations"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"https://www.investopedia.com/terms/s/seigniorage.asp",children:"Seigniorage"})," allocations should be zero at each switch block. This is the related configuration:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:"[core]\ncompute_rewards = false\n"})}),"\n",(0,a.jsx)(n.p,{children:"Validator stakes should not increase on each switch block. Run this command to verify this:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"casper-client get-era-info -n $NODE_ADDR -b 153\n"})}),"\n",(0,a.jsx)(n.p,{children:"The total supply shouldn't increase, and the validator's stakes should remain the same."}),"\n",(0,a.jsx)(n.h3,{id:"operating-guide",children:"Operating guide"}),"\n",(0,a.jsxs)(n.p,{children:["Some configuration options such as ",(0,a.jsx)(n.code,{children:"allow_auction_bids"})," require a private chain operator to perform specific tasks manually through a network upgrade with chainspec and contents of ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file generated by a provided tool ",(0,a.jsx)(n.code,{children:"global-state-update-gen"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"You can find this tool by either downloading a package or by installing it manually from the sources:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ cargo install --git https://github.com/casper-network/casper-node/ --tag private-1.4.6 global-state-update-gen\n$ global-state-update-gen --help\nGlobal State Update Generator 0.2.0\nGenerates a global state update file based on the supplied parameters\n\nUSAGE:\n global-state-update-gen [SUBCOMMAND]\n\nFLAGS:\n -h, --help Prints help information\n -V, --version Prints version information\n\nSUBCOMMANDS:\n balances Generates an update changing account balances\n generate-admins Generates entries to create new admin accounts on a private chain\n help Prints this message or the help of the given subcommand(s)\n system-contract-registry Generates an update creating the system contract registry\n validators Generates an update changing the validators set\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The standard output of running commands listed above is the content of a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file, which contains a list of direct global state modifications."]}),"\n",(0,a.jsxs)(n.p,{children:["Example output of running a ",(0,a.jsx)(n.code,{children:"generate-admins"})," subcommand:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[[entries]]\nkey = "balance-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13"\nvalue = "AAIAAAABCgg="\n\n[[entries]]\nkey = "uref-97bbcc2425b3eda5149a893c6180b62f1472d5143bb1450d01c8e1e96be09f13-007"\nvalue = "AAAAAAAJ"\n\n[[entries]]\nkey = "account-hash-ac2f4caa3e3ce1cd1dfb3d089854020b18a50cac49977d0a4c873c4d3d5a2409"\nvalue = "AawvTKo+POHNHfs9CJhUAgsYpQysSZd9CkyHPE09WiQJAAAAAJe7zCQls+2lFJqJPGGAti8UctUUO7FFDQHI4elr4J8TBwEAAACsL0yqPjzhzR37PQiYVAILGKUMrEmXfQpMhzxNPVokCQEBAQ=="\n\n# total supply increases from 200000000000000000 to 200000000000000010\n[[entries]]\nkey = "uref-f8475fd4125484be39a0793530f09a29d220ffda8e48387b3d2194ddfc22894e-007"\nvalue = "AAkAAAAICgAUu/CKxgII"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["Currently, this tool outputs contents into standard output. You should redirect standard output to a file named ",(0,a.jsx)(n.code,{children:"global_state.toml"})," and place this file in the same directory as ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," before performing a network upgrade."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"$ global-state-update-gen generate-admins --data-dir $DATA_DIR --state-hash $STATE_HASH --admin NEW_PUBLIC_KEY,BALANCE >> global_state.toml\n"})}),"\n",(0,a.jsxs)(n.p,{children:["By using ",(0,a.jsx)(n.code,{children:">>"})," shell redirection you will always append contents to existing file without overwriting it. This is helpful when you need to chain multiple operations in a single upgrade."]}),"\n",(0,a.jsx)(n.p,{children:"Common options:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--data-dir"})," path to a global state directory where ",(0,a.jsx)(n.code,{children:"data.lmdb"})," can be found"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"--state-hash"})," is the state root hash at the latest block. You should use the client to obtain the most recent state root hash to generate the ",(0,a.jsx)(n.code,{children:"global_state.toml"}),"."]}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"rotating-validators",children:"Rotating validators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command rotates the validator set. Perform a network upgrade with a ",(0,a.jsx)(n.code,{children:"global_state.toml"})," with the new entries generated by the ",(0,a.jsx)(n.code,{children:"global-state-update-gen"})," command."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen validators \\\n --data-dir $DATA_DIR \\\n --state-hash $STATE_ROOT_HASH \\\n --validator NEW_PUBLIC_KEY,NEW_STAKE \\\n --validator NEW_PUBLIC_KEY2,NEW_STAKE2\n"})}),"\n",(0,a.jsx)(n.h3,{id:"adding-new-administrators",children:"Adding new administrators"}),"\n",(0,a.jsxs)(n.p,{children:["The following command produces the administrator content in the ",(0,a.jsx)(n.code,{children:"global_state.toml"})," file."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-sh",children:"global-state-update-gen generate-admins --admin NEW_PUBLIC_KEY,NEW_BALANCE --data-dir $DATA_DIR --state-hash $STATE_ROOT_HASH\n"})}),"\n",(0,a.jsx)(n.p,{children:"Remember that new administrators can be created, and the validator set can also be rotated in a single update."}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"chainspec.toml"})," file should contain the following entries that include new administrators as well as existing ones for an upgrade:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-toml",children:'[core]\nadministrators = ["NEW_PUBLIC_KEY"]\n'})}),"\n",(0,a.jsx)(n.p,{children:"After this step, the private network would be ready for use."}),"\n",(0,a.jsx)(n.h2,{id:"setting-up-a-block-explorer",children:"Setting up a Block Explorer"}),"\n",(0,a.jsxs)(n.p,{children:["Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer ",(0,a.jsx)(n.a,{href:"https://github.com/casper-network/casper-blockexplorer-frontend",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5f06d44.f6b77b6b.js b/assets/js/c5f06d44.f6b77b6b.js new file mode 100644 index 000000000..0c592f174 --- /dev/null +++ b/assets/js/c5f06d44.f6b77b6b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[76971],{60793:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},r="Fungible Tokens (CEP-18) Implementation and Usage",i={id:"resources/beginner/cep18",title:"Fungible Tokens",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-2.0.0/resources/beginner/cep18.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/cep18",permalink:"/2.0.0/resources/tutorials/beginner/cep18",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},sidebar:"tutorials",previous:{title:"Contract Upgrades",permalink:"/2.0.0/resources/tutorials/beginner/upgrade-contract"},next:{title:"AWS Casper Nodes",permalink:"/2.0.0/resources/tutorials/beginner/aws-node"}},l={},c=[{value:"Outline of the Tutorial",id:"outline",level:2},{value:"ERC-20 Standard",id:"erc20-standard",level:2},{value:"Interaction of ERC-20 Based Tokens with the Uniswap Standard",id:"erc20-uniswap",level:2},{value:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges",id:"erc20-implications",level:2},{value:"The Casper CEP-18 Standard",id:"cep18-standard",level:2},{value:"Creating a CEP-18 Token on the Testnet",id:"cep18-testnet",level:2},{value:"Clone and Compile the CEP-18 Contract",id:"cep18-contract-clone",level:3},{value:"Install the CEP-18 Contract",id:"cep18-contract-install",level:3},{value:"Query the Entry Points in the CEP-18 contract",id:"cep18-contract-clone",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"fungible-tokens-cep-18-implementation-and-usage",children:"Fungible Tokens (CEP-18) Implementation and Usage"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"outline",children:"Outline of the Tutorial"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-standard",children:"ERC-20 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain."}),"\n",(0,s.jsx)(n.p,{children:"It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana.\nSome key points of the ERC-20 standard include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Optional metadata functions like ",(0,s.jsx)(n.code,{children:"name()"}),", ",(0,s.jsx)(n.code,{children:"symbol()"}),", and ",(0,s.jsx)(n.code,{children:"decimals()"}),", which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets.\nBy adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-uniswap",children:"Interaction of ERC-20 Based Tokens with the Uniswap Standard"}),"\n",(0,s.jsx)(n.p,{children:"By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2."}),"\n",(0,s.jsx)(n.p,{children:"Uniswap V2 uses ERC-20 tokens in the following scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Listing Tokens \u2013 Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard."}),"\n",(0,s.jsx)(n.li,{children:"Liquidity Pools \u2013 any two pairs of ERC-20 tokens can be used to create a liquidity pool."}),"\n",(0,s.jsxs)(n.li,{children:["Uniswap V2 uses the ERC-20 standard ",(0,s.jsx)(n.code,{children:"transfer()"})," function to allow an exchange of tokens within the liquidity pools."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erc20-implications",children:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges"}),"\n",(0,s.jsx)(n.p,{children:"There exist at least two different implementations of the ERC-20 Standard on Casper networks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/Rengo-Labs/casper-erc20",children:"Rengo-Labs implementation"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market implementation"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks."}),"\n",(0,s.jsx)(n.p,{children:"The following considerations should be applied when trying to create an ERC-20 Token:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Interoperability \u2013 Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Project Security Audits \u2013 Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ecosystem \u2013 The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities."}),"\n",(0,s.jsx)(n.h2,{id:"cep18-standard",children:"The Casper CEP-18 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"allowance"})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approve"})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance_of"})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"decimals"})," - Returns the decimal places applied to the balance of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," - Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"symbol"})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"total_supply"})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer"})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from"})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more detail on these methods, there is a reference implementation available on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"cep18-testnet",children:"Creating a CEP-18 Token on the Testnet"}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Clone and Compile the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state."}),"\n",(0,s.jsxs)(n.p,{children:["If you are unsure how to interact with Casper Contracts please refer to the following tutorial: ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We will clone the token repository and prepare the token contract for sending in a Deploy."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tgit clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" cd cep18\n make prepare\n make build-contract\n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"build-contract"})," finishes with an error ",(0,s.jsx)(n.code,{children:"wasm-strip: command not found"}),", make sure you install an additional package on MacOS:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" brew install wabt\n"})})]}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tmake test\n"})}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-install",children:"Install the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet."}),"\n",(0,s.jsx)(n.p,{children:"Use the following template to install the contract on the Testnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777 \n\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should obtain a response similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"An exemplary deploy to the Casper Testnet is as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n'})}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Always be mindful of the ",(0,s.jsx)(n.code,{children:"--secret-key"})," and ",(0,s.jsx)(n.code,{children:"--session-path"})," arguments.\nPath provided to the arguments should always be with regard to the current folder, where the command is executed."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"keys"})," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored."]})]}),"\n",(0,s.jsxs)(n.p,{children:["The response from the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command should look like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," the state of the deploy can be checked:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the execution results we can see, that the deploy was successful:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n... \n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,s.jsx)(n.code,{children:"Out of gas error"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Query the Entry Points in the CEP-18 contract"}),"\n",(0,s.jsx)(n.p,{children:"Get the state root hash from the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n"})}),"\n",(0,s.jsx)(n.p,{children:"Your response should look similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The above command will query the contract for the name. The template for the query is ",(0,s.jsx)(n.code,{children:"contract_name/named_key"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You will obtain the following response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Try to query the contract for other Named Keys and check how the contract behaves."}),"\n",(0,s.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,s.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Explained the ERC20 standard and what the implications are for not using the standard implementations."}),"\n",(0,s.jsx)(n.li,{children:"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."}),"\n",(0,s.jsx)(n.li,{children:"Installed the contract on the Testnet"}),"\n",(0,s.jsxs)(n.li,{children:["Called an entry point on the contract to get the value of the Named Key ",(0,s.jsx)(n.code,{children:"name"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c691959f.300edfdd.js b/assets/js/c691959f.300edfdd.js new file mode 100644 index 000000000..455e6ce99 --- /dev/null +++ b/assets/js/c691959f.300edfdd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86233],{37819:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var o=t(74848),s=t(28453);const a={},i="Casper-Client Commands",r={id:"resources/beginner/counter/commands",title:"Casper-Client Commands",description:"Faucet Account Information",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/commands.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/commands",permalink:"/1.5.X/resources/beginner/counter/commands",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/1.5.X/resources/beginner/counter/overview"},next:{title:"Tutorial Walkthrough",permalink:"/1.5.X/resources/beginner/counter/walkthrough"}},c={},l=[{value:"Faucet Account Information",id:"faucet-account-information",level:2},{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,o.jsx)(n.h2,{id:"faucet-account-information",children:"Faucet Account Information"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"nctl-view-faucet-account\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's ",(0,o.jsx)(n.em,{children:"secret key"})," location and the ",(0,o.jsx)(n.em,{children:"account hash"}),", which are used to sign deploys and query the network state, respectively."]}),"\n",(0,o.jsx)(n.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The first command to cover is the ",(0,o.jsx)(n.em,{children:"get-state-root-hash"})," command from the ",(0,o.jsx)(n.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"After sending 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."})}),"\n",(0,o.jsx)(n.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,o.jsx)(n.em,{children:"state-root-hash"})," described above."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"node-address"})," is the location of the RPC endpoint, which is typically represented in the form ",(0,o.jsx)(n.code,{children:"http://IP:PORT"}),". In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is ",(0,o.jsx)(n.code,{children:"http://localhost:11101"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,o.jsxs)(n.li,{children:["The optional query path argument (",(0,o.jsx)(n.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,o.jsx)(n.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,o.jsxs)(n.li,{children:["This contract is then installed on the network specified by the ",(0,o.jsx)(n.em,{children:"chain-name"}),'. By default, NCTL names the chain "casper-net-1" but this is configurable.']}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This second usage of ",(0,o.jsx)(n.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,o.jsxs)(n.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,o.jsx)(n.a,{href:"/1.5.X/resources/beginner/counter/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,o.jsx)(n.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"get-deploy"})," command is complementary to the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,o.jsx)(n.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c691959f.8bec913d.js b/assets/js/c691959f.8bec913d.js deleted file mode 100644 index 557ea2806..000000000 --- a/assets/js/c691959f.8bec913d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6233],{37819:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var o=t(74848),s=t(28453);const a={},i="Casper-Client Commands",r={id:"resources/beginner/counter/commands",title:"Casper-Client Commands",description:"Faucet Account Information",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/commands.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/commands",permalink:"/resources/beginner/counter/commands",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/resources/beginner/counter/overview"},next:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter/walkthrough"}},c={},l=[{value:"Faucet Account Information",id:"faucet-account-information",level:2},{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,o.jsx)(n.h2,{id:"faucet-account-information",children:"Faucet Account Information"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"nctl-view-faucet-account\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's ",(0,o.jsx)(n.em,{children:"secret key"})," location and the ",(0,o.jsx)(n.em,{children:"account hash"}),", which are used to sign deploys and query the network state, respectively."]}),"\n",(0,o.jsx)(n.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The first command to cover is the ",(0,o.jsx)(n.em,{children:"get-state-root-hash"})," command from the ",(0,o.jsx)(n.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,o.jsx)(n.admonition,{type:"note",children:(0,o.jsx)(n.p,{children:"After sending 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."})}),"\n",(0,o.jsx)(n.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,o.jsx)(n.em,{children:"state-root-hash"})," described above."]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"node-address"})," is the location of the RPC endpoint, which is typically represented in the form ",(0,o.jsx)(n.code,{children:"http://IP:PORT"}),". In this particular tutorial, for a default-configured NCTL network running locally, the address you can use is ",(0,o.jsx)(n.code,{children:"http://localhost:11101"}),"."]}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,o.jsxs)(n.li,{children:["The optional query path argument (",(0,o.jsx)(n.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,o.jsx)(n.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,o.jsx)(n.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,o.jsxs)(n.li,{children:["This contract is then installed on the network specified by the ",(0,o.jsx)(n.em,{children:"chain-name"}),'. By default, NCTL names the chain "casper-net-1" but this is configurable.']}),"\n",(0,o.jsxs)(n.li,{children:["The ",(0,o.jsx)(n.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,o.jsx)(n.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-net-1 \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,o.jsxs)(n.p,{children:["This second usage of ",(0,o.jsx)(n.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,o.jsxs)(n.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,o.jsx)(n.a,{href:"/resources/beginner/counter/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,o.jsx)(n.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.em,{children:"get-deploy"})," command is complementary to the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,o.jsx)(n.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,o.jsx)(n.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>r});var o=t(96540);const s={},a=o.createContext(s);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c74094f8.7db305e4.js b/assets/js/c74094f8.7db305e4.js deleted file mode 100644 index 05637d2ca..000000000 --- a/assets/js/c74094f8.7db305e4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2512],{89738:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>a});var s=t(74848),i=t(28453);const r={title:"Design Overview",slug:"/design"},c=void 0,o={id:"concepts/design/index",title:"Design Overview",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/concepts/design/index.md",sourceDirName:"concepts/design",slug:"/design",permalink:"/design",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Design Overview",slug:"/design"},sidebar:"concepts",previous:{title:"Serialization Standard",permalink:"/concepts/serialization-standard"},next:{title:"Network Design",permalink:"/concepts/design/casper-design"}},d={},a=[];function l(e){const n={a:"a",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/casper-design",children:"Network Design"})}),(0,s.jsx)(n.td,{children:"Overview of execution semantics, account permissions, URefs, block structure, tokens, and more"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network Communication"})}),(0,s.jsx)(n.td,{children:"Peer-to-peer communication for Casper nodes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway Consensus"})}),(0,s.jsx)(n.td,{children:"Brief overview of the Highway Consensus mechanism used in Casper networks"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to Global State"})}),(0,s.jsx)(n.td,{children:"Storing and reading data from the blockchain"})]})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c74094f8.c3dcc644.js b/assets/js/c74094f8.c3dcc644.js new file mode 100644 index 000000000..2b5fde1c2 --- /dev/null +++ b/assets/js/c74094f8.c3dcc644.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52512],{89738:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>a});var s=t(74848),i=t(28453);const r={title:"Design Overview",slug:"/design"},c=void 0,o={id:"concepts/design/index",title:"Design Overview",description:"| Topic | Description |",source:"@site/versioned_docs/version-1.5.X/concepts/design/index.md",sourceDirName:"concepts/design",slug:"/design",permalink:"/1.5.X/design",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Design Overview",slug:"/design"},sidebar:"concepts",previous:{title:"Serialization Standard",permalink:"/1.5.X/concepts/serialization-standard"},next:{title:"Network Design",permalink:"/1.5.X/concepts/design/casper-design"}},d={},a=[];function l(e){const n={a:"a",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design",children:"Network Design"})}),(0,s.jsx)(n.td,{children:"Overview of execution semantics, account permissions, URefs, block structure, tokens, and more"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/p2p",children:"Network Communication"})}),(0,s.jsx)(n.td,{children:"Peer-to-peer communication for Casper nodes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/highway",children:"Highway Consensus"})}),(0,s.jsx)(n.td,{children:"Brief overview of the Highway Consensus mechanism used in Casper networks"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to Global State"})}),(0,s.jsx)(n.td,{children:"Storing and reading data from the blockchain"})]})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>o});var s=t(96540);const i={},r=s.createContext(i);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c7d46fe1.340d8422.js b/assets/js/c7d46fe1.340d8422.js deleted file mode 100644 index b5ed6f960..000000000 --- a/assets/js/c7d46fe1.340d8422.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7935],{94085:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var t=r(74848),s=r(28453);const i={title:"Hardware"},o="Recommended Hardware Specifications",a={id:"operators/setup/hardware",title:"Hardware",description:"System Requirements",source:"@site/docs/operators/setup/hardware.md",sourceDirName:"operators/setup",slug:"/operators/setup/hardware",permalink:"/next/operators/setup/hardware",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Hardware"},sidebar:"operators",previous:{title:"Setting up a Node",permalink:"/next/operators/setup/"},next:{title:"Configuration",permalink:"/next/operators/setup/basic-node-configuration"}},c={},d=[{value:"System Requirements",id:"system-requirements",level:2},{value:"CPU Requirements",id:"cpu-requirements",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"recommended-hardware-specifications",children:"Recommended Hardware Specifications"})}),"\n",(0,t.jsx)(n.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,t.jsxs)(n.p,{children:["The following hardware specifications are recommended for the Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"4 Cores"}),"\n",(0,t.jsx)(n.li,{children:"32 GB Ram"}),"\n",(0,t.jsx)(n.li,{children:"2 TB SSD or network SSD backed disk"}),"\n",(0,t.jsx)(n.li,{children:"Linux machine running Ubuntu 20.04"}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Notes",type:"note",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this."}),"\n"]}),"\n"]})}),"\n",(0,t.jsx)(n.h3,{id:"cpu-requirements",children:"CPU Requirements"}),"\n",(0,t.jsx)(n.p,{children:"Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions."}),"\n",(0,t.jsx)(n.p,{children:"To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question."})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>a});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c7d46fe1.c6ccb6de.js b/assets/js/c7d46fe1.c6ccb6de.js new file mode 100644 index 000000000..f8fe973ca --- /dev/null +++ b/assets/js/c7d46fe1.c6ccb6de.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67935],{94085:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>i,metadata:()=>a,toc:()=>d});var t=r(74848),s=r(28453);const i={title:"Hardware"},o="Recommended Hardware Specifications",a={id:"operators/setup/hardware",title:"Hardware",description:"System Requirements",source:"@site/docs/operators/setup/hardware.md",sourceDirName:"operators/setup",slug:"/operators/setup/hardware",permalink:"/operators/setup/hardware",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Hardware"},sidebar:"operators",previous:{title:"Setting up a Node",permalink:"/operators/setup/"},next:{title:"Configuration",permalink:"/operators/setup/basic-node-configuration"}},c={},d=[{value:"System Requirements",id:"system-requirements",level:2},{value:"CPU Requirements",id:"cpu-requirements",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"recommended-hardware-specifications",children:"Recommended Hardware Specifications"})}),"\n",(0,t.jsx)(n.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,t.jsxs)(n.p,{children:["The following hardware specifications are recommended for the Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"4 Cores"}),"\n",(0,t.jsx)(n.li,{children:"32 GB Ram"}),"\n",(0,t.jsx)(n.li,{children:"2 TB SSD or network SSD backed disk"}),"\n",(0,t.jsx)(n.li,{children:"Linux machine running Ubuntu 20.04"}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Notes",type:"note",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this."}),"\n"]}),"\n"]})}),"\n",(0,t.jsx)(n.h3,{id:"cpu-requirements",children:"CPU Requirements"}),"\n",(0,t.jsx)(n.p,{children:"Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions."}),"\n",(0,t.jsx)(n.p,{children:"To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question."})})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>a});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8e4da00.1ce531b1.js b/assets/js/c8e4da00.1ce531b1.js deleted file mode 100644 index 650658864..000000000 --- a/assets/js/c8e4da00.1ce531b1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5808],{43185:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Overview",slug:"/developers"},o="Developers Overview",d={id:"developers/index",title:"Overview",description:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.",source:"@site/versioned_docs/version-1.5.X/developers/index.md",sourceDirName:"developers",slug:"/developers",permalink:"/developers",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/developers"},sidebar:"developers",next:{title:"Development Prerequisites",permalink:"/developers/prerequisites"}},a={},l=[];function c(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"developers-overview",children:"Developers Overview"})}),"\n",(0,t.jsx)(n.p,{children:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"Development Prerequisites"})}),(0,t.jsx)(n.td,{children:"Setup needed for various workflows"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/essential-crates",children:"Essential Casper Crates"})}),(0,t.jsx)(n.td,{children:"Available Casper crates and the corresponding documentation"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/writing-contracts",children:"Writing On-Chain Code"})}),(0,t.jsx)(n.td,{children:"Writing contracts in Rust and Wasm for a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/",children:"Casper JSON-RPC API"})}),(0,t.jsx)(n.td,{children:"Endpoints for developers wishing to interact directly with a Casper node's JSON-RPC API"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/",children:"Building dApps"})}),(0,t.jsx)(n.td,{children:"Useful information for dApp developers"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/developers/cli/",children:"Interacting with the Blockchain Using CLI"})}),(0,t.jsx)(n.td,{children:"Using a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens."})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open-Source Software"})," may provide other helpful examples."]}),"\n",(0,t.jsx)(n.p,{children:"The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together."})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>d});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8e4da00.377067a0.js b/assets/js/c8e4da00.377067a0.js new file mode 100644 index 000000000..376aedabf --- /dev/null +++ b/assets/js/c8e4da00.377067a0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35808],{43185:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Overview",slug:"/developers"},o="Developers Overview",d={id:"developers/index",title:"Overview",description:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.",source:"@site/versioned_docs/version-1.5.X/developers/index.md",sourceDirName:"developers",slug:"/developers",permalink:"/1.5.X/developers",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/developers"},sidebar:"developers",next:{title:"Development Prerequisites",permalink:"/1.5.X/developers/prerequisites"}},a={},l=[];function c(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"developers-overview",children:"Developers Overview"})}),"\n",(0,t.jsx)(n.p,{children:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"Development Prerequisites"})}),(0,t.jsx)(n.td,{children:"Setup needed for various workflows"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/essential-crates",children:"Essential Casper Crates"})}),(0,t.jsx)(n.td,{children:"Available Casper crates and the corresponding documentation"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/writing-contracts",children:"Writing On-Chain Code"})}),(0,t.jsx)(n.td,{children:"Writing contracts in Rust and Wasm for a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/",children:"Casper JSON-RPC API"})}),(0,t.jsx)(n.td,{children:"Endpoints for developers wishing to interact directly with a Casper node's JSON-RPC API"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/",children:"Building dApps"})}),(0,t.jsx)(n.td,{children:"Useful information for dApp developers"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/",children:"Interacting with the Blockchain Using CLI"})}),(0,t.jsx)(n.td,{children:"Using a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens."})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open-Source Software"})," may provide other helpful examples."]}),"\n",(0,t.jsx)(n.p,{children:"The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together."})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>d});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c8eb2c38.d5c12a00.js b/assets/js/c8eb2c38.d5c12a00.js new file mode 100644 index 000000000..02c09b319 --- /dev/null +++ b/assets/js/c8eb2c38.d5c12a00.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62287],{42567:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>l,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var r=t(74848),s=t(28453);const o={},d="Setting up a Node",i={id:"operators/setup/index",title:"Setting up a Node",description:"The prerequisite for becoming a validator is to set up a node and join a network as described here.",source:"@site/versioned_docs/version-2.0.0/operators/setup/index.md",sourceDirName:"operators/setup",slug:"/operators/setup/",permalink:"/2.0.0/operators/setup/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"operators",previous:{title:"Overview",permalink:"/2.0.0/operators"},next:{title:"Hardware",permalink:"/2.0.0/operators/setup/hardware"}},a={},c=[];function h(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-node",children:"Setting up a Node"})}),"\n",(0,r.jsx)(n.p,{children:"The prerequisite for becoming a validator is to set up a node and join a network as described here."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/hardware",children:"Recommended Hardware Specifications"})}),(0,r.jsx)(n.td,{children:"System requirements for the Casper Mainnet and Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration",children:"Basic Node Configuration"})}),(0,r.jsx)(n.td,{children:"Processes and files involved in setting up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/node-endpoints",children:"Node Endpoints"})}),(0,r.jsx)(n.td,{children:"Ports for communicating with other nodes and dApps"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node",children:"Installing a Node"})}),(0,r.jsx)(n.td,{children:"Step-by-step instructions to install a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/open-files",children:"Setting the Open Files Limit"})}),(0,r.jsx)(n.td,{children:"Required setting for the Casper node to run correctly"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/upgrade",children:"Upgrading the Node"})}),(0,r.jsx)(n.td,{children:"Before joining the network, the node needs to be upgraded"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/joining",children:"Joining a Running Network"})}),(0,r.jsx)(n.td,{children:"Steps to join an existing Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/non-root-user",children:"Setting up a Non-Root User"})}),(0,r.jsx)(n.td,{children:"Logging into the node remotely using a key"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/node-events",children:"Node Events"})}),(0,r.jsx)(n.td,{children:"Information on a node's events stream"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/2.0.0/operators/setup/casper-sidecar",children:"Sidecar Setup"})}),(0,r.jsx)(n.td,{children:"An application allowing subscribers to monitor a node's event stream, query stored events, and query a node\u2019s JSON-RPC API"})]})]})]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>i});var r=t(96540);const s={},o=r.createContext(s);function d(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c95e6d8d.9669f9e6.js b/assets/js/c95e6d8d.9669f9e6.js new file mode 100644 index 000000000..43956c5ff --- /dev/null +++ b/assets/js/c95e6d8d.9669f9e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46879],{86400:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Build on Casper",slug:"build-on-casper/introduction"},o="Building on Casper",a={id:"resources/build-on-casper",title:"Build on Casper",description:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.",source:"@site/versioned_docs/version-2.0.0/resources/build-on-casper.md",sourceDirName:"resources",slug:"/resources/build-on-casper/introduction",permalink:"/2.0.0/resources/build-on-casper/introduction",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Build on Casper",slug:"build-on-casper/introduction"},sidebar:"resources",previous:{title:"Resources Overview",permalink:"/2.0.0/resources/"},next:{title:"Move to Casper",permalink:"/2.0.0/resources/moving-to-casper"}},l={},c=[{value:"Thriving Ecosystem",id:"thriving-ecosystem",level:2},{value:"Wallets",id:"wallets",level:3},{value:"Block Explorers",id:"block-explorers",level:3},{value:"Developer Tools",id:"developer-tools",level:3},{value:"Open Source Software",id:"open-source-software",level:3},{value:"Developer-Friendly Language",id:"developer-friendly-language",level:2},{value:"Powerful Accounts",id:"powerful-accounts",level:2},{value:"Contract Upgrades",id:"contract-upgrades",level:2},{value:"Development Tools",id:"development-tools",level:2},{value:"IDE Integration",id:"ide-integration",level:3},{value:"CI/CD",id:"ci-cd",level:3},{value:"Local Network Testing",id:"local-network-testing",level:3},{value:"Public Mainnet and Testnet",id:"public-mainnet-and-testnet",level:3},{value:"AWS",id:"aws",level:3},{value:"SDK Client Libraries",id:"sdk-client-libraries",level:2},{value:"No Gas Fees",id:"no-gas-fees",level:2}];function d(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"building-on-casper",children:"Building on Casper"})}),"\n",(0,t.jsx)(n.p,{children:"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#thriving-ecosystem",children:"Thriving Ecosystem"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#developer-friendly-language",children:"Developer-Friendly Language"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#powerful-accounts",children:"Powerful Accounts"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#contract-upgrades",children:"Contract Upgrades"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#development-tools",children:"Development Tools"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#no-gas-fees",children:"No Gas Fees"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"thriving-ecosystem",children:"Thriving Ecosystem"}),"\n",(0,t.jsx)(n.p,{children:"The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use."}),"\n",(0,t.jsx)(n.h3,{id:"wallets",children:"Wallets"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4416379141009-Casper-CSPR-?docs=true",children:"Ledger"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper.tor.us",children:"Tor.us"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io",children:"Casper Wallet"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://metamask.io/",children:"Metamask"})," with ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-manager",children:"Casper Snap"})]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"block-explorers",children:"Block Explorers"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cspr.live",children:"cspr.live"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casper-trench.vercel.app/",children:"Casper.info"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://div3.in/",children:"Div3.in"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"developer-tools",children:"Developer Tools"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://casperholders.io",children:"casperholders.io"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://nownodes.io/nodes/casper-cspr",children:"NOWNodes.io"})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"open-source-software",children:"Open Source Software"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open Source Software"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"developer-friendly-language",children:"Developer-Friendly Language"}),"\n",(0,t.jsx)(n.p,{children:"Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet."}),"\n",(0,t.jsxs)(n.p,{children:["Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an ",(0,t.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Open_standard",children:"open standard"})," for performance and portability of modern web applications."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available."})}),"\n",(0,t.jsx)(n.h2,{id:"powerful-accounts",children:"Powerful Accounts"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#accounts-permissions",children:"Casper Permissions Model"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"contract-upgrades",children:"Contract Upgrades"}),"\n",(0,t.jsx)(n.p,{children:"Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts."}),"\n",(0,t.jsx)(n.h2,{id:"development-tools",children:"Development Tools"}),"\n",(0,t.jsx)(n.h3,{id:"ide-integration",children:"IDE Integration"}),"\n",(0,t.jsx)(n.p,{children:"The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started."}),"\n",(0,t.jsx)(n.h3,{id:"ci-cd",children:"CI/CD"}),"\n",(0,t.jsx)(n.p,{children:"Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline."}),"\n",(0,t.jsx)(n.h3,{id:"local-network-testing",children:"Local Network Testing"}),"\n",(0,t.jsxs)(n.p,{children:["We also offer a tool to run a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"local Casper Network"})," Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface."]}),"\n",(0,t.jsx)(n.h3,{id:"public-mainnet-and-testnet",children:"Public Mainnet and Testnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live",children:"Mainnet"})," is a public, open-source, community-driven ecosystem. You can also explore the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live",children:"Testnet"})," to test drive your applications and estimate gas costs."]}),"\n",(0,t.jsx)(n.h3,{id:"aws",children:"AWS"}),"\n",(0,t.jsx)(n.p,{children:"We also offer several tools to run AWS instances of Casper nodes."}),"\n",(0,t.jsx)(n.h2,{id:"sdk-client-libraries",children:"SDK Client Libraries"}),"\n",(0,t.jsxs)(n.p,{children:["In addition to the default ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"command-line Rust client"}),", the Casper community is building ",(0,t.jsx)(n.a,{href:"/sdk",children:"other clients"})," in JavaScript, Java, Golang, Python, C#, and other languages."]}),"\n",(0,t.jsx)(n.h2,{id:"no-gas-fees",children:"No Gas Fees"}),"\n",(0,t.jsxs)(n.p,{children:["Casper seeks to eliminate volatility and improve developer and enterprise experiences by ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"eliminating transaction fees"})," on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9d52fc5.95b1b5e6.js b/assets/js/c9d52fc5.95b1b5e6.js new file mode 100644 index 000000000..de56fa78d --- /dev/null +++ b/assets/js/c9d52fc5.95b1b5e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[69210],{53385:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var a=s(74848),n=s(28453);const r={},o="S",c={id:"concepts/glossary/S",title:"S",description:"---",source:"@site/docs/concepts/glossary/S.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/S",permalink:"/concepts/glossary/S",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"R",permalink:"/concepts/glossary/R"},next:{title:"T",permalink:"/concepts/glossary/T"}},i={},l=[{value:"Safe",id:"safe",level:2},{value:"Secret key",id:"secret-key",level:2},{value:"Seigniorage",id:"seigniorage",level:2},{value:"Session code",id:"session-code",level:2},{value:"Slashing",id:"slashing",level:2},{value:"Smart contract",id:"smart-contract",level:2},{value:"Smart-contract platform",id:"smart-contract-platform",level:2},{value:"Staker",id:"staker",level:2},{value:"Staking",id:"staking",level:2},{value:"State root hash",id:"state-root-hash",level:2},{value:"Stateful",id:"stateful",level:2},{value:"Stateless",id:"stateless",level:2},{value:"Switch Block",id:"switch-block",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"s",children:"S"})}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,a.jsx)(t.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.h2,{id:"safe",children:"Safe"}),"\n",(0,a.jsxs)(t.p,{children:["When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see ",(0,a.jsx)(t.a,{href:"/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,a.jsx)(t.h2,{id:"secret-key",children:"Secret key"}),"\n",(0,a.jsx)(t.p,{children:"A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations)."}),"\n",(0,a.jsx)(t.h2,{id:"seigniorage",children:"Seigniorage"}),"\n",(0,a.jsx)(t.p,{children:"The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators."}),"\n",(0,a.jsx)(t.h2,{id:"session-code",children:"Session code"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"Session code"})," is Wasm executed in the context of an account entity through sending a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T#transaction",children:"transaction"}),". The ",(0,a.jsx)(t.em,{children:"session code"})," contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state."]}),"\n",(0,a.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,a.jsxs)(t.p,{children:["In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets ",(0,a.jsx)(t.em,{children:"slashed"}),", i.e., a part of it is removed."]}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract",children:"Smart contract"}),"\n",(0,a.jsx)(t.p,{children:"Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party."}),"\n",(0,a.jsxs)(t.p,{children:["On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),". The execution of a smart contract causes changes to the global state."]}),"\n",(0,a.jsx)(t.p,{children:"A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values."}),"\n",(0,a.jsx)(t.h2,{id:"smart-contract-platform",children:"Smart-contract platform"}),"\n",(0,a.jsx)(t.p,{children:"A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts."}),"\n",(0,a.jsx)(t.h2,{id:"staker",children:"Staker"}),"\n",(0,a.jsxs)(t.p,{children:["A staker is either a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/V#validator",children:"validator"})," or a ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D#delegator",children:"delegator"}),". Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their ",(0,a.jsx)(t.a,{href:"/concepts/glossary/T#token",children:"tokens"})," by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is ",(0,a.jsx)(t.a,{href:"#slashing",children:"slashed"}),", the staker will lose their tokens."]}),"\n",(0,a.jsx)(t.h2,{id:"staking",children:"Staking"}),"\n",(0,a.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The ",(0,a.jsx)(t.a,{href:"/concepts/economics/staking",children:"Staking Guide"})," highlights the steps required to stake CSPR tokens on the Casper Mainnet."]}),"\n",(0,a.jsx)(t.h2,{id:"state-root-hash",children:"State root hash"}),"\n",(0,a.jsxs)(t.p,{children:["The state root hash is an identifier of the network's ",(0,a.jsx)(t.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras."]}),"\n",(0,a.jsx)(t.h2,{id:"stateful",children:"Stateful"}),"\n",(0,a.jsx)(t.p,{children:"Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions."}),"\n",(0,a.jsx)(t.h2,{id:"stateless",children:"Stateless"}),"\n",(0,a.jsx)(t.p,{children:"Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time."}),"\n",(0,a.jsx)(t.h2,{id:"switch-block",children:"Switch Block"}),"\n",(0,a.jsxs)(t.p,{children:["A ",(0,a.jsx)(t.code,{children:"Switch Block"})," is the final block in an era, which contains the ",(0,a.jsx)(t.code,{children:"era_summary"}),". See also ",(0,a.jsx)(t.a,{href:"/concepts/glossary/B#booking-block",children:"booking block"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var a=s(96540);const n={},r=a.createContext(n);function o(e){const t=a.useContext(r);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:o(e.components),a.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9d52fc5.a4eef94e.js b/assets/js/c9d52fc5.a4eef94e.js deleted file mode 100644 index d8979bcd2..000000000 --- a/assets/js/c9d52fc5.a4eef94e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9210],{53385:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var n=s(74848),a=s(28453);const r={},o="S",c={id:"concepts/glossary/S",title:"S",description:"---",source:"@site/docs/concepts/glossary/S.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/S",permalink:"/next/concepts/glossary/S",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"R",permalink:"/next/concepts/glossary/R"},next:{title:"T",permalink:"/next/concepts/glossary/T"}},i={},l=[{value:"Safe",id:"safe",level:2},{value:"Secret key",id:"secret-key",level:2},{value:"Seigniorage",id:"seigniorage",level:2},{value:"Session code",id:"session-code",level:2},{value:"Slashing",id:"slashing",level:2},{value:"Smart contract",id:"smart-contract",level:2},{value:"Smart-contract platform",id:"smart-contract-platform",level:2},{value:"Staker",id:"staker",level:2},{value:"Staking",id:"staking",level:2},{value:"State root hash",id:"state-root-hash",level:2},{value:"Stateful",id:"stateful",level:2},{value:"Stateless",id:"stateless",level:2},{value:"Switch Block",id:"switch-block",level:2}];function h(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"s",children:"S"})}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsx)(t.h2,{id:"safe",children:"Safe"}),"\n",(0,n.jsxs)(t.p,{children:["When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/C#cbc",children:"CBC"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"secret-key",children:"Secret key"}),"\n",(0,n.jsx)(t.p,{children:"A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations)."}),"\n",(0,n.jsx)(t.h2,{id:"seigniorage",children:"Seigniorage"}),"\n",(0,n.jsx)(t.p,{children:"The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators."}),"\n",(0,n.jsx)(t.h2,{id:"session-code",children:"Session code"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Session code"})," is Wasm executed in the context of an account entity through sending a ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/T#transaction",children:"transaction"}),". The ",(0,n.jsx)(t.em,{children:"session code"})," contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state."]}),"\n",(0,n.jsx)(t.h2,{id:"slashing",children:"Slashing"}),"\n",(0,n.jsxs)(t.p,{children:["In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets ",(0,n.jsx)(t.em,{children:"slashed"}),", i.e., a part of it is removed."]}),"\n",(0,n.jsx)(t.h2,{id:"smart-contract",children:"Smart contract"}),"\n",(0,n.jsx)(t.p,{children:"Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party."}),"\n",(0,n.jsxs)(t.p,{children:["On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"}),". The execution of a smart contract causes changes to the global state."]}),"\n",(0,n.jsx)(t.p,{children:"A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values."}),"\n",(0,n.jsx)(t.h2,{id:"smart-contract-platform",children:"Smart-contract platform"}),"\n",(0,n.jsx)(t.p,{children:"A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts."}),"\n",(0,n.jsx)(t.h2,{id:"staker",children:"Staker"}),"\n",(0,n.jsxs)(t.p,{children:["A staker is either a ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/V#validator",children:"validator"})," or a ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/D#delegator",children:"delegator"}),". Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/T#token",children:"tokens"})," by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is ",(0,n.jsx)(t.a,{href:"#slashing",children:"slashed"}),", the staker will lose their tokens."]}),"\n",(0,n.jsx)(t.h2,{id:"staking",children:"Staking"}),"\n",(0,n.jsxs)(t.p,{children:["A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The ",(0,n.jsx)(t.a,{href:"/next/concepts/economics/staking",children:"Staking Guide"})," highlights the steps required to stake CSPR tokens on the Casper Mainnet."]}),"\n",(0,n.jsx)(t.h2,{id:"state-root-hash",children:"State root hash"}),"\n",(0,n.jsxs)(t.p,{children:["The state root hash is an identifier of the network's ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"})," at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras."]}),"\n",(0,n.jsx)(t.h2,{id:"stateful",children:"Stateful"}),"\n",(0,n.jsx)(t.p,{children:"Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions."}),"\n",(0,n.jsx)(t.h2,{id:"stateless",children:"Stateless"}),"\n",(0,n.jsx)(t.p,{children:"Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time."}),"\n",(0,n.jsx)(t.h2,{id:"switch-block",children:"Switch Block"}),"\n",(0,n.jsxs)(t.p,{children:["A ",(0,n.jsx)(t.code,{children:"Switch Block"})," is the final block in an era, which contains the ",(0,n.jsx)(t.code,{children:"era_summary"}),". See also ",(0,n.jsx)(t.a,{href:"/next/concepts/glossary/B#booking-block",children:"booking block"}),"."]})]})}function d(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var n=s(96540);const a={},r=n.createContext(a);function o(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9db186d.08192e85.js b/assets/js/c9db186d.08192e85.js deleted file mode 100644 index af3b07811..000000000 --- a/assets/js/c9db186d.08192e85.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6988],{59151:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var o=t(74848),r=t(28453);const a={},i="Becoming a Validator",d={id:"operators/becoming-a-validator/index",title:"Becoming a Validator",description:"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/index.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/",permalink:"/operators/becoming-a-validator/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Non-Root Users",permalink:"/operators/setup/non-root-user"},next:{title:"Bonding",permalink:"/operators/becoming-a-validator/bonding"}},s={},c=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"becoming-a-validator",children:"Becoming a Validator"})}),"\n",(0,o.jsxs)(n.p,{children:["After ",(0,o.jsx)(n.a,{href:"/operators/setup/",children:"setting up a node"}),", the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{children:"Title"}),(0,o.jsx)(n.th,{children:"Description"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding",children:"Bonding as a Validator"})}),(0,o.jsx)(n.td,{children:"A guide about the bonding process and submitting a bid"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"Unbonding as a Validator"})}),(0,o.jsx)(n.td,{children:"The process to withdraw a bid and unbonding"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/operators/becoming-a-validator/recovering",children:"Recovering from Validator Eviction"})}),(0,o.jsx)(n.td,{children:"Steps a validator needs to take if it is evicted from the validator set"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Nodes"})}),(0,o.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var o=t(96540);const r={},a=o.createContext(r);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9db186d.fb5fa52a.js b/assets/js/c9db186d.fb5fa52a.js new file mode 100644 index 000000000..948dbeba0 --- /dev/null +++ b/assets/js/c9db186d.fb5fa52a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46988],{59151:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>s,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var o=t(74848),r=t(28453);const a={},i="Becoming a Validator",d={id:"operators/becoming-a-validator/index",title:"Becoming a Validator",description:"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.",source:"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/index.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/",permalink:"/1.5.X/operators/becoming-a-validator/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Non-Root Users",permalink:"/1.5.X/operators/setup/non-root-user"},next:{title:"Bonding",permalink:"/1.5.X/operators/becoming-a-validator/bonding"}},s={},c=[];function l(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"becoming-a-validator",children:"Becoming a Validator"})}),"\n",(0,o.jsxs)(n.p,{children:["After ",(0,o.jsx)(n.a,{href:"/1.5.X/operators/setup/",children:"setting up a node"}),", the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,o.jsxs)(n.table,{children:[(0,o.jsx)(n.thead,{children:(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.th,{children:"Title"}),(0,o.jsx)(n.th,{children:"Description"})]})}),(0,o.jsxs)(n.tbody,{children:[(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/bonding",children:"Bonding as a Validator"})}),(0,o.jsx)(n.td,{children:"A guide about the bonding process and submitting a bid"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/unbonding",children:"Unbonding as a Validator"})}),(0,o.jsx)(n.td,{children:"The process to withdraw a bid and unbonding"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/recovering",children:"Recovering from Validator Eviction"})}),(0,o.jsx)(n.td,{children:"Steps a validator needs to take if it is evicted from the validator set"})]}),(0,o.jsxs)(n.tr,{children:[(0,o.jsx)(n.td,{children:(0,o.jsx)(n.a,{href:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty",children:"Inactive vs. Faulty Nodes"})}),(0,o.jsx)(n.td,{children:"The differences between inactive and faulty nodes"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var o=t(96540);const r={},a=o.createContext(r);function i(e){const n=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),o.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9f0fdac.1f67a1b8.js b/assets/js/c9f0fdac.1f67a1b8.js deleted file mode 100644 index 04bbffc92..000000000 --- a/assets/js/c9f0fdac.1f67a1b8.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5727],{59897:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var n=t(74848),r=t(28453);const a={title:"SDK Client Libraries",slug:"/sdk"},i="SDK Client Libraries",d={id:"developers/dapps/sdk/index",title:"SDK Client Libraries",description:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/index.md",sourceDirName:"developers/dapps/sdk",slug:"/sdk",permalink:"/sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"SDK Client Libraries",slug:"/sdk"},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/developers/dapps/prerequisites"},next:{title:"SDK Client Library Usage",permalink:"/developers/dapps/sdk/client-library-usage"}},o={},c=[{value:"Serialization Standard",id:"serialization-standard",level:2},{value:"JSON-RPC API",id:"json-rpc-api",level:2},{value:"Table of Contents",id:"table-of-contents",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,n.jsx)(s.p,{children:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions."}),"\n",(0,n.jsx)(s.p,{children:"Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories."}),"\n",(0,n.jsx)(s.p,{children:"Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories."}),"\n",(0,n.jsx)(s.h2,{id:"serialization-standard",children:"Serialization Standard"}),"\n",(0,n.jsxs)(s.p,{children:["The Casper platform uses a custom serialization format. To this end, we've established a ",(0,n.jsx)(s.a,{href:"/concepts/serialization-standard",children:"Serialization Standard"}),", which must be followed when building a Casper SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"json-rpc-api",children:"JSON-RPC API"}),"\n",(0,n.jsxs)(s.p,{children:["Developers can interact directly with the ",(0,n.jsx)(s.a,{href:"/developers/json-rpc/",children:"Casper JSON-RPC API"})," instead of using an SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"SDK Documentation"}),(0,n.jsx)(s.th,{children:"GitHub Location"}),(0,n.jsx)(s.th,{children:"Organization"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/script-sdk",children:"JavaScript/TypeScript"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"casper-js-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Java SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-java-sdk/",children:"casper-java-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/csharp-sdk",children:"C# SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-net-sdk",children:"casper-net-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/go-sdk",children:"Go SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-go-sdk",children:"casper-go-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/developers/dapps/sdk/python-sdk",children:"Python SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/",children:"casper-python-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PHP SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-php-sdk",children:"casper-php-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Scala SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"casper-scala-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem",children:"M. Abahmane"})})]})]})]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function i(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9f0fdac.8d113f91.js b/assets/js/c9f0fdac.8d113f91.js new file mode 100644 index 000000000..8d5ddc918 --- /dev/null +++ b/assets/js/c9f0fdac.8d113f91.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75727],{59897:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var n=t(74848),r=t(28453);const a={title:"SDK Client Libraries",slug:"/sdk"},i="SDK Client Libraries",d={id:"developers/dapps/sdk/index",title:"SDK Client Libraries",description:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/index.md",sourceDirName:"developers/dapps/sdk",slug:"/sdk",permalink:"/1.5.X/sdk",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"SDK Client Libraries",slug:"/sdk"},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/1.5.X/developers/dapps/prerequisites"},next:{title:"SDK Client Library Usage",permalink:"/1.5.X/developers/dapps/sdk/client-library-usage"}},o={},c=[{value:"Serialization Standard",id:"serialization-standard",level:2},{value:"JSON-RPC API",id:"json-rpc-api",level:2},{value:"Table of Contents",id:"table-of-contents",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,n.jsx)(s.p,{children:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions."}),"\n",(0,n.jsx)(s.p,{children:"Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories."}),"\n",(0,n.jsx)(s.p,{children:"Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories."}),"\n",(0,n.jsx)(s.h2,{id:"serialization-standard",children:"Serialization Standard"}),"\n",(0,n.jsxs)(s.p,{children:["The Casper platform uses a custom serialization format. To this end, we've established a ",(0,n.jsx)(s.a,{href:"/1.5.X/concepts/serialization-standard",children:"Serialization Standard"}),", which must be followed when building a Casper SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"json-rpc-api",children:"JSON-RPC API"}),"\n",(0,n.jsxs)(s.p,{children:["Developers can interact directly with the ",(0,n.jsx)(s.a,{href:"/1.5.X/developers/json-rpc/",children:"Casper JSON-RPC API"})," instead of using an SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"SDK Documentation"}),(0,n.jsx)(s.th,{children:"GitHub Location"}),(0,n.jsx)(s.th,{children:"Organization"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/1.5.X/developers/dapps/sdk/script-sdk",children:"JavaScript/TypeScript"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"casper-js-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Java SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-java-sdk/",children:"casper-java-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/1.5.X/developers/dapps/sdk/csharp-sdk",children:"C# SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-net-sdk",children:"casper-net-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/1.5.X/developers/dapps/sdk/go-sdk",children:"Go SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-go-sdk",children:"casper-go-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/1.5.X/developers/dapps/sdk/python-sdk",children:"Python SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/",children:"casper-python-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PHP SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-php-sdk",children:"casper-php-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Scala SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"casper-scala-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem",children:"M. Abahmane"})})]})]})]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function i(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ca0e408e.aa3ff09a.js b/assets/js/ca0e408e.aa3ff09a.js deleted file mode 100644 index 1b1f2bb7d..000000000 --- a/assets/js/ca0e408e.aa3ff09a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8431],{43136:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Next","banner":"unreleased","badge":true,"noIndex":false,"className":"docs-version-current","isLast":false,"docsSidebars":{"concepts":[{"type":"link","label":"Overview","href":"/next/concepts/","docId":"concepts/index","unlisted":false},{"type":"link","label":"What is Casper?","href":"/next/","docId":"concepts/about","unlisted":false},{"type":"category","label":"Design","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Network Design","href":"/next/concepts/design/casper-design","docId":"concepts/design/casper-design","unlisted":false},{"type":"link","label":"Network Communication","href":"/next/concepts/design/p2p","docId":"concepts/design/p2p","unlisted":false},{"type":"category","label":"Consensus","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Zug Consensus","href":"/next/concepts/design/zug","docId":"concepts/design/zug","unlisted":false},{"type":"link","label":"Highway Consensus","href":"/next/concepts/design/highway","docId":"concepts/design/highway","unlisted":false}],"href":"/next/concepts/design/consensus"},{"type":"link","label":"Rewards Design","href":"/next/concepts/design/rewards","docId":"concepts/design/rewards","unlisted":false},{"type":"link","label":"Reading and Writing Data","href":"/next/concepts/design/reading-and-writing-to-the-blockchain","docId":"concepts/design/reading-and-writing-to-the-blockchain","unlisted":false}],"href":"/next/design"},{"type":"category","label":"Economics","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Consensus","href":"/next/concepts/economics/consensus","docId":"concepts/economics/consensus","unlisted":false},{"type":"link","label":"Runtime","href":"/next/runtime","docId":"concepts/economics/runtime","unlisted":false},{"type":"link","label":"Gas Cost","href":"/next/concepts/economics/gas-concepts","docId":"concepts/economics/gas-concepts","unlisted":false},{"type":"link","label":"Dynamic Gas Pricing","href":"/next/concepts/economics/dynamic-gas-pricing","docId":"concepts/economics/dynamic-gas-pricing","unlisted":false},{"type":"link","label":"Fee Elimination","href":"/next/concepts/economics/fee-elimination","docId":"concepts/economics/fee-elimination","unlisted":false},{"type":"link","label":"Staking","href":"/next/concepts/economics/staking","docId":"concepts/economics/staking","unlisted":false}],"href":"/next/economics"},{"type":"category","label":"Glossary","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"A","href":"/next/concepts/glossary/A","docId":"concepts/glossary/A","unlisted":false},{"type":"link","label":"B","href":"/next/concepts/glossary/B","docId":"concepts/glossary/B","unlisted":false},{"type":"link","label":"C","href":"/next/concepts/glossary/C","docId":"concepts/glossary/C","unlisted":false},{"type":"link","label":"D","href":"/next/concepts/glossary/D","docId":"concepts/glossary/D","unlisted":false},{"type":"link","label":"E","href":"/next/concepts/glossary/E","docId":"concepts/glossary/E","unlisted":false},{"type":"link","label":"F","href":"/next/concepts/glossary/F","docId":"concepts/glossary/F","unlisted":false},{"type":"link","label":"G","href":"/next/concepts/glossary/G","docId":"concepts/glossary/G","unlisted":false},{"type":"link","label":"H","href":"/next/concepts/glossary/H","docId":"concepts/glossary/H","unlisted":false},{"type":"link","label":"I","href":"/next/concepts/glossary/I","docId":"concepts/glossary/I","unlisted":false},{"type":"link","label":"J","href":"/next/concepts/glossary/J","docId":"concepts/glossary/J","unlisted":false},{"type":"link","label":"K","href":"/next/concepts/glossary/K","docId":"concepts/glossary/K","unlisted":false},{"type":"link","label":"L","href":"/next/concepts/glossary/L","docId":"concepts/glossary/L","unlisted":false},{"type":"link","label":"M","href":"/next/concepts/glossary/M","docId":"concepts/glossary/M","unlisted":false},{"type":"link","label":"N","href":"/next/concepts/glossary/N","docId":"concepts/glossary/N","unlisted":false},{"type":"link","label":"O","href":"/next/concepts/glossary/O","docId":"concepts/glossary/O","unlisted":false},{"type":"link","label":"P","href":"/next/concepts/glossary/P","docId":"concepts/glossary/P","unlisted":false},{"type":"link","label":"Q","href":"/next/concepts/glossary/Q","docId":"concepts/glossary/Q","unlisted":false},{"type":"link","label":"R","href":"/next/concepts/glossary/R","docId":"concepts/glossary/R","unlisted":false},{"type":"link","label":"S","href":"/next/concepts/glossary/S","docId":"concepts/glossary/S","unlisted":false},{"type":"link","label":"T","href":"/next/concepts/glossary/T","docId":"concepts/glossary/T","unlisted":false},{"type":"link","label":"U","href":"/next/concepts/glossary/U","docId":"concepts/glossary/U","unlisted":false},{"type":"link","label":"V","href":"/next/concepts/glossary/V","docId":"concepts/glossary/V","unlisted":false},{"type":"link","label":"W","href":"/next/concepts/glossary/W","docId":"concepts/glossary/W","unlisted":false},{"type":"link","label":"X","href":"/next/concepts/glossary/X","docId":"concepts/glossary/X","unlisted":false},{"type":"link","label":"Y","href":"/next/concepts/glossary/Y","docId":"concepts/glossary/Y","unlisted":false},{"type":"link","label":"Z","href":"/next/concepts/glossary/Z","docId":"concepts/glossary/Z","unlisted":false}],"href":"/next/glossary"},{"type":"category","label":"Binary Serialization Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Primitives and Basic Serialization Rules","href":"/next/concepts/serialization/primitives","docId":"concepts/serialization/primitives","unlisted":false},{"type":"link","label":"Major Structures","href":"/next/concepts/serialization/structures","docId":"concepts/serialization/structures","unlisted":false},{"type":"link","label":"Type Serialization","href":"/next/concepts/serialization/types","docId":"concepts/serialization/types","unlisted":false}],"href":"/next/concepts/serialization/"},{"type":"link","label":"dApps","href":"/next/concepts/intro-to-dapps","docId":"concepts/intro-to-dapps","unlisted":false},{"type":"link","label":"Addressable Entities","href":"/next/concepts/addressable-entity","docId":"concepts/addressable-entity","unlisted":false},{"type":"link","label":"Accounts and Keys","href":"/next/concepts/accounts-and-keys","docId":"concepts/accounts-and-keys","unlisted":false},{"type":"link","label":"Key Types","href":"/next/concepts/key-types","docId":"concepts/key-types","unlisted":false},{"type":"link","label":"Transaction Lifecycle","href":"/next/transactions-and-transaction-lifecycle","docId":"concepts/transactions-and-transaction-lifecycle","unlisted":false},{"type":"link","label":"Global State","href":"/next/concepts/global-state","docId":"concepts/global-state","unlisted":false},{"type":"link","label":"Smart Contracts","href":"/next/concepts/smart-contracts","docId":"concepts/smart-contracts","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/next/concepts/list-auth-keys","docId":"concepts/list-auth-keys","unlisted":false},{"type":"link","label":"Call Stacks","href":"/next/concepts/callstack","docId":"concepts/callstack","unlisted":false},{"type":"link","label":"Dictionaries","href":"/next/concepts/dictionaries","docId":"concepts/dictionaries","unlisted":false}],"developers":[{"type":"link","label":"Overview","href":"/next/developers","docId":"developers/index","unlisted":false},{"type":"link","label":"Development Prerequisites","href":"/next/developers/prerequisites","docId":"developers/prerequisites","unlisted":false},{"type":"link","label":"Essential Rust Crates","href":"/next/developers/essential-crates","docId":"developers/essential-crates","unlisted":false},{"type":"category","label":"Writing On-Chain Code","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started with Rust","href":"/next/developers/writing-onchain-code/getting-started","docId":"developers/writing-onchain-code/getting-started","unlisted":false},{"type":"link","label":"Getting Started with AssemblyScript","href":"/next/developers/writing-onchain-code/assembly-script","docId":"developers/writing-onchain-code/assembly-script","unlisted":false},{"type":"link","label":"Writing a Basic Smart Contract in Rust","href":"/next/developers/writing-onchain-code/simple-contract","docId":"developers/writing-onchain-code/simple-contract","unlisted":false},{"type":"link","label":"Testing Smart Contracts","href":"/next/developers/writing-onchain-code/testing-contracts","docId":"developers/writing-onchain-code/testing-contracts","unlisted":false},{"type":"link","label":"Upgrading and Maintaining Smart Contracts","href":"/next/developers/writing-onchain-code/upgrading-contracts","docId":"developers/writing-onchain-code/upgrading-contracts","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/next/developers/writing-onchain-code/calling-contracts","docId":"developers/writing-onchain-code/calling-contracts","unlisted":false},{"type":"link","label":"Contracts and Session Code","href":"/next/developers/writing-onchain-code/contract-vs-session","docId":"developers/writing-onchain-code/contract-vs-session","unlisted":false},{"type":"link","label":"Writing Session Code","href":"/next/developers/writing-onchain-code/writing-session-code","docId":"developers/writing-onchain-code/writing-session-code","unlisted":false},{"type":"link","label":"Testing Session Code","href":"/next/developers/writing-onchain-code/testing-session-code","docId":"developers/writing-onchain-code/testing-session-code","unlisted":false},{"type":"link","label":"Contract-Level Events","href":"/next/developers/writing-onchain-code/emitting-contract-events","docId":"developers/writing-onchain-code/emitting-contract-events","unlisted":false},{"type":"link","label":"Contract Hash vs. Package Hash","href":"/next/developers/writing-onchain-code/contract-hash-vs-package-hash","docId":"developers/writing-onchain-code/contract-hash-vs-package-hash","unlisted":false},{"type":"link","label":"Factory Contracts","href":"/next/developers/writing-onchain-code/factory-pattern","docId":"developers/writing-onchain-code/factory-pattern","unlisted":false},{"type":"link","label":"Best Practices for Casper Smart Contract Authors","href":"/next/developers/writing-onchain-code/best-practices","docId":"developers/writing-onchain-code/best-practices","unlisted":false}],"href":"/next/writing-contracts"},{"type":"category","label":"Casper JSON-RPC API","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Guidance for JSON-RPC SDK Compliance","href":"/next/developers/json-rpc/guidance","docId":"developers/json-rpc/guidance","unlisted":false},{"type":"link","label":"Required Methods for Minimal Compliance","href":"/next/developers/json-rpc/minimal-compliance","docId":"developers/json-rpc/minimal-compliance","unlisted":false},{"type":"link","label":"Transactional JSON-RPC Methods","href":"/next/developers/json-rpc/json-rpc-transactional","docId":"developers/json-rpc/json-rpc-transactional","unlisted":false},{"type":"link","label":"Informational JSON-RPC Methods","href":"/next/developers/json-rpc/json-rpc-informational","docId":"developers/json-rpc/json-rpc-informational","unlisted":false},{"type":"link","label":"Proof-of-Stake JSON-RPC Methods","href":"/next/developers/json-rpc/json-rpc-pos","docId":"developers/json-rpc/json-rpc-pos","unlisted":false},{"type":"link","label":"Types","href":"/next/developers/json-rpc/types_chain","docId":"developers/json-rpc/types_chain","unlisted":false},{"type":"link","label":"CLType","href":"/next/developers/json-rpc/types_cl","docId":"developers/json-rpc/types_cl","unlisted":false}],"href":"/next/developers/json-rpc/"},{"type":"category","label":"Building dApps","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is a dApp?","href":"/next/developers/dapps/dapp","docId":"developers/dapps/dapp","unlisted":false},{"type":"link","label":"Prerequisites","href":"/next/developers/dapps/prerequisites","docId":"developers/dapps/prerequisites","unlisted":false},{"type":"category","label":"SDK Client Libraries","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SDK Client Library Usage","href":"/next/developers/dapps/sdk/client-library-usage","docId":"developers/dapps/sdk/client-library-usage","unlisted":false},{"type":"link","label":"JavaScript/TypeScript SDK","href":"/next/developers/dapps/sdk/script-sdk","docId":"developers/dapps/sdk/script-sdk","unlisted":false},{"type":"link","label":".NET SDK","href":"/next/developers/dapps/sdk/csharp-sdk","docId":"developers/dapps/sdk/csharp-sdk","unlisted":false},{"type":"link","label":"Go SDK","href":"/next/developers/dapps/sdk/go-sdk","docId":"developers/dapps/sdk/go-sdk","unlisted":false},{"type":"link","label":"Python SDK","href":"/next/developers/dapps/sdk/python-sdk","docId":"developers/dapps/sdk/python-sdk","unlisted":false}],"href":"/next/sdk"},{"type":"link","label":"dApp Technology Stack","href":"/next/developers/dapps/technology-stack","docId":"developers/dapps/technology-stack","unlisted":false},{"type":"link","label":"Front-end in React","href":"/next/developers/dapps/template-frontend","docId":"developers/dapps/template-frontend","unlisted":false},{"type":"link","label":"URef Access Rights","href":"/next/developers/dapps/uref-security","docId":"developers/dapps/uref-security","unlisted":false},{"type":"link","label":"Signing Transactions","href":"/next/developers/dapps/signing-a-transaction","docId":"developers/dapps/signing-a-transaction","unlisted":false},{"type":"link","label":"Estimating Gas Costs with Speculative Execution","href":"/next/developers/dapps/speculative-exec","docId":"developers/dapps/speculative-exec","unlisted":false},{"type":"link","label":"Local Network Setup","href":"/next/developers/dapps/setup-nctl","docId":"developers/dapps/setup-nctl","unlisted":false},{"type":"link","label":"Local Network Testing","href":"/next/developers/dapps/nctl-test","docId":"developers/dapps/nctl-test","unlisted":false},{"type":"link","label":"Monitoring Events with the Casper Sidecar","href":"/next/developers/dapps/monitor-and-consume-events","docId":"developers/dapps/monitor-and-consume-events","unlisted":false}],"href":"/next/developers/dapps/"},{"type":"category","label":"Interacting with the Blockchain","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Transferring Tokens","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Direct Token Transfer","href":"/next/developers/cli/transfers/direct-token-transfer","docId":"developers/cli/transfers/direct-token-transfer","unlisted":false},{"type":"link","label":"Transferring Tokens using a Multi-Sig Deploy","href":"/next/developers/cli/transfers/multisig-deploy-transfer","docId":"developers/cli/transfers/multisig-deploy-transfer","unlisted":false},{"type":"link","label":"Verifying a Transfer","href":"/next/developers/cli/transfers/verify-transfer","docId":"developers/cli/transfers/verify-transfer","unlisted":false}],"href":"/next/developers/cli/transfers/"},{"type":"link","label":"Delegating Tokens","href":"/next/developers/cli/delegate","docId":"developers/cli/delegate","unlisted":false},{"type":"link","label":"Redelegating Tokens with the Casper Client","href":"/next/developers/cli/redelegate","docId":"developers/cli/redelegate","unlisted":false},{"type":"link","label":"Undelegating Tokens","href":"/next/developers/cli/undelegate","docId":"developers/cli/undelegate","unlisted":false},{"type":"link","label":"Sending Transactions","href":"/next/developers/cli/sending-transactions","docId":"developers/cli/sending-transactions","unlisted":false},{"type":"link","label":"Installing Contracts","href":"/next/developers/cli/installing-contracts","docId":"developers/cli/installing-contracts","unlisted":false},{"type":"link","label":"Verifying Contracts","href":"/next/developers/cli/verifying-contracts","docId":"developers/cli/verifying-contracts","unlisted":false},{"type":"link","label":"Querying Global State","href":"/next/developers/cli/querying-global-state","docId":"developers/cli/querying-global-state","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/next/developers/cli/calling-contracts","docId":"developers/cli/calling-contracts","unlisted":false},{"type":"link","label":"OpCode Costs Tables","href":"/next/developers/cli/opcode-costs","docId":"developers/cli/opcode-costs","unlisted":false},{"type":"link","label":"Execution Error Codes","href":"/next/developers/cli/execution-error-codes","docId":"developers/cli/execution-error-codes","unlisted":false}],"href":"/next/developers/cli/"}],"operators":[{"type":"link","label":"Overview","href":"/next/operators","docId":"operators/index","unlisted":false},{"type":"category","label":"Node Setup","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Hardware","href":"/next/operators/setup/hardware","docId":"operators/setup/hardware","unlisted":false},{"type":"link","label":"Configuration","href":"/next/operators/setup/basic-node-configuration","docId":"operators/setup/basic-node-configuration","unlisted":false},{"type":"link","label":"Endpoints","href":"/next/operators/setup/node-endpoints","docId":"operators/setup/node-endpoints","unlisted":false},{"type":"link","label":"Installation","href":"/next/operators/setup/install-node","docId":"operators/setup/install-node","unlisted":false},{"type":"link","label":"Fast Sync","href":"/next/operators/setup/fast-sync","docId":"operators/setup/fast-sync","unlisted":false},{"type":"link","label":"Open Files Limit","href":"/next/operators/setup/open-files","docId":"operators/setup/open-files","unlisted":false},{"type":"link","label":"Upgrades","href":"/next/operators/setup/upgrade","docId":"operators/setup/upgrade","unlisted":false},{"type":"link","label":"Join a Network","href":"/next/operators/setup/joining","docId":"operators/setup/joining","unlisted":false},{"type":"link","label":"Non-Root Users","href":"/next/operators/setup/non-root-user","docId":"operators/setup/non-root-user","unlisted":false},{"type":"link","label":"Node Events","href":"/next/operators/setup/node-events","docId":"operators/setup/node-events","unlisted":false},{"type":"link","label":"Sidecar Setup","href":"/next/operators/setup/casper-sidecar","docId":"operators/setup/casper-sidecar","unlisted":false}],"href":"/next/operators/setup/"},{"type":"category","label":"Validators","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bonding","href":"/next/operators/becoming-a-validator/bonding","docId":"operators/becoming-a-validator/bonding","unlisted":false},{"type":"link","label":"Unbonding","href":"/next/operators/becoming-a-validator/unbonding","docId":"operators/becoming-a-validator/unbonding","unlisted":false},{"type":"link","label":"Recovery","href":"/next/operators/becoming-a-validator/recovering","docId":"operators/becoming-a-validator/recovering","unlisted":false},{"type":"link","label":"Inactive and Faulty Nodes","href":"/next/operators/becoming-a-validator/inactive-vs-faulty","docId":"operators/becoming-a-validator/inactive-vs-faulty","unlisted":false}],"href":"/next/operators/becoming-a-validator/"},{"type":"category","label":"Private Networks","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Genesis","href":"/next/operators/setup-network/genesis","docId":"operators/setup-network/genesis","unlisted":false},{"type":"link","label":"The Chainspec","href":"/next/operators/setup-network/chain-spec","docId":"operators/setup-network/chain-spec","unlisted":false},{"type":"link","label":"Private Network Setup","href":"/next/operators/setup-network/create-private","docId":"operators/setup-network/create-private","unlisted":false},{"type":"link","label":"Staging Files","href":"/next/operators/setup-network/staging-files-for-new-network","docId":"operators/setup-network/staging-files-for-new-network","unlisted":false}],"href":"/next/operators/setup-network/"},{"type":"category","label":"Maintenance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Archive and Restore a DB","href":"/next/operators/maintenance/archiving-and-restoring","docId":"operators/maintenance/archiving-and-restoring","unlisted":false},{"type":"link","label":"Move a Node","href":"/next/operators/maintenance/moving-node","docId":"operators/maintenance/moving-node","unlisted":false}],"href":"/next/operators/maintenance/"}],"resources":[{"type":"link","label":"Resources Overview","href":"/next/resources/","docId":"resources/index","unlisted":false},{"type":"link","label":"Build on Casper","href":"/next/resources/build-on-casper/introduction","docId":"resources/build-on-casper","unlisted":false},{"type":"link","label":"Move to Casper","href":"/next/resources/moving-to-casper","docId":"resources/moving-to-casper","unlisted":false},{"type":"category","label":"Casper Token Standards","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CEP-18 Fungible Token","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"On-chain Installation","href":"/next/resources/tokens/cep18/quickstart-guide","docId":"resources/tokens/cep18/quickstart-guide","unlisted":false},{"type":"link","label":"CEP-18 Contract Details","href":"/next/resources/tokens/cep18/query","docId":"resources/tokens/cep18/query","unlisted":false},{"type":"link","label":"CEP-18 Transfers","href":"/next/resources/tokens/cep18/transfer","docId":"resources/tokens/cep18/transfer","unlisted":false},{"type":"link","label":"Testing Guide","href":"/next/resources/tokens/cep18/tests","docId":"resources/tokens/cep18/tests","unlisted":false}],"href":"/next/resources/tokens/cep18/full-tutorial"},{"type":"category","label":"CEP-78 Enhanced NFT Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CEP-78 Modalities","href":"/next/resources/tokens/cep78/modalities","docId":"resources/tokens/cep78/modalities","unlisted":false},{"type":"link","label":"On-chain Installation","href":"/next/resources/tokens/using-casper-client","docId":"resources/tokens/cep78/using-casper-client","unlisted":false},{"type":"link","label":"Ownership Lookup","href":"/next/resources/tokens/cep78/reverse-lookup","docId":"resources/tokens/cep78/reverse-lookup","unlisted":false},{"type":"link","label":"CEP-78 JavaScript Client","href":"/next/resources/tokens/cep78/js-tutorial","docId":"resources/tokens/cep78/js-tutorial","unlisted":false}],"href":"/next/resources/tokens/cep78/introduction"}],"href":"/next/resources/tokens/"},{"type":"link","label":"Open-Source Software","href":"/next/resources/build-on-casper/casper-open-source-software","docId":"resources/casper-open-source-software","unlisted":false},{"type":"link","label":"Quickstart","href":"/next/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/next/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/next/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/next/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/next/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/next/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/next/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/next/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/next/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/next/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/next/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/next/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/next/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/next/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/next/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/next/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/next/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/next/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/next/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/next/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/next/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/next/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/next/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/next/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/next/resources/tutorials/advanced/"}],"users":[{"type":"link","label":"Users Overview","href":"/next/users/","docId":"users/index","unlisted":false},{"type":"link","label":"Block Explorers","href":"/next/users/block-explorer","docId":"users/block-explorer","unlisted":false},{"type":"link","label":"Funding Mainnet Accounts","href":"/next/users/funding-from-exchanges","docId":"users/funding-from-exchanges","unlisted":false},{"type":"link","label":"Delegating Tokens","href":"/next/users/delegating","docId":"users/delegating","unlisted":false},{"type":"category","label":"Using CSPR.live","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testnet Funding","href":"/next/users/testnet-faucet","docId":"users/csprlive/testnet-faucet","unlisted":false},{"type":"link","label":"Delegate Tokens","href":"/next/users/delegate-ui","docId":"users/csprlive/delegate-ui","unlisted":false},{"type":"link","label":"Undelegate Tokens","href":"/next/users/undelegate-ui","docId":"users/csprlive/undelegate-ui","unlisted":false},{"type":"link","label":"Transfer Tokens","href":"/next/users/token-transfer","docId":"users/csprlive/token-transfer","unlisted":false}],"href":"/next/users/csprlive/"},{"type":"category","label":"Ledger Devices","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Set up Ledger","href":"/next/workflow/ledger-setup/","docId":"users/ledger/ledger-setup","unlisted":false},{"type":"link","label":"Ledger and Ledger Live","href":"/next/users/ledger/ledger-live","docId":"users/ledger/ledger-live","unlisted":false},{"type":"link","label":"Ledger and CSPR.live","href":"/next/users/ledger/ledger-cspr-live","docId":"users/ledger/ledger-cspr-live","unlisted":false},{"type":"link","label":"Delegate with Ledger","href":"/next/users/staking-ledger","docId":"users/ledger/staking-ledger","unlisted":false}],"href":"/next/users/ledger/"}],"tutorials":[{"type":"link","label":"Quickstart","href":"/next/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/next/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/next/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/next/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/next/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/next/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/next/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/next/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/next/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/next/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/next/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/next/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/next/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/next/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/next/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/next/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/next/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/next/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/next/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/next/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/next/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/next/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/next/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/next/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/next/resources/tutorials/advanced/"}]},"docs":{"concepts/about":{"id":"concepts/about","title":"What is Casper?","description":"What is Casper?","sidebar":"concepts"},"concepts/accounts-and-keys":{"id":"concepts/accounts-and-keys","title":"Accounts and Keys","description":"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.","sidebar":"concepts"},"concepts/addressable-entity":{"id":"concepts/addressable-entity","title":"Addressable Entities","description":"What is an Addressable Entity?","sidebar":"concepts"},"concepts/callstack":{"id":"concepts/callstack","title":"Call Stacks","description":"Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.","sidebar":"concepts"},"concepts/design/casper-design":{"id":"concepts/design/casper-design","title":"Network Design","description":"Introduction","sidebar":"concepts"},"concepts/design/consensus":{"id":"concepts/design/consensus","title":"Consensus in a Casper Network","description":"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network\'s consensus protocol is a mechanism for the validators to agree on each finalized block.","sidebar":"concepts"},"concepts/design/highway":{"id":"concepts/design/highway","title":"Highway Consensus","description":"The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.","sidebar":"concepts"},"concepts/design/index":{"id":"concepts/design/index","title":"Design Overview","description":"| Topic | Description |","sidebar":"concepts"},"concepts/design/networking-protocol":{"id":"concepts/design/networking-protocol","title":"Casper Node Networking Protocol","description":"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"},"concepts/design/p2p":{"id":"concepts/design/p2p","title":"Network Communication","description":"communications-head}","sidebar":"concepts"},"concepts/design/reading-and-writing-to-the-blockchain":{"id":"concepts/design/reading-and-writing-to-the-blockchain","title":"Reading and Writing Data","description":"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.","sidebar":"concepts"},"concepts/design/rewards":{"id":"concepts/design/rewards","title":"Rewards Design","description":"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.","sidebar":"concepts"},"concepts/design/zug":{"id":"concepts/design/zug","title":"Zug Consensus","description":"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.","sidebar":"concepts"},"concepts/dictionaries":{"id":"concepts/dictionaries","title":"Dictionaries","description":"dictionaries}","sidebar":"concepts"},"concepts/economics/consensus":{"id":"concepts/economics/consensus","title":"Consensus","description":"Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.","sidebar":"concepts"},"concepts/economics/dynamic-gas-pricing":{"id":"concepts/economics/dynamic-gas-pricing","title":"Dynamic Gas Pricing","description":"The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.","sidebar":"concepts"},"concepts/economics/fee-elimination":{"id":"concepts/economics/fee-elimination","title":"Fee Elimination","description":"Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled \\"fee elimination\\", also known as the \\"no fee mode\\", or \\"no fee transactions\\" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.","sidebar":"concepts"},"concepts/economics/gas-concepts":{"id":"concepts/economics/gas-concepts","title":"Gas Cost","description":"What is gas?","sidebar":"concepts"},"concepts/economics/index":{"id":"concepts/economics/index","title":"Overview","description":"Casper\'s economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform\'s value.","sidebar":"concepts"},"concepts/economics/runtime":{"id":"concepts/economics/runtime","title":"Runtime","description":"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:","sidebar":"concepts"},"concepts/economics/staking":{"id":"concepts/economics/staking","title":"Staking","description":"The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.","sidebar":"concepts"},"concepts/global-state":{"id":"concepts/global-state","title":"Global State","description":"global-state-head}","sidebar":"concepts"},"concepts/glossary/A":{"id":"concepts/glossary/A","title":"A","description":"---","sidebar":"concepts"},"concepts/glossary/B":{"id":"concepts/glossary/B","title":"B","description":"---","sidebar":"concepts"},"concepts/glossary/C":{"id":"concepts/glossary/C","title":"C","description":"---","sidebar":"concepts"},"concepts/glossary/D":{"id":"concepts/glossary/D","title":"D","description":"---","sidebar":"concepts"},"concepts/glossary/E":{"id":"concepts/glossary/E","title":"E","description":"---","sidebar":"concepts"},"concepts/glossary/F":{"id":"concepts/glossary/F","title":"F","description":"---","sidebar":"concepts"},"concepts/glossary/G":{"id":"concepts/glossary/G","title":"G","description":"---","sidebar":"concepts"},"concepts/glossary/H":{"id":"concepts/glossary/H","title":"H","description":"---","sidebar":"concepts"},"concepts/glossary/I":{"id":"concepts/glossary/I","title":"I","description":"---","sidebar":"concepts"},"concepts/glossary/index":{"id":"concepts/glossary/index","title":"Glossary","description":"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.","sidebar":"concepts"},"concepts/glossary/J":{"id":"concepts/glossary/J","title":"J","description":"---","sidebar":"concepts"},"concepts/glossary/K":{"id":"concepts/glossary/K","title":"K","description":"---","sidebar":"concepts"},"concepts/glossary/L":{"id":"concepts/glossary/L","title":"L","description":"---","sidebar":"concepts"},"concepts/glossary/M":{"id":"concepts/glossary/M","title":"M","description":"---","sidebar":"concepts"},"concepts/glossary/N":{"id":"concepts/glossary/N","title":"N","description":"---","sidebar":"concepts"},"concepts/glossary/O":{"id":"concepts/glossary/O","title":"O","description":"---","sidebar":"concepts"},"concepts/glossary/P":{"id":"concepts/glossary/P","title":"P","description":"---","sidebar":"concepts"},"concepts/glossary/Q":{"id":"concepts/glossary/Q","title":"Q","description":"---","sidebar":"concepts"},"concepts/glossary/R":{"id":"concepts/glossary/R","title":"R","description":"---","sidebar":"concepts"},"concepts/glossary/S":{"id":"concepts/glossary/S","title":"S","description":"---","sidebar":"concepts"},"concepts/glossary/T":{"id":"concepts/glossary/T","title":"T","description":"---","sidebar":"concepts"},"concepts/glossary/U":{"id":"concepts/glossary/U","title":"U","description":"---","sidebar":"concepts"},"concepts/glossary/V":{"id":"concepts/glossary/V","title":"V","description":"---","sidebar":"concepts"},"concepts/glossary/W":{"id":"concepts/glossary/W","title":"W","description":"---","sidebar":"concepts"},"concepts/glossary/X":{"id":"concepts/glossary/X","title":"X","description":"---","sidebar":"concepts"},"concepts/glossary/Y":{"id":"concepts/glossary/Y","title":"Y","description":"---","sidebar":"concepts"},"concepts/glossary/Z":{"id":"concepts/glossary/Z","title":"Z","description":"---","sidebar":"concepts"},"concepts/index":{"id":"concepts/index","title":"Overview","description":"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.","sidebar":"concepts"},"concepts/intro-to-dapps":{"id":"concepts/intro-to-dapps","title":"dApps","description":"What is a dApp?","sidebar":"concepts"},"concepts/key-types":{"id":"concepts/key-types","title":"Key Types","description":"For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.","sidebar":"concepts"},"concepts/list-auth-keys":{"id":"concepts/list-auth-keys","title":"Authorization Keys","description":"This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.","sidebar":"concepts"},"concepts/serialization/index":{"id":"concepts/serialization/index","title":"Binary Serialization Standard","description":"serialization-standard-head}","sidebar":"concepts"},"concepts/serialization/primitives":{"id":"concepts/serialization/primitives","title":"Primitives and Basic Serialization Rules","description":"CLValue","sidebar":"concepts"},"concepts/serialization/structures":{"id":"concepts/serialization/structures","title":"Major Structures","description":"Account","sidebar":"concepts"},"concepts/serialization/types":{"id":"concepts/serialization/types","title":"Type Serialization","description":"Account Action Thresholds","sidebar":"concepts"},"concepts/smart-contracts":{"id":"concepts/smart-contracts","title":"Smart Contracts","description":"Smart Contracts in General","sidebar":"concepts"},"concepts/transactions":{"id":"concepts/transactions","title":"Transactions","description":"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."},"concepts/transactions-and-transaction-lifecycle":{"id":"concepts/transactions-and-transaction-lifecycle","title":"Transaction Lifecycle","description":"Transactions","sidebar":"concepts"},"developers/cli/calling-contracts":{"id":"developers/cli/calling-contracts","title":"Calling Contracts","description":"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.","sidebar":"developers"},"developers/cli/delegate":{"id":"developers/cli/delegate","title":"Delegating Tokens","description":"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.","sidebar":"developers"},"developers/cli/execution-error-codes":{"id":"developers/cli/execution-error-codes","title":"Execution Error Codes","description":"This section covers smart contract execution error codes.","sidebar":"developers"},"developers/cli/index":{"id":"developers/cli/index","title":"Interacting with the Blockchain","description":"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.","sidebar":"developers"},"developers/cli/installing-contracts":{"id":"developers/cli/installing-contracts","title":"Installing Contracts","description":"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.","sidebar":"developers"},"developers/cli/opcode-costs":{"id":"developers/cli/opcode-costs","title":"OpCode Costs Tables","description":"The following tables outline the cost, in motes, for a given operation on Casper\'s Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.","sidebar":"developers"},"developers/cli/querying-global-state":{"id":"developers/cli/querying-global-state","title":"Querying Global State","description":"This page explains how to query global state to find account, contract, and package details.","sidebar":"developers"},"developers/cli/redelegate":{"id":"developers/cli/redelegate","title":"Redelegating Tokens with the Casper Client","description":"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.","sidebar":"developers"},"developers/cli/sending-transactions":{"id":"developers/cli/sending-transactions","title":"Sending Transactions","description":"To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:","sidebar":"developers"},"developers/cli/transfers/direct-token-transfer":{"id":"developers/cli/transfers/direct-token-transfer","title":"Direct Token Transfer","description":"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.","sidebar":"developers"},"developers/cli/transfers/index":{"id":"developers/cli/transfers/index","title":"Transferring Tokens","description":"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.","sidebar":"developers"},"developers/cli/transfers/multisig-deploy-transfer":{"id":"developers/cli/transfers/multisig-deploy-transfer","title":"Transferring Tokens using a Multi-Sig Deploy","description":"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.","sidebar":"developers"},"developers/cli/transfers/verify-transfer":{"id":"developers/cli/transfers/verify-transfer","title":"Verifying a Transfer","description":"Prerequisites","sidebar":"developers"},"developers/cli/undelegate":{"id":"developers/cli/undelegate","title":"Undelegating Tokens","description":"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.","sidebar":"developers"},"developers/cli/verifying-contracts":{"id":"developers/cli/verifying-contracts","title":"Verifying Contracts","description":"This document describes actions needed for smart contract verification using the Casper CLI client.","sidebar":"developers"},"developers/dapps/dapp":{"id":"developers/dapps/dapp","title":"What is a dApp?","description":"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.","sidebar":"developers"},"developers/dapps/index":{"id":"developers/dapps/index","title":"Overview of Casper dApps","description":"The following topics are essential for developers building decentralized applications on a Casper network.","sidebar":"developers"},"developers/dapps/monitor-and-consume-events":{"id":"developers/dapps/monitor-and-consume-events","title":"Monitoring Events with the Casper Sidecar","description":"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.","sidebar":"developers"},"developers/dapps/nctl-test":{"id":"developers/dapps/nctl-test","title":"Local Network Testing","description":"NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.","sidebar":"developers"},"developers/dapps/prerequisites":{"id":"developers/dapps/prerequisites","title":"Prerequisites","description":"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:","sidebar":"developers"},"developers/dapps/sdk/client-library-usage":{"id":"developers/dapps/sdk/client-library-usage","title":"SDK Client Library Usage","description":"Installing the SDKs","sidebar":"developers"},"developers/dapps/sdk/csharp-sdk":{"id":"developers/dapps/sdk/csharp-sdk","title":".NET SDK","description":"The C# .NET SDK allows developers to interact with a Casper network using C#.","sidebar":"developers"},"developers/dapps/sdk/go-sdk":{"id":"developers/dapps/sdk/go-sdk","title":"Go SDK","description":"Usage Examples","sidebar":"developers"},"developers/dapps/sdk/index":{"id":"developers/dapps/sdk/index","title":"SDK Client Libraries","description":"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.","sidebar":"developers"},"developers/dapps/sdk/python-sdk":{"id":"developers/dapps/sdk/python-sdk","title":"Python SDK","description":"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.","sidebar":"developers"},"developers/dapps/sdk/script-sdk":{"id":"developers/dapps/sdk/script-sdk","title":"JavaScript/TypeScript SDK","description":"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.","sidebar":"developers"},"developers/dapps/setup-nctl":{"id":"developers/dapps/setup-nctl","title":"Local Network Setup","description":"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.","sidebar":"developers"},"developers/dapps/signing-a-transaction":{"id":"developers/dapps/signing-a-transaction","title":"Signing Transactions","description":"When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account\'s cryptographic key-pair. This key-pair is a combination of the account\'s secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.","sidebar":"developers"},"developers/dapps/speculative-exec":{"id":"developers/dapps/speculative-exec","title":"Estimating Gas Costs with Speculative Execution","description":"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.","sidebar":"developers"},"developers/dapps/technology-stack":{"id":"developers/dapps/technology-stack","title":"dApp Technology Stack","description":"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.","sidebar":"developers"},"developers/dapps/template-frontend":{"id":"developers/dapps/template-frontend","title":"Front-end in React","description":"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.","sidebar":"developers"},"developers/dapps/uref-security":{"id":"developers/dapps/uref-security","title":"URef Access Rights","description":"Understanding Access Rights","sidebar":"developers"},"developers/essential-crates":{"id":"developers/essential-crates","title":"Essential Rust Crates","description":"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.","sidebar":"developers"},"developers/index":{"id":"developers/index","title":"Overview","description":"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.","sidebar":"developers"},"developers/json-rpc/errors":{"id":"developers/json-rpc/errors","title":"Casper JSON-RPC Error Codes","description":"The following document expands on custom error codes provided by casper-json-rpc crate."},"developers/json-rpc/guidance":{"id":"developers/json-rpc/guidance","title":"Guidance for JSON-RPC SDK Compliance","description":"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.","sidebar":"developers"},"developers/json-rpc/index":{"id":"developers/json-rpc/index","title":"Overview","description":"Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.","sidebar":"developers"},"developers/json-rpc/json-rpc-informational":{"id":"developers/json-rpc/json-rpc-informational","title":"Informational JSON-RPC Methods","description":"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.","sidebar":"developers"},"developers/json-rpc/json-rpc-pos":{"id":"developers/json-rpc/json-rpc-pos","title":"Proof-of-Stake JSON-RPC Methods","description":"The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.","sidebar":"developers"},"developers/json-rpc/json-rpc-transactional":{"id":"developers/json-rpc/json-rpc-transactional","title":"Transactional JSON-RPC Methods","description":"---","sidebar":"developers"},"developers/json-rpc/minimal-compliance":{"id":"developers/json-rpc/minimal-compliance","title":"Required Methods for Minimal Compliance","description":"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.","sidebar":"developers"},"developers/json-rpc/types_chain":{"id":"developers/json-rpc/types_chain","title":"Types","description":"The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.","sidebar":"developers"},"developers/json-rpc/types_cl":{"id":"developers/json-rpc/types_cl","title":"CLType","description":"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.","sidebar":"developers"},"developers/prerequisites":{"id":"developers/prerequisites","title":"Development Prerequisites","description":"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.","sidebar":"developers"},"developers/writing-onchain-code/assembly-script":{"id":"developers/writing-onchain-code/assembly-script","title":"Getting Started with AssemblyScript","description":"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.","sidebar":"developers"},"developers/writing-onchain-code/best-practices":{"id":"developers/writing-onchain-code/best-practices","title":"Best Practices for Casper Smart Contract Authors","description":"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.","sidebar":"developers"},"developers/writing-onchain-code/calling-contracts":{"id":"developers/writing-onchain-code/calling-contracts","title":"Calling Contracts","description":"Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.","sidebar":"developers"},"developers/writing-onchain-code/contract-hash-vs-package-hash":{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","title":"Contract Hash vs. Package Hash","description":"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.","sidebar":"developers"},"developers/writing-onchain-code/contract-vs-session":{"id":"developers/writing-onchain-code/contract-vs-session","title":"Contracts and Session Code","description":"What is Session Code?","sidebar":"developers"},"developers/writing-onchain-code/emitting-contract-events":{"id":"developers/writing-onchain-code/emitting-contract-events","title":"Contract-Level Events","description":"Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.","sidebar":"developers"},"developers/writing-onchain-code/factory-pattern":{"id":"developers/writing-onchain-code/factory-pattern","title":"Factory Contracts","description":"This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.","sidebar":"developers"},"developers/writing-onchain-code/getting-started":{"id":"developers/writing-onchain-code/getting-started","title":"Getting Started with Rust","description":"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.","sidebar":"developers"},"developers/writing-onchain-code/index":{"id":"developers/writing-onchain-code/index","title":"Introduction","description":"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.","sidebar":"developers"},"developers/writing-onchain-code/simple-contract":{"id":"developers/writing-onchain-code/simple-contract","title":"Writing a Basic Smart Contract in Rust","description":"What is a Smart Contract?","sidebar":"developers"},"developers/writing-onchain-code/testing-contracts":{"id":"developers/writing-onchain-code/testing-contracts","title":"Testing Smart Contracts","description":"Introduction","sidebar":"developers"},"developers/writing-onchain-code/testing-session-code":{"id":"developers/writing-onchain-code/testing-session-code","title":"Testing Session Code","description":"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.","sidebar":"developers"},"developers/writing-onchain-code/upgrading-contracts":{"id":"developers/writing-onchain-code/upgrading-contracts","title":"Upgrading and Maintaining Smart Contracts","description":"Our smart contract packaging tools enable you to:","sidebar":"developers"},"developers/writing-onchain-code/writing-session-code":{"id":"developers/writing-onchain-code/writing-session-code","title":"Writing Session Code","description":"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.","sidebar":"developers"},"disclaimer":{"id":"disclaimer","title":"Disclaimer","description":"disclaimer}"},"operators/becoming-a-validator/bonding":{"id":"operators/becoming-a-validator/bonding","title":"Bonding","description":"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.","sidebar":"operators"},"operators/becoming-a-validator/change-bid-public-key":{"id":"operators/becoming-a-validator/change-bid-public-key","title":"Change bid public key","description":"The public key associated with a given validator bid can be changed through the auction contract\'s changebidpublic_key entry point."},"operators/becoming-a-validator/inactive-vs-faulty":{"id":"operators/becoming-a-validator/inactive-vs-faulty","title":"Inactive and Faulty Nodes","description":"This page describes the differences between a validator node being considered inactive or faulty.","sidebar":"operators"},"operators/becoming-a-validator/index":{"id":"operators/becoming-a-validator/index","title":"Becoming a Validator","description":"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.","sidebar":"operators"},"operators/becoming-a-validator/recovering":{"id":"operators/becoming-a-validator/recovering","title":"Recovery","description":"This topic discusses the steps a validator needs to take if it is evicted from the validator set:","sidebar":"operators"},"operators/becoming-a-validator/unbonding":{"id":"operators/becoming-a-validator/unbonding","title":"Unbonding","description":"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.","sidebar":"operators"},"operators/index":{"id":"operators/index","title":"Overview","description":"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.","sidebar":"operators"},"operators/maintenance/archiving-and-restoring":{"id":"operators/maintenance/archiving-and-restoring","title":"Archive and Restore a DB","description":"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.","sidebar":"operators"},"operators/maintenance/index":{"id":"operators/maintenance/index","title":"Node Maintenance","description":"This section covers maintenance actions such as moving a node to a different location and restoring a database.","sidebar":"operators"},"operators/maintenance/moving-node":{"id":"operators/maintenance/moving-node","title":"Move a Node","description":"This guide is for active validators who want to move their node to another machine.","sidebar":"operators"},"operators/setup-network/chain-spec":{"id":"operators/setup-network/chain-spec","title":"The Chainspec","description":"the-chain-specification}","sidebar":"operators"},"operators/setup-network/create-private":{"id":"operators/setup-network/create-private","title":"Private Network Setup","description":"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.","sidebar":"operators"},"operators/setup-network/genesis":{"id":"operators/setup-network/genesis","title":"Genesis","description":"the-genesis-block}","sidebar":"operators"},"operators/setup-network/index":{"id":"operators/setup-network/index","title":"Setting up Private Networks","description":"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.","sidebar":"operators"},"operators/setup-network/staging-files-for-new-network":{"id":"operators/setup-network/staging-files-for-new-network","title":"Staging Files","description":"Staging files is not needed for already established running networks.","sidebar":"operators"},"operators/setup/basic-node-configuration":{"id":"operators/setup/basic-node-configuration","title":"Configuration","description":"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.","sidebar":"operators"},"operators/setup/casper-sidecar":{"id":"operators/setup/casper-sidecar","title":"Sidecar Setup","description":"The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node\'s event stream, query stored events, and query the node\'s JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:","sidebar":"operators"},"operators/setup/fast-sync":{"id":"operators/setup/fast-sync","title":"Fast Sync","description":"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 transaction 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.","sidebar":"operators"},"operators/setup/hardware":{"id":"operators/setup/hardware","title":"Hardware","description":"System Requirements","sidebar":"operators"},"operators/setup/index":{"id":"operators/setup/index","title":"Setting up a Node","description":"The prerequisite for becoming a validator is to set up a node and join a network as described here.","sidebar":"operators"},"operators/setup/install-node":{"id":"operators/setup/install-node","title":"Installation","description":"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.","sidebar":"operators"},"operators/setup/joining":{"id":"operators/setup/joining","title":"Join a Network","description":"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.","sidebar":"operators"},"operators/setup/node-endpoints":{"id":"operators/setup/node-endpoints","title":"Endpoints","description":"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.","sidebar":"operators"},"operators/setup/node-events":{"id":"operators/setup/node-events","title":"Node Events","description":"Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the eventstreamserver.address in the node\'s config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.","sidebar":"operators"},"operators/setup/non-root-user":{"id":"operators/setup/non-root-user","title":"Non-Root Users","description":"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.","sidebar":"operators"},"operators/setup/open-files":{"id":"operators/setup/open-files","title":"Open Files Limit","description":"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.","sidebar":"operators"},"operators/setup/upgrade":{"id":"operators/setup/upgrade","title":"Upgrades","description":"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.","sidebar":"operators"},"resources/advanced/cross-contract":{"id":"resources/advanced/cross-contract","title":"Cross-Contract Communication","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/advanced/index":{"id":"resources/advanced/index","title":"Advanced Tutorials","description":"| Title | Description |","sidebar":"tutorials"},"resources/advanced/list-auth-keys-tutorial":{"id":"resources/advanced/list-auth-keys-tutorial","title":"Authorization Keys","description":"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.","sidebar":"tutorials"},"resources/advanced/list-cspr":{"id":"resources/advanced/list-cspr","title":"Listing CSPR","description":"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."},"resources/advanced/multi-sig/index":{"id":"resources/advanced/multi-sig/index","title":"Introduction","description":"In this tutorial, you will use Casper\'s permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.","sidebar":"tutorials"},"resources/advanced/multi-sig/multi-sig-workflow":{"id":"resources/advanced/multi-sig/multi-sig-workflow","title":"Multi-Sig Workflow","description":"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.","sidebar":"tutorials"},"resources/advanced/multi-sig/other-scenarios":{"id":"resources/advanced/multi-sig/other-scenarios","title":"Additional Examples","description":"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.","sidebar":"tutorials"},"resources/advanced/return-values-tutorial":{"id":"resources/advanced/return-values-tutorial","title":"Runtime Return Values","description":"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.","sidebar":"tutorials"},"resources/advanced/storage-workflow":{"id":"resources/advanced/storage-workflow","title":"Storage Workflow","description":"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.","sidebar":"tutorials"},"resources/advanced/transfer-token-to-contract":{"id":"resources/advanced/transfer-token-to-contract","title":"Token Transfers","description":"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.","sidebar":"tutorials"},"resources/advanced/two-party-multi-sig":{"id":"resources/advanced/two-party-multi-sig","title":"Two-Party Multi-Sig","description":"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.","sidebar":"tutorials"},"resources/beginner/aws-node":{"id":"resources/beginner/aws-node","title":"AWS Casper Nodes","description":"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.","sidebar":"tutorials"},"resources/beginner/cep18":{"id":"resources/beginner/cep18","title":"Fungible Tokens","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/beginner/counter-testnet/commands":{"id":"resources/beginner/counter-testnet/commands","title":"Casper-Client Commands","description":"State Root Hash","sidebar":"tutorials"},"resources/beginner/counter-testnet/index":{"id":"resources/beginner/counter-testnet/index","title":"Introduction","description":"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter-testnet/overview":{"id":"resources/beginner/counter-testnet/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter-testnet/walkthrough":{"id":"resources/beginner/counter-testnet/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/counter/commands":{"id":"resources/beginner/counter/commands","title":"Casper-Client Commands","description":"Faucet Account Information","sidebar":"tutorials"},"resources/beginner/counter/index":{"id":"resources/beginner/counter/index","title":"Introduction","description":"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter/overview":{"id":"resources/beginner/counter/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter/walkthrough":{"id":"resources/beginner/counter/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/getting-started-tutorial":{"id":"resources/beginner/getting-started-tutorial","title":"Getting Started","description":"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.","sidebar":"tutorials"},"resources/beginner/index":{"id":"resources/beginner/index","title":"Overview","description":"Beginner Tutorials","sidebar":"tutorials"},"resources/beginner/querying-network":{"id":"resources/beginner/querying-network","title":"Querying a Node","description":"The Casper node supports queries for users and developers to obtain information stored on the blockchain.","sidebar":"tutorials"},"resources/beginner/upgrade-contract":{"id":"resources/beginner/upgrade-contract","title":"Contract Upgrades","description":"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.","sidebar":"tutorials"},"resources/build-on-casper":{"id":"resources/build-on-casper","title":"Build on Casper","description":"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.","sidebar":"resources"},"resources/casper-open-source-software":{"id":"resources/casper-open-source-software","title":"Open-Source Software","description":"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.","sidebar":"resources"},"resources/changelog":{"id":"resources/changelog","title":"Documentation Updates by Protocol Release","description":"Condor (2.0)"},"resources/index":{"id":"resources/index","title":"Resources Overview","description":"Building on Casper","sidebar":"resources"},"resources/moving-to-casper":{"id":"resources/moving-to-casper","title":"Move to Casper","description":"moving-to-casper}","sidebar":"resources"},"resources/quick-start":{"id":"resources/quick-start","title":"Quickstart","description":"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.","sidebar":"tutorials"},"resources/tokens/cep18/full-tutorial":{"id":"resources/tokens/cep18/full-tutorial","title":"Fungible Token Workflow","description":"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.","sidebar":"resources"},"resources/tokens/cep18/query":{"id":"resources/tokens/cep18/query","title":"CEP-18 Contract Details","description":"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:","sidebar":"resources"},"resources/tokens/cep18/quickstart-guide":{"id":"resources/tokens/cep18/quickstart-guide","title":"On-chain Installation","description":"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.","sidebar":"resources"},"resources/tokens/cep18/tests":{"id":"resources/tokens/cep18/tests","title":"Testing Guide","description":"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.","sidebar":"resources"},"resources/tokens/cep18/transfer":{"id":"resources/tokens/cep18/transfer","title":"CEP-18 Transfers","description":"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.","sidebar":"resources"},"resources/tokens/cep78/introduction":{"id":"resources/tokens/cep78/introduction","title":"Introduction","description":"Usage","sidebar":"resources"},"resources/tokens/cep78/js-tutorial":{"id":"resources/tokens/cep78/js-tutorial","title":"CEP-78 JavaScript Client","description":"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.","sidebar":"resources"},"resources/tokens/cep78/modalities":{"id":"resources/tokens/cep78/modalities","title":"CEP-78 Modalities","description":"The enhanced NFT implementation supports various \'modalities\' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.","sidebar":"resources"},"resources/tokens/cep78/reverse-lookup":{"id":"resources/tokens/cep78/reverse-lookup","title":"Ownership Lookup","description":"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client":{"id":"resources/tokens/cep78/using-casper-client","title":"On-chain Installation","description":"This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper\'s Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.","sidebar":"resources"},"resources/tokens/index":{"id":"resources/tokens/index","title":"Casper Token Standards","description":"CEP-18 Casper Fungible Token Standard","sidebar":"resources"},"users/block-explorer":{"id":"users/block-explorer","title":"Block Explorers","description":"The Casper blockchain is available as the Mainnet and Testnet.","sidebar":"users"},"users/csprlive/delegate-ui":{"id":"users/csprlive/delegate-ui","title":"Delegate Tokens","description":"Introduction","sidebar":"users"},"users/csprlive/index":{"id":"users/csprlive/index","title":"Using CSPR.live","description":"| Topic | Description |","sidebar":"users"},"users/csprlive/testnet-faucet":{"id":"users/csprlive/testnet-faucet","title":"Testnet Funding","description":"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.","sidebar":"users"},"users/csprlive/token-transfer":{"id":"users/csprlive/token-transfer","title":"Transfer Tokens","description":"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user\'s purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.","sidebar":"users"},"users/csprlive/undelegate-ui":{"id":"users/csprlive/undelegate-ui","title":"Undelegate Tokens","description":"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.","sidebar":"users"},"users/delegating":{"id":"users/delegating","title":"Delegating Tokens","description":"A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.","sidebar":"users"},"users/funding-from-exchanges":{"id":"users/funding-from-exchanges","title":"Funding Mainnet Accounts","description":"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account\'s public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.","sidebar":"users"},"users/index":{"id":"users/index","title":"Users Overview","description":"General Topics","sidebar":"users"},"users/ledger/index":{"id":"users/ledger/index","title":"Casper on Ledger","description":"| Topic | Description |","sidebar":"users"},"users/ledger/ledger-cspr-live":{"id":"users/ledger/ledger-cspr-live","title":"Ledger and CSPR.live","description":"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-live":{"id":"users/ledger/ledger-live","title":"Ledger and Ledger Live","description":"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-setup":{"id":"users/ledger/ledger-setup","title":"Set up Ledger","description":"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.","sidebar":"users"},"users/ledger/staking-ledger":{"id":"users/ledger/staking-ledger","title":"Delegate with Ledger","description":"Ledger Initialization","sidebar":"users"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/ca7245df.76e3b27d.js b/assets/js/ca7245df.76e3b27d.js new file mode 100644 index 000000000..439e8f134 --- /dev/null +++ b/assets/js/ca7245df.76e3b27d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97419],{76032:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var s=t(74848),i=t(28453);const r={},o="Best Practices for Casper Smart Contract Authors",c={id:"developers/writing-onchain-code/best-practices",title:"Best Practices for Casper Smart Contract Authors",description:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/best-practices.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/best-practices",permalink:"/1.5.X/developers/writing-onchain-code/best-practices",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Contract Hash vs. Package Hash",permalink:"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash"},next:{title:"Overview",permalink:"/1.5.X/developers/json-rpc/"}},a={},l=[{value:"Data Efficiency",id:"data-efficiency",level:2},{value:"Costs",id:"costs",level:2},{value:"Tips to reduce WASM size",id:"tips-to-reduce-wasm-size",level:3},{value:"Inlining",id:"inlining",level:2},{value:"Testing",id:"testing",level:2}];function d(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"best-practices-for-casper-smart-contract-authors",children:"Best Practices for Casper Smart Contract Authors"})}),"\n",(0,s.jsx)(n.p,{children:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources."}),"\n",(0,s.jsx)(n.h2,{id:"data-efficiency",children:"Data Efficiency"}),"\n",(0,s.jsxs)(n.p,{children:["When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Deploys"})," will drastically decrease the overall cost."]}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"call"})," function."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example Self-initialization Entry Point"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'\n// This entry point initializes the donation system, setting up the fundraising purse\n// and creating a dictionary to track the account hashes and the number of donations\n// made.\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary(LEDGER).unwrap_or_revert();\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial deployment."}),"\n",(0,s.jsx)(n.h2,{id:"costs",children:"Costs"}),"\n",(0,s.jsxs)(n.p,{children:["Computations occurring on-chain come with associated ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/economics/gas-concepts",children:"gas costs"}),". Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a Deploy is critical."]}),"\n",(0,s.jsxs)(n.p,{children:["Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract#scenario2",children:"reuse of purses"})," should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author."]}),"\n",(0,s.jsx)(n.h3,{id:"tips-to-reduce-wasm-size",children:"Tips to reduce WASM size"}),"\n",(0,s.jsxs)(n.p,{children:["Deploys have a maxim size specified in each network chainspec as ",(0,s.jsx)(n.code,{children:"max_deploy_size"}),". For example, networks running ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/6873c86cc3ab3aae1c8187a7528f94da605e2669/resources/production/chainspec.toml#L101",children:"node version 1.5.1"}),", have the following maximum deploy size in bytes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"max_deploy_size = 1_048_576\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here are a few tips to reduce the size of Wasm included in a deploy:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the smart contract in release mode. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L10",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run\xa0",(0,s.jsx)(n.code,{children:"wasm-strip"}),"\xa0on the compiled code (see\xa0",(0,s.jsx)(n.a,{href:"https://github.com/WebAssembly/wabt",children:"WABT"}),"). You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L12",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"wasm-strip target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Don't enable the\xa0",(0,s.jsx)(n.code,{children:"std"}),"\xa0feature when linking to the\xa0",(0,s.jsx)(n.code,{children:"casper-contract"}),"\xa0or\xa0",(0,s.jsx)(n.code,{children:"casper-types"}),"\xa0crates using the ",(0,s.jsx)(n.code,{children:"#![no_std]"})," attribute, which tells the program not to import the standard libraries. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/cep18/src/main.rs#L1",children:"here"})," and further details ",(0,s.jsx)(n.a,{href:"https://docs.rust-embedded.org/book/intro/no-std.html",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with ",(0,s.jsx)(n.code,{children:"codegen-units"})," set to 1 by adding ",(0,s.jsx)(n.code,{children:"codegen-units = 1"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release])"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L14",children:"here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with link-time optimizations enabled by adding ",(0,s.jsx)(n.code,{children:"lto = true"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release]"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L15",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"inlining",children:"Inlining"}),"\n",(0,s.jsxs)(n.p,{children:["As often as practicable, developers should inline functions by including the body of the function within their code rather than making ",(0,s.jsx)(n.code,{children:"call"})," or ",(0,s.jsx)(n.code,{children:"call_indirect"})," to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances."]}),"\n",(0,s.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(n.p,{children:["Testing all Deploys prior to committing them to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending Deploys to ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Information on these processes can be found at the following locations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter/",children:"A Counter On An NCTL Network"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter-testnet",children:"A Counter On The Testnet"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ca7245df.9c1a68a4.js b/assets/js/ca7245df.9c1a68a4.js deleted file mode 100644 index 841bda182..000000000 --- a/assets/js/ca7245df.9c1a68a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7419],{76032:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>l});var s=t(74848),i=t(28453);const r={},o="Best Practices for Casper Smart Contract Authors",c={id:"developers/writing-onchain-code/best-practices",title:"Best Practices for Casper Smart Contract Authors",description:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/best-practices.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/best-practices",permalink:"/developers/writing-onchain-code/best-practices",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Contract Hash vs. Package Hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash"},next:{title:"Overview",permalink:"/developers/json-rpc/"}},a={},l=[{value:"Data Efficiency",id:"data-efficiency",level:2},{value:"Costs",id:"costs",level:2},{value:"Tips to reduce WASM size",id:"tips-to-reduce-wasm-size",level:3},{value:"Inlining",id:"inlining",level:2},{value:"Testing",id:"testing",level:2}];function d(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"best-practices-for-casper-smart-contract-authors",children:"Best Practices for Casper Smart Contract Authors"})}),"\n",(0,s.jsx)(n.p,{children:"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources."}),"\n",(0,s.jsx)(n.h2,{id:"data-efficiency",children:"Data Efficiency"}),"\n",(0,s.jsxs)(n.p,{children:["When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"Deploys"})," will drastically decrease the overall cost."]}),"\n",(0,s.jsxs)(n.p,{children:["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 ",(0,s.jsx)(n.code,{children:"call"})," function."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example Self-initialization Entry Point"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'\n// This entry point initializes the donation system, setting up the fundraising purse\n// and creating a dictionary to track the account hashes and the number of donations\n// made.\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary(LEDGER).unwrap_or_revert();\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial deployment."}),"\n",(0,s.jsx)(n.h2,{id:"costs",children:"Costs"}),"\n",(0,s.jsxs)(n.p,{children:["Computations occurring on-chain come with associated ",(0,s.jsx)(n.a,{href:"/concepts/economics/gas-concepts",children:"gas costs"}),". Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a Deploy is critical."]}),"\n",(0,s.jsxs)(n.p,{children:["Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract#scenario2",children:"reuse of purses"})," should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author."]}),"\n",(0,s.jsx)(n.h3,{id:"tips-to-reduce-wasm-size",children:"Tips to reduce WASM size"}),"\n",(0,s.jsxs)(n.p,{children:["Deploys have a maxim size specified in each network chainspec as ",(0,s.jsx)(n.code,{children:"max_deploy_size"}),". For example, networks running ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/6873c86cc3ab3aae1c8187a7528f94da605e2669/resources/production/chainspec.toml#L101",children:"node version 1.5.1"}),", have the following maximum deploy size in bytes:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"max_deploy_size = 1_048_576\n"})}),"\n",(0,s.jsx)(n.p,{children:"Here are a few tips to reduce the size of Wasm included in a deploy:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the smart contract in release mode. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L10",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"cargo build --release --target wasm32-unknown-unknown\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Run\xa0",(0,s.jsx)(n.code,{children:"wasm-strip"}),"\xa0on the compiled code (see\xa0",(0,s.jsx)(n.a,{href:"https://github.com/WebAssembly/wabt",children:"WABT"}),"). You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Makefile#L12",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"wasm-strip target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Don't enable the\xa0",(0,s.jsx)(n.code,{children:"std"}),"\xa0feature when linking to the\xa0",(0,s.jsx)(n.code,{children:"casper-contract"}),"\xa0or\xa0",(0,s.jsx)(n.code,{children:"casper-types"}),"\xa0crates using the ",(0,s.jsx)(n.code,{children:"#![no_std]"})," attribute, which tells the program not to import the standard libraries. You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/cep18/src/main.rs#L1",children:"here"})," and further details ",(0,s.jsx)(n.a,{href:"https://docs.rust-embedded.org/book/intro/no-std.html",children:"here"})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:"#![no_std]\n"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with ",(0,s.jsx)(n.code,{children:"codegen-units"})," set to 1 by adding ",(0,s.jsx)(n.code,{children:"codegen-units = 1"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release])"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L14",children:"here"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Build the contract with link-time optimizations enabled by adding ",(0,s.jsx)(n.code,{children:"lto = true"}),"\xa0to the Cargo.toml under\xa0",(0,s.jsx)(n.code,{children:"[profile.release]"}),". You will find an example ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18/blob/2c702e23497d2c9493374466e7af0c002006cbda/Cargo.toml#L15",children:"here"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"inlining",children:"Inlining"}),"\n",(0,s.jsxs)(n.p,{children:["As often as practicable, developers should inline functions by including the body of the function within their code rather than making ",(0,s.jsx)(n.code,{children:"call"})," or ",(0,s.jsx)(n.code,{children:"call_indirect"})," to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances."]}),"\n",(0,s.jsx)(n.h2,{id:"testing",children:"Testing"}),"\n",(0,s.jsxs)(n.p,{children:["Testing all Deploys prior to committing them to ",(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending Deploys to ",(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Information on these processes can be found at the following locations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-session-code",children:"Unit Testing Session Code"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/developers/dapps/nctl-test",children:"Testing Smart Contracts with NCTL"})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Additionally, the following two tutorials outline sending an example contract using both NCTL and Testnet:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter/",children:"A Counter On An NCTL Network"})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"/counter-testnet",children:"A Counter On The Testnet"})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},r=s.createContext(i);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ca962d2e.fb46012c.js b/assets/js/ca962d2e.fb46012c.js new file mode 100644 index 000000000..43eaa45c4 --- /dev/null +++ b/assets/js/ca962d2e.fb46012c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37639],{88779:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>l});var r=n(74848),o=n(28453);const s={title:"Introduction",slug:"/counter"},i="A Counter on an NCTL Network",a={id:"resources/beginner/counter/index",title:"Introduction",description:"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter/index.md",sourceDirName:"resources/beginner/counter",slug:"/counter",permalink:"/2.0.0/counter",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Introduction",slug:"/counter"},sidebar:"tutorials",previous:{title:"Getting Started",permalink:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial"},next:{title:"Overview",permalink:"/2.0.0/resources/beginner/counter/overview"}},c={},l=[{value:"Prerequisites",id:"prerequisites",level:2}];function u(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"a-counter-on-an-nctl-network",children:"A Counter on an NCTL Network"})}),"\n",(0,r.jsxs)(t.p,{children:["This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a ",(0,r.jsx)(t.a,{href:"/2.0.0/counter-testnet",children:"similar tutorial"}),". Once you are familiar with this process, the next step would be to write more practical smart contracts."]}),"\n",(0,r.jsx)(t.p,{children:"Here is how the tutorial is structured:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter/overview",children:"Tutorial Overview"})," - Introduction to the process and what will be covered"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter/commands",children:"Casper-Client Commands"})," - A summary of all relevant commands and respective arguments"]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter/walkthrough",children:"Tutorial Walkthrough"})," - Step-by-step tutorial instructions"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["You have completed the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started tutorial"})," to set up your development environment, including tools like ",(0,r.jsx)(t.em,{children:"cmake"})," (version 3.1.4+), ",(0,r.jsx)(t.em,{children:"cargo"}),", and ",(0,r.jsx)(t.em,{children:"Rust"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["You have completed the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"NCTL tutorial"}),", which introduces you to the CLI tool to set up and control local Casper networks for development."]}),"\n",(0,r.jsxs)(t.li,{children:["You have installed the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper client"})," to send transactions to the chain."]}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(u,{...e})}):u(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>a});var r=n(96540);const o={},s=r.createContext(o);function i(e){const t=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cacd3f19.fb6d7d41.js b/assets/js/cacd3f19.fb6d7d41.js new file mode 100644 index 000000000..dbefab4e0 --- /dev/null +++ b/assets/js/cacd3f19.fb6d7d41.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18663],{88685:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var t=s(74848),a=s(28453);const r={},o=".NET SDK",c={id:"developers/dapps/sdk/csharp-sdk",title:".NET SDK",description:"The C# .NET SDK allows developers to interact with a Casper network using C#.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/csharp-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/csharp-sdk",permalink:"/2.0.0/developers/dapps/sdk/csharp-sdk",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"JavaScript/TypeScript SDK",permalink:"/2.0.0/developers/dapps/sdk/script-sdk"},next:{title:"Go SDK",permalink:"/2.0.0/developers/dapps/sdk/go-sdk"}},i={},d=[{value:"Documentation",id:"documentation",level:2},{value:"Get started",id:"get-started",level:2}];function p(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"net-sdk",children:".NET SDK"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"C# .NET SDK"})," allows developers to interact with a Casper network using C#."]}),"\n",(0,t.jsx)(n.h2,{id:"documentation",children:"Documentation"}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find the SDK documentation, examples, and tutorials."]}),"\n",(0,t.jsx)(n.h2,{id:"get-started",children:"Get started"}),"\n",(0,t.jsx)(n.p,{children:"This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing."}),"\n",(0,t.jsx)(n.p,{children:"Open a terminal window and create a new console app:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet new console -o GetAccountBalance\ncd GetAccountBalance\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The Casper.Network.SDK for .NET is published on ",(0,t.jsx)(n.a,{href:"https://www.nuget.org/packages/Casper.Network.SDK",children:"nuget.org"})," as a NuGet package."]}),"\n",(0,t.jsxs)(n.p,{children:["To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the ",(0,t.jsx)(n.code,{children:"dotnet"})," CLI tool."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Package Manager (Windows)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"Install-Package Casper.Network.SDK\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"dotnet CLI Tool (Windows, Mac, and Linux)"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet add package Casper.Network.SDK\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Now, replace the default code in ",(0,t.jsx)(n.code,{children:"Program.cs"})," with this main program:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{children:'using System;\nusing System.Threading.Tasks;\nusing Casper.Network.SDK;\nusing Casper.Network.SDK.JsonRpc;\nusing Casper.Network.SDK.Types;\n\nnamespace Casper.NET.SDK.Examples\n{\n public class GetAccountBalance\n {\n public static async Task Main(string[] args)\n {\n string nodeAddress = "http://testnet-node.make.services:7777";\n\n var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";\n var publicKey = PublicKey.FromHexString(hex);\n\n try\n {\n var casperSdk = new NetCasperClient(nodeAddress);\n\n // Get the balance using the account public key\n //\n var rpcResponse = await casperSdk.GetAccountBalance(publicKey);\n Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);\n }\n catch (RpcClientException e)\n {\n Console.WriteLine("ERROR:\\n" + e.RpcError.Message);\n }\n catch (Exception e)\n {\n Console.WriteLine(e);\n }\n }\n }\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:"Finally, run the example with:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"dotnet run\n"})}),"\n",(0,t.jsx)(n.p,{children:"The program will print the account's main purse balance retrieved from the testnet."}),"\n",(0,t.jsxs)(n.p,{children:["Visit ",(0,t.jsx)(n.a,{href:"https://make-software.github.io/casper-net-sdk/",children:"https://make-software.github.io/casper-net-sdk/"})," to find other examples, tutorials, and complete documentation for this SDK."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const a={},r=t.createContext(a);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cad9fd36.a362a2cd.js b/assets/js/cad9fd36.a362a2cd.js new file mode 100644 index 000000000..53b437cc1 --- /dev/null +++ b/assets/js/cad9fd36.a362a2cd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27207],{45024:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var s=n(74848),a=n(28453);const c={title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},r="Installing and Interacting with a CEP-18 Contract",o={id:"resources/tokens/cep18/quickstart-guide",title:"On-chain Installation",description:"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/quickstart-guide.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/quickstart-guide",permalink:"/2.0.0/resources/tokens/cep18/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"On-chain Installation",slug:"/resources/tokens/cep18/quickstart-guide"},sidebar:"resources",previous:{title:"Fungible Token Workflow",permalink:"/2.0.0/resources/tokens/cep18/full-tutorial"},next:{title:"CEP-18 Contract Details",permalink:"/2.0.0/resources/tokens/cep18/query"}},i={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Install the Main Fungible Token Contract",id:"install-the-main-fungible-token-contract",level:2},{value:"Install the <code>cep18_test_contract</code> Contract Package",id:"install-the-cep18_test_contract-contract-package",level:2},{value:"Next Steps",id:"next-steps",level:3}];function d(e){const t={a:"a",blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"installing-and-interacting-with-a-cep-18-contract",children:"Installing and Interacting with a CEP-18 Contract"})}),"\n",(0,s.jsxs)(t.p,{children:["This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a ",(0,s.jsx)(t.a,{href:"https://cspr.live",children:"Casper network"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"https://eips.ethereum.org/EIPS/eip-20#specification",children:"Ethereum Request for Comment (ERC-20)"})," standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded."]}),"\n",(0,s.jsx)(t.p,{children:"To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions."}),"\n",(0,s.jsxs)(t.p,{children:["For greater detail into the creation and mechanics of the Casper fungible token contract, see the full ",(0,s.jsx)(t.a,{href:"/2.0.0/resources/tokens/cep18/full-tutorial",children:"Casper Fungible Token Tutorial"}),"."]}),"\n",(0,s.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsx)(t.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Set up your machine as per the ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,s.jsx)(t.li,{children:"Use the [Casper command-line client]"}),"\n",(0,s.jsxs)(t.li,{children:["Get a valid ",(0,s.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:(0,s.jsx)(t.code,{children:"node-address"})})]}),"\n",(0,s.jsxs)(t.li,{children:["Know how to deploy a ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(t.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,s.jsx)(t.h1,{id:"setup",children:"Setup"}),"\n",(0,s.jsxs)(t.p,{children:["Clone the ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep18",children:"fungible token (CEP-18) contract repository"})," and run the ",(0,s.jsx)(t.code,{children:"make build-contract"})," command. This will create the ",(0,s.jsx)(t.code,{children:"cep18.wasm"})," and the ",(0,s.jsx)(t.code,{children:"cep18_test_contract.wasm"}),". The token Wasm is the main contract. We will use the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Wasm to query the balances and allowances of the fungible token balances throughout this workflow."]}),"\n",(0,s.jsx)(t.h2,{id:"install-the-main-fungible-token-contract",children:"Install the Main Fungible Token Contract"}),"\n",(0,s.jsx)(t.p,{children:"The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Name"})," - The name of your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Symbol"})," - The symbol used to refer to your CEP-18 token"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Total_supply"})," - The total supply of the CEP-18 token to be minted"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Decimals"})," - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a ",(0,s.jsx)(t.code,{children:"decimals"})," setting of 3 would be 1,000.000 tokens)"]}),"\n"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18.wasm \\\n--session-arg \"name:string='CEP18'\" \\\n--session-arg \"symbol:string='gris'\" \\\n--session-arg \"total_supply:u256='100'\" \\\n--session-arg \"decimals:u8='1'\" \\\n--payment-amount 150000000000\n"})}),"\n",(0,s.jsxs)(t.h2,{id:"install-the-cep18_test_contract-contract-package",children:["Install the ",(0,s.jsx)(t.code,{children:"cep18_test_contract"})," Contract Package"]}),"\n",(0,s.jsx)(t.p,{children:"The following command will install the CEP-18 helper contract that allows you to check balances and access approval features."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-path ~/casper/demo/cep18_test_contract.wasm \\\n--payment-amount 50000000000\n"})}),"\n",(0,s.jsx)(t.p,{children:"At this point, the account that installed both the main contract and the helper contract will look like this."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'{\n\t"src": {\n\t"Account": {\n\t"_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t"namedKeys": [\n\t\t{\n\t\t"name": "cep18_test_contract",\n\t\t"key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"\n\t\t},\n\t\t{\n\t\t"name": "cep18_token_contract",\n\t\t"key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"\n\t\t},\n\t],\n\t"mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",\n\t"associatedKeys": [\n\t\t{\n\t\t"accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",\n\t\t"weight": 1\n\t\t}\n\t],\n\t"actionThresholds": {\n\t\t"deployment": 1,\n\t\t"keyManagement": 1\n\t\t}\n\t\t}\n\t}\n}\n'})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:(0,s.jsx)(t.em,{children:"Note:"})})}),"\n",(0,s.jsxs)(t.blockquote,{children:["\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_token_contract"})," is the main contract, and is a stored contract, record its hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"cep18_test_call"})," is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,s.jsx)(t.p,{children:"In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals."}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,s.jsx)(t.li,{children:(0,s.jsx)(t.a,{href:"/2.0.0/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var s=n(96540);const a={},c=s.createContext(a);function r(e){const t=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cb447cb9.2ecfdbd1.js b/assets/js/cb447cb9.2ecfdbd1.js new file mode 100644 index 000000000..f8f885da9 --- /dev/null +++ b/assets/js/cb447cb9.2ecfdbd1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60505],{59184:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var t=s(74848),r=s(28453);const a={},i="Transferring Tokens using a Multi-Sig Deploy",d={id:"developers/cli/transfers/multisig-deploy-transfer",title:"Transferring Tokens using a Multi-Sig Deploy",description:"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.",source:"@site/versioned_docs/version-2.0.0/developers/cli/transfers/multisig-deploy-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/multisig-deploy-transfer",permalink:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Direct Token Transfer",permalink:"/2.0.0/developers/cli/transfers/direct-token-transfer"},next:{title:"Verifying a Transfer",permalink:"/2.0.0/developers/cli/transfers/verify-transfer"}},c={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Token Transfer Workflow",id:"token-transfer-workflow",level:2},{value:"Creating the transfer",id:"creating-the-transfer",level:3},{value:"Signing the transfer",id:"signing-the-transfer",level:3},{value:"Sending the deploy",id:"sending-the-transaction",level:3},{value:"Verifying the transfer",id:"verifying-the-transfer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",mdxadmonitiontitle:"mdxadmonitiontitle",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-using-a-multi-sig-deploy",children:"Transferring Tokens using a Multi-Sig Deploy"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"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 ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command and send it to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"You must ensure the following prerequisites are met."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the prerequisites listed ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"here"}),", including:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A funded ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"Account"})," on Testnet or Mainnet"]}),"\n",(0,t.jsxs)(n.li,{children:["A valid ",(0,t.jsx)(n.em,{children:"node address"})," from the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet peers"})," or ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet peers"})]}),"\n",(0,t.jsxs)(n.li,{children:["The Casper ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"command-line client"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up the source account for multi-signature deploys, as outlined in the ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the path of the source account's ",(0,t.jsx)(n.em,{children:"secret key"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the target account's ",(0,t.jsx)(n.em,{children:"public key"})," in hex format"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"token-transfer-workflow",children:"Token Transfer Workflow"}),"\n",(0,t.jsx)(n.p,{children:"The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"make-transfer"})," command creates and signs a transfer, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command adds additional signatures for a multi-signature transfer"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"send-deploy"})," command sends the deploy containing the transfer to the network"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Deployment flow",src:s(72012).A+"",width:"802",height:"274"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-the-transfer",children:"Creating the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This section explains the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file) to a target account. To use this example on the Mainnet, the ",(0,t.jsx)(n.em,{children:"chain-name"})," would be ",(0,t.jsx)(n.code,{children:"casper"})," instead of ",(0,t.jsx)(n.code,{children:"casper-test"}),". Note that we are saving the output of the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command in a ",(0,t.jsx)(n.code,{children:"transfer.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key [PATH]/secret_key.pem \\\n--chain-name casper-test \\\n--target-account [PUBLIC_KEY_HEX] \\\n--transfer-id [ID] \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following table explains the parameters used in the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"amount"}),(0,t.jsx)(n.td,{children:"The number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file for the source account"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"chain-name"}),(0,t.jsxs)(n.td,{children:["The name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain ",(0,t.jsxs)(n.ul,{children:[(0,t.jsxs)(n.li,{children:["For Testnet use ",(0,t.jsx)(n.strong,{children:"casper-test"})]}),(0,t.jsxs)(n.li,{children:["For Mainnet use ",(0,t.jsx)(n.strong,{children:"casper"})]})]})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"target-account"}),(0,t.jsx)(n.td,{children:"Hex-encoded public key of the target account from which the main purse will be used"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"transfer-id"}),(0,t.jsx)(n.td,{children:"A user-defined identifier permanently associated with the transfer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"payment-amount"}),(0,t.jsxs)(n.td,{children:["The payment for the transfer in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In the output, you will see a section named ",(0,t.jsx)(n.strong,{children:"approvals"}),". This is where a signature from the source account is added to the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \\\n--chain-name casper-test \\\n--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \\\n--transfer-id 1 \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output of the make-transfer command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"signing-the-transfer",children:"Signing the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a ",(0,t.jsx)(n.code,{children:"transfer2.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key [PATH]/another_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which needs to be signed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file used to sign the deploy"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"output"}),(0,t.jsx)(n.td,{children:"The path of the output file used to save the deploy with multiple signatures"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, you can observe that there is an ",(0,t.jsx)(n.strong,{children:"approvals"})," section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output saved in the transfer2.deploy file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n },\n {\n "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",\n "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sending-the-transaction",children:"Sending the deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The next step is to send the deploy for processing on the network. As described in the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})," section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node ",(0,t.jsx)(n.code,{children:"https://rpc.testnet.casperlabs.io/"})," from the Testnet."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy \\\n--input transfer2.deploy \\\n--node-address https://rpc.testnet.casperlabs.io/ \n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which is used as the input"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"node-address"}),(0,t.jsx)(n.td,{children:"The Hostname or IP and port of the node"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Make a note of the ",(0,t.jsx)(n.em,{children:"deploy_hash"})," from the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command output to verify the status of the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Successful output of the send-deploy command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -818883417884028030,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If you encounter an account authorization error, you ",(0,t.jsx)(n.strong,{children:"must set up the source account to allow multi-signature deploys"})," using session code. The ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow is an example of how to accomplish this."]})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example of an account authorization error"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "code": -32008,\n "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"verifying-the-transfer",children:"Verifying the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transfer status, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.mdxadmonitiontitle,{}),(0,t.jsxs)(n.p,{children:["You can also verify if the transfer was successful by checking your account balance using a ",(0,t.jsx)(n.a,{href:"/2.0.0/users/block-explorer",children:"block explorer"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},72012:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-flow-a20851cf502515fa17e5f53f90bf3982.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cb63487a.169a1a3c.js b/assets/js/cb63487a.169a1a3c.js deleted file mode 100644 index 70bd0c13e..000000000 --- a/assets/js/cb63487a.169a1a3c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9081],{68736:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var s=a(74848),t=a(28453);const r={title:"Querying Global State"},c="Querying Global State",d={id:"developers/cli/querying-global-state",title:"Querying Global State",description:"This page explains how to query global state to find account, contract, and package details.",source:"@site/docs/developers/cli/querying-global-state.md",sourceDirName:"developers/cli",slug:"/developers/cli/querying-global-state",permalink:"/next/developers/cli/querying-global-state",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Querying Global State"},sidebar:"developers",previous:{title:"Verifying Contracts",permalink:"/next/developers/cli/verifying-contracts"},next:{title:"Calling Contracts",permalink:"/next/developers/cli/calling-contracts"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Getting the State Root Hash",id:"get-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying a Contract",id:"querying-a-contract",level:2},{value:"Querying a Package",id:"querying-a-package",level:2},{value:"Querying a Named Key",id:"querying-a-named-key",level:2},{value:"Query a value using the contract address hash and its named key",id:"query-a-value-using-the-contract-address-hash-and-its-named-key",level:3},{value:"Query a value using the account hash and its named key",id:"query-a-value-using-the-account-hash-and-its-named-key",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"querying-global-state",children:"Querying Global State"})}),"\n",(0,s.jsx)(n.p,{children:"This page explains how to query global state to find account, contract, and package details."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You have an account and have ",(0,s.jsx)(n.a,{href:"/next/developers/cli/installing-contracts",children:"installed a contract"})," on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"get-state-root-hash",children:"Getting the State Root Hash"}),"\n",(0,s.jsx)(n.p,{children:"The first step in querying global state is obtaining the state root hash, which acts as an identifier for the current state of the network. It is like a Git commit ID for commit history, providing a snapshot of the blockchain state at a specific time."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"After sending transactions to the network, it's necessary to fetch the new state root hash to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,s.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,s.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4225403855447288375,\n "result": {\n "api_version": "2.0.0",\n "state_root_hash": "6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,s.jsx)(n.p,{children:"To find your account details, start by querying global state using the account hash. The response will contain the entity account identifier, needed to query more details about the account. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 2591514718461273084,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "Key",\n "bytes": "11016a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "parsed": "entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n },\n "merkle_proof": "[2566 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, see more account details using the ",(0,s.jsx)(n.code,{children:"get-entity"})," command and the entity identifier or the account hash. Both commands will produce the same output. You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample requests:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:"OR"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.p,{children:'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.'}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4470312592511523509,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n },\n "package_hash": "package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-21dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "counter",\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n {\n "name": "counter_package_name",\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n {\n "name": "version",\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n }\n ],\n "entry_points": []\n }\n },\n "merkle_proof": "[3010 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{})]}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsx)(n.p,{children:"If you don't know your account hash, run this command:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-contract",children:"Querying a Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"query-global-state"}),' command. The contract is stored under the account\'s named keys, with the key named "counter" and identifier ',(0,s.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),". The output will contain the contract's ",(0,s.jsx)(n.code,{children:"package_hash"}),", ",(0,s.jsx)(n.code,{children:"main_purse"}),", ",(0,s.jsx)(n.code,{children:"associated_keys"}),", and ",(0,s.jsx)(n.code,{children:"action_thresholds"}),", but will not contain further details such as the contract's named keys and entry points. You will need to run the ",(0,s.jsx)(n.code,{children:"get-entity"})," command instead for those details."]}),"\n",(0,s.jsxs)(n.p,{children:["For the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the contract address hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -750547909804067196,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Next, query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"get-entity"})," command, which will provide more details such as the contract's ",(0,s.jsx)(n.code,{children:"entry_points"})," and ",(0,s.jsx)(n.code,{children:"named_keys"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entity identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -530362264865678930,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "count",\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n },\n {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-package",children:"Querying a Package"}),"\n",(0,s.jsx)(n.p,{children:"You can query information about a package, given its package hash. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the package identifier."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PACKAGE_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.p,{children:["The response would contain the ",(0,s.jsx)(n.code,{children:"addressable_entity_hash"}),", the ",(0,s.jsx)(n.code,{children:"lock_status"})," for the ",(0,s.jsx)(n.code,{children:"Package"}),", and the current ",(0,s.jsx)(n.code,{children:"entity_version"}),"."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "jsonrpc": "2.0",\n "id": -8280509649720542989,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n },\n "merkle_proof": "[2934 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-named-key",children:"Querying a Named Key"}),"\n",(0,s.jsxs)(n.p,{children:["You can dive into the data stored in global state using the optional query path argument ",(0,s.jsx)(n.code,{children:"-q"})," or ",(0,s.jsx)(n.code,{children:"--query-path"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, deploy-info hash,era-info number, bid, withdraw or dictionary address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"query path"}),", entered in this instance as ",(0,s.jsx)(n.code,{children:"q"}),", which is an optional query path argument that allows you to drill into the specifics of a query with respect to the key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [HASH_STRING] \\\n-q "PATH_FROM_KEY"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-contract-address-hash-and-its-named-key",children:"Query a value using the contract address hash and its named key"}),"\n",(0,s.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command and the ",(0,s.jsx)(n.code,{children:"-q"})," option."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH] \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68" \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -672620332620630019,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[7272 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-account-hash-and-its-named-key",children:"Query a value using the account hash and its named key"}),"\n",(0,s.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n --key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463 \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -8997536139716357387,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[14486 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Learn ",(0,s.jsx)(n.a,{href:"/next/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>d});var s=a(96540);const t={},r=s.createContext(t);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cb63487a.7cab35d9.js b/assets/js/cb63487a.7cab35d9.js new file mode 100644 index 000000000..a756a97c1 --- /dev/null +++ b/assets/js/cb63487a.7cab35d9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59081],{68736:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var s=a(74848),t=a(28453);const r={title:"Querying Global State"},c="Querying Global State",d={id:"developers/cli/querying-global-state",title:"Querying Global State",description:"This page explains how to query global state to find account, contract, and package details.",source:"@site/docs/developers/cli/querying-global-state.md",sourceDirName:"developers/cli",slug:"/developers/cli/querying-global-state",permalink:"/developers/cli/querying-global-state",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Querying Global State"},sidebar:"developers",previous:{title:"Verifying Contracts",permalink:"/developers/cli/verifying-contracts"},next:{title:"Calling Contracts",permalink:"/developers/cli/calling-contracts"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Getting the State Root Hash",id:"get-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying a Contract",id:"querying-a-contract",level:2},{value:"Querying a Package",id:"querying-a-package",level:2},{value:"Querying a Named Key",id:"querying-a-named-key",level:2},{value:"Query a value using the contract address hash and its named key",id:"query-a-value-using-the-contract-address-hash-and-its-named-key",level:3},{value:"Query a value using the account hash and its named key",id:"query-a-value-using-the-account-hash-and-its-named-key",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"querying-global-state",children:"Querying Global State"})}),"\n",(0,s.jsx)(n.p,{children:"This page explains how to query global state to find account, contract, and package details."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You have an account and have ",(0,s.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installed a contract"})," on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"get-state-root-hash",children:"Getting the State Root Hash"}),"\n",(0,s.jsx)(n.p,{children:"The first step in querying global state is obtaining the state root hash, which acts as an identifier for the current state of the network. It is like a Git commit ID for commit history, providing a snapshot of the blockchain state at a specific time."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"After sending transactions to the network, it's necessary to fetch the new state root hash to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,s.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,s.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4225403855447288375,\n "result": {\n "api_version": "2.0.0",\n "state_root_hash": "6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,s.jsx)(n.p,{children:"To find your account details, start by querying global state using the account hash. The response will contain the entity account identifier, needed to query more details about the account. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 2591514718461273084,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "Key",\n "bytes": "11016a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "parsed": "entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n },\n "merkle_proof": "[2566 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, see more account details using the ",(0,s.jsx)(n.code,{children:"get-entity"})," command and the entity identifier or the account hash. Both commands will produce the same output. You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample requests:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:"OR"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.p,{children:'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.'}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4470312592511523509,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n },\n "package_hash": "package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-21dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "counter",\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n {\n "name": "counter_package_name",\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n {\n "name": "version",\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n }\n ],\n "entry_points": []\n }\n },\n "merkle_proof": "[3010 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{})]}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsx)(n.p,{children:"If you don't know your account hash, run this command:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-contract",children:"Querying a Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"query-global-state"}),' command. The contract is stored under the account\'s named keys, with the key named "counter" and identifier ',(0,s.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),". The output will contain the contract's ",(0,s.jsx)(n.code,{children:"package_hash"}),", ",(0,s.jsx)(n.code,{children:"main_purse"}),", ",(0,s.jsx)(n.code,{children:"associated_keys"}),", and ",(0,s.jsx)(n.code,{children:"action_thresholds"}),", but will not contain further details such as the contract's named keys and entry points. You will need to run the ",(0,s.jsx)(n.code,{children:"get-entity"})," command instead for those details."]}),"\n",(0,s.jsxs)(n.p,{children:["For the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the contract address hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -750547909804067196,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Next, query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"get-entity"})," command, which will provide more details such as the contract's ",(0,s.jsx)(n.code,{children:"entry_points"})," and ",(0,s.jsx)(n.code,{children:"named_keys"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entity identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -530362264865678930,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "count",\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n },\n {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-package",children:"Querying a Package"}),"\n",(0,s.jsx)(n.p,{children:"You can query information about a package, given its package hash. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the package identifier."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PACKAGE_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.p,{children:["The response would contain the ",(0,s.jsx)(n.code,{children:"addressable_entity_hash"}),", the ",(0,s.jsx)(n.code,{children:"lock_status"})," for the ",(0,s.jsx)(n.code,{children:"Package"}),", and the current ",(0,s.jsx)(n.code,{children:"entity_version"}),"."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "jsonrpc": "2.0",\n "id": -8280509649720542989,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n },\n "merkle_proof": "[2934 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-named-key",children:"Querying a Named Key"}),"\n",(0,s.jsxs)(n.p,{children:["You can dive into the data stored in global state using the optional query path argument ",(0,s.jsx)(n.code,{children:"-q"})," or ",(0,s.jsx)(n.code,{children:"--query-path"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, deploy-info hash,era-info number, bid, withdraw or dictionary address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"query path"}),", entered in this instance as ",(0,s.jsx)(n.code,{children:"q"}),", which is an optional query path argument that allows you to drill into the specifics of a query with respect to the key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [HASH_STRING] \\\n-q "PATH_FROM_KEY"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-contract-address-hash-and-its-named-key",children:"Query a value using the contract address hash and its named key"}),"\n",(0,s.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command and the ",(0,s.jsx)(n.code,{children:"-q"})," option."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH] \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68" \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -672620332620630019,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[7272 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-account-hash-and-its-named-key",children:"Query a value using the account hash and its named key"}),"\n",(0,s.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n --key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463 \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -8997536139716357387,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[14486 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Learn ",(0,s.jsx)(n.a,{href:"/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>d});var s=a(96540);const t={},r=s.createContext(t);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbe09f13.99a63f42.js b/assets/js/cbe09f13.99a63f42.js deleted file mode 100644 index 485c59f7f..000000000 --- a/assets/js/cbe09f13.99a63f42.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4894],{14516:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var c=t(74848),a=t(28453);const s={title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},r="Exploring the CEP-18 Contracts",o={id:"resources/tokens/cep18/query",title:"CEP-18 Contract Details",description:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/query.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/query",permalink:"/resources/tokens/cep18/query",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/resources/tokens/cep18/quickstart-guide"},next:{title:"CEP-18 Transfers",permalink:"/resources/tokens/cep18/transfer"}},i={},d=[{value:"Querying the Contract Package",id:"querying-the-contract-package",level:2},{value:"Querying the Utility Contract",id:"querying-the-utility-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"exploring-the-cep-18-contracts",children:"Exploring the CEP-18 Contracts"})}),"\n",(0,c.jsx)(n.p,{children:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The Casper fungible token contract"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["The CEP-18 utility contract, which should appear in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the account that sent the Deploy as ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-contract-package",children:"Querying the Contract Package"}),"\n",(0,c.jsxs)(n.p,{children:["We will need the contract package's ",(0,c.jsx)(n.code,{children:"contract_hash"})," to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", under the name given during the installation process."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This will return the ",(0,c.jsx)(n.code,{children:"Contract Package"})," object:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note - In the ",(0,c.jsx)(n.code,{children:"contract_hash"})," field, the hash value represents the stored contract which we will invoke later."]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-utility-contract",children:"Querying the Utility Contract"}),"\n",(0,c.jsxs)(n.p,{children:["In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.jsx)(n.code,{children:"result"}),". You can find this URef in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the utility contract."]}),"\n",(0,c.jsxs)(n.p,{children:["First, you will need to query the ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," hash found within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Which should return information similar to the following:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsxs)(n.p,{children:["You will need to take the ",(0,c.jsx)(n.code,{children:"contract_hash"})," value and replace ",(0,c.jsx)(n.code,{children:"contract"})," with ",(0,c.jsx)(n.code,{children:"hash"})," to run another `query-global-state:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Which will return the full ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," information. The following snippet is condensed to show only the ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", but you should also see the ",(0,c.jsx)(n.code,{children:"entry_points"})," when you run the command. You should see the URef ",(0,c.jsx)(n.code,{children:"result"}),", which will be used to view the results of any checks run through the utility contract."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbe09f13.b56f8a87.js b/assets/js/cbe09f13.b56f8a87.js new file mode 100644 index 000000000..3886395f3 --- /dev/null +++ b/assets/js/cbe09f13.b56f8a87.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[64894],{14516:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var c=t(74848),a=t(28453);const s={title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},r="Exploring the CEP-18 Contracts",o={id:"resources/tokens/cep18/query",title:"CEP-18 Contract Details",description:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/query.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/query",permalink:"/1.5.X/resources/tokens/cep18/query",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/1.5.X/resources/tokens/cep18/quickstart-guide"},next:{title:"CEP-18 Transfers",permalink:"/1.5.X/resources/tokens/cep18/transfer"}},i={},d=[{value:"Querying the Contract Package",id:"querying-the-contract-package",level:2},{value:"Querying the Utility Contract",id:"querying-the-utility-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"exploring-the-cep-18-contracts",children:"Exploring the CEP-18 Contracts"})}),"\n",(0,c.jsx)(n.p,{children:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The Casper fungible token contract"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["The CEP-18 utility contract, which should appear in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the account that sent the Deploy as ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-contract-package",children:"Querying the Contract Package"}),"\n",(0,c.jsxs)(n.p,{children:["We will need the contract package's ",(0,c.jsx)(n.code,{children:"contract_hash"})," to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", under the name given during the installation process."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This will return the ",(0,c.jsx)(n.code,{children:"Contract Package"})," object:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note - In the ",(0,c.jsx)(n.code,{children:"contract_hash"})," field, the hash value represents the stored contract which we will invoke later."]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-utility-contract",children:"Querying the Utility Contract"}),"\n",(0,c.jsxs)(n.p,{children:["In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.jsx)(n.code,{children:"result"}),". You can find this URef in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the utility contract."]}),"\n",(0,c.jsxs)(n.p,{children:["First, you will need to query the ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," hash found within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Which should return information similar to the following:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsxs)(n.p,{children:["You will need to take the ",(0,c.jsx)(n.code,{children:"contract_hash"})," value and replace ",(0,c.jsx)(n.code,{children:"contract"})," with ",(0,c.jsx)(n.code,{children:"hash"})," to run another `query-global-state:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Which will return the full ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," information. The following snippet is condensed to show only the ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", but you should also see the ",(0,c.jsx)(n.code,{children:"entry_points"})," when you run the command. You should see the URef ",(0,c.jsx)(n.code,{children:"result"}),", which will be used to view the results of any checks run through the utility contract."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbe8101d.1206d77a.js b/assets/js/cbe8101d.1206d77a.js deleted file mode 100644 index b33069cfa..000000000 --- a/assets/js/cbe8101d.1206d77a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8723],{18901:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>l});var t=s(74848),i=s(28453);const r={title:"Join a Network"},o="Joining a Running Network",d={id:"operators/setup/joining",title:"Join a Network",description:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.",source:"@site/docs/operators/setup/joining.md",sourceDirName:"operators/setup",slug:"/operators/setup/joining",permalink:"/next/operators/setup/joining",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Join a Network"},sidebar:"operators",previous:{title:"Upgrades",permalink:"/next/operators/setup/upgrade"},next:{title:"Non-Root Users",permalink:"/next/operators/setup/non-root-user"}},a={},l=[{value:"Step 1: Provisioning Hardware",id:"step-1-provision-hardware",level:2},{value:"Step 2: Setting Up the Node",id:"step-2-set-up-the-node",level:2},{value:"Step 3: Building the Required Contracts",id:"step-3-build-contracts",level:2},{value:"Step 4: Creating and Fund Keys for Bonding",id:"step-4-create--fund-keys-for-bonding",level:2},{value:"Step 5: Updating the Trusted Hash",id:"step-5-update-the-trusted-hash",level:2},{value:"Step 6: Starting the Node",id:"step-6-start-the-node",level:2},{value:"Step 7: Confirming the Node is Synchronized",id:"step-7-confirm-the-node-is-synchronized",level:2},{value:"Step 8: Sending the Bonding Request",id:"step-7-send-the-bonding-request",level:2}];function c(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"joining-a-running-network",children:"Joining a Running Network"})}),"\n",(0,t.jsx)(n.p,{children:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network."}),"\n",(0,t.jsx)(n.h2,{id:"step-1-provision-hardware",children:"Step 1: Provisioning Hardware"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/hardware",children:"Hardware Specifications"})," section and provision your node hardware."]}),"\n",(0,t.jsx)(n.h2,{id:"step-2-set-up-the-node",children:"Step 2: Setting Up the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the instructions on the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/install-node",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"step-3-build-contracts",children:"Step 3: Building the Required Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the casper-node repository."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Install these prerequisites, which are also listed ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node#pre-requisites-for-building",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started#installing-rust",children:"Rust"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"CMake"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pkg-config"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install pkg-config"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"openssl"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install openssl"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"libssl-dev"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install libssl-dev"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Rust casper-client"})," and fund the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#create-fund-keys",children:"keys"})," you will use for bonding."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Use the following commands to build the contracts in release mode. Make sure you have ",(0,t.jsx)(n.a,{href:"/next/developers/writing-onchain-code/getting-started#installing-rust",children:"installed Rust"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-client-contracts\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will build all the necessary Wasm contracts for operating as a validator:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"activate_bid.wasm"})," - Reactivates an ejected validator"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_bid.wasm"})," - Enables bonding for validator stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegate.wasm"})," - Delegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"undelegate.wasm"})," - Undelegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"withdraw_bid.wasm"})," - Enables unbonding for validator stake"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-4-create--fund-keys-for-bonding",children:"Step 4: Creating and Fund Keys for Bonding"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," instructions if you have not generated and funded your validator keys."]}),"\n",(0,t.jsx)(n.h2,{id:"step-5-update-the-trusted-hash",children:"Step 5: Updating the Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["The node's ",(0,t.jsx)(n.code,{children:"config.toml"})," needs to be updated with a recent trusted hash."]}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Trusted Hash for Synchronizing"})," instructions if you have not set up a trusted hash during node installation."]}),"\n",(0,t.jsx)(n.h2,{id:"step-6-start-the-node",children:"Step 6: Starting the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Start the node with the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above Debian package installs a casper-node service for systemd."}),"\n",(0,t.jsxs)(n.p,{children:["For more information, visit ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/wiki#node-operators",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-confirm-the-node-is-synchronized",children:"Step 7: Confirming the Node is Synchronized"}),"\n",(0,t.jsxs)(n.p,{children:["While the node is synchronizing, the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint is available. You will be able to compare this to another node's status endpoint ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," to determine if you are caught up. You will not be able to perform any ",(0,t.jsx)(n.code,{children:"casper-client"})," calls to your ",(0,t.jsx)(n.code,{children:"7777"})," RPC port until your node is fully caught up."]}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, notice the ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," that you can use to determine if your node has completed synchronizing."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsxs)(n.summary,{children:["Sample output of the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.3",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",\n "peers": [\n {\n "node_id": "tls:0097..b253",\n "address": "18.163.249.168:35000"\n },\n ...\n ...\n ...\n {\n "node_id": "tls:ff95..c014",\n "address": "93.186.201.14:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",\n "timestamp": "2022-01-04T15:33:08.224Z",\n "era_id": 3240,\n "height": 430162,\n "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",\n "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"\n },\n "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",\n "round_length": null,\n "next_upgrade": null,\n "build_version": "1.4.3-a44bed1fd-casper-mainnet",\n "uptime": "25days 1h 48m 22s 47ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-send-the-bonding-request",children:"Step 8: Sending the Bonding Request"}),"\n",(0,t.jsxs)(n.p,{children:["You can submit a ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/bonding",children:"bonding request"})," to change your synchronized node to a validating node."]}),"\n",(0,t.jsx)(n.p,{children:"The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cbe8101d.7596f688.js b/assets/js/cbe8101d.7596f688.js new file mode 100644 index 000000000..26bbd6919 --- /dev/null +++ b/assets/js/cbe8101d.7596f688.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18723],{18901:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>l});var t=s(74848),i=s(28453);const r={title:"Join a Network"},o="Joining a Running Network",d={id:"operators/setup/joining",title:"Join a Network",description:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.",source:"@site/docs/operators/setup/joining.md",sourceDirName:"operators/setup",slug:"/operators/setup/joining",permalink:"/operators/setup/joining",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Join a Network"},sidebar:"operators",previous:{title:"Upgrades",permalink:"/operators/setup/upgrade"},next:{title:"Non-Root Users",permalink:"/operators/setup/non-root-user"}},a={},l=[{value:"Step 1: Provisioning Hardware",id:"step-1-provision-hardware",level:2},{value:"Step 2: Setting Up the Node",id:"step-2-set-up-the-node",level:2},{value:"Step 3: Building the Required Contracts",id:"step-3-build-contracts",level:2},{value:"Step 4: Creating and Fund Keys for Bonding",id:"step-4-create--fund-keys-for-bonding",level:2},{value:"Step 5: Updating the Trusted Hash",id:"step-5-update-the-trusted-hash",level:2},{value:"Step 6: Starting the Node",id:"step-6-start-the-node",level:2},{value:"Step 7: Confirming the Node is Synchronized",id:"step-7-confirm-the-node-is-synchronized",level:2},{value:"Step 8: Sending the Bonding Request",id:"step-7-send-the-bonding-request",level:2}];function c(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"joining-a-running-network",children:"Joining a Running Network"})}),"\n",(0,t.jsx)(n.p,{children:"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network."}),"\n",(0,t.jsx)(n.h2,{id:"step-1-provision-hardware",children:"Step 1: Provisioning Hardware"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/operators/setup/hardware",children:"Hardware Specifications"})," section and provision your node hardware."]}),"\n",(0,t.jsx)(n.h2,{id:"step-2-set-up-the-node",children:"Step 2: Setting Up the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the instructions on the ",(0,t.jsx)(n.a,{href:"/operators/setup/install-node",children:"Node Setup"})," page."]}),"\n",(0,t.jsx)(n.h2,{id:"step-3-build-contracts",children:"Step 3: Building the Required Contracts"}),"\n",(0,t.jsx)(n.p,{children:"Use the commands below to build all the necessary contracts for bonding, retrieving rewards, and unbonding."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Clone the casper-node repository."}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Install these prerequisites, which are also listed ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node#pre-requisites-for-building",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started#installing-rust",children:"Rust"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://cgold.readthedocs.io/en/latest/first-step/installation.html",children:"CMake"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pkg-config"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install pkg-config"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"openssl"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install openssl"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"libssl-dev"})," - On Ubuntu, use ",(0,t.jsx)(n.code,{children:"sudo apt-get install libssl-dev"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Rust casper-client"})," and fund the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"keys"})," you will use for bonding."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Use the following commands to build the contracts in release mode. Make sure you have ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started#installing-rust",children:"installed Rust"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-client-contracts\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will build all the necessary Wasm contracts for operating as a validator:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"activate_bid.wasm"})," - Reactivates an ejected validator"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_bid.wasm"})," - Enables bonding for validator stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegate.wasm"})," - Delegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"undelegate.wasm"})," - Undelegates stake"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"withdraw_bid.wasm"})," - Enables unbonding for validator stake"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-4-create--fund-keys-for-bonding",children:"Step 4: Creating and Fund Keys for Bonding"}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#create-fund-keys",children:"Node Setup"})," instructions if you have not generated and funded your validator keys."]}),"\n",(0,t.jsx)(n.h2,{id:"step-5-update-the-trusted-hash",children:"Step 5: Updating the Trusted Hash"}),"\n",(0,t.jsxs)(n.p,{children:["The node's ",(0,t.jsx)(n.code,{children:"config.toml"})," needs to be updated with a recent trusted hash."]}),"\n",(0,t.jsxs)(n.p,{children:["See the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Trusted Hash for Synchronizing"})," instructions if you have not set up a trusted hash during node installation."]}),"\n",(0,t.jsx)(n.h2,{id:"step-6-start-the-node",children:"Step 6: Starting the Node"}),"\n",(0,t.jsxs)(n.p,{children:["Start the node with the ",(0,t.jsx)(n.code,{children:"casper-node-launcher"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.p,{children:"The above Debian package installs a casper-node service for systemd."}),"\n",(0,t.jsxs)(n.p,{children:["For more information, visit ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/wiki#node-operators",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-confirm-the-node-is-synchronized",children:"Step 7: Confirming the Node is Synchronized"}),"\n",(0,t.jsxs)(n.p,{children:["While the node is synchronizing, the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint is available. You will be able to compare this to another node's status endpoint ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," to determine if you are caught up. You will not be able to perform any ",(0,t.jsx)(n.code,{children:"casper-client"})," calls to your ",(0,t.jsx)(n.code,{children:"7777"})," RPC port until your node is fully caught up."]}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, notice the ",(0,t.jsx)(n.code,{children:"era_id"})," and ",(0,t.jsx)(n.code,{children:"height"})," that you can use to determine if your node has completed synchronizing."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsxs)(n.summary,{children:["Sample output of the ",(0,t.jsx)(n.code,{children:"/status"})," endpoint"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.3",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "e2218b6bdb8137a178f242e9de24ef5db06af7925e8e4c65fa82d41df38f4576",\n "peers": [\n {\n "node_id": "tls:0097..b253",\n "address": "18.163.249.168:35000"\n },\n ...\n ...\n ...\n {\n "node_id": "tls:ff95..c014",\n "address": "93.186.201.14:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "8280de05cb34071f276fbe7c69a07cb325ddd373f685877911238b614bdcc5b1",\n "timestamp": "2022-01-04T15:33:08.224Z",\n "era_id": 3240,\n "height": 430162,\n "state_root_hash": "ec4ff5c4d0a9021984b56e2b6de4a57188101c24e09b765c3fee740353690076",\n "creator": "01ace6578907bfe6eba3a618e863bbe7274284c88e405e2857be80dd094726a223"\n },\n "our_public_signing_key": "01cb41ee07d1827e243588711d45040fe46402bf3901fb550abfd08d1341700270",\n "round_length": null,\n "next_upgrade": null,\n "build_version": "1.4.3-a44bed1fd-casper-mainnet",\n "uptime": "25days 1h 48m 22s 47ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"step-7-send-the-bonding-request",children:"Step 8: Sending the Bonding Request"}),"\n",(0,t.jsxs)(n.p,{children:["You can submit a ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding",children:"bonding request"})," to change your synchronized node to a validating node."]}),"\n",(0,t.jsx)(n.p,{children:"The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cc2e94c0.ab50e15c.js b/assets/js/cc2e94c0.ab50e15c.js deleted file mode 100644 index f5631e108..000000000 --- a/assets/js/cc2e94c0.ab50e15c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5364],{86447:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>a,toc:()=>h});var t=n(74848),i=n(28453);const r={title:"URef Access Rights"},c="URef Access Rights and Security Considerations",a={id:"developers/dapps/uref-security",title:"URef Access Rights",description:"Understanding Access Rights",source:"@site/docs/developers/dapps/uref-security.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/uref-security",permalink:"/next/developers/dapps/uref-security",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"URef Access Rights"},sidebar:"developers",previous:{title:"Front-end in React",permalink:"/next/developers/dapps/template-frontend"},next:{title:"Signing Transactions",permalink:"/next/developers/dapps/signing-a-transaction"}},d={},h=[{value:"Understanding Access Rights",id:"understanding-access-rights",level:2},{value:"AccessRights and Purses",id:"accessrights-and-purses",level:2},{value:"Security Considerations for dApp Developers",id:"security-considerations-for-dapp-developers",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"uref-access-rights-and-security-considerations",children:"URef Access Rights and Security Considerations"})}),"\n",(0,t.jsx)(s.h2,{id:"understanding-access-rights",children:"Understanding Access Rights"}),"\n",(0,t.jsxs)(s.p,{children:["An ",(0,t.jsx)(s.a,{href:"/concepts/design/casper-design/#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(s.strong,{children:"URef"})," is a key type used for storage on a Casper network. They can store any value other than ",(0,t.jsx)(s.code,{children:"Account"})," and exist as a top-level entity. As such, no individual entity may ",(0,t.jsx)(s.em,{children:"own"})," a URef, they can only hold the necessary ",(0,t.jsx)(s.code,{children:"AccessRights"})," to interact with a given URef."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/next/concepts/serialization/primitives#clvalue-uref",children:(0,t.jsx)(s.code,{children:"AccessRights"})})," determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And this is the same URef with ",(0,t.jsx)(s.code,{children:"READ"})," and ",(0,t.jsx)(s.code,{children:"ADD"})," access rights."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The following table outlines all possible ",(0,t.jsx)(s.code,{children:"AccessRights"})," settings:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Access Rights"}),(0,t.jsx)(s.th,{children:"Serialization"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"NONE"})}),(0,t.jsx)(s.td,{children:"0"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ"})}),(0,t.jsx)(s.td,{children:"1"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"WRITE"})}),(0,t.jsx)(s.td,{children:"2"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_WRITE"})}),(0,t.jsx)(s.td,{children:"3"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD"})}),(0,t.jsx)(s.td,{children:"4"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD"})}),(0,t.jsx)(s.td,{children:"5"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"6"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"7"})]})]})]}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["Any access rights granted alongside a passed URef are ",(0,t.jsx)(s.em,{children:(0,t.jsx)(s.strong,{children:"irrevocable"})}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"accessrights-and-purses",children:"AccessRights and Purses"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"Purse"})," is a unique type of ",(0,t.jsx)(s.code,{children:"URef"})," representing a token balance. Each ",(0,t.jsx)(s.code,{children:"Addressable Entity"})," will have an associated URef that represents its main purse. Account and contract entities may have additional purses."]}),"\n",(0,t.jsx)(s.p,{children:"For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Global State"}),(0,t.jsx)(s.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Add"}),(0,t.jsx)(s.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Write"}),(0,t.jsx)(s.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Read"}),(0,t.jsx)(s.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"security-considerations-for-dapp-developers",children:"Security Considerations for dApp Developers"}),"\n",(0,t.jsxs)(s.p,{children:["When developing a ",(0,t.jsx)(s.a,{href:"/developers/dapps/dapp/",children:"dApp"})," that interacts with tokens in any way, it will be necessary to work with various URef ",(0,t.jsx)(s.code,{children:"AccessRights"})," for associated purse URefs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract/",children:"This tutorial outlines our recommendations when transferring tokens to a contract."})}),"\n",(0,t.jsxs)(s.p,{children:["When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate ",(0,t.jsx)(s.code,{children:"AccessRights"}),". The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the ",(0,t.jsx)(s.code,{children:"new_uref"})," should be passed to another entity."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-js",children:"// This example will create a version of the original URef with access rights stripped entirely.\nlet new_uref = uref.with_access_rights(AccessRights::NONE);\n// This example will create a version of the original URef with only READ access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ);\n// This example will create a version of the original URef with only WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::WRITE);\n// This example will create a version of the original URef with both READ and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_WRITE);\n// This example will create a version of the original URef with only ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD);\n// This example will create a version of the original URef with both READ and ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD);\n// This example will create a version of the original URef with both ADD and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);\n// This example will create a version of the original URef with full access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function c(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cc2e94c0.b91d5649.js b/assets/js/cc2e94c0.b91d5649.js new file mode 100644 index 000000000..3d25609f2 --- /dev/null +++ b/assets/js/cc2e94c0.b91d5649.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5364],{86447:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>a,toc:()=>h});var t=n(74848),i=n(28453);const r={title:"URef Access Rights"},c="URef Access Rights and Security Considerations",a={id:"developers/dapps/uref-security",title:"URef Access Rights",description:"Understanding Access Rights",source:"@site/docs/developers/dapps/uref-security.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/uref-security",permalink:"/developers/dapps/uref-security",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"URef Access Rights"},sidebar:"developers",previous:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"},next:{title:"Signing Transactions",permalink:"/developers/dapps/signing-a-transaction"}},d={},h=[{value:"Understanding Access Rights",id:"understanding-access-rights",level:2},{value:"AccessRights and Purses",id:"accessrights-and-purses",level:2},{value:"Security Considerations for dApp Developers",id:"security-considerations-for-dapp-developers",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"uref-access-rights-and-security-considerations",children:"URef Access Rights and Security Considerations"})}),"\n",(0,t.jsx)(s.h2,{id:"understanding-access-rights",children:"Understanding Access Rights"}),"\n",(0,t.jsxs)(s.p,{children:["An ",(0,t.jsx)(s.a,{href:"/concepts/design/casper-design/#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(s.strong,{children:"URef"})," is a key type used for storage on a Casper network. They can store any value other than ",(0,t.jsx)(s.code,{children:"Account"})," and exist as a top-level entity. As such, no individual entity may ",(0,t.jsx)(s.em,{children:"own"})," a URef, they can only hold the necessary ",(0,t.jsx)(s.code,{children:"AccessRights"})," to interact with a given URef."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/concepts/serialization/primitives#clvalue-uref",children:(0,t.jsx)(s.code,{children:"AccessRights"})})," determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And this is the same URef with ",(0,t.jsx)(s.code,{children:"READ"})," and ",(0,t.jsx)(s.code,{children:"ADD"})," access rights."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The following table outlines all possible ",(0,t.jsx)(s.code,{children:"AccessRights"})," settings:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Access Rights"}),(0,t.jsx)(s.th,{children:"Serialization"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"NONE"})}),(0,t.jsx)(s.td,{children:"0"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ"})}),(0,t.jsx)(s.td,{children:"1"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"WRITE"})}),(0,t.jsx)(s.td,{children:"2"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_WRITE"})}),(0,t.jsx)(s.td,{children:"3"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD"})}),(0,t.jsx)(s.td,{children:"4"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD"})}),(0,t.jsx)(s.td,{children:"5"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"6"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"7"})]})]})]}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["Any access rights granted alongside a passed URef are ",(0,t.jsx)(s.em,{children:(0,t.jsx)(s.strong,{children:"irrevocable"})}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"accessrights-and-purses",children:"AccessRights and Purses"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"Purse"})," is a unique type of ",(0,t.jsx)(s.code,{children:"URef"})," representing a token balance. Each ",(0,t.jsx)(s.code,{children:"Addressable Entity"})," will have an associated URef that represents its main purse. Account and contract entities may have additional purses."]}),"\n",(0,t.jsx)(s.p,{children:"For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Global State"}),(0,t.jsx)(s.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Add"}),(0,t.jsx)(s.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Write"}),(0,t.jsx)(s.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Read"}),(0,t.jsx)(s.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"security-considerations-for-dapp-developers",children:"Security Considerations for dApp Developers"}),"\n",(0,t.jsxs)(s.p,{children:["When developing a ",(0,t.jsx)(s.a,{href:"/developers/dapps/dapp/",children:"dApp"})," that interacts with tokens in any way, it will be necessary to work with various URef ",(0,t.jsx)(s.code,{children:"AccessRights"})," for associated purse URefs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract/",children:"This tutorial outlines our recommendations when transferring tokens to a contract."})}),"\n",(0,t.jsxs)(s.p,{children:["When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate ",(0,t.jsx)(s.code,{children:"AccessRights"}),". The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the ",(0,t.jsx)(s.code,{children:"new_uref"})," should be passed to another entity."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-js",children:"// This example will create a version of the original URef with access rights stripped entirely.\nlet new_uref = uref.with_access_rights(AccessRights::NONE);\n// This example will create a version of the original URef with only READ access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ);\n// This example will create a version of the original URef with only WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::WRITE);\n// This example will create a version of the original URef with both READ and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_WRITE);\n// This example will create a version of the original URef with only ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD);\n// This example will create a version of the original URef with both READ and ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD);\n// This example will create a version of the original URef with both ADD and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);\n// This example will create a version of the original URef with full access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function c(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cc84b9e4.a97ce4c6.js b/assets/js/cc84b9e4.a97ce4c6.js new file mode 100644 index 000000000..3a4a910d6 --- /dev/null +++ b/assets/js/cc84b9e4.a97ce4c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[37057],{86623:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var n=r(74848),a=r(28453);const s={title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},o="Reading and Writing to Global State using Rust",i={id:"resources/advanced/storage-workflow",title:"Storage Workflow",description:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/storage-workflow.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/storage-workflow",permalink:"/2.0.0/resources/tutorials/advanced/storage-workflow",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},sidebar:"tutorials",previous:{title:"Token Transfers",permalink:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract"},next:{title:"Cross-Contract Communication",permalink:"/2.0.0/resources/tutorials/advanced/cross-contract"}},c={},d=[{value:"Description of Functions",id:"description-of-functions",level:2},{value:"<code>runtime::put_key</code> / <code>runtime::get_key</code>",id:"runtimeput_key--runtimeget_key",level:3},{value:"<code>storage::write</code> / <code>storage::read</code>",id:"storagewrite--storageread",level:3},{value:"<code>storage:dictionary_put</code> / <code>storage::dictionary_get</code>",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of <code>put_key</code> and <code>storage::write</code>",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of <code>get_key</code> and <code>storage::read</code>",id:"example-of-get_key-and-storageread",level:3},{value:"Example of <code>dictionary_put</code> and <code>dictionary_get</code>",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"reading-and-writing-to-global-state-using-rust",children:"Reading and Writing to Global State using Rust"})}),"\n",(0,n.jsx)(t.p,{children:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."}),"\n",(0,n.jsxs)(t.p,{children:["Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,n.jsx)(t.code,{children:"runtime::put_key"}),", ",(0,n.jsx)(t.code,{children:"storage::write"}),"(alongside ",(0,n.jsx)(t.code,{children:"storage::new_uref"})," as explained below) and ",(0,n.jsx)(t.code,{children:"storage::dictionary_put"}),". These stored values can be read using ",(0,n.jsx)(t.code,{children:"runtime::get_key"}),", ",(0,n.jsx)(t.code,{children:"storage::read"})," and ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"}),", respectively. Each method stores data in a specific way, and it's important to understand the differences."]}),"\n",(0,n.jsx)(t.h2,{id:"description-of-functions",children:"Description of Functions"}),"\n",(0,n.jsxs)(t.h3,{id:"runtimeput_key--runtimeget_key",children:[(0,n.jsx)(t.code,{children:"runtime::put_key"})," / ",(0,n.jsx)(t.code,{children:"runtime::get_key"})]}),"\n",(0,n.jsxs)(t.p,{children:["Both the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:(0,n.jsx)(t.code,{children:"put_key"})})," and ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:(0,n.jsx)(t.code,{children:"get_key"})})," functions refer to Casper ",(0,n.jsx)(t.code,{children:"Key"})," types as outlined in both the ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/key-types",children:"Understanding Hash Types"})," and ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/serialization/types#serialization-standard-state-keys",children:"Serialization Standard"}),". These keys are stored within a URef as a ",(0,n.jsx)(t.code,{children:"Key"})," type."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagewrite--storageread",children:[(0,n.jsx)(t.code,{children:"storage::write"})," / ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:(0,n.jsx)(t.code,{children:"storage::write"})})," writes a given value to a previously established URef (created using ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:(0,n.jsx)(t.code,{children:"storage::new_uref"})}),"). Unlike ",(0,n.jsx)(t.code,{children:"put_key"}),", this value is not one of the ",(0,n.jsx)(t.code,{children:"Key"})," types listed above, but rather any of the potential ",(0,n.jsx)(t.a,{href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype",children:(0,n.jsx)(t.code,{children:"CLType"})}),"s as outlined. ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:(0,n.jsx)(t.code,{children:"storage::read"})})," provides a method to retrieve these values from the associated URef."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagedictionary_put--storagedictionary_get",children:[(0,n.jsx)(t.code,{children:"storage:dictionary_put"})," / ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,n.jsx)(t.code,{children:"NamedKeys"}),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."]}),"\n",(0,n.jsxs)(t.p,{children:["More information on dictionaries can be found on the ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," page."]}),"\n",(0,n.jsx)(t.h2,{id:"example-code",children:"Example Code"}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-put_key-and-storagewrite",children:["Example of ",(0,n.jsx)(t.code,{children:"put_key"})," and ",(0,n.jsx)(t.code,{children:"storage::write"})]}),"\n",(0,n.jsxs)(t.p,{children:["This sample code creates a new contract and stores the contract hash in global state using the ",(0,n.jsx)(t.code,{children:"runtime::put_key"})," function."]}),"\n",(0,n.jsxs)(t.p,{children:["Once the stored value has been initialized, the ",(0,n.jsx)(t.code,{children:"storage::write"})," function overwrites the existing value with ",(0,n.jsx)(t.code,{children:"true"}),". The URef is then stored in the current context as a ",(0,n.jsx)(t.code,{children:"NamedKey"})," titled ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-get_key-and-storageread",children:["Example of ",(0,n.jsx)(t.code,{children:"get_key"})," and ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:["This example compliments the code sample above by retrieving the ",(0,n.jsx)(t.code,{children:"CONTRACT_HASH"})," using the ",(0,n.jsx)(t.code,{children:"get_key"})," function, before comparing a provided runtime argument ",(0,n.jsx)(t.code,{children:"ARG_MY_STORED_VALUE"})," against the previously stored ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"})," using ",(0,n.jsx)(t.code,{children:"storage::read"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-dictionary_put-and-dictionary_get",children:["Example of ",(0,n.jsx)(t.code,{children:"dictionary_put"})," and ",(0,n.jsx)(t.code,{children:"dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["Examples of dictionary usage for storage can be found in the ",(0,n.jsx)(t.em,{children:"Writing Entries into a Dictionary"})," section of ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/dictionaries#writing-entries-into-a-dictionary",children:"Reading and Writing to Dictionaries"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"additional-functions-for-named-keys",children:"Additional Functions for Named Keys"}),"\n",(0,n.jsx)(t.p,{children:"The following functions might also be of interest for working with named keys:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html",children:"list_named_keys"})," - Returns the named keys of the current context"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html",children:"has_key"})," - Returns true if the key exists in the current context\u2019s named keys"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html",children:"remove_key"})," - Removes the requested ",(0,n.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.78b27ccb.js b/assets/js/ccc49370.78b27ccb.js new file mode 100644 index 000000000..29d180785 --- /dev/null +++ b/assets/js/ccc49370.78b27ccb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83249],{82907:(e,t,n)=>{n.d(t,{A:()=>O});n(96540);var a=n(34164),s=n(44096),r=n(74848);function i(e){let{children:t,className:n}=e;return(0,r.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:i}=(0,s.e7)(),{permalink:c,title:d}=n,m=i?"h1":"h2";return(0,r.jsx)(m,{className:(0,a.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=n(21312),m=n(53465),u=n(36266);const h={container:"container_mt6G"};function g(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,m.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,r.jsx)(r.Fragment,{children:n(t)})}function f(e){let{date:t,formattedDate:n}=e;return(0,r.jsx)("time",{dateTime:t,children:n})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function p(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:i,readingTime:l}=n,o=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,a.A)(h.container,"margin-vert--md",t),children:[(0,r.jsx)(f,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(g,{readingTime:l})]})]});var c}var v=n(56913);const j={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function b(e){let{className:t}=e;const{metadata:{authors:n},assets:i}=(0,s.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,r.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",l?j.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,r.jsx)("div",{className:(0,a.A)(!l&&(o?"col col--12":"col col--6"),l?j.imageOnlyAuthorCol:j.authorCol),children:(0,r.jsx)(v.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function A(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(p,{}),(0,r.jsx)(b,{})]})}var N=n(70440),L=n(88509);function y(e){let{children:t,className:n}=e;const{isBlogPostPage:i}=(0,s.e7)();return(0,r.jsx)("div",{id:i?N.LU:void 0,className:(0,a.A)("markdown",n),children:(0,r.jsx)(L.A,{children:t})})}var C=n(17559),T=n(4336),_=n(62053);function H(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function k(e){const{blogPostTitle:t,...n}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,r.jsx)(H,{})})}function w(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,u=n.length>0;if(!(u||m||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("row","margin-top--sm",C.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(_.A,{tags:n})})}),e&&(0,r.jsx)(T.A,{className:(0,a.A)("margin-top--sm",C.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("col",{"col--9":m}),children:(0,r.jsx)(_.A,{tags:n})}),m&&(0,r.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,r.jsx)(k,{blogPostTitle:i,to:e.permalink})})]})}function O(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,a.A)(l,n),children:[(0,r.jsx)(A,{}),(0,r.jsx)(y,{children:t}),(0,r.jsx)(w,{})]})}},73858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(96540);var a=n(34164),s=n(45500),r=n(17559),i=n(44096),l=n(28027),o=n(82907),c=n(21312),d=n(39022),m=n(74848);function u(e){const{nextItem:t,prevItem:n}=e;return(0,m.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,m.jsx)(d.A,{...n,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,m.jsx)(d.A,{...t,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function h(){const{assets:e,metadata:t}=(0,i.e7)(),{title:n,description:a,date:r,tags:l,authors:o,frontMatter:c}=t,{keywords:d}=c,u=e.image??c.image;return(0,m.jsxs)(s.be,{title:n,description:a,keywords:d,image:u,children:[(0,m.jsx)("meta",{property:"og:type",content:"article"}),(0,m.jsx)("meta",{property:"article:published_time",content:r}),o.some((e=>e.url))&&(0,m.jsx)("meta",{property:"article:author",content:o.map((e=>e.url)).filter(Boolean).join(",")}),l.length>0&&(0,m.jsx)("meta",{property:"article:tag",content:l.map((e=>e.label)).join(",")})]})}var g=n(5260);function f(){const e=(0,i.J_)();return(0,m.jsx)(g.A,{children:(0,m.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var x=n(67763),p=n(41689);function v(e){let{sidebar:t,children:n}=e;const{metadata:a,toc:s}=(0,i.e7)(),{nextItem:r,prevItem:c,frontMatter:d}=a,{hide_table_of_contents:h,toc_min_heading_level:g,toc_max_heading_level:f}=d;return(0,m.jsxs)(l.A,{sidebar:t,toc:!h&&s.length>0?(0,m.jsx)(x.A,{toc:s,minHeadingLevel:g,maxHeadingLevel:f}):void 0,children:[(0,m.jsx)(p.A,{metadata:a}),(0,m.jsx)(o.A,{children:n}),(r||c)&&(0,m.jsx)(u,{nextItem:r,prevItem:c})]})}function j(e){const t=e.content;return(0,m.jsx)(i.in,{content:e.content,isBlogPostPage:!0,children:(0,m.jsxs)(s.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogPostPage),children:[(0,m.jsx)(h,{}),(0,m.jsx)(f,{}),(0,m.jsx)(v,{sidebar:e.sidebar,children:(0,m.jsx)(t,{})})]})})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(34164),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,a.A)(t,r.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(o,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var a=n(34164),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Yh,{}),className:(0,a.A)(t,r.G.common.draftBanner),children:(0,l.jsx)(s.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:a}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||a.unlisted)&&(0,l.jsx)(c.A,{}),a.draft&&(0,l.jsx)(o,{})]})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(34164),s=n(65195);const r={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var i=n(74848);const l="table-of-contents__link toc-highlight",o="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,i.jsx)("div",{className:(0,a.A)(r.tableOfContents,"thin-scrollbar",t),children:(0,i.jsx)(s.A,{...n,linkClassName:l,linkActiveClassName:o})})}},65195:(e,t,n)=>{n.d(t,{A:()=>f});var a=n(96540),s=n(6342);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...s}=e;n>=0?t[n].children.push(s):a.push(s)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function o(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>l(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function c(){const e=(0,a.useRef)(0),{navbar:{hideOnScroll:t}}=(0,s.p)();return(0,a.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:s,minHeadingLevel:r,maxHeadingLevel:i}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let s=t;s<=n;s+=1)a.push(`h${s}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:r,maxHeadingLevel:i}),c=o(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(s),e.classList.add(s),t.current=e):e.classList.remove(s)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var m=n(28774),u=n(74848);function h(e){let{toc:t,className:n,linkClassName:a,isChild:s}=e;return t.length?(0,u.jsx)("ul",{className:s?void 0:n,children:t.map((e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:a})]},e.id)))}):null}const g=a.memo(h);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:c,maxHeadingLevel:m,...h}=e;const f=(0,s.p)(),x=c??f.tableOfContents.minHeadingLevel,p=m??f.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return(0,a.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:s})),[t,n,s])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,a.useMemo)((()=>{if(l&&o)return{linkClassName:l,linkActiveClassName:o,minHeadingLevel:x,maxHeadingLevel:p}}),[l,o,x,p])),(0,u.jsx)(g,{toc:v,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>i,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var a=n(21312),s=n(5260),r=n(74848);function i(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,r.jsx)(s.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/ccc49370.be9d46ff.js b/assets/js/ccc49370.be9d46ff.js deleted file mode 100644 index 5951f0891..000000000 --- a/assets/js/ccc49370.be9d46ff.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3249],{82907:(e,t,n)=>{n.d(t,{A:()=>O});n(96540);var a=n(34164),s=n(44096),r=n(74848);function i(e){let{children:t,className:n}=e;return(0,r.jsx)("article",{className:n,children:t})}var l=n(28774);const o={title:"title_f1Hy"};function c(e){let{className:t}=e;const{metadata:n,isBlogPostPage:i}=(0,s.e7)(),{permalink:c,title:d}=n,m=i?"h1":"h2";return(0,r.jsx)(m,{className:(0,a.A)(o.title,t),children:i?d:(0,r.jsx)(l.A,{to:c,children:d})})}var d=n(21312),m=n(53465),u=n(36266);const h={container:"container_mt6G"};function g(e){let{readingTime:t}=e;const n=function(){const{selectMessage:e}=(0,m.W)();return t=>{const n=Math.ceil(t);return e(n,(0,d.T)({id:"theme.blog.post.readingTime.plurals",description:'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',message:"One min read|{readingTime} min read"},{readingTime:n}))}}();return(0,r.jsx)(r.Fragment,{children:n(t)})}function f(e){let{date:t,formattedDate:n}=e;return(0,r.jsx)("time",{dateTime:t,children:n})}function x(){return(0,r.jsx)(r.Fragment,{children:" \xb7 "})}function p(e){let{className:t}=e;const{metadata:n}=(0,s.e7)(),{date:i,readingTime:l}=n,o=(0,u.i)({day:"numeric",month:"long",year:"numeric",timeZone:"UTC"});return(0,r.jsxs)("div",{className:(0,a.A)(h.container,"margin-vert--md",t),children:[(0,r.jsx)(f,{date:i,formattedDate:(c=i,o.format(new Date(c)))}),void 0!==l&&(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(x,{}),(0,r.jsx)(g,{readingTime:l})]})]});var c}var v=n(56913);const j={authorCol:"authorCol_Hf19",imageOnlyAuthorRow:"imageOnlyAuthorRow_pa_O",imageOnlyAuthorCol:"imageOnlyAuthorCol_G86a"};function b(e){let{className:t}=e;const{metadata:{authors:n},assets:i}=(0,s.e7)();if(0===n.length)return null;const l=n.every((e=>{let{name:t}=e;return!t})),o=1===n.length;return(0,r.jsx)("div",{className:(0,a.A)("margin-top--md margin-bottom--sm",l?j.imageOnlyAuthorRow:"row",t),children:n.map(((e,t)=>(0,r.jsx)("div",{className:(0,a.A)(!l&&(o?"col col--12":"col col--6"),l?j.imageOnlyAuthorCol:j.authorCol),children:(0,r.jsx)(v.A,{author:{...e,imageURL:i.authorsImageUrls[t]??e.imageURL}})},t)))})}function A(){return(0,r.jsxs)("header",{children:[(0,r.jsx)(c,{}),(0,r.jsx)(p,{}),(0,r.jsx)(b,{})]})}var N=n(70440),L=n(88509);function y(e){let{children:t,className:n}=e;const{isBlogPostPage:i}=(0,s.e7)();return(0,r.jsx)("div",{id:i?N.LU:void 0,className:(0,a.A)("markdown",n),children:(0,r.jsx)(L.A,{children:t})})}var C=n(17559),T=n(4336),_=n(62053);function H(){return(0,r.jsx)("b",{children:(0,r.jsx)(d.A,{id:"theme.blog.post.readMore",description:"The label used in blog post item excerpts to link to full blog posts",children:"Read more"})})}function k(e){const{blogPostTitle:t,...n}=e;return(0,r.jsx)(l.A,{"aria-label":(0,d.T)({message:"Read more about {title}",id:"theme.blog.post.readMoreLabel",description:"The ARIA label for the link to full blog posts from excerpts"},{title:t}),...n,children:(0,r.jsx)(H,{})})}function w(){const{metadata:e,isBlogPostPage:t}=(0,s.e7)(),{tags:n,title:i,editUrl:l,hasTruncateMarker:o,lastUpdatedBy:c,lastUpdatedAt:d}=e,m=!t&&o,u=n.length>0;if(!(u||m||l))return null;if(t){const e=!!(l||d||c);return(0,r.jsxs)("footer",{className:"docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("row","margin-top--sm",C.G.blog.blogFooterEditMetaRow),children:(0,r.jsx)("div",{className:"col",children:(0,r.jsx)(_.A,{tags:n})})}),e&&(0,r.jsx)(T.A,{className:(0,a.A)("margin-top--sm",C.G.blog.blogFooterEditMetaRow),editUrl:l,lastUpdatedAt:d,lastUpdatedBy:c})]})}return(0,r.jsxs)("footer",{className:"row docusaurus-mt-lg",children:[u&&(0,r.jsx)("div",{className:(0,a.A)("col",{"col--9":m}),children:(0,r.jsx)(_.A,{tags:n})}),m&&(0,r.jsx)("div",{className:(0,a.A)("col text--right",{"col--3":u}),children:(0,r.jsx)(k,{blogPostTitle:i,to:e.permalink})})]})}function O(e){let{children:t,className:n}=e;const l=function(){const{isBlogPostPage:e}=(0,s.e7)();return e?void 0:"margin-bottom--xl"}();return(0,r.jsxs)(i,{className:(0,a.A)(l,n),children:[(0,r.jsx)(A,{}),(0,r.jsx)(y,{children:t}),(0,r.jsx)(w,{})]})}},73858:(e,t,n)=>{n.r(t),n.d(t,{default:()=>j});n(96540);var a=n(34164),s=n(45500),r=n(17559),i=n(44096),l=n(28027),o=n(82907),c=n(21312),d=n(39022),m=n(74848);function u(e){const{nextItem:t,prevItem:n}=e;return(0,m.jsxs)("nav",{className:"pagination-nav docusaurus-mt-lg","aria-label":(0,c.T)({id:"theme.blog.post.paginator.navAriaLabel",message:"Blog post page navigation",description:"The ARIA label for the blog posts pagination"}),children:[n&&(0,m.jsx)(d.A,{...n,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.newerPost",description:"The blog post button label to navigate to the newer/previous post",children:"Newer post"})}),t&&(0,m.jsx)(d.A,{...t,subLabel:(0,m.jsx)(c.A,{id:"theme.blog.post.paginator.olderPost",description:"The blog post button label to navigate to the older/next post",children:"Older post"}),isNext:!0})]})}function h(){const{assets:e,metadata:t}=(0,i.e7)(),{title:n,description:a,date:r,tags:l,authors:o,frontMatter:c}=t,{keywords:d}=c,u=e.image??c.image;return(0,m.jsxs)(s.be,{title:n,description:a,keywords:d,image:u,children:[(0,m.jsx)("meta",{property:"og:type",content:"article"}),(0,m.jsx)("meta",{property:"article:published_time",content:r}),o.some((e=>e.url))&&(0,m.jsx)("meta",{property:"article:author",content:o.map((e=>e.url)).filter(Boolean).join(",")}),l.length>0&&(0,m.jsx)("meta",{property:"article:tag",content:l.map((e=>e.label)).join(",")})]})}var g=n(5260);function f(){const e=(0,i.J_)();return(0,m.jsx)(g.A,{children:(0,m.jsx)("script",{type:"application/ld+json",children:JSON.stringify(e)})})}var x=n(67763),p=n(41689);function v(e){let{sidebar:t,children:n}=e;const{metadata:a,toc:s}=(0,i.e7)(),{nextItem:r,prevItem:c,frontMatter:d}=a,{hide_table_of_contents:h,toc_min_heading_level:g,toc_max_heading_level:f}=d;return(0,m.jsxs)(l.A,{sidebar:t,toc:!h&&s.length>0?(0,m.jsx)(x.A,{toc:s,minHeadingLevel:g,maxHeadingLevel:f}):void 0,children:[(0,m.jsx)(p.A,{metadata:a}),(0,m.jsx)(o.A,{children:n}),(r||c)&&(0,m.jsx)(u,{nextItem:r,prevItem:c})]})}function j(e){const t=e.content;return(0,m.jsx)(i.in,{content:e.content,isBlogPostPage:!0,children:(0,m.jsxs)(s.e3,{className:(0,a.A)(r.G.wrapper.blogPages,r.G.page.blogPostPage),children:[(0,m.jsx)(h,{}),(0,m.jsx)(f,{}),(0,m.jsx)(v,{sidebar:e.sidebar,children:(0,m.jsx)(t,{})})]})})}},32234:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(34164),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Rc,{}),className:(0,a.A)(t,r.G.common.unlistedBanner),children:(0,l.jsx)(s.Uh,{})})}function c(e){return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(s.AE,{}),(0,l.jsx)(o,{...e})]})}},41689:(e,t,n)=>{n.d(t,{A:()=>d});n(96540);var a=n(34164),s=n(44084),r=n(17559),i=n(27293),l=n(74848);function o(e){let{className:t}=e;return(0,l.jsx)(i.A,{type:"caution",title:(0,l.jsx)(s.Yh,{}),className:(0,a.A)(t,r.G.common.draftBanner),children:(0,l.jsx)(s.TT,{})})}var c=n(32234);function d(e){let{metadata:t}=e;const{unlisted:n,frontMatter:a}=t;return(0,l.jsxs)(l.Fragment,{children:[(n||a.unlisted)&&(0,l.jsx)(c.A,{}),a.draft&&(0,l.jsx)(o,{})]})}},67763:(e,t,n)=>{n.d(t,{A:()=>c});n(96540);var a=n(34164),s=n(65195);const r={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"};var i=n(74848);const l="table-of-contents__link toc-highlight",o="table-of-contents__link--active";function c(e){let{className:t,...n}=e;return(0,i.jsx)("div",{className:(0,a.A)(r.tableOfContents,"thin-scrollbar",t),children:(0,i.jsx)(s.A,{...n,linkClassName:l,linkActiveClassName:o})})}},65195:(e,t,n)=>{n.d(t,{A:()=>f});var a=n(96540),s=n(6342);function r(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const a=n.slice(2,e.level);e.parentIndex=Math.max(...a),n[e.level]=t}));const a=[];return t.forEach((e=>{const{parentIndex:n,...s}=e;n>=0?t[n].children.push(s):a.push(s)})),a}function i(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:a}=e;return t.flatMap((e=>{const t=i({toc:e.children,minHeadingLevel:n,maxHeadingLevel:a});return function(e){return e.level>=n&&e.level<=a}(e)?[{...e,children:t}]:t}))}function l(e){const t=e.getBoundingClientRect();return t.top===t.bottom?l(e.parentNode):t}function o(e,t){let{anchorTopOffset:n}=t;const a=e.find((e=>l(e).top>=n));if(a){return function(e){return e.top>0&&e.bottom<window.innerHeight/2}(l(a))?a:e[e.indexOf(a)-1]??null}return e[e.length-1]??null}function c(){const e=(0,a.useRef)(0),{navbar:{hideOnScroll:t}}=(0,s.p)();return(0,a.useEffect)((()=>{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function d(e){const t=(0,a.useRef)(void 0),n=c();(0,a.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:a,linkActiveClassName:s,minHeadingLevel:r,maxHeadingLevel:i}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(a),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const a=[];for(let s=t;s<=n;s+=1)a.push(`h${s}.anchor`);return Array.from(document.querySelectorAll(a.join()))}({minHeadingLevel:r,maxHeadingLevel:i}),c=o(l,{anchorTopOffset:n.current}),d=e.find((e=>c&&c.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(s),e.classList.add(s),t.current=e):e.classList.remove(s)}(e,e===d)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}var m=n(28774),u=n(74848);function h(e){let{toc:t,className:n,linkClassName:a,isChild:s}=e;return t.length?(0,u.jsx)("ul",{className:s?void 0:n,children:t.map((e=>(0,u.jsxs)("li",{children:[(0,u.jsx)(m.A,{to:`#${e.id}`,className:a??void 0,dangerouslySetInnerHTML:{__html:e.value}}),(0,u.jsx)(h,{isChild:!0,toc:e.children,className:n,linkClassName:a})]},e.id)))}):null}const g=a.memo(h);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:l="table-of-contents__link",linkActiveClassName:o,minHeadingLevel:c,maxHeadingLevel:m,...h}=e;const f=(0,s.p)(),x=c??f.tableOfContents.minHeadingLevel,p=m??f.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:s}=e;return(0,a.useMemo)((()=>i({toc:r(t),minHeadingLevel:n,maxHeadingLevel:s})),[t,n,s])}({toc:t,minHeadingLevel:x,maxHeadingLevel:p});return d((0,a.useMemo)((()=>{if(l&&o)return{linkClassName:l,linkActiveClassName:o,minHeadingLevel:x,maxHeadingLevel:p}}),[l,o,x,p])),(0,u.jsx)(g,{toc:v,className:n,linkClassName:l,...h})}},44084:(e,t,n)=>{n.d(t,{AE:()=>o,Rc:()=>i,TT:()=>d,Uh:()=>l,Yh:()=>c});n(96540);var a=n(21312),s=n(5260),r=n(74848);function i(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.title",description:"The unlisted content banner title",children:"Unlisted page"})}function l(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.unlistedBanner.message",description:"The unlisted content banner message",children:"This page is unlisted. Search engines will not index it, and only users having a direct link can access it."})}function o(){return(0,r.jsx)(s.A,{children:(0,r.jsx)("meta",{name:"robots",content:"noindex, nofollow"})})}function c(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.title",description:"The draft content banner title",children:"Draft page"})}function d(){return(0,r.jsx)(a.A,{id:"theme.contentVisibility.draftBanner.message",description:"The draft content banner message",children:"This page is a draft. It will only be visible in dev and be excluded from the production build."})}}}]); \ No newline at end of file diff --git a/assets/js/cd8c5c3b.2df6b353.js b/assets/js/cd8c5c3b.2df6b353.js new file mode 100644 index 000000000..c6336025f --- /dev/null +++ b/assets/js/cd8c5c3b.2df6b353.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29574],{35887:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var n=s(74848),a=s(28453);const i={title:"Gas Cost"},o="Gas and Resources",c={id:"concepts/economics/gas-concepts",title:"Gas Cost",description:"What is gas?",source:"@site/versioned_docs/version-2.0.0/concepts/economics/gas-concepts.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/gas-concepts",permalink:"/2.0.0/concepts/economics/gas-concepts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Gas Cost"},sidebar:"concepts",previous:{title:"Runtime",permalink:"/2.0.0/runtime"},next:{title:"Dynamic Gas Pricing",permalink:"/2.0.0/concepts/economics/dynamic-gas-pricing"}},r={},l=[{value:"What is gas?",id:"what-is-gas",level:2},{value:"How is gas cost determined?",id:"how-is-gas-cost-determined",level:2},{value:"Why do we need to charge a cost?",id:"why-do-we-need-to-charge-a-cost",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"gas-and-resources",children:"Gas and Resources"})}),"\n",(0,n.jsx)(t.h2,{id:"what-is-gas",children:"What is gas?"}),"\n",(0,n.jsx)(t.p,{children:"Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,n.jsxs)(t.p,{children:["Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational work as gas"})," because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"fee elimination"})," for more details."]}),"\n",(0,n.jsx)(t.h2,{id:"how-is-gas-cost-determined",children:"How is gas cost determined?"}),"\n",(0,n.jsxs)(t.p,{children:["The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the ",(0,n.jsx)(t.code,{children:"current_gas_price"})," multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/economics/dynamic-gas-pricing",children:"dynamic pricing"})," can be configured in a Casper network's ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"why-do-we-need-to-charge-a-cost",children:"Why do we need to charge a cost?"}),"\n",(0,n.jsx)(t.p,{children:"Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Rate-limiting is used to ensure a secure and live network:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era."}),"\n",(0,n.jsx)(t.li,{children:"It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators."}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["Pricing leads to more meaningful transactions:\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction."}),"\n"]}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>c});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cd948886.281c855f.js b/assets/js/cd948886.281c855f.js deleted file mode 100644 index b1b581422..000000000 --- a/assets/js/cd948886.281c855f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8979],{35811:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(74848),t=r(28453);const i={},c="Resources Overview",o={id:"resources/index",title:"Resources Overview",description:"Building on Casper",source:"@site/docs/resources/index.md",sourceDirName:"resources",slug:"/resources/",permalink:"/next/resources/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"resources",next:{title:"Build on Casper",permalink:"/next/resources/build-on-casper/introduction"}},d={},l=[{value:"Building on Casper",id:"building-on-casper",level:2},{value:"Move to Casper",id:"move-to-casper",level:2},{value:"Tutorials",id:"tutorials",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources-overview",children:"Resources Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"building-on-casper",children:"Building on Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/build-on-casper/introduction#wallets",children:"Wallets and Block Explorers"})}),(0,s.jsx)(n.td,{children:"Wallets that support the native Casper token $CSPR"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/build-on-casper/introduction#developer-friendly-language",children:"WebAssembly"})}),(0,s.jsx)(n.td,{children:"Learn why WebAssembly is an advantage in contract development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/build-on-casper/introduction#powerful-accounts",children:"Accounts"})}),(0,s.jsx)(n.td,{children:"The Casper account-model allowing for multi-signature deploys"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/build-on-casper/introduction#development-tools",children:"Developer tools"})}),(0,s.jsx)(n.td,{children:"Available development tools"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Projects"})}),(0,s.jsx)(n.td,{children:"Explore some open-source code available in the Casper ecosystem"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"move-to-casper",children:"Move to Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/moving-to-casper",children:"Move to Casper"})}),(0,s.jsx)(n.td,{children:"Learn how to start working with Casper, having previous knowledge of other blockchains"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/quick-start",children:"Quickstart"})}),(0,s.jsx)(n.td,{children:"Install Rust and setup a Casper environment"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/tutorials/beginner/",children:"Beginner"})}),(0,s.jsx)(n.td,{children:"Learn the basics, such as installing and upgrading contracts"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/resources/tutorials/advanced/",children:"Advanced"})}),(0,s.jsx)(n.td,{children:"Learn about multi-sig, authorization keys, exchange integration, and storage"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>o});var s=r(96540);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cd948886.5aed8c76.js b/assets/js/cd948886.5aed8c76.js new file mode 100644 index 000000000..65484c349 --- /dev/null +++ b/assets/js/cd948886.5aed8c76.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8979],{35811:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=r(74848),t=r(28453);const i={},c="Resources Overview",o={id:"resources/index",title:"Resources Overview",description:"Building on Casper",source:"@site/docs/resources/index.md",sourceDirName:"resources",slug:"/resources/",permalink:"/resources/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"resources",next:{title:"Build on Casper",permalink:"/resources/build-on-casper/introduction"}},d={},l=[{value:"Building on Casper",id:"building-on-casper",level:2},{value:"Move to Casper",id:"move-to-casper",level:2},{value:"Tutorials",id:"tutorials",level:2}];function a(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"resources-overview",children:"Resources Overview"})}),"\n",(0,s.jsx)(n.h2,{id:"building-on-casper",children:"Building on Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#wallets",children:"Wallets and Block Explorers"})}),(0,s.jsx)(n.td,{children:"Wallets that support the native Casper token $CSPR"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#developer-friendly-language",children:"WebAssembly"})}),(0,s.jsx)(n.td,{children:"Learn why WebAssembly is an advantage in contract development"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#powerful-accounts",children:"Accounts"})}),(0,s.jsx)(n.td,{children:"The Casper account-model allowing for multi-signature deploys"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/introduction#development-tools",children:"Developer tools"})}),(0,s.jsx)(n.td,{children:"Available development tools"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Projects"})}),(0,s.jsx)(n.td,{children:"Explore some open-source code available in the Casper ecosystem"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"move-to-casper",children:"Move to Casper"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/moving-to-casper",children:"Move to Casper"})}),(0,s.jsx)(n.td,{children:"Learn how to start working with Casper, having previous knowledge of other blockchains"})]})})]}),"\n",(0,s.jsx)(n.h2,{id:"tutorials",children:"Tutorials"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/quick-start",children:"Quickstart"})}),(0,s.jsx)(n.td,{children:"Install Rust and setup a Casper environment"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/",children:"Beginner"})}),(0,s.jsx)(n.td,{children:"Learn the basics, such as installing and upgrading contracts"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/resources/tutorials/advanced/",children:"Advanced"})}),(0,s.jsx)(n.td,{children:"Learn about multi-sig, authorization keys, exchange integration, and storage"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(a,{...e})}):a(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>o});var s=r(96540);const t={},i=s.createContext(t);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cdd6a56c.a344a0d7.js b/assets/js/cdd6a56c.a344a0d7.js new file mode 100644 index 000000000..c10918bb4 --- /dev/null +++ b/assets/js/cdd6a56c.a344a0d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57915],{2222:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var r=n(74848),s=n(28453);const a={},o="Smart Contracts",c={id:"concepts/smart-contracts",title:"Smart Contracts",description:"Smart Contracts in General",source:"@site/versioned_docs/version-2.0.0/concepts/smart-contracts.md",sourceDirName:"concepts",slug:"/concepts/smart-contracts",permalink:"/2.0.0/concepts/smart-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Global State",permalink:"/2.0.0/concepts/global-state"},next:{title:"Authorization Keys",permalink:"/2.0.0/concepts/list-auth-keys"}},i={},l=[{value:"Smart Contracts in General",id:"smart-contracts-in-general",level:2},{value:"Casper Smart Contracts",id:"casper-smart-contracts",level:2},{value:"Session Code",id:"session-code",level:2},{value:"Factory Pattern",id:"factory-pattern",level:2},{value:"Further Reading",id:"further-reading",level:3}];function d(e){const t={a:"a",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"smart-contracts",children:"Smart Contracts"})}),"\n",(0,r.jsx)(t.h2,{id:"smart-contracts-in-general",children:"Smart Contracts in General"}),"\n",(0,r.jsx)(t.p,{children:"A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism."}),"\n",(0,r.jsx)(t.h2,{id:"casper-smart-contracts",children:"Casper Smart Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Casper smart contracts can be implemented in any programming language that compiles to ",(0,r.jsx)(t.a,{href:"/2.0.0/concepts/glossary/W#webassembly",children:"Wasm"}),", which can be installed and executed on-chain using ",(0,r.jsx)(t.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transactions"}),". Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. Understand when you would use session code over contract code ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"factory-pattern",children:"Factory Pattern"}),"\n",(0,r.jsxs)(t.p,{children:["From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding ",(0,r.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/86/files",children:"Casper Enhancement Proposal"})," provides additional details. Also, you can learn to write a simple contract with factory entry points by following the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})," developer guide."]}),"\n",(0,r.jsx)(t.h3,{id:"further-reading",children:"Further Reading"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending a Transaction"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"Installing Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/calling-contracts",children:"Calling Smart Contracts"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/cli/calling-contracts",children:"Calling Smart Contracts using the Casper Client"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/contract-vs-session",children:"Smart Contracts and Session Code"})}),"\n",(0,r.jsx)(t.li,{children:(0,r.jsx)(t.a,{href:"/2.0.0/developers/writing-onchain-code/factory-pattern",children:"The Factory Pattern"})}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>c});var r=n(96540);const s={},a=r.createContext(s);function o(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce0e1dbb.a2815888.js b/assets/js/ce0e1dbb.a2815888.js new file mode 100644 index 000000000..ff598c3ca --- /dev/null +++ b/assets/js/ce0e1dbb.a2815888.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53025],{37733:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var s=t(74848),i=t(28453);const o={title:"Highway Consensus"},a="The Highway Consensus Protocol",r={id:"concepts/design/highway",title:"Highway Consensus",description:"What is Consensus?",source:"@site/versioned_docs/version-1.5.X/concepts/design/highway.md",sourceDirName:"concepts/design",slug:"/concepts/design/highway",permalink:"/1.5.X/concepts/design/highway",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Highway Consensus"},sidebar:"concepts",previous:{title:"Network Communication",permalink:"/1.5.X/concepts/design/p2p"},next:{title:"Reading and Writing Data",permalink:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain"}},h={},c=[{value:"What is Consensus?",id:"what-is-consensus",level:2},{value:"What is Highway Consensus?",id:"what-is-highway-consensus",level:2},{value:"How does the Casper Mainnet use Highway?",id:"how-does-the-casper-mainnet-use-highway",level:3},{value:"Dynamic Round Length",id:"dynamic-round-length",level:3},{value:"Eras",id:"eras",level:3},{value:"Finality",id:"finality",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"the-highway-consensus-protocol",children:"The Highway Consensus Protocol"})}),"\n",(0,s.jsx)(n.h2,{id:"what-is-consensus",children:"What is Consensus?"}),"\n",(0,s.jsx)(n.p,{children:"Consensus is the backbone of any distributed network. The decentralized nature of a blockchain requires a method through which disparate entities can agree on one immutable truth. This involves determining the validity of transactions, resolving conflicts, and finalizing blocks to be added to the chain by the network. A consensus protocol is a set of mechanisms and rules within the distributed network with which all actors must comply."}),"\n",(0,s.jsx)(n.p,{children:"These rules outline the type of messages sent over the network, when they are sent and how to process them. Within the context of a blockchain, the consensus protocol decides which blocks are added to the chain by the network and the order in which they are added. This determines the state of the distributed ledger and ensures that all nodes agree on that state."}),"\n",(0,s.jsx)(n.p,{children:"The consensus mechanism will determine how a blockchain meets the following requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Safety"})," - All honest nodes eventually agree on the final value. The system is setup in a way where no two honest nodes will report two different blocks at the same height of the blockchain."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Liveness"})," - The system continues running and adds new blocks to the chain indefinitely."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"what-is-highway-consensus",children:"What is Highway Consensus?"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks use a consensus protocol called ",(0,s.jsx)(n.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"}),", ensuring the Safety and Liveness requirements of these networks. Highway is a Byzantine Fault Tolerant protocol requiring a partially synchronous network."]}),"\n",(0,s.jsx)(n.h3,{id:"how-does-the-casper-mainnet-use-highway",children:"How does the Casper Mainnet use Highway?"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Mainnet is a ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/P#proof-of-stake",children:"Proof-of-Stake"})," network in which the on-chain auction contract determines validators participating in Highway. The protocol uses a decentralized network of ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/N#node",children:"nodes"}),", either bonded or unbonded. Nodes actively participating in the consensus process must stake CSPR tokens and are known as ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/V#validator",children:"Validator Nodes"}),". The top 100 bidders are selected through the auction contract every era to act as validators in the era after the next (Current Era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus. Highway does not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model."]}),"\n",(0,s.jsxs)(n.p,{children:["These validators run a Casper network that will continue to function so long as the amount of faulty or dishonest nodes does not exceed one-third of the total number of nodes in the network. Nodes that are not faulty are ",(0,s.jsx)(n.em,{children:"honest"})," nodes. In most cases, the system can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly. A block's fault tolerance increases beyond one-third as the protocol continues. If all validators are honest, it approaches 100%."]}),"\n",(0,s.jsx)(n.h3,{id:"dynamic-round-length",children:"Dynamic Round Length"}),"\n",(0,s.jsx)(n.p,{children:"Within the Highway protocol, the length of a round is determined dynamically to ensure a suitable amount of time for nodes to gossip all messages through several round trips with honest validators. This ensures that the system maintains liveness by ensuring that all messages are properly gossiped while maintaining a timely addition of blocks to the chain."}),"\n",(0,s.jsx)(n.h3,{id:"eras",children:"Eras"}),"\n",(0,s.jsxs)(n.p,{children:["The concept of ",(0,s.jsx)(n.em,{children:"eras"})," allows Highway to reduce the overall operational storage requirements of participating nodes while also rotating validators. A new instance of Highway runs every two hours or approximately 220 blocks, depending on current network metrics. This allows for two benefits:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Data Reduction"}),' - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Banning Equivocators"})," - Dishonest nodes caught equivocating in a previous era are banned from participating in new eras. This allows honest nodes to begin a new era in the ",(0,s.jsx)(n.em,{children:"relaxed mode"}),", no longer needing to send endorsements due to past equivocations."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Rotating Validators"})," - Bonded nodes bid on validator spots each era, with the top 100 highest bidders becoming validators for the era after next (",(0,s.jsx)(n.code,{children:"N"}),"+2)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In any given era, node operators will bid to become validators that will participate in the consensus mechanism for the era after next (",(0,s.jsx)(n.code,{children:"N"}),"+2). Each time slot within the era will also determine a lead validator. The lead validator proposes new blocks to be added to the chain, which are then gossiped among the network's nodes. These messages show an implicit preference for the lead validator's block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. Once this process reaches critical mass, with a sufficient interconnected pattern of messages, it becomes impossible to switch to another block. The selected block is then considered finalized and added to the chain."]}),"\n",(0,s.jsxs)(n.p,{children:["The final block of an era is a ",(0,s.jsx)(n.em,{children:"switch block"})," and forms the initial state of the next era. A new Highway instance begins with the new era, using information contained within the ",(0,s.jsx)(n.em,{children:"switch block"})," and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/economics/consensus",children:"Consensus Economics"})," page."]}),"\n",(0,s.jsx)(n.h3,{id:"finality",children:"Finality"}),"\n",(0,s.jsx)(n.p,{children:"Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require greater than 1/3 of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart."}),"\n",(0,s.jsx)(n.p,{children:"On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously."}),"\n",(0,s.jsxs)(n.p,{children:["Highway's criterion for detecting finality is the presence of a pattern of messages called a ",(0,s.jsx)(n.code,{children:"Summit"}),". It is an improvement over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect. Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time."]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var s=t(96540);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce0e1dbb.b2988b7b.js b/assets/js/ce0e1dbb.b2988b7b.js deleted file mode 100644 index 400049170..000000000 --- a/assets/js/ce0e1dbb.b2988b7b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3025],{37733:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>h,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var s=t(74848),i=t(28453);const o={title:"Highway Consensus"},a="The Highway Consensus Protocol",r={id:"concepts/design/highway",title:"Highway Consensus",description:"What is Consensus?",source:"@site/versioned_docs/version-1.5.X/concepts/design/highway.md",sourceDirName:"concepts/design",slug:"/concepts/design/highway",permalink:"/concepts/design/highway",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Highway Consensus"},sidebar:"concepts",previous:{title:"Network Communication",permalink:"/concepts/design/p2p"},next:{title:"Reading and Writing Data",permalink:"/concepts/design/reading-and-writing-to-the-blockchain"}},h={},c=[{value:"What is Consensus?",id:"what-is-consensus",level:2},{value:"What is Highway Consensus?",id:"what-is-highway-consensus",level:2},{value:"How does the Casper Mainnet use Highway?",id:"how-does-the-casper-mainnet-use-highway",level:3},{value:"Dynamic Round Length",id:"dynamic-round-length",level:3},{value:"Eras",id:"eras",level:3},{value:"Finality",id:"finality",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"the-highway-consensus-protocol",children:"The Highway Consensus Protocol"})}),"\n",(0,s.jsx)(n.h2,{id:"what-is-consensus",children:"What is Consensus?"}),"\n",(0,s.jsx)(n.p,{children:"Consensus is the backbone of any distributed network. The decentralized nature of a blockchain requires a method through which disparate entities can agree on one immutable truth. This involves determining the validity of transactions, resolving conflicts, and finalizing blocks to be added to the chain by the network. A consensus protocol is a set of mechanisms and rules within the distributed network with which all actors must comply."}),"\n",(0,s.jsx)(n.p,{children:"These rules outline the type of messages sent over the network, when they are sent and how to process them. Within the context of a blockchain, the consensus protocol decides which blocks are added to the chain by the network and the order in which they are added. This determines the state of the distributed ledger and ensures that all nodes agree on that state."}),"\n",(0,s.jsx)(n.p,{children:"The consensus mechanism will determine how a blockchain meets the following requirements:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Safety"})," - All honest nodes eventually agree on the final value. The system is setup in a way where no two honest nodes will report two different blocks at the same height of the blockchain."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Liveness"})," - The system continues running and adds new blocks to the chain indefinitely."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"what-is-highway-consensus",children:"What is Highway Consensus?"}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks use a consensus protocol called ",(0,s.jsx)(n.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"}),", ensuring the Safety and Liveness requirements of these networks. Highway is a Byzantine Fault Tolerant protocol requiring a partially synchronous network."]}),"\n",(0,s.jsx)(n.h3,{id:"how-does-the-casper-mainnet-use-highway",children:"How does the Casper Mainnet use Highway?"}),"\n",(0,s.jsxs)(n.p,{children:["The Casper Mainnet is a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/P#proof-of-stake",children:"Proof-of-Stake"})," network in which the on-chain auction contract determines validators participating in Highway. The protocol uses a decentralized network of ",(0,s.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"nodes"}),", either bonded or unbonded. Nodes actively participating in the consensus process must stake CSPR tokens and are known as ",(0,s.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"Validator Nodes"}),". The top 100 bidders are selected through the auction contract every era to act as validators in the era after the next (Current Era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus. Highway does not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model."]}),"\n",(0,s.jsxs)(n.p,{children:["These validators run a Casper network that will continue to function so long as the amount of faulty or dishonest nodes does not exceed one-third of the total number of nodes in the network. Nodes that are not faulty are ",(0,s.jsx)(n.em,{children:"honest"})," nodes. In most cases, the system can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly. A block's fault tolerance increases beyond one-third as the protocol continues. If all validators are honest, it approaches 100%."]}),"\n",(0,s.jsx)(n.h3,{id:"dynamic-round-length",children:"Dynamic Round Length"}),"\n",(0,s.jsx)(n.p,{children:"Within the Highway protocol, the length of a round is determined dynamically to ensure a suitable amount of time for nodes to gossip all messages through several round trips with honest validators. This ensures that the system maintains liveness by ensuring that all messages are properly gossiped while maintaining a timely addition of blocks to the chain."}),"\n",(0,s.jsx)(n.h3,{id:"eras",children:"Eras"}),"\n",(0,s.jsxs)(n.p,{children:["The concept of ",(0,s.jsx)(n.em,{children:"eras"})," allows Highway to reduce the overall operational storage requirements of participating nodes while also rotating validators. A new instance of Highway runs every two hours or approximately 220 blocks, depending on current network metrics. This allows for two benefits:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Data Reduction"}),' - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.']}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Banning Equivocators"})," - Dishonest nodes caught equivocating in a previous era are banned from participating in new eras. This allows honest nodes to begin a new era in the ",(0,s.jsx)(n.em,{children:"relaxed mode"}),", no longer needing to send endorsements due to past equivocations."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Rotating Validators"})," - Bonded nodes bid on validator spots each era, with the top 100 highest bidders becoming validators for the era after next (",(0,s.jsx)(n.code,{children:"N"}),"+2)."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In any given era, node operators will bid to become validators that will participate in the consensus mechanism for the era after next (",(0,s.jsx)(n.code,{children:"N"}),"+2). Each time slot within the era will also determine a lead validator. The lead validator proposes new blocks to be added to the chain, which are then gossiped among the network's nodes. These messages show an implicit preference for the lead validator's block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. Once this process reaches critical mass, with a sufficient interconnected pattern of messages, it becomes impossible to switch to another block. The selected block is then considered finalized and added to the chain."]}),"\n",(0,s.jsxs)(n.p,{children:["The final block of an era is a ",(0,s.jsx)(n.em,{children:"switch block"})," and forms the initial state of the next era. A new Highway instance begins with the new era, using information contained within the ",(0,s.jsx)(n.em,{children:"switch block"})," and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the ",(0,s.jsx)(n.a,{href:"/concepts/economics/consensus",children:"Consensus Economics"})," page."]}),"\n",(0,s.jsx)(n.h3,{id:"finality",children:"Finality"}),"\n",(0,s.jsx)(n.p,{children:"Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require greater than 1/3 of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart."}),"\n",(0,s.jsx)(n.p,{children:"On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously."}),"\n",(0,s.jsxs)(n.p,{children:["Highway's criterion for detecting finality is the presence of a pattern of messages called a ",(0,s.jsx)(n.code,{children:"Summit"}),". It is an improvement over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect. Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time."]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>r});var s=t(96540);const i={},o=s.createContext(i);function a(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce3d5a4b.69e5cefd.js b/assets/js/ce3d5a4b.69e5cefd.js new file mode 100644 index 000000000..6af67b37a --- /dev/null +++ b/assets/js/ce3d5a4b.69e5cefd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16986],{33853:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>d,toc:()=>h});var i=n(74848),t=n(28453);const r={title:"Ledger and CSPR.live"},c="Using Ledger and CSPR.live",d={id:"users/ledger/ledger-cspr-live",title:"Ledger and CSPR.live",description:"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-cspr-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-cspr-live",permalink:"/1.5.X/users/ledger/ledger-cspr-live",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ledger and CSPR.live"},sidebar:"users",previous:{title:"Ledger and Ledger Live",permalink:"/1.5.X/users/ledger/ledger-live"},next:{title:"Delegate with Ledger",permalink:"/1.5.X/users/staking-ledger"}},l={},h=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Signing In",id:"sign-in",level:2},{value:"Viewing Account Details",id:"view-account-details",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function a(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"using-ledger-and-csprlive",children:"Using Ledger and CSPR.live"})}),"\n",(0,i.jsxs)(s.p,{children:["This guide will help you connect your Ledger device to a Casper account using the ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to send and receive CSPR tokens."]}),"\n",(0,i.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Install a Chromium-based browser, such as Chrome or Brave, for use with ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," for the Casper Mainnet."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"sign-in",children:"Signing In"}),"\n",(0,i.jsxs)(s.p,{children:["To use the Ledger device with the ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, follow these steps:"]}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsx)(s.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n",(0,i.jsx)(s.li,{children:"Open the Casper app on the Ledger device as shown above."}),"\n",(0,i.jsxs)(s.li,{children:["While keeping the Casper app open, navigate to ",(0,i.jsx)(s.a,{href:"https://cspr.live/sign-in",children:"cspr.live/sign-in"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(424).A+"",width:"2302",height:"224"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Connect"})," button in the Ledger section."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(10542).A+"",width:"2228",height:"1398"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Click the ",(0,i.jsx)(s.strong,{children:"Connect to Ledger wallet"})," button next."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(88567).A+"",width:"1966",height:"1304"})}),"\n",(0,i.jsxs)(s.ol,{start:"6",children:["\n",(0,i.jsx)(s.li,{children:"Select an account you want to use."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(58238).A+"",width:"1966",height:"1470"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsx)(s.li,{children:"Your Ledger device is now connected to the block explorer, displaying your account details."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(75368).A+"",width:"2192",height:"926"})}),"\n",(0,i.jsx)(s.h2,{id:"view-account-details",children:"Viewing Account Details"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"Click on the account in the upper-right corner of the page."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(71158).A+"",width:"1934",height:"270"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"View Account"})," button."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(64857).A+"",width:"1962",height:"566"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["You are presented with a page displaying details about your account. Check your account's main purse balance in the ",(0,i.jsx)(s.strong,{children:"Liquid"})," row under ",(0,i.jsx)(s.strong,{children:"Total Balance"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(17571).A+"",width:"2180",height:"1255"})}),"\n",(0,i.jsx)(s.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,i.jsx)(s.p,{children:"To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open the account details page as described ",(0,i.jsx)(s.a,{href:"#view-account-details",children:"here"})," and copy the public key in the ",(0,i.jsx)(s.strong,{children:"Public Key"})," row."]}),"\n",(0,i.jsx)(s.li,{children:"Alternatively, click on the drop-down menu on your account address."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(71158).A+"",width:"1934",height:"270"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Copy Public Key"})," button and share it with the sender."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(85182).A+"",width:"2194",height:"512"})}),"\n",(0,i.jsx)(s.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"Sign in with your Ledger device."}),"\n",(0,i.jsxs)(s.li,{children:["Click on ",(0,i.jsx)(s.strong,{children:"Wallet"})," and then ",(0,i.jsx)(s.strong,{children:"Transfer CSPR"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(46046).A+"",width:"2306",height:"430"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsx)(s.li,{children:"Fill in the details for the transfer."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(98674).A+"",width:"1134",height:"1674"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Next"})," button."]}),"\n",(0,i.jsxs)(s.li,{children:["On the next page, click ",(0,i.jsx)(s.strong,{children:"Confirm and transfer"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(61961).A+"",width:"1162",height:"1348"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsxs)(s.li,{children:["On the ",(0,i.jsx)(s.strong,{children:"Sign transaction"})," page, click on the ",(0,i.jsx)(s.strong,{children:"Sign with Ledger"})," button."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(75935).A+"",width:"852",height:"1780"})}),"\n",(0,i.jsxs)(s.ol,{start:"8",children:["\n",(0,i.jsxs)(s.li,{children:["Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source ",(0,i.jsx)(s.strong,{children:"account"}),", fee, target, and amount). Meanwhile, the block explorer will show this message:"]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(96333).A+"",width:"870",height:"190"})}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,i.jsxs)(s.p,{children:["Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see ",(0,i.jsx)(s.strong,{children:'"Approve"'}),"."]}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Txn hash"})," - ensure it matches the value displayed on ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(2689).A+"",width:"935",height:"340"})}),"\n",(0,i.jsx)(s.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(99917).A+"",width:"970",height:"332"})}),"\n",(0,i.jsxs)(s.ol,{start:"2",children:["\n",(0,i.jsxs)(s.li,{children:["The next page displays transaction ",(0,i.jsx)(s.strong,{children:"Type"})," - for CSPR transfers, that will be ",(0,i.jsx)(s.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(15911).A+"",width:"875",height:"282"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Chain ID"}),", which identifies the network to which you want to send the transaction."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(50906).A+"",width:"904",height:"302"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Account"}),", the account's public key initiating the transaction."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(94273).A+"",width:"968",height:"317"})}),"\n",(0,i.jsx)(s.p,{children:"The Account value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(87015).A+"",width:"893",height:"314"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(67569).A+"",width:"1041",height:"306"})}),"\n",(0,i.jsxs)(s.ol,{start:"6",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Target"}),", the recipient's public key. Compare this value with the one in the block explorer."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(85219).A+"",width:"887",height:"324"})}),"\n",(0,i.jsx)(s.p,{children:"The Target value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(42069).A+"",width:"859",height:"381"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(27164).A+"",width:"946",height:"338"})}),"\n",(0,i.jsxs)(s.ol,{start:"8",children:["\n",(0,i.jsxs)(s.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,i.jsx)(s.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(4871).A+"",width:"596",height:"222"})}),"\n",(0,i.jsxs)(s.p,{children:["After approving the transaction with your Ledger hardware wallet, the ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),' block explorer will display a "Transfer completed" page.']}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(70960).A+"",width:"856",height:"1000"})}),"\n",(0,i.jsx)(s.p,{children:"You can now check your account to see a list of all the completed transfers."})]})}function o(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},98674:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/1-transfer-details-d728078c48d947c328a3b23bc15cc17f.png"},61961:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/2-transfer-confirm-cafb3d92204942f3666af11f77d8cd61.png"},75935:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-transfer-sign-eb761f9759ce1a3c70c7968f0e2f1e82.png"},96333:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-transfer-submitted-7cfc5128325445455a67726758f30891.png"},70960:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/4-transfer-completed-e9f855a5ceaa8c958312420012496973.png"},67569:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},85219:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},42069:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},27164:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},4871:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},2689:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},99917:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},15911:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},50906:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},94273:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},87015:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},75368:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/account-connected-ce22088786c03da93e7686c5375000c1.png"},17571:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/account-details-3e4ce3ed866005ac2e670604c6a0a1c4.png"},88567:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/connect-ledger-5cccc2f985729730a69b62543732c2a9.png"},58238:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/connect-select-account-98453e231f218ddfc35417eeb3ff61f4.png"},85182:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/copy-public-key-3f7fc15c50bb5e3410019c468527dc12.png"},10542:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/cspr-connect-5c26775af933c4e7bf446690ed2be84a.png"},424:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/cspr-signin-62933017bd15b98d7d3a588ba8f3f579.png"},46046:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/transfer-wallet-dc9b61bfe299341e3e42fc8cadc707ea.png"},64857:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/view-account-button-8c0f2e206de1dbf6547dd21bb8f27ba4.png"},71158:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/view-account-4d1ba8d5125c4ebd4e80a7016d0f62b6.png"},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>d});var i=n(96540);const t={},r=i.createContext(t);function c(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce3d5a4b.b4b03daf.js b/assets/js/ce3d5a4b.b4b03daf.js deleted file mode 100644 index 2665562b3..000000000 --- a/assets/js/ce3d5a4b.b4b03daf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6986],{33853:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>d,toc:()=>h});var i=n(74848),t=n(28453);const r={title:"Ledger and CSPR.live"},c="Using Ledger and CSPR.live",d={id:"users/ledger/ledger-cspr-live",title:"Ledger and CSPR.live",description:"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.",source:"@site/versioned_docs/version-1.5.X/users/ledger/ledger-cspr-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-cspr-live",permalink:"/users/ledger/ledger-cspr-live",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ledger and CSPR.live"},sidebar:"users",previous:{title:"Ledger and Ledger Live",permalink:"/users/ledger/ledger-live"},next:{title:"Delegate with Ledger",permalink:"/users/staking-ledger"}},l={},h=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Signing In",id:"sign-in",level:2},{value:"Viewing Account Details",id:"view-account-details",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function a(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(s.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,i.jsx)(s.header,{children:(0,i.jsx)(s.h1,{id:"using-ledger-and-csprlive",children:"Using Ledger and CSPR.live"})}),"\n",(0,i.jsxs)(s.p,{children:["This guide will help you connect your Ledger device to a Casper account using the ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer to send and receive CSPR tokens."]}),"\n",(0,i.jsx)(s.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Install a Chromium-based browser, such as Chrome or Brave, for use with ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," for the Casper Mainnet."]}),"\n"]}),"\n",(0,i.jsx)(s.h2,{id:"sign-in",children:"Signing In"}),"\n",(0,i.jsxs)(s.p,{children:["To use the Ledger device with the ",(0,i.jsx)(s.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer, follow these steps:"]}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsx)(s.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n",(0,i.jsx)(s.li,{children:"Open the Casper app on the Ledger device as shown above."}),"\n",(0,i.jsxs)(s.li,{children:["While keeping the Casper app open, navigate to ",(0,i.jsx)(s.a,{href:"https://cspr.live/sign-in",children:"cspr.live/sign-in"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(47062).A+"",width:"2302",height:"224"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Connect"})," button in the Ledger section."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(80780).A+"",width:"2228",height:"1398"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Click the ",(0,i.jsx)(s.strong,{children:"Connect to Ledger wallet"})," button next."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(75417).A+"",width:"1966",height:"1304"})}),"\n",(0,i.jsxs)(s.ol,{start:"6",children:["\n",(0,i.jsx)(s.li,{children:"Select an account you want to use."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(92787).A+"",width:"1966",height:"1470"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsx)(s.li,{children:"Your Ledger device is now connected to the block explorer, displaying your account details."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(88766).A+"",width:"2192",height:"926"})}),"\n",(0,i.jsx)(s.h2,{id:"view-account-details",children:"Viewing Account Details"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"Click on the account in the upper-right corner of the page."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(83444).A+"",width:"1934",height:"270"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"View Account"})," button."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(74135).A+"",width:"1962",height:"566"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["You are presented with a page displaying details about your account. Check your account's main purse balance in the ",(0,i.jsx)(s.strong,{children:"Liquid"})," row under ",(0,i.jsx)(s.strong,{children:"Total Balance"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(44905).A+"",width:"2180",height:"1255"})}),"\n",(0,i.jsx)(s.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,i.jsx)(s.p,{children:"To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open the account details page as described ",(0,i.jsx)(s.a,{href:"#view-account-details",children:"here"})," and copy the public key in the ",(0,i.jsx)(s.strong,{children:"Public Key"})," row."]}),"\n",(0,i.jsx)(s.li,{children:"Alternatively, click on the drop-down menu on your account address."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(83444).A+"",width:"1934",height:"270"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Copy Public Key"})," button and share it with the sender."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(46444).A+"",width:"2194",height:"512"})}),"\n",(0,i.jsx)(s.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Open ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n",(0,i.jsx)(s.li,{children:"Sign in with your Ledger device."}),"\n",(0,i.jsxs)(s.li,{children:["Click on ",(0,i.jsx)(s.strong,{children:"Wallet"})," and then ",(0,i.jsx)(s.strong,{children:"Transfer CSPR"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(56328).A+"",width:"2306",height:"430"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsx)(s.li,{children:"Fill in the details for the transfer."}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(70056).A+"",width:"1134",height:"1674"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Click on the ",(0,i.jsx)(s.strong,{children:"Next"})," button."]}),"\n",(0,i.jsxs)(s.li,{children:["On the next page, click ",(0,i.jsx)(s.strong,{children:"Confirm and transfer"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(20555).A+"",width:"1162",height:"1348"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsxs)(s.li,{children:["On the ",(0,i.jsx)(s.strong,{children:"Sign transaction"})," page, click on the ",(0,i.jsx)(s.strong,{children:"Sign with Ledger"})," button."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(40837).A+"",width:"852",height:"1780"})}),"\n",(0,i.jsxs)(s.ol,{start:"8",children:["\n",(0,i.jsxs)(s.li,{children:["Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source ",(0,i.jsx)(s.strong,{children:"account"}),", fee, target, and amount). Meanwhile, the block explorer will show this message:"]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(94363).A+"",width:"870",height:"190"})}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,i.jsxs)(s.p,{children:["Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see ",(0,i.jsx)(s.strong,{children:'"Approve"'}),"."]}),"\n",(0,i.jsxs)(s.ol,{children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Txn hash"})," - ensure it matches the value displayed on ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(13127).A+"",width:"935",height:"340"})}),"\n",(0,i.jsx)(s.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(31115).A+"",width:"970",height:"332"})}),"\n",(0,i.jsxs)(s.ol,{start:"2",children:["\n",(0,i.jsxs)(s.li,{children:["The next page displays transaction ",(0,i.jsx)(s.strong,{children:"Type"})," - for CSPR transfers, that will be ",(0,i.jsx)(s.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(96873).A+"",width:"875",height:"282"})}),"\n",(0,i.jsxs)(s.ol,{start:"3",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Chain ID"}),", which identifies the network to which you want to send the transaction."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(99604).A+"",width:"904",height:"302"})}),"\n",(0,i.jsxs)(s.ol,{start:"4",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Account"}),", the account's public key initiating the transaction."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(93143).A+"",width:"968",height:"317"})}),"\n",(0,i.jsx)(s.p,{children:"The Account value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(67409).A+"",width:"893",height:"314"})}),"\n",(0,i.jsxs)(s.ol,{start:"5",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(50079).A+"",width:"1041",height:"306"})}),"\n",(0,i.jsxs)(s.ol,{start:"6",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Target"}),", the recipient's public key. Compare this value with the one in the block explorer."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(18489).A+"",width:"887",height:"324"})}),"\n",(0,i.jsx)(s.p,{children:"The Target value continues on a second screen."}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(65251).A+"",width:"859",height:"381"})}),"\n",(0,i.jsxs)(s.ol,{start:"7",children:["\n",(0,i.jsxs)(s.li,{children:["Verify the ",(0,i.jsx)(s.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(44998).A+"",width:"946",height:"338"})}),"\n",(0,i.jsxs)(s.ol,{start:"8",children:["\n",(0,i.jsxs)(s.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,i.jsx)(s.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(70677).A+"",width:"596",height:"222"})}),"\n",(0,i.jsxs)(s.p,{children:["After approving the transaction with your Ledger hardware wallet, the ",(0,i.jsx)(s.a,{href:"https://cspr.live",children:"cspr.live"}),' block explorer will display a "Transfer completed" page.']}),"\n",(0,i.jsx)(s.p,{children:(0,i.jsx)(s.img,{src:n(7962).A+"",width:"856",height:"1000"})}),"\n",(0,i.jsx)(s.p,{children:"You can now check your account to see a list of all the completed transfers."})]})}function o(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,i.jsx)(s,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},70056:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/1-transfer-details-d728078c48d947c328a3b23bc15cc17f.png"},20555:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/2-transfer-confirm-cafb3d92204942f3666af11f77d8cd61.png"},40837:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-transfer-sign-eb761f9759ce1a3c70c7968f0e2f1e82.png"},94363:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-transfer-submitted-7cfc5128325445455a67726758f30891.png"},7962:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/4-transfer-completed-e9f855a5ceaa8c958312420012496973.png"},50079:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},18489:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},65251:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},44998:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},70677:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},13127:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},31115:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},96873:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},99604:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},93143:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},67409:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},88766:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/account-connected-ce22088786c03da93e7686c5375000c1.png"},44905:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/account-details-3e4ce3ed866005ac2e670604c6a0a1c4.png"},75417:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/connect-ledger-5cccc2f985729730a69b62543732c2a9.png"},92787:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/connect-select-account-98453e231f218ddfc35417eeb3ff61f4.png"},46444:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/copy-public-key-3f7fc15c50bb5e3410019c468527dc12.png"},80780:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/cspr-connect-5c26775af933c4e7bf446690ed2be84a.png"},47062:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/cspr-signin-62933017bd15b98d7d3a588ba8f3f579.png"},56328:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/transfer-wallet-dc9b61bfe299341e3e42fc8cadc707ea.png"},74135:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/view-account-button-8c0f2e206de1dbf6547dd21bb8f27ba4.png"},83444:(e,s,n)=>{n.d(s,{A:()=>i});const i=n.p+"assets/images/view-account-4d1ba8d5125c4ebd4e80a7016d0f62b6.png"},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>d});var i=n(96540);const t={},r=i.createContext(t);function c(e){const s=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),i.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce6605d8.702f3687.js b/assets/js/ce6605d8.702f3687.js new file mode 100644 index 000000000..5f733db5e --- /dev/null +++ b/assets/js/ce6605d8.702f3687.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82270],{41693:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var i=s(74848),n=s(28453);const r={title:"Verifying Contracts"},c="Verifying Smart Contracts",o={id:"developers/cli/verifying-contracts",title:"Verifying Contracts",description:"This document describes actions needed for smart contract verification using the Casper CLI client.",source:"@site/docs/developers/cli/verifying-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/verifying-contracts",permalink:"/developers/cli/verifying-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Verifying Contracts"},sidebar:"developers",previous:{title:"Installing Contracts",permalink:"/developers/cli/installing-contracts"},next:{title:"Querying Global State",permalink:"/developers/cli/querying-global-state"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Verifying contracts using the Casper Client",id:"verifying-the-contract",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,n.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"verifying-smart-contracts",children:"Verifying Smart Contracts"})}),"\n",(0,i.jsxs)(t.p,{children:["This document describes actions needed for smart contract verification using the ",(0,i.jsx)(t.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper CLI client"}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"You have built and installed a contract"}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"verifying-the-contract",children:"Verifying contracts using the Casper Client"}),"\n",(0,i.jsxs)(t.p,{children:["You can use the Casper client's ",(0,i.jsx)(t.code,{children:"verify-contract"})," command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-bash",children:"casper-client verify-contract --verification-url-basepath <HOST:PORT> <TRANSACTION-HASH> <PATH>\n"})}),"\n",(0,i.jsxs)(t.ol,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"verification-url-basepath"})," - The address of the verification service that will perform the operation; the current two options are ",(0,i.jsx)(t.a,{href:"https://staging.codeverifier.casper.network",children:"https://staging.codeverifier.casper.network"})," for Testnet and ",(0,i.jsx)(t.a,{href:"https://codeverifier.casper.network",children:"https://codeverifier.casper.network"})," for Mainnet."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"<TRANSACTION-HASH>"})," - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success."]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"<PATH>"})," - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used."]}),"\n"]}),"\n",(0,i.jsx)(t.p,{children:"The prerequisites for the source code are the same as when installing it on the blockchain:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"The source code must be a Rust project as described in The Cargo Book."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:"There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book."}),"\n"]}),"\n",(0,i.jsxs)(t.li,{children:["\n",(0,i.jsx)(t.p,{children:'The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.'}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(t.p,{children:["If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on ",(0,i.jsx)(t.a,{href:"https://staging.casperecosystem.io/check-verification-status/",children:"https://staging.casperecosystem.io/check-verification-status/"})," for Testnet transactions and ",(0,i.jsx)(t.a,{href:"https://casperecosystem.io/check-verification-status/",children:"https://casperecosystem.io/check-verification-status/"})," for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust."]})]})}function d(e={}){const{wrapper:t}={...(0,n.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>o});var i=s(96540);const n={},r=i.createContext(n);function c(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:c(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce6605d8.ba4d38f5.js b/assets/js/ce6605d8.ba4d38f5.js deleted file mode 100644 index 1f9e55fd8..000000000 --- a/assets/js/ce6605d8.ba4d38f5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2270],{41693:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>a,contentTitle:()=>c,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var n=s(74848),i=s(28453);const r={title:"Verifying Contracts"},c="Verifying Smart Contracts",o={id:"developers/cli/verifying-contracts",title:"Verifying Contracts",description:"This document describes actions needed for smart contract verification using the Casper CLI client.",source:"@site/docs/developers/cli/verifying-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/verifying-contracts",permalink:"/next/developers/cli/verifying-contracts",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Verifying Contracts"},sidebar:"developers",previous:{title:"Installing Contracts",permalink:"/next/developers/cli/installing-contracts"},next:{title:"Querying Global State",permalink:"/next/developers/cli/querying-global-state"}},a={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Verifying contracts using the Casper Client",id:"verifying-the-contract",level:2}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"verifying-smart-contracts",children:"Verifying Smart Contracts"})}),"\n",(0,n.jsxs)(t.p,{children:["This document describes actions needed for smart contract verification using the ",(0,n.jsx)(t.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper CLI client"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsx)(t.li,{children:"You have built and installed a contract"}),"\n"]}),"\n",(0,n.jsx)(t.h2,{id:"verifying-the-contract",children:"Verifying contracts using the Casper Client"}),"\n",(0,n.jsxs)(t.p,{children:["You can use the Casper client's ",(0,n.jsx)(t.code,{children:"verify-contract"})," command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-bash",children:"casper-client verify-contract --verification-url-basepath <HOST:PORT> <TRANSACTION-HASH> <PATH>\n"})}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"verification-url-basepath"})," - The address of the verification service that will perform the operation; the current two options are ",(0,n.jsx)(t.a,{href:"https://staging.codeverifier.casper.network",children:"https://staging.codeverifier.casper.network"})," for Testnet and ",(0,n.jsx)(t.a,{href:"https://codeverifier.casper.network",children:"https://codeverifier.casper.network"})," for Mainnet."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"<TRANSACTION-HASH>"})," - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success."]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"<PATH>"})," - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used."]}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"The prerequisites for the source code are the same as when installing it on the blockchain:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"The source code must be a Rust project as described in The Cargo Book."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:"There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book."}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsx)(t.p,{children:'The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.'}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(t.p,{children:["If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on ",(0,n.jsx)(t.a,{href:"https://staging.casperecosystem.io/check-verification-status/",children:"https://staging.casperecosystem.io/check-verification-status/"})," for Testnet transactions and ",(0,n.jsx)(t.a,{href:"https://casperecosystem.io/check-verification-status/",children:"https://casperecosystem.io/check-verification-status/"})," for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust."]})]})}function d(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>c,x:()=>o});var n=s(96540);const i={},r=n.createContext(i);function c(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ce6fe363.8c36f3f4.js b/assets/js/ce6fe363.8c36f3f4.js new file mode 100644 index 000000000..2431c7111 --- /dev/null +++ b/assets/js/ce6fe363.8c36f3f4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86486],{86815:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>o,contentTitle:()=>i,default:()=>l,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var n=t(74848),r=t(28453);const a={title:"SDK Client Libraries",slug:"/sdk"},i="SDK Client Libraries",d={id:"developers/dapps/sdk/index",title:"SDK Client Libraries",description:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/index.md",sourceDirName:"developers/dapps/sdk",slug:"/sdk",permalink:"/2.0.0/sdk",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"SDK Client Libraries",slug:"/sdk"},sidebar:"developers",previous:{title:"Prerequisites",permalink:"/2.0.0/developers/dapps/prerequisites"},next:{title:"SDK Client Library Usage",permalink:"/2.0.0/developers/dapps/sdk/client-library-usage"}},o={},c=[{value:"Serialization Standard",id:"serialization-standard",level:2},{value:"JSON-RPC API",id:"json-rpc-api",level:2},{value:"Table of Contents",id:"table-of-contents",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"sdk-client-libraries",children:"SDK Client Libraries"})}),"\n",(0,n.jsx)(s.p,{children:"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions."}),"\n",(0,n.jsx)(s.p,{children:"Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories."}),"\n",(0,n.jsx)(s.p,{children:"Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories."}),"\n",(0,n.jsx)(s.h2,{id:"serialization-standard",children:"Serialization Standard"}),"\n",(0,n.jsxs)(s.p,{children:["The Casper platform uses a custom serialization format. To this end, we've established a ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization Standard"}),", which must be followed when building a Casper SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"json-rpc-api",children:"JSON-RPC API"}),"\n",(0,n.jsxs)(s.p,{children:["Developers can interact directly with the ",(0,n.jsx)(s.a,{href:"/2.0.0/developers/json-rpc/",children:"Casper JSON-RPC API"})," instead of using an SDK."]}),"\n",(0,n.jsx)(s.h2,{id:"table-of-contents",children:"Table of Contents"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,n.jsxs)(s.table,{children:[(0,n.jsx)(s.thead,{children:(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.th,{children:"SDK Documentation"}),(0,n.jsx)(s.th,{children:"GitHub Location"}),(0,n.jsx)(s.th,{children:"Organization"})]})}),(0,n.jsxs)(s.tbody,{children:[(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/2.0.0/developers/dapps/sdk/script-sdk",children:"JavaScript/TypeScript"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk/",children:"casper-js-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem",children:"Casper Ecosystem"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Java SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-java-sdk/",children:"casper-java-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/2.0.0/developers/dapps/sdk/csharp-sdk",children:"C# SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-net-sdk",children:"casper-net-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/2.0.0/developers/dapps/sdk/go-sdk",children:"Go SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-go-sdk",children:"casper-go-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"/2.0.0/developers/dapps/sdk/python-sdk",children:"Python SDK"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-python-sdk/",children:"casper-python-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/casper-network",children:"Casper Association"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"PHP SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software/casper-php-sdk",children:"casper-php-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/make-software",children:"MAKE"})})]}),(0,n.jsxs)(s.tr,{children:[(0,n.jsx)(s.td,{children:"Scala SDK"}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"casper-scala-sdk"})}),(0,n.jsx)(s.td,{children:(0,n.jsx)(s.a,{href:"https://github.com/abahmanem",children:"M. Abahmane"})})]})]})]})]})}function l(e={}){const{wrapper:s}={...(0,r.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>i,x:()=>d});var n=t(96540);const r={},a=n.createContext(r);function i(e){const s=n.useContext(a);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function d(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),n.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/cf3029ea.f454004c.js b/assets/js/cf3029ea.f454004c.js new file mode 100644 index 000000000..b529d6181 --- /dev/null +++ b/assets/js/cf3029ea.f454004c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9636],{20009:(n,e,d)=>{d.r(e),d.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>x,frontMatter:()=>r,metadata:()=>c,toc:()=>h});var s=d(74848),t=d(28453);const r={title:"OpCode Costs Tables"},i="OpCode Costs Tables",c={id:"developers/cli/opcode-costs",title:"OpCode Costs Tables",description:"The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.",source:"@site/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md",sourceDirName:"developers/cli",slug:"/developers/cli/opcode-costs",permalink:"/2.0.0/developers/cli/opcode-costs",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"OpCode Costs Tables"},sidebar:"developers",previous:{title:"Calling Contracts",permalink:"/2.0.0/developers/cli/calling-contracts"},next:{title:"Execution Error Codes",permalink:"/2.0.0/developers/cli/execution-error-codes"}},l={},h=[{value:"Storage Costs",id:"storage-costs",level:2},{value:"OpCode Costs",id:"opcode-costs",level:2},{value:"Control Flow Operation Costs",id:"control-flow-operation-costs",level:2},{value:"<code>Br_Table</code> OpCode Costs",id:"br_table-opcode-costs",level:2},{value:"External Function Costs",id:"external-function-costs",level:2},{value:"<code>Auction</code> System Contract Costs",id:"auction-system-contract-costs",level:3},{value:"<code>Mint</code> System Contract Costs",id:"mint-system-contract-costs",level:3},{value:"<code>Handle_Payment</code> System Contract Costs",id:"handle_payment-system-contract-costs",level:3},{value:"<code>Standard_Payment</code> System Contract Costs",id:"standard_payment-system-contract-costs",level:3}];function o(n){const e={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"opcode-costs-tables",children:"OpCode Costs Tables"})}),"\n",(0,s.jsxs)(e.p,{children:["The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated ",(0,s.jsx)(e.code,{children:"chainspec.toml"}),"."]}),"\n",(0,s.jsxs)(e.p,{children:["More information on ",(0,s.jsx)(e.code,{children:"chainspec"}),"s for private networks can be found ",(0,s.jsx)(e.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"here"})]}),"\n",(0,s.jsx)(e.admonition,{type:"note",children:(0,s.jsxs)(e.p,{children:["All costs in this table are in ",(0,s.jsx)(e.a,{href:"/concepts/glossary/M/#motes",children:"motes"}),", not CSPR, and the corresponding chainspec is ",(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/53dd33865c2707c29284ccc0e8485f22ddd6fbe3/resources/production/chainspec.toml#L129",children:"here"}),"."]})}),"\n",(0,s.jsx)(e.h2,{id:"storage-costs",children:"Storage Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,s.jsx)(e.h2,{id:"opcode-costs",children:"OpCode Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"control-flow-operation-costs",children:"Control Flow Operation Costs"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsxs)(e.h2,{id:"br_table-opcode-costs",children:[(0,s.jsx)(e.code,{children:"Br_Table"})," OpCode Costs"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"external-function-costs",children:"External Function Costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found ',(0,s.jsx)(e.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/ext_ffi/index.html",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Host-Side Function"}),(0,s.jsx)(e.th,{children:"Cost"}),(0,s.jsx)(e.th,{children:"Arguments"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"5_800"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_associated_key"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"blake2b"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_versioned_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_purse"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"disable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_balance"}),(0,s.jsx)(e.td,{children:"3_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_blocktime"}),(0,s.jsx)(e.td,{children:"330"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_caller"}),(0,s.jsx)(e.td,{children:"380"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_key"}),(0,s.jsx)(e.td,{children:"2_000"}),(0,s.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_main_purse"}),(0,s.jsx)(e.td,{children:"1_300"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg_size"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_phase"}),(0,s.jsx)(e.td,{children:"710"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_system_contract"}),(0,s.jsx)(e.td,{children:"1_100"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"has_key"}),(0,s.jsx)(e.td,{children:"1_500"}),(0,s.jsx)(e.td,{children:"[0, 840]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"is_valid_uref"}),(0,s.jsx)(e.td,{children:"760"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load_named_keys"}),(0,s.jsx)(e.td,{children:"42_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"new_uref"}),(0,s.jsx)(e.td,{children:"17_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"random_bytes"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"print"}),(0,s.jsx)(e.td,{children:"20_000"}),(0,s.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"put_key"}),(0,s.jsx)(e.td,{children:"100_000_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_host_buffer"}),(0,s.jsx)(e.td,{children:"3_500"}),(0,s.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value"}),(0,s.jsx)(e.td,{children:"60_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value_local"}),(0,s.jsx)(e.td,{children:"5_500"}),(0,s.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_key"}),(0,s.jsx)(e.td,{children:"61_000"}),(0,s.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"ret"}),(0,s.jsx)(e.td,{children:"23_000"}),(0,s.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"revert"}),(0,s.jsx)(e.td,{children:"500"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_action_threshold"}),(0,s.jsx)(e.td,{children:"74_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,s.jsx)(e.td,{children:"82_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"update_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"write"}),(0,s.jsx)(e.td,{children:"14_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"dictionary_put"}),(0,s.jsx)(e.td,{children:"9_500"}),(0,s.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"enable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"manage_message_topic"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"emit_message"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost_increase_per_message"}),(0,s.jsx)(e.td,{children:"50"}),(0,s.jsx)(e.td,{})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"auction-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Auction"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"change_bid_public_key"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"mint-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Mint"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"burn"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"handle_payment-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Handle_Payment"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These are the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsxs)(e.h3,{id:"standard_payment-system-contract-costs",children:[(0,s.jsx)(e.code,{children:"Standard_Payment"})," System Contract Costs"]}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Entrypoint"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Cost"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function x(n={}){const{wrapper:e}={...(0,t.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,d)=>{d.d(e,{R:()=>i,x:()=>c});var s=d(96540);const t={},r=s.createContext(t);function i(n){const e=s.useContext(r);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(t):n.components||t:i(n.components),s.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/cf35294f.5c7a277d.js b/assets/js/cf35294f.5c7a277d.js new file mode 100644 index 000000000..63520f413 --- /dev/null +++ b/assets/js/cf35294f.5c7a277d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[33341],{72282:(n,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>s,default:()=>f,frontMatter:()=>r,metadata:()=>d,toc:()=>i});var t=a(74848),c=a(28453);const r={title:"CEP-78 Contract Details"},s="Querying NFT Contracts",d={id:"resources/tokens/cep78/using-casper-client/querying-NFTs",title:"CEP-78 Contract Details",description:"This document covers different commands to query and interact with an NFT (CEP-78) contract instance.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/querying-NFTs",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 Contract Details"},sidebar:"resources",previous:{title:"Interaction Workflow",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs"},next:{title:"Testing NFTs",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Querying the Contract",id:"querying-the-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(n){const e={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"querying-nft-contracts",children:"Querying NFT Contracts"})}),"\n",(0,t.jsx)(e.p,{children:"This document covers different commands to query and interact with an NFT (CEP-78) contract instance."}),"\n",(0,t.jsx)(e.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["Install the contract using the ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"querying-the-contract",children:"Querying the Contract"}),"\n",(0,t.jsx)(e.p,{children:"First, identify the contract hash by looking at the account that installed the contract. Under the account's named keys, you will see a named key for the contract hash, representing the stored contract. Copy this value and save it for future queries."}),"\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:a(11659).A+"",width:"2186",height:"712"})}),"\n",(0,t.jsx)(e.p,{children:"Next, query the contract details."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:"casper-client query-global-state -n http://localhost:11101/rpc/"})}),"\n"]}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:"--key [CONTRACT_HASH]"})}),"\n",(0,t.jsxs)(e.p,{children:["The contract hash, found within the ",(0,t.jsx)(e.code,{children:"NamedKeys"})," of the account that sent the installing deploy."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:"--state-root-hash [STATE_ROOT_HASH]"})}),"\n",(0,t.jsxs)(e.p,{children:["The most up-to-date state root hash, which can be found by using the ",(0,t.jsx)(e.code,{children:"get-state-root-hash"})," command in the Casper client."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(e.details,{children:["\n",(0,t.jsx)(e.summary,{children:(0,t.jsx)(e.b,{children:"Expand to see the query and sample contract"})}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:"casper-client query-global-state -n http://localhost:11101/rpc/ \\\n--key hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--state-root-hash 2a8cfc20d24b4bc629ea6d26cc820560a1baf3d4275079d5382242c9fa1e86fe\n"})}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -5355991397545050403,\n "result": {\n "api_version": "1.5.6",\n "block_header": null,\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "contract_wasm_hash": "contract-wasm-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "named_keys": [\n {\n "name": "acl_package_mode",\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007"\n },\n {\n "name": "acl_whitelist",\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007"\n },\n {\n "name": "allow_minting",\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007"\n },\n {\n "name": "approved",\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007"\n },\n {\n "name": "balances",\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007"\n },\n {\n "name": "burn_mode",\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007"\n },\n {\n "name": "burnt_tokens",\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007"\n },\n {\n "name": "cep78_CEP-78-collection2",\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007"\n },\n {\n "name": "collection_name",\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007"\n },\n {\n "name": "collection_symbol",\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007"\n },\n {\n "name": "events_mode",\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007"\n },\n {\n "name": "hash_by_index",\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007"\n },\n {\n "name": "holder_mode",\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007"\n },\n {\n "name": "identifier_mode",\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007"\n },\n {\n "name": "index_by_hash",\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007"\n },\n {\n "name": "installer",\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n },\n {\n "name": "json_schema",\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007"\n },\n {\n "name": "metadata_cep78",\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007"\n },\n {\n "name": "metadata_custom_validated",\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007"\n },\n {\n "name": "metadata_mutability",\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007"\n },\n {\n "name": "metadata_nft721",\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007"\n },\n {\n "name": "metadata_raw",\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007"\n },\n {\n "name": "minting_mode",\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007"\n },\n {\n "name": "nft_kind",\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007"\n },\n {\n "name": "nft_metadata_kind",\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007"\n },\n {\n "name": "nft_metadata_kinds",\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007"\n },\n {\n "name": "number_of_minted_tokens",\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007"\n },\n {\n "name": "operator_burn_mode",\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007"\n },\n {\n "name": "operators",\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007"\n },\n {\n "name": "ownership_mode",\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007"\n },\n {\n "name": "package_operator_mode",\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007"\n },\n {\n "name": "page_table",\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007"\n },\n {\n "name": "receipt_name",\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007"\n },\n {\n "name": "reporting_mode",\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007"\n },\n {\n "name": "rlo_mflag",\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007"\n },\n {\n "name": "token_issuers",\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007"\n },\n {\n "name": "token_owners",\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007"\n },\n {\n "name": "total_token_supply",\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007"\n },\n {\n "name": "whitelist_mode",\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007"\n }\n ],\n "entry_points": [\n {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "balance_of",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n }\n ],\n "ret": "U64",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "burn",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "get_approved",\n "args": [],\n "ret": {\n "Option": "Key"\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "init",\n "args": [\n {\n "name": "collection_name",\n "cl_type": "String"\n },\n {\n "name": "collection_symbol",\n "cl_type": "String"\n },\n {\n "name": "total_token_supply",\n "cl_type": "U64"\n },\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "minting_mode",\n "cl_type": "U8"\n },\n {\n "name": "ownership_mode",\n "cl_type": "U8"\n },\n {\n "name": "nft_kind",\n "cl_type": "U8"\n },\n {\n "name": "holder_mode",\n "cl_type": "U8"\n },\n {\n "name": "whitelist_mode",\n "cl_type": "U8"\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "json_schema",\n "cl_type": "String"\n },\n {\n "name": "receipt_name",\n "cl_type": "String"\n },\n {\n "name": "identifier_mode",\n "cl_type": "U8"\n },\n {\n "name": "burn_mode",\n "cl_type": "U8"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n },\n {\n "name": "nft_metadata_kind",\n "cl_type": "U8"\n },\n {\n "name": "metadata_mutability",\n "cl_type": "U8"\n },\n {\n "name": "owner_reverse_lookup_mode",\n "cl_type": "U8"\n },\n {\n "name": "events_mode",\n "cl_type": "U8"\n },\n {\n "name": "transfer_filter_contract",\n "cl_type": {\n "Option": "Key"\n }\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "is_approved_for_all",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Bool",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "metadata",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "migrate",\n "args": [\n {\n "name": "cep78_package_key",\n "cl_type": "Any"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "mint",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": {\n "Tuple3": [\n "String",\n "Key",\n "String"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "owner_of",\n "args": [],\n "ret": "Key",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "register_owner",\n "args": [],\n "ret": {\n "Tuple2": [\n "String",\n "URef"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "revoke",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_approval_for_all",\n "args": [\n {\n "name": "approve_all",\n "cl_type": "Bool"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_token_metadata",\n "args": [\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_variables",\n "args": [\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "contract_whitelist",\n "cl_type": {\n "List": {\n "ByteArray": 32\n }\n }\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "transfer",\n "args": [\n {\n "name": "source_key",\n "cl_type": "Key"\n },\n {\n "name": "target_key",\n "cl_type": "Key"\n }\n ],\n "ret": {\n "Tuple2": [\n "String",\n "Key"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "updated_receipts",\n "args": [],\n "ret": {\n "List": {\n "Tuple2": [\n "String",\n "Key"\n ]\n }\n },\n "access": "Public",\n "entry_point_type": "Contract"\n }\n ],\n "protocol_version": "1.5.6"\n }\n },\n "merkle_proof": "[33244 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["Learn to ",(0,t.jsx)(e.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n"]})]})}function f(n={}){const{wrapper:e}={...(0,c.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(l,{...n})}):l(n)}},11659:(n,e,a)=>{a.d(e,{A:()=>t});const t=a.p+"assets/images/the-nft-contract-hash-aa17b5fda876c3e0e39d11a605b4ad01.png"},28453:(n,e,a)=>{a.d(e,{R:()=>s,x:()=>d});var t=a(96540);const c={},r=t.createContext(c);function s(n){const e=t.useContext(r);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function d(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(c):n.components||c:s(n.components),t.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/cf35294f.bb066321.js b/assets/js/cf35294f.bb066321.js deleted file mode 100644 index 95b1d3bd7..000000000 --- a/assets/js/cf35294f.bb066321.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3341],{72282:(n,e,a)=>{a.r(e),a.d(e,{assets:()=>o,contentTitle:()=>s,default:()=>f,frontMatter:()=>r,metadata:()=>d,toc:()=>i});var t=a(74848),c=a(28453);const r={title:"CEP-78 Contract Details"},s="Querying NFT Contracts",d={id:"resources/tokens/cep78/using-casper-client/querying-NFTs",title:"CEP-78 Contract Details",description:"This document covers different commands to query and interact with an NFT (CEP-78) contract instance.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/querying-NFTs",permalink:"/resources/tokens/cep78/using-casper-client/querying-NFTs",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-78 Contract Details"},sidebar:"resources",previous:{title:"Interaction Workflow",permalink:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs"},next:{title:"Testing NFTs",permalink:"/resources/tokens/cep78/using-casper-client/testing-NFTs"}},o={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Querying the Contract",id:"querying-the-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(n){const e={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...n.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(e.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(e.header,{children:(0,t.jsx)(e.h1,{id:"querying-nft-contracts",children:"Querying NFT Contracts"})}),"\n",(0,t.jsx)(e.p,{children:"This document covers different commands to query and interact with an NFT (CEP-78) contract instance."}),"\n",(0,t.jsx)(e.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["Install the contract using the ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/quickstart-guide",children:"Quickstart"})," or the ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Full Installation"})," tutorials"]}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"querying-the-contract",children:"Querying the Contract"}),"\n",(0,t.jsx)(e.p,{children:"First, identify the contract hash by looking at the account that installed the contract. Under the account's named keys, you will see a named key for the contract hash, representing the stored contract. Copy this value and save it for future queries."}),"\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.img,{src:a(8897).A+"",width:"2186",height:"712"})}),"\n",(0,t.jsx)(e.p,{children:"Next, query the contract details."}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsx)(e.li,{children:(0,t.jsx)(e.code,{children:"casper-client query-global-state -n http://localhost:11101/rpc/"})}),"\n"]}),"\n",(0,t.jsxs)(e.ol,{children:["\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:"--key [CONTRACT_HASH]"})}),"\n",(0,t.jsxs)(e.p,{children:["The contract hash, found within the ",(0,t.jsx)(e.code,{children:"NamedKeys"})," of the account that sent the installing deploy."]}),"\n"]}),"\n",(0,t.jsxs)(e.li,{children:["\n",(0,t.jsx)(e.p,{children:(0,t.jsx)(e.code,{children:"--state-root-hash [STATE_ROOT_HASH]"})}),"\n",(0,t.jsxs)(e.p,{children:["The most up-to-date state root hash, which can be found by using the ",(0,t.jsx)(e.code,{children:"get-state-root-hash"})," command in the Casper client."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(e.details,{children:["\n",(0,t.jsx)(e.summary,{children:(0,t.jsx)(e.b,{children:"Expand to see the query and sample contract"})}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-bash",children:"casper-client query-global-state -n http://localhost:11101/rpc/ \\\n--key hash-378a43e38bc5129d8aa3bcd04f5c9a97be73f85b5be574182ac1346f04520796 \\\n--state-root-hash 2a8cfc20d24b4bc629ea6d26cc820560a1baf3d4275079d5382242c9fa1e86fe\n"})}),"\n",(0,t.jsx)(e.pre,{children:(0,t.jsx)(e.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -5355991397545050403,\n "result": {\n "api_version": "1.5.6",\n "block_header": null,\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-2b61207cd0e94ce1b1d40801b0abb1ab55fd7dae94c9dcf670292243f3791a30",\n "contract_wasm_hash": "contract-wasm-845d3d08e29642afba35704bcb6e38f3c40f1469763bff7a88674c9a5be3f01b",\n "named_keys": [\n {\n "name": "acl_package_mode",\n "key": "uref-5e950cdd5497633c1d03284ec6e70ce436744cc172d6e26e21e4e474d1b34312-007"\n },\n {\n "name": "acl_whitelist",\n "key": "uref-77b5861bdc04f3c63417dd2ed1943f659f6180603982a24587f79cbc38801cf4-007"\n },\n {\n "name": "allow_minting",\n "key": "uref-dca79aa4244d0123ad52799fc4f922b2ae9fc023c9e56f999979f535a792eef5-007"\n },\n {\n "name": "approved",\n "key": "uref-76aac8f7224c5c1624b4255fff59ecc8ee2c7a1ba460b4f70945d7548abbffd0-007"\n },\n {\n "name": "balances",\n "key": "uref-3d271bac2030ddee54bf4ea92b9b854d800a10a0df5d6e328a045be19af27538-007"\n },\n {\n "name": "burn_mode",\n "key": "uref-eb1a7f69592881587805fde2d53e8e5b3dcbabd81311faa7b9d19ea731f83d9b-007"\n },\n {\n "name": "burnt_tokens",\n "key": "uref-0c144d231ac070adb2668f2a9f3d0eba32c7468efa879f0f29c832c63698966b-007"\n },\n {\n "name": "cep78_CEP-78-collection2",\n "key": "uref-ac99c07d666f45ff5c86a2c1bb6cc44b612ddd5d39a9de88045b441ff6e6b327-007"\n },\n {\n "name": "collection_name",\n "key": "uref-5aed76a73089e7e32f6fbf5d9a9597843215d4810cd5822c0f5c6e65a0bbb7a3-007"\n },\n {\n "name": "collection_symbol",\n "key": "uref-ba4247cc0354644474758d1292924c5115c61c8012cae3f094a91060d9dff779-007"\n },\n {\n "name": "events_mode",\n "key": "uref-51acad53fd1a6ce6a52cf83ed7f921565311ed86cd362969bacf9457b6bf5c1a-007"\n },\n {\n "name": "hash_by_index",\n "key": "uref-e280dd23c847724422543b0d70f1ed4c95c8da9e1a71927ae39add652859775c-007"\n },\n {\n "name": "holder_mode",\n "key": "uref-8443151d736bb3268815ad7848708d44ccc661799f969697c64b1cddb5ce89a7-007"\n },\n {\n "name": "identifier_mode",\n "key": "uref-f53ea99b60ae6d046a6fb0d996475714ef03ed33b39674a8fe016c8324116baf-007"\n },\n {\n "name": "index_by_hash",\n "key": "uref-6299c9322631f374fc1a5e20920641b23f437a3c0ba8da22cc23cba11b0fa3a5-007"\n },\n {\n "name": "installer",\n "key": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655"\n },\n {\n "name": "json_schema",\n "key": "uref-772103052d4559fcc2f8f2c2568eb75214462d463009106938e6f20e1cc0a7c0-007"\n },\n {\n "name": "metadata_cep78",\n "key": "uref-2c2176a9efd465d2e4d5de05d75d029e03040d0a5668c4e08facb0cd3442d30a-007"\n },\n {\n "name": "metadata_custom_validated",\n "key": "uref-575108b0258e92ebede1e50345b608d42963bdac24379022be20b76cfde15301-007"\n },\n {\n "name": "metadata_mutability",\n "key": "uref-2ca963a70a69df2db931b8761b4de13bd22e2fc54a415b0b57d4204c9b90dde9-007"\n },\n {\n "name": "metadata_nft721",\n "key": "uref-eb37c0fe3b53fa5c72b02976f2840b7bf3692954fc830f8a10dc538d0c506e63-007"\n },\n {\n "name": "metadata_raw",\n "key": "uref-cdb17062423b769a7b0bc18fe0a2202b68d2ba77786291018a24fd53f4532ab8-007"\n },\n {\n "name": "minting_mode",\n "key": "uref-3b45a30c98d90de2c62812c6689aa2fac0cb4d08772fcfdee0584c5db2b1d12a-007"\n },\n {\n "name": "nft_kind",\n "key": "uref-e02c29a6120d5da7f14fb664ca60c3ade56a3171a670c292d0a4ea0f9ae4f0c8-007"\n },\n {\n "name": "nft_metadata_kind",\n "key": "uref-45e1bc671353ae58c41a703055959da243deefc7f4c3f121f3f9828d97475bda-007"\n },\n {\n "name": "nft_metadata_kinds",\n "key": "uref-05c0eb8e7ef4caa6f228e8ee91874dc64926b95926d839b458fdce356063a817-007"\n },\n {\n "name": "number_of_minted_tokens",\n "key": "uref-f86e2c4057cc17d93593fb203a923d67e5bc68e6428a6d94f6eab0c35450653d-007"\n },\n {\n "name": "operator_burn_mode",\n "key": "uref-f226eed9d0c5fcf58e6b481d45417721e35435c2ef5eb4d26d215209149438ba-007"\n },\n {\n "name": "operators",\n "key": "uref-ff8ad952307b57a051ef6cb597a55cc2007e587c575584addf6a6fc12c0efd7b-007"\n },\n {\n "name": "ownership_mode",\n "key": "uref-89711af74265427dc65d7c5a421cedde82de69d192cad36f34efa36504108572-007"\n },\n {\n "name": "package_operator_mode",\n "key": "uref-05c2868f179f6b2323f1d4ea069858956c9666d14073748aae4a748d27a8a894-007"\n },\n {\n "name": "page_table",\n "key": "uref-00efcfa874a60b5b615b3c6d781cf69c3559b5372d15457fe4a3bb6d07c66acd-007"\n },\n {\n "name": "receipt_name",\n "key": "uref-1ec63ea6442d9b4ef40d926280f8b72704b763d3ef7cdaccd9ecb04af5562d99-007"\n },\n {\n "name": "reporting_mode",\n "key": "uref-4d851152d7b89dff805dcf6eb61a33870dab9345084a5874575476a584d71b83-007"\n },\n {\n "name": "rlo_mflag",\n "key": "uref-2e3b8aafb27aae47c9b7d3728d20d8815b706e2245c23b84f0e712cd1d1e9124-007"\n },\n {\n "name": "token_issuers",\n "key": "uref-5700d04b36eb1f50204c0d1d05c8ed6aae77eaeaa8a425c78f5a24cbae2e4d26-007"\n },\n {\n "name": "token_owners",\n "key": "uref-ff53b7094bcb6659b558d31fdf63f837b05c0ee6030bfe18ad4c3fb0462b9b17-007"\n },\n {\n "name": "total_token_supply",\n "key": "uref-e5f06deadcbfe5a469e7c162346580744746bfdc0ec67002e0ecba5b11096827-007"\n },\n {\n "name": "whitelist_mode",\n "key": "uref-a77f2ac1f5e72c6b096ca414ae2c986a5387442ddf8e89a35b787a756adc4bb4-007"\n }\n ],\n "entry_points": [\n {\n "name": "approve",\n "args": [\n {\n "name": "spender",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "balance_of",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n }\n ],\n "ret": "U64",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "burn",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "get_approved",\n "args": [],\n "ret": {\n "Option": "Key"\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "init",\n "args": [\n {\n "name": "collection_name",\n "cl_type": "String"\n },\n {\n "name": "collection_symbol",\n "cl_type": "String"\n },\n {\n "name": "total_token_supply",\n "cl_type": "U64"\n },\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "minting_mode",\n "cl_type": "U8"\n },\n {\n "name": "ownership_mode",\n "cl_type": "U8"\n },\n {\n "name": "nft_kind",\n "cl_type": "U8"\n },\n {\n "name": "holder_mode",\n "cl_type": "U8"\n },\n {\n "name": "whitelist_mode",\n "cl_type": "U8"\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "json_schema",\n "cl_type": "String"\n },\n {\n "name": "receipt_name",\n "cl_type": "String"\n },\n {\n "name": "identifier_mode",\n "cl_type": "U8"\n },\n {\n "name": "burn_mode",\n "cl_type": "U8"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n },\n {\n "name": "nft_metadata_kind",\n "cl_type": "U8"\n },\n {\n "name": "metadata_mutability",\n "cl_type": "U8"\n },\n {\n "name": "owner_reverse_lookup_mode",\n "cl_type": "U8"\n },\n {\n "name": "events_mode",\n "cl_type": "U8"\n },\n {\n "name": "transfer_filter_contract",\n "cl_type": {\n "Option": "Key"\n }\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "is_approved_for_all",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Bool",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "metadata",\n "args": [],\n "ret": "String",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "migrate",\n "args": [\n {\n "name": "cep78_package_key",\n "cl_type": "Any"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "mint",\n "args": [\n {\n "name": "token_owner",\n "cl_type": "Key"\n },\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": {\n "Tuple3": [\n "String",\n "Key",\n "String"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "owner_of",\n "args": [],\n "ret": "Key",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "register_owner",\n "args": [],\n "ret": {\n "Tuple2": [\n "String",\n "URef"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "revoke",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_approval_for_all",\n "args": [\n {\n "name": "approve_all",\n "cl_type": "Bool"\n },\n {\n "name": "operator",\n "cl_type": "Key"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_token_metadata",\n "args": [\n {\n "name": "token_meta_data",\n "cl_type": "String"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "set_variables",\n "args": [\n {\n "name": "allow_minting",\n "cl_type": "Bool"\n },\n {\n "name": "contract_whitelist",\n "cl_type": {\n "List": {\n "ByteArray": 32\n }\n }\n },\n {\n "name": "acl_whitelist",\n "cl_type": {\n "List": "Key"\n }\n },\n {\n "name": "acl_package_mode",\n "cl_type": "Bool"\n },\n {\n "name": "package_operator_mode",\n "cl_type": "Bool"\n },\n {\n "name": "operator_burn_mode",\n "cl_type": "Bool"\n }\n ],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "transfer",\n "args": [\n {\n "name": "source_key",\n "cl_type": "Key"\n },\n {\n "name": "target_key",\n "cl_type": "Key"\n }\n ],\n "ret": {\n "Tuple2": [\n "String",\n "Key"\n ]\n },\n "access": "Public",\n "entry_point_type": "Contract"\n },\n {\n "name": "updated_receipts",\n "args": [],\n "ret": {\n "List": {\n "Tuple2": [\n "String",\n "Key"\n ]\n }\n },\n "access": "Public",\n "entry_point_type": "Contract"\n }\n ],\n "protocol_version": "1.5.6"\n }\n },\n "merkle_proof": "[33244 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(e.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(e.ul,{children:["\n",(0,t.jsxs)(e.li,{children:["Learn to ",(0,t.jsx)(e.a,{href:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n"]})]})}function f(n={}){const{wrapper:e}={...(0,c.R)(),...n.components};return e?(0,t.jsx)(e,{...n,children:(0,t.jsx)(l,{...n})}):l(n)}},8897:(n,e,a)=>{a.d(e,{A:()=>t});const t=a.p+"assets/images/the-nft-contract-hash-aa17b5fda876c3e0e39d11a605b4ad01.png"},28453:(n,e,a)=>{a.d(e,{R:()=>s,x:()=>d});var t=a(96540);const c={},r=t.createContext(c);function s(n){const e=t.useContext(r);return t.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function d(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(c):n.components||c:s(n.components),t.createElement(r.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/cfcbd284.63fc464b.js b/assets/js/cfcbd284.63fc464b.js new file mode 100644 index 000000000..7660f22d3 --- /dev/null +++ b/assets/js/cfcbd284.63fc464b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65845],{46012:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var t=s(74848),i=s(28453);const a={title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},r="CEP-78 JavaScript Client Tutorial",l={id:"resources/tokens/cep78/js-tutorial",title:"CEP-78 JavaScript Client",description:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/js-tutorial.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/js-tutorial",permalink:"/2.0.0/resources/tokens/cep78/js-tutorial",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},sidebar:"resources",previous:{title:"Ownership Lookup",permalink:"/2.0.0/resources/tokens/cep78/reverse-lookup"},next:{title:"Open-Source Software",permalink:"/2.0.0/resources/build-on-casper/casper-open-source-software"}},c={},o=[{value:"Client Installation",id:"client-installation",level:2},{value:"Installing a CEP-78 Contract using the JavaScript Client",id:"installing-a-cep-78-contract-using-the-javascript-client",level:2},{value:"Minting a Token",id:"minting-a-token",level:2},{value:"Register Recipient",id:"register-recipient",level:2},{value:"Transferring a Token",id:"transferring-a-token",level:2},{value:"Burning a Token",id:"burning-a-token",level:2},{value:"Example Usages",id:"example-usages",level:2},{value:"Running an Install Example",id:"running-an-install-example",level:3},{value:"Running a Usage Example",id:"running-a-usage-example",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"cep-78-javascript-client-tutorial",children:"CEP-78 JavaScript Client Tutorial"})}),"\n",(0,t.jsx)(n.p,{children:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on the CEP-78 Enhanced NFT Standard can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The client is available in ",(0,t.jsx)(n.em,{children:"npm"})," as ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-cep78-js-client",children:"casper-cep78-js-client"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"client-installation",children:"Client Installation"}),"\n",(0,t.jsx)(n.p,{children:"The client can be installed in a project you have built using TypeScript / Javascript."}),"\n",(0,t.jsx)(n.p,{children:"To install run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm install casper-cep78-js-client\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-cep-78-contract-using-the-javascript-client",children:"Installing a CEP-78 Contract using the JavaScript Client"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"install"})," method crafts a ",(0,t.jsx)(n.a,{href:"/2.0.0/transactions-and-transaction-lifecycle",children:"Deploy"})," using ",(0,t.jsx)(n.code,{children:"InstallArgs"}),".\nAs with every deploy created by the SDK, you can send it using the ",(0,t.jsx)(n.code,{children:".send(rpcUrl)"})," method providing the RPC URL that you want to use. It will return deployHash."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);\n\n const installDeploy = await cc.install(\n {\n collectionName: "my-collection",\n collectionSymbol: "MY-NFTS",\n totalTokenSupply: "1000",\n ownershipMode: NFTOwnershipMode.Transferable,\n nftKind: NFTKind.Physical,\n jsonSchema: {\n properties: {\n color: { name: "color", description: "", required: true },\n size: { name: "size", description: "", required: true },\n material: { name: "material", description: "", required: true },\n condition: { name: "condition", description: "", required: false },\n },\n },\n nftMetadataKind: NFTMetadataKind.CustomValidated,\n identifierMode: NFTIdentifierMode.Ordinal,\n metadataMutability: MetadataMutability.Immutable,\n mintingMode: MintingMode.Installer,\n ownerReverseLookupMode: OwnerReverseLookupMode.Complete\n },\n "250000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"InstallArgs"})," are specified as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionName"})," - The name of the NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionSymbol"})," - The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"totalTokenSupply"})," - The total number of NFTs that a specific contract instance will mint passed in as a ",(0,t.jsx)(n.code,{children:"U64"})," value. ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownershipMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnershipMode"})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftKind"})," - The ",(0,t.jsx)(n.code,{children:"NFTKind"})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"jsonSchema"})," - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". More information on ",(0,t.jsx)(n.code,{children:"NFTMetadataKind"})," can be found ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/modalities#nftmetadatakind",children:"here"}),". This parameter may be left empty if metadata kind is set to ",(0,t.jsx)(n.code,{children:"Raw(3)"}),". If the metadata kind is set to ",(0,t.jsx)(n.code,{children:"CustomValidated(4)"}),", it will require a specifically formatted custom schema. This parameter ",(0,t.jsx)(n.strong,{children:"cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftMetadataKind"})," - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"identifierMode"})," - The ",(0,t.jsx)(n.code,{children:"NFTIdentifierMode"})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"metadataMutability"})," - The ",(0,t.jsx)(n.code,{children:"MetadataMutability"})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"mintingmode"})," - The ",(0,t.jsx)(n.code,{children:"MintingMode"})," modality dictates the access to the ",(0,t.jsx)(n.code,{children:"mint()"})," entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"holdermode"})," - The ",(0,t.jsx)(n.code,{children:"NFTHolderMode"})," modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either ",(0,t.jsx)(n.code,{children:"Accounts"})," or ",(0,t.jsx)(n.code,{children:"Contracts"})," to hold NFTs. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"burnMode"})," - The ",(0,t.jsx)(n.code,{children:"BurnMode"})," modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownerReverseLookupMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," dictates whether the contract will index ownership of tokens as outlined ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/reverse-lookup#the-cep-78-page-system",children:"here"})," to allow lookup of owned tokens by account. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Further information on CEP-78 modality options can be found ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"minting-a-token",children:"Minting a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The CEP-78 JS Client includes code to construct a deploy that will ",(0,t.jsx)(n.code,{children:"Mint"})," a token, as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const mintDeploy = cc.mint(\n {\n owner: FAUCET_KEYS.publicKey,\n meta: {\n color: "Blue",\n size: "Medium",\n material: "Aluminum",\n condition: "Used",\n },\n },\n { useSessionCode: true },\n "2000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The arguments adhere to those provided in the original installation, with the ",(0,t.jsx)(n.code,{children:".send()"})," pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL."]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L86-L88",children:(0,t.jsx)(n.code,{children:"useSessionCode"})})," variable decides if the user will call ",(0,t.jsx)(n.code,{children:"mint"})," using session code, or not. It will be set to ",(0,t.jsx)(n.code,{children:"true"})," if the ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"Complete"}),". ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L116-L130",children:"It then registers the recipient with the contract"})," and mints the token."]}),"\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"NoLookup"}),", ",(0,t.jsx)(n.code,{children:"useSessionCode"})," will be set to ",(0,t.jsx)(n.code,{children:"false"})," and it will simply mint the token as it does not need to register the recipient."]}),"\n",(0,t.jsx)(n.h2,{id:"register-recipient",children:"Register Recipient"}),"\n",(0,t.jsxs)(n.p,{children:["As we used ",(0,t.jsx)(n.code,{children:"ownerReverseLookupMode: OwnerReverseLookupMode.Complete"})," in this contract installation, we must register the recipient. To do this, we construct a ",(0,t.jsx)(n.code,{children:"register"})," deploy:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const registerDeploy = cc.register(\n {\n tokenOwner: USER1_KEYS.publicKey,\n },\n "1000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");\n \n'})}),"\n",(0,t.jsx)(n.h2,{id:"transferring-a-token",children:"Transferring a Token"}),"\n",(0,t.jsx)(n.p,{children:"After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const transferDeploy = cc.transfer(\n {\n tokenId: "0",\n source: FAUCET_KEYS.publicKey,\n target: USER1_KEYS.publicKey,\n },\n { useSessionCode: true },\n "13000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"Transferring accepts the following arguments:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"tokenId"})," - The sequential ID assigned to a token in mint order."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"source"})," - The account sending the token in question."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"target"})," - The account receiving the transferred token."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["As above, the ",(0,t.jsx)(n.code,{children:"useSessionCode"})," variable determines if the user will call ",(0,t.jsx)(n.code,{children:"transfer"})," using session code based on the setting of ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"burning-a-token",children:"Burning a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the ",(0,t.jsx)(n.code,{children:"tokenId"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const burnDeploy = await contractClient.burn(\n { tokenId: "0" },\n "13000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.h2,{id:"example-usages",children:"Example Usages"}),"\n",(0,t.jsx)(n.h3,{id:"running-an-install-example",children:"Running an Install Example"}),"\n",(0,t.jsx)(n.p,{children:"This repository includes an example script for installing a CEP-78 contract instance."}),"\n",(0,t.jsxs)(n.p,{children:["You will need to define the following variables in the ",(0,t.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NODE_URL"})," - The address of a node. If you are testing using ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/setup-nctl",children:"NCTL"}),", this will be ",(0,t.jsx)(n.code,{children:"http://localhost:11101/rpc"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NETWORK_NAME"})," - The name of the Casper network you are operating on, ",(0,t.jsx)(n.code,{children:"casper-net-1"})," when testing using a local network with NCTL."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MASTER_KEY_PAIR_PATH"})," - The path to the key pair of the minting account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"USER1_KEY_PAIR_PATH"})," - The path to an additional account's key pair for use in testing transfer features."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You may also need to install associated dependencies using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm i\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:install\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The example will then return the installation's ",(0,t.jsx)(n.code,{children:"deployHash"}),", and inform you when the installation is successful."]}),"\n",(0,t.jsx)(n.p,{children:"The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash."}),"\n",(0,t.jsx)(n.h3,{id:"running-a-usage-example",children:"Running a Usage Example"}),"\n",(0,t.jsx)(n.p,{children:"A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation."}),"\n",(0,t.jsx)(n.p,{children:"The usage example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:usage\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Mint"})," - The example will attempt to mint an NFT using the installation account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Transfer"})," - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Burn"})," - The example will burn the minted NFT."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The associated code for these deploys may be found in the ",(0,t.jsx)(n.code,{children:"client-js/examples"})," directory."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d02d0f51.fff99507.js b/assets/js/d02d0f51.fff99507.js new file mode 100644 index 000000000..de909bae4 --- /dev/null +++ b/assets/js/d02d0f51.fff99507.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73621],{98879:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>s,default:()=>f,frontMatter:()=>d,metadata:()=>i,toc:()=>o});var t=a(74848),c=a(28453);const d={title:"Installing Contracts"},s="Installing Smart Contracts",i={id:"developers/cli/installing-contracts",title:"Installing Contracts",description:"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.",source:"@site/versioned_docs/version-2.0.0/developers/cli/installing-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/installing-contracts",permalink:"/2.0.0/developers/cli/installing-contracts",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Installing Contracts"},sidebar:"developers",previous:{title:"Sending Transactions",permalink:"/2.0.0/developers/cli/sending-transactions"},next:{title:"Verifying Contracts",permalink:"/2.0.0/developers/cli/verifying-contracts"}},r={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Contract in Global State",id:"installing-contract-code",level:2},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"installing-smart-contracts",children:"Installing Smart Contracts"})}),"\n",(0,t.jsxs)(n.p,{children:["This document details the process of installing ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Casper smart contracts"})," using the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"You have a compiled contract Wasm to send to a Casper network."}),"\n",(0,t.jsxs)(n.li,{children:["You have installed the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#install-casper-client",children:"Casper CLI client"})," to interact with the network."]}),"\n",(0,t.jsxs)(n.li,{children:["You have a ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#setting-up-an-account",children:"Casper Account"})," with a public and secret key pair to initiate the transaction."]}),"\n",(0,t.jsxs)(n.li,{children:["You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the ",(0,t.jsx)(n.a,{href:"/2.0.0/users/testnet-faucet",children:"faucet"})," to fund your testing account's main purse."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-contract-code",children:"Installing a Contract in Global State"}),"\n",(0,t.jsxs)(n.p,{children:["To install a contract in ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/G#global-state",children:"global state"}),", you need to send a transaction to the network with the contract Wasm. You can do so by using the ",(0,t.jsx)(n.code,{children:"put-transaction session"})," command, or the equivalent ",(0,t.jsx)(n.code,{children:"put-txn session"})," command."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--chain-name [CHAIN_NAME] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--gas-price-tolerance [MAX_GAS_AMOUNT] \\\n--pricing-mode fixed \\\n--transaction-path <PATH> \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The network where you wish to send the transaction. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the transaction"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas-price-tolerance"})," - The maximum amount of gas a user is willing to pay for execution"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing-mode"}),' - Set to "fixed" for Mainnet and Testnet']}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"transaction-path"})," - The path to the contract Wasm, which should point to wherever you compiled the contract (",(0,t.jsx)(n.code,{children:".wasm"})," file) on your computer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when installing the contract, which is usually ",(0,t.jsx)(n.code,{children:"call"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"category"})," - The transaction type, based on Wasm size, with ",(0,t.jsx)(n.code,{children:"install-upgrade"})," being the largest"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Once you call this command, it will return a transaction hash. You can use this hash to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/sending-transactions#sending-the-transaction",children:"verify"})," successful execution of the transaction."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The pricing mode varies based on each network ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),'. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.']})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Contract Installation"})}),"\n",(0,t.jsxs)(n.p,{children:["Here we send a ",(0,t.jsx)(n.code,{children:"counter-installer.wasm"})," to a local NCTL network:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-transaction session \\\n--node-address http://localhost:11101 \\\n--chain-name casper-net-1 \\\n--secret-key ~/casper/casper-nctl/assets/net-1/users/user-1/secret_key.pem \\\n--gas-price-tolerance 10 \\\n--pricing-mode fixed \\\n--transaction-path ~/test_contracts/counter_installer.wasm \\\n--session-entry-point call \\\n--category 'install-upgrade'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The result of the query includes a ",(0,t.jsx)(n.code,{children:"transaction_hash"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 90342686534145684,\n "result": {\n "api_version": "2.0.0",\n "transaction_hash": {\n "Version1": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2"\n }\n }\n}\n'})}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transaction, call ",(0,t.jsx)(n.code,{children:"get-transaction"})," and provide the transaction hash you received from ",(0,t.jsx)(n.code,{children:"put-transaction"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-transaction --node-address http://localhost:11101 [TRANSACTION_HASH]\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Expand to view the sample response details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 5297043714444661948,\n "result": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2",\n "header": {\n "chain_name": "casper-net-1",\n "timestamp": "2024-08-21T11:21:36.201Z",\n "ttl": "30m",\n "body_hash": "543df05d05c456e9b6b5d657029e9ad20c674c6e6b56f498af0052ec87ee9f80",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 10\n }\n },\n "initiator_addr": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n }\n },\n "body": {\n "args": [],\n "target": {\n "Session": {\n "module_bytes": "[105936 hex chars]",\n "runtime": "VmCasperV1"\n }\n },\n "entry_point": "Call",\n "transaction_category": 2,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d",\n "signature": "01537684dd531ce6a4c9383ba7ea565e9408ed2c5dd8bb12787f131e1148fd0f057f45dbaa7bbc0230743cc5740c67db64f66bab1df57547722899f7d7289c1f0c"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "24ead40278a71966e16823150b06c06675a216dbef761c1d6ad1439da4147f4a",\n "block_height": 8463,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"\n },\n "error_message": null,\n "limit": "1000000000000",\n "consumed": "46747144601",\n "cost": "1000000000000",\n "payment": [],\n "transfers": [],\n "size_estimate": 53215,\n "effects": [\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n }\n }\n },\n {\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-05c3e063406ddde43671e0d47c45e31a10e9204137171f96ce818bdc725a4e1b",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1050d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "parsed": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n "name": {\n "cl_type": "String",\n "bytes": "14000000636f756e7465725f7061636b6167655f6e616d65",\n "parsed": "counter_package_name"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-6409273bf327d5a6a39a29dbd07c5cd2f48ee4f227fd443d025adc51e1bd5103",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0229feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a07",\n "parsed": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "13000000636f756e7465725f6163636573735f75726566",\n "parsed": "counter_access_uref"\n }\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "package-f1c97c9b6228be3f316753e4e1289d910071fb880dddccce18881abfb9f53526",\n "kind": "Identity"\n },\n {\n "key": "entry-point-v1-entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",\n "kind": "Identity"\n },\n {\n "key": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "Unit",\n "bytes": "",\n "parsed": null\n }\n }\n }\n },\n {\n "key": "balance-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n }\n },\n {\n "key": "byte-code-v1-wasm-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "kind": {\n "Write": {\n "ByteCode": {\n "kind": "V1CasperWasm",\n "bytes": "[82290 hex chars]"\n }\n }\n }\n },\n {\n "key": "named-key-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-5fed34ec1b2c38445b984eee743ce17fb1e5e89a8cb910cc2f9f12b005360eef",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "0265f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab0363140707",\n "parsed": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "05000000636f756e74",\n "parsed": "count"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-399a84b0da15b34ecd774b1c4ad47c72a9e1298df057d83bee93d22ac4972aa5",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481",\n "kind": {\n "Write": {\n "EntryPoint": {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n }\n }\n },\n {\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "kind": {\n "Write": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n }\n }\n },\n {\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "kind": {\n "Write": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n }\n }\n },\n {\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U32",\n "bytes": "01000000",\n "parsed": 1\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-174ccaaa723ba74cee869017501fab28512b6ef9296d48a38daff7d0da13d1a1",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "027bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf07",\n "parsed": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n },\n "name": {\n "cl_type": "String",\n "bytes": "0700000076657273696f6e",\n "parsed": "version"\n }\n }\n }\n }\n },\n {\n "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-83b1cde13136393741a1e906a892ccdd289e7827cc9ef84a98cc96e86464bde0",\n "kind": {\n "Write": {\n "NamedKey": {\n "named_key": {\n "cl_type": "Key",\n "bytes": "1102a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",\n "parsed": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n "name": {\n "cl_type": "String",\n "bytes": "07000000636f756e746572",\n "parsed": "counter"\n }\n }\n }\n }\n },\n {\n "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Prune": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000"\n }\n },\n {\n "key": "balance-hold-0021dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",\n "kind": {\n "Write": {\n "CLValue": {\n "cl_type": "U512",\n "bytes": "050010a5d4e8",\n "parsed": "1000000000000"\n }\n }\n }\n },\n {\n "key": "entity-system-b76adcf84d4900edec0af9001e727bcc3d4920a40afaa6a0e43137bacf62b91e",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",\n "kind": "Identity"\n },\n {\n "key": "entity-system-1d29f1bd6ba7016f430498de2d0fe7c9d2c14c200d79be33e0ad240bc2a0d229",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-01f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d",\n "kind": "Identity"\n },\n {\n "key": "bid-addr-04f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d0903000000000000",\n "kind": {\n "Write": {\n "BidKind": {\n "Credit": {\n "validator_public_key": "01e4bb993269e0fe33d6e575ab6a642fdcaf692449a1529c4f73e636dfff9d3e61",\n "era_id": 777,\n "amount": "1000000000000"\n }\n }\n }\n }\n }\n ]\n }\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note the contract entity address in the above sample output. You will need this to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/querying-global-state#query-the-contract",children:"query the contract"})," installed. In this example, the address is ",(0,t.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/querying-global-state",children:"query global state"})," to see more details about the successfully installed contract."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/querying-global-state",children:"query global state"})," using the Casper command-line client."]}),"\n"]})]})}function f(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>i});var t=a(96540);const c={},d=t.createContext(c);function s(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:s(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d050b476.240ce090.js b/assets/js/d050b476.240ce090.js new file mode 100644 index 000000000..f737ce434 --- /dev/null +++ b/assets/js/d050b476.240ce090.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58889],{97651:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="U",a={id:"concepts/glossary/U",title:"U",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/U.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/U",permalink:"/1.5.X/concepts/glossary/U",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"T",permalink:"/1.5.X/concepts/glossary/T"},next:{title:"V",permalink:"/1.5.X/concepts/glossary/V"}},i={},l=[{value:"Unbonding",id:"unbonding",level:2},{value:"URef",id:"uref",level:2},{value:"Users",id:"users",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"u",children:"U"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"unbonding",children:"Unbonding"}),"\n",(0,r.jsxs)(s.p,{children:["Withdrawing money from the ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/glossary/A#auction",children:"auction"})," contract with ",(0,r.jsx)(s.em,{children:"withdraw bid"})," and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed."]}),"\n",(0,r.jsx)(s.h2,{id:"uref",children:"URef"}),"\n",(0,r.jsxs)(s.p,{children:["An ",(0,r.jsx)(s.strong,{children:"U"}),"nforgeable ",(0,r.jsx)(s.strong,{children:"Ref"}),"erence, used by a Casper network to store any value other than ",(0,r.jsx)(s.code,{children:"Account"}),". More information can be found ",(0,r.jsx)(s.a,{href:"/1.5.X/concepts/design/casper-design#uref-head",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"users",children:"Users"}),"\n",(0,r.jsx)(s.p,{children:"Users execute session and contract code using the platform's computational resources."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d050b476.71af1ad0.js b/assets/js/d050b476.71af1ad0.js deleted file mode 100644 index c12b606b9..000000000 --- a/assets/js/d050b476.71af1ad0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8889],{97651:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>a,toc:()=>l});var r=n(74848),t=n(28453);const c={},o="U",a={id:"concepts/glossary/U",title:"U",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/U.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/U",permalink:"/concepts/glossary/U",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"T",permalink:"/concepts/glossary/T"},next:{title:"V",permalink:"/concepts/glossary/V"}},i={},l=[{value:"Unbonding",id:"unbonding",level:2},{value:"URef",id:"uref",level:2},{value:"Users",id:"users",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",strong:"strong",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"u",children:"U"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsx)(s.h2,{id:"unbonding",children:"Unbonding"}),"\n",(0,r.jsxs)(s.p,{children:["Withdrawing money from the ",(0,r.jsx)(s.a,{href:"/concepts/glossary/A#auction",children:"auction"})," contract with ",(0,r.jsx)(s.em,{children:"withdraw bid"})," and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed."]}),"\n",(0,r.jsx)(s.h2,{id:"uref",children:"URef"}),"\n",(0,r.jsxs)(s.p,{children:["An ",(0,r.jsx)(s.strong,{children:"U"}),"nforgeable ",(0,r.jsx)(s.strong,{children:"Ref"}),"erence, used by a Casper network to store any value other than ",(0,r.jsx)(s.code,{children:"Account"}),". More information can be found ",(0,r.jsx)(s.a,{href:"/concepts/design/casper-design#uref-head",children:"here"}),"."]}),"\n",(0,r.jsx)(s.h2,{id:"users",children:"Users"}),"\n",(0,r.jsx)(s.p,{children:"Users execute session and contract code using the platform's computational resources."})]})}function h(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0616161.a6c02aa2.js b/assets/js/d0616161.a6c02aa2.js new file mode 100644 index 000000000..2d127059f --- /dev/null +++ b/assets/js/d0616161.a6c02aa2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[17832],{23545:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var n=i(74848),r=i(28453);const s={title:"Dictionaries"},a="Understanding Dictionaries {#dictionaries}",o={id:"concepts/dictionaries",title:"Dictionaries",description:"dictionaries}",source:"@site/versioned_docs/version-2.0.0/concepts/dictionaries.md",sourceDirName:"concepts",slug:"/concepts/dictionaries",permalink:"/2.0.0/concepts/dictionaries",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Dictionaries"},sidebar:"concepts",previous:{title:"Call Stacks",permalink:"/2.0.0/concepts/callstack"}},c={},d=[{value:"Seed URefs",id:"seed-urefs",level:2},{value:"Using Dictionaries",id:"using-dictionaries",level:2},{value:"Practical Dictionary Examples",id:"practical-dictionary-examples",level:2},{value:"Creating Dictionaries in a Contract's Context",id:"creating-dictionaries-in-a-contracts-context",level:2},{value:"Writing Entries into a Dictionary",id:"writing-entries-into-a-dictionary",level:2},{value:"Reading Items from a Dictionary using the JSON-RPC",id:"reading-items-from-a-dictionary-using-the-json-rpc",level:2},{value:"<code>ContractNamedKey</code> lookup via a Contract's named keys.",id:"contractnamedkey-lookup-via-a-contracts-named-keys",level:3},{value:"<code>URef</code> lookup via the dictionary's seed URef.",id:"uref-lookup-via-the-dictionarys-seed-uref",level:3},{value:"<code>Dictionary</code> lookup via the unique dictionary item key.",id:"dictionary-lookup-via-the-unique-dictionary-item-key",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"dictionaries",children:"Understanding Dictionaries"})}),"\n",(0,n.jsxs)(t.p,{children:["In a Casper network, you can now store sets of data under ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/key-types#key-explanations",children:(0,n.jsx)(t.code,{children:"Keys"})}),". Previously, ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/glossary/U#uref",children:"URefs"})," were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an ",(0,n.jsx)(t.code,{children:"addressable entity"}),"'s context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/glossary/N#named-keys",children:"NamedKeys"})," structures."]}),"\n",(0,n.jsx)(t.p,{children:"Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs."}),"\n",(0,n.jsxs)(t.p,{children:["As a solution to this problem, the Casper platform provides the ",(0,n.jsx)(t.code,{children:"Dictionary"})," feature, which allows users a more efficient and scalable means to aggregate data over time."]}),"\n",(0,n.jsxs)(t.p,{children:["Casper's Condor release shifts ",(0,n.jsx)(t.code,{children:"NamedKeys"})," to a top-level key, removing this restriction and making them viable for data storage."]}),"\n",(0,n.jsx)(t.h2,{id:"seed-urefs",children:"Seed URefs"}),"\n",(0,n.jsxs)(t.p,{children:["Items within a dictionary exist as individual records stored underneath their unique ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/key-types#key-explanations",children:"dictionary address"})," in global state. In other words, items associated with a specific dictionary share the same seed ",(0,n.jsx)(t.a,{href:"/2.0.0/concepts/design/casper-design#uref-head",children:(0,n.jsx)(t.code,{children:"URef"})})," but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key."]}),"\n",(0,n.jsx)(t.p,{children:"As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef."}),"\n",(0,n.jsx)(t.h2,{id:"using-dictionaries",children:"Using Dictionaries"}),"\n",(0,n.jsxs)(t.p,{children:["Creating a new dictionary is fairly simple and done within the context of a ",(0,n.jsx)(t.code,{children:"transaction"})," sent to a Casper network. The associated code is included within the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:(0,n.jsx)(t.code,{children:"casper_contract"})})," crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context."]}),"\n",(0,n.jsx)(t.p,{children:"Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract entity."}),"\n",(0,n.jsxs)(t.p,{children:["While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional ",(0,n.jsx)(t.code,{children:"transaction"})," removing those access rights, but it is better to create the dictionary within the context of the Contract."]}),"\n",(0,n.jsx)(t.p,{children:"A dictionary item key can be no longer than 64 bytes in length."}),"\n",(0,n.jsx)(t.h2,{id:"practical-dictionary-examples",children:"Practical Dictionary Examples"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"Casper CEP-78 Enhanced NFT Standard"})," includes several practical applications of dictionaries."]}),"\n",(0,n.jsxs)(t.p,{children:["Simple examples for dictionary use within CEP-78 include the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs#L772",children:(0,n.jsx)(t.code,{children:"approve"})})," dictionary."]}),"\n",(0,n.jsxs)(t.p,{children:["More advanced dictionary functionality can be found in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft#the-cep-78-page-system",children:"CEP-78 Page System"}),", which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract."]}),"\n",(0,n.jsx)(t.h2,{id:"creating-dictionaries-in-a-contracts-context",children:"Creating Dictionaries in a Contract's Context"}),"\n",(0,n.jsx)(t.p,{children:"The following code snippet shows the most basic example of creating a dictionary."}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\ncasper_contract::contract_api::storage::new_dictionary(dict_name)\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The following example includes the creation of a dictionary ",(0,n.jsx)(t.code,{children:'"ledger"'})," within a contract's context. In this instance, the dictionary will be used to track donations made to a fundraising purse also created by the ",(0,n.jsx)(t.code,{children:"init"})," entry point. In any case where you want to use a dictionary within your contract, it should be set up within the initializing entry point."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn init() {\n let fundraising_purse = system::create_purse();\n runtime::put_key("fundraising_purse", fundraising_purse.into());\n // Create a dictionary to track the mapping of account hashes to number of donations made.\n storage::new_dictionary("ledger").unwrap_or_revert();\n}\n\n'})}),"\n",(0,n.jsx)(t.h2,{id:"writing-entries-into-a-dictionary",children:"Writing Entries into a Dictionary"}),"\n",(0,n.jsx)(t.p,{children:"After the creation of a dictionary, you may then add entries through the use of the following code:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\nstorage::dictionary_put(dictionary_uref, &dictionary_item_key, value);\n\n"})}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"dictionary_uref"})," refers to the seed URef established during the dictionary creation process. The ",(0,n.jsx)(t.code,{children:"key"})," is the unique identifier for this dictionary item, and the ",(0,n.jsx)(t.code,{children:"value"})," is the data to be stored within the dictionary."]}),"\n",(0,n.jsx)(t.p,{children:"As stated above, these dictionary items do not require the seed URef, and they exist as individual keys in global state. If you know an individual key's address, you do not need to go through the process of identifying the seed URef first."}),"\n",(0,n.jsx)(t.p,{children:"The following function serves to add an entry to the dictionary. If the item already exists, the entry point will update the value stored and referenced by that key. In this case, the code is storing the number of donations made. Any Rust structure may be stored under a dictionary item, but when updating a value within a larger structure (i.e., a list), the entire structure will be overwritten as part of the update. Updating a larger structure will incur the full cost of writing the structure to a dictionary item."}),"\n",(0,n.jsxs)(t.p,{children:["The first section acquiring the ",(0,n.jsx)(t.code,{children:"LEDGER"})," seed URef to assign the new dictionary item to the proper dictionary."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:'\nfn update_ledger_record(dictionary_item_key: String) {\n // Acquiring the LEDGER seed URef to properly assign the dictionary item.\n let ledger_seed_uref = *runtime::get_key("ledger")\n .unwrap_or_revert_with(FundRaisingError::MissingLedgerSeedURef)\n .as_uref()\n .unwrap_or_revert();\n\n'})}),"\n",(0,n.jsxs)(t.p,{children:["The second section uses ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_get.html",children:(0,n.jsx)(t.code,{children:"dictionary_get"})})," to read an entry within the ",(0,n.jsx)(t.code,{children:"LEDGER"})," dictionary. If the entry does not exist on global state, it will create the entry. If it already exists, the entry is updated with the current value using a ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.dictionary_put.html",children:(0,n.jsx)(t.code,{children:"dictionary_put"})})," operation. As stated above, regardless of the size of the change within the entry, the entire dictionary entry will need to be overwritten and will incur the associated cost."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // This identifies an item within the dictionary and either creates or updates the associated value.\n match storage::dictionary_get::<u64>(ledger_seed_uref, &dictionary_item_key).unwrap_or_revert()\n {\n None => storage::dictionary_put(ledger_seed_uref, &dictionary_item_key, 1u64),\n Some(current_number_of_donations) => storage::dictionary_put(\n ledger_seed_uref,\n &dictionary_item_key,\n current_number_of_donations + 1u64,\n ),\n }\n}\n\n"})}),"\n",(0,n.jsx)(t.h2,{id:"reading-items-from-a-dictionary-using-the-json-rpc",children:"Reading Items from a Dictionary using the JSON-RPC"}),"\n",(0,n.jsxs)(t.p,{children:["The Casper platform provides several means of looking up a dictionary item. These means are explained within the ",(0,n.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_chain#dictionaryidentifier",children:(0,n.jsx)(t.code,{children:"DictionaryIdentifier"})})," JSON-RPC type. The following explains how to query the dictionary items using the ",(0,n.jsx)(t.a,{href:"https://crates.io/crates/casper-client",children:"Casper client"}),"."]}),"\n",(0,n.jsxs)(t.h3,{id:"contractnamedkey-lookup-via-a-contracts-named-keys",children:[(0,n.jsx)(t.code,{children:"ContractNamedKey"})," lookup via a Contract's named keys."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"})," requires the following parameters:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Node Address"})," - The IP and port of a node on a Casper network. In the example below, the node address is pointing to a local NCTL network."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"State Root Hash"})," - The current state root hash of a Casper network hosting the dictionary item you are attempting to read."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Contract Hash"})," - The hash of the contract that references the dictionary in its ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Name"})," - The name of the dictionary as a ",(0,n.jsx)(t.code,{children:"String"})," stored in the Contract's ",(0,n.jsx)(t.code,{children:"NamedKeys"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," - The specific dictionary item key to be read, as a ",(0,n.jsx)(t.code,{children:"String"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --contract-hash hash-09c8fa7c1441ae7c1cbe27ae3a722fd4ffc5290315f8546454454c1b9f85c842 \\\n --dictionary-name <String> \\\n --dictionary-item-key <String>\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"uref-lookup-via-the-dictionarys-seed-uref",children:[(0,n.jsx)(t.code,{children:"URef"})," lookup via the dictionary's seed URef."]}),"\n",(0,n.jsxs)(t.p,{children:["Reading a dictionary item using the dictionary's seed URef requires the ",(0,n.jsx)(t.code,{children:"Node Address"}),", ",(0,n.jsx)(t.code,{children:"State Root Hash"})," and ",(0,n.jsx)(t.code,{children:"Dictionary Item Key"})," as above. However, it does not require the ",(0,n.jsx)(t.code,{children:"Contract Hash"})," or ",(0,n.jsx)(t.code,{children:"Dictionary Name"}),". Instead, it requires:"]}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.code,{children:"Seed URef"})," - The ",(0,n.jsx)(t.a,{href:"#seed-urefs",children:"Seed URef"})," of the dictionary to reference."]}),"\n"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-item-key <String> \\\n --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"dictionary-lookup-via-the-unique-dictionary-item-key",children:[(0,n.jsx)(t.code,{children:"Dictionary"})," lookup via the unique dictionary item key."]}),"\n",(0,n.jsxs)(t.p,{children:["In the event that you know the ",(0,n.jsx)(t.code,{children:"dictionary address"})," of the dictionary item key you need to read, you can read it directly using the following Casper client command."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:"\ncasper-client get-dictionary-item \\\n --node-address http://localhost:11101 \\\n --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \\\n --dictionary-address dictionary-<string>\n\n"})})]})}function l(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>a,x:()=>o});var n=i(96540);const r={},s=n.createContext(r);function a(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d06ee05c.4fae27bd.js b/assets/js/d06ee05c.4fae27bd.js new file mode 100644 index 000000000..9e439ee40 --- /dev/null +++ b/assets/js/d06ee05c.4fae27bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[71451],{48340:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var a=n(74848),r=n(28453);const s={title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},o="Safely Transfer Tokens to a Contract",i={id:"resources/advanced/transfer-token-to-contract",title:"Token Transfers",description:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.",source:"@site/docs/resources/advanced/transfer-token-to-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/transfer-token-to-contract",permalink:"/resources/tutorials/advanced/transfer-token-to-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},sidebar:"tutorials",previous:{title:"Authorization Keys",permalink:"/resources/advanced/list-auth-keys-tutorial"},next:{title:"Storage Workflow",permalink:"/resources/tutorials/advanced/storage-workflow"}},c={},h=[{value:"Scenario 1 - Creating a Throw-Away Purse",id:"scenario1",level:2},{value:"Scenario 1 - Advanced Variation",id:"scenario1-advanced",level:3},{value:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic",id:"scenario2",level:2},{value:"Scenario 2 - Advanced Variation",id:"scenario2-advanced",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"safely-transfer-tokens-to-a-contract",children:"Safely Transfer Tokens to a Contract"})}),"\n",(0,a.jsx)(t.p,{children:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs."}),"\n",(0,a.jsxs)(t.p,{children:["For increased security, token transfers from a main purse must be handled via session code (WASM), as shown ",(0,a.jsx)(t.a,{href:"/developers/writing-onchain-code/writing-session-code#transfers-using-session-code",children:"here"}),". Therefore, ",(0,a.jsx)(t.code,{children:"transfer-*"})," methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario1",children:"Scenario 1 - Creating a Throw-Away Purse"}),"\n",(0,a.jsx)(t.p,{children:"The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee."}),"\n",(0,a.jsx)(t.p,{children:"In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues."}),"\n",(0,a.jsx)(t.p,{children:"This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation."}),"\n",(0,a.jsx)(t.p,{children:"Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_name of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n let entry_point_name = runtime::get_named_arg("entry_point_name");\n\n // This creates a new empty purse that the caller will use just this one time.\n let new_purse = system::create_purse();\n \n // Transfer from the caller\'s main purse to the new purse that was just created.\n // Note that transfer is done safely by the host logic.\n system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)\n .unwrap_or_revert();\n \n // Pass the newly created purse to the smart contract with full access rights; \n // the called contract should receive the new purse, extract the token from it, and then do\n // whatever else it is meant to do if a valid amount was transferred to it. Note that the\n // caller\'s main purse is never exposed to the called contract; the newly created purse\n // is provided instead.\n runtime::call_contract(contract_hash, entry_point_name, runtime_args! {\n // The arg names are defined by the contract that you are calling,\n // there is no canonical name. The contract you are calling may have other\n // runtime args that it requires.\n "????" => new_purse\n });\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario1-advanced",children:"Scenario 1 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs",children:"This example"})," provides a framework for the idea, but will require modification to suit developer needs."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario2",children:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"}),"\n",(0,a.jsx)(t.p,{children:"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."}),"\n",(0,a.jsxs)(t.p,{children:["In ",(0,a.jsx)(t.a,{href:"#scenario1",children:"Scenario 1"}),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,a.jsx)(t.a,{href:"#scenario1-advanced",children:"Scenario 1's Advanced Variation"})," in that the purse in question is under the control of the contract rather than the caller."]}),"\n",(0,a.jsx)(t.p,{children:"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic. \n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments. \n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario2-advanced",children:"Scenario 2 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."}),"\n",(0,a.jsx)(t.p,{children:"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var a=n(96540);const r={},s=a.createContext(r);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d06ee05c.b42299f4.js b/assets/js/d06ee05c.b42299f4.js deleted file mode 100644 index 4e7aebd8b..000000000 --- a/assets/js/d06ee05c.b42299f4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1451],{48340:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>h});var a=n(74848),r=n(28453);const s={title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},o="Safely Transfer Tokens to a Contract",i={id:"resources/advanced/transfer-token-to-contract",title:"Token Transfers",description:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.",source:"@site/docs/resources/advanced/transfer-token-to-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/transfer-token-to-contract",permalink:"/next/resources/tutorials/advanced/transfer-token-to-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Token Transfers",slug:"/resources/tutorials/advanced/transfer-token-to-contract"},sidebar:"tutorials",previous:{title:"Authorization Keys",permalink:"/next/resources/advanced/list-auth-keys-tutorial"},next:{title:"Storage Workflow",permalink:"/next/resources/tutorials/advanced/storage-workflow"}},c={},h=[{value:"Scenario 1 - Creating a Throw-Away Purse",id:"scenario1",level:2},{value:"Scenario 1 - Advanced Variation",id:"scenario1-advanced",level:3},{value:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic",id:"scenario2",level:2},{value:"Scenario 2 - Advanced Variation",id:"scenario2-advanced",level:3}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"safely-transfer-tokens-to-a-contract",children:"Safely Transfer Tokens to a Contract"})}),"\n",(0,a.jsx)(t.p,{children:"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs."}),"\n",(0,a.jsxs)(t.p,{children:["For increased security, token transfers from a main purse must be handled via session code (WASM), as shown ",(0,a.jsx)(t.a,{href:"/next/developers/writing-onchain-code/writing-session-code#transfers-using-session-code",children:"here"}),". Therefore, ",(0,a.jsx)(t.code,{children:"transfer-*"})," methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario1",children:"Scenario 1 - Creating a Throw-Away Purse"}),"\n",(0,a.jsx)(t.p,{children:"The first scenario involves the use of a single-use, throw-away purse. The caller creates and funds a purse independent of their main purse, before passing the URef to the callee."}),"\n",(0,a.jsx)(t.p,{children:"In this example, the smart contract retains full access to the purse, creating security concerns over its reuse by the caller. Further, it is also possible for the caller to retain full access to the disposable purse, although not demonstrated in the example. The contract should remove any tokens from the purse and transfer them to another purse under their control to avoid issues."}),"\n",(0,a.jsx)(t.p,{children:"This scenario is less complex, but more wasteful than the second scenario. Any purses created in this fashion remain permanent, but unused after the initial operation."}),"\n",(0,a.jsx)(t.p,{children:"Please note that the creation of a purse costs 2.5 CSPR on the Casper Mainnet."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_name of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n let entry_point_name = runtime::get_named_arg("entry_point_name");\n\n // This creates a new empty purse that the caller will use just this one time.\n let new_purse = system::create_purse();\n \n // Transfer from the caller\'s main purse to the new purse that was just created.\n // Note that transfer is done safely by the host logic.\n system::transfer_from_purse_to_purse(account::get_main_purse(), new_purse, amount, None)\n .unwrap_or_revert();\n \n // Pass the newly created purse to the smart contract with full access rights; \n // the called contract should receive the new purse, extract the token from it, and then do\n // whatever else it is meant to do if a valid amount was transferred to it. Note that the\n // caller\'s main purse is never exposed to the called contract; the newly created purse\n // is provided instead.\n runtime::call_contract(contract_hash, entry_point_name, runtime_args! {\n // The arg names are defined by the contract that you are calling,\n // there is no canonical name. The contract you are calling may have other\n // runtime args that it requires.\n "????" => new_purse\n });\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario1-advanced",children:"Scenario 1 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"Advanced versions of this scenario can mitigate the wastefulness inherent in the example. If the caller creates a named purse independent of their main purse, they can integrate it with the contract in question. In this way, the same purse can be used to fund a contract repeatedly."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.4.4/smart_contracts/contracts/client/named-purse-payment/src/main.rs",children:"This example"})," provides a framework for the idea, but will require modification to suit developer needs."]}),"\n",(0,a.jsx)(t.h2,{id:"scenario2",children:"Scenario 2 - Maintaining a Reusable Purse within Contract Logic"}),"\n",(0,a.jsx)(t.p,{children:"The second scenario involves more complex internal logic to allow for a purse's reuse. The contract itself keeps track of a purse associated with the caller as internal bookkeeping."}),"\n",(0,a.jsxs)(t.p,{children:["In ",(0,a.jsx)(t.a,{href:"#scenario1",children:"Scenario 1"}),", the newly created purse is a pure means of transferring tokens from the caller to the callee. In contrast, Scenario 2 maintains an internal purse associated with the caller's address. This purse serves as token storage for actions the caller wishes the contract to undertake on their behalf. It differs from ",(0,a.jsx)(t.a,{href:"#scenario1-advanced",children:"Scenario 1's Advanced Variation"})," in that the purse in question is under the control of the contract rather than the caller."]}),"\n",(0,a.jsx)(t.p,{children:"Scenario 2 offers a less wasteful means of transferring tokens to a contract but comes with the added burden of internal complexity. When choosing between the two scenarios, you must evaluate the scope and needs of your project and choose accordingly."}),"\n",(0,a.jsx)(t.pre,{children:(0,a.jsx)(t.code,{className:"language-rust",children:'// Scenario 2: with this style, the contract being called has some internal accounting\n// to keep track of a reusable purse associated to the calling account; this avoids\n// wasteful creation of one time purses but requires the smart contract being called\n// to have more sophisticated internal logic. \n#[no_mangle]\npub extern "C" fn call() {\n let amount: U512 = runtime::get_named_arg("amount");\n\n // This is demonstrating the most direct case, wherein you pass in the contract_hash and\n // the entry_point_names of the target contract as args.\n // With prior setup having been done, this can also be simplified.\n let contract_hash = runtime::get_named_arg("contract_hash");\n // the name of the entry point on the contract that returns a purse uref to receive token at\n // the actual name of the entry point is up to the smart contract authors\n let deposit_point_name = runtime::get_named_arg("deposit_point_name");\n // whatever entry point on the smart contract does the actual work if token has been transferred\n // the actual name of which is up to the smart contract authors.\n let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");\n\n // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)\n // for the caller to transfer to.\n let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});\n\n // transfer from the caller\'s purse to the purse provided by the contract; the transfer is handled\n // safely by the host and the caller\'s purse is never exposed to the called smart contract.\n system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)\n .unwrap_or_revert();\n\n // The contract being interacted with looks up the associated purse, checks its balance, etc.\n // within its logic. That side of it is entirely up to the smart contract authors to code; the caller\n // merely calls the logic. Also, the entry point might require one or more runtime arguments. \n // In all cases some discovery of the API of the contract you are calling is necessary.\n runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});\n}\n\n'})}),"\n",(0,a.jsx)(t.h3,{id:"scenario2-advanced",children:"Scenario 2 - Advanced Variation"}),"\n",(0,a.jsx)(t.p,{children:"In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract."}),"\n",(0,a.jsx)(t.p,{children:"This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup."})]})}function d(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>i});var a=n(96540);const r={},s=a.createContext(r);function o(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0a8493b.0a50edbb.js b/assets/js/d0a8493b.0a50edbb.js deleted file mode 100644 index be3e48f9d..000000000 --- a/assets/js/d0a8493b.0a50edbb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1926],{45341:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var r=t(74848),o=t(28453);const s={},c="Documentation Updates by Protocol Release",a={id:"resources/changelog",title:"Documentation Updates by Protocol Release",description:"Condor (2.0)",source:"@site/docs/resources/changelog.md",sourceDirName:"resources",slug:"/resources/changelog",permalink:"/next/resources/changelog",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},i={},d=[{value:"Condor (2.0)",id:"condor-20",level:2},{value:"Concepts",id:"concepts",level:3},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"documentation-updates-by-protocol-release",children:"Documentation Updates by Protocol Release"})}),"\n",(0,r.jsx)(n.h2,{id:"condor-20",children:"Condor (2.0)"}),"\n",(0,r.jsx)(n.h3,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"The following are changes introduced alongside release of the Condor network upgrade."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/concepts/key-types",children:"Understanding Key Types"})," - Additional Key Types and document restructuring."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/concepts/serialization/",children:"Serialization Standard"})," - Serialization information for new types."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/concepts/smart-contracts",children:"Smart Contracts"})," - Information on the new factory pattern feature for smart contracts."]}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Building dApps -> Monitoring and Consuming Events"})," - Information related to contract-level events."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational",children:"Casper JSON-RPC API -> Informational JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-transactional",children:"Casper JSON-RPC API -> Transactional JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain",children:"Casper JSON-RPC API -> Types"})," - New parameters used by the JSON-RPC API."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/writing-onchain-code/emitting-contract-events",children:"Writing On-Chain Code -> Contract-Level Events"})," - Guide to the new contract-level events feature."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/developers/writing-onchain-code/factory-pattern",children:"Writing On-Chain Code -> Factory Contracts"})," - Guide to the new factory pattern for smart contracts."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/next/operators/setup-network/chain-spec",children:"Private Network -> The Chainspec"})," - Updates to the ",(0,r.jsx)(n.code,{children:"chainpsec"})," relating to contract-level events."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function c(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0a8493b.8611e4aa.js b/assets/js/d0a8493b.8611e4aa.js new file mode 100644 index 000000000..08802e65f --- /dev/null +++ b/assets/js/d0a8493b.8611e4aa.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11926],{45341:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var r=t(74848),o=t(28453);const s={},c="Documentation Updates by Protocol Release",a={id:"resources/changelog",title:"Documentation Updates by Protocol Release",description:"Condor (2.0)",source:"@site/docs/resources/changelog.md",sourceDirName:"resources",slug:"/resources/changelog",permalink:"/resources/changelog",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{}},i={},d=[{value:"Condor (2.0)",id:"condor-20",level:2},{value:"Concepts",id:"concepts",level:3},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"documentation-updates-by-protocol-release",children:"Documentation Updates by Protocol Release"})}),"\n",(0,r.jsx)(n.h2,{id:"condor-20",children:"Condor (2.0)"}),"\n",(0,r.jsx)(n.h3,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"The following are changes introduced alongside release of the Condor network upgrade."}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/concepts/key-types",children:"Understanding Key Types"})," - Additional Key Types and document restructuring."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/concepts/serialization/",children:"Serialization Standard"})," - Serialization information for new types."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})," - Information on the new factory pattern feature for smart contracts."]}),"\n",(0,r.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Building dApps -> Monitoring and Consuming Events"})," - Information related to contract-level events."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational",children:"Casper JSON-RPC API -> Informational JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-transactional",children:"Casper JSON-RPC API -> Transactional JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/json-rpc/types_chain",children:"Casper JSON-RPC API -> Types"})," - New parameters used by the JSON-RPC API."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/emitting-contract-events",children:"Writing On-Chain Code -> Contract-Level Events"})," - Guide to the new contract-level events feature."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/developers/writing-onchain-code/factory-pattern",children:"Writing On-Chain Code -> Factory Contracts"})," - Guide to the new factory pattern for smart contracts."]}),"\n",(0,r.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"Private Network -> The Chainspec"})," - Updates to the ",(0,r.jsx)(n.code,{children:"chainpsec"})," relating to contract-level events."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>a});var r=t(96540);const o={},s=r.createContext(o);function c(e){const n=r.useContext(s);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),r.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d0c6c99a.e6fa3b5a.js b/assets/js/d0c6c99a.e6fa3b5a.js new file mode 100644 index 000000000..20fad5ba7 --- /dev/null +++ b/assets/js/d0c6c99a.e6fa3b5a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75250],{83031:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var s=n(74848),o=n(28453);const r={},a="Casper-Client Commands",i={id:"resources/beginner/counter-testnet/commands",title:"Casper-Client Commands",description:"State Root Hash",source:"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/commands.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/commands",permalink:"/2.0.0/resources/beginner/counter-testnet/commands",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Overview",permalink:"/2.0.0/resources/beginner/counter-testnet/overview"},next:{title:"Tutorial Walkthrough",permalink:"/2.0.0/resources/beginner/counter-testnet/walkthrough"}},c={},l=[{value:"State Root Hash",id:"state-root-hash",level:2},{value:"Querying Network State",id:"querying-network-state",level:2},{value:"Put Deploys (onto the Chain)",id:"put-deploys-onto-the-chain",level:2},{value:"Deploy via a compiled Wasm binary",id:"deploy-via-a-compiled-wasm-binary",level:3},{value:"Deploy via a named key already on the blockchain",id:"deploy-via-a-named-key-already-on-the-blockchain",level:3},{value:"Get Deploys (from the Chain)",id:"get-deploys-from-the-chain",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"casper-client-commands",children:"Casper-Client Commands"})}),"\n",(0,s.jsx)(t.h2,{id:"state-root-hash",children:"State Root Hash"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Example:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-state-root-hash --node-address http://[IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You can find a list of Testnet IP addresses at ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"CSPR live"}),"."]}),"\n",(0,s.jsxs)(t.p,{children:["The first command to cover is the ",(0,s.jsx)(t.em,{children:"get-state-root-hash"})," command from the ",(0,s.jsx)(t.em,{children:"casper-client"})," tool. The state root hash is an identifier of the current network state. It is similar to a Git commit ID for commit history. It gives a snapshot of the blockchain state at a moment in time. For this tutorial, it will be used to query the network state after sending deploys."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"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."})}),"\n",(0,s.jsx)(t.h2,{id:"querying-network-state",children:"Querying Network State"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client query-global-state \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "[SESSION_NAME]/[SESSION_NAMED_KEY]" (OPTIONAL)\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This command allows you to query the state of a Casper network at a given moment in time, which is specified by the ",(0,s.jsx)(t.em,{children:"state-root-hash"})," described above."]}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"node-address"})," is the server on the network."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"key"})," is the identifier for the query. It must be either the account public key, account hash, contract address hash, transfer hash, or deploy hash. The tutorial demonstrates two of these key types."]}),"\n",(0,s.jsxs)(t.li,{children:["The optional query path argument (",(0,s.jsx)(t.em,{children:"q"}),") allows you to drill into the specifics of a query concerning the key."]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"put-deploys-onto-the-chain",children:"Put Deploys (onto the Chain)"}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-compiled-wasm-binary",children:"Deploy via a compiled Wasm binary"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [CONTRACT_PATH]/counter-v1.wasm\n"})}),"\n",(0,s.jsx)(t.p,{children:"This command creates a deploy and sends it to the network for execution. In this first usage of the command,"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," points to a compiled Wasm contract."]}),"\n",(0,s.jsxs)(t.li,{children:["This contract is then installed on the network specified by the ",(0,s.jsx)(t.em,{children:"chain-name"}),'. The Testnet is "casper-test" but this is configurable.']}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"payment-amount"})," is in units of motes (1 nano-CSPR) and is required to pay the transaction fee for the deploy. If it is too small, the transaction will get denied due to insufficient funds."]}),"\n"]}),"\n",(0,s.jsx)(t.h3,{id:"deploy-via-a-named-key-already-on-the-blockchain",children:"Deploy via a named key already on the blockchain"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["This second usage of ",(0,s.jsx)(t.em,{children:"put-deploy"})," does not place a new contract on the chain, but it allows you to call entry points (functions) defined in smart contracts."]}),"\n",(0,s.jsxs)(t.p,{children:['This examples uses "counter" and "counter_inc" from the ',(0,s.jsx)(t.a,{href:"/2.0.0/resources/beginner/counter-testnet/walkthrough",children:"tutorial walkthrough"}),". However, these will be different when you write your contracts."]}),"\n",(0,s.jsx)(t.h2,{id:"get-deploys-from-the-chain",children:"Get Deploys (from the Chain)"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n [DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.em,{children:"get-deploy"})," command is complementary to the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command. It retrieves a deploy from the network and allows you to check the status of the deploy. The ",(0,s.jsx)(t.em,{children:"DEPLOY_HASH"})," is the identifier to a specific deploy and is returned by the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>i});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d13dc577.5be46c79.js b/assets/js/d13dc577.5be46c79.js new file mode 100644 index 000000000..7ac8bf242 --- /dev/null +++ b/assets/js/d13dc577.5be46c79.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82677],{41026:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>a,frontMatter:()=>i,metadata:()=>c,toc:()=>h});var r=s(74848),t=s(28453);const i={},d="Users Overview",c={id:"users/index",title:"Users Overview",description:"General Topics",source:"@site/versioned_docs/version-1.5.X/users/index.md",sourceDirName:"users",slug:"/users/",permalink:"/1.5.X/users/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"users",next:{title:"Block Explorers",permalink:"/1.5.X/users/block-explorer"}},l={},h=[{value:"General Topics",id:"general-topics",level:2},{value:"Using CSPR.live",id:"using-csprlive",level:2},{value:"Using Ledger Devices",id:"using-ledger-devices",level:2}];function o(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"users-overview",children:"Users Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"general-topics",children:"General Topics"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/block-explorer",children:"Block Explorers"})}),(0,r.jsx)(n.td,{children:"A guide to understanding block explorers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/funding-from-exchanges",children:"Funding Mainnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding Mainnet accounts from an exchange"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-csprlive",children:"Using CSPR.live"}),"\n",(0,r.jsxs)(n.p,{children:["Interact with the Casper blockchain using the ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding your Testnet account using the Faucet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/delegate-ui",children:"Delegating Tokens"})}),(0,r.jsxs)(n.td,{children:["Staking your Casper tokens with ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,r.jsx)(n.td,{children:"Un-staking your Casper tokens"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/token-transfer",children:"Transferring Tokens"})}),(0,r.jsxs)(n.td,{children:["Transferring your Casper tokens using ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-ledger-devices",children:"Using Ledger Devices"}),"\n",(0,r.jsx)(n.p,{children:"Interact with the Casper blockchain using a Ledger device."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/workflow/ledger-setup/",children:"Ledger Setup"})}),(0,r.jsx)(n.td,{children:"A guide to setting up your Ledger device"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,r.jsx)(n.td,{children:"Delegating tokens using your Ledger device"})]})]})]})]})}function a(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d13dc577.6fe89c7c.js b/assets/js/d13dc577.6fe89c7c.js deleted file mode 100644 index 07354525e..000000000 --- a/assets/js/d13dc577.6fe89c7c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2677],{41026:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>l,contentTitle:()=>d,default:()=>a,frontMatter:()=>i,metadata:()=>c,toc:()=>h});var r=s(74848),t=s(28453);const i={},d="Users Overview",c={id:"users/index",title:"Users Overview",description:"General Topics",source:"@site/versioned_docs/version-1.5.X/users/index.md",sourceDirName:"users",slug:"/users/",permalink:"/users/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"users",next:{title:"Block Explorers",permalink:"/users/block-explorer"}},l={},h=[{value:"General Topics",id:"general-topics",level:2},{value:"Using CSPR.live",id:"using-csprlive",level:2},{value:"Using Ledger Devices",id:"using-ledger-devices",level:2}];function o(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"users-overview",children:"Users Overview"})}),"\n",(0,r.jsx)(n.h2,{id:"general-topics",children:"General Topics"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/block-explorer",children:"Block Explorers"})}),(0,r.jsx)(n.td,{children:"A guide to understanding block explorers"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/funding-from-exchanges",children:"Funding Mainnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding Mainnet accounts from an exchange"})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-csprlive",children:"Using CSPR.live"}),"\n",(0,r.jsxs)(n.p,{children:["Interact with the Casper blockchain using the ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})," block explorer."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/testnet-faucet",children:"Funding Testnet Accounts"})}),(0,r.jsx)(n.td,{children:"Funding your Testnet account using the Faucet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/delegate-ui",children:"Delegating Tokens"})}),(0,r.jsxs)(n.td,{children:["Staking your Casper tokens with ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/undelegate-ui",children:"Undelegating Tokens"})}),(0,r.jsx)(n.td,{children:"Un-staking your Casper tokens"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/token-transfer",children:"Transferring Tokens"})}),(0,r.jsxs)(n.td,{children:["Transferring your Casper tokens using ",(0,r.jsx)(n.a,{href:"https://cspr.live/",children:"cspr.live"})]})]})]})]}),"\n",(0,r.jsx)(n.h2,{id:"using-ledger-devices",children:"Using Ledger Devices"}),"\n",(0,r.jsx)(n.p,{children:"Interact with the Casper blockchain using a Ledger device."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Topic"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup"})}),(0,r.jsx)(n.td,{children:"A guide to setting up your Ledger device"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,r.jsx)(n.td,{children:"Delegating tokens using your Ledger device"})]})]})]})]})}function a(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(o,{...e})}):o(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var r=s(96540);const t={},i=r.createContext(t);function d(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:d(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d2039ef8.5609990b.js b/assets/js/d2039ef8.5609990b.js deleted file mode 100644 index 57818a837..000000000 --- a/assets/js/d2039ef8.5609990b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5354],{15377:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>o,frontMatter:()=>l,metadata:()=>t,toc:()=>a});var s=i(74848),r=i(28453);const l={},d="Serialization Standard {#serialization-standard-head}",t={id:"concepts/serialization-standard",title:"Serialization Standard",description:"serialization-standard-head}",source:"@site/versioned_docs/version-1.5.X/concepts/serialization-standard.md",sourceDirName:"concepts",slug:"/concepts/serialization-standard",permalink:"/concepts/serialization-standard",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Dictionaries",permalink:"/concepts/dictionaries"},next:{title:"Design Overview",permalink:"/design"}},c={},a=[{value:"Account",id:"serialization-standard-account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Action Thresholds",id:"action-thresholds",level:2},{value:"Activation Point",id:"activation-point",level:2},{value:"Approval",id:"approval",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"Bid",id:"bid",level:2},{value:"Block",id:"serialization-standard-block",level:2},{value:"Block hash",id:"block-hash",level:3},{value:"Block header",id:"block-header",level:3},{value:"EraEnd",id:"serialization-standard-era-end",level:3},{value:"Body",id:"body",level:3},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"ChainspecRegistry",id:"chainspecregistry",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"serialization-standard-deploy",level:2},{value:"Deploy-Hash",id:"deploy-hash",level:3},{value:"Deploy-Header",id:"deploy-header",level:3},{value:"Payment & Session",id:"payment--session",level:3},{value:"Approval",id:"approval",level:3},{value:"DeployInfo",id:"deployinfo",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"<code>Failure</code>",id:"failure",level:3},{value:"<code>Success</code>",id:"success",level:3},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account identity key",id:"global-state-account-key",level:3},{value:"Hash key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (<code>URef</code>)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for <code>Key</code>",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"Operation",id:"operation",level:2},{value:"Parameter",id:"parameter",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"Values",id:"serialization-standard-values",level:2},{value:"<code>CLValue</code>",id:"clvalue",level:3},{value:"Boolean",id:"clvalue-boolean",level:4},{value:"Numeric",id:"clvalue-numeric",level:4},{value:"Unit",id:"clvalue-unit",level:4},{value:"String",id:"clvalue-string",level:4},{value:"Option",id:"clvalue-option",level:4},{value:"List",id:"clvalue-list",level:4},{value:"ByteArray",id:"clvalue-ByteArray",level:4},{value:"Result",id:"clvalue-result",level:4},{value:"Tuple",id:"clvalue-tuple",level:4},{value:"Map",id:"clvalue-map",level:4},{value:"URef",id:"clvalue-uref",level:4},{value:"PublicKey",id:"clvalue-publickey",level:4},{value:"Key",id:"clvalue-key",level:4},{value:"CLType",id:"clvalue-cltype",level:4},{value:"CLValue",id:"clvalue-clvalue",level:4},{value:"Contracts",id:"global-state-contracts",level:3},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"serialization-standard-head",children:"Serialization Standard"})}),"\n",(0,s.jsx)(n.p,{children:"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This document details how this custom serialization is implemented, allowing developers to build a library that implements the custom serialization."}),"\n",(0,s.jsxs)(n.p,{children:["In your smart contracts, you can implement serialization using ",(0,s.jsx)(n.code,{children:"cltype-any"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-account",children:"Account"}),"\n",(0,s.jsx)(n.p,{children:"An Account is a structure that represents a user on a Casper network. The account structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"main_purse"})}),"\n",(0,s.jsxs)(n.p,{children:["The account's main purse ",(0,s.jsx)(n.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(n.code,{children:"URef"})," serialization ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#action-thresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."]}),"\n",(0,s.jsx)(n.h2,{id:"action-thresholds",children:"Action Thresholds"}),"\n",(0,s.jsxs)(n.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as two consecutive ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deployment"})," The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(n.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key_management"})," The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(n.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"activation-point",children:"Activation Point"}),"\n",(0,s.jsxs)(n.p,{children:["The first era to which the associated protocol version applies. It serializes as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,s.jsx)(n.code,{children:"timestamp"}),". If not, the bytes represent an ",(0,s.jsx)(n.code,{children:"era_id"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_id"})," An ",(0,s.jsx)(n.a,{href:"#eraid",children:"Era ID newtype"})," identifying the era when the protocol version will activate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"timestamp"})," A ",(0,s.jsx)(n.a,{href:"#timestamp",children:"timestamp"})," if the activation point is of the Genesis variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"signature"})," The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"Signature"})}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"signer"})," The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsxs)(n.p,{children:["A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"account_hash"})," The ",(0,s.jsx)(n.a,{href:"#account-hash",children:"account hash"})," of the associated key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"weight"})," The weight of an associated key. The weight serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsxs)(n.p,{children:["An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u64"})," values"]})," containing the following two fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"high"})," - The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The validator's public key. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The purse used for bonding. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"Uref"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"staked_amount"})," The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate of the bid. It serializes as an ",(0,s.jsx)(n.code,{children:"i32"})," signed 32-bit integer primitive."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"vesting_schedule"})," The vesting schedule for a genesis validator. ",(0,s.jsx)(n.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegators"})," The validator's delegators, indexed by their public keys. They are serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(n.code,{children:"PublicKey"}),"s and then delegators of the length dictated by the first four bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," If the validator has been evicted. A ",(0,s.jsx)(n.a,{href:"#clvalue-boolean",children:"boolean"})," value that serializes as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block is the core component of the Casper linear blockchain, used in two contexts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(n.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(n.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(n.p,{children:"A block is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": A hash over the header of the block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": The header of the block that contains information about the contents of the block with additional metadata."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body"}),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"block-hash",children:"Block hash"}),"\n",(0,s.jsxs)(n.p,{children:["The block hash is a ",(0,s.jsx)(n.code,{children:"Digest"})," over the contents of the block Header. The ",(0,s.jsx)(n.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.h3,{id:"block-header",children:"Block header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"parent_hash"}),": is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"parent_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"state_root_hash"}),": is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"body_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"random_bit"}),": is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"accumulated_seed"}),": A seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"accumulated_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_end"}),": contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,s.jsx)(n.code,{children:"None"}),", it serializes to ",(0,s.jsx)(n.em,{children:"0"}),". The serialization of the other case is described in the EraEnd."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": The timestamp from when the block was proposed. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value. The serialization of a ",(0,s.jsx)(n.code,{children:"u64"})," value is described in the CLValues section."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_id"}),": Era ID in which this block was created. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"height"}),": The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"protocol_version"}),": The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,s.jsx)(n.code,{children:"u32"})," values. It serializes as a buffer containing the three ",(0,s.jsx)(n.code,{children:"u32"})," serialized values. Refer to the CLValues section on how ",(0,s.jsx)(n.code,{children:"u32"})," values are serialized."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-era-end",children:"EraEnd"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraEnd"})," as represented within the block header, is a struct containing two fields."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_report"}),": The first field is termed as ",(0,s.jsx)(n.code,{children:"EraReport"})," and contains information about equivocators and rewards for an era."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"next_era_validator_weights"}),": The second field is map for the validators and their weights for the era to follow."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraReport"})," itself contains two fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When serializing the overarching struct of ",(0,s.jsx)(n.code,{children:"EraEnd"}),", we first allocate a buffer, which contains the serialized representation of the ",(0,s.jsx)(n.code,{children:"EraReport"})," as described above, followed by the serialized BTreeMap."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"EraEnd"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(n.code,{children:"EraEnd"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(n.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"body",children:"Body"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of the block is structurally defined as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"}),": The PublicKey which proposed this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"}),": Is a vector of hex-encoded hashes identifying Deploys included in this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"}),": Is a vector of hex-encoded hashes identifying Transfers included in this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When we serialize the ",(0,s.jsx)(n.code,{children:"BlockBody"}),", we create a buffer that contains the serialized representations of the individual fields present within the block."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"}),": serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"}),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of deploy hashes present within the body."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"}),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of transfers present within the body."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#block-hash",children:(0,s.jsx)(n.code,{children:"hash"})})," Identify and retrieve a Block with its hash. The ",(0,s.jsx)(n.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," Identify and retrieve the Block with its height. Height serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"state_root_hash"})," Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,s.jsxs)(n.p,{children:["ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,s.jsx)(n.em,{children:"Chainspec.toml"})," and may include ",(0,s.jsx)(n.em,{children:"Accounts.toml"})," and ",(0,s.jsx)(n.em,{children:"GlobalState.toml"}),". It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(n.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"chainspec_raw_hash"})," will always be included."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"genesis_accounts_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"global_state_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct containing the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."]}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."]}),"\n",(0,s.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})})," The contract hash of the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"contract_version"})," The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."]}),"\n",(0,s.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegator_public_key"})," The public key of the delegator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"staked_amount"})," The amount staked by the delegator, serialized as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-uref",children:[(0,s.jsx)(n.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"vesting_schedule"})," The vesting schedule for the provided delegator bid. ",(0,s.jsx)(n.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": The hash of the deploy header."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": Contains metadata about the deploy. The structure of the header is detailed further in this document."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment"}),": The payment code for contained smart contract."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session"}),": The stored contract itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approvals"}),": A list of signatures:"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-hash",children:"Deploy-Hash"}),"\n",(0,s.jsx)(n.p,{children:"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(n.h3,{id:"deploy-header",children:"Deploy-Header"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"account"}),": A supported public key variant (currently either ",(0,s.jsx)(n.code,{children:"Ed25519"})," or ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"). An ",(0,s.jsx)(n.code,{children:"Ed25519"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"1"})," for ",(0,s.jsx)(n.code,{children:"Ed25519"}),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(n.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(n.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(n.code,{children:"0xbd3a847575010000"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ttl"}),": The ",(0,s.jsx)(n.strong,{children:"Time to live"})," is defined as the amount of time for which deploy is considered valid. The ",(0,s.jsx)(n.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"gas_price"}),": The gas is ",(0,s.jsx)(n.code,{children:"u64"})," value which is serialized as ",(0,s.jsx)(n.code,{children:"u64"})," CLValue discussed below."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"dependencies"}),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"payment--session",children:"Payment & Session"}),"\n",(0,s.jsxs)(n.p,{children:["Payment and Session are both defined as ",(0,s.jsx)(n.code,{children:"ExecutableDeployItems"}),". More information on ",(0,s.jsx)(n.code,{children:"ExecutableDeployItems"})," can be found ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/calling-contracts",children:"here"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Module Bytes are serialized such that the first byte within the serialized buffer is ",(0,s.jsx)(n.code,{children:"0"})," with the rest of the buffer containing the bytes present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'ModuleBytes { module_bytes: "[72 bytes]", args: 434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5 }'})," will serialize to"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x0048000000420481b0d5a665c8a7678398103d4333c684461a71e9ee2a13f6e859fb6cd419ed5f8876fc6c3e12dce4385acc777edf42dcf8d8d844bf6a704e5b2446750559911a4a328d649ddd48000000434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"StoredContractByHash serializes such that the first byte within the serialized buffer is 1u8. This is followed by the byte representation of the remaining fields."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredContractByHash { hash: c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa4, entry_point: "pclphXwfYmCmdITj8hnh", args: d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x01c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa41400000070636c7068587766596d436d6449546a38686e685d000000d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"StoredContractByName serializes such that the first byte within the serialized buffer is 2u8. This is followed by the individual byte representation of the remaining fields."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredContractByName { name: "U5A74bSZH8abT8HqVaK9", entry_point: "gIetSxltnRDvMhWdxTqQ", args: 07beadc3da884faa17454a }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x0214000000553541373462535a483861625438487156614b39140000006749657453786c746e5244764d685764785471510b00000007beadc3da884faa17454a"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["StoredVersionedContractByHash serializes such that the first byte within the serialized buffer is 3u8. However, the field version within the enum serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:"Option"})," CLValue."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredVersionedContractByHash { hash: b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423, version: None, entry_point: "PsLz5c7JsqT8BK8ll0kF", args: 3d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x03b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423001400000050734c7a3563374a73715438424b386c6c306b463b0000003d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["StoredVersionedContractByName serializes such that the first byte within the serialized buffer is 4u8. The name and entry_point are serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:"String"})," CLValue, with the version field serializing as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:"Option"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredVersionedContractByName { name: "lWJWKdZUEudSakJzw1tn", version: Some(1632552656), entry_point: "S1cXRT3E1jyFlWBAIVQ8", args: 9975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x04140000006c574a574b645a5545756453616b4a7a7731746e01d0c64e61140000005331635852543345316a79466c57424149565138270000009975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Transfer serializes such that the first byte within the serialized buffer contains is 5u8, with the remaining bytes of the buffer containing the bytes contained within the args field of Transfer."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"Approval contains two fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(n.code,{children:"Signature"}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to a given deploy. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deploy_hash"})," The hash of the relevant deploy, serialized as a byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," Transfers performed by the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"from"})," The account identifier of the creator of the deploy, serialized as an ",(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"source"})," The source purse used for payment of the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas"})," The gas cost of executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash digest. The digest serializes as a byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,s.jsx)(n.p,{children:"Disabled contract versions, containing the following:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"contract_version"})," The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry point, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"args"})," Arguments for this method. They serialize as a list of the ",(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ret"})," The return type of the method, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-unit",children:(0,s.jsx)(n.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"access"})," An enum describing the possible access control options for a contract entry point. It serializes as a 1 for public or a 1 followed by a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entry_point_type"})," Identifies the type of entry point. It serializes as a ",(0,s.jsx)(n.code,{children:"0"})," for Session and a ",(0,s.jsx)(n.code,{children:"1"})," for Contract."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsxs)(n.p,{children:["An Era ID newtype. It serializes as a single ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u64"})," value"]}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsxs)(n.p,{children:["Auction metadata, intended to be recorded each era. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of ",(0,s.jsx)(n.a,{href:"#seigniorageallocation",children:"seigniorage allocations"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(n.p,{children:"The journal of execution transforms from a single deploy."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"operations"})," The resulting operations, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of ",(0,s.jsx)(n.a,{href:"#operation",children:"operations"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transforms"})," The actual ",(0,s.jsx)(n.a,{href:"#transform",children:"transformation"})," performed while executing a deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,s.jsxs)(n.p,{children:["The result of a single deploy. It serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(n.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(n.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(n.h3,{id:"failure",children:(0,s.jsx)(n.code,{children:"Failure"})}),"\n",(0,s.jsx)(n.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"effect"})," The ",(0,s.jsx)(n.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"cost"})," The cost of executing the deploy, serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"error_message"})," The error message associated with executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"success",children:(0,s.jsx)(n.code,{children:"Success"})}),"\n",(0,s.jsx)(n.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"effect"})," The ",(0,s.jsx)(n.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"cost"})," The cost of executing the deploy, serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,s.jsxs)(n.p,{children:['A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,s.jsx)(n.a,{href:"#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"groups",children:"Groups"}),"\n",(0,s.jsxs)(n.p,{children:["They are serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of user groups and ",(0,s.jsx)(n.code,{children:"BTreeSets"})," of ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,s.jsx)(n.code,{children:"BTreeSets"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-state-keys",children:"Keys"}),"\n",(0,s.jsx)(n.p,{children:'In this chapter, we describe what constitutes a "key", the permissions model for the keys, and how they are serialized.'}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.em,{children:"key"})," in ",(0,s.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"})," is one of the following data types:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'32-byte account identifier (called an "account identity key")'}),"\n",(0,s.jsx)(n.li,{children:'32-byte immutable contract identifier (called a "hash key")'}),"\n",(0,s.jsx)(n.li,{children:'32-byte reference identifier (called an "unforgeable reference")'}),"\n",(0,s.jsx)(n.li,{children:"32-byte transfer identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte deploy information identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte purse balance identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction bid identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction withdrawal identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Dictionary identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte System Contract Registry"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction unbond identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Chainspec Registry"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The one exception to note here is the identifier for ",(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})}),", which actually serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value with an additional byte for the tag."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-account-key",children:"Account identity key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-hash-key",children:"Hash key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the deploy hash (see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"block-structure-head"})," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."]}),"\n",(0,s.jsxs)(n.h3,{id:"serialization-standard-uref",children:["Unforgeable Reference (",(0,s.jsx)(n.code,{children:"URef"}),")"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,s.jsx)(n.code,{children:"URef"}),". ",(0,s.jsx)(n.code,{children:"URef"})," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,s.jsx)(n.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#uref-head",children:"Unforgeable Reference"})," section for details on how ",(0,s.jsx)(n.code,{children:"URefs"})," are managed."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-transfer-key",children:"Transfer Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the transfer address associated with the given transfer"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-deploy-info-key",children:"DeployInfo Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the deploy itself."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-era-info-key",children:"EraInfo Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to the ",(0,s.jsx)(n.code,{children:"Auction"})," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,s.jsx)(n.code,{children:"u64"})," data type and co-relates to the era number when the auction information was stored."]}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(n.h3,{id:"serialization-standard-serialization-key",children:["Serialization for ",(0,s.jsx)(n.code,{children:"Key"})]}),"\n",(0,s.jsxs)(n.p,{children:["Given the different variants for the over-arching ",(0,s.jsx)(n.code,{children:"Key"})," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Account"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Hash"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Transfer"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DeployInfo"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"EraInfo"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Balance"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bid"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Withdraw"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Dictionary"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SystemContractRegistry"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unbond"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ChainspecRegistry"})}),(0,s.jsx)(n.td,{children:"12"})]})]})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Account"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(n.code,{children:"AccountHash"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Hash"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(n.code,{children:"Hash"})," itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"URef"})," is a tuple that contains the address of the URef and the access rights to that ",(0,s.jsx)(n.code,{children:"URef"}),". The serialized representation of the ",(0,s.jsx)(n.code,{children:"URef"})," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,s.jsx)(n.code,{children:"URef"})," address, and the last byte contains the bits corresponding to the access rights of the ",(0,s.jsx)(n.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(n.a,{href:"#serialization-standard-values",children:"CLValue"})," section of this chapter for details on how ",(0,s.jsx)(n.code,{children:"AccessRights"})," are serialized."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Transfer"})," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"DeployInfo"})," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"EraInfo"})," serializes a ",(0,s.jsx)(n.code,{children:"u64"})," primitive type containing the little-endian byte representation of ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Balance"})," serializes as 32 byte long buffer containing the byte representation of the URef address."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Bid"})," and ",(0,s.jsx)(n.code,{children:"Withdraw"})," both contain the ",(0,s.jsx)(n.code,{children:"AccountHash"})," as their identifier; therefore, they serialize in the same manner as the ",(0,s.jsx)(n.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Dictionary"})," as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"SystemContractRegistry"})," as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Unbond"})," contains the ",(0,s.jsx)(n.code,{children:"AccountHash"})," as its identifier; therefore, it serialize in the same manner as the ",(0,s.jsx)(n.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ChainspecRegistry"})," as a 32 byte long buffer of ones."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-permissions",children:"Permissions"}),"\n",(0,s.jsxs)(n.p,{children:["There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,s.jsx)(n.em,{children:"add"})," to be called out separately from ",(0,s.jsx)(n.em,{children:"write"})," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Key"}),(0,s.jsx)(n.th,{children:"Type Available Actions"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Account"}),(0,s.jsx)(n.td,{children:"Read + Add (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hash"}),(0,s.jsx)(n.td,{children:"Read"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"URef"}),(0,s.jsx)(n.td,{children:"Read + Write and/or Add"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Transfer"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Deploy"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"EraInfo"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Balance"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Bid"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Withdraw"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Dictionary"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SystemContractRegistry"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Unbond"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"ChainspecRegistry"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["Refer to ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#uref-permissions",children:"URef permissions"})," on how permissions are handled in the case of ",(0,s.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,s.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsxs)(n.p,{children:["Named arguments to a contract. It is serialized by the combination of a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})})," followed by the associated ",(0,s.jsx)(n.a,{href:"#clvalue-clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsxs)(n.p,{children:["A mapping of string identifiers to a Casper ",(0,s.jsx)(n.code,{children:"Key"})," type. It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The value of the entry, which is a Casper ",(0,s.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,s.jsx)(n.code,{children:"Key"})," values as described ",(0,s.jsx)(n.a,{href:"#serialization-standard-serialization-key",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(n.p,{children:"An operation performed while executing a deploy. It contains:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the key, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"kind"})," OpKind, The type of operation performed. It serializes as a single byte based on the following table:"]}),"\n"]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"OpKind"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Read"}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write"}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add"}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"NoOp"}),(0,s.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsxs)(n.p,{children:["Parameter to a method, structured as a name followed by a ",(0,s.jsx)(n.code,{children:"CLType"}),". It is serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})})," followed by a ",(0,s.jsx)(n.a,{href:"#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"CLType"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})," values indicating major, minor and patch versions in that order."]}),"\n",(0,s.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:["Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsxs)(n.p,{children:["Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," comprised of ",(0,s.jsx)(n.a,{href:"#clvalue-tuple",children:(0,s.jsx)(n.code,{children:"Tuples"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(n.p,{children:"Information about seigniorage allocation."}),"\n",(0,s.jsxs)(n.p,{children:["If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})," followed by the ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If it is a delegator, it serializes as the delegator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),", followed by the validator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})," and finally the ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsxs)(n.p,{children:["The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,s.jsxs)(n.p,{children:["SystemContractRegistry is a unique ",(0,s.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ",(0,s.jsx)(n.code,{children:"ContractHashes"})," for system contracts. This includes ",(0,s.jsx)(n.code,{children:"Mint"}),", ",(0,s.jsx)(n.code,{children:"Auction"}),", ",(0,s.jsx)(n.code,{children:"HandlePayment"})," and ",(0,s.jsx)(n.code,{children:"StandardPayment"}),". It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(n.a,{href:"#contracthash",children:"ContractHashes"})," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsxs)(n.p,{children:["A human-readable duration between two timestamps. It serializes as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsxs)(n.p,{children:["A timestamp formatted as per RFC 3339 and serialized as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded transfer address, which serializes as a byte representation of itself."}),"\n",(0,s.jsx)(n.h2,{id:"transform",children:"Transform"}),"\n",(0,s.jsxs)(n.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(n.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Transform Type"}),(0,s.jsx)(n.th,{children:"Serialization"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Identity"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"A transform having no effect."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_CLValue"}),(0,s.jsx)(n.td,{children:"1"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#clvalue-clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Account"}),(0,s.jsx)(n.td,{children:"2"}),(0,s.jsxs)(n.td,{children:["Write the given ",(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"Account"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract_WASM"}),(0,s.jsx)(n.td,{children:"3"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contractwasmhash",children:"contract as Wasm"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract"}),(0,s.jsx)(n.td,{children:"4"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contracthash",children:"contract"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract_Package"}),(0,s.jsx)(n.td,{children:"5"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contractpackagehash",children:"contract package"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Deploy_Info"}),(0,s.jsx)(n.td,{children:"6"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#deployinfo",children:(0,s.jsx)(n.code,{children:"DeployInfo"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Transfer"}),(0,s.jsx)(n.td,{children:"7"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#transferaddr",children:"Transfer"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Era_Info"}),(0,s.jsx)(n.td,{children:"8"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Bid"}),(0,s.jsx)(n.td,{children:"9"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"Bid"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Withdraw"}),(0,s.jsx)(n.td,{children:"10"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_INT32"}),(0,s.jsx)(n.td,{children:"11"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT64"}),(0,s.jsx)(n.td,{children:"12"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT128"}),(0,s.jsx)(n.td,{children:"13"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT256"}),(0,s.jsx)(n.td,{children:"14"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT512"}),(0,s.jsx)(n.td,{children:"15"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_Keys"}),(0,s.jsx)(n.td,{children:"16"}),(0,s.jsxs)(n.td,{children:["Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Failure"}),(0,s.jsx)(n.td,{children:"17"}),(0,s.jsx)(n.td,{children:"A failed transformation, containing an error message."})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a deploy."}),"\n",(0,s.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(n.p,{children:"A purse used for unbonding. The structure consists of the following:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"unbonder_public_key"})," The public key of the unbonder, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"new_validator"})," The validator public key to redelegate to, serialized as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})})," containing the public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-values",children:"Values"}),"\n",(0,s.jsxs)(n.p,{children:["A value stored in the global state is a ",(0,s.jsx)(n.code,{children:"StoredValue"}),". A ",(0,s.jsx)(n.code,{children:"StoredValue"})," is one of three possible variants:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"CLValue"})]}),"\n",(0,s.jsx)(n.li,{children:"A contract"}),"\n",(0,s.jsx)(n.li,{children:"An account"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["We discuss ",(0,s.jsx)(n.code,{children:"CLValue"})," and contract in more detail below. Details about accounts can be found in ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"accounts-head"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Each ",(0,s.jsx)(n.code,{children:"StoredValue"})," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,s.jsx)(n.code,{children:"StoredValue"})," it is, followed by the serialization of that variant. The tag for each variant is as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," is ",(0,s.jsx)(n.code,{children:"0"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Account"})," is ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Contract"})," is ",(0,s.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The details of ",(0,s.jsx)(n.code,{children:"CLType"})," serialization are in the following section. Using the serialization format for ",(0,s.jsx)(n.code,{children:"CLValue"})," as a basis, we can succinctly write the serialization rules for contracts and accounts:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["contracts serialize in the same way as data with ",(0,s.jsx)(n.code,{children:"CLType"})," equal to ",(0,s.jsx)(n.code,{children:"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"}),";"]}),"\n",(0,s.jsxs)(n.li,{children:["accounts serialize in the same way as data with ",(0,s.jsx)(n.code,{children:"CLType"})," equal to ",(0,s.jsx)(n.code,{children:"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Note: ",(0,s.jsx)(n.code,{children:"Tuple5"})," is not a presently supported ",(0,s.jsx)(n.code,{children:"CLType"}),". However, it is clear how to generalize the rules for ",(0,s.jsx)(n.code,{children:"Tuple1"}),", ",(0,s.jsx)(n.code,{children:"Tuple2"}),", ",(0,s.jsx)(n.code,{children:"Tuple3"})," to any size tuple."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," is used to describe data that is used by smart contracts. This could be as a local state variable, input argument, or return value. A ",(0,s.jsx)(n.code,{children:"CLValue"})," consists of two parts: a ",(0,s.jsx)(n.code,{children:"CLType"})," describing the type of the value and an array of bytes representing the data in our serialization format."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," is described by the following recursive data type:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All data which can be assigned a (non-",(0,s.jsx)(n.code,{children:"Any"}),") ",(0,s.jsx)(n.code,{children:"CLType"})," can be serialized according to the following rules (this defines the Casper serialization format):"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-boolean",children:"Boolean"}),"\n",(0,s.jsxs)(n.p,{children:["Boolean values serialize as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-numeric",children:"Numeric"}),"\n",(0,s.jsx)(n.p,{children:"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u8"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"1024u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00040000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Wider numeric values (i.e. ",(0,s.jsx)(n.code,{children:"U128"}),", ",(0,s.jsx)(n.code,{children:"U256"}),", ",(0,s.jsx)(n.code,{children:"U512"}),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This is done to reduce the serialization size when small numbers are represented within a wide data type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(7)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x0107"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(1024)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x020004"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:'U512::from("123456789101112131415")'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0957ff1ada959f4eb106"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-unit",children:"Unit"}),"\n",(0,s.jsx)(n.p,{children:"Unit serializes to an empty byte array."}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-string",children:"String"}),"\n",(0,s.jsx)(n.p,{children:"Strings serialize as a 32-bit integer representing the length in bytes (note: this might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:'"Hello, World!"'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0d00000048656c6c6f2c20576f726c6421"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-option",children:"Option"}),"\n",(0,s.jsxs)(n.p,{children:["Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,s.jsx)(n.code,{children:"0"})," if the value is missing, and ",(0,s.jsx)(n.code,{children:"1"})," if it is present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"None"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"Some(10u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010a000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-list",children:"List"}),"\n",(0,s.jsxs)(n.p,{children:["A list of values serializes as a 32-bit integer representing the number of elements in the list (note this differs from strings where it gives the number of ",(0,s.jsx)(n.em,{children:"bytes"}),"), followed by the concatenation of each serialized element."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List()"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00000000"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List(1u32, 2u32, 3u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x03000000010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-ByteArray",children:"ByteArray"}),"\n",(0,s.jsx)(n.p,{children:"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"[1u32, 2u32, 3u32]"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-result",children:"Result"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Result"})," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,s.jsx)(n.code,{children:"1"})," for the success variant and ",(0,s.jsx)(n.code,{children:"0"})," for the error variant."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n'})}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-tuple",children:"Tuple"}),"\n",(0,s.jsxs)(n.p,{children:["Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,s.jsx)(n.code,{children:"ByteArray"})," the number of elements is not included in the serialization because it is statically known in the type."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n'})}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-map",children:"Map"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Map"})," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,s.jsx)(n.code,{children:"Map"})," data structures can be unordered."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-uref",children:"URef"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," values serialize as the concatenation of its address (which is a fixed-length list of ",(0,s.jsx)(n.code,{children:"u8"}),") and a single byte tag representing the access rights. Access rights are converted as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Access Rights"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"NONE"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WRITE"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_WRITE"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"7"})]})]})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"- E.g. `uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007` shows a `URef` with full `READ_ADD_WRITE` rights.\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["When passing a URef to another entity on chain, you must ensure that the ",(0,s.jsx)(n.code,{children:"AccessRights"})," are set correctly. If the URef represents a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/P#purse",children:"purse"}),", ",(0,s.jsx)(n.code,{children:"AccessRights"})," impact who can deposit and withdraw CSPR."]})}),"\n",(0,s.jsxs)(n.p,{children:["If a passed URef contains ",(0,s.jsx)(n.code,{children:"ADD"})," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions. In this event, ",(0,s.jsx)(n.code,{children:"READ"})," and ",(0,s.jsx)(n.code,{children:"ADD"})," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions unintentionally."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PublicKey"})," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,s.jsx)(n.code,{children:"PublicKey"})," itself:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"System"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"0"}),". With this variant, the single byte of ",(0,s.jsx)(n.code,{children:"0"})," is the entire key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the single tag byte is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-key",children:"Key"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Key"})," values serialize as a single byte tag representing the variant, followed by the serialization of the data that variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,s.jsx)(n.code,{children:"Key::URef"}),", which contains a ",(0,s.jsx)(n.code,{children:"URef"}),"; so its data serializes per the description above. The tags are as follows: ",(0,s.jsx)(n.code,{children:"Key::Account"})," serializes as ",(0,s.jsx)(n.code,{children:"0"}),", ",(0,s.jsx)(n.code,{children:"Key::Hash"})," as ",(0,s.jsx)(n.code,{children:"1"}),", ",(0,s.jsx)(n.code,{children:"Key::URef"})," as ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-cltype",children:"CLType"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," itself also has rules for serialization. A ",(0,s.jsx)(n.code,{children:"CLType"})," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,s.jsx)(n.code,{children:"ByteArray"})," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"CLType"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I32"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I64"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U8"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U32"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U64"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U128"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U256"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U512"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unit"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"12"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Option"})}),(0,s.jsx)(n.td,{children:"13"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"List"})}),(0,s.jsx)(n.td,{children:"14"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ByteArray"})}),(0,s.jsx)(n.td,{children:"15"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Result"})}),(0,s.jsx)(n.td,{children:"16"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Map"})}),(0,s.jsx)(n.td,{children:"17"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple1"})}),(0,s.jsx)(n.td,{children:"18"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple2"})}),(0,s.jsx)(n.td,{children:"19"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple3"})}),(0,s.jsx)(n.td,{children:"20"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Any"})}),(0,s.jsx)(n.td,{children:"21"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PublicKey"})}),(0,s.jsx)(n.td,{children:"22"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-clvalue",children:"CLValue"}),"\n",(0,s.jsxs)(n.p,{children:["A complete ",(0,s.jsx)(n.code,{children:"CLValue"}),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-contracts",children:"Contracts"}),"\n",(0,s.jsxs)(n.p,{children:["Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,s.jsx)(n.em,{children:"contract"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a ",(0,s.jsx)(n.a,{href:"https://webassembly.github.io/spec/core/syntax/modules.html",children:"wasm module"})]}),"\n",(0,s.jsx)(n.li,{children:"a collection of named keys"}),"\n",(0,s.jsx)(n.li,{children:"a protocol version"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The wasm module must contain a function named ",(0,s.jsx)(n.code,{children:"call"}),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-runtime",children:"Casper runtime"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note: though the ",(0,s.jsx)(n.code,{children:"call"})," function signature has no arguments and no return value, within the ",(0,s.jsx)(n.code,{children:"call"})," function body, the ",(0,s.jsx)(n.code,{children:"get_named_arg"})," runtime function can be used to accept arguments (by ordinal), and the ",(0,s.jsx)(n.code,{children:"ret"})," runtime function can be used to return a single ",(0,s.jsx)(n.code,{children:"CLValue"})," to the caller."]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,s.jsx)(n.code,{children:"URef"}),"s, which are known to the contract (see the section on Permissions for details)."]}),"\n",(0,s.jsx)(n.p,{children:"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."}),"\n",(0,s.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsxs)(n.p,{children:["A purse used for unbonding, replaced in 1.5 by ",(0,s.jsx)(n.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"unbonder_public_key"})," The public key of the unbonder, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>t});var s=i(96540);const r={},l=s.createContext(r);function d(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d2039ef8.e3054ff4.js b/assets/js/d2039ef8.e3054ff4.js new file mode 100644 index 000000000..188643f92 --- /dev/null +++ b/assets/js/d2039ef8.e3054ff4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[85354],{15377:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>o,frontMatter:()=>l,metadata:()=>t,toc:()=>a});var s=i(74848),r=i(28453);const l={},d="Serialization Standard {#serialization-standard-head}",t={id:"concepts/serialization-standard",title:"Serialization Standard",description:"serialization-standard-head}",source:"@site/versioned_docs/version-1.5.X/concepts/serialization-standard.md",sourceDirName:"concepts",slug:"/concepts/serialization-standard",permalink:"/1.5.X/concepts/serialization-standard",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Dictionaries",permalink:"/1.5.X/concepts/dictionaries"},next:{title:"Design Overview",permalink:"/1.5.X/design"}},c={},a=[{value:"Account",id:"serialization-standard-account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Action Thresholds",id:"action-thresholds",level:2},{value:"Activation Point",id:"activation-point",level:2},{value:"Approval",id:"approval",level:2},{value:"AssociatedKey",id:"associatedkey",level:2},{value:"AvailableBlockRange",id:"availableblockrange",level:2},{value:"Bid",id:"bid",level:2},{value:"Block",id:"serialization-standard-block",level:2},{value:"Block hash",id:"block-hash",level:3},{value:"Block header",id:"block-header",level:3},{value:"EraEnd",id:"serialization-standard-era-end",level:3},{value:"Body",id:"body",level:3},{value:"BlockIdentifier",id:"blockidentifier",level:2},{value:"ChainspecRegistry",id:"chainspecregistry",level:2},{value:"Contract",id:"contract",level:2},{value:"ContractHash",id:"contracthash",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:2},{value:"ContractVersion",id:"contractversion",level:2},{value:"ContractWasmHash",id:"contractwasmhash",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"serialization-standard-deploy",level:2},{value:"Deploy-Hash",id:"deploy-hash",level:3},{value:"Deploy-Header",id:"deploy-header",level:3},{value:"Payment & Session",id:"payment--session",level:3},{value:"Approval",id:"approval",level:3},{value:"DeployInfo",id:"deployinfo",level:2},{value:"Digest",id:"digest",level:2},{value:"DisabledVersions",id:"disabledversions",level:2},{value:"EntryPoint",id:"entrypoint",level:2},{value:"EraID",id:"eraid",level:2},{value:"EraInfo",id:"erainfo",level:2},{value:"ExecutionEffect",id:"executioneffect",level:2},{value:"ExecutionResult",id:"executionresult",level:2},{value:"<code>Failure</code>",id:"failure",level:3},{value:"<code>Success</code>",id:"success",level:3},{value:"Group",id:"group",level:2},{value:"Groups",id:"groups",level:2},{value:"Keys",id:"serialization-standard-state-keys",level:2},{value:"Account identity key",id:"global-state-account-key",level:3},{value:"Hash key",id:"serialization-standard-hash-key",level:3},{value:"Unforgeable Reference (<code>URef</code>)",id:"serialization-standard-uref",level:3},{value:"Transfer Key",id:"serialization-standard-transfer-key",level:3},{value:"DeployInfo Key",id:"serialization-standard-deploy-info-key",level:3},{value:"EraInfo Key",id:"serialization-standard-era-info-key",level:3},{value:"Serialization for <code>Key</code>",id:"serialization-standard-serialization-key",level:3},{value:"Permissions",id:"serialization-standard-permissions",level:2},{value:"NamedArg",id:"namedarg",level:2},{value:"NamedKey",id:"namedkey",level:2},{value:"Operation",id:"operation",level:2},{value:"Parameter",id:"parameter",level:2},{value:"ProtocolVersion",id:"protocolversion",level:2},{value:"PublicKey",id:"publickey",level:2},{value:"RuntimeArgs",id:"runtimeargs",level:2},{value:"SeigniorageAllocation",id:"seigniorageallocation",level:2},{value:"Signature",id:"signature",level:2},{value:"SystemContractRegistry",id:"systemcontractregistry",level:2},{value:"TimeDiff",id:"timediff",level:2},{value:"Timestamp",id:"timestamp",level:2},{value:"TransferAddr",id:"transferaddr",level:2},{value:"Transform",id:"transform",level:2},{value:"TransformEntry",id:"transformentry",level:2},{value:"UnbondingPurse",id:"unbondingpurse",level:2},{value:"Values",id:"serialization-standard-values",level:2},{value:"<code>CLValue</code>",id:"clvalue",level:3},{value:"Boolean",id:"clvalue-boolean",level:4},{value:"Numeric",id:"clvalue-numeric",level:4},{value:"Unit",id:"clvalue-unit",level:4},{value:"String",id:"clvalue-string",level:4},{value:"Option",id:"clvalue-option",level:4},{value:"List",id:"clvalue-list",level:4},{value:"ByteArray",id:"clvalue-ByteArray",level:4},{value:"Result",id:"clvalue-result",level:4},{value:"Tuple",id:"clvalue-tuple",level:4},{value:"Map",id:"clvalue-map",level:4},{value:"URef",id:"clvalue-uref",level:4},{value:"PublicKey",id:"clvalue-publickey",level:4},{value:"Key",id:"clvalue-key",level:4},{value:"CLType",id:"clvalue-cltype",level:4},{value:"CLValue",id:"clvalue-clvalue",level:4},{value:"Contracts",id:"global-state-contracts",level:3},{value:"WithdrawPurse",id:"withdrawpurse",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"serialization-standard-head",children:"Serialization Standard"})}),"\n",(0,s.jsx)(n.p,{children:"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This document details how this custom serialization is implemented, allowing developers to build a library that implements the custom serialization."}),"\n",(0,s.jsxs)(n.p,{children:["In your smart contracts, you can implement serialization using ",(0,s.jsx)(n.code,{children:"cltype-any"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-account",children:"Account"}),"\n",(0,s.jsx)(n.p,{children:"An Account is a structure that represents a user on a Casper network. The account structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.code,{children:"main_purse"})}),"\n",(0,s.jsxs)(n.p,{children:["The account's main purse ",(0,s.jsx)(n.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(n.code,{children:"URef"})," serialization ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#associatedkey",children:(0,s.jsx)(n.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#action-thresholds",children:(0,s.jsx)(n.code,{children:"action_thresholds"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of the public key, representing the address of a user's account. The account hash serializes as a 32-byte buffer containing the bytes of the account hash."]}),"\n",(0,s.jsx)(n.h2,{id:"action-thresholds",children:"Action Thresholds"}),"\n",(0,s.jsxs)(n.p,{children:["The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as two consecutive ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u8"})," values"]})," as follows."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deployment"})," The minimum weight threshold required to perform deployment actions as a ",(0,s.jsx)(n.code,{children:"u8"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key_management"})," The minimum weight threshold required to perform key management actions as a ",(0,s.jsx)(n.code,{children:"u8"})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"activation-point",children:"Activation Point"}),"\n",(0,s.jsxs)(n.p,{children:["The first era to which the associated protocol version applies. It serializes as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u8"})})," tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a ",(0,s.jsx)(n.code,{children:"timestamp"}),". If not, the bytes represent an ",(0,s.jsx)(n.code,{children:"era_id"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_id"})," An ",(0,s.jsx)(n.a,{href:"#eraid",children:"Era ID newtype"})," identifying the era when the protocol version will activate."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"timestamp"})," A ",(0,s.jsx)(n.a,{href:"#timestamp",children:"timestamp"})," if the activation point is of the Genesis variant."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"A struct containing a signature and the public key of the signer."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"signature"})," The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(n.a,{href:"#signature",children:(0,s.jsx)(n.code,{children:"Signature"})}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"signer"})," The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"associatedkey",children:"AssociatedKey"}),"\n",(0,s.jsxs)(n.p,{children:["A key granted limited permissions to an Account, for purposes such as multisig. It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of keys and weights held within. The remainder consists of a repeating pattern of serialized named keys and then weights of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"account_hash"})," The ",(0,s.jsx)(n.a,{href:"#account-hash",children:"account hash"})," of the associated key."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"weight"})," The weight of an associated key. The weight serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u8"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"availableblockrange",children:"AvailableBlockRange"}),"\n",(0,s.jsxs)(n.p,{children:["An unbroken, inclusive range of blocks. It serializes as two consecutive ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u64"})," values"]})," containing the following two fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"low"})," The inclusive lower bound of the range."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"high"})," - The inclusive upper bound of the range."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"bid",children:"Bid"}),"\n",(0,s.jsx)(n.p,{children:"An entry in the validator map. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The validator's public key. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The purse used for bonding. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"Uref"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"staked_amount"})," The amount of tokens staked by a validator (not including delegators). It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegation_rate"})," The delegation rate of the bid. It serializes as an ",(0,s.jsx)(n.code,{children:"i32"})," signed 32-bit integer primitive."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"vesting_schedule"})," The vesting schedule for a genesis validator. ",(0,s.jsx)(n.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegators"})," The validator's delegators, indexed by their public keys. They are serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"s and delegators held within. The remainder consists of a repeating pattern of serialized ",(0,s.jsx)(n.code,{children:"PublicKey"}),"s and then delegators of the length dictated by the first four bytes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"inactive"})," If the validator has been evicted. A ",(0,s.jsx)(n.a,{href:"#clvalue-boolean",children:"boolean"})," value that serializes as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-block",children:"Block"}),"\n",(0,s.jsx)(n.p,{children:"A block is the core component of the Casper linear blockchain, used in two contexts:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(n.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(n.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(n.p,{children:"A block is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": A hash over the header of the block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": The header of the block that contains information about the contents of the block with additional metadata."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body"}),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"block-hash",children:"Block hash"}),"\n",(0,s.jsxs)(n.p,{children:["The block hash is a ",(0,s.jsx)(n.code,{children:"Digest"})," over the contents of the block Header. The ",(0,s.jsx)(n.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.h3,{id:"block-header",children:"Block header"}),"\n",(0,s.jsx)(n.p,{children:"The header portion of a block, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"parent_hash"}),": is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"parent_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"state_root_hash"}),": is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"body_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"random_bit"}),": is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"accumulated_seed"}),": A seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,s.jsx)(n.code,{children:"accumulated_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_end"}),": contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,s.jsx)(n.code,{children:"None"}),", it serializes to ",(0,s.jsx)(n.em,{children:"0"}),". The serialization of the other case is described in the EraEnd."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": The timestamp from when the block was proposed. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value. The serialization of a ",(0,s.jsx)(n.code,{children:"u64"})," value is described in the CLValues section."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_id"}),": Era ID in which this block was created. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"height"}),": The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"protocol_version"}),": The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,s.jsx)(n.code,{children:"u32"})," values. It serializes as a buffer containing the three ",(0,s.jsx)(n.code,{children:"u32"})," serialized values. Refer to the CLValues section on how ",(0,s.jsx)(n.code,{children:"u32"})," values are serialized."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-era-end",children:"EraEnd"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraEnd"})," as represented within the block header, is a struct containing two fields."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"era_report"}),": The first field is termed as ",(0,s.jsx)(n.code,{children:"EraReport"})," and contains information about equivocators and rewards for an era."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"next_era_validator_weights"}),": The second field is map for the validators and their weights for the era to follow."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"EraReport"})," itself contains two fields:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(n.code,{children:"PublicKey"})," and ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the first byte within the buffer is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When serializing the overarching struct of ",(0,s.jsx)(n.code,{children:"EraEnd"}),", we first allocate a buffer, which contains the serialized representation of the ",(0,s.jsx)(n.code,{children:"EraReport"})," as described above, followed by the serialized BTreeMap."]}),"\n",(0,s.jsxs)(n.p,{children:["Note that ",(0,s.jsx)(n.code,{children:"EraEnd"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(n.code,{children:"EraEnd"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(n.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"body",children:"Body"}),"\n",(0,s.jsx)(n.p,{children:"The body portion of the block is structurally defined as:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"}),": The PublicKey which proposed this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"}),": Is a vector of hex-encoded hashes identifying Deploys included in this block."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"}),": Is a vector of hex-encoded hashes identifying Transfers included in this block."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["When we serialize the ",(0,s.jsx)(n.code,{children:"BlockBody"}),", we create a buffer that contains the serialized representations of the individual fields present within the block."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"proposer"}),": serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"deploy_hashes"}),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of deploy hashes present within the body."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_hashes"}),": serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(n.code,{children:"32 * n"}),", where n denotes the number of transfers present within the body."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"blockidentifier",children:"BlockIdentifier"}),"\n",(0,s.jsx)(n.p,{children:"Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#block-hash",children:(0,s.jsx)(n.code,{children:"hash"})})," Identify and retrieve a Block with its hash. The ",(0,s.jsx)(n.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"height"})," Identify and retrieve the Block with its height. Height serializes as a single ",(0,s.jsx)(n.code,{children:"u64"})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"state_root_hash"})," Identify and retrieve the Block with its state root hash. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chainspecregistry",children:"ChainspecRegistry"}),"\n",(0,s.jsxs)(n.p,{children:["ChainspecRegistry is a unique key variant which contains a mapping of file names to the hash of the file itself. This map includes ",(0,s.jsx)(n.em,{children:"Chainspec.toml"})," and may include ",(0,s.jsx)(n.em,{children:"Accounts.toml"})," and ",(0,s.jsx)(n.em,{children:"GlobalState.toml"}),". It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(n.a,{href:"#digest",children:"digests"})," held within. The remainder consists of a repeating pattern of serialized strings and then digests of the length dictated by the first four bytes. Digests and their inclusion criteria are as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"chainspec_raw_hash"})," will always be included."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"genesis_accounts_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"global_state_raw_hash"})," may be included in specific circumstances."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(n.p,{children:"A contract struct containing the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractpackagehash",children:(0,s.jsx)(n.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#contractwasmhash",children:(0,s.jsx)(n.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#namedkey",children:(0,s.jsx)(n.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#entrypoint",children:(0,s.jsx)(n.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.a,{href:"#protocolversion",children:(0,s.jsx)(n.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."]}),"\n",(0,s.jsx)(n.h2,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."]}),"\n",(0,s.jsx)(n.h2,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(n.p,{children:"The version of the contract."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"#contracthash",children:(0,s.jsx)(n.code,{children:"contract_hash"})})," The contract hash of the contract."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"contract_version"})," The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."]}),"\n",(0,s.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,s.jsx)(n.p,{children:'Represents a party delegating their stake to a validator (or "delegatee"). The structure consists of the following fields:'}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"delegator_public_key"})," The public key of the delegator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"staked_amount"})," The amount staked by the delegator, serialized as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse associated with the delegation. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-uref",children:[(0,s.jsx)(n.code,{children:"URef"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator that the delegator will be delegating to, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"vesting_schedule"})," The vesting schedule for the provided delegator bid. ",(0,s.jsx)(n.code,{children:"None"})," if it is a non-genesis validator. It serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-deploy",children:"Deploy"}),"\n",(0,s.jsx)(n.p,{children:"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"hash"}),": The hash of the deploy header."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"header"}),": Contains metadata about the deploy. The structure of the header is detailed further in this document."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment"}),": The payment code for contained smart contract."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session"}),": The stored contract itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approvals"}),": A list of signatures:"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"deploy-hash",children:"Deploy-Hash"}),"\n",(0,s.jsx)(n.p,{children:"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(n.h3,{id:"deploy-header",children:"Deploy-Header"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"account"}),": A supported public key variant (currently either ",(0,s.jsx)(n.code,{children:"Ed25519"})," or ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"). An ",(0,s.jsx)(n.code,{children:"Ed25519"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"1"})," for ",(0,s.jsx)(n.code,{children:"Ed25519"}),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(n.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(n.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(n.code,{children:"0xbd3a847575010000"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ttl"}),": The ",(0,s.jsx)(n.strong,{children:"Time to live"})," is defined as the amount of time for which deploy is considered valid. The ",(0,s.jsx)(n.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"gas_price"}),": The gas is ",(0,s.jsx)(n.code,{children:"u64"})," value which is serialized as ",(0,s.jsx)(n.code,{children:"u64"})," CLValue discussed below."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"body_hash"}),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"dependencies"}),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"payment--session",children:"Payment & Session"}),"\n",(0,s.jsxs)(n.p,{children:["Payment and Session are both defined as ",(0,s.jsx)(n.code,{children:"ExecutableDeployItems"}),". More information on ",(0,s.jsx)(n.code,{children:"ExecutableDeployItems"})," can be found ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/calling-contracts",children:"here"})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Module Bytes are serialized such that the first byte within the serialized buffer is ",(0,s.jsx)(n.code,{children:"0"})," with the rest of the buffer containing the bytes present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'ModuleBytes { module_bytes: "[72 bytes]", args: 434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5 }'})," will serialize to"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x0048000000420481b0d5a665c8a7678398103d4333c684461a71e9ee2a13f6e859fb6cd419ed5f8876fc6c3e12dce4385acc777edf42dcf8d8d844bf6a704e5b2446750559911a4a328d649ddd48000000434705a38470ec2b008bb693426f47f330802f3bd63588ee275e943407649d3bab1898897ab0400d7fa09fe02ab7b7e8ea443d28069ca557e206916515a7e21d15e5be5eb46235f5"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"StoredContractByHash serializes such that the first byte within the serialized buffer is 1u8. This is followed by the byte representation of the remaining fields."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredContractByHash { hash: c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa4, entry_point: "pclphXwfYmCmdITj8hnh", args: d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x01c4c411864f7b717c27839e56f6f1ebe5da3f35ec0043f437324325d65a22afa41400000070636c7068587766596d436d6449546a38686e685d000000d8b59728274edd2334ea328b3292ed15eaf9134f9a00dce31a87d9050570fb0267a4002c85f3a8384d2502733b2e46f44981df85fed5e4854200bbca313e3bca8d888a84a76a1c5b1b3d236a12401a2999d3cad003c9b9d98c92ab1850"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"StoredContractByName serializes such that the first byte within the serialized buffer is 2u8. This is followed by the individual byte representation of the remaining fields."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredContractByName { name: "U5A74bSZH8abT8HqVaK9", entry_point: "gIetSxltnRDvMhWdxTqQ", args: 07beadc3da884faa17454a }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x0214000000553541373462535a483861625438487156614b39140000006749657453786c746e5244764d685764785471510b00000007beadc3da884faa17454a"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["StoredVersionedContractByHash serializes such that the first byte within the serialized buffer is 3u8. However, the field version within the enum serializes as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:"Option"})," CLValue."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredVersionedContractByHash { hash: b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423, version: None, entry_point: "PsLz5c7JsqT8BK8ll0kF", args: 3d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x03b348fdd0d0b3f66468687df93141b5924f6bb957d5893c08b60d5a78d0b9a423001400000050734c7a3563374a73715438424b386c6c306b463b0000003d0d7f193f70740386cb78b383e2e30c4f976cf3fa834bafbda4ed9dbfeb52ce1777817e8ed8868cfac6462b7cd31028aa5a7a60066db35371a2f8"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["StoredVersionedContractByName serializes such that the first byte within the serialized buffer is 4u8. The name and entry_point are serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:"String"})," CLValue, with the version field serializing as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:"Option"}),"."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:'StoredVersionedContractByName { name: "lWJWKdZUEudSakJzw1tn", version: Some(1632552656), entry_point: "S1cXRT3E1jyFlWBAIVQ8", args: 9975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8 }'})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.code,{children:"0x04140000006c574a574b645a5545756453616b4a7a7731746e01d0c64e61140000005331635852543345316a79466c57424149565138270000009975e6957ea6b07176c7d8471478fb28df9f02a61689ef58234b1a3cffaebf9f303e3ef60ae0d8"})}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Transfer serializes such that the first byte within the serialized buffer contains is 5u8, with the remaining bytes of the buffer containing the bytes contained within the args field of Transfer."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(n.p,{children:"Approval contains two fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(n.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(n.code,{children:"Signature"}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(n.p,{children:"Information relating to a given deploy. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"deploy_hash"})," The hash of the relevant deploy, serialized as a byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," Transfers performed by the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"from"})," The account identifier of the creator of the deploy, serialized as an ",(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"source"})," The source purse used for payment of the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"gas"})," The gas cost of executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"digest",children:"Digest"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"blake2b"})," hash digest. The digest serializes as a byte representation of the hash itself."]}),"\n",(0,s.jsx)(n.h2,{id:"disabledversions",children:"DisabledVersions"}),"\n",(0,s.jsx)(n.p,{children:"Disabled contract versions, containing the following:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"contract_version"})," The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"protocol_version_major"})," The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"entrypoint",children:"EntryPoint"}),"\n",(0,s.jsx)(n.p,{children:"A type of signature method. Order of arguments matters, since this can be referenced by index as well as name."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry point, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"args"})," Arguments for this method. They serialize as a list of the ",(0,s.jsx)(n.a,{href:"#parameter",children:(0,s.jsx)(n.code,{children:"Parameter"})}),"s, where each parameter represents an argument passed to the entrypoint."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"ret"})," The return type of the method, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-unit",children:(0,s.jsx)(n.code,{children:"Unit"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"access"})," An enum describing the possible access control options for a contract entry point. It serializes as a 1 for public or a 1 followed by a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of authorized users."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entry_point_type"})," Identifies the type of entry point. It serializes as a ",(0,s.jsx)(n.code,{children:"0"})," for Session and a ",(0,s.jsx)(n.code,{children:"1"})," for Contract."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"eraid",children:"EraID"}),"\n",(0,s.jsxs)(n.p,{children:["An Era ID newtype. It serializes as a single ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"u64"})," value"]}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"erainfo",children:"EraInfo"}),"\n",(0,s.jsxs)(n.p,{children:["Auction metadata, intended to be recorded each era. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of ",(0,s.jsx)(n.a,{href:"#seigniorageallocation",children:"seigniorage allocations"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"executioneffect",children:"ExecutionEffect"}),"\n",(0,s.jsx)(n.p,{children:"The journal of execution transforms from a single deploy."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"operations"})," The resulting operations, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," of ",(0,s.jsx)(n.a,{href:"#operation",children:"operations"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transforms"})," The actual ",(0,s.jsx)(n.a,{href:"#transform",children:"transformation"})," performed while executing a deploy."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"executionresult",children:"ExecutionResult"}),"\n",(0,s.jsxs)(n.p,{children:["The result of a single deploy. It serializes as a ",(0,s.jsx)(n.code,{children:"u8"})," tag indicating either ",(0,s.jsx)(n.code,{children:"Failure"})," as a 0 or ",(0,s.jsx)(n.code,{children:"Success"})," as a 1. This is followed by the appropriate structure below:"]}),"\n",(0,s.jsx)(n.h3,{id:"failure",children:(0,s.jsx)(n.code,{children:"Failure"})}),"\n",(0,s.jsx)(n.p,{children:"The result of a failed execution."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"effect"})," The ",(0,s.jsx)(n.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"cost"})," The cost of executing the deploy, serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"error_message"})," The error message associated with executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"success",children:(0,s.jsx)(n.code,{children:"Success"})}),"\n",(0,s.jsx)(n.p,{children:"The result of a successful execution."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"effect"})," The ",(0,s.jsx)(n.a,{href:"#executioneffect",children:"effect"})," of executing the deploy."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"transfers"})," A record of transfers performed while executing the deploy, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"cost"})," The cost of executing the deploy, serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"group",children:"Group"}),"\n",(0,s.jsxs)(n.p,{children:['A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a ',(0,s.jsx)(n.a,{href:"#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"groups",children:"Groups"}),"\n",(0,s.jsxs)(n.p,{children:["They are serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of user groups and ",(0,s.jsx)(n.code,{children:"BTreeSets"})," of ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"s held within. The remainder consists of a repeating pattern of serialized user groups and ",(0,s.jsx)(n.code,{children:"BTreeSets"})," of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-state-keys",children:"Keys"}),"\n",(0,s.jsx)(n.p,{children:'In this chapter, we describe what constitutes a "key", the permissions model for the keys, and how they are serialized.'}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.em,{children:"key"})," in ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Global State"})," is one of the following data types:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:'32-byte account identifier (called an "account identity key")'}),"\n",(0,s.jsx)(n.li,{children:'32-byte immutable contract identifier (called a "hash key")'}),"\n",(0,s.jsx)(n.li,{children:'32-byte reference identifier (called an "unforgeable reference")'}),"\n",(0,s.jsx)(n.li,{children:"32-byte transfer identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte deploy information identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte purse balance identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction bid identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction withdrawal identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Dictionary identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte System Contract Registry"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Auction unbond identifier"}),"\n",(0,s.jsx)(n.li,{children:"32-byte Chainspec Registry"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The one exception to note here is the identifier for ",(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})}),", which actually serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value with an additional byte for the tag."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-account-key",children:"Account identity key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-hash-key",children:"Hash key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the deploy hash (see ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#block-structure-head",children:"block-structure-head"})," for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key."]}),"\n",(0,s.jsxs)(n.h3,{id:"serialization-standard-uref",children:["Unforgeable Reference (",(0,s.jsx)(n.code,{children:"URef"}),")"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," broadly speaking can be used to store values and manage permissions to interact with the value stored under the ",(0,s.jsx)(n.code,{children:"URef"}),". ",(0,s.jsx)(n.code,{children:"URef"})," is a tuple which contains the address under which the values are stored and the Access rights to the ",(0,s.jsx)(n.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#uref-head",children:"Unforgeable Reference"})," section for details on how ",(0,s.jsx)(n.code,{children:"URefs"})," are managed."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-transfer-key",children:"Transfer Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the transfer address associated with the given transfer"]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-deploy-info-key",children:"DeployInfo Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the deploy itself."]}),"\n",(0,s.jsx)(n.h3,{id:"serialization-standard-era-info-key",children:"EraInfo Key"}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to the ",(0,s.jsx)(n.code,{children:"Auction"})," metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive ",(0,s.jsx)(n.code,{children:"u64"})," data type and co-relates to the era number when the auction information was stored."]}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(n.p,{children:["This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the public key used to create the associated account (see ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-associated-keys-weights",children:"Accounts"})," for more information)."]}),"\n",(0,s.jsxs)(n.h3,{id:"serialization-standard-serialization-key",children:["Serialization for ",(0,s.jsx)(n.code,{children:"Key"})]}),"\n",(0,s.jsxs)(n.p,{children:["Given the different variants for the over-arching ",(0,s.jsx)(n.code,{children:"Key"})," data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Account"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Hash"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Transfer"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"DeployInfo"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"EraInfo"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Balance"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bid"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Withdraw"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Dictionary"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"SystemContractRegistry"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unbond"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ChainspecRegistry"})}),(0,s.jsx)(n.td,{children:"12"})]})]})]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Account"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(n.code,{children:"AccountHash"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Hash"})," serializes as a 32 byte long buffer containing the byte representation of the underlying ",(0,s.jsx)(n.code,{children:"Hash"})," itself."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"URef"})," is a tuple that contains the address of the URef and the access rights to that ",(0,s.jsx)(n.code,{children:"URef"}),". The serialized representation of the ",(0,s.jsx)(n.code,{children:"URef"})," is 33 bytes long. The first 32 bytes are the byte representation of the ",(0,s.jsx)(n.code,{children:"URef"})," address, and the last byte contains the bits corresponding to the access rights of the ",(0,s.jsx)(n.code,{children:"URef"}),". Refer to the ",(0,s.jsx)(n.a,{href:"#serialization-standard-values",children:"CLValue"})," section of this chapter for details on how ",(0,s.jsx)(n.code,{children:"AccessRights"})," are serialized."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Transfer"})," serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"DeployInfo"})," serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"EraInfo"})," serializes a ",(0,s.jsx)(n.code,{children:"u64"})," primitive type containing the little-endian byte representation of ",(0,s.jsx)(n.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Balance"})," serializes as 32 byte long buffer containing the byte representation of the URef address."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Bid"})," and ",(0,s.jsx)(n.code,{children:"Withdraw"})," both contain the ",(0,s.jsx)(n.code,{children:"AccountHash"})," as their identifier; therefore, they serialize in the same manner as the ",(0,s.jsx)(n.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Dictionary"})," as the 32 byte long buffer containing the byte representation of the seed URef hashed with the identifying name of the dictionary item."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"SystemContractRegistry"})," as a 32 byte long buffer of zeros."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Unbond"})," contains the ",(0,s.jsx)(n.code,{children:"AccountHash"})," as its identifier; therefore, it serialize in the same manner as the ",(0,s.jsx)(n.code,{children:"Account"})," variant."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"ChainspecRegistry"})," as a 32 byte long buffer of ones."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-permissions",children:"Permissions"}),"\n",(0,s.jsxs)(n.p,{children:["There are three types of actions that can be done on a value: read, write, add. The reason for ",(0,s.jsx)(n.em,{children:"add"})," to be called out separately from ",(0,s.jsx)(n.em,{children:"write"})," is to allow for commutativity checking. The available actions depend on the key type and the context. Some key types only allow controlled access by smart contracts via the contract API, and other key types refer to values produced and used by the system itself and are not accessible to smart contracts at all but can be read via off-chain queries. This is summarized in the table below:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Key"}),(0,s.jsx)(n.th,{children:"Type Available Actions"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Account"}),(0,s.jsx)(n.td,{children:"Read + Add (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Hash"}),(0,s.jsx)(n.td,{children:"Read"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"URef"}),(0,s.jsx)(n.td,{children:"Read + Write and/or Add"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Transfer"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Deploy"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"EraInfo"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Balance"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Bid"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Withdraw"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Dictionary"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"SystemContractRegistry"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Unbond"}),(0,s.jsx)(n.td,{children:"System"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"ChainspecRegistry"}),(0,s.jsx)(n.td,{children:"Read (via API)"})]})]})]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsxs)(n.p,{children:["Refer to ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#uref-permissions",children:"URef permissions"})," on how permissions are handled in the case of ",(0,s.jsx)(n.code,{children:"URef"}),"s."]}),"\n",(0,s.jsx)(n.h2,{id:"namedarg",children:"NamedArg"}),"\n",(0,s.jsxs)(n.p,{children:["Named arguments to a contract. It is serialized by the combination of a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})})," followed by the associated ",(0,s.jsx)(n.a,{href:"#clvalue-clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"namedkey",children:"NamedKey"}),"\n",(0,s.jsxs)(n.p,{children:["A mapping of string identifiers to a Casper ",(0,s.jsx)(n.code,{children:"Key"})," type. It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"name"})," The name of the entry. It serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The value of the entry, which is a Casper ",(0,s.jsx)(n.code,{children:"Key"})," type."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys portion of the account structure serializes as a mapping of a string to Casper ",(0,s.jsx)(n.code,{children:"Key"})," values as described ",(0,s.jsx)(n.a,{href:"#serialization-standard-serialization-key",children:"here"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"operation",children:"Operation"}),"\n",(0,s.jsx)(n.p,{children:"An operation performed while executing a deploy. It contains:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"key"})," The formatted string of the key, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"kind"})," OpKind, The type of operation performed. It serializes as a single byte based on the following table:"]}),"\n"]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"OpKind"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Read"}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write"}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add"}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"NoOp"}),(0,s.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"parameter",children:"Parameter"}),"\n",(0,s.jsxs)(n.p,{children:["Parameter to a method, structured as a name followed by a ",(0,s.jsx)(n.code,{children:"CLType"}),". It is serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-string",children:(0,s.jsx)(n.code,{children:"String"})})," followed by a ",(0,s.jsx)(n.a,{href:"#clvalue-cltype",children:(0,s.jsx)(n.code,{children:"CLType"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"protocolversion",children:"ProtocolVersion"}),"\n",(0,s.jsxs)(n.p,{children:["A newtype indicating the Casper Platform protocol version. It is serialized as three ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u32"})})," values indicating major, minor and patch versions in that order."]}),"\n",(0,s.jsx)(n.h2,{id:"publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:["Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"runtimeargs",children:"RuntimeArgs"}),"\n",(0,s.jsxs)(n.p,{children:["Represents a collection of arguments passed to a smart contract. They serialize as a ",(0,s.jsx)(n.a,{href:"#clvalue-list",children:(0,s.jsx)(n.code,{children:"List"})})," comprised of ",(0,s.jsx)(n.a,{href:"#clvalue-tuple",children:(0,s.jsx)(n.code,{children:"Tuples"})}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"seigniorageallocation",children:"SeigniorageAllocation"}),"\n",(0,s.jsx)(n.p,{children:"Information about seigniorage allocation."}),"\n",(0,s.jsxs)(n.p,{children:["If the seigniorage allocation in question is for a validator, it serializes as the validator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})," followed by the ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["If it is a delegator, it serializes as the delegator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),", followed by the validator's ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})})," and finally the ",(0,s.jsxs)(n.a,{href:"#clvalue-numeric",children:[(0,s.jsx)(n.code,{children:"U512"})," amount"]}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"signature",children:"Signature"}),"\n",(0,s.jsxs)(n.p,{children:["The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an ",(0,s.jsx)(n.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(n.code,{children:"Secp256k1"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"systemcontractregistry",children:"SystemContractRegistry"}),"\n",(0,s.jsxs)(n.p,{children:["SystemContractRegistry is a unique ",(0,s.jsx)(n.code,{children:"Key"})," under which a mapping of the names and ",(0,s.jsx)(n.code,{children:"ContractHashes"})," for system contracts. This includes ",(0,s.jsx)(n.code,{children:"Mint"}),", ",(0,s.jsx)(n.code,{children:"Auction"}),", ",(0,s.jsx)(n.code,{children:"HandlePayment"})," and ",(0,s.jsx)(n.code,{children:"StandardPayment"}),". It is serialized as a ",(0,s.jsx)(n.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(n.code,{children:"u32"})," value describing the number of names as strings and ",(0,s.jsx)(n.a,{href:"#contracthash",children:"ContractHashes"})," held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes."]}),"\n",(0,s.jsx)(n.h2,{id:"timediff",children:"TimeDiff"}),"\n",(0,s.jsxs)(n.p,{children:["A human-readable duration between two timestamps. It serializes as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(n.h2,{id:"timestamp",children:"Timestamp"}),"\n",(0,s.jsxs)(n.p,{children:["A timestamp formatted as per RFC 3339 and serialized as a single ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n",(0,s.jsx)(n.h2,{id:"transferaddr",children:"TransferAddr"}),"\n",(0,s.jsx)(n.p,{children:"Hex-encoded transfer address, which serializes as a byte representation of itself."}),"\n",(0,s.jsx)(n.h2,{id:"transform",children:"Transform"}),"\n",(0,s.jsxs)(n.p,{children:["The actual transformation performed while executing a deploy. It serializes as a single ",(0,s.jsx)(n.code,{children:"u8"})," value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Transform Type"}),(0,s.jsx)(n.th,{children:"Serialization"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Identity"}),(0,s.jsx)(n.td,{children:"0"}),(0,s.jsx)(n.td,{children:"A transform having no effect."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_CLValue"}),(0,s.jsx)(n.td,{children:"1"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#clvalue-clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Account"}),(0,s.jsx)(n.td,{children:"2"}),(0,s.jsxs)(n.td,{children:["Write the given ",(0,s.jsx)(n.a,{href:"#account-hash",children:(0,s.jsx)(n.code,{children:"Account"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract_WASM"}),(0,s.jsx)(n.td,{children:"3"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contractwasmhash",children:"contract as Wasm"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract"}),(0,s.jsx)(n.td,{children:"4"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contracthash",children:"contract"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Contract_Package"}),(0,s.jsx)(n.td,{children:"5"}),(0,s.jsxs)(n.td,{children:["Writes a smart ",(0,s.jsx)(n.a,{href:"#contractpackagehash",children:"contract package"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Deploy_Info"}),(0,s.jsx)(n.td,{children:"6"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#deployinfo",children:(0,s.jsx)(n.code,{children:"DeployInfo"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Transfer"}),(0,s.jsx)(n.td,{children:"7"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#transferaddr",children:"Transfer"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Era_Info"}),(0,s.jsx)(n.td,{children:"8"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#erainfo",children:(0,s.jsx)(n.code,{children:"EraInfo"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Bid"}),(0,s.jsx)(n.td,{children:"9"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#bid",children:(0,s.jsx)(n.code,{children:"Bid"})})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Write_Withdraw"}),(0,s.jsx)(n.td,{children:"10"}),(0,s.jsxs)(n.td,{children:["Writes the given ",(0,s.jsx)(n.a,{href:"#unbondingpurse",children:"Withdraw"})," to global state."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_INT32"}),(0,s.jsx)(n.td,{children:"11"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"i32"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT64"}),(0,s.jsx)(n.td,{children:"12"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT128"}),(0,s.jsx)(n.td,{children:"13"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U128"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT256"}),(0,s.jsx)(n.td,{children:"14"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U256"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_UINT512"}),(0,s.jsx)(n.td,{children:"15"}),(0,s.jsxs)(n.td,{children:["Adds the given ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Add_Keys"}),(0,s.jsx)(n.td,{children:"16"}),(0,s.jsxs)(n.td,{children:["Adds the given collection of ",(0,s.jsx)(n.a,{href:"#namedkey",children:"named keys"}),"."]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"Failure"}),(0,s.jsx)(n.td,{children:"17"}),(0,s.jsx)(n.td,{children:"A failed transformation, containing an error message."})]})]})]}),"\n",(0,s.jsx)(n.h2,{id:"transformentry",children:"TransformEntry"}),"\n",(0,s.jsx)(n.p,{children:"A transformation performed while executing a deploy."}),"\n",(0,s.jsx)(n.h2,{id:"unbondingpurse",children:"UnbondingPurse"}),"\n",(0,s.jsx)(n.p,{children:"A purse used for unbonding. The structure consists of the following:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"unbonder_public_key"})," The public key of the unbonder, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"new_validator"})," The validator public key to redelegate to, serialized as an ",(0,s.jsx)(n.a,{href:"#clvalue-option",children:(0,s.jsx)(n.code,{children:"Option"})})," containing the public key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"serialization-standard-values",children:"Values"}),"\n",(0,s.jsxs)(n.p,{children:["A value stored in the global state is a ",(0,s.jsx)(n.code,{children:"StoredValue"}),". A ",(0,s.jsx)(n.code,{children:"StoredValue"})," is one of three possible variants:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A ",(0,s.jsx)(n.code,{children:"CLValue"})]}),"\n",(0,s.jsx)(n.li,{children:"A contract"}),"\n",(0,s.jsx)(n.li,{children:"An account"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["We discuss ",(0,s.jsx)(n.code,{children:"CLValue"})," and contract in more detail below. Details about accounts can be found in ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"accounts-head"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Each ",(0,s.jsx)(n.code,{children:"StoredValue"})," is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of ",(0,s.jsx)(n.code,{children:"StoredValue"})," it is, followed by the serialization of that variant. The tag for each variant is as follows:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," is ",(0,s.jsx)(n.code,{children:"0"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Account"})," is ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"Contract"})," is ",(0,s.jsx)(n.code,{children:"2"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The details of ",(0,s.jsx)(n.code,{children:"CLType"})," serialization are in the following section. Using the serialization format for ",(0,s.jsx)(n.code,{children:"CLValue"})," as a basis, we can succinctly write the serialization rules for contracts and accounts:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["contracts serialize in the same way as data with ",(0,s.jsx)(n.code,{children:"CLType"})," equal to ",(0,s.jsx)(n.code,{children:"Tuple3(List(U8), Map(String, Key), Tuple3(U32, U32, U32))"}),";"]}),"\n",(0,s.jsxs)(n.li,{children:["accounts serialize in the same way as data with ",(0,s.jsx)(n.code,{children:"CLType"})," equal to ",(0,s.jsx)(n.code,{children:"Tuple5(ByteArray(U8, 32), Map(String, Key), URef, Map(ByteArray(U8, 32), U8), Tuple2(U8, U8))"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Note: ",(0,s.jsx)(n.code,{children:"Tuple5"})," is not a presently supported ",(0,s.jsx)(n.code,{children:"CLType"}),". However, it is clear how to generalize the rules for ",(0,s.jsx)(n.code,{children:"Tuple1"}),", ",(0,s.jsx)(n.code,{children:"Tuple2"}),", ",(0,s.jsx)(n.code,{children:"Tuple3"})," to any size tuple."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," is used to describe data that is used by smart contracts. This could be as a local state variable, input argument, or return value. A ",(0,s.jsx)(n.code,{children:"CLValue"})," consists of two parts: a ",(0,s.jsx)(n.code,{children:"CLType"})," describing the type of the value and an array of bytes representing the data in our serialization format."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," is described by the following recursive data type:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All data which can be assigned a (non-",(0,s.jsx)(n.code,{children:"Any"}),") ",(0,s.jsx)(n.code,{children:"CLType"})," can be serialized according to the following rules (this defines the Casper serialization format):"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-boolean",children:"Boolean"}),"\n",(0,s.jsxs)(n.p,{children:["Boolean values serialize as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-numeric",children:"Numeric"}),"\n",(0,s.jsx)(n.p,{children:"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u8"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"1024u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00040000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Wider numeric values (i.e. ",(0,s.jsx)(n.code,{children:"U128"}),", ",(0,s.jsx)(n.code,{children:"U256"}),", ",(0,s.jsx)(n.code,{children:"U512"}),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This is done to reduce the serialization size when small numbers are represented within a wide data type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(7)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x0107"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(1024)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x020004"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:'U512::from("123456789101112131415")'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0957ff1ada959f4eb106"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-unit",children:"Unit"}),"\n",(0,s.jsx)(n.p,{children:"Unit serializes to an empty byte array."}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-string",children:"String"}),"\n",(0,s.jsx)(n.p,{children:"Strings serialize as a 32-bit integer representing the length in bytes (note: this might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:'"Hello, World!"'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0d00000048656c6c6f2c20576f726c6421"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-option",children:"Option"}),"\n",(0,s.jsxs)(n.p,{children:["Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,s.jsx)(n.code,{children:"0"})," if the value is missing, and ",(0,s.jsx)(n.code,{children:"1"})," if it is present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"None"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"Some(10u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010a000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-list",children:"List"}),"\n",(0,s.jsxs)(n.p,{children:["A list of values serializes as a 32-bit integer representing the number of elements in the list (note this differs from strings where it gives the number of ",(0,s.jsx)(n.em,{children:"bytes"}),"), followed by the concatenation of each serialized element."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List()"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00000000"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List(1u32, 2u32, 3u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x03000000010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-ByteArray",children:"ByteArray"}),"\n",(0,s.jsx)(n.p,{children:"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"[1u32, 2u32, 3u32]"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-result",children:"Result"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Result"})," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,s.jsx)(n.code,{children:"1"})," for the success variant and ",(0,s.jsx)(n.code,{children:"0"})," for the error variant."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n'})}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-tuple",children:"Tuple"}),"\n",(0,s.jsxs)(n.p,{children:["Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,s.jsx)(n.code,{children:"ByteArray"})," the number of elements is not included in the serialization because it is statically known in the type."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n'})}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-map",children:"Map"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Map"})," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,s.jsx)(n.code,{children:"Map"})," data structures can be unordered."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-uref",children:"URef"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," values serialize as the concatenation of its address (which is a fixed-length list of ",(0,s.jsx)(n.code,{children:"u8"}),") and a single byte tag representing the access rights. Access rights are converted as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Access Rights"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"NONE"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WRITE"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_WRITE"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"7"})]})]})]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:"- E.g. `uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-007` shows a `URef` with full `READ_ADD_WRITE` rights.\n"})}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["When passing a URef to another entity on chain, you must ensure that the ",(0,s.jsx)(n.code,{children:"AccessRights"})," are set correctly. If the URef represents a ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/P#purse",children:"purse"}),", ",(0,s.jsx)(n.code,{children:"AccessRights"})," impact who can deposit and withdraw CSPR."]})}),"\n",(0,s.jsxs)(n.p,{children:["If a passed URef contains ",(0,s.jsx)(n.code,{children:"ADD"})," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions. In this event, ",(0,s.jsx)(n.code,{children:"READ"})," and ",(0,s.jsx)(n.code,{children:"ADD"})," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions unintentionally."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PublicKey"})," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,s.jsx)(n.code,{children:"PublicKey"})," itself:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"System"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"0"}),". With this variant, the single byte of ",(0,s.jsx)(n.code,{children:"0"})," is the entire key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the single tag byte is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-key",children:"Key"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Key"})," values serialize as a single byte tag representing the variant, followed by the serialization of the data that variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,s.jsx)(n.code,{children:"Key::URef"}),", which contains a ",(0,s.jsx)(n.code,{children:"URef"}),"; so its data serializes per the description above. The tags are as follows: ",(0,s.jsx)(n.code,{children:"Key::Account"})," serializes as ",(0,s.jsx)(n.code,{children:"0"}),", ",(0,s.jsx)(n.code,{children:"Key::Hash"})," as ",(0,s.jsx)(n.code,{children:"1"}),", ",(0,s.jsx)(n.code,{children:"Key::URef"})," as ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-cltype",children:"CLType"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," itself also has rules for serialization. A ",(0,s.jsx)(n.code,{children:"CLType"})," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,s.jsx)(n.code,{children:"ByteArray"})," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"CLType"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I32"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I64"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U8"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U32"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U64"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U128"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U256"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U512"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unit"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"12"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Option"})}),(0,s.jsx)(n.td,{children:"13"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"List"})}),(0,s.jsx)(n.td,{children:"14"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ByteArray"})}),(0,s.jsx)(n.td,{children:"15"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Result"})}),(0,s.jsx)(n.td,{children:"16"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Map"})}),(0,s.jsx)(n.td,{children:"17"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple1"})}),(0,s.jsx)(n.td,{children:"18"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple2"})}),(0,s.jsx)(n.td,{children:"19"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple3"})}),(0,s.jsx)(n.td,{children:"20"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Any"})}),(0,s.jsx)(n.td,{children:"21"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PublicKey"})}),(0,s.jsx)(n.td,{children:"22"})]})]})]}),"\n",(0,s.jsx)(n.h4,{id:"clvalue-clvalue",children:"CLValue"}),"\n",(0,s.jsxs)(n.p,{children:["A complete ",(0,s.jsx)(n.code,{children:"CLValue"}),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-contracts",children:"Contracts"}),"\n",(0,s.jsxs)(n.p,{children:["Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,s.jsx)(n.em,{children:"contract"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a ",(0,s.jsx)(n.a,{href:"https://webassembly.github.io/spec/core/syntax/modules.html",children:"wasm module"})]}),"\n",(0,s.jsx)(n.li,{children:"a collection of named keys"}),"\n",(0,s.jsx)(n.li,{children:"a protocol version"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The wasm module must contain a function named ",(0,s.jsx)(n.code,{children:"call"}),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-runtime",children:"Casper runtime"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note: though the ",(0,s.jsx)(n.code,{children:"call"})," function signature has no arguments and no return value, within the ",(0,s.jsx)(n.code,{children:"call"})," function body, the ",(0,s.jsx)(n.code,{children:"get_named_arg"})," runtime function can be used to accept arguments (by ordinal), and the ",(0,s.jsx)(n.code,{children:"ret"})," runtime function can be used to return a single ",(0,s.jsx)(n.code,{children:"CLValue"})," to the caller."]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,s.jsx)(n.code,{children:"URef"}),"s, which are known to the contract (see the section on Permissions for details)."]}),"\n",(0,s.jsx)(n.p,{children:"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."}),"\n",(0,s.jsx)(n.h2,{id:"withdrawpurse",children:"WithdrawPurse"}),"\n",(0,s.jsxs)(n.p,{children:["A purse used for unbonding, replaced in 1.5 by ",(0,s.jsx)(n.a,{href:"#unbondingpurse",children:"UnbondingPurse"}),". WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"bonding_purse"})," The bonding purse, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-uref",children:(0,s.jsx)(n.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"validator_public_key"})," The public key of the validator, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"unbonder_public_key"})," The public key of the unbonder, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-publickey",children:(0,s.jsx)(n.code,{children:"PublicKey"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"era_of_creation"})," Era in which this unbonding request was created, as an ",(0,s.jsx)(n.a,{href:"#eraid",children:(0,s.jsx)(n.code,{children:"EraId"})})," newtype, which serializes as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"u64"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"amount"})," The unbonding amount, serialized as a ",(0,s.jsx)(n.a,{href:"#clvalue-numeric",children:(0,s.jsx)(n.code,{children:"U512"})})," value."]}),"\n"]}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>t});var s=i(96540);const r={},l=s.createContext(r);function d(e){const n=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d220dcab.b0fd0ac0.js b/assets/js/d220dcab.b0fd0ac0.js deleted file mode 100644 index 2d8e5f4ea..000000000 --- a/assets/js/d220dcab.b0fd0ac0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4941],{85135:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});var a=s(74848),r=s(28453);const d={title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},c="Querying a Casper Node",t={id:"resources/beginner/querying-network",title:"Querying a Node",description:"The Casper node supports queries for users and developers to obtain information stored on the blockchain.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/querying-network.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/querying-network",permalink:"/resources/tutorials/beginner/querying-network",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough"},next:{title:"Contract Upgrades",permalink:"/resources/tutorials/beginner/upgrade-contract"}},i={},o=[{value:"Obtaining the Global State Root Hash",id:"obtaining-the-global-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying Blocks",id:"querying-blocks",level:2},{value:"Querying Deploys",id:"querying-deploys",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"querying-a-casper-node",children:"Querying a Casper Node"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper node supports queries for users and developers to obtain information stored on the blockchain."}),"\n",(0,a.jsx)(n.p,{children:"This document assumes:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["You have met the ",(0,a.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,a.jsxs)(n.li,{children:["You are familiar with the structure of the ",(0,a.jsx)(n.a,{href:"/design",children:"Global State and the Blockchain Design"})," to query data from the network"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Account details"}),"\n",(0,a.jsx)(n.li,{children:"Block information"}),"\n",(0,a.jsx)(n.li,{children:"Deploy information"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"obtaining-the-global-state-root-hash",children:"Obtaining the Global State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node."}),"\n",(0,a.jsxs)(n.p,{children:["All queries made to global state require the ",(0,a.jsx)(n.code,{children:"state-root-hash"}),", which you can obtain with this command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash \\\n --id 1 \\\n --node-address http://<node-ip-address>:7777\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Accounts"})," are stored in the global state and can be queried using the ",(0,a.jsx)(n.code,{children:"query-global-state"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --id 4 \\\n --node-address http://<node-ip-address>:7777 \\\n --state-root-hash <state-root-hash> \\\n --key <hex-encoded-source-account-public-key>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Account Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To query the account balance, use the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address http://<node-ip-address>:7777 \\\n--state-root-hash <state-root-hash> \\\n--purse-identifier <account>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Balance Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-blocks",children:"Querying Blocks"}),"\n",(0,a.jsx)(n.p,{children:"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-block \\\n --id 3 \\\n --node-address http://<node-ip-address>:7777 \\\n --block-identifier <block-hash> \\\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."block"."header"."state_root_hash"'})," - contains the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," for this block"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-deploys",children:"Querying Deploys"}),"\n",(0,a.jsxs)(n.p,{children:["Once you submit a deploy to the network, you can check its execution status using ",(0,a.jsx)(n.code,{children:"get-deploy"}),". If the ",(0,a.jsx)(n.code,{children:"execution_results"})," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --id 2 \\\n --node-address http://<node-ip-address>:7777 \\\n <deploy-hash>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"deploy-hash"})," - Hex-encoded hash of the deploy"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var a=s(96540);const r={},d=a.createContext(r);function c(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d220dcab.d1c22622.js b/assets/js/d220dcab.d1c22622.js new file mode 100644 index 000000000..cc3c7a960 --- /dev/null +++ b/assets/js/d220dcab.d1c22622.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84941],{85135:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>d,metadata:()=>t,toc:()=>o});var a=s(74848),r=s(28453);const d={title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},c="Querying a Casper Node",t={id:"resources/beginner/querying-network",title:"Querying a Node",description:"The Casper node supports queries for users and developers to obtain information stored on the blockchain.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/querying-network.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/querying-network",permalink:"/1.5.X/resources/tutorials/beginner/querying-network",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Querying a Node",slug:"/resources/tutorials/beginner/querying-network"},sidebar:"tutorials",previous:{title:"Tutorial Walkthrough",permalink:"/1.5.X/resources/beginner/counter-testnet/walkthrough"},next:{title:"Contract Upgrades",permalink:"/1.5.X/resources/tutorials/beginner/upgrade-contract"}},i={},o=[{value:"Obtaining the Global State Root Hash",id:"obtaining-the-global-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying Blocks",id:"querying-blocks",level:2},{value:"Querying Deploys",id:"querying-deploys",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"querying-a-casper-node",children:"Querying a Casper Node"})}),"\n",(0,a.jsx)(n.p,{children:"The Casper node supports queries for users and developers to obtain information stored on the blockchain."}),"\n",(0,a.jsx)(n.p,{children:"This document assumes:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["You have met the ",(0,a.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"prerequisites"})]}),"\n",(0,a.jsxs)(n.li,{children:["You are familiar with the structure of the ",(0,a.jsx)(n.a,{href:"/1.5.X/design",children:"Global State and the Blockchain Design"})," to query data from the network"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"When sending a query, it is important to note that the request will be routed to a single node in the network. You can request several types of data from a node:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Account details"}),"\n",(0,a.jsx)(n.li,{children:"Block information"}),"\n",(0,a.jsx)(n.li,{children:"Deploy information"}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"obtaining-the-global-state-root-hash",children:"Obtaining the Global State Root Hash"}),"\n",(0,a.jsx)(n.p,{children:"Since the system state changes with each block created, obtaining the latest global state hash is essential before querying information from a node."}),"\n",(0,a.jsxs)(n.p,{children:["All queries made to global state require the ",(0,a.jsx)(n.code,{children:"state-root-hash"}),", which you can obtain with this command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash \\\n --id 1 \\\n --node-address http://<node-ip-address>:7777\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - (STRING OR INTEGER) Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": null,\n "id": 1\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "state_root_hash": "f97d8d36630a8f4acdb323223596f6fa01ee3b0d49ad70d84d715c156c5dbec6"\n },\n "id": 1\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"Accounts"})," are stored in the global state and can be queried using the ",(0,a.jsx)(n.code,{children:"query-global-state"})," command:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --id 4 \\\n --node-address http://<node-ip-address>:7777 \\\n --state-root-hash <state-root-hash> \\\n --key <hex-encoded-source-account-public-key>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"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."]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"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"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Account Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -v \\\n --id 4 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --key 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the sample JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "path": []\n },\n "id": 4\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4,\n "result": {\n "api_version": "1.5.2",\n "block_header": null,\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "named_keys": [\n {\n "name": "counter",\n "key": "hash-4bf23564c8849a0a3193781f0a9df7d27c4bce2cc585d6e9bb161a7a1ce5cd7e"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-76b6c7e7a87b752d34a8c3ccdc070dbfd1940960016c537525b2ab9076b61a3e-007"\n },\n {\n "name": "counter_package_name",\n "key": "hash-e4b2060f098fa763f9a68c5c98a2d98a4fa80815ec0fd6b93ac9efbb0c18f19b"\n },\n {\n "name": "my-key-name",\n "key": "uref-09376d4202d32457ceefa4d9cdf1db6ab2324981ade06ba6f495cdf14124c3b9-007"\n },\n {\n "name": "version",\n "key": "uref-244a270207dd13ef5ff190f75d84efe4ab54bd5787be0bbb175c3fb154b7f5ed-007"\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-77ea2e433c94c9cb8303942335da458672249d38c1fa5d1d7a7500b862ff52a4",\n "weight": 1\n },\n {\n "account_hash": "account-hash-d65d053f5017af101b752a9a12ba4c41fe3054b8632998a69193b891eab4caf5",\n "weight": 1\n },\n {\n "account_hash": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "weight": 1\n },\n {\n "account_hash": "account-hash-f1802d2dbd83e41f638eb9b046f762e481d56b27d4aa00817fec77fbb21f944a",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n }\n }\n },\n "merkle_proof": "[32054 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["To query the account balance, use the ",(0,a.jsx)(n.code,{children:"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:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance --help\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance \\\n--id 6 \\\n--node-address http://<node-ip-address>:7777 \\\n--state-root-hash <state-root-hash> \\\n--purse-identifier <account>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"state-root-hash"})," - Hex-encoded hash of the state root"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"purse-identifier"})," - A public key or account hash, implying the main purse of the given account should be used. Alternatively, the purse's URef."]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"-v"})," option generates verbose output, printing the RPC request and response generated. Let's explore an example below."]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Example Balance Query with Verbose Output:"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-balance -v \\\n --id 6 \\\n --node-address https://rpc.testnet.casperlabs.io/ \\\n --state-root-hash a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2 \\\n --purse-identifier 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": {\n "state_identifier": {\n "StateRootHash": "a306a9cf869e52fe9eacdc28aade94215112cc04b6737b3669c35568a47a7dc2"\n },\n "purse_identifier": {\n "main_purse_under_public_key": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n },\n "id": 6\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.2",\n "balance": "164000000000"\n },\n "id": 6\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-blocks",children:"Querying Blocks"}),"\n",(0,a.jsx)(n.p,{children:"It is possible to obtain detailed block information from the system. To do this, obtain the hash of the block of interest and send this query to a node in the network. Here is an example:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-block \\\n --id 3 \\\n --node-address http://<node-ip-address>:7777 \\\n --block-identifier <block-hash> \\\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"block-identifier"})," - Hex-encoded block hash or height of the block. If not given, the last block added to the chain as known at the given node will be used"]}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:'"result"."block"."header"."state_root_hash"'})," - contains the ",(0,a.jsx)(n.code,{children:"state-root-hash"})," for this block"]}),"\n"]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": {\n "block_identifier": {\n "Hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9"\n }\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'{\n "id": 3,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block": {\n "body": {\n "deploy_hashes": [],\n "proposer": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "transfer_hashes": ["ec2d477a532e00b08cfa9447b7841a645a27d34ee12ec55318263617e5740713"]\n },\n "hash": "7c7e9b0f087bba5ce6fc4bd067b57f69ea3c8109157a3ad7f6d98b8da77d97f9",\n "header": {\n "accumulated_seed": "50b8ac019b7300cd1fdeec050310e61b900e9238aa879929745900a91bd0fc4f",\n "body_hash": "224076b19c04279ae9b97f620801d5ff40ba64f431fe0d5089ef7cb84fdff45a",\n "era_end": null,\n "era_id": 0,\n "height": 8,\n "parent_hash": "416f339c4c2ff299c64a4b3271c5ef2ac2297bb40a477ceacce1483451a4db16",\n "protocol_version": "1.0.0",\n "random_bit": true,\n "state_root_hash": "cfdbf775b6671de3787cfb1f62f0c5319605a7c1711d6ece4660b37e57e81aa3",\n "timestamp": "2021-04-20T18:04:42.368Z"\n },\n "proofs": [\n {\n "public_key": "010f50b0116f213ef65b99d1bd54483f92bf6131de2f8aceb7e3f825a838292150",\n "signature": "130 chars"\n },\n {\n "public_key": "012c6775c0e9e09f93b9450f1c5348c5f6b97895b0f52bb438f781f96ba2675a94",\n "signature": "130 chars"\n },\n {\n "public_key": "018d5da83f22c9b65cdfdf9f9fdf9f7c98aa2b8c7bcf14bf855177bbb9c1ac7f0a",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9088b92c8a8d592f6ec8c3e8153d7c55fc0c38b5999a214e37e73a2edd6fe0f",\n "signature": "130 chars"\n },\n {\n "public_key": "01b9e3484d96d5693e6c5fe789e7b28972aa392b054a76d175f079692967f604de",\n "signature": "130 chars"\n }\n ]\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"querying-deploys",children:"Querying Deploys"}),"\n",(0,a.jsxs)(n.p,{children:["Once you submit a deploy to the network, you can check its execution status using ",(0,a.jsx)(n.code,{children:"get-deploy"}),". If the ",(0,a.jsx)(n.code,{children:"execution_results"})," in the output are null, the transaction has not run yet. Note that transactions are finalized upon execution."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --id 2 \\\n --node-address http://<node-ip-address>:7777 \\\n <deploy-hash>\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"id"})," - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"deploy-hash"})," - Hex-encoded hash of the deploy"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>t});var a=s(96540);const r={},d=a.createContext(r);function c(e){const n=a.useContext(d);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),a.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d279fdce.312ed6b1.js b/assets/js/d279fdce.312ed6b1.js new file mode 100644 index 000000000..3a51782db --- /dev/null +++ b/assets/js/d279fdce.312ed6b1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35559],{67352:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=t(74848),i=t(28453);const r={},c="Testing Session Code",o={id:"developers/writing-onchain-code/testing-session-code",title:"Testing Session Code",description:"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-session-code",permalink:"/1.5.X/developers/writing-onchain-code/testing-session-code",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing Session Code",permalink:"/1.5.X/developers/writing-onchain-code/writing-session-code"},next:{title:"Contract Hash vs. Package Hash",permalink:"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash"}},a={},d=[{value:"Specifying Dependencies in Cargo.toml",id:"specifying-dependencies",level:2},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Required Packages",id:"importing-required-packages",level:3},{value:"Defining The Constants",id:"defining-the-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Running the Test",id:"running-the-test",level:3},{value:"Other Examples",id:"other-examples",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testing-session-code",children:"Testing Session Code"})}),"\n",(0,n.jsxs)(s.p,{children:["This section describes how to test session code using the Casper unit-testing framework. The ",(0,n.jsx)(s.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code",children:"writing session code"})," section is a prerequisite for this tutorial, which uses the example code described ",(0,n.jsx)(s.a,{href:"/1.5.X/developers/writing-onchain-code/writing-session-code#writing-session-code",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"specifying-dependencies",children:"Specifying Dependencies in Cargo.toml"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/Cargo.toml",children:"Cargo.toml"})," sample file in the ",(0,n.jsx)(s.code,{children:"tests"})," directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'[dev-dependencies]\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-execution-engine = "2.0.0"\ncasper-types = "1.5.0"\n'})}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,n.jsxs)(s.p,{children:["Tests for this example session code reside in the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file."]}),"\n",(0,n.jsxs)(s.p,{children:["Notice that this file contains an empty ",(0,n.jsx)(s.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,n.jsx)(s.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/contract/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,n.jsx)(s.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,n.jsx)(s.code,{children:"mod tests"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"importing-required-packages",children:"Importing Required Packages"}),"\n",(0,n.jsx)(s.p,{children:"Next, import the packages required for the tests to run. The example tests use these packages:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n use casper_types::account::AccountHash;\n use casper_types::{runtime_args, RuntimeArgs};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"defining-the-constants",children:"Defining The Constants"}),"\n",(0,n.jsx)(s.p,{children:"The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account\nconst ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument\nconst CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE\n'})}),"\n",(0,n.jsx)(s.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,n.jsxs)(s.p,{children:["In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the ",(0,n.jsx)(s.code,{children:"#[test]"})," attribute."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[test]\nfn <unit-test-name>{\n // Test function implementation\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["This ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"unit test"})," is a good example of testing session code. At a high level, the test follows this process:"]}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["Initialize an instance of the execution engine and the ",(0,n.jsx)(s.code,{children:"InMemoryWasmTestBuilder"}),"."]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let mut builder = InMemoryWasmTestBuilder::default();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Execute the genesis process."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"GitHub"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsx)(s.p,{children:"Retrieve runtime arguments, which should be the same as defined in the contract."}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Create the execution request that sets up the session code to be processed. In this example, the ",(0,n.jsx)(s.code,{children:"CONTRACT_WASM"})," is the session code."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Invoke the execution engine to process the session code."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.exec(execute_request).expect_success().commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Verify that the results match the expected output. This example checks the associated keys."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n"})}),"\n",(0,n.jsx)(s.h3,{id:"running-the-test",children:"Running the Test"}),"\n",(0,n.jsxs)(s.p,{children:["This example uses a ",(0,n.jsx)(s.code,{children:"Makefile"})," to run the tests."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Under the hood, the ",(0,n.jsx)(s.code,{children:"Makefile"})," generates a ",(0,n.jsx)(s.code,{children:"tests/wasm"})," folder, copies the Wasm to the folder, and runs the tests with ",(0,n.jsx)(s.code,{children:"cargo test"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n"})}),"\n",(0,n.jsx)(s.h3,{id:"other-examples",children:"Other Examples"}),"\n",(0,n.jsxs)(s.p,{children:["In the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"counter unit tests"}),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,n.jsx)(s.p,{children:"The verification step looks like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,n.jsxs)(s.p,{children:["For many more examples, visit the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,n.jsx)(s.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,n.jsxs)(s.p,{children:["The following brief video describes testing the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,n.jsxs)(s.p,{align:"center",children:["\n",(0,n.jsx)(s.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Learn to ",(0,n.jsx)(s.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>o});var n=t(96540);const i={},r=n.createContext(i);function c(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d279fdce.7ef66588.js b/assets/js/d279fdce.7ef66588.js deleted file mode 100644 index f559c3757..000000000 --- a/assets/js/d279fdce.7ef66588.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5559],{67352:(e,s,t)=>{t.r(s),t.d(s,{assets:()=>a,contentTitle:()=>c,default:()=>l,frontMatter:()=>r,metadata:()=>o,toc:()=>d});var n=t(74848),i=t(28453);const r={},c="Testing Session Code",o={id:"developers/writing-onchain-code/testing-session-code",title:"Testing Session Code",description:"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-session-code.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/testing-session-code",permalink:"/developers/writing-onchain-code/testing-session-code",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Writing Session Code",permalink:"/developers/writing-onchain-code/writing-session-code"},next:{title:"Contract Hash vs. Package Hash",permalink:"/developers/writing-onchain-code/contract-hash-vs-package-hash"}},a={},d=[{value:"Specifying Dependencies in Cargo.toml",id:"specifying-dependencies",level:2},{value:"Writing the Tests",id:"writing-the-tests",level:2},{value:"Importing Required Packages",id:"importing-required-packages",level:3},{value:"Defining The Constants",id:"defining-the-constants",level:3},{value:"Creating a Test Function",id:"creating-a-test-function",level:3},{value:"Running the Test",id:"running-the-test",level:3},{value:"Other Examples",id:"other-examples",level:3},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function h(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"testing-session-code",children:"Testing Session Code"})}),"\n",(0,n.jsxs)(s.p,{children:["This section describes how to test session code using the Casper unit-testing framework. The ",(0,n.jsx)(s.a,{href:"/developers/writing-onchain-code/writing-session-code",children:"writing session code"})," section is a prerequisite for this tutorial, which uses the example code described ",(0,n.jsx)(s.a,{href:"/developers/writing-onchain-code/writing-session-code#writing-session-code",children:"here"}),"."]}),"\n",(0,n.jsx)(s.h2,{id:"specifying-dependencies",children:"Specifying Dependencies in Cargo.toml"}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/Cargo.toml",children:"Cargo.toml"})," sample file in the ",(0,n.jsx)(s.code,{children:"tests"})," directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'[dev-dependencies]\ncasper-engine-test-support = { version = "2.2.0", features = ["test-support"] }\ncasper-execution-engine = "2.0.0"\ncasper-types = "1.5.0"\n'})}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-execution-engine"})," - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-engine-test-support"})," - A helper crate that provides the interface to write tests and interact with an instance of the execution engine."]}),"\n",(0,n.jsxs)(s.li,{children:[(0,n.jsx)(s.code,{children:"casper-types"})," - Types shared by many Casper crates for use on a Casper network."]}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"writing-the-tests",children:"Writing the Tests"}),"\n",(0,n.jsxs)(s.p,{children:["Tests for this example session code reside in the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/tests/src/integration_tests.rs",children:"tests/src/integration-tests.rs"})," file."]}),"\n",(0,n.jsxs)(s.p,{children:["Notice that this file contains an empty ",(0,n.jsx)(s.code,{children:"main"})," method to initialize the test program. Alternatively, we could use the ",(0,n.jsx)(s.code,{children:"#![no_main]"})," annotation at the top of the file, as we did ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/contract/src/main.rs#L1-L2",children:"here"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'fn main() {\n panic!("Execute \\"cargo test\\" to test the contract, not \\"cargo run\\".");\n}\n'})}),"\n",(0,n.jsxs)(s.p,{children:["The ",(0,n.jsx)(s.code,{children:"#[cfg(test)]"})," attribute tells the Rust compiler to compile and run the tests only when invoking ",(0,n.jsx)(s.code,{children:"cargo test"}),", not while debugging or releasing. All testing functions reside within the grouping mechanism ",(0,n.jsx)(s.code,{children:"mod tests"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[cfg(test)]\nmod tests {\n // The entire test program resides here\n}\n"})}),"\n",(0,n.jsx)(s.h3,{id:"importing-required-packages",children:"Importing Required Packages"}),"\n",(0,n.jsx)(s.p,{children:"Next, import the packages required for the tests to run. The example tests use these packages:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" use casper_engine_test_support::{\n ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,\n DEFAULT_RUN_GENESIS_REQUEST,\n };\n use casper_types::account::AccountHash;\n use casper_types::{runtime_args, RuntimeArgs};\n"})}),"\n",(0,n.jsx)(s.h3,{id:"defining-the-constants",children:"Defining The Constants"}),"\n",(0,n.jsx)(s.p,{children:"The names of the runtime arguments are defined as constants. Using the exact names as in the original contract class is mandatory to define these constants. These are dictated by the arguments specified by the session code. If your session code takes in different arguments, you should define them as constants at this point."}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'const ASSOCIATED_ACCOUNT_HASH: AccountHash = AccountHash::new([1u8; 32]); // hash of the associated account\nconst ASSOCIATED_ACCOUNT: &str = "deployment-account"; // the associated account argument\nconst CONTRACT_WASM: &str = "contract.wasm"; // file to pass to the instance of the EE\n'})}),"\n",(0,n.jsx)(s.h3,{id:"creating-a-test-function",children:"Creating a Test Function"}),"\n",(0,n.jsxs)(s.p,{children:["In this step, we create a program to test the session code. The bodies of test functions typically perform some setup, run the code, then verify the results using assertions. Each test function is annotated with the ",(0,n.jsx)(s.code,{children:"#[test]"})," attribute."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:"#[test]\nfn <unit-test-name>{\n // Test function implementation\n}\n"})}),"\n",(0,n.jsxs)(s.p,{children:["This ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"unit test"})," is a good example of testing session code. At a high level, the test follows this process:"]}),"\n",(0,n.jsxs)(s.ol,{children:["\n",(0,n.jsxs)(s.li,{children:["Initialize an instance of the execution engine and the ",(0,n.jsx)(s.code,{children:"InMemoryWasmTestBuilder"}),"."]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let mut builder = InMemoryWasmTestBuilder::default();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"2",children:["\n",(0,n.jsx)(s.li,{children:"Execute the genesis process."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"3",children:["\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Execute the test-specific logic. In this example, retrieve information about the account running the session code and its associated keys. For full details, visit ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/236bb18b9e98da7f9d8706f5e4825494845cfec2/tests/src/integration_tests.rs#L15-L55",children:"GitHub"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsx)(s.p,{children:"Retrieve runtime arguments, which should be the same as defined in the contract."}),"\n"]}),"\n",(0,n.jsxs)(s.li,{children:["\n",(0,n.jsxs)(s.p,{children:["Create the execution request that sets up the session code to be processed. In this example, the ",(0,n.jsx)(s.code,{children:"CONTRACT_WASM"})," is the session code."]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" let execute_request =\n ExecuteRequestBuilder::standard(*DEFAULT_ACCOUNT_ADDR, CONTRACT_WASM, runtime_args)\n .build();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"6",children:["\n",(0,n.jsx)(s.li,{children:"Invoke the execution engine to process the session code."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" builder.exec(execute_request).expect_success().commit();\n"})}),"\n",(0,n.jsxs)(s.ol,{start:"7",children:["\n",(0,n.jsx)(s.li,{children:"Verify that the results match the expected output. This example checks the associated keys."}),"\n"]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" assert!(associated_keys.contains_key(&ASSOCIATED_ACCOUNT_HASH));\n"})}),"\n",(0,n.jsx)(s.h3,{id:"running-the-test",children:"Running the Test"}),"\n",(0,n.jsxs)(s.p,{children:["This example uses a ",(0,n.jsx)(s.code,{children:"Makefile"})," to run the tests."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,n.jsxs)(s.p,{children:["Under the hood, the ",(0,n.jsx)(s.code,{children:"Makefile"})," generates a ",(0,n.jsx)(s.code,{children:"tests/wasm"})," folder, copies the Wasm to the folder, and runs the tests with ",(0,n.jsx)(s.code,{children:"cargo test"}),"."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-bash",children:"mkdir -p tests/wasm\ncp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\ncd tests && cargo test\n"})}),"\n",(0,n.jsx)(s.h3,{id:"other-examples",children:"Other Examples"}),"\n",(0,n.jsxs)(s.p,{children:["In the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/tests/src/integration_tests.rs",children:"counter unit tests"}),", we use session code to call the contract. The code loads the account that pays for the session code, the session code Wasm, and the runtime arguments. Then, the code invokes the execution engine to process the session code."]}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:" // Use session code to increment the counter.\n let session_code_request = ExecuteRequestBuilder::standard(\n *DEFAULT_ACCOUNT_ADDR,\n COUNTER_CALL_WASM,\n runtime_args! {\n CONTRACT_KEY => contract_v1_hash\n },\n )\n .build();\n\n builder.exec(session_code_request)\n .expect_success()\n .commit();\n"})}),"\n",(0,n.jsx)(s.p,{children:"The verification step looks like this:"}),"\n",(0,n.jsx)(s.pre,{children:(0,n.jsx)(s.code,{className:"language-rust",children:'\n let incremented_count = builder\n .query(None, count_key, &[])\n .expect("should be stored value.")\n .as_cl_value()\n .expect("should be cl value.")\n .clone()\n .into_t::<i32>()\n .expect("should be i32.");\n\n assert_eq!(incremented_count, 1);\n'})}),"\n",(0,n.jsxs)(s.p,{children:["For many more examples, visit the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/tree/dev/smart_contracts/contracts/test",children:"casper-node"})," GitHub repository."]}),"\n",(0,n.jsx)(s.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,n.jsxs)(s.p,{children:["The following brief video describes testing the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"sample session code"})," for configuring an account."]}),"\n",(0,n.jsxs)(s.p,{align:"center",children:["\n",(0,n.jsx)(s.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=5",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,n.jsx)(s.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,n.jsxs)(s.ul,{children:["\n",(0,n.jsxs)(s.li,{children:["Learn to ",(0,n.jsx)(s.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"}),"."]}),"\n"]})]})}function l(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,t)=>{t.d(s,{R:()=>c,x:()=>o});var n=t(96540);const i={},r=n.createContext(i);function c(e){const s=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),n.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d3ef4614.1ecc7dd0.js b/assets/js/d3ef4614.1ecc7dd0.js new file mode 100644 index 000000000..4906563ab --- /dev/null +++ b/assets/js/d3ef4614.1ecc7dd0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[28548],{27321:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(74848),s=r(28453);const i={title:"Hardware"},o="Recommended Hardware Specifications",a={id:"operators/setup/hardware",title:"Hardware",description:"System Requirements",source:"@site/versioned_docs/version-1.5.X/operators/setup/hardware.md",sourceDirName:"operators/setup",slug:"/operators/setup/hardware",permalink:"/1.5.X/operators/setup/hardware",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Hardware"},sidebar:"operators",previous:{title:"Setting up a Node",permalink:"/1.5.X/operators/setup/"},next:{title:"Configuration",permalink:"/1.5.X/operators/setup/basic-node-configuration"}},d={},c=[{value:"System Requirements",id:"system-requirements",level:2},{value:"CPU Requirements",id:"cpu-requirements",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"recommended-hardware-specifications",children:"Recommended Hardware Specifications"})}),"\n",(0,t.jsx)(n.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,t.jsxs)(n.p,{children:["The following hardware specifications are recommended for the Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"4 Cores"}),"\n",(0,t.jsx)(n.li,{children:"32 GB Ram"}),"\n",(0,t.jsx)(n.li,{children:"2 TB SSD or network SSD backed disk"}),"\n",(0,t.jsx)(n.li,{children:"Linux machine running Ubuntu 20.04"}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Notes",type:"note",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this."}),"\n"]}),"\n"]})}),"\n",(0,t.jsx)(n.h3,{id:"cpu-requirements",children:"CPU Requirements"}),"\n",(0,t.jsx)(n.p,{children:"Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions."}),"\n",(0,t.jsx)(n.p,{children:"To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question."})})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>a});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d3ef4614.82ba742b.js b/assets/js/d3ef4614.82ba742b.js deleted file mode 100644 index 617c9037c..000000000 --- a/assets/js/d3ef4614.82ba742b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8548],{27321:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=r(74848),s=r(28453);const i={title:"Hardware"},o="Recommended Hardware Specifications",a={id:"operators/setup/hardware",title:"Hardware",description:"System Requirements",source:"@site/versioned_docs/version-1.5.X/operators/setup/hardware.md",sourceDirName:"operators/setup",slug:"/operators/setup/hardware",permalink:"/operators/setup/hardware",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Hardware"},sidebar:"operators",previous:{title:"Setting up a Node",permalink:"/operators/setup/"},next:{title:"Configuration",permalink:"/operators/setup/basic-node-configuration"}},d={},c=[{value:"System Requirements",id:"system-requirements",level:2},{value:"CPU Requirements",id:"cpu-requirements",level:3}];function l(e){const n={a:"a",admonition:"admonition",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"recommended-hardware-specifications",children:"Recommended Hardware Specifications"})}),"\n",(0,t.jsx)(n.h2,{id:"system-requirements",children:"System Requirements"}),"\n",(0,t.jsxs)(n.p,{children:["The following hardware specifications are recommended for the Casper ",(0,t.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet"})," and ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"4 Cores"}),"\n",(0,t.jsx)(n.li,{children:"32 GB Ram"}),"\n",(0,t.jsx)(n.li,{children:"2 TB SSD or network SSD backed disk"}),"\n",(0,t.jsx)(n.li,{children:"Linux machine running Ubuntu 20.04"}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{title:"Notes",type:"note",children:(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this."}),"\n"]}),"\n"]})}),"\n",(0,t.jsx)(n.h3,{id:"cpu-requirements",children:"CPU Requirements"}),"\n",(0,t.jsx)(n.p,{children:"Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions."}),"\n",(0,t.jsx)(n.p,{children:"To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question."})})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>a});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d477c291.57fee1c9.js b/assets/js/d477c291.57fee1c9.js deleted file mode 100644 index 93a1e3984..000000000 --- a/assets/js/d477c291.57fee1c9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2684],{74347:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>a,toc:()=>h});var t=n(74848),i=n(28453);const r={title:"URef Access Rights"},c="URef Access Rights and Security Considerations",a={id:"developers/dapps/uref-security",title:"URef Access Rights",description:"Understanding Access Rights",source:"@site/versioned_docs/version-1.5.X/developers/dapps/uref-security.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/uref-security",permalink:"/developers/dapps/uref-security",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"URef Access Rights"},sidebar:"developers",previous:{title:"Front-end in React",permalink:"/developers/dapps/template-frontend"},next:{title:"Signing Deploys",permalink:"/developers/dapps/signing-a-deploy"}},d={},h=[{value:"Understanding Access Rights",id:"understanding-access-rights",level:2},{value:"AccessRights and Purses",id:"accessrights-and-purses",level:2},{value:"Security Considerations for dApp Developers",id:"security-considerations-for-dapp-developers",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"uref-access-rights-and-security-considerations",children:"URef Access Rights and Security Considerations"})}),"\n",(0,t.jsx)(s.h2,{id:"understanding-access-rights",children:"Understanding Access Rights"}),"\n",(0,t.jsxs)(s.p,{children:["An ",(0,t.jsx)(s.a,{href:"/concepts/design/casper-design/#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(s.strong,{children:"URef"})," is a key type used for storage on a Casper network. They can store any value other than ",(0,t.jsx)(s.code,{children:"Account"})," and exist as a top-level entity. As such, no individual account may ",(0,t.jsx)(s.em,{children:"own"})," a URef, they can only hold the necessary ",(0,t.jsx)(s.code,{children:"AccessRights"})," to interact with a given URef."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/concepts/serialization-standard/#clvalue-uref",children:(0,t.jsx)(s.code,{children:"AccessRights"})})," determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And this is the same URef with ",(0,t.jsx)(s.code,{children:"READ"})," and ",(0,t.jsx)(s.code,{children:"ADD"})," access rights."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The following table outlines all possible ",(0,t.jsx)(s.code,{children:"AccessRights"})," settings:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Access Rights"}),(0,t.jsx)(s.th,{children:"Serialization"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"NONE"})}),(0,t.jsx)(s.td,{children:"0"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ"})}),(0,t.jsx)(s.td,{children:"1"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"WRITE"})}),(0,t.jsx)(s.td,{children:"2"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_WRITE"})}),(0,t.jsx)(s.td,{children:"3"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD"})}),(0,t.jsx)(s.td,{children:"4"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD"})}),(0,t.jsx)(s.td,{children:"5"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"6"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"7"})]})]})]}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["Any access rights granted alongside a passed URef are ",(0,t.jsx)(s.em,{children:(0,t.jsx)(s.strong,{children:"irrevocable"})}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"accessrights-and-purses",children:"AccessRights and Purses"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"Purse"})," is a unique type of ",(0,t.jsx)(s.code,{children:"URef"})," representing a token balance. Each ",(0,t.jsx)(s.code,{children:"Account"})," will have an associated URef that represents its main purse. Accounts and contracts may have additional purses."]}),"\n",(0,t.jsx)(s.p,{children:"For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Global State"}),(0,t.jsx)(s.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Add"}),(0,t.jsx)(s.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Write"}),(0,t.jsx)(s.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Read"}),(0,t.jsx)(s.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"security-considerations-for-dapp-developers",children:"Security Considerations for dApp Developers"}),"\n",(0,t.jsxs)(s.p,{children:["When developing a ",(0,t.jsx)(s.a,{href:"/developers/dapps/dapp/",children:"dApp"})," that interacts with tokens in any way, it will be necessary to work with various URef ",(0,t.jsx)(s.code,{children:"AccessRights"})," for associated purse URefs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract/",children:"This tutorial outlines our recommendations when transferring tokens to a contract."})}),"\n",(0,t.jsxs)(s.p,{children:["When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate ",(0,t.jsx)(s.code,{children:"AccessRights"}),". The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the ",(0,t.jsx)(s.code,{children:"new_uref"})," should be passed to another entity."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-js",children:"// This example will create a version of the original URef with access rights stripped entirely.\nlet new_uref = uref.with_access_rights(AccessRights::NONE);\n// This example will create a version of the original URef with only READ access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ);\n// This example will create a version of the original URef with only WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::WRITE);\n// This example will create a version of the original URef with both READ and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_WRITE);\n// This example will create a version of the original URef with only ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD);\n// This example will create a version of the original URef with both READ and ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD);\n// This example will create a version of the original URef with both ADD and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);\n// This example will create a version of the original URef with full access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function c(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d477c291.e950cbd2.js b/assets/js/d477c291.e950cbd2.js new file mode 100644 index 000000000..68e71f359 --- /dev/null +++ b/assets/js/d477c291.e950cbd2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52684],{74347:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>d,contentTitle:()=>c,default:()=>o,frontMatter:()=>r,metadata:()=>a,toc:()=>h});var t=n(74848),i=n(28453);const r={title:"URef Access Rights"},c="URef Access Rights and Security Considerations",a={id:"developers/dapps/uref-security",title:"URef Access Rights",description:"Understanding Access Rights",source:"@site/versioned_docs/version-1.5.X/developers/dapps/uref-security.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/uref-security",permalink:"/1.5.X/developers/dapps/uref-security",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726495933e3,frontMatter:{title:"URef Access Rights"},sidebar:"developers",previous:{title:"Front-end in React",permalink:"/1.5.X/developers/dapps/template-frontend"},next:{title:"Signing Deploys",permalink:"/1.5.X/developers/dapps/signing-a-deploy"}},d={},h=[{value:"Understanding Access Rights",id:"understanding-access-rights",level:2},{value:"AccessRights and Purses",id:"accessrights-and-purses",level:2},{value:"Security Considerations for dApp Developers",id:"security-considerations-for-dapp-developers",level:2}];function l(e){const s={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"uref-access-rights-and-security-considerations",children:"URef Access Rights and Security Considerations"})}),"\n",(0,t.jsx)(s.h2,{id:"understanding-access-rights",children:"Understanding Access Rights"}),"\n",(0,t.jsxs)(s.p,{children:["An ",(0,t.jsx)(s.a,{href:"../../concepts/design/casper-design/#uref-head",children:"Unforgeable Reference"})," or ",(0,t.jsx)(s.strong,{children:"URef"})," is a key type used for storage on a Casper network. They can store any value other than ",(0,t.jsx)(s.code,{children:"Account"})," and exist as a top-level entity. As such, no individual account may ",(0,t.jsx)(s.em,{children:"own"})," a URef, they can only hold the necessary ",(0,t.jsx)(s.code,{children:"AccessRights"})," to interact with a given URef."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"../../concepts/serialization-standard/#clvalue-uref",children:(0,t.jsx)(s.code,{children:"AccessRights"})})," determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:"]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000\n"})}),"\n",(0,t.jsxs)(s.p,{children:["And this is the same URef with ",(0,t.jsx)(s.code,{children:"READ"})," and ",(0,t.jsx)(s.code,{children:"ADD"})," access rights."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-bash",children:"uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005\n"})}),"\n",(0,t.jsxs)(s.p,{children:["The following table outlines all possible ",(0,t.jsx)(s.code,{children:"AccessRights"})," settings:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Access Rights"}),(0,t.jsx)(s.th,{children:"Serialization"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"NONE"})}),(0,t.jsx)(s.td,{children:"0"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ"})}),(0,t.jsx)(s.td,{children:"1"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"WRITE"})}),(0,t.jsx)(s.td,{children:"2"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_WRITE"})}),(0,t.jsx)(s.td,{children:"3"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD"})}),(0,t.jsx)(s.td,{children:"4"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD"})}),(0,t.jsx)(s.td,{children:"5"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"6"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:(0,t.jsx)(s.code,{children:"READ_ADD_WRITE"})}),(0,t.jsx)(s.td,{children:"7"})]})]})]}),"\n",(0,t.jsx)(s.admonition,{type:"warning",children:(0,t.jsxs)(s.p,{children:["Any access rights granted alongside a passed URef are ",(0,t.jsx)(s.em,{children:(0,t.jsx)(s.strong,{children:"irrevocable"})}),"."]})}),"\n",(0,t.jsx)(s.h2,{id:"accessrights-and-purses",children:"AccessRights and Purses"}),"\n",(0,t.jsxs)(s.p,{children:["A ",(0,t.jsx)(s.code,{children:"Purse"})," is a unique type of ",(0,t.jsx)(s.code,{children:"URef"})," representing a token balance. Each ",(0,t.jsx)(s.code,{children:"Account"})," will have an associated URef that represents its main purse. Accounts and contracts may have additional purses."]}),"\n",(0,t.jsx)(s.p,{children:"For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(s.table,{children:[(0,t.jsx)(s.thead,{children:(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.th,{children:"Global State"}),(0,t.jsx)(s.th,{children:"Action Monetary Action"})]})}),(0,t.jsxs)(s.tbody,{children:[(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Add"}),(0,t.jsx)(s.td,{children:"Deposit (i.e. transfer to)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Write"}),(0,t.jsx)(s.td,{children:"Withdraw (i.e. transfer from)"})]}),(0,t.jsxs)(s.tr,{children:[(0,t.jsx)(s.td,{children:"Read"}),(0,t.jsx)(s.td,{children:"Balance check"})]})]})]}),"\n",(0,t.jsx)(s.h2,{id:"security-considerations-for-dapp-developers",children:"Security Considerations for dApp Developers"}),"\n",(0,t.jsxs)(s.p,{children:["When developing a ",(0,t.jsx)(s.a,{href:"../dapps/dapp/",children:"dApp"})," that interacts with tokens in any way, it will be necessary to work with various URef ",(0,t.jsx)(s.code,{children:"AccessRights"})," for associated purse URefs."]}),"\n",(0,t.jsx)(s.p,{children:(0,t.jsx)(s.a,{href:"../../resources/tutorials/advanced/transfer-token-to-contract/",children:"This tutorial outlines our recommendations when transferring tokens to a contract."})}),"\n",(0,t.jsxs)(s.p,{children:["When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate ",(0,t.jsx)(s.code,{children:"AccessRights"}),". The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the ",(0,t.jsx)(s.code,{children:"new_uref"})," should be passed to another entity."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-js",children:"// This example will create a version of the original URef with access rights stripped entirely.\nlet new_uref = uref.with_access_rights(AccessRights::NONE);\n// This example will create a version of the original URef with only READ access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ);\n// This example will create a version of the original URef with only WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::WRITE);\n// This example will create a version of the original URef with both READ and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_WRITE);\n// This example will create a version of the original URef with only ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD);\n// This example will create a version of the original URef with both READ and ADD access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD);\n// This example will create a version of the original URef with both ADD and WRITE access rights.\nlet new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);\n// This example will create a version of the original URef with full access rights.\nlet new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);\n"})})]})}function o(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>c,x:()=>a});var t=n(96540);const i={},r=t.createContext(i);function c(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/9ec4e3de.eaa96579.js b/assets/js/d48191b6.092d048f.js similarity index 60% rename from assets/js/9ec4e3de.eaa96579.js rename to assets/js/d48191b6.092d048f.js index bfa62e475..e4997ae09 100644 --- a/assets/js/9ec4e3de.eaa96579.js +++ b/assets/js/d48191b6.092d048f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1865],{40848:e=>{e.exports=JSON.parse('{"tag":{"label":"docs-redux","permalink":"/blog/tags/docs-redux","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/docs-redux","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[52112],{3131:e=>{e.exports=JSON.parse('{"tag":{"label":"tokenomics","permalink":"/blog/tags/tokenomics","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/tokenomics","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/d48191b6.9a8c43c0.js b/assets/js/d48191b6.9a8c43c0.js deleted file mode 100644 index 34a7279a6..000000000 --- a/assets/js/d48191b6.9a8c43c0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2112],{3131:e=>{e.exports=JSON.parse('{"tag":{"label":"tokenomics","permalink":"/blog/tags/tokenomics","allTagsPath":"/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/blog/tags/tokenomics","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/d49dddd4.766c61f5.js b/assets/js/d49dddd4.766c61f5.js new file mode 100644 index 000000000..cf734f144 --- /dev/null +++ b/assets/js/d49dddd4.766c61f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66784],{8386:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>p,toc:()=>c});var o=t(74848),a=t(28453);const s={},r="Python SDK",p={id:"developers/dapps/sdk/python-sdk",title:"Python SDK",description:"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.",source:"@site/docs/developers/dapps/sdk/python-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/python-sdk",permalink:"/developers/dapps/sdk/python-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Go SDK",permalink:"/developers/dapps/sdk/go-sdk"},next:{title:"dApp Technology Stack",permalink:"/developers/dapps/technology-stack"}},i={},c=[{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Sending a transfer",id:"sending-a-transfer",level:3},{value:"Staking",id:"staking",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"python-sdk",children:"Python SDK"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk",children:"Python SDK"})," allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK."]}),"\n",(0,o.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(n.p,{children:"To install the library, run:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"\n pip3 install pycspr\n"})}),"\n",(0,o.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,o.jsxs)(n.p,{children:["You can find examples of testing this library with python scripts in the ",(0,o.jsx)(n.code,{children:"test"})," directory. To run the tests, we recommend the ",(0,o.jsx)(n.em,{children:"pytest"})," library:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:" pytest ./tests\n"})}),"\n",(0,o.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,o.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the Python SDK:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a transfer"})," between two purses"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#staking",children:"Staking"})," tokens with a validator"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["For further examples, take a look at the ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk/tree/main/how_tos",children:"How-tos"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a transfer"}),"\n",(0,o.jsxs)(n.p,{children:["This example shows you how to define and transfer funds between purses on a Casper network. Replace the ",(0,o.jsx)(n.em,{children:"path_to_cp2_account_key"})," in the code below with the receiver's account public key."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:' import os\n import pathlib\n import random\n import typing\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import PrivateKey\n from pycspr.types import Deploy\n from pycspr.types import PublicKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_cp1_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_cp1_secret_key = KeyAlgorithm.ED25519.name,\n\n # path to cp2 account key - defaults to NCTL user 2.\n path_to_cp2_account_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-2" / "public_key_hex"\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key, chain_name):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client = _get_client(node_host, node_port_rpc)\n\n # Set counter-parties.\n cp1, cp2 = _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key)\n\n # Set deploy.\n deploy: Deploy = _get_deploy(chain_name, cp1, cp2)\n\n # Approve deploy.\n deploy.approve(cp1)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n #If deploy is successful send the indication\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host=node_host,\n port_rpc=node_port_rpc,\n ))\n\n\n def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:\n """Returns the 2 counter-parties participating in the transfer.\n """\n cp1 = pycspr.parse_private_key(\n path_to_cp1_secret_key,\n type_of_cp1_secret_key,\n )\n cp2 = pycspr.parse_public_key(\n path_to_cp2_account_key\n ) \n\n return cp1, cp2\n\n\n def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:\n """Returns transfer deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = cp1,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_native_transfer(\n params = deploy_params,\n amount = int(2.5e9),\n target = cp2.account_hash,\n correlation_id = random.randint(1, 1e6)\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)\n'})}),"\n",(0,o.jsx)(n.h3,{id:"staking",children:"Staking"}),"\n",(0,o.jsx)(n.p,{children:"This example shows you how to define and stake funds with a validator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'\n import os\n import pathlib\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import Deploy\n from pycspr.types import PrivateKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_validator_secret_key = KeyAlgorithm.ED25519.name\n\n # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.\n path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"\n\n # amount to stake, i.e. bond, into the network.\n amount = int(2.5e9)\n\n # amount to charge delegators for service provision.\n delegation_rate = 2\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client: NodeClient = _get_client(node_host, node_port_rpc)\n\n # Set validator key.\n validator: PrivateKey = pycspr.parse_private_key(\n path_to_validator_secret_key,\n type_of_validator_secret_key,\n )\n\n # Set deploy.\n deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)\n\n # Approve deploy.\n deploy.approve(validator)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host = node_host,\n port_rpc = node_port_rpc,\n ))\n\n\n def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:\n """Returns delegation deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = validator,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_validator_auction_bid(\n params = deploy_params,\n amount = amount,\n delegation_rate = delegation_rate,\n public_key = validator.as_public_key(),\n path_to_wasm = path_to_wasm\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)\n'})})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>p});var o=t(96540);const a={},s=o.createContext(a);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function p(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d49dddd4.ceb8eee3.js b/assets/js/d49dddd4.ceb8eee3.js deleted file mode 100644 index 914c4d838..000000000 --- a/assets/js/d49dddd4.ceb8eee3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6784],{8386:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>p,toc:()=>c});var o=t(74848),a=t(28453);const s={},r="Python SDK",p={id:"developers/dapps/sdk/python-sdk",title:"Python SDK",description:"The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.",source:"@site/docs/developers/dapps/sdk/python-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/python-sdk",permalink:"/next/developers/dapps/sdk/python-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Go SDK",permalink:"/next/developers/dapps/sdk/go-sdk"},next:{title:"dApp Technology Stack",permalink:"/next/developers/dapps/technology-stack"}},i={},c=[{value:"Installation",id:"installation",level:2},{value:"Tests",id:"tests",level:2},{value:"Usage Examples",id:"usage-examples",level:2},{value:"Sending a transfer",id:"sending-a-transfer",level:3},{value:"Staking",id:"staking",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.header,{children:(0,o.jsx)(n.h1,{id:"python-sdk",children:"Python SDK"})}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk",children:"Python SDK"})," allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK."]}),"\n",(0,o.jsx)(n.h2,{id:"installation",children:"Installation"}),"\n",(0,o.jsx)(n.p,{children:"To install the library, run:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:"\n pip3 install pycspr\n"})}),"\n",(0,o.jsx)(n.h2,{id:"tests",children:"Tests"}),"\n",(0,o.jsxs)(n.p,{children:["You can find examples of testing this library with python scripts in the ",(0,o.jsx)(n.code,{children:"test"})," directory. To run the tests, we recommend the ",(0,o.jsx)(n.em,{children:"pytest"})," library:"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-bash",children:" pytest ./tests\n"})}),"\n",(0,o.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,o.jsx)(n.p,{children:"In this section, we outline a couple of essential tasks you can accomplish with the Python SDK:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a transfer"})," between two purses"]}),"\n",(0,o.jsxs)(n.li,{children:[(0,o.jsx)(n.a,{href:"#staking",children:"Staking"})," tokens with a validator"]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["For further examples, take a look at the ",(0,o.jsx)(n.a,{href:"https://github.com/casper-network/casper-python-sdk/tree/main/how_tos",children:"How-tos"}),"."]}),"\n",(0,o.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a transfer"}),"\n",(0,o.jsxs)(n.p,{children:["This example shows you how to define and transfer funds between purses on a Casper network. Replace the ",(0,o.jsx)(n.em,{children:"path_to_cp2_account_key"})," in the code below with the receiver's account public key."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:' import os\n import pathlib\n import random\n import typing\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import PrivateKey\n from pycspr.types import Deploy\n from pycspr.types import PublicKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_cp1_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_cp1_secret_key = KeyAlgorithm.ED25519.name,\n\n # path to cp2 account key - defaults to NCTL user 2.\n path_to_cp2_account_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-2" / "public_key_hex"\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key, chain_name):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client = _get_client(node_host, node_port_rpc)\n\n # Set counter-parties.\n cp1, cp2 = _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key)\n\n # Set deploy.\n deploy: Deploy = _get_deploy(chain_name, cp1, cp2)\n\n # Approve deploy.\n deploy.approve(cp1)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n #If deploy is successful send the indication\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host=node_host,\n port_rpc=node_port_rpc,\n ))\n\n\n def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:\n """Returns the 2 counter-parties participating in the transfer.\n """\n cp1 = pycspr.parse_private_key(\n path_to_cp1_secret_key,\n type_of_cp1_secret_key,\n )\n cp2 = pycspr.parse_public_key(\n path_to_cp2_account_key\n ) \n\n return cp1, cp2\n\n\n def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:\n """Returns transfer deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = cp1,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_native_transfer(\n params = deploy_params,\n amount = int(2.5e9),\n target = cp2.account_hash,\n correlation_id = random.randint(1, 1e6)\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)\n'})}),"\n",(0,o.jsx)(n.h3,{id:"staking",children:"Staking"}),"\n",(0,o.jsx)(n.p,{children:"This example shows you how to define and stake funds with a validator."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-python",children:'\n import os\n import pathlib\n\n import pycspr\n from pycspr.client import NodeClient\n from pycspr.client import NodeConnectionInfo\n from pycspr.crypto import KeyAlgorithm\n from pycspr.types import Deploy\n from pycspr.types import PrivateKey\n\n # path to cp1 secret key - defaults to NCTL user 1.\n path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"\n\n # type of cp1 secret key - defaults to ED25519.\n type_of_validator_secret_key = KeyAlgorithm.ED25519.name\n\n # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.\n path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"\n\n # amount to stake, i.e. bond, into the network.\n amount = int(2.5e9)\n\n # amount to charge delegators for service provision.\n delegation_rate = 2\n\n # name of target chain - defaults to NCTL chain.\n chain_name = "casper-net-1"\n\n # host address of target node - defaults to NCTL node 1.\n node_host = "localhost"\n\n # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.\n node_port_rpc = 11101\n\n def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):\n """Main entry point.\n :param args: Parsed command line arguments.\n """\n # Set node client.\n client: NodeClient = _get_client(node_host, node_port_rpc)\n\n # Set validator key.\n validator: PrivateKey = pycspr.parse_private_key(\n path_to_validator_secret_key,\n type_of_validator_secret_key,\n )\n\n # Set deploy.\n deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)\n\n # Approve deploy.\n deploy.approve(validator)\n\n # Dispatch deploy to a node.\n client.deploys.send(deploy)\n\n print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")\n\n\n def _get_client(node_host, node_port_rpc) -> NodeClient:\n """Returns a pycspr client instance.\n """\n return NodeClient(NodeConnectionInfo(\n host = node_host,\n port_rpc = node_port_rpc,\n ))\n\n\n def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:\n """Returns delegation deploy to be dispatched to a node.\n """\n # Set standard deploy parameters.\n deploy_params = pycspr.create_deploy_parameters(\n account = validator,\n chain_name = chain_name\n )\n\n # Set deploy.\n deploy = pycspr.create_validator_auction_bid(\n params = deploy_params,\n amount = amount,\n delegation_rate = delegation_rate,\n public_key = validator.as_public_key(),\n path_to_wasm = path_to_wasm\n )\n\n return deploy\n\n\n # Entry point.\n if __name__ == \'__main__\':\n _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)\n'})})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>p});var o=t(96540);const a={},s=o.createContext(a);function r(e){const n=o.useContext(s);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function p(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),o.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d4c529d3.c6f1d5fa.js b/assets/js/d4c529d3.c6f1d5fa.js deleted file mode 100644 index 3dd19fec0..000000000 --- a/assets/js/d4c529d3.c6f1d5fa.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6379],{72319:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),d=t(28453);const s={title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},r="CEP-78 Modalities",o={id:"resources/tokens/cep78/modalities",title:"CEP-78 Modalities",description:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.",source:"@site/docs/resources/tokens/cep78/modalities.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/modalities",permalink:"/next/resources/tokens/cep78/modalities",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},sidebar:"resources",previous:{title:"Introduction",permalink:"/next/resources/tokens/cep78/introduction"},next:{title:"On-chain Installation",permalink:"/next/resources/tokens/using-casper-client"}},c={},a=[{value:"Ownership",id:"ownership",level:2},{value:"NFTKind",id:"nftkind",level:2},{value:"NFTHolderMode",id:"nftholdermode",level:2},{value:"WhitelistMode",id:"whitelistmode",level:2},{value:"Minting",id:"minting",level:2},{value:"NFTMetadataKind",id:"nftmetadatakind",level:2},{value:"CEP-78 metadata example",id:"cep-78-metadata-example",level:3},{value:"NFT-721 metadata example",id:"nft-721-metadata-example",level:3},{value:"Custom Validated",id:"custom-validated",level:3},{value:"Example Custom Validated schema",id:"example-custom-validated-schema",level:4},{value:"Example Custom Metadata",id:"example-custom-metadata",level:4},{value:"NFTIdentifierMode",id:"nftidentifiermode",level:2},{value:"Metadata Mutability",id:"metadata-mutability",level:2},{value:"BurnMode",id:"burnmode",level:2},{value:"OwnerReverseLookupMode",id:"ownerreverselookupmode",level:2},{value:"NamedKeyConventionMode",id:"namedkeyconventionmode",level:2},{value:"EventsMode",id:"eventsmode",level:2},{value:"Transfer Filter Hook",id:"transfer-filter-hook",level:3},{value:"CEP47 Mode",id:"cep47-mode",level:3},{value:"Casper Event Standard",id:"casper-event-standard",level:3},{value:"Modality Conflicts",id:"modality-conflicts",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cep-78-modalities",children:"CEP-78 Modalities"})}),"\n",(0,i.jsx)(n.p,{children:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior."}),"\n",(0,i.jsx)(n.h2,{id:"ownership",children:"Ownership"}),"\n",(0,i.jsx)(n.p,{children:"This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Minter"}),": ",(0,i.jsx)(n.code,{children:"Minter"})," mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the ",(0,i.jsx)(n.code,{children:"Minter"})," mode the owner of the NFT will not change and thus cannot be transferred to another entity."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Assigned"}),": ",(0,i.jsx)(n.code,{children:"Assigned"})," mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the ",(0,i.jsx)(n.code,{children:"Minter"})," mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Transferable"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode the owner of the newly minted NFT must be specified by the minter. However, in the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, NFTs can be transferred from the owner to another entity."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In all the three mentioned modes, the owner entity is currently restricted to ",(0,i.jsx)(n.code,{children:"Accounts"})," on the Casper network."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, it is possible to transfer the NFT to an ",(0,i.jsx)(n.code,{children:"Account"})," that does not exist."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"Ownership"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:'"ownership_mode"'})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Ownership"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Minter"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Assigned"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transferable"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ownership mode of a contract can be determined by querying the ",(0,i.jsx)(n.code,{children:"ownership_mode"})," entry within the contract's ",(0,i.jsx)(n.code,{children:"NamedKeys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"nftkind",children:"NFTKind"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality does not alter or govern the behavior of the contract itself\nand only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Physical"}),": The NFT represents a real-world physical item e.g., a house."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Digital"}),": The NFT represents a digital item, e.g., a unique JPEG or digital art."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Virtual"}),": The NFT is the virtual representation of a physical notion, e.g., a patent or copyright."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_kind"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Physical"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Digital"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftholdermode",children:"NFTHolderMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Accounts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Accounts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Contracts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mixed"}),": In this mode both ",(0,i.jsx)(n.code,{children:"Accounts"})," and ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," is set to ",(0,i.jsx)(n.code,{children:"Contracts"})," a ",(0,i.jsx)(n.code,{children:"ContractHash"})," whitelist must be provided. This whitelist dictates which\n",(0,i.jsx)(n.code,{children:"Contracts"})," are allowed to mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"Installer"})," minting mode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTHolderMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Accounts"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Contracts"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mixed"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Mixed"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_holder_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"whitelistmode",children:"WhitelistMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unlocked"}),": The ACL whitelist is unlocked and can be updated via the set variables endpoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Locked"}),": The ACL whitelist is locked and cannot be updated further."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is set to ",(0,i.jsx)(n.code,{children:"Locked"})," an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"ACL"})," minting mode. These entities include ",(0,i.jsx)(n.code,{children:"Accounts"})," and/or ",(0,i.jsx)(n.code,{children:"Contracts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"whitelist_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"WhitelistMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Unlocked"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Locked"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"minting",children:"Minting"}),"\n",(0,i.jsx)(n.p,{children:"The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Installer"}),": This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Public"}),": This mode allows any account to mint NFT tokens."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ACL"}),": This mode allows whitelisted accounts or contracts to mint NFT tokens."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Installer"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"minting_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MintingMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Installer"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Public"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ACL"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftmetadatakind",children:"NFTMetadataKind"}),"\n",(0,i.jsx)(n.p,{children:"This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP78"}),": This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NFT721"}),": This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Raw"}),": This mode specifies that metadata validation will not occur and raw strings can be passed to ",(0,i.jsx)(n.code,{children:"token_metadata"})," runtime argument as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CustomValidated"}),": This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["During installation, one ",(0,i.jsx)(n.code,{children:"NFTMetadataKind"})," must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the ",(0,i.jsx)(n.code,{children:"additional_required_metadata"})," or ",(0,i.jsx)(n.code,{children:"optional_metadata"})," arguments."]}),"\n",(0,i.jsx)(n.h3,{id:"cep-78-metadata-example",children:"CEP-78 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "token_uri": "https://www.barfoo.com",\n "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"nft-721-metadata-example",children:"NFT-721 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "symbol": "abc",\n "token_uri": "https://www.barfoo.com"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"custom-validated",children:"Custom Validated"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation.\nThe schema is passed as a String value to ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument at the time of installation. Once provided, the schema\nfor a given instance of the contract cannot be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["The custom JSON schema must contain a top-level ",(0,i.jsx)(n.code,{children:"properties"})," field. An example of a ",(0,i.jsx)(n.a,{href:"#example-custom-validated-schema",children:(0,i.jsx)(n.code,{children:"valid JSON schema"})})," is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata.\nIf the metadata kind is not set to custom validated, then the value passed to the ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument will be ignored."]}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-validated-schema",children:"Example Custom Validated schema"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "properties": {\n "deity_name": {\n "name": "deity_name",\n "description": "The name of deity from a particular pantheon.",\n "required": true\n },\n "mythology": {\n "name": "mythology",\n "description": "The mythology the deity belongs to.",\n "required": true\n }\n }\n}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-metadata",children:"Example Custom Metadata"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "deity_name": "Baldur",\n "mythology": "Nordic"\n}\n'})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTMetadataKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP78"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NFT721"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Raw"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CustomValidated"}),(0,i.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftidentifiermode",children:"NFTIdentifierMode"}),"\n",(0,i.jsx)(n.p,{children:"The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Ordinal"}),": NFTs minted in this modality are identified by a ",(0,i.jsx)(n.code,{children:"u64"})," value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Hash"}),": NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since the primary identifier in the ",(0,i.jsx)(n.code,{children:"Hash"})," mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint."]}),"\n",(0,i.jsxs)(n.p,{children:["Attempting to install the contract with the ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," modality set to ",(0,i.jsx)(n.code,{children:"Mutable"})," in the ",(0,i.jsx)(n.code,{children:"Hash"})," identifier mode will raise an error."]}),"\n",(0,i.jsx)(n.p,{children:"This modality is a required installation parameter and cannot be changed once the contract has been installed."}),"\n",(0,i.jsxs)(n.p,{children:["It is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"identifier_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTIdentifierMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ordinal"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Hash"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"metadata-mutability",children:"Metadata Mutability"}),"\n",(0,i.jsx)(n.p,{children:"The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Immutable"}),": Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mutable"}),": Metadata for NFTs minted in this mode can update the metadata via the ",(0,i.jsx)(n.code,{children:"set_token_metadata"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Mutable"})," option cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"Hash"})," modality for the NFT identifier; attempting to install the contract with this configuration raises ",(0,i.jsx)(n.code,{children:"InvalidMetadataMutability"})," error.\nThis modality is a required installation parameter and cannot be changed once the contract has been installed.\nIt is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"metadata_mutability"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MetadataMutability"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Immutable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mutable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"burnmode",children:"BurnMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"BurnMode"})," modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality\nprovides two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Burnable"}),": Minted tokens can be burnt."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NonBurnable"}),": Minted tokens cannot be burnt."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"BurnMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burnable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NonBurnable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Burnable"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"burn_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"ownerreverselookupmode",children:"OwnerReverseLookupMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides the following options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoLookup"}),": The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Complete"}),": The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/next/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransfersOnly"}),": The reporting and receipt functionality is supported like ",(0,i.jsx)(n.code,{children:"Complete"}),". However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/next/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, when set to ",(0,i.jsx)(n.code,{children:"Complete"}),", causes a receipt to be returned by the ",(0,i.jsx)(n.code,{children:"mint"})," or ",(0,i.jsx)(n.code,{children:"transfer"})," entrypoints, which the caller can store in their account or contract context for later reference."]}),"\n",(0,i.jsxs)(n.p,{children:["Further, two special entrypoints are enabled in ",(0,i.jsx)(n.code,{children:"Complete"})," mode. First, ",(0,i.jsx)(n.code,{children:"register_owner"})," which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, ",(0,i.jsx)(n.code,{children:"updated_receipts"}),", which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"OwnerReverseLookupMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoLookup"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Complete"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TransfersOnly"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"NoLookup"})," mode if not provided. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"owner_reverse_lookup_mode"})," runtime argument. This mode cannot be changed once the contract has been installed."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"ownership_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Minter"})," and the ",(0,i.jsx)(n.code,{children:"minting_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Installer"})," only, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"NoLookup"}),". This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,i.jsx)(n.code,{children:"TransfersOnly"})," then ",(0,i.jsx)(n.code,{children:"ownership_mode"})," has to be set to ",(0,i.jsx)(n.code,{children:"Transferable"})," only. This is because other ownership modes do not allow transfer."]}),"\n",(0,i.jsxs)(n.p,{children:["If you are upgrading a contract from CEP-78 version 1.0 to 1.1, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"Complete"}),", as this was the standard behavior of CEP-78 1.0. In addition to being set to ",(0,i.jsx)(n.code,{children:"Complete"}),", existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration."]}),"\n",(0,i.jsx)(n.p,{children:"If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option."}),"\n",(0,i.jsx)(n.h2,{id:"namedkeyconventionmode",children:"NamedKeyConventionMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NamedKeyConvention"})," modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"DerivedFromCollectionName"}),": This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's ",(0,i.jsx)(n.code,{children:"NamedKeys"})," as ",(0,i.jsx)(n.code,{children:"cep78_contract_package_<collection_name>"})," and ",(0,i.jsx)(n.code,{children:"cep78_contract_package_access_<collection_name>"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_standard"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries originally created during the 1.0 installation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_custom"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,i.jsx)(n.code,{children:"access_key_name"})," and ",(0,i.jsx)(n.code,{children:"hash_key_name"})," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NamedKeyConvention"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"DerivedFromCollectionName"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_standard"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_custom"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"eventsmode",children:"EventsMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."]}),"\n",(0,i.jsx)(n.p,{children:"The modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoEvents"}),": This modality will signal the contract to not record events at all. This is the default mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP47"}),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,i.jsx)(n.a,{href:"#cep47-mode",children:"below"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CES"}),": This modality will signal the contract to record events using the ",(0,i.jsx)(n.a,{href:"#casper-event-standard",children:"Casper Event Standard"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"EventsMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoEvents"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP47"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CES"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"transfer-filter-hook",children:"Transfer Filter Hook"}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,i.jsx)(n.code,{children:"transfer"})," method is invoked on the contract. CEP-78 will call the ",(0,i.jsx)(n.code,{children:"can_transfer"}),"\nmethod on the specified callback contract, which is expected to return a value of ",(0,i.jsx)(n.code,{children:"TransferFilterContractResult"}),", represented as a u8."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::DenyTransfer"})," will block the transfer regardless of the outcome of other checks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::ProceedTransfer"})," will allow the transfer to proceed if other checks also pass"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter can be enabled by passing a ",(0,i.jsx)(n.code,{children:"ARG_TRANSFER_FILTER_CONTRACT"})," argument to the install method, with a value of type ",(0,i.jsx)(n.code,{children:"Option<Key>"})]}),"\n",(0,i.jsx)(n.h3,{id:"cep47-mode",children:"CEP47 Mode"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP47 ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,i.jsx)(n.code,{children:"BTreeMap"})," within a dictionary (",(0,i.jsx)(n.code,{children:"EVENTS"}),") in the contract's context. Entries consist of the ",(0,i.jsx)(n.code,{children:"PREFIX_HASH_KEY_NAME"}),", followed by the ",(0,i.jsx)(n.code,{children:"EVENT_TYPE"})," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,i.jsx)(n.a,{href:"/next/concepts/dictionaries",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalGranted"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdate"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"token_id (String)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"casper-event-standard",children:"Casper Event Standard"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CES"})," is an option within the ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,i.jsx)(n.code,{children:"__events"})," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The emitted events are encoded according to the ",(0,i.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"Casper Event Standard"}),", and the schema is visible to an observer reading the ",(0,i.jsx)(n.code,{children:"__events_schema"})," contract named key."]}),"\n",(0,i.jsx)(n.p,{children:"For this CEP-78 reference implementation, the events schema is as follows:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Approval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdated"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"modality-conflicts",children:"Modality Conflicts"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," option set to ",(0,i.jsx)(n.code,{children:"Mutable"})," cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"NFTIdentifierMode"})," modality set to ",(0,i.jsx)(n.code,{children:"Hash"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const d={},s=i.createContext(d);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d4c529d3.d2c5e7bd.js b/assets/js/d4c529d3.d2c5e7bd.js new file mode 100644 index 000000000..a350d35f6 --- /dev/null +++ b/assets/js/d4c529d3.d2c5e7bd.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96379],{72319:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>a});var i=t(74848),d=t(28453);const s={title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},r="CEP-78 Modalities",o={id:"resources/tokens/cep78/modalities",title:"CEP-78 Modalities",description:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.",source:"@site/docs/resources/tokens/cep78/modalities.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/modalities",permalink:"/resources/tokens/cep78/modalities",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"CEP-78 Modalities",slug:"/resources/tokens/cep78/modalities"},sidebar:"resources",previous:{title:"Introduction",permalink:"/resources/tokens/cep78/introduction"},next:{title:"On-chain Installation",permalink:"/resources/tokens/using-casper-client"}},c={},a=[{value:"Ownership",id:"ownership",level:2},{value:"NFTKind",id:"nftkind",level:2},{value:"NFTHolderMode",id:"nftholdermode",level:2},{value:"WhitelistMode",id:"whitelistmode",level:2},{value:"Minting",id:"minting",level:2},{value:"NFTMetadataKind",id:"nftmetadatakind",level:2},{value:"CEP-78 metadata example",id:"cep-78-metadata-example",level:3},{value:"NFT-721 metadata example",id:"nft-721-metadata-example",level:3},{value:"Custom Validated",id:"custom-validated",level:3},{value:"Example Custom Validated schema",id:"example-custom-validated-schema",level:4},{value:"Example Custom Metadata",id:"example-custom-metadata",level:4},{value:"NFTIdentifierMode",id:"nftidentifiermode",level:2},{value:"Metadata Mutability",id:"metadata-mutability",level:2},{value:"BurnMode",id:"burnmode",level:2},{value:"OwnerReverseLookupMode",id:"ownerreverselookupmode",level:2},{value:"NamedKeyConventionMode",id:"namedkeyconventionmode",level:2},{value:"EventsMode",id:"eventsmode",level:2},{value:"Transfer Filter Hook",id:"transfer-filter-hook",level:3},{value:"CEP47 Mode",id:"cep47-mode",level:3},{value:"Casper Event Standard",id:"casper-event-standard",level:3},{value:"Modality Conflicts",id:"modality-conflicts",level:2}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,d.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cep-78-modalities",children:"CEP-78 Modalities"})}),"\n",(0,i.jsx)(n.p,{children:"The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior."}),"\n",(0,i.jsx)(n.h2,{id:"ownership",children:"Ownership"}),"\n",(0,i.jsx)(n.p,{children:"This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Minter"}),": ",(0,i.jsx)(n.code,{children:"Minter"})," mode is where the ownership of the newly minted NFT is attributed to the minter of the NFT and cannot be specified by the minter. In the ",(0,i.jsx)(n.code,{children:"Minter"})," mode the owner of the NFT will not change and thus cannot be transferred to another entity."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Assigned"}),": ",(0,i.jsx)(n.code,{children:"Assigned"})," mode is where the owner of the newly minted NFT must be specified by the minter of the NFT. In this mode, the assigned entity can be either minter themselves or a separate entity. However, similar to the ",(0,i.jsx)(n.code,{children:"Minter"})," mode, the ownership in this mode cannot be changed, and NFTs minted in this mode cannot be transferred from one entity to another."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Transferable"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode the owner of the newly minted NFT must be specified by the minter. However, in the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, NFTs can be transferred from the owner to another entity."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["In all the three mentioned modes, the owner entity is currently restricted to ",(0,i.jsx)(n.code,{children:"Accounts"})," on the Casper network."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"}),": In the ",(0,i.jsx)(n.code,{children:"Transferable"})," mode, it is possible to transfer the NFT to an ",(0,i.jsx)(n.code,{children:"Account"})," that does not exist."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"Ownership"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:'"ownership_mode"'})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Ownership"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Minter"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Assigned"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transferable"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["The ownership mode of a contract can be determined by querying the ",(0,i.jsx)(n.code,{children:"ownership_mode"})," entry within the contract's ",(0,i.jsx)(n.code,{children:"NamedKeys"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"nftkind",children:"NFTKind"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality specifies the commodity that NFTs minted by a particular contract will represent. Currently, the ",(0,i.jsx)(n.code,{children:"NFTKind"})," modality does not alter or govern the behavior of the contract itself\nand only exists to specify the correlation between on-chain data and off-chain items. There are three different variations of the ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode."]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Physical"}),": The NFT represents a real-world physical item e.g., a house."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Digital"}),": The NFT represents a digital item, e.g., a unique JPEG or digital art."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Virtual"}),": The NFT is the virtual representation of a physical notion, e.g., a patent or copyright."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTKind"})," mode is a required installation parameter and cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_kind"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Physical"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Digital"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Virtual"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftholdermode",children:"NFTHolderMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," dictates which entities on a Casper network can own and mint NFTs. There are three different options currently available:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Accounts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Accounts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Contracts"}),": In this mode, only ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mixed"}),": In this mode both ",(0,i.jsx)(n.code,{children:"Accounts"})," and ",(0,i.jsx)(n.code,{children:"Contracts"})," can own and mint NFTs."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"NFTHolderMode"})," is set to ",(0,i.jsx)(n.code,{children:"Contracts"})," a ",(0,i.jsx)(n.code,{children:"ContractHash"})," whitelist must be provided. This whitelist dictates which\n",(0,i.jsx)(n.code,{children:"Contracts"})," are allowed to mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"Installer"})," minting mode."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTHolderMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Accounts"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Contracts"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mixed"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Mixed"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed.\nThe mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"nft_holder_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"whitelistmode",children:"WhitelistMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," dictates if the ACL whitelist restricting access to the mint entry point can be updated. There are currently two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unlocked"}),": The ACL whitelist is unlocked and can be updated via the set variables endpoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Locked"}),": The ACL whitelist is locked and cannot be updated further."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If the ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is set to ",(0,i.jsx)(n.code,{children:"Locked"})," an ACL whitelist of entity keys must be provided on installation. This whitelist dictates which entities can mint NFTs in the restricted ",(0,i.jsx)(n.code,{children:"ACL"})," minting mode. These entities include ",(0,i.jsx)(n.code,{children:"Accounts"})," and/or ",(0,i.jsx)(n.code,{children:"Contracts"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["This ",(0,i.jsx)(n.code,{children:"WhitelistMode"})," is an optional installation parameter and will be set to unlocked if not passed. However, the whitelist mode itself cannot be changed once the contract has been installed. The mode is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to ",(0,i.jsx)(n.code,{children:"whitelist_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"WhitelistMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Unlocked"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Locked"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"minting",children:"Minting"}),"\n",(0,i.jsx)(n.p,{children:"The minting mode governs the behavior of contract when minting new tokens. The minting modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Installer"}),": This mode restricts the ability to mint new NFT tokens only to the installing account of the NFT contract."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Public"}),": This mode allows any account to mint NFT tokens."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ACL"}),": This mode allows whitelisted accounts or contracts to mint NFT tokens."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Installer"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"minting_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MintingMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Installer"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Public"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ACL"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftmetadatakind",children:"NFTMetadataKind"}),"\n",(0,i.jsx)(n.p,{children:"This modality dictates the schema for the metadata for NFTs minted by a given instance of an NFT contract. There are four supported modalities:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP78"}),": This mode specifies that NFTs minted must have valid metadata conforming to the CEP-78 schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NFT721"}),": This mode specifies that NFTs minted must have valid metadata conforming to the NFT-721 metadata schema."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Raw"}),": This mode specifies that metadata validation will not occur and raw strings can be passed to ",(0,i.jsx)(n.code,{children:"token_metadata"})," runtime argument as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CustomValidated"}),": This mode specifies that a custom schema provided at the time of install will be used when validating the metadata as part of the call to ",(0,i.jsx)(n.code,{children:"mint"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["During installation, one ",(0,i.jsx)(n.code,{children:"NFTMetadataKind"})," must be chosen as the base metadata kind for the contract instance. Additional kinds may be included using either the ",(0,i.jsx)(n.code,{children:"additional_required_metadata"})," or ",(0,i.jsx)(n.code,{children:"optional_metadata"})," arguments."]}),"\n",(0,i.jsx)(n.h3,{id:"cep-78-metadata-example",children:"CEP-78 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "token_uri": "https://www.barfoo.com",\n "checksum": "940bffb3f2bba35f84313aa26da09ece3ad47045c6a1292c2bbd2df4ab1a55fb"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"nft-721-metadata-example",children:"NFT-721 metadata example"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "John Doe",\n "symbol": "abc",\n "token_uri": "https://www.barfoo.com"\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"custom-validated",children:"Custom Validated"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP-78 implementation allows installers of the contract to provide their custom schema at the time of installation.\nThe schema is passed as a String value to ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument at the time of installation. Once provided, the schema\nfor a given instance of the contract cannot be changed."]}),"\n",(0,i.jsxs)(n.p,{children:["The custom JSON schema must contain a top-level ",(0,i.jsx)(n.code,{children:"properties"})," field. An example of a ",(0,i.jsx)(n.a,{href:"#example-custom-validated-schema",children:(0,i.jsx)(n.code,{children:"valid JSON schema"})})," is provided. In this example, each property has a name, the description of the property itself, and whether the property is required to be present in the metadata.\nIf the metadata kind is not set to custom validated, then the value passed to the ",(0,i.jsx)(n.code,{children:"json_schema"})," runtime argument will be ignored."]}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-validated-schema",children:"Example Custom Validated schema"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "properties": {\n "deity_name": {\n "name": "deity_name",\n "description": "The name of deity from a particular pantheon.",\n "required": true\n },\n "mythology": {\n "name": "mythology",\n "description": "The mythology the deity belongs to.",\n "required": true\n }\n }\n}\n'})}),"\n",(0,i.jsx)(n.h4,{id:"example-custom-metadata",children:"Example Custom Metadata"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "deity_name": "Baldur",\n "mythology": "Nordic"\n}\n'})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTMetadataKind"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP78"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NFT721"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Raw"}),(0,i.jsx)(n.td,{children:"2"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CustomValidated"}),(0,i.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"nftidentifiermode",children:"NFTIdentifierMode"}),"\n",(0,i.jsx)(n.p,{children:"The identifier mode governs the primary identifier for NFTs minted for a given instance on an installed contract. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Ordinal"}),": NFTs minted in this modality are identified by a ",(0,i.jsx)(n.code,{children:"u64"})," value. This value is determined by the number of NFTs minted by the contract at the time the NFT is minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Hash"}),": NFTs minted in this modality are identified by a base16 encoded representation of the blake2b hash of the metadata provided at the time of mint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Since the primary identifier in the ",(0,i.jsx)(n.code,{children:"Hash"})," mode is derived by hashing over the metadata, making it a content-addressed identifier, the metadata for the minted NFT cannot be updated after the mint."]}),"\n",(0,i.jsxs)(n.p,{children:["Attempting to install the contract with the ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," modality set to ",(0,i.jsx)(n.code,{children:"Mutable"})," in the ",(0,i.jsx)(n.code,{children:"Hash"})," identifier mode will raise an error."]}),"\n",(0,i.jsx)(n.p,{children:"This modality is a required installation parameter and cannot be changed once the contract has been installed."}),"\n",(0,i.jsxs)(n.p,{children:["It is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"identifier_mode"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NFTIdentifierMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Ordinal"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Hash"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"metadata-mutability",children:"Metadata Mutability"}),"\n",(0,i.jsx)(n.p,{children:"The metadata mutability mode governs the behavior around updates to a given NFTs metadata. This modality provides two options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Immutable"}),": Metadata for NFTs minted in this mode cannot be updated once the NFT has been minted."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Mutable"}),": Metadata for NFTs minted in this mode can update the metadata via the ",(0,i.jsx)(n.code,{children:"set_token_metadata"})," entrypoint."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"Mutable"})," option cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"Hash"})," modality for the NFT identifier; attempting to install the contract with this configuration raises ",(0,i.jsx)(n.code,{children:"InvalidMetadataMutability"})," error.\nThis modality is a required installation parameter and cannot be changed once the contract has been installed.\nIt is passed in as a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"metadata_mutability"})," runtime argument."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"MetadataMutability"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Immutable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mutable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"burnmode",children:"BurnMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"BurnMode"})," modality dictates whether tokens minted by a given instance of an NFT contract can be burnt. This modality\nprovides two options:"]}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Burnable"}),": Minted tokens can be burnt."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NonBurnable"}),": Minted tokens cannot be burnt."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"BurnMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burnable"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NonBurnable"}),(0,i.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"Burnable"})," mode if not provided. However, this\nmode cannot be changed once the contract has been installed. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"burn_mode"})," runtime argument."]}),"\n",(0,i.jsx)(n.h2,{id:"ownerreverselookupmode",children:"OwnerReverseLookupMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," modality is set at install and determines if a given contract instance writes necessary data to allow reverse lookup by owner in addition to by ID."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides the following options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoLookup"}),": The reporting and receipt functionality is not supported. In this option, the contract instance does not maintain a reverse lookup database of ownership and therefore has more predictable gas costs and greater scaling."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Complete"}),": The reporting and receipt functionality is supported. Token ownership will be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransfersOnly"}),": The reporting and receipt functionality is supported like ",(0,i.jsx)(n.code,{children:"Complete"}),". However, it does not begin tracking until the first transfer. This modality is for use cases where the majority of NFTs are owned by a private minter and only NFT's that have been transferred benefit from reverse lookup tracking. Token ownership will also be tracked by the contract instance using the system described ",(0,i.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup",children:"here"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["Additionally, when set to ",(0,i.jsx)(n.code,{children:"Complete"}),", causes a receipt to be returned by the ",(0,i.jsx)(n.code,{children:"mint"})," or ",(0,i.jsx)(n.code,{children:"transfer"})," entrypoints, which the caller can store in their account or contract context for later reference."]}),"\n",(0,i.jsxs)(n.p,{children:["Further, two special entrypoints are enabled in ",(0,i.jsx)(n.code,{children:"Complete"})," mode. First, ",(0,i.jsx)(n.code,{children:"register_owner"})," which when called will allocate the necessary tracking record for the imputed entity. This allows isolation of the one time gas cost to do this per owner, which is convenient for accounting purposes. Second, ",(0,i.jsx)(n.code,{children:"updated_receipts"}),", which allows an owner of one or more NFTs held by the contract instance to attain up to date receipt information for the NFTs they currently own."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"OwnerReverseLookupMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoLookup"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Complete"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"TransfersOnly"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsxs)(n.p,{children:["This modality is an optional installation parameter and will default to the ",(0,i.jsx)(n.code,{children:"NoLookup"})," mode if not provided. The mode is set by passing a ",(0,i.jsx)(n.code,{children:"u8"})," value to the ",(0,i.jsx)(n.code,{children:"owner_reverse_lookup_mode"})," runtime argument. This mode cannot be changed once the contract has been installed."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"ownership_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Minter"})," and the ",(0,i.jsx)(n.code,{children:"minting_mode"})," is set to ",(0,i.jsx)(n.code,{children:"Installer"})," only, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"NoLookup"}),". This is because the minter, by definition, owns all of the tokens forever. Therefore, there is no reason to do a reverse lookup for that owner. This rule applies only to newly installed contract instances."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.strong,{children:"Note"})," : if ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,i.jsx)(n.code,{children:"TransfersOnly"})," then ",(0,i.jsx)(n.code,{children:"ownership_mode"})," has to be set to ",(0,i.jsx)(n.code,{children:"Transferable"})," only. This is because other ownership modes do not allow transfer."]}),"\n",(0,i.jsxs)(n.p,{children:["If you are upgrading a contract from CEP-78 version 1.0 to 1.1, ",(0,i.jsx)(n.code,{children:"OwnerReverseLookupMode"})," will be set to ",(0,i.jsx)(n.code,{children:"Complete"}),", as this was the standard behavior of CEP-78 1.0. In addition to being set to ",(0,i.jsx)(n.code,{children:"Complete"}),", existing records will be migrated into the CEP-78 1.1 format, which will impose a one-time gas cost to cover the migration."]}),"\n",(0,i.jsx)(n.p,{children:"If you have an existing CEP-78 version 1.0 contract instance, and would prefer the newer functionality with no lookup, the only option is to install a separate, new contract instance and mint all of the NFTs anew in that instance and then burn the corresponding NFTs from the old instance. If you do not own all the NFTs held by the old contract instance, you do not have this option."}),"\n",(0,i.jsx)(n.h2,{id:"namedkeyconventionmode",children:"NamedKeyConventionMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"NamedKeyConvention"})," modality dictates whether the Wasm passed will attempt to install a version 1.1.1 instance of CEP-78 or attempt to migrate a version 1.0 CEP-78 instance to version 1.1.1."]}),"\n",(0,i.jsx)(n.p,{children:"This modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"DerivedFromCollectionName"}),": This modality will signal the contract to attempt to install a new version 1.1.1 instance of the CEP-78 contract. The contract package hash and the access URef will be saved in the installing account's ",(0,i.jsx)(n.code,{children:"NamedKeys"})," as ",(0,i.jsx)(n.code,{children:"cep78_contract_package_<collection_name>"})," and ",(0,i.jsx)(n.code,{children:"cep78_contract_package_access_<collection_name>"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_standard"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the contract will retrieve the package hash and the access URef from the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries originally created during the 1.0 installation."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"V_1_0_custom"}),": This modality will signal the contract to attempt to upgrade from version 1.0 to version 1.1.1. In this scenario, the calling account must provide the ",(0,i.jsx)(n.code,{children:"NamedKey"})," entries under which the package hash and the access URef are saved. Additionally, this requires the passing of the runtime arguments ",(0,i.jsx)(n.code,{children:"access_key_name"})," and ",(0,i.jsx)(n.code,{children:"hash_key_name"})," for the access URef and package hash, respectively. In this modality, these arguments are required and must be passed in."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"NamedKeyConvention"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"DerivedFromCollectionName"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_standard"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"V_1_0_custom"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"eventsmode",children:"EventsMode"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality determines how the installed instance of CEP-78 will handle the recording of events that occur from interacting with the contract."]}),"\n",(0,i.jsx)(n.p,{children:"The modality provides three options:"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"NoEvents"}),": This modality will signal the contract to not record events at all. This is the default mode."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CEP47"}),": This modality will signal the contract to record events using the CEP47 event schema. Further information can be found ",(0,i.jsx)(n.a,{href:"#cep47-mode",children:"below"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"CES"}),": This modality will signal the contract to record events using the ",(0,i.jsx)(n.a,{href:"#casper-event-standard",children:"Casper Event Standard"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"EventsMode"}),(0,i.jsx)(n.th,{children:"u8"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"NoEvents"}),(0,i.jsx)(n.td,{children:"0"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CEP47"}),(0,i.jsx)(n.td,{children:"1"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"CES"}),(0,i.jsx)(n.td,{children:"2"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"transfer-filter-hook",children:"Transfer Filter Hook"}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter modality, if enabled, specifies a contract package hash pointing to a contract that will be called when the ",(0,i.jsx)(n.code,{children:"transfer"})," method is invoked on the contract. CEP-78 will call the ",(0,i.jsx)(n.code,{children:"can_transfer"}),"\nmethod on the specified callback contract, which is expected to return a value of ",(0,i.jsx)(n.code,{children:"TransferFilterContractResult"}),", represented as a u8."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::DenyTransfer"})," will block the transfer regardless of the outcome of other checks"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"TransferFilterContractResult::ProceedTransfer"})," will allow the transfer to proceed if other checks also pass"]}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["The transfer filter can be enabled by passing a ",(0,i.jsx)(n.code,{children:"ARG_TRANSFER_FILTER_CONTRACT"})," argument to the install method, with a value of type ",(0,i.jsx)(n.code,{children:"Option<Key>"})]}),"\n",(0,i.jsx)(n.h3,{id:"cep47-mode",children:"CEP47 Mode"}),"\n",(0,i.jsxs)(n.p,{children:["The CEP47 ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality mimics the event schema previously used in the CEP47 NFT standard. Events are stored as a ",(0,i.jsx)(n.code,{children:"BTreeMap"})," within a dictionary (",(0,i.jsx)(n.code,{children:"EVENTS"}),") in the contract's context. Entries consist of the ",(0,i.jsx)(n.code,{children:"PREFIX_HASH_KEY_NAME"}),", followed by the ",(0,i.jsx)(n.code,{children:"EVENT_TYPE"})," and then variable data as listed in the table below. The events can be retrieved directly via their dictionary entry using the JSON-RPC, with more information on this process available ",(0,i.jsx)(n.a,{href:"/concepts/dictionaries",children:"here"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalGranted"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdate"}),(0,i.jsx)(n.td,{children:(0,i.jsx)(n.code,{children:"token_id (String)"})})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h3,{id:"casper-event-standard",children:"Casper Event Standard"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"CES"})," is an option within the ",(0,i.jsx)(n.code,{children:"EventsMode"})," modality that determines how changes to tokens issued by the contract instance will be recorded. Any changes are recorded in the ",(0,i.jsx)(n.code,{children:"__events"})," dictionary and can be observed via a node's Server Side Events stream. They may also be viewed by querying the dictionary at any time using the JSON-RPC interface."]}),"\n",(0,i.jsxs)(n.p,{children:["The emitted events are encoded according to the ",(0,i.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"Casper Event Standard"}),", and the schema is visible to an observer reading the ",(0,i.jsx)(n.code,{children:"__events_schema"})," contract named key."]}),"\n",(0,i.jsx)(n.p,{children:"For this CEP-78 reference implementation, the events schema is as follows:"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(n.table,{children:[(0,i.jsx)(n.thead,{children:(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.th,{children:"Event name"}),(0,i.jsx)(n.th,{children:"Included values and type"})]})}),(0,i.jsxs)(n.tbody,{children:[(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Mint"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Transfer"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Option<Key>)"}),", ",(0,i.jsx)(n.code,{children:"recipient (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Burn"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Approval"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"spender (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalRevoked"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"token_id (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"ApprovalForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"RevokedForAll"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"owner (Key)"}),", ",(0,i.jsx)(n.code,{children:"operator (Key)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"MetadataUpdated"}),(0,i.jsxs)(n.td,{children:[(0,i.jsx)(n.code,{children:"token_id (String)"}),", ",(0,i.jsx)(n.code,{children:"data (String)"})]})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"Migration"}),(0,i.jsx)(n.td,{children:"-"})]}),(0,i.jsxs)(n.tr,{children:[(0,i.jsx)(n.td,{children:"VariablesSet"}),(0,i.jsx)(n.td,{children:"-"})]})]})]}),"\n",(0,i.jsx)(n.h2,{id:"modality-conflicts",children:"Modality Conflicts"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"MetadataMutability"})," option set to ",(0,i.jsx)(n.code,{children:"Mutable"})," cannot be used in conjunction with the ",(0,i.jsx)(n.code,{children:"NFTIdentifierMode"})," modality set to ",(0,i.jsx)(n.code,{children:"Hash"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var i=t(96540);const d={},s=i.createContext(d);function r(e){const n=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),i.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d629d828.9452bae9.js b/assets/js/d629d828.9452bae9.js new file mode 100644 index 000000000..331bc77c7 --- /dev/null +++ b/assets/js/d629d828.9452bae9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[86660],{76895:e=>{e.exports=JSON.parse('{"version":{"pluginId":"default","version":"1.5.X","label":"1.5.X","banner":"unmaintained","badge":true,"noIndex":false,"className":"docs-version-1.5.X","isLast":false,"docsSidebars":{"concepts":[{"type":"link","label":"Overview","href":"/1.5.X/concepts/","docId":"concepts/index","unlisted":false},{"type":"link","label":"What is Casper?","href":"/1.5.X/","docId":"concepts/about","unlisted":false},{"type":"link","label":"dApps","href":"/1.5.X/concepts/intro-to-dapps","docId":"concepts/intro-to-dapps","unlisted":false},{"type":"link","label":"Accounts and Keys","href":"/1.5.X/concepts/accounts-and-keys","docId":"concepts/accounts-and-keys","unlisted":false},{"type":"link","label":"Hash Types","href":"/1.5.X/concepts/hash-types","docId":"concepts/hash-types","unlisted":false},{"type":"link","label":"Deploy Lifecycle","href":"/1.5.X/deploy-and-deploy-lifecycle","docId":"concepts/deploy-and-deploy-lifecycle","unlisted":false},{"type":"link","label":"Global State","href":"/1.5.X/concepts/global-state","docId":"concepts/global-state","unlisted":false},{"type":"link","label":"Smart Contracts","href":"/1.5.X/concepts/smart-contracts","docId":"concepts/smart-contracts","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/1.5.X/concepts/list-auth-keys","docId":"concepts/list-auth-keys","unlisted":false},{"type":"link","label":"Call Stacks","href":"/1.5.X/concepts/callstack","docId":"concepts/callstack","unlisted":false},{"type":"link","label":"Dictionaries","href":"/1.5.X/concepts/dictionaries","docId":"concepts/dictionaries","unlisted":false},{"type":"link","label":"Serialization Standard","href":"/1.5.X/concepts/serialization-standard","docId":"concepts/serialization-standard","unlisted":false},{"type":"category","label":"Design","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Network Design","href":"/1.5.X/concepts/design/casper-design","docId":"concepts/design/casper-design","unlisted":false},{"type":"link","label":"Network Communication","href":"/1.5.X/concepts/design/p2p","docId":"concepts/design/p2p","unlisted":false},{"type":"link","label":"Highway Consensus","href":"/1.5.X/concepts/design/highway","docId":"concepts/design/highway","unlisted":false},{"type":"link","label":"Reading and Writing Data","href":"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain","docId":"concepts/design/reading-and-writing-to-the-blockchain","unlisted":false}],"href":"/1.5.X/design"},{"type":"category","label":"Economics","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Consensus","href":"/1.5.X/concepts/economics/consensus","docId":"concepts/economics/consensus","unlisted":false},{"type":"link","label":"Runtime","href":"/1.5.X/runtime","docId":"concepts/economics/runtime","unlisted":false},{"type":"link","label":"Gas Cost","href":"/1.5.X/concepts/economics/gas-concepts","docId":"concepts/economics/gas-concepts","unlisted":false},{"type":"category","label":"Staking","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Staking vs. Delegating","href":"/1.5.X/staking","docId":"concepts/economics/staking/staking","unlisted":false},{"type":"link","label":"Delegation Details","href":"/1.5.X/concepts/economics/delegation","docId":"concepts/economics/staking/delegation","unlisted":false}],"href":"/1.5.X/concepts/economics/concepts"}],"href":"/1.5.X/economics"},{"type":"category","label":"Glossary","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"A","href":"/1.5.X/concepts/glossary/A","docId":"concepts/glossary/A","unlisted":false},{"type":"link","label":"B","href":"/1.5.X/concepts/glossary/B","docId":"concepts/glossary/B","unlisted":false},{"type":"link","label":"C","href":"/1.5.X/concepts/glossary/C","docId":"concepts/glossary/C","unlisted":false},{"type":"link","label":"D","href":"/1.5.X/concepts/glossary/D","docId":"concepts/glossary/D","unlisted":false},{"type":"link","label":"E","href":"/1.5.X/concepts/glossary/E","docId":"concepts/glossary/E","unlisted":false},{"type":"link","label":"F","href":"/1.5.X/concepts/glossary/F","docId":"concepts/glossary/F","unlisted":false},{"type":"link","label":"G","href":"/1.5.X/concepts/glossary/G","docId":"concepts/glossary/G","unlisted":false},{"type":"link","label":"H","href":"/1.5.X/concepts/glossary/H","docId":"concepts/glossary/H","unlisted":false},{"type":"link","label":"I","href":"/1.5.X/concepts/glossary/I","docId":"concepts/glossary/I","unlisted":false},{"type":"link","label":"J","href":"/1.5.X/concepts/glossary/J","docId":"concepts/glossary/J","unlisted":false},{"type":"link","label":"K","href":"/1.5.X/concepts/glossary/K","docId":"concepts/glossary/K","unlisted":false},{"type":"link","label":"L","href":"/1.5.X/concepts/glossary/L","docId":"concepts/glossary/L","unlisted":false},{"type":"link","label":"M","href":"/1.5.X/concepts/glossary/M","docId":"concepts/glossary/M","unlisted":false},{"type":"link","label":"N","href":"/1.5.X/concepts/glossary/N","docId":"concepts/glossary/N","unlisted":false},{"type":"link","label":"O","href":"/1.5.X/concepts/glossary/O","docId":"concepts/glossary/O","unlisted":false},{"type":"link","label":"P","href":"/1.5.X/concepts/glossary/P","docId":"concepts/glossary/P","unlisted":false},{"type":"link","label":"Q","href":"/1.5.X/concepts/glossary/Q","docId":"concepts/glossary/Q","unlisted":false},{"type":"link","label":"R","href":"/1.5.X/concepts/glossary/R","docId":"concepts/glossary/R","unlisted":false},{"type":"link","label":"S","href":"/1.5.X/concepts/glossary/S","docId":"concepts/glossary/S","unlisted":false},{"type":"link","label":"T","href":"/1.5.X/concepts/glossary/T","docId":"concepts/glossary/T","unlisted":false},{"type":"link","label":"U","href":"/1.5.X/concepts/glossary/U","docId":"concepts/glossary/U","unlisted":false},{"type":"link","label":"V","href":"/1.5.X/concepts/glossary/V","docId":"concepts/glossary/V","unlisted":false},{"type":"link","label":"W","href":"/1.5.X/concepts/glossary/W","docId":"concepts/glossary/W","unlisted":false},{"type":"link","label":"X","href":"/1.5.X/concepts/glossary/X","docId":"concepts/glossary/X","unlisted":false},{"type":"link","label":"Y","href":"/1.5.X/concepts/glossary/Y","docId":"concepts/glossary/Y","unlisted":false},{"type":"link","label":"Z","href":"/1.5.X/concepts/glossary/Z","docId":"concepts/glossary/Z","unlisted":false}],"href":"/1.5.X/glossary"}],"developers":[{"type":"link","label":"Overview","href":"/1.5.X/developers","docId":"developers/index","unlisted":false},{"type":"link","label":"Development Prerequisites","href":"/1.5.X/developers/prerequisites","docId":"developers/prerequisites","unlisted":false},{"type":"link","label":"Essential Rust Crates","href":"/1.5.X/developers/essential-crates","docId":"developers/essential-crates","unlisted":false},{"type":"category","label":"Writing On-Chain Code","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started with Rust","href":"/1.5.X/developers/writing-onchain-code/getting-started","docId":"developers/writing-onchain-code/getting-started","unlisted":false},{"type":"link","label":"Getting Started with AssemblyScript","href":"/1.5.X/developers/writing-onchain-code/assembly-script","docId":"developers/writing-onchain-code/assembly-script","unlisted":false},{"type":"link","label":"Writing a Basic Smart Contract in Rust","href":"/1.5.X/developers/writing-onchain-code/simple-contract","docId":"developers/writing-onchain-code/simple-contract","unlisted":false},{"type":"link","label":"Testing Smart Contracts","href":"/1.5.X/developers/writing-onchain-code/testing-contracts","docId":"developers/writing-onchain-code/testing-contracts","unlisted":false},{"type":"link","label":"Upgrading and Maintaining Smart Contracts","href":"/1.5.X/developers/writing-onchain-code/upgrading-contracts","docId":"developers/writing-onchain-code/upgrading-contracts","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/1.5.X/developers/writing-onchain-code/calling-contracts","docId":"developers/writing-onchain-code/calling-contracts","unlisted":false},{"type":"link","label":"Contracts and Session Code","href":"/1.5.X/developers/writing-onchain-code/contract-vs-session","docId":"developers/writing-onchain-code/contract-vs-session","unlisted":false},{"type":"link","label":"Writing Session Code","href":"/1.5.X/developers/writing-onchain-code/writing-session-code","docId":"developers/writing-onchain-code/writing-session-code","unlisted":false},{"type":"link","label":"Testing Session Code","href":"/1.5.X/developers/writing-onchain-code/testing-session-code","docId":"developers/writing-onchain-code/testing-session-code","unlisted":false},{"type":"link","label":"Contract Hash vs. Package Hash","href":"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash","docId":"developers/writing-onchain-code/contract-hash-vs-package-hash","unlisted":false},{"type":"link","label":"Best Practices for Casper Smart Contract Authors","href":"/1.5.X/developers/writing-onchain-code/best-practices","docId":"developers/writing-onchain-code/best-practices","unlisted":false}],"href":"/1.5.X/writing-contracts"},{"type":"category","label":"Casper JSON-RPC API","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Guidance for JSON-RPC SDK Compliance","href":"/1.5.X/developers/json-rpc/guidance","docId":"developers/json-rpc/guidance","unlisted":false},{"type":"link","label":"Required Methods for Minimal Compliance","href":"/1.5.X/developers/json-rpc/minimal-compliance","docId":"developers/json-rpc/minimal-compliance","unlisted":false},{"type":"link","label":"Transactional JSON-RPC Methods","href":"/1.5.X/developers/json-rpc/json-rpc-transactional","docId":"developers/json-rpc/json-rpc-transactional","unlisted":false},{"type":"link","label":"Informational JSON-RPC Methods","href":"/1.5.X/developers/json-rpc/json-rpc-informational","docId":"developers/json-rpc/json-rpc-informational","unlisted":false},{"type":"link","label":"Proof-of-Stake JSON-RPC Methods","href":"/1.5.X/developers/json-rpc/json-rpc-pos","docId":"developers/json-rpc/json-rpc-pos","unlisted":false},{"type":"link","label":"Types","href":"/1.5.X/developers/json-rpc/types_chain","docId":"developers/json-rpc/types_chain","unlisted":false},{"type":"link","label":"CLType","href":"/1.5.X/developers/json-rpc/types_cl","docId":"developers/json-rpc/types_cl","unlisted":false}],"href":"/1.5.X/developers/json-rpc/"},{"type":"category","label":"Building dApps","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"What is a dApp?","href":"/1.5.X/developers/dapps/dapp","docId":"developers/dapps/dapp","unlisted":false},{"type":"link","label":"Prerequisites","href":"/1.5.X/developers/dapps/prerequisites","docId":"developers/dapps/prerequisites","unlisted":false},{"type":"category","label":"SDK Client Libraries","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"SDK Client Library Usage","href":"/1.5.X/developers/dapps/sdk/client-library-usage","docId":"developers/dapps/sdk/client-library-usage","unlisted":false},{"type":"link","label":"JavaScript/TypeScript SDK","href":"/1.5.X/developers/dapps/sdk/script-sdk","docId":"developers/dapps/sdk/script-sdk","unlisted":false},{"type":"link","label":".NET SDK","href":"/1.5.X/developers/dapps/sdk/csharp-sdk","docId":"developers/dapps/sdk/csharp-sdk","unlisted":false},{"type":"link","label":"Go SDK","href":"/1.5.X/developers/dapps/sdk/go-sdk","docId":"developers/dapps/sdk/go-sdk","unlisted":false},{"type":"link","label":"Python SDK","href":"/1.5.X/developers/dapps/sdk/python-sdk","docId":"developers/dapps/sdk/python-sdk","unlisted":false}],"href":"/1.5.X/sdk"},{"type":"link","label":"dApp Technology Stack","href":"/1.5.X/developers/dapps/technology-stack","docId":"developers/dapps/technology-stack","unlisted":false},{"type":"link","label":"Front-end in React","href":"/1.5.X/developers/dapps/template-frontend","docId":"developers/dapps/template-frontend","unlisted":false},{"type":"link","label":"URef Access Rights","href":"/1.5.X/developers/dapps/uref-security","docId":"developers/dapps/uref-security","unlisted":false},{"type":"link","label":"Signing Deploys","href":"/1.5.X/developers/dapps/signing-a-deploy","docId":"developers/dapps/signing-a-deploy","unlisted":false},{"type":"link","label":"Estimating Gas Costs with Speculative Execution","href":"/1.5.X/developers/dapps/speculative-exec","docId":"developers/dapps/speculative-exec","unlisted":false},{"type":"link","label":"Local Network Setup","href":"/1.5.X/developers/dapps/setup-nctl","docId":"developers/dapps/setup-nctl","unlisted":false},{"type":"link","label":"Local Network Testing","href":"/1.5.X/developers/dapps/nctl-test","docId":"developers/dapps/nctl-test","unlisted":false},{"type":"link","label":"Monitoring and Consuming Events","href":"/1.5.X/developers/dapps/monitor-and-consume-events","docId":"developers/dapps/monitor-and-consume-events","unlisted":false}],"href":"/1.5.X/developers/dapps/"},{"type":"category","label":"Interacting with the Blockchain","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Transferring Tokens","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Direct Token Transfer","href":"/1.5.X/developers/cli/transfers/direct-token-transfer","docId":"developers/cli/transfers/direct-token-transfer","unlisted":false},{"type":"link","label":"Transferring Tokens using a Multi-Sig Deploy","href":"/1.5.X/developers/cli/transfers/multisig-deploy-transfer","docId":"developers/cli/transfers/multisig-deploy-transfer","unlisted":false},{"type":"link","label":"Verifying a Transfer","href":"/1.5.X/developers/cli/transfers/verify-transfer","docId":"developers/cli/transfers/verify-transfer","unlisted":false}],"href":"/1.5.X/developers/cli/transfers/"},{"type":"link","label":"Delegating Tokens","href":"/1.5.X/developers/cli/delegate","docId":"developers/cli/delegate","unlisted":false},{"type":"link","label":"Redelegating Tokens with the Casper Client","href":"/1.5.X/developers/cli/redelegate","docId":"developers/cli/redelegate","unlisted":false},{"type":"link","label":"Undelegating Tokens","href":"/1.5.X/developers/cli/undelegate","docId":"developers/cli/undelegate","unlisted":false},{"type":"link","label":"Sending Deploys","href":"/1.5.X/developers/cli/sending-deploys","docId":"developers/cli/sending-deploys","unlisted":false},{"type":"link","label":"Installing Contracts","href":"/1.5.X/developers/cli/installing-contracts","docId":"developers/cli/installing-contracts","unlisted":false},{"type":"link","label":"Querying Global State","href":"/1.5.X/developers/cli/querying-global-state","docId":"developers/cli/querying-global-state","unlisted":false},{"type":"link","label":"Calling Contracts","href":"/1.5.X/developers/cli/calling-contracts","docId":"developers/cli/calling-contracts","unlisted":false},{"type":"link","label":"OpCode Costs Tables","href":"/1.5.X/developers/cli/opcode-costs","docId":"developers/cli/opcode-costs","unlisted":false},{"type":"link","label":"Execution Error Codes","href":"/1.5.X/developers/cli/execution-error-codes","docId":"developers/cli/execution-error-codes","unlisted":false}],"href":"/1.5.X/developers/cli/"}],"operators":[{"type":"link","label":"Overview","href":"/1.5.X/operators","docId":"operators/index","unlisted":false},{"type":"category","label":"Node Setup","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Hardware","href":"/1.5.X/operators/setup/hardware","docId":"operators/setup/hardware","unlisted":false},{"type":"link","label":"Configuration","href":"/1.5.X/operators/setup/basic-node-configuration","docId":"operators/setup/basic-node-configuration","unlisted":false},{"type":"link","label":"Endpoints","href":"/1.5.X/operators/setup/node-endpoints","docId":"operators/setup/node-endpoints","unlisted":false},{"type":"link","label":"Installation","href":"/1.5.X/operators/setup/install-node","docId":"operators/setup/install-node","unlisted":false},{"type":"link","label":"Fast Sync","href":"/1.5.X/operators/setup/fast-sync","docId":"operators/setup/fast-sync","unlisted":false},{"type":"link","label":"Open Files Limit","href":"/1.5.X/operators/setup/open-files","docId":"operators/setup/open-files","unlisted":false},{"type":"link","label":"Upgrades","href":"/1.5.X/operators/setup/upgrade","docId":"operators/setup/upgrade","unlisted":false},{"type":"link","label":"Join a Network","href":"/1.5.X/operators/setup/joining","docId":"operators/setup/joining","unlisted":false},{"type":"link","label":"Non-Root Users","href":"/1.5.X/operators/setup/non-root-user","docId":"operators/setup/non-root-user","unlisted":false}],"href":"/1.5.X/operators/setup/"},{"type":"category","label":"Validators","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Bonding","href":"/1.5.X/operators/becoming-a-validator/bonding","docId":"operators/becoming-a-validator/bonding","unlisted":false},{"type":"link","label":"Unbonding","href":"/1.5.X/operators/becoming-a-validator/unbonding","docId":"operators/becoming-a-validator/unbonding","unlisted":false},{"type":"link","label":"Recovery","href":"/1.5.X/operators/becoming-a-validator/recovering","docId":"operators/becoming-a-validator/recovering","unlisted":false},{"type":"link","label":"Inactive and Faulty Nodes","href":"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty","docId":"operators/becoming-a-validator/inactive-vs-faulty","unlisted":false}],"href":"/1.5.X/operators/becoming-a-validator/"},{"type":"category","label":"Private Networks","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Genesis","href":"/1.5.X/operators/setup-network/genesis","docId":"operators/setup-network/genesis","unlisted":false},{"type":"link","label":"The Chainspec","href":"/1.5.X/operators/setup-network/chain-spec","docId":"operators/setup-network/chain-spec","unlisted":false},{"type":"link","label":"Private Network Setup","href":"/1.5.X/operators/setup-network/create-private","docId":"operators/setup-network/create-private","unlisted":false},{"type":"link","label":"Staging Files","href":"/1.5.X/operators/setup-network/staging-files-for-new-network","docId":"operators/setup-network/staging-files-for-new-network","unlisted":false}],"href":"/1.5.X/operators/setup-network/"},{"type":"category","label":"Maintenance","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Archive and Restore a DB","href":"/1.5.X/operators/maintenance/archiving-and-restoring","docId":"operators/maintenance/archiving-and-restoring","unlisted":false},{"type":"link","label":"Move a Node","href":"/1.5.X/operators/maintenance/moving-node","docId":"operators/maintenance/moving-node","unlisted":false}],"href":"/1.5.X/operators/maintenance/"}],"resources":[{"type":"link","label":"Resources Overview","href":"/1.5.X/resources/","docId":"resources/index","unlisted":false},{"type":"link","label":"Build on Casper","href":"/1.5.X/resources/build-on-casper/introduction","docId":"resources/build-on-casper","unlisted":false},{"type":"link","label":"Move to Casper","href":"/1.5.X/resources/moving-to-casper","docId":"resources/moving-to-casper","unlisted":false},{"type":"category","label":"Casper Token Standards","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"CEP-18 Fungible Token","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"On-chain Installation","href":"/1.5.X/resources/tokens/cep18/quickstart-guide","docId":"resources/tokens/cep18/quickstart-guide","unlisted":false},{"type":"link","label":"CEP-18 Contract Details","href":"/1.5.X/resources/tokens/cep18/query","docId":"resources/tokens/cep18/query","unlisted":false},{"type":"link","label":"CEP-18 Transfers","href":"/1.5.X/resources/tokens/cep18/transfer","docId":"resources/tokens/cep18/transfer","unlisted":false},{"type":"link","label":"Testing Guide","href":"/1.5.X/resources/tokens/cep18/tests","docId":"resources/tokens/cep18/tests","unlisted":false}],"href":"/1.5.X/resources/tokens/cep18/full-tutorial"},{"type":"category","label":"CEP-78 Enhanced NFT Standard","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"CEP-78 Modalities","href":"/1.5.X/resources/tokens/cep78/modalities","docId":"resources/tokens/cep78/modalities","unlisted":false},{"type":"category","label":"On-chain Installation","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Installation Workflow","href":"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial","docId":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","unlisted":false},{"type":"link","label":"Interaction Workflow","href":"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs","docId":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","unlisted":false},{"type":"link","label":"CEP-78 Contract Details","href":"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs","docId":"resources/tokens/cep78/using-casper-client/querying-NFTs","unlisted":false},{"type":"link","label":"Testing NFTs","href":"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs","docId":"resources/tokens/cep78/using-casper-client/testing-NFTs","unlisted":false}],"href":"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide"},{"type":"link","label":"Ownership Lookup","href":"/1.5.X/resources/tokens/cep78/reverse-lookup","docId":"resources/tokens/cep78/reverse-lookup","unlisted":false},{"type":"link","label":"CEP-78 JavaScript Client","href":"/1.5.X/resources/tokens/cep78/js-tutorial","docId":"resources/tokens/cep78/js-tutorial","unlisted":false}],"href":"/1.5.X/resources/tokens/cep78/introduction"}],"href":"/1.5.X/resources/tokens/"},{"type":"link","label":"Open-Source Software","href":"/1.5.X/resources/build-on-casper/casper-open-source-software","docId":"resources/casper-open-source-software","unlisted":false},{"type":"link","label":"Quickstart","href":"/1.5.X/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/1.5.X/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/1.5.X/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/1.5.X/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/1.5.X/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/1.5.X/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/1.5.X/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/1.5.X/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/1.5.X/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/1.5.X/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/1.5.X/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/1.5.X/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/1.5.X/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/1.5.X/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/1.5.X/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/1.5.X/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/1.5.X/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/1.5.X/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/1.5.X/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/1.5.X/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/1.5.X/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/1.5.X/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/1.5.X/resources/tutorials/advanced/"}],"users":[{"type":"link","label":"Users Overview","href":"/1.5.X/users/","docId":"users/index","unlisted":false},{"type":"link","label":"Block Explorers","href":"/1.5.X/users/block-explorer","docId":"users/block-explorer","unlisted":false},{"type":"link","label":"Funding Mainnet Accounts","href":"/1.5.X/users/funding-from-exchanges","docId":"users/funding-from-exchanges","unlisted":false},{"type":"category","label":"Using CSPR.live","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Testnet Funding","href":"/1.5.X/users/testnet-faucet","docId":"users/csprlive/testnet-faucet","unlisted":false},{"type":"link","label":"Delegate Tokens","href":"/1.5.X/users/delegate-ui","docId":"users/csprlive/delegate-ui","unlisted":false},{"type":"link","label":"Undelegate Tokens","href":"/1.5.X/users/undelegate-ui","docId":"users/csprlive/undelegate-ui","unlisted":false},{"type":"link","label":"Transfer Tokens","href":"/1.5.X/users/token-transfer","docId":"users/csprlive/token-transfer","unlisted":false}],"href":"/1.5.X/users/csprlive/"},{"type":"category","label":"Ledger Devices","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Set up Ledger","href":"/1.5.X/workflow/ledger-setup/","docId":"users/ledger/ledger-setup","unlisted":false},{"type":"link","label":"Ledger and Ledger Live","href":"/1.5.X/users/ledger/ledger-live","docId":"users/ledger/ledger-live","unlisted":false},{"type":"link","label":"Ledger and CSPR.live","href":"/1.5.X/users/ledger/ledger-cspr-live","docId":"users/ledger/ledger-cspr-live","unlisted":false},{"type":"link","label":"Delegate with Ledger","href":"/1.5.X/users/staking-ledger","docId":"users/ledger/staking-ledger","unlisted":false}],"href":"/1.5.X/users/ledger/"}],"tutorials":[{"type":"link","label":"Quickstart","href":"/1.5.X/resources/quick-start","docId":"resources/quick-start","unlisted":false},{"type":"category","label":"Beginner Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Getting Started","href":"/1.5.X/resources/tutorials/beginner/getting-started-tutorial","docId":"resources/beginner/getting-started-tutorial","unlisted":false},{"type":"category","label":"A Counter with NCTL","collapsible":true,"collapsed":true,"className":"text_transform_reset","items":[{"type":"link","label":"Overview","href":"/1.5.X/resources/beginner/counter/overview","docId":"resources/beginner/counter/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/1.5.X/resources/beginner/counter/commands","docId":"resources/beginner/counter/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/1.5.X/resources/beginner/counter/walkthrough","docId":"resources/beginner/counter/walkthrough","unlisted":false}],"href":"/1.5.X/counter"},{"type":"category","label":"A Counter on the Testnet","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Overview","href":"/1.5.X/resources/beginner/counter-testnet/overview","docId":"resources/beginner/counter-testnet/overview","unlisted":false},{"type":"link","label":"Casper-Client Commands","href":"/1.5.X/resources/beginner/counter-testnet/commands","docId":"resources/beginner/counter-testnet/commands","unlisted":false},{"type":"link","label":"Tutorial Walkthrough","href":"/1.5.X/resources/beginner/counter-testnet/walkthrough","docId":"resources/beginner/counter-testnet/walkthrough","unlisted":false}],"href":"/1.5.X/counter-testnet"},{"type":"link","label":"Querying a Node","href":"/1.5.X/resources/tutorials/beginner/querying-network","docId":"resources/beginner/querying-network","unlisted":false},{"type":"link","label":"Contract Upgrades","href":"/1.5.X/resources/tutorials/beginner/upgrade-contract","docId":"resources/beginner/upgrade-contract","unlisted":false},{"type":"link","label":"Fungible Tokens","href":"/1.5.X/resources/tutorials/beginner/cep18","docId":"resources/beginner/cep18","unlisted":false},{"type":"link","label":"AWS Casper Nodes","href":"/1.5.X/resources/tutorials/beginner/aws-node","docId":"resources/beginner/aws-node","unlisted":false}],"href":"/1.5.X/resources/tutorials/beginner/"},{"type":"category","label":"Advanced Tutorials","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Two-Party Multi-Sig","href":"/1.5.X/resources/tutorials/advanced/two-party-multi-sig","docId":"resources/advanced/two-party-multi-sig","unlisted":false},{"type":"category","label":"Multi-Sig Management","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Introduction","href":"/1.5.X/resources/advanced/multi-sig/","docId":"resources/advanced/multi-sig/index","unlisted":false},{"type":"link","label":"Multi-Sig Workflow","href":"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow","docId":"resources/advanced/multi-sig/multi-sig-workflow","unlisted":false},{"type":"link","label":"Additional Examples","href":"/1.5.X/resources/advanced/multi-sig/other-scenarios","docId":"resources/advanced/multi-sig/other-scenarios","unlisted":false}]},{"type":"link","label":"Runtime Return Values","href":"/1.5.X/resources/tutorials/advanced/return-values-tutorial","docId":"resources/advanced/return-values-tutorial","unlisted":false},{"type":"link","label":"Authorization Keys","href":"/1.5.X/resources/advanced/list-auth-keys-tutorial","docId":"resources/advanced/list-auth-keys-tutorial","unlisted":false},{"type":"link","label":"Token Transfers","href":"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract","docId":"resources/advanced/transfer-token-to-contract","unlisted":false},{"type":"link","label":"Storage Workflow","href":"/1.5.X/resources/tutorials/advanced/storage-workflow","docId":"resources/advanced/storage-workflow","unlisted":false},{"type":"link","label":"Cross-Contract Communication","href":"/1.5.X/resources/tutorials/advanced/cross-contract","docId":"resources/advanced/cross-contract","unlisted":false}],"href":"/1.5.X/resources/tutorials/advanced/"}]},"docs":{"concepts/about":{"id":"concepts/about","title":"What is Casper?","description":"What is Casper?","sidebar":"concepts"},"concepts/accounts-and-keys":{"id":"concepts/accounts-and-keys","title":"Accounts and Keys","description":"The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.","sidebar":"concepts"},"concepts/callstack":{"id":"concepts/callstack","title":"Call Stacks","description":"Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.","sidebar":"concepts"},"concepts/deploy-and-deploy-lifecycle":{"id":"concepts/deploy-and-deploy-lifecycle","title":"Deploy Lifecycle","description":"Deploys","sidebar":"concepts"},"concepts/design/casper-design":{"id":"concepts/design/casper-design","title":"Network Design","description":"Introduction","sidebar":"concepts"},"concepts/design/highway":{"id":"concepts/design/highway","title":"Highway Consensus","description":"What is Consensus?","sidebar":"concepts"},"concepts/design/index":{"id":"concepts/design/index","title":"Design Overview","description":"| Topic | Description |","sidebar":"concepts"},"concepts/design/networking-protocol":{"id":"concepts/design/networking-protocol","title":"Casper Node Networking Protocol","description":"Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)"},"concepts/design/p2p":{"id":"concepts/design/p2p","title":"Network Communication","description":"communications-head}","sidebar":"concepts"},"concepts/design/reading-and-writing-to-the-blockchain":{"id":"concepts/design/reading-and-writing-to-the-blockchain","title":"Reading and Writing Data","description":"Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.","sidebar":"concepts"},"concepts/dictionaries":{"id":"concepts/dictionaries","title":"Dictionaries","description":"dictionaries}","sidebar":"concepts"},"concepts/economics/consensus":{"id":"concepts/economics/consensus","title":"Consensus","description":"Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.","sidebar":"concepts"},"concepts/economics/gas-concepts":{"id":"concepts/economics/gas-concepts","title":"Gas Cost","description":"What is gas?","sidebar":"concepts"},"concepts/economics/index":{"id":"concepts/economics/index","title":"Overview","description":"Casper\'s economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform\'s value.","sidebar":"concepts"},"concepts/economics/runtime":{"id":"concepts/economics/runtime","title":"Runtime","description":"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.","sidebar":"concepts"},"concepts/economics/staking/concepts":{"id":"concepts/economics/staking/concepts","title":"Staking Concepts","description":"The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.","sidebar":"concepts"},"concepts/economics/staking/delegation":{"id":"concepts/economics/staking/delegation","title":"Delegation Details","description":"This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.","sidebar":"concepts"},"concepts/economics/staking/staking":{"id":"concepts/economics/staking/staking","title":"Staking vs. Delegating","description":"staking-vs-delegating}","sidebar":"concepts"},"concepts/global-state":{"id":"concepts/global-state","title":"Global State","description":"global-state-head}","sidebar":"concepts"},"concepts/glossary/A":{"id":"concepts/glossary/A","title":"A","description":"---","sidebar":"concepts"},"concepts/glossary/B":{"id":"concepts/glossary/B","title":"B","description":"---","sidebar":"concepts"},"concepts/glossary/C":{"id":"concepts/glossary/C","title":"C","description":"---","sidebar":"concepts"},"concepts/glossary/D":{"id":"concepts/glossary/D","title":"D","description":"---","sidebar":"concepts"},"concepts/glossary/E":{"id":"concepts/glossary/E","title":"E","description":"---","sidebar":"concepts"},"concepts/glossary/F":{"id":"concepts/glossary/F","title":"F","description":"---","sidebar":"concepts"},"concepts/glossary/G":{"id":"concepts/glossary/G","title":"G","description":"---","sidebar":"concepts"},"concepts/glossary/H":{"id":"concepts/glossary/H","title":"H","description":"---","sidebar":"concepts"},"concepts/glossary/I":{"id":"concepts/glossary/I","title":"I","description":"---","sidebar":"concepts"},"concepts/glossary/index":{"id":"concepts/glossary/index","title":"Glossary","description":"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.","sidebar":"concepts"},"concepts/glossary/J":{"id":"concepts/glossary/J","title":"J","description":"---","sidebar":"concepts"},"concepts/glossary/K":{"id":"concepts/glossary/K","title":"K","description":"---","sidebar":"concepts"},"concepts/glossary/L":{"id":"concepts/glossary/L","title":"L","description":"---","sidebar":"concepts"},"concepts/glossary/M":{"id":"concepts/glossary/M","title":"M","description":"---","sidebar":"concepts"},"concepts/glossary/N":{"id":"concepts/glossary/N","title":"N","description":"---","sidebar":"concepts"},"concepts/glossary/O":{"id":"concepts/glossary/O","title":"O","description":"---","sidebar":"concepts"},"concepts/glossary/P":{"id":"concepts/glossary/P","title":"P","description":"---","sidebar":"concepts"},"concepts/glossary/Q":{"id":"concepts/glossary/Q","title":"Q","description":"---","sidebar":"concepts"},"concepts/glossary/R":{"id":"concepts/glossary/R","title":"R","description":"---","sidebar":"concepts"},"concepts/glossary/S":{"id":"concepts/glossary/S","title":"S","description":"---","sidebar":"concepts"},"concepts/glossary/T":{"id":"concepts/glossary/T","title":"T","description":"---","sidebar":"concepts"},"concepts/glossary/U":{"id":"concepts/glossary/U","title":"U","description":"---","sidebar":"concepts"},"concepts/glossary/V":{"id":"concepts/glossary/V","title":"V","description":"---","sidebar":"concepts"},"concepts/glossary/W":{"id":"concepts/glossary/W","title":"W","description":"---","sidebar":"concepts"},"concepts/glossary/X":{"id":"concepts/glossary/X","title":"X","description":"---","sidebar":"concepts"},"concepts/glossary/Y":{"id":"concepts/glossary/Y","title":"Y","description":"---","sidebar":"concepts"},"concepts/glossary/Z":{"id":"concepts/glossary/Z","title":"Z","description":"---","sidebar":"concepts"},"concepts/hash-types":{"id":"concepts/hash-types","title":"Hash Types","description":"For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.","sidebar":"concepts"},"concepts/index":{"id":"concepts/index","title":"Overview","description":"The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.","sidebar":"concepts"},"concepts/intro-to-dapps":{"id":"concepts/intro-to-dapps","title":"dApps","description":"What is a dApp?","sidebar":"concepts"},"concepts/list-auth-keys":{"id":"concepts/list-auth-keys","title":"Authorization Keys","description":"This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.","sidebar":"concepts"},"concepts/serialization-standard":{"id":"concepts/serialization-standard","title":"Serialization Standard","description":"serialization-standard-head}","sidebar":"concepts"},"concepts/smart-contracts":{"id":"concepts/smart-contracts","title":"Smart Contracts","description":"Smart Contracts in General","sidebar":"concepts"},"developers/cli/calling-contracts":{"id":"developers/cli/calling-contracts","title":"Calling Contracts","description":"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.","sidebar":"developers"},"developers/cli/delegate":{"id":"developers/cli/delegate","title":"Delegating Tokens","description":"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.","sidebar":"developers"},"developers/cli/execution-error-codes":{"id":"developers/cli/execution-error-codes","title":"Execution Error Codes","description":"This section covers smart contract execution error codes.","sidebar":"developers"},"developers/cli/index":{"id":"developers/cli/index","title":"Interacting with the Blockchain","description":"This section explains how to interact with a Casper network using the Casper command-line client written in Rust.","sidebar":"developers"},"developers/cli/installing-contracts":{"id":"developers/cli/installing-contracts","title":"Installing Contracts","description":"This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.","sidebar":"developers"},"developers/cli/opcode-costs":{"id":"developers/cli/opcode-costs","title":"OpCode Costs Tables","description":"The following tables outline the cost, in motes, for a given operation on Casper\'s Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.","sidebar":"developers"},"developers/cli/querying-global-state":{"id":"developers/cli/querying-global-state","title":"Querying Global State","description":"This page explains how to query global state after contract installation.","sidebar":"developers"},"developers/cli/redelegate":{"id":"developers/cli/redelegate","title":"Redelegating Tokens with the Casper Client","description":"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.","sidebar":"developers"},"developers/cli/sending-deploys":{"id":"developers/cli/sending-deploys","title":"Sending Deploys","description":"To install smart contracts on the blockchain, you can send your Wasm to the network via a Deploy. To do this, you will need to meet a few prerequisites:","sidebar":"developers"},"developers/cli/transfers/direct-token-transfer":{"id":"developers/cli/transfers/direct-token-transfer","title":"Direct Token Transfer","description":"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.","sidebar":"developers"},"developers/cli/transfers/index":{"id":"developers/cli/transfers/index","title":"Transferring Tokens","description":"The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.","sidebar":"developers"},"developers/cli/transfers/multisig-deploy-transfer":{"id":"developers/cli/transfers/multisig-deploy-transfer","title":"Transferring Tokens using a Multi-Sig Deploy","description":"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.","sidebar":"developers"},"developers/cli/transfers/verify-transfer":{"id":"developers/cli/transfers/verify-transfer","title":"Verifying a Transfer","description":"Prerequisites","sidebar":"developers"},"developers/cli/undelegate":{"id":"developers/cli/undelegate","title":"Undelegating Tokens","description":"This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.","sidebar":"developers"},"developers/dapps/dapp":{"id":"developers/dapps/dapp","title":"What is a dApp?","description":"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.","sidebar":"developers"},"developers/dapps/index":{"id":"developers/dapps/index","title":"Overview of Casper dApps","description":"The following topics are essential for developers building decentralized applications on a Casper network.","sidebar":"developers"},"developers/dapps/monitor-and-consume-events":{"id":"developers/dapps/monitor-and-consume-events","title":"Monitoring and Consuming Events","description":"The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper\'s client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.","sidebar":"developers"},"developers/dapps/nctl-test":{"id":"developers/dapps/nctl-test","title":"Local Network Testing","description":"NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.","sidebar":"developers"},"developers/dapps/prerequisites":{"id":"developers/dapps/prerequisites","title":"Prerequisites","description":"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:","sidebar":"developers"},"developers/dapps/sdk/client-library-usage":{"id":"developers/dapps/sdk/client-library-usage","title":"SDK Client Library Usage","description":"Installing the SDKs","sidebar":"developers"},"developers/dapps/sdk/csharp-sdk":{"id":"developers/dapps/sdk/csharp-sdk","title":".NET SDK","description":"The C# .NET SDK allows developers to interact with a Casper network using C#.","sidebar":"developers"},"developers/dapps/sdk/go-sdk":{"id":"developers/dapps/sdk/go-sdk","title":"Go SDK","description":"Usage Examples","sidebar":"developers"},"developers/dapps/sdk/index":{"id":"developers/dapps/sdk/index","title":"SDK Client Libraries","description":"This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.","sidebar":"developers"},"developers/dapps/sdk/python-sdk":{"id":"developers/dapps/sdk/python-sdk","title":"Python SDK","description":"The Python SDK allows developers to interact with the Casper platform using Python 3.12+.","sidebar":"developers"},"developers/dapps/sdk/script-sdk":{"id":"developers/dapps/sdk/script-sdk","title":"JavaScript/TypeScript SDK","description":"This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.","sidebar":"developers"},"developers/dapps/setup-nctl":{"id":"developers/dapps/setup-nctl","title":"Local Network Setup","description":"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.","sidebar":"developers"},"developers/dapps/signing-a-deploy":{"id":"developers/dapps/signing-a-deploy","title":"Signing Deploys","description":"When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account\'s cryptographic key-pair. This key-pair is a combination of the account\'s secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.","sidebar":"developers"},"developers/dapps/speculative-exec":{"id":"developers/dapps/speculative-exec","title":"Estimating Gas Costs with Speculative Execution","description":"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.","sidebar":"developers"},"developers/dapps/technology-stack":{"id":"developers/dapps/technology-stack","title":"dApp Technology Stack","description":"There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.","sidebar":"developers"},"developers/dapps/template-frontend":{"id":"developers/dapps/template-frontend","title":"Front-end in React","description":"For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.","sidebar":"developers"},"developers/dapps/uref-security":{"id":"developers/dapps/uref-security","title":"URef Access Rights","description":"Understanding Access Rights","sidebar":"developers"},"developers/essential-crates":{"id":"developers/essential-crates","title":"Essential Rust Crates","description":"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.","sidebar":"developers"},"developers/index":{"id":"developers/index","title":"Overview","description":"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.","sidebar":"developers"},"developers/json-rpc/errors":{"id":"developers/json-rpc/errors","title":"Casper JSON-RPC Error Codes","description":"The following document expands on custom error codes provided by casper-json-rpc crate."},"developers/json-rpc/guidance":{"id":"developers/json-rpc/guidance","title":"Guidance for JSON-RPC SDK Compliance","description":"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.","sidebar":"developers"},"developers/json-rpc/index":{"id":"developers/json-rpc/index","title":"Overview","description":"Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node\'s JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.","sidebar":"developers"},"developers/json-rpc/json-rpc-informational":{"id":"developers/json-rpc/json-rpc-informational","title":"Informational JSON-RPC Methods","description":"informational}","sidebar":"developers"},"developers/json-rpc/json-rpc-pos":{"id":"developers/json-rpc/json-rpc-pos","title":"Proof-of-Stake JSON-RPC Methods","description":"proof-of-stake}","sidebar":"developers"},"developers/json-rpc/json-rpc-transactional":{"id":"developers/json-rpc/json-rpc-transactional","title":"Transactional JSON-RPC Methods","description":"transactional}","sidebar":"developers"},"developers/json-rpc/minimal-compliance":{"id":"developers/json-rpc/minimal-compliance","title":"Required Methods for Minimal Compliance","description":"The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.","sidebar":"developers"},"developers/json-rpc/types_chain":{"id":"developers/json-rpc/types_chain","title":"Types","description":"types}","sidebar":"developers"},"developers/json-rpc/types_cl":{"id":"developers/json-rpc/types_cl","title":"CLType","description":"cltype}","sidebar":"developers"},"developers/prerequisites":{"id":"developers/prerequisites","title":"Development Prerequisites","description":"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.","sidebar":"developers"},"developers/writing-onchain-code/assembly-script":{"id":"developers/writing-onchain-code/assembly-script","title":"Getting Started with AssemblyScript","description":"Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.","sidebar":"developers"},"developers/writing-onchain-code/best-practices":{"id":"developers/writing-onchain-code/best-practices","title":"Best Practices for Casper Smart Contract Authors","description":"At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.","sidebar":"developers"},"developers/writing-onchain-code/calling-contracts":{"id":"developers/writing-onchain-code/calling-contracts","title":"Calling Contracts","description":"Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.","sidebar":"developers"},"developers/writing-onchain-code/contract-hash-vs-package-hash":{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","title":"Contract Hash vs. Package Hash","description":"This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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.","sidebar":"developers"},"developers/writing-onchain-code/contract-vs-session":{"id":"developers/writing-onchain-code/contract-vs-session","title":"Contracts and Session Code","description":"What is Session Code?","sidebar":"developers"},"developers/writing-onchain-code/getting-started":{"id":"developers/writing-onchain-code/getting-started","title":"Getting Started with Rust","description":"This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.","sidebar":"developers"},"developers/writing-onchain-code/index":{"id":"developers/writing-onchain-code/index","title":"Introduction","description":"This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.","sidebar":"developers"},"developers/writing-onchain-code/simple-contract":{"id":"developers/writing-onchain-code/simple-contract","title":"Writing a Basic Smart Contract in Rust","description":"What is a Smart Contract?","sidebar":"developers"},"developers/writing-onchain-code/testing-contracts":{"id":"developers/writing-onchain-code/testing-contracts","title":"Testing Smart Contracts","description":"Introduction","sidebar":"developers"},"developers/writing-onchain-code/testing-session-code":{"id":"developers/writing-onchain-code/testing-session-code","title":"Testing Session Code","description":"This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.","sidebar":"developers"},"developers/writing-onchain-code/upgrading-contracts":{"id":"developers/writing-onchain-code/upgrading-contracts","title":"Upgrading and Maintaining Smart Contracts","description":"Our smart contract packaging tools enable you to:","sidebar":"developers"},"developers/writing-onchain-code/writing-session-code":{"id":"developers/writing-onchain-code/writing-session-code","title":"Writing Session Code","description":"This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.","sidebar":"developers"},"disclaimer":{"id":"disclaimer","title":"Disclaimer","description":"disclaimer}"},"operators/becoming-a-validator/bonding":{"id":"operators/becoming-a-validator/bonding","title":"Bonding","description":"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.","sidebar":"operators"},"operators/becoming-a-validator/inactive-vs-faulty":{"id":"operators/becoming-a-validator/inactive-vs-faulty","title":"Inactive and Faulty Nodes","description":"This page describes the differences between a validator node being considered inactive or faulty.","sidebar":"operators"},"operators/becoming-a-validator/index":{"id":"operators/becoming-a-validator/index","title":"Becoming a Validator","description":"After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.","sidebar":"operators"},"operators/becoming-a-validator/recovering":{"id":"operators/becoming-a-validator/recovering","title":"Recovery","description":"This topic discusses the steps a validator needs to take if it is evicted from the validator set:","sidebar":"operators"},"operators/becoming-a-validator/unbonding":{"id":"operators/becoming-a-validator/unbonding","title":"Unbonding","description":"Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.","sidebar":"operators"},"operators/index":{"id":"operators/index","title":"Overview","description":"Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.","sidebar":"operators"},"operators/maintenance/archiving-and-restoring":{"id":"operators/maintenance/archiving-and-restoring","title":"Archive and Restore a DB","description":"This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.","sidebar":"operators"},"operators/maintenance/index":{"id":"operators/maintenance/index","title":"Node Maintenance","description":"This section covers maintenance actions such as moving a node to a different location and restoring a database.","sidebar":"operators"},"operators/maintenance/moving-node":{"id":"operators/maintenance/moving-node","title":"Move a Node","description":"This guide is for active validators who want to move their node to another machine.","sidebar":"operators"},"operators/setup-network/chain-spec":{"id":"operators/setup-network/chain-spec","title":"The Chainspec","description":"the-chain-specification}","sidebar":"operators"},"operators/setup-network/create-private":{"id":"operators/setup-network/create-private","title":"Private Network Setup","description":"Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.","sidebar":"operators"},"operators/setup-network/genesis":{"id":"operators/setup-network/genesis","title":"Genesis","description":"the-genesis-block}","sidebar":"operators"},"operators/setup-network/index":{"id":"operators/setup-network/index","title":"Setting up Private Networks","description":"Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.","sidebar":"operators"},"operators/setup-network/staging-files-for-new-network":{"id":"operators/setup-network/staging-files-for-new-network","title":"Staging Files","description":"Staging files is not needed for already established running networks.","sidebar":"operators"},"operators/setup/basic-node-configuration":{"id":"operators/setup/basic-node-configuration","title":"Configuration","description":"This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.","sidebar":"operators"},"operators/setup/fast-sync":{"id":"operators/setup/fast-sync","title":"Fast Sync","description":"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.","sidebar":"operators"},"operators/setup/hardware":{"id":"operators/setup/hardware","title":"Hardware","description":"System Requirements","sidebar":"operators"},"operators/setup/index":{"id":"operators/setup/index","title":"Setting up a Node","description":"The prerequisite for becoming a validator is to set up a node and join a network as described here.","sidebar":"operators"},"operators/setup/install-node":{"id":"operators/setup/install-node","title":"Installation","description":"Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.","sidebar":"operators"},"operators/setup/joining":{"id":"operators/setup/joining","title":"Join a Network","description":"Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.","sidebar":"operators"},"operators/setup/node-endpoints":{"id":"operators/setup/node-endpoints","title":"Endpoints","description":"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.","sidebar":"operators"},"operators/setup/non-root-user":{"id":"operators/setup/non-root-user","title":"Non-Root Users","description":"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.","sidebar":"operators"},"operators/setup/open-files":{"id":"operators/setup/open-files","title":"Open Files Limit","description":"When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.","sidebar":"operators"},"operators/setup/upgrade":{"id":"operators/setup/upgrade","title":"Upgrades","description":"The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.","sidebar":"operators"},"resources/advanced/cross-contract":{"id":"resources/advanced/cross-contract","title":"Cross-Contract Communication","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/advanced/index":{"id":"resources/advanced/index","title":"Advanced Tutorials","description":"| Title | Description |","sidebar":"tutorials"},"resources/advanced/list-auth-keys-tutorial":{"id":"resources/advanced/list-auth-keys-tutorial","title":"Authorization Keys","description":"These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.","sidebar":"tutorials"},"resources/advanced/list-cspr":{"id":"resources/advanced/list-cspr","title":"Listing CSPR","description":"This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange."},"resources/advanced/multi-sig/index":{"id":"resources/advanced/multi-sig/index","title":"Introduction","description":"In this tutorial, you will use Casper\'s permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.","sidebar":"tutorials"},"resources/advanced/multi-sig/multi-sig-workflow":{"id":"resources/advanced/multi-sig/multi-sig-workflow","title":"Multi-Sig Workflow","description":"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.","sidebar":"tutorials"},"resources/advanced/multi-sig/other-scenarios":{"id":"resources/advanced/multi-sig/other-scenarios","title":"Additional Examples","description":"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.","sidebar":"tutorials"},"resources/advanced/return-values-tutorial":{"id":"resources/advanced/return-values-tutorial","title":"Runtime Return Values","description":"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.","sidebar":"tutorials"},"resources/advanced/storage-workflow":{"id":"resources/advanced/storage-workflow","title":"Storage Workflow","description":"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.","sidebar":"tutorials"},"resources/advanced/transfer-token-to-contract":{"id":"resources/advanced/transfer-token-to-contract","title":"Token Transfers","description":"This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.","sidebar":"tutorials"},"resources/advanced/two-party-multi-sig":{"id":"resources/advanced/two-party-multi-sig","title":"Two-Party Multi-Sig","description":"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.","sidebar":"tutorials"},"resources/beginner/aws-node":{"id":"resources/beginner/aws-node","title":"AWS Casper Nodes","description":"The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.","sidebar":"tutorials"},"resources/beginner/cep18":{"id":"resources/beginner/cep18","title":"Fungible Tokens","description":"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:","sidebar":"tutorials"},"resources/beginner/counter-testnet/commands":{"id":"resources/beginner/counter-testnet/commands","title":"Casper-Client Commands","description":"State Root Hash","sidebar":"tutorials"},"resources/beginner/counter-testnet/index":{"id":"resources/beginner/counter-testnet/index","title":"Introduction","description":"This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter-testnet/overview":{"id":"resources/beginner/counter-testnet/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter-testnet/walkthrough":{"id":"resources/beginner/counter-testnet/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/counter/commands":{"id":"resources/beginner/counter/commands","title":"Casper-Client Commands","description":"Faucet Account Information","sidebar":"tutorials"},"resources/beginner/counter/index":{"id":"resources/beginner/counter/index","title":"Introduction","description":"This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.","sidebar":"tutorials"},"resources/beginner/counter/overview":{"id":"resources/beginner/counter/overview","title":"Overview","description":"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.","sidebar":"tutorials"},"resources/beginner/counter/walkthrough":{"id":"resources/beginner/counter/walkthrough","title":"Tutorial Walkthrough","description":"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.","sidebar":"tutorials"},"resources/beginner/getting-started-tutorial":{"id":"resources/beginner/getting-started-tutorial","title":"Getting Started","description":"This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.","sidebar":"tutorials"},"resources/beginner/index":{"id":"resources/beginner/index","title":"Overview","description":"Beginner Tutorials","sidebar":"tutorials"},"resources/beginner/querying-network":{"id":"resources/beginner/querying-network","title":"Querying a Node","description":"The Casper node supports queries for users and developers to obtain information stored on the blockchain.","sidebar":"tutorials"},"resources/beginner/upgrade-contract":{"id":"resources/beginner/upgrade-contract","title":"Contract Upgrades","description":"This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the addcontractversion API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.","sidebar":"tutorials"},"resources/build-on-casper":{"id":"resources/build-on-casper","title":"Build on Casper","description":"This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.","sidebar":"resources"},"resources/casper-open-source-software":{"id":"resources/casper-open-source-software","title":"Open-Source Software","description":"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.","sidebar":"resources"},"resources/condor-for-exchanges":{"id":"resources/condor-for-exchanges","title":"Condor Release Notes for Exchanges","description":"Account/Contract Merge"},"resources/index":{"id":"resources/index","title":"Resources Overview","description":"Building on Casper","sidebar":"resources"},"resources/moving-to-casper":{"id":"resources/moving-to-casper","title":"Move to Casper","description":"moving-to-casper}","sidebar":"resources"},"resources/quick-start":{"id":"resources/quick-start","title":"Quickstart","description":"Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.","sidebar":"tutorials"},"resources/tokens/cep18/full-tutorial":{"id":"resources/tokens/cep18/full-tutorial","title":"Fungible Token Workflow","description":"This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.","sidebar":"resources"},"resources/tokens/cep18/query":{"id":"resources/tokens/cep18/query","title":"CEP-18 Contract Details","description":"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:","sidebar":"resources"},"resources/tokens/cep18/quickstart-guide":{"id":"resources/tokens/cep18/quickstart-guide","title":"On-chain Installation","description":"This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.","sidebar":"resources"},"resources/tokens/cep18/tests":{"id":"resources/tokens/cep18/tests","title":"Testing Guide","description":"The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.","sidebar":"resources"},"resources/tokens/cep18/transfer":{"id":"resources/tokens/cep18/transfer","title":"CEP-18 Transfers","description":"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.","sidebar":"resources"},"resources/tokens/cep78/introduction":{"id":"resources/tokens/cep78/introduction","title":"Introduction","description":"Usage","sidebar":"resources"},"resources/tokens/cep78/js-tutorial":{"id":"resources/tokens/cep78/js-tutorial","title":"CEP-78 JavaScript Client","description":"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.","sidebar":"resources"},"resources/tokens/cep78/modalities":{"id":"resources/tokens/cep78/modalities","title":"CEP-78 Modalities","description":"The enhanced NFT implementation supports various \'modalities\' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.","sidebar":"resources"},"resources/tokens/cep78/reverse-lookup":{"id":"resources/tokens/cep78/reverse-lookup","title":"Ownership Lookup","description":"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/full-installation-tutorial":{"id":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","title":"Installation Workflow","description":"This documentation will guide you through installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper\'s Rust CLI client. The contract code installs an instance of CEP-78 given the session arguments provided. It requires a minimum Rust version of 1.63.0. The code for this tutorial is available in GitHub. A portion of this tutorial reviews the contract.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/interacting-with-NFTs":{"id":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","title":"Interaction Workflow","description":"This document describes interacting with NFTs on a Casper network using the Rust command-line client.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/querying-NFTs":{"id":"resources/tokens/cep78/using-casper-client/querying-NFTs","title":"CEP-78 Contract Details","description":"This document covers different commands to query and interact with an NFT (CEP-78) contract instance.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/quickstart-guide":{"id":"resources/tokens/cep78/using-casper-client/quickstart-guide","title":"Quick Installation","description":"This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.","sidebar":"resources"},"resources/tokens/cep78/using-casper-client/testing-NFTs":{"id":"resources/tokens/cep78/using-casper-client/testing-NFTs","title":"Testing NFTs","description":"Prerequisites","sidebar":"resources"},"resources/tokens/index":{"id":"resources/tokens/index","title":"Casper Token Standards","description":"CEP-18 Casper Fungible Token Standard","sidebar":"resources"},"users/block-explorer":{"id":"users/block-explorer","title":"Block Explorers","description":"The Casper blockchain is available as the Mainnet and Testnet.","sidebar":"users"},"users/csprlive/delegate-ui":{"id":"users/csprlive/delegate-ui","title":"Delegate Tokens","description":"Introduction","sidebar":"users"},"users/csprlive/index":{"id":"users/csprlive/index","title":"Using CSPR.live","description":"| Topic | Description |","sidebar":"users"},"users/csprlive/testnet-faucet":{"id":"users/csprlive/testnet-faucet","title":"Testnet Funding","description":"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.","sidebar":"users"},"users/csprlive/token-transfer":{"id":"users/csprlive/token-transfer","title":"Transfer Tokens","description":"You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user\'s purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.","sidebar":"users"},"users/csprlive/undelegate-ui":{"id":"users/csprlive/undelegate-ui","title":"Undelegate Tokens","description":"If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.","sidebar":"users"},"users/funding-from-exchanges":{"id":"users/funding-from-exchanges","title":"Funding Mainnet Accounts","description":"To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account\'s public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.","sidebar":"users"},"users/index":{"id":"users/index","title":"Users Overview","description":"General Topics","sidebar":"users"},"users/ledger/index":{"id":"users/ledger/index","title":"Casper on Ledger","description":"| Topic | Description |","sidebar":"users"},"users/ledger/ledger-cspr-live":{"id":"users/ledger/ledger-cspr-live","title":"Ledger and CSPR.live","description":"This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-live":{"id":"users/ledger/ledger-live","title":"Ledger and Ledger Live","description":"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.","sidebar":"users"},"users/ledger/ledger-setup":{"id":"users/ledger/ledger-setup","title":"Set up Ledger","description":"A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.","sidebar":"users"},"users/ledger/staking-ledger":{"id":"users/ledger/staking-ledger","title":"Delegate with Ledger","description":"Ledger Initialization","sidebar":"users"}}}}')}}]); \ No newline at end of file diff --git a/assets/js/d638c601.15664957.js b/assets/js/d638c601.15664957.js new file mode 100644 index 000000000..8735740ca --- /dev/null +++ b/assets/js/d638c601.15664957.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4858],{97218:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>o,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var s=a(74848),r=a(28453);const t={},d="Informational JSON-RPC Methods",c={id:"developers/json-rpc/json-rpc-informational",title:"Informational JSON-RPC Methods",description:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.",source:"@site/docs/developers/json-rpc/json-rpc-informational.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-informational",permalink:"/developers/json-rpc/json-rpc-informational",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"developers",previous:{title:"Transactional JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-transactional"},next:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/developers/json-rpc/json-rpc-pos"}},i={},l=[{value:"chain_get_block",id:"chain_get_block",level:2},{value:"<code>chain_get_block_result</code>",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain_get_block_transfers",level:2},{value:"<code>chain_get_block_transfers_result</code>",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain_get_era_summary",level:2},{value:"<code>chain_get_era_summary_result</code>",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain_get_state_root_hash",level:2},{value:"<code>chain_get_state_root_hash_result</code>",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info_get_chainspec",level:2},{value:"<code>info_get_chainspec_result</code>",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info_get_deploy",level:2},{value:"<code>info_get_deploy_result</code>",id:"info_get_deploy_result",level:3},{value:"info_get_reward",id:"info_get_reward",level:2},{value:"<code>info_get_reward_result</code>",id:"info_get_reward_result",level:3},{value:"info_get_transaction",id:"info_get_transaction",level:2},{value:"<code>info_get_transaction_result</code>",id:"info_get_transaction_result",level:3},{value:"query_balance",id:"query_balance",level:2},{value:"<code>query_balance_result</code>",id:"query_balance_result",level:3},{value:"query_balance_details",id:"query_balance_details",level:2},{value:"<code>query_balance_details_result</code>",id:"query_balance_details_result",level:3},{value:"query_global_state",id:"query_global_state",level:2},{value:"<code>query_global_state_result</code>",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state_get_account_info",level:2},{value:"<code>state_get_account_info_result</code>",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state_get_dictionary_item",level:2},{value:"<code>state_get_dictionary_item_result</code>",id:"state_get_dictionary_item_result",level:3},{value:"state_get_entity",id:"state_get_entity",level:2},{value:"<code>state_get_entity_result</code>",id:"state_get_entity_result",level:3},{value:"info_get_peers",id:"info_get_peers",level:2},{value:"<code>info_get_peers_result</code>",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info_get_status",level:2},{value:"<code>info_get_status_result</code>",id:"info_get_status_result",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"informational-json-rpc-methods",children:"Informational JSON-RPC Methods"})}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block",children:"chain_get_block"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the JSON representation of a ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"})," from the network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash or the Block height. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_result"})}),"\n",(0,s.jsxs)(n.p,{children:["The result from ",(0,s.jsx)(n.code,{children:"chain_get_block"})," depends on block availability from a given node. If ",(0,s.jsx)(n.code,{children:"chain_get_block"})," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#jsonblockwithsignatures",children:"block"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_result",\n "value": {\n "api_version": "2.0.0",\n "block_with_signatures": {\n "block": {\n "Version2": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "header": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "48859fb4865d8637d6a35cb224e222cd0e1b1c2dd72928932c1e35ac0550818b",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a"\n },\n "body": {\n "transactions": {\n "0": [\n {\n "Version1": "1414141414141414141414141414141414141414141414141414141414141414"\n }\n ],\n "1": [\n {\n "Version1": "1515151515151515151515151515151515151515151515151515151515151515"\n }\n ],\n "2": [\n {\n "Version1": "1616161616161616161616161616161616161616161616161616161616161616"\n }\n ],\n "3": [\n {\n "Version1": "1717171717171717171717171717171717171717171717171717171717171717"\n }\n ]\n },\n "rewarded_signatures": []\n }\n }\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "01e18ca03d2ef0238a6a2460a222e0b818406bda99d4c05502c80232013559b926d1c8bca6bf65386f54a847d7850cb76c0c5fd5e633c34c749b8b9958a638d806"\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block_transfers",children:"chain_get_block_transfers"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns all ",(0,s.jsx)(n.strong,{children:"successful"})," native transfers within a given ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"})," from a network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the transfers from the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_transfers_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_transfers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash, if found. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#transfer",children:"transfers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The Block's successful transfers, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_transfers_result",\n "value": {\n "api_version": "2.0.0",\n "block_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_era_summary",children:"chain_get_era_summary"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the era summary at a given ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the era summary at the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_era_summary_result",children:(0,s.jsx)(n.code,{children:"chain_get_era_summary_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "chain_get_era_summary_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_state_root_hash",children:"chain_get_state_root_hash"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a state root hash at a given ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Height": 10\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_state_root_hash_result",children:(0,s.jsx)(n.code,{children:"chain_get_state_root_hash_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hex-encoded hash of the state root."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_state_root_hash_result",\n "value": {\n "api_version": "2.0.0",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_chainspec",children:"info_get_chainspec"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 5510244237763930243,\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_chainspec_result",children:(0,s.jsx)(n.code,{children:"info_get_chainspec_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#chainspecrawbytes",children:"chainspec_bytes"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec result"}),"\n",(0,s.jsxs)(n.p,{children:["Please note that adding a ",(0,s.jsx)(n.code,{children:"--vv"})," flag will return the full chainspec bytes."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_chainspec_result",\n "value": {\n "api_version": "2.0.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n }\n },\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_deploy",children:"info_get_deploy"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"DEPRECATED"}),": Use ",(0,s.jsx)(n.a,{href:"#info_get_transaction",children:"info_get_transaction"})," instead."]})}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-deploys",children:"Deploy"})," from a network. It requires a ",(0,s.jsx)(n.code,{children:"deploy_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The Deploy hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n {\n "name": "deploy_hash",\n "value": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_deploy_result",children:(0,s.jsx)(n.code,{children:"info_get_deploy_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the Deploy and the results of executing the Deploy."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", but has yet to execute it. If the network executed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Deploy."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_reward",children:"info_get_reward"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the reward for a given era and a validator or delegator."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:"validator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key of the validator."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#eraidentifier",children:"era_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsxs)(n.td,{children:["The era identifier. If ",(0,s.jsx)(n.code,{children:"None"}),", the last finalized era is used. (Optional)"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:"delegator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsxs)(n.td,{children:["The public key of the delegator. If ",(0,s.jsx)(n.code,{children:"Some"}),", the rewards for the delegator are returned. If ",(0,s.jsx)(n.code,{children:"None"}),", the rewards for the validator are returned. (Optional)"]})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_reward",\n "params": [\n {\n "name": "era_identifier",\n "value": {\n "Era": 1\n }\n },\n {\n "name": "validator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n {\n "name": "delegator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_reward_result",children:(0,s.jsx)(n.code,{children:"info_get_reward_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#eraid",children:"era_id"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The era for which the reward was calculated."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#u512",children:"reward_amount"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The total reward amount in the requested era."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_reward_result",\n "value": {\n "api_version": "2.0.0",\n "reward_amount": "42",\n "era_id": 1\n }\n } \n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_transaction",children:"info_get_transaction"}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a transaction from a network. It requires a ",(0,s.jsx)(n.code,{children:"transaction_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The transaction hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the transaction with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_transaction",\n "params": [\n {\n "name": "transaction_hash",\n "value": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_transaction_result",children:(0,s.jsx)(n.code,{children:"info_get_transaction_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the transaction and the results of executing it on the network."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the transaction but has yet to execute it. If the network executed the transaction, it will return the execution information, along with the block hash containing the transaction."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The transaction."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n } \n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance",children:"query_balance"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for the balance of a purse using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_result",children:(0,s.jsx)(n.code,{children:"query_balance_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#u512",children:"balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The balance represented in motes."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_result",\n "value": {\n "api_version": "2.0.0",\n "balance": "123456"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance_details",children:"query_balance_details"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for full balance information using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance_details",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_details_result",children:(0,s.jsx)(n.code,{children:"query_balance_details_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#u512",children:"available_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available balance in motes (total balance - sum of all active holds)."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#balanceholdwithproof",children:"holds"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The holds active at the requested point in time."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#u512",children:"total_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The purses total balance, not considering holds."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"`total_balance_proof"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"A proof that the given value is present in the Merkle trie."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_details_result",\n "value": {\n "api_version": "2.0.0",\n "total_balance": "123456",\n "available_balance": "123456",\n "total_balance_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "holds": [\n {\n "time": 0,\n "amount": "123456",\n "proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_global_state",children:"query_global_state"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block_hash",children:"Block hash"})," or state root hash."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Note: Querying a purse's balance requires the use of ",(0,s.jsx)(n.code,{children:"query_balance"}),", rather than any iteration of ",(0,s.jsx)(n.code,{children:"query_global_state"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#key",children:"key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key as a formatted string, under which data can be stored in global state."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier used for the query. If not provided, the tip of the chain will be used. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"path"}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The path components starting from the key as base. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n },\n {\n "name": "key",\n "value": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"\n },\n {\n "name": "path",\n "value": []\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_global_state_result",children:(0,s.jsx)(n.code,{children:"query_global_state_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockheaderv2",children:"block_header"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block header if a Block hash was provided. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "2.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "0505050505050505050505050505050505050505050505050505050505050505",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0909090909090909090909090909090909090909090909090909090909090909"\n }\n },\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_account_info",children:"state_get_account_info"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the account at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the Account's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#accountidentifier",children:"account_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key or account hash of the Account."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "name": "account_identifier",\n "value": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_account_info_result",children:(0,s.jsx)(n.code,{children:"state_get_account_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#account",children:"account"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the Account structure."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_account_info_result",\n "value": {\n "api_version": "2.0.0",\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_dictionary_item",children:"state_get_dictionary_item"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,s.jsx)(n.code,{children:"dictionary_identifier"}),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."]}),"\n",(0,s.jsx)(n.p,{children:"You may query a stored value directly using the dictionary address."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hash of the state root."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#dictionaryidentifier",children:"dictionary_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Dictionary query identifier."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "name": "state_root_hash",\n "value": "0808080808080808080808080808080808080808080808080808080808080808"\n },\n {\n "name": "dictionary_identifier",\n "value": {\n "URef": {\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "dictionary_item_key": "a_unique_entry_identifier"\n }\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_dictionary_item_result",children:(0,s.jsx)(n.code,{children:"state_get_dictionary_item_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"dictionary_key"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key under which the value is stored."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_dictionary_item_result",\n "value": {\n "api_version": "2.0.0",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "stored_value": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_entity",children:"state_get_entity"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#addressableentity",children:"AddressableEntity"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the entity at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the entity's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#entityidentifier",children:"entity_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Identifier of an addressable entity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_entity",\n "params": [\n {\n "name": "entity_identifier",\n "value": {\n "EntityAddr": "entity-account-0000000000000000000000000000000000000000000000000000000000000000"\n }\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_entity_result",children:(0,s.jsx)(n.code,{children:"state_get_entity_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#addressableentity",children:"entity"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the AddressableEntity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_entity_result",\n "value": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c"\n },\n "package_hash": "package-0000000000000000000000000000000000000000000000000000000000000000",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "topic",\n "topic_name_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n ]\n },\n "named_keys": [\n {\n "name": "key",\n "key": "hash-0000000000000000000000000000000000000000000000000000000000000000"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "entry_point",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Caller",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h1,{id:"node-informational-json-rpc-methods",children:"Node Informational JSON-RPC Methods"}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"info_get_peers",children:"info_get_peers"}),"\n",(0,s.jsx)(n.p,{children:"This method returns a list of peers connected to the node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_peers_result",children:(0,s.jsx)(n.code,{children:"info_get_peers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#peers",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_peers_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_status",children:"info_get_status"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the current status of a node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_status_result",children:(0,s.jsx)(n.code,{children:"info_get_status_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#availableblockrange",children:"available_block_range"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available block range in storage."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blocksynchronizerstatus",children:"block_sync"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The status of the block synchronizer builders."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"build_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The compiled node version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"chainspec_name"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The chainspec name, used to identify the currently connected network."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#minimalblockinfo",children:"last_added_block_info"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The minimal info of the last Block from the linear chain. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timestamp",children:"last_progress"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Timestamp of the last recorded progress in the reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#blockhash",children:"latest_switch_block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The hash of the latest switch block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#nextupgrade",children:"next_upgrade"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"Information about the next scheduled upgrade. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#publickey",children:"our_public_signing_key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Our public signing key. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#reactorstate",children:"reactor_state"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The current state of the node reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timediff",children:"round_length"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#digest",children:"starting_state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The state root hash used at the start of the current session."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/developers/json-rpc/types_chain#timediff",children:"uptime"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"Time that passed since the node has started."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "last_added_block_info": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n },\n "latest_switch_block_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n }\n}\n}\n\n'})}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>c});var s=a(96540);const r={},t=s.createContext(r);function d(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d638c601.58b730d1.js b/assets/js/d638c601.58b730d1.js deleted file mode 100644 index 530d9b96c..000000000 --- a/assets/js/d638c601.58b730d1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4858],{97218:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>o,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var s=a(74848),r=a(28453);const t={},d="Informational JSON-RPC Methods",c={id:"developers/json-rpc/json-rpc-informational",title:"Informational JSON-RPC Methods",description:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.",source:"@site/docs/developers/json-rpc/json-rpc-informational.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/json-rpc-informational",permalink:"/next/developers/json-rpc/json-rpc-informational",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{},sidebar:"developers",previous:{title:"Transactional JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-transactional"},next:{title:"Proof-of-Stake JSON-RPC Methods",permalink:"/next/developers/json-rpc/json-rpc-pos"}},i={},l=[{value:"chain_get_block",id:"chain_get_block",level:2},{value:"<code>chain_get_block_result</code>",id:"chain_get_block_result",level:3},{value:"chain_get_block_transfers",id:"chain_get_block_transfers",level:2},{value:"<code>chain_get_block_transfers_result</code>",id:"chain_get_block_transfers_result",level:3},{value:"chain_get_era_summary",id:"chain_get_era_summary",level:2},{value:"<code>chain_get_era_summary_result</code>",id:"chain_get_era_summary_result",level:3},{value:"chain_get_state_root_hash",id:"chain_get_state_root_hash",level:2},{value:"<code>chain_get_state_root_hash_result</code>",id:"chain_get_state_root_hash_result",level:3},{value:"info_get_chainspec",id:"info_get_chainspec",level:2},{value:"<code>info_get_chainspec_result</code>",id:"info_get_chainspec_result",level:3},{value:"info_get_deploy",id:"info_get_deploy",level:2},{value:"<code>info_get_deploy_result</code>",id:"info_get_deploy_result",level:3},{value:"info_get_reward",id:"info_get_reward",level:2},{value:"<code>info_get_reward_result</code>",id:"info_get_reward_result",level:3},{value:"info_get_transaction",id:"info_get_transaction",level:2},{value:"<code>info_get_transaction_result</code>",id:"info_get_transaction_result",level:3},{value:"query_balance",id:"query_balance",level:2},{value:"<code>query_balance_result</code>",id:"query_balance_result",level:3},{value:"query_balance_details",id:"query_balance_details",level:2},{value:"<code>query_balance_details_result</code>",id:"query_balance_details_result",level:3},{value:"query_global_state",id:"query_global_state",level:2},{value:"<code>query_global_state_result</code>",id:"query_global_state_result",level:3},{value:"state_get_account_info",id:"state_get_account_info",level:2},{value:"<code>state_get_account_info_result</code>",id:"state_get_account_info_result",level:3},{value:"state_get_dictionary_item",id:"state_get_dictionary_item",level:2},{value:"<code>state_get_dictionary_item_result</code>",id:"state_get_dictionary_item_result",level:3},{value:"state_get_entity",id:"state_get_entity",level:2},{value:"<code>state_get_entity_result</code>",id:"state_get_entity_result",level:3},{value:"info_get_peers",id:"info_get_peers",level:2},{value:"<code>info_get_peers_result</code>",id:"info_get_peers_result",level:3},{value:"info_get_status",id:"info_get_status",level:2},{value:"<code>info_get_status_result</code>",id:"info_get_status_result",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"informational-json-rpc-methods",children:"Informational JSON-RPC Methods"})}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block",children:"chain_get_block"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the JSON representation of a ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"})," from the network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash or the Block height. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_result"})}),"\n",(0,s.jsxs)(n.p,{children:["The result from ",(0,s.jsx)(n.code,{children:"chain_get_block"})," depends on block availability from a given node. If ",(0,s.jsx)(n.code,{children:"chain_get_block"})," returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#jsonblockwithsignatures",children:"block"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_result",\n "value": {\n "api_version": "2.0.0",\n "block_with_signatures": {\n "block": {\n "Version2": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "header": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "48859fb4865d8637d6a35cb224e222cd0e1b1c2dd72928932c1e35ac0550818b",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a"\n },\n "body": {\n "transactions": {\n "0": [\n {\n "Version1": "1414141414141414141414141414141414141414141414141414141414141414"\n }\n ],\n "1": [\n {\n "Version1": "1515151515151515151515151515151515151515151515151515151515151515"\n }\n ],\n "2": [\n {\n "Version1": "1616161616161616161616161616161616161616161616161616161616161616"\n }\n ],\n "3": [\n {\n "Version1": "1717171717171717171717171717171717171717171717171717171717171717"\n }\n ]\n },\n "rewarded_signatures": []\n }\n }\n },\n "proofs": [\n {\n "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "01e18ca03d2ef0238a6a2460a222e0b818406bda99d4c05502c80232013559b926d1c8bca6bf65386f54a847d7850cb76c0c5fd5e633c34c749b8b9958a638d806"\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_block_transfers",children:"chain_get_block_transfers"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns all ",(0,s.jsx)(n.strong,{children:"successful"})," native transfers within a given ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"})," from a network. If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the transfers from the most recent block."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_block_transfers",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_block_transfers_result",children:(0,s.jsx)(n.code,{children:"chain_get_block_transfers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockhash",children:"block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash, if found. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#transfer",children:"transfers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The Block's successful transfers, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_block_transfers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_block_transfers_result",\n "value": {\n "api_version": "2.0.0",\n "block_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_era_summary",children:"chain_get_era_summary"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns the era summary at a given ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the era summary at the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc":"2.0",\n "method":"chain_get_era_summary",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_era_summary_result",children:(0,s.jsx)(n.code,{children:"chain_get_era_summary_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#erasummary",children:"era_summary"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The era summary, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_era_summary result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": 1,\n "result": {\n "name": "chain_get_era_summary_result",\n "value": {\n "api_version": "2.0.0",\n "era_summary": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "era_id": 42,\n "stored_value": {\n "EraInfo": {\n "seigniorage_allocations": [\n {\n "Delegator": {\n "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "1000"\n }\n },\n {\n "Validator": {\n "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",\n "amount": "2000"\n }\n }\n ]\n }\n },\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"chain_get_state_root_hash",children:"chain_get_state_root_hash"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a state root hash at a given ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the highest state root hash."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsx)(n.tbody,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "chain_get_state_root_hash",\n "params": [\n {\n "name": "block_identifier",\n "value": {\n "Height": 10\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"chain_get_state_root_hash_result",children:(0,s.jsx)(n.code,{children:"chain_get_state_root_hash_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hex-encoded hash of the state root."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example chain_get_state_root_hash result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "chain_get_state_root_hash_result",\n "value": {\n "api_version": "2.0.0",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_chainspec",children:"info_get_chainspec"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 5510244237763930243,\n "jsonrpc": "2.0",\n "method": "info_get_chainspec",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_chainspec_result",children:(0,s.jsx)(n.code,{children:"info_get_chainspec_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#chainspecrawbytes",children:"chainspec_bytes"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_chainspec result"}),"\n",(0,s.jsxs)(n.p,{children:["Please note that adding a ",(0,s.jsx)(n.code,{children:"--vv"})," flag will return the full chainspec bytes."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_chainspec_result",\n "value": {\n "api_version": "2.0.0",\n "chainspec_bytes": {\n "chainspec_bytes": "[22040 hex chars]",\n "maybe_genesis_accounts_bytes": null,\n "maybe_global_state_bytes": null\n }\n }\n },\n "id": 5510244237763930243\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_deploy",children:"info_get_deploy"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"DEPRECATED"}),": Use ",(0,s.jsx)(n.a,{href:"#info_get_transaction",children:"info_get_transaction"})," instead."]})}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#execution-semantics-deploys",children:"Deploy"})," from a network. It requires a ",(0,s.jsx)(n.code,{children:"deploy_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#deployhash",children:"deploy_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The Deploy hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the Deploy with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": [\n {\n "name": "deploy_hash",\n "value": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_deploy_result",children:(0,s.jsx)(n.code,{children:"info_get_deploy_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the Deploy and the results of executing the Deploy."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", but has yet to execute it. If the network executed the ",(0,s.jsx)(n.code,{children:"Deploy"}),", it will return the results of the execution. The execution results contain the Block hash which contains the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#deploy",children:"deploy"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Deploy."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_deploy result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_deploy_result",\n "value": {\n "api_version": "2.0.0",\n "deploy": {\n "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",\n "header": {\n "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "gas_price": 1,\n "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",\n "dependencies": [\n "0101010101010101010101010101010101010101010101010101010101010101"\n ],\n "chain_name": "casper-example"\n },\n "payment": {\n "StoredContractByName": {\n "name": "casper-example",\n "entry_point": "example-entry-point",\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "I32",\n "bytes": "e8030000",\n "parsed": 1000\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"\n }\n ]\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_reward",children:"info_get_reward"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the reward for a given era and a validator or delegator."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#publickey",children:"validator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key of the validator."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#eraidentifier",children:"era_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsxs)(n.td,{children:["The era identifier. If ",(0,s.jsx)(n.code,{children:"None"}),", the last finalized era is used. (Optional)"]})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#publickey",children:"delegator"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsxs)(n.td,{children:["The public key of the delegator. If ",(0,s.jsx)(n.code,{children:"Some"}),", the rewards for the delegator are returned. If ",(0,s.jsx)(n.code,{children:"None"}),", the rewards for the validator are returned. (Optional)"]})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_reward",\n "params": [\n {\n "name": "era_identifier",\n "value": {\n "Era": 1\n }\n },\n {\n "name": "validator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n {\n "name": "delegator",\n "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_reward_result",children:(0,s.jsx)(n.code,{children:"info_get_reward_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#eraid",children:"era_id"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The era for which the reward was calculated."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#u512",children:"reward_amount"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The total reward amount in the requested era."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_reward result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_reward_result",\n "value": {\n "api_version": "2.0.0",\n "reward_amount": "42",\n "era_id": 1\n }\n } \n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_transaction",children:"info_get_transaction"}),"\n",(0,s.jsxs)(n.p,{children:["This method retrieves a transaction from a network. It requires a ",(0,s.jsx)(n.code,{children:"transaction_hash"})," to query the Deploy."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#transactionhash",children:"transaction_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The transaction hash."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#finalizedapprovals",children:"finalized_approvals"})}),(0,s.jsx)(n.td,{children:"Boolean"}),(0,s.jsx)(n.td,{children:"Determines whether to return the transaction with the finalized approvals substituted. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_transaction",\n "params": [\n {\n "name": "transaction_hash",\n "value": {\n "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"\n }\n },\n {\n "name": "finalized_approvals",\n "value": true\n }\n ],\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_transaction_result",children:(0,s.jsx)(n.code,{children:"info_get_transaction_result"})}),"\n",(0,s.jsx)(n.p,{children:"The response contains the transaction and the results of executing it on the network."}),"\n",(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"execution_info"})," field is empty, it means that the network processed the transaction but has yet to execute it. If the network executed the transaction, it will return the execution information, along with the block hash containing the transaction."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:"transaction"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The transaction."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#executioninfo",children:"execution_info"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"An array of execution results with Block hashes, if found. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_transaction result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_transaction_result",\n "value": {\n "api_version": "2.0.0",\n "transaction": {\n "Version1": {\n "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",\n "header": {\n "chain_name": "casper-example",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "ttl": "1h",\n "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",\n "pricing_mode": {\n "Fixed": {\n "gas_price_tolerance": 5\n }\n },\n "initiator_addr": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n }\n },\n "body": {\n "args": [\n [\n "source",\n {\n "cl_type": {\n "Option": "URef"\n },\n "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",\n "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"\n }\n ],\n [\n "target",\n {\n "cl_type": "URef",\n "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",\n "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"\n }\n ],\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500ac23fc06",\n "parsed": "30000000000"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "01e703000000000000",\n "parsed": 999\n }\n ]\n ],\n "target": "Native",\n "entry_point": "Transfer",\n "transaction_category": 0,\n "scheduling": "Standard"\n },\n "approvals": [\n {\n "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"\n }\n ]\n }\n },\n "execution_info": {\n "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "block_height": 10,\n "execution_result": {\n "Version2": {\n "initiator": {\n "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "error_message": null,\n "limit": "123456",\n "consumed": "100000",\n "cost": "246912",\n "payment": [\n {\n "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"\n }\n ],\n "transfers": [\n {\n "Version2": {\n "transaction_hash": {\n "Version1": "0101010101010101010101010101010101010101010101010101010101010101"\n },\n "from": {\n "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"\n },\n "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",\n "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",\n "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",\n "amount": "1000000000000",\n "gas": "2500000000",\n "id": 999\n }\n }\n ],\n "size_estimate": 186,\n "effects": [\n {\n "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",\n "kind": {\n "AddUInt64": 8\n }\n },\n {\n "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",\n "kind": "Identity"\n }\n ]\n }\n }\n }\n }\n } \n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance",children:"query_balance"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for the balance of a purse using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_result",children:(0,s.jsx)(n.code,{children:"query_balance_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#u512",children:"balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The balance represented in motes."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_result",\n "value": {\n "api_version": "2.0.0",\n "balance": "123456"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_balance_details",children:"query_balance_details"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows you to query for full balance information using a ",(0,s.jsx)(n.code,{children:"PurseIdentifier"})," and ",(0,s.jsx)(n.code,{children:"StateIdentifier"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#purseidentifier",children:"purse_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier to obtain the purse corresponding to the balance query."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_balance_details",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n },\n {\n "name": "purse_identifier",\n "value": {\n "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_balance_details_result",children:(0,s.jsx)(n.code,{children:"query_balance_details_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#u512",children:"available_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available balance in motes (total balance - sum of all active holds)."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#balanceholdwithproof",children:"holds"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The holds active at the requested point in time."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#u512",children:"total_balance"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The purses total balance, not considering holds."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"`total_balance_proof"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"A proof that the given value is present in the Merkle trie."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_balance_details result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "jsonrpc": "2.0",\n "id": -6143675785141640608,\n "result": {\n "name": "query_balance_details_result",\n "value": {\n "api_version": "2.0.0",\n "total_balance": "123456",\n "available_balance": "123456",\n "total_balance_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",\n "holds": [\n {\n "time": 0,\n "amount": "123456",\n "proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"query_global_state",children:"query_global_state"}),"\n",(0,s.jsxs)(n.p,{children:["This method allows for you to query for a value stored under certain keys in global state. You may query using either a ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block_hash",children:"Block hash"})," or state root hash."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Note: Querying a purse's balance requires the use of ",(0,s.jsx)(n.code,{children:"query_balance"}),", rather than any iteration of ",(0,s.jsx)(n.code,{children:"query_global_state"}),"."]}),"\n"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#key",children:"key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key as a formatted string, under which data can be stored in global state."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#globalstateidentifier",children:"state_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The identifier used for the query. If not provided, the tip of the chain will be used. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"path"}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The path components starting from the key as base. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "query_global_state",\n "params": [\n {\n "name": "state_identifier",\n "value": {\n "BlockHash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"\n }\n },\n {\n "name": "key",\n "value": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"\n },\n {\n "name": "path",\n "value": []\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"query_global_state_result",children:(0,s.jsx)(n.code,{children:"query_global_state_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockheaderv2",children:"block_header"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block header if a Block hash was provided. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example query_global_state result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "2.0.0",\n "block_header": {\n "Version2": {\n "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "body_hash": "0505050505050505050505050505050505050505050505050505050505050505",\n "random_bit": true,\n "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",\n "era_end": {\n "equivocators": [\n "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n ],\n "inactive_validators": [\n "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"\n ],\n "next_era_validator_weights": [\n {\n "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",\n "weight": "123"\n },\n {\n "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",\n "weight": "456"\n },\n {\n "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",\n "weight": "789"\n }\n ],\n "rewards": {},\n "next_era_gas_price": 1\n },\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "protocol_version": "1.0.0",\n "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "current_gas_price": 1,\n "last_switch_block_hash": "0909090909090909090909090909090909090909090909090909090909090909"\n }\n },\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_account_info",children:"state_get_account_info"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Account"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the account at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the Account's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#accountidentifier",children:"account_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The public key or account hash of the Account."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_account_info",\n "params": [\n {\n "name": "account_identifier",\n "value": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_account_info_result",children:(0,s.jsx)(n.code,{children:"state_get_account_info_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#account",children:"account"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the Account structure."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_account_info result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_account_info_result",\n "value": {\n "api_version": "2.0.0",\n "account": {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "named_keys": [\n {\n "name": "main_purse",\n "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"\n }\n ],\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_dictionary_item",children:"state_get_dictionary_item"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns an item from a Dictionary. Every dictionary has a seed URef, findable by using a ",(0,s.jsx)(n.code,{children:"dictionary_identifier"}),". The address of a stored value is the blake2b hash of the seed URef and the byte representation of the dictionary key."]}),"\n",(0,s.jsx)(n.p,{children:"You may query a stored value directly using the dictionary address."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#digest",children:"state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Hash of the state root."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#dictionaryidentifier",children:"dictionary_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Dictionary query identifier."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_dictionary_item",\n "params": [\n {\n "name": "state_root_hash",\n "value": "0808080808080808080808080808080808080808080808080808080808080808"\n },\n {\n "name": "dictionary_identifier",\n "value": {\n "URef": {\n "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "dictionary_item_key": "a_unique_entry_identifier"\n }\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_dictionary_item_result",children:(0,s.jsx)(n.code,{children:"state_get_dictionary_item_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"dictionary_key"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The key under which the value is stored."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#storedvalue",children:"stored_value"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The stored value."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#merkle-proof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_dictionary_item result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_dictionary_item_result",\n "value": {\n "api_version": "2.0.0",\n "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",\n "stored_value": {\n "CLValue": {\n "cl_type": "U64",\n "bytes": "0100000000000000",\n "parsed": 1\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"state_get_entity",children:"state_get_entity"}),"\n",(0,s.jsxs)(n.p,{children:["This method returns a JSON representation of an ",(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#addressableentity",children:"AddressableEntity"})," from the network at a given ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#block-structure-head",children:"Block"}),". If you do not specify a ",(0,s.jsx)(n.code,{children:"block_identifier"}),", you will receive the state of the entity at the highest state root hash. The ",(0,s.jsx)(n.code,{children:"block_identifier"})," must refer to a Block after the entity's creation, or the method will return an empty response."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#entityidentifier",children:"entity_identifier"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Identifier of an addressable entity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockidentifier",children:"block_identifier"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The Block hash. (Optional)"})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "state_get_entity",\n "params": [\n {\n "name": "entity_identifier",\n "value": {\n "EntityAddr": "entity-account-0000000000000000000000000000000000000000000000000000000000000000"\n }\n },\n {\n "name": "block_identifier",\n "value": {\n "Hash": "0707070707070707070707070707070707070707070707070707070707070707"\n }\n }\n ]\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"state_get_entity_result",children:(0,s.jsx)(n.code,{children:"state_get_entity_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#addressableentity",children:"entity"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"A JSON representation of the AddressableEntity."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#merkleproof",children:"merkle_proof"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The merkle proof."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example state_get_entity result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "state_get_entity_result",\n "value": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c"\n },\n "package_hash": "package-0000000000000000000000000000000000000000000000000000000000000000",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": [\n {\n "topic_name": "topic",\n "topic_name_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n ]\n },\n "named_keys": [\n {\n "name": "key",\n "key": "hash-0000000000000000000000000000000000000000000000000000000000000000"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "entry_point",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Caller",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h1,{id:"node-informational-json-rpc-methods",children:"Node Informational JSON-RPC Methods"}),"\n",(0,s.jsx)(n.p,{children:"The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary."}),"\n",(0,s.jsx)(n.hr,{}),"\n",(0,s.jsx)(n.h2,{id:"info_get_peers",children:"info_get_peers"}),"\n",(0,s.jsx)(n.p,{children:"This method returns a list of peers connected to the node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_peers",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_peers_result",children:(0,s.jsx)(n.code,{children:"info_get_peers_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#peers",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_peers result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_peers_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ]\n }\n }\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"info_get_status",children:"info_get_status"}),"\n",(0,s.jsx)(n.p,{children:"This method returns the current status of a node."}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status request"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "method": "info_get_status",\n "params": []\n}\n\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"info_get_status_result",children:(0,s.jsx)(n.code,{children:"info_get_status_result"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Parameter"}),(0,s.jsx)(n.th,{children:"Type"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"api_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The RPC API version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#availableblockrange",children:"available_block_range"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The available block range in storage."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blocksynchronizerstatus",children:"block_sync"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The status of the block synchronizer builders."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"build_version"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The compiled node version."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:"chainspec_name"}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The chainspec name, used to identify the currently connected network."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#minimalblockinfo",children:"last_added_block_info"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The minimal info of the last Block from the linear chain. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#timestamp",children:"last_progress"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Timestamp of the last recorded progress in the reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#blockhash",children:"latest_switch_block_hash"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"The hash of the latest switch block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#nextupgrade",children:"next_upgrade"})}),(0,s.jsx)(n.td,{children:"Object"}),(0,s.jsx)(n.td,{children:"Information about the next scheduled upgrade. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#publickey",children:"our_public_signing_key"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"Our public signing key. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#peersmap",children:"peers"})}),(0,s.jsx)(n.td,{children:"Array"}),(0,s.jsx)(n.td,{children:"The node ID and network address of each connected peer."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#reactorstate",children:"reactor_state"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The current state of the node reactor."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#timediff",children:"round_length"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"The next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#digest",children:"starting_state_root_hash"})}),(0,s.jsx)(n.td,{children:"String"}),(0,s.jsx)(n.td,{children:"The state root hash used at the start of the current session."})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#timediff",children:"uptime"})}),(0,s.jsx)(n.td,{children:"Integer"}),(0,s.jsx)(n.td,{children:"Time that passed since the node has started."})]})]})]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example info_get_status result"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'\n{\n "id": 1,\n "jsonrpc": "2.0",\n "result": {\n "name": "info_get_status_result",\n "value": {\n "api_version": "2.0.0",\n "peers": [\n {\n "node_id": "tls:0101..0101",\n "address": "127.0.0.1:54321"\n }\n ],\n "build_version": "1.0.0-xxxxxxxxx@DEBUG",\n "chainspec_name": "casper-example",\n "starting_state_root_hash": "0000000000000000000000000000000000000000000000000000000000000000",\n "last_added_block_info": {\n "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",\n "timestamp": "2020-11-17T00:39:24.072Z",\n "era_id": 1,\n "height": 10,\n "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",\n "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"\n },\n "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",\n "round_length": "1m 5s 536ms",\n "next_upgrade": {\n "activation_point": 42,\n "protocol_version": "2.0.1"\n },\n "uptime": "13s",\n "reactor_state": "Initialize",\n "last_progress": "1970-01-01T00:00:00.000Z",\n "available_block_range": {\n "low": 0,\n "high": 0\n },\n "block_sync": {\n "historical": {\n "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",\n "block_height": 40,\n "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"\n },\n "forward": {\n "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",\n "block_height": 6701,\n "acquisition_state": "have block body(6701) for: block hash 5990..4983"\n }\n },\n "latest_switch_block_hash": "0000000000000000000000000000000000000000000000000000000000000000"\n }\n }\n}\n}\n\n'})}),"\n"]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>c});var s=a(96540);const r={},t=s.createContext(r);function d(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7289626.35d9a384.js b/assets/js/d7289626.35d9a384.js new file mode 100644 index 000000000..80fa021cf --- /dev/null +++ b/assets/js/d7289626.35d9a384.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66247],{53158:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>a});var s=t(74848),r=t(28453);const i={title:"Design Overview",slug:"/design"},c=void 0,d={id:"concepts/design/index",title:"Design Overview",description:"| Topic | Description |",source:"@site/docs/concepts/design/index.md",sourceDirName:"concepts/design",slug:"/design",permalink:"/design",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Design Overview",slug:"/design"},sidebar:"concepts",previous:{title:"What is Casper?",permalink:"/concepts/about"},next:{title:"Network Design",permalink:"/concepts/design/casper-design"}},o={},a=[];function l(e){const n={a:"a",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/casper-design",children:"Network Design"})}),(0,s.jsx)(n.td,{children:"Overview of execution semantics, account permissions, URefs, block structure, tokens, and more"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network Communication"})}),(0,s.jsx)(n.td,{children:"Peer-to-peer communication for Casper nodes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/consensus",children:"Consensus in Casper"})}),(0,s.jsx)(n.td,{children:"Introduction to Consensus in a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/zug",children:"Zug Consensus"})}),(0,s.jsx)(n.td,{children:"An overview of the Zug consensus used in Mainnet and Testnet"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway Consensus"})}),(0,s.jsx)(n.td,{children:"Brief overview of the Highway consensus available as an alternative to Zug"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/rewards",children:"Validator Rewards"})}),(0,s.jsx)(n.td,{children:"Overview of how rewards are calculated and distributed"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to Global State"})}),(0,s.jsx)(n.td,{children:"Storing and reading data from the blockchain"})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>d});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7289626.6cdeaeb0.js b/assets/js/d7289626.6cdeaeb0.js deleted file mode 100644 index 898890193..000000000 --- a/assets/js/d7289626.6cdeaeb0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6247],{53158:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>d,toc:()=>a});var s=t(74848),r=t(28453);const i={title:"Design Overview",slug:"/design"},c=void 0,d={id:"concepts/design/index",title:"Design Overview",description:"| Topic | Description |",source:"@site/docs/concepts/design/index.md",sourceDirName:"concepts/design",slug:"/design",permalink:"/next/design",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Design Overview",slug:"/design"},sidebar:"concepts",previous:{title:"What is Casper?",permalink:"/next/"},next:{title:"Network Design",permalink:"/next/concepts/design/casper-design"}},o={},a=[];function l(e){const n={a:"a",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Topic"}),(0,s.jsx)(n.th,{children:"Description"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design",children:"Network Design"})}),(0,s.jsx)(n.td,{children:"Overview of execution semantics, account permissions, URefs, block structure, tokens, and more"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/p2p",children:"Network Communication"})}),(0,s.jsx)(n.td,{children:"Peer-to-peer communication for Casper nodes"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/consensus",children:"Consensus in Casper"})}),(0,s.jsx)(n.td,{children:"Introduction to Consensus in a Casper network"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/zug",children:"Zug Consensus"})}),(0,s.jsx)(n.td,{children:"An overview of the Zug consensus used in Mainnet and Testnet"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/highway",children:"Highway Consensus"})}),(0,s.jsx)(n.td,{children:"Brief overview of the Highway consensus available as an alternative to Zug"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/rewards",children:"Validator Rewards"})}),(0,s.jsx)(n.td,{children:"Overview of how rewards are calculated and distributed"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.a,{href:"/next/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to Global State"})}),(0,s.jsx)(n.td,{children:"Storing and reading data from the blockchain"})]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>c,x:()=>d});var s=t(96540);const r={},i=s.createContext(r);function c(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7f9f727.75d78148.js b/assets/js/d7f9f727.75d78148.js deleted file mode 100644 index fece13d38..000000000 --- a/assets/js/d7f9f727.75d78148.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3495],{54541:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>i});var t=n(74848),c=n(28453);const r={},a="G",o={id:"concepts/glossary/G",title:"G",description:"---",source:"@site/docs/concepts/glossary/G.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/G",permalink:"/next/concepts/glossary/G",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"F",permalink:"/next/concepts/glossary/F"},next:{title:"H",permalink:"/next/concepts/glossary/H"}},l={},i=[{value:"Gas",id:"gas",level:2},{value:"Gas cost",id:"gas-cost",level:2},{value:"Gas price",id:"gas-price",level:2},{value:"Genesis",id:"genesis",level:2},{value:"Groups",id:"groups",level:2},{value:"Global state",id:"global-state",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"g",children:"G"})}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(s.hr,{}),"\n",(0,t.jsx)(s.h2,{id:"gas",children:"Gas"}),"\n",(0,t.jsx)(s.p,{children:"Gas is a conceptual measure of resources used when executing transactions on the blockchain."}),"\n",(0,t.jsx)(s.h2,{id:"gas-cost",children:"Gas cost"}),"\n",(0,t.jsx)(s.p,{children:"Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,t.jsx)(s.h2,{id:"gas-price",children:"Gas price"}),"\n",(0,t.jsxs)(s.p,{children:["Multiplier applied to gas cost. See ",(0,t.jsx)(s.a,{href:"/next/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"}),"."]}),"\n",(0,t.jsx)(s.h2,{id:"genesis",children:"Genesis"}),"\n",(0,t.jsx)(s.p,{children:"The state of the virtual machine at the beginning of the blockchain."}),"\n",(0,t.jsx)(s.h2,{id:"groups",children:"Groups"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"user groups"})," feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:"]}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:"User groups associate a set of URefs with a label."}),"\n",(0,t.jsx)(s.li,{children:"The entry points on a contract can accept a list of labels"}),"\n",(0,t.jsx)(s.li,{children:"The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution."}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"global-state",children:"Global state"}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#blockchain",children:"blockchain"})," as a decentralized computer, the global state is its memory state."]}),"\n",(0,t.jsxs)(s.p,{children:["When thinking of a ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#blockchain",children:"blockchain"})," as a shared database, the global state is the snapshot of the database's data."]}),"\n",(0,t.jsxs)(s.p,{children:["Technically, a ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"})," is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs)."]}),"\n",(0,t.jsxs)(s.p,{children:["For every ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#block",children:"block"})," B in the ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/B#blockchain",children:"blockchain"}),", one can compute the ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"})," achieved by executing all ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/T#transaction",children:"transactions"})," in this block and its ancestors. The ",(0,t.jsx)(s.a,{href:"/next/concepts/glossary/R#root-hash",children:"root hash"})," identifying this state is stored in every executed block."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var t=n(96540);const c={},r=t.createContext(c);function a(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:a(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7f9f727.baf34cdc.js b/assets/js/d7f9f727.baf34cdc.js new file mode 100644 index 000000000..c208f7e0a --- /dev/null +++ b/assets/js/d7f9f727.baf34cdc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[83495],{54541:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>i});var c=n(74848),t=n(28453);const r={},a="G",o={id:"concepts/glossary/G",title:"G",description:"---",source:"@site/docs/concepts/glossary/G.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/G",permalink:"/concepts/glossary/G",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"ipopescu",lastUpdatedAt:1724191663e3,frontMatter:{},sidebar:"concepts",previous:{title:"F",permalink:"/concepts/glossary/F"},next:{title:"H",permalink:"/concepts/glossary/H"}},l={},i=[{value:"Gas",id:"gas",level:2},{value:"Gas cost",id:"gas-cost",level:2},{value:"Gas price",id:"gas-price",level:2},{value:"Genesis",id:"genesis",level:2},{value:"Groups",id:"groups",level:2},{value:"Global state",id:"global-state",level:2}];function h(e){const s={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",ul:"ul",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"g",children:"G"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"gas",children:"Gas"}),"\n",(0,c.jsx)(s.p,{children:"Gas is a conceptual measure of resources used when executing transactions on the blockchain."}),"\n",(0,c.jsx)(s.h2,{id:"gas-cost",children:"Gas cost"}),"\n",(0,c.jsx)(s.p,{children:"Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction."}),"\n",(0,c.jsx)(s.h2,{id:"gas-price",children:"Gas price"}),"\n",(0,c.jsxs)(s.p,{children:["Multiplier applied to gas cost. See ",(0,c.jsx)(s.a,{href:"/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"genesis",children:"Genesis"}),"\n",(0,c.jsx)(s.p,{children:"The state of the virtual machine at the beginning of the blockchain."}),"\n",(0,c.jsx)(s.h2,{id:"groups",children:"Groups"}),"\n",(0,c.jsxs)(s.p,{children:["The ",(0,c.jsx)(s.em,{children:"user groups"})," feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:"]}),"\n",(0,c.jsxs)(s.ul,{children:["\n",(0,c.jsx)(s.li,{children:"User groups associate a set of URefs with a label."}),"\n",(0,c.jsx)(s.li,{children:"The entry points on a contract can accept a list of labels"}),"\n",(0,c.jsx)(s.li,{children:"The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution."}),"\n"]}),"\n",(0,c.jsx)(s.h2,{id:"global-state",children:"Global state"}),"\n",(0,c.jsxs)(s.p,{children:["When thinking of a ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"})," as a decentralized computer, the global state is its memory state."]}),"\n",(0,c.jsxs)(s.p,{children:["When thinking of a ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"})," as a shared database, the global state is the snapshot of the database's data."]}),"\n",(0,c.jsxs)(s.p,{children:["Technically, a ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs)."]}),"\n",(0,c.jsxs)(s.p,{children:["For every ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B#block",children:"block"})," B in the ",(0,c.jsx)(s.a,{href:"/concepts/glossary/B#blockchain",children:"blockchain"}),", one can compute the ",(0,c.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"})," achieved by executing all ",(0,c.jsx)(s.a,{href:"/concepts/glossary/T#transaction",children:"transactions"})," in this block and its ancestors. The ",(0,c.jsx)(s.a,{href:"/concepts/glossary/R#root-hash",children:"root hash"})," identifying this state is stored in every executed block."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var c=n(96540);const t={},r=c.createContext(t);function a(e){const s=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7fae98e.1349e043.js b/assets/js/d7fae98e.1349e043.js new file mode 100644 index 000000000..9a70b9b59 --- /dev/null +++ b/assets/js/d7fae98e.1349e043.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[17636],{70358:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>d,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=n(74848),s=n(28453);const a={slug:"/resources/tutorials/advanced/"},d="Advanced Tutorials",i={id:"resources/advanced/index",title:"Advanced Tutorials",description:"| Title | Description |",source:"@site/versioned_docs/version-1.5.X/resources/advanced/index.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/",permalink:"/1.5.X/resources/tutorials/advanced/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tutorials/advanced/"},sidebar:"tutorials",previous:{title:"AWS Casper Nodes",permalink:"/1.5.X/resources/tutorials/beginner/aws-node"},next:{title:"Two-Party Multi-Sig",permalink:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig"}},o={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"advanced-tutorials",children:"Advanced Tutorials"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Title"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})}),(0,r.jsx)(t.td,{children:"A trivial two-party multi-signature scheme for signing and sending deploys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/advanced/multi-sig/",children:"Multi-Sig Management"})}),(0,r.jsx)(t.td,{children:"Integrate key management on Casper accounts and sign deploys with multiple keys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsxs)(t.td,{children:["Contract code returning a value to the immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(t.td,{children:"Two methods to handle tokens via a contract"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})}),(0,r.jsx)(t.td,{children:"Methods to read and write data to global state on a Casper network using Rust"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/cross-contract",children:"Cross Contract Communication"})}),(0,r.jsx)(t.td,{children:"Variations of cross-contract communication for more complex scenarios"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/1.5.X/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(t.td,{children:"Retrieve and use the authorization keys associated with a deploy"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>i});var r=n(96540);const s={},a=r.createContext(s);function d(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d7fae98e.1faab744.js b/assets/js/d7fae98e.1faab744.js deleted file mode 100644 index 72c1e092a..000000000 --- a/assets/js/d7fae98e.1faab744.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7636],{70358:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>o,contentTitle:()=>d,default:()=>u,frontMatter:()=>a,metadata:()=>i,toc:()=>c});var r=n(74848),s=n(28453);const a={slug:"/resources/tutorials/advanced/"},d="Advanced Tutorials",i={id:"resources/advanced/index",title:"Advanced Tutorials",description:"| Title | Description |",source:"@site/versioned_docs/version-1.5.X/resources/advanced/index.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/",permalink:"/resources/tutorials/advanced/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{slug:"/resources/tutorials/advanced/"},sidebar:"tutorials",previous:{title:"AWS Casper Nodes",permalink:"/resources/tutorials/beginner/aws-node"},next:{title:"Two-Party Multi-Sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig"}},o={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"advanced-tutorials",children:"Advanced Tutorials"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(t.table,{children:[(0,r.jsx)(t.thead,{children:(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.th,{children:"Title"}),(0,r.jsx)(t.th,{children:"Description"})]})}),(0,r.jsxs)(t.tbody,{children:[(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})}),(0,r.jsx)(t.td,{children:"A trivial two-party multi-signature scheme for signing and sending deploys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/advanced/multi-sig/",children:"Multi-Sig Management"})}),(0,r.jsx)(t.td,{children:"Integrate key management on Casper accounts and sign deploys with multiple keys"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})}),(0,r.jsxs)(t.td,{children:["Contract code returning a value to the immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"})]})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/transfer-token-to-contract",children:"Safely Transfer Tokens to a Contract"})}),(0,r.jsx)(t.td,{children:"Two methods to handle tokens via a contract"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/storage-workflow",children:"Reading and Writing to Global State using Rust"})}),(0,r.jsx)(t.td,{children:"Methods to read and write data to global state on a Casper network using Rust"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/tutorials/advanced/cross-contract",children:"Cross Contract Communication"})}),(0,r.jsx)(t.td,{children:"Variations of cross-contract communication for more complex scenarios"})]}),(0,r.jsxs)(t.tr,{children:[(0,r.jsx)(t.td,{children:(0,r.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})}),(0,r.jsx)(t.td,{children:"Retrieve and use the authorization keys associated with a deploy"})]})]})]})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>d,x:()=>i});var r=n(96540);const s={},a=r.createContext(s);function d(e){const t=r.useContext(a);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),r.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d80df429.67028afb.js b/assets/js/d80df429.67028afb.js deleted file mode 100644 index e563678ff..000000000 --- a/assets/js/d80df429.67028afb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3846],{48130:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var t=s(74848),i=s(28453);const a={title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},r="CEP-78 JavaScript Client Tutorial",l={id:"resources/tokens/cep78/js-tutorial",title:"CEP-78 JavaScript Client",description:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.",source:"@site/docs/resources/tokens/cep78/js-tutorial.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/js-tutorial",permalink:"/next/resources/tokens/cep78/js-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},sidebar:"resources",previous:{title:"Ownership Lookup",permalink:"/next/resources/tokens/cep78/reverse-lookup"},next:{title:"Open-Source Software",permalink:"/next/resources/build-on-casper/casper-open-source-software"}},c={},o=[{value:"Client Installation",id:"client-installation",level:2},{value:"Installing a CEP-78 Contract using the JavaScript Client",id:"installing-a-cep-78-contract-using-the-javascript-client",level:2},{value:"Minting a Token",id:"minting-a-token",level:2},{value:"Register Recipient",id:"register-recipient",level:2},{value:"Transferring a Token",id:"transferring-a-token",level:2},{value:"Burning a Token",id:"burning-a-token",level:2},{value:"Example Usages",id:"example-usages",level:2},{value:"Running an Install Example",id:"running-an-install-example",level:3},{value:"Running a Usage Example",id:"running-a-usage-example",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"cep-78-javascript-client-tutorial",children:"CEP-78 JavaScript Client Tutorial"})}),"\n",(0,t.jsx)(n.p,{children:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on the CEP-78 Enhanced NFT Standard can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The client is available in ",(0,t.jsx)(n.em,{children:"npm"})," as ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-cep78-js-client",children:"casper-cep78-js-client"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"client-installation",children:"Client Installation"}),"\n",(0,t.jsx)(n.p,{children:"The client can be installed in a project you have built using TypeScript / Javascript."}),"\n",(0,t.jsx)(n.p,{children:"To install run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm install casper-cep78-js-client\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-cep-78-contract-using-the-javascript-client",children:"Installing a CEP-78 Contract using the JavaScript Client"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"install"})," method crafts a ",(0,t.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle",children:"Deploy"})," using ",(0,t.jsx)(n.code,{children:"InstallArgs"}),".\nAs with every deploy created by the SDK, you can send it using the ",(0,t.jsx)(n.code,{children:".send(rpcUrl)"})," method providing the RPC URL that you want to use. It will return deployHash."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);\n\n const installDeploy = await cc.install(\n {\n collectionName: "my-collection",\n collectionSymbol: "MY-NFTS",\n totalTokenSupply: "1000",\n ownershipMode: NFTOwnershipMode.Transferable,\n nftKind: NFTKind.Physical,\n jsonSchema: {\n properties: {\n color: { name: "color", description: "", required: true },\n size: { name: "size", description: "", required: true },\n material: { name: "material", description: "", required: true },\n condition: { name: "condition", description: "", required: false },\n },\n },\n nftMetadataKind: NFTMetadataKind.CustomValidated,\n identifierMode: NFTIdentifierMode.Ordinal,\n metadataMutability: MetadataMutability.Immutable,\n mintingMode: MintingMode.Installer,\n ownerReverseLookupMode: OwnerReverseLookupMode.Complete\n },\n "250000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"InstallArgs"})," are specified as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionName"})," - The name of the NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionSymbol"})," - The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"totalTokenSupply"})," - The total number of NFTs that a specific contract instance will mint passed in as a ",(0,t.jsx)(n.code,{children:"U64"})," value. ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownershipMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnershipMode"})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftKind"})," - The ",(0,t.jsx)(n.code,{children:"NFTKind"})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"jsonSchema"})," - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". More information on ",(0,t.jsx)(n.code,{children:"NFTMetadataKind"})," can be found ",(0,t.jsx)(n.a,{href:"/next/resources/tokens/cep78/modalities#nftmetadatakind",children:"here"}),". This parameter may be left empty if metadata kind is set to ",(0,t.jsx)(n.code,{children:"Raw(3)"}),". If the metadata kind is set to ",(0,t.jsx)(n.code,{children:"CustomValidated(4)"}),", it will require a specifically formatted custom schema. This parameter ",(0,t.jsx)(n.strong,{children:"cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftMetadataKind"})," - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"identifierMode"})," - The ",(0,t.jsx)(n.code,{children:"NFTIdentifierMode"})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"metadataMutability"})," - The ",(0,t.jsx)(n.code,{children:"MetadataMutability"})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"mintingmode"})," - The ",(0,t.jsx)(n.code,{children:"MintingMode"})," modality dictates the access to the ",(0,t.jsx)(n.code,{children:"mint()"})," entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"holdermode"})," - The ",(0,t.jsx)(n.code,{children:"NFTHolderMode"})," modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either ",(0,t.jsx)(n.code,{children:"Accounts"})," or ",(0,t.jsx)(n.code,{children:"Contracts"})," to hold NFTs. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"burnMode"})," - The ",(0,t.jsx)(n.code,{children:"BurnMode"})," modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownerReverseLookupMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," dictates whether the contract will index ownership of tokens as outlined ",(0,t.jsx)(n.a,{href:"/next/resources/tokens/cep78/reverse-lookup#the-cep-78-page-system",children:"here"})," to allow lookup of owned tokens by account. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Further information on CEP-78 modality options can be found ",(0,t.jsx)(n.a,{href:"/next/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"minting-a-token",children:"Minting a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The CEP-78 JS Client includes code to construct a deploy that will ",(0,t.jsx)(n.code,{children:"Mint"})," a token, as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const mintDeploy = cc.mint(\n {\n owner: FAUCET_KEYS.publicKey,\n meta: {\n color: "Blue",\n size: "Medium",\n material: "Aluminum",\n condition: "Used",\n },\n },\n { useSessionCode: true },\n "2000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The arguments adhere to those provided in the original installation, with the ",(0,t.jsx)(n.code,{children:".send()"})," pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL."]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L86-L88",children:(0,t.jsx)(n.code,{children:"useSessionCode"})})," variable decides if the user will call ",(0,t.jsx)(n.code,{children:"mint"})," using session code, or not. It will be set to ",(0,t.jsx)(n.code,{children:"true"})," if the ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"Complete"}),". ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L116-L130",children:"It then registers the recipient with the contract"})," and mints the token."]}),"\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"NoLookup"}),", ",(0,t.jsx)(n.code,{children:"useSessionCode"})," will be set to ",(0,t.jsx)(n.code,{children:"false"})," and it will simply mint the token as it does not need to register the recipient."]}),"\n",(0,t.jsx)(n.h2,{id:"register-recipient",children:"Register Recipient"}),"\n",(0,t.jsxs)(n.p,{children:["As we used ",(0,t.jsx)(n.code,{children:"ownerReverseLookupMode: OwnerReverseLookupMode.Complete"})," in this contract installation, we must register the recipient. To do this, we construct a ",(0,t.jsx)(n.code,{children:"register"})," deploy:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const registerDeploy = cc.register(\n {\n tokenOwner: USER1_KEYS.publicKey,\n },\n "1000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");\n \n'})}),"\n",(0,t.jsx)(n.h2,{id:"transferring-a-token",children:"Transferring a Token"}),"\n",(0,t.jsx)(n.p,{children:"After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const transferDeploy = cc.transfer(\n {\n tokenId: "0",\n source: FAUCET_KEYS.publicKey,\n target: USER1_KEYS.publicKey,\n },\n { useSessionCode: true },\n "13000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"Transferring accepts the following arguments:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"tokenId"})," - The sequential ID assigned to a token in mint order."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"source"})," - The account sending the token in question."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"target"})," - The account receiving the transferred token."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["As above, the ",(0,t.jsx)(n.code,{children:"useSessionCode"})," variable determines if the user will call ",(0,t.jsx)(n.code,{children:"transfer"})," using session code based on the setting of ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"burning-a-token",children:"Burning a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the ",(0,t.jsx)(n.code,{children:"tokenId"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const burnDeploy = await contractClient.burn(\n { tokenId: "0" },\n "13000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.h2,{id:"example-usages",children:"Example Usages"}),"\n",(0,t.jsx)(n.h3,{id:"running-an-install-example",children:"Running an Install Example"}),"\n",(0,t.jsx)(n.p,{children:"This repository includes an example script for installing a CEP-78 contract instance."}),"\n",(0,t.jsxs)(n.p,{children:["You will need to define the following variables in the ",(0,t.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NODE_URL"})," - The address of a node. If you are testing using ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/setup-nctl",children:"NCTL"}),", this will be ",(0,t.jsx)(n.code,{children:"http://localhost:11101/rpc"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NETWORK_NAME"})," - The name of the Casper network you are operating on, ",(0,t.jsx)(n.code,{children:"casper-net-1"})," when testing using a local network with NCTL."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MASTER_KEY_PAIR_PATH"})," - The path to the key pair of the minting account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"USER1_KEY_PAIR_PATH"})," - The path to an additional account's key pair for use in testing transfer features."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You may also need to install associated dependencies using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm i\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:install\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The example will then return the installation's ",(0,t.jsx)(n.code,{children:"deployHash"}),", and inform you when the installation is successful."]}),"\n",(0,t.jsx)(n.p,{children:"The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash."}),"\n",(0,t.jsx)(n.h3,{id:"running-a-usage-example",children:"Running a Usage Example"}),"\n",(0,t.jsx)(n.p,{children:"A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation."}),"\n",(0,t.jsx)(n.p,{children:"The usage example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:usage\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Mint"})," - The example will attempt to mint an NFT using the installation account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Transfer"})," - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Burn"})," - The example will burn the minted NFT."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The associated code for these deploys may be found in the ",(0,t.jsx)(n.code,{children:"client-js/examples"})," directory."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d80df429.d3c78300.js b/assets/js/d80df429.d3c78300.js new file mode 100644 index 000000000..1f617a47e --- /dev/null +++ b/assets/js/d80df429.d3c78300.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73846],{48130:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>o});var t=s(74848),i=s(28453);const a={title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},r="CEP-78 JavaScript Client Tutorial",l={id:"resources/tokens/cep78/js-tutorial",title:"CEP-78 JavaScript Client",description:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.",source:"@site/docs/resources/tokens/cep78/js-tutorial.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/js-tutorial",permalink:"/resources/tokens/cep78/js-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"CEP-78 JavaScript Client",slug:"/resources/tokens/cep78/js-tutorial"},sidebar:"resources",previous:{title:"Ownership Lookup",permalink:"/resources/tokens/cep78/reverse-lookup"},next:{title:"Open-Source Software",permalink:"/resources/build-on-casper/casper-open-source-software"}},c={},o=[{value:"Client Installation",id:"client-installation",level:2},{value:"Installing a CEP-78 Contract using the JavaScript Client",id:"installing-a-cep-78-contract-using-the-javascript-client",level:2},{value:"Minting a Token",id:"minting-a-token",level:2},{value:"Register Recipient",id:"register-recipient",level:2},{value:"Transferring a Token",id:"transferring-a-token",level:2},{value:"Burning a Token",id:"burning-a-token",level:2},{value:"Example Usages",id:"example-usages",level:2},{value:"Running an Install Example",id:"running-an-install-example",level:3},{value:"Running a Usage Example",id:"running-a-usage-example",level:3}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"cep-78-javascript-client-tutorial",children:"CEP-78 JavaScript Client Tutorial"})}),"\n",(0,t.jsx)(n.p,{children:"This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard."}),"\n",(0,t.jsxs)(n.p,{children:["Further information on the CEP-78 Enhanced NFT Standard can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The client is available in ",(0,t.jsx)(n.em,{children:"npm"})," as ",(0,t.jsx)(n.a,{href:"https://www.npmjs.com/package/casper-cep78-js-client",children:"casper-cep78-js-client"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"client-installation",children:"Client Installation"}),"\n",(0,t.jsx)(n.p,{children:"The client can be installed in a project you have built using TypeScript / Javascript."}),"\n",(0,t.jsx)(n.p,{children:"To install run:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm install casper-cep78-js-client\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-cep-78-contract-using-the-javascript-client",children:"Installing a CEP-78 Contract using the JavaScript Client"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"install"})," method crafts a ",(0,t.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle",children:"Deploy"})," using ",(0,t.jsx)(n.code,{children:"InstallArgs"}),".\nAs with every deploy created by the SDK, you can send it using the ",(0,t.jsx)(n.code,{children:".send(rpcUrl)"})," method providing the RPC URL that you want to use. It will return deployHash."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);\n\n const installDeploy = await cc.install(\n {\n collectionName: "my-collection",\n collectionSymbol: "MY-NFTS",\n totalTokenSupply: "1000",\n ownershipMode: NFTOwnershipMode.Transferable,\n nftKind: NFTKind.Physical,\n jsonSchema: {\n properties: {\n color: { name: "color", description: "", required: true },\n size: { name: "size", description: "", required: true },\n material: { name: "material", description: "", required: true },\n condition: { name: "condition", description: "", required: false },\n },\n },\n nftMetadataKind: NFTMetadataKind.CustomValidated,\n identifierMode: NFTIdentifierMode.Ordinal,\n metadataMutability: MetadataMutability.Immutable,\n mintingMode: MintingMode.Installer,\n ownerReverseLookupMode: OwnerReverseLookupMode.Complete\n },\n "250000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"InstallArgs"})," are specified as follows:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionName"})," - The name of the NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collectionSymbol"})," - The symbol representing a given NFT collection, passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"totalTokenSupply"})," - The total number of NFTs that a specific contract instance will mint passed in as a ",(0,t.jsx)(n.code,{children:"U64"})," value. ",(0,t.jsx)(n.strong,{children:"This parameter is required and cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownershipMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnershipMode"})," modality that dictates the ownership behavior of the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftKind"})," - The ",(0,t.jsx)(n.code,{children:"NFTKind"})," modality that specifies the off-chain items represented by the on-chain NFT data. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"jsonSchema"})," - The JSON schema for the NFT tokens that will be minted by the NFT contract passed in as a ",(0,t.jsx)(n.code,{children:"String"}),". More information on ",(0,t.jsx)(n.code,{children:"NFTMetadataKind"})," can be found ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities#nftmetadatakind",children:"here"}),". This parameter may be left empty if metadata kind is set to ",(0,t.jsx)(n.code,{children:"Raw(3)"}),". If the metadata kind is set to ",(0,t.jsx)(n.code,{children:"CustomValidated(4)"}),", it will require a specifically formatted custom schema. This parameter ",(0,t.jsx)(n.strong,{children:"cannot be changed post installation"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"nftMetadataKind"})," - The metadata schema for the NFTs to be minted by the NFT contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"identifierMode"})," - The ",(0,t.jsx)(n.code,{children:"NFTIdentifierMode"})," modality dictates the primary identifier for NFTs minted by the contract. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"metadataMutability"})," - The ",(0,t.jsx)(n.code,{children:"MetadataMutability"})," modality dictates whether the metadata of minted NFTs can be updated. This argument is passed in as a ",(0,t.jsx)(n.code,{children:"u8"})," value and is required at the time of installation."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"mintingmode"})," - The ",(0,t.jsx)(n.code,{children:"MintingMode"})," modality dictates the access to the ",(0,t.jsx)(n.code,{children:"mint()"})," entry point in the NFT contract. This optional parameter will default to restricting access to the installer of the contract. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"holdermode"})," - The ",(0,t.jsx)(n.code,{children:"NFTHolderMode"})," modality dictates which entities can hold NFTs. This optional parameter will default to a mixed mode, allowing either ",(0,t.jsx)(n.code,{children:"Accounts"})," or ",(0,t.jsx)(n.code,{children:"Contracts"})," to hold NFTs. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"burnMode"})," - The ",(0,t.jsx)(n.code,{children:"BurnMode"})," modality dictates whether minted NFTs can be burned. This optional parameter will allow tokens to be burnt by default. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"ownerReverseLookupMode"})," - The ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," dictates whether the contract will index ownership of tokens as outlined ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/reverse-lookup#the-cep-78-page-system",children:"here"})," to allow lookup of owned tokens by account. ",(0,t.jsx)(n.strong,{children:"This parameter cannot be changed once the contract has been installed"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Further information on CEP-78 modality options can be found ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/modalities",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"minting-a-token",children:"Minting a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The CEP-78 JS Client includes code to construct a deploy that will ",(0,t.jsx)(n.code,{children:"Mint"})," a token, as follows:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const mintDeploy = cc.mint(\n {\n owner: FAUCET_KEYS.publicKey,\n meta: {\n color: "Blue",\n size: "Medium",\n material: "Aluminum",\n condition: "Used",\n },\n },\n { useSessionCode: true },\n "2000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const mintDeployHash = await mintDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The arguments adhere to those provided in the original installation, with the ",(0,t.jsx)(n.code,{children:".send()"})," pointing to a valid RPC URL on your target Casper network. In this instance, we are using an NCTL RPC URL."]}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L86-L88",children:(0,t.jsx)(n.code,{children:"useSessionCode"})})," variable decides if the user will call ",(0,t.jsx)(n.code,{children:"mint"})," using session code, or not. It will be set to ",(0,t.jsx)(n.code,{children:"true"})," if the ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"Complete"}),". ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/client-js/examples/usage.ts#L116-L130",children:"It then registers the recipient with the contract"})," and mints the token."]}),"\n",(0,t.jsxs)(n.p,{children:["If ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"})," is set to ",(0,t.jsx)(n.code,{children:"NoLookup"}),", ",(0,t.jsx)(n.code,{children:"useSessionCode"})," will be set to ",(0,t.jsx)(n.code,{children:"false"})," and it will simply mint the token as it does not need to register the recipient."]}),"\n",(0,t.jsx)(n.h2,{id:"register-recipient",children:"Register Recipient"}),"\n",(0,t.jsxs)(n.p,{children:["As we used ",(0,t.jsx)(n.code,{children:"ownerReverseLookupMode: OwnerReverseLookupMode.Complete"})," in this contract installation, we must register the recipient. To do this, we construct a ",(0,t.jsx)(n.code,{children:"register"})," deploy:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const registerDeploy = cc.register(\n {\n tokenOwner: USER1_KEYS.publicKey,\n },\n "1000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const registerDeployHash = await registerDeploy.send("http://localhost:11101/rpc");\n \n'})}),"\n",(0,t.jsx)(n.h2,{id:"transferring-a-token",children:"Transferring a Token"}),"\n",(0,t.jsx)(n.p,{children:"After minting one or more tokens, you can then use the following code to transfer the tokens between accounts:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const transferDeploy = cc.transfer(\n {\n tokenId: "0",\n source: FAUCET_KEYS.publicKey,\n target: USER1_KEYS.publicKey,\n },\n { useSessionCode: true },\n "13000000000",\n FAUCET_KEYS.publicKey,\n [FAUCET_KEYS]\n );\n\n const transferDeployHash = await transferDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.p,{children:"Transferring accepts the following arguments:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"tokenId"})," - The sequential ID assigned to a token in mint order."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"source"})," - The account sending the token in question."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"target"})," - The account receiving the transferred token."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["As above, the ",(0,t.jsx)(n.code,{children:"useSessionCode"})," variable determines if the user will call ",(0,t.jsx)(n.code,{children:"transfer"})," using session code based on the setting of ",(0,t.jsx)(n.code,{children:"OwnerReverseLookupMode"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"burning-a-token",children:"Burning a Token"}),"\n",(0,t.jsxs)(n.p,{children:["The following code shows how to burn a minted NFT that you hold and have access rights to, requiring only the ",(0,t.jsx)(n.code,{children:"tokenId"})," argument:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:'\n const burnDeploy = await contractClient.burn(\n { tokenId: "0" },\n "13000000000",\n USER1_KEYS.publicKey,\n [USER1_KEYS]\n );\n\n const burnDeployHash = await burnDeploy.send("http://localhost:11101/rpc");\n\n'})}),"\n",(0,t.jsx)(n.h2,{id:"example-usages",children:"Example Usages"}),"\n",(0,t.jsx)(n.h3,{id:"running-an-install-example",children:"Running an Install Example"}),"\n",(0,t.jsx)(n.p,{children:"This repository includes an example script for installing a CEP-78 contract instance."}),"\n",(0,t.jsxs)(n.p,{children:["You will need to define the following variables in the ",(0,t.jsx)(n.code,{children:".env"})," file:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NODE_URL"})," - The address of a node. If you are testing using ",(0,t.jsx)(n.a,{href:"/developers/dapps/setup-nctl",children:"NCTL"}),", this will be ",(0,t.jsx)(n.code,{children:"http://localhost:11101/rpc"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"NETWORK_NAME"})," - The name of the Casper network you are operating on, ",(0,t.jsx)(n.code,{children:"casper-net-1"})," when testing using a local network with NCTL."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"MASTER_KEY_PAIR_PATH"})," - The path to the key pair of the minting account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"USER1_KEY_PAIR_PATH"})," - The path to an additional account's key pair for use in testing transfer features."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You may also need to install associated dependencies using:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm i\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:install\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The example will then return the installation's ",(0,t.jsx)(n.code,{children:"deployHash"}),", and inform you when the installation is successful."]}),"\n",(0,t.jsx)(n.p,{children:"The example will then provide the installing account's information, which will include the CEP-78 NFT contract's hash and package hash."}),"\n",(0,t.jsx)(n.h3,{id:"running-a-usage-example",children:"Running a Usage Example"}),"\n",(0,t.jsx)(n.p,{children:"A usage example uses the same variables as the Install example above, but tests the basic functionality of the contract after installation."}),"\n",(0,t.jsx)(n.p,{children:"The usage example can be run using the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-js",children:"npm run example:usage\n"})}),"\n",(0,t.jsx)(n.p,{children:"This example will acquire the contract's hash and package hash, prior to sending three separate deploys to perform several function tests as follows:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Mint"})," - The example will attempt to mint an NFT using the installation account."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Transfer"})," - The example will transfer the previously minted NFT to a second account (USER1 as defined in the variables.)"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"Burn"})," - The example will burn the minted NFT."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The associated code for these deploys may be found in the ",(0,t.jsx)(n.code,{children:"client-js/examples"})," directory."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>l});var t=s(96540);const i={},a=t.createContext(i);function r(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:r(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d81ba6be.98f8f400.js b/assets/js/d81ba6be.98f8f400.js new file mode 100644 index 000000000..83e5425c7 --- /dev/null +++ b/assets/js/d81ba6be.98f8f400.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[41156],{61813:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>o,toc:()=>l});var c=n(74848),t=n(28453);const r={},a="A",o={id:"concepts/glossary/A",title:"A",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/A.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/A",permalink:"/2.0.0/concepts/glossary/A",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Glossary",permalink:"/2.0.0/glossary"},next:{title:"B",permalink:"/2.0.0/concepts/glossary/B"}},i={},l=[{value:"Account",id:"account",level:2},{value:"Account Hash",id:"account-hash",level:2},{value:"Addressable Entity",id:"addressable-entity",level:2},{value:"AssemblyScript",id:"assemblyscript",level:2},{value:"Auction",id:"auction",level:2},{value:"Auction contract",id:"auction-contract",level:2},{value:"Auction delay",id:"auction-delay",level:2}];function h(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"a",children:"A"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"account",children:"Account"}),"\n",(0,c.jsxs)(s.p,{children:["An Account is a structure that represents a user on a Casper network. Information on creating an account can be found ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/design/casper-design#accounts-head",children:"here"}),". Casper's Condor release introduces the concept of an ",(0,c.jsx)(s.a,{href:"#addressable-entity",children:"addressable entity"}),", which contains an account entity type that supersedes legacy accounts."]}),"\n",(0,c.jsx)(s.h2,{id:"account-hash",children:"Account Hash"}),"\n",(0,c.jsxs)(s.p,{children:["The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found ",(0,c.jsx)(s.a,{href:"https://support.casperlabs.io/hc/en-gb/articles/13781616975131-How-do-I-generate-an-account-hash-",children:"here"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"addressable-entity",children:"Addressable Entity"}),"\n",(0,c.jsxs)(s.p,{children:["An addressable entity is a post-2.0 type that merges the concept of an ",(0,c.jsx)(s.code,{children:"Account"})," and a ",(0,c.jsx)(s.code,{children:"Contract"}),", bringing in features from both. More information can be found ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/addressable-entity",children:"here"}),"."]}),"\n",(0,c.jsx)(s.h2,{id:"assemblyscript",children:"AssemblyScript"}),"\n",(0,c.jsxs)(s.p,{children:["AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using ",(0,c.jsx)(s.em,{children:"asc"}),", the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community."]}),"\n",(0,c.jsx)(s.h2,{id:"auction",children:"Auction"}),"\n",(0,c.jsx)(s.p,{children:'The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.'}),"\n",(0,c.jsx)(s.h2,{id:"auction-contract",children:"Auction contract"}),"\n",(0,c.jsx)(s.p,{children:"The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction."}),"\n",(0,c.jsx)(s.h2,{id:"auction-delay",children:"Auction delay"}),"\n",(0,c.jsxs)(s.p,{children:["The number of full eras that pass between the ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B#booking-block",children:"booking block"})," and the era whose validator set it defines. The auction delay is configurable and can be several eras long."]})]})}function d(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(h,{...e})}):h(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>a,x:()=>o});var c=n(96540);const t={},r=c.createContext(t);function a(e){const s=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function o(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:a(e.components),c.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d8ae3676.ed256976.js b/assets/js/d8ae3676.ed256976.js new file mode 100644 index 000000000..743090912 --- /dev/null +++ b/assets/js/d8ae3676.ed256976.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74541],{45316:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>a});var t=s(74848),i=s(28453);const r={title:"Design Overview",slug:"/design"},c=void 0,d={id:"concepts/design/index",title:"Design Overview",description:"| Topic | Description |",source:"@site/versioned_docs/version-2.0.0/concepts/design/index.md",sourceDirName:"concepts/design",slug:"/design",permalink:"/2.0.0/design",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Design Overview",slug:"/design"},sidebar:"concepts",previous:{title:"What is Casper?",permalink:"/2.0.0/concepts/about"},next:{title:"Network Design",permalink:"/2.0.0/concepts/design/casper-design"}},o={},a=[];function l(e){const n={a:"a",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,i.R)(),...e.components};return(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design",children:"Network Design"})}),(0,t.jsx)(n.td,{children:"Overview of execution semantics, account permissions, URefs, block structure, tokens, and more"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/p2p",children:"Network Communication"})}),(0,t.jsx)(n.td,{children:"Peer-to-peer communication for Casper nodes"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/consensus",children:"Consensus in Casper"})}),(0,t.jsx)(n.td,{children:"Introduction to Consensus in a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/zug",children:"Zug Consensus"})}),(0,t.jsx)(n.td,{children:"An overview of the Zug consensus used in Mainnet and Testnet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/highway",children:"Highway Consensus"})}),(0,t.jsx)(n.td,{children:"Brief overview of the Highway consensus available as an alternative to Zug"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/rewards",children:"Validator Rewards"})}),(0,t.jsx)(n.td,{children:"Overview of how rewards are calculated and distributed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain",children:"Reading and Writing Data to Global State"})}),(0,t.jsx)(n.td,{children:"Storing and reading data from the blockchain"})]})]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d8c709f8.5f79bc8f.js b/assets/js/d8c709f8.5f79bc8f.js new file mode 100644 index 000000000..fb9fde641 --- /dev/null +++ b/assets/js/d8c709f8.5f79bc8f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65610],{50890:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>d});var c=t(74848),a=t(28453);const s={title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},r="Exploring the CEP-18 Contracts",o={id:"resources/tokens/cep18/query",title:"CEP-18 Contract Details",description:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:",source:"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/query.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/query",permalink:"/2.0.0/resources/tokens/cep18/query",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"CEP-18 Contract Details",slug:"/resources/tokens/cep18/query"},sidebar:"resources",previous:{title:"On-chain Installation",permalink:"/2.0.0/resources/tokens/cep18/quickstart-guide"},next:{title:"CEP-18 Transfers",permalink:"/2.0.0/resources/tokens/cep18/transfer"}},i={},d=[{value:"Querying the Contract Package",id:"querying-the-contract-package",level:2},{value:"Querying the Utility Contract",id:"querying-the-utility-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function l(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"exploring-the-cep-18-contracts",children:"Exploring the CEP-18 Contracts"})}),"\n",(0,c.jsx)(n.p,{children:"This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsx)(n.p,{children:"The Casper fungible token contract"}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:["The CEP-18 utility contract, which should appear in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the account that sent the transaction as ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-contract-package",children:"Querying the Contract Package"}),"\n",(0,c.jsxs)(n.p,{children:["We will need the contract package's ",(0,c.jsx)(n.code,{children:"contract_hash"})," to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", under the name given during the installation process."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing transaction.\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n// This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["This will return the ",(0,c.jsx)(n.code,{children:"Contract Package"})," object:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1489823435760214673,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-8dac847ce0ae20f0156cf37dd233cc1d166fde8269fc9a393b0ea04174be1167-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n'})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["Note - In the ",(0,c.jsx)(n.code,{children:"contract_hash"})," field, the hash value represents the stored contract which we will invoke later."]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"querying-the-utility-contract",children:"Querying the Utility Contract"}),"\n",(0,c.jsxs)(n.p,{children:["In addition, there is a utility contract that invokes the various balance and allowance entry points of the main fungible token contract. Upon receiving the returned value, the utility contract will write the value to a URef called ",(0,c.jsx)(n.code,{children:"result"}),". You can find this URef in the ",(0,c.jsx)(n.code,{children:"NamedKeys"})," of the utility contract."]}),"\n",(0,c.jsxs)(n.p,{children:["First, you will need to query the ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," hash found within the installing account's ",(0,c.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n// This is the contract hash for the `cep18_test_contract` as found from the installing account's `NamedKeys`\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:(0,c.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6 \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:"Which should return information similar to the following:"}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5359405942597097786,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[2048 hex chars]",\n "stored_value": {\n "ContractPackage": {\n "access_key": "uref-1b867a3751f505762c69c8d92ba7462818cd0c2a705bb5d4270bce479410ee55-007",\n "disabled_versions": [],\n "groups": [],\n "versions": [\n {\n "contract_hash": "contract-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca",\n "contract_version": 1,\n "protocol_version_major": 1\n }\n ]\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsxs)(n.p,{children:["You will need to take the ",(0,c.jsx)(n.code,{children:"contract_hash"})," value and replace ",(0,c.jsx)(n.code,{children:"contract"})," with ",(0,c.jsx)(n.code,{children:"hash"})," to run another `query-global-state:"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<HOST IP>:<PORT> \\\n--key hash-a8fe057675930f0951d45816c55615228ac8af2b7b231788278dffcf1dd8c0ca \\\n--state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933\n"})}),"\n",(0,c.jsxs)(n.p,{children:["Which will return the full ",(0,c.jsx)(n.code,{children:"cep18_test_contract"})," information. The following snippet is condensed to show only the ",(0,c.jsx)(n.code,{children:"NamedKeys"}),", but you should also see the ",(0,c.jsx)(n.code,{children:"entry_points"})," when you run the command. You should see the URef ",(0,c.jsx)(n.code,{children:"result"}),", which will be used to view the results of any checks run through the utility contract."]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:'{\n "id": -1426549275795832481,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3370 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-015b99020edb40e7e1e2b31a8e104bc226242f960a2d10dc1d91ae3eb6fa41b6",\n "contract_wasm_hash": "contract-wasm-7959083a4df983ddcd3a9ae46af092dbf126031181ab2619ddc64db09bde8c27",\n "named_keys": [\n {\n "key": "uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007",\n "name": "result"\n }\n ],\n "protocol_version": "1.0.0"\n }\n }\n }\n}\n\n'})}),"\n",(0,c.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsx)(n.li,{children:(0,c.jsx)(n.a,{href:"/2.0.0/resources/tokens/cep18/transfer",children:"CEP-18 Token Transfers and Allowances"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(l,{...e})}):l(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var c=t(96540);const a={},s=c.createContext(a);function r(e){const n=c.useContext(s);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),c.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d92b4d08.2f4390d9.js b/assets/js/d92b4d08.2f4390d9.js deleted file mode 100644 index 4a62ee590..000000000 --- a/assets/js/d92b4d08.2f4390d9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3422],{66395:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const c={title:"Multi-Sig Workflow"},d="Multi-Signature Workflow",r={id:"resources/advanced/multi-sig/multi-sig-workflow",title:"Multi-Sig Workflow",description:"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.",source:"@site/docs/resources/advanced/multi-sig/multi-sig-workflow.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/multi-sig-workflow",permalink:"/next/resources/advanced/multi-sig/multi-sig-workflow",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Multi-Sig Workflow"},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/next/resources/advanced/multi-sig/"},next:{title:"Additional Examples",permalink:"/next/resources/advanced/multi-sig/other-scenarios"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Session Code Required for Key Management",id:"session-code-required-for-key-management",level:2},{value:"Tutorial Workflow",id:"tutorial-workflow",level:2},{value:"Step 1: Clone the example Wasm for this workflow",id:"step-1-clone-the-example-wasm-for-this-workflow",level:3},{value:"Step 2: Build the sample Wasm provided",id:"step-2-build-the-sample-wasm-provided",level:3},{value:"Step 3: Increase the primary key's weight to set thresholds",id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",level:3},{value:"Step 4: Update the account's action thresholds",id:"step-4-update-the-accounts-action-thresholds",level:3},{value:"Step 5: Add associated keys to the primary account",id:"step-5-add-associated-keys-to-the-primary-account",level:3},{value:"Step 6: Send a deploy from the primary account",id:"step-6-send-a-deploy-from-the-primary-account",level:3},{value:"Step 7: Send a multi-signature deploy from an associated key",id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",level:3},{value:"Removing a Compromised Key",id:"removing-a-compromised-key",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"multi-signature-workflow",children:"Multi-Signature Workflow"})}),"\n",(0,t.jsxs)(n.p,{children:["The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," tutorial, among other prerequisites. You will also need the Casper CLI client to use the ",(0,t.jsx)(n.code,{children:"make-deploy"}),", ",(0,t.jsx)(n.code,{children:"sign-deploy"}),", and ",(0,t.jsx)(n.code,{children:"send-deploy"})," Casper CLI client commands."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"The following prerequisites are required for this workflow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites",children:"development environment prerequisites"}),", including a ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#setting-up-an-account",children:"funded account"})," and the ",(0,t.jsx)(n.a,{href:"/next/developers/prerequisites#install-casper-client",children:"Casper CLI client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Complete the ",(0,t.jsx)(n.a,{href:"/next/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow and set up the source account for multi-signature deploys"]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the Casper ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"account-based model"})," before proceeding"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"session-code-required-for-key-management",children:"Session Code Required for Key Management"}),"\n",(0,t.jsx)(n.p,{children:"To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Do not run these examples on Mainnet. Update each command for your environment."})}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-workflow",children:"Tutorial Workflow"}),"\n",(0,t.jsx)(n.h3,{id:"step-1-clone-the-example-wasm-for-this-workflow",children:"Step 1: Clone the example Wasm for this workflow"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"multi-sig GitHub repository"})," contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you take a look at the repository structure and open the ",(0,t.jsx)(n.code,{children:"contracts"})," folder, you will see session code with different functionality:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_account.wasm"})," - adds an associated account with a specified weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"})," - updates a key\u2019s weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," - updates the account's action thresholds for deployment and account management"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"remove_account.wasm"})," - removes an associated account from the primary account"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-2-build-the-sample-wasm-provided",children:"Step 2: Build the sample Wasm provided"}),"\n",(0,t.jsx)(n.p,{children:"Prepare your environment, build and test the session code provided with the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\nmake prepare\nmake test\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rustup update"})," - checks and updates your Rust installation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make prepare"})," - sets the Wasm target"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make test"})," - builds and verifies the session code"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that in the test folder there is a ",(0,t.jsx)(n.code,{children:"contract.wasm"})," that is needed for the tests to pass. If you run ",(0,t.jsx)(n.code,{children:"make clean"})," that file will be deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",children:"Step 3: Increase the primary key's weight to set thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.code,{children:"key_management"})," threshold. In a later step, you will add the associated accounts that will participate in signing deploys."]}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update the weight of the primary key to 3 by calling the ",(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-<ACCOUNT_HASH>\'" \\\n--session-arg "new_weight:u8=\'3\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The primary key in this account should now have weight 3."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-update-the-accounts-action-thresholds",children:"Step 4: Update the account's action thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["Set up a multi-signature scheme for the account by updating the ",(0,t.jsx)(n.code,{children:"deployment"})," and ",(0,t.jsx)(n.code,{children:"key_management"})," thresholds. The ",(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," will take two arguments and set the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to 2 and the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold to 3."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The account's action thresholds should look like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n'})}),"\n",(0,t.jsx)(n.p,{children:"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-add-associated-keys-to-the-primary-account",children:"Step 5: Add associated keys to the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["To add an associated key to the primary account, use the ",(0,t.jsx)(n.code,{children:"add_account.wasm"})," provided. This example adds two keys to the primary account (",(0,t.jsx)(n.code,{children:"account-hash-d89c*"}),"): ",(0,t.jsx)(n.code,{children:"user_1"})," with ",(0,t.jsx)(n.code,{children:"account-hash-e2d0*"}),", and ",(0,t.jsx)(n.code,{children:"user_2"})," with ",(0,t.jsx)(n.code,{children:"account-hash-04a9*"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."}),"\n",(0,t.jsx)(n.li,{children:"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."}),"\n"]})}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-6-send-a-deploy-from-the-primary-account",children:"Step 6: Send a deploy from the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["This step sends a deploy containing Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"hello-world"})," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h3,{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",children:"Step 7: Send a multi-signature deploy from an associated key"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-deploy"})," - creates and signs a deploy, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-deploy"})," - adds additional signatures for a multi-signature deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-deploy"})," - sends the deploy to the network"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to step 6, this example uses Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument. The deploy needs two signatures to meet the ",(0,t.jsx)(n.code,{children:"deployment"})," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."]}),"\n",(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."]}),"\n",(0,t.jsxs)(n.p,{children:["One associated key creates and signs the deploy with the ",(0,t.jsx)(n.code,{children:"make-deploy"})," command, indicating the account context under which the session code will be executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The second associated key signs the deploy with ",(0,t.jsx)(n.code,{children:"sign-deploy"})," to meet the deployment threshold for the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The deploy can be sent to the network using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.h2,{id:"removing-a-compromised-key",children:"Removing a Compromised Key"}),"\n",(0,t.jsxs)(n.p,{children:["This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," session code."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Remove keys with caution! Do not run this example on Mainnet."}),(0,t.jsx)(n.p,{children:"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution."})]}),"\n",(0,t.jsx)(n.p,{children:"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"add_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The resulting account should not contain the associated key that was just removed."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"N/A (Removed)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.p,{children:["The next section contains ",(0,t.jsx)(n.a,{href:"/next/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," where Casper's multi-signature feature would be helpful."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(96540);const a={},c=t.createContext(a);function d(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d92b4d08.d98a3927.js b/assets/js/d92b4d08.d98a3927.js new file mode 100644 index 000000000..8eaef6fb9 --- /dev/null +++ b/assets/js/d92b4d08.d98a3927.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[93422],{66395:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const c={title:"Multi-Sig Workflow"},d="Multi-Signature Workflow",r={id:"resources/advanced/multi-sig/multi-sig-workflow",title:"Multi-Sig Workflow",description:"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.",source:"@site/docs/resources/advanced/multi-sig/multi-sig-workflow.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/multi-sig-workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Multi-Sig Workflow"},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/resources/advanced/multi-sig/"},next:{title:"Additional Examples",permalink:"/resources/advanced/multi-sig/other-scenarios"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Session Code Required for Key Management",id:"session-code-required-for-key-management",level:2},{value:"Tutorial Workflow",id:"tutorial-workflow",level:2},{value:"Step 1: Clone the example Wasm for this workflow",id:"step-1-clone-the-example-wasm-for-this-workflow",level:3},{value:"Step 2: Build the sample Wasm provided",id:"step-2-build-the-sample-wasm-provided",level:3},{value:"Step 3: Increase the primary key's weight to set thresholds",id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",level:3},{value:"Step 4: Update the account's action thresholds",id:"step-4-update-the-accounts-action-thresholds",level:3},{value:"Step 5: Add associated keys to the primary account",id:"step-5-add-associated-keys-to-the-primary-account",level:3},{value:"Step 6: Send a deploy from the primary account",id:"step-6-send-a-deploy-from-the-primary-account",level:3},{value:"Step 7: Send a multi-signature deploy from an associated key",id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",level:3},{value:"Removing a Compromised Key",id:"removing-a-compromised-key",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"multi-signature-workflow",children:"Multi-Signature Workflow"})}),"\n",(0,t.jsxs)(n.p,{children:["The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," tutorial, among other prerequisites. You will also need the Casper CLI client to use the ",(0,t.jsx)(n.code,{children:"make-deploy"}),", ",(0,t.jsx)(n.code,{children:"sign-deploy"}),", and ",(0,t.jsx)(n.code,{children:"send-deploy"})," Casper CLI client commands."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"The following prerequisites are required for this workflow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"development environment prerequisites"}),", including a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"funded account"})," and the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper CLI client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Complete the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow and set up the source account for multi-signature deploys"]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the Casper ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"account-based model"})," before proceeding"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"session-code-required-for-key-management",children:"Session Code Required for Key Management"}),"\n",(0,t.jsx)(n.p,{children:"To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Do not run these examples on Mainnet. Update each command for your environment."})}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-workflow",children:"Tutorial Workflow"}),"\n",(0,t.jsx)(n.h3,{id:"step-1-clone-the-example-wasm-for-this-workflow",children:"Step 1: Clone the example Wasm for this workflow"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"multi-sig GitHub repository"})," contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you take a look at the repository structure and open the ",(0,t.jsx)(n.code,{children:"contracts"})," folder, you will see session code with different functionality:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_account.wasm"})," - adds an associated account with a specified weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"})," - updates a key\u2019s weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," - updates the account's action thresholds for deployment and account management"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"remove_account.wasm"})," - removes an associated account from the primary account"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-2-build-the-sample-wasm-provided",children:"Step 2: Build the sample Wasm provided"}),"\n",(0,t.jsx)(n.p,{children:"Prepare your environment, build and test the session code provided with the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\nmake prepare\nmake test\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rustup update"})," - checks and updates your Rust installation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make prepare"})," - sets the Wasm target"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make test"})," - builds and verifies the session code"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that in the test folder there is a ",(0,t.jsx)(n.code,{children:"contract.wasm"})," that is needed for the tests to pass. If you run ",(0,t.jsx)(n.code,{children:"make clean"})," that file will be deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",children:"Step 3: Increase the primary key's weight to set thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.code,{children:"key_management"})," threshold. In a later step, you will add the associated accounts that will participate in signing deploys."]}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update the weight of the primary key to 3 by calling the ",(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-<ACCOUNT_HASH>\'" \\\n--session-arg "new_weight:u8=\'3\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The primary key in this account should now have weight 3."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-update-the-accounts-action-thresholds",children:"Step 4: Update the account's action thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["Set up a multi-signature scheme for the account by updating the ",(0,t.jsx)(n.code,{children:"deployment"})," and ",(0,t.jsx)(n.code,{children:"key_management"})," thresholds. The ",(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," will take two arguments and set the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to 2 and the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold to 3."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The account's action thresholds should look like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n'})}),"\n",(0,t.jsx)(n.p,{children:"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-add-associated-keys-to-the-primary-account",children:"Step 5: Add associated keys to the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["To add an associated key to the primary account, use the ",(0,t.jsx)(n.code,{children:"add_account.wasm"})," provided. This example adds two keys to the primary account (",(0,t.jsx)(n.code,{children:"account-hash-d89c*"}),"): ",(0,t.jsx)(n.code,{children:"user_1"})," with ",(0,t.jsx)(n.code,{children:"account-hash-e2d0*"}),", and ",(0,t.jsx)(n.code,{children:"user_2"})," with ",(0,t.jsx)(n.code,{children:"account-hash-04a9*"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."}),"\n",(0,t.jsx)(n.li,{children:"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."}),"\n"]})}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-6-send-a-deploy-from-the-primary-account",children:"Step 6: Send a deploy from the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["This step sends a deploy containing Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"hello-world"})," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h3,{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",children:"Step 7: Send a multi-signature deploy from an associated key"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-deploy"})," - creates and signs a deploy, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-deploy"})," - adds additional signatures for a multi-signature deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-deploy"})," - sends the deploy to the network"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to step 6, this example uses Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument. The deploy needs two signatures to meet the ",(0,t.jsx)(n.code,{children:"deployment"})," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."]}),"\n",(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."]}),"\n",(0,t.jsxs)(n.p,{children:["One associated key creates and signs the deploy with the ",(0,t.jsx)(n.code,{children:"make-deploy"})," command, indicating the account context under which the session code will be executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The second associated key signs the deploy with ",(0,t.jsx)(n.code,{children:"sign-deploy"})," to meet the deployment threshold for the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The deploy can be sent to the network using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.h2,{id:"removing-a-compromised-key",children:"Removing a Compromised Key"}),"\n",(0,t.jsxs)(n.p,{children:["This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," session code."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Remove keys with caution! Do not run this example on Mainnet."}),(0,t.jsx)(n.p,{children:"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution."})]}),"\n",(0,t.jsx)(n.p,{children:"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"add_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The resulting account should not contain the associated key that was just removed."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"N/A (Removed)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.p,{children:["The next section contains ",(0,t.jsx)(n.a,{href:"/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," where Casper's multi-signature feature would be helpful."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(96540);const a={},c=t.createContext(a);function d(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d94d6bbe.5f51f6b7.js b/assets/js/d94d6bbe.5f51f6b7.js new file mode 100644 index 000000000..81c028eac --- /dev/null +++ b/assets/js/d94d6bbe.5f51f6b7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[49065],{78715:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var n=s(74848),o=s(28453);const r={title:"Fast Sync"},a="Introducing Fast Sync",i={id:"operators/setup/fast-sync",title:"Fast Sync",description:"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.",source:"@site/versioned_docs/version-1.5.X/operators/setup/fast-sync.md",sourceDirName:"operators/setup",slug:"/operators/setup/fast-sync",permalink:"/1.5.X/operators/setup/fast-sync",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Fast Sync"},sidebar:"operators",previous:{title:"Installation",permalink:"/1.5.X/operators/setup/install-node"},next:{title:"Open Files Limit",permalink:"/1.5.X/operators/setup/open-files"}},c={},l=[{value:"How Fast Sync Works",id:"how-fast-sync-works",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"introducing-fast-sync",children:"Introducing Fast Sync"})}),"\n",(0,n.jsx)(t.p,{children:"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."}),"\n",(0,n.jsxs)(t.p,{children:["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 ",(0,n.jsx)(t.a,{href:"/1.5.X/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"trusted hash"})," 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."]}),"\n",(0,n.jsx)(t.h2,{id:"how-fast-sync-works",children:"How Fast Sync Works"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:s(32688).A+"",width:"661",height:"81"})}),"\n",(0,n.jsxs)(t.p,{children:["For fast sync, operators must provide the trusted hash of a block in the ",(0,n.jsx)(t.code,{children:"config.toml"})," file. An example can be found ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},32688:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/fast-sync-process-b20a3732a0c1a20e1ff682568f6a8390.png"},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>i});var n=s(96540);const o={},r=n.createContext(o);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d94d6bbe.f9bfb75e.js b/assets/js/d94d6bbe.f9bfb75e.js deleted file mode 100644 index 9e4cd3b4d..000000000 --- a/assets/js/d94d6bbe.f9bfb75e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9065],{78715:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>i,toc:()=>l});var n=s(74848),o=s(28453);const r={title:"Fast Sync"},a="Introducing Fast Sync",i={id:"operators/setup/fast-sync",title:"Fast Sync",description:"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.",source:"@site/versioned_docs/version-1.5.X/operators/setup/fast-sync.md",sourceDirName:"operators/setup",slug:"/operators/setup/fast-sync",permalink:"/operators/setup/fast-sync",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Fast Sync"},sidebar:"operators",previous:{title:"Installation",permalink:"/operators/setup/install-node"},next:{title:"Open Files Limit",permalink:"/operators/setup/open-files"}},c={},l=[{value:"How Fast Sync Works",id:"how-fast-sync-works",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"introducing-fast-sync",children:"Introducing Fast Sync"})}),"\n",(0,n.jsx)(t.p,{children:"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."}),"\n",(0,n.jsxs)(t.p,{children:["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 ",(0,n.jsx)(t.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"trusted hash"})," 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."]}),"\n",(0,n.jsx)(t.h2,{id:"how-fast-sync-works",children:"How Fast Sync Works"}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{src:s(41582).A+"",width:"661",height:"81"})}),"\n",(0,n.jsxs)(t.p,{children:["For fast sync, operators must provide the trusted hash of a block in the ",(0,n.jsx)(t.code,{children:"config.toml"})," file. An example can be found ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/casper-node/blob/f7d8228de3cb56a3fe705f5a787d3dbf03ff7998/resources/production/config-example.toml#L7",children:"here"}),"."]}),"\n",(0,n.jsx)(t.p,{children:"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."})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},41582:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/fast-sync-process-b20a3732a0c1a20e1ff682568f6a8390.png"},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>i});var n=s(96540);const o={},r=n.createContext(o);function a(e){const t=n.useContext(r);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/db24aef0.5b7d27fc.js b/assets/js/db24aef0.5b7d27fc.js deleted file mode 100644 index 83b07af5b..000000000 --- a/assets/js/db24aef0.5b7d27fc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2799],{71383:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>a});var r=s(74848),o=s(28453);const t={title:"Non-Root Users"},i="Setting up a Non-Root User",c={id:"operators/setup/non-root-user",title:"Non-Root Users",description:"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.",source:"@site/docs/operators/setup/non-root-user.md",sourceDirName:"operators/setup",slug:"/operators/setup/non-root-user",permalink:"/next/operators/setup/non-root-user",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Non-Root Users"},sidebar:"operators",previous:{title:"Join a Network",permalink:"/next/operators/setup/joining"},next:{title:"Node Events",permalink:"/next/operators/setup/node-events"}},d={},a=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-non-root-user",children:"Setting up a Non-Root User"})}),"\n",(0,r.jsxs)(n.p,{children:["Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace ",(0,r.jsx)(n.code,{children:"<username>"})," in the instructions below with your username."]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.a,{href:"https://www.ssh.com/academy/ssh/keygen",children:"ssh-keygen"})," to generate a new SSH key."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Create the user with no password, as the key is your password."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo adduser <username> --disabled-password\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"3",children:["\n",(0,r.jsx)(n.li,{children:"Create authorized_keys with your key to log in."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo su - <username>\nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"4",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Use the editor of your choice and paste your .ssh public key i the ",(0,r.jsx)(n.code,{children:".ssh/authorized_keys"})," file."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Exit out of the ",(0,r.jsx)(n.code,{children:"<username>"})," account and log into the root or previous sudo-er account."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"exit\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"6",children:["\n",(0,r.jsx)(n.li,{children:"Add your user to sudo-ers under the root account or your previous sudo-er account."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo visudo\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"7",children:["\n",(0,r.jsxs)(n.li,{children:["Type ",(0,r.jsx)(n.code,{children:"<username> ALL=(ALL:ALL) NOPASSWD:ALL"})," below the row containing ",(0,r.jsx)(n.code,{children:"root ALL=(ALL:ALL) ALL"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n<username> ALL=(ALL:ALL) NOPASSWD:ALL\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"8",children:["\n",(0,r.jsx)(n.li,{children:"You should be able to log in with the key and not use the root user."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh -i <your ssh private key> <username>@<server ip>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Here is an example command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var r=s(96540);const o={},t=r.createContext(o);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/db24aef0.7be66191.js b/assets/js/db24aef0.7be66191.js new file mode 100644 index 000000000..3bab065d1 --- /dev/null +++ b/assets/js/db24aef0.7be66191.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[92799],{71383:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>i,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>a});var r=s(74848),o=s(28453);const t={title:"Non-Root Users"},i="Setting up a Non-Root User",c={id:"operators/setup/non-root-user",title:"Non-Root Users",description:"Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace `` in the instructions below with your username.",source:"@site/docs/operators/setup/non-root-user.md",sourceDirName:"operators/setup",slug:"/operators/setup/non-root-user",permalink:"/operators/setup/non-root-user",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Non-Root Users"},sidebar:"operators",previous:{title:"Join a Network",permalink:"/operators/setup/joining"},next:{title:"Node Events",permalink:"/operators/setup/node-events"}},d={},a=[];function l(e){const n={a:"a",code:"code",h1:"h1",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-non-root-user",children:"Setting up a Non-Root User"})}),"\n",(0,r.jsxs)(n.p,{children:["Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace ",(0,r.jsx)(n.code,{children:"<username>"})," in the instructions below with your username."]}),"\n",(0,r.jsxs)(n.ol,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Use ",(0,r.jsx)(n.a,{href:"https://www.ssh.com/academy/ssh/keygen",children:"ssh-keygen"})," to generate a new SSH key."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsx)(n.p,{children:"Create the user with no password, as the key is your password."}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo adduser <username> --disabled-password\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"3",children:["\n",(0,r.jsx)(n.li,{children:"Create authorized_keys with your key to log in."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo su - <username>\nmkdir .ssh\nchmod 700 .ssh\ntouch .ssh/authorized_keys\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"4",children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Use the editor of your choice and paste your .ssh public key i the ",(0,r.jsx)(n.code,{children:".ssh/authorized_keys"})," file."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:["Exit out of the ",(0,r.jsx)(n.code,{children:"<username>"})," account and log into the root or previous sudo-er account."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"exit\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"6",children:["\n",(0,r.jsx)(n.li,{children:"Add your user to sudo-ers under the root account or your previous sudo-er account."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"sudo visudo\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"7",children:["\n",(0,r.jsxs)(n.li,{children:["Type ",(0,r.jsx)(n.code,{children:"<username> ALL=(ALL:ALL) NOPASSWD:ALL"})," below the row containing ",(0,r.jsx)(n.code,{children:"root ALL=(ALL:ALL) ALL"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"# User privilege specification\nroot ALL=(ALL:ALL) ALL\n<username> ALL=(ALL:ALL) NOPASSWD:ALL\n"})}),"\n",(0,r.jsxs)(n.ol,{start:"8",children:["\n",(0,r.jsx)(n.li,{children:"You should be able to log in with the key and not use the root user."}),"\n"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh -i <your ssh private key> <username>@<server ip>\n"})}),"\n",(0,r.jsx)(n.p,{children:"Here is an example command:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"ssh -i ~/.ssh/id_rsa casper@10.21.10.200\n"})})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>c});var r=s(96540);const o={},t=r.createContext(o);function i(e){const n=r.useContext(t);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),r.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dbfc4782.400f41c7.js b/assets/js/dbfc4782.400f41c7.js new file mode 100644 index 000000000..b150dc565 --- /dev/null +++ b/assets/js/dbfc4782.400f41c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[38749],{91895:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"condor-validator-rewards","metadata":{"permalink":"/blog/condor-validator-rewards","source":"@site/blog/2024-08-20-validator-rewards.md","title":"validator rewards in Casper 2.0","description":"A discussion of validator rewards under Casper 2.0","date":"2024-08-20T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":false,"label":"Validators","permalink":"/blog/tags/validators","description":"Validators"}],"readingTime":6.96,"hasTruncateMarker":true,"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"},{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov"}],"frontMatter":{"title":"validator rewards in Casper 2.0","description":"A discussion of validator rewards under Casper 2.0","slug":"condor-validator-rewards","date":"2024-08-20T18:00","authors":["melpadden","alexanderlimonov"],"tags":["condor","validators"],"hide_table_of_contents":false},"unlisted":false,"nextItem":{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux"}},"content":"In this post we discuss the changes to validator rewards in Casper v2.0.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Economics of consensus\\n\\nProof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally. \\n\\nProof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress.\\n\\nIncentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain.\\n\\n## Casper 1.X Highway-specific incentives\\n\\nThe 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round. \\n\\nDegrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others. \\n\\nThe weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality. \\n\\n## Casper 2.0 \\n\\n### Public knowledge of finality\\n\\nA necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators.\\n\\nThis mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators\' knowledge of the canonical history be attested publicly.\\n\\nIn Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one\'s own and other validators\' finality signatures.\\n\\n### Design\\n\\nRewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities\\n\\n* Block proposal\\n* Signature creation\\n* Signature publication\\n\\nNote that we expect very little, if any, rewards to be allocated for block proposals on mainnet, but the feature remains available.\\n\\nThe rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era\'s end multiplied by an inflation factor derived from the chainspec. \\"Nominal\\" here means that all rounds result in a finalized block and that all finality signatures are collected and published.\\n\\nThe rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication.\\n\\nNote that this split ensures that validators\' incentives are aligned, in the sense that other validators\' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators\' signature, and because each validator benefits from other publishing its own signatures.\\n\\n#### Expected rewards & volatility\\n\\nUnder nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable.\\n\\nIn the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility.\\n\\n#### Rewards formula\\n\\nThe rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section.\\n\\nLet us define some notation first\\n\\n**N** - expected number of blocks in an era\\n\\n**N*** - the *set* of observed blocks in an era\\n\\n**R** - total potential reward pot for the era (i.e., nominal inflation based on chainspec and current supply)\\n\\n**r** - fraction of reward pot dedicated to block production rewards\\n\\n**f** - finder\'s fee for finality signatures\\n\\n**I** - validator index set\\n\\n**i**: **N*** -> {0,1} - indicator function for blocks produced by validator i (with abuse of notation)\\n\\n**w**: **I** -> [0,1] - validator\'s weight\\n\\n**W** - total weight of the validator set\\n\\n**S**: **N*** -> **P(I)** - set of validators associated with finality signatures for a particular observed block\\n\\n**s_i**: **N*** -> {0,1} - indicator functions for existence of finality signatures associated with validator i for particular observed blocks\\n\\nNow, we can use our defined symbols to concisely describe era rewards for a particular validator\\n\\nEra rewards for validator i = \\n\\n**\u03a3** (n in **N***) **i(n)** * (**rR/N**) (block production)\\n\\n+ **\u03a3** (n in **N***) **i(n)** * **\u03a3** (j in **S(n)**) (**w(j)/W**) * (**f(1-r)R/N**) (finality signature publication) \\n\\n+ **\u03a3** (n in **N***) **s_i(n)** * (**w(i)/W**) * (**(1-f)(1-r)R/N**) (finality signature contribution)\\n\\nThe meanings of the three additive components in the formula above are, in order\\n\\n* Sum over blocks, discarding blocks not proposed by this validator\\n * For each block, add the per-block reward allocation for block proposals from the total pot for the era\\n* Sum over blocks, discarding blocks not proposed by this validator\\n * For each block, sum over published signatures\\n * For each signature, add the per-block reward allocation for signature publication from the total pot for the era, weighing each signature by its creator\'s proportion of total validator weight\\n* Sum over blocks, discarding those for which this validator did not create a signature\\n * For each block, add the per-block reward allocation for signature creation from the total pot for the era, weighing it by the validator\'s proportion of total validator weight\\n\\n#### Notes on implementation\\n\\nIn a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block.\\n\\nWe solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards. \\n\\nHowever, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created.\\n\\n### Impact on validator revenue\\n\\nNo impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile."},{"id":"welcome-docs-redux","metadata":{"permalink":"/blog/welcome-docs-redux","source":"@site/blog/2024-08-15-hello-blogworld.md","title":"Casper Docs Redux!","description":"The first blog post using the new Docs portal.","date":"2024-08-15T18:00:00.000Z","tags":[{"inline":true,"label":"hello","permalink":"/blog/tags/hello"},{"inline":true,"label":"new docs","permalink":"/blog/tags/new-docs"},{"inline":true,"label":"docs-redux","permalink":"/blog/tags/docs-redux"}],"readingTime":0.595,"hasTruncateMarker":true,"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Casper Docs Redux!","description":"The first blog post using the new Docs portal.","slug":"welcome-docs-redux","date":"2024-08-15T18:00","authors":["melpadden"],"tags":["hello","new docs","docs-redux"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"validator rewards in Casper 2.0","permalink":"/blog/condor-validator-rewards"},"nextItem":{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity"}},"content":"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.\\n\\nPlease enjoy and if you have any comments, suggestions or errata, please email [devrel@casper.network](mailto:devrel@casper.network) with your contribution or query.\\n\\n\x3c!-- truncate --\x3e"},{"id":"addressable-entity","metadata":{"permalink":"/blog/addressable-entity","source":"@site/blog/2024-07-17-addressable-entity.md","title":"Addressable Entity in Casper 2.0","description":"An introduction to the Addressable Entity concept.","date":"2024-07-17T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"}],"readingTime":3.665,"hasTruncateMarker":true,"authors":[{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor"},{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Addressable Entity in Casper 2.0","description":"An introduction to the Addressable Entity concept.","slug":"addressable-entity","date":"2024-07-17T18:00","authors":["sczembor","melpadden"],"tags":["condor"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux"},"nextItem":{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination"}},"content":"Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the `AddressableEntity` type. This new structure replaces the separate `AccountHash` and `ContractHash` used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.\\n\\nIn this article, we\'ll dive into the details of `AddressableEntity`, exploring its structure and functionalities.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Key Concepts\\n\\n**AddressableEntity**\\n\\nAt its core, an `AddressableEntity` is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An `AddressableEntity` provides a unified interface for various operations, including authorization, access control, and execution of functions.\\n\\n**EntityAddr**\\n\\nAn `EntityAddr` serves as the address for an `AddressableEntity`. It not only encodes the unique identifier (hash) of the entity but also its type. There are three distinct variants of `EntityAddr`:\\n\\n1. **System:** Used for built-in, native contracts crucial for the blockchain\'s operation.\\n2. **Account:** Represents a user\'s account.\\n3. **SmartContract:** Represents a user-deployed smart contract.\\n\\n**AddressableEntityHash**\\n\\nThe `AddressableEntityHash` is a newtype wrapper around a 32-byte hash (`HashAddr`). This hash functions as a unique identifier for the `AddressableEntity`, typically derived from either the account\'s public key or the smart contract\'s hash using hashing algorithm.\\n\\n## The inner workings of AddressableEntity\\n\\nLet\'s dive into the critical components within an `AddressableEntity`:\\n\\n* **`protocol_version` (ProtocolVersion):** This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves.\\n* **`entity_kind` (EntityKind):** As mentioned earlier, this enum determines the type of entity \u2013 System, Account, or SmartContract.\\n* **`associated_keys` (AssociatedKeys):** This data structure stores a map of public keys authorized to interact with the entity. Each key is associated with a weight that represents its voting power in decision-making processes within the entity.\\n* **`action_thresholds` (ActionThresholds):** These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are `deployment`, `key_management`, and `upgrade_management`. Each action type has its own weight threshold, allowing for fine-grained control over permissions.\\n* **`entry_points` (EntryPoints):** This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions.\\n\\n## Obtaining and converting Keys\\n\\nIn Casper 2.0, developers will primarily work with `Key::AddressableEntity` when referring to accounts and smart contracts. Here\'s how you can create them and convert between different key formats:\\n\\n### Creating AddressableEntity Keys\\n\\n**From Account Hash:**\\n\\n```rust\\nlet addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); \\n```\\n\\n**From Smart Contract Hash:**\\n\\n```rust\\nlet addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));\\n```\\n\\n### Extracting AccountHash or ContractHash from a Key\\nYou can extract the `AccountHash` or `ContractHash` from a `Key::AddressableEntity` using pattern matching:\\n\\n```rust\\n//For Accounts\\nlet account_hash = match addressable_entity_key {\\n Key::AddressableEntity(EntityAddr::Account(hash)) => hash,\\n _ => panic!(\\"Not an account key\\"), \\n};\\n//For Contracts\\nlet contract_hash = match addressable_entity_key {\\n Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,\\n _ => panic!(\\"Not a contract key\\"), \\n};\\n```\\n\\n## The Address Merge in Condor\\n\\nThe \\"Address Merge\\" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with. \\n\\n**Global State Transformation:**\\n\\nPost-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the `AddressableEntity` structure. This means the network itself will recognize and handle these entities using the new format.\\n\\n**Smart Contract Compatibility Considerations:**\\n\\nWhile the global state automatically transitions to `AddressableEntity`, existing contracts are expected to function without any modification. \\n\\n* **Caller Identification:**\\nExisting host functions used to identify the caller within your contract will continue to work as before, ensuring no disruption to your contract\'s functionality. However, new host functions have been introduced that are specifically designed to work with the AddressableEntity format.\\n\\n* **External Contract Interaction:** Other contracts may have updated their interfaces to accept AddressableEntity arguments. Its worth to verify the argument types to avoid potential errors.\\n\\n> **Note**\\n> * Upgrading a contract to a newer version may involve complexities, such as changes to the contract\'s addressable hash. These changes might require coordination with centralized and decentralized exchanges, as well as communication with your community to ensure a smooth transition."},{"id":"condor-fee-elimination","metadata":{"permalink":"/blog/condor-fee-elimination","source":"@site/blog/2024-07-16-fee-elimination.md","title":"Fee Elimination in Condor","description":"A discussion of the Fee Elimination feature in Casper 2.0","date":"2024-07-16T22:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":true,"label":"features","permalink":"/blog/tags/features"},{"inline":true,"label":"tokenomics","permalink":"/blog/tags/tokenomics"}],"readingTime":8.84,"hasTruncateMarker":true,"authors":[{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland"},{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Fee Elimination in Condor","description":"A discussion of the Fee Elimination feature in Casper 2.0","slug":"condor-fee-elimination","date":"2024-07-16T22:00","authors":["dylanireland","melpadden"],"tags":["condor","features","tokenomics"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity"},"nextItem":{"title":"Setting Up a Local Casper Condor Network for Development","permalink":"/blog/condor-local-setup"}},"content":"The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as **Fee Elimination** for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Concepts\\nPublic distributed blockchain networks that support smart contracts generally employ a concept known as \\"[gas](https://docs.casper.network/concepts/glossary/G/#gas)\\", which can be thought of as \\"the ability to do work on-chain\\". The problem addressed by this mechanism is that **any finite resource on a publicly accessible computer network must be rate-limited**, because a resource made available without limit is a denial of service attack vector. \\n\\nGas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor\'s available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses.\\n\\n## Payment, Gas Price, Fees\\nOn Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the [proposer](#proposer) of that block in the form of transaction [fees](#fees). The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:\\n\\n* **Gas Limit**: An amount of gas, specified by the transactor, at which to cancel a transaction.\\n* **Gas Price**: The network gas price; the ratio between the cost of 1 unit of gas and 1 mote.\\n* **Gas Cost**: The amount of gas needed to pay for execution of a transaction.\\n* **Payment**: The amount of token specified by the transactor to pay for the execution of a transaction.\\n* **Refund**: All or a portion of the remaining token after gas is purchased for execution.\\n\\n> \\n> The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article.\\n\\n## Fee Elimination\\n\\n> __Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances__.\\n\\nUnder 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated **Gas Cost** for a configurable period of time known as the **Hold Period**. Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions.\\n\\n### Holds\\n\\nA hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse. \\n\\n### Hold Release\\n\\nThe Casper Node 2.0 software currently supports two hold release models: **Accrued** and **Amortized**. \\n\\n> \\n> The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options.\\n\\n#### Accrued\\n100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor.\\n\\n#### Amortized\\nThe effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold *amount* is proportional to the percentage of the hold *duration* that remains before expiry. \\n\\nFor example, if:\\n- A hold of 180 CSPR is placed on an purse which holds 1000 CSPR\\n- The configured hold period is 90 days\\n- The hold release model is configured to use amortization\\n\\nThen, 9 days after the hold was placed, the current effective amount of the hold may be calculated by \\n - $\\\\frac{\\\\text{Hold Duration} - \\\\text{Time Elapsed}}{\\\\text{Hold Duration}} = \\\\frac{90 - 9}{90} = 0.9$\\n - Multiplied by the hold amount: $180 \\\\times 0.9 = 162$\\n\\nThe effective balance in that purse, at that point in time, is $1000 - 162 = 838 \\\\ \\\\text{CSPR}$\\n\\nOver the course of the hold\'s duration, this calculation gives us:\\n| Hold Amount | Hold Period | Time Elapsed | Effective Hold |\\n| --- | --- | --- | --- |\\n| 180 | 90 | 1 | 178 |\\n| 180 | 90 | 9 | 162 |\\n| 180 | 90 | 45 | 90 |\\n| 180 | 90 | 89 | 2 |\\n\\n### More about Gas holds \\nThe duration of gas holds is defined [here](https://github.com/casper-network/casper-node/blob/feat-2.0/resources/production/chainspec.toml#L166) in the [casper-node](https://github.com/casper-network/casper-node) chainspec:\\n\\n```toml\\n# If fee_handling is set to \'no_fee\', the system places a balance hold on the payer\\n# equal to the value the fee would have been. Such balance holds expire after a time\\n# interval has elapsed. This setting controls how long that interval is. The available\\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\\n#\\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\\n# a hold for 100 is placed on that purse and is considered when calculating total balance\\n# for 24 hours starting from the block_time when the hold was placed.\\ngas_hold_interval = \'24 hours\'\\n```\\n\\n\\n### Preventing Exploitation\\nThe ultimate goal of any gas mechanism is to prevent exploitation of a network\'s resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely.\\n\\nHowever, any gas mechanism that doesn\'t charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances. \\n\\nAttacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper\'s approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly.\\n\\nConsidering a token locking period of 30 days and the **Accrued** unlocking schedule, purchasing just 1% of the total block space of each block would cost:\\n\\n$\\\\frac{T}{B} \\\\cdot \\\\frac{G}{100} = 5,346,000 \\\\, \\\\text{CSPR}$\\n\\nWhere:\\n\\n* `T` = 30 day locking period\\n* `B` = 16 second blocktime\\n* `G` = 3300 CSPR block gas limit\\n\\nIf this proves to be too cheap, the locking period can be extended or the block gas limit increased.\\n\\n#### Opportunity Cost\\nIn addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high. \\n\\n### Incentivizing Validators\\n\\nThe Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators.\\n\\nCasper\'s solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current \\"[era](https://docs.casper.network/concepts/glossary/E/#era)\\", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a \\"validator credit\\" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next [booking block](https://docs.casper.network/concepts/glossary/B/#booking-block) appears.\\n\\n## Looking Forward\\n\\nBy introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols.\\n\\nAs the model is rolled out to Casper\'s mainnet and testnet, economists and engineers will study its effects on Casper\'s transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented.\\n\\n---\\n### Further Reading/Terms\\n\\n#### Proposer\\nA validator proposing a block to the network for execution \\n[Consensus](https://docs.casper.network/concepts/economics/consensus/) \\n[Validator](https://docs.casper.network/concepts/glossary/V/#validator)\\n\\n#### Fees\\nA portion of a transaction\'s gas costs given over to the proposer of the block containing that transaction. \\n[Gas Concepts](https://docs.casper.network/concepts/economics/gas-concepts/) \\n[Runtime Economics](https://docs.casper.network/runtime/) \\n[Validator Rewards](https://docs.casper.network/concepts/glossary/R/#reward)"},{"id":"condor-local-setup","metadata":{"permalink":"/blog/condor-local-setup","source":"@site/blog/2024-07-16-setting-up-condor-local.md","title":"Setting Up a Local Casper Condor Network for Development","description":"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.","date":"2024-07-16T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":false,"label":"Set-up","permalink":"/blog/tags/setup","description":"Getting set up on Casper"}],"readingTime":4.08,"hasTruncateMarker":true,"authors":[{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor"}],"frontMatter":{"title":"Setting Up a Local Casper Condor Network for Development","description":"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.","slug":"condor-local-setup","date":"2024-07-16T18:00","authors":["sczembor"],"tags":["condor","setup"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination"}},"content":"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Prerequisites\\n\\n* Docker installed and running on your machine \\n\\n## Part 1: The Dockerized NCTL (Network Control Tool)\\n\\nNCTL is your tool for managing the Casper network. We\'ll use a Dockerized version for easier setup.\\n\\n1. **Clone the Repository:**\\n ```bash\\n git clone https://github.com/make-software/casper-nctl-docker.git\\n cd casper-nctl-docker\\n ```\\n\\n2. **Switch to the Condor Branch:**\\n ```bash\\n git checkout feat-2.0\\n ```\\n\\n3. **Clone the `casper-node` Repository:**\\n ```bash\\n git clone https://github.com/casper-network/casper-node.git\\n cd casper-node\\n git checkout release-2.0.0-rc3\\n ```\\n Ensure you\'re in the `casper-nctl-docker` directory when running this command\\n\\n4. **Build the Docker Image:**\\n ```bash\\n docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .\\n ```\\n This may take a while\\n\\n5. **Verify the Image:**\\n ```bash\\n docker image ls\\n ```\\n Look for the `casper-nctl:rc3` image in the output\\n ```\\n REPOSITORY TAG IMAGE ID CREATED SIZE\\n casper-nctl rc3 9fd1e7b25d42 40 hours ago 433MB\\n ```\\n\\n6. **Start the NCTL Docker Container:**\\n * **Docker Compose (Recommended):** If you\'re using the `docker-compose.yml` file, make sure that the `image` under the `mynctl` service points to `casper-nctl:rc3`. Then run `docker-compose up`.\\n * **Manual Docker Command:** \\n ```bash\\n docker run -d --name mynctl -p 11101:11101 casper-nctl:rc3\\n ```\\n\\n Once it is up and running you should see that there are 5 nodes and 5 sidecars running and another 5 nodes and 5 sidecars that are inactive:\\n ```\\n casper-nctl | validators-1:casper-net-1-node-1 RUNNING pid 996, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-node-2 RUNNING pid 998, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-node-3 RUNNING pid 1002, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-1 RUNNING pid 997, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-2 RUNNING pid 1000, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-3 RUNNING pid 1011, uptime 0:00:03\\n casper-nctl | validators-2:casper-net-1-node-4 RUNNING pid 1082, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-node-5 RUNNING pid 1084, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-sidecar-4 RUNNING pid 1083, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-sidecar-5 RUNNING pid 1085, uptime 0:00:02\\n casper-nctl | validators-3:casper-net-1-node-10 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-6 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-7 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-8 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-9 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-10 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-6 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-7 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-8 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-9 STOPPED Not started\\n ```\\n\\n\\n## Part 2: Casper Client (Rust)\\n\\nTo interact with your local Condor network, we\'ll use the Casper Client. You have two options for using the Casper Client:\\n\\n**Option 1: Using the Casper Client from the Docker Image**\\n\\n* The `casper-nctl:rc3` Docker image already includes the `casper-client`.\\n* You can skip the next two steps if you want to use the pre-installed client.\\n\\n**Option 2: Using Your Local Casper Client**\\n\\n1. **Clone the Repository (Optional):**\\n ```bash\\n git clone https://github.com/casper-ecosystem/casper-client-rs.git\\n cd casper-client-rs\\n ```\\n\\n2. **Switch to the Condor-Compatible Branch (Optional):**\\n ```bash\\n git checkout feat-track-node-2.0\\n ```\\n\\n3. **Activate NCTL scripts:**\\n ```bash\\n source nctl-activate.sh casper-nctl\\n ```\\n\\n4 **Test Your Setup:**\\n ```bash\\n nctl-view-node-status\\n ```\\n This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:\\n ```\\n ------------------------------------------------------------------------------------------------------------------------------------\\n 2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:\\n {\\n \\"api_version\\": \\"2.0.0\\",\\n \\"peers\\": [\\n {\\n \\"node_id\\": \\"tls:05b5..7b39\\",\\n \\"address\\": \\"127.0.0.1:22103\\"\\n },\\n {\\n \\"node_id\\": \\"tls:527e..37d2\\",\\n \\"address\\": \\"127.0.0.1:22105\\"\\n },\\n {\\n \\"node_id\\": \\"tls:b1d0..870f\\",\\n \\"address\\": \\"127.0.0.1:22102\\"\\n },\\n {\\n \\"node_id\\": \\"tls:dcdf..e348\\",\\n \\"address\\": \\"127.0.0.1:22104\\"\\n }\\n ],\\n \\"build_version\\": \\"2.0.0-d5c0d238f\\",\\n \\"chainspec_name\\": \\"casper-net-1\\",\\n \\"starting_state_root_hash\\": \\"2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80\\",\\n \\"last_added_block_info\\": {\\n \\"hash\\": \\"c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395\\",\\n \\"timestamp\\": \\"2024-07-10T15:31:38.601Z\\",\\n \\"era_id\\": 19,\\n \\"height\\": 205,\\n \\"state_root_hash\\": \\"6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612\\",\\n \\"creator\\": \\"0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab\\"\\n },\\n \\"our_public_signing_key\\": \\"01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b\\",\\n \\"round_length\\": \\"4s 96ms\\",\\n \\"next_upgrade\\": null,\\n \\"uptime\\": \\"13m 15s\\",\\n \\"reactor_state\\": \\"Validate\\",\\n \\"last_progress\\": \\"2024-07-10T15:18:26.354Z\\",\\n \\"available_block_range\\": {\\n \\"low\\": 0,\\n \\"high\\": 205\\n },\\n \\"block_sync\\": {\\n \\"historical\\": null,\\n \\"forward\\": null\\n },\\n \\"latest_switch_block_hash\\": \\"5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68\\"\\n }\\n .\\n .\\n .\\n ```\\n\\n## Troubleshooting\\n\\n**If sidecars or nodes are not running:** If you see `null` values under each node in the output of `nctl-view-node-status`, it means the version of `casper-sidecar` is not compatible with the `casper-node`.\\n\\n**Solution:**\\n1. Go to the `casper-node/ci/ci.json` file.\\n2. Change the `casper-sidecar` branch under `external_deps` from:\\n ```json\\n \\"branch\\": \\"feat-2.0\\"\\n ``` \\n to:\\n ```json\\n \\"branch\\": \\"release-1.0.0rc2_node-2.0.0rc3\\" \\n ```\\n\\n This is because the `casper-node` we are using is `release-2.0.0-rc3`. The required combination of versions of `casper-sidecar` and `casper-node` may change in the future (rc4 etc.).\\n\\n3. Rebuild the NCTL image: `docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .`\\n\\n## Using the Casper Client\\n\\n* **Command Format(Using local casper-client):** `cargo run --release [command] --node-address http://127.0.0.1:11101`\\n* **Command Format(Using casper-client from the docker image):** `casper-client [command] --node-address http://127.0.0.1:11101`\\n\\n## Accessing the NCTL Block Web Explorer\\n\\nThe NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:\\n\\n```\\nhttp://127.0.0.1:8080\\n```\\n\\nThis allows you to visually explore blocks, transactions, and other details of your local network.\\n\\n## Important Notes\\n\\n* **Work in Progress:** Condor compatibility is still evolving. Some features may be unstable or incomplete.\\n\\n## Additional Tips\\n\\n* **Community Resources:** Join the [Casper Telegram](https://t.me/CSPRCondor) for help and discussion."}]}}')}}]); \ No newline at end of file diff --git a/assets/js/dbfc4782.468a1d4c.js b/assets/js/dbfc4782.468a1d4c.js deleted file mode 100644 index b753bd651..000000000 --- a/assets/js/dbfc4782.468a1d4c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8749],{91895:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"condor-validator-rewards","metadata":{"permalink":"/blog/condor-validator-rewards","source":"@site/blog/2024-08-20-validator-rewards.md","title":"validator rewards in Casper 2.0","description":"A discussion of validator rewards under Casper 2.0","date":"2024-08-20T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":true,"label":"validators","permalink":"/blog/tags/validators"}],"readingTime":6.96,"hasTruncateMarker":true,"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"},{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov"}],"frontMatter":{"title":"validator rewards in Casper 2.0","description":"A discussion of validator rewards under Casper 2.0","slug":"condor-validator-rewards","date":"2024-08-20T18:00","authors":["melpadden","alexanderlimonov"],"tags":["condor","validators"],"hide_table_of_contents":false},"unlisted":false,"nextItem":{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux"}},"content":"In this post we discuss the changes to validator rewards in Casper v2.0.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Economics of consensus\\n\\nProof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally. \\n\\nProof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress.\\n\\nIncentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain.\\n\\n## Casper 1.X Highway-specific incentives\\n\\nThe 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round. \\n\\nDegrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others. \\n\\nThe weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality. \\n\\n## Casper 2.0 \\n\\n### Public knowledge of finality\\n\\nA necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators.\\n\\nThis mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators\' knowledge of the canonical history be attested publicly.\\n\\nIn Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one\'s own and other validators\' finality signatures.\\n\\n### Design\\n\\nRewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities\\n\\n* Block proposal\\n* Signature creation\\n* Signature publication\\n\\nNote that we expect very little, if any, rewards to be allocated for block proposals on mainnet, but the feature remains available.\\n\\nThe rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era\'s end multiplied by an inflation factor derived from the chainspec. \\"Nominal\\" here means that all rounds result in a finalized block and that all finality signatures are collected and published.\\n\\nThe rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication.\\n\\nNote that this split ensures that validators\' incentives are aligned, in the sense that other validators\' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators\' signature, and because each validator benefits from other publishing its own signatures.\\n\\n#### Expected rewards & volatility\\n\\nUnder nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable.\\n\\nIn the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility.\\n\\n#### Rewards formula\\n\\nThe rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section.\\n\\nLet us define some notation first\\n\\n**N** - expected number of blocks in an era\\n\\n**N*** - the *set* of observed blocks in an era\\n\\n**R** - total potential reward pot for the era (i.e., nominal inflation based on chainspec and current supply)\\n\\n**r** - fraction of reward pot dedicated to block production rewards\\n\\n**f** - finder\'s fee for finality signatures\\n\\n**I** - validator index set\\n\\n**i**: **N*** -> {0,1} - indicator function for blocks produced by validator i (with abuse of notation)\\n\\n**w**: **I** -> [0,1] - validator\'s weight\\n\\n**W** - total weight of the validator set\\n\\n**S**: **N*** -> **P(I)** - set of validators associated with finality signatures for a particular observed block\\n\\n**s_i**: **N*** -> {0,1} - indicator functions for existence of finality signatures associated with validator i for particular observed blocks\\n\\nNow, we can use our defined symbols to concisely describe era rewards for a particular validator\\n\\nEra rewards for validator i = \\n\\n**\u03a3** (n in **N***) **i(n)** * (**rR/N**) (block production)\\n\\n+ **\u03a3** (n in **N***) **i(n)** * **\u03a3** (j in **S(n)**) (**w(j)/W**) * (**f(1-r)R/N**) (finality signature publication) \\n\\n+ **\u03a3** (n in **N***) **s_i(n)** * (**w(i)/W**) * (**(1-f)(1-r)R/N**) (finality signature contribution)\\n\\nThe meanings of the three additive components in the formula above are, in order\\n\\n* Sum over blocks, discarding blocks not proposed by this validator\\n * For each block, add the per-block reward allocation for block proposals from the total pot for the era\\n* Sum over blocks, discarding blocks not proposed by this validator\\n * For each block, sum over published signatures\\n * For each signature, add the per-block reward allocation for signature publication from the total pot for the era, weighing each signature by its creator\'s proportion of total validator weight\\n* Sum over blocks, discarding those for which this validator did not create a signature\\n * For each block, add the per-block reward allocation for signature creation from the total pot for the era, weighing it by the validator\'s proportion of total validator weight\\n\\n#### Notes on implementation\\n\\nIn a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block.\\n\\nWe solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards. \\n\\nHowever, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created.\\n\\n### Impact on validator revenue\\n\\nNo impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile."},{"id":"welcome-docs-redux","metadata":{"permalink":"/blog/welcome-docs-redux","source":"@site/blog/2024-08-15-hello-blogworld.md","title":"Casper Docs Redux!","description":"The first blog post using the new Docs portal.","date":"2024-08-15T18:00:00.000Z","tags":[{"inline":true,"label":"hello","permalink":"/blog/tags/hello"},{"inline":true,"label":"new docs","permalink":"/blog/tags/new-docs"},{"inline":true,"label":"docs-redux","permalink":"/blog/tags/docs-redux"}],"readingTime":0.595,"hasTruncateMarker":true,"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Casper Docs Redux!","description":"The first blog post using the new Docs portal.","slug":"welcome-docs-redux","date":"2024-08-15T18:00","authors":["melpadden"],"tags":["hello","new docs","docs-redux"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"validator rewards in Casper 2.0","permalink":"/blog/condor-validator-rewards"},"nextItem":{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity"}},"content":"Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.\\n\\nPlease enjoy and if you have any comments, suggestions or errata, please email [devrel@casper.network](mailto:devrel@casper.network) with your contribution or query.\\n\\n\x3c!-- truncate --\x3e"},{"id":"addressable-entity","metadata":{"permalink":"/blog/addressable-entity","source":"@site/blog/2024-07-17-addressable-entity.md","title":"Addressable Entity in Casper 2.0","description":"An introduction to the Addressable Entity concept.","date":"2024-07-17T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"}],"readingTime":3.665,"hasTruncateMarker":true,"authors":[{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor"},{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Addressable Entity in Casper 2.0","description":"An introduction to the Addressable Entity concept.","slug":"addressable-entity","date":"2024-07-17T18:00","authors":["sczembor","melpadden"],"tags":["condor"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Casper Docs Redux!","permalink":"/blog/welcome-docs-redux"},"nextItem":{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination"}},"content":"Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the `AddressableEntity` type. This new structure replaces the separate `AccountHash` and `ContractHash` used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.\\n\\nIn this article, we\'ll dive into the details of `AddressableEntity`, exploring its structure and functionalities.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Key Concepts\\n\\n**AddressableEntity**\\n\\nAt its core, an `AddressableEntity` is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An `AddressableEntity` provides a unified interface for various operations, including authorization, access control, and execution of functions.\\n\\n**EntityAddr**\\n\\nAn `EntityAddr` serves as the address for an `AddressableEntity`. It not only encodes the unique identifier (hash) of the entity but also its type. There are three distinct variants of `EntityAddr`:\\n\\n1. **System:** Used for built-in, native contracts crucial for the blockchain\'s operation.\\n2. **Account:** Represents a user\'s account.\\n3. **SmartContract:** Represents a user-deployed smart contract.\\n\\n**AddressableEntityHash**\\n\\nThe `AddressableEntityHash` is a newtype wrapper around a 32-byte hash (`HashAddr`). This hash functions as a unique identifier for the `AddressableEntity`, typically derived from either the account\'s public key or the smart contract\'s hash using hashing algorithm.\\n\\n## The inner workings of AddressableEntity\\n\\nLet\'s dive into the critical components within an `AddressableEntity`:\\n\\n* **`protocol_version` (ProtocolVersion):** This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves.\\n* **`entity_kind` (EntityKind):** As mentioned earlier, this enum determines the type of entity \u2013 System, Account, or SmartContract.\\n* **`associated_keys` (AssociatedKeys):** This data structure stores a map of public keys authorized to interact with the entity. Each key is associated with a weight that represents its voting power in decision-making processes within the entity.\\n* **`action_thresholds` (ActionThresholds):** These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are `deployment`, `key_management`, and `upgrade_management`. Each action type has its own weight threshold, allowing for fine-grained control over permissions.\\n* **`entry_points` (EntryPoints):** This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions.\\n\\n## Obtaining and converting Keys\\n\\nIn Casper 2.0, developers will primarily work with `Key::AddressableEntity` when referring to accounts and smart contracts. Here\'s how you can create them and convert between different key formats:\\n\\n### Creating AddressableEntity Keys\\n\\n**From Account Hash:**\\n\\n```rust\\nlet addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); \\n```\\n\\n**From Smart Contract Hash:**\\n\\n```rust\\nlet addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));\\n```\\n\\n### Extracting AccountHash or ContractHash from a Key\\nYou can extract the `AccountHash` or `ContractHash` from a `Key::AddressableEntity` using pattern matching:\\n\\n```rust\\n//For Accounts\\nlet account_hash = match addressable_entity_key {\\n Key::AddressableEntity(EntityAddr::Account(hash)) => hash,\\n _ => panic!(\\"Not an account key\\"), \\n};\\n//For Contracts\\nlet contract_hash = match addressable_entity_key {\\n Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,\\n _ => panic!(\\"Not a contract key\\"), \\n};\\n```\\n\\n## The Address Merge in Condor\\n\\nThe \\"Address Merge\\" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with. \\n\\n**Global State Transformation:**\\n\\nPost-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the `AddressableEntity` structure. This means the network itself will recognize and handle these entities using the new format.\\n\\n**Smart Contract Compatibility Considerations:**\\n\\nWhile the global state automatically transitions to `AddressableEntity`, existing contracts are expected to function without any modification. \\n\\n* **Caller Identification:**\\nExisting host functions used to identify the caller within your contract will continue to work as before, ensuring no disruption to your contract\'s functionality. However, new host functions have been introduced that are specifically designed to work with the AddressableEntity format.\\n\\n* **External Contract Interaction:** Other contracts may have updated their interfaces to accept AddressableEntity arguments. Its worth to verify the argument types to avoid potential errors.\\n\\n> **Note**\\n> * Upgrading a contract to a newer version may involve complexities, such as changes to the contract\'s addressable hash. These changes might require coordination with centralized and decentralized exchanges, as well as communication with your community to ensure a smooth transition."},{"id":"condor-fee-elimination","metadata":{"permalink":"/blog/condor-fee-elimination","source":"@site/blog/2024-07-16-fee-elimination.md","title":"Fee Elimination in Condor","description":"A discussion of the Fee Elimination feature in Casper 2.0","date":"2024-07-16T22:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":true,"label":"features","permalink":"/blog/tags/features"},{"inline":true,"label":"tokenomics","permalink":"/blog/tags/tokenomics"}],"readingTime":8.84,"hasTruncateMarker":true,"authors":[{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland"},{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden"}],"frontMatter":{"title":"Fee Elimination in Condor","description":"A discussion of the Fee Elimination feature in Casper 2.0","slug":"condor-fee-elimination","date":"2024-07-16T22:00","authors":["dylanireland","melpadden"],"tags":["condor","features","tokenomics"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Addressable Entity in Casper 2.0","permalink":"/blog/addressable-entity"},"nextItem":{"title":"Setting Up a Local Casper Condor Network for Development","permalink":"/blog/condor-local-setup"}},"content":"The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as **Fee Elimination** for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Concepts\\nPublic distributed blockchain networks that support smart contracts generally employ a concept known as \\"[gas](https://docs.casper.network/concepts/glossary/G/#gas)\\", which can be thought of as \\"the ability to do work on-chain\\". The problem addressed by this mechanism is that **any finite resource on a publicly accessible computer network must be rate-limited**, because a resource made available without limit is a denial of service attack vector. \\n\\nGas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor\'s available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses.\\n\\n## Payment, Gas Price, Fees\\nOn Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the [proposer](#proposer) of that block in the form of transaction [fees](#fees). The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:\\n\\n* **Gas Limit**: An amount of gas, specified by the transactor, at which to cancel a transaction.\\n* **Gas Price**: The network gas price; the ratio between the cost of 1 unit of gas and 1 mote.\\n* **Gas Cost**: The amount of gas needed to pay for execution of a transaction.\\n* **Payment**: The amount of token specified by the transactor to pay for the execution of a transaction.\\n* **Refund**: All or a portion of the remaining token after gas is purchased for execution.\\n\\n> \\n> The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article.\\n\\n## Fee Elimination\\n\\n> __Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances__.\\n\\nUnder 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated **Gas Cost** for a configurable period of time known as the **Hold Period**. Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions.\\n\\n### Holds\\n\\nA hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse. \\n\\n### Hold Release\\n\\nThe Casper Node 2.0 software currently supports two hold release models: **Accrued** and **Amortized**. \\n\\n> \\n> The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options.\\n\\n#### Accrued\\n100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor.\\n\\n#### Amortized\\nThe effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold *amount* is proportional to the percentage of the hold *duration* that remains before expiry. \\n\\nFor example, if:\\n- A hold of 180 CSPR is placed on an purse which holds 1000 CSPR\\n- The configured hold period is 90 days\\n- The hold release model is configured to use amortization\\n\\nThen, 9 days after the hold was placed, the current effective amount of the hold may be calculated by \\n - $\\\\frac{\\\\text{Hold Duration} - \\\\text{Time Elapsed}}{\\\\text{Hold Duration}} = \\\\frac{90 - 9}{90} = 0.9$\\n - Multiplied by the hold amount: $180 \\\\times 0.9 = 162$\\n\\nThe effective balance in that purse, at that point in time, is $1000 - 162 = 838 \\\\ \\\\text{CSPR}$\\n\\nOver the course of the hold\'s duration, this calculation gives us:\\n| Hold Amount | Hold Period | Time Elapsed | Effective Hold |\\n| --- | --- | --- | --- |\\n| 180 | 90 | 1 | 178 |\\n| 180 | 90 | 9 | 162 |\\n| 180 | 90 | 45 | 90 |\\n| 180 | 90 | 89 | 2 |\\n\\n### More about Gas holds \\nThe duration of gas holds is defined [here](https://github.com/casper-network/casper-node/blob/feat-2.0/resources/production/chainspec.toml#L166) in the [casper-node](https://github.com/casper-network/casper-node) chainspec:\\n\\n```toml\\n# If fee_handling is set to \'no_fee\', the system places a balance hold on the payer\\n# equal to the value the fee would have been. Such balance holds expire after a time\\n# interval has elapsed. This setting controls how long that interval is. The available\\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\\n#\\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\\n# a hold for 100 is placed on that purse and is considered when calculating total balance\\n# for 24 hours starting from the block_time when the hold was placed.\\ngas_hold_interval = \'24 hours\'\\n```\\n\\n\\n### Preventing Exploitation\\nThe ultimate goal of any gas mechanism is to prevent exploitation of a network\'s resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely.\\n\\nHowever, any gas mechanism that doesn\'t charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances. \\n\\nAttacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper\'s approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly.\\n\\nConsidering a token locking period of 30 days and the **Accrued** unlocking schedule, purchasing just 1% of the total block space of each block would cost:\\n\\n$\\\\frac{T}{B} \\\\cdot \\\\frac{G}{100} = 5,346,000 \\\\, \\\\text{CSPR}$\\n\\nWhere:\\n\\n* `T` = 30 day locking period\\n* `B` = 16 second blocktime\\n* `G` = 3300 CSPR block gas limit\\n\\nIf this proves to be too cheap, the locking period can be extended or the block gas limit increased.\\n\\n#### Opportunity Cost\\nIn addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high. \\n\\n### Incentivizing Validators\\n\\nThe Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators.\\n\\nCasper\'s solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current \\"[era](https://docs.casper.network/concepts/glossary/E/#era)\\", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a \\"validator credit\\" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next [booking block](https://docs.casper.network/concepts/glossary/B/#booking-block) appears.\\n\\n## Looking Forward\\n\\nBy introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols.\\n\\nAs the model is rolled out to Casper\'s mainnet and testnet, economists and engineers will study its effects on Casper\'s transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented.\\n\\n---\\n### Further Reading/Terms\\n\\n#### Proposer\\nA validator proposing a block to the network for execution \\n[Consensus](https://docs.casper.network/concepts/economics/consensus/) \\n[Validator](https://docs.casper.network/concepts/glossary/V/#validator)\\n\\n#### Fees\\nA portion of a transaction\'s gas costs given over to the proposer of the block containing that transaction. \\n[Gas Concepts](https://docs.casper.network/concepts/economics/gas-concepts/) \\n[Runtime Economics](https://docs.casper.network/runtime/) \\n[Validator Rewards](https://docs.casper.network/concepts/glossary/R/#reward)"},{"id":"condor-local-setup","metadata":{"permalink":"/blog/condor-local-setup","source":"@site/blog/2024-07-16-setting-up-condor-local.md","title":"Setting Up a Local Casper Condor Network for Development","description":"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.","date":"2024-07-16T18:00:00.000Z","tags":[{"inline":false,"label":"Condor","permalink":"/blog/tags/condor","description":"Blog posts related to the Condor upgrade"},{"inline":true,"label":"setup","permalink":"/blog/tags/setup"}],"readingTime":4.08,"hasTruncateMarker":true,"authors":[{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor"}],"frontMatter":{"title":"Setting Up a Local Casper Condor Network for Development","description":"How to set up a local Casper Condor Network for Development using CCTL and the Rust Casper client.","slug":"condor-local-setup","date":"2024-07-16T18:00","authors":["sczembor"],"tags":["condor","setup"],"hide_table_of_contents":false},"unlisted":false,"prevItem":{"title":"Fee Elimination in Condor","permalink":"/blog/condor-fee-elimination"}},"content":"Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.\\n\\n\x3c!-- truncate --\x3e\\n\\n## Prerequisites\\n\\n* Docker installed and running on your machine \\n\\n## Part 1: The Dockerized NCTL (Network Control Tool)\\n\\nNCTL is your tool for managing the Casper network. We\'ll use a Dockerized version for easier setup.\\n\\n1. **Clone the Repository:**\\n ```bash\\n git clone https://github.com/make-software/casper-nctl-docker.git\\n cd casper-nctl-docker\\n ```\\n\\n2. **Switch to the Condor Branch:**\\n ```bash\\n git checkout feat-2.0\\n ```\\n\\n3. **Clone the `casper-node` Repository:**\\n ```bash\\n git clone https://github.com/casper-network/casper-node.git\\n cd casper-node\\n git checkout release-2.0.0-rc3\\n ```\\n Ensure you\'re in the `casper-nctl-docker` directory when running this command\\n\\n4. **Build the Docker Image:**\\n ```bash\\n docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .\\n ```\\n This may take a while\\n\\n5. **Verify the Image:**\\n ```bash\\n docker image ls\\n ```\\n Look for the `casper-nctl:rc3` image in the output\\n ```\\n REPOSITORY TAG IMAGE ID CREATED SIZE\\n casper-nctl rc3 9fd1e7b25d42 40 hours ago 433MB\\n ```\\n\\n6. **Start the NCTL Docker Container:**\\n * **Docker Compose (Recommended):** If you\'re using the `docker-compose.yml` file, make sure that the `image` under the `mynctl` service points to `casper-nctl:rc3`. Then run `docker-compose up`.\\n * **Manual Docker Command:** \\n ```bash\\n docker run -d --name mynctl -p 11101:11101 casper-nctl:rc3\\n ```\\n\\n Once it is up and running you should see that there are 5 nodes and 5 sidecars running and another 5 nodes and 5 sidecars that are inactive:\\n ```\\n casper-nctl | validators-1:casper-net-1-node-1 RUNNING pid 996, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-node-2 RUNNING pid 998, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-node-3 RUNNING pid 1002, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-1 RUNNING pid 997, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-2 RUNNING pid 1000, uptime 0:00:03\\n casper-nctl | validators-1:casper-net-1-sidecar-3 RUNNING pid 1011, uptime 0:00:03\\n casper-nctl | validators-2:casper-net-1-node-4 RUNNING pid 1082, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-node-5 RUNNING pid 1084, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-sidecar-4 RUNNING pid 1083, uptime 0:00:02\\n casper-nctl | validators-2:casper-net-1-sidecar-5 RUNNING pid 1085, uptime 0:00:02\\n casper-nctl | validators-3:casper-net-1-node-10 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-6 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-7 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-8 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-node-9 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-10 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-6 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-7 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-8 STOPPED Not started\\n casper-nctl | validators-3:casper-net-1-sidecar-9 STOPPED Not started\\n ```\\n\\n\\n## Part 2: Casper Client (Rust)\\n\\nTo interact with your local Condor network, we\'ll use the Casper Client. You have two options for using the Casper Client:\\n\\n**Option 1: Using the Casper Client from the Docker Image**\\n\\n* The `casper-nctl:rc3` Docker image already includes the `casper-client`.\\n* You can skip the next two steps if you want to use the pre-installed client.\\n\\n**Option 2: Using Your Local Casper Client**\\n\\n1. **Clone the Repository (Optional):**\\n ```bash\\n git clone https://github.com/casper-ecosystem/casper-client-rs.git\\n cd casper-client-rs\\n ```\\n\\n2. **Switch to the Condor-Compatible Branch (Optional):**\\n ```bash\\n git checkout feat-track-node-2.0\\n ```\\n\\n3. **Activate NCTL scripts:**\\n ```bash\\n source nctl-activate.sh casper-nctl\\n ```\\n\\n4 **Test Your Setup:**\\n ```bash\\n nctl-view-node-status\\n ```\\n This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:\\n ```\\n ------------------------------------------------------------------------------------------------------------------------------------\\n 2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:\\n {\\n \\"api_version\\": \\"2.0.0\\",\\n \\"peers\\": [\\n {\\n \\"node_id\\": \\"tls:05b5..7b39\\",\\n \\"address\\": \\"127.0.0.1:22103\\"\\n },\\n {\\n \\"node_id\\": \\"tls:527e..37d2\\",\\n \\"address\\": \\"127.0.0.1:22105\\"\\n },\\n {\\n \\"node_id\\": \\"tls:b1d0..870f\\",\\n \\"address\\": \\"127.0.0.1:22102\\"\\n },\\n {\\n \\"node_id\\": \\"tls:dcdf..e348\\",\\n \\"address\\": \\"127.0.0.1:22104\\"\\n }\\n ],\\n \\"build_version\\": \\"2.0.0-d5c0d238f\\",\\n \\"chainspec_name\\": \\"casper-net-1\\",\\n \\"starting_state_root_hash\\": \\"2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80\\",\\n \\"last_added_block_info\\": {\\n \\"hash\\": \\"c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395\\",\\n \\"timestamp\\": \\"2024-07-10T15:31:38.601Z\\",\\n \\"era_id\\": 19,\\n \\"height\\": 205,\\n \\"state_root_hash\\": \\"6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612\\",\\n \\"creator\\": \\"0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab\\"\\n },\\n \\"our_public_signing_key\\": \\"01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b\\",\\n \\"round_length\\": \\"4s 96ms\\",\\n \\"next_upgrade\\": null,\\n \\"uptime\\": \\"13m 15s\\",\\n \\"reactor_state\\": \\"Validate\\",\\n \\"last_progress\\": \\"2024-07-10T15:18:26.354Z\\",\\n \\"available_block_range\\": {\\n \\"low\\": 0,\\n \\"high\\": 205\\n },\\n \\"block_sync\\": {\\n \\"historical\\": null,\\n \\"forward\\": null\\n },\\n \\"latest_switch_block_hash\\": \\"5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68\\"\\n }\\n .\\n .\\n .\\n ```\\n\\n## Troubleshooting\\n\\n**If sidecars or nodes are not running:** If you see `null` values under each node in the output of `nctl-view-node-status`, it means the version of `casper-sidecar` is not compatible with the `casper-node`.\\n\\n**Solution:**\\n1. Go to the `casper-node/ci/ci.json` file.\\n2. Change the `casper-sidecar` branch under `external_deps` from:\\n ```json\\n \\"branch\\": \\"feat-2.0\\"\\n ``` \\n to:\\n ```json\\n \\"branch\\": \\"release-1.0.0rc2_node-2.0.0rc3\\" \\n ```\\n\\n This is because the `casper-node` we are using is `release-2.0.0-rc3`. The required combination of versions of `casper-sidecar` and `casper-node` may change in the future (rc4 etc.).\\n\\n3. Rebuild the NCTL image: `docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .`\\n\\n## Using the Casper Client\\n\\n* **Command Format(Using local casper-client):** `cargo run --release [command] --node-address http://127.0.0.1:11101`\\n* **Command Format(Using casper-client from the docker image):** `casper-client [command] --node-address http://127.0.0.1:11101`\\n\\n## Accessing the NCTL Block Web Explorer\\n\\nThe NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:\\n\\n```\\nhttp://127.0.0.1:8080\\n```\\n\\nThis allows you to visually explore blocks, transactions, and other details of your local network.\\n\\n## Important Notes\\n\\n* **Work in Progress:** Condor compatibility is still evolving. Some features may be unstable or incomplete.\\n\\n## Additional Tips\\n\\n* **Community Resources:** Join the [Casper Telegram](https://t.me/CSPRCondor) for help and discussion."}]}}')}}]); \ No newline at end of file diff --git a/assets/js/dc1c4417.1f2e5fdc.js b/assets/js/dc1c4417.1f2e5fdc.js deleted file mode 100644 index 58e538730..000000000 --- a/assets/js/dc1c4417.1f2e5fdc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5580],{26937:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>h});var s=n(74848),o=n(28453);const r={},a="Tutorial Walkthrough",c={id:"resources/beginner/counter-testnet/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/walkthrough.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/walkthrough",permalink:"/resources/beginner/counter-testnet/walkthrough",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter-testnet/commands"},next:{title:"Querying a Node",permalink:"/resources/tutorials/beginner/querying-network"}},i={},h=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"account hash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, you can check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]"})," - Get the account-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state-root-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-state"})," - Query the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first."}),"\n",(0,s.jsx)(t.p,{children:"Next, get the state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You need to use the IP address of one of the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["Please be mindful of the node address format when using the ",(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," command."]})}),"\n",(0,s.jsxs)(t.p,{children:["While browsing the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," list, you might encounter entries similar to ",(0,s.jsx)(t.code,{children:"44.222.236.237:35000"}),". These entries only provide the IP address and port used for peer-to-peer communication within the network."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["For the ",(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," command, you need to modify the address slightly:"]})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:["Add the ",(0,s.jsx)(t.code,{children:"http://"})," prefix:"]})," This indicates that you're communicating with the node using the HTTP protocol."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Replace the port:"})," While the peers list might show a different port (e.g., ",(0,s.jsx)(t.code,{children:"35000"}),"), the Casper node uses port ",(0,s.jsx)(t.code,{children:"7777"})," for state queries."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Following these steps, the correct command format for your example address would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://44.222.236.237:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember to apply this modification to any node address you use with the ",(0,s.jsx)(t.code,{children:"get-state-root-hash"})," command."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to deploy the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on the Testnet!"})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc1c4417.31cadd38.js b/assets/js/dc1c4417.31cadd38.js new file mode 100644 index 000000000..0156aecb9 --- /dev/null +++ b/assets/js/dc1c4417.31cadd38.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[35580],{26937:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>c,toc:()=>h});var s=n(74848),o=n(28453);const r={},a="Tutorial Walkthrough",c={id:"resources/beginner/counter-testnet/walkthrough",title:"Tutorial Walkthrough",description:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/walkthrough.md",sourceDirName:"resources/beginner/counter-testnet",slug:"/resources/beginner/counter-testnet/walkthrough",permalink:"/1.5.X/resources/beginner/counter-testnet/walkthrough",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Casper-Client Commands",permalink:"/1.5.X/resources/beginner/counter-testnet/commands"},next:{title:"Querying a Node",permalink:"/1.5.X/resources/tutorials/beginner/querying-network"}},i={},h=[{value:"Clone the Repository",id:"clone-the-repository",level:2},{value:"View the Network State",id:"view-the-network-state",level:2},{value:"Install the Contract",id:"install-the-contract",level:2},{value:"View the Updated Network State",id:"view-the-updated-network-state",level:2},{value:"Increment the Counter",id:"increment-the-counter",level:2},{value:"View the Updated Network State Again",id:"view-the-updated-network-state-again",level:2},{value:"Increment the Counter Again",id:"increment-the-counter-again",level:2},{value:"View the Final Network State",id:"view-the-final-network-state",level:2}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"tutorial-walkthrough",children:"Tutorial Walkthrough"})}),"\n",(0,s.jsx)(t.p,{children:"Now that you are familiar with the basic commands, you can begin the tutorial walkthrough."}),"\n",(0,s.jsx)(t.h2,{id:"clone-the-repository",children:"Clone the Repository"}),"\n",(0,s.jsxs)(t.p,{children:["First, you will need to clone ",(0,s.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter",children:"the counter contract repository"})," on our local machine."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/counter\n"})}),"\n",(0,s.jsx)(t.p,{children:"If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v1"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is the first version of the counter contract."}),"\n",(0,s.jsxs)(t.li,{children:["Defines two named keys: ",(0,s.jsx)(t.em,{children:"counter"})," to reference the contract and an associated variable ",(0,s.jsx)(t.em,{children:"count"})," to store a value."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to get the current count (",(0,s.jsx)(t.em,{children:"count_get"}),")."]}),"\n",(0,s.jsxs)(t.li,{children:["Provides a function to increment the current count (",(0,s.jsx)(t.em,{children:"counter_inc"}),")."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"contract-v2"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsx)(t.li,{children:"This is a second version of the counter contract, which will not be used in this tutorial."}),"\n",(0,s.jsx)(t.li,{children:"This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.code,{children:"counter-call"})}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["This is session code that retrieves the ",(0,s.jsx)(t.em,{children:"contract-v1"})," contract, gets the current count value, increments it, and ensures the count was incremented by 1."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-network-state",children:"View the Network State"}),"\n",(0,s.jsxs)(t.p,{children:["With a network up and running, you can use the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check the status of the network. However, you first need an ",(0,s.jsx)(t.code,{children:"account hash"})," and the ",(0,s.jsx)(t.code,{children:"state-root-hash"})," so that you can get the current snapshot. Once you have that information, you can check the status of the network."]}),"\n",(0,s.jsx)(t.p,{children:"You will need to use the following three commands:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]"})," - Get the account-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," - Get the state-root-hash"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"casper-client query-state"})," - Query the network state"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Run through these commands in order."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You will need to specify the location of your public-key files. If you used the block explorer to generate the keys, you will need to download them first."}),"\n",(0,s.jsx)(t.p,{children:"Next, get the state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You need to use the IP address of one of the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["Please be mindful of the node address format when using the ",(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," command."]})}),"\n",(0,s.jsxs)(t.p,{children:["While browsing the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/peers",children:"connected peers"})," list, you might encounter entries similar to ",(0,s.jsx)(t.code,{children:"44.222.236.237:35000"}),". These entries only provide the IP address and port used for peer-to-peer communication within the network."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsxs)(t.strong,{children:["For the ",(0,s.jsx)(t.code,{children:"casper-client get-state-root-hash"})," command, you need to modify the address slightly:"]})}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsxs)(t.strong,{children:["Add the ",(0,s.jsx)(t.code,{children:"http://"})," prefix:"]})," This indicates that you're communicating with the node using the HTTP protocol."]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.strong,{children:"Replace the port:"})," While the peers list might show a different port (e.g., ",(0,s.jsx)(t.code,{children:"35000"}),"), the Casper node uses port ",(0,s.jsx)(t.code,{children:"7777"})," for state queries."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Following these steps, the correct command format for your example address would be:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://44.222.236.237:7777\n"})}),"\n",(0,s.jsxs)(t.p,{children:["Remember to apply this modification to any node address you use with the ",(0,s.jsx)(t.code,{children:"get-state-root-hash"})," command."]}),"\n",(0,s.jsx)(t.p,{children:"Finally, query the actual state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet."}),"\n",(0,s.jsx)(t.h2,{id:"install-the-contract",children:"Install the Contract"}),"\n",(0,s.jsx)(t.p,{children:"Before installing the contract on the chain, you will need to compile it to Wasm."}),"\n",(0,s.jsxs)(t.p,{children:["The Makefile included in the repository makes compilation trivial. With these two commands, you can build (in release mode) and test the contract before installing it. ",(0,s.jsx)(t.em,{children:"make prepare"})," sets the Wasm target and ",(0,s.jsx)(t.em,{children:"make test"})," builds the contracts and verifies them."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"cd counter\nmake prepare\nmake test\n"})}),"\n",(0,s.jsxs)(t.p,{children:["With the compiled contract, you can call the ",(0,s.jsx)(t.code,{children:"casper-client put-deploy"})," command to install the contract on the chain."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./contract-v1/target/wasm32-unknown-unknown/release/counter-v1.wasm\n"})}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["Replace the ",(0,s.jsx)(t.code,{children:"[PATH_TO_YOUR_KEY]"})," field with the actual path of where your secret key is stored."]}),"\n",(0,s.jsxs)(t.li,{children:["The ",(0,s.jsx)(t.em,{children:"session-path"})," argument should point to wherever you compiled the counter-v1.wasm on your computer. The code snippet shows you the default path if the counter folder is in the same directory."]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:"Once you call this command, it will return a deploy hash. You can use this hash to verify that the deploy successfully took place."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-rust",children:"casper-client get-deploy \\\n --node-address http://[NODE_IP]:7777 [DEPLOY_HASH]\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state",children:"View the Updated Network State"}),"\n",(0,s.jsxs)(t.p,{children:["Hopefully, the deploy was successful. Call the ",(0,s.jsx)(t.code,{children:"casper-client query-global-state"})," command to check if the named key is visible on the chain."]}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsx)(t.p,{children:"You must get the new state root hash since you just wrote a deploy to the chain."})}),"\n",(0,s.jsx)(t.p,{children:"If you run these two commands, there will be a new counter named key on the chain."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(t.p,{children:"You can actually dive further into the data stored on the chain using the query path argument or directly querying the deploy hash. Try the following commands and notice that each one gives you a different level of detail."}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific counter contract details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific count value:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"Retrieve the specific deploy details:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] --key deploy-[DEPLOY_HASH]\n"})}),"\n",(0,s.jsxs)(t.p,{children:["The first two commands access the ",(0,s.jsx)(t.code,{children:"counter"})," and ",(0,s.jsx)(t.code,{children:"count"})," named keys, respectively, using the query path argument. The third command uses the deploy hash (the return value of ",(0,s.jsx)(t.em,{children:"put-deploy"}),") to query the state of that specific deploy only."]}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter",children:"Increment the Counter"}),"\n",(0,s.jsxs)(t.p,{children:["You now have a counter on the chain, and you can increment it by calling the entry-point ",(0,s.jsx)(t.em,{children:"counter_inc"}),", the function defined in the contract. You can call an entry-point in an installed contract by using the ",(0,s.jsx)(t.em,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Notice that this command is nearly identical to the command used to deploy the contract. However, instead of ",(0,s.jsx)(t.em,{children:"session-path"})," pointing to the Wasm binary, you have ",(0,s.jsx)(t.em,{children:"session-name"})," and ",(0,s.jsx)(t.em,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry-point to execute."]}),"\n",(0,s.jsx)(t.h2,{id:"view-the-updated-network-state-again",children:"View the Updated Network State Again"}),"\n",(0,s.jsx)(t.p,{children:"After calling the entry-point, theoretically, the count value should increment by one, but how can you be sure of that? You can query the network again, however, remember that you have to get a new state root hash. Check if the count was incremented by looking at it with the query argument."}),"\n",(0,s.jsx)(t.p,{children:"Get the NEW state-root-hash:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"You should be able to see the count value and observe that it has increased."}),"\n",(0,s.jsx)(t.h2,{id:"increment-the-counter-again",children:"Increment the Counter Again"}),"\n",(0,s.jsxs)(t.p,{children:["If you recall, in the repository there is session code called ",(0,s.jsx)(t.em,{children:"counter-call"}),". Try to increment the count using that session code instead of the session entry-point used above."]}),"\n",(0,s.jsxs)(t.p,{children:["Keep in mind, this is another ",(0,s.jsx)(t.em,{children:"put-deploy"})," call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://[NODE_IP]:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path ./counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm\n"})}),"\n",(0,s.jsx)(t.h2,{id:"view-the-final-network-state",children:"View the Final Network State"}),"\n",(0,s.jsx)(t.p,{children:"To make sure that the session code ran successfully, get the new state root hash and query the network."}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://[NODE_IP]:7777\n"})}),"\n",(0,s.jsx)(t.p,{children:"Get the network state, specifically for the count variable this time:"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://[NODE_IP]:7777 \\\n --state-root-hash [STATE_ROOT_HASH]\n --key [ACCOUNT_HASH] -q "counter/count"\n'})}),"\n",(0,s.jsx)(t.p,{children:"If all went according to plan, your count value should be 2 at this point."}),"\n",(0,s.jsx)(t.p,{children:"Congratulations on building, installing, and using a smart contract on the Testnet!"})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>c});var s=n(96540);const o={},r=s.createContext(o);function a(e){const t=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc5e10d3.7935911a.js b/assets/js/dc5e10d3.7935911a.js new file mode 100644 index 000000000..b21c9be0b --- /dev/null +++ b/assets/js/dc5e10d3.7935911a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[94557],{47374:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},o="Transactions and the Transaction Lifecycle",c={id:"concepts/transactions-and-transaction-lifecycle",title:"Transaction Lifecycle",description:"Transactions",source:"@site/docs/concepts/transactions-and-transaction-lifecycle.md",sourceDirName:"concepts",slug:"/transactions-and-transaction-lifecycle",permalink:"/transactions-and-transaction-lifecycle",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},sidebar:"concepts",previous:{title:"Key Types",permalink:"/concepts/key-types"},next:{title:"Global State",permalink:"/concepts/global-state"}},r={},d=[{value:"Transactions",id:"execution-semantics-transactions",level:2},{value:"The Transaction Lifecycle",id:"execution-semantics-phases",level:2},{value:"Transaction Received",id:"transaction-received",level:3},{value:"Transaction Gossiped",id:"transaction-gossiped",level:3},{value:"Block Proposed",id:"block-proposed",level:3},{value:"Block Gossiped",id:"block-gossiped",level:3},{value:"Consensus Reached",id:"consensus-reached",level:3},{value:"Transaction Executed",id:"transaction-executed",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"transactions-and-the-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-transactions",children:"Transactions"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"/concepts/glossary/T#transaction",children:"transaction"})," is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions\u2019s structure is as follows:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Transaction Data Structure",src:t(62423).A+"",width:"900",height:"586"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Body: Containing payment code and session code (more details on these below)"}),"\n",(0,s.jsxs)(n.li,{children:["Header: containing\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.a,{href:"/concepts/serialization/types#publickey",children:"Public Key"})," of the account in whose context the transaction will run"]}),"\n",(0,s.jsx)(n.li,{children:"The timestamp of the transaction\u2019s creation"}),"\n",(0,s.jsx)(n.li,{children:"A time-to-live, after which the transaction expires and cannot be included in a block"}),"\n",(0,s.jsxs)(n.li,{children:["the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the body"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Transaction hash: the ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of the Header"]}),"\n",(0,s.jsxs)(n.li,{children:["Approvals: the set of signatures which have signed the transaction hash; these are used in the ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"account permissions model"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-phases",children:"The Transaction Lifecycle"}),"\n",(0,s.jsx)(n.p,{children:"A transaction goes through the following phases on Casper:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Transaction Received"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Block Proposed"}),"\n",(0,s.jsx)(n.li,{children:"Block Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Consensus Reached"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Executed"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-received",children:"Transaction Received"}),"\n",(0,s.jsxs)(n.p,{children:["A client sending the transaction will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given transaction matches configuration settings outlined in the network's chainspec. Transaction configuration for the Casper Mainnet can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L79",children:"here"}),". Once accepted, the system returns the transaction hash to the client to indicate it has been enqueued for execution. The transaction could expire while waiting to be gossiped; whenever this happens, a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event is emitted by the event stream servers of all nodes which have the expired transaction."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-gossiped",children:"Transaction Gossiped"}),"\n",(0,s.jsxs)(n.p,{children:["After a node accepts a new transaction, it will gossip to all other nodes. A validator node will put the transaction into the block proposer buffer. The validator leader will pick the transaction from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given transaction. Each node that accepts a gossiped transaction also emits a ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," event on its event stream server. The transaction may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event."]}),"\n",(0,s.jsx)(n.h3,{id:"block-proposed",children:"Block Proposed"}),"\n",(0,s.jsx)(n.p,{children:"The validator leader for this round will propose a block that includes as many transactions from the block proposer buffer as can fit in a block."}),"\n",(0,s.jsx)(n.h3,{id:"block-gossiped",children:"Block Gossiped"}),"\n",(0,s.jsx)(n.p,{children:"The proposed block propagates to all other nodes."}),"\n",(0,s.jsx)(n.h3,{id:"consensus-reached",children:"Consensus Reached"}),"\n",(0,s.jsxs)(n.p,{children:["Once the other validators reach consensus that the proposed block is valid, all transactions in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a ",(0,s.jsx)(n.code,{children:"BlockAdded"}),". ",(0,s.jsx)(n.code,{children:"FinalitySignature"})," events emit shortly after that. Finality signatures for the new block arrive from the validators."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-executed",children:"Transaction Executed"}),"\n",(0,s.jsxs)(n.p,{children:["A transaction executes in distinct phases to accommodate flexibly paying for computation. The phases of a transaction are ",(0,s.jsx)(n.em,{children:"payment"}),", ",(0,s.jsx)(n.em,{children:"session"}),", and ",(0,s.jsx)(n.em,{children:"finalization"}),". Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the transaction is executed, a ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event is emitted by the event stream server."]}),"\n",(0,s.jsx)(n.p,{children:"In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty transactions."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Payment code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Payment code"})," determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#tokens-purses-and-accounts",children:"main purse"}),". In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," motes (a constant of the system.)\nIf the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending entity's main purse."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Session code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Session code"})," provides the main logic for the transaction. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself)."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Specifying payment code and session code"})}),"\n",(0,s.jsx)(n.p,{children:"The user-defined logic of a transaction can be specified in a number of ways:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account entity or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the entity the transaction is running in.)"}),"\n",(0,s.jsxs)(n.li,{children:["a 32-byte identifier representing the ",(0,s.jsx)(n.a,{href:"/concepts/serialization/types#hash-key-serialization-standard-hash-key",children:"hash"})," where a contract is already stored in the global state"]}),"\n",(0,s.jsx)(n.li,{children:"a name corresponding to a named key, where a contract is stored under the key"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module)."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},62423:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/transaction-structure-658d8000fd6a573bafc1e7b8535b3c07.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dc5e10d3.854abbc3.js b/assets/js/dc5e10d3.854abbc3.js deleted file mode 100644 index 6396abab7..000000000 --- a/assets/js/dc5e10d3.854abbc3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4557],{47374:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>d});var s=t(74848),i=t(28453);const a={title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},o="Transactions and the Transaction Lifecycle",c={id:"concepts/transactions-and-transaction-lifecycle",title:"Transaction Lifecycle",description:"Transactions",source:"@site/docs/concepts/transactions-and-transaction-lifecycle.md",sourceDirName:"concepts",slug:"/transactions-and-transaction-lifecycle",permalink:"/next/transactions-and-transaction-lifecycle",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725635514e3,frontMatter:{title:"Transaction Lifecycle",slug:"/transactions-and-transaction-lifecycle"},sidebar:"concepts",previous:{title:"Key Types",permalink:"/next/concepts/key-types"},next:{title:"Global State",permalink:"/next/concepts/global-state"}},r={},d=[{value:"Transactions",id:"execution-semantics-transactions",level:2},{value:"The Transaction Lifecycle",id:"execution-semantics-phases",level:2},{value:"Transaction Received",id:"transaction-received",level:3},{value:"Transaction Gossiped",id:"transaction-gossiped",level:3},{value:"Block Proposed",id:"block-proposed",level:3},{value:"Block Gossiped",id:"block-gossiped",level:3},{value:"Consensus Reached",id:"consensus-reached",level:3},{value:"Transaction Executed",id:"transaction-executed",level:3}];function l(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"transactions-and-the-transaction-lifecycle",children:"Transactions and the Transaction Lifecycle"})}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-transactions",children:"Transactions"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"transaction"})," is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions\u2019s structure is as follows:"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.img,{alt:"Transaction Data Structure",src:t(13373).A+"",width:"900",height:"586"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Body: Containing payment code and session code (more details on these below)"}),"\n",(0,s.jsxs)(n.li,{children:["Header: containing\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["The ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#publickey",children:"Public Key"})," of the account in whose context the transaction will run"]}),"\n",(0,s.jsx)(n.li,{children:"The timestamp of the transaction\u2019s creation"}),"\n",(0,s.jsx)(n.li,{children:"A time-to-live, after which the transaction expires and cannot be included in a block"}),"\n",(0,s.jsxs)(n.li,{children:["the ",(0,s.jsx)(n.code,{children:"blake2b256"})," hash of the body"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["Transaction hash: the ",(0,s.jsx)(n.code,{children:"blake2b"})," hash of the Header"]}),"\n",(0,s.jsxs)(n.li,{children:["Approvals: the set of signatures which have signed the transaction hash; these are used in the ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-associated-keys-weights",children:"account permissions model"})]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"execution-semantics-phases",children:"The Transaction Lifecycle"}),"\n",(0,s.jsx)(n.p,{children:"A transaction goes through the following phases on Casper:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Transaction Received"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Block Proposed"}),"\n",(0,s.jsx)(n.li,{children:"Block Gossiped"}),"\n",(0,s.jsx)(n.li,{children:"Consensus Reached"}),"\n",(0,s.jsx)(n.li,{children:"Transaction Executed"}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-received",children:"Transaction Received"}),"\n",(0,s.jsxs)(n.p,{children:["A client sending the transaction will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given transaction matches configuration settings outlined in the network's chainspec. Transaction configuration for the Casper Mainnet can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/production/chainspec.toml#L79",children:"here"}),". Once accepted, the system returns the transaction hash to the client to indicate it has been enqueued for execution. The transaction could expire while waiting to be gossiped; whenever this happens, a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event is emitted by the event stream servers of all nodes which have the expired transaction."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-gossiped",children:"Transaction Gossiped"}),"\n",(0,s.jsxs)(n.p,{children:["After a node accepts a new transaction, it will gossip to all other nodes. A validator node will put the transaction into the block proposer buffer. The validator leader will pick the transaction from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given transaction. Each node that accepts a gossiped transaction also emits a ",(0,s.jsx)(n.code,{children:"TransactionAccepted"})," event on its event stream server. The transaction may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a ",(0,s.jsx)(n.code,{children:"TransactionExpired"})," event."]}),"\n",(0,s.jsx)(n.h3,{id:"block-proposed",children:"Block Proposed"}),"\n",(0,s.jsx)(n.p,{children:"The validator leader for this round will propose a block that includes as many transactions from the block proposer buffer as can fit in a block."}),"\n",(0,s.jsx)(n.h3,{id:"block-gossiped",children:"Block Gossiped"}),"\n",(0,s.jsx)(n.p,{children:"The proposed block propagates to all other nodes."}),"\n",(0,s.jsx)(n.h3,{id:"consensus-reached",children:"Consensus Reached"}),"\n",(0,s.jsxs)(n.p,{children:["Once the other validators reach consensus that the proposed block is valid, all transactions in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a ",(0,s.jsx)(n.code,{children:"BlockAdded"}),". ",(0,s.jsx)(n.code,{children:"FinalitySignature"})," events emit shortly after that. Finality signatures for the new block arrive from the validators."]}),"\n",(0,s.jsx)(n.h3,{id:"transaction-executed",children:"Transaction Executed"}),"\n",(0,s.jsxs)(n.p,{children:["A transaction executes in distinct phases to accommodate flexibly paying for computation. The phases of a transaction are ",(0,s.jsx)(n.em,{children:"payment"}),", ",(0,s.jsx)(n.em,{children:"session"}),", and ",(0,s.jsx)(n.em,{children:"finalization"}),". Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the transaction is executed, a ",(0,s.jsx)(n.code,{children:"TransactionProcessed"})," event is emitted by the event stream server."]}),"\n",(0,s.jsx)(n.p,{children:"In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty transactions."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Payment code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Payment code"})," determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#tokens-purses-and-accounts",children:"main purse"}),". In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than ",(0,s.jsx)(n.code,{children:"MAX_PAYMENT_COST"})," motes (a constant of the system.)\nIf the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending entity's main purse."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Session code"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.em,{children:"Session code"})," provides the main logic for the transaction. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself)."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Specifying payment code and session code"})}),"\n",(0,s.jsx)(n.p,{children:"The user-defined logic of a transaction can be specified in a number of ways:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account entity or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the entity the transaction is running in.)"}),"\n",(0,s.jsxs)(n.li,{children:["a 32-byte identifier representing the ",(0,s.jsx)(n.a,{href:"/next/concepts/serialization/types#hash-key-serialization-standard-hash-key",children:"hash"})," where a contract is already stored in the global state"]}),"\n",(0,s.jsx)(n.li,{children:"a name corresponding to a named key, where a contract is stored under the key"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module)."})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},13373:(e,n,t)=>{t.d(n,{A:()=>s});const s=t.p+"assets/images/transaction-structure-658d8000fd6a573bafc1e7b8535b3c07.png"},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>c});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcb4c613.333717ee.js b/assets/js/dcb4c613.333717ee.js new file mode 100644 index 000000000..ab00399a8 --- /dev/null +++ b/assets/js/dcb4c613.333717ee.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43445],{74671:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Testnet Funding",slug:"/users/testnet-faucet"},a="Funding Testnet Accounts",o={id:"users/csprlive/testnet-faucet",title:"Testnet Funding",description:"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.",source:"@site/docs/users/csprlive/testnet-faucet.md",sourceDirName:"users/csprlive",slug:"/users/testnet-faucet",permalink:"/users/testnet-faucet",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Testnet Funding",slug:"/users/testnet-faucet"},sidebar:"users",previous:{title:"Using CSPR.live",permalink:"/users/csprlive/"},next:{title:"Delegate Tokens",permalink:"/users/delegate-ui"}},c={},l=[{value:"Requesting Testnet Tokens",id:"requesting-testnet-tokens",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"funding-testnet-accounts",children:"Funding Testnet Accounts"})}),"\n",(0,s.jsxs)(t.p,{children:["The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"cspr.live"})," block explorer."]}),"\n",(0,s.jsx)(t.p,{children:"Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below."}),"\n",(0,s.jsx)(t.h3,{id:"requesting-testnet-tokens",children:"Requesting Testnet Tokens"}),"\n",(0,s.jsx)(t.p,{children:"To request test tokens, follow these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Log into the Casper Testnet with the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Tools"})," on the top menu bar and select ",(0,s.jsx)(t.strong,{children:"Faucet"})," from the drop-down menu. Or, navigate to the Faucet using this link: ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/faucet",children:"https://testnet.cspr.live/tools/faucet"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Request tokens"})," on the Faucet page:"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Faucet",src:n(66723).A+"",width:"1379",height:"617"})}),"\n",(0,s.jsxs)(t.admonition,{type:"caution",children:[(0,s.jsxs)(t.p,{children:["Tokens can be requested ",(0,s.jsx)(t.strong,{children:"only once per account"}),". Otherwise, the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/deploy/f0f6b25db767d1a6c2244324661d853ad7d4766f8489d81c36b5e2c9d982891e",children:"deploy will fail"})," with status ",(0,s.jsx)(t.code,{children:"User error: 1"}),"."]}),(0,s.jsxs)(t.p,{children:["If you have already exhausted your test funds, you can always ",(0,s.jsx)(t.a,{href:"/developers/prerequisites#creating-an-account",children:"create a new account"}),"."]})]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:"The Testnet will credit your account with test tokens."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},66723:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/faucet-function-f3c2d05a9fd17287ec2fb304731a0197.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dcb4c613.9305969c.js b/assets/js/dcb4c613.9305969c.js deleted file mode 100644 index 20e697c5a..000000000 --- a/assets/js/dcb4c613.9305969c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3445],{74671:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=n(74848),r=n(28453);const i={title:"Testnet Funding",slug:"/users/testnet-faucet"},a="Funding Testnet Accounts",o={id:"users/csprlive/testnet-faucet",title:"Testnet Funding",description:"The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.",source:"@site/docs/users/csprlive/testnet-faucet.md",sourceDirName:"users/csprlive",slug:"/users/testnet-faucet",permalink:"/next/users/testnet-faucet",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724763233e3,frontMatter:{title:"Testnet Funding",slug:"/users/testnet-faucet"},sidebar:"users",previous:{title:"Using CSPR.live",permalink:"/next/users/csprlive/"},next:{title:"Delegate Tokens",permalink:"/next/users/delegate-ui"}},c={},l=[{value:"Requesting Testnet Tokens",id:"requesting-testnet-tokens",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h3:"h3",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"funding-testnet-accounts",children:"Funding Testnet Accounts"})}),"\n",(0,s.jsxs)(t.p,{children:["The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/",children:"cspr.live"})," block explorer."]}),"\n",(0,s.jsx)(t.p,{children:"Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below."}),"\n",(0,s.jsx)(t.h3,{id:"requesting-testnet-tokens",children:"Requesting Testnet Tokens"}),"\n",(0,s.jsx)(t.p,{children:"To request test tokens, follow these steps:"}),"\n",(0,s.jsxs)(t.ol,{children:["\n",(0,s.jsxs)(t.li,{children:["Log into the Casper Testnet with the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"}),". See the ",(0,s.jsx)(t.a,{href:"https://www.casperwallet.io/user-guide/getting-started",children:"Getting Started"})," user guide for detailed instructions."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Tools"})," on the top menu bar and select ",(0,s.jsx)(t.strong,{children:"Faucet"})," from the drop-down menu. Or, navigate to the Faucet using this link: ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/tools/faucet",children:"https://testnet.cspr.live/tools/faucet"}),"."]}),"\n",(0,s.jsxs)(t.li,{children:["Click ",(0,s.jsx)(t.strong,{children:"Request tokens"})," on the Faucet page:"]}),"\n"]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Faucet",src:n(97245).A+"",width:"1379",height:"617"})}),"\n",(0,s.jsxs)(t.admonition,{type:"caution",children:[(0,s.jsxs)(t.p,{children:["Tokens can be requested ",(0,s.jsx)(t.strong,{children:"only once per account"}),". Otherwise, the ",(0,s.jsx)(t.a,{href:"https://testnet.cspr.live/deploy/f0f6b25db767d1a6c2244324661d853ad7d4766f8489d81c36b5e2c9d982891e",children:"deploy will fail"})," with status ",(0,s.jsx)(t.code,{children:"User error: 1"}),"."]}),(0,s.jsxs)(t.p,{children:["If you have already exhausted your test funds, you can always ",(0,s.jsx)(t.a,{href:"/next/developers/prerequisites#creating-an-account",children:"create a new account"}),"."]})]}),"\n",(0,s.jsxs)(t.ol,{start:"4",children:["\n",(0,s.jsx)(t.li,{children:"The Testnet will credit your account with test tokens."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},97245:(e,t,n)=>{n.d(t,{A:()=>s});const s=n.p+"assets/images/faucet-function-f3c2d05a9fd17287ec2fb304731a0197.png"},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var s=n(96540);const r={},i=s.createContext(r);function a(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd04b75e.3463f4df.js b/assets/js/dd04b75e.3463f4df.js new file mode 100644 index 000000000..b2a3f9ab0 --- /dev/null +++ b/assets/js/dd04b75e.3463f4df.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[21672],{33024:e=>{e.exports=JSON.parse('{"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden","count":4},{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor","count":2},{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland","count":1},{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/dd04b75e.7f740bf3.js b/assets/js/dd04b75e.7f740bf3.js deleted file mode 100644 index e191215bf..000000000 --- a/assets/js/dd04b75e.7f740bf3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1672],{33024:e=>{e.exports=JSON.parse('{"authors":[{"name":"Mel Padden","page":{"permalink":"/blog/authors/melpadden"},"title":"Head of Developer Relations for Casper Association","url":"https://github.com/melpadden","socials":{"x":"https://x.com/mel_casper"},"permalink":"/melpadden","imageURL":"https://github.com/melpadden.png","key":"melpadden","count":4},{"name":"Stanislaw Czembor","page":{"permalink":"/blog/authors/sczembor"},"title":"Developer Advocate for Casper Association","url":"https://github.com/sczembor","permalink":"/sczembor","imageURL":"https://github.com/sczembor.png","key":"sczembor","count":2},{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland","count":1},{"name":"Alexander Limonov","page":{"permalink":"/blog/authors/alexanderlimonov"},"title":"Economist for Casper Labs","url":"https://github.com/AlexanderLimonov","permalink":"/alexanderlimonov","imageURL":"https://github.com/AlexanderLimonov.png","key":"alexanderlimonov","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/dd908370.a9598e25.js b/assets/js/dd908370.a9598e25.js deleted file mode 100644 index 416187d82..000000000 --- a/assets/js/dd908370.a9598e25.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9918],{77237:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var r=t(74848),s=t(28453);const o={},i="Setting up a Node",d={id:"operators/setup/index",title:"Setting up a Node",description:"The prerequisite for becoming a validator is to set up a node and join a network as described here.",source:"@site/versioned_docs/version-1.5.X/operators/setup/index.md",sourceDirName:"operators/setup",slug:"/operators/setup/",permalink:"/operators/setup/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Overview",permalink:"/operators"},next:{title:"Hardware",permalink:"/operators/setup/hardware"}},a={},c=[];function p(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-node",children:"Setting up a Node"})}),"\n",(0,r.jsx)(n.p,{children:"The prerequisite for becoming a validator is to set up a node and join a network as described here."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/hardware",children:"Recommended Hardware Specifications"})}),(0,r.jsx)(n.td,{children:"System requirements for the Casper Mainnet and Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/basic-node-configuration",children:"Basic Node Configuration"})}),(0,r.jsx)(n.td,{children:"Processes and files involved in setting up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/node-endpoints",children:"Node Endpoints"})}),(0,r.jsx)(n.td,{children:"Ports for communicating with other nodes and dApps"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/install-node",children:"Installing a Node"})}),(0,r.jsx)(n.td,{children:"Step-by-step instructions to install a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/open-files",children:"Setting the Open Files Limit"})}),(0,r.jsx)(n.td,{children:"Required setting for the Casper node to run correctly"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/upgrade",children:"Upgrading the Node"})}),(0,r.jsx)(n.td,{children:"Before joining the network, the node needs to be upgraded"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/joining",children:"Joining a Running Network"})}),(0,r.jsx)(n.td,{children:"Steps to join an existing Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/operators/setup/non-root-user",children:"Setting up a Non-Root User"})}),(0,r.jsx)(n.td,{children:"Logging into the node remotely using a key"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var r=t(96540);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd908370.b6499474.js b/assets/js/dd908370.b6499474.js new file mode 100644 index 000000000..1c82d7f19 --- /dev/null +++ b/assets/js/dd908370.b6499474.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[69918],{77237:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>d,toc:()=>c});var r=t(74848),s=t(28453);const o={},i="Setting up a Node",d={id:"operators/setup/index",title:"Setting up a Node",description:"The prerequisite for becoming a validator is to set up a node and join a network as described here.",source:"@site/versioned_docs/version-1.5.X/operators/setup/index.md",sourceDirName:"operators/setup",slug:"/operators/setup/",permalink:"/1.5.X/operators/setup/",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"operators",previous:{title:"Overview",permalink:"/1.5.X/operators"},next:{title:"Hardware",permalink:"/1.5.X/operators/setup/hardware"}},a={},c=[];function p(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"setting-up-a-node",children:"Setting up a Node"})}),"\n",(0,r.jsx)(n.p,{children:"The prerequisite for becoming a validator is to set up a node and join a network as described here."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,r.jsxs)(n.table,{children:[(0,r.jsx)(n.thead,{children:(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.th,{children:"Title"}),(0,r.jsx)(n.th,{children:"Description"})]})}),(0,r.jsxs)(n.tbody,{children:[(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/hardware",children:"Recommended Hardware Specifications"})}),(0,r.jsx)(n.td,{children:"System requirements for the Casper Mainnet and Testnet"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/basic-node-configuration",children:"Basic Node Configuration"})}),(0,r.jsx)(n.td,{children:"Processes and files involved in setting up a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/node-endpoints",children:"Node Endpoints"})}),(0,r.jsx)(n.td,{children:"Ports for communicating with other nodes and dApps"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/install-node",children:"Installing a Node"})}),(0,r.jsx)(n.td,{children:"Step-by-step instructions to install a Casper node"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/open-files",children:"Setting the Open Files Limit"})}),(0,r.jsx)(n.td,{children:"Required setting for the Casper node to run correctly"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/upgrade",children:"Upgrading the Node"})}),(0,r.jsx)(n.td,{children:"Before joining the network, the node needs to be upgraded"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/joining",children:"Joining a Running Network"})}),(0,r.jsx)(n.td,{children:"Steps to join an existing Casper network"})]}),(0,r.jsxs)(n.tr,{children:[(0,r.jsx)(n.td,{children:(0,r.jsx)(n.a,{href:"/1.5.X/operators/setup/non-root-user",children:"Setting up a Non-Root User"})}),(0,r.jsx)(n.td,{children:"Logging into the node remotely using a key"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>d});var r=t(96540);const s={},o=r.createContext(s);function i(e){const n=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),r.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dd93ee27.c6c59160.js b/assets/js/dd93ee27.c6c59160.js new file mode 100644 index 000000000..0f98a59a7 --- /dev/null +++ b/assets/js/dd93ee27.c6c59160.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70720],{68127:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>r,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>i});var a=t(74848),c=t(28453);const s={title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},r="Cross-Contract Communication",o={id:"resources/advanced/cross-contract",title:"Cross-Contract Communication",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-2.0.0/resources/advanced/cross-contract.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/cross-contract",permalink:"/2.0.0/resources/tutorials/advanced/cross-contract",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Cross-Contract Communication",slug:"/resources/tutorials/advanced/cross-contract"},sidebar:"tutorials",previous:{title:"Storage Workflow",permalink:"/2.0.0/resources/tutorials/advanced/storage-workflow"}},d={},i=[{value:"Tutorial Outline",id:"outline",level:2},{value:"Creating the Project",id:"create-project",level:2},{value:"Changing the Standard Contract",id:"changing-contract",level:2},{value:"Deploying the Contract",id:"deploying-contract",level:2},{value:"Create Another Contract for the Cross-Contract Call",id:"cross-contract",level:2},{value:"Summary",id:"summary",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cross-contract-communication",children:"Cross-Contract Communication"})}),"\n",(0,a.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"outline",children:"Tutorial Outline"}),"\n",(0,a.jsx)(n.p,{children:"This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol."}),"\n",(0,a.jsx)(n.p,{children:"Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose.\nThe contracts are as follows:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Factory"}),"\n",(0,a.jsx)(n.li,{children:"Pair"}),"\n",(0,a.jsx)(n.li,{children:"Pair (ERC20)"}),"\n",(0,a.jsx)(n.li,{children:"Library"}),"\n",(0,a.jsx)(n.li,{children:"Router01"}),"\n",(0,a.jsx)(n.li,{children:"Router02"}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash.\nThe Pair smart contract is used to perform operations like mint or burn on a created pair of tokens."}),"\n",(0,a.jsx)(n.p,{children:"Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called."}),"\n",(0,a.jsx)(n.h2,{id:"create-project",children:"Creating the Project"}),"\n",(0,a.jsx)(n.p,{children:"In the appropriate folder, create the project for the contract using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cargo casper cross-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will create the following structure under your desired smart contract folder:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cross-contract/\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 .cargo/\n \u2514\u2500\u2500 config.toml\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n\u2514\u2500\u2500 .travis.yml\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n"})}),"\n",(0,a.jsx)(n.p,{children:"After creating the project directory structure, use the following commands to go into the project folder and compile the files:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This will also create a target folder under the contract folder where the .wasm of the contract can be found.\nAdditionally you can check if the tests can be performed using the following command:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make test\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"running 2 tests\ntest tests::should_error_on_missing_runtime_arg ... ok\ntest tests::should_store_hello_world ... ok\n\ntest result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsx)(n.p,{children:"If this is not the case and you see the following error:"}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'warning: `tests` (bin "integration-tests" test) generated 2 warnings\nerror: could not compile `tests` due to 3 previous errors; 2 warnings emitted\nmake: *** [test] Error 101\n'})}),(0,a.jsxs)(n.p,{children:["Then it is useful to check if the dependencies in ",(0,a.jsx)(n.code,{children:"Cargo.toml"})," are still up to date."]}),(0,a.jsx)(n.p,{children:(0,a.jsx)(n.img,{alt:"CargoToml",src:t(94819).A+"",width:"1570",height:"614"})}),(0,a.jsx)(n.p,{children:"If you see the red cross, it means the version is not up to date and has to be updated."})]}),"\n",(0,a.jsx)(n.h2,{id:"changing-contract",children:"Changing the Standard Contract"}),"\n",(0,a.jsxs)(n.p,{children:["The standard Casper contract from ",(0,a.jsx)(n.code,{children:"cargo-casper"})," contains some methods that we will reuse. However, we will be getting rid of most auto-generated code."]}),"\n",(0,a.jsxs)(n.p,{children:["We will be changing the ",(0,a.jsx)(n.code,{children:"main.rs"})," file. Your code should look exactly as below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"This will serve as a base for introducing the elements needed for cross-contract communication."}),"\n",(0,a.jsxs)(n.p,{children:["In a contract, you should first define the ",(0,a.jsx)(n.code,{children:"call"})," entry point. It should be understood as a ",(0,a.jsx)(n.code,{children:"constructor"})," for the contract. Everything included in the ",(0,a.jsx)(n.code,{children:"call"})," entry point will be visible as metadata on a Casper network, in the contract's context.\nYou should already be familiar with the ",(0,a.jsx)(n.code,{children:"call"})," entry point from the ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})," document. If this is not the case, be sure to familiarize yourself with it now."]}),"\n",(0,a.jsxs)(n.p,{children:["The contract code, with changes to the ",(0,a.jsx)(n.code,{children:"call"})," entry point, should look as shown below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n\n#[no_mangle]\npub extern "C" fn call() {\n\n // Get the value of the runtime argument named "message"\n let value: String = runtime::get_named_arg("message");\n\n // The value will be written under a URef\n let value_ref = storage::new_uref(value);\n\n // Creating the new set of named keys\n // The keys are a Map of String/casper_types::Key\n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key\n // Create a new vector \n let mut params = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Describing the metadata for the entry point\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg", // the name of the entry point\n vec, // the arguments which can be passed into the entry point\n CLType::Unit, // return type of the entry point\n EntryPointAccess::Public, // access permissions - public can be accessed always\n EntryPointType::Contract // in most cases it will be contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access the contract hash from the accounts named keys\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"runtime"})," and ",(0,a.jsx)(n.code,{children:"storage"})," appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the ",(0,a.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"Contract API Modules"}),"."]})}),"\n",(0,a.jsxs)(n.p,{children:["The metadata for each of the contract's entry points is defined in the ",(0,a.jsx)(n.code,{children:"call"})," entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the ",(0,a.jsx)(n.code,{children:"String"})," value passed when defining the metadata for the entry point."]}),"\n",(0,a.jsx)(n.p,{children:"The #[no_mangle] flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points."}),"\n",(0,a.jsxs)(n.p,{children:["In our case, we will define the entry point ",(0,a.jsx)(n.code,{children:"update_msg"})," in the contract code just before ",(0,a.jsx)(n.code,{children:"call"}),"."]}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract should match the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse alloc::collections::BTreeMap;\nuse crate::alloc::string::ToString;\n\n\n// Casper crates\nuse casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n\n#[no_mangle]\npub extern "C" fn update_msg() {\n\n let value: String = runtime::get_named_arg("message");\n // Get the uref of the message stored in global state\n let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();\n // Write the message to global state\n storage::write(uref, String::from(value));\n}\n\n\n#[no_mangle]\npub extern "C" fn call() {\n // Get the value of a passed parameter with the key "message"\n let value: String = runtime::get_named_arg("message");\n // The value will be wraped in a URef\n let value_ref = storage::new_uref(value);\n // Creating the new set of named keys\n // The keys are a Map of Key/Value \n let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();\n // Insert the new value into the named keys\n named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key\n // Create a new vector \n let mut vec = Vec::new();\n vec.push(Parameter::new("message", CLType::String));\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Define the metadata for the entry point `update_msg`\n entry_points.add_entry_point(EntryPoint::new(\n "update_msg",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points metadata\n Some(named_keys), // named keys \n Some("Hello_world_package_name".to_string()), // package name\n Some("Hello_world_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("hello_world_contract", stored_contract_hash.into());\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["There is a distinction between storing data in a contract\u2019s ",(0,a.jsx)(n.code,{children:"NamedKeys"})," and using a dictionary. ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/dictionaries",children:"Dictionaries"})," can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application."]})}),"\n",(0,a.jsx)(n.h2,{id:"deploying-contract",children:"Deploying the Contract"}),"\n",(0,a.jsxs)(n.p,{children:["There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts#installing-contract-code",children:"put_deploy"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Be sure to go through the prerequisites from the ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"Installing Smart Contracts and Querying Global State"})," documentation."]}),"\n",(0,a.jsx)(n.p,{children:"Make sure that after doing this you have:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsx)(n.li,{children:"A valid private key for your account."}),"\n",(0,a.jsx)(n.li,{children:"Funded your account with 2000 CSPR on the Testnet, which you can use for testing your smart contract."}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," folder in the main folder of your project and make sure that the private key which you put into the folder is called ",(0,a.jsx)(n.code,{children:"secret_key.pem"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["Compile the contract in the contract directory so you obtain the contracts ",(0,a.jsx)(n.code,{children:".wasm"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd cross-contract\nmake prepare\nmake build-contract\n"})}),"\n",(0,a.jsx)(n.p,{children:"This should produce the following outcome:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Finished release [optimized] target(s) in 0.13s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsx)(n.p,{children:"With this step everything is in place to deploy the contract."}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"When working with lengthy command strings, it may help to maintain a .txt file where you can edit the runtime arguments of the commands before sending them to the CLI. This will save you time and frustration when working with multiple contracts and commands."})}),"\n",(0,a.jsxs)(n.p,{children:["Since we are using a default contract structure, the command called from the ",(0,a.jsx)(n.code,{children:"cross-contract"})," folder should be the following:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n --session-arg \"message:string='hello world'\"\n"})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The parameters used in this command need to be adjusted based on your use case. For details, see ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/prerequisites#acquire-node-address-from-network-peers",children:"querying a node"})," and ",(0,a.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"installing contracts"}),". The payment amount may also need to be adjusted based on the latest Testnet ",(0,a.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of this command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9119604526598719721,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"\n }\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["To verify that the contract was successfully deployed, use the ",(0,a.jsx)(n.code,{children:"get-deploy"})," subcommand, providing as a parameter the ",(0,a.jsx)(n.code,{children:"deploy_hash"})," received from the ",(0,a.jsx)(n.code,{children:"put-deploy"})," above."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["This should return a JSON output containing information such as header data, approvers and payments. You can also receive this information by using the ",(0,a.jsx)(n.code,{children:"verbose"})," flag with the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand. Take time to familiarize yourself with the structure of the output."]}),"\n",(0,a.jsxs)(n.p,{children:["We can use the supplied deploy hash, ",(0,a.jsx)(n.code,{children:"af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832"})," to find this contract using a block explorer. When viewed through the explorer, the status of the Deploy should be marked as ",(0,a.jsx)(n.code,{children:"Success"}),"."]}),"\n",(0,a.jsxs)(n.p,{children:["From your ",(0,a.jsx)(n.code,{children:"cspr.live"})," account, you will find a tab called ",(0,a.jsx)(n.code,{children:"NamedKeys"}),". This tab includes a list of all contracts deployed using the private key connected to your account."]}),"\n",(0,a.jsxs)(n.p,{children:["By clicking the contract hash, you can see all entry points included in the contract, as well as the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," under which your contract\u2019s name is stored. You should keep these named keys organized to avoid losing track while creating larger implementations."]}),"\n",(0,a.jsxs)(n.p,{children:["An additional tab, ",(0,a.jsx)(n.code,{children:"Deploys"}),", that is currently empty. If our contract included a cross-contract call that called an entry point from another contract, it would appear here. For now, we can note the hash of the contract, which is ",(0,a.jsx)(n.code,{children:"hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"cross-contract",children:"Create Another Contract for the Cross-Contract Call"}),"\n",(0,a.jsxs)(n.p,{children:["This section describes the process of writing an additional contract, which will use an entry point titled ",(0,a.jsx)(n.code,{children:"call_contract_2"})," to invoke the ",(0,a.jsx)(n.code,{children:"update_msg"})," entry point on the previous contract."]}),"\n",(0,a.jsxs)(n.p,{children:["In this tutorial we will be passing the contract hash, as an argument, into the ",(0,a.jsx)(n.code,{children:"call"})," entry point and use this to perform the calls to the destination contract."]}),"\n",(0,a.jsxs)(n.p,{children:["Prepare the ",(0,a.jsx)(n.code,{children:"call"})," entry point as described below:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create the list of required runtime arguments for the given entry point.\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let mut named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point metadata definition.\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in the global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n}\n\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This would be the easiest implementation of the ",(0,a.jsx)(n.code,{children:"call"})," entry point. There is only one entry point which accepts the key ",(0,a.jsx)(n.code,{children:"contract2"})," of type ",(0,a.jsx)(n.code,{children:"String"})," and the key ",(0,a.jsx)(n.code,{children:"hello_world_contract"})," of the type ",(0,a.jsx)(n.code,{children:"Key"}),". There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys."]}),"\n",(0,a.jsxs)(n.p,{children:["Now that we have defined the metadata for the ",(0,a.jsx)(n.code,{children:"call_contract_2"})," entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point ",(0,a.jsx)(n.code,{children:"update_msg"}),". It will then pass a message to the second contract as a parameter, which will be stored in that contract\u2019s context."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n // Get the value of the message from the second parameter \n let new_value: String = runtime::get_named_arg("new_message");\n\n // Call the update_msg entry point on the other contract with the parameter values\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n "message" => new_value,\n },\n );\n\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Your complete contract implementation should look as follows:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n#![no_std]\n#![no_main]\n\n#[cfg(not(target_arch = "wasm32"))]\ncompile_error!("target arch should be wasm32: compile with \'--target wasm32-unknown-unknown\'");\n\n// We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a\n// `no_std` environment.\nextern crate alloc;\n\n// The elementary types \nuse alloc::string::String;\nuse alloc::vec::Vec;\nuse crate::alloc::string::ToString;\nuse crate::runtime_args::RuntimeArgs;\n\n// Casper crates\nuse casper_types::{\n api_error::ApiError,\n contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};\n\nuse casper_contract::{\n unwrap_or_revert::UnwrapOrRevert,\n contract_api::{runtime, storage},\n};\n\n// The contract key in the account named keys\nconst CONTRACT_HASH: &str = "hello_world_contract";\n\n#[no_mangle]\npub extern "C" fn call_contract_2() {\n\n let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)\n .into_hash()\n .map(|hash| ContractHash::new(hash))\n .unwrap();\n\n let new_value: String = runtime::get_named_arg("new_message");\n\n let _: () = runtime::call_contract(\n contract_hash, \n "update_msg", \n runtime_args! {\n // key => value\n "message" => new_value,\n },\n );\n\n}\n\n#[no_mangle]\npub extern "C" fn call() {\n \n // Create a new vector - this will be the signature of the entrypoint\n let mut vec = Vec::new();\n vec.push(Parameter::new("new_message", CLType::String));\n vec.push(Parameter::new("hello_world_contract", CLType::Key));\n\n // In the named keys of the contract, add a key for the count.\n let named_keys = NamedKeys::new();\n\n // Create an Entry Point Object\n let mut entry_points = EntryPoints::new();\n\n // Add the entry point to the entry points object\n entry_points.add_entry_point(EntryPoint::new(\n "call_contract_2",\n vec,\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract\n ));\n\n // The contract is stored in global state\n let (stored_contract_hash, _contract_version) = storage::new_contract(\n entry_points, // entry points\n Some(named_keys), // named keys \n Some("contract2_package_name".to_string()), // package name\n Some("contract2_access_uref".to_string()) // access uref\n );\n\n // To access from the account - named keys of the account\n runtime::put_key("cross_contract_2", stored_contract_hash.into());\n\n}\n'})}),"\n",(0,a.jsxs)(n.p,{children:["After you run ",(0,a.jsx)(n.code,{children:"make build-contract"})," in your second contract's directory, you should obtain the outcome:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"cd contract && cargo build --release --target wasm32-unknown-unknown\n Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)\n Finished release [optimized] target(s) in 0.69s\nwasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n"})}),"\n",(0,a.jsxs)(n.p,{children:["Create the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder and copy the keys from the ",(0,a.jsx)(n.code,{children:"keys"})," subfolder in the first contract into this subfolder.\nThe call from the terminal will look as follows:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm\n"})}),"\n",(0,a.jsxs)(n.admonition,{type:"tip",children:[(0,a.jsxs)(n.p,{children:["You may have noticed that the contract.wasm is always output to the same filename for each new ",(0,a.jsx)(n.code,{children:"cargo casper"})," project. You can change this by editing the ",(0,a.jsx)(n.code,{children:"Makefile"})," in the main directory. You can then observe the result by recompiling your contract with these commands;"]}),(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})})]}),"\n",(0,a.jsx)(n.p,{children:"After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points."}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the ",(0,a.jsx)(n.code,{children:"put-deploy"})," subcommand is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7557689417621513622,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "faeb7e4f010c20c88d2dd126da545933c26fd8ce370282b8cd49f7f6fe7304b9"\n }\n}\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsx)(n.p,{children:"If the contract name doesn't change during concurrent deploys, the urefs/hashes will be overwritten in the account's named keys."})}),"\n",(0,a.jsx)(n.p,{children:"Observing the deploy, we can see that it succeeded:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832\n"})}),"\n",(0,a.jsxs)(n.p,{children:["In the ",(0,a.jsx)(n.code,{children:"execution_results"}),' JSON element we should see "Success".']}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'\n "execution_results": [\n {\n "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",\n "result": {\n "Success": {\n "cost": "16580565260",\n "effect": { ...\n \n }\n }\n }\n }\n ]\n\n'})}),"\n",(0,a.jsx)(n.p,{children:"Get the state root hash of the current network state:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://136.243.187.84:7777\n"})}),"\n",(0,a.jsxs)(n.p,{children:["The result of invoking the",(0,a.jsx)(n.code,{children:"get-state-root-hash"})," command is:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -3631326529646611302,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "state_root_hash": "2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Query the state of Casper network using the account hash:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:" casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9\n"})}),"\n",(0,a.jsx)(n.p,{children:"If we check the account's named keys, we can see all of the account's deployed contracts:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Account's named keys"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6842818667609668962,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[30424 hex chars]",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "weight": 1\n }\n ],\n "main_purse": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "named_keys": [\n {\n "key": "uref-94c54f24273f1fb874eff33f3d4211a254622edfd1b980d5e758bd719b46fd0d-007",\n "name": "Hello_world_access_uref"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "name": "Hello_world_package_name"\n },\n {\n "key": "uref-ae2f94bf959ec06a80b2035f31d7e4c65c01bf24bbbf794a473bc743c4b2f655-007",\n "name": "contract2_access_uref"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "name": "contract2_package_name"\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "name": "cross_contract_2"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "name": "hello_world_contract"\n }\n ]\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"As we have now managed to deploy two contracts, we can call the entry point of this contract, passing appropriate arguments to the function."}),"\n",(0,a.jsx)(n.p,{children:"The Uref of the message variable is stored under the Named Keys in the contract."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\n"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2434670480361972874,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[25224 hex chars]",\n "stored_value": {\n "Contract": {\n "contract_package_hash": "contract-package-wasm7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "contract_wasm_hash": "contract-wasm-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "entry_points": [\n {\n "access": "Public",\n "args": [\n {\n "cl_type": "String",\n "name": "message"\n }\n ],\n "entry_point_type": "Contract",\n "name": "update_msg",\n "ret": "Unit"\n }\n ],\n "named_keys": [\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-007",\n "name": "message"\n }\n ],\n "protocol_version": "1.4.13"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Checking the state of the message in the first contract, we observe the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsxs)(n.p,{children:["This is a simple ",(0,a.jsx)(n.code,{children:"hello world"})," string. After invoking the entry point using the command below this value should change."]}),"\n",(0,a.jsxs)(n.admonition,{type:"info",children:[(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-hash"})," - is the contract hash, which is returned from the put-deploy."]}),(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"--session-arg"}),' "hello world_contract:Key= ..." - the hash of the contract which we want to call from within the contract identified by the session-hash.']})]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy \\\n --node-address http://136.243.187.84:7777 \\\n --chain-name casper-test \\\n --secret-key ./keys/secret_key.pem \\\n --payment-amount 20000000000 \\\n --session-hash hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92 \\\n --session-entry-point "call_contract_2" \\\n --session-arg "new_message:string=\'Hello new message!\'" \\\n --session-arg "hello_world_contract:Key=\'hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea\'"\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"tip",children:(0,a.jsxs)(n.p,{children:["The contract hash has to be of type ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the contract itself. We can pass the hash as a ",(0,a.jsx)(n.code,{children:"Key"})," argument and change it to ",(0,a.jsx)(n.code,{children:"ContractHash"})," in the smart contract."]})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -6419793201665396463,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537"\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"Check the deploy with:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n --node-address http://136.243.187.84:7777 15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537\n"})}),"\n",(0,a.jsx)(n.p,{children:"After the deploy finishes successfully, you should see a similar outcome to the following:"}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:"Deploy details"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3968762702269106998,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "deploy": {\n "approvals": [\n {\n "signature": "01319eee9bcfde6963e5b47164dd2c8044f0c20dd59f0c2993db55bec6bd3802fec2c9c6cae6ca8993c8aee0440be43f6c38bdc4bbdce501837ff5ca66fbd7c902",\n "signer": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af"\n }\n ],\n "hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "header": {\n "account": "010e732fe2fbbcf62f2e46500d4cd8ff58a3bfd8dcb44c8b6f9a87dc5d573556af",\n "body_hash": "26282fa50b8e7c240025d683f197661ca846f2c1a3521a5dd604e6066d89d6d7",\n "chain_name": "casper-test",\n "dependencies": [],\n "gas_price": 1,\n "timestamp": "2023-03-09T14:39:24.974Z",\n "ttl": "30m"\n },\n "payment": {\n "ModuleBytes": {\n "args": [\n [\n "amount",\n {\n "bytes": "0500c817a804",\n "cl_type": "U512",\n "parsed": "20000000000"\n }\n ]\n ],\n "module_bytes": ""\n }\n },\n "session": {\n "StoredContractByHash": {\n "args": [\n [\n "new_message",\n {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n ],\n [\n "hello_world_contract",\n {\n "bytes": "01b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "cl_type": "Key",\n "parsed": {\n "Hash": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea"\n }\n }\n ]\n ],\n "entry_point": "call_contract_2",\n "hash": "32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92"\n }\n }\n },\n "execution_results": [\n {\n "block_hash": "9c81259ac5ef7b953656a9327a479ae771a15c5ef131c91216e9e697dfdb09eb",\n "result": {\n "Success": {\n "cost": "462273650",\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5",\n "transform": {\n "WriteCLValue": {\n "bytes": "0600876bf27301",\n "cl_type": "U512",\n "parsed": "1597500000000"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "20000000000"\n }\n },\n {\n "key": "hash-32ad0e54e874f68706708ebfd2c5aba7803eb64ccff71a50d3c4d4f29db15c92",\n "transform": "Identity"\n },\n {\n "key": "hash-a7810282c275d525f083a756aba6912513a4a494ae317503cf6018c0fbaf9c4d",\n "transform": "Identity"\n },\n {\n "key": "hash-b48ccc725ba948405d01205e64acff09ac24c899aed8d649f7bc1572216266c2",\n "transform": "Identity"\n },\n {\n "key": "hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea",\n "transform": "Identity"\n },\n {\n "key": "hash-7a581d353665b74779dc8d446d33a5086bb367a29a558490d1e524f9c12002d3",\n "transform": "Identity"\n },\n {\n "key": "hash-c0384d4041950780bd3b167b4516a306e308e2d4729d08f6d2b10dfa1dbdaad6",\n "transform": "Identity"\n },\n {\n "key": "uref-aa758090d9bc1364754180f9f6bfc8821275038fd5d794a5dfb60bd2838a8670-000",\n "transform": {\n "WriteCLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n },\n {\n "key": "deploy-15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "15e11340d92fc9e64deb38bd942f4efb69caad0851eec24fd577070309d18537",\n "from": "account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9",\n "gas": "462273650",\n "source": "uref-453534c5c380862c2d814b5879f08fe6b5a3d4f031eaf20e08cf091d274035a5-007",\n "transfers": []\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "bytes": "00",\n "cl_type": "U512",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-bb9f47c30ddbe192438fad10b7db8200247529d6592af7159d92c5f3aa7716a1",\n "transform": {\n "AddUInt512": "20000000000"\n }\n }\n ]\n },\n "transfers": []\n }\n }\n }\n ]\n }\n}\n'})}),"\n"]}),"\n",(0,a.jsx)(n.br,{}),(0,a.jsx)(n.br,{}),"\n",(0,a.jsx)(n.p,{children:"We would expect that the value of the message reference in the other contract would have changed, which we can check:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://136.243.187.84:7777 \\\n --state-root-hash 2f3e100324deb999107229dbec5c4b724653174328c99ea0836931248c3cc9cb \\\n --key hash-b7a06298cc71d4cac05929cc0713dfd5a541c68b71cb500cd04547b5cd0385ea -q "message"\n'})}),"\n",(0,a.jsx)(n.p,{children:"The output of the above command is:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -5477027327608594231,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.13",\n "block_header": null,\n "merkle_proof": "[61444 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "1200000048656c6c6f206e6577206d65737361676521",\n "cl_type": "String",\n "parsed": "Hello new message!"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.p,{children:"With this we have succeeded in cross-contract communication between two contracts."}),"\n",(0,a.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,a.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:"Developed two Rust contracts on a Casper network, where one smart contract is calling an entry point of the second smart contract"}),"\n",(0,a.jsx)(n.li,{children:"Called an entry point on one contract from the other contract, passing a value as an argument to this entry point."}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},94819:(e,n,t)=>{t.d(n,{A:()=>a});const a=t.p+"assets/images/CargoToml-0df722b819fb823a4a14d90b45076240.png"},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const c={},s=a.createContext(c);function r(e){const n=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:r(e.components),a.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/de33ad21.8fafd612.js b/assets/js/de33ad21.8fafd612.js new file mode 100644 index 000000000..5459c9f2d --- /dev/null +++ b/assets/js/de33ad21.8fafd612.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[50196],{20448:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>n,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>d});var t=r(74848),c=r(28453);const a={},n="Essential Rust Crates",i={id:"developers/essential-crates",title:"Essential Rust Crates",description:"Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.",source:"@site/versioned_docs/version-2.0.0/developers/essential-crates.md",sourceDirName:"developers",slug:"/developers/essential-crates",permalink:"/2.0.0/developers/essential-crates",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Development Prerequisites",permalink:"/2.0.0/developers/prerequisites"},next:{title:"Introduction",permalink:"/2.0.0/writing-contracts"}},l={},d=[{value:"<code>casper-types</code>",id:"casper-types",level:2},{value:"<code>casper-contract</code>",id:"casper-contract",level:2},{value:"<code>casper-engine-test-support</code>",id:"casper-engine-test-support",level:2},{value:"<code>casper-node</code>",id:"casper-node",level:2},{value:"<code>casper-client</code>",id:"casper-client",level:2},{value:"<code>casper-event-standard</code>",id:"casper-event-standard",level:2},{value:"<code>casper-hashing</code>",id:"casper-hashing",level:2},{value:"<code>casper-wasm-utils</code>",id:"casper-wasm-utils",level:2},{value:"<code>cargo-casper</code>",id:"cargo-casper",level:2},{value:"Other Libraries",id:"other-libraries",level:2}];function o(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,c.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.header,{children:(0,t.jsx)(s.h1,{id:"essential-rust-crates",children:"Essential Rust Crates"})}),"\n",(0,t.jsxs)(s.p,{children:["Several Rust crates are available on ",(0,t.jsx)(s.a,{href:"https://crates.io/",children:"crates.io"})," to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on ",(0,t.jsx)(s.a,{href:"https://docs.rs",children:"docs.rs"}),". The most important crates are listed below."]}),"\n",(0,t.jsx)(s.h2,{id:"casper-types",children:(0,t.jsx)(s.code,{children:"casper-types"})}),"\n",(0,t.jsx)(s.p,{children:"Types shared by many Casper crates:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-types",children:"https://crates.io/crates/casper-types"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-types/latest",children:"https://docs.rs/casper-types/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-contract",children:(0,t.jsx)(s.code,{children:"casper-contract"})}),"\n",(0,t.jsx)(s.p,{children:"A library for developing Casper smart contracts:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-contract",children:"https://crates.io/crates/casper-contract"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-contract/latest",children:"https://docs.rs/casper-contract/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-engine-test-support",children:(0,t.jsx)(s.code,{children:"casper-engine-test-support"})}),"\n",(0,t.jsx)(s.p,{children:"The Casper test support library:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-engine-test-support",children:"https://crates.io/crates/casper-engine-test-support"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-engine-test-support/",children:"https://docs.rs/casper-engine-test-support/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-node",children:(0,t.jsx)(s.code,{children:"casper-node"})}),"\n",(0,t.jsx)(s.p,{children:"The component for running a node on a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-node",children:"https://crates.io/crates/casper-node"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-node/latest",children:"https://docs.rs/casper-node/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-client",children:(0,t.jsx)(s.code,{children:"casper-client"})}),"\n",(0,t.jsx)(s.p,{children:"A client library for interacting with a Casper network:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-client",children:"https://crates.io/crates/casper-client"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-client/latest",children:"https://docs.rs/casper-client/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-event-standard",children:(0,t.jsx)(s.code,{children:"casper-event-standard"})}),"\n",(0,t.jsx)(s.p,{children:"A Rust library that provides a simple and standardized way for Casper contracts to emit events:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-event-standard",children:"https://crates.io/crates/casper-event-standard"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-event-standard/latest",children:"https://docs.rs/casper-event-standard/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-hashing",children:(0,t.jsx)(s.code,{children:"casper-hashing"})}),"\n",(0,t.jsx)(s.p,{children:"A library providing hashing functionality including Merkle Proof utilities:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-hashing",children:"https://crates.io/crates/casper-hashing"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-hashing/latest/",children:"https://docs.rs/casper-hashing/latest/"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"casper-wasm-utils",children:(0,t.jsx)(s.code,{children:"casper-wasm-utils"})}),"\n",(0,t.jsx)(s.p,{children:"Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/casper-wasm-utils",children:"https://crates.io/crates/casper-wasm-utils"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/casper-wasm-utils/latest",children:"https://docs.rs/casper-wasm-utils/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"cargo-casper",children:(0,t.jsx)(s.code,{children:"cargo-casper"})}),"\n",(0,t.jsx)(s.p,{children:"A command line tool for creating a Wasm smart contract and tests:"}),"\n",(0,t.jsxs)(s.ul,{children:["\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://crates.io/crates/cargo-casper",children:"https://crates.io/crates/cargo-casper"})}),"\n",(0,t.jsx)(s.li,{children:(0,t.jsx)(s.a,{href:"https://docs.rs/crate/cargo-casper/latest",children:"https://docs.rs/crate/cargo-casper/latest"})}),"\n"]}),"\n",(0,t.jsx)(s.h2,{id:"other-libraries",children:"Other Libraries"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.a,{href:"/2.0.0/resources/build-on-casper/casper-open-source-software",children:"Open-Source Software"})," page provides other community-curated tools and libraries."]})]})}function p(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>n,x:()=>i});var t=r(96540);const c={},a=t.createContext(c);function n(e){const s=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function i(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:n(e.components),t.createElement(a.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df5bc763.577a5deb.js b/assets/js/df5bc763.577a5deb.js new file mode 100644 index 000000000..1e63e2f05 --- /dev/null +++ b/assets/js/df5bc763.577a5deb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[34555],{23946:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const i={},s="Overview",c={id:"resources/beginner/counter/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/overview.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/overview",permalink:"/1.5.X/resources/beginner/counter/overview",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/1.5.X/counter"},next:{title:"Casper-Client Commands",permalink:"/1.5.X/resources/beginner/counter/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(21909).A+"",width:"1166",height:"614"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},21909:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-2f7c7ea9d18c57e4cd8b8d010eee38fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const o={},i=r.createContext(o);function s(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/df5bc763.837d978f.js b/assets/js/df5bc763.837d978f.js deleted file mode 100644 index 29e1167e8..000000000 --- a/assets/js/df5bc763.837d978f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4555],{23946:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>c,toc:()=>u});var r=n(74848),o=n(28453);const i={},s="Overview",c={id:"resources/beginner/counter/overview",title:"Overview",description:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.",source:"@site/versioned_docs/version-1.5.X/resources/beginner/counter/overview.md",sourceDirName:"resources/beginner/counter",slug:"/resources/beginner/counter/overview",permalink:"/resources/beginner/counter/overview",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/counter"},next:{title:"Casper-Client Commands",permalink:"/resources/beginner/counter/commands"}},a={},u=[];function l(e){const t={h1:"h1",header:"header",img:"img",p:"p",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"overview",children:"Overview"})}),"\n",(0,r.jsx)(t.p,{children:"This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own."}),"\n",(0,r.jsx)(t.p,{children:"To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter."}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"image",src:n(76371).A+"",width:"1166",height:"614"})})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},76371:(e,t,n)=>{n.d(t,{A:()=>r});const r=n.p+"assets/images/counter-overview-2f7c7ea9d18c57e4cd8b8d010eee38fc.png"},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>c});var r=n(96540);const o={},i=r.createContext(o);function s(e){const t=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function c(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),r.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfbc8a55.1e3a65ca.js b/assets/js/dfbc8a55.1e3a65ca.js deleted file mode 100644 index 4b327d7fa..000000000 --- a/assets/js/dfbc8a55.1e3a65ca.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[3307],{53301:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var n=r(74848),a=r(28453);const s={title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},o="Reading and Writing to Global State using Rust",i={id:"resources/advanced/storage-workflow",title:"Storage Workflow",description:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.",source:"@site/docs/resources/advanced/storage-workflow.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/storage-workflow",permalink:"/next/resources/tutorials/advanced/storage-workflow",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},sidebar:"tutorials",previous:{title:"Token Transfers",permalink:"/next/resources/tutorials/advanced/transfer-token-to-contract"},next:{title:"Cross-Contract Communication",permalink:"/next/resources/tutorials/advanced/cross-contract"}},c={},d=[{value:"Description of Functions",id:"description-of-functions",level:2},{value:"<code>runtime::put_key</code> / <code>runtime::get_key</code>",id:"runtimeput_key--runtimeget_key",level:3},{value:"<code>storage::write</code> / <code>storage::read</code>",id:"storagewrite--storageread",level:3},{value:"<code>storage:dictionary_put</code> / <code>storage::dictionary_get</code>",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of <code>put_key</code> and <code>storage::write</code>",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of <code>get_key</code> and <code>storage::read</code>",id:"example-of-get_key-and-storageread",level:3},{value:"Example of <code>dictionary_put</code> and <code>dictionary_get</code>",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"reading-and-writing-to-global-state-using-rust",children:"Reading and Writing to Global State using Rust"})}),"\n",(0,n.jsx)(t.p,{children:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."}),"\n",(0,n.jsxs)(t.p,{children:["Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,n.jsx)(t.code,{children:"runtime::put_key"}),", ",(0,n.jsx)(t.code,{children:"storage::write"}),"(alongside ",(0,n.jsx)(t.code,{children:"storage::new_uref"})," as explained below) and ",(0,n.jsx)(t.code,{children:"storage::dictionary_put"}),". These stored values can be read using ",(0,n.jsx)(t.code,{children:"runtime::get_key"}),", ",(0,n.jsx)(t.code,{children:"storage::read"})," and ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"}),", respectively. Each method stores data in a specific way, and it's important to understand the differences."]}),"\n",(0,n.jsx)(t.h2,{id:"description-of-functions",children:"Description of Functions"}),"\n",(0,n.jsxs)(t.h3,{id:"runtimeput_key--runtimeget_key",children:[(0,n.jsx)(t.code,{children:"runtime::put_key"})," / ",(0,n.jsx)(t.code,{children:"runtime::get_key"})]}),"\n",(0,n.jsxs)(t.p,{children:["Both the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:(0,n.jsx)(t.code,{children:"put_key"})})," and ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:(0,n.jsx)(t.code,{children:"get_key"})})," functions refer to Casper ",(0,n.jsx)(t.code,{children:"Key"})," types as outlined in both the ",(0,n.jsx)(t.a,{href:"/next/concepts/key-types",children:"Understanding Hash Types"})," and ",(0,n.jsx)(t.a,{href:"/next/concepts/serialization/types#serialization-standard-state-keys",children:"Serialization Standard"}),". These keys are stored within a URef as a ",(0,n.jsx)(t.code,{children:"Key"})," type."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagewrite--storageread",children:[(0,n.jsx)(t.code,{children:"storage::write"})," / ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:(0,n.jsx)(t.code,{children:"storage::write"})})," writes a given value to a previously established URef (created using ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:(0,n.jsx)(t.code,{children:"storage::new_uref"})}),"). Unlike ",(0,n.jsx)(t.code,{children:"put_key"}),", this value is not one of the ",(0,n.jsx)(t.code,{children:"Key"})," types listed above, but rather any of the potential ",(0,n.jsx)(t.a,{href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype",children:(0,n.jsx)(t.code,{children:"CLType"})}),"s as outlined. ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:(0,n.jsx)(t.code,{children:"storage::read"})})," provides a method to retrieve these values from the associated URef."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagedictionary_put--storagedictionary_get",children:[(0,n.jsx)(t.code,{children:"storage:dictionary_put"})," / ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,n.jsx)(t.code,{children:"NamedKeys"}),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."]}),"\n",(0,n.jsxs)(t.p,{children:["More information on dictionaries can be found on the ",(0,n.jsx)(t.a,{href:"/next/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," page."]}),"\n",(0,n.jsx)(t.h2,{id:"example-code",children:"Example Code"}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-put_key-and-storagewrite",children:["Example of ",(0,n.jsx)(t.code,{children:"put_key"})," and ",(0,n.jsx)(t.code,{children:"storage::write"})]}),"\n",(0,n.jsxs)(t.p,{children:["This sample code creates a new contract and stores the contract hash in global state using the ",(0,n.jsx)(t.code,{children:"runtime::put_key"})," function."]}),"\n",(0,n.jsxs)(t.p,{children:["Once the stored value has been initialized, the ",(0,n.jsx)(t.code,{children:"storage::write"})," function overwrites the existing value with ",(0,n.jsx)(t.code,{children:"true"}),". The URef is then stored in the current context as a ",(0,n.jsx)(t.code,{children:"NamedKey"})," titled ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-get_key-and-storageread",children:["Example of ",(0,n.jsx)(t.code,{children:"get_key"})," and ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:["This example compliments the code sample above by retrieving the ",(0,n.jsx)(t.code,{children:"CONTRACT_HASH"})," using the ",(0,n.jsx)(t.code,{children:"get_key"})," function, before comparing a provided runtime argument ",(0,n.jsx)(t.code,{children:"ARG_MY_STORED_VALUE"})," against the previously stored ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"})," using ",(0,n.jsx)(t.code,{children:"storage::read"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-dictionary_put-and-dictionary_get",children:["Example of ",(0,n.jsx)(t.code,{children:"dictionary_put"})," and ",(0,n.jsx)(t.code,{children:"dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["Examples of dictionary usage for storage can be found in the ",(0,n.jsx)(t.em,{children:"Writing Entries into a Dictionary"})," section of ",(0,n.jsx)(t.a,{href:"/next/concepts/dictionaries#writing-entries-into-a-dictionary",children:"Reading and Writing to Dictionaries"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"additional-functions-for-named-keys",children:"Additional Functions for Named Keys"}),"\n",(0,n.jsx)(t.p,{children:"The following functions might also be of interest for working with named keys:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html",children:"list_named_keys"})," - Returns the named keys of the current context"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html",children:"has_key"})," - Returns true if the key exists in the current context\u2019s named keys"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html",children:"remove_key"})," - Removes the requested ",(0,n.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfbc8a55.270b4583.js b/assets/js/dfbc8a55.270b4583.js new file mode 100644 index 000000000..ea08a9935 --- /dev/null +++ b/assets/js/dfbc8a55.270b4583.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[53307],{53301:(e,t,r)=>{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>s,metadata:()=>i,toc:()=>d});var n=r(74848),a=r(28453);const s={title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},o="Reading and Writing to Global State using Rust",i={id:"resources/advanced/storage-workflow",title:"Storage Workflow",description:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.",source:"@site/docs/resources/advanced/storage-workflow.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/storage-workflow",permalink:"/resources/tutorials/advanced/storage-workflow",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{title:"Storage Workflow",slug:"/resources/tutorials/advanced/storage-workflow"},sidebar:"tutorials",previous:{title:"Token Transfers",permalink:"/resources/tutorials/advanced/transfer-token-to-contract"},next:{title:"Cross-Contract Communication",permalink:"/resources/tutorials/advanced/cross-contract"}},c={},d=[{value:"Description of Functions",id:"description-of-functions",level:2},{value:"<code>runtime::put_key</code> / <code>runtime::get_key</code>",id:"runtimeput_key--runtimeget_key",level:3},{value:"<code>storage::write</code> / <code>storage::read</code>",id:"storagewrite--storageread",level:3},{value:"<code>storage:dictionary_put</code> / <code>storage::dictionary_get</code>",id:"storagedictionary_put--storagedictionary_get",level:3},{value:"Example Code",id:"example-code",level:2},{value:"Example of <code>put_key</code> and <code>storage::write</code>",id:"example-of-put_key-and-storagewrite",level:3},{value:"Example of <code>get_key</code> and <code>storage::read</code>",id:"example-of-get_key-and-storageread",level:3},{value:"Example of <code>dictionary_put</code> and <code>dictionary_get</code>",id:"example-of-dictionary_put-and-dictionary_get",level:3},{value:"Additional Functions for Named Keys",id:"additional-functions-for-named-keys",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"reading-and-writing-to-global-state-using-rust",children:"Reading and Writing to Global State using Rust"})}),"\n",(0,n.jsx)(t.p,{children:"The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language."}),"\n",(0,n.jsxs)(t.p,{children:["Essentially, there are three means of storage within the Casper ecosystem. These consist of ",(0,n.jsx)(t.code,{children:"runtime::put_key"}),", ",(0,n.jsx)(t.code,{children:"storage::write"}),"(alongside ",(0,n.jsx)(t.code,{children:"storage::new_uref"})," as explained below) and ",(0,n.jsx)(t.code,{children:"storage::dictionary_put"}),". These stored values can be read using ",(0,n.jsx)(t.code,{children:"runtime::get_key"}),", ",(0,n.jsx)(t.code,{children:"storage::read"})," and ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"}),", respectively. Each method stores data in a specific way, and it's important to understand the differences."]}),"\n",(0,n.jsx)(t.h2,{id:"description-of-functions",children:"Description of Functions"}),"\n",(0,n.jsxs)(t.h3,{id:"runtimeput_key--runtimeget_key",children:[(0,n.jsx)(t.code,{children:"runtime::put_key"})," / ",(0,n.jsx)(t.code,{children:"runtime::get_key"})]}),"\n",(0,n.jsxs)(t.p,{children:["Both the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.put_key.html",children:(0,n.jsx)(t.code,{children:"put_key"})})," and ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.get_key.html",children:(0,n.jsx)(t.code,{children:"get_key"})})," functions refer to Casper ",(0,n.jsx)(t.code,{children:"Key"})," types as outlined in both the ",(0,n.jsx)(t.a,{href:"/concepts/key-types",children:"Understanding Hash Types"})," and ",(0,n.jsx)(t.a,{href:"/concepts/serialization/types#serialization-standard-state-keys",children:"Serialization Standard"}),". These keys are stored within a URef as a ",(0,n.jsx)(t.code,{children:"Key"})," type."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagewrite--storageread",children:[(0,n.jsx)(t.code,{children:"storage::write"})," / ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.write.html",children:(0,n.jsx)(t.code,{children:"storage::write"})})," writes a given value to a previously established URef (created using ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_uref.html",children:(0,n.jsx)(t.code,{children:"storage::new_uref"})}),"). Unlike ",(0,n.jsx)(t.code,{children:"put_key"}),", this value is not one of the ",(0,n.jsx)(t.code,{children:"Key"})," types listed above, but rather any of the potential ",(0,n.jsx)(t.a,{href:"https://docs.casperlabs.io/developers/json-rpc/types_cl/#cltype",children:(0,n.jsx)(t.code,{children:"CLType"})}),"s as outlined. ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.read.html",children:(0,n.jsx)(t.code,{children:"storage::read"})})," provides a method to retrieve these values from the associated URef."]}),"\n",(0,n.jsxs)(t.h3,{id:"storagedictionary_put--storagedictionary_get",children:[(0,n.jsx)(t.code,{children:"storage:dictionary_put"})," / ",(0,n.jsx)(t.code,{children:"storage::dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["For most data storage needs on a Casper network, dictionaries are more efficient and provide lower gas costs than ",(0,n.jsx)(t.code,{children:"NamedKeys"}),". Each dictionary item exists independently, sharing a single dictionary seed URef for reference purposes."]}),"\n",(0,n.jsxs)(t.p,{children:["More information on dictionaries can be found on the ",(0,n.jsx)(t.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," page."]}),"\n",(0,n.jsx)(t.h2,{id:"example-code",children:"Example Code"}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-put_key-and-storagewrite",children:["Example of ",(0,n.jsx)(t.code,{children:"put_key"})," and ",(0,n.jsx)(t.code,{children:"storage::write"})]}),"\n",(0,n.jsxs)(t.p,{children:["This sample code creates a new contract and stores the contract hash in global state using the ",(0,n.jsx)(t.code,{children:"runtime::put_key"})," function."]}),"\n",(0,n.jsxs)(t.p,{children:["Once the stored value has been initialized, the ",(0,n.jsx)(t.code,{children:"storage::write"})," function overwrites the existing value with ",(0,n.jsx)(t.code,{children:"true"}),". The URef is then stored in the current context as a ",(0,n.jsx)(t.code,{children:"NamedKey"})," titled ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n // Store contract hash under a Named key CONTRACT_HASH\n runtime::put_key(CONTRACT_HASH, contract_hash.into());\n\n // Store !MY_STORED_VALUE (false) as init value/type into a new URef\n let my_value_uref = storage::new_uref(!MY_STORED_VALUE);\n\n // Store MY_STORED_VALUE (true) under the URef value\n storage::write(my_value_uref, MY_STORED_VALUE);\n\n // Store the Uref under a Named key MY_STORED_VALUE_UREF\n let my_value_key: Key = my_value_uref.into();\n runtime::put_key(MY_STORED_VALUE_UREF, my_value_key);\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-get_key-and-storageread",children:["Example of ",(0,n.jsx)(t.code,{children:"get_key"})," and ",(0,n.jsx)(t.code,{children:"storage::read"})]}),"\n",(0,n.jsxs)(t.p,{children:["This example compliments the code sample above by retrieving the ",(0,n.jsx)(t.code,{children:"CONTRACT_HASH"})," using the ",(0,n.jsx)(t.code,{children:"get_key"})," function, before comparing a provided runtime argument ",(0,n.jsx)(t.code,{children:"ARG_MY_STORED_VALUE"})," against the previously stored ",(0,n.jsx)(t.code,{children:"MY_STORED_VALUE_UREF"})," using ",(0,n.jsx)(t.code,{children:"storage::read"}),"."]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-rust",children:"\n let my_stored_value_uref: URef = runtime::get_key(MY_STORED_VALUE_UREF)\n .unwrap_or_revert()\n .into_uref()\n .map(|uref| URef::new(uref.addr(), AccessRights::default()))\n .unwrap_or_revert()\n .into_read();\n\n let my_actual_stored_value: bool = storage::read(my_stored_value_uref).unwrap().unwrap();\n\n // Compare my stored value with runtime arg\n let my_expected_stored_value: bool = runtime::get_named_arg(ARG_MY_STORED_VALUE);\n if my_actual_stored_value != my_expected_stored_value {\n // We revert if my stored value is not what is expected from caller argument\n runtime::revert(UserError::StoredValueError);\n }\n\n runtime::print(&my_actual_stored_value.to_string());\n}\n\n"})}),"\n",(0,n.jsxs)(t.h3,{id:"example-of-dictionary_put-and-dictionary_get",children:["Example of ",(0,n.jsx)(t.code,{children:"dictionary_put"})," and ",(0,n.jsx)(t.code,{children:"dictionary_get"})]}),"\n",(0,n.jsxs)(t.p,{children:["Examples of dictionary usage for storage can be found in the ",(0,n.jsx)(t.em,{children:"Writing Entries into a Dictionary"})," section of ",(0,n.jsx)(t.a,{href:"/concepts/dictionaries#writing-entries-into-a-dictionary",children:"Reading and Writing to Dictionaries"}),"."]}),"\n",(0,n.jsx)(t.h2,{id:"additional-functions-for-named-keys",children:"Additional Functions for Named Keys"}),"\n",(0,n.jsx)(t.p,{children:"The following functions might also be of interest for working with named keys:"}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_named_keys.html",children:"list_named_keys"})," - Returns the named keys of the current context"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.has_key.html",children:"has_key"})," - Returns true if the key exists in the current context\u2019s named keys"]}),"\n",(0,n.jsxs)(t.li,{children:[(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.remove_key.html",children:"remove_key"})," - Removes the requested ",(0,n.jsx)(t.code,{children:"NamedKey"})," from the current context"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(l,{...e})}):l(e)}},28453:(e,t,r)=>{r.d(t,{R:()=>o,x:()=>i});var n=r(96540);const a={},s=n.createContext(a);function o(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function i(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfcc4619.0ab89293.js b/assets/js/dfcc4619.0ab89293.js deleted file mode 100644 index 828d37e4c..000000000 --- a/assets/js/dfcc4619.0ab89293.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7083],{54972:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(74848),s=n(28453);const r={},a="Binary Serialization Standard {#serialization-standard-head}",o={id:"concepts/serialization/index",title:"Binary Serialization Standard",description:"serialization-standard-head}",source:"@site/docs/concepts/serialization/index.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/",permalink:"/next/concepts/serialization/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Z",permalink:"/next/concepts/glossary/Z"},next:{title:"Primitives and Basic Serialization Rules",permalink:"/next/concepts/serialization/primitives"}},d={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"serialization-standard-head",children:"Binary Serialization Standard"})}),"\n",(0,i.jsx)(t.p,{children:"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Casper Binary Serialization Standard"})," uses a default ",(0,i.jsx)(t.code,{children:"u8"})," byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Page"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/next/concepts/serialization/primitives",children:"Primitives"})}),(0,i.jsx)(t.td,{children:"Base-level types used to create more complex structures."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/next/concepts/serialization/structures",children:"Structures"})}),(0,i.jsx)(t.td,{children:"Major structures used through Casper systems, as well as their included sub-types."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/next/concepts/serialization/types",children:"Types"})}),(0,i.jsxs)(t.td,{children:["Minor types not covered ",(0,i.jsx)(t.code,{children:"Primitives"})," or ",(0,i.jsx)(t.code,{children:"Structures"}),"."]})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/dfcc4619.c764dc8b.js b/assets/js/dfcc4619.c764dc8b.js new file mode 100644 index 000000000..442c91e8a --- /dev/null +++ b/assets/js/dfcc4619.c764dc8b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7083],{54972:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(74848),s=n(28453);const r={},a="Binary Serialization Standard {#serialization-standard-head}",o={id:"concepts/serialization/index",title:"Binary Serialization Standard",description:"serialization-standard-head}",source:"@site/docs/concepts/serialization/index.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/",permalink:"/concepts/serialization/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Z",permalink:"/concepts/glossary/Z"},next:{title:"Primitives and Basic Serialization Rules",permalink:"/concepts/serialization/primitives"}},d={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"serialization-standard-head",children:"Binary Serialization Standard"})}),"\n",(0,i.jsx)(t.p,{children:"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Casper Binary Serialization Standard"})," uses a default ",(0,i.jsx)(t.code,{children:"u8"})," byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Page"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/concepts/serialization/primitives",children:"Primitives"})}),(0,i.jsx)(t.td,{children:"Base-level types used to create more complex structures."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/concepts/serialization/structures",children:"Structures"})}),(0,i.jsx)(t.td,{children:"Major structures used through Casper systems, as well as their included sub-types."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/concepts/serialization/types",children:"Types"})}),(0,i.jsxs)(t.td,{children:["Minor types not covered ",(0,i.jsx)(t.code,{children:"Primitives"})," or ",(0,i.jsx)(t.code,{children:"Structures"}),"."]})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e068c333.4084d666.js b/assets/js/e068c333.4084d666.js new file mode 100644 index 000000000..26fae0ab4 --- /dev/null +++ b/assets/js/e068c333.4084d666.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[43886],{17502:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var s=a(74848),t=a(28453);const r={title:"Querying Global State"},c="Querying Global State",d={id:"developers/cli/querying-global-state",title:"Querying Global State",description:"This page explains how to query global state to find account, contract, and package details.",source:"@site/versioned_docs/version-2.0.0/developers/cli/querying-global-state.md",sourceDirName:"developers/cli",slug:"/developers/cli/querying-global-state",permalink:"/2.0.0/developers/cli/querying-global-state",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Querying Global State"},sidebar:"developers",previous:{title:"Verifying Contracts",permalink:"/2.0.0/developers/cli/verifying-contracts"},next:{title:"Calling Contracts",permalink:"/2.0.0/developers/cli/calling-contracts"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Getting the State Root Hash",id:"get-state-root-hash",level:2},{value:"Querying an Account",id:"querying-an-account",level:2},{value:"Querying a Contract",id:"querying-a-contract",level:2},{value:"Querying a Package",id:"querying-a-package",level:2},{value:"Querying a Named Key",id:"querying-a-named-key",level:2},{value:"Query a value using the contract address hash and its named key",id:"query-a-value-using-the-contract-address-hash-and-its-named-key",level:3},{value:"Query a value using the account hash and its named key",id:"query-a-value-using-the-account-hash-and-its-named-key",level:3},{value:"What's Next?",id:"whats-next",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"querying-global-state",children:"Querying Global State"})}),"\n",(0,s.jsx)(n.p,{children:"This page explains how to query global state to find account, contract, and package details."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["You have an account and have ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/installing-contracts",children:"installed a contract"})," on a Casper network."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"get-state-root-hash",children:"Getting the State Root Hash"}),"\n",(0,s.jsx)(n.p,{children:"The first step in querying global state is obtaining the state root hash, which acts as an identifier for the current state of the network. It is like a Git commit ID for commit history, providing a snapshot of the blockchain state at a specific time."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"After sending transactions to the network, it's necessary to fetch the new state root hash to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state."})}),"\n",(0,s.jsxs)(n.p,{children:["To get the state root hash, use the ",(0,s.jsx)(n.code,{children:"get-state-root-hash"})," command:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://localhost:11101\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -4225403855447288375,\n "result": {\n "api_version": "2.0.0",\n "state_root_hash": "6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"querying-an-account",children:"Querying an Account"}),"\n",(0,s.jsx)(n.p,{children:"To find your account details, start by querying global state using the account hash. The response will contain the entity account identifier, needed to query more details about the account. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [ACCOUNT_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 2591514718461273084,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "Key",\n "bytes": "11016a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "parsed": "entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n },\n "merkle_proof": "[2566 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Next, see more account details using the ",(0,s.jsx)(n.code,{children:"get-entity"})," command and the entity identifier or the account hash. Both commands will produce the same output. You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample requests:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:"OR"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsx)(n.p,{children:'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.'}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 4470312592511523509,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "Account": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n },\n "package_hash": "package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51",\n "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",\n "main_purse": "uref-21dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f1-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "counter",\n "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n },\n {\n "name": "counter_access_uref",\n "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"\n },\n {\n "name": "counter_package_name",\n "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"\n },\n {\n "name": "version",\n "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"\n }\n ],\n "entry_points": []\n }\n },\n "merkle_proof": "[3010 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.br,{}),(0,s.jsx)(n.br,{})]}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsx)(n.p,{children:"If you don't know your account hash, run this command:"}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]\n"})})]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-contract",children:"Querying a Contract"}),"\n",(0,s.jsxs)(n.p,{children:["Query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"query-global-state"}),' command. The contract is stored under the account\'s named keys, with the key named "counter" and identifier ',(0,s.jsx)(n.code,{children:"entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"}),". The output will contain the contract's ",(0,s.jsx)(n.code,{children:"package_hash"}),", ",(0,s.jsx)(n.code,{children:"main_purse"}),", ",(0,s.jsx)(n.code,{children:"associated_keys"}),", and ",(0,s.jsx)(n.code,{children:"action_thresholds"}),", but will not contain further details such as the contract's named keys and entry points. You will need to run the ",(0,s.jsx)(n.code,{children:"get-entity"})," command instead for those details."]}),"\n",(0,s.jsxs)(n.p,{children:["For the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command, you will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the contract address hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"\n'})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -750547909804067196,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "AddressableEntity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Next, query global state given the contract identifier and the ",(0,s.jsx)(n.code,{children:"get-entity"})," command, which will provide more details such as the contract's ",(0,s.jsx)(n.code,{children:"entry_points"})," and ",(0,s.jsx)(n.code,{children:"named_keys"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"entity identifier"})," for an addressable entity or an account. This can be an entity hash, a public key, or an account hash."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--entity-identifier [FORMATTED_STRING_OR_PATH]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-entity \\\n--node-address http://localhost:11101 \\\n--entity-identifier entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -530362264865678930,\n "result": {\n "api_version": "2.0.0",\n "entity": {\n "AddressableEntity": {\n "entity": {\n "protocol_version": "2.0.0",\n "entity_kind": {\n "SmartContract": "VmCasperV1"\n },\n "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",\n "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",\n "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",\n "associated_keys": [\n {\n "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",\n "weight": 1\n }\n ],\n "action_thresholds": {\n "deployment": 1,\n "upgrade_management": 1,\n "key_management": 1\n },\n "message_topics": []\n },\n "named_keys": [\n {\n "name": "count",\n "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"\n }\n ],\n "entry_points": [\n {\n "V1CasperVm": {\n "name": "counter_get",\n "args": [],\n "ret": "I32",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n },\n {\n "V1CasperVm": {\n "name": "counter_inc",\n "args": [],\n "ret": "Unit",\n "access": "Public",\n "entry_point_type": "Called",\n "entry_point_payment": "Caller"\n }\n }\n ]\n }\n },\n "merkle_proof": "[1508 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-package",children:"Querying a Package"}),"\n",(0,s.jsx)(n.p,{children:"You can query information about a package, given its package hash. You will need the following information:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query, which in this case would be the package identifier."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [PACKAGE_ADDRESS]\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample request:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51\n"})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Sample response:"})}),"\n",(0,s.jsxs)(n.p,{children:["The response would contain the ",(0,s.jsx)(n.code,{children:"addressable_entity_hash"}),", the ",(0,s.jsx)(n.code,{children:"lock_status"})," for the ",(0,s.jsx)(n.code,{children:"Package"}),", and the current ",(0,s.jsx)(n.code,{children:"entity_version"}),"."]}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Expand to see the sample response"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "jsonrpc": "2.0",\n "id": -8280509649720542989,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "Package": {\n "versions": [\n {\n "entity_version_key": {\n "protocol_version_major": 2,\n "entity_version": 1\n },\n "addressable_entity_hash": "addressable-entity-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"\n }\n ],\n "disabled_versions": [],\n "groups": [],\n "lock_status": "Unlocked"\n }\n },\n "merkle_proof": "[2934 hex chars]"\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"querying-a-named-key",children:"Querying a Named Key"}),"\n",(0,s.jsxs)(n.p,{children:["You can dive into the data stored in global state using the optional query path argument ",(0,s.jsx)(n.code,{children:"-q"})," or ",(0,s.jsx)(n.code,{children:"--query-path"}),". You will need the following information:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"node address"}),", representing an IP address of a peer on the network."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"state root hash"}),", as a hex-encoded hash of the state root."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.strong,{children:"key"})," identifier for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, deploy-info hash,era-info number, bid, withdraw or dictionary address."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.strong,{children:"query path"}),", entered in this instance as ",(0,s.jsx)(n.code,{children:"q"}),", which is an optional query path argument that allows you to drill into the specifics of a query with respect to the key."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [HASH_STRING] \\\n-q "PATH_FROM_KEY"\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-contract-address-hash-and-its-named-key",children:"Query a value using the contract address hash and its named key"}),"\n",(0,s.jsxs)(n.p,{children:["Next, you can query a named key associated with the contract using the ",(0,s.jsx)(n.code,{children:"query-global-state"})," command and the ",(0,s.jsx)(n.code,{children:"-q"})," option."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash [STATE_ROOT_HASH] \\\n--key [CONTRACT_ADDRESS_HASH] \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n--node-address http://localhost:11101 \\\n--state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n--key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68" \\\n-q "count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -672620332620630019,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[7272 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"query-a-value-using-the-account-hash-and-its-named-key",children:"Query a value using the account hash and its named key"}),"\n",(0,s.jsx)(n.p,{children:'It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash [STATE_ROOT_HASH] \\\n --key [ACCOUNT_HASH] \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample request"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state \\\n --node-address http://localhost:11101 \\\n --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \\\n --key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463 \\\n -q "counter/count"\n'})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Sample response"}),":"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -8997536139716357387,\n "result": {\n "api_version": "2.0.0",\n "block_header": null,\n "stored_value": {\n "CLValue": {\n "cl_type": "I32",\n "bytes": "00000000",\n "parsed": 0\n }\n },\n "merkle_proof": "[14486 hex chars]"\n }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["Learn ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/calling-contracts",children:"different ways to call contracts"})," using the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>c,x:()=>d});var s=a(96540);const t={},r=s.createContext(t);function c(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:c(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e08eef46.56de3c31.js b/assets/js/e08eef46.56de3c31.js deleted file mode 100644 index 5fbfa9b7d..000000000 --- a/assets/js/e08eef46.56de3c31.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9037],{57446:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const i={},l="Development Prerequisites",r={id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.",source:"@site/docs/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/next/developers/prerequisites",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726055376e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/next/developers"},next:{title:"Essential Rust Crates",permalink:"/next/developers/essential-crates"}},c={},o=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing <code>curl</code>",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing <code>cargo</code> on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing <code>brew</code>",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"development-prerequisites",children:"Development Prerequisites"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,t.jsx)(n.code,{children:"Linux Ubuntu 20.04"})," or ",(0,t.jsx)(n.code,{children:"macOS"}),". Developing on Windows is not advised."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["Casper does not officially support ",(0,t.jsx)(n.code,{children:"macOS"}),". If you encounter any problems, reach out to the community on ",(0,t.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"})," or ",(0,t.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"preparing-your-development-environment",children:"Preparing your Development Environment"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsxs)(n.h3,{id:"install-curl",children:["Installing ",(0,t.jsx)(n.code,{children:"curl"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install curl\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-essential",children:"Installing essential Linux packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-linux-cargo",children:["Installing ",(0,t.jsx)(n.code,{children:"cargo"})," on Linux"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install cargo\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.h3,{id:"install-xcode",children:"Installing Xcode developer tools for macOS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select -p\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-brew",children:["Installing ",(0,t.jsx)(n.code,{children:"brew"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds-macos",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-rust",children:"Installing Rust"}),"\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust programming language"})," if you don't already have it on your computer."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"official Rust guide"})," recommends installing Rust by using ",(0,t.jsx)(n.code,{children:"curl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.p,{children:"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source $HOME/.cargo/env\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: You can also use ",(0,t.jsx)(n.code,{children:"brew"})," on MacOS or ",(0,t.jsx)(n.code,{children:"apt"})," on Linux to install Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-casper-crates",children:"Installing the Casper Crates"}),"\n",(0,t.jsxs)(n.p,{children:["The best and fastest way to set up a Casper Rust project is to use ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/cargo-casper",children:"cargo casper"}),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,t.jsx)(n.em,{children:"Cargo"})," is a build system and package manager for Rust (much like ",(0,t.jsx)(n.em,{children:"pip"})," if you are familiar with Python, or ",(0,t.jsx)(n.em,{children:"npm"})," and ",(0,t.jsx)(n.em,{children:"yarn"})," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install cargo-casper\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo-casper --version\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Familiarize yourself with the essential Casper crates described ",(0,t.jsx)(n.a,{href:"/next/developers/essential-crates",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"install-casper-client",children:"Installing the Casper Client"}),"\n",(0,t.jsxs)(n.p,{children:["The default Casper client is on ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-client",children:"crates.io"}),". This client can transmit your transactions to a Casper network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install casper-client\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"help"})," for each command to get the most up-to-date arguments and descriptions."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client <command> --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"building-client-from-source",children:"Accessing the Casper client source code"}),"\n",(0,t.jsxs)(n.p,{children:["You can access the Casper client source code ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs",children:"here"}),". The ",(0,t.jsx)(n.code,{children:"lib"})," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,t.jsx)(n.code,{children:"casper-client"})," uses this library to implement its functionality."]}),"\n",(0,t.jsx)(n.p,{children:"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, compile the source code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You will find the ",(0,t.jsx)(n.code,{children:"casper-client"})," executable in the ",(0,t.jsx)(n.code,{children:"target/release"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"install-cmake",children:"Installing CMake"}),"\n",(0,t.jsxs)(n.p,{children:["If you plan to compile contracts from the source code, including those provided in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, install ",(0,t.jsx)(n.code,{children:"CMake"})," with the commands below."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://cmake.org/",children:"CMake"})," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"CMake website"}),". Once installed, check your version as shown below."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get -y install cmake\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install cmake\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sample output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-an-ide",children:"Installing an IDE"}),"\n",(0,t.jsx)(n.p,{children:"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://code.visualstudio.com",children:"Visual Studio Code"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/clion/",children:"CLion"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/idea/",children:"IntelliJ Idea"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.vim.org/",children:"Vim"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."}),"\n",(0,t.jsx)(n.p,{children:"If you are using VSC, you might find the following extensions useful:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"CodeLLDB"})," \u2013 An important extension for debugging Rust code"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rust-analyzer"})," \u2013 The official Rust language extension"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Better TOML"})," \u2013 Support for formatting TOML files"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"crates"})," \u2013 An extension to help manage crates"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Error Lens"})," \u2013 Enhances the programming experience by highlighting syntax errors"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-an-account",children:"Setting up a Casper Account"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/next/concepts/design/casper-design#accounts-head",children:"Account"})," creation process consists of two steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Creating an Account"}),"\n",(0,t.jsx)(n.li,{children:"Funding the Account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following video complements the instructions below, showing you the expected output."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"creating-an-account",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,t.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,t.jsxs)(n.p,{children:["Users can create accounts using the ",(0,t.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined ",(0,t.jsx)(n.a,{href:"/next/concepts/accounts-and-keys#option-2-key-generation-using-a-block-explorer",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Use either method to generate an account and its corresponding cryptographic key-pair."}),"\n",(0,t.jsx)(n.h3,{id:"generating-the-account-hash",children:"Generating the account hash"}),"\n",(0,t.jsxs)(n.p,{children:["As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,t.jsx)(n.code,{children:"AccountHashes"})," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,t.jsx)(n.code,{children:"account-address"})," option of the Casper CLI client:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"fund-your-account",children:"Funding an Account"}),"\n",(0,t.jsx)(n.p,{children:"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."}),"\n",(0,t.jsxs)(n.p,{children:["On Testnet, you can fund an account by requesting test tokens according to ",(0,t.jsx)(n.a,{href:"/next/users/testnet-faucet",children:"this guide"}),". You can request test tokens ",(0,t.jsx)(n.strong,{children:"only once"})," for each account."]}),"\n",(0,t.jsx)(n.p,{children:"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."}),"\n",(0,t.jsx)(n.h2,{id:"acquire-node-address-from-network-peers",children:"Acquiring a Node Address from the Network"}),"\n",(0,t.jsxs)(n.p,{children:["Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,t.jsx)(n.code,{children:"http://<node-ip-address>:7777"})," by default."]}),"\n",(0,t.jsx)(n.p,{children:"The node address is the IP of a peer node."}),"\n",(0,t.jsx)(n.p,{children:"Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."}),"\n",(0,t.jsxs)(n.p,{children:["You can get the ",(0,t.jsx)(n.code,{children:"node-ip-address"})," of a node on the network by visiting the following block explorers:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Peers"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Peers"})," on Mainnet"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You will see a list of peers, and you can select the IP of any peer on the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": If the selected peer is unresponsive, pick a different peer and try again."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e08eef46.c3b1a795.js b/assets/js/e08eef46.c3b1a795.js new file mode 100644 index 000000000..1eb456217 --- /dev/null +++ b/assets/js/e08eef46.c3b1a795.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61418],{57446:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const i={},l="Development Prerequisites",r={id:"developers/prerequisites",title:"Development Prerequisites",description:"This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.",source:"@site/docs/developers/prerequisites.md",sourceDirName:"developers",slug:"/developers/prerequisites",permalink:"/developers/prerequisites",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726055376e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers"},next:{title:"Essential Rust Crates",permalink:"/developers/essential-crates"}},c={},o=[{value:"Preparing your Development Environment",id:"preparing-your-development-environment",level:2},{value:"Installing <code>curl</code>",id:"install-curl",level:3},{value:"Installing essential Linux packages",id:"install-essential",level:3},{value:"Installing packages required for Casper tools",id:"install-adds",level:3},{value:"Installing <code>cargo</code> on Linux",id:"install-linux-cargo",level:3},{value:"Installing Xcode developer tools for macOS",id:"install-xcode",level:3},{value:"Installing <code>brew</code>",id:"install-brew",level:3},{value:"Installing packages required for Casper tools",id:"install-adds-macos",level:3},{value:"Installing Rust",id:"install-rust",level:2},{value:"Installing the Casper Crates",id:"installing-the-casper-crates",level:2},{value:"Installing the Casper Client",id:"install-casper-client",level:2},{value:"Accessing the Casper client source code",id:"building-client-from-source",level:3},{value:"Installing CMake",id:"install-cmake",level:2},{value:"Installing an IDE",id:"installing-an-ide",level:2},{value:"Setting up a Casper Account",id:"setting-up-an-account",level:2},{value:"Creating an account",id:"creating-an-account",level:3},{value:"Generating the account hash",id:"generating-the-account-hash",level:3},{value:"Funding an Account",id:"fund-your-account",level:2},{value:"Acquiring a Node Address from the Network",id:"acquire-node-address-from-network-peers",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",tabitem:"tabitem",tabs:"tabs",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import Tabs from '@theme/Tabs';\nimport TabItem from '@theme/TabItem';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"development-prerequisites",children:"Development Prerequisites"})}),"\n",(0,t.jsxs)(n.p,{children:["This page covers the necessary software for your Casper development environment. To develop comfortably, you should use ",(0,t.jsx)(n.code,{children:"Linux Ubuntu 20.04"})," or ",(0,t.jsx)(n.code,{children:"macOS"}),". Developing on Windows is not advised."]}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsxs)(n.p,{children:["Casper does not officially support ",(0,t.jsx)(n.code,{children:"macOS"}),". If you encounter any problems, reach out to the community on ",(0,t.jsx)(n.a,{href:"https://t.me/casperblockchain",children:"Telegram"})," or ",(0,t.jsx)(n.a,{href:"https://discord.com/invite/casperblockchain",children:"Discord"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"preparing-your-development-environment",children:"Preparing your Development Environment"}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsxs)(n.h3,{id:"install-curl",children:["Installing ",(0,t.jsx)(n.code,{children:"curl"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install curl\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-essential",children:"Installing essential Linux packages"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install build-essential\n"})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get install pkg-config\nsudo apt-get install openssl\nsudo apt-get install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-linux-cargo",children:["Installing ",(0,t.jsx)(n.code,{children:"cargo"})," on Linux"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install cargo\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.h3,{id:"install-xcode",children:"Installing Xcode developer tools for macOS"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select --install\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"xcode-select -p\n"})}),"\n",(0,t.jsxs)(n.h3,{id:"install-brew",children:["Installing ",(0,t.jsx)(n.code,{children:"brew"})]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"\n'})}),"\n",(0,t.jsx)(n.h3,{id:"install-adds-macos",children:"Installing packages required for Casper tools"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install pkg-config\nbrew install openssl\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"install-rust",children:"Installing Rust"}),"\n",(0,t.jsxs)(n.p,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org",children:"Rust programming language"})," if you don't already have it on your computer."]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://www.rust-lang.org/tools/install",children:"official Rust guide"})," recommends installing Rust by using ",(0,t.jsx)(n.code,{children:"curl"}),":"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n"})}),"\n",(0,t.jsx)(n.p,{children:"After your next login, the installation script automatically adds Rust to your system PATH. To start using Rust immediately, run the following command in your shell instead of restarting your terminal. The command will add Rust to your system PATH."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"source $HOME/.cargo/env\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Note: You can also use ",(0,t.jsx)(n.code,{children:"brew"})," on MacOS or ",(0,t.jsx)(n.code,{children:"apt"})," on Linux to install Rust."]}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-casper-crates",children:"Installing the Casper Crates"}),"\n",(0,t.jsxs)(n.p,{children:["The best and fastest way to set up a Casper Rust project is to use ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/cargo-casper",children:"cargo casper"}),", which is the command line tool for creating a Wasm smart contract and tests for use on a Casper network. This tool will create a simple contract, a runtime environment, and a testing framework with a simple test. ",(0,t.jsx)(n.em,{children:"Cargo"})," is a build system and package manager for Rust (much like ",(0,t.jsx)(n.em,{children:"pip"})," if you are familiar with Python, or ",(0,t.jsx)(n.em,{children:"npm"})," and ",(0,t.jsx)(n.em,{children:"yarn"})," for those familiar with Javascript). It is also possible to use this configuration in your CI/CD pipeline."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install cargo-casper\n"})}),"\n",(0,t.jsx)(n.p,{children:"If you run into any issues with this command and you have not recently installed Rust from scratch, please make sure to update your Rust version with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo-casper --version\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Familiarize yourself with the essential Casper crates described ",(0,t.jsx)(n.a,{href:"/developers/essential-crates",children:"here"}),"."]})}),"\n",(0,t.jsx)(n.h2,{id:"install-casper-client",children:"Installing the Casper Client"}),"\n",(0,t.jsxs)(n.p,{children:["The default Casper client is on ",(0,t.jsx)(n.a,{href:"https://crates.io/crates/casper-client",children:"crates.io"}),". This client can transmit your transactions to a Casper network."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo install casper-client\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify the installation:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper client can print out help information, which provides an up-to-date list of supported commands. To do so, use the following command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client --help\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You can use ",(0,t.jsx)(n.code,{children:"help"})," for each command to get the most up-to-date arguments and descriptions."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client <command> --help\n"})}),"\n",(0,t.jsx)(n.h3,{id:"building-client-from-source",children:"Accessing the Casper client source code"}),"\n",(0,t.jsxs)(n.p,{children:["You can access the Casper client source code ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs",children:"here"}),". The ",(0,t.jsx)(n.code,{children:"lib"})," directory contains the source for the client library, which may be called directly rather than through the CLI binary. The CLI app ",(0,t.jsx)(n.code,{children:"casper-client"})," uses this library to implement its functionality."]}),"\n",(0,t.jsx)(n.p,{children:"If you wish to compile it, you will need to first install the nightly Rust toolchain with this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup toolchain install nightly\n"})}),"\n",(0,t.jsx)(n.p,{children:"Then, compile the source code:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cargo build --release\n"})}),"\n",(0,t.jsxs)(n.p,{children:["You will find the ",(0,t.jsx)(n.code,{children:"casper-client"})," executable in the ",(0,t.jsx)(n.code,{children:"target/release"})," directory."]}),"\n",(0,t.jsx)(n.h2,{id:"install-cmake",children:"Installing CMake"}),"\n",(0,t.jsxs)(n.p,{children:["If you plan to compile contracts from the source code, including those provided in the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository, install ",(0,t.jsx)(n.code,{children:"CMake"})," with the commands below."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"https://cmake.org/",children:"CMake"})," is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the ",(0,t.jsx)(n.a,{href:"https://cmake.org/install/",children:"CMake website"}),". Once installed, check your version as shown below."]}),"\n",(0,t.jsxs)(n.tabs,{children:["\n",(0,t.jsxs)(n.tabitem,{value:"Linux",label:"Linux",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt-get -y install cmake\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.tabitem,{value:"macOS",label:"macOS",children:["\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"brew install cmake\n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Check your version:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sample output:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cmake version 3.20.0 (or above)\n\nCMake suite maintained and supported by Kitware (kitware.com/cmake).\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-an-ide",children:"Installing an IDE"}),"\n",(0,t.jsx)(n.p,{children:"We advise using an integrated development environment such as Visual Studio Code (VSC) for development. There are many IDEs available for Rust development. The most popular IDEs for Rust are the following:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://code.visualstudio.com",children:"Visual Studio Code"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/clion/",children:"CLion"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.jetbrains.com/idea/",children:"IntelliJ Idea"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://www.vim.org/",children:"Vim"})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can use any IDE you wish. Most of our documentation and examples use Visual Studio Code (VSC), a popular IDE with many extensions that might be helpful during development."}),"\n",(0,t.jsx)(n.p,{children:"If you are using VSC, you might find the following extensions useful:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"CodeLLDB"})," \u2013 An important extension for debugging Rust code"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rust-analyzer"})," \u2013 The official Rust language extension"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Better TOML"})," \u2013 Support for formatting TOML files"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"crates"})," \u2013 An extension to help manage crates"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"Error Lens"})," \u2013 Enhances the programming experience by highlighting syntax errors"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-an-account",children:"Setting up a Casper Account"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"Account"})," creation process consists of two steps:"]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Creating an Account"}),"\n",(0,t.jsx)(n.li,{children:"Funding the Account"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The following video complements the instructions below, showing you the expected output."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sA1HTPjV_bc&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=3",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"creating-an-account",children:"Creating an account"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper blockchain uses an on-chain account-based model, uniquely identified by an ",(0,t.jsx)(n.code,{children:"AccountHash"})," derived from a specific ",(0,t.jsx)(n.code,{children:"PublicKey"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["By default, a transactional interaction with the blockchain takes the form of a ",(0,t.jsx)(n.code,{children:"Transaction"})," cryptographically signed by the key-pair corresponding to the ",(0,t.jsx)(n.code,{children:"PublicKey"})," used to create the account."]}),"\n",(0,t.jsxs)(n.p,{children:["Users can create accounts using the ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#option-1-key-generation-using-the-casper-client",children:"Casper command-line client"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined ",(0,t.jsx)(n.a,{href:"/concepts/accounts-and-keys#option-2-key-generation-using-a-block-explorer",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Use either method to generate an account and its corresponding cryptographic key-pair."}),"\n",(0,t.jsx)(n.h3,{id:"generating-the-account-hash",children:"Generating the account hash"}),"\n",(0,t.jsxs)(n.p,{children:["As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain ",(0,t.jsx)(n.code,{children:"AccountHashes"})," instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the ",(0,t.jsx)(n.code,{children:"account-address"})," option of the Casper CLI client:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>\n"})}),"\n",(0,t.jsx)(n.h2,{id:"fund-your-account",children:"Funding an Account"}),"\n",(0,t.jsx)(n.p,{children:"After generating the cryptographic key-pair for an Account, you must fund the account's main purse to create it on-chain."}),"\n",(0,t.jsxs)(n.p,{children:["On Testnet, you can fund an account by requesting test tokens according to ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"this guide"}),". You can request test tokens ",(0,t.jsx)(n.strong,{children:"only once"})," for each account."]}),"\n",(0,t.jsx)(n.p,{children:"On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet."}),"\n",(0,t.jsx)(n.h2,{id:"acquire-node-address-from-network-peers",children:"Acquiring a Node Address from the Network"}),"\n",(0,t.jsxs)(n.p,{children:["Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, ",(0,t.jsx)(n.code,{children:"http://<node-ip-address>:7777"})," by default."]}),"\n",(0,t.jsx)(n.p,{children:"The node address is the IP of a peer node."}),"\n",(0,t.jsx)(n.p,{children:"Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks."}),"\n",(0,t.jsxs)(n.p,{children:["You can get the ",(0,t.jsx)(n.code,{children:"node-ip-address"})," of a node on the network by visiting the following block explorers:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Peers"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Peers"})," on Mainnet"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You will see a list of peers, and you can select the IP of any peer on the list."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Note"}),": If the selected peer is unresponsive, pick a different peer and try again."]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>l,x:()=>r});var t=s(96540);const a={},i=t.createContext(a);function l(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:l(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e10cd13d.5aff8aea.js b/assets/js/e10cd13d.5aff8aea.js new file mode 100644 index 000000000..e05abd4a8 --- /dev/null +++ b/assets/js/e10cd13d.5aff8aea.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5118],{92770:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(74848),a=n(28453);const o={title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},i="Interacting with Runtime Return Values",s={id:"resources/advanced/return-values-tutorial",title:"Runtime Return Values",description:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/return-values-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/return-values-tutorial",permalink:"/2.0.0/resources/tutorials/advanced/return-values-tutorial",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},sidebar:"tutorials",previous:{title:"Additional Examples",permalink:"/2.0.0/resources/advanced/multi-sig/other-scenarios"},next:{title:"Authorization Keys",permalink:"/2.0.0/resources/advanced/list-auth-keys-tutorial"}},c={},d=[{value:"Contract Code",id:"return-contract-code",level:2},{value:"Session Code",id:"return-session-code",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"interacting-with-runtime-return-values",children:"Interacting with Runtime Return Values"})}),"\n",(0,r.jsx)(t.p,{children:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code."}),"\n",(0,r.jsx)(t.p,{children:"Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers."}),"\n",(0,r.jsxs)(t.p,{children:["Contract code can optionally return a value to their immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"}),", whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance."]}),"\n",(0,r.jsx)(t.p,{children:"Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything."}),"\n",(0,r.jsx)(t.h2,{id:"return-contract-code",children:"Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["For example, if we create a contract to accept and keep a record of donations, we would use ",(0,r.jsx)(t.code,{children:"runtime::ret()"})," to define the results that should be passed to the caller as per the following:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn donate() {\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n if let Key::Account(donating_account_hash) = donating_account_key {\n update_ledger_record(donating_account_hash.to_string())\n } else {\n runtime::revert(FundRaisingError::InvalidKeyVariant)\n }\n let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)\n .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)\n .as_uref()\n .unwrap_or_revert();\n let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();\n runtime::ret(value)\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["In this example, the return value is the URef corresponding to the purse used to raise funds, with ",(0,r.jsx)(t.code,{children:"add"})," permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the ",(0,r.jsx)(t.code,{children:"donate"})," entry point."]}),"\n",(0,r.jsxs)(t.p,{children:["Without the addition of the ",(0,r.jsx)(t.code,{children:"runtime::ret"}),", the purse would not be returned to the caller."]}),"\n",(0,r.jsx)(t.h2,{id:"return-session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["The following is an example of session code calling the ",(0,r.jsx)(t.a,{href:"#return-contract-code",children:"specified entry point"}),". Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);\n\n let donating_purse_uref: URef = runtime::call_contract(\n fundraiser_contract_hash,\n ENTRY_POINT_DONATE,\n runtime_args! {\n DONATING_ACCOUNT_KEY => donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["This session code calls into a contract's entry point by using ",(0,r.jsx)(t.code,{children:"runtime::call_contract"}),", supplying the ",(0,r.jsx)(t.code,{children:"contract_hash"})," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,r.jsx)(t.code,{children:"donate"}),". It supplies the ",(0,r.jsx)(t.code,{children:"donating_account_key"}),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,r.jsx)(t.code,{children:"donating_purse_uref"}),". To call an entry point, you will need to know the ",(0,r.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/types_cl",children:"CLType"})," of the return value and identify it within the code."]}),"\n",(0,r.jsxs)(t.p,{children:["You can determine the type of the return value by ",(0,r.jsx)(t.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-an-account",children:"querying the contract object"})," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."]}),"\n",(0,r.jsxs)(t.p,{children:["This example code takes that returned value and transfers a ",(0,r.jsx)(t.code,{children:"donation_amount"})," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const a={},o=r.createContext(a);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e15566cb.26ef38f0.js b/assets/js/e15566cb.26ef38f0.js new file mode 100644 index 000000000..60946946a --- /dev/null +++ b/assets/js/e15566cb.26ef38f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59784],{63018:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var t=r(74848),s=r(28453);const d={title:"Casper on Ledger"},i="Using Ledger with Casper",c={id:"users/ledger/index",title:"Casper on Ledger",description:"| Topic | Description |",source:"@site/docs/users/ledger/index.md",sourceDirName:"users/ledger",slug:"/users/ledger/",permalink:"/users/ledger/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Casper on Ledger"},sidebar:"users",previous:{title:"Transfer Tokens",permalink:"/users/token-transfer"},next:{title:"Set up Ledger",permalink:"/workflow/ledger-setup/"}},l={},a=[];function o(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-with-casper",children:"Using Ledger with Casper"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"Ledger Setup with Casper"})}),(0,t.jsx)(n.td,{children:"Connect a Ledger device to the Casper application"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/ledger/ledger-live",children:"Using Ledger and Ledger Live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and Ledger Live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/ledger/ledger-cspr-live",children:"Using Ledger and CSPR.live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and CSPR.live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,t.jsx)(n.td,{children:"Delegate tokens using a Ledger device and CSPR.live"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var t=r(96540);const s={},d=t.createContext(s);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e15566cb.87dbe301.js b/assets/js/e15566cb.87dbe301.js deleted file mode 100644 index 66bd7dae5..000000000 --- a/assets/js/e15566cb.87dbe301.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9784],{63018:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>d,metadata:()=>c,toc:()=>a});var t=r(74848),s=r(28453);const d={title:"Casper on Ledger"},i="Using Ledger with Casper",c={id:"users/ledger/index",title:"Casper on Ledger",description:"| Topic | Description |",source:"@site/docs/users/ledger/index.md",sourceDirName:"users/ledger",slug:"/users/ledger/",permalink:"/next/users/ledger/",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Casper on Ledger"},sidebar:"users",previous:{title:"Transfer Tokens",permalink:"/next/users/token-transfer"},next:{title:"Set up Ledger",permalink:"/next/workflow/ledger-setup/"}},l={},a=[];function o(e){const n={a:"a",h1:"h1",header:"header",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-with-casper",children:"Using Ledger with Casper"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/workflow/ledger-setup/",children:"Ledger Setup with Casper"})}),(0,t.jsx)(n.td,{children:"Connect a Ledger device to the Casper application"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/users/ledger/ledger-live",children:"Using Ledger and Ledger Live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and Ledger Live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/users/ledger/ledger-cspr-live",children:"Using Ledger and CSPR.live"})}),(0,t.jsx)(n.td,{children:"Send and receive CSPR using Ledger and CSPR.live"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/next/users/staking-ledger",children:"Delegating with Ledger Devices"})}),(0,t.jsx)(n.td,{children:"Delegate tokens using a Ledger device and CSPR.live"})]})]})]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(o,{...e})}):o(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>i,x:()=>c});var t=r(96540);const s={},d=t.createContext(s);function i(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1e5af17.a55d48e0.js b/assets/js/e1e5af17.a55d48e0.js new file mode 100644 index 000000000..f304d1b6c --- /dev/null +++ b/assets/js/e1e5af17.a55d48e0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[60202],{26628:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var n=s(74848),a=s(28453);const t={title:"Zug Consensus"},r="Simple and Fast Consensus with Zug",i={id:"concepts/design/zug",title:"Zug Consensus",description:"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.",source:"@site/docs/concepts/design/zug.md",sourceDirName:"concepts/design",slug:"/concepts/design/zug",permalink:"/concepts/design/zug",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{title:"Zug Consensus"},sidebar:"concepts",previous:{title:"Consensus in a Casper Network",permalink:"/concepts/design/consensus"},next:{title:"Highway Consensus",permalink:"/concepts/design/highway"}},l={},d=[{value:"How Zug Works",id:"how-zug-works",level:2},{value:"Some Advantages of Zug",id:"some-advantages-of-zug",level:2},{value:"Comparison with Highway",id:"comparison-with-highway",level:2},{value:"Block Rewards",id:"block-rewards",level:3},{value:"Read the Paper",id:"read-the-paper",level:2}];function h(e){const o={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"simple-and-fast-consensus-with-zug",children:"Simple and Fast Consensus with Zug"})}),"\n",(0,n.jsxs)(o.p,{children:["The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"a much simpler consensus protocol"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The Zug protocol requires that at most one-third of the validator weight could be attributed to faulty validators. It also assumes that there exists an upper bound for the network delay, which is the duration for a correct validator to deliver a message. The value of the upper bound may be unknown, but it exists. Under these conditions, all correct nodes will reach agreement on a chain of finalized blocks."}),"\n",(0,n.jsxs)(o.p,{children:["Of course, all nodes in a network have to run the same protocol to work together, but when starting a new network or upgrading an existing one, either ",(0,n.jsx)(o.code,{children:"Highway"})," or ",(0,n.jsx)(o.code,{children:"Zug"})," can now be selected as the ",(0,n.jsx)(o.code,{children:"consensus_protocol"})," in the chainspec file. The Casper Mainnet will switch to Zug."]}),"\n",(0,n.jsx)(o.h2,{id:"how-zug-works",children:"How Zug Works"}),"\n",(0,n.jsxs)(o.p,{children:["In every round, the designated leader can sign a ",(0,n.jsx)(o.strong,{children:"proposal message"})," to suggest a block. The proposal also points to an earlier round in which the parent block was proposed."]}),"\n",(0,n.jsxs)(o.p,{children:["Each validator then signs an ",(0,n.jsx)(o.strong,{children:"echo message"})," with the proposal's hash. Correct validators only sign one echo per round, so at most one proposal can get echo messages signed by a quorum. A ",(0,n.jsx)(o.strong,{children:"quorum"})," is a set of validators whose total weight is greater than ",(0,n.jsx)(o.code,{children:"(n + f) / 2"}),", where ",(0,n.jsx)(o.code,{children:"n"})," is the total weight of all validators and ",(0,n.jsx)(o.code,{children:"f"})," is the maximum allowed total weight of faulty validators. Thus, any two quorums always have a correct validator in common. As long as ",(0,n.jsx)(o.code,{children:"n > 3f"}),", the correct validators will constitute a quorum since ",(0,n.jsx)(o.code,{children:"(n + f) / 2 < n - f"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The proposal is accepted if there is a quorum and some other conditions are met (see below). Now, the next round's leader can make a new proposal that uses this proposal as a parent."}),"\n",(0,n.jsxs)(o.p,{children:["Each validator observing the proposal in time signs a ",(0,n.jsx)(o.code,{children:"Vote(true)"})," message. If validators time out while waiting, they sign ",(0,n.jsx)(o.code,{children:"Vote(false)"})," message instead. If a quorum signs ",(0,n.jsx)(o.em,{children:"true"}),", the round is committed and the proposal and all its ancestors are finalized. If a quorum signs ",(0,n.jsx)(o.em,{children:"false"}),", the round is ",(0,n.jsx)(o.strong,{children:"skippable"}),", meaning that the next round's leader can propose a block with a parent from an earlier round. Correct validators only sign either ",(0,n.jsx)(o.em,{children:"true"})," or ",(0,n.jsx)(o.em,{children:"false"}),", so a round can be either committed or skippable, but not both."]}),"\n",(0,n.jsxs)(o.p,{children:["If there is no accepted proposal, all correct validators will eventually vote ",(0,n.jsx)(o.em,{children:"false"}),", so the round becomes skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"live"}),". The next leader will eventually be allowed to make a proposal because either there is an accepted proposal that can be the parent, or the round will eventually be skippable, and an earlier round's proposal can be used as a parent. If the timeout is long enough, the correct proposers' blocks will usually get finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["For a proposal to be accepted, the parent proposal must also be accepted, and all rounds between the parent and the current round must be skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"safe"}),". If two rounds are committed, their proposals must be ancestors of each other because they are not skippable. Thus, the protocol cannot finalize two conflicting blocks."]}),"\n",(0,n.jsx)(o.p,{children:"Of course, there is also a first block. Whenever all earlier rounds are skippable (particularly the first round), the leader may propose a block with no parent."}),"\n",(0,n.jsxs)(o.p,{children:["Every new signed message is optimistically sent directly to all peers. We want to guarantee that it is eventually seen by all validators, even if they are not fully connected. This is achieved via a pull-based randomized gossip mechanism, where a ",(0,n.jsx)(o.code,{children:"SyncRequest"})," message containing information about a random part of the local protocol state is periodically sent to a random peer. The peer compares that to its local state and responds with all the signed messages that it has recorded."]}),"\n",(0,n.jsxs)(o.admonition,{type:"important",children:[(0,n.jsx)(o.p,{children:"The Zug protocol can be summarized as follows:"}),(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["In every round, the round leader proposes a new block, ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator creates and broadcasts an ",(0,n.jsx)(o.em,{children:"echo"})," message, with a signature of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["When a suitable block ",(0,n.jsx)(o.code,{children:"B"})," has received echoes from 67% of the validators:\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["The next round begins. The next leader can propose a child of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator signs and broadcasts a ",(0,n.jsx)(o.em,{children:"vote"})," message, voting ",(0,n.jsx)(o.code,{children:"yes"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If this does not happen before a timeout, the validators vote ",(0,n.jsx)(o.code,{children:"no"})," instead.\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"no"})," votes from 67%, the next round begins, too.\nThe next leader can propose a child from an earlier block and skip this round."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"yes"})," votes from 67%, ",(0,n.jsx)(o.code,{children:"B"})," is finalized and gets executed, together with all its ancestors. (Usually, the next round has already started at this point.)"]}),"\n"]})]}),"\n",(0,n.jsxs)(o.p,{children:["Notice that proposals, votes, and echoes are broadcast, so if one correct node receives a message, all nodes will eventually receive it. An honest validator sends only one echo or vote per round. So, unless 34% of validators double-sign, at most one block per round gets 67% echoes, and no finalized block can ever be skipped, ensuring safety. As long as there are 67% of echoes for a proposal, the next round begins and Zug doesn't get stuck. If there are not, everyone votes ",(0,n.jsx)(o.code,{children:"no"}),", and the next round also begins."]}),"\n",(0,n.jsxs)(o.details,{children:["\n",(0,n.jsx)(o.summary,{children:(0,n.jsx)(o.b,{children:"Expand to see a simple example"})}),"\n",(0,n.jsx)(o.p,{children:"Let's review a simple scenario demonstrating the Zug consensus. The example shows five rounds with a different leader and nodes voting on a card suit. The bottom row indicates whether or not the round was finalized. Notice that round 5 was the first finalized round."}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.img,{alt:"ZUG",src:s(5484).A+"",width:"1284",height:"528"})}),"\n",(0,n.jsxs)(o.p,{children:["In round 1, we had a leader who proposed ",(0,n.jsx)(o.code,{children:"\u2665"}),", but was slow, so the other nodes timed out and voted ",(0,n.jsx)(o.code,{children:"no."})," The first round had a proposal and was skippable, but nothing was finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 2, the second proposer saw ",(0,n.jsx)(o.code,{children:"\u2665"})," and proposed ",(0,n.jsx)(o.code,{children:"\u2663"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2665"}),". Some nodes voted ",(0,n.jsx)(o.code,{children:"yes"}),", and some timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),". So, round 2 will never output anything because there wasn't a decision."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 3, the leader proposed ",(0,n.jsx)(o.code,{children:"\u2666"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". Assuming the leader was still too slow, everyone voted ",(0,n.jsx)(o.code,{children:"no"}),", and round 3 became skippable even though it had a proposal."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 4, the proposer might have crashed or been malicious, so everyone timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 5, the leader didn't see the ",(0,n.jsx)(o.code,{children:"\u2666"})," proposal from round 3 but saw the ",(0,n.jsx)(o.code,{children:"no"})," decision. So, from their perspective, rounds 3 and 4 were skippable and had no proposals. Thus, the leader in round 5 proposed ",(0,n.jsx)(o.code,{children:"\u2660"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". ",(0,n.jsx)(o.strong,{children:"Notice that the algorithm encountered a fork"}),". Regardless, everyone voted ",(0,n.jsx)(o.code,{children:"yes"}),", and round 5 was finalized. I.e., at that moment, ",(0,n.jsx)(o.code,{children:"\u2665"}),", ",(0,n.jsx)(o.code,{children:"\u2663"}),", and ",(0,n.jsx)(o.code,{children:"\u2660"})," all become finalized and executed in that order. As a result, every future proposer needs to propose children of this round."]}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.strong,{children:"Important Notes:"})}),"\n",(0,n.jsxs)(o.p,{children:["Even proposals from rounds with a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes can become finalized indirectly."]}),"\n",(0,n.jsxs)(o.p,{children:["If a round is neither finalized nor skippable, the round will likely be finalized at some point in the future. When one-third of the network's weight votes ",(0,n.jsx)(o.code,{children:"yes"}),", a proposal with a quorum of echoes is formed. Consequently, all other honest nodes will eventually see this quorum of echoes and the accepted proposal, which will serve as a parent in future rounds."]}),"\n",(0,n.jsxs)(o.p,{children:["Nodes vote ",(0,n.jsx)(o.code,{children:"yes"})," when they have a quorum of echoes, and all the ancestors of that proposal have a quorum of echoes. Also, those ancestors have a quorum of echoes, and the rounds with no ancestors all have a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes (being skippable)."]}),"\n",(0,n.jsxs)(o.p,{children:["The algorithm will always produce a result in at least one of the ",(0,n.jsx)(o.code,{children:"Accepted proposal"})," or ",(0,n.jsx)(o.code,{children:"Finalized round"})," rows. If a proposal doesn't get accepted in a round, everyone times out and votes ",(0,n.jsx)(o.code,{children:"no"}),". Otherwise, a proposal is visible to someone with a quorum of votes and will eventually be visible to everyone."]}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"some-advantages-of-zug",children:"Some Advantages of Zug"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"Apart from the leader, who has to send the proposed block, each validator node broadcasts only two tiny messages in each round, making the communication overhead very small."}),"\n",(0,n.jsx)(o.li,{children:"Unlike in Highway and Practical Byzantine Fault Tolerance (PBFT), and similar to pipelined protocols like HotStuff, only one round of messages (the echoes) is needed for the next leader to propose a block, reducing the delay between a block and its child."}),"\n",(0,n.jsxs)(o.li,{children:["But ",(0,n.jsx)(o.em,{children:"unlike"})," HotStuff, Zug can finalize a block without waiting for its child or grandchild. And, unlike Highway, it does so without waiting for any timeout. Even if a network is configured to produce only one block per minute, every block gets finalized within seconds, as fast as the network connections allow."]}),"\n",(0,n.jsx)(o.li,{children:"Zug's technical description is more flexible than Highway's, giving us a family of related, correct implementations from which to choose."}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"comparison-with-highway",children:"Comparison with Highway"}),"\n",(0,n.jsxs)(o.p,{children:["Unlike Highway, Zug does not use a communication history DAG. Highway sends larger messages due to citing and is slower. Zug does not have any notion of citing units, as does Highway, and relies on exchanging signed messages. On the other hand, Highway allows for more fine-grained ",(0,n.jsx)(o.a,{href:"#block-rewards",children:"block rewards"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["With Zug, finality happens after nodes constituting two-thirds of the network's total weight vote ",(0,n.jsx)(o.code,{children:"true"})," for a round in which the block was proposed or a later round that has this one as an ancestor. Highways' criterion for detecting finality is the presence of a pattern of messages called a ",(0,n.jsx)(o.code,{children:"Summit."})," Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time. Both ways of detecting finality are improvements over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect."]}),"\n",(0,n.jsx)(o.p,{children:"Highway and Zug offer flexibility in terms of fault tolerance thresholds. Highway allows different clients to follow the protocol with varying thresholds, each with its own balance between security and latency. However, if a sufficient number of validators are online, Zug demonstrates lower latency than Highway at any threshold. This is because Zug does not have predefined, rigid values for the round length, and its design allows the network to adapt to actual delays. If delays occur, block times may vary. Otherwise, blocks should appear as soon as they are finalized. Highway has a defined minimum round length, and the round lengths have to be powers of two times that minimum. Zug has a defined minimum round length, but a round can finish anytime as soon as enough messages are successfully exchanged. So, with Zug, there is no need to wait for a power of two times the minimum if the actual time falls somewhere between."}),"\n",(0,n.jsx)(o.p,{children:"Highway is a much more complicated protocol than Zug. Implementing it takes more than twice as many lines of code. Also, Highway's proof of correctness has proved more difficult to verify than Zug's. Zug will make it easier for third parties to create compatible node software that works with the Casper node."}),"\n",(0,n.jsx)(o.p,{children:"Using Zug consensus and smaller messages, the network could scale to a larger number of validators."}),"\n",(0,n.jsx)(o.h3,{id:"block-rewards",children:"Block Rewards"}),"\n",(0,n.jsx)(o.p,{children:"Using a DAG in Highway makes fine-grained information about the validators' behavior available temporarily in the protocol state, so block rewards can be tuned to incentivize full participation in the consensus protocol. However, this does not apply at the end of each era. Any message sent after the era's last block was proposed cannot be taken into account, even though these messages are still needed to finalize that block. And this granularity comes at a cost: Highway messages are relatively big."}),"\n",(0,n.jsx)(o.p,{children:"The current system does not reward finality signatures, which are arguably the most important outcome. The signatures are the user-visible proof, signed by the validators, that an executed block is correct."}),"\n",(0,n.jsx)(o.p,{children:"In Zug, messages are much smaller, so a smaller incentive is needed to send them."}),"\n",(0,n.jsx)(o.p,{children:"Casper 2.0.0 will distribute a configurable fraction of the seigniorage as a reward for finality signatures and the rest as a simple reward for each block, both proportionally to the validators' stakes."}),"\n",(0,n.jsx)(o.p,{children:"This new reward system is simpler, fairer, predictable, and transparent. It will give equal weight to all blocks (including at the end of an era), but it will not take into account every single consensus message."}),"\n",(0,n.jsx)(o.h2,{id:"read-the-paper",children:"Read the Paper"}),"\n",(0,n.jsxs)(o.p,{children:["Here, we describe Zug, an implementation of the ideas from our paper ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),". The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the ",(0,n.jsx)(o.em,{children:"echo"})," messages are used by our Reliable Broadcast implementation, and the ",(0,n.jsx)(o.em,{children:"vote"})," messages are used by our Weakly-terminating Binary Agreement implementation."]})]})}function c(e={}){const{wrapper:o}={...(0,a.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},5484:(e,o,s)=>{s.d(o,{A:()=>n});const n=s.p+"assets/images/zug-example-5515691ed63d9f310e573eb5742c1701.png"},28453:(e,o,s)=>{s.d(o,{R:()=>r,x:()=>i});var n=s(96540);const a={},t=n.createContext(a);function r(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function i(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e1e5af17.e2008a93.js b/assets/js/e1e5af17.e2008a93.js deleted file mode 100644 index d0132cd2f..000000000 --- a/assets/js/e1e5af17.e2008a93.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[202],{26628:(e,o,s)=>{s.r(o),s.d(o,{assets:()=>l,contentTitle:()=>r,default:()=>c,frontMatter:()=>t,metadata:()=>i,toc:()=>d});var n=s(74848),a=s(28453);const t={title:"Zug Consensus"},r="Simple and Fast Consensus with Zug",i={id:"concepts/design/zug",title:"Zug Consensus",description:"The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.",source:"@site/docs/concepts/design/zug.md",sourceDirName:"concepts/design",slug:"/concepts/design/zug",permalink:"/next/concepts/design/zug",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1724650828e3,frontMatter:{title:"Zug Consensus"},sidebar:"concepts",previous:{title:"Consensus in a Casper Network",permalink:"/next/concepts/design/consensus"},next:{title:"Highway Consensus",permalink:"/next/concepts/design/highway"}},l={},d=[{value:"How Zug Works",id:"how-zug-works",level:2},{value:"Some Advantages of Zug",id:"some-advantages-of-zug",level:2},{value:"Comparison with Highway",id:"comparison-with-highway",level:2},{value:"Block Rewards",id:"block-rewards",level:3},{value:"Read the Paper",id:"read-the-paper",level:2}];function h(e){const o={a:"a",admonition:"admonition",b:"b",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(o.header,{children:(0,n.jsx)(o.h1,{id:"simple-and-fast-consensus-with-zug",children:"Simple and Fast Consensus with Zug"})}),"\n",(0,n.jsxs)(o.p,{children:["The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"a much simpler consensus protocol"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The Zug protocol requires that at most one-third of the validator weight could be attributed to faulty validators. It also assumes that there exists an upper bound for the network delay, which is the duration for a correct validator to deliver a message. The value of the upper bound may be unknown, but it exists. Under these conditions, all correct nodes will reach agreement on a chain of finalized blocks."}),"\n",(0,n.jsxs)(o.p,{children:["Of course, all nodes in a network have to run the same protocol to work together, but when starting a new network or upgrading an existing one, either ",(0,n.jsx)(o.code,{children:"Highway"})," or ",(0,n.jsx)(o.code,{children:"Zug"})," can now be selected as the ",(0,n.jsx)(o.code,{children:"consensus_protocol"})," in the chainspec file. The Casper Mainnet will switch to Zug."]}),"\n",(0,n.jsx)(o.h2,{id:"how-zug-works",children:"How Zug Works"}),"\n",(0,n.jsxs)(o.p,{children:["In every round, the designated leader can sign a ",(0,n.jsx)(o.strong,{children:"proposal message"})," to suggest a block. The proposal also points to an earlier round in which the parent block was proposed."]}),"\n",(0,n.jsxs)(o.p,{children:["Each validator then signs an ",(0,n.jsx)(o.strong,{children:"echo message"})," with the proposal's hash. Correct validators only sign one echo per round, so at most one proposal can get echo messages signed by a quorum. A ",(0,n.jsx)(o.strong,{children:"quorum"})," is a set of validators whose total weight is greater than ",(0,n.jsx)(o.code,{children:"(n + f) / 2"}),", where ",(0,n.jsx)(o.code,{children:"n"})," is the total weight of all validators and ",(0,n.jsx)(o.code,{children:"f"})," is the maximum allowed total weight of faulty validators. Thus, any two quorums always have a correct validator in common. As long as ",(0,n.jsx)(o.code,{children:"n > 3f"}),", the correct validators will constitute a quorum since ",(0,n.jsx)(o.code,{children:"(n + f) / 2 < n - f"}),"."]}),"\n",(0,n.jsx)(o.p,{children:"The proposal is accepted if there is a quorum and some other conditions are met (see below). Now, the next round's leader can make a new proposal that uses this proposal as a parent."}),"\n",(0,n.jsxs)(o.p,{children:["Each validator observing the proposal in time signs a ",(0,n.jsx)(o.code,{children:"Vote(true)"})," message. If validators time out while waiting, they sign ",(0,n.jsx)(o.code,{children:"Vote(false)"})," message instead. If a quorum signs ",(0,n.jsx)(o.em,{children:"true"}),", the round is committed and the proposal and all its ancestors are finalized. If a quorum signs ",(0,n.jsx)(o.em,{children:"false"}),", the round is ",(0,n.jsx)(o.strong,{children:"skippable"}),", meaning that the next round's leader can propose a block with a parent from an earlier round. Correct validators only sign either ",(0,n.jsx)(o.em,{children:"true"})," or ",(0,n.jsx)(o.em,{children:"false"}),", so a round can be either committed or skippable, but not both."]}),"\n",(0,n.jsxs)(o.p,{children:["If there is no accepted proposal, all correct validators will eventually vote ",(0,n.jsx)(o.em,{children:"false"}),", so the round becomes skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"live"}),". The next leader will eventually be allowed to make a proposal because either there is an accepted proposal that can be the parent, or the round will eventually be skippable, and an earlier round's proposal can be used as a parent. If the timeout is long enough, the correct proposers' blocks will usually get finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["For a proposal to be accepted, the parent proposal must also be accepted, and all rounds between the parent and the current round must be skippable. This is what makes the protocol ",(0,n.jsx)(o.strong,{children:"safe"}),". If two rounds are committed, their proposals must be ancestors of each other because they are not skippable. Thus, the protocol cannot finalize two conflicting blocks."]}),"\n",(0,n.jsx)(o.p,{children:"Of course, there is also a first block. Whenever all earlier rounds are skippable (particularly the first round), the leader may propose a block with no parent."}),"\n",(0,n.jsxs)(o.p,{children:["Every new signed message is optimistically sent directly to all peers. We want to guarantee that it is eventually seen by all validators, even if they are not fully connected. This is achieved via a pull-based randomized gossip mechanism, where a ",(0,n.jsx)(o.code,{children:"SyncRequest"})," message containing information about a random part of the local protocol state is periodically sent to a random peer. The peer compares that to its local state and responds with all the signed messages that it has recorded."]}),"\n",(0,n.jsxs)(o.admonition,{type:"important",children:[(0,n.jsx)(o.p,{children:"The Zug protocol can be summarized as follows:"}),(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["In every round, the round leader proposes a new block, ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator creates and broadcasts an ",(0,n.jsx)(o.em,{children:"echo"})," message, with a signature of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["When a suitable block ",(0,n.jsx)(o.code,{children:"B"})," has received echoes from 67% of the validators:\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["The next round begins. The next leader can propose a child of ",(0,n.jsx)(o.code,{children:"B"}),"."]}),"\n",(0,n.jsxs)(o.li,{children:["Every validator signs and broadcasts a ",(0,n.jsx)(o.em,{children:"vote"})," message, voting ",(0,n.jsx)(o.code,{children:"yes"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If this does not happen before a timeout, the validators vote ",(0,n.jsx)(o.code,{children:"no"})," instead.\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"no"})," votes from 67%, the next round begins, too.\nThe next leader can propose a child from an earlier block and skip this round."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(o.li,{children:["If there are ",(0,n.jsx)(o.code,{children:"yes"})," votes from 67%, ",(0,n.jsx)(o.code,{children:"B"})," is finalized and gets executed, together with all its ancestors. (Usually, the next round has already started at this point.)"]}),"\n"]})]}),"\n",(0,n.jsxs)(o.p,{children:["Notice that proposals, votes, and echoes are broadcast, so if one correct node receives a message, all nodes will eventually receive it. An honest validator sends only one echo or vote per round. So, unless 34% of validators double-sign, at most one block per round gets 67% echoes, and no finalized block can ever be skipped, ensuring safety. As long as there are 67% of echoes for a proposal, the next round begins and Zug doesn't get stuck. If there are not, everyone votes ",(0,n.jsx)(o.code,{children:"no"}),", and the next round also begins."]}),"\n",(0,n.jsxs)(o.details,{children:["\n",(0,n.jsx)(o.summary,{children:(0,n.jsx)(o.b,{children:"Expand to see a simple example"})}),"\n",(0,n.jsx)(o.p,{children:"Let's review a simple scenario demonstrating the Zug consensus. The example shows five rounds with a different leader and nodes voting on a card suit. The bottom row indicates whether or not the round was finalized. Notice that round 5 was the first finalized round."}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.img,{alt:"ZUG",src:s(75470).A+"",width:"1284",height:"528"})}),"\n",(0,n.jsxs)(o.p,{children:["In round 1, we had a leader who proposed ",(0,n.jsx)(o.code,{children:"\u2665"}),", but was slow, so the other nodes timed out and voted ",(0,n.jsx)(o.code,{children:"no."})," The first round had a proposal and was skippable, but nothing was finalized."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 2, the second proposer saw ",(0,n.jsx)(o.code,{children:"\u2665"})," and proposed ",(0,n.jsx)(o.code,{children:"\u2663"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2665"}),". Some nodes voted ",(0,n.jsx)(o.code,{children:"yes"}),", and some timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),". So, round 2 will never output anything because there wasn't a decision."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 3, the leader proposed ",(0,n.jsx)(o.code,{children:"\u2666"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". Assuming the leader was still too slow, everyone voted ",(0,n.jsx)(o.code,{children:"no"}),", and round 3 became skippable even though it had a proposal."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 4, the proposer might have crashed or been malicious, so everyone timed out and voted ",(0,n.jsx)(o.code,{children:"no"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["In round 5, the leader didn't see the ",(0,n.jsx)(o.code,{children:"\u2666"})," proposal from round 3 but saw the ",(0,n.jsx)(o.code,{children:"no"})," decision. So, from their perspective, rounds 3 and 4 were skippable and had no proposals. Thus, the leader in round 5 proposed ",(0,n.jsx)(o.code,{children:"\u2660"})," as a child of ",(0,n.jsx)(o.code,{children:"\u2663"}),". ",(0,n.jsx)(o.strong,{children:"Notice that the algorithm encountered a fork"}),". Regardless, everyone voted ",(0,n.jsx)(o.code,{children:"yes"}),", and round 5 was finalized. I.e., at that moment, ",(0,n.jsx)(o.code,{children:"\u2665"}),", ",(0,n.jsx)(o.code,{children:"\u2663"}),", and ",(0,n.jsx)(o.code,{children:"\u2660"})," all become finalized and executed in that order. As a result, every future proposer needs to propose children of this round."]}),"\n",(0,n.jsx)(o.p,{children:(0,n.jsx)(o.strong,{children:"Important Notes:"})}),"\n",(0,n.jsxs)(o.p,{children:["Even proposals from rounds with a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes can become finalized indirectly."]}),"\n",(0,n.jsxs)(o.p,{children:["If a round is neither finalized nor skippable, the round will likely be finalized at some point in the future. When one-third of the network's weight votes ",(0,n.jsx)(o.code,{children:"yes"}),", a proposal with a quorum of echoes is formed. Consequently, all other honest nodes will eventually see this quorum of echoes and the accepted proposal, which will serve as a parent in future rounds."]}),"\n",(0,n.jsxs)(o.p,{children:["Nodes vote ",(0,n.jsx)(o.code,{children:"yes"})," when they have a quorum of echoes, and all the ancestors of that proposal have a quorum of echoes. Also, those ancestors have a quorum of echoes, and the rounds with no ancestors all have a quorum of ",(0,n.jsx)(o.code,{children:"no"})," votes (being skippable)."]}),"\n",(0,n.jsxs)(o.p,{children:["The algorithm will always produce a result in at least one of the ",(0,n.jsx)(o.code,{children:"Accepted proposal"})," or ",(0,n.jsx)(o.code,{children:"Finalized round"})," rows. If a proposal doesn't get accepted in a round, everyone times out and votes ",(0,n.jsx)(o.code,{children:"no"}),". Otherwise, a proposal is visible to someone with a quorum of votes and will eventually be visible to everyone."]}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"some-advantages-of-zug",children:"Some Advantages of Zug"}),"\n",(0,n.jsxs)(o.ul,{children:["\n",(0,n.jsx)(o.li,{children:"Apart from the leader, who has to send the proposed block, each validator node broadcasts only two tiny messages in each round, making the communication overhead very small."}),"\n",(0,n.jsx)(o.li,{children:"Unlike in Highway and Practical Byzantine Fault Tolerance (PBFT), and similar to pipelined protocols like HotStuff, only one round of messages (the echoes) is needed for the next leader to propose a block, reducing the delay between a block and its child."}),"\n",(0,n.jsxs)(o.li,{children:["But ",(0,n.jsx)(o.em,{children:"unlike"})," HotStuff, Zug can finalize a block without waiting for its child or grandchild. And, unlike Highway, it does so without waiting for any timeout. Even if a network is configured to produce only one block per minute, every block gets finalized within seconds, as fast as the network connections allow."]}),"\n",(0,n.jsx)(o.li,{children:"Zug's technical description is more flexible than Highway's, giving us a family of related, correct implementations from which to choose."}),"\n"]}),"\n",(0,n.jsx)(o.h2,{id:"comparison-with-highway",children:"Comparison with Highway"}),"\n",(0,n.jsxs)(o.p,{children:["Unlike Highway, Zug does not use a communication history DAG. Highway sends larger messages due to citing and is slower. Zug does not have any notion of citing units, as does Highway, and relies on exchanging signed messages. On the other hand, Highway allows for more fine-grained ",(0,n.jsx)(o.a,{href:"#block-rewards",children:"block rewards"}),"."]}),"\n",(0,n.jsxs)(o.p,{children:["With Zug, finality happens after nodes constituting two-thirds of the network's total weight vote ",(0,n.jsx)(o.code,{children:"true"})," for a round in which the block was proposed or a later round that has this one as an ancestor. Highways' criterion for detecting finality is the presence of a pattern of messages called a ",(0,n.jsx)(o.code,{children:"Summit."})," Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time. Both ways of detecting finality are improvements over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect."]}),"\n",(0,n.jsx)(o.p,{children:"Highway and Zug offer flexibility in terms of fault tolerance thresholds. Highway allows different clients to follow the protocol with varying thresholds, each with its own balance between security and latency. However, if a sufficient number of validators are online, Zug demonstrates lower latency than Highway at any threshold. This is because Zug does not have predefined, rigid values for the round length, and its design allows the network to adapt to actual delays. If delays occur, block times may vary. Otherwise, blocks should appear as soon as they are finalized. Highway has a defined minimum round length, and the round lengths have to be powers of two times that minimum. Zug has a defined minimum round length, but a round can finish anytime as soon as enough messages are successfully exchanged. So, with Zug, there is no need to wait for a power of two times the minimum if the actual time falls somewhere between."}),"\n",(0,n.jsx)(o.p,{children:"Highway is a much more complicated protocol than Zug. Implementing it takes more than twice as many lines of code. Also, Highway's proof of correctness has proved more difficult to verify than Zug's. Zug will make it easier for third parties to create compatible node software that works with the Casper node."}),"\n",(0,n.jsx)(o.p,{children:"Using Zug consensus and smaller messages, the network could scale to a larger number of validators."}),"\n",(0,n.jsx)(o.h3,{id:"block-rewards",children:"Block Rewards"}),"\n",(0,n.jsx)(o.p,{children:"Using a DAG in Highway makes fine-grained information about the validators' behavior available temporarily in the protocol state, so block rewards can be tuned to incentivize full participation in the consensus protocol. However, this does not apply at the end of each era. Any message sent after the era's last block was proposed cannot be taken into account, even though these messages are still needed to finalize that block. And this granularity comes at a cost: Highway messages are relatively big."}),"\n",(0,n.jsx)(o.p,{children:"The current system does not reward finality signatures, which are arguably the most important outcome. The signatures are the user-visible proof, signed by the validators, that an executed block is correct."}),"\n",(0,n.jsx)(o.p,{children:"In Zug, messages are much smaller, so a smaller incentive is needed to send them."}),"\n",(0,n.jsx)(o.p,{children:"Casper 2.0.0 will distribute a configurable fraction of the seigniorage as a reward for finality signatures and the rest as a simple reward for each block, both proportionally to the validators' stakes."}),"\n",(0,n.jsx)(o.p,{children:"This new reward system is simpler, fairer, predictable, and transparent. It will give equal weight to all blocks (including at the end of an era), but it will not take into account every single consensus message."}),"\n",(0,n.jsx)(o.h2,{id:"read-the-paper",children:"Read the Paper"}),"\n",(0,n.jsxs)(o.p,{children:["Here, we describe Zug, an implementation of the ideas from our paper ",(0,n.jsx)(o.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),". The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the ",(0,n.jsx)(o.em,{children:"echo"})," messages are used by our Reliable Broadcast implementation, and the ",(0,n.jsx)(o.em,{children:"vote"})," messages are used by our Weakly-terminating Binary Agreement implementation."]})]})}function c(e={}){const{wrapper:o}={...(0,a.R)(),...e.components};return o?(0,n.jsx)(o,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},75470:(e,o,s)=>{s.d(o,{A:()=>n});const n=s.p+"assets/images/zug-example-5515691ed63d9f310e573eb5742c1701.png"},28453:(e,o,s)=>{s.d(o,{R:()=>r,x:()=>i});var n=s(96540);const a={},t=n.createContext(a);function r(e){const o=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(o):{...o,...e}}),[o,e])}function i(e){let o;return o=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(t.Provider,{value:o},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e238c115.03c04108.js b/assets/js/e238c115.03c04108.js new file mode 100644 index 000000000..5d8ffce18 --- /dev/null +++ b/assets/js/e238c115.03c04108.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[40229],{18822:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Z",a={id:"concepts/glossary/Z",title:"Z",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Z.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Z",permalink:"/1.5.X/concepts/glossary/Z",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Y",permalink:"/1.5.X/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"z",children:"Z"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/e238c115.2aaf7fc9.js b/assets/js/e238c115.2aaf7fc9.js deleted file mode 100644 index 065f8b726..000000000 --- a/assets/js/e238c115.2aaf7fc9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[229],{18822:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Z",a={id:"concepts/glossary/Z",title:"Z",description:"---",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/Z.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Z",permalink:"/concepts/glossary/Z",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Y",permalink:"/concepts/glossary/Y"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"z",children:"Z"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2509bb6.6b2e5db8.js b/assets/js/e2509bb6.6b2e5db8.js new file mode 100644 index 000000000..0b284af1a --- /dev/null +++ b/assets/js/e2509bb6.6b2e5db8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[15196],{98442:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>d,default:()=>h,frontMatter:()=>s,metadata:()=>o,toc:()=>r});var t=a(74848),i=a(28453);const s={title:"Bonding"},d="Bonding as a Validator",o={id:"operators/becoming-a-validator/bonding",title:"Bonding",description:"It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.",source:"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/bonding.md",sourceDirName:"operators/becoming-a-validator",slug:"/operators/becoming-a-validator/bonding",permalink:"/2.0.0/operators/becoming-a-validator/bonding",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Bonding"},sidebar:"operators",previous:{title:"Becoming a Validator",permalink:"/2.0.0/operators/becoming-a-validator/"},next:{title:"Unbonding",permalink:"/2.0.0/operators/becoming-a-validator/unbonding"}},c={},r=[{value:"Method 1: Bonding with the System Auction Contract",id:"bonding-system-auction",level:2},{value:"Method 2: Bonding with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Checking the Bid Status",id:"check-the-status-of-the-bid-in-the-auction",level:2},{value:"A Losing Bid",id:"losing-bid",level:2},{value:"Avoiding Ejection",id:"avoiding-ejection",level:2},{value:"Withdrawing a Bid",id:"withdrawing-a-bid",level:2}];function l(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"bonding-as-a-validator",children:"Bonding as a Validator"})}),"\n",(0,t.jsxs)(n.p,{children:["It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," contract. The auction runs for a future era, every era. The ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era."]}),"\n",(0,t.jsxs)(n.p,{children:["In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, ",(0,t.jsx)(n.strong,{children:"the time for bid submission to inclusion in the validator set is a minimum of six hours"}),". Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-system-auction",children:"Method 1: Bonding with the System Auction Contract"}),"\n",(0,t.jsxs)(n.p,{children:["This method submits a bid using the system auction contract. Call the existing ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID_AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Testnet"}),": ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Mainnet"}),": ",(0,t.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.p,{children:"This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point add_bid \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Next, ",(0,t.jsx)(n.a,{href:"#check-the-status-of-the-bid-in-the-auction",children:"check the status of the auction"})," to see if you have won a validator slot."]}),"\n",(0,t.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Bonding with Compiled Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Another way to send a bonding transaction to the network is via a deploy containing the compiled ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". For details, refer to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/joining#step-3-build-contracts",children:"Building the Required Contracts"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The following deploy is a template for sending a bonding request:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://<HOST:PORT> \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='<PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<BID-AMOUNT>'\" \\\n--session-arg \"delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'\"\n--session-arg \"minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'\"\n--session-arg \"maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'\"\n"})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"add_bid.wasm"})," expects three arguments:"]}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"public_key"}),": The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"amount"}),": The bidding amount"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"delegation_rate"}),": Percentage of the rewards that the node operator retains for their services"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"minimum_delegation_amount"})," (optional): Minimum allowed delegation amount in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"maximum_delegation_amount"})," (optional): Maximum allowed delegation amount in motes"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["This method is more expensive than calling the ",(0,t.jsx)(n.code,{children:"add_bid"})," entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR."]})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsxs)(n.p,{children:["Here is an example request to bond using the ",(0,t.jsx)(n.code,{children:"add_bid.wasm"}),". The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo -u casper casper-client put-deploy \\\n--node-address http://65.21.235.219:7777 \\\n--secret-key /etc/casper/validator_keys/secret_key.pem \\\n--chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \\\n--session-arg \"public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'\" \\\n--session-arg \"amount:U512='$[10000 * 1000000000]'\" \\\n--session-arg \"delegation_rate:u8='10'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Next, check the bid status to see if you have won a validator slot."}),"\n",(0,t.jsx)(n.h2,{id:"check-the-status-of-the-bid-in-the-auction",children:"Checking the Bid Status"}),"\n",(0,t.jsxs)(n.p,{children:["Since the bid was submitted using a deploy like any other, perform ",(0,t.jsx)(n.code,{children:"get-deploy"})," using the ",(0,t.jsx)(n.code,{children:"casper-client"}),", to see the execution status."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address http://<HOST:PORT> <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the bid wins the auction, the public key and associated bonded amount will appear in the auction contract as part of the validator set for a future era. To determine if the bid was accepted, query the auction contract:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info --node-address http://<HOST:PORT>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example auction info response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'{\n"jsonrpc": "2.0",\n"result": {\n "bids": [\n {\n "bid": {\n "bonding_purse": "uref-488a0bbc3c3729f5696965da7a3aeee83805392944e36157909da273255fdb85-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012"\n },\n {\n "bid": {\n "bonding_purse": "uref-14e128b099b0c3680100520226e6999b322989586cc22db0630db5ec1329f0a7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87"\n },\n {\n "bid": {\n "bonding_purse": "uref-6c0bf8cee1c0749dd9766376910867a84b2e826eaf6c118fcb0224c7d8d229dd-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "266185120443441810685787",\n "staked_amount": "100000000"\n },\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f"\n },\n {\n "bid": {\n "bonding_purse": "uref-3880b3daf95f962f57e6a4b1589564abf7deef58a1fb0753d1108316bba7b3d7-007",\n "delegation_rate": 10,\n "delegators": [],\n "release_era": null,\n "reward": "0",\n "staked_amount": "9000000000000000"\n },\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643"\n },\n {\n "bid": {\n "bonding_purse": "uref-5a777c9cd53456b49eecf25dcc13e12ddff4106175a69f8e24a7c9a4c135df0d-007",\n "delegation_rate": 0,\n "delegators": [],\n "release_era": null,\n "reward": "93328432442428418861229954179737",\n "staked_amount": "10000000000000000"\n },\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e"\n }\n ],\n "block_height": 318,\n "era_validators": [\n {\n "era_id": 20,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 21,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 22,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n },\n {\n "era_id": 23,\n "validator_weights": [\n {\n "public_key": "013f774a58f4d40bd9b6cce7e306e53646913860ef2a111d00f0fe7794010c4012",\n "weight": "10000000000000000"\n },\n {\n "public_key": "01405133e73ef2946fe3a2d76a4c75d305a04ad6b969f3c4a8a0d27235eb260f87",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01524a5f3567d7b5ea17ca518c9d0320fb4a75a28a5eab58d06c755c388f20a19f",\n "weight": "100000000"\n },\n {\n "public_key": "01a6901408eda702a653805f50060bfe00d5e962747ee7133df64bd7bab50b4643",\n "weight": "9000000000000000"\n },\n {\n "public_key": "01d62fc9b894218bfbe8eebcc4a28a1fc4cb3a5c6120bb0027207ba8214439929e",\n "weight": "10000000000000000"\n }\n ]\n }\n ],\n "state_root_hash": "c16ba80ea200d786008f8100ea79f9cfeb8d7d5ee8b133eda5a50dcf1c7131e8"\n},\n"id": -3624528661787095850\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsxs)(n.p,{children:["Note the ",(0,t.jsx)(n.code,{children:"era_id"})," and the ",(0,t.jsx)(n.code,{children:"validator_weights"})," in the response above. The current era is the one with the lowest ID in the ",(0,t.jsx)(n.code,{children:"era_validators"})," array. For a given ",(0,t.jsx)(n.code,{children:"era_id"}),", a set of validators is defined. If the public key associated with a bid appears in the ",(0,t.jsx)(n.code,{children:"validator_weights"})," structure for an era, then the account is bonded in that era."]}),"\n",(0,t.jsx)(n.h2,{id:"losing-bid",children:"A Losing Bid"}),"\n",(0,t.jsx)(n.p,{children:"If a bid doesn't win a slot in the auction, it is too low. The resolution is to increase the bid amount. It is possible to submit additional bids, to increase the odds of winning a slot. It is also possible to encourage token holders to delegate stake to you for bonding."}),"\n",(0,t.jsx)(n.h2,{id:"avoiding-ejection",children:"Avoiding Ejection"}),"\n",(0,t.jsxs)(n.p,{children:["To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/recovering",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"withdrawing-a-bid",children:"Withdrawing a Bid"}),"\n",(0,t.jsxs)(n.p,{children:["Follow the steps in ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/unbonding",children:"Unbonding"})," to withdraw a bid."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>o});var t=a(96540);const i={},s=t.createContext(i);function d(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:d(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2799c63.caf45662.js b/assets/js/e2799c63.caf45662.js new file mode 100644 index 000000000..d53bfb5e9 --- /dev/null +++ b/assets/js/e2799c63.caf45662.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[99303],{44946:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Endpoints"},o="Node Endpoints",a={id:"operators/setup/node-endpoints",title:"Endpoints",description:"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.",source:"@site/docs/operators/setup/node-endpoints.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-endpoints",permalink:"/operators/setup/node-endpoints",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Endpoints"},sidebar:"operators",previous:{title:"Configuration",permalink:"/operators/setup/basic-node-configuration"},next:{title:"Installation",permalink:"/operators/setup/install-node"}},d={},c=[{value:"Default Networking Port: 35000",id:"35000",level:2},{value:"Default JSON-RPC HTTP Server Port: 7777",id:"7777",level:2},{value:"Default REST HTTP Server Port: 8888",id:"8888",level:2},{value:"Example usage",id:"example-usage",level:3},{value:"Default SSE HTTP Event Stream Server Port: 9999",id:"9999",level:2},{value:"Setting up Firewall Rules",id:"setting-up-firewall-rules",level:2},{value:"Restricting Access for Private Networks",id:"restricting-access-for-private-networks",level:2},{value:"Summary of Related Links",id:"summary-of-related-links",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"node-endpoints",children:"Node Endpoints"})}),"\n",(0,t.jsxs)(n.p,{children:["As specified in the ",(0,t.jsx)(n.a,{href:"/operators/setup/install-node#network-requirements",children:"Network Requirements"}),", a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The ",(0,t.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network Communication"})," page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication."]}),"\n",(0,t.jsx)(n.p,{children:"This document describes in more detail a Casper node's default endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#35000",children:"Networking port: 35000"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#7777",children:"JSON-RPC HTTP server port: 7777"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#8888",children:"REST HTTP server port: 8888"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#9999",children:"SSE HTTP event stream server port: 9999"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Node operators can modify a node's configuration options, including the port settings, by updating the ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"node's config.toml"})," file. An example configuration file can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up."}),"\n",(0,t.jsx)(n.h2,{id:"35000",children:"Default Networking Port: 35000"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for networking are under the ",(0,t.jsx)(n.code,{children:"network"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"bind_address"})," using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the ",(0,t.jsx)(n.code,{children:"config.toml"})," file, the setting is:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"bind_address = '0.0.0.0:35000'\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline."}),"\n",(0,t.jsx)(n.h2,{id:"7777",children:"Default JSON-RPC HTTP Server Port: 7777"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rpc_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," using port 7777 is the listening address for JSON-RPC HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:7777'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["DApps would use this address to ",(0,t.jsx)(n.a,{href:"/developers/json-rpc/",children:"interact with the Casper JSON-RPC API"}),". Users would use this address to ",(0,t.jsx)(n.a,{href:"/developers/cli/",children:"interact with the network using CLI"}),". Validators would use this address to ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"bond"})," or ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"unbond"}),". If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."]}),"\n",(0,t.jsx)(n.h2,{id:"8888",children:"Default REST HTTP Server Port: 8888"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rest_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 8888 is the listening address for the REST HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:8888'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."}),"\n",(0,t.jsxs)(n.p,{children:["One may use this port to ",(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"get a trusted hash"}),", ",(0,t.jsx)(n.a,{href:"/operators/setup/upgrade#verifying-successful-staging",children:"verify successful staging"})," during an upgrade, or to ",(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"confirm that the node is synchronized"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"example-usage",children:"Example usage"}),"\n",(0,t.jsx)(n.p,{children:"For general health metrics, use this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/metrics\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can check the node's status using this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The status endpoint provides a JSON response that can be parsed with ",(0,t.jsx)(n.code,{children:"jq"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...\n {\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can filter the result with dot notation, specifying one of the following parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"api_version"})," - The RPC API version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chainspec_name"})," - The chainspec name, used to identify the currently connected network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"starting_state_root_hash"})," - The state root hash used at the start of the current session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"peers"})," - The node ID and network address of each connected peer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"last_added_block_info"})," - The minimal info of the last Block from the linear chain"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"our_public_signing_key"})," - Our public signing key"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"round_length"})," - The next round length if this node is a validator."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"next_upgrade"})," - Information about the next scheduled upgrade"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"build_version"})," - The compiled node version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"uptime"})," - Time that has passed since the node has started."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is an example command for retrieving general network information:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To get information about the next upgrade, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .next_upgrade\n"})}),"\n",(0,t.jsx)(n.p,{children:"To get information about the last added block, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .last_added_block_info\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor the downloading of blocks to your node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor local block height as well as RPC port status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"9999",children:"Default SSE HTTP Event Stream Server Port: 9999"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the SSE HTTP event stream server are listed under the ",(0,t.jsx)(n.code,{children:"event_stream_server"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 9999 is the listening address for the SSE HTTP event stream server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:9999'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-firewall-rules",children:"Setting up Firewall Rules"}),"\n",(0,t.jsxs)(n.p,{children:["To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,t.jsx)(n.code,{children:"ufw"})," commands below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."}),"\n",(0,t.jsxs)(n.p,{children:["If you have any concerns, questions, or issues, please ",(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/requests/new",children:"submit a request"})," to the Casper support team."]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-access-for-private-networks",children:"Restricting Access for Private Networks"}),"\n",(0,t.jsxs)(n.p,{children:["Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,t.jsx)(n.a,{href:"/operators/setup-network/create-private#network-access-control",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"summary-of-related-links",children:"Summary of Related Links"}),"\n",(0,t.jsx)(n.p,{children:"Here is a summary of the links mentioned on this page:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/install-node#network-requirements",children:"Network requirements"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/concepts/design/p2p",children:"Network communication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#config-file",children:"The node configuration file"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/json-rpc/",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/cli/",children:"Interacting with the network using CLI"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"Bonding"})," or ",(0,t.jsx)(n.a,{href:"/operators/becoming-a-validator/unbonding",children:"unbonding"})," as a validator"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Getting a trusted node hash"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/upgrade#verifying-successful-staging",children:"Verifying successful staging"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"Confirming that the node is synchronized"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/developers/dapps/monitor-and-consume-events",children:"Monitoring and consuming events"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/operators/setup-network/create-private#network-access-control",children:"Private network access control"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2799c63.d128e43e.js b/assets/js/e2799c63.d128e43e.js deleted file mode 100644 index b20cd7f1b..000000000 --- a/assets/js/e2799c63.d128e43e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9303],{44946:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Endpoints"},o="Node Endpoints",a={id:"operators/setup/node-endpoints",title:"Endpoints",description:"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.",source:"@site/docs/operators/setup/node-endpoints.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-endpoints",permalink:"/next/operators/setup/node-endpoints",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Endpoints"},sidebar:"operators",previous:{title:"Configuration",permalink:"/next/operators/setup/basic-node-configuration"},next:{title:"Installation",permalink:"/next/operators/setup/install-node"}},d={},c=[{value:"Default Networking Port: 35000",id:"35000",level:2},{value:"Default JSON-RPC HTTP Server Port: 7777",id:"7777",level:2},{value:"Default REST HTTP Server Port: 8888",id:"8888",level:2},{value:"Example usage",id:"example-usage",level:3},{value:"Default SSE HTTP Event Stream Server Port: 9999",id:"9999",level:2},{value:"Setting up Firewall Rules",id:"setting-up-firewall-rules",level:2},{value:"Restricting Access for Private Networks",id:"restricting-access-for-private-networks",level:2},{value:"Summary of Related Links",id:"summary-of-related-links",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"node-endpoints",children:"Node Endpoints"})}),"\n",(0,t.jsxs)(n.p,{children:["As specified in the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/install-node#network-requirements",children:"Network Requirements"}),", a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The ",(0,t.jsx)(n.a,{href:"/next/concepts/design/p2p",children:"Network Communication"})," page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication."]}),"\n",(0,t.jsx)(n.p,{children:"This document describes in more detail a Casper node's default endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#35000",children:"Networking port: 35000"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#7777",children:"JSON-RPC HTTP server port: 7777"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#8888",children:"REST HTTP server port: 8888"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#9999",children:"SSE HTTP event stream server port: 9999"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Node operators can modify a node's configuration options, including the port settings, by updating the ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#config-file",children:"node's config.toml"})," file. An example configuration file can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up."}),"\n",(0,t.jsx)(n.h2,{id:"35000",children:"Default Networking Port: 35000"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for networking are under the ",(0,t.jsx)(n.code,{children:"network"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"bind_address"})," using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the ",(0,t.jsx)(n.code,{children:"config.toml"})," file, the setting is:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"bind_address = '0.0.0.0:35000'\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline."}),"\n",(0,t.jsx)(n.h2,{id:"7777",children:"Default JSON-RPC HTTP Server Port: 7777"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rpc_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," using port 7777 is the listening address for JSON-RPC HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:7777'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["DApps would use this address to ",(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/",children:"interact with the Casper JSON-RPC API"}),". Users would use this address to ",(0,t.jsx)(n.a,{href:"/next/developers/cli/",children:"interact with the network using CLI"}),". Validators would use this address to ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"bond"})," or ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/unbonding",children:"unbond"}),". If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."]}),"\n",(0,t.jsx)(n.h2,{id:"8888",children:"Default REST HTTP Server Port: 8888"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rest_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 8888 is the listening address for the REST HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:8888'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."}),"\n",(0,t.jsxs)(n.p,{children:["One may use this port to ",(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"get a trusted hash"}),", ",(0,t.jsx)(n.a,{href:"/next/operators/setup/upgrade#verifying-successful-staging",children:"verify successful staging"})," during an upgrade, or to ",(0,t.jsx)(n.a,{href:"/next/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"confirm that the node is synchronized"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"example-usage",children:"Example usage"}),"\n",(0,t.jsx)(n.p,{children:"For general health metrics, use this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/metrics\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can check the node's status using this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The status endpoint provides a JSON response that can be parsed with ",(0,t.jsx)(n.code,{children:"jq"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...\n {\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can filter the result with dot notation, specifying one of the following parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"api_version"})," - The RPC API version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chainspec_name"})," - The chainspec name, used to identify the currently connected network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"starting_state_root_hash"})," - The state root hash used at the start of the current session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"peers"})," - The node ID and network address of each connected peer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"last_added_block_info"})," - The minimal info of the last Block from the linear chain"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"our_public_signing_key"})," - Our public signing key"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"round_length"})," - The next round length if this node is a validator."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"next_upgrade"})," - Information about the next scheduled upgrade"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"build_version"})," - The compiled node version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"uptime"})," - Time that has passed since the node has started."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is an example command for retrieving general network information:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To get information about the next upgrade, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .next_upgrade\n"})}),"\n",(0,t.jsx)(n.p,{children:"To get information about the last added block, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .last_added_block_info\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor the downloading of blocks to your node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor local block height as well as RPC port status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"9999",children:"Default SSE HTTP Event Stream Server Port: 9999"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the SSE HTTP event stream server are listed under the ",(0,t.jsx)(n.code,{children:"event_stream_server"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 9999 is the listening address for the SSE HTTP event stream server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:9999'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,t.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-firewall-rules",children:"Setting up Firewall Rules"}),"\n",(0,t.jsxs)(n.p,{children:["To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,t.jsx)(n.code,{children:"ufw"})," commands below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."}),"\n",(0,t.jsxs)(n.p,{children:["If you have any concerns, questions, or issues, please ",(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/requests/new",children:"submit a request"})," to the Casper support team."]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-access-for-private-networks",children:"Restricting Access for Private Networks"}),"\n",(0,t.jsxs)(n.p,{children:["Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,t.jsx)(n.a,{href:"/next/operators/setup-network/create-private#network-access-control",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"summary-of-related-links",children:"Summary of Related Links"}),"\n",(0,t.jsx)(n.p,{children:"Here is a summary of the links mentioned on this page:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup/install-node#network-requirements",children:"Network requirements"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/concepts/design/p2p",children:"Network communication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#config-file",children:"The node configuration file"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/developers/json-rpc/",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/developers/cli/",children:"Interacting with the network using CLI"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"Bonding"})," or ",(0,t.jsx)(n.a,{href:"/next/operators/becoming-a-validator/unbonding",children:"unbonding"})," as a validator"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Getting a trusted node hash"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup/upgrade#verifying-successful-staging",children:"Verifying successful staging"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"Confirming that the node is synchronized"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/developers/dapps/monitor-and-consume-events",children:"Monitoring and consuming events"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/next/operators/setup-network/create-private#network-access-control",children:"Private network access control"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e289ead3.1f169ca7.js b/assets/js/e289ead3.1f169ca7.js deleted file mode 100644 index 9f154829b..000000000 --- a/assets/js/e289ead3.1f169ca7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7394],{46593:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var t=s(74848),i=s(28453);const o={},a="Consensus in a Casper Network",r={id:"concepts/design/consensus",title:"Consensus in a Casper Network",description:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.",source:"@site/docs/concepts/design/consensus.md",sourceDirName:"concepts/design",slug:"/concepts/design/consensus",permalink:"/next/concepts/design/consensus",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Communication",permalink:"/next/concepts/design/p2p"},next:{title:"Zug Consensus",permalink:"/next/concepts/design/zug"}},c={},l=[{value:"Safety, Liveness, and Byzantine Fault Tolerance",id:"safety-liveness-and-byzantine-fault-tolerance",level:2},{value:"Casper Consensus Protocols",id:"casper-consensus-protocols",level:2},{value:"Consensus in the Casper Mainnet",id:"consensus-in-the-casper-mainnet",level:2},{value:"Dynamic Round Length",id:"dynamic-round-length",level:3},{value:"Eras",id:"eras",level:3},{value:"Finality",id:"finality",level:3},{value:"Important Links",id:"important-links",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"consensus-in-a-casper-network",children:"Consensus in a Casper Network"})}),"\n",(0,t.jsx)(n.p,{children:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block."}),"\n",(0,t.jsx)(n.h2,{id:"safety-liveness-and-byzantine-fault-tolerance",children:"Safety, Liveness, and Byzantine Fault Tolerance"}),"\n",(0,t.jsxs)(n.p,{children:["In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The ",(0,t.jsx)(n.a,{href:"/next/transactions-and-transaction-lifecycle",children:"Transaction Lifecycle"})," describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called ",(0,t.jsx)(n.strong,{children:"safety"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called ",(0,t.jsx)(n.strong,{children:"liveness"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a ",(0,t.jsx)(n.strong,{children:"Byzantine fault"})," and thus secure against malicious activity."]}),"\n",(0,t.jsx)(n.p,{children:"To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Safety"}),": All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Liveness"}),": The network runs indefinitely and adds new blocks to the chain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Byzantine Fault Tolerance (BFT)"}),": All honest nodes eventually agree on the final value, even if some are faulty."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"casper-consensus-protocols",children:"Casper Consensus Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are ",(0,t.jsx)(n.a,{href:"/next/concepts/design/zug",children:"Zug"})," and ",(0,t.jsx)(n.a,{href:"/next/concepts/design/highway",children:"Highway"}),". ",(0,t.jsx)(n.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"})," served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper ",(0,t.jsx)(n.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),", which describes how Zug meets the safety, liveness, and resiliency requirements."]}),"\n",(0,t.jsx)(n.h2,{id:"consensus-in-the-casper-mainnet",children:"Consensus in the Casper Mainnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper Mainnet is a ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P#proof-of-stake",children:"Proof-of-Stake"})," network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N#node",children:"nodes"}),", which participate in the consensus process by staking CSPR tokens. These active nodes are known as ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validators"}),". The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus."]}),"\n",(0,t.jsxs)(n.p,{children:["The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are ",(0,t.jsx)(n.em,{children:"honest"})," nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model."})}),"\n",(0,t.jsx)(n.h3,{id:"dynamic-round-length",children:"Dynamic Round Length"}),"\n",(0,t.jsx)(n.p,{children:"Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner."}),"\n",(0,t.jsx)(n.h3,{id:"eras",children:"Eras"}),"\n",(0,t.jsx)(n.p,{children:"The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Data Reduction"}),' - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.']}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Banning Equivocators"})," - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Rotating Validators"})," - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (",(0,t.jsx)(n.code,{children:"current era"}),"+ 2)."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (",(0,t.jsx)(n.code,{children:"current era"})," + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain."]}),"\n",(0,t.jsxs)(n.p,{children:["The final block of an era is a ",(0,t.jsx)(n.em,{children:"switch block"})," and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the ",(0,t.jsx)(n.em,{children:"switch block"})," and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/consensus",children:"Consensus Economics"})," page."]}),"\n",(0,t.jsx)(n.h3,{id:"finality",children:"Finality"}),"\n",(0,t.jsx)(n.p,{children:"Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart."}),"\n",(0,t.jsx)(n.p,{children:"On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously."}),"\n",(0,t.jsx)(n.h2,{id:"important-links",children:"Important Links"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/design/zug",children:"Zug Consensus"})," - An overview of the Zug consensus used in Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/design/highway",children:"Highway Consensus"})," - Brief overview of the Highway consensus available as an alternative to Zug"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e289ead3.b2eba89f.js b/assets/js/e289ead3.b2eba89f.js new file mode 100644 index 000000000..07985db68 --- /dev/null +++ b/assets/js/e289ead3.b2eba89f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[77394],{46593:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>o,metadata:()=>r,toc:()=>l});var t=s(74848),i=s(28453);const o={},a="Consensus in a Casper Network",r={id:"concepts/design/consensus",title:"Consensus in a Casper Network",description:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.",source:"@site/docs/concepts/design/consensus.md",sourceDirName:"concepts/design",slug:"/concepts/design/consensus",permalink:"/concepts/design/consensus",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"concepts",previous:{title:"Network Communication",permalink:"/concepts/design/p2p"},next:{title:"Zug Consensus",permalink:"/concepts/design/zug"}},c={},l=[{value:"Safety, Liveness, and Byzantine Fault Tolerance",id:"safety-liveness-and-byzantine-fault-tolerance",level:2},{value:"Casper Consensus Protocols",id:"casper-consensus-protocols",level:2},{value:"Consensus in the Casper Mainnet",id:"consensus-in-the-casper-mainnet",level:2},{value:"Dynamic Round Length",id:"dynamic-round-length",level:3},{value:"Eras",id:"eras",level:3},{value:"Finality",id:"finality",level:3},{value:"Important Links",id:"important-links",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"consensus-in-a-casper-network",children:"Consensus in a Casper Network"})}),"\n",(0,t.jsx)(n.p,{children:"The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block."}),"\n",(0,t.jsx)(n.h2,{id:"safety-liveness-and-byzantine-fault-tolerance",children:"Safety, Liveness, and Byzantine Fault Tolerance"}),"\n",(0,t.jsxs)(n.p,{children:["In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The ",(0,t.jsx)(n.a,{href:"/transactions-and-transaction-lifecycle",children:"Transaction Lifecycle"})," describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called ",(0,t.jsx)(n.strong,{children:"safety"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called ",(0,t.jsx)(n.strong,{children:"liveness"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a ",(0,t.jsx)(n.strong,{children:"Byzantine fault"})," and thus secure against malicious activity."]}),"\n",(0,t.jsx)(n.p,{children:"To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Safety"}),": All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Liveness"}),": The network runs indefinitely and adds new blocks to the chain."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Byzantine Fault Tolerance (BFT)"}),": All honest nodes eventually agree on the final value, even if some are faulty."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"casper-consensus-protocols",children:"Casper Consensus Protocols"}),"\n",(0,t.jsxs)(n.p,{children:["Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are ",(0,t.jsx)(n.a,{href:"/concepts/design/zug",children:"Zug"})," and ",(0,t.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway"}),". ",(0,t.jsx)(n.a,{href:"https://arxiv.org/pdf/2101.02159.pdf",children:"Highway"})," served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper ",(0,t.jsx)(n.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),", which describes how Zug meets the safety, liveness, and resiliency requirements."]}),"\n",(0,t.jsx)(n.h2,{id:"consensus-in-the-casper-mainnet",children:"Consensus in the Casper Mainnet"}),"\n",(0,t.jsxs)(n.p,{children:["The Casper Mainnet is a ",(0,t.jsx)(n.a,{href:"/concepts/glossary/P#proof-of-stake",children:"Proof-of-Stake"})," network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of ",(0,t.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"nodes"}),", which participate in the consensus process by staking CSPR tokens. These active nodes are known as ",(0,t.jsx)(n.a,{href:"/concepts/glossary/V#validator",children:"validators"}),". The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus."]}),"\n",(0,t.jsxs)(n.p,{children:["The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are ",(0,t.jsx)(n.em,{children:"honest"})," nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model."})}),"\n",(0,t.jsx)(n.h3,{id:"dynamic-round-length",children:"Dynamic Round Length"}),"\n",(0,t.jsx)(n.p,{children:"Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner."}),"\n",(0,t.jsx)(n.h3,{id:"eras",children:"Eras"}),"\n",(0,t.jsx)(n.p,{children:"The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Data Reduction"}),' - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.']}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Banning Equivocators"})," - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras."]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.strong,{children:"Rotating Validators"})," - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (",(0,t.jsx)(n.code,{children:"current era"}),"+ 2)."]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (",(0,t.jsx)(n.code,{children:"current era"})," + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain."]}),"\n",(0,t.jsxs)(n.p,{children:["The final block of an era is a ",(0,t.jsx)(n.em,{children:"switch block"})," and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the ",(0,t.jsx)(n.em,{children:"switch block"})," and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the ",(0,t.jsx)(n.a,{href:"/concepts/economics/consensus",children:"Consensus Economics"})," page."]}),"\n",(0,t.jsx)(n.h3,{id:"finality",children:"Finality"}),"\n",(0,t.jsx)(n.p,{children:"Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart."}),"\n",(0,t.jsx)(n.p,{children:"On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously."}),"\n",(0,t.jsx)(n.h2,{id:"important-links",children:"Important Links"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/design/zug",children:"Zug Consensus"})," - An overview of the Zug consensus used in Mainnet and Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/concepts/design/highway",children:"Highway Consensus"})," - Brief overview of the Highway consensus available as an alternative to Zug"]}),"\n"]})]})}function d(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>r});var t=s(96540);const i={},o=t.createContext(i);function a(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2975a84.51a6b884.js b/assets/js/e2975a84.51a6b884.js new file mode 100644 index 000000000..0efbf40d9 --- /dev/null +++ b/assets/js/e2975a84.51a6b884.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[58204],{33467:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=n(74848),o=n(28453);const s={title:"What is a dApp?"},i="What is a dApp?",r={id:"developers/dapps/dapp",title:"What is a dApp?",description:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/dapp.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/dapp",permalink:"/1.5.X/developers/dapps/dapp",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"What is a dApp?"},sidebar:"developers",previous:{title:"Overview of Casper dApps",permalink:"/1.5.X/developers/dapps/"},next:{title:"Prerequisites",permalink:"/1.5.X/developers/dapps/prerequisites"}},c={},d=[{value:"How are Decentralized Applications Different?",id:"how-are-decentralized-applications-different",level:2},{value:"Interacting with a Decentralized Network",id:"interacting-with-a-decentralized-network",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"what-is-a-dapp",children:"What is a dApp?"})}),"\n",(0,a.jsx)(t.p,{children:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network."}),"\n",(0,a.jsx)(t.p,{children:"The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself."}),"\n",(0,a.jsx)(t.h2,{id:"how-are-decentralized-applications-different",children:"How are Decentralized Applications Different?"}),"\n",(0,a.jsxs)(t.p,{children:["A decentralized system consists of a group of interchangeable machines that can perform as a full system or ",(0,a.jsx)(t.code,{children:"distributed database"}),". Additional machines strengthen the overall system by adding redundancy and computational power."]}),"\n",(0,a.jsxs)(t.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"node"}),". The ",(0,a.jsx)(t.code,{children:"decentralized"})," aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsxs)(t.p,{children:["Routine operations in a decentralized network may result in nodes coming on or offline. This ",(0,a.jsx)(t.em,{children:"node churn"})," can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node."]}),"\n",(0,a.jsx)(t.h2,{id:"interacting-with-a-decentralized-network",children:"Interacting with a Decentralized Network"}),"\n",(0,a.jsxs)(t.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploys"})," via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. ",(0,a.jsx)(t.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Sending a Deploy"})," to a node will result in that node ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution."]}),"\n",(0,a.jsxs)(t.p,{children:["A Deploy contains ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later."]}),"\n",(0,a.jsx)(t.p,{children:"Sending a Deploy is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy."}),"\n",(0,a.jsx)(t.p,{children:"All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."}),"\n",(0,a.jsx)(t.p,{children:"Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy."}),"\n",(0,a.jsxs)(t.p,{children:["There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The ",(0,a.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy Lifecycle"})," results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const o={},s=a.createContext(o);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2975a84.5efeb63f.js b/assets/js/e2975a84.5efeb63f.js deleted file mode 100644 index eb063faef..000000000 --- a/assets/js/e2975a84.5efeb63f.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8204],{33467:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>p,frontMatter:()=>s,metadata:()=>r,toc:()=>d});var a=n(74848),o=n(28453);const s={title:"What is a dApp?"},i="What is a dApp?",r={id:"developers/dapps/dapp",title:"What is a dApp?",description:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.",source:"@site/versioned_docs/version-1.5.X/developers/dapps/dapp.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/dapp",permalink:"/developers/dapps/dapp",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"What is a dApp?"},sidebar:"developers",previous:{title:"Overview of Casper dApps",permalink:"/developers/dapps/"},next:{title:"Prerequisites",permalink:"/developers/dapps/prerequisites"}},c={},d=[{value:"How are Decentralized Applications Different?",id:"how-are-decentralized-applications-different",level:2},{value:"Interacting with a Decentralized Network",id:"interacting-with-a-decentralized-network",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"what-is-a-dapp",children:"What is a dApp?"})}),"\n",(0,a.jsx)(t.p,{children:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network."}),"\n",(0,a.jsx)(t.p,{children:"The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself."}),"\n",(0,a.jsx)(t.h2,{id:"how-are-decentralized-applications-different",children:"How are Decentralized Applications Different?"}),"\n",(0,a.jsxs)(t.p,{children:["A decentralized system consists of a group of interchangeable machines that can perform as a full system or ",(0,a.jsx)(t.code,{children:"distributed database"}),". Additional machines strengthen the overall system by adding redundancy and computational power."]}),"\n",(0,a.jsxs)(t.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"node"}),". The ",(0,a.jsx)(t.code,{children:"decentralized"})," aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsxs)(t.p,{children:["Routine operations in a decentralized network may result in nodes coming on or offline. This ",(0,a.jsx)(t.em,{children:"node churn"})," can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node."]}),"\n",(0,a.jsx)(t.h2,{id:"interacting-with-a-decentralized-network",children:"Interacting with a Decentralized Network"}),"\n",(0,a.jsxs)(t.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(t.a,{href:"/concepts/glossary/D#deploy",children:"Deploys"})," via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. ",(0,a.jsx)(t.a,{href:"/developers/cli/sending-deploys",children:"Sending a Deploy"})," to a node will result in that node ",(0,a.jsx)(t.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution."]}),"\n",(0,a.jsxs)(t.p,{children:["A Deploy contains ",(0,a.jsx)(t.a,{href:"/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(t.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later."]}),"\n",(0,a.jsx)(t.p,{children:"Sending a Deploy is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy."}),"\n",(0,a.jsx)(t.p,{children:"All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."}),"\n",(0,a.jsx)(t.p,{children:"Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy."}),"\n",(0,a.jsxs)(t.p,{children:["There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The ",(0,a.jsx)(t.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy Lifecycle"})," results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase."]})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var a=n(96540);const o={},s=a.createContext(o);function i(e){const t=a.useContext(s);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:i(e.components),a.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2f5312b.06dbe2a4.js b/assets/js/e2f5312b.06dbe2a4.js deleted file mode 100644 index cf807e75b..000000000 --- a/assets/js/e2f5312b.06dbe2a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1997],{97687:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const i={},o="Condor Release Notes for Exchanges",a={id:"resources/condor-for-exchanges",title:"Condor Release Notes for Exchanges",description:"Account/Contract Merge",source:"@site/versioned_docs/version-1.5.X/resources/condor-for-exchanges.md",sourceDirName:"resources",slug:"/resources/condor-for-exchanges",permalink:"/resources/condor-for-exchanges",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},c={},l=[{value:"Account/Contract Merge",id:"accountcontract-merge",level:2},{value:"Dynamic Pricing",id:"dynamic-pricing",level:2},{value:"Transaction Types",id:"transaction-types",level:2},{value:"Block Restructure",id:"block-restructure",level:2},{value:"Contract Level Events",id:"contract-level-events",level:2},{value:"Zug Consensus Protocol",id:"zug-consensus-protocol",level:2},{value:"Server-Sent Event (SSE) Endpoint Changes",id:"server-sent-event-sse-endpoint-changes",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"condor-release-notes-for-exchanges",children:"Condor Release Notes for Exchanges"})}),"\n",(0,s.jsx)(n.h2,{id:"accountcontract-merge",children:"Account/Contract Merge"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, Casper contains separate Accounts and Contracts. These record types are similar, but contain small differences. Condor merges these two into one record called AddressableEntity."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"All existing Account and Contract records will be migrated upon on-chain interaction (i.e., sending of transactions, native transfers)."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"All new \u201caccounts\u201d and \u201ccontracts\u201d created on the system will result in an AddressableEntity record being created."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"PublicKeys and AccountHashes for existing Account records remain in place and continue to function with the corresponding AddressableEntity record."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Named keys are now a top-level concern and stored directly in global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The outcome and behavior of named keys is the same; this is an implementation detail addressing the scalability issues of the previous design."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Similarly, entry points for smart contracts are now a top level concern, with each entry point being stored directly in global state rather than embedded within an AddressableEntity record.."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: While the Casper node software handles all on-chain interactions with these new data structures, any off-chain logic that retrieves Account and/or Contract records from the blockchain for any purpose (i.e., processing, storage, indexing, etc) will need to be modified to retrieve and use the AddressableEntity record structure going forward."})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h1,{id:"fee-elimination",children:"Fee Elimination"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Condor adds support for configurable fee, refund, and pricing strategies. The current plan is to roll out Condor with \u201cNoFee\u201d mode on. Rather than transferring tokens from a paying purse, they are now placed on hold temporarily."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There is a configurable interval that determines how long a balance hold remains in effect. The available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The held portion of a purse balance is not available to transfer or spend until it is released."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The on-chain logic calculates the correct values for total balance and available balance. Off-chain logic can continue to use the existing query_balance endpoint, which will return the available balance. This is sufficient for the majority of use cases. However, off-chain logic that wants to get the full details including total, available, and all hold records can use the new query_balance_details RPC endpoint."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Overall, placing holds rather than taking fees is beneficial to exchanges and other parties who send periodic transactions to the network, as their gas costs return to them over time rather than being spent."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Existing implementations should generally not need to change anything to take advantage of this behavior of the system."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Any advanced platform with automated funding that periodically tops off operating balances with new tokens to replace spent gas would benefit from some consideration of this new behavior."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Advanced platforms seeking optimal scheduling strategies would benefit from retrieving the hold records for their operating purse(s) to calculate projected future available balances and use that to inform the scheduling of automated transaction submissions."})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"dynamic-pricing",children:"Dynamic Pricing"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, the gas price on the Casper network is equal to 1, meaning 1 unit of gas costs 1 mote. Condor introduces a configurable gas price multiplier. If turned on, at the end of each era a calculation is run to determine block usage in the current era and adjust the multiplier for the era that is starting."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"If overall block use rises above a threshold the gas price goes up by 1, if use falls below a threshold the gas price goes down by 1. If use remains within those thresholds the gas price remains the same."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The gas price will not go up or down by more than 1 in a given era, and will not go above the maximum or below the minimum threshold."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The minimum and maximum gas prices and the go-up and go-down threshold are configurable."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The current gas price is used as a straight multiplier to determine actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1, but would cost 2 CSPR if the current gas price is 2."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The calculated gas price has been added to the block header to make it easily discoverable (for determining what the current price is), and for posterity (for determining what the gas price was for a given era in the historical context)."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: During times of high network usage, you may find that costs for interacting with the blockchain increase. Plan accordingly for any transactions."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"As a quality of life feature for those operating on a strict budget, transactions have a gas_tolerance field, which allows the sender of a transaction to specify the maximum gas price they are willing to pay for (minimum 1). For instance, if a transaction is sent with gas_tolerance = 2 and the network is currently at gas price 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price later walks down to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transaction-types",children:"Transaction Types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, work to be done on the Casper network is sent using the Deploy structure. With Condor we are transitioning to a Transaction model. There are some structural changes introduced to support more advanced features."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Under the new Transaction model, Condor offers direct support for native / Wasm-less usage of all user-land mint and stake management actions."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Existing off-chain systems should determine if their operation continues to work using the legacy Deploy model support."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"In cases where legacy integration remains compatible, upgrading to take advantage of the new Transaction model can be delayed temporarily or indefinitely until the removal of Deploys with a later release."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"In cases where one or more incompatibilities have been introduced, some fix short of a full upgrade to the Transaction model may be possible on a case by case basis, but a forced upgrade may be preferable or even necessary in some cases."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Even off-chain systems that continue to work using legacy support may want to consider upgrading to the new Transaction model to take advantage of efficiencies or new capabilities."})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"block-restructure",children:"Block Restructure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The structure of the Block record is being modified as part of Condor. As all blocks are immutable once added to the chain, previously produced blocks remain in their original format. All new blocks produced after Condor will have the new format. The change in structure can be seen ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/docs/blob/feat-2.0_docs/source/docs/casper/developers/json-rpc/types_chain.md#blockv2-blockv2",children:"here in the upcoming documentation changes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: While existing client software (including SDKs) remain able to request and parse historical blocks that use the original Block structure, they must be upgraded to request and parse new blocks if they wish to continue to follow the chain. This is the primary breaking change for most off-chain consumers of the Casper network."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"To continue to service historical/archival usage of old blocks, such software should not code over or remove handling for the original block structure. Instead they should retain that capability and add handling for the new block structure."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract-level-events",children:"Contract Level Events"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Condor adds support for smart contracts to define message topics and emit their own messages which are passed to the event stream for consumption as contract level events. Details on this feature can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/ceps/blob/master/text/0088-contract-level-messages.md",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: As this is an entirely new feature, existing systems do not have to change anything."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"Some existing smart contracts have adopted a convention using one or more dictionaries to approximate contract level events. Such smart contracts cannot directly address spoofing, and repudiation protection requires off-chain support. Thus, they should consider making the necessary changes to their logic to take advantage of the built in and safe support offered in Condor."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"zug-consensus-protocol",children:"Zug Consensus Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The Zug Consensus Protocol will replace Highway on the Casper network alongside the Condor release. Other instances of a Casper network (private/hybrid networks) may choose to use either Highway or Zug."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Information on Zug\u2019s implementation can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/docs/blob/feat-2.0_docs/source/docs/casper/concepts/design/zug.md",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A more in-depth view of Zug and the theory behind it can be found ",(0,s.jsx)(n.a,{href:"https://arxiv.org/abs/2205.06314",children:"here"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: None."})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"server-sent-event-sse-endpoint-changes",children:"Server-Sent Event (SSE) Endpoint Changes"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Due to the previously mentioned structural changes to certain record kinds, most notably the Block record structure and the transition from the Deploy model to the Transaction model, and the addition of contract level events in the form of Messages, there are breaking changes to the contents of the event stream."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The changes are minor schematic changes and rather obvious; for instance instead of a DeployProcessed event there is a TransactionProcessed event, instead of a DeployExpired event there is a TransactionExpired event, and so on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The overall verbs and their behavioral semantics remain the same (BlockAdded, ~Accepted, ~Processed, ~Expired, etc)."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Existing software (including SDKs) that deserializes the JSON produced by the SSE event stream will require updating to continue to follow the event stream post-Condor. Software that does not follow the event stream is unaffected."})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e2f5312b.d4f136f1.js b/assets/js/e2f5312b.d4f136f1.js new file mode 100644 index 000000000..ee6533846 --- /dev/null +++ b/assets/js/e2f5312b.d4f136f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31997],{97687:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var s=t(74848),r=t(28453);const i={},o="Condor Release Notes for Exchanges",a={id:"resources/condor-for-exchanges",title:"Condor Release Notes for Exchanges",description:"Account/Contract Merge",source:"@site/versioned_docs/version-1.5.X/resources/condor-for-exchanges.md",sourceDirName:"resources",slug:"/resources/condor-for-exchanges",permalink:"/1.5.X/resources/condor-for-exchanges",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{}},c={},l=[{value:"Account/Contract Merge",id:"accountcontract-merge",level:2},{value:"Dynamic Pricing",id:"dynamic-pricing",level:2},{value:"Transaction Types",id:"transaction-types",level:2},{value:"Block Restructure",id:"block-restructure",level:2},{value:"Contract Level Events",id:"contract-level-events",level:2},{value:"Zug Consensus Protocol",id:"zug-consensus-protocol",level:2},{value:"Server-Sent Event (SSE) Endpoint Changes",id:"server-sent-event-sse-endpoint-changes",level:2}];function d(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"condor-release-notes-for-exchanges",children:"Condor Release Notes for Exchanges"})}),"\n",(0,s.jsx)(n.h2,{id:"accountcontract-merge",children:"Account/Contract Merge"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, Casper contains separate Accounts and Contracts. These record types are similar, but contain small differences. Condor merges these two into one record called AddressableEntity."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"All existing Account and Contract records will be migrated upon on-chain interaction (i.e., sending of transactions, native transfers)."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"All new \u201caccounts\u201d and \u201ccontracts\u201d created on the system will result in an AddressableEntity record being created."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"PublicKeys and AccountHashes for existing Account records remain in place and continue to function with the corresponding AddressableEntity record."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Named keys are now a top-level concern and stored directly in global state."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The outcome and behavior of named keys is the same; this is an implementation detail addressing the scalability issues of the previous design."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Similarly, entry points for smart contracts are now a top level concern, with each entry point being stored directly in global state rather than embedded within an AddressableEntity record.."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: While the Casper node software handles all on-chain interactions with these new data structures, any off-chain logic that retrieves Account and/or Contract records from the blockchain for any purpose (i.e., processing, storage, indexing, etc) will need to be modified to retrieve and use the AddressableEntity record structure going forward."})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h1,{id:"fee-elimination",children:"Fee Elimination"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Condor adds support for configurable fee, refund, and pricing strategies. The current plan is to roll out Condor with \u201cNoFee\u201d mode on. Rather than transferring tokens from a paying purse, they are now placed on hold temporarily."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"There is a configurable interval that determines how long a balance hold remains in effect. The available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The held portion of a purse balance is not available to transfer or spend until it is released."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The on-chain logic calculates the correct values for total balance and available balance. Off-chain logic can continue to use the existing query_balance endpoint, which will return the available balance. This is sufficient for the majority of use cases. However, off-chain logic that wants to get the full details including total, available, and all hold records can use the new query_balance_details RPC endpoint."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Overall, placing holds rather than taking fees is beneficial to exchanges and other parties who send periodic transactions to the network, as their gas costs return to them over time rather than being spent."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Existing implementations should generally not need to change anything to take advantage of this behavior of the system."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Any advanced platform with automated funding that periodically tops off operating balances with new tokens to replace spent gas would benefit from some consideration of this new behavior."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Advanced platforms seeking optimal scheduling strategies would benefit from retrieving the hold records for their operating purse(s) to calculate projected future available balances and use that to inform the scheduling of automated transaction submissions."})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"dynamic-pricing",children:"Dynamic Pricing"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, the gas price on the Casper network is equal to 1, meaning 1 unit of gas costs 1 mote. Condor introduces a configurable gas price multiplier. If turned on, at the end of each era a calculation is run to determine block usage in the current era and adjust the multiplier for the era that is starting."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"If overall block use rises above a threshold the gas price goes up by 1, if use falls below a threshold the gas price goes down by 1. If use remains within those thresholds the gas price remains the same."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The gas price will not go up or down by more than 1 in a given era, and will not go above the maximum or below the minimum threshold."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The minimum and maximum gas prices and the go-up and go-down threshold are configurable."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The current gas price is used as a straight multiplier to determine actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1, but would cost 2 CSPR if the current gas price is 2."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The calculated gas price has been added to the block header to make it easily discoverable (for determining what the current price is), and for posterity (for determining what the gas price was for a given era in the historical context)."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: During times of high network usage, you may find that costs for interacting with the blockchain increase. Plan accordingly for any transactions."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"As a quality of life feature for those operating on a strict budget, transactions have a gas_tolerance field, which allows the sender of a transaction to specify the maximum gas price they are willing to pay for (minimum 1). For instance, if a transaction is sent with gas_tolerance = 2 and the network is currently at gas price 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price later walks down to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"transaction-types",children:"Transaction Types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Currently, work to be done on the Casper network is sent using the Deploy structure. With Condor we are transitioning to a Transaction model. There are some structural changes introduced to support more advanced features."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Under the new Transaction model, Condor offers direct support for native / Wasm-less usage of all user-land mint and stake management actions."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Existing off-chain systems should determine if their operation continues to work using the legacy Deploy model support."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"In cases where legacy integration remains compatible, upgrading to take advantage of the new Transaction model can be delayed temporarily or indefinitely until the removal of Deploys with a later release."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"In cases where one or more incompatibilities have been introduced, some fix short of a full upgrade to the Transaction model may be possible on a case by case basis, but a forced upgrade may be preferable or even necessary in some cases."})}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Even off-chain systems that continue to work using legacy support may want to consider upgrading to the new Transaction model to take advantage of efficiencies or new capabilities."})}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"block-restructure",children:"Block Restructure"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["The structure of the Block record is being modified as part of Condor. As all blocks are immutable once added to the chain, previously produced blocks remain in their original format. All new blocks produced after Condor will have the new format. The change in structure can be seen ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/docs/blob/feat-2.0_docs/source/docs/casper/developers/json-rpc/types_chain.md#blockv2-blockv2",children:"here in the upcoming documentation changes"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: While existing client software (including SDKs) remain able to request and parse historical blocks that use the original Block structure, they must be upgraded to request and parse new blocks if they wish to continue to follow the chain. This is the primary breaking change for most off-chain consumers of the Casper network."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"To continue to service historical/archival usage of old blocks, such software should not code over or remove handling for the original block structure. Instead they should retain that capability and add handling for the new block structure."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"contract-level-events",children:"Contract Level Events"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Condor adds support for smart contracts to define message topics and emit their own messages which are passed to the event stream for consumption as contract level events. Details on this feature can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/ceps/blob/master/text/0088-contract-level-messages.md",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: As this is an entirely new feature, existing systems do not have to change anything."})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.strong,{children:"Some existing smart contracts have adopted a convention using one or more dictionaries to approximate contract level events. Such smart contracts cannot directly address spoofing, and repudiation protection requires off-chain support. Thus, they should consider making the necessary changes to their logic to take advantage of the built in and safe support offered in Condor."})}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"zug-consensus-protocol",children:"Zug Consensus Protocol"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The Zug Consensus Protocol will replace Highway on the Casper network alongside the Condor release. Other instances of a Casper network (private/hybrid networks) may choose to use either Highway or Zug."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Information on Zug\u2019s implementation can be found ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/docs/blob/feat-2.0_docs/source/docs/casper/concepts/design/zug.md",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["A more in-depth view of Zug and the theory behind it can be found ",(0,s.jsx)(n.a,{href:"https://arxiv.org/abs/2205.06314",children:"here"}),"."]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: None."})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"server-sent-event-sse-endpoint-changes",children:"Server-Sent Event (SSE) Endpoint Changes"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Due to the previously mentioned structural changes to certain record kinds, most notably the Block record structure and the transition from the Deploy model to the Transaction model, and the addition of contract level events in the form of Messages, there are breaking changes to the contents of the event stream."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The changes are minor schematic changes and rather obvious; for instance instead of a DeployProcessed event there is a TransactionProcessed event, instead of a DeployExpired event there is a TransactionExpired event, and so on."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"The overall verbs and their behavioral semantics remain the same (BlockAdded, ~Accepted, ~Processed, ~Expired, etc)."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Action Items: Existing software (including SDKs) that deserializes the JSON produced by the SSE event stream will require updating to continue to follow the event stream post-Condor. Software that does not follow the event stream is unaffected."})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>a});var s=t(96540);const r={},i=s.createContext(r);function o(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e3f9a068.2511d6f6.js b/assets/js/e3f9a068.2511d6f6.js deleted file mode 100644 index 8651e6d5c..000000000 --- a/assets/js/e3f9a068.2511d6f6.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1561],{86271:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const c={title:"Multi-Sig Workflow"},d="Multi-Signature Workflow",r={id:"resources/advanced/multi-sig/multi-sig-workflow",title:"Multi-Sig Workflow",description:"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/multi-sig-workflow.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/multi-sig-workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Multi-Sig Workflow"},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/resources/advanced/multi-sig/"},next:{title:"Additional Examples",permalink:"/resources/advanced/multi-sig/other-scenarios"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Session Code Required for Key Management",id:"session-code-required-for-key-management",level:2},{value:"Tutorial Workflow",id:"tutorial-workflow",level:2},{value:"Step 1: Clone the example Wasm for this workflow",id:"step-1-clone-the-example-wasm-for-this-workflow",level:3},{value:"Step 2: Build the sample Wasm provided",id:"step-2-build-the-sample-wasm-provided",level:3},{value:"Step 3: Increase the primary key's weight to set thresholds",id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",level:3},{value:"Step 4: Update the account's action thresholds",id:"step-4-update-the-accounts-action-thresholds",level:3},{value:"Step 5: Add associated keys to the primary account",id:"step-5-add-associated-keys-to-the-primary-account",level:3},{value:"Step 6: Send a deploy from the primary account",id:"step-6-send-a-deploy-from-the-primary-account",level:3},{value:"Step 7: Send a multi-signature deploy from an associated key",id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",level:3},{value:"Removing a Compromised Key",id:"removing-a-compromised-key",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"multi-signature-workflow",children:"Multi-Signature Workflow"})}),"\n",(0,t.jsxs)(n.p,{children:["The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," tutorial, among other prerequisites. You will also need the Casper CLI client to use the ",(0,t.jsx)(n.code,{children:"make-deploy"}),", ",(0,t.jsx)(n.code,{children:"sign-deploy"}),", and ",(0,t.jsx)(n.code,{children:"send-deploy"})," Casper CLI client commands."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"The following prerequisites are required for this workflow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"development environment prerequisites"}),", including a ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"funded account"})," and the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper CLI client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Complete the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow and set up the source account for multi-signature deploys"]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the Casper ",(0,t.jsx)(n.a,{href:"/concepts/design/casper-design#accounts-head",children:"account-based model"})," before proceeding"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"session-code-required-for-key-management",children:"Session Code Required for Key Management"}),"\n",(0,t.jsx)(n.p,{children:"To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Do not run these examples on Mainnet. Update each command for your environment."})}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-workflow",children:"Tutorial Workflow"}),"\n",(0,t.jsx)(n.h3,{id:"step-1-clone-the-example-wasm-for-this-workflow",children:"Step 1: Clone the example Wasm for this workflow"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"multi-sig GitHub repository"})," contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you take a look at the repository structure and open the ",(0,t.jsx)(n.code,{children:"contracts"})," folder, you will see session code with different functionality:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_account.wasm"})," - adds an associated account with a specified weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"})," - updates a key\u2019s weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," - updates the account's action thresholds for deployment and account management"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"remove_account.wasm"})," - removes an associated account from the primary account"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-2-build-the-sample-wasm-provided",children:"Step 2: Build the sample Wasm provided"}),"\n",(0,t.jsx)(n.p,{children:"Prepare your environment, build and test the session code provided with the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\nmake prepare\nmake test\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rustup update"})," - checks and updates your Rust installation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make prepare"})," - sets the Wasm target"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make test"})," - builds and verifies the session code"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that in the test folder there is a ",(0,t.jsx)(n.code,{children:"contract.wasm"})," that is needed for the tests to pass. If you run ",(0,t.jsx)(n.code,{children:"make clean"})," that file will be deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",children:"Step 3: Increase the primary key's weight to set thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.code,{children:"key_management"})," threshold. In a later step, you will add the associated accounts that will participate in signing deploys."]}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update the weight of the primary key to 3 by calling the ",(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-<ACCOUNT_HASH>\'" \\\n--session-arg "new_weight:u8=\'3\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The primary key in this account should now have weight 3."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-update-the-accounts-action-thresholds",children:"Step 4: Update the account's action thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["Set up a multi-signature scheme for the account by updating the ",(0,t.jsx)(n.code,{children:"deployment"})," and ",(0,t.jsx)(n.code,{children:"key_management"})," thresholds. The ",(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," will take two arguments and set the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to 2 and the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold to 3."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The account's action thresholds should look like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n'})}),"\n",(0,t.jsx)(n.p,{children:"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-add-associated-keys-to-the-primary-account",children:"Step 5: Add associated keys to the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["To add an associated key to the primary account, use the ",(0,t.jsx)(n.code,{children:"add_account.wasm"})," provided. This example adds two keys to the primary account (",(0,t.jsx)(n.code,{children:"account-hash-d89c*"}),"): ",(0,t.jsx)(n.code,{children:"user_1"})," with ",(0,t.jsx)(n.code,{children:"account-hash-e2d0*"}),", and ",(0,t.jsx)(n.code,{children:"user_2"})," with ",(0,t.jsx)(n.code,{children:"account-hash-04a9*"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."}),"\n",(0,t.jsx)(n.li,{children:"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."}),"\n"]})}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-6-send-a-deploy-from-the-primary-account",children:"Step 6: Send a deploy from the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["This step sends a deploy containing Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"hello-world"})," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h3,{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",children:"Step 7: Send a multi-signature deploy from an associated key"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-deploy"})," - creates and signs a deploy, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-deploy"})," - adds additional signatures for a multi-signature deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-deploy"})," - sends the deploy to the network"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to step 6, this example uses Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument. The deploy needs two signatures to meet the ",(0,t.jsx)(n.code,{children:"deployment"})," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."]}),"\n",(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."]}),"\n",(0,t.jsxs)(n.p,{children:["One associated key creates and signs the deploy with the ",(0,t.jsx)(n.code,{children:"make-deploy"})," command, indicating the account context under which the session code will be executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The second associated key signs the deploy with ",(0,t.jsx)(n.code,{children:"sign-deploy"})," to meet the deployment threshold for the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The deploy can be sent to the network using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.h2,{id:"removing-a-compromised-key",children:"Removing a Compromised Key"}),"\n",(0,t.jsxs)(n.p,{children:["This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," session code."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Remove keys with caution! Do not run this example on Mainnet."}),(0,t.jsx)(n.p,{children:"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution."})]}),"\n",(0,t.jsx)(n.p,{children:"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"add_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The resulting account should not contain the associated key that was just removed."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"N/A (Removed)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.p,{children:["The next section contains ",(0,t.jsx)(n.a,{href:"/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," where Casper's multi-signature feature would be helpful."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(96540);const a={},c=t.createContext(a);function d(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e3f9a068.ee51fe72.js b/assets/js/e3f9a068.ee51fe72.js new file mode 100644 index 000000000..4aa5f909b --- /dev/null +++ b/assets/js/e3f9a068.ee51fe72.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51561],{86271:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>d,default:()=>l,frontMatter:()=>c,metadata:()=>r,toc:()=>o});var t=s(74848),a=s(28453);const c={title:"Multi-Sig Workflow"},d="Multi-Signature Workflow",r={id:"resources/advanced/multi-sig/multi-sig-workflow",title:"Multi-Sig Workflow",description:"The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/multi-sig-workflow.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/multi-sig-workflow",permalink:"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Multi-Sig Workflow"},sidebar:"tutorials",previous:{title:"Introduction",permalink:"/1.5.X/resources/advanced/multi-sig/"},next:{title:"Additional Examples",permalink:"/1.5.X/resources/advanced/multi-sig/other-scenarios"}},i={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Session Code Required for Key Management",id:"session-code-required-for-key-management",level:2},{value:"Tutorial Workflow",id:"tutorial-workflow",level:2},{value:"Step 1: Clone the example Wasm for this workflow",id:"step-1-clone-the-example-wasm-for-this-workflow",level:3},{value:"Step 2: Build the sample Wasm provided",id:"step-2-build-the-sample-wasm-provided",level:3},{value:"Step 3: Increase the primary key's weight to set thresholds",id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",level:3},{value:"Step 4: Update the account's action thresholds",id:"step-4-update-the-accounts-action-thresholds",level:3},{value:"Step 5: Add associated keys to the primary account",id:"step-5-add-associated-keys-to-the-primary-account",level:3},{value:"Step 6: Send a deploy from the primary account",id:"step-6-send-a-deploy-from-the-primary-account",level:3},{value:"Step 7: Send a multi-signature deploy from an associated key",id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",level:3},{value:"Removing a Compromised Key",id:"removing-a-compromised-key",level:2},{value:"Next Steps",id:"next-steps",level:2}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"multi-signature-workflow",children:"Multi-Signature Workflow"})}),"\n",(0,t.jsxs)(n.p,{children:["The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," tutorial, among other prerequisites. You will also need the Casper CLI client to use the ",(0,t.jsx)(n.code,{children:"make-deploy"}),", ",(0,t.jsx)(n.code,{children:"sign-deploy"}),", and ",(0,t.jsx)(n.code,{children:"send-deploy"})," Casper CLI client commands."]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"The following prerequisites are required for this workflow:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"development environment prerequisites"}),", including a ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"funded account"})," and the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper CLI client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Complete the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow and set up the source account for multi-signature deploys"]}),"\n",(0,t.jsxs)(n.li,{children:["Understand the Casper ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#accounts-head",children:"account-based model"})," before proceeding"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"session-code-required-for-key-management",children:"Session Code Required for Key Management"}),"\n",(0,t.jsx)(n.p,{children:"To manage an account's associated keys and thresholds, you must run session code that executes within the account's context. Note that the session code provided in this workflow is not a general-purpose program and needs to be modified for each use case."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Do not run these examples on Mainnet. Update each command for your environment."})}),"\n",(0,t.jsx)(n.h2,{id:"tutorial-workflow",children:"Tutorial Workflow"}),"\n",(0,t.jsx)(n.h3,{id:"step-1-clone-the-example-wasm-for-this-workflow",children:"Step 1: Clone the example Wasm for this workflow"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/tutorials-example-wasm/tree/dev/multi-sig",children:"multi-sig GitHub repository"})," contains session code that can be used for learning how to configure Casper accounts using associated keys and multi-signature deploys. Clone the repository and navigate to the corresponding folder."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/tutorials-example-wasm/ && cd multi-sig\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If you take a look at the repository structure and open the ",(0,t.jsx)(n.code,{children:"contracts"})," folder, you will see session code with different functionality:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"add_account.wasm"})," - adds an associated account with a specified weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"})," - updates a key\u2019s weight"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," - updates the account's action thresholds for deployment and account management"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"remove_account.wasm"})," - removes an associated account from the primary account"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"step-2-build-the-sample-wasm-provided",children:"Step 2: Build the sample Wasm provided"}),"\n",(0,t.jsx)(n.p,{children:"Prepare your environment, build and test the session code provided with the following commands:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"rustup update\nmake prepare\nmake test\n"})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rustup update"})," - checks and updates your Rust installation"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make prepare"})," - sets the Wasm target"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make test"})," - builds and verifies the session code"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Note that in the test folder there is a ",(0,t.jsx)(n.code,{children:"contract.wasm"})," that is needed for the tests to pass. If you run ",(0,t.jsx)(n.code,{children:"make clean"})," that file will be deleted."]}),"\n",(0,t.jsx)(n.h3,{id:"step-3-increase-the-primary-keys-weight-to-set-thresholds",children:"Step 3: Increase the primary key's weight to set thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["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 ",(0,t.jsx)(n.code,{children:"key_management"})," threshold. In a later step, you will add the associated accounts that will participate in signing deploys."]}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the account hash of the primary key you are working with using a block explorer or the Casper CLI client."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client account-address --public-key <INSERT_PUBLIC_KEY_HEX>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Update the weight of the primary key to 3 by calling the ",(0,t.jsx)(n.code,{children:"update_associated_keys.wasm"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_associated_keys.wasm \\\n--session-arg "associated_key:key=\'account-hash-<ACCOUNT_HASH>\'" \\\n--session-arg "new_weight:u8=\'3\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The primary key in this account should now have weight 3."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-4-update-the-accounts-action-thresholds",children:"Step 4: Update the account's action thresholds"}),"\n",(0,t.jsxs)(n.p,{children:["Set up a multi-signature scheme for the account by updating the ",(0,t.jsx)(n.code,{children:"deployment"})," and ",(0,t.jsx)(n.code,{children:"key_management"})," thresholds. The ",(0,t.jsx)(n.code,{children:"update_thresholds.wasm"})," will take two arguments and set the ",(0,t.jsx)(n.code,{children:"deployment"})," threshold to 2 and the ",(0,t.jsx)(n.code,{children:"key_management"})," threshold to 3."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \\\n--chain-name casper-test \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/update_thresholds.wasm \\\n--session-arg \"deployment_threshold:u8='2'\" \\\n--session-arg \"key_management_threshold:u8='3'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The account's action thresholds should look like this:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"action_thresholds": {\n "deployment": 2,\n "key_management": 3\n},\n'})}),"\n",(0,t.jsx)(n.p,{children:"This account configuration requires a cumulative weight of 3 to manage keys and a cumulative weight of 2 to send deploys. For example, if two associated keys have weight 1, they must both sign and send the deploy as part of this account context. The cumulative weight of these two keys would not meet the threshold for key management."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-5-add-associated-keys-to-the-primary-account",children:"Step 5: Add associated keys to the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["To add an associated key to the primary account, use the ",(0,t.jsx)(n.code,{children:"add_account.wasm"})," provided. This example adds two keys to the primary account (",(0,t.jsx)(n.code,{children:"account-hash-d89c*"}),"): ",(0,t.jsx)(n.code,{children:"user_1"})," with ",(0,t.jsx)(n.code,{children:"account-hash-e2d0*"}),", and ",(0,t.jsx)(n.code,{children:"user_2"})," with ",(0,t.jsx)(n.code,{children:"account-hash-04a9*"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Now, the account should have one primary key with weight 3, and two associated accounts, each with weight 1."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"All associated keys should be kept incredibly secure to ensure the security and integrity of the account."}),"\n",(0,t.jsx)(n.li,{children:"After all associated keys and action thresholds have been set to the desired multi-signature scheme, the weight of the original primary key can be increased or lowered, depending on your use case. Be careful with this! If you lower the primary key's weight below the key management threshold, the account will require multiple signatures for key management. The account will be unusable if you do not have enough associated keys set up."}),"\n"]})}),"\n",(0,t.jsx)(n.p,{children:"The table below summarizes the updates."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsx)(n.h3,{id:"step-6-send-a-deploy-from-the-primary-account",children:"Step 6: Send a deploy from the primary account"}),"\n",(0,t.jsxs)(n.p,{children:["This step sends a deploy containing Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The source code for the Wasm comes from the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"hello-world"})," repository. The deploy should succeed as the primary account has a weight of 3, which is greater than the deployment threshold."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy --chain-name casper-test \\\n--payment-amount 3000000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/secret_key.pem \\\n--session-arg \"my-key-name:string='primary_account_key'\" \\\n--session-arg \"message:string='Hello, World'\"\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"named_keys": [\n {\n "key": "uref-9b9ecaa9e5e235fc6955d4d528cb1b5b38f2d800f6cbbc55351131a3701b5a81-007",\n "name": "my-key-name"\n }\n]\n'})}),"\n",(0,t.jsx)(n.h3,{id:"step-7-send-a-multi-signature-deploy-from-an-associated-key",children:"Step 7: Send a multi-signature deploy from an associated key"}),"\n",(0,t.jsx)(n.p,{children:"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:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"make-deploy"})," - creates and signs a deploy, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"sign-deploy"})," - adds additional signatures for a multi-signature deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"send-deploy"})," - sends the deploy to the network"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to step 6, this example uses Wasm (",(0,t.jsx)(n.code,{children:"contract.wasm"}),"), which adds a named key to the account. The deploy originates from the primary account, specified with the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument. The deploy needs two signatures to meet the ",(0,t.jsx)(n.code,{children:"deployment"})," weight equal to 2. Once both associated keys sign the deploy, either can send it to the network."]}),"\n",(0,t.jsxs)(n.p,{children:["When using the ",(0,t.jsx)(n.code,{children:"--session-account"})," argument, specify the hex-encoded public key of the primary account context under which the session code will be executed."]}),"\n",(0,t.jsxs)(n.p,{children:["One associated key creates and signs the deploy with the ",(0,t.jsx)(n.code,{children:"make-deploy"})," command, indicating the account context under which the session code will be executed."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-deploy --chain-name casper-test \\\n--payment-amount 300000000 \\\n--session-path tests/wasm/contract.wasm \\\n--secret-key $PATH/user_1_secret_key.pem \\\n--session-arg \"my-key-name:string='user_1_key'\" \\\n--session-arg \"message:string='Hello, World'\" \\\n--session-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--output hello_world_one_signature\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The second associated key signs the deploy with ",(0,t.jsx)(n.code,{children:"sign-deploy"})," to meet the deployment threshold for the account."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy -i hello_world_one_signature -k $PATH/user_2_secret_key.pem -o hello_world_two_signatures\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The deploy can be sent to the network using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy --node-address https://rpc.testnet.casperlabs.io -i hello_world_two_signatures\n"})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"hello_world.wasm"})," should have run and added a named key to the account."]}),"\n",(0,t.jsx)(n.h2,{id:"removing-a-compromised-key",children:"Removing a Compromised Key"}),"\n",(0,t.jsxs)(n.p,{children:["This example shows how to remove a compromised key from an account. The example adds an associated key only to remove it using the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," session code."]}),"\n",(0,t.jsxs)(n.admonition,{type:"caution",children:[(0,t.jsx)(n.p,{children:"Remove keys with caution! Do not run this example on Mainnet."}),(0,t.jsx)(n.p,{children:"Before removing a key, ensure the remaining associated keys can combine their weight to meet the threshold for key management. Otherwise, the account could become unusable. Changing key weights or adding new associated keys would only be possible by meeting the key management threshold. Proceed with caution."})]}),"\n",(0,t.jsx)(n.p,{children:"Given the current setup, the primary account will add an associated key, and then remove it. In other use cases, associated keys may need to combine their signatures to send a multi-sig deploy that removes a key."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/add_account.wasm \\\n--session-arg "new_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8" \\\n--session-arg "weight:u8=\'1\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"add_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"N/A"}),(0,t.jsx)(n.td,{children:"1"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"remove_account.wasm"})," will remove the newly added account to demonstrate the possibility of removing associated keys that may have been compromised."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address https://rpc.testnet.casperlabs.io/ \\\n--chain-name "casper-test" \\\n--payment-amount 500000000 \\\n--secret-key $PATH/secret_key.pem \\\n--session-path target/wasm32-unknown-unknown/release/remove_account.wasm \\\n--session-arg "remove_key:key=\'account-hash-1fed34baa6807a7868bb18f91b161d99ebf21763810fe4c92e39775d10bbf1f8"\n'})}),"\n",(0,t.jsx)(n.p,{children:"Verify that the deploy ran successfully."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy --node-address https://rpc.testnet.casperlabs.io/ <DEPLOY_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"Retrieve the latest state root hash and check the primary account details."}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address https://rpc.testnet.casperlabs.io/\n\ncasper-client query-global-state \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--state-root-hash <STATE_ROOT_HASH> \\\n--key account-hash-<PRIMARY_ACCOUNT_HASH>\n"})}),"\n",(0,t.jsx)(n.p,{children:"The resulting account should not contain the associated key that was just removed."}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Account details"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-04a9691a9f8f05a0f08bd686f188b27c7dbcd644b415759fd3ca043d916ea02f",\n "weight": 1\n },\n {\n "account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "weight": 3\n },\n {\n "account_hash": "account-hash-e2d00525cac31ae2756fb155f289d276c6945b6914923fe275de0cb127bffee7",\n "weight": 1\n }\n ],\n "main_purse": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-007",\n "named_keys": []\n}\n'})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["The table below summarizes the updates after calling the ",(0,t.jsx)(n.code,{children:"remove_account.wasm"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Threshold / Key"}),(0,t.jsx)(n.th,{children:"Previous weight"}),(0,t.jsx)(n.th,{children:"Current weight"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"deployment"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"2"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.code,{children:"key_management"})}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Primary key (",(0,t.jsx)(n.code,{children:"1ed5..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"3"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"04a9..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"e2d0..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"1"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:["Associated key (",(0,t.jsx)(n.code,{children:"1fed..."}),")"]}),(0,t.jsx)(n.td,{children:"1"}),(0,t.jsx)(n.td,{children:"N/A (Removed)"})]})]})]}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.p,{children:["The next section contains ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/advanced/multi-sig/other-scenarios",children:"additional examples"})," where Casper's multi-signature feature would be helpful."]})]})}function l(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>r});var t=s(96540);const a={},c=t.createContext(a);function d(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e45056bc.816736bc.js b/assets/js/e45056bc.816736bc.js new file mode 100644 index 000000000..d34a5d881 --- /dev/null +++ b/assets/js/e45056bc.816736bc.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22527],{72814:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var s=t(74848),r=t(28453);const a={},o="Go SDK",d={id:"developers/dapps/sdk/go-sdk",title:"Go SDK",description:"Usage Examples",source:"@site/docs/developers/dapps/sdk/go-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/go-sdk",permalink:"/developers/dapps/sdk/go-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:".NET SDK",permalink:"/developers/dapps/sdk/csharp-sdk"},next:{title:"Python SDK",permalink:"/developers/dapps/sdk/python-sdk"}},l={},c=[{value:"Usage Examples",id:"usage-examples",level:2},{value:"Get a Deploy from the Network",id:"get-a-deploy-from-the-network",level:3},{value:"Handle the Deploy Processed Event",id:"handle-the-deploy-processed-event",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"go-sdk",children:"Go SDK"})}),"\n",(0,s.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,s.jsx)(n.p,{children:"This section includes some examples of how to use Go SDK:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"#get-a-deploy-from-the-network",children:["Get a ",(0,s.jsx)(n.em,{children:"Deploy"})," from the Network"]})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a Transfer"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"get-a-deploy-from-the-network",children:"Get a Deploy from the Network"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "fmt"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n)\n\nfunc main() {\n handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https://<Node Address and Port>/events")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n'})})]})}function i(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e45056bc.9693a59b.js b/assets/js/e45056bc.9693a59b.js deleted file mode 100644 index 2b79d35f7..000000000 --- a/assets/js/e45056bc.9693a59b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2527],{72814:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>a,metadata:()=>d,toc:()=>c});var s=t(74848),r=t(28453);const a={},o="Go SDK",d={id:"developers/dapps/sdk/go-sdk",title:"Go SDK",description:"Usage Examples",source:"@site/docs/developers/dapps/sdk/go-sdk.md",sourceDirName:"developers/dapps/sdk",slug:"/developers/dapps/sdk/go-sdk",permalink:"/next/developers/dapps/sdk/go-sdk",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:".NET SDK",permalink:"/next/developers/dapps/sdk/csharp-sdk"},next:{title:"Python SDK",permalink:"/next/developers/dapps/sdk/python-sdk"}},l={},c=[{value:"Usage Examples",id:"usage-examples",level:2},{value:"Get a Deploy from the Network",id:"get-a-deploy-from-the-network",level:3},{value:"Handle the Deploy Processed Event",id:"handle-the-deploy-processed-event",level:3},{value:"Sending a Transfer",id:"sending-a-transfer",level:3}];function p(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"go-sdk",children:"Go SDK"})}),"\n",(0,s.jsx)(n.h2,{id:"usage-examples",children:"Usage Examples"}),"\n",(0,s.jsx)(n.p,{children:"This section includes some examples of how to use Go SDK:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsxs)(n.a,{href:"#get-a-deploy-from-the-network",children:["Get a ",(0,s.jsx)(n.em,{children:"Deploy"})," from the Network"]})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#sending-a-transfer",children:"Sending a Transfer"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"get-a-deploy-from-the-network",children:"Get a Deploy from the Network"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "fmt"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n)\n\nfunc main() {\n handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"\n deploy, err := client.GetDeploy(context.Background(), deployHash)\n if err != nil {\n return\n }\n fmt.Println(deploy.Deploy.Hash)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"handle-the-deploy-processed-event",children:"Handle the Deploy Processed Event"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "log"\n\n "github.com/make-software/casper-go-sdk/sse"\n)\n\nfunc main() {\n client := sse.NewClient("https://<Node Address and Port>/events")\n defer client.Stop()\n client.RegisterHandler(\n sse.DeployProcessedEventType,\n func(ctx context.Context, rawEvent sse.RawEvent) error {\n deploy, err := rawEvent.ParseAsDeployProcessedEvent()\n if err != nil {\n return err\n }\n log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)\n return nil\n })\n lastEventID := 1234\n client.Start(context.TODO(), lastEventID)\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"sending-a-transfer",children:"Sending a Transfer"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-go",children:'package main\n\nimport (\n "context"\n "encoding/hex"\n "log"\n "math/big"\n "net/http"\n\n "github.com/make-software/casper-go-sdk/casper"\n "github.com/make-software/casper-go-sdk/types/clvalue"\n)\n\nfunc main() {\n accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")\n if err != nil { return }\n amount := big.NewInt(100000000)\n session := casper.ExecutableDeployItem{\n ModuleBytes: &casper.ModuleBytes{\n ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),\n Args: (&casper.Args{}).\n AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).\n AddArgument("amount", *clvalue.NewCLUInt512(amount)),\n },\n }\n\n payment := casper.StandardPayment(amount)\n\n deployHeader := casper.DefaultHeader()\n deployHeader.Account = accountPublicKey\n deployHeader.ChainName = "casper-test"\n\n newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)\n\n handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)\n client := casper.NewRPCClient(handler)\n result, err := client.PutDeploy(context.Background(), *newDeploy)\n\n log.Println(result.DeployHash)\n}\n'})})]})}function i(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>d});var s=t(96540);const r={},a=s.createContext(r);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e4d870e1.abd2b6f0.js b/assets/js/e4d870e1.abd2b6f0.js new file mode 100644 index 000000000..c527817db --- /dev/null +++ b/assets/js/e4d870e1.abd2b6f0.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[25751],{10935:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},r="Fungible Tokens (CEP-18) Implementation and Usage",i={id:"resources/beginner/cep18",title:"Fungible Tokens",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-1.5.X/resources/beginner/cep18.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/cep18",permalink:"/1.5.X/resources/tutorials/beginner/cep18",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},sidebar:"tutorials",previous:{title:"Contract Upgrades",permalink:"/1.5.X/resources/tutorials/beginner/upgrade-contract"},next:{title:"AWS Casper Nodes",permalink:"/1.5.X/resources/tutorials/beginner/aws-node"}},l={},c=[{value:"Outline of the Tutorial",id:"outline",level:2},{value:"ERC-20 Standard",id:"erc20-standard",level:2},{value:"Interaction of ERC-20 Based Tokens with the Uniswap Standard",id:"erc20-uniswap",level:2},{value:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges",id:"erc20-implications",level:2},{value:"The Casper CEP-18 Standard",id:"cep18-standard",level:2},{value:"Creating a CEP-18 Token on the Testnet",id:"cep18-testnet",level:2},{value:"Clone and Compile the CEP-18 Contract",id:"cep18-contract-clone",level:3},{value:"Install the CEP-18 Contract",id:"cep18-contract-install",level:3},{value:"Query the Entry Points in the CEP-18 contract",id:"cep18-contract-clone",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"fungible-tokens-cep-18-implementation-and-usage",children:"Fungible Tokens (CEP-18) Implementation and Usage"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"outline",children:"Outline of the Tutorial"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-standard",children:"ERC-20 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain."}),"\n",(0,s.jsx)(n.p,{children:"It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana.\nSome key points of the ERC-20 standard include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Optional metadata functions like ",(0,s.jsx)(n.code,{children:"name()"}),", ",(0,s.jsx)(n.code,{children:"symbol()"}),", and ",(0,s.jsx)(n.code,{children:"decimals()"}),", which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets.\nBy adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-uniswap",children:"Interaction of ERC-20 Based Tokens with the Uniswap Standard"}),"\n",(0,s.jsx)(n.p,{children:"By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2."}),"\n",(0,s.jsx)(n.p,{children:"Uniswap V2 uses ERC-20 tokens in the following scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Listing Tokens \u2013 Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard."}),"\n",(0,s.jsx)(n.li,{children:"Liquidity Pools \u2013 any two pairs of ERC-20 tokens can be used to create a liquidity pool."}),"\n",(0,s.jsxs)(n.li,{children:["Uniswap V2 uses the ERC-20 standard ",(0,s.jsx)(n.code,{children:"transfer()"})," function to allow an exchange of tokens within the liquidity pools."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erc20-implications",children:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges"}),"\n",(0,s.jsx)(n.p,{children:"There exist at least two different implementations of the ERC-20 Standard on Casper networks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/Rengo-Labs/casper-erc20",children:"Rengo-Labs implementation"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market implementation"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks."}),"\n",(0,s.jsx)(n.p,{children:"The following considerations should be applied when trying to create an ERC-20 Token:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Interoperability \u2013 Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Project Security Audits \u2013 Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ecosystem \u2013 The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities."}),"\n",(0,s.jsx)(n.h2,{id:"cep18-standard",children:"The Casper CEP-18 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"allowance"})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approve"})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance_of"})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"decimals"})," - Returns the decimal places applied to the balance of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," - Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"symbol"})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"total_supply"})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer"})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from"})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more detail on these methods, there is a reference implementation available on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"cep18-testnet",children:"Creating a CEP-18 Token on the Testnet"}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Clone and Compile the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state."}),"\n",(0,s.jsxs)(n.p,{children:["If you are unsure how to interact with Casper Contracts please refer to the following tutorial: ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We will clone the token repository and prepare the token contract for sending in a Deploy."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tgit clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" cd cep18\n make prepare\n make build-contract\n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"build-contract"})," finishes with an error ",(0,s.jsx)(n.code,{children:"wasm-strip: command not found"}),", make sure you install an additional package on MacOS:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" brew install wabt\n"})})]}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tmake test\n"})}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-install",children:"Install the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet."}),"\n",(0,s.jsx)(n.p,{children:"Use the following template to install the contract on the Testnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777 \n\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should obtain a response similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"An exemplary deploy to the Casper Testnet is as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n'})}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Always be mindful of the ",(0,s.jsx)(n.code,{children:"--secret-key"})," and ",(0,s.jsx)(n.code,{children:"--session-path"})," arguments.\nPath provided to the arguments should always be with regard to the current folder, where the command is executed."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"keys"})," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored."]})]}),"\n",(0,s.jsxs)(n.p,{children:["The response from the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command should look like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," the state of the deploy can be checked:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the execution results we can see, that the deploy was successful:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n... \n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,s.jsx)(n.code,{children:"Out of gas error"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Query the Entry Points in the CEP-18 contract"}),"\n",(0,s.jsx)(n.p,{children:"Get the state root hash from the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n"})}),"\n",(0,s.jsx)(n.p,{children:"Your response should look similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The above command will query the contract for the name. The template for the query is ",(0,s.jsx)(n.code,{children:"contract_name/named_key"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You will obtain the following response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Try to query the contract for other Named Keys and check how the contract behaves."}),"\n",(0,s.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,s.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Explained the ERC20 standard and what the implications are for not using the standard implementations."}),"\n",(0,s.jsx)(n.li,{children:"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."}),"\n",(0,s.jsx)(n.li,{children:"Installed the contract on the Testnet"}),"\n",(0,s.jsxs)(n.li,{children:["Called an entry point on the contract to get the value of the Named Key ",(0,s.jsx)(n.code,{children:"name"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e4d870e1.f85bd94e.js b/assets/js/e4d870e1.f85bd94e.js deleted file mode 100644 index f4ea56c34..000000000 --- a/assets/js/e4d870e1.f85bd94e.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5751],{10935:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>i,toc:()=>c});var s=t(74848),a=t(28453);const o={title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},r="Fungible Tokens (CEP-18) Implementation and Usage",i={id:"resources/beginner/cep18",title:"Fungible Tokens",description:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:",source:"@site/versioned_docs/version-1.5.X/resources/beginner/cep18.md",sourceDirName:"resources/beginner",slug:"/resources/tutorials/beginner/cep18",permalink:"/resources/tutorials/beginner/cep18",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Fungible Tokens",slug:"/resources/tutorials/beginner/cep18"},sidebar:"tutorials",previous:{title:"Contract Upgrades",permalink:"/resources/tutorials/beginner/upgrade-contract"},next:{title:"AWS Casper Nodes",permalink:"/resources/tutorials/beginner/aws-node"}},l={},c=[{value:"Outline of the Tutorial",id:"outline",level:2},{value:"ERC-20 Standard",id:"erc20-standard",level:2},{value:"Interaction of ERC-20 Based Tokens with the Uniswap Standard",id:"erc20-uniswap",level:2},{value:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges",id:"erc20-implications",level:2},{value:"The Casper CEP-18 Standard",id:"cep18-standard",level:2},{value:"Creating a CEP-18 Token on the Testnet",id:"cep18-testnet",level:2},{value:"Clone and Compile the CEP-18 Contract",id:"cep18-contract-clone",level:3},{value:"Install the CEP-18 Contract",id:"cep18-contract-install",level:3},{value:"Query the Entry Points in the CEP-18 contract",id:"cep18-contract-clone",level:3},{value:"Summary",id:"summary",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"fungible-tokens-cep-18-implementation-and-usage",children:"Fungible Tokens (CEP-18) Implementation and Usage"})}),"\n",(0,s.jsx)(n.p,{children:"This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"Developer Prerequisites"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/getting-started",children:"Getting Started with Rust"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"})}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"outline",children:"Outline of the Tutorial"}),"\n",(0,s.jsx)(n.p,{children:"This tutorial explains the purpose of the ERC-20 standard and the Casper CEP-18 Fungible Token implementation, which serves the same purpose for Casper blockchains. It explains the implications of not adhering to the standard and why it is important to base dApps on one common standard implementation supported by the underlying blockchain protocol."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-standard",children:"ERC-20 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The ERC-20 (Ethereum Request for Comment 20) standard is a technical specification used for creating and implementing tokens on the Ethereum blockchain."}),"\n",(0,s.jsx)(n.p,{children:"It outlines a set of rules and interfaces that tokens must adhere to in order to be compatible with the broader Ethereum ecosystem. ERC-20 tokens have become the most widely adopted and recognized token standard on Ethereum network and other Blockchain protocols like NEAR or Solana.\nSome key points of the ERC-20 standard include:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A set of functions and events that a token contract must implement to enable basic functionalities such as transferring tokens between addresses, checking token balances, and approving third-party spending of tokens. These functions include transfer(), balanceOf(), approve(), transferFrom(), and others. The tokens are not sent between wallet addresses. Instead, the token contract creates an owner list to track how many tokens are owned by which owner address."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Optional metadata functions like ",(0,s.jsx)(n.code,{children:"name()"}),", ",(0,s.jsx)(n.code,{children:"symbol()"}),", and ",(0,s.jsx)(n.code,{children:"decimals()"}),", which provide additional information about the token. These functions allow for the retrieval of token name, ticker symbol, and decimal places for proper display and identification purposes."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"A common set of rules for token developers to follow concerning security and consistency. This helps prevent potential vulnerabilities and ensures that tokens behave predictably across different platforms and wallets.\nBy adhering to the ERC-20 standard, token developers can leverage the existing infrastructure, wallets, and exchanges that support ERC-20 tokens."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Each blockchain protocol should have one official supported implementation of the ERC-20 Standard as to allow the interoperability of the assets between the protocols."}),"\n",(0,s.jsx)(n.h2,{id:"erc20-uniswap",children:"Interaction of ERC-20 Based Tokens with the Uniswap Standard"}),"\n",(0,s.jsx)(n.p,{children:"By conforming to the ERC-20 specification it is possible to leverage the functionality of decentralized exchange (DEX) implementations like Uniswap V2."}),"\n",(0,s.jsx)(n.p,{children:"Uniswap V2 uses ERC-20 tokens in the following scenarios:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Listing Tokens \u2013 Any ERC-20 token can be listed on Uniswap V2 if it complies with the ERC-20 standard."}),"\n",(0,s.jsx)(n.li,{children:"Liquidity Pools \u2013 any two pairs of ERC-20 tokens can be used to create a liquidity pool."}),"\n",(0,s.jsxs)(n.li,{children:["Uniswap V2 uses the ERC-20 standard ",(0,s.jsx)(n.code,{children:"transfer()"})," function to allow an exchange of tokens within the liquidity pools."]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"erc20-implications",children:"ERC-20 Implementations on Casper and Implications for Decentralized Exchanges"}),"\n",(0,s.jsx)(n.p,{children:"There exist at least two different implementations of the ERC-20 Standard on Casper networks."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/Rengo-Labs/casper-erc20",children:"Rengo-Labs implementation"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market implementation"}),"."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"While both implement the ERC-20 specification using a common set of rules devised from the original ERC-20 Ethereum standard, using different implementations of the standard can introduce complexities and potential risks."}),"\n",(0,s.jsx)(n.p,{children:"The following considerations should be applied when trying to create an ERC-20 Token:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Interoperability \u2013 Different implementations of the ERC-20 standard can hinder seamless integration between tokens, dApps or wallets."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Project Security Audits \u2013 Well-established standards usually undergo a thorough security audit. This ensures a higher level of security and reduces the risk of vulnerabilities."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Ecosystem \u2013 The longer a blockchain network exists, the more widespread a standard implementation like ERC-20 becomes. Using a different implementation may limit availability of supported projects and require additional effort for integration."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Casper Fungible Token Standard establishes a single implementation of the ERC-20 Standard for Casper networks to avoid disparities and incompatibilities."}),"\n",(0,s.jsx)(n.h2,{id:"cep18-standard",children:"The Casper CEP-18 Standard"}),"\n",(0,s.jsx)(n.p,{children:"The CEP-18 Token Standard is a Casper network compliant implementation of ERC-20 that provides the following contract methods to interact with the token contract:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"allowance"})," - Returns the amount of owner\u2019s tokens allowed to be spent by the spender"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"approve"})," - Allows a spender to transfer up to an amount of the direct caller\u2019s tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"balance_of"})," - Returns the token balance of the owner"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"decimals"})," - Returns the decimal places applied to the balance of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," - Returns the name of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"symbol"})," - Returns the symbol of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"total_supply"})," - Returns the total supply of the token"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer"})," - Transfers an amount of tokens from the direct caller to a recipient"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"transfer_from"})," - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["For more detail on these methods, there is a reference implementation available on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"GitHub"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"cep18-testnet",children:"Creating a CEP-18 Token on the Testnet"}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Clone and Compile the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"Building on the construction of a CEP-18 token as explained above, we will be installing our own token contract in global state."}),"\n",(0,s.jsxs)(n.p,{children:["If you are unsure how to interact with Casper Contracts please refer to the following tutorial: ",(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We will clone the token repository and prepare the token contract for sending in a Deploy."}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Clone the Fungible Token contract from the repository."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tgit clone https://github.com/casper-ecosystem/cep18.git\n"})}),"\n",(0,s.jsxs)(n.ol,{start:"2",children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Make any necessary changes to the code for your customization requirements."}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Compile the contract to create the target .wasm file and build the Wasm."}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" cd cep18\n make prepare\n make build-contract\n"})}),"\n",(0,s.jsxs)(n.admonition,{type:"tip",children:[(0,s.jsxs)(n.p,{children:["If the ",(0,s.jsx)(n.code,{children:"build-contract"})," finishes with an error ",(0,s.jsx)(n.code,{children:"wasm-strip: command not found"}),", make sure you install an additional package on MacOS:"]}),(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:" brew install wabt\n"})})]}),"\n",(0,s.jsxs)(n.ol,{start:"4",children:["\n",(0,s.jsx)(n.li,{children:"Build and verify the compiled contract."}),"\n"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\tmake test\n"})}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-install",children:"Install the CEP-18 Contract"}),"\n",(0,s.jsx)(n.p,{children:"As it is important to understand the potential costs of your Deploy, you should send several on Testnet to familiarize yourself before sending a Deploy to Mainnet."}),"\n",(0,s.jsx)(n.p,{children:"Use the following template to install the contract on the Testnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n --node-address http://<HOST:PORT> \\\n --chain-name [NETWORK_NAME]] \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount [AMOUNT] \\\n --session-path [WASM_FILE_PATH]/[File_Name].wasm\n --session-arg <"NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null">\n\n'})}),"\n",(0,s.jsx)(n.p,{children:"Check if the request to the Testnet can be made and get a snapshot of the network with the state root hash:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-state-root-hash --node-address http://78.46.32.13:7777 \n\n"})}),"\n",(0,s.jsx)(n.p,{children:"You should obtain a response similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 3323991011802671610,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "9b43fd7388559c078f363403972cb079d69786259bf6c5cd9cd7adcc14029d74"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"An exemplary deploy to the Casper Testnet is as follows:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\ncasper-client put-deploy \\\n--node-address http://78.46.32.13:7777 \\\n--chain-name casper-test \\\n--secret-key "./keys/secret_key.pem" \\\n--payment-amount 150000000000 \\\n--session-path "./target/wasm32-unknown-unknown/release/cep18.wasm" \\\n--session-arg "name:string=\'CHF Coin\'" \\\n--session-arg "symbol:string=\'CHFC\'" \\\n--session-arg "decimals:u8=\'10\'" \\\n--session-arg "total_supply:u256=\'1000\'"\n\n'})}),"\n",(0,s.jsxs)(n.admonition,{type:"info",children:[(0,s.jsxs)(n.p,{children:["Always be mindful of the ",(0,s.jsx)(n.code,{children:"--secret-key"})," and ",(0,s.jsx)(n.code,{children:"--session-path"})," arguments.\nPath provided to the arguments should always be with regard to the current folder, where the command is executed."]}),(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"keys"})," folder is not a part of the CEP18 folder structure. Optionally you should provide a folder where your keys are stored."]})]}),"\n",(0,s.jsxs)(n.p,{children:["The response from the ",(0,s.jsx)(n.code,{children:"put-deploy"})," command should look like this:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n{\n "id": 5066914343373494745,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "deploy_hash": "19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6"\n }\n}\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"deploy_hash"})," the state of the deploy can be checked:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"\ncasper-client get-deploy \\\n --node-address http://78.46.32.13:7777 19853d1569fec2b0fa36e81f2f24bea77ccf039a399071cb7d4b377202a073d6\n\n"})}),"\n",(0,s.jsx)(n.p,{children:"In the execution results we can see, that the deploy was successful:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'\n... \n "execution_results": [\n {\n "block_hash": "426a8823c1018e75f8c3823d580116269fd272f20e60561dff0565375a95316d",\n "result": {\n "Success": {\n "cost": "140416131900",\n "effect": {\n "operations": [],\n...\n\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Be always mindful of the payment amount during the deploy process. If the amount is too small, then the deploy will fail with ",(0,s.jsx)(n.code,{children:"Out of gas error"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"cep18-contract-clone",children:"Query the Entry Points in the CEP-18 contract"}),"\n",(0,s.jsx)(n.p,{children:"Get the state root hash from the network:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-state-root-hash --node-address http://78.46.32.13:7777\n"})}),"\n",(0,s.jsx)(n.p,{children:"Your response should look similar to:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": 2950480729544096556,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "state_root_hash": "7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705"\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"With the state root hash and the account hash which performed the deploy, you can query the contract arguments."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'casper-client query-global-state --node-address http://78.46.32.13:7777 \\\n--state-root-hash 7706d906fce25dcdadb2a9453f5243a6c72c4444e6c826cf2941157333a48705 \\\n--key account-hash-ee57bb3b39eb66b74a1dcf12f3f0e7d8e906e34b11f85dc05497bf33fbf3a1f9 \\\n-q "cep18_contract_hash_CHF Coin/name"\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The above command will query the contract for the name. The template for the query is ",(0,s.jsx)(n.code,{children:"contract_name/named_key"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"You will obtain the following response:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:'{\n "id": -7058786841478812744,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.15",\n "block_header": null,\n "merkle_proof": "[94526 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "0800000043484620436f696e",\n "cl_type": "String",\n "parsed": "CHF Coin"\n }\n }\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"Try to query the contract for other Named Keys and check how the contract behaves."}),"\n",(0,s.jsx)(n.h2,{id:"summary",children:"Summary"}),"\n",(0,s.jsx)(n.p,{children:"In this tutorial, we:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"Explained the ERC20 standard and what the implications are for not using the standard implementations."}),"\n",(0,s.jsx)(n.li,{children:"Developed a CEP-18 Rust contract on a Casper network and defined the proper arguments for the deploy."}),"\n",(0,s.jsx)(n.li,{children:"Installed the contract on the Testnet"}),"\n",(0,s.jsxs)(n.li,{children:["Called an entry point on the contract to get the value of the Named Key ",(0,s.jsx)(n.code,{children:"name"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>i});var s=t(96540);const a={},o=s.createContext(a);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e5493a21.b67e196f.js b/assets/js/e5493a21.b67e196f.js new file mode 100644 index 000000000..ab41ebbca --- /dev/null +++ b/assets/js/e5493a21.b67e196f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[46607],{90555:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>p,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="Y",a={id:"concepts/glossary/Y",title:"Y",description:"---",source:"@site/docs/concepts/glossary/Y.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Y",permalink:"/concepts/glossary/Y",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"X",permalink:"/concepts/glossary/X"},next:{title:"Z",permalink:"/concepts/glossary/Z"}},l={},h=[];function i(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,n.R)(),...s.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(e.header,{children:(0,c.jsx)(e.h1,{id:"y",children:"Y"})}),"\n",(0,c.jsx)(e.hr,{}),"\n",(0,c.jsxs)(e.p,{children:[(0,c.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(e.hr,{})]})}function p(s={}){const{wrapper:e}={...(0,n.R)(),...s.components};return e?(0,c.jsx)(e,{...s,children:(0,c.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(s){const e=c.useContext(o);return c.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(n):s.components||n:t(s.components),c.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/e5493a21.e2c9467a.js b/assets/js/e5493a21.e2c9467a.js deleted file mode 100644 index 6a6ef101f..000000000 --- a/assets/js/e5493a21.e2c9467a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8988],{90555:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>l,contentTitle:()=>o,default:()=>i,frontMatter:()=>c,metadata:()=>a,toc:()=>h});var r=n(74848),t=n(28453);const c={},o="Y",a={id:"concepts/glossary/Y",title:"Y",description:"---",source:"@site/docs/concepts/glossary/Y.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Y",permalink:"/next/concepts/glossary/Y",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"concepts",previous:{title:"X",permalink:"/next/concepts/glossary/X"},next:{title:"Z",permalink:"/next/concepts/glossary/Z"}},l={},h=[];function x(e){const s={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(s.header,{children:(0,r.jsx)(s.h1,{id:"y",children:"Y"})}),"\n",(0,r.jsx)(s.hr,{}),"\n",(0,r.jsxs)(s.p,{children:[(0,r.jsx)(s.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,r.jsx)(s.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,r.jsx)(s.hr,{})]})}function i(e={}){const{wrapper:s}={...(0,t.R)(),...e.components};return s?(0,r.jsx)(s,{...e,children:(0,r.jsx)(x,{...e})}):x(e)}},28453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>a});var r=n(96540);const t={},c=r.createContext(t);function o(e){const s=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),r.createElement(c.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e5afa1a3.435be811.js b/assets/js/e5afa1a3.435be811.js new file mode 100644 index 000000000..9b932ff42 --- /dev/null +++ b/assets/js/e5afa1a3.435be811.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96578],{12499:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});var t=r(74848),s=r(28453);const i={title:"Overview",slug:"/developers"},o="Developers Overview",d={id:"developers/index",title:"Overview",description:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.",source:"@site/versioned_docs/version-2.0.0/developers/index.md",sourceDirName:"developers",slug:"/developers",permalink:"/2.0.0/developers",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Overview",slug:"/developers"},sidebar:"developers",next:{title:"Development Prerequisites",permalink:"/2.0.0/developers/prerequisites"}},a={},l=[];function c(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"developers-overview",children:"Developers Overview"})}),"\n",(0,t.jsx)(n.p,{children:"This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Topic"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"Development Prerequisites"})}),(0,t.jsx)(n.td,{children:"Setup needed for various workflows"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/essential-crates",children:"Essential Casper Crates"})}),(0,t.jsx)(n.td,{children:"Available Casper crates and the corresponding documentation"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/writing-contracts",children:"Writing On-Chain Code"})}),(0,t.jsx)(n.td,{children:"Writing contracts in Rust and Wasm for a Casper network"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/",children:"Casper JSON-RPC API"})}),(0,t.jsx)(n.td,{children:"Endpoints for developers wishing to interact directly with a Casper node's JSON-RPC API"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/",children:"Building dApps"})}),(0,t.jsx)(n.td,{children:"Useful information for dApp developers"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/",children:"Interacting with the Blockchain Using CLI"})}),(0,t.jsx)(n.td,{children:"Using a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens."})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/2.0.0/resources/build-on-casper/casper-open-source-software",children:"Ecosystem Open-Source Software"})," may provide other helpful examples."]}),"\n",(0,t.jsx)(n.p,{children:"The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together."})]})}function p(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>o,x:()=>d});var t=r(96540);const s={},i=t.createContext(s);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e605c6b3.e7d9d88b.js b/assets/js/e605c6b3.e7d9d88b.js new file mode 100644 index 000000000..3f5130740 --- /dev/null +++ b/assets/js/e605c6b3.e7d9d88b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[96325],{75146:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=a(74848),t=a(28453);const c={title:"Additional Examples"},o="Additional Examples",i={id:"resources/advanced/multi-sig/other-scenarios",title:"Additional Examples",description:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.",source:"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/other-scenarios.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/other-scenarios",permalink:"/2.0.0/resources/advanced/multi-sig/other-scenarios",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Additional Examples"},sidebar:"tutorials",previous:{title:"Multi-Sig Workflow",permalink:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow"},next:{title:"Runtime Return Values",permalink:"/2.0.0/resources/tutorials/advanced/return-values-tutorial"}},r={},d=[{value:"Example 1: An account with a single (primary) key",id:"example-1-an-account-with-a-single-primary-key",level:3},{value:"Example 2: An account with primary and associated keys",id:"example-2-an-account-with-primary-and-associated-keys",level:3},{value:"Example 3: Multi-sig setup for deploys and account updates",id:"example-3-multi-sig-setup-for-deploys-and-account-updates",level:3},{value:"Example 4: Signing deploys but restricting account updates",id:"example-4-signing-deploys-but-restricting-account-updates",level:3},{value:"Example 5: Recovering a lost primary key",id:"example-5-recovering-a-lost-primary-key",level:3}];function l(e){const n={code:"code",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"additional-examples",children:"Additional Examples"})}),"\n",(0,s.jsx)(n.p,{children:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions."}),"\n",(0,s.jsx)(n.h3,{id:"example-1-an-account-with-a-single-primary-key",children:"Example 1: An account with a single (primary) key"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, only one key (",(0,s.jsx)(n.code,{children:"account-hash-a1\u2026"}),") can sign transactions in the name of this account. This key is the primary key of the account and has a ",(0,s.jsx)(n.code,{children:"weight"})," equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 1:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-2-an-account-with-primary-and-associated-keys",children:"Example 2: An account with primary and associated keys"}),"\n",(0,s.jsx)(n.p,{children:"In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 2:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key for key management\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key used for deploys\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-3-multi-sig-setup-for-deploys-and-account-updates",children:"Example 3: Multi-sig setup for deploys and account updates"}),"\n",(0,s.jsx)(n.p,{children:"The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 3:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-4-signing-deploys-but-restricting-account-updates",children:"Example 4: Signing deploys but restricting account updates"}),"\n",(0,s.jsx)(n.p,{children:"This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 4:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-5-recovering-a-lost-primary-key",children:"Example 5: Recovering a lost primary key"}),"\n",(0,s.jsx)(n.p,{children:"This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 5:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-d4\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var s=a(96540);const t={},c=s.createContext(t);function o(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e7589c2a.a8005701.js b/assets/js/e7589c2a.a8005701.js new file mode 100644 index 000000000..622dbbeca --- /dev/null +++ b/assets/js/e7589c2a.a8005701.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[32831],{73122:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>t,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>l,toc:()=>d});var s=n(74848),r=n(28453);const a={},c="Major Structures",l={id:"concepts/serialization/structures",title:"Major Structures",description:"Account",source:"@site/versioned_docs/version-2.0.0/concepts/serialization/structures.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/structures",permalink:"/2.0.0/concepts/serialization/structures",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Primitives and Basic Serialization Rules",permalink:"/2.0.0/concepts/serialization/primitives"},next:{title:"Type Serialization",permalink:"/2.0.0/concepts/serialization/types"}},t={},d=[{value:"Account",id:"serialization-standard-account",level:2},{value:"AddressableEntity",id:"addressable-entity",level:2},{value:"Block",id:"serialization-standard-block",level:2},{value:"BlockHash",id:"block-hash",level:3},{value:"BlockHeader",id:"block-header",level:3},{value:"EraEndV1",id:"eraendV1",level:3},{value:"EraEndV2",id:"eraendV2",level:3},{value:"BlockBodyV1",id:"blockbodyV1",level:3},{value:"BlockBodyV2 {blockbodyv2}",id:"blockbodyv2-blockbodyv2",level:3},{value:"Contract",id:"contract",level:2},{value:"ContractPackageHash",id:"contractpackagehash",level:3},{value:"ContractWasmHash",id:"contractwasmhash",level:3},{value:"ContractHash",id:"contracthash",level:3},{value:"ContractPackageStatus",id:"contractpackagestatus",level:3},{value:"ContractVersion",id:"contractversion",level:3},{value:"ContractVersionKey",id:"contractversionkey",level:3},{value:"ContractWasm",id:"contractwasm",level:3},{value:"Message",id:"message",level:2},{value:"MessageAddr",id:"message-addr",level:3},{value:"MessageChecksum",id:"message-checksum",level:3},{value:"MessageLimits",id:"message-limits",level:3},{value:"MessagePayload",id:"message-payload",level:3},{value:"MessageTopicOperation",id:"message-topic-operation",level:3},{value:"TopicNameHash",id:"topic-name-hash",level:3},{value:"Transaction",id:"transaction",level:2},{value:"Deploy",id:"serialization-standard-deploy",level:3},{value:"DeployHash",id:"deploy-hash",level:3},{value:"DeployHeader",id:"deploy-header",level:3},{value:"Approval",id:"approval",level:3},{value:"ApprovalsHash",id:"approvals-hash",level:3},{value:"DeployInfo",id:"deployinfo",level:3},{value:"DeployConfig",id:"deployconfig",level:2},{value:"TransactionV1",id:"transactionV1",level:3},{value:"TransactionV1Hash",id:"transactionv1hash",level:3},{value:"TransactionV1Header",id:"transactionv1header",level:3},{value:"TransactionV1Body",id:"transactionv1body",level:3},{value:"TransactionRuntime",id:"transactionruntime",level:3},{value:"TransactionEntryPoint",id:"transactionentrypoint",level:3},{value:"TransactionConfig",id:"transactionconfig",level:3},{value:"TransactionV1Config",id:"transactionV1config",level:3},{value:"TransactionHash",id:"transactionhash",level:3},{value:"TransactionHeader",id:"transactionheader",level:3},{value:"TransactionId",id:"transactionid",level:3},{value:"TransactionScheduling",id:"transactionscheduling",level:3},{value:"TransactionInvocationTarget",id:"transactioninvocationtarget",level:3},{value:"TransactionTarget",id:"transactiontarget",level:3},{value:"TransactionWithExecutionInfo",id:"transaction-with-execution-info",level:3}];function o(e){const i={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.header,{children:(0,s.jsx)(i.h1,{id:"major-structures",children:"Major Structures"})}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-account",children:"Account"}),"\n",(0,s.jsxs)(i.p,{children:["An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, ",(0,s.jsx)(i.code,{children:"Accounts"})," were replaced with ",(0,s.jsx)(i.code,{children:"AddressableEntities"})," of the type ",(0,s.jsx)(i.code,{children:"Account"}),". The account structure consists of the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#namedkey",children:(0,s.jsx)(i.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"main_purse"}),": The account's main purse ",(0,s.jsx)(i.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(i.code,{children:"URef"})," serialization ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#associatedkey",children:(0,s.jsx)(i.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#account-action-thresholds",children:(0,s.jsx)(i.code,{children:"action_thresholds"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"addressable-entity",children:"AddressableEntity"}),"\n",(0,s.jsx)(i.p,{children:"An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#package-hash",children:(0,s.jsx)(i.code,{children:"package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#byte-code-hash",children:(0,s.jsx)(i.code,{children:"byte_code_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entrypoints",children:(0,s.jsx)(i.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#protocolversion",children:(0,s.jsx)(i.code,{children:"protocol_version"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"main_purse"}),": The entity's main purse ",(0,s.jsx)(i.code,{children:"URef"}),". You may find information on ",(0,s.jsx)(i.code,{children:"URef"})," serialization ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:"here"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#associatedkey",children:(0,s.jsx)(i.code,{children:"associated_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entity-action-thresholds",children:(0,s.jsx)(i.code,{children:"action_thresholds"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#message-topics",children:(0,s.jsx)(i.code,{children:"message_topics"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entity-kind",children:(0,s.jsx)(i.code,{children:"entity_kind"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"serialization-standard-block",children:"Block"}),"\n",(0,s.jsx)(i.p,{children:"A block is the core component of the Casper linear blockchain, used in two contexts:"}),"\n",(0,s.jsxs)(i.ol,{children:["\n",(0,s.jsx)(i.li,{children:"A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain."}),"\n",(0,s.jsx)(i.li,{children:"A message that is exchanged between nodes containing the data structure as explained in (1)."}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Each block has a globally unique ID, achieved by hashing the contents of the block."}),"\n",(0,s.jsx)(i.p,{children:"Each block points to its parent. An exception is the first block, which has no parent."}),"\n",(0,s.jsx)(i.p,{children:"A block is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hash"}),": A hash over the header of the block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"header"}),": The header of the block that contains information about the contents of the block with additional metadata."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body"}),": The block's body contains the proposer of the block and hashes of deploys and transfers contained within it."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"Further, a block may consist of one of the following types:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Version1"}),": A legacy block created prior to the Condor upgrade."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Version2"}),": A modern block."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"block-hash",children:"BlockHash"}),"\n",(0,s.jsxs)(i.p,{children:["The block hash is a ",(0,s.jsx)(i.code,{children:"Digest"})," over the contents of the block Header. The ",(0,s.jsx)(i.code,{children:"BlockHash"})," serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.h3,{id:"block-header",children:"BlockHeader"}),"\n",(0,s.jsx)(i.p,{children:"The header portion of a block, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"parent_hash"})," is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"parent_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"state_root_hash"})," is the global state root hash produced by executing this block's body. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"state root hash"}),". The serialized buffer of the ",(0,s.jsx)(i.code,{children:"state_root_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"})," the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"body_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"random_bit"})," is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"accumulated_seed"})," is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the ",(0,s.jsx)(i.code,{children:"accumulated_hash"})," is 32 bytes long."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_end"})," contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as ",(0,s.jsx)(i.code,{children:"None"}),", it serializes to ",(0,s.jsx)(i.em,{children:"0"}),". The serialization of the other case is described in the EraEnd."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"})," The timestamp from when the block was proposed. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value. The serialization of a ",(0,s.jsx)(i.code,{children:"u64"})," value is described in the CLValues section."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_id"})," Era ID in which this block was created. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"height"})," The height of this block, i.e., the number of ancestors. It serializes as a single ",(0,s.jsx)(i.code,{children:"u64"})," value."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"protocol_version"})," The version of the Casper network when this block was proposed. It is 3-element tuple containing ",(0,s.jsx)(i.code,{children:"u32"})," values. It serializes as a buffer containing the three ",(0,s.jsx)(i.code,{children:"u32"})," serialized values. Refer to the CLValues section on how ",(0,s.jsx)(i.code,{children:"u32"})," values are serialized."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Both ",(0,s.jsx)(i.code,{children:"BlockHeaderV1"})," and ",(0,s.jsx)(i.code,{children:"BlockHeaderV2"})," serialize in the same way."]}),"\n",(0,s.jsx)(i.h3,{id:"eraendV1",children:"EraEndV1"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing two fields."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"era_report"}),": The first field is termed as ",(0,s.jsx)(i.code,{children:"EraReport"})," and contains information about equivocators and rewards for an era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_validator_weights"}),": The second field is map for the validators and their weights for the era to follow."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraReport"})," itself contains two fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(i.code,{children:"PublicKey"})," and ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"inactive_validators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.p,{children:"When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, the first byte within the buffer is a ",(0,s.jsx)(i.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(i.li,{children:["If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Secp256k1"})," key, the first byte within the buffer is a ",(0,s.jsx)(i.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["When serializing the overarching struct of ",(0,s.jsx)(i.code,{children:"EraEndV1"}),", we first allocate a buffer, which contains the serialized representation of the ",(0,s.jsx)(i.code,{children:"EraReport"})," as described above, followed by the serialized BTreeMap."]}),"\n",(0,s.jsxs)(i.p,{children:["Note that ",(0,s.jsx)(i.code,{children:"EraEndV1"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(i.code,{children:"EraEndV1"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(i.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"eraendV2",children:"EraEndV2"}),"\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"EraEndV1"})," as represented within the block header, is a struct containing four fields."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"equivocators"}),": A vector of ",(0,s.jsx)(i.code,{children:"PublicKey"})," listing equivocators for the era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"inactive_validators"}),": A list of inactive validators for the era."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_validator_weights"}),": A map of validators and their weights for the era to follow."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"rewards"}),": A Binary Tree Map of ",(0,s.jsx)(i.code,{children:"PublicKey"})," and ",(0,s.jsx)(i.code,{children:"u64"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"next_era_gas_price"}),": The next era's gas price as a ",(0,s.jsx)(i.code,{children:"u8"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["Note that ",(0,s.jsx)(i.code,{children:"EraEndV2"})," is an optional field. Thus the above scheme only applies if there is an ",(0,s.jsx)(i.code,{children:"EraEndV2"}),"; if there is no era end, the field simply serializes to ",(0,s.jsx)(i.em,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"blockbodyV1",children:"BlockBodyV1"}),"\n",(0,s.jsx)(i.p,{children:"The body portion of a block, prior to the Condor upgrade, is structurally defined as:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"proposer"}),": The PublicKey which proposed this block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"deploy_hashes"}),": Is a vector of hex-encoded hashes identifying Deploys included in this block."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"transfer_hashes"}),": Is a vector of hex-encoded hashes identifying Transfers included in this block."]}),"\n"]}),"\n",(0,s.jsxs)(i.p,{children:["When we serialize the ",(0,s.jsx)(i.code,{children:"BlockBodyV1"}),", we create a buffer that contains the serialized representations of the individual fields present within the block."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"proposer"})," serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"deploy_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(i.code,{children:"32 * n"}),", where n denotes the number of deploy hashes present within the body."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"transfer_hashes"})," serializes to the byte representation of all the deploy_hashes within the block header. Its length is ",(0,s.jsx)(i.code,{children:"32 * n"}),", where n denotes the number of transfers present within the body."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"blockbodyv2-blockbodyv2",children:"BlockBodyV2 {blockbodyv2}"}),"\n",(0,s.jsx)(i.p,{children:"A modern block is structurally defined as:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#transaction",children:(0,s.jsx)(i.code,{children:"transactions"})}),": Is a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," of transaction hashes and their given categories. It is serialized as a ",(0,s.jsx)(i.code,{children:"BTreeMap"})," where the first 4 bytes represent a ",(0,s.jsx)(i.code,{children:"u32"})," value describing the number of values held within. The remainder consists of a repeating pattern of transaction categories as a ",(0,s.jsx)(i.code,{children:"u8"})," value and then the associated ",(0,s.jsx)(i.code,{children:"TransactionHash"})," the category tag describes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#rewarded-signatures",children:(0,s.jsx)(i.code,{children:"rewarded_signatures"})}),": A list of identifiers for finality signatures for a particular past block. It serializes as a vector of ",(0,s.jsx)(i.code,{children:"SingleBlockRewardedSignatures"})," which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"contract",children:"Contract"}),"\n",(0,s.jsx)(i.p,{children:"A contract struct containing the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#contractpackagehash",children:(0,s.jsx)(i.code,{children:"contract_package_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#contractwasmhash",children:(0,s.jsx)(i.code,{children:"contract_wasm_hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#namedkey",children:(0,s.jsx)(i.code,{children:"named_keys"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entrypoints",children:(0,s.jsx)(i.code,{children:"entry_points"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#protocolversion",children:(0,s.jsx)(i.code,{children:"protocol_version"})})}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"contractpackagehash",children:"ContractPackageHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contractwasmhash",children:"ContractWasmHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contracthash",children:"ContractHash"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"blake2b"})," hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash."]}),"\n",(0,s.jsx)(i.h3,{id:"contractpackagestatus",children:"ContractPackageStatus"}),"\n",(0,s.jsxs)(i.p,{children:["The lock status of the contract package, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-boolean",children:(0,s.jsx)(i.code,{children:"boolean"})})," where ",(0,s.jsx)(i.code,{children:"true"})," indicates a locked contract and ",(0,s.jsx)(i.code,{children:"false"})," indicates an unlocked contract package."]}),"\n",(0,s.jsx)(i.h3,{id:"contractversion",children:"ContractVersion"}),"\n",(0,s.jsx)(i.p,{children:"The version of the contract."}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#contracthash",children:(0,s.jsx)(i.code,{children:"contract_hash"})}),": The contract hash of the contract."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"contract_version"}),": The version of the contract within the protocol major version. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"protocol_version_major"}),": The major element of the protocol version this contract is compatible with. It serializes as a ",(0,s.jsxs)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:[(0,s.jsx)(i.code,{children:"u32"})," value"]}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"contractversionkey",children:"ContractVersionKey"}),"\n",(0,s.jsxs)(i.p,{children:["The major element of ",(0,s.jsx)(i.code,{children:"ProtocolVersion"})," combined with ",(0,s.jsx)(i.code,{children:"Contract"})," Version serialized as two ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values."]}),"\n",(0,s.jsx)(i.h3,{id:"contractwasm",children:"ContractWasm"}),"\n",(0,s.jsx)(i.p,{children:"A container for a contract's Wasm bytes, serialized as the byte representation of itself."}),"\n",(0,s.jsx)(i.h2,{id:"message",children:"Message"}),"\n",(0,s.jsxs)(i.p,{children:["A message emitted by an addressable entity during execution. The message ",(0,s.jsx)(i.code,{children:"struct"})," contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entity_hash"}),": The identity of the entity that produced the message, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"message"}),": The payload of the message, serialized as a ",(0,s.jsx)(i.a,{href:"#message-payload",children:(0,s.jsx)(i.code,{children:"MessagePayload"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name"}),": The name of the topic on which the message was emitted, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_index"}),": The message index in the topic, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," value."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_index"}),": The message index in the block, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," value."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-addr",children:"MessageAddr"}),"\n",(0,s.jsx)(i.p,{children:"A message topic address, a structure which consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"entity_addr"}),": The entity address, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entity-addr",children:(0,s.jsx)(i.code,{children:"EntityAddr"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"topic_name_hash"}),": The hash of the topic name, serialized as a ",(0,s.jsx)(i.a,{href:"#topic-name-hash",children:(0,s.jsx)(i.code,{children:"TopicNameHash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"message_index"}),": The message index, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," of ",(0,s.jsx)(i.code,{children:"u32"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-checksum",children:"MessageChecksum"}),"\n",(0,s.jsxs)(i.p,{children:["A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a ",(0,s.jsx)(i.code,{children:"CLType"})," ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag followed by a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-ByteArray",children:(0,s.jsx)(i.code,{children:"ByteArray"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"message-limits",children:"MessageLimits"}),"\n",(0,s.jsxs)(i.p,{children:["Configuration for message lists, serialized as three ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})," values:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_topic_name_size"}),": Maximum size in bytes of a topic name string."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_message_size"}),": Maximum message size in bytes."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_topics_per_contract"}),": Maximum number of topics that a contract can register."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"message-payload",children:"MessagePayload"}),"\n",(0,s.jsxs)(i.p,{children:["The payload of a message emitted by an addressable entity during execution. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a a serialized version of a human-readable ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"String"})}),", or as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by serialized raw ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#bytes",children:(0,s.jsx)(i.code,{children:"Bytes"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"message-topic-operation",children:"MessageTopicOperation"}),"\n",(0,s.jsxs)(i.p,{children:["Operations that can be performed on message topics. Currently, serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," of 0 representing the ",(0,s.jsx)(i.code,{children:"Add"})," function."]}),"\n",(0,s.jsx)(i.h3,{id:"topic-name-hash",children:"TopicNameHash"}),"\n",(0,s.jsxs)(i.p,{children:["The hash of the name of a message topic, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," describing the length of the string and the 32-byte serialized representation of the ",(0,s.jsx)(i.code,{children:"string"})," itself."]}),"\n",(0,s.jsx)(i.h2,{id:"transaction",children:"Transaction"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for a transaction or deploy. It serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"0"})," followed by a ",(0,s.jsx)(i.a,{href:"#serialization-standard-deploy",children:(0,s.jsx)(i.code,{children:"Deploy"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"1"})," followed by a ",(0,s.jsx)(i.a,{href:"#transactionV1",children:(0,s.jsx)(i.code,{children:"TransactionV1"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"serialization-standard-deploy",children:"Deploy"}),"\n",(0,s.jsx)(i.p,{children:"A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"hash"}),": The hash of the deploy header."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"header"}),": Contains metadata about the deploy. The structure of the header is detailed further in this document."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"payment"}),": The payment code for contained smart contract."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"session"}),": The stored contract itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"deploy-hash",children:"DeployHash"}),"\n",(0,s.jsx)(i.p,{children:"The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h3,{id:"deploy-header",children:"DeployHeader"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"account"}),": A supported public key variant (currently either ",(0,s.jsx)(i.code,{children:"Ed25519"})," or ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"). An ",(0,s.jsx)(i.code,{children:"Ed25519"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(i.code,{children:"1"})," for ",(0,s.jsx)(i.code,{children:"Ed25519"}),", with remainder of the buffer containing the byte representation of the signature. Correspondingly, a ",(0,s.jsx)(i.code,{children:"Secp256k1"})," key is serialized as a buffer of bytes, with the leading byte being ",(0,s.jsx)(i.code,{children:"2"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(i.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(i.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(i.code,{children:"0xbd3a847575010000"})]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ttl"}),": The ",(0,s.jsx)(i.strong,{children:"Time to live"})," is defined as the amount of time for which deploy is considered valid. The ",(0,s.jsx)(i.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"gas_price"}),": The gas is ",(0,s.jsx)(i.code,{children:"u64"})," value which is serialized as ",(0,s.jsx)(i.code,{children:"u64"})," CLValue discussed below."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"}),": Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"dependencies"}),": Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"approval",children:"Approval"}),"\n",(0,s.jsx)(i.p,{children:"Approval contains two fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"signer"}),": The public key of the approvals signer. It serializes to the byte representation of the ",(0,s.jsx)(i.code,{children:"PublicKey"}),". If the ",(0,s.jsx)(i.code,{children:"PublicKey"})," is an ",(0,s.jsx)(i.code,{children:"Ed25519"})," key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),", the first byte is 2."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"signature"}),": The approval signature, which serializes as the byte representation of the ",(0,s.jsx)(i.code,{children:"Signature"}),". The first byte within the signature is 1 in the case of an ",(0,s.jsx)(i.code,{children:"Ed25519"})," signature or 2 in the case of ",(0,s.jsx)(i.code,{children:"Secp256k1"}),"."]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"approvals-hash",children:"ApprovalsHash"}),"\n",(0,s.jsxs)(i.p,{children:["The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#digest",children:(0,s.jsx)(i.code,{children:"digest"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"deployinfo",children:"DeployInfo"}),"\n",(0,s.jsx)(i.p,{children:"Information relating to a given deploy. The structure consists of the following fields:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"deploy_hash"}),": The hash of the relevant deploy, serialized as a byte representation of the hash itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"transfers"}),": Transfers performed by the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-list",children:(0,s.jsx)(i.code,{children:"List"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"from"}),": The account identifier of the creator of the deploy, serialized as an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#account-hash",children:(0,s.jsx)(i.code,{children:"account_hash"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"source"}),": The source purse used for payment of the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-uref",children:(0,s.jsx)(i.code,{children:"URef"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"gas"}),": The gas cost of executing the deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"U512"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"deployconfig",children:"DeployConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"deploys"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_payment_cost"}),": The maximum amount any deploy can pay, serialized in ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#motes",children:(0,s.jsx)(i.code,{children:"Motes"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_dependencies"}),": The maximum time to live any deploy can specify, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"payment_args_max_length"}),": The maximum length in bytes of payment args per deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"session_args_max_length"}),": The maximum length in bytes of session args per deploy, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionV1",children:"TransactionV1"}),"\n",(0,s.jsx)(i.p,{children:"A unit of work sent by a client to the network, which when executed can cause global state to be altered. It is structurally defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1hash",children:(0,s.jsx)(i.code,{children:"TransactionV1Hash"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1header",children:(0,s.jsx)(i.code,{children:"TransactionV1Header"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsx)(i.p,{children:(0,s.jsx)(i.a,{href:"#transactionv1body",children:(0,s.jsx)(i.code,{children:"TransactionV1Body"})})}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"approvals"}),": A list of signatures."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1hash",children:"TransactionV1Hash"}),"\n",(0,s.jsx)(i.p,{children:"The transaction hash is a digest over the contents of the transaction header. The transaction hash serializes as the byte representation of the hash itself."}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1header",children:"TransactionV1Header"}),"\n",(0,s.jsx)(i.p,{children:"The header portion of a transaction, structurally, is defined as follows:"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"chain_name"}),": Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:"String"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"timestamp"}),": A timestamp is a struct that is a unary tuple containing a ",(0,s.jsx)(i.code,{children:"u64"})," value. This value is a count of the milliseconds since the UNIX epoch. Thus the value ",(0,s.jsx)(i.code,{children:"1603994401469"})," serializes as ",(0,s.jsx)(i.code,{children:"0xbd3a847575010000"}),"."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"ttl"}),": The ",(0,s.jsx)(i.strong,{children:"Time to live"})," is defined as the amount of time for which the transaction is considered valid. The ",(0,s.jsx)(i.code,{children:"ttl"})," serializes in the same manner as the timestamp."]}),"\n",(0,s.jsxs)(i.li,{children:[(0,s.jsx)(i.code,{children:"body_hash"}),": Body hash is a hash over the contents of the ",(0,s.jsx)(i.a,{href:"#transactionv1body",children:"transaction body"}),". It serializes as the byte representation of the hash itself."]}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#pricingmode",children:(0,s.jsx)(i.code,{children:"pricing_mode"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#initiatoraddr",children:(0,s.jsx)(i.code,{children:"initator_addr"})})}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionv1body",children:"TransactionV1Body"}),"\n",(0,s.jsxs)(i.p,{children:["The body of a ",(0,s.jsx)(i.code,{children:"TransactionV1"}),", consisting of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#runtimeargs",children:(0,s.jsx)(i.code,{children:"args"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactiontarget",children:(0,s.jsx)(i.code,{children:"target"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactionentrypoint",children:(0,s.jsx)(i.code,{children:"entry_point"})})}),"\n",(0,s.jsx)(i.li,{children:(0,s.jsx)(i.a,{href:"#transactionscheduling",children:(0,s.jsx)(i.code,{children:"scheduling"})})}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionruntime",children:"TransactionRuntime"}),"\n",(0,s.jsxs)(i.p,{children:["The runtime used to execute a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})}),". Currently, only the ",(0,s.jsx)(i.code,{children:"VmCasperV1"})," is available, which serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionentrypoint",children:"TransactionEntryPoint"}),"\n",(0,s.jsxs)(i.p,{children:["An entry point of a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," value based on the type of entry point. The following table outlines the available types:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(i.table,{children:[(0,s.jsx)(i.thead,{children:(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.th,{children:"Tag"}),(0,s.jsx)(i.th,{children:"Entry Point"})]})}),(0,s.jsxs)(i.tbody,{children:[(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"0"}),(0,s.jsx)(i.td,{children:"Custom"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"1"}),(0,s.jsx)(i.td,{children:"Transfer"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"2"}),(0,s.jsx)(i.td,{children:"Add_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"3"}),(0,s.jsx)(i.td,{children:"Withdraw_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"4"}),(0,s.jsx)(i.td,{children:"Delegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"5"}),(0,s.jsx)(i.td,{children:"Undelegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"6"}),(0,s.jsx)(i.td,{children:"Redelegate"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"7"}),(0,s.jsx)(i.td,{children:"Activate_Bid"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"8"}),(0,s.jsx)(i.td,{children:"ChangePublicKey"})]}),(0,s.jsxs)(i.tr,{children:[(0,s.jsx)(i.td,{children:"9"}),(0,s.jsx)(i.td,{children:"Call"})]})]})]}),"\n",(0,s.jsx)(i.h3,{id:"transactionconfig",children:"TransactionConfig"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"Transactions"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_ttl"}),": The maximum time to live any transaction can specify, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#timediff",children:(0,s.jsx)(i.code,{children:"TimeDiff"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_max_approval_count"}),": The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_block_size"}),": The maximum possible size in bytes of a block, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u32"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"block_gas_limit"}),": The maximum sum of payment across al transactions included in a block, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_transfer_minimum_motes"}),": The minimum token amount for a native transfer deploy or transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"max_timestamp_leeway"}),": The maximum value to which a ",(0,s.jsx)(i.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the ",(0,s.jsx)(i.em,{children:"config.toml"})," file."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#deployconfig",children:(0,s.jsx)(i.code,{children:"deploy_config"})}),": Configuration values specific to Deploy transactions."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.a,{href:"#transactionV1config",children:(0,s.jsx)(i.code,{children:"transaction_v1_config"})}),": Configuration values specific to V1 transactions."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionV1config",children:"TransactionV1Config"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing configuration values associated with ",(0,s.jsx)(i.code,{children:"TransactionV1s"}),". The structure contains the following fields:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_mint_lane"}),": The lane configuration for the native mint interaction, serializing as a vector of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native_auction_lane"}),": The lane configuration for the native auction interaction, serializing as a vector of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"wasm_lanes"}),": The lane configuration for the Wasm-based lanes, serializing as a nested vector of ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u64"})})," values."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactionhash",children:"TransactionHash"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for transaction hash or deploy hash. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(i.a,{href:"#deploy-hash",children:(0,s.jsx)(i.code,{children:"DeployHash"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(i.a,{href:"#transactionv1hash",children:(0,s.jsx)(i.code,{children:"TransactionV1Hash"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionheader",children:"TransactionHeader"}),"\n",(0,s.jsxs)(i.p,{children:["A versioned wrapper for transaction header or deploy header. It serializes as either a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 0 followed by a ",(0,s.jsx)(i.a,{href:"#deploy-header",children:(0,s.jsx)(i.code,{children:"DeployHeader"})})," or a ",(0,s.jsx)(i.code,{children:"u8"})," tag of 1 followed by a ",(0,s.jsx)(i.a,{href:"#transactionv1header",children:(0,s.jsx)(i.code,{children:"TransactionV1Header"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionid",children:"TransactionId"}),"\n",(0,s.jsxs)(i.p,{children:["The unique identifier of a ",(0,s.jsx)(i.code,{children:"Transaction"}),", serialized as its ",(0,s.jsx)(i.a,{href:"#transactionhash",children:(0,s.jsx)(i.code,{children:"TransactionHash"})})," and ",(0,s.jsx)(i.a,{href:"#approvals-hash",children:(0,s.jsx)(i.code,{children:"ApprovalsHash"})}),"."]}),"\n",(0,s.jsx)(i.h3,{id:"transactionscheduling",children:"TransactionScheduling"}),"\n",(0,s.jsxs)(i.p,{children:["The scheduling mode of a transaction, serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," tag identifying the type:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Standard"})," serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"FutureEra"})," serializes as a ",(0,s.jsx)(i.code,{children:"1"})," followed by a future ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#eraid",children:(0,s.jsx)(i.code,{children:"era_id"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"FutureTimestamp"})," serializes as a ",(0,s.jsx)(i.code,{children:"2"})," followed by a future ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#timestamp",children:(0,s.jsx)(i.code,{children:"timestamp"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactioninvocationtarget",children:"TransactionInvocationTarget"}),"\n",(0,s.jsxs)(i.p,{children:["The identifier of a ",(0,s.jsx)(i.code,{children:"stored"})," transaction target, serialized as one of the following:"]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"InvocableEntity"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"0"})," followed by the hex-encoded entity address serialized as the byte representation of itself."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"InvocableEntityAlias"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"1"})," followed by the alias serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"Package"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#package-hash",children:(0,s.jsx)(i.code,{children:"package hash"})})," and optionally the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(i.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"PackageAlias"})," serializes as a ",(0,s.jsx)(i.code,{children:"u8"})," tag of ",(0,s.jsx)(i.code,{children:"3"})," followed by the alias serialized as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-string",children:(0,s.jsx)(i.code,{children:"string"})})," and optionally the ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/types#entityversionkey",children:(0,s.jsx)(i.code,{children:"entity_version"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transactiontarget",children:"TransactionTarget"}),"\n",(0,s.jsxs)(i.p,{children:["The execution target of a transaction, serializing as a ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-numeric",children:(0,s.jsx)(i.code,{children:"u8"})})," that identifies the type, followed by any additional data."]}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"native"})," serializes as a ",(0,s.jsx)(i.code,{children:"0"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"stored"})," serializes as a ",(0,s.jsx)(i.code,{children:"1"})," followed by the ",(0,s.jsx)(i.a,{href:"#transactioninvocationtarget",children:(0,s.jsx)(i.code,{children:"id"})})," and ",(0,s.jsx)(i.a,{href:"#transactionruntime",children:(0,s.jsx)(i.code,{children:"runtime"})}),"."]}),"\n"]}),"\n",(0,s.jsxs)(i.li,{children:["\n",(0,s.jsxs)(i.p,{children:[(0,s.jsx)(i.code,{children:"session"})," serializes as a ",(0,s.jsx)(i.code,{children:"2"})," followed by the ",(0,s.jsx)(i.a,{href:"#transactionsessionkind",children:(0,s.jsx)(i.code,{children:"kind"})}),", ",(0,s.jsx)(i.a,{href:"#payment--session",children:(0,s.jsx)(i.code,{children:"module_bytes"})})," and ",(0,s.jsx)(i.a,{href:"#transactionruntime",children:(0,s.jsx)(i.code,{children:"runtime"})}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(i.h3,{id:"transaction-with-execution-info",children:"TransactionWithExecutionInfo"}),"\n",(0,s.jsxs)(i.p,{children:["A ",(0,s.jsx)(i.code,{children:"struct"})," containing a",(0,s.jsx)(i.code,{children:"Transaction"})," with execution info. It serializes as a ",(0,s.jsx)(i.a,{href:"#transaction",children:(0,s.jsx)(i.code,{children:"Transaction"})})," followed by an ",(0,s.jsx)(i.a,{href:"/2.0.0/concepts/serialization/primitives#clvalue-option",children:(0,s.jsx)(i.code,{children:"Option"})})," of ",(0,s.jsx)(i.code,{children:"ExecutionInfo"}),"."]})]})}function h(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(o,{...e})}):o(e)}},28453:(e,i,n)=>{n.d(i,{R:()=>c,x:()=>l});var s=n(96540);const r={},a=s.createContext(r);function c(e){const i=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function l(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),s.createElement(a.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e8b40bee.16146a5b.js b/assets/js/e8b40bee.16146a5b.js new file mode 100644 index 000000000..31d372a5b --- /dev/null +++ b/assets/js/e8b40bee.16146a5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[65282],{80870:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const c={},a="Writing a Basic Smart Contract in Rust",o={id:"developers/writing-onchain-code/simple-contract",title:"Writing a Basic Smart Contract in Rust",description:"What is a Smart Contract?",source:"@site/docs/developers/writing-onchain-code/simple-contract.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/simple-contract",permalink:"/developers/writing-onchain-code/simple-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with AssemblyScript",permalink:"/developers/writing-onchain-code/assembly-script"},next:{title:"Testing Smart Contracts",permalink:"/developers/writing-onchain-code/testing-contracts"}},i={},l=[{value:"What is a Smart Contract?",id:"what-is-a-smart-contract",level:2},{value:"Key Features of Casper Contracts",id:"key-features-of-casper-contracts",level:2},{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Automatically using <code>cargo casper</code>",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain <code>cargo</code>",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"step-4-defining-the-contract-entry-points",level:4},{value:"Defining the <code>call</code> function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-a-basic-smart-contract-in-rust",children:"Writing a Basic Smart Contract in Rust"})}),"\n",(0,r.jsx)(t.h2,{id:"what-is-a-smart-contract",children:"What is a Smart Contract?"}),"\n",(0,r.jsxs)(t.p,{children:["A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,r.jsx)(t.a,{href:"/transactions",children:"transaction"}),". Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic."]}),"\n",(0,r.jsx)(t.p,{children:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."}),"\n",(0,r.jsx)(t.h2,{id:"key-features-of-casper-contracts",children:"Key Features of Casper Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,r.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"sent to a node"})," on a Casper network using a transaction. Nodes within the network then ",(0,r.jsx)(t.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossip transactions"}),", include them within a block, and finalize them. After finalizing, the network executes the transactions within the block."]}),"\n",(0,r.jsxs)(t.p,{children:["Further, the Casper platform allows for ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"upgradable contracts"}),". A ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html",children:"ContractPackage"})," is created through the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," or ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,r.jsx)(t.a,{href:"/concepts/key-types#hash-and-key-explanations",children:(0,r.jsx)(t.code,{children:"ContractPackageHash"})}),". The new contract is added to this package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"ContractHash"})})," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"new_contract"})," and ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The contract contains required metadata, and it is primarily identified by its ",(0,r.jsx)(t.code,{children:"ContractHash"}),". While the contract hash identifies a specific ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"ContractVersion"}),", the ",(0,r.jsx)(t.code,{children:"ContractPackageHash"})," serves as an identifier for the most recent contract version in the contract package."]}),"\n",(0,r.jsx)(t.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,r.jsx)(t.p,{children:"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n"})}),"\n",(0,r.jsx)(t.p,{children:"The project structure would be different in a dApp with full-stack architecture. "}),"\n",(0,r.jsxs)(t.h3,{id:"automatic-project-setup",children:["Automatically using ",(0,r.jsx)(t.code,{children:"cargo casper"})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started#creating-a-project",children:"cargo casper command"})," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"cargo casper"})," command will generate an example contract in the contract directory and an example ",(0,r.jsx)(t.code,{children:"tests"})," crate with logic defined in the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file. The ",(0,r.jsx)(t.code,{children:"Makefile"})," includes commands to prepare and build the contract, and the ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," file specifies the target build version of Rust."]}),"\n",(0,r.jsxs)(t.h3,{id:"semi-automatic-project-setup",children:["Semi-automatically using plain ",(0,r.jsx)(t.code,{children:"cargo"})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory for the contract code and its corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the following command to create a new binary package called ",(0,r.jsx)(t.code,{children:"contract"}),". Use a different name instead of ",(0,r.jsx)(t.code,{children:"contract"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new contract\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"contract"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would contain the contract code."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This file would contain crate dependencies and other configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following sections explain how to update these files using example code."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,r.jsx)(t.code,{children:"tests"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new tests\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"tests"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," as shown in the example structure."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This is the file with test configurations."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," guide explains how to update the tests using example code."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Unlike ",(0,r.jsx)(t.code,{children:"cargo casper"}),", ",(0,r.jsx)(t.code,{children:"cargo"})," does not create a ",(0,r.jsx)(t.code,{children:"Makefile"})," and ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," configuration file. Therefore, you must manually add these files to the project's root folder."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example Makefile"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example rust-toolchain file"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"manual-project-setup",children:"Manually"}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended, and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory to store the contract code and corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"contract"}),". You can use a different folder name if you wish."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"contract"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the contract's dependencies."]}),"\n",(0,r.jsxs)(t.li,{children:["Add a Rust file with the contract code in the ",(0,r.jsx)(t.code,{children:"src"})," folder. In this example, we have the ",(0,r.jsx)(t.code,{children:"main.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"tests"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"tests"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the required dependencies to run the tests."]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"src"})," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Manually create Makefile and rust-toolchain as per ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"Semi-automatic setup (4.)"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file in the ",(0,r.jsx)(t.code,{children:"contract"})," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,r.jsxs)(t.p,{children:["If you followed the ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic setup"}),", the dependencies should be in the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file. For the ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic setup"})," and ",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual setup"}),", however, you'll need to manually add the dependencies to the crate's ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-toml",children:'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n'})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"writing-a-basic-smart-contract",children:"Writing a Basic Smart Contract"}),"\n",(0,r.jsxs)(t.p,{children:["At this point, you either have the default example contract defined in ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic"})," setup using cargo-casper), an empty ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," file (",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual"}),' project setup), or a Rust "hello world" program defined in the ',(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic"})," setup)."]}),"\n",(0,r.jsxs)(t.p,{children:["This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,r.jsx)(t.code,{children:"contract/main.rs"})," file if there are any."]}),"\n",(0,r.jsxs)(t.p,{children:["The example code comes from the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"counter contract"}),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"contract API"})," within the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:(0,r.jsx)(t.code,{children:"casper_contract"})})," crate."]}),"\n",(0,r.jsxs)(t.admonition,{type:"info",children:[(0,r.jsx)(t.p,{children:"Important syntax elements used frequently in Rust:"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html",children:"Match"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html",children:"Array"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html",children:"Loop"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/std/vec.html",children:"Vectors"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/fn.html",children:"Functions"}),(0,r.jsx)(t.br,{})]}),"\n"]}),(0,r.jsx)(t.p,{children:"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples."})]}),"\n",(0,r.jsxs)(t.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,r.jsx)(t.code,{children:"main.rs"})," File"]}),"\n",(0,r.jsxs)(t.p,{children:["To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,r.jsx)(t.code,{children:"main.rs"})," file, remove the auto-generated main function."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_main]"})," - This attribute tells the program not to use the standard main function as its entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_std]"})," - This attribute tells the program not to import the standard libraries."]}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"defining-required-dependencies",children:"Defining required dependencies"}),"\n",(0,r.jsx)(t.p,{children:"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n"})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-global-constants",children:"Defining the global constants"}),"\n",(0,r.jsx)(t.p,{children:"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n'})}),"\n",(0,r.jsx)(t.h4,{id:"step-4-defining-the-contract-entry-points",children:"Defining the contract entry points"}),"\n",(0,r.jsxs)(t.p,{children:["Entry points provide access to contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."]}),"\n",(0,r.jsx)(t.p,{children:"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the transaction. Note that another smart contract may access any of these entry points."}),"\n",(0,r.jsx)(t.p,{children:"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."}),"\n",(0,r.jsxs)(t.p,{children:["When defining entry points, begin with a ",(0,r.jsx)(t.code,{children:"#[no_mangle]"})," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"GitHub"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n'})}),"\n",(0,r.jsxs)(t.h4,{id:"defining-the-call-function",children:["Defining the ",(0,r.jsx)(t.code,{children:"call"})," function"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,r.jsx)(t.code,{children:"call"})," function. Review the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55",children:"call function"})," in the counter contract."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Define the runtime arguments."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."}),"\n",(0,r.jsxs)(t.p,{children:["Look at the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"CEP-78 contract"})," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."]}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Add the entry points into the ",(0,r.jsx)(t.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function replaces a traditional ",(0,r.jsx)(t.code,{children:"main"})," function and executes automatically when a caller interacts with the contract. Within the ",(0,r.jsx)(t.code,{children:"call"})," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."]}),"\n",(0,r.jsx)(t.p,{children:"Each entry point should have these arguments:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"name"})," - The entry point's name, which should be the same as the initial definition."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"arguments"})," - A list of runtime arguments declared as part of the definition of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"return type"})," - The CLType returned by the entry point. Use the type ",(0,r.jsx)(t.em,{children:"Unit"})," for empty return types."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"access level"})," - Access permissions of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry point type"})," - This can be ",(0,r.jsx)(t.code,{children:"contract"})," or ",(0,r.jsx)(t.code,{children:"session"})," code."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["This step adds the individual entry points to a ",(0,r.jsx)(t.code,{children:"counter_entry_points"})," object using the ",(0,r.jsx)(t.code,{children:"add_entry_point"})," method. This object will later be passed to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n'})}),"\n",(0,r.jsx)(t.p,{children:"In the following, we will add more content to this call function."}),"\n",(0,r.jsxs)(t.ol,{start:"3",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract's named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"})," are a collection of String-Key pairs used to identify some network data quickly."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, transaction information, purse balances, etc. The list of possible Key variants can be found ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"For the counter, we store the integer that we increment into a named key."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"4",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Use the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,r.jsx)(t.code,{children:"contractPackageHash"}),". Then, it adds the contract to the package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"contractHash"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Usually, these contracts are upgradeable with the ability to add new ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"}),". You ",(0,r.jsx)(t.strong,{children:"must have the access URef"})," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,r.jsx)(t.code,{children:"Some(CONTRACT_ACCESS_UREF.to_string())"})," argument to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method. To prevent any upgrades to a contract, use the ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," method described ",(0,r.jsx)(t.a,{href:"#locked-contracts",children:"below"}),"."]}),"\n",(0,r.jsxs)(t.ol,{start:"5",children:["\n",(0,r.jsx)(t.li,{children:"Create additional named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Generally, the ",(0,r.jsx)(t.code,{children:"Contract_Hash"})," and ",(0,r.jsx)(t.code,{children:"Contract_Version"})," are saved as ",(0,r.jsx)(t.code,{children:"NamedKeys"})," for later use."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,r.jsx)(t.p,{children:"The complete call function should look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"locked-contracts",children:"Locked Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Locked contracts cannot contain other contract ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"})," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option<NamedKeys>,\n hash_name: Option<String>,\n uref_name: Option<String>,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry_points"})," - The set of entry points defined inside the smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"named_keys"})," - Any ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"named-key"})," pairs for the contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"hash_name"})," - Contract hash value. Puts ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:"contractHash"})," in the current context's named keys under ",(0,r.jsx)(t.code,{children:"hash_name"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"uref_name"})," - Access URef value. Puts access_uref in the current context's named keys under ",(0,r.jsx)(t.code,{children:"uref_name"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Note"}),": The current context is the context of the person who initiated the ",(0,r.jsx)(t.code,{children:"call"})," function, usually an account entity."]}),"\n",(0,r.jsx)(t.p,{children:"The counter contract in our example would be locked if we created it this way:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n"})}),"\n",(0,r.jsx)(t.h2,{id:"compiling-contract-code",children:"Compiling Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["To compile the smart contract, run the following commands in the ",(0,r.jsx)(t.code,{children:"contract"})," folder in your project's directory, where the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file and ",(0,r.jsx)(t.code,{children:"src"})," folder are hosted."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For the counter example, in the project directory where the ",(0,r.jsx)(t.code,{children:"Makefile"})," is, run the following commands:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})}),"\n",(0,r.jsx)(t.h2,{id:"executing-contract-code",children:"Executing Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["Contract execution must be initiated through an outside call, usually via ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."]}),"\n",(0,r.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)(t.p,{children:"The following brief video accompanies this guide."}),"\n",(0,r.jsxs)(t.p,{align:"center",children:["\n",(0,r.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"test your contract"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Understand ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e8b40bee.291c4a8c.js b/assets/js/e8b40bee.291c4a8c.js deleted file mode 100644 index d2e667807..000000000 --- a/assets/js/e8b40bee.291c4a8c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5282],{80870:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const c={},a="Writing a Basic Smart Contract in Rust",o={id:"developers/writing-onchain-code/simple-contract",title:"Writing a Basic Smart Contract in Rust",description:"What is a Smart Contract?",source:"@site/docs/developers/writing-onchain-code/simple-contract.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/simple-contract",permalink:"/next/developers/writing-onchain-code/simple-contract",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with AssemblyScript",permalink:"/next/developers/writing-onchain-code/assembly-script"},next:{title:"Testing Smart Contracts",permalink:"/next/developers/writing-onchain-code/testing-contracts"}},i={},l=[{value:"What is a Smart Contract?",id:"what-is-a-smart-contract",level:2},{value:"Key Features of Casper Contracts",id:"key-features-of-casper-contracts",level:2},{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Automatically using <code>cargo casper</code>",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain <code>cargo</code>",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"step-4-defining-the-contract-entry-points",level:4},{value:"Defining the <code>call</code> function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-a-basic-smart-contract-in-rust",children:"Writing a Basic Smart Contract in Rust"})}),"\n",(0,r.jsx)(t.h2,{id:"what-is-a-smart-contract",children:"What is a Smart Contract?"}),"\n",(0,r.jsxs)(t.p,{children:["A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,r.jsx)(t.a,{href:"/next/transactions",children:"transaction"}),". Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic."]}),"\n",(0,r.jsx)(t.p,{children:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."}),"\n",(0,r.jsx)(t.h2,{id:"key-features-of-casper-contracts",children:"Key Features of Casper Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,r.jsx)(t.a,{href:"/next/developers/cli/installing-contracts",children:"sent to a node"})," on a Casper network using a transaction. Nodes within the network then ",(0,r.jsx)(t.a,{href:"/next/concepts/design/p2p#communications-gossiping",children:"gossip transactions"}),", include them within a block, and finalize them. After finalizing, the network executes the transactions within the block."]}),"\n",(0,r.jsxs)(t.p,{children:["Further, the Casper platform allows for ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts",children:"upgradable contracts"}),". A ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html",children:"ContractPackage"})," is created through the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," or ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,r.jsx)(t.a,{href:"/next/concepts/key-types#hash-and-key-explanations",children:(0,r.jsx)(t.code,{children:"ContractPackageHash"})}),". The new contract is added to this package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"ContractHash"})})," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"new_contract"})," and ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The contract contains required metadata, and it is primarily identified by its ",(0,r.jsx)(t.code,{children:"ContractHash"}),". While the contract hash identifies a specific ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"ContractVersion"}),", the ",(0,r.jsx)(t.code,{children:"ContractPackageHash"})," serves as an identifier for the most recent contract version in the contract package."]}),"\n",(0,r.jsx)(t.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,r.jsx)(t.p,{children:"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n"})}),"\n",(0,r.jsx)(t.p,{children:"The project structure would be different in a dApp with full-stack architecture. "}),"\n",(0,r.jsxs)(t.h3,{id:"automatic-project-setup",children:["Automatically using ",(0,r.jsx)(t.code,{children:"cargo casper"})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/getting-started#creating-a-project",children:"cargo casper command"})," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"cargo casper"})," command will generate an example contract in the contract directory and an example ",(0,r.jsx)(t.code,{children:"tests"})," crate with logic defined in the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file. The ",(0,r.jsx)(t.code,{children:"Makefile"})," includes commands to prepare and build the contract, and the ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," file specifies the target build version of Rust."]}),"\n",(0,r.jsxs)(t.h3,{id:"semi-automatic-project-setup",children:["Semi-automatically using plain ",(0,r.jsx)(t.code,{children:"cargo"})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory for the contract code and its corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the following command to create a new binary package called ",(0,r.jsx)(t.code,{children:"contract"}),". Use a different name instead of ",(0,r.jsx)(t.code,{children:"contract"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new contract\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"contract"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would contain the contract code."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This file would contain crate dependencies and other configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following sections explain how to update these files using example code."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,r.jsx)(t.code,{children:"tests"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new tests\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"tests"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," as shown in the example structure."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This is the file with test configurations."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," guide explains how to update the tests using example code."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Unlike ",(0,r.jsx)(t.code,{children:"cargo casper"}),", ",(0,r.jsx)(t.code,{children:"cargo"})," does not create a ",(0,r.jsx)(t.code,{children:"Makefile"})," and ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," configuration file. Therefore, you must manually add these files to the project's root folder."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example Makefile"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example rust-toolchain file"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"manual-project-setup",children:"Manually"}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#creating-the-project-automatically",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended, and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory to store the contract code and corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"contract"}),". You can use a different folder name if you wish."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"contract"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the contract's dependencies."]}),"\n",(0,r.jsxs)(t.li,{children:["Add a Rust file with the contract code in the ",(0,r.jsx)(t.code,{children:"src"})," folder. In this example, we have the ",(0,r.jsx)(t.code,{children:"main.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"tests"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"tests"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the required dependencies to run the tests."]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"src"})," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Manually create Makefile and rust-toolchain as per ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"Semi-automatic setup (4.)"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file in the ",(0,r.jsx)(t.code,{children:"contract"})," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,r.jsxs)(t.p,{children:["If you followed the ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic setup"}),", the dependencies should be in the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file. For the ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic setup"})," and ",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual setup"}),", however, you'll need to manually add the dependencies to the crate's ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-toml",children:'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n'})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"writing-a-basic-smart-contract",children:"Writing a Basic Smart Contract"}),"\n",(0,r.jsxs)(t.p,{children:["At this point, you either have the default example contract defined in ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic"})," setup using cargo-casper), an empty ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," file (",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual"}),' project setup), or a Rust "hello world" program defined in the ',(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic"})," setup)."]}),"\n",(0,r.jsxs)(t.p,{children:["This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,r.jsx)(t.code,{children:"contract/main.rs"})," file if there are any."]}),"\n",(0,r.jsxs)(t.p,{children:["The example code comes from the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"counter contract"}),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"contract API"})," within the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:(0,r.jsx)(t.code,{children:"casper_contract"})})," crate."]}),"\n",(0,r.jsxs)(t.admonition,{type:"info",children:[(0,r.jsx)(t.p,{children:"Important syntax elements used frequently in Rust:"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html",children:"Match"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html",children:"Array"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html",children:"Loop"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/std/vec.html",children:"Vectors"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/fn.html",children:"Functions"}),(0,r.jsx)(t.br,{})]}),"\n"]}),(0,r.jsx)(t.p,{children:"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples."})]}),"\n",(0,r.jsxs)(t.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,r.jsx)(t.code,{children:"main.rs"})," File"]}),"\n",(0,r.jsxs)(t.p,{children:["To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,r.jsx)(t.code,{children:"main.rs"})," file, remove the auto-generated main function."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_main]"})," - This attribute tells the program not to use the standard main function as its entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_std]"})," - This attribute tells the program not to import the standard libraries."]}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"defining-required-dependencies",children:"Defining required dependencies"}),"\n",(0,r.jsx)(t.p,{children:"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n"})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-global-constants",children:"Defining the global constants"}),"\n",(0,r.jsx)(t.p,{children:"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n'})}),"\n",(0,r.jsx)(t.h4,{id:"step-4-defining-the-contract-entry-points",children:"Defining the contract entry points"}),"\n",(0,r.jsxs)(t.p,{children:["Entry points provide access to contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."]}),"\n",(0,r.jsx)(t.p,{children:"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the transaction. Note that another smart contract may access any of these entry points."}),"\n",(0,r.jsx)(t.p,{children:"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."}),"\n",(0,r.jsxs)(t.p,{children:["When defining entry points, begin with a ",(0,r.jsx)(t.code,{children:"#[no_mangle]"})," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"GitHub"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n'})}),"\n",(0,r.jsxs)(t.h4,{id:"defining-the-call-function",children:["Defining the ",(0,r.jsx)(t.code,{children:"call"})," function"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,r.jsx)(t.code,{children:"call"})," function. Review the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55",children:"call function"})," in the counter contract."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Define the runtime arguments."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."}),"\n",(0,r.jsxs)(t.p,{children:["Look at the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"CEP-78 contract"})," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."]}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Add the entry points into the ",(0,r.jsx)(t.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function replaces a traditional ",(0,r.jsx)(t.code,{children:"main"})," function and executes automatically when a caller interacts with the contract. Within the ",(0,r.jsx)(t.code,{children:"call"})," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."]}),"\n",(0,r.jsx)(t.p,{children:"Each entry point should have these arguments:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"name"})," - The entry point's name, which should be the same as the initial definition."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"arguments"})," - A list of runtime arguments declared as part of the definition of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"return type"})," - The CLType returned by the entry point. Use the type ",(0,r.jsx)(t.em,{children:"Unit"})," for empty return types."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"access level"})," - Access permissions of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry point type"})," - This can be ",(0,r.jsx)(t.code,{children:"contract"})," or ",(0,r.jsx)(t.code,{children:"session"})," code."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["This step adds the individual entry points to a ",(0,r.jsx)(t.code,{children:"counter_entry_points"})," object using the ",(0,r.jsx)(t.code,{children:"add_entry_point"})," method. This object will later be passed to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n'})}),"\n",(0,r.jsx)(t.p,{children:"In the following, we will add more content to this call function."}),"\n",(0,r.jsxs)(t.ol,{start:"3",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract's named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"})," are a collection of String-Key pairs used to identify some network data quickly."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, transaction information, purse balances, etc. The list of possible Key variants can be found ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"For the counter, we store the integer that we increment into a named key."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"4",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Use the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,r.jsx)(t.code,{children:"contractPackageHash"}),". Then, it adds the contract to the package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"contractHash"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Usually, these contracts are upgradeable with the ability to add new ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"}),". You ",(0,r.jsx)(t.strong,{children:"must have the access URef"})," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,r.jsx)(t.code,{children:"Some(CONTRACT_ACCESS_UREF.to_string())"})," argument to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method. To prevent any upgrades to a contract, use the ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," method described ",(0,r.jsx)(t.a,{href:"#locked-contracts",children:"below"}),"."]}),"\n",(0,r.jsxs)(t.ol,{start:"5",children:["\n",(0,r.jsx)(t.li,{children:"Create additional named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Generally, the ",(0,r.jsx)(t.code,{children:"Contract_Hash"})," and ",(0,r.jsx)(t.code,{children:"Contract_Version"})," are saved as ",(0,r.jsx)(t.code,{children:"NamedKeys"})," for later use."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,r.jsx)(t.p,{children:"The complete call function should look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"locked-contracts",children:"Locked Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Locked contracts cannot contain other contract ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"})," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option<NamedKeys>,\n hash_name: Option<String>,\n uref_name: Option<String>,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry_points"})," - The set of entry points defined inside the smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"named_keys"})," - Any ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"named-key"})," pairs for the contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"hash_name"})," - Contract hash value. Puts ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:"contractHash"})," in the current context's named keys under ",(0,r.jsx)(t.code,{children:"hash_name"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"uref_name"})," - Access URef value. Puts access_uref in the current context's named keys under ",(0,r.jsx)(t.code,{children:"uref_name"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Note"}),": The current context is the context of the person who initiated the ",(0,r.jsx)(t.code,{children:"call"})," function, usually an account entity."]}),"\n",(0,r.jsx)(t.p,{children:"The counter contract in our example would be locked if we created it this way:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n"})}),"\n",(0,r.jsx)(t.h2,{id:"compiling-contract-code",children:"Compiling Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["To compile the smart contract, run the following commands in the ",(0,r.jsx)(t.code,{children:"contract"})," folder in your project's directory, where the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file and ",(0,r.jsx)(t.code,{children:"src"})," folder are hosted."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For the counter example, in the project directory where the ",(0,r.jsx)(t.code,{children:"Makefile"})," is, run the following commands:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})}),"\n",(0,r.jsx)(t.h2,{id:"executing-contract-code",children:"Executing Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["Contract execution must be initiated through an outside call, usually via ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."]}),"\n",(0,r.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)(t.p,{children:"The following brief video accompanies this guide."}),"\n",(0,r.jsxs)(t.p,{align:"center",children:["\n",(0,r.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/testing-contracts",children:"test your contract"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Understand ",(0,r.jsx)(t.a,{href:"/next/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/next/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/e939f825.436c9fa9.js b/assets/js/e939f825.436c9fa9.js new file mode 100644 index 000000000..47626e647 --- /dev/null +++ b/assets/js/e939f825.436c9fa9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11904],{95065:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>a,toc:()=>r});var s=n(74848),o=n(28453);const i={},c="Estimating Gas Costs with Speculative Execution",a={id:"developers/dapps/speculative-exec",title:"Estimating Gas Costs with Speculative Execution",description:"Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculativeexec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/speculative-exec.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/speculative-exec",permalink:"/2.0.0/developers/dapps/speculative-exec",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Signing Transactions",permalink:"/2.0.0/developers/dapps/signing-a-transaction"},next:{title:"Local Network Setup",permalink:"/2.0.0/developers/dapps/setup-nctl"}},l={},r=[{value:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client",id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",level:2}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"estimating-gas-costs-with-speculative-execution",children:"Estimating Gas Costs with Speculative Execution"})}),"\n",(0,s.jsxs)(t.p,{children:["Version 1.5 of the Casper Node includes a new JSON RPC endpoint called ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/json-rpc/json-rpc-transactional#speculative_exec",children:(0,s.jsx)(t.code,{children:"speculative_exec"})}),". This endpoint allows developers to send a ",(0,s.jsx)(t.a,{href:"/2.0.0/concepts/glossary/D#deploy",children:"Deploy"})," to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution."]}),"\n",(0,s.jsxs)(t.p,{children:["In addition to the Deploy in question, ",(0,s.jsx)(t.code,{children:"speculative_exec"})," also accepts a [",(0,s.jsx)(t.code,{children:"block_identifier"}),"] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block."]}),"\n",(0,s.jsx)(t.h2,{id:"sending-a-speculative-execution-deploy-using-the-rust-cli-casper-client",children:"Sending a Speculative Execution Deploy using the Rust CLI Casper Client"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Rust CLI Casper client"})," includes a ",(0,s.jsx)(t.code,{children:"speculative-exec"})," option that will flag a normal ",(0,s.jsx)(t.code,{children:"put-deploy"})," for execution but not commitment to global state. The following command shows an example:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:"\ncasper client put-deploy /\n--node-address <HOST:PORT> /\n--chain-name <CHAIN_NAME> /\n--secret-key <PATH> /\n--session-path <PATH> /\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES>\n--speculative-exec <BLOCK HEIGHT OR HASH>\n\n"})}),"\n",(0,s.jsxs)(t.p,{children:["You should receive ",(0,s.jsx)(t.code,{children:"execution_result"}),"s that show a ",(0,s.jsx)(t.code,{children:"cost"}),"."]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-bash",children:'\n{\n "jsonrpc": "2.0",\n "id": -4571113357017152230,\n "result": {\n "api_version": "1.0.0",\n "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",\n "execution_result": {\n "Success": {\n "effect": {\n <Deploy effects removed for conciseness.>\n },\n "transfers": [],\n "cost": "87300473670"\n }\n }\n }\n}\n\n'})}),"\n",(0,s.jsx)(t.admonition,{type:"note",children:(0,s.jsxs)(t.p,{children:["Cost estimates acquired through ",(0,s.jsx)(t.code,{children:"speculative_exec"})," may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary."]})})]})}function p(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>c,x:()=>a});var s=n(96540);const o={},i=s.createContext(o);function c(e){const t=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),s.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea0474c4.2a0d441d.js b/assets/js/ea0474c4.2a0d441d.js deleted file mode 100644 index 784643620..000000000 --- a/assets/js/ea0474c4.2a0d441d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6481],{949:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),a=t(28453);const i={title:"Delegating Tokens"},d="Delegating with the Casper Client",r={id:"developers/cli/delegate",title:"Delegating Tokens",description:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.",source:"@site/versioned_docs/version-1.5.X/developers/cli/delegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/delegate",permalink:"/developers/cli/delegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Delegating Tokens"},sidebar:"developers",previous:{title:"Verifying a Transfer",permalink:"/developers/cli/transfers/verify-transfer"},next:{title:"Redelegating Tokens with the Casper Client",permalink:"/developers/cli/redelegate"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Acquiring a Validator's Public Key",id:"acquiring-a-validators-public-key",level:3},{value:"Sending the Delegation Request",id:"sending-the-delegation-request",level:2},{value:"Method 1: Delegating with the System Auction Contract",id:"delegating-system-auction",level:3},{value:"Method 2: Delegating with Compiled Wasm",id:"delegating-compiled-wasm",level:3},{value:"Building the delegation Wasm",id:"building-the-delegation-wasm",level:4},{value:"Sending the delegation request",id:"sending-the-delegation-wasm-request",level:4},{value:"Confirming the Delegation",id:"confirming-the-delegation",level:2},{value:"Checking Validator Status",id:"checking-validator-status",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"delegating-with-the-casper-client",children:"Delegating with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all prerequisites listed ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"here"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"installed a smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"}),"\n",(0,s.jsxs)(n.p,{children:["This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the ",(0,s.jsx)(n.a,{href:"/developers/cli/delegate#sending-the-delegation-request",children:"delegation request"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process."}),"\n",(0,s.jsx)(n.p,{children:"The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set."}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-delegation-request",children:"Sending the Delegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"The minimum amount to delegate is 500 CSPR (500,000,000,000 motes)."})}),"\n",(0,s.jsx)(n.h3,{id:"delegating-system-auction",children:"Method 1: Delegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 500 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"delegating-compiled-wasm",children:"Method 2: Delegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a delegation is to compile the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," and send it to the network via a deploy. Here are the steps to compile the contract yourself."]}),"\n",(0,s.jsx)(n.h4,{id:"building-the-delegation-wasm",children:"Building the delegation Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Obtain the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," by cloning the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Prepare the Rust environment and then build the contracts using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/Makefile",children:"Makefile"})," provided in the repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Once you build the contracts, you can use the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,s.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release/"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ls target/wasm32-unknown-unknown/release/delegate.wasm\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-delegation-wasm-request",children:"Sending the delegation request"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, we use the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to the network to initiate the delegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/delegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"confirming-the-delegation",children:"Confirming the Delegation"}),"\n",(0,s.jsxs)(n.p,{children:["A Casper network maintains an ",(0,s.jsx)(n.em,{children:"auction"})," where validators ",(0,s.jsx)(n.em,{children:"bid"})," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Your delegation is part of the ",(0,s.jsx)(n.em,{children:"bid"})," to the ",(0,s.jsx)(n.em,{children:"auction"})]}),"\n",(0,s.jsxs)(n.li,{children:["The validator is part of the ",(0,s.jsx)(n.em,{children:"active"})," validator set"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"get-auction-info"})," call will return all the bids currently in the auction contract and the list of active validators for ",(0,s.jsx)(n.code,{children:"4"})," future eras from the present era."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a sample of the ",(0,s.jsx)(n.code,{children:"bids"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,s.jsx)(n.code,{children:"bid"})," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure."]}),"\n",(0,s.jsx)(n.h4,{id:"checking-validator-status",children:"Checking Validator Status"}),"\n",(0,s.jsxs)(n.p,{children:["The auction maintains a field called ",(0,s.jsx)(n.code,{children:"era_validators"}),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,s.jsx)(n.code,{children:"PublicKeys"})," of the active validators for that era, along with their stake in the network."]}),"\n",(0,s.jsxs)(n.p,{children:["If a validator is part of the set, its public key will be in the ",(0,s.jsx)(n.code,{children:"era_validators"})," field as part of the ",(0,s.jsx)(n.code,{children:"Auction"})," data structure returned by ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In the response, check the ",(0,s.jsx)(n.code,{children:'"auction_state"."era_validators"'})," structure, which should contain the public key of the selected validator for the era in which the validator will be active."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is an example of the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the above example, we see the public keys of the active validators in Era ",(0,s.jsx)(n.code,{children:"9"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea0474c4.f097486d.js b/assets/js/ea0474c4.f097486d.js new file mode 100644 index 000000000..67f9805fb --- /dev/null +++ b/assets/js/ea0474c4.f097486d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[66481],{949:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>o,contentTitle:()=>d,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var s=t(74848),a=t(28453);const i={title:"Delegating Tokens"},d="Delegating with the Casper Client",r={id:"developers/cli/delegate",title:"Delegating Tokens",description:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.",source:"@site/versioned_docs/version-1.5.X/developers/cli/delegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/delegate",permalink:"/1.5.X/developers/cli/delegate",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Delegating Tokens"},sidebar:"developers",previous:{title:"Verifying a Transfer",permalink:"/1.5.X/developers/cli/transfers/verify-transfer"},next:{title:"Redelegating Tokens with the Casper Client",permalink:"/1.5.X/developers/cli/redelegate"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Acquiring a Validator's Public Key",id:"acquiring-a-validators-public-key",level:3},{value:"Sending the Delegation Request",id:"sending-the-delegation-request",level:2},{value:"Method 1: Delegating with the System Auction Contract",id:"delegating-system-auction",level:3},{value:"Method 2: Delegating with Compiled Wasm",id:"delegating-compiled-wasm",level:3},{value:"Building the delegation Wasm",id:"building-the-delegation-wasm",level:4},{value:"Sending the delegation request",id:"sending-the-delegation-wasm-request",level:4},{value:"Confirming the Delegation",id:"confirming-the-delegation",level:2},{value:"Checking Validator Status",id:"checking-validator-status",level:4}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"delegating-with-the-casper-client",children:"Delegating with the Casper Client"})}),"\n",(0,s.jsx)(n.p,{children:"This document details a workflow where an account holder on a Casper network can delegate tokens to a validator."}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all prerequisites listed ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"here"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"installed a smart contract"})," to a Casper network"]}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"}),"\n",(0,s.jsxs)(n.p,{children:["This workflow will take you through the additional prerequisite to acquire a validator's public key before sending the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate#sending-the-delegation-request",children:"delegation request"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"Any rewards earned are also redelegated by default to the validator from the initial delegation request. Therefore at the time of undelegation, you should consider undelegating the initial amount plus any additional rewards earned through the delegation process."}),"\n",(0,s.jsx)(n.p,{children:"The active validator set constantly rotates; therefore, when delegating to a validator, remember that the validator you selected may have been rotated out of the set."}),"\n",(0,s.jsx)(n.h2,{id:"sending-the-delegation-request",children:"Sending the Delegation Request"}),"\n",(0,s.jsxs)(n.p,{children:["There are two ways to delegate CSPR to a validator. The recommended and cheaper method is to call the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. The second method involves building the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," from the ",(0,s.jsx)(n.code,{children:"casper-node"})," repository and installing it on the network."]}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsx)(n.p,{children:"The minimum amount to delegate is 500 CSPR (500,000,000,000 motes)."})}),"\n",(0,s.jsx)(n.h3,{id:"delegating-system-auction",children:"Method 1: Delegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"delegate"})," entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entry point that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"delegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsx)(n.p,{children:"This example shows an account delegating 500 CSPR:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n--session-entry-point delegate \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"delegating-compiled-wasm",children:"Method 2: Delegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a delegation is to compile the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," and send it to the network via a deploy. Here are the steps to compile the contract yourself."]}),"\n",(0,s.jsx)(n.h4,{id:"building-the-delegation-wasm",children:"Building the delegation Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Obtain the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," by cloning the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node",children:"casper-node"})," repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Prepare the Rust environment and then build the contracts using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/Makefile",children:"Makefile"})," provided in the repository."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd casper-node\nmake setup-rs\nmake build-contracts-rs\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Once you build the contracts, you can use the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to create a deploy that will initiate the delegation process. The Wasm can be found in this directory: ",(0,s.jsx)(n.code,{children:"target/wasm32-unknown-unknown/release/"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"ls target/wasm32-unknown-unknown/release/delegate.wasm\n"})}),"\n",(0,s.jsx)(n.h4,{id:"sending-the-delegation-wasm-request",children:"Sending the delegation request"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, we use the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," to the network to initiate the delegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT_IN_MOTES> \\\n--session-path <PATH_TO_WASM>/delegate.wasm \\\n--session-arg \"validator:public_key='<HEX_ENCODED_VALIDATOR_PULIC_KEY>'\" \\\n--session-arg \"amount:u512='<AMOUNT_TO_DELEGATE>'\" \\\n--session-arg \"delegator:public_key='<HEX_ENCODED_DELEGATOR_PULIC_KEY>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR for node version ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to where the ",(0,s.jsx)(n.code,{children:"delegate.wasm"})," is located"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"delegate"})," entry point expects three arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator"}),": The hexadecimal public key of the validator receiving the delegated tokens"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The number of tokens to be delegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator"}),": The hexadecimal public key of the account delegating tokens to a validator. ",(0,s.jsx)(n.strong,{children:"This key must match the secret key that signs the delegation"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The command will return a deploy hash, which is needed to verify the deploy's processing results. Refer to the ",(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Deploy Status"})," section for more details."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example command uses the Casper Testnet to delegate 500 CSPR, and the payment amount is 6 CSPR. The payment amount varies based on each deploy and network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". However, notice that this method is more expensive than the previous one that calls the delegate entry point."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://65.21.75.254:7777 \\\n--chain-name casper-test \\\n--secret-key ~/KEYS/secret_key.pem \\\n--payment-amount 20000000000 \\\n--session-path ~/delegate.wasm \\\n--session-arg \"validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#confirming-the-delegation",children:"confirm the delegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"confirming-the-delegation",children:"Confirming the Delegation"}),"\n",(0,s.jsxs)(n.p,{children:["A Casper network maintains an ",(0,s.jsx)(n.em,{children:"auction"})," where validators ",(0,s.jsx)(n.em,{children:"bid"})," on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Your delegation is part of the ",(0,s.jsx)(n.em,{children:"bid"})," to the ",(0,s.jsx)(n.em,{children:"auction"})]}),"\n",(0,s.jsxs)(n.li,{children:["The validator is part of the ",(0,s.jsx)(n.em,{children:"active"})," validator set"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Once the deploy has been processed, you can query the auction for information to confirm our delegation. Use the Casper command-line client to create an RPC request with the following query:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client get-auction-info \\\n--node-address http://<peer-ip-address>:7777\n"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Request fields"}),":"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"get-auction-info"})," call will return all the bids currently in the auction contract and the list of active validators for ",(0,s.jsx)(n.code,{children:"4"})," future eras from the present era."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is a sample of the ",(0,s.jsx)(n.code,{children:"bids"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"bids": [\n{\n "bid": {\n "bonding_purse": "uref-a5ce7dbc5f7e02ef52048e64b2ff4693a472a1a56fe71e83b180cd33271b2ed9-007",\n "delegation_rate": 1,\n "delegators": [\n {\n "bonding_purse": "uref-ca9247ad56a4d5be70484303133e2d6db97f7d7385772155763749af98ace0b0-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "010c7fef89bf1fc38363bd2ec20bbfb5e1152d6a9579c8847615c59c7e461ece89",\n "staked_amount": "1"\n },\n {\n "bonding_purse": "uref-38a2e9cad51b380e478c9a325578f4bbdaa0337b99b9ab9bf1dc2a114eb948b9-007",\n "delegatee": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "public_key": "016ebb38d613f2550e7c21ff9d99f6249b4ae5fb9e30938f6ece2d84a22a36b035",\n "staked_amount": "478473232415318176495746923"\n }\n ],\n "inactive": false,\n "staked_amount": "493754513995516852173468935"\n },\n "public_key": "0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd"\n},\n'})}),"\n",(0,s.jsxs)(n.p,{children:["The delegation request has been processed successfully if your public key and associated amount appear in the ",(0,s.jsx)(n.code,{children:"bid"})," data structure. However, this does not mean the associated validator is part of the validator set, so you must check the validator status recorded in the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure."]}),"\n",(0,s.jsx)(n.h4,{id:"checking-validator-status",children:"Checking Validator Status"}),"\n",(0,s.jsxs)(n.p,{children:["The auction maintains a field called ",(0,s.jsx)(n.code,{children:"era_validators"}),", which contains the validator information for 4 future eras from the current era. An entry for a specific era lists the ",(0,s.jsx)(n.code,{children:"PublicKeys"})," of the active validators for that era, along with their stake in the network."]}),"\n",(0,s.jsxs)(n.p,{children:["If a validator is part of the set, its public key will be in the ",(0,s.jsx)(n.code,{children:"era_validators"})," field as part of the ",(0,s.jsx)(n.code,{children:"Auction"})," data structure returned by ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["In the response, check the ",(0,s.jsx)(n.code,{children:'"auction_state"."era_validators"'})," structure, which should contain the public key of the selected validator for the era in which the validator will be active."]}),"\n",(0,s.jsxs)(n.p,{children:["Below is an example of the ",(0,s.jsx)(n.code,{children:"era_validators"})," structure:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"block_height":105,\n "era_validators":[\n {\n "era_id":9,\n "validator_weights":[\n {\n "public_key":"0102db4e11bccb3f9d823c82b9389625d383867d00d09b343043cdbe5ca56dd1fd",\n "weight":"648151805935226166098427654"\n },\n {\n "public_key":"01aa67009b37a23c7ad0ca632da5da239d5db46067d4b34125f61b04611f610baf",\n "weight":"648151805938466925128109996"\n },\n {\n "public_key":"01b7afa2beeddffd13458b763d7a00259f7dc0fa45498dfed05b4d7df4b7d65e2c",\n "weight":"648151805935226166098427656"\n },\n {\n "public_key":"01ca5463dac047cbd750d97ee42dd810cf1e081ece7d83ae4fc03b25a9ecad3b6a",\n "weight":"648151805938466925128109998"\n },\n {\n "public_key":"01f4a7644695aa129eba09fb3f11d0277b2bea1a3d5bc1933bcda93fdb4ad17e55",\n "weight":"648151805938466925128110000"\n }\n ]\n },\n'})}),"\n",(0,s.jsxs)(n.p,{children:["In the above example, we see the public keys of the active validators in Era ",(0,s.jsx)(n.code,{children:"9"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Validators earn delegation rewards only when they are part of the active set. This information is time-sensitive; therefore, a validator selected today may not be part of the set tomorrow. Keep this in mind when creating a delegation request."]}),"\n",(0,s.jsx)(n.p,{children:"If your account is on the official Testnet or Mainnet, you can use the block explorer to look up your account balance and see that the tokens have been delegated:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet explorer"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"https://cspr.live/",children:"Mainnet explorer"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>d,x:()=>r});var s=t(96540);const a={},i=s.createContext(a);function d(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:d(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ea921b39.308e6c57.js b/assets/js/ea921b39.308e6c57.js new file mode 100644 index 000000000..6e55cf4f2 --- /dev/null +++ b/assets/js/ea921b39.308e6c57.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[68013],{80498:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=s(74848),o=s(28453);const i={title:"Genesis"},c="The Genesis Block {#the-genesis-block}",r={id:"operators/setup-network/genesis",title:"Genesis",description:"the-genesis-block}",source:"@site/versioned_docs/version-2.0.0/operators/setup-network/genesis.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/genesis",permalink:"/2.0.0/operators/setup-network/genesis",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Genesis"},sidebar:"operators",previous:{title:"Setting up Private Networks",permalink:"/2.0.0/operators/setup-network/"},next:{title:"The Chainspec",permalink:"/2.0.0/operators/setup-network/chain-spec"}},a={},l=[{value:"chainspec.toml",id:"chainspectoml",level:2},{value:"accounts.toml",id:"accountstoml",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"the-genesis-block",children:"The Genesis Block"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper node software creates a genesis block from the following input files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"chainspec.toml"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"accounts.toml"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,t.jsxs)(n.p,{children:["A version of the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"})," is downloaded by the ",(0,t.jsx)(n.code,{children:"pull_casper_node_version.sh"})," script installed with the casper-node-launcher debian package. This script pulls the ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," file from the appropriate path defined in the network config file used (",(0,t.jsx)(n.code,{children:"casper.conf"})," for MainNet and ",(0,t.jsx)(n.code,{children:"casper-test.conf"})," for TestNet)."]}),"\n",(0,t.jsxs)(n.p,{children:["The production version of the file from which this is based on can be found at ",(0,t.jsx)(n.code,{children:"casper-node/resources/production/chainspec.toml"})," in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"this page"})," for detailed documentation on each of the variables in the file."]}),"\n",(0,t.jsx)(n.h2,{id:"accountstoml",children:"accounts.toml"}),"\n",(0,t.jsx)(n.p,{children:"This file contains the genesis validator set information, starting accounts and associated balances and bond amounts."}),"\n",(0,t.jsxs)(n.p,{children:["If an account is not bonded at genesis, specify a ",(0,t.jsx)(n.code,{children:"0"})," for the bond amount."]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the ",(0,t.jsx)(n.code,{children:"chainspec.toml"}),", this is pulled from the appropriate path defined in the network config file used."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eaba5dd2.013bab1c.js b/assets/js/eaba5dd2.013bab1c.js deleted file mode 100644 index bae9c6873..000000000 --- a/assets/js/eaba5dd2.013bab1c.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2067],{30229:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var t=s(74848),r=s(28453);const a={},i="Transferring Tokens using a Multi-Sig Deploy",d={id:"developers/cli/transfers/multisig-deploy-transfer",title:"Transferring Tokens using a Multi-Sig Deploy",description:"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.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/multisig-deploy-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/multisig-deploy-transfer",permalink:"/developers/cli/transfers/multisig-deploy-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Direct Token Transfer",permalink:"/developers/cli/transfers/direct-token-transfer"},next:{title:"Verifying a Transfer",permalink:"/developers/cli/transfers/verify-transfer"}},c={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Token Transfer Workflow",id:"token-transfer-workflow",level:2},{value:"Creating the transfer",id:"creating-the-transfer",level:3},{value:"Signing the transfer",id:"signing-the-transfer",level:3},{value:"Sending the deploy",id:"sending-the-deploy",level:3},{value:"Verifying the transfer",id:"verifying-the-transfer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",mdxadmonitiontitle:"mdxadmonitiontitle",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-using-a-multi-sig-deploy",children:"Transferring Tokens using a Multi-Sig Deploy"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"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 ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command and send it to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"You must ensure the following prerequisites are met."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the prerequisites listed ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"here"}),", including:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A funded ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#setting-up-an-account",children:"Account"})," on Testnet or Mainnet"]}),"\n",(0,t.jsxs)(n.li,{children:["A valid ",(0,t.jsx)(n.em,{children:"node address"})," from the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet peers"})," or ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet peers"})]}),"\n",(0,t.jsxs)(n.li,{children:["The Casper ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"command-line client"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up the source account for multi-signature deploys, as outlined in the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the path of the source account's ",(0,t.jsx)(n.em,{children:"secret key"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the target account's ",(0,t.jsx)(n.em,{children:"public key"})," in hex format"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"token-transfer-workflow",children:"Token Transfer Workflow"}),"\n",(0,t.jsx)(n.p,{children:"The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"make-transfer"})," command creates and signs a transfer, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command adds additional signatures for a multi-signature transfer"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"send-deploy"})," command sends the deploy containing the transfer to the network"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(8868).A+"",width:"802",height:"274"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-the-transfer",children:"Creating the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This section explains the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file) to a target account. To use this example on the Mainnet, the ",(0,t.jsx)(n.em,{children:"chain-name"})," would be ",(0,t.jsx)(n.code,{children:"casper"})," instead of ",(0,t.jsx)(n.code,{children:"casper-test"}),". Note that we are saving the output of the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command in a ",(0,t.jsx)(n.code,{children:"transfer.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key [PATH]/secret_key.pem \\\n--chain-name casper-test \\\n--target-account [PUBLIC_KEY_HEX] \\\n--transfer-id [ID] \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following table explains the parameters used in the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"amount"}),(0,t.jsx)(n.td,{children:"The number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file for the source account"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"chain-name"}),(0,t.jsxs)(n.td,{children:["The name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain ",(0,t.jsxs)(n.ul,{children:[(0,t.jsxs)(n.li,{children:["For Testnet use ",(0,t.jsx)(n.strong,{children:"casper-test"})]}),(0,t.jsxs)(n.li,{children:["For Mainnet use ",(0,t.jsx)(n.strong,{children:"casper"})]})]})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"target-account"}),(0,t.jsx)(n.td,{children:"Hex-encoded public key of the target account from which the main purse will be used"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"transfer-id"}),(0,t.jsx)(n.td,{children:"A user-defined identifier permanently associated with the transfer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"payment-amount"}),(0,t.jsxs)(n.td,{children:["The payment for the transfer in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In the output, you will see a section named ",(0,t.jsx)(n.strong,{children:"approvals"}),". This is where a signature from the source account is added to the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \\\n--chain-name casper-test \\\n--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \\\n--transfer-id 1 \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output of the make-transfer command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"signing-the-transfer",children:"Signing the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a ",(0,t.jsx)(n.code,{children:"transfer2.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key [PATH]/another_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which needs to be signed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file used to sign the deploy"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"output"}),(0,t.jsx)(n.td,{children:"The path of the output file used to save the deploy with multiple signatures"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, you can observe that there is an ",(0,t.jsx)(n.strong,{children:"approvals"})," section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output saved in the transfer2.deploy file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n },\n {\n "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",\n "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sending-the-deploy",children:"Sending the deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The next step is to send the deploy for processing on the network. As described in the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})," section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node ",(0,t.jsx)(n.code,{children:"https://rpc.testnet.casperlabs.io/"})," from the Testnet."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy \\\n--input transfer2.deploy \\\n--node-address https://rpc.testnet.casperlabs.io/ \n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which is used as the input"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"node-address"}),(0,t.jsx)(n.td,{children:"The Hostname or IP and port of the node"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Make a note of the ",(0,t.jsx)(n.em,{children:"deploy_hash"})," from the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command output to verify the status of the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Successful output of the send-deploy command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -818883417884028030,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If you encounter an account authorization error, you ",(0,t.jsx)(n.strong,{children:"must set up the source account to allow multi-signature deploys"})," using session code. The ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow is an example of how to accomplish this."]})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example of an account authorization error"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "code": -32008,\n "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"verifying-the-transfer",children:"Verifying the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transfer status, see ",(0,t.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.mdxadmonitiontitle,{}),(0,t.jsxs)(n.p,{children:["You can also verify if the transfer was successful by checking your account balance using a ",(0,t.jsx)(n.a,{href:"/users/block-explorer",children:"block explorer"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8868:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-flow-a20851cf502515fa17e5f53f90bf3982.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eaba5dd2.a045f2ae.js b/assets/js/eaba5dd2.a045f2ae.js new file mode 100644 index 000000000..4837a53ba --- /dev/null +++ b/assets/js/eaba5dd2.a045f2ae.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72067],{30229:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>c,contentTitle:()=>i,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>o});var t=s(74848),r=s(28453);const a={},i="Transferring Tokens using a Multi-Sig Deploy",d={id:"developers/cli/transfers/multisig-deploy-transfer",title:"Transferring Tokens using a Multi-Sig Deploy",description:"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.",source:"@site/versioned_docs/version-1.5.X/developers/cli/transfers/multisig-deploy-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/multisig-deploy-transfer",permalink:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Direct Token Transfer",permalink:"/1.5.X/developers/cli/transfers/direct-token-transfer"},next:{title:"Verifying a Transfer",permalink:"/1.5.X/developers/cli/transfers/verify-transfer"}},c={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Token Transfer Workflow",id:"token-transfer-workflow",level:2},{value:"Creating the transfer",id:"creating-the-transfer",level:3},{value:"Signing the transfer",id:"signing-the-transfer",level:3},{value:"Sending the deploy",id:"sending-the-deploy",level:3},{value:"Verifying the transfer",id:"verifying-the-transfer",level:3}];function l(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",mdxadmonitiontitle:"mdxadmonitiontitle",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"transferring-tokens-using-a-multi-sig-deploy",children:"Transferring Tokens using a Multi-Sig Deploy"})}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"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 ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command and send it to the network for execution using the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"You must ensure the following prerequisites are met."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up all the prerequisites listed ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"here"}),", including:\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["A funded ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#setting-up-an-account",children:"Account"})," on Testnet or Mainnet"]}),"\n",(0,t.jsxs)(n.li,{children:["A valid ",(0,t.jsx)(n.em,{children:"node address"})," from the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/tools/peers",children:"Testnet peers"})," or ",(0,t.jsx)(n.a,{href:"https://cspr.live/tools/peers",children:"Mainnet peers"})]}),"\n",(0,t.jsxs)(n.li,{children:["The Casper ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"command-line client"})]}),"\n"]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["Set up the source account for multi-signature deploys, as outlined in the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the path of the source account's ",(0,t.jsx)(n.em,{children:"secret key"})," file"]}),"\n",(0,t.jsxs)(n.li,{children:["Get the target account's ",(0,t.jsx)(n.em,{children:"public key"})," in hex format"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"token-transfer-workflow",children:"Token Transfer Workflow"}),"\n",(0,t.jsx)(n.p,{children:"The high-level flow to transfer tokens using the Casper CLI client and a deploy file is described in the following steps:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"make-transfer"})," command creates and signs a transfer, saving the output to a file"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"sign-deploy"})," command adds additional signatures for a multi-signature transfer"]}),"\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.code,{children:"send-deploy"})," command sends the deploy containing the transfer to the network"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{src:s(714).A+"",width:"802",height:"274"})}),"\n",(0,t.jsx)(n.h3,{id:"creating-the-transfer",children:"Creating the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["This section explains the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the ",(0,t.jsx)(n.code,{children:"secret_key.pem"})," file) to a target account. To use this example on the Mainnet, the ",(0,t.jsx)(n.em,{children:"chain-name"})," would be ",(0,t.jsx)(n.code,{children:"casper"})," instead of ",(0,t.jsx)(n.code,{children:"casper-test"}),". Note that we are saving the output of the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command in a ",(0,t.jsx)(n.code,{children:"transfer.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key [PATH]/secret_key.pem \\\n--chain-name casper-test \\\n--target-account [PUBLIC_KEY_HEX] \\\n--transfer-id [ID] \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The following table explains the parameters used in the ",(0,t.jsx)(n.code,{children:"make-transfer"})," command."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"amount"}),(0,t.jsx)(n.td,{children:"The number of motes you wish to transfer (1 CSPR = 1,000,000,000 motes)"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file for the source account"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"chain-name"}),(0,t.jsxs)(n.td,{children:["The name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain ",(0,t.jsxs)(n.ul,{children:[(0,t.jsxs)(n.li,{children:["For Testnet use ",(0,t.jsx)(n.strong,{children:"casper-test"})]}),(0,t.jsxs)(n.li,{children:["For Mainnet use ",(0,t.jsx)(n.strong,{children:"casper"})]})]})]})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"target-account"}),(0,t.jsx)(n.td,{children:"Hex-encoded public key of the target account from which the main purse will be used"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"transfer-id"}),(0,t.jsx)(n.td,{children:"A user-defined identifier permanently associated with the transfer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"payment-amount"}),(0,t.jsxs)(n.td,{children:["The payment for the transfer in motes. The payment amount varies based on the deploy and network ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", wasmless transfers cost 10^8 motes"]})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["In the output, you will see a section named ",(0,t.jsx)(n.strong,{children:"approvals"}),". This is where a signature from the source account is added to the deploy."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client make-transfer --amount 2500000000 \\\n--secret-key ~/KEYS/multi-sig/keys/default_secret_key.pem \\\n--chain-name casper-test \\\n--target-account 0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf \\\n--transfer-id 1 \\\n--payment-amount 100000000 \\\n--output transfer.deploy\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output of the make-transfer command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"signing-the-transfer",children:"Signing the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["Once the deploy file is created, you can sign the deploy using other designated accounts. For this example, we are signing the deploy with a second secret key and saving the output in a ",(0,t.jsx)(n.code,{children:"transfer2.deploy"})," file."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key [PATH]/another_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which needs to be signed"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"secret-key"}),(0,t.jsx)(n.td,{children:"The path of the secret key file used to sign the deploy"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"output"}),(0,t.jsx)(n.td,{children:"The path of the output file used to save the deploy with multiple signatures"})]})]})]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example:"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client sign-deploy \\\n--input transfer.deploy \\\n--secret-key ~/KEYS/multi-sig/keys/user_1_secret_key.pem \\\n--output transfer2.deploy\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Towards the end of the following output, you can observe that there is an ",(0,t.jsx)(n.strong,{children:"approvals"})," section, which has two signatures, one from the account initiating the transfer and the second from the account used to sign the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample output saved in the transfer2.deploy file"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",\n "header": {\n "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "timestamp": "2023-10-12T19:14:22.080Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400f90295",\n "parsed": "2500000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "010100000000000000",\n "parsed": 1\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"\n },\n {\n "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",\n "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"\n }\n ]\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"sending-the-deploy",children:"Sending the deploy"}),"\n",(0,t.jsxs)(n.p,{children:["The next step is to send the deploy for processing on the network. As described in the ",(0,t.jsx)(n.a,{href:"#prerequisites",children:"Prerequisites"})," section, you need to get an active node address from the corresponding network to complete this task. The following example uses the node ",(0,t.jsx)(n.code,{children:"https://rpc.testnet.casperlabs.io/"})," from the Testnet."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"casper-client send-deploy \\\n--input transfer2.deploy \\\n--node-address https://rpc.testnet.casperlabs.io/ \n"})}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Parameter"}),(0,t.jsx)(n.th,{children:"Description"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"input"}),(0,t.jsx)(n.td,{children:"The path of the deploy file, which is used as the input"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:"node-address"}),(0,t.jsx)(n.td,{children:"The Hostname or IP and port of the node"})]})]})]}),"\n",(0,t.jsxs)(n.p,{children:["Make a note of the ",(0,t.jsx)(n.em,{children:"deploy_hash"})," from the ",(0,t.jsx)(n.code,{children:"send-deploy"})," command output to verify the status of the deploy."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Successful output of the send-deploy command"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": -818883417884028030,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["If you encounter an account authorization error, you ",(0,t.jsx)(n.strong,{children:"must set up the source account to allow multi-signature deploys"})," using session code. The ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature Deploys"})," workflow is an example of how to accomplish this."]})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Example of an account authorization error"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "code": -32008,\n "message": "deploy parameter failure: account authorization invalid at prestate_hash: 5f0392de8ac3512a48a110acfc5bc10d4a6a07109b350ae14cbec0428656c8ac"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"verifying-the-transfer",children:"Verifying the transfer"}),"\n",(0,t.jsxs)(n.p,{children:["To verify the transfer status, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/transfers/verify-transfer",children:"Verifying a Transfer"}),"."]}),"\n",(0,t.jsxs)(n.admonition,{type:"tip",children:[(0,t.jsx)(n.mdxadmonitiontitle,{}),(0,t.jsxs)(n.p,{children:["You can also verify if the transfer was successful by checking your account balance using a ",(0,t.jsx)(n.a,{href:"/1.5.X/users/block-explorer",children:"block explorer"}),"."]})]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},714:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/deploy-flow-a20851cf502515fa17e5f53f90bf3982.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>d});var t=s(96540);const r={},a=t.createContext(r);function i(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eacea541.713b9738.js b/assets/js/eacea541.713b9738.js new file mode 100644 index 000000000..afb7b8940 --- /dev/null +++ b/assets/js/eacea541.713b9738.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[51434],{2880:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>t,metadata:()=>c,toc:()=>l});var n=r(74848),a=r(28453);const t={},o="D",c={id:"concepts/glossary/D",title:"D",description:"---",source:"@site/docs/concepts/glossary/D.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/D",permalink:"/concepts/glossary/D",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{},sidebar:"concepts",previous:{title:"C",permalink:"/concepts/glossary/C"},next:{title:"E",permalink:"/concepts/glossary/E"}},i={},l=[{value:"dApp",id:"dapp",level:2},{value:"Delegation rate",id:"delegation-rate",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Dynamic gas pricing",id:"dynamic-gas-pricing",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"d",children:"D"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"dapp",children:"dApp"}),"\n",(0,n.jsxs)(s.p,{children:["A decentralized application (dApp) employs ",(0,n.jsx)(s.a,{href:"/concepts/glossary/S#smart-contract",children:"smart contracts"})," installed on a decentralized peer-to-peer network such as a blockchain."]}),"\n",(0,n.jsx)(s.h2,{id:"delegation-rate",children:"Delegation rate"}),"\n",(0,n.jsxs)(s.p,{children:["Node operators (",(0,n.jsx)(s.a,{href:"/concepts/glossary/V#validator",children:"validators"}),") define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services."]}),"\n",(0,n.jsx)(s.h2,{id:"delegator",children:"Delegator"}),"\n",(0,n.jsx)(s.p,{children:'Delegators are users who participate in the platform\'s security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.'}),"\n",(0,n.jsx)(s.h2,{id:"deploy",children:"Deploy"}),"\n",(0,n.jsx)(s.p,{children:"Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network."}),"\n",(0,n.jsxs)(s.p,{children:["Casper's Condor release introduces the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/T#transaction",children:"Transaction"}),". Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected."]}),"\n",(0,n.jsxs)(s.p,{children:["All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the ",(0,n.jsx)(s.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["Review the ",(0,n.jsx)(s.a,{href:"/concepts/serialization/structures#serialization-standard-deploy",children:"deploy data structure"})," and the ",(0,n.jsx)(s.a,{href:"https://github.com/casper-network/casper-node/blob/master/node/src/types/deploy.rs#L475",children:"deploy implementation"})," for more details."]}),"\n",(0,n.jsx)(s.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,n.jsxs)(s.p,{children:["A ",(0,n.jsx)(s.code,{children:"Dictionary"})," is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to ",(0,n.jsx)(s.a,{href:"/concepts/glossary/N#named-keys",children:(0,n.jsx)(s.code,{children:"NamedKeys"})}),"."]}),"\n",(0,n.jsxs)(s.p,{children:["More information can be found in the ",(0,n.jsx)(s.a,{href:"/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," document."]}),"\n",(0,n.jsx)(s.h2,{id:"dynamic-gas-pricing",children:"Dynamic gas pricing"}),"\n",(0,n.jsxs)(s.p,{children:["Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details ",(0,n.jsx)(s.a,{href:"/concepts/economics/dynamic-gas-pricing",children:"here"}),"."]})]})}function h(e={}){const{wrapper:s}={...(0,a.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>o,x:()=>c});var n=r(96540);const a={},t=n.createContext(a);function o(e){const s=n.useContext(t);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function c(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(t.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eacea541.eb56de71.js b/assets/js/eacea541.eb56de71.js deleted file mode 100644 index a64fb320f..000000000 --- a/assets/js/eacea541.eb56de71.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1434],{2880:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var t=s(74848),r=s(28453);const a={},o="D",c={id:"concepts/glossary/D",title:"D",description:"---",source:"@site/docs/concepts/glossary/D.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/D",permalink:"/next/concepts/glossary/D",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724327789e3,frontMatter:{},sidebar:"concepts",previous:{title:"C",permalink:"/next/concepts/glossary/C"},next:{title:"E",permalink:"/next/concepts/glossary/E"}},i={},l=[{value:"dApp",id:"dapp",level:2},{value:"Delegation rate",id:"delegation-rate",level:2},{value:"Delegator",id:"delegator",level:2},{value:"Deploy",id:"deploy",level:2},{value:"Dictionary",id:"dictionary",level:2},{value:"Dynamic gas pricing",id:"dynamic-gas-pricing",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"d",children:"D"})}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/next/concepts/glossary/A",children:"A"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/B",children:"B"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/C",children:"C"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/D",children:"D"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/E",children:"E"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/F",children:"F"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G",children:"G"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/H",children:"H"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/I",children:"I"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/J",children:"J"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/K",children:"K"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/L",children:"L"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/M",children:"M"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N",children:"N"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/O",children:"O"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/P",children:"P"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Q",children:"Q"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/R",children:"R"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S",children:"S"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T",children:"T"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/U",children:"U"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V",children:"V"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/W",children:"W"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/X",children:"X"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Y",children:"Y"})," ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/Z",children:"Z"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h2,{id:"dapp",children:"dApp"}),"\n",(0,t.jsxs)(n.p,{children:["A decentralized application (dApp) employs ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/S#smart-contract",children:"smart contracts"})," installed on a decentralized peer-to-peer network such as a blockchain."]}),"\n",(0,t.jsx)(n.h2,{id:"delegation-rate",children:"Delegation rate"}),"\n",(0,t.jsxs)(n.p,{children:["Node operators (",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/V#validator",children:"validators"}),") define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services."]}),"\n",(0,t.jsx)(n.h2,{id:"delegator",children:"Delegator"}),"\n",(0,t.jsx)(n.p,{children:'Delegators are users who participate in the platform\'s security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.'}),"\n",(0,t.jsx)(n.h2,{id:"deploy",children:"Deploy"}),"\n",(0,t.jsx)(n.p,{children:"Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network."}),"\n",(0,t.jsxs)(n.p,{children:["Casper's Condor release introduces the ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/T#transaction",children:"Transaction"}),". Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected."]}),"\n",(0,t.jsxs)(n.p,{children:["All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/G#global-state",children:"global state"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Review the ",(0,t.jsx)(n.a,{href:"/next/concepts/serialization/structures#serialization-standard-deploy",children:"deploy data structure"})," and the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/node/src/types/deploy.rs#L475",children:"deploy implementation"})," for more details."]}),"\n",(0,t.jsx)(n.h2,{id:"dictionary",children:"Dictionary"}),"\n",(0,t.jsxs)(n.p,{children:["A ",(0,t.jsx)(n.code,{children:"Dictionary"})," is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to ",(0,t.jsx)(n.a,{href:"/next/concepts/glossary/N#named-keys",children:(0,t.jsx)(n.code,{children:"NamedKeys"})}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["More information can be found in the ",(0,t.jsx)(n.a,{href:"/next/concepts/dictionaries",children:"Reading and Writing to Dictionaries"})," document."]}),"\n",(0,t.jsx)(n.h2,{id:"dynamic-gas-pricing",children:"Dynamic gas pricing"}),"\n",(0,t.jsxs)(n.p,{children:["Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details ",(0,t.jsx)(n.a,{href:"/next/concepts/economics/dynamic-gas-pricing",children:"here"}),"."]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>c});var t=s(96540);const r={},a=t.createContext(r);function o(e){const n=t.useContext(a);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb0d94ae.4b8f7e24.js b/assets/js/eb0d94ae.4b8f7e24.js new file mode 100644 index 000000000..2e41ce13c --- /dev/null +++ b/assets/js/eb0d94ae.4b8f7e24.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[97575],{51352:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={title:"Glossary",slug:"/glossary"},t="Glossary",a={id:"concepts/glossary/index",title:"Glossary",description:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/index.md",sourceDirName:"concepts/glossary",slug:"/glossary",permalink:"/1.5.X/glossary",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Glossary",slug:"/glossary"},sidebar:"concepts",previous:{title:"Delegation Details",permalink:"/1.5.X/concepts/economics/delegation"},next:{title:"A",permalink:"/1.5.X/concepts/glossary/A"}},l={},i=[];function h(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,n.jsx)(e.p,{children:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts."}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/1.5.X/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb0d94ae.58bdbefc.js b/assets/js/eb0d94ae.58bdbefc.js deleted file mode 100644 index 235e1681e..000000000 --- a/assets/js/eb0d94ae.58bdbefc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7575],{51352:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={title:"Glossary",slug:"/glossary"},t="Glossary",a={id:"concepts/glossary/index",title:"Glossary",description:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.",source:"@site/versioned_docs/version-1.5.X/concepts/glossary/index.md",sourceDirName:"concepts/glossary",slug:"/glossary",permalink:"/glossary",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Glossary",slug:"/glossary"},sidebar:"concepts",previous:{title:"Delegation Details",permalink:"/concepts/economics/delegation"},next:{title:"A",permalink:"/concepts/glossary/A"}},l={},i=[];function h(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,n.jsx)(e.p,{children:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts."}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb1cd7f2.1282bdde.js b/assets/js/eb1cd7f2.1282bdde.js new file mode 100644 index 000000000..83b1a17da --- /dev/null +++ b/assets/js/eb1cd7f2.1282bdde.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11969],{46250:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const c={},a="Writing a Basic Smart Contract in Rust",o={id:"developers/writing-onchain-code/simple-contract",title:"Writing a Basic Smart Contract in Rust",description:"What is a Smart Contract?",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/simple-contract.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/simple-contract",permalink:"/1.5.X/developers/writing-onchain-code/simple-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with AssemblyScript",permalink:"/1.5.X/developers/writing-onchain-code/assembly-script"},next:{title:"Testing Smart Contracts",permalink:"/1.5.X/developers/writing-onchain-code/testing-contracts"}},i={},l=[{value:"What is a Smart Contract?",id:"what-is-a-smart-contract",level:2},{value:"Key Features of Casper Contracts",id:"key-features-of-casper-contracts",level:2},{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Automatically using <code>cargo casper</code>",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain <code>cargo</code>",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"defining-the-contract-entry-points",level:4},{value:"Defining the <code>call</code> function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-a-basic-smart-contract-in-rust",children:"Writing a Basic Smart Contract in Rust"})}),"\n",(0,r.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,r.jsx)(t.h2,{id:"what-is-a-smart-contract",children:"What is a Smart Contract?"}),"\n",(0,r.jsxs)(t.p,{children:["A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,r.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy"}),". Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic."]}),"\n",(0,r.jsx)(t.p,{children:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."}),"\n",(0,r.jsx)(t.h2,{id:"key-features-of-casper-contracts",children:"Key Features of Casper Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"sent to a node"})," on a Casper network using a Deploy. Nodes within the network then ",(0,r.jsx)(t.a,{href:"/1.5.X/concepts/design/p2p#communications-gossiping",children:"gossip deploys"}),", include them within a block, and finalize them. After finalizing, the network executes the deploys within the block."]}),"\n",(0,r.jsxs)(t.p,{children:["Further, the Casper platform allows for ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/upgrading-contracts",children:"upgradable contracts"}),". A ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html",children:"ContractPackage"})," is created through the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," or ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,r.jsx)(t.a,{href:"/1.5.X/concepts/hash-types#hash-and-key-explanations",children:(0,r.jsx)(t.code,{children:"ContractPackageHash"})}),". The new contract is added to this package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"ContractHash"})})," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"new_contract"})," and ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The contract contains required metadata, and it is primarily identified by its ",(0,r.jsx)(t.code,{children:"ContractHash"}),". While the contract hash identifies a specific ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"ContractVersion"}),", the ",(0,r.jsx)(t.code,{children:"ContractPackageHash"})," serves as an identifier for the most recent contract version in the contract package."]}),"\n",(0,r.jsx)(t.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,r.jsx)(t.p,{children:"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n"})}),"\n",(0,r.jsx)(t.p,{children:"The project structure would be different in a dApp with full-stack architecture. "}),"\n",(0,r.jsxs)(t.h3,{id:"automatic-project-setup",children:["Automatically using ",(0,r.jsx)(t.code,{children:"cargo casper"})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/getting-started#creating-a-project",children:"cargo casper command"})," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"cargo casper"})," command will generate an example contract in the contract directory and an example ",(0,r.jsx)(t.code,{children:"tests"})," crate with logic defined in the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file. The ",(0,r.jsx)(t.code,{children:"Makefile"})," includes commands to prepare and build the contract, and the ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," file specifies the target build version of Rust."]}),"\n",(0,r.jsxs)(t.h3,{id:"semi-automatic-project-setup",children:["Semi-automatically using plain ",(0,r.jsx)(t.code,{children:"cargo"})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory for the contract code and its corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the following command to create a new binary package called ",(0,r.jsx)(t.code,{children:"contract"}),". Use a different name instead of ",(0,r.jsx)(t.code,{children:"contract"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new contract\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"contract"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would contain the contract code."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This file would contain crate dependencies and other configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following sections explain how to update these files using example code."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,r.jsx)(t.code,{children:"tests"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new tests\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"tests"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," as shown in the example structure."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This is the file with test configurations."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," guide explains how to update the tests using example code."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Unlike ",(0,r.jsx)(t.code,{children:"cargo casper"}),", ",(0,r.jsx)(t.code,{children:"cargo"})," does not create a ",(0,r.jsx)(t.code,{children:"Makefile"})," and ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," configuration file. Therefore, you must manually add these files to the project's root folder."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example Makefile"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example rust-toolchain file"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"manual-project-setup",children:"Manually"}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended, and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory to store the contract code and corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"contract"}),". You can use a different folder name if you wish."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"contract"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the contract's dependencies."]}),"\n",(0,r.jsxs)(t.li,{children:["Add a Rust file with the contract code in the ",(0,r.jsx)(t.code,{children:"src"})," folder. In this example, we have the ",(0,r.jsx)(t.code,{children:"main.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"tests"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"tests"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the required dependencies to run the tests."]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"src"})," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Manually create Makefile and rust-toolchain as per ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"Semi-automatic setup (4.)"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file in the ",(0,r.jsx)(t.code,{children:"contract"})," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,r.jsxs)(t.p,{children:["If you followed the ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic setup"}),", the dependencies should be in the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file. For the ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic setup"})," and ",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual setup"}),", however, you'll need to manually add the dependencies to the crate's ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-toml",children:'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n'})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"writing-a-basic-smart-contract",children:"Writing a Basic Smart Contract"}),"\n",(0,r.jsxs)(t.p,{children:["At this point, you either have the default example contract defined in ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic"})," setup using cargo-casper), an empty ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," file (",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual"}),' project setup), or a Rust "hello world" program defined in the ',(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic"})," setup)."]}),"\n",(0,r.jsxs)(t.p,{children:["This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,r.jsx)(t.code,{children:"contract/main.rs"})," file if there are any."]}),"\n",(0,r.jsxs)(t.p,{children:["The example code comes from the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"counter contract"}),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"contract API"})," within the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:(0,r.jsx)(t.code,{children:"casper_contract"})})," crate."]}),"\n",(0,r.jsxs)(t.admonition,{type:"info",children:[(0,r.jsx)(t.p,{children:"Important syntax elements used frequently in Rust:"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html",children:"Match"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html",children:"Array"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html",children:"Loop"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/std/vec.html",children:"Vectors"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/fn.html",children:"Functions"}),(0,r.jsx)(t.br,{})]}),"\n"]}),(0,r.jsx)(t.p,{children:"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples."})]}),"\n",(0,r.jsxs)(t.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,r.jsx)(t.code,{children:"main.rs"})," File"]}),"\n",(0,r.jsxs)(t.p,{children:["To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,r.jsx)(t.code,{children:"main.rs"})," file, remove the auto-generated main function."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_main]"})," - This attribute tells the program not to use the standard main function as its entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_std]"})," - This attribute tells the program not to import the standard libraries."]}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"defining-required-dependencies",children:"Defining required dependencies"}),"\n",(0,r.jsx)(t.p,{children:"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n"})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-global-constants",children:"Defining the global constants"}),"\n",(0,r.jsx)(t.p,{children:"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n'})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-contract-entry-points",children:"Defining the contract entry points"}),"\n",(0,r.jsxs)(t.p,{children:["Entry points provide access to contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."]}),"\n",(0,r.jsx)(t.p,{children:"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points."}),"\n",(0,r.jsx)(t.p,{children:"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."}),"\n",(0,r.jsxs)(t.p,{children:["When defining entry points, begin with a ",(0,r.jsx)(t.code,{children:"#[no_mangle]"})," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"GitHub"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n'})}),"\n",(0,r.jsxs)(t.h4,{id:"defining-the-call-function",children:["Defining the ",(0,r.jsx)(t.code,{children:"call"})," function"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,r.jsx)(t.code,{children:"call"})," function. Review the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55",children:"call function"})," in the counter contract."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Define the runtime arguments."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."}),"\n",(0,r.jsxs)(t.p,{children:["Look at the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"CEP-78 contract"})," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."]}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Add the entry points into the ",(0,r.jsx)(t.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function replaces a traditional ",(0,r.jsx)(t.code,{children:"main"})," function and executes automatically when a caller interacts with the contract. Within the ",(0,r.jsx)(t.code,{children:"call"})," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."]}),"\n",(0,r.jsx)(t.p,{children:"Each entry point should have these arguments:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"name"})," - The entry point's name, which should be the same as the initial definition."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"arguments"})," - A list of runtime arguments declared as part of the definition of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"return type"})," - The CLType returned by the entry point. Use the type ",(0,r.jsx)(t.em,{children:"Unit"})," for empty return types."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"access level"})," - Access permissions of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry point type"})," - This can be ",(0,r.jsx)(t.code,{children:"contract"})," or ",(0,r.jsx)(t.code,{children:"session"})," code."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["This step adds the individual entry points to a ",(0,r.jsx)(t.code,{children:"counter_entry_points"})," object using the ",(0,r.jsx)(t.code,{children:"add_entry_point"})," method. This object will later be passed to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n'})}),"\n",(0,r.jsx)(t.p,{children:"In the following, we will add more content to this call function."}),"\n",(0,r.jsxs)(t.ol,{start:"3",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract's named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"})," are a collection of String-Key pairs used to identify some network data quickly."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"For the counter, we store the integer that we increment into a named key."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"4",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Use the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,r.jsx)(t.code,{children:"contractPackageHash"}),". Then, it adds the contract to the package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"contractHash"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Usually, these contracts are upgradeable with the ability to add new ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"}),". You ",(0,r.jsx)(t.strong,{children:"must have the access URef"})," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,r.jsx)(t.code,{children:"Some(CONTRACT_ACCESS_UREF.to_string())"})," argument to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method. To prevent any upgrades to a contract, use the ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," method described ",(0,r.jsx)(t.a,{href:"#locked-contracts",children:"below"}),"."]}),"\n",(0,r.jsxs)(t.ol,{start:"5",children:["\n",(0,r.jsx)(t.li,{children:"Create additional named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Generally, the ",(0,r.jsx)(t.code,{children:"Contract_Hash"})," and ",(0,r.jsx)(t.code,{children:"Contract_Version"})," are saved as ",(0,r.jsx)(t.code,{children:"NamedKeys"})," in the account's context for later use."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,r.jsx)(t.p,{children:"The complete call function should look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"locked-contracts",children:"Locked Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Locked contracts cannot contain other contract ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"})," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option<NamedKeys>,\n hash_name: Option<String>,\n uref_name: Option<String>,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry_points"})," - The set of entry points defined inside the smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"named_keys"})," - Any ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"named-key"})," pairs for the contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"hash_name"})," - Contract hash value. Puts ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:"contractHash"})," in the current context's named keys under ",(0,r.jsx)(t.code,{children:"hash_name"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"uref_name"})," - Access URef value. Puts access_uref in the current context's named keys under ",(0,r.jsx)(t.code,{children:"uref_name"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Note"}),": The current context is the context of the person who initiated the ",(0,r.jsx)(t.code,{children:"call"})," function, usually an account."]}),"\n",(0,r.jsx)(t.p,{children:"The counter contract in our example would be locked if we created it this way:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n"})}),"\n",(0,r.jsx)(t.h2,{id:"compiling-contract-code",children:"Compiling Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["To compile the smart contract, run the following commands in the ",(0,r.jsx)(t.code,{children:"contract"})," folder in your project's directory, where the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file and ",(0,r.jsx)(t.code,{children:"src"})," folder are hosted."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For the counter example, in the project directory where the ",(0,r.jsx)(t.code,{children:"Makefile"})," is, run the following commands:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})}),"\n",(0,r.jsx)(t.h2,{id:"executing-contract-code",children:"Executing Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["Contract execution must be initiated through an outside call, usually via ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."]}),"\n",(0,r.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)(t.p,{children:"The following brief video accompanies this guide."}),"\n",(0,r.jsxs)(t.p,{align:"center",children:["\n",(0,r.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/testing-contracts",children:"test your contract"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Understand ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb1cd7f2.4d0cd80d.js b/assets/js/eb1cd7f2.4d0cd80d.js deleted file mode 100644 index 531a285cf..000000000 --- a/assets/js/eb1cd7f2.4d0cd80d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1969],{46250:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>h,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var r=n(74848),s=n(28453);const c={},a="Writing a Basic Smart Contract in Rust",o={id:"developers/writing-onchain-code/simple-contract",title:"Writing a Basic Smart Contract in Rust",description:"What is a Smart Contract?",source:"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/simple-contract.md",sourceDirName:"developers/writing-onchain-code",slug:"/developers/writing-onchain-code/simple-contract",permalink:"/developers/writing-onchain-code/simple-contract",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"Getting Started with AssemblyScript",permalink:"/developers/writing-onchain-code/assembly-script"},next:{title:"Testing Smart Contracts",permalink:"/developers/writing-onchain-code/testing-contracts"}},i={},l=[{value:"What is a Smart Contract?",id:"what-is-a-smart-contract",level:2},{value:"Key Features of Casper Contracts",id:"key-features-of-casper-contracts",level:2},{value:"Creating the Directory Structure",id:"directory-structure",level:2},{value:"Automatically using <code>cargo casper</code>",id:"automatic-project-setup",level:3},{value:"Semi-automatically using plain <code>cargo</code>",id:"semi-automatic-project-setup",level:3},{value:"Manually",id:"manual-project-setup",level:3},{value:"Dependencies",id:"dependencies",level:3},{value:"Writing a Basic Smart Contract",id:"writing-a-basic-smart-contract",level:2},{value:"Updating the <code>main.rs</code> File",id:"updating-the-mainrs-file",level:3},{value:"Defining required dependencies",id:"defining-required-dependencies",level:4},{value:"Defining the global constants",id:"defining-the-global-constants",level:4},{value:"Defining the contract entry points",id:"defining-the-contract-entry-points",level:4},{value:"Defining the <code>call</code> function",id:"defining-the-call-function",level:4},{value:"Locked Contracts",id:"locked-contracts",level:2},{value:"Compiling Contract Code",id:"compiling-contract-code",level:2},{value:"Executing Contract Code",id:"executing-contract-code",level:2},{value:"Video Walkthrough",id:"video-walkthrough",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const t={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",iframe:"iframe",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"writing-a-basic-smart-contract-in-rust",children:"Writing a Basic Smart Contract in Rust"})}),"\n",(0,r.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,r.jsx)(t.h2,{id:"what-is-a-smart-contract",children:"What is a Smart Contract?"}),"\n",(0,r.jsxs)(t.p,{children:["A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a ",(0,r.jsx)(t.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy"}),". Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic."]}),"\n",(0,r.jsx)(t.p,{children:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended."}),"\n",(0,r.jsx)(t.h2,{id:"key-features-of-casper-contracts",children:"Key Features of Casper Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be ",(0,r.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"sent to a node"})," on a Casper network using a Deploy. Nodes within the network then ",(0,r.jsx)(t.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossip deploys"}),", include them within a block, and finalize them. After finalizing, the network executes the deploys within the block."]}),"\n",(0,r.jsxs)(t.p,{children:["Further, the Casper platform allows for ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"upgradable contracts"}),". A ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractPackage.html",children:"ContractPackage"})," is created through the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," or ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_locked_contract.html",children:"new_locked_contract"})," methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ",(0,r.jsx)(t.a,{href:"/concepts/hash-types#hash-and-key-explanations",children:(0,r.jsx)(t.code,{children:"ContractPackageHash"})}),". The new contract is added to this package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"ContractHash"})})," key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"new_contract"})," and ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract."]}),"\n",(0,r.jsxs)(t.p,{children:["The contract contains required metadata, and it is primarily identified by its ",(0,r.jsx)(t.code,{children:"ContractHash"}),". While the contract hash identifies a specific ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"ContractVersion"}),", the ",(0,r.jsx)(t.code,{children:"ContractPackageHash"})," serves as an identifier for the most recent contract version in the contract package."]}),"\n",(0,r.jsx)(t.h2,{id:"directory-structure",children:"Creating the Directory Structure"}),"\n",(0,r.jsx)(t.p,{children:"To begin creating a smart contract, you need to set up the project structure, either manually or automatically, as shown below."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"project-directory/\n\n\u2514\u2500\u2500 contract/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 main.rs\n \u2514\u2500\u2500 Cargo.toml\n\n\u2514\u2500\u2500 Makefile\n\u2514\u2500\u2500 rust-toolchain\n\n\u2514\u2500\u2500 tests/\n \u251c\u2500\u2500 src/\n \u2514\u2500\u2500 integration-tests.rs\n \u2514\u2500\u2500 Cargo.toml\n"})}),"\n",(0,r.jsx)(t.p,{children:"The project structure would be different in a dApp with full-stack architecture. "}),"\n",(0,r.jsxs)(t.h3,{id:"automatic-project-setup",children:["Automatically using ",(0,r.jsx)(t.code,{children:"cargo casper"})]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/getting-started#creating-a-project",children:"cargo casper command"})," can automatically set up the project structure. This is the recommended way of setting up a new Casper project."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo casper my-project\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"cargo casper"})," command will generate an example contract in the contract directory and an example ",(0,r.jsx)(t.code,{children:"tests"})," crate with logic defined in the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file. The ",(0,r.jsx)(t.code,{children:"Makefile"})," includes commands to prepare and build the contract, and the ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," file specifies the target build version of Rust."]}),"\n",(0,r.jsxs)(t.h3,{id:"semi-automatic-project-setup",children:["Semi-automatically using plain ",(0,r.jsx)(t.code,{children:"cargo"})]}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory for the contract code and its corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the following command to create a new binary package called ",(0,r.jsx)(t.code,{children:"contract"}),". Use a different name instead of ",(0,r.jsx)(t.code,{children:"contract"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new contract\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"contract"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would contain the contract code."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This file would contain crate dependencies and other configurations."]}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"The following sections explain how to update these files using example code."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Inside the project directory, run the command to auto-generate the folder structure for the tests. Use a different name instead of ",(0,r.jsx)(t.code,{children:"tests"})," if you wish."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"cargo new tests\n"})}),"\n",(0,r.jsxs)(t.p,{children:["The command creates a ",(0,r.jsx)(t.code,{children:"tests"})," folder with a ",(0,r.jsx)(t.code,{children:"/src/main.rs"})," file and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"main.rs"})," - This file would store the unit test code required to test the contract. You can rename the file to ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," as shown in the example structure."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"Cargo.toml"})," - This is the file with test configurations."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"Testing Smart Contracts"})," guide explains how to update the tests using example code."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Unlike ",(0,r.jsx)(t.code,{children:"cargo casper"}),", ",(0,r.jsx)(t.code,{children:"cargo"})," does not create a ",(0,r.jsx)(t.code,{children:"Makefile"})," and ",(0,r.jsx)(t.code,{children:"rust-toolchain"})," configuration file. Therefore, you must manually add these files to the project's root folder."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example Makefile"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"prepare:\n rustup target add wasm32-unknown-unknown\n\nbuild-contract:\n cd contract && cargo build --release --target wasm32-unknown-unknown\n wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true\n\ntest: build-contract\n mkdir -p tests/wasm\n cp contract/target/wasm32-unknown-unknown/release/contract.wasm tests/wasm\n cd tests && cargo test\n\nclippy:\n cd contract && cargo clippy --all-targets -- -D warnings\n cd tests && cargo clippy --all-targets -- -D warnings\n\ncheck-lint: clippy\n cd contract && cargo fmt -- --check\n cd tests && cargo fmt -- --check\n\nlint: clippy\n cd contract && cargo fmt\n cd tests && cargo fmt\n"})}),"\n"]}),"\n",(0,r.jsxs)(t.details,{children:["\n",(0,r.jsx)(t.summary,{children:"Example rust-toolchain file"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"nightly-2022-08-03\n"})}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"manual-project-setup",children:"Manually"}),"\n",(0,r.jsx)(t.admonition,{type:"tip",children:(0,r.jsxs)(t.p,{children:["If you are a beginner, ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"creating the structure automatically"})," with ",(0,r.jsx)(t.code,{children:"cargo casper"})," is recommended, and the command creates everything you need to start coding."]})}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsx)(t.p,{children:"Create a top-level project directory to store the contract code and corresponding tests."}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Create a folder for the contract code inside the project directory. This folder contains the logic that will be compiled into Wasm and executed on a Casper node. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"contract"}),". You can use a different folder name if you wish."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"contract"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the contract's dependencies."]}),"\n",(0,r.jsxs)(t.li,{children:["Add a Rust file with the contract code in the ",(0,r.jsx)(t.code,{children:"src"})," folder. In this example, we have the ",(0,r.jsx)(t.code,{children:"main.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Navigating back to the project directory, create a folder for the tests, which help verify the contract's functionality. In this example, we named the folder ",(0,r.jsx)(t.code,{children:"tests"}),"."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"tests"})," folder, add a source folder called ",(0,r.jsx)(t.code,{children:"src"})," and a ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file, which specifies the required dependencies to run the tests."]}),"\n",(0,r.jsxs)(t.li,{children:["In the ",(0,r.jsx)(t.code,{children:"src"})," folder, add a Rust file with the tests that verify the contract's behavior. In this example, we have the ",(0,r.jsx)(t.code,{children:"integration-tests.rs"})," file."]}),"\n"]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["Manually create Makefile and rust-toolchain as per ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"Semi-automatic setup (4.)"})]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"dependencies",children:"Dependencies"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file in the ",(0,r.jsx)(t.code,{children:"contract"})," folder includes the dependencies and versions the contract requires. At a minimum, you need to import the latest versions of the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/",children:"casper-contract"})," and ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/",children:"casper-types"})," crates. The following dependencies and version numbers are only examples and must be adjusted based on your requirements."]}),"\n",(0,r.jsxs)(t.p,{children:["If you followed the ",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic setup"}),", the dependencies should be in the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file. For the ",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic setup"})," and ",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual setup"}),", however, you'll need to manually add the dependencies to the crate's ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-toml",children:'[dependencies]\n# A library for developing Casper network smart contracts.\ncasper-contract = "1.4.4"\n# Types shared by many Casper crates for use on a Casper network.\ncasper-types = "1.5.0"\n'})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-contract = "1.4.4"'})," - Provides the SDK for the execution engine (EE). The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-contract",children:"here"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:'casper-types = "1.5.0"'})," - Includes types shared by many Casper crates for use on a Casper network. This crate is necessary for the EE to understand and interpret the session code. The latest version of the crate is published ",(0,r.jsx)(t.a,{href:"https://crates.io/crates/casper-types",children:"here"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"writing-a-basic-smart-contract",children:"Writing a Basic Smart Contract"}),"\n",(0,r.jsxs)(t.p,{children:["At this point, you either have the default example contract defined in ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#automatic-project-setup",children:"automatic"})," setup using cargo-casper), an empty ",(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," file (",(0,r.jsx)(t.a,{href:"#manual-project-setup",children:"manual"}),' project setup), or a Rust "hello world" program defined in the ',(0,r.jsx)(t.code,{children:"contract/src/main.rs"})," (",(0,r.jsx)(t.a,{href:"#semi-automatic-project-setup",children:"semi-automatic"})," setup)."]}),"\n",(0,r.jsxs)(t.p,{children:["This section covers the process of writing a smart contract in Rust, step by step. Therefore, you should clear the contents of the ",(0,r.jsx)(t.code,{children:"contract/main.rs"})," file if there are any."]}),"\n",(0,r.jsxs)(t.p,{children:["The example code comes from the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/",children:"counter contract"}),". This simple contract allows callers to increment and retrieve an integer. Casper provides a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/index.html",children:"contract API"})," within the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/index.html",children:(0,r.jsx)(t.code,{children:"casper_contract"})})," crate."]}),"\n",(0,r.jsxs)(t.admonition,{type:"info",children:[(0,r.jsx)(t.p,{children:"Important syntax elements used frequently in Rust:"}),(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/match.html",children:"Match"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/primitives/array.html",children:"Array"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/flow_control/loop.html",children:"Loop"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/std/vec.html",children:"Vectors"}),(0,r.jsx)(t.br,{})]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/rust-by-example/fn.html",children:"Functions"}),(0,r.jsx)(t.br,{})]}),"\n"]}),(0,r.jsx)(t.p,{children:"To be able to comfortably write code in Rust it is crucial to understand these topics before going further into the examples."})]}),"\n",(0,r.jsxs)(t.h3,{id:"updating-the-mainrs-file",children:["Updating the ",(0,r.jsx)(t.code,{children:"main.rs"})," File"]}),"\n",(0,r.jsxs)(t.p,{children:["To begin writing contract code, add the following file attributes to support the Wasm execution environment. If you still have an auto-generated ",(0,r.jsx)(t.code,{children:"main.rs"})," file, remove the auto-generated main function."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"#![no_std]\n#![no_main]\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_main]"})," - This attribute tells the program not to use the standard main function as its entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"#![no_std]"})," - This attribute tells the program not to import the standard libraries."]}),"\n"]}),"\n",(0,r.jsx)(t.h4,{id:"defining-required-dependencies",children:"Defining required dependencies"}),"\n",(0,r.jsx)(t.p,{children:"Add the required imports and dependencies. The example code for the counter contract declares the following dependencies."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"// This code imports necessary aspects of external crates that we will use in our contract code.\nextern crate alloc;\n\n// Importing Rust types.\nuse alloc::{\n string::{String, ToString},\n vec::Vec,\n};\n// Importing aspects of the Casper platform.\nuse casper_contract::{\n contract_api::{runtime, storage},\n unwrap_or_revert::UnwrapOrRevert,\n};\n// Importing specific Casper types.\nuse casper_types::{\n api_error::ApiError,\n contracts::{EntryPoint, EntryPointAccess, EntryPointType, EntryPoints, NamedKeys},\n CLType, CLValue, URef,\n};\n"})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-global-constants",children:"Defining the global constants"}),"\n",(0,r.jsx)(t.p,{children:"After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'// Creating constants for values within the contract package.\nconst CONTRACT_PACKAGE_NAME: &str = "counter_package_name";\nconst CONTRACT_ACCESS_UREF: &str = "counter_access_uref";\n\n// Creating constants for the various contract entry points.\nconst ENTRY_POINT_COUNTER_INC: &str = "counter_inc";\nconst ENTRY_POINT_COUNTER_GET: &str = "counter_get";\n\n// Creating constants for values within the contract.\nconst CONTRACT_VERSION_KEY: &str = "version";\nconst CONTRACT_KEY: &str = "counter";\nconst COUNT_KEY: &str = "count";\n'})}),"\n",(0,r.jsx)(t.h4,{id:"defining-the-contract-entry-points",children:"Defining the contract entry points"}),"\n",(0,r.jsxs)(t.p,{children:["Entry points provide access to contract code installed in global state. Either ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program."]}),"\n",(0,r.jsx)(t.p,{children:"Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points."}),"\n",(0,r.jsx)(t.p,{children:"If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded."}),"\n",(0,r.jsxs)(t.p,{children:["When defining entry points, begin with a ",(0,r.jsx)(t.code,{children:"#[no_mangle]"})," line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable."]}),"\n",(0,r.jsxs)(t.p,{children:["The following entry point is an example from the counter contract. To see all the available entry points, review the contract in ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"GitHub"}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn counter_inc() {\n let uref: URef = runtime::get_key(COUNT_KEY)\n .unwrap_or_revert_with(ApiError::MissingKey)\n .into_uref()\n .unwrap_or_revert_with(ApiError::UnexpectedKeyVariant);\n storage::add(uref, 1); // Increment the count by 1.\n}\n'})}),"\n",(0,r.jsxs)(t.h4,{id:"defining-the-call-function",children:["Defining the ",(0,r.jsx)(t.code,{children:"call"})," function"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function starts the code execution and installs the contract on-chain. In some cases, it also initializes some constructs, such as a Dictionary for record-keeping or a purse. The following steps describe how to structure the ",(0,r.jsx)(t.code,{children:"call"})," function. Review the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/counter/blob/8a622cd92d768893b9ef9fc2b150c674415be87e/contract-v1/src/main.rs#L55",children:"call function"})," in the counter contract."]}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"Define the runtime arguments."}),"\n"]}),"\n",(0,r.jsx)(t.p,{children:"At the time of contract installation, pass in parameters as runtime arguments. Use this pattern of variable definition to collect any sentinel values that dictate the behavior of the contract. If the entry point takes in arguments, you must declare those as part of the entry point's definition."}),"\n",(0,r.jsxs)(t.p,{children:["Look at the ",(0,r.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/contract/src/main.rs",children:"CEP-78 contract"})," to see examples of entry points taking in arguments. The counter contract does not use variable parameters since it is too simple."]}),"\n",(0,r.jsxs)(t.ol,{start:"2",children:["\n",(0,r.jsxs)(t.li,{children:["Add the entry points into the ",(0,r.jsx)(t.code,{children:"call"})," function."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.code,{children:"call"})," function replaces a traditional ",(0,r.jsx)(t.code,{children:"main"})," function and executes automatically when a caller interacts with the contract. Within the ",(0,r.jsx)(t.code,{children:"call"})," function, we define entry points the caller can access using session code or another contract. When writing code that calls an entry point, there must be a one-to-one mapping of the entry point name. Otherwise, the execution engine will return an error that the entry point does not exist."]}),"\n",(0,r.jsx)(t.p,{children:"Each entry point should have these arguments:"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"name"})," - The entry point's name, which should be the same as the initial definition."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"arguments"})," - A list of runtime arguments declared as part of the definition of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"return type"})," - The CLType returned by the entry point. Use the type ",(0,r.jsx)(t.em,{children:"Unit"})," for empty return types."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"access level"})," - Access permissions of the entry point."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry point type"})," - This can be ",(0,r.jsx)(t.code,{children:"contract"})," or ",(0,r.jsx)(t.code,{children:"session"})," code."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["This step adds the individual entry points to a ",(0,r.jsx)(t.code,{children:"counter_entry_points"})," object using the ",(0,r.jsx)(t.code,{children:"add_entry_point"})," method. This object will later be passed to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n}\n'})}),"\n",(0,r.jsx)(t.p,{children:"In the following, we will add more content to this call function."}),"\n",(0,r.jsxs)(t.ol,{start:"3",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract's named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"NamedKeys"})," are a collection of String-Key pairs used to identify some network data quickly."]}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://doc.rust-lang.org/nightly/alloc/string/struct.String.html",children:"String"})," is the name given to identify the data"]}),"\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"Key"})," is the data to be referenced"]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/enum.Key.html",children:"here"}),"."]}),"\n",(0,r.jsx)(t.p,{children:"For the counter, we store the integer that we increment into a named key."}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n"})}),"\n",(0,r.jsxs)(t.ol,{start:"4",children:["\n",(0,r.jsx)(t.li,{children:"Create the contract."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Use the ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"})," method to create the contract with its named keys and entry points. This method creates the contract object and saves the access URef and the contract package hash in the caller's context. The execution engine automatically creates a contract package and assigns it a ",(0,r.jsx)(t.code,{children:"contractPackageHash"}),". Then, it adds the contract to the package with a ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:(0,r.jsx)(t.code,{children:"contractHash"})}),"."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n"})}),"\n",(0,r.jsxs)(t.p,{children:["Usually, these contracts are upgradeable with the ability to add new ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"}),". You ",(0,r.jsx)(t.strong,{children:"must have the access URef"})," to the contract package to add a new contract version. This can be accomplished by passing the ",(0,r.jsx)(t.code,{children:"Some(CONTRACT_ACCESS_UREF.to_string())"})," argument to the ",(0,r.jsx)(t.code,{children:"new_contract"})," method. To prevent any upgrades to a contract, use the ",(0,r.jsx)(t.code,{children:"new_locked_contract"})," method described ",(0,r.jsx)(t.a,{href:"#locked-contracts",children:"below"}),"."]}),"\n",(0,r.jsxs)(t.ol,{start:"5",children:["\n",(0,r.jsx)(t.li,{children:"Create additional named keys."}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Generally, the ",(0,r.jsx)(t.code,{children:"Contract_Hash"})," and ",(0,r.jsx)(t.code,{children:"Contract_Version"})," are saved as ",(0,r.jsx)(t.code,{children:"NamedKeys"})," in the account's context for later use."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:" // Store the contract version in the context's named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,r.jsx)(t.p,{children:"The complete call function should look like this:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'#[no_mangle]\npub extern "C" fn call() {\n // Initialize the count to 0 locally\n let count_start = storage::new_uref(0_i32);\n // Create the entry points for this contract\n let mut counter_entry_points = EntryPoints::new();\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_GET,\n Vec::new(),\n CLType::I32,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n counter_entry_points.add_entry_point(EntryPoint::new(\n ENTRY_POINT_COUNTER_INC,\n Vec::new(),\n CLType::Unit,\n EntryPointAccess::Public,\n EntryPointType::Contract,\n ));\n\n // In the named keys of the counter contract, add a key for the count.\n let mut counter_named_keys = NamedKeys::new();\n let key_name = String::from(COUNT_KEY);\n counter_named_keys.insert(key_name, count_start.into());\n\n // Create a new contract package that can be upgraded.\n let (stored_contract_hash, contract_version) = storage::new_contract(\n counter_entry_points,\n Some(counter_named_keys),\n Some(CONTRACT_PACKAGE_NAME.to_string()),\n Some(CONTRACT_ACCESS_UREF.to_string()),\n );\n\n /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned\n let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */\n\n // Store the contract version in the context\'s named keys.\n let version_uref = storage::new_uref(contract_version);\n runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());\n\n // Create a named key for the contract hash.\n runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n}\n'})}),"\n",(0,r.jsx)(t.h2,{id:"locked-contracts",children:"Locked Contracts"}),"\n",(0,r.jsxs)(t.p,{children:["Locked contracts cannot contain other contract ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.ContractVersion.html",children:"versions"})," in the same contract package; thus, they cannot be upgraded. In this scenario, the Casper execution engine will create a contract package, add a contract to that package and prevent any further upgrades to the contract. Use locked contracts when you need to ensure high security and will not require updates to the contract."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"pub fn new_locked_contract(\n entry_points: EntryPoints,\n named_keys: Option<NamedKeys>,\n hash_name: Option<String>,\n uref_name: Option<String>,\n) -> (ContractHash, ContractVersion) {\n create_contract(entry_points, named_keys, hash_name, uref_name, true)\n}\n"})}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"entry_points"})," - The set of entry points defined inside the smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"named_keys"})," - Any ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html",children:"named-key"})," pairs for the contract."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"hash_name"})," - Contract hash value. Puts ",(0,r.jsx)(t.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/struct.ContractHash.html",children:"contractHash"})," in the current context's named keys under ",(0,r.jsx)(t.code,{children:"hash_name"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:[(0,r.jsx)(t.code,{children:"uref_name"})," - Access URef value. Puts access_uref in the current context's named keys under ",(0,r.jsx)(t.code,{children:"uref_name"}),"."]}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"Note"}),": The current context is the context of the person who initiated the ",(0,r.jsx)(t.code,{children:"call"})," function, usually an account."]}),"\n",(0,r.jsx)(t.p,{children:"The counter contract in our example would be locked if we created it this way:"}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:"let (stored_contract_hash, _) =\n storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);\n"})}),"\n",(0,r.jsx)(t.h2,{id:"compiling-contract-code",children:"Compiling Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["To compile the smart contract, run the following commands in the ",(0,r.jsx)(t.code,{children:"contract"})," folder in your project's directory, where the ",(0,r.jsx)(t.code,{children:"Cargo.toml"})," file and ",(0,r.jsx)(t.code,{children:"src"})," folder are hosted."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"rustup target add wasm32-unknown-unknown\ncargo build --release --target wasm32-unknown-unknown\n"})}),"\n",(0,r.jsxs)(t.p,{children:["For the counter example, in the project directory where the ",(0,r.jsx)(t.code,{children:"Makefile"})," is, run the following commands:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-bash",children:"make prepare\nmake build-contract\n"})}),"\n",(0,r.jsx)(t.h2,{id:"executing-contract-code",children:"Executing Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["Contract execution must be initiated through an outside call, usually via ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," or another smart contract. Developers should also be familiar with the difference between contract code and session code, explained in the next section."]}),"\n",(0,r.jsx)(t.h2,{id:"video-walkthrough",children:"Video Walkthrough"}),"\n",(0,r.jsx)(t.p,{children:"The following brief video accompanies this guide."}),"\n",(0,r.jsxs)(t.p,{align:"center",children:["\n",(0,r.jsx)(t.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/yHJwkhO5EQg",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/testing-contracts",children:"test your contract"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["Understand ",(0,r.jsx)(t.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"session code"})," and how it triggers a smart contract."]}),"\n",(0,r.jsxs)(t.li,{children:["Learn to ",(0,r.jsx)(t.a,{href:"/developers/cli/installing-contracts",children:"install a contract and query global state"})," with the Casper command-line client."]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var r=n(96540);const s={},c=r.createContext(s);function a(e){const t=r.useContext(c);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),r.createElement(c.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb5a6cc0.5fb4114d.js b/assets/js/eb5a6cc0.5fb4114d.js new file mode 100644 index 000000000..660e02180 --- /dev/null +++ b/assets/js/eb5a6cc0.5fb4114d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[280],{66747:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(74848),s=n(28453);const i={title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},r="Owner Reverse Lookup Functionality",a={id:"resources/tokens/cep78/reverse-lookup",title:"Ownership Lookup",description:"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/reverse-lookup.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/reverse-lookup",permalink:"/1.5.X/resources/tokens/cep78/reverse-lookup",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},sidebar:"resources",previous:{title:"Testing NFTs",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs"},next:{title:"CEP-78 JavaScript Client",permalink:"/1.5.X/resources/tokens/cep78/js-tutorial"}},c={},l=[{value:"The CEP-78 Page System",id:"the-cep-78-page-system",level:2},{value:"Updated Receipts",id:"updated-receipts",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"owner-reverse-lookup-functionality",children:"Owner Reverse Lookup Functionality"})}),"\n",(0,o.jsxs)(t.p,{children:["In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found ",(0,o.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"here"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract."}),"\n",(0,o.jsx)(t.p,{children:"This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page."}),"\n",(0,o.jsx)(t.h2,{id:"the-cep-78-page-system",children:"The CEP-78 Page System"}),"\n",(0,o.jsxs)(t.p,{children:["Ownership of NFTs within a CEP-78 contract is now tracked with a series of ",(0,o.jsx)(t.code,{children:"pages"}),", with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs."]}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"page_table"})," tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the ",(0,o.jsx)(t.code,{children:"register_owner"})," entrypoint."]}),"\n",(0,o.jsxs)(t.p,{children:["After registering as an owner, the contract creates an entry within the ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for the minting account or contract. This dictionary entry consists of a series of ",(0,o.jsx)(t.code,{children:"boolean"})," values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false."]}),"\n",(0,o.jsxs)(t.p,{children:["Upon minting the token, the user will pay for a page allocation. This adds them to the ",(0,o.jsx)(t.code,{children:"page"})," dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the ",(0,o.jsx)(t.code,{children:"page"})," dictionary will consist of 1,000 ",(0,o.jsx)(t.code,{children:"page_address"})," bits set to ",(0,o.jsx)(t.code,{children:"False"})," upon allocation, and the minting of any given token in that page will set the ",(0,o.jsx)(t.code,{children:"page_address"})," bit to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, that account or contract's ",(0,o.jsx)(t.code,{children:"page_table"})," will be updated by marking the corresponding page number's bit as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"The contract registers their account as an owner."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The contract creates a ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for that account, with 10 boolean values. As the numbering system begins with ",(0,o.jsx)(t.code,{children:"0"}),", the third boolean value corresponding with page ",(0,o.jsx)(t.code,{children:"2"})," is set to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The account pays for allocation of page 2, creating an entry in the ",(0,o.jsx)(t.code,{children:"Page 2"})," dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 350 as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for ",(0,o.jsx)(t.code,{children:"page 5"})," to be allocated to them. They would then be added to the ",(0,o.jsx)(t.code,{children:"page 5"})," dictionary with the ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 125 set as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"This system binds the data writing costs to a maximum size of any given page dictionary."}),"\n",(0,o.jsx)(t.h2,{id:"updated-receipts",children:"Updated Receipts"}),"\n",(0,o.jsxs)(t.p,{children:["If the contract enables ",(0,o.jsx)(t.code,{children:"OwnerReverseLookupMode"}),", calling the ",(0,o.jsx)(t.code,{children:"updated_receipts"})," entrypoint will return a list of receipt names alongside the dictionary for the relevant pages."]}),"\n",(0,o.jsxs)(t.p,{children:["Updated receipts come in the format of ",(0,o.jsx)(t.code,{children:'"{<collection name>}\\_m{modulo}\\_p{<page number>}"'}),". Once again using the 2,350th token as an example, the receipt would read:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"cep78_collection_m_350_p_2\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can determine the token number by multiplying the ",(0,o.jsx)(t.code,{children:"page_number"})," by the ",(0,o.jsx)(t.code,{children:"page_size"}),"(1,000) and adding the ",(0,o.jsx)(t.code,{children:"modulo"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["If the ",(0,o.jsx)(t.code,{children:"NFTIdentifierMode"})," is set to ",(0,o.jsx)(t.code,{children:"Ordinal"}),", this number corresponds directly to the token ID."]}),"\n",(0,o.jsxs)(t.p,{children:["If it is set to ",(0,o.jsx)(t.code,{children:"Hash"}),", you will need to reference the ",(0,o.jsx)(t.code,{children:"HASH_BY_INDEX"})," dictionary to determine the mapping of token numbers to token hashes."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eb5a6cc0.bb4e4618.js b/assets/js/eb5a6cc0.bb4e4618.js deleted file mode 100644 index 9c6d90030..000000000 --- a/assets/js/eb5a6cc0.bb4e4618.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[280],{66747:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>l});var o=n(74848),s=n(28453);const i={title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},r="Owner Reverse Lookup Functionality",a={id:"resources/tokens/cep78/reverse-lookup",title:"Ownership Lookup",description:"In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/reverse-lookup.md",sourceDirName:"resources/tokens/cep78",slug:"/resources/tokens/cep78/reverse-lookup",permalink:"/resources/tokens/cep78/reverse-lookup",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Ownership Lookup",slug:"/resources/tokens/cep78/reverse-lookup"},sidebar:"resources",previous:{title:"Testing NFTs",permalink:"/resources/tokens/cep78/using-casper-client/testing-NFTs"},next:{title:"CEP-78 JavaScript Client",permalink:"/resources/tokens/cep78/js-tutorial"}},c={},l=[{value:"The CEP-78 Page System",id:"the-cep-78-page-system",level:2},{value:"Updated Receipts",id:"updated-receipts",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.header,{children:(0,o.jsx)(t.h1,{id:"owner-reverse-lookup-functionality",children:"Owner Reverse Lookup Functionality"})}),"\n",(0,o.jsxs)(t.p,{children:["In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found ",(0,o.jsx)(t.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/blob/dev/docs/tutorials/token-ownership-tutorial.md",children:"here"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract."}),"\n",(0,o.jsx)(t.p,{children:"This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page."}),"\n",(0,o.jsx)(t.h2,{id:"the-cep-78-page-system",children:"The CEP-78 Page System"}),"\n",(0,o.jsxs)(t.p,{children:["Ownership of NFTs within a CEP-78 contract is now tracked with a series of ",(0,o.jsx)(t.code,{children:"pages"}),", with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs."]}),"\n",(0,o.jsxs)(t.p,{children:["A ",(0,o.jsx)(t.code,{children:"page_table"})," tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the ",(0,o.jsx)(t.code,{children:"register_owner"})," entrypoint."]}),"\n",(0,o.jsxs)(t.p,{children:["After registering as an owner, the contract creates an entry within the ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for the minting account or contract. This dictionary entry consists of a series of ",(0,o.jsx)(t.code,{children:"boolean"})," values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false."]}),"\n",(0,o.jsxs)(t.p,{children:["Upon minting the token, the user will pay for a page allocation. This adds them to the ",(0,o.jsx)(t.code,{children:"page"})," dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the ",(0,o.jsx)(t.code,{children:"page"})," dictionary will consist of 1,000 ",(0,o.jsx)(t.code,{children:"page_address"})," bits set to ",(0,o.jsx)(t.code,{children:"False"})," upon allocation, and the minting of any given token in that page will set the ",(0,o.jsx)(t.code,{children:"page_address"})," bit to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["In addition, that account or contract's ",(0,o.jsx)(t.code,{children:"page_table"})," will be updated by marking the corresponding page number's bit as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n",(0,o.jsx)(t.p,{children:"As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:"}),"\n",(0,o.jsxs)(t.ol,{children:["\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsx)(t.p,{children:"The contract registers their account as an owner."}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The contract creates a ",(0,o.jsx)(t.code,{children:"page_table"})," dictionary for that account, with 10 boolean values. As the numbering system begins with ",(0,o.jsx)(t.code,{children:"0"}),", the third boolean value corresponding with page ",(0,o.jsx)(t.code,{children:"2"})," is set to ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["The account pays for allocation of page 2, creating an entry in the ",(0,o.jsx)(t.code,{children:"Page 2"})," dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 350 as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n",(0,o.jsxs)(t.li,{children:["\n",(0,o.jsxs)(t.p,{children:["Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for ",(0,o.jsx)(t.code,{children:"page 5"})," to be allocated to them. They would then be added to the ",(0,o.jsx)(t.code,{children:"page 5"})," dictionary with the ",(0,o.jsx)(t.code,{children:"page_address"})," boolean for 125 set as ",(0,o.jsx)(t.code,{children:"True"}),"."]}),"\n"]}),"\n"]}),"\n",(0,o.jsx)(t.p,{children:"This system binds the data writing costs to a maximum size of any given page dictionary."}),"\n",(0,o.jsx)(t.h2,{id:"updated-receipts",children:"Updated Receipts"}),"\n",(0,o.jsxs)(t.p,{children:["If the contract enables ",(0,o.jsx)(t.code,{children:"OwnerReverseLookupMode"}),", calling the ",(0,o.jsx)(t.code,{children:"updated_receipts"})," entrypoint will return a list of receipt names alongside the dictionary for the relevant pages."]}),"\n",(0,o.jsxs)(t.p,{children:["Updated receipts come in the format of ",(0,o.jsx)(t.code,{children:'"{<collection name>}\\_m{modulo}\\_p{<page number>}"'}),". Once again using the 2,350th token as an example, the receipt would read:"]}),"\n",(0,o.jsx)(t.pre,{children:(0,o.jsx)(t.code,{children:"cep78_collection_m_350_p_2\n"})}),"\n",(0,o.jsxs)(t.p,{children:["You can determine the token number by multiplying the ",(0,o.jsx)(t.code,{children:"page_number"})," by the ",(0,o.jsx)(t.code,{children:"page_size"}),"(1,000) and adding the ",(0,o.jsx)(t.code,{children:"modulo"}),"."]}),"\n",(0,o.jsxs)(t.p,{children:["If the ",(0,o.jsx)(t.code,{children:"NFTIdentifierMode"})," is set to ",(0,o.jsx)(t.code,{children:"Ordinal"}),", this number corresponds directly to the token ID."]}),"\n",(0,o.jsxs)(t.p,{children:["If it is set to ",(0,o.jsx)(t.code,{children:"Hash"}),", you will need to reference the ",(0,o.jsx)(t.code,{children:"HASH_BY_INDEX"})," dictionary to determine the mapping of token numbers to token hashes."]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var o=n(96540);const s={},i=o.createContext(s);function r(e){const t=o.useContext(i);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),o.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ebb9a3ce.877a950d.js b/assets/js/ebb9a3ce.877a950d.js deleted file mode 100644 index a62e82784..000000000 --- a/assets/js/ebb9a3ce.877a950d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1093],{75736:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=a(74848),t=a(28453);const c={title:"Additional Examples"},o="Additional Examples",i={id:"resources/advanced/multi-sig/other-scenarios",title:"Additional Examples",description:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/other-scenarios.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/other-scenarios",permalink:"/resources/advanced/multi-sig/other-scenarios",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Additional Examples"},sidebar:"tutorials",previous:{title:"Multi-Sig Workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow"},next:{title:"Runtime Return Values",permalink:"/resources/tutorials/advanced/return-values-tutorial"}},r={},d=[{value:"Example 1: An account with a single (primary) key",id:"example-1-an-account-with-a-single-primary-key",level:3},{value:"Example 2: An account with primary and associated keys",id:"example-2-an-account-with-primary-and-associated-keys",level:3},{value:"Example 3: Multi-sig setup for deploys and account updates",id:"example-3-multi-sig-setup-for-deploys-and-account-updates",level:3},{value:"Example 4: Signing deploys but restricting account updates",id:"example-4-signing-deploys-but-restricting-account-updates",level:3},{value:"Example 5: Recovering a lost primary key",id:"example-5-recovering-a-lost-primary-key",level:3}];function l(e){const n={code:"code",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"additional-examples",children:"Additional Examples"})}),"\n",(0,s.jsx)(n.p,{children:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions."}),"\n",(0,s.jsx)(n.h3,{id:"example-1-an-account-with-a-single-primary-key",children:"Example 1: An account with a single (primary) key"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, only one key (",(0,s.jsx)(n.code,{children:"account-hash-a1\u2026"}),") can sign transactions in the name of this account. This key is the primary key of the account and has a ",(0,s.jsx)(n.code,{children:"weight"})," equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 1:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-2-an-account-with-primary-and-associated-keys",children:"Example 2: An account with primary and associated keys"}),"\n",(0,s.jsx)(n.p,{children:"In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 2:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key for key management\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key used for deploys\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-3-multi-sig-setup-for-deploys-and-account-updates",children:"Example 3: Multi-sig setup for deploys and account updates"}),"\n",(0,s.jsx)(n.p,{children:"The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 3:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-4-signing-deploys-but-restricting-account-updates",children:"Example 4: Signing deploys but restricting account updates"}),"\n",(0,s.jsx)(n.p,{children:"This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 4:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-5-recovering-a-lost-primary-key",children:"Example 5: Recovering a lost primary key"}),"\n",(0,s.jsx)(n.p,{children:"This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 5:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-d4\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var s=a(96540);const t={},c=s.createContext(t);function o(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ebb9a3ce.bdc45b5b.js b/assets/js/ebb9a3ce.bdc45b5b.js new file mode 100644 index 000000000..36906b7ba --- /dev/null +++ b/assets/js/ebb9a3ce.bdc45b5b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1093],{75736:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=a(74848),t=a(28453);const c={title:"Additional Examples"},o="Additional Examples",i={id:"resources/advanced/multi-sig/other-scenarios",title:"Additional Examples",description:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/other-scenarios.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/other-scenarios",permalink:"/1.5.X/resources/advanced/multi-sig/other-scenarios",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Additional Examples"},sidebar:"tutorials",previous:{title:"Multi-Sig Workflow",permalink:"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow"},next:{title:"Runtime Return Values",permalink:"/1.5.X/resources/tutorials/advanced/return-values-tutorial"}},r={},d=[{value:"Example 1: An account with a single (primary) key",id:"example-1-an-account-with-a-single-primary-key",level:3},{value:"Example 2: An account with primary and associated keys",id:"example-2-an-account-with-primary-and-associated-keys",level:3},{value:"Example 3: Multi-sig setup for deploys and account updates",id:"example-3-multi-sig-setup-for-deploys-and-account-updates",level:3},{value:"Example 4: Signing deploys but restricting account updates",id:"example-4-signing-deploys-but-restricting-account-updates",level:3},{value:"Example 5: Recovering a lost primary key",id:"example-5-recovering-a-lost-primary-key",level:3}];function l(e){const n={code:"code",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"additional-examples",children:"Additional Examples"})}),"\n",(0,s.jsx)(n.p,{children:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions."}),"\n",(0,s.jsx)(n.h3,{id:"example-1-an-account-with-a-single-primary-key",children:"Example 1: An account with a single (primary) key"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, only one key (",(0,s.jsx)(n.code,{children:"account-hash-a1\u2026"}),") can sign transactions in the name of this account. This key is the primary key of the account and has a ",(0,s.jsx)(n.code,{children:"weight"})," equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 1:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-2-an-account-with-primary-and-associated-keys",children:"Example 2: An account with primary and associated keys"}),"\n",(0,s.jsx)(n.p,{children:"In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 2:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key for key management\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key used for deploys\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-3-multi-sig-setup-for-deploys-and-account-updates",children:"Example 3: Multi-sig setup for deploys and account updates"}),"\n",(0,s.jsx)(n.p,{children:"The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 3:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-4-signing-deploys-but-restricting-account-updates",children:"Example 4: Signing deploys but restricting account updates"}),"\n",(0,s.jsx)(n.p,{children:"This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 4:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-5-recovering-a-lost-primary-key",children:"Example 5: Recovering a lost primary key"}),"\n",(0,s.jsx)(n.p,{children:"This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 5:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-d4\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var s=a(96540);const t={},c=s.createContext(t);function o(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ed267fba.167c6c60.js b/assets/js/ed267fba.167c6c60.js deleted file mode 100644 index 3d7d15631..000000000 --- a/assets/js/ed267fba.167c6c60.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[367],{61809:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=s(74848),r=s(28453);const i={},a="Prerequisites",o={id:"developers/dapps/prerequisites",title:"Prerequisites",description:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:",source:"@site/versioned_docs/version-1.5.X/developers/dapps/prerequisites.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/prerequisites",permalink:"/developers/dapps/prerequisites",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"What is a dApp?",permalink:"/developers/dapps/dapp"},next:{title:"SDK Client Libraries",permalink:"/sdk"}},d={},l=[{value:"Development Considerations",id:"development-considerations",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"prerequisites",children:"Prerequisites"})}),"\n",(0,t.jsx)(n.p,{children:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up your ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"development environment"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Be sure you understand the language(s) you are developing in."}),"\n",(0,t.jsx)(n.p,{children:"Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you."}),"\n",(0,t.jsxs)(n.p,{children:["The preferred stack for building on Casper is JavaScript using the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),", however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the ",(0,t.jsx)(n.a,{href:"/sdk",children:"Introduction to SDKs"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Familiarize yourself with the fundamentals of Casper networks."}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the ",(0,t.jsx)(n.a,{href:"/design",children:"design section"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Read the documentation or source code of your chosen SDK."}),"\n",(0,t.jsxs)(n.p,{children:["Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see ",(0,t.jsx)(n.a,{href:"/developers/dapps/sdk/client-library-usage",children:"Client Library Usage"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"development-considerations",children:"Development Considerations"}),"\n",(0,t.jsx)(n.p,{children:"When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value."}),"\n",(0,t.jsx)(n.p,{children:"To ensure the highest level of security, consider the following practices:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code."}),"\n",(0,t.jsx)(n.li,{children:"Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors."}),"\n",(0,t.jsx)(n.li,{children:"Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet."}),"\n",(0,t.jsx)(n.li,{children:"Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes."}),"\n",(0,t.jsx)(n.li,{children:"Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ed267fba.6c0f909a.js b/assets/js/ed267fba.6c0f909a.js new file mode 100644 index 000000000..43b750801 --- /dev/null +++ b/assets/js/ed267fba.6c0f909a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[22748],{61809:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=s(74848),r=s(28453);const i={},a="Prerequisites",o={id:"developers/dapps/prerequisites",title:"Prerequisites",description:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:",source:"@site/versioned_docs/version-1.5.X/developers/dapps/prerequisites.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/prerequisites",permalink:"/1.5.X/developers/dapps/prerequisites",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"developers",previous:{title:"What is a dApp?",permalink:"/1.5.X/developers/dapps/dapp"},next:{title:"SDK Client Libraries",permalink:"/1.5.X/sdk"}},d={},l=[{value:"Development Considerations",id:"development-considerations",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"prerequisites",children:"Prerequisites"})}),"\n",(0,t.jsx)(n.p,{children:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up your ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"development environment"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Be sure you understand the language(s) you are developing in."}),"\n",(0,t.jsx)(n.p,{children:"Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you."}),"\n",(0,t.jsxs)(n.p,{children:["The preferred stack for building on Casper is JavaScript using the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),", however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the ",(0,t.jsx)(n.a,{href:"/1.5.X/sdk",children:"Introduction to SDKs"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Familiarize yourself with the fundamentals of Casper networks."}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the ",(0,t.jsx)(n.a,{href:"/1.5.X/design",children:"design section"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Read the documentation or source code of your chosen SDK."}),"\n",(0,t.jsxs)(n.p,{children:["Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/dapps/sdk/client-library-usage",children:"Client Library Usage"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"development-considerations",children:"Development Considerations"}),"\n",(0,t.jsx)(n.p,{children:"When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value."}),"\n",(0,t.jsx)(n.p,{children:"To ensure the highest level of security, consider the following practices:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code."}),"\n",(0,t.jsx)(n.li,{children:"Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors."}),"\n",(0,t.jsx)(n.li,{children:"Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet."}),"\n",(0,t.jsx)(n.li,{children:"Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes."}),"\n",(0,t.jsx)(n.li,{children:"Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ed3af4a0.611178a8.js b/assets/js/ed3af4a0.611178a8.js new file mode 100644 index 000000000..9cfd98f46 --- /dev/null +++ b/assets/js/ed3af4a0.611178a8.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[77533],{92461:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=s(74848),r=s(28453);const o={title:"Local Network Setup"},i="Setting up a Local Network with NCTL",l={id:"developers/dapps/setup-nctl",title:"Local Network Setup",description:"NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/setup-nctl.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/setup-nctl",permalink:"/2.0.0/developers/dapps/setup-nctl",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Local Network Setup"},sidebar:"developers",previous:{title:"Estimating Gas Costs with Speculative Execution",permalink:"/2.0.0/developers/dapps/speculative-exec"},next:{title:"Local Network Testing",permalink:"/2.0.0/developers/dapps/nctl-test"}},a={},c=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Installing a Virtual Environment",id:"installing-a-virtual-environment",level:2},{value:"Setting up the Network",id:"setting-up-the-network",level:2},{value:"Stopping the Network",id:"stopping-the-network",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"setting-up-a-local-network-with-nctl",children:"Setting up a Local Network with NCTL"})}),"\n",(0,t.jsxs)(n.p,{children:["NCTL stands for network/node control. ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/tree/master/utils/nctl",children:"NCTL"})," is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["You have completed the ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/getting-started",children:"Getting Started section"}),", which shows you how to install your development environment, including tools like ",(0,t.jsx)(n.em,{children:"CMake"})," (version 3.1.4+), ",(0,t.jsx)(n.em,{children:"Cargo"}),", and ",(0,t.jsx)(n.em,{children:"Rust"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Make sure you have ",(0,t.jsx)(n.a,{href:"https://www.python.org/downloads/",children:"Python 3 installed"})," if your operating system does not include Python."]}),"\n",(0,t.jsxs)(n.li,{children:["To run NCTL, you will also need ",(0,t.jsx)(n.a,{href:"https://www.gnu.org/savannah-checkouts/gnu/bash/bash.html",children:"the bash shell"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"installing-a-virtual-environment",children:"Installing a Virtual Environment"}),"\n",(0,t.jsx)(n.p,{children:"We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing."}),"\n",(0,t.jsx)(n.p,{children:"First, you will need to install a set of tools required for running NCTL."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 1."})," The first tool you will need is ",(0,t.jsx)(n.strong,{children:"pip"}),", a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or ",(0,t.jsx)(n.a,{href:"https://pip.pypa.io/en/stable/installing/",children:"the full installation instructions"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py\n$ python3 get-pip.py\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install python3-pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 2."})," Install ",(0,t.jsx)(n.strong,{children:"pkg-config"}),", a program used to compile and link against one or more libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install pkg-config\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install pkg-config\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 3."})," Install either ",(0,t.jsx)(n.strong,{children:"libssl-dev"})," (Linux) or ",(0,t.jsx)(n.strong,{children:"openssl"})," (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ brew install openssl\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install libssl-dev\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 4."})," You will also need the ",(0,t.jsx)(n.strong,{children:"gcc"})," and ",(0,t.jsx)(n.strong,{children:"g++"})," compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing)."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ xcode-select --install\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsx)(n.p,{children:"Instructions for Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ sudo apt install build-essential\n$ gcc --version\n$ g++ --version\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 5."})," Create and activate a new virtual environment. ",(0,t.jsx)(n.strong,{children:"Commands applicable to the virtual environment will be prefixed with (env)"}),". Run the following commands to set it up."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ python3 -m venv env\n$ source env/bin/activate\n(env) $\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 6."})," Inside the virtual environment, upgrade ",(0,t.jsx)(n.strong,{children:"pip"})," to the latest version."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install --upgrade pip\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 7."})," Install ",(0,t.jsx)(n.strong,{children:"jq"}),", a command-line JSON processor."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install jq\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 8."})," Install ",(0,t.jsx)(n.strong,{children:"supervisor"}),", a cross-platform process manager."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install supervisor\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 9."})," Install ",(0,t.jsx)(n.strong,{children:"toml"}),", a configuration file parser."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"(env) $ pip install toml\n"})}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-the-network",children:"Setting up the Network"}),"\n",(0,t.jsx)(n.p,{children:"You are now ready to set up and run your local network of Casper nodes."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["NCTL will not work properly if the following repositories are downloaded via Github's web GUI. To ensure functionality, use the CLI ",(0,t.jsx)(n.code,{children:"git clone"})," command."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 10."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-nctl"})," software in your working directory, referenced here as ",(0,t.jsx)(n.em,{children:"WORKING_DIRECTORY"}),". ",(0,t.jsx)(n.strong,{children:"Very Important!!! Choose a short path for your working directory"}),"; otherwise, the NCTL tool will report that the path is too long."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ cd <WORKING_DIRECTORY>\n$ git clone https://github.com/casper-network/casper-nctl\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 11."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 12."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-client-rs"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-ecosystem/casper-client-rs\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 13."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-node-launcher"})," software in your working directory."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-node-launcher\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsxs)(n.p,{children:["Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the ",(0,t.jsx)(n.code,{children:"deploy_delay"})," in your ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/dev/resources/local/config.toml#L390",children:"local config.toml"})," before running ",(0,t.jsx)(n.code,{children:"nctl-assets-setup"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 14."})," Clone the ",(0,t.jsx)(n.em,{children:"casper-sidecar"})," software in your working directory. As part of Casper's Condor release, the sidecar is now necessary to interact with a Casper network and will handle any API requests."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ git clone https://github.com/casper-network/casper-sidecar\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 15."})," You may need to extend your ",(0,t.jsx)(n.code,{children:".bashrc"})," file to make NCTL commands available from the terminal session. You can do so using the following commands:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"cd YOUR_WORKING_DIRECTORY/casper-nctl\n\ncat >> $HOME/.bashrc <<- EOM\n\n# ----------------------------------------------------------------------\n# CASPER - NCTL\n# ----------------------------------------------------------------------\n\n# Activate NCTL shell.\n. $(pwd)/activate\n\nEOM\n"})}),"\n",(0,t.jsx)(n.p,{children:"Followed by refreshing the bash session:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:". $HOME/.bashrc\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 16."})," Activate the NCTL environment with the following command."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ source casper-node/utils/nctl/activate\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 17."})," Compile the NCTL binary scripts. The following command compiles both the ",(0,t.jsx)(n.em,{children:"casper-node"})," and the ",(0,t.jsx)(n.em,{children:"casper-client"})," in release mode."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-compile\n"})}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"The compilation takes some time, so it might be a perfect moment to get some coffee."})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 18."})," Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes and 10 instances of the sidecar, with 5 active nodes and sidecars and 5 inactive nodes and sidecars."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-assets-setup && nctl-start\n"})}),"\n",(0,t.jsx)(n.p,{children:"Once a network is up and running, you can control each node within the network and add new nodes to the network."}),"\n",(0,t.jsxs)(n.p,{children:["Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by ",(0,t.jsx)(n.em,{children:"nctl-"})," and allow you to perform various tasks."]}),"\n",(0,t.jsxs)(n.p,{children:["You should see the new directory ",(0,t.jsx)(n.em,{children:"utils/nctl/assets"}),", with the following structure."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Assets Setup",src:s(84804).A+"",width:"391",height:"706"})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command line output you would expect."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"NCTL Output",src:s(16943).A+"",width:"795",height:"258"})}),"\n",(0,t.jsx)(n.h2,{id:"stopping-the-network",children:"Stopping the Network"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.strong,{children:"Step 19."})," Although not necessary, you can stop and clean the NCTL setup with the following commands."]}),"\n",(0,t.jsx)(n.p,{children:"Instructions for MacOS and Linux:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"$ nctl-stop\n$ nctl-clean\n"})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/commands.md",children:"various NCTL commands"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Explore the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/master/utils/nctl/docs/usage.md",children:"NCTL usage guide"}),"."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},84804:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/assets_setup-193e704630a056cb0dbb8e86dfac0366.png"},16943:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/nctl_output-8acd66f819f302adcb1d34cc0ff03fe0.png"},28453:(e,n,s)=>{s.d(n,{R:()=>i,x:()=>l});var t=s(96540);const r={},o=t.createContext(r);function i(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ed772d97.ff32e5f5.js b/assets/js/ed772d97.ff32e5f5.js new file mode 100644 index 000000000..6aa31d8fa --- /dev/null +++ b/assets/js/ed772d97.ff32e5f5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[36920],{13127:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var a=n(74848),o=n(28453);const i={title:"Welcome to the official Casper documentation",slug:"/"},s=void 0,r={id:"index",title:"Welcome to the official Casper documentation",description:"What is Casper?",source:"@site/versioned_docs/version-2.0.0/index.md",sourceDirName:".",slug:"/",permalink:"/2.0.0/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Welcome to the official Casper documentation",slug:"/"}},c={},l=[{value:"What is Casper?",id:"what-is-casper",level:2},{value:"How to use this documentation portal",id:"how-to-use-this-documentation-portal",level:2},{value:"Navigation/Layout",id:"navigationlayout",level:3},{value:"Nav bar and Sidebar",id:"nav-bar-and-sidebar",level:4},{value:"Disclaimer",id:"disclaimer",level:2}];function d(e){const t={a:"a",h2:"h2",h3:"h3",h4:"h4",p:"p",...(0,o.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h2,{id:"what-is-casper",children:"What is Casper?"}),"\n",(0,a.jsxs)(t.p,{children:["Casper is a smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/P#permissionless",children:"permissionless"}),", decentralized, public blockchain."]}),"\n",(0,a.jsx)(t.h2,{id:"how-to-use-this-documentation-portal",children:"How to use this documentation portal"}),"\n",(0,a.jsx)(t.h3,{id:"navigationlayout",children:"Navigation/Layout"}),"\n",(0,a.jsx)(t.h4,{id:"nav-bar-and-sidebar",children:"Nav bar and Sidebar"}),"\n",(0,a.jsx)(t.p,{children:"The Nav bar is arranged along the top of your browser window, and may be broken down into left and right. On the left hand side, you will see 5 links, each of which corresponds to a sidebar. There are 5 Sidebars, each of which contains links to content broken down by subject area within the documentation."}),"\n",(0,a.jsx)(t.h2,{id:"disclaimer",children:"Disclaimer"}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.a,{href:"/2.0.0/disclaimer",children:"Legal Disclaimer"}),"."]})]})}function h(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(96540);const o={},i=a.createContext(o);function s(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee7c1cc7.acd77737.js b/assets/js/ee7c1cc7.acd77737.js new file mode 100644 index 000000000..c3f337813 --- /dev/null +++ b/assets/js/ee7c1cc7.acd77737.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[79041],{52306:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var n=s(74848),o=s(28453);const i={title:"Overview",slug:"/economics"},a="Overview of Casper Economics",r={id:"concepts/economics/index",title:"Overview",description:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/index.md",sourceDirName:"concepts/economics",slug:"/economics",permalink:"/1.5.X/economics",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/economics"},sidebar:"concepts",previous:{title:"Reading and Writing Data",permalink:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain"},next:{title:"Consensus",permalink:"/1.5.X/concepts/economics/consensus"}},c={},l=[{value:"Consensus",id:"consensus",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer",level:3},{value:"Runtime",id:"runtime",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer-1",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer-1",level:3},{value:"Ecosystem",id:"ecosystem",level:2},{value:"Macroeconomy",id:"macroeconomy",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview-of-casper-economics",children:"Overview of Casper Economics"})}),"\n",(0,n.jsx)(t.p,{children:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value."}),"\n",(0,n.jsxs)(t.p,{children:["We cannot yet provide formal game-theoretic results for our incentive mechanisms, but interested readers can follow our progress with the ",(0,n.jsx)(t.a,{href:"https://github.com/CasperLabs/Casper-economics-paper",children:"Economics of the Casper Blockchain"})," paper, which will be periodically updated to summarize ongoing research."]}),"\n",(0,n.jsx)(t.p,{children:"This section of our online documentation is intended only to familiarize the user with our core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active."}),"\n",(0,n.jsx)(t.h2,{id:"consensus",children:"Consensus"}),"\n",(0,n.jsxs)(t.p,{children:["The consensus layer of our platform runs on the Highway flavor of CBC-Casper. The distinguishing characteristics of this protocol are its safety and liveness guarantees. Specifically, under the assumptions made in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/highway",children:"Highway protocol paper"}),", blocks in the canonical history cannot be reverted, and new blocks continue to be added to this history indefinitely. The assumptions, however, require that a large portion of validators remain online and honest; this assumed behavior must be incentivized for the platform to remain secure and live."]}),"\n",(0,n.jsx)(t.p,{children:'When discussing consensus, we default to considering it "one era at a time," unless expressly stated otherwise, in keeping with the Highway paper. Recall that each era is, effectively, a separate instance of the protocol.'}),"\n",(0,n.jsx)(t.h3,{id:"agents-consensus-layer",children:"Agents (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Validators"}),' are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.']}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Delegators"}),' are users who participate in the platform\'s security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.']}),"\n",(0,n.jsx)(t.h3,{id:"incentives-consensus-layer",children:"Incentives (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.em,{children:"auction"}),' determines the composition of the validator set for each era of the protocol. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.']}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Rewards"})," (per era) are issued to validators who perform, at their nominal pace, in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Evictions"})," deactivate validators who fail to participate in an era, disabling their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract."]}),"\n",(0,n.jsx)(t.h2,{id:"runtime",children:"Runtime"}),"\n",(0,n.jsxs)(t.p,{children:["The runtime layer encompasses the deployment and execution of smart contracts, session code, and other activity that performs computation on the global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-gas",children:"metering computing time"}),", measured as gas. Gas can be conceptualized as relative time use of different Wasm operations and host-side functions. Use of storage is also presently assigned a gas cost. We do not currently have a pricing mechanism for metered gas, although an outstanding Casper Enhancement Proposal (",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/22",children:"CEP #22"}),") suggests the implementation of a first-price gas auction similar to Ethereum's. The initial Mainnet deploy selection mechanism is based on FIFO."]}),"\n",(0,n.jsxs)(t.p,{children:["We expect to continue work on runtime resource markets, particularly gas futures (",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/17",children:"CEP #17"}),")."]}),"\n",(0,n.jsx)(t.h3,{id:"agents-consensus-layer-1",children:"Agents (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Validators"})," again play a vital role in this layer since protocol operation includes construction and validation of new blocks, consisting of deploys that change the global state, which the validators also maintain."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Users"})," execute session and contract code using the platform's computational resources"]}),"\n",(0,n.jsx)(t.h3,{id:"incentives-consensus-layer-1",children:"Incentives (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Transaction fees"}),", or charges for gas use, ensure that the users compensate validators for performing their computations. Transaction fees are awarded to the block creator. Because we expect to launch with FIFO ordering of deploys, it can be assumed that one unit of gas will be priced at one mote until future changes to deploy orders are implemented."]}),"\n",(0,n.jsx)(t.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,n.jsx)(t.p,{children:"The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps."}),"\n",(0,n.jsx)(t.h2,{id:"macroeconomy",children:"Macroeconomy"}),"\n",(0,n.jsx)(t.p,{children:'Casper\'s macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics are different from those of "digital gold" tokens like Bitcoin, designed to be scarce. Our tokens are minted from a fixed starting basis, which is accounted for by tokens distributed to genesis validators, employees, community members and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate from this basis.'}),"\n",(0,n.jsx)(t.p,{children:"The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, a behavior we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity on the platform and discourage hoarding tokens in expectation of speculative gain."})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const o={},i=n.createContext(o);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee7c1cc7.f382d244.js b/assets/js/ee7c1cc7.f382d244.js deleted file mode 100644 index a57f6b9f0..000000000 --- a/assets/js/ee7c1cc7.f382d244.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9041],{52306:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>a,default:()=>d,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var n=s(74848),o=s(28453);const i={title:"Overview",slug:"/economics"},a="Overview of Casper Economics",r={id:"concepts/economics/index",title:"Overview",description:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value.",source:"@site/versioned_docs/version-1.5.X/concepts/economics/index.md",sourceDirName:"concepts/economics",slug:"/economics",permalink:"/economics",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Overview",slug:"/economics"},sidebar:"concepts",previous:{title:"Reading and Writing Data",permalink:"/concepts/design/reading-and-writing-to-the-blockchain"},next:{title:"Consensus",permalink:"/concepts/economics/consensus"}},c={},l=[{value:"Consensus",id:"consensus",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer",level:3},{value:"Runtime",id:"runtime",level:2},{value:"Agents (consensus layer)",id:"agents-consensus-layer-1",level:3},{value:"Incentives (consensus layer)",id:"incentives-consensus-layer-1",level:3},{value:"Ecosystem",id:"ecosystem",level:2},{value:"Macroeconomy",id:"macroeconomy",level:2}];function h(e){const t={a:"a",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"overview-of-casper-economics",children:"Overview of Casper Economics"})}),"\n",(0,n.jsx)(t.p,{children:"Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value."}),"\n",(0,n.jsxs)(t.p,{children:["We cannot yet provide formal game-theoretic results for our incentive mechanisms, but interested readers can follow our progress with the ",(0,n.jsx)(t.a,{href:"https://github.com/CasperLabs/Casper-economics-paper",children:"Economics of the Casper Blockchain"})," paper, which will be periodically updated to summarize ongoing research."]}),"\n",(0,n.jsx)(t.p,{children:"This section of our online documentation is intended only to familiarize the user with our core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active."}),"\n",(0,n.jsx)(t.h2,{id:"consensus",children:"Consensus"}),"\n",(0,n.jsxs)(t.p,{children:["The consensus layer of our platform runs on the Highway flavor of CBC-Casper. The distinguishing characteristics of this protocol are its safety and liveness guarantees. Specifically, under the assumptions made in the ",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/highway",children:"Highway protocol paper"}),", blocks in the canonical history cannot be reverted, and new blocks continue to be added to this history indefinitely. The assumptions, however, require that a large portion of validators remain online and honest; this assumed behavior must be incentivized for the platform to remain secure and live."]}),"\n",(0,n.jsx)(t.p,{children:'When discussing consensus, we default to considering it "one era at a time," unless expressly stated otherwise, in keeping with the Highway paper. Recall that each era is, effectively, a separate instance of the protocol.'}),"\n",(0,n.jsx)(t.h3,{id:"agents-consensus-layer",children:"Agents (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Validators"}),' are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain\'s security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.']}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Delegators"}),' are users who participate in the platform\'s security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.']}),"\n",(0,n.jsx)(t.h3,{id:"incentives-consensus-layer",children:"Incentives (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.em,{children:"auction"}),' determines the composition of the validator set for each era of the protocol. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.']}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Rewards"})," (per era) are issued to validators who perform, at their nominal pace, in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Evictions"})," deactivate validators who fail to participate in an era, disabling their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract."]}),"\n",(0,n.jsx)(t.h2,{id:"runtime",children:"Runtime"}),"\n",(0,n.jsxs)(t.p,{children:["The runtime layer encompasses the deployment and execution of smart contracts, session code, and other activity that performs computation on the global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to ",(0,n.jsx)(t.a,{href:"/concepts/design/casper-design#execution-semantics-gas",children:"metering computing time"}),", measured as gas. Gas can be conceptualized as relative time use of different Wasm operations and host-side functions. Use of storage is also presently assigned a gas cost. We do not currently have a pricing mechanism for metered gas, although an outstanding Casper Enhancement Proposal (",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/22",children:"CEP #22"}),") suggests the implementation of a first-price gas auction similar to Ethereum's. The initial Mainnet deploy selection mechanism is based on FIFO."]}),"\n",(0,n.jsxs)(t.p,{children:["We expect to continue work on runtime resource markets, particularly gas futures (",(0,n.jsx)(t.a,{href:"https://github.com/casper-network/ceps/pull/17",children:"CEP #17"}),")."]}),"\n",(0,n.jsx)(t.h3,{id:"agents-consensus-layer-1",children:"Agents (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Validators"})," again play a vital role in this layer since protocol operation includes construction and validation of new blocks, consisting of deploys that change the global state, which the validators also maintain."]}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Users"})," execute session and contract code using the platform's computational resources"]}),"\n",(0,n.jsx)(t.h3,{id:"incentives-consensus-layer-1",children:"Incentives (consensus layer)"}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.em,{children:"Transaction fees"}),", or charges for gas use, ensure that the users compensate validators for performing their computations. Transaction fees are awarded to the block creator. Because we expect to launch with FIFO ordering of deploys, it can be assumed that one unit of gas will be priced at one mote until future changes to deploy orders are implemented."]}),"\n",(0,n.jsx)(t.h2,{id:"ecosystem",children:"Ecosystem"}),"\n",(0,n.jsx)(t.p,{children:"The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps."}),"\n",(0,n.jsx)(t.h2,{id:"macroeconomy",children:"Macroeconomy"}),"\n",(0,n.jsx)(t.p,{children:'Casper\'s macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics are different from those of "digital gold" tokens like Bitcoin, designed to be scarce. Our tokens are minted from a fixed starting basis, which is accounted for by tokens distributed to genesis validators, employees, community members and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate from this basis.'}),"\n",(0,n.jsx)(t.p,{children:"The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, a behavior we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity on the platform and discourage hoarding tokens in expectation of speculative gain."})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,t,s)=>{s.d(t,{R:()=>a,x:()=>r});var n=s(96540);const o={},i=n.createContext(o);function a(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee94176e.42f353c4.js b/assets/js/ee94176e.42f353c4.js new file mode 100644 index 000000000..90708f593 --- /dev/null +++ b/assets/js/ee94176e.42f353c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[11433],{4080:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(74848),a=n(28453);const o={title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},i="Interacting with Runtime Return Values",s={id:"resources/advanced/return-values-tutorial",title:"Runtime Return Values",description:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.",source:"@site/docs/resources/advanced/return-values-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/return-values-tutorial",permalink:"/resources/tutorials/advanced/return-values-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},sidebar:"tutorials",previous:{title:"Additional Examples",permalink:"/resources/advanced/multi-sig/other-scenarios"},next:{title:"Authorization Keys",permalink:"/resources/advanced/list-auth-keys-tutorial"}},c={},d=[{value:"Contract Code",id:"return-contract-code",level:2},{value:"Session Code",id:"return-session-code",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"interacting-with-runtime-return-values",children:"Interacting with Runtime Return Values"})}),"\n",(0,r.jsx)(t.p,{children:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code."}),"\n",(0,r.jsx)(t.p,{children:"Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers."}),"\n",(0,r.jsxs)(t.p,{children:["Contract code can optionally return a value to their immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"}),", whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance."]}),"\n",(0,r.jsx)(t.p,{children:"Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything."}),"\n",(0,r.jsx)(t.h2,{id:"return-contract-code",children:"Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["For example, if we create a contract to accept and keep a record of donations, we would use ",(0,r.jsx)(t.code,{children:"runtime::ret()"})," to define the results that should be passed to the caller as per the following:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn donate() {\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n if let Key::Account(donating_account_hash) = donating_account_key {\n update_ledger_record(donating_account_hash.to_string())\n } else {\n runtime::revert(FundRaisingError::InvalidKeyVariant)\n }\n let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)\n .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)\n .as_uref()\n .unwrap_or_revert();\n let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();\n runtime::ret(value)\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["In this example, the return value is the URef corresponding to the purse used to raise funds, with ",(0,r.jsx)(t.code,{children:"add"})," permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the ",(0,r.jsx)(t.code,{children:"donate"})," entry point."]}),"\n",(0,r.jsxs)(t.p,{children:["Without the addition of the ",(0,r.jsx)(t.code,{children:"runtime::ret"}),", the purse would not be returned to the caller."]}),"\n",(0,r.jsx)(t.h2,{id:"return-session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["The following is an example of session code calling the ",(0,r.jsx)(t.a,{href:"#return-contract-code",children:"specified entry point"}),". Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);\n\n let donating_purse_uref: URef = runtime::call_contract(\n fundraiser_contract_hash,\n ENTRY_POINT_DONATE,\n runtime_args! {\n DONATING_ACCOUNT_KEY => donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["This session code calls into a contract's entry point by using ",(0,r.jsx)(t.code,{children:"runtime::call_contract"}),", supplying the ",(0,r.jsx)(t.code,{children:"contract_hash"})," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,r.jsx)(t.code,{children:"donate"}),". It supplies the ",(0,r.jsx)(t.code,{children:"donating_account_key"}),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,r.jsx)(t.code,{children:"donating_purse_uref"}),". To call an entry point, you will need to know the ",(0,r.jsx)(t.a,{href:"/developers/json-rpc/types_cl",children:"CLType"})," of the return value and identify it within the code."]}),"\n",(0,r.jsxs)(t.p,{children:["You can determine the type of the return value by ",(0,r.jsx)(t.a,{href:"/resources/tutorials/beginner/querying-network#querying-an-account",children:"querying the contract object"})," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."]}),"\n",(0,r.jsxs)(t.p,{children:["This example code takes that returned value and transfers a ",(0,r.jsx)(t.code,{children:"donation_amount"})," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const a={},o=r.createContext(a);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ee94176e.948fb7cb.js b/assets/js/ee94176e.948fb7cb.js deleted file mode 100644 index a2e301a38..000000000 --- a/assets/js/ee94176e.948fb7cb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1433],{4080:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>u,frontMatter:()=>o,metadata:()=>s,toc:()=>d});var r=n(74848),a=n(28453);const o={title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},i="Interacting with Runtime Return Values",s={id:"resources/advanced/return-values-tutorial",title:"Runtime Return Values",description:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.",source:"@site/docs/resources/advanced/return-values-tutorial.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/return-values-tutorial",permalink:"/next/resources/tutorials/advanced/return-values-tutorial",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Runtime Return Values",slug:"/resources/tutorials/advanced/return-values-tutorial"},sidebar:"tutorials",previous:{title:"Additional Examples",permalink:"/next/resources/advanced/multi-sig/other-scenarios"},next:{title:"Authorization Keys",permalink:"/next/resources/advanced/list-auth-keys-tutorial"}},c={},d=[{value:"Contract Code",id:"return-contract-code",level:2},{value:"Session Code",id:"return-session-code",level:2}];function l(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",p:"p",pre:"pre",...(0,a.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(t.header,{children:(0,r.jsx)(t.h1,{id:"interacting-with-runtime-return-values",children:"Interacting with Runtime Return Values"})}),"\n",(0,r.jsx)(t.p,{children:"Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code."}),"\n",(0,r.jsx)(t.p,{children:"Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers."}),"\n",(0,r.jsxs)(t.p,{children:["Contract code can optionally return a value to their immediate caller via ",(0,r.jsx)(t.code,{children:"runtime::ret()"}),", whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance."]}),"\n",(0,r.jsx)(t.p,{children:"Session code initiates actions on behalf of an account which is considered to be the caller. Therefore, it cannot return anything."}),"\n",(0,r.jsx)(t.h2,{id:"return-contract-code",children:"Contract Code"}),"\n",(0,r.jsxs)(t.p,{children:["For example, if we create a contract to accept and keep a record of donations, we would use ",(0,r.jsx)(t.code,{children:"runtime::ret()"})," to define the results that should be passed to the caller as per the following:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn donate() {\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n if let Key::Account(donating_account_hash) = donating_account_key {\n update_ledger_record(donating_account_hash.to_string())\n } else {\n runtime::revert(FundRaisingError::InvalidKeyVariant)\n }\n let donation_purse = *runtime::get_key(FUNDRAISING_PURSE)\n .unwrap_or_revert_with(FundRaisingError::MissingFundRaisingPurseURef)\n .as_uref()\n .unwrap_or_revert();\n let value = CLValue::from_t(donation_purse.into_add()).unwrap_or_revert();\n runtime::ret(value)\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["In this example, the return value is the URef corresponding to the purse used to raise funds, with ",(0,r.jsx)(t.code,{children:"add"})," permission only. Using this information, the calling code will be able to then transfer funds into the purse, after calling the ",(0,r.jsx)(t.code,{children:"donate"})," entry point."]}),"\n",(0,r.jsxs)(t.p,{children:["Without the addition of the ",(0,r.jsx)(t.code,{children:"runtime::ret"}),", the purse would not be returned to the caller."]}),"\n",(0,r.jsx)(t.h2,{id:"return-session-code",children:"Session Code"}),"\n",(0,r.jsxs)(t.p,{children:["The following is an example of session code calling the ",(0,r.jsx)(t.a,{href:"#return-contract-code",children:"specified entry point"}),". Keep in mind that the immediate caller does not need to be session code, and the immediate caller could be another instance of contract code."]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{className:"language-rust",children:'\n#[no_mangle]\npub extern "C" fn call() {\n let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);\n let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);\n let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);\n\n let donating_purse_uref: URef = runtime::call_contract(\n fundraiser_contract_hash,\n ENTRY_POINT_DONATE,\n runtime_args! {\n DONATING_ACCOUNT_KEY => donating_account_key\n },\n );\n system::transfer_from_purse_to_purse(\n account::get_main_purse(),\n donating_purse_uref,\n donation_amount,\n None\n )\n .unwrap_or_revert()\n}\n\n'})}),"\n",(0,r.jsxs)(t.p,{children:["This session code calls into a contract's entry point by using ",(0,r.jsx)(t.code,{children:"runtime::call_contract"}),", supplying the ",(0,r.jsx)(t.code,{children:"contract_hash"})," to identify the contract to be called, and the name of the entry point to be invoked, in this case ",(0,r.jsx)(t.code,{children:"donate"}),". It supplies the ",(0,r.jsx)(t.code,{children:"donating_account_key"}),", which in this case is the account key of the caller. The contract will then provide a return value, in this case ",(0,r.jsx)(t.code,{children:"donating_purse_uref"}),". To call an entry point, you will need to know the ",(0,r.jsx)(t.a,{href:"/next/developers/json-rpc/types_cl",children:"CLType"})," of the return value and identify it within the code."]}),"\n",(0,r.jsxs)(t.p,{children:["You can determine the type of the return value by ",(0,r.jsx)(t.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-an-account",children:"querying the contract object"})," in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash."]}),"\n",(0,r.jsxs)(t.p,{children:["This example code takes that returned value and transfers a ",(0,r.jsx)(t.code,{children:"donation_amount"})," from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer."]})]})}function u(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,r.jsx)(t,{...e,children:(0,r.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>s});var r=n(96540);const a={},o=r.createContext(a);function i(e){const t=r.useContext(o);return r.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),r.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eeb3740b.7aca9b4d.js b/assets/js/eeb3740b.7aca9b4d.js new file mode 100644 index 000000000..631b1837b --- /dev/null +++ b/assets/js/eeb3740b.7aca9b4d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84391],{37713:(n,e,t)=>{t.r(e),t.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>a,frontMatter:()=>d,metadata:()=>c,toc:()=>h});var s=t(74848),r=t(28453);const d={title:"The Chainspec"},i="The Blockchain Specification {#the-chain-specification}",c={id:"operators/setup-network/chain-spec",title:"The Chainspec",description:"the-chain-specification}",source:"@site/versioned_docs/version-2.0.0/operators/setup-network/chain-spec.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/chain-spec",permalink:"/2.0.0/operators/setup-network/chain-spec",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"The Chainspec"},sidebar:"operators",previous:{title:"Genesis",permalink:"/2.0.0/operators/setup-network/genesis"},next:{title:"Private Network Setup",permalink:"/2.0.0/operators/setup-network/create-private"}},l={},h=[{value:"protocol",id:"protocol",level:2},{value:"network",id:"network",level:2},{value:"core",id:"core",level:2},{value:"highway",id:"highway",level:2},{value:"transactions",id:"transactions",level:2},{value:"transactions.v1",id:"transactionsv1",level:3},{value:"transactions.deploy",id:"transactionsdeploy",level:3},{value:"wasm",id:"wasm",level:2},{value:"wasm.storage_costs",id:"wasmstorage_costs",level:3},{value:"wasm.opcode_costs",id:"wasmopcode_costs",level:3},{value:"wasm.opcode_costs.control_flow",id:"wasmopcode_costscontrol_flow",level:3},{value:"wasm.opcode_costs.control_flow.br_table",id:"wasmopcode_costscontrol_flowbr_table",level:3},{value:"wasm.messages_limits",id:"wasmmessages_limits",level:2},{value:"wasm.host_function_costs",id:"wasmhost_function_costs",level:3},{value:"system_costs",id:"system_costs",level:2},{value:"system_costs.auction_costs",id:"system_costsauction_costs",level:3},{value:"system_costs.mint_costs",id:"system_costsmint_costs",level:3},{value:"system_costs.handle_payment_costs",id:"system_costshandle_payment_costs",level:3},{value:"system_costs.standard_payment_costs",id:"system_costsstandard_payment_costs",level:3}];function o(n){const e={a:"a",br:"br",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...n.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(e.header,{children:(0,s.jsx)(e.h1,{id:"the-chain-specification",children:"The Blockchain Specification"})}),"\n",(0,s.jsxs)(e.p,{children:["The blockchain specification, or ",(0,s.jsx)(e.code,{children:"chainspec"}),", is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 2.0.0 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring. "]}),"\n",(0,s.jsx)(e.h2,{id:"protocol",children:"protocol"}),"\n",(0,s.jsx)(e.p,{children:"These settings describe the active protocol version."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"version"}),(0,s.jsx)(e.td,{children:"The Casper node protocol version."}),(0,s.jsx)(e.td,{children:"'2.0.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"hard_reset"}),(0,s.jsx)(e.td,{children:"When set to true, clear blocks and transactions back to the switch block (the end of the last era) just before the activation point. Used during the upgrade process to reset the network progress. In most cases, this setting should be true."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activation_point"}),(0,s.jsxs)(e.td,{children:["The protocol version that should become active. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is a timestamp string, it represents the timestamp for the genesis block. This is the beginning of Era 0. By this time, a sufficient majority (> 50% + F/2 \u2014 see the ",(0,s.jsx)(e.code,{children:"finality_threshold_fraction"})," below) of validator nodes must be running to start the blockchain. This timestamp is also used in seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash. ",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"If it is an integer, it represents an era ID, meaning the protocol version becomes active at the start of this era."]}),(0,s.jsx)(e.td,{children:"11100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"network",children:"network"}),"\n",(0,s.jsx)(e.p,{children:"The following settings configure the networking layer."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"name"}),(0,s.jsx)(e.td,{children:"Human readable network name for convenience. The state_root_hash of the genesis block is the true identifier. The name influences the genesis hash by contributing to seeding the pseudo-random number generator used in the contract runtime for computing the genesis post-state hash."}),(0,s.jsx)(e.td,{children:"'casper'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_net_message_size"}),(0,s.jsx)(e.td,{children:"The maximum size of an acceptable networking message in bytes. Any message larger than this will be rejected at the networking level."}),(0,s.jsx)(e.td,{children:"25_165_824"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"core",children:"core"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage the core protocol behavior."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"era_duration"}),(0,s.jsx)(e.td,{children:"Era duration."}),(0,s.jsx)(e.td,{children:"'120 minutes'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_era_height"}),(0,s.jsxs)(e.td,{children:["Minimum number of blocks per era. An era will take longer than ",(0,s.jsx)(e.code,{children:"era_duration"})," if that is necessary to reach the minimum height."]}),(0,s.jsx)(e.td,{children:"20"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_block_time"}),(0,s.jsx)(e.td,{children:"Minimum difference between a block's and its child's timestamp."}),(0,s.jsx)(e.td,{children:"'16384 ms'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_slots"}),(0,s.jsx)(e.td,{children:"Number of slots available in the validator auction."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_threshold_fraction"}),(0,s.jsxs)(e.td,{children:["A number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.",(0,s.jsx)(e.br,{}),"It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.",(0,s.jsx)(e.br,{}),"Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly."]}),(0,s.jsx)(e.td,{children:"[1, 3]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsxs)(e.td,{children:["start_protocol_version_with_strict",(0,s.jsx)(e.br,{}),"_finality_signatures_required"]}),(0,s.jsx)(e.td,{children:"Protocol version from which nodes are required to hold strict finality signatures."}),(0,s.jsx)(e.td,{children:"'1.5.0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"legacy_required_finality"}),(0,s.jsxs)(e.td,{children:["The finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'. ",(0,s.jsx)(e.br,{}),"Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures."]}),(0,s.jsx)(e.td,{children:"'Strict'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_accounts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user accounts to addressable entity. If false, user accounts will be left as they are and will be lazily migrated on a per-account basis if / when that account is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"migrate_legacy_contracts"}),(0,s.jsx)(e.td,{children:"If true, the protocol upgrade will migrate ALL user contracts to addressable entity. If false, user contracts will be left as they are and will be lazily migrated on a per-contract basis if / when that contract is used during transaction execution."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"auction_delay"}),(0,s.jsx)(e.td,{children:"Number of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1."}),(0,s.jsx)(e.td,{children:"1"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"locked_funds_period"}),(0,s.jsx)(e.td,{children:"The period after genesis during which a genesis validator's bid is locked."}),(0,s.jsx)(e.td,{children:"'0 days'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"vesting_schedule_period"}),(0,s.jsx)(e.td,{children:"The period in which the genesis validator's bid is released over time after it is unlocked."}),(0,s.jsx)(e.td,{children:"'0 weeks'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unbonding_delay"}),(0,s.jsx)(e.td,{children:"Default number of eras that need to pass to be able to withdraw unbonded funds."}),(0,s.jsx)(e.td,{children:"7"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"round_seigniorage_rate"}),(0,s.jsxs)(e.td,{children:["Round seigniorage rate represented as a fraction of the total supply.",(0,s.jsx)(e.br,{}),"- Annual issuance: 8%.",(0,s.jsx)(e.br,{}),"- Minimum block time: 2^15 milliseconds.",(0,s.jsx)(e.br,{}),"- Ticks per year: 31536000000.",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.br,{}),"(1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:",(0,s.jsx)(e.br,{}),(0,s.jsx)(e.code,{children:"Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)"})]}),(0,s.jsx)(e.td,{children:"[7, 175070816]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_associated_keys"}),(0,s.jsx)(e.td,{children:"Maximum number of associated keys for a single account."}),(0,s.jsx)(e.td,{children:"100"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_runtime_call_stack_height"}),(0,s.jsx)(e.td,{children:"Maximum height of the contract runtime call stack."}),(0,s.jsx)(e.td,{children:"12"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"minimum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Minimum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"500_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_delegation_amount"}),(0,s.jsx)(e.td,{children:"Maximum allowed delegation amount in motes."}),(0,s.jsx)(e.td,{children:"1_000_000_000_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"prune_batch_size"}),(0,s.jsxs)(e.td,{children:["Global state prune batch size for tip pruning. Possible values:",(0,s.jsx)(e.br,{}),"- 0 when the feature is OFF",(0,s.jsx)(e.br,{}),"- Integer if the feature is ON, representing the number of eras to process per block."]}),(0,s.jsx)(e.td,{children:"0"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"strict_argument_checking"}),(0,s.jsxs)(e.td,{children:["Enables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct ",(0,s.jsx)(e.code,{children:"CLType"}),"."]}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"simultaneous_peer_requests"}),(0,s.jsx)(e.td,{children:"Number of simultaneous peer requests."}),(0,s.jsx)(e.td,{children:"5"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"consensus_protocol"}),(0,s.jsx)(e.td,{children:"The consensus protocol to use. Options are 'Zug' or 'Highway'."}),(0,s.jsx)(e.td,{children:"'Zug'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_delegators_per_validator"}),(0,s.jsx)(e.td,{children:"The maximum amount of delegators per validator. If the value is 0, there is no maximum capacity."}),(0,s.jsx)(e.td,{children:"1200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finders_fee"}),(0,s.jsx)(e.td,{children:"The split in finality signature rewards between block producer and participating signers."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finality_signature_proportion"}),(0,s.jsx)(e.td,{children:"The proportion of baseline rewards going to reward finality signatures specifically."}),(0,s.jsx)(e.td,{children:"[1, 2]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"signature_rewards_max_delay"}),(0,s.jsx)(e.td,{children:"Lookback interval indicating how many past blocks we are looking at to reward."}),(0,s.jsx)(e.td,{children:"3"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_unrestricted_transfers"}),(0,s.jsx)(e.td,{children:"Allows peer to peer transfers between users. Setting this to false makes sense only for private chains."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_auction_bids"}),(0,s.jsx)(e.td,{children:"Enables the auction entry points 'delegate' and 'add_bid'. Setting this to false makes sense only for private chains that don't need to auction new validator slots. These auction entry points will return an error if called, when this option is set to false."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"compute_rewards"}),(0,s.jsx)(e.td,{children:"If set to false, then consensus doesn't compute rewards and always uses 0."}),(0,s.jsx)(e.td,{children:"true"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"refund_handling"}),(0,s.jsx)(e.td,{children:"Defines how refunds of the unused portion of payment amounts are calculated and handled. Valid options are: refund (a ratio of the unspent token is returned to the spender); burn (a ratio of the unspent token is burned); no_refund (no refunds are paid out)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_refund' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"fee_handling"}),(0,s.jsx)(e.td,{children:"Defines how fees are handled. Valid options are: no_fee (fees are eliminated); pay_to_proposer (fees are paid to the block proposer); accumulate (fees are accumulated in a special purse and distributed at the end of each era evenly among all administrator accounts); burn (fees are burned)"}),(0,s.jsx)(e.td,{children:"{ type = 'no_fee' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"validator_credit_cap"}),(0,s.jsx)(e.td,{children:"If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake."}),(0,s.jsx)(e.td,{children:"[1, 5]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pricing_handling"}),(0,s.jsx)(e.td,{children:"Defines how pricing is handled. Valid options are: classic (senders of transaction self-specify how much they pay); fixed (costs are fixed, per the cost table); reserved (prepaid transaction, currently not supported)"}),(0,s.jsx)(e.td,{children:"{ type = 'fixed' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"allow_reservations"}),(0,s.jsx)(e.td,{children:"Does the network allow pre-payment / reservations for future execution? Currently not supported."}),(0,s.jsx)(e.td,{children:"false"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_balance_handling"}),(0,s.jsx)(e.td,{children:"Defines how gas holds affect available balance calculations. Valid options are: accrued (sum of full value of all non-expired holds) and amortized (sum of each hold is amortized over the time remaining until expiry)."}),(0,s.jsx)(e.td,{children:"{ type = 'accrued' }"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_hold_interval"}),(0,s.jsx)(e.td,{children:"Defines how long gas holds last."}),(0,s.jsx)(e.td,{children:"'24 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"administrators"}),(0,s.jsx)(e.td,{children:"List of public keys of administrator accounts. Setting this option makes only on private chains which require administrator accounts for regulatory reasons."}),(0,s.jsx)(e.td,{children:"[]"})]})]})]}),"\n",(0,s.jsxs)(e.p,{children:["See the ",(0,s.jsx)(e.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"Fee Elimination"})," page for more details regarding ",(0,s.jsx)(e.code,{children:"refund_handling"}),", ",(0,s.jsx)(e.code,{children:"fee_handling"}),", ",(0,s.jsx)(e.code,{children:"validator_credit_cap"}),", ",(0,s.jsx)(e.code,{children:"pricing_handling"}),", ",(0,s.jsx)(e.code,{children:"gas_hold_balance_handling"}),", and ",(0,s.jsx)(e.code,{children:"gas_hold_interval"}),"."]}),"\n",(0,s.jsx)(e.h2,{id:"highway",children:"highway"}),"\n",(0,s.jsx)(e.p,{children:"These settings configure the Highway Consensus protocol."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"maximum_round_length"}),(0,s.jsxs)(e.td,{children:["Highway dynamically chooses its round length between ",(0,s.jsx)(e.code,{children:"minimum_block_time"})," and ",(0,s.jsx)(e.code,{children:"maximum_round_length"}),"."]}),(0,s.jsx)(e.td,{children:"'66 seconds'"})]})})]}),"\n",(0,s.jsx)(e.h2,{id:"transactions",children:"transactions"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage transactions and their lifecycle."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_ttl"}),(0,s.jsx)(e.td,{children:"The duration after the transaction timestamp during which the transaction can be included in a block."}),(0,s.jsx)(e.td,{children:"'2 hours'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_max_approval_count"}),(0,s.jsx)(e.td,{children:"The maximum number of approvals permitted in a single block."}),(0,s.jsx)(e.td,{children:"2600"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_block_size"}),(0,s.jsx)(e.td,{children:"Maximum block size in bytes, including transactions contained by the block. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"5_242_880"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block_gas_limit"}),(0,s.jsx)(e.td,{children:"The upper limit of the total gas of all transactions in a block."}),(0,s.jsx)(e.td,{children:"3_300_000_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_transfer_minimum_motes"}),(0,s.jsx)(e.td,{children:"The minimum amount in motes for a valid native transfer."}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_timestamp_leeway"}),(0,s.jsxs)(e.td,{children:["The maximum value to which ",(0,s.jsx)(e.code,{children:"transaction_acceptor.timestamp_leeway"})," can be set in the config.toml file."]}),(0,s.jsx)(e.td,{children:"'5 seconds'"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsv1",children:"transactions.v1"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the transaction lanes including both native and Wasm based interactions. See ",(0,s.jsx)(e.a,{href:"/2.0.0/runtime#lanes-and-gas-costs-lanes",children:"Lanes and gas costs"})," for details."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_mint_lane"}),(0,s.jsx)(e.td,{children:"[0, 1024, 1024, 65_000_000_000, 650]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"native_auction_lane"}),(0,s.jsx)(e.td,{children:"[1, 2048, 2048, 362_500_000_000, 145]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"wasm_lanes"}),(0,s.jsx)(e.td,{children:"[[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"transactionsdeploy",children:"transactions.deploy"}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_payment_cost"}),(0,s.jsx)(e.td,{children:"The maximum number of motes allowed to be spent during payment. 0 means unlimited."}),(0,s.jsx)(e.td,{children:"'0'"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_dependencies"}),(0,s.jsx)(e.td,{children:"The maximum number of other transactions a transaction can depend on (requiring them to have been executed before it can execute)."}),(0,s.jsx)(e.td,{children:"10"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"payment_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized payment code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"session_args_max_length"}),(0,s.jsx)(e.td,{children:"The limit of length of serialized session code arguments."}),(0,s.jsx)(e.td,{children:"1024"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasm",children:"wasm"}),"\n",(0,s.jsx)(e.p,{children:"The following are Wasm-related settings."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_memory"}),(0,s.jsx)(e.td,{children:"Amount of free memory (in 64 kB pages) each contract can use for its stack."}),(0,s.jsx)(e.td,{children:"64"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_stack_height"}),(0,s.jsx)(e.td,{children:"Max stack height (native WebAssembly stack limiter)."}),(0,s.jsx)(e.td,{children:"500"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmstorage_costs",children:"wasm.storage_costs"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage Wasm storage costs."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"gas_per_byte"}),(0,s.jsx)(e.td,{children:"Gas charged per byte stored in global state."}),(0,s.jsx)(e.td,{children:"1_117_587"})]})})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costs",children:"wasm.opcode_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage the cost table for Wasm opcodes."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"bit"}),(0,s.jsx)(e.td,{children:"Bit operations multiplier."}),(0,s.jsx)(e.td,{children:"300"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"Arithmetic add operations multiplier."}),(0,s.jsx)(e.td,{children:"210"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mul"}),(0,s.jsx)(e.td,{children:"Mul operations multiplier."}),(0,s.jsx)(e.td,{children:"240"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"div"}),(0,s.jsx)(e.td,{children:"Div operations multiplier."}),(0,s.jsx)(e.td,{children:"320"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load"}),(0,s.jsx)(e.td,{children:"Memory load operation multiplier."}),(0,s.jsx)(e.td,{children:"2_500"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"store"}),(0,s.jsx)(e.td,{children:"Memory store operation multiplier."}),(0,s.jsx)(e.td,{children:"4_700"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"const"}),(0,s.jsx)(e.td,{children:"Const store operation multiplier."}),(0,s.jsx)(e.td,{children:"110"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"local"}),(0,s.jsx)(e.td,{children:"Local operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"global"}),(0,s.jsx)(e.td,{children:"Global operations multiplier."}),(0,s.jsx)(e.td,{children:"390"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"integer_comparison"}),(0,s.jsx)(e.td,{children:"Integer operations multiplier."}),(0,s.jsx)(e.td,{children:"250"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"conversion"}),(0,s.jsx)(e.td,{children:"Conversion operations multiplier."}),(0,s.jsx)(e.td,{children:"420"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"unreachable"}),(0,s.jsx)(e.td,{children:"Unreachable operation multiplier."}),(0,s.jsx)(e.td,{children:"270"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"nop"}),(0,s.jsx)(e.td,{children:"Nop operation multiplier."}),(0,s.jsx)(e.td,{children:"200"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"current_memory"}),(0,s.jsx)(e.td,{children:"Get the current memory operation multiplier."}),(0,s.jsx)(e.td,{children:"290"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"grow_memory"}),(0,s.jsx)(e.td,{children:"Grow memory cost per page (64 kB)."}),(0,s.jsx)(e.td,{children:"240_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flow",children:"wasm.opcode_costs.control_flow"}),"\n",(0,s.jsx)(e.p,{children:"These settings manage costs for control flow operations."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"block"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"block"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"loop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"loop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"if"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"else"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"else"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"end"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"end"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"br_if"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"br_if"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"return"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"return"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"select"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"select"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_indirect"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"call_indirect"})," opcode."]}),(0,s.jsx)(e.td,{children:"68_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"drop"}),(0,s.jsxs)(e.td,{children:["Cost for ",(0,s.jsx)(e.code,{children:"drop"})," opcode."]}),(0,s.jsx)(e.td,{children:"440"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmopcode_costscontrol_flowbr_table",children:"wasm.opcode_costs.control_flow.br_table"}),"\n",(0,s.jsxs)(e.p,{children:["The following settings manage ",(0,s.jsx)(e.code,{children:"br_table"})," Wasm opcodes."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost"}),(0,s.jsxs)(e.td,{children:["Fixed cost per ",(0,s.jsx)(e.code,{children:"br_table"})," opcode."]}),(0,s.jsx)(e.td,{children:"35_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"size_multiplier"}),(0,s.jsxs)(e.td,{children:["Size of target labels in the ",(0,s.jsx)(e.code,{children:"br_table"})," opcode will be multiplied by ",(0,s.jsx)(e.code,{children:"size_multiplier"}),"."]}),(0,s.jsx)(e.td,{children:"100"})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"wasmmessages_limits",children:"wasm.messages_limits"}),"\n",(0,s.jsx)(e.p,{children:"The following chainspec settings manage the cost of contract-level messages."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topic_name_size"}),(0,s.jsx)(e.td,{children:"Maximum size of the topic name."}),(0,s.jsx)(e.td,{children:"256"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_topics_per_contract"}),(0,s.jsx)(e.td,{children:"Maximum number of topics that can be added for each contract."}),(0,s.jsx)(e.td,{children:"128"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"max_message_size"}),(0,s.jsx)(e.td,{children:"Maximum size in bytes of the serialized message payload."}),(0,s.jsx)(e.td,{children:"1_024"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"wasmhost_function_costs",children:"wasm.host_function_costs"}),"\n",(0,s.jsxs)(e.p,{children:['The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in ',(0,s.jsx)(e.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.2/smart_contracts/contract/src/ext_ffi.rs",children:"smart_contracts/contract/src/ext_ffi.rs"}),"."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Host-Side Function"}),(0,s.jsx)(e.th,{children:"Cost"}),(0,s.jsx)(e.th,{children:"Arguments"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add"}),(0,s.jsx)(e.td,{children:"5_800"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_associated_key"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"blake2b"}),(0,s.jsx)(e.td,{children:"1_200_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"call_versioned_contract"}),(0,s.jsx)(e.td,{children:"300_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 120_000, 0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_package_at_hash"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create_purse"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"disable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_balance"}),(0,s.jsx)(e.td,{children:"3_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_blocktime"}),(0,s.jsx)(e.td,{children:"330"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_caller"}),(0,s.jsx)(e.td,{children:"380"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_key"}),(0,s.jsx)(e.td,{children:"2_000"}),(0,s.jsx)(e.td,{children:"[0, 440, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_main_purse"}),(0,s.jsx)(e.td,{children:"1_300"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_named_arg_size"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_phase"}),(0,s.jsx)(e.td,{children:"710"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_system_contract"}),(0,s.jsx)(e.td,{children:"1_100"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"has_key"}),(0,s.jsx)(e.td,{children:"1_500"}),(0,s.jsx)(e.td,{children:"[0, 840]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"is_valid_uref"}),(0,s.jsx)(e.td,{children:"760"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"load_named_keys"}),(0,s.jsx)(e.td,{children:"42_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"new_uref"}),(0,s.jsx)(e.td,{children:"17_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 590]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"random_bytes"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"print"}),(0,s.jsx)(e.td,{children:"20_000"}),(0,s.jsx)(e.td,{children:"[0, 4_600]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"provision_contract_user_group_uref"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"put_key"}),(0,s.jsx)(e.td,{children:"100_000_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_host_buffer"}),(0,s.jsx)(e.td,{children:"3_500"}),(0,s.jsx)(e.td,{children:"[0, 310, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value"}),(0,s.jsx)(e.td,{children:"60_000"}),(0,s.jsx)(e.td,{children:"[0, 120_000, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_value_local"}),(0,s.jsx)(e.td,{children:"5_500"}),(0,s.jsx)(e.td,{children:"[0, 590, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_contract_user_group_urefs"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"remove_key"}),(0,s.jsx)(e.td,{children:"61_000"}),(0,s.jsx)(e.td,{children:"[0, 3_200]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"ret"}),(0,s.jsx)(e.td,{children:"23_000"}),(0,s.jsx)(e.td,{children:"[0, 420_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"revert"}),(0,s.jsx)(e.td,{children:"500"}),(0,s.jsx)(e.td,{children:"[0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_action_threshold"}),(0,s.jsx)(e.td,{children:"74_000"}),(0,s.jsx)(e.td,{children:"[0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_from_purse_to_purse"}),(0,s.jsx)(e.td,{children:"82_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer_to_account"}),(0,s.jsx)(e.td,{children:"2_500_000_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"update_associated_key"}),(0,s.jsx)(e.td,{children:"4_200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"write"}),(0,s.jsx)(e.td,{children:"14_000"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 980]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"dictionary_put"}),(0,s.jsx)(e.td,{children:"9_500"}),(0,s.jsx)(e.td,{children:"[0, 1_800, 0, 520]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"enable_contract_version"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 0, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"manage_message_topic"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 0]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"emit_message"}),(0,s.jsx)(e.td,{children:"200"}),(0,s.jsx)(e.td,{children:"[0, 30_000, 0, 120_000]"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"cost_increase_per_message"}),(0,s.jsx)(e.td,{children:"50"}),(0,s.jsx)(e.td,{})]})]})]}),"\n",(0,s.jsx)(e.h2,{id:"system_costs",children:"system_costs"}),"\n",(0,s.jsx)(e.p,{children:"The following settings manage protocol operating costs."}),"\n",(0,s.jsx)(e.h3,{id:"system_costsauction_costs",children:"system_costs.auction_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"auction"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_era_validators"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_era_validators"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_seigniorage_recipients"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_seigniorage_recipients"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"add_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"add_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"delegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"delegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"undelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"undelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"run_auction"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"run_auction"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"slash"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"slash"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"distribute"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"distribute"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_delegator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_delegator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"withdraw_validator_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"withdraw_validator_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_era_id"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_era_id"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"activate_bid"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"activate_bid"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"redelegate"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"redelegate"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"change_bid_public_key"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"change_bid_public_key"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"5_000_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsmint_costs",children:"system_costs.mint_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling the ",(0,s.jsx)(e.code,{children:"mint"})," system contract entrypoints."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"reduce_total_supply"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"reduce_total_supply"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"create"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"create"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"balance"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"balance"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"burn"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"burn"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"transfer"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"transfer"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"read_base_round_reward"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"read_base_round_reward"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"mint_into_existing_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"mint_into_existing_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"2_500_000_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costshandle_payment_costs",children:"system_costs.handle_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"handle_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsxs)(e.tbody,{children:[(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_payment_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_payment_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"set_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"set_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"get_refund_purse"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"get_refund_purse"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]}),(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"finalize_payment"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"finalize_payment"})," entrypoint."]}),(0,s.jsx)(e.td,{children:"10_000"})]})]})]}),"\n",(0,s.jsx)(e.h3,{id:"system_costsstandard_payment_costs",children:"system_costs.standard_payment_costs"}),"\n",(0,s.jsxs)(e.p,{children:["These settings manage the costs of calling entrypoints on the ",(0,s.jsx)(e.code,{children:"standard_payment"})," system contract."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(e.table,{children:[(0,s.jsx)(e.thead,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.th,{children:"Attribute"}),(0,s.jsx)(e.th,{children:"Description"}),(0,s.jsx)(e.th,{children:"Mainnet Setting"})]})}),(0,s.jsx)(e.tbody,{children:(0,s.jsxs)(e.tr,{children:[(0,s.jsx)(e.td,{children:"pay"}),(0,s.jsxs)(e.td,{children:["Cost of calling the ",(0,s.jsx)(e.code,{children:"pay"})," entrypoint and sending an amount to a payment purse."]}),(0,s.jsx)(e.td,{children:"10_000"})]})})]})]})}function a(n={}){const{wrapper:e}={...(0,r.R)(),...n.components};return e?(0,s.jsx)(e,{...n,children:(0,s.jsx)(o,{...n})}):o(n)}},28453:(n,e,t)=>{t.d(e,{R:()=>i,x:()=>c});var s=t(96540);const r={},d=s.createContext(r);function i(n){const e=s.useContext(d);return s.useMemo((function(){return"function"==typeof n?n(e):{...e,...n}}),[e,n])}function c(n){let e;return e=n.disableParentContext?"function"==typeof n.components?n.components(r):n.components||r:i(n.components),s.createElement(d.Provider,{value:e},n.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef2abd7e.4f00923b.js b/assets/js/ef2abd7e.4f00923b.js new file mode 100644 index 000000000..8a33ae63a --- /dev/null +++ b/assets/js/ef2abd7e.4f00923b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[70715],{798:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var s=t(74848),a=t(28453);const o={title:"dApps"},i="Introduction to dApps",c={id:"concepts/intro-to-dapps",title:"dApps",description:"What is a dApp?",source:"@site/versioned_docs/version-1.5.X/concepts/intro-to-dapps.md",sourceDirName:"concepts",slug:"/concepts/intro-to-dapps",permalink:"/1.5.X/concepts/intro-to-dapps",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"dApps"},sidebar:"concepts",previous:{title:"What is Casper?",permalink:"/1.5.X/"},next:{title:"Accounts and Keys",permalink:"/1.5.X/concepts/accounts-and-keys"}},r={},l=[{value:"What is a dApp?",id:"what-is-a-dapp",level:3},{value:"Interacting with a Casper Decentralized Network",id:"interacting-with-a-casper-decentralized-network",level:3},{value:"Updating data in a Casper dApp",id:"updating-data-in-a-casper-dapp",level:4},{value:"Post-Consensus Execution in a Casper network",id:"post-consensus-execution-in-a-casper-network",level:4},{value:"Deploy lifecycle",id:"deploy-lifecycle",level:4},{value:"Related reading",id:"related-reading",level:3}];function d(e){const n={a:"a",em:"em",h1:"h1",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"introduction-to-dapps",children:"Introduction to dApps"})}),"\n",(0,s.jsx)(n.h3,{id:"what-is-a-dapp",children:"What is a dApp?"}),"\n",(0,s.jsxs)(n.p,{children:["DApp stands for ",(0,s.jsx)(n.strong,{children:"Decentralized Application"}),". Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface."]}),"\n",(0,s.jsx)(n.p,{children:"A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power."}),"\n",(0,s.jsxs)(n.p,{children:["A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/N#node",children:"nodes"})," does the processing of smart contracts instead of a single central server."]}),"\n",(0,s.jsxs)(n.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/N#node",children:"node"}),". The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,s.jsx)(n.h3,{id:"interacting-with-a-casper-decentralized-network",children:"Interacting with a Casper Decentralized Network"}),"\n",(0,s.jsxs)(n.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/D#deploy",children:"Deploys"})," via the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/json-rpc/",children:"JSON-RPC"}),". Business logic specific to the dApp can then be executed on chain via the Deploy. ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"Sending a Deploy"})," to a node will result in that node ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution."]}),"\n",(0,s.jsxs)(n.p,{children:["A Deploy contains ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/A#account",children:"account"}),". Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly.\nA dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy."]}),"\n",(0,s.jsx)(n.h4,{id:"updating-data-in-a-casper-dapp",children:"Updating data in a Casper dApp"}),"\n",(0,s.jsxs)(n.p,{children:["Sending a Deploy is the only means by which a dApp can change ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/G#global-state",children:"global state"}),". All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."]}),"\n",(0,s.jsx)(n.h4,{id:"post-consensus-execution-in-a-casper-network",children:"Post-Consensus Execution in a Casper network"}),"\n",(0,s.jsxs)(n.p,{children:["Unlike other blockchain networks, a Casper network performs execution ",(0,s.jsx)(n.em,{children:(0,s.jsx)(n.strong,{children:"after"})})," ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#consensus",children:"consensus"}),". This means that observing the execution of the Deploy is sufficient proof of ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/B#block-finality",children:"finality"})," for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy."]}),"\n",(0,s.jsx)(n.h4,{id:"deploy-lifecycle",children:"Deploy lifecycle"}),"\n",(0,s.jsxs)(n.p,{children:["There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/design/casper-design#execution-semantics-head",children:"Deploy Lifecycle"})," results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase."]}),"\n",(0,s.jsx)(n.h3,{id:"related-reading",children:"Related reading"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/deploy-and-deploy-lifecycle",children:"Deploys and the Deploy lifecycle"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Global State"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Session Code"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef2abd7e.e1b228a5.js b/assets/js/ef2abd7e.e1b228a5.js deleted file mode 100644 index e21cee604..000000000 --- a/assets/js/ef2abd7e.e1b228a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[715],{798:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>c,toc:()=>l});var s=t(74848),a=t(28453);const o={title:"dApps"},i="Introduction to dApps",c={id:"concepts/intro-to-dapps",title:"dApps",description:"What is a dApp?",source:"@site/versioned_docs/version-1.5.X/concepts/intro-to-dapps.md",sourceDirName:"concepts",slug:"/concepts/intro-to-dapps",permalink:"/concepts/intro-to-dapps",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"dApps"},sidebar:"concepts",previous:{title:"What is Casper?",permalink:"/"},next:{title:"Accounts and Keys",permalink:"/concepts/accounts-and-keys"}},r={},l=[{value:"What is a dApp?",id:"what-is-a-dapp",level:3},{value:"Interacting with a Casper Decentralized Network",id:"interacting-with-a-casper-decentralized-network",level:3},{value:"Updating data in a Casper dApp",id:"updating-data-in-a-casper-dapp",level:4},{value:"Post-Consensus Execution in a Casper network",id:"post-consensus-execution-in-a-casper-network",level:4},{value:"Deploy lifecycle",id:"deploy-lifecycle",level:4},{value:"Related reading",id:"related-reading",level:3}];function d(e){const n={a:"a",em:"em",h1:"h1",h3:"h3",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"introduction-to-dapps",children:"Introduction to dApps"})}),"\n",(0,s.jsx)(n.h3,{id:"what-is-a-dapp",children:"What is a dApp?"}),"\n",(0,s.jsxs)(n.p,{children:["DApp stands for ",(0,s.jsx)(n.strong,{children:"Decentralized Application"}),". Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface."]}),"\n",(0,s.jsx)(n.p,{children:"A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power."}),"\n",(0,s.jsxs)(n.p,{children:["A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of ",(0,s.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"nodes"})," does the processing of smart contracts instead of a single central server."]}),"\n",(0,s.jsxs)(n.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/N#node",children:"node"}),". The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,s.jsx)(n.h3,{id:"interacting-with-a-casper-decentralized-network",children:"Interacting with a Casper Decentralized Network"}),"\n",(0,s.jsxs)(n.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,s.jsx)(n.a,{href:"/concepts/glossary/D#deploy",children:"Deploys"})," via the ",(0,s.jsx)(n.a,{href:"/developers/json-rpc/",children:"JSON-RPC"}),". Business logic specific to the dApp can then be executed on chain via the Deploy. ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"Sending a Deploy"})," to a node will result in that node ",(0,s.jsx)(n.a,{href:"/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution."]}),"\n",(0,s.jsxs)(n.p,{children:["A Deploy contains ",(0,s.jsx)(n.a,{href:"/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,s.jsx)(n.a,{href:"/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending ",(0,s.jsx)(n.a,{href:"/concepts/glossary/A#account",children:"account"}),". Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly.\nA dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy."]}),"\n",(0,s.jsx)(n.h4,{id:"updating-data-in-a-casper-dapp",children:"Updating data in a Casper dApp"}),"\n",(0,s.jsxs)(n.p,{children:["Sending a Deploy is the only means by which a dApp can change ",(0,s.jsx)(n.a,{href:"/concepts/glossary/G#global-state",children:"global state"}),". All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."]}),"\n",(0,s.jsx)(n.h4,{id:"post-consensus-execution-in-a-casper-network",children:"Post-Consensus Execution in a Casper network"}),"\n",(0,s.jsxs)(n.p,{children:["Unlike other blockchain networks, a Casper network performs execution ",(0,s.jsx)(n.em,{children:(0,s.jsx)(n.strong,{children:"after"})})," ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#consensus",children:"consensus"}),". This means that observing the execution of the Deploy is sufficient proof of ",(0,s.jsx)(n.a,{href:"/concepts/glossary/B#block-finality",children:"finality"})," for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy."]}),"\n",(0,s.jsx)(n.h4,{id:"deploy-lifecycle",children:"Deploy lifecycle"}),"\n",(0,s.jsxs)(n.p,{children:["There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-head",children:"Deploy Lifecycle"})," results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase."]}),"\n",(0,s.jsx)(n.h3,{id:"related-reading",children:"Related reading"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/deploy-and-deploy-lifecycle",children:"Deploys and the Deploy lifecycle"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/concepts/smart-contracts",children:"Smart Contracts"})}),"\n",(0,s.jsx)(n.li,{children:(0,s.jsx)(n.a,{href:"/developers/writing-onchain-code/contract-vs-session#what-is-session-code",children:"Session Code"})}),"\n"]})]})}function p(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>i,x:()=>c});var s=t(96540);const a={},o=s.createContext(a);function i(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:i(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef646837.20fafc7e.js b/assets/js/ef646837.20fafc7e.js new file mode 100644 index 000000000..268c88c47 --- /dev/null +++ b/assets/js/ef646837.20fafc7e.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8456],{25359:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>p,frontMatter:()=>s,metadata:()=>a,toc:()=>d});var t=r(74848),o=r(28453);const s={},c="Documentation Updates by Protocol Release",a={id:"resources/changelog",title:"Documentation Updates by Protocol Release",description:"Condor (2.0)",source:"@site/versioned_docs/version-2.0.0/resources/changelog.md",sourceDirName:"resources",slug:"/resources/changelog",permalink:"/2.0.0/resources/changelog",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{}},i={},d=[{value:"Condor (2.0)",id:"condor-20",level:2},{value:"Concepts",id:"concepts",level:3},{value:"Developers",id:"developers",level:3},{value:"Operators",id:"operators",level:3}];function l(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"documentation-updates-by-protocol-release",children:"Documentation Updates by Protocol Release"})}),"\n",(0,t.jsx)(n.h2,{id:"condor-20",children:"Condor (2.0)"}),"\n",(0,t.jsx)(n.h3,{id:"concepts",children:"Concepts"}),"\n",(0,t.jsx)(n.p,{children:"The following are changes introduced alongside release of the Condor network upgrade."}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/key-types",children:"Understanding Key Types"})," - Additional Key Types and document restructuring."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization Standard"})," - Serialization information for new types."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/concepts/smart-contracts",children:"Smart Contracts"})," - Information on the new factory pattern feature for smart contracts."]}),"\n",(0,t.jsx)(n.h3,{id:"developers",children:"Developers"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Building dApps -> Monitoring and Consuming Events"})," - Information related to contract-level events."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational",children:"Casper JSON-RPC API -> Informational JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-transactional",children:"Casper JSON-RPC API -> Transactional JSON-RPC Methods"})," - New RPC methods."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/types_chain",children:"Casper JSON-RPC API -> Types"})," - New parameters used by the JSON-RPC API."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/emitting-contract-events",children:"Writing On-Chain Code -> Contract-Level Events"})," - Guide to the new contract-level events feature."]}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/developers/writing-onchain-code/factory-pattern",children:"Writing On-Chain Code -> Factory Contracts"})," - Guide to the new factory pattern for smart contracts."]}),"\n",(0,t.jsx)(n.h3,{id:"operators",children:"Operators"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"Private Network -> The Chainspec"})," - Updates to the ",(0,t.jsx)(n.code,{children:"chainpsec"})," relating to contract-level events."]})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,r)=>{r.d(n,{R:()=>c,x:()=>a});var t=r(96540);const o={},s=t.createContext(o);function c(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef726b40.2fca8d33.js b/assets/js/ef726b40.2fca8d33.js new file mode 100644 index 000000000..1280467f9 --- /dev/null +++ b/assets/js/ef726b40.2fca8d33.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4125],{59544:(e,a,n)=>{n.r(a),n.d(a,{assets:()=>l,contentTitle:()=>s,default:()=>h,frontMatter:()=>t,metadata:()=>o,toc:()=>c});var i=n(74848),r=n(28453);const t={title:"Rewards Design"},s="Network Participation Rewards",o={id:"concepts/design/rewards",title:"Rewards Design",description:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.",source:"@site/versioned_docs/version-2.0.0/concepts/design/rewards.md",sourceDirName:"concepts/design",slug:"/concepts/design/rewards",permalink:"/2.0.0/concepts/design/rewards",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Rewards Design"},sidebar:"concepts",previous:{title:"Highway Consensus",permalink:"/2.0.0/concepts/design/highway"},next:{title:"Reading and Writing Data",permalink:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain"}},l={},c=[{value:"Calculating Rewards",id:"calculating-rewards",level:2},{value:"Chainspec settings for calculating rewards",id:"chainspec-settings-for-calculating-rewards",level:3},{value:"Rewards distribution summary",id:"rewards-distribution-summary",level:3}];function d(e){const a={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(a.header,{children:(0,i.jsx)(a.h1,{id:"network-participation-rewards",children:"Network Participation Rewards"})}),"\n",(0,i.jsx)(a.p,{children:"Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP. "}),"\n",(0,i.jsx)(a.p,{children:"Like other Proof-of-Stake chains, a Casper network rewards validators for participating in building a linear chain of blocks, each containing ordered state changes and ensuring that the entire ecosystem of validators, builders, and users eventually achieve common knowledge of the chain's history. External, non-validator participants in the ecosystem can thus have a high degree of confidence on the canonical history of the blockchain's state, thus making the blockchain economically useful."}),"\n",(0,i.jsxs)(a.p,{children:["The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both ",(0,i.jsx)(a.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," and ",(0,i.jsx)(a.a,{href:"/2.0.0/concepts/design/highway",children:"Highway"}),". The current reward scheme has the following properties:"]}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"Rewards are proportional to a validator's weight on average."}),"\n",(0,i.jsx)(a.li,{children:"The reward scheme incentivizes cooperation."}),"\n",(0,i.jsx)(a.li,{children:"Rewards are distributed at the end of an era for all blocks in that era and several eligible blocks from the previous era."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations depend only on the linear structure of the blockchain and published finality signatures, rather than any internal details of the consensus protocol."}),"\n",(0,i.jsx)(a.li,{children:"Reward calculations assume a known constant token supply inflation with nominal platform operation."}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"Previously, with Highway, the reward scheme incentivized block production and participation in their finalization. Unfortunately, this scheme was highly coupled with the consensus protocol and unsuitable for adaptation with the Zug consensus. The current scheme calculates rewards after blocks have been finalized, as described below."}),"\n",(0,i.jsx)(a.h2,{id:"calculating-rewards",children:"Calculating Rewards"}),"\n",(0,i.jsx)(a.p,{children:'The execution engine calculates rewards for block production and finality signature generation and distribution in each switch block. Finality signatures are produced after a block has been finalized by consensus. Thus, rewards are independent of the consensus algorithm used. Block proposers collect those finality signatures and include them in future blocks. The rewards scheme allows blocks to cite finality signatures for several past blocks so that validators can agree on which finality signatures have been produced and should be rewarded. This mechanism to "look back" is necessary because signatures cannot be distributed instantly.'}),"\n",(0,i.jsx)(a.p,{children:"Rewards are divided into these categories:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Block rewards"}),": These rewards are received for each proposed block that is finalized. They incentivize timely participation in building the chain."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.strong,{children:"Finality signature rewards"}),": These rewards are received for collecting finality signatures for each block and generating a finality signature to sign a block. They incentivize the creation, propagation and publication of finality signatures, which is critical in establishing common knowledge of the canonical chain."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:"In each round, a total reward pool is shared among all participating validators proportionally to their weight, as long as all validators fully participate in the processes that are rewarded by this mechanism. These processes are block creation, signature creation, signature propagation and signature publication as part of block proposals."}),"\n",(0,i.jsxs)(a.p,{children:["The ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," setting in the chainspec determines the total reward pool for a block. This value, along with the current total supply and minimum round length, is used to compute the full allocation of rewards for a particular block. The rate itself is set to result in a target annual inflation, provided validators fully participate in the rewardable processes described above."]}),"\n",(0,i.jsxs)(a.p,{children:['Each switch block triggers a reward calculation. To account for potential network lag delaying the timely arrival of signatures for finalized blocks, the calculation "looks back" into previous eras. In particular, this enables rewards for switch blocks, which was impossible with the prior Highway-specific calculation. The number of prior blocks to look up is specified using the ',(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," setting in the chainspec."]}),"\n",(0,i.jsxs)(a.p,{children:["Blocks carry information on their proposer and the finality signatures collected for several past blocks, the depth being determined by the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter. Global state contains data on token supply and validator weights as part of the Mint and Auction states. Based on these inputs, the rewards are calculated according to a formula. Rewards are designed to be proportional to weight on average, as long as blocks are created and the finality signatures are propagated and published in a timely manner. "]}),"\n",(0,i.jsx)(a.p,{children:"Validators are motivated to produce, propagate and publish (i.e., include in the block body) finality signatures as quickly as possible. If they do not include a finality signature in a block, the next validator can include it in their block and get the collection fee."}),"\n",(0,i.jsx)(a.h3,{id:"chainspec-settings-for-calculating-rewards",children:"Chainspec settings for calculating rewards"}),"\n",(0,i.jsx)(a.p,{children:"Each Casper network chainspec contains 4 settings related to calculating rewards:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finality_signature_proportion"}),": The proportion of baseline rewards going to reward finality signatures, rather than block proposal rewards."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"finders_fee"}),": The proportion of the rewards allocated to finality signatures that are due for signature publication in a block proposal."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"}),": The number of prior blocks to include for the reward calculation."]}),"\n",(0,i.jsxs)(a.li,{children:[(0,i.jsx)(a.code,{children:"round_seigniorage_rate"}),": Setting that calculates the fraction of the total supply that will constitute the reward pool for every round."]}),"\n"]}),"\n",(0,i.jsxs)(a.details,{children:["\n",(0,i.jsx)(a.summary,{children:(0,i.jsx)(a.b,{children:"Expand to see sample values"})}),"\n",(0,i.jsx)(a.pre,{children:(0,i.jsx)(a.code,{className:"language-json",children:"# The split in finality signature rewards between block producer and participating signers.\nfinders_fee = [1, 5]\n# The proportion of baseline rewards going to reward finality signatures specifically.\nfinality_signature_proportion = [1, 2]\n# Lookback interval indicating which past block we are looking at to reward.\nsignature_rewards_max_delay = 3\n...\n# Round seigniorage rate represented as a fraction of the total supply.\n#\n# Annual issuance: 8%\n# Minimum block time: 2^14 milliseconds\n# Ticks per year: 31536000000\n#\n# (1+0.08)^((2^14)/31536000000)-1 is expressed as a fractional number below\n# Python:\n# from fractions import Fraction\n# Fraction((1 + 0.08)**((2**14)/31536000000) - 1).limit_denominator(1000000000)\nround_seigniorage_rate = [7, 175070816]\n"})}),"\n"]}),"\n",(0,i.jsx)(a.h3,{id:"rewards-distribution-summary",children:"Rewards distribution summary"}),"\n",(0,i.jsx)(a.p,{children:"The following steps summarize the rewards distribution mechanism."}),"\n",(0,i.jsxs)(a.p,{children:["Each round has a reward pool calculated from the ",(0,i.jsx)(a.code,{children:"round_seigniorage_rate"})," chainspec parameter and the current total supply for the relevant era."]}),"\n",(0,i.jsxs)(a.p,{children:["In each round, the reward pool is split into two parts for block proposals and finality signature rewards, based on the ",(0,i.jsx)(a.code,{children:"finality_signature_proportion"})," chainspec parameter."]}),"\n",(0,i.jsxs)(a.p,{children:["The amount allocated for finality signatures is split further into two parts: creating and publishing finality signatures. The split is configurable in the chainspec using the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter."]}),"\n",(0,i.jsx)(a.p,{children:"For each finality signature:"}),"\n",(0,i.jsxs)(a.ul,{children:["\n",(0,i.jsx)(a.li,{children:"The creator gets a portion of what was allocated for creating signatures, in proportion to relative consensus weight."}),"\n",(0,i.jsxs)(a.li,{children:["The block proposer gets a portion corresponding to the ",(0,i.jsx)(a.code,{children:"finders_fee"})," chainspec parameter, scaled by the total collected signature creator weight divided by the total weight in the relevant era."]}),"\n"]}),"\n",(0,i.jsx)(a.p,{children:(0,i.jsx)(a.img,{alt:"Rewards Pot",src:n(86017).A+"",width:"747",height:"743"})}),"\n",(0,i.jsxs)(a.p,{children:["The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the ",(0,i.jsx)(a.code,{children:"signature_rewards_max_delay"})," parameter, to compensate for the delay in creating and distributing finality signatures."]})]})}function h(e={}){const{wrapper:a}={...(0,r.R)(),...e.components};return a?(0,i.jsx)(a,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},86017:(e,a,n)=>{n.d(a,{A:()=>i});const i=n.p+"assets/images/rewards-pot-abc6a18cf2901d137d80907cdedd6d8f.png"},28453:(e,a,n)=>{n.d(a,{R:()=>s,x:()=>o});var i=n(96540);const r={},t=i.createContext(r);function s(e){const a=i.useContext(t);return i.useMemo((function(){return"function"==typeof e?e(a):{...a,...e}}),[a,e])}function o(e){let a;return a=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(t.Provider,{value:a},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef7672e3.34f0b8af.js b/assets/js/ef7672e3.34f0b8af.js new file mode 100644 index 000000000..38e292959 --- /dev/null +++ b/assets/js/ef7672e3.34f0b8af.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67110],{63457:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=s(74848),c=s(28453);const t={title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},o="CEP-18 Token Transfers and Allowances",r={id:"resources/tokens/cep18/transfer",title:"CEP-18 Transfers",description:"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/transfer.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/transfer",permalink:"/1.5.X/resources/tokens/cep18/transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},sidebar:"resources",previous:{title:"CEP-18 Contract Details",permalink:"/1.5.X/resources/tokens/cep18/query"},next:{title:"Testing Guide",permalink:"/1.5.X/resources/tokens/cep18/tests"}},i={},d=[{value:"Transferring CEP-18 Tokens to Another Account",id:"transferring-cep-18-tokens-to-another-account",level:2},{value:"Invoking the <code>check_balance_of</code> Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}];function h(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cep-18-token-transfers-and-allowances",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,a.jsxs)(n.p,{children:["This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,a.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."]}),"\n",(0,a.jsx)(n.h2,{id:"transferring-cep-18-tokens-to-another-account",children:"Transferring CEP-18 Tokens to Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The following command will invoke the ",(0,a.jsx)(n.code,{children:"transfer"})," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name <CHAIN NAME>\\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n--chain-name <CHAIN NAME>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,a.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the utility contract to verify the account's balance."]}),"\n",(0,a.jsxs)(n.h3,{id:"invoking-the-check_balance_of-entry-point",children:["Invoking the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," Entry Point"]}),"\n",(0,a.jsxs)(n.p,{children:["The following Casper client command invokes the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the ",(0,a.jsx)(n.code,{children:"cep18_test_contract"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["After sending this command, you will need to query the ",(0,a.jsx)(n.code,{children:"results"})," URef within the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," of your ",(0,a.jsx)(n.code,{children:"cep18_test_contract"})," utility contract instance. More information on finding this URef can be found in the ",(0,a.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/query#querying-the-utility-contract",children:"Exploring the CEP18 Contracts"})," document."]}),"\n",(0,a.jsxs)(n.p,{children:["You can use the following command to query global state for the ",(0,a.jsx)(n.code,{children:"results"})," URef."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command should show something similar to the following in response, with ",(0,a.jsx)(n.code,{children:"parsed"})," being the amount of CEP-18 tokens that the account holds."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approving-an-allowance-for-another-account",children:"Approving an Allowance for Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The Casper fungible token contract features an ",(0,a.jsx)(n.code,{children:"allowance"})," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."]}),"\n",(0,a.jsx)(n.h3,{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",children:"Approving an Account to Spend Tokens on Another Account's Behalf"}),"\n",(0,a.jsxs)(n.p,{children:["The following command approves a third-party account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"verifying-a-previously-issued-allowance",children:"Verifying a Previously Issued Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["After approving an account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,a.jsx)(n.code,{children:"allowance"})," of the spender's account to the ",(0,a.jsx)(n.code,{children:"result"})," URef of in the utility contract's ",(0,a.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following command queries global state to return the value stored under the ",(0,a.jsx)(n.code,{children:"result"})," URef:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You should get a response similar to the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"transferring-tokens-from-an-allowance",children:"Transferring Tokens from an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,a.jsx)(n.code,{children:"allowance"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"increasing-and-decreasing-an-allowance",children:"Increasing and Decreasing an Allowance"}),"\n",(0,a.jsx)(n.h4,{id:"increasing-an-allowance",children:"Increasing an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command increases the designated ",(0,a.jsx)(n.code,{children:"allowance"})," for the provided account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"decreasing-an-allowance",children:"Decreasing an Allowance"}),"\n",(0,a.jsx)(n.p,{children:"The following command decreases the designated allowance for the provided account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"minting-and-burning-additional-cep-18-tokens",children:"Minting and Burning Additional CEP-18 Tokens"}),"\n",(0,a.jsx)(n.h4,{id:"minting-additional-tokens",children:"Minting Additional Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"burning-tokens",children:"Burning Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"changing-account-security-permissions",children:"Changing Account Security Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"change_security"})," entrypoint can be used by an account with ",(0,a.jsx)(n.code,{children:"admin"})," access to alter the security level of other accounts."]}),"\n",(0,a.jsx)(n.p,{children:"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"None"})," - ",(0,a.jsx)(n.code,{children:"None"})," overrides other security levels and removes all admin, minting and burning access of an account."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Admin"})," - Allows the account full access and control over the CEP-18 contract."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"MintAndBurn"})," - Allows the account to mint new tokens and burn existing tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Burner"})," - The account can burn tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Minter"})," - The account can mint new tokens."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Here is an example of a ",(0,a.jsx)(n.code,{children:"session-arg"})," that provides a list of account hashes to be included on the ",(0,a.jsx)(n.code,{children:"mint_and_burn_list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Be aware that removing all admin accounts will lock out all admin functionality."})}),"\n",(0,a.jsx)(n.p,{children:"The following command can be supplied with any of the optional arguments above:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'<List of account hashes>\'" \\\n--session-arg "admin_list:string:\'<List of account hashes>\'" \\\n--session-arg "mint_and_burn_list:string:\'<List of account hashes>\'" \\\n--session-arg "burner_list:string:\'<List of account hashes>\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsx)(n.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var a=s(96540);const c={},t=a.createContext(c);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ef7672e3.d080a329.js b/assets/js/ef7672e3.d080a329.js deleted file mode 100644 index 8fbe12952..000000000 --- a/assets/js/ef7672e3.d080a329.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7110],{63457:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>i,contentTitle:()=>o,default:()=>l,frontMatter:()=>t,metadata:()=>r,toc:()=>d});var a=s(74848),c=s(28453);const t={title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},o="CEP-18 Token Transfers and Allowances",r={id:"resources/tokens/cep18/transfer",title:"CEP-18 Transfers",description:"This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/transfer.md",sourceDirName:"resources/tokens/cep18",slug:"/resources/tokens/cep18/transfer",permalink:"/resources/tokens/cep18/transfer",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"CEP-18 Transfers",slug:"/resources/tokens/cep18/transfer"},sidebar:"resources",previous:{title:"CEP-18 Contract Details",permalink:"/resources/tokens/cep18/query"},next:{title:"Testing Guide",permalink:"/resources/tokens/cep18/tests"}},i={},d=[{value:"Transferring CEP-18 Tokens to Another Account",id:"transferring-cep-18-tokens-to-another-account",level:2},{value:"Invoking the <code>check_balance_of</code> Entry Point",id:"invoking-the-check_balance_of-entry-point",level:3},{value:"Approving an Allowance for Another Account",id:"approving-an-allowance-for-another-account",level:2},{value:"Approving an Account to Spend Tokens on Another Account's Behalf",id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",level:3},{value:"Verifying a Previously Issued Allowance",id:"verifying-a-previously-issued-allowance",level:3},{value:"Transferring Tokens from an Allowance",id:"transferring-tokens-from-an-allowance",level:3},{value:"Increasing and Decreasing an Allowance",id:"increasing-and-decreasing-an-allowance",level:3},{value:"Increasing an Allowance",id:"increasing-an-allowance",level:4},{value:"Decreasing an Allowance",id:"decreasing-an-allowance",level:4},{value:"Minting and Burning Additional CEP-18 Tokens",id:"minting-and-burning-additional-cep-18-tokens",level:3},{value:"Minting Additional Tokens",id:"minting-additional-tokens",level:4},{value:"Burning Tokens",id:"burning-tokens",level:4},{value:"Changing Account Security Permissions",id:"changing-account-security-permissions",level:3},{value:"Next Steps",id:"next-steps",level:3}];function h(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,c.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"cep-18-token-transfers-and-allowances",children:"CEP-18 Token Transfers and Allowances"})}),"\n",(0,a.jsxs)(n.p,{children:["This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The ",(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/query",children:"Exploring the CEP18 Contracts"})," documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document."]}),"\n",(0,a.jsx)(n.h2,{id:"transferring-cep-18-tokens-to-another-account",children:"Transferring CEP-18 Tokens to Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The following command will invoke the ",(0,a.jsx)(n.code,{children:"transfer"})," entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n// The chain name of the Casper network on which your CEP-18 instance was installed.\n--chain-name <CHAIN NAME>\\\n// The local path to your account\'s secret key.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// The contract hash of your CEP-18 contract instance.\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n// The name of the entry point you are invoking.\n--session-entry-point "transfer" \\\n// The account hash of the account that you are sending CEP-18 tokens to.\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n// The amount of CEP-18 tokens you are sending to the receiving account.\n--session-arg "amount:u256=\'10\'" \\\n// The gas payment you are allotting, in motes.\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT> \\\n--chain-name <CHAIN NAME>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180 \\\n--session-entry-point "transfer" \\\n--session-arg "recipient:key=\'account-hash-9f81014b9c7406c531ebf0477132283f4eb59143d7903a2fae54358b26cea44b" \\\n--session-arg "amount:u256=\'50\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command will return a deploy hash that you can query using ",(0,a.jsx)(n.code,{children:"casper-client get-deploy"}),". Querying the Deploy allows you to verify execution success, but you will need to use the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the utility contract to verify the account's balance."]}),"\n",(0,a.jsxs)(n.h3,{id:"invoking-the-check_balance_of-entry-point",children:["Invoking the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," Entry Point"]}),"\n",(0,a.jsxs)(n.p,{children:["The following Casper client command invokes the ",(0,a.jsx)(n.code,{children:"check_balance_of"})," entry point on the ",(0,a.jsx)(n.code,{children:"cep18_test_contract"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n// This is the contract hash of your CEP-18 contract instance, passed in as an `account-hash-`.\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n// This is the account hash of the account you are checking the balance of.\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_balance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n--session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["After sending this command, you will need to query the ",(0,a.jsx)(n.code,{children:"results"})," URef within the ",(0,a.jsx)(n.code,{children:"NamedKeys"})," of your ",(0,a.jsx)(n.code,{children:"cep18_test_contract"})," utility contract instance. More information on finding this URef can be found in the ",(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/query#querying-the-utility-contract",children:"Exploring the CEP18 Contracts"})," document."]}),"\n",(0,a.jsxs)(n.p,{children:["You can use the following command to query global state for the ",(0,a.jsx)(n.code,{children:"results"})," URef."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n// This is the `results` URef location from your `cep18_test_contract` `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<NODE IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash 3aecd0e4b6ec29ee7c1eed701132eabfe6e66a1e0f1595c9c65bfed447e474f7\n"})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["This command should show something similar to the following in response, with ",(0,a.jsx)(n.code,{children:"parsed"})," being the amount of CEP-18 tokens that the account holds."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -8841145064950441692,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010a",\n "cl_type": "U256",\n "parsed": "10"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h2,{id:"approving-an-allowance-for-another-account",children:"Approving an Allowance for Another Account"}),"\n",(0,a.jsxs)(n.p,{children:["The Casper fungible token contract features an ",(0,a.jsx)(n.code,{children:"allowance"})," entry point that allows an account to delegate another account to spend a preset number of CEP-18 tokens from their balance."]}),"\n",(0,a.jsx)(n.h3,{id:"approving-an-account-to-spend-tokens-on-another-accounts-behalf",children:"Approving an Account to Spend Tokens on Another Account's Behalf"}),"\n",(0,a.jsxs)(n.p,{children:["The following command approves a third-party account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of 15 CEP-18 tokens from the balance of the account that sent the CEP-18 instance."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the contract hash of the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n// This is the account hash of the account that will receive an allowance from the balance of the account that sent the Deploy.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the number of CEP-18 tokens included in the allowance.\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "approve" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'15\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"verifying-a-previously-issued-allowance",children:"Verifying a Previously Issued Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["After approving an account to spend an ",(0,a.jsx)(n.code,{children:"allowance"})," of tokens, we can verify the allotted allowance by using the utility contract. The following command will write the ",(0,a.jsx)(n.code,{children:"allowance"})," of the spender's account to the ",(0,a.jsx)(n.code,{children:"result"})," URef of in the utility contract's ",(0,a.jsx)(n.code,{children:"NamedKeys"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n// This is the contract hash for the CEP-18 token.\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n// This is the account hash for the account that owns the CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash for the account previously authorized to spend an allowance of the owning account\'s CEP-18 tokens.\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<node IP>:<PORT>\\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_test_contract" \\\n--session-entry-point "check_allowance_of" \\\n--session-arg "token_contract:account_hash=\'account-hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e\'" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "spender:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 10000000000\n'})}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["The following command queries global state to return the value stored under the ",(0,a.jsx)(n.code,{children:"result"})," URef:"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n// This is the previously identified `result` URef from the utility contract's `NamedKeys`\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state -n http://<node IP>:<PORT> \\\n--key uref-a46ad389b53715d9991a513c8ca48e1502facc4c563c0700a31e830c4cb8a7d4-007 \\\n--state-root-hash e64f877f65df26db74300bb175c244d589bd88a23b91abf9ceb73ac5e65e90f1\n"})}),"\n"]}),"\n",(0,a.jsx)(n.p,{children:"You should get a response similar to the following:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'{\n "id": -9142472925449984061,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "block_header": null,\n "merkle_proof": "[3796 hex chars]",\n "stored_value": {\n "CLValue": {\n "bytes": "010f",\n "cl_type": "U256",\n "parsed": "15"\n }\n }\n }\n}\n'})}),"\n",(0,a.jsx)(n.h3,{id:"transferring-tokens-from-an-allowance",children:"Transferring Tokens from an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command allows an account to transfer CEP-18 tokens held by another account up to their approved ",(0,a.jsx)(n.code,{children:"allowance"}),"."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n// This is the secret key for the account that is spending their `allowance` from another account\'s balance.\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n// This is the CEP-18 token contract.\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n// This is the account hash of the account that holds the CEP-18 in their balance.\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n// This is the account hash of the account that will receive the transferred CEP-18 tokens.\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n// This is the amount of tokens to be transferred. If this amount exceeds the `allowance` of the account sending the Deploy, it will fail.\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--chain-name <CHAIN NAME> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-hash hash-05d893e76c731729fc26339e5a970bd79fbf4a6adf743c8385431fb494bff45e \\\n--session-entry-point "transfer_from" \\\n--session-arg "owner:key=\'account-hash-39f15c23df9be1244572bb499fac62cbcad3cab2dc1438609842f602f943d7d2\'" \\\n--session-arg "recipient:key=\'account-hash-17192017d32db5dc9f598bf8ac6ac35ee4b64748669b00572d88335941479513\'" \\\n--session-arg "amount:u256=\'10\'" \\\n--payment-amount "10000000000"\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"increasing-and-decreasing-an-allowance",children:"Increasing and Decreasing an Allowance"}),"\n",(0,a.jsx)(n.h4,{id:"increasing-an-allowance",children:"Increasing an Allowance"}),"\n",(0,a.jsxs)(n.p,{children:["The following command increases the designated ",(0,a.jsx)(n.code,{children:"allowance"})," for the provided account."]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "increase_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"decreasing-an-allowance",children:"Decreasing an Allowance"}),"\n",(0,a.jsx)(n.p,{children:"The following command decreases the designated allowance for the provided account."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n// This is the account hash of the previously authorized allowance account.\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the additional number of CEP-18 tokens that the authorized account may spend.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "decrease_allowance" \\\n--session-arg "spender:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"minting-and-burning-additional-cep-18-tokens",children:"Minting and Burning Additional CEP-18 Tokens"}),"\n",(0,a.jsx)(n.h4,{id:"minting-additional-tokens",children:"Minting Additional Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for minting, the following command will mint a number of CEP-18 tokens directly to the provided account. This increases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n// This is the account that will receive the newly minted CEP-18 tokens.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of additional CEP-18 tokens to add to the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "mint" \\\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h4,{id:"burning-tokens",children:"Burning Tokens"}),"\n",(0,a.jsx)(n.p,{children:"If the contract allows for burning, the following command will burn a number of CEP-18 tokens directly from the provided account. This decreases the total supply of the token in question."}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper client command without comments"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "burn" \\\n// This is the account that the tokens will be burned from.\n--session-arg "owner:key=\'account-hash-683f53f56926f54ef9584b07585b025c68415dc05f7b2e56749153574b83d5cd\'" \\\n// This is the number of CEP-18 tokens to remove from the total supply.\n--session-arg "amount:U256=\'10\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"changing-account-security-permissions",children:"Changing Account Security Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["The ",(0,a.jsx)(n.code,{children:"change_security"})," entrypoint can be used by an account with ",(0,a.jsx)(n.code,{children:"admin"})," access to alter the security level of other accounts."]}),"\n",(0,a.jsx)(n.p,{children:"There are five security levels, with the strongest level taking precedence over any other assigned levels. In order of highest strength to lowest:"}),"\n",(0,a.jsxs)(n.ol,{children:["\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"None"})," - ",(0,a.jsx)(n.code,{children:"None"})," overrides other security levels and removes all admin, minting and burning access of an account."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Admin"})," - Allows the account full access and control over the CEP-18 contract."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"MintAndBurn"})," - Allows the account to mint new tokens and burn existing tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Burner"})," - The account can burn tokens."]}),"\n"]}),"\n",(0,a.jsxs)(n.li,{children:["\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"Minter"})," - The account can mint new tokens."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["Here is an example of a ",(0,a.jsx)(n.code,{children:"session-arg"})," that provides a list of account hashes to be included on the ",(0,a.jsx)(n.code,{children:"mint_and_burn_list"}),":"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:"--session-arg \"mint_and_burn_list:string='account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7,account-hash-0ea7998b2822afe5b62b08a21d54c941ad791279b089f3f7ede0d72b477eca34,account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655'\"\n"})}),"\n",(0,a.jsx)(n.p,{children:(0,a.jsx)(n.strong,{children:"Be aware that removing all admin accounts will lock out all admin functionality."})}),"\n",(0,a.jsx)(n.p,{children:"The following command can be supplied with any of the optional arguments above:"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy -n http://<NODE IP>:<PORT> \\\n--secret-key ~/casper/demo/user_a/secret_key.pem \\\n--session-package-name "cep18_contract_package_CEP18" \\\n--session-entry-point "change_security" \\\n/// The following arguments are all optional and each consists of a string of the account hashes to be added to the list specified, separated by commas.\n--session-arg "none_list:string:\'<List of account hashes>\'" \\\n--session-arg "admin_list:string:\'<List of account hashes>\'" \\\n--session-arg "mint_and_burn_list:string:\'<List of account hashes>\'" \\\n--session-arg "burner_list:string:\'<List of account hashes>\'" \\\n--chain-name <CHAIN NAME> \\\n--payment-amount 1000000000\n'})}),"\n",(0,a.jsx)(n.h3,{id:"next-steps",children:"Next Steps"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"/resources/tokens/cep18/tests",children:"Testing Framework for CEP-18"})}),"\n"]})]})}function l(e={}){const{wrapper:n}={...(0,c.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(h,{...e})}):h(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>r});var a=s(96540);const c={},t=a.createContext(c);function o(e){const n=a.useContext(t);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:o(e.components),a.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/efd01d75.02a4a077.js b/assets/js/efd01d75.02a4a077.js new file mode 100644 index 000000000..286cb0570 --- /dev/null +++ b/assets/js/efd01d75.02a4a077.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[72753],{35351:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>i,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var c=r(74848),n=r(28453);const o={},t="K",a={id:"concepts/glossary/K",title:"K",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/K.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/K",permalink:"/2.0.0/concepts/glossary/K",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"J",permalink:"/2.0.0/concepts/glossary/J"},next:{title:"L",permalink:"/2.0.0/concepts/glossary/L"}},l={},h=[{value:"Key",id:"key",level:2}];function d(e){const s={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,n.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(s.header,{children:(0,c.jsx)(s.h1,{id:"k",children:"K"})}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,c.jsx)(s.hr,{}),"\n",(0,c.jsx)(s.h2,{id:"key",children:"Key"}),"\n",(0,c.jsxs)(s.p,{children:[(0,c.jsx)(s.code,{children:"Keys"})," are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found ",(0,c.jsx)(s.a,{href:"/2.0.0/concepts/accounts-and-keys",children:"here"}),"."]})]})}function i(e={}){const{wrapper:s}={...(0,n.R)(),...e.components};return s?(0,c.jsx)(s,{...e,children:(0,c.jsx)(d,{...e})}):d(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var c=r(96540);const n={},o=c.createContext(n);function t(e){const s=c.useContext(o);return c.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(n):e.components||n:t(e.components),c.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eff21157.bd65bcae.js b/assets/js/eff21157.bd65bcae.js deleted file mode 100644 index 59dde238e..000000000 --- a/assets/js/eff21157.bd65bcae.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9080],{33997:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const c={title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},a="Two-Party Multi-Signature Deploys",i={id:"resources/advanced/two-party-multi-sig",title:"Two-Party Multi-Sig",description:"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/two-party-multi-sig.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/two-party-multi-sig",permalink:"/resources/tutorials/advanced/two-party-multi-sig",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},sidebar:"tutorials",previous:{title:"Advanced Tutorials",permalink:"/resources/tutorials/advanced/"},next:{title:"Introduction",permalink:"/resources/advanced/multi-sig/"}},r={},d=[{value:"Configuring the Main Account",id:"configuring-the-main-account",level:2},{value:"Running session code to set up associated keys",id:"running-session-code-to-set-up-associated-keys",level:3},{value:"Confirming Processing and Account Status",id:"confirming-execution-and-account-status",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"two-party-multi-signature-deploys",children:"Two-Party Multi-Signature Deploys"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/concepts/global-state",children:"Accounts"})," on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys."]}),"\n",(0,s.jsx)(n.p,{children:"This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet the ",(0,s.jsx)(n.a,{href:"/developers/prerequisites",children:"prerequisites"}),", including having the Casper command-line client and a valid node address"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the main account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex (",(0,s.jsx)(n.strong,{children:"MA"}),") and another ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex to associate (",(0,s.jsx)(n.strong,{children:"AA"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"sent deploys"})," to a Casper network"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-the-main-account",children:"Configuring the Main Account"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet."})}),"\n",(0,s.jsxs)(n.p,{children:["Each Account has an ",(0,s.jsx)(n.code,{children:"associated_keys"})," field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the ",(0,s.jsx)(n.code,{children:"associated_keys"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the ",(0,s.jsx)(n.code,{children:"action_thresholds"})," for the account."]}),"\n",(0,s.jsx)(n.p,{children:"Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Send a deploy to the network; determined by the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold"]}),"\n",(0,s.jsxs)(n.li,{children:["Edit the ",(0,s.jsx)(n.code,{children:"associated keys"})," and the ",(0,s.jsx)(n.code,{children:"action_thresholds"}),"; determined by the ",(0,s.jsx)(n.code,{children:"key_management"})," threshold"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the ",(0,s.jsx)(n.em,{children:"main key"})," and ",(0,s.jsx)(n.em,{children:"associated key"}),"'s combined weight must be greater than or equal to the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold. This can be achieved by having each key's weight equal to half of the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold."]}),"\n",(0,s.jsx)(n.h3,{id:"running-session-code-to-set-up-associated-keys",children:"Running session code to set up associated keys"}),"\n",(0,s.jsxs)(n.p,{children:["To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"GitHub"}),". Note that this session code is not a general-purpose program and needs to be modified for each use case."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/contract/src/main.rs",children:"session code"})," executes ",(0,s.jsx)(n.strong,{children:"3 crucial steps"})," to enforce the multi-sig scheme for the main account:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Adds an associated key to the account; we will refer to this key as ",(0,s.jsx)(n.strong,{children:"AA"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"action"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", such that the weight required to send a deploy is split equally between the keys associated with the account"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The repository contains a ",(0,s.jsx)(n.em,{children:"Makefile"})," with the build commands necessary to compile the contract and generate the necessary Wasm."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd two-party-multi-sig\nmake build-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The compiled Wasm will be saved on this path: ",(0,s.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper command-line client can be used to send the compiled Wasm to the network for execution."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://<peer-ip-address>:7777 \\\n--secret-key <secret-key-MA>.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path <path-to-contract-wasm> \\\n--session-arg \"deployment-account:account_hash='account-hash-<hash-AA>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the main account"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,s.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-arg"})," - The contract takes the account hash of the associated account as an argument labeled ",(0,s.jsx)(n.code,{children:"deployment-account"}),". You can pass this argument using the ",(0,s.jsx)(n.code,{children:"--session-arg"})," flag in the command line client"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'"result"."deploy_hash"'})," - the address of the executed deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Save the returned ",(0,s.jsx)(n.code,{children:"deploy_hash"})," from the output to query information about execution status."]}),"\n",(0,s.jsx)(n.h3,{id:"confirming-execution-and-account-status",children:"Confirming Processing and Account Status"}),"\n",(0,s.jsxs)(n.p,{children:["Account configuration on a Casper blockchain is stored in a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/M#merkle-tree",children:"Merkle Tree"})," and is a snapshot of the blockchain's ",(0,s.jsx)(n.a,{href:"/concepts/global-state",children:"Global State"}),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," and is stored in every executed block."]}),"\n",(0,s.jsxs)(n.p,{children:["To check that the account was configured correctly, you need the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," corresponding to the block that contains your deploy. To obtain the ",(0,s.jsx)(n.code,{children:"state-root-hash"}),", you need to:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"Confirm the execution status of the deploy"})," and obtain the hash of the block containing it"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-blocks",children:"Query the block containing the deploy"})," to obtain the corresponding ",(0,s.jsx)(n.code,{children:"state_root_hash"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," and the ",(0,s.jsx)(n.code,{children:"hex-encoded-public-key"})," of the main account, query the network and check the account's configuration."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<peer-ip-address>:7777 \\\n--state-root-hash <state-root-hash-from-block> \\\n--key <hex-encoded-public-key-MA>\n"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example output"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In the example output, you can see the account hashes listed within the ",(0,s.jsx)(n.code,{children:"associated_keys"})," section. Each key has weight ",(0,s.jsx)(n.code,{children:"1"}),"; since the action threshold for ",(0,s.jsx)(n.code,{children:"deployment"})," is ",(0,s.jsx)(n.code,{children:"2"}),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},c=s.createContext(o);function a(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/eff21157.d54a2b5c.js b/assets/js/eff21157.d54a2b5c.js new file mode 100644 index 000000000..854e91513 --- /dev/null +++ b/assets/js/eff21157.d54a2b5c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[29080],{33997:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>r,contentTitle:()=>a,default:()=>l,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=t(74848),o=t(28453);const c={title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},a="Two-Party Multi-Signature Deploys",i={id:"resources/advanced/two-party-multi-sig",title:"Two-Party Multi-Sig",description:"Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.",source:"@site/versioned_docs/version-1.5.X/resources/advanced/two-party-multi-sig.md",sourceDirName:"resources/advanced",slug:"/resources/tutorials/advanced/two-party-multi-sig",permalink:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Two-Party Multi-Sig",slug:"/resources/tutorials/advanced/two-party-multi-sig"},sidebar:"tutorials",previous:{title:"Advanced Tutorials",permalink:"/1.5.X/resources/tutorials/advanced/"},next:{title:"Introduction",permalink:"/1.5.X/resources/advanced/multi-sig/"}},r={},d=[{value:"Configuring the Main Account",id:"configuring-the-main-account",level:2},{value:"Running session code to set up associated keys",id:"running-session-code-to-set-up-associated-keys",level:3},{value:"Confirming Processing and Account Status",id:"confirming-execution-and-account-status",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,o.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"two-party-multi-signature-deploys",children:"Two-Party Multi-Signature Deploys"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Accounts"})," on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys."]}),"\n",(0,s.jsx)(n.p,{children:"This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet the ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"prerequisites"}),", including having the Casper command-line client and a valid node address"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the main account's ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex (",(0,s.jsx)(n.strong,{children:"MA"}),") and another ",(0,s.jsx)(n.code,{children:"PublicKey"})," hex to associate (",(0,s.jsx)(n.strong,{children:"AA"}),")"]}),"\n",(0,s.jsxs)(n.li,{children:["You have previously ",(0,s.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"sent deploys"})," to a Casper network"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"configuring-the-main-account",children:"Configuring the Main Account"}),"\n",(0,s.jsx)(n.admonition,{type:"caution",children:(0,s.jsx)(n.p,{children:"Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet."})}),"\n",(0,s.jsxs)(n.p,{children:["Each Account has an ",(0,s.jsx)(n.code,{children:"associated_keys"})," field, which is a list containing account hashes and their corresponding weights. Accounts can be associated by adding the account hash to the ",(0,s.jsx)(n.code,{children:"associated_keys"})," field."]}),"\n",(0,s.jsxs)(n.p,{children:["An Account on a Casper network assigns weights to keys associated with it. For a single key to sign a deploy, or edit the state of the account, its weight must be greater than or equal to a set threshold. The thresholds are labeled as the ",(0,s.jsx)(n.code,{children:"action_thresholds"})," for the account."]}),"\n",(0,s.jsx)(n.p,{children:"Each account within a Casper network has two action thresholds that manage the permissions to send deploys or manage the account. Each threshold defines the minimum weight that a single key or a combination of keys must have to either:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Send a deploy to the network; determined by the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold"]}),"\n",(0,s.jsxs)(n.li,{children:["Edit the ",(0,s.jsx)(n.code,{children:"associated keys"})," and the ",(0,s.jsx)(n.code,{children:"action_thresholds"}),"; determined by the ",(0,s.jsx)(n.code,{children:"key_management"})," threshold"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["To enforce the multi-signature (multi-sig) feature for an account on a Casper network, the ",(0,s.jsx)(n.em,{children:"main key"})," and ",(0,s.jsx)(n.em,{children:"associated key"}),"'s combined weight must be greater than or equal to the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold. This can be achieved by having each key's weight equal to half of the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold."]}),"\n",(0,s.jsx)(n.h3,{id:"running-session-code-to-set-up-associated-keys",children:"Running session code to set up associated keys"}),"\n",(0,s.jsxs)(n.p,{children:["To set up the associated keys for an Account, you must run session code that executes within the account's context. You will find an example of such session code on ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/",children:"GitHub"}),". Note that this session code is not a general-purpose program and needs to be modified for each use case."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/two-party-multi-sig\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig/blob/main/contract/src/main.rs",children:"session code"})," executes ",(0,s.jsx)(n.strong,{children:"3 crucial steps"})," to enforce the multi-sig scheme for the main account:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["Adds an associated key to the account; we will refer to this key as ",(0,s.jsx)(n.strong,{children:"AA"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"action"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", because action thresholds for deploys cannot be greater than the action threshold for key management. By default, all action thresholds are set to ",(0,s.jsx)(n.code,{children:"1"})]}),"\n",(0,s.jsxs)(n.li,{children:["Raises the ",(0,s.jsx)(n.code,{children:"deployment"})," threshold to ",(0,s.jsx)(n.code,{children:"2"}),", such that the weight required to send a deploy is split equally between the keys associated with the account"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The repository contains a ",(0,s.jsx)(n.em,{children:"Makefile"})," with the build commands necessary to compile the contract and generate the necessary Wasm."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"cd two-party-multi-sig\nmake build-contract\n"})}),"\n",(0,s.jsxs)(n.p,{children:["The compiled Wasm will be saved on this path: ",(0,s.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release/contract.wasm"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"The Casper command-line client can be used to send the compiled Wasm to the network for execution."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://<peer-ip-address>:7777 \\\n--secret-key <secret-key-MA>.pem \\\n--chain-name casper-test \\\n--payment-amount 2500000000 \\\n--session-path <path-to-contract-wasm> \\\n--session-arg \"deployment-account:account_hash='account-hash-<hash-AA>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a node on the network"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the main account"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the deploy (this example uses the Testnet)"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The cost of the deploy. This example uses 2.5 CSPR, which may need to be adjusted based on the network ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the contract Wasm"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-arg"})," - The contract takes the account hash of the associated account as an argument labeled ",(0,s.jsx)(n.code,{children:"deployment-account"}),". You can pass this argument using the ",(0,s.jsx)(n.code,{children:"--session-arg"})," flag in the command line client"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:'"result"."deploy_hash"'})," - the address of the executed deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.strong,{children:"Note"}),": Save the returned ",(0,s.jsx)(n.code,{children:"deploy_hash"})," from the output to query information about execution status."]}),"\n",(0,s.jsx)(n.h3,{id:"confirming-execution-and-account-status",children:"Confirming Processing and Account Status"}),"\n",(0,s.jsxs)(n.p,{children:["Account configuration on a Casper blockchain is stored in a ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/glossary/M#merkle-tree",children:"Merkle Tree"})," and is a snapshot of the blockchain's ",(0,s.jsx)(n.a,{href:"/1.5.X/concepts/global-state",children:"Global State"}),". The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," and is stored in every executed block."]}),"\n",(0,s.jsxs)(n.p,{children:["To check that the account was configured correctly, you need the ",(0,s.jsx)(n.code,{children:"state-root-hash"})," corresponding to the block that contains your deploy. To obtain the ",(0,s.jsx)(n.code,{children:"state-root-hash"}),", you need to:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-deploys",children:"Confirm the execution status of the deploy"})," and obtain the hash of the block containing it"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.a,{href:"/1.5.X/resources/tutorials/beginner/querying-network#querying-blocks",children:"Query the block containing the deploy"})," to obtain the corresponding ",(0,s.jsx)(n.code,{children:"state_root_hash"})]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Using the ",(0,s.jsx)(n.code,{children:"state_root_hash"})," and the ",(0,s.jsx)(n.code,{children:"hex-encoded-public-key"})," of the main account, query the network and check the account's configuration."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client query-global-state \\\n--node-address http://<peer-ip-address>:7777 \\\n--state-root-hash <state-root-hash-from-block> \\\n--key <hex-encoded-public-key-MA>\n"})}),"\n",(0,s.jsxs)(n.details,{children:["\n",(0,s.jsx)(n.summary,{children:"Example output"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'{\n "id": 1126043166167626077,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.0.0",\n "merkle_proof": "2226 chars",\n "stored_value": {\n "Account": {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",\n "weight": 1\n },\n {\n "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",\n "weight": 1\n }\n ],\n "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",\n "named_keys": []\n }\n }\n }\n}\n'})}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["In the example output, you can see the account hashes listed within the ",(0,s.jsx)(n.code,{children:"associated_keys"})," section. Each key has weight ",(0,s.jsx)(n.code,{children:"1"}),"; since the action threshold for ",(0,s.jsx)(n.code,{children:"deployment"})," is ",(0,s.jsx)(n.code,{children:"2"}),", neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold."]})]})}function l(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>i});var s=t(96540);const o={},c=s.createContext(o);function a(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:a(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f0563fee.0da4678b.js b/assets/js/f0563fee.0da4678b.js deleted file mode 100644 index c1f873ac6..000000000 --- a/assets/js/f0563fee.0da4678b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7865],{17606:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var a=t(74848),s=t(28453);const i={title:"Transactions",slug:"/transactions"},r="Transactions",o={id:"concepts/transactions",title:"Transactions",description:"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.",source:"@site/docs/concepts/transactions.md",sourceDirName:"concepts",slug:"/transactions",permalink:"/next/transactions",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Transactions",slug:"/transactions"}},l={},c=[{value:"Transaction Types",id:"transaction-types",level:2},{value:"Withdraw Bid",id:"withdraw-bid",level:3},{value:"Add Bid",id:"add-bid",level:3},{value:"Delegate",id:"delegate",level:3},{value:"Undelegate",id:"undelegate",level:3},{value:"Redelegate",id:"redelegate",level:3},{value:"Invocable Entity",id:"invocable-entity",level:3},{value:"Invocable Entity Alias",id:"invocable-entity-alias",level:3},{value:"Package",id:"package",level:3},{value:"Package Name",id:"package-name",level:3},{value:"Session",id:"session",level:3},{value:"Transfer",id:"transfer",level:3}];function d(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",summary:"summary",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"transactions",children:"Transactions"})}),"\n",(0,a.jsxs)(n.p,{children:["Transactions are ",(0,a.jsx)(n.a,{href:"/next/developers/json-rpc/types_chain#transaction",children:"a new structure"})," that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/D#deploy",children:"Deploys"}),", allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."]}),"\n",(0,a.jsx)(n.p,{children:"The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute."}),"\n",(0,a.jsx)(n.h2,{id:"transaction-types",children:"Transaction Types"}),"\n",(0,a.jsxs)(n.p,{children:["The following is a list of Transaction types included within the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/tree/dev",children:"CLI Casper client"})," ",(0,a.jsx)(n.code,{children:"put-transaction"})," or ",(0,a.jsx)(n.code,{children:"put-txn"})," command."]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw-bid",children:"Withdraw Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"withdraw-bid"})," allows validators to withdraw their auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn withdraw-bid\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be withdrawn.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"add-bid",children:"Add Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"add-bid"})," allows validators to place an auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn add-bid\n/// The [delegation rate](../concepts/economics/staking.md#delegation-rate) for delegators staking on to this validator.\n --delegation-rate <INTEGER>\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be bid.\n --transaction-amount <INTEGER>\n/// The minimum amount of motes that a delegator can stake to this validator.\n --minimum-delegation-amount <INTEGER>\n/// The maximum amount of motes that a delegator can stake to this validator.\n --maximum-delegation-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"delegate",children:"Delegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"delegate"})," allows a user to delegate a stake of CSPR to a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn delegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to stake with this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"undelegate",children:"Undelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"undelegate"})," allows a user to undelegate their previously staked CSPR from a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn undelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to undelegate from this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"redelegate",children:"Redelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"redelegate"})," allows a user to redelegate their previously staked CSPR to a new validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn redelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The old validator's public key.\n --validator <STRING>\n/// The new validator's public key.\n --new-validator <STRING>\n/// The amount in motes to redelegate from the old validator to the new validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity",children:"Invocable Entity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/next/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an ",(0,a.jsx)(n.a,{href:"/next/concepts/key-types#addressableentity",children:(0,a.jsx)(n.code,{children:"Entity Address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity\n/// The [`entity-hash`](../developers/json-rpc/types_chain.md#addressableentityhash) of the entity to invoke.\n --entity-address <FORMATTED STRING or PATH>\n/// The entry point on the invocable entity.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity-alias",children:"Invocable Entity Alias"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity-alias"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/next/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an alias stored in their ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity-alias\n/// The entity alias stored in the calling entity's named keys.\n --entity-alias <STRING>\n/// The entry point on the invocable entity. \n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using the associated ",(0,a.jsx)(n.a,{href:"/next/concepts/key-types#package",children:(0,a.jsx)(n.code,{children:"package-address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package\n/// The address of the contract package.\n --package-address <FORMATTED STRING or PATH>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package-name",children:"Package Name"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package-name"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/next/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using an alias stored in their ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package-name\n/// The package alias stored in the calling entity's named keys.\n --package-alias <STRING>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"session",children:"Session"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"session"})," allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial ",(0,a.jsx)(n.a,{href:"/next/developers/cli/sending-transactions",children:"Sending Transactions"})," covers this in depth."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn session\n/// The local path pointing to Wasm that will be sent to global state.\n --transaction-path <PATH>\n/// An entry point on a previously installed contract, if applicable.\n --session-entry-point <NAME>\n/// The category of the Transaction, in decreasing size order.\n --category <install-upgrade|large|medium|small>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"transfer"})," allows a user to transfer the designated number of ",(0,a.jsx)(n.a,{href:"/next/concepts/glossary/M#motes",children:"motes"})," to a target address."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn transfer\n/// The recipient of the transfer.\n --target <FORMATTED STRING>\n/// The amount in motes to be transferred.\n --transfer-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n "]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f0563fee.df8d1b93.js b/assets/js/f0563fee.df8d1b93.js new file mode 100644 index 000000000..1dcc94661 --- /dev/null +++ b/assets/js/f0563fee.df8d1b93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[27865],{17606:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>r,default:()=>h,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var a=t(74848),s=t(28453);const i={title:"Transactions",slug:"/transactions"},r="Transactions",o={id:"concepts/transactions",title:"Transactions",description:"Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.",source:"@site/docs/concepts/transactions.md",sourceDirName:"concepts",slug:"/transactions",permalink:"/transactions",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724245416e3,frontMatter:{title:"Transactions",slug:"/transactions"}},l={},c=[{value:"Transaction Types",id:"transaction-types",level:2},{value:"Withdraw Bid",id:"withdraw-bid",level:3},{value:"Add Bid",id:"add-bid",level:3},{value:"Delegate",id:"delegate",level:3},{value:"Undelegate",id:"undelegate",level:3},{value:"Redelegate",id:"redelegate",level:3},{value:"Invocable Entity",id:"invocable-entity",level:3},{value:"Invocable Entity Alias",id:"invocable-entity-alias",level:3},{value:"Package",id:"package",level:3},{value:"Package Name",id:"package-name",level:3},{value:"Session",id:"session",level:3},{value:"Transfer",id:"transfer",level:3}];function d(e){const n={a:"a",b:"b",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",p:"p",pre:"pre",summary:"summary",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"transactions",children:"Transactions"})}),"\n",(0,a.jsxs)(n.p,{children:["Transactions are ",(0,a.jsx)(n.a,{href:"/developers/json-rpc/types_chain#transaction",children:"a new structure"})," that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy ",(0,a.jsx)(n.a,{href:"/concepts/glossary/D#deploy",children:"Deploys"}),", allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available."]}),"\n",(0,a.jsx)(n.p,{children:"The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute."}),"\n",(0,a.jsx)(n.h2,{id:"transaction-types",children:"Transaction Types"}),"\n",(0,a.jsxs)(n.p,{children:["The following is a list of Transaction types included within the ",(0,a.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-client-rs/tree/dev",children:"CLI Casper client"})," ",(0,a.jsx)(n.code,{children:"put-transaction"})," or ",(0,a.jsx)(n.code,{children:"put-txn"})," command."]}),"\n",(0,a.jsx)(n.h3,{id:"withdraw-bid",children:"Withdraw Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"withdraw-bid"})," allows validators to withdraw their auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn withdraw-bid\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be withdrawn.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"add-bid",children:"Add Bid"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"add-bid"})," allows validators to place an auction bid."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn add-bid\n/// The [delegation rate](../concepts/economics/staking.md#delegation-rate) for delegators staking on to this validator.\n --delegation-rate <INTEGER>\n/// The public key of the bidder.\n --public-key <FORMATTED STRING or PATH>\n/// The amount in motes to be bid.\n --transaction-amount <INTEGER>\n/// The minimum amount of motes that a delegator can stake to this validator.\n --minimum-delegation-amount <INTEGER>\n/// The maximum amount of motes that a delegator can stake to this validator.\n --maximum-delegation-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"delegate",children:"Delegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"delegate"})," allows a user to delegate a stake of CSPR to a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn delegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to stake with this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"undelegate",children:"Undelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"undelegate"})," allows a user to undelegate their previously staked CSPR from a validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn undelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The validator's public key.\n --validator <STRING>\n/// The amount in motes to undelegate from this validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"redelegate",children:"Redelegate"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"redelegate"})," allows a user to redelegate their previously staked CSPR to a new validator."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn redelegate\n/// The delegator's public key.\n --delegator <STRING>\n/// The old validator's public key.\n --validator <STRING>\n/// The new validator's public key.\n --new-validator <STRING>\n/// The amount in motes to redelegate from the old validator to the new validator.\n --transaction-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction. \n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity",children:"Invocable Entity"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an ",(0,a.jsx)(n.a,{href:"/concepts/key-types#addressableentity",children:(0,a.jsx)(n.code,{children:"Entity Address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity\n/// The [`entity-hash`](../developers/json-rpc/types_chain.md#addressableentityhash) of the entity to invoke.\n --entity-address <FORMATTED STRING or PATH>\n/// The entry point on the invocable entity.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"invocable-entity-alias",children:"Invocable Entity Alias"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"invocable-entity-alias"})," allows a user to invoke an entry point on the given ",(0,a.jsx)(n.a,{href:"/concepts/addressable-entity",children:(0,a.jsx)(n.code,{children:"AddressableEntity"})})," directly using an alias stored in their ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn invocable-entity-alias\n/// The entity alias stored in the calling entity's named keys.\n --entity-alias <STRING>\n/// The entry point on the invocable entity. \n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package",children:"Package"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using the associated ",(0,a.jsx)(n.a,{href:"/concepts/key-types#package",children:(0,a.jsx)(n.code,{children:"package-address"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package\n/// The address of the contract package.\n --package-address <FORMATTED STRING or PATH>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"package-name",children:"Package Name"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"package-name"})," allows a user to invoke an entry point on the given contract ",(0,a.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts#the-contract-package",children:(0,a.jsx)(n.code,{children:"package"})})," using an alias stored in their ",(0,a.jsx)(n.a,{href:"/concepts/glossary/N#named-keys",children:(0,a.jsx)(n.code,{children:"named keys"})}),"."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn package-name\n/// The package alias stored in the calling entity's named keys.\n --package-alias <STRING>\n/// The entry point to invoke on the package.\n --session-entry-point <NAME>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"session",children:"Session"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"session"})," allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial ",(0,a.jsx)(n.a,{href:"/developers/cli/sending-transactions",children:"Sending Transactions"})," covers this in depth."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn session\n/// The local path pointing to Wasm that will be sent to global state.\n --transaction-path <PATH>\n/// An entry point on a previously installed contract, if applicable.\n --session-entry-point <NAME>\n/// The category of the Transaction, in decreasing size order.\n --category <install-upgrade|large|medium|small>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n"]}),"\n",(0,a.jsx)(n.h3,{id:"transfer",children:"Transfer"}),"\n",(0,a.jsxs)(n.p,{children:[(0,a.jsx)(n.code,{children:"transfer"})," allows a user to transfer the designated number of ",(0,a.jsx)(n.a,{href:"/concepts/glossary/M#motes",children:"motes"})," to a target address."]}),"\n",(0,a.jsxs)(n.details,{children:["\n",(0,a.jsx)(n.summary,{children:(0,a.jsx)(n.b,{children:"Casper Client Command"})}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-json",children:"\ncasper-client put-txn transfer\n/// The recipient of the transfer.\n --target <FORMATTED STRING>\n/// The amount in motes to be transferred.\n --transfer-amount <INTEGER>\n/// The maximum gas price that the user is willing to pay for this transaction.\n --gas-price-tolerance <INTEGER>\n/// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.\n <--secret-key <PATH>|--initiator-address <HEX STRING>>\n\n"})}),"\n "]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>r,x:()=>o});var a=t(96540);const s={},i=a.createContext(s);function r(e){const n=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f070a991.8a1ac562.js b/assets/js/f070a991.8a1ac562.js deleted file mode 100644 index ee64c415c..000000000 --- a/assets/js/f070a991.8a1ac562.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5592],{26591:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>h});var n=s(74848),a=s(28453);const i={},o="Authorization Keys",r={id:"concepts/list-auth-keys",title:"Authorization Keys",description:"This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.",source:"@site/versioned_docs/version-1.5.X/concepts/list-auth-keys.md",sourceDirName:"concepts",slug:"/concepts/list-auth-keys",permalink:"/concepts/list-auth-keys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Smart Contracts",permalink:"/concepts/smart-contracts"},next:{title:"Call Stacks",permalink:"/concepts/callstack"}},c={},h=[{value:"Associated Keys vs. Authorization Keys",id:"associated-keys-vs-authorization-keys",level:2},{value:"Accessing Authorization Keys from a Smart Contract",id:"accessing-authorization-keys-from-a-smart-contract",level:2},{value:"When to Use Authorization Keys",id:"when-to-use-authorization-keys",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"authorization-keys",children:"Authorization Keys"})}),"\n",(0,n.jsxs)(t.p,{children:["This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the ",(0,n.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial for an example."]}),"\n",(0,n.jsx)(t.h2,{id:"associated-keys-vs-authorization-keys",children:"Associated Keys vs. Authorization Keys"}),"\n",(0,n.jsx)(t.p,{children:"Let's review the difference between associated keys to an Account and authorization keys for a Deploy."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about ",(0,n.jsx)(t.a,{href:"/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys and weights"})," and try the ",(0,n.jsx)(t.a,{href:"/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,n.jsxs)(t.li,{children:["Authorization keys are public keys used to sign a deploy and are listed in the Deploy's ",(0,n.jsx)(t.code,{children:"approvals"}),". Authorization keys are a subset of the associated keys of the account under which the deploy is executed."]}),"\n",(0,n.jsxs)(t.li,{children:["When a node receives a deploy, it checks that the deploy has the required authorization keys under ",(0,n.jsx)(t.code,{children:"approvals"})," before including it in a block."]}),"\n",(0,n.jsx)(t.li,{children:"Different deploys executing the same smart contract can have different authorization keys."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image showing associated keys and authorization keys",src:s(25110).A+"",width:"862",height:"842"})}),"\n",(0,n.jsx)(t.p,{children:"Here is a sample JSON representation of an Account's associated keys:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'"associated_keys": [\n{\n "account_hash": "account-hash-1ab\u202611",\n "weight": 1\n},\n{\n "account_hash": "account-hash-2cd\u202622",\n "weight": 1\n},\n{\n "account_hash": "account-hash-3de\u202633",\n "weight": 1\n },\n{\n "account_hash": "account-hash-4fg\u202644",\n "weight": 1\n}\n ], ...\n'})}),"\n",(0,n.jsx)(t.p,{children:"Here is a sample JSON representation of a Deploy's authorization keys:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'"approvals": [\n {\n "signer": " 2cd...22",\n "signature": "02df8c...f481"\n },\n {\n "signer": "4fg...44",\n "signature": "02ef21...756a"\n }\n]\n'})}),"\n",(0,n.jsx)(t.h2,{id:"accessing-authorization-keys-from-a-smart-contract",children:"Accessing Authorization Keys from a Smart Contract"}),"\n",(0,n.jsxs)(t.p,{children:["Contract code can retrieve the set of authorization keys for a given deploy by calling the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"contract_api::runtime::list_authorization_keys"})," function, which returns the set of account hashes representing the keys used to sign the deploy."]}),"\n",(0,n.jsx)(t.h2,{id:"when-to-use-authorization-keys",children:"When to Use Authorization Keys"}),"\n",(0,n.jsx)(t.p,{children:"Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations."}),"\n",(0,n.jsxs)(t.p,{children:["Try the ",(0,n.jsx)(t.a,{href:"/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial to view an example workflow."]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},25110:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/authorization-keys-9187fa39eca478722639797b5109fa50.png"},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f070a991.984951c4.js b/assets/js/f070a991.984951c4.js new file mode 100644 index 000000000..6608cec4b --- /dev/null +++ b/assets/js/f070a991.984951c4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55592],{26591:(e,t,s)=>{s.r(t),s.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>l,frontMatter:()=>i,metadata:()=>r,toc:()=>h});var n=s(74848),a=s(28453);const i={},o="Authorization Keys",r={id:"concepts/list-auth-keys",title:"Authorization Keys",description:"This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.",source:"@site/versioned_docs/version-1.5.X/concepts/list-auth-keys.md",sourceDirName:"concepts",slug:"/concepts/list-auth-keys",permalink:"/1.5.X/concepts/list-auth-keys",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{},sidebar:"concepts",previous:{title:"Smart Contracts",permalink:"/1.5.X/concepts/smart-contracts"},next:{title:"Call Stacks",permalink:"/1.5.X/concepts/callstack"}},c={},h=[{value:"Associated Keys vs. Authorization Keys",id:"associated-keys-vs-authorization-keys",level:2},{value:"Accessing Authorization Keys from a Smart Contract",id:"accessing-authorization-keys-from-a-smart-contract",level:2},{value:"When to Use Authorization Keys",id:"when-to-use-authorization-keys",level:2}];function d(e){const t={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"authorization-keys",children:"Authorization Keys"})}),"\n",(0,n.jsxs)(t.p,{children:["This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the ",(0,n.jsx)(t.a,{href:"/1.5.X/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial for an example."]}),"\n",(0,n.jsx)(t.h2,{id:"associated-keys-vs-authorization-keys",children:"Associated Keys vs. Authorization Keys"}),"\n",(0,n.jsx)(t.p,{children:"Let's review the difference between associated keys to an Account and authorization keys for a Deploy."}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about ",(0,n.jsx)(t.a,{href:"/1.5.X/concepts/design/casper-design#accounts-associated-keys-weights",children:"associated keys and weights"})," and try the ",(0,n.jsx)(t.a,{href:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig",children:"Two-Party Multi-Signature"})," tutorial."]}),"\n",(0,n.jsxs)(t.li,{children:["Authorization keys are public keys used to sign a deploy and are listed in the Deploy's ",(0,n.jsx)(t.code,{children:"approvals"}),". Authorization keys are a subset of the associated keys of the account under which the deploy is executed."]}),"\n",(0,n.jsxs)(t.li,{children:["When a node receives a deploy, it checks that the deploy has the required authorization keys under ",(0,n.jsx)(t.code,{children:"approvals"})," before including it in a block."]}),"\n",(0,n.jsx)(t.li,{children:"Different deploys executing the same smart contract can have different authorization keys."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:(0,n.jsx)(t.img,{alt:"Image showing associated keys and authorization keys",src:s(40408).A+"",width:"862",height:"842"})}),"\n",(0,n.jsx)(t.p,{children:"Here is a sample JSON representation of an Account's associated keys:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'"associated_keys": [\n{\n "account_hash": "account-hash-1ab\u202611",\n "weight": 1\n},\n{\n "account_hash": "account-hash-2cd\u202622",\n "weight": 1\n},\n{\n "account_hash": "account-hash-3de\u202633",\n "weight": 1\n },\n{\n "account_hash": "account-hash-4fg\u202644",\n "weight": 1\n}\n ], ...\n'})}),"\n",(0,n.jsx)(t.p,{children:"Here is a sample JSON representation of a Deploy's authorization keys:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{children:'"approvals": [\n {\n "signer": " 2cd...22",\n "signature": "02df8c...f481"\n },\n {\n "signer": "4fg...44",\n "signature": "02ef21...756a"\n }\n]\n'})}),"\n",(0,n.jsx)(t.h2,{id:"accessing-authorization-keys-from-a-smart-contract",children:"Accessing Authorization Keys from a Smart Contract"}),"\n",(0,n.jsxs)(t.p,{children:["Contract code can retrieve the set of authorization keys for a given deploy by calling the ",(0,n.jsx)(t.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/runtime/fn.list_authorization_keys.html",children:"contract_api::runtime::list_authorization_keys"})," function, which returns the set of account hashes representing the keys used to sign the deploy."]}),"\n",(0,n.jsx)(t.h2,{id:"when-to-use-authorization-keys",children:"When to Use Authorization Keys"}),"\n",(0,n.jsx)(t.p,{children:"Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations."}),"\n",(0,n.jsxs)(t.p,{children:["Try the ",(0,n.jsx)(t.a,{href:"/1.5.X/resources/advanced/list-auth-keys-tutorial",children:"Working with Authorization Keys"})," tutorial to view an example workflow."]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},40408:(e,t,s)=>{s.d(t,{A:()=>n});const n=s.p+"assets/images/authorization-keys-9187fa39eca478722639797b5109fa50.png"},28453:(e,t,s)=>{s.d(t,{R:()=>o,x:()=>r});var n=s(96540);const a={},i=n.createContext(a);function o(e){const t=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1245771.23f1d291.js b/assets/js/f1245771.23f1d291.js deleted file mode 100644 index fbe5d3565..000000000 --- a/assets/js/f1245771.23f1d291.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1630],{51485:a=>{a.exports=JSON.parse('{"author":{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland","count":1},"listMetadata":{"permalink":"/blog/authors/dylanireland","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/f1245771.8a14c444.js b/assets/js/f1245771.8a14c444.js new file mode 100644 index 000000000..5f2d33f41 --- /dev/null +++ b/assets/js/f1245771.8a14c444.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[31630],{51485:a=>{a.exports=JSON.parse('{"author":{"name":"Dylan Ireland","page":{"permalink":"/blog/authors/dylanireland"},"title":"Developer Advocate for Casper Association","url":"https://github.com/dylanireland","permalink":"/dylanireland","imageURL":"https://github.com/dylanireland.png","key":"dylanireland","count":1},"listMetadata":{"permalink":"/blog/authors/dylanireland","page":1,"postsPerPage":1,"totalPages":1,"totalCount":1,"blogDescription":"A blog about all things to do with developing on the Casper Blockchain","blogTitle":"Casper Developer Relations Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/f1a6c2e6.30426d72.js b/assets/js/f1a6c2e6.30426d72.js new file mode 100644 index 000000000..466b38015 --- /dev/null +++ b/assets/js/f1a6c2e6.30426d72.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8595],{24140:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(74848),o=t(28453);const a={},s="Guidance for JSON-RPC SDK Compliance",r={id:"developers/json-rpc/guidance",title:"Guidance for JSON-RPC SDK Compliance",description:"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/guidance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/guidance",permalink:"/2.0.0/developers/json-rpc/guidance",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/2.0.0/developers/json-rpc/"},next:{title:"Required Methods for Minimal Compliance",permalink:"/2.0.0/developers/json-rpc/minimal-compliance"}},l={},c=[{value:"Consistency",id:"consistency",level:2},{value:"Advanced Functionality",id:"advanced-functionality",level:2}];function d(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"guidance-for-json-rpc-sdk-compliance",children:"Guidance for JSON-RPC SDK Compliance"})}),"\n",(0,i.jsxs)(n.p,{children:["A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the ",(0,i.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational",children:"informational JSON-RPC methods"})," page."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["A Casper JSON-RPC SDK claiming to be complete is expected to implement ",(0,i.jsx)(n.em,{children:"all"})," endpoints and ",(0,i.jsx)(n.em,{children:"all"})," types defined in the serialization standard."]})}),"\n",(0,i.jsx)(n.h2,{id:"consistency",children:"Consistency"}),"\n",(0,i.jsx)(n.p,{children:"A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet."}),"\n",(0,i.jsx)(n.p,{children:"Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-functionality",children:"Advanced Functionality"}),"\n",(0,i.jsx)(n.p,{children:"SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations."}),"\n",(0,i.jsx)(n.p,{children:"However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience."}),"\n",(0,i.jsx)(n.p,{children:"For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1c6b7a3.50559f74.js b/assets/js/f1c6b7a3.50559f74.js deleted file mode 100644 index c45a0ac99..000000000 --- a/assets/js/f1c6b7a3.50559f74.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8694],{13548:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>i});var c=a(74848),s=a(28453);const r={},d="Direct Token Transfer",t={id:"developers/cli/transfers/direct-token-transfer",title:"Direct Token Transfer",description:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.",source:"@site/docs/developers/cli/transfers/direct-token-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/direct-token-transfer",permalink:"/next/developers/cli/transfers/direct-token-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens",permalink:"/next/developers/cli/transfers/"},next:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/next/developers/cli/transfers/multisig-deploy-transfer"}},f={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Direct Transfer Example",id:"transfer",level:2},{value:"Verifying the Deploy",id:"verify-deploy",level:2},{value:"Verifying the Transfer",id:"verifying-the-transfer",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"direct-token-transfer",children:"Direct Token Transfer"})}),"\n",(0,c.jsx)(n.p,{children:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"This workflow assumes:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["You meet the general ",(0,c.jsx)(n.a,{href:"/next/developers/prerequisites",children:"development prerequisites"})]}),"\n",(0,c.jsx)(n.li,{children:"You are using the Casper command-line client"}),"\n",(0,c.jsxs)(n.li,{children:["You have a target ",(0,c.jsx)(n.em,{children:"public key"})]}),"\n",(0,c.jsxs)(n.li,{children:["You have a valid ",(0,c.jsx)(n.em,{children:"node address"})]}),"\n",(0,c.jsxs)(n.li,{children:["You must be able to sign a deploy for the source account using the source ",(0,c.jsx)(n.em,{children:"secret key"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transfer",children:"Direct Transfer Example"}),"\n",(0,c.jsxs)(n.p,{children:["The following ",(0,c.jsx)(n.code,{children:"transfer"})," command allows you to move CSPR from one account's purse to another as denominated in ",(0,c.jsx)(n.a,{href:"/next/concepts/design/casper-design#tokens-divisibility",children:"Motes"}),". A ",(0,c.jsx)(n.em,{children:"Mote"})," is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id <ID> \\\n--transfer-id <TRANSFER_ID> \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"transfer-id"})," -<64-BIT INTEGER> The ",(0,c.jsx)(n.code,{children:"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,c.jsx)(n.code,{children:"0"})," or some ",(0,c.jsx)(n.code,{children:"u64"})," value that is meaningful to you"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint default:",(0,c.jsx)(n.a,{href:"http://localhost:7777",children:"http://localhost:7777"})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"amount"})," -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.jsx)(n.code,{children:"Motes"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"secret-key"})," - Path to secret key file"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"chain-name"})," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Testnet is ",(0,c.jsx)(n.strong,{children:"casper-test"})]}),"\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Mainnet is ",(0,c.jsx)(n.strong,{children:"casper"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"target-account"})," - Hex-encoded public key of the account that will receive the funds in its main purse"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"payment-amount"})," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", you can specify 10^8 motes"]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."deploy_hash"'})," - The address of the deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Save the returned ",(0,c.jsx)(n.em,{children:"deploy_hash"})," from the output to query information about the transfer deploy later."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Transfer:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"verify-deploy",children:"Verifying the Deploy"}),"\n",(0,c.jsx)(n.p,{children:"A transfer on a Casper network is only executed after it has been included in a finalized block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"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"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."execution_results"[0]."block_hash"'})," - contains the block hash of the block that included the transfer. We will require the ",(0,c.jsx)(n.em,{children:"state_root_hash"})," of this block to look up information about the accounts and their purse balances"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Transfer addresses use a ",(0,c.jsx)(n.code,{children:"transfer-"})," string prefix."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["Refer to the Section on ",(0,c.jsx)(n.a,{href:"/next/resources/tutorials/beginner/querying-network#querying-deploys",children:"querying deploys"})," for more information."]}),"\n",(0,c.jsx)(n.h2,{id:"verifying-the-transfer",children:"Verifying the Transfer"}),"\n",(0,c.jsxs)(n.p,{children:["In addition to verifying the deploy, you also need to ",(0,c.jsx)(n.a,{href:"/next/developers/cli/transfers/verify-transfer",children:"verify the transfer details"}),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>t});var c=a(96540);const s={},r=c.createContext(s);function d(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1c6b7a3.dd24385f.js b/assets/js/f1c6b7a3.dd24385f.js new file mode 100644 index 000000000..b7c24f78f --- /dev/null +++ b/assets/js/f1c6b7a3.dd24385f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8694],{13548:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>f,contentTitle:()=>d,default:()=>l,frontMatter:()=>r,metadata:()=>t,toc:()=>i});var c=a(74848),s=a(28453);const r={},d="Direct Token Transfer",t={id:"developers/cli/transfers/direct-token-transfer",title:"Direct Token Transfer",description:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.",source:"@site/docs/developers/cli/transfers/direct-token-transfer.md",sourceDirName:"developers/cli/transfers",slug:"/developers/cli/transfers/direct-token-transfer",permalink:"/developers/cli/transfers/direct-token-transfer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Transferring Tokens",permalink:"/developers/cli/transfers/"},next:{title:"Transferring Tokens using a Multi-Sig Deploy",permalink:"/developers/cli/transfers/multisig-deploy-transfer"}},f={},i=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Direct Transfer Example",id:"transfer",level:2},{value:"Verifying the Deploy",id:"verify-deploy",level:2},{value:"Verifying the Transfer",id:"verifying-the-transfer",level:2}];function o(e){const n={a:"a",admonition:"admonition",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,s.R)(),...e.components};return(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(n.header,{children:(0,c.jsx)(n.h1,{id:"direct-token-transfer",children:"Direct Token Transfer"})}),"\n",(0,c.jsx)(n.p,{children:"This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network."}),"\n",(0,c.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,c.jsx)(n.p,{children:"This workflow assumes:"}),"\n",(0,c.jsxs)(n.ol,{children:["\n",(0,c.jsxs)(n.li,{children:["You meet the general ",(0,c.jsx)(n.a,{href:"/developers/prerequisites",children:"development prerequisites"})]}),"\n",(0,c.jsx)(n.li,{children:"You are using the Casper command-line client"}),"\n",(0,c.jsxs)(n.li,{children:["You have a target ",(0,c.jsx)(n.em,{children:"public key"})]}),"\n",(0,c.jsxs)(n.li,{children:["You have a valid ",(0,c.jsx)(n.em,{children:"node address"})]}),"\n",(0,c.jsxs)(n.li,{children:["You must be able to sign a deploy for the source account using the source ",(0,c.jsx)(n.em,{children:"secret key"})]}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"transfer",children:"Direct Transfer Example"}),"\n",(0,c.jsxs)(n.p,{children:["The following ",(0,c.jsx)(n.code,{children:"transfer"})," command allows you to move CSPR from one account's purse to another as denominated in ",(0,c.jsx)(n.a,{href:"/concepts/design/casper-design#tokens-divisibility",children:"Motes"}),". A ",(0,c.jsx)(n.em,{children:"Mote"})," is a denomination of the cryptocurrency CSPR, where 1 CSPR = 1,000,000,000 Motes."]}),"\n",(0,c.jsx)(n.p,{children:"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."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer \\\n--id <ID> \\\n--transfer-id <TRANSFER_ID> \\\n--node-address [NODE_SERVER_ADDRESS] \\\n--amount [AMOUNT_TO_TRANSFER] \\\n--secret-key [KEY_PATH]/secret_key.pem \\\n--chain-name [CHAIN_NAME] \\\n--target-account [TARGET_PUBLIC_KEY_HEX] \\\n--payment-amount [PAYMENT_AMOUNT_IN_MOTES]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Request fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"id"})," - Optional JSON-RPC identifier applied to the request and returned in the response. If not provided, a random integer will be assigned"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"transfer-id"})," -<64-BIT INTEGER> The ",(0,c.jsx)(n.code,{children:"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,c.jsx)(n.code,{children:"0"})," or some ",(0,c.jsx)(n.code,{children:"u64"})," value that is meaningful to you"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"node-address"})," - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint default:",(0,c.jsx)(n.a,{href:"http://localhost:7777",children:"http://localhost:7777"})]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"amount"})," -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 ",(0,c.jsx)(n.code,{children:"Motes"}),")"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"secret-key"})," - Path to secret key file"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"chain-name"})," - Name of the chain, to avoid the deploy from being accidentally or maliciously included in a different chain"]}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Testnet is ",(0,c.jsx)(n.strong,{children:"casper-test"})]}),"\n",(0,c.jsxs)(n.li,{children:["The ",(0,c.jsx)(n.em,{children:"chain-name"})," for Mainnet is ",(0,c.jsx)(n.strong,{children:"casper"})]}),"\n"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"target-account"})," - Hex-encoded public key of the account that will receive the funds in its main purse"]}),"\n"]}),"\n",(0,c.jsxs)(n.li,{children:["\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.code,{children:"payment-amount"})," - The payment for the transfer in motes. The payment amount varies based on each deploy and network ",(0,c.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),". For Testnet node version ",(0,c.jsx)(n.a,{href:"https://github.com/casper-network/casper-node/blob/release-1.5.1/resources/production/chainspec.toml",children:"1.5.1"}),", you can specify 10^8 motes"]}),"\n"]}),"\n"]}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."deploy_hash"'})," - The address of the deploy, needed to look up additional information about the transfer"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Save the returned ",(0,c.jsx)(n.em,{children:"deploy_hash"})," from the output to query information about the transfer deploy later."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Transfer:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client transfer -v \\\n--id 3 \\\n--transfer-id 11102023 \\\n--node-address https://rpc.testnet.casperlabs.io/ \\\n--amount 5000000000 \\\n--secret-key ~/KEYS/secret_key.pem \\\n--chain-name casper-test \\\n--target-account 01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986 \\\n--payment-amount 100000000\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "account_put_deploy",\n "params": {\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n }\n },\n "id": 3\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "id": 3,\n "result": {\n "api_version": "1.5.3",\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c"\n }\n}\n'})}),"\n"]}),"\n",(0,c.jsx)(n.h2,{id:"verify-deploy",children:"Verifying the Deploy"}),"\n",(0,c.jsx)(n.p,{children:"A transfer on a Casper network is only executed after it has been included in a finalized block."}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]\n"})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Important response fields:"})}),"\n",(0,c.jsxs)(n.ul,{children:["\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"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"]}),"\n",(0,c.jsxs)(n.li,{children:[(0,c.jsx)(n.code,{children:'"result"."execution_results"[0]."block_hash"'})," - contains the block hash of the block that included the transfer. We will require the ",(0,c.jsx)(n.em,{children:"state_root_hash"})," of this block to look up information about the accounts and their purse balances"]}),"\n"]}),"\n",(0,c.jsx)(n.admonition,{type:"note",children:(0,c.jsxs)(n.p,{children:["Transfer addresses use a ",(0,c.jsx)(n.code,{children:"transfer-"})," string prefix."]})}),"\n",(0,c.jsx)(n.p,{children:(0,c.jsx)(n.strong,{children:"Example Query:"})}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-bash",children:"casper-client get-deploy \\\n--node-address https://rpc.testnet.casperlabs.io \n1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c\n"})}),"\n",(0,c.jsxs)(n.details,{children:["\n",(0,c.jsx)(n.summary,{children:"Explore the JSON-RPC request and response generated."}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Request"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "method": "info_get_deploy",\n "params": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "finalized_approvals": false\n },\n "id": -3447643973713335073\n}\n'})}),"\n",(0,c.jsxs)(n.p,{children:[(0,c.jsx)(n.strong,{children:"JSON-RPC Response"}),":"]}),"\n",(0,c.jsx)(n.pre,{children:(0,c.jsx)(n.code,{className:"language-json",children:'{\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.5.3",\n "deploy": {\n "hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "header": {\n "account": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "timestamp": "2023-10-12T14:59:40.760Z",\n "ttl": "30m",\n "gas_price": 1,\n "body_hash": "ea7e6a6cbdd4d761827cb627e162896bee3e771beda000550615c9b4fafa3a2d",\n "dependencies": [],\n "chain_name": "casper-test"\n },\n "payment": {\n "ModuleBytes": {\n "module_bytes": "",\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0400e1f505",\n "parsed": "100000000"\n }\n ]\n ]\n }\n },\n "session": {\n "Transfer": {\n "args": [\n [\n "amount",\n {\n "cl_type": "U512",\n "bytes": "0500f2052a01",\n "parsed": "5000000000"\n }\n ],\n [\n "target",\n {\n "cl_type": "PublicKey",\n "bytes": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",\n "parsed": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986"\n }\n ],\n [\n "id",\n {\n "cl_type": {\n "Option": "U64"\n },\n "bytes": "014767a90000000000",\n "parsed": 11102023\n }\n ]\n ]\n }\n },\n "approvals": [\n {\n "signer": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",\n "signature": "01e53cb742ed13ff4f0584a3da0f22f5942a33e010965adf640c91204ae4bc7436f1e5534d338ffa117d193295214816445439781229d24a372085c316eac5e305"\n }\n ]\n },\n "execution_results": [\n {\n "block_hash": "aac51dad028ba8b3d6fec86a39252bbc4285d513fd57a8af4696ab5390ac5c2b",\n "result": {\n "Success": {\n "effect": {\n "operations": [],\n "transforms": [\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06621c3e660301",\n "parsed": "1114111876194"\n }\n }\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "AddUInt512": "100000000"\n }\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": "Identity"\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": "Identity"\n },\n {\n "key": "balance-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "06622a383c0201",\n "parsed": "1109111876194"\n }\n }\n },\n {\n "key": "balance-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c",\n "transform": {\n "AddUInt512": "5000000000"\n }\n },\n {\n "key": "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405",\n "transform": {\n "WriteTransfer": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "to": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "target": "uref-8294864177c2c1ec887a11dae095e487b5256ce6bd2a1f2740d0e4f28bd3251c-004",\n "amount": "5000000000",\n "gas": "0",\n "id": 11102023\n }\n }\n },\n {\n "key": "deploy-1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transform": {\n "WriteDeployInfo": {\n "deploy_hash": "1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c",\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "from": "account-hash-e70dbca48c2d31bc2d754e51860ceaa8a1a49dc627b20320b0ecee1b6d9ce655",\n "source": "uref-11e6fc5354f61a004df98482376c45964b8b1557e8f2f13fb5f3adab5faa8be1-007",\n "gas": "100000000"\n }\n }\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-624dbe2395b9d9503fbee82162f1714ebff6b639f96d2084d26d944c354ec4c5",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "hash-8cf5e4acf51f54eb59291599187838dc3bc234089c46fc6ca8ad17e762ae4401",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "hash-9824d60dc3a5c44a20b9fd260a412437933835b52fc683d8ae36e4ec2114843e",\n "transform": "Identity"\n },\n {\n "key": "hash-010c3fe81b7b862e50c77ef9a958a05bfa98444f26f96f23d37a13c96244cfb7",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": "Identity"\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": "Identity"\n },\n {\n "key": "balance-98d945f5324f865243b7c02c0417ab6eac361c5c56602fd42ced834a1ba201b6",\n "transform": {\n "WriteCLValue": {\n "cl_type": "U512",\n "bytes": "00",\n "parsed": "0"\n }\n }\n },\n {\n "key": "balance-da632bfba17f4a7882581de2a37219be71628600ccd0df83f1d42465bd018537",\n "transform": {\n "AddUInt512": "100000000"\n }\n }\n ]\n },\n "transfers": [\n "transfer-0de7250864e67aa76626a844dcc931e615284a13a110df3f97cec9e3e97af405"\n ],\n "cost": "100000000"\n }\n }\n }\n ]\n },\n "id": -3447643973713335073\n}\n'})}),"\n"]}),"\n",(0,c.jsxs)(n.p,{children:["Refer to the Section on ",(0,c.jsx)(n.a,{href:"/resources/tutorials/beginner/querying-network#querying-deploys",children:"querying deploys"})," for more information."]}),"\n",(0,c.jsx)(n.h2,{id:"verifying-the-transfer",children:"Verifying the Transfer"}),"\n",(0,c.jsxs)(n.p,{children:["In addition to verifying the deploy, you also need to ",(0,c.jsx)(n.a,{href:"/developers/cli/transfers/verify-transfer",children:"verify the transfer details"}),". The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly."]})]})}function l(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,c.jsx)(n,{...e,children:(0,c.jsx)(o,{...e})}):o(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>d,x:()=>t});var c=a(96540);const s={},r=c.createContext(s);function d(e){const n=c.useContext(r);return c.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function t(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),c.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1f89c2e.04046fd4.js b/assets/js/f1f89c2e.04046fd4.js deleted file mode 100644 index f7840458e..000000000 --- a/assets/js/f1f89c2e.04046fd4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2021],{24434:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var t=s(74848),a=s(28453);const c={title:"Calling Contracts"},r="Calling Smart Contracts with the Rust Client",i={id:"developers/cli/calling-contracts",title:"Calling Contracts",description:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.",source:"@site/versioned_docs/version-1.5.X/developers/cli/calling-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/calling-contracts",permalink:"/developers/cli/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Calling Contracts"},sidebar:"developers",previous:{title:"Querying Global State",permalink:"/developers/cli/querying-global-state"},next:{title:"OpCode Costs Tables",permalink:"/developers/cli/opcode-costs"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Calling Contracts by Contract Hash",id:"calling-contracts-by-hash",level:2},{value:"Calling Contracts with Session Arguments",id:"calling-contracts-with-session-args",level:2},{value:"Calling Contracts by Package Hash",id:"calling-contracts-by-package-hash",level:2},{value:"Calling Contracts by Contract Name",id:"calling-contracts-by-name",level:2},{value:"Calling Contracts by Package Name",id:"calling-contracts-by-package-name",level:2},{value:"Calling a Contract using Wasm",id:"calling-a-contract-using-wasm",level:2},{value:"Calling Contracts that Return a Value",id:"calling-contracts-that-return-a-value",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"calling-smart-contracts-with-the-rust-client",children:"Calling Smart Contracts with the Rust Client"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Each section below includes a short video demonstrating some example output."]}),"\n",(0,t.jsxs)(n.p,{children:["The following examples use two contracts on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," described while ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),". You will need to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"install this contract"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The Auction contract found in ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"this contract package"}),", already installed on Testnet as a system contract. The examples will call its ",(0,t.jsx)(n.code,{children:"delegate"})," entry point"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"send and verify deploys"})]}),"\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"install contracts and query global state"})," using the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," on Testnet if you have not done so already"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"system Auction contract"})," on Testnet"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-hash",children:"Calling Contracts by Contract Hash"}),"\n",(0,t.jsxs)(n.p,{children:["After ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts",children:"installing a contract"})," in global state, you can use the contract's hash to call one of its entry points. The following usage of ",(0,t.jsx)(n.code,{children:"put-deploy"})," allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name of the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Counter contract by hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.code,{children:"--session-hash"}),' option identifies a stored contract with an entry-point called "counter-inc".']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \\\n --session-entry-point "counter-inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.code,{children:"put-deploy"})," command is nearly identical to the command used to ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#installing-contract-code",children:"install the contract"}),". Here, instead of ",(0,t.jsx)(n.code,{children:"session-path"})," pointing to the Wasm binary, we have ",(0,t.jsx)(n.code,{children:"session-hash"})," and ",(0,t.jsx)(n.code,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn\u2019t return a value. If an entry point returns a value, use code to ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"interact with runtime return values"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The following sample response contains a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", needed to verify the changes in global state, as described ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'{\n "id": 1197172763279676268,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract by hash:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to query a previously installed Counter contract by hash."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=11",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-args",children:"Calling Contracts with Session Arguments"}),"\n",(0,t.jsxs)(n.p,{children:["When calling contract entry points, you may need to pass in information using session arguments. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command allows you to do this with the ",(0,t.jsx)(n.code,{children:"--session-arg"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-arg ["NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null"]...\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Auction contract using session arguments:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's entry point ",(0,t.jsx)(n.code,{children:"delegate"})," with three arguments:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"validator"})," is the public key of the validator to whom the tokens will be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"amount"})," is the number of tokens to be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"delegator"})," is the public key of the account delegating tokens to a validator"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To make the call, we use the contract hash, ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"}),", and the ",(0,t.jsx)(n.code,{children:"--session-hash"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract with session arguments:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to call a modified Counter contract using session arguments."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/XB_ojY1_0Uo",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-hash",children:"Calling Contracts by Package Hash"}),"\n",(0,t.jsxs)(n.p,{children:["You can also call an entry point in a contract that is part of a contract package (see ",(0,t.jsx)(n.a,{href:"/developers/writing-onchain-code/upgrading-contracts",children:"contract upgrades"}),"). Call ",(0,t.jsx)(n.code,{children:"put-deploy"})," using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-hash"})," - Hex-encoded hash of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter using the package hash and version:"})}),"\n",(0,t.jsx)(n.p,{children:'In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:"To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction using the package hash and version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's ",(0,t.jsx)(n.code,{children:"delegate"})," entry point by specifying the package hash using the ",(0,t.jsx)(n.code,{children:"--session-package-hash"})," option. The call defaults to the highest enabled version since no version was specified with the ",(0,t.jsx)(n.code,{children:"--session-version"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package hash:"})}),"\n",(0,t.jsx)(n.p,{children:"The video shows how to query the previously installed Counter contract package."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=15",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-name",children:"Calling Contracts by Contract Name"}),"\n",(0,t.jsxs)(n.p,{children:["We can also reference a contract using a key as the contract name. When you write the contract, use the ",(0,t.jsx)(n.code,{children:"put_key"})," function to add the ContractHash under the contract's ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html#",children:"NamedKeys"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Having a key enables you to call a contract's entry-point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-name"})," - Name of the stored contract (associated with the executing account) to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on ',(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/934a452ccba8c5cf12f8bde706736400e047fba5/contract-v1/src/main.rs#L110",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,t.jsx)(n.p,{children:'The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The sample response will contain a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", which you need to use as described ",(0,t.jsx)(n.a,{href:"/developers/cli/installing-contracts#querying-global-state",children:"here"})," to verify the changes in global state."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the system Auction contract stored in global state under the "auction" key and its ',(0,t.jsx)(n.code,{children:"delegate"})," entry point."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-name "auction" \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using a named key:"})}),"\n",(0,t.jsx)(n.p,{children:"This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=12",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-name",children:"Calling Contracts by Package Name"}),"\n",(0,t.jsxs)(n.p,{children:["To call an entry point in a contract by referencing the contract package name, you can use the ",(0,t.jsx)(n.code,{children:"session-package-name"}),", ",(0,t.jsx)(n.code,{children:"session-entry-point"}),", and ",(0,t.jsx)(n.code,{children:"session-version"})," arguments. This will enable you to access the entry point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name [NAMED_KEY_FOR_PACKAGE] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-name"})," - Name of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Specifying the package name and version number:"})}),"\n",(0,t.jsx)(n.p,{children:'This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.'}),"\n",(0,t.jsxs)(n.p,{children:["You should have previously created the contract by using ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),", and provided the contract package name as the ",(0,t.jsx)(n.code,{children:"hash_name"})," argument of ",(0,t.jsx)(n.code,{children:"new_contract"}),"."]}),"\n",(0,t.jsx)(n.p,{children:'This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' let (stored_contract_hash, contract_version) =\n storage::new_contract(counter_entry_points, \n Some(counter_named_keys), \n Some("counter_package_name".to_string()),\n Some("counter_access_uref".to_string())\n );\n'})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command to call the contract using the package name:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the package without specifying the version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call a contract that is part of the ",(0,t.jsx)(n.code,{children:"erc20_test_call"}),' package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper-client put-deploy \\\n --node-address http://3.143.158.19:7777 \\\n --chain-name integration-test \\\n --secret-key ~/casper/demo/user_a/secret_key.pem \\\n --payment-amount 1000000000 \\\n --session-package-name "erc20_test_call" \\\n --session-entry-point "check_balance_of" \\\n --session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n --session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package name:"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates how to call versioned contracts by package name."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=16",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-a-contract-using-wasm",children:"Calling a Contract using Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Session code or contract code (compiled to Wasm) can act on a contract and change its state. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command supports this mechanism as well:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/[FILE_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The argument of interest is:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Session code acting on a contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"})," shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"\ncasper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 25000000000 \\\n --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm\n\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using Wasm:"})}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=13",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-that-return-a-value",children:"Calling Contracts that Return a Value"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial to learn how to call a contract that returns a value using session code or contract code."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/counter",children:"Counter Contract Tutorial"})," takes you through a detailed walkthrough on how to query global state to verify a contract's state"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"/developers/cli/delegate",children:"Delegating with the Casper Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Look into the ",(0,t.jsx)(n.a,{href:"/resources/",children:"Resources for Smart Contract Authors"})]}),"\n",(0,t.jsxs)(n.li,{children:["See the ",(0,t.jsx)(n.a,{href:"/developers",children:"Developer How To Guides"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const a={},c=t.createContext(a);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f1f89c2e.2e307f65.js b/assets/js/f1f89c2e.2e307f65.js new file mode 100644 index 000000000..b73cb4d4c --- /dev/null +++ b/assets/js/f1f89c2e.2e307f65.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[62021],{24434:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>l});var t=s(74848),a=s(28453);const c={title:"Calling Contracts"},r="Calling Smart Contracts with the Rust Client",i={id:"developers/cli/calling-contracts",title:"Calling Contracts",description:"Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.",source:"@site/versioned_docs/version-1.5.X/developers/cli/calling-contracts.md",sourceDirName:"developers/cli",slug:"/developers/cli/calling-contracts",permalink:"/1.5.X/developers/cli/calling-contracts",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Calling Contracts"},sidebar:"developers",previous:{title:"Querying Global State",permalink:"/1.5.X/developers/cli/querying-global-state"},next:{title:"OpCode Costs Tables",permalink:"/1.5.X/developers/cli/opcode-costs"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Calling Contracts by Contract Hash",id:"calling-contracts-by-hash",level:2},{value:"Calling Contracts with Session Arguments",id:"calling-contracts-with-session-args",level:2},{value:"Calling Contracts by Package Hash",id:"calling-contracts-by-package-hash",level:2},{value:"Calling Contracts by Contract Name",id:"calling-contracts-by-name",level:2},{value:"Calling Contracts by Package Name",id:"calling-contracts-by-package-name",level:2},{value:"Calling a Contract using Wasm",id:"calling-a-contract-using-wasm",level:2},{value:"Calling Contracts that Return a Value",id:"calling-contracts-that-return-a-value",level:2},{value:"What's Next?",id:"whats-next",level:2}];function d(e){const n={a:"a",admonition:"admonition",br:"br",code:"code",details:"details",em:"em",h1:"h1",h2:"h2",header:"header",iframe:"iframe",li:"li",p:"p",pre:"pre",strong:"strong",summary:"summary",ul:"ul",...(0,a.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.p,{children:"import useBaseUrl from '@docusaurus/useBaseUrl';"}),"\n",(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"calling-smart-contracts-with-the-rust-client",children:"Calling Smart Contracts with the Rust Client"})}),"\n",(0,t.jsxs)(n.p,{children:["Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper command-line client"})," and the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command. Each section below includes a short video demonstrating some example output."]}),"\n",(0,t.jsxs)(n.p,{children:["The following examples use two contracts on ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Testnet"}),":"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," described while ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/simple-contract",children:"Writing a Basic Smart Contract in Rust"}),". You will need to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install this contract"})," on Testnet"]}),"\n",(0,t.jsxs)(n.li,{children:["The Auction contract found in ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"this contract package"}),", already installed on Testnet as a system contract. The examples will call its ",(0,t.jsx)(n.code,{children:"delegate"})," entry point"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"send and verify deploys"})]}),"\n",(0,t.jsxs)(n.li,{children:["You know how to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"install contracts and query global state"})," using the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"default Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Install the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/master/contract-v1/src/main.rs",children:"Counter contract"})," on Testnet if you have not done so already"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/contract-package/e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9",children:"system Auction contract"})," on Testnet"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-hash",children:"Calling Contracts by Contract Hash"}),"\n",(0,t.jsxs)(n.p,{children:["After ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts",children:"installing a contract"})," in global state, you can use the contract's hash to call one of its entry points. The following usage of ",(0,t.jsx)(n.code,{children:"put-deploy"})," allows you to call an entry point and receive a deploy hash. The hash is needed to verify that the deploy was processed successfully."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments used above are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chain-name"})," - The chain name of the network where you wish to send the deploy. For Mainnet, use ",(0,t.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,t.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the deploy"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"payment-amount"})," - The payment for the deploy in motes"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Counter contract by hash:"})}),"\n",(0,t.jsxs)(n.p,{children:["In this example, the ",(0,t.jsx)(n.code,{children:"--session-hash"}),' option identifies a stored contract with an entry-point called "counter-inc".']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-hash hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e \\\n --session-entry-point "counter-inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["This ",(0,t.jsx)(n.code,{children:"put-deploy"})," command is nearly identical to the command used to ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts#installing-contract-code",children:"install the contract"}),". Here, instead of ",(0,t.jsx)(n.code,{children:"session-path"})," pointing to the Wasm binary, we have ",(0,t.jsx)(n.code,{children:"session-hash"})," and ",(0,t.jsx)(n.code,{children:"session-entry-point"})," identifying the on-chain contract and its associated entry point. No Wasm file is needed in this example since the contract is already on the blockchain, and the entry point doesn\u2019t return a value. If an entry point returns a value, use code to ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"interact with runtime return values"}),"."]}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsxs)(n.p,{children:["The payment amount varies based on each deploy and network ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"}),"."]})}),"\n",(0,t.jsxs)(n.p,{children:["The following sample response contains a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", needed to verify the changes in global state, as described ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts#querying-global-state",children:"here"}),"."]}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'{\n "id": 1197172763279676268,\n "jsonrpc": "2.0",\n "result": {\n "api_version": "1.4.5",\n "deploy_hash": "24b58fbc0cbbfa3be978e7b78b9b37fc1d17c887b1abed2b2e2e704f7ee5427c"\n }\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.br,{}),(0,t.jsx)(n.br,{}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract by hash:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to query a previously installed Counter contract by hash."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=11",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-with-session-args",children:"Calling Contracts with Session Arguments"}),"\n",(0,t.jsxs)(n.p,{children:["When calling contract entry points, you may need to pass in information using session arguments. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command allows you to do this with the ",(0,t.jsx)(n.code,{children:"--session-arg"})," option:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-arg ["NAME:TYPE=\'VALUE\'" OR "NAME:TYPE=null"]...\n'})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored contract to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-arg"})," - For simple CLTypes, a named and typed arg is passed to the Wasm code. To see an example for each type, run: 'casper-client put-deploy --show-arg-examples'"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Calling the Auction contract using session arguments:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's entry point ",(0,t.jsx)(n.code,{children:"delegate"})," with three arguments:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"validator"})," is the public key of the validator to whom the tokens will be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"amount"})," is the number of tokens to be delegated"]}),"\n",(0,t.jsxs)(n.li,{children:["The argument ",(0,t.jsx)(n.code,{children:"delegator"})," is the public key of the account delegating tokens to a validator"]}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["To make the call, we use the contract hash, ",(0,t.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"}),", and the ",(0,t.jsx)(n.code,{children:"--session-hash"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract with session arguments:"})}),"\n",(0,t.jsx)(n.p,{children:"This video shows how to call a modified Counter contract using session arguments."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed/XB_ojY1_0Uo",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-hash",children:"Calling Contracts by Package Hash"}),"\n",(0,t.jsxs)(n.p,{children:["You can also call an entry point in a contract that is part of a contract package (see ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/writing-onchain-code/upgrading-contracts",children:"contract upgrades"}),"). Call ",(0,t.jsx)(n.code,{children:"put-deploy"})," using the stored package hash, the entry point you wish to access, the contract version number, and any runtime arguments. The call defaults to the highest enabled version if no version was specified."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-hash [HEX_STRING] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-hash"})," - Hex-encoded hash of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter using the package hash and version:"})}),"\n",(0,t.jsx)(n.p,{children:'In this example, we call the Counter contract by its package hash and version number. The entry point invoked is "counter-inc".'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-hash hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:"To find the contract package hash, look at the account's named keys associated with the contract. Here is an example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",\n "name": "counter_package_name"\n}\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction using the package hash and version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call the Auction contract's ",(0,t.jsx)(n.code,{children:"delegate"})," entry point by specifying the package hash using the ",(0,t.jsx)(n.code,{children:"--session-package-hash"})," option. The call defaults to the highest enabled version since no version was specified with the ",(0,t.jsx)(n.code,{children:"--session-version"})," option."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-package-hash hash-e375d42c29c0e4b2baefa63cf2d70af34439eda851e08129d8515515d63bd6a9 \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package hash:"})}),"\n",(0,t.jsx)(n.p,{children:"The video shows how to query the previously installed Counter contract package."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=15",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-name",children:"Calling Contracts by Contract Name"}),"\n",(0,t.jsxs)(n.p,{children:["We can also reference a contract using a key as the contract name. When you write the contract, use the ",(0,t.jsx)(n.code,{children:"put_key"})," function to add the ContractHash under the contract's ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-types/latest/casper_types/contracts/type.NamedKeys.html#",children:"NamedKeys"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["Having a key enables you to call a contract's entry-point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-name [NAMED_KEY_FOR_SMART_CONTRACT] \\\n --session-entry-point [ENTRY_POINT_FUNCTION]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-name"})," - Name of the stored contract (associated with the executing account) to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Calling the Counter contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the Counter contract stored in global state under the "counter" named key. The code stores the ContractHash into a URef, which can be referenced once the contract is installed in global state. The full implementation is available on ',(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/counter/blob/934a452ccba8c5cf12f8bde706736400e047fba5/contract-v1/src/main.rs#L110",children:"GitHub"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());\n"})}),"\n",(0,t.jsx)(n.p,{children:'The following command invokes the entry point "counter_inc" and the contract stored under the "counter" named key.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-name "counter" \\\n --session-entry-point "counter_inc"\n'})}),"\n",(0,t.jsxs)(n.p,{children:["The sample response will contain a ",(0,t.jsx)(n.code,{children:"deploy_hash"}),", which you need to use as described ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/installing-contracts#querying-global-state",children:"here"})," to verify the changes in global state."]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the Auction contract using a named key:"})}),"\n",(0,t.jsxs)(n.p,{children:['This example uses the system Auction contract stored in global state under the "auction" key and its ',(0,t.jsx)(n.code,{children:"delegate"})," entry point."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 2500000000 \\\n --session-name "auction" \\\n --session-entry-point "delegate" \\\n --session-arg "validator:public_key=\'0145fb72c75e1b459839555d70356a5e6172e706efa204d86c86050e2f7878960f\'" \\\n --session-arg "amount:u512=\'500000000000\'" \\\n --session-arg "delegator:public_key=\'0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf\'"\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using a named key:"})}),"\n",(0,t.jsx)(n.p,{children:"This short video shows how to query the previously installed Counter contract using a named key, which is the name used to reference the contract."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=12",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-by-package-name",children:"Calling Contracts by Package Name"}),"\n",(0,t.jsxs)(n.p,{children:["To call an entry point in a contract by referencing the contract package name, you can use the ",(0,t.jsx)(n.code,{children:"session-package-name"}),", ",(0,t.jsx)(n.code,{children:"session-entry-point"}),", and ",(0,t.jsx)(n.code,{children:"session-version"})," arguments. This will enable you to access the entry point in global state by using the ",(0,t.jsx)(n.code,{children:"put-deploy"})," command as illustrated here:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-package-name [NAMED_KEY_FOR_PACKAGE] \\\n --session-entry-point [ENTRY_POINT_FUNCTION] \\\n --session-version [INTEGER]\n"})}),"\n",(0,t.jsx)(n.p,{children:"The arguments of interest are:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-package-name"})," - Name of the stored package to be called as the session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-entry-point"})," - Name of the method that will be used when calling the session contract"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-version"})," - Version of the called session contract. The latest will be used by default"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 1 - Specifying the package name and version number:"})}),"\n",(0,t.jsx)(n.p,{children:'This example calls the entry point "counter-inc" as part of the contract package name "counter_package_name", version 1, without any runtime arguments.'}),"\n",(0,t.jsxs)(n.p,{children:["You should have previously created the contract by using ",(0,t.jsx)(n.a,{href:"https://docs.rs/casper-contract/latest/casper_contract/contract_api/storage/fn.new_contract.html",children:"new_contract"}),", and provided the contract package name as the ",(0,t.jsx)(n.code,{children:"hash_name"})," argument of ",(0,t.jsx)(n.code,{children:"new_contract"}),"."]}),"\n",(0,t.jsx)(n.p,{children:'This example code stores the "contract_package_name" into a NamedKey, which you can reference once you install the contract in global state.'}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' let (stored_contract_hash, contract_version) =\n storage::new_contract(counter_entry_points, \n Some(counter_named_keys), \n Some("counter_package_name".to_string()),\n Some("counter_access_uref".to_string())\n );\n'})}),"\n",(0,t.jsx)(n.p,{children:"Here is the command to call the contract using the package name:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:'casper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount 100000000 \\\n --session-package-name "counter_package_name" \\\n --session-entry-point "counter-inc" \\\n --session-version 1\n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example 2 - Calling the package without specifying the version:"})}),"\n",(0,t.jsxs)(n.p,{children:["This example demonstrates how to call a contract that is part of the ",(0,t.jsx)(n.code,{children:"erc20_test_call"}),' package using runtime arguments. The call invokes the "check_balance_of" entry point and defaults to the highest enabled version since no version was specified.']}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:' casper-client put-deploy \\\n --node-address http://3.143.158.19:7777 \\\n --chain-name integration-test \\\n --secret-key ~/casper/demo/user_a/secret_key.pem \\\n --payment-amount 1000000000 \\\n --session-package-name "erc20_test_call" \\\n --session-entry-point "check_balance_of" \\\n --session-arg "token_contract:account_hash=\'account-hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180\'" \\\n --session-arg "address:key=\'account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd\'" \n'})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using the package name:"})}),"\n",(0,t.jsx)(n.p,{children:"This video demonstrates how to call versioned contracts by package name."}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=16",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-a-contract-using-wasm",children:"Calling a Contract using Wasm"}),"\n",(0,t.jsxs)(n.p,{children:["Session code or contract code (compiled to Wasm) can act on a contract and change its state. The ",(0,t.jsx)(n.code,{children:"put-deploy"})," command supports this mechanism as well:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"casper-client put-deploy \\\n --node-address [NODE_SERVER_ADDRESS] \\\n --chain-name [CHAIN_NAME] \\\n --secret-key [KEY_PATH]/secret_key.pem \\\n --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \\\n --session-path [PATH]/[FILE_NAME].wasm\n"})}),"\n",(0,t.jsx)(n.p,{children:"The argument of interest is:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"session-path"})," - The path to the compiled Wasm on your computer"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Example - Session code acting on a contract:"})}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/counter",children:"Counter Contract Tutorial"})," shows how to change the state of a contract (counter-v1.wasm) using session code (counter-call.wasm)."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-rust",children:"\ncasper-client put-deploy \\\n --node-address http://65.21.235.219:7777 \\\n --chain-name casper-test \\\n --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \\\n --payment-amount 25000000000 \\\n --session-path [PATH_TO_YOUR_COMPILED_WASM]/counter-call.wasm\n\n"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Video - Calling a contract using Wasm:"})}),"\n",(0,t.jsxs)(n.p,{align:"center",children:["\n",(0,t.jsx)(n.iframe,{width:"400",height:"225",src:"https://www.youtube.com/embed?v=sUg0nh3K3iQ&list=PL8oWxbJ-csEqi5FP87EJZViE2aLz6X1Mj&index=13",frameBorder:"0",allow:"accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture",allowFullScreen:!0}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"calling-contracts-that-return-a-value",children:"Calling Contracts that Return a Value"}),"\n",(0,t.jsxs)(n.p,{children:["Visit the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tutorials/advanced/return-values-tutorial",children:"Interacting with Runtime Return Values"})," tutorial to learn how to call a contract that returns a value using session code or contract code."]}),"\n",(0,t.jsx)(n.h2,{id:"whats-next",children:"What's Next?"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["The ",(0,t.jsx)(n.a,{href:"/1.5.X/counter",children:"Counter Contract Tutorial"})," takes you through a detailed walkthrough on how to query global state to verify a contract's state"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn more about ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/delegate",children:"Delegating with the Casper Client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Look into the ",(0,t.jsx)(n.a,{href:"/resources/",children:"Resources for Smart Contract Authors"})]}),"\n",(0,t.jsxs)(n.li,{children:["See the ",(0,t.jsx)(n.a,{href:"/developers",children:"Developer How To Guides"})]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>r,x:()=>i});var t=s(96540);const a={},c=t.createContext(a);function r(e){const n=t.useContext(c);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),t.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f203f57a.c10ab2eb.js b/assets/js/f203f57a.c10ab2eb.js new file mode 100644 index 000000000..3691c7744 --- /dev/null +++ b/assets/js/f203f57a.c10ab2eb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[84063],{59784:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=i(74848),t=i(28453);const a={title:"Runtime",slug:"/runtime"},o="Runtime Economics",r={id:"concepts/economics/runtime",title:"Runtime",description:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:",source:"@site/versioned_docs/version-2.0.0/concepts/economics/runtime.md",sourceDirName:"concepts/economics",slug:"/runtime",permalink:"/2.0.0/runtime",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Runtime",slug:"/runtime"},sidebar:"concepts",previous:{title:"Consensus",permalink:"/2.0.0/concepts/economics/consensus"},next:{title:"Gas Cost",permalink:"/2.0.0/concepts/economics/gas-concepts"}},c={},l=[{value:"Gas Allocation",id:"gas-allocation",level:2},{value:"Consensus before execution & basics of payment",id:"consensus-before-execution-basics-of-payment",level:3},{value:"Costs and limits",id:"costs-and-limits",level:3},{value:"Lanes and gas costs",id:"lanes",level:3},{value:"Dynamic Gas Pricing",id:"dynamic-gas-pricing",level:2},{value:"Eliminating Gas Fees",id:"gas-fees",level:2}];function d(e){const n={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"runtime-economics",children:"Runtime Economics"})}),"\n",(0,s.jsx)(n.p,{children:"The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]}),"\n",(0,s.jsxs)(n.li,{children:["A form of ",(0,s.jsx)(n.a,{href:"#dynamic-gas-pricing",children:"dynamic pricing"})," that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era."]}),"\n",(0,s.jsxs)(n.li,{children:["Blocks are structured into ",(0,s.jsx)(n.a,{href:"#lanes-lanes",children:"lanes"})," that can only hold a particular number of transactions of specified types."]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These economic features are configurable using chainspec parameters."}),"\n",(0,s.jsx)(n.h2,{id:"gas-allocation",children:"Gas Allocation"}),"\n",(0,s.jsxs)(n.p,{children:["Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/gas-concepts",children:"gas"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant ",(0,s.jsx)(n.a,{href:"https://github.com/casper-network/ceps",children:"CEPs"}),". In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model."]}),"\n",(0,s.jsx)(n.h3,{id:"consensus-before-execution-basics-of-payment",children:"Consensus before execution & basics of payment"}),"\n",(0,s.jsx)(n.p,{children:"The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas."}),"\n",(0,s.jsx)(n.p,{children:"Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future."}),"\n",(0,s.jsx)(n.h3,{id:"costs-and-limits",children:"Costs and limits"}),"\n",(0,s.jsxs)(n.p,{children:["Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex ",(0,s.jsx)(n.em,{children:"host-side"})," functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec"})," and may vary according to arguments. Read more about how Casper measures computational work ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"here"}),"."]}),"\n",(0,s.jsx)(n.p,{children:"We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades."}),"\n",(0,s.jsx)(n.h3,{id:"lanes",children:"Lanes and gas costs"}),"\n",(0,s.jsx)(n.p,{children:"There are several platform parameters that delineate the sets of transactions that may be included in a valid block:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Number of lanes and lane types"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"System interaction lanes for Mint (transfers) and Auction transactions."}),"\n",(0,s.jsx)(n.li,{children:"WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction."}),"\n",(0,s.jsx)(n.li,{children:"All lanes can contain some finite number of transactions, set separately for each lane."}),"\n",(0,s.jsx)(n.li,{children:"For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time."}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Block gas and size limits"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots."}),"\n",(0,s.jsx)(n.li,{children:"The block size limit imposes an absolute ceiling on the total byte size of included transactions."}),"\n",(0,s.jsx)(n.li,{children:"Individual transaction size limits are also enforced."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"These are the lane configuration settings for the Condor release on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[transactions.v1]\n# The configuration settings for the lanes of transactions including both native and Wasm based interactions.\n# Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1\n# respectively\n# The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction\n# within a given lane.\n# The maximum length in bytes of runtime args per V1 transaction.\n# [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)\n# Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and\n# the lane must be present and defined.\n# Different casper networks may not impose such a restriction.\n# [1] -> Max transaction size in bytes for a given transaction in a certain lane\n# [2] -> Max args length size in bytes for a given transaction in a certain lane\n# [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane\n# [4] -> The maximum number of transactions the lane can contain\nnative_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]\nnative_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]\nwasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]\n"})}),"\n",(0,s.jsx)(n.p,{children:"These are the block gas and size limits for the Condor release on Mainnet:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-toml",children:"[transactions]\n...\n# Maximum block size in bytes including transactions contained by the block. 0 means unlimited.\nmax_block_size = 5_242_880\n# The upper limit of total gas of all transactions in a block.\nblock_gas_limit = 3_300_000_000_000\n"})}),"\n",(0,s.jsx)(n.h2,{id:"dynamic-gas-pricing",children:"Dynamic Gas Pricing"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack."]}),"\n",(0,s.jsx)(n.h2,{id:"gas-fees",children:"Eliminating Gas Fees"}),"\n",(0,s.jsxs)(n.p,{children:["See ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/gas-concepts",children:"Gas"})," and ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/economics/fee-elimination",children:"Fee Elimination"})," for more details."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(d,{...e})}):d(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>r});var s=i(96540);const t={},a=s.createContext(t);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f224ad82.becdd6c1.js b/assets/js/f224ad82.becdd6c1.js new file mode 100644 index 000000000..85cbded70 --- /dev/null +++ b/assets/js/f224ad82.becdd6c1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[75932],{51630:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>a,default:()=>h,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(74848),s=n(28453);const r={},a="Binary Serialization Standard {#serialization-standard-head}",o={id:"concepts/serialization/index",title:"Binary Serialization Standard",description:"serialization-standard-head}",source:"@site/versioned_docs/version-2.0.0/concepts/serialization/index.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/",permalink:"/2.0.0/concepts/serialization/",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Z",permalink:"/2.0.0/concepts/glossary/Z"},next:{title:"Primitives and Basic Serialization Rules",permalink:"/2.0.0/concepts/serialization/primitives"}},d={},c=[];function l(e){const t={a:"a",code:"code",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"serialization-standard-head",children:"Binary Serialization Standard"})}),"\n",(0,i.jsx)(t.p,{children:"We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization."}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"Casper Binary Serialization Standard"})," uses a default ",(0,i.jsx)(t.code,{children:"u8"})," byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories."]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,i.jsxs)(t.table,{children:[(0,i.jsx)(t.thead,{children:(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.th,{children:"Page"}),(0,i.jsx)(t.th,{children:"Description"})]})}),(0,i.jsxs)(t.tbody,{children:[(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/2.0.0/concepts/serialization/primitives",children:"Primitives"})}),(0,i.jsx)(t.td,{children:"Base-level types used to create more complex structures."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/2.0.0/concepts/serialization/structures",children:"Structures"})}),(0,i.jsx)(t.td,{children:"Major structures used through Casper systems, as well as their included sub-types."})]}),(0,i.jsxs)(t.tr,{children:[(0,i.jsx)(t.td,{children:(0,i.jsx)(t.a,{href:"/2.0.0/concepts/serialization/types",children:"Types"})}),(0,i.jsxs)(t.td,{children:["Minor types not covered ",(0,i.jsx)(t.code,{children:"Primitives"})," or ",(0,i.jsx)(t.code,{children:"Structures"}),"."]})]})]})]})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>a,x:()=>o});var i=n(96540);const s={},r=i.createContext(s);function a(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:a(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2779c45.1985fa4b.js b/assets/js/f2779c45.1985fa4b.js new file mode 100644 index 000000000..1f7ed4710 --- /dev/null +++ b/assets/js/f2779c45.1985fa4b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[74192],{54770:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(74848),o=t(28453);const a={},s="Guidance for JSON-RPC SDK Compliance",r={id:"developers/json-rpc/guidance",title:"Guidance for JSON-RPC SDK Compliance",description:"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.",source:"@site/docs/developers/json-rpc/guidance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/guidance",permalink:"/developers/json-rpc/guidance",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/developers/json-rpc/"},next:{title:"Required Methods for Minimal Compliance",permalink:"/developers/json-rpc/minimal-compliance"}},l={},c=[{value:"Consistency",id:"consistency",level:2},{value:"Advanced Functionality",id:"advanced-functionality",level:2}];function d(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"guidance-for-json-rpc-sdk-compliance",children:"Guidance for JSON-RPC SDK Compliance"})}),"\n",(0,i.jsxs)(n.p,{children:["A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the ",(0,i.jsx)(n.a,{href:"/developers/json-rpc/json-rpc-informational",children:"informational JSON-RPC methods"})," page."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["A Casper JSON-RPC SDK claiming to be complete is expected to implement ",(0,i.jsx)(n.em,{children:"all"})," endpoints and ",(0,i.jsx)(n.em,{children:"all"})," types defined in the serialization standard."]})}),"\n",(0,i.jsx)(n.h2,{id:"consistency",children:"Consistency"}),"\n",(0,i.jsx)(n.p,{children:"A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet."}),"\n",(0,i.jsx)(n.p,{children:"Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-functionality",children:"Advanced Functionality"}),"\n",(0,i.jsx)(n.p,{children:"SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations."}),"\n",(0,i.jsx)(n.p,{children:"However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience."}),"\n",(0,i.jsx)(n.p,{children:"For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2779c45.270e5772.js b/assets/js/f2779c45.270e5772.js deleted file mode 100644 index 230d765b1..000000000 --- a/assets/js/f2779c45.270e5772.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4192],{54770:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var i=t(74848),o=t(28453);const a={},s="Guidance for JSON-RPC SDK Compliance",r={id:"developers/json-rpc/guidance",title:"Guidance for JSON-RPC SDK Compliance",description:"A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.",source:"@site/docs/developers/json-rpc/guidance.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/guidance",permalink:"/next/developers/json-rpc/guidance",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{},sidebar:"developers",previous:{title:"Overview",permalink:"/next/developers/json-rpc/"},next:{title:"Required Methods for Minimal Compliance",permalink:"/next/developers/json-rpc/minimal-compliance"}},l={},c=[{value:"Consistency",id:"consistency",level:2},{value:"Advanced Functionality",id:"advanced-functionality",level:2}];function d(e){const n={a:"a",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"guidance-for-json-rpc-sdk-compliance",children:"Guidance for JSON-RPC SDK Compliance"})}),"\n",(0,i.jsxs)(n.p,{children:["A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the ",(0,i.jsx)(n.a,{href:"/next/developers/json-rpc/json-rpc-informational",children:"informational JSON-RPC methods"})," page."]}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsxs)(n.strong,{children:["A Casper JSON-RPC SDK claiming to be complete is expected to implement ",(0,i.jsx)(n.em,{children:"all"})," endpoints and ",(0,i.jsx)(n.em,{children:"all"})," types defined in the serialization standard."]})}),"\n",(0,i.jsx)(n.h2,{id:"consistency",children:"Consistency"}),"\n",(0,i.jsx)(n.p,{children:"A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet."}),"\n",(0,i.jsx)(n.p,{children:"Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK."}),"\n",(0,i.jsx)(n.h2,{id:"advanced-functionality",children:"Advanced Functionality"}),"\n",(0,i.jsx)(n.p,{children:"SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations."}),"\n",(0,i.jsx)(n.p,{children:"However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience."}),"\n",(0,i.jsx)(n.p,{children:"For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform."})]})}function p(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>s,x:()=>r});var i=t(96540);const o={},a=i.createContext(o);function s(e){const n=i.useContext(a);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2a77c75.4e76bee9.js b/assets/js/f2a77c75.4e76bee9.js new file mode 100644 index 000000000..d71acc496 --- /dev/null +++ b/assets/js/f2a77c75.4e76bee9.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[80277],{93666:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>a,metadata:()=>r,toc:()=>l});var s=t(74848),i=t(28453);const a={},o="Redelegating Tokens with the Casper Client",r={id:"developers/cli/redelegate",title:"Redelegating Tokens with the Casper Client",description:"This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.",source:"@site/versioned_docs/version-2.0.0/developers/cli/redelegate.md",sourceDirName:"developers/cli",slug:"/developers/cli/redelegate",permalink:"/2.0.0/developers/cli/redelegate",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Delegating Tokens",permalink:"/2.0.0/developers/cli/delegate"},next:{title:"Undelegating Tokens",permalink:"/2.0.0/developers/cli/undelegate"}},d={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Method 1: Redelegating with the System Auction Contract",id:"redelegating-system-auction",level:2},{value:"Method 2: Redelegating with Compiled Wasm",id:"bonding-compiled-wasm",level:2},{value:"Sending the redelegation request",id:"sending-the-redelegation-deploy",level:3},{value:"Verifying the Redelegation",id:"verifying-the-redelegation",level:2}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"redelegating-tokens-with-the-casper-client",children:"Redelegating Tokens with the Casper Client"})}),"\n",(0,s.jsxs)(n.p,{children:["This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/undelegate",children:"unbonding request"})," first and then ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"delegate"})," the tokens to the new validator."]}),"\n",(0,s.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["You meet all ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/prerequisites",children:"prerequisites"}),", including having a valid ",(0,s.jsx)(n.code,{children:"node-address"})," and the Casper command-line client"]}),"\n",(0,s.jsxs)(n.li,{children:["You have ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate",children:"delegated tokens"})," to a validator on a Casper network, and you have the validator's public key"]}),"\n",(0,s.jsxs)(n.li,{children:["You have the public key of the new validator to whom you wish to redelegate tokens. See ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate#acquiring-a-validators-public-key",children:"Acquiring a Validator's Public Key"})," for more details"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"redelegating-system-auction",children:"Method 1: Redelegating with the System Auction Contract"}),"\n",(0,s.jsxs)(n.p,{children:["This method calls the existing ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point from the system auction contract. Using this method, you do not need to build contracts, reducing cost and complexity."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount 2500000000 \\\n--session-hash <SESSION_HASH> \\\n--session-entry-point redelegate \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-hash"})," - Hex-encoded hash of the stored auction contract, which depends on the network you are using. For Casper's Mainnet and Testnet, the hashes are as follows:"]}),"\n"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Testnet"}),": ",(0,s.jsx)(n.code,{children:"hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.strong,{children:"Mainnet"}),": ",(0,s.jsx)(n.code,{children:"hash-ccb576d6ce6dec84a551e48f0d0b7af89ddba44c7390b690036257a04a3ae9ea"})]}),"\n"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-entry-point"})," - Name of the entrypoint that will be used when calling the contract"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"7",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"The command will return a deploy hash, which is needed to verify the deploy's processing results."}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entry point on the auction contract has a fixed cost of 2.5 CSPR and there is a minimum delegation amount of 500 CSPR that also applies to redelegations."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 2.5 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 2500000000 \\\n--session-hash hash-e22d38bcf3454a93face78a353feaccbf1d637d1ef9ef2e061a655728ff59bbe \\\n--session-entry-point redelegate \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsxs)(n.p,{children:["Next, ",(0,s.jsx)(n.a,{href:"#verifying-the-redelegation",children:"verify the redelegation"}),"."]}),"\n",(0,s.jsx)(n.h2,{id:"bonding-compiled-wasm",children:"Method 2: Redelegating with Compiled Wasm"}),"\n",(0,s.jsxs)(n.p,{children:["Another way to send a redelegation is to compile the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," and send it to the network via a deploy. To compile the Wasm yourself, ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate#building-the-delegation-wasm",children:"build the casper-node contracts"})," that will include the redelegation Wasm."]}),"\n",(0,s.jsx)(n.h3,{id:"sending-the-redelegation-deploy",children:"Sending the redelegation request"}),"\n",(0,s.jsx)(n.p,{children:"We recommend testing the following steps on the official Testnet before performing them in a live environment like the Casper Mainnet."}),"\n",(0,s.jsxs)(n.p,{children:["This example uses the Casper client to send a deploy containing the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," to the network to initiate the redelegation process."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address <HOST:PORT> \\\n--secret-key <PATH_TO_DELEGATOR_SECRET_KEY> \\\n--chain-name <CHAIN_NAME> \\\n--payment-amount <PAYMENT_AMOUNT> \\\n--session-path <PATH_TO_WASM>/redelegate.wasm \\\n--session-arg \"delegator:public_key='<DELEGATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"validator:public_key='<CURRENT_VALIDATOR_PUBLIC_KEY_HEX>'\" \\\n--session-arg \"amount:u512='<DELEGATION_AMOUNT>'\" \\\n--session-arg \"new_validator:public_key='<NEW_VALIDATOR_PUBLIC_KEY_HEX>'\"\n"})}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"node-address"})," - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"secret-key"})," - The file name containing the secret key of the account paying for the Deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"chain-name"})," - The chain-name to the network where you wish to send the Deploy. For Mainnet, use ",(0,s.jsx)(n.em,{children:"casper"}),". For Testnet, use ",(0,s.jsx)(n.em,{children:"casper-test"})]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"payment-amount"})," - The payment for the Deploy in motes. This entry point call needs 2.5 CSPR"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"session-path"})," - The path to the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," on your computer"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," expects four arguments:"]}),"\n",(0,s.jsxs)(n.ol,{start:"6",children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"delegator:public_key"}),": The hexadecimal public key of the account submitting the redelegate request. This key must match the secret key that signs the deploy"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"validator:public_key"}),": The hexadecimal public key of the validator from whom the tokens will be undelegated"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"amount"}),": The amount to be redelegated to the new validator"]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"new_validator:public_key"}),": The hexadecimal public key of the validator to whom the tokens will be delegated"]}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["Save the returned ",(0,s.jsx)(n.em,{children:"deploy_hash"})," from the output to ",(0,s.jsx)(n.a,{href:"/2.0.0/resources/tutorials/beginner/querying-network#querying-deploys",children:"query information"})," about the redelegation Deploy."]}),"\n",(0,s.jsx)(n.admonition,{type:"note",children:(0,s.jsxs)(n.p,{children:["Running the ",(0,s.jsx)(n.code,{children:"redelegate.wasm"})," is a more expensive operation than calling the ",(0,s.jsx)(n.code,{children:"redelegate"})," entrypoint from the system auction contract."]})}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Example:"})}),"\n",(0,s.jsxs)(n.p,{children:["This example uses a private network running ",(0,s.jsx)(n.code,{children:"casper-node"})," version 1.5. The payment amount specified is 8 CSPR. You must modify the payment and other values in the deploy based on the network's ",(0,s.jsx)(n.a,{href:"/2.0.0/concepts/glossary/C#chainspec",children:"chainspec.toml"}),"."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-bash",children:"casper-client put-deploy \\\n--node-address http://3.143.158.19:7777 \\\n--chain-name integration-test \\\n--secret-key ~/KEYS/integration/Test_secret_key.pem \\\n--payment-amount 8000000000 \\\n--session-path ~/redelegate.wasm \\\n--session-arg \"validator:public_key='017fec504c642f2b321b8591f1c3008348c57a81acafceb5a392cf8416a5fb4a3c'\" \\\n--session-arg \"amount:u512='500000000000'\" \\\n--session-arg \"delegator:public_key='01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986'\" \\\n--session-arg \"new_validator:public_key='019e7b8bdec03ba83be4f5443d9f7f9111c77fec984ce9bb5bb7eb3da1e689c02d'\"\n"})}),"\n",(0,s.jsx)(n.h2,{id:"verifying-the-redelegation",children:"Verifying the Redelegation"}),"\n",(0,s.jsx)(n.p,{children:"The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy."}),"\n",(0,s.jsx)(n.p,{children:"Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator."}),"\n",(0,s.jsxs)(n.p,{children:["Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as ",(0,s.jsx)(n.a,{href:"/2.0.0/developers/cli/delegate#confirming-the-delegation",children:"verifying a delegation request"})," using the ",(0,s.jsx)(n.code,{children:"casper-client get-auction-info"})," command."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>r});var s=t(96540);const i={},a=s.createContext(i);function o(e){const n=s.useContext(a);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),s.createElement(a.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f2e157d0.d49d6620.js b/assets/js/f2e157d0.d49d6620.js new file mode 100644 index 000000000..351f083ab --- /dev/null +++ b/assets/js/f2e157d0.d49d6620.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4301],{10642:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>p,frontMatter:()=>i,metadata:()=>r,toc:()=>d});var a=n(74848),s=n(28453);const i={title:"What is a dApp?"},o="What is a dApp?",r={id:"developers/dapps/dapp",title:"What is a dApp?",description:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.",source:"@site/versioned_docs/version-2.0.0/developers/dapps/dapp.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/dapp",permalink:"/2.0.0/developers/dapps/dapp",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"What is a dApp?"},sidebar:"developers",previous:{title:"Overview of Casper dApps",permalink:"/2.0.0/developers/dapps/"},next:{title:"Prerequisites",permalink:"/2.0.0/developers/dapps/prerequisites"}},c={},d=[{value:"How are Decentralized Applications Different?",id:"how-are-decentralized-applications-different",level:2},{value:"Interacting with a Decentralized Network",id:"interacting-with-a-decentralized-network",level:2}];function l(e){const t={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",header:"header",p:"p",...(0,s.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.header,{children:(0,a.jsx)(t.h1,{id:"what-is-a-dapp",children:"What is a dApp?"})}),"\n",(0,a.jsx)(t.p,{children:"A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network."}),"\n",(0,a.jsx)(t.p,{children:"The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself."}),"\n",(0,a.jsx)(t.h2,{id:"how-are-decentralized-applications-different",children:"How are Decentralized Applications Different?"}),"\n",(0,a.jsxs)(t.p,{children:["A decentralized system consists of a group of interchangeable machines that can perform as a full system or ",(0,a.jsx)(t.code,{children:"distributed database"}),". Additional machines strengthen the overall system by adding redundancy and computational power."]}),"\n",(0,a.jsxs)(t.p,{children:["Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a ",(0,a.jsx)(t.a,{href:"https://cspr.live/tools/peers",children:"node"}),". The ",(0,a.jsx)(t.code,{children:"decentralized"})," aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality."]}),"\n",(0,a.jsxs)(t.p,{children:["Routine operations in a decentralized network may result in nodes coming on or offline. This ",(0,a.jsx)(t.em,{children:"node churn"})," can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node."]}),"\n",(0,a.jsx)(t.h2,{id:"interacting-with-a-decentralized-network",children:"Interacting with a Decentralized Network"}),"\n",(0,a.jsxs)(t.p,{children:["For a dApp to integrate with a Casper network, it must be able to send ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/T#transaction",children:"transactions"})," via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. ",(0,a.jsx)(t.a,{href:"/2.0.0/developers/cli/sending-transactions",children:"Sending a Transaction"})," to a node will result in that node ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/design/p2p#communications-gossiping",children:"gossiping"})," that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution."]}),"\n",(0,a.jsxs)(t.p,{children:["A transaction contains ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/S#session-code",children:"session code"})," in the form of ",(0,a.jsx)(t.a,{href:"/2.0.0/concepts/glossary/W#webassembly",children:"Wasm"})," to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later."]}),"\n",(0,a.jsx)(t.p,{children:"Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction."}),"\n",(0,a.jsx)(t.p,{children:"All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR."}),"\n",(0,a.jsx)(t.p,{children:"Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction."}),"\n",(0,a.jsxs)(t.p,{children:["There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The ",(0,a.jsx)(t.a,{href:"/2.0.0/transactions-and-transaction-lifecycle#execution-semantics-phases",children:"Transaction Lifecycle"})," results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase."]})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},28453:(e,t,n)=>{n.d(t,{R:()=>o,x:()=>r});var a=n(96540);const s={},i=a.createContext(s);function o(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),a.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f3bf6984.253d30ee.js b/assets/js/f3bf6984.253d30ee.js deleted file mode 100644 index 8cbbf3c04..000000000 --- a/assets/js/f3bf6984.253d30ee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[9349],{79029:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var s=t(74848),r=t(28453);const i={},a="Prerequisites",o={id:"developers/dapps/prerequisites",title:"Prerequisites",description:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:",source:"@site/docs/developers/dapps/prerequisites.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/prerequisites",permalink:"/next/developers/dapps/prerequisites",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"What is a dApp?",permalink:"/next/developers/dapps/dapp"},next:{title:"SDK Client Libraries",permalink:"/next/sdk"}},d={},l=[{value:"Development Considerations",id:"development-considerations",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"prerequisites",children:"Prerequisites"})}),"\n",(0,s.jsx)(n.p,{children:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Set up your ",(0,s.jsx)(n.a,{href:"/next/developers/prerequisites",children:"development environment"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Be sure you understand the language(s) you are developing in."}),"\n",(0,s.jsx)(n.p,{children:"Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you."}),"\n",(0,s.jsxs)(n.p,{children:["The preferred stack for building on Casper is JavaScript using the ",(0,s.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),", however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the ",(0,s.jsx)(n.a,{href:"/next/sdk",children:"Introduction to SDKs"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Familiarize yourself with the fundamentals of Casper networks."}),"\n",(0,s.jsxs)(n.p,{children:["Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the ",(0,s.jsx)(n.a,{href:"/next/design",children:"design section"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsx)(n.p,{children:"Read the documentation or source code of your chosen SDK."}),"\n",(0,s.jsxs)(n.p,{children:["Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see ",(0,s.jsx)(n.a,{href:"/next/developers/dapps/sdk/client-library-usage",children:"Client Library Usage"}),"."]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h2,{id:"development-considerations",children:"Development Considerations"}),"\n",(0,s.jsx)(n.p,{children:"When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value."}),"\n",(0,s.jsx)(n.p,{children:"To ensure the highest level of security, consider the following practices:"}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code."}),"\n",(0,s.jsx)(n.li,{children:"Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors."}),"\n",(0,s.jsx)(n.li,{children:"Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet."}),"\n",(0,s.jsx)(n.li,{children:"Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes."}),"\n",(0,s.jsx)(n.li,{children:"Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities."}),"\n",(0,s.jsx)(n.li,{children:"Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively."}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453:(e,n,t)=>{t.d(n,{R:()=>a,x:()=>o});var s=t(96540);const r={},i=s.createContext(r);function a(e){const n=s.useContext(i);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),s.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f3bf6984.d6d4b2c7.js b/assets/js/f3bf6984.d6d4b2c7.js new file mode 100644 index 000000000..24c0e3982 --- /dev/null +++ b/assets/js/f3bf6984.d6d4b2c7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[89349],{79029:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>i,metadata:()=>o,toc:()=>l});var t=s(74848),r=s(28453);const i={},a="Prerequisites",o={id:"developers/dapps/prerequisites",title:"Prerequisites",description:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:",source:"@site/docs/developers/dapps/prerequisites.md",sourceDirName:"developers/dapps",slug:"/developers/dapps/prerequisites",permalink:"/developers/dapps/prerequisites",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{},sidebar:"developers",previous:{title:"What is a dApp?",permalink:"/developers/dapps/dapp"},next:{title:"SDK Client Libraries",permalink:"/sdk"}},d={},l=[{value:"Development Considerations",id:"development-considerations",level:2}];function p(e){const n={a:"a",h1:"h1",h2:"h2",header:"header",li:"li",ol:"ol",p:"p",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"prerequisites",children:"Prerequisites"})}),"\n",(0,t.jsx)(n.p,{children:"Before trying your hand at dApp development on a Casper network, there are a few things you should do first:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Set up your ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"development environment"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Be sure you understand the language(s) you are developing in."}),"\n",(0,t.jsx)(n.p,{children:"Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you."}),"\n",(0,t.jsxs)(n.p,{children:["The preferred stack for building on Casper is JavaScript using the ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JS SDK"}),", however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the ",(0,t.jsx)(n.a,{href:"/sdk",children:"Introduction to SDKs"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Familiarize yourself with the fundamentals of Casper networks."}),"\n",(0,t.jsxs)(n.p,{children:["Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the ",(0,t.jsx)(n.a,{href:"/design",children:"design section"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Read the documentation or source code of your chosen SDK."}),"\n",(0,t.jsxs)(n.p,{children:["Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see ",(0,t.jsx)(n.a,{href:"/developers/dapps/sdk/client-library-usage",children:"Client Library Usage"}),"."]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"development-considerations",children:"Development Considerations"}),"\n",(0,t.jsx)(n.p,{children:"When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value."}),"\n",(0,t.jsx)(n.p,{children:"To ensure the highest level of security, consider the following practices:"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code."}),"\n",(0,t.jsx)(n.li,{children:"Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors."}),"\n",(0,t.jsx)(n.li,{children:"Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet."}),"\n",(0,t.jsx)(n.li,{children:"Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes."}),"\n",(0,t.jsx)(n.li,{children:"Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities."}),"\n",(0,t.jsx)(n.li,{children:"Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network."})]})}function c(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(p,{...e})}):p(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>o});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f46d6e59.b998f248.js b/assets/js/f46d6e59.b998f248.js new file mode 100644 index 000000000..8ee4786b8 --- /dev/null +++ b/assets/js/f46d6e59.b998f248.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[82858],{57806:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={title:"Move a Node"},o="Moving a Validating Node",d={id:"operators/maintenance/moving-node",title:"Move a Node",description:"This guide is for active validators who want to move their node to another machine.",source:"@site/docs/operators/maintenance/moving-node.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/moving-node",permalink:"/operators/maintenance/moving-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Move a Node"},sidebar:"operators",previous:{title:"Archive and Restore a DB",permalink:"/operators/maintenance/archiving-and-restoring"}},a={},c=[{value:"Swapping Keys with a Hot Backup",id:"swapping-keys-with-a-hot-backup",level:2},{value:"Preparation for swapping",id:"preparation-for-swapping",level:3},{value:"Swapping the nodes",id:"swapping-the-nodes",level:3},{value:"Understanding rewards impact",id:"understanding-rewards-impact",level:3},{value:"Checking file permissions",id:"checking-file-permissions",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"moving-a-validating-node",children:"Moving a Validating Node"})}),"\n",(0,i.jsx)(n.p,{children:"This guide is for active validators who want to move their node to another machine."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"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."})}),"\n",(0,i.jsx)(n.h2,{id:"swapping-keys-with-a-hot-backup",children:"Swapping Keys with a Hot Backup"}),"\n",(0,i.jsx)(n.p,{children:"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."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Once a node is running (",(0,i.jsx)(n.code,{children:"current_node"}),"), create a second node (",(0,i.jsx)(n.code,{children:"backup_node"}),") on another machine. These two nodes will run in parallel."]}),"\n",(0,i.jsxs)(n.li,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Move the unit files at the DB level using ",(0,i.jsx)(n.code,{children:"rsync"}),". This step allows moving the node with nearly zero rewards loss."]}),"\n",(0,i.jsxs)(n.li,{children:["Stop the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"backup_node"}),", now the new validator."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"current_node"}),", now the new backup."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"preparation-for-swapping",children:"Preparation for swapping"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Prepare to swap keys by following these steps:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create the following folder structure on both nodes under the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/"})," directory."]}),"\n",(0,i.jsxs)(n.li,{children:["Create subdirectories for the ",(0,i.jsx)(n.code,{children:"current_node"})," and ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Copy each node's keyset under the corresponding directories."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" /etc/casper/validator_keys/\n \u251c\u2500\u2500 public_key.pem\n \u251c\u2500\u2500 public_key_hex\n \u251c\u2500\u2500 secret_key.pem\n \u251c\u2500\u2500 current_node\n \u2502 \u251c\u2500\u2500 public_key.pem\n \u2502 \u251c\u2500\u2500 public_key_hex\n \u2502 \u2514\u2500\u2500 secret_key.pem\n \u2514\u2500\u2500 backup_node\n | \u251c\u2500\u2500 public_key.pem\n | \u251c\u2500\u2500 public_key_hex\n | \u2514\u2500\u2500 secret_key.pem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This setup allows key swapping by running the ",(0,i.jsx)(n.code,{children:"sudo -u casper cp * ../"})," command, as shown below."]}),"\n",(0,i.jsx)(n.h3,{id:"swapping-the-nodes",children:"Swapping the nodes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"})," (the future validator), use ",(0,i.jsx)(n.code,{children:"rsync"})," to move the unit files from the ",(0,i.jsx)(n.code,{children:"current_node"}),", located in ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"}),", run these commands to stop the node, swap keys, and restart the node:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/current_node\nsudo -u casper cp * ../\nsudo systemctl start casper-node-launcher\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"current_node"}),", run these commands to stop the node and swap keys:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/backup_node\nsudo -u casper cp * ../\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Restart the original validator node (",(0,i.jsx)(n.code,{children:"current_node"}),"), which is now the new backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher \n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"understanding-rewards-impact",children:"Understanding rewards impact"}),"\n",(0,i.jsx)(n.p,{children:"After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"You could time the swap right before the era ends to minimize reward losses."})}),"\n",(0,i.jsx)(n.h3,{id:"checking-file-permissions",children:"Checking file permissions"}),"\n",(0,i.jsxs)(n.p,{children:["After the swap, check and fix file permissions by running the ",(0,i.jsx)(n.code,{children:"/etc/casper/node_util.py"})," utility."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f46d6e59.d7f83469.js b/assets/js/f46d6e59.d7f83469.js deleted file mode 100644 index 02d3a16ac..000000000 --- a/assets/js/f46d6e59.d7f83469.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[2858],{57806:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var t=s(74848),i=s(28453);const r={title:"Move a Node"},o="Moving a Validating Node",d={id:"operators/maintenance/moving-node",title:"Move a Node",description:"This guide is for active validators who want to move their node to another machine.",source:"@site/docs/operators/maintenance/moving-node.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/moving-node",permalink:"/next/operators/maintenance/moving-node",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Move a Node"},sidebar:"operators",previous:{title:"Archive and Restore a DB",permalink:"/next/operators/maintenance/archiving-and-restoring"}},a={},c=[{value:"Swapping Keys with a Hot Backup",id:"swapping-keys-with-a-hot-backup",level:2},{value:"Preparation for swapping",id:"preparation-for-swapping",level:3},{value:"Swapping the nodes",id:"swapping-the-nodes",level:3},{value:"Understanding rewards impact",id:"understanding-rewards-impact",level:3},{value:"Checking file permissions",id:"checking-file-permissions",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"moving-a-validating-node",children:"Moving a Validating Node"})}),"\n",(0,t.jsx)(n.p,{children:"This guide is for active validators who want to move their node to another machine."}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"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."})}),"\n",(0,t.jsx)(n.h2,{id:"swapping-keys-with-a-hot-backup",children:"Swapping Keys with a Hot Backup"}),"\n",(0,t.jsx)(n.p,{children:"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."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Once a node is running (",(0,t.jsx)(n.code,{children:"current_node"}),"), create a second node (",(0,t.jsx)(n.code,{children:"backup_node"}),") on another machine. These two nodes will run in parallel."]}),"\n",(0,t.jsxs)(n.li,{children:["When the ",(0,t.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,t.jsx)(n.code,{children:"current_node"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Move the unit files at the DB level using ",(0,t.jsx)(n.code,{children:"rsync"}),". This step allows moving the node with nearly zero rewards loss."]}),"\n",(0,t.jsxs)(n.li,{children:["Stop the ",(0,t.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Swap keys on the ",(0,t.jsx)(n.code,{children:"backup_node"}),", now the new validator."]}),"\n",(0,t.jsxs)(n.li,{children:["Restart the ",(0,t.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:["Swap keys on the ",(0,t.jsx)(n.code,{children:"current_node"}),", now the new backup."]}),"\n",(0,t.jsxs)(n.li,{children:["Restart the ",(0,t.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"preparation-for-swapping",children:"Preparation for swapping"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset."}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsx)(n.p,{children:"Prepare to swap keys by following these steps:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Create the following folder structure on both nodes under the ",(0,t.jsx)(n.code,{children:"/etc/casper/validator_keys/"})," directory."]}),"\n",(0,t.jsxs)(n.li,{children:["Create subdirectories for the ",(0,t.jsx)(n.code,{children:"current_node"})," and ",(0,t.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,t.jsx)(n.li,{children:"Copy each node's keyset under the corresponding directories."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:" /etc/casper/validator_keys/\n \u251c\u2500\u2500 public_key.pem\n \u251c\u2500\u2500 public_key_hex\n \u251c\u2500\u2500 secret_key.pem\n \u251c\u2500\u2500 current_node\n \u2502 \u251c\u2500\u2500 public_key.pem\n \u2502 \u251c\u2500\u2500 public_key_hex\n \u2502 \u2514\u2500\u2500 secret_key.pem\n \u2514\u2500\u2500 backup_node\n | \u251c\u2500\u2500 public_key.pem\n | \u251c\u2500\u2500 public_key_hex\n | \u2514\u2500\u2500 secret_key.pem\n"})}),"\n",(0,t.jsxs)(n.p,{children:["This setup allows key swapping by running the ",(0,t.jsx)(n.code,{children:"sudo -u casper cp * ../"})," command, as shown below."]}),"\n",(0,t.jsx)(n.h3,{id:"swapping-the-nodes",children:"Swapping the nodes"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["When the ",(0,t.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,t.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["On the ",(0,t.jsx)(n.code,{children:"backup_node"})," (the future validator), use ",(0,t.jsx)(n.code,{children:"rsync"})," to move the unit files from the ",(0,t.jsx)(n.code,{children:"current_node"}),", located in ",(0,t.jsx)(n.code,{children:"/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files"}),"."]}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["On the ",(0,t.jsx)(n.code,{children:"backup_node"}),", run these commands to stop the node, swap keys, and restart the node:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/current_node\nsudo -u casper cp * ../\nsudo systemctl start casper-node-launcher\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["On the ",(0,t.jsx)(n.code,{children:"current_node"}),", run these commands to stop the node and swap keys:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/backup_node\nsudo -u casper cp * ../\n"})}),"\n"]}),"\n",(0,t.jsxs)(n.li,{children:["\n",(0,t.jsxs)(n.p,{children:["Restart the original validator node (",(0,t.jsx)(n.code,{children:"current_node"}),"), which is now the new backup:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher \n"})}),"\n"]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"understanding-rewards-impact",children:"Understanding rewards impact"}),"\n",(0,t.jsx)(n.p,{children:"After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era."}),"\n",(0,t.jsx)(n.admonition,{type:"tip",children:(0,t.jsx)(n.p,{children:"You could time the swap right before the era ends to minimize reward losses."})}),"\n",(0,t.jsx)(n.h3,{id:"checking-file-permissions",children:"Checking file permissions"}),"\n",(0,t.jsxs)(n.p,{children:["After the swap, check and fix file permissions by running the ",(0,t.jsx)(n.code,{children:"/etc/casper/node_util.py"})," utility."]})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f5c04343.715b43d2.js b/assets/js/f5c04343.715b43d2.js new file mode 100644 index 000000000..577991511 --- /dev/null +++ b/assets/js/f5c04343.715b43d2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30605],{36831:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var i=s(74848),r=s(28453);const l={},d="CLType",c={id:"developers/json-rpc/types_cl",title:"CLType",description:"Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.",source:"@site/versioned_docs/version-2.0.0/developers/json-rpc/types_cl.md",sourceDirName:"developers/json-rpc",slug:"/developers/json-rpc/types_cl",permalink:"/2.0.0/developers/json-rpc/types_cl",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"developers",previous:{title:"Types",permalink:"/2.0.0/developers/json-rpc/types_chain"},next:{title:"Overview of Casper dApps",permalink:"/2.0.0/developers/dapps/"}},t={},o=[{value:"CLValue",id:"clvalue",level:2}];function a(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"cltype",children:"CLType"})}),"\n",(0,i.jsxs)(n.p,{children:["Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a ",(0,i.jsx)(n.a,{href:"#clvalue",children:(0,i.jsx)(n.code,{children:"CLValue"})}),"."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Bool"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"I64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U8"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U32"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U64"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U128"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U256"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"U512"})," Large unsigned integer type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Unit"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"String"})," Primitive"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Key"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"URef"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"PublicKey"})," System type"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Option"})," Option of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"List"})," Variable-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a ",(0,i.jsx)(n.code,{children:"Vec"}),")"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"ByteArray"})," Fixed-length list of a single ",(0,i.jsx)(n.code,{children:"CLType"})," (comparable to a Rust array)"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Result"})," ",(0,i.jsx)(n.code,{children:"Result"})," with ",(0,i.jsx)(n.code,{children:"Ok"})," and ",(0,i.jsx)(n.code,{children:"Err"})," variants of ",(0,i.jsx)(n.code,{children:"CLType"}),"'s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Map"})," Map with keys of a single ",(0,i.jsx)(n.code,{children:"CLType"})," and values of a single ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple1"})," 1-ary tuple of a ",(0,i.jsx)(n.code,{children:"CLType"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple2"})," 2-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Tuple3"})," 3-ary tuple of ",(0,i.jsx)(n.code,{children:"CLType"}),"s"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"Any"})," Unspecified type"]}),"\n"]}),"\n",(0,i.jsx)(n.h2,{id:"clvalue",children:"CLValue"}),"\n",(0,i.jsxs)(n.p,{children:["A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized ",(0,i.jsx)(n.code,{children:"Vec<u8>"})," and also holds the CLType of the underlying data as a separate member. The ",(0,i.jsx)(n.code,{children:"parsed"})," field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred."]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"bytes"})," A Casper serialized representation of the underlying value. For more information, reference the ",(0,i.jsx)(n.a,{href:"/2.0.0/concepts/serialization/",children:"Serialization Standard"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.a,{href:"#cltype",children:(0,i.jsx)(n.code,{children:"cl_type"})})}),"\n"]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>d,x:()=>c});var i=s(96540);const r={},l=i.createContext(r);function d(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f6320c57.a7d30f9d.js b/assets/js/f6320c57.a7d30f9d.js new file mode 100644 index 000000000..108519c93 --- /dev/null +++ b/assets/js/f6320c57.a7d30f9d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[95875],{15562:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={title:"Glossary",slug:"/glossary"},t="Glossary",a={id:"concepts/glossary/index",title:"Glossary",description:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/index.md",sourceDirName:"concepts/glossary",slug:"/glossary",permalink:"/2.0.0/glossary",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Glossary",slug:"/glossary"},sidebar:"concepts",previous:{title:"Staking",permalink:"/2.0.0/concepts/economics/staking"},next:{title:"A",permalink:"/2.0.0/concepts/glossary/A"}},l={},i=[];function h(s){const e={a:"a",h1:"h1",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"glossary",children:"Glossary"})}),"\n",(0,n.jsx)(e.p,{children:"These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts."}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(h,{...s})}):h(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/f69b951d.a8eed262.js b/assets/js/f69b951d.a8eed262.js new file mode 100644 index 000000000..3d39a2e8f --- /dev/null +++ b/assets/js/f69b951d.a8eed262.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[59683],{2154:(s,e,r)=>{r.r(e),r.d(e,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>h});var n=r(74848),c=r(28453);const o={},t="L",a={id:"concepts/glossary/L",title:"L",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/L.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/L",permalink:"/2.0.0/concepts/glossary/L",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"K",permalink:"/2.0.0/concepts/glossary/K"},next:{title:"M",permalink:"/2.0.0/concepts/glossary/M"}},l={},h=[{value:"Liveness",id:"liveness",level:2}];function i(s){const e={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...s.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.header,{children:(0,n.jsx)(e.h1,{id:"l",children:"L"})}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsxs)(e.p,{children:[(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(e.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(e.hr,{}),"\n",(0,n.jsx)(e.h2,{id:"liveness",children:"Liveness"}),"\n",(0,n.jsx)(e.p,{children:"A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions)."}),"\n",(0,n.jsx)(e.p,{children:"If the protocol is not live, the blockchain does not grow anymore, and the network stalls."})]})}function d(s={}){const{wrapper:e}={...(0,c.R)(),...s.components};return e?(0,n.jsx)(e,{...s,children:(0,n.jsx)(i,{...s})}):i(s)}},28453:(s,e,r)=>{r.d(e,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(s){const e=n.useContext(o);return n.useMemo((function(){return"function"==typeof s?s(e):{...e,...s}}),[e,s])}function a(s){let e;return e=s.disableParentContext?"function"==typeof s.components?s.components(c):s.components||c:t(s.components),n.createElement(o.Provider,{value:e},s.children)}}}]); \ No newline at end of file diff --git a/assets/js/f71fe95d.9ad08d80.js b/assets/js/f71fe95d.9ad08d80.js new file mode 100644 index 000000000..e92e317c9 --- /dev/null +++ b/assets/js/f71fe95d.9ad08d80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[30670],{38636:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>o,frontMatter:()=>d,metadata:()=>i,toc:()=>l});var t=s(74848),r=s(28453);const d={title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},c="Ecosystem Open-Source Software",i={id:"resources/casper-open-source-software",title:"Open-Source Software",description:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.",source:"@site/versioned_docs/version-1.5.X/resources/casper-open-source-software.md",sourceDirName:"resources",slug:"/resources/build-on-casper/casper-open-source-software",permalink:"/1.5.X/resources/build-on-casper/casper-open-source-software",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},sidebar:"resources",previous:{title:"CEP-78 JavaScript Client",permalink:"/1.5.X/resources/tokens/cep78/js-tutorial"},next:{title:"Quickstart",permalink:"/1.5.X/resources/quick-start"}},h={},l=[];function a(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ecosystem-open-source-software",children:"Ecosystem Open-Source Software"})}),"\n",(0,t.jsx)(n.p,{children:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Name"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Author"}),(0,t.jsx)(n.th,{children:"Language"}),(0,t.jsx)(n.th,{children:"License"}),(0,t.jsx)(n.th,{children:"Last Update Date"}),(0,t.jsx)(n.th,{children:"Type"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-StakingRewards",children:"Basic Yield Farm"})}),(0,t.jsx)(n.td,{children:"Staking Rewards"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/amazanzan/casper-cert-issuer",children:"Blockcerts on Casper"})}),(0,t.jsx)(n.td,{children:"Issues Blockcerts using the Bitcoin, Ethereum, or Casper blockchain"}),(0,t.jsx)(n.td,{children:"amazanzan"}),(0,t.jsx)(n.td,{children:"Python"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-22"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://blockmatcher.ledgerleap.com/",children:"BlockMatcher"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-frontend",children:"Frontend"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-backend",children:"Backend"})]}),(0,t.jsx)(n.td,{children:"Private Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches."}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-15"}),(0,t.jsx)(n.td,{children:"Exchange"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/camel-casper",children:"Camel Casper"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://camel.apache.org/",children:"Apache Camel"})," connector for the Casper Blockchain"]}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"Casper .NET SDK"})}),(0,t.jsx)(n.td,{children:"Casper .NET Client SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:".NET"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-19"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/casper-analytics-app",children:"Casper Analytics App"})}),(0,t.jsx)(n.td,{children:"Casper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod App"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-20"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercppsdk/casper-cpp-sdk",children:"Casper C++ SDK"})}),(0,t.jsx)(n.td,{children:"C++ library to interact with Casper network nodes via RPC"}),(0,t.jsx)(n.td,{children:"Yusuf Keten"}),(0,t.jsx)(n.td,{children:"C++"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/nad128668/casper-calculator",children:"Casper Calculator"})}),(0,t.jsx)(n.td,{children:"Casper Earnings Calculator and Node Monitor"}),(0,t.jsx)(n.td,{children:"Charles Nguyen"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2021-09-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/contract-upgrade-example",children:"Casper Contract Upgrade"})}),(0,t.jsx)(n.td,{children:"Example contract to demonstrate the general way of upgrading a contract and the necessary steps"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-21"}),(0,t.jsx)(n.td,{children:"Example Contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/cdolaz/casper_dart_sdk",children:"Casper Dart SDK"})}),(0,t.jsx)(n.td,{children:"Casper Dart SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"Temiltas"}),(0,t.jsx)(n.td,{children:"Dart"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-26"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market's Casper variant of ERC20"})}),(0,t.jsx)(n.td,{children:"Implementation of the ERC20 standard for Casper networks"}),(0,t.jsx)(n.td,{children:"Friendly Market"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-10"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-go-sdk",children:"Casper Go SDK"})}),(0,t.jsx)(n.td,{children:"Casper Go SDK"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-01"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"Casper Hello World Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKey"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-13"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JavaScript SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client JavaScript SDK"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-Kotlin-sdk",children:"Casper Kotlin SDK"})}),(0,t.jsx)(n.td,{children:"Casper Kotlin Client SDK to interact with a Casper network."}),(0,t.jsx)(n.td,{children:"tqhuy2018"}),(0,t.jsx)(n.td,{children:"Kotlin"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-21"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/Casper-Metrics",children:"Casper Metrics"})}),(0,t.jsx)(n.td,{children:"Casper Metrics - fast blockchain crawler, API, and analysis tool"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-09"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-nctl-docker",children:"Casper NCTL Docker"})}),(0,t.jsx)(n.td,{children:"A Docker container that runs Casper NCTL as a service"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Shell"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-17"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/node-red-contrib-casper",children:"Casper Node-RED"})}),(0,t.jsx)(n.td,{children:"Nodes to communicate with the Casper's Blockchain using node-red"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-02-08"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-ObjectiveC-sdk",children:"Casper Objective-C SDK"})}),(0,t.jsx)(n.td,{children:"Casper Objective-C SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Objective-C"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-18"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-php-sdk",children:"Casper PHP SDK"})}),(0,t.jsx)(n.td,{children:"PHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHP"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/saitgulmez/casper-ruby-sdk",children:"Casper Ruby Client SDK"})}),(0,t.jsx)(n.td,{children:"Ruby SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"Sait Gulmez"}),(0,t.jsx)(n.td,{children:"Ruby"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"Casper Scala SDK"})}),(0,t.jsx)(n.td,{children:"Casper Scala client SDK to interact with the Casper Network nodes via RPC"}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Scala"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-23"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})}),(0,t.jsx)(n.td,{children:"A browser wallet for the Casper Network"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-04-12"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/credentia-network/casper-ssi-demo",children:"Casper SSI Web App"})}),(0,t.jsx)(n.td,{children:"Casper SSI Framework in the form of a demo web application."}),(0,t.jsx)(n.td,{children:"Credentia Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casper-storage",children:"Casper Storage"})}),(0,t.jsx)(n.td,{children:"Casper storage - HD wallets"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/hienbui9999/CasperSDKInSwift",children:"Casper Swift SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client SDK. Casper SDK methods implementation in Swift."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Swift"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig",children:"Casper Two-Party MultiSig Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys."}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-04-26"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/NodesGuru/casper-world",children:"Casper World"})}),(0,t.jsx)(n.td,{children:"Casper network status and decentralization map web application"}),(0,t.jsx)(n.td,{children:"Nodes Guru"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-26"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casperdash-extension",children:"CasperDash Wallet"})}),(0,t.jsx)(n.td,{children:"A non-custodial wallet for the Casper blockchain"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/casperfyre-frontend",children:"CasperFYRE API"})}),(0,t.jsx)(n.td,{children:"Dispensory API interface for Casper Mainnet"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-06"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casperholders/casperholdersfront",children:"CasperHolders"})}),(0,t.jsx)(n.td,{children:"First 3rd party UI to interact with Casper Blockchain"}),(0,t.jsx)(n.td,{children:"CasperHolders"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/chronologic/caspersign-validator-ui",children:"CasperSign"})}),(0,t.jsx)(n.td,{children:"The First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper Blockchain"}),(0,t.jsx)(n.td,{children:"ChronoLogic and Digital Strategies"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-08-31"}),(0,t.jsx)(n.td,{children:"dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"CEP-78 Enhanced NFT Standard"})}),(0,t.jsx)(n.td,{children:"Standard Contract Generator for NFTs"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"CES Rust Event Emitter"})}),(0,t.jsx)(n.td,{children:"Rust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-05-11"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-js-parser",children:"CES JS Parser"})}),(0,t.jsx)(n.td,{children:"JS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-03-27"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-go-parser",children:"CES Go Parser"})}),(0,t.jsx)(n.td,{children:"Go library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-02"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/cleareststake-frontend",children:"Clearest Stake"})}),(0,t.jsx)(n.td,{children:"Staking Asset Manager for Node operators and groups"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-02"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/dao-contracts",children:"DAO Contracts"})}),(0,t.jsx)(n.td,{children:"Smart Contracts for the MVPR On-Chain Governance System on Casper"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-07-17"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/DHFinance/dhf-pay-front",children:"DHF PAY"})}),(0,t.jsx)(n.td,{children:"The crypto currency payment gateway on the CSPR blockchain"}),(0,t.jsx)(n.td,{children:"DHFinance"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-28"}),(0,t.jsx)(n.td,{children:"Payments"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dlndao/start/",children:"DLN DAO"})}),(0,t.jsx)(n.td,{children:"DLN DAO"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-10"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/paradiso-io/bridge-ui",children:"DotOracle"})}),(0,t.jsx)(n.td,{children:"Realtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains."}),(0,t.jsx)(n.td,{children:"DotOracle Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-09-26"}),(0,t.jsx)(n.td,{children:"Bridge"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Dragonlair",children:"Dragon\u2019s Lair Style Staking"})}),(0,t.jsx)(n.td,{children:"Lair Style Staking"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-EIP1337",children:"Subscription Billing"})}),(0,t.jsx)(n.td,{children:"ERC-1337 subscription billing"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-04-07"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Casper Fungible Token"})}),(0,t.jsx)(n.td,{children:"Implementation of Fungible Tokens for Casper networks"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-01"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-ERC777",children:"Advanced Fungible Token"})}),(0,t.jsx)(n.td,{children:"ERC-777 + 1820 Advanced Fungible Token with Callbacks & Self Identification"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-16"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/helperbot",children:"Helper Bot"})}),(0,t.jsx)(n.td,{children:"Helper bot for improving DevDao VAs productivity"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-08-19"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-java-sdk",children:"Java SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client Java SDK"}),(0,t.jsx)(n.td,{children:"SyntiFi"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2021-04-20"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/kyc-proxy-contract",children:"KYC Proxy Contact"})}),(0,t.jsx)(n.td,{children:"This is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-01"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-LiquidNFT",children:"LiquidNFT"})}),(0,t.jsx)(n.td,{children:"NFT Collateralized Loans"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GNU General Public License v3.0"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/payment-example",children:"Payment Example Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the usage of purses to transfer motes inside a contract"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-06-22"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/EKON-YAZILIM/ServicesDAO",children:"ServicesDAO"})}),(0,t.jsx)(n.td,{children:"The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR."}),(0,t.jsx)(n.td,{children:"Ekon Yazilim"}),(0,t.jsx)(n.td,{children:"HTML-CSS-C#"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp",children:"Uniswap DemoApp"})}),(0,t.jsx)(n.td,{children:"Uniswap UI + Contracts"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GPL-3.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/AdelElMessiry/Verified-Impact-NFTs",children:"Verified Impact NFT"})}),(0,t.jsx)(n.td,{children:"An NFT platform dedicated to impact causes with verification of the beneficiaries"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"JavaScript-Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-08"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://usewallet.casperdash.io",children:"UseWallet"})}),(0,t.jsx)(n.td,{children:"useWallet is a collection of React Hooks containing everything you need to start working with a Casper network"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://faucet.casperdash.io",children:"Testnet Faucet"})}),(0,t.jsx)(n.td,{children:"A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"Tools"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>i});var t=s(96540);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f71fe95d.fa1be639.js b/assets/js/f71fe95d.fa1be639.js deleted file mode 100644 index b97d3bda1..000000000 --- a/assets/js/f71fe95d.fa1be639.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[670],{38636:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>o,frontMatter:()=>d,metadata:()=>i,toc:()=>l});var t=s(74848),r=s(28453);const d={title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},c="Ecosystem Open-Source Software",i={id:"resources/casper-open-source-software",title:"Open-Source Software",description:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.",source:"@site/versioned_docs/version-1.5.X/resources/casper-open-source-software.md",sourceDirName:"resources",slug:"/resources/build-on-casper/casper-open-source-software",permalink:"/resources/build-on-casper/casper-open-source-software",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},sidebar:"resources",previous:{title:"CEP-78 JavaScript Client",permalink:"/resources/tokens/cep78/js-tutorial"},next:{title:"Quickstart",permalink:"/resources/quick-start"}},h={},l=[];function a(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ecosystem-open-source-software",children:"Ecosystem Open-Source Software"})}),"\n",(0,t.jsx)(n.p,{children:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Name"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Author"}),(0,t.jsx)(n.th,{children:"Language"}),(0,t.jsx)(n.th,{children:"License"}),(0,t.jsx)(n.th,{children:"Last Update Date"}),(0,t.jsx)(n.th,{children:"Type"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-StakingRewards",children:"Basic Yield Farm"})}),(0,t.jsx)(n.td,{children:"Staking Rewards"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/amazanzan/casper-cert-issuer",children:"Blockcerts on Casper"})}),(0,t.jsx)(n.td,{children:"Issues Blockcerts using the Bitcoin, Ethereum, or Casper blockchain"}),(0,t.jsx)(n.td,{children:"amazanzan"}),(0,t.jsx)(n.td,{children:"Python"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-22"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://blockmatcher.ledgerleap.com/",children:"BlockMatcher"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-frontend",children:"Frontend"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-backend",children:"Backend"})]}),(0,t.jsx)(n.td,{children:"Private Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches."}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-15"}),(0,t.jsx)(n.td,{children:"Exchange"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/camel-casper",children:"Camel Casper"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://camel.apache.org/",children:"Apache Camel"})," connector for the Casper Blockchain"]}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"Casper .NET SDK"})}),(0,t.jsx)(n.td,{children:"Casper .NET Client SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:".NET"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-19"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/casper-analytics-app",children:"Casper Analytics App"})}),(0,t.jsx)(n.td,{children:"Casper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod App"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-20"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercppsdk/casper-cpp-sdk",children:"Casper C++ SDK"})}),(0,t.jsx)(n.td,{children:"C++ library to interact with Casper network nodes via RPC"}),(0,t.jsx)(n.td,{children:"Yusuf Keten"}),(0,t.jsx)(n.td,{children:"C++"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/nad128668/casper-calculator",children:"Casper Calculator"})}),(0,t.jsx)(n.td,{children:"Casper Earnings Calculator and Node Monitor"}),(0,t.jsx)(n.td,{children:"Charles Nguyen"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2021-09-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/contract-upgrade-example",children:"Casper Contract Upgrade"})}),(0,t.jsx)(n.td,{children:"Example contract to demonstrate the general way of upgrading a contract and the necessary steps"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-21"}),(0,t.jsx)(n.td,{children:"Example Contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/cdolaz/casper_dart_sdk",children:"Casper Dart SDK"})}),(0,t.jsx)(n.td,{children:"Casper Dart SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"Temiltas"}),(0,t.jsx)(n.td,{children:"Dart"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-26"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market's Casper variant of ERC20"})}),(0,t.jsx)(n.td,{children:"Implementation of the ERC20 standard for Casper networks"}),(0,t.jsx)(n.td,{children:"Friendly Market"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-10"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-go-sdk",children:"Casper Go SDK"})}),(0,t.jsx)(n.td,{children:"Casper Go SDK"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-01"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"Casper Hello World Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKey"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-13"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JavaScript SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client JavaScript SDK"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-Kotlin-sdk",children:"Casper Kotlin SDK"})}),(0,t.jsx)(n.td,{children:"Casper Kotlin Client SDK to interact with a Casper network."}),(0,t.jsx)(n.td,{children:"tqhuy2018"}),(0,t.jsx)(n.td,{children:"Kotlin"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-21"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/Casper-Metrics",children:"Casper Metrics"})}),(0,t.jsx)(n.td,{children:"Casper Metrics - fast blockchain crawler, API, and analysis tool"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-09"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-nctl-docker",children:"Casper NCTL Docker"})}),(0,t.jsx)(n.td,{children:"A Docker container that runs Casper NCTL as a service"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Shell"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-17"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/node-red-contrib-casper",children:"Casper Node-RED"})}),(0,t.jsx)(n.td,{children:"Nodes to communicate with the Casper's Blockchain using node-red"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-02-08"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-ObjectiveC-sdk",children:"Casper Objective-C SDK"})}),(0,t.jsx)(n.td,{children:"Casper Objective-C SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Objective-C"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-18"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-php-sdk",children:"Casper PHP SDK"})}),(0,t.jsx)(n.td,{children:"PHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHP"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/saitgulmez/casper-ruby-sdk",children:"Casper Ruby Client SDK"})}),(0,t.jsx)(n.td,{children:"Ruby SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"Sait Gulmez"}),(0,t.jsx)(n.td,{children:"Ruby"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"Casper Scala SDK"})}),(0,t.jsx)(n.td,{children:"Casper Scala client SDK to interact with the Casper Network nodes via RPC"}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Scala"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-23"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})}),(0,t.jsx)(n.td,{children:"A browser wallet for the Casper Network"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-04-12"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/credentia-network/casper-ssi-demo",children:"Casper SSI Web App"})}),(0,t.jsx)(n.td,{children:"Casper SSI Framework in the form of a demo web application."}),(0,t.jsx)(n.td,{children:"Credentia Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casper-storage",children:"Casper Storage"})}),(0,t.jsx)(n.td,{children:"Casper storage - HD wallets"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/hienbui9999/CasperSDKInSwift",children:"Casper Swift SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client SDK. Casper SDK methods implementation in Swift."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Swift"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig",children:"Casper Two-Party MultiSig Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys."}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-04-26"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/NodesGuru/casper-world",children:"Casper World"})}),(0,t.jsx)(n.td,{children:"Casper network status and decentralization map web application"}),(0,t.jsx)(n.td,{children:"Nodes Guru"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-26"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casperdash-extension",children:"CasperDash Wallet"})}),(0,t.jsx)(n.td,{children:"A non-custodial wallet for the Casper blockchain"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/casperfyre-frontend",children:"CasperFYRE API"})}),(0,t.jsx)(n.td,{children:"Dispensory API interface for Casper Mainnet"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-06"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casperholders/casperholdersfront",children:"CasperHolders"})}),(0,t.jsx)(n.td,{children:"First 3rd party UI to interact with Casper Blockchain"}),(0,t.jsx)(n.td,{children:"CasperHolders"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/chronologic/caspersign-validator-ui",children:"CasperSign"})}),(0,t.jsx)(n.td,{children:"The First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper Blockchain"}),(0,t.jsx)(n.td,{children:"ChronoLogic and Digital Strategies"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-08-31"}),(0,t.jsx)(n.td,{children:"dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"CEP-78 Enhanced NFT Standard"})}),(0,t.jsx)(n.td,{children:"Standard Contract Generator for NFTs"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"CES Rust Event Emitter"})}),(0,t.jsx)(n.td,{children:"Rust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-05-11"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-js-parser",children:"CES JS Parser"})}),(0,t.jsx)(n.td,{children:"JS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-03-27"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-go-parser",children:"CES Go Parser"})}),(0,t.jsx)(n.td,{children:"Go library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-02"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/cleareststake-frontend",children:"Clearest Stake"})}),(0,t.jsx)(n.td,{children:"Staking Asset Manager for Node operators and groups"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-02"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/dao-contracts",children:"DAO Contracts"})}),(0,t.jsx)(n.td,{children:"Smart Contracts for the MVPR On-Chain Governance System on Casper"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-07-17"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/DHFinance/dhf-pay-front",children:"DHF PAY"})}),(0,t.jsx)(n.td,{children:"The crypto currency payment gateway on the CSPR blockchain"}),(0,t.jsx)(n.td,{children:"DHFinance"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-28"}),(0,t.jsx)(n.td,{children:"Payments"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dlndao/start/",children:"DLN DAO"})}),(0,t.jsx)(n.td,{children:"DLN DAO"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-10"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/paradiso-io/bridge-ui",children:"DotOracle"})}),(0,t.jsx)(n.td,{children:"Realtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains."}),(0,t.jsx)(n.td,{children:"DotOracle Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-09-26"}),(0,t.jsx)(n.td,{children:"Bridge"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Dragonlair",children:"Dragon\u2019s Lair Style Staking"})}),(0,t.jsx)(n.td,{children:"Lair Style Staking"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-EIP1337",children:"Subscription Billing"})}),(0,t.jsx)(n.td,{children:"ERC-1337 subscription billing"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-04-07"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Casper Fungible Token"})}),(0,t.jsx)(n.td,{children:"Implementation of Fungible Tokens for Casper networks"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-01"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-ERC777",children:"Advanced Fungible Token"})}),(0,t.jsx)(n.td,{children:"ERC-777 + 1820 Advanced Fungible Token with Callbacks & Self Identification"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-16"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/helperbot",children:"Helper Bot"})}),(0,t.jsx)(n.td,{children:"Helper bot for improving DevDao VAs productivity"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-08-19"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-java-sdk",children:"Java SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client Java SDK"}),(0,t.jsx)(n.td,{children:"SyntiFi"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2021-04-20"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/kyc-proxy-contract",children:"KYC Proxy Contact"})}),(0,t.jsx)(n.td,{children:"This is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-01"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-LiquidNFT",children:"LiquidNFT"})}),(0,t.jsx)(n.td,{children:"NFT Collateralized Loans"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GNU General Public License v3.0"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/payment-example",children:"Payment Example Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the usage of purses to transfer motes inside a contract"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-06-22"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/EKON-YAZILIM/ServicesDAO",children:"ServicesDAO"})}),(0,t.jsx)(n.td,{children:"The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR."}),(0,t.jsx)(n.td,{children:"Ekon Yazilim"}),(0,t.jsx)(n.td,{children:"HTML-CSS-C#"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp",children:"Uniswap DemoApp"})}),(0,t.jsx)(n.td,{children:"Uniswap UI + Contracts"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GPL-3.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/AdelElMessiry/Verified-Impact-NFTs",children:"Verified Impact NFT"})}),(0,t.jsx)(n.td,{children:"An NFT platform dedicated to impact causes with verification of the beneficiaries"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"JavaScript-Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-08"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://usewallet.casperdash.io",children:"UseWallet"})}),(0,t.jsx)(n.td,{children:"useWallet is a collection of React Hooks containing everything you need to start working with a Casper network"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://faucet.casperdash.io",children:"Testnet Faucet"})}),(0,t.jsx)(n.td,{children:"A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"Tools"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>i});var t=s(96540);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f74078f7.5b44140b.js b/assets/js/f74078f7.5b44140b.js new file mode 100644 index 000000000..eca9bf584 --- /dev/null +++ b/assets/js/f74078f7.5b44140b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[24682],{23936:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>c,contentTitle:()=>s,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=a(74848),o=a(28453);const i={title:"Fee Elimination"},s="Fee Elimination on Mainnet",r={id:"concepts/economics/fee-elimination",title:"Fee Elimination",description:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.',source:"@site/versioned_docs/version-2.0.0/concepts/economics/fee-elimination.md",sourceDirName:"concepts/economics",slug:"/concepts/economics/fee-elimination",permalink:"/2.0.0/concepts/economics/fee-elimination",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Fee Elimination"},sidebar:"concepts",previous:{title:"Dynamic Gas Pricing",permalink:"/2.0.0/concepts/economics/dynamic-gas-pricing"},next:{title:"Staking",permalink:"/2.0.0/concepts/economics/staking"}},c={},l=[{value:"Chainspec Configurations",id:"chainspec-configurations",level:2},{value:"Mainnet Condor Configurations",id:"mainnet-condor-configurations",level:3},{value:"Computational and Storage Costs",id:"computational-and-storage-costs",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"fee-elimination-on-mainnet",children:"Fee Elimination on Mainnet"})}),"\n",(0,t.jsx)(n.p,{children:'Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user\'s purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.'}),"\n",(0,t.jsxs)(n.p,{children:["Instead of paying for gas to execute transactions, the ",(0,t.jsx)(n.code,{children:"no_fee"})," chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: ",(0,t.jsx)(n.code,{children:"fee_handling = { type = 'no_fee'}"}),'. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable ',(0,t.jsx)(n.code,{children:"gas_hold_interval"})," determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/json-rpc-informational#query_balance_details",children:"query_balance_details"})," RPC endpoint provides details on available balances and hold records."]}),"\n",(0,t.jsx)(n.admonition,{type:"note",children:(0,t.jsx)(n.p,{children:"A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer."})}),"\n",(0,t.jsx)(n.h2,{id:"chainspec-configurations",children:"Chainspec Configurations"}),"\n",(0,t.jsxs)(n.p,{children:["The following ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup-network/chain-spec",children:"chainspec configurations"})," manage this feature:"]}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"fee_handling"}),' - Defines how fees are handled. To enable the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_fee'}"}),"."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"refund_handling"}),' Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to ',(0,t.jsx)(n.code,{children:"{ type = 'no_refund'}"}),". If no fees are transferred from the paying purse, no refunds need to be paid out."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"pricing_handling"})," - Defines how pricing is handled. For this setting to work with the ",(0,t.jsx)(n.code,{children:"no_fee"})," mode, set it to ",(0,t.jsx)(n.code,{children:"{ type = 'fixed'}"}),", which means that costs are fixed per the cost table, and senders do not specify how much they pay."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"validator_credit_cap"})," - The validator credit cannot exceed this percentage of their total stake."]}),"\n",(0,t.jsx)(n.li,{children:"`gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry)."}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"gas_hold_interval"})," - Defines how long gas holds last."]}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"mainnet-condor-configurations",children:"Mainnet Condor Configurations"}),"\n",(0,t.jsx)(n.p,{children:"These are the fee elimination settings for the Condor release on Mainnet:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-toml",children:"# Defines how refunds of the unused portion of payment amounts are calculated and handled.\n#\n# Valid options are:\n# 'refund': a ratio of the unspent token is returned to the spender.\n# 'burn': a ratio of the unspent token is burned.\n# 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.\n# This causes excess payment amounts to be sent to either a\n# pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount\n# minus the execution costs.\nrefund_handling = { type = 'no_refund' }\n# Defines how fees are handled.\n#\n# Valid options are:\n# 'no_fee': fees are eliminated.\n# 'pay_to_proposer': fees are paid to the block proposer\n# 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all\n# administrator accounts\n# 'burn': fees are burned\nfee_handling = { type = 'no_fee' }\n# If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.\nvalidator_credit_cap = [1, 5]\n# Defines how pricing is handled.\n#\n# Valid options are:\n# 'classic': senders of transaction self-specify how much they pay.\n# 'fixed': costs are fixed, per the cost table\n# 'reserved': prepaid transaction (currently not supported)\npricing_handling = { type = 'fixed' }\n\n# Defines how gas holds affect available balance calculations.\n#\n# Valid options are:\n# 'accrued': sum of full value of all non-expired holds.\n# 'amortized': sum of each hold is amortized over the time remaining until expiry.\n#\n# For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,\n# with accrued, the full hold amount would be applied\n# with amortized, half the hold amount would be applied\ngas_hold_balance_handling = { type = 'accrued' }\n# Defines how long gas holds last.\n#\n# If fee_handling is set to 'no_fee', the system places a balance hold on the payer\n# equal to the value the fee would have been. Such balance holds expire after a time\n# interval has elapsed. This setting controls how long that interval is. The available\n# balance of a purse equals its total balance minus the held amount(s) of non-expired\n# holds (see gas_hold_balance_handling setting for details of how that is calculated).\n#\n# For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,\n# a hold for 100 is placed on that purse and is considered when calculating total balance\n# for 24 hours starting from the block_time when the hold was placed.\ngas_hold_interval = '24 hours'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"computational-and-storage-costs",children:"Computational and Storage Costs"}),"\n",(0,t.jsxs)(n.p,{children:["Despite the introduction of fee elimination, the network continues to track ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/casper-design#measuring-computational-work-execution-semantics-gas",children:"computational cost"})," based on opcodes as defined in the chainspec, thus retaining the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/gas-concepts",children:"gas pricing mechanism"}),". Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines."]}),"\n",(0,t.jsx)(n.p,{children:"Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state."}),"\n",(0,t.jsxs)(n.p,{children:["This feature complements the ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/economics/dynamic-gas-pricing",children:"dynamic gas pricing"})," model introduced and configured to scale gas costs based on network utilization."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>s,x:()=>r});var t=a(96540);const o={},i=t.createContext(o);function s(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f776c06c.59c0b752.js b/assets/js/f776c06c.59c0b752.js deleted file mode 100644 index 41e0c09e2..000000000 --- a/assets/js/f776c06c.59c0b752.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7033],{20528:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>o,frontMatter:()=>d,metadata:()=>i,toc:()=>l});var t=s(74848),r=s(28453);const d={title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},c="Ecosystem Open-Source Software",i={id:"resources/casper-open-source-software",title:"Open-Source Software",description:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.",source:"@site/docs/resources/casper-open-source-software.md",sourceDirName:"resources",slug:"/resources/build-on-casper/casper-open-source-software",permalink:"/next/resources/build-on-casper/casper-open-source-software",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},sidebar:"resources",previous:{title:"CEP-78 JavaScript Client",permalink:"/next/resources/tokens/cep78/js-tutorial"},next:{title:"Quickstart",permalink:"/next/resources/quick-start"}},h={},l=[];function a(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ecosystem-open-source-software",children:"Ecosystem Open-Source Software"})}),"\n",(0,t.jsx)(n.p,{children:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Name"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Author"}),(0,t.jsx)(n.th,{children:"Language"}),(0,t.jsx)(n.th,{children:"License"}),(0,t.jsx)(n.th,{children:"Last Update Date"}),(0,t.jsx)(n.th,{children:"Type"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-StakingRewards",children:"Basic Yield Farm"})}),(0,t.jsx)(n.td,{children:"Staking Rewards"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/amazanzan/casper-cert-issuer",children:"Blockcerts on Casper"})}),(0,t.jsx)(n.td,{children:"Issues Blockcerts using the Bitcoin, Ethereum, or Casper blockchain"}),(0,t.jsx)(n.td,{children:"amazanzan"}),(0,t.jsx)(n.td,{children:"Python"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-22"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://blockmatcher.ledgerleap.com/",children:"BlockMatcher"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-frontend",children:"Frontend"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-backend",children:"Backend"})]}),(0,t.jsx)(n.td,{children:"Private Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches."}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-15"}),(0,t.jsx)(n.td,{children:"Exchange"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/camel-casper",children:"Camel Casper"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://camel.apache.org/",children:"Apache Camel"})," connector for the Casper Blockchain"]}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"Casper .NET SDK"})}),(0,t.jsx)(n.td,{children:"Casper .NET Client SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:".NET"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-19"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/casper-analytics-app",children:"Casper Analytics App"})}),(0,t.jsx)(n.td,{children:"Casper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod App"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-20"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercppsdk/casper-cpp-sdk",children:"Casper C++ SDK"})}),(0,t.jsx)(n.td,{children:"C++ library to interact with Casper network nodes via RPC"}),(0,t.jsx)(n.td,{children:"Yusuf Keten"}),(0,t.jsx)(n.td,{children:"C++"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/nad128668/casper-calculator",children:"Casper Calculator"})}),(0,t.jsx)(n.td,{children:"Casper Earnings Calculator and Node Monitor"}),(0,t.jsx)(n.td,{children:"Charles Nguyen"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2021-09-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/contract-upgrade-example",children:"Casper Contract Upgrade"})}),(0,t.jsx)(n.td,{children:"Example contract to demonstrate the general way of upgrading a contract and the necessary steps"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-21"}),(0,t.jsx)(n.td,{children:"Example Contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/cdolaz/casper_dart_sdk",children:"Casper Dart SDK"})}),(0,t.jsx)(n.td,{children:"Casper Dart SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"Temiltas"}),(0,t.jsx)(n.td,{children:"Dart"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-26"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market's Casper variant of ERC20"})}),(0,t.jsx)(n.td,{children:"Implementation of the ERC20 standard for Casper networks"}),(0,t.jsx)(n.td,{children:"Friendly Market"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-10"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-go-sdk",children:"Casper Go SDK"})}),(0,t.jsx)(n.td,{children:"Casper Go SDK"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-01"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"Casper Hello World Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKey"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-13"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JavaScript SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client JavaScript SDK"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-Kotlin-sdk",children:"Casper Kotlin SDK"})}),(0,t.jsx)(n.td,{children:"Casper Kotlin Client SDK to interact with a Casper network."}),(0,t.jsx)(n.td,{children:"tqhuy2018"}),(0,t.jsx)(n.td,{children:"Kotlin"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-21"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/Casper-Metrics",children:"Casper Metrics"})}),(0,t.jsx)(n.td,{children:"Casper Metrics - fast blockchain crawler, API, and analysis tool"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-09"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-nctl-docker",children:"Casper NCTL Docker"})}),(0,t.jsx)(n.td,{children:"A Docker container that runs Casper NCTL as a service"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Shell"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-17"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/node-red-contrib-casper",children:"Casper Node-RED"})}),(0,t.jsx)(n.td,{children:"Nodes to communicate with the Casper's Blockchain using node-red"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-02-08"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-ObjectiveC-sdk",children:"Casper Objective-C SDK"})}),(0,t.jsx)(n.td,{children:"Casper Objective-C SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Objective-C"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-18"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-php-sdk",children:"Casper PHP SDK"})}),(0,t.jsx)(n.td,{children:"PHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHP"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/saitgulmez/casper-ruby-sdk",children:"Casper Ruby Client SDK"})}),(0,t.jsx)(n.td,{children:"Ruby SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"Sait Gulmez"}),(0,t.jsx)(n.td,{children:"Ruby"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"Casper Scala SDK"})}),(0,t.jsx)(n.td,{children:"Casper Scala client SDK to interact with the Casper Network nodes via RPC"}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Scala"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-23"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})}),(0,t.jsx)(n.td,{children:"A browser wallet for the Casper Network"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-04-12"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/credentia-network/casper-ssi-demo",children:"Casper SSI Web App"})}),(0,t.jsx)(n.td,{children:"Casper SSI Framework in the form of a demo web application."}),(0,t.jsx)(n.td,{children:"Credentia Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casper-storage",children:"Casper Storage"})}),(0,t.jsx)(n.td,{children:"Casper storage - HD wallets"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/hienbui9999/CasperSDKInSwift",children:"Casper Swift SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client SDK. Casper SDK methods implementation in Swift."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Swift"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig",children:"Casper Two-Party MultiSig Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys."}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-04-26"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/NodesGuru/casper-world",children:"Casper World"})}),(0,t.jsx)(n.td,{children:"Casper network status and decentralization map web application"}),(0,t.jsx)(n.td,{children:"Nodes Guru"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-26"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casperdash-client",children:"CasperDash Wallet"})}),(0,t.jsx)(n.td,{children:"A non-custodial wallet for the Casper blockchain"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/casperfyre-frontend",children:"CasperFYRE API"})}),(0,t.jsx)(n.td,{children:"Dispensory API interface for Casper Mainnet"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-06"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casperholders/casperholdersfront",children:"CasperHolders"})}),(0,t.jsx)(n.td,{children:"First 3rd party UI to interact with Casper Blockchain"}),(0,t.jsx)(n.td,{children:"CasperHolders"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/chronologic/caspersign-validator-ui",children:"CasperSign"})}),(0,t.jsx)(n.td,{children:"The First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper Blockchain"}),(0,t.jsx)(n.td,{children:"ChronoLogic and Digital Strategies"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-08-31"}),(0,t.jsx)(n.td,{children:"dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"CEP-78 Enhanced NFT Standard"})}),(0,t.jsx)(n.td,{children:"Standard Contract Generator for NFTs"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"CES Rust Event Emitter"})}),(0,t.jsx)(n.td,{children:"Rust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-05-11"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-js-parser",children:"CES JS Parser"})}),(0,t.jsx)(n.td,{children:"JS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-03-27"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-go-parser",children:"CES Go Parser"})}),(0,t.jsx)(n.td,{children:"Go library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-02"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/cleareststake-frontend",children:"Clearest Stake"})}),(0,t.jsx)(n.td,{children:"Staking Asset Manager for Node operators and groups"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-02"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/dao-contracts",children:"DAO Contracts"})}),(0,t.jsx)(n.td,{children:"Smart Contracts for the MVPR On-Chain Governance System on Casper"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-07-17"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/DHFinance/dhf-pay-front",children:"DHF PAY"})}),(0,t.jsx)(n.td,{children:"The crypto currency payment gateway on the CSPR blockchain"}),(0,t.jsx)(n.td,{children:"DHFinance"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-28"}),(0,t.jsx)(n.td,{children:"Payments"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dlndao/start/",children:"DLN DAO"})}),(0,t.jsx)(n.td,{children:"DLN DAO"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-10"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dotoracle/bridge-ui",children:"DotOracle"})}),(0,t.jsx)(n.td,{children:"Realtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains."}),(0,t.jsx)(n.td,{children:"DotOracle Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-09-26"}),(0,t.jsx)(n.td,{children:"Bridge"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Dragonlair",children:"Dragon\u2019s Lair Style Staking"})}),(0,t.jsx)(n.td,{children:"Lair Style Staking"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-EIP1337",children:"Subscription Billing"})}),(0,t.jsx)(n.td,{children:"ERC-1337 subscription billing"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-04-07"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Casper Fungible Token"})}),(0,t.jsx)(n.td,{children:"Implementation of Fungible Tokens for Casper networks"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-01"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-ERC777",children:"Advanced Fungible Token"})}),(0,t.jsx)(n.td,{children:"ERC-777 + 1820 Advanced Fungible Token with Callbacks & Self Identification"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-16"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/helperbot",children:"Helper Bot"})}),(0,t.jsx)(n.td,{children:"Helper bot for improving DevDao VAs productivity"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-08-19"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-java-sdk",children:"Java SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client Java SDK"}),(0,t.jsx)(n.td,{children:"SyntiFi"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2021-04-20"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/kyc-proxy-contract",children:"KYC Proxy Contact"})}),(0,t.jsx)(n.td,{children:"This is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-01"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-LiquidNFT",children:"LiquidNFT"})}),(0,t.jsx)(n.td,{children:"NFT Collateralized Loans"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GNU General Public License v3.0"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/payment-example",children:"Payment Example Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the usage of purses to transfer motes inside a contract"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-06-22"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/EKON-YAZILIM/ServicesDAO",children:"ServicesDAO"})}),(0,t.jsx)(n.td,{children:"The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR."}),(0,t.jsx)(n.td,{children:"Ekon Yazilim"}),(0,t.jsx)(n.td,{children:"HTML-CSS-C#"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp",children:"Uniswap DemoApp"})}),(0,t.jsx)(n.td,{children:"Uniswap UI + Contracts"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GPL-3.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/AdelElMessiry/Verified-Impact-NFTs",children:"Verified Impact NFT"})}),(0,t.jsx)(n.td,{children:"An NFT platform dedicated to impact causes with verification of the beneficiaries"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"JavaScript-Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-08"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://usewallet.casperdash.io",children:"UseWallet"})}),(0,t.jsx)(n.td,{children:"useWallet is a collection of React Hooks containing everything you need to start working with a Casper network"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://faucet.casperdash.io",children:"Testnet Faucet"})}),(0,t.jsx)(n.td,{children:"A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"Tools"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>i});var t=s(96540);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f776c06c.6260625f.js b/assets/js/f776c06c.6260625f.js new file mode 100644 index 000000000..c884b42aa --- /dev/null +++ b/assets/js/f776c06c.6260625f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[57033],{20528:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>h,contentTitle:()=>c,default:()=>o,frontMatter:()=>d,metadata:()=>i,toc:()=>l});var t=s(74848),r=s(28453);const d={title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},c="Ecosystem Open-Source Software",i={id:"resources/casper-open-source-software",title:"Open-Source Software",description:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.",source:"@site/docs/resources/casper-open-source-software.md",sourceDirName:"resources",slug:"/resources/build-on-casper/casper-open-source-software",permalink:"/resources/build-on-casper/casper-open-source-software",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1723745091e3,frontMatter:{title:"Open-Source Software",slug:"build-on-casper/casper-open-source-software"},sidebar:"resources",previous:{title:"CEP-78 JavaScript Client",permalink:"/resources/tokens/cep78/js-tutorial"},next:{title:"Quickstart",permalink:"/resources/quick-start"}},h={},l=[];function a(e){const n={a:"a",h1:"h1",header:"header",p:"p",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"ecosystem-open-source-software",children:"Ecosystem Open-Source Software"})}),"\n",(0,t.jsx)(n.p,{children:"This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions."}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,t.jsxs)(n.table,{children:[(0,t.jsx)(n.thead,{children:(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.th,{children:"Name"}),(0,t.jsx)(n.th,{children:"Description"}),(0,t.jsx)(n.th,{children:"Author"}),(0,t.jsx)(n.th,{children:"Language"}),(0,t.jsx)(n.th,{children:"License"}),(0,t.jsx)(n.th,{children:"Last Update Date"}),(0,t.jsx)(n.th,{children:"Type"})]})}),(0,t.jsxs)(n.tbody,{children:[(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-StakingRewards",children:"Basic Yield Farm"})}),(0,t.jsx)(n.td,{children:"Staking Rewards"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/amazanzan/casper-cert-issuer",children:"Blockcerts on Casper"})}),(0,t.jsx)(n.td,{children:"Issues Blockcerts using the Bitcoin, Ethereum, or Casper blockchain"}),(0,t.jsx)(n.td,{children:"amazanzan"}),(0,t.jsx)(n.td,{children:"Python"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-22"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://blockmatcher.ledgerleap.com/",children:"BlockMatcher"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-frontend",children:"Frontend"})," ",(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/blockmatcher-backend",children:"Backend"})]}),(0,t.jsx)(n.td,{children:"Private Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches."}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-15"}),(0,t.jsx)(n.td,{children:"Exchange"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/camel-casper",children:"Camel Casper"})}),(0,t.jsxs)(n.td,{children:[(0,t.jsx)(n.a,{href:"https://camel.apache.org/",children:"Apache Camel"})," connector for the Casper Blockchain"]}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-net-sdk",children:"Casper .NET SDK"})}),(0,t.jsx)(n.td,{children:"Casper .NET Client SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:".NET"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-19"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/casper-analytics-app",children:"Casper Analytics App"})}),(0,t.jsx)(n.td,{children:"Casper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod App"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-20"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercppsdk/casper-cpp-sdk",children:"Casper C++ SDK"})}),(0,t.jsx)(n.td,{children:"C++ library to interact with Casper network nodes via RPC"}),(0,t.jsx)(n.td,{children:"Yusuf Keten"}),(0,t.jsx)(n.td,{children:"C++"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/nad128668/casper-calculator",children:"Casper Calculator"})}),(0,t.jsx)(n.td,{children:"Casper Earnings Calculator and Node Monitor"}),(0,t.jsx)(n.td,{children:"Charles Nguyen"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2021-09-26"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/contract-upgrade-example",children:"Casper Contract Upgrade"})}),(0,t.jsx)(n.td,{children:"Example contract to demonstrate the general way of upgrading a contract and the necessary steps"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-21"}),(0,t.jsx)(n.td,{children:"Example Contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/cdolaz/casper_dart_sdk",children:"Casper Dart SDK"})}),(0,t.jsx)(n.td,{children:"Casper Dart SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"Temiltas"}),(0,t.jsx)(n.td,{children:"Dart"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-26"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/FriendlyMarket/casper-erc20",children:"Friendly Market's Casper variant of ERC20"})}),(0,t.jsx)(n.td,{children:"Implementation of the ERC20 standard for Casper networks"}),(0,t.jsx)(n.td,{children:"Friendly Market"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-10"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-go-sdk",children:"Casper Go SDK"})}),(0,t.jsx)(n.td,{children:"Casper Go SDK"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-01"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/hello-world",children:"Casper Hello World Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKey"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-13"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/casper-js-sdk",children:"Casper JavaScript SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client JavaScript SDK"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-Kotlin-sdk",children:"Casper Kotlin SDK"})}),(0,t.jsx)(n.td,{children:"Casper Kotlin Client SDK to interact with a Casper network."}),(0,t.jsx)(n.td,{children:"tqhuy2018"}),(0,t.jsx)(n.td,{children:"Kotlin"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-21"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/Casper-Metrics",children:"Casper Metrics"})}),(0,t.jsx)(n.td,{children:"Casper Metrics - fast blockchain crawler, API, and analysis tool"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-09"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-nctl-docker",children:"Casper NCTL Docker"})}),(0,t.jsx)(n.td,{children:"A Docker container that runs Casper NCTL as a service"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Shell"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-17"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/caspercommunityio/node-red-contrib-casper",children:"Casper Node-RED"})}),(0,t.jsx)(n.td,{children:"Nodes to communicate with the Casper's Blockchain using node-red"}),(0,t.jsx)(n.td,{children:"caspercommunity.io"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-02-08"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/tqhuy2018/Casper-ObjectiveC-sdk",children:"Casper Objective-C SDK"})}),(0,t.jsx)(n.td,{children:"Casper Objective-C SDK is for interacting with the Casper Blockchain using RPC."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Objective-C"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-18"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-php-sdk",children:"Casper PHP SDK"})}),(0,t.jsx)(n.td,{children:"PHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHP"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/saitgulmez/casper-ruby-sdk",children:"Casper Ruby Client SDK"})}),(0,t.jsx)(n.td,{children:"Ruby SDK to interact with Casper network nodes via RPC."}),(0,t.jsx)(n.td,{children:"Sait Gulmez"}),(0,t.jsx)(n.td,{children:"Ruby"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-03-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/abahmanem/casper-scala-sdk",children:"Casper Scala SDK"})}),(0,t.jsx)(n.td,{children:"Casper Scala client SDK to interact with the Casper Network nodes via RPC"}),(0,t.jsx)(n.td,{children:"M.Abahmane"}),(0,t.jsx)(n.td,{children:"Scala"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-03-23"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://www.casperwallet.io/",children:"Casper Wallet"})}),(0,t.jsx)(n.td,{children:"A browser wallet for the Casper Network"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"TypeScript-JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-04-12"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/credentia-network/casper-ssi-demo",children:"Casper SSI Web App"})}),(0,t.jsx)(n.td,{children:"Casper SSI Framework in the form of a demo web application."}),(0,t.jsx)(n.td,{children:"Credentia Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-29"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casper-storage",children:"Casper Storage"})}),(0,t.jsx)(n.td,{children:"Casper storage - HD wallets"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/hienbui9999/CasperSDKInSwift",children:"Casper Swift SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client SDK. Casper SDK methods implementation in Swift."}),(0,t.jsx)(n.td,{children:"hienbui9999"}),(0,t.jsx)(n.td,{children:"Swift"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-06-08"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/two-party-multi-sig",children:"Casper Two-Party MultiSig Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys."}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-04-26"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/NodesGuru/casper-world",children:"Casper World"})}),(0,t.jsx)(n.td,{children:"Casper network status and decentralization map web application"}),(0,t.jsx)(n.td,{children:"Nodes Guru"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-01-26"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/CasperDash/casperdash-client",children:"CasperDash Wallet"})}),(0,t.jsx)(n.td,{children:"A non-custodial wallet for the Casper blockchain"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-14"}),(0,t.jsx)(n.td,{children:"Wallet"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/casperfyre-frontend",children:"CasperFYRE API"})}),(0,t.jsx)(n.td,{children:"Dispensory API interface for Casper Mainnet"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"JavaScript-PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-06"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casperholders/casperholdersfront",children:"CasperHolders"})}),(0,t.jsx)(n.td,{children:"First 3rd party UI to interact with Casper Blockchain"}),(0,t.jsx)(n.td,{children:"CasperHolders"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"Blockchain Explorer"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/chronologic/caspersign-validator-ui",children:"CasperSign"})}),(0,t.jsx)(n.td,{children:"The First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper Blockchain"}),(0,t.jsx)(n.td,{children:"ChronoLogic and Digital Strategies"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-08-31"}),(0,t.jsx)(n.td,{children:"dApp"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft",children:"CEP-78 Enhanced NFT Standard"})}),(0,t.jsx)(n.td,{children:"Standard Contract Generator for NFTs"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-23"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/casper-event-standard",children:"CES Rust Event Emitter"})}),(0,t.jsx)(n.td,{children:"Rust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-05-11"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-js-parser",children:"CES JS Parser"})}),(0,t.jsx)(n.td,{children:"JS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-03-27"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/ces-go-parser",children:"CES Go Parser"})}),(0,t.jsx)(n.td,{children:"Go library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution results"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Go"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2023-06-02"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/ledgerleapllc/cleareststake-frontend",children:"Clearest Stake"})}),(0,t.jsx)(n.td,{children:"Staking Asset Manager for Node operators and groups"}),(0,t.jsx)(n.td,{children:"LedgerLeap"}),(0,t.jsx)(n.td,{children:"PHP"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-04-02"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/make-software/dao-contracts",children:"DAO Contracts"})}),(0,t.jsx)(n.td,{children:"Smart Contracts for the MVPR On-Chain Governance System on Casper"}),(0,t.jsx)(n.td,{children:"MAKE Software"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-07-17"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/DHFinance/dhf-pay-front",children:"DHF PAY"})}),(0,t.jsx)(n.td,{children:"The crypto currency payment gateway on the CSPR blockchain"}),(0,t.jsx)(n.td,{children:"DHFinance"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-28"}),(0,t.jsx)(n.td,{children:"Payments"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dlndao/start/",children:"DLN DAO"})}),(0,t.jsx)(n.td,{children:"DLN DAO"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-10"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/dotoracle/bridge-ui",children:"DotOracle"})}),(0,t.jsx)(n.td,{children:"Realtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains."}),(0,t.jsx)(n.td,{children:"DotOracle Network"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-09-26"}),(0,t.jsx)(n.td,{children:"Bridge"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Dragonlair",children:"Dragon\u2019s Lair Style Staking"})}),(0,t.jsx)(n.td,{children:"Lair Style Staking"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-06-24"}),(0,t.jsx)(n.td,{children:"Staking"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-EIP1337",children:"Subscription Billing"})}),(0,t.jsx)(n.td,{children:"ERC-1337 subscription billing"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-04-07"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep18",children:"Casper Fungible Token"})}),(0,t.jsx)(n.td,{children:"Implementation of Fungible Tokens for Casper networks"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-01"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-ERC777",children:"Advanced Fungible Token"})}),(0,t.jsx)(n.td,{children:"ERC-777 + 1820 Advanced Fungible Token with Callbacks & Self Identification"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2022-08-16"}),(0,t.jsx)(n.td,{children:"Tokens"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/a3mc/helperbot",children:"Helper Bot"})}),(0,t.jsx)(n.td,{children:"Helper bot for improving DevDao VAs productivity"}),(0,t.jsx)(n.td,{children:"A3MC"}),(0,t.jsx)(n.td,{children:"TypeScript"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-08-19"}),(0,t.jsx)(n.td,{children:"Tools"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-java-sdk",children:"Java SDK"})}),(0,t.jsx)(n.td,{children:"Casper Client Java SDK"}),(0,t.jsx)(n.td,{children:"SyntiFi"}),(0,t.jsx)(n.td,{children:"Java"}),(0,t.jsx)(n.td,{children:"Apache-2.0 license"}),(0,t.jsx)(n.td,{children:"2021-04-20"}),(0,t.jsx)(n.td,{children:"Client SDK"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/kyc-proxy-contract",children:"KYC Proxy Contact"})}),(0,t.jsx)(n.td,{children:"This is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-07-01"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-LiquidNFT",children:"LiquidNFT"})}),(0,t.jsx)(n.td,{children:"NFT Collateralized Loans"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GNU General Public License v3.0"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/payment-example",children:"Payment Example Contract"})}),(0,t.jsx)(n.td,{children:"This example demonstrates the usage of purses to transfer motes inside a contract"}),(0,t.jsx)(n.td,{children:"Casper Labs"}),(0,t.jsx)(n.td,{children:"Rust"}),(0,t.jsx)(n.td,{children:"NA"}),(0,t.jsx)(n.td,{children:"2022-06-22"}),(0,t.jsx)(n.td,{children:"Example contracts"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/EKON-YAZILIM/ServicesDAO",children:"ServicesDAO"})}),(0,t.jsx)(n.td,{children:"The ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR."}),(0,t.jsx)(n.td,{children:"Ekon Yazilim"}),(0,t.jsx)(n.td,{children:"HTML-CSS-C#"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-09-13"}),(0,t.jsx)(n.td,{children:"DAO"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/Rengo-Labs/CasperLabs-Uniswap-DemoApp",children:"Uniswap DemoApp"})}),(0,t.jsx)(n.td,{children:"Uniswap UI + Contracts"}),(0,t.jsx)(n.td,{children:"Rengo Labs"}),(0,t.jsx)(n.td,{children:"JavaScript"}),(0,t.jsx)(n.td,{children:"GPL-3.0 license"}),(0,t.jsx)(n.td,{children:"2022-09-15"}),(0,t.jsx)(n.td,{children:"DeFi"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://github.com/AdelElMessiry/Verified-Impact-NFTs",children:"Verified Impact NFT"})}),(0,t.jsx)(n.td,{children:"An NFT platform dedicated to impact causes with verification of the beneficiaries"}),(0,t.jsx)(n.td,{children:"AlphaFin"}),(0,t.jsx)(n.td,{children:"JavaScript-Rust"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2022-07-08"}),(0,t.jsx)(n.td,{children:"NFT"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://usewallet.casperdash.io",children:"UseWallet"})}),(0,t.jsx)(n.td,{children:"useWallet is a collection of React Hooks containing everything you need to start working with a Casper network"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"dApp library"})]}),(0,t.jsxs)(n.tr,{children:[(0,t.jsx)(n.td,{children:(0,t.jsx)(n.a,{href:"https://faucet.casperdash.io",children:"Testnet Faucet"})}),(0,t.jsx)(n.td,{children:"A faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for free"}),(0,t.jsx)(n.td,{children:"CasperDash"}),(0,t.jsx)(n.td,{children:"Typescript-React"}),(0,t.jsx)(n.td,{children:"MIT license"}),(0,t.jsx)(n.td,{children:"2023-09-19"}),(0,t.jsx)(n.td,{children:"Tools"})]})]})]})]})}function o(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(a,{...e})}):a(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>i});var t=s(96540);const r={},d=t.createContext(r);function c(e){const n=t.useContext(d);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:c(e.components),t.createElement(d.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f8743170.a30916fe.js b/assets/js/f8743170.a30916fe.js new file mode 100644 index 000000000..da714214d --- /dev/null +++ b/assets/js/f8743170.a30916fe.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[73421],{65916:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>c});var i=s(74848),t=s(28453);const r={title:"Move a Node"},o="Moving a Validating Node",d={id:"operators/maintenance/moving-node",title:"Move a Node",description:"This guide is for active validators who want to move their node to another machine.",source:"@site/versioned_docs/version-2.0.0/operators/maintenance/moving-node.md",sourceDirName:"operators/maintenance",slug:"/operators/maintenance/moving-node",permalink:"/2.0.0/operators/maintenance/moving-node",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Move a Node"},sidebar:"operators",previous:{title:"Archive and Restore a DB",permalink:"/2.0.0/operators/maintenance/archiving-and-restoring"}},a={},c=[{value:"Swapping Keys with a Hot Backup",id:"swapping-keys-with-a-hot-backup",level:2},{value:"Preparation for swapping",id:"preparation-for-swapping",level:3},{value:"Swapping the nodes",id:"swapping-the-nodes",level:3},{value:"Understanding rewards impact",id:"understanding-rewards-impact",level:3},{value:"Checking file permissions",id:"checking-file-permissions",level:3}];function l(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"moving-a-validating-node",children:"Moving a Validating Node"})}),"\n",(0,i.jsx)(n.p,{children:"This guide is for active validators who want to move their node to another machine."}),"\n",(0,i.jsx)(n.admonition,{type:"note",children:(0,i.jsx)(n.p,{children:"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."})}),"\n",(0,i.jsx)(n.h2,{id:"swapping-keys-with-a-hot-backup",children:"Swapping Keys with a Hot Backup"}),"\n",(0,i.jsx)(n.p,{children:"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."}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["Once a node is running (",(0,i.jsx)(n.code,{children:"current_node"}),"), create a second node (",(0,i.jsx)(n.code,{children:"backup_node"}),") on another machine. These two nodes will run in parallel."]}),"\n",(0,i.jsxs)(n.li,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Move the unit files at the DB level using ",(0,i.jsx)(n.code,{children:"rsync"}),". This step allows moving the node with nearly zero rewards loss."]}),"\n",(0,i.jsxs)(n.li,{children:["Stop the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"backup_node"}),", now the new validator."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsxs)(n.li,{children:["Swap keys on the ",(0,i.jsx)(n.code,{children:"current_node"}),", now the new backup."]}),"\n",(0,i.jsxs)(n.li,{children:["Restart the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"preparation-for-swapping",children:"Preparation for swapping"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Let both nodes synchronize to the tip of the blockchain. Keep the current validating node running with the original validator keyset."}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsx)(n.p,{children:"Prepare to swap keys by following these steps:"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:["Create the following folder structure on both nodes under the ",(0,i.jsx)(n.code,{children:"/etc/casper/validator_keys/"})," directory."]}),"\n",(0,i.jsxs)(n.li,{children:["Create subdirectories for the ",(0,i.jsx)(n.code,{children:"current_node"})," and ",(0,i.jsx)(n.code,{children:"backup_node"}),"."]}),"\n",(0,i.jsx)(n.li,{children:"Copy each node's keyset under the corresponding directories."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:" /etc/casper/validator_keys/\n \u251c\u2500\u2500 public_key.pem\n \u251c\u2500\u2500 public_key_hex\n \u251c\u2500\u2500 secret_key.pem\n \u251c\u2500\u2500 current_node\n \u2502 \u251c\u2500\u2500 public_key.pem\n \u2502 \u251c\u2500\u2500 public_key_hex\n \u2502 \u2514\u2500\u2500 secret_key.pem\n \u2514\u2500\u2500 backup_node\n | \u251c\u2500\u2500 public_key.pem\n | \u251c\u2500\u2500 public_key_hex\n | \u2514\u2500\u2500 secret_key.pem\n"})}),"\n",(0,i.jsxs)(n.p,{children:["This setup allows key swapping by running the ",(0,i.jsx)(n.code,{children:"sudo -u casper cp * ../"})," command, as shown below."]}),"\n",(0,i.jsx)(n.h3,{id:"swapping-the-nodes",children:"Swapping the nodes"}),"\n",(0,i.jsxs)(n.ol,{children:["\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"backup_node"})," is up to date, stop the ",(0,i.jsx)(n.code,{children:"current_node"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"})," (the future validator), use ",(0,i.jsx)(n.code,{children:"rsync"})," to move the unit files from the ",(0,i.jsx)(n.code,{children:"current_node"}),", located in ",(0,i.jsx)(n.code,{children:"/var/lib/casper/casper-node/[NETWORK_NAME]/unit_files"}),"."]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"backup_node"}),", run these commands to stop the node, swap keys, and restart the node:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/current_node\nsudo -u casper cp * ../\nsudo systemctl start casper-node-launcher\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["On the ",(0,i.jsx)(n.code,{children:"current_node"}),", run these commands to stop the node and swap keys:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl stop casper-node-launcher\ncd /etc/casper/validator_keys/backup_node\nsudo -u casper cp * ../\n"})}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:["\n",(0,i.jsxs)(n.p,{children:["Restart the original validator node (",(0,i.jsx)(n.code,{children:"current_node"}),"), which is now the new backup:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo systemctl start casper-node-launcher \n"})}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.h3,{id:"understanding-rewards-impact",children:"Understanding rewards impact"}),"\n",(0,i.jsx)(n.p,{children:"After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era."}),"\n",(0,i.jsx)(n.admonition,{type:"tip",children:(0,i.jsx)(n.p,{children:"You could time the swap right before the era ends to minimize reward losses."})}),"\n",(0,i.jsx)(n.h3,{id:"checking-file-permissions",children:"Checking file permissions"}),"\n",(0,i.jsxs)(n.p,{children:["After the swap, check and fix file permissions by running the ",(0,i.jsx)(n.code,{children:"/etc/casper/node_util.py"})," utility."]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>d});var i=s(96540);const t={},r=i.createContext(t);function o(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f88cb658.93e9da43.js b/assets/js/f88cb658.93e9da43.js new file mode 100644 index 000000000..624939704 --- /dev/null +++ b/assets/js/f88cb658.93e9da43.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[61153],{56531:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=o(74848),s=o(28453);const r={title:"Staging Files"},t="Staging Files for a New Network",c={id:"operators/setup-network/staging-files-for-new-network",title:"Staging Files",description:"Staging files is not needed for already established running networks.",source:"@site/docs/operators/setup-network/staging-files-for-new-network.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/staging-files-for-new-network",permalink:"/operators/setup-network/staging-files-for-new-network",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Staging Files"},sidebar:"operators",previous:{title:"Private Network Setup",permalink:"/operators/setup-network/create-private"},next:{title:"Node Maintenance",permalink:"/operators/maintenance/"}},l={},d=[{value:"Hosting Server",id:"hosting-server",level:2},{value:"More on <code>protocol_versions</code>",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"staging-files-for-a-new-network",children:"Staging Files for a New Network"})}),"\n",(0,i.jsxs)(n.admonition,{type:"important",children:[(0,i.jsx)(n.p,{children:"Staging files is not needed for already established running networks."}),(0,i.jsx)(n.p,{children:"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network."})]}),"\n",(0,i.jsx)(n.h2,{id:"hosting-server",children:"Hosting Server"}),"\n",(0,i.jsx)(n.p,{children:"Files for staging protocol versions are hosted on a typical HTTP(S) server."}),"\n",(0,i.jsxs)(n.p,{children:["Scripts included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."]}),"\n",(0,i.jsx)(n.p,{children:"Since a given server can be used for multiple networks, a network named directory is used to\nhold files for that network."}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of Mainnet protocol version hosting (with network name: ",(0,i.jsx)(n.code,{children:"casper"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"genesis.casperlab.io"})," is the web server URL with the following directory structure:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"protocol_versions"})," - File listing active protocol versions so scripts know what directories to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0"})," - Genesis protocol version\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_1_0"})," - First upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_1_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_1_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"... (skipping many other protocol versions)"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_4_6"})," - A later upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_4_6"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_4_6"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"more-on-protocol_versions",children:["More on ",(0,i.jsx)(n.code,{children:"protocol_versions"})]}),"\n",(0,i.jsxs)(n.p,{children:["At the root of the hosting server directory for a given network, a ",(0,i.jsx)(n.code,{children:"protocol_versions"})," file exists. This holds the valid protocol versions for a network."]}),"\n",(0,i.jsxs)(n.p,{children:["We can look at this manually on Mainnet using ",(0,i.jsx)(n.em,{children:"curl"}),". As of writing this, ",(0,i.jsx)(n.code,{children:"1.4.6"})," is the latest version and the contents of this file will change."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We should find ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," in those directories under ",(0,i.jsx)(n.code,{children:"casper"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["The protocol version of a network is not related to the ",(0,i.jsx)(n.code,{children:"casper-node"})," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.jsx)(n.code,{children:"casper-node"})," version for your\n",(0,i.jsx)(n.code,{children:"1.0.0"})," protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"network-configuration-file",children:"Network Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," package is installed, both ",(0,i.jsx)(n.code,{children:"casper.conf"})," and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," are installed\nin ",(0,i.jsx)(n.code,{children:"/etc/casper/network_configs"}),". Once a valid config file for a new network is copied to this location,\nall commands with ",(0,i.jsx)(n.em,{children:"node_util.py"})," will work as they do on existing networks."]}),"\n",(0,i.jsxs)(n.p,{children:["By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.jsx)(n.code,{children:"casper"})," and we use\n",(0,i.jsx)(n.code,{children:"casper.conf"})," for the config file."]}),"\n",(0,i.jsxs)(n.p,{children:["For a new network using server ",(0,i.jsx)(n.code,{children:"casper.mydomain.com"})," to host files for ",(0,i.jsx)(n.code,{children:"our-network"})," network, we would have a\n",(0,i.jsx)(n.code,{children:"our-network.conf"})," file that looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Host this ",(0,i.jsx)(n.code,{children:"our-network.conf"})," in the root of ",(0,i.jsx)(n.code,{children:"casper.mydomain.com/our-network"})," at the same level as ",(0,i.jsx)(n.code,{children:"protocol_versions"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This allows any node which wants to use the new network to run the following to install this configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any command needing a network config from ",(0,i.jsx)(n.code,{children:"node_util.py"})," can use ",(0,i.jsx)(n.code,{children:"our-network.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n"})}),"\n",(0,i.jsx)(n.h2,{id:"setup-configuration-files",children:"Setup Configuration Files"}),"\n",(0,i.jsx)(n.p,{children:"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."}),"\n",(0,i.jsx)(n.h3,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec.toml"})," file is configuration for the network and must be exactly the same on all nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["The name for a network is specified ",(0,i.jsx)(n.code,{children:"network.name"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Each protocol will have a ",(0,i.jsx)(n.code,{children:"version"})," and ",(0,i.jsx)(n.code,{children:"activation_point"}),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.jsx)(n.code,{children:"era_id"})," for activation of the upgrade."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"config-exampletoml",children:"config-example.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.jsx)(n.code,{children:"public_address"})," is auto-detected with ",(0,i.jsx)(n.code,{children:"node_util.py stage_protocols"}),". If using a NAT environment, the public IP can be specified with the ",(0,i.jsx)(n.code,{children:"--ip"})," argument."]}),"\n",(0,i.jsxs)(n.p,{children:["This file should have ",(0,i.jsx)(n.code,{children:"known_addresses"})," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[network]\nknown_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.toml"})," can be setup to customized fields for a given node. ",(0,i.jsx)(n.code,{children:"config-example.toml"})," is a default configuration."]}),"\n",(0,i.jsx)(n.h2,{id:"staging-a-protocol-version",children:"Staging a Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["For the initial genesis protocol version or future upgrade protocol versions, you will typically use\nprebuilt and tested ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," that have been tested and staged for existing networks. The ",(0,i.jsx)(n.code,{children:"config.tar.gz"}),"\nfile must be customized for the specific network with a network name, protocol version and activation point at the very least."]}),"\n",(0,i.jsxs)(n.p,{children:["These archives should be created with no directory information stored. This is done by using ",(0,i.jsx)(n.code,{children:"tar"})," in the same directory as the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can test what was compressed with untar'ing the file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will expand files for verification."}),"\n",(0,i.jsxs)(n.p,{children:["For custom ",(0,i.jsx)(n.code,{children:"casper-node"})," builds, the minimum contents of ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," is the ",(0,i.jsx)(n.code,{children:"casper-node"})," executable."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A directory for the protocol_version will be created on the server. For example: ",(0,i.jsx)(n.code,{children:"1_1_0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will copy ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," into ",(0,i.jsx)(n.code,{children:"1_1_0"}),". Once this is done, we are safe to update\n",(0,i.jsx)(n.code,{children:"protocol_versions"})," by appending ",(0,i.jsx)(n.code,{children:"1_1_0"})," to the end of the file and uploading it into the root of the network directory."]}),"\n",(0,i.jsx)(n.p,{children:"Any node that runs the following command will get this new upgrade:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>c});var i=o(96540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f88cb658.de8becbc.js b/assets/js/f88cb658.de8becbc.js deleted file mode 100644 index a121114d8..000000000 --- a/assets/js/f88cb658.de8becbc.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1153],{56531:(e,n,o)=>{o.r(n),o.d(n,{assets:()=>l,contentTitle:()=>t,default:()=>h,frontMatter:()=>r,metadata:()=>c,toc:()=>d});var i=o(74848),s=o(28453);const r={title:"Staging Files"},t="Staging Files for a New Network",c={id:"operators/setup-network/staging-files-for-new-network",title:"Staging Files",description:"Staging files is not needed for already established running networks.",source:"@site/docs/operators/setup-network/staging-files-for-new-network.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/staging-files-for-new-network",permalink:"/next/operators/setup-network/staging-files-for-new-network",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Staging Files"},sidebar:"operators",previous:{title:"Private Network Setup",permalink:"/next/operators/setup-network/create-private"},next:{title:"Node Maintenance",permalink:"/next/operators/maintenance/"}},l={},d=[{value:"Hosting Server",id:"hosting-server",level:2},{value:"More on <code>protocol_versions</code>",id:"more-on-protocol_versions",level:3},{value:"Protocol Version",id:"protocol-version",level:2},{value:"Network Configuration File",id:"network-configuration-file",level:2},{value:"Setup Configuration Files",id:"setup-configuration-files",level:2},{value:"chainspec.toml",id:"chainspectoml",level:3},{value:"config-example.toml",id:"config-exampletoml",level:3},{value:"Staging a Protocol Version",id:"staging-a-protocol-version",level:2}];function a(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.header,{children:(0,i.jsx)(n.h1,{id:"staging-files-for-a-new-network",children:"Staging Files for a New Network"})}),"\n",(0,i.jsxs)(n.admonition,{type:"important",children:[(0,i.jsx)(n.p,{children:"Staging files is not needed for already established running networks."}),(0,i.jsx)(n.p,{children:"Only use these instructions if you are creating a new Casper network and hosting protocol files for this network."})]}),"\n",(0,i.jsx)(n.h2,{id:"hosting-server",children:"Hosting Server"}),"\n",(0,i.jsx)(n.p,{children:"Files for staging protocol versions are hosted on a typical HTTP(S) server."}),"\n",(0,i.jsxs)(n.p,{children:["Scripts included with the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," have network configurations for Mainnet and Testnet. These scripts point to the server hosting files and network name."]}),"\n",(0,i.jsx)(n.p,{children:"Since a given server can be used for multiple networks, a network named directory is used to\nhold files for that network."}),"\n",(0,i.jsxs)(n.p,{children:["This is a description of Mainnet protocol version hosting (with network name: ",(0,i.jsx)(n.code,{children:"casper"}),")."]}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.code,{children:"genesis.casperlab.io"})," is the web server URL with the following directory structure:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"casper"}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"protocol_versions"})," - File listing active protocol versions so scripts know what directories to use"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_0_0"})," - Genesis protocol version\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_0_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_0_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_1_0"})," - First upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_1_0"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_1_0"})]}),"\n"]}),"\n"]}),"\n",(0,i.jsx)(n.li,{children:"... (skipping many other protocol versions)"}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"1_4_6"})," - A later upgrade\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"config.tar.gz"})," - Configuration files to be expanded into ",(0,i.jsx)(n.code,{children:"/etc/casper/1_4_6"})]}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"bin.tar.gz"})," - Binary files to be expanded into ",(0,i.jsx)(n.code,{children:"/var/lib/casper/bin/1_4_6"})]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,i.jsxs)(n.h3,{id:"more-on-protocol_versions",children:["More on ",(0,i.jsx)(n.code,{children:"protocol_versions"})]}),"\n",(0,i.jsxs)(n.p,{children:["At the root of the hosting server directory for a given network, a ",(0,i.jsx)(n.code,{children:"protocol_versions"})," file exists. This holds the valid protocol versions for a network."]}),"\n",(0,i.jsxs)(n.p,{children:["We can look at this manually on Mainnet using ",(0,i.jsx)(n.em,{children:"curl"}),". As of writing this, ",(0,i.jsx)(n.code,{children:"1.4.6"})," is the latest version and the contents of this file will change."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"\n$ curl -s genesis.casperlabs.io/casper/protocol_versions\n1_0_0\n1_1_0\n1_1_2\n1_2_0\n1_2_1\n1_3_2\n1_3_4\n1_4_1\n1_4_3\n1_4_4\n1_4_5\n1_4_6\n\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We should find ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," in those directories under ",(0,i.jsx)(n.code,{children:"casper"}),"."]}),"\n",(0,i.jsx)(n.h2,{id:"protocol-version",children:"Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["The protocol version of a network is not related to the ",(0,i.jsx)(n.code,{children:"casper-node"})," version. In Mainnet, these have often been the same. However, with a new network, you would use the latest ",(0,i.jsx)(n.code,{children:"casper-node"})," version for your\n",(0,i.jsx)(n.code,{children:"1.0.0"})," protocol."]}),"\n",(0,i.jsx)(n.h2,{id:"network-configuration-file",children:"Network Configuration File"}),"\n",(0,i.jsxs)(n.p,{children:["When the ",(0,i.jsx)(n.code,{children:"casper-node-launcher"})," package is installed, both ",(0,i.jsx)(n.code,{children:"casper.conf"})," and ",(0,i.jsx)(n.code,{children:"casper-test.conf"})," are installed\nin ",(0,i.jsx)(n.code,{children:"/etc/casper/network_configs"}),". Once a valid config file for a new network is copied to this location,\nall commands with ",(0,i.jsx)(n.em,{children:"node_util.py"})," will work as they do on existing networks."]}),"\n",(0,i.jsxs)(n.p,{children:["By convention, we name the config file the same as the network. So Mainnet has a network name of ",(0,i.jsx)(n.code,{children:"casper"})," and we use\n",(0,i.jsx)(n.code,{children:"casper.conf"})," for the config file."]}),"\n",(0,i.jsxs)(n.p,{children:["For a new network using server ",(0,i.jsx)(n.code,{children:"casper.mydomain.com"})," to host files for ",(0,i.jsx)(n.code,{children:"our-network"})," network, we would have a\n",(0,i.jsx)(n.code,{children:"our-network.conf"})," file that looks like this:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"SOURCE_URL=casper.mydomain.com\nNETWORK_NAME=our-network\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Host this ",(0,i.jsx)(n.code,{children:"our-network.conf"})," in the root of ",(0,i.jsx)(n.code,{children:"casper.mydomain.com/our-network"})," at the same level as ",(0,i.jsx)(n.code,{children:"protocol_versions"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"This allows any node which wants to use the new network to run the following to install this configuration:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"cd /etc/casper/network_configs\nsudo -u casper curl -JLO casper.mydomain.com/our-network/our-network.conf\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Any command needing a network config from ",(0,i.jsx)(n.code,{children:"node_util.py"})," can use ",(0,i.jsx)(n.code,{children:"our-network.conf"}),"."]}),"\n",(0,i.jsx)(n.p,{children:"Staging protocol versions for a new node with this network or staging an upcoming upgrade would just need this command:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols our-network.conf\n"})}),"\n",(0,i.jsx)(n.h2,{id:"setup-configuration-files",children:"Setup Configuration Files"}),"\n",(0,i.jsx)(n.p,{children:"For a network to be started, we to build the configuration files for a certain genesis time and with nodes that will be running. These files need to be configured in advanced, so a genesis time should be selected that allows packaging the files, loading onto nodes and starting nodes prior to the genesis time."}),"\n",(0,i.jsx)(n.h3,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.a,{href:"/next/concepts/glossary/C#chainspec",children:"chainspec.toml"})," file is configuration for the network and must be exactly the same on all nodes."]}),"\n",(0,i.jsxs)(n.p,{children:["The name for a network is specified ",(0,i.jsx)(n.code,{children:"network.name"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["Each protocol will have a ",(0,i.jsx)(n.code,{children:"version"})," and ",(0,i.jsx)(n.code,{children:"activation_point"}),". At genesis this is a date and time in format shown below. For future upgrades it would be an integer of the ",(0,i.jsx)(n.code,{children:"era_id"})," for activation of the upgrade."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[protocol]\nversion = '1.0.0'\nactivation_point = '2022-08-01T10:00:00Z'\n\n[network]\nname = 'mynetwork'\n"})}),"\n",(0,i.jsx)(n.h3,{id:"config-exampletoml",children:"config-example.toml"}),"\n",(0,i.jsxs)(n.p,{children:["The config-example.toml is used to generate config.toml for a protocol after the node's IP is inserted. The ",(0,i.jsx)(n.code,{children:"public_address"})," is auto-detected with ",(0,i.jsx)(n.code,{children:"node_util.py stage_protocols"}),". If using a NAT environment, the public IP can be specified with the ",(0,i.jsx)(n.code,{children:"--ip"})," argument."]}),"\n",(0,i.jsxs)(n.p,{children:["This file should have ",(0,i.jsx)(n.code,{children:"known_addresses"})," added that are relevant to the network. Nodes that will be genesis validators are added to this list in the form:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"[network]\nknown_addresses = ['<ip 1>:35000','<ip 2>:35000','<ip 3>:35000']\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The ",(0,i.jsx)(n.code,{children:"config.toml"})," can be setup to customized fields for a given node. ",(0,i.jsx)(n.code,{children:"config-example.toml"})," is a default configuration."]}),"\n",(0,i.jsx)(n.h2,{id:"staging-a-protocol-version",children:"Staging a Protocol Version"}),"\n",(0,i.jsxs)(n.p,{children:["For the initial genesis protocol version or future upgrade protocol versions, you will typically use\nprebuilt and tested ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," that have been tested and staged for existing networks. The ",(0,i.jsx)(n.code,{children:"config.tar.gz"}),"\nfile must be customized for the specific network with a network name, protocol version and activation point at the very least."]}),"\n",(0,i.jsxs)(n.p,{children:["These archives should be created with no directory information stored. This is done by using ",(0,i.jsx)(n.code,{children:"tar"})," in the same directory as the files."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir config\ncd config\nmv [source of chainspec.toml] ./chainspec.toml\nmv [source of config-example.toml] ./config-example.toml\ntar -czvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"You can test what was compressed with untar'ing the file."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir conftest\ncd conftest\ntar -xzvf ../config.tar.gz .\n"})}),"\n",(0,i.jsx)(n.p,{children:"This will expand files for verification."}),"\n",(0,i.jsxs)(n.p,{children:["For custom ",(0,i.jsx)(n.code,{children:"casper-node"})," builds, the minimum contents of ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," is the ",(0,i.jsx)(n.code,{children:"casper-node"})," executable."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"mkdir bin\ncd bin\ncp [source of casper-node] ./casper-node\ntar -czvf ../bin.tar.gz .\n"})}),"\n",(0,i.jsxs)(n.p,{children:["A directory for the protocol_version will be created on the server. For example: ",(0,i.jsx)(n.code,{children:"1_1_0"}),"."]}),"\n",(0,i.jsxs)(n.p,{children:["We will copy ",(0,i.jsx)(n.code,{children:"bin.tar.gz"})," and ",(0,i.jsx)(n.code,{children:"config.tar.gz"})," into ",(0,i.jsx)(n.code,{children:"1_1_0"}),". Once this is done, we are safe to update\n",(0,i.jsx)(n.code,{children:"protocol_versions"})," by appending ",(0,i.jsx)(n.code,{children:"1_1_0"})," to the end of the file and uploading it into the root of the network directory."]}),"\n",(0,i.jsx)(n.p,{children:"Any node that runs the following command will get this new upgrade:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-bash",children:"sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>\n"})})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(a,{...e})}):a(e)}},28453:(e,n,o)=>{o.d(n,{R:()=>t,x:()=>c});var i=o(96540);const s={},r=i.createContext(s);function t(e){const n=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:t(e.components),i.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f95b1f88.2c0ea01f.js b/assets/js/f95b1f88.2c0ea01f.js new file mode 100644 index 000000000..5ac2c41e5 --- /dev/null +++ b/assets/js/f95b1f88.2c0ea01f.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[67876],{70748:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>t,metadata:()=>d,toc:()=>a});var s=i(74848),l=i(28453);const t={},r="Primitives and Basic Serialization Rules",d={id:"concepts/serialization/primitives",title:"Primitives and Basic Serialization Rules",description:"CLValue",source:"@site/docs/concepts/serialization/primitives.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/primitives",permalink:"/concepts/serialization/primitives",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Binary Serialization Standard",permalink:"/concepts/serialization/"},next:{title:"Major Structures",permalink:"/concepts/serialization/structures"}},c={},a=[{value:"<code>CLValue</code>",id:"clvalue",level:2},{value:"Boolean",id:"clvalue-boolean",level:3},{value:"Numeric",id:"clvalue-numeric",level:3},{value:"Unit",id:"clvalue-unit",level:3},{value:"String",id:"clvalue-string",level:3},{value:"Option",id:"clvalue-option",level:3},{value:"List",id:"clvalue-list",level:3},{value:"ByteArray",id:"clvalue-ByteArray",level:3},{value:"Result",id:"clvalue-result",level:3},{value:"Tuple",id:"clvalue-tuple",level:3},{value:"Map",id:"clvalue-map",level:3},{value:"URef",id:"clvalue-uref",level:3},{value:"PublicKey",id:"clvalue-publickey",level:3},{value:"Key",id:"clvalue-key",level:3},{value:"CLType",id:"clvalue-cltype",level:3},{value:"CLValue",id:"clvalue-clvalue",level:3},{value:"Contracts",id:"global-state-contracts",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"primitives-and-basic-serialization-rules",children:"Primitives and Basic Serialization Rules"})}),"\n",(0,s.jsx)(n.h2,{id:"clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," describes data that is used by smart contracts. This could be a local state variable, input argument, or return value. A ",(0,s.jsx)(n.code,{children:"CLValue"})," consists of two parts: a ",(0,s.jsx)(n.code,{children:"CLType"})," describing the type of the value and an array of bytes representing the data in our serialization format."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," is described by the following recursive data type:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All data that can be assigned a (non-",(0,s.jsx)(n.code,{children:"Any"}),") ",(0,s.jsx)(n.code,{children:"CLType"})," can be serialized according to the following rules, which define the Casper serialization format:"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-boolean",children:"Boolean"}),"\n",(0,s.jsxs)(n.p,{children:["Boolean values serialize as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-numeric",children:"Numeric"}),"\n",(0,s.jsx)(n.p,{children:"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u8"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"1024u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00040000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Wider numeric values (i.e. ",(0,s.jsx)(n.code,{children:"U128"}),", ",(0,s.jsx)(n.code,{children:"U256"}),", ",(0,s.jsx)(n.code,{children:"U512"}),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This reduces the serialization size when small numbers are represented within a wide data type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(7)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x0107"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(1024)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x020004"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:'U512::from("123456789101112131415")'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0957ff1ada959f4eb106"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-unit",children:"Unit"}),"\n",(0,s.jsx)(n.p,{children:"Unit serializes to an empty byte array."}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-string",children:"String"}),"\n",(0,s.jsx)(n.p,{children:"Strings serialize as a 32-bit integer representing the length in bytes (that might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:'"Hello, World!"'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0d00000048656c6c6f2c20576f726c6421"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-option",children:"Option"}),"\n",(0,s.jsxs)(n.p,{children:["Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,s.jsx)(n.code,{children:"0"})," if the value is missing, and ",(0,s.jsx)(n.code,{children:"1"})," if it is present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"None"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"Some(10u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010a000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-list",children:"List"}),"\n",(0,s.jsxs)(n.p,{children:["A list of values serializes as a 32-bit integer representing the number of elements in the list (differing from strings where it gives the number of ",(0,s.jsx)(n.em,{children:"bytes"}),"), followed by the concatenation of each serialized element."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List()"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00000000"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List(1u32, 2u32, 3u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x03000000010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-ByteArray",children:"ByteArray"}),"\n",(0,s.jsx)(n.p,{children:"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"[1u32, 2u32, 3u32]"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-result",children:"Result"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Result"})," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,s.jsx)(n.code,{children:"1"})," for the success variant and ",(0,s.jsx)(n.code,{children:"0"})," for the error variant."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-tuple",children:"Tuple"}),"\n",(0,s.jsxs)(n.p,{children:["Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,s.jsx)(n.code,{children:"ByteArray"})," the number of elements is not included in the serialization because it is statically known in the type."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-map",children:"Map"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Map"})," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,s.jsx)(n.code,{children:"Map"})," data structures can be unordered."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-uref",children:"URef"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," values serialize as the concatenation of their address (a fixed-length list of ",(0,s.jsx)(n.code,{children:"u8"}),") and a single byte tag representing access rights, which are converted as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Access Rights"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"NONE"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WRITE"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_WRITE"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"7"})]})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["When passing a URef to another entity on chain, you must ensure that the ",(0,s.jsx)(n.code,{children:"AccessRights"})," are set correctly. If the URef represents a ",(0,s.jsx)(n.a,{href:"/concepts/glossary/P#purse",children:"purse"}),", ",(0,s.jsx)(n.code,{children:"AccessRights"})," impact who can deposit and withdraw CSPR."]})}),"\n",(0,s.jsxs)(n.p,{children:["If a passed URef contains ",(0,s.jsx)(n.code,{children:"ADD"})," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions. In this event, ",(0,s.jsx)(n.code,{children:"READ"})," and ",(0,s.jsx)(n.code,{children:"ADD"})," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions unintentionally."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PublicKey"})," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,s.jsx)(n.code,{children:"PublicKey"})," itself:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"System"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"0"}),". With this variant, the single byte of ",(0,s.jsx)(n.code,{children:"0"})," is the entire key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the single tag byte is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-key",children:"Key"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Key"})," values serialize as a single byte tag representing the variant, followed by the serialization of the data that the variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,s.jsx)(n.code,{children:"Key::URef"}),", which contains a ",(0,s.jsx)(n.code,{children:"URef"}),"; so its data serializes per the description above. The tags are as follows: ",(0,s.jsx)(n.code,{children:"Key::Account"})," serializes as ",(0,s.jsx)(n.code,{children:"0"}),", ",(0,s.jsx)(n.code,{children:"Key::Hash"})," as ",(0,s.jsx)(n.code,{children:"1"}),", ",(0,s.jsx)(n.code,{children:"Key::URef"})," as ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-cltype",children:"CLType"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," itself also has rules for serialization. A ",(0,s.jsx)(n.code,{children:"CLType"})," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,s.jsx)(n.code,{children:"ByteArray"})," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"CLType"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I32"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I64"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U8"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U32"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U64"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U128"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U256"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U512"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unit"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"12"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Option"})}),(0,s.jsx)(n.td,{children:"13"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"List"})}),(0,s.jsx)(n.td,{children:"14"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ByteArray"})}),(0,s.jsx)(n.td,{children:"15"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Result"})}),(0,s.jsx)(n.td,{children:"16"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Map"})}),(0,s.jsx)(n.td,{children:"17"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple1"})}),(0,s.jsx)(n.td,{children:"18"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple2"})}),(0,s.jsx)(n.td,{children:"19"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple3"})}),(0,s.jsx)(n.td,{children:"20"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Any"})}),(0,s.jsx)(n.td,{children:"21"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PublicKey"})}),(0,s.jsx)(n.td,{children:"22"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-clvalue",children:"CLValue"}),"\n",(0,s.jsxs)(n.p,{children:["A complete ",(0,s.jsx)(n.code,{children:"CLValue"}),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-contracts",children:"Contracts"}),"\n",(0,s.jsxs)(n.p,{children:["Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,s.jsx)(n.em,{children:"contract"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a ",(0,s.jsx)(n.a,{href:"https://webassembly.github.io/spec/core/syntax/modules.html",children:"wasm module"})]}),"\n",(0,s.jsx)(n.li,{children:"a collection of named keys"}),"\n",(0,s.jsx)(n.li,{children:"a protocol version"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The wasm module must contain a function named ",(0,s.jsx)(n.code,{children:"call"}),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,s.jsx)(n.a,{href:"/concepts/design/casper-design#execution-semantics-runtime",children:"Casper runtime"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note: though the ",(0,s.jsx)(n.code,{children:"call"})," function signature has no arguments and no return value, within the ",(0,s.jsx)(n.code,{children:"call"})," function body, the ",(0,s.jsx)(n.code,{children:"get_named_arg"})," runtime function can be used to accept arguments (by ordinal), and the ",(0,s.jsx)(n.code,{children:"ret"})," runtime function can be used to return a single ",(0,s.jsx)(n.code,{children:"CLValue"})," to the caller."]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,s.jsx)(n.code,{children:"URef"}),"s, which are known to the contract (see the section on Permissions for details)."]}),"\n",(0,s.jsx)(n.p,{children:"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."})]})}function o(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var s=i(96540);const l={},t=s.createContext(l);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/f95b1f88.7cc6f7b3.js b/assets/js/f95b1f88.7cc6f7b3.js deleted file mode 100644 index 57f9f390f..000000000 --- a/assets/js/f95b1f88.7cc6f7b3.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[7876],{70748:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>r,default:()=>o,frontMatter:()=>t,metadata:()=>d,toc:()=>a});var s=i(74848),l=i(28453);const t={},r="Primitives and Basic Serialization Rules",d={id:"concepts/serialization/primitives",title:"Primitives and Basic Serialization Rules",description:"CLValue",source:"@site/docs/concepts/serialization/primitives.md",sourceDirName:"concepts/serialization",slug:"/concepts/serialization/primitives",permalink:"/next/concepts/serialization/primitives",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"sczembor",lastUpdatedAt:1724329928e3,frontMatter:{},sidebar:"concepts",previous:{title:"Binary Serialization Standard",permalink:"/next/concepts/serialization/"},next:{title:"Major Structures",permalink:"/next/concepts/serialization/structures"}},c={},a=[{value:"<code>CLValue</code>",id:"clvalue",level:2},{value:"Boolean",id:"clvalue-boolean",level:3},{value:"Numeric",id:"clvalue-numeric",level:3},{value:"Unit",id:"clvalue-unit",level:3},{value:"String",id:"clvalue-string",level:3},{value:"Option",id:"clvalue-option",level:3},{value:"List",id:"clvalue-list",level:3},{value:"ByteArray",id:"clvalue-ByteArray",level:3},{value:"Result",id:"clvalue-result",level:3},{value:"Tuple",id:"clvalue-tuple",level:3},{value:"Map",id:"clvalue-map",level:3},{value:"URef",id:"clvalue-uref",level:3},{value:"PublicKey",id:"clvalue-publickey",level:3},{value:"Key",id:"clvalue-key",level:3},{value:"CLType",id:"clvalue-cltype",level:3},{value:"CLValue",id:"clvalue-clvalue",level:3},{value:"Contracts",id:"global-state-contracts",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",ul:"ul",...(0,l.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"primitives-and-basic-serialization-rules",children:"Primitives and Basic Serialization Rules"})}),"\n",(0,s.jsx)(n.h2,{id:"clvalue",children:(0,s.jsx)(n.code,{children:"CLValue"})}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLValue"})," describes data that is used by smart contracts. This could be a local state variable, input argument, or return value. A ",(0,s.jsx)(n.code,{children:"CLValue"})," consists of two parts: a ",(0,s.jsx)(n.code,{children:"CLType"})," describing the type of the value and an array of bytes representing the data in our serialization format."]}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," is described by the following recursive data type:"]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-rust",children:'enum CLType {\n Bool, // boolean primitive\n I32, // signed 32-bit integer primitive\n I64, // signed 64-bit integer primitive\n U8, // unsigned 8-bit integer primitive\n U32, // unsigned 32-bit integer primitive\n U64, // unsigned 64-bit integer primitive\n U128, // unsigned 128-bit integer primitive\n U256, // unsigned 256-bit integer primitive\n U512, // unsigned 512-bit integer primitive\n Unit, // singleton value without additional semantics\n String, // e.g. "Hello, World!"\n URef, // unforgeable reference (see above)\n Key, // global state key (see above)\n PublicKey // A Casper system PublicKey type\n Option(CLType), // optional value of the given type\n List(CLType), // list of values of the given type (e.g. Vec in rust)\n ByteArray(CLType, u32), // same as `List` above, but number of elements\n // is statically known (e.g. arrays in rust)\n Result(CLType, CLType), // co-product of the given types;\n // one variant meaning success, the other failure\n Map(CLType, CLType), // key-value association where keys and values have the given types\n Tuple1(CLType), // single value of the given type\n Tuple2(CLType, CLType), // pair consisting of elements of the given types\n Tuple3(CLType, CLType, CLType), // triple consisting of elements of the given types\n Any // Indicates the type is not known\n}\n'})}),"\n",(0,s.jsxs)(n.p,{children:["All data that can be assigned a (non-",(0,s.jsx)(n.code,{children:"Any"}),") ",(0,s.jsx)(n.code,{children:"CLType"})," can be serialized according to the following rules, which define the Casper serialization format:"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-boolean",children:"Boolean"}),"\n",(0,s.jsxs)(n.p,{children:["Boolean values serialize as a single byte; ",(0,s.jsx)(n.code,{children:"true"})," maps to ",(0,s.jsx)(n.code,{children:"1"}),", while ",(0,s.jsx)(n.code,{children:"false"})," maps to ",(0,s.jsx)(n.code,{children:"0"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-numeric",children:"Numeric"}),"\n",(0,s.jsx)(n.p,{children:"Numeric values consisting of 64 bits or less serialize in the two's complement representation with little-endian byte order, and the appropriate number of bytes for the bit-width."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u8"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"7u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x07000000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"1024u32"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00040000"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["Wider numeric values (i.e. ",(0,s.jsx)(n.code,{children:"U128"}),", ",(0,s.jsx)(n.code,{children:"U256"}),", ",(0,s.jsx)(n.code,{children:"U512"}),") serialize as one byte given the length of the next number (in bytes), followed by the two's complement representation with little-endian byte order. The number of bytes should be chosen as small as possible to represent the given number. This reduces the serialization size when small numbers are represented within a wide data type."]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(7)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x0107"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:"U512::from(1024)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x020004"})]}),"\n"]}),"\n",(0,s.jsxs)(n.li,{children:["\n",(0,s.jsxs)(n.p,{children:["E.g. ",(0,s.jsx)(n.code,{children:'U512::from("123456789101112131415")'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0957ff1ada959f4eb106"})]}),"\n"]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-unit",children:"Unit"}),"\n",(0,s.jsx)(n.p,{children:"Unit serializes to an empty byte array."}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-string",children:"String"}),"\n",(0,s.jsx)(n.p,{children:"Strings serialize as a 32-bit integer representing the length in bytes (that might be different than the number of characters since special characters, such as emojis, take more than one byte), followed by the UTF-8 encoding of the characters in the string."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:'"Hello, World!"'})," serializes as ",(0,s.jsx)(n.code,{children:"0x0d00000048656c6c6f2c20576f726c6421"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-option",children:"Option"}),"\n",(0,s.jsxs)(n.p,{children:["Optional values serialize with a single byte tag, followed by the serialization of the value itself. The tag is equal to ",(0,s.jsx)(n.code,{children:"0"})," if the value is missing, and ",(0,s.jsx)(n.code,{children:"1"})," if it is present."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"None"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"Some(10u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010a000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-list",children:"List"}),"\n",(0,s.jsxs)(n.p,{children:["A list of values serializes as a 32-bit integer representing the number of elements in the list (differing from strings where it gives the number of ",(0,s.jsx)(n.em,{children:"bytes"}),"), followed by the concatenation of each serialized element."]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List()"})," serializes as ",(0,s.jsx)(n.code,{children:"0x00000000"})]}),"\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"List(1u32, 2u32, 3u32)"})," serializes as ",(0,s.jsx)(n.code,{children:"0x03000000010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-ByteArray",children:"ByteArray"}),"\n",(0,s.jsx)(n.p,{children:"A fixed-length list of values serializes as the concatenation of the serialized elements. Unlike a variable-length list, the length is not included in the serialization because it is statically known by the type of the value."}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["E.g. ",(0,s.jsx)(n.code,{children:"[1u32, 2u32, 3u32]"})," serializes as ",(0,s.jsx)(n.code,{children:"0x010000000200000003000000"})]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-result",children:"Result"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Result"})," serializes as a single byte tag followed by the serialization of the contained value. The tag is equal to ",(0,s.jsx)(n.code,{children:"1"})," for the success variant and ",(0,s.jsx)(n.code,{children:"0"})," for the error variant."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `Ok(314u64)` serializes as `0x013a01000000000000`\n- E.g. `Err("Uh oh")` serializes as `0x00050000005568206f68`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-tuple",children:"Tuple"}),"\n",(0,s.jsxs)(n.p,{children:["Tuples serialize as the concatenation of their serialized elements. Similar to ",(0,s.jsx)(n.code,{children:"ByteArray"})," the number of elements is not included in the serialization because it is statically known in the type."]}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{children:'- E.g. `(1u32, "Hello, World!", true)` serializes as `0x010000000d00000048656c6c6f2c20576f726c642101`\n'})}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-map",children:"Map"}),"\n",(0,s.jsxs)(n.p,{children:["A ",(0,s.jsx)(n.code,{children:"Map"})," serializes as a list of key-value tuples. There must be a well-defined ordering on the keys, and in the serialization, the pairs are listed in ascending order. This is done to ensure determinism in the serialization, as ",(0,s.jsx)(n.code,{children:"Map"})," data structures can be unordered."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-uref",children:"URef"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"URef"})," values serialize as the concatenation of their address (a fixed-length list of ",(0,s.jsx)(n.code,{children:"u8"}),") and a single byte tag representing access rights, which are converted as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:"Access Rights"}),(0,s.jsx)(n.th,{children:"Serialization"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"NONE"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"WRITE"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_WRITE"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"READ_ADD_WRITE"})}),(0,s.jsx)(n.td,{children:"7"})]})]})]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:["When passing a URef to another entity on chain, you must ensure that the ",(0,s.jsx)(n.code,{children:"AccessRights"})," are set correctly. If the URef represents a ",(0,s.jsx)(n.a,{href:"/next/concepts/glossary/P#purse",children:"purse"}),", ",(0,s.jsx)(n.code,{children:"AccessRights"})," impact who can deposit and withdraw CSPR."]})}),"\n",(0,s.jsxs)(n.p,{children:["If a passed URef contains ",(0,s.jsx)(n.code,{children:"ADD"})," permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions. In this event, ",(0,s.jsx)(n.code,{children:"READ"})," and ",(0,s.jsx)(n.code,{children:"ADD"})," permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with ",(0,s.jsx)(n.code,{children:"WRITE"})," permissions unintentionally."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-publickey",children:"PublicKey"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"PublicKey"})," serializes as a single byte tag representing the algorithm followed by 32 bytes of the ",(0,s.jsx)(n.code,{children:"PublicKey"})," itself:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"System"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"0"}),". With this variant, the single byte of ",(0,s.jsx)(n.code,{children:"0"})," is the entire key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is an ",(0,s.jsx)(n.code,{children:"Ed25519"})," key, the single tag byte is ",(0,s.jsx)(n.code,{children:"1"})," followed by the individual bytes of the serialized key."]}),"\n",(0,s.jsxs)(n.li,{children:["If the ",(0,s.jsx)(n.code,{children:"PublicKey"})," is a ",(0,s.jsx)(n.code,{children:"Secp256k1"})," key, the single tag byte is a ",(0,s.jsx)(n.code,{children:"2"})," followed by the individual bytes of the serialized key."]}),"\n"]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-key",children:"Key"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"Key"})," values serialize as a single byte tag representing the variant, followed by the serialization of the data that the variant contains. For most variants, this is simply a fixed-length 32-byte array. The exception is ",(0,s.jsx)(n.code,{children:"Key::URef"}),", which contains a ",(0,s.jsx)(n.code,{children:"URef"}),"; so its data serializes per the description above. The tags are as follows: ",(0,s.jsx)(n.code,{children:"Key::Account"})," serializes as ",(0,s.jsx)(n.code,{children:"0"}),", ",(0,s.jsx)(n.code,{children:"Key::Hash"})," as ",(0,s.jsx)(n.code,{children:"1"}),", ",(0,s.jsx)(n.code,{children:"Key::URef"})," as ",(0,s.jsx)(n.code,{children:"2"}),"."]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-cltype",children:"CLType"}),"\n",(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"CLType"})," itself also has rules for serialization. A ",(0,s.jsx)(n.code,{children:"CLType"})," serializes as a single-byte tag, followed by the concatenation of serialized inner types, if any (e.g., lists and tuples have inner types). ",(0,s.jsx)(n.code,{children:"ByteArray"})," is a minor exception because it also includes the length in the type. However, the length is included in the serialization (as a 32-bit integer, per the serialization rules above), following the serialization of the inner type. The tags are as follows:"]}),"\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n",(0,s.jsxs)(n.table,{children:[(0,s.jsx)(n.thead,{children:(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.th,{children:(0,s.jsx)(n.code,{children:"CLType"})}),(0,s.jsx)(n.th,{children:"Serialization Tag"})]})}),(0,s.jsxs)(n.tbody,{children:[(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Bool"})}),(0,s.jsx)(n.td,{children:"0"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I32"})}),(0,s.jsx)(n.td,{children:"1"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"I64"})}),(0,s.jsx)(n.td,{children:"2"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U8"})}),(0,s.jsx)(n.td,{children:"3"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U32"})}),(0,s.jsx)(n.td,{children:"4"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U64"})}),(0,s.jsx)(n.td,{children:"5"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U128"})}),(0,s.jsx)(n.td,{children:"6"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U256"})}),(0,s.jsx)(n.td,{children:"7"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"U512"})}),(0,s.jsx)(n.td,{children:"8"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Unit"})}),(0,s.jsx)(n.td,{children:"9"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"String"})}),(0,s.jsx)(n.td,{children:"10"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Key"})}),(0,s.jsx)(n.td,{children:"11"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"URef"})}),(0,s.jsx)(n.td,{children:"12"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Option"})}),(0,s.jsx)(n.td,{children:"13"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"List"})}),(0,s.jsx)(n.td,{children:"14"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"ByteArray"})}),(0,s.jsx)(n.td,{children:"15"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Result"})}),(0,s.jsx)(n.td,{children:"16"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Map"})}),(0,s.jsx)(n.td,{children:"17"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple1"})}),(0,s.jsx)(n.td,{children:"18"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple2"})}),(0,s.jsx)(n.td,{children:"19"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Tuple3"})}),(0,s.jsx)(n.td,{children:"20"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"Any"})}),(0,s.jsx)(n.td,{children:"21"})]}),(0,s.jsxs)(n.tr,{children:[(0,s.jsx)(n.td,{children:(0,s.jsx)(n.code,{children:"PublicKey"})}),(0,s.jsx)(n.td,{children:"22"})]})]})]}),"\n",(0,s.jsx)(n.h3,{id:"clvalue-clvalue",children:"CLValue"}),"\n",(0,s.jsxs)(n.p,{children:["A complete ",(0,s.jsx)(n.code,{children:"CLValue"}),", including both the data and the type, can also be serialized (to store it in the global state). This is done by concatenating: the serialization of the length (as a 32-bit integer) of the serialized data (in bytes), the serialized data itself, and the serialization of the type."]}),"\n",(0,s.jsx)(n.h3,{id:"global-state-contracts",children:"Contracts"}),"\n",(0,s.jsxs)(n.p,{children:["Contracts are a special value type because they contain the on-chain logic of the applications running on a Casper network. A ",(0,s.jsx)(n.em,{children:"contract"})," contains the following data:"]}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:["a ",(0,s.jsx)(n.a,{href:"https://webassembly.github.io/spec/core/syntax/modules.html",children:"wasm module"})]}),"\n",(0,s.jsx)(n.li,{children:"a collection of named keys"}),"\n",(0,s.jsx)(n.li,{children:"a protocol version"}),"\n"]}),"\n",(0,s.jsxs)(n.p,{children:["The wasm module must contain a function named ",(0,s.jsx)(n.code,{children:"call"}),", which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the ",(0,s.jsx)(n.a,{href:"/next/concepts/design/casper-design#execution-semantics-runtime",children:"Casper runtime"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Note: though the ",(0,s.jsx)(n.code,{children:"call"})," function signature has no arguments and no return value, within the ",(0,s.jsx)(n.code,{children:"call"})," function body, the ",(0,s.jsx)(n.code,{children:"get_named_arg"})," runtime function can be used to accept arguments (by ordinal), and the ",(0,s.jsx)(n.code,{children:"ret"})," runtime function can be used to return a single ",(0,s.jsx)(n.code,{children:"CLValue"})," to the caller."]}),"\n",(0,s.jsxs)(n.p,{children:["The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the ",(0,s.jsx)(n.code,{children:"URef"}),"s, which are known to the contract (see the section on Permissions for details)."]}),"\n",(0,s.jsx)(n.p,{children:"Each contract specifies the Casper protocol version that was active when the contract was written to the global state."})]})}function o(e={}){const{wrapper:n}={...(0,l.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(h,{...e})}):h(e)}},28453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>d});var s=i(96540);const l={},t=s.createContext(l);function r(e){const n=s.useContext(t);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(l):e.components||l:r(e.components),s.createElement(t.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/faf2a93e.41ab65a9.js b/assets/js/faf2a93e.41ab65a9.js deleted file mode 100644 index e896eabc8..000000000 --- a/assets/js/faf2a93e.41ab65a9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[6666],{88956:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var t=s(74848),i=s(28453);const r={title:"Ledger and Ledger Live"},c="Using Ledger and Ledger Live",d={id:"users/ledger/ledger-live",title:"Ledger and Ledger Live",description:"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.",source:"@site/docs/users/ledger/ledger-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-live",permalink:"/next/users/ledger/ledger-live",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Ledger and Ledger Live"},sidebar:"users",previous:{title:"Set up Ledger",permalink:"/next/workflow/ledger-setup/"},next:{title:"Ledger and CSPR.live",permalink:"/next/users/ledger/ledger-cspr-live"}},a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Connecting to Ledger Live",id:"connect-ledge-live",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function l(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-ledger-live",children:"Using Ledger and Ledger Live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect accounts from the Ledger device to the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.admonition,{type:"important",children:(0,t.jsx)(n.p,{children:"From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,t.jsxs)(n.li,{children:["Install the Casper app as described ",(0,t.jsx)(n.a,{href:"/next/workflow/ledger-setup/",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"connect-ledge-live",children:"Connecting to Ledger Live"}),"\n",(0,t.jsxs)(n.p,{children:["This section describes using the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application and your Casper accounts."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect the Ledger to your computer",src:s(90893).A+"",width:"2024",height:"770"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Allow Ledger Manager to connect by clicking the two buttons on the Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Unlock the ledger",src:s(74992).A+"",width:"2018",height:"974"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will verify your Ledger device and display the following confirmation:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(99330).A+"",width:"2014",height:"362"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"My Ledger"})," in the left-side navigation bar, and search for ",(0,t.jsx)(n.em,{children:"Casper"})," or ",(0,t.jsx)(n.em,{children:"CSPR"})," in the ",(0,t.jsx)(n.strong,{children:"App catalog"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(94688).A+"",width:"2272",height:"1536"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["To import a Casper account from the Ledger device into the Ledger Live application, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click the Add account link",src:s(69828).A+"",width:"2044",height:"390"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Open the Casper app on your Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Open the Casper app",src:s(57561).A+"",width:"1006",height:"932"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will import the first account listed on your Ledger device. Choose a name for the account."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Name the account",src:s(64422).A+"",width:"999",height:"714"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"After synchronizing the account, Ledger Live will confirm that the account was successfully added."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Synchronizing the account",src:s(76971).A+"",width:"1001",height:"626"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the account was added",src:s(67944).A+"",width:"1001",height:"955"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"Click on the account summary, to view more details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account summary",src:s(32112).A+"",width:"2278",height:"726"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account details",src:s(99546).A+"",width:"2252",height:"1452"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["To add another account, open the ",(0,t.jsx)(n.strong,{children:"Account"})," option in the left-side navigation bar. Then, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Add a second account",src:s(71513).A+"",width:"2180",height:"466"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Receive"})," option in the left-side navigation bar."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click on Receive",src:s(31475).A+"",width:"990",height:"934"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Choose an account from the drop-down list."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account",src:s(88570).A+"",width:"998",height:"920"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Copy the address displayed, or use the corresponding QR code."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account 2",src:s(14825).A+"",width:"990",height:"1192"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click ",(0,t.jsx)(n.strong,{children:"APPROVE"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 1",src:s(87848).A+"",width:"640",height:"313"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 2",src:s(48887).A+"",width:"640",height:"247"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click approve",src:s(78366).A+"",width:"640",height:"297"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation displayed",src:s(57229).A+"",width:"986",height:"748"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsx)(n.p,{children:"Ledger Live supports sending CSPR tokens from one Casper account to another."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Start by clicking on the ",(0,t.jsx)(n.strong,{children:"Send"})," option in the left-side navigation bar. Choose the account to debit:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose the account to debit",src:s(68265).A+"",width:"994",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the recipient's address and click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter reciepient",src:s(69821).A+"",width:"990",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the amount and an optional transfer ID. Click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter amount and transfer ID",src:s(98666).A+"",width:"992",height:"1052"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Review the summary, and if everything is correct, click ",(0,t.jsx)(n.strong,{children:"Continue"}),". Otherwise, click the ",(0,t.jsx)(n.strong,{children:"Back"})," link in the top-left corner."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transfer",src:s(62715).A+"",width:"990",height:"1132"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount. Meanwhile, Ledger Live will display this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transaction in the Ledger",src:s(60768).A+"",width:"990",height:"1290"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details until you see ",(0,t.jsx)(n.strong,{children:'"APPROVE"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.strong,{children:"Txn hash"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(86580).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-tx-2",src:s(48592).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["The next screen displays the transaction ",(0,t.jsx)(n.strong,{children:"Type"}),", which will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(93532).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"chain ID"}),", which for Mainnet should be ",(0,t.jsx)(n.strong,{children:"casper"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(47263).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"})," initiating the token transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(64840).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(25702).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(88706).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", which is the recipient's public key."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(24222).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(68328).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(66785).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(58180).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Broadcasting transaction",src:s(42841).A+"",width:"979",height:"938"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction sent",src:s(10374).A+"",width:"992",height:"992"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsxs)(n.li,{children:["To view the transaction details, click on the ",(0,t.jsx)(n.strong,{children:"View details"})," button. The following screen will appear:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction details",src:s(77095).A+"",width:"982",height:"1334"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsxs)(n.li,{children:["You can view the transaction in the CSPR.live block explorer by clicking on the ",(0,t.jsx)(n.strong,{children:"View in explorer"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Explorer chowing transaction",src:s(50268).A+"",width:"1960",height:"1140"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},88706:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},24222:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},68328:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},66785:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},58180:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},86580:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},48592:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},93532:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},47263:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},64840:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},25702:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},90893:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/0-connect-51dc63eac8bb4108b5819e53b2320101.png"},74992:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-unlock-3bd74f14f8d1c98ed8e0693e4b60ee08.png"},99546:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-account-details-b948b4322fa45f1eb4084921908054da.png"},71513:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-second-account-452dfda3813f97866e7109c383b52494.png"},31475:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-receive-e96873468302c422b0f759cf7dc2b452.png"},88570:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-receive-39af424b927864f776f577543e6d5617.png"},14825:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/14-receive-dc8f6cf7abd29ecd60fde182f8a3eb2b.png"},87848:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-receive-4ff498e5dd601eb18cd46a0d7648f675.png"},48887:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/16-receive-3fefa1c9455c51718f5414c0941efe8d.png"},78366:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/17-receive-e560cc80468abe4d8cff6582c7c916af.png"},57229:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/18-receive-50241c9e26a773568154d73110fa0eaf.png"},68265:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/19-send-f0b733857a605b692aef8d985ca53cf7.png"},99330:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-confirmation-93db08f91f73e80e194b83a38335e2f7.png"},69821:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/20-send-a47149d85a3a55b96523dd39d071eec9.png"},98666:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/21-send-dbff3394e9ee1dc0ba7e3455139f6857.png"},62715:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/22-send-710e2cb1e9623e8285386e9d2401bf6a.png"},60768:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/23-send-6b6a8ededcf9f387ca3ad2a969b794eb.png"},42841:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/24-send-fe804e955323f7d7efa274791f1f3b19.png"},10374:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/25-send-8b261293298a9a96470f648907576326.png"},77095:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/26-send-59402163032dba28406efe5fa1ac2bc6.png"},50268:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/27-send-28a4e6195b22c34240acd3f162fe0a5c.png"},94688:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-app-cspr-a6c84f316cd2e0c1ee8ee2dce4052d1d.png"},69828:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-add-account-601e6f86db467e2dc565a8f450bdccb0.png"},57561:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-add-account-9497a448d27f533f230e3e681b568eb7.png"},64422:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/6-add-account-ef77a19736e2fec10e5e3e58610b6cd2.png"},76971:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-add-account-993de3e6854e0b2713bd8df1b1b3bd80.png"},67944:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-add-account-746309f12b6b97426a1696b3a9712730.png"},32112:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-summary-e314cd0c1ca2e839a48ef4b80c44f198.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/faf2a93e.5f4fcdac.js b/assets/js/faf2a93e.5f4fcdac.js new file mode 100644 index 000000000..f11636a11 --- /dev/null +++ b/assets/js/faf2a93e.5f4fcdac.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[16666],{88956:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>r,metadata:()=>d,toc:()=>o});var t=s(74848),i=s(28453);const r={title:"Ledger and Ledger Live"},c="Using Ledger and Ledger Live",d={id:"users/ledger/ledger-live",title:"Ledger and Ledger Live",description:"This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.",source:"@site/docs/users/ledger/ledger-live.md",sourceDirName:"users/ledger",slug:"/users/ledger/ledger-live",permalink:"/users/ledger/ledger-live",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1725898285e3,frontMatter:{title:"Ledger and Ledger Live"},sidebar:"users",previous:{title:"Set up Ledger",permalink:"/workflow/ledger-setup/"},next:{title:"Ledger and CSPR.live",permalink:"/users/ledger/ledger-cspr-live"}},a={},o=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Connecting to Ledger Live",id:"connect-ledge-live",level:2},{value:"Receiving Tokens",id:"receive-tokens",level:2},{value:"Sending Tokens",id:"send-tokens",level:2}];function l(e){const n={a:"a",admonition:"admonition",em:"em",h1:"h1",h2:"h2",header:"header",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"using-ledger-and-ledger-live",children:"Using Ledger and Ledger Live"})}),"\n",(0,t.jsxs)(n.p,{children:["This guide will help you connect accounts from the Ledger device to the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application to send and receive CSPR tokens."]}),"\n",(0,t.jsx)(n.admonition,{type:"important",children:(0,t.jsx)(n.p,{children:"From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live."})}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Configure your Ledger and the Ledger Live application as described in the ",(0,t.jsx)(n.a,{href:"https://support.ledger.com/hc/en-us/articles/4404389503889?docs=true",children:"Getting Started with Ledger Live"})," article."]}),"\n",(0,t.jsxs)(n.li,{children:["Install the Casper app as described ",(0,t.jsx)(n.a,{href:"/workflow/ledger-setup/",children:"here"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"connect-ledge-live",children:"Connecting to Ledger Live"}),"\n",(0,t.jsxs)(n.p,{children:["This section describes using the Ledger device with the ",(0,t.jsx)(n.a,{href:"https://www.ledger.com/ledger-live",children:"Ledger Live"})," application and your Casper accounts."]}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsx)(n.li,{children:"Connect the Ledger device to your computer and unlock it by entering your device PIN."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Connect the Ledger to your computer",src:s(94571).A+"",width:"2024",height:"770"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Allow Ledger Manager to connect by clicking the two buttons on the Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Unlock the ledger",src:s(63478).A+"",width:"2018",height:"974"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will verify your Ledger device and display the following confirmation:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(24632).A+"",width:"2014",height:"362"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Click ",(0,t.jsx)(n.strong,{children:"My Ledger"})," in the left-side navigation bar, and search for ",(0,t.jsx)(n.em,{children:"Casper"})," or ",(0,t.jsx)(n.em,{children:"CSPR"})," in the ",(0,t.jsx)(n.strong,{children:"App catalog"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the Ledger is genuine",src:s(47982).A+"",width:"2272",height:"1536"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["To import a Casper account from the Ledger device into the Ledger Live application, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click the Add account link",src:s(15334).A+"",width:"2044",height:"390"})}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsx)(n.li,{children:"Open the Casper app on your Ledger device."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Open the Casper app",src:s(11531).A+"",width:"1006",height:"932"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsx)(n.li,{children:"Ledger Live will import the first account listed on your Ledger device. Choose a name for the account."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Name the account",src:s(4388).A+"",width:"999",height:"714"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsx)(n.li,{children:"After synchronizing the account, Ledger Live will confirm that the account was successfully added."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Synchronizing the account",src:s(8473).A+"",width:"1001",height:"626"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation that the account was added",src:s(80650).A+"",width:"1001",height:"955"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsx)(n.li,{children:"Click on the account summary, to view more details."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account summary",src:s(6834).A+"",width:"2278",height:"726"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Account details",src:s(34740).A+"",width:"2252",height:"1452"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["To add another account, open the ",(0,t.jsx)(n.strong,{children:"Account"})," option in the left-side navigation bar. Then, click on the ",(0,t.jsx)(n.strong,{children:"Add account"})," button."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Add a second account",src:s(89683).A+"",width:"2180",height:"466"})}),"\n",(0,t.jsx)(n.h2,{id:"receive-tokens",children:"Receiving Tokens"}),"\n",(0,t.jsx)(n.p,{children:"To receive tokens, you need to provide the sender with your account's public key."}),"\n",(0,t.jsx)(n.admonition,{type:"caution",children:(0,t.jsx)(n.p,{children:"Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds."})}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Click on the ",(0,t.jsx)(n.strong,{children:"Receive"})," option in the left-side navigation bar."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click on Receive",src:s(96513).A+"",width:"990",height:"934"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsx)(n.li,{children:"Choose an account from the drop-down list."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account",src:s(83456).A+"",width:"998",height:"920"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsx)(n.li,{children:"Copy the address displayed, or use the corresponding QR code."}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose an account 2",src:s(62059).A+"",width:"990",height:"1192"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click ",(0,t.jsx)(n.strong,{children:"APPROVE"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 1",src:s(89650).A+"",width:"640",height:"313"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Verify address part 2",src:s(99501).A+"",width:"640",height:"247"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Click approve",src:s(24316).A+"",width:"640",height:"297"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Confirmation displayed",src:s(70871).A+"",width:"986",height:"748"})}),"\n",(0,t.jsx)(n.h2,{id:"send-tokens",children:"Sending Tokens"}),"\n",(0,t.jsx)(n.p,{children:"Ledger Live supports sending CSPR tokens from one Casper account to another."}),"\n",(0,t.jsxs)(n.ol,{children:["\n",(0,t.jsxs)(n.li,{children:["Start by clicking on the ",(0,t.jsx)(n.strong,{children:"Send"})," option in the left-side navigation bar. Choose the account to debit:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Choose the account to debit",src:s(54883).A+"",width:"994",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"2",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the recipient's address and click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter reciepient",src:s(12627).A+"",width:"990",height:"998"})}),"\n",(0,t.jsxs)(n.ol,{start:"3",children:["\n",(0,t.jsxs)(n.li,{children:["Enter the amount and an optional transfer ID. Click ",(0,t.jsx)(n.strong,{children:"Continue"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Enter amount and transfer ID",src:s(43448).A+"",width:"992",height:"1052"})}),"\n",(0,t.jsxs)(n.ol,{start:"4",children:["\n",(0,t.jsxs)(n.li,{children:["Review the summary, and if everything is correct, click ",(0,t.jsx)(n.strong,{children:"Continue"}),". Otherwise, click the ",(0,t.jsx)(n.strong,{children:"Back"})," link in the top-left corner."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transfer",src:s(69493).A+"",width:"990",height:"1132"})}),"\n",(0,t.jsxs)(n.ol,{start:"5",children:["\n",(0,t.jsxs)(n.li,{children:["Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source ",(0,t.jsx)(n.strong,{children:"account"}),", fee, target, and amount. Meanwhile, Ledger Live will display this message:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Review the transaction in the Ledger",src:s(37634).A+"",width:"990",height:"1290"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.strong,{children:"Verify the transaction on your Ledger device"})}),"\n",(0,t.jsxs)(n.p,{children:["Press the right button on your Ledger Device to review the transaction details until you see ",(0,t.jsx)(n.strong,{children:'"APPROVE"'}),"."]}),"\n",(0,t.jsxs)(n.ol,{start:"6",children:["\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.strong,{children:"Txn hash"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"3-txn-1",src:s(72678).A+"",width:"935",height:"340"})}),"\n",(0,t.jsx)(n.p,{children:"The Txn hash value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"4-tx-2",src:s(57362).A+"",width:"970",height:"332"})}),"\n",(0,t.jsxs)(n.ol,{start:"7",children:["\n",(0,t.jsxs)(n.li,{children:["The next screen displays the transaction ",(0,t.jsx)(n.strong,{children:"Type"}),", which will be ",(0,t.jsx)(n.strong,{children:"Token transfer"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"5-type",src:s(8810).A+"",width:"875",height:"282"})}),"\n",(0,t.jsxs)(n.ol,{start:"8",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"chain ID"}),", which for Mainnet should be ",(0,t.jsx)(n.strong,{children:"casper"}),"."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"7-chain",src:s(68533).A+"",width:"904",height:"302"})}),"\n",(0,t.jsxs)(n.ol,{start:"9",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Account"})," initiating the token transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"8-account-1",src:s(80514).A+"",width:"968",height:"317"})}),"\n",(0,t.jsx)(n.p,{children:"The Account value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"9-account-2",src:s(98516).A+"",width:"893",height:"314"})}),"\n",(0,t.jsxs)(n.ol,{start:"10",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Fee"}),". For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"10-fee",src:s(58900).A+"",width:"1041",height:"306"})}),"\n",(0,t.jsxs)(n.ol,{start:"11",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Target"}),", which is the recipient's public key."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"11-target-1",src:s(3984).A+"",width:"887",height:"324"})}),"\n",(0,t.jsx)(n.p,{children:"The Target value continues on a second screen."}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"12-target-2",src:s(22026).A+"",width:"859",height:"381"})}),"\n",(0,t.jsxs)(n.ol,{start:"12",children:["\n",(0,t.jsxs)(n.li,{children:["Verify the ",(0,t.jsx)(n.strong,{children:"Amount"})," you want to transfer."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"13-amount",src:s(88767).A+"",width:"946",height:"338"})}),"\n",(0,t.jsxs)(n.ol,{start:"13",children:["\n",(0,t.jsxs)(n.li,{children:["If you want to approve the transaction, click both buttons on the Ledger device while on the ",(0,t.jsx)(n.strong,{children:"APPROVE"})," screen."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"15-approve",src:s(13046).A+"",width:"596",height:"222"})}),"\n",(0,t.jsxs)(n.ol,{start:"14",children:["\n",(0,t.jsx)(n.li,{children:"After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:"}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Broadcasting transaction",src:s(68415).A+"",width:"979",height:"938"})}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction sent",src:s(31252).A+"",width:"992",height:"992"})}),"\n",(0,t.jsxs)(n.ol,{start:"15",children:["\n",(0,t.jsxs)(n.li,{children:["To view the transaction details, click on the ",(0,t.jsx)(n.strong,{children:"View details"})," button. The following screen will appear:"]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Transaction details",src:s(27537).A+"",width:"982",height:"1334"})}),"\n",(0,t.jsxs)(n.ol,{start:"16",children:["\n",(0,t.jsxs)(n.li,{children:["You can view the transaction in the CSPR.live block explorer by clicking on the ",(0,t.jsx)(n.strong,{children:"View in explorer"})," link."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:(0,t.jsx)(n.img,{alt:"Explorer chowing transaction",src:s(73726).A+"",width:"1960",height:"1140"})})]})}function h(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},58900:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-fee-2e09b26e7ec4422c1202cba8ba8797b4.jpg"},3984:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-target-1-64692038c58c95f4589314c1a9852fdb.jpg"},22026:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-target-2-b2658a414ca3b5b195addf308cac7915.jpg"},88767:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-amount-63d3fb28fbf3379e593cef4456dc058b.jpg"},13046:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-approve-cded340d1f30853048cbd6c59c0a2baa.jpg"},72678:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-txn-1-bf9589c738fd87a4fa96c70bca3fd4c0.jpg"},57362:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-txn-2-3405106f669dd00a733f23e74ae80e29.jpg"},8810:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-type-0869d1f976192a5178e3c04e32175cd2.jpg"},68533:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-chain-2bb09ef08fb373fac6fb4ae464356282.jpg"},80514:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-account-1-00dbcd2825587ee61c49be6adf97ef3c.jpg"},98516:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-2-b17bd4328131a08b82fcb578d806210a.jpg"},94571:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/0-connect-51dc63eac8bb4108b5819e53b2320101.png"},63478:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/1-unlock-3bd74f14f8d1c98ed8e0693e4b60ee08.png"},34740:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/10-account-details-b948b4322fa45f1eb4084921908054da.png"},89683:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/11-second-account-452dfda3813f97866e7109c383b52494.png"},96513:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/12-receive-e96873468302c422b0f759cf7dc2b452.png"},83456:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/13-receive-39af424b927864f776f577543e6d5617.png"},62059:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/14-receive-dc8f6cf7abd29ecd60fde182f8a3eb2b.png"},89650:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/15-receive-4ff498e5dd601eb18cd46a0d7648f675.png"},99501:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/16-receive-3fefa1c9455c51718f5414c0941efe8d.png"},24316:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/17-receive-e560cc80468abe4d8cff6582c7c916af.png"},70871:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/18-receive-50241c9e26a773568154d73110fa0eaf.png"},54883:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/19-send-f0b733857a605b692aef8d985ca53cf7.png"},24632:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/2-confirmation-93db08f91f73e80e194b83a38335e2f7.png"},12627:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/20-send-a47149d85a3a55b96523dd39d071eec9.png"},43448:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/21-send-dbff3394e9ee1dc0ba7e3455139f6857.png"},69493:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/22-send-710e2cb1e9623e8285386e9d2401bf6a.png"},37634:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/23-send-6b6a8ededcf9f387ca3ad2a969b794eb.png"},68415:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/24-send-fe804e955323f7d7efa274791f1f3b19.png"},31252:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/25-send-8b261293298a9a96470f648907576326.png"},27537:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/26-send-59402163032dba28406efe5fa1ac2bc6.png"},73726:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/27-send-28a4e6195b22c34240acd3f162fe0a5c.png"},47982:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/3-app-cspr-a6c84f316cd2e0c1ee8ee2dce4052d1d.png"},15334:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/4-add-account-601e6f86db467e2dc565a8f450bdccb0.png"},11531:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/5-add-account-9497a448d27f533f230e3e681b568eb7.png"},4388:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/6-add-account-ef77a19736e2fec10e5e3e58610b6cd2.png"},8473:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/7-add-account-993de3e6854e0b2713bd8df1b1b3bd80.png"},80650:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/8-add-account-746309f12b6b97426a1696b3a9712730.png"},6834:(e,n,s)=>{s.d(n,{A:()=>t});const t=s.p+"assets/images/9-account-summary-e314cd0c1ca2e839a48ef4b80c44f198.png"},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>d});var t=s(96540);const i={},r=t.createContext(i);function c(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function d(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:c(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fb804d1c.8135cc99.js b/assets/js/fb804d1c.8135cc99.js new file mode 100644 index 000000000..1ed1b4376 --- /dev/null +++ b/assets/js/fb804d1c.8135cc99.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[54939],{8060:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=a(74848),t=a(28453);const c={title:"Additional Examples"},o="Additional Examples",i={id:"resources/advanced/multi-sig/other-scenarios",title:"Additional Examples",description:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.",source:"@site/docs/resources/advanced/multi-sig/other-scenarios.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/other-scenarios",permalink:"/resources/advanced/multi-sig/other-scenarios",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Additional Examples"},sidebar:"tutorials",previous:{title:"Multi-Sig Workflow",permalink:"/resources/advanced/multi-sig/multi-sig-workflow"},next:{title:"Runtime Return Values",permalink:"/resources/tutorials/advanced/return-values-tutorial"}},r={},d=[{value:"Example 1: An account with a single (primary) key",id:"example-1-an-account-with-a-single-primary-key",level:3},{value:"Example 2: An account with primary and associated keys",id:"example-2-an-account-with-primary-and-associated-keys",level:3},{value:"Example 3: Multi-sig setup for deploys and account updates",id:"example-3-multi-sig-setup-for-deploys-and-account-updates",level:3},{value:"Example 4: Signing deploys but restricting account updates",id:"example-4-signing-deploys-but-restricting-account-updates",level:3},{value:"Example 5: Recovering a lost primary key",id:"example-5-recovering-a-lost-primary-key",level:3}];function l(e){const n={code:"code",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"additional-examples",children:"Additional Examples"})}),"\n",(0,s.jsx)(n.p,{children:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions."}),"\n",(0,s.jsx)(n.h3,{id:"example-1-an-account-with-a-single-primary-key",children:"Example 1: An account with a single (primary) key"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, only one key (",(0,s.jsx)(n.code,{children:"account-hash-a1\u2026"}),") can sign transactions in the name of this account. This key is the primary key of the account and has a ",(0,s.jsx)(n.code,{children:"weight"})," equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 1:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-2-an-account-with-primary-and-associated-keys",children:"Example 2: An account with primary and associated keys"}),"\n",(0,s.jsx)(n.p,{children:"In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 2:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key for key management\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key used for deploys\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-3-multi-sig-setup-for-deploys-and-account-updates",children:"Example 3: Multi-sig setup for deploys and account updates"}),"\n",(0,s.jsx)(n.p,{children:"The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 3:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-4-signing-deploys-but-restricting-account-updates",children:"Example 4: Signing deploys but restricting account updates"}),"\n",(0,s.jsx)(n.p,{children:"This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 4:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-5-recovering-a-lost-primary-key",children:"Example 5: Recovering a lost primary key"}),"\n",(0,s.jsx)(n.p,{children:"This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 5:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-d4\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var s=a(96540);const t={},c=s.createContext(t);function o(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fb804d1c.9658edac.js b/assets/js/fb804d1c.9658edac.js deleted file mode 100644 index ca60b427f..000000000 --- a/assets/js/fb804d1c.9658edac.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[4939],{8060:(e,n,a)=>{a.r(n),a.d(n,{assets:()=>r,contentTitle:()=>o,default:()=>h,frontMatter:()=>c,metadata:()=>i,toc:()=>d});var s=a(74848),t=a(28453);const c={title:"Additional Examples"},o="Additional Examples",i={id:"resources/advanced/multi-sig/other-scenarios",title:"Additional Examples",description:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.",source:"@site/docs/resources/advanced/multi-sig/other-scenarios.md",sourceDirName:"resources/advanced/multi-sig",slug:"/resources/advanced/multi-sig/other-scenarios",permalink:"/next/resources/advanced/multi-sig/other-scenarios",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Karol Marter",lastUpdatedAt:1722798267e3,frontMatter:{title:"Additional Examples"},sidebar:"tutorials",previous:{title:"Multi-Sig Workflow",permalink:"/next/resources/advanced/multi-sig/multi-sig-workflow"},next:{title:"Runtime Return Values",permalink:"/next/resources/tutorials/advanced/return-values-tutorial"}},r={},d=[{value:"Example 1: An account with a single (primary) key",id:"example-1-an-account-with-a-single-primary-key",level:3},{value:"Example 2: An account with primary and associated keys",id:"example-2-an-account-with-primary-and-associated-keys",level:3},{value:"Example 3: Multi-sig setup for deploys and account updates",id:"example-3-multi-sig-setup-for-deploys-and-account-updates",level:3},{value:"Example 4: Signing deploys but restricting account updates",id:"example-4-signing-deploys-but-restricting-account-updates",level:3},{value:"Example 5: Recovering a lost primary key",id:"example-5-recovering-a-lost-primary-key",level:3}];function l(e){const n={code:"code",h1:"h1",h3:"h3",header:"header",p:"p",pre:"pre",strong:"strong",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.header,{children:(0,s.jsx)(n.h1,{id:"additional-examples",children:"Additional Examples"})}),"\n",(0,s.jsx)(n.p,{children:"This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions."}),"\n",(0,s.jsx)(n.h3,{id:"example-1-an-account-with-a-single-primary-key",children:"Example 1: An account with a single (primary) key"}),"\n",(0,s.jsxs)(n.p,{children:["In this example, only one key (",(0,s.jsx)(n.code,{children:"account-hash-a1\u2026"}),") can sign transactions in the name of this account. This key is the primary key of the account and has a ",(0,s.jsx)(n.code,{children:"weight"})," equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions."]}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 1:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 1\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-2-an-account-with-primary-and-associated-keys",children:"Example 2: An account with primary and associated keys"}),"\n",(0,s.jsx)(n.p,{children:"In this example, the account has a primary key with weight 2 and an associated key with a lower weight for signing deploys. The primary key can perform account updates and deploys, while the associated key can only sign deploys."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 2:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 1,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key for key management\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key used for deploys\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-3-multi-sig-setup-for-deploys-and-account-updates",children:"Example 3: Multi-sig setup for deploys and account updates"}),"\n",(0,s.jsx)(n.p,{children:"The following account has associated keys that can manage the account and send deploys independently of the primary key. The two associated keys have a cumulative weight of 2, which meets the deployment and key management thresholds. Both keys must sign the deploy to make updates."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 3:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 2\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 2\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-4-signing-deploys-but-restricting-account-updates",children:"Example 4: Signing deploys but restricting account updates"}),"\n",(0,s.jsx)(n.p,{children:"This scenario builds on the previous example. The account has a primary key with a weight of 3, equal to the key management threshold, and two associated keys with a cumulative weight of 2, for signing deploys. The associated keys can sign deploys but not make account updates because they do not meet the key management threshold. Only the primary key can update the account. If the primary key is lost or compromised, the entire account becomes compromised because the associated keys do not have enough cumulative weight to remove the compromised key."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 4:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})}),"\n",(0,s.jsx)(n.h3,{id:"example-5-recovering-a-lost-primary-key",children:"Example 5: Recovering a lost primary key"}),"\n",(0,s.jsx)(n.p,{children:"This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account."}),"\n",(0,s.jsx)(n.p,{children:(0,s.jsx)(n.strong,{children:"Account details in example 5:"})}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",children:'"Account": {\n "account_address": "account-hash-a1\u2026",\n "action_thresholds": {\n "deployment": 2,\n "key_management": 3\n },\n "associated_keys": [\n {\n "account_address": "account-hash-a1\u2026", // primary key\n "weight": 3\n },\n {\n "account_address": "account-hash-b2\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-c3\u2026", // associated key\n "weight": 1\n },\n {\n "account_address": "account-hash-d4\u2026", // associated key\n "weight": 1\n }\n ],\n "main_purse": "uref-1234\u2026",\n "named_keys": []\n}\n'})})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},28453:(e,n,a)=>{a.d(n,{R:()=>o,x:()=>i});var s=a(96540);const t={},c=s.createContext(t);function o(e){const n=s.useContext(c);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(c.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fb904585.9a2467f1.js b/assets/js/fb904585.9a2467f1.js new file mode 100644 index 000000000..e5eb07e0e --- /dev/null +++ b/assets/js/fb904585.9a2467f1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[45140],{88320:(e,s,r)=>{r.r(s),r.d(s,{assets:()=>l,contentTitle:()=>t,default:()=>d,frontMatter:()=>o,metadata:()=>a,toc:()=>i});var n=r(74848),c=r(28453);const o={},t="Z",a={id:"concepts/glossary/Z",title:"Z",description:"---",source:"@site/versioned_docs/version-2.0.0/concepts/glossary/Z.md",sourceDirName:"concepts/glossary",slug:"/concepts/glossary/Z",permalink:"/2.0.0/concepts/glossary/Z",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{},sidebar:"concepts",previous:{title:"Y",permalink:"/2.0.0/concepts/glossary/Y"},next:{title:"Binary Serialization Standard",permalink:"/2.0.0/concepts/serialization/"}},l={},i=[{value:"Zug",id:"zug",level:2}];function h(e){const s={a:"a",h1:"h1",h2:"h2",header:"header",hr:"hr",p:"p",...(0,c.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(s.header,{children:(0,n.jsx)(s.h1,{id:"z",children:"Z"})}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/A",children:"A"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/B",children:"B"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/C",children:"C"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/D",children:"D"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/E",children:"E"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/F",children:"F"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/G",children:"G"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/H",children:"H"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/I",children:"I"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/J",children:"J"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/K",children:"K"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/L",children:"L"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/M",children:"M"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/N",children:"N"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/O",children:"O"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/P",children:"P"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Q",children:"Q"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/R",children:"R"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/S",children:"S"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/T",children:"T"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/U",children:"U"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/V",children:"V"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/W",children:"W"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/X",children:"X"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Y",children:"Y"})," ",(0,n.jsx)(s.a,{href:"/2.0.0/concepts/glossary/Z",children:"Z"})]}),"\n",(0,n.jsx)(s.hr,{}),"\n",(0,n.jsx)(s.h2,{id:"zug",children:"Zug"}),"\n",(0,n.jsxs)(s.p,{children:[(0,n.jsx)(s.a,{href:"/2.0.0/concepts/design/zug",children:"Zug"})," is a simple, fast, and secure consensus protocol used on the Casper Mainnet. Read the paper: ",(0,n.jsx)(s.a,{href:"https://arxiv.org/abs/2205.06314",children:"From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast"}),"."]})]})}function d(e={}){const{wrapper:s}={...(0,c.R)(),...e.components};return s?(0,n.jsx)(s,{...e,children:(0,n.jsx)(h,{...e})}):h(e)}},28453:(e,s,r)=>{r.d(s,{R:()=>t,x:()=>a});var n=r(96540);const c={},o=n.createContext(c);function t(e){const s=n.useContext(o);return n.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function a(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(c):e.components||c:t(e.components),n.createElement(o.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd661beb.9306c892.js b/assets/js/fd661beb.9306c892.js new file mode 100644 index 000000000..7dd76c505 --- /dev/null +++ b/assets/js/fd661beb.9306c892.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[55789],{33142:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=s(74848),r=s(28453);const i={title:"Quick Installation"},a="Casper NFT Quick Installation Guide",c={id:"resources/tokens/cep78/using-casper-client/quickstart-guide",title:"Quick Installation",description:"This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/quickstart-guide",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Quick Installation"},sidebar:"resources",previous:{title:"CEP-78 Modalities",permalink:"/1.5.X/resources/tokens/cep78/modalities"},next:{title:"Installation Workflow",permalink:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setup",id:"setup",level:2},{value:"Installing the NFT Contract",id:"installing-the-nft-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-nft-quick-installation-guide",children:"Casper NFT Quick Installation Guide"})}),"\n",(0,t.jsxs)(n.p,{children:["This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Casper Testnet"}),". For greater detail into the creation and mechanics of the Casper NFT contract, see the complete ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Casper NFT Tutorial"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["To execute transactions on a Casper network involving NFTs, you will need some CSPR tokens to pay for the transactions. The Testnet provides test tokens using a ",(0,t.jsx)(n.a,{href:"/1.5.X/users/testnet-faucet",children:"faucet"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites",children:"development prerequisites"}),", including the ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#install-casper-client",children:"Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Get a valid ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/prerequisites#acquire-node-address-from-network-peers",children:"node address"})," from the network"]}),"\n",(0,t.jsxs)(n.li,{children:["Know how to install a ",(0,t.jsx)(n.a,{href:"/1.5.X/developers/cli/sending-deploys",children:"smart contract"})," on a Casper network"]}),"\n",(0,t.jsx)(n.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,t.jsxs)(n.p,{children:["Clone the Casper NFT (CEP-78) ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/",children:"contract repository"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Run the following commands to build the ",(0,t.jsx)(n.code,{children:"contract.wasm"})," in the ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory and run the tests."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake test\n"})}),"\n",(0,t.jsx)(n.p,{children:"The output of the command would end with the following message:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"test result: ok. 159 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.33s\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-nft-contract",children:"Installing the NFT Contract"}),"\n",(0,t.jsx)(n.p,{children:"The following command will install a sample NFT contract on the Testnet:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsx)(n.p,{children:"Learn to query the contract, perform token transfers, set up approvals, and understand the testing framework."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query"})," the NTF Contract"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs",children:"Tests"})]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd661beb.dd72aba0.js b/assets/js/fd661beb.dd72aba0.js deleted file mode 100644 index 288b10be7..000000000 --- a/assets/js/fd661beb.dd72aba0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[5789],{33142:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>o,contentTitle:()=>a,default:()=>u,frontMatter:()=>i,metadata:()=>c,toc:()=>l});var t=s(74848),r=s(28453);const i={title:"Quick Installation"},a="Casper NFT Quick Installation Guide",c={id:"resources/tokens/cep78/using-casper-client/quickstart-guide",title:"Quick Installation",description:"This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.",source:"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide.md",sourceDirName:"resources/tokens/cep78/using-casper-client",slug:"/resources/tokens/cep78/using-casper-client/quickstart-guide",permalink:"/resources/tokens/cep78/using-casper-client/quickstart-guide",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Quick Installation"},sidebar:"resources",previous:{title:"CEP-78 Modalities",permalink:"/resources/tokens/cep78/modalities"},next:{title:"Installation Workflow",permalink:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial"}},o={},l=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"Setup",id:"setup",level:2},{value:"Installing the NFT Contract",id:"installing-the-nft-contract",level:2},{value:"Next Steps",id:"next-steps",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"casper-nft-quick-installation-guide",children:"Casper NFT Quick Installation Guide"})}),"\n",(0,t.jsxs)(n.p,{children:["This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the ",(0,t.jsx)(n.a,{href:"https://testnet.cspr.live/",children:"Casper Testnet"}),". For greater detail into the creation and mechanics of the Casper NFT contract, see the complete ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial",children:"Casper NFT Tutorial"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["To execute transactions on a Casper network involving NFTs, you will need some CSPR tokens to pay for the transactions. The Testnet provides test tokens using a ",(0,t.jsx)(n.a,{href:"/users/testnet-faucet",children:"faucet"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"prerequisites",children:"Prerequisites"}),"\n",(0,t.jsx)(n.p,{children:"Before using this guide, ensure you meet the following requirements:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:["Set up the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites",children:"development prerequisites"}),", including the ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#install-casper-client",children:"Casper client"})]}),"\n",(0,t.jsxs)(n.li,{children:["Get a valid ",(0,t.jsx)(n.a,{href:"/developers/prerequisites#acquire-node-address-from-network-peers",children:"node address"})," from the network"]}),"\n",(0,t.jsxs)(n.li,{children:["Know how to install a ",(0,t.jsx)(n.a,{href:"/developers/cli/sending-deploys",children:"smart contract"})," on a Casper network"]}),"\n",(0,t.jsx)(n.li,{children:"Hold enough CSPR tokens to pay for transactions"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"setup",children:"Setup"}),"\n",(0,t.jsxs)(n.p,{children:["Clone the Casper NFT (CEP-78) ",(0,t.jsx)(n.a,{href:"https://github.com/casper-ecosystem/cep-78-enhanced-nft/",children:"contract repository"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Run the following commands to build the ",(0,t.jsx)(n.code,{children:"contract.wasm"})," in the ",(0,t.jsx)(n.code,{children:"contract/target/wasm32-unknown-unknown/release"})," directory and run the tests."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"make prepare\nmake test\n"})}),"\n",(0,t.jsx)(n.p,{children:"The output of the command would end with the following message:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"test result: ok. 159 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.33s\n"})}),"\n",(0,t.jsx)(n.h2,{id:"installing-the-nft-contract",children:"Installing the NFT Contract"}),"\n",(0,t.jsx)(n.p,{children:"The following command will install a sample NFT contract on the Testnet:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:'casper-client put-deploy --node-address http://localhost:11101/rpc/ \\\n--chain-name "casper-net-1" \\\n--payment-amount 5000000000 \\\n--secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \\\n--session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \\\n--session-arg "collection_name:string=\'CEP-78-collection\'" \\\n--session-arg "collection_symbol:string=\'CEP78\'" \\\n--session-arg "total_token_supply:u64=\'100\'" \\\n--session-arg "ownership_mode:u8=\'2\'" \\\n--session-arg "nft_kind:u8=\'1\'" \\\n--session-arg "nft_metadata_kind:u8=\'0\'" \\\n--session-arg "json_schema:string=\'nft-schema\'" \\\n--session-arg "identifier_mode:u8=\'0\'" \\\n--session-arg "metadata_mutability:u8=\'0\'"\n'})}),"\n",(0,t.jsx)(n.h2,{id:"next-steps",children:"Next Steps"}),"\n",(0,t.jsx)(n.p,{children:"Learn to query the contract, perform token transfers, set up approvals, and understand the testing framework."}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/querying-NFTs",children:"Query"})," the NTF Contract"]}),"\n",(0,t.jsxs)(n.li,{children:["Learn to ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs",children:"Mint, Transfer, and Burn"})," NFT tokens"]}),"\n",(0,t.jsxs)(n.li,{children:["Review the ",(0,t.jsx)(n.a,{href:"/resources/tokens/cep78/using-casper-client/testing-NFTs",children:"Tests"})]}),"\n"]})]})}function u(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>a,x:()=>c});var t=s(96540);const r={},i=t.createContext(r);function a(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:a(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fd967833.84a1d37c.js b/assets/js/fd967833.84a1d37c.js new file mode 100644 index 000000000..94d914c67 --- /dev/null +++ b/assets/js/fd967833.84a1d37c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[19179],{584:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>d,contentTitle:()=>o,default:()=>h,frontMatter:()=>i,metadata:()=>a,toc:()=>c});var t=s(74848),r=s(28453);const i={title:"Endpoints"},o="Node Endpoints",a={id:"operators/setup/node-endpoints",title:"Endpoints",description:"As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.",source:"@site/versioned_docs/version-2.0.0/operators/setup/node-endpoints.md",sourceDirName:"operators/setup",slug:"/operators/setup/node-endpoints",permalink:"/2.0.0/operators/setup/node-endpoints",draft:!1,unlisted:!1,tags:[],version:"2.0.0",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1726493368e3,frontMatter:{title:"Endpoints"},sidebar:"operators",previous:{title:"Configuration",permalink:"/2.0.0/operators/setup/basic-node-configuration"},next:{title:"Installation",permalink:"/2.0.0/operators/setup/install-node"}},d={},c=[{value:"Default Networking Port: 35000",id:"35000",level:2},{value:"Default JSON-RPC HTTP Server Port: 7777",id:"7777",level:2},{value:"Default REST HTTP Server Port: 8888",id:"8888",level:2},{value:"Example usage",id:"example-usage",level:3},{value:"Default SSE HTTP Event Stream Server Port: 9999",id:"9999",level:2},{value:"Setting up Firewall Rules",id:"setting-up-firewall-rules",level:2},{value:"Restricting Access for Private Networks",id:"restricting-access-for-private-networks",level:2},{value:"Summary of Related Links",id:"summary-of-related-links",level:2}];function l(e){const n={a:"a",code:"code",details:"details",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",summary:"summary",ul:"ul",...(0,r.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"node-endpoints",children:"Node Endpoints"})}),"\n",(0,t.jsxs)(n.p,{children:["As specified in the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node#network-requirements",children:"Network Requirements"}),", a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The ",(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/p2p",children:"Network Communication"})," page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication."]}),"\n",(0,t.jsx)(n.p,{children:"This document describes in more detail a Casper node's default endpoints:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#35000",children:"Networking port: 35000"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#7777",children:"JSON-RPC HTTP server port: 7777"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#8888",children:"REST HTTP server port: 8888"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"#9999",children:"SSE HTTP event stream server port: 9999"})}),"\n"]}),"\n",(0,t.jsxs)(n.p,{children:["Node operators can modify a node's configuration options, including the port settings, by updating the ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#config-file",children:"node's config.toml"})," file. An example configuration file can be found ",(0,t.jsx)(n.a,{href:"https://github.com/casper-network/casper-protocol-release/blob/main/config/config-example.toml",children:"here"}),"."]}),"\n",(0,t.jsx)(n.p,{children:"The default endpoints for Mainnet and Testnet are open by default and are described below in more detail. If the node connects to a different network, the ports may differ depending on how the network was set up."}),"\n",(0,t.jsx)(n.h2,{id:"35000",children:"Default Networking Port: 35000"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for networking are under the ",(0,t.jsx)(n.code,{children:"network"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"bind_address"})," using port 35000 is the only port required to be open for the node to function. A Casper node taking part in the network should open connections to every other node it is aware of and has not blocked. In the ",(0,t.jsx)(n.code,{children:"config.toml"})," file, the setting is:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"bind_address = '0.0.0.0:35000'\n"})}),"\n",(0,t.jsx)(n.p,{children:"If the networking port is closed, the node becomes unreachable, and the node won't be discoverable in the network. If this is a validator, it will face eviction. A read-only node will be considered to be offline."}),"\n",(0,t.jsx)(n.h2,{id:"7777",children:"Default JSON-RPC HTTP Server Port: 7777"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rpc_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," using port 7777 is the listening address for JSON-RPC HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:7777'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["DApps would use this address to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/",children:"interact with the Casper JSON-RPC API"}),". Users would use this address to ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/",children:"interact with the network using CLI"}),". Validators would use this address to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"bond"})," or ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/unbonding",children:"unbond"}),". If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."]}),"\n",(0,t.jsx)(n.h2,{id:"8888",children:"Default REST HTTP Server Port: 8888"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the JSON-RPC HTTP server are under the ",(0,t.jsx)(n.code,{children:"rest_server"})," section in the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 8888 is the listening address for the REST HTTP server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:8888'\n"})}),"\n",(0,t.jsx)(n.p,{children:"Opening port 8888 is recommended but not required. This port allows the node to be included in the general network health metrics, thus giving a more accurate picture of overall network health. If this port is closed, the requests coming to this port will not be served, but the node remains unaffected."}),"\n",(0,t.jsxs)(n.p,{children:["One may use this port to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"get a trusted hash"}),", ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/upgrade#verifying-successful-staging",children:"verify successful staging"})," during an upgrade, or to ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"confirm that the node is synchronized"}),"."]}),"\n",(0,t.jsx)(n.h3,{id:"example-usage",children:"Example usage"}),"\n",(0,t.jsx)(n.p,{children:"For general health metrics, use this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/metrics\n"})}),"\n",(0,t.jsx)(n.p,{children:"You can check the node's status using this command:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status\n"})}),"\n",(0,t.jsxs)(n.p,{children:["The status endpoint provides a JSON response that can be parsed with ",(0,t.jsx)(n.code,{children:"jq"}),"."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'{\n "api_version": "1.4.15",\n "chainspec_name": "casper-test",\n "starting_state_root_hash": "4c3856bd6a95b566301b9da61aaf84589a51ee2980f3cc7bbef78e7745386955",\n "peers": [\n {\n "node_id": "tls:007e..e14b",\n "address": "89.58.52.245:35000"\n },\n {\n "node_id": "tls:00eb..ac11",\n "address": "65.109.17.120:35000"\n },\n ...\n {\n "node_id": "tls:ffc0..555b",\n "address": "95.217.228.224:35000"\n }\n ],\n "last_added_block_info": {\n "hash": "7acd2f48b573704e96eab54322f7e91a0624252baca3583ad2aae38229fe1715",\n "timestamp": "2023-05-10T09:20:10.752Z",\n "era_id": 9085,\n "height": 1711254,\n "state_root_hash": "1ac74071c1e76937c372c8d2ae22ea036a77578aad03821ec98021fdc1c5d06b",\n "creator": "0106ca7c39cd272dbf21a86eeb3b36b7c26e2e9b94af64292419f7862936bca2ca"\n },\n "our_public_signing_key": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e",\n "round_length": "32s 768ms",\n "next_upgrade": null,\n "build_version": "1.4.15-039d438f2-casper-mainnet",\n "uptime": "5days 13h 46m 54s 520ms"\n}\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"You can filter the result with dot notation, specifying one of the following parameters:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"api_version"})," - The RPC API version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"chainspec_name"})," - The chainspec name, used to identify the currently connected network"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"starting_state_root_hash"})," - The state root hash used at the start of the current session"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"peers"})," - The node ID and network address of each connected peer"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"last_added_block_info"})," - The minimal info of the last Block from the linear chain"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"our_public_signing_key"})," - Our public signing key"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"round_length"})," - The next round length if this node is a validator."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"next_upgrade"})," - Information about the next scheduled upgrade"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"build_version"})," - The compiled node version"]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"uptime"})," - Time that has passed since the node has started."]}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"Here is an example command for retrieving general network information:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq -r '.api_version, .last_added_block_info, .build_version, .uptime'\n"})}),"\n",(0,t.jsxs)(n.details,{children:["\n",(0,t.jsx)(n.summary,{children:"Sample response"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",children:'"1.4.15"\n{\n "hash": "dca9959b21df52633f85cd373a8117fe8e89629dd2a0455781484a439f7d9f62",\n "timestamp": "2023-05-10T09:26:43.968Z",\n "era_id": 9085,\n "height": 1711266,\n "state_root_hash": "5f374529e747a06ec825e07a030df7b9d80d1f7ffac9156779b4466620721872",\n "creator": "0107cba5b4826a87ddbe0ba8cda8064881b75882f05094c1a5f95e957512a3450e"\n}\n"1.4.15-039d438f2-casper-mainnet"\n"5days 13h 53m 10s 763ms"\n'})}),"\n"]}),"\n",(0,t.jsx)(n.p,{children:"To get information about the next upgrade, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .next_upgrade\n"})}),"\n",(0,t.jsx)(n.p,{children:"To get information about the last added block, use:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"curl -s http://<node_address>:8888/status | jq .last_added_block_info\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor the downloading of blocks to your node:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info'\n"})}),"\n",(0,t.jsx)(n.p,{children:"To monitor local block height as well as RPC port status:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"watch -n 15 'curl -s http://<node_address>:8888/status | jq \".peers | length\"; curl -s http://<node_address>:8888/status | jq .last_added_block_info; casper-client get-block -n http://<node_address>:8888/status'\n"})}),"\n",(0,t.jsx)(n.h2,{id:"9999",children:"Default SSE HTTP Event Stream Server Port: 9999"}),"\n",(0,t.jsxs)(n.p,{children:["The configuration options for the SSE HTTP event stream server are listed under the ",(0,t.jsx)(n.code,{children:"event_stream_server"})," section of the ",(0,t.jsx)(n.code,{children:"config.toml"})," file. The ",(0,t.jsx)(n.code,{children:"address"})," listing port 9999 is the listening address for the SSE HTTP event stream server."]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-md",children:"address = '0.0.0.0:9999'\n"})}),"\n",(0,t.jsxs)(n.p,{children:["If this port is closed, the requests coming to this port will not be served, but the node remains unaffected. For details and useful commands, see ",(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and Consuming Events"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"setting-up-firewall-rules",children:"Setting up Firewall Rules"}),"\n",(0,t.jsxs)(n.p,{children:["To limit inbound traffic to the node\u2019s endpoints, you can set firewall rules similar to the ",(0,t.jsx)(n.code,{children:"ufw"})," commands below:"]}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-bash",children:"sudo apt install ufw -y\nsudo ufw disable\nsudo ufw reset\nsudo ufw default allow outgoing\nsudo ufw default deny incoming\nsudo ufw limit ssh\nsudo ufw limit 7777/tcp\nsudo ufw limit 8888/tcp\nsudo ufw limit 35000/tcp\nsudo ufw enable\n"})}),"\n",(0,t.jsx)(n.p,{children:"These commands will limit requests to the available ports of your node. Port 35000 should be left open, although you can limit traffic, as it is crucial for node-to-node communication."}),"\n",(0,t.jsxs)(n.p,{children:["If you have any concerns, questions, or issues, please ",(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/requests/new",children:"submit a request"})," to the Casper support team."]}),"\n",(0,t.jsx)(n.h2,{id:"restricting-access-for-private-networks",children:"Restricting Access for Private Networks"}),"\n",(0,t.jsxs)(n.p,{children:["Any node can join Mainnet and Testnet and communicate with the nodes in the network. Private networks may wish to restrict access for new nodes joining the network as described ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup-network/create-private#network-access-control",children:"here"}),"."]}),"\n",(0,t.jsx)(n.h2,{id:"summary-of-related-links",children:"Summary of Related Links"}),"\n",(0,t.jsx)(n.p,{children:"Here is a summary of the links mentioned on this page:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/install-node#network-requirements",children:"Network requirements"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/concepts/design/p2p",children:"Network communication"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#config-file",children:"The node configuration file"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/json-rpc/",children:"Interacting with the Casper JSON-RPC API"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/cli/",children:"Interacting with the network using CLI"})}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/bonding#example-bonding-transaction",children:"Bonding"})," or ",(0,t.jsx)(n.a,{href:"/2.0.0/operators/becoming-a-validator/unbonding",children:"unbonding"})," as a validator"]}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/basic-node-configuration#trusted-hash-for-synchronizing",children:"Getting a trusted node hash"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/upgrade#verifying-successful-staging",children:"Verifying successful staging"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup/joining#step-7-confirm-the-node-is-synchronized",children:"Confirming that the node is synchronized"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/developers/dapps/monitor-and-consume-events",children:"Monitoring and consuming events"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"/2.0.0/operators/setup-network/create-private#network-access-control",children:"Private network access control"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://support.casperlabs.io/hc/en-gb/sections/6960448246683-Node-Operation-FAQ",children:"FAQs for a basic validator node "})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.a,{href:"https://docs.cspr.community/docs/faq-validator.html",children:"External FAQs on Mainnet and Testnet validator node setup"})}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var t=s(96540);const r={},i=t.createContext(r);function o(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe0242b1.4ee542a5.js b/assets/js/fe0242b1.4ee542a5.js new file mode 100644 index 000000000..ceef321d1 --- /dev/null +++ b/assets/js/fe0242b1.4ee542a5.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[48631],{67074:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var n=i(74848),a=i(28453);const s={id:"disclaimer",title:"Disclaimer"},r="Disclaimer {#disclaimer}",o={id:"disclaimer",title:"Disclaimer",description:"disclaimer}",source:"@site/docs/disclaimer.md",sourceDirName:".",slug:"/disclaimer",permalink:"/disclaimer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1719954371e3,frontMatter:{id:"disclaimer",title:"Disclaimer"}},c={},h=[{value:"Preliminary Nature of this Whitepaper",id:"preliminary-nature-of-this-whitepaper",level:4},{value:"Forward-Looking Statements",id:"forward-looking-statements",level:4},{value:"Risk Factors",id:"risk-factors",level:4}];function d(e){const t={h1:"h1",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"disclaimer",children:"Disclaimer"})}),"\n",(0,n.jsx)(t.p,{children:'By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR\u201d). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO\u201d) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA\u201d) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA\u201d) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.'}),"\n",(0,n.jsx)(t.p,{children:'The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC\u201d). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.'}),"\n",(0,n.jsx)(t.p,{children:"The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required."}),"\n",(0,n.jsx)(t.p,{children:"No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient\u2019s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature."}),"\n",(0,n.jsx)(t.h4,{id:"preliminary-nature-of-this-whitepaper",children:"Preliminary Nature of this Whitepaper"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA\u201d). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.'}),"\n",(0,n.jsx)(t.h4,{id:"forward-looking-statements",children:"Forward-Looking Statements"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper includes "forward-looking statements\u201d, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe\u201d, "anticipate\u201d, "expect\u201d, "project\u201d, "estimate\u201d, "predict\u201d, "intend\u201d, "target\u201d, "assume\u201d, "may\u201d, "might\u201d, "could\u201d, "should\u201d, "will\u201d and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 present and future expectations regarding the development of the Casper blockchain and the associated software.'}),"\n",(0,n.jsx)(t.p,{children:"These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based."}),"\n",(0,n.jsx)(t.h4,{id:"risk-factors",children:"Risk Factors"}),"\n",(0,n.jsx)(t.p,{children:'Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient\u201d) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.'}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CasperLabs Networks AG\u2019s experience"}),": the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CSPR relative value"}),": the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with (intellectual) property rights"}),": the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with blockchain"}),": the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risk of weaknesses in the field of cryptography"}),": the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Regulatory risks"}),": the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with abandonment / lack of success"}),": the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a loss of private key"}),": the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient\u2019s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient\u2019s account (address) will be unrecoverable and will be permanently lost."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with wallets"}),": the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with theft/hacks"}),": the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with mining attacks"}),": the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a lack of consensus"}),": the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with liquidity of CSPR"}),": the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with forking"}),": the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient\u2019s CSPR (if and when created and/or issued)."]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>o});var n=i(96540);const a={},s=n.createContext(a);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fe0242b1.da99f6c2.js b/assets/js/fe0242b1.da99f6c2.js deleted file mode 100644 index c5a35bb67..000000000 --- a/assets/js/fe0242b1.da99f6c2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[1012],{67074:(e,t,i)=>{i.r(t),i.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>l,frontMatter:()=>s,metadata:()=>o,toc:()=>h});var n=i(74848),a=i(28453);const s={id:"disclaimer",title:"Disclaimer"},r="Disclaimer {#disclaimer}",o={id:"disclaimer",title:"Disclaimer",description:"disclaimer}",source:"@site/docs/disclaimer.md",sourceDirName:".",slug:"/disclaimer",permalink:"/next/disclaimer",draft:!1,unlisted:!1,tags:[],version:"current",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1719954371e3,frontMatter:{id:"disclaimer",title:"Disclaimer"}},c={},h=[{value:"Preliminary Nature of this Whitepaper",id:"preliminary-nature-of-this-whitepaper",level:4},{value:"Forward-Looking Statements",id:"forward-looking-statements",level:4},{value:"Risk Factors",id:"risk-factors",level:4}];function d(e){const t={h1:"h1",h4:"h4",header:"header",li:"li",p:"p",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"disclaimer",children:"Disclaimer"})}),"\n",(0,n.jsx)(t.p,{children:'By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR\u201d). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.'}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO\u201d) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA\u201d) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA\u201d) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.'}),"\n",(0,n.jsx)(t.p,{children:'The CSPR are not expected to be instruments in an offer and sale which are subject to the jurisdiction or oversight of the U.S. Securities Exchange Commission (the "SEC\u201d). In any event, however, CSPR have not been approved or disapproved by, and are not expected to be approved or disapproved by, the SEC nor by the securities regulatory authority of any state of the United States of America or of any other jurisdiction, and neither the SEC nor any such securities regulatory authority has passed, or is expected to pass, upon the accuracy or adequacy of this Whitepaper.'}),"\n",(0,n.jsx)(t.p,{children:"The distribution of this Whitepaper and the purchase, holding, and/or disposal of CSPR may be restricted by law in certain jurisdictions. Persons reading this Whitepaper should inform themselves as to (i) the possible tax consequences, (ii) the legal and regulatory requirements, and (iii) any foreign exchange restrictions or exchange control requirements, which they might encounter under the laws of the countries of their citizenship, residence or domi-cile and which might be relevant to the purchase, holding or disposal of CSPR. No action has been taken to authorise the distribution of this Whitepaper in any jurisdiction in which such authorisation might be required."}),"\n",(0,n.jsx)(t.p,{children:"No action has been or is intended to be taken by CasperLabs Networks AG and/or any of its affiliates in any jurisdiction that would or is intended to, permit a public sale or offering of any CSPR, or possession or distribution of this Whitepaper (in preliminary, proof or final form) or any other sale, offering or publicity material relating to the CSPR, in any country or jurisdiction where action for that purpose is required. Each recipient of this Whitepaper is reminded that it has received this Whitepaper on the basis that it is a person into whose possession this Whitepaper may be lawfully delivered in accordance with the laws of the jurisdiction in which it is located and/or bound and it may not nor is it authorised to deliver this document, electronically or otherwise, to any other person. If the recipient receives this document by e-mail, then its use of this e-mail is at its own risk and it is the recipient\u2019s responsibility to take precautions to ensure that such e-mail is free from viruses and other items of a destructive nature."}),"\n",(0,n.jsx)(t.h4,{id:"preliminary-nature-of-this-whitepaper",children:"Preliminary Nature of this Whitepaper"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper is a draft and the information set out herein is of a preliminary nature. Consequently, neither CasperLabs Networks AG nor any of its affiliates assumes any responsibility that the information set out herein is final or correct and each of the foregoing disclaims, to the fullest extent permitted by applicable law, any and all liability whether arising in tort, contract or otherwise in respect of this Whitepaper. Neither this Whitepaper nor anything contained herein shall form the basis of or be relied on in connection with or act as an inducement to enter into any contract or commitment whatsoever. Recipients should note that the final structuring of CSPR and the Casper blockchain is subject to ongoing technical, legal, regulatory and tax considerations and each is, therefore, subject to material changes. In particular, neither the applicability nor the non-applicability of Swiss financial market regulations on the CSPR sale has not been confirmed by the Swiss Financial Market Supervisory Authority ("FINMA\u201d). CasperLabs Networks AG and all its affiliates reserve the right to not assist in the completion of the software underlying CSPR and the CasperLabs blockchain, to not participate in the issuance or creation of CSPR or to change the structure of CSPR and/or the Casper blockchain for any reason, each at its sole discretion.'}),"\n",(0,n.jsx)(t.h4,{id:"forward-looking-statements",children:"Forward-Looking Statements"}),"\n",(0,n.jsx)(t.p,{children:'This Whitepaper includes "forward-looking statements\u201d, which are all statements other than statements of historical facts included in this Whitepaper. Words like "believe\u201d, "anticipate\u201d, "expect\u201d, "project\u201d, "estimate\u201d, "predict\u201d, "intend\u201d, "target\u201d, "assume\u201d, "may\u201d, "might\u201d, "could\u201d, "should\u201d, "will\u201d and similar expressions are intended to identify such forward-looking statements. Such forward-looking statements involve known and unknown risks, uncertainties and other factors, which may cause the actual functionality, performance or features of the Casper blockchain and/or CSPR to be materially different from any future functionality, performance or features expressed or implied by such forward-looking statements. Such forward-looking statements are based on numerous assumptions regarding the CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 present and future expectations regarding the development of the Casper blockchain and the associated software.'}),"\n",(0,n.jsx)(t.p,{children:"These forward-looking statements speak only as of the date of this Whitepaper. CasperLabs Networks AG and its affiliates expressly disclaim any obligation or undertaking to release any updates of or revisions to any forward-looking statement contained herein to reflect any change in CasperLabs Networks AG\u2019s and/or any of its affiliates\u2019 expectations with regard thereto or any change in events, conditions or circumstances on which any such statement is based."}),"\n",(0,n.jsx)(t.h4,{id:"risk-factors",children:"Risk Factors"}),"\n",(0,n.jsx)(t.p,{children:'Furthermore, by accepting this Whitepaper, the recipient of hereof (the "Recipient\u201d) acknowledges and agrees that it understands the inherent risks associated with blockchain and distributed ledger technology, tokens and cryptocurrencies in general and the CSPR in particular, including, but not limited to, those outlined hereinafter.'}),"\n",(0,n.jsxs)(t.ul,{children:["\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CasperLabs Networks AG\u2019s experience"}),": the Recipient is aware that CasperLabs Networks AG and its affiliates constitute a start-up group of companies. Inability of such companies to manage their affairs, including any failure to attract and retain appropriate personnel, could affect the completion and functionality of the Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with CSPR relative value"}),": the Recipient understands and accepts that a purchaser of CSPR may experience financial losses relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR). Potential purchasers and holders of CSPR are urged to carefully review this Whitepaper and assess and understand the risk factors relating to the CSPR and the Casper blockchain before acquiring CSPR (when and if CSPR become available)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with (intellectual) property rights"}),": the Recipient understands and accepts that, due to a lack of originality of the software and to the immaterial character of the CSPR, there may be no title of ownership in and to the intellectual property rights relating to CSPR."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with blockchain"}),": the Recipient understands and accepts that the smart contract, the underlying software application and software platform (i.e. the Casper blockchain) is still in an early development stage and unproven. The Recipient understands and accepts that there is no warranty that the process for creating the CSPR and/or the Casper blockchain will be uninterrupted or error-free and acknowledges that there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of CSPR. The Recipient understands and accepts that, after launch of the Casper blockchain, the smart contract and/or underlying protocols and/or the Casper blockchain and/or any other software involved may either delay and/or not execute a contribution due to the overall contribution volume, mining attacks and/or similar events."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risk of weaknesses in the field of cryptography"}),": the Recipient understands and accepts that cryptography is a technology that evolves relatively fast over time. At the same time, methods and tools to decrypt, access and/or manipulate data stored on a distributed ledger or blockchain are highly likely to progress in parallel and in addition, new technological developments such as quantum computers may pose as of now unpredictable risks to the CSPR and the Casper blockchain that could increase the risk of theft or loss of CSPR (if and when CSPR are created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Regulatory risks"}),": the Recipient understands and accepts that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, distributed ledger technology and/or blockchain technology based applications, which may be contrary to the current setup of the smart contract or the CasperLabs Networks AG project and which may, inter alia, result in substantial modifications of the smart contract and/or the CasperLabs Networks AG project, including its termination and the loss of the CSPR, if and when created and/or issued, or entitlements to receive CSPR, for the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with abandonment / lack of success"}),": the Recipient understands and accepts that the creation of the CSPR and the development of the Casper blockchain as well as the CasperLabs Networks AG project may be abandoned for a number of reasons, including lack of interest from the public, lack of funding, lack of prospects (e.g. caused by competing projects) and legal, tax or regulatory considerations. The Recipient therefore understands that there is no assurance that, even if the CSPR/CasperLabs blockchain project is partially or fully developed and launched, the Recipient will receive any benefits through the CSPR held by it (if and when created and/or issued)."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a loss of private key"}),": the Recipient understands and accepts that CSPR, if and when created and/or issued, will only be accessed by using a wallet technically compatible with CSPR and with a combination of the Recipient\u2019s account information (address) and private key, seed or password. The Recipient understands and accepts that if its private key or password gets lost or stolen, the CSPR associated with the Recipient\u2019s account (address) will be unrecoverable and will be permanently lost."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with wallets"}),": the Recipient understands and accepts that CasperLabs Networks AG or any of its affiliates, employees, partners or advisors are in no way responsible for the wallet to which any CSPR are transferred. The Recipient understands and agrees that it is solely responsible for the access and security of its wallet, for any security breach of its wallet and/or with any loss of CSPR resulting from its wallet service provider, including any termination of the service by the wallet provider and/or bankruptcy of the wallet provider."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with theft/hacks"}),": the Recipient understands and accepts that the smart contract, the website, the underlying software application and software platform (i.e. the Casper blockchain), during its development and after its launch, may be exposed to attacks by hackers or other individuals that could result in an inability to launch the Casper blockchain or the theft or loss of CSPR. Any such event could also result in the loss of financial and other support of the CasperLabs Networks AG project impacting the ability to develop the CasperLabs Networks AG project and Casper blockchain."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with mining attacks"}),": the Recipient understands and accepts that, as with other cryptocurrencies and tokens, if and when launched, the Casper blockchain is susceptible to attacks relating to validators. Any successful attack presents a risk to the smart contract, expected proper execution and sequencing of transactions, and expected proper execution and sequencing of contract computations."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with a lack of consensus"}),": the Recipient understands and accepts that the network of validators will be ultimately in control of the genesis block and future blocks and that there is no warranty or assurance that the network of validators will perform their functions and reach proper consensus and allocate the CSPR to the Recipient as proposed by any terms. The Recipient further understands that a majority of the validators could agree at any point to make changes to the software and/or smart contracts and to run the new version of the software and/or smart contracts. Such a scenario could lead to the CSPR losing intrinsic value."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with liquidity of CSPR"}),": the Recipient understands and accepts that with regard to the CSPR, if and when created and/or issued, no market liquidity may be guaranteed and that the value of CSPR relative to other assets, including fiat currency and/or any other cryptocurrency (including any cryptocurrency used to acquire CSPR) over time may experience extreme volatility or depreciate in full (including to zero) resulting in loss that will be borne exclusively by the Recipient."]}),"\n"]}),"\n",(0,n.jsxs)(t.li,{children:["\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.strong,{children:"Risks associated with forking"}),": the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient\u2019s CSPR (if and when created and/or issued)."]}),"\n"]}),"\n"]})]})}function l(e={}){const{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,n.jsx)(t,{...e,children:(0,n.jsx)(d,{...e})}):d(e)}},28453:(e,t,i)=>{i.d(t,{R:()=>r,x:()=>o});var n=i(96540);const a={},s=n.createContext(a);function r(e){const t=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:r(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fef6ab33.16f28ded.js b/assets/js/fef6ab33.16f28ded.js deleted file mode 100644 index c1669129c..000000000 --- a/assets/js/fef6ab33.16f28ded.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8155],{79008:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=s(74848),o=s(28453);const i={title:"Genesis"},c="The Genesis Block {#the-genesis-block}",r={id:"operators/setup-network/genesis",title:"Genesis",description:"the-genesis-block}",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/genesis.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/genesis",permalink:"/operators/setup-network/genesis",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Genesis"},sidebar:"operators",previous:{title:"Setting up Private Networks",permalink:"/operators/setup-network/"},next:{title:"The Chainspec",permalink:"/operators/setup-network/chain-spec"}},a={},l=[{value:"chainspec.toml",id:"chainspectoml",level:2},{value:"accounts.toml",id:"accountstoml",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"the-genesis-block",children:"The Genesis Block"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper node software creates a genesis block from the following input files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"chainspec.toml"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"accounts.toml"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,t.jsxs)(n.p,{children:["A version of the ",(0,t.jsx)(n.a,{href:"/concepts/glossary/C#chainspec",children:"chainspec"})," is downloaded by the ",(0,t.jsx)(n.code,{children:"pull_casper_node_version.sh"})," script installed with the casper-node-launcher debian package. This script pulls the ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," file from the appropriate path defined in the network config file used (",(0,t.jsx)(n.code,{children:"casper.conf"})," for MainNet and ",(0,t.jsx)(n.code,{children:"casper-test.conf"})," for TestNet)."]}),"\n",(0,t.jsxs)(n.p,{children:["The production version of the file from which this is based on can be found at ",(0,t.jsx)(n.code,{children:"casper-node/resources/production/chainspec.toml"})," in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to ",(0,t.jsx)(n.a,{href:"/operators/setup-network/chain-spec",children:"this page"})," for detailed documentation on each of the variables in the file."]}),"\n",(0,t.jsx)(n.h2,{id:"accountstoml",children:"accounts.toml"}),"\n",(0,t.jsx)(n.p,{children:"This file contains the genesis validator set information, starting accounts and associated balances and bond amounts."}),"\n",(0,t.jsxs)(n.p,{children:["If an account is not bonded at genesis, specify a ",(0,t.jsx)(n.code,{children:"0"})," for the bond amount."]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the ",(0,t.jsx)(n.code,{children:"chainspec.toml"}),", this is pulled from the appropriate path defined in the network config file used."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/fef6ab33.746d8b52.js b/assets/js/fef6ab33.746d8b52.js new file mode 100644 index 000000000..e67f6da90 --- /dev/null +++ b/assets/js/fef6ab33.746d8b52.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[18155],{79008:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>a,contentTitle:()=>c,default:()=>h,frontMatter:()=>i,metadata:()=>r,toc:()=>l});var t=s(74848),o=s(28453);const i={title:"Genesis"},c="The Genesis Block {#the-genesis-block}",r={id:"operators/setup-network/genesis",title:"Genesis",description:"the-genesis-block}",source:"@site/versioned_docs/version-1.5.X/operators/setup-network/genesis.md",sourceDirName:"operators/setup-network",slug:"/operators/setup-network/genesis",permalink:"/1.5.X/operators/setup-network/genesis",draft:!1,unlisted:!1,tags:[],version:"1.5.X",lastUpdatedBy:"Mel Padden",lastUpdatedAt:1724759228e3,frontMatter:{title:"Genesis"},sidebar:"operators",previous:{title:"Setting up Private Networks",permalink:"/1.5.X/operators/setup-network/"},next:{title:"The Chainspec",permalink:"/1.5.X/operators/setup-network/chain-spec"}},a={},l=[{value:"chainspec.toml",id:"chainspectoml",level:2},{value:"accounts.toml",id:"accountstoml",level:2}];function d(e){const n={a:"a",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.header,{children:(0,t.jsx)(n.h1,{id:"the-genesis-block",children:"The Genesis Block"})}),"\n",(0,t.jsx)(n.p,{children:"The Casper node software creates a genesis block from the following input files:"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"chainspec.toml"})}),"\n",(0,t.jsx)(n.li,{children:(0,t.jsx)(n.code,{children:"accounts.toml"})}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"chainspectoml",children:"chainspec.toml"}),"\n",(0,t.jsxs)(n.p,{children:["A version of the ",(0,t.jsx)(n.a,{href:"/1.5.X/concepts/glossary/C#chainspec",children:"chainspec"})," is downloaded by the ",(0,t.jsx)(n.code,{children:"pull_casper_node_version.sh"})," script installed with the casper-node-launcher debian package. This script pulls the ",(0,t.jsx)(n.code,{children:"chainspec.toml"})," file from the appropriate path defined in the network config file used (",(0,t.jsx)(n.code,{children:"casper.conf"})," for MainNet and ",(0,t.jsx)(n.code,{children:"casper-test.conf"})," for TestNet)."]}),"\n",(0,t.jsxs)(n.p,{children:["The production version of the file from which this is based on can be found at ",(0,t.jsx)(n.code,{children:"casper-node/resources/production/chainspec.toml"})," in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to ",(0,t.jsx)(n.a,{href:"/1.5.X/operators/setup-network/chain-spec",children:"this page"})," for detailed documentation on each of the variables in the file."]}),"\n",(0,t.jsx)(n.h2,{id:"accountstoml",children:"accounts.toml"}),"\n",(0,t.jsx)(n.p,{children:"This file contains the genesis validator set information, starting accounts and associated balances and bond amounts."}),"\n",(0,t.jsxs)(n.p,{children:["If an account is not bonded at genesis, specify a ",(0,t.jsx)(n.code,{children:"0"})," for the bond amount."]}),"\n",(0,t.jsxs)(n.p,{children:["Similar to the ",(0,t.jsx)(n.code,{children:"chainspec.toml"}),", this is pulled from the appropriate path defined in the network config file used."]})]})}function h(e={}){const{wrapper:n}={...(0,o.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},28453:(e,n,s)=>{s.d(n,{R:()=>c,x:()=>r});var t=s(96540);const o={},i=t.createContext(o);function c(e){const n=t.useContext(i);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function r(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:c(e.components),t.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/main.8959bba6.js b/assets/js/main.8959bba6.js deleted file mode 100644 index f47644a70..000000000 --- a/assets/js/main.8959bba6.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.8959bba6.js.LICENSE.txt */ -(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[8792],{89188:(e,t,n)=>{"use strict";n.d(t,{W:()=>o});var r=n(96540);function o(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20","aria-hidden":"true"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},35947:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});n(96540);var r=n(53259),o=n.n(r),s=n(84054);const a={"01a85c17":[()=>Promise.all([n.e(1869),n.e(8209)]).then(n.bind(n,69158)),"@theme/BlogTagsListPage",69158],"028247bf":[()=>n.e(3540).then(n.bind(n,71648)),"@site/versioned_docs/version-1.5.X/concepts/glossary/P.md",71648],"03aa8e23":[()=>n.e(3586).then(n.bind(n,94073)),"@site/docs/concepts/design/highway.md",94073],"03acd2fb":[()=>n.e(9378).then(n.bind(n,94903)),"@site/docs/operators/setup/install-node.md",94903],"03c6d9c7":[()=>n.e(4684).then(n.bind(n,33603)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-pos.md",33603],"044f7961":[()=>n.e(8114).then(n.bind(n,88914)),"@site/docs/developers/dapps/signing-a-transaction.md",88914],"04f8200d":[()=>n.e(635).then(n.bind(n,48232)),"@site/versioned_docs/version-1.5.X/users/csprlive/undelegate-ui.md",48232],"053d5d89":[()=>n.e(8953).then(n.bind(n,14764)),"@site/docs/developers/writing-onchain-code/upgrading-contracts.md",14764],"05a3aa78":[()=>n.e(885).then(n.bind(n,95773)),"@site/docs/resources/beginner/counter-testnet/commands.md",95773],"06c1e821":[()=>n.e(1381).then(n.bind(n,91015)),"@site/docs/developers/dapps/sdk/csharp-sdk.md",91015],"074e7bdc":[()=>n.e(2289).then(n.bind(n,29066)),"@site/docs/operators/maintenance/archiving-and-restoring.md",29066],"0753c93f":[()=>n.e(8579).then(n.bind(n,46963)),"@site/versioned_docs/version-1.5.X/developers/cli/opcode-costs.md",46963],"0791978c":[()=>n.e(2905).then(n.bind(n,22285)),"@site/versioned_docs/version-1.5.X/resources/advanced/cross-contract.md",22285],"08996e66":[()=>n.e(4426).then(n.bind(n,57450)),"@site/docs/developers/dapps/sdk/client-library-usage.md",57450],"08af526d":[()=>n.e(529).then(n.t.bind(n,41344,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-3ce.json",41344],"0904ce24":[()=>n.e(5552).then(n.bind(n,18923)),"@site/versioned_docs/version-1.5.X/operators/index.md",18923],"0ac4e675":[()=>n.e(8562).then(n.bind(n,17451)),"@site/versioned_docs/version-1.5.X/developers/dapps/technology-stack.md",17451],"0b8cc739":[()=>n.e(9356).then(n.bind(n,69833)),"@site/docs/developers/cli/installing-contracts.md",69833],"0bb2dbe9":[()=>n.e(8061).then(n.bind(n,84303)),"@site/docs/developers/writing-onchain-code/calling-contracts.md",84303],"0bd3b317":[()=>n.e(4643).then(n.bind(n,40975)),"@site/blog/2024-07-16-fee-elimination.md",40975],"0c098c15":[()=>n.e(5884).then(n.bind(n,82880)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/upgrading-contracts.md",82880],"0cde4ba3":[()=>n.e(7491).then(n.bind(n,8542)),"@site/docs/resources/tokens/index.md",8542],"0dea8207":[()=>n.e(2352).then(n.bind(n,48563)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/csharp-sdk.md",48563],"106a38e1":[()=>n.e(8256).then(n.bind(n,82480)),"@site/versioned_docs/version-1.5.X/developers/cli/redelegate.md",82480],"106b67a5":[()=>n.e(899).then(n.bind(n,65699)),"@site/docs/developers/writing-onchain-code/testing-contracts.md",65699],"116fa82a":[()=>n.e(3509).then(n.bind(n,85298)),"@site/docs/operators/setup-network/index.md",85298],"124873a8":[()=>n.e(7795).then(n.bind(n,39026)),"@site/blog/2024-07-17-addressable-entity.md",39026],"12e95288":[()=>n.e(889).then(n.bind(n,88738)),"@site/versioned_docs/version-1.5.X/concepts/glossary/N.md",88738],"130631d9":[()=>n.e(2748).then(n.bind(n,59869)),"@site/docs/concepts/glossary/W.md",59869],"134a9ec2":[()=>n.e(9635).then(n.bind(n,41392)),"@site/docs/concepts/key-types.md",41392],"14620e15":[()=>n.e(2447).then(n.bind(n,12114)),"@site/docs/concepts/glossary/J.md",12114],"157e4bc2":[()=>n.e(3632).then(n.bind(n,84775)),"@site/docs/resources/tokens/cep78/using-casper-client.md",84775],"15ce11b3":[()=>n.e(7746).then(n.bind(n,84209)),"@site/docs/resources/advanced/two-party-multi-sig.md",84209],"168da062":[()=>n.e(6365).then(n.bind(n,26962)),"@site/versioned_docs/version-1.5.X/operators/maintenance/moving-node.md",26962],17896441:[()=>Promise.all([n.e(1869),n.e(1494),n.e(8401)]).then(n.bind(n,30575)),"@theme/DocItem",30575],"1871ac35":[()=>n.e(7356).then(n.bind(n,61594)),"@site/versioned_docs/version-1.5.X/resources/tokens/index.md",61594],"197196c4":[()=>n.e(9941).then(n.bind(n,37581)),"@site/blog/2024-07-16-setting-up-condor-local.md",37581],"19770ceb":[()=>n.e(1393).then(n.bind(n,7132)),"@site/docs/developers/writing-onchain-code/best-practices.md",7132],"1a4e3797":[()=>Promise.all([n.e(1869),n.e(2138)]).then(n.bind(n,74604)),"@theme/SearchPage",74604],"1b0eecbc":[()=>n.e(526).then(n.bind(n,62284)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-transactional.md",62284],"1b2f0a70":[()=>n.e(414).then(n.bind(n,77553)),"@site/docs/developers/json-rpc/minimal-compliance.md",77553],"1c694ffb":[()=>n.e(6898).then(n.bind(n,10289)),"@site/docs/developers/writing-onchain-code/assembly-script.md",10289],"1e144f6d":[()=>n.e(2702).then(n.bind(n,10816)),"@site/docs/resources/beginner/counter-testnet/overview.md",10816],"202767e6":[()=>n.e(4008).then(n.bind(n,5385)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_cl.md",5385],"2063472f":[()=>n.e(3215).then(n.t.bind(n,17646,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-18b.json",17646],"20f436ec":[()=>n.e(9392).then(n.bind(n,95578)),"@site/versioned_docs/version-1.5.X/developers/cli/undelegate.md",95578],"212aab5d":[()=>n.e(2709).then(n.bind(n,93522)),"@site/versioned_docs/version-1.5.X/developers/prerequisites.md",93522],"21ae0e7e":[()=>n.e(5819).then(n.bind(n,73177)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/staking.md",73177],"22dd74f7":[()=>n.e(1567).then(n.t.bind(n,55226,19)),"@generated/docusaurus-plugin-content-docs/default/p/index-466.json",55226],"236eb0f0":[()=>n.e(3101).then(n.bind(n,61055)),"@site/docs/resources/beginner/counter/walkthrough.md",61055],"23e022aa":[()=>n.e(9155).then(n.bind(n,62267)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/errors.md",62267],"241648bf":[()=>n.e(6220).then(n.bind(n,1202)),"@site/versioned_docs/version-1.5.X/developers/cli/execution-error-codes.md",1202],"25f19435":[()=>n.e(8344).then(n.bind(n,82432)),"@site/docs/concepts/global-state.md",82432],"261dbd4a":[()=>n.e(9899).then(n.bind(n,38123)),"@site/docs/developers/writing-onchain-code/emitting-contract-events.md",38123],"2668f34f":[()=>n.e(1458).then(n.bind(n,93517)),"@site/docs/users/ledger/ledger-setup.md",93517],"26a33332":[()=>n.e(4998).then(n.bind(n,33219)),"@site/versioned_docs/version-1.5.X/resources/advanced/list-auth-keys-tutorial.md",33219],"26f7e8fd":[()=>n.e(4891).then(n.bind(n,85947)),"@site/versioned_docs/version-1.5.X/concepts/design/casper-design.md",85947],"277b6be0":[()=>n.e(4054).then(n.bind(n,96738)),"@site/blog/2024-08-20-validator-rewards.md",96738],"28b5b925":[()=>n.e(1818).then(n.bind(n,95038)),"@site/docs/resources/tokens/cep18/full-tutorial.md",95038],"28bc9864":[()=>n.e(5069).then(n.bind(n,1697)),"@site/docs/operators/becoming-a-validator/unbonding.md",1697],"2b8e251b":[()=>n.e(1180).then(n.bind(n,6994)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/full-tutorial.md",6994],"2bd0ed90":[()=>n.e(6595).then(n.bind(n,95239)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Q.md",95239],"2c04116d":[()=>n.e(7802).then(n.bind(n,54575)),"@site/versioned_docs/version-1.5.X/resources/index.md",54575],"2c27a7b4":[()=>n.e(4805).then(n.bind(n,35224)),"@site/docs/resources/moving-to-casper.md",35224],"2cb8ed3d":[()=>n.e(8794).then(n.bind(n,35946)),"@site/docs/concepts/glossary/R.md",35946],"2cc4f81c":[()=>n.e(1741).then(n.bind(n,69319)),"@site/versioned_docs/version-1.5.X/concepts/hash-types.md",69319],"2d971abe":[()=>n.e(5768).then(n.bind(n,35040)),"@site/docs/developers/dapps/nctl-test.md",35040],"2e4bdb60":[()=>n.e(4586).then(n.bind(n,476)),"@site/docs/concepts/glossary/index.md",476],"2fb5589e":[()=>n.e(3213).then(n.bind(n,91376)),"@site/docs/resources/advanced/multi-sig/index.md",91376],"2ffce966":[()=>n.e(6552).then(n.bind(n,25255)),"@site/docs/developers/cli/transfers/index.md",25255],"31722bc4":[()=>n.e(1961).then(n.bind(n,45539)),"@site/docs/operators/setup/casper-sidecar.md",45539],"31dbaea7":[()=>n.e(7675).then(n.bind(n,87669)),"@site/versioned_docs/version-1.5.X/concepts/glossary/K.md",87669],"32dd135c":[()=>n.e(9540).then(n.bind(n,29683)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/modalities.md",29683],"331badc5":[()=>n.e(4707).then(n.bind(n,39824)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-live.md",39824],"3362155c":[()=>n.e(4635).then(n.bind(n,20633)),"@site/versioned_docs/version-1.5.X/developers/dapps/monitor-and-consume-events.md",20633],"33a9c3bd":[()=>n.e(8631).then(n.t.bind(n,48018,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-hello-f4b.json",48018],"33fc5bb8":[()=>Promise.all([n.e(1869),n.e(1494),n.e(3347),n.e(867)]).then(n.bind(n,30778)),"@theme/Blog/Pages/BlogAuthorsPostsPage",30778],"340c2365":[()=>n.e(1187).then(n.bind(n,62651)),"@site/versioned_docs/version-1.5.X/operators/setup/install-node.md",62651],"34b086e1":[()=>n.e(140).then(n.bind(n,98733)),"@site/versioned_docs/version-1.5.X/concepts/economics/consensus.md",98733],"35808b61":[()=>n.e(2714).then(n.bind(n,30347)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/script-sdk.md",30347],"358cf6da":[()=>n.e(6109).then(n.t.bind(n,13275,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-sczembor-c4b.json",13275],"35a4f7b3":[()=>n.e(956).then(n.bind(n,87675)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/index.md",87675],"3619739c":[()=>n.e(124).then(n.bind(n,19790)),"@site/docs/concepts/economics/runtime.md",19790],"362368d5":[()=>n.e(8190).then(n.bind(n,60940)),"@site/docs/concepts/glossary/P.md",60940],"3669623c":[()=>n.e(442).then(n.bind(n,68329)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-setup.md",68329],"36994c47":[()=>n.e(9858).then(n.t.bind(n,45516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",45516],"3724f9ed":[()=>n.e(5255).then(n.bind(n,58592)),"@site/docs/developers/writing-onchain-code/writing-session-code.md",58592],"381391cb":[()=>n.e(6139).then(n.bind(n,35170)),"@site/docs/resources/advanced/index.md",35170],38296185:[()=>n.e(2743).then(n.bind(n,42311)),"@site/docs/concepts/glossary/E.md",42311],"38b4dbd3":[()=>n.e(2033).then(n.bind(n,99648)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/delegation.md",99648],"398cf21c":[()=>n.e(7320).then(n.bind(n,68259)),"@site/docs/concepts/list-auth-keys.md",68259],"39ac5a41":[()=>n.e(8016).then(n.bind(n,55847)),"@site/versioned_docs/version-1.5.X/concepts/callstack.md",55847],"3a5d5492":[()=>n.e(5418).then(n.bind(n,63944)),"@site/docs/resources/tokens/cep78/introduction.md",63944],"3a9d2720":[()=>n.e(3127).then(n.bind(n,52886)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/inactive-vs-faulty.md",52886],"3aa29420":[()=>n.e(1515).then(n.bind(n,28510)),"@site/versioned_docs/version-1.5.X/concepts/glossary/B.md",28510],"3aaf2bfb":[()=>n.e(666).then(n.bind(n,76599)),"@site/docs/developers/json-rpc/errors.md",76599],"3ac85609":[()=>n.e(8626).then(n.bind(n,42429)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/index.md",42429],"3b749ca6":[()=>n.e(6708).then(n.bind(n,69261)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/tests.md",69261],"3b86d751":[()=>n.e(6815).then(n.bind(n,25023)),"@site/versioned_docs/version-1.5.X/operators/maintenance/index.md",25023],"3bf1ce3c":[()=>n.e(2349).then(n.bind(n,86344)),"@site/docs/developers/cli/transfers/verify-transfer.md",86344],"3ce1a06b":[()=>n.e(7816).then(n.bind(n,70151)),"@site/versioned_docs/version-1.5.X/developers/dapps/speculative-exec.md",70151],"3d90f760":[()=>n.e(186).then(n.bind(n,94150)),"@site/versioned_docs/version-1.5.X/disclaimer.md",94150],"3e796ac9":[()=>n.e(5680).then(n.bind(n,98619)),"@site/docs/concepts/addressable-entity.md",98619],"3efe71e8":[()=>n.e(7559).then(n.bind(n,63768)),"@site/docs/concepts/glossary/L.md",63768],"3fe76c6c":[()=>n.e(9672).then(n.bind(n,19259)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/walkthrough.md",19259],40078125:[()=>n.e(6194).then(n.bind(n,69403)),"@site/versioned_docs/version-1.5.X/operators/setup-network/chain-spec.md",69403],"40c07125":[()=>n.e(3485).then(n.bind(n,40232)),"@site/versioned_docs/version-1.5.X/concepts/accounts-and-keys.md",40232],"41905acb":[()=>n.e(3920).then(n.bind(n,88694)),"@site/versioned_docs/version-1.5.X/users/csprlive/token-transfer.md",88694],"41e7d56e":[()=>n.e(4932).then(n.bind(n,40529)),"@site/docs/concepts/glossary/K.md",40529],"41eb5a6a":[()=>n.e(5650).then(n.bind(n,78593)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/commands.md",78593],"43a834ef":[()=>n.e(1991).then(n.bind(n,48596)),"@site/versioned_docs/version-1.5.X/resources/moving-to-casper.md",48596],"43fd3112":[()=>n.e(4191).then(n.bind(n,41699)),"@site/versioned_docs/version-1.5.X/concepts/glossary/E.md",41699],"4423d65b":[()=>n.e(7201).then(n.bind(n,15944)),"@site/versioned_docs/version-1.5.X/concepts/glossary/H.md",15944],"449bc0d9":[()=>n.e(2686).then(n.bind(n,34406)),"@site/docs/users/index.md",34406],"452e65d7":[()=>n.e(9109).then(n.bind(n,30383)),"@site/docs/developers/cli/opcode-costs.md",30383],"4545390c":[()=>n.e(2720).then(n.bind(n,20688)),"@site/docs/concepts/glossary/T.md",20688],"459c4db6":[()=>n.e(5338).then(n.bind(n,11878)),"@site/docs/developers/cli/execution-error-codes.md",11878],"46c04ff3":[()=>n.e(3919).then(n.bind(n,55737)),"@site/docs/resources/advanced/cross-contract.md",55737],"46e94768":[()=>n.e(2646).then(n.bind(n,25120)),"@site/docs/developers/cli/index.md",25120],"471ca6e4":[()=>n.e(7174).then(n.bind(n,78139)),"@site/docs/concepts/economics/staking.md",78139],"4804492c":[()=>n.e(7375).then(n.bind(n,43894)),"@site/versioned_docs/version-1.5.X/concepts/glossary/J.md",43894],"480fa8f7":[()=>n.e(7903).then(n.bind(n,69029)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/minimal-compliance.md",69029],"481163ce":[()=>n.e(3552).then(n.t.bind(n,22999,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-new-docs-5aa.json",22999],"4832c6fe":[()=>n.e(9408).then(n.bind(n,50929)),"@site/versioned_docs/version-1.5.X/users/ledger/staking-ledger.md",50929],"4ab63648":[()=>n.e(1973).then(n.bind(n,87630)),"@site/versioned_docs/version-1.5.X/concepts/glossary/R.md",87630],"4ba3ceff":[()=>n.e(9457).then(n.bind(n,36921)),"@site/docs/resources/beginner/getting-started-tutorial.md",36921],"4c91363f":[()=>n.e(4374).then(n.bind(n,92383)),"@site/docs/resources/tokens/cep78/reverse-lookup.md",92383],"4cc75cd6":[()=>n.e(3580).then(n.bind(n,98924)),"@site/versioned_docs/version-1.5.X/developers/cli/querying-global-state.md",98924],"4d118a4e":[()=>n.e(8621).then(n.bind(n,33041)),"@site/docs/developers/cli/delegate.md",33041],"4db682c6":[()=>n.e(3766).then(n.bind(n,86243)),"@site/docs/concepts/callstack.md",86243],"4e015808":[()=>n.e(5712).then(n.bind(n,90710)),"@site/versioned_docs/version-1.5.X/resources/quick-start.md",90710],"4e4df367":[()=>n.e(1894).then(n.bind(n,74299)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/recovering.md",74299],"4e8b7bcc":[()=>n.e(3469).then(n.bind(n,28010)),"@site/versioned_docs/version-1.5.X/concepts/glossary/F.md",28010],"4fdb6df3":[()=>n.e(5844).then(n.bind(n,15366)),"@site/docs/concepts/glossary/N.md",15366],"5052751d":[()=>n.e(6590).then(n.bind(n,9184)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/bonding.md",9184],"5109d3ad":[()=>n.e(6224).then(n.bind(n,1222)),"@site/versioned_docs/version-1.5.X/operators/setup-network/create-private.md",1222],"51719dea":[()=>n.e(6444).then(n.bind(n,9431)),"@site/docs/developers/dapps/dapp.md",9431],"51ce653c":[()=>n.e(2072).then(n.bind(n,18801)),"@site/docs/developers/writing-onchain-code/index.md",18801],"521a6610":[()=>n.e(3027).then(n.bind(n,38764)),"@site/versioned_docs/version-1.5.X/developers/cli/index.md",38764],"52fa5650":[()=>n.e(2275).then(n.bind(n,64954)),"@site/versioned_docs/version-1.5.X/concepts/glossary/V.md",64954],"533ebf6b":[()=>n.e(3931).then(n.bind(n,56193)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs.md",56193],"5364a150":[()=>n.e(2152).then(n.bind(n,31487)),"@site/versioned_docs/version-1.5.X/developers/dapps/signing-a-deploy.md",31487],"53d095ec":[()=>n.e(8425).then(n.bind(n,91722)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-vs-session.md",91722],"546b5549":[()=>n.e(1651).then(n.bind(n,76419)),"@site/docs/resources/beginner/cep18.md",76419],"5497691c":[()=>n.e(4035).then(n.bind(n,48025)),"@site/docs/developers/writing-onchain-code/getting-started.md",48025],55568807:[()=>n.e(7543).then(n.bind(n,71870)),"@site/versioned_docs/version-1.5.X/developers/essential-crates.md",71870],"555a4473":[()=>n.e(9861).then(n.bind(n,45493)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/getting-started.md",45493],"560adf9d":[()=>n.e(1574).then(n.bind(n,41711)),"@site/docs/resources/beginner/counter/commands.md",41711],"56746dcb":[()=>n.e(690).then(n.bind(n,29010)),"@site/versioned_docs/version-1.5.X/concepts/economics/runtime.md",29010],"56ad65de":[()=>n.e(3471).then(n.bind(n,98132)),"@site/docs/concepts/serialization/structures.md",98132],"57f923a9":[()=>n.e(3627).then(n.bind(n,46896)),"@site/versioned_docs/version-1.5.X/resources/beginner/aws-node.md",46896],"58092c27":[()=>n.e(2697).then(n.bind(n,81832)),"@site/docs/concepts/smart-contracts.md",81832],58718032:[()=>n.e(2071).then(n.bind(n,63785)),"@site/versioned_docs/version-1.5.X/concepts/glossary/G.md",63785],"5979a0ec":[()=>n.e(3226).then(n.bind(n,5513)),"@site/docs/users/ledger/ledger-cspr-live.md",5513],"5a22b142":[()=>n.e(9940).then(n.bind(n,47609)),"@site/docs/users/csprlive/delegate-ui.md",47609],"5a3b84ba":[()=>n.e(5409).then(n.bind(n,47398)),"@site/docs/developers/json-rpc/index.md",47398],"5b827590":[()=>n.e(7371).then(n.bind(n,33143)),"@site/versioned_docs/version-1.5.X/users/block-explorer.md",33143],"5c07109c":[()=>n.e(8183).then(n.bind(n,70843)),"@site/versioned_docs/version-1.5.X/operators/setup/basic-node-configuration.md",70843],"5c3f78ae":[()=>n.e(871).then(n.bind(n,39911)),"@site/versioned_docs/version-1.5.X/developers/dapps/template-frontend.md",39911],"5ce0f216":[()=>n.e(2321).then(n.t.bind(n,36433,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-features-efe.json",36433],"5cf40dea":[()=>n.e(7927).then(n.bind(n,47994)),"@site/docs/concepts/intro-to-dapps.md",47994],"5d4e9672":[()=>n.e(5059).then(n.bind(n,41788)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/introduction.md",41788],"5e9306ee":[()=>n.e(9029).then(n.bind(n,70580)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/verify-transfer.md",70580],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5ed91ab5":[()=>n.e(3337).then(n.bind(n,65483)),"@site/docs/concepts/glossary/I.md",65483],"5f02ec4e":[()=>n.e(7753).then(n.bind(n,4879)),"@site/docs/operators/index.md",4879],"603aca9e":[()=>n.e(2059).then(n.bind(n,2839)),"@site/versioned_docs/version-1.5.X/concepts/glossary/A.md",2839],"6043c3f4":[()=>n.e(6046).then(n.bind(n,38513)),"@site/versioned_docs/version-1.5.X/resources/advanced/storage-workflow.md",38513],"60d3a705":[()=>n.e(3979).then(n.bind(n,57921)),"@site/docs/developers/json-rpc/types_chain.md",57921],"60fa9972":[()=>n.e(6215).then(n.bind(n,44881)),"@site/versioned_docs/version-1.5.X/resources/advanced/list-cspr.md",44881],"6193b30e":[()=>n.e(6232).then(n.bind(n,52850)),"@site/docs/resources/tokens/cep18/quickstart-guide.md",52850],"621db11d":[()=>Promise.all([n.e(1869),n.e(3347),n.e(4212)]).then(n.bind(n,13250)),"@theme/Blog/Pages/BlogAuthorsListPage",13250],"6245c126":[()=>n.e(6342).then(n.bind(n,85916)),"@site/versioned_docs/version-1.5.X/concepts/glossary/T.md",85916],"6318ac72":[()=>n.e(9238).then(n.bind(n,34198)),"@site/docs/concepts/design/rewards.md",34198],"63925da8":[()=>n.e(6871).then(n.bind(n,93061)),"@site/docs/developers/index.md",93061],"63d4ce07":[()=>n.e(1261).then(n.bind(n,64740)),"@site/docs/developers/cli/redelegate.md",64740],"6474e148":[()=>n.e(9126).then(n.bind(n,79375)),"@site/versioned_docs/version-1.5.X/concepts/glossary/I.md",79375],"64899cf9":[()=>n.e(6087).then(n.bind(n,97329)),"@site/docs/concepts/serialization/types.md",97329],"64959b1e":[()=>n.e(7796).then(n.bind(n,16527)),"@site/docs/concepts/design/casper-design.md",16527],"64c09e2e":[()=>n.e(3697).then(n.bind(n,73571)),"@site/docs/operators/maintenance/index.md",73571],"650a8fc0":[()=>n.e(3894).then(n.bind(n,86943)),"@site/docs/concepts/glossary/M.md",86943],"6520db96":[()=>n.e(9025).then(n.bind(n,15820)),"@site/docs/developers/writing-onchain-code/factory-pattern.md",15820],"65961da4":[()=>n.e(4889).then(n.bind(n,1051)),"@site/docs/concepts/design/networking-protocol.md",1051],"65a9ed9e":[()=>n.e(5731).then(n.bind(n,92439)),"@site/docs/concepts/glossary/U.md",92439],"65cd111b":[()=>n.e(910).then(n.bind(n,1879)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-contracts.md",1879],"680b7fa9":[()=>n.e(2446).then(n.bind(n,22210)),"@site/docs/developers/essential-crates.md",22210],"6875c492":[()=>Promise.all([n.e(1869),n.e(1494),n.e(3347),n.e(4813)]).then(n.bind(n,33069)),"@theme/BlogTagsPostsPage",33069],"68ccb7f6":[()=>n.e(6474).then(n.bind(n,88599)),"@site/docs/operators/setup/open-files.md",88599],"6a307077":[()=>n.e(4110).then(n.bind(n,88261)),"@site/docs/developers/json-rpc/types_cl.md",88261],"6c606038":[()=>n.e(8471).then(n.bind(n,87251)),"@site/docs/concepts/glossary/A.md",87251],"6dcb5e16":[()=>n.e(4005).then(n.bind(n,14062)),"@site/docs/concepts/economics/fee-elimination.md",14062],"6e2737c0":[()=>n.e(6958).then(n.bind(n,16484)),"@site/docs/developers/writing-onchain-code/contract-hash-vs-package-hash.md",16484],"6e34a484":[()=>n.e(4814).then(n.bind(n,64930)),"@site/docs/developers/cli/sending-transactions.md",64930],"6fe126b9":[()=>n.e(8950).then(n.bind(n,82244)),"@site/versioned_docs/version-1.5.X/concepts/glossary/L.md",82244],"705e93ef":[()=>n.e(8729).then(n.bind(n,52314)),"@site/versioned_docs/version-1.5.X/developers/dapps/index.md",52314],"709dfa47":[()=>n.e(3297).then(n.bind(n,34238)),"@site/versioned_docs/version-1.5.X/resources/build-on-casper.md",34238],"727f767d":[()=>n.e(5833).then(n.bind(n,70827)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/calling-contracts.md",70827],"72a89de8":[()=>n.e(5687).then(n.bind(n,65693)),"@site/versioned_docs/version-1.5.X/users/csprlive/delegate-ui.md",65693],"72b43be8":[()=>n.e(6770).then(n.bind(n,68966)),"@site/versioned_docs/version-1.5.X/resources/beginner/index.md",68966],"72c6e609":[()=>n.e(2107).then(n.bind(n,56341)),"@site/versioned_docs/version-1.5.X/operators/setup/upgrade.md",56341],"72cc2261":[()=>n.e(3793).then(n.bind(n,7753)),"@site/versioned_docs/version-1.5.X/resources/beginner/upgrade-contract.md",7753],"738a6ad4":[()=>n.e(8727).then(n.bind(n,78009)),"@site/versioned_docs/version-1.5.X/operators/setup/joining.md",78009],"74d57d33":[()=>n.e(200).then(n.bind(n,92827)),"@site/docs/users/funding-from-exchanges.md",92827],"753d7b98":[()=>n.e(1790).then(n.bind(n,440)),"@site/docs/developers/json-rpc/json-rpc-transactional.md",440],"75de5623":[()=>n.e(2670).then(n.bind(n,82799)),"@site/versioned_docs/version-1.5.X/users/funding-from-exchanges.md",82799],"7607f1d5":[()=>n.e(793).then(n.bind(n,27843)),"@site/docs/developers/dapps/template-frontend.md",27843],"76a75fbd":[()=>n.e(7667).then(n.bind(n,34868)),"@site/docs/users/csprlive/undelegate-ui.md",34868],"7708241d":[()=>n.e(8728).then(n.bind(n,62157)),"@site/docs/resources/beginner/upgrade-contract.md",62157],"772d3db3":[()=>n.e(4491).then(n.bind(n,95631)),"@site/versioned_docs/version-1.5.X/operators/setup-network/staging-files-for-new-network.md",95631],"77981a3a":[()=>n.e(7440).then(n.bind(n,46453)),"@site/versioned_docs/version-1.5.X/resources/beginner/getting-started-tutorial.md",46453],"78c66fad":[()=>n.e(9902).then(n.bind(n,4690)),"@site/docs/operators/becoming-a-validator/inactive-vs-faulty.md",4690],"79474bae":[()=>n.e(5296).then(n.bind(n,60507)),"@site/versioned_docs/version-1.5.X/operators/setup/non-root-user.md",60507],"79d896a3":[()=>n.e(8426).then(n.bind(n,70525)),"@site/docs/concepts/economics/gas-concepts.md",70525],"7ade0b2a":[()=>n.e(6163).then(n.bind(n,13868)),"@site/versioned_docs/version-1.5.X/concepts/glossary/D.md",13868],"7b1c3c68":[()=>n.e(8652).then(n.bind(n,42903)),"@site/docs/developers/json-rpc/json-rpc-pos.md",42903],"7b8da7d8":[()=>n.e(3e3).then(n.bind(n,6188)),"@site/docs/resources/beginner/aws-node.md",6188],"7c67ea25":[()=>n.e(7937).then(n.bind(n,62301)),"@site/versioned_docs/version-1.5.X/developers/cli/installing-contracts.md",62301],"7c798d59":[()=>n.e(1535).then(n.bind(n,51753)),"@site/docs/developers/cli/transfers/multisig-deploy-transfer.md",51753],"7ce4a62a":[()=>n.e(6568).then(n.bind(n,83277)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/assembly-script.md",83277],"7cf62e8d":[()=>n.e(566).then(n.bind(n,54814)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/guidance.md",54814],"7cff47a5":[()=>n.e(8916).then(n.bind(n,93507)),"@site/docs/developers/dapps/speculative-exec.md",93507],"7e55f6e6":[()=>n.e(2028).then(n.bind(n,60588)),"@site/versioned_docs/version-1.5.X/concepts/smart-contracts.md",60588],"7effaf45":[()=>n.e(5087).then(n.bind(n,58347)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/concepts.md",58347],"7f115b1f":[()=>n.e(4358).then(n.bind(n,59460)),"@site/docs/developers/writing-onchain-code/testing-session-code.md",59460],"80e6044e":[()=>n.e(7915).then(n.bind(n,25377)),"@site/blog/2024-07-16-fee-elimination.md?truncated=true",25377],"814f3328":[()=>n.e(7472).then(n.t.bind(n,55513,19)),"~blog/default/blog-post-list-prop-default.json",55513],"821dc1e3":[()=>n.e(898).then(n.bind(n,56752)),"@site/versioned_docs/version-1.5.X/resources/advanced/transfer-token-to-contract.md",56752],"830e9e14":[()=>n.e(5732).then(n.bind(n,17703)),"@site/docs/operators/setup/node-events.md",17703],"8323e0f5":[()=>n.e(9749).then(n.bind(n,30491)),"@site/docs/resources/beginner/querying-network.md",30491],"85b8bb26":[()=>n.e(5096).then(n.bind(n,29387)),"@site/docs/concepts/dictionaries.md",29387],"861e5e13":[()=>n.e(7837).then(n.bind(n,32858)),"@site/docs/resources/build-on-casper.md",32858],"870de909":[()=>n.e(6755).then(n.bind(n,91820)),"@site/docs/users/delegating.md",91820],"87f5bee7":[()=>n.e(3144).then(n.bind(n,58116)),"@site/docs/concepts/glossary/X.md",58116],"883310e5":[()=>n.e(3048).then(n.bind(n,57558)),"@site/versioned_docs/version-1.5.X/concepts/design/reading-and-writing-to-the-blockchain.md",57558],"8833ab21":[()=>n.e(8875).then(n.t.bind(n,66079,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-alexanderlimonov-e61.json",66079],"8941358f":[()=>n.e(5469).then(n.bind(n,33366)),"@site/blog/2024-08-20-validator-rewards.md?truncated=true",33366],"897e9cb3":[()=>n.e(2035).then(n.bind(n,1368)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs.md",1368],"89c22482":[()=>n.e(3781).then(n.bind(n,40611)),"@site/docs/users/block-explorer.md",40611],"89d896be":[()=>n.e(3852).then(n.bind(n,18069)),"@site/docs/resources/tokens/cep18/transfer.md",18069],"8c0ead1f":[()=>n.e(6091).then(n.bind(n,63543)),"@site/docs/developers/dapps/sdk/script-sdk.md",63543],"8d265689":[()=>n.e(5631).then(n.bind(n,68814)),"@site/versioned_docs/version-1.5.X/operators/setup-network/index.md",68814],"8d81394c":[()=>n.e(9529).then(n.bind(n,42706)),"@site/docs/resources/beginner/index.md",42706],"8de9f24f":[()=>n.e(699).then(n.t.bind(n,56922,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-validators-6b7.json",56922],"8e1fd569":[()=>n.e(4097).then(n.bind(n,85936)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/direct-token-transfer.md",85936],"8f27be43":[()=>n.e(6088).then(n.bind(n,18277)),"@site/docs/resources/beginner/counter-testnet/walkthrough.md",18277],"8ff31131":[()=>n.e(6346).then(n.bind(n,9414)),"@site/docs/developers/cli/calling-contracts.md",9414],"90efbb16":[()=>n.e(8132).then(n.bind(n,31352)),"@site/versioned_docs/version-1.5.X/concepts/design/p2p.md",31352],"9116852a":[()=>n.e(2418).then(n.bind(n,38646)),"@site/docs/resources/beginner/counter/overview.md",38646],"915d90e1":[()=>n.e(2455).then(n.bind(n,67689)),"@site/docs/operators/becoming-a-validator/change-bid-public-key.md",67689],"931ecaed":[()=>n.e(558).then(n.bind(n,99247)),"@site/versioned_docs/version-1.5.X/concepts/deploy-and-deploy-lifecycle.md",99247],"94f643bb":[()=>n.e(7024).then(n.bind(n,40867)),"@site/docs/concepts/glossary/Q.md",40867],"977c8faa":[()=>n.e(6221).then(n.bind(n,63116)),"@site/docs/concepts/design/p2p.md",63116],"98df448b":[()=>n.e(7772).then(n.bind(n,24120)),"@site/blog/2024-08-15-hello-blogworld.md?truncated=true",24120],"99a13742":[()=>n.e(9895).then(n.bind(n,58591)),"@site/docs/operators/setup/basic-node-configuration.md",58591],"9acc619b":[()=>n.e(5465).then(n.bind(n,31662)),"@site/versioned_docs/version-1.5.X/operators/maintenance/archiving-and-restoring.md",31662],"9afe1d3d":[()=>n.e(240).then(n.bind(n,63131)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/index.md",63131],"9b0d9b67":[()=>n.e(9078).then(n.bind(n,10158)),"@site/versioned_docs/version-1.5.X/users/ledger/index.md",10158],"9c5b6467":[()=>n.e(3265).then(n.bind(n,72675)),"@site/docs/operators/becoming-a-validator/index.md",72675],"9c6aa8d2":[()=>n.e(2381).then(n.bind(n,55711)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Y.md",55711],"9c780b1a":[()=>n.e(7438).then(n.bind(n,20621)),"@site/docs/developers/dapps/sdk/index.md",20621],"9cd0819b":[()=>n.e(247).then(n.bind(n,92367)),"@site/docs/operators/becoming-a-validator/recovering.md",92367],"9d275d72":[()=>n.e(3829).then(n.bind(n,42877)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/index.md",42877],"9e4087bc":[()=>n.e(2711).then(n.bind(n,89331)),"@theme/BlogArchivePage",89331],"9ec4e3de":[()=>n.e(1865).then(n.t.bind(n,40848,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-docs-redux-08d.json",40848],"9ed00072":[()=>n.e(642).then(n.bind(n,29274)),"@site/docs/users/csprlive/token-transfer.md",29274],"9ee7887a":[()=>n.e(2473).then(n.bind(n,80156)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/index.md",80156],a03c4947:[()=>n.e(1368).then(n.bind(n,24311)),"@site/versioned_docs/version-1.5.X/concepts/dictionaries.md",24311],a0ccdbb2:[()=>n.e(9460).then(n.bind(n,72407)),"@site/docs/operators/setup-network/chain-spec.md",72407],a1868598:[()=>n.e(6265).then(n.bind(n,41214)),"@site/docs/developers/dapps/index.md",41214],a2874f18:[()=>n.e(6512).then(n.bind(n,71968)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash.md",71968],a30e2bb0:[()=>n.e(5496).then(n.bind(n,38440)),"@site/docs/concepts/economics/dynamic-gas-pricing.md",38440],a35afcc3:[()=>n.e(398).then(n.bind(n,15739)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial.md",15739],a3dc4ae2:[()=>n.e(3100).then(n.bind(n,43322)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/go-sdk.md",43322],a4046515:[()=>n.e(453).then(n.bind(n,48724)),"@site/versioned_docs/version-1.5.X/concepts/global-state.md",48724],a40a2cf8:[()=>n.e(5458).then(n.bind(n,21814)),"@site/versioned_docs/version-1.5.X/operators/setup/node-endpoints.md",21814],a434b528:[()=>n.e(884).then(n.bind(n,77875)),"@site/versioned_docs/version-1.5.X/developers/cli/sending-deploys.md",77875],a4ae8417:[()=>n.e(9314).then(n.bind(n,40347)),"@site/docs/developers/dapps/setup-nctl.md",40347],a4b0daeb:[()=>n.e(4686).then(n.bind(n,36539)),"@site/versioned_docs/version-1.5.X/concepts/glossary/M.md",36539],a4cd78b5:[()=>n.e(7403).then(n.bind(n,37340)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/overview.md",37340],a4f8fe7e:[()=>n.e(7205).then(n.bind(n,34777)),"@site/docs/concepts/economics/consensus.md",34777],a53bd891:[()=>n.e(5664).then(n.bind(n,47150)),"@site/docs/concepts/glossary/F.md",47150],a55b9639:[()=>n.e(6453).then(n.bind(n,46557)),"@site/docs/resources/advanced/list-cspr.md",46557],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(1494),n.e(3347),n.e(7643)]).then(n.bind(n,35124)),"@theme/BlogListPage",35124],a6efe0e1:[()=>n.e(4766).then(n.bind(n,62409)),"@site/versioned_docs/version-1.5.X/users/csprlive/index.md",62409],a72bcf22:[()=>n.e(3828).then(n.t.bind(n,21980,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-setup-b32.json",21980],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,74532)),"@theme/DocVersionRoot",74532],a80f26d4:[()=>n.e(2218).then(n.bind(n,54801)),"@site/versioned_docs/version-1.5.X/concepts/economics/gas-concepts.md",54801],a811e42c:[()=>n.e(1408).then(n.bind(n,97681)),"@site/docs/resources/tokens/cep18/tests.md",97681],a81b7004:[()=>n.e(6044).then(n.bind(n,14086)),"@site/docs/developers/writing-onchain-code/contract-vs-session.md",14086],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,11377)),"@theme/DocRoot",11377],a9deb425:[()=>n.e(5157).then(n.bind(n,25943)),"@site/docs/developers/dapps/technology-stack.md",25943],a9f5564d:[()=>n.e(9235).then(n.bind(n,66428)),"@site/docs/operators/setup-network/genesis.md",66428],aa162190:[()=>n.e(1512).then(n.bind(n,93573)),"@site/docs/concepts/glossary/O.md",93573],aafbba97:[()=>n.e(2986).then(n.bind(n,40261)),"@site/docs/users/csprlive/index.md",40261],ab246697:[()=>n.e(9756).then(n.bind(n,884)),"@site/docs/concepts/glossary/H.md",884],ab991e0e:[()=>n.e(56).then(n.bind(n,71353)),"@site/docs/resources/beginner/counter/index.md",71353],aba21aa0:[()=>n.e(5742).then(n.t.bind(n,27093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",27093],abd56c27:[()=>n.e(7267).then(n.bind(n,5804)),"@site/versioned_docs/version-1.5.X/resources/advanced/return-values-tutorial.md",5804],ac361b55:[()=>n.e(3019).then(n.bind(n,70)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-informational.md",70],acecf23e:[()=>n.e(1903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],ad0b296a:[()=>n.e(5378).then(n.bind(n,64336)),"@site/docs/resources/tokens/cep18/query.md",64336],ad15c07f:[()=>n.e(9044).then(n.bind(n,84798)),"@site/docs/concepts/economics/index.md",84798],ad727d36:[()=>n.e(4457).then(n.bind(n,88030)),"@site/docs/concepts/glossary/V.md",88030],ad7eda35:[()=>n.e(5721).then(n.bind(n,47501)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_chain.md",47501],ae470ddc:[()=>n.e(1089).then(n.bind(n,5029)),"@site/docs/users/ledger/staking-ledger.md",5029],aee0fe92:[()=>n.e(7832).then(n.bind(n,32330)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/index.md",32330],aefd42fa:[()=>n.e(1418).then(n.bind(n,90171)),"@site/versioned_docs/version-1.5.X/operators/setup/open-files.md",90171],af050a36:[()=>n.e(9293).then(n.bind(n,87614)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/js-tutorial.md",87614],af1112c6:[()=>n.e(5210).then(n.bind(n,55679)),"@site/versioned_docs/version-1.5.X/developers/dapps/setup-nctl.md",55679],afa6d836:[()=>n.e(6724).then(n.bind(n,96186)),"@site/docs/concepts/glossary/B.md",96186],b15d29cb:[()=>n.e(1767).then(n.bind(n,96409)),"@site/docs/concepts/glossary/C.md",96409],b1eae65b:[()=>n.e(9218).then(n.bind(n,56358)),"@site/blog/2024-07-17-addressable-entity.md?truncated=true",56358],b36f50d3:[()=>n.e(3990).then(n.bind(n,29337)),"@site/docs/operators/setup/index.md",29337],b3a49b92:[()=>n.e(9113).then(n.bind(n,48258)),"@site/docs/concepts/glossary/Z.md",48258],b3b8c5cb:[()=>n.e(9687).then(n.bind(n,72781)),"@site/versioned_docs/version-1.5.X/concepts/glossary/S.md",72781],b46ec474:[()=>n.e(2958).then(n.bind(n,2945)),"@site/docs/operators/setup/upgrade.md",2945],b67f60dc:[()=>n.e(1801).then(n.bind(n,36889)),"@site/versioned_docs/version-1.5.X/concepts/glossary/W.md",36889],b687a817:[()=>n.e(1627).then(n.bind(n,13663)),"@site/versioned_docs/version-1.5.X/concepts/design/networking-protocol.md",13663],b71ecf14:[()=>n.e(6736).then(n.bind(n,70255)),"@site/blog/2024-07-16-setting-up-condor-local.md?truncated=true",70255],b7708f1e:[()=>n.e(6167).then(n.bind(n,69094)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/client-library-usage.md",69094],b8c8445c:[()=>n.e(4336).then(n.bind(n,674)),"@site/docs/concepts/about.md",674],ba0fa3fe:[()=>n.e(4225).then(n.bind(n,64287)),"@site/docs/resources/advanced/list-auth-keys-tutorial.md",64287],baabe181:[()=>n.e(2510).then(n.t.bind(n,37324,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-melpadden-a93.json",37324],baf71301:[()=>n.e(2996).then(n.bind(n,28646)),"@site/versioned_docs/version-1.5.X/concepts/about.md",28646],bafead24:[()=>n.e(286).then(n.bind(n,70269)),"@site/versioned_docs/version-1.5.X/concepts/glossary/C.md",70269],bb037852:[()=>n.e(4096).then(n.bind(n,90282)),"@site/docs/concepts/design/reading-and-writing-to-the-blockchain.md",90282],bb9db0dd:[()=>n.e(4198).then(n.bind(n,72876)),"@site/versioned_docs/version-1.5.X/developers/dapps/nctl-test.md",72876],bc4bfdf0:[()=>n.e(6476).then(n.bind(n,82008)),"@site/versioned_docs/version-1.5.X/concepts/glossary/X.md",82008],bd7d26b2:[()=>n.e(3708).then(n.bind(n,2509)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/unbonding.md",2509],be0df356:[()=>n.e(2048).then(n.bind(n,97636)),"@site/docs/operators/becoming-a-validator/bonding.md",97636],be5e85f4:[()=>n.e(4325).then(n.bind(n,52133)),"@site/docs/resources/quick-start.md",52133],befad559:[()=>n.e(1968).then(n.bind(n,16247)),"@site/versioned_docs/version-1.5.X/concepts/index.md",16247],bf5bbaf8:[()=>n.e(6607).then(n.bind(n,19903)),"@site/docs/resources/beginner/counter-testnet/index.md",19903],bfb3244a:[()=>n.e(8445).then(n.bind(n,14966)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/python-sdk.md",14966],c0299000:[()=>n.e(5890).then(n.bind(n,8077)),"@site/docs/developers/dapps/monitor-and-consume-events.md",8077],c10b8a9f:[()=>n.e(781).then(n.bind(n,58107)),"@site/versioned_docs/version-1.5.X/users/csprlive/testnet-faucet.md",58107],c10cfbfe:[()=>n.e(8455).then(n.bind(n,40260)),"@site/docs/concepts/accounts-and-keys.md",40260],c141421f:[()=>n.e(957).then(n.t.bind(n,40936,19)),"@generated/docusaurus-theme-search-algolia/default/__plugin.json",40936],c19e69a7:[()=>n.e(6962).then(n.bind(n,75574)),"@site/docs/developers/cli/undelegate.md",75574],c2728190:[()=>n.e(6121).then(n.bind(n,31011)),"@site/docs/concepts/index.md",31011],c2a48fdb:[()=>n.e(6623).then(n.bind(n,30919)),"@site/docs/operators/setup/fast-sync.md",30919],c3308ba6:[()=>n.e(6547).then(n.t.bind(n,5571,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-condor-e10.json",5571],c377dc4a:[()=>n.e(4425).then(n.bind(n,48188)),"@site/blog/2024-08-15-hello-blogworld.md",48188],c37f176d:[()=>n.e(9596).then(n.bind(n,6910)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/quickstart-guide.md",6910],c380abc4:[()=>n.e(2910).then(n.bind(n,72028)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/writing-session-code.md",72028],c4561df8:[()=>n.e(4846).then(n.bind(n,72353)),"@site/versioned_docs/version-1.5.X/concepts/glossary/O.md",72353],c52eaa26:[()=>n.e(6938).then(n.bind(n,83106)),"@site/docs/operators/setup-network/create-private.md",83106],c691959f:[()=>n.e(6233).then(n.bind(n,37819)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/commands.md",37819],c74094f8:[()=>n.e(2512).then(n.bind(n,89738)),"@site/versioned_docs/version-1.5.X/concepts/design/index.md",89738],c7d46fe1:[()=>n.e(7935).then(n.bind(n,94085)),"@site/docs/operators/setup/hardware.md",94085],c8e4da00:[()=>n.e(5808).then(n.bind(n,43185)),"@site/versioned_docs/version-1.5.X/developers/index.md",43185],c9d52fc5:[()=>n.e(9210).then(n.bind(n,53385)),"@site/docs/concepts/glossary/S.md",53385],c9db186d:[()=>n.e(6988).then(n.bind(n,59151)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/index.md",59151],c9f0fdac:[()=>n.e(5727).then(n.bind(n,59897)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/index.md",59897],ca0e408e:[()=>n.e(8431).then(n.t.bind(n,43136,19)),"@generated/docusaurus-plugin-content-docs/default/p/next-09d.json",43136],ca7245df:[()=>n.e(7419).then(n.bind(n,76032)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/best-practices.md",76032],cb63487a:[()=>n.e(9081).then(n.bind(n,68736)),"@site/docs/developers/cli/querying-global-state.md",68736],cbe09f13:[()=>n.e(4894).then(n.bind(n,14516)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/query.md",14516],cbe8101d:[()=>n.e(8723).then(n.bind(n,18901)),"@site/docs/operators/setup/joining.md",18901],cc2e94c0:[()=>n.e(5364).then(n.bind(n,86447)),"@site/docs/developers/dapps/uref-security.md",86447],ccc49370:[()=>Promise.all([n.e(1869),n.e(1494),n.e(3347),n.e(3249)]).then(n.bind(n,73858)),"@theme/BlogPostPage",73858],cd948886:[()=>n.e(8979).then(n.bind(n,35811)),"@site/docs/resources/index.md",35811],ce0e1dbb:[()=>n.e(3025).then(n.bind(n,37733)),"@site/versioned_docs/version-1.5.X/concepts/design/highway.md",37733],ce3d5a4b:[()=>n.e(6986).then(n.bind(n,33853)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-cspr-live.md",33853],ce6605d8:[()=>n.e(2270).then(n.bind(n,41693)),"@site/docs/developers/cli/verifying-contracts.md",41693],cf35294f:[()=>n.e(3341).then(n.bind(n,72282)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs.md",72282],d050b476:[()=>n.e(8889).then(n.bind(n,97651)),"@site/versioned_docs/version-1.5.X/concepts/glossary/U.md",97651],d06ee05c:[()=>n.e(1451).then(n.bind(n,48340)),"@site/docs/resources/advanced/transfer-token-to-contract.md",48340],d0a8493b:[()=>n.e(1926).then(n.bind(n,45341)),"@site/docs/resources/changelog.md",45341],d13dc577:[()=>n.e(2677).then(n.bind(n,41026)),"@site/versioned_docs/version-1.5.X/users/index.md",41026],d2039ef8:[()=>n.e(5354).then(n.bind(n,15377)),"@site/versioned_docs/version-1.5.X/concepts/serialization-standard.md",15377],d220dcab:[()=>n.e(4941).then(n.bind(n,85135)),"@site/versioned_docs/version-1.5.X/resources/beginner/querying-network.md",85135],d279fdce:[()=>n.e(5559).then(n.bind(n,67352)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-session-code.md",67352],d3ef4614:[()=>n.e(8548).then(n.bind(n,27321)),"@site/versioned_docs/version-1.5.X/operators/setup/hardware.md",27321],d477c291:[()=>n.e(2684).then(n.bind(n,74347)),"@site/versioned_docs/version-1.5.X/developers/dapps/uref-security.md",74347],d48191b6:[()=>n.e(2112).then(n.t.bind(n,3131,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-tokenomics-137.json",3131],d49dddd4:[()=>n.e(6784).then(n.bind(n,8386)),"@site/docs/developers/dapps/sdk/python-sdk.md",8386],d4c529d3:[()=>n.e(6379).then(n.bind(n,72319)),"@site/docs/resources/tokens/cep78/modalities.md",72319],d638c601:[()=>n.e(4858).then(n.bind(n,97218)),"@site/docs/developers/json-rpc/json-rpc-informational.md",97218],d7289626:[()=>n.e(6247).then(n.bind(n,53158)),"@site/docs/concepts/design/index.md",53158],d7f9f727:[()=>n.e(3495).then(n.bind(n,54541)),"@site/docs/concepts/glossary/G.md",54541],d7fae98e:[()=>n.e(7636).then(n.bind(n,70358)),"@site/versioned_docs/version-1.5.X/resources/advanced/index.md",70358],d80df429:[()=>n.e(3846).then(n.bind(n,48130)),"@site/docs/resources/tokens/cep78/js-tutorial.md",48130],d92b4d08:[()=>n.e(3422).then(n.bind(n,66395)),"@site/docs/resources/advanced/multi-sig/multi-sig-workflow.md",66395],d94d6bbe:[()=>n.e(9065).then(n.bind(n,78715)),"@site/versioned_docs/version-1.5.X/operators/setup/fast-sync.md",78715],db24aef0:[()=>n.e(2799).then(n.bind(n,71383)),"@site/docs/operators/setup/non-root-user.md",71383],dbfc4782:[()=>n.e(8749).then(n.t.bind(n,91895,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-archive-61f.json",91895],dc1c4417:[()=>n.e(5580).then(n.bind(n,26937)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/walkthrough.md",26937],dc5e10d3:[()=>n.e(4557).then(n.bind(n,47374)),"@site/docs/concepts/transactions-and-transaction-lifecycle.md",47374],dcb4c613:[()=>n.e(3445).then(n.bind(n,74671)),"@site/docs/users/csprlive/testnet-faucet.md",74671],dd04b75e:[()=>n.e(1672).then(n.t.bind(n,33024,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-8ff.json",33024],dd908370:[()=>n.e(9918).then(n.bind(n,77237)),"@site/versioned_docs/version-1.5.X/operators/setup/index.md",77237],df5bc763:[()=>n.e(4555).then(n.bind(n,23946)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/overview.md",23946],dfbc8a55:[()=>n.e(3307).then(n.bind(n,53301)),"@site/docs/resources/advanced/storage-workflow.md",53301],dfcc4619:[()=>n.e(7083).then(n.bind(n,54972)),"@site/docs/concepts/serialization/index.md",54972],e08eef46:[()=>n.e(9037).then(n.bind(n,57446)),"@site/docs/developers/prerequisites.md",57446],e15566cb:[()=>n.e(9784).then(n.bind(n,63018)),"@site/docs/users/ledger/index.md",63018],e1e5af17:[()=>n.e(202).then(n.bind(n,26628)),"@site/docs/concepts/design/zug.md",26628],e238c115:[()=>n.e(229).then(n.bind(n,18822)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Z.md",18822],e2799c63:[()=>n.e(9303).then(n.bind(n,44946)),"@site/docs/operators/setup/node-endpoints.md",44946],e289ead3:[()=>n.e(7394).then(n.bind(n,46593)),"@site/docs/concepts/design/consensus.md",46593],e2975a84:[()=>n.e(8204).then(n.bind(n,33467)),"@site/versioned_docs/version-1.5.X/developers/dapps/dapp.md",33467],e2f5312b:[()=>n.e(1997).then(n.bind(n,97687)),"@site/versioned_docs/version-1.5.X/resources/condor-for-exchanges.md",97687],e3f9a068:[()=>n.e(1561).then(n.bind(n,86271)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/multi-sig-workflow.md",86271],e45056bc:[()=>n.e(2527).then(n.bind(n,72814)),"@site/docs/developers/dapps/sdk/go-sdk.md",72814],e4d870e1:[()=>n.e(5751).then(n.bind(n,10935)),"@site/versioned_docs/version-1.5.X/resources/beginner/cep18.md",10935],e5493a21:[()=>n.e(8988).then(n.bind(n,90555)),"@site/docs/concepts/glossary/Y.md",90555],e8b40bee:[()=>n.e(5282).then(n.bind(n,80870)),"@site/docs/developers/writing-onchain-code/simple-contract.md",80870],ea0474c4:[()=>n.e(6481).then(n.bind(n,949)),"@site/versioned_docs/version-1.5.X/developers/cli/delegate.md",949],eaba5dd2:[()=>n.e(2067).then(n.bind(n,30229)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/multisig-deploy-transfer.md",30229],eacea541:[()=>n.e(1434).then(n.bind(n,2880)),"@site/docs/concepts/glossary/D.md",2880],eb0d94ae:[()=>n.e(7575).then(n.bind(n,51352)),"@site/versioned_docs/version-1.5.X/concepts/glossary/index.md",51352],eb1cd7f2:[()=>n.e(1969).then(n.bind(n,46250)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/simple-contract.md",46250],eb5a6cc0:[()=>n.e(280).then(n.bind(n,66747)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/reverse-lookup.md",66747],ebb9a3ce:[()=>n.e(1093).then(n.bind(n,75736)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/other-scenarios.md",75736],ed267fba:[()=>n.e(367).then(n.bind(n,61809)),"@site/versioned_docs/version-1.5.X/developers/dapps/prerequisites.md",61809],ee7c1cc7:[()=>n.e(9041).then(n.bind(n,52306)),"@site/versioned_docs/version-1.5.X/concepts/economics/index.md",52306],ee94176e:[()=>n.e(1433).then(n.bind(n,4080)),"@site/docs/resources/advanced/return-values-tutorial.md",4080],ef2abd7e:[()=>n.e(715).then(n.bind(n,798)),"@site/versioned_docs/version-1.5.X/concepts/intro-to-dapps.md",798],ef7672e3:[()=>n.e(7110).then(n.bind(n,63457)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/transfer.md",63457],eff21157:[()=>n.e(9080).then(n.bind(n,33997)),"@site/versioned_docs/version-1.5.X/resources/advanced/two-party-multi-sig.md",33997],f0563fee:[()=>n.e(7865).then(n.bind(n,17606)),"@site/docs/concepts/transactions.md",17606],f070a991:[()=>n.e(5592).then(n.bind(n,26591)),"@site/versioned_docs/version-1.5.X/concepts/list-auth-keys.md",26591],f1245771:[()=>n.e(1630).then(n.t.bind(n,51485,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-dylanireland-62c.json",51485],f1c6b7a3:[()=>n.e(8694).then(n.bind(n,13548)),"@site/docs/developers/cli/transfers/direct-token-transfer.md",13548],f1f89c2e:[()=>n.e(2021).then(n.bind(n,24434)),"@site/versioned_docs/version-1.5.X/developers/cli/calling-contracts.md",24434],f2779c45:[()=>n.e(4192).then(n.bind(n,54770)),"@site/docs/developers/json-rpc/guidance.md",54770],f3bf6984:[()=>n.e(9349).then(n.bind(n,79029)),"@site/docs/developers/dapps/prerequisites.md",79029],f46d6e59:[()=>n.e(2858).then(n.bind(n,57806)),"@site/docs/operators/maintenance/moving-node.md",57806],f71fe95d:[()=>n.e(670).then(n.bind(n,38636)),"@site/versioned_docs/version-1.5.X/resources/casper-open-source-software.md",38636],f776c06c:[()=>n.e(7033).then(n.bind(n,20528)),"@site/docs/resources/casper-open-source-software.md",20528],f88cb658:[()=>n.e(1153).then(n.bind(n,56531)),"@site/docs/operators/setup-network/staging-files-for-new-network.md",56531],f95b1f88:[()=>n.e(7876).then(n.bind(n,70748)),"@site/docs/concepts/serialization/primitives.md",70748],faf2a93e:[()=>n.e(6666).then(n.bind(n,88956)),"@site/docs/users/ledger/ledger-live.md",88956],fb804d1c:[()=>n.e(4939).then(n.bind(n,8060)),"@site/docs/resources/advanced/multi-sig/other-scenarios.md",8060],fd661beb:[()=>n.e(5789).then(n.bind(n,33142)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide.md",33142],fe0242b1:[()=>n.e(1012).then(n.bind(n,67074)),"@site/docs/disclaimer.md",67074],fef6ab33:[()=>n.e(8155).then(n.bind(n,79008)),"@site/versioned_docs/version-1.5.X/operators/setup-network/genesis.md",79008]};var i=n(74848);function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,i.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,i.jsx)("p",{children:String(t)}),(0,i.jsx)("div",{children:(0,i.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,i.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,i.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,i.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,i.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var l=n(86921),d=n(53102);function u(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(2237).then(n.bind(n,82237)),modules:["@theme/NotFound"],webpack:()=>[82237],render(e,t){const n=e.default;return(0,i.jsx)(d.W,{value:{plugin:{name:"native",id:"default"}},children:(0,i.jsx)(n,{...t})})}});const r=s[`${e}-${t}`],u={},p=[],f=[],g=(0,l.A)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=a[n];r&&(u[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:c,loader:u,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const s=r.default;if(!s)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof s&&"function"!=typeof s||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{s[e]=r[e]}));let a=o;const i=n.split(".");i.slice(0,-1).forEach((e=>{a=a[e]})),a[i[i.length-1]]=s}));const s=o.__comp;delete o.__comp;const a=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,i.jsx)(d.W,{value:a,children:(0,i.jsx)(s,{...o,...c,...n})})}})}const p=[{path:"/blog/",component:u("/blog/","834"),exact:!0},{path:"/blog/addressable-entity/",component:u("/blog/addressable-entity/","887"),exact:!0},{path:"/blog/archive/",component:u("/blog/archive/","1d9"),exact:!0},{path:"/blog/authors/",component:u("/blog/authors/","347"),exact:!0},{path:"/blog/authors/alexanderlimonov/",component:u("/blog/authors/alexanderlimonov/","e4c"),exact:!0},{path:"/blog/authors/dylanireland/",component:u("/blog/authors/dylanireland/","a3a"),exact:!0},{path:"/blog/authors/melpadden/",component:u("/blog/authors/melpadden/","0d6"),exact:!0},{path:"/blog/authors/sczembor/",component:u("/blog/authors/sczembor/","8cb"),exact:!0},{path:"/blog/condor-fee-elimination/",component:u("/blog/condor-fee-elimination/","f26"),exact:!0},{path:"/blog/condor-local-setup/",component:u("/blog/condor-local-setup/","2aa"),exact:!0},{path:"/blog/condor-validator-rewards/",component:u("/blog/condor-validator-rewards/","3b7"),exact:!0},{path:"/blog/tags/",component:u("/blog/tags/","e17"),exact:!0},{path:"/blog/tags/condor/",component:u("/blog/tags/condor/","cf9"),exact:!0},{path:"/blog/tags/docs-redux/",component:u("/blog/tags/docs-redux/","339"),exact:!0},{path:"/blog/tags/features/",component:u("/blog/tags/features/","bc2"),exact:!0},{path:"/blog/tags/hello/",component:u("/blog/tags/hello/","8a7"),exact:!0},{path:"/blog/tags/new-docs/",component:u("/blog/tags/new-docs/","fdd"),exact:!0},{path:"/blog/tags/setup/",component:u("/blog/tags/setup/","a7c"),exact:!0},{path:"/blog/tags/tokenomics/",component:u("/blog/tags/tokenomics/","9c1"),exact:!0},{path:"/blog/tags/validators/",component:u("/blog/tags/validators/","87b"),exact:!0},{path:"/blog/welcome-docs-redux/",component:u("/blog/welcome-docs-redux/","fc7"),exact:!0},{path:"/search/",component:u("/search/","21e"),exact:!0},{path:"/",component:u("/","9e1"),routes:[{path:"/next/",component:u("/next/","245"),routes:[{path:"/next/",component:u("/next/","eec"),routes:[{path:"/next/",component:u("/next/","431"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/",component:u("/next/concepts/","0f4"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/accounts-and-keys/",component:u("/next/concepts/accounts-and-keys/","36b"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/addressable-entity/",component:u("/next/concepts/addressable-entity/","61d"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/callstack/",component:u("/next/concepts/callstack/","ef6"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/casper-design/",component:u("/next/concepts/design/casper-design/","0eb"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/consensus/",component:u("/next/concepts/design/consensus/","7be"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/highway/",component:u("/next/concepts/design/highway/","94c"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/networking-protocol/",component:u("/next/concepts/design/networking-protocol/","df6"),exact:!0},{path:"/next/concepts/design/p2p/",component:u("/next/concepts/design/p2p/","256"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/reading-and-writing-to-the-blockchain/",component:u("/next/concepts/design/reading-and-writing-to-the-blockchain/","709"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/rewards/",component:u("/next/concepts/design/rewards/","456"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/design/zug/",component:u("/next/concepts/design/zug/","8ee"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/dictionaries/",component:u("/next/concepts/dictionaries/","24e"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/economics/consensus/",component:u("/next/concepts/economics/consensus/","997"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/economics/dynamic-gas-pricing/",component:u("/next/concepts/economics/dynamic-gas-pricing/","df8"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/economics/fee-elimination/",component:u("/next/concepts/economics/fee-elimination/","3e8"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/economics/gas-concepts/",component:u("/next/concepts/economics/gas-concepts/","0de"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/economics/staking/",component:u("/next/concepts/economics/staking/","ef2"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/global-state/",component:u("/next/concepts/global-state/","0a0"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/A/",component:u("/next/concepts/glossary/A/","999"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/B/",component:u("/next/concepts/glossary/B/","e2a"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/C/",component:u("/next/concepts/glossary/C/","274"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/D/",component:u("/next/concepts/glossary/D/","4b8"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/E/",component:u("/next/concepts/glossary/E/","a2a"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/F/",component:u("/next/concepts/glossary/F/","dab"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/G/",component:u("/next/concepts/glossary/G/","4f5"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/H/",component:u("/next/concepts/glossary/H/","d9c"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/I/",component:u("/next/concepts/glossary/I/","4d9"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/J/",component:u("/next/concepts/glossary/J/","963"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/K/",component:u("/next/concepts/glossary/K/","730"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/L/",component:u("/next/concepts/glossary/L/","73f"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/M/",component:u("/next/concepts/glossary/M/","682"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/N/",component:u("/next/concepts/glossary/N/","d95"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/O/",component:u("/next/concepts/glossary/O/","df1"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/P/",component:u("/next/concepts/glossary/P/","df7"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/Q/",component:u("/next/concepts/glossary/Q/","e4b"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/R/",component:u("/next/concepts/glossary/R/","29a"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/S/",component:u("/next/concepts/glossary/S/","e28"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/T/",component:u("/next/concepts/glossary/T/","9aa"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/U/",component:u("/next/concepts/glossary/U/","bc5"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/V/",component:u("/next/concepts/glossary/V/","e9c"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/W/",component:u("/next/concepts/glossary/W/","74f"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/X/",component:u("/next/concepts/glossary/X/","d66"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/Y/",component:u("/next/concepts/glossary/Y/","d4c"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/glossary/Z/",component:u("/next/concepts/glossary/Z/","f02"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/intro-to-dapps/",component:u("/next/concepts/intro-to-dapps/","799"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/key-types/",component:u("/next/concepts/key-types/","f53"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/list-auth-keys/",component:u("/next/concepts/list-auth-keys/","8a6"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/serialization/",component:u("/next/concepts/serialization/","c63"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/serialization/primitives/",component:u("/next/concepts/serialization/primitives/","84c"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/serialization/structures/",component:u("/next/concepts/serialization/structures/","f86"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/serialization/types/",component:u("/next/concepts/serialization/types/","764"),exact:!0,sidebar:"concepts"},{path:"/next/concepts/smart-contracts/",component:u("/next/concepts/smart-contracts/","130"),exact:!0,sidebar:"concepts"},{path:"/next/counter-testnet/",component:u("/next/counter-testnet/","ba2"),exact:!0,sidebar:"tutorials"},{path:"/next/counter/",component:u("/next/counter/","356"),exact:!0,sidebar:"tutorials"},{path:"/next/design/",component:u("/next/design/","5b5"),exact:!0,sidebar:"concepts"},{path:"/next/developers/",component:u("/next/developers/","a93"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/",component:u("/next/developers/cli/","9b6"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/calling-contracts/",component:u("/next/developers/cli/calling-contracts/","9cf"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/delegate/",component:u("/next/developers/cli/delegate/","453"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/execution-error-codes/",component:u("/next/developers/cli/execution-error-codes/","e24"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/installing-contracts/",component:u("/next/developers/cli/installing-contracts/","ae4"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/opcode-costs/",component:u("/next/developers/cli/opcode-costs/","739"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/querying-global-state/",component:u("/next/developers/cli/querying-global-state/","2f4"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/redelegate/",component:u("/next/developers/cli/redelegate/","846"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/sending-transactions/",component:u("/next/developers/cli/sending-transactions/","110"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/transfers/",component:u("/next/developers/cli/transfers/","937"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/transfers/direct-token-transfer/",component:u("/next/developers/cli/transfers/direct-token-transfer/","b10"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/transfers/multisig-deploy-transfer/",component:u("/next/developers/cli/transfers/multisig-deploy-transfer/","fe4"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/transfers/verify-transfer/",component:u("/next/developers/cli/transfers/verify-transfer/","e9e"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/undelegate/",component:u("/next/developers/cli/undelegate/","8c5"),exact:!0,sidebar:"developers"},{path:"/next/developers/cli/verifying-contracts/",component:u("/next/developers/cli/verifying-contracts/","431"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/",component:u("/next/developers/dapps/","972"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/dapp/",component:u("/next/developers/dapps/dapp/","072"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/monitor-and-consume-events/",component:u("/next/developers/dapps/monitor-and-consume-events/","f22"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/nctl-test/",component:u("/next/developers/dapps/nctl-test/","74b"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/prerequisites/",component:u("/next/developers/dapps/prerequisites/","92e"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/sdk/client-library-usage/",component:u("/next/developers/dapps/sdk/client-library-usage/","f98"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/sdk/csharp-sdk/",component:u("/next/developers/dapps/sdk/csharp-sdk/","111"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/sdk/go-sdk/",component:u("/next/developers/dapps/sdk/go-sdk/","72a"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/sdk/python-sdk/",component:u("/next/developers/dapps/sdk/python-sdk/","10b"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/sdk/script-sdk/",component:u("/next/developers/dapps/sdk/script-sdk/","e20"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/setup-nctl/",component:u("/next/developers/dapps/setup-nctl/","f0c"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/signing-a-transaction/",component:u("/next/developers/dapps/signing-a-transaction/","82d"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/speculative-exec/",component:u("/next/developers/dapps/speculative-exec/","d76"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/technology-stack/",component:u("/next/developers/dapps/technology-stack/","22e"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/template-frontend/",component:u("/next/developers/dapps/template-frontend/","fba"),exact:!0,sidebar:"developers"},{path:"/next/developers/dapps/uref-security/",component:u("/next/developers/dapps/uref-security/","6a8"),exact:!0,sidebar:"developers"},{path:"/next/developers/essential-crates/",component:u("/next/developers/essential-crates/","aa0"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/",component:u("/next/developers/json-rpc/","09a"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/errors/",component:u("/next/developers/json-rpc/errors/","4a3"),exact:!0},{path:"/next/developers/json-rpc/guidance/",component:u("/next/developers/json-rpc/guidance/","875"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/json-rpc-informational/",component:u("/next/developers/json-rpc/json-rpc-informational/","c16"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/json-rpc-pos/",component:u("/next/developers/json-rpc/json-rpc-pos/","b71"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/json-rpc-transactional/",component:u("/next/developers/json-rpc/json-rpc-transactional/","11d"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/minimal-compliance/",component:u("/next/developers/json-rpc/minimal-compliance/","8e2"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/types_chain/",component:u("/next/developers/json-rpc/types_chain/","cc2"),exact:!0,sidebar:"developers"},{path:"/next/developers/json-rpc/types_cl/",component:u("/next/developers/json-rpc/types_cl/","437"),exact:!0,sidebar:"developers"},{path:"/next/developers/prerequisites/",component:u("/next/developers/prerequisites/","0ad"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/assembly-script/",component:u("/next/developers/writing-onchain-code/assembly-script/","1f0"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/best-practices/",component:u("/next/developers/writing-onchain-code/best-practices/","857"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/calling-contracts/",component:u("/next/developers/writing-onchain-code/calling-contracts/","825"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:u("/next/developers/writing-onchain-code/contract-hash-vs-package-hash/","f3a"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/contract-vs-session/",component:u("/next/developers/writing-onchain-code/contract-vs-session/","89b"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/emitting-contract-events/",component:u("/next/developers/writing-onchain-code/emitting-contract-events/","1ff"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/factory-pattern/",component:u("/next/developers/writing-onchain-code/factory-pattern/","aea"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/getting-started/",component:u("/next/developers/writing-onchain-code/getting-started/","ece"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/simple-contract/",component:u("/next/developers/writing-onchain-code/simple-contract/","c49"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/testing-contracts/",component:u("/next/developers/writing-onchain-code/testing-contracts/","878"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/testing-session-code/",component:u("/next/developers/writing-onchain-code/testing-session-code/","db8"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/upgrading-contracts/",component:u("/next/developers/writing-onchain-code/upgrading-contracts/","6fd"),exact:!0,sidebar:"developers"},{path:"/next/developers/writing-onchain-code/writing-session-code/",component:u("/next/developers/writing-onchain-code/writing-session-code/","ebe"),exact:!0,sidebar:"developers"},{path:"/next/disclaimer/",component:u("/next/disclaimer/","f2d"),exact:!0},{path:"/next/economics/",component:u("/next/economics/","67e"),exact:!0,sidebar:"concepts"},{path:"/next/glossary/",component:u("/next/glossary/","415"),exact:!0,sidebar:"concepts"},{path:"/next/operators/",component:u("/next/operators/","233"),exact:!0,sidebar:"operators"},{path:"/next/operators/becoming-a-validator/",component:u("/next/operators/becoming-a-validator/","bfc"),exact:!0,sidebar:"operators"},{path:"/next/operators/becoming-a-validator/bonding/",component:u("/next/operators/becoming-a-validator/bonding/","f30"),exact:!0,sidebar:"operators"},{path:"/next/operators/becoming-a-validator/change-bid-public-key/",component:u("/next/operators/becoming-a-validator/change-bid-public-key/","47f"),exact:!0},{path:"/next/operators/becoming-a-validator/inactive-vs-faulty/",component:u("/next/operators/becoming-a-validator/inactive-vs-faulty/","ab0"),exact:!0,sidebar:"operators"},{path:"/next/operators/becoming-a-validator/recovering/",component:u("/next/operators/becoming-a-validator/recovering/","e27"),exact:!0,sidebar:"operators"},{path:"/next/operators/becoming-a-validator/unbonding/",component:u("/next/operators/becoming-a-validator/unbonding/","133"),exact:!0,sidebar:"operators"},{path:"/next/operators/maintenance/",component:u("/next/operators/maintenance/","ec3"),exact:!0,sidebar:"operators"},{path:"/next/operators/maintenance/archiving-and-restoring/",component:u("/next/operators/maintenance/archiving-and-restoring/","c92"),exact:!0,sidebar:"operators"},{path:"/next/operators/maintenance/moving-node/",component:u("/next/operators/maintenance/moving-node/","d48"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup-network/",component:u("/next/operators/setup-network/","21a"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup-network/chain-spec/",component:u("/next/operators/setup-network/chain-spec/","530"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup-network/create-private/",component:u("/next/operators/setup-network/create-private/","032"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup-network/genesis/",component:u("/next/operators/setup-network/genesis/","9ed"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup-network/staging-files-for-new-network/",component:u("/next/operators/setup-network/staging-files-for-new-network/","922"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/",component:u("/next/operators/setup/","485"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/basic-node-configuration/",component:u("/next/operators/setup/basic-node-configuration/","65b"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/casper-sidecar/",component:u("/next/operators/setup/casper-sidecar/","f49"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/fast-sync/",component:u("/next/operators/setup/fast-sync/","dd1"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/hardware/",component:u("/next/operators/setup/hardware/","5ac"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/install-node/",component:u("/next/operators/setup/install-node/","493"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/joining/",component:u("/next/operators/setup/joining/","a69"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/node-endpoints/",component:u("/next/operators/setup/node-endpoints/","21b"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/node-events/",component:u("/next/operators/setup/node-events/","f97"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/non-root-user/",component:u("/next/operators/setup/non-root-user/","682"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/open-files/",component:u("/next/operators/setup/open-files/","555"),exact:!0,sidebar:"operators"},{path:"/next/operators/setup/upgrade/",component:u("/next/operators/setup/upgrade/","3cc"),exact:!0,sidebar:"operators"},{path:"/next/resources/",component:u("/next/resources/","4af"),exact:!0,sidebar:"resources"},{path:"/next/resources/advanced/list-auth-keys-tutorial/",component:u("/next/resources/advanced/list-auth-keys-tutorial/","384"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/advanced/multi-sig/",component:u("/next/resources/advanced/multi-sig/","cb2"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/advanced/multi-sig/multi-sig-workflow/",component:u("/next/resources/advanced/multi-sig/multi-sig-workflow/","118"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/advanced/multi-sig/other-scenarios/",component:u("/next/resources/advanced/multi-sig/other-scenarios/","707"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter-testnet/commands/",component:u("/next/resources/beginner/counter-testnet/commands/","12c"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter-testnet/overview/",component:u("/next/resources/beginner/counter-testnet/overview/","1d0"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter-testnet/walkthrough/",component:u("/next/resources/beginner/counter-testnet/walkthrough/","d50"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter/commands/",component:u("/next/resources/beginner/counter/commands/","312"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter/overview/",component:u("/next/resources/beginner/counter/overview/","34f"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/beginner/counter/walkthrough/",component:u("/next/resources/beginner/counter/walkthrough/","69e"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/build-on-casper/casper-open-source-software/",component:u("/next/resources/build-on-casper/casper-open-source-software/","778"),exact:!0,sidebar:"resources"},{path:"/next/resources/build-on-casper/introduction/",component:u("/next/resources/build-on-casper/introduction/","597"),exact:!0,sidebar:"resources"},{path:"/next/resources/changelog/",component:u("/next/resources/changelog/","3c8"),exact:!0},{path:"/next/resources/moving-to-casper/",component:u("/next/resources/moving-to-casper/","b9c"),exact:!0,sidebar:"resources"},{path:"/next/resources/quick-start/",component:u("/next/resources/quick-start/","cc3"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tokens/",component:u("/next/resources/tokens/","169"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep18/full-tutorial/",component:u("/next/resources/tokens/cep18/full-tutorial/","259"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep18/query/",component:u("/next/resources/tokens/cep18/query/","9e3"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep18/quickstart-guide/",component:u("/next/resources/tokens/cep18/quickstart-guide/","a3d"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep18/tests/",component:u("/next/resources/tokens/cep18/tests/","a8b"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep18/transfer/",component:u("/next/resources/tokens/cep18/transfer/","8b3"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep78/introduction/",component:u("/next/resources/tokens/cep78/introduction/","ca5"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep78/js-tutorial/",component:u("/next/resources/tokens/cep78/js-tutorial/","52e"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep78/modalities/",component:u("/next/resources/tokens/cep78/modalities/","c7d"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/cep78/reverse-lookup/",component:u("/next/resources/tokens/cep78/reverse-lookup/","cd8"),exact:!0,sidebar:"resources"},{path:"/next/resources/tokens/using-casper-client/",component:u("/next/resources/tokens/using-casper-client/","e2e"),exact:!0,sidebar:"resources"},{path:"/next/resources/tutorials/advanced/",component:u("/next/resources/tutorials/advanced/","6ca"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/advanced/cross-contract/",component:u("/next/resources/tutorials/advanced/cross-contract/","d51"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/advanced/list-cspr/",component:u("/next/resources/tutorials/advanced/list-cspr/","374"),exact:!0},{path:"/next/resources/tutorials/advanced/return-values-tutorial/",component:u("/next/resources/tutorials/advanced/return-values-tutorial/","49e"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/advanced/storage-workflow/",component:u("/next/resources/tutorials/advanced/storage-workflow/","f4d"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/advanced/transfer-token-to-contract/",component:u("/next/resources/tutorials/advanced/transfer-token-to-contract/","6d6"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/advanced/two-party-multi-sig/",component:u("/next/resources/tutorials/advanced/two-party-multi-sig/","b67"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/",component:u("/next/resources/tutorials/beginner/","026"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/aws-node/",component:u("/next/resources/tutorials/beginner/aws-node/","f3b"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/cep18/",component:u("/next/resources/tutorials/beginner/cep18/","8eb"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/getting-started-tutorial/",component:u("/next/resources/tutorials/beginner/getting-started-tutorial/","6d3"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/querying-network/",component:u("/next/resources/tutorials/beginner/querying-network/","57a"),exact:!0,sidebar:"tutorials"},{path:"/next/resources/tutorials/beginner/upgrade-contract/",component:u("/next/resources/tutorials/beginner/upgrade-contract/","90d"),exact:!0,sidebar:"tutorials"},{path:"/next/runtime/",component:u("/next/runtime/","670"),exact:!0,sidebar:"concepts"},{path:"/next/sdk/",component:u("/next/sdk/","b20"),exact:!0,sidebar:"developers"},{path:"/next/transactions-and-transaction-lifecycle/",component:u("/next/transactions-and-transaction-lifecycle/","6b1"),exact:!0,sidebar:"concepts"},{path:"/next/transactions/",component:u("/next/transactions/","184"),exact:!0},{path:"/next/users/",component:u("/next/users/","cba"),exact:!0,sidebar:"users"},{path:"/next/users/block-explorer/",component:u("/next/users/block-explorer/","d36"),exact:!0,sidebar:"users"},{path:"/next/users/csprlive/",component:u("/next/users/csprlive/","462"),exact:!0,sidebar:"users"},{path:"/next/users/delegate-ui/",component:u("/next/users/delegate-ui/","513"),exact:!0,sidebar:"users"},{path:"/next/users/delegating/",component:u("/next/users/delegating/","d1d"),exact:!0,sidebar:"users"},{path:"/next/users/funding-from-exchanges/",component:u("/next/users/funding-from-exchanges/","4ed"),exact:!0,sidebar:"users"},{path:"/next/users/ledger/",component:u("/next/users/ledger/","130"),exact:!0,sidebar:"users"},{path:"/next/users/ledger/ledger-cspr-live/",component:u("/next/users/ledger/ledger-cspr-live/","adb"),exact:!0,sidebar:"users"},{path:"/next/users/ledger/ledger-live/",component:u("/next/users/ledger/ledger-live/","c01"),exact:!0,sidebar:"users"},{path:"/next/users/staking-ledger/",component:u("/next/users/staking-ledger/","e01"),exact:!0,sidebar:"users"},{path:"/next/users/testnet-faucet/",component:u("/next/users/testnet-faucet/","95b"),exact:!0,sidebar:"users"},{path:"/next/users/token-transfer/",component:u("/next/users/token-transfer/","d87"),exact:!0,sidebar:"users"},{path:"/next/users/undelegate-ui/",component:u("/next/users/undelegate-ui/","75d"),exact:!0,sidebar:"users"},{path:"/next/workflow/ledger-setup/",component:u("/next/workflow/ledger-setup/","32f"),exact:!0,sidebar:"users"},{path:"/next/writing-contracts/",component:u("/next/writing-contracts/","68e"),exact:!0,sidebar:"developers"}]}]},{path:"/",component:u("/","92c"),routes:[{path:"/",component:u("/","57d"),routes:[{path:"/concepts/",component:u("/concepts/","9a3"),exact:!0,sidebar:"concepts"},{path:"/concepts/accounts-and-keys/",component:u("/concepts/accounts-and-keys/","18a"),exact:!0,sidebar:"concepts"},{path:"/concepts/callstack/",component:u("/concepts/callstack/","218"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/casper-design/",component:u("/concepts/design/casper-design/","608"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/highway/",component:u("/concepts/design/highway/","237"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/networking-protocol/",component:u("/concepts/design/networking-protocol/","3a3"),exact:!0},{path:"/concepts/design/p2p/",component:u("/concepts/design/p2p/","8b8"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/reading-and-writing-to-the-blockchain/",component:u("/concepts/design/reading-and-writing-to-the-blockchain/","55e"),exact:!0,sidebar:"concepts"},{path:"/concepts/dictionaries/",component:u("/concepts/dictionaries/","767"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/concepts/",component:u("/concepts/economics/concepts/","1e0"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/consensus/",component:u("/concepts/economics/consensus/","294"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/delegation/",component:u("/concepts/economics/delegation/","837"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/gas-concepts/",component:u("/concepts/economics/gas-concepts/","57f"),exact:!0,sidebar:"concepts"},{path:"/concepts/global-state/",component:u("/concepts/global-state/","25c"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/A/",component:u("/concepts/glossary/A/","85a"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/B/",component:u("/concepts/glossary/B/","a71"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/C/",component:u("/concepts/glossary/C/","8d7"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/D/",component:u("/concepts/glossary/D/","990"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/E/",component:u("/concepts/glossary/E/","843"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/F/",component:u("/concepts/glossary/F/","7ff"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/G/",component:u("/concepts/glossary/G/","54f"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/H/",component:u("/concepts/glossary/H/","0c5"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/I/",component:u("/concepts/glossary/I/","f08"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/J/",component:u("/concepts/glossary/J/","580"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/K/",component:u("/concepts/glossary/K/","7dd"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/L/",component:u("/concepts/glossary/L/","0f8"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/M/",component:u("/concepts/glossary/M/","626"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/N/",component:u("/concepts/glossary/N/","0e3"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/O/",component:u("/concepts/glossary/O/","c7e"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/P/",component:u("/concepts/glossary/P/","903"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Q/",component:u("/concepts/glossary/Q/","927"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/R/",component:u("/concepts/glossary/R/","8da"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/S/",component:u("/concepts/glossary/S/","de1"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/T/",component:u("/concepts/glossary/T/","826"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/U/",component:u("/concepts/glossary/U/","4db"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/V/",component:u("/concepts/glossary/V/","c26"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/W/",component:u("/concepts/glossary/W/","c97"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/X/",component:u("/concepts/glossary/X/","fd1"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Y/",component:u("/concepts/glossary/Y/","c1a"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Z/",component:u("/concepts/glossary/Z/","903"),exact:!0,sidebar:"concepts"},{path:"/concepts/hash-types/",component:u("/concepts/hash-types/","664"),exact:!0,sidebar:"concepts"},{path:"/concepts/intro-to-dapps/",component:u("/concepts/intro-to-dapps/","fb0"),exact:!0,sidebar:"concepts"},{path:"/concepts/list-auth-keys/",component:u("/concepts/list-auth-keys/","93f"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization-standard/",component:u("/concepts/serialization-standard/","fab"),exact:!0,sidebar:"concepts"},{path:"/concepts/smart-contracts/",component:u("/concepts/smart-contracts/","b66"),exact:!0,sidebar:"concepts"},{path:"/counter-testnet/",component:u("/counter-testnet/","c0a"),exact:!0,sidebar:"tutorials"},{path:"/counter/",component:u("/counter/","c0d"),exact:!0,sidebar:"tutorials"},{path:"/deploy-and-deploy-lifecycle/",component:u("/deploy-and-deploy-lifecycle/","985"),exact:!0,sidebar:"concepts"},{path:"/design/",component:u("/design/","ad0"),exact:!0,sidebar:"concepts"},{path:"/developers/",component:u("/developers/","856"),exact:!0,sidebar:"developers"},{path:"/developers/cli/",component:u("/developers/cli/","227"),exact:!0,sidebar:"developers"},{path:"/developers/cli/calling-contracts/",component:u("/developers/cli/calling-contracts/","210"),exact:!0,sidebar:"developers"},{path:"/developers/cli/delegate/",component:u("/developers/cli/delegate/","fde"),exact:!0,sidebar:"developers"},{path:"/developers/cli/execution-error-codes/",component:u("/developers/cli/execution-error-codes/","fef"),exact:!0,sidebar:"developers"},{path:"/developers/cli/installing-contracts/",component:u("/developers/cli/installing-contracts/","410"),exact:!0,sidebar:"developers"},{path:"/developers/cli/opcode-costs/",component:u("/developers/cli/opcode-costs/","4ae"),exact:!0,sidebar:"developers"},{path:"/developers/cli/querying-global-state/",component:u("/developers/cli/querying-global-state/","62b"),exact:!0,sidebar:"developers"},{path:"/developers/cli/redelegate/",component:u("/developers/cli/redelegate/","e46"),exact:!0,sidebar:"developers"},{path:"/developers/cli/sending-deploys/",component:u("/developers/cli/sending-deploys/","67a"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/",component:u("/developers/cli/transfers/","78b"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/direct-token-transfer/",component:u("/developers/cli/transfers/direct-token-transfer/","169"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/multisig-deploy-transfer/",component:u("/developers/cli/transfers/multisig-deploy-transfer/","9c9"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/verify-transfer/",component:u("/developers/cli/transfers/verify-transfer/","451"),exact:!0,sidebar:"developers"},{path:"/developers/cli/undelegate/",component:u("/developers/cli/undelegate/","98c"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/",component:u("/developers/dapps/","33b"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/dapp/",component:u("/developers/dapps/dapp/","0f4"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/monitor-and-consume-events/",component:u("/developers/dapps/monitor-and-consume-events/","f6e"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/nctl-test/",component:u("/developers/dapps/nctl-test/","e5c"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/prerequisites/",component:u("/developers/dapps/prerequisites/","d2d"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/client-library-usage/",component:u("/developers/dapps/sdk/client-library-usage/","c13"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/csharp-sdk/",component:u("/developers/dapps/sdk/csharp-sdk/","b9a"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/go-sdk/",component:u("/developers/dapps/sdk/go-sdk/","465"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/python-sdk/",component:u("/developers/dapps/sdk/python-sdk/","e6f"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/script-sdk/",component:u("/developers/dapps/sdk/script-sdk/","701"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/setup-nctl/",component:u("/developers/dapps/setup-nctl/","88f"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/signing-a-deploy/",component:u("/developers/dapps/signing-a-deploy/","fe7"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/speculative-exec/",component:u("/developers/dapps/speculative-exec/","be2"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/technology-stack/",component:u("/developers/dapps/technology-stack/","79a"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/template-frontend/",component:u("/developers/dapps/template-frontend/","21e"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/uref-security/",component:u("/developers/dapps/uref-security/","1a5"),exact:!0,sidebar:"developers"},{path:"/developers/essential-crates/",component:u("/developers/essential-crates/","7ef"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/",component:u("/developers/json-rpc/","6b0"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/errors/",component:u("/developers/json-rpc/errors/","e89"),exact:!0},{path:"/developers/json-rpc/guidance/",component:u("/developers/json-rpc/guidance/","d85"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-informational/",component:u("/developers/json-rpc/json-rpc-informational/","d2f"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-pos/",component:u("/developers/json-rpc/json-rpc-pos/","8f5"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-transactional/",component:u("/developers/json-rpc/json-rpc-transactional/","491"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/minimal-compliance/",component:u("/developers/json-rpc/minimal-compliance/","4e6"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_chain/",component:u("/developers/json-rpc/types_chain/","f3f"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_cl/",component:u("/developers/json-rpc/types_cl/","43c"),exact:!0,sidebar:"developers"},{path:"/developers/prerequisites/",component:u("/developers/prerequisites/","0c3"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/assembly-script/",component:u("/developers/writing-onchain-code/assembly-script/","ea8"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/best-practices/",component:u("/developers/writing-onchain-code/best-practices/","a98"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/calling-contracts/",component:u("/developers/writing-onchain-code/calling-contracts/","f79"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:u("/developers/writing-onchain-code/contract-hash-vs-package-hash/","f11"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-vs-session/",component:u("/developers/writing-onchain-code/contract-vs-session/","f69"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/getting-started/",component:u("/developers/writing-onchain-code/getting-started/","fb8"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/simple-contract/",component:u("/developers/writing-onchain-code/simple-contract/","a5e"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-contracts/",component:u("/developers/writing-onchain-code/testing-contracts/","e4c"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-session-code/",component:u("/developers/writing-onchain-code/testing-session-code/","ec5"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/upgrading-contracts/",component:u("/developers/writing-onchain-code/upgrading-contracts/","101"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/writing-session-code/",component:u("/developers/writing-onchain-code/writing-session-code/","98d"),exact:!0,sidebar:"developers"},{path:"/disclaimer/",component:u("/disclaimer/","daa"),exact:!0},{path:"/economics/",component:u("/economics/","660"),exact:!0,sidebar:"concepts"},{path:"/glossary/",component:u("/glossary/","710"),exact:!0,sidebar:"concepts"},{path:"/operators/",component:u("/operators/","631"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/",component:u("/operators/becoming-a-validator/","531"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/bonding/",component:u("/operators/becoming-a-validator/bonding/","a3b"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/inactive-vs-faulty/",component:u("/operators/becoming-a-validator/inactive-vs-faulty/","364"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/recovering/",component:u("/operators/becoming-a-validator/recovering/","119"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/unbonding/",component:u("/operators/becoming-a-validator/unbonding/","c65"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/",component:u("/operators/maintenance/","4d1"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/archiving-and-restoring/",component:u("/operators/maintenance/archiving-and-restoring/","1e6"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/moving-node/",component:u("/operators/maintenance/moving-node/","e95"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/",component:u("/operators/setup-network/","93d"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/chain-spec/",component:u("/operators/setup-network/chain-spec/","94f"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/create-private/",component:u("/operators/setup-network/create-private/","e21"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/genesis/",component:u("/operators/setup-network/genesis/","1c0"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/staging-files-for-new-network/",component:u("/operators/setup-network/staging-files-for-new-network/","610"),exact:!0,sidebar:"operators"},{path:"/operators/setup/",component:u("/operators/setup/","f6c"),exact:!0,sidebar:"operators"},{path:"/operators/setup/basic-node-configuration/",component:u("/operators/setup/basic-node-configuration/","f3b"),exact:!0,sidebar:"operators"},{path:"/operators/setup/fast-sync/",component:u("/operators/setup/fast-sync/","972"),exact:!0,sidebar:"operators"},{path:"/operators/setup/hardware/",component:u("/operators/setup/hardware/","53b"),exact:!0,sidebar:"operators"},{path:"/operators/setup/install-node/",component:u("/operators/setup/install-node/","b94"),exact:!0,sidebar:"operators"},{path:"/operators/setup/joining/",component:u("/operators/setup/joining/","62b"),exact:!0,sidebar:"operators"},{path:"/operators/setup/node-endpoints/",component:u("/operators/setup/node-endpoints/","427"),exact:!0,sidebar:"operators"},{path:"/operators/setup/non-root-user/",component:u("/operators/setup/non-root-user/","f5a"),exact:!0,sidebar:"operators"},{path:"/operators/setup/open-files/",component:u("/operators/setup/open-files/","fff"),exact:!0,sidebar:"operators"},{path:"/operators/setup/upgrade/",component:u("/operators/setup/upgrade/","68f"),exact:!0,sidebar:"operators"},{path:"/resources/",component:u("/resources/","586"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/list-auth-keys-tutorial/",component:u("/resources/advanced/list-auth-keys-tutorial/","c29"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/",component:u("/resources/advanced/multi-sig/","058"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/multi-sig-workflow/",component:u("/resources/advanced/multi-sig/multi-sig-workflow/","268"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/other-scenarios/",component:u("/resources/advanced/multi-sig/other-scenarios/","984"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/commands/",component:u("/resources/beginner/counter-testnet/commands/","8e9"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/overview/",component:u("/resources/beginner/counter-testnet/overview/","bc2"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/walkthrough/",component:u("/resources/beginner/counter-testnet/walkthrough/","305"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/commands/",component:u("/resources/beginner/counter/commands/","565"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/overview/",component:u("/resources/beginner/counter/overview/","011"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/walkthrough/",component:u("/resources/beginner/counter/walkthrough/","fd8"),exact:!0,sidebar:"tutorials"},{path:"/resources/build-on-casper/casper-open-source-software/",component:u("/resources/build-on-casper/casper-open-source-software/","e3a"),exact:!0,sidebar:"resources"},{path:"/resources/build-on-casper/introduction/",component:u("/resources/build-on-casper/introduction/","2c7"),exact:!0,sidebar:"resources"},{path:"/resources/condor-for-exchanges/",component:u("/resources/condor-for-exchanges/","d24"),exact:!0},{path:"/resources/moving-to-casper/",component:u("/resources/moving-to-casper/","45a"),exact:!0,sidebar:"resources"},{path:"/resources/quick-start/",component:u("/resources/quick-start/","bce"),exact:!0,sidebar:"tutorials"},{path:"/resources/tokens/",component:u("/resources/tokens/","2fb"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/full-tutorial/",component:u("/resources/tokens/cep18/full-tutorial/","0c2"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/query/",component:u("/resources/tokens/cep18/query/","044"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/quickstart-guide/",component:u("/resources/tokens/cep18/quickstart-guide/","f97"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/tests/",component:u("/resources/tokens/cep18/tests/","056"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/transfer/",component:u("/resources/tokens/cep18/transfer/","84f"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/introduction/",component:u("/resources/tokens/cep78/introduction/","ca6"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/js-tutorial/",component:u("/resources/tokens/cep78/js-tutorial/","05a"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/modalities/",component:u("/resources/tokens/cep78/modalities/","f34"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/reverse-lookup/",component:u("/resources/tokens/cep78/reverse-lookup/","70d"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/using-casper-client/full-installation-tutorial/",component:u("/resources/tokens/cep78/using-casper-client/full-installation-tutorial/","4e1"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/",component:u("/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/","d6d"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/using-casper-client/querying-NFTs/",component:u("/resources/tokens/cep78/using-casper-client/querying-NFTs/","258"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/using-casper-client/quickstart-guide/",component:u("/resources/tokens/cep78/using-casper-client/quickstart-guide/","056"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/using-casper-client/testing-NFTs/",component:u("/resources/tokens/cep78/using-casper-client/testing-NFTs/","1aa"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/",component:u("/resources/tutorials/advanced/","134"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/cross-contract/",component:u("/resources/tutorials/advanced/cross-contract/","c0d"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/list-cspr/",component:u("/resources/tutorials/advanced/list-cspr/","2b6"),exact:!0},{path:"/resources/tutorials/advanced/return-values-tutorial/",component:u("/resources/tutorials/advanced/return-values-tutorial/","433"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/storage-workflow/",component:u("/resources/tutorials/advanced/storage-workflow/","42e"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/transfer-token-to-contract/",component:u("/resources/tutorials/advanced/transfer-token-to-contract/","ea6"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/two-party-multi-sig/",component:u("/resources/tutorials/advanced/two-party-multi-sig/","f0f"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/",component:u("/resources/tutorials/beginner/","06a"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/aws-node/",component:u("/resources/tutorials/beginner/aws-node/","435"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/cep18/",component:u("/resources/tutorials/beginner/cep18/","58e"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/getting-started-tutorial/",component:u("/resources/tutorials/beginner/getting-started-tutorial/","647"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/querying-network/",component:u("/resources/tutorials/beginner/querying-network/","6ba"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/upgrade-contract/",component:u("/resources/tutorials/beginner/upgrade-contract/","d39"),exact:!0,sidebar:"tutorials"},{path:"/runtime/",component:u("/runtime/","e97"),exact:!0,sidebar:"concepts"},{path:"/sdk/",component:u("/sdk/","2a1"),exact:!0,sidebar:"developers"},{path:"/staking/",component:u("/staking/","02d"),exact:!0,sidebar:"concepts"},{path:"/users/",component:u("/users/","e5e"),exact:!0,sidebar:"users"},{path:"/users/block-explorer/",component:u("/users/block-explorer/","889"),exact:!0,sidebar:"users"},{path:"/users/csprlive/",component:u("/users/csprlive/","165"),exact:!0,sidebar:"users"},{path:"/users/delegate-ui/",component:u("/users/delegate-ui/","c78"),exact:!0,sidebar:"users"},{path:"/users/funding-from-exchanges/",component:u("/users/funding-from-exchanges/","921"),exact:!0,sidebar:"users"},{path:"/users/ledger/",component:u("/users/ledger/","914"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-cspr-live/",component:u("/users/ledger/ledger-cspr-live/","aef"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-live/",component:u("/users/ledger/ledger-live/","4da"),exact:!0,sidebar:"users"},{path:"/users/staking-ledger/",component:u("/users/staking-ledger/","8d6"),exact:!0,sidebar:"users"},{path:"/users/testnet-faucet/",component:u("/users/testnet-faucet/","a2e"),exact:!0,sidebar:"users"},{path:"/users/token-transfer/",component:u("/users/token-transfer/","ded"),exact:!0,sidebar:"users"},{path:"/users/undelegate-ui/",component:u("/users/undelegate-ui/","96f"),exact:!0,sidebar:"users"},{path:"/workflow/ledger-setup/",component:u("/workflow/ledger-setup/","228"),exact:!0,sidebar:"users"},{path:"/writing-contracts/",component:u("/writing-contracts/","147"),exact:!0,sidebar:"developers"},{path:"/",component:u("/","981"),exact:!0,sidebar:"concepts"}]}]}]},{path:"*",component:u("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>s,x:()=>a});var r=n(96540),o=n(74848);const s=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),(0,o.jsx)(s.Provider,{value:n,children:t})}},38536:(e,t,n)=>{"use strict";var r=n(96540),o=n(5338),s=n(80545),a=n(54625),i=n(4784),c=n(38193);const l=[n(10119),n(26134),n(76294),n(51043)];var d=n(35947),u=n(56347),p=n(22831),f=n(74848);function g(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var m=n(5260),h=n(44586),b=n(86025),v=n(6342),y=n(45500),x=n(32131),w=n(14090),k=n(2967),_=n(70440),S=n(41463);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.A)(),r=(0,x.o)(),o=n[e].htmlLang,s=e=>e.replace("-","_");return(0,f.jsxs)(m.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:s(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:s(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.A)(),{pathname:r}=(0,u.zy)();return e+(0,_.Ks)((0,b.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,f.jsxs)(m.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:o}),(0,f.jsx)("link",{rel:"canonical",href:o})]})}function T(){const{i18n:{currentLocale:e}}=(0,h.A)(),{metadata:t,image:n}=(0,v.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(m.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:w.w})]}),n&&(0,f.jsx)(y.be,{image:n}),(0,f.jsx)(C,{}),(0,f.jsx)(E,{}),(0,f.jsx)(S.A,{tag:k.C,locale:e}),(0,f.jsx)(m.A,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const j=new Map;var A=n(6125),R=n(26988),P=n(205);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const o=l.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const L=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,P.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,s=t.search===n.search;if(r&&o&&!s)return;const{hash:a}=t;if(a){const e=decodeURIComponent(a.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),N("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,p.u)(d.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class D extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=c.A.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(L,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(u.qh,{location:t,render:()=>e})})}}const I=D,M="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${F}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${z}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${z}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function U(){const{siteConfig:{baseUrl:e}}=(0,h.A)();return(0,f.jsx)(f.Fragment,{children:!c.A.canUseDOM&&(0,f.jsx)(m.A,{children:(0,f.jsx)("script",{children:B(e)})})})}function $(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.A)(),{pathname:n}=(0,u.zy)();return t&&n===e?(0,f.jsx)(U,{}):null}function q(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,h.A)(),s=(0,b.Ay)(e),{htmlLang:a,direction:i}=o[r];return(0,f.jsxs)(m.A,{children:[(0,f.jsx)("html",{lang:a,dir:i}),(0,f.jsx)("title",{children:t}),(0,f.jsx)("meta",{property:"og:title",content:t}),(0,f.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,f.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,f.jsx)("link",{rel:"icon",href:s})]})}var X=n(67489),H=n(92303);function G(){const e=(0,H.A)();return(0,f.jsx)(m.A,{children:(0,f.jsx)("html",{"data-has-hydrated":e})})}const V=(0,p.v)(d.A);function W(){const e=function(e){if(j.has(e.pathname))return{...e,pathname:j.get(e.pathname)};if((0,p.u)(d.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return j.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return j.set(e.pathname,t),{...e,pathname:t}}((0,u.zy)());return(0,f.jsx)(I,{location:e,children:V})}function K(){return(0,f.jsx)(X.A,{children:(0,f.jsx)(R.l,{children:(0,f.jsxs)(A.x,{children:[(0,f.jsxs)(g,{children:[(0,f.jsx)(q,{}),(0,f.jsx)(T,{}),(0,f.jsx)($,{}),(0,f.jsx)(W,{})]}),(0,f.jsx)(G,{})]})})})}var Q=n(84054);const Y=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Z=n(86921);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,p.u)(d.A,e).flatMap((e=>{return t=e.route.path,Object.entries(Q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Z.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),O(e))},re=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===i.A.future.experimental_router?(0,f.jsx)(a.I9,{children:t}):(0,f.jsx)(a.Kd,{children:t})}const se=Boolean(!0);if(c.A.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(s.vd,{children:(0,f.jsx)(oe,{children:(0,f.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},a=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(se)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};O(window.location.pathname).then((()=>{(0,r.startTransition)(a)}))}},26988:(e,t,n)=>{"use strict";n.d(t,{o:()=>u,l:()=>p});var r=n(96540),o=n(4784);const s=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/","versions":[{"name":"current","label":"Next","isLast":false,"path":"/next","mainDocId":"concepts/about","docs":[{"id":"concepts/about","path":"/next/","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/next/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/addressable-entity","path":"/next/concepts/addressable-entity","sidebar":"concepts"},{"id":"concepts/callstack","path":"/next/concepts/callstack","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/next/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/consensus","path":"/next/concepts/design/consensus","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/next/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/next/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/next/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/next/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/next/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/design/rewards","path":"/next/concepts/design/rewards","sidebar":"concepts"},{"id":"concepts/design/zug","path":"/next/concepts/design/zug","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/next/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/next/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/dynamic-gas-pricing","path":"/next/concepts/economics/dynamic-gas-pricing","sidebar":"concepts"},{"id":"concepts/economics/fee-elimination","path":"/next/concepts/economics/fee-elimination","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/next/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/next/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/next/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking","path":"/next/concepts/economics/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/next/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/next/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/next/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/next/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/next/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/next/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/next/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/next/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/next/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/next/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/next/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/next/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/next/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/next/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/next/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/next/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/next/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/next/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/next/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/next/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/next/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/next/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/next/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/next/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/next/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/next/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/next/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/next/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/index","path":"/next/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/next/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/key-types","path":"/next/concepts/key-types","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/next/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization/index","path":"/next/concepts/serialization/","sidebar":"concepts"},{"id":"concepts/serialization/primitives","path":"/next/concepts/serialization/primitives","sidebar":"concepts"},{"id":"concepts/serialization/structures","path":"/next/concepts/serialization/structures","sidebar":"concepts"},{"id":"concepts/serialization/types","path":"/next/concepts/serialization/types","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/next/concepts/smart-contracts","sidebar":"concepts"},{"id":"concepts/transactions","path":"/next/transactions"},{"id":"concepts/transactions-and-transaction-lifecycle","path":"/next/transactions-and-transaction-lifecycle","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/next/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/next/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/next/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/next/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/next/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/next/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/next/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/next/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-transactions","path":"/next/developers/cli/sending-transactions","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/next/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/next/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/next/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/next/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/next/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/cli/verifying-contracts","path":"/next/developers/cli/verifying-contracts","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/next/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/next/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/next/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/next/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/next/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/next/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/next/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/next/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/next/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/next/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/next/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/next/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-transaction","path":"/next/developers/dapps/signing-a-transaction","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/next/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/next/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/next/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/next/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/next/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/next/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/next/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/next/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/next/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/next/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/next/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/next/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/next/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/next/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/next/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/next/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/next/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/next/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/next/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/next/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/next/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/emitting-contract-events","path":"/next/developers/writing-onchain-code/emitting-contract-events","sidebar":"developers"},{"id":"developers/writing-onchain-code/factory-pattern","path":"/next/developers/writing-onchain-code/factory-pattern","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/next/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/next/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/next/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/next/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/next/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/next/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/next/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/next/disclaimer"},{"id":"operators/becoming-a-validator/bonding","path":"/next/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/change-bid-public-key","path":"/next/operators/becoming-a-validator/change-bid-public-key"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/next/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/next/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/next/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/next/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/next/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/next/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/next/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/next/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/next/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/next/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/next/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/next/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/next/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/next/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/casper-sidecar","path":"/next/operators/setup/casper-sidecar","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/next/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/next/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/next/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/next/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/next/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/next/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/node-events","path":"/next/operators/setup/node-events","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/next/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/next/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/next/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/next/resources/tutorials/advanced/cross-contract","sidebar":"tutorials"},{"id":"resources/advanced/index","path":"/next/resources/tutorials/advanced/","sidebar":"tutorials"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/next/resources/advanced/list-auth-keys-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/list-cspr","path":"/next/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/next/resources/advanced/multi-sig/","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/next/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/next/resources/advanced/multi-sig/other-scenarios","sidebar":"tutorials"},{"id":"resources/advanced/return-values-tutorial","path":"/next/resources/tutorials/advanced/return-values-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/storage-workflow","path":"/next/resources/tutorials/advanced/storage-workflow","sidebar":"tutorials"},{"id":"resources/advanced/transfer-token-to-contract","path":"/next/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"tutorials"},{"id":"resources/advanced/two-party-multi-sig","path":"/next/resources/tutorials/advanced/two-party-multi-sig","sidebar":"tutorials"},{"id":"resources/beginner/aws-node","path":"/next/resources/tutorials/beginner/aws-node","sidebar":"tutorials"},{"id":"resources/beginner/cep18","path":"/next/resources/tutorials/beginner/cep18","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/commands","path":"/next/resources/beginner/counter-testnet/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/index","path":"/next/counter-testnet","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/overview","path":"/next/resources/beginner/counter-testnet/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/next/resources/beginner/counter-testnet/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/counter/commands","path":"/next/resources/beginner/counter/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter/index","path":"/next/counter","sidebar":"tutorials"},{"id":"resources/beginner/counter/overview","path":"/next/resources/beginner/counter/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter/walkthrough","path":"/next/resources/beginner/counter/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/getting-started-tutorial","path":"/next/resources/tutorials/beginner/getting-started-tutorial","sidebar":"tutorials"},{"id":"resources/beginner/index","path":"/next/resources/tutorials/beginner/","sidebar":"tutorials"},{"id":"resources/beginner/querying-network","path":"/next/resources/tutorials/beginner/querying-network","sidebar":"tutorials"},{"id":"resources/beginner/upgrade-contract","path":"/next/resources/tutorials/beginner/upgrade-contract","sidebar":"tutorials"},{"id":"resources/build-on-casper","path":"/next/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/next/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/changelog","path":"/next/resources/changelog"},{"id":"resources/index","path":"/next/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/next/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/next/resources/quick-start","sidebar":"tutorials"},{"id":"resources/tokens/cep18/full-tutorial","path":"/next/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/next/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/next/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/next/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/next/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/next/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/next/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/next/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/next/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client","path":"/next/resources/tokens/using-casper-client","sidebar":"resources"},{"id":"resources/tokens/index","path":"/next/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/next/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/next/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/next/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/next/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/next/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/next/users/undelegate-ui","sidebar":"users"},{"id":"users/delegating","path":"/next/users/delegating","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/next/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/next/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/next/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/next/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/next/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/next/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/next/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/next/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/next/developers","label":"developers/index"}},"operators":{"link":{"path":"/next/operators","label":"operators/index"}},"resources":{"link":{"path":"/next/resources/","label":"resources/index"}},"users":{"link":{"path":"/next/users/","label":"users/index"}},"tutorials":{"link":{"path":"/next/resources/quick-start","label":"resources/quick-start"}}}},{"name":"1.5.X","label":"1.5.X","isLast":true,"path":"/","mainDocId":"concepts/about","docs":[{"id":"concepts/about","path":"/","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/callstack","path":"/concepts/callstack","sidebar":"concepts"},{"id":"concepts/deploy-and-deploy-lifecycle","path":"/deploy-and-deploy-lifecycle","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking/concepts","path":"/concepts/economics/concepts","sidebar":"concepts"},{"id":"concepts/economics/staking/delegation","path":"/concepts/economics/delegation","sidebar":"concepts"},{"id":"concepts/economics/staking/staking","path":"/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/hash-types","path":"/concepts/hash-types","sidebar":"concepts"},{"id":"concepts/index","path":"/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization-standard","path":"/concepts/serialization-standard","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/concepts/smart-contracts","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-deploys","path":"/developers/cli/sending-deploys","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-deploy","path":"/developers/dapps/signing-a-deploy","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/disclaimer"},{"id":"operators/becoming-a-validator/bonding","path":"/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/resources/tutorials/advanced/cross-contract","sidebar":"tutorials"},{"id":"resources/advanced/index","path":"/resources/tutorials/advanced/","sidebar":"tutorials"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/resources/advanced/list-auth-keys-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/list-cspr","path":"/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/resources/advanced/multi-sig/","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/resources/advanced/multi-sig/other-scenarios","sidebar":"tutorials"},{"id":"resources/advanced/return-values-tutorial","path":"/resources/tutorials/advanced/return-values-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/storage-workflow","path":"/resources/tutorials/advanced/storage-workflow","sidebar":"tutorials"},{"id":"resources/advanced/transfer-token-to-contract","path":"/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"tutorials"},{"id":"resources/advanced/two-party-multi-sig","path":"/resources/tutorials/advanced/two-party-multi-sig","sidebar":"tutorials"},{"id":"resources/beginner/aws-node","path":"/resources/tutorials/beginner/aws-node","sidebar":"tutorials"},{"id":"resources/beginner/cep18","path":"/resources/tutorials/beginner/cep18","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/commands","path":"/resources/beginner/counter-testnet/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/index","path":"/counter-testnet","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/overview","path":"/resources/beginner/counter-testnet/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/resources/beginner/counter-testnet/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/counter/commands","path":"/resources/beginner/counter/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter/index","path":"/counter","sidebar":"tutorials"},{"id":"resources/beginner/counter/overview","path":"/resources/beginner/counter/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter/walkthrough","path":"/resources/beginner/counter/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/getting-started-tutorial","path":"/resources/tutorials/beginner/getting-started-tutorial","sidebar":"tutorials"},{"id":"resources/beginner/index","path":"/resources/tutorials/beginner/","sidebar":"tutorials"},{"id":"resources/beginner/querying-network","path":"/resources/tutorials/beginner/querying-network","sidebar":"tutorials"},{"id":"resources/beginner/upgrade-contract","path":"/resources/tutorials/beginner/upgrade-contract","sidebar":"tutorials"},{"id":"resources/build-on-casper","path":"/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/condor-for-exchanges","path":"/resources/condor-for-exchanges"},{"id":"resources/index","path":"/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/resources/quick-start","sidebar":"tutorials"},{"id":"resources/tokens/cep18/full-tutorial","path":"/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","path":"/resources/tokens/cep78/using-casper-client/full-installation-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","path":"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/querying-NFTs","path":"/resources/tokens/cep78/using-casper-client/querying-NFTs","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/quickstart-guide","path":"/resources/tokens/cep78/using-casper-client/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/testing-NFTs","path":"/resources/tokens/cep78/using-casper-client/testing-NFTs","sidebar":"resources"},{"id":"resources/tokens/index","path":"/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/users/undelegate-ui","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/developers","label":"developers/index"}},"operators":{"link":{"path":"/operators","label":"operators/index"}},"resources":{"link":{"path":"/resources/","label":"resources/index"}},"users":{"link":{"path":"/users/","label":"users/index"}},"tutorials":{"link":{"path":"/resources/quick-start","label":"resources/quick-start"}}}}],"breadcrumbs":true}}}'),a=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(22654);const c=JSON.parse('{"docusaurusVersion":"3.5.2","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.5.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.5.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.5.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.5.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.5.2"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.5.2"}}}');var l=n(74848);const d={siteConfig:o.A,siteMetadata:c,globalData:s,i18n:a,codeTranslations:i},u=r.createContext(d);function p(e){let{children:t}=e;return(0,l.jsx)(u.Provider,{value:d,children:t})}},67489:(e,t,n)=>{"use strict";n.d(t,{A:()=>m});var r=n(96540),o=n(38193),s=n(5260),a=n(70440),i=n(79201),c=n(53102),l=n(74848);function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(u,{error:t})]})}function u(e){let{error:t}=e;const n=(0,a.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,l.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,l.jsx)(p,{children:(0,l.jsxs)(m,{fallback:()=>(0,l.jsx)(d,{error:t,tryAgain:n}),children:[(0,l.jsx)(s.A,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(i.A,{children:(0,l.jsx)(d,{error:t,tryAgain:n})})]})})}const g=e=>(0,l.jsx)(f,{...e});class m extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??g)(e)}return e??null}}},38193:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var r=n(80545),o=n(74848);function s(e){return(0,o.jsx)(r.mg,{...e})}},28774:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(96540),o=n(54625),s=n(70440),a=n(44586),i=n(16654),c=n(38193),l=n(63427),d=n(86025),u=n(74848);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:y}=(0,a.A)(),{trailingSlash:x,baseUrl:w}=y,k=y.future.experimental_router,{withBaseUrl:_}=(0,d.hH)(),S=(0,l.A)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const C=p||f;const T=(0,i.A)(C),j=C?.replace("pathname://","");let A=void 0!==j?(R=j,b&&(e=>e.startsWith("/"))(R)?_(R):R):void 0;var R;"hash"===k&&A?.startsWith("./")&&(A=A?.slice(1)),A&&T&&(A=(0,s.Ks)(A,{trailingSlash:x,baseUrl:w}));const P=(0,r.useRef)(!1),N=n?o.k2:o.N_,L=c.A.canUseIntersectionObserver,O=(0,r.useRef)(),D=()=>{P.current||null==A||(window.docusaurus.preload(A),P.current=!0)};(0,r.useEffect)((()=>(!L&&T&&c.A.canUseDOM&&null!=A&&window.docusaurus.prefetch(A),()=>{L&&O.current&&O.current.disconnect()})),[O,A,L,T]);const I=A?.startsWith("#")??!1,M=!v.target||"_self"===v.target,F=!A||!T||!M||I&&"hash"!==k;h||!I&&F||S.collectLink(A),v.id&&S.collectAnchor(v.id);const z={};return F?(0,u.jsx)("a",{ref:E,href:A,...C&&!T&&{target:"_blank",rel:"noopener noreferrer"},...v,...z}):(0,u.jsx)(N,{...v,onMouseEnter:D,onTouchStart:D,innerRef:e=>{E.current=e,L&&e&&T&&(O.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(O.current.unobserve(e),O.current.disconnect(),null!=A&&window.docusaurus.prefetch(A))}))})),O.current.observe(e))},to:A,...n&&{isActive:m,activeClassName:g},...z})}const f=r.forwardRef(p)},21312:(e,t,n)=>{"use strict";n.d(t,{A:()=>l,T:()=>c});var r=n(96540),o=n(74848);function s(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var a=n(22654);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return a[t??n]??n??t}function c(e,t){let{message:n,id:r}=e;return s(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const a=i({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:s(a,r)})}},17065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},16654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},86025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>i,hH:()=>a});var r=n(96540),o=n(44586),s=n(16654);function a(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,a=e.future.experimental_router,i=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:a=!1}={},router:i}=e;if(!r||r.startsWith("#")||(0,s.z)(r))return r;if("hash"===i)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const c=r.startsWith(n)?r:n+r.replace(/^\//,"");return a?t+c:c}({siteUrl:n,baseUrl:t,url:e,options:r,router:a})),[n,t,a]);return{withBaseUrl:i}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=a();return n(e,t)}},63427:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(96540);n(74848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),s=()=>(0,r.useContext)(o);function a(){return s()}},44586:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(26988);function s(){return(0,r.useContext)(o.o)}},92303:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(6125);function s(){return(0,r.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(96540);const o=n(38193).A.canUseDOM?r.useLayoutEffect:r.useEffect},36803:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(53102);function s(){const e=r.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},86921:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[s,a]=n;const i=o?`${o}.${s}`:s;r(a)?e(a,i):t[i]=a}))}(e),t}},53102:(e,t,n)=>{"use strict";n.d(t,{W:()=>a,o:()=>s});var r=n(96540),o=n(74848);const s=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(s),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return(0,o.jsx)(s.Provider,{value:i,children:t})}},53886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>h,XK:()=>y,g1:()=>v});var r=n(96540),o=n(44070),s=n(17065),a=n(6342),i=n(70679),c=n(89532),l=n(74848);const d=e=>`docs-preferred-version-${e}`,u={save:(e,t,n)=>{(0,i.Wf)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,i.Wf)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,i.Wf)(d(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function g(){const e=(0,o.Gy)(),t=(0,a.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[s,i]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{i(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=u.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(u.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[s,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){u.save(e,t,n),i((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=g();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(e){let{children:t}=e;return(0,l.jsx)(m,{children:t})}function b(){const e=(0,r.useContext)(f);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=s.W);const t=(0,o.ht)(e),[n,a]=b(),{preferredVersionName:i}=n[e];return{preferredVersion:t.versions.find((e=>e.name===i))??null,savePreferredVersionName:(0,r.useCallback)((t=>{a.savePreferredVersion(e,t)}),[a,e])}}function y(){const e=(0,o.Gy)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},82565:(e,t,n)=>{"use strict";n.d(t,{k:()=>s,v:()=>a});var r=n(44070),o=n(53886);function s(e,t){return`docs-${e}-${t}`}function a(){const e=(0,r.Gy)(),t=(0,r.gk)(),n=(0,o.XK)();return[...Object.keys(e).map((function(r){const o=t?.activePlugin.pluginId===r?t.activeVersion:void 0,a=n[r],i=e[r].versions.find((e=>e.isLast));return s(r,(o??a??i).name)}))]}},60609:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>l});var r=n(96540),o=n(89532),s=n(74848);const a=Symbol("EmptyContext"),i=r.createContext(a);function c(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,s.jsx)(i.Provider,{value:a,children:t})}function l(){const e=(0,r.useContext)(i);if(e===a)throw new o.dV("DocsSidebarProvider");return e}},26972:(e,t,n)=>{"use strict";n.d(t,{B5:()=>_,Nr:()=>p,OF:()=>y,QB:()=>k,Vd:()=>x,Y:()=>b,fW:()=>w,w8:()=>m});var r=n(96540),o=n(56347),s=n(22831),a=n(44070),i=n(99169),c=n(31682),l=n(53886),d=n(23025),u=n(60609);function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}const f=(e,t)=>void 0!==e&&(0,i.ys)(e,t),g=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||g(e.items,t))}function h(e,t){switch(e.type){case"category":return m(e,t)||e.items.some((e=>h(e,t)));case"link":return!e.unlisted||m(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>h(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const s of t)if("category"===s.type&&((0,i.ys)(s.href,n)||e(s.items))||"link"===s.type&&(0,i.ys)(s.href,n)){return r&&"category"!==s.type||o.unshift(s),!0}return!1}(t),o}function y(){const e=(0,u.t)(),{pathname:t}=(0,o.zy)(),n=(0,a.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,a.zK)(e),{preferredVersion:n}=(0,l.g1)(e),o=(0,a.r7)(e);return(0,r.useMemo)((()=>(0,c.sb)([t,n,o].filter(Boolean))),[t,n,o])}function w(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function _(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,d.r)(),a=t.routes,i=a.find((e=>(0,o.B6)(n.pathname,e)));if(!i)return null;const c=i.sidebar,l=c?r.docsSidebars[c]:void 0;return{docElement:(0,s.v)(a),sidebarName:c,sidebarItems:l}}},23025:(e,t,n)=>{"use strict";n.d(t,{n:()=>i,r:()=>c});var r=n(96540),o=n(89532),s=n(74848);const a=r.createContext(null);function i(e){let{children:t,version:n}=e;return(0,s.jsx)(a.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(a);if(null===e)throw new o.dV("DocsVersionProvider");return e}},44070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>b,vT:()=>f,gk:()=>g,Gy:()=>u,HW:()=>v,ht:()=>p,r7:()=>h,jh:()=>m});var r=n(56347),o=n(44586),s=n(17065);function a(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const i=e=>e.versions.find((e=>e.isLast));function c(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}function l(e,t){const n=c(e,t),o=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const d={},u=()=>a("docusaurus-plugin-content-docs")??d,p=e=>{try{return function(e,t,n){void 0===t&&(t=s.W),void 0===n&&(n={});const r=a(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),s=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!s&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return s}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.zy)();if(!t)return;return{activePlugin:t,activeVersion:c(t.pluginData,n)}}function m(e){return p(e).versions}function h(e){const t=p(e);return i(t)}function b(e){const t=p(e),{pathname:n}=(0,r.zy)();return l(t,n)}function v(e){const t=p(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=i(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},76294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(5947),o=n.n(r);o().configure({showSpinner:!1});const s={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},26134:(e,t,n)=>{"use strict";n.r(t);var r=n(71765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.A,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(19700),n(18692)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},51107:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(34164),o=n(21312),s=n(6342),a=n(28774),i=n(63427);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(74848);function d(e){let{as:t,id:n,...d}=e;const u=(0,i.A)(),{navbar:{hideOnScroll:p}}=(0,s.p)();if("h1"===t||!n)return(0,l.jsx)(t,{...d,id:void 0});u.collectAnchor(n);const f=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof d.children?d.children:n});return(0,l.jsxs)(t,{...d,className:(0,r.A)("anchor",p?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,d.className),id:n,children:[d.children,(0,l.jsx)(a.A,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},43186:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(74848);function s(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},79201:(e,t,n)=>{"use strict";n.d(t,{A:()=>Dt});var r=n(96540),o=n(34164),s=n(67489),a=n(45500),i=n(56347),c=n(21312),l=n(75062),d=n(74848);const u="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,i.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(u);t&&p(t)}),[]);return(0,l.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,d.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,d.jsx)("a",{...e,href:`#${u}`,onClick:r,children:t})})}var h=n(17559),b=n(14090);const v={skipToContent:"skipToContent_fXgn"};function y(){return(0,d.jsx)(m,{className:v.skipToContent})}var x=n(6342),w=n(65041);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:s,...a}=e;return(0,d.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...a,children:(0,d.jsx)("g",{stroke:r,strokeWidth:o,children:(0,d.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const _={closeButton:"closeButton_CVFx"};function S(e){return(0,d.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",_.closeButton,e.className),children:(0,d.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,x.p)(),{content:n}=t;return(0,d.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function j(){const{announcementBar:e}=(0,x.p)(),{isActive:t,close:n}=(0,w.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:s}=e;return(0,d.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[s&&(0,d.jsx)("div",{className:T.announcementBarPlaceholder}),(0,d.jsx)(C,{className:T.announcementBarContent}),s&&(0,d.jsx)(S,{onClick:n,className:T.announcementBarClose})]})}var A=n(22069),R=n(23104);var P=n(89532),N=n(75600);const L=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,A.M)(),t=(0,N.YL)(),[n,o]=(0,r.useState)(!1),s=null!==t.component,a=(0,P.ZC)(s);return(0,r.useEffect)((()=>{s&&!a&&o(!0)}),[s,a]),(0,r.useEffect)((()=>{s?e.shown||o(!0):o(!1)}),[e.shown,s]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,d.jsx)(L.Provider,{value:n,children:t})}function D(e){if(e.component){const t=e.component;return(0,d.jsx)(t,{...e.props})}}function I(){const e=(0,r.useContext)(L);if(!e)throw new P.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),s=(0,N.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:D(s)})),[o,s,t])}function M(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:s}=I();return(0,d.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,d.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s}),children:[(0,d.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,d.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var F=n(95293),z=n(92303);function B(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,d.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function U(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,d.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:s}=e;const a=(0,z.A)(),i=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,d.jsx)("div",{className:(0,o.A)($.toggle,t),children:(0,d.jsxs)("button",{className:(0,o.A)("clean-btn",$.toggleButton,!a&&$.toggleButtonDisabled,n),type:"button",onClick:()=>s("dark"===r?"light":"dark"),disabled:!a,title:i,"aria-label":i,"aria-live":"polite",children:[(0,d.jsx)(B,{className:(0,o.A)($.toggleIcon,$.lightToggleIcon)}),(0,d.jsx)(U,{className:(0,o.A)($.toggleIcon,$.darkToggleIcon)})]})})}const X=r.memo(q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function G(e){let{className:t}=e;const n=(0,x.p)().navbar.style,r=(0,x.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:s}=(0,F.G)();return r?null:(0,d.jsx)(X,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:s})}var V=n(23465);function W(){return(0,d.jsx)(V.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,A.M)();return(0,d.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,d.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function Q(){return(0,d.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,d.jsx)(W,{}),(0,d.jsx)(G,{className:"margin-right--md"}),(0,d.jsx)(K,{})]})}var Y=n(28774),Z=n(86025),J=n(16654),ee=n(91252),te=n(43186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:s,html:a,isDropdownLink:i,prependBaseUrlToHref:c,...l}=e;const u=(0,Z.Ay)(r),p=(0,Z.Ay)(t),f=(0,Z.Ay)(o,{forcePrependBaseUrl:!0}),g=s&&o&&!(0,J.A)(o),m=a?{dangerouslySetInnerHTML:{__html:a}}:{children:(0,d.jsxs)(d.Fragment,{children:[s,g&&(0,d.jsx)(te.A,{...i&&{width:12,height:12}})]})};return o?(0,d.jsx)(Y.A,{href:c?f:o,...l,...m}):(0,d.jsx)(Y.A,{to:u,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.G)(n,t.pathname):t.pathname.startsWith(p)},...l,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const s=(0,d.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,d.jsx)("li",{children:s}):s}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,d.jsx)("li",{className:"menu__list-item",children:(0,d.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function se(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,d.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ae=n(41422),ie=n(99169),ce=n(44586);const le={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function de(e,t){return e.some((e=>function(e,t){return!!(0,ie.ys)(e.to,t)||!!(0,ee.G)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ue(e){let{items:t,position:n,className:s,onClick:a,...i}=e;const c=(0,r.useRef)(null),[l,u]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&u(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,d.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":l}),children:[(0,d.jsx)(ne,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:i.to?void 0:"#",className:(0,o.A)("navbar__link",s),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),u(!l))},children:i.children??i.label}),(0,d.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ve,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:s,onClick:a,...c}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,i.zy)();return t.replace(e,"/")}(),u=de(t,l),{collapsed:p,toggleCollapsed:f,setCollapsed:g}=(0,ae.u)({initialState:()=>!u});return(0,r.useEffect)((()=>{u&&g(!u)}),[l,u,g]),(0,d.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,d.jsx)(ne,{role:"button",className:(0,o.A)(le.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),f()},children:c.children??c.label}),(0,d.jsx)(ae.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Ve,{mobile:!0,isDropdownItem:!0,onClick:a,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:ue;return(0,d.jsx)(r,{...n})}var ge=n(32131);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,d.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";var be=n(40961);function ve(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var ye=n(89188),xe=["translations"];function we(){return we=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},we.apply(this,arguments)}function ke(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,o,s=[],a=!0,i=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(s.push(r.value),!t||s.length!==t);a=!0);}catch(c){i=!0,o=c}finally{try{a||null==n.return||n.return()}finally{if(i)throw o}}return s}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return _e(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _e(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function _e(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Se(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Ee="Ctrl";var Ce=r.forwardRef((function(e,t){var n=e.translations,o=void 0===n?{}:n,s=Se(e,xe),a=o.buttonText,i=void 0===a?"Search":a,c=o.buttonAriaLabel,l=void 0===c?"Search":c,d=ke((0,r.useState)(null),2),u=d[0],p=d[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?p("\u2318"):p(Ee))}),[]),r.createElement("button",we({type:"button",className:"DocSearch DocSearch-Button","aria-label":l},s,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(ye.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},i)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==u&&r.createElement(r.Fragment,null,r.createElement(Te,{reactsToKey:u===Ee?Ee:"Meta"},u===Ee?r.createElement(ve,null):u),r.createElement(Te,{reactsToKey:"k"},"K"))))}));function Te(e){var t=e.reactsToKey,n=e.children,o=ke((0,r.useState)(!1),2),s=o[0],a=o[1];return(0,r.useEffect)((function(){if(t)return window.addEventListener("keydown",e),window.addEventListener("keyup",n),function(){window.removeEventListener("keydown",e),window.removeEventListener("keyup",n)};function e(e){e.key===t&&a(!0)}function n(e){e.key!==t&&"Meta"!==e.key||a(!1)}}),[t]),r.createElement("kbd",{className:s?"DocSearch-Button-Key DocSearch-Button-Key--pressed":"DocSearch-Button-Key"},n)}var je=n(5260),Ae=n(24255),Re=n(51062),Pe=n(2967),Ne=n(82565);function Le(){return[`language:${(0,ce.A)().i18n.currentLocale}`,function(){const e=(0,Ne.v)();return[Pe.C,...e]}().map((e=>`docusaurus_tag:${e}`))]}const Oe={button:{buttonText:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,c.T)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,c.T)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,c.T)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,c.T)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,c.T)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,c.T)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,c.T)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,c.T)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let De=null;function Ie(e){let{hit:t,children:n}=e;return(0,d.jsx)(Y.A,{to:t.url,children:n})}function Me(e){let{state:t,onClose:n}=e;const r=(0,Ae.w)();return(0,d.jsx)(Y.A,{to:r(t.query),onClick:n,children:(0,d.jsx)(c.A,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Fe(e){let{contextualSearch:t,externalUrlRegex:o,...s}=e;const{siteMetadata:a}=(0,ce.A)(),c=(0,Re.C)(),l=Le(),u=s.searchParameters?.facetFilters??[],p=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(l,u):u,f={...s.searchParameters,facetFilters:p},g=(0,i.W6)(),m=(0,r.useRef)(null),h=(0,r.useRef)(null),[b,v]=(0,r.useState)(!1),[y,x]=(0,r.useState)(void 0),w=(0,r.useCallback)((()=>De?Promise.resolve():Promise.all([n.e(9462).then(n.bind(n,9462)),Promise.all([n.e(1869),n.e(8913)]).then(n.bind(n,58913)),Promise.all([n.e(1869),n.e(416)]).then(n.bind(n,90416))]).then((e=>{let[{DocSearchModal:t}]=e;De=t}))),[]),k=(0,r.useCallback)((()=>{if(!m.current){const e=document.createElement("div");m.current=e,document.body.insertBefore(e,document.body.firstChild)}}),[]),_=(0,r.useCallback)((()=>{k(),w().then((()=>v(!0)))}),[w,k]),S=(0,r.useCallback)((()=>{v(!1),h.current?.focus()}),[]),E=(0,r.useCallback)((e=>{"f"===e.key&&(e.metaKey||e.ctrlKey)||(e.preventDefault(),x(e.key),_())}),[_]),C=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.G)(o,t)?window.location.href=t:g.push(t)}}).current,T=(0,r.useRef)((e=>s.transformItems?s.transformItems(e):e.map((e=>({...e,url:c(e.url)}))))).current,j=(0,r.useMemo)((()=>e=>(0,d.jsx)(Me,{...e,onClose:S})),[S]),A=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",a.docusaurusVersion),e)),[a.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,s=e.onInput,a=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),a&&a.current===document.activeElement&&s&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&s(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,s,a])}({isOpen:b,onOpen:_,onClose:S,onInput:E,searchButtonRef:h}),(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(je.A,{children:(0,d.jsx)("link",{rel:"preconnect",href:`https://${s.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,d.jsx)(Ce,{onTouchStart:w,onFocus:w,onMouseOver:w,onClick:_,ref:h,translations:Oe.button}),b&&De&&m.current&&(0,be.createPortal)((0,d.jsx)(De,{onClose:S,initialScrollY:window.scrollY,initialQuery:y,navigator:C,transformItems:T,hitComponent:Ie,transformSearchClient:A,...s.searchPagePath&&{resultsFooterComponent:j},...s,searchParameters:f,placeholder:Oe.placeholder,translations:Oe.modal}),m.current)]})}function ze(){const{siteConfig:e}=(0,ce.A)();return(0,d.jsx)(Fe,{...e.themeConfig.algolia})}const Be={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Ue(e){let{children:t,className:n}=e;return(0,d.jsx)("div",{className:(0,o.A)(n,Be.navbarSearchContainer),children:t})}var $e=n(44070),qe=n(26972);var Xe=n(53886);function He(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ge={default:se,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...s}=e;const{i18n:{currentLocale:a,locales:l,localeConfigs:u}}=(0,ce.A)(),p=(0,ge.o)(),{search:f,hash:g}=(0,i.zy)(),m=[...n,...l.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${o}`;return{label:u[e].label,lang:u[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===a?t?"menu__link--active":"dropdown__link--active":""}})),...r],h=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):u[a].label;return(0,d.jsx)(fe,{...s,mobile:t,label:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(me,{className:he}),h]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,d.jsx)(Ue,{className:n,children:(0,d.jsx)(ze,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:s=!1}=e;const a=s?"li":"div";return(0,d.jsx)(a,{className:(0,o.A)({navbar__item:!r&&!s,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:s}=(0,$e.zK)(r),a=(0,qe.QB)(t,r),i=s?.path===a?.path;return null===a||a.unlisted&&!i?null:(0,d.jsx)(se,{exact:!0,...o,isActive:()=>i||!!s?.sidebar&&s.sidebar===a.sidebar,label:n??a.id,to:a.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:s}=(0,$e.zK)(r),a=(0,qe.fW)(t,r).link;if(!a)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,d.jsx)(se,{exact:!0,...o,isActive:()=>s?.sidebar===t,label:n??a.label,to:a.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const s=(0,qe.Vd)(r)[0],a=t??s.label,i=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(s).path;return(0,d.jsx)(se,{...o,label:a,to:i})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:s,...a}=e;const{search:l,hash:u}=(0,i.zy)(),p=(0,$e.zK)(n),f=(0,$e.jh)(n),{savePreferredVersionName:g}=(0,Xe.g1)(n),m=[...o,...f.map((function(e){const t=He(e,p);return{label:e.label,to:`${t.path}${l}${u}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...s],h=(0,qe.Vd)(n)[0],b=t&&m.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,v=t&&m.length>1?void 0:He(h,p).path;return m.length<=1?(0,d.jsx)(se,{...a,mobile:t,label:b,to:v,isActive:r?()=>!1:void 0}):(0,d.jsx)(fe,{...a,mobile:t,label:b,to:v,items:m,isActive:r?()=>!1:void 0})}};function Ve(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ge[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,d.jsx)(o,{...n})}function We(){const e=(0,A.M)(),t=(0,x.p)().navbar.items;return(0,d.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ve,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ke(e){return(0,d.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,d.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Qe(){const e=0===(0,x.p)().navbar.items.length,t=I();return(0,d.jsxs)(d.Fragment,{children:[!e&&(0,d.jsx)(Ke,{onClick:()=>t.hide()}),t.content]})}function Ye(){const e=(0,A.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,d.jsx)(M,{header:(0,d.jsx)(Q,{}),primaryMenu:(0,d.jsx)(We,{}),secondaryMenu:(0,d.jsx)(Qe,{})}):null}const Ze={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,d.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:s}}=(0,x.p)(),a=(0,A.M)(),{navbarRef:i,isNavbarVisible:u}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),s=(0,r.useRef)(0),a=(0,r.useCallback)((e=>{null!==e&&(s.current=e.getBoundingClientRect().height)}),[]);return(0,R.Mq)(((t,r)=>{let{scrollY:a}=t;if(!e)return;if(a<s.current)return void n(!0);if(o.current)return void(o.current=!1);const i=r?.scrollY,c=document.documentElement.scrollHeight-s.current,l=window.innerHeight;i&&a>=i?n(!1):a+l<c&&n(!0)})),(0,l.$)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:a,isNavbarVisible:t}}(n);return(0,d.jsxs)("nav",{ref:i,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Ze.navbarHideable,!u&&Ze.navbarHidden],{"navbar--dark":"dark"===s,"navbar--primary":"primary"===s,"navbar-sidebar--show":a.shown}),children:[t,(0,d.jsx)(Je,{onClick:a.toggle}),(0,d.jsx)(Ye,{})]})}var tt=n(70440);const nt={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function rt(e){return(0,d.jsx)("button",{type:"button",...e,children:(0,d.jsx)(c.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function ot(e){let{error:t}=e;const n=(0,tt.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,d.jsx)("p",{className:nt.errorBoundaryError,children:n})}class st extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const at="right";function it(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,d.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,d.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ct(){const{toggle:e,shown:t}=(0,A.M)();return(0,d.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,d.jsx)(it,{})})}const lt={colorModeToggle:"colorModeToggle_DEke"};function dt(e){let{items:t}=e;return(0,d.jsx)(d.Fragment,{children:t.map(((e,t)=>(0,d.jsx)(st,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,d.jsx)(Ve,{...e})},t)))})}function ut(e){let{left:t,right:n}=e;return(0,d.jsxs)("div",{className:"navbar__inner",children:[(0,d.jsx)("div",{className:"navbar__items",children:t}),(0,d.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function pt(){const e=(0,A.M)(),t=(0,x.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??at)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,d.jsx)(ut,{left:(0,d.jsxs)(d.Fragment,{children:[!e.disabled&&(0,d.jsx)(ct,{}),(0,d.jsx)(W,{}),(0,d.jsx)(dt,{items:n})]}),right:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(dt,{items:r}),(0,d.jsx)(G,{className:lt.colorModeToggle}),!o&&(0,d.jsx)(Ue,{children:(0,d.jsx)(ze,{})})]})})}function ft(){return(0,d.jsx)(et,{children:(0,d.jsx)(pt,{})})}function gt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:s,...a}=t,i=(0,Z.Ay)(n),c=(0,Z.Ay)(r,{forcePrependBaseUrl:!0});return(0,d.jsxs)(Y.A,{className:"footer__link-item",...r?{href:s?c:r}:{to:i},...a,children:[o,r&&!(0,J.A)(r)&&(0,d.jsx)(te.A,{})]})}function mt(e){let{item:t}=e;return t.html?(0,d.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,d.jsx)("li",{className:"footer__item",children:(0,d.jsx)(gt,{item:t})},t.href??t.to)}function ht(e){let{column:t}=e;return(0,d.jsxs)("div",{className:"col footer__col",children:[(0,d.jsx)("div",{className:"footer__title",children:t.title}),(0,d.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,d.jsx)(mt,{item:e},t)))})]})}function bt(e){let{columns:t}=e;return(0,d.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,d.jsx)(ht,{column:e},t)))})}function vt(){return(0,d.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function yt(e){let{item:t}=e;return t.html?(0,d.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,d.jsx)(gt,{item:t})}function xt(e){let{links:t}=e;return(0,d.jsx)("div",{className:"footer__links text--center",children:(0,d.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,d.jsxs)(r.Fragment,{children:[(0,d.jsx)(yt,{item:e}),t.length!==n+1&&(0,d.jsx)(vt,{})]},n)))})})}function wt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,d.jsx)(bt,{columns:t}):(0,d.jsx)(xt,{links:t})}var kt=n(21122);const _t={footerLogoLink:"footerLogoLink_BH7S"};function St(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Z.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,d.jsx)(kt.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function Et(e){let{logo:t}=e;return t.href?(0,d.jsx)(Y.A,{href:t.href,className:_t.footerLogoLink,target:t.target,children:(0,d.jsx)(St,{logo:t})}):(0,d.jsx)(St,{logo:t})}function Ct(e){let{copyright:t}=e;return(0,d.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Tt(e){let{style:t,links:n,logo:r,copyright:s}=e;return(0,d.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,d.jsxs)("div",{className:"container container-fluid",children:[n,(r||s)&&(0,d.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,d.jsx)("div",{className:"margin-bottom--sm",children:r}),s]})]})})}function jt(){const{footer:e}=(0,x.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,d.jsx)(Tt,{style:o,links:n&&n.length>0&&(0,d.jsx)(wt,{links:n}),logo:r&&(0,d.jsx)(Et,{logo:r}),copyright:t&&(0,d.jsx)(Ct,{copyright:t})})}const At=r.memo(jt),Rt=(0,P.fM)([F.a,w.o,R.Tv,Xe.VQ,a.Jx,function(e){let{children:t}=e;return(0,d.jsx)(N.y_,{children:(0,d.jsx)(A.e,{children:(0,d.jsx)(O,{children:t})})})}]);function Pt(e){let{children:t}=e;return(0,d.jsx)(Rt,{children:t})}var Nt=n(51107);function Lt(e){let{error:t,tryAgain:n}=e;return(0,d.jsx)("main",{className:"container margin-vert--xl",children:(0,d.jsx)("div",{className:"row",children:(0,d.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,d.jsx)(Nt.A,{as:"h1",className:"hero__title",children:(0,d.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,d.jsx)("div",{className:"margin-vert--lg",children:(0,d.jsx)(rt,{onClick:n,className:"button button--primary shadow--lw"})}),(0,d.jsx)("hr",{}),(0,d.jsx)("div",{className:"margin-vert--md",children:(0,d.jsx)(ot,{error:t})})]})})})}const Ot={mainWrapper:"mainWrapper_z2l0"};function Dt(e){const{children:t,noFooter:n,wrapperClassName:r,title:i,description:c}=e;return(0,b.J)(),(0,d.jsxs)(Pt,{children:[(0,d.jsx)(a.be,{title:i,description:c}),(0,d.jsx)(y,{}),(0,d.jsx)(j,{}),(0,d.jsx)(ft,{}),(0,d.jsx)("div",{id:u,className:(0,o.A)(h.G.wrapper.main,Ot.mainWrapper,r),children:(0,d.jsx)(s.A,{fallback:e=>(0,d.jsx)(Lt,{...e}),children:t})}),!n&&(0,d.jsx)(At,{})]})}},23465:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(28774),o=n(86025),s=n(44586),a=n(6342),i=n(21122),c=n(74848);function l(e){let{logo:t,alt:n,imageClassName:r}=e;const s={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},a=(0,c.jsx)(i.A,{className:t.className,sources:s,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,c.jsx)("div",{className:r,children:a}):a}function d(e){const{siteConfig:{title:t}}=(0,s.A)(),{navbar:{title:n,logo:i}}=(0,a.p)(),{imageClassName:d,titleClassName:u,...p}=e,f=(0,o.Ay)(i?.href||"/"),g=n?"":t,m=i?.alt??g;return(0,c.jsxs)(r.A,{to:f,...p,...i?.target&&{target:i.target},children:[i&&(0,c.jsx)(l,{logo:i,alt:m,imageClassName:d}),null!=n&&(0,c.jsx)("b",{className:u,children:n})]})}},41463:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var r=n(5260),o=n(74848);function s(e){let{locale:t,version:n,tag:s}=e;const a=t;return(0,o.jsxs)(r.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),s&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:s}),a&&(0,o.jsx)("meta",{name:"docsearch:language",content:a}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),s&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:s})]})}},21122:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});var r=n(96540),o=n(34164),s=n(92303),a=n(95293);const i={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(74848);function l(e){let{className:t,children:n}=e;const l=(0,s.A)(),{colorMode:d}=(0,a.G)();return(0,c.jsx)(c.Fragment,{children:(l?"dark"===d?["dark"]:["light"]:["light","dark"]).map((e=>{const s=n({theme:e,className:(0,o.A)(t,i.themedComponent,i[`themedComponent--${e}`])});return(0,c.jsx)(r.Fragment,{children:s},e)}))})}function d(e){const{sources:t,className:n,alt:r,...o}=e;return(0,c.jsx)(l,{className:n,children:e=>{let{theme:n,className:s}=e;return(0,c.jsx)("img",{src:t[n],alt:r,className:s,...o})}})}},41422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>l});var r=n(96540),o=n(38193),s=n(205),a=n(53109),i=n(74848);const c="ease-in-out";function l(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),s=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:s}}const d={display:"none",overflow:"hidden",height:"0px"},u={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?d:u;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const s=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,a.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function i(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!s.current)return p(e,n),void(s.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=d.height,e.style.overflow=d.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function g(e){if(!o.A.canUseDOM)return e?d:u}function m(e){let{as:t="div",collapsed:n,children:o,animation:s,onCollapseTransitionEnd:a,className:c,disableSSRStyle:l}=e;const d=(0,r.useRef)(null);return f({collapsibleRef:d,collapsed:n,animation:s}),(0,i.jsx)(t,{ref:d,style:l?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(d.current,n),a?.(n))},className:c,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,a]=(0,r.useState)(!t),[c,l]=(0,r.useState)(t);return(0,s.A)((()=>{t||a(!0)}),[t]),(0,s.A)((()=>{o&&l(t)}),[o,t]),o?(0,i.jsx)(m,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const r=t?h:m;return(0,i.jsx)(r,{...n})}},65041:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,o:()=>g});var r=n(96540),o=n(92303),s=n(70679),a=n(89532),i=n(6342),c=n(74848);const l=(0,s.Wf)("docusaurus.announcement.dismiss"),d=(0,s.Wf)("docusaurus.announcement.id"),u=()=>"true"===l.get(),p=e=>l.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,i.p)(),t=(0,o.A)(),[n,s]=(0,r.useState)((()=>!!t&&u()));(0,r.useEffect)((()=>{s(u())}),[]);const a=(0,r.useCallback)((()=>{p(!0),s(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=d.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;d.set(t),r&&p(!1),!r&&u()||s(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:a})),[e,n,a])}();return(0,c.jsx)(f.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(f);if(!e)throw new a.dV("AnnouncementBarProvider");return e}},95293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>h});var r=n(96540),o=n(38193),s=n(89532),a=n(70679),i=n(6342),c=n(74848);const l=r.createContext(void 0),d="theme",u=(0,a.Wf)(d),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,g=e=>o.A.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{u.set(f(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),[o,s]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const a=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(s(t),o&&m(t)):(s(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==d)return;const t=u.get();null!==t&&a(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,a]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:a(null)};return e.addListener(r),()=>e.removeListener(r)}),[a,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:a,get isDarkTheme(){return o===p.dark},setLightTheme(){a(p.light)},setDarkTheme(){a(p.dark)}})),[o,a])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(l);if(null==e)throw new s.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},22069:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>p});var r=n(96540),o=n(75600),s=n(24581),a=n(57485),i=n(6342),c=n(89532),l=n(74848);const d=r.createContext(void 0);function u(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,i.p)().navbar;return 0===t.length&&!e.component}(),t=(0,s.l)(),n=!e&&"mobile"===t,[c,l]=(0,r.useState)(!1);(0,a.$Z)((()=>{if(c)return l(!1),!1}));const d=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:d,shown:c})),[e,n,d,c])}function p(e){let{children:t}=e;const n=u();return(0,l.jsx)(d.Provider,{value:n,children:t})}function f(){const e=r.useContext(d);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},75600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>l,YL:()=>c,y_:()=>i});var r=n(96540),o=n(89532),s=n(74848);const a=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,s.jsx)(a.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(a);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const s=(0,r.useContext)(a);if(!s)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,i]=s,c=(0,o.Be)(n);return(0,r.useEffect)((()=>{i({component:t,props:c})}),[i,t,c]),(0,r.useEffect)((()=>()=>i({component:null,props:null})),[i]),null}},14090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>s});var r=n(96540);const o="navigation-with-keyboard";function s(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},24255:(e,t,n)=>{"use strict";n.d(t,{b:()=>i,w:()=>c});var r=n(96540),o=n(44586),s=n(57485);const a="q";function i(){return(0,s.l)(a)}function c(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,o.A)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${a}=${encodeURIComponent(t)}`),[e,n])}},24581:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(96540),o=n(38193);const s={desktop:"desktop",mobile:"mobile",ssr:"ssr"},a=996;function i(e){let{desktopBreakpoint:t=a}=void 0===e?{}:e;const[n,i]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){i(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?s.desktop:s.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},17559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},53109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},20481:(e,t,n)=>{"use strict";n.d(t,{s:()=>o});var r=n(44586);function o(e){const{siteConfig:t}=(0,r.A)(),{title:n,titleDelimiter:o}=t;return e?.trim().length?`${e.trim()} ${o} ${n}`:n}},57485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>a,l:()=>c});var r=n(96540),o=n(56347),s=n(89532);function a(e){!function(e){const t=(0,o.W6)(),n=(0,s._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function i(e){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){const t=function(e){return i((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}(e)??"",n=function(e){const t=(0,o.W6)();return(0,r.useCallback)(((n,r)=>{const o=new URLSearchParams(t.location.search);n?o.set(e,n):o.delete(e),(r?.push?t.push:t.replace)({search:o.toString()})}),[e,t])}(e);return[t,n]}},31682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function o(e,t){const n={};let r=0;for(const o of e){const e=t(o,r);n[e]??=[],n[e].push(o),r+=1}return n}n.d(t,{$z:()=>o,sb:()=>r})},45500:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>f,be:()=>d,e3:()=>p});var r=n(96540),o=n(34164),s=n(5260),a=n(36803),i=n(86025),c=n(20481),l=n(74848);function d(e){let{title:t,description:n,keywords:r,image:o,children:a}=e;const d=(0,c.s)(t),{withBaseUrl:u}=(0,i.hH)(),p=o?u(o,{absolute:!0}):void 0;return(0,l.jsxs)(s.A,{children:[t&&(0,l.jsx)("title",{children:d}),t&&(0,l.jsx)("meta",{property:"og:title",content:d}),n&&(0,l.jsx)("meta",{name:"description",content:n}),n&&(0,l.jsx)("meta",{property:"og:description",content:n}),r&&(0,l.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,l.jsx)("meta",{property:"og:image",content:p}),p&&(0,l.jsx)("meta",{name:"twitter:image",content:p}),a]})}const u=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const a=r.useContext(u),i=(0,o.A)(a,t);return(0,l.jsxs)(u.Provider,{value:i,children:[(0,l.jsx)(s.A,{children:(0,l.jsx)("html",{className:i})}),n]})}function f(e){let{children:t}=e;const n=(0,a.A)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const s=`plugin-id-${n.plugin.id}`;return(0,l.jsx)(p,{className:(0,o.A)(r,s),children:t})}},89532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>l,ZC:()=>i,_q:()=>a,dV:()=>c,fM:()=>d});var r=n(96540),o=n(205),s=n(74848);function a(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function d(e){return t=>{let{children:n}=t;return(0,s.jsx)(s.Fragment,{children:e.reduceRight(((e,t)=>(0,s.jsx)(t,{children:e})),n)})}}},91252:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{G:()=>r})},99169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>i,ys:()=>a});var r=n(96540),o=n(35947),s=n(44586);function a(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function i(){const{baseUrl:e}=(0,s.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},23104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>p,Tv:()=>l,gk:()=>f});var r=n(96540),o=n(38193),s=n(92303),a=(n(205),n(89532)),i=n(74848);const c=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,i.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new a.dV("ScrollControllerProvider");return e}const u=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function p(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(u()),s=(0,a._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=u();s(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[s,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,s.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{C:()=>r});const r="default"},70679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>l});n(96540);const r=JSON.parse('{"N":"localStorage","M":""}'),o=r.N;function s(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const s=document.createEvent("StorageEvent");s.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(s)}function a(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const o=a(t?.persistence);return null===o?c:{get:()=>{try{return o.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=o.getItem(n);o.setItem(n,e),s({key:n,oldValue:t,newValue:e,storage:o})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=o.getItem(n);o.removeItem(n),s({key:n,oldValue:e,newValue:null,storage:o})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===o&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},32131:(e,t,n)=>{"use strict";n.d(t,{o:()=>a});var r=n(44586),o=n(56347),s=n(70440);function a(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:a,currentLocale:i}}=(0,r.A)(),{pathname:c}=(0,o.zy)(),l=(0,s.Ks)(c,{trailingSlash:n,baseUrl:e}),d=i===a?e:e.replace(`/${i}/`,"/"),u=l.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===a?`${d}`:`${d}${e}/`}(n)}${u}`}}}},75062:(e,t,n)=>{"use strict";n.d(t,{$:()=>a});var r=n(96540),o=n(56347),s=n(89532);function a(e){const t=(0,o.zy)(),n=(0,s.ZC)(t),a=(0,s._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&a({location:t,previousLocation:n})}),[a,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(44586);function o(){return(0,r.A)().siteConfig.themeConfig}},38126:(e,t,n)=>{"use strict";n.d(t,{c:()=>o});var r=n(44586);function o(){const{siteConfig:{themeConfig:e}}=(0,r.A)();return e}},51062:(e,t,n)=>{"use strict";n.d(t,{C:()=>i});var r=n(96540),o=n(91252),s=n(86025),a=n(38126);function i(){const{withBaseUrl:e}=(0,s.hH)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,a.c)();return(0,r.useCallback)((r=>{const s=new URL(r);if((0,o.G)(t,s.href))return r;const a=`${s.pathname+s.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(a,n))}),[e,t,n])}},12983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),i="/"===a||a===r?a:(c=a,l=n,l?o(c):s(c));var c,l;return e.replace(a,i)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=s;const r=n(42566);function o(e){return e.endsWith("/")?e:`${e}/`}function s(e){return(0,r.removeSuffix)(e,"/")}},80253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},70440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(31635);t.LU="__blog-post-container";var o=n(12983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var s=n(42566);var a=n(80253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},42566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>x,TM:()=>C,yJ:()=>f,sC:()=>j,AO:()=>p});var r=n(58168);function o(e){return"/"===e.charAt(0)}function s(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const a=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],a=t&&t.split("/")||[],i=e&&o(e),c=t&&o(t),l=i||c;if(e&&o(e)?a=r:r.length&&(a.pop(),a=a.concat(r)),!a.length)return"/";if(a.length){var d=a[a.length-1];n="."===d||".."===d||""===d}else n=!1;for(var u=0,p=a.length;p>=0;p--){var f=a[p];"."===f?s(a,p):".."===f?(s(a,p),u++):u&&(s(a,p),u--)}if(!l)for(;u--;u)a.unshift("..");!l||""===a[0]||a[0]&&o(a[0])||a.unshift("");var g=a.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var i=n(11561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function d(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function u(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var s;"string"==typeof e?(s=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var s=t.indexOf("?");return-1!==s&&(n=t.substr(s),t=t.substr(0,s)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),s.state=t):(void 0===(s=(0,r.A)({},e)).pathname&&(s.pathname=""),s.search?"?"!==s.search.charAt(0)&&(s.search="?"+s.search):s.search="",s.hash?"#"!==s.hash.charAt(0)&&(s.hash="#"+s.hash):s.hash="",void 0!==t&&void 0===s.state&&(s.state=t));try{s.pathname=decodeURI(s.pathname)}catch(i){throw i instanceof URIError?new URIError('Pathname "'+s.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):i}return n&&(s.key=n),o?s.pathname?"/"!==s.pathname.charAt(0)&&(s.pathname=a(s.pathname,o.pathname)):s.pathname=o.pathname:s.pathname||(s.pathname="/"),s}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var s="function"==typeof e?e(t,n):e;"string"==typeof s?"function"==typeof r?r(s,o):o(!0):o(!1!==s)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var m=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function x(e){void 0===e&&(e={}),m||(0,i.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,s=!(-1===window.navigator.userAgent.indexOf("Trident")),a=e,l=a.forceRefresh,x=void 0!==l&&l,w=a.getUserConfirmation,k=void 0===w?h:w,_=a.keyLength,S=void 0===_?6:_,E=e.basename?u(c(e.basename)):"";function C(e){var t=e||{},n=t.key,r=t.state,o=window.location,s=o.pathname+o.search+o.hash;return E&&(s=d(s,E)),f(s,r,n)}function T(){return Math.random().toString(36).substr(2,S)}var j=g();function A(e){(0,r.A)(U,e),U.length=n.length,j.notifyListeners(U.location,U.action)}function R(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||L(C(e.state))}function P(){L(C(y()))}var N=!1;function L(e){if(N)N=!1,A();else{j.confirmTransitionTo(e,"POP",k,(function(t){t?A({action:"POP",location:e}):function(e){var t=U.location,n=D.indexOf(t.key);-1===n&&(n=0);var r=D.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(N=!0,M(o))}(e)}))}}var O=C(y()),D=[O.key];function I(e){return E+p(e)}function M(e){n.go(e)}var F=0;function z(e){1===(F+=e)&&1===e?(window.addEventListener(b,R),s&&window.addEventListener(v,P)):0===F&&(window.removeEventListener(b,R),s&&window.removeEventListener(v,P))}var B=!1;var U={length:n.length,action:"POP",location:O,createHref:I,push:function(e,t){var r="PUSH",s=f(e,t,T(),U.location);j.confirmTransitionTo(s,r,k,(function(e){if(e){var t=I(s),a=s.key,i=s.state;if(o)if(n.pushState({key:a,state:i},null,t),x)window.location.href=t;else{var c=D.indexOf(U.location.key),l=D.slice(0,c+1);l.push(s.key),D=l,A({action:r,location:s})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",s=f(e,t,T(),U.location);j.confirmTransitionTo(s,r,k,(function(e){if(e){var t=I(s),a=s.key,i=s.state;if(o)if(n.replaceState({key:a,state:i},null,t),x)window.location.replace(t);else{var c=D.indexOf(U.location.key);-1!==c&&(D[c]=s.key),A({action:r,location:s})}else window.location.replace(t)}}))},go:M,goBack:function(){M(-1)},goForward:function(){M(1)},block:function(e){void 0===e&&(e=!1);var t=j.setPrompt(e);return B||(z(1),B=!0),function(){return B&&(B=!1,z(-1)),t()}},listen:function(e){var t=j.appendListener(e);return z(1),function(){z(-1),t()}}};return U}var w="hashchange",k={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+l(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:l,decodePath:c},slash:{encodePath:c,decodePath:c}};function _(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function S(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(_(window.location.href)+"#"+e)}function C(e){void 0===e&&(e={}),m||(0,i.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,s=void 0===o?h:o,a=n.hashType,l=void 0===a?"slash":a,b=e.basename?u(c(e.basename)):"",v=k[l],y=v.encodePath,x=v.decodePath;function C(){var e=x(S());return b&&(e=d(e,b)),f(e)}var T=g();function j(e){(0,r.A)(B,e),B.length=t.length,T.notifyListeners(B.location,B.action)}var A=!1,R=null;function P(){var e,t,n=S(),r=y(n);if(n!==r)E(r);else{var o=C(),a=B.location;if(!A&&(t=o,(e=a).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(R===p(o))return;R=null,function(e){if(A)A=!1,j();else{var t="POP";T.confirmTransitionTo(e,t,s,(function(n){n?j({action:t,location:e}):function(e){var t=B.location,n=D.lastIndexOf(p(t));-1===n&&(n=0);var r=D.lastIndexOf(p(e));-1===r&&(r=0);var o=n-r;o&&(A=!0,I(o))}(e)}))}}(o)}}var N=S(),L=y(N);N!==L&&E(L);var O=C(),D=[p(O)];function I(e){t.go(e)}var M=0;function F(e){1===(M+=e)&&1===e?window.addEventListener(w,P):0===M&&window.removeEventListener(w,P)}var z=!1;var B={length:t.length,action:"POP",location:O,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=_(window.location.href)),n+"#"+y(b+p(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,B.location);T.confirmTransitionTo(r,n,s,(function(e){if(e){var t=p(r),o=y(b+t);if(S()!==o){R=t,function(e){window.location.hash=e}(o);var s=D.lastIndexOf(p(B.location)),a=D.slice(0,s+1);a.push(t),D=a,j({action:n,location:r})}else j()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,B.location);T.confirmTransitionTo(r,n,s,(function(e){if(e){var t=p(r),o=y(b+t);S()!==o&&(R=t,E(o));var s=D.indexOf(p(B.location));-1!==s&&(D[s]=t),j({action:n,location:r})}}))},go:I,goBack:function(){I(-1)},goForward:function(){I(1)},block:function(e){void 0===e&&(e=!1);var t=T.setPrompt(e);return z||(F(1),z=!0),function(){return z&&(z=!1,F(-1)),t()}},listen:function(e){var t=T.appendListener(e);return F(1),function(){F(-1),t()}}};return B}function T(e,t,n){return Math.min(Math.max(e,t),n)}function j(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,s=void 0===o?["/"]:o,a=t.initialIndex,i=void 0===a?0:a,c=t.keyLength,l=void 0===c?6:c,d=g();function u(e){(0,r.A)(x,e),x.length=x.entries.length,d.notifyListeners(x.location,x.action)}function m(){return Math.random().toString(36).substr(2,l)}var h=T(i,0,s.length-1),b=s.map((function(e){return f(e,void 0,"string"==typeof e?m():e.key||m())})),v=p;function y(e){var t=T(x.index+e,0,x.entries.length-1),r=x.entries[t];d.confirmTransitionTo(r,"POP",n,(function(e){e?u({action:"POP",location:r,index:t}):u()}))}var x={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",o=f(e,t,m(),x.location);d.confirmTransitionTo(o,r,n,(function(e){if(e){var t=x.index+1,n=x.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),u({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,m(),x.location);d.confirmTransitionTo(o,r,n,(function(e){e&&(x.entries[x.index]=o,u({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=x.index+e;return t>=0&&t<x.entries.length},block:function(e){return void 0===e&&(e=!1),d.setPrompt(e)},listen:function(e){return d.appendListener(e)}};return x}},4146:(e,t,n)=>{"use strict";var r=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},s={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function c(e){return r.isMemo(e)?a:i[e.$$typeof]||o}i[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[r.Memo]=a;var l=Object.defineProperty,d=Object.getOwnPropertyNames,u=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var o=f(n);o&&o!==g&&e(t,o,r)}var a=d(n);u&&(a=a.concat(u(n)));for(var i=c(t),m=c(n),h=0;h<a.length;++h){var b=a[h];if(!(s[b]||r&&r[b]||m&&m[b]||i&&i[b])){var v=p(n,b);try{l(t,b,v)}catch(y){}}}}return t}},20311:e=>{"use strict";e.exports=function(e,t,n,r,o,s,a,i){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,s,a,i],d=0;(c=new Error(t.replace(/%s/g,(function(){return l[d++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},10119:(e,t,n)=>{"use strict";n.r(t)},51043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function s(e){return 100*(-1+e)}function a(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+s(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+s(e)+"%,0)"}:{"margin-left":s(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var s=n.render(!t),l=s.querySelector(r.barSelector),d=r.speed,u=r.easing;return s.offsetWidth,i((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,a(e,d,u)),1===e?(c(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){c(s,{transition:"all "+d+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),d)}),d)):setTimeout(t,d)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");d(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,a=t.querySelector(r.barSelector),i=e?"-100":s(n.status||0),l=document.querySelector(r.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+i+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),l!=document.body&&d(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){u(document.documentElement,"nprogress-busy"),u(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var i=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,s=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+s)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function s(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&s(e,n,r);else s(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function d(e,t){var n=p(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function u(e,t){var n,r=p(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},6969:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},8722:(e,t,n)=>{const r=n(6969),o=n(98380),s=new Set;function a(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...s,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(a.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(63157).resolve(t)],delete Prism.languages[e],n(63157)(t),s.add(e)}))}a.silent=!1,e.exports=a},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,s){if(n.language===r){var a=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof s&&!s(e))return e;for(var o,i=a.length;-1!==n.code.indexOf(o=t(r,i));)++i;return a[i]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,s=Object.keys(n.tokenStack);!function a(i){for(var c=0;c<i.length&&!(o>=s.length);c++){var l=i[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var d=s[o],u=n.tokenStack[d],p="string"==typeof l?l:l.content,f=t(r,d),g=p.indexOf(f);if(g>-1){++o;var m=p.substring(0,g),h=new e.Token(r,e.tokenize(u,n.grammar),"language-"+r,u),b=p.substring(g+f.length),v=[];m&&v.push.apply(v,a([m])),v.push(h),b&&v.push.apply(v,a([b])),"string"==typeof l?i.splice.apply(i,[c,1].concat(v)):l.content=v}}else l.content&&a(l.content)}return i}(n.tokens)}}}})}(Prism)},18692:(e,t,n)=>{var r={"./":8722};function o(e){var t=s(e);return n(t)}function s(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=s,e.exports=o,o.id=18692},63157:(e,t,n)=>{var r={"./":8722};function o(e){var t=s(e);return n(t)}function s(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=s,e.exports=o,o.id=63157},98380:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function o(r,s){if(!(r in n)){s.push(r);var a=s.indexOf(r);if(a<s.length-1)throw new Error("Circular dependency: "+s.slice(a).join(" -> "));var i={},c=e[r];if(c){function l(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in i))for(var a in o(t,s),i[t]=!0,n[t])i[a]=!0}t(c.require,l),t(c.optional,l),t(c.modify,l)}n[r]=i,s.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(s,a,i){var c=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var s=r[o];t[o]="string"==typeof s?{title:s}:s}}return t}(s),l=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var s=e[o];t(s&&s.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(c);a=a.map(l),i=(i||[]).map(l);var d=n(a),u=n(i);a.forEach((function e(n){var r=c[n];t(r&&r.require,(function(t){t in u||(d[t]=!0,e(t))}))}));for(var p,f=r(c),g=d;o(g);){for(var m in p={},g){var h=c[m];t(h&&h.modify,(function(e){e in u&&(p[e]=!0)}))}for(var b in u)if(!(b in d))for(var v in f(b))if(v in d){p[b]=!0;break}for(var y in g=p)d[y]=!0}var x={getIds:function(){var e=[];return x.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var s=o?o.series:void 0,a=o?o.parallel:e,i={},c={};function l(e){if(e in i)return i[e];c[e]=!0;var o,d=[];for(var u in t(e))u in n&&d.push(u);if(0===d.length)o=r(e);else{var p=a(d.map((function(e){var t=l(e);return delete c[e],t})));s?o=s(p,(function(){return r(e)})):r(e)}return i[e]=o}for(var d in n)l(d);var u=[];for(var p in c)u.push(i[p]);return a(u)}(f,d,t,n)}};return x}}();e.exports=t},2694:(e,t,n)=>{"use strict";var r=n(6925);function o(){}function s(){}s.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,s,a){if(a!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:s,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},22551:(e,t,n)=>{"use strict";var r=n(96540),o=n(69982);function s(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var a=new Set,i={};function c(e,t){l(e,t),l(e+"Capture",t)}function l(e,t){for(i[e]=t,e=0;e<t.length;e++)a.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),u=Object.prototype.hasOwnProperty,p=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},g={};function m(e,t,n,r,o,s,a){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=s,this.removeEmptyString=a}var h={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){h[e]=new m(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];h[t]=new m(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){h[e]=new m(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){h[e]=new m(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){h[e]=new m(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){h[e]=new m(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){h[e]=new m(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){h[e]=new m(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){h[e]=new m(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function v(e){return e[1].toUpperCase()}function y(e,t,n,r){var o=h.hasOwnProperty(t)?h[t]:null;(null!==o?0!==o.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!u.call(g,e)||!u.call(f,e)&&(p.test(e)?g[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){h[e]=new m(e,1,!1,e.toLowerCase(),null,!1,!1)})),h.xlinkHref=new m("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){h[e]=new m(e,1,!1,e.toLowerCase(),null,!0,!0)}));var x=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,w=Symbol.for("react.element"),k=Symbol.for("react.portal"),_=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),C=Symbol.for("react.provider"),T=Symbol.for("react.context"),j=Symbol.for("react.forward_ref"),A=Symbol.for("react.suspense"),R=Symbol.for("react.suspense_list"),P=Symbol.for("react.memo"),N=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var L=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var O=Symbol.iterator;function D(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=O&&e[O]||e["@@iterator"])?e:null}var I,M=Object.assign;function F(e){if(void 0===I)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);I=t&&t[1]||""}return"\n"+I+e}var z=!1;function B(e,t){if(!e||z)return"";z=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var r=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){r=l}e.call(t.prototype)}else{try{throw Error()}catch(l){r=l}e()}}catch(l){if(l&&r&&"string"==typeof l.stack){for(var o=l.stack.split("\n"),s=r.stack.split("\n"),a=o.length-1,i=s.length-1;1<=a&&0<=i&&o[a]!==s[i];)i--;for(;1<=a&&0<=i;a--,i--)if(o[a]!==s[i]){if(1!==a||1!==i)do{if(a--,0>--i||o[a]!==s[i]){var c="\n"+o[a].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=a&&0<=i);break}}}finally{z=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?F(e):""}function U(e){switch(e.tag){case 5:return F(e.type);case 16:return F("Lazy");case 13:return F("Suspense");case 19:return F("SuspenseList");case 0:case 2:case 15:return e=B(e.type,!1);case 11:return e=B(e.type.render,!1);case 1:return e=B(e.type,!0);default:return""}}function $(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case _:return"Fragment";case k:return"Portal";case E:return"Profiler";case S:return"StrictMode";case A:return"Suspense";case R:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case T:return(e.displayName||"Context")+".Consumer";case C:return(e._context.displayName||"Context")+".Provider";case j:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case P:return null!==(t=e.displayName||null)?t:$(e.type)||"Memo";case N:t=e._payload,e=e._init;try{return $(e(t))}catch(n){}}return null}function q(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return $(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function X(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function H(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function G(e){e._valueTracker||(e._valueTracker=function(e){var t=H(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,s=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,s.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function V(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=H(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function W(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function K(e,t){var n=t.checked;return M({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Q(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=X(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Y(e,t){null!=(t=t.checked)&&y(e,"checked",t,!1)}function Z(e,t){Y(e,t);var n=X(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,X(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&W(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+X(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function re(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(s(91));return M({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(s(92));if(te(n)){if(1<n.length)throw Error(s(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:X(n)}}function se(e,t){var n=X(t.value),r=X(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ae(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function ie(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ce(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ie(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var le,de,ue=(de=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((le=le||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=le.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return de(e,t)}))}:de);function pe(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ge=["Webkit","ms","Moz","O"];function me(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function he(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=me(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(fe).forEach((function(e){ge.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]}))}));var be=M({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ve(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(s(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(s(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(s(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(s(62))}}function ye(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var xe=null;function we(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var ke=null,_e=null,Se=null;function Ee(e){if(e=xo(e)){if("function"!=typeof ke)throw Error(s(280));var t=e.stateNode;t&&(t=ko(t),ke(e.stateNode,e.type,t))}}function Ce(e){_e?Se?Se.push(e):Se=[e]:_e=e}function Te(){if(_e){var e=_e,t=Se;if(Se=_e=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function je(e,t){return e(t)}function Ae(){}var Re=!1;function Pe(e,t,n){if(Re)return e(t,n);Re=!0;try{return je(e,t,n)}finally{Re=!1,(null!==_e||null!==Se)&&(Ae(),Te())}}function Ne(e,t){var n=e.stateNode;if(null===n)return null;var r=ko(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(s(231,t,typeof n));return n}var Le=!1;if(d)try{var Oe={};Object.defineProperty(Oe,"passive",{get:function(){Le=!0}}),window.addEventListener("test",Oe,Oe),window.removeEventListener("test",Oe,Oe)}catch(de){Le=!1}function De(e,t,n,r,o,s,a,i,c){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(d){this.onError(d)}}var Ie=!1,Me=null,Fe=!1,ze=null,Be={onError:function(e){Ie=!0,Me=e}};function Ue(e,t,n,r,o,s,a,i,c){Ie=!1,Me=null,De.apply(Be,arguments)}function $e(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function qe(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function Xe(e){if($e(e)!==e)throw Error(s(188))}function He(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=$e(e)))throw Error(s(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var a=o.alternate;if(null===a){if(null!==(r=o.return)){n=r;continue}break}if(o.child===a.child){for(a=o.child;a;){if(a===n)return Xe(o),e;if(a===r)return Xe(o),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=o,r=a;else{for(var i=!1,c=o.child;c;){if(c===n){i=!0,n=o,r=a;break}if(c===r){i=!0,r=o,n=a;break}c=c.sibling}if(!i){for(c=a.child;c;){if(c===n){i=!0,n=a,r=o;break}if(c===r){i=!0,r=a,n=o;break}c=c.sibling}if(!i)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(3!==n.tag)throw Error(s(188));return n.stateNode.current===n?e:t}(e))?Ge(e):null}function Ge(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=Ge(e);if(null!==t)return t;e=e.sibling}return null}var Ve=o.unstable_scheduleCallback,We=o.unstable_cancelCallback,Ke=o.unstable_shouldYield,Qe=o.unstable_requestPaint,Ye=o.unstable_now,Ze=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,rt=o.unstable_IdlePriority,ot=null,st=null;var at=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(it(e)/ct|0)|0},it=Math.log,ct=Math.LN2;var lt=64,dt=4194304;function ut(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function pt(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,s=e.pingedLanes,a=268435455&n;if(0!==a){var i=a&~o;0!==i?r=ut(i):0!==(s&=a)&&(r=ut(s))}else 0!==(a=n&~o)?r=ut(a):0!==s&&(r=ut(s));if(0===r)return 0;if(0!==t&&t!==r&&!(t&o)&&((o=r&-r)>=(s=t&-t)||16===o&&4194240&s))return t;if(4&r&&(r|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-at(t)),r|=e[n],t&=~o;return r}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function gt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function mt(){var e=lt;return!(4194240&(lt<<=1))&&(lt=64),e}function ht(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-at(t)]=n}function vt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-at(n),o=1<<r;o&t|e[r]&t&&(e[r]|=t),n&=~o}}var yt=0;function xt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var wt,kt,_t,St,Et,Ct=!1,Tt=[],jt=null,At=null,Rt=null,Pt=new Map,Nt=new Map,Lt=[],Ot="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Dt(e,t){switch(e){case"focusin":case"focusout":jt=null;break;case"dragenter":case"dragleave":At=null;break;case"mouseover":case"mouseout":Rt=null;break;case"pointerover":case"pointerout":Pt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Nt.delete(t.pointerId)}}function It(e,t,n,r,o,s){return null===e||e.nativeEvent!==s?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:s,targetContainers:[o]},null!==t&&(null!==(t=xo(t))&&kt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function Mt(e){var t=yo(e.target);if(null!==t){var n=$e(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=qe(n)))return e.blockedOn=t,void Et(e.priority,(function(){_t(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Ft(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Kt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=xo(n))&&kt(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);xe=r,n.target.dispatchEvent(r),xe=null,t.shift()}return!0}function zt(e,t,n){Ft(e)&&n.delete(t)}function Bt(){Ct=!1,null!==jt&&Ft(jt)&&(jt=null),null!==At&&Ft(At)&&(At=null),null!==Rt&&Ft(Rt)&&(Rt=null),Pt.forEach(zt),Nt.forEach(zt)}function Ut(e,t){e.blockedOn===t&&(e.blockedOn=null,Ct||(Ct=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,Bt)))}function $t(e){function t(t){return Ut(t,e)}if(0<Tt.length){Ut(Tt[0],e);for(var n=1;n<Tt.length;n++){var r=Tt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==jt&&Ut(jt,e),null!==At&&Ut(At,e),null!==Rt&&Ut(Rt,e),Pt.forEach(t),Nt.forEach(t),n=0;n<Lt.length;n++)(r=Lt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<Lt.length&&null===(n=Lt[0]).blockedOn;)Mt(n),null===n.blockedOn&&Lt.shift()}var qt=x.ReactCurrentBatchConfig,Xt=!0;function Ht(e,t,n,r){var o=yt,s=qt.transition;qt.transition=null;try{yt=1,Vt(e,t,n,r)}finally{yt=o,qt.transition=s}}function Gt(e,t,n,r){var o=yt,s=qt.transition;qt.transition=null;try{yt=4,Vt(e,t,n,r)}finally{yt=o,qt.transition=s}}function Vt(e,t,n,r){if(Xt){var o=Kt(e,t,n,r);if(null===o)Xr(e,t,r,Wt,n),Dt(e,r);else if(function(e,t,n,r,o){switch(t){case"focusin":return jt=It(jt,e,t,n,r,o),!0;case"dragenter":return At=It(At,e,t,n,r,o),!0;case"mouseover":return Rt=It(Rt,e,t,n,r,o),!0;case"pointerover":var s=o.pointerId;return Pt.set(s,It(Pt.get(s)||null,e,t,n,r,o)),!0;case"gotpointercapture":return s=o.pointerId,Nt.set(s,It(Nt.get(s)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r))r.stopPropagation();else if(Dt(e,r),4&t&&-1<Ot.indexOf(e)){for(;null!==o;){var s=xo(o);if(null!==s&&wt(s),null===(s=Kt(e,t,n,r))&&Xr(e,t,r,Wt,n),s===o)break;o=s}null!==o&&r.stopPropagation()}else Xr(e,t,r,null,n)}}var Wt=null;function Kt(e,t,n,r){if(Wt=null,null!==(e=yo(e=we(r))))if(null===(t=$e(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=qe(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Wt=e,null}function Qt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ze()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case rt:return 536870912;default:return 16}default:return 16}}var Yt=null,Zt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Zt,r=n.length,o="value"in Yt?Yt.value:Yt.textContent,s=o.length;for(e=0;e<r&&n[e]===o[e];e++);var a=r-e;for(t=1;t<=a&&n[r-t]===o[s-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function rn(){return!1}function on(e){function t(t,n,r,o,s){for(var a in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=s,this.currentTarget=null,e)e.hasOwnProperty(a)&&(t=e[a],this[a]=t?t(o):o[a]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:rn,this.isPropagationStopped=rn,this}return M(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var sn,an,cn,ln={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},dn=on(ln),un=M({},ln,{view:0,detail:0}),pn=on(un),fn=M({},un,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==cn&&(cn&&"mousemove"===e.type?(sn=e.screenX-cn.screenX,an=e.screenY-cn.screenY):an=sn=0,cn=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:an}}),gn=on(fn),mn=on(M({},fn,{dataTransfer:0})),hn=on(M({},un,{relatedTarget:0})),bn=on(M({},ln,{animationName:0,elapsedTime:0,pseudoElement:0})),vn=M({},ln,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),yn=on(vn),xn=on(M({},ln,{data:0})),wn={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},kn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},_n={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=_n[e])&&!!t[e]}function En(){return Sn}var Cn=M({},un,{key:function(e){if(e.key){var t=wn[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?kn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Tn=on(Cn),jn=on(M({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),An=on(M({},un,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),Rn=on(M({},ln,{propertyName:0,elapsedTime:0,pseudoElement:0})),Pn=M({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Nn=on(Pn),Ln=[9,13,27,32],On=d&&"CompositionEvent"in window,Dn=null;d&&"documentMode"in document&&(Dn=document.documentMode);var In=d&&"TextEvent"in window&&!Dn,Mn=d&&(!On||Dn&&8<Dn&&11>=Dn),Fn=String.fromCharCode(32),zn=!1;function Bn(e,t){switch(e){case"keyup":return-1!==Ln.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Un(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var $n=!1;var qn={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Xn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!qn[e.type]:"textarea"===t}function Hn(e,t,n,r){Ce(r),0<(t=Gr(t,"onChange")).length&&(n=new dn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Gn=null,Vn=null;function Wn(e){Fr(e,0)}function Kn(e){if(V(wo(e)))return e}function Qn(e,t){if("change"===e)return t}var Yn=!1;if(d){var Zn;if(d){var Jn="oninput"in document;if(!Jn){var er=document.createElement("div");er.setAttribute("oninput","return;"),Jn="function"==typeof er.oninput}Zn=Jn}else Zn=!1;Yn=Zn&&(!document.documentMode||9<document.documentMode)}function tr(){Gn&&(Gn.detachEvent("onpropertychange",nr),Vn=Gn=null)}function nr(e){if("value"===e.propertyName&&Kn(Vn)){var t=[];Hn(t,Vn,e,we(e)),Pe(Wn,t)}}function rr(e,t,n){"focusin"===e?(tr(),Vn=n,(Gn=t).attachEvent("onpropertychange",nr)):"focusout"===e&&tr()}function or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(Vn)}function sr(e,t){if("click"===e)return Kn(t)}function ar(e,t){if("input"===e||"change"===e)return Kn(t)}var ir="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function cr(e,t){if(ir(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var o=n[r];if(!u.call(t,o)||!ir(e[o],t[o]))return!1}return!0}function lr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function dr(e,t){var n,r=lr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=lr(r)}}function ur(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?ur(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function pr(){for(var e=window,t=W();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=W((e=t.contentWindow).document)}return t}function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function gr(e){var t=pr(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&ur(n.ownerDocument.documentElement,n)){if(null!==r&&fr(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,s=Math.min(r.start,o);r=void 0===r.end?s:Math.min(r.end,o),!e.extend&&s>r&&(o=r,r=s,s=o),o=dr(n,s);var a=dr(n,r);o&&a&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),s>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var mr=d&&"documentMode"in document&&11>=document.documentMode,hr=null,br=null,vr=null,yr=!1;function xr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;yr||null==hr||hr!==W(r)||("selectionStart"in(r=hr)&&fr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},vr&&cr(vr,r)||(vr=r,0<(r=Gr(br,"onSelect")).length&&(t=new dn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=hr)))}function wr(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var kr={animationend:wr("Animation","AnimationEnd"),animationiteration:wr("Animation","AnimationIteration"),animationstart:wr("Animation","AnimationStart"),transitionend:wr("Transition","TransitionEnd")},_r={},Sr={};function Er(e){if(_r[e])return _r[e];if(!kr[e])return e;var t,n=kr[e];for(t in n)if(n.hasOwnProperty(t)&&t in Sr)return _r[e]=n[t];return e}d&&(Sr=document.createElement("div").style,"AnimationEvent"in window||(delete kr.animationend.animation,delete kr.animationiteration.animation,delete kr.animationstart.animation),"TransitionEvent"in window||delete kr.transitionend.transition);var Cr=Er("animationend"),Tr=Er("animationiteration"),jr=Er("animationstart"),Ar=Er("transitionend"),Rr=new Map,Pr="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Nr(e,t){Rr.set(e,t),c(t,[e])}for(var Lr=0;Lr<Pr.length;Lr++){var Or=Pr[Lr];Nr(Or.toLowerCase(),"on"+(Or[0].toUpperCase()+Or.slice(1)))}Nr(Cr,"onAnimationEnd"),Nr(Tr,"onAnimationIteration"),Nr(jr,"onAnimationStart"),Nr("dblclick","onDoubleClick"),Nr("focusin","onFocus"),Nr("focusout","onBlur"),Nr(Ar,"onTransitionEnd"),l("onMouseEnter",["mouseout","mouseover"]),l("onMouseLeave",["mouseout","mouseover"]),l("onPointerEnter",["pointerout","pointerover"]),l("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Dr="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Ir=new Set("cancel close invalid load scroll toggle".split(" ").concat(Dr));function Mr(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,a,i,c,l){if(Ue.apply(this,arguments),Ie){if(!Ie)throw Error(s(198));var d=Me;Ie=!1,Me=null,Fe||(Fe=!0,ze=d)}}(r,t,void 0,e),e.currentTarget=null}function Fr(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var s=void 0;if(t)for(var a=r.length-1;0<=a;a--){var i=r[a],c=i.instance,l=i.currentTarget;if(i=i.listener,c!==s&&o.isPropagationStopped())break e;Mr(o,i,l),s=c}else for(a=0;a<r.length;a++){if(c=(i=r[a]).instance,l=i.currentTarget,i=i.listener,c!==s&&o.isPropagationStopped())break e;Mr(o,i,l),s=c}}}if(Fe)throw e=ze,Fe=!1,ze=null,e}function zr(e,t){var n=t[ho];void 0===n&&(n=t[ho]=new Set);var r=e+"__bubble";n.has(r)||(qr(t,e,2,!1),n.add(r))}function Br(e,t,n){var r=0;t&&(r|=4),qr(n,e,r,t)}var Ur="_reactListening"+Math.random().toString(36).slice(2);function $r(e){if(!e[Ur]){e[Ur]=!0,a.forEach((function(t){"selectionchange"!==t&&(Ir.has(t)||Br(t,!1,e),Br(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[Ur]||(t[Ur]=!0,Br("selectionchange",!1,t))}}function qr(e,t,n,r){switch(Qt(t)){case 1:var o=Ht;break;case 4:o=Gt;break;default:o=Vt}n=o.bind(null,t,n,e),o=void 0,!Le||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function Xr(e,t,n,r,o){var s=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var a=r.tag;if(3===a||4===a){var i=r.stateNode.containerInfo;if(i===o||8===i.nodeType&&i.parentNode===o)break;if(4===a)for(a=r.return;null!==a;){var c=a.tag;if((3===c||4===c)&&((c=a.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;a=a.return}for(;null!==i;){if(null===(a=yo(i)))return;if(5===(c=a.tag)||6===c){r=s=a;continue e}i=i.parentNode}}r=r.return}Pe((function(){var r=s,o=we(n),a=[];e:{var i=Rr.get(e);if(void 0!==i){var c=dn,l=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":c=Tn;break;case"focusin":l="focus",c=hn;break;case"focusout":l="blur",c=hn;break;case"beforeblur":case"afterblur":c=hn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=gn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=mn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=An;break;case Cr:case Tr:case jr:c=bn;break;case Ar:c=Rn;break;case"scroll":c=pn;break;case"wheel":c=Nn;break;case"copy":case"cut":case"paste":c=yn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=jn}var d=!!(4&t),u=!d&&"scroll"===e,p=d?null!==i?i+"Capture":null:i;d=[];for(var f,g=r;null!==g;){var m=(f=g).stateNode;if(5===f.tag&&null!==m&&(f=m,null!==p&&(null!=(m=Ne(g,p))&&d.push(Hr(g,m,f)))),u)break;g=g.return}0<d.length&&(i=new c(i,l,null,n,o),a.push({event:i,listeners:d}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(i="mouseover"===e||"pointerover"===e)||n===xe||!(l=n.relatedTarget||n.fromElement)||!yo(l)&&!l[mo])&&(c||i)&&(i=o.window===o?o:(i=o.ownerDocument)?i.defaultView||i.parentWindow:window,c?(c=r,null!==(l=(l=n.relatedTarget||n.toElement)?yo(l):null)&&(l!==(u=$e(l))||5!==l.tag&&6!==l.tag)&&(l=null)):(c=null,l=r),c!==l)){if(d=gn,m="onMouseLeave",p="onMouseEnter",g="mouse","pointerout"!==e&&"pointerover"!==e||(d=jn,m="onPointerLeave",p="onPointerEnter",g="pointer"),u=null==c?i:wo(c),f=null==l?i:wo(l),(i=new d(m,g+"leave",c,n,o)).target=u,i.relatedTarget=f,m=null,yo(o)===r&&((d=new d(p,g+"enter",l,n,o)).target=f,d.relatedTarget=u,m=d),u=m,c&&l)e:{for(p=l,g=0,f=d=c;f;f=Vr(f))g++;for(f=0,m=p;m;m=Vr(m))f++;for(;0<g-f;)d=Vr(d),g--;for(;0<f-g;)p=Vr(p),f--;for(;g--;){if(d===p||null!==p&&d===p.alternate)break e;d=Vr(d),p=Vr(p)}d=null}else d=null;null!==c&&Wr(a,i,c,d,!1),null!==l&&null!==u&&Wr(a,u,l,d,!0)}if("select"===(c=(i=r?wo(r):window).nodeName&&i.nodeName.toLowerCase())||"input"===c&&"file"===i.type)var h=Qn;else if(Xn(i))if(Yn)h=ar;else{h=or;var b=rr}else(c=i.nodeName)&&"input"===c.toLowerCase()&&("checkbox"===i.type||"radio"===i.type)&&(h=sr);switch(h&&(h=h(e,r))?Hn(a,h,n,o):(b&&b(e,i,r),"focusout"===e&&(b=i._wrapperState)&&b.controlled&&"number"===i.type&&ee(i,"number",i.value)),b=r?wo(r):window,e){case"focusin":(Xn(b)||"true"===b.contentEditable)&&(hr=b,br=r,vr=null);break;case"focusout":vr=br=hr=null;break;case"mousedown":yr=!0;break;case"contextmenu":case"mouseup":case"dragend":yr=!1,xr(a,n,o);break;case"selectionchange":if(mr)break;case"keydown":case"keyup":xr(a,n,o)}var v;if(On)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else $n?Bn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(Mn&&"ko"!==n.locale&&($n||"onCompositionStart"!==y?"onCompositionEnd"===y&&$n&&(v=en()):(Zt="value"in(Yt=o)?Yt.value:Yt.textContent,$n=!0)),0<(b=Gr(r,y)).length&&(y=new xn(y,e,null,n,o),a.push({event:y,listeners:b}),v?y.data=v:null!==(v=Un(n))&&(y.data=v))),(v=In?function(e,t){switch(e){case"compositionend":return Un(t);case"keypress":return 32!==t.which?null:(zn=!0,Fn);case"textInput":return(e=t.data)===Fn&&zn?null:e;default:return null}}(e,n):function(e,t){if($n)return"compositionend"===e||!On&&Bn(e,t)?(e=en(),Jt=Zt=Yt=null,$n=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return Mn&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Gr(r,"onBeforeInput")).length&&(o=new xn("onBeforeInput","beforeinput",null,n,o),a.push({event:o,listeners:r}),o.data=v))}Fr(a,t)}))}function Hr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Gr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,s=o.stateNode;5===o.tag&&null!==s&&(o=s,null!=(s=Ne(e,n))&&r.unshift(Hr(e,s,o)),null!=(s=Ne(e,t))&&r.push(Hr(e,s,o))),e=e.return}return r}function Vr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Wr(e,t,n,r,o){for(var s=t._reactName,a=[];null!==n&&n!==r;){var i=n,c=i.alternate,l=i.stateNode;if(null!==c&&c===r)break;5===i.tag&&null!==l&&(i=l,o?null!=(c=Ne(n,s))&&a.unshift(Hr(n,c,i)):o||null!=(c=Ne(n,s))&&a.push(Hr(n,c,i))),n=n.return}0!==a.length&&e.push({event:t,listeners:a})}var Kr=/\r\n?/g,Qr=/\u0000|\uFFFD/g;function Yr(e){return("string"==typeof e?e:""+e).replace(Kr,"\n").replace(Qr,"")}function Zr(e,t,n){if(t=Yr(t),Yr(e)!==t&&n)throw Error(s(425))}function Jr(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ro="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,so="function"==typeof Promise?Promise:void 0,ao="function"==typeof queueMicrotask?queueMicrotask:void 0!==so?function(e){return so.resolve(null).then(e).catch(io)}:ro;function io(e){setTimeout((function(){throw e}))}function co(e,t){var n=t,r=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===r)return e.removeChild(o),void $t(t);r--}else"$"!==n&&"$?"!==n&&"$!"!==n||r++;n=o}while(n);$t(t)}function lo(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function uo(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var po=Math.random().toString(36).slice(2),fo="__reactFiber$"+po,go="__reactProps$"+po,mo="__reactContainer$"+po,ho="__reactEvents$"+po,bo="__reactListeners$"+po,vo="__reactHandles$"+po;function yo(e){var t=e[fo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[mo]||n[fo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=uo(e);null!==e;){if(n=e[fo])return n;e=uo(e)}return t}n=(e=n).parentNode}return null}function xo(e){return!(e=e[fo]||e[mo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function wo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(s(33))}function ko(e){return e[go]||null}var _o=[],So=-1;function Eo(e){return{current:e}}function Co(e){0>So||(e.current=_o[So],_o[So]=null,So--)}function To(e,t){So++,_o[So]=e.current,e.current=t}var jo={},Ao=Eo(jo),Ro=Eo(!1),Po=jo;function No(e,t){var n=e.type.contextTypes;if(!n)return jo;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,s={};for(o in n)s[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function Lo(e){return null!=(e=e.childContextTypes)}function Oo(){Co(Ro),Co(Ao)}function Do(e,t,n){if(Ao.current!==jo)throw Error(s(168));To(Ao,t),To(Ro,n)}function Io(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in t))throw Error(s(108,q(e)||"Unknown",o));return M({},n,r)}function Mo(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||jo,Po=Ao.current,To(Ao,e),To(Ro,Ro.current),!0}function Fo(e,t,n){var r=e.stateNode;if(!r)throw Error(s(169));n?(e=Io(e,t,Po),r.__reactInternalMemoizedMergedChildContext=e,Co(Ro),Co(Ao),To(Ao,e)):Co(Ro),To(Ro,n)}var zo=null,Bo=!1,Uo=!1;function $o(e){null===zo?zo=[e]:zo.push(e)}function qo(){if(!Uo&&null!==zo){Uo=!0;var e=0,t=yt;try{var n=zo;for(yt=1;e<n.length;e++){var r=n[e];do{r=r(!0)}while(null!==r)}zo=null,Bo=!1}catch(o){throw null!==zo&&(zo=zo.slice(e+1)),Ve(Je,qo),o}finally{yt=t,Uo=!1}}return null}var Xo=[],Ho=0,Go=null,Vo=0,Wo=[],Ko=0,Qo=null,Yo=1,Zo="";function Jo(e,t){Xo[Ho++]=Vo,Xo[Ho++]=Go,Go=e,Vo=t}function es(e,t,n){Wo[Ko++]=Yo,Wo[Ko++]=Zo,Wo[Ko++]=Qo,Qo=e;var r=Yo;e=Zo;var o=32-at(r)-1;r&=~(1<<o),n+=1;var s=32-at(t)+o;if(30<s){var a=o-o%5;s=(r&(1<<a)-1).toString(32),r>>=a,o-=a,Yo=1<<32-at(t)+o|n<<o|r,Zo=s+e}else Yo=1<<s|n<<o|r,Zo=e}function ts(e){null!==e.return&&(Jo(e,1),es(e,1,0))}function ns(e){for(;e===Go;)Go=Xo[--Ho],Xo[Ho]=null,Vo=Xo[--Ho],Xo[Ho]=null;for(;e===Qo;)Qo=Wo[--Ko],Wo[Ko]=null,Zo=Wo[--Ko],Wo[Ko]=null,Yo=Wo[--Ko],Wo[Ko]=null}var rs=null,os=null,ss=!1,as=null;function is(e,t){var n=Pl(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function cs(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,rs=e,os=lo(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,rs=e,os=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Qo?{id:Yo,overflow:Zo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Pl(18,null,null,0)).stateNode=t,n.return=e,e.child=n,rs=e,os=null,!0);default:return!1}}function ls(e){return!(!(1&e.mode)||128&e.flags)}function ds(e){if(ss){var t=os;if(t){var n=t;if(!cs(e,t)){if(ls(e))throw Error(s(418));t=lo(n.nextSibling);var r=rs;t&&cs(e,t)?is(r,n):(e.flags=-4097&e.flags|2,ss=!1,rs=e)}}else{if(ls(e))throw Error(s(418));e.flags=-4097&e.flags|2,ss=!1,rs=e}}}function us(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;rs=e}function ps(e){if(e!==rs)return!1;if(!ss)return us(e),ss=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=os)){if(ls(e))throw fs(),Error(s(418));for(;t;)is(e,t),t=lo(t.nextSibling)}if(us(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(s(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){os=lo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}os=null}}else os=rs?lo(e.stateNode.nextSibling):null;return!0}function fs(){for(var e=os;e;)e=lo(e.nextSibling)}function gs(){os=rs=null,ss=!1}function ms(e){null===as?as=[e]:as.push(e)}var hs=x.ReactCurrentBatchConfig;function bs(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(s(309));var r=n.stateNode}if(!r)throw Error(s(147,e));var o=r,a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=o.refs;null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(s(284));if(!n._owner)throw Error(s(290,e))}return e}function vs(e,t){throw e=Object.prototype.toString.call(t),Error(s(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function ys(e){return(0,e._init)(e._payload)}function xs(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Ll(e,t)).index=0,e.sibling=null,e}function a(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=2,n):r:(t.flags|=2,n):(t.flags|=1048576,n)}function i(t){return e&&null===t.alternate&&(t.flags|=2),t}function c(e,t,n,r){return null===t||6!==t.tag?((t=Ml(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function l(e,t,n,r){var s=n.type;return s===_?u(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===s||"object"==typeof s&&null!==s&&s.$$typeof===N&&ys(s)===t.type)?((r=o(t,n.props)).ref=bs(e,t,n),r.return=e,r):((r=Ol(n.type,n.key,n.props,null,e.mode,r)).ref=bs(e,t,n),r.return=e,r)}function d(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Fl(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function u(e,t,n,r,s){return null===t||7!==t.tag?((t=Dl(n,e.mode,r,s)).return=e,t):((t=o(t,n)).return=e,t)}function p(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Ml(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case w:return(n=Ol(t.type,t.key,t.props,null,e.mode,n)).ref=bs(e,null,t),n.return=e,n;case k:return(t=Fl(t,e.mode,n)).return=e,t;case N:return p(e,(0,t._init)(t._payload),n)}if(te(t)||D(t))return(t=Dl(t,e.mode,n,null)).return=e,t;vs(e,t)}return null}function f(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:c(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case w:return n.key===o?l(e,t,n,r):null;case k:return n.key===o?d(e,t,n,r):null;case N:return f(e,t,(o=n._init)(n._payload),r)}if(te(n)||D(n))return null!==o?null:u(e,t,n,r,null);vs(e,n)}return null}function g(e,t,n,r,o){if("string"==typeof r&&""!==r||"number"==typeof r)return c(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case w:return l(t,e=e.get(null===r.key?n:r.key)||null,r,o);case k:return d(t,e=e.get(null===r.key?n:r.key)||null,r,o);case N:return g(e,t,n,(0,r._init)(r._payload),o)}if(te(r)||D(r))return u(t,e=e.get(n)||null,r,o,null);vs(t,r)}return null}function m(o,s,i,c){for(var l=null,d=null,u=s,m=s=0,h=null;null!==u&&m<i.length;m++){u.index>m?(h=u,u=null):h=u.sibling;var b=f(o,u,i[m],c);if(null===b){null===u&&(u=h);break}e&&u&&null===b.alternate&&t(o,u),s=a(b,s,m),null===d?l=b:d.sibling=b,d=b,u=h}if(m===i.length)return n(o,u),ss&&Jo(o,m),l;if(null===u){for(;m<i.length;m++)null!==(u=p(o,i[m],c))&&(s=a(u,s,m),null===d?l=u:d.sibling=u,d=u);return ss&&Jo(o,m),l}for(u=r(o,u);m<i.length;m++)null!==(h=g(u,o,m,i[m],c))&&(e&&null!==h.alternate&&u.delete(null===h.key?m:h.key),s=a(h,s,m),null===d?l=h:d.sibling=h,d=h);return e&&u.forEach((function(e){return t(o,e)})),ss&&Jo(o,m),l}function h(o,i,c,l){var d=D(c);if("function"!=typeof d)throw Error(s(150));if(null==(c=d.call(c)))throw Error(s(151));for(var u=d=null,m=i,h=i=0,b=null,v=c.next();null!==m&&!v.done;h++,v=c.next()){m.index>h?(b=m,m=null):b=m.sibling;var y=f(o,m,v.value,l);if(null===y){null===m&&(m=b);break}e&&m&&null===y.alternate&&t(o,m),i=a(y,i,h),null===u?d=y:u.sibling=y,u=y,m=b}if(v.done)return n(o,m),ss&&Jo(o,h),d;if(null===m){for(;!v.done;h++,v=c.next())null!==(v=p(o,v.value,l))&&(i=a(v,i,h),null===u?d=v:u.sibling=v,u=v);return ss&&Jo(o,h),d}for(m=r(o,m);!v.done;h++,v=c.next())null!==(v=g(m,o,h,v.value,l))&&(e&&null!==v.alternate&&m.delete(null===v.key?h:v.key),i=a(v,i,h),null===u?d=v:u.sibling=v,u=v);return e&&m.forEach((function(e){return t(o,e)})),ss&&Jo(o,h),d}return function e(r,s,a,c){if("object"==typeof a&&null!==a&&a.type===_&&null===a.key&&(a=a.props.children),"object"==typeof a&&null!==a){switch(a.$$typeof){case w:e:{for(var l=a.key,d=s;null!==d;){if(d.key===l){if((l=a.type)===_){if(7===d.tag){n(r,d.sibling),(s=o(d,a.props.children)).return=r,r=s;break e}}else if(d.elementType===l||"object"==typeof l&&null!==l&&l.$$typeof===N&&ys(l)===d.type){n(r,d.sibling),(s=o(d,a.props)).ref=bs(r,d,a),s.return=r,r=s;break e}n(r,d);break}t(r,d),d=d.sibling}a.type===_?((s=Dl(a.props.children,r.mode,c,a.key)).return=r,r=s):((c=Ol(a.type,a.key,a.props,null,r.mode,c)).ref=bs(r,s,a),c.return=r,r=c)}return i(r);case k:e:{for(d=a.key;null!==s;){if(s.key===d){if(4===s.tag&&s.stateNode.containerInfo===a.containerInfo&&s.stateNode.implementation===a.implementation){n(r,s.sibling),(s=o(s,a.children||[])).return=r,r=s;break e}n(r,s);break}t(r,s),s=s.sibling}(s=Fl(a,r.mode,c)).return=r,r=s}return i(r);case N:return e(r,s,(d=a._init)(a._payload),c)}if(te(a))return m(r,s,a,c);if(D(a))return h(r,s,a,c);vs(r,a)}return"string"==typeof a&&""!==a||"number"==typeof a?(a=""+a,null!==s&&6===s.tag?(n(r,s.sibling),(s=o(s,a)).return=r,r=s):(n(r,s),(s=Ml(a,r.mode,c)).return=r,r=s),i(r)):n(r,s)}}var ws=xs(!0),ks=xs(!1),_s=Eo(null),Ss=null,Es=null,Cs=null;function Ts(){Cs=Es=Ss=null}function js(e){var t=_s.current;Co(_s),e._currentValue=t}function As(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function Rs(e,t){Ss=e,Cs=Es=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&t)&&(yi=!0),e.firstContext=null)}function Ps(e){var t=e._currentValue;if(Cs!==e)if(e={context:e,memoizedValue:t,next:null},null===Es){if(null===Ss)throw Error(s(308));Es=e,Ss.dependencies={lanes:0,firstContext:e}}else Es=Es.next=e;return t}var Ns=null;function Ls(e){null===Ns?Ns=[e]:Ns.push(e)}function Os(e,t,n,r){var o=t.interleaved;return null===o?(n.next=n,Ls(t)):(n.next=o.next,o.next=n),t.interleaved=n,Ds(e,r)}function Ds(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Is=!1;function Ms(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Fs(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function zs(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function Bs(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&jc){var o=r.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),r.pending=t,Ds(e,n)}return null===(o=r.interleaved)?(t.next=t,Ls(r)):(t.next=o.next,o.next=t),r.interleaved=t,Ds(e,n)}function Us(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,vt(e,n)}}function $s(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,s=null;if(null!==(n=n.firstBaseUpdate)){do{var a={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===s?o=s=a:s=s.next=a,n=n.next}while(null!==n);null===s?o=s=t:s=s.next=t}else o=s=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:s,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function qs(e,t,n,r){var o=e.updateQueue;Is=!1;var s=o.firstBaseUpdate,a=o.lastBaseUpdate,i=o.shared.pending;if(null!==i){o.shared.pending=null;var c=i,l=c.next;c.next=null,null===a?s=l:a.next=l,a=c;var d=e.alternate;null!==d&&((i=(d=d.updateQueue).lastBaseUpdate)!==a&&(null===i?d.firstBaseUpdate=l:i.next=l,d.lastBaseUpdate=c))}if(null!==s){var u=o.baseState;for(a=0,d=l=c=null,i=s;;){var p=i.lane,f=i.eventTime;if((r&p)===p){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var g=e,m=i;switch(p=t,f=n,m.tag){case 1:if("function"==typeof(g=m.payload)){u=g.call(f,u,p);break e}u=g;break e;case 3:g.flags=-65537&g.flags|128;case 0:if(null==(p="function"==typeof(g=m.payload)?g.call(f,u,p):g))break e;u=M({},u,p);break e;case 2:Is=!0}}null!==i.callback&&0!==i.lane&&(e.flags|=64,null===(p=o.effects)?o.effects=[i]:p.push(i))}else f={eventTime:f,lane:p,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(l=d=f,c=u):d=d.next=f,a|=p;if(null===(i=i.next)){if(null===(i=o.shared.pending))break;i=(p=i).next,p.next=null,o.lastBaseUpdate=p,o.shared.pending=null}}if(null===d&&(c=u),o.baseState=c,o.firstBaseUpdate=l,o.lastBaseUpdate=d,null!==(t=o.shared.interleaved)){o=t;do{a|=o.lane,o=o.next}while(o!==t)}else null===s&&(o.shared.lanes=0);Ic|=a,e.lanes=a,e.memoizedState=u}}function Xs(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(s(191,o));o.call(r)}}}var Hs={},Gs=Eo(Hs),Vs=Eo(Hs),Ws=Eo(Hs);function Ks(e){if(e===Hs)throw Error(s(174));return e}function Qs(e,t){switch(To(Ws,t),To(Vs,e),To(Gs,Hs),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ce(null,"");break;default:t=ce(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}Co(Gs),To(Gs,t)}function Ys(){Co(Gs),Co(Vs),Co(Ws)}function Zs(e){Ks(Ws.current);var t=Ks(Gs.current),n=ce(t,e.type);t!==n&&(To(Vs,e),To(Gs,n))}function Js(e){Vs.current===e&&(Co(Gs),Co(Vs))}var ea=Eo(0);function ta(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var na=[];function ra(){for(var e=0;e<na.length;e++)na[e]._workInProgressVersionPrimary=null;na.length=0}var oa=x.ReactCurrentDispatcher,sa=x.ReactCurrentBatchConfig,aa=0,ia=null,ca=null,la=null,da=!1,ua=!1,pa=0,fa=0;function ga(){throw Error(s(321))}function ma(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!ir(e[n],t[n]))return!1;return!0}function ha(e,t,n,r,o,a){if(aa=a,ia=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,oa.current=null===e||null===e.memoizedState?Ja:ei,e=n(r,o),ua){a=0;do{if(ua=!1,pa=0,25<=a)throw Error(s(301));a+=1,la=ca=null,t.updateQueue=null,oa.current=ti,e=n(r,o)}while(ua)}if(oa.current=Za,t=null!==ca&&null!==ca.next,aa=0,la=ca=ia=null,da=!1,t)throw Error(s(300));return e}function ba(){var e=0!==pa;return pa=0,e}function va(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===la?ia.memoizedState=la=e:la=la.next=e,la}function ya(){if(null===ca){var e=ia.alternate;e=null!==e?e.memoizedState:null}else e=ca.next;var t=null===la?ia.memoizedState:la.next;if(null!==t)la=t,ca=e;else{if(null===e)throw Error(s(310));e={memoizedState:(ca=e).memoizedState,baseState:ca.baseState,baseQueue:ca.baseQueue,queue:ca.queue,next:null},null===la?ia.memoizedState=la=e:la=la.next=e}return la}function xa(e,t){return"function"==typeof t?t(e):t}function wa(e){var t=ya(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var r=ca,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var i=o.next;o.next=a.next,a.next=i}r.baseQueue=o=a,n.pending=null}if(null!==o){a=o.next,r=r.baseState;var c=i=null,l=null,d=a;do{var u=d.lane;if((aa&u)===u)null!==l&&(l=l.next={lane:0,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null}),r=d.hasEagerState?d.eagerState:e(r,d.action);else{var p={lane:u,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null};null===l?(c=l=p,i=r):l=l.next=p,ia.lanes|=u,Ic|=u}d=d.next}while(null!==d&&d!==a);null===l?i=r:l.next=c,ir(r,t.memoizedState)||(yi=!0),t.memoizedState=r,t.baseState=i,t.baseQueue=l,n.lastRenderedState=r}if(null!==(e=n.interleaved)){o=e;do{a=o.lane,ia.lanes|=a,Ic|=a,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function ka(e){var t=ya(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{a=e(a,i.action),i=i.next}while(i!==o);ir(a,t.memoizedState)||(yi=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function _a(){}function Sa(e,t){var n=ia,r=ya(),o=t(),a=!ir(r.memoizedState,o);if(a&&(r.memoizedState=o,yi=!0),r=r.queue,Ia(Ta.bind(null,n,r,e),[e]),r.getSnapshot!==t||a||null!==la&&1&la.memoizedState.tag){if(n.flags|=2048,Pa(9,Ca.bind(null,n,r,o,t),void 0,null),null===Ac)throw Error(s(349));30&aa||Ea(n,t,o)}return o}function Ea(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=ia.updateQueue)?(t={lastEffect:null,stores:null},ia.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function Ca(e,t,n,r){t.value=n,t.getSnapshot=r,ja(t)&&Aa(e)}function Ta(e,t,n){return n((function(){ja(t)&&Aa(e)}))}function ja(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!ir(e,n)}catch(r){return!0}}function Aa(e){var t=Ds(e,1);null!==t&&nl(t,e,1,-1)}function Ra(e){var t=va();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:xa,lastRenderedState:e},t.queue=e,e=e.dispatch=Wa.bind(null,ia,e),[t.memoizedState,e]}function Pa(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=ia.updateQueue)?(t={lastEffect:null,stores:null},ia.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function Na(){return ya().memoizedState}function La(e,t,n,r){var o=va();ia.flags|=e,o.memoizedState=Pa(1|t,n,void 0,void 0===r?null:r)}function Oa(e,t,n,r){var o=ya();r=void 0===r?null:r;var s=void 0;if(null!==ca){var a=ca.memoizedState;if(s=a.destroy,null!==r&&ma(r,a.deps))return void(o.memoizedState=Pa(t,n,s,r))}ia.flags|=e,o.memoizedState=Pa(1|t,n,s,r)}function Da(e,t){return La(8390656,8,e,t)}function Ia(e,t){return Oa(2048,8,e,t)}function Ma(e,t){return Oa(4,2,e,t)}function Fa(e,t){return Oa(4,4,e,t)}function za(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function Ba(e,t,n){return n=null!=n?n.concat([e]):null,Oa(4,4,za.bind(null,t,e),n)}function Ua(){}function $a(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ma(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function qa(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ma(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function Xa(e,t,n){return 21&aa?(ir(n,t)||(n=mt(),ia.lanes|=n,Ic|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,yi=!0),e.memoizedState=n)}function Ha(e,t){var n=yt;yt=0!==n&&4>n?n:4,e(!0);var r=sa.transition;sa.transition={};try{e(!1),t()}finally{yt=n,sa.transition=r}}function Ga(){return ya().memoizedState}function Va(e,t,n){var r=tl(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Ka(e))Qa(t,n);else if(null!==(n=Os(e,t,n,r))){nl(n,e,r,el()),Ya(n,t,r)}}function Wa(e,t,n){var r=tl(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ka(e))Qa(t,o);else{var s=e.alternate;if(0===e.lanes&&(null===s||0===s.lanes)&&null!==(s=t.lastRenderedReducer))try{var a=t.lastRenderedState,i=s(a,n);if(o.hasEagerState=!0,o.eagerState=i,ir(i,a)){var c=t.interleaved;return null===c?(o.next=o,Ls(t)):(o.next=c.next,c.next=o),void(t.interleaved=o)}}catch(l){}null!==(n=Os(e,t,o,r))&&(nl(n,e,r,o=el()),Ya(n,t,r))}}function Ka(e){var t=e.alternate;return e===ia||null!==t&&t===ia}function Qa(e,t){ua=da=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ya(e,t,n){if(4194240&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,vt(e,n)}}var Za={readContext:Ps,useCallback:ga,useContext:ga,useEffect:ga,useImperativeHandle:ga,useInsertionEffect:ga,useLayoutEffect:ga,useMemo:ga,useReducer:ga,useRef:ga,useState:ga,useDebugValue:ga,useDeferredValue:ga,useTransition:ga,useMutableSource:ga,useSyncExternalStore:ga,useId:ga,unstable_isNewReconciler:!1},Ja={readContext:Ps,useCallback:function(e,t){return va().memoizedState=[e,void 0===t?null:t],e},useContext:Ps,useEffect:Da,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,La(4194308,4,za.bind(null,t,e),n)},useLayoutEffect:function(e,t){return La(4194308,4,e,t)},useInsertionEffect:function(e,t){return La(4,2,e,t)},useMemo:function(e,t){var n=va();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=va();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Va.bind(null,ia,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},va().memoizedState=e},useState:Ra,useDebugValue:Ua,useDeferredValue:function(e){return va().memoizedState=e},useTransition:function(){var e=Ra(!1),t=e[0];return e=Ha.bind(null,e[1]),va().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=ia,o=va();if(ss){if(void 0===n)throw Error(s(407));n=n()}else{if(n=t(),null===Ac)throw Error(s(349));30&aa||Ea(r,t,n)}o.memoizedState=n;var a={value:n,getSnapshot:t};return o.queue=a,Da(Ta.bind(null,r,a,e),[e]),r.flags|=2048,Pa(9,Ca.bind(null,r,a,n,t),void 0,null),n},useId:function(){var e=va(),t=Ac.identifierPrefix;if(ss){var n=Zo;t=":"+t+"R"+(n=(Yo&~(1<<32-at(Yo)-1)).toString(32)+n),0<(n=pa++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=fa++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ei={readContext:Ps,useCallback:$a,useContext:Ps,useEffect:Ia,useImperativeHandle:Ba,useInsertionEffect:Ma,useLayoutEffect:Fa,useMemo:qa,useReducer:wa,useRef:Na,useState:function(){return wa(xa)},useDebugValue:Ua,useDeferredValue:function(e){return Xa(ya(),ca.memoizedState,e)},useTransition:function(){return[wa(xa)[0],ya().memoizedState]},useMutableSource:_a,useSyncExternalStore:Sa,useId:Ga,unstable_isNewReconciler:!1},ti={readContext:Ps,useCallback:$a,useContext:Ps,useEffect:Ia,useImperativeHandle:Ba,useInsertionEffect:Ma,useLayoutEffect:Fa,useMemo:qa,useReducer:ka,useRef:Na,useState:function(){return ka(xa)},useDebugValue:Ua,useDeferredValue:function(e){var t=ya();return null===ca?t.memoizedState=e:Xa(t,ca.memoizedState,e)},useTransition:function(){return[ka(xa)[0],ya().memoizedState]},useMutableSource:_a,useSyncExternalStore:Sa,useId:Ga,unstable_isNewReconciler:!1};function ni(e,t){if(e&&e.defaultProps){for(var n in t=M({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}function ri(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:M({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var oi={isMounted:function(e){return!!(e=e._reactInternals)&&$e(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),s=zs(r,o);s.payload=t,null!=n&&(s.callback=n),null!==(t=Bs(e,s,o))&&(nl(t,e,o,r),Us(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),s=zs(r,o);s.tag=1,s.payload=t,null!=n&&(s.callback=n),null!==(t=Bs(e,s,o))&&(nl(t,e,o,r),Us(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=el(),r=tl(e),o=zs(n,r);o.tag=2,null!=t&&(o.callback=t),null!==(t=Bs(e,o,r))&&(nl(t,e,r,n),Us(t,e,r))}};function si(e,t,n,r,o,s,a){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,s,a):!t.prototype||!t.prototype.isPureReactComponent||(!cr(n,r)||!cr(o,s))}function ai(e,t,n){var r=!1,o=jo,s=t.contextType;return"object"==typeof s&&null!==s?s=Ps(s):(o=Lo(t)?Po:Ao.current,s=(r=null!=(r=t.contextTypes))?No(e,o):jo),t=new t(n,s),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=oi,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=s),t}function ii(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&oi.enqueueReplaceState(t,t.state,null)}function ci(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs={},Ms(e);var s=t.contextType;"object"==typeof s&&null!==s?o.context=Ps(s):(s=Lo(t)?Po:Ao.current,o.context=No(e,s)),o.state=e.memoizedState,"function"==typeof(s=t.getDerivedStateFromProps)&&(ri(e,t,s,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&oi.enqueueReplaceState(o,o.state,null),qs(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function li(e,t){try{var n="",r=t;do{n+=U(r),r=r.return}while(r);var o=n}catch(s){o="\nError generating stack: "+s.message+"\n"+s.stack}return{value:e,source:t,stack:o,digest:null}}function di(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function ui(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var pi="function"==typeof WeakMap?WeakMap:Map;function fi(e,t,n){(n=zs(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){Xc||(Xc=!0,Hc=r),ui(0,t)},n}function gi(e,t,n){(n=zs(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return r(o)},n.callback=function(){ui(0,t)}}var s=e.stateNode;return null!==s&&"function"==typeof s.componentDidCatch&&(n.callback=function(){ui(0,t),"function"!=typeof r&&(null===Gc?Gc=new Set([this]):Gc.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function mi(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new pi;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(o.add(n),e=El.bind(null,e,t,n),t.then(e,e))}function hi(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function bi(e,t,n,r,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=zs(-1,1)).tag=2,Bs(n,t,1))),n.lanes|=1),e)}var vi=x.ReactCurrentOwner,yi=!1;function xi(e,t,n,r){t.child=null===e?ks(t,null,n,r):ws(t,e.child,n,r)}function wi(e,t,n,r,o){n=n.render;var s=t.ref;return Rs(t,o),r=ha(e,t,n,r,s,o),n=ba(),null===e||yi?(ss&&n&&ts(t),t.flags|=1,xi(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Xi(e,t,o))}function ki(e,t,n,r,o){if(null===e){var s=n.type;return"function"!=typeof s||Nl(s)||void 0!==s.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Ol(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=s,_i(e,t,s,r,o))}if(s=e.child,!(e.lanes&o)){var a=s.memoizedProps;if((n=null!==(n=n.compare)?n:cr)(a,r)&&e.ref===t.ref)return Xi(e,t,o)}return t.flags|=1,(e=Ll(s,r)).ref=t.ref,e.return=t,t.child=e}function _i(e,t,n,r,o){if(null!==e){var s=e.memoizedProps;if(cr(s,r)&&e.ref===t.ref){if(yi=!1,t.pendingProps=r=s,!(e.lanes&o))return t.lanes=e.lanes,Xi(e,t,o);131072&e.flags&&(yi=!0)}}return Ci(e,t,n,r,o)}function Si(e,t,n){var r=t.pendingProps,o=r.children,s=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==s?s.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,To(Lc,Nc),Nc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==s?s.baseLanes:n,To(Lc,Nc),Nc|=r}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},To(Lc,Nc),Nc|=n;else null!==s?(r=s.baseLanes|n,t.memoizedState=null):r=n,To(Lc,Nc),Nc|=r;return xi(e,t,o,n),t.child}function Ei(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function Ci(e,t,n,r,o){var s=Lo(n)?Po:Ao.current;return s=No(t,s),Rs(t,o),n=ha(e,t,n,r,s,o),r=ba(),null===e||yi?(ss&&r&&ts(t),t.flags|=1,xi(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,Xi(e,t,o))}function Ti(e,t,n,r,o){if(Lo(n)){var s=!0;Mo(t)}else s=!1;if(Rs(t,o),null===t.stateNode)qi(e,t),ai(t,n,r),ci(t,n,r,o),r=!0;else if(null===e){var a=t.stateNode,i=t.memoizedProps;a.props=i;var c=a.context,l=n.contextType;"object"==typeof l&&null!==l?l=Ps(l):l=No(t,l=Lo(n)?Po:Ao.current);var d=n.getDerivedStateFromProps,u="function"==typeof d||"function"==typeof a.getSnapshotBeforeUpdate;u||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(i!==r||c!==l)&&ii(t,a,r,l),Is=!1;var p=t.memoizedState;a.state=p,qs(t,r,a,o),c=t.memoizedState,i!==r||p!==c||Ro.current||Is?("function"==typeof d&&(ri(t,n,d,r),c=t.memoizedState),(i=Is||si(t,n,i,r,p,c,l))?(u||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||("function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount()),"function"==typeof a.componentDidMount&&(t.flags|=4194308)):("function"==typeof a.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=c),a.props=r,a.state=c,a.context=l,r=i):("function"==typeof a.componentDidMount&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,Fs(e,t),i=t.memoizedProps,l=t.type===t.elementType?i:ni(t.type,i),a.props=l,u=t.pendingProps,p=a.context,"object"==typeof(c=n.contextType)&&null!==c?c=Ps(c):c=No(t,c=Lo(n)?Po:Ao.current);var f=n.getDerivedStateFromProps;(d="function"==typeof f||"function"==typeof a.getSnapshotBeforeUpdate)||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(i!==u||p!==c)&&ii(t,a,r,c),Is=!1,p=t.memoizedState,a.state=p,qs(t,r,a,o);var g=t.memoizedState;i!==u||p!==g||Ro.current||Is?("function"==typeof f&&(ri(t,n,f,r),g=t.memoizedState),(l=Is||si(t,n,l,r,p,g,c)||!1)?(d||"function"!=typeof a.UNSAFE_componentWillUpdate&&"function"!=typeof a.componentWillUpdate||("function"==typeof a.componentWillUpdate&&a.componentWillUpdate(r,g,c),"function"==typeof a.UNSAFE_componentWillUpdate&&a.UNSAFE_componentWillUpdate(r,g,c)),"function"==typeof a.componentDidUpdate&&(t.flags|=4),"function"==typeof a.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof a.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=g),a.props=r,a.state=g,a.context=c,r=l):("function"!=typeof a.componentDidUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||i===e.memoizedProps&&p===e.memoizedState||(t.flags|=1024),r=!1)}return ji(e,t,n,r,s,o)}function ji(e,t,n,r,o,s){Ei(e,t);var a=!!(128&t.flags);if(!r&&!a)return o&&Fo(t,n,!1),Xi(e,t,s);r=t.stateNode,vi.current=t;var i=a&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&a?(t.child=ws(t,e.child,null,s),t.child=ws(t,null,i,s)):xi(e,t,i,s),t.memoizedState=r.state,o&&Fo(t,n,!0),t.child}function Ai(e){var t=e.stateNode;t.pendingContext?Do(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Do(0,t.context,!1),Qs(e,t.containerInfo)}function Ri(e,t,n,r,o){return gs(),ms(o),t.flags|=256,xi(e,t,n,r),t.child}var Pi,Ni,Li,Oi,Di={dehydrated:null,treeContext:null,retryLane:0};function Ii(e){return{baseLanes:e,cachePool:null,transitions:null}}function Mi(e,t,n){var r,o=t.pendingProps,a=ea.current,i=!1,c=!!(128&t.flags);if((r=c)||(r=(null===e||null!==e.memoizedState)&&!!(2&a)),r?(i=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(a|=1),To(ea,1&a),null===e)return ds(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(c=o.children,e=o.fallback,i?(o=t.mode,i=t.child,c={mode:"hidden",children:c},1&o||null===i?i=Il(c,o,0,null):(i.childLanes=0,i.pendingProps=c),e=Dl(e,o,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Ii(n),t.memoizedState=Di,e):Fi(t,c));if(null!==(a=e.memoizedState)&&null!==(r=a.dehydrated))return function(e,t,n,r,o,a,i){if(n)return 256&t.flags?(t.flags&=-257,zi(e,t,i,r=di(Error(s(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(a=r.fallback,o=t.mode,r=Il({mode:"visible",children:r.children},o,0,null),(a=Dl(a,o,i,null)).flags|=2,r.return=t,a.return=t,r.sibling=a,t.child=r,1&t.mode&&ws(t,e.child,null,i),t.child.memoizedState=Ii(i),t.memoizedState=Di,a);if(!(1&t.mode))return zi(e,t,i,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var c=r.dgst;return r=c,zi(e,t,i,r=di(a=Error(s(419)),r,void 0))}if(c=!!(i&e.childLanes),yi||c){if(null!==(r=Ac)){switch(i&-i){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(r.suspendedLanes|i)?0:o)&&o!==a.retryLane&&(a.retryLane=o,Ds(e,o),nl(r,e,o,-1))}return ml(),zi(e,t,i,r=di(Error(s(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=Tl.bind(null,e),o._reactRetry=t,null):(e=a.treeContext,os=lo(o.nextSibling),rs=t,ss=!0,as=null,null!==e&&(Wo[Ko++]=Yo,Wo[Ko++]=Zo,Wo[Ko++]=Qo,Yo=e.id,Zo=e.overflow,Qo=t),t=Fi(t,r.children),t.flags|=4096,t)}(e,t,c,o,r,a,n);if(i){i=o.fallback,c=t.mode,r=(a=e.child).sibling;var l={mode:"hidden",children:o.children};return 1&c||t.child===a?(o=Ll(a,l)).subtreeFlags=14680064&a.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=l,t.deletions=null),null!==r?i=Ll(r,i):(i=Dl(i,c,n,null)).flags|=2,i.return=t,o.return=t,o.sibling=i,t.child=o,o=i,i=t.child,c=null===(c=e.child.memoizedState)?Ii(n):{baseLanes:c.baseLanes|n,cachePool:null,transitions:c.transitions},i.memoizedState=c,i.childLanes=e.childLanes&~n,t.memoizedState=Di,o}return e=(i=e.child).sibling,o=Ll(i,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Fi(e,t){return(t=Il({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function zi(e,t,n,r){return null!==r&&ms(r),ws(t,e.child,null,n),(e=Fi(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function Bi(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),As(e.return,t,n)}function Ui(e,t,n,r,o){var s=e.memoizedState;null===s?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(s.isBackwards=t,s.rendering=null,s.renderingStartTime=0,s.last=r,s.tail=n,s.tailMode=o)}function $i(e,t,n){var r=t.pendingProps,o=r.revealOrder,s=r.tail;if(xi(e,t,r.children,n),2&(r=ea.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&Bi(e,n,t);else if(19===e.tag)Bi(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(To(ea,r),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===ta(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),Ui(t,!1,o,n,s);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===ta(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}Ui(t,!0,n,null,s);break;case"together":Ui(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function qi(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function Xi(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Ic|=t.lanes,!(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(s(153));if(null!==t.child){for(n=Ll(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Ll(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Hi(e,t){if(!ss)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Gi(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function Vi(e,t,n){var r=t.pendingProps;switch(ns(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Gi(t),null;case 1:case 17:return Lo(t.type)&&Oo(),Gi(t),null;case 3:return r=t.stateNode,Ys(),Co(Ro),Co(Ao),ra(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(ps(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==as&&(al(as),as=null))),Ni(e,t),Gi(t),null;case 5:Js(t);var o=Ks(Ws.current);if(n=t.type,null!==e&&null!=t.stateNode)Li(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(null===t.stateNode)throw Error(s(166));return Gi(t),null}if(e=Ks(Gs.current),ps(t)){r=t.stateNode,n=t.type;var a=t.memoizedProps;switch(r[fo]=t,r[go]=a,e=!!(1&t.mode),n){case"dialog":zr("cancel",r),zr("close",r);break;case"iframe":case"object":case"embed":zr("load",r);break;case"video":case"audio":for(o=0;o<Dr.length;o++)zr(Dr[o],r);break;case"source":zr("error",r);break;case"img":case"image":case"link":zr("error",r),zr("load",r);break;case"details":zr("toggle",r);break;case"input":Q(r,a),zr("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!a.multiple},zr("invalid",r);break;case"textarea":oe(r,a),zr("invalid",r)}for(var c in ve(n,a),o=null,a)if(a.hasOwnProperty(c)){var l=a[c];"children"===c?"string"==typeof l?r.textContent!==l&&(!0!==a.suppressHydrationWarning&&Zr(r.textContent,l,e),o=["children",l]):"number"==typeof l&&r.textContent!==""+l&&(!0!==a.suppressHydrationWarning&&Zr(r.textContent,l,e),o=["children",""+l]):i.hasOwnProperty(c)&&null!=l&&"onScroll"===c&&zr("scroll",r)}switch(n){case"input":G(r),J(r,a,!0);break;case"textarea":G(r),ae(r);break;case"select":case"option":break;default:"function"==typeof a.onClick&&(r.onclick=Jr)}r=o,t.updateQueue=r,null!==r&&(t.flags|=4)}else{c=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=ie(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[fo]=t,e[go]=r,Pi(e,t,!1,!1),t.stateNode=e;e:{switch(c=ye(n,r),n){case"dialog":zr("cancel",e),zr("close",e),o=r;break;case"iframe":case"object":case"embed":zr("load",e),o=r;break;case"video":case"audio":for(o=0;o<Dr.length;o++)zr(Dr[o],e);o=r;break;case"source":zr("error",e),o=r;break;case"img":case"image":case"link":zr("error",e),zr("load",e),o=r;break;case"details":zr("toggle",e),o=r;break;case"input":Q(e,r),o=K(e,r),zr("invalid",e);break;case"option":default:o=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=M({},r,{value:void 0}),zr("invalid",e);break;case"textarea":oe(e,r),o=re(e,r),zr("invalid",e)}for(a in ve(n,o),l=o)if(l.hasOwnProperty(a)){var d=l[a];"style"===a?he(e,d):"dangerouslySetInnerHTML"===a?null!=(d=d?d.__html:void 0)&&ue(e,d):"children"===a?"string"==typeof d?("textarea"!==n||""!==d)&&pe(e,d):"number"==typeof d&&pe(e,""+d):"suppressContentEditableWarning"!==a&&"suppressHydrationWarning"!==a&&"autoFocus"!==a&&(i.hasOwnProperty(a)?null!=d&&"onScroll"===a&&zr("scroll",e):null!=d&&y(e,a,d,c))}switch(n){case"input":G(e),J(e,r,!1);break;case"textarea":G(e),ae(e);break;case"option":null!=r.value&&e.setAttribute("value",""+X(r.value));break;case"select":e.multiple=!!r.multiple,null!=(a=r.value)?ne(e,!!r.multiple,a,!1):null!=r.defaultValue&&ne(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Jr)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Gi(t),null;case 6:if(e&&null!=t.stateNode)Oi(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(s(166));if(n=Ks(Ws.current),Ks(Gs.current),ps(t)){if(r=t.stateNode,n=t.memoizedProps,r[fo]=t,(a=r.nodeValue!==n)&&null!==(e=rs))switch(e.tag){case 3:Zr(r.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Zr(r.nodeValue,n,!!(1&e.mode))}a&&(t.flags|=4)}else(r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[fo]=t,t.stateNode=r}return Gi(t),null;case 13:if(Co(ea),r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(ss&&null!==os&&1&t.mode&&!(128&t.flags))fs(),gs(),t.flags|=98560,a=!1;else if(a=ps(t),null!==r&&null!==r.dehydrated){if(null===e){if(!a)throw Error(s(318));if(!(a=null!==(a=t.memoizedState)?a.dehydrated:null))throw Error(s(317));a[fo]=t}else gs(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Gi(t),a=!1}else null!==as&&(al(as),as=null),a=!0;if(!a)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(t.child.flags|=8192,1&t.mode&&(null===e||1&ea.current?0===Oc&&(Oc=3):ml())),null!==t.updateQueue&&(t.flags|=4),Gi(t),null);case 4:return Ys(),Ni(e,t),null===e&&$r(t.stateNode.containerInfo),Gi(t),null;case 10:return js(t.type._context),Gi(t),null;case 19:if(Co(ea),null===(a=t.memoizedState))return Gi(t),null;if(r=!!(128&t.flags),null===(c=a.rendering))if(r)Hi(a,!1);else{if(0!==Oc||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(c=ta(e))){for(t.flags|=128,Hi(a,!1),null!==(r=c.updateQueue)&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;null!==n;)e=r,(a=n).flags&=14680066,null===(c=a.alternate)?(a.childLanes=0,a.lanes=e,a.child=null,a.subtreeFlags=0,a.memoizedProps=null,a.memoizedState=null,a.updateQueue=null,a.dependencies=null,a.stateNode=null):(a.childLanes=c.childLanes,a.lanes=c.lanes,a.child=c.child,a.subtreeFlags=0,a.deletions=null,a.memoizedProps=c.memoizedProps,a.memoizedState=c.memoizedState,a.updateQueue=c.updateQueue,a.type=c.type,e=c.dependencies,a.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return To(ea,1&ea.current|2),t.child}e=e.sibling}null!==a.tail&&Ye()>$c&&(t.flags|=128,r=!0,Hi(a,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=ta(c))){if(t.flags|=128,r=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Hi(a,!0),null===a.tail&&"hidden"===a.tailMode&&!c.alternate&&!ss)return Gi(t),null}else 2*Ye()-a.renderingStartTime>$c&&1073741824!==n&&(t.flags|=128,r=!0,Hi(a,!1),t.lanes=4194304);a.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=a.last)?n.sibling=c:t.child=c,a.last=c)}return null!==a.tail?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=Ye(),t.sibling=null,n=ea.current,To(ea,r?1&n|2:1&n),t):(Gi(t),null);case 22:case 23:return ul(),r=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==r&&(t.flags|=8192),r&&1&t.mode?!!(1073741824&Nc)&&(Gi(t),6&t.subtreeFlags&&(t.flags|=8192)):Gi(t),null;case 24:case 25:return null}throw Error(s(156,t.tag))}function Wi(e,t){switch(ns(t),t.tag){case 1:return Lo(t.type)&&Oo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return Ys(),Co(Ro),Co(Ao),ra(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return Js(t),null;case 13:if(Co(ea),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(s(340));gs()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return Co(ea),null;case 4:return Ys(),null;case 10:return js(t.type._context),null;case 22:case 23:return ul(),null;default:return null}}Pi=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Ni=function(){},Li=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ks(Gs.current);var s,a=null;switch(n){case"input":o=K(e,o),r=K(e,r),a=[];break;case"select":o=M({},o,{value:void 0}),r=M({},r,{value:void 0}),a=[];break;case"textarea":o=re(e,o),r=re(e,r),a=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Jr)}for(d in ve(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(s in c)c.hasOwnProperty(s)&&(n||(n={}),n[s]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(i.hasOwnProperty(d)?a||(a=[]):(a=a||[]).push(d,null));for(d in r){var l=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&l!==c&&(null!=l||null!=c))if("style"===d)if(c){for(s in c)!c.hasOwnProperty(s)||l&&l.hasOwnProperty(s)||(n||(n={}),n[s]="");for(s in l)l.hasOwnProperty(s)&&c[s]!==l[s]&&(n||(n={}),n[s]=l[s])}else n||(a||(a=[]),a.push(d,n)),n=l;else"dangerouslySetInnerHTML"===d?(l=l?l.__html:void 0,c=c?c.__html:void 0,null!=l&&c!==l&&(a=a||[]).push(d,l)):"children"===d?"string"!=typeof l&&"number"!=typeof l||(a=a||[]).push(d,""+l):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(i.hasOwnProperty(d)?(null!=l&&"onScroll"===d&&zr("scroll",e),a||c===l||(a=[])):(a=a||[]).push(d,l))}n&&(a=a||[]).push("style",n);var d=a;(t.updateQueue=d)&&(t.flags|=4)}},Oi=function(e,t,n,r){n!==r&&(t.flags|=4)};var Ki=!1,Qi=!1,Yi="function"==typeof WeakSet?WeakSet:Set,Zi=null;function Ji(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){Sl(e,t,r)}else n.current=null}function ec(e,t,n){try{n()}catch(r){Sl(e,t,r)}}var tc=!1;function nc(e,t,n){var r=t.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&e)===e){var s=o.destroy;o.destroy=void 0,void 0!==s&&ec(t,n,s)}o=o.next}while(o!==r)}}function rc(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function oc(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function sc(e){var t=e.alternate;null!==t&&(e.alternate=null,sc(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[fo],delete t[go],delete t[ho],delete t[bo],delete t[vo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function ac(e){return 5===e.tag||3===e.tag||4===e.tag}function ic(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||ac(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Jr));else if(4!==r&&null!==(e=e.child))for(cc(e,t,n),e=e.sibling;null!==e;)cc(e,t,n),e=e.sibling}function lc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(lc(e,t,n),e=e.sibling;null!==e;)lc(e,t,n),e=e.sibling}var dc=null,uc=!1;function pc(e,t,n){for(n=n.child;null!==n;)fc(e,t,n),n=n.sibling}function fc(e,t,n){if(st&&"function"==typeof st.onCommitFiberUnmount)try{st.onCommitFiberUnmount(ot,n)}catch(i){}switch(n.tag){case 5:Qi||Ji(n,t);case 6:var r=dc,o=uc;dc=null,pc(e,t,n),uc=o,null!==(dc=r)&&(uc?(e=dc,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):dc.removeChild(n.stateNode));break;case 18:null!==dc&&(uc?(e=dc,n=n.stateNode,8===e.nodeType?co(e.parentNode,n):1===e.nodeType&&co(e,n),$t(e)):co(dc,n.stateNode));break;case 4:r=dc,o=uc,dc=n.stateNode.containerInfo,uc=!0,pc(e,t,n),dc=r,uc=o;break;case 0:case 11:case 14:case 15:if(!Qi&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var s=o,a=s.destroy;s=s.tag,void 0!==a&&(2&s||4&s)&&ec(n,t,a),o=o.next}while(o!==r)}pc(e,t,n);break;case 1:if(!Qi&&(Ji(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(i){Sl(n,t,i)}pc(e,t,n);break;case 21:pc(e,t,n);break;case 22:1&n.mode?(Qi=(r=Qi)||null!==n.memoizedState,pc(e,t,n),Qi=r):pc(e,t,n);break;default:pc(e,t,n)}}function gc(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Yi),t.forEach((function(t){var r=jl.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function mc(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var o=n[r];try{var a=e,i=t,c=i;e:for(;null!==c;){switch(c.tag){case 5:dc=c.stateNode,uc=!1;break e;case 3:case 4:dc=c.stateNode.containerInfo,uc=!0;break e}c=c.return}if(null===dc)throw Error(s(160));fc(a,i,o),dc=null,uc=!1;var l=o.alternate;null!==l&&(l.return=null),o.return=null}catch(d){Sl(o,t,d)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)hc(t,e),t=t.sibling}function hc(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(mc(t,e),bc(e),4&r){try{nc(3,e,e.return),rc(3,e)}catch(h){Sl(e,e.return,h)}try{nc(5,e,e.return)}catch(h){Sl(e,e.return,h)}}break;case 1:mc(t,e),bc(e),512&r&&null!==n&&Ji(n,n.return);break;case 5:if(mc(t,e),bc(e),512&r&&null!==n&&Ji(n,n.return),32&e.flags){var o=e.stateNode;try{pe(o,"")}catch(h){Sl(e,e.return,h)}}if(4&r&&null!=(o=e.stateNode)){var a=e.memoizedProps,i=null!==n?n.memoizedProps:a,c=e.type,l=e.updateQueue;if(e.updateQueue=null,null!==l)try{"input"===c&&"radio"===a.type&&null!=a.name&&Y(o,a),ye(c,i);var d=ye(c,a);for(i=0;i<l.length;i+=2){var u=l[i],p=l[i+1];"style"===u?he(o,p):"dangerouslySetInnerHTML"===u?ue(o,p):"children"===u?pe(o,p):y(o,u,p,d)}switch(c){case"input":Z(o,a);break;case"textarea":se(o,a);break;case"select":var f=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!a.multiple;var g=a.value;null!=g?ne(o,!!a.multiple,g,!1):f!==!!a.multiple&&(null!=a.defaultValue?ne(o,!!a.multiple,a.defaultValue,!0):ne(o,!!a.multiple,a.multiple?[]:"",!1))}o[go]=a}catch(h){Sl(e,e.return,h)}}break;case 6:if(mc(t,e),bc(e),4&r){if(null===e.stateNode)throw Error(s(162));o=e.stateNode,a=e.memoizedProps;try{o.nodeValue=a}catch(h){Sl(e,e.return,h)}}break;case 3:if(mc(t,e),bc(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{$t(t.containerInfo)}catch(h){Sl(e,e.return,h)}break;case 4:default:mc(t,e),bc(e);break;case 13:mc(t,e),bc(e),8192&(o=e.child).flags&&(a=null!==o.memoizedState,o.stateNode.isHidden=a,!a||null!==o.alternate&&null!==o.alternate.memoizedState||(Uc=Ye())),4&r&&gc(e);break;case 22:if(u=null!==n&&null!==n.memoizedState,1&e.mode?(Qi=(d=Qi)||u,mc(t,e),Qi=d):mc(t,e),bc(e),8192&r){if(d=null!==e.memoizedState,(e.stateNode.isHidden=d)&&!u&&1&e.mode)for(Zi=e,u=e.child;null!==u;){for(p=Zi=u;null!==Zi;){switch(g=(f=Zi).child,f.tag){case 0:case 11:case 14:case 15:nc(4,f,f.return);break;case 1:Ji(f,f.return);var m=f.stateNode;if("function"==typeof m.componentWillUnmount){r=f,n=f.return;try{t=r,m.props=t.memoizedProps,m.state=t.memoizedState,m.componentWillUnmount()}catch(h){Sl(r,n,h)}}break;case 5:Ji(f,f.return);break;case 22:if(null!==f.memoizedState){wc(p);continue}}null!==g?(g.return=f,Zi=g):wc(p)}u=u.sibling}e:for(u=null,p=e;;){if(5===p.tag){if(null===u){u=p;try{o=p.stateNode,d?"function"==typeof(a=o.style).setProperty?a.setProperty("display","none","important"):a.display="none":(c=p.stateNode,i=null!=(l=p.memoizedProps.style)&&l.hasOwnProperty("display")?l.display:null,c.style.display=me("display",i))}catch(h){Sl(e,e.return,h)}}}else if(6===p.tag){if(null===u)try{p.stateNode.nodeValue=d?"":p.memoizedProps}catch(h){Sl(e,e.return,h)}}else if((22!==p.tag&&23!==p.tag||null===p.memoizedState||p===e)&&null!==p.child){p.child.return=p,p=p.child;continue}if(p===e)break e;for(;null===p.sibling;){if(null===p.return||p.return===e)break e;u===p&&(u=null),p=p.return}u===p&&(u=null),p.sibling.return=p.return,p=p.sibling}}break;case 19:mc(t,e),bc(e),4&r&&gc(e);case 21:}}function bc(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(ac(n)){var r=n;break e}n=n.return}throw Error(s(160))}switch(r.tag){case 5:var o=r.stateNode;32&r.flags&&(pe(o,""),r.flags&=-33),lc(e,ic(e),o);break;case 3:case 4:var a=r.stateNode.containerInfo;cc(e,ic(e),a);break;default:throw Error(s(161))}}catch(i){Sl(e,e.return,i)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function vc(e,t,n){Zi=e,yc(e,t,n)}function yc(e,t,n){for(var r=!!(1&e.mode);null!==Zi;){var o=Zi,s=o.child;if(22===o.tag&&r){var a=null!==o.memoizedState||Ki;if(!a){var i=o.alternate,c=null!==i&&null!==i.memoizedState||Qi;i=Ki;var l=Qi;if(Ki=a,(Qi=c)&&!l)for(Zi=o;null!==Zi;)c=(a=Zi).child,22===a.tag&&null!==a.memoizedState?kc(o):null!==c?(c.return=a,Zi=c):kc(o);for(;null!==s;)Zi=s,yc(s,t,n),s=s.sibling;Zi=o,Ki=i,Qi=l}xc(e)}else 8772&o.subtreeFlags&&null!==s?(s.return=o,Zi=s):xc(e)}}function xc(e){for(;null!==Zi;){var t=Zi;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Qi||rc(5,t);break;case 1:var r=t.stateNode;if(4&t.flags&&!Qi)if(null===n)r.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ni(t.type,n.memoizedProps);r.componentDidUpdate(o,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var a=t.updateQueue;null!==a&&Xs(t,a,r);break;case 3:var i=t.updateQueue;if(null!==i){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}Xs(t,i,n)}break;case 5:var c=t.stateNode;if(null===n&&4&t.flags){n=c;var l=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":l.autoFocus&&n.focus();break;case"img":l.src&&(n.src=l.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var d=t.alternate;if(null!==d){var u=d.memoizedState;if(null!==u){var p=u.dehydrated;null!==p&&$t(p)}}}break;default:throw Error(s(163))}Qi||512&t.flags&&oc(t)}catch(f){Sl(t,t.return,f)}}if(t===e){Zi=null;break}if(null!==(n=t.sibling)){n.return=t.return,Zi=n;break}Zi=t.return}}function wc(e){for(;null!==Zi;){var t=Zi;if(t===e){Zi=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Zi=n;break}Zi=t.return}}function kc(e){for(;null!==Zi;){var t=Zi;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{rc(4,t)}catch(c){Sl(t,n,c)}break;case 1:var r=t.stateNode;if("function"==typeof r.componentDidMount){var o=t.return;try{r.componentDidMount()}catch(c){Sl(t,o,c)}}var s=t.return;try{oc(t)}catch(c){Sl(t,s,c)}break;case 5:var a=t.return;try{oc(t)}catch(c){Sl(t,a,c)}}}catch(c){Sl(t,t.return,c)}if(t===e){Zi=null;break}var i=t.sibling;if(null!==i){i.return=t.return,Zi=i;break}Zi=t.return}}var _c,Sc=Math.ceil,Ec=x.ReactCurrentDispatcher,Cc=x.ReactCurrentOwner,Tc=x.ReactCurrentBatchConfig,jc=0,Ac=null,Rc=null,Pc=0,Nc=0,Lc=Eo(0),Oc=0,Dc=null,Ic=0,Mc=0,Fc=0,zc=null,Bc=null,Uc=0,$c=1/0,qc=null,Xc=!1,Hc=null,Gc=null,Vc=!1,Wc=null,Kc=0,Qc=0,Yc=null,Zc=-1,Jc=0;function el(){return 6&jc?Ye():-1!==Zc?Zc:Zc=Ye()}function tl(e){return 1&e.mode?2&jc&&0!==Pc?Pc&-Pc:null!==hs.transition?(0===Jc&&(Jc=mt()),Jc):0!==(e=yt)?e:e=void 0===(e=window.event)?16:Qt(e.type):1}function nl(e,t,n,r){if(50<Qc)throw Qc=0,Yc=null,Error(s(185));bt(e,n,r),2&jc&&e===Ac||(e===Ac&&(!(2&jc)&&(Mc|=n),4===Oc&&il(e,Pc)),rl(e,r),1===n&&0===jc&&!(1&t.mode)&&($c=Ye()+500,Bo&&qo()))}function rl(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,s=e.pendingLanes;0<s;){var a=31-at(s),i=1<<a,c=o[a];-1===c?i&n&&!(i&r)||(o[a]=ft(i,t)):c<=t&&(e.expiredLanes|=i),s&=~i}}(e,t);var r=pt(e,e===Ac?Pc:0);if(0===r)null!==n&&We(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(null!=n&&We(n),1===t)0===e.tag?function(e){Bo=!0,$o(e)}(cl.bind(null,e)):$o(cl.bind(null,e)),ao((function(){!(6&jc)&&qo()})),n=null;else{switch(xt(r)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=rt}n=Al(n,ol.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function ol(e,t){if(Zc=-1,Jc=0,6&jc)throw Error(s(327));var n=e.callbackNode;if(kl()&&e.callbackNode!==n)return null;var r=pt(e,e===Ac?Pc:0);if(0===r)return null;if(30&r||r&e.expiredLanes||t)t=hl(e,r);else{t=r;var o=jc;jc|=2;var a=gl();for(Ac===e&&Pc===t||(qc=null,$c=Ye()+500,pl(e,t));;)try{vl();break}catch(c){fl(e,c)}Ts(),Ec.current=a,jc=o,null!==Rc?t=0:(Ac=null,Pc=0,t=Oc)}if(0!==t){if(2===t&&(0!==(o=gt(e))&&(r=o,t=sl(e,o))),1===t)throw n=Dc,pl(e,0),il(e,r),rl(e,Ye()),n;if(6===t)il(e,r);else{if(o=e.current.alternate,!(30&r||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var r=0;r<n.length;r++){var o=n[r],s=o.getSnapshot;o=o.value;try{if(!ir(s(),o))return!1}catch(i){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=hl(e,r),2===t&&(a=gt(e),0!==a&&(r=a,t=sl(e,a))),1!==t)))throw n=Dc,pl(e,0),il(e,r),rl(e,Ye()),n;switch(e.finishedWork=o,e.finishedLanes=r,t){case 0:case 1:throw Error(s(345));case 2:case 5:wl(e,Bc,qc);break;case 3:if(il(e,r),(130023424&r)===r&&10<(t=Uc+500-Ye())){if(0!==pt(e,0))break;if(((o=e.suspendedLanes)&r)!==r){el(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ro(wl.bind(null,e,Bc,qc),t);break}wl(e,Bc,qc);break;case 4:if(il(e,r),(4194240&r)===r)break;for(t=e.eventTimes,o=-1;0<r;){var i=31-at(r);a=1<<i,(i=t[i])>o&&(o=i),r&=~a}if(r=o,10<(r=(120>(r=Ye()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Sc(r/1960))-r)){e.timeoutHandle=ro(wl.bind(null,e,Bc,qc),r);break}wl(e,Bc,qc);break;default:throw Error(s(329))}}}return rl(e,Ye()),e.callbackNode===n?ol.bind(null,e):null}function sl(e,t){var n=zc;return e.current.memoizedState.isDehydrated&&(pl(e,t).flags|=256),2!==(e=hl(e,t))&&(t=Bc,Bc=n,null!==t&&al(t)),e}function al(e){null===Bc?Bc=e:Bc.push.apply(Bc,e)}function il(e,t){for(t&=~Fc,t&=~Mc,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-at(t),r=1<<n;e[n]=-1,t&=~r}}function cl(e){if(6&jc)throw Error(s(327));kl();var t=pt(e,0);if(!(1&t))return rl(e,Ye()),null;var n=hl(e,t);if(0!==e.tag&&2===n){var r=gt(e);0!==r&&(t=r,n=sl(e,r))}if(1===n)throw n=Dc,pl(e,0),il(e,t),rl(e,Ye()),n;if(6===n)throw Error(s(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,wl(e,Bc,qc),rl(e,Ye()),null}function ll(e,t){var n=jc;jc|=1;try{return e(t)}finally{0===(jc=n)&&($c=Ye()+500,Bo&&qo())}}function dl(e){null!==Wc&&0===Wc.tag&&!(6&jc)&&kl();var t=jc;jc|=1;var n=Tc.transition,r=yt;try{if(Tc.transition=null,yt=1,e)return e()}finally{yt=r,Tc.transition=n,!(6&(jc=t))&&qo()}}function ul(){Nc=Lc.current,Co(Lc)}function pl(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Rc)for(n=Rc.return;null!==n;){var r=n;switch(ns(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Oo();break;case 3:Ys(),Co(Ro),Co(Ao),ra();break;case 5:Js(r);break;case 4:Ys();break;case 13:case 19:Co(ea);break;case 10:js(r.type._context);break;case 22:case 23:ul()}n=n.return}if(Ac=e,Rc=e=Ll(e.current,null),Pc=Nc=t,Oc=0,Dc=null,Fc=Mc=Ic=0,Bc=zc=null,null!==Ns){for(t=0;t<Ns.length;t++)if(null!==(r=(n=Ns[t]).interleaved)){n.interleaved=null;var o=r.next,s=n.pending;if(null!==s){var a=s.next;s.next=o,r.next=a}n.pending=r}Ns=null}return e}function fl(e,t){for(;;){var n=Rc;try{if(Ts(),oa.current=Za,da){for(var r=ia.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}da=!1}if(aa=0,la=ca=ia=null,ua=!1,pa=0,Cc.current=null,null===n||null===n.return){Oc=1,Dc=t,Rc=null;break}e:{var a=e,i=n.return,c=n,l=t;if(t=Pc,c.flags|=32768,null!==l&&"object"==typeof l&&"function"==typeof l.then){var d=l,u=c,p=u.tag;if(!(1&u.mode||0!==p&&11!==p&&15!==p)){var f=u.alternate;f?(u.updateQueue=f.updateQueue,u.memoizedState=f.memoizedState,u.lanes=f.lanes):(u.updateQueue=null,u.memoizedState=null)}var g=hi(i);if(null!==g){g.flags&=-257,bi(g,i,c,0,t),1&g.mode&&mi(a,d,t),l=d;var m=(t=g).updateQueue;if(null===m){var h=new Set;h.add(l),t.updateQueue=h}else m.add(l);break e}if(!(1&t)){mi(a,d,t),ml();break e}l=Error(s(426))}else if(ss&&1&c.mode){var b=hi(i);if(null!==b){!(65536&b.flags)&&(b.flags|=256),bi(b,i,c,0,t),ms(li(l,c));break e}}a=l=li(l,c),4!==Oc&&(Oc=2),null===zc?zc=[a]:zc.push(a),a=i;do{switch(a.tag){case 3:a.flags|=65536,t&=-t,a.lanes|=t,$s(a,fi(0,l,t));break e;case 1:c=l;var v=a.type,y=a.stateNode;if(!(128&a.flags||"function"!=typeof v.getDerivedStateFromError&&(null===y||"function"!=typeof y.componentDidCatch||null!==Gc&&Gc.has(y)))){a.flags|=65536,t&=-t,a.lanes|=t,$s(a,gi(a,c,t));break e}}a=a.return}while(null!==a)}xl(n)}catch(x){t=x,Rc===n&&null!==n&&(Rc=n=n.return);continue}break}}function gl(){var e=Ec.current;return Ec.current=Za,null===e?Za:e}function ml(){0!==Oc&&3!==Oc&&2!==Oc||(Oc=4),null===Ac||!(268435455&Ic)&&!(268435455&Mc)||il(Ac,Pc)}function hl(e,t){var n=jc;jc|=2;var r=gl();for(Ac===e&&Pc===t||(qc=null,pl(e,t));;)try{bl();break}catch(o){fl(e,o)}if(Ts(),jc=n,Ec.current=r,null!==Rc)throw Error(s(261));return Ac=null,Pc=0,Oc}function bl(){for(;null!==Rc;)yl(Rc)}function vl(){for(;null!==Rc&&!Ke();)yl(Rc)}function yl(e){var t=_c(e.alternate,e,Nc);e.memoizedProps=e.pendingProps,null===t?xl(e):Rc=t,Cc.current=null}function xl(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Wi(n,t)))return n.flags&=32767,void(Rc=n);if(null===e)return Oc=6,void(Rc=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=Vi(n,t,Nc)))return void(Rc=n);if(null!==(t=t.sibling))return void(Rc=t);Rc=t=e}while(null!==t);0===Oc&&(Oc=5)}function wl(e,t,n){var r=yt,o=Tc.transition;try{Tc.transition=null,yt=1,function(e,t,n,r){do{kl()}while(null!==Wc);if(6&jc)throw Error(s(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(s(177));e.callbackNode=null,e.callbackPriority=0;var a=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-at(n),s=1<<o;t[o]=0,r[o]=-1,e[o]=-1,n&=~s}}(e,a),e===Ac&&(Rc=Ac=null,Pc=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||Vc||(Vc=!0,Al(tt,(function(){return kl(),null}))),a=!!(15990&n.flags),!!(15990&n.subtreeFlags)||a){a=Tc.transition,Tc.transition=null;var i=yt;yt=1;var c=jc;jc|=4,Cc.current=null,function(e,t){if(eo=Xt,fr(e=pr())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var o=r.anchorOffset,a=r.focusNode;r=r.focusOffset;try{n.nodeType,a.nodeType}catch(w){n=null;break e}var i=0,c=-1,l=-1,d=0,u=0,p=e,f=null;t:for(;;){for(var g;p!==n||0!==o&&3!==p.nodeType||(c=i+o),p!==a||0!==r&&3!==p.nodeType||(l=i+r),3===p.nodeType&&(i+=p.nodeValue.length),null!==(g=p.firstChild);)f=p,p=g;for(;;){if(p===e)break t;if(f===n&&++d===o&&(c=i),f===a&&++u===r&&(l=i),null!==(g=p.nextSibling))break;f=(p=f).parentNode}p=g}n=-1===c||-1===l?null:{start:c,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},Xt=!1,Zi=t;null!==Zi;)if(e=(t=Zi).child,1028&t.subtreeFlags&&null!==e)e.return=t,Zi=e;else for(;null!==Zi;){t=Zi;try{var m=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==m){var h=m.memoizedProps,b=m.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?h:ni(t.type,h),b);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var x=t.stateNode.containerInfo;1===x.nodeType?x.textContent="":9===x.nodeType&&x.documentElement&&x.removeChild(x.documentElement);break;default:throw Error(s(163))}}catch(w){Sl(t,t.return,w)}if(null!==(e=t.sibling)){e.return=t.return,Zi=e;break}Zi=t.return}m=tc,tc=!1}(e,n),hc(n,e),gr(to),Xt=!!eo,to=eo=null,e.current=n,vc(n,e,o),Qe(),jc=c,yt=i,Tc.transition=a}else e.current=n;if(Vc&&(Vc=!1,Wc=e,Kc=o),a=e.pendingLanes,0===a&&(Gc=null),function(e){if(st&&"function"==typeof st.onCommitFiberRoot)try{st.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),rl(e,Ye()),null!==t)for(r=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],r(o.value,{componentStack:o.stack,digest:o.digest});if(Xc)throw Xc=!1,e=Hc,Hc=null,e;!!(1&Kc)&&0!==e.tag&&kl(),a=e.pendingLanes,1&a?e===Yc?Qc++:(Qc=0,Yc=e):Qc=0,qo()}(e,t,n,r)}finally{Tc.transition=o,yt=r}return null}function kl(){if(null!==Wc){var e=xt(Kc),t=Tc.transition,n=yt;try{if(Tc.transition=null,yt=16>e?16:e,null===Wc)var r=!1;else{if(e=Wc,Wc=null,Kc=0,6&jc)throw Error(s(331));var o=jc;for(jc|=4,Zi=e.current;null!==Zi;){var a=Zi,i=a.child;if(16&Zi.flags){var c=a.deletions;if(null!==c){for(var l=0;l<c.length;l++){var d=c[l];for(Zi=d;null!==Zi;){var u=Zi;switch(u.tag){case 0:case 11:case 15:nc(8,u,a)}var p=u.child;if(null!==p)p.return=u,Zi=p;else for(;null!==Zi;){var f=(u=Zi).sibling,g=u.return;if(sc(u),u===d){Zi=null;break}if(null!==f){f.return=g,Zi=f;break}Zi=g}}}var m=a.alternate;if(null!==m){var h=m.child;if(null!==h){m.child=null;do{var b=h.sibling;h.sibling=null,h=b}while(null!==h)}}Zi=a}}if(2064&a.subtreeFlags&&null!==i)i.return=a,Zi=i;else e:for(;null!==Zi;){if(2048&(a=Zi).flags)switch(a.tag){case 0:case 11:case 15:nc(9,a,a.return)}var v=a.sibling;if(null!==v){v.return=a.return,Zi=v;break e}Zi=a.return}}var y=e.current;for(Zi=y;null!==Zi;){var x=(i=Zi).child;if(2064&i.subtreeFlags&&null!==x)x.return=i,Zi=x;else e:for(i=y;null!==Zi;){if(2048&(c=Zi).flags)try{switch(c.tag){case 0:case 11:case 15:rc(9,c)}}catch(k){Sl(c,c.return,k)}if(c===i){Zi=null;break e}var w=c.sibling;if(null!==w){w.return=c.return,Zi=w;break e}Zi=c.return}}if(jc=o,qo(),st&&"function"==typeof st.onPostCommitFiberRoot)try{st.onPostCommitFiberRoot(ot,e)}catch(k){}r=!0}return r}finally{yt=n,Tc.transition=t}}return!1}function _l(e,t,n){e=Bs(e,t=fi(0,t=li(n,t),1),1),t=el(),null!==e&&(bt(e,1,t),rl(e,t))}function Sl(e,t,n){if(3===e.tag)_l(e,e,n);else for(;null!==t;){if(3===t.tag){_l(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Gc||!Gc.has(r))){t=Bs(t,e=gi(t,e=li(n,e),1),1),e=el(),null!==t&&(bt(t,1,e),rl(t,e));break}}t=t.return}}function El(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=el(),e.pingedLanes|=e.suspendedLanes&n,Ac===e&&(Pc&n)===n&&(4===Oc||3===Oc&&(130023424&Pc)===Pc&&500>Ye()-Uc?pl(e,0):Fc|=n),rl(e,t)}function Cl(e,t){0===t&&(1&e.mode?(t=dt,!(130023424&(dt<<=1))&&(dt=4194304)):t=1);var n=el();null!==(e=Ds(e,t))&&(bt(e,t,n),rl(e,n))}function Tl(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),Cl(e,n)}function jl(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(s(314))}null!==r&&r.delete(t),Cl(e,n)}function Al(e,t){return Ve(e,t)}function Rl(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Pl(e,t,n,r){return new Rl(e,t,n,r)}function Nl(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Ll(e,t){var n=e.alternate;return null===n?((n=Pl(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ol(e,t,n,r,o,a){var i=2;if(r=e,"function"==typeof e)Nl(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case _:return Dl(n.children,o,a,t);case S:i=8,o|=8;break;case E:return(e=Pl(12,n,t,2|o)).elementType=E,e.lanes=a,e;case A:return(e=Pl(13,n,t,o)).elementType=A,e.lanes=a,e;case R:return(e=Pl(19,n,t,o)).elementType=R,e.lanes=a,e;case L:return Il(n,o,a,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case C:i=10;break e;case T:i=9;break e;case j:i=11;break e;case P:i=14;break e;case N:i=16,r=null;break e}throw Error(s(130,null==e?e:typeof e,""))}return(t=Pl(i,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Dl(e,t,n,r){return(e=Pl(7,e,r,t)).lanes=n,e}function Il(e,t,n,r){return(e=Pl(22,e,r,t)).elementType=L,e.lanes=n,e.stateNode={isHidden:!1},e}function Ml(e,t,n){return(e=Pl(6,e,null,t)).lanes=n,e}function Fl(e,t,n){return(t=Pl(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function zl(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ht(0),this.expirationTimes=ht(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ht(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function Bl(e,t,n,r,o,s,a,i,c){return e=new zl(e,t,n,i,c),1===t?(t=1,!0===s&&(t|=8)):t=0,s=Pl(3,null,null,t),e.current=s,s.stateNode=e,s.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Ms(s),e}function Ul(e){if(!e)return jo;e:{if($e(e=e._reactInternals)!==e||1!==e.tag)throw Error(s(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(Lo(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(s(171))}if(1===e.tag){var n=e.type;if(Lo(n))return Io(e,n,t)}return t}function $l(e,t,n,r,o,s,a,i,c){return(e=Bl(n,r,!0,e,0,s,0,i,c)).context=Ul(null),n=e.current,(s=zs(r=el(),o=tl(n))).callback=null!=t?t:null,Bs(n,s,o),e.current.lanes=o,bt(e,o,r),rl(e,r),e}function ql(e,t,n,r){var o=t.current,s=el(),a=tl(o);return n=Ul(n),null===t.context?t.context=n:t.pendingContext=n,(t=zs(s,a)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),null!==(e=Bs(o,t,a))&&(nl(e,o,a,s),Us(e,o,a)),a}function Xl(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Hl(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Gl(e,t){Hl(e,t),(e=e.alternate)&&Hl(e,t)}_c=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Ro.current)yi=!0;else{if(!(e.lanes&n||128&t.flags))return yi=!1,function(e,t,n){switch(t.tag){case 3:Ai(t),gs();break;case 5:Zs(t);break;case 1:Lo(t.type)&&Mo(t);break;case 4:Qs(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;To(_s,r._currentValue),r._currentValue=o;break;case 13:if(null!==(r=t.memoizedState))return null!==r.dehydrated?(To(ea,1&ea.current),t.flags|=128,null):n&t.child.childLanes?Mi(e,t,n):(To(ea,1&ea.current),null!==(e=Xi(e,t,n))?e.sibling:null);To(ea,1&ea.current);break;case 19:if(r=!!(n&t.childLanes),128&e.flags){if(r)return $i(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),To(ea,ea.current),r)break;return null;case 22:case 23:return t.lanes=0,Si(e,t,n)}return Xi(e,t,n)}(e,t,n);yi=!!(131072&e.flags)}else yi=!1,ss&&1048576&t.flags&&es(t,Vo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;qi(e,t),e=t.pendingProps;var o=No(t,Ao.current);Rs(t,n),o=ha(null,t,r,e,o,n);var a=ba();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,Lo(r)?(a=!0,Mo(t)):a=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Ms(t),o.updater=oi,t.stateNode=o,o._reactInternals=t,ci(t,r,e,n),t=ji(null,t,r,!0,a,n)):(t.tag=0,ss&&a&&ts(t),xi(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(qi(e,t),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Nl(e)?1:0;if(null!=e){if((e=e.$$typeof)===j)return 11;if(e===P)return 14}return 2}(r),e=ni(r,e),o){case 0:t=Ci(null,t,r,e,n);break e;case 1:t=Ti(null,t,r,e,n);break e;case 11:t=wi(null,t,r,e,n);break e;case 14:t=ki(null,t,r,ni(r.type,e),n);break e}throw Error(s(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,Ci(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 1:return r=t.type,o=t.pendingProps,Ti(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 3:e:{if(Ai(t),null===e)throw Error(s(387));r=t.pendingProps,o=(a=t.memoizedState).element,Fs(e,t),qs(t,r,null,n);var i=t.memoizedState;if(r=i.element,a.isDehydrated){if(a={element:r,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=a,t.memoizedState=a,256&t.flags){t=Ri(e,t,r,n,o=li(Error(s(423)),t));break e}if(r!==o){t=Ri(e,t,r,n,o=li(Error(s(424)),t));break e}for(os=lo(t.stateNode.containerInfo.firstChild),rs=t,ss=!0,as=null,n=ks(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(gs(),r===o){t=Xi(e,t,n);break e}xi(e,t,r,n)}t=t.child}return t;case 5:return Zs(t),null===e&&ds(t),r=t.type,o=t.pendingProps,a=null!==e?e.memoizedProps:null,i=o.children,no(r,o)?i=null:null!==a&&no(r,a)&&(t.flags|=32),Ei(e,t),xi(e,t,i,n),t.child;case 6:return null===e&&ds(t),null;case 13:return Mi(e,t,n);case 4:return Qs(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=ws(t,null,r,n):xi(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,wi(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 7:return xi(e,t,t.pendingProps,n),t.child;case 8:case 12:return xi(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,a=t.memoizedProps,i=o.value,To(_s,r._currentValue),r._currentValue=i,null!==a)if(ir(a.value,i)){if(a.children===o.children&&!Ro.current){t=Xi(e,t,n);break e}}else for(null!==(a=t.child)&&(a.return=t);null!==a;){var c=a.dependencies;if(null!==c){i=a.child;for(var l=c.firstContext;null!==l;){if(l.context===r){if(1===a.tag){(l=zs(-1,n&-n)).tag=2;var d=a.updateQueue;if(null!==d){var u=(d=d.shared).pending;null===u?l.next=l:(l.next=u.next,u.next=l),d.pending=l}}a.lanes|=n,null!==(l=a.alternate)&&(l.lanes|=n),As(a.return,n,t),c.lanes|=n;break}l=l.next}}else if(10===a.tag)i=a.type===t.type?null:a.child;else if(18===a.tag){if(null===(i=a.return))throw Error(s(341));i.lanes|=n,null!==(c=i.alternate)&&(c.lanes|=n),As(i,n,t),i=a.sibling}else i=a.child;if(null!==i)i.return=a;else for(i=a;null!==i;){if(i===t){i=null;break}if(null!==(a=i.sibling)){a.return=i.return,i=a;break}i=i.return}a=i}xi(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,Rs(t,n),r=r(o=Ps(o)),t.flags|=1,xi(e,t,r,n),t.child;case 14:return o=ni(r=t.type,t.pendingProps),ki(e,t,r,o=ni(r.type,o),n);case 15:return _i(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:ni(r,o),qi(e,t),t.tag=1,Lo(r)?(e=!0,Mo(t)):e=!1,Rs(t,n),ai(t,r,o),ci(t,r,o,n),ji(null,t,r,!0,e,n);case 19:return $i(e,t,n);case 22:return Si(e,t,n)}throw Error(s(156,t.tag))};var Vl="function"==typeof reportError?reportError:function(e){console.error(e)};function Wl(e){this._internalRoot=e}function Kl(e){this._internalRoot=e}function Ql(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Yl(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Zl(){}function Jl(e,t,n,r,o){var s=n._reactRootContainer;if(s){var a=s;if("function"==typeof o){var i=o;o=function(){var e=Xl(a);i.call(e)}}ql(t,a,e,o)}else a=function(e,t,n,r,o){if(o){if("function"==typeof r){var s=r;r=function(){var e=Xl(a);s.call(e)}}var a=$l(t,r,e,0,null,!1,0,"",Zl);return e._reactRootContainer=a,e[mo]=a.current,$r(8===e.nodeType?e.parentNode:e),dl(),a}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof r){var i=r;r=function(){var e=Xl(c);i.call(e)}}var c=Bl(e,0,!1,null,0,!1,0,"",Zl);return e._reactRootContainer=c,e[mo]=c.current,$r(8===e.nodeType?e.parentNode:e),dl((function(){ql(t,c,n,r)})),c}(n,t,e,o,r);return Xl(a)}Kl.prototype.render=Wl.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(s(409));ql(e,t,null,null)},Kl.prototype.unmount=Wl.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;dl((function(){ql(null,e,null,null)})),t[mo]=null}},Kl.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Lt.length&&0!==t&&t<Lt[n].priority;n++);Lt.splice(n,0,e),0===n&&Mt(e)}},wt=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=ut(t.pendingLanes);0!==n&&(vt(t,1|n),rl(t,Ye()),!(6&jc)&&($c=Ye()+500,qo()))}break;case 13:dl((function(){var t=Ds(e,1);if(null!==t){var n=el();nl(t,e,1,n)}})),Gl(e,1)}},kt=function(e){if(13===e.tag){var t=Ds(e,134217728);if(null!==t)nl(t,e,134217728,el());Gl(e,134217728)}},_t=function(e){if(13===e.tag){var t=tl(e),n=Ds(e,t);if(null!==n)nl(n,e,t,el());Gl(e,t)}},St=function(){return yt},Et=function(e,t){var n=yt;try{return yt=e,t()}finally{yt=n}},ke=function(e,t,n){switch(t){case"input":if(Z(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ko(r);if(!o)throw Error(s(90));V(r),Z(r,o)}}}break;case"textarea":se(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},je=ll,Ae=dl;var ed={usingClientEntryPoint:!1,Events:[xo,wo,ko,Ce,Te,ll]},td={findFiberByHostInstance:yo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},nd={bundleType:td.bundleType,version:td.version,rendererPackageName:td.rendererPackageName,rendererConfig:td.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:x.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=He(e))?null:e.stateNode},findFiberByHostInstance:td.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var rd=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!rd.isDisabled&&rd.supportsFiber)try{ot=rd.inject(nd),st=rd}catch(de){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=ed,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Ql(t))throw Error(s(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Ql(e))throw Error(s(299));var n=!1,r="",o=Vl;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=Bl(e,1,!1,null,0,n,0,r,o),e[mo]=t.current,$r(8===e.nodeType?e.parentNode:e),new Wl(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(s(188));throw e=Object.keys(e).join(","),Error(s(268,e))}return e=null===(e=He(t))?null:e.stateNode},t.flushSync=function(e){return dl(e)},t.hydrate=function(e,t,n){if(!Yl(t))throw Error(s(200));return Jl(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Ql(e))throw Error(s(405));var r=null!=n&&n.hydratedSources||null,o=!1,a="",i=Vl;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(a=n.identifierPrefix),void 0!==n.onRecoverableError&&(i=n.onRecoverableError)),t=$l(t,null,e,1,null!=n?n:null,o,0,a,i),e[mo]=t.current,$r(e),r)for(e=0;e<r.length;e++)o=(o=(n=r[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Kl(t)},t.render=function(e,t,n){if(!Yl(t))throw Error(s(200));return Jl(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Yl(e))throw Error(s(40));return!!e._reactRootContainer&&(dl((function(){Jl(null,null,e,!1,(function(){e._reactRootContainer=null,e[mo]=null}))})),!0)},t.unstable_batchedUpdates=ll,t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Yl(n))throw Error(s(200));if(null==e||void 0===e._reactInternals)throw Error(s(38));return Jl(e,t,n,!1,r)},t.version="18.3.1-next-f1338f8080-20240426"},5338:(e,t,n)=>{"use strict";var r=n(40961);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function s(e,a){if(e===a)return!0;if(e&&a&&"object"==typeof e&&"object"==typeof a){if(e.constructor!==a.constructor)return!1;var i,c,l,d;if(Array.isArray(e)){if((i=e.length)!=a.length)return!1;for(c=i;0!=c--;)if(!s(e[c],a[c]))return!1;return!0}if(n&&e instanceof Map&&a instanceof Map){if(e.size!==a.size)return!1;for(d=e.entries();!(c=d.next()).done;)if(!a.has(c.value[0]))return!1;for(d=e.entries();!(c=d.next()).done;)if(!s(c.value[1],a.get(c.value[0])))return!1;return!0}if(r&&e instanceof Set&&a instanceof Set){if(e.size!==a.size)return!1;for(d=e.entries();!(c=d.next()).done;)if(!a.has(c.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(a)){if((i=e.length)!=a.length)return!1;for(c=i;0!=c--;)if(e[c]!==a[c])return!1;return!0}if(e.constructor===RegExp)return e.source===a.source&&e.flags===a.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof a.valueOf)return e.valueOf()===a.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof a.toString)return e.toString()===a.toString();if((i=(l=Object.keys(e)).length)!==Object.keys(a).length)return!1;for(c=i;0!=c--;)if(!Object.prototype.hasOwnProperty.call(a,l[c]))return!1;if(t&&e instanceof Element)return!1;for(c=i;0!=c--;)if(("_owner"!==l[c]&&"__v"!==l[c]&&"__o"!==l[c]||!e.$$typeof)&&!s(e[l[c]],a[l[c]]))return!1;return!0}return e!=e&&a!=a}e.exports=function(e,t){try{return s(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>H});var r=n(96540),o=n(5556),s=n.n(o),a=n(30115),i=n.n(a),c=n(20311),l=n.n(c),d=n(2833),u=n.n(d);function p(){return p=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},p.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,g(e,t)}function g(e,t){return g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},g(e,t)}function m(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)t.indexOf(n=s[r])>=0||(o[n]=e[n]);return o}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},x=Object.keys(h).map((function(e){return h[e]})),w={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},k=Object.keys(w).reduce((function(e,t){return e[w[t]]=t,e}),{}),_=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},S=function(e){var t=_(e,h.TITLE),n=_(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=_(e,"defaultTitle");return t||r||void 0},E=function(e){return _(e,"onChangeClientState")||function(){}},C=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return p({},e,t)}),{})},T=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var s=r[o].toLowerCase();if(-1!==e.indexOf(s)&&n[s])return t.concat(n)}return t}),[])},j=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,s=Object.keys(e),a=0;a<s.length;a+=1){var i=s[a],c=i.toLowerCase();-1===t.indexOf(c)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===c&&"stylesheet"===e[c].toLowerCase()||(n=c),-1===t.indexOf(i)||"innerHTML"!==i&&"cssText"!==i&&"itemprop"!==i||(n=i)}if(!n||!e[n])return!1;var l=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][l]&&(o[n][l]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var s=Object.keys(o),a=0;a<s.length;a+=1){var i=s[a],c=p({},r[i],o[i]);r[i]=c}return e}),[]).reverse()},A=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},R=function(e){return Array.isArray(e)?e.join(""):e},P=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},N=function(e,t){var n;return p({},e,((n={})[t]=void 0,n))},L=[h.NOSCRIPT,h.SCRIPT,h.STYLE],O=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},D=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},I=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[w[n]||n]=e[n],t}),t)},M=function(e,t){return t.map((function(t,n){var o,s=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=w[e]||e;"innerHTML"===n||"cssText"===n?s.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:s[n]=t[e]})),r.createElement(e,s)}))},F=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,s=I(n,o),[r.createElement(h.TITLE,s,e)];var e,n,o,s},toString:function(){return function(e,t,n,r){var o=D(n),s=R(t);return o?"<"+e+' data-rh="true" '+o+">"+O(s,r)+"</"+e+">":"<"+e+' data-rh="true">'+O(s,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return I(t)},toString:function(){return D(t)}};default:return{toComponent:function(){return M(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+O(r[t],n)+'"';return e?e+" "+o:o}),""),s=r.innerHTML||r.cssText||"",a=-1===L.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(a?"/>":">"+s+"</"+e+">")}),"")}(e,t,n)}}}},z=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,s=e.noscriptTags,a=e.styleTags,i=e.title,c=void 0===i?"":i,l=e.titleAttributes,d=e.linkTags,u=e.metaTags,p=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var g=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=P(e.metaTags,y),s=P(t,b),a=P(n,v);return{priorityMethods:{toComponent:function(){return[].concat(M(h.META,o.priority),M(h.LINK,s.priority),M(h.SCRIPT,a.priority))},toString:function(){return F(h.META,o.priority,r)+" "+F(h.LINK,s.priority,r)+" "+F(h.SCRIPT,a.priority,r)}},metaTags:o.default,linkTags:s.default,scriptTags:a.default}}(e);f=g.priorityMethods,d=g.linkTags,u=g.metaTags,p=g.scriptTags}return{priority:f,base:F(h.BASE,t,r),bodyAttributes:F("bodyAttributes",n,r),htmlAttributes:F("htmlAttributes",o,r),link:F(h.LINK,d,r),meta:F(h.META,u,r),noscript:F(h.NOSCRIPT,s,r),script:F(h.SCRIPT,p,r),style:F(h.STYLE,a,r),title:F(h.TITLE,{title:c,titleAttributes:l},r)}},B=[],U=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?B:n.instances},add:function(e){(n.canUseDOM?B:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?B:n.instances).indexOf(e);(n.canUseDOM?B:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=z({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},$=r.createContext({}),q=s().shape({setHelmet:s().func,helmetInstances:s().shape({get:s().func,add:s().func,remove:s().func})}),X="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new U(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement($.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=X,H.propTypes={context:s().shape({helmet:s().shape()}),children:s().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var G=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),o=r.querySelectorAll(e+"[data-rh]"),s=[].slice.call(o),a=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),s.some((function(e,t){return n=t,r.isEqualNode(e)}))?s.splice(n,1):a.push(r)})),s.forEach((function(e){return e.parentNode.removeChild(e)})),a.forEach((function(e){return r.appendChild(e)})),{oldTags:s,newTags:a}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],s=[].concat(o),a=Object.keys(t),i=0;i<a.length;i+=1){var c=a[i],l=t[c]||"";n.getAttribute(c)!==l&&n.setAttribute(c,l),-1===o.indexOf(c)&&o.push(c);var d=s.indexOf(c);-1!==d&&s.splice(d,1)}for(var u=s.length-1;u>=0;u-=1)n.removeAttribute(s[u]);o.length===s.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==a.join(",")&&n.setAttribute("data-rh",a.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,s=e.metaTags,a=e.noscriptTags,i=e.onChangeClientState,c=e.scriptTags,l=e.styleTags,d=e.title,u=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=R(e)),V(h.TITLE,t)}(d,u);var p={baseTag:G(h.BASE,n),linkTags:G(h.LINK,o),metaTags:G(h.META,s),noscriptTags:G(h.NOSCRIPT,a),scriptTags:G(h.SCRIPT,c),styleTags:G(h.STYLE,l)},f={},g={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(g[e]=p[e].oldTags)})),t&&t(),i(e,f,g)},K=null,Q=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!u()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,s=(e=n.helmetInstances.get().map((function(e){var t=p({},e.props);return delete t.context,t})),{baseTag:T(["href"],e),bodyAttributes:C("bodyAttributes",e),defer:_(e,"defer"),encode:_(e,"encodeSpecialCharacters"),htmlAttributes:C("htmlAttributes",e),linkTags:j(h.LINK,["rel","href"],e),metaTags:j(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:j(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:j(h.SCRIPT,["src","innerHTML"],e),styleTags:j(h.STYLE,["cssText"],e),title:S(e),titleAttributes:C("titleAttributes",e),prioritizeSeoTags:A(e,"prioritizeSeoTags")});H.canUseDOM?(t=s,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){W(t,(function(){K=null}))})):(W(t),K=null)):z&&(o=z(s)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Q.propTypes={context:q.isRequired},Q.displayName="HelmetDispatcher";var Y=["children"],Z=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!i()(N(this.props,"helmetData"),N(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return p({},r,((t={})[n.type]=[].concat(r[n.type]||[],[p({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,s=e.newChildProps,a=e.nestedChildren;switch(r.type){case h.TITLE:return p({},o,((t={})[r.type]=a,t.titleAttributes=p({},s),t));case h.BODY:return p({},o,{bodyAttributes:p({},s)});case h.HTML:return p({},o,{htmlAttributes:p({},s)});default:return p({},o,((n={})[r.type]=p({},s),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=p({},t);return Object.keys(e).forEach((function(t){var r;n=p({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return l()(x.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+x.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),l()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,s=r.children,a=m(r,Y),i=Object.keys(a).reduce((function(e,t){return e[k[t]||t]=a[t],e}),{}),c=e.type;switch("symbol"==typeof c?c=c.toString():n.warnOnInvalidChildren(e,s),c){case h.FRAGMENT:t=n.mapChildrenToProps(s,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:i,nestedChildren:s});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:s})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,Z),o=p({},n),s=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!s||s instanceof U||(s=new U(s.context,s.instances)),s?r.createElement(Q,p({},o,{context:s.value,helmetData:void 0})):r.createElement($.Consumer,null,(function(e){return r.createElement(Q,p({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:s().object,bodyAttributes:s().object,children:s().oneOfType([s().arrayOf(s().node),s().node]),defaultTitle:s().string,defer:s().bool,encodeSpecialCharacters:s().bool,htmlAttributes:s().object,link:s().arrayOf(s().object),meta:s().arrayOf(s().object),noscript:s().arrayOf(s().object),onChangeClientState:s().func,script:s().arrayOf(s().object),style:s().arrayOf(s().object),title:s().string,titleAttributes:s().object,titleTemplate:s().string,prioritizeSeoTags:s().bool,helmetData:s().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,s=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,c=n?Symbol.for("react.provider"):60109,l=n?Symbol.for("react.context"):60110,d=n?Symbol.for("react.async_mode"):60111,u=n?Symbol.for("react.concurrent_mode"):60111,p=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,g=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,x=n?Symbol.for("react.scope"):60119;function w(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case d:case u:case s:case i:case a:case f:return e;default:switch(e=e&&e.$$typeof){case l:case p:case h:case m:case c:return e;default:return t}}case o:return t}}}function k(e){return w(e)===u}t.AsyncMode=d,t.ConcurrentMode=u,t.ContextConsumer=l,t.ContextProvider=c,t.Element=r,t.ForwardRef=p,t.Fragment=s,t.Lazy=h,t.Memo=m,t.Portal=o,t.Profiler=i,t.StrictMode=a,t.Suspense=f,t.isAsyncMode=function(e){return k(e)||w(e)===d},t.isConcurrentMode=k,t.isContextConsumer=function(e){return w(e)===l},t.isContextProvider=function(e){return w(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return w(e)===p},t.isFragment=function(e){return w(e)===s},t.isLazy=function(e){return w(e)===h},t.isMemo=function(e){return w(e)===m},t.isPortal=function(e){return w(e)===o},t.isProfiler=function(e){return w(e)===i},t.isStrictMode=function(e){return w(e)===a},t.isSuspense=function(e){return w(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===s||e===u||e===i||e===a||e===f||e===g||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===m||e.$$typeof===c||e.$$typeof===l||e.$$typeof===p||e.$$typeof===v||e.$$typeof===y||e.$$typeof===x||e.$$typeof===b)},t.typeOf=w},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},53259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var i=n(96540),c=[],l=[];var d=i.createContext(null);function u(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function p(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=u(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return i.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function g(e,t){var u,p;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var g=a({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),m=null;function h(){return m||(m=e(g.loader)),m.promise}return c.push(h),"function"==typeof g.webpack&&l.push((function(){if((0,g.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),p=u=function(t){function n(n){var r;return s(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),m=e(g.loader),r._loadModule()})),h(),r.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},r}r(n,t),n.preload=function(){return h()};var a=n.prototype;return a.UNSAFE_componentWillMount=function(){this._loadModule()},a.componentDidMount=function(){this._mounted=!0},a._loadModule=function(){var e=this;if(this.context&&Array.isArray(g.modules)&&g.modules.forEach((function(t){e.context.report(t)})),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof g.delay&&(0===g.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),g.delay)),"number"==typeof g.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),g.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},a.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},a._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},a.render=function(){return this.state.loading||this.state.error?i.createElement(g.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?g.render(this.state.loaded,this.props):null},n}(i.Component),s(u,"contextType",d),p}function m(e){return g(u,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return g(p,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return i.createElement(d.Provider,{value:{report:this.props.report}},i.Children.only(this.props.children))},t}(i.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}m.Capture=h,m.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},m.preloadReady=function(){return new Promise((function(e,t){b(l).then(e,e)}))},e.exports=m},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>a,v:()=>i});var r=n(56347),o=n(58168),s=n(96540);function a(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&a(e.routes,t,n)),o})),n}function i(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?s.createElement(r.dO,n,e.map((function(e,n){return s.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):s.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})}))):null}},54625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>u,Kd:()=>d,N_:()=>b,k2:()=>x});var r=n(56347),o=n(42892),s=n(96540),a=n(31513),i=n(58168),c=n(98587),l=n(11561),d=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return s.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(s.Component);var u=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.TM)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return s.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(s.Component);var p=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,a.yJ)(e,null,null,t):e},g=function(e){return e},m=s.forwardRef;void 0===m&&(m=g);var h=m((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,a=(0,c.A)(e,["innerRef","navigate","onClick"]),l=a.target,d=(0,i.A)({},a,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||l&&"_self"!==l||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return d.ref=g!==m&&t||n,s.createElement("a",d)}));var b=m((function(e,t){var n=e.component,o=void 0===n?h:n,d=e.replace,u=e.to,b=e.innerRef,v=(0,c.A)(e,["component","replace","to","innerRef"]);return s.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=e.history,r=f(p(u,e.location),e.location),c=r?n.createHref(r):"",h=(0,i.A)({},v,{href:c,navigate:function(){var t=p(u,e.location),r=(0,a.AO)(e.location)===(0,a.AO)(f(t));(d||r?n.replace:n.push)(t)}});return g!==m?h.ref=t||b:h.innerRef=b,s.createElement(o,h)}))})),v=function(e){return e},y=s.forwardRef;void 0===y&&(y=v);var x=y((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,a=e.activeClassName,d=void 0===a?"active":a,u=e.activeStyle,g=e.className,m=e.exact,h=e.isActive,x=e.location,w=e.sensitive,k=e.strict,_=e.style,S=e.to,E=e.innerRef,C=(0,c.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return s.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=x||e.location,a=f(p(S,n),n),c=a.pathname,T=c&&c.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),j=T?(0,r.B6)(n.pathname,{path:T,exact:m,sensitive:w,strict:k}):null,A=!!(h?h(j,n):j),R="function"==typeof g?g(A):g,P="function"==typeof _?_(A):_;A&&(R=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(R,d),P=(0,i.A)({},P,u));var N=(0,i.A)({"aria-current":A&&o||null,className:R,style:P,to:a},C);return v!==y?N.ref=t||E:N.innerRef=E,s.createElement(b,N)}))}))},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>_,Ix:()=>y,W6:()=>N,XZ:()=>v,dO:()=>R,qh:()=>S,zy:()=>L});var r=n(42892),o=n(96540),s=n(5556),a=n.n(s),i=n(31513),c=n(11561),l=n(58168),d=n(8505),u=n.n(d),p=(n(44363),n(98587)),f=(n(4146),1073741823),g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var m=o.createContext||function(e,t){var n,s,i="__create-react-context-"+function(){var e="__global_unique_id__";return g[e]=(g[e]||0)+1}()+"__",c=function(e){function n(){for(var t,n,r,o=arguments.length,s=new Array(o),a=0;a<o;a++)s[a]=arguments[a];return(t=e.call.apply(e,[this].concat(s))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((s=r)===(a=o)?0!==s||1/s==1/a:s!=s&&a!=a)?n=0:(n="function"==typeof t?t(r,o):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var s,a},o.render=function(){return this.props.children},n}(o.Component);c.childContextTypes=((n={})[i]=a().object.isRequired,n);var l=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){(0|e.observedBits)&n&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},o.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},o.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},o.getValue=function(){return this.context[i]?this.context[i].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return l.contextTypes=((s={})[i]=a().object,s),{Provider:c,Consumer:l}},h=function(e){var t=m();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var x={},w=1e4,k=0;function _(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,s=void 0!==o&&o,a=n.strict,i=void 0!==a&&a,c=n.sensitive,l=void 0!==c&&c;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=x[n]||(x[n]={});if(r[e])return r[e];var o=[],s={regexp:u()(e,o,t),keys:o};return k<w&&(r[e]=s,k++),s}(n,{end:s,strict:i,sensitive:l}),o=r.regexp,a=r.keys,c=o.exec(e);if(!c)return null;var d=c[0],p=c.slice(1),f=e===d;return s&&!f?null:{path:n,url:"/"===n&&""===d?"/":d,isExact:f,params:a.reduce((function(e,t,n){return e[t.name]=p[n],e}),{})}}),null)}var S=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(v.Consumer,null,(function(t){t||(0,c.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?_(n.pathname,e.props):t.match,s=(0,l.A)({},t,{location:n,match:r}),a=e.props,i=a.children,d=a.component,u=a.render;return Array.isArray(i)&&function(e){return 0===o.Children.count(e)}(i)&&(i=null),o.createElement(v.Provider,{value:s},s.match?i?"function"==typeof i?i(s):i:d?o.createElement(d,s):u?u(s):null:"function"==typeof i?i(s):null)}))},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function C(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,l.A)({},t,{pathname:t.pathname.substr(n.length)})}function T(e){return"string"==typeof e?e:(0,i.AO)(e)}function j(e){return function(){(0,c.A)(!1)}}function A(){}o.Component;var R=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(v.Consumer,null,(function(t){t||(0,c.A)(!1);var n,r,s=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?_(s.pathname,(0,l.A)({},e.props,{path:a})):t.match}})),r?o.cloneElement(n,{location:s,computedMatch:r}):null}))},t}(o.Component);var P=o.useContext;function N(){return P(b)}function L(){return P(v).location}},8505:(e,t,n)=>{var r=n(64634);e.exports=f,e.exports.parse=s,e.exports.compile=function(e,t){return i(s(e,t),t)},e.exports.tokensToFunction=i,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function s(e,t){for(var n,r=[],s=0,a=0,i="",d=t&&t.delimiter||"/";null!=(n=o.exec(e));){var u=n[0],p=n[1],f=n.index;if(i+=e.slice(a,f),a=f+u.length,p)i+=p[1];else{var g=e[a],m=n[2],h=n[3],b=n[4],v=n[5],y=n[6],x=n[7];i&&(r.push(i),i="");var w=null!=m&&null!=g&&g!==m,k="+"===y||"*"===y,_="?"===y||"*"===y,S=n[2]||d,E=b||v;r.push({name:h||s++,prefix:m||"",delimiter:S,optional:_,repeat:k,partial:w,asterisk:!!x,pattern:E?l(E):x?".*":"[^"+c(S)+"]+?"})}}return a<e.length&&(i+=e.substr(a)),i&&r.push(i),r}function a(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function i(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",u(t)));return function(t,o){for(var s="",i=t||{},c=(o||{}).pretty?a:encodeURIComponent,l=0;l<e.length;l++){var d=e[l];if("string"!=typeof d){var u,p=i[d.name];if(null==p){if(d.optional){d.partial&&(s+=d.prefix);continue}throw new TypeError('Expected "'+d.name+'" to be defined')}if(r(p)){if(!d.repeat)throw new TypeError('Expected "'+d.name+'" to not repeat, but received `'+JSON.stringify(p)+"`");if(0===p.length){if(d.optional)continue;throw new TypeError('Expected "'+d.name+'" to not be empty')}for(var f=0;f<p.length;f++){if(u=c(p[f]),!n[l].test(u))throw new TypeError('Expected all "'+d.name+'" to match "'+d.pattern+'", but received `'+JSON.stringify(u)+"`");s+=(0===f?d.prefix:d.delimiter)+u}}else{if(u=d.asterisk?encodeURI(p).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):c(p),!n[l].test(u))throw new TypeError('Expected "'+d.name+'" to match "'+d.pattern+'", but received "'+u+'"');s+=d.prefix+u}}else s+=d}return s}}function c(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function l(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function d(e,t){return e.keys=t,e}function u(e){return e&&e.sensitive?"":"i"}function p(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,s=!1!==n.end,a="",i=0;i<e.length;i++){var l=e[i];if("string"==typeof l)a+=c(l);else{var p=c(l.prefix),f="(?:"+l.pattern+")";t.push(l),l.repeat&&(f+="(?:"+p+f+")*"),a+=f=l.optional?l.partial?p+"("+f+")?":"(?:"+p+"("+f+"))?":p+"("+f+")"}}var g=c(n.delimiter||"/"),m=a.slice(-g.length)===g;return o||(a=(m?a.slice(0,-g.length):a)+"(?:"+g+"(?=$))?"),a+=s?"$":o&&m?"":"(?="+g+"|$)",d(new RegExp("^"+a,u(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return d(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(f(e[o],t,n).source);return d(new RegExp("(?:"+r.join("|")+")",u(n)),t)}(e,t,n):function(e,t,n){return p(s(e,n),t,n)}(e,t,n)}},21020:(e,t,n)=>{"use strict";var r=n(96540),o=Symbol.for("react.element"),s=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,i=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function l(e,t,n){var r,s={},l=null,d=null;for(r in void 0!==n&&(l=""+n),void 0!==t.key&&(l=""+t.key),void 0!==t.ref&&(d=t.ref),t)a.call(t,r)&&!c.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:o,type:e,key:l,ref:d,props:s,_owner:i.current}}t.Fragment=s,t.jsx=l,t.jsxs=l},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),c=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),u=Symbol.for("react.memo"),p=Symbol.for("react.lazy"),f=Symbol.iterator;var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m=Object.assign,h={};function b(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}function v(){}function y(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},v.prototype=b.prototype;var x=y.prototype=new v;x.constructor=y,m(x,b.prototype),x.isPureReactComponent=!0;var w=Array.isArray,k=Object.prototype.hasOwnProperty,_={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,r){var o,s={},a=null,i=null;if(null!=t)for(o in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(a=""+t.key),t)k.call(t,o)&&!S.hasOwnProperty(o)&&(s[o]=t[o]);var c=arguments.length-2;if(1===c)s.children=r;else if(1<c){for(var l=Array(c),d=0;d<c;d++)l[d]=arguments[d+2];s.children=l}if(e&&e.defaultProps)for(o in c=e.defaultProps)void 0===s[o]&&(s[o]=c[o]);return{$$typeof:n,type:e,key:a,ref:i,props:s,_owner:_.current}}function C(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var T=/\/+/g;function j(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function A(e,t,o,s,a){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var c=!1;if(null===e)c=!0;else switch(i){case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case r:c=!0}}if(c)return a=a(c=e),e=""===s?"."+j(c,0):s,w(a)?(o="",null!=e&&(o=e.replace(T,"$&/")+"/"),A(a,t,o,"",(function(e){return e}))):null!=a&&(C(a)&&(a=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(a,o+(!a.key||c&&c.key===a.key?"":(""+a.key).replace(T,"$&/")+"/")+e)),t.push(a)),1;if(c=0,s=""===s?".":s+":",w(e))for(var l=0;l<e.length;l++){var d=s+j(i=e[l],l);c+=A(i,t,o,d,a)}else if(d=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof d)for(e=d.call(e),l=0;!(i=e.next()).done;)c+=A(i=i.value,t,o,d=s+j(i,l++),a);else if("object"===i)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return c}function R(e,t,n){if(null==e)return e;var r=[],o=0;return A(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function P(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var N={current:null},L={transition:null},O={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:L,ReactCurrentOwner:_};function D(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:R,forEach:function(e,t,n){R(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return R(e,(function(){t++})),t},toArray:function(e){return R(e,(function(e){return e}))||[]},only:function(e){if(!C(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=o,t.Profiler=a,t.PureComponent=y,t.StrictMode=s,t.Suspense=d,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=O,t.act=D,t.cloneElement=function(e,t,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=m({},e.props),s=e.key,a=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(a=t.ref,i=_.current),void 0!==t.key&&(s=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(l in t)k.call(t,l)&&!S.hasOwnProperty(l)&&(o[l]=void 0===t[l]&&void 0!==c?c[l]:t[l])}var l=arguments.length-2;if(1===l)o.children=r;else if(1<l){c=Array(l);for(var d=0;d<l;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:n,type:e.type,key:s,ref:a,props:o,_owner:i}},t.createContext=function(e){return(e={$$typeof:c,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:l,render:e}},t.isValidElement=C,t.lazy=function(e){return{$$typeof:p,_payload:{_status:-1,_result:e},_init:P}},t.memo=function(e,t){return{$$typeof:u,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=L.transition;L.transition={};try{e()}finally{L.transition=t}},t.unstable_act=D,t.useCallback=function(e,t){return N.current.useCallback(e,t)},t.useContext=function(e){return N.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return N.current.useDeferredValue(e)},t.useEffect=function(e,t){return N.current.useEffect(e,t)},t.useId=function(){return N.current.useId()},t.useImperativeHandle=function(e,t,n){return N.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return N.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return N.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return N.current.useMemo(e,t)},t.useReducer=function(e,t,n){return N.current.useReducer(e,t,n)},t.useRef=function(e){return N.current.useRef(e)},t.useState=function(e){return N.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return N.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return N.current.useTransition()},t.version="18.3.1"},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,o=e[r];if(!(0<s(o,t)))break e;e[r]=t,e[n]=o,n=r}}function r(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length,a=o>>>1;r<a;){var i=2*(r+1)-1,c=e[i],l=i+1,d=e[l];if(0>s(c,n))l<o&&0>s(d,c)?(e[r]=d,e[l]=n,r=l):(e[r]=c,e[i]=n,r=i);else{if(!(l<o&&0>s(d,n)))break e;e[r]=d,e[l]=n,r=l}}}return t}function s(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var a=performance;t.unstable_now=function(){return a.now()}}else{var i=Date,c=i.now();t.unstable_now=function(){return i.now()-c}}var l=[],d=[],u=1,p=null,f=3,g=!1,m=!1,h=!1,b="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function x(e){for(var t=r(d);null!==t;){if(null===t.callback)o(d);else{if(!(t.startTime<=e))break;o(d),t.sortIndex=t.expirationTime,n(l,t)}t=r(d)}}function w(e){if(h=!1,x(e),!m)if(null!==r(l))m=!0,L(k);else{var t=r(d);null!==t&&O(w,t.startTime-e)}}function k(e,n){m=!1,h&&(h=!1,v(C),C=-1),g=!0;var s=f;try{for(x(n),p=r(l);null!==p&&(!(p.expirationTime>n)||e&&!A());){var a=p.callback;if("function"==typeof a){p.callback=null,f=p.priorityLevel;var i=a(p.expirationTime<=n);n=t.unstable_now(),"function"==typeof i?p.callback=i:p===r(l)&&o(l),x(n)}else o(l);p=r(l)}if(null!==p)var c=!0;else{var u=r(d);null!==u&&O(w,u.startTime-n),c=!1}return c}finally{p=null,f=s,g=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var _,S=!1,E=null,C=-1,T=5,j=-1;function A(){return!(t.unstable_now()-j<T)}function R(){if(null!==E){var e=t.unstable_now();j=e;var n=!0;try{n=E(!0,e)}finally{n?_():(S=!1,E=null)}}else S=!1}if("function"==typeof y)_=function(){y(R)};else if("undefined"!=typeof MessageChannel){var P=new MessageChannel,N=P.port2;P.port1.onmessage=R,_=function(){N.postMessage(null)}}else _=function(){b(R,0)};function L(e){E=e,S||(S=!0,_())}function O(e,n){C=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){m||g||(m=!0,L(k))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):T=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return r(l)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,o,s){var a=t.unstable_now();switch("object"==typeof s&&null!==s?s="number"==typeof(s=s.delay)&&0<s?a+s:a:s=a,e){case 1:var i=-1;break;case 2:i=250;break;case 5:i=1073741823;break;case 4:i=1e4;break;default:i=5e3}return e={id:u++,callback:o,priorityLevel:e,startTime:s,expirationTime:i=s+i,sortIndex:-1},s>a?(e.sortIndex=s,n(d,e),null===r(l)&&e===r(d)&&(h?(v(C),C=-1):h=!0,O(w,s-a))):(e.sortIndex=i,n(l,e),m||g||(m=!0,L(k))),e},t.unstable_shouldYield=A,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},2833:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var s=Object.keys(e),a=Object.keys(t);if(s.length!==a.length)return!1;for(var i=Object.prototype.hasOwnProperty.bind(t),c=0;c<s.length;c++){var l=s[c];if(!i(l))return!1;var d=e[l],u=t[l];if(!1===(o=n?n.call(r,d,u,l):void 0)||void 0===o&&d!==u)return!1}return!0}},4784:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r={title:"Casper Docs - Redux",tagline:"Casper Documentation",favicon:"icon/favicon.ico",url:"https://casper-devrel.github.io",baseUrl:"/",organizationName:"casper-devrel",projectName:"docs-redux",deploymentBranch:"gh-pages",trailingSlash:!0,onBrokenLinks:"warn",onBrokenMarkdownLinks:"warn",onDuplicateRoutes:"throw",markdown:{format:"detect",mermaid:!1,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}},presets:[["classic",{theme:{customCss:"./src/css/custom.css"},docs:{path:"./docs",sidebarPath:"./config/sidebar.config.js",routeBasePath:"/",exclude:["./contract-dsl/archived","./economics/archived","./theory"],showLastUpdateTime:!0,showLastUpdateAuthor:!0},blog:{path:"./blog",routeBasePath:"blog",blogTitle:"Casper Developer Relations Blog",blogDescription:"A blog about all things to do with developing on the Casper Blockchain",postsPerPage:"ALL",blogSidebarTitle:"All posts",blogSidebarCount:"ALL"}}]],themeConfig:{colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!0},algolia:{appId:"A1AAQ71KTN",apiKey:"b098dcb7941fa8314891fa88ea7b5e31",indexName:"casper-devrelio",contextualSearch:!0,externalUrlRegex:"external\\.com|domain\\.com",replaceSearchResultPathname:{from:"/docs/",to:"/"},searchParameters:{},searchPagePath:"search",insights:!1},navbar:{title:"",logo:{alt:"Casper Logo",src:"/icon/Casper_Wordmark_Red_RGB.png",srcDark:"/icon/Casper_Wordmark_Red_RGB.png"},items:[{type:"docSidebar",sidebarId:"concepts",label:"Concepts",position:"left"},{type:"docSidebar",sidebarId:"developers",label:"Developers",position:"left"},{type:"docSidebar",sidebarId:"operators",label:"Operators",position:"left"},{type:"docSidebar",sidebarId:"users",label:"Users",position:"left"},{type:"docSidebar",sidebarId:"resources",label:"Resources",position:"left"},{type:"docSidebar",sidebarId:"tutorials",label:"Tutorials",position:"left"},{to:"https://github.com/casper-devrel/docs-redux/issues/new?assignees=&labels=docs-v2-feedback&projects=&template=feedback.yml&title=Docs+Feedback",label:"Feedback",position:"right"},{to:"blog/tags/condor",label:"Condor",position:"right"},{to:"blog",label:"Blog",position:"right"},{type:"search",position:"right"},{type:"docsVersionDropdown",position:"right",dropdownActiveClassDisabled:!0,dropdownItemsBefore:[],dropdownItemsAfter:[]},{href:"https://support.casperlabs.io/",label:"Support",position:"right"},{href:"https://discord.com/invite/casperblockchain",label:"Chat",position:"right"},{href:"https://github.com/casper-devrel/docs-redux",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{logo:{alt:"Casper Logo",src:"/icon/Casper_Wordmark_Horizontal_Red_RGB.png",srcDark:"/icon/Casper_Wordmark_Horizontal_White_RGB.png",href:"https://casper.network/",width:120,height:30},copyright:"Copyright \xa9 2024 Casper Association. Built with Docusaurus.",links:[],style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},announcementBar:{id:"announcement",content:'This is an Alpha version of the Casper Docs Redux. \n Any suggestions please email to <a href="mailto:devrel@casper.network">devrel@casper.network</a>, or \n submit an issue on <a href="https://github.com/casper-devrel/docs-redux/issues/new?assignees=&labels=docs-v2-feedback&projects=&template=feedback.yml&title=Docs+Feedback">Github<a/>',backgroundColor:"#f9f9f9",textColor:"#000000",isCloseable:!0},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,i18n:{defaultLocale:"en",path:"i18n",locales:["en"],localeConfigs:{}},future:{experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},onBrokenAnchors:"warn",staticDirectories:["static"],customFields:{},plugins:[],themes:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},58168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},42892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>o})},98587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})},34164:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},71765:(e,t,n)=>{"use strict";n.d(t,{My:()=>T,f4:()=>ee});var r,o,s,a,i,c,l,d=n(96540),u=n(34164),p=Object.create,f=Object.defineProperty,g=Object.defineProperties,m=Object.getOwnPropertyDescriptor,h=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,v=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,x=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable,k=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))x.call(t,n)&&k(e,n,t[n]);if(v)for(var n of v(t))w.call(t,n)&&k(e,n,t[n]);return e},S=(e,t)=>g(e,h(t)),E=(e,t)=>{var n={};for(var r in e)x.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&v)for(var r of v(e))t.indexOf(r)<0&&w.call(e,r)&&(n[r]=e[r]);return n},C=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,s;switch(n=n||{},r.util.type(t)){case"Object":if(s=r.util.objId(t),n[s])return n[s];for(var a in o={},n[s]=o,t)t.hasOwnProperty(a)&&(o[a]=e(t[a],n));return o;case"Array":return s=r.util.objId(t),n[s]?n[s]:(o=[],n[s]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var s=(o=o||r.languages)[e],a={};for(var i in s)if(s.hasOwnProperty(i)){if(i==t)for(var c in n)n.hasOwnProperty(c)&&(a[c]=n[c]);n.hasOwnProperty(i)||(a[i]=s[i])}var l=o[e];return o[e]=a,r.languages.DFS(r.languages,(function(t,n){n===l&&t!=e&&(this[t]=a)})),a},DFS:function e(t,n,o,s){s=s||{};var a=r.util.objId;for(var i in t)if(t.hasOwnProperty(i)){n.call(t,i,t[i],o||i);var c=t[i],l=r.util.type(c);"Object"!==l||s[a(c)]?"Array"!==l||s[a(c)]||(s[a(c)]=!0,e(c,n,i,s)):(s[a(c)]=!0,e(c,n,null,s))}}},plugins:{},highlight:function(e,t,n){var s={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",s),!s.grammar)throw new Error('The language "'+s.language+'" has no grammar.');return s.tokens=r.tokenize(s.code,s.grammar),r.hooks.run("after-tokenize",s),o.stringify(r.util.encode(s.tokens),s.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new i;return c(o,o.head,e),a(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,s=0;o=n[s++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var s=o[1].length;o.index+=s,o[0]=o[0].slice(s)}return o}function a(e,t,n,i,d,u){for(var p in n)if(n.hasOwnProperty(p)&&n[p]){var f=n[p];f=Array.isArray(f)?f:[f];for(var g=0;g<f.length;++g){if(u&&u.cause==p+","+g)return;var m=f[g],h=m.inside,b=!!m.lookbehind,v=!!m.greedy,y=m.alias;if(v&&!m.pattern.global){var x=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,x+"g")}for(var w=m.pattern||m,k=i.next,_=d;k!==t.tail&&!(u&&_>=u.reach);_+=k.value.length,k=k.next){var S=k.value;if(t.length>e.length)return;if(!(S instanceof o)){var E,C=1;if(v){if(!(E=s(w,_,e,b))||E.index>=e.length)break;var T=E.index,j=E.index+E[0].length,A=_;for(A+=k.value.length;T>=A;)A+=(k=k.next).value.length;if(_=A-=k.value.length,k.value instanceof o)continue;for(var R=k;R!==t.tail&&(A<j||"string"==typeof R.value);R=R.next)C++,A+=R.value.length;C--,S=e.slice(_,A),E.index-=_}else if(!(E=s(w,0,S,b)))continue;T=E.index;var P=E[0],N=S.slice(0,T),L=S.slice(T+P.length),O=_+S.length;u&&O>u.reach&&(u.reach=O);var D=k.prev;if(N&&(D=c(t,D,N),_+=N.length),l(t,D,C),k=c(t,D,new o(p,h?r.tokenize(P,h):P,y,P)),L&&c(t,k,L),C>1){var I={cause:p+","+g,reach:O};a(e,t,n,k.prev,_,I),u&&I.reach>u.reach&&(u.reach=I.reach)}}}}}}function i(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function l(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var s={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},a=t.alias;a&&(Array.isArray(a)?Array.prototype.push.apply(s.classes,a):s.classes.push(a)),r.hooks.run("wrap",s);var i="";for(var c in s.attributes)i+=" "+c+'="'+(s.attributes[c]||"").replace(/"/g,""")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'"'+i+">"+s.content+"</"+s.tag+">"},r}();t.exports=n,n.default=n}},function(){return o||(0,r[b(r)[0]])((o={exports:{}}).exports,o),o.exports}),T=((e,t,n)=>(n=null!=e?p(y(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of b(t))x.call(e,o)||o===n||f(e,o,{get:()=>t[o],enumerable:!(r=m(t,o))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(C());T.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},T.languages.markup.tag.inside["attr-value"].inside.entity=T.languages.markup.entity,T.languages.markup.doctype.inside["internal-subset"].inside=T.languages.markup,T.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(T.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:T.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:T.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},T.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(T.languages.markup.tag,"addAttribute",{value:function(e,t){T.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:T.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),T.languages.html=T.languages.markup,T.languages.mathml=T.languages.markup,T.languages.svg=T.languages.markup,T.languages.xml=T.languages.extend("markup",{}),T.languages.ssml=T.languages.xml,T.languages.atom=T.languages.xml,T.languages.rss=T.languages.xml,s=T,a={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},c="(?:[^\\\\-]|"+(i=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",c=RegExp(c+"-"+c),l={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},s.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:c,inside:{escape:i,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":a,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:i}},"special-escape":a,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":l}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:i,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":l}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},T.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},T.languages.javascript=T.languages.extend("clike",{"class-name":[T.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),T.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,T.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:T.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:T.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:T.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:T.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:T.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),T.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:T.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),T.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),T.languages.markup&&(T.languages.markup.tag.addInlined("script","javascript"),T.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),T.languages.js=T.languages.javascript,T.languages.actionscript=T.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),T.languages.actionscript["class-name"].alias="function",delete T.languages.actionscript.parameter,delete T.languages.actionscript["literal-property"],T.languages.markup&&T.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:T.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(T),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(s=e.languages[t]){var s,a=s[o];if((a=a||(s=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(a=s[o]={pattern:a}),Array.isArray(a))for(var i=0,c=a.length;i<c;i++)a[i]instanceof RegExp&&(a[i]={pattern:a[i]}),r(a[i]);else r(a)}}))}}),t.addSupport(["java","javascript","php"],t)}(T),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(T),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(T),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),s=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function a(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+s+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:a(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:a(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:a(s),lookbehind:!0,greedy:!0},number:{pattern:a(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(T),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),s=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,a=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+s+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+s+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+s+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o,s=t[n];"code"!==s.type?e(s.content):(o=s.content[1],s=s.content[3],o&&s&&"code-language"===o.type&&"code-block"===s.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),s.alias?"string"==typeof s.alias?s.alias=[s.alias,o]:s.alias.push(o):s.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var s=t.classes[r];if(s=/language-(.+)/.exec(s)){n=s[1];break}}var l,d=e.languages[n];d?t.content=e.highlight(t.content.replace(a,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),c(n)):i[t]||e})),d,n):n&&"none"!==n&&e.plugins.autoloader&&(l="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=l,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(l);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),i={amp:"&",lt:"<",gt:">",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(T),T.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:T.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},T.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(u(["definition-mutation","punctuation"])&&"("===d(1).content){n+=2;var s=p(/^\($/,/^\)$/);if(-1===s)continue;for(;n<s;n++){var a=d(0);"variable"===a.type&&(f(a,"variable-input"),o.push(a.content))}n=s+1}if(u(["punctuation","property-query"])&&"{"===d(0).content&&(n++,f(d(0),"property-mutation"),0<o.length)){var i=p(/^\{$/,/^\}$/);if(-1!==i)for(var c=n;c<i;c++){var l=t[c];"variable"===l.type&&0<=o.indexOf(l.content)&&f(l,"variable-input")}}}}function d(e){return t[n+e]}function u(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=d(n+t);if(!r||r.type!==e[n])return}return 1}function p(e,r){for(var o=1,s=n;s<t.length;s++){var a=t[s],i=a.content;if("punctuation"===a.type&&"string"==typeof i)if(e.test(i))o++;else if(r.test(i)&&0==--o)return s}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),T.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],s=r.pattern.source;function a(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function i(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function c(t,n,a){var c=e.tokenize(t,{interpolation:{pattern:RegExp(s),lookbehind:!0}}),l=0,d={},u=(c=i(c.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=l++,n="___"+a.toUpperCase()+"_"+r+"___")););return d[n]=e,n})).join(""),n,a),Object.keys(d));return l=0,function t(n){for(var s=0;s<n.length;s++){if(l>=u.length)return;var a,c,p,f,g,m,h,b=n[s];"string"==typeof b||"string"==typeof b.content?(a=u[l],-1!==(h=(m="string"==typeof b?b:b.content).indexOf(a))&&(++l,c=m.substring(0,h),g=d[a],p=void 0,(f={})["interpolation-punctuation"]=o,3===(f=e.tokenize(g,f)).length&&((p=[1,1]).push.apply(p,i(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,p)),p=new e.Token("interpolation",f,r.alias,g),f=m.substring(h+a.length),g=[],c&&g.push(c),g.push(p),f&&(t(m=[f]),g.push.apply(g,m)),"string"==typeof b?(n.splice.apply(n,[s,1].concat(g)),s+=g.length-1):b.content=g)):(h=b.content,Array.isArray(h)?t(h):t([h]))}}(c),new e.Token(a,c,"language-"+a,t)}e.languages.javascript["template-string"]=[a("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),a("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),a("svg",/\bsvg/.source),a("markdown",/\b(?:markdown|md)/.source),a("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),a("sql",/\bsql/.source),t].filter(Boolean);var l={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function d(e){return"string"==typeof e?e:Array.isArray(e)?e.map(d).join(""):d(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in l&&function t(n){for(var r=0,o=n.length;r<o;r++){var s,a,i,l=n[r];"string"!=typeof l&&(s=l.content,Array.isArray(s)?"template-string"===l.type?(l=s[1],3===s.length&&"string"!=typeof l&&"embedded-code"===l.type&&(a=d(l),l=l.alias,l=Array.isArray(l)?l[0]:l,i=e.languages[l])&&(s[1]=c(a,i,l))):t(s):"string"!=typeof s&&t([s]))}}(t.tokens)}))}(T),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(T),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(T),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(T),T.languages.n4js=T.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),T.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),T.languages.n4jsd=T.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],s=e.languages.javascript[o];o=(s="RegExp"===e.util.type(s)?e.languages.javascript[o]={pattern:s}:s).inside||{};(s.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(T),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function s(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function a(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],s=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:s=!0),(s||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(s=i(o),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)),o.content&&"string"!=typeof o.content&&a(o.content)}}o=s(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=s(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:s(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:s(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||a(e.tokens)}))}(T),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(T),T.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},T.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=T.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(T),T.languages.c=T.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),T.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),T.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},T.languages.c.string],char:T.languages.c.char,comment:T.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:T.languages.c}}}}),T.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete T.languages.c.boolean,T.languages.objectivec=T.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete T.languages.objectivec["class-name"],T.languages.objc=T.languages.objectivec,T.languages.reason=T.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),T.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete T.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(T),T.languages.go=T.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),T.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete T.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(T),T.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},T.languages.python["string-interpolation"].inside.interpolation.inside.rest=T.languages.python,T.languages.py=T.languages.python;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>j,duotoneDark:()=>A,duotoneLight:()=>R,github:()=>P,jettwaveDark:()=>X,jettwaveLight:()=>H,nightOwl:()=>N,nightOwlLight:()=>L,oceanicNext:()=>I,okaidia:()=>M,oneDark:()=>G,oneLight:()=>V,palenight:()=>F,shadesOfPurple:()=>z,synthwave84:()=>B,ultramin:()=>U,vsDark:()=>$,vsLight:()=>q});var j={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},A={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},R={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},P={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},N={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},L={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},O="#c5a5c5",D="#8dc891",I={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:O}},{types:["attr-value"],style:{color:D}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:D}},{types:["punctuation"],style:{color:D}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:O}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},M={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},F={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},z={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},B={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},U={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},$={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},q={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},X={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},H={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},G={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},V={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},W=(e,t)=>{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:o}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=_(_({},e[t]),o);e[t]=n})),e}),{});return r.root=n,r.plain=S(_({},n),{backgroundColor:void 0}),r},K=/\r\n|\r|\n/,Q=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Y=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},Z=e=>{const t=[[]],n=[e],r=[0],o=[e.length];let s=0,a=0,i=[];const c=[i];for(;a>-1;){for(;(s=r[a]++)<o[a];){let e,l=t[a];const d=n[a][s];if("string"==typeof d?(l=a>0?l:["plain"],e=d):(l=Y(l,d.type),d.alias&&(l=Y(l,d.alias)),e=d.content),"string"!=typeof e){a++,t.push(l),n.push(e),r.push(0),o.push(e.length);continue}const u=e.split(K),p=u.length;i.push({types:l,content:u[0]});for(let t=1;t<p;t++)Q(i),c.push(i=[]),i.push({types:l,content:u[t]})}a--,t.pop(),n.pop(),r.pop(),o.pop()}return Q(i),c},J=({children:e,language:t,code:n,theme:r,prism:o})=>{const s=t.toLowerCase(),a=((e,t)=>{const[n,r]=(0,d.useState)(W(t,e)),o=(0,d.useRef)(),s=(0,d.useRef)();return(0,d.useEffect)((()=>{t===o.current&&e===s.current||(o.current=t,s.current=e,r(W(t,e)))}),[e,t]),n})(s,r),i=(e=>(0,d.useCallback)((t=>{var n=t,{className:r,style:o,line:s}=n,a=E(n,["className","style","line"]);const i=S(_({},a),{className:(0,u.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(i.style=e.plain),"object"==typeof o&&(i.style=_(_({},i.style||{}),o)),i}),[e]))(a),c=(e=>{const t=(0,d.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,d.useCallback)((e=>{var n=e,{token:r,className:o,style:s}=n,a=E(n,["token","className","style"]);const i=S(_({},a),{className:(0,u.A)("token",...r.types,o),children:r.content,style:t(r)});return null!=s&&(i.style=_(_({},i.style||{}),s)),i}),[t])})(a),l=(({prism:e,code:t,grammar:n,language:r})=>{const o=(0,d.useRef)(e);return(0,d.useMemo)((()=>{if(null==n)return Z([t]);const e={code:t,grammar:n,language:r,tokens:[]};return o.current.hooks.run("before-tokenize",e),e.tokens=o.current.tokenize(t,n),o.current.hooks.run("after-tokenize",e),Z(e.tokens)}),[t,n,r])})({prism:o,language:s,code:n,grammar:o.languages[s]});return e({tokens:l,className:`prism-code language-${s}`,style:null!=a?a.root:{},getLineProps:i,getTokenProps:c})},ee=e=>(0,d.createElement)(J,S(_({},e),{prism:e.prism||T,theme:e.theme||$,code:e.code,language:e.language}))},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=!0,o="Invariant failed";function s(e,t){if(!e){if(r)throw new Error(o);var n="function"==typeof t?t():t,s=n?"".concat(o,": ").concat(n):o;throw new Error(s)}}},31635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>O,__assign:()=>s,__asyncDelegator:()=>E,__asyncGenerator:()=>S,__asyncValues:()=>C,__await:()=>_,__awaiter:()=>g,__classPrivateFieldGet:()=>P,__classPrivateFieldIn:()=>L,__classPrivateFieldSet:()=>N,__createBinding:()=>h,__decorate:()=>i,__disposeResources:()=>I,__esDecorate:()=>l,__exportStar:()=>b,__extends:()=>o,__generator:()=>m,__importDefault:()=>R,__importStar:()=>A,__makeTemplateObject:()=>T,__metadata:()=>f,__param:()=>c,__propKey:()=>u,__read:()=>y,__rest:()=>a,__runInitializers:()=>d,__setFunctionName:()=>p,__spread:()=>x,__spreadArray:()=>k,__spreadArrays:()=>w,__values:()=>v,default:()=>M});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var s=function(){return s=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},s.apply(this,arguments)};function a(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function i(e,t,n,r){var o,s=arguments.length,a=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,n,r);else for(var i=e.length-1;i>=0;i--)(o=e[i])&&(a=(s<3?o(a):s>3?o(t,n,a):o(t,n))||a);return s>3&&a&&Object.defineProperty(t,n,a),a}function c(e,t){return function(n,r){t(n,r,e)}}function l(e,t,n,r,o,s){function a(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var i,c=r.kind,l="getter"===c?"get":"setter"===c?"set":"value",d=!t&&e?r.static?e:e.prototype:null,u=t||(d?Object.getOwnPropertyDescriptor(d,r.name):{}),p=!1,f=n.length-1;f>=0;f--){var g={};for(var m in r)g[m]="access"===m?{}:r[m];for(var m in r.access)g.access[m]=r.access[m];g.addInitializer=function(e){if(p)throw new TypeError("Cannot add initializers after decoration has completed");s.push(a(e||null))};var h=(0,n[f])("accessor"===c?{get:u.get,set:u.set}:u[l],g);if("accessor"===c){if(void 0===h)continue;if(null===h||"object"!=typeof h)throw new TypeError("Object expected");(i=a(h.get))&&(u.get=i),(i=a(h.set))&&(u.set=i),(i=a(h.init))&&o.unshift(i)}else(i=a(h))&&("field"===c?o.unshift(i):u[l]=i)}d&&Object.defineProperty(d,r.name,u),p=!0}function d(e,t,n){for(var r=arguments.length>2,o=0;o<t.length;o++)n=r?t[o].call(e,n):t[o].call(e);return r?n:void 0}function u(e){return"symbol"==typeof e?e:"".concat(e)}function p(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function f(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function g(e,t,n,r){return new(n||(n=Promise))((function(o,s){function a(e){try{c(r.next(e))}catch(t){s(t)}}function i(e){try{c(r.throw(e))}catch(t){s(t)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,i)}c((r=r.apply(e,t||[])).next())}))}function m(e,t){var n,r,o,s,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(c){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(a=0)),a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(e,a)}catch(c){i=[6,c],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,c])}}}var h=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function b(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||h(t,e,n)}function v(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function y(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,s=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=s.next()).done;)a.push(r.value)}catch(i){o={error:i}}finally{try{r&&!r.done&&(n=s.return)&&n.call(s)}finally{if(o)throw o.error}}return a}function x(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(y(arguments[t]));return e}function w(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var s=arguments[t],a=0,i=s.length;a<i;a++,o++)r[o]=s[a];return r}function k(e,t,n){if(n||2===arguments.length)for(var r,o=0,s=t.length;o<s;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function _(e){return this instanceof _?(this.v=e,this):new _(e)}function S(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),s=[];return r={},a("next"),a("throw"),a("return",(function(e){return function(t){return Promise.resolve(t).then(e,l)}})),r[Symbol.asyncIterator]=function(){return this},r;function a(e,t){o[e]&&(r[e]=function(t){return new Promise((function(n,r){s.push([e,t,n,r])>1||i(e,t)}))},t&&(r[e]=t(r[e])))}function i(e,t){try{(n=o[e](t)).value instanceof _?Promise.resolve(n.value.v).then(c,l):d(s[0][2],n)}catch(r){d(s[0][3],r)}var n}function c(e){i("next",e)}function l(e){i("throw",e)}function d(e,t){e(t),s.shift(),s.length&&i(s[0][0],s[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:_(e[r](t)),done:!1}:o?o(t):t}:o}}function C(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=v(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}function T(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var j=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function A(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&h(t,e,n);return j(t,e),t}function R(e){return e&&e.__esModule?e:{default:e}}function P(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function N(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function L(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function O(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,o;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(o=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");o&&(r=function(){try{o.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var D="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function I(e){function t(t){e.error=e.hasError?new D(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}return function n(){for(;e.stack.length;){var r=e.stack.pop();try{var o=r.dispose&&r.dispose.call(r.value);if(r.async)return Promise.resolve(o).then(n,(function(e){return t(e),n()}))}catch(s){t(s)}}if(e.hasError)throw e.error}()}const M={__extends:o,__assign:s,__rest:a,__decorate:i,__param:c,__metadata:f,__awaiter:g,__generator:m,__createBinding:h,__exportStar:b,__values:v,__read:y,__spread:x,__spreadArrays:w,__spreadArray:k,__await:_,__asyncGenerator:S,__asyncDelegator:E,__asyncValues:C,__makeTemplateObject:T,__importStar:A,__importDefault:R,__classPrivateFieldGet:P,__classPrivateFieldSet:N,__classPrivateFieldIn:L,__addDisposableResource:O,__disposeResources:I}},22654:e=>{"use strict";e.exports={}},84054:e=>{"use strict";e.exports=JSON.parse('{"/blog/-834":{"__comp":"a6aa9e1f","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"},{"content":"98df448b"},{"content":"b1eae65b"},{"content":"80e6044e"},{"content":"b71ecf14"}],"__props":"08af526d"},"/blog/addressable-entity/-887":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"124873a8"},"/blog/archive/-1d9":{"__comp":"9e4087bc","__context":{"plugin":"36994c47"},"__props":"dbfc4782"},"/blog/authors/-347":{"__comp":"621db11d","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","__props":"dd04b75e"},"/blog/authors/alexanderlimonov/-e4c":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"8941358f"}],"sidebar":"814f3328","__props":"8833ab21"},"/blog/authors/dylanireland/-a3a":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"80e6044e"}],"sidebar":"814f3328","__props":"f1245771"},"/blog/authors/melpadden/-0d6":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"8941358f"},{"content":"98df448b"},{"content":"b1eae65b"},{"content":"80e6044e"}],"sidebar":"814f3328","__props":"baabe181"},"/blog/authors/sczembor/-8cb":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"b1eae65b"},{"content":"b71ecf14"}],"sidebar":"814f3328","__props":"358cf6da"},"/blog/condor-fee-elimination/-f26":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"0bd3b317"},"/blog/condor-local-setup/-2aa":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"197196c4"},"/blog/condor-validator-rewards/-3b7":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"277b6be0"},"/blog/tags/-e17":{"__comp":"01a85c17","__context":{"plugin":"36994c47"},"sidebar":"814f3328","__props":"2063472f"},"/blog/tags/condor/-cf9":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"},{"content":"b1eae65b"},{"content":"80e6044e"},{"content":"b71ecf14"}],"__props":"c3308ba6"},"/blog/tags/docs-redux/-339":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"9ec4e3de"},"/blog/tags/features/-bc2":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"80e6044e"}],"__props":"5ce0f216"},"/blog/tags/hello/-8a7":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"33a9c3bd"},"/blog/tags/new-docs/-fdd":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"481163ce"},"/blog/tags/setup/-a7c":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"b71ecf14"}],"__props":"a72bcf22"},"/blog/tags/tokenomics/-9c1":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"80e6044e"}],"__props":"d48191b6"},"/blog/tags/validators/-87b":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"}],"__props":"8de9f24f"},"/blog/welcome-docs-redux/-fc7":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"c377dc4a"},"/search/-21e":{"__comp":"1a4e3797","__context":{"plugin":"c141421f"}},"/-9e1":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/next/-245":{"__comp":"a7bd4aaa","__props":"ca0e408e"},"/next/-eec":{"__comp":"a94703ab"},"/next/-431":{"__comp":"17896441","content":"b8c8445c"},"/next/concepts/-0f4":{"__comp":"17896441","content":"c2728190"},"/next/concepts/accounts-and-keys/-36b":{"__comp":"17896441","content":"c10cfbfe"},"/next/concepts/addressable-entity/-61d":{"__comp":"17896441","content":"3e796ac9"},"/next/concepts/callstack/-ef6":{"__comp":"17896441","content":"4db682c6"},"/next/concepts/design/casper-design/-0eb":{"__comp":"17896441","content":"64959b1e"},"/next/concepts/design/consensus/-7be":{"__comp":"17896441","content":"e289ead3"},"/next/concepts/design/highway/-94c":{"__comp":"17896441","content":"03aa8e23"},"/next/concepts/design/networking-protocol/-df6":{"__comp":"17896441","content":"65961da4"},"/next/concepts/design/p2p/-256":{"__comp":"17896441","content":"977c8faa"},"/next/concepts/design/reading-and-writing-to-the-blockchain/-709":{"__comp":"17896441","content":"bb037852"},"/next/concepts/design/rewards/-456":{"__comp":"17896441","content":"6318ac72"},"/next/concepts/design/zug/-8ee":{"__comp":"17896441","content":"e1e5af17"},"/next/concepts/dictionaries/-24e":{"__comp":"17896441","content":"85b8bb26"},"/next/concepts/economics/consensus/-997":{"__comp":"17896441","content":"a4f8fe7e"},"/next/concepts/economics/dynamic-gas-pricing/-df8":{"__comp":"17896441","content":"a30e2bb0"},"/next/concepts/economics/fee-elimination/-3e8":{"__comp":"17896441","content":"6dcb5e16"},"/next/concepts/economics/gas-concepts/-0de":{"__comp":"17896441","content":"79d896a3"},"/next/concepts/economics/staking/-ef2":{"__comp":"17896441","content":"471ca6e4"},"/next/concepts/global-state/-0a0":{"__comp":"17896441","content":"25f19435"},"/next/concepts/glossary/A/-999":{"__comp":"17896441","content":"6c606038"},"/next/concepts/glossary/B/-e2a":{"__comp":"17896441","content":"afa6d836"},"/next/concepts/glossary/C/-274":{"__comp":"17896441","content":"b15d29cb"},"/next/concepts/glossary/D/-4b8":{"__comp":"17896441","content":"eacea541"},"/next/concepts/glossary/E/-a2a":{"__comp":"17896441","content":"38296185"},"/next/concepts/glossary/F/-dab":{"__comp":"17896441","content":"a53bd891"},"/next/concepts/glossary/G/-4f5":{"__comp":"17896441","content":"d7f9f727"},"/next/concepts/glossary/H/-d9c":{"__comp":"17896441","content":"ab246697"},"/next/concepts/glossary/I/-4d9":{"__comp":"17896441","content":"5ed91ab5"},"/next/concepts/glossary/J/-963":{"__comp":"17896441","content":"14620e15"},"/next/concepts/glossary/K/-730":{"__comp":"17896441","content":"41e7d56e"},"/next/concepts/glossary/L/-73f":{"__comp":"17896441","content":"3efe71e8"},"/next/concepts/glossary/M/-682":{"__comp":"17896441","content":"650a8fc0"},"/next/concepts/glossary/N/-d95":{"__comp":"17896441","content":"4fdb6df3"},"/next/concepts/glossary/O/-df1":{"__comp":"17896441","content":"aa162190"},"/next/concepts/glossary/P/-df7":{"__comp":"17896441","content":"362368d5"},"/next/concepts/glossary/Q/-e4b":{"__comp":"17896441","content":"94f643bb"},"/next/concepts/glossary/R/-29a":{"__comp":"17896441","content":"2cb8ed3d"},"/next/concepts/glossary/S/-e28":{"__comp":"17896441","content":"c9d52fc5"},"/next/concepts/glossary/T/-9aa":{"__comp":"17896441","content":"4545390c"},"/next/concepts/glossary/U/-bc5":{"__comp":"17896441","content":"65a9ed9e"},"/next/concepts/glossary/V/-e9c":{"__comp":"17896441","content":"ad727d36"},"/next/concepts/glossary/W/-74f":{"__comp":"17896441","content":"130631d9"},"/next/concepts/glossary/X/-d66":{"__comp":"17896441","content":"87f5bee7"},"/next/concepts/glossary/Y/-d4c":{"__comp":"17896441","content":"e5493a21"},"/next/concepts/glossary/Z/-f02":{"__comp":"17896441","content":"b3a49b92"},"/next/concepts/intro-to-dapps/-799":{"__comp":"17896441","content":"5cf40dea"},"/next/concepts/key-types/-f53":{"__comp":"17896441","content":"134a9ec2"},"/next/concepts/list-auth-keys/-8a6":{"__comp":"17896441","content":"398cf21c"},"/next/concepts/serialization/-c63":{"__comp":"17896441","content":"dfcc4619"},"/next/concepts/serialization/primitives/-84c":{"__comp":"17896441","content":"f95b1f88"},"/next/concepts/serialization/structures/-f86":{"__comp":"17896441","content":"56ad65de"},"/next/concepts/serialization/types/-764":{"__comp":"17896441","content":"64899cf9"},"/next/concepts/smart-contracts/-130":{"__comp":"17896441","content":"58092c27"},"/next/counter-testnet/-ba2":{"__comp":"17896441","content":"bf5bbaf8"},"/next/counter/-356":{"__comp":"17896441","content":"ab991e0e"},"/next/design/-5b5":{"__comp":"17896441","content":"d7289626"},"/next/developers/-a93":{"__comp":"17896441","content":"63925da8"},"/next/developers/cli/-9b6":{"__comp":"17896441","content":"46e94768"},"/next/developers/cli/calling-contracts/-9cf":{"__comp":"17896441","content":"8ff31131"},"/next/developers/cli/delegate/-453":{"__comp":"17896441","content":"4d118a4e"},"/next/developers/cli/execution-error-codes/-e24":{"__comp":"17896441","content":"459c4db6"},"/next/developers/cli/installing-contracts/-ae4":{"__comp":"17896441","content":"0b8cc739"},"/next/developers/cli/opcode-costs/-739":{"__comp":"17896441","content":"452e65d7"},"/next/developers/cli/querying-global-state/-2f4":{"__comp":"17896441","content":"cb63487a"},"/next/developers/cli/redelegate/-846":{"__comp":"17896441","content":"63d4ce07"},"/next/developers/cli/sending-transactions/-110":{"__comp":"17896441","content":"6e34a484"},"/next/developers/cli/transfers/-937":{"__comp":"17896441","content":"2ffce966"},"/next/developers/cli/transfers/direct-token-transfer/-b10":{"__comp":"17896441","content":"f1c6b7a3"},"/next/developers/cli/transfers/multisig-deploy-transfer/-fe4":{"__comp":"17896441","content":"7c798d59"},"/next/developers/cli/transfers/verify-transfer/-e9e":{"__comp":"17896441","content":"3bf1ce3c"},"/next/developers/cli/undelegate/-8c5":{"__comp":"17896441","content":"c19e69a7"},"/next/developers/cli/verifying-contracts/-431":{"__comp":"17896441","content":"ce6605d8"},"/next/developers/dapps/-972":{"__comp":"17896441","content":"a1868598"},"/next/developers/dapps/dapp/-072":{"__comp":"17896441","content":"51719dea"},"/next/developers/dapps/monitor-and-consume-events/-f22":{"__comp":"17896441","content":"c0299000"},"/next/developers/dapps/nctl-test/-74b":{"__comp":"17896441","content":"2d971abe"},"/next/developers/dapps/prerequisites/-92e":{"__comp":"17896441","content":"f3bf6984"},"/next/developers/dapps/sdk/client-library-usage/-f98":{"__comp":"17896441","content":"08996e66"},"/next/developers/dapps/sdk/csharp-sdk/-111":{"__comp":"17896441","content":"06c1e821"},"/next/developers/dapps/sdk/go-sdk/-72a":{"__comp":"17896441","content":"e45056bc"},"/next/developers/dapps/sdk/python-sdk/-10b":{"__comp":"17896441","content":"d49dddd4"},"/next/developers/dapps/sdk/script-sdk/-e20":{"__comp":"17896441","content":"8c0ead1f"},"/next/developers/dapps/setup-nctl/-f0c":{"__comp":"17896441","content":"a4ae8417"},"/next/developers/dapps/signing-a-transaction/-82d":{"__comp":"17896441","content":"044f7961"},"/next/developers/dapps/speculative-exec/-d76":{"__comp":"17896441","content":"7cff47a5"},"/next/developers/dapps/technology-stack/-22e":{"__comp":"17896441","content":"a9deb425"},"/next/developers/dapps/template-frontend/-fba":{"__comp":"17896441","content":"7607f1d5"},"/next/developers/dapps/uref-security/-6a8":{"__comp":"17896441","content":"cc2e94c0"},"/next/developers/essential-crates/-aa0":{"__comp":"17896441","content":"680b7fa9"},"/next/developers/json-rpc/-09a":{"__comp":"17896441","content":"5a3b84ba"},"/next/developers/json-rpc/errors/-4a3":{"__comp":"17896441","content":"3aaf2bfb"},"/next/developers/json-rpc/guidance/-875":{"__comp":"17896441","content":"f2779c45"},"/next/developers/json-rpc/json-rpc-informational/-c16":{"__comp":"17896441","content":"d638c601"},"/next/developers/json-rpc/json-rpc-pos/-b71":{"__comp":"17896441","content":"7b1c3c68"},"/next/developers/json-rpc/json-rpc-transactional/-11d":{"__comp":"17896441","content":"753d7b98"},"/next/developers/json-rpc/minimal-compliance/-8e2":{"__comp":"17896441","content":"1b2f0a70"},"/next/developers/json-rpc/types_chain/-cc2":{"__comp":"17896441","content":"60d3a705"},"/next/developers/json-rpc/types_cl/-437":{"__comp":"17896441","content":"6a307077"},"/next/developers/prerequisites/-0ad":{"__comp":"17896441","content":"e08eef46"},"/next/developers/writing-onchain-code/assembly-script/-1f0":{"__comp":"17896441","content":"1c694ffb"},"/next/developers/writing-onchain-code/best-practices/-857":{"__comp":"17896441","content":"19770ceb"},"/next/developers/writing-onchain-code/calling-contracts/-825":{"__comp":"17896441","content":"0bb2dbe9"},"/next/developers/writing-onchain-code/contract-hash-vs-package-hash/-f3a":{"__comp":"17896441","content":"6e2737c0"},"/next/developers/writing-onchain-code/contract-vs-session/-89b":{"__comp":"17896441","content":"a81b7004"},"/next/developers/writing-onchain-code/emitting-contract-events/-1ff":{"__comp":"17896441","content":"261dbd4a"},"/next/developers/writing-onchain-code/factory-pattern/-aea":{"__comp":"17896441","content":"6520db96"},"/next/developers/writing-onchain-code/getting-started/-ece":{"__comp":"17896441","content":"5497691c"},"/next/developers/writing-onchain-code/simple-contract/-c49":{"__comp":"17896441","content":"e8b40bee"},"/next/developers/writing-onchain-code/testing-contracts/-878":{"__comp":"17896441","content":"106b67a5"},"/next/developers/writing-onchain-code/testing-session-code/-db8":{"__comp":"17896441","content":"7f115b1f"},"/next/developers/writing-onchain-code/upgrading-contracts/-6fd":{"__comp":"17896441","content":"053d5d89"},"/next/developers/writing-onchain-code/writing-session-code/-ebe":{"__comp":"17896441","content":"3724f9ed"},"/next/disclaimer/-f2d":{"__comp":"17896441","content":"fe0242b1"},"/next/economics/-67e":{"__comp":"17896441","content":"ad15c07f"},"/next/glossary/-415":{"__comp":"17896441","content":"2e4bdb60"},"/next/operators/-233":{"__comp":"17896441","content":"5f02ec4e"},"/next/operators/becoming-a-validator/-bfc":{"__comp":"17896441","content":"9c5b6467"},"/next/operators/becoming-a-validator/bonding/-f30":{"__comp":"17896441","content":"be0df356"},"/next/operators/becoming-a-validator/change-bid-public-key/-47f":{"__comp":"17896441","content":"915d90e1"},"/next/operators/becoming-a-validator/inactive-vs-faulty/-ab0":{"__comp":"17896441","content":"78c66fad"},"/next/operators/becoming-a-validator/recovering/-e27":{"__comp":"17896441","content":"9cd0819b"},"/next/operators/becoming-a-validator/unbonding/-133":{"__comp":"17896441","content":"28bc9864"},"/next/operators/maintenance/-ec3":{"__comp":"17896441","content":"64c09e2e"},"/next/operators/maintenance/archiving-and-restoring/-c92":{"__comp":"17896441","content":"074e7bdc"},"/next/operators/maintenance/moving-node/-d48":{"__comp":"17896441","content":"f46d6e59"},"/next/operators/setup-network/-21a":{"__comp":"17896441","content":"116fa82a"},"/next/operators/setup-network/chain-spec/-530":{"__comp":"17896441","content":"a0ccdbb2"},"/next/operators/setup-network/create-private/-032":{"__comp":"17896441","content":"c52eaa26"},"/next/operators/setup-network/genesis/-9ed":{"__comp":"17896441","content":"a9f5564d"},"/next/operators/setup-network/staging-files-for-new-network/-922":{"__comp":"17896441","content":"f88cb658"},"/next/operators/setup/-485":{"__comp":"17896441","content":"b36f50d3"},"/next/operators/setup/basic-node-configuration/-65b":{"__comp":"17896441","content":"99a13742"},"/next/operators/setup/casper-sidecar/-f49":{"__comp":"17896441","content":"31722bc4"},"/next/operators/setup/fast-sync/-dd1":{"__comp":"17896441","content":"c2a48fdb"},"/next/operators/setup/hardware/-5ac":{"__comp":"17896441","content":"c7d46fe1"},"/next/operators/setup/install-node/-493":{"__comp":"17896441","content":"03acd2fb"},"/next/operators/setup/joining/-a69":{"__comp":"17896441","content":"cbe8101d"},"/next/operators/setup/node-endpoints/-21b":{"__comp":"17896441","content":"e2799c63"},"/next/operators/setup/node-events/-f97":{"__comp":"17896441","content":"830e9e14"},"/next/operators/setup/non-root-user/-682":{"__comp":"17896441","content":"db24aef0"},"/next/operators/setup/open-files/-555":{"__comp":"17896441","content":"68ccb7f6"},"/next/operators/setup/upgrade/-3cc":{"__comp":"17896441","content":"b46ec474"},"/next/resources/-4af":{"__comp":"17896441","content":"cd948886"},"/next/resources/advanced/list-auth-keys-tutorial/-384":{"__comp":"17896441","content":"ba0fa3fe"},"/next/resources/advanced/multi-sig/-cb2":{"__comp":"17896441","content":"2fb5589e"},"/next/resources/advanced/multi-sig/multi-sig-workflow/-118":{"__comp":"17896441","content":"d92b4d08"},"/next/resources/advanced/multi-sig/other-scenarios/-707":{"__comp":"17896441","content":"fb804d1c"},"/next/resources/beginner/counter-testnet/commands/-12c":{"__comp":"17896441","content":"05a3aa78"},"/next/resources/beginner/counter-testnet/overview/-1d0":{"__comp":"17896441","content":"1e144f6d"},"/next/resources/beginner/counter-testnet/walkthrough/-d50":{"__comp":"17896441","content":"8f27be43"},"/next/resources/beginner/counter/commands/-312":{"__comp":"17896441","content":"560adf9d"},"/next/resources/beginner/counter/overview/-34f":{"__comp":"17896441","content":"9116852a"},"/next/resources/beginner/counter/walkthrough/-69e":{"__comp":"17896441","content":"236eb0f0"},"/next/resources/build-on-casper/casper-open-source-software/-778":{"__comp":"17896441","content":"f776c06c"},"/next/resources/build-on-casper/introduction/-597":{"__comp":"17896441","content":"861e5e13"},"/next/resources/changelog/-3c8":{"__comp":"17896441","content":"d0a8493b"},"/next/resources/moving-to-casper/-b9c":{"__comp":"17896441","content":"2c27a7b4"},"/next/resources/quick-start/-cc3":{"__comp":"17896441","content":"be5e85f4"},"/next/resources/tokens/-169":{"__comp":"17896441","content":"0cde4ba3"},"/next/resources/tokens/cep18/full-tutorial/-259":{"__comp":"17896441","content":"28b5b925"},"/next/resources/tokens/cep18/query/-9e3":{"__comp":"17896441","content":"ad0b296a"},"/next/resources/tokens/cep18/quickstart-guide/-a3d":{"__comp":"17896441","content":"6193b30e"},"/next/resources/tokens/cep18/tests/-a8b":{"__comp":"17896441","content":"a811e42c"},"/next/resources/tokens/cep18/transfer/-8b3":{"__comp":"17896441","content":"89d896be"},"/next/resources/tokens/cep78/introduction/-ca5":{"__comp":"17896441","content":"3a5d5492"},"/next/resources/tokens/cep78/js-tutorial/-52e":{"__comp":"17896441","content":"d80df429"},"/next/resources/tokens/cep78/modalities/-c7d":{"__comp":"17896441","content":"d4c529d3"},"/next/resources/tokens/cep78/reverse-lookup/-cd8":{"__comp":"17896441","content":"4c91363f"},"/next/resources/tokens/using-casper-client/-e2e":{"__comp":"17896441","content":"157e4bc2"},"/next/resources/tutorials/advanced/-6ca":{"__comp":"17896441","content":"381391cb"},"/next/resources/tutorials/advanced/cross-contract/-d51":{"__comp":"17896441","content":"46c04ff3"},"/next/resources/tutorials/advanced/list-cspr/-374":{"__comp":"17896441","content":"a55b9639"},"/next/resources/tutorials/advanced/return-values-tutorial/-49e":{"__comp":"17896441","content":"ee94176e"},"/next/resources/tutorials/advanced/storage-workflow/-f4d":{"__comp":"17896441","content":"dfbc8a55"},"/next/resources/tutorials/advanced/transfer-token-to-contract/-6d6":{"__comp":"17896441","content":"d06ee05c"},"/next/resources/tutorials/advanced/two-party-multi-sig/-b67":{"__comp":"17896441","content":"15ce11b3"},"/next/resources/tutorials/beginner/-026":{"__comp":"17896441","content":"8d81394c"},"/next/resources/tutorials/beginner/aws-node/-f3b":{"__comp":"17896441","content":"7b8da7d8"},"/next/resources/tutorials/beginner/cep18/-8eb":{"__comp":"17896441","content":"546b5549"},"/next/resources/tutorials/beginner/getting-started-tutorial/-6d3":{"__comp":"17896441","content":"4ba3ceff"},"/next/resources/tutorials/beginner/querying-network/-57a":{"__comp":"17896441","content":"8323e0f5"},"/next/resources/tutorials/beginner/upgrade-contract/-90d":{"__comp":"17896441","content":"7708241d"},"/next/runtime/-670":{"__comp":"17896441","content":"3619739c"},"/next/sdk/-b20":{"__comp":"17896441","content":"9c780b1a"},"/next/transactions-and-transaction-lifecycle/-6b1":{"__comp":"17896441","content":"dc5e10d3"},"/next/transactions/-184":{"__comp":"17896441","content":"f0563fee"},"/next/users/-cba":{"__comp":"17896441","content":"449bc0d9"},"/next/users/block-explorer/-d36":{"__comp":"17896441","content":"89c22482"},"/next/users/csprlive/-462":{"__comp":"17896441","content":"aafbba97"},"/next/users/delegate-ui/-513":{"__comp":"17896441","content":"5a22b142"},"/next/users/delegating/-d1d":{"__comp":"17896441","content":"870de909"},"/next/users/funding-from-exchanges/-4ed":{"__comp":"17896441","content":"74d57d33"},"/next/users/ledger/-130":{"__comp":"17896441","content":"e15566cb"},"/next/users/ledger/ledger-cspr-live/-adb":{"__comp":"17896441","content":"5979a0ec"},"/next/users/ledger/ledger-live/-c01":{"__comp":"17896441","content":"faf2a93e"},"/next/users/staking-ledger/-e01":{"__comp":"17896441","content":"ae470ddc"},"/next/users/testnet-faucet/-95b":{"__comp":"17896441","content":"dcb4c613"},"/next/users/token-transfer/-d87":{"__comp":"17896441","content":"9ed00072"},"/next/users/undelegate-ui/-75d":{"__comp":"17896441","content":"76a75fbd"},"/next/workflow/ledger-setup/-32f":{"__comp":"17896441","content":"2668f34f"},"/next/writing-contracts/-68e":{"__comp":"17896441","content":"51ce653c"},"/-92c":{"__comp":"a7bd4aaa","__props":"22dd74f7"},"/-57d":{"__comp":"a94703ab"},"/concepts/-9a3":{"__comp":"17896441","content":"befad559"},"/concepts/accounts-and-keys/-18a":{"__comp":"17896441","content":"40c07125"},"/concepts/callstack/-218":{"__comp":"17896441","content":"39ac5a41"},"/concepts/design/casper-design/-608":{"__comp":"17896441","content":"26f7e8fd"},"/concepts/design/highway/-237":{"__comp":"17896441","content":"ce0e1dbb"},"/concepts/design/networking-protocol/-3a3":{"__comp":"17896441","content":"b687a817"},"/concepts/design/p2p/-8b8":{"__comp":"17896441","content":"90efbb16"},"/concepts/design/reading-and-writing-to-the-blockchain/-55e":{"__comp":"17896441","content":"883310e5"},"/concepts/dictionaries/-767":{"__comp":"17896441","content":"a03c4947"},"/concepts/economics/concepts/-1e0":{"__comp":"17896441","content":"7effaf45"},"/concepts/economics/consensus/-294":{"__comp":"17896441","content":"34b086e1"},"/concepts/economics/delegation/-837":{"__comp":"17896441","content":"38b4dbd3"},"/concepts/economics/gas-concepts/-57f":{"__comp":"17896441","content":"a80f26d4"},"/concepts/global-state/-25c":{"__comp":"17896441","content":"a4046515"},"/concepts/glossary/A/-85a":{"__comp":"17896441","content":"603aca9e"},"/concepts/glossary/B/-a71":{"__comp":"17896441","content":"3aa29420"},"/concepts/glossary/C/-8d7":{"__comp":"17896441","content":"bafead24"},"/concepts/glossary/D/-990":{"__comp":"17896441","content":"7ade0b2a"},"/concepts/glossary/E/-843":{"__comp":"17896441","content":"43fd3112"},"/concepts/glossary/F/-7ff":{"__comp":"17896441","content":"4e8b7bcc"},"/concepts/glossary/G/-54f":{"__comp":"17896441","content":"58718032"},"/concepts/glossary/H/-0c5":{"__comp":"17896441","content":"4423d65b"},"/concepts/glossary/I/-f08":{"__comp":"17896441","content":"6474e148"},"/concepts/glossary/J/-580":{"__comp":"17896441","content":"4804492c"},"/concepts/glossary/K/-7dd":{"__comp":"17896441","content":"31dbaea7"},"/concepts/glossary/L/-0f8":{"__comp":"17896441","content":"6fe126b9"},"/concepts/glossary/M/-626":{"__comp":"17896441","content":"a4b0daeb"},"/concepts/glossary/N/-0e3":{"__comp":"17896441","content":"12e95288"},"/concepts/glossary/O/-c7e":{"__comp":"17896441","content":"c4561df8"},"/concepts/glossary/P/-903":{"__comp":"17896441","content":"028247bf"},"/concepts/glossary/Q/-927":{"__comp":"17896441","content":"2bd0ed90"},"/concepts/glossary/R/-8da":{"__comp":"17896441","content":"4ab63648"},"/concepts/glossary/S/-de1":{"__comp":"17896441","content":"b3b8c5cb"},"/concepts/glossary/T/-826":{"__comp":"17896441","content":"6245c126"},"/concepts/glossary/U/-4db":{"__comp":"17896441","content":"d050b476"},"/concepts/glossary/V/-c26":{"__comp":"17896441","content":"52fa5650"},"/concepts/glossary/W/-c97":{"__comp":"17896441","content":"b67f60dc"},"/concepts/glossary/X/-fd1":{"__comp":"17896441","content":"bc4bfdf0"},"/concepts/glossary/Y/-c1a":{"__comp":"17896441","content":"9c6aa8d2"},"/concepts/glossary/Z/-903":{"__comp":"17896441","content":"e238c115"},"/concepts/hash-types/-664":{"__comp":"17896441","content":"2cc4f81c"},"/concepts/intro-to-dapps/-fb0":{"__comp":"17896441","content":"ef2abd7e"},"/concepts/list-auth-keys/-93f":{"__comp":"17896441","content":"f070a991"},"/concepts/serialization-standard/-fab":{"__comp":"17896441","content":"d2039ef8"},"/concepts/smart-contracts/-b66":{"__comp":"17896441","content":"7e55f6e6"},"/counter-testnet/-c0a":{"__comp":"17896441","content":"9afe1d3d"},"/counter/-c0d":{"__comp":"17896441","content":"9d275d72"},"/deploy-and-deploy-lifecycle/-985":{"__comp":"17896441","content":"931ecaed"},"/design/-ad0":{"__comp":"17896441","content":"c74094f8"},"/developers/-856":{"__comp":"17896441","content":"c8e4da00"},"/developers/cli/-227":{"__comp":"17896441","content":"521a6610"},"/developers/cli/calling-contracts/-210":{"__comp":"17896441","content":"f1f89c2e"},"/developers/cli/delegate/-fde":{"__comp":"17896441","content":"ea0474c4"},"/developers/cli/execution-error-codes/-fef":{"__comp":"17896441","content":"241648bf"},"/developers/cli/installing-contracts/-410":{"__comp":"17896441","content":"7c67ea25"},"/developers/cli/opcode-costs/-4ae":{"__comp":"17896441","content":"0753c93f"},"/developers/cli/querying-global-state/-62b":{"__comp":"17896441","content":"4cc75cd6"},"/developers/cli/redelegate/-e46":{"__comp":"17896441","content":"106a38e1"},"/developers/cli/sending-deploys/-67a":{"__comp":"17896441","content":"a434b528"},"/developers/cli/transfers/-78b":{"__comp":"17896441","content":"35a4f7b3"},"/developers/cli/transfers/direct-token-transfer/-169":{"__comp":"17896441","content":"8e1fd569"},"/developers/cli/transfers/multisig-deploy-transfer/-9c9":{"__comp":"17896441","content":"eaba5dd2"},"/developers/cli/transfers/verify-transfer/-451":{"__comp":"17896441","content":"5e9306ee"},"/developers/cli/undelegate/-98c":{"__comp":"17896441","content":"20f436ec"},"/developers/dapps/-33b":{"__comp":"17896441","content":"705e93ef"},"/developers/dapps/dapp/-0f4":{"__comp":"17896441","content":"e2975a84"},"/developers/dapps/monitor-and-consume-events/-f6e":{"__comp":"17896441","content":"3362155c"},"/developers/dapps/nctl-test/-e5c":{"__comp":"17896441","content":"bb9db0dd"},"/developers/dapps/prerequisites/-d2d":{"__comp":"17896441","content":"ed267fba"},"/developers/dapps/sdk/client-library-usage/-c13":{"__comp":"17896441","content":"b7708f1e"},"/developers/dapps/sdk/csharp-sdk/-b9a":{"__comp":"17896441","content":"0dea8207"},"/developers/dapps/sdk/go-sdk/-465":{"__comp":"17896441","content":"a3dc4ae2"},"/developers/dapps/sdk/python-sdk/-e6f":{"__comp":"17896441","content":"bfb3244a"},"/developers/dapps/sdk/script-sdk/-701":{"__comp":"17896441","content":"35808b61"},"/developers/dapps/setup-nctl/-88f":{"__comp":"17896441","content":"af1112c6"},"/developers/dapps/signing-a-deploy/-fe7":{"__comp":"17896441","content":"5364a150"},"/developers/dapps/speculative-exec/-be2":{"__comp":"17896441","content":"3ce1a06b"},"/developers/dapps/technology-stack/-79a":{"__comp":"17896441","content":"0ac4e675"},"/developers/dapps/template-frontend/-21e":{"__comp":"17896441","content":"5c3f78ae"},"/developers/dapps/uref-security/-1a5":{"__comp":"17896441","content":"d477c291"},"/developers/essential-crates/-7ef":{"__comp":"17896441","content":"55568807"},"/developers/json-rpc/-6b0":{"__comp":"17896441","content":"aee0fe92"},"/developers/json-rpc/errors/-e89":{"__comp":"17896441","content":"23e022aa"},"/developers/json-rpc/guidance/-d85":{"__comp":"17896441","content":"7cf62e8d"},"/developers/json-rpc/json-rpc-informational/-d2f":{"__comp":"17896441","content":"ac361b55"},"/developers/json-rpc/json-rpc-pos/-8f5":{"__comp":"17896441","content":"03c6d9c7"},"/developers/json-rpc/json-rpc-transactional/-491":{"__comp":"17896441","content":"1b0eecbc"},"/developers/json-rpc/minimal-compliance/-4e6":{"__comp":"17896441","content":"480fa8f7"},"/developers/json-rpc/types_chain/-f3f":{"__comp":"17896441","content":"ad7eda35"},"/developers/json-rpc/types_cl/-43c":{"__comp":"17896441","content":"202767e6"},"/developers/prerequisites/-0c3":{"__comp":"17896441","content":"212aab5d"},"/developers/writing-onchain-code/assembly-script/-ea8":{"__comp":"17896441","content":"7ce4a62a"},"/developers/writing-onchain-code/best-practices/-a98":{"__comp":"17896441","content":"ca7245df"},"/developers/writing-onchain-code/calling-contracts/-f79":{"__comp":"17896441","content":"727f767d"},"/developers/writing-onchain-code/contract-hash-vs-package-hash/-f11":{"__comp":"17896441","content":"a2874f18"},"/developers/writing-onchain-code/contract-vs-session/-f69":{"__comp":"17896441","content":"53d095ec"},"/developers/writing-onchain-code/getting-started/-fb8":{"__comp":"17896441","content":"555a4473"},"/developers/writing-onchain-code/simple-contract/-a5e":{"__comp":"17896441","content":"eb1cd7f2"},"/developers/writing-onchain-code/testing-contracts/-e4c":{"__comp":"17896441","content":"65cd111b"},"/developers/writing-onchain-code/testing-session-code/-ec5":{"__comp":"17896441","content":"d279fdce"},"/developers/writing-onchain-code/upgrading-contracts/-101":{"__comp":"17896441","content":"0c098c15"},"/developers/writing-onchain-code/writing-session-code/-98d":{"__comp":"17896441","content":"c380abc4"},"/disclaimer/-daa":{"__comp":"17896441","content":"3d90f760"},"/economics/-660":{"__comp":"17896441","content":"ee7c1cc7"},"/glossary/-710":{"__comp":"17896441","content":"eb0d94ae"},"/operators/-631":{"__comp":"17896441","content":"0904ce24"},"/operators/becoming-a-validator/-531":{"__comp":"17896441","content":"c9db186d"},"/operators/becoming-a-validator/bonding/-a3b":{"__comp":"17896441","content":"5052751d"},"/operators/becoming-a-validator/inactive-vs-faulty/-364":{"__comp":"17896441","content":"3a9d2720"},"/operators/becoming-a-validator/recovering/-119":{"__comp":"17896441","content":"4e4df367"},"/operators/becoming-a-validator/unbonding/-c65":{"__comp":"17896441","content":"bd7d26b2"},"/operators/maintenance/-4d1":{"__comp":"17896441","content":"3b86d751"},"/operators/maintenance/archiving-and-restoring/-1e6":{"__comp":"17896441","content":"9acc619b"},"/operators/maintenance/moving-node/-e95":{"__comp":"17896441","content":"168da062"},"/operators/setup-network/-93d":{"__comp":"17896441","content":"8d265689"},"/operators/setup-network/chain-spec/-94f":{"__comp":"17896441","content":"40078125"},"/operators/setup-network/create-private/-e21":{"__comp":"17896441","content":"5109d3ad"},"/operators/setup-network/genesis/-1c0":{"__comp":"17896441","content":"fef6ab33"},"/operators/setup-network/staging-files-for-new-network/-610":{"__comp":"17896441","content":"772d3db3"},"/operators/setup/-f6c":{"__comp":"17896441","content":"dd908370"},"/operators/setup/basic-node-configuration/-f3b":{"__comp":"17896441","content":"5c07109c"},"/operators/setup/fast-sync/-972":{"__comp":"17896441","content":"d94d6bbe"},"/operators/setup/hardware/-53b":{"__comp":"17896441","content":"d3ef4614"},"/operators/setup/install-node/-b94":{"__comp":"17896441","content":"340c2365"},"/operators/setup/joining/-62b":{"__comp":"17896441","content":"738a6ad4"},"/operators/setup/node-endpoints/-427":{"__comp":"17896441","content":"a40a2cf8"},"/operators/setup/non-root-user/-f5a":{"__comp":"17896441","content":"79474bae"},"/operators/setup/open-files/-fff":{"__comp":"17896441","content":"aefd42fa"},"/operators/setup/upgrade/-68f":{"__comp":"17896441","content":"72c6e609"},"/resources/-586":{"__comp":"17896441","content":"2c04116d"},"/resources/advanced/list-auth-keys-tutorial/-c29":{"__comp":"17896441","content":"26a33332"},"/resources/advanced/multi-sig/-058":{"__comp":"17896441","content":"9ee7887a"},"/resources/advanced/multi-sig/multi-sig-workflow/-268":{"__comp":"17896441","content":"e3f9a068"},"/resources/advanced/multi-sig/other-scenarios/-984":{"__comp":"17896441","content":"ebb9a3ce"},"/resources/beginner/counter-testnet/commands/-8e9":{"__comp":"17896441","content":"41eb5a6a"},"/resources/beginner/counter-testnet/overview/-bc2":{"__comp":"17896441","content":"a4cd78b5"},"/resources/beginner/counter-testnet/walkthrough/-305":{"__comp":"17896441","content":"dc1c4417"},"/resources/beginner/counter/commands/-565":{"__comp":"17896441","content":"c691959f"},"/resources/beginner/counter/overview/-011":{"__comp":"17896441","content":"df5bc763"},"/resources/beginner/counter/walkthrough/-fd8":{"__comp":"17896441","content":"3fe76c6c"},"/resources/build-on-casper/casper-open-source-software/-e3a":{"__comp":"17896441","content":"f71fe95d"},"/resources/build-on-casper/introduction/-2c7":{"__comp":"17896441","content":"709dfa47"},"/resources/condor-for-exchanges/-d24":{"__comp":"17896441","content":"e2f5312b"},"/resources/moving-to-casper/-45a":{"__comp":"17896441","content":"43a834ef"},"/resources/quick-start/-bce":{"__comp":"17896441","content":"4e015808"},"/resources/tokens/-2fb":{"__comp":"17896441","content":"1871ac35"},"/resources/tokens/cep18/full-tutorial/-0c2":{"__comp":"17896441","content":"2b8e251b"},"/resources/tokens/cep18/query/-044":{"__comp":"17896441","content":"cbe09f13"},"/resources/tokens/cep18/quickstart-guide/-f97":{"__comp":"17896441","content":"c37f176d"},"/resources/tokens/cep18/tests/-056":{"__comp":"17896441","content":"3b749ca6"},"/resources/tokens/cep18/transfer/-84f":{"__comp":"17896441","content":"ef7672e3"},"/resources/tokens/cep78/introduction/-ca6":{"__comp":"17896441","content":"5d4e9672"},"/resources/tokens/cep78/js-tutorial/-05a":{"__comp":"17896441","content":"af050a36"},"/resources/tokens/cep78/modalities/-f34":{"__comp":"17896441","content":"32dd135c"},"/resources/tokens/cep78/reverse-lookup/-70d":{"__comp":"17896441","content":"eb5a6cc0"},"/resources/tokens/cep78/using-casper-client/full-installation-tutorial/-4e1":{"__comp":"17896441","content":"a35afcc3"},"/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/-d6d":{"__comp":"17896441","content":"533ebf6b"},"/resources/tokens/cep78/using-casper-client/querying-NFTs/-258":{"__comp":"17896441","content":"cf35294f"},"/resources/tokens/cep78/using-casper-client/quickstart-guide/-056":{"__comp":"17896441","content":"fd661beb"},"/resources/tokens/cep78/using-casper-client/testing-NFTs/-1aa":{"__comp":"17896441","content":"897e9cb3"},"/resources/tutorials/advanced/-134":{"__comp":"17896441","content":"d7fae98e"},"/resources/tutorials/advanced/cross-contract/-c0d":{"__comp":"17896441","content":"0791978c"},"/resources/tutorials/advanced/list-cspr/-2b6":{"__comp":"17896441","content":"60fa9972"},"/resources/tutorials/advanced/return-values-tutorial/-433":{"__comp":"17896441","content":"abd56c27"},"/resources/tutorials/advanced/storage-workflow/-42e":{"__comp":"17896441","content":"6043c3f4"},"/resources/tutorials/advanced/transfer-token-to-contract/-ea6":{"__comp":"17896441","content":"821dc1e3"},"/resources/tutorials/advanced/two-party-multi-sig/-f0f":{"__comp":"17896441","content":"eff21157"},"/resources/tutorials/beginner/-06a":{"__comp":"17896441","content":"72b43be8"},"/resources/tutorials/beginner/aws-node/-435":{"__comp":"17896441","content":"57f923a9"},"/resources/tutorials/beginner/cep18/-58e":{"__comp":"17896441","content":"e4d870e1"},"/resources/tutorials/beginner/getting-started-tutorial/-647":{"__comp":"17896441","content":"77981a3a"},"/resources/tutorials/beginner/querying-network/-6ba":{"__comp":"17896441","content":"d220dcab"},"/resources/tutorials/beginner/upgrade-contract/-d39":{"__comp":"17896441","content":"72cc2261"},"/runtime/-e97":{"__comp":"17896441","content":"56746dcb"},"/sdk/-2a1":{"__comp":"17896441","content":"c9f0fdac"},"/staking/-02d":{"__comp":"17896441","content":"21ae0e7e"},"/users/-e5e":{"__comp":"17896441","content":"d13dc577"},"/users/block-explorer/-889":{"__comp":"17896441","content":"5b827590"},"/users/csprlive/-165":{"__comp":"17896441","content":"a6efe0e1"},"/users/delegate-ui/-c78":{"__comp":"17896441","content":"72a89de8"},"/users/funding-from-exchanges/-921":{"__comp":"17896441","content":"75de5623"},"/users/ledger/-914":{"__comp":"17896441","content":"9b0d9b67"},"/users/ledger/ledger-cspr-live/-aef":{"__comp":"17896441","content":"ce3d5a4b"},"/users/ledger/ledger-live/-4da":{"__comp":"17896441","content":"331badc5"},"/users/staking-ledger/-8d6":{"__comp":"17896441","content":"4832c6fe"},"/users/testnet-faucet/-a2e":{"__comp":"17896441","content":"c10b8a9f"},"/users/token-transfer/-ded":{"__comp":"17896441","content":"41905acb"},"/users/undelegate-ui/-96f":{"__comp":"17896441","content":"04f8200d"},"/workflow/ledger-setup/-228":{"__comp":"17896441","content":"3669623c"},"/writing-contracts/-147":{"__comp":"17896441","content":"3ac85609"},"/-981":{"__comp":"17896441","content":"baf71301"}}')}},e=>{e.O(0,[1869],(()=>{return t=38536,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.d3917998.js b/assets/js/main.d3917998.js new file mode 100644 index 000000000..605012a0d --- /dev/null +++ b/assets/js/main.d3917998.js @@ -0,0 +1,2 @@ +/*! For license information please see main.d3917998.js.LICENSE.txt */ +(self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[]).push([[38792],{89188:(e,t,n)=>{"use strict";n.d(t,{W:()=>o});var r=n(96540);function o(){return r.createElement("svg",{width:"20",height:"20",className:"DocSearch-Search-Icon",viewBox:"0 0 20 20","aria-hidden":"true"},r.createElement("path",{d:"M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z",stroke:"currentColor",fill:"none",fillRule:"evenodd",strokeLinecap:"round",strokeLinejoin:"round"}))}},35947:(e,t,n)=>{"use strict";n.d(t,{A:()=>u});n(96540);var r=n(53259),o=n.n(r),s=n(84054);const a={"00935d0c":[()=>n.e(82487).then(n.bind(n,42254)),"@site/versioned_docs/version-2.0.0/users/csprlive/undelegate-ui.md",42254],"017e616b":[()=>n.e(93253).then(n.bind(n,37388)),"@site/versioned_docs/version-2.0.0/operators/setup-network/create-private.md",37388],"01a85c17":[()=>Promise.all([n.e(71869),n.e(8209)]).then(n.bind(n,69158)),"@theme/BlogTagsListPage",69158],"01be152e":[()=>n.e(94912).then(n.bind(n,27586)),"@site/versioned_docs/version-2.0.0/concepts/accounts-and-keys.md",27586],"01db17fe":[()=>n.e(9867).then(n.bind(n,69676)),"@site/versioned_docs/version-2.0.0/concepts/glossary/N.md",69676],"02627fb8":[()=>n.e(49900).then(n.bind(n,43934)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/factory-pattern.md",43934],"028247bf":[()=>n.e(53540).then(n.bind(n,71648)),"@site/versioned_docs/version-1.5.X/concepts/glossary/P.md",71648],"03aa8e23":[()=>n.e(93586).then(n.bind(n,94073)),"@site/docs/concepts/design/highway.md",94073],"03acd2fb":[()=>n.e(79378).then(n.bind(n,94903)),"@site/docs/operators/setup/install-node.md",94903],"03c6d9c7":[()=>n.e(34684).then(n.bind(n,33603)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-pos.md",33603],"044f7961":[()=>n.e(78114).then(n.bind(n,88914)),"@site/docs/developers/dapps/signing-a-transaction.md",88914],"04a0dcd6":[()=>n.e(11573).then(n.bind(n,94512)),"@site/versioned_docs/version-2.0.0/developers/prerequisites.md",94512],"04f8200d":[()=>n.e(30635).then(n.bind(n,48232)),"@site/versioned_docs/version-1.5.X/users/csprlive/undelegate-ui.md",48232],"051b98e7":[()=>n.e(47740).then(n.bind(n,32563)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/transfer.md",32563],"053d5d89":[()=>n.e(98953).then(n.bind(n,14764)),"@site/docs/developers/writing-onchain-code/upgrading-contracts.md",14764],"056155c0":[()=>n.e(12250).then(n.bind(n,91368)),"@site/versioned_docs/version-2.0.0/resources/advanced/index.md",91368],"05a3aa78":[()=>n.e(80885).then(n.bind(n,95773)),"@site/docs/resources/beginner/counter-testnet/commands.md",95773],"06c1e821":[()=>n.e(1381).then(n.bind(n,91015)),"@site/docs/developers/dapps/sdk/csharp-sdk.md",91015],"074e7bdc":[()=>n.e(62289).then(n.bind(n,29066)),"@site/docs/operators/maintenance/archiving-and-restoring.md",29066],"0753c93f":[()=>n.e(28579).then(n.bind(n,46963)),"@site/versioned_docs/version-1.5.X/developers/cli/opcode-costs.md",46963],"0791978c":[()=>n.e(52905).then(n.bind(n,22285)),"@site/versioned_docs/version-1.5.X/resources/advanced/cross-contract.md",22285],"08996e66":[()=>n.e(94426).then(n.bind(n,57450)),"@site/docs/developers/dapps/sdk/client-library-usage.md",57450],"08af526d":[()=>n.e(30529).then(n.t.bind(n,41344,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-3ce.json",41344],"0904ce24":[()=>n.e(85552).then(n.bind(n,18923)),"@site/versioned_docs/version-1.5.X/operators/index.md",18923],"09278318":[()=>n.e(503).then(n.bind(n,82395)),"@site/versioned_docs/version-2.0.0/developers/cli/verifying-contracts.md",82395],"094b4aff":[()=>n.e(76749).then(n.bind(n,80626)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/writing-session-code.md",80626],"0ac4e675":[()=>n.e(48562).then(n.bind(n,17451)),"@site/versioned_docs/version-1.5.X/developers/dapps/technology-stack.md",17451],"0ae07240":[()=>n.e(57366).then(n.bind(n,33153)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/recovering.md",33153],"0b20c33e":[()=>n.e(75941).then(n.bind(n,59560)),"@site/versioned_docs/version-2.0.0/developers/cli/execution-error-codes.md",59560],"0b3fc8e9":[()=>n.e(54041).then(n.bind(n,65357)),"@site/versioned_docs/version-2.0.0/concepts/index.md",65357],"0b8cc739":[()=>n.e(19356).then(n.bind(n,69833)),"@site/docs/developers/cli/installing-contracts.md",69833],"0bb2dbe9":[()=>n.e(38061).then(n.bind(n,84303)),"@site/docs/developers/writing-onchain-code/calling-contracts.md",84303],"0bd3b317":[()=>n.e(24643).then(n.bind(n,40975)),"@site/blog/2024-07-16-fee-elimination.md",40975],"0c098c15":[()=>n.e(45884).then(n.bind(n,82880)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/upgrading-contracts.md",82880],"0cde4ba3":[()=>n.e(97491).then(n.bind(n,8542)),"@site/docs/resources/tokens/index.md",8542],"0dea8207":[()=>n.e(72352).then(n.bind(n,48563)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/csharp-sdk.md",48563],"0fa7e001":[()=>n.e(1971).then(n.bind(n,21239)),"@site/versioned_docs/version-2.0.0/developers/dapps/prerequisites.md",21239],"106a38e1":[()=>n.e(8256).then(n.bind(n,82480)),"@site/versioned_docs/version-1.5.X/developers/cli/redelegate.md",82480],"106b67a5":[()=>n.e(50899).then(n.bind(n,65699)),"@site/docs/developers/writing-onchain-code/testing-contracts.md",65699],"10ab4195":[()=>n.e(98806).then(n.bind(n,97032)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/go-sdk.md",97032],"10dd5949":[()=>n.e(91415).then(n.bind(n,4785)),"@site/versioned_docs/version-2.0.0/concepts/list-auth-keys.md",4785],"116fa82a":[()=>n.e(13509).then(n.bind(n,85298)),"@site/docs/operators/setup-network/index.md",85298],"124873a8":[()=>n.e(57795).then(n.bind(n,39026)),"@site/blog/2024-07-17-addressable-entity.md",39026],"12984b65":[()=>n.e(90236).then(n.bind(n,92694)),"@site/versioned_docs/version-2.0.0/developers/cli/transfers/verify-transfer.md",92694],"12e95288":[()=>n.e(50889).then(n.bind(n,88738)),"@site/versioned_docs/version-1.5.X/concepts/glossary/N.md",88738],"130631d9":[()=>n.e(32748).then(n.bind(n,59869)),"@site/docs/concepts/glossary/W.md",59869],"134a9ec2":[()=>n.e(19635).then(n.bind(n,41392)),"@site/docs/concepts/key-types.md",41392],"13f7cbc7":[()=>n.e(27167).then(n.bind(n,43254)),"@site/versioned_docs/version-2.0.0/resources/casper-open-source-software.md",43254],"14620e15":[()=>n.e(82447).then(n.bind(n,12114)),"@site/docs/concepts/glossary/J.md",12114],"157e4bc2":[()=>n.e(93632).then(n.bind(n,84775)),"@site/docs/resources/tokens/cep78/using-casper-client.md",84775],"158765df":[()=>n.e(11595).then(n.bind(n,93194)),"@site/versioned_docs/version-2.0.0/users/ledger/ledger-live.md",93194],"15ce11b3":[()=>n.e(87746).then(n.bind(n,84209)),"@site/docs/resources/advanced/two-party-multi-sig.md",84209],"168da062":[()=>n.e(56365).then(n.bind(n,26962)),"@site/versioned_docs/version-1.5.X/operators/maintenance/moving-node.md",26962],"175e85c1":[()=>n.e(80724).then(n.bind(n,91335)),"@site/versioned_docs/version-2.0.0/users/csprlive/delegate-ui.md",91335],17896441:[()=>Promise.all([n.e(71869),n.e(79113),n.e(18401)]).then(n.bind(n,30575)),"@theme/DocItem",30575],"1871ac35":[()=>n.e(57356).then(n.bind(n,61594)),"@site/versioned_docs/version-1.5.X/resources/tokens/index.md",61594],"18b84202":[()=>n.e(53462).then(n.bind(n,30047)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/getting-started.md",30047],"1966dde1":[()=>n.e(65951).then(n.bind(n,89328)),"@site/versioned_docs/version-2.0.0/operators/maintenance/archiving-and-restoring.md",89328],"197196c4":[()=>n.e(59941).then(n.bind(n,37581)),"@site/blog/2024-07-16-setting-up-condor-local.md",37581],"19770ceb":[()=>n.e(61393).then(n.bind(n,7132)),"@site/docs/developers/writing-onchain-code/best-practices.md",7132],"19b85f8d":[()=>n.e(28114).then(n.bind(n,3273)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter/walkthrough.md",3273],"1a4e3797":[()=>Promise.all([n.e(71869),n.e(62138)]).then(n.bind(n,74604)),"@theme/SearchPage",74604],"1b0eecbc":[()=>n.e(80526).then(n.bind(n,62284)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-transactional.md",62284],"1b2f0a70":[()=>n.e(414).then(n.bind(n,77553)),"@site/docs/developers/json-rpc/minimal-compliance.md",77553],"1b312e15":[()=>n.e(44683).then(n.bind(n,84147)),"@site/versioned_docs/version-2.0.0/resources/beginner/getting-started-tutorial.md",84147],"1c694ffb":[()=>n.e(86898).then(n.bind(n,10289)),"@site/docs/developers/writing-onchain-code/assembly-script.md",10289],"1cd8ca26":[()=>n.e(94531).then(n.bind(n,18144)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-informational.md",18144],"1e144f6d":[()=>n.e(72702).then(n.bind(n,10816)),"@site/docs/resources/beginner/counter-testnet/overview.md",10816],"1e2c8091":[()=>n.e(2810).then(n.bind(n,32241)),"@site/versioned_docs/version-2.0.0/operators/setup/casper-sidecar.md",32241],"202767e6":[()=>n.e(34008).then(n.bind(n,5385)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_cl.md",5385],"2063472f":[()=>n.e(13215).then(n.t.bind(n,17646,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-18b.json",17646],"20e65df1":[()=>n.e(66476).then(n.bind(n,5143)),"@site/versioned_docs/version-2.0.0/users/ledger/ledger-setup.md",5143],"20f436ec":[()=>n.e(49392).then(n.bind(n,95578)),"@site/versioned_docs/version-1.5.X/developers/cli/undelegate.md",95578],"212aab5d":[()=>n.e(92709).then(n.bind(n,93522)),"@site/versioned_docs/version-1.5.X/developers/prerequisites.md",93522],"21ae0e7e":[()=>n.e(15819).then(n.bind(n,73177)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/staking.md",73177],"21d2c26c":[()=>n.e(74280).then(n.bind(n,1469)),"@site/versioned_docs/version-2.0.0/operators/maintenance/index.md",1469],"22dd74f7":[()=>n.e(11567).then(n.t.bind(n,55226,19)),"@generated/docusaurus-plugin-content-docs/default/p/index-466.json",55226],"236eb0f0":[()=>n.e(53101).then(n.bind(n,61055)),"@site/docs/resources/beginner/counter/walkthrough.md",61055],"23e022aa":[()=>n.e(29155).then(n.bind(n,62267)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/errors.md",62267],"241648bf":[()=>n.e(26220).then(n.bind(n,1202)),"@site/versioned_docs/version-1.5.X/developers/cli/execution-error-codes.md",1202],"241f36ed":[()=>n.e(24972).then(n.bind(n,34394)),"@site/versioned_docs/version-2.0.0/concepts/serialization/primitives.md",34394],"24433f15":[()=>n.e(25959).then(n.bind(n,57698)),"@site/versioned_docs/version-2.0.0/resources/advanced/transfer-token-to-contract.md",57698],"25f19435":[()=>n.e(88344).then(n.bind(n,82432)),"@site/docs/concepts/global-state.md",82432],"261dbd4a":[()=>n.e(79899).then(n.bind(n,38123)),"@site/docs/developers/writing-onchain-code/emitting-contract-events.md",38123],"2668f34f":[()=>n.e(31458).then(n.bind(n,93517)),"@site/docs/users/ledger/ledger-setup.md",93517],"26a33332":[()=>n.e(94998).then(n.bind(n,33219)),"@site/versioned_docs/version-1.5.X/resources/advanced/list-auth-keys-tutorial.md",33219],"26ab9a7a":[()=>n.e(3568).then(n.bind(n,93511)),"@site/versioned_docs/version-2.0.0/concepts/design/consensus.md",93511],"26f7e8fd":[()=>n.e(84891).then(n.bind(n,85947)),"@site/versioned_docs/version-1.5.X/concepts/design/casper-design.md",85947],"277b6be0":[()=>n.e(24054).then(n.bind(n,96738)),"@site/blog/2024-08-20-validator-rewards.md",96738],"280f0f40":[()=>n.e(42081).then(n.bind(n,237)),"@site/versioned_docs/version-2.0.0/users/block-explorer.md",237],"285c66e7":[()=>n.e(71049).then(n.bind(n,4110)),"@site/versioned_docs/version-2.0.0/developers/cli/index.md",4110],"28b5b925":[()=>n.e(81818).then(n.bind(n,95038)),"@site/docs/resources/tokens/cep18/full-tutorial.md",95038],"28bc9864":[()=>n.e(5069).then(n.bind(n,1697)),"@site/docs/operators/becoming-a-validator/unbonding.md",1697],"2a21571b":[()=>n.e(2306).then(n.bind(n,57011)),"@site/versioned_docs/version-2.0.0/operators/setup/joining.md",57011],"2ac03470":[()=>n.e(27941).then(n.bind(n,22426)),"@site/versioned_docs/version-2.0.0/resources/moving-to-casper.md",22426],"2b8e251b":[()=>n.e(31180).then(n.bind(n,6994)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/full-tutorial.md",6994],"2bd0ed90":[()=>n.e(36595).then(n.bind(n,95239)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Q.md",95239],"2c04116d":[()=>n.e(37802).then(n.bind(n,54575)),"@site/versioned_docs/version-1.5.X/resources/index.md",54575],"2c27a7b4":[()=>n.e(64805).then(n.bind(n,35224)),"@site/docs/resources/moving-to-casper.md",35224],"2cb8ed3d":[()=>n.e(18794).then(n.bind(n,35946)),"@site/docs/concepts/glossary/R.md",35946],"2cc4f81c":[()=>n.e(91741).then(n.bind(n,69319)),"@site/versioned_docs/version-1.5.X/concepts/hash-types.md",69319],"2d971abe":[()=>n.e(5768).then(n.bind(n,35040)),"@site/docs/developers/dapps/nctl-test.md",35040],"2e4bdb60":[()=>n.e(74586).then(n.bind(n,476)),"@site/docs/concepts/glossary/index.md",476],"2fb5589e":[()=>n.e(73213).then(n.bind(n,91376)),"@site/docs/resources/advanced/multi-sig/index.md",91376],"2fe2b30f":[()=>n.e(61109).then(n.bind(n,62121)),"@site/versioned_docs/version-2.0.0/concepts/glossary/M.md",62121],"2ffce966":[()=>n.e(66552).then(n.bind(n,25255)),"@site/docs/developers/cli/transfers/index.md",25255],"31722bc4":[()=>n.e(91961).then(n.bind(n,45539)),"@site/docs/operators/setup/casper-sidecar.md",45539],"31dbaea7":[()=>n.e(77675).then(n.bind(n,87669)),"@site/versioned_docs/version-1.5.X/concepts/glossary/K.md",87669],"31e8518f":[()=>n.e(62604).then(n.bind(n,21905)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/testing-contracts.md",21905],"32dd135c":[()=>n.e(49540).then(n.bind(n,29683)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/modalities.md",29683],"331badc5":[()=>n.e(4707).then(n.bind(n,39824)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-live.md",39824],"3362155c":[()=>n.e(34635).then(n.bind(n,20633)),"@site/versioned_docs/version-1.5.X/developers/dapps/monitor-and-consume-events.md",20633],"33a9c3bd":[()=>n.e(38631).then(n.t.bind(n,48018,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-hello-f4b.json",48018],"33fc5bb8":[()=>Promise.all([n.e(71869),n.e(79113),n.e(3347),n.e(50867)]).then(n.bind(n,30778)),"@theme/Blog/Pages/BlogAuthorsPostsPage",30778],"340c2365":[()=>n.e(11187).then(n.bind(n,62651)),"@site/versioned_docs/version-1.5.X/operators/setup/install-node.md",62651],"34b086e1":[()=>n.e(50140).then(n.bind(n,98733)),"@site/versioned_docs/version-1.5.X/concepts/economics/consensus.md",98733],"35808b61":[()=>n.e(2714).then(n.bind(n,30347)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/script-sdk.md",30347],"358cf6da":[()=>n.e(46109).then(n.t.bind(n,13275,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-sczembor-c4b.json",13275],"35a4f7b3":[()=>n.e(70956).then(n.bind(n,87675)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/index.md",87675],"3619739c":[()=>n.e(10124).then(n.bind(n,97409)),"@site/docs/concepts/economics/runtime.md",97409],"362368d5":[()=>n.e(58190).then(n.bind(n,60940)),"@site/docs/concepts/glossary/P.md",60940],"3669623c":[()=>n.e(58061).then(n.bind(n,68329)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-setup.md",68329],"36994c47":[()=>n.e(89858).then(n.t.bind(n,45516,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",45516],"3724f9ed":[()=>n.e(15255).then(n.bind(n,58592)),"@site/docs/developers/writing-onchain-code/writing-session-code.md",58592],"372c0574":[()=>n.e(11208).then(n.bind(n,11044)),"@site/versioned_docs/version-2.0.0/developers/cli/calling-contracts.md",11044],"381391cb":[()=>n.e(36139).then(n.bind(n,35170)),"@site/docs/resources/advanced/index.md",35170],38296185:[()=>n.e(22743).then(n.bind(n,42311)),"@site/docs/concepts/glossary/E.md",42311],"387aabc2":[()=>n.e(67880).then(n.bind(n,24651)),"@site/versioned_docs/version-2.0.0/users/csprlive/index.md",24651],"38b4dbd3":[()=>n.e(72033).then(n.bind(n,99648)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/delegation.md",99648],"38ff73e5":[()=>n.e(65438).then(n.bind(n,99793)),"@site/versioned_docs/version-2.0.0/concepts/glossary/U.md",99793],"396a697c":[()=>n.e(25005).then(n.bind(n,48949)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/modalities.md",48949],"398cf21c":[()=>n.e(57320).then(n.bind(n,68259)),"@site/docs/concepts/list-auth-keys.md",68259],"39ac5a41":[()=>n.e(8016).then(n.bind(n,55847)),"@site/versioned_docs/version-1.5.X/concepts/callstack.md",55847],"3a19cb34":[()=>n.e(3155).then(n.bind(n,86767)),"@site/versioned_docs/version-2.0.0/concepts/glossary/C.md",86767],"3a5d5492":[()=>n.e(75418).then(n.bind(n,63944)),"@site/docs/resources/tokens/cep78/introduction.md",63944],"3a98aaad":[()=>n.e(28801).then(n.bind(n,56901)),"@site/versioned_docs/version-2.0.0/operators/index.md",56901],"3a9d2720":[()=>n.e(23127).then(n.bind(n,52886)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/inactive-vs-faulty.md",52886],"3aa29420":[()=>n.e(81515).then(n.bind(n,28510)),"@site/versioned_docs/version-1.5.X/concepts/glossary/B.md",28510],"3aaf2bfb":[()=>n.e(30666).then(n.bind(n,76599)),"@site/docs/developers/json-rpc/errors.md",76599],"3ac85609":[()=>n.e(28626).then(n.bind(n,42429)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/index.md",42429],"3b749ca6":[()=>n.e(6708).then(n.bind(n,69261)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/tests.md",69261],"3b86d751":[()=>n.e(6815).then(n.bind(n,25023)),"@site/versioned_docs/version-1.5.X/operators/maintenance/index.md",25023],"3bf1ce3c":[()=>n.e(52349).then(n.bind(n,86344)),"@site/docs/developers/cli/transfers/verify-transfer.md",86344],"3c9a8a22":[()=>n.e(32154).then(n.bind(n,24708)),"@site/versioned_docs/version-2.0.0/concepts/economics/index.md",24708],"3ce1a06b":[()=>n.e(97816).then(n.bind(n,70151)),"@site/versioned_docs/version-1.5.X/developers/dapps/speculative-exec.md",70151],"3d262e04":[()=>n.e(49105).then(n.bind(n,62672)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/client-library-usage.md",62672],"3d90f760":[()=>n.e(70186).then(n.bind(n,94150)),"@site/versioned_docs/version-1.5.X/disclaimer.md",94150],"3d9ade7d":[()=>n.e(83184).then(n.bind(n,57155)),"@site/versioned_docs/version-2.0.0/developers/cli/delegate.md",57155],"3db2ed27":[()=>n.e(712).then(n.bind(n,26761)),"@site/versioned_docs/version-2.0.0/operators/setup-network/staging-files-for-new-network.md",26761],"3e796ac9":[()=>n.e(15680).then(n.bind(n,98619)),"@site/docs/concepts/addressable-entity.md",98619],"3efe71e8":[()=>n.e(87559).then(n.bind(n,63768)),"@site/docs/concepts/glossary/L.md",63768],"3fe76c6c":[()=>n.e(59672).then(n.bind(n,19259)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/walkthrough.md",19259],40078125:[()=>n.e(36194).then(n.bind(n,69403)),"@site/versioned_docs/version-1.5.X/operators/setup-network/chain-spec.md",69403],"40c07125":[()=>n.e(63485).then(n.bind(n,40232)),"@site/versioned_docs/version-1.5.X/concepts/accounts-and-keys.md",40232],"411a45a4":[()=>n.e(27686).then(n.bind(n,28312)),"@site/versioned_docs/version-2.0.0/resources/tokens/index.md",28312],"41905acb":[()=>n.e(93920).then(n.bind(n,88694)),"@site/versioned_docs/version-1.5.X/users/csprlive/token-transfer.md",88694],"41e7d56e":[()=>n.e(64932).then(n.bind(n,40529)),"@site/docs/concepts/glossary/K.md",40529],"41eb5a6a":[()=>n.e(5650).then(n.bind(n,78593)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/commands.md",78593],42744730:[()=>n.e(12478).then(n.bind(n,37100)),"@site/versioned_docs/version-2.0.0/concepts/transactions-and-transaction-lifecycle.md",37100],"433fdaab":[()=>n.e(78263).then(n.bind(n,41258)),"@site/versioned_docs/version-2.0.0/developers/cli/transfers/direct-token-transfer.md",41258],"43a834ef":[()=>n.e(1991).then(n.bind(n,48596)),"@site/versioned_docs/version-1.5.X/resources/moving-to-casper.md",48596],"43fd3112":[()=>n.e(34191).then(n.bind(n,41699)),"@site/versioned_docs/version-1.5.X/concepts/glossary/E.md",41699],"4423d65b":[()=>n.e(17201).then(n.bind(n,15944)),"@site/versioned_docs/version-1.5.X/concepts/glossary/H.md",15944],"449bc0d9":[()=>n.e(32686).then(n.bind(n,34406)),"@site/docs/users/index.md",34406],"452e65d7":[()=>n.e(89109).then(n.bind(n,30383)),"@site/docs/developers/cli/opcode-costs.md",30383],"4545390c":[()=>n.e(82720).then(n.bind(n,20688)),"@site/docs/concepts/glossary/T.md",20688],"459c4db6":[()=>n.e(15338).then(n.bind(n,11878)),"@site/docs/developers/cli/execution-error-codes.md",11878],46206018:[()=>n.e(46198).then(n.bind(n,85102)),"@site/versioned_docs/version-2.0.0/users/delegating.md",85102],"46c04ff3":[()=>n.e(23919).then(n.bind(n,55737)),"@site/docs/resources/advanced/cross-contract.md",55737],"46e94768":[()=>n.e(72646).then(n.bind(n,25120)),"@site/docs/developers/cli/index.md",25120],"471ca6e4":[()=>n.e(87174).then(n.bind(n,78139)),"@site/docs/concepts/economics/staking.md",78139],"4732c0e2":[()=>n.e(23963).then(n.bind(n,59073)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/index.md",59073],"473a077c":[()=>n.e(24281).then(n.bind(n,58376)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/contract-vs-session.md",58376],"4804492c":[()=>n.e(87375).then(n.bind(n,43894)),"@site/versioned_docs/version-1.5.X/concepts/glossary/J.md",43894],"480fa8f7":[()=>n.e(87903).then(n.bind(n,69029)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/minimal-compliance.md",69029],"481163ce":[()=>n.e(93552).then(n.t.bind(n,22999,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-new-docs-5aa.json",22999],"4832c6fe":[()=>n.e(29408).then(n.bind(n,50929)),"@site/versioned_docs/version-1.5.X/users/ledger/staking-ledger.md",50929],"4a522ab0":[()=>n.e(9950).then(n.bind(n,63369)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/using-casper-client.md",63369],"4ab63648":[()=>n.e(31973).then(n.bind(n,87630)),"@site/versioned_docs/version-1.5.X/concepts/glossary/R.md",87630],"4ba3ceff":[()=>n.e(69457).then(n.bind(n,36921)),"@site/docs/resources/beginner/getting-started-tutorial.md",36921],"4bf77031":[()=>n.e(92805).then(n.bind(n,86151)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/walkthrough.md",86151],"4c91363f":[()=>n.e(74374).then(n.bind(n,92383)),"@site/docs/resources/tokens/cep78/reverse-lookup.md",92383],"4cc44e19":[()=>n.e(73030).then(n.bind(n,19066)),"@site/versioned_docs/version-2.0.0/concepts/global-state.md",19066],"4cc75cd6":[()=>n.e(13580).then(n.bind(n,98924)),"@site/versioned_docs/version-1.5.X/developers/cli/querying-global-state.md",98924],"4d118a4e":[()=>n.e(18621).then(n.bind(n,33041)),"@site/docs/developers/cli/delegate.md",33041],"4d355c12":[()=>n.e(49546).then(n.bind(n,33580)),"@site/versioned_docs/version-2.0.0/developers/cli/undelegate.md",33580],"4d4c05c4":[()=>n.e(46928).then(n.bind(n,90719)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/index.md",90719],"4db682c6":[()=>n.e(3766).then(n.bind(n,86243)),"@site/docs/concepts/callstack.md",86243],"4e015808":[()=>n.e(95712).then(n.bind(n,90710)),"@site/versioned_docs/version-1.5.X/resources/quick-start.md",90710],"4e4df367":[()=>n.e(11894).then(n.bind(n,74299)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/recovering.md",74299],"4e8b7bcc":[()=>n.e(93469).then(n.bind(n,28010)),"@site/versioned_docs/version-1.5.X/concepts/glossary/F.md",28010],"4ed7ac06":[()=>n.e(82399).then(n.bind(n,49208)),"@site/versioned_docs/version-2.0.0/concepts/glossary/R.md",49208],"4fdb6df3":[()=>n.e(55844).then(n.bind(n,15366)),"@site/docs/concepts/glossary/N.md",15366],"5052751d":[()=>n.e(96590).then(n.bind(n,9184)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/bonding.md",9184],"50c21d96":[()=>n.e(40145).then(n.bind(n,13358)),"@site/versioned_docs/version-2.0.0/concepts/glossary/X.md",13358],"5109d3ad":[()=>n.e(6224).then(n.bind(n,1222)),"@site/versioned_docs/version-1.5.X/operators/setup-network/create-private.md",1222],"5168ee15":[()=>n.e(30471).then(n.bind(n,59781)),"@site/versioned_docs/version-2.0.0/concepts/glossary/Q.md",59781],"51719dea":[()=>n.e(76444).then(n.bind(n,9431)),"@site/docs/developers/dapps/dapp.md",9431],"51ce653c":[()=>n.e(32072).then(n.bind(n,18801)),"@site/docs/developers/writing-onchain-code/index.md",18801],"521a6610":[()=>n.e(73027).then(n.bind(n,38764)),"@site/versioned_docs/version-1.5.X/developers/cli/index.md",38764],"52927c97":[()=>n.e(64917).then(n.bind(n,1028)),"@site/versioned_docs/version-2.0.0/concepts/glossary/F.md",1028],"52ab49a5":[()=>n.e(85240).then(n.bind(n,76164)),"@site/versioned_docs/version-2.0.0/concepts/transactions.md",76164],"52fa5650":[()=>n.e(92275).then(n.bind(n,64954)),"@site/versioned_docs/version-1.5.X/concepts/glossary/V.md",64954],"533ebf6b":[()=>n.e(73931).then(n.bind(n,56193)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs.md",56193],"5364a150":[()=>n.e(92152).then(n.bind(n,31487)),"@site/versioned_docs/version-1.5.X/developers/dapps/signing-a-deploy.md",31487],"53d095ec":[()=>n.e(48425).then(n.bind(n,91722)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-vs-session.md",91722],"53dc618d":[()=>n.e(10419).then(n.bind(n,3317)),"@site/versioned_docs/version-2.0.0/operators/setup/install-node.md",3317],"546b5549":[()=>n.e(91651).then(n.bind(n,76419)),"@site/docs/resources/beginner/cep18.md",76419],"5496fb16":[()=>n.e(39468).then(n.bind(n,96588)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/index.md",96588],"5497691c":[()=>n.e(24035).then(n.bind(n,48025)),"@site/docs/developers/writing-onchain-code/getting-started.md",48025],"54fcde43":[()=>n.e(6107).then(n.bind(n,56994)),"@site/versioned_docs/version-2.0.0/concepts/glossary/D.md",56994],55568807:[()=>n.e(77543).then(n.bind(n,71870)),"@site/versioned_docs/version-1.5.X/developers/essential-crates.md",71870],"555a4473":[()=>n.e(29861).then(n.bind(n,45493)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/getting-started.md",45493],"559dc838":[()=>n.e(94686).then(n.bind(n,67092)),"@site/versioned_docs/version-2.0.0/concepts/glossary/V.md",67092],"560adf9d":[()=>n.e(81574).then(n.bind(n,41711)),"@site/docs/resources/beginner/counter/commands.md",41711],"5611a8f0":[()=>n.e(98069).then(n.bind(n,39981)),"@site/versioned_docs/version-2.0.0/concepts/glossary/Y.md",39981],"56746dcb":[()=>n.e(80690).then(n.bind(n,29010)),"@site/versioned_docs/version-1.5.X/concepts/economics/runtime.md",29010],"56aa8058":[()=>n.e(63055).then(n.bind(n,63784)),"@site/versioned_docs/version-2.0.0/concepts/intro-to-dapps.md",63784],"56ad65de":[()=>n.e(23471).then(n.bind(n,98132)),"@site/docs/concepts/serialization/structures.md",98132],"56fae639":[()=>n.e(67920).then(n.bind(n,41982)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/overview.md",41982],"56ffdb25":[()=>n.e(45647).then(n.bind(n,4944)),"@site/versioned_docs/version-2.0.0/resources/beginner/index.md",4944],"576e11bb":[()=>n.e(71914).then(n.bind(n,67472)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/full-tutorial.md",67472],"57d593f0":[()=>n.e(25120).then(n.bind(n,90459)),"@site/versioned_docs/version-2.0.0/concepts/design/highway.md",90459],"57f923a9":[()=>n.e(83627).then(n.bind(n,46896)),"@site/versioned_docs/version-1.5.X/resources/beginner/aws-node.md",46896],"58092c27":[()=>n.e(82697).then(n.bind(n,81832)),"@site/docs/concepts/smart-contracts.md",81832],58718032:[()=>n.e(52071).then(n.bind(n,63785)),"@site/versioned_docs/version-1.5.X/concepts/glossary/G.md",63785],"5979a0ec":[()=>n.e(93226).then(n.bind(n,5513)),"@site/docs/users/ledger/ledger-cspr-live.md",5513],"59b77803":[()=>n.e(34346).then(n.bind(n,8368)),"@site/versioned_docs/version-2.0.0/users/ledger/index.md",8368],"5a22b142":[()=>n.e(69940).then(n.bind(n,47609)),"@site/docs/users/csprlive/delegate-ui.md",47609],"5a3b84ba":[()=>n.e(65409).then(n.bind(n,47398)),"@site/docs/developers/json-rpc/index.md",47398],"5a6ba1cd":[()=>n.e(60570).then(n.bind(n,24029)),"@site/versioned_docs/version-2.0.0/operators/setup/fast-sync.md",24029],"5b38c543":[()=>n.e(19744).then(n.bind(n,95284)),"@site/versioned_docs/version-2.0.0/developers/cli/sending-transactions.md",95284],"5b827590":[()=>n.e(57371).then(n.bind(n,33143)),"@site/versioned_docs/version-1.5.X/users/block-explorer.md",33143],"5c07109c":[()=>n.e(98183).then(n.bind(n,70843)),"@site/versioned_docs/version-1.5.X/operators/setup/basic-node-configuration.md",70843],"5c08a95a":[()=>n.e(54635).then(n.bind(n,47051)),"@site/versioned_docs/version-2.0.0/resources/quick-start.md",47051],"5c3f78ae":[()=>n.e(40871).then(n.bind(n,39911)),"@site/versioned_docs/version-1.5.X/developers/dapps/template-frontend.md",39911],"5ce0f216":[()=>n.e(52321).then(n.t.bind(n,36433,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-features-efe.json",36433],"5cf40dea":[()=>n.e(27927).then(n.bind(n,47994)),"@site/docs/concepts/intro-to-dapps.md",47994],"5d4e9672":[()=>n.e(65059).then(n.bind(n,41788)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/introduction.md",41788],"5db8b942":[()=>n.e(14235).then(n.bind(n,75995)),"@site/versioned_docs/version-2.0.0/concepts/glossary/G.md",75995],"5e5b712e":[()=>n.e(25235).then(n.bind(n,83779)),"@site/versioned_docs/version-2.0.0/concepts/glossary/O.md",83779],"5e9306ee":[()=>n.e(59029).then(n.bind(n,70580)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/verify-transfer.md",70580],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5eb62c95":[()=>n.e(35774).then(n.bind(n,47294)),"@site/versioned_docs/version-2.0.0/concepts/glossary/H.md",47294],"5ed91ab5":[()=>n.e(53337).then(n.bind(n,65483)),"@site/docs/concepts/glossary/I.md",65483],"5f02ec4e":[()=>n.e(57753).then(n.bind(n,4879)),"@site/docs/operators/index.md",4879],"5f241059":[()=>n.e(18193).then(n.bind(n,97005)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/script-sdk.md",97005],"603aca9e":[()=>n.e(12059).then(n.bind(n,2839)),"@site/versioned_docs/version-1.5.X/concepts/glossary/A.md",2839],"6043c3f4":[()=>n.e(46046).then(n.bind(n,38513)),"@site/versioned_docs/version-1.5.X/resources/advanced/storage-workflow.md",38513],"60d3a705":[()=>n.e(43979).then(n.bind(n,57921)),"@site/docs/developers/json-rpc/types_chain.md",57921],"60fa9972":[()=>n.e(56215).then(n.bind(n,44881)),"@site/versioned_docs/version-1.5.X/resources/advanced/list-cspr.md",44881],"61415b83":[()=>n.e(70687).then(n.bind(n,12099)),"@site/versioned_docs/version-2.0.0/concepts/serialization/types.md",12099],"6193b30e":[()=>n.e(96232).then(n.bind(n,52850)),"@site/docs/resources/tokens/cep18/quickstart-guide.md",52850],"621db11d":[()=>Promise.all([n.e(71869),n.e(3347),n.e(64212)]).then(n.bind(n,13250)),"@theme/Blog/Pages/BlogAuthorsListPage",13250],"6245c126":[()=>n.e(96342).then(n.bind(n,85916)),"@site/versioned_docs/version-1.5.X/concepts/glossary/T.md",85916],"62569fa7":[()=>n.e(17287).then(n.bind(n,59213)),"@site/versioned_docs/version-2.0.0/users/csprlive/testnet-faucet.md",59213],"6318ac72":[()=>n.e(39238).then(n.bind(n,34198)),"@site/docs/concepts/design/rewards.md",34198],"631bdc93":[()=>n.e(38656).then(n.bind(n,2781)),"@site/versioned_docs/version-2.0.0/concepts/glossary/I.md",2781],"63925da8":[()=>n.e(16871).then(n.bind(n,93061)),"@site/docs/developers/index.md",93061],"63d4ce07":[()=>n.e(21261).then(n.bind(n,64740)),"@site/docs/developers/cli/redelegate.md",64740],"64733a41":[()=>n.e(87914).then(n.bind(n,79985)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter/commands.md",79985],"6474e148":[()=>n.e(39126).then(n.bind(n,79375)),"@site/versioned_docs/version-1.5.X/concepts/glossary/I.md",79375],"64899cf9":[()=>n.e(16087).then(n.bind(n,97329)),"@site/docs/concepts/serialization/types.md",97329],"64959b1e":[()=>n.e(67796).then(n.bind(n,16527)),"@site/docs/concepts/design/casper-design.md",16527],"64bdcaf3":[()=>n.e(1130).then(n.bind(n,84549)),"@site/versioned_docs/version-2.0.0/operators/setup/open-files.md",84549],"64c09e2e":[()=>n.e(33697).then(n.bind(n,73571)),"@site/docs/operators/maintenance/index.md",73571],"650a8fc0":[()=>n.e(63894).then(n.bind(n,86943)),"@site/docs/concepts/glossary/M.md",86943],"6520db96":[()=>n.e(19025).then(n.bind(n,15820)),"@site/docs/developers/writing-onchain-code/factory-pattern.md",15820],"65961da4":[()=>n.e(94889).then(n.bind(n,1051)),"@site/docs/concepts/design/networking-protocol.md",1051],"65a9ed9e":[()=>n.e(5731).then(n.bind(n,92439)),"@site/docs/concepts/glossary/U.md",92439],"65cd111b":[()=>n.e(10910).then(n.bind(n,1879)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-contracts.md",1879],"680b7fa9":[()=>n.e(32446).then(n.bind(n,22210)),"@site/docs/developers/essential-crates.md",22210],68730730:[()=>n.e(8113).then(n.bind(n,85311)),"@site/versioned_docs/version-2.0.0/operators/setup/hardware.md",85311],"6875c492":[()=>Promise.all([n.e(71869),n.e(79113),n.e(3347),n.e(84813)]).then(n.bind(n,33069)),"@theme/BlogTagsPostsPage",33069],"68ccb7f6":[()=>n.e(56474).then(n.bind(n,88599)),"@site/docs/operators/setup/open-files.md",88599],"6a307077":[()=>n.e(84110).then(n.bind(n,88261)),"@site/docs/developers/json-rpc/types_cl.md",88261],"6bed00f2":[()=>n.e(37832).then(n.bind(n,59694)),"@site/versioned_docs/version-2.0.0/concepts/design/zug.md",59694],"6c606038":[()=>n.e(98471).then(n.bind(n,87251)),"@site/docs/concepts/glossary/A.md",87251],"6ceb2263":[()=>n.e(65710).then(n.bind(n,56414)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-transactional.md",56414],"6dcb5e16":[()=>n.e(4005).then(n.bind(n,14062)),"@site/docs/concepts/economics/fee-elimination.md",14062],"6e2737c0":[()=>n.e(76958).then(n.bind(n,16484)),"@site/docs/developers/writing-onchain-code/contract-hash-vs-package-hash.md",16484],"6e34a484":[()=>n.e(4814).then(n.bind(n,64930)),"@site/docs/developers/cli/sending-transactions.md",64930],"6fe126b9":[()=>n.e(98950).then(n.bind(n,82244)),"@site/versioned_docs/version-1.5.X/concepts/glossary/L.md",82244],"705e93ef":[()=>n.e(28729).then(n.bind(n,52314)),"@site/versioned_docs/version-1.5.X/developers/dapps/index.md",52314],"709dfa47":[()=>n.e(83297).then(n.bind(n,34238)),"@site/versioned_docs/version-1.5.X/resources/build-on-casper.md",34238],"72106d8f":[()=>n.e(7283).then(n.t.bind(n,43937,19)),"@generated/docusaurus-plugin-content-docs/default/p/2-0-0-6e2.json",43937],"727f767d":[()=>n.e(85833).then(n.bind(n,70827)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/calling-contracts.md",70827],"72a89de8":[()=>n.e(75687).then(n.bind(n,65693)),"@site/versioned_docs/version-1.5.X/users/csprlive/delegate-ui.md",65693],"72b43be8":[()=>n.e(6770).then(n.bind(n,68966)),"@site/versioned_docs/version-1.5.X/resources/beginner/index.md",68966],"72c6e609":[()=>n.e(22107).then(n.bind(n,56341)),"@site/versioned_docs/version-1.5.X/operators/setup/upgrade.md",56341],"72cc2261":[()=>n.e(73793).then(n.bind(n,7753)),"@site/versioned_docs/version-1.5.X/resources/beginner/upgrade-contract.md",7753],"7366a28d":[()=>n.e(73820).then(n.bind(n,67297)),"@site/versioned_docs/version-2.0.0/concepts/callstack.md",67297],"738a6ad4":[()=>n.e(28727).then(n.bind(n,78009)),"@site/versioned_docs/version-1.5.X/operators/setup/joining.md",78009],"74d57d33":[()=>n.e(60200).then(n.bind(n,92827)),"@site/docs/users/funding-from-exchanges.md",92827],"753d7b98":[()=>n.e(1790).then(n.bind(n,440)),"@site/docs/developers/json-rpc/json-rpc-transactional.md",440],"75de5623":[()=>n.e(32670).then(n.bind(n,82799)),"@site/versioned_docs/version-1.5.X/users/funding-from-exchanges.md",82799],"7607f1d5":[()=>n.e(40793).then(n.bind(n,27843)),"@site/docs/developers/dapps/template-frontend.md",27843],"76839fc0":[()=>n.e(84259).then(n.bind(n,12525)),"@site/versioned_docs/version-2.0.0/concepts/economics/staking.md",12525],"76a75fbd":[()=>n.e(37667).then(n.bind(n,34868)),"@site/docs/users/csprlive/undelegate-ui.md",34868],"76ea157b":[()=>n.e(1867).then(n.bind(n,30599)),"@site/versioned_docs/version-2.0.0/users/ledger/ledger-cspr-live.md",30599],"7708241d":[()=>n.e(58728).then(n.bind(n,62157)),"@site/docs/resources/beginner/upgrade-contract.md",62157],"772d3db3":[()=>n.e(94491).then(n.bind(n,95631)),"@site/versioned_docs/version-1.5.X/operators/setup-network/staging-files-for-new-network.md",95631],"77395f9a":[()=>n.e(60710).then(n.bind(n,89249)),"@site/versioned_docs/version-2.0.0/concepts/design/casper-design.md",89249],"77981a3a":[()=>n.e(67440).then(n.bind(n,46453)),"@site/versioned_docs/version-1.5.X/resources/beginner/getting-started-tutorial.md",46453],"77c92c8c":[()=>n.e(59387).then(n.bind(n,63469)),"@site/versioned_docs/version-2.0.0/resources/index.md",63469],"7850177d":[()=>n.e(88668).then(n.bind(n,74219)),"@site/versioned_docs/version-2.0.0/concepts/glossary/W.md",74219],"78c66fad":[()=>n.e(39902).then(n.bind(n,4690)),"@site/docs/operators/becoming-a-validator/inactive-vs-faulty.md",4690],"79474bae":[()=>n.e(5296).then(n.bind(n,60507)),"@site/versioned_docs/version-1.5.X/operators/setup/non-root-user.md",60507],"79d896a3":[()=>n.e(48426).then(n.bind(n,70525)),"@site/docs/concepts/economics/gas-concepts.md",70525],"7ade0b2a":[()=>n.e(76163).then(n.bind(n,13868)),"@site/versioned_docs/version-1.5.X/concepts/glossary/D.md",13868],"7b1c3c68":[()=>n.e(88652).then(n.bind(n,42903)),"@site/docs/developers/json-rpc/json-rpc-pos.md",42903],"7b8da7d8":[()=>n.e(13e3).then(n.bind(n,6188)),"@site/docs/resources/beginner/aws-node.md",6188],"7bf3b0fc":[()=>n.e(94338).then(n.bind(n,72241)),"@site/versioned_docs/version-2.0.0/concepts/addressable-entity.md",72241],"7c67ea25":[()=>n.e(97937).then(n.bind(n,62301)),"@site/versioned_docs/version-1.5.X/developers/cli/installing-contracts.md",62301],"7c798d59":[()=>n.e(91535).then(n.bind(n,51753)),"@site/docs/developers/cli/transfers/multisig-deploy-transfer.md",51753],"7ce4a62a":[()=>n.e(76568).then(n.bind(n,83277)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/assembly-script.md",83277],"7ce91694":[()=>n.e(51721).then(n.bind(n,13923)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/unbonding.md",13923],"7cf62e8d":[()=>n.e(566).then(n.bind(n,54814)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/guidance.md",54814],"7cff47a5":[()=>n.e(48916).then(n.bind(n,93507)),"@site/docs/developers/dapps/speculative-exec.md",93507],"7e55f6e6":[()=>n.e(72028).then(n.bind(n,60588)),"@site/versioned_docs/version-1.5.X/concepts/smart-contracts.md",60588],"7effaf45":[()=>n.e(15087).then(n.bind(n,58347)),"@site/versioned_docs/version-1.5.X/concepts/economics/staking/concepts.md",58347],"7f115b1f":[()=>n.e(64358).then(n.bind(n,59460)),"@site/docs/developers/writing-onchain-code/testing-session-code.md",59460],"7feecbc1":[()=>n.e(95773).then(n.bind(n,57440)),"@site/versioned_docs/version-2.0.0/concepts/about.md",57440],"80510dbd":[()=>n.e(95283).then(n.bind(n,51871)),"@site/versioned_docs/version-2.0.0/resources/advanced/list-cspr.md",51871],"80e6044e":[()=>n.e(87915).then(n.bind(n,25377)),"@site/blog/2024-07-16-fee-elimination.md?truncated=true",25377],"814e64cc":[()=>n.e(24439).then(n.bind(n,92683)),"@site/versioned_docs/version-2.0.0/users/ledger/staking-ledger.md",92683],"814f3328":[()=>n.e(67472).then(n.t.bind(n,55513,19)),"~blog/default/blog-post-list-prop-default.json",55513],"8154f86c":[()=>n.e(94490).then(n.bind(n,63137)),"@site/versioned_docs/version-2.0.0/operators/setup/basic-node-configuration.md",63137],"821dc1e3":[()=>n.e(30898).then(n.bind(n,56752)),"@site/versioned_docs/version-1.5.X/resources/advanced/transfer-token-to-contract.md",56752],"830e9e14":[()=>n.e(55732).then(n.bind(n,17703)),"@site/docs/operators/setup/node-events.md",17703],"8323e0f5":[()=>n.e(69749).then(n.bind(n,30491)),"@site/docs/resources/beginner/querying-network.md",30491],"85b8bb26":[()=>n.e(75096).then(n.bind(n,29387)),"@site/docs/concepts/dictionaries.md",29387],"861e5e13":[()=>n.e(27837).then(n.bind(n,32858)),"@site/docs/resources/build-on-casper.md",32858],"862f9df3":[()=>n.e(2119).then(n.bind(n,97568)),"@site/versioned_docs/version-2.0.0/developers/dapps/signing-a-transaction.md",97568],"8675f5af":[()=>n.e(24907).then(n.bind(n,93911)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/tests.md",93911],"86ae953a":[()=>n.e(60173).then(n.bind(n,28874)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/best-practices.md",28874],"86b0038a":[()=>n.e(51625).then(n.bind(n,16232)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/simple-contract.md",16232],"870de909":[()=>n.e(96755).then(n.bind(n,91820)),"@site/docs/users/delegating.md",91820],"871da383":[()=>n.e(50620).then(n.bind(n,74871)),"@site/versioned_docs/version-2.0.0/resources/beginner/upgrade-contract.md",74871],"8768801e":[()=>n.e(67840).then(n.bind(n,44006)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash.md",44006],"87867a42":[()=>n.e(29040).then(n.bind(n,57209)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/index.md",57209],"87f5bee7":[()=>n.e(63144).then(n.bind(n,58116)),"@site/docs/concepts/glossary/X.md",58116],"883310e5":[()=>n.e(3048).then(n.bind(n,57558)),"@site/versioned_docs/version-1.5.X/concepts/design/reading-and-writing-to-the-blockchain.md",57558],"8833ab21":[()=>n.e(28875).then(n.t.bind(n,66079,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-alexanderlimonov-e61.json",66079],"8941358f":[()=>n.e(95469).then(n.bind(n,33366)),"@site/blog/2024-08-20-validator-rewards.md?truncated=true",33366],"897e9cb3":[()=>n.e(72035).then(n.bind(n,1368)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs.md",1368],"89c22482":[()=>n.e(63781).then(n.bind(n,40611)),"@site/docs/users/block-explorer.md",40611],"89d896be":[()=>n.e(43852).then(n.bind(n,18069)),"@site/docs/resources/tokens/cep18/transfer.md",18069],"8c0ead1f":[()=>n.e(36091).then(n.bind(n,63543)),"@site/docs/developers/dapps/sdk/script-sdk.md",63543],"8d265689":[()=>n.e(75631).then(n.bind(n,68814)),"@site/versioned_docs/version-1.5.X/operators/setup-network/index.md",68814],"8d81394c":[()=>n.e(49529).then(n.bind(n,42706)),"@site/docs/resources/beginner/index.md",42706],"8d90c7e3":[()=>n.e(40414).then(n.bind(n,82887)),"@site/versioned_docs/version-2.0.0/resources/advanced/two-party-multi-sig.md",82887],"8dd9adb4":[()=>n.e(42587).then(n.bind(n,71586)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/testing-session-code.md",71586],"8de9f24f":[()=>n.e(699).then(n.t.bind(n,56922,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-validators-6b7.json",56922],"8e1fd569":[()=>n.e(64097).then(n.bind(n,85936)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/direct-token-transfer.md",85936],"8f27be43":[()=>n.e(46088).then(n.bind(n,18277)),"@site/docs/resources/beginner/counter-testnet/walkthrough.md",18277],"8fcee16d":[()=>n.e(31725).then(n.bind(n,13297)),"@site/versioned_docs/version-2.0.0/developers/cli/transfers/index.md",13297],"8ff31131":[()=>n.e(6346).then(n.bind(n,9414)),"@site/docs/developers/cli/calling-contracts.md",9414],"905c7445":[()=>n.e(94552).then(n.bind(n,98081)),"@site/versioned_docs/version-2.0.0/concepts/glossary/E.md",98081],"90efbb16":[()=>n.e(18132).then(n.bind(n,31352)),"@site/versioned_docs/version-1.5.X/concepts/design/p2p.md",31352],"90f2be13":[()=>n.e(2407).then(n.bind(n,9008)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/inactive-vs-faulty.md",9008],"9116852a":[()=>n.e(12418).then(n.bind(n,38646)),"@site/docs/resources/beginner/counter/overview.md",38646],"915d90e1":[()=>n.e(12455).then(n.bind(n,67689)),"@site/docs/operators/becoming-a-validator/change-bid-public-key.md",67689],"931ecaed":[()=>n.e(40558).then(n.bind(n,99247)),"@site/versioned_docs/version-1.5.X/concepts/deploy-and-deploy-lifecycle.md",99247],"947e950c":[()=>n.e(83317).then(n.bind(n,85867)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/minimal-compliance.md",85867],"94f643bb":[()=>n.e(64643).then(n.bind(n,40867)),"@site/docs/concepts/glossary/Q.md",40867],"95c53987":[()=>n.e(6746).then(n.bind(n,72383)),"@site/versioned_docs/version-2.0.0/concepts/glossary/S.md",72383],"962c96ee":[()=>n.e(80852).then(n.bind(n,82189)),"@site/versioned_docs/version-2.0.0/developers/dapps/technology-stack.md",82189],"96fcb421":[()=>n.e(87446).then(n.bind(n,39724)),"@site/versioned_docs/version-2.0.0/operators/setup-network/index.md",39724],"977c8faa":[()=>n.e(66221).then(n.bind(n,63116)),"@site/docs/concepts/design/p2p.md",63116],"98d1a471":[()=>n.e(13986).then(n.bind(n,5987)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/assembly-script.md",5987],"98df448b":[()=>n.e(77772).then(n.bind(n,24120)),"@site/blog/2024-08-15-hello-blogworld.md?truncated=true",24120],"99a13742":[()=>n.e(59895).then(n.bind(n,58591)),"@site/docs/operators/setup/basic-node-configuration.md",58591],"9a38f23f":[()=>n.e(44771).then(n.bind(n,5132)),"@site/versioned_docs/version-2.0.0/disclaimer.md",5132],"9a508619":[()=>n.e(95882).then(n.bind(n,63629)),"@site/versioned_docs/version-2.0.0/concepts/design/networking-protocol.md",63629],"9acc619b":[()=>n.e(25465).then(n.bind(n,31662)),"@site/versioned_docs/version-1.5.X/operators/maintenance/archiving-and-restoring.md",31662],"9afe1d3d":[()=>n.e(240).then(n.bind(n,63131)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/index.md",63131],"9b0d9b67":[()=>n.e(89078).then(n.bind(n,10158)),"@site/versioned_docs/version-1.5.X/users/ledger/index.md",10158],"9b70ce79":[()=>n.e(20367).then(n.bind(n,23943)),"@site/versioned_docs/version-2.0.0/concepts/economics/consensus.md",23943],"9c5b6467":[()=>n.e(53265).then(n.bind(n,72675)),"@site/docs/operators/becoming-a-validator/index.md",72675],"9c6aa8d2":[()=>n.e(92381).then(n.bind(n,55711)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Y.md",55711],"9c780b1a":[()=>n.e(17438).then(n.bind(n,20621)),"@site/docs/developers/dapps/sdk/index.md",20621],"9cb749bd":[()=>n.e(39457).then(n.bind(n,53086)),"@site/versioned_docs/version-2.0.0/developers/dapps/nctl-test.md",53086],"9cd0819b":[()=>n.e(30247).then(n.bind(n,92367)),"@site/docs/operators/becoming-a-validator/recovering.md",92367],"9d275d72":[()=>n.e(53829).then(n.bind(n,42877)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/index.md",42877],"9dd9d4ea":[()=>n.e(19751).then(n.bind(n,41672)),"@site/versioned_docs/version-2.0.0/concepts/glossary/B.md",41672],"9e4087bc":[()=>n.e(52711).then(n.bind(n,89331)),"@theme/BlogArchivePage",89331],"9ec4e3de":[()=>n.e(41865).then(n.t.bind(n,40848,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-docs-redux-08d.json",40848],"9ed00072":[()=>n.e(60642).then(n.bind(n,29274)),"@site/docs/users/csprlive/token-transfer.md",29274],"9ee7887a":[()=>n.e(22473).then(n.bind(n,80156)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/index.md",80156],a024ab51:[()=>n.e(90613).then(n.bind(n,26773)),"@site/versioned_docs/version-2.0.0/developers/dapps/uref-security.md",26773],a03c4947:[()=>n.e(61368).then(n.bind(n,24311)),"@site/versioned_docs/version-1.5.X/concepts/dictionaries.md",24311],a0ccdbb2:[()=>n.e(9460).then(n.bind(n,72407)),"@site/docs/operators/setup-network/chain-spec.md",72407],a1868598:[()=>n.e(16265).then(n.bind(n,41214)),"@site/docs/developers/dapps/index.md",41214],a2874f18:[()=>n.e(16512).then(n.bind(n,71968)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash.md",71968],a2ea0fe7:[()=>n.e(70246).then(n.bind(n,69999)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/change-bid-public-key.md",69999],a30e2bb0:[()=>n.e(35496).then(n.bind(n,38440)),"@site/docs/concepts/economics/dynamic-gas-pricing.md",38440],a35afcc3:[()=>n.e(90398).then(n.bind(n,15739)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial.md",15739],a36dca7d:[()=>n.e(55740).then(n.bind(n,48553)),"@site/versioned_docs/version-2.0.0/resources/beginner/querying-network.md",48553],a3c7ece8:[()=>n.e(76214).then(n.bind(n,55405)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/json-rpc-pos.md",55405],a3dc4ae2:[()=>n.e(93100).then(n.bind(n,43322)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/go-sdk.md",43322],a3e473b3:[()=>n.e(44479).then(n.bind(n,61441)),"@site/versioned_docs/version-2.0.0/developers/dapps/template-frontend.md",61441],a4046515:[()=>n.e(50453).then(n.bind(n,48724)),"@site/versioned_docs/version-1.5.X/concepts/global-state.md",48724],a40a2cf8:[()=>n.e(25458).then(n.bind(n,21814)),"@site/versioned_docs/version-1.5.X/operators/setup/node-endpoints.md",21814],a434b528:[()=>n.e(20884).then(n.bind(n,77875)),"@site/versioned_docs/version-1.5.X/developers/cli/sending-deploys.md",77875],a4ae8417:[()=>n.e(49314).then(n.bind(n,40347)),"@site/docs/developers/dapps/setup-nctl.md",40347],a4b0daeb:[()=>n.e(72305).then(n.bind(n,36539)),"@site/versioned_docs/version-1.5.X/concepts/glossary/M.md",36539],a4cd78b5:[()=>n.e(7403).then(n.bind(n,37340)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/overview.md",37340],a4f8fe7e:[()=>n.e(67205).then(n.bind(n,34777)),"@site/docs/concepts/economics/consensus.md",34777],a53bd891:[()=>n.e(55664).then(n.bind(n,47150)),"@site/docs/concepts/glossary/F.md",47150],a55b9639:[()=>n.e(46453).then(n.bind(n,46557)),"@site/docs/resources/advanced/list-cspr.md",46557],a6957975:[()=>n.e(78540).then(n.bind(n,3930)),"@site/versioned_docs/version-2.0.0/resources/beginner/aws-node.md",3930],a6aa9e1f:[()=>Promise.all([n.e(71869),n.e(79113),n.e(3347),n.e(37643)]).then(n.bind(n,35124)),"@theme/BlogListPage",35124],a6c56441:[()=>n.e(36337).then(n.bind(n,95250)),"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/index.md",95250],a6efe0e1:[()=>n.e(54766).then(n.bind(n,62409)),"@site/versioned_docs/version-1.5.X/users/csprlive/index.md",62409],a72bcf22:[()=>n.e(13828).then(n.t.bind(n,21980,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-setup-b32.json",21980],a7bd4aaa:[()=>n.e(67098).then(n.bind(n,74532)),"@theme/DocVersionRoot",74532],a7e0ea76:[()=>n.e(21421).then(n.bind(n,89780)),"@site/versioned_docs/version-2.0.0/users/index.md",89780],a80f26d4:[()=>n.e(92218).then(n.bind(n,54801)),"@site/versioned_docs/version-1.5.X/concepts/economics/gas-concepts.md",54801],a811e42c:[()=>n.e(41408).then(n.bind(n,97681)),"@site/docs/resources/tokens/cep18/tests.md",97681],a81b7004:[()=>n.e(16044).then(n.bind(n,14086)),"@site/docs/developers/writing-onchain-code/contract-vs-session.md",14086],a833d846:[()=>n.e(78848).then(n.bind(n,86896)),"@site/versioned_docs/version-2.0.0/concepts/glossary/J.md",86896],a94703ab:[()=>Promise.all([n.e(71869),n.e(79048)]).then(n.bind(n,11377)),"@theme/DocRoot",11377],a9707311:[()=>n.e(8816).then(n.bind(n,72514)),"@site/versioned_docs/version-2.0.0/concepts/economics/dynamic-gas-pricing.md",72514],a9deb425:[()=>n.e(55157).then(n.bind(n,25943)),"@site/docs/developers/dapps/technology-stack.md",25943],a9f5564d:[()=>n.e(79235).then(n.bind(n,66428)),"@site/docs/operators/setup-network/genesis.md",66428],aa162190:[()=>n.e(71512).then(n.bind(n,93573)),"@site/docs/concepts/glossary/O.md",93573],aafbba97:[()=>n.e(92986).then(n.bind(n,40261)),"@site/docs/users/csprlive/index.md",40261],ab246697:[()=>n.e(59756).then(n.bind(n,884)),"@site/docs/concepts/glossary/H.md",884],ab991e0e:[()=>n.e(27675).then(n.bind(n,71353)),"@site/docs/resources/beginner/counter/index.md",71353],aba21aa0:[()=>n.e(35742).then(n.t.bind(n,27093,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",27093],abd56c27:[()=>n.e(97267).then(n.bind(n,5804)),"@site/versioned_docs/version-1.5.X/resources/advanced/return-values-tutorial.md",5804],ac16ac20:[()=>n.e(67280).then(n.bind(n,7737)),"@site/versioned_docs/version-2.0.0/operators/setup/non-root-user.md",7737],ac361b55:[()=>n.e(43019).then(n.bind(n,70)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/json-rpc-informational.md",70],ac9a16c0:[()=>n.e(87013).then(n.bind(n,58043)),"@site/versioned_docs/version-2.0.0/developers/dapps/monitor-and-consume-events.md",58043],acecf23e:[()=>n.e(81903).then(n.t.bind(n,1912,19)),"~blog/default/blogMetadata-default.json",1912],acee0a96:[()=>n.e(35569).then(n.bind(n,63516)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/python-sdk.md",63516],ad0b296a:[()=>n.e(35378).then(n.bind(n,64336)),"@site/docs/resources/tokens/cep18/query.md",64336],ad15c07f:[()=>n.e(19044).then(n.bind(n,84798)),"@site/docs/concepts/economics/index.md",84798],ad591877:[()=>n.e(91035).then(n.bind(n,80884)),"@site/versioned_docs/version-2.0.0/developers/dapps/index.md",80884],ad727d36:[()=>n.e(84457).then(n.bind(n,88030)),"@site/docs/concepts/glossary/V.md",88030],ad7eda35:[()=>n.e(75721).then(n.bind(n,47501)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/types_chain.md",47501],ae470ddc:[()=>n.e(31089).then(n.bind(n,5029)),"@site/docs/users/ledger/staking-ledger.md",5029],ae5d26cf:[()=>n.e(67461).then(n.bind(n,14377)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/reverse-lookup.md",14377],aee0fe92:[()=>n.e(27832).then(n.bind(n,32330)),"@site/versioned_docs/version-1.5.X/developers/json-rpc/index.md",32330],aefd42fa:[()=>n.e(21418).then(n.bind(n,90171)),"@site/versioned_docs/version-1.5.X/operators/setup/open-files.md",90171],af050a36:[()=>n.e(79293).then(n.bind(n,87614)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/js-tutorial.md",87614],af1112c6:[()=>n.e(25210).then(n.bind(n,55679)),"@site/versioned_docs/version-1.5.X/developers/dapps/setup-nctl.md",55679],afa6d836:[()=>n.e(46724).then(n.bind(n,96186)),"@site/docs/concepts/glossary/B.md",96186],b0b03333:[()=>n.e(30123).then(n.bind(n,30931)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/types_chain.md",30931],b0e8b9d5:[()=>n.e(90616).then(n.bind(n,7278)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/introduction.md",7278],b114f501:[()=>n.e(7089).then(n.bind(n,9877)),"@site/versioned_docs/version-2.0.0/users/funding-from-exchanges.md",9877],b15d29cb:[()=>n.e(61767).then(n.bind(n,96409)),"@site/docs/concepts/glossary/C.md",96409],b192e983:[()=>n.e(74428).then(n.bind(n,2473)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/emitting-contract-events.md",2473],b1eae65b:[()=>n.e(99218).then(n.bind(n,56358)),"@site/blog/2024-07-17-addressable-entity.md?truncated=true",56358],b36f50d3:[()=>n.e(43990).then(n.bind(n,29337)),"@site/docs/operators/setup/index.md",29337],b3a49b92:[()=>n.e(9113).then(n.bind(n,48258)),"@site/docs/concepts/glossary/Z.md",48258],b3b8c5cb:[()=>n.e(39687).then(n.bind(n,72781)),"@site/versioned_docs/version-1.5.X/concepts/glossary/S.md",72781],b415f00a:[()=>n.e(3428).then(n.bind(n,58278)),"@site/versioned_docs/version-2.0.0/concepts/glossary/P.md",58278],b46ec474:[()=>n.e(62958).then(n.bind(n,2945)),"@site/docs/operators/setup/upgrade.md",2945],b67f60dc:[()=>n.e(81801).then(n.bind(n,36889)),"@site/versioned_docs/version-1.5.X/concepts/glossary/W.md",36889],b687a817:[()=>n.e(51627).then(n.bind(n,36044)),"@site/versioned_docs/version-1.5.X/concepts/design/networking-protocol.md",36044],b70225e0:[()=>n.e(80372).then(n.bind(n,21013)),"@site/versioned_docs/version-2.0.0/operators/setup/node-events.md",21013],b70624a2:[()=>n.e(15211).then(n.bind(n,68066)),"@site/versioned_docs/version-2.0.0/concepts/design/p2p.md",68066],b71ecf14:[()=>n.e(46736).then(n.bind(n,70255)),"@site/blog/2024-07-16-setting-up-condor-local.md?truncated=true",70255],b7708f1e:[()=>n.e(96167).then(n.bind(n,69094)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/client-library-usage.md",69094],b7a2b993:[()=>n.e(9396).then(n.bind(n,74200)),"@site/versioned_docs/version-2.0.0/users/csprlive/token-transfer.md",74200],b7cc26e1:[()=>n.e(63530).then(n.bind(n,69710)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/upgrading-contracts.md",69710],b8c8445c:[()=>n.e(84336).then(n.bind(n,674)),"@site/docs/concepts/about.md",674],b8ef17b7:[()=>n.e(57797).then(n.bind(n,20112)),"@site/versioned_docs/version-2.0.0/concepts/design/reading-and-writing-to-the-blockchain.md",20112],b8f04a6b:[()=>n.e(14910).then(n.bind(n,98478)),"@site/versioned_docs/version-2.0.0/concepts/key-types.md",98478],b9ffcd07:[()=>n.e(44690).then(n.bind(n,17921)),"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/multi-sig-workflow.md",17921],ba0fa3fe:[()=>n.e(94225).then(n.bind(n,64287)),"@site/docs/resources/advanced/list-auth-keys-tutorial.md",64287],baabe181:[()=>n.e(22510).then(n.t.bind(n,37324,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-melpadden-a93.json",37324],baf71301:[()=>n.e(2996).then(n.bind(n,28646)),"@site/versioned_docs/version-1.5.X/concepts/about.md",28646],bafead24:[()=>n.e(30286).then(n.bind(n,70269)),"@site/versioned_docs/version-1.5.X/concepts/glossary/C.md",70269],bb037852:[()=>n.e(74096).then(n.bind(n,90282)),"@site/docs/concepts/design/reading-and-writing-to-the-blockchain.md",90282],bb9db0dd:[()=>n.e(24198).then(n.bind(n,72876)),"@site/versioned_docs/version-1.5.X/developers/dapps/nctl-test.md",72876],bc4bfdf0:[()=>n.e(36476).then(n.bind(n,82008)),"@site/versioned_docs/version-1.5.X/concepts/glossary/X.md",82008],bcd2587d:[()=>n.e(11378).then(n.bind(n,15569)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/errors.md",15569],bd7d26b2:[()=>n.e(93708).then(n.bind(n,2509)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/unbonding.md",2509],be0df356:[()=>n.e(52048).then(n.bind(n,97636)),"@site/docs/operators/becoming-a-validator/bonding.md",97636],be5e85f4:[()=>n.e(64325).then(n.bind(n,52133)),"@site/docs/resources/quick-start.md",52133],befad559:[()=>n.e(51968).then(n.bind(n,16247)),"@site/versioned_docs/version-1.5.X/concepts/index.md",16247],bf5bbaf8:[()=>n.e(66607).then(n.bind(n,19903)),"@site/docs/resources/beginner/counter-testnet/index.md",19903],bfb3244a:[()=>n.e(78445).then(n.bind(n,14966)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/python-sdk.md",14966],c00ffc57:[()=>n.e(32985).then(n.bind(n,97554)),"@site/versioned_docs/version-2.0.0/concepts/glossary/T.md",97554],c0299000:[()=>n.e(35890).then(n.bind(n,8077)),"@site/docs/developers/dapps/monitor-and-consume-events.md",8077],c0def98a:[()=>n.e(61669).then(n.bind(n,79173)),"@site/versioned_docs/version-2.0.0/developers/writing-onchain-code/calling-contracts.md",79173],c10b8a9f:[()=>n.e(60781).then(n.bind(n,58107)),"@site/versioned_docs/version-1.5.X/users/csprlive/testnet-faucet.md",58107],c10cfbfe:[()=>n.e(98455).then(n.bind(n,40260)),"@site/docs/concepts/accounts-and-keys.md",40260],c141421f:[()=>n.e(80957).then(n.t.bind(n,40936,19)),"@generated/docusaurus-theme-search-algolia/default/__plugin.json",40936],c19e69a7:[()=>n.e(96962).then(n.bind(n,75574)),"@site/docs/developers/cli/undelegate.md",75574],c2728190:[()=>n.e(86121).then(n.bind(n,31011)),"@site/docs/concepts/index.md",31011],c2a48fdb:[()=>n.e(66623).then(n.bind(n,30919)),"@site/docs/operators/setup/fast-sync.md",30919],c3308ba6:[()=>n.e(86547).then(n.t.bind(n,5571,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-condor-e10.json",5571],c34be5c7:[()=>n.e(44123).then(n.bind(n,49196)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter/overview.md",49196],c377a04b:[()=>n.e(45742).then(n.bind(n,48321)),"@site/docs/index.md",48321],c377dc4a:[()=>n.e(14425).then(n.bind(n,48188)),"@site/blog/2024-08-15-hello-blogworld.md",48188],c37f176d:[()=>n.e(79596).then(n.bind(n,6910)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/quickstart-guide.md",6910],c380abc4:[()=>n.e(80529).then(n.bind(n,72028)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/writing-session-code.md",72028],c4561df8:[()=>n.e(34846).then(n.bind(n,72353)),"@site/versioned_docs/version-1.5.X/concepts/glossary/O.md",72353],c45e62e7:[()=>n.e(52296).then(n.bind(n,89157)),"@site/versioned_docs/version-2.0.0/resources/advanced/list-auth-keys-tutorial.md",89157],c474c2b1:[()=>n.e(9603).then(n.bind(n,87771)),"@site/versioned_docs/version-2.0.0/operators/setup/upgrade.md",87771],c52eaa26:[()=>n.e(16938).then(n.bind(n,83106)),"@site/docs/operators/setup-network/create-private.md",83106],c5f06d44:[()=>n.e(76971).then(n.bind(n,60793)),"@site/versioned_docs/version-2.0.0/resources/beginner/cep18.md",60793],c691959f:[()=>n.e(86233).then(n.bind(n,37819)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/commands.md",37819],c74094f8:[()=>n.e(52512).then(n.bind(n,89738)),"@site/versioned_docs/version-1.5.X/concepts/design/index.md",89738],c7d46fe1:[()=>n.e(67935).then(n.bind(n,94085)),"@site/docs/operators/setup/hardware.md",94085],c8e4da00:[()=>n.e(35808).then(n.bind(n,43185)),"@site/versioned_docs/version-1.5.X/developers/index.md",43185],c8eb2c38:[()=>n.e(62287).then(n.bind(n,42567)),"@site/versioned_docs/version-2.0.0/operators/setup/index.md",42567],c95e6d8d:[()=>n.e(46879).then(n.bind(n,86400)),"@site/versioned_docs/version-2.0.0/resources/build-on-casper.md",86400],c9d52fc5:[()=>n.e(69210).then(n.bind(n,53385)),"@site/docs/concepts/glossary/S.md",53385],c9db186d:[()=>n.e(46988).then(n.bind(n,59151)),"@site/versioned_docs/version-1.5.X/operators/becoming-a-validator/index.md",59151],c9f0fdac:[()=>n.e(75727).then(n.bind(n,59897)),"@site/versioned_docs/version-1.5.X/developers/dapps/sdk/index.md",59897],ca7245df:[()=>n.e(97419).then(n.bind(n,76032)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/best-practices.md",76032],ca962d2e:[()=>n.e(37639).then(n.bind(n,88779)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter/index.md",88779],cacd3f19:[()=>n.e(18663).then(n.bind(n,88685)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/csharp-sdk.md",88685],cad9fd36:[()=>n.e(27207).then(n.bind(n,45024)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/quickstart-guide.md",45024],cb447cb9:[()=>n.e(60505).then(n.bind(n,59184)),"@site/versioned_docs/version-2.0.0/developers/cli/transfers/multisig-deploy-transfer.md",59184],cb63487a:[()=>n.e(59081).then(n.bind(n,68736)),"@site/docs/developers/cli/querying-global-state.md",68736],cbe09f13:[()=>n.e(64894).then(n.bind(n,14516)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/query.md",14516],cbe8101d:[()=>n.e(18723).then(n.bind(n,18901)),"@site/docs/operators/setup/joining.md",18901],cc2e94c0:[()=>n.e(5364).then(n.bind(n,86447)),"@site/docs/developers/dapps/uref-security.md",86447],cc84b9e4:[()=>n.e(37057).then(n.bind(n,86623)),"@site/versioned_docs/version-2.0.0/resources/advanced/storage-workflow.md",86623],ccc49370:[()=>Promise.all([n.e(71869),n.e(79113),n.e(3347),n.e(83249)]).then(n.bind(n,73858)),"@theme/BlogPostPage",73858],cd8c5c3b:[()=>n.e(29574).then(n.bind(n,35887)),"@site/versioned_docs/version-2.0.0/concepts/economics/gas-concepts.md",35887],cd948886:[()=>n.e(8979).then(n.bind(n,35811)),"@site/docs/resources/index.md",35811],cdd6a56c:[()=>n.e(57915).then(n.bind(n,2222)),"@site/versioned_docs/version-2.0.0/concepts/smart-contracts.md",2222],ce0e1dbb:[()=>n.e(53025).then(n.bind(n,37733)),"@site/versioned_docs/version-1.5.X/concepts/design/highway.md",37733],ce3d5a4b:[()=>n.e(16986).then(n.bind(n,33853)),"@site/versioned_docs/version-1.5.X/users/ledger/ledger-cspr-live.md",33853],ce6605d8:[()=>n.e(82270).then(n.bind(n,41693)),"@site/docs/developers/cli/verifying-contracts.md",41693],ce6fe363:[()=>n.e(86486).then(n.bind(n,86815)),"@site/versioned_docs/version-2.0.0/developers/dapps/sdk/index.md",86815],cf3029ea:[()=>n.e(9636).then(n.bind(n,20009)),"@site/versioned_docs/version-2.0.0/developers/cli/opcode-costs.md",20009],cf35294f:[()=>n.e(33341).then(n.bind(n,72282)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs.md",72282],cfcbd284:[()=>n.e(65845).then(n.bind(n,46012)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep78/js-tutorial.md",46012],d02d0f51:[()=>n.e(73621).then(n.bind(n,98879)),"@site/versioned_docs/version-2.0.0/developers/cli/installing-contracts.md",98879],d050b476:[()=>n.e(58889).then(n.bind(n,97651)),"@site/versioned_docs/version-1.5.X/concepts/glossary/U.md",97651],d0616161:[()=>n.e(17832).then(n.bind(n,23545)),"@site/versioned_docs/version-2.0.0/concepts/dictionaries.md",23545],d06ee05c:[()=>n.e(71451).then(n.bind(n,48340)),"@site/docs/resources/advanced/transfer-token-to-contract.md",48340],d0a8493b:[()=>n.e(11926).then(n.bind(n,45341)),"@site/docs/resources/changelog.md",45341],d0c6c99a:[()=>n.e(75250).then(n.bind(n,83031)),"@site/versioned_docs/version-2.0.0/resources/beginner/counter-testnet/commands.md",83031],d13dc577:[()=>n.e(82677).then(n.bind(n,41026)),"@site/versioned_docs/version-1.5.X/users/index.md",41026],d2039ef8:[()=>n.e(85354).then(n.bind(n,15377)),"@site/versioned_docs/version-1.5.X/concepts/serialization-standard.md",15377],d220dcab:[()=>n.e(84941).then(n.bind(n,85135)),"@site/versioned_docs/version-1.5.X/resources/beginner/querying-network.md",85135],d279fdce:[()=>n.e(35559).then(n.bind(n,67352)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/testing-session-code.md",67352],d3ef4614:[()=>n.e(28548).then(n.bind(n,27321)),"@site/versioned_docs/version-1.5.X/operators/setup/hardware.md",27321],d477c291:[()=>n.e(52684).then(n.bind(n,74347)),"@site/versioned_docs/version-1.5.X/developers/dapps/uref-security.md",74347],d48191b6:[()=>n.e(52112).then(n.t.bind(n,3131,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-tags-tokenomics-137.json",3131],d49dddd4:[()=>n.e(66784).then(n.bind(n,8386)),"@site/docs/developers/dapps/sdk/python-sdk.md",8386],d4c529d3:[()=>n.e(96379).then(n.bind(n,72319)),"@site/docs/resources/tokens/cep78/modalities.md",72319],d629d828:[()=>n.e(86660).then(n.t.bind(n,76895,19)),"@generated/docusaurus-plugin-content-docs/default/p/1-5-x-201.json",76895],d638c601:[()=>n.e(4858).then(n.bind(n,97218)),"@site/docs/developers/json-rpc/json-rpc-informational.md",97218],d7289626:[()=>n.e(66247).then(n.bind(n,53158)),"@site/docs/concepts/design/index.md",53158],d7f9f727:[()=>n.e(83495).then(n.bind(n,54541)),"@site/docs/concepts/glossary/G.md",54541],d7fae98e:[()=>n.e(17636).then(n.bind(n,70358)),"@site/versioned_docs/version-1.5.X/resources/advanced/index.md",70358],d80df429:[()=>n.e(73846).then(n.bind(n,48130)),"@site/docs/resources/tokens/cep78/js-tutorial.md",48130],d81ba6be:[()=>n.e(41156).then(n.bind(n,61813)),"@site/versioned_docs/version-2.0.0/concepts/glossary/A.md",61813],d8ae3676:[()=>n.e(74541).then(n.bind(n,45316)),"@site/versioned_docs/version-2.0.0/concepts/design/index.md",45316],d8c709f8:[()=>n.e(65610).then(n.bind(n,50890)),"@site/versioned_docs/version-2.0.0/resources/tokens/cep18/query.md",50890],d92b4d08:[()=>n.e(93422).then(n.bind(n,66395)),"@site/docs/resources/advanced/multi-sig/multi-sig-workflow.md",66395],d94d6bbe:[()=>n.e(49065).then(n.bind(n,78715)),"@site/versioned_docs/version-1.5.X/operators/setup/fast-sync.md",78715],db24aef0:[()=>n.e(92799).then(n.bind(n,71383)),"@site/docs/operators/setup/non-root-user.md",71383],dbfc4782:[()=>n.e(38749).then(n.t.bind(n,91895,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-archive-61f.json",91895],dc1c4417:[()=>n.e(35580).then(n.bind(n,26937)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter-testnet/walkthrough.md",26937],dc5e10d3:[()=>n.e(94557).then(n.bind(n,47374)),"@site/docs/concepts/transactions-and-transaction-lifecycle.md",47374],dcb4c613:[()=>n.e(43445).then(n.bind(n,74671)),"@site/docs/users/csprlive/testnet-faucet.md",74671],dd04b75e:[()=>n.e(21672).then(n.t.bind(n,33024,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-8ff.json",33024],dd908370:[()=>n.e(69918).then(n.bind(n,77237)),"@site/versioned_docs/version-1.5.X/operators/setup/index.md",77237],dd93ee27:[()=>n.e(70720).then(n.bind(n,68127)),"@site/versioned_docs/version-2.0.0/resources/advanced/cross-contract.md",68127],de33ad21:[()=>n.e(50196).then(n.bind(n,20448)),"@site/versioned_docs/version-2.0.0/developers/essential-crates.md",20448],df5bc763:[()=>n.e(34555).then(n.bind(n,23946)),"@site/versioned_docs/version-1.5.X/resources/beginner/counter/overview.md",23946],dfbc8a55:[()=>n.e(53307).then(n.bind(n,53301)),"@site/docs/resources/advanced/storage-workflow.md",53301],dfcc4619:[()=>n.e(7083).then(n.bind(n,54972)),"@site/docs/concepts/serialization/index.md",54972],e068c333:[()=>n.e(43886).then(n.bind(n,17502)),"@site/versioned_docs/version-2.0.0/developers/cli/querying-global-state.md",17502],e08eef46:[()=>n.e(61418).then(n.bind(n,57446)),"@site/docs/developers/prerequisites.md",57446],e10cd13d:[()=>n.e(5118).then(n.bind(n,92770)),"@site/versioned_docs/version-2.0.0/resources/advanced/return-values-tutorial.md",92770],e15566cb:[()=>n.e(59784).then(n.bind(n,63018)),"@site/docs/users/ledger/index.md",63018],e1e5af17:[()=>n.e(60202).then(n.bind(n,26628)),"@site/docs/concepts/design/zug.md",26628],e238c115:[()=>n.e(40229).then(n.bind(n,18822)),"@site/versioned_docs/version-1.5.X/concepts/glossary/Z.md",18822],e2509bb6:[()=>n.e(15196).then(n.bind(n,98442)),"@site/versioned_docs/version-2.0.0/operators/becoming-a-validator/bonding.md",98442],e2799c63:[()=>n.e(99303).then(n.bind(n,44946)),"@site/docs/operators/setup/node-endpoints.md",44946],e289ead3:[()=>n.e(77394).then(n.bind(n,46593)),"@site/docs/concepts/design/consensus.md",46593],e2975a84:[()=>n.e(58204).then(n.bind(n,33467)),"@site/versioned_docs/version-1.5.X/developers/dapps/dapp.md",33467],e2f5312b:[()=>n.e(31997).then(n.bind(n,97687)),"@site/versioned_docs/version-1.5.X/resources/condor-for-exchanges.md",97687],e3f9a068:[()=>n.e(51561).then(n.bind(n,86271)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/multi-sig-workflow.md",86271],e45056bc:[()=>n.e(22527).then(n.bind(n,72814)),"@site/docs/developers/dapps/sdk/go-sdk.md",72814],e4d870e1:[()=>n.e(25751).then(n.bind(n,10935)),"@site/versioned_docs/version-1.5.X/resources/beginner/cep18.md",10935],e5493a21:[()=>n.e(46607).then(n.bind(n,90555)),"@site/docs/concepts/glossary/Y.md",90555],e5afa1a3:[()=>n.e(96578).then(n.bind(n,12499)),"@site/versioned_docs/version-2.0.0/developers/index.md",12499],e605c6b3:[()=>n.e(96325).then(n.bind(n,75146)),"@site/versioned_docs/version-2.0.0/resources/advanced/multi-sig/other-scenarios.md",75146],e7589c2a:[()=>n.e(32831).then(n.bind(n,73122)),"@site/versioned_docs/version-2.0.0/concepts/serialization/structures.md",73122],e8b40bee:[()=>n.e(65282).then(n.bind(n,80870)),"@site/docs/developers/writing-onchain-code/simple-contract.md",80870],e939f825:[()=>n.e(11904).then(n.bind(n,95065)),"@site/versioned_docs/version-2.0.0/developers/dapps/speculative-exec.md",95065],ea0474c4:[()=>n.e(66481).then(n.bind(n,949)),"@site/versioned_docs/version-1.5.X/developers/cli/delegate.md",949],ea921b39:[()=>n.e(68013).then(n.bind(n,80498)),"@site/versioned_docs/version-2.0.0/operators/setup-network/genesis.md",80498],eaba5dd2:[()=>n.e(72067).then(n.bind(n,30229)),"@site/versioned_docs/version-1.5.X/developers/cli/transfers/multisig-deploy-transfer.md",30229],eacea541:[()=>n.e(51434).then(n.bind(n,2880)),"@site/docs/concepts/glossary/D.md",2880],eb0d94ae:[()=>n.e(97575).then(n.bind(n,51352)),"@site/versioned_docs/version-1.5.X/concepts/glossary/index.md",51352],eb1cd7f2:[()=>n.e(11969).then(n.bind(n,46250)),"@site/versioned_docs/version-1.5.X/developers/writing-onchain-code/simple-contract.md",46250],eb5a6cc0:[()=>n.e(280).then(n.bind(n,66747)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/reverse-lookup.md",66747],ebb9a3ce:[()=>n.e(1093).then(n.bind(n,75736)),"@site/versioned_docs/version-1.5.X/resources/advanced/multi-sig/other-scenarios.md",75736],ed267fba:[()=>n.e(22748).then(n.bind(n,61809)),"@site/versioned_docs/version-1.5.X/developers/dapps/prerequisites.md",61809],ed3af4a0:[()=>n.e(77533).then(n.bind(n,92461)),"@site/versioned_docs/version-2.0.0/developers/dapps/setup-nctl.md",92461],ed772d97:[()=>n.e(36920).then(n.bind(n,13127)),"@site/versioned_docs/version-2.0.0/index.md",13127],ee7c1cc7:[()=>n.e(79041).then(n.bind(n,52306)),"@site/versioned_docs/version-1.5.X/concepts/economics/index.md",52306],ee94176e:[()=>n.e(11433).then(n.bind(n,4080)),"@site/docs/resources/advanced/return-values-tutorial.md",4080],eeb3740b:[()=>n.e(84391).then(n.bind(n,37713)),"@site/versioned_docs/version-2.0.0/operators/setup-network/chain-spec.md",37713],ef2abd7e:[()=>n.e(70715).then(n.bind(n,798)),"@site/versioned_docs/version-1.5.X/concepts/intro-to-dapps.md",798],ef646837:[()=>n.e(8456).then(n.bind(n,25359)),"@site/versioned_docs/version-2.0.0/resources/changelog.md",25359],ef726b40:[()=>n.e(4125).then(n.bind(n,59544)),"@site/versioned_docs/version-2.0.0/concepts/design/rewards.md",59544],ef7672e3:[()=>n.e(67110).then(n.bind(n,63457)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep18/transfer.md",63457],efd01d75:[()=>n.e(72753).then(n.bind(n,35351)),"@site/versioned_docs/version-2.0.0/concepts/glossary/K.md",35351],eff21157:[()=>n.e(29080).then(n.bind(n,33997)),"@site/versioned_docs/version-1.5.X/resources/advanced/two-party-multi-sig.md",33997],f0563fee:[()=>n.e(27865).then(n.bind(n,17606)),"@site/docs/concepts/transactions.md",17606],f070a991:[()=>n.e(55592).then(n.bind(n,26591)),"@site/versioned_docs/version-1.5.X/concepts/list-auth-keys.md",26591],f1245771:[()=>n.e(31630).then(n.t.bind(n,51485,19)),"@generated/docusaurus-plugin-content-blog/default/p/blog-authors-dylanireland-62c.json",51485],f1a6c2e6:[()=>n.e(8595).then(n.bind(n,24140)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/guidance.md",24140],f1c6b7a3:[()=>n.e(8694).then(n.bind(n,13548)),"@site/docs/developers/cli/transfers/direct-token-transfer.md",13548],f1f89c2e:[()=>n.e(62021).then(n.bind(n,24434)),"@site/versioned_docs/version-1.5.X/developers/cli/calling-contracts.md",24434],f203f57a:[()=>n.e(84063).then(n.bind(n,59784)),"@site/versioned_docs/version-2.0.0/concepts/economics/runtime.md",59784],f224ad82:[()=>n.e(75932).then(n.bind(n,51630)),"@site/versioned_docs/version-2.0.0/concepts/serialization/index.md",51630],f2779c45:[()=>n.e(74192).then(n.bind(n,54770)),"@site/docs/developers/json-rpc/guidance.md",54770],f2a77c75:[()=>n.e(80277).then(n.bind(n,93666)),"@site/versioned_docs/version-2.0.0/developers/cli/redelegate.md",93666],f2e157d0:[()=>n.e(4301).then(n.bind(n,10642)),"@site/versioned_docs/version-2.0.0/developers/dapps/dapp.md",10642],f3bf6984:[()=>n.e(89349).then(n.bind(n,79029)),"@site/docs/developers/dapps/prerequisites.md",79029],f46d6e59:[()=>n.e(82858).then(n.bind(n,57806)),"@site/docs/operators/maintenance/moving-node.md",57806],f5c04343:[()=>n.e(30605).then(n.bind(n,36831)),"@site/versioned_docs/version-2.0.0/developers/json-rpc/types_cl.md",36831],f6320c57:[()=>n.e(95875).then(n.bind(n,15562)),"@site/versioned_docs/version-2.0.0/concepts/glossary/index.md",15562],f69b951d:[()=>n.e(59683).then(n.bind(n,2154)),"@site/versioned_docs/version-2.0.0/concepts/glossary/L.md",2154],f71fe95d:[()=>n.e(30670).then(n.bind(n,38636)),"@site/versioned_docs/version-1.5.X/resources/casper-open-source-software.md",38636],f74078f7:[()=>n.e(24682).then(n.bind(n,23936)),"@site/versioned_docs/version-2.0.0/concepts/economics/fee-elimination.md",23936],f776c06c:[()=>n.e(57033).then(n.bind(n,20528)),"@site/docs/resources/casper-open-source-software.md",20528],f8743170:[()=>n.e(73421).then(n.bind(n,65916)),"@site/versioned_docs/version-2.0.0/operators/maintenance/moving-node.md",65916],f88cb658:[()=>n.e(61153).then(n.bind(n,56531)),"@site/docs/operators/setup-network/staging-files-for-new-network.md",56531],f95b1f88:[()=>n.e(67876).then(n.bind(n,70748)),"@site/docs/concepts/serialization/primitives.md",70748],faf2a93e:[()=>n.e(16666).then(n.bind(n,88956)),"@site/docs/users/ledger/ledger-live.md",88956],fb804d1c:[()=>n.e(54939).then(n.bind(n,8060)),"@site/docs/resources/advanced/multi-sig/other-scenarios.md",8060],fb904585:[()=>n.e(45140).then(n.bind(n,88320)),"@site/versioned_docs/version-2.0.0/concepts/glossary/Z.md",88320],fd661beb:[()=>n.e(55789).then(n.bind(n,33142)),"@site/versioned_docs/version-1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide.md",33142],fd967833:[()=>n.e(19179).then(n.bind(n,584)),"@site/versioned_docs/version-2.0.0/operators/setup/node-endpoints.md",584],fe0242b1:[()=>n.e(48631).then(n.bind(n,67074)),"@site/docs/disclaimer.md",67074],fef6ab33:[()=>n.e(18155).then(n.bind(n,79008)),"@site/versioned_docs/version-1.5.X/operators/setup-network/genesis.md",79008]};var i=n(74848);function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,i.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,i.jsx)("p",{children:String(t)}),(0,i.jsx)("div",{children:(0,i.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,i.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,i.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,i.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,i.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,i.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,i.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,i.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var l=n(86921),d=n(53102);function p(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(82237).then(n.bind(n,82237)),modules:["@theme/NotFound"],webpack:()=>[82237],render(e,t){const n=e.default;return(0,i.jsx)(d.W,{value:{plugin:{name:"native",id:"default"}},children:(0,i.jsx)(n,{...t})})}});const r=s[`${e}-${t}`],p={},u=[],f=[],g=(0,l.A)(r);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=a[n];r&&(p[t]=r[0],u.push(r[1]),f.push(r[2]))})),o().Map({loading:c,loader:p,modules:u,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const s=r.default;if(!s)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof s&&"function"!=typeof s||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{s[e]=r[e]}));let a=o;const i=n.split(".");i.slice(0,-1).forEach((e=>{a=a[e]})),a[i[i.length-1]]=s}));const s=o.__comp;delete o.__comp;const a=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,i.jsx)(d.W,{value:a,children:(0,i.jsx)(s,{...o,...c,...n})})}})}const u=[{path:"/blog/",component:p("/blog/","834"),exact:!0},{path:"/blog/addressable-entity/",component:p("/blog/addressable-entity/","887"),exact:!0},{path:"/blog/archive/",component:p("/blog/archive/","1d9"),exact:!0},{path:"/blog/authors/",component:p("/blog/authors/","347"),exact:!0},{path:"/blog/authors/alexanderlimonov/",component:p("/blog/authors/alexanderlimonov/","e4c"),exact:!0},{path:"/blog/authors/dylanireland/",component:p("/blog/authors/dylanireland/","a3a"),exact:!0},{path:"/blog/authors/melpadden/",component:p("/blog/authors/melpadden/","0d6"),exact:!0},{path:"/blog/authors/sczembor/",component:p("/blog/authors/sczembor/","8cb"),exact:!0},{path:"/blog/condor-fee-elimination/",component:p("/blog/condor-fee-elimination/","f26"),exact:!0},{path:"/blog/condor-local-setup/",component:p("/blog/condor-local-setup/","2aa"),exact:!0},{path:"/blog/condor-validator-rewards/",component:p("/blog/condor-validator-rewards/","3b7"),exact:!0},{path:"/blog/tags/",component:p("/blog/tags/","e17"),exact:!0},{path:"/blog/tags/condor/",component:p("/blog/tags/condor/","cf9"),exact:!0},{path:"/blog/tags/docs-redux/",component:p("/blog/tags/docs-redux/","339"),exact:!0},{path:"/blog/tags/features/",component:p("/blog/tags/features/","bc2"),exact:!0},{path:"/blog/tags/hello/",component:p("/blog/tags/hello/","8a7"),exact:!0},{path:"/blog/tags/new-docs/",component:p("/blog/tags/new-docs/","fdd"),exact:!0},{path:"/blog/tags/setup/",component:p("/blog/tags/setup/","a7c"),exact:!0},{path:"/blog/tags/tokenomics/",component:p("/blog/tags/tokenomics/","9c1"),exact:!0},{path:"/blog/tags/validators/",component:p("/blog/tags/validators/","87b"),exact:!0},{path:"/blog/welcome-docs-redux/",component:p("/blog/welcome-docs-redux/","fc7"),exact:!0},{path:"/search/",component:p("/search/","21e"),exact:!0},{path:"/",component:p("/","0c1"),routes:[{path:"/1.5.X/",component:p("/1.5.X/","6a4"),routes:[{path:"/1.5.X/",component:p("/1.5.X/","3ce"),routes:[{path:"/1.5.X/",component:p("/1.5.X/","1b3"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/",component:p("/1.5.X/concepts/","9f0"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/accounts-and-keys/",component:p("/1.5.X/concepts/accounts-and-keys/","eaa"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/callstack/",component:p("/1.5.X/concepts/callstack/","f4d"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/design/casper-design/",component:p("/1.5.X/concepts/design/casper-design/","65f"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/design/highway/",component:p("/1.5.X/concepts/design/highway/","174"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/design/networking-protocol/",component:p("/1.5.X/concepts/design/networking-protocol/","1fa"),exact:!0},{path:"/1.5.X/concepts/design/p2p/",component:p("/1.5.X/concepts/design/p2p/","955"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/",component:p("/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/","366"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/dictionaries/",component:p("/1.5.X/concepts/dictionaries/","192"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/economics/concepts/",component:p("/1.5.X/concepts/economics/concepts/","4cb"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/economics/consensus/",component:p("/1.5.X/concepts/economics/consensus/","016"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/economics/delegation/",component:p("/1.5.X/concepts/economics/delegation/","a09"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/economics/gas-concepts/",component:p("/1.5.X/concepts/economics/gas-concepts/","60a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/global-state/",component:p("/1.5.X/concepts/global-state/","47f"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/A/",component:p("/1.5.X/concepts/glossary/A/","391"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/B/",component:p("/1.5.X/concepts/glossary/B/","ff4"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/C/",component:p("/1.5.X/concepts/glossary/C/","680"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/D/",component:p("/1.5.X/concepts/glossary/D/","53a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/E/",component:p("/1.5.X/concepts/glossary/E/","0f3"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/F/",component:p("/1.5.X/concepts/glossary/F/","af6"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/G/",component:p("/1.5.X/concepts/glossary/G/","78b"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/H/",component:p("/1.5.X/concepts/glossary/H/","e95"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/I/",component:p("/1.5.X/concepts/glossary/I/","7bf"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/J/",component:p("/1.5.X/concepts/glossary/J/","1cd"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/K/",component:p("/1.5.X/concepts/glossary/K/","267"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/L/",component:p("/1.5.X/concepts/glossary/L/","9e1"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/M/",component:p("/1.5.X/concepts/glossary/M/","bce"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/N/",component:p("/1.5.X/concepts/glossary/N/","94a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/O/",component:p("/1.5.X/concepts/glossary/O/","af6"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/P/",component:p("/1.5.X/concepts/glossary/P/","4a5"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/Q/",component:p("/1.5.X/concepts/glossary/Q/","b85"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/R/",component:p("/1.5.X/concepts/glossary/R/","1c6"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/S/",component:p("/1.5.X/concepts/glossary/S/","e2b"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/T/",component:p("/1.5.X/concepts/glossary/T/","dd8"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/U/",component:p("/1.5.X/concepts/glossary/U/","b39"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/V/",component:p("/1.5.X/concepts/glossary/V/","46a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/W/",component:p("/1.5.X/concepts/glossary/W/","71a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/X/",component:p("/1.5.X/concepts/glossary/X/","c9c"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/Y/",component:p("/1.5.X/concepts/glossary/Y/","b6d"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/glossary/Z/",component:p("/1.5.X/concepts/glossary/Z/","43a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/hash-types/",component:p("/1.5.X/concepts/hash-types/","3a9"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/intro-to-dapps/",component:p("/1.5.X/concepts/intro-to-dapps/","d7f"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/list-auth-keys/",component:p("/1.5.X/concepts/list-auth-keys/","069"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/serialization-standard/",component:p("/1.5.X/concepts/serialization-standard/","a9a"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/concepts/smart-contracts/",component:p("/1.5.X/concepts/smart-contracts/","b11"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/counter-testnet/",component:p("/1.5.X/counter-testnet/","7af"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/counter/",component:p("/1.5.X/counter/","aa5"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/deploy-and-deploy-lifecycle/",component:p("/1.5.X/deploy-and-deploy-lifecycle/","599"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/design/",component:p("/1.5.X/design/","41f"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/developers/",component:p("/1.5.X/developers/","0cd"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/",component:p("/1.5.X/developers/cli/","a34"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/calling-contracts/",component:p("/1.5.X/developers/cli/calling-contracts/","06b"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/delegate/",component:p("/1.5.X/developers/cli/delegate/","0ce"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/execution-error-codes/",component:p("/1.5.X/developers/cli/execution-error-codes/","7b6"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/installing-contracts/",component:p("/1.5.X/developers/cli/installing-contracts/","e22"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/opcode-costs/",component:p("/1.5.X/developers/cli/opcode-costs/","196"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/querying-global-state/",component:p("/1.5.X/developers/cli/querying-global-state/","1aa"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/redelegate/",component:p("/1.5.X/developers/cli/redelegate/","bd7"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/sending-deploys/",component:p("/1.5.X/developers/cli/sending-deploys/","b22"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/transfers/",component:p("/1.5.X/developers/cli/transfers/","25e"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/transfers/direct-token-transfer/",component:p("/1.5.X/developers/cli/transfers/direct-token-transfer/","b8e"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/transfers/multisig-deploy-transfer/",component:p("/1.5.X/developers/cli/transfers/multisig-deploy-transfer/","685"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/transfers/verify-transfer/",component:p("/1.5.X/developers/cli/transfers/verify-transfer/","558"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/cli/undelegate/",component:p("/1.5.X/developers/cli/undelegate/","a29"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/",component:p("/1.5.X/developers/dapps/","56e"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/dapp/",component:p("/1.5.X/developers/dapps/dapp/","6f9"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/monitor-and-consume-events/",component:p("/1.5.X/developers/dapps/monitor-and-consume-events/","8bb"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/nctl-test/",component:p("/1.5.X/developers/dapps/nctl-test/","19a"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/prerequisites/",component:p("/1.5.X/developers/dapps/prerequisites/","1d2"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/sdk/client-library-usage/",component:p("/1.5.X/developers/dapps/sdk/client-library-usage/","416"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/sdk/csharp-sdk/",component:p("/1.5.X/developers/dapps/sdk/csharp-sdk/","417"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/sdk/go-sdk/",component:p("/1.5.X/developers/dapps/sdk/go-sdk/","1ae"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/sdk/python-sdk/",component:p("/1.5.X/developers/dapps/sdk/python-sdk/","828"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/sdk/script-sdk/",component:p("/1.5.X/developers/dapps/sdk/script-sdk/","639"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/setup-nctl/",component:p("/1.5.X/developers/dapps/setup-nctl/","341"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/signing-a-deploy/",component:p("/1.5.X/developers/dapps/signing-a-deploy/","5e8"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/speculative-exec/",component:p("/1.5.X/developers/dapps/speculative-exec/","612"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/technology-stack/",component:p("/1.5.X/developers/dapps/technology-stack/","8e6"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/template-frontend/",component:p("/1.5.X/developers/dapps/template-frontend/","106"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/dapps/uref-security/",component:p("/1.5.X/developers/dapps/uref-security/","511"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/essential-crates/",component:p("/1.5.X/developers/essential-crates/","ab9"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/",component:p("/1.5.X/developers/json-rpc/","fdb"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/errors/",component:p("/1.5.X/developers/json-rpc/errors/","79a"),exact:!0},{path:"/1.5.X/developers/json-rpc/guidance/",component:p("/1.5.X/developers/json-rpc/guidance/","387"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/json-rpc-informational/",component:p("/1.5.X/developers/json-rpc/json-rpc-informational/","fb7"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/json-rpc-pos/",component:p("/1.5.X/developers/json-rpc/json-rpc-pos/","6c1"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/json-rpc-transactional/",component:p("/1.5.X/developers/json-rpc/json-rpc-transactional/","c4f"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/minimal-compliance/",component:p("/1.5.X/developers/json-rpc/minimal-compliance/","e6b"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/types_chain/",component:p("/1.5.X/developers/json-rpc/types_chain/","28d"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/json-rpc/types_cl/",component:p("/1.5.X/developers/json-rpc/types_cl/","85a"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/prerequisites/",component:p("/1.5.X/developers/prerequisites/","b66"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/assembly-script/",component:p("/1.5.X/developers/writing-onchain-code/assembly-script/","56e"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/best-practices/",component:p("/1.5.X/developers/writing-onchain-code/best-practices/","fe4"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/calling-contracts/",component:p("/1.5.X/developers/writing-onchain-code/calling-contracts/","500"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:p("/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/","82a"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/contract-vs-session/",component:p("/1.5.X/developers/writing-onchain-code/contract-vs-session/","ee5"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/getting-started/",component:p("/1.5.X/developers/writing-onchain-code/getting-started/","b3f"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/simple-contract/",component:p("/1.5.X/developers/writing-onchain-code/simple-contract/","97d"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/testing-contracts/",component:p("/1.5.X/developers/writing-onchain-code/testing-contracts/","08d"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/testing-session-code/",component:p("/1.5.X/developers/writing-onchain-code/testing-session-code/","9b4"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/upgrading-contracts/",component:p("/1.5.X/developers/writing-onchain-code/upgrading-contracts/","e21"),exact:!0,sidebar:"developers"},{path:"/1.5.X/developers/writing-onchain-code/writing-session-code/",component:p("/1.5.X/developers/writing-onchain-code/writing-session-code/","887"),exact:!0,sidebar:"developers"},{path:"/1.5.X/disclaimer/",component:p("/1.5.X/disclaimer/","956"),exact:!0},{path:"/1.5.X/economics/",component:p("/1.5.X/economics/","e26"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/glossary/",component:p("/1.5.X/glossary/","fa3"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/operators/",component:p("/1.5.X/operators/","c91"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/becoming-a-validator/",component:p("/1.5.X/operators/becoming-a-validator/","f58"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/becoming-a-validator/bonding/",component:p("/1.5.X/operators/becoming-a-validator/bonding/","4d7"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/",component:p("/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/","92f"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/becoming-a-validator/recovering/",component:p("/1.5.X/operators/becoming-a-validator/recovering/","37b"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/becoming-a-validator/unbonding/",component:p("/1.5.X/operators/becoming-a-validator/unbonding/","110"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/maintenance/",component:p("/1.5.X/operators/maintenance/","8c1"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/maintenance/archiving-and-restoring/",component:p("/1.5.X/operators/maintenance/archiving-and-restoring/","976"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/maintenance/moving-node/",component:p("/1.5.X/operators/maintenance/moving-node/","b15"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup-network/",component:p("/1.5.X/operators/setup-network/","772"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup-network/chain-spec/",component:p("/1.5.X/operators/setup-network/chain-spec/","5d5"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup-network/create-private/",component:p("/1.5.X/operators/setup-network/create-private/","496"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup-network/genesis/",component:p("/1.5.X/operators/setup-network/genesis/","410"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup-network/staging-files-for-new-network/",component:p("/1.5.X/operators/setup-network/staging-files-for-new-network/","1cd"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/",component:p("/1.5.X/operators/setup/","557"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/basic-node-configuration/",component:p("/1.5.X/operators/setup/basic-node-configuration/","5d2"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/fast-sync/",component:p("/1.5.X/operators/setup/fast-sync/","bb1"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/hardware/",component:p("/1.5.X/operators/setup/hardware/","4b9"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/install-node/",component:p("/1.5.X/operators/setup/install-node/","b59"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/joining/",component:p("/1.5.X/operators/setup/joining/","0b4"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/node-endpoints/",component:p("/1.5.X/operators/setup/node-endpoints/","00e"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/non-root-user/",component:p("/1.5.X/operators/setup/non-root-user/","60b"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/open-files/",component:p("/1.5.X/operators/setup/open-files/","5f3"),exact:!0,sidebar:"operators"},{path:"/1.5.X/operators/setup/upgrade/",component:p("/1.5.X/operators/setup/upgrade/","be0"),exact:!0,sidebar:"operators"},{path:"/1.5.X/resources/",component:p("/1.5.X/resources/","581"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/advanced/list-auth-keys-tutorial/",component:p("/1.5.X/resources/advanced/list-auth-keys-tutorial/","8d4"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/advanced/multi-sig/",component:p("/1.5.X/resources/advanced/multi-sig/","e36"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/",component:p("/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/","f41"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/advanced/multi-sig/other-scenarios/",component:p("/1.5.X/resources/advanced/multi-sig/other-scenarios/","2c5"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter-testnet/commands/",component:p("/1.5.X/resources/beginner/counter-testnet/commands/","d06"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter-testnet/overview/",component:p("/1.5.X/resources/beginner/counter-testnet/overview/","d67"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter-testnet/walkthrough/",component:p("/1.5.X/resources/beginner/counter-testnet/walkthrough/","74f"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter/commands/",component:p("/1.5.X/resources/beginner/counter/commands/","156"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter/overview/",component:p("/1.5.X/resources/beginner/counter/overview/","e03"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/beginner/counter/walkthrough/",component:p("/1.5.X/resources/beginner/counter/walkthrough/","451"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/build-on-casper/casper-open-source-software/",component:p("/1.5.X/resources/build-on-casper/casper-open-source-software/","c75"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/build-on-casper/introduction/",component:p("/1.5.X/resources/build-on-casper/introduction/","9f0"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/condor-for-exchanges/",component:p("/1.5.X/resources/condor-for-exchanges/","59c"),exact:!0},{path:"/1.5.X/resources/moving-to-casper/",component:p("/1.5.X/resources/moving-to-casper/","594"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/quick-start/",component:p("/1.5.X/resources/quick-start/","a34"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tokens/",component:p("/1.5.X/resources/tokens/","98c"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep18/full-tutorial/",component:p("/1.5.X/resources/tokens/cep18/full-tutorial/","ab9"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep18/query/",component:p("/1.5.X/resources/tokens/cep18/query/","0b4"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep18/quickstart-guide/",component:p("/1.5.X/resources/tokens/cep18/quickstart-guide/","1fa"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep18/tests/",component:p("/1.5.X/resources/tokens/cep18/tests/","76b"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep18/transfer/",component:p("/1.5.X/resources/tokens/cep18/transfer/","fec"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/introduction/",component:p("/1.5.X/resources/tokens/cep78/introduction/","913"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/js-tutorial/",component:p("/1.5.X/resources/tokens/cep78/js-tutorial/","a05"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/modalities/",component:p("/1.5.X/resources/tokens/cep78/modalities/","4e3"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/reverse-lookup/",component:p("/1.5.X/resources/tokens/cep78/reverse-lookup/","c4f"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/",component:p("/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/","ccd"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/",component:p("/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/","399"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/",component:p("/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/","9f5"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/",component:p("/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/","8d9"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/",component:p("/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/","afc"),exact:!0,sidebar:"resources"},{path:"/1.5.X/resources/tutorials/advanced/",component:p("/1.5.X/resources/tutorials/advanced/","273"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/advanced/cross-contract/",component:p("/1.5.X/resources/tutorials/advanced/cross-contract/","f50"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/advanced/list-cspr/",component:p("/1.5.X/resources/tutorials/advanced/list-cspr/","1a8"),exact:!0},{path:"/1.5.X/resources/tutorials/advanced/return-values-tutorial/",component:p("/1.5.X/resources/tutorials/advanced/return-values-tutorial/","2df"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/advanced/storage-workflow/",component:p("/1.5.X/resources/tutorials/advanced/storage-workflow/","516"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/",component:p("/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/","56c"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/advanced/two-party-multi-sig/",component:p("/1.5.X/resources/tutorials/advanced/two-party-multi-sig/","261"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/",component:p("/1.5.X/resources/tutorials/beginner/","b26"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/aws-node/",component:p("/1.5.X/resources/tutorials/beginner/aws-node/","8f5"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/cep18/",component:p("/1.5.X/resources/tutorials/beginner/cep18/","3c4"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/getting-started-tutorial/",component:p("/1.5.X/resources/tutorials/beginner/getting-started-tutorial/","f2b"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/querying-network/",component:p("/1.5.X/resources/tutorials/beginner/querying-network/","569"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/resources/tutorials/beginner/upgrade-contract/",component:p("/1.5.X/resources/tutorials/beginner/upgrade-contract/","9ab"),exact:!0,sidebar:"tutorials"},{path:"/1.5.X/runtime/",component:p("/1.5.X/runtime/","60c"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/sdk/",component:p("/1.5.X/sdk/","d96"),exact:!0,sidebar:"developers"},{path:"/1.5.X/staking/",component:p("/1.5.X/staking/","a8d"),exact:!0,sidebar:"concepts"},{path:"/1.5.X/users/",component:p("/1.5.X/users/","d68"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/block-explorer/",component:p("/1.5.X/users/block-explorer/","c3e"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/csprlive/",component:p("/1.5.X/users/csprlive/","54f"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/delegate-ui/",component:p("/1.5.X/users/delegate-ui/","28d"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/funding-from-exchanges/",component:p("/1.5.X/users/funding-from-exchanges/","78b"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/ledger/",component:p("/1.5.X/users/ledger/","dac"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/ledger/ledger-cspr-live/",component:p("/1.5.X/users/ledger/ledger-cspr-live/","a78"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/ledger/ledger-live/",component:p("/1.5.X/users/ledger/ledger-live/","320"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/staking-ledger/",component:p("/1.5.X/users/staking-ledger/","6d4"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/testnet-faucet/",component:p("/1.5.X/users/testnet-faucet/","65e"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/token-transfer/",component:p("/1.5.X/users/token-transfer/","5a0"),exact:!0,sidebar:"users"},{path:"/1.5.X/users/undelegate-ui/",component:p("/1.5.X/users/undelegate-ui/","21f"),exact:!0,sidebar:"users"},{path:"/1.5.X/workflow/ledger-setup/",component:p("/1.5.X/workflow/ledger-setup/","388"),exact:!0,sidebar:"users"},{path:"/1.5.X/writing-contracts/",component:p("/1.5.X/writing-contracts/","5ba"),exact:!0,sidebar:"developers"}]}]},{path:"/2.0.0/",component:p("/2.0.0/","bbd"),routes:[{path:"/2.0.0/",component:p("/2.0.0/","028"),routes:[{path:"/2.0.0/",component:p("/2.0.0/","269"),exact:!0},{path:"/2.0.0/concepts/",component:p("/2.0.0/concepts/","5e5"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/about/",component:p("/2.0.0/concepts/about/","60d"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/accounts-and-keys/",component:p("/2.0.0/concepts/accounts-and-keys/","0bd"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/addressable-entity/",component:p("/2.0.0/concepts/addressable-entity/","8be"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/callstack/",component:p("/2.0.0/concepts/callstack/","9a4"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/casper-design/",component:p("/2.0.0/concepts/design/casper-design/","c92"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/consensus/",component:p("/2.0.0/concepts/design/consensus/","418"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/highway/",component:p("/2.0.0/concepts/design/highway/","fa0"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/networking-protocol/",component:p("/2.0.0/concepts/design/networking-protocol/","510"),exact:!0},{path:"/2.0.0/concepts/design/p2p/",component:p("/2.0.0/concepts/design/p2p/","a13"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/",component:p("/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/","366"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/rewards/",component:p("/2.0.0/concepts/design/rewards/","a13"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/design/zug/",component:p("/2.0.0/concepts/design/zug/","9a5"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/dictionaries/",component:p("/2.0.0/concepts/dictionaries/","045"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/economics/consensus/",component:p("/2.0.0/concepts/economics/consensus/","d42"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/economics/dynamic-gas-pricing/",component:p("/2.0.0/concepts/economics/dynamic-gas-pricing/","9b0"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/economics/fee-elimination/",component:p("/2.0.0/concepts/economics/fee-elimination/","2a4"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/economics/gas-concepts/",component:p("/2.0.0/concepts/economics/gas-concepts/","c40"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/economics/staking/",component:p("/2.0.0/concepts/economics/staking/","1da"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/global-state/",component:p("/2.0.0/concepts/global-state/","226"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/A/",component:p("/2.0.0/concepts/glossary/A/","510"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/B/",component:p("/2.0.0/concepts/glossary/B/","8a9"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/C/",component:p("/2.0.0/concepts/glossary/C/","a7e"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/D/",component:p("/2.0.0/concepts/glossary/D/","6fd"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/E/",component:p("/2.0.0/concepts/glossary/E/","ccb"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/F/",component:p("/2.0.0/concepts/glossary/F/","501"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/G/",component:p("/2.0.0/concepts/glossary/G/","343"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/H/",component:p("/2.0.0/concepts/glossary/H/","c5f"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/I/",component:p("/2.0.0/concepts/glossary/I/","ea0"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/J/",component:p("/2.0.0/concepts/glossary/J/","21b"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/K/",component:p("/2.0.0/concepts/glossary/K/","b63"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/L/",component:p("/2.0.0/concepts/glossary/L/","d8f"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/M/",component:p("/2.0.0/concepts/glossary/M/","525"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/N/",component:p("/2.0.0/concepts/glossary/N/","c39"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/O/",component:p("/2.0.0/concepts/glossary/O/","6ca"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/P/",component:p("/2.0.0/concepts/glossary/P/","f0f"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/Q/",component:p("/2.0.0/concepts/glossary/Q/","7fa"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/R/",component:p("/2.0.0/concepts/glossary/R/","57e"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/S/",component:p("/2.0.0/concepts/glossary/S/","c51"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/T/",component:p("/2.0.0/concepts/glossary/T/","0f0"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/U/",component:p("/2.0.0/concepts/glossary/U/","e0f"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/V/",component:p("/2.0.0/concepts/glossary/V/","041"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/W/",component:p("/2.0.0/concepts/glossary/W/","764"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/X/",component:p("/2.0.0/concepts/glossary/X/","b00"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/Y/",component:p("/2.0.0/concepts/glossary/Y/","e85"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/glossary/Z/",component:p("/2.0.0/concepts/glossary/Z/","30f"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/intro-to-dapps/",component:p("/2.0.0/concepts/intro-to-dapps/","53d"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/key-types/",component:p("/2.0.0/concepts/key-types/","df8"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/list-auth-keys/",component:p("/2.0.0/concepts/list-auth-keys/","136"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/serialization/",component:p("/2.0.0/concepts/serialization/","5be"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/serialization/primitives/",component:p("/2.0.0/concepts/serialization/primitives/","a66"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/serialization/structures/",component:p("/2.0.0/concepts/serialization/structures/","65c"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/serialization/types/",component:p("/2.0.0/concepts/serialization/types/","0c5"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/concepts/smart-contracts/",component:p("/2.0.0/concepts/smart-contracts/","aa4"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/counter-testnet/",component:p("/2.0.0/counter-testnet/","838"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/counter/",component:p("/2.0.0/counter/","0e7"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/design/",component:p("/2.0.0/design/","be5"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/developers/",component:p("/2.0.0/developers/","800"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/",component:p("/2.0.0/developers/cli/","74f"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/calling-contracts/",component:p("/2.0.0/developers/cli/calling-contracts/","b66"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/delegate/",component:p("/2.0.0/developers/cli/delegate/","11a"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/execution-error-codes/",component:p("/2.0.0/developers/cli/execution-error-codes/","a4e"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/installing-contracts/",component:p("/2.0.0/developers/cli/installing-contracts/","6dc"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/opcode-costs/",component:p("/2.0.0/developers/cli/opcode-costs/","624"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/querying-global-state/",component:p("/2.0.0/developers/cli/querying-global-state/","65a"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/redelegate/",component:p("/2.0.0/developers/cli/redelegate/","9aa"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/sending-transactions/",component:p("/2.0.0/developers/cli/sending-transactions/","8fb"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/transfers/",component:p("/2.0.0/developers/cli/transfers/","ebd"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/transfers/direct-token-transfer/",component:p("/2.0.0/developers/cli/transfers/direct-token-transfer/","f97"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/transfers/multisig-deploy-transfer/",component:p("/2.0.0/developers/cli/transfers/multisig-deploy-transfer/","0d2"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/transfers/verify-transfer/",component:p("/2.0.0/developers/cli/transfers/verify-transfer/","04e"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/undelegate/",component:p("/2.0.0/developers/cli/undelegate/","684"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/cli/verifying-contracts/",component:p("/2.0.0/developers/cli/verifying-contracts/","10a"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/",component:p("/2.0.0/developers/dapps/","ccf"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/dapp/",component:p("/2.0.0/developers/dapps/dapp/","961"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/monitor-and-consume-events/",component:p("/2.0.0/developers/dapps/monitor-and-consume-events/","812"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/nctl-test/",component:p("/2.0.0/developers/dapps/nctl-test/","869"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/prerequisites/",component:p("/2.0.0/developers/dapps/prerequisites/","cdd"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/sdk/client-library-usage/",component:p("/2.0.0/developers/dapps/sdk/client-library-usage/","cfc"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/sdk/csharp-sdk/",component:p("/2.0.0/developers/dapps/sdk/csharp-sdk/","4b4"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/sdk/go-sdk/",component:p("/2.0.0/developers/dapps/sdk/go-sdk/","b42"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/sdk/python-sdk/",component:p("/2.0.0/developers/dapps/sdk/python-sdk/","29b"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/sdk/script-sdk/",component:p("/2.0.0/developers/dapps/sdk/script-sdk/","f4d"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/setup-nctl/",component:p("/2.0.0/developers/dapps/setup-nctl/","b3b"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/signing-a-transaction/",component:p("/2.0.0/developers/dapps/signing-a-transaction/","bc5"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/speculative-exec/",component:p("/2.0.0/developers/dapps/speculative-exec/","86f"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/technology-stack/",component:p("/2.0.0/developers/dapps/technology-stack/","77a"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/template-frontend/",component:p("/2.0.0/developers/dapps/template-frontend/","550"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/dapps/uref-security/",component:p("/2.0.0/developers/dapps/uref-security/","226"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/essential-crates/",component:p("/2.0.0/developers/essential-crates/","a16"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/",component:p("/2.0.0/developers/json-rpc/","dd7"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/errors/",component:p("/2.0.0/developers/json-rpc/errors/","bff"),exact:!0},{path:"/2.0.0/developers/json-rpc/guidance/",component:p("/2.0.0/developers/json-rpc/guidance/","eb1"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/json-rpc-informational/",component:p("/2.0.0/developers/json-rpc/json-rpc-informational/","1ad"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/json-rpc-pos/",component:p("/2.0.0/developers/json-rpc/json-rpc-pos/","b71"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/json-rpc-transactional/",component:p("/2.0.0/developers/json-rpc/json-rpc-transactional/","19f"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/minimal-compliance/",component:p("/2.0.0/developers/json-rpc/minimal-compliance/","576"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/types_chain/",component:p("/2.0.0/developers/json-rpc/types_chain/","949"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/json-rpc/types_cl/",component:p("/2.0.0/developers/json-rpc/types_cl/","cd1"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/prerequisites/",component:p("/2.0.0/developers/prerequisites/","54d"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/assembly-script/",component:p("/2.0.0/developers/writing-onchain-code/assembly-script/","c62"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/best-practices/",component:p("/2.0.0/developers/writing-onchain-code/best-practices/","2b9"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/calling-contracts/",component:p("/2.0.0/developers/writing-onchain-code/calling-contracts/","aac"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:p("/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/","ff9"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/contract-vs-session/",component:p("/2.0.0/developers/writing-onchain-code/contract-vs-session/","2e1"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/emitting-contract-events/",component:p("/2.0.0/developers/writing-onchain-code/emitting-contract-events/","642"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/factory-pattern/",component:p("/2.0.0/developers/writing-onchain-code/factory-pattern/","63c"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/getting-started/",component:p("/2.0.0/developers/writing-onchain-code/getting-started/","8d6"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/simple-contract/",component:p("/2.0.0/developers/writing-onchain-code/simple-contract/","be0"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/testing-contracts/",component:p("/2.0.0/developers/writing-onchain-code/testing-contracts/","c60"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/testing-session-code/",component:p("/2.0.0/developers/writing-onchain-code/testing-session-code/","c7f"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/upgrading-contracts/",component:p("/2.0.0/developers/writing-onchain-code/upgrading-contracts/","b34"),exact:!0,sidebar:"developers"},{path:"/2.0.0/developers/writing-onchain-code/writing-session-code/",component:p("/2.0.0/developers/writing-onchain-code/writing-session-code/","30f"),exact:!0,sidebar:"developers"},{path:"/2.0.0/disclaimer/",component:p("/2.0.0/disclaimer/","159"),exact:!0},{path:"/2.0.0/economics/",component:p("/2.0.0/economics/","6f6"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/glossary/",component:p("/2.0.0/glossary/","d6c"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/operators/",component:p("/2.0.0/operators/","7f8"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/becoming-a-validator/",component:p("/2.0.0/operators/becoming-a-validator/","591"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/becoming-a-validator/bonding/",component:p("/2.0.0/operators/becoming-a-validator/bonding/","d91"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/becoming-a-validator/change-bid-public-key/",component:p("/2.0.0/operators/becoming-a-validator/change-bid-public-key/","4e9"),exact:!0},{path:"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/",component:p("/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/","5c5"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/becoming-a-validator/recovering/",component:p("/2.0.0/operators/becoming-a-validator/recovering/","dfe"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/becoming-a-validator/unbonding/",component:p("/2.0.0/operators/becoming-a-validator/unbonding/","451"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/maintenance/",component:p("/2.0.0/operators/maintenance/","652"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/maintenance/archiving-and-restoring/",component:p("/2.0.0/operators/maintenance/archiving-and-restoring/","f78"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/maintenance/moving-node/",component:p("/2.0.0/operators/maintenance/moving-node/","cd8"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup-network/",component:p("/2.0.0/operators/setup-network/","fce"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup-network/chain-spec/",component:p("/2.0.0/operators/setup-network/chain-spec/","064"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup-network/create-private/",component:p("/2.0.0/operators/setup-network/create-private/","13a"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup-network/genesis/",component:p("/2.0.0/operators/setup-network/genesis/","46e"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup-network/staging-files-for-new-network/",component:p("/2.0.0/operators/setup-network/staging-files-for-new-network/","2af"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/",component:p("/2.0.0/operators/setup/","e68"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/basic-node-configuration/",component:p("/2.0.0/operators/setup/basic-node-configuration/","88d"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/casper-sidecar/",component:p("/2.0.0/operators/setup/casper-sidecar/","44a"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/fast-sync/",component:p("/2.0.0/operators/setup/fast-sync/","5f7"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/hardware/",component:p("/2.0.0/operators/setup/hardware/","4a2"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/install-node/",component:p("/2.0.0/operators/setup/install-node/","bb5"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/joining/",component:p("/2.0.0/operators/setup/joining/","f93"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/node-endpoints/",component:p("/2.0.0/operators/setup/node-endpoints/","d07"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/node-events/",component:p("/2.0.0/operators/setup/node-events/","24f"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/non-root-user/",component:p("/2.0.0/operators/setup/non-root-user/","122"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/open-files/",component:p("/2.0.0/operators/setup/open-files/","b36"),exact:!0,sidebar:"operators"},{path:"/2.0.0/operators/setup/upgrade/",component:p("/2.0.0/operators/setup/upgrade/","eb8"),exact:!0,sidebar:"operators"},{path:"/2.0.0/resources/",component:p("/2.0.0/resources/","2aa"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/advanced/list-auth-keys-tutorial/",component:p("/2.0.0/resources/advanced/list-auth-keys-tutorial/","4e9"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/advanced/multi-sig/",component:p("/2.0.0/resources/advanced/multi-sig/","ed1"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/",component:p("/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/","eb3"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/advanced/multi-sig/other-scenarios/",component:p("/2.0.0/resources/advanced/multi-sig/other-scenarios/","240"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter-testnet/commands/",component:p("/2.0.0/resources/beginner/counter-testnet/commands/","47e"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter-testnet/overview/",component:p("/2.0.0/resources/beginner/counter-testnet/overview/","2c2"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter-testnet/walkthrough/",component:p("/2.0.0/resources/beginner/counter-testnet/walkthrough/","385"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter/commands/",component:p("/2.0.0/resources/beginner/counter/commands/","f18"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter/overview/",component:p("/2.0.0/resources/beginner/counter/overview/","809"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/beginner/counter/walkthrough/",component:p("/2.0.0/resources/beginner/counter/walkthrough/","147"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/build-on-casper/casper-open-source-software/",component:p("/2.0.0/resources/build-on-casper/casper-open-source-software/","c9f"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/build-on-casper/introduction/",component:p("/2.0.0/resources/build-on-casper/introduction/","e41"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/changelog/",component:p("/2.0.0/resources/changelog/","620"),exact:!0},{path:"/2.0.0/resources/moving-to-casper/",component:p("/2.0.0/resources/moving-to-casper/","3a2"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/quick-start/",component:p("/2.0.0/resources/quick-start/","4bf"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tokens/",component:p("/2.0.0/resources/tokens/","7b5"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep18/full-tutorial/",component:p("/2.0.0/resources/tokens/cep18/full-tutorial/","a48"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep18/query/",component:p("/2.0.0/resources/tokens/cep18/query/","ee8"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep18/quickstart-guide/",component:p("/2.0.0/resources/tokens/cep18/quickstart-guide/","197"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep18/tests/",component:p("/2.0.0/resources/tokens/cep18/tests/","1dc"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep18/transfer/",component:p("/2.0.0/resources/tokens/cep18/transfer/","ff2"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep78/introduction/",component:p("/2.0.0/resources/tokens/cep78/introduction/","0cb"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep78/js-tutorial/",component:p("/2.0.0/resources/tokens/cep78/js-tutorial/","54b"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep78/modalities/",component:p("/2.0.0/resources/tokens/cep78/modalities/","e9f"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/cep78/reverse-lookup/",component:p("/2.0.0/resources/tokens/cep78/reverse-lookup/","ae0"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tokens/using-casper-client/",component:p("/2.0.0/resources/tokens/using-casper-client/","1cf"),exact:!0,sidebar:"resources"},{path:"/2.0.0/resources/tutorials/advanced/",component:p("/2.0.0/resources/tutorials/advanced/","107"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/advanced/cross-contract/",component:p("/2.0.0/resources/tutorials/advanced/cross-contract/","303"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/advanced/list-cspr/",component:p("/2.0.0/resources/tutorials/advanced/list-cspr/","f1a"),exact:!0},{path:"/2.0.0/resources/tutorials/advanced/return-values-tutorial/",component:p("/2.0.0/resources/tutorials/advanced/return-values-tutorial/","1ef"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/advanced/storage-workflow/",component:p("/2.0.0/resources/tutorials/advanced/storage-workflow/","0df"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/",component:p("/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/","546"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/advanced/two-party-multi-sig/",component:p("/2.0.0/resources/tutorials/advanced/two-party-multi-sig/","cf3"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/",component:p("/2.0.0/resources/tutorials/beginner/","dbf"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/aws-node/",component:p("/2.0.0/resources/tutorials/beginner/aws-node/","867"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/cep18/",component:p("/2.0.0/resources/tutorials/beginner/cep18/","e69"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/getting-started-tutorial/",component:p("/2.0.0/resources/tutorials/beginner/getting-started-tutorial/","bbf"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/querying-network/",component:p("/2.0.0/resources/tutorials/beginner/querying-network/","7d3"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/resources/tutorials/beginner/upgrade-contract/",component:p("/2.0.0/resources/tutorials/beginner/upgrade-contract/","2b9"),exact:!0,sidebar:"tutorials"},{path:"/2.0.0/runtime/",component:p("/2.0.0/runtime/","6c9"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/sdk/",component:p("/2.0.0/sdk/","34a"),exact:!0,sidebar:"developers"},{path:"/2.0.0/transactions-and-transaction-lifecycle/",component:p("/2.0.0/transactions-and-transaction-lifecycle/","34d"),exact:!0,sidebar:"concepts"},{path:"/2.0.0/transactions/",component:p("/2.0.0/transactions/","a3e"),exact:!0},{path:"/2.0.0/users/",component:p("/2.0.0/users/","be6"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/block-explorer/",component:p("/2.0.0/users/block-explorer/","733"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/csprlive/",component:p("/2.0.0/users/csprlive/","04a"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/delegate-ui/",component:p("/2.0.0/users/delegate-ui/","d92"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/delegating/",component:p("/2.0.0/users/delegating/","379"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/funding-from-exchanges/",component:p("/2.0.0/users/funding-from-exchanges/","ff7"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/ledger/",component:p("/2.0.0/users/ledger/","cfa"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/ledger/ledger-cspr-live/",component:p("/2.0.0/users/ledger/ledger-cspr-live/","9aa"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/ledger/ledger-live/",component:p("/2.0.0/users/ledger/ledger-live/","56b"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/staking-ledger/",component:p("/2.0.0/users/staking-ledger/","e96"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/testnet-faucet/",component:p("/2.0.0/users/testnet-faucet/","8bf"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/token-transfer/",component:p("/2.0.0/users/token-transfer/","f77"),exact:!0,sidebar:"users"},{path:"/2.0.0/users/undelegate-ui/",component:p("/2.0.0/users/undelegate-ui/","d21"),exact:!0,sidebar:"users"},{path:"/2.0.0/workflow/ledger-setup/",component:p("/2.0.0/workflow/ledger-setup/","2cd"),exact:!0,sidebar:"users"},{path:"/2.0.0/writing-contracts/",component:p("/2.0.0/writing-contracts/","908"),exact:!0,sidebar:"developers"}]}]},{path:"/",component:p("/","d96"),routes:[{path:"/",component:p("/","bf8"),routes:[{path:"/concepts/",component:p("/concepts/","478"),exact:!0,sidebar:"concepts"},{path:"/concepts/about/",component:p("/concepts/about/","690"),exact:!0,sidebar:"concepts"},{path:"/concepts/accounts-and-keys/",component:p("/concepts/accounts-and-keys/","31f"),exact:!0,sidebar:"concepts"},{path:"/concepts/addressable-entity/",component:p("/concepts/addressable-entity/","546"),exact:!0,sidebar:"concepts"},{path:"/concepts/callstack/",component:p("/concepts/callstack/","442"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/casper-design/",component:p("/concepts/design/casper-design/","37d"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/consensus/",component:p("/concepts/design/consensus/","10b"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/highway/",component:p("/concepts/design/highway/","575"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/networking-protocol/",component:p("/concepts/design/networking-protocol/","47d"),exact:!0},{path:"/concepts/design/p2p/",component:p("/concepts/design/p2p/","b2f"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/reading-and-writing-to-the-blockchain/",component:p("/concepts/design/reading-and-writing-to-the-blockchain/","4ae"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/rewards/",component:p("/concepts/design/rewards/","fb4"),exact:!0,sidebar:"concepts"},{path:"/concepts/design/zug/",component:p("/concepts/design/zug/","119"),exact:!0,sidebar:"concepts"},{path:"/concepts/dictionaries/",component:p("/concepts/dictionaries/","acb"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/consensus/",component:p("/concepts/economics/consensus/","7dc"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/dynamic-gas-pricing/",component:p("/concepts/economics/dynamic-gas-pricing/","6fb"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/fee-elimination/",component:p("/concepts/economics/fee-elimination/","8ef"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/gas-concepts/",component:p("/concepts/economics/gas-concepts/","776"),exact:!0,sidebar:"concepts"},{path:"/concepts/economics/staking/",component:p("/concepts/economics/staking/","e62"),exact:!0,sidebar:"concepts"},{path:"/concepts/global-state/",component:p("/concepts/global-state/","af6"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/A/",component:p("/concepts/glossary/A/","005"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/B/",component:p("/concepts/glossary/B/","e82"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/C/",component:p("/concepts/glossary/C/","d64"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/D/",component:p("/concepts/glossary/D/","99f"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/E/",component:p("/concepts/glossary/E/","779"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/F/",component:p("/concepts/glossary/F/","491"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/G/",component:p("/concepts/glossary/G/","6a1"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/H/",component:p("/concepts/glossary/H/","d67"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/I/",component:p("/concepts/glossary/I/","e1a"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/J/",component:p("/concepts/glossary/J/","179"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/K/",component:p("/concepts/glossary/K/","919"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/L/",component:p("/concepts/glossary/L/","78d"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/M/",component:p("/concepts/glossary/M/","792"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/N/",component:p("/concepts/glossary/N/","bcf"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/O/",component:p("/concepts/glossary/O/","445"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/P/",component:p("/concepts/glossary/P/","3f8"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Q/",component:p("/concepts/glossary/Q/","a32"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/R/",component:p("/concepts/glossary/R/","6d3"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/S/",component:p("/concepts/glossary/S/","ad0"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/T/",component:p("/concepts/glossary/T/","97c"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/U/",component:p("/concepts/glossary/U/","fc5"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/V/",component:p("/concepts/glossary/V/","e4f"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/W/",component:p("/concepts/glossary/W/","872"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/X/",component:p("/concepts/glossary/X/","097"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Y/",component:p("/concepts/glossary/Y/","157"),exact:!0,sidebar:"concepts"},{path:"/concepts/glossary/Z/",component:p("/concepts/glossary/Z/","6de"),exact:!0,sidebar:"concepts"},{path:"/concepts/intro-to-dapps/",component:p("/concepts/intro-to-dapps/","a56"),exact:!0,sidebar:"concepts"},{path:"/concepts/key-types/",component:p("/concepts/key-types/","e8c"),exact:!0,sidebar:"concepts"},{path:"/concepts/list-auth-keys/",component:p("/concepts/list-auth-keys/","3f0"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization/",component:p("/concepts/serialization/","d4a"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization/primitives/",component:p("/concepts/serialization/primitives/","d90"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization/structures/",component:p("/concepts/serialization/structures/","0ad"),exact:!0,sidebar:"concepts"},{path:"/concepts/serialization/types/",component:p("/concepts/serialization/types/","3fe"),exact:!0,sidebar:"concepts"},{path:"/concepts/smart-contracts/",component:p("/concepts/smart-contracts/","b31"),exact:!0,sidebar:"concepts"},{path:"/counter-testnet/",component:p("/counter-testnet/","262"),exact:!0,sidebar:"tutorials"},{path:"/counter/",component:p("/counter/","c46"),exact:!0,sidebar:"tutorials"},{path:"/design/",component:p("/design/","52f"),exact:!0,sidebar:"concepts"},{path:"/developers/",component:p("/developers/","d10"),exact:!0,sidebar:"developers"},{path:"/developers/cli/",component:p("/developers/cli/","0e2"),exact:!0,sidebar:"developers"},{path:"/developers/cli/calling-contracts/",component:p("/developers/cli/calling-contracts/","ee1"),exact:!0,sidebar:"developers"},{path:"/developers/cli/delegate/",component:p("/developers/cli/delegate/","062"),exact:!0,sidebar:"developers"},{path:"/developers/cli/execution-error-codes/",component:p("/developers/cli/execution-error-codes/","370"),exact:!0,sidebar:"developers"},{path:"/developers/cli/installing-contracts/",component:p("/developers/cli/installing-contracts/","7a6"),exact:!0,sidebar:"developers"},{path:"/developers/cli/opcode-costs/",component:p("/developers/cli/opcode-costs/","dbe"),exact:!0,sidebar:"developers"},{path:"/developers/cli/querying-global-state/",component:p("/developers/cli/querying-global-state/","c3c"),exact:!0,sidebar:"developers"},{path:"/developers/cli/redelegate/",component:p("/developers/cli/redelegate/","124"),exact:!0,sidebar:"developers"},{path:"/developers/cli/sending-transactions/",component:p("/developers/cli/sending-transactions/","820"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/",component:p("/developers/cli/transfers/","f71"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/direct-token-transfer/",component:p("/developers/cli/transfers/direct-token-transfer/","4e8"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/multisig-deploy-transfer/",component:p("/developers/cli/transfers/multisig-deploy-transfer/","c03"),exact:!0,sidebar:"developers"},{path:"/developers/cli/transfers/verify-transfer/",component:p("/developers/cli/transfers/verify-transfer/","ad4"),exact:!0,sidebar:"developers"},{path:"/developers/cli/undelegate/",component:p("/developers/cli/undelegate/","9e2"),exact:!0,sidebar:"developers"},{path:"/developers/cli/verifying-contracts/",component:p("/developers/cli/verifying-contracts/","099"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/",component:p("/developers/dapps/","8c0"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/dapp/",component:p("/developers/dapps/dapp/","0b8"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/monitor-and-consume-events/",component:p("/developers/dapps/monitor-and-consume-events/","f8f"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/nctl-test/",component:p("/developers/dapps/nctl-test/","380"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/prerequisites/",component:p("/developers/dapps/prerequisites/","ac3"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/client-library-usage/",component:p("/developers/dapps/sdk/client-library-usage/","3e7"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/csharp-sdk/",component:p("/developers/dapps/sdk/csharp-sdk/","43a"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/go-sdk/",component:p("/developers/dapps/sdk/go-sdk/","743"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/python-sdk/",component:p("/developers/dapps/sdk/python-sdk/","2b8"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/sdk/script-sdk/",component:p("/developers/dapps/sdk/script-sdk/","d81"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/setup-nctl/",component:p("/developers/dapps/setup-nctl/","685"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/signing-a-transaction/",component:p("/developers/dapps/signing-a-transaction/","62a"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/speculative-exec/",component:p("/developers/dapps/speculative-exec/","9a4"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/technology-stack/",component:p("/developers/dapps/technology-stack/","923"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/template-frontend/",component:p("/developers/dapps/template-frontend/","7cf"),exact:!0,sidebar:"developers"},{path:"/developers/dapps/uref-security/",component:p("/developers/dapps/uref-security/","94b"),exact:!0,sidebar:"developers"},{path:"/developers/essential-crates/",component:p("/developers/essential-crates/","b0d"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/",component:p("/developers/json-rpc/","ce3"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/errors/",component:p("/developers/json-rpc/errors/","907"),exact:!0},{path:"/developers/json-rpc/guidance/",component:p("/developers/json-rpc/guidance/","a0f"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-informational/",component:p("/developers/json-rpc/json-rpc-informational/","81d"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-pos/",component:p("/developers/json-rpc/json-rpc-pos/","453"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/json-rpc-transactional/",component:p("/developers/json-rpc/json-rpc-transactional/","f46"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/minimal-compliance/",component:p("/developers/json-rpc/minimal-compliance/","a83"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_chain/",component:p("/developers/json-rpc/types_chain/","45b"),exact:!0,sidebar:"developers"},{path:"/developers/json-rpc/types_cl/",component:p("/developers/json-rpc/types_cl/","057"),exact:!0,sidebar:"developers"},{path:"/developers/prerequisites/",component:p("/developers/prerequisites/","061"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/assembly-script/",component:p("/developers/writing-onchain-code/assembly-script/","145"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/best-practices/",component:p("/developers/writing-onchain-code/best-practices/","3f7"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/calling-contracts/",component:p("/developers/writing-onchain-code/calling-contracts/","639"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-hash-vs-package-hash/",component:p("/developers/writing-onchain-code/contract-hash-vs-package-hash/","4e1"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/contract-vs-session/",component:p("/developers/writing-onchain-code/contract-vs-session/","da0"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/emitting-contract-events/",component:p("/developers/writing-onchain-code/emitting-contract-events/","56b"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/factory-pattern/",component:p("/developers/writing-onchain-code/factory-pattern/","a2a"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/getting-started/",component:p("/developers/writing-onchain-code/getting-started/","7fb"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/simple-contract/",component:p("/developers/writing-onchain-code/simple-contract/","e80"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-contracts/",component:p("/developers/writing-onchain-code/testing-contracts/","a8c"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/testing-session-code/",component:p("/developers/writing-onchain-code/testing-session-code/","a87"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/upgrading-contracts/",component:p("/developers/writing-onchain-code/upgrading-contracts/","e41"),exact:!0,sidebar:"developers"},{path:"/developers/writing-onchain-code/writing-session-code/",component:p("/developers/writing-onchain-code/writing-session-code/","c4f"),exact:!0,sidebar:"developers"},{path:"/disclaimer/",component:p("/disclaimer/","70f"),exact:!0},{path:"/economics/",component:p("/economics/","dd5"),exact:!0,sidebar:"concepts"},{path:"/glossary/",component:p("/glossary/","8b4"),exact:!0,sidebar:"concepts"},{path:"/operators/",component:p("/operators/","8ec"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/",component:p("/operators/becoming-a-validator/","09d"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/bonding/",component:p("/operators/becoming-a-validator/bonding/","5d8"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/change-bid-public-key/",component:p("/operators/becoming-a-validator/change-bid-public-key/","d51"),exact:!0},{path:"/operators/becoming-a-validator/inactive-vs-faulty/",component:p("/operators/becoming-a-validator/inactive-vs-faulty/","bde"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/recovering/",component:p("/operators/becoming-a-validator/recovering/","22d"),exact:!0,sidebar:"operators"},{path:"/operators/becoming-a-validator/unbonding/",component:p("/operators/becoming-a-validator/unbonding/","ff4"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/",component:p("/operators/maintenance/","059"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/archiving-and-restoring/",component:p("/operators/maintenance/archiving-and-restoring/","67c"),exact:!0,sidebar:"operators"},{path:"/operators/maintenance/moving-node/",component:p("/operators/maintenance/moving-node/","931"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/",component:p("/operators/setup-network/","ebd"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/chain-spec/",component:p("/operators/setup-network/chain-spec/","a86"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/create-private/",component:p("/operators/setup-network/create-private/","c58"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/genesis/",component:p("/operators/setup-network/genesis/","612"),exact:!0,sidebar:"operators"},{path:"/operators/setup-network/staging-files-for-new-network/",component:p("/operators/setup-network/staging-files-for-new-network/","9e9"),exact:!0,sidebar:"operators"},{path:"/operators/setup/",component:p("/operators/setup/","fe8"),exact:!0,sidebar:"operators"},{path:"/operators/setup/basic-node-configuration/",component:p("/operators/setup/basic-node-configuration/","638"),exact:!0,sidebar:"operators"},{path:"/operators/setup/casper-sidecar/",component:p("/operators/setup/casper-sidecar/","865"),exact:!0,sidebar:"operators"},{path:"/operators/setup/fast-sync/",component:p("/operators/setup/fast-sync/","c40"),exact:!0,sidebar:"operators"},{path:"/operators/setup/hardware/",component:p("/operators/setup/hardware/","296"),exact:!0,sidebar:"operators"},{path:"/operators/setup/install-node/",component:p("/operators/setup/install-node/","b2e"),exact:!0,sidebar:"operators"},{path:"/operators/setup/joining/",component:p("/operators/setup/joining/","821"),exact:!0,sidebar:"operators"},{path:"/operators/setup/node-endpoints/",component:p("/operators/setup/node-endpoints/","58f"),exact:!0,sidebar:"operators"},{path:"/operators/setup/node-events/",component:p("/operators/setup/node-events/","cbf"),exact:!0,sidebar:"operators"},{path:"/operators/setup/non-root-user/",component:p("/operators/setup/non-root-user/","bd6"),exact:!0,sidebar:"operators"},{path:"/operators/setup/open-files/",component:p("/operators/setup/open-files/","de5"),exact:!0,sidebar:"operators"},{path:"/operators/setup/upgrade/",component:p("/operators/setup/upgrade/","d73"),exact:!0,sidebar:"operators"},{path:"/resources/",component:p("/resources/","c8c"),exact:!0,sidebar:"resources"},{path:"/resources/advanced/list-auth-keys-tutorial/",component:p("/resources/advanced/list-auth-keys-tutorial/","b65"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/",component:p("/resources/advanced/multi-sig/","5fe"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/multi-sig-workflow/",component:p("/resources/advanced/multi-sig/multi-sig-workflow/","c3b"),exact:!0,sidebar:"tutorials"},{path:"/resources/advanced/multi-sig/other-scenarios/",component:p("/resources/advanced/multi-sig/other-scenarios/","b05"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/commands/",component:p("/resources/beginner/counter-testnet/commands/","110"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/overview/",component:p("/resources/beginner/counter-testnet/overview/","a44"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter-testnet/walkthrough/",component:p("/resources/beginner/counter-testnet/walkthrough/","ece"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/commands/",component:p("/resources/beginner/counter/commands/","869"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/overview/",component:p("/resources/beginner/counter/overview/","061"),exact:!0,sidebar:"tutorials"},{path:"/resources/beginner/counter/walkthrough/",component:p("/resources/beginner/counter/walkthrough/","7f1"),exact:!0,sidebar:"tutorials"},{path:"/resources/build-on-casper/casper-open-source-software/",component:p("/resources/build-on-casper/casper-open-source-software/","9c4"),exact:!0,sidebar:"resources"},{path:"/resources/build-on-casper/introduction/",component:p("/resources/build-on-casper/introduction/","7a5"),exact:!0,sidebar:"resources"},{path:"/resources/changelog/",component:p("/resources/changelog/","538"),exact:!0},{path:"/resources/moving-to-casper/",component:p("/resources/moving-to-casper/","9bf"),exact:!0,sidebar:"resources"},{path:"/resources/quick-start/",component:p("/resources/quick-start/","1dd"),exact:!0,sidebar:"tutorials"},{path:"/resources/tokens/",component:p("/resources/tokens/","1d2"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/full-tutorial/",component:p("/resources/tokens/cep18/full-tutorial/","136"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/query/",component:p("/resources/tokens/cep18/query/","845"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/quickstart-guide/",component:p("/resources/tokens/cep18/quickstart-guide/","42b"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/tests/",component:p("/resources/tokens/cep18/tests/","6e0"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep18/transfer/",component:p("/resources/tokens/cep18/transfer/","dc0"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/introduction/",component:p("/resources/tokens/cep78/introduction/","669"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/js-tutorial/",component:p("/resources/tokens/cep78/js-tutorial/","e2c"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/modalities/",component:p("/resources/tokens/cep78/modalities/","928"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/cep78/reverse-lookup/",component:p("/resources/tokens/cep78/reverse-lookup/","dbb"),exact:!0,sidebar:"resources"},{path:"/resources/tokens/using-casper-client/",component:p("/resources/tokens/using-casper-client/","70a"),exact:!0,sidebar:"resources"},{path:"/resources/tutorials/advanced/",component:p("/resources/tutorials/advanced/","8e2"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/cross-contract/",component:p("/resources/tutorials/advanced/cross-contract/","ddd"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/list-cspr/",component:p("/resources/tutorials/advanced/list-cspr/","1af"),exact:!0},{path:"/resources/tutorials/advanced/return-values-tutorial/",component:p("/resources/tutorials/advanced/return-values-tutorial/","323"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/storage-workflow/",component:p("/resources/tutorials/advanced/storage-workflow/","611"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/transfer-token-to-contract/",component:p("/resources/tutorials/advanced/transfer-token-to-contract/","8dd"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/advanced/two-party-multi-sig/",component:p("/resources/tutorials/advanced/two-party-multi-sig/","1c6"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/",component:p("/resources/tutorials/beginner/","0fa"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/aws-node/",component:p("/resources/tutorials/beginner/aws-node/","f28"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/cep18/",component:p("/resources/tutorials/beginner/cep18/","47e"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/getting-started-tutorial/",component:p("/resources/tutorials/beginner/getting-started-tutorial/","e6b"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/querying-network/",component:p("/resources/tutorials/beginner/querying-network/","80d"),exact:!0,sidebar:"tutorials"},{path:"/resources/tutorials/beginner/upgrade-contract/",component:p("/resources/tutorials/beginner/upgrade-contract/","647"),exact:!0,sidebar:"tutorials"},{path:"/runtime/",component:p("/runtime/","c35"),exact:!0,sidebar:"concepts"},{path:"/sdk/",component:p("/sdk/","4f6"),exact:!0,sidebar:"developers"},{path:"/transactions-and-transaction-lifecycle/",component:p("/transactions-and-transaction-lifecycle/","1f4"),exact:!0,sidebar:"concepts"},{path:"/transactions/",component:p("/transactions/","e9e"),exact:!0},{path:"/users/",component:p("/users/","a55"),exact:!0,sidebar:"users"},{path:"/users/block-explorer/",component:p("/users/block-explorer/","e55"),exact:!0,sidebar:"users"},{path:"/users/csprlive/",component:p("/users/csprlive/","e85"),exact:!0,sidebar:"users"},{path:"/users/delegate-ui/",component:p("/users/delegate-ui/","2cb"),exact:!0,sidebar:"users"},{path:"/users/delegating/",component:p("/users/delegating/","214"),exact:!0,sidebar:"users"},{path:"/users/funding-from-exchanges/",component:p("/users/funding-from-exchanges/","979"),exact:!0,sidebar:"users"},{path:"/users/ledger/",component:p("/users/ledger/","06e"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-cspr-live/",component:p("/users/ledger/ledger-cspr-live/","93d"),exact:!0,sidebar:"users"},{path:"/users/ledger/ledger-live/",component:p("/users/ledger/ledger-live/","d19"),exact:!0,sidebar:"users"},{path:"/users/staking-ledger/",component:p("/users/staking-ledger/","198"),exact:!0,sidebar:"users"},{path:"/users/testnet-faucet/",component:p("/users/testnet-faucet/","6f0"),exact:!0,sidebar:"users"},{path:"/users/token-transfer/",component:p("/users/token-transfer/","e4a"),exact:!0,sidebar:"users"},{path:"/users/undelegate-ui/",component:p("/users/undelegate-ui/","7b8"),exact:!0,sidebar:"users"},{path:"/workflow/ledger-setup/",component:p("/workflow/ledger-setup/","5c0"),exact:!0,sidebar:"users"},{path:"/writing-contracts/",component:p("/writing-contracts/","93e"),exact:!0,sidebar:"developers"},{path:"/",component:p("/","214"),exact:!0}]}]}]},{path:"*",component:p("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>s,x:()=>a});var r=n(96540),o=n(74848);const s=r.createContext(!1);function a(e){let{children:t}=e;const[n,a]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{a(!0)}),[]),(0,o.jsx)(s.Provider,{value:n,children:t})}},38536:(e,t,n)=>{"use strict";var r=n(96540),o=n(5338),s=n(80545),a=n(54625),i=n(4784),c=n(38193);const l=[n(10119),n(26134),n(76294),n(51043)];var d=n(35947),p=n(56347),u=n(22831),f=n(74848);function g(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var m=n(5260),h=n(44586),b=n(86025),v=n(6342),y=n(45500),w=n(32131),_=n(14090),k=n(2967),x=n(70440),S=n(41463);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.A)(),r=(0,w.o)(),o=n[e].htmlLang,s=e=>e.replace("-","_");return(0,f.jsxs)(m.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:s(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:s(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function j(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.A)(),{pathname:r}=(0,p.zy)();return e+(0,x.Ks)((0,b.Ay)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,f.jsxs)(m.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:o}),(0,f.jsx)("link",{rel:"canonical",href:o})]})}function X(){const{i18n:{currentLocale:e}}=(0,h.A)(),{metadata:t,image:n}=(0,v.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(m.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:_.w})]}),n&&(0,f.jsx)(y.be,{image:n}),(0,f.jsx)(j,{}),(0,f.jsx)(E,{}),(0,f.jsx)(S.A,{tag:k.C,locale:e}),(0,f.jsx)(m.A,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const C=new Map;var T=n(6125),A=n(26988),R=n(205);function P(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r<t;r++)n[r-1]=arguments[r];const o=l.map((t=>{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,R.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,s=t.search===n.search;if(r&&o&&!s)return;const{hash:a}=t;if(a){const e=decodeURIComponent(a.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),P("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function L(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,u.u)(d.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class O extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=c.A.canUseDOM?P("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=P("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),L(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(p.qh,{location:t,render:()=>e})})}}const D=O,I="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",F="__docusaurus-base-url-issue-banner-suggestion-container";function z(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${I}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n<div id="${M}" style="border: thick solid red; background-color: rgb(255, 230, 179); margin: 20px; padding: 20px; font-size: 20px;">\n <p style="font-weight: bold; font-size: 30px;">Your Docusaurus site did not load properly.</p>\n <p>A very common reason is a wrong site <a href="https://docusaurus.io/docs/docusaurus.config.js/#baseUrl" style="font-weight: bold;">baseUrl configuration</a>.</p>\n <p>Current configured baseUrl = <span style="font-weight: bold; color: red;">${e}</span> ${"/"===e?" (default value)":""}</p>\n <p>We suggest trying baseUrl = <span id="${F}" style="font-weight: bold; color: green;"></span></p>\n</div>\n`}(e)).replace(/</g,"\\<")};\n bannerContainer.innerHTML = bannerHtml;\n document.body.prepend(bannerContainer);\n var suggestionContainer = document.getElementById('${F}');\n var actualHomePagePath = window.location.pathname;\n var suggestedBaseUrl = actualHomePagePath.substr(-1) === '/'\n ? actualHomePagePath\n : actualHomePagePath + '/';\n suggestionContainer.innerHTML = suggestedBaseUrl;\n}\n`}function B(){const{siteConfig:{baseUrl:e}}=(0,h.A)();return(0,f.jsx)(f.Fragment,{children:!c.A.canUseDOM&&(0,f.jsx)(m.A,{children:(0,f.jsx)("script",{children:z(e)})})})}function q(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,h.A)(),{pathname:n}=(0,p.zy)();return t&&n===e?(0,f.jsx)(B,{}):null}function U(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:r,localeConfigs:o}}=(0,h.A)(),s=(0,b.Ay)(e),{htmlLang:a,direction:i}=o[r];return(0,f.jsxs)(m.A,{children:[(0,f.jsx)("html",{lang:a,dir:i}),(0,f.jsx)("title",{children:t}),(0,f.jsx)("meta",{property:"og:title",content:t}),(0,f.jsx)("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&(0,f.jsx)("meta",{name:"robots",content:"noindex, nofollow"}),e&&(0,f.jsx)("link",{rel:"icon",href:s})]})}var $=n(67489),H=n(92303);function G(){const e=(0,H.A)();return(0,f.jsx)(m.A,{children:(0,f.jsx)("html",{"data-has-hydrated":e})})}const V=(0,u.v)(d.A);function W(){const e=function(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,u.u)(d.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}((0,p.zy)());return(0,f.jsx)(D,{location:e,children:V})}function K(){return(0,f.jsx)($.A,{children:(0,f.jsx)(A.l,{children:(0,f.jsxs)(T.x,{children:[(0,f.jsxs)(g,{children:[(0,f.jsx)(U,{}),(0,f.jsx)(X,{}),(0,f.jsx)(q,{}),(0,f.jsx)(W,{})]}),(0,f.jsx)(G,{})]})})})}var Q=n(84054);const Y=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Z=n(86921);const J=new Set,ee=new Set,te=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ne={prefetch:e=>{if(!(e=>!te()&&!ee.has(e)&&!J.has(e))(e))return!1;J.add(e);const t=(0,u.u)(d.A,e).flatMap((e=>{return t=e.route.path,Object.entries(Q).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Z.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!te()&&!ee.has(e))(e)&&(ee.add(e),L(e))},re=Object.freeze(ne);function oe(e){let{children:t}=e;return"hash"===i.A.future.experimental_router?(0,f.jsx)(a.I9,{children:t}):(0,f.jsx)(a.Kd,{children:t})}const se=Boolean(!0);if(c.A.canUseDOM){window.docusaurus=re;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(s.vd,{children:(0,f.jsx)(oe,{children:(0,f.jsx)(K,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},a=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(se)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};L(window.location.pathname).then((()=>{(0,r.startTransition)(a)}))}},26988:(e,t,n)=>{"use strict";n.d(t,{o:()=>p,l:()=>u});var r=n(96540),o=n(4784);const s=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"index","docs":[{"id":"concepts/about","path":"/concepts/about","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/addressable-entity","path":"/concepts/addressable-entity","sidebar":"concepts"},{"id":"concepts/callstack","path":"/concepts/callstack","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/consensus","path":"/concepts/design/consensus","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/design/rewards","path":"/concepts/design/rewards","sidebar":"concepts"},{"id":"concepts/design/zug","path":"/concepts/design/zug","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/dynamic-gas-pricing","path":"/concepts/economics/dynamic-gas-pricing","sidebar":"concepts"},{"id":"concepts/economics/fee-elimination","path":"/concepts/economics/fee-elimination","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking","path":"/concepts/economics/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/index","path":"/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/key-types","path":"/concepts/key-types","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization/index","path":"/concepts/serialization/","sidebar":"concepts"},{"id":"concepts/serialization/primitives","path":"/concepts/serialization/primitives","sidebar":"concepts"},{"id":"concepts/serialization/structures","path":"/concepts/serialization/structures","sidebar":"concepts"},{"id":"concepts/serialization/types","path":"/concepts/serialization/types","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/concepts/smart-contracts","sidebar":"concepts"},{"id":"concepts/transactions","path":"/transactions"},{"id":"concepts/transactions-and-transaction-lifecycle","path":"/transactions-and-transaction-lifecycle","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-transactions","path":"/developers/cli/sending-transactions","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/cli/verifying-contracts","path":"/developers/cli/verifying-contracts","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-transaction","path":"/developers/dapps/signing-a-transaction","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/emitting-contract-events","path":"/developers/writing-onchain-code/emitting-contract-events","sidebar":"developers"},{"id":"developers/writing-onchain-code/factory-pattern","path":"/developers/writing-onchain-code/factory-pattern","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/disclaimer"},{"id":"index","path":"/"},{"id":"operators/becoming-a-validator/bonding","path":"/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/change-bid-public-key","path":"/operators/becoming-a-validator/change-bid-public-key"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/casper-sidecar","path":"/operators/setup/casper-sidecar","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/node-events","path":"/operators/setup/node-events","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/resources/tutorials/advanced/cross-contract","sidebar":"tutorials"},{"id":"resources/advanced/index","path":"/resources/tutorials/advanced/","sidebar":"tutorials"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/resources/advanced/list-auth-keys-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/list-cspr","path":"/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/resources/advanced/multi-sig/","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/resources/advanced/multi-sig/other-scenarios","sidebar":"tutorials"},{"id":"resources/advanced/return-values-tutorial","path":"/resources/tutorials/advanced/return-values-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/storage-workflow","path":"/resources/tutorials/advanced/storage-workflow","sidebar":"tutorials"},{"id":"resources/advanced/transfer-token-to-contract","path":"/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"tutorials"},{"id":"resources/advanced/two-party-multi-sig","path":"/resources/tutorials/advanced/two-party-multi-sig","sidebar":"tutorials"},{"id":"resources/beginner/aws-node","path":"/resources/tutorials/beginner/aws-node","sidebar":"tutorials"},{"id":"resources/beginner/cep18","path":"/resources/tutorials/beginner/cep18","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/commands","path":"/resources/beginner/counter-testnet/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/index","path":"/counter-testnet","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/overview","path":"/resources/beginner/counter-testnet/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/resources/beginner/counter-testnet/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/counter/commands","path":"/resources/beginner/counter/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter/index","path":"/counter","sidebar":"tutorials"},{"id":"resources/beginner/counter/overview","path":"/resources/beginner/counter/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter/walkthrough","path":"/resources/beginner/counter/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/getting-started-tutorial","path":"/resources/tutorials/beginner/getting-started-tutorial","sidebar":"tutorials"},{"id":"resources/beginner/index","path":"/resources/tutorials/beginner/","sidebar":"tutorials"},{"id":"resources/beginner/querying-network","path":"/resources/tutorials/beginner/querying-network","sidebar":"tutorials"},{"id":"resources/beginner/upgrade-contract","path":"/resources/tutorials/beginner/upgrade-contract","sidebar":"tutorials"},{"id":"resources/build-on-casper","path":"/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/changelog","path":"/resources/changelog"},{"id":"resources/index","path":"/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/resources/quick-start","sidebar":"tutorials"},{"id":"resources/tokens/cep18/full-tutorial","path":"/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client","path":"/resources/tokens/using-casper-client","sidebar":"resources"},{"id":"resources/tokens/index","path":"/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/users/undelegate-ui","sidebar":"users"},{"id":"users/delegating","path":"/users/delegating","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/developers","label":"developers/index"}},"operators":{"link":{"path":"/operators","label":"operators/index"}},"resources":{"link":{"path":"/resources/","label":"resources/index"}},"users":{"link":{"path":"/users/","label":"users/index"}},"tutorials":{"link":{"path":"/resources/quick-start","label":"resources/quick-start"}}}},{"name":"2.0.0","label":"2.0.0","isLast":false,"path":"/2.0.0","mainDocId":"index","docs":[{"id":"concepts/about","path":"/2.0.0/concepts/about","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/2.0.0/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/addressable-entity","path":"/2.0.0/concepts/addressable-entity","sidebar":"concepts"},{"id":"concepts/callstack","path":"/2.0.0/concepts/callstack","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/2.0.0/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/consensus","path":"/2.0.0/concepts/design/consensus","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/2.0.0/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/2.0.0/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/2.0.0/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/2.0.0/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/design/rewards","path":"/2.0.0/concepts/design/rewards","sidebar":"concepts"},{"id":"concepts/design/zug","path":"/2.0.0/concepts/design/zug","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/2.0.0/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/2.0.0/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/dynamic-gas-pricing","path":"/2.0.0/concepts/economics/dynamic-gas-pricing","sidebar":"concepts"},{"id":"concepts/economics/fee-elimination","path":"/2.0.0/concepts/economics/fee-elimination","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/2.0.0/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/2.0.0/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/2.0.0/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking","path":"/2.0.0/concepts/economics/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/2.0.0/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/2.0.0/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/2.0.0/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/2.0.0/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/2.0.0/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/2.0.0/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/2.0.0/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/2.0.0/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/2.0.0/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/2.0.0/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/2.0.0/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/2.0.0/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/2.0.0/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/2.0.0/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/2.0.0/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/2.0.0/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/2.0.0/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/2.0.0/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/2.0.0/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/2.0.0/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/2.0.0/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/2.0.0/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/2.0.0/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/2.0.0/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/2.0.0/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/2.0.0/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/2.0.0/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/2.0.0/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/index","path":"/2.0.0/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/2.0.0/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/key-types","path":"/2.0.0/concepts/key-types","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/2.0.0/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization/index","path":"/2.0.0/concepts/serialization/","sidebar":"concepts"},{"id":"concepts/serialization/primitives","path":"/2.0.0/concepts/serialization/primitives","sidebar":"concepts"},{"id":"concepts/serialization/structures","path":"/2.0.0/concepts/serialization/structures","sidebar":"concepts"},{"id":"concepts/serialization/types","path":"/2.0.0/concepts/serialization/types","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/2.0.0/concepts/smart-contracts","sidebar":"concepts"},{"id":"concepts/transactions","path":"/2.0.0/transactions"},{"id":"concepts/transactions-and-transaction-lifecycle","path":"/2.0.0/transactions-and-transaction-lifecycle","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/2.0.0/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/2.0.0/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/2.0.0/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/2.0.0/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/2.0.0/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/2.0.0/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/2.0.0/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/2.0.0/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-transactions","path":"/2.0.0/developers/cli/sending-transactions","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/2.0.0/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/2.0.0/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/2.0.0/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/2.0.0/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/2.0.0/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/cli/verifying-contracts","path":"/2.0.0/developers/cli/verifying-contracts","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/2.0.0/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/2.0.0/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/2.0.0/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/2.0.0/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/2.0.0/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/2.0.0/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/2.0.0/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/2.0.0/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/2.0.0/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/2.0.0/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/2.0.0/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/2.0.0/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-transaction","path":"/2.0.0/developers/dapps/signing-a-transaction","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/2.0.0/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/2.0.0/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/2.0.0/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/2.0.0/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/2.0.0/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/2.0.0/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/2.0.0/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/2.0.0/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/2.0.0/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/2.0.0/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/2.0.0/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/2.0.0/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/2.0.0/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/2.0.0/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/2.0.0/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/2.0.0/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/2.0.0/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/2.0.0/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/2.0.0/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/2.0.0/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/emitting-contract-events","path":"/2.0.0/developers/writing-onchain-code/emitting-contract-events","sidebar":"developers"},{"id":"developers/writing-onchain-code/factory-pattern","path":"/2.0.0/developers/writing-onchain-code/factory-pattern","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/2.0.0/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/2.0.0/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/2.0.0/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/2.0.0/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/2.0.0/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/2.0.0/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/2.0.0/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/2.0.0/disclaimer"},{"id":"index","path":"/2.0.0/"},{"id":"operators/becoming-a-validator/bonding","path":"/2.0.0/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/change-bid-public-key","path":"/2.0.0/operators/becoming-a-validator/change-bid-public-key"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/2.0.0/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/2.0.0/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/2.0.0/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/2.0.0/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/2.0.0/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/2.0.0/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/2.0.0/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/2.0.0/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/2.0.0/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/2.0.0/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/2.0.0/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/2.0.0/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/2.0.0/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/casper-sidecar","path":"/2.0.0/operators/setup/casper-sidecar","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/2.0.0/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/2.0.0/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/2.0.0/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/2.0.0/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/2.0.0/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/2.0.0/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/node-events","path":"/2.0.0/operators/setup/node-events","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/2.0.0/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/2.0.0/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/2.0.0/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/2.0.0/resources/tutorials/advanced/cross-contract","sidebar":"tutorials"},{"id":"resources/advanced/index","path":"/2.0.0/resources/tutorials/advanced/","sidebar":"tutorials"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/2.0.0/resources/advanced/list-auth-keys-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/list-cspr","path":"/2.0.0/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/2.0.0/resources/advanced/multi-sig/","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/2.0.0/resources/advanced/multi-sig/other-scenarios","sidebar":"tutorials"},{"id":"resources/advanced/return-values-tutorial","path":"/2.0.0/resources/tutorials/advanced/return-values-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/storage-workflow","path":"/2.0.0/resources/tutorials/advanced/storage-workflow","sidebar":"tutorials"},{"id":"resources/advanced/transfer-token-to-contract","path":"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"tutorials"},{"id":"resources/advanced/two-party-multi-sig","path":"/2.0.0/resources/tutorials/advanced/two-party-multi-sig","sidebar":"tutorials"},{"id":"resources/beginner/aws-node","path":"/2.0.0/resources/tutorials/beginner/aws-node","sidebar":"tutorials"},{"id":"resources/beginner/cep18","path":"/2.0.0/resources/tutorials/beginner/cep18","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/commands","path":"/2.0.0/resources/beginner/counter-testnet/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/index","path":"/2.0.0/counter-testnet","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/overview","path":"/2.0.0/resources/beginner/counter-testnet/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/2.0.0/resources/beginner/counter-testnet/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/counter/commands","path":"/2.0.0/resources/beginner/counter/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter/index","path":"/2.0.0/counter","sidebar":"tutorials"},{"id":"resources/beginner/counter/overview","path":"/2.0.0/resources/beginner/counter/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter/walkthrough","path":"/2.0.0/resources/beginner/counter/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/getting-started-tutorial","path":"/2.0.0/resources/tutorials/beginner/getting-started-tutorial","sidebar":"tutorials"},{"id":"resources/beginner/index","path":"/2.0.0/resources/tutorials/beginner/","sidebar":"tutorials"},{"id":"resources/beginner/querying-network","path":"/2.0.0/resources/tutorials/beginner/querying-network","sidebar":"tutorials"},{"id":"resources/beginner/upgrade-contract","path":"/2.0.0/resources/tutorials/beginner/upgrade-contract","sidebar":"tutorials"},{"id":"resources/build-on-casper","path":"/2.0.0/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/2.0.0/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/changelog","path":"/2.0.0/resources/changelog"},{"id":"resources/index","path":"/2.0.0/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/2.0.0/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/2.0.0/resources/quick-start","sidebar":"tutorials"},{"id":"resources/tokens/cep18/full-tutorial","path":"/2.0.0/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/2.0.0/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/2.0.0/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/2.0.0/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/2.0.0/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/2.0.0/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/2.0.0/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/2.0.0/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/2.0.0/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client","path":"/2.0.0/resources/tokens/using-casper-client","sidebar":"resources"},{"id":"resources/tokens/index","path":"/2.0.0/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/2.0.0/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/2.0.0/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/2.0.0/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/2.0.0/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/2.0.0/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/2.0.0/users/undelegate-ui","sidebar":"users"},{"id":"users/delegating","path":"/2.0.0/users/delegating","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/2.0.0/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/2.0.0/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/2.0.0/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/2.0.0/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/2.0.0/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/2.0.0/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/2.0.0/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/2.0.0/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/2.0.0/developers","label":"developers/index"}},"operators":{"link":{"path":"/2.0.0/operators","label":"operators/index"}},"resources":{"link":{"path":"/2.0.0/resources/","label":"resources/index"}},"users":{"link":{"path":"/2.0.0/users/","label":"users/index"}},"tutorials":{"link":{"path":"/2.0.0/resources/quick-start","label":"resources/quick-start"}}}},{"name":"1.5.X","label":"1.5.X","isLast":false,"path":"/1.5.X","mainDocId":"concepts/about","docs":[{"id":"concepts/about","path":"/1.5.X/","sidebar":"concepts"},{"id":"concepts/accounts-and-keys","path":"/1.5.X/concepts/accounts-and-keys","sidebar":"concepts"},{"id":"concepts/callstack","path":"/1.5.X/concepts/callstack","sidebar":"concepts"},{"id":"concepts/deploy-and-deploy-lifecycle","path":"/1.5.X/deploy-and-deploy-lifecycle","sidebar":"concepts"},{"id":"concepts/design/casper-design","path":"/1.5.X/concepts/design/casper-design","sidebar":"concepts"},{"id":"concepts/design/highway","path":"/1.5.X/concepts/design/highway","sidebar":"concepts"},{"id":"concepts/design/index","path":"/1.5.X/design","sidebar":"concepts"},{"id":"concepts/design/networking-protocol","path":"/1.5.X/concepts/design/networking-protocol"},{"id":"concepts/design/p2p","path":"/1.5.X/concepts/design/p2p","sidebar":"concepts"},{"id":"concepts/design/reading-and-writing-to-the-blockchain","path":"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain","sidebar":"concepts"},{"id":"concepts/dictionaries","path":"/1.5.X/concepts/dictionaries","sidebar":"concepts"},{"id":"concepts/economics/consensus","path":"/1.5.X/concepts/economics/consensus","sidebar":"concepts"},{"id":"concepts/economics/gas-concepts","path":"/1.5.X/concepts/economics/gas-concepts","sidebar":"concepts"},{"id":"concepts/economics/index","path":"/1.5.X/economics","sidebar":"concepts"},{"id":"concepts/economics/runtime","path":"/1.5.X/runtime","sidebar":"concepts"},{"id":"concepts/economics/staking/concepts","path":"/1.5.X/concepts/economics/concepts","sidebar":"concepts"},{"id":"concepts/economics/staking/delegation","path":"/1.5.X/concepts/economics/delegation","sidebar":"concepts"},{"id":"concepts/economics/staking/staking","path":"/1.5.X/staking","sidebar":"concepts"},{"id":"concepts/global-state","path":"/1.5.X/concepts/global-state","sidebar":"concepts"},{"id":"concepts/glossary/A","path":"/1.5.X/concepts/glossary/A","sidebar":"concepts"},{"id":"concepts/glossary/B","path":"/1.5.X/concepts/glossary/B","sidebar":"concepts"},{"id":"concepts/glossary/C","path":"/1.5.X/concepts/glossary/C","sidebar":"concepts"},{"id":"concepts/glossary/D","path":"/1.5.X/concepts/glossary/D","sidebar":"concepts"},{"id":"concepts/glossary/E","path":"/1.5.X/concepts/glossary/E","sidebar":"concepts"},{"id":"concepts/glossary/F","path":"/1.5.X/concepts/glossary/F","sidebar":"concepts"},{"id":"concepts/glossary/G","path":"/1.5.X/concepts/glossary/G","sidebar":"concepts"},{"id":"concepts/glossary/H","path":"/1.5.X/concepts/glossary/H","sidebar":"concepts"},{"id":"concepts/glossary/I","path":"/1.5.X/concepts/glossary/I","sidebar":"concepts"},{"id":"concepts/glossary/index","path":"/1.5.X/glossary","sidebar":"concepts"},{"id":"concepts/glossary/J","path":"/1.5.X/concepts/glossary/J","sidebar":"concepts"},{"id":"concepts/glossary/K","path":"/1.5.X/concepts/glossary/K","sidebar":"concepts"},{"id":"concepts/glossary/L","path":"/1.5.X/concepts/glossary/L","sidebar":"concepts"},{"id":"concepts/glossary/M","path":"/1.5.X/concepts/glossary/M","sidebar":"concepts"},{"id":"concepts/glossary/N","path":"/1.5.X/concepts/glossary/N","sidebar":"concepts"},{"id":"concepts/glossary/O","path":"/1.5.X/concepts/glossary/O","sidebar":"concepts"},{"id":"concepts/glossary/P","path":"/1.5.X/concepts/glossary/P","sidebar":"concepts"},{"id":"concepts/glossary/Q","path":"/1.5.X/concepts/glossary/Q","sidebar":"concepts"},{"id":"concepts/glossary/R","path":"/1.5.X/concepts/glossary/R","sidebar":"concepts"},{"id":"concepts/glossary/S","path":"/1.5.X/concepts/glossary/S","sidebar":"concepts"},{"id":"concepts/glossary/T","path":"/1.5.X/concepts/glossary/T","sidebar":"concepts"},{"id":"concepts/glossary/U","path":"/1.5.X/concepts/glossary/U","sidebar":"concepts"},{"id":"concepts/glossary/V","path":"/1.5.X/concepts/glossary/V","sidebar":"concepts"},{"id":"concepts/glossary/W","path":"/1.5.X/concepts/glossary/W","sidebar":"concepts"},{"id":"concepts/glossary/X","path":"/1.5.X/concepts/glossary/X","sidebar":"concepts"},{"id":"concepts/glossary/Y","path":"/1.5.X/concepts/glossary/Y","sidebar":"concepts"},{"id":"concepts/glossary/Z","path":"/1.5.X/concepts/glossary/Z","sidebar":"concepts"},{"id":"concepts/hash-types","path":"/1.5.X/concepts/hash-types","sidebar":"concepts"},{"id":"concepts/index","path":"/1.5.X/concepts/","sidebar":"concepts"},{"id":"concepts/intro-to-dapps","path":"/1.5.X/concepts/intro-to-dapps","sidebar":"concepts"},{"id":"concepts/list-auth-keys","path":"/1.5.X/concepts/list-auth-keys","sidebar":"concepts"},{"id":"concepts/serialization-standard","path":"/1.5.X/concepts/serialization-standard","sidebar":"concepts"},{"id":"concepts/smart-contracts","path":"/1.5.X/concepts/smart-contracts","sidebar":"concepts"},{"id":"developers/cli/calling-contracts","path":"/1.5.X/developers/cli/calling-contracts","sidebar":"developers"},{"id":"developers/cli/delegate","path":"/1.5.X/developers/cli/delegate","sidebar":"developers"},{"id":"developers/cli/execution-error-codes","path":"/1.5.X/developers/cli/execution-error-codes","sidebar":"developers"},{"id":"developers/cli/index","path":"/1.5.X/developers/cli/","sidebar":"developers"},{"id":"developers/cli/installing-contracts","path":"/1.5.X/developers/cli/installing-contracts","sidebar":"developers"},{"id":"developers/cli/opcode-costs","path":"/1.5.X/developers/cli/opcode-costs","sidebar":"developers"},{"id":"developers/cli/querying-global-state","path":"/1.5.X/developers/cli/querying-global-state","sidebar":"developers"},{"id":"developers/cli/redelegate","path":"/1.5.X/developers/cli/redelegate","sidebar":"developers"},{"id":"developers/cli/sending-deploys","path":"/1.5.X/developers/cli/sending-deploys","sidebar":"developers"},{"id":"developers/cli/transfers/direct-token-transfer","path":"/1.5.X/developers/cli/transfers/direct-token-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/index","path":"/1.5.X/developers/cli/transfers/","sidebar":"developers"},{"id":"developers/cli/transfers/multisig-deploy-transfer","path":"/1.5.X/developers/cli/transfers/multisig-deploy-transfer","sidebar":"developers"},{"id":"developers/cli/transfers/verify-transfer","path":"/1.5.X/developers/cli/transfers/verify-transfer","sidebar":"developers"},{"id":"developers/cli/undelegate","path":"/1.5.X/developers/cli/undelegate","sidebar":"developers"},{"id":"developers/dapps/dapp","path":"/1.5.X/developers/dapps/dapp","sidebar":"developers"},{"id":"developers/dapps/index","path":"/1.5.X/developers/dapps/","sidebar":"developers"},{"id":"developers/dapps/monitor-and-consume-events","path":"/1.5.X/developers/dapps/monitor-and-consume-events","sidebar":"developers"},{"id":"developers/dapps/nctl-test","path":"/1.5.X/developers/dapps/nctl-test","sidebar":"developers"},{"id":"developers/dapps/prerequisites","path":"/1.5.X/developers/dapps/prerequisites","sidebar":"developers"},{"id":"developers/dapps/sdk/client-library-usage","path":"/1.5.X/developers/dapps/sdk/client-library-usage","sidebar":"developers"},{"id":"developers/dapps/sdk/csharp-sdk","path":"/1.5.X/developers/dapps/sdk/csharp-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/go-sdk","path":"/1.5.X/developers/dapps/sdk/go-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/index","path":"/1.5.X/sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/python-sdk","path":"/1.5.X/developers/dapps/sdk/python-sdk","sidebar":"developers"},{"id":"developers/dapps/sdk/script-sdk","path":"/1.5.X/developers/dapps/sdk/script-sdk","sidebar":"developers"},{"id":"developers/dapps/setup-nctl","path":"/1.5.X/developers/dapps/setup-nctl","sidebar":"developers"},{"id":"developers/dapps/signing-a-deploy","path":"/1.5.X/developers/dapps/signing-a-deploy","sidebar":"developers"},{"id":"developers/dapps/speculative-exec","path":"/1.5.X/developers/dapps/speculative-exec","sidebar":"developers"},{"id":"developers/dapps/technology-stack","path":"/1.5.X/developers/dapps/technology-stack","sidebar":"developers"},{"id":"developers/dapps/template-frontend","path":"/1.5.X/developers/dapps/template-frontend","sidebar":"developers"},{"id":"developers/dapps/uref-security","path":"/1.5.X/developers/dapps/uref-security","sidebar":"developers"},{"id":"developers/essential-crates","path":"/1.5.X/developers/essential-crates","sidebar":"developers"},{"id":"developers/index","path":"/1.5.X/developers","sidebar":"developers"},{"id":"developers/json-rpc/errors","path":"/1.5.X/developers/json-rpc/errors"},{"id":"developers/json-rpc/guidance","path":"/1.5.X/developers/json-rpc/guidance","sidebar":"developers"},{"id":"developers/json-rpc/index","path":"/1.5.X/developers/json-rpc/","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-informational","path":"/1.5.X/developers/json-rpc/json-rpc-informational","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-pos","path":"/1.5.X/developers/json-rpc/json-rpc-pos","sidebar":"developers"},{"id":"developers/json-rpc/json-rpc-transactional","path":"/1.5.X/developers/json-rpc/json-rpc-transactional","sidebar":"developers"},{"id":"developers/json-rpc/minimal-compliance","path":"/1.5.X/developers/json-rpc/minimal-compliance","sidebar":"developers"},{"id":"developers/json-rpc/types_chain","path":"/1.5.X/developers/json-rpc/types_chain","sidebar":"developers"},{"id":"developers/json-rpc/types_cl","path":"/1.5.X/developers/json-rpc/types_cl","sidebar":"developers"},{"id":"developers/prerequisites","path":"/1.5.X/developers/prerequisites","sidebar":"developers"},{"id":"developers/writing-onchain-code/assembly-script","path":"/1.5.X/developers/writing-onchain-code/assembly-script","sidebar":"developers"},{"id":"developers/writing-onchain-code/best-practices","path":"/1.5.X/developers/writing-onchain-code/best-practices","sidebar":"developers"},{"id":"developers/writing-onchain-code/calling-contracts","path":"/1.5.X/developers/writing-onchain-code/calling-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-hash-vs-package-hash","path":"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash","sidebar":"developers"},{"id":"developers/writing-onchain-code/contract-vs-session","path":"/1.5.X/developers/writing-onchain-code/contract-vs-session","sidebar":"developers"},{"id":"developers/writing-onchain-code/getting-started","path":"/1.5.X/developers/writing-onchain-code/getting-started","sidebar":"developers"},{"id":"developers/writing-onchain-code/index","path":"/1.5.X/writing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/simple-contract","path":"/1.5.X/developers/writing-onchain-code/simple-contract","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-contracts","path":"/1.5.X/developers/writing-onchain-code/testing-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/testing-session-code","path":"/1.5.X/developers/writing-onchain-code/testing-session-code","sidebar":"developers"},{"id":"developers/writing-onchain-code/upgrading-contracts","path":"/1.5.X/developers/writing-onchain-code/upgrading-contracts","sidebar":"developers"},{"id":"developers/writing-onchain-code/writing-session-code","path":"/1.5.X/developers/writing-onchain-code/writing-session-code","sidebar":"developers"},{"id":"disclaimer","path":"/1.5.X/disclaimer"},{"id":"operators/becoming-a-validator/bonding","path":"/1.5.X/operators/becoming-a-validator/bonding","sidebar":"operators"},{"id":"operators/becoming-a-validator/inactive-vs-faulty","path":"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty","sidebar":"operators"},{"id":"operators/becoming-a-validator/index","path":"/1.5.X/operators/becoming-a-validator/","sidebar":"operators"},{"id":"operators/becoming-a-validator/recovering","path":"/1.5.X/operators/becoming-a-validator/recovering","sidebar":"operators"},{"id":"operators/becoming-a-validator/unbonding","path":"/1.5.X/operators/becoming-a-validator/unbonding","sidebar":"operators"},{"id":"operators/index","path":"/1.5.X/operators","sidebar":"operators"},{"id":"operators/maintenance/archiving-and-restoring","path":"/1.5.X/operators/maintenance/archiving-and-restoring","sidebar":"operators"},{"id":"operators/maintenance/index","path":"/1.5.X/operators/maintenance/","sidebar":"operators"},{"id":"operators/maintenance/moving-node","path":"/1.5.X/operators/maintenance/moving-node","sidebar":"operators"},{"id":"operators/setup-network/chain-spec","path":"/1.5.X/operators/setup-network/chain-spec","sidebar":"operators"},{"id":"operators/setup-network/create-private","path":"/1.5.X/operators/setup-network/create-private","sidebar":"operators"},{"id":"operators/setup-network/genesis","path":"/1.5.X/operators/setup-network/genesis","sidebar":"operators"},{"id":"operators/setup-network/index","path":"/1.5.X/operators/setup-network/","sidebar":"operators"},{"id":"operators/setup-network/staging-files-for-new-network","path":"/1.5.X/operators/setup-network/staging-files-for-new-network","sidebar":"operators"},{"id":"operators/setup/basic-node-configuration","path":"/1.5.X/operators/setup/basic-node-configuration","sidebar":"operators"},{"id":"operators/setup/fast-sync","path":"/1.5.X/operators/setup/fast-sync","sidebar":"operators"},{"id":"operators/setup/hardware","path":"/1.5.X/operators/setup/hardware","sidebar":"operators"},{"id":"operators/setup/index","path":"/1.5.X/operators/setup/","sidebar":"operators"},{"id":"operators/setup/install-node","path":"/1.5.X/operators/setup/install-node","sidebar":"operators"},{"id":"operators/setup/joining","path":"/1.5.X/operators/setup/joining","sidebar":"operators"},{"id":"operators/setup/node-endpoints","path":"/1.5.X/operators/setup/node-endpoints","sidebar":"operators"},{"id":"operators/setup/non-root-user","path":"/1.5.X/operators/setup/non-root-user","sidebar":"operators"},{"id":"operators/setup/open-files","path":"/1.5.X/operators/setup/open-files","sidebar":"operators"},{"id":"operators/setup/upgrade","path":"/1.5.X/operators/setup/upgrade","sidebar":"operators"},{"id":"resources/advanced/cross-contract","path":"/1.5.X/resources/tutorials/advanced/cross-contract","sidebar":"tutorials"},{"id":"resources/advanced/index","path":"/1.5.X/resources/tutorials/advanced/","sidebar":"tutorials"},{"id":"resources/advanced/list-auth-keys-tutorial","path":"/1.5.X/resources/advanced/list-auth-keys-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/list-cspr","path":"/1.5.X/resources/tutorials/advanced/list-cspr"},{"id":"resources/advanced/multi-sig/index","path":"/1.5.X/resources/advanced/multi-sig/","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/multi-sig-workflow","path":"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow","sidebar":"tutorials"},{"id":"resources/advanced/multi-sig/other-scenarios","path":"/1.5.X/resources/advanced/multi-sig/other-scenarios","sidebar":"tutorials"},{"id":"resources/advanced/return-values-tutorial","path":"/1.5.X/resources/tutorials/advanced/return-values-tutorial","sidebar":"tutorials"},{"id":"resources/advanced/storage-workflow","path":"/1.5.X/resources/tutorials/advanced/storage-workflow","sidebar":"tutorials"},{"id":"resources/advanced/transfer-token-to-contract","path":"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract","sidebar":"tutorials"},{"id":"resources/advanced/two-party-multi-sig","path":"/1.5.X/resources/tutorials/advanced/two-party-multi-sig","sidebar":"tutorials"},{"id":"resources/beginner/aws-node","path":"/1.5.X/resources/tutorials/beginner/aws-node","sidebar":"tutorials"},{"id":"resources/beginner/cep18","path":"/1.5.X/resources/tutorials/beginner/cep18","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/commands","path":"/1.5.X/resources/beginner/counter-testnet/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/index","path":"/1.5.X/counter-testnet","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/overview","path":"/1.5.X/resources/beginner/counter-testnet/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter-testnet/walkthrough","path":"/1.5.X/resources/beginner/counter-testnet/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/counter/commands","path":"/1.5.X/resources/beginner/counter/commands","sidebar":"tutorials"},{"id":"resources/beginner/counter/index","path":"/1.5.X/counter","sidebar":"tutorials"},{"id":"resources/beginner/counter/overview","path":"/1.5.X/resources/beginner/counter/overview","sidebar":"tutorials"},{"id":"resources/beginner/counter/walkthrough","path":"/1.5.X/resources/beginner/counter/walkthrough","sidebar":"tutorials"},{"id":"resources/beginner/getting-started-tutorial","path":"/1.5.X/resources/tutorials/beginner/getting-started-tutorial","sidebar":"tutorials"},{"id":"resources/beginner/index","path":"/1.5.X/resources/tutorials/beginner/","sidebar":"tutorials"},{"id":"resources/beginner/querying-network","path":"/1.5.X/resources/tutorials/beginner/querying-network","sidebar":"tutorials"},{"id":"resources/beginner/upgrade-contract","path":"/1.5.X/resources/tutorials/beginner/upgrade-contract","sidebar":"tutorials"},{"id":"resources/build-on-casper","path":"/1.5.X/resources/build-on-casper/introduction","sidebar":"resources"},{"id":"resources/casper-open-source-software","path":"/1.5.X/resources/build-on-casper/casper-open-source-software","sidebar":"resources"},{"id":"resources/condor-for-exchanges","path":"/1.5.X/resources/condor-for-exchanges"},{"id":"resources/index","path":"/1.5.X/resources/","sidebar":"resources"},{"id":"resources/moving-to-casper","path":"/1.5.X/resources/moving-to-casper","sidebar":"resources"},{"id":"resources/quick-start","path":"/1.5.X/resources/quick-start","sidebar":"tutorials"},{"id":"resources/tokens/cep18/full-tutorial","path":"/1.5.X/resources/tokens/cep18/full-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep18/query","path":"/1.5.X/resources/tokens/cep18/query","sidebar":"resources"},{"id":"resources/tokens/cep18/quickstart-guide","path":"/1.5.X/resources/tokens/cep18/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep18/tests","path":"/1.5.X/resources/tokens/cep18/tests","sidebar":"resources"},{"id":"resources/tokens/cep18/transfer","path":"/1.5.X/resources/tokens/cep18/transfer","sidebar":"resources"},{"id":"resources/tokens/cep78/introduction","path":"/1.5.X/resources/tokens/cep78/introduction","sidebar":"resources"},{"id":"resources/tokens/cep78/js-tutorial","path":"/1.5.X/resources/tokens/cep78/js-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/modalities","path":"/1.5.X/resources/tokens/cep78/modalities","sidebar":"resources"},{"id":"resources/tokens/cep78/reverse-lookup","path":"/1.5.X/resources/tokens/cep78/reverse-lookup","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/full-installation-tutorial","path":"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/interacting-with-NFTs","path":"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/querying-NFTs","path":"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/quickstart-guide","path":"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide","sidebar":"resources"},{"id":"resources/tokens/cep78/using-casper-client/testing-NFTs","path":"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs","sidebar":"resources"},{"id":"resources/tokens/index","path":"/1.5.X/resources/tokens/","sidebar":"resources"},{"id":"users/block-explorer","path":"/1.5.X/users/block-explorer","sidebar":"users"},{"id":"users/csprlive/delegate-ui","path":"/1.5.X/users/delegate-ui","sidebar":"users"},{"id":"users/csprlive/index","path":"/1.5.X/users/csprlive/","sidebar":"users"},{"id":"users/csprlive/testnet-faucet","path":"/1.5.X/users/testnet-faucet","sidebar":"users"},{"id":"users/csprlive/token-transfer","path":"/1.5.X/users/token-transfer","sidebar":"users"},{"id":"users/csprlive/undelegate-ui","path":"/1.5.X/users/undelegate-ui","sidebar":"users"},{"id":"users/funding-from-exchanges","path":"/1.5.X/users/funding-from-exchanges","sidebar":"users"},{"id":"users/index","path":"/1.5.X/users/","sidebar":"users"},{"id":"users/ledger/index","path":"/1.5.X/users/ledger/","sidebar":"users"},{"id":"users/ledger/ledger-cspr-live","path":"/1.5.X/users/ledger/ledger-cspr-live","sidebar":"users"},{"id":"users/ledger/ledger-live","path":"/1.5.X/users/ledger/ledger-live","sidebar":"users"},{"id":"users/ledger/ledger-setup","path":"/1.5.X/workflow/ledger-setup/","sidebar":"users"},{"id":"users/ledger/staking-ledger","path":"/1.5.X/users/staking-ledger","sidebar":"users"}],"draftIds":[],"sidebars":{"concepts":{"link":{"path":"/1.5.X/concepts/","label":"concepts/index"}},"developers":{"link":{"path":"/1.5.X/developers","label":"developers/index"}},"operators":{"link":{"path":"/1.5.X/operators","label":"operators/index"}},"resources":{"link":{"path":"/1.5.X/resources/","label":"resources/index"}},"users":{"link":{"path":"/1.5.X/users/","label":"users/index"}},"tutorials":{"link":{"path":"/1.5.X/resources/quick-start","label":"resources/quick-start"}}}}],"breadcrumbs":true}}}'),a=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(22654);const c=JSON.parse('{"docusaurusVersion":"3.5.2","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.5.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.5.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.5.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.5.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.5.2"},"docusaurus-theme-search-algolia":{"type":"package","name":"@docusaurus/theme-search-algolia","version":"3.5.2"}}}');var l=n(74848);const d={siteConfig:o.A,siteMetadata:c,globalData:s,i18n:a,codeTranslations:i},p=r.createContext(d);function u(e){let{children:t}=e;return(0,l.jsx)(p.Provider,{value:d,children:t})}},67489:(e,t,n)=>{"use strict";n.d(t,{A:()=>m});var r=n(96540),o=n(38193),s=n(5260),a=n(70440),i=n(79201),c=n(53102),l=n(74848);function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(p,{error:t})]})}function p(e){let{error:t}=e;const n=(0,a.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function u(e){let{children:t}=e;return(0,l.jsx)(c.W,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,l.jsx)(u,{children:(0,l.jsxs)(m,{fallback:()=>(0,l.jsx)(d,{error:t,tryAgain:n}),children:[(0,l.jsx)(s.A,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(i.A,{children:(0,l.jsx)(d,{error:t,tryAgain:n})})]})})}const g=e=>(0,l.jsx)(f,{...e});class m extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??g)(e)}return e??null}}},38193:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var r=n(80545),o=n(74848);function s(e){return(0,o.jsx)(r.mg,{...e})}},28774:(e,t,n)=>{"use strict";n.d(t,{A:()=>f});var r=n(96540),o=n(54625),s=n(70440),a=n(44586),i=n(16654),c=n(38193),l=n(63427),d=n(86025),p=n(74848);function u(e,t){let{isNavLink:n,to:u,href:f,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:y}=(0,a.A)(),{trailingSlash:w,baseUrl:_}=y,k=y.future.experimental_router,{withBaseUrl:x}=(0,d.hH)(),S=(0,l.A)(),E=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>E.current));const j=u||f;const X=(0,i.A)(j),C=j?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?x(A):A):void 0;var A;"hash"===k&&T?.startsWith("./")&&(T=T?.slice(1)),T&&X&&(T=(0,s.Ks)(T,{trailingSlash:w,baseUrl:_}));const R=(0,r.useRef)(!1),P=n?o.k2:o.N_,N=c.A.canUseIntersectionObserver,L=(0,r.useRef)(),O=()=>{R.current||null==T||(window.docusaurus.preload(T),R.current=!0)};(0,r.useEffect)((()=>(!N&&X&&c.A.canUseDOM&&null!=T&&window.docusaurus.prefetch(T),()=>{N&&L.current&&L.current.disconnect()})),[L,T,N,X]);const D=T?.startsWith("#")??!1,I=!v.target||"_self"===v.target,M=!T||!X||!I||D&&"hash"!==k;h||!D&&M||S.collectLink(T),v.id&&S.collectAnchor(v.id);const F={};return M?(0,p.jsx)("a",{ref:E,href:T,...j&&!X&&{target:"_blank",rel:"noopener noreferrer"},...v,...F}):(0,p.jsx)(P,{...v,onMouseEnter:O,onTouchStart:O,innerRef:e=>{E.current=e,N&&e&&X&&(L.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(L.current.unobserve(e),L.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),L.current.observe(e))},to:T,...n&&{isActive:m,activeClassName:g},...F})}const f=r.forwardRef(u)},21312:(e,t,n)=>{"use strict";n.d(t,{A:()=>l,T:()=>c});var r=n(96540),o=n(74848);function s(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var a=n(22654);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return a[t??n]??n??t}function c(e,t){let{message:n,id:r}=e;return s(i({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal <Translate> children",t),new Error("The Docusaurus <Translate> component only accept simple string values");const a=i({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:s(a,r)})}},17065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},16654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>o,z:()=>r})},86025:(e,t,n)=>{"use strict";n.d(t,{Ay:()=>i,hH:()=>a});var r=n(96540),o=n(44586),s=n(16654);function a(){const{siteConfig:e}=(0,o.A)(),{baseUrl:t,url:n}=e,a=e.future.experimental_router,i=(0,r.useCallback)(((e,r)=>function(e){let{siteUrl:t,baseUrl:n,url:r,options:{forcePrependBaseUrl:o=!1,absolute:a=!1}={},router:i}=e;if(!r||r.startsWith("#")||(0,s.z)(r))return r;if("hash"===i)return r.startsWith("/")?`.${r}`:`./${r}`;if(o)return n+r.replace(/^\//,"");if(r===n.replace(/\/$/,""))return n;const c=r.startsWith(n)?r:n+r.replace(/^\//,"");return a?t+c:c}({siteUrl:n,baseUrl:t,url:e,options:r,router:a})),[n,t,a]);return{withBaseUrl:i}}function i(e,t){void 0===t&&(t={});const{withBaseUrl:n}=a();return n(e,t)}},63427:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(96540);n(74848);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),s=()=>(0,r.useContext)(o);function a(){return s()}},44586:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(26988);function s(){return(0,r.useContext)(o.o)}},92303:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(6125);function s(){return(0,r.useContext)(o.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(96540);const o=n(38193).A.canUseDOM?r.useLayoutEffect:r.useEffect},36803:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=n(96540),o=n(53102);function s(){const e=r.useContext(o.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},86921:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[s,a]=n;const i=o?`${o}.${s}`:s;r(a)?e(a,i):t[i]=a}))}(e),t}},53102:(e,t,n)=>{"use strict";n.d(t,{W:()=>a,o:()=>s});var r=n(96540),o=n(74848);const s=r.createContext(null);function a(e){let{children:t,value:n}=e;const a=r.useContext(s),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:a,value:n})),[a,n]);return(0,o.jsx)(s.Provider,{value:i,children:t})}},53886:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>h,XK:()=>y,g1:()=>v});var r=n(96540),o=n(44070),s=n(17065),a=n(6342),i=n(70679),c=n(89532),l=n(74848);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,i.Wf)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,i.Wf)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,i.Wf)(d(e),{persistence:t}).del()}},u=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const f=r.createContext(null);function g(){const e=(0,o.Gy)(),t=(0,a.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[s,i]=(0,r.useState)((()=>u(n)));(0,r.useEffect)((()=>{i(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[s,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),i((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=g();return(0,l.jsx)(f.Provider,{value:n,children:t})}function h(e){let{children:t}=e;return(0,l.jsx)(m,{children:t})}function b(){const e=(0,r.useContext)(f);if(!e)throw new c.dV("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=s.W);const t=(0,o.ht)(e),[n,a]=b(),{preferredVersionName:i}=n[e];return{preferredVersion:t.versions.find((e=>e.name===i))??null,savePreferredVersionName:(0,r.useCallback)((t=>{a.savePreferredVersion(e,t)}),[a,e])}}function y(){const e=(0,o.Gy)(),[t]=b();function n(n){const r=e[n],{preferredVersionName:o}=t[n];return r.versions.find((e=>e.name===o))??null}const r=Object.keys(e);return Object.fromEntries(r.map((e=>[e,n(e)])))}},82565:(e,t,n)=>{"use strict";n.d(t,{k:()=>s,v:()=>a});var r=n(44070),o=n(53886);function s(e,t){return`docs-${e}-${t}`}function a(){const e=(0,r.Gy)(),t=(0,r.gk)(),n=(0,o.XK)();return[...Object.keys(e).map((function(r){const o=t?.activePlugin.pluginId===r?t.activeVersion:void 0,a=n[r],i=e[r].versions.find((e=>e.isLast));return s(r,(o??a??i).name)}))]}},60609:(e,t,n)=>{"use strict";n.d(t,{V:()=>c,t:()=>l});var r=n(96540),o=n(89532),s=n(74848);const a=Symbol("EmptyContext"),i=r.createContext(a);function c(e){let{children:t,name:n,items:o}=e;const a=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,s.jsx)(i.Provider,{value:a,children:t})}function l(){const e=(0,r.useContext)(i);if(e===a)throw new o.dV("DocsSidebarProvider");return e}},26972:(e,t,n)=>{"use strict";n.d(t,{B5:()=>x,Nr:()=>u,OF:()=>y,QB:()=>k,Vd:()=>w,Y:()=>b,fW:()=>_,w8:()=>m});var r=n(96540),o=n(56347),s=n(22831),a=n(44070),i=n(99169),c=n(31682),l=n(53886),d=n(23025),p=n(60609);function u(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=u(t);if(e)return e}}(e):void 0:e.href}const f=(e,t)=>void 0!==e&&(0,i.ys)(e,t),g=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?f(e.href,t):"category"===e.type&&(f(e.href,t)||g(e.items,t))}function h(e,t){switch(e.type){case"category":return m(e,t)||e.items.some((e=>h(e,t)));case"link":return!e.unlisted||m(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>h(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const s of t)if("category"===s.type&&((0,i.ys)(s.href,n)||e(s.items))||"link"===s.type&&(0,i.ys)(s.href,n)){return r&&"category"!==s.type||o.unshift(s),!0}return!1}(t),o}function y(){const e=(0,p.t)(),{pathname:t}=(0,o.zy)(),n=(0,a.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function w(e){const{activeVersion:t}=(0,a.zK)(e),{preferredVersion:n}=(0,l.g1)(e),o=(0,a.r7)(e);return(0,r.useMemo)((()=>(0,c.sb)([t,n,o].filter(Boolean))),[t,n,o])}function _(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function k(e,t){const n=w(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,c.sb)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function x(e){let{route:t}=e;const n=(0,o.zy)(),r=(0,d.r)(),a=t.routes,i=a.find((e=>(0,o.B6)(n.pathname,e)));if(!i)return null;const c=i.sidebar,l=c?r.docsSidebars[c]:void 0;return{docElement:(0,s.v)(a),sidebarName:c,sidebarItems:l}}},23025:(e,t,n)=>{"use strict";n.d(t,{n:()=>i,r:()=>c});var r=n(96540),o=n(89532),s=n(74848);const a=r.createContext(null);function i(e){let{children:t,version:n}=e;return(0,s.jsx)(a.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(a);if(null===e)throw new o.dV("DocsVersionProvider");return e}},44070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>b,vT:()=>f,gk:()=>g,Gy:()=>p,HW:()=>v,ht:()=>u,r7:()=>h,jh:()=>m});var r=n(56347),o=n(44586),s=n(17065);function a(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const i=e=>e.versions.find((e=>e.isLast));function c(e,t){return[...e.versions].sort(((e,t)=>e.path===t.path?0:e.path.includes(t.path)?-1:t.path.includes(e.path)?1:0)).find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}function l(e,t){const n=c(e,t),o=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const d={},p=()=>a("docusaurus-plugin-content-docs")??d,u=e=>{try{return function(e,t,n){void 0===t&&(t=s.W),void 0===n&&(n={});const r=a(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function f(e){void 0===e&&(e={});const t=p(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),s=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!s&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return s}(t,n,e)}function g(e){void 0===e&&(e={});const t=f(e),{pathname:n}=(0,r.zy)();if(!t)return;return{activePlugin:t,activeVersion:c(t.pluginData,n)}}function m(e){return u(e).versions}function h(e){const t=u(e);return i(t)}function b(e){const t=u(e),{pathname:n}=(0,r.zy)();return l(t,n)}function v(e){const t=u(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=i(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},76294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(5947),o=n.n(r);o().configure({showSpinner:!1});const s={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},26134:(e,t,n)=>{"use strict";n.r(t);var r=n(71765),o=n(4784);!function(e){const{themeConfig:{prism:t}}=o.A,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(19700),n(18692)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},51107:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(34164),o=n(21312),s=n(6342),a=n(28774),i=n(63427);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(74848);function d(e){let{as:t,id:n,...d}=e;const p=(0,i.A)(),{navbar:{hideOnScroll:u}}=(0,s.p)();if("h1"===t||!n)return(0,l.jsx)(t,{...d,id:void 0});p.collectAnchor(n);const f=(0,o.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof d.children?d.children:n});return(0,l.jsxs)(t,{...d,className:(0,r.A)("anchor",u?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,d.className),id:n,children:[d.children,(0,l.jsx)(a.A,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},43186:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(74848);function s(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},79201:(e,t,n)=>{"use strict";n.d(t,{A:()=>Ot});var r=n(96540),o=n(34164),s=n(67489),a=n(45500),i=n(56347),c=n(21312),l=n(75062),d=n(74848);const p="__docusaurus_skipToContent_fallback";function u(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,i.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(p);t&&u(t)}),[]);return(0,l.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&u(e.current)})),{containerRef:e,onClick:n}}const g=(0,c.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:r}=f();return(0,d.jsx)("div",{ref:n,role:"region","aria-label":g,children:(0,d.jsx)("a",{...e,href:`#${p}`,onClick:r,children:t})})}var h=n(17559),b=n(14090);const v={skipToContent:"skipToContent_fXgn"};function y(){return(0,d.jsx)(m,{className:v.skipToContent})}var w=n(6342),_=n(65041);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:s,...a}=e;return(0,d.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...a,children:(0,d.jsx)("g",{stroke:r,strokeWidth:o,children:(0,d.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const x={closeButton:"closeButton_CVFx"};function S(e){return(0,d.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.A)("clean-btn close",x.closeButton,e.className),children:(0,d.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const E={content:"content_knG7"};function j(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,d.jsx)("div",{...e,className:(0,o.A)(E.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const X={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function C(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,_.M)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:s}=e;return(0,d.jsxs)("div",{className:X.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[s&&(0,d.jsx)("div",{className:X.announcementBarPlaceholder}),(0,d.jsx)(j,{className:X.announcementBarContent}),s&&(0,d.jsx)(S,{onClick:n,className:X.announcementBarClose})]})}var T=n(22069),A=n(23104);var R=n(89532),P=n(75600);const N=r.createContext(null);function L(e){let{children:t}=e;const n=function(){const e=(0,T.M)(),t=(0,P.YL)(),[n,o]=(0,r.useState)(!1),s=null!==t.component,a=(0,R.ZC)(s);return(0,r.useEffect)((()=>{s&&!a&&o(!0)}),[s,a]),(0,r.useEffect)((()=>{s?e.shown||o(!0):o(!1)}),[e.shown,s]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,d.jsx)(N.Provider,{value:n,children:t})}function O(e){if(e.component){const t=e.component;return(0,d.jsx)(t,{...e.props})}}function D(){const e=(0,r.useContext)(N);if(!e)throw new R.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),s=(0,P.YL)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:O(s)})),[o,s,t])}function I(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:s}=D();return(0,d.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,d.jsxs)("div",{className:(0,o.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":s}),children:[(0,d.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,d.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(95293),F=n(92303);function z(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,d.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function B(e){return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,d.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const q={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function U(e){let{className:t,buttonClassName:n,value:r,onChange:s}=e;const a=(0,F.A)(),i=(0,c.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,c.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,d.jsx)("div",{className:(0,o.A)(q.toggle,t),children:(0,d.jsxs)("button",{className:(0,o.A)("clean-btn",q.toggleButton,!a&&q.toggleButtonDisabled,n),type:"button",onClick:()=>s("dark"===r?"light":"dark"),disabled:!a,title:i,"aria-label":i,"aria-live":"polite",children:[(0,d.jsx)(z,{className:(0,o.A)(q.toggleIcon,q.lightToggleIcon)}),(0,d.jsx)(B,{className:(0,o.A)(q.toggleIcon,q.darkToggleIcon)})]})})}const $=r.memo(U),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function G(e){let{className:t}=e;const n=(0,w.p)().navbar.style,r=(0,w.p)().colorMode.disableSwitch,{colorMode:o,setColorMode:s}=(0,M.G)();return r?null:(0,d.jsx)($,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:o,onChange:s})}var V=n(23465);function W(){return(0,d.jsx)(V.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function K(){const e=(0,T.M)();return(0,d.jsx)("button",{type:"button","aria-label":(0,c.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,d.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function Q(){return(0,d.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,d.jsx)(W,{}),(0,d.jsx)(G,{className:"margin-right--md"}),(0,d.jsx)(K,{})]})}var Y=n(28774),Z=n(86025),J=n(16654),ee=n(91252),te=n(43186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:s,html:a,isDropdownLink:i,prependBaseUrlToHref:c,...l}=e;const p=(0,Z.Ay)(r),u=(0,Z.Ay)(t),f=(0,Z.Ay)(o,{forcePrependBaseUrl:!0}),g=s&&o&&!(0,J.A)(o),m=a?{dangerouslySetInnerHTML:{__html:a}}:{children:(0,d.jsxs)(d.Fragment,{children:[s,g&&(0,d.jsx)(te.A,{...i&&{width:12,height:12}})]})};return o?(0,d.jsx)(Y.A,{href:c?f:o,...l,...m}):(0,d.jsx)(Y.A,{to:p,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?(0,ee.G)(n,t.pathname):t.pathname.startsWith(u)},...l,...m})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const s=(0,d.jsx)(ne,{className:(0,o.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,d.jsx)("li",{children:s}):s}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,d.jsx)("li",{className:"menu__list-item",children:(0,d.jsx)(ne,{className:(0,o.A)("menu__link",t),...r})})}function se(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,d.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ae=n(41422),ie=n(99169),ce=n(44586);const le={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function de(e,t){return e.some((e=>function(e,t){return!!(0,ie.ys)(e.to,t)||!!(0,ee.G)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function pe(e){let{items:t,position:n,className:s,onClick:a,...i}=e;const c=(0,r.useRef)(null),[l,p]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&p(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,d.jsxs)("div",{ref:c,className:(0,o.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":l}),children:[(0,d.jsx)(ne,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:i.to?void 0:"#",className:(0,o.A)("navbar__link",s),...i,onClick:i.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),p(!l))},children:i.children??i.label}),(0,d.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Ve,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function ue(e){let{items:t,className:n,position:s,onClick:a,...c}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.A)(),{pathname:t}=(0,i.zy)();return t.replace(e,"/")}(),p=de(t,l),{collapsed:u,toggleCollapsed:f,setCollapsed:g}=(0,ae.u)({initialState:()=>!p});return(0,r.useEffect)((()=>{p&&g(!p)}),[l,p,g]),(0,d.jsxs)("li",{className:(0,o.A)("menu__list-item",{"menu__list-item--collapsed":u}),children:[(0,d.jsx)(ne,{role:"button",className:(0,o.A)(le.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),f()},children:c.children??c.label}),(0,d.jsx)(ae.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:u,children:t.map(((e,t)=>(0,r.createElement)(Ve,{mobile:!0,isDropdownItem:!0,onClick:a,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?ue:pe;return(0,d.jsx)(r,{...n})}var ge=n(32131);function me(e){let{width:t=20,height:n=20,...r}=e;return(0,d.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,d.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const he="iconLanguage_nlXk";var be=n(40961);function ve(){return r.createElement("svg",{width:"15",height:"15",className:"DocSearch-Control-Key-Icon"},r.createElement("path",{d:"M4.505 4.496h2M5.505 5.496v5M8.216 4.496l.055 5.993M10 7.5c.333.333.5.667.5 1v2M12.326 4.5v5.996M8.384 4.496c1.674 0 2.116 0 2.116 1.5s-.442 1.5-2.116 1.5M3.205 9.303c-.09.448-.277 1.21-1.241 1.203C1 10.5.5 9.513.5 8V7c0-1.57.5-2.5 1.464-2.494.964.006 1.134.598 1.24 1.342M12.553 10.5h1.953",strokeWidth:"1.2",stroke:"currentColor",fill:"none",strokeLinecap:"square"}))}var ye=n(89188),we=["translations"];function _e(){return _e=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},_e.apply(this,arguments)}function ke(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var r,o,s=[],a=!0,i=!1;try{for(n=n.call(e);!(a=(r=n.next()).done)&&(s.push(r.value),!t||s.length!==t);a=!0);}catch(c){i=!0,o=c}finally{try{a||null==n.return||n.return()}finally{if(i)throw o}}return s}(e,t)||function(e,t){if(!e)return;if("string"==typeof e)return xe(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return xe(e,t)}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function xe(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function Se(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(r=0;r<s.length;r++)n=s[r],t.indexOf(n)>=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var Ee="Ctrl";var je=r.forwardRef((function(e,t){var n=e.translations,o=void 0===n?{}:n,s=Se(e,we),a=o.buttonText,i=void 0===a?"Search":a,c=o.buttonAriaLabel,l=void 0===c?"Search":c,d=ke((0,r.useState)(null),2),p=d[0],u=d[1];return(0,r.useEffect)((function(){"undefined"!=typeof navigator&&(/(Mac|iPhone|iPod|iPad)/i.test(navigator.platform)?u("\u2318"):u(Ee))}),[]),r.createElement("button",_e({type:"button",className:"DocSearch DocSearch-Button","aria-label":l},s,{ref:t}),r.createElement("span",{className:"DocSearch-Button-Container"},r.createElement(ye.W,null),r.createElement("span",{className:"DocSearch-Button-Placeholder"},i)),r.createElement("span",{className:"DocSearch-Button-Keys"},null!==p&&r.createElement(r.Fragment,null,r.createElement(Xe,{reactsToKey:p===Ee?Ee:"Meta"},p===Ee?r.createElement(ve,null):p),r.createElement(Xe,{reactsToKey:"k"},"K"))))}));function Xe(e){var t=e.reactsToKey,n=e.children,o=ke((0,r.useState)(!1),2),s=o[0],a=o[1];return(0,r.useEffect)((function(){if(t)return window.addEventListener("keydown",e),window.addEventListener("keyup",n),function(){window.removeEventListener("keydown",e),window.removeEventListener("keyup",n)};function e(e){e.key===t&&a(!0)}function n(e){e.key!==t&&"Meta"!==e.key||a(!1)}}),[t]),r.createElement("kbd",{className:s?"DocSearch-Button-Key DocSearch-Button-Key--pressed":"DocSearch-Button-Key"},n)}var Ce=n(5260),Te=n(24255),Ae=n(51062),Re=n(2967),Pe=n(82565);function Ne(){return[`language:${(0,ce.A)().i18n.currentLocale}`,function(){const e=(0,Pe.v)();return[Re.C,...e]}().map((e=>`docusaurus_tag:${e}`))]}const Le={button:{buttonText:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),buttonAriaLabel:(0,c.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"})},modal:{searchBox:{resetButtonTitle:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),resetButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.resetButtonTitle",message:"Clear the query",description:"The label and ARIA label for search box reset button"}),cancelButtonText:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"}),cancelButtonAriaLabel:(0,c.T)({id:"theme.SearchModal.searchBox.cancelButtonText",message:"Cancel",description:"The label and ARIA label for search box cancel button"})},startScreen:{recentSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.recentSearchesTitle",message:"Recent",description:"The title for recent searches"}),noRecentSearchesText:(0,c.T)({id:"theme.SearchModal.startScreen.noRecentSearchesText",message:"No recent searches",description:"The text when no recent searches"}),saveRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.saveRecentSearchButtonTitle",message:"Save this search",description:"The label for save recent search button"}),removeRecentSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeRecentSearchButtonTitle",message:"Remove this search from history",description:"The label for remove recent search button"}),favoriteSearchesTitle:(0,c.T)({id:"theme.SearchModal.startScreen.favoriteSearchesTitle",message:"Favorite",description:"The title for favorite searches"}),removeFavoriteSearchButtonTitle:(0,c.T)({id:"theme.SearchModal.startScreen.removeFavoriteSearchButtonTitle",message:"Remove this search from favorites",description:"The label for remove favorite search button"})},errorScreen:{titleText:(0,c.T)({id:"theme.SearchModal.errorScreen.titleText",message:"Unable to fetch results",description:"The title for error screen of search modal"}),helpText:(0,c.T)({id:"theme.SearchModal.errorScreen.helpText",message:"You might want to check your network connection.",description:"The help text for error screen of search modal"})},footer:{selectText:(0,c.T)({id:"theme.SearchModal.footer.selectText",message:"to select",description:"The explanatory text of the action for the enter key"}),selectKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.selectKeyAriaLabel",message:"Enter key",description:"The ARIA label for the Enter key button that makes the selection"}),navigateText:(0,c.T)({id:"theme.SearchModal.footer.navigateText",message:"to navigate",description:"The explanatory text of the action for the Arrow up and Arrow down key"}),navigateUpKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateUpKeyAriaLabel",message:"Arrow up",description:"The ARIA label for the Arrow up key button that makes the navigation"}),navigateDownKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.navigateDownKeyAriaLabel",message:"Arrow down",description:"The ARIA label for the Arrow down key button that makes the navigation"}),closeText:(0,c.T)({id:"theme.SearchModal.footer.closeText",message:"to close",description:"The explanatory text of the action for Escape key"}),closeKeyAriaLabel:(0,c.T)({id:"theme.SearchModal.footer.closeKeyAriaLabel",message:"Escape key",description:"The ARIA label for the Escape key button that close the modal"}),searchByText:(0,c.T)({id:"theme.SearchModal.footer.searchByText",message:"Search by",description:"The text explain that the search is making by Algolia"})},noResultsScreen:{noResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.noResultsText",message:"No results for",description:"The text explains that there are no results for the following search"}),suggestedQueryText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.suggestedQueryText",message:"Try searching for",description:"The text for the suggested query when no results are found for the following search"}),reportMissingResultsText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsText",message:"Believe this query should return results?",description:"The text for the question where the user thinks there are missing results"}),reportMissingResultsLinkText:(0,c.T)({id:"theme.SearchModal.noResultsScreen.reportMissingResultsLinkText",message:"Let us know.",description:"The text for the link to report missing results"})}},placeholder:(0,c.T)({id:"theme.SearchModal.placeholder",message:"Search docs",description:"The placeholder of the input of the DocSearch pop-up modal"})};let Oe=null;function De(e){let{hit:t,children:n}=e;return(0,d.jsx)(Y.A,{to:t.url,children:n})}function Ie(e){let{state:t,onClose:n}=e;const r=(0,Te.w)();return(0,d.jsx)(Y.A,{to:r(t.query),onClick:n,children:(0,d.jsx)(c.A,{id:"theme.SearchBar.seeAll",values:{count:t.context.nbHits},children:"See all {count} results"})})}function Me(e){let{contextualSearch:t,externalUrlRegex:o,...s}=e;const{siteMetadata:a}=(0,ce.A)(),c=(0,Ae.C)(),l=Ne(),p=s.searchParameters?.facetFilters??[],u=t?function(e,t){const n=e=>"string"==typeof e?[e]:e;return[...n(e),...n(t)]}(l,p):p,f={...s.searchParameters,facetFilters:u},g=(0,i.W6)(),m=(0,r.useRef)(null),h=(0,r.useRef)(null),[b,v]=(0,r.useState)(!1),[y,w]=(0,r.useState)(void 0),_=(0,r.useCallback)((()=>Oe?Promise.resolve():Promise.all([n.e(9462).then(n.bind(n,9462)),Promise.all([n.e(71869),n.e(58913)]).then(n.bind(n,58913)),Promise.all([n.e(71869),n.e(90416)]).then(n.bind(n,90416))]).then((e=>{let[{DocSearchModal:t}]=e;Oe=t}))),[]),k=(0,r.useCallback)((()=>{if(!m.current){const e=document.createElement("div");m.current=e,document.body.insertBefore(e,document.body.firstChild)}}),[]),x=(0,r.useCallback)((()=>{k(),_().then((()=>v(!0)))}),[_,k]),S=(0,r.useCallback)((()=>{v(!1),h.current?.focus()}),[]),E=(0,r.useCallback)((e=>{"f"===e.key&&(e.metaKey||e.ctrlKey)||(e.preventDefault(),w(e.key),x())}),[x]),j=(0,r.useRef)({navigate(e){let{itemUrl:t}=e;(0,ee.G)(o,t)?window.location.href=t:g.push(t)}}).current,X=(0,r.useRef)((e=>s.transformItems?s.transformItems(e):e.map((e=>({...e,url:c(e.url)}))))).current,C=(0,r.useMemo)((()=>e=>(0,d.jsx)(Ie,{...e,onClose:S})),[S]),T=(0,r.useCallback)((e=>(e.addAlgoliaAgent("docusaurus",a.docusaurusVersion),e)),[a.docusaurusVersion]);return function(e){var t=e.isOpen,n=e.onOpen,o=e.onClose,s=e.onInput,a=e.searchButtonRef;r.useEffect((function(){function e(e){var r;(27===e.keyCode&&t||"k"===(null===(r=e.key)||void 0===r?void 0:r.toLowerCase())&&(e.metaKey||e.ctrlKey)||!function(e){var t=e.target,n=t.tagName;return t.isContentEditable||"INPUT"===n||"SELECT"===n||"TEXTAREA"===n}(e)&&"/"===e.key&&!t)&&(e.preventDefault(),t?o():document.body.classList.contains("DocSearch--active")||document.body.classList.contains("DocSearch--active")||n()),a&&a.current===document.activeElement&&s&&/[a-zA-Z0-9]/.test(String.fromCharCode(e.keyCode))&&s(e)}return window.addEventListener("keydown",e),function(){window.removeEventListener("keydown",e)}}),[t,n,o,s,a])}({isOpen:b,onOpen:x,onClose:S,onInput:E,searchButtonRef:h}),(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(Ce.A,{children:(0,d.jsx)("link",{rel:"preconnect",href:`https://${s.appId}-dsn.algolia.net`,crossOrigin:"anonymous"})}),(0,d.jsx)(je,{onTouchStart:_,onFocus:_,onMouseOver:_,onClick:x,ref:h,translations:Le.button}),b&&Oe&&m.current&&(0,be.createPortal)((0,d.jsx)(Oe,{onClose:S,initialScrollY:window.scrollY,initialQuery:y,navigator:j,transformItems:X,hitComponent:De,transformSearchClient:T,...s.searchPagePath&&{resultsFooterComponent:C},...s,searchParameters:f,placeholder:Le.placeholder,translations:Le.modal}),m.current)]})}function Fe(){const{siteConfig:e}=(0,ce.A)();return(0,d.jsx)(Me,{...e.themeConfig.algolia})}const ze={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Be(e){let{children:t,className:n}=e;return(0,d.jsx)("div",{className:(0,o.A)(n,ze.navbarSearchContainer),children:t})}var qe=n(44070),Ue=n(26972);var $e=n(53886);function He(e,t){return t.alternateDocVersions[e.name]??function(e){return e.docs.find((t=>t.id===e.mainDocId))}(e)}const Ge={default:se,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...s}=e;const{i18n:{currentLocale:a,locales:l,localeConfigs:p}}=(0,ce.A)(),u=(0,ge.o)(),{search:f,hash:g}=(0,i.zy)(),m=[...n,...l.map((e=>{const n=`${`pathname://${u.createUrl({locale:e,fullyQualified:!1})}`}${f}${g}${o}`;return{label:p[e].label,lang:p[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===a?t?"menu__link--active":"dropdown__link--active":""}})),...r],h=t?(0,c.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):p[a].label;return(0,d.jsx)(fe,{...s,mobile:t,label:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(me,{className:he}),h]}),items:m})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,d.jsx)(Be,{className:n,children:(0,d.jsx)(Fe,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:s=!1}=e;const a=s?"li":"div";return(0,d.jsx)(a,{className:(0,o.A)({navbar__item:!r&&!s,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:s}=(0,qe.zK)(r),a=(0,Ue.QB)(t,r),i=s?.path===a?.path;return null===a||a.unlisted&&!i?null:(0,d.jsx)(se,{exact:!0,...o,isActive:()=>i||!!s?.sidebar&&s.sidebar===a.sidebar,label:n??a.id,to:a.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:s}=(0,qe.zK)(r),a=(0,Ue.fW)(t,r).link;if(!a)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,d.jsx)(se,{exact:!0,...o,isActive:()=>s?.sidebar===t,label:n??a.label,to:a.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const s=(0,Ue.Vd)(r)[0],a=t??s.label,i=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(s).path;return(0,d.jsx)(se,{...o,label:a,to:i})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:s,...a}=e;const{search:l,hash:p}=(0,i.zy)(),u=(0,qe.zK)(n),f=(0,qe.jh)(n),{savePreferredVersionName:g}=(0,$e.g1)(n),m=[...o,...f.map((function(e){const t=He(e,u);return{label:e.label,to:`${t.path}${l}${p}`,isActive:()=>e===u.activeVersion,onClick:()=>g(e.name)}})),...s],h=(0,Ue.Vd)(n)[0],b=t&&m.length>1?(0,c.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,v=t&&m.length>1?void 0:He(h,u).path;return m.length<=1?(0,d.jsx)(se,{...a,mobile:t,label:b,to:v,isActive:r?()=>!1:void 0}):(0,d.jsx)(fe,{...a,mobile:t,label:b,to:v,items:m,isActive:r?()=>!1:void 0})}};function Ve(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ge[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,d.jsx)(o,{...n})}function We(){const e=(0,T.M)(),t=(0,w.p)().navbar.items;return(0,d.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Ve,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ke(e){return(0,d.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,d.jsx)(c.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Qe(){const e=0===(0,w.p)().navbar.items.length,t=D();return(0,d.jsxs)(d.Fragment,{children:[!e&&(0,d.jsx)(Ke,{onClick:()=>t.hide()}),t.content]})}function Ye(){const e=(0,T.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,d.jsx)(I,{header:(0,d.jsx)(Q,{}),primaryMenu:(0,d.jsx)(We,{}),secondaryMenu:(0,d.jsx)(Qe,{})}):null}const Ze={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,d.jsx)("div",{role:"presentation",...e,className:(0,o.A)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:s}}=(0,w.p)(),a=(0,T.M)(),{navbarRef:i,isNavbarVisible:p}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),s=(0,r.useRef)(0),a=(0,r.useCallback)((e=>{null!==e&&(s.current=e.getBoundingClientRect().height)}),[]);return(0,A.Mq)(((t,r)=>{let{scrollY:a}=t;if(!e)return;if(a<s.current)return void n(!0);if(o.current)return void(o.current=!1);const i=r?.scrollY,c=document.documentElement.scrollHeight-s.current,l=window.innerHeight;i&&a>=i?n(!1):a+l<c&&n(!0)})),(0,l.$)((t=>{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:a,isNavbarVisible:t}}(n);return(0,d.jsxs)("nav",{ref:i,"aria-label":(0,c.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.A)("navbar","navbar--fixed-top",n&&[Ze.navbarHideable,!p&&Ze.navbarHidden],{"navbar--dark":"dark"===s,"navbar--primary":"primary"===s,"navbar-sidebar--show":a.shown}),children:[t,(0,d.jsx)(Je,{onClick:a.toggle}),(0,d.jsx)(Ye,{})]})}var tt=n(70440);const nt={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function rt(e){return(0,d.jsx)("button",{type:"button",...e,children:(0,d.jsx)(c.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function ot(e){let{error:t}=e;const n=(0,tt.rA)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,d.jsx)("p",{className:nt.errorBoundaryError,children:n})}class st extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const at="right";function it(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,d.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,d.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ct(){const{toggle:e,shown:t}=(0,T.M)();return(0,d.jsx)("button",{onClick:e,"aria-label":(0,c.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,d.jsx)(it,{})})}const lt={colorModeToggle:"colorModeToggle_DEke"};function dt(e){let{items:t}=e;return(0,d.jsx)(d.Fragment,{children:t.map(((e,t)=>(0,d.jsx)(st,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,d.jsx)(Ve,{...e})},t)))})}function pt(e){let{left:t,right:n}=e;return(0,d.jsxs)("div",{className:"navbar__inner",children:[(0,d.jsx)("div",{className:"navbar__items",children:t}),(0,d.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ut(){const e=(0,T.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??at)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,d.jsx)(pt,{left:(0,d.jsxs)(d.Fragment,{children:[!e.disabled&&(0,d.jsx)(ct,{}),(0,d.jsx)(W,{}),(0,d.jsx)(dt,{items:n})]}),right:(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(dt,{items:r}),(0,d.jsx)(G,{className:lt.colorModeToggle}),!o&&(0,d.jsx)(Be,{children:(0,d.jsx)(Fe,{})})]})})}function ft(){return(0,d.jsx)(et,{children:(0,d.jsx)(ut,{})})}function gt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:s,...a}=t,i=(0,Z.Ay)(n),c=(0,Z.Ay)(r,{forcePrependBaseUrl:!0});return(0,d.jsxs)(Y.A,{className:"footer__link-item",...r?{href:s?c:r}:{to:i},...a,children:[o,r&&!(0,J.A)(r)&&(0,d.jsx)(te.A,{})]})}function mt(e){let{item:t}=e;return t.html?(0,d.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,d.jsx)("li",{className:"footer__item",children:(0,d.jsx)(gt,{item:t})},t.href??t.to)}function ht(e){let{column:t}=e;return(0,d.jsxs)("div",{className:"col footer__col",children:[(0,d.jsx)("div",{className:"footer__title",children:t.title}),(0,d.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,d.jsx)(mt,{item:e},t)))})]})}function bt(e){let{columns:t}=e;return(0,d.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,d.jsx)(ht,{column:e},t)))})}function vt(){return(0,d.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function yt(e){let{item:t}=e;return t.html?(0,d.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,d.jsx)(gt,{item:t})}function wt(e){let{links:t}=e;return(0,d.jsx)("div",{className:"footer__links text--center",children:(0,d.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,d.jsxs)(r.Fragment,{children:[(0,d.jsx)(yt,{item:e}),t.length!==n+1&&(0,d.jsx)(vt,{})]},n)))})})}function _t(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,d.jsx)(bt,{columns:t}):(0,d.jsx)(wt,{links:t})}var kt=n(21122);const xt={footerLogoLink:"footerLogoLink_BH7S"};function St(e){let{logo:t}=e;const{withBaseUrl:n}=(0,Z.hH)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,d.jsx)(kt.A,{className:(0,o.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function Et(e){let{logo:t}=e;return t.href?(0,d.jsx)(Y.A,{href:t.href,className:xt.footerLogoLink,target:t.target,children:(0,d.jsx)(St,{logo:t})}):(0,d.jsx)(St,{logo:t})}function jt(e){let{copyright:t}=e;return(0,d.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Xt(e){let{style:t,links:n,logo:r,copyright:s}=e;return(0,d.jsx)("footer",{className:(0,o.A)("footer",{"footer--dark":"dark"===t}),children:(0,d.jsxs)("div",{className:"container container-fluid",children:[n,(r||s)&&(0,d.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,d.jsx)("div",{className:"margin-bottom--sm",children:r}),s]})]})})}function Ct(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e;return(0,d.jsx)(Xt,{style:o,links:n&&n.length>0&&(0,d.jsx)(_t,{links:n}),logo:r&&(0,d.jsx)(Et,{logo:r}),copyright:t&&(0,d.jsx)(jt,{copyright:t})})}const Tt=r.memo(Ct),At=(0,R.fM)([M.a,_.o,A.Tv,$e.VQ,a.Jx,function(e){let{children:t}=e;return(0,d.jsx)(P.y_,{children:(0,d.jsx)(T.e,{children:(0,d.jsx)(L,{children:t})})})}]);function Rt(e){let{children:t}=e;return(0,d.jsx)(At,{children:t})}var Pt=n(51107);function Nt(e){let{error:t,tryAgain:n}=e;return(0,d.jsx)("main",{className:"container margin-vert--xl",children:(0,d.jsx)("div",{className:"row",children:(0,d.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,d.jsx)(Pt.A,{as:"h1",className:"hero__title",children:(0,d.jsx)(c.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,d.jsx)("div",{className:"margin-vert--lg",children:(0,d.jsx)(rt,{onClick:n,className:"button button--primary shadow--lw"})}),(0,d.jsx)("hr",{}),(0,d.jsx)("div",{className:"margin-vert--md",children:(0,d.jsx)(ot,{error:t})})]})})})}const Lt={mainWrapper:"mainWrapper_z2l0"};function Ot(e){const{children:t,noFooter:n,wrapperClassName:r,title:i,description:c}=e;return(0,b.J)(),(0,d.jsxs)(Rt,{children:[(0,d.jsx)(a.be,{title:i,description:c}),(0,d.jsx)(y,{}),(0,d.jsx)(C,{}),(0,d.jsx)(ft,{}),(0,d.jsx)("div",{id:p,className:(0,o.A)(h.G.wrapper.main,Lt.mainWrapper,r),children:(0,d.jsx)(s.A,{fallback:e=>(0,d.jsx)(Nt,{...e}),children:t})}),!n&&(0,d.jsx)(Tt,{})]})}},23465:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});n(96540);var r=n(28774),o=n(86025),s=n(44586),a=n(6342),i=n(21122),c=n(74848);function l(e){let{logo:t,alt:n,imageClassName:r}=e;const s={light:(0,o.Ay)(t.src),dark:(0,o.Ay)(t.srcDark||t.src)},a=(0,c.jsx)(i.A,{className:t.className,sources:s,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,c.jsx)("div",{className:r,children:a}):a}function d(e){const{siteConfig:{title:t}}=(0,s.A)(),{navbar:{title:n,logo:i}}=(0,a.p)(),{imageClassName:d,titleClassName:p,...u}=e,f=(0,o.Ay)(i?.href||"/"),g=n?"":t,m=i?.alt??g;return(0,c.jsxs)(r.A,{to:f,...u,...i?.target&&{target:i.target},children:[i&&(0,c.jsx)(l,{logo:i,alt:m,imageClassName:d}),null!=n&&(0,c.jsx)("b",{className:p,children:n})]})}},41463:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});n(96540);var r=n(5260),o=n(74848);function s(e){let{locale:t,version:n,tag:s}=e;const a=t;return(0,o.jsxs)(r.A,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),s&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:s}),a&&(0,o.jsx)("meta",{name:"docsearch:language",content:a}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),s&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:s})]})}},21122:(e,t,n)=>{"use strict";n.d(t,{A:()=>d});var r=n(96540),o=n(34164),s=n(92303),a=n(95293);const i={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(74848);function l(e){let{className:t,children:n}=e;const l=(0,s.A)(),{colorMode:d}=(0,a.G)();return(0,c.jsx)(c.Fragment,{children:(l?"dark"===d?["dark"]:["light"]:["light","dark"]).map((e=>{const s=n({theme:e,className:(0,o.A)(t,i.themedComponent,i[`themedComponent--${e}`])});return(0,c.jsx)(r.Fragment,{children:s},e)}))})}function d(e){const{sources:t,className:n,alt:r,...o}=e;return(0,c.jsx)(l,{className:n,children:e=>{let{theme:n,className:s}=e;return(0,c.jsx)("img",{src:t[n],alt:r,className:s,...o})}})}},41422:(e,t,n)=>{"use strict";n.d(t,{N:()=>b,u:()=>l});var r=n(96540),o=n(38193),s=n(205),a=n(53109),i=n(74848);const c="ease-in-out";function l(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),s=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:s}}const d={display:"none",overflow:"hidden",height:"0px"},p={display:"block",overflow:"visible",height:"auto"};function u(e,t){const n=t?d:p;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const s=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,a.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function i(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!s.current)return u(e,n),void(s.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(i(),requestAnimationFrame((()=>{e.style.height=d.height,e.style.overflow=d.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{i()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function g(e){if(!o.A.canUseDOM)return e?d:p}function m(e){let{as:t="div",collapsed:n,children:o,animation:s,onCollapseTransitionEnd:a,className:c,disableSSRStyle:l}=e;const d=(0,r.useRef)(null);return f({collapsibleRef:d,collapsed:n,animation:s}),(0,i.jsx)(t,{ref:d,style:l?void 0:g(n),onTransitionEnd:e=>{"height"===e.propertyName&&(u(d.current,n),a?.(n))},className:c,children:o})}function h(e){let{collapsed:t,...n}=e;const[o,a]=(0,r.useState)(!t),[c,l]=(0,r.useState)(t);return(0,s.A)((()=>{t||a(!0)}),[t]),(0,s.A)((()=>{o&&l(t)}),[o,t]),o?(0,i.jsx)(m,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const r=t?h:m;return(0,i.jsx)(r,{...n})}},65041:(e,t,n)=>{"use strict";n.d(t,{M:()=>m,o:()=>g});var r=n(96540),o=n(92303),s=n(70679),a=n(89532),i=n(6342),c=n(74848);const l=(0,s.Wf)("docusaurus.announcement.dismiss"),d=(0,s.Wf)("docusaurus.announcement.id"),p=()=>"true"===l.get(),u=e=>l.set(String(e)),f=r.createContext(null);function g(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,i.p)(),t=(0,o.A)(),[n,s]=(0,r.useState)((()=>!!t&&p()));(0,r.useEffect)((()=>{s(p())}),[]);const a=(0,r.useCallback)((()=>{u(!0),s(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=d.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;d.set(t),r&&u(!1),!r&&p()||s(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:a})),[e,n,a])}();return(0,c.jsx)(f.Provider,{value:n,children:t})}function m(){const e=(0,r.useContext)(f);if(!e)throw new a.dV("AnnouncementBarProvider");return e}},95293:(e,t,n)=>{"use strict";n.d(t,{G:()=>b,a:()=>h});var r=n(96540),o=n(38193),s=n(89532),a=n(70679),i=n(6342),c=n(74848);const l=r.createContext(void 0),d="theme",p=(0,a.Wf)(d),u={light:"light",dark:"dark"},f=e=>e===u.dark?u.dark:u.light,g=e=>o.A.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{p.set(f(e))};function h(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,i.p)(),[o,s]=(0,r.useState)(g(e));(0,r.useEffect)((()=>{t&&p.del()}),[t]);const a=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(s(t),o&&m(t)):(s(n?window.matchMedia("(prefers-color-scheme: dark)").matches?u.dark:u.light:e),p.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==d)return;const t=p.get();null!==t&&a(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,a]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:a(null)};return e.addListener(r),()=>e.removeListener(r)}),[a,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:a,get isDarkTheme(){return o===u.dark},setLightTheme(){a(u.light)},setDarkTheme(){a(u.dark)}})),[o,a])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(l);if(null==e)throw new s.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},22069:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>u});var r=n(96540),o=n(75600),s=n(24581),a=n(57485),i=n(6342),c=n(89532),l=n(74848);const d=r.createContext(void 0);function p(){const e=function(){const e=(0,o.YL)(),{items:t}=(0,i.p)().navbar;return 0===t.length&&!e.component}(),t=(0,s.l)(),n=!e&&"mobile"===t,[c,l]=(0,r.useState)(!1);(0,a.$Z)((()=>{if(c)return l(!1),!1}));const d=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:d,shown:c})),[e,n,d,c])}function u(e){let{children:t}=e;const n=p();return(0,l.jsx)(d.Provider,{value:n,children:t})}function f(){const e=r.useContext(d);if(void 0===e)throw new c.dV("NavbarMobileSidebarProvider");return e}},75600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>l,YL:()=>c,y_:()=>i});var r=n(96540),o=n(89532),s=n(74848);const a=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,s.jsx)(a.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(a);if(!e)throw new o.dV("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const s=(0,r.useContext)(a);if(!s)throw new o.dV("NavbarSecondaryMenuContentProvider");const[,i]=s,c=(0,o.Be)(n);return(0,r.useEffect)((()=>{i({component:t,props:c})}),[i,t,c]),(0,r.useEffect)((()=>()=>i({component:null,props:null})),[i]),null}},14090:(e,t,n)=>{"use strict";n.d(t,{w:()=>o,J:()=>s});var r=n(96540);const o="navigation-with-keyboard";function s(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},24255:(e,t,n)=>{"use strict";n.d(t,{b:()=>i,w:()=>c});var r=n(96540),o=n(44586),s=n(57485);const a="q";function i(){return(0,s.l)(a)}function c(){const{siteConfig:{baseUrl:e,themeConfig:t}}=(0,o.A)(),{algolia:{searchPagePath:n}}=t;return(0,r.useCallback)((t=>`${e}${n}?${a}=${encodeURIComponent(t)}`),[e,n])}},24581:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(96540),o=n(38193);const s={desktop:"desktop",mobile:"mobile",ssr:"ssr"},a=996;function i(e){let{desktopBreakpoint:t=a}=void 0===e?{}:e;const[n,i]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){i(function(e){if(!o.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?s.desktop:s.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},17559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",blogAuthorsListPage:"blog-authors-list-page",blogAuthorsPostsPage:"blog-authors-posts-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",draftBanner:"theme-draft-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},53109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},20481:(e,t,n)=>{"use strict";n.d(t,{s:()=>o});var r=n(44586);function o(e){const{siteConfig:t}=(0,r.A)(),{title:n,titleDelimiter:o}=t;return e?.trim().length?`${e.trim()} ${o} ${n}`:n}},57485:(e,t,n)=>{"use strict";n.d(t,{$Z:()=>a,l:()=>c});var r=n(96540),o=n(56347),s=n(89532);function a(e){!function(e){const t=(0,o.W6)(),n=(0,s._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function i(e){const t=(0,o.W6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){const t=function(e){return i((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}(e)??"",n=function(e){const t=(0,o.W6)();return(0,r.useCallback)(((n,r)=>{const o=new URLSearchParams(t.location.search);n?o.set(e,n):o.delete(e),(r?.push?t.push:t.replace)({search:o.toString()})}),[e,t])}(e);return[t,n]}},31682:(e,t,n)=>{"use strict";function r(e){return Array.from(new Set(e))}function o(e,t){const n={};let r=0;for(const o of e){const e=t(o,r);n[e]??=[],n[e].push(o),r+=1}return n}n.d(t,{$z:()=>o,sb:()=>r})},45500:(e,t,n)=>{"use strict";n.d(t,{Jx:()=>f,be:()=>d,e3:()=>u});var r=n(96540),o=n(34164),s=n(5260),a=n(36803),i=n(86025),c=n(20481),l=n(74848);function d(e){let{title:t,description:n,keywords:r,image:o,children:a}=e;const d=(0,c.s)(t),{withBaseUrl:p}=(0,i.hH)(),u=o?p(o,{absolute:!0}):void 0;return(0,l.jsxs)(s.A,{children:[t&&(0,l.jsx)("title",{children:d}),t&&(0,l.jsx)("meta",{property:"og:title",content:d}),n&&(0,l.jsx)("meta",{name:"description",content:n}),n&&(0,l.jsx)("meta",{property:"og:description",content:n}),r&&(0,l.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),u&&(0,l.jsx)("meta",{property:"og:image",content:u}),u&&(0,l.jsx)("meta",{name:"twitter:image",content:u}),a]})}const p=r.createContext(void 0);function u(e){let{className:t,children:n}=e;const a=r.useContext(p),i=(0,o.A)(a,t);return(0,l.jsxs)(p.Provider,{value:i,children:[(0,l.jsx)(s.A,{children:(0,l.jsx)("html",{className:i})}),n]})}function f(e){let{children:t}=e;const n=(0,a.A)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const s=`plugin-id-${n.plugin.id}`;return(0,l.jsx)(u,{className:(0,o.A)(r,s),children:t})}},89532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>l,ZC:()=>i,_q:()=>a,dV:()=>c,fM:()=>d});var r=n(96540),o=n(205),s=n(74848);function a(e){const t=(0,r.useRef)(e);return(0,o.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return(0,o.A)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?<name>\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function d(e){return t=>{let{children:n}=t;return(0,s.jsx)(s.Fragment,{children:e.reduceRight(((e,t)=>(0,s.jsx)(t,{children:e})),n)})}}},91252:(e,t,n)=>{"use strict";function r(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}n.d(t,{G:()=>r})},99169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>i,ys:()=>a});var r=n(96540),o=n(35947),s=n(44586);function a(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function i(){const{baseUrl:e}=(0,s.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.A,baseUrl:e})),[e])}},23104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>u,Tv:()=>l,gk:()=>f});var r=n(96540),o=n(38193),s=n(92303),a=(n(205),n(89532)),i=n(74848);const c=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,i.jsx)(c.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(c);if(null==e)throw new a.dV("ScrollControllerProvider");return e}const p=()=>o.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function u(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(p()),s=(0,a._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();s(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[s,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,s.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&o<e)&&(t=requestAnimationFrame(r),window.scrollTo(0,Math.floor(.85*(o-e))+e))}(),()=>t&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{C:()=>r});const r="default"},70679:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>l});n(96540);const r=JSON.parse('{"N":"localStorage","M":""}'),o=r.N;function s(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const s=document.createEvent("StorageEvent");s.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(s)}function a(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){const n=`${e}${r.M}`;if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(n);const o=a(t?.persistence);return null===o?c:{get:()=>{try{return o.getItem(n)}catch(e){return console.error(`Docusaurus storage error, can't get key=${n}`,e),null}},set:e=>{try{const t=o.getItem(n);o.setItem(n,e),s({key:n,oldValue:t,newValue:e,storage:o})}catch(t){console.error(`Docusaurus storage error, can't set ${n}=${e}`,t)}},del:()=>{try{const e=o.getItem(n);o.removeItem(n),s({key:n,oldValue:e,newValue:null,storage:o})}catch(e){console.error(`Docusaurus storage error, can't delete key=${n}`,e)}},listen:e=>{try{const t=t=>{t.storageArea===o&&t.key===n&&e(t)};return window.addEventListener("storage",t),()=>window.removeEventListener("storage",t)}catch(t){return console.error(`Docusaurus storage error, can't listen for changes of key=${n}`,t),()=>{}}}}}},32131:(e,t,n)=>{"use strict";n.d(t,{o:()=>a});var r=n(44586),o=n(56347),s=n(70440);function a(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:a,currentLocale:i}}=(0,r.A)(),{pathname:c}=(0,o.zy)(),l=(0,s.Ks)(c,{trailingSlash:n,baseUrl:e}),d=i===a?e:e.replace(`/${i}/`,"/"),p=l.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===a?`${d}`:`${d}${e}/`}(n)}${p}`}}}},75062:(e,t,n)=>{"use strict";n.d(t,{$:()=>a});var r=n(96540),o=n(56347),s=n(89532);function a(e){const t=(0,o.zy)(),n=(0,s.ZC)(t),a=(0,s._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&a({location:t,previousLocation:n})}),[a,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>o});var r=n(44586);function o(){return(0,r.A)().siteConfig.themeConfig}},38126:(e,t,n)=>{"use strict";n.d(t,{c:()=>o});var r=n(44586);function o(){const{siteConfig:{themeConfig:e}}=(0,r.A)();return e}},51062:(e,t,n)=>{"use strict";n.d(t,{C:()=>i});var r=n(96540),o=n(91252),s=n(86025),a=n(38126);function i(){const{withBaseUrl:e}=(0,s.hH)(),{algolia:{externalUrlRegex:t,replaceSearchResultPathname:n}}=(0,a.c)();return(0,r.useCallback)((r=>{const s=new URL(r);if((0,o.G)(t,s.href))return r;const a=`${s.pathname+s.hash}`;return e(function(e,t){return t?e.replaceAll(new RegExp(t.from,"g"),t.to):e}(a,n))}),[e,t,n])}},12983:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),i="/"===a||a===r?a:(c=a,l=n,l?o(c):s(c));var c,l;return e.replace(a,i)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=s;const r=n(42566);function o(e){return e.endsWith("/")?e:`${e}/`}function s(e){return(0,r.removeSuffix)(e,"/")}},80253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=function e(t){if(t.cause)return[t,...e(t.cause)];return[t]}},70440:(e,t,n)=>{"use strict";t.rA=t.Ks=t.LU=void 0;const r=n(31635);t.LU="__blog-post-container";var o=n(12983);Object.defineProperty(t,"Ks",{enumerable:!0,get:function(){return r.__importDefault(o).default}});var s=n(42566);var a=n(80253);Object.defineProperty(t,"rA",{enumerable:!0,get:function(){return a.getErrorCausalChain}})},42566:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){if(""===t)return e;return e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},31513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>j,yJ:()=>f,sC:()=>C,AO:()=>u});var r=n(58168);function o(e){return"/"===e.charAt(0)}function s(e,t){for(var n=t,r=n+1,o=e.length;r<o;n+=1,r+=1)e[n]=e[r];e.pop()}const a=function(e,t){void 0===t&&(t="");var n,r=e&&e.split("/")||[],a=t&&t.split("/")||[],i=e&&o(e),c=t&&o(t),l=i||c;if(e&&o(e)?a=r:r.length&&(a.pop(),a=a.concat(r)),!a.length)return"/";if(a.length){var d=a[a.length-1];n="."===d||".."===d||""===d}else n=!1;for(var p=0,u=a.length;u>=0;u--){var f=a[u];"."===f?s(a,u):".."===f?(s(a,u),p++):p&&(s(a,u),p--)}if(!l)for(;p--;p)a.unshift("..");!l||""===a[0]||a[0]&&o(a[0])||a.unshift("");var g=a.join("/");return n&&"/"!==g.substr(-1)&&(g+="/"),g};var i=n(11561);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function d(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function u(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var s;"string"==typeof e?(s=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var s=t.indexOf("?");return-1!==s&&(n=t.substr(s),t=t.substr(0,s)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),s.state=t):(void 0===(s=(0,r.A)({},e)).pathname&&(s.pathname=""),s.search?"?"!==s.search.charAt(0)&&(s.search="?"+s.search):s.search="",s.hash?"#"!==s.hash.charAt(0)&&(s.hash="#"+s.hash):s.hash="",void 0!==t&&void 0===s.state&&(s.state=t));try{s.pathname=decodeURI(s.pathname)}catch(i){throw i instanceof URIError?new URIError('Pathname "'+s.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):i}return n&&(s.key=n),o?s.pathname?"/"!==s.pathname.charAt(0)&&(s.pathname=a(s.pathname,o.pathname)):s.pathname=o.pathname:s.pathname||(s.pathname="/"),s}function g(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var s="function"==typeof e?e(t,n):e;"string"==typeof s?"function"==typeof r?r(s,o):o(!0):o(!1!==s)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;r<e;r++)n[r]=arguments[r];t.forEach((function(e){return e.apply(void 0,n)}))}}}var m=!("undefined"==typeof window||!window.document||!window.document.createElement);function h(e,t){t(window.confirm(e))}var b="popstate",v="hashchange";function y(){try{return window.history.state||{}}catch(e){return{}}}function w(e){void 0===e&&(e={}),m||(0,i.A)(!1);var t,n=window.history,o=(-1===(t=window.navigator.userAgent).indexOf("Android 2.")&&-1===t.indexOf("Android 4.0")||-1===t.indexOf("Mobile Safari")||-1!==t.indexOf("Chrome")||-1!==t.indexOf("Windows Phone"))&&window.history&&"pushState"in window.history,s=!(-1===window.navigator.userAgent.indexOf("Trident")),a=e,l=a.forceRefresh,w=void 0!==l&&l,_=a.getUserConfirmation,k=void 0===_?h:_,x=a.keyLength,S=void 0===x?6:x,E=e.basename?p(c(e.basename)):"";function j(e){var t=e||{},n=t.key,r=t.state,o=window.location,s=o.pathname+o.search+o.hash;return E&&(s=d(s,E)),f(s,r,n)}function X(){return Math.random().toString(36).substr(2,S)}var C=g();function T(e){(0,r.A)(B,e),B.length=n.length,C.notifyListeners(B.location,B.action)}function A(e){(function(e){return void 0===e.state&&-1===navigator.userAgent.indexOf("CriOS")})(e)||N(j(e.state))}function R(){N(j(y()))}var P=!1;function N(e){if(P)P=!1,T();else{C.confirmTransitionTo(e,"POP",k,(function(t){t?T({action:"POP",location:e}):function(e){var t=B.location,n=O.indexOf(t.key);-1===n&&(n=0);var r=O.indexOf(e.key);-1===r&&(r=0);var o=n-r;o&&(P=!0,I(o))}(e)}))}}var L=j(y()),O=[L.key];function D(e){return E+u(e)}function I(e){n.go(e)}var M=0;function F(e){1===(M+=e)&&1===e?(window.addEventListener(b,A),s&&window.addEventListener(v,R)):0===M&&(window.removeEventListener(b,A),s&&window.removeEventListener(v,R))}var z=!1;var B={length:n.length,action:"POP",location:L,createHref:D,push:function(e,t){var r="PUSH",s=f(e,t,X(),B.location);C.confirmTransitionTo(s,r,k,(function(e){if(e){var t=D(s),a=s.key,i=s.state;if(o)if(n.pushState({key:a,state:i},null,t),w)window.location.href=t;else{var c=O.indexOf(B.location.key),l=O.slice(0,c+1);l.push(s.key),O=l,T({action:r,location:s})}else window.location.href=t}}))},replace:function(e,t){var r="REPLACE",s=f(e,t,X(),B.location);C.confirmTransitionTo(s,r,k,(function(e){if(e){var t=D(s),a=s.key,i=s.state;if(o)if(n.replaceState({key:a,state:i},null,t),w)window.location.replace(t);else{var c=O.indexOf(B.location.key);-1!==c&&(O[c]=s.key),T({action:r,location:s})}else window.location.replace(t)}}))},go:I,goBack:function(){I(-1)},goForward:function(){I(1)},block:function(e){void 0===e&&(e=!1);var t=C.setPrompt(e);return z||(F(1),z=!0),function(){return z&&(z=!1,F(-1)),t()}},listen:function(e){var t=C.appendListener(e);return F(1),function(){F(-1),t()}}};return B}var _="hashchange",k={hashbang:{encodePath:function(e){return"!"===e.charAt(0)?e:"!/"+l(e)},decodePath:function(e){return"!"===e.charAt(0)?e.substr(1):e}},noslash:{encodePath:l,decodePath:c},slash:{encodePath:c,decodePath:c}};function x(e){var t=e.indexOf("#");return-1===t?e:e.slice(0,t)}function S(){var e=window.location.href,t=e.indexOf("#");return-1===t?"":e.substring(t+1)}function E(e){window.location.replace(x(window.location.href)+"#"+e)}function j(e){void 0===e&&(e={}),m||(0,i.A)(!1);var t=window.history,n=(window.navigator.userAgent.indexOf("Firefox"),e),o=n.getUserConfirmation,s=void 0===o?h:o,a=n.hashType,l=void 0===a?"slash":a,b=e.basename?p(c(e.basename)):"",v=k[l],y=v.encodePath,w=v.decodePath;function j(){var e=w(S());return b&&(e=d(e,b)),f(e)}var X=g();function C(e){(0,r.A)(z,e),z.length=t.length,X.notifyListeners(z.location,z.action)}var T=!1,A=null;function R(){var e,t,n=S(),r=y(n);if(n!==r)E(r);else{var o=j(),a=z.location;if(!T&&(t=o,(e=a).pathname===t.pathname&&e.search===t.search&&e.hash===t.hash))return;if(A===u(o))return;A=null,function(e){if(T)T=!1,C();else{var t="POP";X.confirmTransitionTo(e,t,s,(function(n){n?C({action:t,location:e}):function(e){var t=z.location,n=O.lastIndexOf(u(t));-1===n&&(n=0);var r=O.lastIndexOf(u(e));-1===r&&(r=0);var o=n-r;o&&(T=!0,D(o))}(e)}))}}(o)}}var P=S(),N=y(P);P!==N&&E(N);var L=j(),O=[u(L)];function D(e){t.go(e)}var I=0;function M(e){1===(I+=e)&&1===e?window.addEventListener(_,R):0===I&&window.removeEventListener(_,R)}var F=!1;var z={length:t.length,action:"POP",location:L,createHref:function(e){var t=document.querySelector("base"),n="";return t&&t.getAttribute("href")&&(n=x(window.location.href)),n+"#"+y(b+u(e))},push:function(e,t){var n="PUSH",r=f(e,void 0,void 0,z.location);X.confirmTransitionTo(r,n,s,(function(e){if(e){var t=u(r),o=y(b+t);if(S()!==o){A=t,function(e){window.location.hash=e}(o);var s=O.lastIndexOf(u(z.location)),a=O.slice(0,s+1);a.push(t),O=a,C({action:n,location:r})}else C()}}))},replace:function(e,t){var n="REPLACE",r=f(e,void 0,void 0,z.location);X.confirmTransitionTo(r,n,s,(function(e){if(e){var t=u(r),o=y(b+t);S()!==o&&(A=t,E(o));var s=O.indexOf(u(z.location));-1!==s&&(O[s]=t),C({action:n,location:r})}}))},go:D,goBack:function(){D(-1)},goForward:function(){D(1)},block:function(e){void 0===e&&(e=!1);var t=X.setPrompt(e);return F||(M(1),F=!0),function(){return F&&(F=!1,M(-1)),t()}},listen:function(e){var t=X.appendListener(e);return M(1),function(){M(-1),t()}}};return z}function X(e,t,n){return Math.min(Math.max(e,t),n)}function C(e){void 0===e&&(e={});var t=e,n=t.getUserConfirmation,o=t.initialEntries,s=void 0===o?["/"]:o,a=t.initialIndex,i=void 0===a?0:a,c=t.keyLength,l=void 0===c?6:c,d=g();function p(e){(0,r.A)(w,e),w.length=w.entries.length,d.notifyListeners(w.location,w.action)}function m(){return Math.random().toString(36).substr(2,l)}var h=X(i,0,s.length-1),b=s.map((function(e){return f(e,void 0,"string"==typeof e?m():e.key||m())})),v=u;function y(e){var t=X(w.index+e,0,w.entries.length-1),r=w.entries[t];d.confirmTransitionTo(r,"POP",n,(function(e){e?p({action:"POP",location:r,index:t}):p()}))}var w={length:b.length,action:"POP",location:b[h],index:h,entries:b,createHref:v,push:function(e,t){var r="PUSH",o=f(e,t,m(),w.location);d.confirmTransitionTo(o,r,n,(function(e){if(e){var t=w.index+1,n=w.entries.slice(0);n.length>t?n.splice(t,n.length-t,o):n.push(o),p({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,m(),w.location);d.confirmTransitionTo(o,r,n,(function(e){e&&(w.entries[w.index]=o,p({action:r,location:o}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t<w.entries.length},block:function(e){return void 0===e&&(e=!1),d.setPrompt(e)},listen:function(e){return d.appendListener(e)}};return w}},4146:(e,t,n)=>{"use strict";var r=n(44363),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},s={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},a={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},i={};function c(e){return r.isMemo(e)?a:i[e.$$typeof]||o}i[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},i[r.Memo]=a;var l=Object.defineProperty,d=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,u=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,g=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(g){var o=f(n);o&&o!==g&&e(t,o,r)}var a=d(n);p&&(a=a.concat(p(n)));for(var i=c(t),m=c(n),h=0;h<a.length;++h){var b=a[h];if(!(s[b]||r&&r[b]||m&&m[b]||i&&i[b])){var v=u(n,b);try{l(t,b,v)}catch(y){}}}}return t}},20311:e=>{"use strict";e.exports=function(e,t,n,r,o,s,a,i){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,s,a,i],d=0;(c=new Error(t.replace(/%s/g,(function(){return l[d++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},64634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},10119:(e,t,n)=>{"use strict";n.r(t)},51043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};function o(e,t,n){return e<t?t:e>n?n:e}function s(e){return 100*(-1+e)}function a(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+s(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+s(e)+"%,0)"}:{"margin-left":s(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var s=n.render(!t),l=s.querySelector(r.barSelector),d=r.speed,p=r.easing;return s.offsetWidth,i((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,a(e,d,p)),1===e?(c(s,{transition:"none",opacity:1}),s.offsetWidth,setTimeout((function(){c(s,{transition:"all "+d+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),d)}),d)):setTimeout(t,d)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");d(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,a=t.querySelector(r.barSelector),i=e?"-100":s(n.status||0),l=document.querySelector(r.parent);return c(a,{transition:"all 0 linear",transform:"translate3d("+i+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),l!=document.body&&d(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){p(document.documentElement,"nprogress-busy"),p(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var i=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,s=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+s)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function s(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&s(e,n,r);else s(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:u(e)).indexOf(" "+t+" ")>=0}function d(e,t){var n=u(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function p(e,t){var n,r=u(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function u(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},6969:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to <a href="https://webplatform.github.io/docs/">WebPlatform.org documentation</a>. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (<code>.comment</code> can become <code>.namespace--comment</code>) or replace them with your defined ones (like <code>.editor__comment</code>). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the <code>highlightAll</code> and <code>highlightAllUnder</code> methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},8722:(e,t,n)=>{const r=n(6969),o=n(98380),s=new Set;function a(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...s,...Object.keys(Prism.languages)];o(r,e,t).load((e=>{if(!(e in r.languages))return void(a.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(63157).resolve(t)],delete Prism.languages[e],n(63157)(t),s.add(e)}))}a.silent=!1,e.exports=a},19700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,s){if(n.language===r){var a=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof s&&!s(e))return e;for(var o,i=a.length;-1!==n.code.indexOf(o=t(r,i));)++i;return a[i]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,s=Object.keys(n.tokenStack);!function a(i){for(var c=0;c<i.length&&!(o>=s.length);c++){var l=i[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var d=s[o],p=n.tokenStack[d],u="string"==typeof l?l:l.content,f=t(r,d),g=u.indexOf(f);if(g>-1){++o;var m=u.substring(0,g),h=new e.Token(r,e.tokenize(p,n.grammar),"language-"+r,p),b=u.substring(g+f.length),v=[];m&&v.push.apply(v,a([m])),v.push(h),b&&v.push.apply(v,a([b])),"string"==typeof l?i.splice.apply(i,[c,1].concat(v)):l.content=v}}else l.content&&a(l.content)}return i}(n.tokens)}}}})}(Prism)},18692:(e,t,n)=>{var r={"./":8722};function o(e){var t=s(e);return n(t)}function s(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=s,e.exports=o,o.id=18692},63157:(e,t,n)=>{var r={"./":8722};function o(e){var t=s(e);return n(t)}function s(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=s,e.exports=o,o.id=63157},98380:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n<r;n++)t[e[n]]=!0;return t}function r(e){var n={},r=[];function o(r,s){if(!(r in n)){s.push(r);var a=s.indexOf(r);if(a<s.length-1)throw new Error("Circular dependency: "+s.slice(a).join(" -> "));var i={},c=e[r];if(c){function l(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in i))for(var a in o(t,s),i[t]=!0,n[t])i[a]=!0}t(c.require,l),t(c.optional,l),t(c.modify,l)}n[r]=i,s.pop()}}return function(e){var t=n[e];return t||(o(e,r),t=n[e]),t}}function o(e){for(var t in e)return!0;return!1}return function(s,a,i){var c=function(e){var t={};for(var n in e){var r=e[n];for(var o in r)if("meta"!=o){var s=r[o];t[o]="string"==typeof s?{title:s}:s}}return t}(s),l=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var o in n={},e){var s=e[o];t(s&&s.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+o+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+o+" because it is a component.");n[t]=o}))}return n[r]||r}}(c);a=a.map(l),i=(i||[]).map(l);var d=n(a),p=n(i);a.forEach((function e(n){var r=c[n];t(r&&r.require,(function(t){t in p||(d[t]=!0,e(t))}))}));for(var u,f=r(c),g=d;o(g);){for(var m in u={},g){var h=c[m];t(h&&h.modify,(function(e){e in p&&(u[e]=!0)}))}for(var b in p)if(!(b in d))for(var v in f(b))if(v in d){u[b]=!0;break}for(var y in g=u)d[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,o){var s=o?o.series:void 0,a=o?o.parallel:e,i={},c={};function l(e){if(e in i)return i[e];c[e]=!0;var o,d=[];for(var p in t(e))p in n&&d.push(p);if(0===d.length)o=r(e);else{var u=a(d.map((function(e){var t=l(e);return delete c[e],t})));s?o=s(u,(function(){return r(e)})):r(e)}return i[e]=o}for(var d in n)l(d);var p=[];for(var u in c)p.push(i[u]);return a(p)}(f,d,t,n)}};return w}}();e.exports=t},2694:(e,t,n)=>{"use strict";var r=n(6925);function o(){}function s(){}s.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,s,a){if(a!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:s,resetWarningCache:o};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},22551:(e,t,n)=>{"use strict";var r=n(96540),o=n(69982);function s(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var a=new Set,i={};function c(e,t){l(e,t),l(e+"Capture",t)}function l(e,t){for(i[e]=t,e=0;e<t.length;e++)a.add(t[e])}var d=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement),p=Object.prototype.hasOwnProperty,u=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,f={},g={};function m(e,t,n,r,o,s,a){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=s,this.removeEmptyString=a}var h={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){h[e]=new m(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];h[t]=new m(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){h[e]=new m(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){h[e]=new m(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){h[e]=new m(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){h[e]=new m(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){h[e]=new m(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){h[e]=new m(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){h[e]=new m(e,5,!1,e.toLowerCase(),null,!1,!1)}));var b=/[\-:]([a-z])/g;function v(e){return e[1].toUpperCase()}function y(e,t,n,r){var o=h.hasOwnProperty(t)?h[t]:null;(null!==o?0!==o.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null==t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,o,r)&&(n=null),r||null===o?function(e){return!!p.call(g,e)||!p.call(f,e)&&(u.test(e)?g[e]=!0:(f[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):o.mustUseProperty?e[o.propertyName]=null===n?3!==o.type&&"":n:(t=o.attributeName,r=o.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(o=o.type)||4===o&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e){var t=e.replace(b,v);h[t]=new m(t,1,!1,e,"http://www.w3.org/XML/1998/namespace",!1,!1)})),["tabIndex","crossOrigin"].forEach((function(e){h[e]=new m(e,1,!1,e.toLowerCase(),null,!1,!1)})),h.xlinkHref=new m("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1),["src","href","action","formAction"].forEach((function(e){h[e]=new m(e,1,!1,e.toLowerCase(),null,!0,!0)}));var w=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,_=Symbol.for("react.element"),k=Symbol.for("react.portal"),x=Symbol.for("react.fragment"),S=Symbol.for("react.strict_mode"),E=Symbol.for("react.profiler"),j=Symbol.for("react.provider"),X=Symbol.for("react.context"),C=Symbol.for("react.forward_ref"),T=Symbol.for("react.suspense"),A=Symbol.for("react.suspense_list"),R=Symbol.for("react.memo"),P=Symbol.for("react.lazy");Symbol.for("react.scope"),Symbol.for("react.debug_trace_mode");var N=Symbol.for("react.offscreen");Symbol.for("react.legacy_hidden"),Symbol.for("react.cache"),Symbol.for("react.tracing_marker");var L=Symbol.iterator;function O(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=L&&e[L]||e["@@iterator"])?e:null}var D,I=Object.assign;function M(e){if(void 0===D)try{throw Error()}catch(n){var t=n.stack.trim().match(/\n( *(at )?)/);D=t&&t[1]||""}return"\n"+D+e}var F=!1;function z(e,t){if(!e||F)return"";F=!0;var n=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(t)if(t=function(){throw Error()},Object.defineProperty(t.prototype,"props",{set:function(){throw Error()}}),"object"==typeof Reflect&&Reflect.construct){try{Reflect.construct(t,[])}catch(l){var r=l}Reflect.construct(e,[],t)}else{try{t.call()}catch(l){r=l}e.call(t.prototype)}else{try{throw Error()}catch(l){r=l}e()}}catch(l){if(l&&r&&"string"==typeof l.stack){for(var o=l.stack.split("\n"),s=r.stack.split("\n"),a=o.length-1,i=s.length-1;1<=a&&0<=i&&o[a]!==s[i];)i--;for(;1<=a&&0<=i;a--,i--)if(o[a]!==s[i]){if(1!==a||1!==i)do{if(a--,0>--i||o[a]!==s[i]){var c="\n"+o[a].replace(" at new "," at ");return e.displayName&&c.includes("<anonymous>")&&(c=c.replace("<anonymous>",e.displayName)),c}}while(1<=a&&0<=i);break}}}finally{F=!1,Error.prepareStackTrace=n}return(e=e?e.displayName||e.name:"")?M(e):""}function B(e){switch(e.tag){case 5:return M(e.type);case 16:return M("Lazy");case 13:return M("Suspense");case 19:return M("SuspenseList");case 0:case 2:case 15:return e=z(e.type,!1);case 11:return e=z(e.type.render,!1);case 1:return e=z(e.type,!0);default:return""}}function q(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case x:return"Fragment";case k:return"Portal";case E:return"Profiler";case S:return"StrictMode";case T:return"Suspense";case A:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case X:return(e.displayName||"Context")+".Consumer";case j:return(e._context.displayName||"Context")+".Provider";case C:var t=e.render;return(e=e.displayName)||(e=""!==(e=t.displayName||t.name||"")?"ForwardRef("+e+")":"ForwardRef"),e;case R:return null!==(t=e.displayName||null)?t:q(e.type)||"Memo";case P:t=e._payload,e=e._init;try{return q(e(t))}catch(n){}}return null}function U(e){var t=e.type;switch(e.tag){case 24:return"Cache";case 9:return(t.displayName||"Context")+".Consumer";case 10:return(t._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return e=(e=t.render).displayName||e.name||"",t.displayName||(""!==e?"ForwardRef("+e+")":"ForwardRef");case 7:return"Fragment";case 5:return t;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return q(t);case 8:return t===S?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"==typeof t)return t.displayName||t.name||null;if("string"==typeof t)return t}return null}function $(e){switch(typeof e){case"boolean":case"number":case"string":case"undefined":case"object":return e;default:return""}}function H(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function G(e){e._valueTracker||(e._valueTracker=function(e){var t=H(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var o=n.get,s=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=""+e,s.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function V(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=H(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function W(e){if(void 0===(e=e||("undefined"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(t){return e.body}}function K(e,t){var n=t.checked;return I({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Q(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=$(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function Y(e,t){null!=(t=t.checked)&&y(e,"checked",t,!1)}function Z(e,t){Y(e,t);var n=$(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?ee(e,t.type,n):t.hasOwnProperty("defaultValue")&&ee(e,t.type,$(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function J(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function ee(e,t,n){"number"===t&&W(e.ownerDocument)===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}var te=Array.isArray;function ne(e,t,n,r){if(e=e.options,t){t={};for(var o=0;o<n.length;o++)t["$"+n[o]]=!0;for(n=0;n<e.length;n++)o=t.hasOwnProperty("$"+e[n].value),e[n].selected!==o&&(e[n].selected=o),o&&r&&(e[n].defaultSelected=!0)}else{for(n=""+$(n),t=null,o=0;o<e.length;o++){if(e[o].value===n)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==t||e[o].disabled||(t=e[o])}null!==t&&(t.selected=!0)}}function re(e,t){if(null!=t.dangerouslySetInnerHTML)throw Error(s(91));return I({},t,{value:void 0,defaultValue:void 0,children:""+e._wrapperState.initialValue})}function oe(e,t){var n=t.value;if(null==n){if(n=t.children,t=t.defaultValue,null!=n){if(null!=t)throw Error(s(92));if(te(n)){if(1<n.length)throw Error(s(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:$(n)}}function se(e,t){var n=$(t.value),r=$(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function ae(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}function ie(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function ce(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?ie(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var le,de,pe=(de=function(e,t){if("http://www.w3.org/2000/svg"!==e.namespaceURI||"innerHTML"in e)e.innerHTML=t;else{for((le=le||document.createElement("div")).innerHTML="<svg>"+t.valueOf().toString()+"</svg>",t=le.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return de(e,t)}))}:de);function ue(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}var fe={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ge=["Webkit","ms","Moz","O"];function me(e,t,n){return null==t||"boolean"==typeof t||""===t?"":n||"number"!=typeof t||0===t||fe.hasOwnProperty(e)&&fe[e]?(""+t).trim():t+"px"}function he(e,t){for(var n in e=e.style,t)if(t.hasOwnProperty(n)){var r=0===n.indexOf("--"),o=me(n,t[n],r);"float"===n&&(n="cssFloat"),r?e.setProperty(n,o):e[n]=o}}Object.keys(fe).forEach((function(e){ge.forEach((function(t){t=t+e.charAt(0).toUpperCase()+e.substring(1),fe[t]=fe[e]}))}));var be=I({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function ve(e,t){if(t){if(be[e]&&(null!=t.children||null!=t.dangerouslySetInnerHTML))throw Error(s(137,e));if(null!=t.dangerouslySetInnerHTML){if(null!=t.children)throw Error(s(60));if("object"!=typeof t.dangerouslySetInnerHTML||!("__html"in t.dangerouslySetInnerHTML))throw Error(s(61))}if(null!=t.style&&"object"!=typeof t.style)throw Error(s(62))}}function ye(e,t){if(-1===e.indexOf("-"))return"string"==typeof t.is;switch(e){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var we=null;function _e(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var ke=null,xe=null,Se=null;function Ee(e){if(e=wo(e)){if("function"!=typeof ke)throw Error(s(280));var t=e.stateNode;t&&(t=ko(t),ke(e.stateNode,e.type,t))}}function je(e){xe?Se?Se.push(e):Se=[e]:xe=e}function Xe(){if(xe){var e=xe,t=Se;if(Se=xe=null,Ee(e),t)for(e=0;e<t.length;e++)Ee(t[e])}}function Ce(e,t){return e(t)}function Te(){}var Ae=!1;function Re(e,t,n){if(Ae)return e(t,n);Ae=!0;try{return Ce(e,t,n)}finally{Ae=!1,(null!==xe||null!==Se)&&(Te(),Xe())}}function Pe(e,t){var n=e.stateNode;if(null===n)return null;var r=ko(n);if(null===r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(s(231,t,typeof n));return n}var Ne=!1;if(d)try{var Le={};Object.defineProperty(Le,"passive",{get:function(){Ne=!0}}),window.addEventListener("test",Le,Le),window.removeEventListener("test",Le,Le)}catch(de){Ne=!1}function Oe(e,t,n,r,o,s,a,i,c){var l=Array.prototype.slice.call(arguments,3);try{t.apply(n,l)}catch(d){this.onError(d)}}var De=!1,Ie=null,Me=!1,Fe=null,ze={onError:function(e){De=!0,Ie=e}};function Be(e,t,n,r,o,s,a,i,c){De=!1,Ie=null,Oe.apply(ze,arguments)}function qe(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{!!(4098&(t=e).flags)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function Ue(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function $e(e){if(qe(e)!==e)throw Error(s(188))}function He(e){return null!==(e=function(e){var t=e.alternate;if(!t){if(null===(t=qe(e)))throw Error(s(188));return t!==e?null:e}for(var n=e,r=t;;){var o=n.return;if(null===o)break;var a=o.alternate;if(null===a){if(null!==(r=o.return)){n=r;continue}break}if(o.child===a.child){for(a=o.child;a;){if(a===n)return $e(o),e;if(a===r)return $e(o),t;a=a.sibling}throw Error(s(188))}if(n.return!==r.return)n=o,r=a;else{for(var i=!1,c=o.child;c;){if(c===n){i=!0,n=o,r=a;break}if(c===r){i=!0,r=o,n=a;break}c=c.sibling}if(!i){for(c=a.child;c;){if(c===n){i=!0,n=a,r=o;break}if(c===r){i=!0,r=a,n=o;break}c=c.sibling}if(!i)throw Error(s(189))}}if(n.alternate!==r)throw Error(s(190))}if(3!==n.tag)throw Error(s(188));return n.stateNode.current===n?e:t}(e))?Ge(e):null}function Ge(e){if(5===e.tag||6===e.tag)return e;for(e=e.child;null!==e;){var t=Ge(e);if(null!==t)return t;e=e.sibling}return null}var Ve=o.unstable_scheduleCallback,We=o.unstable_cancelCallback,Ke=o.unstable_shouldYield,Qe=o.unstable_requestPaint,Ye=o.unstable_now,Ze=o.unstable_getCurrentPriorityLevel,Je=o.unstable_ImmediatePriority,et=o.unstable_UserBlockingPriority,tt=o.unstable_NormalPriority,nt=o.unstable_LowPriority,rt=o.unstable_IdlePriority,ot=null,st=null;var at=Math.clz32?Math.clz32:function(e){return e>>>=0,0===e?32:31-(it(e)/ct|0)|0},it=Math.log,ct=Math.LN2;var lt=64,dt=4194304;function pt(e){switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return 4194240&e;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return 130023424&e;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return e}}function ut(e,t){var n=e.pendingLanes;if(0===n)return 0;var r=0,o=e.suspendedLanes,s=e.pingedLanes,a=268435455&n;if(0!==a){var i=a&~o;0!==i?r=pt(i):0!==(s&=a)&&(r=pt(s))}else 0!==(a=n&~o)?r=pt(a):0!==s&&(r=pt(s));if(0===r)return 0;if(0!==t&&t!==r&&!(t&o)&&((o=r&-r)>=(s=t&-t)||16===o&&4194240&s))return t;if(4&r&&(r|=16&n),0!==(t=e.entangledLanes))for(e=e.entanglements,t&=r;0<t;)o=1<<(n=31-at(t)),r|=e[n],t&=~o;return r}function ft(e,t){switch(e){case 1:case 2:case 4:return t+250;case 8:case 16:case 32:case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t+5e3;default:return-1}}function gt(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function mt(){var e=lt;return!(4194240&(lt<<=1))&&(lt=64),e}function ht(e){for(var t=[],n=0;31>n;n++)t.push(e);return t}function bt(e,t,n){e.pendingLanes|=t,536870912!==t&&(e.suspendedLanes=0,e.pingedLanes=0),(e=e.eventTimes)[t=31-at(t)]=n}function vt(e,t){var n=e.entangledLanes|=t;for(e=e.entanglements;n;){var r=31-at(n),o=1<<r;o&t|e[r]&t&&(e[r]|=t),n&=~o}}var yt=0;function wt(e){return 1<(e&=-e)?4<e?268435455&e?16:536870912:4:1}var _t,kt,xt,St,Et,jt=!1,Xt=[],Ct=null,Tt=null,At=null,Rt=new Map,Pt=new Map,Nt=[],Lt="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit".split(" ");function Ot(e,t){switch(e){case"focusin":case"focusout":Ct=null;break;case"dragenter":case"dragleave":Tt=null;break;case"mouseover":case"mouseout":At=null;break;case"pointerover":case"pointerout":Rt.delete(t.pointerId);break;case"gotpointercapture":case"lostpointercapture":Pt.delete(t.pointerId)}}function Dt(e,t,n,r,o,s){return null===e||e.nativeEvent!==s?(e={blockedOn:t,domEventName:n,eventSystemFlags:r,nativeEvent:s,targetContainers:[o]},null!==t&&(null!==(t=wo(t))&&kt(t)),e):(e.eventSystemFlags|=r,t=e.targetContainers,null!==o&&-1===t.indexOf(o)&&t.push(o),e)}function It(e){var t=yo(e.target);if(null!==t){var n=qe(t);if(null!==n)if(13===(t=n.tag)){if(null!==(t=Ue(n)))return e.blockedOn=t,void Et(e.priority,(function(){xt(n)}))}else if(3===t&&n.stateNode.current.memoizedState.isDehydrated)return void(e.blockedOn=3===n.tag?n.stateNode.containerInfo:null)}e.blockedOn=null}function Mt(e){if(null!==e.blockedOn)return!1;for(var t=e.targetContainers;0<t.length;){var n=Kt(e.domEventName,e.eventSystemFlags,t[0],e.nativeEvent);if(null!==n)return null!==(t=wo(n))&&kt(t),e.blockedOn=n,!1;var r=new(n=e.nativeEvent).constructor(n.type,n);we=r,n.target.dispatchEvent(r),we=null,t.shift()}return!0}function Ft(e,t,n){Mt(e)&&n.delete(t)}function zt(){jt=!1,null!==Ct&&Mt(Ct)&&(Ct=null),null!==Tt&&Mt(Tt)&&(Tt=null),null!==At&&Mt(At)&&(At=null),Rt.forEach(Ft),Pt.forEach(Ft)}function Bt(e,t){e.blockedOn===t&&(e.blockedOn=null,jt||(jt=!0,o.unstable_scheduleCallback(o.unstable_NormalPriority,zt)))}function qt(e){function t(t){return Bt(t,e)}if(0<Xt.length){Bt(Xt[0],e);for(var n=1;n<Xt.length;n++){var r=Xt[n];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==Ct&&Bt(Ct,e),null!==Tt&&Bt(Tt,e),null!==At&&Bt(At,e),Rt.forEach(t),Pt.forEach(t),n=0;n<Nt.length;n++)(r=Nt[n]).blockedOn===e&&(r.blockedOn=null);for(;0<Nt.length&&null===(n=Nt[0]).blockedOn;)It(n),null===n.blockedOn&&Nt.shift()}var Ut=w.ReactCurrentBatchConfig,$t=!0;function Ht(e,t,n,r){var o=yt,s=Ut.transition;Ut.transition=null;try{yt=1,Vt(e,t,n,r)}finally{yt=o,Ut.transition=s}}function Gt(e,t,n,r){var o=yt,s=Ut.transition;Ut.transition=null;try{yt=4,Vt(e,t,n,r)}finally{yt=o,Ut.transition=s}}function Vt(e,t,n,r){if($t){var o=Kt(e,t,n,r);if(null===o)$r(e,t,r,Wt,n),Ot(e,r);else if(function(e,t,n,r,o){switch(t){case"focusin":return Ct=Dt(Ct,e,t,n,r,o),!0;case"dragenter":return Tt=Dt(Tt,e,t,n,r,o),!0;case"mouseover":return At=Dt(At,e,t,n,r,o),!0;case"pointerover":var s=o.pointerId;return Rt.set(s,Dt(Rt.get(s)||null,e,t,n,r,o)),!0;case"gotpointercapture":return s=o.pointerId,Pt.set(s,Dt(Pt.get(s)||null,e,t,n,r,o)),!0}return!1}(o,e,t,n,r))r.stopPropagation();else if(Ot(e,r),4&t&&-1<Lt.indexOf(e)){for(;null!==o;){var s=wo(o);if(null!==s&&_t(s),null===(s=Kt(e,t,n,r))&&$r(e,t,r,Wt,n),s===o)break;o=s}null!==o&&r.stopPropagation()}else $r(e,t,r,null,n)}}var Wt=null;function Kt(e,t,n,r){if(Wt=null,null!==(e=yo(e=_e(r))))if(null===(t=qe(e)))e=null;else if(13===(n=t.tag)){if(null!==(e=Ue(t)))return e;e=null}else if(3===n){if(t.stateNode.current.memoizedState.isDehydrated)return 3===t.tag?t.stateNode.containerInfo:null;e=null}else t!==e&&(e=null);return Wt=e,null}function Qt(e){switch(e){case"cancel":case"click":case"close":case"contextmenu":case"copy":case"cut":case"auxclick":case"dblclick":case"dragend":case"dragstart":case"drop":case"focusin":case"focusout":case"input":case"invalid":case"keydown":case"keypress":case"keyup":case"mousedown":case"mouseup":case"paste":case"pause":case"play":case"pointercancel":case"pointerdown":case"pointerup":case"ratechange":case"reset":case"resize":case"seeked":case"submit":case"touchcancel":case"touchend":case"touchstart":case"volumechange":case"change":case"selectionchange":case"textInput":case"compositionstart":case"compositionend":case"compositionupdate":case"beforeblur":case"afterblur":case"beforeinput":case"blur":case"fullscreenchange":case"focus":case"hashchange":case"popstate":case"select":case"selectstart":return 1;case"drag":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"mousemove":case"mouseout":case"mouseover":case"pointermove":case"pointerout":case"pointerover":case"scroll":case"toggle":case"touchmove":case"wheel":case"mouseenter":case"mouseleave":case"pointerenter":case"pointerleave":return 4;case"message":switch(Ze()){case Je:return 1;case et:return 4;case tt:case nt:return 16;case rt:return 536870912;default:return 16}default:return 16}}var Yt=null,Zt=null,Jt=null;function en(){if(Jt)return Jt;var e,t,n=Zt,r=n.length,o="value"in Yt?Yt.value:Yt.textContent,s=o.length;for(e=0;e<r&&n[e]===o[e];e++);var a=r-e;for(t=1;t<=a&&n[r-t]===o[s-t];t++);return Jt=o.slice(e,1<t?1-t:void 0)}function tn(e){var t=e.keyCode;return"charCode"in e?0===(e=e.charCode)&&13===t&&(e=13):e=t,10===e&&(e=13),32<=e||13===e?e:0}function nn(){return!0}function rn(){return!1}function on(e){function t(t,n,r,o,s){for(var a in this._reactName=t,this._targetInst=r,this.type=n,this.nativeEvent=o,this.target=s,this.currentTarget=null,e)e.hasOwnProperty(a)&&(t=e[a],this[a]=t?t(o):o[a]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?nn:rn,this.isPropagationStopped=rn,this}return I(t.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=nn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=nn)},persist:function(){},isPersistent:nn}),t}var sn,an,cn,ln={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},dn=on(ln),pn=I({},ln,{view:0,detail:0}),un=on(pn),fn=I({},pn,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:En,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return"movementX"in e?e.movementX:(e!==cn&&(cn&&"mousemove"===e.type?(sn=e.screenX-cn.screenX,an=e.screenY-cn.screenY):an=sn=0,cn=e),sn)},movementY:function(e){return"movementY"in e?e.movementY:an}}),gn=on(fn),mn=on(I({},fn,{dataTransfer:0})),hn=on(I({},pn,{relatedTarget:0})),bn=on(I({},ln,{animationName:0,elapsedTime:0,pseudoElement:0})),vn=I({},ln,{clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),yn=on(vn),wn=on(I({},ln,{data:0})),_n={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},kn={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},xn={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function Sn(e){var t=this.nativeEvent;return t.getModifierState?t.getModifierState(e):!!(e=xn[e])&&!!t[e]}function En(){return Sn}var jn=I({},pn,{key:function(e){if(e.key){var t=_n[e.key]||e.key;if("Unidentified"!==t)return t}return"keypress"===e.type?13===(e=tn(e))?"Enter":String.fromCharCode(e):"keydown"===e.type||"keyup"===e.type?kn[e.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:En,charCode:function(e){return"keypress"===e.type?tn(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?tn(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Xn=on(jn),Cn=on(I({},fn,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),Tn=on(I({},pn,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:En})),An=on(I({},ln,{propertyName:0,elapsedTime:0,pseudoElement:0})),Rn=I({},fn,{deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Pn=on(Rn),Nn=[9,13,27,32],Ln=d&&"CompositionEvent"in window,On=null;d&&"documentMode"in document&&(On=document.documentMode);var Dn=d&&"TextEvent"in window&&!On,In=d&&(!Ln||On&&8<On&&11>=On),Mn=String.fromCharCode(32),Fn=!1;function zn(e,t){switch(e){case"keyup":return-1!==Nn.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Bn(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var qn=!1;var Un={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function $n(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return"input"===t?!!Un[e.type]:"textarea"===t}function Hn(e,t,n,r){je(r),0<(t=Gr(t,"onChange")).length&&(n=new dn("onChange","change",null,n,r),e.push({event:n,listeners:t}))}var Gn=null,Vn=null;function Wn(e){Mr(e,0)}function Kn(e){if(V(_o(e)))return e}function Qn(e,t){if("change"===e)return t}var Yn=!1;if(d){var Zn;if(d){var Jn="oninput"in document;if(!Jn){var er=document.createElement("div");er.setAttribute("oninput","return;"),Jn="function"==typeof er.oninput}Zn=Jn}else Zn=!1;Yn=Zn&&(!document.documentMode||9<document.documentMode)}function tr(){Gn&&(Gn.detachEvent("onpropertychange",nr),Vn=Gn=null)}function nr(e){if("value"===e.propertyName&&Kn(Vn)){var t=[];Hn(t,Vn,e,_e(e)),Re(Wn,t)}}function rr(e,t,n){"focusin"===e?(tr(),Vn=n,(Gn=t).attachEvent("onpropertychange",nr)):"focusout"===e&&tr()}function or(e){if("selectionchange"===e||"keyup"===e||"keydown"===e)return Kn(Vn)}function sr(e,t){if("click"===e)return Kn(t)}function ar(e,t){if("input"===e||"change"===e)return Kn(t)}var ir="function"==typeof Object.is?Object.is:function(e,t){return e===t&&(0!==e||1/e==1/t)||e!=e&&t!=t};function cr(e,t){if(ir(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;var n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(r=0;r<n.length;r++){var o=n[r];if(!p.call(t,o)||!ir(e[o],t[o]))return!1}return!0}function lr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function dr(e,t){var n,r=lr(e);for(e=0;r;){if(3===r.nodeType){if(n=e+r.textContent.length,e<=t&&n>=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=lr(r)}}function pr(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?pr(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function ur(){for(var e=window,t=W();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=W((e=t.contentWindow).document)}return t}function fr(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function gr(e){var t=ur(),n=e.focusedElem,r=e.selectionRange;if(t!==n&&n&&n.ownerDocument&&pr(n.ownerDocument.documentElement,n)){if(null!==r&&fr(n))if(t=r.start,void 0===(e=r.end)&&(e=t),"selectionStart"in n)n.selectionStart=t,n.selectionEnd=Math.min(e,n.value.length);else if((e=(t=n.ownerDocument||document)&&t.defaultView||window).getSelection){e=e.getSelection();var o=n.textContent.length,s=Math.min(r.start,o);r=void 0===r.end?s:Math.min(r.end,o),!e.extend&&s>r&&(o=r,r=s,s=o),o=dr(n,s);var a=dr(n,r);o&&a&&(1!==e.rangeCount||e.anchorNode!==o.node||e.anchorOffset!==o.offset||e.focusNode!==a.node||e.focusOffset!==a.offset)&&((t=t.createRange()).setStart(o.node,o.offset),e.removeAllRanges(),s>r?(e.addRange(t),e.extend(a.node,a.offset)):(t.setEnd(a.node,a.offset),e.addRange(t)))}for(t=[],e=n;e=e.parentNode;)1===e.nodeType&&t.push({element:e,left:e.scrollLeft,top:e.scrollTop});for("function"==typeof n.focus&&n.focus(),n=0;n<t.length;n++)(e=t[n]).element.scrollLeft=e.left,e.element.scrollTop=e.top}}var mr=d&&"documentMode"in document&&11>=document.documentMode,hr=null,br=null,vr=null,yr=!1;function wr(e,t,n){var r=n.window===n?n.document:9===n.nodeType?n:n.ownerDocument;yr||null==hr||hr!==W(r)||("selectionStart"in(r=hr)&&fr(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},vr&&cr(vr,r)||(vr=r,0<(r=Gr(br,"onSelect")).length&&(t=new dn("onSelect","select",null,t,n),e.push({event:t,listeners:r}),t.target=hr)))}function _r(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var kr={animationend:_r("Animation","AnimationEnd"),animationiteration:_r("Animation","AnimationIteration"),animationstart:_r("Animation","AnimationStart"),transitionend:_r("Transition","TransitionEnd")},xr={},Sr={};function Er(e){if(xr[e])return xr[e];if(!kr[e])return e;var t,n=kr[e];for(t in n)if(n.hasOwnProperty(t)&&t in Sr)return xr[e]=n[t];return e}d&&(Sr=document.createElement("div").style,"AnimationEvent"in window||(delete kr.animationend.animation,delete kr.animationiteration.animation,delete kr.animationstart.animation),"TransitionEvent"in window||delete kr.transitionend.transition);var jr=Er("animationend"),Xr=Er("animationiteration"),Cr=Er("animationstart"),Tr=Er("transitionend"),Ar=new Map,Rr="abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");function Pr(e,t){Ar.set(e,t),c(t,[e])}for(var Nr=0;Nr<Rr.length;Nr++){var Lr=Rr[Nr];Pr(Lr.toLowerCase(),"on"+(Lr[0].toUpperCase()+Lr.slice(1)))}Pr(jr,"onAnimationEnd"),Pr(Xr,"onAnimationIteration"),Pr(Cr,"onAnimationStart"),Pr("dblclick","onDoubleClick"),Pr("focusin","onFocus"),Pr("focusout","onBlur"),Pr(Tr,"onTransitionEnd"),l("onMouseEnter",["mouseout","mouseover"]),l("onMouseLeave",["mouseout","mouseover"]),l("onPointerEnter",["pointerout","pointerover"]),l("onPointerLeave",["pointerout","pointerover"]),c("onChange","change click focusin focusout input keydown keyup selectionchange".split(" ")),c("onSelect","focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange".split(" ")),c("onBeforeInput",["compositionend","keypress","textInput","paste"]),c("onCompositionEnd","compositionend focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionStart","compositionstart focusout keydown keypress keyup mousedown".split(" ")),c("onCompositionUpdate","compositionupdate focusout keydown keypress keyup mousedown".split(" "));var Or="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Dr=new Set("cancel close invalid load scroll toggle".split(" ").concat(Or));function Ir(e,t,n){var r=e.type||"unknown-event";e.currentTarget=n,function(e,t,n,r,o,a,i,c,l){if(Be.apply(this,arguments),De){if(!De)throw Error(s(198));var d=Ie;De=!1,Ie=null,Me||(Me=!0,Fe=d)}}(r,t,void 0,e),e.currentTarget=null}function Mr(e,t){t=!!(4&t);for(var n=0;n<e.length;n++){var r=e[n],o=r.event;r=r.listeners;e:{var s=void 0;if(t)for(var a=r.length-1;0<=a;a--){var i=r[a],c=i.instance,l=i.currentTarget;if(i=i.listener,c!==s&&o.isPropagationStopped())break e;Ir(o,i,l),s=c}else for(a=0;a<r.length;a++){if(c=(i=r[a]).instance,l=i.currentTarget,i=i.listener,c!==s&&o.isPropagationStopped())break e;Ir(o,i,l),s=c}}}if(Me)throw e=Fe,Me=!1,Fe=null,e}function Fr(e,t){var n=t[ho];void 0===n&&(n=t[ho]=new Set);var r=e+"__bubble";n.has(r)||(Ur(t,e,2,!1),n.add(r))}function zr(e,t,n){var r=0;t&&(r|=4),Ur(n,e,r,t)}var Br="_reactListening"+Math.random().toString(36).slice(2);function qr(e){if(!e[Br]){e[Br]=!0,a.forEach((function(t){"selectionchange"!==t&&(Dr.has(t)||zr(t,!1,e),zr(t,!0,e))}));var t=9===e.nodeType?e:e.ownerDocument;null===t||t[Br]||(t[Br]=!0,zr("selectionchange",!1,t))}}function Ur(e,t,n,r){switch(Qt(t)){case 1:var o=Ht;break;case 4:o=Gt;break;default:o=Vt}n=o.bind(null,t,n,e),o=void 0,!Ne||"touchstart"!==t&&"touchmove"!==t&&"wheel"!==t||(o=!0),r?void 0!==o?e.addEventListener(t,n,{capture:!0,passive:o}):e.addEventListener(t,n,!0):void 0!==o?e.addEventListener(t,n,{passive:o}):e.addEventListener(t,n,!1)}function $r(e,t,n,r,o){var s=r;if(!(1&t||2&t||null===r))e:for(;;){if(null===r)return;var a=r.tag;if(3===a||4===a){var i=r.stateNode.containerInfo;if(i===o||8===i.nodeType&&i.parentNode===o)break;if(4===a)for(a=r.return;null!==a;){var c=a.tag;if((3===c||4===c)&&((c=a.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;a=a.return}for(;null!==i;){if(null===(a=yo(i)))return;if(5===(c=a.tag)||6===c){r=s=a;continue e}i=i.parentNode}}r=r.return}Re((function(){var r=s,o=_e(n),a=[];e:{var i=Ar.get(e);if(void 0!==i){var c=dn,l=e;switch(e){case"keypress":if(0===tn(n))break e;case"keydown":case"keyup":c=Xn;break;case"focusin":l="focus",c=hn;break;case"focusout":l="blur",c=hn;break;case"beforeblur":case"afterblur":c=hn;break;case"click":if(2===n.button)break e;case"auxclick":case"dblclick":case"mousedown":case"mousemove":case"mouseup":case"mouseout":case"mouseover":case"contextmenu":c=gn;break;case"drag":case"dragend":case"dragenter":case"dragexit":case"dragleave":case"dragover":case"dragstart":case"drop":c=mn;break;case"touchcancel":case"touchend":case"touchmove":case"touchstart":c=Tn;break;case jr:case Xr:case Cr:c=bn;break;case Tr:c=An;break;case"scroll":c=un;break;case"wheel":c=Pn;break;case"copy":case"cut":case"paste":c=yn;break;case"gotpointercapture":case"lostpointercapture":case"pointercancel":case"pointerdown":case"pointermove":case"pointerout":case"pointerover":case"pointerup":c=Cn}var d=!!(4&t),p=!d&&"scroll"===e,u=d?null!==i?i+"Capture":null:i;d=[];for(var f,g=r;null!==g;){var m=(f=g).stateNode;if(5===f.tag&&null!==m&&(f=m,null!==u&&(null!=(m=Pe(g,u))&&d.push(Hr(g,m,f)))),p)break;g=g.return}0<d.length&&(i=new c(i,l,null,n,o),a.push({event:i,listeners:d}))}}if(!(7&t)){if(c="mouseout"===e||"pointerout"===e,(!(i="mouseover"===e||"pointerover"===e)||n===we||!(l=n.relatedTarget||n.fromElement)||!yo(l)&&!l[mo])&&(c||i)&&(i=o.window===o?o:(i=o.ownerDocument)?i.defaultView||i.parentWindow:window,c?(c=r,null!==(l=(l=n.relatedTarget||n.toElement)?yo(l):null)&&(l!==(p=qe(l))||5!==l.tag&&6!==l.tag)&&(l=null)):(c=null,l=r),c!==l)){if(d=gn,m="onMouseLeave",u="onMouseEnter",g="mouse","pointerout"!==e&&"pointerover"!==e||(d=Cn,m="onPointerLeave",u="onPointerEnter",g="pointer"),p=null==c?i:_o(c),f=null==l?i:_o(l),(i=new d(m,g+"leave",c,n,o)).target=p,i.relatedTarget=f,m=null,yo(o)===r&&((d=new d(u,g+"enter",l,n,o)).target=f,d.relatedTarget=p,m=d),p=m,c&&l)e:{for(u=l,g=0,f=d=c;f;f=Vr(f))g++;for(f=0,m=u;m;m=Vr(m))f++;for(;0<g-f;)d=Vr(d),g--;for(;0<f-g;)u=Vr(u),f--;for(;g--;){if(d===u||null!==u&&d===u.alternate)break e;d=Vr(d),u=Vr(u)}d=null}else d=null;null!==c&&Wr(a,i,c,d,!1),null!==l&&null!==p&&Wr(a,p,l,d,!0)}if("select"===(c=(i=r?_o(r):window).nodeName&&i.nodeName.toLowerCase())||"input"===c&&"file"===i.type)var h=Qn;else if($n(i))if(Yn)h=ar;else{h=or;var b=rr}else(c=i.nodeName)&&"input"===c.toLowerCase()&&("checkbox"===i.type||"radio"===i.type)&&(h=sr);switch(h&&(h=h(e,r))?Hn(a,h,n,o):(b&&b(e,i,r),"focusout"===e&&(b=i._wrapperState)&&b.controlled&&"number"===i.type&&ee(i,"number",i.value)),b=r?_o(r):window,e){case"focusin":($n(b)||"true"===b.contentEditable)&&(hr=b,br=r,vr=null);break;case"focusout":vr=br=hr=null;break;case"mousedown":yr=!0;break;case"contextmenu":case"mouseup":case"dragend":yr=!1,wr(a,n,o);break;case"selectionchange":if(mr)break;case"keydown":case"keyup":wr(a,n,o)}var v;if(Ln)e:{switch(e){case"compositionstart":var y="onCompositionStart";break e;case"compositionend":y="onCompositionEnd";break e;case"compositionupdate":y="onCompositionUpdate";break e}y=void 0}else qn?zn(e,n)&&(y="onCompositionEnd"):"keydown"===e&&229===n.keyCode&&(y="onCompositionStart");y&&(In&&"ko"!==n.locale&&(qn||"onCompositionStart"!==y?"onCompositionEnd"===y&&qn&&(v=en()):(Zt="value"in(Yt=o)?Yt.value:Yt.textContent,qn=!0)),0<(b=Gr(r,y)).length&&(y=new wn(y,e,null,n,o),a.push({event:y,listeners:b}),v?y.data=v:null!==(v=Bn(n))&&(y.data=v))),(v=Dn?function(e,t){switch(e){case"compositionend":return Bn(t);case"keypress":return 32!==t.which?null:(Fn=!0,Mn);case"textInput":return(e=t.data)===Mn&&Fn?null:e;default:return null}}(e,n):function(e,t){if(qn)return"compositionend"===e||!Ln&&zn(e,t)?(e=en(),Jt=Zt=Yt=null,qn=!1,e):null;switch(e){case"paste":default:return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1<t.char.length)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case"compositionend":return In&&"ko"!==t.locale?null:t.data}}(e,n))&&(0<(r=Gr(r,"onBeforeInput")).length&&(o=new wn("onBeforeInput","beforeinput",null,n,o),a.push({event:o,listeners:r}),o.data=v))}Mr(a,t)}))}function Hr(e,t,n){return{instance:e,listener:t,currentTarget:n}}function Gr(e,t){for(var n=t+"Capture",r=[];null!==e;){var o=e,s=o.stateNode;5===o.tag&&null!==s&&(o=s,null!=(s=Pe(e,n))&&r.unshift(Hr(e,s,o)),null!=(s=Pe(e,t))&&r.push(Hr(e,s,o))),e=e.return}return r}function Vr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Wr(e,t,n,r,o){for(var s=t._reactName,a=[];null!==n&&n!==r;){var i=n,c=i.alternate,l=i.stateNode;if(null!==c&&c===r)break;5===i.tag&&null!==l&&(i=l,o?null!=(c=Pe(n,s))&&a.unshift(Hr(n,c,i)):o||null!=(c=Pe(n,s))&&a.push(Hr(n,c,i))),n=n.return}0!==a.length&&e.push({event:t,listeners:a})}var Kr=/\r\n?/g,Qr=/\u0000|\uFFFD/g;function Yr(e){return("string"==typeof e?e:""+e).replace(Kr,"\n").replace(Qr,"")}function Zr(e,t,n){if(t=Yr(t),Yr(e)!==t&&n)throw Error(s(425))}function Jr(){}var eo=null,to=null;function no(e,t){return"textarea"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var ro="function"==typeof setTimeout?setTimeout:void 0,oo="function"==typeof clearTimeout?clearTimeout:void 0,so="function"==typeof Promise?Promise:void 0,ao="function"==typeof queueMicrotask?queueMicrotask:void 0!==so?function(e){return so.resolve(null).then(e).catch(io)}:ro;function io(e){setTimeout((function(){throw e}))}function co(e,t){var n=t,r=0;do{var o=n.nextSibling;if(e.removeChild(n),o&&8===o.nodeType)if("/$"===(n=o.data)){if(0===r)return e.removeChild(o),void qt(t);r--}else"$"!==n&&"$?"!==n&&"$!"!==n||r++;n=o}while(n);qt(t)}function lo(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break;if(8===t){if("$"===(t=e.data)||"$!"===t||"$?"===t)break;if("/$"===t)return null}}return e}function po(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||"$!"===n||"$?"===n){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var uo=Math.random().toString(36).slice(2),fo="__reactFiber$"+uo,go="__reactProps$"+uo,mo="__reactContainer$"+uo,ho="__reactEvents$"+uo,bo="__reactListeners$"+uo,vo="__reactHandles$"+uo;function yo(e){var t=e[fo];if(t)return t;for(var n=e.parentNode;n;){if(t=n[mo]||n[fo]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=po(e);null!==e;){if(n=e[fo])return n;e=po(e)}return t}n=(e=n).parentNode}return null}function wo(e){return!(e=e[fo]||e[mo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function _o(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(s(33))}function ko(e){return e[go]||null}var xo=[],So=-1;function Eo(e){return{current:e}}function jo(e){0>So||(e.current=xo[So],xo[So]=null,So--)}function Xo(e,t){So++,xo[So]=e.current,e.current=t}var Co={},To=Eo(Co),Ao=Eo(!1),Ro=Co;function Po(e,t){var n=e.type.contextTypes;if(!n)return Co;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var o,s={};for(o in n)s[o]=t[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=s),s}function No(e){return null!=(e=e.childContextTypes)}function Lo(){jo(Ao),jo(To)}function Oo(e,t,n){if(To.current!==Co)throw Error(s(168));Xo(To,t),Xo(Ao,n)}function Do(e,t,n){var r=e.stateNode;if(t=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in t))throw Error(s(108,U(e)||"Unknown",o));return I({},n,r)}function Io(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||Co,Ro=To.current,Xo(To,e),Xo(Ao,Ao.current),!0}function Mo(e,t,n){var r=e.stateNode;if(!r)throw Error(s(169));n?(e=Do(e,t,Ro),r.__reactInternalMemoizedMergedChildContext=e,jo(Ao),jo(To),Xo(To,e)):jo(Ao),Xo(Ao,n)}var Fo=null,zo=!1,Bo=!1;function qo(e){null===Fo?Fo=[e]:Fo.push(e)}function Uo(){if(!Bo&&null!==Fo){Bo=!0;var e=0,t=yt;try{var n=Fo;for(yt=1;e<n.length;e++){var r=n[e];do{r=r(!0)}while(null!==r)}Fo=null,zo=!1}catch(o){throw null!==Fo&&(Fo=Fo.slice(e+1)),Ve(Je,Uo),o}finally{yt=t,Bo=!1}}return null}var $o=[],Ho=0,Go=null,Vo=0,Wo=[],Ko=0,Qo=null,Yo=1,Zo="";function Jo(e,t){$o[Ho++]=Vo,$o[Ho++]=Go,Go=e,Vo=t}function es(e,t,n){Wo[Ko++]=Yo,Wo[Ko++]=Zo,Wo[Ko++]=Qo,Qo=e;var r=Yo;e=Zo;var o=32-at(r)-1;r&=~(1<<o),n+=1;var s=32-at(t)+o;if(30<s){var a=o-o%5;s=(r&(1<<a)-1).toString(32),r>>=a,o-=a,Yo=1<<32-at(t)+o|n<<o|r,Zo=s+e}else Yo=1<<s|n<<o|r,Zo=e}function ts(e){null!==e.return&&(Jo(e,1),es(e,1,0))}function ns(e){for(;e===Go;)Go=$o[--Ho],$o[Ho]=null,Vo=$o[--Ho],$o[Ho]=null;for(;e===Qo;)Qo=Wo[--Ko],Wo[Ko]=null,Zo=Wo[--Ko],Wo[Ko]=null,Yo=Wo[--Ko],Wo[Ko]=null}var rs=null,os=null,ss=!1,as=null;function is(e,t){var n=Rl(5,null,null,0);n.elementType="DELETED",n.stateNode=t,n.return=e,null===(t=e.deletions)?(e.deletions=[n],e.flags|=16):t.push(n)}function cs(e,t){switch(e.tag){case 5:var n=e.type;return null!==(t=1!==t.nodeType||n.toLowerCase()!==t.nodeName.toLowerCase()?null:t)&&(e.stateNode=t,rs=e,os=lo(t.firstChild),!0);case 6:return null!==(t=""===e.pendingProps||3!==t.nodeType?null:t)&&(e.stateNode=t,rs=e,os=null,!0);case 13:return null!==(t=8!==t.nodeType?null:t)&&(n=null!==Qo?{id:Yo,overflow:Zo}:null,e.memoizedState={dehydrated:t,treeContext:n,retryLane:1073741824},(n=Rl(18,null,null,0)).stateNode=t,n.return=e,e.child=n,rs=e,os=null,!0);default:return!1}}function ls(e){return!(!(1&e.mode)||128&e.flags)}function ds(e){if(ss){var t=os;if(t){var n=t;if(!cs(e,t)){if(ls(e))throw Error(s(418));t=lo(n.nextSibling);var r=rs;t&&cs(e,t)?is(r,n):(e.flags=-4097&e.flags|2,ss=!1,rs=e)}}else{if(ls(e))throw Error(s(418));e.flags=-4097&e.flags|2,ss=!1,rs=e}}}function ps(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;rs=e}function us(e){if(e!==rs)return!1;if(!ss)return ps(e),ss=!0,!1;var t;if((t=3!==e.tag)&&!(t=5!==e.tag)&&(t="head"!==(t=e.type)&&"body"!==t&&!no(e.type,e.memoizedProps)),t&&(t=os)){if(ls(e))throw fs(),Error(s(418));for(;t;)is(e,t),t=lo(t.nextSibling)}if(ps(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(s(317));e:{for(e=e.nextSibling,t=0;e;){if(8===e.nodeType){var n=e.data;if("/$"===n){if(0===t){os=lo(e.nextSibling);break e}t--}else"$"!==n&&"$!"!==n&&"$?"!==n||t++}e=e.nextSibling}os=null}}else os=rs?lo(e.stateNode.nextSibling):null;return!0}function fs(){for(var e=os;e;)e=lo(e.nextSibling)}function gs(){os=rs=null,ss=!1}function ms(e){null===as?as=[e]:as.push(e)}var hs=w.ReactCurrentBatchConfig;function bs(e,t,n){if(null!==(e=n.ref)&&"function"!=typeof e&&"object"!=typeof e){if(n._owner){if(n=n._owner){if(1!==n.tag)throw Error(s(309));var r=n.stateNode}if(!r)throw Error(s(147,e));var o=r,a=""+e;return null!==t&&null!==t.ref&&"function"==typeof t.ref&&t.ref._stringRef===a?t.ref:(t=function(e){var t=o.refs;null===e?delete t[a]:t[a]=e},t._stringRef=a,t)}if("string"!=typeof e)throw Error(s(284));if(!n._owner)throw Error(s(290,e))}return e}function vs(e,t){throw e=Object.prototype.toString.call(t),Error(s(31,"[object Object]"===e?"object with keys {"+Object.keys(t).join(", ")+"}":e))}function ys(e){return(0,e._init)(e._payload)}function ws(e){function t(t,n){if(e){var r=t.deletions;null===r?(t.deletions=[n],t.flags|=16):r.push(n)}}function n(n,r){if(!e)return null;for(;null!==r;)t(n,r),r=r.sibling;return null}function r(e,t){for(e=new Map;null!==t;)null!==t.key?e.set(t.key,t):e.set(t.index,t),t=t.sibling;return e}function o(e,t){return(e=Nl(e,t)).index=0,e.sibling=null,e}function a(t,n,r){return t.index=r,e?null!==(r=t.alternate)?(r=r.index)<n?(t.flags|=2,n):r:(t.flags|=2,n):(t.flags|=1048576,n)}function i(t){return e&&null===t.alternate&&(t.flags|=2),t}function c(e,t,n,r){return null===t||6!==t.tag?((t=Il(n,e.mode,r)).return=e,t):((t=o(t,n)).return=e,t)}function l(e,t,n,r){var s=n.type;return s===x?p(e,t,n.props.children,r,n.key):null!==t&&(t.elementType===s||"object"==typeof s&&null!==s&&s.$$typeof===P&&ys(s)===t.type)?((r=o(t,n.props)).ref=bs(e,t,n),r.return=e,r):((r=Ll(n.type,n.key,n.props,null,e.mode,r)).ref=bs(e,t,n),r.return=e,r)}function d(e,t,n,r){return null===t||4!==t.tag||t.stateNode.containerInfo!==n.containerInfo||t.stateNode.implementation!==n.implementation?((t=Ml(n,e.mode,r)).return=e,t):((t=o(t,n.children||[])).return=e,t)}function p(e,t,n,r,s){return null===t||7!==t.tag?((t=Ol(n,e.mode,r,s)).return=e,t):((t=o(t,n)).return=e,t)}function u(e,t,n){if("string"==typeof t&&""!==t||"number"==typeof t)return(t=Il(""+t,e.mode,n)).return=e,t;if("object"==typeof t&&null!==t){switch(t.$$typeof){case _:return(n=Ll(t.type,t.key,t.props,null,e.mode,n)).ref=bs(e,null,t),n.return=e,n;case k:return(t=Ml(t,e.mode,n)).return=e,t;case P:return u(e,(0,t._init)(t._payload),n)}if(te(t)||O(t))return(t=Ol(t,e.mode,n,null)).return=e,t;vs(e,t)}return null}function f(e,t,n,r){var o=null!==t?t.key:null;if("string"==typeof n&&""!==n||"number"==typeof n)return null!==o?null:c(e,t,""+n,r);if("object"==typeof n&&null!==n){switch(n.$$typeof){case _:return n.key===o?l(e,t,n,r):null;case k:return n.key===o?d(e,t,n,r):null;case P:return f(e,t,(o=n._init)(n._payload),r)}if(te(n)||O(n))return null!==o?null:p(e,t,n,r,null);vs(e,n)}return null}function g(e,t,n,r,o){if("string"==typeof r&&""!==r||"number"==typeof r)return c(t,e=e.get(n)||null,""+r,o);if("object"==typeof r&&null!==r){switch(r.$$typeof){case _:return l(t,e=e.get(null===r.key?n:r.key)||null,r,o);case k:return d(t,e=e.get(null===r.key?n:r.key)||null,r,o);case P:return g(e,t,n,(0,r._init)(r._payload),o)}if(te(r)||O(r))return p(t,e=e.get(n)||null,r,o,null);vs(t,r)}return null}function m(o,s,i,c){for(var l=null,d=null,p=s,m=s=0,h=null;null!==p&&m<i.length;m++){p.index>m?(h=p,p=null):h=p.sibling;var b=f(o,p,i[m],c);if(null===b){null===p&&(p=h);break}e&&p&&null===b.alternate&&t(o,p),s=a(b,s,m),null===d?l=b:d.sibling=b,d=b,p=h}if(m===i.length)return n(o,p),ss&&Jo(o,m),l;if(null===p){for(;m<i.length;m++)null!==(p=u(o,i[m],c))&&(s=a(p,s,m),null===d?l=p:d.sibling=p,d=p);return ss&&Jo(o,m),l}for(p=r(o,p);m<i.length;m++)null!==(h=g(p,o,m,i[m],c))&&(e&&null!==h.alternate&&p.delete(null===h.key?m:h.key),s=a(h,s,m),null===d?l=h:d.sibling=h,d=h);return e&&p.forEach((function(e){return t(o,e)})),ss&&Jo(o,m),l}function h(o,i,c,l){var d=O(c);if("function"!=typeof d)throw Error(s(150));if(null==(c=d.call(c)))throw Error(s(151));for(var p=d=null,m=i,h=i=0,b=null,v=c.next();null!==m&&!v.done;h++,v=c.next()){m.index>h?(b=m,m=null):b=m.sibling;var y=f(o,m,v.value,l);if(null===y){null===m&&(m=b);break}e&&m&&null===y.alternate&&t(o,m),i=a(y,i,h),null===p?d=y:p.sibling=y,p=y,m=b}if(v.done)return n(o,m),ss&&Jo(o,h),d;if(null===m){for(;!v.done;h++,v=c.next())null!==(v=u(o,v.value,l))&&(i=a(v,i,h),null===p?d=v:p.sibling=v,p=v);return ss&&Jo(o,h),d}for(m=r(o,m);!v.done;h++,v=c.next())null!==(v=g(m,o,h,v.value,l))&&(e&&null!==v.alternate&&m.delete(null===v.key?h:v.key),i=a(v,i,h),null===p?d=v:p.sibling=v,p=v);return e&&m.forEach((function(e){return t(o,e)})),ss&&Jo(o,h),d}return function e(r,s,a,c){if("object"==typeof a&&null!==a&&a.type===x&&null===a.key&&(a=a.props.children),"object"==typeof a&&null!==a){switch(a.$$typeof){case _:e:{for(var l=a.key,d=s;null!==d;){if(d.key===l){if((l=a.type)===x){if(7===d.tag){n(r,d.sibling),(s=o(d,a.props.children)).return=r,r=s;break e}}else if(d.elementType===l||"object"==typeof l&&null!==l&&l.$$typeof===P&&ys(l)===d.type){n(r,d.sibling),(s=o(d,a.props)).ref=bs(r,d,a),s.return=r,r=s;break e}n(r,d);break}t(r,d),d=d.sibling}a.type===x?((s=Ol(a.props.children,r.mode,c,a.key)).return=r,r=s):((c=Ll(a.type,a.key,a.props,null,r.mode,c)).ref=bs(r,s,a),c.return=r,r=c)}return i(r);case k:e:{for(d=a.key;null!==s;){if(s.key===d){if(4===s.tag&&s.stateNode.containerInfo===a.containerInfo&&s.stateNode.implementation===a.implementation){n(r,s.sibling),(s=o(s,a.children||[])).return=r,r=s;break e}n(r,s);break}t(r,s),s=s.sibling}(s=Ml(a,r.mode,c)).return=r,r=s}return i(r);case P:return e(r,s,(d=a._init)(a._payload),c)}if(te(a))return m(r,s,a,c);if(O(a))return h(r,s,a,c);vs(r,a)}return"string"==typeof a&&""!==a||"number"==typeof a?(a=""+a,null!==s&&6===s.tag?(n(r,s.sibling),(s=o(s,a)).return=r,r=s):(n(r,s),(s=Il(a,r.mode,c)).return=r,r=s),i(r)):n(r,s)}}var _s=ws(!0),ks=ws(!1),xs=Eo(null),Ss=null,Es=null,js=null;function Xs(){js=Es=Ss=null}function Cs(e){var t=xs.current;jo(xs),e._currentValue=t}function Ts(e,t,n){for(;null!==e;){var r=e.alternate;if((e.childLanes&t)!==t?(e.childLanes|=t,null!==r&&(r.childLanes|=t)):null!==r&&(r.childLanes&t)!==t&&(r.childLanes|=t),e===n)break;e=e.return}}function As(e,t){Ss=e,js=Es=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(!!(e.lanes&t)&&(yi=!0),e.firstContext=null)}function Rs(e){var t=e._currentValue;if(js!==e)if(e={context:e,memoizedValue:t,next:null},null===Es){if(null===Ss)throw Error(s(308));Es=e,Ss.dependencies={lanes:0,firstContext:e}}else Es=Es.next=e;return t}var Ps=null;function Ns(e){null===Ps?Ps=[e]:Ps.push(e)}function Ls(e,t,n,r){var o=t.interleaved;return null===o?(n.next=n,Ns(t)):(n.next=o.next,o.next=n),t.interleaved=n,Os(e,r)}function Os(e,t){e.lanes|=t;var n=e.alternate;for(null!==n&&(n.lanes|=t),n=e,e=e.return;null!==e;)e.childLanes|=t,null!==(n=e.alternate)&&(n.childLanes|=t),n=e,e=e.return;return 3===n.tag?n.stateNode:null}var Ds=!1;function Is(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,interleaved:null,lanes:0},effects:null}}function Ms(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function Fs(e,t){return{eventTime:e,lane:t,tag:0,payload:null,callback:null,next:null}}function zs(e,t,n){var r=e.updateQueue;if(null===r)return null;if(r=r.shared,2&Cc){var o=r.pending;return null===o?t.next=t:(t.next=o.next,o.next=t),r.pending=t,Os(e,n)}return null===(o=r.interleaved)?(t.next=t,Ns(r)):(t.next=o.next,o.next=t),r.interleaved=t,Os(e,n)}function Bs(e,t,n){if(null!==(t=t.updateQueue)&&(t=t.shared,4194240&n)){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,vt(e,n)}}function qs(e,t){var n=e.updateQueue,r=e.alternate;if(null!==r&&n===(r=r.updateQueue)){var o=null,s=null;if(null!==(n=n.firstBaseUpdate)){do{var a={eventTime:n.eventTime,lane:n.lane,tag:n.tag,payload:n.payload,callback:n.callback,next:null};null===s?o=s=a:s=s.next=a,n=n.next}while(null!==n);null===s?o=s=t:s=s.next=t}else o=s=t;return n={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:s,shared:r.shared,effects:r.effects},void(e.updateQueue=n)}null===(e=n.lastBaseUpdate)?n.firstBaseUpdate=t:e.next=t,n.lastBaseUpdate=t}function Us(e,t,n,r){var o=e.updateQueue;Ds=!1;var s=o.firstBaseUpdate,a=o.lastBaseUpdate,i=o.shared.pending;if(null!==i){o.shared.pending=null;var c=i,l=c.next;c.next=null,null===a?s=l:a.next=l,a=c;var d=e.alternate;null!==d&&((i=(d=d.updateQueue).lastBaseUpdate)!==a&&(null===i?d.firstBaseUpdate=l:i.next=l,d.lastBaseUpdate=c))}if(null!==s){var p=o.baseState;for(a=0,d=l=c=null,i=s;;){var u=i.lane,f=i.eventTime;if((r&u)===u){null!==d&&(d=d.next={eventTime:f,lane:0,tag:i.tag,payload:i.payload,callback:i.callback,next:null});e:{var g=e,m=i;switch(u=t,f=n,m.tag){case 1:if("function"==typeof(g=m.payload)){p=g.call(f,p,u);break e}p=g;break e;case 3:g.flags=-65537&g.flags|128;case 0:if(null==(u="function"==typeof(g=m.payload)?g.call(f,p,u):g))break e;p=I({},p,u);break e;case 2:Ds=!0}}null!==i.callback&&0!==i.lane&&(e.flags|=64,null===(u=o.effects)?o.effects=[i]:u.push(i))}else f={eventTime:f,lane:u,tag:i.tag,payload:i.payload,callback:i.callback,next:null},null===d?(l=d=f,c=p):d=d.next=f,a|=u;if(null===(i=i.next)){if(null===(i=o.shared.pending))break;i=(u=i).next,u.next=null,o.lastBaseUpdate=u,o.shared.pending=null}}if(null===d&&(c=p),o.baseState=c,o.firstBaseUpdate=l,o.lastBaseUpdate=d,null!==(t=o.shared.interleaved)){o=t;do{a|=o.lane,o=o.next}while(o!==t)}else null===s&&(o.shared.lanes=0);Dc|=a,e.lanes=a,e.memoizedState=p}}function $s(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;t<e.length;t++){var r=e[t],o=r.callback;if(null!==o){if(r.callback=null,r=n,"function"!=typeof o)throw Error(s(191,o));o.call(r)}}}var Hs={},Gs=Eo(Hs),Vs=Eo(Hs),Ws=Eo(Hs);function Ks(e){if(e===Hs)throw Error(s(174));return e}function Qs(e,t){switch(Xo(Ws,t),Xo(Vs,e),Xo(Gs,Hs),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:ce(null,"");break;default:t=ce(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}jo(Gs),Xo(Gs,t)}function Ys(){jo(Gs),jo(Vs),jo(Ws)}function Zs(e){Ks(Ws.current);var t=Ks(Gs.current),n=ce(t,e.type);t!==n&&(Xo(Vs,e),Xo(Gs,n))}function Js(e){Vs.current===e&&(jo(Gs),jo(Vs))}var ea=Eo(0);function ta(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||"$?"===n.data||"$!"===n.data))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(128&t.flags)return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}var na=[];function ra(){for(var e=0;e<na.length;e++)na[e]._workInProgressVersionPrimary=null;na.length=0}var oa=w.ReactCurrentDispatcher,sa=w.ReactCurrentBatchConfig,aa=0,ia=null,ca=null,la=null,da=!1,pa=!1,ua=0,fa=0;function ga(){throw Error(s(321))}function ma(e,t){if(null===t)return!1;for(var n=0;n<t.length&&n<e.length;n++)if(!ir(e[n],t[n]))return!1;return!0}function ha(e,t,n,r,o,a){if(aa=a,ia=t,t.memoizedState=null,t.updateQueue=null,t.lanes=0,oa.current=null===e||null===e.memoizedState?Ja:ei,e=n(r,o),pa){a=0;do{if(pa=!1,ua=0,25<=a)throw Error(s(301));a+=1,la=ca=null,t.updateQueue=null,oa.current=ti,e=n(r,o)}while(pa)}if(oa.current=Za,t=null!==ca&&null!==ca.next,aa=0,la=ca=ia=null,da=!1,t)throw Error(s(300));return e}function ba(){var e=0!==ua;return ua=0,e}function va(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===la?ia.memoizedState=la=e:la=la.next=e,la}function ya(){if(null===ca){var e=ia.alternate;e=null!==e?e.memoizedState:null}else e=ca.next;var t=null===la?ia.memoizedState:la.next;if(null!==t)la=t,ca=e;else{if(null===e)throw Error(s(310));e={memoizedState:(ca=e).memoizedState,baseState:ca.baseState,baseQueue:ca.baseQueue,queue:ca.queue,next:null},null===la?ia.memoizedState=la=e:la=la.next=e}return la}function wa(e,t){return"function"==typeof t?t(e):t}function _a(e){var t=ya(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var r=ca,o=r.baseQueue,a=n.pending;if(null!==a){if(null!==o){var i=o.next;o.next=a.next,a.next=i}r.baseQueue=o=a,n.pending=null}if(null!==o){a=o.next,r=r.baseState;var c=i=null,l=null,d=a;do{var p=d.lane;if((aa&p)===p)null!==l&&(l=l.next={lane:0,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null}),r=d.hasEagerState?d.eagerState:e(r,d.action);else{var u={lane:p,action:d.action,hasEagerState:d.hasEagerState,eagerState:d.eagerState,next:null};null===l?(c=l=u,i=r):l=l.next=u,ia.lanes|=p,Dc|=p}d=d.next}while(null!==d&&d!==a);null===l?i=r:l.next=c,ir(r,t.memoizedState)||(yi=!0),t.memoizedState=r,t.baseState=i,t.baseQueue=l,n.lastRenderedState=r}if(null!==(e=n.interleaved)){o=e;do{a=o.lane,ia.lanes|=a,Dc|=a,o=o.next}while(o!==e)}else null===o&&(n.lanes=0);return[t.memoizedState,n.dispatch]}function ka(e){var t=ya(),n=t.queue;if(null===n)throw Error(s(311));n.lastRenderedReducer=e;var r=n.dispatch,o=n.pending,a=t.memoizedState;if(null!==o){n.pending=null;var i=o=o.next;do{a=e(a,i.action),i=i.next}while(i!==o);ir(a,t.memoizedState)||(yi=!0),t.memoizedState=a,null===t.baseQueue&&(t.baseState=a),n.lastRenderedState=a}return[a,r]}function xa(){}function Sa(e,t){var n=ia,r=ya(),o=t(),a=!ir(r.memoizedState,o);if(a&&(r.memoizedState=o,yi=!0),r=r.queue,Da(Xa.bind(null,n,r,e),[e]),r.getSnapshot!==t||a||null!==la&&1&la.memoizedState.tag){if(n.flags|=2048,Ra(9,ja.bind(null,n,r,o,t),void 0,null),null===Tc)throw Error(s(349));30&aa||Ea(n,t,o)}return o}function Ea(e,t,n){e.flags|=16384,e={getSnapshot:t,value:n},null===(t=ia.updateQueue)?(t={lastEffect:null,stores:null},ia.updateQueue=t,t.stores=[e]):null===(n=t.stores)?t.stores=[e]:n.push(e)}function ja(e,t,n,r){t.value=n,t.getSnapshot=r,Ca(t)&&Ta(e)}function Xa(e,t,n){return n((function(){Ca(t)&&Ta(e)}))}function Ca(e){var t=e.getSnapshot;e=e.value;try{var n=t();return!ir(e,n)}catch(r){return!0}}function Ta(e){var t=Os(e,1);null!==t&&nl(t,e,1,-1)}function Aa(e){var t=va();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:wa,lastRenderedState:e},t.queue=e,e=e.dispatch=Wa.bind(null,ia,e),[t.memoizedState,e]}function Ra(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=ia.updateQueue)?(t={lastEffect:null,stores:null},ia.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function Pa(){return ya().memoizedState}function Na(e,t,n,r){var o=va();ia.flags|=e,o.memoizedState=Ra(1|t,n,void 0,void 0===r?null:r)}function La(e,t,n,r){var o=ya();r=void 0===r?null:r;var s=void 0;if(null!==ca){var a=ca.memoizedState;if(s=a.destroy,null!==r&&ma(r,a.deps))return void(o.memoizedState=Ra(t,n,s,r))}ia.flags|=e,o.memoizedState=Ra(1|t,n,s,r)}function Oa(e,t){return Na(8390656,8,e,t)}function Da(e,t){return La(2048,8,e,t)}function Ia(e,t){return La(4,2,e,t)}function Ma(e,t){return La(4,4,e,t)}function Fa(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function za(e,t,n){return n=null!=n?n.concat([e]):null,La(4,4,Fa.bind(null,t,e),n)}function Ba(){}function qa(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ma(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function Ua(e,t){var n=ya();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&ma(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function $a(e,t,n){return 21&aa?(ir(n,t)||(n=mt(),ia.lanes|=n,Dc|=n,e.baseState=!0),t):(e.baseState&&(e.baseState=!1,yi=!0),e.memoizedState=n)}function Ha(e,t){var n=yt;yt=0!==n&&4>n?n:4,e(!0);var r=sa.transition;sa.transition={};try{e(!1),t()}finally{yt=n,sa.transition=r}}function Ga(){return ya().memoizedState}function Va(e,t,n){var r=tl(e);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},Ka(e))Qa(t,n);else if(null!==(n=Ls(e,t,n,r))){nl(n,e,r,el()),Ya(n,t,r)}}function Wa(e,t,n){var r=tl(e),o={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(Ka(e))Qa(t,o);else{var s=e.alternate;if(0===e.lanes&&(null===s||0===s.lanes)&&null!==(s=t.lastRenderedReducer))try{var a=t.lastRenderedState,i=s(a,n);if(o.hasEagerState=!0,o.eagerState=i,ir(i,a)){var c=t.interleaved;return null===c?(o.next=o,Ns(t)):(o.next=c.next,c.next=o),void(t.interleaved=o)}}catch(l){}null!==(n=Ls(e,t,o,r))&&(nl(n,e,r,o=el()),Ya(n,t,r))}}function Ka(e){var t=e.alternate;return e===ia||null!==t&&t===ia}function Qa(e,t){pa=da=!0;var n=e.pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}function Ya(e,t,n){if(4194240&n){var r=t.lanes;n|=r&=e.pendingLanes,t.lanes=n,vt(e,n)}}var Za={readContext:Rs,useCallback:ga,useContext:ga,useEffect:ga,useImperativeHandle:ga,useInsertionEffect:ga,useLayoutEffect:ga,useMemo:ga,useReducer:ga,useRef:ga,useState:ga,useDebugValue:ga,useDeferredValue:ga,useTransition:ga,useMutableSource:ga,useSyncExternalStore:ga,useId:ga,unstable_isNewReconciler:!1},Ja={readContext:Rs,useCallback:function(e,t){return va().memoizedState=[e,void 0===t?null:t],e},useContext:Rs,useEffect:Oa,useImperativeHandle:function(e,t,n){return n=null!=n?n.concat([e]):null,Na(4194308,4,Fa.bind(null,t,e),n)},useLayoutEffect:function(e,t){return Na(4194308,4,e,t)},useInsertionEffect:function(e,t){return Na(4,2,e,t)},useMemo:function(e,t){var n=va();return t=void 0===t?null:t,e=e(),n.memoizedState=[e,t],e},useReducer:function(e,t,n){var r=va();return t=void 0!==n?n(t):t,r.memoizedState=r.baseState=t,e={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:t},r.queue=e,e=e.dispatch=Va.bind(null,ia,e),[r.memoizedState,e]},useRef:function(e){return e={current:e},va().memoizedState=e},useState:Aa,useDebugValue:Ba,useDeferredValue:function(e){return va().memoizedState=e},useTransition:function(){var e=Aa(!1),t=e[0];return e=Ha.bind(null,e[1]),va().memoizedState=e,[t,e]},useMutableSource:function(){},useSyncExternalStore:function(e,t,n){var r=ia,o=va();if(ss){if(void 0===n)throw Error(s(407));n=n()}else{if(n=t(),null===Tc)throw Error(s(349));30&aa||Ea(r,t,n)}o.memoizedState=n;var a={value:n,getSnapshot:t};return o.queue=a,Oa(Xa.bind(null,r,a,e),[e]),r.flags|=2048,Ra(9,ja.bind(null,r,a,n,t),void 0,null),n},useId:function(){var e=va(),t=Tc.identifierPrefix;if(ss){var n=Zo;t=":"+t+"R"+(n=(Yo&~(1<<32-at(Yo)-1)).toString(32)+n),0<(n=ua++)&&(t+="H"+n.toString(32)),t+=":"}else t=":"+t+"r"+(n=fa++).toString(32)+":";return e.memoizedState=t},unstable_isNewReconciler:!1},ei={readContext:Rs,useCallback:qa,useContext:Rs,useEffect:Da,useImperativeHandle:za,useInsertionEffect:Ia,useLayoutEffect:Ma,useMemo:Ua,useReducer:_a,useRef:Pa,useState:function(){return _a(wa)},useDebugValue:Ba,useDeferredValue:function(e){return $a(ya(),ca.memoizedState,e)},useTransition:function(){return[_a(wa)[0],ya().memoizedState]},useMutableSource:xa,useSyncExternalStore:Sa,useId:Ga,unstable_isNewReconciler:!1},ti={readContext:Rs,useCallback:qa,useContext:Rs,useEffect:Da,useImperativeHandle:za,useInsertionEffect:Ia,useLayoutEffect:Ma,useMemo:Ua,useReducer:ka,useRef:Pa,useState:function(){return ka(wa)},useDebugValue:Ba,useDeferredValue:function(e){var t=ya();return null===ca?t.memoizedState=e:$a(t,ca.memoizedState,e)},useTransition:function(){return[ka(wa)[0],ya().memoizedState]},useMutableSource:xa,useSyncExternalStore:Sa,useId:Ga,unstable_isNewReconciler:!1};function ni(e,t){if(e&&e.defaultProps){for(var n in t=I({},t),e=e.defaultProps)void 0===t[n]&&(t[n]=e[n]);return t}return t}function ri(e,t,n,r){n=null==(n=n(r,t=e.memoizedState))?t:I({},t,n),e.memoizedState=n,0===e.lanes&&(e.updateQueue.baseState=n)}var oi={isMounted:function(e){return!!(e=e._reactInternals)&&qe(e)===e},enqueueSetState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),s=Fs(r,o);s.payload=t,null!=n&&(s.callback=n),null!==(t=zs(e,s,o))&&(nl(t,e,o,r),Bs(t,e,o))},enqueueReplaceState:function(e,t,n){e=e._reactInternals;var r=el(),o=tl(e),s=Fs(r,o);s.tag=1,s.payload=t,null!=n&&(s.callback=n),null!==(t=zs(e,s,o))&&(nl(t,e,o,r),Bs(t,e,o))},enqueueForceUpdate:function(e,t){e=e._reactInternals;var n=el(),r=tl(e),o=Fs(n,r);o.tag=2,null!=t&&(o.callback=t),null!==(t=zs(e,o,r))&&(nl(t,e,r,n),Bs(t,e,r))}};function si(e,t,n,r,o,s,a){return"function"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,s,a):!t.prototype||!t.prototype.isPureReactComponent||(!cr(n,r)||!cr(o,s))}function ai(e,t,n){var r=!1,o=Co,s=t.contextType;return"object"==typeof s&&null!==s?s=Rs(s):(o=No(t)?Ro:To.current,s=(r=null!=(r=t.contextTypes))?Po(e,o):Co),t=new t(n,s),e.memoizedState=null!==t.state&&void 0!==t.state?t.state:null,t.updater=oi,e.stateNode=t,t._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=s),t}function ii(e,t,n,r){e=t.state,"function"==typeof t.componentWillReceiveProps&&t.componentWillReceiveProps(n,r),"function"==typeof t.UNSAFE_componentWillReceiveProps&&t.UNSAFE_componentWillReceiveProps(n,r),t.state!==e&&oi.enqueueReplaceState(t,t.state,null)}function ci(e,t,n,r){var o=e.stateNode;o.props=n,o.state=e.memoizedState,o.refs={},Is(e);var s=t.contextType;"object"==typeof s&&null!==s?o.context=Rs(s):(s=No(t)?Ro:To.current,o.context=Po(e,s)),o.state=e.memoizedState,"function"==typeof(s=t.getDerivedStateFromProps)&&(ri(e,t,s,n),o.state=e.memoizedState),"function"==typeof t.getDerivedStateFromProps||"function"==typeof o.getSnapshotBeforeUpdate||"function"!=typeof o.UNSAFE_componentWillMount&&"function"!=typeof o.componentWillMount||(t=o.state,"function"==typeof o.componentWillMount&&o.componentWillMount(),"function"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),t!==o.state&&oi.enqueueReplaceState(o,o.state,null),Us(e,n,o,r),o.state=e.memoizedState),"function"==typeof o.componentDidMount&&(e.flags|=4194308)}function li(e,t){try{var n="",r=t;do{n+=B(r),r=r.return}while(r);var o=n}catch(s){o="\nError generating stack: "+s.message+"\n"+s.stack}return{value:e,source:t,stack:o,digest:null}}function di(e,t,n){return{value:e,source:null,stack:null!=n?n:null,digest:null!=t?t:null}}function pi(e,t){try{console.error(t.value)}catch(n){setTimeout((function(){throw n}))}}var ui="function"==typeof WeakMap?WeakMap:Map;function fi(e,t,n){(n=Fs(-1,n)).tag=3,n.payload={element:null};var r=t.value;return n.callback=function(){$c||($c=!0,Hc=r),pi(0,t)},n}function gi(e,t,n){(n=Fs(-1,n)).tag=3;var r=e.type.getDerivedStateFromError;if("function"==typeof r){var o=t.value;n.payload=function(){return r(o)},n.callback=function(){pi(0,t)}}var s=e.stateNode;return null!==s&&"function"==typeof s.componentDidCatch&&(n.callback=function(){pi(0,t),"function"!=typeof r&&(null===Gc?Gc=new Set([this]):Gc.add(this));var e=t.stack;this.componentDidCatch(t.value,{componentStack:null!==e?e:""})}),n}function mi(e,t,n){var r=e.pingCache;if(null===r){r=e.pingCache=new ui;var o=new Set;r.set(t,o)}else void 0===(o=r.get(t))&&(o=new Set,r.set(t,o));o.has(n)||(o.add(n),e=El.bind(null,e,t,n),t.then(e,e))}function hi(e){do{var t;if((t=13===e.tag)&&(t=null===(t=e.memoizedState)||null!==t.dehydrated),t)return e;e=e.return}while(null!==e);return null}function bi(e,t,n,r,o){return 1&e.mode?(e.flags|=65536,e.lanes=o,e):(e===t?e.flags|=65536:(e.flags|=128,n.flags|=131072,n.flags&=-52805,1===n.tag&&(null===n.alternate?n.tag=17:((t=Fs(-1,1)).tag=2,zs(n,t,1))),n.lanes|=1),e)}var vi=w.ReactCurrentOwner,yi=!1;function wi(e,t,n,r){t.child=null===e?ks(t,null,n,r):_s(t,e.child,n,r)}function _i(e,t,n,r,o){n=n.render;var s=t.ref;return As(t,o),r=ha(e,t,n,r,s,o),n=ba(),null===e||yi?(ss&&n&&ts(t),t.flags|=1,wi(e,t,r,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,$i(e,t,o))}function ki(e,t,n,r,o){if(null===e){var s=n.type;return"function"!=typeof s||Pl(s)||void 0!==s.defaultProps||null!==n.compare||void 0!==n.defaultProps?((e=Ll(n.type,null,r,t,t.mode,o)).ref=t.ref,e.return=t,t.child=e):(t.tag=15,t.type=s,xi(e,t,s,r,o))}if(s=e.child,!(e.lanes&o)){var a=s.memoizedProps;if((n=null!==(n=n.compare)?n:cr)(a,r)&&e.ref===t.ref)return $i(e,t,o)}return t.flags|=1,(e=Nl(s,r)).ref=t.ref,e.return=t,t.child=e}function xi(e,t,n,r,o){if(null!==e){var s=e.memoizedProps;if(cr(s,r)&&e.ref===t.ref){if(yi=!1,t.pendingProps=r=s,!(e.lanes&o))return t.lanes=e.lanes,$i(e,t,o);131072&e.flags&&(yi=!0)}}return ji(e,t,n,r,o)}function Si(e,t,n){var r=t.pendingProps,o=r.children,s=null!==e?e.memoizedState:null;if("hidden"===r.mode)if(1&t.mode){if(!(1073741824&n))return e=null!==s?s.baseLanes|n:n,t.lanes=t.childLanes=1073741824,t.memoizedState={baseLanes:e,cachePool:null,transitions:null},t.updateQueue=null,Xo(Nc,Pc),Pc|=e,null;t.memoizedState={baseLanes:0,cachePool:null,transitions:null},r=null!==s?s.baseLanes:n,Xo(Nc,Pc),Pc|=r}else t.memoizedState={baseLanes:0,cachePool:null,transitions:null},Xo(Nc,Pc),Pc|=n;else null!==s?(r=s.baseLanes|n,t.memoizedState=null):r=n,Xo(Nc,Pc),Pc|=r;return wi(e,t,o,n),t.child}function Ei(e,t){var n=t.ref;(null===e&&null!==n||null!==e&&e.ref!==n)&&(t.flags|=512,t.flags|=2097152)}function ji(e,t,n,r,o){var s=No(n)?Ro:To.current;return s=Po(t,s),As(t,o),n=ha(e,t,n,r,s,o),r=ba(),null===e||yi?(ss&&r&&ts(t),t.flags|=1,wi(e,t,n,o),t.child):(t.updateQueue=e.updateQueue,t.flags&=-2053,e.lanes&=~o,$i(e,t,o))}function Xi(e,t,n,r,o){if(No(n)){var s=!0;Io(t)}else s=!1;if(As(t,o),null===t.stateNode)Ui(e,t),ai(t,n,r),ci(t,n,r,o),r=!0;else if(null===e){var a=t.stateNode,i=t.memoizedProps;a.props=i;var c=a.context,l=n.contextType;"object"==typeof l&&null!==l?l=Rs(l):l=Po(t,l=No(n)?Ro:To.current);var d=n.getDerivedStateFromProps,p="function"==typeof d||"function"==typeof a.getSnapshotBeforeUpdate;p||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(i!==r||c!==l)&&ii(t,a,r,l),Ds=!1;var u=t.memoizedState;a.state=u,Us(t,r,a,o),c=t.memoizedState,i!==r||u!==c||Ao.current||Ds?("function"==typeof d&&(ri(t,n,d,r),c=t.memoizedState),(i=Ds||si(t,n,i,r,u,c,l))?(p||"function"!=typeof a.UNSAFE_componentWillMount&&"function"!=typeof a.componentWillMount||("function"==typeof a.componentWillMount&&a.componentWillMount(),"function"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount()),"function"==typeof a.componentDidMount&&(t.flags|=4194308)):("function"==typeof a.componentDidMount&&(t.flags|=4194308),t.memoizedProps=r,t.memoizedState=c),a.props=r,a.state=c,a.context=l,r=i):("function"==typeof a.componentDidMount&&(t.flags|=4194308),r=!1)}else{a=t.stateNode,Ms(e,t),i=t.memoizedProps,l=t.type===t.elementType?i:ni(t.type,i),a.props=l,p=t.pendingProps,u=a.context,"object"==typeof(c=n.contextType)&&null!==c?c=Rs(c):c=Po(t,c=No(n)?Ro:To.current);var f=n.getDerivedStateFromProps;(d="function"==typeof f||"function"==typeof a.getSnapshotBeforeUpdate)||"function"!=typeof a.UNSAFE_componentWillReceiveProps&&"function"!=typeof a.componentWillReceiveProps||(i!==p||u!==c)&&ii(t,a,r,c),Ds=!1,u=t.memoizedState,a.state=u,Us(t,r,a,o);var g=t.memoizedState;i!==p||u!==g||Ao.current||Ds?("function"==typeof f&&(ri(t,n,f,r),g=t.memoizedState),(l=Ds||si(t,n,l,r,u,g,c)||!1)?(d||"function"!=typeof a.UNSAFE_componentWillUpdate&&"function"!=typeof a.componentWillUpdate||("function"==typeof a.componentWillUpdate&&a.componentWillUpdate(r,g,c),"function"==typeof a.UNSAFE_componentWillUpdate&&a.UNSAFE_componentWillUpdate(r,g,c)),"function"==typeof a.componentDidUpdate&&(t.flags|=4),"function"==typeof a.getSnapshotBeforeUpdate&&(t.flags|=1024)):("function"!=typeof a.componentDidUpdate||i===e.memoizedProps&&u===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||i===e.memoizedProps&&u===e.memoizedState||(t.flags|=1024),t.memoizedProps=r,t.memoizedState=g),a.props=r,a.state=g,a.context=c,r=l):("function"!=typeof a.componentDidUpdate||i===e.memoizedProps&&u===e.memoizedState||(t.flags|=4),"function"!=typeof a.getSnapshotBeforeUpdate||i===e.memoizedProps&&u===e.memoizedState||(t.flags|=1024),r=!1)}return Ci(e,t,n,r,s,o)}function Ci(e,t,n,r,o,s){Ei(e,t);var a=!!(128&t.flags);if(!r&&!a)return o&&Mo(t,n,!1),$i(e,t,s);r=t.stateNode,vi.current=t;var i=a&&"function"!=typeof n.getDerivedStateFromError?null:r.render();return t.flags|=1,null!==e&&a?(t.child=_s(t,e.child,null,s),t.child=_s(t,null,i,s)):wi(e,t,i,s),t.memoizedState=r.state,o&&Mo(t,n,!0),t.child}function Ti(e){var t=e.stateNode;t.pendingContext?Oo(0,t.pendingContext,t.pendingContext!==t.context):t.context&&Oo(0,t.context,!1),Qs(e,t.containerInfo)}function Ai(e,t,n,r,o){return gs(),ms(o),t.flags|=256,wi(e,t,n,r),t.child}var Ri,Pi,Ni,Li,Oi={dehydrated:null,treeContext:null,retryLane:0};function Di(e){return{baseLanes:e,cachePool:null,transitions:null}}function Ii(e,t,n){var r,o=t.pendingProps,a=ea.current,i=!1,c=!!(128&t.flags);if((r=c)||(r=(null===e||null!==e.memoizedState)&&!!(2&a)),r?(i=!0,t.flags&=-129):null!==e&&null===e.memoizedState||(a|=1),Xo(ea,1&a),null===e)return ds(t),null!==(e=t.memoizedState)&&null!==(e=e.dehydrated)?(1&t.mode?"$!"===e.data?t.lanes=8:t.lanes=1073741824:t.lanes=1,null):(c=o.children,e=o.fallback,i?(o=t.mode,i=t.child,c={mode:"hidden",children:c},1&o||null===i?i=Dl(c,o,0,null):(i.childLanes=0,i.pendingProps=c),e=Ol(e,o,n,null),i.return=t,e.return=t,i.sibling=e,t.child=i,t.child.memoizedState=Di(n),t.memoizedState=Oi,e):Mi(t,c));if(null!==(a=e.memoizedState)&&null!==(r=a.dehydrated))return function(e,t,n,r,o,a,i){if(n)return 256&t.flags?(t.flags&=-257,Fi(e,t,i,r=di(Error(s(422))))):null!==t.memoizedState?(t.child=e.child,t.flags|=128,null):(a=r.fallback,o=t.mode,r=Dl({mode:"visible",children:r.children},o,0,null),(a=Ol(a,o,i,null)).flags|=2,r.return=t,a.return=t,r.sibling=a,t.child=r,1&t.mode&&_s(t,e.child,null,i),t.child.memoizedState=Di(i),t.memoizedState=Oi,a);if(!(1&t.mode))return Fi(e,t,i,null);if("$!"===o.data){if(r=o.nextSibling&&o.nextSibling.dataset)var c=r.dgst;return r=c,Fi(e,t,i,r=di(a=Error(s(419)),r,void 0))}if(c=!!(i&e.childLanes),yi||c){if(null!==(r=Tc)){switch(i&-i){case 4:o=2;break;case 16:o=8;break;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:o=32;break;case 536870912:o=268435456;break;default:o=0}0!==(o=o&(r.suspendedLanes|i)?0:o)&&o!==a.retryLane&&(a.retryLane=o,Os(e,o),nl(r,e,o,-1))}return ml(),Fi(e,t,i,r=di(Error(s(421))))}return"$?"===o.data?(t.flags|=128,t.child=e.child,t=Xl.bind(null,e),o._reactRetry=t,null):(e=a.treeContext,os=lo(o.nextSibling),rs=t,ss=!0,as=null,null!==e&&(Wo[Ko++]=Yo,Wo[Ko++]=Zo,Wo[Ko++]=Qo,Yo=e.id,Zo=e.overflow,Qo=t),t=Mi(t,r.children),t.flags|=4096,t)}(e,t,c,o,r,a,n);if(i){i=o.fallback,c=t.mode,r=(a=e.child).sibling;var l={mode:"hidden",children:o.children};return 1&c||t.child===a?(o=Nl(a,l)).subtreeFlags=14680064&a.subtreeFlags:((o=t.child).childLanes=0,o.pendingProps=l,t.deletions=null),null!==r?i=Nl(r,i):(i=Ol(i,c,n,null)).flags|=2,i.return=t,o.return=t,o.sibling=i,t.child=o,o=i,i=t.child,c=null===(c=e.child.memoizedState)?Di(n):{baseLanes:c.baseLanes|n,cachePool:null,transitions:c.transitions},i.memoizedState=c,i.childLanes=e.childLanes&~n,t.memoizedState=Oi,o}return e=(i=e.child).sibling,o=Nl(i,{mode:"visible",children:o.children}),!(1&t.mode)&&(o.lanes=n),o.return=t,o.sibling=null,null!==e&&(null===(n=t.deletions)?(t.deletions=[e],t.flags|=16):n.push(e)),t.child=o,t.memoizedState=null,o}function Mi(e,t){return(t=Dl({mode:"visible",children:t},e.mode,0,null)).return=e,e.child=t}function Fi(e,t,n,r){return null!==r&&ms(r),_s(t,e.child,null,n),(e=Mi(t,t.pendingProps.children)).flags|=2,t.memoizedState=null,e}function zi(e,t,n){e.lanes|=t;var r=e.alternate;null!==r&&(r.lanes|=t),Ts(e.return,t,n)}function Bi(e,t,n,r,o){var s=e.memoizedState;null===s?e.memoizedState={isBackwards:t,rendering:null,renderingStartTime:0,last:r,tail:n,tailMode:o}:(s.isBackwards=t,s.rendering=null,s.renderingStartTime=0,s.last=r,s.tail=n,s.tailMode=o)}function qi(e,t,n){var r=t.pendingProps,o=r.revealOrder,s=r.tail;if(wi(e,t,r.children,n),2&(r=ea.current))r=1&r|2,t.flags|=128;else{if(null!==e&&128&e.flags)e:for(e=t.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&zi(e,n,t);else if(19===e.tag)zi(e,n,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===t)break e;for(;null===e.sibling;){if(null===e.return||e.return===t)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(Xo(ea,r),1&t.mode)switch(o){case"forwards":for(n=t.child,o=null;null!==n;)null!==(e=n.alternate)&&null===ta(e)&&(o=n),n=n.sibling;null===(n=o)?(o=t.child,t.child=null):(o=n.sibling,n.sibling=null),Bi(t,!1,o,n,s);break;case"backwards":for(n=null,o=t.child,t.child=null;null!==o;){if(null!==(e=o.alternate)&&null===ta(e)){t.child=o;break}e=o.sibling,o.sibling=n,n=o,o=e}Bi(t,!0,n,null,s);break;case"together":Bi(t,!1,null,null,void 0);break;default:t.memoizedState=null}else t.memoizedState=null;return t.child}function Ui(e,t){!(1&t.mode)&&null!==e&&(e.alternate=null,t.alternate=null,t.flags|=2)}function $i(e,t,n){if(null!==e&&(t.dependencies=e.dependencies),Dc|=t.lanes,!(n&t.childLanes))return null;if(null!==e&&t.child!==e.child)throw Error(s(153));if(null!==t.child){for(n=Nl(e=t.child,e.pendingProps),t.child=n,n.return=t;null!==e.sibling;)e=e.sibling,(n=n.sibling=Nl(e,e.pendingProps)).return=t;n.sibling=null}return t.child}function Hi(e,t){if(!ss)switch(e.tailMode){case"hidden":t=e.tail;for(var n=null;null!==t;)null!==t.alternate&&(n=t),t=t.sibling;null===n?e.tail=null:n.sibling=null;break;case"collapsed":n=e.tail;for(var r=null;null!==n;)null!==n.alternate&&(r=n),n=n.sibling;null===r?t||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function Gi(e){var t=null!==e.alternate&&e.alternate.child===e.child,n=0,r=0;if(t)for(var o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=14680064&o.subtreeFlags,r|=14680064&o.flags,o.return=e,o=o.sibling;else for(o=e.child;null!==o;)n|=o.lanes|o.childLanes,r|=o.subtreeFlags,r|=o.flags,o.return=e,o=o.sibling;return e.subtreeFlags|=r,e.childLanes=n,t}function Vi(e,t,n){var r=t.pendingProps;switch(ns(t),t.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return Gi(t),null;case 1:case 17:return No(t.type)&&Lo(),Gi(t),null;case 3:return r=t.stateNode,Ys(),jo(Ao),jo(To),ra(),r.pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(us(t)?t.flags|=4:null===e||e.memoizedState.isDehydrated&&!(256&t.flags)||(t.flags|=1024,null!==as&&(al(as),as=null))),Pi(e,t),Gi(t),null;case 5:Js(t);var o=Ks(Ws.current);if(n=t.type,null!==e&&null!=t.stateNode)Ni(e,t,n,r,o),e.ref!==t.ref&&(t.flags|=512,t.flags|=2097152);else{if(!r){if(null===t.stateNode)throw Error(s(166));return Gi(t),null}if(e=Ks(Gs.current),us(t)){r=t.stateNode,n=t.type;var a=t.memoizedProps;switch(r[fo]=t,r[go]=a,e=!!(1&t.mode),n){case"dialog":Fr("cancel",r),Fr("close",r);break;case"iframe":case"object":case"embed":Fr("load",r);break;case"video":case"audio":for(o=0;o<Or.length;o++)Fr(Or[o],r);break;case"source":Fr("error",r);break;case"img":case"image":case"link":Fr("error",r),Fr("load",r);break;case"details":Fr("toggle",r);break;case"input":Q(r,a),Fr("invalid",r);break;case"select":r._wrapperState={wasMultiple:!!a.multiple},Fr("invalid",r);break;case"textarea":oe(r,a),Fr("invalid",r)}for(var c in ve(n,a),o=null,a)if(a.hasOwnProperty(c)){var l=a[c];"children"===c?"string"==typeof l?r.textContent!==l&&(!0!==a.suppressHydrationWarning&&Zr(r.textContent,l,e),o=["children",l]):"number"==typeof l&&r.textContent!==""+l&&(!0!==a.suppressHydrationWarning&&Zr(r.textContent,l,e),o=["children",""+l]):i.hasOwnProperty(c)&&null!=l&&"onScroll"===c&&Fr("scroll",r)}switch(n){case"input":G(r),J(r,a,!0);break;case"textarea":G(r),ae(r);break;case"select":case"option":break;default:"function"==typeof a.onClick&&(r.onclick=Jr)}r=o,t.updateQueue=r,null!==r&&(t.flags|=4)}else{c=9===o.nodeType?o:o.ownerDocument,"http://www.w3.org/1999/xhtml"===e&&(e=ie(n)),"http://www.w3.org/1999/xhtml"===e?"script"===n?((e=c.createElement("div")).innerHTML="<script><\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=c.createElement(n,{is:r.is}):(e=c.createElement(n),"select"===n&&(c=e,r.multiple?c.multiple=!0:r.size&&(c.size=r.size))):e=c.createElementNS(e,n),e[fo]=t,e[go]=r,Ri(e,t,!1,!1),t.stateNode=e;e:{switch(c=ye(n,r),n){case"dialog":Fr("cancel",e),Fr("close",e),o=r;break;case"iframe":case"object":case"embed":Fr("load",e),o=r;break;case"video":case"audio":for(o=0;o<Or.length;o++)Fr(Or[o],e);o=r;break;case"source":Fr("error",e),o=r;break;case"img":case"image":case"link":Fr("error",e),Fr("load",e),o=r;break;case"details":Fr("toggle",e),o=r;break;case"input":Q(e,r),o=K(e,r),Fr("invalid",e);break;case"option":default:o=r;break;case"select":e._wrapperState={wasMultiple:!!r.multiple},o=I({},r,{value:void 0}),Fr("invalid",e);break;case"textarea":oe(e,r),o=re(e,r),Fr("invalid",e)}for(a in ve(n,o),l=o)if(l.hasOwnProperty(a)){var d=l[a];"style"===a?he(e,d):"dangerouslySetInnerHTML"===a?null!=(d=d?d.__html:void 0)&&pe(e,d):"children"===a?"string"==typeof d?("textarea"!==n||""!==d)&&ue(e,d):"number"==typeof d&&ue(e,""+d):"suppressContentEditableWarning"!==a&&"suppressHydrationWarning"!==a&&"autoFocus"!==a&&(i.hasOwnProperty(a)?null!=d&&"onScroll"===a&&Fr("scroll",e):null!=d&&y(e,a,d,c))}switch(n){case"input":G(e),J(e,r,!1);break;case"textarea":G(e),ae(e);break;case"option":null!=r.value&&e.setAttribute("value",""+$(r.value));break;case"select":e.multiple=!!r.multiple,null!=(a=r.value)?ne(e,!!r.multiple,a,!1):null!=r.defaultValue&&ne(e,!!r.multiple,r.defaultValue,!0);break;default:"function"==typeof o.onClick&&(e.onclick=Jr)}switch(n){case"button":case"input":case"select":case"textarea":r=!!r.autoFocus;break e;case"img":r=!0;break e;default:r=!1}}r&&(t.flags|=4)}null!==t.ref&&(t.flags|=512,t.flags|=2097152)}return Gi(t),null;case 6:if(e&&null!=t.stateNode)Li(e,t,e.memoizedProps,r);else{if("string"!=typeof r&&null===t.stateNode)throw Error(s(166));if(n=Ks(Ws.current),Ks(Gs.current),us(t)){if(r=t.stateNode,n=t.memoizedProps,r[fo]=t,(a=r.nodeValue!==n)&&null!==(e=rs))switch(e.tag){case 3:Zr(r.nodeValue,n,!!(1&e.mode));break;case 5:!0!==e.memoizedProps.suppressHydrationWarning&&Zr(r.nodeValue,n,!!(1&e.mode))}a&&(t.flags|=4)}else(r=(9===n.nodeType?n:n.ownerDocument).createTextNode(r))[fo]=t,t.stateNode=r}return Gi(t),null;case 13:if(jo(ea),r=t.memoizedState,null===e||null!==e.memoizedState&&null!==e.memoizedState.dehydrated){if(ss&&null!==os&&1&t.mode&&!(128&t.flags))fs(),gs(),t.flags|=98560,a=!1;else if(a=us(t),null!==r&&null!==r.dehydrated){if(null===e){if(!a)throw Error(s(318));if(!(a=null!==(a=t.memoizedState)?a.dehydrated:null))throw Error(s(317));a[fo]=t}else gs(),!(128&t.flags)&&(t.memoizedState=null),t.flags|=4;Gi(t),a=!1}else null!==as&&(al(as),as=null),a=!0;if(!a)return 65536&t.flags?t:null}return 128&t.flags?(t.lanes=n,t):((r=null!==r)!==(null!==e&&null!==e.memoizedState)&&r&&(t.child.flags|=8192,1&t.mode&&(null===e||1&ea.current?0===Lc&&(Lc=3):ml())),null!==t.updateQueue&&(t.flags|=4),Gi(t),null);case 4:return Ys(),Pi(e,t),null===e&&qr(t.stateNode.containerInfo),Gi(t),null;case 10:return Cs(t.type._context),Gi(t),null;case 19:if(jo(ea),null===(a=t.memoizedState))return Gi(t),null;if(r=!!(128&t.flags),null===(c=a.rendering))if(r)Hi(a,!1);else{if(0!==Lc||null!==e&&128&e.flags)for(e=t.child;null!==e;){if(null!==(c=ta(e))){for(t.flags|=128,Hi(a,!1),null!==(r=c.updateQueue)&&(t.updateQueue=r,t.flags|=4),t.subtreeFlags=0,r=n,n=t.child;null!==n;)e=r,(a=n).flags&=14680066,null===(c=a.alternate)?(a.childLanes=0,a.lanes=e,a.child=null,a.subtreeFlags=0,a.memoizedProps=null,a.memoizedState=null,a.updateQueue=null,a.dependencies=null,a.stateNode=null):(a.childLanes=c.childLanes,a.lanes=c.lanes,a.child=c.child,a.subtreeFlags=0,a.deletions=null,a.memoizedProps=c.memoizedProps,a.memoizedState=c.memoizedState,a.updateQueue=c.updateQueue,a.type=c.type,e=c.dependencies,a.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),n=n.sibling;return Xo(ea,1&ea.current|2),t.child}e=e.sibling}null!==a.tail&&Ye()>qc&&(t.flags|=128,r=!0,Hi(a,!1),t.lanes=4194304)}else{if(!r)if(null!==(e=ta(c))){if(t.flags|=128,r=!0,null!==(n=e.updateQueue)&&(t.updateQueue=n,t.flags|=4),Hi(a,!0),null===a.tail&&"hidden"===a.tailMode&&!c.alternate&&!ss)return Gi(t),null}else 2*Ye()-a.renderingStartTime>qc&&1073741824!==n&&(t.flags|=128,r=!0,Hi(a,!1),t.lanes=4194304);a.isBackwards?(c.sibling=t.child,t.child=c):(null!==(n=a.last)?n.sibling=c:t.child=c,a.last=c)}return null!==a.tail?(t=a.tail,a.rendering=t,a.tail=t.sibling,a.renderingStartTime=Ye(),t.sibling=null,n=ea.current,Xo(ea,r?1&n|2:1&n),t):(Gi(t),null);case 22:case 23:return pl(),r=null!==t.memoizedState,null!==e&&null!==e.memoizedState!==r&&(t.flags|=8192),r&&1&t.mode?!!(1073741824&Pc)&&(Gi(t),6&t.subtreeFlags&&(t.flags|=8192)):Gi(t),null;case 24:case 25:return null}throw Error(s(156,t.tag))}function Wi(e,t){switch(ns(t),t.tag){case 1:return No(t.type)&&Lo(),65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 3:return Ys(),jo(Ao),jo(To),ra(),65536&(e=t.flags)&&!(128&e)?(t.flags=-65537&e|128,t):null;case 5:return Js(t),null;case 13:if(jo(ea),null!==(e=t.memoizedState)&&null!==e.dehydrated){if(null===t.alternate)throw Error(s(340));gs()}return 65536&(e=t.flags)?(t.flags=-65537&e|128,t):null;case 19:return jo(ea),null;case 4:return Ys(),null;case 10:return Cs(t.type._context),null;case 22:case 23:return pl(),null;default:return null}}Ri=function(e,t){for(var n=t.child;null!==n;){if(5===n.tag||6===n.tag)e.appendChild(n.stateNode);else if(4!==n.tag&&null!==n.child){n.child.return=n,n=n.child;continue}if(n===t)break;for(;null===n.sibling;){if(null===n.return||n.return===t)return;n=n.return}n.sibling.return=n.return,n=n.sibling}},Pi=function(){},Ni=function(e,t,n,r){var o=e.memoizedProps;if(o!==r){e=t.stateNode,Ks(Gs.current);var s,a=null;switch(n){case"input":o=K(e,o),r=K(e,r),a=[];break;case"select":o=I({},o,{value:void 0}),r=I({},r,{value:void 0}),a=[];break;case"textarea":o=re(e,o),r=re(e,r),a=[];break;default:"function"!=typeof o.onClick&&"function"==typeof r.onClick&&(e.onclick=Jr)}for(d in ve(n,r),n=null,o)if(!r.hasOwnProperty(d)&&o.hasOwnProperty(d)&&null!=o[d])if("style"===d){var c=o[d];for(s in c)c.hasOwnProperty(s)&&(n||(n={}),n[s]="")}else"dangerouslySetInnerHTML"!==d&&"children"!==d&&"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&"autoFocus"!==d&&(i.hasOwnProperty(d)?a||(a=[]):(a=a||[]).push(d,null));for(d in r){var l=r[d];if(c=null!=o?o[d]:void 0,r.hasOwnProperty(d)&&l!==c&&(null!=l||null!=c))if("style"===d)if(c){for(s in c)!c.hasOwnProperty(s)||l&&l.hasOwnProperty(s)||(n||(n={}),n[s]="");for(s in l)l.hasOwnProperty(s)&&c[s]!==l[s]&&(n||(n={}),n[s]=l[s])}else n||(a||(a=[]),a.push(d,n)),n=l;else"dangerouslySetInnerHTML"===d?(l=l?l.__html:void 0,c=c?c.__html:void 0,null!=l&&c!==l&&(a=a||[]).push(d,l)):"children"===d?"string"!=typeof l&&"number"!=typeof l||(a=a||[]).push(d,""+l):"suppressContentEditableWarning"!==d&&"suppressHydrationWarning"!==d&&(i.hasOwnProperty(d)?(null!=l&&"onScroll"===d&&Fr("scroll",e),a||c===l||(a=[])):(a=a||[]).push(d,l))}n&&(a=a||[]).push("style",n);var d=a;(t.updateQueue=d)&&(t.flags|=4)}},Li=function(e,t,n,r){n!==r&&(t.flags|=4)};var Ki=!1,Qi=!1,Yi="function"==typeof WeakSet?WeakSet:Set,Zi=null;function Ji(e,t){var n=e.ref;if(null!==n)if("function"==typeof n)try{n(null)}catch(r){Sl(e,t,r)}else n.current=null}function ec(e,t,n){try{n()}catch(r){Sl(e,t,r)}}var tc=!1;function nc(e,t,n){var r=t.updateQueue;if(null!==(r=null!==r?r.lastEffect:null)){var o=r=r.next;do{if((o.tag&e)===e){var s=o.destroy;o.destroy=void 0,void 0!==s&&ec(t,n,s)}o=o.next}while(o!==r)}}function rc(e,t){if(null!==(t=null!==(t=t.updateQueue)?t.lastEffect:null)){var n=t=t.next;do{if((n.tag&e)===e){var r=n.create;n.destroy=r()}n=n.next}while(n!==t)}}function oc(e){var t=e.ref;if(null!==t){var n=e.stateNode;e.tag,e=n,"function"==typeof t?t(e):t.current=e}}function sc(e){var t=e.alternate;null!==t&&(e.alternate=null,sc(t)),e.child=null,e.deletions=null,e.sibling=null,5===e.tag&&(null!==(t=e.stateNode)&&(delete t[fo],delete t[go],delete t[ho],delete t[bo],delete t[vo])),e.stateNode=null,e.return=null,e.dependencies=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.stateNode=null,e.updateQueue=null}function ac(e){return 5===e.tag||3===e.tag||4===e.tag}function ic(e){e:for(;;){for(;null===e.sibling;){if(null===e.return||ac(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;5!==e.tag&&6!==e.tag&&18!==e.tag;){if(2&e.flags)continue e;if(null===e.child||4===e.tag)continue e;e.child.return=e,e=e.child}if(!(2&e.flags))return e.stateNode}}function cc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?8===n.nodeType?n.parentNode.insertBefore(e,t):n.insertBefore(e,t):(8===n.nodeType?(t=n.parentNode).insertBefore(e,n):(t=n).appendChild(e),null!=(n=n._reactRootContainer)||null!==t.onclick||(t.onclick=Jr));else if(4!==r&&null!==(e=e.child))for(cc(e,t,n),e=e.sibling;null!==e;)cc(e,t,n),e=e.sibling}function lc(e,t,n){var r=e.tag;if(5===r||6===r)e=e.stateNode,t?n.insertBefore(e,t):n.appendChild(e);else if(4!==r&&null!==(e=e.child))for(lc(e,t,n),e=e.sibling;null!==e;)lc(e,t,n),e=e.sibling}var dc=null,pc=!1;function uc(e,t,n){for(n=n.child;null!==n;)fc(e,t,n),n=n.sibling}function fc(e,t,n){if(st&&"function"==typeof st.onCommitFiberUnmount)try{st.onCommitFiberUnmount(ot,n)}catch(i){}switch(n.tag){case 5:Qi||Ji(n,t);case 6:var r=dc,o=pc;dc=null,uc(e,t,n),pc=o,null!==(dc=r)&&(pc?(e=dc,n=n.stateNode,8===e.nodeType?e.parentNode.removeChild(n):e.removeChild(n)):dc.removeChild(n.stateNode));break;case 18:null!==dc&&(pc?(e=dc,n=n.stateNode,8===e.nodeType?co(e.parentNode,n):1===e.nodeType&&co(e,n),qt(e)):co(dc,n.stateNode));break;case 4:r=dc,o=pc,dc=n.stateNode.containerInfo,pc=!0,uc(e,t,n),dc=r,pc=o;break;case 0:case 11:case 14:case 15:if(!Qi&&(null!==(r=n.updateQueue)&&null!==(r=r.lastEffect))){o=r=r.next;do{var s=o,a=s.destroy;s=s.tag,void 0!==a&&(2&s||4&s)&&ec(n,t,a),o=o.next}while(o!==r)}uc(e,t,n);break;case 1:if(!Qi&&(Ji(n,t),"function"==typeof(r=n.stateNode).componentWillUnmount))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(i){Sl(n,t,i)}uc(e,t,n);break;case 21:uc(e,t,n);break;case 22:1&n.mode?(Qi=(r=Qi)||null!==n.memoizedState,uc(e,t,n),Qi=r):uc(e,t,n);break;default:uc(e,t,n)}}function gc(e){var t=e.updateQueue;if(null!==t){e.updateQueue=null;var n=e.stateNode;null===n&&(n=e.stateNode=new Yi),t.forEach((function(t){var r=Cl.bind(null,e,t);n.has(t)||(n.add(t),t.then(r,r))}))}}function mc(e,t){var n=t.deletions;if(null!==n)for(var r=0;r<n.length;r++){var o=n[r];try{var a=e,i=t,c=i;e:for(;null!==c;){switch(c.tag){case 5:dc=c.stateNode,pc=!1;break e;case 3:case 4:dc=c.stateNode.containerInfo,pc=!0;break e}c=c.return}if(null===dc)throw Error(s(160));fc(a,i,o),dc=null,pc=!1;var l=o.alternate;null!==l&&(l.return=null),o.return=null}catch(d){Sl(o,t,d)}}if(12854&t.subtreeFlags)for(t=t.child;null!==t;)hc(t,e),t=t.sibling}function hc(e,t){var n=e.alternate,r=e.flags;switch(e.tag){case 0:case 11:case 14:case 15:if(mc(t,e),bc(e),4&r){try{nc(3,e,e.return),rc(3,e)}catch(h){Sl(e,e.return,h)}try{nc(5,e,e.return)}catch(h){Sl(e,e.return,h)}}break;case 1:mc(t,e),bc(e),512&r&&null!==n&&Ji(n,n.return);break;case 5:if(mc(t,e),bc(e),512&r&&null!==n&&Ji(n,n.return),32&e.flags){var o=e.stateNode;try{ue(o,"")}catch(h){Sl(e,e.return,h)}}if(4&r&&null!=(o=e.stateNode)){var a=e.memoizedProps,i=null!==n?n.memoizedProps:a,c=e.type,l=e.updateQueue;if(e.updateQueue=null,null!==l)try{"input"===c&&"radio"===a.type&&null!=a.name&&Y(o,a),ye(c,i);var d=ye(c,a);for(i=0;i<l.length;i+=2){var p=l[i],u=l[i+1];"style"===p?he(o,u):"dangerouslySetInnerHTML"===p?pe(o,u):"children"===p?ue(o,u):y(o,p,u,d)}switch(c){case"input":Z(o,a);break;case"textarea":se(o,a);break;case"select":var f=o._wrapperState.wasMultiple;o._wrapperState.wasMultiple=!!a.multiple;var g=a.value;null!=g?ne(o,!!a.multiple,g,!1):f!==!!a.multiple&&(null!=a.defaultValue?ne(o,!!a.multiple,a.defaultValue,!0):ne(o,!!a.multiple,a.multiple?[]:"",!1))}o[go]=a}catch(h){Sl(e,e.return,h)}}break;case 6:if(mc(t,e),bc(e),4&r){if(null===e.stateNode)throw Error(s(162));o=e.stateNode,a=e.memoizedProps;try{o.nodeValue=a}catch(h){Sl(e,e.return,h)}}break;case 3:if(mc(t,e),bc(e),4&r&&null!==n&&n.memoizedState.isDehydrated)try{qt(t.containerInfo)}catch(h){Sl(e,e.return,h)}break;case 4:default:mc(t,e),bc(e);break;case 13:mc(t,e),bc(e),8192&(o=e.child).flags&&(a=null!==o.memoizedState,o.stateNode.isHidden=a,!a||null!==o.alternate&&null!==o.alternate.memoizedState||(Bc=Ye())),4&r&&gc(e);break;case 22:if(p=null!==n&&null!==n.memoizedState,1&e.mode?(Qi=(d=Qi)||p,mc(t,e),Qi=d):mc(t,e),bc(e),8192&r){if(d=null!==e.memoizedState,(e.stateNode.isHidden=d)&&!p&&1&e.mode)for(Zi=e,p=e.child;null!==p;){for(u=Zi=p;null!==Zi;){switch(g=(f=Zi).child,f.tag){case 0:case 11:case 14:case 15:nc(4,f,f.return);break;case 1:Ji(f,f.return);var m=f.stateNode;if("function"==typeof m.componentWillUnmount){r=f,n=f.return;try{t=r,m.props=t.memoizedProps,m.state=t.memoizedState,m.componentWillUnmount()}catch(h){Sl(r,n,h)}}break;case 5:Ji(f,f.return);break;case 22:if(null!==f.memoizedState){_c(u);continue}}null!==g?(g.return=f,Zi=g):_c(u)}p=p.sibling}e:for(p=null,u=e;;){if(5===u.tag){if(null===p){p=u;try{o=u.stateNode,d?"function"==typeof(a=o.style).setProperty?a.setProperty("display","none","important"):a.display="none":(c=u.stateNode,i=null!=(l=u.memoizedProps.style)&&l.hasOwnProperty("display")?l.display:null,c.style.display=me("display",i))}catch(h){Sl(e,e.return,h)}}}else if(6===u.tag){if(null===p)try{u.stateNode.nodeValue=d?"":u.memoizedProps}catch(h){Sl(e,e.return,h)}}else if((22!==u.tag&&23!==u.tag||null===u.memoizedState||u===e)&&null!==u.child){u.child.return=u,u=u.child;continue}if(u===e)break e;for(;null===u.sibling;){if(null===u.return||u.return===e)break e;p===u&&(p=null),u=u.return}p===u&&(p=null),u.sibling.return=u.return,u=u.sibling}}break;case 19:mc(t,e),bc(e),4&r&&gc(e);case 21:}}function bc(e){var t=e.flags;if(2&t){try{e:{for(var n=e.return;null!==n;){if(ac(n)){var r=n;break e}n=n.return}throw Error(s(160))}switch(r.tag){case 5:var o=r.stateNode;32&r.flags&&(ue(o,""),r.flags&=-33),lc(e,ic(e),o);break;case 3:case 4:var a=r.stateNode.containerInfo;cc(e,ic(e),a);break;default:throw Error(s(161))}}catch(i){Sl(e,e.return,i)}e.flags&=-3}4096&t&&(e.flags&=-4097)}function vc(e,t,n){Zi=e,yc(e,t,n)}function yc(e,t,n){for(var r=!!(1&e.mode);null!==Zi;){var o=Zi,s=o.child;if(22===o.tag&&r){var a=null!==o.memoizedState||Ki;if(!a){var i=o.alternate,c=null!==i&&null!==i.memoizedState||Qi;i=Ki;var l=Qi;if(Ki=a,(Qi=c)&&!l)for(Zi=o;null!==Zi;)c=(a=Zi).child,22===a.tag&&null!==a.memoizedState?kc(o):null!==c?(c.return=a,Zi=c):kc(o);for(;null!==s;)Zi=s,yc(s,t,n),s=s.sibling;Zi=o,Ki=i,Qi=l}wc(e)}else 8772&o.subtreeFlags&&null!==s?(s.return=o,Zi=s):wc(e)}}function wc(e){for(;null!==Zi;){var t=Zi;if(8772&t.flags){var n=t.alternate;try{if(8772&t.flags)switch(t.tag){case 0:case 11:case 15:Qi||rc(5,t);break;case 1:var r=t.stateNode;if(4&t.flags&&!Qi)if(null===n)r.componentDidMount();else{var o=t.elementType===t.type?n.memoizedProps:ni(t.type,n.memoizedProps);r.componentDidUpdate(o,n.memoizedState,r.__reactInternalSnapshotBeforeUpdate)}var a=t.updateQueue;null!==a&&$s(t,a,r);break;case 3:var i=t.updateQueue;if(null!==i){if(n=null,null!==t.child)switch(t.child.tag){case 5:case 1:n=t.child.stateNode}$s(t,i,n)}break;case 5:var c=t.stateNode;if(null===n&&4&t.flags){n=c;var l=t.memoizedProps;switch(t.type){case"button":case"input":case"select":case"textarea":l.autoFocus&&n.focus();break;case"img":l.src&&(n.src=l.src)}}break;case 6:case 4:case 12:case 19:case 17:case 21:case 22:case 23:case 25:break;case 13:if(null===t.memoizedState){var d=t.alternate;if(null!==d){var p=d.memoizedState;if(null!==p){var u=p.dehydrated;null!==u&&qt(u)}}}break;default:throw Error(s(163))}Qi||512&t.flags&&oc(t)}catch(f){Sl(t,t.return,f)}}if(t===e){Zi=null;break}if(null!==(n=t.sibling)){n.return=t.return,Zi=n;break}Zi=t.return}}function _c(e){for(;null!==Zi;){var t=Zi;if(t===e){Zi=null;break}var n=t.sibling;if(null!==n){n.return=t.return,Zi=n;break}Zi=t.return}}function kc(e){for(;null!==Zi;){var t=Zi;try{switch(t.tag){case 0:case 11:case 15:var n=t.return;try{rc(4,t)}catch(c){Sl(t,n,c)}break;case 1:var r=t.stateNode;if("function"==typeof r.componentDidMount){var o=t.return;try{r.componentDidMount()}catch(c){Sl(t,o,c)}}var s=t.return;try{oc(t)}catch(c){Sl(t,s,c)}break;case 5:var a=t.return;try{oc(t)}catch(c){Sl(t,a,c)}}}catch(c){Sl(t,t.return,c)}if(t===e){Zi=null;break}var i=t.sibling;if(null!==i){i.return=t.return,Zi=i;break}Zi=t.return}}var xc,Sc=Math.ceil,Ec=w.ReactCurrentDispatcher,jc=w.ReactCurrentOwner,Xc=w.ReactCurrentBatchConfig,Cc=0,Tc=null,Ac=null,Rc=0,Pc=0,Nc=Eo(0),Lc=0,Oc=null,Dc=0,Ic=0,Mc=0,Fc=null,zc=null,Bc=0,qc=1/0,Uc=null,$c=!1,Hc=null,Gc=null,Vc=!1,Wc=null,Kc=0,Qc=0,Yc=null,Zc=-1,Jc=0;function el(){return 6&Cc?Ye():-1!==Zc?Zc:Zc=Ye()}function tl(e){return 1&e.mode?2&Cc&&0!==Rc?Rc&-Rc:null!==hs.transition?(0===Jc&&(Jc=mt()),Jc):0!==(e=yt)?e:e=void 0===(e=window.event)?16:Qt(e.type):1}function nl(e,t,n,r){if(50<Qc)throw Qc=0,Yc=null,Error(s(185));bt(e,n,r),2&Cc&&e===Tc||(e===Tc&&(!(2&Cc)&&(Ic|=n),4===Lc&&il(e,Rc)),rl(e,r),1===n&&0===Cc&&!(1&t.mode)&&(qc=Ye()+500,zo&&Uo()))}function rl(e,t){var n=e.callbackNode;!function(e,t){for(var n=e.suspendedLanes,r=e.pingedLanes,o=e.expirationTimes,s=e.pendingLanes;0<s;){var a=31-at(s),i=1<<a,c=o[a];-1===c?i&n&&!(i&r)||(o[a]=ft(i,t)):c<=t&&(e.expiredLanes|=i),s&=~i}}(e,t);var r=ut(e,e===Tc?Rc:0);if(0===r)null!==n&&We(n),e.callbackNode=null,e.callbackPriority=0;else if(t=r&-r,e.callbackPriority!==t){if(null!=n&&We(n),1===t)0===e.tag?function(e){zo=!0,qo(e)}(cl.bind(null,e)):qo(cl.bind(null,e)),ao((function(){!(6&Cc)&&Uo()})),n=null;else{switch(wt(r)){case 1:n=Je;break;case 4:n=et;break;case 16:default:n=tt;break;case 536870912:n=rt}n=Tl(n,ol.bind(null,e))}e.callbackPriority=t,e.callbackNode=n}}function ol(e,t){if(Zc=-1,Jc=0,6&Cc)throw Error(s(327));var n=e.callbackNode;if(kl()&&e.callbackNode!==n)return null;var r=ut(e,e===Tc?Rc:0);if(0===r)return null;if(30&r||r&e.expiredLanes||t)t=hl(e,r);else{t=r;var o=Cc;Cc|=2;var a=gl();for(Tc===e&&Rc===t||(Uc=null,qc=Ye()+500,ul(e,t));;)try{vl();break}catch(c){fl(e,c)}Xs(),Ec.current=a,Cc=o,null!==Ac?t=0:(Tc=null,Rc=0,t=Lc)}if(0!==t){if(2===t&&(0!==(o=gt(e))&&(r=o,t=sl(e,o))),1===t)throw n=Oc,ul(e,0),il(e,r),rl(e,Ye()),n;if(6===t)il(e,r);else{if(o=e.current.alternate,!(30&r||function(e){for(var t=e;;){if(16384&t.flags){var n=t.updateQueue;if(null!==n&&null!==(n=n.stores))for(var r=0;r<n.length;r++){var o=n[r],s=o.getSnapshot;o=o.value;try{if(!ir(s(),o))return!1}catch(i){return!1}}}if(n=t.child,16384&t.subtreeFlags&&null!==n)n.return=t,t=n;else{if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return!0;t=t.return}t.sibling.return=t.return,t=t.sibling}}return!0}(o)||(t=hl(e,r),2===t&&(a=gt(e),0!==a&&(r=a,t=sl(e,a))),1!==t)))throw n=Oc,ul(e,0),il(e,r),rl(e,Ye()),n;switch(e.finishedWork=o,e.finishedLanes=r,t){case 0:case 1:throw Error(s(345));case 2:case 5:_l(e,zc,Uc);break;case 3:if(il(e,r),(130023424&r)===r&&10<(t=Bc+500-Ye())){if(0!==ut(e,0))break;if(((o=e.suspendedLanes)&r)!==r){el(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=ro(_l.bind(null,e,zc,Uc),t);break}_l(e,zc,Uc);break;case 4:if(il(e,r),(4194240&r)===r)break;for(t=e.eventTimes,o=-1;0<r;){var i=31-at(r);a=1<<i,(i=t[i])>o&&(o=i),r&=~a}if(r=o,10<(r=(120>(r=Ye()-r)?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Sc(r/1960))-r)){e.timeoutHandle=ro(_l.bind(null,e,zc,Uc),r);break}_l(e,zc,Uc);break;default:throw Error(s(329))}}}return rl(e,Ye()),e.callbackNode===n?ol.bind(null,e):null}function sl(e,t){var n=Fc;return e.current.memoizedState.isDehydrated&&(ul(e,t).flags|=256),2!==(e=hl(e,t))&&(t=zc,zc=n,null!==t&&al(t)),e}function al(e){null===zc?zc=e:zc.push.apply(zc,e)}function il(e,t){for(t&=~Mc,t&=~Ic,e.suspendedLanes|=t,e.pingedLanes&=~t,e=e.expirationTimes;0<t;){var n=31-at(t),r=1<<n;e[n]=-1,t&=~r}}function cl(e){if(6&Cc)throw Error(s(327));kl();var t=ut(e,0);if(!(1&t))return rl(e,Ye()),null;var n=hl(e,t);if(0!==e.tag&&2===n){var r=gt(e);0!==r&&(t=r,n=sl(e,r))}if(1===n)throw n=Oc,ul(e,0),il(e,t),rl(e,Ye()),n;if(6===n)throw Error(s(345));return e.finishedWork=e.current.alternate,e.finishedLanes=t,_l(e,zc,Uc),rl(e,Ye()),null}function ll(e,t){var n=Cc;Cc|=1;try{return e(t)}finally{0===(Cc=n)&&(qc=Ye()+500,zo&&Uo())}}function dl(e){null!==Wc&&0===Wc.tag&&!(6&Cc)&&kl();var t=Cc;Cc|=1;var n=Xc.transition,r=yt;try{if(Xc.transition=null,yt=1,e)return e()}finally{yt=r,Xc.transition=n,!(6&(Cc=t))&&Uo()}}function pl(){Pc=Nc.current,jo(Nc)}function ul(e,t){e.finishedWork=null,e.finishedLanes=0;var n=e.timeoutHandle;if(-1!==n&&(e.timeoutHandle=-1,oo(n)),null!==Ac)for(n=Ac.return;null!==n;){var r=n;switch(ns(r),r.tag){case 1:null!=(r=r.type.childContextTypes)&&Lo();break;case 3:Ys(),jo(Ao),jo(To),ra();break;case 5:Js(r);break;case 4:Ys();break;case 13:case 19:jo(ea);break;case 10:Cs(r.type._context);break;case 22:case 23:pl()}n=n.return}if(Tc=e,Ac=e=Nl(e.current,null),Rc=Pc=t,Lc=0,Oc=null,Mc=Ic=Dc=0,zc=Fc=null,null!==Ps){for(t=0;t<Ps.length;t++)if(null!==(r=(n=Ps[t]).interleaved)){n.interleaved=null;var o=r.next,s=n.pending;if(null!==s){var a=s.next;s.next=o,r.next=a}n.pending=r}Ps=null}return e}function fl(e,t){for(;;){var n=Ac;try{if(Xs(),oa.current=Za,da){for(var r=ia.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}da=!1}if(aa=0,la=ca=ia=null,pa=!1,ua=0,jc.current=null,null===n||null===n.return){Lc=1,Oc=t,Ac=null;break}e:{var a=e,i=n.return,c=n,l=t;if(t=Rc,c.flags|=32768,null!==l&&"object"==typeof l&&"function"==typeof l.then){var d=l,p=c,u=p.tag;if(!(1&p.mode||0!==u&&11!==u&&15!==u)){var f=p.alternate;f?(p.updateQueue=f.updateQueue,p.memoizedState=f.memoizedState,p.lanes=f.lanes):(p.updateQueue=null,p.memoizedState=null)}var g=hi(i);if(null!==g){g.flags&=-257,bi(g,i,c,0,t),1&g.mode&&mi(a,d,t),l=d;var m=(t=g).updateQueue;if(null===m){var h=new Set;h.add(l),t.updateQueue=h}else m.add(l);break e}if(!(1&t)){mi(a,d,t),ml();break e}l=Error(s(426))}else if(ss&&1&c.mode){var b=hi(i);if(null!==b){!(65536&b.flags)&&(b.flags|=256),bi(b,i,c,0,t),ms(li(l,c));break e}}a=l=li(l,c),4!==Lc&&(Lc=2),null===Fc?Fc=[a]:Fc.push(a),a=i;do{switch(a.tag){case 3:a.flags|=65536,t&=-t,a.lanes|=t,qs(a,fi(0,l,t));break e;case 1:c=l;var v=a.type,y=a.stateNode;if(!(128&a.flags||"function"!=typeof v.getDerivedStateFromError&&(null===y||"function"!=typeof y.componentDidCatch||null!==Gc&&Gc.has(y)))){a.flags|=65536,t&=-t,a.lanes|=t,qs(a,gi(a,c,t));break e}}a=a.return}while(null!==a)}wl(n)}catch(w){t=w,Ac===n&&null!==n&&(Ac=n=n.return);continue}break}}function gl(){var e=Ec.current;return Ec.current=Za,null===e?Za:e}function ml(){0!==Lc&&3!==Lc&&2!==Lc||(Lc=4),null===Tc||!(268435455&Dc)&&!(268435455&Ic)||il(Tc,Rc)}function hl(e,t){var n=Cc;Cc|=2;var r=gl();for(Tc===e&&Rc===t||(Uc=null,ul(e,t));;)try{bl();break}catch(o){fl(e,o)}if(Xs(),Cc=n,Ec.current=r,null!==Ac)throw Error(s(261));return Tc=null,Rc=0,Lc}function bl(){for(;null!==Ac;)yl(Ac)}function vl(){for(;null!==Ac&&!Ke();)yl(Ac)}function yl(e){var t=xc(e.alternate,e,Pc);e.memoizedProps=e.pendingProps,null===t?wl(e):Ac=t,jc.current=null}function wl(e){var t=e;do{var n=t.alternate;if(e=t.return,32768&t.flags){if(null!==(n=Wi(n,t)))return n.flags&=32767,void(Ac=n);if(null===e)return Lc=6,void(Ac=null);e.flags|=32768,e.subtreeFlags=0,e.deletions=null}else if(null!==(n=Vi(n,t,Pc)))return void(Ac=n);if(null!==(t=t.sibling))return void(Ac=t);Ac=t=e}while(null!==t);0===Lc&&(Lc=5)}function _l(e,t,n){var r=yt,o=Xc.transition;try{Xc.transition=null,yt=1,function(e,t,n,r){do{kl()}while(null!==Wc);if(6&Cc)throw Error(s(327));n=e.finishedWork;var o=e.finishedLanes;if(null===n)return null;if(e.finishedWork=null,e.finishedLanes=0,n===e.current)throw Error(s(177));e.callbackNode=null,e.callbackPriority=0;var a=n.lanes|n.childLanes;if(function(e,t){var n=e.pendingLanes&~t;e.pendingLanes=t,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=t,e.mutableReadLanes&=t,e.entangledLanes&=t,t=e.entanglements;var r=e.eventTimes;for(e=e.expirationTimes;0<n;){var o=31-at(n),s=1<<o;t[o]=0,r[o]=-1,e[o]=-1,n&=~s}}(e,a),e===Tc&&(Ac=Tc=null,Rc=0),!(2064&n.subtreeFlags)&&!(2064&n.flags)||Vc||(Vc=!0,Tl(tt,(function(){return kl(),null}))),a=!!(15990&n.flags),!!(15990&n.subtreeFlags)||a){a=Xc.transition,Xc.transition=null;var i=yt;yt=1;var c=Cc;Cc|=4,jc.current=null,function(e,t){if(eo=$t,fr(e=ur())){if("selectionStart"in e)var n={start:e.selectionStart,end:e.selectionEnd};else e:{var r=(n=(n=e.ownerDocument)&&n.defaultView||window).getSelection&&n.getSelection();if(r&&0!==r.rangeCount){n=r.anchorNode;var o=r.anchorOffset,a=r.focusNode;r=r.focusOffset;try{n.nodeType,a.nodeType}catch(_){n=null;break e}var i=0,c=-1,l=-1,d=0,p=0,u=e,f=null;t:for(;;){for(var g;u!==n||0!==o&&3!==u.nodeType||(c=i+o),u!==a||0!==r&&3!==u.nodeType||(l=i+r),3===u.nodeType&&(i+=u.nodeValue.length),null!==(g=u.firstChild);)f=u,u=g;for(;;){if(u===e)break t;if(f===n&&++d===o&&(c=i),f===a&&++p===r&&(l=i),null!==(g=u.nextSibling))break;f=(u=f).parentNode}u=g}n=-1===c||-1===l?null:{start:c,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(to={focusedElem:e,selectionRange:n},$t=!1,Zi=t;null!==Zi;)if(e=(t=Zi).child,1028&t.subtreeFlags&&null!==e)e.return=t,Zi=e;else for(;null!==Zi;){t=Zi;try{var m=t.alternate;if(1024&t.flags)switch(t.tag){case 0:case 11:case 15:case 5:case 6:case 4:case 17:break;case 1:if(null!==m){var h=m.memoizedProps,b=m.memoizedState,v=t.stateNode,y=v.getSnapshotBeforeUpdate(t.elementType===t.type?h:ni(t.type,h),b);v.__reactInternalSnapshotBeforeUpdate=y}break;case 3:var w=t.stateNode.containerInfo;1===w.nodeType?w.textContent="":9===w.nodeType&&w.documentElement&&w.removeChild(w.documentElement);break;default:throw Error(s(163))}}catch(_){Sl(t,t.return,_)}if(null!==(e=t.sibling)){e.return=t.return,Zi=e;break}Zi=t.return}m=tc,tc=!1}(e,n),hc(n,e),gr(to),$t=!!eo,to=eo=null,e.current=n,vc(n,e,o),Qe(),Cc=c,yt=i,Xc.transition=a}else e.current=n;if(Vc&&(Vc=!1,Wc=e,Kc=o),a=e.pendingLanes,0===a&&(Gc=null),function(e){if(st&&"function"==typeof st.onCommitFiberRoot)try{st.onCommitFiberRoot(ot,e,void 0,!(128&~e.current.flags))}catch(t){}}(n.stateNode),rl(e,Ye()),null!==t)for(r=e.onRecoverableError,n=0;n<t.length;n++)o=t[n],r(o.value,{componentStack:o.stack,digest:o.digest});if($c)throw $c=!1,e=Hc,Hc=null,e;!!(1&Kc)&&0!==e.tag&&kl(),a=e.pendingLanes,1&a?e===Yc?Qc++:(Qc=0,Yc=e):Qc=0,Uo()}(e,t,n,r)}finally{Xc.transition=o,yt=r}return null}function kl(){if(null!==Wc){var e=wt(Kc),t=Xc.transition,n=yt;try{if(Xc.transition=null,yt=16>e?16:e,null===Wc)var r=!1;else{if(e=Wc,Wc=null,Kc=0,6&Cc)throw Error(s(331));var o=Cc;for(Cc|=4,Zi=e.current;null!==Zi;){var a=Zi,i=a.child;if(16&Zi.flags){var c=a.deletions;if(null!==c){for(var l=0;l<c.length;l++){var d=c[l];for(Zi=d;null!==Zi;){var p=Zi;switch(p.tag){case 0:case 11:case 15:nc(8,p,a)}var u=p.child;if(null!==u)u.return=p,Zi=u;else for(;null!==Zi;){var f=(p=Zi).sibling,g=p.return;if(sc(p),p===d){Zi=null;break}if(null!==f){f.return=g,Zi=f;break}Zi=g}}}var m=a.alternate;if(null!==m){var h=m.child;if(null!==h){m.child=null;do{var b=h.sibling;h.sibling=null,h=b}while(null!==h)}}Zi=a}}if(2064&a.subtreeFlags&&null!==i)i.return=a,Zi=i;else e:for(;null!==Zi;){if(2048&(a=Zi).flags)switch(a.tag){case 0:case 11:case 15:nc(9,a,a.return)}var v=a.sibling;if(null!==v){v.return=a.return,Zi=v;break e}Zi=a.return}}var y=e.current;for(Zi=y;null!==Zi;){var w=(i=Zi).child;if(2064&i.subtreeFlags&&null!==w)w.return=i,Zi=w;else e:for(i=y;null!==Zi;){if(2048&(c=Zi).flags)try{switch(c.tag){case 0:case 11:case 15:rc(9,c)}}catch(k){Sl(c,c.return,k)}if(c===i){Zi=null;break e}var _=c.sibling;if(null!==_){_.return=c.return,Zi=_;break e}Zi=c.return}}if(Cc=o,Uo(),st&&"function"==typeof st.onPostCommitFiberRoot)try{st.onPostCommitFiberRoot(ot,e)}catch(k){}r=!0}return r}finally{yt=n,Xc.transition=t}}return!1}function xl(e,t,n){e=zs(e,t=fi(0,t=li(n,t),1),1),t=el(),null!==e&&(bt(e,1,t),rl(e,t))}function Sl(e,t,n){if(3===e.tag)xl(e,e,n);else for(;null!==t;){if(3===t.tag){xl(t,e,n);break}if(1===t.tag){var r=t.stateNode;if("function"==typeof t.type.getDerivedStateFromError||"function"==typeof r.componentDidCatch&&(null===Gc||!Gc.has(r))){t=zs(t,e=gi(t,e=li(n,e),1),1),e=el(),null!==t&&(bt(t,1,e),rl(t,e));break}}t=t.return}}function El(e,t,n){var r=e.pingCache;null!==r&&r.delete(t),t=el(),e.pingedLanes|=e.suspendedLanes&n,Tc===e&&(Rc&n)===n&&(4===Lc||3===Lc&&(130023424&Rc)===Rc&&500>Ye()-Bc?ul(e,0):Mc|=n),rl(e,t)}function jl(e,t){0===t&&(1&e.mode?(t=dt,!(130023424&(dt<<=1))&&(dt=4194304)):t=1);var n=el();null!==(e=Os(e,t))&&(bt(e,t,n),rl(e,n))}function Xl(e){var t=e.memoizedState,n=0;null!==t&&(n=t.retryLane),jl(e,n)}function Cl(e,t){var n=0;switch(e.tag){case 13:var r=e.stateNode,o=e.memoizedState;null!==o&&(n=o.retryLane);break;case 19:r=e.stateNode;break;default:throw Error(s(314))}null!==r&&r.delete(t),jl(e,n)}function Tl(e,t){return Ve(e,t)}function Al(e,t,n,r){this.tag=e,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=t,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Rl(e,t,n,r){return new Al(e,t,n,r)}function Pl(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Nl(e,t){var n=e.alternate;return null===n?((n=Rl(e.tag,t,e.key,e.mode)).elementType=e.elementType,n.type=e.type,n.stateNode=e.stateNode,n.alternate=e,e.alternate=n):(n.pendingProps=t,n.type=e.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=14680064&e.flags,n.childLanes=e.childLanes,n.lanes=e.lanes,n.child=e.child,n.memoizedProps=e.memoizedProps,n.memoizedState=e.memoizedState,n.updateQueue=e.updateQueue,t=e.dependencies,n.dependencies=null===t?null:{lanes:t.lanes,firstContext:t.firstContext},n.sibling=e.sibling,n.index=e.index,n.ref=e.ref,n}function Ll(e,t,n,r,o,a){var i=2;if(r=e,"function"==typeof e)Pl(e)&&(i=1);else if("string"==typeof e)i=5;else e:switch(e){case x:return Ol(n.children,o,a,t);case S:i=8,o|=8;break;case E:return(e=Rl(12,n,t,2|o)).elementType=E,e.lanes=a,e;case T:return(e=Rl(13,n,t,o)).elementType=T,e.lanes=a,e;case A:return(e=Rl(19,n,t,o)).elementType=A,e.lanes=a,e;case N:return Dl(n,o,a,t);default:if("object"==typeof e&&null!==e)switch(e.$$typeof){case j:i=10;break e;case X:i=9;break e;case C:i=11;break e;case R:i=14;break e;case P:i=16,r=null;break e}throw Error(s(130,null==e?e:typeof e,""))}return(t=Rl(i,n,t,o)).elementType=e,t.type=r,t.lanes=a,t}function Ol(e,t,n,r){return(e=Rl(7,e,r,t)).lanes=n,e}function Dl(e,t,n,r){return(e=Rl(22,e,r,t)).elementType=N,e.lanes=n,e.stateNode={isHidden:!1},e}function Il(e,t,n){return(e=Rl(6,e,null,t)).lanes=n,e}function Ml(e,t,n){return(t=Rl(4,null!==e.children?e.children:[],e.key,t)).lanes=n,t.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},t}function Fl(e,t,n,r,o){this.tag=t,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=ht(0),this.expirationTimes=ht(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=ht(0),this.identifierPrefix=r,this.onRecoverableError=o,this.mutableSourceEagerHydrationData=null}function zl(e,t,n,r,o,s,a,i,c){return e=new Fl(e,t,n,i,c),1===t?(t=1,!0===s&&(t|=8)):t=0,s=Rl(3,null,null,t),e.current=s,s.stateNode=e,s.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Is(s),e}function Bl(e){if(!e)return Co;e:{if(qe(e=e._reactInternals)!==e||1!==e.tag)throw Error(s(170));var t=e;do{switch(t.tag){case 3:t=t.stateNode.context;break e;case 1:if(No(t.type)){t=t.stateNode.__reactInternalMemoizedMergedChildContext;break e}}t=t.return}while(null!==t);throw Error(s(171))}if(1===e.tag){var n=e.type;if(No(n))return Do(e,n,t)}return t}function ql(e,t,n,r,o,s,a,i,c){return(e=zl(n,r,!0,e,0,s,0,i,c)).context=Bl(null),n=e.current,(s=Fs(r=el(),o=tl(n))).callback=null!=t?t:null,zs(n,s,o),e.current.lanes=o,bt(e,o,r),rl(e,r),e}function Ul(e,t,n,r){var o=t.current,s=el(),a=tl(o);return n=Bl(n),null===t.context?t.context=n:t.pendingContext=n,(t=Fs(s,a)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),null!==(e=zs(o,t,a))&&(nl(e,o,a,s),Bs(e,o,a)),a}function $l(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Hl(e,t){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var n=e.retryLane;e.retryLane=0!==n&&n<t?n:t}}function Gl(e,t){Hl(e,t),(e=e.alternate)&&Hl(e,t)}xc=function(e,t,n){if(null!==e)if(e.memoizedProps!==t.pendingProps||Ao.current)yi=!0;else{if(!(e.lanes&n||128&t.flags))return yi=!1,function(e,t,n){switch(t.tag){case 3:Ti(t),gs();break;case 5:Zs(t);break;case 1:No(t.type)&&Io(t);break;case 4:Qs(t,t.stateNode.containerInfo);break;case 10:var r=t.type._context,o=t.memoizedProps.value;Xo(xs,r._currentValue),r._currentValue=o;break;case 13:if(null!==(r=t.memoizedState))return null!==r.dehydrated?(Xo(ea,1&ea.current),t.flags|=128,null):n&t.child.childLanes?Ii(e,t,n):(Xo(ea,1&ea.current),null!==(e=$i(e,t,n))?e.sibling:null);Xo(ea,1&ea.current);break;case 19:if(r=!!(n&t.childLanes),128&e.flags){if(r)return qi(e,t,n);t.flags|=128}if(null!==(o=t.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),Xo(ea,ea.current),r)break;return null;case 22:case 23:return t.lanes=0,Si(e,t,n)}return $i(e,t,n)}(e,t,n);yi=!!(131072&e.flags)}else yi=!1,ss&&1048576&t.flags&&es(t,Vo,t.index);switch(t.lanes=0,t.tag){case 2:var r=t.type;Ui(e,t),e=t.pendingProps;var o=Po(t,To.current);As(t,n),o=ha(null,t,r,e,o,n);var a=ba();return t.flags|=1,"object"==typeof o&&null!==o&&"function"==typeof o.render&&void 0===o.$$typeof?(t.tag=1,t.memoizedState=null,t.updateQueue=null,No(r)?(a=!0,Io(t)):a=!1,t.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,Is(t),o.updater=oi,t.stateNode=o,o._reactInternals=t,ci(t,r,e,n),t=Ci(null,t,r,!0,a,n)):(t.tag=0,ss&&a&&ts(t),wi(null,t,o,n),t=t.child),t;case 16:r=t.elementType;e:{switch(Ui(e,t),e=t.pendingProps,r=(o=r._init)(r._payload),t.type=r,o=t.tag=function(e){if("function"==typeof e)return Pl(e)?1:0;if(null!=e){if((e=e.$$typeof)===C)return 11;if(e===R)return 14}return 2}(r),e=ni(r,e),o){case 0:t=ji(null,t,r,e,n);break e;case 1:t=Xi(null,t,r,e,n);break e;case 11:t=_i(null,t,r,e,n);break e;case 14:t=ki(null,t,r,ni(r.type,e),n);break e}throw Error(s(306,r,""))}return t;case 0:return r=t.type,o=t.pendingProps,ji(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 1:return r=t.type,o=t.pendingProps,Xi(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 3:e:{if(Ti(t),null===e)throw Error(s(387));r=t.pendingProps,o=(a=t.memoizedState).element,Ms(e,t),Us(t,r,null,n);var i=t.memoizedState;if(r=i.element,a.isDehydrated){if(a={element:r,isDehydrated:!1,cache:i.cache,pendingSuspenseBoundaries:i.pendingSuspenseBoundaries,transitions:i.transitions},t.updateQueue.baseState=a,t.memoizedState=a,256&t.flags){t=Ai(e,t,r,n,o=li(Error(s(423)),t));break e}if(r!==o){t=Ai(e,t,r,n,o=li(Error(s(424)),t));break e}for(os=lo(t.stateNode.containerInfo.firstChild),rs=t,ss=!0,as=null,n=ks(t,null,r,n),t.child=n;n;)n.flags=-3&n.flags|4096,n=n.sibling}else{if(gs(),r===o){t=$i(e,t,n);break e}wi(e,t,r,n)}t=t.child}return t;case 5:return Zs(t),null===e&&ds(t),r=t.type,o=t.pendingProps,a=null!==e?e.memoizedProps:null,i=o.children,no(r,o)?i=null:null!==a&&no(r,a)&&(t.flags|=32),Ei(e,t),wi(e,t,i,n),t.child;case 6:return null===e&&ds(t),null;case 13:return Ii(e,t,n);case 4:return Qs(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=_s(t,null,r,n):wi(e,t,r,n),t.child;case 11:return r=t.type,o=t.pendingProps,_i(e,t,r,o=t.elementType===r?o:ni(r,o),n);case 7:return wi(e,t,t.pendingProps,n),t.child;case 8:case 12:return wi(e,t,t.pendingProps.children,n),t.child;case 10:e:{if(r=t.type._context,o=t.pendingProps,a=t.memoizedProps,i=o.value,Xo(xs,r._currentValue),r._currentValue=i,null!==a)if(ir(a.value,i)){if(a.children===o.children&&!Ao.current){t=$i(e,t,n);break e}}else for(null!==(a=t.child)&&(a.return=t);null!==a;){var c=a.dependencies;if(null!==c){i=a.child;for(var l=c.firstContext;null!==l;){if(l.context===r){if(1===a.tag){(l=Fs(-1,n&-n)).tag=2;var d=a.updateQueue;if(null!==d){var p=(d=d.shared).pending;null===p?l.next=l:(l.next=p.next,p.next=l),d.pending=l}}a.lanes|=n,null!==(l=a.alternate)&&(l.lanes|=n),Ts(a.return,n,t),c.lanes|=n;break}l=l.next}}else if(10===a.tag)i=a.type===t.type?null:a.child;else if(18===a.tag){if(null===(i=a.return))throw Error(s(341));i.lanes|=n,null!==(c=i.alternate)&&(c.lanes|=n),Ts(i,n,t),i=a.sibling}else i=a.child;if(null!==i)i.return=a;else for(i=a;null!==i;){if(i===t){i=null;break}if(null!==(a=i.sibling)){a.return=i.return,i=a;break}i=i.return}a=i}wi(e,t,o.children,n),t=t.child}return t;case 9:return o=t.type,r=t.pendingProps.children,As(t,n),r=r(o=Rs(o)),t.flags|=1,wi(e,t,r,n),t.child;case 14:return o=ni(r=t.type,t.pendingProps),ki(e,t,r,o=ni(r.type,o),n);case 15:return xi(e,t,t.type,t.pendingProps,n);case 17:return r=t.type,o=t.pendingProps,o=t.elementType===r?o:ni(r,o),Ui(e,t),t.tag=1,No(r)?(e=!0,Io(t)):e=!1,As(t,n),ai(t,r,o),ci(t,r,o,n),Ci(null,t,r,!0,e,n);case 19:return qi(e,t,n);case 22:return Si(e,t,n)}throw Error(s(156,t.tag))};var Vl="function"==typeof reportError?reportError:function(e){console.error(e)};function Wl(e){this._internalRoot=e}function Kl(e){this._internalRoot=e}function Ql(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType)}function Yl(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||" react-mount-point-unstable "!==e.nodeValue))}function Zl(){}function Jl(e,t,n,r,o){var s=n._reactRootContainer;if(s){var a=s;if("function"==typeof o){var i=o;o=function(){var e=$l(a);i.call(e)}}Ul(t,a,e,o)}else a=function(e,t,n,r,o){if(o){if("function"==typeof r){var s=r;r=function(){var e=$l(a);s.call(e)}}var a=ql(t,r,e,0,null,!1,0,"",Zl);return e._reactRootContainer=a,e[mo]=a.current,qr(8===e.nodeType?e.parentNode:e),dl(),a}for(;o=e.lastChild;)e.removeChild(o);if("function"==typeof r){var i=r;r=function(){var e=$l(c);i.call(e)}}var c=zl(e,0,!1,null,0,!1,0,"",Zl);return e._reactRootContainer=c,e[mo]=c.current,qr(8===e.nodeType?e.parentNode:e),dl((function(){Ul(t,c,n,r)})),c}(n,t,e,o,r);return $l(a)}Kl.prototype.render=Wl.prototype.render=function(e){var t=this._internalRoot;if(null===t)throw Error(s(409));Ul(e,t,null,null)},Kl.prototype.unmount=Wl.prototype.unmount=function(){var e=this._internalRoot;if(null!==e){this._internalRoot=null;var t=e.containerInfo;dl((function(){Ul(null,e,null,null)})),t[mo]=null}},Kl.prototype.unstable_scheduleHydration=function(e){if(e){var t=St();e={blockedOn:null,target:e,priority:t};for(var n=0;n<Nt.length&&0!==t&&t<Nt[n].priority;n++);Nt.splice(n,0,e),0===n&&It(e)}},_t=function(e){switch(e.tag){case 3:var t=e.stateNode;if(t.current.memoizedState.isDehydrated){var n=pt(t.pendingLanes);0!==n&&(vt(t,1|n),rl(t,Ye()),!(6&Cc)&&(qc=Ye()+500,Uo()))}break;case 13:dl((function(){var t=Os(e,1);if(null!==t){var n=el();nl(t,e,1,n)}})),Gl(e,1)}},kt=function(e){if(13===e.tag){var t=Os(e,134217728);if(null!==t)nl(t,e,134217728,el());Gl(e,134217728)}},xt=function(e){if(13===e.tag){var t=tl(e),n=Os(e,t);if(null!==n)nl(n,e,t,el());Gl(e,t)}},St=function(){return yt},Et=function(e,t){var n=yt;try{return yt=e,t()}finally{yt=n}},ke=function(e,t,n){switch(t){case"input":if(Z(e,n),t=n.name,"radio"===n.type&&null!=t){for(n=e;n.parentNode;)n=n.parentNode;for(n=n.querySelectorAll("input[name="+JSON.stringify(""+t)+'][type="radio"]'),t=0;t<n.length;t++){var r=n[t];if(r!==e&&r.form===e.form){var o=ko(r);if(!o)throw Error(s(90));V(r),Z(r,o)}}}break;case"textarea":se(e,n);break;case"select":null!=(t=n.value)&&ne(e,!!n.multiple,t,!1)}},Ce=ll,Te=dl;var ed={usingClientEntryPoint:!1,Events:[wo,_o,ko,je,Xe,ll]},td={findFiberByHostInstance:yo,bundleType:0,version:"18.3.1",rendererPackageName:"react-dom"},nd={bundleType:td.bundleType,version:td.version,rendererPackageName:td.rendererPackageName,rendererConfig:td.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setErrorHandler:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:w.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=He(e))?null:e.stateNode},findFiberByHostInstance:td.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null,reconcilerVersion:"18.3.1-next-f1338f8080-20240426"};if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var rd=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!rd.isDisabled&&rd.supportsFiber)try{ot=rd.inject(nd),st=rd}catch(de){}}t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=ed,t.createPortal=function(e,t){var n=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!Ql(t))throw Error(s(200));return function(e,t,n){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:k,key:null==r?null:""+r,children:e,containerInfo:t,implementation:n}}(e,t,null,n)},t.createRoot=function(e,t){if(!Ql(e))throw Error(s(299));var n=!1,r="",o=Vl;return null!=t&&(!0===t.unstable_strictMode&&(n=!0),void 0!==t.identifierPrefix&&(r=t.identifierPrefix),void 0!==t.onRecoverableError&&(o=t.onRecoverableError)),t=zl(e,1,!1,null,0,n,0,r,o),e[mo]=t.current,qr(8===e.nodeType?e.parentNode:e),new Wl(t)},t.findDOMNode=function(e){if(null==e)return null;if(1===e.nodeType)return e;var t=e._reactInternals;if(void 0===t){if("function"==typeof e.render)throw Error(s(188));throw e=Object.keys(e).join(","),Error(s(268,e))}return e=null===(e=He(t))?null:e.stateNode},t.flushSync=function(e){return dl(e)},t.hydrate=function(e,t,n){if(!Yl(t))throw Error(s(200));return Jl(null,e,t,!0,n)},t.hydrateRoot=function(e,t,n){if(!Ql(e))throw Error(s(405));var r=null!=n&&n.hydratedSources||null,o=!1,a="",i=Vl;if(null!=n&&(!0===n.unstable_strictMode&&(o=!0),void 0!==n.identifierPrefix&&(a=n.identifierPrefix),void 0!==n.onRecoverableError&&(i=n.onRecoverableError)),t=ql(t,null,e,1,null!=n?n:null,o,0,a,i),e[mo]=t.current,qr(e),r)for(e=0;e<r.length;e++)o=(o=(n=r[e])._getVersion)(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o);return new Kl(t)},t.render=function(e,t,n){if(!Yl(t))throw Error(s(200));return Jl(null,e,t,!1,n)},t.unmountComponentAtNode=function(e){if(!Yl(e))throw Error(s(40));return!!e._reactRootContainer&&(dl((function(){Jl(null,null,e,!1,(function(){e._reactRootContainer=null,e[mo]=null}))})),!0)},t.unstable_batchedUpdates=ll,t.unstable_renderSubtreeIntoContainer=function(e,t,n,r){if(!Yl(n))throw Error(s(200));if(null==e||void 0===e._reactInternals)throw Error(s(38));return Jl(e,t,n,!1,r)},t.version="18.3.1-next-f1338f8080-20240426"},5338:(e,t,n)=>{"use strict";var r=n(40961);t.createRoot=r.createRoot,t.hydrateRoot=r.hydrateRoot},40961:(e,t,n)=>{"use strict";!function e(){if("undefined"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&"function"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(t){console.error(t)}}(),e.exports=n(22551)},30115:e=>{var t="undefined"!=typeof Element,n="function"==typeof Map,r="function"==typeof Set,o="function"==typeof ArrayBuffer&&!!ArrayBuffer.isView;function s(e,a){if(e===a)return!0;if(e&&a&&"object"==typeof e&&"object"==typeof a){if(e.constructor!==a.constructor)return!1;var i,c,l,d;if(Array.isArray(e)){if((i=e.length)!=a.length)return!1;for(c=i;0!=c--;)if(!s(e[c],a[c]))return!1;return!0}if(n&&e instanceof Map&&a instanceof Map){if(e.size!==a.size)return!1;for(d=e.entries();!(c=d.next()).done;)if(!a.has(c.value[0]))return!1;for(d=e.entries();!(c=d.next()).done;)if(!s(c.value[1],a.get(c.value[0])))return!1;return!0}if(r&&e instanceof Set&&a instanceof Set){if(e.size!==a.size)return!1;for(d=e.entries();!(c=d.next()).done;)if(!a.has(c.value[0]))return!1;return!0}if(o&&ArrayBuffer.isView(e)&&ArrayBuffer.isView(a)){if((i=e.length)!=a.length)return!1;for(c=i;0!=c--;)if(e[c]!==a[c])return!1;return!0}if(e.constructor===RegExp)return e.source===a.source&&e.flags===a.flags;if(e.valueOf!==Object.prototype.valueOf&&"function"==typeof e.valueOf&&"function"==typeof a.valueOf)return e.valueOf()===a.valueOf();if(e.toString!==Object.prototype.toString&&"function"==typeof e.toString&&"function"==typeof a.toString)return e.toString()===a.toString();if((i=(l=Object.keys(e)).length)!==Object.keys(a).length)return!1;for(c=i;0!=c--;)if(!Object.prototype.hasOwnProperty.call(a,l[c]))return!1;if(t&&e instanceof Element)return!1;for(c=i;0!=c--;)if(("_owner"!==l[c]&&"__v"!==l[c]&&"__o"!==l[c]||!e.$$typeof)&&!s(e[l[c]],a[l[c]]))return!1;return!0}return e!=e&&a!=a}e.exports=function(e,t){try{return s(e,t)}catch(n){if((n.message||"").match(/stack|recursion/i))return console.warn("react-fast-compare cannot handle circular refs"),!1;throw n}}},80545:(e,t,n)=>{"use strict";n.d(t,{mg:()=>J,vd:()=>H});var r=n(96540),o=n(5556),s=n.n(o),a=n(30115),i=n.n(a),c=n(20311),l=n.n(c),d=n(2833),p=n.n(d);function u(){return u=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},u.apply(this,arguments)}function f(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,g(e,t)}function g(e,t){return g=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},g(e,t)}function m(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)t.indexOf(n=s[r])>=0||(o[n]=e[n]);return o}var h={BASE:"base",BODY:"body",HEAD:"head",HTML:"html",LINK:"link",META:"meta",NOSCRIPT:"noscript",SCRIPT:"script",STYLE:"style",TITLE:"title",FRAGMENT:"Symbol(react.fragment)"},b={rel:["amphtml","canonical","alternate"]},v={type:["application/ld+json"]},y={charset:"",name:["robots","description"],property:["og:type","og:title","og:url","og:image","og:image:alt","og:description","twitter:url","twitter:title","twitter:description","twitter:image","twitter:image:alt","twitter:card","twitter:site"]},w=Object.keys(h).map((function(e){return h[e]})),_={accesskey:"accessKey",charset:"charSet",class:"className",contenteditable:"contentEditable",contextmenu:"contextMenu","http-equiv":"httpEquiv",itemprop:"itemProp",tabindex:"tabIndex"},k=Object.keys(_).reduce((function(e,t){return e[_[t]]=t,e}),{}),x=function(e,t){for(var n=e.length-1;n>=0;n-=1){var r=e[n];if(Object.prototype.hasOwnProperty.call(r,t))return r[t]}return null},S=function(e){var t=x(e,h.TITLE),n=x(e,"titleTemplate");if(Array.isArray(t)&&(t=t.join("")),n&&t)return n.replace(/%s/g,(function(){return t}));var r=x(e,"defaultTitle");return t||r||void 0},E=function(e){return x(e,"onChangeClientState")||function(){}},j=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return u({},e,t)}),{})},X=function(e,t){return t.filter((function(e){return void 0!==e[h.BASE]})).map((function(e){return e[h.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),o=0;o<r.length;o+=1){var s=r[o].toLowerCase();if(-1!==e.indexOf(s)&&n[s])return t.concat(n)}return t}),[])},C=function(e,t,n){var r={};return n.filter((function(t){return!!Array.isArray(t[e])||(void 0!==t[e]&&console&&"function"==typeof console.warn&&console.warn("Helmet: "+e+' should be of type "Array". Instead found type "'+typeof t[e]+'"'),!1)})).map((function(t){return t[e]})).reverse().reduce((function(e,n){var o={};n.filter((function(e){for(var n,s=Object.keys(e),a=0;a<s.length;a+=1){var i=s[a],c=i.toLowerCase();-1===t.indexOf(c)||"rel"===n&&"canonical"===e[n].toLowerCase()||"rel"===c&&"stylesheet"===e[c].toLowerCase()||(n=c),-1===t.indexOf(i)||"innerHTML"!==i&&"cssText"!==i&&"itemprop"!==i||(n=i)}if(!n||!e[n])return!1;var l=e[n].toLowerCase();return r[n]||(r[n]={}),o[n]||(o[n]={}),!r[n][l]&&(o[n][l]=!0,!0)})).reverse().forEach((function(t){return e.push(t)}));for(var s=Object.keys(o),a=0;a<s.length;a+=1){var i=s[a],c=u({},r[i],o[i]);r[i]=c}return e}),[]).reverse()},T=function(e,t){if(Array.isArray(e)&&e.length)for(var n=0;n<e.length;n+=1)if(e[n][t])return!0;return!1},A=function(e){return Array.isArray(e)?e.join(""):e},R=function(e,t){return Array.isArray(e)?e.reduce((function(e,n){return function(e,t){for(var n=Object.keys(e),r=0;r<n.length;r+=1)if(t[n[r]]&&t[n[r]].includes(e[n[r]]))return!0;return!1}(n,t)?e.priority.push(n):e.default.push(n),e}),{priority:[],default:[]}):{default:e}},P=function(e,t){var n;return u({},e,((n={})[t]=void 0,n))},N=[h.NOSCRIPT,h.SCRIPT,h.STYLE],L=function(e,t){return void 0===t&&(t=!0),!1===t?String(e):String(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")},O=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},D=function(e,t){return void 0===t&&(t={}),Object.keys(e).reduce((function(t,n){return t[_[n]||n]=e[n],t}),t)},I=function(e,t){return t.map((function(t,n){var o,s=((o={key:n})["data-rh"]=!0,o);return Object.keys(t).forEach((function(e){var n=_[e]||e;"innerHTML"===n||"cssText"===n?s.dangerouslySetInnerHTML={__html:t.innerHTML||t.cssText}:s[n]=t[e]})),r.createElement(e,s)}))},M=function(e,t,n){switch(e){case h.TITLE:return{toComponent:function(){return n=t.titleAttributes,(o={key:e=t.title})["data-rh"]=!0,s=D(n,o),[r.createElement(h.TITLE,s,e)];var e,n,o,s},toString:function(){return function(e,t,n,r){var o=O(n),s=A(t);return o?"<"+e+' data-rh="true" '+o+">"+L(s,r)+"</"+e+">":"<"+e+' data-rh="true">'+L(s,r)+"</"+e+">"}(e,t.title,t.titleAttributes,n)}};case"bodyAttributes":case"htmlAttributes":return{toComponent:function(){return D(t)},toString:function(){return O(t)}};default:return{toComponent:function(){return I(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var o=Object.keys(r).filter((function(e){return!("innerHTML"===e||"cssText"===e)})).reduce((function(e,t){var o=void 0===r[t]?t:t+'="'+L(r[t],n)+'"';return e?e+" "+o:o}),""),s=r.innerHTML||r.cssText||"",a=-1===N.indexOf(e);return t+"<"+e+' data-rh="true" '+o+(a?"/>":">"+s+"</"+e+">")}),"")}(e,t,n)}}}},F=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,o=e.htmlAttributes,s=e.noscriptTags,a=e.styleTags,i=e.title,c=void 0===i?"":i,l=e.titleAttributes,d=e.linkTags,p=e.metaTags,u=e.scriptTags,f={toComponent:function(){},toString:function(){return""}};if(e.prioritizeSeoTags){var g=function(e){var t=e.linkTags,n=e.scriptTags,r=e.encode,o=R(e.metaTags,y),s=R(t,b),a=R(n,v);return{priorityMethods:{toComponent:function(){return[].concat(I(h.META,o.priority),I(h.LINK,s.priority),I(h.SCRIPT,a.priority))},toString:function(){return M(h.META,o.priority,r)+" "+M(h.LINK,s.priority,r)+" "+M(h.SCRIPT,a.priority,r)}},metaTags:o.default,linkTags:s.default,scriptTags:a.default}}(e);f=g.priorityMethods,d=g.linkTags,p=g.metaTags,u=g.scriptTags}return{priority:f,base:M(h.BASE,t,r),bodyAttributes:M("bodyAttributes",n,r),htmlAttributes:M("htmlAttributes",o,r),link:M(h.LINK,d,r),meta:M(h.META,p,r),noscript:M(h.NOSCRIPT,s,r),script:M(h.SCRIPT,u,r),style:M(h.STYLE,a,r),title:M(h.TITLE,{title:c,titleAttributes:l},r)}},z=[],B=function(e,t){var n=this;void 0===t&&(t="undefined"!=typeof document),this.instances=[],this.value={setHelmet:function(e){n.context.helmet=e},helmetInstances:{get:function(){return n.canUseDOM?z:n.instances},add:function(e){(n.canUseDOM?z:n.instances).push(e)},remove:function(e){var t=(n.canUseDOM?z:n.instances).indexOf(e);(n.canUseDOM?z:n.instances).splice(t,1)}}},this.context=e,this.canUseDOM=t,t||(e.helmet=F({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}}))},q=r.createContext({}),U=s().shape({setHelmet:s().func,helmetInstances:s().shape({get:s().func,add:s().func,remove:s().func})}),$="undefined"!=typeof document,H=function(e){function t(n){var r;return(r=e.call(this,n)||this).helmetData=new B(r.props.context,t.canUseDOM),r}return f(t,e),t.prototype.render=function(){return r.createElement(q.Provider,{value:this.helmetData.value},this.props.children)},t}(r.Component);H.canUseDOM=$,H.propTypes={context:s().shape({helmet:s().shape()}),children:s().node.isRequired},H.defaultProps={context:{}},H.displayName="HelmetProvider";var G=function(e,t){var n,r=document.head||document.querySelector(h.HEAD),o=r.querySelectorAll(e+"[data-rh]"),s=[].slice.call(o),a=[];return t&&t.length&&t.forEach((function(t){var r=document.createElement(e);for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&("innerHTML"===o?r.innerHTML=t.innerHTML:"cssText"===o?r.styleSheet?r.styleSheet.cssText=t.cssText:r.appendChild(document.createTextNode(t.cssText)):r.setAttribute(o,void 0===t[o]?"":t[o]));r.setAttribute("data-rh","true"),s.some((function(e,t){return n=t,r.isEqualNode(e)}))?s.splice(n,1):a.push(r)})),s.forEach((function(e){return e.parentNode.removeChild(e)})),a.forEach((function(e){return r.appendChild(e)})),{oldTags:s,newTags:a}},V=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute("data-rh"),o=r?r.split(","):[],s=[].concat(o),a=Object.keys(t),i=0;i<a.length;i+=1){var c=a[i],l=t[c]||"";n.getAttribute(c)!==l&&n.setAttribute(c,l),-1===o.indexOf(c)&&o.push(c);var d=s.indexOf(c);-1!==d&&s.splice(d,1)}for(var p=s.length-1;p>=0;p-=1)n.removeAttribute(s[p]);o.length===s.length?n.removeAttribute("data-rh"):n.getAttribute("data-rh")!==a.join(",")&&n.setAttribute("data-rh",a.join(","))}},W=function(e,t){var n=e.baseTag,r=e.htmlAttributes,o=e.linkTags,s=e.metaTags,a=e.noscriptTags,i=e.onChangeClientState,c=e.scriptTags,l=e.styleTags,d=e.title,p=e.titleAttributes;V(h.BODY,e.bodyAttributes),V(h.HTML,r),function(e,t){void 0!==e&&document.title!==e&&(document.title=A(e)),V(h.TITLE,t)}(d,p);var u={baseTag:G(h.BASE,n),linkTags:G(h.LINK,o),metaTags:G(h.META,s),noscriptTags:G(h.NOSCRIPT,a),scriptTags:G(h.SCRIPT,c),styleTags:G(h.STYLE,l)},f={},g={};Object.keys(u).forEach((function(e){var t=u[e],n=t.newTags,r=t.oldTags;n.length&&(f[e]=n),r.length&&(g[e]=u[e].oldTags)})),t&&t(),i(e,f,g)},K=null,Q=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).rendered=!1,t}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!p()(e,this.props)},n.componentDidUpdate=function(){this.emitChange()},n.componentWillUnmount=function(){this.props.context.helmetInstances.remove(this),this.emitChange()},n.emitChange=function(){var e,t,n=this.props.context,r=n.setHelmet,o=null,s=(e=n.helmetInstances.get().map((function(e){var t=u({},e.props);return delete t.context,t})),{baseTag:X(["href"],e),bodyAttributes:j("bodyAttributes",e),defer:x(e,"defer"),encode:x(e,"encodeSpecialCharacters"),htmlAttributes:j("htmlAttributes",e),linkTags:C(h.LINK,["rel","href"],e),metaTags:C(h.META,["name","charset","http-equiv","property","itemprop"],e),noscriptTags:C(h.NOSCRIPT,["innerHTML"],e),onChangeClientState:E(e),scriptTags:C(h.SCRIPT,["src","innerHTML"],e),styleTags:C(h.STYLE,["cssText"],e),title:S(e),titleAttributes:j("titleAttributes",e),prioritizeSeoTags:T(e,"prioritizeSeoTags")});H.canUseDOM?(t=s,K&&cancelAnimationFrame(K),t.defer?K=requestAnimationFrame((function(){W(t,(function(){K=null}))})):(W(t),K=null)):F&&(o=F(s)),r(o)},n.init=function(){this.rendered||(this.rendered=!0,this.props.context.helmetInstances.add(this),this.emitChange())},n.render=function(){return this.init(),null},t}(r.Component);Q.propTypes={context:U.isRequired},Q.displayName="HelmetDispatcher";var Y=["children"],Z=["children"],J=function(e){function t(){return e.apply(this,arguments)||this}f(t,e);var n=t.prototype;return n.shouldComponentUpdate=function(e){return!i()(P(this.props,"helmetData"),P(e,"helmetData"))},n.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case h.SCRIPT:case h.NOSCRIPT:return{innerHTML:t};case h.STYLE:return{cssText:t};default:throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")}},n.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren;return u({},r,((t={})[n.type]=[].concat(r[n.type]||[],[u({},e.newChildProps,this.mapNestedChildrenToProps(n,e.nestedChildren))]),t))},n.mapObjectTypeChildren=function(e){var t,n,r=e.child,o=e.newProps,s=e.newChildProps,a=e.nestedChildren;switch(r.type){case h.TITLE:return u({},o,((t={})[r.type]=a,t.titleAttributes=u({},s),t));case h.BODY:return u({},o,{bodyAttributes:u({},s)});case h.HTML:return u({},o,{htmlAttributes:u({},s)});default:return u({},o,((n={})[r.type]=u({},s),n))}},n.mapArrayTypeChildrenToProps=function(e,t){var n=u({},t);return Object.keys(e).forEach((function(t){var r;n=u({},n,((r={})[t]=e[t],r))})),n},n.warnOnInvalidChildren=function(e,t){return l()(w.some((function(t){return e.type===t})),"function"==typeof e.type?"You may be attempting to nest <Helmet> components within each other, which is not allowed. Refer to our API for more information.":"Only elements types "+w.join(", ")+" are allowed. Helmet does not support rendering <"+e.type+"> elements. Refer to our API for more information."),l()(!t||"string"==typeof t||Array.isArray(t)&&!t.some((function(e){return"string"!=typeof e})),"Helmet expects a string as a child of <"+e.type+">. Did you forget to wrap your children in braces? ( <"+e.type+">{``}</"+e.type+"> ) Refer to our API for more information."),!0},n.mapChildrenToProps=function(e,t){var n=this,o={};return r.Children.forEach(e,(function(e){if(e&&e.props){var r=e.props,s=r.children,a=m(r,Y),i=Object.keys(a).reduce((function(e,t){return e[k[t]||t]=a[t],e}),{}),c=e.type;switch("symbol"==typeof c?c=c.toString():n.warnOnInvalidChildren(e,s),c){case h.FRAGMENT:t=n.mapChildrenToProps(s,t);break;case h.LINK:case h.META:case h.NOSCRIPT:case h.SCRIPT:case h.STYLE:o=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:o,newChildProps:i,nestedChildren:s});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:i,nestedChildren:s})}}})),this.mapArrayTypeChildrenToProps(o,t)},n.render=function(){var e=this.props,t=e.children,n=m(e,Z),o=u({},n),s=n.helmetData;return t&&(o=this.mapChildrenToProps(t,o)),!s||s instanceof B||(s=new B(s.context,s.instances)),s?r.createElement(Q,u({},o,{context:s.value,helmetData:void 0})):r.createElement(q.Consumer,null,(function(e){return r.createElement(Q,u({},o,{context:e}))}))},t}(r.Component);J.propTypes={base:s().object,bodyAttributes:s().object,children:s().oneOfType([s().arrayOf(s().node),s().node]),defaultTitle:s().string,defer:s().bool,encodeSpecialCharacters:s().bool,htmlAttributes:s().object,link:s().arrayOf(s().object),meta:s().arrayOf(s().object),noscript:s().arrayOf(s().object),onChangeClientState:s().func,script:s().arrayOf(s().object),style:s().arrayOf(s().object),title:s().string,titleAttributes:s().object,titleTemplate:s().string,prioritizeSeoTags:s().bool,helmetData:s().object},J.defaultProps={defer:!0,encodeSpecialCharacters:!0,prioritizeSeoTags:!1},J.displayName="Helmet"},22799:(e,t)=>{"use strict";var n="function"==typeof Symbol&&Symbol.for,r=n?Symbol.for("react.element"):60103,o=n?Symbol.for("react.portal"):60106,s=n?Symbol.for("react.fragment"):60107,a=n?Symbol.for("react.strict_mode"):60108,i=n?Symbol.for("react.profiler"):60114,c=n?Symbol.for("react.provider"):60109,l=n?Symbol.for("react.context"):60110,d=n?Symbol.for("react.async_mode"):60111,p=n?Symbol.for("react.concurrent_mode"):60111,u=n?Symbol.for("react.forward_ref"):60112,f=n?Symbol.for("react.suspense"):60113,g=n?Symbol.for("react.suspense_list"):60120,m=n?Symbol.for("react.memo"):60115,h=n?Symbol.for("react.lazy"):60116,b=n?Symbol.for("react.block"):60121,v=n?Symbol.for("react.fundamental"):60117,y=n?Symbol.for("react.responder"):60118,w=n?Symbol.for("react.scope"):60119;function _(e){if("object"==typeof e&&null!==e){var t=e.$$typeof;switch(t){case r:switch(e=e.type){case d:case p:case s:case i:case a:case f:return e;default:switch(e=e&&e.$$typeof){case l:case u:case h:case m:case c:return e;default:return t}}case o:return t}}}function k(e){return _(e)===p}t.AsyncMode=d,t.ConcurrentMode=p,t.ContextConsumer=l,t.ContextProvider=c,t.Element=r,t.ForwardRef=u,t.Fragment=s,t.Lazy=h,t.Memo=m,t.Portal=o,t.Profiler=i,t.StrictMode=a,t.Suspense=f,t.isAsyncMode=function(e){return k(e)||_(e)===d},t.isConcurrentMode=k,t.isContextConsumer=function(e){return _(e)===l},t.isContextProvider=function(e){return _(e)===c},t.isElement=function(e){return"object"==typeof e&&null!==e&&e.$$typeof===r},t.isForwardRef=function(e){return _(e)===u},t.isFragment=function(e){return _(e)===s},t.isLazy=function(e){return _(e)===h},t.isMemo=function(e){return _(e)===m},t.isPortal=function(e){return _(e)===o},t.isProfiler=function(e){return _(e)===i},t.isStrictMode=function(e){return _(e)===a},t.isSuspense=function(e){return _(e)===f},t.isValidElementType=function(e){return"string"==typeof e||"function"==typeof e||e===s||e===p||e===i||e===a||e===f||e===g||"object"==typeof e&&null!==e&&(e.$$typeof===h||e.$$typeof===m||e.$$typeof===c||e.$$typeof===l||e.$$typeof===u||e.$$typeof===v||e.$$typeof===y||e.$$typeof===w||e.$$typeof===b)},t.typeOf=_},44363:(e,t,n)=>{"use strict";e.exports=n(22799)},53259:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function o(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(){return a=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},a.apply(this,arguments)}var i=n(96540),c=[],l=[];var d=i.createContext(null);function p(e){var t=e(),n={loading:!0,loaded:null,error:null};return n.promise=t.then((function(e){return n.loading=!1,n.loaded=e,e})).catch((function(e){throw n.loading=!1,n.error=e,e})),n}function u(e){var t={loading:!1,loaded:{},error:null},n=[];try{Object.keys(e).forEach((function(r){var o=p(e[r]);o.loading?t.loading=!0:(t.loaded[r]=o.loaded,t.error=o.error),n.push(o.promise),o.promise.then((function(e){t.loaded[r]=e})).catch((function(e){t.error=e}))}))}catch(r){t.error=r}return t.promise=Promise.all(n).then((function(e){return t.loading=!1,e})).catch((function(e){throw t.loading=!1,e})),t}function f(e,t){return i.createElement((n=e)&&n.__esModule?n.default:n,t);var n}function g(e,t){var p,u;if(!t.loading)throw new Error("react-loadable requires a `loading` component");var g=a({loader:null,loading:null,delay:200,timeout:null,render:f,webpack:null,modules:null},t),m=null;function h(){return m||(m=e(g.loader)),m.promise}return c.push(h),"function"==typeof g.webpack&&l.push((function(){if((0,g.webpack)().every((function(e){return void 0!==e&&void 0!==n.m[e]})))return h()})),u=p=function(t){function n(n){var r;return s(o(o(r=t.call(this,n)||this)),"retry",(function(){r.setState({error:null,loading:!0,timedOut:!1}),m=e(g.loader),r._loadModule()})),h(),r.state={error:m.error,pastDelay:!1,timedOut:!1,loading:m.loading,loaded:m.loaded},r}r(n,t),n.preload=function(){return h()};var a=n.prototype;return a.UNSAFE_componentWillMount=function(){this._loadModule()},a.componentDidMount=function(){this._mounted=!0},a._loadModule=function(){var e=this;if(this.context&&Array.isArray(g.modules)&&g.modules.forEach((function(t){e.context.report(t)})),m.loading){var t=function(t){e._mounted&&e.setState(t)};"number"==typeof g.delay&&(0===g.delay?this.setState({pastDelay:!0}):this._delay=setTimeout((function(){t({pastDelay:!0})}),g.delay)),"number"==typeof g.timeout&&(this._timeout=setTimeout((function(){t({timedOut:!0})}),g.timeout));var n=function(){t({error:m.error,loaded:m.loaded,loading:m.loading}),e._clearTimeouts()};m.promise.then((function(){return n(),null})).catch((function(e){return n(),null}))}},a.componentWillUnmount=function(){this._mounted=!1,this._clearTimeouts()},a._clearTimeouts=function(){clearTimeout(this._delay),clearTimeout(this._timeout)},a.render=function(){return this.state.loading||this.state.error?i.createElement(g.loading,{isLoading:this.state.loading,pastDelay:this.state.pastDelay,timedOut:this.state.timedOut,error:this.state.error,retry:this.retry}):this.state.loaded?g.render(this.state.loaded,this.props):null},n}(i.Component),s(p,"contextType",d),u}function m(e){return g(p,e)}m.Map=function(e){if("function"!=typeof e.render)throw new Error("LoadableMap requires a `render(loaded, props)` function");return g(u,e)};var h=function(e){function t(){return e.apply(this,arguments)||this}return r(t,e),t.prototype.render=function(){return i.createElement(d.Provider,{value:{report:this.props.report}},i.Children.only(this.props.children))},t}(i.Component);function b(e){for(var t=[];e.length;){var n=e.pop();t.push(n())}return Promise.all(t).then((function(){if(e.length)return b(e)}))}m.Capture=h,m.preloadAll=function(){return new Promise((function(e,t){b(c).then(e,t)}))},m.preloadReady=function(){return new Promise((function(e,t){b(l).then(e,e)}))},e.exports=m},22831:(e,t,n)=>{"use strict";n.d(t,{u:()=>a,v:()=>i});var r=n(56347),o=n(58168),s=n(96540);function a(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var o=e.path?(0,r.B6)(t,e):n.length?n[n.length-1].match:r.Ix.computeRootMatch(t);return o&&(n.push({route:e,match:o}),e.routes&&a(e.routes,t,n)),o})),n}function i(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?s.createElement(r.dO,n,e.map((function(e,n){return s.createElement(r.qh,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,o.A)({},n,{},t,{route:e})):s.createElement(e.component,(0,o.A)({},n,t,{route:e}))}})}))):null}},54625:(e,t,n)=>{"use strict";n.d(t,{I9:()=>p,Kd:()=>d,N_:()=>b,k2:()=>w});var r=n(56347),o=n(42892),s=n(96540),a=n(31513),i=n(58168),c=n(98587),l=n(11561),d=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.zR)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return s.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(s.Component);var p=function(e){function t(){for(var t,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(t=e.call.apply(e,[this].concat(r))||this).history=(0,a.TM)(t.props),t}return(0,o.A)(t,e),t.prototype.render=function(){return s.createElement(r.Ix,{history:this.history,children:this.props.children})},t}(s.Component);var u=function(e,t){return"function"==typeof e?e(t):e},f=function(e,t){return"string"==typeof e?(0,a.yJ)(e,null,null,t):e},g=function(e){return e},m=s.forwardRef;void 0===m&&(m=g);var h=m((function(e,t){var n=e.innerRef,r=e.navigate,o=e.onClick,a=(0,c.A)(e,["innerRef","navigate","onClick"]),l=a.target,d=(0,i.A)({},a,{onClick:function(e){try{o&&o(e)}catch(t){throw e.preventDefault(),t}e.defaultPrevented||0!==e.button||l&&"_self"!==l||function(e){return!!(e.metaKey||e.altKey||e.ctrlKey||e.shiftKey)}(e)||(e.preventDefault(),r())}});return d.ref=g!==m&&t||n,s.createElement("a",d)}));var b=m((function(e,t){var n=e.component,o=void 0===n?h:n,d=e.replace,p=e.to,b=e.innerRef,v=(0,c.A)(e,["component","replace","to","innerRef"]);return s.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=e.history,r=f(u(p,e.location),e.location),c=r?n.createHref(r):"",h=(0,i.A)({},v,{href:c,navigate:function(){var t=u(p,e.location),r=(0,a.AO)(e.location)===(0,a.AO)(f(t));(d||r?n.replace:n.push)(t)}});return g!==m?h.ref=t||b:h.innerRef=b,s.createElement(o,h)}))})),v=function(e){return e},y=s.forwardRef;void 0===y&&(y=v);var w=y((function(e,t){var n=e["aria-current"],o=void 0===n?"page":n,a=e.activeClassName,d=void 0===a?"active":a,p=e.activeStyle,g=e.className,m=e.exact,h=e.isActive,w=e.location,_=e.sensitive,k=e.strict,x=e.style,S=e.to,E=e.innerRef,j=(0,c.A)(e,["aria-current","activeClassName","activeStyle","className","exact","isActive","location","sensitive","strict","style","to","innerRef"]);return s.createElement(r.XZ.Consumer,null,(function(e){e||(0,l.A)(!1);var n=w||e.location,a=f(u(S,n),n),c=a.pathname,X=c&&c.replace(/([.+*?=^!:${}()[\]|/\\])/g,"\\$1"),C=X?(0,r.B6)(n.pathname,{path:X,exact:m,sensitive:_,strict:k}):null,T=!!(h?h(C,n):C),A="function"==typeof g?g(T):g,R="function"==typeof x?x(T):x;T&&(A=function(){for(var e=arguments.length,t=new Array(e),n=0;n<e;n++)t[n]=arguments[n];return t.filter((function(e){return e})).join(" ")}(A,d),R=(0,i.A)({},R,p));var P=(0,i.A)({"aria-current":T&&o||null,className:A,style:R,to:a},j);return v!==y?P.ref=t||E:P.innerRef=E,s.createElement(b,P)}))}))},56347:(e,t,n)=>{"use strict";n.d(t,{B6:()=>x,Ix:()=>y,W6:()=>P,XZ:()=>v,dO:()=>A,qh:()=>S,zy:()=>N});var r=n(42892),o=n(96540),s=n(5556),a=n.n(s),i=n(31513),c=n(11561),l=n(58168),d=n(8505),p=n.n(d),u=(n(44363),n(98587)),f=(n(4146),1073741823),g="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:void 0!==n.g?n.g:{};var m=o.createContext||function(e,t){var n,s,i="__create-react-context-"+function(){var e="__global_unique_id__";return g[e]=(g[e]||0)+1}()+"__",c=function(e){function n(){for(var t,n,r,o=arguments.length,s=new Array(o),a=0;a<o;a++)s[a]=arguments[a];return(t=e.call.apply(e,[this].concat(s))||this).emitter=(n=t.props.value,r=[],{on:function(e){r.push(e)},off:function(e){r=r.filter((function(t){return t!==e}))},get:function(){return n},set:function(e,t){n=e,r.forEach((function(e){return e(n,t)}))}}),t}(0,r.A)(n,e);var o=n.prototype;return o.getChildContext=function(){var e;return(e={})[i]=this.emitter,e},o.componentWillReceiveProps=function(e){if(this.props.value!==e.value){var n,r=this.props.value,o=e.value;((s=r)===(a=o)?0!==s||1/s==1/a:s!=s&&a!=a)?n=0:(n="function"==typeof t?t(r,o):f,0!==(n|=0)&&this.emitter.set(e.value,n))}var s,a},o.render=function(){return this.props.children},n}(o.Component);c.childContextTypes=((n={})[i]=a().object.isRequired,n);var l=function(t){function n(){for(var e,n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return(e=t.call.apply(t,[this].concat(r))||this).observedBits=void 0,e.state={value:e.getValue()},e.onUpdate=function(t,n){(0|e.observedBits)&n&&e.setState({value:e.getValue()})},e}(0,r.A)(n,t);var o=n.prototype;return o.componentWillReceiveProps=function(e){var t=e.observedBits;this.observedBits=null==t?f:t},o.componentDidMount=function(){this.context[i]&&this.context[i].on(this.onUpdate);var e=this.props.observedBits;this.observedBits=null==e?f:e},o.componentWillUnmount=function(){this.context[i]&&this.context[i].off(this.onUpdate)},o.getValue=function(){return this.context[i]?this.context[i].get():e},o.render=function(){return(e=this.props.children,Array.isArray(e)?e[0]:e)(this.state.value);var e},n}(o.Component);return l.contextTypes=((s={})[i]=a().object,s),{Provider:c,Consumer:l}},h=function(e){var t=m();return t.displayName=e,t},b=h("Router-History"),v=h("Router"),y=function(e){function t(t){var n;return(n=e.call(this,t)||this).state={location:t.history.location},n._isMounted=!1,n._pendingLocation=null,t.staticContext||(n.unlisten=t.history.listen((function(e){n._pendingLocation=e}))),n}(0,r.A)(t,e),t.computeRootMatch=function(e){return{path:"/",url:"/",params:{},isExact:"/"===e}};var n=t.prototype;return n.componentDidMount=function(){var e=this;this._isMounted=!0,this.unlisten&&this.unlisten(),this.props.staticContext||(this.unlisten=this.props.history.listen((function(t){e._isMounted&&e.setState({location:t})}))),this._pendingLocation&&this.setState({location:this._pendingLocation})},n.componentWillUnmount=function(){this.unlisten&&(this.unlisten(),this._isMounted=!1,this._pendingLocation=null)},n.render=function(){return o.createElement(v.Provider,{value:{history:this.props.history,location:this.state.location,match:t.computeRootMatch(this.state.location.pathname),staticContext:this.props.staticContext}},o.createElement(b.Provider,{children:this.props.children||null,value:this.props.history}))},t}(o.Component);o.Component;o.Component;var w={},_=1e4,k=0;function x(e,t){void 0===t&&(t={}),("string"==typeof t||Array.isArray(t))&&(t={path:t});var n=t,r=n.path,o=n.exact,s=void 0!==o&&o,a=n.strict,i=void 0!==a&&a,c=n.sensitive,l=void 0!==c&&c;return[].concat(r).reduce((function(t,n){if(!n&&""!==n)return null;if(t)return t;var r=function(e,t){var n=""+t.end+t.strict+t.sensitive,r=w[n]||(w[n]={});if(r[e])return r[e];var o=[],s={regexp:p()(e,o,t),keys:o};return k<_&&(r[e]=s,k++),s}(n,{end:s,strict:i,sensitive:l}),o=r.regexp,a=r.keys,c=o.exec(e);if(!c)return null;var d=c[0],u=c.slice(1),f=e===d;return s&&!f?null:{path:n,url:"/"===n&&""===d?"/":d,isExact:f,params:a.reduce((function(e,t,n){return e[t.name]=u[n],e}),{})}}),null)}var S=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(v.Consumer,null,(function(t){t||(0,c.A)(!1);var n=e.props.location||t.location,r=e.props.computedMatch?e.props.computedMatch:e.props.path?x(n.pathname,e.props):t.match,s=(0,l.A)({},t,{location:n,match:r}),a=e.props,i=a.children,d=a.component,p=a.render;return Array.isArray(i)&&function(e){return 0===o.Children.count(e)}(i)&&(i=null),o.createElement(v.Provider,{value:s},s.match?i?"function"==typeof i?i(s):i:d?o.createElement(d,s):p?p(s):null:"function"==typeof i?i(s):null)}))},t}(o.Component);function E(e){return"/"===e.charAt(0)?e:"/"+e}function j(e,t){if(!e)return t;var n=E(e);return 0!==t.pathname.indexOf(n)?t:(0,l.A)({},t,{pathname:t.pathname.substr(n.length)})}function X(e){return"string"==typeof e?e:(0,i.AO)(e)}function C(e){return function(){(0,c.A)(!1)}}function T(){}o.Component;var A=function(e){function t(){return e.apply(this,arguments)||this}return(0,r.A)(t,e),t.prototype.render=function(){var e=this;return o.createElement(v.Consumer,null,(function(t){t||(0,c.A)(!1);var n,r,s=e.props.location||t.location;return o.Children.forEach(e.props.children,(function(e){if(null==r&&o.isValidElement(e)){n=e;var a=e.props.path||e.props.from;r=a?x(s.pathname,(0,l.A)({},e.props,{path:a})):t.match}})),r?o.cloneElement(n,{location:s,computedMatch:r}):null}))},t}(o.Component);var R=o.useContext;function P(){return R(b)}function N(){return R(v).location}},8505:(e,t,n)=>{var r=n(64634);e.exports=f,e.exports.parse=s,e.exports.compile=function(e,t){return i(s(e,t),t)},e.exports.tokensToFunction=i,e.exports.tokensToRegExp=u;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function s(e,t){for(var n,r=[],s=0,a=0,i="",d=t&&t.delimiter||"/";null!=(n=o.exec(e));){var p=n[0],u=n[1],f=n.index;if(i+=e.slice(a,f),a=f+p.length,u)i+=u[1];else{var g=e[a],m=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];i&&(r.push(i),i="");var _=null!=m&&null!=g&&g!==m,k="+"===y||"*"===y,x="?"===y||"*"===y,S=n[2]||d,E=b||v;r.push({name:h||s++,prefix:m||"",delimiter:S,optional:x,repeat:k,partial:_,asterisk:!!w,pattern:E?l(E):w?".*":"[^"+c(S)+"]+?"})}}return a<e.length&&(i+=e.substr(a)),i&&r.push(i),r}function a(e){return encodeURI(e).replace(/[\/?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()}))}function i(e,t){for(var n=new Array(e.length),o=0;o<e.length;o++)"object"==typeof e[o]&&(n[o]=new RegExp("^(?:"+e[o].pattern+")$",p(t)));return function(t,o){for(var s="",i=t||{},c=(o||{}).pretty?a:encodeURIComponent,l=0;l<e.length;l++){var d=e[l];if("string"!=typeof d){var p,u=i[d.name];if(null==u){if(d.optional){d.partial&&(s+=d.prefix);continue}throw new TypeError('Expected "'+d.name+'" to be defined')}if(r(u)){if(!d.repeat)throw new TypeError('Expected "'+d.name+'" to not repeat, but received `'+JSON.stringify(u)+"`");if(0===u.length){if(d.optional)continue;throw new TypeError('Expected "'+d.name+'" to not be empty')}for(var f=0;f<u.length;f++){if(p=c(u[f]),!n[l].test(p))throw new TypeError('Expected all "'+d.name+'" to match "'+d.pattern+'", but received `'+JSON.stringify(p)+"`");s+=(0===f?d.prefix:d.delimiter)+p}}else{if(p=d.asterisk?encodeURI(u).replace(/[?#]/g,(function(e){return"%"+e.charCodeAt(0).toString(16).toUpperCase()})):c(u),!n[l].test(p))throw new TypeError('Expected "'+d.name+'" to match "'+d.pattern+'", but received "'+p+'"');s+=d.prefix+p}}else s+=d}return s}}function c(e){return e.replace(/([.+*?=^!:${}()[\]|\/\\])/g,"\\$1")}function l(e){return e.replace(/([=!:$\/()])/g,"\\$1")}function d(e,t){return e.keys=t,e}function p(e){return e&&e.sensitive?"":"i"}function u(e,t,n){r(t)||(n=t||n,t=[]);for(var o=(n=n||{}).strict,s=!1!==n.end,a="",i=0;i<e.length;i++){var l=e[i];if("string"==typeof l)a+=c(l);else{var u=c(l.prefix),f="(?:"+l.pattern+")";t.push(l),l.repeat&&(f+="(?:"+u+f+")*"),a+=f=l.optional?l.partial?u+"("+f+")?":"(?:"+u+"("+f+"))?":u+"("+f+")"}}var g=c(n.delimiter||"/"),m=a.slice(-g.length)===g;return o||(a=(m?a.slice(0,-g.length):a)+"(?:"+g+"(?=$))?"),a+=s?"$":o&&m?"":"(?="+g+"|$)",d(new RegExp("^"+a,p(n)),t)}function f(e,t,n){return r(t)||(n=t||n,t=[]),n=n||{},e instanceof RegExp?function(e,t){var n=e.source.match(/\((?!\?)/g);if(n)for(var r=0;r<n.length;r++)t.push({name:r,prefix:null,delimiter:null,optional:!1,repeat:!1,partial:!1,asterisk:!1,pattern:null});return d(e,t)}(e,t):r(e)?function(e,t,n){for(var r=[],o=0;o<e.length;o++)r.push(f(e[o],t,n).source);return d(new RegExp("(?:"+r.join("|")+")",p(n)),t)}(e,t,n):function(e,t,n){return u(s(e,n),t,n)}(e,t,n)}},21020:(e,t,n)=>{"use strict";var r=n(96540),o=Symbol.for("react.element"),s=Symbol.for("react.fragment"),a=Object.prototype.hasOwnProperty,i=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,c={key:!0,ref:!0,__self:!0,__source:!0};function l(e,t,n){var r,s={},l=null,d=null;for(r in void 0!==n&&(l=""+n),void 0!==t.key&&(l=""+t.key),void 0!==t.ref&&(d=t.ref),t)a.call(t,r)&&!c.hasOwnProperty(r)&&(s[r]=t[r]);if(e&&e.defaultProps)for(r in t=e.defaultProps)void 0===s[r]&&(s[r]=t[r]);return{$$typeof:o,type:e,key:l,ref:d,props:s,_owner:i.current}}t.Fragment=s,t.jsx=l,t.jsxs=l},15287:(e,t)=>{"use strict";var n=Symbol.for("react.element"),r=Symbol.for("react.portal"),o=Symbol.for("react.fragment"),s=Symbol.for("react.strict_mode"),a=Symbol.for("react.profiler"),i=Symbol.for("react.provider"),c=Symbol.for("react.context"),l=Symbol.for("react.forward_ref"),d=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),u=Symbol.for("react.lazy"),f=Symbol.iterator;var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},m=Object.assign,h={};function b(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}function v(){}function y(e,t,n){this.props=e,this.context=t,this.refs=h,this.updater=n||g}b.prototype.isReactComponent={},b.prototype.setState=function(e,t){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,e,t,"setState")},b.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},v.prototype=b.prototype;var w=y.prototype=new v;w.constructor=y,m(w,b.prototype),w.isPureReactComponent=!0;var _=Array.isArray,k=Object.prototype.hasOwnProperty,x={current:null},S={key:!0,ref:!0,__self:!0,__source:!0};function E(e,t,r){var o,s={},a=null,i=null;if(null!=t)for(o in void 0!==t.ref&&(i=t.ref),void 0!==t.key&&(a=""+t.key),t)k.call(t,o)&&!S.hasOwnProperty(o)&&(s[o]=t[o]);var c=arguments.length-2;if(1===c)s.children=r;else if(1<c){for(var l=Array(c),d=0;d<c;d++)l[d]=arguments[d+2];s.children=l}if(e&&e.defaultProps)for(o in c=e.defaultProps)void 0===s[o]&&(s[o]=c[o]);return{$$typeof:n,type:e,key:a,ref:i,props:s,_owner:x.current}}function j(e){return"object"==typeof e&&null!==e&&e.$$typeof===n}var X=/\/+/g;function C(e,t){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var t={"=":"=0",":":"=2"};return"$"+e.replace(/[=:]/g,(function(e){return t[e]}))}(""+e.key):t.toString(36)}function T(e,t,o,s,a){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var c=!1;if(null===e)c=!0;else switch(i){case"string":case"number":c=!0;break;case"object":switch(e.$$typeof){case n:case r:c=!0}}if(c)return a=a(c=e),e=""===s?"."+C(c,0):s,_(a)?(o="",null!=e&&(o=e.replace(X,"$&/")+"/"),T(a,t,o,"",(function(e){return e}))):null!=a&&(j(a)&&(a=function(e,t){return{$$typeof:n,type:e.type,key:t,ref:e.ref,props:e.props,_owner:e._owner}}(a,o+(!a.key||c&&c.key===a.key?"":(""+a.key).replace(X,"$&/")+"/")+e)),t.push(a)),1;if(c=0,s=""===s?".":s+":",_(e))for(var l=0;l<e.length;l++){var d=s+C(i=e[l],l);c+=T(i,t,o,d,a)}else if(d=function(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=f&&e[f]||e["@@iterator"])?e:null}(e),"function"==typeof d)for(e=d.call(e),l=0;!(i=e.next()).done;)c+=T(i=i.value,t,o,d=s+C(i,l++),a);else if("object"===i)throw t=String(e),Error("Objects are not valid as a React child (found: "+("[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t)+"). If you meant to render a collection of children, use an array instead.");return c}function A(e,t,n){if(null==e)return e;var r=[],o=0;return T(e,r,"","",(function(e){return t.call(n,e,o++)})),r}function R(e){if(-1===e._status){var t=e._result;(t=t()).then((function(t){0!==e._status&&-1!==e._status||(e._status=1,e._result=t)}),(function(t){0!==e._status&&-1!==e._status||(e._status=2,e._result=t)})),-1===e._status&&(e._status=0,e._result=t)}if(1===e._status)return e._result.default;throw e._result}var P={current:null},N={transition:null},L={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:N,ReactCurrentOwner:x};function O(){throw Error("act(...) is not supported in production builds of React.")}t.Children={map:A,forEach:function(e,t,n){A(e,(function(){t.apply(this,arguments)}),n)},count:function(e){var t=0;return A(e,(function(){t++})),t},toArray:function(e){return A(e,(function(e){return e}))||[]},only:function(e){if(!j(e))throw Error("React.Children.only expected to receive a single React element child.");return e}},t.Component=b,t.Fragment=o,t.Profiler=a,t.PureComponent=y,t.StrictMode=s,t.Suspense=d,t.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=L,t.act=O,t.cloneElement=function(e,t,r){if(null==e)throw Error("React.cloneElement(...): The argument must be a React element, but you passed "+e+".");var o=m({},e.props),s=e.key,a=e.ref,i=e._owner;if(null!=t){if(void 0!==t.ref&&(a=t.ref,i=x.current),void 0!==t.key&&(s=""+t.key),e.type&&e.type.defaultProps)var c=e.type.defaultProps;for(l in t)k.call(t,l)&&!S.hasOwnProperty(l)&&(o[l]=void 0===t[l]&&void 0!==c?c[l]:t[l])}var l=arguments.length-2;if(1===l)o.children=r;else if(1<l){c=Array(l);for(var d=0;d<l;d++)c[d]=arguments[d+2];o.children=c}return{$$typeof:n,type:e.type,key:s,ref:a,props:o,_owner:i}},t.createContext=function(e){return(e={$$typeof:c,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null,_defaultValue:null,_globalName:null}).Provider={$$typeof:i,_context:e},e.Consumer=e},t.createElement=E,t.createFactory=function(e){var t=E.bind(null,e);return t.type=e,t},t.createRef=function(){return{current:null}},t.forwardRef=function(e){return{$$typeof:l,render:e}},t.isValidElement=j,t.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:R}},t.memo=function(e,t){return{$$typeof:p,type:e,compare:void 0===t?null:t}},t.startTransition=function(e){var t=N.transition;N.transition={};try{e()}finally{N.transition=t}},t.unstable_act=O,t.useCallback=function(e,t){return P.current.useCallback(e,t)},t.useContext=function(e){return P.current.useContext(e)},t.useDebugValue=function(){},t.useDeferredValue=function(e){return P.current.useDeferredValue(e)},t.useEffect=function(e,t){return P.current.useEffect(e,t)},t.useId=function(){return P.current.useId()},t.useImperativeHandle=function(e,t,n){return P.current.useImperativeHandle(e,t,n)},t.useInsertionEffect=function(e,t){return P.current.useInsertionEffect(e,t)},t.useLayoutEffect=function(e,t){return P.current.useLayoutEffect(e,t)},t.useMemo=function(e,t){return P.current.useMemo(e,t)},t.useReducer=function(e,t,n){return P.current.useReducer(e,t,n)},t.useRef=function(e){return P.current.useRef(e)},t.useState=function(e){return P.current.useState(e)},t.useSyncExternalStore=function(e,t,n){return P.current.useSyncExternalStore(e,t,n)},t.useTransition=function(){return P.current.useTransition()},t.version="18.3.1"},96540:(e,t,n)=>{"use strict";e.exports=n(15287)},74848:(e,t,n)=>{"use strict";e.exports=n(21020)},7463:(e,t)=>{"use strict";function n(e,t){var n=e.length;e.push(t);e:for(;0<n;){var r=n-1>>>1,o=e[r];if(!(0<s(o,t)))break e;e[r]=t,e[n]=o,n=r}}function r(e){return 0===e.length?null:e[0]}function o(e){if(0===e.length)return null;var t=e[0],n=e.pop();if(n!==t){e[0]=n;e:for(var r=0,o=e.length,a=o>>>1;r<a;){var i=2*(r+1)-1,c=e[i],l=i+1,d=e[l];if(0>s(c,n))l<o&&0>s(d,c)?(e[r]=d,e[l]=n,r=l):(e[r]=c,e[i]=n,r=i);else{if(!(l<o&&0>s(d,n)))break e;e[r]=d,e[l]=n,r=l}}}return t}function s(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}if("object"==typeof performance&&"function"==typeof performance.now){var a=performance;t.unstable_now=function(){return a.now()}}else{var i=Date,c=i.now();t.unstable_now=function(){return i.now()-c}}var l=[],d=[],p=1,u=null,f=3,g=!1,m=!1,h=!1,b="function"==typeof setTimeout?setTimeout:null,v="function"==typeof clearTimeout?clearTimeout:null,y="undefined"!=typeof setImmediate?setImmediate:null;function w(e){for(var t=r(d);null!==t;){if(null===t.callback)o(d);else{if(!(t.startTime<=e))break;o(d),t.sortIndex=t.expirationTime,n(l,t)}t=r(d)}}function _(e){if(h=!1,w(e),!m)if(null!==r(l))m=!0,N(k);else{var t=r(d);null!==t&&L(_,t.startTime-e)}}function k(e,n){m=!1,h&&(h=!1,v(j),j=-1),g=!0;var s=f;try{for(w(n),u=r(l);null!==u&&(!(u.expirationTime>n)||e&&!T());){var a=u.callback;if("function"==typeof a){u.callback=null,f=u.priorityLevel;var i=a(u.expirationTime<=n);n=t.unstable_now(),"function"==typeof i?u.callback=i:u===r(l)&&o(l),w(n)}else o(l);u=r(l)}if(null!==u)var c=!0;else{var p=r(d);null!==p&&L(_,p.startTime-n),c=!1}return c}finally{u=null,f=s,g=!1}}"undefined"!=typeof navigator&&void 0!==navigator.scheduling&&void 0!==navigator.scheduling.isInputPending&&navigator.scheduling.isInputPending.bind(navigator.scheduling);var x,S=!1,E=null,j=-1,X=5,C=-1;function T(){return!(t.unstable_now()-C<X)}function A(){if(null!==E){var e=t.unstable_now();C=e;var n=!0;try{n=E(!0,e)}finally{n?x():(S=!1,E=null)}}else S=!1}if("function"==typeof y)x=function(){y(A)};else if("undefined"!=typeof MessageChannel){var R=new MessageChannel,P=R.port2;R.port1.onmessage=A,x=function(){P.postMessage(null)}}else x=function(){b(A,0)};function N(e){E=e,S||(S=!0,x())}function L(e,n){j=b((function(){e(t.unstable_now())}),n)}t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){m||g||(m=!0,N(k))},t.unstable_forceFrameRate=function(e){0>e||125<e?console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"):X=0<e?Math.floor(1e3/e):5},t.unstable_getCurrentPriorityLevel=function(){return f},t.unstable_getFirstCallbackNode=function(){return r(l)},t.unstable_next=function(e){switch(f){case 1:case 2:case 3:var t=3;break;default:t=f}var n=f;f=t;try{return e()}finally{f=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=function(){},t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=f;f=e;try{return t()}finally{f=n}},t.unstable_scheduleCallback=function(e,o,s){var a=t.unstable_now();switch("object"==typeof s&&null!==s?s="number"==typeof(s=s.delay)&&0<s?a+s:a:s=a,e){case 1:var i=-1;break;case 2:i=250;break;case 5:i=1073741823;break;case 4:i=1e4;break;default:i=5e3}return e={id:p++,callback:o,priorityLevel:e,startTime:s,expirationTime:i=s+i,sortIndex:-1},s>a?(e.sortIndex=s,n(d,e),null===r(l)&&e===r(d)&&(h?(v(j),j=-1):h=!0,L(_,s-a))):(e.sortIndex=i,n(l,e),m||g||(m=!0,N(k))),e},t.unstable_shouldYield=T,t.unstable_wrapCallback=function(e){var t=f;return function(){var n=f;f=t;try{return e.apply(this,arguments)}finally{f=n}}}},69982:(e,t,n)=>{"use strict";e.exports=n(7463)},2833:e=>{e.exports=function(e,t,n,r){var o=n?n.call(r,e,t):void 0;if(void 0!==o)return!!o;if(e===t)return!0;if("object"!=typeof e||!e||"object"!=typeof t||!t)return!1;var s=Object.keys(e),a=Object.keys(t);if(s.length!==a.length)return!1;for(var i=Object.prototype.hasOwnProperty.bind(t),c=0;c<s.length;c++){var l=s[c];if(!i(l))return!1;var d=e[l],p=t[l];if(!1===(o=n?n.call(r,d,p,l):void 0)||void 0===o&&d!==p)return!1}return!0}},4784:(e,t,n)=>{"use strict";n.d(t,{A:()=>r});const r={title:"Casper Docs - Redux",tagline:"Casper Documentation",favicon:"icon/favicon.ico",url:"https://casper-network.github.io",baseUrl:"/",organizationName:"casper-network",projectName:"docs-redux",deploymentBranch:"gh-pages",trailingSlash:!0,onBrokenLinks:"warn",onBrokenMarkdownLinks:"warn",onDuplicateRoutes:"throw",markdown:{format:"detect",mermaid:!1,mdx1Compat:{comments:!0,admonitions:!0,headingIds:!0},anchors:{maintainCase:!1}},presets:[["classic",{theme:{customCss:"./src/css/custom.css"},docs:{path:"./docs",sidebarPath:"./config/sidebar.config.js",routeBasePath:"/",exclude:["./contract-dsl/archived","./economics/archived","./theory"],showLastUpdateTime:!0,showLastUpdateAuthor:!0,lastVersion:"current"},blog:{path:"./blog",routeBasePath:"blog",blogTitle:"Casper Developer Relations Blog",blogDescription:"A blog about all things to do with developing on the Casper Blockchain",postsPerPage:"ALL",blogSidebarTitle:"All posts",blogSidebarCount:"ALL"}}]],themeConfig:{colorMode:{defaultMode:"dark",disableSwitch:!1,respectPrefersColorScheme:!0},algolia:{appId:"KQNX60E7J5",apiKey:"42e859bcdaa94a6c412d933cbaabe2e2",indexName:"casperlabs",contextualSearch:!0,externalUrlRegex:"external\\.com|domain\\.com",replaceSearchResultPathname:{from:"/docs/",to:"/"},searchParameters:{},searchPagePath:"search",insights:!1},navbar:{title:"",logo:{alt:"Casper Logo",src:"/icon/Casper_Wordmark_Red_RGB.png",srcDark:"/icon/Casper_Wordmark_Red_RGB.png"},items:[{type:"docSidebar",sidebarId:"concepts",label:"Concepts",position:"left"},{type:"docSidebar",sidebarId:"developers",label:"Developers",position:"left"},{type:"docSidebar",sidebarId:"operators",label:"Operators",position:"left"},{type:"docSidebar",sidebarId:"users",label:"Users",position:"left"},{type:"docSidebar",sidebarId:"resources",label:"Resources",position:"left"},{type:"docSidebar",sidebarId:"tutorials",label:"Tutorials",position:"left"},{to:"https://github.com/casper-devrel/docs-redux/issues/new?assignees=&labels=docs-v2-feedback&projects=&template=feedback.yml&title=Docs+Feedback",label:"Feedback",position:"right"},{to:"blog/tags/condor",label:"Condor",position:"right"},{to:"blog",label:"Blog",position:"right"},{type:"search",position:"right"},{type:"docsVersionDropdown",position:"right",dropdownActiveClassDisabled:!0,dropdownItemsBefore:[],dropdownItemsAfter:[]},{href:"https://support.casperlabs.io/",label:"Support",position:"right"},{href:"https://discord.com/invite/casperblockchain",label:"Chat",position:"right"},{href:"https://github.com/casper-devrel/docs-redux",label:"GitHub",position:"right"}],hideOnScroll:!1},footer:{logo:{alt:"Casper Logo",src:"/icon/Casper_Wordmark_Horizontal_Red_RGB.png",srcDark:"/icon/Casper_Wordmark_Horizontal_White_RGB.png",href:"https://casper.network/",width:120,height:30},copyright:"Copyright \xa9 2024 Casper Association. Built with Docusaurus.",links:[],style:"light"},prism:{theme:{plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},darkTheme:{plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},additionalLanguages:[],magicComments:[{className:"theme-code-block-highlighted-line",line:"highlight-next-line",block:{start:"highlight-start",end:"highlight-end"}}]},announcementBar:{id:"announcement",content:'This is an Alpha version of the Casper Docs Redux. \n Any suggestions please email to <a href="mailto:devrel@casper.network">devrel@casper.network</a>, or \n submit an issue on <a href="https://github.com/casper-devrel/docs-redux/issues/new?assignees=&labels=docs-v2-feedback&projects=&template=feedback.yml&title=Docs+Feedback">Github<a/>',backgroundColor:"#f9f9f9",textColor:"#000000",isCloseable:!0},docs:{versionPersistence:"localStorage",sidebar:{hideable:!1,autoCollapseCategories:!1}},blog:{sidebar:{groupByYear:!0}},metadata:[],tableOfContents:{minHeadingLevel:2,maxHeadingLevel:3}},baseUrlIssueBanner:!0,i18n:{defaultLocale:"en",path:"i18n",locales:["en"],localeConfigs:{}},future:{experimental_storage:{type:"localStorage",namespace:!1},experimental_router:"browser"},onBrokenAnchors:"warn",staticDirectories:["static"],customFields:{},plugins:[],themes:[],scripts:[],headTags:[],stylesheets:[],clientModules:[],titleDelimiter:"|",noIndex:!1}},58168:(e,t,n)=>{"use strict";function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}n.d(t,{A:()=>r})},42892:(e,t,n)=>{"use strict";function r(e,t){return r=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,t){return e.__proto__=t,e},r(e,t)}function o(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,r(e,t)}n.d(t,{A:()=>o})},98587:(e,t,n)=>{"use strict";function r(e,t){if(null==e)return{};var n={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(t.indexOf(r)>=0)continue;n[r]=e[r]}return n}n.d(t,{A:()=>r})},34164:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e)){var s=e.length;for(t=0;t<s;t++)e[t]&&(n=r(e[t]))&&(o&&(o+=" "),o+=n)}else for(n in e)e[n]&&(o&&(o+=" "),o+=n);return o}n.d(t,{A:()=>o});const o=function(){for(var e,t,n=0,o="",s=arguments.length;n<s;n++)(e=arguments[n])&&(t=r(e))&&(o&&(o+=" "),o+=t);return o}},71765:(e,t,n)=>{"use strict";n.d(t,{My:()=>X,f4:()=>ee});var r,o,s,a,i,c,l,d=n(96540),p=n(34164),u=Object.create,f=Object.defineProperty,g=Object.defineProperties,m=Object.getOwnPropertyDescriptor,h=Object.getOwnPropertyDescriptors,b=Object.getOwnPropertyNames,v=Object.getOwnPropertySymbols,y=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty,_=Object.prototype.propertyIsEnumerable,k=(e,t,n)=>t in e?f(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,x=(e,t)=>{for(var n in t||(t={}))w.call(t,n)&&k(e,n,t[n]);if(v)for(var n of v(t))_.call(t,n)&&k(e,n,t[n]);return e},S=(e,t)=>g(e,h(t)),E=(e,t)=>{var n={};for(var r in e)w.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&v)for(var r of v(e))t.indexOf(r)<0&&_.call(e,r)&&(n[r]=e[r]);return n},j=(r={"../../node_modules/.pnpm/prismjs@1.29.0_patch_hash=vrxx3pzkik6jpmgpayxfjunetu/node_modules/prismjs/prism.js"(e,t){var n=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof o?new o(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++t}),e.__id},clone:function e(t,n){var o,s;switch(n=n||{},r.util.type(t)){case"Object":if(s=r.util.objId(t),n[s])return n[s];for(var a in o={},n[s]=o,t)t.hasOwnProperty(a)&&(o[a]=e(t[a],n));return o;case"Array":return s=r.util.objId(t),n[s]?n[s]:(o=[],n[s]=o,t.forEach((function(t,r){o[r]=e(t,n)})),o);default:return t}},getLanguage:function(t){for(;t;){var n=e.exec(t.className);if(n)return n[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,n){t.className=t.className.replace(RegExp(e,"gi"),""),t.classList.add("language-"+n)},isActive:function(e,t,n){for(var r="no-"+t;e;){var o=e.classList;if(o.contains(t))return!0;if(o.contains(r))return!1;e=e.parentElement}return!!n}},languages:{plain:n,plaintext:n,text:n,txt:n,extend:function(e,t){var n=r.util.clone(r.languages[e]);for(var o in t)n[o]=t[o];return n},insertBefore:function(e,t,n,o){var s=(o=o||r.languages)[e],a={};for(var i in s)if(s.hasOwnProperty(i)){if(i==t)for(var c in n)n.hasOwnProperty(c)&&(a[c]=n[c]);n.hasOwnProperty(i)||(a[i]=s[i])}var l=o[e];return o[e]=a,r.languages.DFS(r.languages,(function(t,n){n===l&&t!=e&&(this[t]=a)})),a},DFS:function e(t,n,o,s){s=s||{};var a=r.util.objId;for(var i in t)if(t.hasOwnProperty(i)){n.call(t,i,t[i],o||i);var c=t[i],l=r.util.type(c);"Object"!==l||s[a(c)]?"Array"!==l||s[a(c)]||(s[a(c)]=!0,e(c,n,i,s)):(s[a(c)]=!0,e(c,n,null,s))}}},plugins:{},highlight:function(e,t,n){var s={code:e,grammar:t,language:n};if(r.hooks.run("before-tokenize",s),!s.grammar)throw new Error('The language "'+s.language+'" has no grammar.');return s.tokens=r.tokenize(s.code,s.grammar),r.hooks.run("after-tokenize",s),o.stringify(r.util.encode(s.tokens),s.language)},tokenize:function(e,t){var n=t.rest;if(n){for(var r in n)t[r]=n[r];delete t.rest}var o=new i;return c(o,o.head,e),a(e,o,t,o.head,0),function(e){for(var t=[],n=e.head.next;n!==e.tail;)t.push(n.value),n=n.next;return t}(o)},hooks:{all:{},add:function(e,t){var n=r.hooks.all;n[e]=n[e]||[],n[e].push(t)},run:function(e,t){var n=r.hooks.all[e];if(n&&n.length)for(var o,s=0;o=n[s++];)o(t)}},Token:o};function o(e,t,n,r){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length}function s(e,t,n,r){e.lastIndex=t;var o=e.exec(n);if(o&&r&&o[1]){var s=o[1].length;o.index+=s,o[0]=o[0].slice(s)}return o}function a(e,t,n,i,d,p){for(var u in n)if(n.hasOwnProperty(u)&&n[u]){var f=n[u];f=Array.isArray(f)?f:[f];for(var g=0;g<f.length;++g){if(p&&p.cause==u+","+g)return;var m=f[g],h=m.inside,b=!!m.lookbehind,v=!!m.greedy,y=m.alias;if(v&&!m.pattern.global){var w=m.pattern.toString().match(/[imsuy]*$/)[0];m.pattern=RegExp(m.pattern.source,w+"g")}for(var _=m.pattern||m,k=i.next,x=d;k!==t.tail&&!(p&&x>=p.reach);x+=k.value.length,k=k.next){var S=k.value;if(t.length>e.length)return;if(!(S instanceof o)){var E,j=1;if(v){if(!(E=s(_,x,e,b))||E.index>=e.length)break;var X=E.index,C=E.index+E[0].length,T=x;for(T+=k.value.length;X>=T;)T+=(k=k.next).value.length;if(x=T-=k.value.length,k.value instanceof o)continue;for(var A=k;A!==t.tail&&(T<C||"string"==typeof A.value);A=A.next)j++,T+=A.value.length;j--,S=e.slice(x,T),E.index-=x}else if(!(E=s(_,0,S,b)))continue;X=E.index;var R=E[0],P=S.slice(0,X),N=S.slice(X+R.length),L=x+S.length;p&&L>p.reach&&(p.reach=L);var O=k.prev;if(P&&(O=c(t,O,P),x+=P.length),l(t,O,j),k=c(t,O,new o(u,h?r.tokenize(R,h):R,y,R)),N&&c(t,k,N),j>1){var D={cause:u+","+g,reach:L};a(e,t,n,k.prev,x,D),p&&D.reach>p.reach&&(p.reach=D.reach)}}}}}}function i(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,o={value:n,prev:t,next:r};return t.next=o,r.prev=o,e.length++,o}function l(e,t,n){for(var r=t.next,o=0;o<n&&r!==e.tail;o++)r=r.next;t.next=r,r.prev=t,e.length-=o}return o.stringify=function e(t,n){if("string"==typeof t)return t;if(Array.isArray(t)){var o="";return t.forEach((function(t){o+=e(t,n)})),o}var s={type:t.type,content:e(t.content,n),tag:"span",classes:["token",t.type],attributes:{},language:n},a=t.alias;a&&(Array.isArray(a)?Array.prototype.push.apply(s.classes,a):s.classes.push(a)),r.hooks.run("wrap",s);var i="";for(var c in s.attributes)i+=" "+c+'="'+(s.attributes[c]||"").replace(/"/g,""")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'"'+i+">"+s.content+"</"+s.tag+">"},r}();t.exports=n,n.default=n}},function(){return o||(0,r[b(r)[0]])((o={exports:{}}).exports,o),o.exports}),X=((e,t,n)=>(n=null!=e?u(y(e)):{},((e,t,n,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let o of b(t))w.call(e,o)||o===n||f(e,o,{get:()=>t[o],enumerable:!(r=m(t,o))||r.enumerable});return e})(!t&&e&&e.__esModule?n:f(n,"default",{value:e,enumerable:!0}),e)))(j());X.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},X.languages.markup.tag.inside["attr-value"].inside.entity=X.languages.markup.entity,X.languages.markup.doctype.inside["internal-subset"].inside=X.languages.markup,X.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(X.languages.markup.tag,"addInlined",{value:function(e,t){var n;(t=((n=((n={})["language-"+t]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:X.languages[t]},n.cdata=/^<!\[CDATA\[|\]\]>$/i,{"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:n}}))["language-"+t]={pattern:/[\s\S]+/,inside:X.languages[t]},{}))[e]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:n},X.languages.insertBefore("markup","cdata",t)}}),Object.defineProperty(X.languages.markup.tag,"addAttribute",{value:function(e,t){X.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:X.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),X.languages.html=X.languages.markup,X.languages.mathml=X.languages.markup,X.languages.svg=X.languages.markup,X.languages.xml=X.languages.extend("markup",{}),X.languages.ssml=X.languages.xml,X.languages.atom=X.languages.xml,X.languages.rss=X.languages.xml,s=X,a={pattern:/\\[\\(){}[\]^$+*?|.]/,alias:"escape"},c="(?:[^\\\\-]|"+(i=/\\(?:x[\da-fA-F]{2}|u[\da-fA-F]{4}|u\{[\da-fA-F]+\}|0[0-7]{0,2}|[123][0-7]{2}|c[a-zA-Z]|.)/).source+")",c=RegExp(c+"-"+c),l={pattern:/(<|')[^<>']+(?=[>']$)/,lookbehind:!0,alias:"variable"},s.languages.regex={"char-class":{pattern:/((?:^|[^\\])(?:\\\\)*)\[(?:[^\\\]]|\\[\s\S])*\]/,lookbehind:!0,inside:{"char-class-negation":{pattern:/(^\[)\^/,lookbehind:!0,alias:"operator"},"char-class-punctuation":{pattern:/^\[|\]$/,alias:"punctuation"},range:{pattern:c,inside:{escape:i,"range-punctuation":{pattern:/-/,alias:"operator"}}},"special-escape":a,"char-set":{pattern:/\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},escape:i}},"special-escape":a,"char-set":{pattern:/\.|\\[wsd]|\\p\{[^{}]+\}/i,alias:"class-name"},backreference:[{pattern:/\\(?![123][0-7]{2})[1-9]/,alias:"keyword"},{pattern:/\\k<[^<>']+>/,alias:"keyword",inside:{"group-name":l}}],anchor:{pattern:/[$^]|\\[ABbGZz]/,alias:"function"},escape:i,group:[{pattern:/\((?:\?(?:<[^<>']+>|'[^<>']+'|[>:]|<?[=!]|[idmnsuxU]+(?:-[idmnsuxU]+)?:?))?/,alias:"punctuation",inside:{"group-name":l}},{pattern:/\)/,alias:"punctuation"}],quantifier:{pattern:/(?:[+*?]|\{\d+(?:,\d*)?\})[?+]?/,alias:"number"},alternation:{pattern:/\|/,alias:"keyword"}},X.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},X.languages.javascript=X.languages.extend("clike",{"class-name":[X.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),X.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,X.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:X.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:X.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:X.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:X.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:X.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),X.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:X.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),X.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),X.languages.markup&&(X.languages.markup.tag.addInlined("script","javascript"),X.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),X.languages.js=X.languages.javascript,X.languages.actionscript=X.languages.extend("javascript",{keyword:/\b(?:as|break|case|catch|class|const|default|delete|do|dynamic|each|else|extends|final|finally|for|function|get|if|implements|import|in|include|instanceof|interface|internal|is|namespace|native|new|null|override|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|use|var|void|while|with)\b/,operator:/\+\+|--|(?:[+\-*\/%^]|&&?|\|\|?|<<?|>>?>?|[!=]=?)=?|[~?@]/}),X.languages.actionscript["class-name"].alias="function",delete X.languages.actionscript.parameter,delete X.languages.actionscript["literal-property"],X.languages.markup&&X.languages.insertBefore("actionscript","string",{xml:{pattern:/(^|[^.])<\/?\w+(?:\s+[^\s>\/=]+=("|')(?:\\[\s\S]|(?!\2)[^\\])*\2)*\s*\/?>/,lookbehind:!0,inside:X.languages.markup}}),function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(X),function(e){var t=e.languages.javadoclike={parameter:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*@(?:arg|arguments|param)\s+)\w+/m,lookbehind:!0},keyword:{pattern:/(^[\t ]*(?:\/{3}|\*|\/\*\*)\s*|\{)@[a-z][a-zA-Z-]+\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(t,"addSupport",{value:function(t,n){(t="string"==typeof t?[t]:t).forEach((function(t){var r=function(e){e.inside||(e.inside={}),e.inside.rest=n},o="doc-comment";if(s=e.languages[t]){var s,a=s[o];if((a=a||(s=e.languages.insertBefore(t,"comment",{"doc-comment":{pattern:/(^|[^\\])\/\*\*[^/][\s\S]*?(?:\*\/|$)/,lookbehind:!0,alias:"comment"}}))[o])instanceof RegExp&&(a=s[o]={pattern:a}),Array.isArray(a))for(var i=0,c=a.length;i<c;i++)a[i]instanceof RegExp&&(a[i]={pattern:a[i]}),r(a[i]);else r(a)}}))}}),t.addSupport(["java","javascript","php"],t)}(X),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;(t=(e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+t.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css,e.languages.markup))&&(t.tag.addInlined("style","css"),t.tag.addAttribute("style","css"))}(X),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,n=(t=(e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+t.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[t,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}}),{pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0}),{pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0});e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|RebeccaPurple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,number:n})}(X),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",o=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-]<PLAIN>)(?:[ \t]*(?:(?![#:])<PLAIN>|:<PLAIN>))*/.source.replace(/<PLAIN>/g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),s=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function a(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<<prop>>[ \t]+)?)(?:<<value>>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<value>>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<<prop>>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<<prop>>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<<prop>>[ \t]+)?)<<key>>(?=\s*:\s)/.source.replace(/<<prop>>/g,(function(){return r})).replace(/<<key>>/g,(function(){return"(?:"+o+"|"+s+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:a(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:a(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:a(s),lookbehind:!0,greedy:!0},number:{pattern:a(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(X),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(/<inner>/g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,o=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),s=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source,a=(e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+o+s+"(?:"+o+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+o+s+")(?:"+o+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+o+")"+s+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+o+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)<inner>|_(?:(?!_)<inner>)+_)+__\b|\*\*(?:(?!\*)<inner>|\*(?:(?!\*)<inner>)+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)<inner>|__(?:(?!_)<inner>)+__)+_\b|\*(?:(?!\*)<inner>|\*\*(?:(?!\*)<inner>)+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~)<inner>)+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\])<inner>)+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\])<inner>)+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n<r;n++){var o,s=t[n];"code"!==s.type?e(s.content):(o=s.content[1],s=s.content[3],o&&s&&"code-language"===o.type&&"code-block"===s.type&&"string"==typeof o.content&&(o=o.content.replace(/\b#/g,"sharp").replace(/\b\+\+/g,"pp"),o="language-"+(o=(/[a-z][\w-]*/i.exec(o)||[""])[0].toLowerCase()),s.alias?"string"==typeof s.alias?s.alias=[s.alias,o]:s.alias.push(o):s.alias=[o]))}}(e.tokens)})),e.hooks.add("wrap",(function(t){if("code-block"===t.type){for(var n="",r=0,o=t.classes.length;r<o;r++){var s=t.classes[r];if(s=/language-(.+)/.exec(s)){n=s[1];break}}var l,d=e.languages[n];d?t.content=e.highlight(t.content.replace(a,"").replace(/&(\w{1,8}|#x?[\da-f]{1,8});/gi,(function(e,t){var n;return"#"===(t=t.toLowerCase())[0]?(n="x"===t[1]?parseInt(t.slice(2),16):Number(t.slice(1)),c(n)):i[t]||e})),d,n):n&&"none"!==n&&e.plugins.autoloader&&(l="md-"+(new Date).valueOf()+"-"+Math.floor(1e16*Math.random()),t.attributes.id=l,e.plugins.autoloader.loadLanguages(n,(function(){var t=document.getElementById(l);t&&(t.innerHTML=e.highlight(t.textContent,e.languages[n],n))})))}})),RegExp(e.languages.markup.tag.pattern.source,"gi")),i={amp:"&",lt:"<",gt:">",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(X),X.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:X.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},X.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n<t.length;){var r=t[n++];if("keyword"===r.type&&"mutation"===r.content){var o=[];if(p(["definition-mutation","punctuation"])&&"("===d(1).content){n+=2;var s=u(/^\($/,/^\)$/);if(-1===s)continue;for(;n<s;n++){var a=d(0);"variable"===a.type&&(f(a,"variable-input"),o.push(a.content))}n=s+1}if(p(["punctuation","property-query"])&&"{"===d(0).content&&(n++,f(d(0),"property-mutation"),0<o.length)){var i=u(/^\{$/,/^\}$/);if(-1!==i)for(var c=n;c<i;c++){var l=t[c];"variable"===l.type&&0<=o.indexOf(l.content)&&f(l,"variable-input")}}}}function d(e){return t[n+e]}function p(e,t){t=t||0;for(var n=0;n<e.length;n++){var r=d(n+t);if(!r||r.type!==e[n])return}return 1}function u(e,r){for(var o=1,s=n;s<t.length;s++){var a=t[s],i=a.content;if("punctuation"===a.type&&"string"==typeof i)if(e.test(i))o++;else if(r.test(i)&&0==--o)return s}return-1}function f(e,t){var n=e.alias;n?Array.isArray(n)||(e.alias=n=[n]):e.alias=n=[],n.push(t)}})),X.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,o=r.inside["interpolation-punctuation"],s=r.pattern.source;function a(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function i(t,n,r){return t={code:t,grammar:n,language:r},e.hooks.run("before-tokenize",t),t.tokens=e.tokenize(t.code,t.grammar),e.hooks.run("after-tokenize",t),t.tokens}function c(t,n,a){var c=e.tokenize(t,{interpolation:{pattern:RegExp(s),lookbehind:!0}}),l=0,d={},p=(c=i(c.map((function(e){if("string"==typeof e)return e;var n,r;for(e=e.content;-1!==t.indexOf((r=l++,n="___"+a.toUpperCase()+"_"+r+"___")););return d[n]=e,n})).join(""),n,a),Object.keys(d));return l=0,function t(n){for(var s=0;s<n.length;s++){if(l>=p.length)return;var a,c,u,f,g,m,h,b=n[s];"string"==typeof b||"string"==typeof b.content?(a=p[l],-1!==(h=(m="string"==typeof b?b:b.content).indexOf(a))&&(++l,c=m.substring(0,h),g=d[a],u=void 0,(f={})["interpolation-punctuation"]=o,3===(f=e.tokenize(g,f)).length&&((u=[1,1]).push.apply(u,i(f[1],e.languages.javascript,"javascript")),f.splice.apply(f,u)),u=new e.Token("interpolation",f,r.alias,g),f=m.substring(h+a.length),g=[],c&&g.push(c),g.push(u),f&&(t(m=[f]),g.push.apply(g,m)),"string"==typeof b?(n.splice.apply(n,[s,1].concat(g)),s+=g.length-1):b.content=g)):(h=b.content,Array.isArray(h)?t(h):t([h]))}}(c),new e.Token(a,c,"language-"+a,t)}e.languages.javascript["template-string"]=[a("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),a("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),a("svg",/\bsvg/.source),a("markdown",/\b(?:markdown|md)/.source),a("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),a("sql",/\bsql/.source),t].filter(Boolean);var l={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function d(e){return"string"==typeof e?e:Array.isArray(e)?e.map(d).join(""):d(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in l&&function t(n){for(var r=0,o=n.length;r<o;r++){var s,a,i,l=n[r];"string"!=typeof l&&(s=l.content,Array.isArray(s)?"template-string"===l.type?(l=s[1],3===s.length&&"string"!=typeof l&&"embedded-code"===l.type&&(a=d(l),l=l.alias,l=Array.isArray(l)?l[0]:l,i=e.languages[l])&&(s[1]=c(a,i,l))):t(s):"string"!=typeof s&&t([s]))}}(t.tokens)}))}(X),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(X),function(e){var t=e.languages.javascript,n=/\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})+\}/.source,r="(@(?:arg|argument|param|property)\\s+(?:"+n+"\\s+)?)";e.languages.jsdoc=e.languages.extend("javadoclike",{parameter:{pattern:RegExp(r+/(?:(?!\s)[$\w\xA0-\uFFFF.])+(?=\s|$)/.source),lookbehind:!0,inside:{punctuation:/\./}}}),e.languages.insertBefore("jsdoc","keyword",{"optional-parameter":{pattern:RegExp(r+/\[(?:(?!\s)[$\w\xA0-\uFFFF.])+(?:=[^[\]]+)?\](?=\s|$)/.source),lookbehind:!0,inside:{parameter:{pattern:/(^\[)[$\w\xA0-\uFFFF\.]+/,lookbehind:!0,inside:{punctuation:/\./}},code:{pattern:/(=)[\s\S]*(?=\]$)/,lookbehind:!0,inside:t,alias:"language-javascript"},punctuation:/[=[\]]/}},"class-name":[{pattern:RegExp(/(@(?:augments|class|extends|interface|memberof!?|template|this|typedef)\s+(?:<TYPE>\s+)?)[A-Z]\w*(?:\.[A-Z]\w*)*/.source.replace(/<TYPE>/g,(function(){return n}))),lookbehind:!0,inside:{punctuation:/\./}},{pattern:RegExp("(@[a-z]+\\s+)"+n),lookbehind:!0,inside:{string:t.string,number:t.number,boolean:t.boolean,keyword:e.languages.typescript.keyword,operator:/=>|\.\.\.|[&|?:*]/,punctuation:/[.,;=<>{}()[\]]/}}],example:{pattern:/(@example\s+(?!\s))(?:[^@\s]|\s+(?!\s))+?(?=\s*(?:\*\s*)?(?:@\w|\*\/))/,lookbehind:!0,inside:{code:{pattern:/^([\t ]*(?:\*\s*)?)\S.*$/m,lookbehind:!0,inside:t,alias:"language-javascript"}}}}),e.languages.javadoclike.addSupport("javascript",e.languages.jsdoc)}(X),function(e){e.languages.flow=e.languages.extend("javascript",{}),e.languages.insertBefore("flow","keyword",{type:[{pattern:/\b(?:[Bb]oolean|Function|[Nn]umber|[Ss]tring|[Ss]ymbol|any|mixed|null|void)\b/,alias:"class-name"}]}),e.languages.flow["function-variable"].pattern=/(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=\s*(?:function\b|(?:\([^()]*\)(?:\s*:\s*\w+)?|(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/i,delete e.languages.flow.parameter,e.languages.insertBefore("flow","operator",{"flow-punctuation":{pattern:/\{\||\|\}/,alias:"punctuation"}}),Array.isArray(e.languages.flow.keyword)||(e.languages.flow.keyword=[e.languages.flow.keyword]),e.languages.flow.keyword.unshift({pattern:/(^|[^$]\b)(?:Class|declare|opaque|type)\b(?!\$)/,lookbehind:!0},{pattern:/(^|[^$]\B)\$(?:Diff|Enum|Exact|Keys|ObjMap|PropertyType|Record|Shape|Subtype|Supertype|await)\b(?!\$)/,lookbehind:!0})}(X),X.languages.n4js=X.languages.extend("javascript",{keyword:/\b(?:Array|any|boolean|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|false|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|module|new|null|number|package|private|protected|public|return|set|static|string|super|switch|this|throw|true|try|typeof|var|void|while|with|yield)\b/}),X.languages.insertBefore("n4js","constant",{annotation:{pattern:/@+\w+/,alias:"operator"}}),X.languages.n4jsd=X.languages.n4js,function(e){function t(e,t){return RegExp(e.replace(/<ID>/g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:<ID>(?:\s*,\s*(?:\*\s*as\s+<ID>|\{[^{}]*\}))?|\*\s*as\s+<ID>|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+<ID>)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?<ID>/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r<n.length;r++){var o=n[r],s=e.languages.javascript[o];o=(s="RegExp"===e.util.type(s)?e.languages.javascript[o]={pattern:s}:s).inside||{};(s.inside=o)["maybe-class-name"]=/^[A-Z][\s\S]*/}}(X),function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,o=/(?:\{<S>*\.{3}(?:[^{}]|<BRACES>)*\})/.source;function s(e,t){return e=e.replace(/<S>/g,(function(){return n})).replace(/<BRACES>/g,(function(){return r})).replace(/<SPREAD>/g,(function(){return o})),RegExp(e,t)}function a(t){for(var n=[],r=0;r<t.length;r++){var o=t[r],s=!1;"string"!=typeof o&&("tag"===o.type&&o.content[0]&&"tag"===o.content[0].type?"</"===o.content[0].content[0].content?0<n.length&&n[n.length-1].tagName===i(o.content[0].content[1])&&n.pop():"/>"!==o.content[o.content.length-1].content&&n.push({tagName:i(o.content[0].content[1]),openedBraces:0}):0<n.length&&"punctuation"===o.type&&"{"===o.content?n[n.length-1].openedBraces++:0<n.length&&0<n[n.length-1].openedBraces&&"punctuation"===o.type&&"}"===o.content?n[n.length-1].openedBraces--:s=!0),(s||"string"==typeof o)&&0<n.length&&0===n[n.length-1].openedBraces&&(s=i(o),r<t.length-1&&("string"==typeof t[r+1]||"plain-text"===t[r+1].type)&&(s+=i(t[r+1]),t.splice(r+1,1)),0<r&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)),o.content&&"string"!=typeof o.content&&a(o.content)}}o=s(o).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=s(/<\/?(?:[\w.:-]+(?:<S>+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|<BRACES>))?|<SPREAD>))*<S>*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:s(/<SPREAD>/.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:s(/=<BRACES>/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||a(e.tokens)}))}(X),function(e){var t=e.util.clone(e.languages.typescript);(t=(e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"],e.languages.tsx.tag)).pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+t.pattern.source+")",t.pattern.flags),t.lookbehind=!0}(X),X.languages.swift={comment:{pattern:/(^|[^\\:])(?:\/\/.*|\/\*(?:[^/*]|\/(?!\*)|\*(?!\/)|\/\*(?:[^*]|\*(?!\/))*\*\/)*\*\/)/,lookbehind:!0,greedy:!0},"string-literal":[{pattern:RegExp(/(^|[^"#])/.source+"(?:"+/"(?:\\(?:\((?:[^()]|\([^()]*\))*\)|\r\n|[^(])|[^\\\r\n"])*"/.source+"|"+/"""(?:\\(?:\((?:[^()]|\([^()]*\))*\)|[^(])|[^\\"]|"(?!""))*"""/.source+")"+/(?!["#])/.source),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\\($/,alias:"punctuation"},punctuation:/\\(?=[\r\n])/,string:/[\s\S]+/}},{pattern:RegExp(/(^|[^"#])(#+)/.source+"(?:"+/"(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|\r\n|[^#])|[^\\\r\n])*?"/.source+"|"+/"""(?:\\(?:#+\((?:[^()]|\([^()]*\))*\)|[^#])|[^\\])*?"""/.source+")\\2"),lookbehind:!0,greedy:!0,inside:{interpolation:{pattern:/(\\#+\()(?:[^()]|\([^()]*\))*(?=\))/,lookbehind:!0,inside:null},"interpolation-punctuation":{pattern:/^\)|\\#+\($/,alias:"punctuation"},string:/[\s\S]+/}}],directive:{pattern:RegExp(/#/.source+"(?:"+/(?:elseif|if)\b/.source+"(?:[ \t]*"+/(?:![ \t]*)?(?:\b\w+\b(?:[ \t]*\((?:[^()]|\([^()]*\))*\))?|\((?:[^()]|\([^()]*\))*\))(?:[ \t]*(?:&&|\|\|))?/.source+")+|"+/(?:else|endif)\b/.source+")"),alias:"property",inside:{"directive-name":/^#\w+/,boolean:/\b(?:false|true)\b/,number:/\b\d+(?:\.\d+)*\b/,operator:/!|&&|\|\||[<>]=?/,punctuation:/[(),]/}},literal:{pattern:/#(?:colorLiteral|column|dsohandle|file(?:ID|Literal|Path)?|function|imageLiteral|line)\b/,alias:"constant"},"other-directive":{pattern:/#\w+\b/,alias:"property"},attribute:{pattern:/@\w+/,alias:"atrule"},"function-definition":{pattern:/(\bfunc\s+)\w+/,lookbehind:!0,alias:"function"},label:{pattern:/\b(break|continue)\s+\w+|\b[a-zA-Z_]\w*(?=\s*:\s*(?:for|repeat|while)\b)/,lookbehind:!0,alias:"important"},keyword:/\b(?:Any|Protocol|Self|Type|actor|as|assignment|associatedtype|associativity|async|await|break|case|catch|class|continue|convenience|default|defer|deinit|didSet|do|dynamic|else|enum|extension|fallthrough|fileprivate|final|for|func|get|guard|higherThan|if|import|in|indirect|infix|init|inout|internal|is|isolated|lazy|left|let|lowerThan|mutating|none|nonisolated|nonmutating|open|operator|optional|override|postfix|precedencegroup|prefix|private|protocol|public|repeat|required|rethrows|return|right|safe|self|set|some|static|struct|subscript|super|switch|throw|throws|try|typealias|unowned|unsafe|var|weak|where|while|willSet)\b/,boolean:/\b(?:false|true)\b/,nil:{pattern:/\bnil\b/,alias:"constant"},"short-argument":/\$\d+\b/,omit:{pattern:/\b_\b/,alias:"keyword"},number:/\b(?:[\d_]+(?:\.[\de_]+)?|0x[a-f0-9_]+(?:\.[a-f0-9p_]+)?|0b[01_]+|0o[0-7_]+)\b/i,"class-name":/\b[A-Z](?:[A-Z_\d]*[a-z]\w*)?\b/,function:/\b[a-z_]\w*(?=\s*\()/i,constant:/\b(?:[A-Z_]{2,}|k[A-Z][A-Za-z_]+)\b/,operator:/[-+*/%=!<>&|^~?]+|\.[.\-+*/%=!<>&|^~?]+/,punctuation:/[{}[\]();,.:\\]/},X.languages.swift["string-literal"].forEach((function(e){e.inside.interpolation.inside=X.languages.swift})),function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(X),X.languages.c=X.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),X.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),X.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},X.languages.c.string],char:X.languages.c.char,comment:X.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:X.languages.c}}}}),X.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete X.languages.c.boolean,X.languages.objectivec=X.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<<?=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete X.languages.objectivec["class-name"],X.languages.objc=X.languages.objectivec,X.languages.reason=X.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),X.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete X.languages.reason.function,function(e){for(var t=/\/\*(?:[^*/]|\*(?!\/)|\/(?!\*)|<self>)*\*\//.source,n=0;n<2;n++)t=t.replace(/<self>/g,(function(){return t}));t=t.replace(/<self>/g,(function(){return/[^\s\S]/.source})),e.languages.rust={comment:[{pattern:RegExp(/(^|[^\\])/.source+t),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<<?=?|>>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(X),X.languages.go=X.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),X.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete X.languages.go["class-name"],function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!<keyword>)\w+(?:\s*\.\s*\w+)*\b/.source.replace(/<keyword>/g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!<keyword>)\w+/.source.replace(/<keyword>/g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/<mod-name>(?:\s*:\s*<mod-name>)?|:\s*<mod-name>/.source.replace(/<mod-name>/g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(X),X.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},X.languages.python["string-interpolation"].inside.interpolation.inside.rest=X.languages.python,X.languages.py=X.languages.python;((e,t)=>{for(var n in t)f(e,n,{get:t[n],enumerable:!0})})({},{dracula:()=>C,duotoneDark:()=>T,duotoneLight:()=>A,github:()=>R,jettwaveDark:()=>$,jettwaveLight:()=>H,nightOwl:()=>P,nightOwlLight:()=>N,oceanicNext:()=>D,okaidia:()=>I,oneDark:()=>G,oneLight:()=>V,palenight:()=>M,shadesOfPurple:()=>F,synthwave84:()=>z,ultramin:()=>B,vsDark:()=>q,vsLight:()=>U});var C={plain:{color:"#F8F8F2",backgroundColor:"#282A36"},styles:[{types:["prolog","constant","builtin"],style:{color:"rgb(189, 147, 249)"}},{types:["inserted","function"],style:{color:"rgb(80, 250, 123)"}},{types:["deleted"],style:{color:"rgb(255, 85, 85)"}},{types:["changed"],style:{color:"rgb(255, 184, 108)"}},{types:["punctuation","symbol"],style:{color:"rgb(248, 248, 242)"}},{types:["string","char","tag","selector"],style:{color:"rgb(255, 121, 198)"}},{types:["keyword","variable"],style:{color:"rgb(189, 147, 249)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(98, 114, 164)"}},{types:["attr-name"],style:{color:"rgb(241, 250, 140)"}}]},T={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]},A={plain:{backgroundColor:"#faf8f5",color:"#728fcb"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#b6ad9a"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#063289"}},{types:["property","function"],style:{color:"#b29762"}},{types:["tag-id","selector","atrule-id"],style:{color:"#2d2006"}},{types:["attr-name"],style:{color:"#896724"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule"],style:{color:"#728fcb"}},{types:["placeholder","variable"],style:{color:"#93abdc"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#896724"}}]},R={plain:{color:"#393A34",backgroundColor:"#f6f8fa"},styles:[{types:["comment","prolog","doctype","cdata"],style:{color:"#999988",fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}},{types:["string","attr-value"],style:{color:"#e3116c"}},{types:["punctuation","operator"],style:{color:"#393A34"}},{types:["entity","url","symbol","number","boolean","variable","constant","property","regex","inserted"],style:{color:"#36acaa"}},{types:["atrule","keyword","attr-name","selector"],style:{color:"#00a4db"}},{types:["function","deleted","tag"],style:{color:"#d73a49"}},{types:["function-variable"],style:{color:"#6f42c1"}},{types:["tag","selector","keyword"],style:{color:"#00009f"}}]},P={plain:{color:"#d6deeb",backgroundColor:"#011627"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(99, 119, 119)",fontStyle:"italic"}},{types:["string","url"],style:{color:"rgb(173, 219, 103)"}},{types:["variable"],style:{color:"rgb(214, 222, 235)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation"],style:{color:"rgb(199, 146, 234)"}},{types:["selector","doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(255, 203, 139)"}},{types:["tag","operator","keyword"],style:{color:"rgb(127, 219, 202)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["property"],style:{color:"rgb(128, 203, 196)"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}}]},N={plain:{color:"#403f53",backgroundColor:"#FBFBFB"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)",fontStyle:"italic"}},{types:["inserted","attr-name"],style:{color:"rgb(72, 118, 214)",fontStyle:"italic"}},{types:["comment"],style:{color:"rgb(152, 159, 177)",fontStyle:"italic"}},{types:["string","builtin","char","constant","url"],style:{color:"rgb(72, 118, 214)"}},{types:["variable"],style:{color:"rgb(201, 103, 101)"}},{types:["number"],style:{color:"rgb(170, 9, 130)"}},{types:["punctuation"],style:{color:"rgb(153, 76, 195)"}},{types:["function","selector","doctype"],style:{color:"rgb(153, 76, 195)",fontStyle:"italic"}},{types:["class-name"],style:{color:"rgb(17, 17, 17)"}},{types:["tag"],style:{color:"rgb(153, 76, 195)"}},{types:["operator","property","keyword","namespace"],style:{color:"rgb(12, 150, 155)"}},{types:["boolean"],style:{color:"rgb(188, 84, 84)"}}]},L="#c5a5c5",O="#8dc891",D={plain:{backgroundColor:"#282c34",color:"#ffffff"},styles:[{types:["attr-name"],style:{color:L}},{types:["attr-value"],style:{color:O}},{types:["comment","block-comment","prolog","doctype","cdata","shebang"],style:{color:"#999999"}},{types:["property","number","function-name","constant","symbol","deleted"],style:{color:"#5a9bcf"}},{types:["boolean"],style:{color:"#ff8b50"}},{types:["tag"],style:{color:"#fc929e"}},{types:["string"],style:{color:O}},{types:["punctuation"],style:{color:O}},{types:["selector","char","builtin","inserted"],style:{color:"#D8DEE9"}},{types:["function"],style:{color:"#79b6f2"}},{types:["operator","entity","url","variable"],style:{color:"#d7deea"}},{types:["keyword"],style:{color:L}},{types:["atrule","class-name"],style:{color:"#FAC863"}},{types:["important"],style:{fontWeight:"400"}},{types:["bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["namespace"],style:{opacity:.7}}]},I={plain:{color:"#f8f8f2",backgroundColor:"#272822"},styles:[{types:["changed"],style:{color:"rgb(162, 191, 252)",fontStyle:"italic"}},{types:["deleted"],style:{color:"#f92672",fontStyle:"italic"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)",fontStyle:"italic"}},{types:["comment"],style:{color:"#8292a2",fontStyle:"italic"}},{types:["string","url"],style:{color:"#a6e22e"}},{types:["variable"],style:{color:"#f8f8f2"}},{types:["number"],style:{color:"#ae81ff"}},{types:["builtin","char","constant","function","class-name"],style:{color:"#e6db74"}},{types:["punctuation"],style:{color:"#f8f8f2"}},{types:["selector","doctype"],style:{color:"#a6e22e",fontStyle:"italic"}},{types:["tag","operator","keyword"],style:{color:"#66d9ef"}},{types:["boolean"],style:{color:"#ae81ff"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)",opacity:.7}},{types:["tag","property"],style:{color:"#f92672"}},{types:["attr-name"],style:{color:"#a6e22e !important"}},{types:["doctype"],style:{color:"#8292a2"}},{types:["rule"],style:{color:"#e6db74"}}]},M={plain:{color:"#bfc7d5",backgroundColor:"#292d3e"},styles:[{types:["comment"],style:{color:"rgb(105, 112, 152)",fontStyle:"italic"}},{types:["string","inserted"],style:{color:"rgb(195, 232, 141)"}},{types:["number"],style:{color:"rgb(247, 140, 108)"}},{types:["builtin","char","constant","function"],style:{color:"rgb(130, 170, 255)"}},{types:["punctuation","selector"],style:{color:"rgb(199, 146, 234)"}},{types:["variable"],style:{color:"rgb(191, 199, 213)"}},{types:["class-name","attr-name"],style:{color:"rgb(255, 203, 107)"}},{types:["tag","deleted"],style:{color:"rgb(255, 85, 114)"}},{types:["operator"],style:{color:"rgb(137, 221, 255)"}},{types:["boolean"],style:{color:"rgb(255, 88, 116)"}},{types:["keyword"],style:{fontStyle:"italic"}},{types:["doctype"],style:{color:"rgb(199, 146, 234)",fontStyle:"italic"}},{types:["namespace"],style:{color:"rgb(178, 204, 214)"}},{types:["url"],style:{color:"rgb(221, 221, 221)"}}]},F={plain:{color:"#9EFEFF",backgroundColor:"#2D2A55"},styles:[{types:["changed"],style:{color:"rgb(255, 238, 128)"}},{types:["deleted"],style:{color:"rgba(239, 83, 80, 0.56)"}},{types:["inserted"],style:{color:"rgb(173, 219, 103)"}},{types:["comment"],style:{color:"rgb(179, 98, 255)",fontStyle:"italic"}},{types:["punctuation"],style:{color:"rgb(255, 255, 255)"}},{types:["constant"],style:{color:"rgb(255, 98, 140)"}},{types:["string","url"],style:{color:"rgb(165, 255, 144)"}},{types:["variable"],style:{color:"rgb(255, 238, 128)"}},{types:["number","boolean"],style:{color:"rgb(255, 98, 140)"}},{types:["attr-name"],style:{color:"rgb(255, 180, 84)"}},{types:["keyword","operator","property","namespace","tag","selector","doctype"],style:{color:"rgb(255, 157, 0)"}},{types:["builtin","char","constant","function","class-name"],style:{color:"rgb(250, 208, 0)"}}]},z={plain:{backgroundColor:"linear-gradient(to bottom, #2a2139 75%, #34294f)",backgroundImage:"#34294f",color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"},styles:[{types:["comment","block-comment","prolog","doctype","cdata"],style:{color:"#495495",fontStyle:"italic"}},{types:["punctuation"],style:{color:"#ccc"}},{types:["tag","attr-name","namespace","number","unit","hexcode","deleted"],style:{color:"#e2777a"}},{types:["property","selector"],style:{color:"#72f1b8",textShadow:"0 0 2px #100c0f, 0 0 10px #257c5575, 0 0 35px #21272475"}},{types:["function-name"],style:{color:"#6196cc"}},{types:["boolean","selector-id","function"],style:{color:"#fdfdfd",textShadow:"0 0 2px #001716, 0 0 3px #03edf975, 0 0 5px #03edf975, 0 0 8px #03edf975"}},{types:["class-name","maybe-class-name","builtin"],style:{color:"#fff5f6",textShadow:"0 0 2px #000, 0 0 10px #fc1f2c75, 0 0 5px #fc1f2c75, 0 0 25px #fc1f2c75"}},{types:["constant","symbol"],style:{color:"#f92aad",textShadow:"0 0 2px #100c0f, 0 0 5px #dc078e33, 0 0 10px #fff3"}},{types:["important","atrule","keyword","selector-class"],style:{color:"#f4eee4",textShadow:"0 0 2px #393a33, 0 0 8px #f39f0575, 0 0 2px #f39f0575"}},{types:["string","char","attr-value","regex","variable"],style:{color:"#f87c32"}},{types:["parameter"],style:{fontStyle:"italic"}},{types:["entity","url"],style:{color:"#67cdcc"}},{types:["operator"],style:{color:"ffffffee"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["entity"],style:{cursor:"help"}},{types:["inserted"],style:{color:"green"}}]},B={plain:{color:"#282a2e",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(197, 200, 198)"}},{types:["string","number","builtin","variable"],style:{color:"rgb(150, 152, 150)"}},{types:["class-name","function","tag","attr-name"],style:{color:"rgb(40, 42, 46)"}}]},q={plain:{color:"#9CDCFE",backgroundColor:"#1E1E1E"},styles:[{types:["prolog"],style:{color:"rgb(0, 0, 128)"}},{types:["comment"],style:{color:"rgb(106, 153, 85)"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"rgb(86, 156, 214)"}},{types:["number","inserted"],style:{color:"rgb(181, 206, 168)"}},{types:["constant"],style:{color:"rgb(100, 102, 149)"}},{types:["attr-name","variable"],style:{color:"rgb(156, 220, 254)"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"rgb(206, 145, 120)"}},{types:["selector"],style:{color:"rgb(215, 186, 125)"}},{types:["tag"],style:{color:"rgb(78, 201, 176)"}},{types:["tag"],languages:["markup"],style:{color:"rgb(86, 156, 214)"}},{types:["punctuation","operator"],style:{color:"rgb(212, 212, 212)"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"rgb(220, 220, 170)"}},{types:["class-name"],style:{color:"rgb(78, 201, 176)"}},{types:["char"],style:{color:"rgb(209, 105, 105)"}}]},U={plain:{color:"#000000",backgroundColor:"#ffffff"},styles:[{types:["comment"],style:{color:"rgb(0, 128, 0)"}},{types:["builtin"],style:{color:"rgb(0, 112, 193)"}},{types:["number","variable","inserted"],style:{color:"rgb(9, 134, 88)"}},{types:["operator"],style:{color:"rgb(0, 0, 0)"}},{types:["constant","char"],style:{color:"rgb(129, 31, 63)"}},{types:["tag"],style:{color:"rgb(128, 0, 0)"}},{types:["attr-name"],style:{color:"rgb(255, 0, 0)"}},{types:["deleted","string"],style:{color:"rgb(163, 21, 21)"}},{types:["changed","punctuation"],style:{color:"rgb(4, 81, 165)"}},{types:["function","keyword"],style:{color:"rgb(0, 0, 255)"}},{types:["class-name"],style:{color:"rgb(38, 127, 153)"}}]},$={plain:{color:"#f8fafc",backgroundColor:"#011627"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#569CD6"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#f8fafc"}},{types:["attr-name","variable"],style:{color:"#9CDCFE"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#cbd5e1"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#D4D4D4"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#7dd3fc"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},H={plain:{color:"#0f172a",backgroundColor:"#f1f5f9"},styles:[{types:["prolog"],style:{color:"#000080"}},{types:["comment"],style:{color:"#6A9955"}},{types:["builtin","changed","keyword","interpolation-punctuation"],style:{color:"#0c4a6e"}},{types:["number","inserted"],style:{color:"#B5CEA8"}},{types:["constant"],style:{color:"#0f172a"}},{types:["attr-name","variable"],style:{color:"#0c4a6e"}},{types:["deleted","string","attr-value","template-punctuation"],style:{color:"#64748b"}},{types:["selector"],style:{color:"#D7BA7D"}},{types:["tag"],style:{color:"#0ea5e9"}},{types:["tag"],languages:["markup"],style:{color:"#0ea5e9"}},{types:["punctuation","operator"],style:{color:"#475569"}},{types:["punctuation"],languages:["markup"],style:{color:"#808080"}},{types:["function"],style:{color:"#0e7490"}},{types:["class-name"],style:{color:"#0ea5e9"}},{types:["char"],style:{color:"#D16969"}}]},G={plain:{backgroundColor:"hsl(220, 13%, 18%)",color:"hsl(220, 14%, 71%)",textShadow:"0 1px rgba(0, 0, 0, 0.3)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(220, 10%, 40%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(220, 14%, 71%)"}},{types:["attr-name","class-name","maybe-class-name","boolean","constant","number","atrule"],style:{color:"hsl(29, 54%, 61%)"}},{types:["keyword"],style:{color:"hsl(286, 60%, 67%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(355, 65%, 65%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value"],style:{color:"hsl(95, 38%, 62%)"}},{types:["variable","operator","function"],style:{color:"hsl(207, 82%, 66%)"}},{types:["url"],style:{color:"hsl(187, 47%, 55%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(220, 14%, 71%)"}}]},V={plain:{backgroundColor:"hsl(230, 1%, 98%)",color:"hsl(230, 8%, 24%)"},styles:[{types:["comment","prolog","cdata"],style:{color:"hsl(230, 4%, 64%)"}},{types:["doctype","punctuation","entity"],style:{color:"hsl(230, 8%, 24%)"}},{types:["attr-name","class-name","boolean","constant","number","atrule"],style:{color:"hsl(35, 99%, 36%)"}},{types:["keyword"],style:{color:"hsl(301, 63%, 40%)"}},{types:["property","tag","symbol","deleted","important"],style:{color:"hsl(5, 74%, 59%)"}},{types:["selector","string","char","builtin","inserted","regex","attr-value","punctuation"],style:{color:"hsl(119, 34%, 47%)"}},{types:["variable","operator","function"],style:{color:"hsl(221, 87%, 60%)"}},{types:["url"],style:{color:"hsl(198, 99%, 37%)"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"hsl(230, 8%, 24%)"}}]},W=(e,t)=>{const{plain:n}=e,r=e.styles.reduce(((e,n)=>{const{languages:r,style:o}=n;return r&&!r.includes(t)||n.types.forEach((t=>{const n=x(x({},e[t]),o);e[t]=n})),e}),{});return r.root=n,r.plain=S(x({},n),{backgroundColor:void 0}),r},K=/\r\n|\r|\n/,Q=e=>{0===e.length?e.push({types:["plain"],content:"\n",empty:!0}):1===e.length&&""===e[0].content&&(e[0].content="\n",e[0].empty=!0)},Y=(e,t)=>{const n=e.length;return n>0&&e[n-1]===t?e:e.concat(t)},Z=e=>{const t=[[]],n=[e],r=[0],o=[e.length];let s=0,a=0,i=[];const c=[i];for(;a>-1;){for(;(s=r[a]++)<o[a];){let e,l=t[a];const d=n[a][s];if("string"==typeof d?(l=a>0?l:["plain"],e=d):(l=Y(l,d.type),d.alias&&(l=Y(l,d.alias)),e=d.content),"string"!=typeof e){a++,t.push(l),n.push(e),r.push(0),o.push(e.length);continue}const p=e.split(K),u=p.length;i.push({types:l,content:p[0]});for(let t=1;t<u;t++)Q(i),c.push(i=[]),i.push({types:l,content:p[t]})}a--,t.pop(),n.pop(),r.pop(),o.pop()}return Q(i),c},J=({children:e,language:t,code:n,theme:r,prism:o})=>{const s=t.toLowerCase(),a=((e,t)=>{const[n,r]=(0,d.useState)(W(t,e)),o=(0,d.useRef)(),s=(0,d.useRef)();return(0,d.useEffect)((()=>{t===o.current&&e===s.current||(o.current=t,s.current=e,r(W(t,e)))}),[e,t]),n})(s,r),i=(e=>(0,d.useCallback)((t=>{var n=t,{className:r,style:o,line:s}=n,a=E(n,["className","style","line"]);const i=S(x({},a),{className:(0,p.A)("token-line",r)});return"object"==typeof e&&"plain"in e&&(i.style=e.plain),"object"==typeof o&&(i.style=x(x({},i.style||{}),o)),i}),[e]))(a),c=(e=>{const t=(0,d.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,d.useCallback)((e=>{var n=e,{token:r,className:o,style:s}=n,a=E(n,["token","className","style"]);const i=S(x({},a),{className:(0,p.A)("token",...r.types,o),children:r.content,style:t(r)});return null!=s&&(i.style=x(x({},i.style||{}),s)),i}),[t])})(a),l=(({prism:e,code:t,grammar:n,language:r})=>{const o=(0,d.useRef)(e);return(0,d.useMemo)((()=>{if(null==n)return Z([t]);const e={code:t,grammar:n,language:r,tokens:[]};return o.current.hooks.run("before-tokenize",e),e.tokens=o.current.tokenize(t,n),o.current.hooks.run("after-tokenize",e),Z(e.tokens)}),[t,n,r])})({prism:o,language:s,code:n,grammar:o.languages[s]});return e({tokens:l,className:`prism-code language-${s}`,style:null!=a?a.root:{},getLineProps:i,getTokenProps:c})},ee=e=>(0,d.createElement)(J,S(x({},e),{prism:e.prism||X,theme:e.theme||q,code:e.code,language:e.language}))},11561:(e,t,n)=>{"use strict";n.d(t,{A:()=>s});var r=!0,o="Invariant failed";function s(e,t){if(!e){if(r)throw new Error(o);var n="function"==typeof t?t():t,s=n?"".concat(o,": ").concat(n):o;throw new Error(s)}}},31635:(e,t,n)=>{"use strict";n.r(t),n.d(t,{__addDisposableResource:()=>L,__assign:()=>s,__asyncDelegator:()=>E,__asyncGenerator:()=>S,__asyncValues:()=>j,__await:()=>x,__awaiter:()=>g,__classPrivateFieldGet:()=>R,__classPrivateFieldIn:()=>N,__classPrivateFieldSet:()=>P,__createBinding:()=>h,__decorate:()=>i,__disposeResources:()=>D,__esDecorate:()=>l,__exportStar:()=>b,__extends:()=>o,__generator:()=>m,__importDefault:()=>A,__importStar:()=>T,__makeTemplateObject:()=>X,__metadata:()=>f,__param:()=>c,__propKey:()=>p,__read:()=>y,__rest:()=>a,__runInitializers:()=>d,__setFunctionName:()=>u,__spread:()=>w,__spreadArray:()=>k,__spreadArrays:()=>_,__values:()=>v,default:()=>I});var r=function(e,t){return r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},r(e,t)};function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var s=function(){return s=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},s.apply(this,arguments)};function a(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function i(e,t,n,r){var o,s=arguments.length,a=s<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)a=Reflect.decorate(e,t,n,r);else for(var i=e.length-1;i>=0;i--)(o=e[i])&&(a=(s<3?o(a):s>3?o(t,n,a):o(t,n))||a);return s>3&&a&&Object.defineProperty(t,n,a),a}function c(e,t){return function(n,r){t(n,r,e)}}function l(e,t,n,r,o,s){function a(e){if(void 0!==e&&"function"!=typeof e)throw new TypeError("Function expected");return e}for(var i,c=r.kind,l="getter"===c?"get":"setter"===c?"set":"value",d=!t&&e?r.static?e:e.prototype:null,p=t||(d?Object.getOwnPropertyDescriptor(d,r.name):{}),u=!1,f=n.length-1;f>=0;f--){var g={};for(var m in r)g[m]="access"===m?{}:r[m];for(var m in r.access)g.access[m]=r.access[m];g.addInitializer=function(e){if(u)throw new TypeError("Cannot add initializers after decoration has completed");s.push(a(e||null))};var h=(0,n[f])("accessor"===c?{get:p.get,set:p.set}:p[l],g);if("accessor"===c){if(void 0===h)continue;if(null===h||"object"!=typeof h)throw new TypeError("Object expected");(i=a(h.get))&&(p.get=i),(i=a(h.set))&&(p.set=i),(i=a(h.init))&&o.unshift(i)}else(i=a(h))&&("field"===c?o.unshift(i):p[l]=i)}d&&Object.defineProperty(d,r.name,p),u=!0}function d(e,t,n){for(var r=arguments.length>2,o=0;o<t.length;o++)n=r?t[o].call(e,n):t[o].call(e);return r?n:void 0}function p(e){return"symbol"==typeof e?e:"".concat(e)}function u(e,t,n){return"symbol"==typeof t&&(t=t.description?"[".concat(t.description,"]"):""),Object.defineProperty(e,"name",{configurable:!0,value:n?"".concat(n," ",t):t})}function f(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}function g(e,t,n,r){return new(n||(n=Promise))((function(o,s){function a(e){try{c(r.next(e))}catch(t){s(t)}}function i(e){try{c(r.throw(e))}catch(t){s(t)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(a,i)}c((r=r.apply(e,t||[])).next())}))}function m(e,t){var n,r,o,s,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return s={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(s[Symbol.iterator]=function(){return this}),s;function i(i){return function(c){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;s&&(s=0,i[0]&&(a=0)),a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=a.trys,(o=o.length>0&&o[o.length-1])||6!==i[0]&&2!==i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(e,a)}catch(c){i=[6,c],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,c])}}}var h=Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]};function b(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||h(t,e,n)}function v(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function y(e,t){var n="function"==typeof Symbol&&e[Symbol.iterator];if(!n)return e;var r,o,s=n.call(e),a=[];try{for(;(void 0===t||t-- >0)&&!(r=s.next()).done;)a.push(r.value)}catch(i){o={error:i}}finally{try{r&&!r.done&&(n=s.return)&&n.call(s)}finally{if(o)throw o.error}}return a}function w(){for(var e=[],t=0;t<arguments.length;t++)e=e.concat(y(arguments[t]));return e}function _(){for(var e=0,t=0,n=arguments.length;t<n;t++)e+=arguments[t].length;var r=Array(e),o=0;for(t=0;t<n;t++)for(var s=arguments[t],a=0,i=s.length;a<i;a++,o++)r[o]=s[a];return r}function k(e,t,n){if(n||2===arguments.length)for(var r,o=0,s=t.length;o<s;o++)!r&&o in t||(r||(r=Array.prototype.slice.call(t,0,o)),r[o]=t[o]);return e.concat(r||Array.prototype.slice.call(t))}function x(e){return this instanceof x?(this.v=e,this):new x(e)}function S(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var r,o=n.apply(e,t||[]),s=[];return r={},a("next"),a("throw"),a("return",(function(e){return function(t){return Promise.resolve(t).then(e,l)}})),r[Symbol.asyncIterator]=function(){return this},r;function a(e,t){o[e]&&(r[e]=function(t){return new Promise((function(n,r){s.push([e,t,n,r])>1||i(e,t)}))},t&&(r[e]=t(r[e])))}function i(e,t){try{(n=o[e](t)).value instanceof x?Promise.resolve(n.value.v).then(c,l):d(s[0][2],n)}catch(r){d(s[0][3],r)}var n}function c(e){i("next",e)}function l(e){i("throw",e)}function d(e,t){e(t),s.shift(),s.length&&i(s[0][0],s[0][1])}}function E(e){var t,n;return t={},r("next"),r("throw",(function(e){throw e})),r("return"),t[Symbol.iterator]=function(){return this},t;function r(r,o){t[r]=e[r]?function(t){return(n=!n)?{value:x(e[r](t)),done:!1}:o?o(t):t}:o}}function j(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t,n=e[Symbol.asyncIterator];return n?n.call(e):(e=v(e),t={},r("next"),r("throw"),r("return"),t[Symbol.asyncIterator]=function(){return this},t);function r(n){t[n]=e[n]&&function(t){return new Promise((function(r,o){(function(e,t,n,r){Promise.resolve(r).then((function(t){e({value:t,done:n})}),t)})(r,o,(t=e[n](t)).done,t.value)}))}}}function X(e,t){return Object.defineProperty?Object.defineProperty(e,"raw",{value:t}):e.raw=t,e}var C=Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t};function T(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&h(t,e,n);return C(t,e),t}function A(e){return e&&e.__esModule?e:{default:e}}function R(e,t,n,r){if("a"===n&&!r)throw new TypeError("Private accessor was defined without a getter");if("function"==typeof t?e!==t||!r:!t.has(e))throw new TypeError("Cannot read private member from an object whose class did not declare it");return"m"===n?r:"a"===n?r.call(e):r?r.value:t.get(e)}function P(e,t,n,r,o){if("m"===r)throw new TypeError("Private method is not writable");if("a"===r&&!o)throw new TypeError("Private accessor was defined without a setter");if("function"==typeof t?e!==t||!o:!t.has(e))throw new TypeError("Cannot write private member to an object whose class did not declare it");return"a"===r?o.call(e,n):o?o.value=n:t.set(e,n),n}function N(e,t){if(null===t||"object"!=typeof t&&"function"!=typeof t)throw new TypeError("Cannot use 'in' operator on non-object");return"function"==typeof e?t===e:e.has(t)}function L(e,t,n){if(null!=t){if("object"!=typeof t&&"function"!=typeof t)throw new TypeError("Object expected.");var r,o;if(n){if(!Symbol.asyncDispose)throw new TypeError("Symbol.asyncDispose is not defined.");r=t[Symbol.asyncDispose]}if(void 0===r){if(!Symbol.dispose)throw new TypeError("Symbol.dispose is not defined.");r=t[Symbol.dispose],n&&(o=r)}if("function"!=typeof r)throw new TypeError("Object not disposable.");o&&(r=function(){try{o.call(this)}catch(e){return Promise.reject(e)}}),e.stack.push({value:t,dispose:r,async:n})}else n&&e.stack.push({async:!0});return t}var O="function"==typeof SuppressedError?SuppressedError:function(e,t,n){var r=new Error(n);return r.name="SuppressedError",r.error=e,r.suppressed=t,r};function D(e){function t(t){e.error=e.hasError?new O(t,e.error,"An error was suppressed during disposal."):t,e.hasError=!0}return function n(){for(;e.stack.length;){var r=e.stack.pop();try{var o=r.dispose&&r.dispose.call(r.value);if(r.async)return Promise.resolve(o).then(n,(function(e){return t(e),n()}))}catch(s){t(s)}}if(e.hasError)throw e.error}()}const I={__extends:o,__assign:s,__rest:a,__decorate:i,__param:c,__metadata:f,__awaiter:g,__generator:m,__createBinding:h,__exportStar:b,__values:v,__read:y,__spread:w,__spreadArrays:_,__spreadArray:k,__await:x,__asyncGenerator:S,__asyncDelegator:E,__asyncValues:j,__makeTemplateObject:X,__importStar:T,__importDefault:A,__classPrivateFieldGet:R,__classPrivateFieldSet:P,__classPrivateFieldIn:N,__addDisposableResource:L,__disposeResources:D}},22654:e=>{"use strict";e.exports={}},84054:e=>{"use strict";e.exports=JSON.parse('{"/blog/-834":{"__comp":"a6aa9e1f","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"},{"content":"98df448b"},{"content":"b1eae65b"},{"content":"80e6044e"},{"content":"b71ecf14"}],"__props":"08af526d"},"/blog/addressable-entity/-887":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"124873a8"},"/blog/archive/-1d9":{"__comp":"9e4087bc","__context":{"plugin":"36994c47"},"__props":"dbfc4782"},"/blog/authors/-347":{"__comp":"621db11d","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","__props":"dd04b75e"},"/blog/authors/alexanderlimonov/-e4c":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"8941358f"}],"sidebar":"814f3328","__props":"8833ab21"},"/blog/authors/dylanireland/-a3a":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"80e6044e"}],"sidebar":"814f3328","__props":"f1245771"},"/blog/authors/melpadden/-0d6":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"8941358f"},{"content":"98df448b"},{"content":"b1eae65b"},{"content":"80e6044e"}],"sidebar":"814f3328","__props":"baabe181"},"/blog/authors/sczembor/-8cb":{"__comp":"33fc5bb8","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"items":[{"content":"b1eae65b"},{"content":"b71ecf14"}],"sidebar":"814f3328","__props":"358cf6da"},"/blog/condor-fee-elimination/-f26":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"0bd3b317"},"/blog/condor-local-setup/-2aa":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"197196c4"},"/blog/condor-validator-rewards/-3b7":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"277b6be0"},"/blog/tags/-e17":{"__comp":"01a85c17","__context":{"plugin":"36994c47"},"sidebar":"814f3328","__props":"2063472f"},"/blog/tags/condor/-cf9":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"},{"content":"b1eae65b"},{"content":"80e6044e"},{"content":"b71ecf14"}],"__props":"c3308ba6"},"/blog/tags/docs-redux/-339":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"9ec4e3de"},"/blog/tags/features/-bc2":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"80e6044e"}],"__props":"5ce0f216"},"/blog/tags/hello/-8a7":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"33a9c3bd"},"/blog/tags/new-docs/-fdd":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"98df448b"}],"__props":"481163ce"},"/blog/tags/setup/-a7c":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"b71ecf14"}],"__props":"a72bcf22"},"/blog/tags/tokenomics/-9c1":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"80e6044e"}],"__props":"d48191b6"},"/blog/tags/validators/-87b":{"__comp":"6875c492","__context":{"plugin":"36994c47"},"sidebar":"814f3328","items":[{"content":"8941358f"}],"__props":"8de9f24f"},"/blog/welcome-docs-redux/-fc7":{"__comp":"ccc49370","__context":{"data":{"blogMetadata":"acecf23e"},"plugin":"36994c47"},"sidebar":"814f3328","content":"c377dc4a"},"/search/-21e":{"__comp":"1a4e3797","__context":{"plugin":"c141421f"}},"/-0c1":{"__comp":"5e95c892","__context":{"plugin":"aba21aa0"}},"/1.5.X/-6a4":{"__comp":"a7bd4aaa","__props":"d629d828"},"/1.5.X/-3ce":{"__comp":"a94703ab"},"/1.5.X/-1b3":{"__comp":"17896441","content":"baf71301"},"/1.5.X/concepts/-9f0":{"__comp":"17896441","content":"befad559"},"/1.5.X/concepts/accounts-and-keys/-eaa":{"__comp":"17896441","content":"40c07125"},"/1.5.X/concepts/callstack/-f4d":{"__comp":"17896441","content":"39ac5a41"},"/1.5.X/concepts/design/casper-design/-65f":{"__comp":"17896441","content":"26f7e8fd"},"/1.5.X/concepts/design/highway/-174":{"__comp":"17896441","content":"ce0e1dbb"},"/1.5.X/concepts/design/networking-protocol/-1fa":{"__comp":"17896441","content":"b687a817"},"/1.5.X/concepts/design/p2p/-955":{"__comp":"17896441","content":"90efbb16"},"/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/-366":{"__comp":"17896441","content":"883310e5"},"/1.5.X/concepts/dictionaries/-192":{"__comp":"17896441","content":"a03c4947"},"/1.5.X/concepts/economics/concepts/-4cb":{"__comp":"17896441","content":"7effaf45"},"/1.5.X/concepts/economics/consensus/-016":{"__comp":"17896441","content":"34b086e1"},"/1.5.X/concepts/economics/delegation/-a09":{"__comp":"17896441","content":"38b4dbd3"},"/1.5.X/concepts/economics/gas-concepts/-60a":{"__comp":"17896441","content":"a80f26d4"},"/1.5.X/concepts/global-state/-47f":{"__comp":"17896441","content":"a4046515"},"/1.5.X/concepts/glossary/A/-391":{"__comp":"17896441","content":"603aca9e"},"/1.5.X/concepts/glossary/B/-ff4":{"__comp":"17896441","content":"3aa29420"},"/1.5.X/concepts/glossary/C/-680":{"__comp":"17896441","content":"bafead24"},"/1.5.X/concepts/glossary/D/-53a":{"__comp":"17896441","content":"7ade0b2a"},"/1.5.X/concepts/glossary/E/-0f3":{"__comp":"17896441","content":"43fd3112"},"/1.5.X/concepts/glossary/F/-af6":{"__comp":"17896441","content":"4e8b7bcc"},"/1.5.X/concepts/glossary/G/-78b":{"__comp":"17896441","content":"58718032"},"/1.5.X/concepts/glossary/H/-e95":{"__comp":"17896441","content":"4423d65b"},"/1.5.X/concepts/glossary/I/-7bf":{"__comp":"17896441","content":"6474e148"},"/1.5.X/concepts/glossary/J/-1cd":{"__comp":"17896441","content":"4804492c"},"/1.5.X/concepts/glossary/K/-267":{"__comp":"17896441","content":"31dbaea7"},"/1.5.X/concepts/glossary/L/-9e1":{"__comp":"17896441","content":"6fe126b9"},"/1.5.X/concepts/glossary/M/-bce":{"__comp":"17896441","content":"a4b0daeb"},"/1.5.X/concepts/glossary/N/-94a":{"__comp":"17896441","content":"12e95288"},"/1.5.X/concepts/glossary/O/-af6":{"__comp":"17896441","content":"c4561df8"},"/1.5.X/concepts/glossary/P/-4a5":{"__comp":"17896441","content":"028247bf"},"/1.5.X/concepts/glossary/Q/-b85":{"__comp":"17896441","content":"2bd0ed90"},"/1.5.X/concepts/glossary/R/-1c6":{"__comp":"17896441","content":"4ab63648"},"/1.5.X/concepts/glossary/S/-e2b":{"__comp":"17896441","content":"b3b8c5cb"},"/1.5.X/concepts/glossary/T/-dd8":{"__comp":"17896441","content":"6245c126"},"/1.5.X/concepts/glossary/U/-b39":{"__comp":"17896441","content":"d050b476"},"/1.5.X/concepts/glossary/V/-46a":{"__comp":"17896441","content":"52fa5650"},"/1.5.X/concepts/glossary/W/-71a":{"__comp":"17896441","content":"b67f60dc"},"/1.5.X/concepts/glossary/X/-c9c":{"__comp":"17896441","content":"bc4bfdf0"},"/1.5.X/concepts/glossary/Y/-b6d":{"__comp":"17896441","content":"9c6aa8d2"},"/1.5.X/concepts/glossary/Z/-43a":{"__comp":"17896441","content":"e238c115"},"/1.5.X/concepts/hash-types/-3a9":{"__comp":"17896441","content":"2cc4f81c"},"/1.5.X/concepts/intro-to-dapps/-d7f":{"__comp":"17896441","content":"ef2abd7e"},"/1.5.X/concepts/list-auth-keys/-069":{"__comp":"17896441","content":"f070a991"},"/1.5.X/concepts/serialization-standard/-a9a":{"__comp":"17896441","content":"d2039ef8"},"/1.5.X/concepts/smart-contracts/-b11":{"__comp":"17896441","content":"7e55f6e6"},"/1.5.X/counter-testnet/-7af":{"__comp":"17896441","content":"9afe1d3d"},"/1.5.X/counter/-aa5":{"__comp":"17896441","content":"9d275d72"},"/1.5.X/deploy-and-deploy-lifecycle/-599":{"__comp":"17896441","content":"931ecaed"},"/1.5.X/design/-41f":{"__comp":"17896441","content":"c74094f8"},"/1.5.X/developers/-0cd":{"__comp":"17896441","content":"c8e4da00"},"/1.5.X/developers/cli/-a34":{"__comp":"17896441","content":"521a6610"},"/1.5.X/developers/cli/calling-contracts/-06b":{"__comp":"17896441","content":"f1f89c2e"},"/1.5.X/developers/cli/delegate/-0ce":{"__comp":"17896441","content":"ea0474c4"},"/1.5.X/developers/cli/execution-error-codes/-7b6":{"__comp":"17896441","content":"241648bf"},"/1.5.X/developers/cli/installing-contracts/-e22":{"__comp":"17896441","content":"7c67ea25"},"/1.5.X/developers/cli/opcode-costs/-196":{"__comp":"17896441","content":"0753c93f"},"/1.5.X/developers/cli/querying-global-state/-1aa":{"__comp":"17896441","content":"4cc75cd6"},"/1.5.X/developers/cli/redelegate/-bd7":{"__comp":"17896441","content":"106a38e1"},"/1.5.X/developers/cli/sending-deploys/-b22":{"__comp":"17896441","content":"a434b528"},"/1.5.X/developers/cli/transfers/-25e":{"__comp":"17896441","content":"35a4f7b3"},"/1.5.X/developers/cli/transfers/direct-token-transfer/-b8e":{"__comp":"17896441","content":"8e1fd569"},"/1.5.X/developers/cli/transfers/multisig-deploy-transfer/-685":{"__comp":"17896441","content":"eaba5dd2"},"/1.5.X/developers/cli/transfers/verify-transfer/-558":{"__comp":"17896441","content":"5e9306ee"},"/1.5.X/developers/cli/undelegate/-a29":{"__comp":"17896441","content":"20f436ec"},"/1.5.X/developers/dapps/-56e":{"__comp":"17896441","content":"705e93ef"},"/1.5.X/developers/dapps/dapp/-6f9":{"__comp":"17896441","content":"e2975a84"},"/1.5.X/developers/dapps/monitor-and-consume-events/-8bb":{"__comp":"17896441","content":"3362155c"},"/1.5.X/developers/dapps/nctl-test/-19a":{"__comp":"17896441","content":"bb9db0dd"},"/1.5.X/developers/dapps/prerequisites/-1d2":{"__comp":"17896441","content":"ed267fba"},"/1.5.X/developers/dapps/sdk/client-library-usage/-416":{"__comp":"17896441","content":"b7708f1e"},"/1.5.X/developers/dapps/sdk/csharp-sdk/-417":{"__comp":"17896441","content":"0dea8207"},"/1.5.X/developers/dapps/sdk/go-sdk/-1ae":{"__comp":"17896441","content":"a3dc4ae2"},"/1.5.X/developers/dapps/sdk/python-sdk/-828":{"__comp":"17896441","content":"bfb3244a"},"/1.5.X/developers/dapps/sdk/script-sdk/-639":{"__comp":"17896441","content":"35808b61"},"/1.5.X/developers/dapps/setup-nctl/-341":{"__comp":"17896441","content":"af1112c6"},"/1.5.X/developers/dapps/signing-a-deploy/-5e8":{"__comp":"17896441","content":"5364a150"},"/1.5.X/developers/dapps/speculative-exec/-612":{"__comp":"17896441","content":"3ce1a06b"},"/1.5.X/developers/dapps/technology-stack/-8e6":{"__comp":"17896441","content":"0ac4e675"},"/1.5.X/developers/dapps/template-frontend/-106":{"__comp":"17896441","content":"5c3f78ae"},"/1.5.X/developers/dapps/uref-security/-511":{"__comp":"17896441","content":"d477c291"},"/1.5.X/developers/essential-crates/-ab9":{"__comp":"17896441","content":"55568807"},"/1.5.X/developers/json-rpc/-fdb":{"__comp":"17896441","content":"aee0fe92"},"/1.5.X/developers/json-rpc/errors/-79a":{"__comp":"17896441","content":"23e022aa"},"/1.5.X/developers/json-rpc/guidance/-387":{"__comp":"17896441","content":"7cf62e8d"},"/1.5.X/developers/json-rpc/json-rpc-informational/-fb7":{"__comp":"17896441","content":"ac361b55"},"/1.5.X/developers/json-rpc/json-rpc-pos/-6c1":{"__comp":"17896441","content":"03c6d9c7"},"/1.5.X/developers/json-rpc/json-rpc-transactional/-c4f":{"__comp":"17896441","content":"1b0eecbc"},"/1.5.X/developers/json-rpc/minimal-compliance/-e6b":{"__comp":"17896441","content":"480fa8f7"},"/1.5.X/developers/json-rpc/types_chain/-28d":{"__comp":"17896441","content":"ad7eda35"},"/1.5.X/developers/json-rpc/types_cl/-85a":{"__comp":"17896441","content":"202767e6"},"/1.5.X/developers/prerequisites/-b66":{"__comp":"17896441","content":"212aab5d"},"/1.5.X/developers/writing-onchain-code/assembly-script/-56e":{"__comp":"17896441","content":"7ce4a62a"},"/1.5.X/developers/writing-onchain-code/best-practices/-fe4":{"__comp":"17896441","content":"ca7245df"},"/1.5.X/developers/writing-onchain-code/calling-contracts/-500":{"__comp":"17896441","content":"727f767d"},"/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/-82a":{"__comp":"17896441","content":"a2874f18"},"/1.5.X/developers/writing-onchain-code/contract-vs-session/-ee5":{"__comp":"17896441","content":"53d095ec"},"/1.5.X/developers/writing-onchain-code/getting-started/-b3f":{"__comp":"17896441","content":"555a4473"},"/1.5.X/developers/writing-onchain-code/simple-contract/-97d":{"__comp":"17896441","content":"eb1cd7f2"},"/1.5.X/developers/writing-onchain-code/testing-contracts/-08d":{"__comp":"17896441","content":"65cd111b"},"/1.5.X/developers/writing-onchain-code/testing-session-code/-9b4":{"__comp":"17896441","content":"d279fdce"},"/1.5.X/developers/writing-onchain-code/upgrading-contracts/-e21":{"__comp":"17896441","content":"0c098c15"},"/1.5.X/developers/writing-onchain-code/writing-session-code/-887":{"__comp":"17896441","content":"c380abc4"},"/1.5.X/disclaimer/-956":{"__comp":"17896441","content":"3d90f760"},"/1.5.X/economics/-e26":{"__comp":"17896441","content":"ee7c1cc7"},"/1.5.X/glossary/-fa3":{"__comp":"17896441","content":"eb0d94ae"},"/1.5.X/operators/-c91":{"__comp":"17896441","content":"0904ce24"},"/1.5.X/operators/becoming-a-validator/-f58":{"__comp":"17896441","content":"c9db186d"},"/1.5.X/operators/becoming-a-validator/bonding/-4d7":{"__comp":"17896441","content":"5052751d"},"/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/-92f":{"__comp":"17896441","content":"3a9d2720"},"/1.5.X/operators/becoming-a-validator/recovering/-37b":{"__comp":"17896441","content":"4e4df367"},"/1.5.X/operators/becoming-a-validator/unbonding/-110":{"__comp":"17896441","content":"bd7d26b2"},"/1.5.X/operators/maintenance/-8c1":{"__comp":"17896441","content":"3b86d751"},"/1.5.X/operators/maintenance/archiving-and-restoring/-976":{"__comp":"17896441","content":"9acc619b"},"/1.5.X/operators/maintenance/moving-node/-b15":{"__comp":"17896441","content":"168da062"},"/1.5.X/operators/setup-network/-772":{"__comp":"17896441","content":"8d265689"},"/1.5.X/operators/setup-network/chain-spec/-5d5":{"__comp":"17896441","content":"40078125"},"/1.5.X/operators/setup-network/create-private/-496":{"__comp":"17896441","content":"5109d3ad"},"/1.5.X/operators/setup-network/genesis/-410":{"__comp":"17896441","content":"fef6ab33"},"/1.5.X/operators/setup-network/staging-files-for-new-network/-1cd":{"__comp":"17896441","content":"772d3db3"},"/1.5.X/operators/setup/-557":{"__comp":"17896441","content":"dd908370"},"/1.5.X/operators/setup/basic-node-configuration/-5d2":{"__comp":"17896441","content":"5c07109c"},"/1.5.X/operators/setup/fast-sync/-bb1":{"__comp":"17896441","content":"d94d6bbe"},"/1.5.X/operators/setup/hardware/-4b9":{"__comp":"17896441","content":"d3ef4614"},"/1.5.X/operators/setup/install-node/-b59":{"__comp":"17896441","content":"340c2365"},"/1.5.X/operators/setup/joining/-0b4":{"__comp":"17896441","content":"738a6ad4"},"/1.5.X/operators/setup/node-endpoints/-00e":{"__comp":"17896441","content":"a40a2cf8"},"/1.5.X/operators/setup/non-root-user/-60b":{"__comp":"17896441","content":"79474bae"},"/1.5.X/operators/setup/open-files/-5f3":{"__comp":"17896441","content":"aefd42fa"},"/1.5.X/operators/setup/upgrade/-be0":{"__comp":"17896441","content":"72c6e609"},"/1.5.X/resources/-581":{"__comp":"17896441","content":"2c04116d"},"/1.5.X/resources/advanced/list-auth-keys-tutorial/-8d4":{"__comp":"17896441","content":"26a33332"},"/1.5.X/resources/advanced/multi-sig/-e36":{"__comp":"17896441","content":"9ee7887a"},"/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/-f41":{"__comp":"17896441","content":"e3f9a068"},"/1.5.X/resources/advanced/multi-sig/other-scenarios/-2c5":{"__comp":"17896441","content":"ebb9a3ce"},"/1.5.X/resources/beginner/counter-testnet/commands/-d06":{"__comp":"17896441","content":"41eb5a6a"},"/1.5.X/resources/beginner/counter-testnet/overview/-d67":{"__comp":"17896441","content":"a4cd78b5"},"/1.5.X/resources/beginner/counter-testnet/walkthrough/-74f":{"__comp":"17896441","content":"dc1c4417"},"/1.5.X/resources/beginner/counter/commands/-156":{"__comp":"17896441","content":"c691959f"},"/1.5.X/resources/beginner/counter/overview/-e03":{"__comp":"17896441","content":"df5bc763"},"/1.5.X/resources/beginner/counter/walkthrough/-451":{"__comp":"17896441","content":"3fe76c6c"},"/1.5.X/resources/build-on-casper/casper-open-source-software/-c75":{"__comp":"17896441","content":"f71fe95d"},"/1.5.X/resources/build-on-casper/introduction/-9f0":{"__comp":"17896441","content":"709dfa47"},"/1.5.X/resources/condor-for-exchanges/-59c":{"__comp":"17896441","content":"e2f5312b"},"/1.5.X/resources/moving-to-casper/-594":{"__comp":"17896441","content":"43a834ef"},"/1.5.X/resources/quick-start/-a34":{"__comp":"17896441","content":"4e015808"},"/1.5.X/resources/tokens/-98c":{"__comp":"17896441","content":"1871ac35"},"/1.5.X/resources/tokens/cep18/full-tutorial/-ab9":{"__comp":"17896441","content":"2b8e251b"},"/1.5.X/resources/tokens/cep18/query/-0b4":{"__comp":"17896441","content":"cbe09f13"},"/1.5.X/resources/tokens/cep18/quickstart-guide/-1fa":{"__comp":"17896441","content":"c37f176d"},"/1.5.X/resources/tokens/cep18/tests/-76b":{"__comp":"17896441","content":"3b749ca6"},"/1.5.X/resources/tokens/cep18/transfer/-fec":{"__comp":"17896441","content":"ef7672e3"},"/1.5.X/resources/tokens/cep78/introduction/-913":{"__comp":"17896441","content":"5d4e9672"},"/1.5.X/resources/tokens/cep78/js-tutorial/-a05":{"__comp":"17896441","content":"af050a36"},"/1.5.X/resources/tokens/cep78/modalities/-4e3":{"__comp":"17896441","content":"32dd135c"},"/1.5.X/resources/tokens/cep78/reverse-lookup/-c4f":{"__comp":"17896441","content":"eb5a6cc0"},"/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/-ccd":{"__comp":"17896441","content":"a35afcc3"},"/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/-399":{"__comp":"17896441","content":"533ebf6b"},"/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/-9f5":{"__comp":"17896441","content":"cf35294f"},"/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/-8d9":{"__comp":"17896441","content":"fd661beb"},"/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/-afc":{"__comp":"17896441","content":"897e9cb3"},"/1.5.X/resources/tutorials/advanced/-273":{"__comp":"17896441","content":"d7fae98e"},"/1.5.X/resources/tutorials/advanced/cross-contract/-f50":{"__comp":"17896441","content":"0791978c"},"/1.5.X/resources/tutorials/advanced/list-cspr/-1a8":{"__comp":"17896441","content":"60fa9972"},"/1.5.X/resources/tutorials/advanced/return-values-tutorial/-2df":{"__comp":"17896441","content":"abd56c27"},"/1.5.X/resources/tutorials/advanced/storage-workflow/-516":{"__comp":"17896441","content":"6043c3f4"},"/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/-56c":{"__comp":"17896441","content":"821dc1e3"},"/1.5.X/resources/tutorials/advanced/two-party-multi-sig/-261":{"__comp":"17896441","content":"eff21157"},"/1.5.X/resources/tutorials/beginner/-b26":{"__comp":"17896441","content":"72b43be8"},"/1.5.X/resources/tutorials/beginner/aws-node/-8f5":{"__comp":"17896441","content":"57f923a9"},"/1.5.X/resources/tutorials/beginner/cep18/-3c4":{"__comp":"17896441","content":"e4d870e1"},"/1.5.X/resources/tutorials/beginner/getting-started-tutorial/-f2b":{"__comp":"17896441","content":"77981a3a"},"/1.5.X/resources/tutorials/beginner/querying-network/-569":{"__comp":"17896441","content":"d220dcab"},"/1.5.X/resources/tutorials/beginner/upgrade-contract/-9ab":{"__comp":"17896441","content":"72cc2261"},"/1.5.X/runtime/-60c":{"__comp":"17896441","content":"56746dcb"},"/1.5.X/sdk/-d96":{"__comp":"17896441","content":"c9f0fdac"},"/1.5.X/staking/-a8d":{"__comp":"17896441","content":"21ae0e7e"},"/1.5.X/users/-d68":{"__comp":"17896441","content":"d13dc577"},"/1.5.X/users/block-explorer/-c3e":{"__comp":"17896441","content":"5b827590"},"/1.5.X/users/csprlive/-54f":{"__comp":"17896441","content":"a6efe0e1"},"/1.5.X/users/delegate-ui/-28d":{"__comp":"17896441","content":"72a89de8"},"/1.5.X/users/funding-from-exchanges/-78b":{"__comp":"17896441","content":"75de5623"},"/1.5.X/users/ledger/-dac":{"__comp":"17896441","content":"9b0d9b67"},"/1.5.X/users/ledger/ledger-cspr-live/-a78":{"__comp":"17896441","content":"ce3d5a4b"},"/1.5.X/users/ledger/ledger-live/-320":{"__comp":"17896441","content":"331badc5"},"/1.5.X/users/staking-ledger/-6d4":{"__comp":"17896441","content":"4832c6fe"},"/1.5.X/users/testnet-faucet/-65e":{"__comp":"17896441","content":"c10b8a9f"},"/1.5.X/users/token-transfer/-5a0":{"__comp":"17896441","content":"41905acb"},"/1.5.X/users/undelegate-ui/-21f":{"__comp":"17896441","content":"04f8200d"},"/1.5.X/workflow/ledger-setup/-388":{"__comp":"17896441","content":"3669623c"},"/1.5.X/writing-contracts/-5ba":{"__comp":"17896441","content":"3ac85609"},"/2.0.0/-bbd":{"__comp":"a7bd4aaa","__props":"72106d8f"},"/2.0.0/-028":{"__comp":"a94703ab"},"/2.0.0/-269":{"__comp":"17896441","content":"ed772d97"},"/2.0.0/concepts/-5e5":{"__comp":"17896441","content":"0b3fc8e9"},"/2.0.0/concepts/about/-60d":{"__comp":"17896441","content":"7feecbc1"},"/2.0.0/concepts/accounts-and-keys/-0bd":{"__comp":"17896441","content":"01be152e"},"/2.0.0/concepts/addressable-entity/-8be":{"__comp":"17896441","content":"7bf3b0fc"},"/2.0.0/concepts/callstack/-9a4":{"__comp":"17896441","content":"7366a28d"},"/2.0.0/concepts/design/casper-design/-c92":{"__comp":"17896441","content":"77395f9a"},"/2.0.0/concepts/design/consensus/-418":{"__comp":"17896441","content":"26ab9a7a"},"/2.0.0/concepts/design/highway/-fa0":{"__comp":"17896441","content":"57d593f0"},"/2.0.0/concepts/design/networking-protocol/-510":{"__comp":"17896441","content":"9a508619"},"/2.0.0/concepts/design/p2p/-a13":{"__comp":"17896441","content":"b70624a2"},"/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/-366":{"__comp":"17896441","content":"b8ef17b7"},"/2.0.0/concepts/design/rewards/-a13":{"__comp":"17896441","content":"ef726b40"},"/2.0.0/concepts/design/zug/-9a5":{"__comp":"17896441","content":"6bed00f2"},"/2.0.0/concepts/dictionaries/-045":{"__comp":"17896441","content":"d0616161"},"/2.0.0/concepts/economics/consensus/-d42":{"__comp":"17896441","content":"9b70ce79"},"/2.0.0/concepts/economics/dynamic-gas-pricing/-9b0":{"__comp":"17896441","content":"a9707311"},"/2.0.0/concepts/economics/fee-elimination/-2a4":{"__comp":"17896441","content":"f74078f7"},"/2.0.0/concepts/economics/gas-concepts/-c40":{"__comp":"17896441","content":"cd8c5c3b"},"/2.0.0/concepts/economics/staking/-1da":{"__comp":"17896441","content":"76839fc0"},"/2.0.0/concepts/global-state/-226":{"__comp":"17896441","content":"4cc44e19"},"/2.0.0/concepts/glossary/A/-510":{"__comp":"17896441","content":"d81ba6be"},"/2.0.0/concepts/glossary/B/-8a9":{"__comp":"17896441","content":"9dd9d4ea"},"/2.0.0/concepts/glossary/C/-a7e":{"__comp":"17896441","content":"3a19cb34"},"/2.0.0/concepts/glossary/D/-6fd":{"__comp":"17896441","content":"54fcde43"},"/2.0.0/concepts/glossary/E/-ccb":{"__comp":"17896441","content":"905c7445"},"/2.0.0/concepts/glossary/F/-501":{"__comp":"17896441","content":"52927c97"},"/2.0.0/concepts/glossary/G/-343":{"__comp":"17896441","content":"5db8b942"},"/2.0.0/concepts/glossary/H/-c5f":{"__comp":"17896441","content":"5eb62c95"},"/2.0.0/concepts/glossary/I/-ea0":{"__comp":"17896441","content":"631bdc93"},"/2.0.0/concepts/glossary/J/-21b":{"__comp":"17896441","content":"a833d846"},"/2.0.0/concepts/glossary/K/-b63":{"__comp":"17896441","content":"efd01d75"},"/2.0.0/concepts/glossary/L/-d8f":{"__comp":"17896441","content":"f69b951d"},"/2.0.0/concepts/glossary/M/-525":{"__comp":"17896441","content":"2fe2b30f"},"/2.0.0/concepts/glossary/N/-c39":{"__comp":"17896441","content":"01db17fe"},"/2.0.0/concepts/glossary/O/-6ca":{"__comp":"17896441","content":"5e5b712e"},"/2.0.0/concepts/glossary/P/-f0f":{"__comp":"17896441","content":"b415f00a"},"/2.0.0/concepts/glossary/Q/-7fa":{"__comp":"17896441","content":"5168ee15"},"/2.0.0/concepts/glossary/R/-57e":{"__comp":"17896441","content":"4ed7ac06"},"/2.0.0/concepts/glossary/S/-c51":{"__comp":"17896441","content":"95c53987"},"/2.0.0/concepts/glossary/T/-0f0":{"__comp":"17896441","content":"c00ffc57"},"/2.0.0/concepts/glossary/U/-e0f":{"__comp":"17896441","content":"38ff73e5"},"/2.0.0/concepts/glossary/V/-041":{"__comp":"17896441","content":"559dc838"},"/2.0.0/concepts/glossary/W/-764":{"__comp":"17896441","content":"7850177d"},"/2.0.0/concepts/glossary/X/-b00":{"__comp":"17896441","content":"50c21d96"},"/2.0.0/concepts/glossary/Y/-e85":{"__comp":"17896441","content":"5611a8f0"},"/2.0.0/concepts/glossary/Z/-30f":{"__comp":"17896441","content":"fb904585"},"/2.0.0/concepts/intro-to-dapps/-53d":{"__comp":"17896441","content":"56aa8058"},"/2.0.0/concepts/key-types/-df8":{"__comp":"17896441","content":"b8f04a6b"},"/2.0.0/concepts/list-auth-keys/-136":{"__comp":"17896441","content":"10dd5949"},"/2.0.0/concepts/serialization/-5be":{"__comp":"17896441","content":"f224ad82"},"/2.0.0/concepts/serialization/primitives/-a66":{"__comp":"17896441","content":"241f36ed"},"/2.0.0/concepts/serialization/structures/-65c":{"__comp":"17896441","content":"e7589c2a"},"/2.0.0/concepts/serialization/types/-0c5":{"__comp":"17896441","content":"61415b83"},"/2.0.0/concepts/smart-contracts/-aa4":{"__comp":"17896441","content":"cdd6a56c"},"/2.0.0/counter-testnet/-838":{"__comp":"17896441","content":"4732c0e2"},"/2.0.0/counter/-0e7":{"__comp":"17896441","content":"ca962d2e"},"/2.0.0/design/-be5":{"__comp":"17896441","content":"d8ae3676"},"/2.0.0/developers/-800":{"__comp":"17896441","content":"e5afa1a3"},"/2.0.0/developers/cli/-74f":{"__comp":"17896441","content":"285c66e7"},"/2.0.0/developers/cli/calling-contracts/-b66":{"__comp":"17896441","content":"372c0574"},"/2.0.0/developers/cli/delegate/-11a":{"__comp":"17896441","content":"3d9ade7d"},"/2.0.0/developers/cli/execution-error-codes/-a4e":{"__comp":"17896441","content":"0b20c33e"},"/2.0.0/developers/cli/installing-contracts/-6dc":{"__comp":"17896441","content":"d02d0f51"},"/2.0.0/developers/cli/opcode-costs/-624":{"__comp":"17896441","content":"cf3029ea"},"/2.0.0/developers/cli/querying-global-state/-65a":{"__comp":"17896441","content":"e068c333"},"/2.0.0/developers/cli/redelegate/-9aa":{"__comp":"17896441","content":"f2a77c75"},"/2.0.0/developers/cli/sending-transactions/-8fb":{"__comp":"17896441","content":"5b38c543"},"/2.0.0/developers/cli/transfers/-ebd":{"__comp":"17896441","content":"8fcee16d"},"/2.0.0/developers/cli/transfers/direct-token-transfer/-f97":{"__comp":"17896441","content":"433fdaab"},"/2.0.0/developers/cli/transfers/multisig-deploy-transfer/-0d2":{"__comp":"17896441","content":"cb447cb9"},"/2.0.0/developers/cli/transfers/verify-transfer/-04e":{"__comp":"17896441","content":"12984b65"},"/2.0.0/developers/cli/undelegate/-684":{"__comp":"17896441","content":"4d355c12"},"/2.0.0/developers/cli/verifying-contracts/-10a":{"__comp":"17896441","content":"09278318"},"/2.0.0/developers/dapps/-ccf":{"__comp":"17896441","content":"ad591877"},"/2.0.0/developers/dapps/dapp/-961":{"__comp":"17896441","content":"f2e157d0"},"/2.0.0/developers/dapps/monitor-and-consume-events/-812":{"__comp":"17896441","content":"ac9a16c0"},"/2.0.0/developers/dapps/nctl-test/-869":{"__comp":"17896441","content":"9cb749bd"},"/2.0.0/developers/dapps/prerequisites/-cdd":{"__comp":"17896441","content":"0fa7e001"},"/2.0.0/developers/dapps/sdk/client-library-usage/-cfc":{"__comp":"17896441","content":"3d262e04"},"/2.0.0/developers/dapps/sdk/csharp-sdk/-4b4":{"__comp":"17896441","content":"cacd3f19"},"/2.0.0/developers/dapps/sdk/go-sdk/-b42":{"__comp":"17896441","content":"10ab4195"},"/2.0.0/developers/dapps/sdk/python-sdk/-29b":{"__comp":"17896441","content":"acee0a96"},"/2.0.0/developers/dapps/sdk/script-sdk/-f4d":{"__comp":"17896441","content":"5f241059"},"/2.0.0/developers/dapps/setup-nctl/-b3b":{"__comp":"17896441","content":"ed3af4a0"},"/2.0.0/developers/dapps/signing-a-transaction/-bc5":{"__comp":"17896441","content":"862f9df3"},"/2.0.0/developers/dapps/speculative-exec/-86f":{"__comp":"17896441","content":"e939f825"},"/2.0.0/developers/dapps/technology-stack/-77a":{"__comp":"17896441","content":"962c96ee"},"/2.0.0/developers/dapps/template-frontend/-550":{"__comp":"17896441","content":"a3e473b3"},"/2.0.0/developers/dapps/uref-security/-226":{"__comp":"17896441","content":"a024ab51"},"/2.0.0/developers/essential-crates/-a16":{"__comp":"17896441","content":"de33ad21"},"/2.0.0/developers/json-rpc/-dd7":{"__comp":"17896441","content":"5496fb16"},"/2.0.0/developers/json-rpc/errors/-bff":{"__comp":"17896441","content":"bcd2587d"},"/2.0.0/developers/json-rpc/guidance/-eb1":{"__comp":"17896441","content":"f1a6c2e6"},"/2.0.0/developers/json-rpc/json-rpc-informational/-1ad":{"__comp":"17896441","content":"1cd8ca26"},"/2.0.0/developers/json-rpc/json-rpc-pos/-b71":{"__comp":"17896441","content":"a3c7ece8"},"/2.0.0/developers/json-rpc/json-rpc-transactional/-19f":{"__comp":"17896441","content":"6ceb2263"},"/2.0.0/developers/json-rpc/minimal-compliance/-576":{"__comp":"17896441","content":"947e950c"},"/2.0.0/developers/json-rpc/types_chain/-949":{"__comp":"17896441","content":"b0b03333"},"/2.0.0/developers/json-rpc/types_cl/-cd1":{"__comp":"17896441","content":"f5c04343"},"/2.0.0/developers/prerequisites/-54d":{"__comp":"17896441","content":"04a0dcd6"},"/2.0.0/developers/writing-onchain-code/assembly-script/-c62":{"__comp":"17896441","content":"98d1a471"},"/2.0.0/developers/writing-onchain-code/best-practices/-2b9":{"__comp":"17896441","content":"86ae953a"},"/2.0.0/developers/writing-onchain-code/calling-contracts/-aac":{"__comp":"17896441","content":"c0def98a"},"/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/-ff9":{"__comp":"17896441","content":"8768801e"},"/2.0.0/developers/writing-onchain-code/contract-vs-session/-2e1":{"__comp":"17896441","content":"473a077c"},"/2.0.0/developers/writing-onchain-code/emitting-contract-events/-642":{"__comp":"17896441","content":"b192e983"},"/2.0.0/developers/writing-onchain-code/factory-pattern/-63c":{"__comp":"17896441","content":"02627fb8"},"/2.0.0/developers/writing-onchain-code/getting-started/-8d6":{"__comp":"17896441","content":"18b84202"},"/2.0.0/developers/writing-onchain-code/simple-contract/-be0":{"__comp":"17896441","content":"86b0038a"},"/2.0.0/developers/writing-onchain-code/testing-contracts/-c60":{"__comp":"17896441","content":"31e8518f"},"/2.0.0/developers/writing-onchain-code/testing-session-code/-c7f":{"__comp":"17896441","content":"8dd9adb4"},"/2.0.0/developers/writing-onchain-code/upgrading-contracts/-b34":{"__comp":"17896441","content":"b7cc26e1"},"/2.0.0/developers/writing-onchain-code/writing-session-code/-30f":{"__comp":"17896441","content":"094b4aff"},"/2.0.0/disclaimer/-159":{"__comp":"17896441","content":"9a38f23f"},"/2.0.0/economics/-6f6":{"__comp":"17896441","content":"3c9a8a22"},"/2.0.0/glossary/-d6c":{"__comp":"17896441","content":"f6320c57"},"/2.0.0/operators/-7f8":{"__comp":"17896441","content":"3a98aaad"},"/2.0.0/operators/becoming-a-validator/-591":{"__comp":"17896441","content":"87867a42"},"/2.0.0/operators/becoming-a-validator/bonding/-d91":{"__comp":"17896441","content":"e2509bb6"},"/2.0.0/operators/becoming-a-validator/change-bid-public-key/-4e9":{"__comp":"17896441","content":"a2ea0fe7"},"/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/-5c5":{"__comp":"17896441","content":"90f2be13"},"/2.0.0/operators/becoming-a-validator/recovering/-dfe":{"__comp":"17896441","content":"0ae07240"},"/2.0.0/operators/becoming-a-validator/unbonding/-451":{"__comp":"17896441","content":"7ce91694"},"/2.0.0/operators/maintenance/-652":{"__comp":"17896441","content":"21d2c26c"},"/2.0.0/operators/maintenance/archiving-and-restoring/-f78":{"__comp":"17896441","content":"1966dde1"},"/2.0.0/operators/maintenance/moving-node/-cd8":{"__comp":"17896441","content":"f8743170"},"/2.0.0/operators/setup-network/-fce":{"__comp":"17896441","content":"96fcb421"},"/2.0.0/operators/setup-network/chain-spec/-064":{"__comp":"17896441","content":"eeb3740b"},"/2.0.0/operators/setup-network/create-private/-13a":{"__comp":"17896441","content":"017e616b"},"/2.0.0/operators/setup-network/genesis/-46e":{"__comp":"17896441","content":"ea921b39"},"/2.0.0/operators/setup-network/staging-files-for-new-network/-2af":{"__comp":"17896441","content":"3db2ed27"},"/2.0.0/operators/setup/-e68":{"__comp":"17896441","content":"c8eb2c38"},"/2.0.0/operators/setup/basic-node-configuration/-88d":{"__comp":"17896441","content":"8154f86c"},"/2.0.0/operators/setup/casper-sidecar/-44a":{"__comp":"17896441","content":"1e2c8091"},"/2.0.0/operators/setup/fast-sync/-5f7":{"__comp":"17896441","content":"5a6ba1cd"},"/2.0.0/operators/setup/hardware/-4a2":{"__comp":"17896441","content":"68730730"},"/2.0.0/operators/setup/install-node/-bb5":{"__comp":"17896441","content":"53dc618d"},"/2.0.0/operators/setup/joining/-f93":{"__comp":"17896441","content":"2a21571b"},"/2.0.0/operators/setup/node-endpoints/-d07":{"__comp":"17896441","content":"fd967833"},"/2.0.0/operators/setup/node-events/-24f":{"__comp":"17896441","content":"b70225e0"},"/2.0.0/operators/setup/non-root-user/-122":{"__comp":"17896441","content":"ac16ac20"},"/2.0.0/operators/setup/open-files/-b36":{"__comp":"17896441","content":"64bdcaf3"},"/2.0.0/operators/setup/upgrade/-eb8":{"__comp":"17896441","content":"c474c2b1"},"/2.0.0/resources/-2aa":{"__comp":"17896441","content":"77c92c8c"},"/2.0.0/resources/advanced/list-auth-keys-tutorial/-4e9":{"__comp":"17896441","content":"c45e62e7"},"/2.0.0/resources/advanced/multi-sig/-ed1":{"__comp":"17896441","content":"a6c56441"},"/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/-eb3":{"__comp":"17896441","content":"b9ffcd07"},"/2.0.0/resources/advanced/multi-sig/other-scenarios/-240":{"__comp":"17896441","content":"e605c6b3"},"/2.0.0/resources/beginner/counter-testnet/commands/-47e":{"__comp":"17896441","content":"d0c6c99a"},"/2.0.0/resources/beginner/counter-testnet/overview/-2c2":{"__comp":"17896441","content":"56fae639"},"/2.0.0/resources/beginner/counter-testnet/walkthrough/-385":{"__comp":"17896441","content":"4bf77031"},"/2.0.0/resources/beginner/counter/commands/-f18":{"__comp":"17896441","content":"64733a41"},"/2.0.0/resources/beginner/counter/overview/-809":{"__comp":"17896441","content":"c34be5c7"},"/2.0.0/resources/beginner/counter/walkthrough/-147":{"__comp":"17896441","content":"19b85f8d"},"/2.0.0/resources/build-on-casper/casper-open-source-software/-c9f":{"__comp":"17896441","content":"13f7cbc7"},"/2.0.0/resources/build-on-casper/introduction/-e41":{"__comp":"17896441","content":"c95e6d8d"},"/2.0.0/resources/changelog/-620":{"__comp":"17896441","content":"ef646837"},"/2.0.0/resources/moving-to-casper/-3a2":{"__comp":"17896441","content":"2ac03470"},"/2.0.0/resources/quick-start/-4bf":{"__comp":"17896441","content":"5c08a95a"},"/2.0.0/resources/tokens/-7b5":{"__comp":"17896441","content":"411a45a4"},"/2.0.0/resources/tokens/cep18/full-tutorial/-a48":{"__comp":"17896441","content":"576e11bb"},"/2.0.0/resources/tokens/cep18/query/-ee8":{"__comp":"17896441","content":"d8c709f8"},"/2.0.0/resources/tokens/cep18/quickstart-guide/-197":{"__comp":"17896441","content":"cad9fd36"},"/2.0.0/resources/tokens/cep18/tests/-1dc":{"__comp":"17896441","content":"8675f5af"},"/2.0.0/resources/tokens/cep18/transfer/-ff2":{"__comp":"17896441","content":"051b98e7"},"/2.0.0/resources/tokens/cep78/introduction/-0cb":{"__comp":"17896441","content":"b0e8b9d5"},"/2.0.0/resources/tokens/cep78/js-tutorial/-54b":{"__comp":"17896441","content":"cfcbd284"},"/2.0.0/resources/tokens/cep78/modalities/-e9f":{"__comp":"17896441","content":"396a697c"},"/2.0.0/resources/tokens/cep78/reverse-lookup/-ae0":{"__comp":"17896441","content":"ae5d26cf"},"/2.0.0/resources/tokens/using-casper-client/-1cf":{"__comp":"17896441","content":"4a522ab0"},"/2.0.0/resources/tutorials/advanced/-107":{"__comp":"17896441","content":"056155c0"},"/2.0.0/resources/tutorials/advanced/cross-contract/-303":{"__comp":"17896441","content":"dd93ee27"},"/2.0.0/resources/tutorials/advanced/list-cspr/-f1a":{"__comp":"17896441","content":"80510dbd"},"/2.0.0/resources/tutorials/advanced/return-values-tutorial/-1ef":{"__comp":"17896441","content":"e10cd13d"},"/2.0.0/resources/tutorials/advanced/storage-workflow/-0df":{"__comp":"17896441","content":"cc84b9e4"},"/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/-546":{"__comp":"17896441","content":"24433f15"},"/2.0.0/resources/tutorials/advanced/two-party-multi-sig/-cf3":{"__comp":"17896441","content":"8d90c7e3"},"/2.0.0/resources/tutorials/beginner/-dbf":{"__comp":"17896441","content":"56ffdb25"},"/2.0.0/resources/tutorials/beginner/aws-node/-867":{"__comp":"17896441","content":"a6957975"},"/2.0.0/resources/tutorials/beginner/cep18/-e69":{"__comp":"17896441","content":"c5f06d44"},"/2.0.0/resources/tutorials/beginner/getting-started-tutorial/-bbf":{"__comp":"17896441","content":"1b312e15"},"/2.0.0/resources/tutorials/beginner/querying-network/-7d3":{"__comp":"17896441","content":"a36dca7d"},"/2.0.0/resources/tutorials/beginner/upgrade-contract/-2b9":{"__comp":"17896441","content":"871da383"},"/2.0.0/runtime/-6c9":{"__comp":"17896441","content":"f203f57a"},"/2.0.0/sdk/-34a":{"__comp":"17896441","content":"ce6fe363"},"/2.0.0/transactions-and-transaction-lifecycle/-34d":{"__comp":"17896441","content":"42744730"},"/2.0.0/transactions/-a3e":{"__comp":"17896441","content":"52ab49a5"},"/2.0.0/users/-be6":{"__comp":"17896441","content":"a7e0ea76"},"/2.0.0/users/block-explorer/-733":{"__comp":"17896441","content":"280f0f40"},"/2.0.0/users/csprlive/-04a":{"__comp":"17896441","content":"387aabc2"},"/2.0.0/users/delegate-ui/-d92":{"__comp":"17896441","content":"175e85c1"},"/2.0.0/users/delegating/-379":{"__comp":"17896441","content":"46206018"},"/2.0.0/users/funding-from-exchanges/-ff7":{"__comp":"17896441","content":"b114f501"},"/2.0.0/users/ledger/-cfa":{"__comp":"17896441","content":"59b77803"},"/2.0.0/users/ledger/ledger-cspr-live/-9aa":{"__comp":"17896441","content":"76ea157b"},"/2.0.0/users/ledger/ledger-live/-56b":{"__comp":"17896441","content":"158765df"},"/2.0.0/users/staking-ledger/-e96":{"__comp":"17896441","content":"814e64cc"},"/2.0.0/users/testnet-faucet/-8bf":{"__comp":"17896441","content":"62569fa7"},"/2.0.0/users/token-transfer/-f77":{"__comp":"17896441","content":"b7a2b993"},"/2.0.0/users/undelegate-ui/-d21":{"__comp":"17896441","content":"00935d0c"},"/2.0.0/workflow/ledger-setup/-2cd":{"__comp":"17896441","content":"20e65df1"},"/2.0.0/writing-contracts/-908":{"__comp":"17896441","content":"4d4c05c4"},"/-d96":{"__comp":"a7bd4aaa","__props":"22dd74f7"},"/-bf8":{"__comp":"a94703ab"},"/concepts/-478":{"__comp":"17896441","content":"c2728190"},"/concepts/about/-690":{"__comp":"17896441","content":"b8c8445c"},"/concepts/accounts-and-keys/-31f":{"__comp":"17896441","content":"c10cfbfe"},"/concepts/addressable-entity/-546":{"__comp":"17896441","content":"3e796ac9"},"/concepts/callstack/-442":{"__comp":"17896441","content":"4db682c6"},"/concepts/design/casper-design/-37d":{"__comp":"17896441","content":"64959b1e"},"/concepts/design/consensus/-10b":{"__comp":"17896441","content":"e289ead3"},"/concepts/design/highway/-575":{"__comp":"17896441","content":"03aa8e23"},"/concepts/design/networking-protocol/-47d":{"__comp":"17896441","content":"65961da4"},"/concepts/design/p2p/-b2f":{"__comp":"17896441","content":"977c8faa"},"/concepts/design/reading-and-writing-to-the-blockchain/-4ae":{"__comp":"17896441","content":"bb037852"},"/concepts/design/rewards/-fb4":{"__comp":"17896441","content":"6318ac72"},"/concepts/design/zug/-119":{"__comp":"17896441","content":"e1e5af17"},"/concepts/dictionaries/-acb":{"__comp":"17896441","content":"85b8bb26"},"/concepts/economics/consensus/-7dc":{"__comp":"17896441","content":"a4f8fe7e"},"/concepts/economics/dynamic-gas-pricing/-6fb":{"__comp":"17896441","content":"a30e2bb0"},"/concepts/economics/fee-elimination/-8ef":{"__comp":"17896441","content":"6dcb5e16"},"/concepts/economics/gas-concepts/-776":{"__comp":"17896441","content":"79d896a3"},"/concepts/economics/staking/-e62":{"__comp":"17896441","content":"471ca6e4"},"/concepts/global-state/-af6":{"__comp":"17896441","content":"25f19435"},"/concepts/glossary/A/-005":{"__comp":"17896441","content":"6c606038"},"/concepts/glossary/B/-e82":{"__comp":"17896441","content":"afa6d836"},"/concepts/glossary/C/-d64":{"__comp":"17896441","content":"b15d29cb"},"/concepts/glossary/D/-99f":{"__comp":"17896441","content":"eacea541"},"/concepts/glossary/E/-779":{"__comp":"17896441","content":"38296185"},"/concepts/glossary/F/-491":{"__comp":"17896441","content":"a53bd891"},"/concepts/glossary/G/-6a1":{"__comp":"17896441","content":"d7f9f727"},"/concepts/glossary/H/-d67":{"__comp":"17896441","content":"ab246697"},"/concepts/glossary/I/-e1a":{"__comp":"17896441","content":"5ed91ab5"},"/concepts/glossary/J/-179":{"__comp":"17896441","content":"14620e15"},"/concepts/glossary/K/-919":{"__comp":"17896441","content":"41e7d56e"},"/concepts/glossary/L/-78d":{"__comp":"17896441","content":"3efe71e8"},"/concepts/glossary/M/-792":{"__comp":"17896441","content":"650a8fc0"},"/concepts/glossary/N/-bcf":{"__comp":"17896441","content":"4fdb6df3"},"/concepts/glossary/O/-445":{"__comp":"17896441","content":"aa162190"},"/concepts/glossary/P/-3f8":{"__comp":"17896441","content":"362368d5"},"/concepts/glossary/Q/-a32":{"__comp":"17896441","content":"94f643bb"},"/concepts/glossary/R/-6d3":{"__comp":"17896441","content":"2cb8ed3d"},"/concepts/glossary/S/-ad0":{"__comp":"17896441","content":"c9d52fc5"},"/concepts/glossary/T/-97c":{"__comp":"17896441","content":"4545390c"},"/concepts/glossary/U/-fc5":{"__comp":"17896441","content":"65a9ed9e"},"/concepts/glossary/V/-e4f":{"__comp":"17896441","content":"ad727d36"},"/concepts/glossary/W/-872":{"__comp":"17896441","content":"130631d9"},"/concepts/glossary/X/-097":{"__comp":"17896441","content":"87f5bee7"},"/concepts/glossary/Y/-157":{"__comp":"17896441","content":"e5493a21"},"/concepts/glossary/Z/-6de":{"__comp":"17896441","content":"b3a49b92"},"/concepts/intro-to-dapps/-a56":{"__comp":"17896441","content":"5cf40dea"},"/concepts/key-types/-e8c":{"__comp":"17896441","content":"134a9ec2"},"/concepts/list-auth-keys/-3f0":{"__comp":"17896441","content":"398cf21c"},"/concepts/serialization/-d4a":{"__comp":"17896441","content":"dfcc4619"},"/concepts/serialization/primitives/-d90":{"__comp":"17896441","content":"f95b1f88"},"/concepts/serialization/structures/-0ad":{"__comp":"17896441","content":"56ad65de"},"/concepts/serialization/types/-3fe":{"__comp":"17896441","content":"64899cf9"},"/concepts/smart-contracts/-b31":{"__comp":"17896441","content":"58092c27"},"/counter-testnet/-262":{"__comp":"17896441","content":"bf5bbaf8"},"/counter/-c46":{"__comp":"17896441","content":"ab991e0e"},"/design/-52f":{"__comp":"17896441","content":"d7289626"},"/developers/-d10":{"__comp":"17896441","content":"63925da8"},"/developers/cli/-0e2":{"__comp":"17896441","content":"46e94768"},"/developers/cli/calling-contracts/-ee1":{"__comp":"17896441","content":"8ff31131"},"/developers/cli/delegate/-062":{"__comp":"17896441","content":"4d118a4e"},"/developers/cli/execution-error-codes/-370":{"__comp":"17896441","content":"459c4db6"},"/developers/cli/installing-contracts/-7a6":{"__comp":"17896441","content":"0b8cc739"},"/developers/cli/opcode-costs/-dbe":{"__comp":"17896441","content":"452e65d7"},"/developers/cli/querying-global-state/-c3c":{"__comp":"17896441","content":"cb63487a"},"/developers/cli/redelegate/-124":{"__comp":"17896441","content":"63d4ce07"},"/developers/cli/sending-transactions/-820":{"__comp":"17896441","content":"6e34a484"},"/developers/cli/transfers/-f71":{"__comp":"17896441","content":"2ffce966"},"/developers/cli/transfers/direct-token-transfer/-4e8":{"__comp":"17896441","content":"f1c6b7a3"},"/developers/cli/transfers/multisig-deploy-transfer/-c03":{"__comp":"17896441","content":"7c798d59"},"/developers/cli/transfers/verify-transfer/-ad4":{"__comp":"17896441","content":"3bf1ce3c"},"/developers/cli/undelegate/-9e2":{"__comp":"17896441","content":"c19e69a7"},"/developers/cli/verifying-contracts/-099":{"__comp":"17896441","content":"ce6605d8"},"/developers/dapps/-8c0":{"__comp":"17896441","content":"a1868598"},"/developers/dapps/dapp/-0b8":{"__comp":"17896441","content":"51719dea"},"/developers/dapps/monitor-and-consume-events/-f8f":{"__comp":"17896441","content":"c0299000"},"/developers/dapps/nctl-test/-380":{"__comp":"17896441","content":"2d971abe"},"/developers/dapps/prerequisites/-ac3":{"__comp":"17896441","content":"f3bf6984"},"/developers/dapps/sdk/client-library-usage/-3e7":{"__comp":"17896441","content":"08996e66"},"/developers/dapps/sdk/csharp-sdk/-43a":{"__comp":"17896441","content":"06c1e821"},"/developers/dapps/sdk/go-sdk/-743":{"__comp":"17896441","content":"e45056bc"},"/developers/dapps/sdk/python-sdk/-2b8":{"__comp":"17896441","content":"d49dddd4"},"/developers/dapps/sdk/script-sdk/-d81":{"__comp":"17896441","content":"8c0ead1f"},"/developers/dapps/setup-nctl/-685":{"__comp":"17896441","content":"a4ae8417"},"/developers/dapps/signing-a-transaction/-62a":{"__comp":"17896441","content":"044f7961"},"/developers/dapps/speculative-exec/-9a4":{"__comp":"17896441","content":"7cff47a5"},"/developers/dapps/technology-stack/-923":{"__comp":"17896441","content":"a9deb425"},"/developers/dapps/template-frontend/-7cf":{"__comp":"17896441","content":"7607f1d5"},"/developers/dapps/uref-security/-94b":{"__comp":"17896441","content":"cc2e94c0"},"/developers/essential-crates/-b0d":{"__comp":"17896441","content":"680b7fa9"},"/developers/json-rpc/-ce3":{"__comp":"17896441","content":"5a3b84ba"},"/developers/json-rpc/errors/-907":{"__comp":"17896441","content":"3aaf2bfb"},"/developers/json-rpc/guidance/-a0f":{"__comp":"17896441","content":"f2779c45"},"/developers/json-rpc/json-rpc-informational/-81d":{"__comp":"17896441","content":"d638c601"},"/developers/json-rpc/json-rpc-pos/-453":{"__comp":"17896441","content":"7b1c3c68"},"/developers/json-rpc/json-rpc-transactional/-f46":{"__comp":"17896441","content":"753d7b98"},"/developers/json-rpc/minimal-compliance/-a83":{"__comp":"17896441","content":"1b2f0a70"},"/developers/json-rpc/types_chain/-45b":{"__comp":"17896441","content":"60d3a705"},"/developers/json-rpc/types_cl/-057":{"__comp":"17896441","content":"6a307077"},"/developers/prerequisites/-061":{"__comp":"17896441","content":"e08eef46"},"/developers/writing-onchain-code/assembly-script/-145":{"__comp":"17896441","content":"1c694ffb"},"/developers/writing-onchain-code/best-practices/-3f7":{"__comp":"17896441","content":"19770ceb"},"/developers/writing-onchain-code/calling-contracts/-639":{"__comp":"17896441","content":"0bb2dbe9"},"/developers/writing-onchain-code/contract-hash-vs-package-hash/-4e1":{"__comp":"17896441","content":"6e2737c0"},"/developers/writing-onchain-code/contract-vs-session/-da0":{"__comp":"17896441","content":"a81b7004"},"/developers/writing-onchain-code/emitting-contract-events/-56b":{"__comp":"17896441","content":"261dbd4a"},"/developers/writing-onchain-code/factory-pattern/-a2a":{"__comp":"17896441","content":"6520db96"},"/developers/writing-onchain-code/getting-started/-7fb":{"__comp":"17896441","content":"5497691c"},"/developers/writing-onchain-code/simple-contract/-e80":{"__comp":"17896441","content":"e8b40bee"},"/developers/writing-onchain-code/testing-contracts/-a8c":{"__comp":"17896441","content":"106b67a5"},"/developers/writing-onchain-code/testing-session-code/-a87":{"__comp":"17896441","content":"7f115b1f"},"/developers/writing-onchain-code/upgrading-contracts/-e41":{"__comp":"17896441","content":"053d5d89"},"/developers/writing-onchain-code/writing-session-code/-c4f":{"__comp":"17896441","content":"3724f9ed"},"/disclaimer/-70f":{"__comp":"17896441","content":"fe0242b1"},"/economics/-dd5":{"__comp":"17896441","content":"ad15c07f"},"/glossary/-8b4":{"__comp":"17896441","content":"2e4bdb60"},"/operators/-8ec":{"__comp":"17896441","content":"5f02ec4e"},"/operators/becoming-a-validator/-09d":{"__comp":"17896441","content":"9c5b6467"},"/operators/becoming-a-validator/bonding/-5d8":{"__comp":"17896441","content":"be0df356"},"/operators/becoming-a-validator/change-bid-public-key/-d51":{"__comp":"17896441","content":"915d90e1"},"/operators/becoming-a-validator/inactive-vs-faulty/-bde":{"__comp":"17896441","content":"78c66fad"},"/operators/becoming-a-validator/recovering/-22d":{"__comp":"17896441","content":"9cd0819b"},"/operators/becoming-a-validator/unbonding/-ff4":{"__comp":"17896441","content":"28bc9864"},"/operators/maintenance/-059":{"__comp":"17896441","content":"64c09e2e"},"/operators/maintenance/archiving-and-restoring/-67c":{"__comp":"17896441","content":"074e7bdc"},"/operators/maintenance/moving-node/-931":{"__comp":"17896441","content":"f46d6e59"},"/operators/setup-network/-ebd":{"__comp":"17896441","content":"116fa82a"},"/operators/setup-network/chain-spec/-a86":{"__comp":"17896441","content":"a0ccdbb2"},"/operators/setup-network/create-private/-c58":{"__comp":"17896441","content":"c52eaa26"},"/operators/setup-network/genesis/-612":{"__comp":"17896441","content":"a9f5564d"},"/operators/setup-network/staging-files-for-new-network/-9e9":{"__comp":"17896441","content":"f88cb658"},"/operators/setup/-fe8":{"__comp":"17896441","content":"b36f50d3"},"/operators/setup/basic-node-configuration/-638":{"__comp":"17896441","content":"99a13742"},"/operators/setup/casper-sidecar/-865":{"__comp":"17896441","content":"31722bc4"},"/operators/setup/fast-sync/-c40":{"__comp":"17896441","content":"c2a48fdb"},"/operators/setup/hardware/-296":{"__comp":"17896441","content":"c7d46fe1"},"/operators/setup/install-node/-b2e":{"__comp":"17896441","content":"03acd2fb"},"/operators/setup/joining/-821":{"__comp":"17896441","content":"cbe8101d"},"/operators/setup/node-endpoints/-58f":{"__comp":"17896441","content":"e2799c63"},"/operators/setup/node-events/-cbf":{"__comp":"17896441","content":"830e9e14"},"/operators/setup/non-root-user/-bd6":{"__comp":"17896441","content":"db24aef0"},"/operators/setup/open-files/-de5":{"__comp":"17896441","content":"68ccb7f6"},"/operators/setup/upgrade/-d73":{"__comp":"17896441","content":"b46ec474"},"/resources/-c8c":{"__comp":"17896441","content":"cd948886"},"/resources/advanced/list-auth-keys-tutorial/-b65":{"__comp":"17896441","content":"ba0fa3fe"},"/resources/advanced/multi-sig/-5fe":{"__comp":"17896441","content":"2fb5589e"},"/resources/advanced/multi-sig/multi-sig-workflow/-c3b":{"__comp":"17896441","content":"d92b4d08"},"/resources/advanced/multi-sig/other-scenarios/-b05":{"__comp":"17896441","content":"fb804d1c"},"/resources/beginner/counter-testnet/commands/-110":{"__comp":"17896441","content":"05a3aa78"},"/resources/beginner/counter-testnet/overview/-a44":{"__comp":"17896441","content":"1e144f6d"},"/resources/beginner/counter-testnet/walkthrough/-ece":{"__comp":"17896441","content":"8f27be43"},"/resources/beginner/counter/commands/-869":{"__comp":"17896441","content":"560adf9d"},"/resources/beginner/counter/overview/-061":{"__comp":"17896441","content":"9116852a"},"/resources/beginner/counter/walkthrough/-7f1":{"__comp":"17896441","content":"236eb0f0"},"/resources/build-on-casper/casper-open-source-software/-9c4":{"__comp":"17896441","content":"f776c06c"},"/resources/build-on-casper/introduction/-7a5":{"__comp":"17896441","content":"861e5e13"},"/resources/changelog/-538":{"__comp":"17896441","content":"d0a8493b"},"/resources/moving-to-casper/-9bf":{"__comp":"17896441","content":"2c27a7b4"},"/resources/quick-start/-1dd":{"__comp":"17896441","content":"be5e85f4"},"/resources/tokens/-1d2":{"__comp":"17896441","content":"0cde4ba3"},"/resources/tokens/cep18/full-tutorial/-136":{"__comp":"17896441","content":"28b5b925"},"/resources/tokens/cep18/query/-845":{"__comp":"17896441","content":"ad0b296a"},"/resources/tokens/cep18/quickstart-guide/-42b":{"__comp":"17896441","content":"6193b30e"},"/resources/tokens/cep18/tests/-6e0":{"__comp":"17896441","content":"a811e42c"},"/resources/tokens/cep18/transfer/-dc0":{"__comp":"17896441","content":"89d896be"},"/resources/tokens/cep78/introduction/-669":{"__comp":"17896441","content":"3a5d5492"},"/resources/tokens/cep78/js-tutorial/-e2c":{"__comp":"17896441","content":"d80df429"},"/resources/tokens/cep78/modalities/-928":{"__comp":"17896441","content":"d4c529d3"},"/resources/tokens/cep78/reverse-lookup/-dbb":{"__comp":"17896441","content":"4c91363f"},"/resources/tokens/using-casper-client/-70a":{"__comp":"17896441","content":"157e4bc2"},"/resources/tutorials/advanced/-8e2":{"__comp":"17896441","content":"381391cb"},"/resources/tutorials/advanced/cross-contract/-ddd":{"__comp":"17896441","content":"46c04ff3"},"/resources/tutorials/advanced/list-cspr/-1af":{"__comp":"17896441","content":"a55b9639"},"/resources/tutorials/advanced/return-values-tutorial/-323":{"__comp":"17896441","content":"ee94176e"},"/resources/tutorials/advanced/storage-workflow/-611":{"__comp":"17896441","content":"dfbc8a55"},"/resources/tutorials/advanced/transfer-token-to-contract/-8dd":{"__comp":"17896441","content":"d06ee05c"},"/resources/tutorials/advanced/two-party-multi-sig/-1c6":{"__comp":"17896441","content":"15ce11b3"},"/resources/tutorials/beginner/-0fa":{"__comp":"17896441","content":"8d81394c"},"/resources/tutorials/beginner/aws-node/-f28":{"__comp":"17896441","content":"7b8da7d8"},"/resources/tutorials/beginner/cep18/-47e":{"__comp":"17896441","content":"546b5549"},"/resources/tutorials/beginner/getting-started-tutorial/-e6b":{"__comp":"17896441","content":"4ba3ceff"},"/resources/tutorials/beginner/querying-network/-80d":{"__comp":"17896441","content":"8323e0f5"},"/resources/tutorials/beginner/upgrade-contract/-647":{"__comp":"17896441","content":"7708241d"},"/runtime/-c35":{"__comp":"17896441","content":"3619739c"},"/sdk/-4f6":{"__comp":"17896441","content":"9c780b1a"},"/transactions-and-transaction-lifecycle/-1f4":{"__comp":"17896441","content":"dc5e10d3"},"/transactions/-e9e":{"__comp":"17896441","content":"f0563fee"},"/users/-a55":{"__comp":"17896441","content":"449bc0d9"},"/users/block-explorer/-e55":{"__comp":"17896441","content":"89c22482"},"/users/csprlive/-e85":{"__comp":"17896441","content":"aafbba97"},"/users/delegate-ui/-2cb":{"__comp":"17896441","content":"5a22b142"},"/users/delegating/-214":{"__comp":"17896441","content":"870de909"},"/users/funding-from-exchanges/-979":{"__comp":"17896441","content":"74d57d33"},"/users/ledger/-06e":{"__comp":"17896441","content":"e15566cb"},"/users/ledger/ledger-cspr-live/-93d":{"__comp":"17896441","content":"5979a0ec"},"/users/ledger/ledger-live/-d19":{"__comp":"17896441","content":"faf2a93e"},"/users/staking-ledger/-198":{"__comp":"17896441","content":"ae470ddc"},"/users/testnet-faucet/-6f0":{"__comp":"17896441","content":"dcb4c613"},"/users/token-transfer/-e4a":{"__comp":"17896441","content":"9ed00072"},"/users/undelegate-ui/-7b8":{"__comp":"17896441","content":"76a75fbd"},"/workflow/ledger-setup/-5c0":{"__comp":"17896441","content":"2668f34f"},"/writing-contracts/-93e":{"__comp":"17896441","content":"51ce653c"},"/-214":{"__comp":"17896441","content":"c377a04b"}}')}},e=>{e.O(0,[71869],(()=>{return t=38536,e(e.s=t);var t}));e.O()}]); \ No newline at end of file diff --git a/assets/js/main.8959bba6.js.LICENSE.txt b/assets/js/main.d3917998.js.LICENSE.txt similarity index 100% rename from assets/js/main.8959bba6.js.LICENSE.txt rename to assets/js/main.d3917998.js.LICENSE.txt diff --git a/assets/js/runtime~main.d0ca807f.js b/assets/js/runtime~main.d0ca807f.js deleted file mode 100644 index 2eaacd905..000000000 --- a/assets/js/runtime~main.d0ca807f.js +++ /dev/null @@ -1 +0,0 @@ -(()=>{"use strict";var e,a,d,c,b,f={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var d=t[e]={id:e,loaded:!1,exports:{}};return f[e].call(d.exports,d,d.exports,r),d.loaded=!0,d.exports}r.m=f,r.c=t,e=[],r.O=(a,d,c,b)=>{if(!d){var f=1/0;for(i=0;i<e.length;i++){d=e[i][0],c=e[i][1],b=e[i][2];for(var t=!0,o=0;o<d.length;o++)(!1&b||f>=b)&&Object.keys(r.O).every((e=>r.O[e](d[o])))?d.splice(o--,1):(t=!1,b<f&&(f=b));if(t){e.splice(i--,1);var n=c();void 0!==n&&(a=n)}}return a}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[d,c,b]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},d=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,c){if(1&c&&(e=this(e)),8&c)return e;if("object"==typeof e&&e){if(4&c&&e.__esModule)return e;if(16&c&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var f={};a=a||[null,d({}),d([]),d(d)];for(var t=2&c&&e;"object"==typeof t&&!~a.indexOf(t);t=d(t))Object.getOwnPropertyNames(t).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,r.d(b,f),b},r.d=(e,a)=>{for(var d in a)r.o(a,d)&&!r.o(e,d)&&Object.defineProperty(e,d,{enumerable:!0,get:a[d]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,d)=>(r.f[d](e,a),a)),[])),r.u=e=>"assets/js/"+({56:"ab991e0e",124:"3619739c",140:"34b086e1",186:"3d90f760",200:"74d57d33",202:"e1e5af17",229:"e238c115",240:"9afe1d3d",247:"9cd0819b",280:"eb5a6cc0",286:"bafead24",367:"ed267fba",398:"a35afcc3",414:"1b2f0a70",442:"3669623c",453:"a4046515",526:"1b0eecbc",529:"08af526d",558:"931ecaed",566:"7cf62e8d",635:"04f8200d",642:"9ed00072",666:"3aaf2bfb",670:"f71fe95d",690:"56746dcb",699:"8de9f24f",715:"ef2abd7e",781:"c10b8a9f",793:"7607f1d5",867:"33fc5bb8",871:"5c3f78ae",884:"a434b528",885:"05a3aa78",889:"12e95288",898:"821dc1e3",899:"106b67a5",910:"65cd111b",956:"35a4f7b3",957:"c141421f",1012:"fe0242b1",1089:"ae470ddc",1093:"ebb9a3ce",1153:"f88cb658",1180:"2b8e251b",1187:"340c2365",1261:"63d4ce07",1368:"a03c4947",1381:"06c1e821",1393:"19770ceb",1408:"a811e42c",1418:"aefd42fa",1433:"ee94176e",1434:"eacea541",1451:"d06ee05c",1458:"2668f34f",1512:"aa162190",1515:"3aa29420",1535:"7c798d59",1561:"e3f9a068",1567:"22dd74f7",1574:"560adf9d",1627:"b687a817",1630:"f1245771",1651:"546b5549",1672:"dd04b75e",1741:"2cc4f81c",1767:"b15d29cb",1790:"753d7b98",1801:"b67f60dc",1818:"28b5b925",1865:"9ec4e3de",1894:"4e4df367",1903:"acecf23e",1926:"d0a8493b",1961:"31722bc4",1968:"befad559",1969:"eb1cd7f2",1973:"4ab63648",1991:"43a834ef",1997:"e2f5312b",2021:"f1f89c2e",2028:"7e55f6e6",2033:"38b4dbd3",2035:"897e9cb3",2048:"be0df356",2059:"603aca9e",2067:"eaba5dd2",2071:"58718032",2072:"51ce653c",2107:"72c6e609",2112:"d48191b6",2138:"1a4e3797",2152:"5364a150",2218:"a80f26d4",2270:"ce6605d8",2275:"52fa5650",2289:"074e7bdc",2321:"5ce0f216",2349:"3bf1ce3c",2352:"0dea8207",2381:"9c6aa8d2",2418:"9116852a",2446:"680b7fa9",2447:"14620e15",2455:"915d90e1",2473:"9ee7887a",2510:"baabe181",2512:"c74094f8",2527:"e45056bc",2646:"46e94768",2670:"75de5623",2677:"d13dc577",2684:"d477c291",2686:"449bc0d9",2697:"58092c27",2702:"1e144f6d",2709:"212aab5d",2711:"9e4087bc",2714:"35808b61",2720:"4545390c",2743:"38296185",2748:"130631d9",2799:"db24aef0",2858:"f46d6e59",2905:"0791978c",2910:"c380abc4",2958:"b46ec474",2986:"aafbba97",2996:"baf71301",3e3:"7b8da7d8",3019:"ac361b55",3025:"ce0e1dbb",3027:"521a6610",3048:"883310e5",3100:"a3dc4ae2",3101:"236eb0f0",3127:"3a9d2720",3144:"87f5bee7",3213:"2fb5589e",3215:"2063472f",3226:"5979a0ec",3249:"ccc49370",3265:"9c5b6467",3297:"709dfa47",3307:"dfbc8a55",3337:"5ed91ab5",3341:"cf35294f",3422:"d92b4d08",3445:"dcb4c613",3469:"4e8b7bcc",3471:"56ad65de",3485:"40c07125",3495:"d7f9f727",3509:"116fa82a",3540:"028247bf",3552:"481163ce",3580:"4cc75cd6",3586:"03aa8e23",3627:"57f923a9",3632:"157e4bc2",3697:"64c09e2e",3708:"bd7d26b2",3766:"4db682c6",3781:"89c22482",3793:"72cc2261",3828:"a72bcf22",3829:"9d275d72",3846:"d80df429",3852:"89d896be",3894:"650a8fc0",3919:"46c04ff3",3920:"41905acb",3931:"533ebf6b",3979:"60d3a705",3990:"b36f50d3",4005:"6dcb5e16",4008:"202767e6",4035:"5497691c",4054:"277b6be0",4096:"bb037852",4097:"8e1fd569",4110:"6a307077",4191:"43fd3112",4192:"f2779c45",4198:"bb9db0dd",4212:"621db11d",4225:"ba0fa3fe",4325:"be5e85f4",4336:"b8c8445c",4358:"7f115b1f",4374:"4c91363f",4425:"c377dc4a",4426:"08996e66",4457:"ad727d36",4491:"772d3db3",4555:"df5bc763",4557:"dc5e10d3",4586:"2e4bdb60",4635:"3362155c",4643:"0bd3b317",4684:"03c6d9c7",4686:"a4b0daeb",4707:"331badc5",4766:"a6efe0e1",4805:"2c27a7b4",4813:"6875c492",4814:"6e34a484",4846:"c4561df8",4858:"d638c601",4889:"65961da4",4891:"26f7e8fd",4894:"cbe09f13",4932:"41e7d56e",4939:"fb804d1c",4941:"d220dcab",4998:"26a33332",5059:"5d4e9672",5069:"28bc9864",5087:"7effaf45",5096:"85b8bb26",5157:"a9deb425",5210:"af1112c6",5255:"3724f9ed",5282:"e8b40bee",5296:"79474bae",5338:"459c4db6",5354:"d2039ef8",5364:"cc2e94c0",5378:"ad0b296a",5409:"5a3b84ba",5418:"3a5d5492",5458:"a40a2cf8",5465:"9acc619b",5469:"8941358f",5496:"a30e2bb0",5552:"0904ce24",5559:"d279fdce",5580:"dc1c4417",5592:"f070a991",5631:"8d265689",5650:"41eb5a6a",5664:"a53bd891",5680:"3e796ac9",5687:"72a89de8",5712:"4e015808",5721:"ad7eda35",5727:"c9f0fdac",5731:"65a9ed9e",5732:"830e9e14",5742:"aba21aa0",5751:"e4d870e1",5768:"2d971abe",5789:"fd661beb",5808:"c8e4da00",5819:"21ae0e7e",5833:"727f767d",5844:"4fdb6df3",5884:"0c098c15",5890:"c0299000",6044:"a81b7004",6046:"6043c3f4",6087:"64899cf9",6088:"8f27be43",6091:"8c0ead1f",6109:"358cf6da",6121:"c2728190",6139:"381391cb",6163:"7ade0b2a",6167:"b7708f1e",6194:"40078125",6215:"60fa9972",6220:"241648bf",6221:"977c8faa",6224:"5109d3ad",6232:"6193b30e",6233:"c691959f",6247:"d7289626",6265:"a1868598",6342:"6245c126",6346:"8ff31131",6365:"168da062",6379:"d4c529d3",6444:"51719dea",6453:"a55b9639",6474:"68ccb7f6",6476:"bc4bfdf0",6481:"ea0474c4",6512:"a2874f18",6547:"c3308ba6",6552:"2ffce966",6568:"7ce4a62a",6590:"5052751d",6595:"2bd0ed90",6607:"bf5bbaf8",6623:"c2a48fdb",6666:"faf2a93e",6708:"3b749ca6",6724:"afa6d836",6736:"b71ecf14",6755:"870de909",6770:"72b43be8",6784:"d49dddd4",6815:"3b86d751",6871:"63925da8",6898:"1c694ffb",6938:"c52eaa26",6958:"6e2737c0",6962:"c19e69a7",6986:"ce3d5a4b",6988:"c9db186d",7024:"94f643bb",7033:"f776c06c",7083:"dfcc4619",7098:"a7bd4aaa",7110:"ef7672e3",7174:"471ca6e4",7201:"4423d65b",7205:"a4f8fe7e",7267:"abd56c27",7320:"398cf21c",7356:"1871ac35",7371:"5b827590",7375:"4804492c",7394:"e289ead3",7403:"a4cd78b5",7419:"ca7245df",7438:"9c780b1a",7440:"77981a3a",7472:"814f3328",7491:"0cde4ba3",7543:"55568807",7559:"3efe71e8",7575:"eb0d94ae",7636:"d7fae98e",7643:"a6aa9e1f",7667:"76a75fbd",7675:"31dbaea7",7746:"15ce11b3",7753:"5f02ec4e",7772:"98df448b",7795:"124873a8",7796:"64959b1e",7802:"2c04116d",7816:"3ce1a06b",7832:"aee0fe92",7837:"861e5e13",7865:"f0563fee",7876:"f95b1f88",7903:"480fa8f7",7915:"80e6044e",7927:"5cf40dea",7935:"c7d46fe1",7937:"7c67ea25",8016:"39ac5a41",8061:"0bb2dbe9",8114:"044f7961",8132:"90efbb16",8155:"fef6ab33",8183:"5c07109c",8190:"362368d5",8204:"e2975a84",8209:"01a85c17",8256:"106a38e1",8344:"25f19435",8401:"17896441",8425:"53d095ec",8426:"79d896a3",8431:"ca0e408e",8445:"bfb3244a",8455:"c10cfbfe",8471:"6c606038",8548:"d3ef4614",8562:"0ac4e675",8579:"0753c93f",8621:"4d118a4e",8626:"3ac85609",8631:"33a9c3bd",8652:"7b1c3c68",8694:"f1c6b7a3",8723:"cbe8101d",8727:"738a6ad4",8728:"7708241d",8729:"705e93ef",8749:"dbfc4782",8794:"2cb8ed3d",8875:"8833ab21",8889:"d050b476",8916:"7cff47a5",8950:"6fe126b9",8953:"053d5d89",8979:"cd948886",8988:"e5493a21",9025:"6520db96",9029:"5e9306ee",9037:"e08eef46",9041:"ee7c1cc7",9044:"ad15c07f",9048:"a94703ab",9065:"d94d6bbe",9078:"9b0d9b67",9080:"eff21157",9081:"cb63487a",9109:"452e65d7",9113:"b3a49b92",9126:"6474e148",9155:"23e022aa",9210:"c9d52fc5",9218:"b1eae65b",9235:"a9f5564d",9238:"6318ac72",9293:"af050a36",9303:"e2799c63",9314:"a4ae8417",9349:"f3bf6984",9356:"0b8cc739",9378:"03acd2fb",9392:"20f436ec",9408:"4832c6fe",9457:"4ba3ceff",9460:"a0ccdbb2",9529:"8d81394c",9540:"32dd135c",9596:"c37f176d",9635:"134a9ec2",9647:"5e95c892",9672:"3fe76c6c",9687:"b3b8c5cb",9749:"8323e0f5",9756:"ab246697",9784:"e15566cb",9858:"36994c47",9861:"555a4473",9895:"99a13742",9899:"261dbd4a",9902:"78c66fad",9918:"dd908370",9940:"5a22b142",9941:"197196c4"}[e]||e)+"."+{56:"54fa42af",124:"88978e27",140:"d5c23182",186:"a5aed92d",200:"882cb0d6",202:"e2008a93",229:"2aaf7fc9",240:"e763479c",247:"14619139",280:"bb4e4618",286:"1578a574",367:"167c6c60",398:"c8f608cb",414:"d99e2656",416:"c7de0599",442:"858e4657",453:"82e9c056",526:"35fe077e",529:"cefb371d",558:"0c0278da",566:"f6f618ae",635:"35a20847",642:"861eaae3",666:"7183a894",670:"fa1be639",690:"f4900217",699:"27e228f9",715:"e1b228a5",781:"7b6997c1",793:"09164840",867:"4b577c2a",871:"c5d549a0",884:"63eb51ca",885:"baa762b5",889:"dcfe96df",898:"484815c2",899:"9d743cdc",910:"64289a65",956:"e6576d4a",957:"80b09241",1012:"da99f6c2",1089:"f89950ff",1093:"877a950d",1153:"de8becbc",1180:"f0bf2b40",1187:"a24dd798",1261:"8dccf7cc",1368:"715ecbfc",1381:"b9348323",1393:"8387e9e3",1408:"b14b4cad",1418:"03d773c1",1433:"948fb7cb",1434:"eb56de71",1451:"b42299f4",1458:"81895d61",1494:"44935779",1512:"1c22b5a0",1515:"a18fd86b",1535:"93f88623",1561:"2511d6f6",1567:"d59e4fd6",1574:"033a09e9",1627:"0ec13cad",1630:"23f1d291",1651:"588a9376",1672:"7f740bf3",1741:"f99f6439",1767:"801818ce",1790:"aa766a46",1801:"7656748c",1818:"0168630d",1865:"eaa96579",1894:"d91fcd1d",1903:"77fdf311",1926:"0a50edbb",1961:"9f4ab15b",1968:"b54dfbe5",1969:"4d0cd80d",1973:"80eee16a",1991:"022fd866",1997:"06dbe2a4",2021:"04046fd4",2028:"22836de1",2033:"bdc4f617",2035:"7555ccf7",2048:"811aeaeb",2059:"56ef5275",2067:"013bab1c",2071:"25ddfdd1",2072:"21c89cba",2107:"8779ead0",2112:"9a8c43c0",2138:"db7f4d3c",2152:"155bae67",2218:"7206c3fd",2237:"2be052d4",2270:"ba4d38f5",2275:"b182f278",2289:"4eb0678a",2321:"2ca1cbe8",2349:"4be36f8e",2352:"4f27fd0b",2381:"87f1ae35",2418:"95b23be5",2446:"7fd0fcdc",2447:"210101ba",2455:"21e8e7ff",2473:"a80b72fc",2510:"5c403d89",2512:"7db305e4",2527:"9693a59b",2646:"e7996bf8",2670:"40d8f83e",2677:"6fe89c7c",2684:"57fee1c9",2686:"5dd63daf",2697:"b116ed08",2702:"846df292",2709:"1a701a70",2711:"c84286d7",2714:"27d7ec33",2720:"0ca5f8dc",2743:"1abf2f2d",2748:"473508f7",2799:"5b7d27fc",2858:"d7f83469",2905:"6cb20991",2910:"bac3fe3d",2958:"0abc05a8",2986:"658201c7",2996:"8c98a771",3e3:"eab766d1",3019:"a49eb8bd",3025:"b2988b7b",3027:"95717138",3048:"f84c5342",3100:"0aa14bc4",3101:"ea22eadd",3127:"e34e9dc9",3144:"c06abb9f",3213:"18083c1f",3215:"f81204a0",3226:"ef4511ba",3249:"be9d46ff",3265:"3db5c71f",3297:"62b3e248",3307:"1e3a65ca",3337:"d74e522c",3341:"bb066321",3347:"f799bb61",3422:"2f4390d9",3445:"9305969c",3469:"034fae29",3471:"d53d5c28",3485:"9be41738",3495:"75d78148",3509:"7fdfa28d",3540:"e22beb61",3552:"aa41f256",3580:"34166208",3586:"0a426846",3627:"ad12da5f",3632:"eba0692b",3697:"d5d788c7",3708:"6860a437",3766:"c730ac08",3781:"8436b3a0",3793:"d789919f",3828:"d7ffd90c",3829:"668b0bc7",3846:"67028afb",3852:"f7cb4e66",3894:"6c05b66c",3919:"0ad52045",3920:"9b219f55",3931:"62b843d3",3979:"cec61f0b",3990:"b825a751",4005:"e806e70a",4008:"662bbd94",4035:"3c574e7f",4054:"6924c872",4096:"a0493efc",4097:"c1e0d801",4110:"51e38375",4191:"179a51de",4192:"270e5772",4198:"0b2c5312",4212:"81ae89ad",4225:"2c38bb2c",4325:"f95550ce",4336:"ff0cc91b",4358:"4ae39270",4374:"d784b1bc",4425:"bac70803",4426:"378c3d02",4457:"f0083a21",4491:"b3494ddc",4555:"837d978f",4557:"854abbc3",4586:"fa0d0d8f",4635:"196ff25b",4643:"d740e1e1",4684:"c792cbe5",4686:"ca90cf11",4707:"a0e388dd",4766:"17fb2b9f",4805:"6fa37b9d",4813:"b515c771",4814:"5e7fcec6",4846:"dd6655af",4858:"58b730d1",4889:"60f93cb9",4891:"759ba063",4894:"99a63f42",4932:"2064be67",4939:"9658edac",4941:"b0fd0ac0",4998:"9159dc58",5059:"00906f33",5069:"9af5621d",5087:"395677e0",5096:"da81382e",5157:"39296314",5210:"4e044cf1",5255:"c1aaf3d4",5282:"291c4a8c",5296:"b05288fa",5338:"2d3b0e56",5354:"5609990b",5364:"ab50e15c",5378:"ec564b7f",5409:"73c72eda",5418:"554dd0cb",5458:"5c89beea",5465:"a5bfebce",5469:"b44c7608",5496:"89267903",5552:"59e4ae24",5559:"7ef66588",5580:"1f2e5fdc",5592:"8a1ac562",5631:"94e8c769",5650:"432785b3",5664:"34baf369",5680:"d85b7445",5687:"820a02b4",5712:"a485ffdf",5721:"de731ba0",5727:"1f67a1b8",5731:"f11f4e01",5732:"b215aae2",5742:"9fadd1f0",5751:"f85bd94e",5768:"26e71149",5789:"dd72aba0",5808:"1ce531b1",5819:"0ab591f6",5833:"bf85bdde",5844:"2cd2adde",5884:"5f193e57",5890:"a0ce979e",6044:"8421c8ce",6046:"024a7c77",6087:"d83e08cf",6088:"9c50069b",6091:"9f40d963",6109:"1b3e0934",6121:"0a5a894f",6139:"1c3e00bf",6163:"77621e50",6167:"99acd00d",6194:"bd3a3d60",6215:"b69bb4a6",6220:"5946a39a",6221:"34237830",6224:"b642a8c5",6232:"8f5c08a1",6233:"8bec913d",6247:"6cdeaeb0",6265:"bd404523",6342:"30b30088",6346:"5c0f2d85",6365:"f79ac659",6379:"c6f1d5fa",6444:"6107622a",6453:"792f74b1",6474:"108271e9",6476:"65012c91",6481:"2a0d441d",6512:"d9627a72",6547:"dabf8cd8",6552:"af34eb97",6568:"8943f664",6590:"e6a325fc",6595:"42d1714b",6607:"79578d9c",6623:"c860eb25",6666:"41ab65a9",6708:"2b2c6cde",6724:"ec61673a",6736:"1f26aa20",6755:"59012146",6770:"5416988c",6784:"ceb8eee3",6815:"8b6804b4",6871:"a65c70bf",6898:"eb41d9b2",6938:"32d71864",6958:"94881826",6962:"2fc7560a",6986:"b4b03daf",6988:"08192e85",7024:"31c536d4",7033:"59c0b752",7083:"0ab89293",7098:"951f72a9",7110:"d080a329",7174:"a462efc0",7201:"01606f7a",7205:"b982673b",7267:"bf3ed5c3",7320:"db34c60d",7356:"c8a05ff4",7371:"803d7896",7375:"1872c747",7394:"1f169ca7",7403:"cbc7d4a6",7419:"9c1a68a4",7438:"134169a6",7440:"abfda3cf",7472:"f0c18ae2",7491:"db3b01f2",7543:"2e91d1c2",7559:"65395bbf",7575:"58bdbefc",7636:"1faab744",7643:"43025aa7",7667:"cb2ccf80",7675:"cb2ad24d",7746:"dca58b4c",7753:"e8115c1a",7772:"23f7a8f8",7795:"3f86c852",7796:"487a4de3",7802:"e52985c2",7816:"211c5901",7832:"cc892c71",7837:"2a7daafb",7865:"0da4678b",7876:"7cc6f7b3",7903:"d7f8bb82",7915:"713e25c1",7927:"eeda9684",7935:"340d8422",7937:"dbf66f2d",8016:"6476776a",8061:"0880aaaf",8114:"5f1b0a68",8132:"0264317d",8155:"16f28ded",8183:"72972707",8190:"3185e36c",8204:"5efeb63f",8209:"f0d674b1",8256:"01a8cfcd",8344:"e9c61eb7",8401:"e301f0ef",8425:"d55cf378",8426:"a26aa031",8431:"aa3ff09a",8445:"40640614",8455:"9a85001f",8471:"42035320",8548:"82ba742b",8562:"ee46eb79",8579:"38bf38b5",8621:"fd0876b0",8626:"db0b618c",8631:"3a1f4799",8652:"e8be7755",8694:"50559f74",8723:"1206d77a",8727:"cf62d230",8728:"76dde882",8729:"1d983d05",8749:"468a1d4c",8794:"81fd42ba",8875:"8e10ccb3",8889:"71af1ad0",8913:"b6442bb9",8916:"af4053dd",8950:"1e04b30e",8953:"4f1b46a0",8979:"281c855f",8988:"e2c9467a",9025:"17ace29b",9029:"35f8dd24",9037:"56de3c31",9041:"f382d244",9044:"9bfac3bd",9048:"1cba57a1",9065:"f9bfb75e",9078:"bbbfb3bf",9080:"bd65bcae",9081:"169a1a3c",9109:"cb4a29c5",9113:"abfa439b",9126:"836b5554",9155:"6c773674",9210:"a4eef94e",9218:"5f062bf3",9235:"2e90b9b1",9238:"49f55d51",9293:"9b90e62b",9303:"d128e43e",9314:"97847ea7",9349:"253d30ee",9356:"79de13f9",9378:"d5a0a15f",9392:"0bdc9c76",9408:"1c554d77",9457:"df7f2c6a",9460:"cf1b6b50",9462:"9d10cf9f",9529:"b71ef1fd",9540:"20dd4de8",9596:"df6ecd7f",9635:"a9986cfa",9647:"e9a6d627",9672:"fdefcb5a",9687:"d5f88718",9749:"5f3557eb",9756:"680665e7",9784:"87dbe301",9858:"31271808",9861:"0aea839c",9895:"d3215e16",9899:"690860d0",9902:"6c958184",9918:"a9598e25",9940:"d6483baa",9941:"af135d1b"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),c={},b="cspr-docs:",r.l=(e,a,d,f)=>{if(c[e])c[e].push(a);else{var t,o;if(void 0!==d)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==b+d){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+d),t.src=e),c[e]=[a];var l=(a,d)=>{t.onerror=t.onload=null,clearTimeout(s);var b=c[e];if(delete c[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(d))),a)return a(d)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"8401",38296185:"2743",40078125:"6194",55568807:"7543",58718032:"2071",ab991e0e:"56","3619739c":"124","34b086e1":"140","3d90f760":"186","74d57d33":"200",e1e5af17:"202",e238c115:"229","9afe1d3d":"240","9cd0819b":"247",eb5a6cc0:"280",bafead24:"286",ed267fba:"367",a35afcc3:"398","1b2f0a70":"414","3669623c":"442",a4046515:"453","1b0eecbc":"526","08af526d":"529","931ecaed":"558","7cf62e8d":"566","04f8200d":"635","9ed00072":"642","3aaf2bfb":"666",f71fe95d:"670","56746dcb":"690","8de9f24f":"699",ef2abd7e:"715",c10b8a9f:"781","7607f1d5":"793","33fc5bb8":"867","5c3f78ae":"871",a434b528:"884","05a3aa78":"885","12e95288":"889","821dc1e3":"898","106b67a5":"899","65cd111b":"910","35a4f7b3":"956",c141421f:"957",fe0242b1:"1012",ae470ddc:"1089",ebb9a3ce:"1093",f88cb658:"1153","2b8e251b":"1180","340c2365":"1187","63d4ce07":"1261",a03c4947:"1368","06c1e821":"1381","19770ceb":"1393",a811e42c:"1408",aefd42fa:"1418",ee94176e:"1433",eacea541:"1434",d06ee05c:"1451","2668f34f":"1458",aa162190:"1512","3aa29420":"1515","7c798d59":"1535",e3f9a068:"1561","22dd74f7":"1567","560adf9d":"1574",b687a817:"1627",f1245771:"1630","546b5549":"1651",dd04b75e:"1672","2cc4f81c":"1741",b15d29cb:"1767","753d7b98":"1790",b67f60dc:"1801","28b5b925":"1818","9ec4e3de":"1865","4e4df367":"1894",acecf23e:"1903",d0a8493b:"1926","31722bc4":"1961",befad559:"1968",eb1cd7f2:"1969","4ab63648":"1973","43a834ef":"1991",e2f5312b:"1997",f1f89c2e:"2021","7e55f6e6":"2028","38b4dbd3":"2033","897e9cb3":"2035",be0df356:"2048","603aca9e":"2059",eaba5dd2:"2067","51ce653c":"2072","72c6e609":"2107",d48191b6:"2112","1a4e3797":"2138","5364a150":"2152",a80f26d4:"2218",ce6605d8:"2270","52fa5650":"2275","074e7bdc":"2289","5ce0f216":"2321","3bf1ce3c":"2349","0dea8207":"2352","9c6aa8d2":"2381","9116852a":"2418","680b7fa9":"2446","14620e15":"2447","915d90e1":"2455","9ee7887a":"2473",baabe181:"2510",c74094f8:"2512",e45056bc:"2527","46e94768":"2646","75de5623":"2670",d13dc577:"2677",d477c291:"2684","449bc0d9":"2686","58092c27":"2697","1e144f6d":"2702","212aab5d":"2709","9e4087bc":"2711","35808b61":"2714","4545390c":"2720","130631d9":"2748",db24aef0:"2799",f46d6e59:"2858","0791978c":"2905",c380abc4:"2910",b46ec474:"2958",aafbba97:"2986",baf71301:"2996","7b8da7d8":"3000",ac361b55:"3019",ce0e1dbb:"3025","521a6610":"3027","883310e5":"3048",a3dc4ae2:"3100","236eb0f0":"3101","3a9d2720":"3127","87f5bee7":"3144","2fb5589e":"3213","2063472f":"3215","5979a0ec":"3226",ccc49370:"3249","9c5b6467":"3265","709dfa47":"3297",dfbc8a55:"3307","5ed91ab5":"3337",cf35294f:"3341",d92b4d08:"3422",dcb4c613:"3445","4e8b7bcc":"3469","56ad65de":"3471","40c07125":"3485",d7f9f727:"3495","116fa82a":"3509","028247bf":"3540","481163ce":"3552","4cc75cd6":"3580","03aa8e23":"3586","57f923a9":"3627","157e4bc2":"3632","64c09e2e":"3697",bd7d26b2:"3708","4db682c6":"3766","89c22482":"3781","72cc2261":"3793",a72bcf22:"3828","9d275d72":"3829",d80df429:"3846","89d896be":"3852","650a8fc0":"3894","46c04ff3":"3919","41905acb":"3920","533ebf6b":"3931","60d3a705":"3979",b36f50d3:"3990","6dcb5e16":"4005","202767e6":"4008","5497691c":"4035","277b6be0":"4054",bb037852:"4096","8e1fd569":"4097","6a307077":"4110","43fd3112":"4191",f2779c45:"4192",bb9db0dd:"4198","621db11d":"4212",ba0fa3fe:"4225",be5e85f4:"4325",b8c8445c:"4336","7f115b1f":"4358","4c91363f":"4374",c377dc4a:"4425","08996e66":"4426",ad727d36:"4457","772d3db3":"4491",df5bc763:"4555",dc5e10d3:"4557","2e4bdb60":"4586","3362155c":"4635","0bd3b317":"4643","03c6d9c7":"4684",a4b0daeb:"4686","331badc5":"4707",a6efe0e1:"4766","2c27a7b4":"4805","6875c492":"4813","6e34a484":"4814",c4561df8:"4846",d638c601:"4858","65961da4":"4889","26f7e8fd":"4891",cbe09f13:"4894","41e7d56e":"4932",fb804d1c:"4939",d220dcab:"4941","26a33332":"4998","5d4e9672":"5059","28bc9864":"5069","7effaf45":"5087","85b8bb26":"5096",a9deb425:"5157",af1112c6:"5210","3724f9ed":"5255",e8b40bee:"5282","79474bae":"5296","459c4db6":"5338",d2039ef8:"5354",cc2e94c0:"5364",ad0b296a:"5378","5a3b84ba":"5409","3a5d5492":"5418",a40a2cf8:"5458","9acc619b":"5465","8941358f":"5469",a30e2bb0:"5496","0904ce24":"5552",d279fdce:"5559",dc1c4417:"5580",f070a991:"5592","8d265689":"5631","41eb5a6a":"5650",a53bd891:"5664","3e796ac9":"5680","72a89de8":"5687","4e015808":"5712",ad7eda35:"5721",c9f0fdac:"5727","65a9ed9e":"5731","830e9e14":"5732",aba21aa0:"5742",e4d870e1:"5751","2d971abe":"5768",fd661beb:"5789",c8e4da00:"5808","21ae0e7e":"5819","727f767d":"5833","4fdb6df3":"5844","0c098c15":"5884",c0299000:"5890",a81b7004:"6044","6043c3f4":"6046","64899cf9":"6087","8f27be43":"6088","8c0ead1f":"6091","358cf6da":"6109",c2728190:"6121","381391cb":"6139","7ade0b2a":"6163",b7708f1e:"6167","60fa9972":"6215","241648bf":"6220","977c8faa":"6221","5109d3ad":"6224","6193b30e":"6232",c691959f:"6233",d7289626:"6247",a1868598:"6265","6245c126":"6342","8ff31131":"6346","168da062":"6365",d4c529d3:"6379","51719dea":"6444",a55b9639:"6453","68ccb7f6":"6474",bc4bfdf0:"6476",ea0474c4:"6481",a2874f18:"6512",c3308ba6:"6547","2ffce966":"6552","7ce4a62a":"6568","5052751d":"6590","2bd0ed90":"6595",bf5bbaf8:"6607",c2a48fdb:"6623",faf2a93e:"6666","3b749ca6":"6708",afa6d836:"6724",b71ecf14:"6736","870de909":"6755","72b43be8":"6770",d49dddd4:"6784","3b86d751":"6815","63925da8":"6871","1c694ffb":"6898",c52eaa26:"6938","6e2737c0":"6958",c19e69a7:"6962",ce3d5a4b:"6986",c9db186d:"6988","94f643bb":"7024",f776c06c:"7033",dfcc4619:"7083",a7bd4aaa:"7098",ef7672e3:"7110","471ca6e4":"7174","4423d65b":"7201",a4f8fe7e:"7205",abd56c27:"7267","398cf21c":"7320","1871ac35":"7356","5b827590":"7371","4804492c":"7375",e289ead3:"7394",a4cd78b5:"7403",ca7245df:"7419","9c780b1a":"7438","77981a3a":"7440","814f3328":"7472","0cde4ba3":"7491","3efe71e8":"7559",eb0d94ae:"7575",d7fae98e:"7636",a6aa9e1f:"7643","76a75fbd":"7667","31dbaea7":"7675","15ce11b3":"7746","5f02ec4e":"7753","98df448b":"7772","124873a8":"7795","64959b1e":"7796","2c04116d":"7802","3ce1a06b":"7816",aee0fe92:"7832","861e5e13":"7837",f0563fee:"7865",f95b1f88:"7876","480fa8f7":"7903","80e6044e":"7915","5cf40dea":"7927",c7d46fe1:"7935","7c67ea25":"7937","39ac5a41":"8016","0bb2dbe9":"8061","044f7961":"8114","90efbb16":"8132",fef6ab33:"8155","5c07109c":"8183","362368d5":"8190",e2975a84:"8204","01a85c17":"8209","106a38e1":"8256","25f19435":"8344","53d095ec":"8425","79d896a3":"8426",ca0e408e:"8431",bfb3244a:"8445",c10cfbfe:"8455","6c606038":"8471",d3ef4614:"8548","0ac4e675":"8562","0753c93f":"8579","4d118a4e":"8621","3ac85609":"8626","33a9c3bd":"8631","7b1c3c68":"8652",f1c6b7a3:"8694",cbe8101d:"8723","738a6ad4":"8727","7708241d":"8728","705e93ef":"8729",dbfc4782:"8749","2cb8ed3d":"8794","8833ab21":"8875",d050b476:"8889","7cff47a5":"8916","6fe126b9":"8950","053d5d89":"8953",cd948886:"8979",e5493a21:"8988","6520db96":"9025","5e9306ee":"9029",e08eef46:"9037",ee7c1cc7:"9041",ad15c07f:"9044",a94703ab:"9048",d94d6bbe:"9065","9b0d9b67":"9078",eff21157:"9080",cb63487a:"9081","452e65d7":"9109",b3a49b92:"9113","6474e148":"9126","23e022aa":"9155",c9d52fc5:"9210",b1eae65b:"9218",a9f5564d:"9235","6318ac72":"9238",af050a36:"9293",e2799c63:"9303",a4ae8417:"9314",f3bf6984:"9349","0b8cc739":"9356","03acd2fb":"9378","20f436ec":"9392","4832c6fe":"9408","4ba3ceff":"9457",a0ccdbb2:"9460","8d81394c":"9529","32dd135c":"9540",c37f176d:"9596","134a9ec2":"9635","5e95c892":"9647","3fe76c6c":"9672",b3b8c5cb:"9687","8323e0f5":"9749",ab246697:"9756",e15566cb:"9784","36994c47":"9858","555a4473":"9861","99a13742":"9895","261dbd4a":"9899","78c66fad":"9902",dd908370:"9918","5a22b142":"9940","197196c4":"9941"}[e]||e,r.p+r.u(e)},(()=>{var e={2973:0,1869:0};r.f.j=(a,d)=>{var c=r.o(e,a)?e[a]:void 0;if(0!==c)if(c)d.push(c[2]);else if(/^(1869|2973)$/.test(a))e[a]=0;else{var b=new Promise(((d,b)=>c=e[a]=[d,b]));d.push(c[2]=b);var f=r.p+r.u(a),t=new Error;r.l(f,(d=>{if(r.o(e,a)&&(0!==(c=e[a])&&(e[a]=void 0),c)){var b=d&&("load"===d.type?"missing":d.type),f=d&&d.target&&d.target.src;t.message="Loading chunk "+a+" failed.\n("+b+": "+f+")",t.name="ChunkLoadError",t.type=b,t.request=f,c[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,d)=>{var c,b,f=d[0],t=d[1],o=d[2],n=0;if(f.some((a=>0!==e[a]))){for(c in t)r.o(t,c)&&(r.m[c]=t[c]);if(o)var i=o(r)}for(a&&a(d);n<f.length;n++)b=f[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},d=self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[];d.forEach(a.bind(null,0)),d.push=a.bind(null,d.push.bind(d))})()})(); \ No newline at end of file diff --git a/assets/js/runtime~main.f9ac0d96.js b/assets/js/runtime~main.f9ac0d96.js new file mode 100644 index 000000000..7061770f7 --- /dev/null +++ b/assets/js/runtime~main.f9ac0d96.js @@ -0,0 +1 @@ +(()=>{"use strict";var e,a,c,d,b,f={},t={};function r(e){var a=t[e];if(void 0!==a)return a.exports;var c=t[e]={id:e,loaded:!1,exports:{}};return f[e].call(c.exports,c,c.exports,r),c.loaded=!0,c.exports}r.m=f,r.c=t,e=[],r.O=(a,c,d,b)=>{if(!c){var f=1/0;for(i=0;i<e.length;i++){c=e[i][0],d=e[i][1],b=e[i][2];for(var t=!0,o=0;o<c.length;o++)(!1&b||f>=b)&&Object.keys(r.O).every((e=>r.O[e](c[o])))?c.splice(o--,1):(t=!1,b<f&&(f=b));if(t){e.splice(i--,1);var n=d();void 0!==n&&(a=n)}}return a}b=b||0;for(var i=e.length;i>0&&e[i-1][2]>b;i--)e[i]=e[i-1];e[i]=[c,d,b]},r.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return r.d(a,{a:a}),a},c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,r.t=function(e,d){if(1&d&&(e=this(e)),8&d)return e;if("object"==typeof e&&e){if(4&d&&e.__esModule)return e;if(16&d&&"function"==typeof e.then)return e}var b=Object.create(null);r.r(b);var f={};a=a||[null,c({}),c([]),c(c)];for(var t=2&d&&e;"object"==typeof t&&!~a.indexOf(t);t=c(t))Object.getOwnPropertyNames(t).forEach((a=>f[a]=()=>e[a]));return f.default=()=>e,r.d(b,f),b},r.d=(e,a)=>{for(var c in a)r.o(a,c)&&!r.o(e,c)&&Object.defineProperty(e,c,{enumerable:!0,get:a[c]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce(((a,c)=>(r.f[c](e,a),a)),[])),r.u=e=>"assets/js/"+({240:"9afe1d3d",280:"eb5a6cc0",414:"1b2f0a70",503:"09278318",566:"7cf62e8d",699:"8de9f24f",712:"3db2ed27",1093:"ebb9a3ce",1130:"64bdcaf3",1381:"06c1e821",1790:"753d7b98",1867:"76ea157b",1971:"0fa7e001",1991:"43a834ef",2119:"862f9df3",2306:"2a21571b",2407:"90f2be13",2714:"35808b61",2810:"1e2c8091",2996:"baf71301",3048:"883310e5",3155:"3a19cb34",3428:"b415f00a",3568:"26ab9a7a",3766:"4db682c6",4005:"6dcb5e16",4125:"ef726b40",4301:"f2e157d0",4707:"331badc5",4814:"6e34a484",4858:"d638c601",5069:"28bc9864",5118:"e10cd13d",5296:"79474bae",5364:"cc2e94c0",5650:"41eb5a6a",5731:"65a9ed9e",5768:"2d971abe",6107:"54fcde43",6224:"5109d3ad",6346:"8ff31131",6708:"3b749ca6",6746:"95c53987",6770:"72b43be8",6815:"3b86d751",7083:"dfcc4619",7089:"b114f501",7283:"72106d8f",7403:"a4cd78b5",8016:"39ac5a41",8113:"68730730",8209:"01a85c17",8256:"106a38e1",8456:"ef646837",8595:"f1a6c2e6",8694:"f1c6b7a3",8816:"a9707311",8979:"cd948886",9113:"b3a49b92",9396:"b7a2b993",9460:"a0ccdbb2",9603:"c474c2b1",9636:"cf3029ea",9647:"5e95c892",9867:"01db17fe",9950:"4a522ab0",10124:"3619739c",10419:"53dc618d",10910:"65cd111b",11187:"340c2365",11208:"372c0574",11378:"bcd2587d",11433:"ee94176e",11567:"22dd74f7",11573:"04a0dcd6",11595:"158765df",11894:"4e4df367",11904:"e939f825",11926:"d0a8493b",11969:"eb1cd7f2",12059:"603aca9e",12250:"056155c0",12418:"9116852a",12455:"915d90e1",12478:"42744730",13e3:"7b8da7d8",13215:"2063472f",13509:"116fa82a",13580:"4cc75cd6",13828:"a72bcf22",13986:"98d1a471",14235:"5db8b942",14425:"c377dc4a",14910:"b8f04a6b",15087:"7effaf45",15196:"e2509bb6",15211:"b70624a2",15255:"3724f9ed",15338:"459c4db6",15680:"3e796ac9",15819:"21ae0e7e",16044:"a81b7004",16087:"64899cf9",16265:"a1868598",16512:"a2874f18",16666:"faf2a93e",16871:"63925da8",16938:"c52eaa26",16986:"ce3d5a4b",17201:"4423d65b",17287:"62569fa7",17438:"9c780b1a",17636:"d7fae98e",17832:"d0616161",18132:"90efbb16",18155:"fef6ab33",18193:"5f241059",18401:"17896441",18621:"4d118a4e",18663:"cacd3f19",18723:"cbe8101d",18794:"2cb8ed3d",19025:"6520db96",19044:"ad15c07f",19179:"fd967833",19356:"0b8cc739",19635:"134a9ec2",19744:"5b38c543",19751:"9dd9d4ea",20367:"9b70ce79",20884:"a434b528",21261:"63d4ce07",21418:"aefd42fa",21421:"a7e0ea76",21672:"dd04b75e",22107:"72c6e609",22473:"9ee7887a",22510:"baabe181",22527:"e45056bc",22743:"38296185",22748:"ed267fba",23127:"3a9d2720",23471:"56ad65de",23919:"46c04ff3",23963:"4732c0e2",24035:"5497691c",24054:"277b6be0",24198:"bb9db0dd",24281:"473a077c",24439:"814e64cc",24643:"0bd3b317",24682:"f74078f7",24907:"8675f5af",24972:"241f36ed",25005:"396a697c",25120:"57d593f0",25210:"af1112c6",25235:"5e5b712e",25458:"a40a2cf8",25465:"9acc619b",25751:"e4d870e1",25959:"24433f15",26220:"241648bf",27167:"13f7cbc7",27207:"cad9fd36",27675:"ab991e0e",27686:"411a45a4",27832:"aee0fe92",27837:"861e5e13",27865:"f0563fee",27927:"5cf40dea",27941:"2ac03470",28114:"19b85f8d",28548:"d3ef4614",28579:"0753c93f",28626:"3ac85609",28727:"738a6ad4",28729:"705e93ef",28801:"3a98aaad",28875:"8833ab21",29040:"87867a42",29080:"eff21157",29155:"23e022aa",29408:"4832c6fe",29574:"cd8c5c3b",29861:"555a4473",30123:"b0b03333",30247:"9cd0819b",30286:"bafead24",30471:"5168ee15",30529:"08af526d",30605:"f5c04343",30635:"04f8200d",30666:"3aaf2bfb",30670:"f71fe95d",30898:"821dc1e3",31089:"ae470ddc",31180:"2b8e251b",31458:"2668f34f",31630:"f1245771",31725:"8fcee16d",31973:"4ab63648",31997:"e2f5312b",32072:"51ce653c",32154:"3c9a8a22",32446:"680b7fa9",32670:"75de5623",32686:"449bc0d9",32748:"130631d9",32831:"e7589c2a",32985:"c00ffc57",33341:"cf35294f",33697:"64c09e2e",34008:"202767e6",34191:"43fd3112",34346:"59b77803",34555:"df5bc763",34635:"3362155c",34684:"03c6d9c7",34846:"c4561df8",35378:"ad0b296a",35496:"a30e2bb0",35559:"d279fdce",35569:"acee0a96",35580:"dc1c4417",35742:"aba21aa0",35774:"5eb62c95",35808:"c8e4da00",35890:"c0299000",36091:"8c0ead1f",36139:"381391cb",36194:"40078125",36337:"a6c56441",36476:"bc4bfdf0",36595:"2bd0ed90",36920:"ed772d97",37057:"cc84b9e4",37639:"ca962d2e",37643:"a6aa9e1f",37667:"76a75fbd",37802:"2c04116d",37832:"6bed00f2",38061:"0bb2dbe9",38631:"33a9c3bd",38656:"631bdc93",38749:"dbfc4782",39126:"6474e148",39238:"6318ac72",39457:"9cb749bd",39468:"5496fb16",39687:"b3b8c5cb",39902:"78c66fad",40145:"50c21d96",40229:"e238c115",40414:"8d90c7e3",40558:"931ecaed",40793:"7607f1d5",40871:"5c3f78ae",41156:"d81ba6be",41408:"a811e42c",41865:"9ec4e3de",42081:"280f0f40",42587:"8dd9adb4",43019:"ac361b55",43445:"dcb4c613",43852:"89d896be",43886:"e068c333",43979:"60d3a705",43990:"b36f50d3",44123:"c34be5c7",44479:"a3e473b3",44683:"1b312e15",44690:"b9ffcd07",44771:"9a38f23f",45140:"fb904585",45647:"56ffdb25",45742:"c377a04b",45884:"0c098c15",46046:"6043c3f4",46088:"8f27be43",46109:"358cf6da",46198:"46206018",46453:"a55b9639",46607:"e5493a21",46724:"afa6d836",46736:"b71ecf14",46879:"c95e6d8d",46928:"4d4c05c4",46988:"c9db186d",47740:"051b98e7",48425:"53d095ec",48426:"79d896a3",48562:"0ac4e675",48631:"fe0242b1",48916:"7cff47a5",49065:"d94d6bbe",49105:"3d262e04",49314:"a4ae8417",49392:"20f436ec",49529:"8d81394c",49540:"32dd135c",49546:"4d355c12",49900:"02627fb8",50140:"34b086e1",50196:"de33ad21",50453:"a4046515",50620:"871da383",50867:"33fc5bb8",50889:"12e95288",50899:"106b67a5",51434:"eacea541",51561:"e3f9a068",51625:"86b0038a",51627:"b687a817",51721:"7ce91694",51968:"befad559",52048:"be0df356",52071:"58718032",52112:"d48191b6",52296:"c45e62e7",52321:"5ce0f216",52349:"3bf1ce3c",52512:"c74094f8",52684:"d477c291",52711:"9e4087bc",52905:"0791978c",53025:"ce0e1dbb",53101:"236eb0f0",53265:"9c5b6467",53307:"dfbc8a55",53337:"5ed91ab5",53462:"18b84202",53540:"028247bf",53829:"9d275d72",54041:"0b3fc8e9",54635:"5c08a95a",54766:"a6efe0e1",54939:"fb804d1c",55157:"a9deb425",55592:"f070a991",55664:"a53bd891",55732:"830e9e14",55740:"a36dca7d",55789:"fd661beb",55844:"4fdb6df3",56215:"60fa9972",56365:"168da062",56474:"68ccb7f6",57033:"f776c06c",57320:"398cf21c",57356:"1871ac35",57366:"0ae07240",57371:"5b827590",57753:"5f02ec4e",57795:"124873a8",57797:"b8ef17b7",57915:"cdd6a56c",58061:"3669623c",58190:"362368d5",58204:"e2975a84",58728:"7708241d",58889:"d050b476",59029:"5e9306ee",59081:"cb63487a",59387:"77c92c8c",59672:"3fe76c6c",59683:"f69b951d",59756:"ab246697",59784:"e15566cb",59895:"99a13742",59941:"197196c4",60173:"86ae953a",60200:"74d57d33",60202:"e1e5af17",60505:"cb447cb9",60570:"5a6ba1cd",60642:"9ed00072",60710:"77395f9a",60781:"c10b8a9f",61109:"2fe2b30f",61153:"f88cb658",61368:"a03c4947",61393:"19770ceb",61418:"e08eef46",61669:"c0def98a",61767:"b15d29cb",62021:"f1f89c2e",62138:"1a4e3797",62287:"c8eb2c38",62289:"074e7bdc",62604:"31e8518f",62958:"b46ec474",63055:"56aa8058",63144:"87f5bee7",63485:"40c07125",63530:"b7cc26e1",63781:"89c22482",63894:"650a8fc0",64097:"8e1fd569",64212:"621db11d",64325:"be5e85f4",64358:"7f115b1f",64643:"94f643bb",64805:"2c27a7b4",64894:"cbe09f13",64917:"52927c97",64932:"41e7d56e",65059:"5d4e9672",65282:"e8b40bee",65409:"5a3b84ba",65438:"38ff73e5",65610:"d8c709f8",65710:"6ceb2263",65845:"cfcbd284",65951:"1966dde1",66221:"977c8faa",66247:"d7289626",66476:"20e65df1",66481:"ea0474c4",66552:"2ffce966",66607:"bf5bbaf8",66623:"c2a48fdb",66784:"d49dddd4",67098:"a7bd4aaa",67110:"ef7672e3",67205:"a4f8fe7e",67280:"ac16ac20",67440:"77981a3a",67461:"ae5d26cf",67472:"814f3328",67796:"64959b1e",67840:"8768801e",67876:"f95b1f88",67880:"387aabc2",67920:"56fae639",67935:"c7d46fe1",68013:"ea921b39",69210:"c9d52fc5",69457:"4ba3ceff",69749:"8323e0f5",69918:"dd908370",69940:"5a22b142",70186:"3d90f760",70246:"a2ea0fe7",70687:"61415b83",70715:"ef2abd7e",70720:"dd93ee27",70956:"35a4f7b3",71049:"285c66e7",71451:"d06ee05c",71512:"aa162190",71914:"576e11bb",72028:"7e55f6e6",72033:"38b4dbd3",72035:"897e9cb3",72067:"eaba5dd2",72305:"a4b0daeb",72352:"0dea8207",72646:"46e94768",72702:"1e144f6d",72753:"efd01d75",73027:"521a6610",73030:"4cc44e19",73213:"2fb5589e",73421:"f8743170",73621:"d02d0f51",73793:"72cc2261",73820:"7366a28d",73846:"d80df429",73931:"533ebf6b",74096:"bb037852",74192:"f2779c45",74280:"21d2c26c",74374:"4c91363f",74428:"b192e983",74541:"d8ae3676",74586:"2e4bdb60",75096:"85b8bb26",75250:"d0c6c99a",75418:"3a5d5492",75631:"8d265689",75687:"72a89de8",75721:"ad7eda35",75727:"c9f0fdac",75932:"f224ad82",75941:"0b20c33e",76163:"7ade0b2a",76214:"a3c7ece8",76444:"51719dea",76568:"7ce4a62a",76749:"094b4aff",76958:"6e2737c0",76971:"c5f06d44",77394:"e289ead3",77533:"ed3af4a0",77543:"55568807",77675:"31dbaea7",77772:"98df448b",78114:"044f7961",78263:"433fdaab",78445:"bfb3244a",78540:"a6957975",78848:"a833d846",79041:"ee7c1cc7",79048:"a94703ab",79235:"a9f5564d",79293:"af050a36",79378:"03acd2fb",79596:"c37f176d",79899:"261dbd4a",80277:"f2a77c75",80372:"b70225e0",80526:"1b0eecbc",80529:"c380abc4",80690:"56746dcb",80724:"175e85c1",80852:"962c96ee",80885:"05a3aa78",80957:"c141421f",81515:"3aa29420",81574:"560adf9d",81801:"b67f60dc",81818:"28b5b925",81903:"acecf23e",82270:"ce6605d8",82399:"4ed7ac06",82447:"14620e15",82487:"00935d0c",82677:"d13dc577",82697:"58092c27",82720:"4545390c",82858:"f46d6e59",83184:"3d9ade7d",83249:"ccc49370",83297:"709dfa47",83317:"947e950c",83495:"d7f9f727",83627:"57f923a9",84063:"f203f57a",84110:"6a307077",84259:"76839fc0",84336:"b8c8445c",84391:"eeb3740b",84457:"ad727d36",84813:"6875c492",84891:"26f7e8fd",84941:"d220dcab",85240:"52ab49a5",85354:"d2039ef8",85552:"0904ce24",85833:"727f767d",86121:"c2728190",86233:"c691959f",86486:"ce6fe363",86547:"c3308ba6",86660:"d629d828",86898:"1c694ffb",87013:"ac9a16c0",87174:"471ca6e4",87375:"4804492c",87446:"96fcb421",87559:"3efe71e8",87746:"15ce11b3",87903:"480fa8f7",87914:"64733a41",87915:"80e6044e",88344:"25f19435",88652:"7b1c3c68",88668:"7850177d",89078:"9b0d9b67",89109:"452e65d7",89349:"f3bf6984",89858:"36994c47",90236:"12984b65",90398:"a35afcc3",90613:"a024ab51",90616:"b0e8b9d5",91035:"ad591877",91415:"10dd5949",91535:"7c798d59",91651:"546b5549",91741:"2cc4f81c",91961:"31722bc4",92152:"5364a150",92218:"a80f26d4",92275:"52fa5650",92381:"9c6aa8d2",92709:"212aab5d",92799:"db24aef0",92805:"4bf77031",92986:"aafbba97",93100:"a3dc4ae2",93226:"5979a0ec",93253:"017e616b",93422:"d92b4d08",93469:"4e8b7bcc",93552:"481163ce",93586:"03aa8e23",93632:"157e4bc2",93708:"bd7d26b2",93920:"41905acb",94225:"ba0fa3fe",94338:"7bf3b0fc",94426:"08996e66",94490:"8154f86c",94491:"772d3db3",94531:"1cd8ca26",94552:"905c7445",94557:"dc5e10d3",94686:"559dc838",94889:"65961da4",94912:"01be152e",94998:"26a33332",95283:"80510dbd",95469:"8941358f",95712:"4e015808",95773:"7feecbc1",95875:"f6320c57",95882:"9a508619",96167:"b7708f1e",96232:"6193b30e",96325:"e605c6b3",96342:"6245c126",96379:"d4c529d3",96578:"e5afa1a3",96590:"5052751d",96755:"870de909",96962:"c19e69a7",97267:"abd56c27",97419:"ca7245df",97491:"0cde4ba3",97575:"eb0d94ae",97816:"3ce1a06b",97937:"7c67ea25",98069:"5611a8f0",98183:"5c07109c",98455:"c10cfbfe",98471:"6c606038",98806:"10ab4195",98950:"6fe126b9",98953:"053d5d89",99218:"b1eae65b",99303:"e2799c63"}[e]||e)+"."+{240:"115a3c11",280:"5fb4114d",414:"1f2d7217",503:"4b956a66",566:"1ebdf3ec",699:"046ff0c7",712:"9501e9bc",1093:"bdc45b5b",1130:"e264dcdb",1381:"b8aa7d80",1790:"669096ae",1867:"4cf4a84d",1971:"d0182770",1991:"36ed403d",2119:"ca8d966e",2306:"eb912000",2407:"1d93cdbb",2714:"5e787011",2810:"780b66ed",2996:"b7c5f244",3048:"f489e4cb",3155:"19cbf1ee",3347:"f799bb61",3428:"bd7e11c9",3568:"06a0c1d8",3766:"25cb8a9e",4005:"631ecf42",4125:"2fca8d33",4301:"d49d6620",4707:"26951b81",4814:"df202898",4858:"15664957",5069:"246d5f11",5118:"5aff8aea",5296:"a5a4db28",5364:"b91d5649",5650:"25e46683",5731:"3fe3d223",5768:"1121b1e3",6107:"7c8f527d",6224:"4be6508a",6346:"13194bde",6708:"12e4a5ed",6746:"293de8d0",6770:"3923b0c1",6815:"aaac82d9",7083:"c764dc8b",7089:"3335785a",7283:"bdea1c52",7403:"e215ea72",8016:"0cb58650",8113:"64e6198a",8209:"f0d674b1",8256:"08a834c1",8456:"20fafc7e",8595:"30426d72",8694:"dd24385f",8816:"4c91be6f",8979:"5aed8c76",9113:"cbe25f10",9396:"47bcf617",9460:"9cb4eb73",9462:"9d10cf9f",9603:"b1dce14d",9636:"f454004c",9647:"e9a6d627",9867:"4fe78b51",9950:"74a2f484",10124:"59a850b5",10419:"924994dd",10910:"9f4c0cef",11187:"f9fb5495",11208:"041c94fa",11378:"f268cb4c",11433:"42f353c4",11567:"e428a829",11573:"f1fd239f",11595:"0818e83f",11894:"6b2bf3f2",11904:"436c9fa9",11926:"8611e4aa",11969:"1282bdde",12059:"d3942f34",12250:"abd058a6",12418:"695b9cf3",12455:"6837c1e2",12478:"53821c1f",13e3:"8db3e644",13215:"3db4a69b",13509:"4ab1633b",13580:"c5db8ce8",13828:"e9c31f44",13986:"222d0cf9",14235:"1835e546",14425:"607514a8",14910:"619e6ba5",15087:"b7576d51",15196:"6b2e5db8",15211:"df42b3c0",15255:"5eafca9c",15338:"5ba5952e",15680:"77cf76db",15819:"b7e7da29",16044:"614649de",16087:"892e78a4",16265:"e4c98816",16512:"02b183f5",16666:"5f4fcdac",16871:"5e258b77",16938:"dc4744b9",16986:"69e5cefd",17201:"43623fa8",17287:"4c155b8f",17438:"7540caa7",17636:"1349e043",17832:"a6c02aa2",18132:"eca6bbe3",18155:"746d8b52",18193:"4b623e89",18401:"a80fb57c",18621:"26672722",18663:"fb6d7d41",18723:"7596f688",18794:"cd46c6fa",19025:"0f7b780d",19044:"89ebc550",19179:"84a1d37c",19356:"11d60f3d",19635:"0ccdf24e",19744:"7266d270",19751:"3a5f592e",20367:"bc96c9f0",20884:"8590c09f",21261:"2ce275cd",21418:"55d4578e",21421:"d1f0fa4d",21672:"3463f4df",22107:"3cf437f8",22473:"3c988df8",22510:"1d890051",22527:"816736bc",22743:"4a41b532",22748:"6c0f909a",23127:"81ccdd66",23471:"fcda7351",23919:"202aa580",23963:"3853b69c",24035:"7a0da876",24054:"0f968348",24198:"83c0a3cb",24281:"eb7aa5a0",24439:"3ab7cd73",24643:"a7a76776",24682:"5b44140b",24907:"bfe5a528",24972:"20e39934",25005:"6fa30002",25120:"9081b32b",25210:"45aa0929",25235:"6e7d89b9",25458:"a2747ba0",25465:"fdbf2c17",25751:"abd2b6f0",25959:"4be389a9",26220:"39c48090",27167:"8e07b7af",27207:"a362a2cd",27675:"afb1898b",27686:"bfced875",27832:"50fa9bd5",27837:"e59049a7",27865:"df8d1b93",27927:"940a452c",27941:"9c632600",28114:"9543118f",28548:"1ecc7dd0",28579:"c3fc9760",28626:"12ab7143",28727:"df968aee",28729:"e6ce9050",28801:"38c11bd1",28875:"2f4414a2",29040:"4e487d7d",29080:"d54a2b5c",29155:"9f08479d",29408:"829d1c30",29574:"2df6b353",29861:"fbed11b1",30123:"557020ef",30247:"647896eb",30286:"e60d55cc",30471:"9f3c0d6d",30529:"864924c4",30605:"715b43d2",30635:"5228b822",30666:"b2e73a42",30670:"9ad08d80",30898:"07ce4564",31089:"47363dbf",31180:"baf2f328",31458:"8cbf8a64",31630:"8a14c444",31725:"27cfe3cc",31973:"4c995b82",31997:"d4f136f1",32072:"dc35e1ca",32154:"cbde2a2a",32446:"83815de4",32670:"515b1f12",32686:"ed4526e9",32748:"5fa36173",32831:"a8005701",32985:"c6e16365",33341:"5c7a277d",33697:"fa6ac55d",34008:"650f5669",34191:"e7439ebf",34346:"fd87f57e",34555:"577a5deb",34635:"2951497f",34684:"4f0c8d42",34846:"e426f1f3",35378:"459bbd0d",35496:"db4101ac",35559:"312ed6b1",35569:"3b8121a3",35580:"31cadd38",35742:"1ae003ba",35774:"f9ba076c",35808:"377067a0",35890:"60ccb8d1",36091:"ef689526",36139:"289be185",36194:"92fe6e66",36337:"56418c50",36476:"6b70cee0",36595:"2b52c78d",36920:"ff32e5f5",37057:"a97ce4c6",37639:"fb46012c",37643:"4977cbdf",37667:"8393010c",37802:"a32622f9",37832:"4b14e37a",38061:"25561148",38631:"2116c2c6",38656:"abd03f43",38749:"400f41c7",39126:"f34dd9c3",39238:"262b8dce",39457:"a84526b3",39468:"e37b2d67",39687:"66ba977e",39902:"28feae2f",40145:"c39e8686",40229:"03c04108",40414:"28b4caa2",40558:"28170080",40793:"d4ae0eb6",40871:"1c8dc26f",41156:"98f8f400",41408:"6d7c6526",41865:"88035139",42081:"42bc3e47",42587:"f35c58e4",43019:"023b05ee",43445:"333717ee",43852:"164f310b",43886:"4084d666",43979:"8959a6ed",43990:"ce29c971",44123:"a0d52e84",44479:"b3680e8e",44683:"3da2e07f",44690:"a7d11053",44771:"5bb7b4cd",45140:"9a2467f1",45647:"995afe37",45742:"d0facf52",45884:"9fdd6a6d",46046:"9b2ce9e7",46088:"ca74fdf7",46109:"50a774a3",46198:"718b2b19",46453:"bcfdb692",46607:"b67e196f",46724:"e95ff699",46736:"1d11eac0",46879:"9669f9e6",46928:"06123333",46988:"fb5fa52a",47740:"8a9171cd",48425:"27dbcfb8",48426:"09570395",48562:"f7475e94",48631:"4ee542a5",48916:"24df3477",49065:"5f51f6b7",49105:"8ce8efde",49314:"5511ae65",49392:"d9cf2a40",49529:"8dfe83fc",49540:"45237611",49546:"2357dd50",49900:"7d16ba66",50140:"d56022ae",50196:"8fafd612",50453:"c01a629a",50620:"0bff42d1",50867:"1380a971",50889:"283682c6",50899:"5be98423",51434:"713b9738",51561:"ee51fe72",51625:"ae57b7f1",51627:"353ec7bd",51721:"521657b2",51968:"50157083",52048:"4be5fb84",52071:"68396545",52112:"092d048f",52296:"265d09b1",52321:"5f134790",52349:"e158e2c3",52512:"c3dcc644",52684:"e950cbd2",52711:"426382ea",52905:"8b8ea331",53025:"a2815888",53101:"5852e7f6",53265:"3d86687a",53307:"270b4583",53337:"744eaccf",53462:"39914aaa",53540:"b7389543",53829:"0b08718a",54041:"ce7a5cab",54635:"26a3ecb2",54766:"f66fc475",54939:"8135cc99",55157:"4b3ac4cb",55592:"984951c4",55664:"07818a14",55732:"801017c6",55740:"ea67c2e6",55789:"9306c892",55844:"3ae7fba2",56215:"532892dc",56365:"e84c3ca9",56474:"22bc5312",57033:"6260625f",57320:"1c69896e",57356:"4fb85a4c",57366:"2f1af85d",57371:"e6f4f0a7",57753:"25f504ac",57795:"ea47be98",57797:"802d36c5",57915:"a344a0d7",58061:"b2f466b1",58190:"b933ef02",58204:"51a6b884",58728:"c2fc2488",58889:"240ce090",58913:"6eee2a6e",59029:"39afcc18",59081:"7cab35d9",59387:"228a09d7",59672:"09dd3645",59683:"a8eed262",59756:"e9ff96c3",59784:"26ef38f0",59895:"82691f99",59941:"10c851c2",60173:"101fb2af",60200:"872e0d5f",60202:"a55d48e0",60505:"2ecfdbd1",60570:"fa112277",60642:"851b8b22",60710:"d869d436",60781:"f9001f93",61109:"134c1dc9",61153:"93e9da43",61368:"b024c0ac",61393:"85de565a",61418:"c3b1a795",61669:"5774eed0",61767:"755d6cd9",62021:"2e307f65",62138:"87166043",62287:"d5c12a00",62289:"1512fa35",62604:"78747659",62958:"8b17c0c3",63055:"bdb374f9",63144:"11d7c141",63485:"b0d71ef3",63530:"2bfdb498",63781:"b950b66f",63894:"fcb9962e",64097:"89ba8087",64212:"72d8a767",64325:"e6fa4137",64358:"08f8427a",64643:"0ffdacc0",64805:"dfdad9af",64894:"b56f8a87",64917:"de1bbc11",64932:"3c81128b",65059:"604f7974",65282:"16146a5b",65409:"63717aa0",65438:"a2c2ca1e",65610:"5f79bc8f",65710:"4869c915",65845:"63fc464b",65951:"2677b260",66221:"143671f7",66247:"35d9a384",66476:"58813634",66481:"f097486d",66552:"32a561e7",66607:"13f23cdc",66623:"aa595378",66784:"766c61f5",67098:"f6bd7d37",67110:"34f0b8af",67205:"83f1a268",67280:"7b905f4c",67440:"5c6f062e",67461:"38358f39",67472:"42442acd",67796:"2d006066",67840:"c7c6d258",67876:"2c0ea01f",67880:"5dc9fb8c",67920:"036d3ba6",67935:"c6ccb6de",68013:"308e6c57",69210:"95b1b5e6",69457:"081c4b34",69749:"8ddff4c3",69918:"b6499474",69940:"b646e6c0",70186:"85ca88d2",70246:"f73f7874",70687:"6de3dfdc",70715:"4f00923b",70720:"c6c59160",70956:"f6ca0fad",71049:"2cc1f187",71451:"4fae27bd",71512:"42fe6ae5",71914:"b19d9462",72028:"80a4eced",72033:"7e645026",72035:"4f6ab0e4",72067:"a045f2ae",72305:"2b9391ae",72352:"469d8eba",72646:"dab245b0",72702:"3fce115e",72753:"02a4a077",73027:"546443b5",73030:"7d979e88",73213:"7b8c9375",73421:"a30916fe",73621:"fff99507",73793:"0d29617c",73820:"4e7c9bfa",73846:"d3c78300",73931:"d593cda4",74096:"08cf4bca",74192:"1985fa4b",74280:"34fe9668",74374:"93a6ede3",74428:"9d48f4fd",74541:"ed256976",74586:"94cd32d7",75096:"306e91f8",75250:"e6fa3b5a",75418:"d650666a",75631:"b6706ec9",75687:"adc4dd3e",75721:"6b9ae2e7",75727:"8d113f91",75932:"becdd6c1",75941:"4baa51ac",76163:"9718930e",76214:"5621f945",76444:"65346675",76568:"76742a6b",76749:"6cc550cf",76958:"fc64a7ef",76971:"f6b77b6b",77394:"b2eba89f",77533:"611178a8",77543:"da999a9a",77675:"4f18e31a",77772:"4dbc3804",78114:"a5cca8cf",78263:"7d8c5d7c",78445:"0a60faf8",78540:"4b06c94e",78848:"fbb45413",79041:"acd77737",79048:"6d07f677",79113:"6a88e948",79235:"7ae89e3b",79293:"f22df805",79378:"9a8b2e6c",79596:"38ea646e",79899:"98bcfe9f",80277:"4e76bee9",80372:"6b9ec728",80526:"03a68f28",80529:"9161c3a0",80690:"51ad8181",80724:"ae48dd54",80852:"fd744aa5",80885:"7bddfc8e",80957:"4ae5844e",81515:"3264772a",81574:"05f652ff",81801:"9c1e5109",81818:"0cbd1f9b",81903:"1d924b0f",82237:"082e051d",82270:"702f3687",82399:"e7cc3604",82447:"e55ff3e7",82487:"4467c113",82677:"5be46c79",82697:"8c31d248",82720:"1d3a08c0",82858:"b998f248",83184:"23253525",83249:"78b27ccb",83297:"969b3e76",83317:"16603b98",83495:"baf34cdc",83627:"f57d37c0",84063:"c10ab2eb",84110:"880239fa",84259:"2942aa34",84336:"2da23794",84391:"7aca9b4d",84457:"001c91d8",84813:"b5181e60",84891:"9da42033",84941:"d1c22622",85240:"7e1e13d0",85354:"e3054ff4",85552:"a293aebe",85833:"5bc07a55",86121:"c9436c76",86233:"300edfdd",86486:"8c36f3f4",86547:"425334c7",86660:"9452bae9",86898:"e2c21c8e",87013:"8245bc52",87174:"fc8efafc",87375:"9bff2638",87446:"99cb328e",87559:"3d46f3c7",87746:"3da7da11",87903:"75e26ad2",87914:"aa5d15dd",87915:"be8973b1",88344:"f0517f89",88652:"2f0f9401",88668:"e012839f",89078:"d0cc04c6",89109:"1de256df",89349:"d6d4b2c7",89858:"ce48ef1d",90236:"704e4746",90398:"76af9ebf",90416:"140f33a2",90613:"21c9b95c",90616:"48be246d",91035:"cf7047e7",91415:"d7da3af3",91535:"a338572d",91651:"3f31a8ae",91741:"309d1501",91961:"8b17745a",92152:"134445fe",92218:"8ef94877",92275:"deb039aa",92381:"a5007e66",92709:"5eef133e",92799:"7be66191",92805:"6626d6ed",92986:"d6419f85",93100:"ee951085",93226:"621162c0",93253:"8ebc0779",93422:"d98a3927",93469:"d320f421",93552:"cef26660",93586:"2c61f65f",93632:"7b9ed566",93708:"4f702e53",93920:"2fa671b8",94225:"45f877c7",94338:"dec4d3c2",94426:"45d2a303",94490:"6126d122",94491:"5265c340",94531:"cbdbeb37",94552:"20605116",94557:"7935911a",94686:"8f1fde69",94889:"2834b925",94912:"b1fca991",94998:"6303f856",95283:"8f6dc460",95469:"e38b3228",95712:"64ad3dfe",95773:"0bd89ed5",95875:"a7d30f9d",95882:"234da57e",96167:"2b3f2d3b",96232:"8d7754ae",96325:"e7d9d88b",96342:"8cf7cbff",96379:"d2c5e7bd",96578:"435be811",96590:"2ecba4e7",96755:"24484384",96962:"9d2442b7",97267:"10b1808e",97419:"76e3b27d",97491:"766b9399",97575:"4b8f7e24",97816:"08bdbb80",97937:"976f293e",98069:"95614330",98183:"9dc5bbd3",98455:"2a9f53c2",98471:"a21110c8",98806:"ee7630a9",98950:"e52a98b9",98953:"4f2907f5",99218:"e24179ba",99303:"caf45662"}[e]+".js",r.miniCssF=e=>{},r.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),r.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),d={},b="cspr-docs:",r.l=(e,a,c,f)=>{if(d[e])d[e].push(a);else{var t,o;if(void 0!==c)for(var n=document.getElementsByTagName("script"),i=0;i<n.length;i++){var u=n[i];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==b+c){t=u;break}}t||(o=!0,(t=document.createElement("script")).charset="utf-8",t.timeout=120,r.nc&&t.setAttribute("nonce",r.nc),t.setAttribute("data-webpack",b+c),t.src=e),d[e]=[a];var l=(a,c)=>{t.onerror=t.onload=null,clearTimeout(s);var b=d[e];if(delete d[e],t.parentNode&&t.parentNode.removeChild(t),b&&b.forEach((e=>e(c))),a)return a(c)},s=setTimeout(l.bind(null,void 0,{type:"timeout",target:t}),12e4);t.onerror=l.bind(null,t.onerror),t.onload=l.bind(null,t.onload),o&&document.head.appendChild(t)}},r.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.p="/",r.gca=function(e){return e={17896441:"18401",38296185:"22743",40078125:"36194",42744730:"12478",46206018:"46198",55568807:"77543",58718032:"52071",68730730:"8113","9afe1d3d":"240",eb5a6cc0:"280","1b2f0a70":"414","09278318":"503","7cf62e8d":"566","8de9f24f":"699","3db2ed27":"712",ebb9a3ce:"1093","64bdcaf3":"1130","06c1e821":"1381","753d7b98":"1790","76ea157b":"1867","0fa7e001":"1971","43a834ef":"1991","862f9df3":"2119","2a21571b":"2306","90f2be13":"2407","35808b61":"2714","1e2c8091":"2810",baf71301:"2996","883310e5":"3048","3a19cb34":"3155",b415f00a:"3428","26ab9a7a":"3568","4db682c6":"3766","6dcb5e16":"4005",ef726b40:"4125",f2e157d0:"4301","331badc5":"4707","6e34a484":"4814",d638c601:"4858","28bc9864":"5069",e10cd13d:"5118","79474bae":"5296",cc2e94c0:"5364","41eb5a6a":"5650","65a9ed9e":"5731","2d971abe":"5768","54fcde43":"6107","5109d3ad":"6224","8ff31131":"6346","3b749ca6":"6708","95c53987":"6746","72b43be8":"6770","3b86d751":"6815",dfcc4619:"7083",b114f501:"7089","72106d8f":"7283",a4cd78b5:"7403","39ac5a41":"8016","01a85c17":"8209","106a38e1":"8256",ef646837:"8456",f1a6c2e6:"8595",f1c6b7a3:"8694",a9707311:"8816",cd948886:"8979",b3a49b92:"9113",b7a2b993:"9396",a0ccdbb2:"9460",c474c2b1:"9603",cf3029ea:"9636","5e95c892":"9647","01db17fe":"9867","4a522ab0":"9950","3619739c":"10124","53dc618d":"10419","65cd111b":"10910","340c2365":"11187","372c0574":"11208",bcd2587d:"11378",ee94176e:"11433","22dd74f7":"11567","04a0dcd6":"11573","158765df":"11595","4e4df367":"11894",e939f825:"11904",d0a8493b:"11926",eb1cd7f2:"11969","603aca9e":"12059","056155c0":"12250","9116852a":"12418","915d90e1":"12455","7b8da7d8":"13000","2063472f":"13215","116fa82a":"13509","4cc75cd6":"13580",a72bcf22:"13828","98d1a471":"13986","5db8b942":"14235",c377dc4a:"14425",b8f04a6b:"14910","7effaf45":"15087",e2509bb6:"15196",b70624a2:"15211","3724f9ed":"15255","459c4db6":"15338","3e796ac9":"15680","21ae0e7e":"15819",a81b7004:"16044","64899cf9":"16087",a1868598:"16265",a2874f18:"16512",faf2a93e:"16666","63925da8":"16871",c52eaa26:"16938",ce3d5a4b:"16986","4423d65b":"17201","62569fa7":"17287","9c780b1a":"17438",d7fae98e:"17636",d0616161:"17832","90efbb16":"18132",fef6ab33:"18155","5f241059":"18193","4d118a4e":"18621",cacd3f19:"18663",cbe8101d:"18723","2cb8ed3d":"18794","6520db96":"19025",ad15c07f:"19044",fd967833:"19179","0b8cc739":"19356","134a9ec2":"19635","5b38c543":"19744","9dd9d4ea":"19751","9b70ce79":"20367",a434b528:"20884","63d4ce07":"21261",aefd42fa:"21418",a7e0ea76:"21421",dd04b75e:"21672","72c6e609":"22107","9ee7887a":"22473",baabe181:"22510",e45056bc:"22527",ed267fba:"22748","3a9d2720":"23127","56ad65de":"23471","46c04ff3":"23919","4732c0e2":"23963","5497691c":"24035","277b6be0":"24054",bb9db0dd:"24198","473a077c":"24281","814e64cc":"24439","0bd3b317":"24643",f74078f7:"24682","8675f5af":"24907","241f36ed":"24972","396a697c":"25005","57d593f0":"25120",af1112c6:"25210","5e5b712e":"25235",a40a2cf8:"25458","9acc619b":"25465",e4d870e1:"25751","24433f15":"25959","241648bf":"26220","13f7cbc7":"27167",cad9fd36:"27207",ab991e0e:"27675","411a45a4":"27686",aee0fe92:"27832","861e5e13":"27837",f0563fee:"27865","5cf40dea":"27927","2ac03470":"27941","19b85f8d":"28114",d3ef4614:"28548","0753c93f":"28579","3ac85609":"28626","738a6ad4":"28727","705e93ef":"28729","3a98aaad":"28801","8833ab21":"28875","87867a42":"29040",eff21157:"29080","23e022aa":"29155","4832c6fe":"29408",cd8c5c3b:"29574","555a4473":"29861",b0b03333:"30123","9cd0819b":"30247",bafead24:"30286","5168ee15":"30471","08af526d":"30529",f5c04343:"30605","04f8200d":"30635","3aaf2bfb":"30666",f71fe95d:"30670","821dc1e3":"30898",ae470ddc:"31089","2b8e251b":"31180","2668f34f":"31458",f1245771:"31630","8fcee16d":"31725","4ab63648":"31973",e2f5312b:"31997","51ce653c":"32072","3c9a8a22":"32154","680b7fa9":"32446","75de5623":"32670","449bc0d9":"32686","130631d9":"32748",e7589c2a:"32831",c00ffc57:"32985",cf35294f:"33341","64c09e2e":"33697","202767e6":"34008","43fd3112":"34191","59b77803":"34346",df5bc763:"34555","3362155c":"34635","03c6d9c7":"34684",c4561df8:"34846",ad0b296a:"35378",a30e2bb0:"35496",d279fdce:"35559",acee0a96:"35569",dc1c4417:"35580",aba21aa0:"35742","5eb62c95":"35774",c8e4da00:"35808",c0299000:"35890","8c0ead1f":"36091","381391cb":"36139",a6c56441:"36337",bc4bfdf0:"36476","2bd0ed90":"36595",ed772d97:"36920",cc84b9e4:"37057",ca962d2e:"37639",a6aa9e1f:"37643","76a75fbd":"37667","2c04116d":"37802","6bed00f2":"37832","0bb2dbe9":"38061","33a9c3bd":"38631","631bdc93":"38656",dbfc4782:"38749","6474e148":"39126","6318ac72":"39238","9cb749bd":"39457","5496fb16":"39468",b3b8c5cb:"39687","78c66fad":"39902","50c21d96":"40145",e238c115:"40229","8d90c7e3":"40414","931ecaed":"40558","7607f1d5":"40793","5c3f78ae":"40871",d81ba6be:"41156",a811e42c:"41408","9ec4e3de":"41865","280f0f40":"42081","8dd9adb4":"42587",ac361b55:"43019",dcb4c613:"43445","89d896be":"43852",e068c333:"43886","60d3a705":"43979",b36f50d3:"43990",c34be5c7:"44123",a3e473b3:"44479","1b312e15":"44683",b9ffcd07:"44690","9a38f23f":"44771",fb904585:"45140","56ffdb25":"45647",c377a04b:"45742","0c098c15":"45884","6043c3f4":"46046","8f27be43":"46088","358cf6da":"46109",a55b9639:"46453",e5493a21:"46607",afa6d836:"46724",b71ecf14:"46736",c95e6d8d:"46879","4d4c05c4":"46928",c9db186d:"46988","051b98e7":"47740","53d095ec":"48425","79d896a3":"48426","0ac4e675":"48562",fe0242b1:"48631","7cff47a5":"48916",d94d6bbe:"49065","3d262e04":"49105",a4ae8417:"49314","20f436ec":"49392","8d81394c":"49529","32dd135c":"49540","4d355c12":"49546","02627fb8":"49900","34b086e1":"50140",de33ad21:"50196",a4046515:"50453","871da383":"50620","33fc5bb8":"50867","12e95288":"50889","106b67a5":"50899",eacea541:"51434",e3f9a068:"51561","86b0038a":"51625",b687a817:"51627","7ce91694":"51721",befad559:"51968",be0df356:"52048",d48191b6:"52112",c45e62e7:"52296","5ce0f216":"52321","3bf1ce3c":"52349",c74094f8:"52512",d477c291:"52684","9e4087bc":"52711","0791978c":"52905",ce0e1dbb:"53025","236eb0f0":"53101","9c5b6467":"53265",dfbc8a55:"53307","5ed91ab5":"53337","18b84202":"53462","028247bf":"53540","9d275d72":"53829","0b3fc8e9":"54041","5c08a95a":"54635",a6efe0e1:"54766",fb804d1c:"54939",a9deb425:"55157",f070a991:"55592",a53bd891:"55664","830e9e14":"55732",a36dca7d:"55740",fd661beb:"55789","4fdb6df3":"55844","60fa9972":"56215","168da062":"56365","68ccb7f6":"56474",f776c06c:"57033","398cf21c":"57320","1871ac35":"57356","0ae07240":"57366","5b827590":"57371","5f02ec4e":"57753","124873a8":"57795",b8ef17b7:"57797",cdd6a56c:"57915","3669623c":"58061","362368d5":"58190",e2975a84:"58204","7708241d":"58728",d050b476:"58889","5e9306ee":"59029",cb63487a:"59081","77c92c8c":"59387","3fe76c6c":"59672",f69b951d:"59683",ab246697:"59756",e15566cb:"59784","99a13742":"59895","197196c4":"59941","86ae953a":"60173","74d57d33":"60200",e1e5af17:"60202",cb447cb9:"60505","5a6ba1cd":"60570","9ed00072":"60642","77395f9a":"60710",c10b8a9f:"60781","2fe2b30f":"61109",f88cb658:"61153",a03c4947:"61368","19770ceb":"61393",e08eef46:"61418",c0def98a:"61669",b15d29cb:"61767",f1f89c2e:"62021","1a4e3797":"62138",c8eb2c38:"62287","074e7bdc":"62289","31e8518f":"62604",b46ec474:"62958","56aa8058":"63055","87f5bee7":"63144","40c07125":"63485",b7cc26e1:"63530","89c22482":"63781","650a8fc0":"63894","8e1fd569":"64097","621db11d":"64212",be5e85f4:"64325","7f115b1f":"64358","94f643bb":"64643","2c27a7b4":"64805",cbe09f13:"64894","52927c97":"64917","41e7d56e":"64932","5d4e9672":"65059",e8b40bee:"65282","5a3b84ba":"65409","38ff73e5":"65438",d8c709f8:"65610","6ceb2263":"65710",cfcbd284:"65845","1966dde1":"65951","977c8faa":"66221",d7289626:"66247","20e65df1":"66476",ea0474c4:"66481","2ffce966":"66552",bf5bbaf8:"66607",c2a48fdb:"66623",d49dddd4:"66784",a7bd4aaa:"67098",ef7672e3:"67110",a4f8fe7e:"67205",ac16ac20:"67280","77981a3a":"67440",ae5d26cf:"67461","814f3328":"67472","64959b1e":"67796","8768801e":"67840",f95b1f88:"67876","387aabc2":"67880","56fae639":"67920",c7d46fe1:"67935",ea921b39:"68013",c9d52fc5:"69210","4ba3ceff":"69457","8323e0f5":"69749",dd908370:"69918","5a22b142":"69940","3d90f760":"70186",a2ea0fe7:"70246","61415b83":"70687",ef2abd7e:"70715",dd93ee27:"70720","35a4f7b3":"70956","285c66e7":"71049",d06ee05c:"71451",aa162190:"71512","576e11bb":"71914","7e55f6e6":"72028","38b4dbd3":"72033","897e9cb3":"72035",eaba5dd2:"72067",a4b0daeb:"72305","0dea8207":"72352","46e94768":"72646","1e144f6d":"72702",efd01d75:"72753","521a6610":"73027","4cc44e19":"73030","2fb5589e":"73213",f8743170:"73421",d02d0f51:"73621","72cc2261":"73793","7366a28d":"73820",d80df429:"73846","533ebf6b":"73931",bb037852:"74096",f2779c45:"74192","21d2c26c":"74280","4c91363f":"74374",b192e983:"74428",d8ae3676:"74541","2e4bdb60":"74586","85b8bb26":"75096",d0c6c99a:"75250","3a5d5492":"75418","8d265689":"75631","72a89de8":"75687",ad7eda35:"75721",c9f0fdac:"75727",f224ad82:"75932","0b20c33e":"75941","7ade0b2a":"76163",a3c7ece8:"76214","51719dea":"76444","7ce4a62a":"76568","094b4aff":"76749","6e2737c0":"76958",c5f06d44:"76971",e289ead3:"77394",ed3af4a0:"77533","31dbaea7":"77675","98df448b":"77772","044f7961":"78114","433fdaab":"78263",bfb3244a:"78445",a6957975:"78540",a833d846:"78848",ee7c1cc7:"79041",a94703ab:"79048",a9f5564d:"79235",af050a36:"79293","03acd2fb":"79378",c37f176d:"79596","261dbd4a":"79899",f2a77c75:"80277",b70225e0:"80372","1b0eecbc":"80526",c380abc4:"80529","56746dcb":"80690","175e85c1":"80724","962c96ee":"80852","05a3aa78":"80885",c141421f:"80957","3aa29420":"81515","560adf9d":"81574",b67f60dc:"81801","28b5b925":"81818",acecf23e:"81903",ce6605d8:"82270","4ed7ac06":"82399","14620e15":"82447","00935d0c":"82487",d13dc577:"82677","58092c27":"82697","4545390c":"82720",f46d6e59:"82858","3d9ade7d":"83184",ccc49370:"83249","709dfa47":"83297","947e950c":"83317",d7f9f727:"83495","57f923a9":"83627",f203f57a:"84063","6a307077":"84110","76839fc0":"84259",b8c8445c:"84336",eeb3740b:"84391",ad727d36:"84457","6875c492":"84813","26f7e8fd":"84891",d220dcab:"84941","52ab49a5":"85240",d2039ef8:"85354","0904ce24":"85552","727f767d":"85833",c2728190:"86121",c691959f:"86233",ce6fe363:"86486",c3308ba6:"86547",d629d828:"86660","1c694ffb":"86898",ac9a16c0:"87013","471ca6e4":"87174","4804492c":"87375","96fcb421":"87446","3efe71e8":"87559","15ce11b3":"87746","480fa8f7":"87903","64733a41":"87914","80e6044e":"87915","25f19435":"88344","7b1c3c68":"88652","7850177d":"88668","9b0d9b67":"89078","452e65d7":"89109",f3bf6984:"89349","36994c47":"89858","12984b65":"90236",a35afcc3:"90398",a024ab51:"90613",b0e8b9d5:"90616",ad591877:"91035","10dd5949":"91415","7c798d59":"91535","546b5549":"91651","2cc4f81c":"91741","31722bc4":"91961","5364a150":"92152",a80f26d4:"92218","52fa5650":"92275","9c6aa8d2":"92381","212aab5d":"92709",db24aef0:"92799","4bf77031":"92805",aafbba97:"92986",a3dc4ae2:"93100","5979a0ec":"93226","017e616b":"93253",d92b4d08:"93422","4e8b7bcc":"93469","481163ce":"93552","03aa8e23":"93586","157e4bc2":"93632",bd7d26b2:"93708","41905acb":"93920",ba0fa3fe:"94225","7bf3b0fc":"94338","08996e66":"94426","8154f86c":"94490","772d3db3":"94491","1cd8ca26":"94531","905c7445":"94552",dc5e10d3:"94557","559dc838":"94686","65961da4":"94889","01be152e":"94912","26a33332":"94998","80510dbd":"95283","8941358f":"95469","4e015808":"95712","7feecbc1":"95773",f6320c57:"95875","9a508619":"95882",b7708f1e:"96167","6193b30e":"96232",e605c6b3:"96325","6245c126":"96342",d4c529d3:"96379",e5afa1a3:"96578","5052751d":"96590","870de909":"96755",c19e69a7:"96962",abd56c27:"97267",ca7245df:"97419","0cde4ba3":"97491",eb0d94ae:"97575","3ce1a06b":"97816","7c67ea25":"97937","5611a8f0":"98069","5c07109c":"98183",c10cfbfe:"98455","6c606038":"98471","10ab4195":"98806","6fe126b9":"98950","053d5d89":"98953",b1eae65b:"99218",e2799c63:"99303"}[e]||e,r.p+r.u(e)},(()=>{var e={45354:0,71869:0};r.f.j=(a,c)=>{var d=r.o(e,a)?e[a]:void 0;if(0!==d)if(d)c.push(d[2]);else if(/^(45354|71869)$/.test(a))e[a]=0;else{var b=new Promise(((c,b)=>d=e[a]=[c,b]));c.push(d[2]=b);var f=r.p+r.u(a),t=new Error;r.l(f,(c=>{if(r.o(e,a)&&(0!==(d=e[a])&&(e[a]=void 0),d)){var b=c&&("load"===c.type?"missing":c.type),f=c&&c.target&&c.target.src;t.message="Loading chunk "+a+" failed.\n("+b+": "+f+")",t.name="ChunkLoadError",t.type=b,t.request=f,d[1](t)}}),"chunk-"+a,a)}},r.O.j=a=>0===e[a];var a=(a,c)=>{var d,b,f=c[0],t=c[1],o=c[2],n=0;if(f.some((a=>0!==e[a]))){for(d in t)r.o(t,d)&&(r.m[d]=t[d]);if(o)var i=o(r)}for(a&&a(c);n<f.length;n++)b=f[n],r.o(e,b)&&e[b]&&e[b][0](),e[b]=0;return r.O(i)},c=self.webpackChunkcspr_docs=self.webpackChunkcspr_docs||[];c.forEach(a.bind(null,0)),c.push=a.bind(null,c.push.bind(c))})()})(); \ No newline at end of file diff --git a/blog/addressable-entity/index.html b/blog/addressable-entity/index.html index 8702bf131..372bf026f 100644 --- a/blog/addressable-entity/index.html +++ b/blog/addressable-entity/index.html @@ -3,19 +3,19 @@ <head> <meta charset="UTF-8"> <meta name="generator" content="Docusaurus v3.5.2"> -<title data-rh="true">Addressable Entity in Casper 2.0 | Casper Docs - Redux +Addressable Entity in Casper 2.0 | Casper Docs - Redux - - + +

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    + submit an issue on Github

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    Key Concepts

    AddressableEntity

    diff --git a/blog/archive/index.html b/blog/archive/index.html index 185592d2c..ee4048e74 100644 --- a/blog/archive/index.html +++ b/blog/archive/index.html @@ -3,18 +3,18 @@ -Archive | Casper Docs - Redux +Archive | Casper Docs - Redux - - + + + submit an issue on Github
    \ No newline at end of file diff --git a/blog/atom.xml b/blog/atom.xml index acfaade4c..09e673ebc 100644 --- a/blog/atom.xml +++ b/blog/atom.xml @@ -1,33 +1,33 @@ - https://casper-devrel.github.io/blog/ + https://casper-network.github.io/blog/ Casper Docs - Redux Blog 2024-08-20T18:00:00.000Z https://github.com/jpmonette/feed - + Casper Docs - Redux Blog - https://casper-devrel.github.io/icon/favicon.ico + https://casper-network.github.io/icon/favicon.ico <![CDATA[validator rewards in Casper 2.0]]> - https://casper-devrel.github.io/blog/condor-validator-rewards/ - + https://casper-network.github.io/blog/condor-validator-rewards/ + 2024-08-20T18:00:00.000Z In this post we discuss the changes to validator rewards in Casper v2.0.

    -

    Economics of consensus

    +

    Economics of consensus

    Proof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally.

    Proof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress.

    Incentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain.

    -

    Casper 1.X Highway-specific incentives

    +

    Casper 1.X Highway-specific incentives

    The 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round.

    Degrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others.

    The weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality.

    -

    Casper 2.0

    -

    Public knowledge of finality

    +

    Casper 2.0

    +

    Public knowledge of finality

    A necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators.

    This mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators' knowledge of the canonical history be attested publicly.

    In Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one's own and other validators' finality signatures.

    -

    Design

    +

    Design

    Rewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities

    • Block proposal
    • @@ -38,10 +38,10 @@

      The rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era's end multiplied by an inflation factor derived from the chainspec. "Nominal" here means that all rounds result in a finalized block and that all finality signatures are collected and published.

      The rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication.

      Note that this split ensures that validators' incentives are aligned, in the sense that other validators' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators' signature, and because each validator benefits from other publishing its own signatures.

      -

      Expected rewards & volatility

      +

      Expected rewards & volatility

      Under nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable.

      In the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility.

      -

      Rewards formula

      +

      Rewards formula

      The rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section.

      Let us define some notation first

      N - expected number of blocks in an era

      @@ -82,11 +82,11 @@
    -

    Notes on implementation

    +

    Notes on implementation

    In a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block.

    We solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards.

    However, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created.

    -

    Impact on validator revenue

    +

    Impact on validator revenue

    No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile.

    ]]>
    Mel Padden @@ -97,12 +97,12 @@ https://github.com/AlexanderLimonov - +
    <![CDATA[Casper Docs Redux!]]> - https://casper-devrel.github.io/blog/welcome-docs-redux/ - + https://casper-network.github.io/blog/welcome-docs-redux/ + 2024-08-15T18:00:00.000Z Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    @@ -117,13 +117,13 @@
    <![CDATA[Addressable Entity in Casper 2.0]]> - https://casper-devrel.github.io/blog/addressable-entity/ - + https://casper-network.github.io/blog/addressable-entity/ + 2024-07-17T18:00:00.000Z Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    -

    Key Concepts

    +

    Key Concepts

    AddressableEntity

    At its core, an AddressableEntity is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An AddressableEntity provides a unified interface for various operations, including authorization, access control, and execution of functions.

    EntityAddr

    @@ -135,7 +135,7 @@

    AddressableEntityHash

    The AddressableEntityHash is a newtype wrapper around a 32-byte hash (HashAddr). This hash functions as a unique identifier for the AddressableEntity, typically derived from either the account's public key or the smart contract's hash using hashing algorithm.

    -

    The inner workings of AddressableEntity

    +

    The inner workings of AddressableEntity

    Let's dive into the critical components within an AddressableEntity:

    • protocol_version (ProtocolVersion): This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves.
    • @@ -144,17 +144,17 @@
    • action_thresholds (ActionThresholds): These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are deployment, key_management, and upgrade_management. Each action type has its own weight threshold, allowing for fine-grained control over permissions.
    • entry_points (EntryPoints): This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions.
    -

    Obtaining and converting Keys

    +

    Obtaining and converting Keys

    In Casper 2.0, developers will primarily work with Key::AddressableEntity when referring to accounts and smart contracts. Here's how you can create them and convert between different key formats:

    -

    Creating AddressableEntity Keys

    +

    Creating AddressableEntity Keys

    From Account Hash:

    let addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); 

    From Smart Contract Hash:

    let addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));
    -

    Extracting AccountHash or ContractHash from a Key

    +

    Extracting AccountHash or ContractHash from a Key

    You can extract the AccountHash or ContractHash from a Key::AddressableEntity using pattern matching:

    //For Accounts
    let account_hash = match addressable_entity_key {
    Key::AddressableEntity(EntityAddr::Account(hash)) => hash,
    _ => panic!("Not an account key"),
    };
    //For Contracts
    let contract_hash = match addressable_entity_key {
    Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,
    _ => panic!("Not a contract key"),
    };
    -

    The Address Merge in Condor

    +

    The Address Merge in Condor

    The "Address Merge" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with.

    Global State Transformation:

    Post-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the AddressableEntity structure. This means the network itself will recognize and handle these entities using the new format.

    @@ -187,16 +187,16 @@ Existing host functions used to identify the caller within your contract will co
    <![CDATA[Fee Elimination in Condor]]> - https://casper-devrel.github.io/blog/condor-fee-elimination/ - + https://casper-network.github.io/blog/condor-fee-elimination/ + 2024-07-16T22:00:00.000Z The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    -

    Concepts

    +

    Concepts

    Public distributed blockchain networks that support smart contracts generally employ a concept known as "gas", which can be thought of as "the ability to do work on-chain". The problem addressed by this mechanism is that any finite resource on a publicly accessible computer network must be rate-limited, because a resource made available without limit is a denial of service attack vector.

    Gas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor's available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses.

    -

    Payment, Gas Price, Fees

    -

    On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the proposer of that block in the form of transaction fees. The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:

    +

    Payment, Gas Price, Fees

    +

    On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the proposer of that block in the form of transaction fees. The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:

    • Gas Limit: An amount of gas, specified by the transactor, at which to cancel a transaction.
    • Gas Price: The network gas price; the ratio between the cost of 1 unit of gas and 1 mote.
    • @@ -207,21 +207,21 @@ Existing host functions used to identify the caller within your contract will co

      The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article.

      -

      Fee Elimination

      +

      Fee Elimination

      Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances.

      Under 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated Gas Cost for a configurable period of time known as the Hold Period. Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions.

      -

      Holds

      +

      Holds

      A hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse.

      -

      Hold Release

      +

      Hold Release

      The Casper Node 2.0 software currently supports two hold release models: Accrued and Amortized.

      The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options.

      -

      Accrued

      +

      Accrued

      100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor.

      -

      Amortized

      +

      Amortized

      The effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold amount is proportional to the percentage of the hold duration that remains before expiry.

      For example, if:

        @@ -272,10 +272,10 @@ Existing host functions used to identify the caller within your contract will co
        Hold AmountHold PeriodTime ElapsedEffective Hold
        180901178
        180909162
        180904590
        18090892
        -

        More about Gas holds

        +

        More about Gas holds

        The duration of gas holds is defined here in the casper-node chainspec:

        # If fee_handling is set to 'no_fee', the system places a balance hold on the payer
        # equal to the value the fee would have been. Such balance holds expire after a time
        # interval has elapsed. This setting controls how long that interval is. The available
        # balance of a purse equals its total balance minus the held amount(s) of non-expired
        # holds (see gas_hold_balance_handling setting for details of how that is calculated).
        #
        # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,
        # a hold for 100 is placed on that purse and is considered when calculating total balance
        # for 24 hours starting from the block_time when the hold was placed.
        gas_hold_interval = '24 hours'
        -

        Preventing Exploitation

        +

        Preventing Exploitation

        The ultimate goal of any gas mechanism is to prevent exploitation of a network's resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely.

        However, any gas mechanism that doesn't charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances.

        Attacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper's approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly.

        @@ -288,21 +288,21 @@ Existing host functions used to identify the caller within your contract will co
      • G = 3300 CSPR block gas limit

      If this proves to be too cheap, the locking period can be extended or the block gas limit increased.

      -

      Opportunity Cost

      +

      Opportunity Cost

      In addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high.

      -

      Incentivizing Validators

      +

      Incentivizing Validators

      The Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators.

      Casper's solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current "era", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a "validator credit" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next booking block appears.

      -

      Looking Forward

      +

      Looking Forward

      By introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols.

      As the model is rolled out to Casper's mainnet and testnet, economists and engineers will study its effects on Casper's transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented.


      -

      Further Reading/Terms

      -

      Proposer

      +

      Further Reading/Terms

      +

      Proposer

      A validator proposing a block to the network for execution
      Consensus
      Validator

      -

      Fees

      +

      Fees

      A portion of a transaction's gas costs given over to the proposer of the block containing that transaction.
      Gas Concepts
      Runtime Economics
      @@ -321,16 +321,16 @@ Existing host functions used to identify the caller within your contract will co <![CDATA[Setting Up a Local Casper Condor Network for Development]]> - https://casper-devrel.github.io/blog/condor-local-setup/ - + https://casper-network.github.io/blog/condor-local-setup/ + 2024-07-16T18:00:00.000Z

      Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.

      -

      Prerequisites

      +

      Prerequisites

      • Docker installed and running on your machine
      -

      Part 1: The Dockerized NCTL (Network Control Tool)

      +

      Part 1: The Dockerized NCTL (Network Control Tool)

      NCTL is your tool for managing the Casper network. We'll use a Dockerized version for easier setup.

      1. @@ -372,7 +372,7 @@ Existing host functions used to identify the caller within your contract will co
    -

    Part 2: Casper Client (Rust)

    +

    Part 2: Casper Client (Rust)

    To interact with your local Condor network, we'll use the Casper Client. You have two options for using the Casper Client:

    Option 1: Using the Casper Client from the Docker Image

      @@ -398,7 +398,7 @@ Existing host functions used to identify the caller within your contract will co
      nctl-view-node-status

      This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:

      ------------------------------------------------------------------------------------------------------------------------------------
      2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:
      {
      "api_version": "2.0.0",
      "peers": [
      {
      "node_id": "tls:05b5..7b39",
      "address": "127.0.0.1:22103"
      },
      {
      "node_id": "tls:527e..37d2",
      "address": "127.0.0.1:22105"
      },
      {
      "node_id": "tls:b1d0..870f",
      "address": "127.0.0.1:22102"
      },
      {
      "node_id": "tls:dcdf..e348",
      "address": "127.0.0.1:22104"
      }
      ],
      "build_version": "2.0.0-d5c0d238f",
      "chainspec_name": "casper-net-1",
      "starting_state_root_hash": "2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80",
      "last_added_block_info": {
      "hash": "c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395",
      "timestamp": "2024-07-10T15:31:38.601Z",
      "era_id": 19,
      "height": 205,
      "state_root_hash": "6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612",
      "creator": "0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab"
      },
      "our_public_signing_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b",
      "round_length": "4s 96ms",
      "next_upgrade": null,
      "uptime": "13m 15s",
      "reactor_state": "Validate",
      "last_progress": "2024-07-10T15:18:26.354Z",
      "available_block_range": {
      "low": 0,
      "high": 205
      },
      "block_sync": {
      "historical": null,
      "forward": null
      },
      "latest_switch_block_hash": "5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68"
      }
      .
      .
      .
      -

      Troubleshooting

      +

      Troubleshooting

      If sidecars or nodes are not running: If you see null values under each node in the output of nctl-view-node-status, it means the version of casper-sidecar is not compatible with the casper-node.

      Solution:

        @@ -416,20 +416,20 @@ Existing host functions used to identify the caller within your contract will co

        Rebuild the NCTL image: docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .

      -

      Using the Casper Client

      +

      Using the Casper Client

      • Command Format(Using local casper-client): cargo run --release [command] --node-address http://127.0.0.1:11101
      • Command Format(Using casper-client from the docker image): casper-client [command] --node-address http://127.0.0.1:11101
      -

      Accessing the NCTL Block Web Explorer

      +

      Accessing the NCTL Block Web Explorer

      The NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:

      http://127.0.0.1:8080

      This allows you to visually explore blocks, transactions, and other details of your local network.

      -

      Important Notes

      +

      Important Notes

      • Work in Progress: Condor compatibility is still evolving. Some features may be unstable or incomplete.
      -

      Additional Tips

      +

      Additional Tips

      ]]> @@ -438,6 +438,6 @@ Existing host functions used to identify the caller within your contract will co https://github.com/sczembor - + \ No newline at end of file diff --git a/blog/authors/alexanderlimonov/index.html b/blog/authors/alexanderlimonov/index.html index b158651f0..f57cd3b7b 100644 --- a/blog/authors/alexanderlimonov/index.html +++ b/blog/authors/alexanderlimonov/index.html @@ -3,18 +3,18 @@ -Alexander Limonov - One post | Casper Docs - Redux +Alexander Limonov - One post | Casper Docs - Redux - - + +
      Alexander Limonov
      Economist for Casper Labs
      View all authors

      + submit an issue on Github
    Alexander Limonov
    Economist for Casper Labs
    View all authors

    \ No newline at end of file diff --git a/blog/authors/dylanireland/index.html b/blog/authors/dylanireland/index.html index 27b169719..b9f4fa53e 100644 --- a/blog/authors/dylanireland/index.html +++ b/blog/authors/dylanireland/index.html @@ -3,18 +3,18 @@ -Dylan Ireland - One post | Casper Docs - Redux +Dylan Ireland - One post | Casper Docs - Redux - - + +
    Dylan Ireland
    Developer Advocate for Casper Association
    View all authors

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    + submit an issue on Github
    Dylan Ireland
    Developer Advocate for Casper Association
    View all authors

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    \ No newline at end of file diff --git a/blog/authors/index.html b/blog/authors/index.html index ae49d7719..959ef5819 100644 --- a/blog/authors/index.html +++ b/blog/authors/index.html @@ -3,18 +3,18 @@ -Authors | Casper Docs - Redux +Authors | Casper Docs - Redux - - + +

    Authors

    + submit an issue on Github

    Authors

    \ No newline at end of file diff --git a/blog/authors/melpadden/index.html b/blog/authors/melpadden/index.html index 471f96240..c5e255c31 100644 --- a/blog/authors/melpadden/index.html +++ b/blog/authors/melpadden/index.html @@ -3,19 +3,19 @@ -Mel Padden - 4 posts | Casper Docs - Redux +Mel Padden - 4 posts | Casper Docs - Redux - - + +
    Mel Padden
    Head of Developer Relations for Casper Association
    View all authors

    Casper Docs Redux!

    · One min read
    Mel Padden
    Head of Developer Relations for Casper Association

    Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    + submit an issue on Github
    Mel Padden
    Head of Developer Relations for Casper Association
    View all authors

    Casper Docs Redux!

    · One min read
    Mel Padden
    Head of Developer Relations for Casper Association

    Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    diff --git a/blog/authors/sczembor/index.html b/blog/authors/sczembor/index.html index aed913372..c4aee6644 100644 --- a/blog/authors/sczembor/index.html +++ b/blog/authors/sczembor/index.html @@ -3,19 +3,19 @@ -Stanislaw Czembor - 2 posts | Casper Docs - Redux +Stanislaw Czembor - 2 posts | Casper Docs - Redux - - + +
    Stanislaw Czembor
    Developer Advocate for Casper Association
    View all authors

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    -

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    + submit an issue on Github
    Stanislaw Czembor
    Developer Advocate for Casper Association
    View all authors

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    +

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    \ No newline at end of file diff --git a/blog/condor-fee-elimination/index.html b/blog/condor-fee-elimination/index.html index fa503a6eb..17f28b58e 100644 --- a/blog/condor-fee-elimination/index.html +++ b/blog/condor-fee-elimination/index.html @@ -3,19 +3,19 @@ -Fee Elimination in Condor | Casper Docs - Redux +Fee Elimination in Condor | Casper Docs - Redux - - + +

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    + submit an issue on Github

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    Concepts

    Public distributed blockchain networks that support smart contracts generally employ a concept known as "gas", which can be thought of as "the ability to do work on-chain". The problem addressed by this mechanism is that any finite resource on a publicly accessible computer network must be rate-limited, because a resource made available without limit is a denial of service attack vector.

    Gas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor's available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses.

    diff --git a/blog/condor-local-setup/index.html b/blog/condor-local-setup/index.html index b43d340cf..b49250073 100644 --- a/blog/condor-local-setup/index.html +++ b/blog/condor-local-setup/index.html @@ -3,19 +3,19 @@ -Setting Up a Local Casper Condor Network for Development | Casper Docs - Redux +Setting Up a Local Casper Condor Network for Development | Casper Docs - Redux - - + +

    Setting Up a Local Casper Condor Network for Development

    · 5 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association

    Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.

    + submit an issue on Github

    Setting Up a Local Casper Condor Network for Development

    · 5 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association

    Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.

    Prerequisites

    • Docker installed and running on your machine
    • @@ -122,6 +122,6 @@

      Important No

      Additional Tips

    +
    \ No newline at end of file diff --git a/blog/condor-validator-rewards/index.html b/blog/condor-validator-rewards/index.html index d85f186ba..0bc4cd6ef 100644 --- a/blog/condor-validator-rewards/index.html +++ b/blog/condor-validator-rewards/index.html @@ -3,19 +3,19 @@ -validator rewards in Casper 2.0 | Casper Docs - Redux +validator rewards in Casper 2.0 | Casper Docs - Redux - - + +

    validator rewards in Casper 2.0

    · 7 min read
    Mel Padden
    Head of Developer Relations for Casper Association
    Alexander Limonov
    Economist for Casper Labs

    In this post we discuss the changes to validator rewards in Casper v2.0.

    + submit an issue on Github

    validator rewards in Casper 2.0

    · 7 min read
    Mel Padden
    Head of Developer Relations for Casper Association
    Alexander Limonov
    Economist for Casper Labs

    In this post we discuss the changes to validator rewards in Casper v2.0.

    Economics of consensus

    Proof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally.

    Proof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress.

    @@ -89,6 +89,6 @@

    Note

    We solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards.

    However, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created.

    Impact on validator revenue

    -

    No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile.

    +

    No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile.

    \ No newline at end of file diff --git a/blog/index.html b/blog/index.html index 6041c113d..4a7e8dbbd 100644 --- a/blog/index.html +++ b/blog/index.html @@ -3,20 +3,20 @@ -Casper Developer Relations Blog | Casper Docs - Redux +Casper Developer Relations Blog | Casper Docs - Redux - - + +

    Casper Docs Redux!

    · One min read
    Mel Padden
    Head of Developer Relations for Casper Association

    Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    + submit an issue on Github

    Casper Docs Redux!

    · One min read
    Mel Padden
    Head of Developer Relations for Casper Association

    Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

    Addressable Entity in Casper 2.0

    · 4 min read
    Stanislaw Czembor
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    -

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    +

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    Fee Elimination in Condor

    · 9 min read
    Dylan Ireland
    Developer Advocate for Casper Association
    Mel Padden
    Head of Developer Relations for Casper Association

    The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    \ No newline at end of file diff --git a/blog/rss.xml b/blog/rss.xml index 5e6733d74..8d8ad6f2b 100644 --- a/blog/rss.xml +++ b/blog/rss.xml @@ -2,7 +2,7 @@ Casper Docs - Redux Blog - https://casper-devrel.github.io/blog/ + https://casper-network.github.io/blog/ Casper Docs - Redux Blog Tue, 20 Aug 2024 18:00:00 GMT https://validator.w3.org/feed/docs/rss2.html @@ -10,25 +10,25 @@ en <![CDATA[validator rewards in Casper 2.0]]> - https://casper-devrel.github.io/blog/condor-validator-rewards/ - https://casper-devrel.github.io/blog/condor-validator-rewards/ + https://casper-network.github.io/blog/condor-validator-rewards/ + https://casper-network.github.io/blog/condor-validator-rewards/ Tue, 20 Aug 2024 18:00:00 GMT In this post we discuss the changes to validator rewards in Casper v2.0.

    -

    Economics of consensus

    +

    Economics of consensus

    Proof of Stake consensus protocols explicitly impose an assumption that a critical portion of the validator set, by weight, remains honest. Normally, just as it is in Highway and will be in Zug, there is a requirement that at least 2/3 of the weight remain honest for the chain to continue to operate normally.

    Proof of Stake protocols do not typically describe the particular incentives that should keep validators honest, however, so some incentive scheme must be independently developed to ensure that the assumptions of the safety and liveness theorems actually hold. Such a scheme may directly reward some measure of performance within the protocol model, but an alternative model can choose to reward consensus-independent measures of chain performance, such as chain progress.

    Incentive rewards in Casper come from issuance of new token at the end of each era, with quantity derived from an inflation parameter in the chainspec. The minted token are distributed in proportion to weight, assuming nominal performance of the chain.

    -

    Casper 1.X Highway-specific incentives

    +

    Casper 1.X Highway-specific incentives

    The 1.0 rewards scheme introduced with Highway on mainnet is directly tied to the details of Highway consensus. Rewards are maximized when all validators regularly send messages necessary to finalize a block within a time limit in a particular round.

    Degrading platform performance by delaying block finalization is disadvantageous for all validators, even those not directly responsible for the delay, which is a means of aligning validator incentives with each other by discouraging censorship of consensus messages produced by others.

    The weakness of the 1.0 rewards model is that it is difficult to understand and maintain. Additionally, by focusing on a consensus-specific measure of performance, it does not directly incentivize the observable outcome that we actually care about, which is public knowledge of block finality.

    -

    Casper 2.0

    -

    Public knowledge of finality

    +

    Casper 2.0

    +

    Public knowledge of finality

    A necessary outcome of a safe consensus process over possible histories of the chain is that all honest validators should have at least mutual knowledge of the canonical history. That is, each honest validator should believe that a particular history is the correct one, and this history should be the same for all validators.

    This mutual knowledge is sufficient for validators to make further progress in building up the canonical history. However, for a user of the blockchain, establishing confidence in the correct operation of the protocol and the identity of the canonical history requires that the validators' knowledge of the canonical history be attested publicly.

    In Casper, validators create and distribute finality signatures, which are cryptographically secure witnesses of their belief in the finality of a particular block. Under 1.X, however, these are not easily verifiable by users and play no role in the reward mechanism, despite being a critical tool for building user confidence in the canonical history. In 2.0, we propose to allocate rewards for creation and publication of one's own and other validators' finality signatures.

    -

    Design

    +

    Design

    Rewards that promote public knowledge of finality naturally suggest rewarding publicly observable behaviors, rather than metrics only readily visible to the consensus component. This, together with the expected transition from Highway to Zug, naturally led to a system that rewards three publicly observable activities

    • Block proposal
    • @@ -39,10 +39,10 @@

      The rewards apportioned to a block, under nominal operating conditions, are the same as they are under 1.X, that is, they amount to total supply at last era's end multiplied by an inflation factor derived from the chainspec. "Nominal" here means that all rounds result in a finalized block and that all finality signatures are collected and published.

      The rewards are apportioned to these three activities based on chainspec settings governing the split between block proposals and signature rewards, and, within signature rewards, between finality signature creation and publication.

      Note that this split ensures that validators' incentives are aligned, in the sense that other validators' correct operation is beneficial for each validator. This is because each validator is rewarded for publishing other validators' signature, and because each validator benefits from other publishing its own signatures.

      -

      Expected rewards & volatility

      +

      Expected rewards & volatility

      Under nominal operating conditions, the total rewards for each validator will be proportional to weight in the long run. Depending on the particular values of the parameters governing the split between the three components of the rewards, short-run rewards can be more or less variable.

      In the long run, with a stable validator set, each validator eventually produces a number of blocks proportional to its weight. Small validators can do months between producing a block, and will experience variable wait times between such occasions. However, each validator is supposed to produce signatures for each finalized block, so moving the allocation towards signature creation can reduce volatility.

      -

      Rewards formula

      +

      Rewards formula

      The rewards have three additive components, one for each observable activity we described in the previous section. The era rewards for a particular validator can be described using a simple formula, given below. Note that the formula does not exactly correspond to the actual on-chain calculation, for technical reasons we discuss in a further section.

      Let us define some notation first

      N - expected number of blocks in an era

      @@ -83,19 +83,19 @@
    -

    Notes on implementation

    +

    Notes on implementation

    In a real network, messages arrive with a delay. This means that we cannot guarantee that all finality signatures for an era will arrive in time to be used by the rewards calculation carried out in the switch block.

    We solve this problem by allowing publication of finality signatures for a preceding era. As long as the validator set stays unchanged, in the long run the formula above is a near-exact representation of rewards.

    However, entry of new validators means that some of the publication rewards may be distributed among more validators than just those who participated in the era in which the signatures were created.

    -

    Impact on validator revenue

    +

    Impact on validator revenue

    No impact is expected on average validator rewards under nominal operating conditions. Note that shortfall in signature creation, or network issues preventing the propagation of such signatures, can reduce rewards, even for validators who honestly publish all incoming signatures and honestly create signatures for each block. Additionally, allocating more rewards to block proposals or finality publication can make the rewards more volatile.

    ]]>
    Condor - validators + Validators
    <![CDATA[Casper Docs Redux!]]> - https://casper-devrel.github.io/blog/welcome-docs-redux/ - https://casper-devrel.github.io/blog/welcome-docs-redux/ + https://casper-network.github.io/blog/welcome-docs-redux/ + https://casper-network.github.io/blog/welcome-docs-redux/ Thu, 15 Aug 2024 18:00:00 GMT Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

    @@ -106,13 +106,13 @@
    <![CDATA[Addressable Entity in Casper 2.0]]> - https://casper-devrel.github.io/blog/addressable-entity/ - https://casper-devrel.github.io/blog/addressable-entity/ + https://casper-network.github.io/blog/addressable-entity/ + https://casper-network.github.io/blog/addressable-entity/ Wed, 17 Jul 2024 18:00:00 GMT Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

    In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

    -

    Key Concepts

    +

    Key Concepts

    AddressableEntity

    At its core, an AddressableEntity is a versatile data structure that represents both accounts and smart contracts within the Casper global state. It encapsulates all the necessary information for identifying and managing these entities. An AddressableEntity provides a unified interface for various operations, including authorization, access control, and execution of functions.

    EntityAddr

    @@ -124,7 +124,7 @@

    AddressableEntityHash

    The AddressableEntityHash is a newtype wrapper around a 32-byte hash (HashAddr). This hash functions as a unique identifier for the AddressableEntity, typically derived from either the account's public key or the smart contract's hash using hashing algorithm.

    -

    The inner workings of AddressableEntity

    +

    The inner workings of AddressableEntity

    Let's dive into the critical components within an AddressableEntity:

    • protocol_version (ProtocolVersion): This field indicates the protocol version that the entity is compatible with. It ensures backward compatibility and allows for smooth upgrades as the Casper network evolves.
    • @@ -133,17 +133,17 @@
    • action_thresholds (ActionThresholds): These thresholds define the minimum combined weight of associated keys required to authorize specific actions. The three main action types are deployment, key_management, and upgrade_management. Each action type has its own weight threshold, allowing for fine-grained control over permissions.
    • entry_points (EntryPoints): This component is relevant only for smart contracts. It defines the functions (entry points) that external actors can call on the contract, along with their parameters, return types, and access permissions.
    -

    Obtaining and converting Keys

    +

    Obtaining and converting Keys

    In Casper 2.0, developers will primarily work with Key::AddressableEntity when referring to accounts and smart contracts. Here's how you can create them and convert between different key formats:

    -

    Creating AddressableEntity Keys

    +

    Creating AddressableEntity Keys

    From Account Hash:

    let addressable_entity_key = Key::AddressableEntity(EntityAddr::Account(account_hash)); 

    From Smart Contract Hash:

    let addressable_entity_key = Key::AddressableEntity(EntityAddr::SmartContract(contract_hash));
    -

    Extracting AccountHash or ContractHash from a Key

    +

    Extracting AccountHash or ContractHash from a Key

    You can extract the AccountHash or ContractHash from a Key::AddressableEntity using pattern matching:

    //For Accounts
    let account_hash = match addressable_entity_key {
    Key::AddressableEntity(EntityAddr::Account(hash)) => hash,
    _ => panic!("Not an account key"),
    };
    //For Contracts
    let contract_hash = match addressable_entity_key {
    Key::AddressableEntity(EntityAddr::SmartContract(hash)) => hash,
    _ => panic!("Not a contract key"),
    };
    -

    The Address Merge in Condor

    +

    The Address Merge in Condor

    The "Address Merge" in the Condor upgrade of Casper is a foundational shift, impacting how accounts and smart contracts are identified and interacted with.

    Global State Transformation:

    Post-Condor, all accounts and smart contract addresses residing within the global state will be automatically migrated to the AddressableEntity structure. This means the network itself will recognize and handle these entities using the new format.

    @@ -168,16 +168,16 @@ Existing host functions used to identify the caller within your contract will co
    <![CDATA[Fee Elimination in Condor]]> - https://casper-devrel.github.io/blog/condor-fee-elimination/ - https://casper-devrel.github.io/blog/condor-fee-elimination/ + https://casper-network.github.io/blog/condor-fee-elimination/ + https://casper-network.github.io/blog/condor-fee-elimination/ Tue, 16 Jul 2024 22:00:00 GMT The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

    -

    Concepts

    +

    Concepts

    Public distributed blockchain networks that support smart contracts generally employ a concept known as "gas", which can be thought of as "the ability to do work on-chain". The problem addressed by this mechanism is that any finite resource on a publicly accessible computer network must be rate-limited, because a resource made available without limit is a denial of service attack vector.

    Gas is acquired in finite quantities and used to meter and limit resource consumption by individual transactors. A transactor's available gas is consumed by their on-chain usage of computation, data storage, and possibly other chain-specific resources. The public Casper Network and its testnet have used such a gas model since their geneses.

    -

    Payment, Gas Price, Fees

    -

    On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the proposer of that block in the form of transaction fees. The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:

    +

    Payment, Gas Price, Fees

    +

    On Casper 1.x, every transaction is subject to gas consumption. The transactor must specify an amount of token that is converted to gas and used to pay for execution. All gas consumed in each block is allotted to the proposer of that block in the form of transaction fees. The model also includes tables to allow calculation of gas costs, and support for some portion of unconsumed gas to be refunded to transactors. We refer to these concepts using the following terms:

    • Gas Limit: An amount of gas, specified by the transactor, at which to cancel a transaction.
    • Gas Price: The network gas price; the ratio between the cost of 1 unit of gas and 1 mote.
    • @@ -188,21 +188,21 @@ Existing host functions used to identify the caller within your contract will co

      The Casper node software supports a number of configurable options which govern how gas may be calculated for a given transaction. A discussion of these is outside the scope of this article. This article is concerned with how these gas costs are dealt with, once calculated. Gas cost options will be the subject of another article.

      -

      Fee Elimination

      +

      Fee Elimination

      Fee Elimination is the strategy of placing temporary holds on transactor balances corresponding to their incurred gas costs, instead of taking those costs from their on-chain balances.

      Under 1.x, transactors must pay for gas directly from their purse balances. With Fee Elimination on Casper 2.0, a hold is placed on the calculated Gas Cost for a configurable period of time known as the Hold Period. Fees are therefore not forfeited by transactors, and funds are not spent to execute transactions.

      -

      Holds

      +

      Holds

      A hold may be thought of as a temporary freeze on some portion of the funds in an account. The funds never leave the purse upon which the hold is placed, but the owner of those funds may not spend them as long as the hold is in effect, and the funds held are not counted towards the available balance of that purse.

      -

      Hold Release

      +

      Hold Release

      The Casper Node 2.0 software currently supports two hold release models: Accrued and Amortized.

      The Condor node architecture allows for any time-based function to be developed and used to calculate hold releases. However, for simplicity, this article will deal with the two currently available options.

      -

      Accrued

      +

      Accrued

      100% of the hold is held until the hold expires. At any given point in the duration of the hold, the effective amount of the hold is 100%. At expiry, all of the funds are again made available to the transactor.

      -

      Amortized

      +

      Amortized

      The effective amount of the hold is reduced linearly over the course of the hold duration. At any point in the duration of the hold, the effective hold amount is proportional to the percentage of the hold duration that remains before expiry.

      For example, if:

        @@ -253,10 +253,10 @@ Existing host functions used to identify the caller within your contract will co
        Hold AmountHold PeriodTime ElapsedEffective Hold
        180901178
        180909162
        180904590
        18090892
        -

        More about Gas holds

        +

        More about Gas holds

        The duration of gas holds is defined here in the casper-node chainspec:

        # If fee_handling is set to 'no_fee', the system places a balance hold on the payer
        # equal to the value the fee would have been. Such balance holds expire after a time
        # interval has elapsed. This setting controls how long that interval is. The available
        # balance of a purse equals its total balance minus the held amount(s) of non-expired
        # holds (see gas_hold_balance_handling setting for details of how that is calculated).
        #
        # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,
        # a hold for 100 is placed on that purse and is considered when calculating total balance
        # for 24 hours starting from the block_time when the hold was placed.
        gas_hold_interval = '24 hours'
        -

        Preventing Exploitation

        +

        Preventing Exploitation

        The ultimate goal of any gas mechanism is to prevent exploitation of a network's resources. Aside from incentivizing validators, there is no fundamental reason to charge users for making transactions if their honesty can be guaranteed. By designing a system that disincentivizes wasteful transactions without charging a fee, resistance to exploitation can be maintained while allowing users to transact freely.

        However, any gas mechanism that doesn't charge users could be vulnerable to denial-of-service attacks. Provided a large enough bankroll, a user could deploy enough transactions to slow the network for the amount of time needed for his or her previous gas payments to unlock, and use these unlocked funds to deploy more transactions, and thus repeat the process ad infinitum. In this way, one could theoretically deploy infinite transactions, cycling through their locked and unlocked balances.

        Attacking the network in this way is a challenge of economic feasibility, much like many other aspects of blockchains. To prevent an attack like this from taking place, it must be made prohibitively expensive to mount such an attack, with little to no incentive to the attacker. Casper's approach involves using a long locking period, combined with 16 second blocktimes. The Casper 2.0 mainnet is slated to roll out with a 30 day locking period, but if increased, the cost to attack would scale linearly.

        @@ -269,21 +269,21 @@ Existing host functions used to identify the caller within your contract will co
      • G = 3300 CSPR block gas limit

      If this proves to be too cheap, the locking period can be extended or the block gas limit increased.

      -

      Opportunity Cost

      +

      Opportunity Cost

      In addition to the necessity to maintain large amounts of CSPR token in order to facilitate a DoS attack as laid out above, any prospective attacker would also incur the opportunity cost of being unable to use their CSPR for the duration of the hold period. Simply put, while their CSPR is locked up attacking the network, it cannot be used to earn rewards by staking. Given the amount of CSPR necessarily involved, and assuming any non-trivial potential annualized return on staking CSPR tokens, the ratio of opportunity cost of mounting such an attack versus the incentive to do so swiftly becomes prohibitively high.

      -

      Incentivizing Validators

      +

      Incentivizing Validators

      The Casper Network, like any truly decentralized blockchain, allows nodes to act in their greatest economic interest when it comes to validating transactions. The purpose of this is to incentivize validators as much as possible, encouraging more to come online. Part of the income a validator earns comes from fees paid by a deployer, which entices validators to pick up their transactions. When no fee is paid by the deployer at all, however, another incentive must be provided to the validators.

      Casper's solution is quite simple, but requires understanding how validators are selected and compensated. On Casper Networks, 100 validators are weightily selected to validate all the blocks within the current "era", which advances every 2 hours. At the end of each era, validator rewards are calculated, put into a pot, and distributed to validators based on the amount of token staked by each. Additionally, a "validator credit" is added to validators who propose populated blocks, proportional to the size of the blocks they propose. This validator credit is then applied to the payout scheme, awarding more of the pot to the hardest-working nodes. Additionally, the validator credit is considered as additional staking weight for the next era when the next booking block appears.

      -

      Looking Forward

      +

      Looking Forward

      By introducing Fee Elimination to the Casper Network, we hope to make transacting with the blockchain more accessible and less financially cumbersome. With this new model, interacting with smart contracts can become effectively free for users, inviting larger audiences to participate in new and exciting protocols.

      As the model is rolled out to Casper's mainnet and testnet, economists and engineers will study its effects on Casper's transaction economy. The data observed will be used to devise proposals and improvements, need they be implemented.


      -

      Further Reading/Terms

      -

      Proposer

      +

      Further Reading/Terms

      +

      Proposer

      A validator proposing a block to the network for execution
      Consensus
      Validator

      -

      Fees

      +

      Fees

      A portion of a transaction's gas costs given over to the proposer of the block containing that transaction.
      Gas Concepts
      Runtime Economics
      @@ -294,16 +294,16 @@ Existing host functions used to identify the caller within your contract will co <![CDATA[Setting Up a Local Casper Condor Network for Development]]> - https://casper-devrel.github.io/blog/condor-local-setup/ - https://casper-devrel.github.io/blog/condor-local-setup/ + https://casper-network.github.io/blog/condor-local-setup/ + https://casper-network.github.io/blog/condor-local-setup/ Tue, 16 Jul 2024 18:00:00 GMT Casper Condor is a major upgrade to the Casper Network. This guide walks you through creating a local Condor environment for testing and development using Dockerized NCTL and the Rust Casper Client.

      -

      Prerequisites

      +

      Prerequisites

      • Docker installed and running on your machine
      -

      Part 1: The Dockerized NCTL (Network Control Tool)

      +

      Part 1: The Dockerized NCTL (Network Control Tool)

      NCTL is your tool for managing the Casper network. We'll use a Dockerized version for easier setup.

      1. @@ -345,7 +345,7 @@ Existing host functions used to identify the caller within your contract will co
    -

    Part 2: Casper Client (Rust)

    +

    Part 2: Casper Client (Rust)

    To interact with your local Condor network, we'll use the Casper Client. You have two options for using the Casper Client:

    Option 1: Using the Casper Client from the Docker Image

      @@ -371,7 +371,7 @@ Existing host functions used to identify the caller within your contract will co
      nctl-view-node-status

      This command should return the status of all the nodes running in your local network, indicating a successful setup. The output should look similar to this:

      ------------------------------------------------------------------------------------------------------------------------------------
      2024-07-10T15:31:42.181535 [INFO] [2043] NCTL :: node #1 :: status:
      {
      "api_version": "2.0.0",
      "peers": [
      {
      "node_id": "tls:05b5..7b39",
      "address": "127.0.0.1:22103"
      },
      {
      "node_id": "tls:527e..37d2",
      "address": "127.0.0.1:22105"
      },
      {
      "node_id": "tls:b1d0..870f",
      "address": "127.0.0.1:22102"
      },
      {
      "node_id": "tls:dcdf..e348",
      "address": "127.0.0.1:22104"
      }
      ],
      "build_version": "2.0.0-d5c0d238f",
      "chainspec_name": "casper-net-1",
      "starting_state_root_hash": "2d92cf9f3ff3eb70f40be598b61cbf747c1b5ea67df9596d84a88c5458028a80",
      "last_added_block_info": {
      "hash": "c1056e0e5978e725777f48e4488462d7794e6547f25b1fbcc4ba261ca2864395",
      "timestamp": "2024-07-10T15:31:38.601Z",
      "era_id": 19,
      "height": 205,
      "state_root_hash": "6c5502c3443f526e943fa5a5421349e938464c063c8dd0ada616c997e3805612",
      "creator": "0190664e16a17594ed2d0e3c279c4cf5894e8db0da15e3b91c938562a1caae32ab"
      },
      "our_public_signing_key": "01fed662dc7f1f7af43ad785ba07a8cc05b7a96f9ee69613cfde43bc56bec1140b",
      "round_length": "4s 96ms",
      "next_upgrade": null,
      "uptime": "13m 15s",
      "reactor_state": "Validate",
      "last_progress": "2024-07-10T15:18:26.354Z",
      "available_block_range": {
      "low": 0,
      "high": 205
      },
      "block_sync": {
      "historical": null,
      "forward": null
      },
      "latest_switch_block_hash": "5192198c783ed8b66e206c37b34c5e268c84be2f4b78dd9899eecf5f37fb9f68"
      }
      .
      .
      .
      -

      Troubleshooting

      +

      Troubleshooting

      If sidecars or nodes are not running: If you see null values under each node in the output of nctl-view-node-status, it means the version of casper-sidecar is not compatible with the casper-node.

      Solution:

        @@ -389,25 +389,25 @@ Existing host functions used to identify the caller within your contract will co

        Rebuild the NCTL image: docker build -f casper-nctl-condor.Dockerfile -t casper-nctl:rc3 .

      -

      Using the Casper Client

      +

      Using the Casper Client

      • Command Format(Using local casper-client): cargo run --release [command] --node-address http://127.0.0.1:11101
      • Command Format(Using casper-client from the docker image): casper-client [command] --node-address http://127.0.0.1:11101
      -

      Accessing the NCTL Block Web Explorer

      +

      Accessing the NCTL Block Web Explorer

      The NCTL Docker setup includes a web-based block explorer. You can access it in your browser at:

      http://127.0.0.1:8080

      This allows you to visually explore blocks, transactions, and other details of your local network.

      -

      Important Notes

      +

      Important Notes

      • Work in Progress: Condor compatibility is still evolving. Some features may be unstable or incomplete.
      -

      Additional Tips

      +

      Additional Tips

      ]]> Condor - setup + Set-up \ No newline at end of file diff --git a/blog/tags/condor/index.html b/blog/tags/condor/index.html index 180e53317..555ff754d 100644 --- a/blog/tags/condor/index.html +++ b/blog/tags/condor/index.html @@ -3,19 +3,19 @@ -4 posts tagged with "Condor" | Casper Docs - Redux +4 posts tagged with "Condor" | Casper Docs - Redux - - + +

      4 posts tagged with "Condor"

      Blog posts related to the Condor upgrade

      View All Tags

      Addressable Entity in Casper 2.0

      · 4 min read
      Stanislaw Czembor
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

      -

      In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      + submit an issue on Github

      4 posts tagged with "Condor"

      Blog posts related to the Condor upgrade

      View All Tags

      Addressable Entity in Casper 2.0

      · 4 min read
      Stanislaw Czembor
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      Casper 2.0 introduces significant changes in the representation and management of accounts and smart contracts, through the introduction of the AddressableEntity type. This new structure replaces the separate AccountHash and ContractHash used in Casper 1.x, bringing a unified approach to interact with entities on the network. Contracts can now hold and manage funds directly through associated purses, similar to user accounts. They can also manage their own keys, enabling more sophisticated access control.

      +

      In this article, we'll dive into the details of AddressableEntity, exploring its structure and functionalities.

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      \ No newline at end of file diff --git a/blog/tags/docs-redux/index.html b/blog/tags/docs-redux/index.html index de105e42d..a8cffa9a8 100644 --- a/blog/tags/docs-redux/index.html +++ b/blog/tags/docs-redux/index.html @@ -3,19 +3,19 @@ -One post tagged with "docs-redux" | Casper Docs - Redux +One post tagged with "docs-redux" | Casper Docs - Redux - - + +

      One post tagged with "docs-redux"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      + submit an issue on Github

      One post tagged with "docs-redux"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

      \ No newline at end of file diff --git a/blog/tags/features/index.html b/blog/tags/features/index.html index b8e28785a..169d27200 100644 --- a/blog/tags/features/index.html +++ b/blog/tags/features/index.html @@ -3,18 +3,18 @@ -One post tagged with "features" | Casper Docs - Redux +One post tagged with "features" | Casper Docs - Redux - - + +

      One post tagged with "features"

      View All Tags

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      + submit an issue on Github

      One post tagged with "features"

      View All Tags

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      \ No newline at end of file diff --git a/blog/tags/hello/index.html b/blog/tags/hello/index.html index 8a321dac9..434afa708 100644 --- a/blog/tags/hello/index.html +++ b/blog/tags/hello/index.html @@ -3,19 +3,19 @@ -One post tagged with "hello" | Casper Docs - Redux +One post tagged with "hello" | Casper Docs - Redux - - + +

      One post tagged with "hello"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      + submit an issue on Github

      One post tagged with "hello"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

      \ No newline at end of file diff --git a/blog/tags/index.html b/blog/tags/index.html index d8af7ed1c..94e7c47ca 100644 --- a/blog/tags/index.html +++ b/blog/tags/index.html @@ -3,18 +3,18 @@ -Tags | Casper Docs - Redux +Tags | Casper Docs - Redux - - + + + submit an issue on Github
      \ No newline at end of file diff --git a/blog/tags/new-docs/index.html b/blog/tags/new-docs/index.html index d33757047..c2d50d3d2 100644 --- a/blog/tags/new-docs/index.html +++ b/blog/tags/new-docs/index.html @@ -3,19 +3,19 @@ -One post tagged with "new docs" | Casper Docs - Redux +One post tagged with "new docs" | Casper Docs - Redux - - + +

      One post tagged with "new docs"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      + submit an issue on Github

      One post tagged with "new docs"

      View All Tags

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

      \ No newline at end of file diff --git a/blog/tags/setup/index.html b/blog/tags/setup/index.html index 455e78173..63ffbe521 100644 --- a/blog/tags/setup/index.html +++ b/blog/tags/setup/index.html @@ -3,18 +3,18 @@ -One post tagged with "setup" | Casper Docs - Redux +One post tagged with "Set-up" | Casper Docs - Redux - - + +

      One post tagged with "setup"

      View All Tags
      + submit an issue on Github

      One post tagged with "Set-up"

      Getting set up on Casper

      View All Tags
      \ No newline at end of file diff --git a/blog/tags/tokenomics/index.html b/blog/tags/tokenomics/index.html index 8ccb522da..ae10977ee 100644 --- a/blog/tags/tokenomics/index.html +++ b/blog/tags/tokenomics/index.html @@ -3,18 +3,18 @@ -One post tagged with "tokenomics" | Casper Docs - Redux +One post tagged with "tokenomics" | Casper Docs - Redux - - + +

      One post tagged with "tokenomics"

      View All Tags

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      + submit an issue on Github

      One post tagged with "tokenomics"

      View All Tags

      Fee Elimination in Condor

      · 9 min read
      Dylan Ireland
      Developer Advocate for Casper Association
      Mel Padden
      Head of Developer Relations for Casper Association

      The Casper 2.0 (aka Condor) network upgrade introduces new options to the way a Casper Network can be configured to handle gas consumption. Scheduled along with the release of Condor into Mainnet is a change in the configuration of the Casper Network to use a model known as Fee Elimination for gas payments. The purpose of this article is to introduce this model, and describe how Fee Elimination will affect the behavior of the Casper Network once Condor is released.

      \ No newline at end of file diff --git a/blog/tags/validators/index.html b/blog/tags/validators/index.html index 91db6a885..64ec8eb24 100644 --- a/blog/tags/validators/index.html +++ b/blog/tags/validators/index.html @@ -3,18 +3,18 @@ -One post tagged with "validators" | Casper Docs - Redux +One post tagged with "Validators" | Casper Docs - Redux - - + +

      One post tagged with "validators"

      View All Tags
      + submit an issue on Github

      One post tagged with "Validators"

      Validators

      View All Tags
      \ No newline at end of file diff --git a/blog/welcome-docs-redux/index.html b/blog/welcome-docs-redux/index.html index f2e165995..dfd91472c 100644 --- a/blog/welcome-docs-redux/index.html +++ b/blog/welcome-docs-redux/index.html @@ -3,19 +3,19 @@ -Casper Docs Redux! | Casper Docs - Redux +Casper Docs Redux! | Casper Docs - Redux - - + +

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      + submit an issue on Github

      Casper Docs Redux!

      · One min read
      Mel Padden
      Head of Developer Relations for Casper Association

      Welcome to the new-look Casper documentation portal. We have put a lot of thought into making the documentation more accessible, easier to move around, and easier on the eye. We have stripped away some visual clutter to allow you to focus on the content, and introduced versioning so that you can compare versions to see what has changed. This is obviously with a mind to the Condor changeover, as we thought it made a lot of sense to allow you to move between versions of the docs as you upgrade your systems and applications for Casper v2.0.

      Please enjoy and if you have any comments, suggestions or errata, please email devrel@casper.network with your contribution or query.

      \ No newline at end of file diff --git a/concepts/about/index.html b/concepts/about/index.html new file mode 100644 index 000000000..fd272eb93 --- /dev/null +++ b/concepts/about/index.html @@ -0,0 +1,29 @@ + + + + + +What is Casper? | Casper Docs - Redux + + + + + + + + + +
      Version: Next

      What is Casper?

      What is Casper?

      +

      Casper is a Turing-complete smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

      +

      The network's consensus protocol is called Zug, and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of finality, meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

      +

      Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's core features and strengths enable developers and enterprises to reap the benefits of blockchain technology.

      +

      Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises.

      +

      How does Casper work?

      +

      Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network.

      +

      To understand the design further, read this article.

      +

      Disclaimer

      +

      Read the Legal Disclaimer regarding this CasperLabs Tech Spec (this "Whitepaper").

      + + \ No newline at end of file diff --git a/concepts/accounts-and-keys/index.html b/concepts/accounts-and-keys/index.html index b01f88e31..121dcb0d8 100644 --- a/concepts/accounts-and-keys/index.html +++ b/concepts/accounts-and-keys/index.html @@ -1,33 +1,32 @@ - + -Accounts and Keys | Casper Docs - Redux +Accounts and Keys | Casper Docs - Redux - - + +
      Version: 1.5.X

      import useBaseUrl from '@docusaurus/useBaseUrl';

      -

      Accounts and Cryptographic Keys

      + submit an issue on Github
      Version: Next

      Accounts and Cryptographic Keys

      The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The AccountHash is a 32-byte hash derived from any of the supported PublicKey variants below to standardize keys that can vary in length.

      -

      By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

      +

      By default, a transactional interaction with the blockchain takes the form of a Transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

      The Casper platform supports two types of keys for creating accounts and signing transactions:

      • Ed25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long
      • -
      • Secp256k1 keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain
      • +
      • Secp256k1 keys, which use the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve; they are 68 bytes long and are also found on the Ethereum blockchain

      You can generate keys using both formats, and it is also possible to work with existing Ethereum keys.

      You can also generate an account hash from a public key with the Casper command-line client.

      Creating Accounts and Keys

      -

      When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the Casper command-line client or a block explorer. Developers must use the Casper command-line client as described below. Otherwise, they won't have access to the secret key file needed during development.

      +

      When you create an account on the Casper blockchain, a cryptographic key-pair will be created when using either the Casper command-line client or a block explorer.

      note

      SAVE your keys to a safe place, preferably offline.

      Option 1: Generating keys using the Casper Client

      This option describes how you can use the Casper command-line client to set up an account using either key type.

      @@ -56,7 +55,7 @@

      CSPR.live block explorer is available, and the following instructions assume you are using it.

      Start by creating an account using the Casper Wallet, Ledger, or Torus Wallet.

      -
      caution

      Developers must generate keys using the Casper command-line client to access the secret_key.pem file.

      The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined here.

      +
      caution

      The Casper Signer has been replaced with the Casper Wallet and will be deprecated. We recommend migrating all your Casper accounts to the Casper Wallet as outlined here.

      Funding your Account

      Once you create your account, you can fund the account's main purse to finish the process of setting it up.

      note

      Until you fund your account's main purse, it does not exist on the blockchain.

      @@ -68,12 +67,12 @@

      casper-client transfer \
      --transfer-id 1234567 \
      --node-address http://localhost:7777 \
      --chain-name casper \
      --target-account 020470fecd1f7ae5c1cd53a52c4ca88cd5b76c2926d7e1d831addaa2a64bea9cc3ede6a8e9981c609ee7ab7e3fa37ba914f2fc52f6eea9b746b6fe663afa96750d66 \
      --amount 10000000000 \
      --secret-key <path-to-secret_key.pem> \
      --payment-amount 100000000

      -
      tip

      The payment amount varies based on each deploy and network chainspec.

      -

      The Casper command-line client requires the secret key in PEM format to send a Deploy from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to PEM format is needed.

      +
      tip

      The payment amount varies based on each transaction and network chainspec.

      +

      The Casper command-line client requires the secret key in PEM format to send a transaction from this account. If you want to use existing Ethereum keys with the command-line client, a conversion to PEM format is needed.

      The following example is a JS script that generates a PEM file, using a key encoder and Node.js. To install these components, do the following:

      sudo apt install nodejs
      npm install key-encoder

      Then create the JS script convert-to-pem.js using vi or nano, and include this content:

      -
      var KeyEncoder = require("key-encoder"),
      keyEncoder = new KeyEncoder.default("secp256k1");
      let priv_hex = "THE SECRET KEY TO ENCODE";
      let priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");
      console.log(priv_pem);
      +
      var KeyEncoder = require('key-encoder'),
      keyEncoder = new KeyEncoder.default('secp256k1');
      let priv_hex = "THE SECRET KEY TO ENCODE";
      let priv_pem = keyEncoder.encodePrivate(priv_hex, "raw", "pem");
      console.log(priv_pem);

      Then run the script using Node.js and name the secret key.

      node convert-to-pem.js > eth-secret.pem

      To view the secret key, use cat <filename>:

      @@ -107,6 +106,6 @@

      casper-client get-account-info --help

      Using a block explorer

      Using the block explorer for Mainnet or Testnet, open the Account in question, and expand the Raw Data section. Look for the main_purse field and find the corresponding URef. If you do not see data in the Raw Data section, then the account has not been funded yet.

      -

      Image showing an account&#39;s main purse

      +

      Main purse

      \ No newline at end of file diff --git a/concepts/addressable-entity/index.html b/concepts/addressable-entity/index.html new file mode 100644 index 000000000..9c9cb7c92 --- /dev/null +++ b/concepts/addressable-entity/index.html @@ -0,0 +1,40 @@ + + + + + +Addressable Entities | Casper Docs - Redux + + + + + + + + + +
      Version: Next

      Addressable Entities

      +

      What is an Addressable Entity?

      +

      The AddressableEntity data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system. +Casper 2.0 introduces the concept of an AddressableEntity which replaces the existing Account and Contract types.

      +

      The merger of the Account and Contract concepts allows for some new possibilities.

      +

      For any given AddressableEntity, the EntityType will identify if it is an Account, a user-deployed SmartContract, or a System contract such as Mint or HandlePayment.

      +

      This EntityType will dictate what the addressable entity can and cannot do.

      +

      Account

      +

      An addressable entity marked as an Account will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a PublicKey and a secret key, and an AccountHash derived from the public key. There is also an associated main purse.

      +

      A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same.

      +

      SmartContract

      +

      An addressable entity marked as a SmartContract will have the same functionality as a legacy contract, but with several new features. The SmartContract now possesses a main purse, and may have associated keys and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found here.

      +

      System

      +

      As part of the migration to Casper 2.0, system contracts (Mint, Auction and HandlePayment) will migrate to a special type of addressable entity with the EntityType of System. The StandardPayment system contract will be pruned away.

      +

      Further Reading

      +
      + + \ No newline at end of file diff --git a/concepts/callstack/index.html b/concepts/callstack/index.html index b47a160a6..285d1636b 100644 --- a/concepts/callstack/index.html +++ b/concepts/callstack/index.html @@ -1,33 +1,33 @@ - + -Call Stacks | Casper Docs - Redux +Call Stacks | Casper Docs - Redux - - + +
      Version: 1.5.X

      Understanding Call Stacks

      -

      Users wishing to interact with a Casper network must do so through sending a Deploy. All Deploys consist of session code run in the context of the user account that sent the Deploy. The session code may install contract code to global state, or interact with previously installed contract code.

      -

      When the session code within a Deploy interacts with one or more contracts, this is the beginning of a Call Stack. A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code.

      + submit an issue on Github
      Version: Next

      Understanding Call Stacks

      +

      Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.

      +

      When the session code within a transaction interacts with one or more contracts, this is the beginning of a Call Stack. A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code.

      The Caller

      -

      In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the zeroth entity in each call stack. The account that initiated the deploy can be retrieved with the contract_api::runtime::get_caller function.

      +

      In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the zeroth entity in each call stack. The account that initiated the transaction can be retrieved with the contract_api::runtime::get_caller function.

      The Call Stack

      Developers can access the call stack with the contract_api::runtime::get_call_stack function.

      If session code calls a contract, which in turn calls another contract, then the session code would represent the zeroth entity in the stack, the contract called by the initiating session code would be the first and the contract called by the first contract would be the second.

      In this example, the first contract would be the immediate caller of the second contract, meaning it interacted directly with it. The session code would remain the caller.

      -

      +

      Call Stack

      Limitations

      Casper networks place a limitation on the maximum height of a call stack. This value can be set within the chainspec for the network in question. For the Casper Mainnet, this limit is set at 10 contracts. This does not include the initiating session code, which would still count as the zeroth instance within the stack.

      As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation.

      -
      note

      Contract code cannot call session code, only other contract code.

      +
      note

      Contract code cannot call session code, only other contract code.

      \ No newline at end of file diff --git a/concepts/design/casper-design/index.html b/concepts/design/casper-design/index.html index 05df8548e..22211d951 100644 --- a/concepts/design/casper-design/index.html +++ b/concepts/design/casper-design/index.html @@ -1,25 +1,24 @@ - + -Network Design | Casper Docs - Redux +Network Design | Casper Docs - Redux - - + +
      Version: 1.5.X

      import useBaseUrl from '@docusaurus/useBaseUrl';

      -

      Casper Network Design

      + submit an issue on Github
      Version: Next

      Casper Network Design

      Introduction

      -

      Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a Deploy. Deploys contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

      -

      A deploy executes in the context of the user's Account but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an Unforgeable Reference or URef. After a node accepts a deploy as valid, it places the deploy in a proposed Block and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the deploy.

      +

      Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. A Casper network stores data in a structure known as Global State. Users interact with global state through session code sent in a transaction. Transactions may contain Wasm to be executed by the network, thus allowing developers to use their preferred programming language rather than a proprietary language.

      +

      A transaction executes in the context of the user's Account but can call stored Wasm that will execute in its own context. User-related information other than an account is stored in global state as an Unforgeable Reference or URef. After a node accepts a transaction as valid, it places the transaction in a proposed Block and gossips it among nodes until the network reaches consensus. At this point, the network executes the Wasm included within the transaction.

      1. Execution Semantics

        @@ -42,15 +41,15 @@

        Exe

        Measuring Computational Work

        Computation is done in a WebAssembly (Wasm) interpreter, allowing any programming language which compiles to Wasm to become a smart contract language for the Casper blockchain. Similar to Ethereum, Casper uses Gas to measure computational work in a way that is consistent from node to node in a Casper network. Each Wasm opcode is assigned a Gas cost, and the amount of gas spent is tracked by the runtime with each opcode executed by the interpreter.

        Costs for opcode instructions on the Casper Mainnet network can be found here.

        -

        All executions are finite because each has a finite gas limit that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the deploy. The gas limit is set by executing the payment code specified within the deploy.

        +

        All executions are finite because each has a finite gas limit that specifies the maximum amount of gas available to spend before the runtime terminates the computation. The payment executable session determines how to pay for the transaction. The gas limit is set by executing the payment code specified within the transaction.

        Although the network measures costs in Gas, payment for computation occurs in motes. Therefore, there is a conversion rate between Gas and motes.

        -
        note

        Please note that Casper will not refund any amount of unused gas.

        This decision is taken to incentivize the Casper Runtime Economics by efficiently allocating the computational resources. The consensus-before-execution model implements the mechanism to encourage the optimized gas consumption from users and to prevent the overuse of block space by poorly handled deploys.

        +
        note

        Casper networks support configurable fee, refund, and pricing strategies to incentivize the Casper Runtime Economics by efficiently allocating computational resources. The consensus-before-execution model implements the mechanism to encourage optimized gas consumption from users and to prevent the overuse of block space by poorly handled transactions.

        The Casper Network Runtime

        A Wasm module is not natively able to create any effects outside of reading or writing from its own linear memory. Wasm modules must import functions from the host environment they are running in to enable other desired effects, such as reading or writing to global state.

        Casper Network Runtime

        All these features are accessible via functions in the Casper External FFI.

        Generating URefs

        -

        URefs are generated using a cryptographically secure random number generator using the ChaCha algorithm. The random number generator is seeded by taking the blake2b256 hash of the deploy hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same deploy).

        +

        URefs are generated using a cryptographically secure random number generator using the ChaCha algorithm. The random number generator is seeded by taking the blake2b256 hash of the transaction hash concatenated with an index representing the current phase of execution (to prevent collisions between URefs generated in different phases of the same transaction).

        Generating URefs

        Accounts

        The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey. The global state trie store requires all keys to be the same length, so the AccountHash is a 32-byte derivative used to abstract any of the supported public key variants.

        @@ -59,7 +58,7 @@

        AccountsEd25519 keys, which use the Edwards-curve Digital Signature Algorithm (EdDSA) and are 66 bytes long

      2. Secp256k1 keys, commonly known as Ethereum keys, which are 68 bytes long
    -

    By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "deploys") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see Tokens for more information).

    +

    By default, a transactional interaction with the blockchain takes the form of a transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account. All user activity on the Casper blockchain (i.e., "transactions") must originate from an account. Each account has its own context where it can locally store information (e.g., references to useful contracts, metrics, and aggregated data from other parts of the blockchain). Each account also has a "main purse" where it can hold Casper tokens (see Tokens for more information).

    This chapter describes the permission model for accounts and their local storage capabilities and briefly mentions some runtime functions for interacting with accounts.

    Creating an account

    Account creation automatically happens upon transferring tokens to a yet unused PublicKey. On account creation, the balance of its main purse is equal to the number of tokens transferred during the creation process. Its action thresholds are equal to 1, and there is one associated key. The associated key is the PublicKey used to create the account. In this way, an account is essentially a context object encapsulating the main purse, used to pay for transactions. However, an account may have an additional purse beyond the main purse.

    @@ -73,10 +72,10 @@

    Creating a

    Permissions Model

    Actions and Thresholds

    -

    An account can perform two types of actions: sending deploys and managing keys. A deploy is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a deploy; therefore, a key management action implies that a deploy action is also taking place.

    -

    The ActionThresholds contained in the Account data structure set a Weight, which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a deploy action, the key management threshold should always be greater than or equal to the deploy threshold.

    +

    An account can perform two types of actions: sending transactions and managing keys. A transaction is simply executing some code on the blockchain, while key management involves changing the associated keys (which will be described in more detail later). Key management cannot be performed independently, as all effects on the blockchain must come via a transaction; therefore, a key management action implies that a transaction is also taking place.

    +

    The ActionThresholds contained in the Account data structure set a Weight, which must be met to perform that action. The next section describes these weight thresholds. Since a key management action requires a transaction, the key management threshold should always be greater than or equal to the transaction threshold.

    Associated Keys and Weights

    -

    Accounts on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An account's associated keys are the set of public keys allowed to provide signatures on deploys for that account. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each deploy must be signed by one or more keys associated with the account that deploy is for, and the sum of the weights of those keys must be greater than or equal to the deployment threshold weight for that account. We call the keys that have signed a deploy the "authorizing keys". Similarly, if a deploy contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the account.

    +

    Addressable entities on a Casper network can associate other key pairs through a multiple signature scheme for sending transactions. An addressable entity's associated keys are the set of public keys allowed to provide signatures on transactions for that entity. Each associated key has a weight; these weights combine to meet the action thresholds provided in the previous section. Each transaction must be signed by one or more keys associated with the entity that transaction is for, and the sum of the weights of those keys must be greater than or equal to the transaction threshold weight for that account. We call the keys that have signed a transaction the "authorizing keys". Similarly, if a transaction contains key management actions (detailed below), the sum of the weights of the authorizing keys must be greater than or equal to the key management action threshold of the entity.

    note

    Any key may help authorize any action; there are no "special keys". All keys contribute their weight in exactly the same way.

    Key Management Actions

    A key management action is a change to the account permissions, including:

    @@ -87,13 +86,13 @@

    Key

    Key management actions have validity rules preventing users from locking themselves out of their accounts. For example, one can set a threshold, at most, the sum of the weights of all associated keys.

    Account security and recovery using key management

    -

    This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign deploys from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the deploy threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone.

    +

    This permissions model's purpose is to keep accounts safe from lost or stolen keys while allowing the usage of modern mobile devices. For example, it may be convenient to sign transactions from a smartphone without worrying about the repercussions of losing the phone. The recommended setup is to have a low-weight key on the phone, enough for the transaction threshold but not enough for key management. If the phone is lost or stolen, a key management action using other associated keys from another device (e.g., a home computer) can be used to remove the lost associated key and add a key that resides on a replacement phone.

    note

    It is extremely important to ensure there will always be access to a sufficient number of keys to perform the key management action. Otherwise, future recovery will be impossible (Casper currently does not support "inactive recovery").

    The Account Context

    -

    A deploy is a user request to perform some execution on the blockchain (see Execution Semantics for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the account signing the deploy. This means that the executing Wasm has access to the named keys and main purse of the account's context.

    -
    note

    In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account.

    +

    A transaction is a user request to perform some execution on the blockchain (see Execution Semantics for more information). It contains "payment code" and "session code", which are references to stored on-chain contracts or Wasm to be executed. For executable Wasm, its execution and the logic therein occur within the context of the entity signing the transaction. This means that the executing Wasm has access to the named keys and main purse of the account entity's context.

    +
    note

    In the case where there is a reference to stored on-chain Wasm (smart contracts), the execution of the on-chain Wasm will occur in its own separate runtime context. As a result, the stored Wasm will not have access to the named keys or main purse of the calling account entity.

    Unforgeable Reference (URef)

    -

    This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

    +

    This key type is used for storing any value except Account. Additionally, URefs used in Wasm carry permission information to prevent unauthorized usage of the value stored under the key. The runtime tracks this permission information. This means that if malicious Wasm attempts to produce a URef with permissions that the Wasm does not have, the Wasm has attempted to "forge" the unforgeable reference, and the runtime will raise a forged URef error. Permissions for a URef can be given across contract calls, allowing data stored under a URef to be shared in a controlled way. The 32-byte identifier representing the key is generated randomly by the runtime (see Execution Semantics for more information). The serialization for Access Rights that define the permissions for URefs is detailed in the CLValues section.

    Permissions for URefs

    In the runtime, a URef carries its permissions called AccessRights. Additionally, the runtime tracks what AccessRights would be valid for each URef in each context. The system assumes that a sent URef is invalid, regardless of declared AccessRights, and will check it against the executing context to determine validity on each usage. Only the host logic can add a URef, in the following ways:

      @@ -105,8 +104,8 @@

      Permissions

      Note that only valid URefs may be added to the known URefs or cross-call boundaries; this means the system cannot be tricked into accepting a forged URef by getting it through a contract or stashing it in the known URefs.

      The ability to pass URefs between contexts via call_contract / ret, allows them to share state among a fixed number of parties while keeping it private from all others.

      URefs and Purses

      -

      Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual accounts do not own ‘URef’s. As described above, accounts and contracts possess certain Access Rights, allowing them to interact with the given URef. While an account will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

      -

      Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of accounts and contracts as required.

      +

      Purses represent a unique type of URef used for accounting measures within a Casper network. URefs exist as a top-level entity, meaning that individual entities do not own ‘URef’s. As described above, entities possess certain Access Rights, allowing them to interact with the given URef. While an account entity will possess an associated URef representing their main purse, this URef exists as a Unit and corresponds to a balance key within the Casper mint. The individual balance key within the Casper mint is the account entity's purse, with transfers authorized solely through the associated URef and the Access Rights granted to it.

      +

      Through this logic, the Casper mint holds all motes on the network and transfers between balance keys at the behest of entities as required.

      Block Structure

      A block is the primary data structure by which network nodes communicate information about the state of a Casper network. We briefly describe here the format of this data structure.

      Data Fields

      @@ -120,7 +119,7 @@

      Data Fi

      block_hash

      The block_hash is the blake2b256 hash of the block header.

      -

      The block header contains the following fields:

      +

      The block header contains the following fields:

      • parent_hash

        @@ -164,11 +163,11 @@ -

        The block body contains an ordered list of DeployHashes which refer to deploys, and an ordered list of DeployHashes for native transfers (which are specialized deploys that only transfer tokens between accounts). All deploys, including a specialization such as native transfer, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no deploys and / or native transfers.

        +

        The block body contains an ordered list of transaction hashes. All transactions, including mint, auction, install_upgrade and standard transactions, can be broadly categorized as some unit of work that, when executed and committed, affect change to Global State. A valid block may contain no transactions.

        The block body also contains the public key of the validator that proposed the block.

        -

        Refer to the Serialization Standard for additional information on how blocks and deploy are serialized.

        +

        Refer to the Serialization Standard for additional information on how blocks and transactions are serialized.

        Tokens

        -

        Casper is a decentralized Proof-of-Stake blockchain platform that uses a consensus algorithm called Highway. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

        +

        Casper is a decentralized Proof-of-Stake blockchain platform that may use either the Highway or Zug consensus mechanisms. Having a unit of value is required to make this system work because users must pay for computation, and validators must have stake to bond. In the blockchain space, this unit of value is a token.

        This chapter describes tokens and how one can use them on the Casper platform.

        Token Generation and Distribution

        A blockchain system generally needs a supply of tokens available to pay for computation and reward validators for processing transactions on the network. The initial supply at the launch of Mainnet was 10 billion CSPR. The current supply is available here. In addition to the initial supply, the system will have a low rate of inflation, the results of which will be paid out to validators in the form of seigniorage.

        @@ -177,10 +176,10 @@

        Divisibility of Tokens

        Typically, a token is divisible into some number of parts. We call the indivisible units which make up the CSPR token motes. Each CSPR is divisible into 109 motes. To avoid rounding errors, it is essential to always represent token balances in motes. In comparison, Ether is divisible into 1018 parts called Wei.

        The concept of CSPR is human-readable convenience and does not exist within the actual infrastructure of a Casper network. Instead, all transactions deal solely with motes.

        -

        Purses and Accounts

        -

        All accounts on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that account (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account. This function uses the mint transfer function with the current account's main purse as the source and the main purse of the account at the provided key as the target.

        +

        Purses and Addressable Entities

        +

        All entities on the Casper system have a purse associated with the Casper system mint, called the main purse. However, for security reasons, the URef of the main purse is only available to code running in the context of that entity (i.e. only in payment or session code). Therefore, the mint's transfer method that accepts URefs is not the most convenient when transferring between account entity main purses. For this reason, Casper supplies a transfer_to_account function, which takes the public key used to derive the identity key of the account entity. This function uses the mint transfer function with the current account entity's main purse as the source and the main purse of the account entity at the provided key as the target.

        The Casper Mint Contract

        -

        The Casper mint is a system contract that manages the balance of motes within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each Account's main purse. Each balance is associated with a URef, which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as purses and conceptually represent a container for motes. The URef is how a purse is referenced externally, outside the mint.

        +

        The Casper mint is a system contract that manages the balance of motes within a Casper network. These motes are used to pay for computation and bonding on the network. The mint system contract holds all motes on a Casper network but maintains an internal ledger of the balances for each entity's main purse. Each balance is associated with a URef, which is a key to instruct the mint to perform actions on that balance (e.g., transfer motes). Informally, these balances are referred to as purses and conceptually represent a container for motes. The URef is how a purse is referenced externally, outside the mint.

        The AccessRights of the URefs permissions model determines what actions can be performed when using a URef associated with a purse.

        As all URefs 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:

        @@ -232,6 +231,6 @@

        The mi
      • BalanceResult either returns the number of motes held by the purse, or nothing if the URef is not valid
      -
    +
    \ No newline at end of file diff --git a/concepts/design/consensus/index.html b/concepts/design/consensus/index.html new file mode 100644 index 000000000..75df56922 --- /dev/null +++ b/concepts/design/consensus/index.html @@ -0,0 +1,68 @@ + + + + + +Consensus in a Casper Network | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Consensus in a Casper Network

    +

    The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.

    +

    Safety, Liveness, and Byzantine Fault Tolerance

    +

    In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The Transaction Lifecycle describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called safety.

    +

    The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called liveness.

    +

    Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a Byzantine fault and thus secure against malicious activity.

    +

    To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:

    +
      +
    • +

      Safety: All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain.

      +
    • +
    • +

      Liveness: The network runs indefinitely and adds new blocks to the chain.

      +
    • +
    • +

      Byzantine Fault Tolerance (BFT): All honest nodes eventually agree on the final value, even if some are faulty.

      +
    • +
    +

    Casper Consensus Protocols

    +

    Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are Zug and Highway. Highway served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast, which describes how Zug meets the safety, liveness, and resiliency requirements.

    +

    Consensus in the Casper Mainnet

    +

    The Casper Mainnet is a Proof-of-Stake network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of nodes, which participate in the consensus process by staking CSPR tokens. These active nodes are known as validators. The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus.

    +

    The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are honest nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly.

    +
    note

    The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model.

    +

    Dynamic Round Length

    +

    Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner.

    +

    Eras

    +

    The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:

    +
      +
    • +

      Data Reduction - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.

      +
    • +
    • +

      Banning Equivocators - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras.

      +
    • +
    +
      +
    • Rotating Validators - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (current era+ 2).
    • +
    +

    In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (current era + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain.

    +

    The final block of an era is a switch block and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the switch block and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the Consensus Economics page.

    +

    Finality

    +

    Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart.

    +

    On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously.

    + +
      +
    • Zug Consensus - An overview of the Zug consensus used in Mainnet and Testnet
    • +
    • Highway Consensus - Brief overview of the Highway consensus available as an alternative to Zug
    • +
    + + \ No newline at end of file diff --git a/concepts/design/highway/index.html b/concepts/design/highway/index.html index 58d1f715b..04facc7a0 100644 --- a/concepts/design/highway/index.html +++ b/concepts/design/highway/index.html @@ -1,58 +1,45 @@ - + -Highway Consensus | Casper Docs - Redux +Highway Consensus | Casper Docs - Redux - - + +
    Version: 1.5.X

    The Highway Consensus Protocol

    -

    What is Consensus?

    -

    Consensus is the backbone of any distributed network. The decentralized nature of a blockchain requires a method through which disparate entities can agree on one immutable truth. This involves determining the validity of transactions, resolving conflicts, and finalizing blocks to be added to the chain by the network. A consensus protocol is a set of mechanisms and rules within the distributed network with which all actors must comply.

    -

    These rules outline the type of messages sent over the network, when they are sent and how to process them. Within the context of a blockchain, the consensus protocol decides which blocks are added to the chain by the network and the order in which they are added. This determines the state of the distributed ledger and ensures that all nodes agree on that state.

    -

    The consensus mechanism will determine how a blockchain meets the following requirements:

    + submit an issue on Github
    Version: Next

    The Highway Consensus Protocol

    +

    The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.

    +

    Unit Broadcasting

    +

    In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:

      -
    • -

      Safety - All honest nodes eventually agree on the final value. The system is setup in a way where no two honest nodes will report two different blocks at the same height of the blockchain.

      -
    • -
    • -

      Liveness - The system continues running and adds new blocks to the chain indefinitely.

      -
    • +
    • Citations of other units (at most one per node), subject to validity conditions
    • +
    • An optional proposed list of transactions to be included in a block. Note that the list can be empty
    • +
    • The unit's creator and its digital signature
    • +
    • Additional metadata, including a timestamp, sequence number, round length, etc.
    -

    What is Highway Consensus?

    -

    Casper networks use a consensus protocol called Highway, ensuring the Safety and Liveness requirements of these networks. Highway is a Byzantine Fault Tolerant protocol requiring a partially synchronous network.

    -

    How does the Casper Mainnet use Highway?

    -

    The Casper Mainnet is a Proof-of-Stake network in which the on-chain auction contract determines validators participating in Highway. The protocol uses a decentralized network of nodes, either bonded or unbonded. Nodes actively participating in the consensus process must stake CSPR tokens and are known as Validator Nodes. The top 100 bidders are selected through the auction contract every era to act as validators in the era after the next (Current Era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus. Highway does not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model.

    -

    These validators run a Casper network that will continue to function so long as the amount of faulty or dishonest nodes does not exceed one-third of the total number of nodes in the network. Nodes that are not faulty are honest nodes. In most cases, the system can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly. A block's fault tolerance increases beyond one-third as the protocol continues. If all validators are honest, it approaches 100%.

    -

    Dynamic Round Length

    -

    Within the Highway protocol, the length of a round is determined dynamically to ensure a suitable amount of time for nodes to gossip all messages through several round trips with honest validators. This ensures that the system maintains liveness by ensuring that all messages are properly gossiped while maintaining a timely addition of blocks to the chain.

    -

    Eras

    -

    The concept of eras allows Highway to reduce the overall operational storage requirements of participating nodes while also rotating validators. A new instance of Highway runs every two hours or approximately 220 blocks, depending on current network metrics. This allows for two benefits:

    +

    An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn't clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.

    +

    Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges.

    +

    DAG

    +

    Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator.

    +

    The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era.

    +

    Block Finalization

    +

    In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum q, a percentage of the participating validator weight, and a level k. Level k represents the depth in the graph. For a given fault tolerance threshold t (FTT), finality is defined as:

    +

    Finality Equation

    +

    If q is close to n, meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT).

    +

    The existence of such a summit means that a weight of more than t would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block.

    +

    In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network.

    +
      -
    • -

      Data Reduction - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.

      -
    • -
    • -

      Banning Equivocators - Dishonest nodes caught equivocating in a previous era are banned from participating in new eras. This allows honest nodes to begin a new era in the relaxed mode, no longer needing to send endorsements due to past equivocations.

      -
    • -
    • -

      Rotating Validators - Bonded nodes bid on validator spots each era, with the top 100 highest bidders becoming validators for the era after next (N+2).

      -
    • -
    -

    In any given era, node operators will bid to become validators that will participate in the consensus mechanism for the era after next (N+2). Each time slot within the era will also determine a lead validator. The lead validator proposes new blocks to be added to the chain, which are then gossiped among the network's nodes. These messages show an implicit preference for the lead validator's block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. Once this process reaches critical mass, with a sufficient interconnected pattern of messages, it becomes impossible to switch to another block. The selected block is then considered finalized and added to the chain.

    -

    The final block of an era is a switch block and forms the initial state of the next era. A new Highway instance begins with the new era, using information contained within the switch block and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the Consensus Economics page.

    -

    Finality

    -

    Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require greater than 1/3 of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart.

    -

    On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously.

    -

    Highway's criterion for detecting finality is the presence of a pattern of messages called a Summit. It is an improvement over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect. Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time.

    +
  • Highway Whitepaper - Describes the protocol, and the liveness and safety proofs in detail
  • +
  • Zug Consensus - The protocol currently used in Mainnet and Testnet
  • +
    \ No newline at end of file diff --git a/concepts/design/networking-protocol/index.html b/concepts/design/networking-protocol/index.html index 81570532a..ad4fd57bd 100644 --- a/concepts/design/networking-protocol/index.html +++ b/concepts/design/networking-protocol/index.html @@ -1,21 +1,21 @@ - + -Casper Node Networking Protocol | Casper Docs - Redux +Casper Node Networking Protocol | Casper Docs - Redux - - + +
    Version: 1.5.X

    Casper Node Networking Protocol

    + submit an issue on Github
    Version: Next

    Casper Node Networking Protocol

    Casper Node Networking Protocol (Mainnet Protocol Version 1.5.0)

    This is a description of the casper-node's networking protocol. This document follows the conventions laid out in RFC2119.

    Connection Level

    @@ -89,7 +89,7 @@

    The P

    The Payload (found in the node sources as Message in payload.rs) contains variants for all node-to-node communicating subsystems of a running node, which are described below. Note that some of the variants have been renamed for clarity in this specification. Since field names are not used in bincode encoding, this should have no effect on implementations.

    enum Payload {
    Consensus(ConsensusMessage),
    DeployGossiper(DeployGossiperMessage),
    AddressGossiper(AddressGossiperMessage),
    GetRequest {
    tag: Tag,
    serialized_id: Vec<u8>,
    },
    GetResponse {
    tag: Tag,
    serialized_item: Vec<[u8]>,
    },
    FinalitySignature(FinalitySignature),
    }

    enum DeployGossiperMessage {
    Gossip(DeployHash),
    GossipResponse {
    item_id: DeployHash,
    is_already_held: bool,
    },
    }

    enum AddressGossiperMessage {
    Gossip(GossippedAddress),
    GossipResponse {
    item_id: GossippedAddress,
    is_already_held: bool,
    },
    }

    struct DeployHash(Digest);
    struct GossipedAddress(SocketAddr);

    Consensus

    -

    A consensus message is sent exclusively between instances of the consensus component, from one peer to another. A precise description of the Highway consensus protocol is out of scope of this document, see the consensus::Message type or an appropriate description of the underlying protocol for details.

    +

    A consensus message is sent exclusively between instances of the consensus component, from one peer to another.

    Gossiping

    Gossiping messages are sent by a node to a subset of its peers to announce the availability of new data items. Peers MUST be distinguished by NodeID, not by listening address.

    A node must support a gossiper for deploys and one for GossippedAddress, which is an alias for the regular Rust standard library's SocketAddr.

    @@ -117,7 +117,7 @@

    GetRequestsIf the item was found, serialized_item MUST contain a serialized FetchedOrNotFound::Fetched instance, with the inner value T being the item.

    If the item was not found, serialized_item MUST contain a FetchedOrNotFound::NotFound instance, with the inner value Id being the ID found in the originating GetRequest.

    A node MUST not send any items to a peer that it itself has not verified.

    -

    The following table shows which tag corresponds to which ID and item type. Type definitions for DeployHash and GossippedAddress can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the Serialization Standard, but be aware that those docs describe serializing using bytesrepr rather than bincode.

    +

    The following table shows which tag corresponds to which ID and item type. Type definitions for DeployHash and GossippedAddress can be found earlier in this document, other types are described following this section. Further details of many of these types can be found in the Serialization Standard, but be aware that those docs describe serializing using bytesrepr rather than bincode.

    @@ -204,6 +204,6 @@

    Trie Chunking<

    Large trie nodes are split when transferred across the network, according to CHUNK_SIZE_BYTES, which is set to 8388608 bytes (8 megabytes). Any trie node that is less than 8388608 in size will be represented by a TrieOrChunk::Trie instance.

    Should a trie node be larger than this, a Merkle tree is constructed with CHUNK_SIZE_BYTES sized chunks and is identified by the root hash of the resulting tree instead.

    Peers MUST only request chunks. The TrieOrChunkId type allows for requesting the n-th chunk of a given trie node. See the casper-hashing crate for details.

    -

    A node receiving a TrieOrChunk item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it.

    +

    A node receiving a TrieOrChunk item from a peer MUST validate it by checking the given Merkle proof against the item hash (which is the tree's root hash), before accepting it.

    \ No newline at end of file diff --git a/concepts/design/p2p/index.html b/concepts/design/p2p/index.html index 69cb9fad6..245d453fb 100644 --- a/concepts/design/p2p/index.html +++ b/concepts/design/p2p/index.html @@ -1,21 +1,21 @@ - + -Network Communication | Casper Docs - Redux +Network Communication | Casper Docs - Redux - - + +
    Version: 1.5.X

    Network Communication

    + submit an issue on Github
    Version: Next

    Network Communication

    Identity

    Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID.

    Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint.

    @@ -30,7 +30,7 @@

    NetworkGossiping

    -

    Multiple types of objects are gossipped, the most prominent ones being blocks, deploys, and endpoints (see Identity). Each of these objects is immutable and can be identified by a unique hash.

    +

    Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see Identity). Each of these objects is immutable and can be identified by a unique hash.

    Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed.

    The process can be summarized as follows:

    Given a message M to gossip, the desired saturation S, and an infection limit L:

    @@ -42,12 +42,12 @@

    Gos

    Through this process, a message will spread to almost all nodes over time.

    Requesting missing data

    -

    While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing deploy from a block.

    +

    While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block.

    Validation

    -

    Objects have a concept of dependencies. For example, a block depends on all the deploys whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node.

    +

    Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node.

    Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved.

    Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so.

    Node Discovery

    -

    Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful.

    +

    Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful.

    \ No newline at end of file diff --git a/concepts/design/reading-and-writing-to-the-blockchain/index.html b/concepts/design/reading-and-writing-to-the-blockchain/index.html index 51795770c..d77019939 100644 --- a/concepts/design/reading-and-writing-to-the-blockchain/index.html +++ b/concepts/design/reading-and-writing-to-the-blockchain/index.html @@ -1,25 +1,25 @@ - + -Reading and Writing Data | Casper Docs - Redux +Reading and Writing Data | Casper Docs - Redux - - + +
    Version: 1.5.X

    Reading and Writing Data to Global State

    + submit an issue on Github
    Version: Next

    Reading and Writing Data to Global State

    Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.

    -
    note

    Due to the nature of Casper's serialization standard, NamedKeys should be used sparingly and only for small data sets. Developers should use dictionaries for larger mapped structures.

    +
    note

    Casper's Condor release shifts NamedKeys to a top-level key type, making them more viable for larger data sets.

    Using the Casper JSON-RPC

    -

    The query_global_state method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the Querying a Casper Network tutorial.

    +

    The query_global_state method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the Querying a Casper Network tutorial.

    Using the Casper Rust API

    The Casper API includes the following functions for reading and writing to global state:

      @@ -31,6 +31,6 @@

      Us
    • dictionary_put - Writes the given value under the given dictionary_item_key
    • dictionary_get - Retrieves the value stored under a dictionary_item_key
    -

    For more details, see the Reading and Writing to Global State using Rust tutorial.

    +

    For more details, see the Reading and Writing to Global State using Rust tutorial.

    \ No newline at end of file diff --git a/concepts/design/rewards/index.html b/concepts/design/rewards/index.html new file mode 100644 index 000000000..a82c133ab --- /dev/null +++ b/concepts/design/rewards/index.html @@ -0,0 +1,67 @@ + + + + + +Rewards Design | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Network Participation Rewards

    +

    Validators receive rewards for participating in consensus and thus securing the network. Delegators also receive rewards indirectly by staking with a validator. This page serves as an introduction to how the rewards are calculated and distributed. For more details, refer to the corresponding CEP.

    +

    Like other Proof-of-Stake chains, a Casper network rewards validators for participating in building a linear chain of blocks, each containing ordered state changes and ensuring that the entire ecosystem of validators, builders, and users eventually achieve common knowledge of the chain's history. External, non-validator participants in the ecosystem can thus have a high degree of confidence on the canonical history of the blockchain's state, thus making the blockchain economically useful.

    +

    The network uses a new reward scheme that does not depend on the details of the consensus protocol and is compatible with both Zug and Highway. The current reward scheme has the following properties:

    +
      +
    • Rewards are proportional to a validator's weight on average.
    • +
    • The reward scheme incentivizes cooperation.
    • +
    • Rewards are distributed at the end of an era for all blocks in that era and several eligible blocks from the previous era.
    • +
    • Reward calculations depend only on the linear structure of the blockchain and published finality signatures, rather than any internal details of the consensus protocol.
    • +
    • Reward calculations assume a known constant token supply inflation with nominal platform operation.
    • +
    +

    Previously, with Highway, the reward scheme incentivized block production and participation in their finalization. Unfortunately, this scheme was highly coupled with the consensus protocol and unsuitable for adaptation with the Zug consensus. The current scheme calculates rewards after blocks have been finalized, as described below.

    +

    Calculating Rewards

    +

    The execution engine calculates rewards for block production and finality signature generation and distribution in each switch block. Finality signatures are produced after a block has been finalized by consensus. Thus, rewards are independent of the consensus algorithm used. Block proposers collect those finality signatures and include them in future blocks. The rewards scheme allows blocks to cite finality signatures for several past blocks so that validators can agree on which finality signatures have been produced and should be rewarded. This mechanism to "look back" is necessary because signatures cannot be distributed instantly.

    +

    Rewards are divided into these categories:

    +
      +
    • Block rewards: These rewards are received for each proposed block that is finalized. They incentivize timely participation in building the chain.
    • +
    • Finality signature rewards: These rewards are received for collecting finality signatures for each block and generating a finality signature to sign a block. They incentivize the creation, propagation and publication of finality signatures, which is critical in establishing common knowledge of the canonical chain.
    • +
    +

    In each round, a total reward pool is shared among all participating validators proportionally to their weight, as long as all validators fully participate in the processes that are rewarded by this mechanism. These processes are block creation, signature creation, signature propagation and signature publication as part of block proposals.

    +

    The round_seigniorage_rate setting in the chainspec determines the total reward pool for a block. This value, along with the current total supply and minimum round length, is used to compute the full allocation of rewards for a particular block. The rate itself is set to result in a target annual inflation, provided validators fully participate in the rewardable processes described above.

    +

    Each switch block triggers a reward calculation. To account for potential network lag delaying the timely arrival of signatures for finalized blocks, the calculation "looks back" into previous eras. In particular, this enables rewards for switch blocks, which was impossible with the prior Highway-specific calculation. The number of prior blocks to look up is specified using the signature_rewards_max_delay setting in the chainspec.

    +

    Blocks carry information on their proposer and the finality signatures collected for several past blocks, the depth being determined by the signature_rewards_max_delay parameter. Global state contains data on token supply and validator weights as part of the Mint and Auction states. Based on these inputs, the rewards are calculated according to a formula. Rewards are designed to be proportional to weight on average, as long as blocks are created and the finality signatures are propagated and published in a timely manner.

    +

    Validators are motivated to produce, propagate and publish (i.e., include in the block body) finality signatures as quickly as possible. If they do not include a finality signature in a block, the next validator can include it in their block and get the collection fee.

    +

    Chainspec settings for calculating rewards

    +

    Each Casper network chainspec contains 4 settings related to calculating rewards:

    +
      +
    • finality_signature_proportion: The proportion of baseline rewards going to reward finality signatures, rather than block proposal rewards.
    • +
    • finders_fee: The proportion of the rewards allocated to finality signatures that are due for signature publication in a block proposal.
    • +
    • signature_rewards_max_delay: The number of prior blocks to include for the reward calculation.
    • +
    • round_seigniorage_rate: Setting that calculates the fraction of the total supply that will constitute the reward pool for every round.
    • +
    +
    Expand to see sample values
    + +
    # The split in finality signature rewards between block producer and participating signers.
    finders_fee = [1, 5]
    # The proportion of baseline rewards going to reward finality signatures specifically.
    finality_signature_proportion = [1, 2]
    # Lookback interval indicating which past block we are looking at to reward.
    signature_rewards_max_delay = 3
    ...
    # Round seigniorage rate represented as a fraction of the total supply.
    #
    # Annual issuance: 8%
    # Minimum block time: 2^14 milliseconds
    # Ticks per year: 31536000000
    #
    # (1+0.08)^((2^14)/31536000000)-1 is expressed as a fractional number below
    # Python:
    # from fractions import Fraction
    # Fraction((1 + 0.08)**((2**14)/31536000000) - 1).limit_denominator(1000000000)
    round_seigniorage_rate = [7, 175070816]
    +
    +

    Rewards distribution summary

    +

    The following steps summarize the rewards distribution mechanism.

    +

    Each round has a reward pool calculated from the round_seigniorage_rate chainspec parameter and the current total supply for the relevant era.

    +

    In each round, the reward pool is split into two parts for block proposals and finality signature rewards, based on the finality_signature_proportion chainspec parameter.

    +

    The amount allocated for finality signatures is split further into two parts: creating and publishing finality signatures. The split is configurable in the chainspec using the finders_fee chainspec parameter.

    +

    For each finality signature:

    +
      +
    • The creator gets a portion of what was allocated for creating signatures, in proportion to relative consensus weight.
    • +
    • The block proposer gets a portion corresponding to the finders_fee chainspec parameter, scaled by the total collected signature creator weight divided by the total weight in the relevant era.
    • +
    +

    Rewards Pot

    +

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era, depending on the signature_rewards_max_delay parameter, to compensate for the delay in creating and distributing finality signatures.

    + + \ No newline at end of file diff --git a/concepts/design/zug/index.html b/concepts/design/zug/index.html new file mode 100644 index 000000000..a8738b39b --- /dev/null +++ b/concepts/design/zug/index.html @@ -0,0 +1,86 @@ + + + + + +Zug Consensus | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Simple and Fast Consensus with Zug

    +

    The Casper node was designed with a pluggable consensus protocol in mind. So far the only choice was Highway. Casper 2.0.0 has added Zug, a much simpler consensus protocol.

    +

    The Zug protocol requires that at most one-third of the validator weight could be attributed to faulty validators. It also assumes that there exists an upper bound for the network delay, which is the duration for a correct validator to deliver a message. The value of the upper bound may be unknown, but it exists. Under these conditions, all correct nodes will reach agreement on a chain of finalized blocks.

    +

    Of course, all nodes in a network have to run the same protocol to work together, but when starting a new network or upgrading an existing one, either Highway or Zug can now be selected as the consensus_protocol in the chainspec file. The Casper Mainnet will switch to Zug.

    +

    How Zug Works

    +

    In every round, the designated leader can sign a proposal message to suggest a block. The proposal also points to an earlier round in which the parent block was proposed.

    +

    Each validator then signs an echo message with the proposal's hash. Correct validators only sign one echo per round, so at most one proposal can get echo messages signed by a quorum. A quorum is a set of validators whose total weight is greater than (n + f) / 2, where n is the total weight of all validators and f is the maximum allowed total weight of faulty validators. Thus, any two quorums always have a correct validator in common. As long as n > 3f, the correct validators will constitute a quorum since (n + f) / 2 < n - f.

    +

    The proposal is accepted if there is a quorum and some other conditions are met (see below). Now, the next round's leader can make a new proposal that uses this proposal as a parent.

    +

    Each validator observing the proposal in time signs a Vote(true) message. If validators time out while waiting, they sign Vote(false) message instead. If a quorum signs true, the round is committed and the proposal and all its ancestors are finalized. If a quorum signs false, the round is skippable, meaning that the next round's leader can propose a block with a parent from an earlier round. Correct validators only sign either true or false, so a round can be either committed or skippable, but not both.

    +

    If there is no accepted proposal, all correct validators will eventually vote false, so the round becomes skippable. This is what makes the protocol live. The next leader will eventually be allowed to make a proposal because either there is an accepted proposal that can be the parent, or the round will eventually be skippable, and an earlier round's proposal can be used as a parent. If the timeout is long enough, the correct proposers' blocks will usually get finalized.

    +

    For a proposal to be accepted, the parent proposal must also be accepted, and all rounds between the parent and the current round must be skippable. This is what makes the protocol safe. If two rounds are committed, their proposals must be ancestors of each other because they are not skippable. Thus, the protocol cannot finalize two conflicting blocks.

    +

    Of course, there is also a first block. Whenever all earlier rounds are skippable (particularly the first round), the leader may propose a block with no parent.

    +

    Every new signed message is optimistically sent directly to all peers. We want to guarantee that it is eventually seen by all validators, even if they are not fully connected. This is achieved via a pull-based randomized gossip mechanism, where a SyncRequest message containing information about a random part of the local protocol state is periodically sent to a random peer. The peer compares that to its local state and responds with all the signed messages that it has recorded.

    +
    important

    The Zug protocol can be summarized as follows:

      +
    • In every round, the round leader proposes a new block, B.
    • +
    • Every validator creates and broadcasts an echo message, with a signature of B.
    • +
    • When a suitable block B has received echoes from 67% of the validators: +
        +
      • The next round begins. The next leader can propose a child of B.
      • +
      • Every validator signs and broadcasts a vote message, voting yes.
      • +
      +
    • +
    • If this does not happen before a timeout, the validators vote no instead. +
        +
      • If there are no votes from 67%, the next round begins, too. +The next leader can propose a child from an earlier block and skip this round.
      • +
      +
    • +
    • If there are yes votes from 67%, B is finalized and gets executed, together with all its ancestors. (Usually, the next round has already started at this point.)
    • +
    +

    Notice that proposals, votes, and echoes are broadcast, so if one correct node receives a message, all nodes will eventually receive it. An honest validator sends only one echo or vote per round. So, unless 34% of validators double-sign, at most one block per round gets 67% echoes, and no finalized block can ever be skipped, ensuring safety. As long as there are 67% of echoes for a proposal, the next round begins and Zug doesn't get stuck. If there are not, everyone votes no, and the next round also begins.

    +
    Expand to see a simple example
    + +

    Let's review a simple scenario demonstrating the Zug consensus. The example shows five rounds with a different leader and nodes voting on a card suit. The bottom row indicates whether or not the round was finalized. Notice that round 5 was the first finalized round.

    +

    ZUG

    +

    In round 1, we had a leader who proposed , but was slow, so the other nodes timed out and voted no. The first round had a proposal and was skippable, but nothing was finalized.

    +

    In round 2, the second proposer saw and proposed as a child of . Some nodes voted yes, and some timed out and voted no. So, round 2 will never output anything because there wasn't a decision.

    +

    In round 3, the leader proposed as a child of . Assuming the leader was still too slow, everyone voted no, and round 3 became skippable even though it had a proposal.

    +

    In round 4, the proposer might have crashed or been malicious, so everyone timed out and voted no.

    +

    In round 5, the leader didn't see the proposal from round 3 but saw the no decision. So, from their perspective, rounds 3 and 4 were skippable and had no proposals. Thus, the leader in round 5 proposed as a child of . Notice that the algorithm encountered a fork. Regardless, everyone voted yes, and round 5 was finalized. I.e., at that moment, , , and all become finalized and executed in that order. As a result, every future proposer needs to propose children of this round.

    +

    Important Notes:

    +

    Even proposals from rounds with a quorum of no votes can become finalized indirectly.

    +

    If a round is neither finalized nor skippable, the round will likely be finalized at some point in the future. When one-third of the network's weight votes yes, a proposal with a quorum of echoes is formed. Consequently, all other honest nodes will eventually see this quorum of echoes and the accepted proposal, which will serve as a parent in future rounds.

    +

    Nodes vote yes when they have a quorum of echoes, and all the ancestors of that proposal have a quorum of echoes. Also, those ancestors have a quorum of echoes, and the rounds with no ancestors all have a quorum of no votes (being skippable).

    +

    The algorithm will always produce a result in at least one of the Accepted proposal or Finalized round rows. If a proposal doesn't get accepted in a round, everyone times out and votes no. Otherwise, a proposal is visible to someone with a quorum of votes and will eventually be visible to everyone.

    +
    +

    Some Advantages of Zug

    +
      +
    • Apart from the leader, who has to send the proposed block, each validator node broadcasts only two tiny messages in each round, making the communication overhead very small.
    • +
    • Unlike in Highway and Practical Byzantine Fault Tolerance (PBFT), and similar to pipelined protocols like HotStuff, only one round of messages (the echoes) is needed for the next leader to propose a block, reducing the delay between a block and its child.
    • +
    • But unlike HotStuff, Zug can finalize a block without waiting for its child or grandchild. And, unlike Highway, it does so without waiting for any timeout. Even if a network is configured to produce only one block per minute, every block gets finalized within seconds, as fast as the network connections allow.
    • +
    • Zug's technical description is more flexible than Highway's, giving us a family of related, correct implementations from which to choose.
    • +
    +

    Comparison with Highway

    +

    Unlike Highway, Zug does not use a communication history DAG. Highway sends larger messages due to citing and is slower. Zug does not have any notion of citing units, as does Highway, and relies on exchanging signed messages. On the other hand, Highway allows for more fine-grained block rewards.

    +

    With Zug, finality happens after nodes constituting two-thirds of the network's total weight vote true for a round in which the block was proposed or a later round that has this one as an ancestor. Highways' criterion for detecting finality is the presence of a pattern of messages called a Summit. Summits preserve the advantage of tunable fault tolerance while being detected in polynomial time. Both ways of detecting finality are improvements over previous CBC Casper finality criteria, which were more difficult to attain and computationally more expensive to detect.

    +

    Highway and Zug offer flexibility in terms of fault tolerance thresholds. Highway allows different clients to follow the protocol with varying thresholds, each with its own balance between security and latency. However, if a sufficient number of validators are online, Zug demonstrates lower latency than Highway at any threshold. This is because Zug does not have predefined, rigid values for the round length, and its design allows the network to adapt to actual delays. If delays occur, block times may vary. Otherwise, blocks should appear as soon as they are finalized. Highway has a defined minimum round length, and the round lengths have to be powers of two times that minimum. Zug has a defined minimum round length, but a round can finish anytime as soon as enough messages are successfully exchanged. So, with Zug, there is no need to wait for a power of two times the minimum if the actual time falls somewhere between.

    +

    Highway is a much more complicated protocol than Zug. Implementing it takes more than twice as many lines of code. Also, Highway's proof of correctness has proved more difficult to verify than Zug's. Zug will make it easier for third parties to create compatible node software that works with the Casper node.

    +

    Using Zug consensus and smaller messages, the network could scale to a larger number of validators.

    +

    Block Rewards

    +

    Using a DAG in Highway makes fine-grained information about the validators' behavior available temporarily in the protocol state, so block rewards can be tuned to incentivize full participation in the consensus protocol. However, this does not apply at the end of each era. Any message sent after the era's last block was proposed cannot be taken into account, even though these messages are still needed to finalize that block. And this granularity comes at a cost: Highway messages are relatively big.

    +

    The current system does not reward finality signatures, which are arguably the most important outcome. The signatures are the user-visible proof, signed by the validators, that an executed block is correct.

    +

    In Zug, messages are much smaller, so a smaller incentive is needed to send them.

    +

    Casper 2.0.0 will distribute a configurable fraction of the seigniorage as a reward for finality signatures and the rest as a simple reward for each block, both proportionally to the validators' stakes.

    +

    This new reward system is simpler, fairer, predictable, and transparent. It will give equal weight to all blocks (including at the end of an era), but it will not take into account every single consensus message.

    +

    Read the Paper

    +

    Here, we describe Zug, an implementation of the ideas from our paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast. The paper, however, contains a much more general algorithm parameterized by the two subprotocols named in the title: Reliable Broadcast and Weakly-terminating Binary Agreement. In our specialization of this algorithm made for the Casper blockchain, the echo messages are used by our Reliable Broadcast implementation, and the vote messages are used by our Weakly-terminating Binary Agreement implementation.

    + + \ No newline at end of file diff --git a/concepts/dictionaries/index.html b/concepts/dictionaries/index.html index 8053ed75f..e88088de8 100644 --- a/concepts/dictionaries/index.html +++ b/concepts/dictionaries/index.html @@ -1,39 +1,37 @@ - + -Dictionaries | Casper Docs - Redux +Dictionaries | Casper Docs - Redux - - + +
    Version: 1.5.X

    Understanding Dictionaries

    -

    In a Casper network, you can now store sets of data under Keys. Previously, URefs were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an Account or Contract context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated NamedKeys structures.

    + submit an issue on Github
    Version: Next

    Understanding Dictionaries

    +

    In a Casper network, you can now store sets of data under Keys. Previously, URefs were the exclusive means by which users could store data in global state. To maintain persistent access to these URefs, they would have to be stored within an addressable entity's context. In the case of Contracts, sustained and continuous use of URefs would result in the expansion of the associated NamedKeys structures.

    Individual value changes to data stored within the NamedKeys would require deserializing the entire NamedKeys data structure, increasing gas costs over time and thus having a negative impact. Additionally, users storing large subsets of mapped data structures would face the same deep copy problem where minor or single updates required the complete deserialization of the map structure, also leading to increased gas costs.

    As a solution to this problem, the Casper platform provides the Dictionary feature, which allows users a more efficient and scalable means to aggregate data over time.

    -

    In almost all cases, dictionaries are the better form of data storage. They allow greater flexibility in altering stored data at a lower cost.

    +

    Casper's Condor release shifts NamedKeys to a top-level key, removing this restriction and making them viable for data storage.

    Seed URefs

    -

    Items within a dictionary exist as individual records stored underneath their unique dictionary address in global state. In other words, items associated with a specific dictionary share the same seed URef but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key.

    +

    Items within a dictionary exist as individual records stored underneath their unique dictionary address in global state. In other words, items associated with a specific dictionary share the same seed URef but are otherwise independent of each other. Dictionary items are not stored beneath this URef, it is only used to create the dictionary key.

    As each dictionary item exists as a stand-alone entity in global state, regularly used dictionary keys may be used directly without referencing their seed URef.

    Using Dictionaries

    -

    Dictionaries are ideal for storing larger volumes of data for which NamedKeys would be less suitable.

    -

    Creating a new dictionary is fairly simple and done within the context of a Deploy sent to a Casper network. The associated code is included within the casper_contract crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context.

    -

    Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract.

    -

    While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional Deploy removing those access rights, but it is better to create the dictionary within the context of the Contract.

    -

    Dictionaries allow a contract to store additional data without drastically expanding the size of the NamedKeys within their context. If a contract's NamedKeys expand too far, they may run into system limitations that would unintentionally disable the contract's functionality.

    +

    Creating a new dictionary is fairly simple and done within the context of a transaction sent to a Casper network. The associated code is included within the casper_contract crate. Creating a dictionary also stores the associated seed URef within the named keys of the current context.

    +

    Developers should always consider context when creating dictionaries. We recommend creating a dictionary within the context of a Contract entity.

    +

    While you can create a dictionary in the context of an Account and then pass associated access rights to a Contract, this approach can create potential security issues. If a third party uses the Contract, the initiating Account with access rights to the dictionary may be undesirable. To rectify this, you may send an additional transaction removing those access rights, but it is better to create the dictionary within the context of the Contract.

    A dictionary item key can be no longer than 64 bytes in length.

    Practical Dictionary Examples

    The Casper CEP-78 Enhanced NFT Standard includes several practical applications of dictionaries.

    Simple examples for dictionary use within CEP-78 include the approve dictionary.

    -

    More advanced dictionary functionality can be found in the CEP-78 Page System, which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract.

    +

    More advanced dictionary functionality can be found in the CEP-78 Page System, which uses a series of dictionaries to keep track of token ownership. These dictionaries form the basis of the reverse lookup mode, which allows users to easily view a list of owned tokens by account or contract.

    Creating Dictionaries in a Contract's Context

    The following code snippet shows the most basic example of creating a dictionary.


    casper_contract::contract_api::storage::new_dictionary(dict_name)

    @@ -79,6 +77,6 @@


    casper-client get-dictionary-item \
    --node-address http://localhost:11101 \
    --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
    --dictionary-item-key <String> \
    --seed-uref uref-90b4a8d936b881d3b45b73a102adb2b652181d75c76b7547ae9d1bb213f8db6b-007

    Dictionary lookup via the unique dictionary item key.

    In the event that you know the dictionary address of the dictionary item key you need to read, you can read it directly using the following Casper client command.

    -

    casper-client get-dictionary-item \
    --node-address http://localhost:11101 \
    --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
    --dictionary-address dictionary-<string>

    +

    casper-client get-dictionary-item \
    --node-address http://localhost:11101 \
    --state-root-hash 50c34ccbe1315d58ce22bf7518071164d16acd20a1becb0b423293418297416d \
    --dictionary-address dictionary-<string>

    \ No newline at end of file diff --git a/concepts/economics/concepts/index.html b/concepts/economics/concepts/index.html deleted file mode 100644 index 63a2027f9..000000000 --- a/concepts/economics/concepts/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -Staking Concepts | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Staking Concepts

    -

    The Casper network is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for continuing to maintain and secure the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.

    -

    Consensus mechanism: Casper operates using a Proof-of-Stake consensus mechanism per the Highway Protocol, a specification of Correct-by-Construction Casper (CBC Casper).

    -

    Number of validators: The Casper Mainnet supports up to 100 validators on the network. This number is chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through a process of permission-less bonding by participating in an auction for the validator slot.

    -

    Permission-less bonding: For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permission-less, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens.

    -

    Unbonding: To detach from a Casper network, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards during the seven eras required for unbonding, as they are not actively contributing to the network's security during that time.

    -

    Eras and block times: An era on Casper is roughly 2 hours long. Casper's Highway protocol allows validators to propose blocks as quickly as network conditions allow, subject to a platform-wide limit that may be adjusted with upgrades. We anticipate block times to last between thirty seconds and eight minutes.

    -

    Block rewards: Block time is orthogonal to rewards, so there is no precise reward per block. Instead, the number of rewards is split proportionally among stakes and reduced for failure to participate in the protocol promptly.

    -

    Reward cycle: Rewards are distributed to validators and delegators once per era.

    -

    Token supply and inflation: Mainnet launched with ten billion CSPR at the time of genesis. The target annual supply growth rate is 8%.

    -

    Annual reward percentage: Validators on the Casper Mainnet earn between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes is dependent on total active stake, as only a fixed number of tokens is created per era.

    -

    Please visit the Staking Guide for further details on the staking mechanism.

    - - \ No newline at end of file diff --git a/concepts/economics/consensus/index.html b/concepts/economics/consensus/index.html index d8604e389..1c75bab5a 100644 --- a/concepts/economics/consensus/index.html +++ b/concepts/economics/consensus/index.html @@ -1,23 +1,23 @@ - + -Consensus | Casper Docs - Redux +Consensus | Casper Docs - Redux - - + +
    Version: 1.5.X

    Consensus Economics

    -

    Highway consensus is a continuous, trust-less process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes to the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.

    -

    Entry

    + submit an issue on Github
    Version: Next

    Consensus Economics

    +

    Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.

    +

    Validator Selection

    After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a chainspec configuration file specifies a few key parameters:

    • The auction_delay specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the auction_delay is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era.
    • @@ -28,13 +28,13 @@

      BidsEach bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document.

      Delegation

      Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate.

      -

      Currently, delegation is unrestricted. Please visit Delegation details page to check more about delegation cost and related details.

      +

      Currently, there are delegation limits in the chainspec. Visit the Delegating Tokens page for more details.

      Incentives

      -

      Correct operation of the Highway protocol requires the economics of the platform to discourage equivocation for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals.

      +

      The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals.

      Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future.

      -

      The network incentivizes participation by scaling rewards for on-time proposals and responses, taking into account the speed of finalizing blocks. All rewards are added directly to the corresponding bids and delegations.

      -

      Participation

      -

      Issuance of new tokens and their distribution to validators incentivizes work even under low transaction load.

      +

      The network incentivizes participation by issuing rewards to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by staking with a validator. All rewards are added directly to the corresponding bids and delegations.

      +

      Validator Participation

      +

      The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load.

      CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:

      • The growth of CSPR supply is exponential
      • @@ -54,25 +54,26 @@

        Participation<

        Finally, the base round reward is computed as:

        base_round_reward(i) = round_issuance_rate * supply(i)

        This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block.

        -

        Distribution

        -

        Validators receive tokens for proposing and finalizing blocks according to their performance. The concept of weight is crucial for understanding this distribution scheme:

        +

        Rewards Distribution

        +

        Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals.

        +

        The concept of validator weight is crucial in understanding the distribution scheme:

          -
        • Weight: A validator's bonded stake, used in consensus
        • -
        • Assigned weight of a block/round: The total stake of validators scheduled to participate in a block
        • -
        • Participated weight of a block/round: The total stake of validators that end up participating or sending messages to finalize a block before the end of their respective round
        • +
        • Weight: A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average
        • +
        • Assigned weight of a round: The total weight of validators scheduled to participate in a round
        • +
        • Participated weight of a round: The total weight of validators that participated or sent messages before the end of the round
        • +
        • Relative weight: A validator's weight relative to the total validator weight that participated in a round
        -

        To determine eligibility, we look at on-time finalization (OTF). Validators should finalize blocks on time by sending required messages before the end of their respective round.

        -

        Switch blocks are not visible to the issuance calculation (as this calculation is performed in the switch block itself for each era), and, consequently, no tokens are issued for switch blocks.

        -
        Participation schedule
        -

        The participation schedule is segmented into rounds, which are allocated dynamically according to the validators' exponents and a deterministic (randomized at era start) assignment of validators to milliseconds of an era. Thus, a validator with the round exponent n must participate in rounds that repeat every 2^n ticks.

        -

        Each validator is assessed according to its round exponent. All assigned validators become eligible to receive tokens as long as the block gets finalized with messages sent within each validator's round.

        -
        Eligibility
        -

        Once a block has been proposed and enough time has passed, the history of protocol messages can be examined to detect whether the block was finalized on time, according to the conditions given above. If the block was not finalized on time, validators receive a fraction of the expected tokens, governed by the reduced_reward_multiplier chainspec parameter. If the block was finalized on time, assigned validators share the reward proportionally to their stake, regardless of whether they have sent messages or not.

        -

        Inactivity

        -

        Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special deploy that reactivates their bid.

        -

        Slashing

        -

        Please review our Equivocator Policy. We are currently conducting research into the utility of slashing as an incentive mechanism.

        -

        Founding validators

        -

        Founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days, then releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days.

    +

    The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:

    +
      +
    • For each finalized block, there is a fraction of rewards due for signature creation and collection
    • +
    • Signature rewards are split between the finder (block proposer) and the signature creators
    • +
    • The signature creators get a part of the signature reward pot due for the block: (1 - finder's fee) * relative weight
    • +
    • The finder gets a small reward as well to incentivize collecting and reporting all the signatures: finder's fee * total relative weight of signatures collected
    • +
    +

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the Rewards Design page for more details.

    +

    Validator Inactivity

    +

    Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid.

    +

    Founding Validators

    +

    When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days.

    \ No newline at end of file diff --git a/concepts/economics/delegation/index.html b/concepts/economics/delegation/index.html deleted file mode 100644 index a9e315500..000000000 --- a/concepts/economics/delegation/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Delegation Details | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Delegation Details

    -

    This section provides a detailed explanation of the delegation cost mechanism, how the gas cost relates with delegations, where to find the details etc. Please note that the cost amounts are likely to change with time and you may have to check the latest release details to get the most up-to-date and accurate details.

    -

    Delegation Cost

    -

    The delegation cost is defined in the chainspec.toml file for each Casper network. In this example chainspec, the delegation is set to cost 2.5 CSPR. However, when you perform the delegation, you see that it costs a little more than what is specified in the chainspec. Let’s discuss why this happens.

    -

    When you delegate, the system automatically charges some gas to set up related data in the global state of the network to track your delegation. This cost is addition to the delegation cost defined in the chainspec file.

    -

    For example, the chainspec file in release 1.3.2 will contain the following information. This is how the delegation cost is defined in the chainspec.toml file of a Casper network.

    -

    Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network

    -

    Figure 1: Delegation cost is defined in the chainspec.toml file of a Casper network
-

    -

    Delegation fees may change over time, so, it is essential to stay up to date. To do so, select the latest release in Github, and navigate to the chainspec.toml file.

    -

    If you are unsure about anything, please join the Discord channel to ask us questions.

    -

    First-time Delegation

    -

    If you perform the delegation for the first time, the system charges some gas to create a purse to hold the delegated tokens.

    -

    Example: The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on Mainnet

    -

    It is essential to have enough funds in your account's main purse when you set up a delegation transaction. Otherwise, the transaction will fail, and you will lose the transfer cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer.

    -

    As a result, when performing a delegation using the command line, we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure.

    -

    Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR -Delegation Details

    -
    -

    NOTE:

    -

    Transaction costs depend on each Casper network and the cost tables defined in the chainspec. The examples you will find in the documentation are general.

    -
    -

    Lastly, we recommend that you try out delegations on the Casper Testnet before making actual transactions on the Casper Mainnet. This way, you will understand the costs involved in delegating tokens.

    - - \ No newline at end of file diff --git a/next/concepts/economics/dynamic-gas-pricing/index.html b/concepts/economics/dynamic-gas-pricing/index.html similarity index 57% rename from next/concepts/economics/dynamic-gas-pricing/index.html rename to concepts/economics/dynamic-gas-pricing/index.html index 471ed4747..05d1f3db6 100644 --- a/next/concepts/economics/dynamic-gas-pricing/index.html +++ b/concepts/economics/dynamic-gas-pricing/index.html @@ -3,19 +3,19 @@ -Dynamic Gas Pricing | Casper Docs - Redux +Dynamic Gas Pricing | Casper Docs - Redux - - + +
    Version: Next

    Dynamic Gas Pricing on Mainnet

    + submit an issue on Github
    Version: Next

    Dynamic Gas Pricing on Mainnet

    The Condor release introduced a configurable capability to calculate dynamic gas prices based on block vacancy (or consumption). The network chainspec configures the vacancy, as shown below, which refers to this feature. This capability prevents malicious actors from filling the blocks with useless transactions and ensures network integrity.

    When dynamic gas pricing is enabled, a calculation runs at the end of each era to average block usage within that era. This calculation determines the gas price the network will use for the next era. If overall consumption rises above a threshold, the gas price increases by 1. If consumption falls below a threshold, the gas price decreases by 1. The gas price remains the same if overall consumption remains within those thresholds. The gas price will not go up or down by more than 1 in a given era and will not go above the maximum or below the minimum threshold.

    The gas price is recorded in the block header and is easily discoverable for current and historical purposes. The current gas price is a multiplier that determines the actual gas cost. For instance, an operation with a base cost of 1 CSPR would cost 1 CSPR if the current gas price is 1 but would cost 2 CSPR if the current gas price is 2. As blocks become congested, the amount of CSPR required to obtain a slot for executing transactions will increase by a multiple. The following configuration settings control this behavior:

    @@ -29,9 +29,9 @@

    [vacancy]
    # The cost of a transaction is based on a multiplier. This allows for economic disincentives for misuse of the network.
    #
    # The network starts with a current_gas_price of min_gas_price.
    #
    # Each block has multiple limits (bytes, transactions, transfers, gas, etc.)
    # The utilization for a block is determined by the highest percentage utilization of each these limits.
    #
    # Ex: transfers limit is 650 and transactions limit is 20 (assume other limits are not a factor here)
    # 19 transactons -> 19/20 or 95%
    # 600 transfers -> 600/650 or 92.3%
    # resulting block utilization is 95
    #
    # The utilization for an era is the average of all block utilizations. At the switch block, the dynamic gas_price is
    # adjusted with the following:
    #
    # If utilization was below the lower_threshold, current_gas_price is decremented by one if higher than min_gas_price.
    # If utilization falls between the thresholds, current_gas_price is not changed.
    # If utilization was above the upper_threshold, current_gas_price is incremented by one if lower than max_gas_price.
    #
    # The cost charged for the transaction is simply the gas_used * current_gas_price.
    upper_threshold = 90
    lower_threshold = 50
    max_gas_price = 3
    min_gas_price = 1

    Fixed Transaction Costs vs. Dynamic Gas Prices

    -

    The current gas price and the slot’s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it’s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost here. Also, the pricing_handling = { type = 'fixed' } setting is described here.

    +

    The current gas price and the slot’s maximum gas cost determine how much CSPR gets locked up for a transaction. Thus, the transaction price is predictable and fixed but has a dynamic component in that it’s pegged to the gas price. The system is designed this way to protect the network, adjusting the gas price as needed. Read more about lanes and gas cost here. Also, the pricing_handling = { type = 'fixed' } setting is described here.

    Gas Tolerance

    caution

    The cost of interacting with the blockchain increases during high network usage. Plan accordingly for any transactions and use the gas_tolerance field described below.

    -

    Transactions have a gas_tolerance field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with gas_tolerance = 2 and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block.

    +

    Transactions have a gas_tolerance field, allowing the sender to specify the maximum gas price they are willing to pay (the minimum is 1). For instance, if a transaction is sent with gas_tolerance = 2 and the network is currently at a gas price of 3 or higher, that transaction will not be included in a proposed block. If the calculated gas price decreases to 2 before the transaction has expired, the transaction will be eligible for inclusion in a proposed block.

    \ No newline at end of file diff --git a/concepts/economics/fee-elimination/index.html b/concepts/economics/fee-elimination/index.html new file mode 100644 index 000000000..87603b411 --- /dev/null +++ b/concepts/economics/fee-elimination/index.html @@ -0,0 +1,40 @@ + + + + + +Fee Elimination | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Fee Elimination on Mainnet

    +

    Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user's purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.

    +

    Instead of paying for gas to execute transactions, the no_fee chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: fee_handling = { type = 'no_fee'}. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable gas_hold_interval determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The query_balance_details RPC endpoint provides details on available balances and hold records.

    +
    note

    A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer.

    +

    Chainspec Configurations

    +

    The following chainspec configurations manage this feature:

    +
      +
    • fee_handling - Defines how fees are handled. To enable the "no fee" mode, set it to { type = 'no_fee'}.
    • +
    • refund_handling Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to { type = 'no_refund'}. If no fees are transferred from the paying purse, no refunds need to be paid out.
    • +
    • pricing_handling - Defines how pricing is handled. For this setting to work with the no_fee mode, set it to { type = 'fixed'}, which means that costs are fixed per the cost table, and senders do not specify how much they pay.
    • +
    • validator_credit_cap - The validator credit cannot exceed this percentage of their total stake.
    • +
    • `gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry).
    • +
    • gas_hold_interval - Defines how long gas holds last.
    • +
    +

    Mainnet Condor Configurations

    +

    These are the fee elimination settings for the Condor release on Mainnet:

    +
    # Defines how refunds of the unused portion of payment amounts are calculated and handled.
    #
    # Valid options are:
    # 'refund': a ratio of the unspent token is returned to the spender.
    # 'burn': a ratio of the unspent token is burned.
    # 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.
    # This causes excess payment amounts to be sent to either a
    # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount
    # minus the execution costs.
    refund_handling = { type = 'no_refund' }
    # Defines how fees are handled.
    #
    # Valid options are:
    # 'no_fee': fees are eliminated.
    # 'pay_to_proposer': fees are paid to the block proposer
    # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all
    # administrator accounts
    # 'burn': fees are burned
    fee_handling = { type = 'no_fee' }
    # If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.
    validator_credit_cap = [1, 5]
    # Defines how pricing is handled.
    #
    # Valid options are:
    # 'classic': senders of transaction self-specify how much they pay.
    # 'fixed': costs are fixed, per the cost table
    # 'reserved': prepaid transaction (currently not supported)
    pricing_handling = { type = 'fixed' }

    # Defines how gas holds affect available balance calculations.
    #
    # Valid options are:
    # 'accrued': sum of full value of all non-expired holds.
    # 'amortized': sum of each hold is amortized over the time remaining until expiry.
    #
    # For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,
    # with accrued, the full hold amount would be applied
    # with amortized, half the hold amount would be applied
    gas_hold_balance_handling = { type = 'accrued' }
    # Defines how long gas holds last.
    #
    # If fee_handling is set to 'no_fee', the system places a balance hold on the payer
    # equal to the value the fee would have been. Such balance holds expire after a time
    # interval has elapsed. This setting controls how long that interval is. The available
    # balance of a purse equals its total balance minus the held amount(s) of non-expired
    # holds (see gas_hold_balance_handling setting for details of how that is calculated).
    #
    # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,
    # a hold for 100 is placed on that purse and is considered when calculating total balance
    # for 24 hours starting from the block_time when the hold was placed.
    gas_hold_interval = '24 hours'
    +

    Computational and Storage Costs

    +

    Despite the introduction of fee elimination, the network continues to track computational cost based on opcodes as defined in the chainspec, thus retaining the gas pricing mechanism. Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines.

    +

    Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state.

    +

    This feature complements the dynamic gas pricing model introduced and configured to scale gas costs based on network utilization.

    + + \ No newline at end of file diff --git a/concepts/economics/gas-concepts/index.html b/concepts/economics/gas-concepts/index.html index e5a1e3b86..859118a25 100644 --- a/concepts/economics/gas-concepts/index.html +++ b/concepts/economics/gas-concepts/index.html @@ -1,54 +1,40 @@ - + -Gas Cost | Casper Docs - Redux +Gas Cost | Casper Docs - Redux - - + +
    Version: 1.5.X

    Gas and Resources

    + submit an issue on Github
    Version: Next

    Gas and Resources

    What is gas?

    -

    Gas is a conceptual measure of resources utilized when executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide in order to execute a transaction.

    -

    Gas fees are consumed on the network irrespective of whether your transaction was successful or not. Even when a transaction fails, you have to pay the transaction fee because your deploy consumed resources and space on the block as the validator attempted to execute it on your behalf.

    +

    Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction.

    +

    Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures computational work as gas because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    How is gas cost determined?

    -

    The amount of gas required for a transaction is determined by how much code is executed on the blockchain. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. The gas charged for a transaction on the blockchain is paid to the network's validators.

    -

    Why do we need gas cost?

    +

    The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's current_gas_price multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the current_gas_price multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to dynamic pricing can be configured in a Casper network's chainspec.

    +

    Why do we need to charge a cost?

    Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:

    • Rate-limiting is used to ensure a secure and live network:
        -
      • It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting is used to control the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves in a similar fashion, because each block permits only a fixed amount of transactions (gas) to be included in the era.
      • -
      • It explicitly quantifies the system load. The gas cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators.
      • +
      • It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era.
      • +
      • It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators.
    • Pricing leads to more meaningful transactions:
        -
      • Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each deploy.
      • +
      • Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction.
    • -
    -

    Why do I see an ‘Out of gas error’?

    -

    You might encounter an ‘Out of gas error’ when the gas payment you supplied for the transaction was insufficient to cover the actual cost of computation for the transaction. The amount of gas required for a transaction is determined by how much code is executed on the blockchain and also the storage utilized.

    -

    Here is an example of a transaction resulting in an ‘Out of gas error’ on the Mainnet.

    -

    Figure 1: In the Deploys tab of an account on cspr.live, a red exclamation mark is shown. By moving the cursor over it, the tooltip displays an 'Out of gas error'.

    -

    -

    Figure 2: Click the specific deploy to see more details such as the deploy hash, cost, and the status as an 'Out of gas error'. This indicates that the transaction did not have sufficient payment to cover the gas required for it to complete successfully.

    -

    -

    Figure 3: Click the Show raw data button, to see more details about the deploy. Towards the end of the raw data, you can see the error message.

    -

    -

    How do I determine the gas cost for a transaction?

    -

    Currently, we are hard at work to create tools to help you estimate gas costs. Meanwhile, we recommend using the NCTL tool on your local machine or the Testnet to deploy your contracts in a test environment. You can check a deploy status and roughly see how much it would actually cost when deployed. You can estimate the costs in this way and then add a small buffer if the network state has changed. Note that when estimating gas cost locally or on the Testnet, the blockchain specification needs to match the specification of the Mainnet, where you will need to pay for the transaction with actual Casper (CSPR) tokens.

    -

    Why do I see a gas limit error?

    -

    You may sometimes see an error such as ‘payment: 2.5, cost: 2.5, Error::GasLimit’, This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error. Let’s explore this error message a little further.

    -

    When a smart contract hits its gas limit (the payment amount), execution stops. If your limit is 2.5 CSPR, execution stops and that is the computation cost even if the smart contract did not run to completion. So, the error message tries to communicate to you that execution stopped at 2.5 CSPR. The computation resulted in an error because there were not enough funds to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution there and charged you that much, even though it was a failed transaction. The execution engine does not actually know how much it would have cost if allowed to run to completion, because it did not allow the contract to finish since the contract would have run over its gas limit.

    +
    \ No newline at end of file diff --git a/concepts/economics/staking/index.html b/concepts/economics/staking/index.html new file mode 100644 index 000000000..4e676f037 --- /dev/null +++ b/concepts/economics/staking/index.html @@ -0,0 +1,33 @@ + + + + + +Staking | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Staking

    +

    The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.

    +

    Consensus mechanism: The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called Zug. Another Casper network can choose between Zug and Highway using the network's chainspec.

    +

    Number of validators: The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot.

    +

    Permission-less bonding: For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens.

    +

    Unbonding: To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution here. The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings.

    +

    Eras and block times: An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute.

    +

    Block rewards: Validators receive rewards proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate.

    +

    Reward calculations: Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation.

    +

    Reward cycle: Rewards are calculated and distributed to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures.

    +

    Token supply and inflation: Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%.

    +

    Annual reward percentage: Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era.

    +

    Slashing: Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated.

    +

    Delegation rate: Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services.

    + + \ No newline at end of file diff --git a/concepts/global-state/index.html b/concepts/global-state/index.html index 2a7e14c6f..5235a97f5 100644 --- a/concepts/global-state/index.html +++ b/concepts/global-state/index.html @@ -1,25 +1,25 @@ - + -Global State | Casper Docs - Redux +Global State | Casper Docs - Redux - - + +
    Version: 1.5.X

    Global State

    + submit an issue on Github
    Version: Next

    Global State

    Introduction

    The storage layer for the Casper blockchain is called global state and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly.

    -
    note

    Refer to Keys and Permissions for further information on keys.

    -

    Each finalized block causes changes to the network's global state because of the execution of the deploys it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a Merkle trie.

    +
    note

    Refer to Keys and Permissions for further information on keys.

    +

    Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a Merkle trie.

    Merkle Trie Structure

    Global State

    At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes.

    @@ -37,6 +37,6 @@

    Merkle Tri
  • Reading from the trie
  • Writing to the trie
  • -
    note

    Conceptually, each block has its trie because the state changes based on the deploys it contains. For this reason, Casper's implementation has a notion of a TrieStore, which allows us to look up the root node for each trie.

    +
    note

    Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a TrieStore, which allows us to look up the root node for each trie.

    \ No newline at end of file diff --git a/concepts/glossary/A/index.html b/concepts/glossary/A/index.html index b4c590924..576dbcbfc 100644 --- a/concepts/glossary/A/index.html +++ b/concepts/glossary/A/index.html @@ -1,28 +1,30 @@ - + -A | Casper Docs - Redux +A | Casper Docs - Redux - - + +
    Version: Next

    A


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Account

    -

    An Account is a structure that represents a user on a Casper network. Information on creating an account can be found here.

    +

    An Account is a structure that represents a user on a Casper network. Information on creating an account can be found here. Casper's Condor release introduces the concept of an addressable entity, which contains an account entity type that supersedes legacy accounts.

    Account Hash

    The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found here.

    +

    Addressable Entity

    +

    An addressable entity is a post-2.0 type that merges the concept of an Account and a Contract, bringing in features from both. More information can be found here.

    AssemblyScript

    AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using asc, the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community.

    Auction

    @@ -30,6 +32,6 @@

    AuctionAuction contract

    The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction.

    Auction delay

    -

    The number of full eras that pass between the booking block and the era whose validator set it defines. The auction delay is configurable and can be several eras long.

    +

    The number of full eras that pass between the booking block and the era whose validator set it defines. The auction delay is configurable and can be several eras long.

    \ No newline at end of file diff --git a/concepts/glossary/B/index.html b/concepts/glossary/B/index.html index a2ca47a07..a5a069399 100644 --- a/concepts/glossary/B/index.html +++ b/concepts/glossary/B/index.html @@ -1,21 +1,21 @@ - + -B | Casper Docs - Redux +B | Casper Docs - Redux - - + +
    Version: Next

    B


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -30,13 +30,13 @@

    BlockEach block has a globally unique ID, achieved by hashing the contents of the block.

    Each block points to its parent. An exception is the first block, which has no parent.

    Block creation

    -

    Block creation means computing the deployment results and collecting the results that belong together into a block. We follow a process called execution after consensus.

    -

    The block proposal happens first, and the proposed proto block contains a set of deploys that have not been executed yet.

    -

    Only after consensus on a proto block has been reached, the deploys are executed. The resulting new global state root hash is put into an actual block, together with the executed deploys.

    +

    Block creation means computing the transaction results and collecting the results into a block. We follow a process called execution after consensus.

    +

    The block proposal happens first, and the proposed proto block contains a set of transactions that have not been executed yet.

    +

    Only after consensus on a proto block has been reached, the transactions are executed. The resulting new global state root hash is put into an actual block, together with the executed transactions.

    Note that only validators can create valid blocks.

    Block finality

    -

    A block is "finalized" if the validators agree on adding it to the blockchain.

    -

    There are different levels of finality in the Highway protocol. A finalized block has a fault-tolerance F, expressed as a fraction of the total stake. For an observer to see a conflicting block as finalized, several validators whose total stake exceeds F would have to collude and show different information in a way that would ultimately be detected and punished (see slashing).

    +

    A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.

    +

    For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see eviction).

    Block gossiping

    Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms block gossiping and block passing are interchangeable.

    Block height

    @@ -44,7 +44,7 @@

    Block heightBlock passing

    See block gossiping.

    Block processing

    -

    Block processing consists of running the deploys in a block received from another node to determine updates to the global state. Note that this is an essential part of validating blocks.

    +

    Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of validating blocks.

    Block proposal

    Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only.

    Block validation

    @@ -58,6 +58,6 @@

    BondBonding

    Depositing money in the auction contract and try to become a staker. The bonding request is a transaction that transfers tokens to the auction contract. In the next booking block, a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block.

    Booking block

    -

    The booking block for an era is the block that determines the era's validator set. In it, the auction contract selects the highest bidders to be the future era's validators. There is a configurable delay, the auction_delay, which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era N + auction_delay + 1 is the last block of era N.

    +

    The booking block for an era is the block that determines the era's validator set. In it, the auction contract selects the highest bidders to be the future era's validators. There is a configurable delay, the auction_delay, which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era N + auction_delay + 1 is the last block of era N.

    \ No newline at end of file diff --git a/concepts/glossary/C/index.html b/concepts/glossary/C/index.html index b848678a3..35b617ee1 100644 --- a/concepts/glossary/C/index.html +++ b/concepts/glossary/C/index.html @@ -1,21 +1,21 @@ - + -C | Casper Docs - Redux +C | Casper Docs - Redux - - + +
    Version: Next

    C


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -32,8 +32,7 @@

    CBCChainspec

    A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. Here is an example chainspec, which will change with newer releases.

    Consensus

    -

    An algorithm used to mandate agreement on the blockchain between all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not.

    -

    Casper uses the Highway algorithm in the CBC Casper family of consensus algorithms. The algorithm for securing an agreement is what is known as consensus. The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer.

    +

    Consensus is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as consensus. The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer.

    Contract runtime

    Enables developers to use a seamless workflow for authoring and testing their smart contracts. This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices.

    Correct by construction

    @@ -41,6 +40,6 @@

    Corr

    Crate

    A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, rustc, the compiler for the Rust programming language, will produce a binary from a crate.

    CSPR

    -

    CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for staking (securing the network).

    +

    CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for staking (securing the network).

    \ No newline at end of file diff --git a/concepts/glossary/D/index.html b/concepts/glossary/D/index.html index b51c01922..d36092360 100644 --- a/concepts/glossary/D/index.html +++ b/concepts/glossary/D/index.html @@ -1,21 +1,21 @@ - + -D | Casper Docs - Redux +D | Casper Docs - Redux - - + +
    Version: Next

    D


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -27,10 +27,13 @@

    DelegatorDeploy

    Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network.

    +

    Casper's Condor release introduces the Transaction. Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected.

    All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the global state.

    -

    Review the deploy data structure and the deploy implementation for more details.

    +

    Review the deploy data structure and the deploy implementation for more details.

    Dictionary

    A Dictionary is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to NamedKeys.

    -

    More information can be found in the Reading and Writing to Dictionaries document.

    +

    More information can be found in the Reading and Writing to Dictionaries document.

    +

    Dynamic gas pricing

    +

    Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details here.

    \ No newline at end of file diff --git a/concepts/glossary/E/index.html b/concepts/glossary/E/index.html index 37b201d73..295ed9f6c 100644 --- a/concepts/glossary/E/index.html +++ b/concepts/glossary/E/index.html @@ -1,34 +1,36 @@ - + -E | Casper Docs - Redux +E | Casper Docs - Redux - - + +
    Version: Next

    E


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Ecosystem

    The ecosystem layer in Casper encompasses dApp design and operation.

    Entry point

    -

    See EntryPoint and Defining the Contract Entry Points.

    +

    See EntryPoint and Defining the Contract Entry Points.

    +

    Equivocation

    +

    A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive.

    Era

    A period of time during which the validator set does not change.

    -

    In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an auction. At the beginning of the era, the validators create a new instance of the Highway protocol and run this consensus protocol until they finalize the era's last block (see booking block).

    +

    In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an auction. At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see booking block).

    Eviction

    Validators that fail to participate in era will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the auction contract.

    External client

    -

    Any hardware/software connecting to a Node for the purpose of sending deploys or querying the state of the blockchain.

    +

    Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain.

    \ No newline at end of file diff --git a/concepts/glossary/F/index.html b/concepts/glossary/F/index.html index ca5b3117f..78da78fdb 100644 --- a/concepts/glossary/F/index.html +++ b/concepts/glossary/F/index.html @@ -1,27 +1,27 @@ - + -F | Casper Docs - Redux +F | Casper Docs - Redux - - + +
    Version: Next

    F


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Finality

    See block finality.

    Fungible

    -

    A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a non-fungible token, where each token is unique and not interchangeable.

    +

    A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a non-fungible token, where each token is unique and not interchangeable.

    \ No newline at end of file diff --git a/concepts/glossary/G/index.html b/concepts/glossary/G/index.html index 8eaf2b661..afc3d6279 100644 --- a/concepts/glossary/G/index.html +++ b/concepts/glossary/G/index.html @@ -1,26 +1,30 @@ - + -G | Casper Docs - Redux +G | Casper Docs - Redux - - + +
    Version: Next

    G


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Gas

    -

    Gas is the virtual currency for calculating the cost of transaction execution. The transaction cost is expressed as a given amount of gas consumed and can be seen intuitively as some cycles of the virtual processor that has to be used to run the computation defined as the transaction's code.

    +

    Gas is a conceptual measure of resources used when executing transactions on the blockchain.

    +

    Gas cost

    +

    Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction.

    +

    Gas price

    +

    Multiplier applied to gas cost. See dynamic gas pricing.

    Genesis

    The state of the virtual machine at the beginning of the blockchain.

    Groups

    @@ -34,6 +38,6 @@

    Global stateWhen thinking of a blockchain as a decentralized computer, the global state is its memory state.

    When thinking of a blockchain as a shared database, the global state is the snapshot of the database's data.

    Technically, a global state is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs).

    -

    For every block B in the blockchain, one can compute the global state achieved by executing all transactions in this block and its ancestors. The root hash identifying this state is stored in every executed block.

    +

    For every block B in the blockchain, one can compute the global state achieved by executing all transactions in this block and its ancestors. The root hash identifying this state is stored in every executed block.

    \ No newline at end of file diff --git a/concepts/glossary/H/index.html b/concepts/glossary/H/index.html index 2aefb47f4..d9d1c890d 100644 --- a/concepts/glossary/H/index.html +++ b/concepts/glossary/H/index.html @@ -1,27 +1,27 @@ - + -H | Casper Docs - Redux +H | Casper Docs - Redux - - + +
    Version: Next

    H


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Hash

    A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the blake2b function.

    Highway

    -

    A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is finalized. The full paper is found in GitHub: https://github.com/casper-network/highway.

    +

    A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is finalized. The full paper is found in GitHub: https://github.com/casper-network/highway.

    \ No newline at end of file diff --git a/concepts/glossary/I/index.html b/concepts/glossary/I/index.html index f6352d4fc..08a84f059 100644 --- a/concepts/glossary/I/index.html +++ b/concepts/glossary/I/index.html @@ -1,23 +1,23 @@ - + -I | Casper Docs - Redux +I | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/concepts/glossary/J/index.html b/concepts/glossary/J/index.html index ad41c9995..6f42a99c0 100644 --- a/concepts/glossary/J/index.html +++ b/concepts/glossary/J/index.html @@ -1,25 +1,25 @@ - + -J | Casper Docs - Redux +J | Casper Docs - Redux - - + +
    Version: Next

    J


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    JSON

    -

    JSON (JavaScript Object Notation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found here.

    +

    JSON (JavaScript Object Notation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found here.

    \ No newline at end of file diff --git a/concepts/glossary/K/index.html b/concepts/glossary/K/index.html index 7b03f156d..0365c792f 100644 --- a/concepts/glossary/K/index.html +++ b/concepts/glossary/K/index.html @@ -1,25 +1,25 @@ - + -K | Casper Docs - Redux +K | Casper Docs - Redux - - + +
    Version: Next

    K


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Key

    -

    Keys are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found here.

    +

    Keys are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found here.

    \ No newline at end of file diff --git a/concepts/glossary/L/index.html b/concepts/glossary/L/index.html index 313a8db0a..3cb3bbc27 100644 --- a/concepts/glossary/L/index.html +++ b/concepts/glossary/L/index.html @@ -1,26 +1,26 @@ - + -L | Casper Docs - Redux +L | Casper Docs - Redux - - + +
    Version: Next

    L


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Liveness

    A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions).

    -

    If the protocol is not live, the blockchain does not grow anymore, and the network stalls.

    +

    If the protocol is not live, the blockchain does not grow anymore, and the network stalls.

    \ No newline at end of file diff --git a/concepts/glossary/M/index.html b/concepts/glossary/M/index.html index 8eac64304..867e5ebc7 100644 --- a/concepts/glossary/M/index.html +++ b/concepts/glossary/M/index.html @@ -1,21 +1,21 @@ - + -M | Casper Docs - Redux +M | Casper Docs - Redux - - + +
    Version: Next

    M


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -26,6 +26,6 @@

    Merkle treeMotes

    A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the CSPR token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes.

    Multi-Sig

    -

    Short for Multi-Signature. Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for deploys. More information on the use of Multi-Sig can be found here.

    +

    Short for Multi-Signature. Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found here.

    \ No newline at end of file diff --git a/concepts/glossary/N/index.html b/concepts/glossary/N/index.html index 5566478ce..fcbf92a9d 100644 --- a/concepts/glossary/N/index.html +++ b/concepts/glossary/N/index.html @@ -1,21 +1,21 @@ - + -N | Casper Docs - Redux +N | Casper Docs - Redux - - + +
    Version: Next

    N


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -36,6 +36,6 @@

    NodeNode operator

    See operator.

    Non-Fungible Token (NFT)

    -

    Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions.

    +

    Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions.

    \ No newline at end of file diff --git a/concepts/glossary/O/index.html b/concepts/glossary/O/index.html index edb57aceb..f8cf6942c 100644 --- a/concepts/glossary/O/index.html +++ b/concepts/glossary/O/index.html @@ -1,21 +1,21 @@ - + -O | Casper Docs - Redux +O | Casper Docs - Redux - - + +
    Version: Next

    O


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -23,6 +23,6 @@

    Operatorvalidator in that era.

    -

    It is common for a staked operator to win an auction slot for many eras in a row and thus be a validator for a range of eras.

    +

    It is common for a staked operator to win an auction slot for many eras in a row and thus be a validator for a range of eras.

    \ No newline at end of file diff --git a/concepts/glossary/P/index.html b/concepts/glossary/P/index.html index c9cd1a592..c517208d0 100644 --- a/concepts/glossary/P/index.html +++ b/concepts/glossary/P/index.html @@ -1,21 +1,21 @@ - + -P | Casper Docs - Redux +P | Casper Docs - Redux - - + +
    Version: Next

    P


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -37,14 +37,12 @@

    Proof-of-Stak

    Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain.

    Proof-of-Work

    A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed.

    -

    Proof-of-Stake contract

    -

    The Proof-of-Stake (PoS) contract holds on to transaction fees for the time while the state transition is happening (contracts are being executed). The PoS contract remits the transaction fees to the block proposer.

    Proposer

    The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain.

    Proto block

    -

    The block proposed by the leader, which the consensus processes (in highway). Only after consensus is complete, the proto block is executed, and the global state is updated.

    +

    The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated.

    A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era.

    Purse

    -

    A purse is a unique type of URef representing a token balance. An account's main purse represents the balance of CSPR tokens (in motes) the account has access to on a Casper network. An account may have more than one purse in some instances. More information on purses can be found here.

    +

    A purse is a unique type of URef representing a token balance. An entity's main purse represents the balance of CSPR tokens (in motes) the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found here.

    \ No newline at end of file diff --git a/concepts/glossary/Q/index.html b/concepts/glossary/Q/index.html index 12972d661..62e3d2fd5 100644 --- a/concepts/glossary/Q/index.html +++ b/concepts/glossary/Q/index.html @@ -1,23 +1,23 @@ - + -Q | Casper Docs - Redux +Q | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/concepts/glossary/R/index.html b/concepts/glossary/R/index.html index 84624cc7d..c8e6e732a 100644 --- a/concepts/glossary/R/index.html +++ b/concepts/glossary/R/index.html @@ -1,21 +1,21 @@ - + -R | Casper Docs - Redux +R | Casper Docs - Redux - - + +
    +

    As part of the Rust development environment, the Rustdocs describe the Casper contracts library, the Casper types library, and the Casper test support library.

    \ No newline at end of file diff --git a/concepts/glossary/S/index.html b/concepts/glossary/S/index.html index 8e0027b4e..eed77b01a 100644 --- a/concepts/glossary/S/index.html +++ b/concepts/glossary/S/index.html @@ -1,21 +1,21 @@ - + -S | Casper Docs - Redux +S | Casper Docs - Redux - - + +
    Version: Next

    S


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -26,7 +26,7 @@

    Secret keySeigniorage

    The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators.

    Session code

    -

    Session code is Wasm executed in the context of an account through sending a Deploy. The session code contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state.

    +

    Session code is Wasm executed in the context of an account entity through sending a transaction. The session code contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state.

    Slashing

    In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets slashed, i.e., a part of it is removed.

    Smart contract

    @@ -36,16 +36,16 @@

    Smart contrac

    Smart-contract platform

    A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts.

    Staker

    -

    A person that deposits tokens in the proof-of-stake contract. A staker is either a validator or a delegator. Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their tokens by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is slashed, the staker will lose their tokens.

    +

    A staker is either a validator or a delegator. Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their tokens by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is slashed, the staker will lose their tokens.

    Staking

    -

    A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The Staking Guide highlights the steps required to stake CSPR tokens on the Casper Mainnet.

    +

    A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The Staking Guide highlights the steps required to stake CSPR tokens on the Casper Mainnet.

    State root hash

    -

    The state root hash is an identifier of the network's global state at a moment in time. The state root hash changes with each block executed, containing deploys. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras.

    +

    The state root hash is an identifier of the network's global state at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras.

    Stateful

    Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions.

    Stateless

    Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time.

    Switch Block

    -

    A Switch Block is the final block in an era, which contains the era_summary. See also booking block.

    +

    A Switch Block is the final block in an era, which contains the era_summary. See also booking block.

    \ No newline at end of file diff --git a/concepts/glossary/T/index.html b/concepts/glossary/T/index.html index e7fff7889..1857b97d3 100644 --- a/concepts/glossary/T/index.html +++ b/concepts/glossary/T/index.html @@ -1,30 +1,30 @@ - + -T | Casper Docs - Redux +T | Casper Docs - Redux - - + +
    Version: Next

    T


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Token

    A type of cryptocurrency that represents an asset. See CSPR.

    Transaction

    -

    See deploy.

    +

    Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a Deploy. Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found here.

    Turing-complete blockchain

    Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets.

    -

    For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference.

    +

    For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference.

    \ No newline at end of file diff --git a/concepts/glossary/U/index.html b/concepts/glossary/U/index.html index d6b3343a3..dd3dc0652 100644 --- a/concepts/glossary/U/index.html +++ b/concepts/glossary/U/index.html @@ -1,21 +1,21 @@ - + -U | Casper Docs - Redux +U | Casper Docs - Redux - - + +
    Version: Next

    U


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -24,6 +24,6 @@

    UnbondingURef

    An Unforgeable Reference, used by a Casper network to store any value other than Account. More information can be found here.

    Users

    -

    Users execute session and contract code using the platform's computational resources.

    +

    Users execute session and contract code using the platform's computational resources.

    \ No newline at end of file diff --git a/concepts/glossary/V/index.html b/concepts/glossary/V/index.html index dea383587..873fb38cc 100644 --- a/concepts/glossary/V/index.html +++ b/concepts/glossary/V/index.html @@ -1,21 +1,21 @@ - + -V | Casper Docs - Redux +V | Casper Docs - Redux - - + +
    Version: Next

    V


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    @@ -27,6 +27,6 @@

    Validatorblock validation
  • block gossiping
  • -

    Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending deploys). Validators and stakers can lose their bond (be slashed) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly.

    +

    Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and stakers can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly.

    \ No newline at end of file diff --git a/concepts/glossary/W/index.html b/concepts/glossary/W/index.html index 6d5431c80..4ca98fcfe 100644 --- a/concepts/glossary/W/index.html +++ b/concepts/glossary/W/index.html @@ -1,27 +1,27 @@ - + -W | Casper Docs - Redux +W | Casper Docs - Redux - - + +
    Version: Next

    W


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z


    Web3

    An advanced version of the internet based on decentralization and trustless interactions.

    WebAssembly

    -

    WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones.

    +

    WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones.

    \ No newline at end of file diff --git a/concepts/glossary/X/index.html b/concepts/glossary/X/index.html index 9d84a9970..f2707bd9a 100644 --- a/concepts/glossary/X/index.html +++ b/concepts/glossary/X/index.html @@ -1,23 +1,23 @@ - + -X | Casper Docs - Redux +X | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/concepts/glossary/Y/index.html b/concepts/glossary/Y/index.html index 6f8d81aba..287cf9425 100644 --- a/concepts/glossary/Y/index.html +++ b/concepts/glossary/Y/index.html @@ -1,23 +1,23 @@ - + -Y | Casper Docs - Redux +Y | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/concepts/glossary/Z/index.html b/concepts/glossary/Z/index.html index cee7ba5f9..cb69c076e 100644 --- a/concepts/glossary/Z/index.html +++ b/concepts/glossary/Z/index.html @@ -1,23 +1,25 @@ - + -Z | Casper Docs - Redux +Z | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/concepts/hash-types/index.html b/concepts/hash-types/index.html deleted file mode 100644 index 0f9b6e1c7..000000000 --- a/concepts/hash-types/index.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - -Hash Types | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Understanding Hash Types

    -

    For the sake of user convenience and compatibility, we expect the delivery of hashes and similar data in the form of a prefixed string when using the node. The following is a list of string representations used.

    -

    Table of Associated Hash Types

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypePrefixExample
    PublicKey018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c
    AccountHashaccount-hash-account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    ContractHashcontract-contract-0101010101010101010101010101010101010101010101010101010101010101
    ContractPackageHashcontract-package-contract-package-0101010101010101010101010101010101010101010101010101010101010101
    Key::Accountaccount-hash-account-hash-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    Key::Hashhash-hash-0101010101010101010101010101010101010101010101010101010101010101
    Key::URefuref-uref-0101010101010101010101010101010101010101010101010101010101010101-001
    Key::Transfertransfer-transfer-0101010101010101010101010101010101010101010101010101010101010101
    Key::DeployInfodeploy-deploy-0101010101010101010101010101010101010101010101010101010101010101
    Key::EraInfoera-era-1
    Key::Balancebalance-balance-0101010101010101010101010101010101010101010101010101010101010101
    Key::Bidbid-bid-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    Key::Withdrawwithdraw-withdraw-ef4687f74d465826239bab05c4e1bdd2223dd8c201b96f361f775125e624ef70
    Key::Dictionarydictionary-dictionary-0101010101010101010101010101010101010101010101010101010101010101
    Key::SystemContractRegistrysystem-contract-registry-system-contract-registry-00000000000000000000000000000000
    Key::EraSummaryera-summary-era-summary-00000000000000000000000000000000
    -

    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 the system and it is a single 00.

    -

    AccountHash is a 32 byte hash of the PublicKey serving to identify user accounts.

    -

    ContractHash is the 32 byte hash of specific smart contract versions. You can use this to call specific contract versions.

    -

    ContractPackageHash is a 32 byte hash of the smart contract package. This hash directs you to the contract package. The function call_versioned_contract uses ContractPackageHash and allows you to call the latest version of the contract (by default). It also allows you to call any version stored previously to the package.

    -

    Key is a wrapper type that may contain one of several possible sets of data.

    -
      -
    • Key::Account contains an AccountHash.
    • -
    • Key::Hash contains a byte array with a length of 32, and as such can be used to pass any of the hashes. Please take note that the developer of the contract is responsible for implementation of any checks necessary on the receiving side.
    • -
    • Key::URef contains an URef suffixed by access rights.
    • -
    • Key::Transfer should contain the address hash for a transfer.
    • -
    • Key::DeployInfo retains the address hash of deploy information.
    • -
    • Key::EraInfo is the integer number of the associated era.
    • -
    • Key::Balance is the balance of a purse.
    • -
    • Key::Bid is used to keep track of bids for the auction contract. It is not generally used by users.
    • -
    • Key::Withdraw is used to keep track of withdraws for the auction contract. It is not generally used by users and exists in a historical context.
    • -
    • Key::Dictionary is the hash derived from a URef and a piece of arbitrary data and leads to a dictionary.
    • -
    • Key::SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts, including Mint, Auction, HandlePayment and StandardPayment, is stored.
    • -
    • Key::EraSummary is a Key under which we store current era info.
    • -
    - - \ No newline at end of file diff --git a/concepts/index.html b/concepts/index.html index 3e4d8bbc1..7ef982841 100644 --- a/concepts/index.html +++ b/concepts/index.html @@ -1,21 +1,21 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Concepts Overview

    + submit an issue on Github
    Version: Next

    Concepts Overview

    The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.

    Concepts

    This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper.

    @@ -80,7 +80,11 @@

    ConceptsIntroduction to the Casper BlockchainHigh-level details about the Casper blockchainIntroduction to dAppsDeveloping distributed applications on the Casper blockchainAccounts and Cryptographic KeysThe Casper programming model is account-based. Learn how Casper accounts work and how they are securedHash TypesHashes are used throughout the Casper ecosystem for keys, addresses, packaging data, and moreGlobal StateLearn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global stateCall StacksLearn how Casper manages the calling of a contractDeploys and the Deploy LifecycleDeploys are a concept fundamental to the Casper blockchain. Learn about deploys, what they are for, how to create and send themSmart ContractsLearn how to develop smart contracts on CasperDictionariesLearn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platformSerializationLearn about serializing data types and the Casper Serialization StandardDesignThe high-level design of a Casper networkEconomicsLearn about the Casper on-chain economicsGlossaryA compendium of all the terms used in Casper, in alphabetical order + + + + +
    TopicDescription
    Introduction to the Casper BlockchainHigh-level details about the Casper blockchain
    Introduction to dAppsDeveloping distributed applications on the Casper blockchain
    Addressable EntitiesLearn about addressable entities and how they relate to accounts and smart contracts.
    Accounts and Cryptographic KeysThe Casper programming model is account-based. Learn how Casper accounts work and how they are secured
    Key TypesHashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more
    Global StateLearn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state
    Call StacksLearn how Casper manages the calling of a contract
    Transactions and the Transaction LifecycleTransactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them
    Smart ContractsLearn how to develop smart contracts on Casper
    DictionariesLearn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform
    SerializationLearn about serializing data types and the Casper Serialization Standard
    DesignThe high-level design of a Casper network
    EconomicsLearn about the Casper on-chain economics
    GlossaryA compendium of all the terms used in Casper, in alphabetical order

    Next Steps

    After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories.

    Developers

    @@ -90,6 +94,6 @@

    OperatorsUsers

    The Users section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device.

    Resources

    -

    Navigate to Resources to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the beginner tutorials. Afterward, continue with more advanced tutorials to explore the multi-signature feature, runtime return values, and other essential features.

    +

    Navigate to Resources to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the beginner tutorials. Afterward, continue with more advanced tutorials to explore the multi-signature feature, runtime return values, and other essential features.

    \ No newline at end of file diff --git a/concepts/intro-to-dapps/index.html b/concepts/intro-to-dapps/index.html index 3b03177dd..ea5aca89e 100644 --- a/concepts/intro-to-dapps/index.html +++ b/concepts/intro-to-dapps/index.html @@ -1,42 +1,42 @@ - + -dApps | Casper Docs - Redux +dApps | Casper Docs - Redux - - + +
    Version: 1.5.X

    Introduction to dApps

    + submit an issue on Github
    Version: Next

    Introduction to dApps

    What is a dApp?

    DApp stands for Decentralized Application. Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface.

    A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of nodes does the processing of smart contracts instead of a single central server.

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    Interacting with a Casper Decentralized Network

    -

    For a dApp to integrate with a Casper network, it must be able to send Deploys via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. Sending a Deploy to a node will result in that node gossiping that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution.

    -

    A Deploy contains session code in the form of Wasm to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. -A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy.

    +

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    +

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. +A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    Updating data in a Casper dApp

    -

    Sending a Deploy is the only means by which a dApp can change global state. All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    +

    Sending a transaction is the only means by which a dApp can change global state. All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    Post-Consensus Execution in a Casper network

    -

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means that observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy.

    -

    Deploy lifecycle

    -

    There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The Deploy Lifecycle results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase.

    +

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means that observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    +

    Transaction lifecycle

    +

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    +
    \ No newline at end of file diff --git a/next/concepts/key-types/index.html b/concepts/key-types/index.html similarity index 55% rename from next/concepts/key-types/index.html rename to concepts/key-types/index.html index 88caa19ba..54daaecc8 100644 --- a/next/concepts/key-types/index.html +++ b/concepts/key-types/index.html @@ -3,19 +3,19 @@ -Key Types | Casper Docs - Redux +Key Types | Casper Docs - Redux - - + +
    Version: Next

    Understanding Key Types

    + submit an issue on Github
    Version: Next

    Understanding Key Types

    For user convenience and compatibility, we expect the delivery of hashes, keys, and similar data as a prefixed string when using the node. The following is a list of string representations used.

    Key Explanations

    Key is a wrapper type that may contain one of several possible sets of data.

    @@ -56,7 +56,7 @@

    HashTypePrefixExampleKey::Hashhash-hash-0101010101010101010101010101010101010101010101010101010101010101

    URef

    -

    Key::URef contains an URef suffixed by access rights.

    +

    Key::URef contains an URef suffixed by access rights.

    @@ -339,7 +339,7 @@

    PackageAddressableEntity

    -

    Key::AddressableEntity is a Key under which an AddressableEntity is stored. It may be one of three variants: Account, System or SmartContract.

    +

    Key::AddressableEntity is a Key under which an AddressableEntity is stored. It may be one of three variants: Account, System or SmartContract.

    @@ -480,6 +480,6 @@

    EntryPointTypePrefixExampleV1 Entry Pointentry-point-v1-entity-contract-entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481V2 Entry Pointentry-point-v2-entity-contract-entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1

    +
    TypePrefixExample
    V1 Entry Pointentry-point-v1-entity-contract-entry-point-v1-entity-contract-53c02487fa9a4bb1cd3e27b849e942cddb97caacb357e5b6bc86f702b2e32dbb-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481
    V2 Entry Pointentry-point-v2-entity-contract-entry-point-v2-entity-contract-2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a-1
    \ No newline at end of file diff --git a/concepts/list-auth-keys/index.html b/concepts/list-auth-keys/index.html index 22773c814..9646e9837 100644 --- a/concepts/list-auth-keys/index.html +++ b/concepts/list-auth-keys/index.html @@ -1,40 +1,39 @@ - + -Authorization Keys | Casper Docs - Redux +Authorization Keys | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Authorization Keys

    -

    This topic explains the usage of authorization keys when signing a deploy and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.

    + submit an issue on Github
    Version: Next

    Authorization Keys

    +

    This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.

    Associated Keys vs. Authorization Keys

    -

    Let's review the difference between associated keys to an Account and authorization keys for a Deploy.

    +

    Let's review the difference between associated keys to an Account and authorization keys for a transaction.

    • Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about associated keys and weights and try the Two-Party Multi-Signature tutorial.
    • -
    • Authorization keys are public keys used to sign a deploy and are listed in the Deploy's approvals. Authorization keys are a subset of the associated keys of the account under which the deploy is executed.
    • -
    • When a node receives a deploy, it checks that the deploy has the required authorization keys under approvals before including it in a block.
    • -
    • Different deploys executing the same smart contract can have different authorization keys.
    • +
    • Authorization keys are public keys used to sign a transaction and are listed in the transaction's approvals. Authorization keys are a subset of the associated keys of the account under which the transaction is executed.
    • +
    • When a node receives a transaction, it checks that the transaction has the required authorization keys under approvals before including it in a block.
    • +
    • Different transactions executing the same smart contract can have different authorization keys.
    -

    Image showing associated keys and authorization keys

    +

    Auth Keys

    Here is a sample JSON representation of an Account's associated keys:

    "associated_keys": [
    {
    "account_hash": "account-hash-1ab…11",
    "weight": 1
    },
    {
    "account_hash": "account-hash-2cd…22",
    "weight": 1
    },
    {
    "account_hash": "account-hash-3de…33",
    "weight": 1
    },
    {
    "account_hash": "account-hash-4fg…44",
    "weight": 1
    }
    ], ...
    -

    Here is a sample JSON representation of a Deploy's authorization keys:

    +

    Here is a sample JSON representation of a transaction's authorization keys:

    "approvals": [
    {
    "signer": " 2cd...22",
    "signature": "02df8c...f481"
    },
    {
    "signer": "4fg...44",
    "signature": "02ef21...756a"
    }
    ]

    Accessing Authorization Keys from a Smart Contract

    -

    Contract code can retrieve the set of authorization keys for a given deploy by calling the contract_api::runtime::list_authorization_keys function, which returns the set of account hashes representing the keys used to sign the deploy.

    +

    Contract code can retrieve the set of authorization keys for a given transaction by calling the contract_api::runtime::list_authorization_keys function, which returns the set of account hashes representing the keys used to sign the transaction.

    When to Use Authorization Keys

    Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations.

    -

    Try the Working with Authorization Keys tutorial to view an example workflow.

    +

    Try the Working with Authorization Keys tutorial to view an example workflow.

    \ No newline at end of file diff --git a/concepts/serialization/index.html b/concepts/serialization/index.html new file mode 100644 index 000000000..c24c11207 --- /dev/null +++ b/concepts/serialization/index.html @@ -0,0 +1,44 @@ + + + + + +Binary Serialization Standard | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Binary Serialization Standard

    +

    We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization.

    +

    The Casper Binary Serialization Standard uses a default u8 byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories.

    + + + + + + + + + + + + + + + + + + + + + +
    PageDescription
    PrimitivesBase-level types used to create more complex structures.
    StructuresMajor structures used through Casper systems, as well as their included sub-types.
    TypesMinor types not covered Primitives or Structures.
    + + \ No newline at end of file diff --git a/next/concepts/serialization/primitives/index.html b/concepts/serialization/primitives/index.html similarity index 67% rename from next/concepts/serialization/primitives/index.html rename to concepts/serialization/primitives/index.html index 542839f54..2ed3d3982 100644 --- a/next/concepts/serialization/primitives/index.html +++ b/concepts/serialization/primitives/index.html @@ -3,19 +3,19 @@ -Primitives and Basic Serialization Rules | Casper Docs - Redux +Primitives and Basic Serialization Rules | Casper Docs - Redux - - + +
    Version: Next

    Primitives and Basic Serialization Rules

    CLValue

    CLValue describes data that is used by smart contracts. This could be a local state variable, input argument, or return value. A CLValue consists of two parts: a CLType describing the type of the value and an array of bytes representing the data in our serialization format.

    CLType is described by the following recursive data type:

    @@ -124,7 +124,7 @@

    URef
    warning

    +
    warning

    When passing a URef to another entity on chain, you must ensure that the AccessRights are set correctly. If the URef represents a purse, AccessRights impact who can deposit and withdraw CSPR.

    If a passed URef contains ADD permissions, the entity receiving the URef will then be able to deposit CSPR into the associated purse. WRITE permissions allow for withdrawing CSPR. As of 1.4.5, passing a main purse URef as a runtime argument will cause the host to automatically remove WRITE permissions. In this event, READ and ADD permissions will remain. Regardless, all due diligence should be performed to avoid passing a URef with WRITE permissions unintentionally.

    PublicKey

    PublicKey serializes as a single byte tag representing the algorithm followed by 32 bytes of the PublicKey itself:

    @@ -248,9 +248,9 @@

    Contr
  • a collection of named keys
  • a protocol version
  • -

    The wasm module must contain a function named call, which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the Casper runtime.

    +

    The wasm module must contain a function named call, which takes no arguments and returns no values. This is the main entry point into the contract. Moreover, the module may import any of the functions supported by the Casper runtime.

    Note: though the call function signature has no arguments and no return value, within the call function body, the get_named_arg runtime function can be used to accept arguments (by ordinal), and the ret runtime function can be used to return a single CLValue to the caller.

    The named keys are used to give human-readable names to keys in the global state, which are essential to the contract. For example, the hash key of another contract it frequently calls may be stored under a meaningful name. It is also used to store the URefs, which are known to the contract (see the section on Permissions for details).

    -

    Each contract specifies the Casper protocol version that was active when the contract was written to the global state.

    +

    Each contract specifies the Casper protocol version that was active when the contract was written to the global state.

    \ No newline at end of file diff --git a/concepts/serialization/structures/index.html b/concepts/serialization/structures/index.html new file mode 100644 index 000000000..35b1c1e18 --- /dev/null +++ b/concepts/serialization/structures/index.html @@ -0,0 +1,509 @@ + + + + + +Major Structures | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Major Structures

    +

    Account

    +

    An Account is a structure that represented a user on a legacy Casper network. Alongside the Condor protocol release, Accounts were replaced with AddressableEntities of the type Account. The account structure consists of the following fields:

    + +

    AddressableEntity

    +

    An Addressable Entity is a structure that represents an entity on a Casper network. The addressable entity consists of the following fields:

    + +

    Block

    +

    A block is the core component of the Casper linear blockchain, used in two contexts:

    +
      +
    1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain.
    2. +
    3. A message that is exchanged between nodes containing the data structure as explained in (1).
    4. +
    +

    Each block has a globally unique ID, achieved by hashing the contents of the block.

    +

    Each block points to its parent. An exception is the first block, which has no parent.

    +

    A block is structurally defined as follows:

    +
      +
    • hash: A hash over the header of the block.
    • +
    • header: The header of the block that contains information about the contents of the block with additional metadata.
    • +
    • body: The block's body contains the proposer of the block and hashes of deploys and transfers contained within it.
    • +
    +

    Further, a block may consist of one of the following types:

    +
      +
    • +

      Version1: A legacy block created prior to the Condor upgrade.

      +
    • +
    • +

      Version2: A modern block.

      +
    • +
    +

    BlockHash

    +

    The block hash is a Digest over the contents of the block Header. The BlockHash serializes as the byte representation of the hash itself.

    +

    BlockHeader

    +

    The header portion of a block, structurally, is defined as follows:

    +
      +
    • parent_hash is the hash of the parent block. It serializes to the byte representation of the parent hash. The serialized buffer of the parent_hash is 32 bytes long.
    • +
    • state_root_hash is the global state root hash produced by executing this block's body. It serializes to the byte representation of the state root hash. The serialized buffer of the state_root_hash is 32 bytes long.
    • +
    • body_hash the hash of the block body. It serializes to the byte representation of the body hash. The serialized buffer of the body_hash is 32 bytes long.
    • +
    • random_bit is a boolean needed for initializing a future era. It is serialized as a single byte; true maps to 1, while false maps to 0.
    • +
    • accumulated_seed is a seed needed for initializing a future era. It serializes to the byte representation of the parent Hash. The serialized buffer of the accumulated_hash is 32 bytes long.
    • +
    • era_end contains equivocation and reward information to be included in the terminal finalized block. It is an optional field. Thus if the field is set as None, it serializes to 0. The serialization of the other case is described in the EraEnd.
    • +
    • timestamp The timestamp from when the block was proposed. It serializes as a single u64 value. The serialization of a u64 value is described in the CLValues section.
    • +
    • era_id Era ID in which this block was created. It serializes as a single u64 value.
    • +
    • height The height of this block, i.e., the number of ancestors. It serializes as a single u64 value.
    • +
    • protocol_version The version of the Casper network when this block was proposed. It is 3-element tuple containing u32 values. It serializes as a buffer containing the three u32 serialized values. Refer to the CLValues section on how u32 values are serialized.
    • +
    +

    Both BlockHeaderV1 and BlockHeaderV2 serialize in the same way.

    +

    EraEndV1

    +

    EraEndV1 as represented within the block header, is a struct containing two fields.

    +
      +
    • era_report: The first field is termed as EraReport and contains information about equivocators and rewards for an era.
    • +
    • next_era_validator_weights: The second field is map for the validators and their weights for the era to follow.
    • +
    +

    EraReport itself contains two fields:

    +
      +
    • equivocators: A vector of PublicKey.
    • +
    • rewards: A Binary Tree Map of PublicKey and u64.
    • +
    • inactive_validators: A vector of PublicKey.
    • +
    +

    When serializing an EraReport, the buffer is first filled with the individual serialization of the PublicKey contained within the vector.

    +
      +
    • If the PublicKey is an Ed25519 key, the first byte within the buffer is a 1 followed by the individual bytes of the serialized key.
    • +
    • If the PublicKey is an Secp256k1 key, the first byte within the buffer is a 2 followed by the individual bytes of the serialized key.
    • +
    +

    When serializing the overarching struct of EraEndV1, we first allocate a buffer, which contains the serialized representation of the EraReport as described above, followed by the serialized BTreeMap.

    +

    Note that EraEndV1 is an optional field. Thus the above scheme only applies if there is an EraEndV1; if there is no era end, the field simply serializes to 0.

    +

    EraEndV2

    +

    EraEndV1 as represented within the block header, is a struct containing four fields.

    +
      +
    • equivocators: A vector of PublicKey listing equivocators for the era.
    • +
    • inactive_validators: A list of inactive validators for the era.
    • +
    • next_era_validator_weights: A map of validators and their weights for the era to follow.
    • +
    • rewards: A Binary Tree Map of PublicKey and u64.
    • +
    • next_era_gas_price: The next era's gas price as a u8.
    • +
    +

    Note that EraEndV2 is an optional field. Thus the above scheme only applies if there is an EraEndV2; if there is no era end, the field simply serializes to 0.

    +

    BlockBodyV1

    +

    The body portion of a block, prior to the Condor upgrade, is structurally defined as:

    +
      +
    • proposer: The PublicKey which proposed this block.
    • +
    • deploy_hashes: Is a vector of hex-encoded hashes identifying Deploys included in this block.
    • +
    • transfer_hashes: Is a vector of hex-encoded hashes identifying Transfers included in this block.
    • +
    +

    When we serialize the BlockBodyV1, we create a buffer that contains the serialized representations of the individual fields present within the block.

    +
      +
    • proposer serializes to the byte representation of the PublicKey. If the PublicKey is an Ed25519 key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of Secp256k1, the first byte is 2.
    • +
    • deploy_hashes serializes to the byte representation of all the deploy_hashes within the block header. Its length is 32 * n, where n denotes the number of deploy hashes present within the body.
    • +
    • transfer_hashes serializes to the byte representation of all the deploy_hashes within the block header. Its length is 32 * n, where n denotes the number of transfers present within the body.
    • +
    +

    BlockBodyV2 {blockbodyv2}

    +

    A modern block is structurally defined as:

    +
      +
    • +

      transactions: Is a BTreeMap of transaction hashes and their given categories. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of values held within. The remainder consists of a repeating pattern of transaction categories as a u8 value and then the associated TransactionHash the category tag describes.

      +
    • +
    • +

      rewarded_signatures: A list of identifiers for finality signatures for a particular past block. It serializes as a vector of SingleBlockRewardedSignatures which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

      +
    • +
    +

    Contract

    +

    A contract struct containing the following fields:

    + +

    ContractPackageHash

    +

    A blake2b hash of a contract package. The contract package hash serializes as a 32-byte buffer containing the bytes of the contract package hash.

    +

    ContractWasmHash

    +

    A blake2b hash of a contract's Wasm. The contract's Wasm hash serializes as a 32-byte buffer containing the bytes of the contract's Wasm hash.

    +

    ContractHash

    +

    A blake2b hash of a contract. The contract hash serializes as a 32-byte buffer containing the bytes of the contract hash.

    +

    ContractPackageStatus

    +

    The lock status of the contract package, serialized as a boolean where true indicates a locked contract and false indicates an unlocked contract package.

    +

    ContractVersion

    +

    The version of the contract.

    +
      +
    • +

      contract_hash: The contract hash of the contract.

      +
    • +
    • +

      contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

      +
    • +
    • +

      protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

      +
    • +
    +

    ContractVersionKey

    +

    The major element of ProtocolVersion combined with Contract Version serialized as two u32 values.

    +

    ContractWasm

    +

    A container for a contract's Wasm bytes, serialized as the byte representation of itself.

    +

    Message

    +

    A message emitted by an addressable entity during execution. The message struct contains the following fields:

    +
      +
    • +

      entity_hash: The identity of the entity that produced the message, serialized as an EntityAddr.

      +
    • +
    • +

      message: The payload of the message, serialized as a MessagePayload.

      +
    • +
    • +

      topic_name: The name of the topic on which the message was emitted, serialized as a String.

      +
    • +
    • +

      topic_name_hash: The hash of the topic name, serialized as a TopicNameHash.

      +
    • +
    • +

      topic_index: The message index in the topic, serialized as a u32 value.

      +
    • +
    • +

      block_index: The message index in the block, serialized as a u64 value.

      +
    • +
    +

    MessageAddr

    +

    A message topic address, a structure which consists of the following fields:

    +
      +
    • +

      entity_addr: The entity address, serialized as an EntityAddr.

      +
    • +
    • +

      topic_name_hash: The hash of the topic name, serialized as a TopicNameHash.

      +
    • +
    • +

      message_index: The message index, serialized as an Option of u32.

      +
    • +
    +

    MessageChecksum

    +

    A newtype wrapping an array which contains the raw bytes of the hash of the message emitted. It serializes as a CLType u8 tag followed by a ByteArray.

    +

    MessageLimits

    +

    Configuration for message lists, serialized as three u32 values:

    +
      +
    • +

      max_topic_name_size: Maximum size in bytes of a topic name string.

      +
    • +
    • +

      max_message_size: Maximum message size in bytes.

      +
    • +
    • +

      max_topics_per_contract: Maximum number of topics that a contract can register.

      +
    • +
    +

    MessagePayload

    +

    The payload of a message emitted by an addressable entity during execution. It serializes as either a u8 tag of 0 followed by a a serialized version of a human-readable String, or as a u8 tag of 1 followed by serialized raw Bytes.

    +

    MessageTopicOperation

    +

    Operations that can be performed on message topics. Currently, serializes as a u8 of 0 representing the Add function.

    +

    TopicNameHash

    +

    The hash of the name of a message topic, serialized as a u8 describing the length of the string and the 32-byte serialized representation of the string itself.

    +

    Transaction

    +

    A versioned wrapper for a transaction or deploy. It serializes as a u8 tag of 0 followed by a Deploy or a u8 tag of 1 followed by a TransactionV1.

    +

    Deploy

    +

    A deploy is a data structure containing a smart contract and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy is structurally defined as follows:

    +
      +
    • hash: The hash of the deploy header.
    • +
    • header: Contains metadata about the deploy. The structure of the header is detailed further in this document.
    • +
    • payment: The payment code for contained smart contract.
    • +
    • session: The stored contract itself.
    • +
    • approvals: A list of signatures.
    • +
    +

    DeployHash

    +

    The deploy hash is a digest over the contents of the deploy header. The deploy hash serializes as the byte representation of the hash itself.

    +

    DeployHeader

    +
      +
    • account: A supported public key variant (currently either Ed25519 or Secp256k1). An Ed25519 key is serialized as a buffer of bytes, with the leading byte being 1 for Ed25519, with remainder of the buffer containing the byte representation of the signature. Correspondingly, a Secp256k1 key is serialized as a buffer of bytes, with the leading byte being 2.
    • +
    • timestamp: A timestamp is a struct that is a unary tuple containing a u64 value. This value is a count of the milliseconds since the UNIX epoch. Thus the value 1603994401469 serializes as 0xbd3a847575010000
    • +
    • ttl: The Time to live is defined as the amount of time for which deploy is considered valid. The ttl serializes in the same manner as the timestamp.
    • +
    • gas_price: The gas is u64 value which is serialized as u64 CLValue discussed below.
    • +
    • body_hash: Body hash is a hash over the contents of the deploy body, which includes the payment, session, and approval fields. Its serialization is the byte representation of the hash itself.
    • +
    • dependencies: Dependencies is a vector of deploy hashes referencing deploys that must execute before the current deploy can be executed. It serializes as a buffer containing the individual serialization of each DeployHash within the Vector.
    • +
    • chain_name: Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String CLValue described below.
    • +
    +

    Approval

    +

    Approval contains two fields:

    +
      +
    • signer: The public key of the approvals signer. It serializes to the byte representation of the PublicKey. If the PublicKey is an Ed25519 key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of Secp256k1, the first byte is 2.
    • +
    • signature: The approval signature, which serializes as the byte representation of the Signature. The first byte within the signature is 1 in the case of an Ed25519 signature or 2 in the case of Secp256k1.
    • +
    +

    ApprovalsHash

    +

    The cryptographic hash of the bytesrepr-encoded set of approvals. It serializes as a digest.

    +

    DeployInfo

    +

    Information relating to a given deploy. The structure consists of the following fields:

    +
      +
    • +

      deploy_hash: The hash of the relevant deploy, serialized as a byte representation of the hash itself.

      +
    • +
    • +

      transfers: Transfers performed by the deploy, serialized as a List.

      +
    • +
    • +

      from: The account identifier of the creator of the deploy, serialized as an account_hash.

      +
    • +
    • +

      source: The source purse used for payment of the deploy, serialized as a URef.

      +
    • +
    • +

      gas: The gas cost of executing the deploy, serialized as a U512.

      +
    • +
    +

    DeployConfig

    +

    A struct containing configuration values associated with deploys. The structure contains the following fields:

    +
      +
    • +

      max_payment_cost: The maximum amount any deploy can pay, serialized in Motes.

      +
    • +
    • +

      max_dependencies: The maximum time to live any deploy can specify, serialized as a u8.

      +
    • +
    • +

      payment_args_max_length: The maximum length in bytes of payment args per deploy, serialized as a u32

      +
    • +
    • +

      session_args_max_length: The maximum length in bytes of session args per deploy, serialized as a u32

      +
    • +
    +

    TransactionV1

    +

    A unit of work sent by a client to the network, which when executed can cause global state to be altered. It is structurally defined as follows:

    + +

    TransactionV1Hash

    +

    The transaction hash is a digest over the contents of the transaction header. The transaction hash serializes as the byte representation of the hash itself.

    +

    TransactionV1Header

    +

    The header portion of a transaction, structurally, is defined as follows:

    +
      +
    • chain_name: Chain name is a human-readable string describing the name of the chain as detailed in the chainspec. It is serialized as a String.
    • +
    • timestamp: A timestamp is a struct that is a unary tuple containing a u64 value. This value is a count of the milliseconds since the UNIX epoch. Thus the value 1603994401469 serializes as 0xbd3a847575010000.
    • +
    • ttl: The Time to live is defined as the amount of time for which the transaction is considered valid. The ttl serializes in the same manner as the timestamp.
    • +
    • body_hash: Body hash is a hash over the contents of the transaction body. It serializes as the byte representation of the hash itself.
    • +
    • pricing_mode
    • +
    • initator_addr
    • +
    +

    TransactionV1Body

    +

    The body of a TransactionV1, consisting of the following:

    + +

    TransactionRuntime

    +

    The runtime used to execute a transaction, serialized as a u8. Currently, only the VmCasperV1 is available, which serializes as a 0.

    +

    TransactionEntryPoint

    +

    An entry point of a transaction, serialized as a u8 value based on the type of entry point. The following table outlines the available types:

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    TagEntry Point
    0Custom
    1Transfer
    2Add_Bid
    3Withdraw_Bid
    4Delegate
    5Undelegate
    6Redelegate
    7Activate_Bid
    8ChangePublicKey
    9Call
    +

    TransactionConfig

    +

    A struct containing configuration values associated with Transactions. The structure contains the following fields:

    +
      +
    • +

      max_ttl: The maximum time to live any transaction can specify, serialized as a TimeDiff.

      +
    • +
    • +

      block_max_approval_count: The maximum number of approvals (signatures) allowed in a block across all transactions, serialized as a u32.

      +
    • +
    • +

      max_block_size: The maximum possible size in bytes of a block, serialized as a u32.

      +
    • +
    • +

      block_gas_limit: The maximum sum of payment across al transactions included in a block, serialized as a u64.

      +
    • +
    • +

      native_transfer_minimum_motes: The minimum token amount for a native transfer deploy or transaction, serialized as a u64.

      +
    • +
    • +

      max_timestamp_leeway: The maximum value to which a transaction_acceptor.timestamp_leeway can be set in the config.toml file.

      +
    • +
    • +

      deploy_config: Configuration values specific to Deploy transactions.

      +
    • +
    • +

      transaction_v1_config: Configuration values specific to V1 transactions.

      +
    • +
    +

    TransactionV1Config

    +

    A struct containing configuration values associated with TransactionV1s. The structure contains the following fields:

    +
      +
    • +

      native_mint_lane: The lane configuration for the native mint interaction, serializing as a vector of u64 values.

      +
    • +
    • +

      native_auction_lane: The lane configuration for the native auction interaction, serializing as a vector of u64 values.

      +
    • +
    • +

      wasm_lanes: The lane configuration for the Wasm-based lanes, serializing as a nested vector of u64 values.

      +
    • +
    +

    TransactionHash

    +

    A versioned wrapper for transaction hash or deploy hash. It serializes as either a u8 tag of 0 followed by a DeployHash or a u8 tag of 1 followed by a TransactionV1Hash.

    +

    TransactionHeader

    +

    A versioned wrapper for transaction header or deploy header. It serializes as either a u8 tag of 0 followed by a DeployHeader or a u8 tag of 1 followed by a TransactionV1Header.

    +

    TransactionId

    +

    The unique identifier of a Transaction, serialized as its TransactionHash and ApprovalsHash.

    +

    TransactionScheduling

    +

    The scheduling mode of a transaction, serialized as a u8 tag identifying the type:

    +
      +
    • +

      Standard serializes as a 0.

      +
    • +
    • +

      FutureEra serializes as a 1 followed by a future era_id.

      +
    • +
    • +

      FutureTimestamp serializes as a 2 followed by a future timestamp.

      +
    • +
    +

    TransactionInvocationTarget

    +

    The identifier of a stored transaction target, serialized as one of the following:

    +
      +
    • +

      InvocableEntity serializes as a u8 tag of 0 followed by the hex-encoded entity address serialized as the byte representation of itself.

      +
    • +
    • +

      InvocableEntityAlias serializes as a u8 tag of 1 followed by the alias serialized as a string.

      +
    • +
    • +

      Package serializes as a u8 tag of 2 followed by the package hash and optionally the entity_version.

      +
    • +
    • +

      PackageAlias serializes as a u8 tag of 3 followed by the alias serialized as a string and optionally the entity_version.

      +
    • +
    +

    TransactionTarget

    +

    The execution target of a transaction, serializing as a u8 that identifies the type, followed by any additional data.

    +
      +
    • +

      native serializes as a 0.

      +
    • +
    • +

      stored serializes as a 1 followed by the id and runtime.

      +
    • +
    • +

      session serializes as a 2 followed by the kind, module_bytes and runtime.

      +
    • +
    +

    TransactionWithExecutionInfo

    +

    A struct containing aTransaction with execution info. It serializes as a Transaction followed by an Option of ExecutionInfo.

    + + \ No newline at end of file diff --git a/next/concepts/serialization/types/index.html b/concepts/serialization/types/index.html similarity index 60% rename from next/concepts/serialization/types/index.html rename to concepts/serialization/types/index.html index f70933151..a2440d4af 100644 --- a/next/concepts/serialization/types/index.html +++ b/concepts/serialization/types/index.html @@ -3,21 +3,21 @@ -Type Serialization | Casper Docs - Redux +Type Serialization | Casper Docs - Redux - - + +
    Version: Next

    Type Serialization

    Account Action Thresholds

    -

    The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

    +

    The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

    • deployment: The minimum weight threshold required to perform deployment actions as a u8 value.

      @@ -30,13 +30,13 @@

      Account Confi

      Configuration of an individual account in accounts.toml, containing the account's public key, main purse balance and validator config.

      • -

        public_key The public key of the account, serialized as the byte representation of itself.

        +

        public_key The public key of the account, serialized as the byte representation of itself.

      • -

        balance The balance of the account's main purse, serialized as a U512 value.

        +

        balance The balance of the account's main purse, serialized as a U512 value.

      • -

        validator The validator configuration for the account, serialized as an Option.

        +

        validator The validator configuration for the account, serialized as an Option.

      Account Hash

      @@ -52,7 +52,7 @@

      Account I

    Activation Point

    -

    The first era to which the associated protocol version applies. It serializes as a single u8 tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a timestamp. If not, the bytes represent an era_id.

    +

    The first era to which the associated protocol version applies. It serializes as a single u8 tag indicating if the era in question is genesis. If it is the genesis era, the following bytes will be a timestamp. If not, the bytes represent an era_id.

    • era_id: An Era ID newtype identifying the era when the protocol version will activate.

      @@ -70,7 +70,7 @@

      ApprovalSignature. The first byte within the signature is 1 in the case of an Ed25519 signature or 2 in the case of Secp256k1.

    • -

      signer: The public key of the approvals signer. It serializes to the byte representation of the PublicKey. If the PublicKey is an Ed25519 key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of Secp256k1, the first byte is 2.

      +

      signer: The public key of the approvals signer. It serializes to the byte representation of the PublicKey. If the PublicKey is an Ed25519 key, then the first byte within the serialized buffer is 1 followed by the bytes of the key itself; else, in the case of Secp256k1, the first byte is 2.

    ApprovalsHash

    @@ -82,11 +82,11 @@

    AssociatedKey<

    account_hash: The account hash of the associated key.

  • -

    weight: The weight of an associated key. The weight serializes as a u8 value.

    +

    weight: The weight of an associated key. The weight serializes as a u8 value.

  • AvailableBlockRange

    -

    An unbroken, inclusive range of blocks. It serializes as two consecutive u64 values containing the following two fields:

    +

    An unbroken, inclusive range of blocks. It serializes as two consecutive u64 values containing the following two fields:

    • low: The inclusive lower bound of the range.

      @@ -99,22 +99,22 @@

      BalanceHoldA

      A balance hold address. It serializes as a BalanceHoldAddrTag describing the type of balance hold address as follows:

      • -

        Gas serializes as a BalanceHoldAddrTag of 0 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

        +

        Gas serializes as a BalanceHoldAddrTag of 0 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

      • -

        Processing serializes as a BalanceHoldAddrTag of 1 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

        +

        Processing serializes as a BalanceHoldAddrTag of 1 followed by the URef of the purse the hold will be placed on, and the block_time that the hold was placed.

      BalanceHoldAddrTag

      -

      A tag describing the type of BalanceHoldAddr, serializing as a single u8 value.

      +

      A tag describing the type of BalanceHoldAddr, serializing as a single u8 value.

      BalanceResponse

      BalanceResponse is a struct that provides the response to a balance query. It consists of the following fields:

      • -

        total_balance: The purse's total balance, not considering holds. It serializes as a U512 value.

        +

        total_balance: The purse's total balance, not considering holds. It serializes as a U512 value.

      • -

        available_balance: The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a U512 value.

        +

        available_balance: The available balance, consisting of the total balance minus the sum of all active holds. It serializes as a U512 value.

      • total_balance_proof: A proof that the given value is present in the Merkle trie. It serializes as a TrieMerkleProof, consisting of a key, a value and a proof_step.

        @@ -127,29 +127,29 @@

        BidAn entry in the validator map. The structure consists of the following fields:

        • -

          validator_public_key: The validator's public key. It serializes as a PublicKey.

          +

          validator_public_key: The validator's public key. It serializes as a PublicKey.

        • -

          bonding_purse: The purse used for bonding. It serializes as a Uref.

          +

          bonding_purse: The purse used for bonding. It serializes as a Uref.

        • -

          staked_amount: The amount of tokens staked by a validator (not including delegators). It serializes as a U512 value.

          +

          staked_amount: The amount of tokens staked by a validator (not including delegators). It serializes as a U512 value.

        • delegation_rate: The delegation rate of the bid. It serializes as an i32 signed 32-bit integer primitive.

        • -

          vesting_schedule: The vesting schedule for a genesis validator. None if it is a non-genesis validator. It serializes as an Option.

          +

          vesting_schedule: The vesting schedule for a genesis validator. None if it is a non-genesis validator. It serializes as an Option.

        • delegators: The validator's delegators, indexed by their public keys. They are serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of PublicKeys and delegators held within. The remainder consists of a repeating pattern of serialized PublicKeys and then delegators of the length dictated by the first four bytes.

        • -

          inactive: If the validator has been evicted. A boolean value that serializes as a single byte; true maps to 1, while false maps to 0.

          +

          inactive: If the validator has been evicted. A boolean value that serializes as a single byte; true maps to 1, while false maps to 0.

        BidAddr

        -

        BidAddr manages data associated with bids for the Auction system contract. It serializes as a single u8 tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:

        +

        BidAddr manages data associated with bids for the Auction system contract. It serializes as a single u8 tag describing the type of Bid, followed by information relating to the bid itself. It may be one of the following:

        • Unified A BidAddr for legacy unified bids. It serializes as a u8 of 0 followed by the account_hash identifying the legacy bid.

          @@ -165,7 +165,7 @@

          BidAddrBidKind

          -

          Auction bid variants. It serializes as a single u8 value indicating the type of bid kind as per the following table:

          +

          Auction bid variants. It serializes as a single u8 value indicating the type of bid kind as per the following table:

          @@ -207,7 +207,7 @@

          BlockIdentif

          Identifier for possible ways to retrieve a Block. It can consist of any of the following in most situations:

          • -

            hash: Identify and retrieve a Block with its hash. The BlockHash serializes as the byte representation of the hash itself.

            +

            hash: Identify and retrieve a Block with its hash. The BlockHash serializes as the byte representation of the hash itself.

          • height: Identify and retrieve the Block with its height. Height serializes as a single u64 value.

            @@ -231,10 +231,10 @@

            BlockSig

            BlockSignaturesV1 is a legacy version of BlockSignatures that applies to blocks created before the Condor release. The structure is as follows:

            • -

              block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

              +

              block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

            • -

              era_id: The era ID in which this block was created. It serializes as a single u64 value.

              +

              era_id: The era ID in which this block was created. It serializes as a single u64 value.

            • proofs: The proofs of the block, a collection of validator's signatures of the block hash. It serializes as a BTreeMap where the first 4 bytes represent a u32 value describing the number of PublicKeys and signatures held within. The remainder consists of a repeating pattern of serialized public keys and signatures of the length dictated by the first four bytes.

              @@ -244,13 +244,13 @@

              BlockSig

              BlockSignaturesV2 is the current version of BlockSignatures that applies to blocks created after the Condor release. The structure is as follows:

              • -

                block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

                +

                block_hash: The block hash of the associated block. It serializes as the byte representation of the hash itself.

              • block_height: The block height. It serializes as a single u64 value.

              • -

                era_id: The era ID in which this block was created. It serializes as a single u64 value.

                +

                era_id: The era ID in which this block was created. It serializes as a single u64 value.

              • chain_name_hash: The hash of the chain name of the associated block. It serializes as the byte representation of the hash itself.

                @@ -260,7 +260,7 @@

                BlockSig

              BlockSyncStatus

              -

              The status of syncing an individual block. It serializes as the byte representation of the block hash of the block in question, followed by an option representing a u64 of the block height and the remainder is the byte representation of the acquisition_state as a string.

              +

              The status of syncing an individual block. It serializes as the byte representation of the block hash of the block in question, followed by an option representing a u64 of the block height and the remainder is the byte representation of the acquisition_state as a string.

              BlockTime

              The block time serialized as a single u64 value.

              BTreeMap

              @@ -268,7 +268,7 @@

              BTreeMapBTreeSet

              A BTreeSet is a method of storing a set of values within a Casper network. They serialize with the first 4 bytes representing a u32 value describing the number of values held within. The remainder consists of a repeating series of values of the length dictated by the first four bytes.

              ByteCode

              -

              A container for a contract's Wasm bytes. It serializes as the single u8 BidKind, followed by a u32 value describing the size of the remaining Bytes and then the bytes as described.

              +

              A container for a contract's Wasm bytes. It serializes as the single u8 BidKind, followed by a u32 value describing the size of the remaining Bytes and then the bytes as described.

              Bytes

              Hex-encoded bytes serialized as a u32 value describing the length of the bytes, followed by the bytes themselves.

              ByteCodeKind

              @@ -290,10 +290,10 @@

              CallStack

              Session: Session code, which serializes as a u8 tag of 0 followed by the account_hash of the calling account.

            • -

              StoredSession: Stored access to a session, serializing as a u8 of 1 followed by the account_hash, contract_package_hash and the contract_hash.

              +

              StoredSession: Stored access to a session, serializing as a u8 of 1 followed by the account_hash, contract_package_hash and the contract_hash.

            • -

              StoredContract: A contract, which serializes as a u8 tag of 2 followed by the contract_package_hash and the contract_hash.

              +

              StoredContract: A contract, which serializes as a u8 tag of 2 followed by the contract_package_hash and the contract_hash.

            ChainNameDigest

            @@ -317,19 +317,19 @@

            DelegatorPublicKey.

            +

            delegator_public_key: The public key of the delegator, serialized as a PublicKey.

          • -

            staked_amount: The amount staked by the delegator, serialized as a U512 value.

            +

            staked_amount: The amount staked by the delegator, serialized as a U512 value.

          • -

            bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

            +

            bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

          • -

            validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

            +

            validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

          • -

            vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

            +

            vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

          Digest

          @@ -338,16 +338,16 @@

          DisabledVer

          Disabled contract versions, containing the following:

          • -

            contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

            +

            contract_version: The version of the contract within the protocol major version. It serializes as a u32 value.

          • -

            protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

            +

            protocol_version_major: The major element of the protocol version this contract is compatible with. It serializes as a u32 value.

          Effects

          A log of all transforms produced during execution, serialized as a vector of transforms.

          Entity Action Thresholds

          -

          The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

          +

          The minimum weight thresholds that have to be met when executing an action of a certain type. It serializes as three consecutive u8 values as follows.

          EntityKindTag

          A tag for the variants of EntityKind, serialized as a single u8 tag of 0 for System, 1 for Account and 2 for SmartContract.

          EntityVersionKey

          -

          The major element of ProtocolVersion combined with EntityVersion serialized as two u32 values.

          +

          The major element of ProtocolVersion combined with EntityVersion serialized as two u32 values.

          EntityVersions

          A collection of entity versions, serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of EntityVersionKeys mapped to AddressableEntityHashes within. The remainder consists of a repeating pattern of serialized EntityVersionKeys and AddressableEntityHashes of the length dictated by the first four bytes.

          EntryPoint (Contract)

          A type of signature method. Order of arguments matters, since this can be referenced by index as well as name.

          • -

            name: The name of the entry point, serialized as a String.

            +

            name: The name of the entry point, serialized as a String.

          • args: Arguments for this method. They serialize as a list of the Parameters, where each parameter represents an argument passed to the entrypoint.

          • -

            ret: The return type of the method, serialized as a Unit.

            +

            ret: The return type of the method, serialized as a Unit.

          • -

            access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

            +

            access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

          • entry_point_type: Identifies the type of entry point. It serializes as a 0 for Session and a 1 for Contract.

            @@ -414,22 +414,22 @@

            EntryPoint (Enti

            The type signature of a method. This structure consists of the following fields:

            • -

              name: The name of the entry point, serialized as a String.

              +

              name: The name of the entry point, serialized as a String.

            • args: Arguments for this method. They serialize as a list of the Parameters, where each parameter represents an argument passed to the entrypoint.

            • -

              ret: The return type of the method, serialized as a Unit.

              +

              ret: The return type of the method, serialized as a Unit.

            • -

              access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

              +

              access: An enum describing the possible access control options for a contract entry point. It serializes as a u8 value of 1 for public or a 2 followed by a List of authorized users.

            • -

              entry_point_type

              +

              entry_point_type

            • -

              entry_point_payment

              +

              entry_point_payment

            EntryPointAddr

            @@ -473,9 +473,9 @@

            EntrypointV2EntryPoints

            Entry points for a given entity, serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of String to EntryPoints held within. The remainder consists of a repeating pattern of serialized Strings and then EntryPoints of the length dictated by the first four bytes.

            EraID

            -

            An Era ID newtype. It serializes as a single u64 value.

            +

            An Era ID newtype. It serializes as a single u64 value.

            EraInfo

            -

            Auction metadata, intended to be recorded each era. It serializes as a List of seigniorage allocations.

            +

            Auction metadata, intended to be recorded each era. It serializes as a List of seigniorage allocations.

            ExecutableDeployItem

            The executable component of a Deploy, serialized as a u8 identifying tag followed by additional bytes as follows:

              @@ -483,16 +483,16 @@

              Execu

              ModuleBytes: Serializes as a u8 tag of 0 followed by bytes and runtimeargs.

            • -

              StoredContractByHash: Serializes as a u8 tag of 1 followed by the contract hash as an AddressableEntityHash, the name of an entry point as a String and runtimeargs.

              +

              StoredContractByHash: Serializes as a u8 tag of 1 followed by the contract hash as an AddressableEntityHash, the name of an entry point as a String and runtimeargs.

            • -

              StoredContractByName: Serializes as a u8 tag of 2 followed by the named key as a String, the name of an entry point as a String and runtimeargs.

              +

              StoredContractByName: Serializes as a u8 tag of 2 followed by the named key as a String, the name of an entry point as a String and runtimeargs.

            • -

              StoredVersionedContractByHash: Serializes as a u8 tag of 3 followed by the PackageHash, the version as an Option, an entry point as a String and runtimeargs.

              +

              StoredVersionedContractByHash: Serializes as a u8 tag of 3 followed by the PackageHash, the version as an Option, an entry point as a String and runtimeargs.

            • -

              StoredVersionedContractByName: Serializes as a u8 tag of 4 followed by the named key as a String, the version as an Option, the name of an entry point as a String and runtimeargs.

              +

              StoredVersionedContractByName: Serializes as a u8 tag of 4 followed by the named key as a String, the version as an Option, the name of an entry point as a String and runtimeargs.

            • Transfer: Serializes as a u8 tag of 5 followed by runtimeargs.

              @@ -502,7 +502,7 @@

              ExecutionEff

              The journal of execution transforms from a single deploy.

              • -

                operations: The resulting operations, serialized as a List of operations.

                +

                operations: The resulting operations, serialized as a List of operations.

              • transforms: The actual transformation performed while executing a deploy.

                @@ -517,13 +517,13 @@

                Failure

                effect: The effect of executing the deploy.

              • -

                transfers: A record of transfers performed while executing the deploy, serialized as a List.

                +

                transfers: A record of transfers performed while executing the deploy, serialized as a List.

              • -

                cost: The cost of executing the deploy, serializes as a U512 value.

                +

                cost: The cost of executing the deploy, serializes as a U512 value.

              • -

                error_message: The error message associated with executing the deploy, serialized as a String.

                +

                error_message: The error message associated with executing the deploy, serialized as a String.

              Success

              @@ -533,10 +533,10 @@

              Success

              effect: The effect of executing the deploy.

            • -

              transfers: A record of transfers performed while executing the deploy, serialized as a List.

              +

              transfers: A record of transfers performed while executing the deploy, serialized as a List.

            • -

              cost: The cost of executing the deploy, serializes as a U512 value.

              +

              cost: The cost of executing the deploy, serializes as a U512 value.

            ExecutionResultV2

            @@ -548,13 +548,13 @@

            Failureeffects: The effect of executing the transaction.

          • -

            transfers: A record of transfers performed while executing the transaction, serialized as a List.

            +

            transfers: A record of transfers performed while executing the transaction, serialized as a List.

          • -

            cost: The cost of executing the transaction, serializes as a U512 value.

            +

            cost: The cost of executing the transaction, serializes as a U512 value.

          • -

            error_message: The error message associated with executing the transaction, serialized as a String.

            +

            error_message: The error message associated with executing the transaction, serialized as a String.

          Success

          @@ -564,22 +564,22 @@

          Successeffects: The effects of executing the transaction.

        • -

          transfers: A record of transfers performed while executing the transaction, serialized as a List.

          +

          transfers: A record of transfers performed while executing the transaction, serialized as a List.

        • -

          cost: The cost of executing the transaction, serializes as a U512 value.

          +

          cost: The cost of executing the transaction, serializes as a U512 value.

        Gas

        -

        The Gas structure serializes as a U512 amount of gas.

        +

        The Gas structure serializes as a U512 amount of gas.

        Group

        -

        A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a String.

        +

        A (labeled) "user group". Each method of a versioned contract may be associated with one or more user groups which are allowed to call it. User groups are serialized as a String.

        Groups

        -

        They are serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of user groups and BTreeSets of URefs held within. The remainder consists of a repeating pattern of serialized user groups and BTreeSets of the length dictated by the first four bytes.

        +

        They are serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of user groups and BTreeSets of URefs held within. The remainder consists of a repeating pattern of serialized user groups and BTreeSets of the length dictated by the first four bytes.

        InitiatorAddr

        -

        The address of the initiator of a TransactionV1, which serializes as a u8 of 0 followed by a PublicKey or a 1 followed by an AccountHash.

        +

        The address of the initiator of a TransactionV1, which serializes as a u8 of 0 followed by a PublicKey or a 1 followed by an AccountHash.

        Keys

        -

        A key in Global State is one of the following data types:

        +

        A key in Global State is one of the following data types:

        • 32-byte account identifier (called an "account identity key")
        • 32-byte immutable contract identifier (called a "hash key")
        • @@ -594,21 +594,21 @@

          EraInfo, which actually serializes as a u64 value with an additional byte for the tag.

          +

          The one exception to note here is the identifier for EraInfo, which actually serializes as a u64 value with an additional byte for the tag.

          Account Identity Key

          -

          This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          +

          This key type is used specifically for accounts in the global state. All accounts in the system must be stored under an account identity key, and no other types. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          Hash Key

          -

          This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the blake2b256 hash of the deploy hash (see block-structure-head for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key.

          +

          This key type is used for storing contracts immutably. Once a contract is written under a hash key, that contract can never change. The 32-byte identifier representing this key is derived from the blake2b256 hash of the deploy hash (see block-structure-head for more information) concatenated with a 4-byte sequential ID. The ID begins at zero for each deploy and increments by one each time a contract is stored. The purpose of this ID is to allow each contract stored in the same deploy to have a unique key.

          Unforgeable Reference (URef)

          -

          URef broadly speaking can be used to store values and manage permissions to interact with the value stored under the URef. URef is a tuple which contains the address under which the values are stored and the Access rights to the URef. Refer to the Unforgeable Reference section for details on how URefs are managed.

          +

          URef broadly speaking can be used to store values and manage permissions to interact with the value stored under the URef. URef is a tuple which contains the address under which the values are stored and the Access rights to the URef. Refer to the Unforgeable Reference section for details on how URefs are managed.

          Transfer Key

          This key type is used specifically for transfers in the global state. All transfers in the system must be stored under a transfer key and no other type. The 32-byte identifier representing this key is derived from the blake2b256 hash of the transfer address associated with the given transfer.

          DeployInfo Key

          This key type is used specifically for storing information related to deploys in the global state. Information for a given deploy is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the deploy itself.

          EraInfo Key

          This key type is used specifically for storing information related to the Auction metadata for a particular era. The underlying data type stored under this is a vector of the allocation of seigniorage for that given era. The identifier for this key is a new type that wraps around the primitive u64 data type and co-relates to the era number when the auction information was stored.

          -

          This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          -

          This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          +

          This key type is used specifically for storing information related to auction bids in the global state. Information for the bids is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          +

          This key type is used specifically for storing information related to auction withdraws in the global state. Information for the withdrawals is stored under this key only. The 32-byte identifier which represents this key is derived from the blake2b256 hash of the public key used to create the associated account (see Accounts for more information).

          Serialization for Key

          Given the different variants for the over-arching Key data-type, each of the different variants is serialized differently. This section of this chapter details how the individual variants are serialized. The leading byte of the serialized buffer acts as a tag indicating the serialized variant.

          @@ -692,7 +692,7 @@

          CLValue section of this chapter for details on how AccessRights are serialized. +
        • URef is a tuple that contains the address of the URef and the access rights to that URef. The serialized representation of the URef is 33 bytes long. The first 32 bytes are the byte representation of the URef address, and the last byte contains the bits corresponding to the access rights of the URef. Refer to the CLValue section of this chapter for details on how AccessRights are serialized.
        • Transfer serializes as a 32 byte long buffer containing the byte representation of the hash of the transfer.
        • DeployInfo serializes as 32 byte long buffer containing the byte representation of the Deploy hash. See the Deploy section above for how Deploy hashes are serialized.
        • EraInfo serializes a u64 primitive type containing the little-endian byte representation of u64.
        • @@ -777,20 +777,20 @@

          URef permissions on how permissions are handled in the case of URefs.

          +

          Refer to URef permissions on how permissions are handled in the case of URefs.

          MessageTopics

          A topic for contract-level messages. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of topic_name strings and topic_name_hash held within. The remainder consists of a repeating pattern of serialized topic_name and topic_name_hash of the length dictated by the first four bytes.

          MessageTopicSummary

          -

          A summary of a message topic that will be stored in global state. It serializes as a u32 value for the message_count followed by the BlockTime

          +

          A summary of a message topic that will be stored in global state. It serializes as a u32 value for the message_count followed by the BlockTime

          Motes

          -

          A struct representing a number of Motes serialized as a U512 value.

          +

          A struct representing a number of Motes serialized as a U512 value.

          NamedArg

          -

          Named arguments to a contract. It is serialized by the combination of a String followed by the associated CLValue.

          +

          Named arguments to a contract. It is serialized by the combination of a String followed by the associated CLValue.

          NamedKey

          A mapping of string identifiers to a Casper Key type. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of named keys and values held within. The remainder consists of a repeating pattern of serialized named keys and then values of the length dictated by the first four bytes.

          • -

            name: The name of the entry. It serializes as a string.

            +

            name: The name of the entry. It serializes as a string.

          • key: The value of the entry, which is a Casper Key type.

            @@ -798,16 +798,16 @@

            NamedKeyhere.

            NamedKeyAddr

            -

            A NamedKey address, serialized as an EntityAddr followed by a u8 describing the length of a string and the 32-byte representation of the string itself.

            +

            A NamedKey address, serialized as an EntityAddr followed by a u8 describing the length of a string and the 32-byte representation of the string itself.

            NamedKeyValue

            -

            A NamedKey value, serialized as the named_key serialized as a CLValue followed by the name of the key also serialized as a CLValue.

            +

            A NamedKey value, serialized as the named_key serialized as a CLValue followed by the name of the key also serialized as a CLValue.

            NamedKeys

            -

            A collection of named keys. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names and keys held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes.

            +

            A collection of named keys. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names and keys held within. The remainder consists of a repeating pattern of names and keys of the length dictated by the first four bytes.

            Operation

            An operation performed while executing a deploy. It contains:

            • -

              key: The formatted string of the key, serialized as a String.

              +

              key: The formatted string of the key, serialized as a String.

            • kind: OpKind, The type of operation performed. It serializes as a single byte based on the following table:

              @@ -843,7 +843,7 @@

              Packageaccess_key

              +

              access_key

            • versions: An array of entity versions associated with given hashes.

              @@ -855,15 +855,15 @@

              Packagegroups

            • -

              lock_status

              +

              lock_status

            PackageHash

            -

            The hex-encoded address of a package associated with an AddressableEntity, serialized as the byte representation of itself.

            +

            The hex-encoded address of a package associated with an AddressableEntity, serialized as the byte representation of itself.

            PackageStatus

            -

            The lock status of the package, serialized as a boolean where true indicates a locked package and false indicates an unlocked package.

            +

            The lock status of the package, serialized as a boolean where true indicates a locked package and false indicates an unlocked package.

            Parameter

            -

            Parameter to a method, structured as a name followed by a CLType. It is serialized as a String followed by a CLType.

            +

            Parameter to a method, structured as a name followed by a CLType. It is serialized as a String followed by a CLType.

            PricingMode

            The pricing mode of a transaction, with two possible variants. It serializes as a u8 tag followed by additional data based on the following table:

            @@ -888,23 +888,23 @@

            PricingModeTagPricingModeDescription0ClassicThe original payment model, in which the creator of a transaction specifies how much they will pay and at which gas price.1FixedThe cost of the transaction is determined by the cost table, per the transaction kind.

            Classic

            -

            After the 0 tag, a Classic PricingMode serializes as the u64 payment_amount followed by the u64 value of the gas_price.

            +

            After the 0 tag, a Classic PricingMode serializes as the u64 payment_amount followed by the u64 value of the gas_price.

            Fixed

            -

            After the 1 tag, a Fixed PricingMode serializes as the u64 gas_price_tolerance.

            +

            After the 1 tag, a Fixed PricingMode serializes as the u64 gas_price_tolerance.

            ProtocolVersion

            -

            A newtype indicating the Casper Platform protocol version. It is serialized as three u32 values indicating major, minor and patch versions in that order.

            +

            A newtype indicating the Casper Platform protocol version. It is serialized as three u32 values indicating major, minor and patch versions in that order.

            PublicKey

            -

            Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under PublicKey.

            +

            Hex-encoded cryptographic public key, including the algorithm tag prefix. Serialization can be found under PublicKey.

            RewardedSignatures

            A list of identifiers for finality signatures for a particular past block. It serializes as a vector of SingleBlockRewardedSignatures which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

            RuntimeArgs

            -

            Represents a collection of arguments passed to a smart contract. They serialize as a List comprised of Tuples.

            +

            Represents a collection of arguments passed to a smart contract. They serialize as a List comprised of Tuples.

            SeigniorageAllocation

            Information about seigniorage allocation.

            -

            If the seigniorage allocation in question is for a validator, it serializes as the validator's PublicKey followed by the U512 amount.

            -

            If it is a delegator, it serializes as the delegator's PublicKey, followed by the validator's PublicKey and finally the U512 amount.

            +

            If the seigniorage allocation in question is for a validator, it serializes as the validator's PublicKey followed by the U512 amount.

            +

            If it is a delegator, it serializes as the delegator's PublicKey, followed by the validator's PublicKey and finally the U512 amount.

            SemVer

            -

            A struct for semantic versioning, it serializes as three u32 that describe the major version, minor version and patch version.

            +

            A struct for semantic versioning, it serializes as three u32 that describe the major version, minor version and patch version.

            Signature

            The signature serializes the byte representation of the underlying cryptographic primitive signature. The first byte within the signature is 1 in the case of an Ed25519 signature or 2 in the case of Secp256k1.

            Stored Values

            @@ -914,7 +914,7 @@

            accounts-head.

            +

            We discuss CLValue and contract in more detail below. Details about accounts can be found in accounts-head.

            Each StoredValue is serialized when written to the global state. The serialization format consists of a single byte tag, indicating which variant of StoredValue it is, followed by the serialization of that variant. The tag for each variant is as follows:

            • CLValue is 0
            • @@ -928,7 +928,7 @@

              SystemContractRegistry

              -

              SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts. This includes Mint, Auction, HandlePayment and StandardPayment. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names as strings and ContractHashes held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes.

              +

              SystemContractRegistry is a unique Key under which a mapping of the names and ContractHashes for system contracts. This includes Mint, Auction, HandlePayment and StandardPayment. It is serialized as a BTreeMap where the first 4 bytes represent a u32 value describing the number of names as strings and ContractHashes held within. The remainder consists of a repeating pattern of serialized strings and then ContractHashes of the length dictated by the first four bytes.

              SystemEntityType

              Entity types for system contracts, serialized as a single u8 tag identifying the contract as per the following table:

              @@ -958,9 +958,9 @@

              SystemEnt
              TagSystem Contract
              0Mint
              1Auction
              2StandardPayment
              3HandlePayment

              TimeDiff

              -

              A human-readable duration between two timestamps. It serializes as a single u64 value.

              +

              A human-readable duration between two timestamps. It serializes as a single u64 value.

              Timestamp

              -

              A timestamp formatted as per RFC 3339 and serialized as a single u64 value.

              +

              A timestamp formatted as per RFC 3339 and serialized as a single u64 value.

              TopicNameHash

              A blake2b hash of a topic name. The topic name hash serializes as a 32-byte buffer containing the bytes of the topic name hash.

              TransferAddr

              @@ -1067,7 +1067,7 @@

              TransformKin -
              Transform TypeSerializationDescription
              Identity0A transform having no effect.
              Write_CLValue1Writes the given CLValue to global state.
              Write_Account2Writes the given Account to global state.
              Write_Contract_WASM3Writes a smart contract as Wasm to global state.
              Write_Contract4Writes a smart contract to global state.
              Write_Contract_Package5Writes a smart contract package to global state.
              Write_Deploy_Info6Writes the given DeployInfo to global state.
              Write_Transfer7Writes the given Transfer to global state.
              Write_Era_Info8Writes the given EraInfo to global state.
              Write_Bid9Writes the given Bid to global state.
              Write_Withdraw10Writes the given Withdraw to global state.
              Add_INT3211Adds the given i32.
              Add_UINT6412Adds the given u64.
              Add_UINT12813Adds the given U128.
              Add_UINT25614Adds the given U256.
              Add_UINT51215Adds the given U512.
              Add_Keys16Adds the given collection of named keys.
              Failure17A failed transformation, containing an error message.
              +
              Transform TypeSerializationDescription
              Identity0A transform having no effect.
              Write_CLValue1Writes the given CLValue to global state.
              Write_Account2Writes the given Account to global state.
              Write_Contract_WASM3Writes a smart contract as Wasm to global state.
              Write_Contract4Writes a smart contract to global state.
              Write_Contract_Package5Writes a smart contract package to global state.
              Write_Deploy_Info6Writes the given DeployInfo to global state.
              Write_Transfer7Writes the given Transfer to global state.
              Write_Era_Info8Writes the given EraInfo to global state.
              Write_Bid9Writes the given Bid to global state.
              Write_Withdraw10Writes the given Withdraw to global state.
              Add_INT3211Adds the given i32.
              Add_UINT6412Adds the given u64.
              Add_UINT12813Adds the given U128.
              Add_UINT25614Adds the given U256.
              Add_UINT51215Adds the given U512.
              Add_Keys16Adds the given collection of named keys.
              Failure17A failed transformation, containing an error message.

              TransformKindV2

              The actual transformation performed while executing a deploy. It serializes as a single u8 value indicating the type of transform performed as per the following table. The remaining bytes represent the information and serialization as listed.

              @@ -1130,59 +1130,59 @@

              TransformKin -
              Transform TypeSerializationDescription
              Identity0A transform having no effect, created as a result of reading from the global state.
              Write1Writes a new value in the global state.
              AddInt322Adds the given i32.
              AddUInt643Adds the given u64.
              AddUInt1284Adds the given U128.
              AddUInt2565Adds the given U256.
              AddUInt5126Adds the given U512.
              AddKeys7Adds the given collection of named keys.
              Failure8A failed transformation, containing an error message.
              Prune9Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states.
              +
              Transform TypeSerializationDescription
              Identity0A transform having no effect, created as a result of reading from the global state.
              Write1Writes a new value in the global state.
              AddInt322Adds the given i32.
              AddUInt643Adds the given u64.
              AddUInt1284Adds the given U128.
              AddUInt2565Adds the given U256.
              AddUInt5126Adds the given U512.
              AddKeys7Adds the given collection of named keys.
              Failure8A failed transformation, containing an error message.
              Prune9Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states.

              TransformEntry

              A transformation performed while executing a deploy.

              TransformV1

              -

              A legacy transform struct serialized as a String of the key followed by the transformkindv1.

              +

              A legacy transform struct serialized as a String of the key followed by the transformkindv1.

              Transformv2

              -

              A struct representing an executed transformation serialized as a String of the key followed by the transformkindv2.

              +

              A struct representing an executed transformation serialized as a String of the key followed by the transformkindv2.

              UnbondingPurse

              A purse used for unbonding. The structure consists of the following:

              • -

                bonding_purse: The bonding purse, serialized as a URef.

                +

                bonding_purse: The bonding purse, serialized as a URef.

              • -

                validator_public_key: The public key of the validator, serialized as a PublicKey.

                +

                validator_public_key: The public key of the validator, serialized as a PublicKey.

              • -

                unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

                +

                unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

              • -

                era_of_creation: Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

                +

                era_of_creation: Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

              • -

                amount: The unbonding amount, serialized as a U512 value.

                +

                amount: The unbonding amount, serialized as a U512 value.

              • -

                new_validator: The validator public key to redelegate to, serialized as an Option containing the public key.

                +

                new_validator: The validator public key to redelegate to, serialized as an Option containing the public key.

              ValidatorBid

              An entry in the validator map. The structure consists of the following fields:

              • -

                validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

                +

                validator_public_key: The public key of the validator that the delegator will be delegating to, serialized as a PublicKey.

              • -

                bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

                +

                bonding_purse: The bonding purse associated with the delegation. It serializes as a URef value.

              • -

                staked_amount: The amount staked by the delegator, serialized as a U512 value.

                +

                staked_amount: The amount staked by the delegator, serialized as a U512 value.

              • -

                delegation_rate: The delegation rate serialized as a u8 value.

                +

                delegation_rate: The delegation rate serialized as a u8 value.

              • -

                vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

                +

                vesting_schedule: The vesting schedule for the provided delegator bid. None if it is a non-genesis validator. It serializes as an Option.

              • -

                inactive: The validator's inactivity status, serialized as a boolean.

                +

                inactive: The validator's inactivity status, serialized as a boolean.

              ValidatorChange

              -

              A change to a validator's status between two eras, serialized as a u8 tag as follows:

              +

              A change to a validator's status between two eras, serialized as a u8 tag as follows:

              @@ -1214,38 +1214,38 @@

              ValidatorCh
              TagChange
              0Added
              1Removed
              2Banned
              3Cannot Propose
              4Seen as Faulty

              ValidatorConfig

              -

              A validator account configuration, serialized as a bonded_amount followed by the delegation_rate as a u8.

              +

              A validator account configuration, serialized as a bonded_amount followed by the delegation_rate as a u8.

              ValidatorCredit

              A struct representing the record of a validator credit, with fields as follows:

              WithdrawPurse

              A purse used for unbonding, replaced in 1.5 by UnbondingPurse. WithdrawPurses prior to 1.5 were known as UnbondingPurses and now consist of historical data.

              • -

                bonding_purse: The bonding purse, serialized as a URef.

                +

                bonding_purse: The bonding purse, serialized as a URef.

              • -

                validator_public_key: The public key of the validator, serialized as a PublicKey.

                +

                validator_public_key: The public key of the validator, serialized as a PublicKey.

              • -

                unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

                +

                unbonder_public_key: The public key of the unbonder, serialized as a PublicKey.

              • -

                era_of_creation Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

                +

                era_of_creation Era in which this unbonding request was created, as an EraId newtype, which serializes as a u64 value.

              • -

                amount The unbonding amount, serialized as a U512 value.

                +

                amount The unbonding amount, serialized as a U512 value.

              • -

    +
    \ No newline at end of file diff --git a/concepts/smart-contracts/index.html b/concepts/smart-contracts/index.html index ca749cf9d..e3095d485 100644 --- a/concepts/smart-contracts/index.html +++ b/concepts/smart-contracts/index.html @@ -1,35 +1,38 @@ - + -Smart Contracts | Casper Docs - Redux +Smart Contracts | Casper Docs - Redux - - + +
    Version: 1.5.X

    Smart Contracts

    + submit an issue on Github
    Version: Next

    Smart Contracts

    Smart Contracts in General

    A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism.

    Casper Smart Contracts

    -

    Casper smart contracts can be implemented in any programming language that compiles to Wasm, which can be installed and executed on-chain using Deploys. Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust here.

    +

    Casper smart contracts can be implemented in any programming language that compiles to Wasm, which can be installed and executed on-chain using transactions. Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust here.

    Session Code

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either session code or another smart contract may call these entry points. Understand when you would use session code over contract code here.

    +

    Factory Pattern

    +

    From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding Casper Enhancement Proposal provides additional details. Also, you can learn to write a simple contract with factory entry points by following the The Factory Pattern developer guide.

    Further Reading

    +
  • The Factory Pattern
  • +
    \ No newline at end of file diff --git a/counter-testnet/index.html b/counter-testnet/index.html index 6d196f505..1093eb21b 100644 --- a/counter-testnet/index.html +++ b/counter-testnet/index.html @@ -1,22 +1,22 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: 1.5.X

    A Counter on the Testnet

    -

    This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    + submit an issue on Github
    Version: Next

    A Counter on the Testnet

    +

    This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    Here is how the tutorial is structured:

    • Tutorial Overview - Introduction to the process and what will be covered
    • @@ -26,17 +26,17 @@

      Prerequisites

      1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
      2. -
      3. You have installed the Casper client to send deploys to the chain.
      4. +
      5. You have installed the Casper client to send transactions to the chain.
      6. You were able to set up and fund an account on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial:
        • The location of your account’s secret_key.pem file
        • Your account hash identifier
      7. -
      8. You selected a node whose RPC port will be receiving the deploys coming from your account.
      9. +
      10. You selected a node whose RPC port will be receiving the transactions coming from your account.

      Video Tutorial

      If you prefer a video walkthrough of this guide, you can check out this video.

      -
    +
    \ No newline at end of file diff --git a/counter/index.html b/counter/index.html index 06d04103b..17e3fe79b 100644 --- a/counter/index.html +++ b/counter/index.html @@ -1,22 +1,22 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: 1.5.X

    A Counter on an NCTL Network

    -

    This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send deploys to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    + submit an issue on Github
    Version: Next

    A Counter on an NCTL Network

    +

    This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    Here is how the tutorial is structured:

    • Tutorial Overview - Introduction to the process and what will be covered
    • @@ -27,7 +27,7 @@

      Prerequisites<
      1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
      2. You have completed the NCTL tutorial, which introduces you to the CLI tool to set up and control local Casper networks for development.
      3. -
      4. You have installed the Casper client to send deploys to the chain.
      5. -

    +
  • You have installed the Casper client to send transactions to the chain.
  • +
    \ No newline at end of file diff --git a/deploy-and-deploy-lifecycle/index.html b/deploy-and-deploy-lifecycle/index.html deleted file mode 100644 index 85187395a..000000000 --- a/deploy-and-deploy-lifecycle/index.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - -Deploy Lifecycle | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Deploys and the Deploy Lifecycle

    -

    Deploys

    -

    A Deploy is a data structure containing Wasm and the requester's signature(s). Additionally, the deploy header contains additional metadata about the deploy itself. A deploy’s structure is as follows:

    -

    Structure of a Deploy

    -
      -
    • Body: Containing payment code and session code (more details on these below)
    • -
    • Header: containing -
        -
      • The Public Key of the account in whose context the deploy will run
      • -
      • The timestamp of the deploy’s creation
      • -
      • A time-to-live, after which the deploy expires and cannot be included in a block
      • -
      • the blake2b256 hash of the body
      • -
      -
    • -
    • Deploy hash: the blake2b hash of the Header
    • -
    • Approvals: the set of signatures which have signed the deploy hash; these are used in the account permissions model
    • -
    -

    The Deploy Lifecycle

    -

    A deploy goes through the following phases on Casper:

    -
      -
    1. Deploy Received
    2. -
    3. Deploy Gossiped
    4. -
    5. Block Proposed
    6. -
    7. Block Gossiped
    8. -
    9. Consensus Reached
    10. -
    11. Deploy Executed
    12. -
    -

    Deploy Received

    -

    A client sending the deploy will send it to one or more nodes via their JSON RPC servers. The node will ensure that a given deploy matches configuration settings outlined in the network's chainspec. Deploy configuration for the Casper Mainnet can be found here. Once accepted, the system returns the deploy hash to the client to indicate it has been enqueued for execution. The deploy could expire while waiting to be gossiped; whenever this happens, a DeployExpired event is emitted by the event stream servers of all nodes which have the expired deploy.

    -

    Deploy Gossiped

    -

    After a node accepts a new deploy, it will gossip to all other nodes. A validator node will put the deploy into the block proposer buffer. The validator leader will pick the deploy from the block proposer buffer to create a new proposed block for the chain. This mechanism is efficient and ensures all nodes in the network eventually hold the given deploy. Each node that accepts a gossiped deploy also emits a DeployAccepted event on its event stream server. The deploy may expire while waiting for a node to add it to the block. Whenever this happens, the node emits a DeployExpired event.

    -

    Block Proposed

    -

    The validator leader for this round will propose a block that includes as many deploys from the block proposer buffer as can fit in a block.

    -

    Block Gossiped

    -

    The proposed block propagates to all other nodes.

    -

    Consensus Reached

    -

    Once the other validators reach consensus that the proposed block is valid, all deploys in the block are executed, and this block becomes the final block added to the chain. Whenever reaching consensus, the event stream server emits a BlockAdded. FinalitySignature events emit shortly after that. Finality signatures for the new block arrive from the validators.

    -

    Deploy Executed

    -

    A deploy executes in distinct phases to accommodate flexibly paying for computation. The phases of a deploy are payment, session, and finalization. Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the deploy is executed, a DeployProcessed event is emitted by the event stream server.

    -

    In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty deploys.

    -

    Payment code

    -

    Payment code determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a deploy. For example, the simplest payment code could use the account's main purse. In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only accounts with a balance in their main purse greater than or equal to MAX_PAYMENT_COST may execute deploys. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than MAX_PAYMENT_COST motes (a constant of the system.) -If the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending account's main purse.

    -

    Session code

    -

    Session code provides the main logic for the deploy. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself).

    -

    Specifying payment code and session code

    -

    The user-defined logic of a deploy can be specified in a number of ways:

    -
      -
    • a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the account the deploy is running in.)
    • -
    • a 32-byte identifier representing the hash where a contract is already stored in the global state
    • -
    • a name corresponding to a named key in the account, where a contract is stored under the key
    • -
    -

    Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module).

    -

    Summary

    -

    The following diagram summarizes the deploy lifecycle.

    -

    Image showing the deploy lifecycle

    - - \ No newline at end of file diff --git a/design/index.html b/design/index.html index a8644b0da..f4c07a8bf 100644 --- a/design/index.html +++ b/design/index.html @@ -1,20 +1,20 @@ - + -Design Overview | Casper Docs - Redux +Design Overview | Casper Docs - Redux - - + +
    + submit an issue on Github
    Version: Next

    Design Overview

    TopicDescription
    Network DesignOverview of execution semantics, account permissions, URefs, block structure, tokens, and more
    Network CommunicationPeer-to-peer communication for Casper nodes
    Consensus in CasperIntroduction to Consensus in a Casper network
    Zug ConsensusAn overview of the Zug consensus used in Mainnet and Testnet
    Highway ConsensusBrief overview of the Highway consensus available as an alternative to Zug
    Validator RewardsOverview of how rewards are calculated and distributed
    Reading and Writing Data to Global StateStoring and reading data from the blockchain
    \ No newline at end of file diff --git a/developers/cli/calling-contracts/index.html b/developers/cli/calling-contracts/index.html index 43b130823..8d740b15c 100644 --- a/developers/cli/calling-contracts/index.html +++ b/developers/cli/calling-contracts/index.html @@ -1,22 +1,21 @@ - + -Calling Contracts | Casper Docs - Redux +Calling Contracts | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Calling Smart Contracts with the Rust Client

    + submit an issue on Github
    Version: Next

    Calling Smart Contracts with the Rust Client

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. This tutorial covers different ways to call Casper contracts with the Casper command-line client and the put-deploy command. Each section below includes a short video demonstrating some example output.

    The following examples use two contracts on Testnet:

      @@ -25,7 +24,7 @@

    Prerequisites

    +
    \ No newline at end of file diff --git a/developers/cli/delegate/index.html b/developers/cli/delegate/index.html index 5bd1232bf..d450e1bab 100644 --- a/developers/cli/delegate/index.html +++ b/developers/cli/delegate/index.html @@ -1,26 +1,26 @@ - + -Delegating Tokens | Casper Docs - Redux +Delegating Tokens | Casper Docs - Redux - - + +
    Version: Next

    Delegating with the Casper Client

    This document details a workflow where an account holder on a Casper network can delegate tokens to a validator.

    Prerequisites

    1. You meet all prerequisites listed here, including having a valid node-address and the Casper command-line client
    2. -
    3. You have previously installed a smart contract to a Casper network
    4. +
    5. You have previously installed a smart contract to a Casper network
    6. Acquiring a Validator's Public Key

    Acquiring a Validator's Public Key

    @@ -91,7 +91,7 @@

    casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key ~/KEYS/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ~/delegate.wasm \
    --session-arg "validator:public_key='01aa17f7b9889480b1bd34c3f94f263b229c7a9b01dd4dda19c2dd1d38d176c7a0'" \
    --session-arg "amount:u512='500000000000'" \
    --session-arg "delegator:public_key='01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51'"

    Next, confirm the delegation.

    Confirming the Delegation

    -

    A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the foloowing:

    +

    A Casper network maintains an auction where validators bid on slots to become part of the active validator set. Delegation rewards are only earned for a validator who has won the auction and is part of the active set. Thus to ensure the delegated tokens can earn rewards, you must first check the following:

    1. Your delegation is part of the bid to the auction
    2. The validator is part of the active validator set
    3. @@ -118,6 +118,6 @@

      Ch
      1. Testnet explorer
      2. Mainnet explorer
      3. -

    +
    \ No newline at end of file diff --git a/developers/cli/execution-error-codes/index.html b/developers/cli/execution-error-codes/index.html index d326f612f..1e7cf3877 100644 --- a/developers/cli/execution-error-codes/index.html +++ b/developers/cli/execution-error-codes/index.html @@ -1,21 +1,21 @@ - + -Execution Error Codes | Casper Docs - Redux +Execution Error Codes | Casper Docs - Redux - - + +
    Version: Next

    Execution Error Codes

    This section covers smart contract execution error codes.

    As mentioned in Writing Rust Contracts, smart contracts can exit with an error code defined by an ApiError. Descriptions of each variant are found here and include the following sub-types:

    -

    An ApiError of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ApiError::User(2) maps to an exit code of 65538 (i.e. 65536 + 2). You can find a mapping from contract exit codes to ApiError variants here.

    +

    An ApiError of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ApiError::User(2) maps to an exit code of 65538 (i.e. 65536 + 2). You can find a mapping from contract exit codes to ApiError variants here.

    \ No newline at end of file diff --git a/developers/cli/index.html b/developers/cli/index.html index abd72a2d6..3c864b3de 100644 --- a/developers/cli/index.html +++ b/developers/cli/index.html @@ -1,21 +1,21 @@ - + -Interacting with the Blockchain | Casper Docs - Redux +Interacting with the Blockchain | Casper Docs - Redux - - + +
    Version: 1.5.X

    Using the Casper CLI Client

    + submit an issue on Github
    Version: Next

    Using the Casper CLI Client

    This section explains how to interact with a Casper network using the Casper command-line client written in Rust.

    @@ -58,6 +58,10 @@ -
    TopicDescription
    Transferring TokensTransferring tokens from one account to another using the Casper command-line client
    Delegating tokensDelegating tokens to a validator on a Casper network
    Undelegating Tokens with the Casper ClientUndelegating tokens from a validator on a Casper network
    Sending Deploys to a NetworkSending Deploys to a Casper network using the Rust CLI Client
    Installing Smart ContractsSteps to install a contract on a Casper network
    Querying Global StateHow to query global state after contract installation
    Calling Smart Contracts with the Rust ClientVarious ways to call a contract's entry-points
    Execution Error CodesError codes for smart contract execution
    + + + + +
    TopicDescription
    Transferring TokensTransferring tokens from one account to another using the Casper command-line client
    Delegating tokensDelegating tokens to a validator on a Casper network
    Undelegating Tokens with the Casper ClientUndelegating tokens from a validator on a Casper network
    Sending Deploys to a NetworkSending Deploys to a Casper network using the Rust CLI Client
    Installing Smart ContractsSteps to install a contract on a Casper network
    Verifying contracts using the Casper ClientHow to use Smart Contract Verification Service
    Querying Global StateHow to query global state after contract installation
    Calling Smart Contracts with the Rust ClientVarious ways to call a contract's entry-points
    Execution Error CodesError codes for smart contract execution
    \ No newline at end of file diff --git a/developers/cli/installing-contracts/index.html b/developers/cli/installing-contracts/index.html index 2a2914fb1..1ac6f4717 100644 --- a/developers/cli/installing-contracts/index.html +++ b/developers/cli/installing-contracts/index.html @@ -1,118 +1,61 @@ - + -Installing Contracts | Casper Docs - Redux +Installing Contracts | Casper Docs - Redux - - + +
    Version: Next

    Installing Smart Contracts

    This document details the process of installing Casper smart contracts using the Casper command-line client and the put-deploy command.

    Prerequisites

      -
    • You have a compiled contract (.wasm file) to send to a Casper network
    • -
    • You have installed the Casper CLI client to interact with the network
    • -
    • You have a Casper Account with a public and secret key pair to initiate the deploy
    • -
    • You have enough CSPR tokens in your account's main purse to pay for deploys. If you plan to use the Casper Testnet, learn about the faucet to fund your testing account's main purse
    • +
    • You have a compiled contract Wasm to send to a Casper network.
    • +
    • You have installed the Casper CLI client to interact with the network.
    • +
    • You have a Casper Account with a public and secret key pair to initiate the transaction.
    • +
    • You have enough CSPR tokens in your account's main purse to pay for transactions. If you plan to use the Casper Testnet, learn about the faucet to fund your testing account's main purse.

    Installing a Contract in Global State

    -

    To install a contract in global state, you need to send a deploy to the network with the contract Wasm. You can do so by using the put-deploy command.

    -
    casper-client put-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [CONTRACT_PATH]/[CONTRACT_NAME].wasm
    +

    To install a contract in global state, you need to send a transaction to the network with the contract Wasm. You can do so by using the put-transaction session command, or the equivalent put-txn session command.

    +
    casper-client put-transaction session \
    --node-address [NODE_SERVER_ADDRESS] \
    --chain-name [CHAIN_NAME] \
    --secret-key [KEY_PATH]/secret_key.pem \
    --gas-price-tolerance [MAX_GAS_AMOUNT] \
    --pricing-mode fixed \
    --transaction-path <PATH> \
    --session-entry-point call \
    --category 'install-upgrade'

    The arguments used above are:

    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • -
    • chain-name - The chain name to the network where you wish to send the deploy. For Mainnet, use casper. For Testnet, use casper-test
    • -
    • secret-key - The file name containing the secret key of the account paying for the deploy
    • -
    • payment-amount - The payment for the deploy in motes
    • -
    • session-path - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer
    • +
    • chain-name - The network where you wish to send the transaction. For Mainnet, use casper. For Testnet, use casper-test
    • +
    • secret-key - The file name containing the secret key of the account paying for the transaction
    • +
    • gas-price-tolerance - The maximum amount of gas a user is willing to pay for execution
    • +
    • pricing-mode - Set to "fixed" for Mainnet and Testnet
    • +
    • transaction-path - The path to the contract Wasm, which should point to wherever you compiled the contract (.wasm file) on your computer
    • +
    • session-entry-point - Name of the entrypoint that will be used when installing the contract, which is usually call
    • +
    • category - The transaction type, based on Wasm size, with install-upgrade being the largest
    -

    Once you call this command, it will return a deploy hash. You can use this hash to verify successful execution of the deploy.

    -

    Example - Install the contract:

    -

    Here we send a counter-v1.wasm to a local NCTL network.

    -
    casper-client put-deploy \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount 5000000000000 \
    --session-path ./counter/target/wasm32-unknown-unknown/release/counter-v1.wasm
    -
    tip

    The payment amount varies based on each contract and network chainspec.

    -

    To verify the deploy, call get-deploy and provide the deploy hash you received from put-deploy.

    -
    casper-client get-deploy \
    --node-address http://localhost:11101 [DEPLOY_HASH]
    -

    Video - Contract Installation Walkthrough

    -

    This video demonstrates the commands described above for installing a contract on-chain.

    -

    - -

    -

    Querying Global State

    -

    Here we look at how to query global state to see details about a successfully installed contract.

    -

    Get the state root hash

    -

    The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time.

    -
    note

    After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state.

    -

    To get the state root hash, use the get-state-root-hash command:

    -
    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    -

    Query global state

    -

    Next, query the state of a Casper network at a given time, specified by the state-root-hash described above. You can dive into the data stored in global state using the optional query path argument -q.

    -
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [HASH_STRING] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"
    -

    The arguments used above are:

    -
      -
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • -
    • state-root-hash - Hex-encoded hash of the state root
    • -
    • key - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash
    • -
    • q - An optional query path argument that allows you to drill into the specifics of a query with respect to the key
    • -
    -

    Example - Query the account:

    -

    To find your account details, query global state using your account hash.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d
    -

    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
    - -
    {
    "id": -6831525034388467034,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[27614 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "weight": 1
    }
    ],
    "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",
    "named_keys": [
    {
    "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "name": "counter"
    },
    {
    "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "name": "counter_access_uref"
    },
    {
    "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "name": "counter_package_name"
    },
    {
    "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",
    "name": "version"
    }
    ]
    }
    }
    }
    }
    -
    -

    -
    tip

    If you don't know your account hash, you can run this command:

    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    -

    Example - Query the contract:

    -

    This example shows how to query global state given a contract hash. We use the contract hash from the sample response above.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e
    -

    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
    - -
    {
    "id": -4657473054587773855,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[21330 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",
    "entry_points": [
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_get",
    "ret": "I32"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_inc",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",
    "name": "count"
    }
    ],
    "protocol_version": "1.4.5"
    }
    }
    }
    }

    -
    -

    -

    Example - Query a value using its key and the contract hash:

    -

    Next, you can query a named key associated with the contract using the -q option. This example comes from the Counter Contract Tutorial, where a "count" variable is incremented and stored under a named key.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_HASH] \
    -q "count"
    -
    Sample stored value
    - -
    {
    "id": -2540117660598287261,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[56562 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "00000000",
    "cl_type": "I32",
    "parsed": 0
    }
    }
    }
    }
    -
    -

    -

    Example - Query a value using the account hash and named keys:

    -

    It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \
    -q "counter/count"
    -

    The response should be the same as in Example 3, above.

    -

    Example - Query contract package state:

    -

    You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \
    --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966
    -

    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 in the next section. You would also see the access_key for the ContractPackage and the current contract_version.

    -
    Sample contract package state
    +

    Once you call this command, it will return a transaction hash. You can use this hash to verify successful execution of the transaction.

    +
    tip

    The pricing mode varies based on each network chainspec. For Mainnet and Testnet, the pricing mode is "fixed", meaning that costs are fixed per the cost table, and senders do not specify how much they pay.

    +

    Example - Contract Installation

    +

    Here we send a counter-installer.wasm to a local NCTL network:

    +
    casper-client put-transaction session \
    --node-address http://localhost:11101 \
    --chain-name casper-net-1 \
    --secret-key ~/casper/casper-nctl/assets/net-1/users/user-1/secret_key.pem \
    --gas-price-tolerance 10 \
    --pricing-mode fixed \
    --transaction-path ~/test_contracts/counter_installer.wasm \
    --session-entry-point call \
    --category 'install-upgrade'
    +

    The result of the query includes a transaction_hash:

    +
    {
    "jsonrpc": "2.0",
    "id": 90342686534145684,
    "result": {
    "api_version": "2.0.0",
    "transaction_hash": {
    "Version1": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2"
    }
    }
    }
    +

    To verify the transaction, call get-transaction and provide the transaction hash you received from put-transaction.

    +
    casper-client get-transaction --node-address http://localhost:11101 [TRANSACTION_HASH]
    +
    Expand to view the sample response details
    -
    {
    "id": -6225901853092301031,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[20964 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }
    +
    {
    "jsonrpc": "2.0",
    "id": 5297043714444661948,
    "result": {
    "api_version": "2.0.0",
    "transaction": {
    "Version1": {
    "hash": "49c36616a50962fa5a7dd7901677ae44667fa9f8c542e49eb2284ba2c900bba2",
    "header": {
    "chain_name": "casper-net-1",
    "timestamp": "2024-08-21T11:21:36.201Z",
    "ttl": "30m",
    "body_hash": "543df05d05c456e9b6b5d657029e9ad20c674c6e6b56f498af0052ec87ee9f80",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 10
    }
    },
    "initiator_addr": {
    "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"
    }
    },
    "body": {
    "args": [],
    "target": {
    "Session": {
    "module_bytes": "[105936 hex chars]",
    "runtime": "VmCasperV1"
    }
    },
    "entry_point": "Call",
    "transaction_category": 2,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d",
    "signature": "01537684dd531ce6a4c9383ba7ea565e9408ed2c5dd8bb12787f131e1148fd0f057f45dbaa7bbc0230743cc5740c67db64f66bab1df57547722899f7d7289c1f0c"
    }
    ]
    }
    },
    "execution_info": {
    "block_hash": "24ead40278a71966e16823150b06c06675a216dbef761c1d6ad1439da4147f4a",
    "block_height": 8463,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "0149d133f697b5867d312e18ae0b129ef0c63499df2815fe339dca727963edb80d"
    },
    "error_message": null,
    "limit": "1000000000000",
    "consumed": "46747144601",
    "cost": "1000000000000",
    "payment": [],
    "transfers": [],
    "size_estimate": 53215,
    "effects": [
    {
    "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "I32",
    "bytes": "00000000",
    "parsed": 0
    }
    }
    }
    },
    {
    "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-05c3e063406ddde43671e0d47c45e31a10e9204137171f96ce818bdc725a4e1b",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1050d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "parsed": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"
    },
    "name": {
    "cl_type": "String",
    "bytes": "14000000636f756e7465725f7061636b6167655f6e616d65",
    "parsed": "counter_package_name"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-6409273bf327d5a6a39a29dbd07c5cd2f48ee4f227fd443d025adc51e1bd5103",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0229feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a07",
    "parsed": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000636f756e7465725f6163636573735f75726566",
    "parsed": "counter_access_uref"
    }
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",
    "kind": "Identity"
    },
    {
    "key": "package-f1c97c9b6228be3f316753e4e1289d910071fb880dddccce18881abfb9f53526",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "[82290 hex chars]"
    }
    }
    }
    },
    {
    "key": "named-key-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-5fed34ec1b2c38445b984eee743ce17fb1e5e89a8cb910cc2f9f12b005360eef",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab0363140707",
    "parsed": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "05000000636f756e74",
    "parsed": "count"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-399a84b0da15b34ecd774b1c4ad47c72a9e1298df057d83bee93d22ac4972aa5",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "counter_get",
    "args": [],
    "ret": "I32",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68-3eba75fc27f0ec2786e09c09d72d61e4c28a86d44d8efc9911460d5438396481",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "counter_inc",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-174ccaaa723ba74cee869017501fab28512b6ef9296d48a38daff7d0da13d1a1",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "027bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf07",
    "parsed": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "0700000076657273696f6e",
    "parsed": "version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463-83b1cde13136393741a1e906a892ccdd289e7827cc9ef84a98cc96e86464bde0",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68",
    "parsed": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    },
    "name": {
    "cl_type": "String",
    "bytes": "07000000636f756e746572",
    "parsed": "counter"
    }
    }
    }
    }
    },
    {
    "key": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Prune": "balance-hold-0121dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000"
    }
    },
    {
    "key": "balance-hold-0021dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f172b7ab7491010000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "050010a5d4e8",
    "parsed": "1000000000000"
    }
    }
    }
    },
    {
    "key": "entity-system-b76adcf84d4900edec0af9001e727bcc3d4920a40afaa6a0e43137bacf62b91e",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1f15cf43df68e8b382415a8ef687521f61f1ecce6960b72eaa13f43bfc448139",
    "kind": "Identity"
    },
    {
    "key": "entity-system-1d29f1bd6ba7016f430498de2d0fe7c9d2c14c200d79be33e0ad240bc2a0d229",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-01f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d",
    "kind": "Identity"
    },
    {
    "key": "bid-addr-04f47c77764d4d4c0030c563266724e78e07b2b4719ecfceeae816470c5ecf882d0903000000000000",
    "kind": {
    "Write": {
    "BidKind": {
    "Credit": {
    "validator_public_key": "01e4bb993269e0fe33d6e575ab6a642fdcaf692449a1529c4f73e636dfff9d3e61",
    "era_id": 777,
    "amount": "1000000000000"
    }
    }
    }
    }
    }
    ]
    }
    }
    }
    }
    }
    -

    -

    Video - Querying Walkthrough

    -

    This video shows you what to expect when querying the network.

    -

    - -

    +

    Note the contract entity address in the above sample output. You will need this to query the contract installed. In this example, the address is entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68.

    +

    Next, query global state to see more details about the successfully installed contract.

    What's Next?

    +
  • Learn to query global state using the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/developers/cli/opcode-costs/index.html b/developers/cli/opcode-costs/index.html index 044343e46..68a6df41a 100644 --- a/developers/cli/opcode-costs/index.html +++ b/developers/cli/opcode-costs/index.html @@ -1,21 +1,21 @@ - + -OpCode Costs Tables | Casper Docs - Redux +OpCode Costs Tables | Casper Docs - Redux - - + +
    Version: Next

    OpCode Costs Tables

    The following tables outline the cost, in motes, for a given operation on Casper's Mainnet. If you are building for a private network or other instance of Casper, you will need to verify these costs in the associated chainspec.toml.

    More information on chainspecs for private networks can be found here

    note

    All costs in this table are in motes, not CSPR, and the corresponding chainspec is here.

    @@ -35,7 +35,7 @@

    Storage Costs< -
    AttributeDescriptionCost
    gas_per_byteGas charged per byte stored in global state.630,000
    +
    AttributeDescriptionCost
    gas_per_byteGas charged per byte stored in global state.1_117_587

    OpCode Costs

    @@ -122,7 +122,7 @@

    OpCode CostsAttributeDescriptionCostbitBit operations multiplier.300addArithmetic add operations multiplier.210mulMul operations multiplier.240divDiv operations multiplier.320loadMemory load operation multiplier.2_500storeMemory store operation multiplier.4,700constConst store operation multiplier.110localLocal operations multiplier.390globalGlobal operations multiplier.390integer_comparisonInteger operations multiplier.250conversionConversion operations multiplier.420unreachableUnreachable operation multiplier.270nopNop operation multiplier.200current_memoryGet the current memory operation multiplier.290grow_memoryGrow memory cost per page (64 kB).240,000 +
    AttributeDescriptionCost
    bitBit operations multiplier.300
    addArithmetic add operations multiplier.210
    mulMul operations multiplier.240
    divDiv operations multiplier.320
    loadMemory load operation multiplier.2_500
    storeMemory store operation multiplier.4_700
    constConst store operation multiplier.110
    localLocal operations multiplier.390
    globalGlobal operations multiplier.390
    integer_comparisonInteger operations multiplier.250
    conversionConversion operations multiplier.420
    unreachableUnreachable operation multiplier.270
    nopNop operation multiplier.200
    current_memoryGet the current memory operation multiplier.290
    grow_memoryGrow memory cost per page (64 kB).240_000

    Control Flow Operation Costs

    @@ -194,7 +194,7 @@

    AttributeDescriptionCostblockCost for block opcode.440loopCost for loop opcode.440ifCost for if opcode.440elseCost for else opcode.440endCost for end opcode.440brCost for br opcode.35_000br_ifCost for br_if opcode.35,000returnCost for return opcode.440selectCost for select opcode.440callCost for call opcode.68_000call_indirectCost for call_indirect opcode.68,000dropCost for drop opcode.440 +
    AttributeDescriptionCost
    blockCost for block opcode.440
    loopCost for loop opcode.440
    ifCost for if opcode.440
    elseCost for else opcode.440
    endCost for end opcode.440
    brCost for br opcode.35_000
    br_ifCost for br_if opcode.35_000
    returnCost for return opcode.440
    selectCost for select opcode.440
    callCost for call opcode.68_000
    call_indirectCost for call_indirect opcode.68_000
    dropCost for drop opcode.440

    Br_Table OpCode Costs

    @@ -216,7 +216,7 @@

    -
    AttributeDescriptionCost
    costFixed cost per br_table opcode.35,000
    size_multiplierSize of target labels in the br_table opcode will be multiplied by size_multiplier.100
    +
    AttributeDescriptionCost
    costFixed cost per br_table opcode.35_000
    size_multiplierSize of target labels in the br_table opcode will be multiplied by size_multiplier.100

    External Function Costs

    The following costs are for low-level bindings for host-side ("external") functions. More information on the Casper external FFI can be found here.

    @@ -444,8 +444,6 @@

    Exte -
    Host-Side FunctionCostArguments
    add5,800[0, 0, 0, 0]
    add_associated_key9,000[0, 0, 0]
    add_contract_version200[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    blake2b200[0, 0, 0, 0]
    call_contract4,500[0, 0, 0, 0, 0, 420, 0]
    call_versioned_contract4,500[0, 0, 0, 0, 0, 0, 0, 420, 0]
    create_contract_package_at_hash200[0, 0]
    create_contract_user_group200[0, 0, 0, 0, 0, 0, 0, 0]
    create_purse2,500,000,000[0, 0]
    disable_contract_version200[0, 0, 0, 0]
    get_balance3,800[0, 0, 0]
    get_blocktime330[0]
    get_caller380[0]
    get_key2,000[0, 440, 0, 0, 0]
    get_main_purse1,300[0]
    get_named_arg200[0, 0, 0, 0]
    get_named_arg_size200[0, 0, 0]
    get_phase710[0]
    get_system_contract1,100[0, 0, 0]
    has_key1,500[0, 840]
    is_valid_uref760[0, 0]
    load_named_keys42,000[0, 0]
    new_uref17,000[0, 0, 590]
    random_bytes200[0, 0]
    print20,000[0, 4,600]
    provision_contract_user_group_uref200[0, 0, 0, 0, 0]
    put_key38,000[0, 1,100, 0, 0]
    read_host_buffer3,500[0, 310, 0]
    read_value6,000[0, 0, 0]
    read_value_local5,500[0, 590, 0]
    remove_associated_key4,200[0, 0]
    remove_contract_user_group200[0, 0, 0, 0]
    remove_contract_user_group_urefs200[0, 0, 0, 0, 0, 0]
    remove_key61,000[0, 3,200]
    ret23,000[0, 420,000]
    revert500[0]
    set_action_threshold74,000[0, 0]
    transfer_from_purse_to_account2,500,000,000[0, 0, 0, 0, 0, 0, 0, 0, 0]
    transfer_from_purse_to_purse82,000[0, 0, 0, 0, 0, 0, 0, 0]
    transfer_to_account2,500,000,000[0, 0, 0, 0, 0, 0, 0]
    update_associated_key4,200[0, 0, 0]
    write14,000[0, 0, 0, 980]
    write_local9,500[0, 1,800, 0, 520]
    -

    Protocol Operating Costs

    @@ -461,7 +459,12 @@

    Pro -
    AttributeDescriptionCost
    wasmless_transfer_costDefault gas cost for a wasmless transfer.100,000,000
    + + + + + +
    Host-Side FunctionCostArguments
    add5_800[0, 0, 0, 0]
    add_associated_key1_200_000[0, 0, 0]
    add_contract_version200[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]
    blake2b1_200_000[0, 120_000, 0, 0]
    call_contract300_000_000[0, 0, 0, 120_000, 0, 120_000, 0]
    call_versioned_contract300_000_000[0, 0, 0, 0, 120_000, 0, 120_000, 0]
    create_contract_package_at_hash200[0, 0]
    create_contract_user_group200[0, 0, 0, 0, 0, 0, 0, 0]
    create_purse2_500_000_000[0, 0]
    disable_contract_version200[0, 0, 0, 0]
    get_balance3_000_000[0, 0, 0]
    get_blocktime330[0]
    get_caller380[0]
    get_key2_000[0, 440, 0, 0, 0]
    get_main_purse1_300[0]
    get_named_arg200[0, 120_000, 0, 120_000]
    get_named_arg_size200[0, 0, 0]
    get_phase710[0]
    get_system_contract1_100[0, 0, 0]
    has_key1_500[0, 840]
    is_valid_uref760[0, 0]
    load_named_keys42_000[0, 0]
    new_uref17_000[0, 0, 590]
    random_bytes200[0, 0]
    print20_000[0, 4_600]
    provision_contract_user_group_uref200[0, 0, 0, 0, 0]
    put_key100_000_000[0, 120_000, 0, 120_000]
    read_host_buffer3_500[0, 310, 0]
    read_value60_000[0, 120_000, 0]
    read_value_local5_500[0, 590, 0]
    remove_associated_key4_200[0, 0]
    remove_contract_user_group200[0, 0, 0, 0]
    remove_contract_user_group_urefs200[0, 0, 0, 0, 0, 120_000]
    remove_key61_000[0, 3_200]
    ret23_000[0, 420_000]
    revert500[0]
    set_action_threshold74_000[0, 0]
    transfer_from_purse_to_account2_500_000_000[0, 0, 0, 0, 0, 0, 0, 0, 0]
    transfer_from_purse_to_purse82_000_000[0, 0, 0, 0, 0, 0, 0, 0]
    transfer_to_account2_500_000_000[0, 0, 0, 0, 0, 0, 0]
    update_associated_key4_200[0, 0, 0]
    write14_000[0, 0, 0, 980]
    dictionary_put9_500[0, 1_800, 0, 520]
    enable_contract_version200[0, 0, 0, 0]
    manage_message_topic200[0, 30_000, 0, 0]
    emit_message200[0, 30_000, 0, 120_000]
    cost_increase_per_message50

    Auction System Contract Costs

    These are the costs of calling auction system contract entrypoints.

    @@ -544,7 +547,12 @@

    Mint System Contract Costs

    These are the costs of calling mint system contract entrypoints.

    @@ -592,7 +600,12 @@

    < -
    EntrypointDescriptionCost
    mintCost of calling the mint entrypoint.2,500,000,000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10,000
    createCost of calling the create entrypoint.2,500,000,000
    balanceCost of calling the balance entrypoint.10,000
    transferCost of calling the transfer entrypoint.10,000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10,000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2,500,000,000
    + + + + + +
    EntrypointDescriptionCost
    mintCost of calling the mint entrypoint.2_500_000_000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10_000
    createCost of calling the create entrypoint.2_500_000_000
    balanceCost of calling the balance entrypoint.10_000
    burnCost of calling the burn entrypoint.10_000
    transferCost of calling the transfer entrypoint.10_000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10_000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2_500_000_000

    Handle_Payment System Contract Costs

    These are the costs of calling entrypoints on the handle_payment system contract.

    @@ -625,7 +638,7 @@

    Standard_Payment System Contract Costs

    These settings manage the costs of calling entrypoints on the standard_payment system contract.

    @@ -643,6 +656,6 @@

    +
    EntrypointDescriptionCost
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10_000
    \ No newline at end of file diff --git a/developers/cli/querying-global-state/index.html b/developers/cli/querying-global-state/index.html index b7f9067cf..5e288d439 100644 --- a/developers/cli/querying-global-state/index.html +++ b/developers/cli/querying-global-state/index.html @@ -1,90 +1,170 @@ - + -Querying Global State | Casper Docs - Redux +Querying Global State | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Querying Global State

    -

    This page explains how to query global state after contract installation.

    + submit an issue on Github
    Version: Next

    Querying Global State

    +

    This page explains how to query global state to find account, contract, and package details.

    Prerequisites

    Getting the State Root Hash

    -

    The first step in querying the global state is obtaining the state root hash. The state root hash acts as an identifier for the current state of the network (global state). It is like a Git commit ID for commit history, and it provides a snapshot of the blockchain state at a specific point in time.

    -
    note

    After sending deploys to the network, it's necessary to fetch the new state root hash in order to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state.

    +

    The first step in querying global state is obtaining the state root hash, which acts as an identifier for the current state of the network. It is like a Git commit ID for commit history, providing a snapshot of the blockchain state at a specific time.

    +
    note

    After sending transactions to the network, it's necessary to fetch the new state root hash to see the changes reflected in the global state. Without doing this, you would be querying past versions of the state.

    To get the state root hash, use the get-state-root-hash command:

    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]
    -

    Sending the Query

    -

    Next, query the state of a Casper network at a given time, specified by the state-root-hash described above. You can dive into the data stored in global state using the optional query path argument -q.

    -
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [HASH_STRING] \
    -q "[SESSION_NAME]/[SESSION_NAMED_KEY]"
    -

    The arguments used above are:

    +

    Sample request:

    +
    casper-client get-state-root-hash --node-address http://localhost:11101
    +

    Sample response:

    +
    {
    "jsonrpc": "2.0",
    "id": -4225403855447288375,
    "result": {
    "api_version": "2.0.0",
    "state_root_hash": "6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81"
    }
    }
    +

    Querying an Account

    +

    To find your account details, start by querying global state using the account hash. The response will contain the entity account identifier, needed to query more details about the account. You will need the following information:

      -
    • node-address - An IP address of a peer on the network. The default port for JSON-RPC servers on Mainnet and Testnet is 7777
    • -
    • state-root-hash - Hex-encoded hash of the state root
    • -
    • key - The identifier for the query. This must be one of the following: public key, account hash, contract package hash, transfer hash, or deploy hash
    • -
    • q - An optional query path argument that allows you to drill into the specifics of a query with respect to the key
    • +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The state root hash, as a hex-encoded hash of the state root.

      +
    • +
    • +

      A key identifier for the query, which in this case would be the account hash.

      +
    -

    Query the account

    -

    To find your account details, query global state using your account hash.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d
    -

    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
    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]
    +

    Sample request:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \
    --key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463
    +

    Sample response:

    +
    {
    "jsonrpc": "2.0",
    "id": 2591514718461273084,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "CLValue": {
    "cl_type": "Key",
    "bytes": "11016a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "parsed": "entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"
    }
    },
    "merkle_proof": "[2566 hex chars]"
    }
    }
    +

    Next, see more account details using the get-entity command and the entity identifier or the account hash. Both commands will produce the same output. You will need the following information:

    +
      +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The identifier for an addressable entity or an account. This can be an entity hash, a public key, or an account hash.

      +
    • +
    +
    casper-client get-entity \
    --node-address [NODE_SERVER_ADDRESS] \
    --entity-identifier [FORMATTED_STRING_OR_PATH]
    +

    Sample requests:

    +
    casper-client get-entity \
    --node-address http://localhost:11101 \
    --entity-identifier entity-account-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463
    +

    OR

    +
    casper-client get-entity \
    --node-address http://localhost:11101 \
    --entity-identifier account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463
    +

    Sample response:

    +

    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.

    +
    Expand to see the sample response
    -
    {
    "id": -6831525034388467034,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[27614 hex chars]",
    "stored_value": {
    "Account": {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "action_thresholds": {
    "deployment": 1,
    "key_management": 1
    },
    "associated_keys": [
    {
    "account_hash": "account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d",
    "weight": 1
    }
    ],
    "main_purse": "uref-d92e420120199f90005802bf3036362f368ab69bebf17e7e53856d6ac82e117f-007",
    "named_keys": [
    {
    "key": "hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "name": "counter"
    },
    {
    "key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "name": "counter_access_uref"
    },
    {
    "key": "hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "name": "counter_package_name"
    },
    {
    "key": "uref-917762490591a1404cba59ed8dcf0bcfa7f644ef6c6be9bf5ea7b1641617cad0-007",
    "name": "version"
    }
    ]
    }
    }
    }
    }
    +
    {
    "jsonrpc": "2.0",
    "id": 4470312592511523509,
    "result": {
    "api_version": "2.0.0",
    "entity": {
    "AddressableEntity": {
    "entity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "Account": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"
    },
    "package_hash": "package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51",
    "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",
    "main_purse": "uref-21dc8fc358c4e30ae29786bd4842a5f99da83efa0b9ca8461cd2196ffbfd07f1-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    },
    "named_keys": [
    {
    "name": "counter",
    "key": "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    },
    {
    "name": "counter_access_uref",
    "key": "uref-29feb2af8a9d7b6d2ef6be875a0aa326b646a00b7cdd2dd4a65365e84e9f2e9a-007"
    },
    {
    "name": "counter_package_name",
    "key": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94"
    },
    {
    "name": "version",
    "key": "uref-7bc25880db57763fccfa858185becd8de40a890d9e006e067352f011bdcf03bf-007"
    }
    ],
    "entry_points": []
    }
    },
    "merkle_proof": "[3010 hex chars]"
    }
    }
    -

    -
    tip

    If you don't know your account hash, you can run this command:

    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    -

    Query the contract

    -

    This example shows how to query global state given a contract hash. We use the contract hash from the sample response above.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key hash-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e
    -

    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
    +



    +
    tip

    If you don't know your account hash, run this command:

    casper-client account-address --public-key [PATH_TO_PUBLIC_KEY]
    +

    Querying a Contract

    +

    Query global state given the contract identifier and the query-global-state command. The contract is stored under the account's named keys, with the key named "counter" and identifier entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68. The output will contain the contract's package_hash, main_purse, associated_keys, and action_thresholds, but will not contain further details such as the contract's named keys and entry points. You will need to run the get-entity command instead for those details.

    +

    For the query-global-state command, you will need the following information:

    +
      +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The state root hash, as a hex-encoded hash of the state root.

      +
    • +
    • +

      A key identifier for the query, which in this case would be the contract address hash.

      +
    • +
    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_ADDRESS_HASH]
    +

    Sample request:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \
    --key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68"
    +

    Sample response:

    +
    Expand to see the sample response
    -
    {
    "id": -4657473054587773855,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[21330 hex chars]",
    "stored_value": {
    "Contract": {
    "contract_package_hash": "contract-package-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e",
    "contract_wasm_hash": "contract-wasm-576b1718711d524a79ab2f05ce801006a3fd32eb48b9f7dac69a9fa966d634e3",
    "entry_points": [
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_get",
    "ret": "I32"
    },
    {
    "access": "Public",
    "args": [],
    "entry_point_type": "Contract",
    "name": "counter_inc",
    "ret": "Unit"
    }
    ],
    "named_keys": [
    {
    "key": "uref-d40613e50c7b405b02795e3fe3252554bef49b4b522e31a55f39b87c442f922a-007",
    "name": "count"
    }
    ],
    "protocol_version": "1.4.5"
    }
    }
    }
    }

    +
    {
    "jsonrpc": "2.0",
    "id": -750547909804067196,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    },
    "merkle_proof": "[1508 hex chars]"
    }
    }
    -

    -

    Query a value using its key and the contract hash

    -

    Next, you can query a named key associated with the contract using the -q option. This example comes from the Counter Contract Tutorial, where a "count" variable is incremented and stored under a named key.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_HASH] \
    -q "count"
    -
    Sample stored value
    +

    Next, query global state given the contract identifier and the get-entity command, which will provide more details such as the contract's entry_points and named_keys. You will need the following information:

    +
      +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The entity identifier for an addressable entity or an account. This can be an entity hash, a public key, or an account hash.

      +
    • +
    +
    casper-client get-entity \
    --node-address [NODE_SERVER_ADDRESS] \
    --entity-identifier [FORMATTED_STRING_OR_PATH]
    +

    Sample request:

    +
    casper-client get-entity \
    --node-address http://localhost:11101 \
    --entity-identifier entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68
    +

    Sample response:

    +
    Expand to see the sample response
    -
    {
    "id": -2540117660598287261,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[56562 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "00000000",
    "cl_type": "I32",
    "parsed": 0
    }
    }
    }
    }
    +
    {
    "jsonrpc": "2.0",
    "id": -530362264865678930,
    "result": {
    "api_version": "2.0.0",
    "entity": {
    "AddressableEntity": {
    "entity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-50d487af45f8cec533c6813801a7630ff97e5ee3964daf7915d5451b4812ac94",
    "byte_code_hash": "byte-code-0577a7c92fd20e1af76aa9e257631cb240e8187191bba2025e88663d0288e936",
    "main_purse": "uref-2cb7e46fcde2c4d395a6850bb3b7edbb0b4db6018643e535fa0dfdeeb006d6ef-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    },
    "named_keys": [
    {
    "name": "count",
    "key": "uref-65f3f583bf1ac01b6c90d9c9478bd239c09e46f48fb693918726eaab03631407-007"
    }
    ],
    "entry_points": [
    {
    "V1CasperVm": {
    "name": "counter_get",
    "args": [],
    "ret": "I32",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    },
    {
    "V1CasperVm": {
    "name": "counter_inc",
    "args": [],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    ]
    }
    },
    "merkle_proof": "[1508 hex chars]"
    }
    }
    -

    -

    Query a value using the account hash and named keys

    -

    It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash fa968344a2000282686303f1664c474465f9a028f32ec4f51791d9fa64c0bcd7 \
    --key account-hash-1d17e3fdad268f866a73558d1ae45e1eea3924c247871cb63f67ebf1a116e66d \
    -q "counter/count"
    -

    The response should be the same as in Example 3, above.

    -

    Query contract package state

    -

    You can query information about a contract package, such as the latest contract hash and contract version, given its contract package hash.

    -
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --key hash-76a8c3daa6d6ac799ce9f46d82ac98efb271d2d64b517861ec89a06051ef019e \
    --state-root-hash 763e737cf55a298d54bcdfb4ee55526538a1a086128914b9cc25ccbdebbbb966
    -

    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 in the next section. You would also see the access_key for the ContractPackage and the current contract_version.

    -
    Sample contract package state
    +

    Querying a Package

    +

    You can query information about a package, given its package hash. You will need the following information:

    +
      +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The state root hash, as a hex-encoded hash of the state root.

      +
    • +
    • +

      A key identifier for the query, which in this case would be the package identifier.

      +
    • +
    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [PACKAGE_ADDRESS]
    +

    Sample request:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \
    --key package-1bf60faed9931e95e99912aa82f545a85f374dcbcd0c145ee2a5820b39b31d51
    +

    Sample response:

    +

    The response would contain the addressable_entity_hash, the lock_status for the Package, and the current entity_version.

    +
    Expand to see the sample response
    -
    {
    "id": -6225901853092301031,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.5",
    "block_header": null,
    "merkle_proof": "[20964 hex chars]",
    "stored_value": {
    "ContractPackage": {
    "access_key": "uref-41c3f4ae3c1ce2446f6fd880a96e698ae5abc715151e45e357d88bb739489c03-007",
    "disabled_versions": [],
    "groups": [],
    "versions": [
    {
    "contract_hash": "contract-22228188b85b6ee4a4a41c7e98225c3918139e9a5eb4b865711f2e409d85e88e",
    "contract_version": 1,
    "protocol_version_major": 1
    }
    ]
    }
    }
    }
    }
    +
    {
    "jsonrpc": "2.0",
    "id": -8280509649720542989,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    },
    "merkle_proof": "[2934 hex chars]"
    }
    }
    -

    -

    Video Walkthrough

    -

    This video shows you what to expect when querying the network.

    -

    - -

    +

    Querying a Named Key

    +

    You can dive into the data stored in global state using the optional query path argument -q or --query-path. You will need the following information:

    +
      +
    • +

      The node address, representing an IP address of a peer on the network.

      +
    • +
    • +

      The state root hash, as a hex-encoded hash of the state root.

      +
    • +
    • +

      A key identifier for the query. This must be a properly formatted public key, account hash, contract address hash, URef, transfer hash, deploy-info hash,era-info number, bid, withdraw or dictionary address.

      +
    • +
    • +

      The query path, entered in this instance as q, which is an optional query path argument that allows you to drill into the specifics of a query with respect to the key.

      +
    • +
    +
    casper-client query-global-state \
    --node-address [NODE_SERVER_ADDRESS] \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [HASH_STRING] \
    -q "PATH_FROM_KEY"
    +

    Query a value using the contract address hash and its named key

    +

    Next, you can query a named key associated with the contract using the query-global-state command and the -q option.

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [CONTRACT_ADDRESS_HASH] \
    -q "count"
    +

    Sample request:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \
    --key "entity-contract-a1d0bf9d96f3efc9ea67f627df3a7cba390bfc582956032db91060ca5d413e68" \
    -q "count"
    +

    Sample response:

    +
    {
    "jsonrpc": "2.0",
    "id": -672620332620630019,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "CLValue": {
    "cl_type": "I32",
    "bytes": "00000000",
    "parsed": 0
    }
    },
    "merkle_proof": "[7272 hex chars]"
    }
    }
    +

    Query a value using the account hash and its named key

    +

    It is also possible to check the state of a specific contract variable in global state given the account hash under which the contract was installed. Here we query the named key "count", stored under another key identifying the contract and named "counter".

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH] \
    -q "counter/count"
    +

    Sample request:

    +
    casper-client query-global-state \
    --node-address http://localhost:11101 \
    --state-root-hash 6b5849caa605acdc29564f303764396a27ef7a6b1a61f7b13109b129e7e70d81 \
    --key account-hash-6a56c4eee172043975aea72221eaf09f3c3a24f09a379935e44c9979f1ae9463 \
    -q "counter/count"
    +

    Sample response:

    +
    {
    "jsonrpc": "2.0",
    "id": -8997536139716357387,
    "result": {
    "api_version": "2.0.0",
    "block_header": null,
    "stored_value": {
    "CLValue": {
    "cl_type": "I32",
    "bytes": "00000000",
    "parsed": 0
    }
    },
    "merkle_proof": "[14486 hex chars]"
    }
    }

    What's Next?

    +
  • Learn different ways to call contracts using the Casper command-line client.
  • +
    \ No newline at end of file diff --git a/developers/cli/redelegate/index.html b/developers/cli/redelegate/index.html index 3f96d7938..6181d04e0 100644 --- a/developers/cli/redelegate/index.html +++ b/developers/cli/redelegate/index.html @@ -1,21 +1,21 @@ - + -Redelegating Tokens with the Casper Client | Casper Docs - Redux +Redelegating Tokens with the Casper Client | Casper Docs - Redux - - + +
    Version: Next

    Redelegating Tokens with the Casper Client

    This document details a workflow where tokens staked with a validator can be redelegated to another validator with a single call while the unbonding process runs in the background. Otherwise, delegators would have to complete two steps by sending an unbonding request first and then delegate the tokens to the new validator.

    Prerequisites

      @@ -81,6 +81,6 @@

      Verifying the Redelegation

      The redelegation process includes an unbonding delay before the tokens are redelegated to a new validator. In contrast, initial delegation occurs when a Casper network finalizes the associated Deploy.

      Due to this delay, the new validator may become inactive before the redelegation completes. If this happens, the tokens will be returned to the delegator.

      -

      Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as verifying a delegation request using the casper-client get-auction-info command.

    +

    Once the redelegation Deploy has been processed, you can query the auction to confirm the redelegation. This process is the same as verifying a delegation request using the casper-client get-auction-info command.

    \ No newline at end of file diff --git a/next/developers/cli/sending-transactions/index.html b/developers/cli/sending-transactions/index.html similarity index 91% rename from next/developers/cli/sending-transactions/index.html rename to developers/cli/sending-transactions/index.html index ca9448b2d..380162c32 100644 --- a/next/developers/cli/sending-transactions/index.html +++ b/developers/cli/sending-transactions/index.html @@ -3,38 +3,38 @@ -Sending Transactions | Casper Docs - Redux +Sending Transactions | Casper Docs - Redux - - + +
    Version: Next

    Sending Transactions using the Casper Client

    -

    To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:

    + submit an issue on Github
    Version: Next

    Sending Transactions using the Casper Client

    +

    To install smart contracts on the blockchain, you can send your Wasm to the network via a Transaction. To do this, you will need to meet a few prerequisites:

      -
    • You will need a client to interact with the network, such as the default Casper client
    • -
    • Ensure you have an Account and its associated keys This account will pay for the Transaction, and its secret key will sign the Transaction
    • +
    • You will need a client to interact with the network, such as the default Casper client
    • +
    • Ensure you have an Account and its associated keys This account will pay for the Transaction, and its secret key will sign the Transaction
    • Ensure this account has enough CSPR tokens to pay for the Transaction

    Paying for Transactions

    CSPR tokens are used to pay for transactions on the Casper Mainnet and Testnet. There are several ways to fund your account:

    Monitoring the Event Stream for Transactions

    -

    If you want to follow the lifecycle of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described here. You need the following information to proceed:

    +

    If you want to follow the lifecycle of the Transaction, you can start monitoring a node's event stream. This section will focus only on TransactionAccepted events, but there are other event types described here. You need the following information to proceed:

      -
    • The IP address of a peer on the network
    • +
    • The IP address of a peer on the network
    • The port specified as the event_stream_server.address in the node's config.toml, which is by default 9999 on Mainnet and Testnet
    • The URL for streamed events, which is HOST:PORT/events
    @@ -93,7 +93,7 @@

    casper-client put-txn session --help

    Advanced Features

    -

    Casper networks support complex transactions using multiple signatures. Casper Accounts use a powerful permissions model that enables a multi-signature scheme for transactions.

    +

    Casper networks support complex transactions using multiple signatures. Casper Accounts use a powerful permissions model that enables a multi-signature scheme for transactions.

    The put-transaction command performs multiple actions under the hood, optimizing the typical use case. It creates a transaction, signs it, and sends the Transaction to the network without allowing multiple signatures. However, it is possible to call the following three commands and separate key management from account creation:

    • make-transaction - Creates a Transaction and outputs it to a file or stdout. As a file, the transaction can subsequently be signed by other parties using the sign-transaction subcommand and then sent to the network for execution using the send-transaction subcommand
    • @@ -101,14 +101,14 @@

      Advanced F
    • send-transaction - Reads a previously-saved Transaction from a file and sends it to the network for execution

    To sign a Transaction with multiple keys, create the Transaction with the make-transaction command. The generated transaction file can be sent to the other signers, who then sign it with their keys by calling the sign-transaction for each key. Signatures need to be gathered on the Transaction one after another until all required parties have signed the Transaction. Finally, the signed Transaction is sent to the network with the send-transaction command for processing.

    -

    For a step-by-step workflow, visit the Two-Party Multi-Signature Transaction guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network.

    +

    For a step-by-step workflow, visit the Two-Party Multi-Signature Transaction guide. This workflow describes how a trivial two-party multi-signature scheme for signing and sending transactions can be enforced for an account on a Casper network.

    Gas Cost for Transactions

    A common question frequently arises: "How do I know what the payment amount (gas cost) should be?"

    We recommend installing your contracts in a test environment, making sure the cost tables match those of the production Casper network to which you want to send the transaction. If you plan on sending a transaction to Mainnet, you can use the Testnet to estimate the payment amount needed for the transaction.

    -
    note

    Casper's "Condor" release introduces a new payment system that includes the concept of fee elimination.

    -

    If your test configuration matches your production chainspec, you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the runtime economics section for more details about gas usage and fees.

    -

    Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    -

    If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the failed execution.

    +
    note

    Casper's "Condor" release introduces a new payment system that includes the concept of fee elimination.

    +

    If your test configuration matches your production chainspec, you can check the transaction status and roughly see how much it would cost. You can estimate the costs in this way and then add a small buffer to be sure. Refer to the runtime economics section for more details about gas usage and fees.

    +

    Please be aware that sending a transaction always requires payment. This is true regardless of the validity of included Wasm. Depending on how the network was configured, the transaction payment may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    +

    If the transaction failure occurs after session execution begins, the penalty payment of 2.5 CSPR is included in the gas costs of the failed execution.

    However, if the failure occurs prior to session execution, the penalty payment will not appear in the transaction's gas cost. Depending on the network configuration, the system will deduct the processing fee from the sending account's main purse or place a processing hold on the purse.

    Out of gas error

    @@ -123,6 +123,6 @@

    Out of gas

    Gas limit error

    You may sometimes see an error such as "payment: 2.5, cost: 2.5, Error::GasLimit". This message seems to say that the transaction cost is 2.5 CSPR and you paid 2.5 CSPR, yet the transaction resulted in an error.

    This error message tries to communicate that execution stopped at 2.5 CSPR, and the transaction did not run to completion. In other words, the computation resulted in an error because there were insufficient funds for the transaction to run to completion. It would have cost more than 2.5 CSPR to complete execution, but since you only supplied a payment of 2.5 CSPR worth of computation, the network stopped execution and charged that much, resulting in a failed transaction. The execution engine does not know how much it would have cost if allowed to run to completion because it did not allow the transaction to finish since it would have run over its gas limit.

    -

    In summary, when a transaction hits its gas limit (the payment amount), execution stops.

    +

    In summary, when a transaction hits its gas limit (the payment amount), execution stops.

    \ No newline at end of file diff --git a/developers/cli/transfers/direct-token-transfer/index.html b/developers/cli/transfers/direct-token-transfer/index.html index f6a921595..849a88406 100644 --- a/developers/cli/transfers/direct-token-transfer/index.html +++ b/developers/cli/transfers/direct-token-transfer/index.html @@ -1,21 +1,21 @@ - + -Direct Token Transfer | Casper Docs - Redux +Direct Token Transfer | Casper Docs - Redux - - + +
    Version: Next

    Direct Token Transfer

    This workflow describes how to use the Casper command-line client to transfer tokens between purses on a Casper network.

    Prerequisites

    This workflow assumes:

    @@ -36,13 +36,13 @@

    Direct Transfer Exa

    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

    +

    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:<http://localhost:7777\>\]

    +

    node-address - Hostname or IP and port of a node on a network bound to a JSON-RPC endpoint default:http://localhost:7777

  • -

    amount -512-BIT INTEGER The number of motes to transfer (1 CSPR = 1,000,000,000 Motes)

    +

    amount -<512-BIT INTEGER> The number of motes to transfer (1 CSPR = 1,000,000,000 Motes)

  • secret-key - Path to secret key file

    @@ -77,7 +77,7 @@

    Direct Transfer Exa

  • Verifying the Deploy

    A transfer on a Casper network is only executed after it has been included in a finalized block.

    -
    casper-client get-deploy 
    --node-address [NODE_SERVER_ADDRESS] [DEPLOY_HASH]
    +
    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
    • @@ -85,7 +85,7 @@

      Verifying the

    note

    Transfer addresses use a transfer- string prefix.

    Example Query:

    -
    casper-client get-deploy 
    --node-address https://rpc.testnet.casperlabs.io
    1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c
    +
    casper-client get-deploy \
    --node-address https://rpc.testnet.casperlabs.io
    1f17a0bdeaaf71abd03492c854cdf97f746432751721ce555e95b9cefe641e3c
    Explore the JSON-RPC request and response generated.

    JSON-RPC Request:

    @@ -95,6 +95,6 @@

    Verifying the

    Refer to the Section on querying deploys for more information.

    Verifying the Transfer

    -

    In addition to verifying the deploy, you also need to verify the transfer details. The deploy may have been successful, but you also need to ensure the source and target accounts were updated correctly.

    +

    In addition to verifying the deploy, you also need to verify the transfer details. 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 diff --git a/developers/cli/transfers/index.html b/developers/cli/transfers/index.html index 71b4926cb..c2970e69f 100644 --- a/developers/cli/transfers/index.html +++ b/developers/cli/transfers/index.html @@ -1,27 +1,27 @@ - + -Transferring Tokens | Casper Docs - Redux +Transferring Tokens | Casper Docs - Redux - - + +
    Version: 1.5.X

    Transferring Tokens with the Casper CLI Client

    -

    The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) deploy transfer can be utilized.

    + submit an issue on Github
    Version: Next

    Transferring Tokens with the Casper CLI Client

    +

    The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.

    Transferring tokens using a direct transfer

    Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see Transferring Tokens Using Direct Transfer.

    -

    Transferring tokens using a multi-sig deploy

    -

    Multi-sig deploy transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the deploy. To set up the account's associated keys, see the Two-Party Multi-Signature Deploys workflow. To use a multi-sig deploy transfer, see Transferring Tokens Using a Multi-sig Account.

    +

    Transferring tokens using a multi-sig tranasction

    +

    Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the Two-Party Multi-Signature transactions workflow. To use a multi-sig transaction transfer, see Transferring Tokens Using a Multi-sig Account.

    Verifying a transfer using the command-line client

    -

    To verify the status of a transfer, see Verifying a Transfer.

    +

    To verify the status of a transfer, see Verifying a Transfer.

    \ No newline at end of file diff --git a/developers/cli/transfers/multisig-deploy-transfer/index.html b/developers/cli/transfers/multisig-deploy-transfer/index.html index 79475af25..2f0d46199 100644 --- a/developers/cli/transfers/multisig-deploy-transfer/index.html +++ b/developers/cli/transfers/multisig-deploy-transfer/index.html @@ -1,21 +1,21 @@ - + -Transferring Tokens using a Multi-Sig Deploy | Casper Docs - Redux +Transferring Tokens using a Multi-Sig Deploy | Casper Docs - Redux - - + +
    Version: Next

    Transferring Tokens using a Multi-Sig Deploy

    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

    @@ -39,7 +39,7 @@

    Toke
  • The sign-deploy command adds additional signatures for a multi-signature transfer
  • The send-deploy command sends the deploy containing the transfer to the network
  • -

    +

    Deployment flow

    Creating the transfer

    This section explains the make-transfer command using an example you can try on the Testnet. For this example, we are transferring 2,500,000,000 motes from the source account (with the secret_key.pem file) to a target account. To use this example on the Mainnet, the chain-name would be casper instead of casper-test. Note that we are saving the output of the make-transfer command in a transfer.deploy file.

    casper-client make-transfer --amount 2500000000 \
    --secret-key [PATH]/secret_key.pem \
    --chain-name casper-test \
    --target-account [PUBLIC_KEY_HEX] \
    --transfer-id [ID] \
    --payment-amount 100000000 \
    --output transfer.deploy
    @@ -117,7 +117,7 @@

    Signing
    {
    "hash": "88c49fa9108485397a330f294914a6c2d614c581fbe0a31de1a954baad6d709b",
    "header": {
    "account": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "timestamp": "2023-10-12T19:14:22.080Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "1bb7436d4703816b5cbeef245dd83c0520f1c7173cdf609c664a29487cc5de1c",
    "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": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf",
    "parsed": "0154d828baafa6858b92919c4d78f26747430dcbecb9aa03e8b44077dc6266cabf"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010100000000000000",
    "parsed": 1
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01360af61b50cdcb7b92cffe2c99315d413d34ef77fadee0c105cc4f1d4120f986",
    "signature": "015e0db50b174f3627e0e27cb503f0836b30bd0e0f2c4b989366b0df57500a1cb2b0945408c938bc3c33c40dab59a9c6af6f4e01e474330cd27262bfc87680030e"
    },
    {
    "signer": "01e3d3392c2e0b943abe709b25de5c353e5e1e9d95c7a76e3dd343d8aa1aa08d51",
    "signature": "017793ad52d27393b1aa8ff5bb9bdbcb48708910d6cdabd9a89b44690ca174edf8924aad340bf901ac343391cb4cba7cf4db07390372f28ecf471fd522e0b63803"
    }
    ]
    }

    -

    Sending the deploy

    +

    Sending the deploy

    The next step is to send the deploy for processing on the network. As described in the 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.

    casper-client send-deploy \
    --input transfer2.deploy \
    --node-address https://rpc.testnet.casperlabs.io/
    @@ -150,6 +150,6 @@

    Sending t

    Verifying the transfer

    To verify the transfer status, see Verifying a Transfer.

    -
    tip

    You can also verify if the transfer was successful by checking your account balance using a block explorer.

    +
    tip

    You can also verify if the transfer was successful by checking your account balance using a block explorer.

    \ No newline at end of file diff --git a/developers/cli/transfers/verify-transfer/index.html b/developers/cli/transfers/verify-transfer/index.html index d89319bc7..3885aac04 100644 --- a/developers/cli/transfers/verify-transfer/index.html +++ b/developers/cli/transfers/verify-transfer/index.html @@ -1,21 +1,21 @@ - + -Verifying a Transfer | Casper Docs - Redux +Verifying a Transfer | Casper Docs - Redux - - + +
    Version: Next

    Verifying a Transfer

    Prerequisites

    Before verifying a transfer, make sure you have:

      @@ -35,9 +35,9 @@

      Qu
      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

      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.

      -

      +

      Transfer hash

      First, use the get-deploy command and the deploy_hash to identify the corresponding transfer:

      -
      casper-client get-deploy \
      --node-address [NODE_SERVER_ADDRESS] \
      [DEPLOY_HASH]
      +
      casper-client get-deploy \
      --node-address [NODE_SERVER_ADDRESS] \
      [DEPLOY_HASH]

      Important response fields:

      • "result"."execution_results"."result"."Success"."transfers" - List of transfers contained in a successful deploy
      • @@ -126,6 +126,6 @@

        Query the
        {
        "jsonrpc": "2.0",
        "method": "query_balance",
        "params": {
        "state_identifier": {
        "StateRootHash": "fdb1474d441ec0fcbf2e088f1630dbf98d3bcf7f7a7fe298303797f35b8cb4e1"
        },
        "purse_identifier": {
        "main_purse_under_account_hash": "account-hash-1ed5a1c39bea93c105f2d22c965a84b205b36734a377d05dbb103b6bfaa595a7"
        }
        },
        "id": 7
        }

        JSON-RPC Response:

        {
        "jsonrpc": "2.0",
        "result": {
        "api_version": "1.5.3",
        "balance": "46200000000"
        },
        "id": 7
        }
        -

    +
    \ No newline at end of file diff --git a/developers/cli/undelegate/index.html b/developers/cli/undelegate/index.html index 01df2baf1..2d2a7cc51 100644 --- a/developers/cli/undelegate/index.html +++ b/developers/cli/undelegate/index.html @@ -1,21 +1,21 @@ - + -Undelegating Tokens | Casper Docs - Redux +Undelegating Tokens | Casper Docs - Redux - - + +
    Version: Next

    Undelegating Tokens with the Casper Client

    This document details a workflow where tokens delegated to a validator on a Casper network can be undelegated.

    Prerequisites

      @@ -90,6 +90,6 @@

      V
    1. Testnet explorer
    2. Mainnet explorer
    -

    Important Note: After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator.

    +

    Important Note: After undelegating tokens from a validator, you must wait for the unbonding period to lapse before redelegating tokens to either the same validator or a different validator.

    \ No newline at end of file diff --git a/developers/cli/verifying-contracts/index.html b/developers/cli/verifying-contracts/index.html new file mode 100644 index 000000000..c746bf26b --- /dev/null +++ b/developers/cli/verifying-contracts/index.html @@ -0,0 +1,46 @@ + + + + + +Verifying Contracts | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Verifying Smart Contracts

    +

    This document describes actions needed for smart contract verification using the Casper CLI client.

    +

    Prerequisites

    +
      +
    • You have built and installed a contract
    • +
    +

    Verifying contracts using the Casper Client

    +

    You can use the Casper client's verify-contract command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success.

    +
    casper-client verify-contract --verification-url-basepath <HOST:PORT> <TRANSACTION-HASH> <PATH>
    +
      +
    1. verification-url-basepath - The address of the verification service that will perform the operation; the current two options are https://staging.codeverifier.casper.network for Testnet and https://codeverifier.casper.network for Mainnet.
    2. +
    3. <TRANSACTION-HASH> - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success.
    4. +
    5. <PATH> - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used.
    6. +
    +

    The prerequisites for the source code are the same as when installing it on the blockchain:

    +
      +
    • +

      The source code must be a Rust project as described in The Cargo Book.

      +
    • +
    • +

      There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book.

      +
    • +
    • +

      The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.

      +
    • +
    +

    If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on https://staging.casperecosystem.io/check-verification-status/ for Testnet transactions and https://casperecosystem.io/check-verification-status/ for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust.

    + + \ No newline at end of file diff --git a/developers/dapps/dapp/index.html b/developers/dapps/dapp/index.html index 288d74ffb..d261aa8a1 100644 --- a/developers/dapps/dapp/index.html +++ b/developers/dapps/dapp/index.html @@ -1,21 +1,21 @@ - + -What is a dApp? | Casper Docs - Redux +What is a dApp? | Casper Docs - Redux - - + +
    Version: Next

    What is a dApp?

    A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.

    The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself.

    How are Decentralized Applications Different?

    @@ -23,11 +23,11 @@

    node. The decentralized aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    Routine operations in a decentralized network may result in nodes coming on or offline. This node churn can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node.

    Interacting with a Decentralized Network

    -

    For a dApp to integrate with a Casper network, it must be able to send Deploys via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the Deploy. Sending a Deploy to a node will result in that node gossiping that Deploy to other nodes, assuming that the Deploy is valid and accepted. The Deploy will then be enqueued for execution.

    -

    A Deploy contains session code in the form of Wasm to be executed in the context of the sending account. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later.

    -

    Sending a Deploy is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a Deploy simultaneously to each node it is connected to, but can only do so once per node, per Deploy.

    -

    All associated changes to global state occur after successful execution of the Deploy. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the Deploy are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a Deploy, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    -

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the Deploy is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given Deploy.

    -

    There is an inherent timing consideration when sending a Deploy, from the point where it is sent to when it is executed. The Deploy Lifecycle results in a delay longer than would be expected from a centralized application. The Deploy must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of Deploys currently being sent may cause it to increase.

    +

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    +

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later.

    +

    Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    +

    All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    +

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    +

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    \ No newline at end of file diff --git a/developers/dapps/index.html b/developers/dapps/index.html index 470e441dd..e62a0f346 100644 --- a/developers/dapps/index.html +++ b/developers/dapps/index.html @@ -1,21 +1,21 @@ - + -Overview of Casper dApps | Casper Docs - Redux +Overview of Casper dApps | Casper Docs - Redux - - + +
    Version: 1.5.X

    Overview of Casper dApps

    + submit an issue on Github
    Version: Next

    Overview of Casper dApps

    The following topics are essential for developers building decentralized applications on a Casper network.

    @@ -62,6 +62,6 @@ -
    TopicDescription
    Introducing dAppsIntroducing dApps on a Casper network
    Prerequisites for Building dAppsRecommended setup for building dApps on Casper
    SDK Client LibrariesClient-side libraries providing ways to interact with a Casper network
    dApp Technology StackBuilding the front-end, backend, and on-chain logic of a dApp
    Front-end Template with ReactUse the Casper JS SDK with React to build a dApp fron-tend
    Signing DeploysDetails about the signatures required for deploys
    Setting up a Local Network with NCTLLearn to set up a local test network
    Testing Smart Contracts with NCTLTest deploys locally before sending them to a Casper network
    Monitoring and Consuming EventsHow dApps can listen for emitted events and perform actions based on event data
    +
    TopicDescription
    Introducing dAppsIntroducing dApps on a Casper network
    Prerequisites for Building dAppsRecommended setup for building dApps on Casper
    SDK Client LibrariesClient-side libraries providing ways to interact with a Casper network
    dApp Technology StackBuilding the front-end, backend, and on-chain logic of a dApp
    Front-end Template with ReactUse the Casper JS SDK with React to build a dApp frontend
    Signing TransactionsDetails about the signatures required for transactions
    Setting up a Local Network with NCTLLearn to set up a local test network
    Testing Smart Contracts with NCTLTest transactions locally before sending them to a Casper network
    Monitoring and Consuming EventsHow dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data
    \ No newline at end of file diff --git a/developers/dapps/monitor-and-consume-events/index.html b/developers/dapps/monitor-and-consume-events/index.html index 1d7996e96..59687facb 100644 --- a/developers/dapps/monitor-and-consume-events/index.html +++ b/developers/dapps/monitor-and-consume-events/index.html @@ -1,161 +1,86 @@ - + -Monitoring and Consuming Events | Casper Docs - Redux +Monitoring Events with the Casper Sidecar | Casper Docs - Redux - - + +
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    + submit an issue on Github
    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Monitoring and Consuming Events

    -

    The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using Casper's client-side SDKs, dApps actively listening for emitted events can consume these events and perform actions based on event data.

    -

    Each Casper node streams events through the SSE (Server Sent Event) server via the port specified as the event_stream_server.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.

    -

    Events are divided into three categories and streamed on their respective endpoints:

    +

    The Casper platform uses event streaming to signal state changes in smart contracts and nodes. Using the Casper Sidecar service and client-side SDKs, dApps actively listening for emitted events can consume them and perform actions based on event data.

    +

    Smart contracts can also emit contract-level events, as explained here. DApps can consume these events by listening to the event stream, detecting TransactionProcessed events, and parsing the messages array storing String-representations of the emitted events.

    +

    The Casper Sidecar

    +

    The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar supports the following functionalities:

      -
    • Deploy events - Associated with Deploys on a node. Currently, only a DeployAccepted event is emitted. The URL to consume deploy-related events on Mainnet and Testnet is http://<HOST>:9999/events/deploys/.
    • -
    • Finality Signature events - Emitted when a block has been finalized and cannot be altered. The URL to consume finality signature events on Mainnet and Testnet is http://<HOST>:9999/events/sigs/.
    • -
    • Main events - All other events fall under this type, including: BlockAdded, DeployProcessed, DeployExpired, Fault, Step, and Shutdown events. The URL to consume these events on Mainnet and Testnet is http://<HOST>:9999/events/main/.
    • +
    • A server-sent events (SSE) endpoint with an /events endpoint streaming events from all the connected nodes. The Sidecar also stores these events.
    • +
    • A REST API server that allows clients to query stored events.
    • +
    • A JSON-RPC API to interact with a Casper node.
    • +
    • Legacy emulation for clients using older versions of the SSE API.
    -
    note

    An ApiVersion event is always emitted when a new client connects to a node's SSE server, informing the client of the node's software version.

    -

    Listening to the Event Stream

    -

    Applications can listen for such events for a specific account during a particular era, containing certain data. Then, they can parse the data and discard what they do not need. To consume the event stream, set up an event listener in your dApp using the following code:

    +

    Sidecar components and architecture

    +

    Visit GitHub for the latest source code and information on:

    + +

    The Event Stream

    +

    Casper nodes offer an event stream API that returns server-sent events (SSEs) with JSON-encoded data. The Sidecar reads the event stream of all connected nodes, acting as a passthrough and replicating the SSE interface of the connected nodes.

    +

    The Sidecar can:

    +
      +
    • Republish the current events from the node to clients listening to Sidecar's SSE API.
    • +
    • Publish a configurable number of previous events to clients connecting to the Sidecar's SSE API with ?start_from= query (similar to the node's SSE API).
    • +
    • Store the events in external storage so clients can query them via the REST API.
    • +
    +

    The Sidecar also provides an endpoint for Sidecar-generated events that can be useful, although the node did not emit them.

    +

    To summarize, events are divided into two categories and emitted on their respective endpoints:

    +
      +
    • Node-generated events - All events coming from connected node(s) are emitted on the events endpoint. The default URL to consume these events on a Mainnet or Testnet node is usually http://HOST:19999/events/. This URL depends on how the Sidecar was configured on the node.
    • +
    • Sidecar-generated events - The Sidecar also emits events on the events/sidecar endpoint, designated for events originating solely from the Sidecar service. The URL to consume these events using Sidecar on a Mainnet or Testnet node is usually http://HOST:19999/events/sidecar/. This URL depends on how the Sidecar was configured on the node.
    • +
    +

    The Casper Sidecar Usage Guide describes each event type in detail.

    +

    Listening to the Event Stream

    +

    Set up an event listener in your dApp using the following code to consume the event stream. The NODE_ADDRESS is the address of the node where the Sidecar was installed. The PORT is the address where the Sidecar streams events. It is 19999 by default, but you must find out how the Sidecar was configured.

    -
    const { EventStream, EventName } = require("casper-js-sdk")

    const es = new EventStream("http://NODE_ADDRESS:9999/events/" + CHANNEL)
    es.start()
    es.subscribe(EventName.EVENT_NAME, eventHandler)

    const eventHandler = (event) => {
    console.log(event)
    }
    +
    const { EventStream, EventName } = require("casper-js-sdk")

    const es = new EventStream("http://NODE_ADDRESS:PORT/events/")
    es.start()
    es.subscribe(EventName.EVENT_NAME, eventHandler)

    const eventHandler = (event) => {
    console.log(event)
    }
    -
    from pycspr import NodeClient, NodeConnection, NodeEventChannel, NodeEventType

    def eventHandler(event):
    print(event)

    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    client.get_events(eventHandler, NodeEventChannel.CHANNEL, NodeEventType.EVENT_NAME)
    +
    from pycspr import NodeClient, NodeConnection, NodeEventType

    def eventHandler(event):
    print(event)

    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = "PORT"))
    client.get_events(eventHandler, NodeEventType.EVENT_NAME)
    -
    curl -s http://NODE_ADDRESS:9999/events/CHANNEL
    +
    curl -s http://NODE_ADDRESS:PORT/events/

    You can find node addresses of active online peers to replace NODE_ADDRESS, by navigating to cspr.live for Mainnet and testnet.cspr.live for Testnet.

    Replace EVENT_NAME with one of the event types listed below.

    -

    Replace CHANNEL with one of the following event streams:

    -
      -
    • main for ApiVersion, BlockAdded, DeployExpired, DeployProcessed, Fault, or Step events.
    • -
    • deploys for DeployAccepted events.
    • -
    • sigs for FinalitySignature events.
    • -
    -

    Event Types

    -

    ApiVersion

    -

    The ApiVersion event is always the first event emitted when a new client connects to a node's SSE server. It specifies the protocol version of a node on the Casper platform. The following example contains the JSON representation of the ApiVersion event structure.

    -
    data:{"ApiVersion":"1.0.0"}
    -

    BlockAdded

    -

    A BlockAdded event is emitted when a new block is added to the blockchain and stored locally in the node.

    -
    Expand to view output
    - -
    {
    "BlockAdded": {
    "block_hash": "62ddf902e9b6988b978413e2a9a2c6c95f8e1ddf452afd8e8a68f0ac22bf391a",
    "block": {
    "hash": "62ddf105e9b6988b378413e2a9a2c6c95f8e1ddf458afd8e8268f0ac72bfe91a",
    "header": {
    "parent_hash": "ed11ac2117edb9c5b26cf0cde318a807fd68e76206855a70429012ef16b557f5",
    "state_root_hash": "3c1ad31757ae40f934de4825a818274e0c246d304c661daf656e22b65174ad66",
    "body_hash": "eb2344f37193395bbc83587e498bc12ad5f0019055abcfa4c3b989d382a7969a",
    "random_bit": true,
    "accumulated_seed": "b8b671530f2221c8fdf201083f43c51e215e2f6ffcbe2d63238a2779eb177922",
    "era_end": null,
    "timestamp": "2023-01-01T09:55:25.312Z",
    "era_id": 8426,
    "height": 1566677,
    "protocol_version": "1.4.13"
    },
    "body": {
    "proposer": "010e5669b0f0545e2b32bc66363b9d3d4390fca56bf52305f1411b7fa12ca311c7",
    "deploy_hashes": [],
    "transfer_hashes": []
    },
    "proofs": []
    }
    }
    }
    -
      -
    • block_hash - The cryptographic hash that identifies a block.
    • -
    • block - The JSON representation of the block.
    • -
    • proposer - The validator selected to propose the block.
    • -
    -
    -

    DeployAccepted

    -

    DeployAccepted events are emitted when a node on the network receives a deploy.

    -
    Expand to view output
    - -
    {
    "DeployAccepted": {
    "hash": "db84ba229ea37716230ac9874f66c0f12b9731d8d42f28060e481ef3d7263ead",
    "header": {
    "account": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",
    "timestamp": "2023-01-01T20:22:45.383Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "8a377b07a01ac23905b2e416ff388508301feffbb9bdf275c59f87be1e9d0de5",
    "dependencies": [],
    "chain_name": "casper-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "040008af2f",
    "parsed": "800000000"
    }
    ]
    ]
    }
    },
    "session": {
    "StoredContractByHash": {
    "hash": "1040f40d06f0355a80149befc4b5d1f203231231d66c4903688e178c36066539",
    "entry_point": "test_entry_point",
    "args": [
    [
    "cost",
    {
    "cl_type": "U512",
    "bytes": "0500c817a804",
    "parsed": "20000000000"
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c",
    "signature": "01d81d4dc9504a356c23d3c161b87b39b1708cd282b59d3e44d9b999e787643ab495f168475bed8dc48d1056605e06c8ba74d96c69ae5b506c4312be8871c0c701"
    }
    ]
    }
    }
    -
      -
    • hash - The blake2b hash of the Deploy.
    • -
    • account - The hexadecimal-encoded public key of the account submitting the Deploy.
    • -
    • body_hash - The blake2b hash of the Deploy body.
    • -
    • payment - Gas payment information.
    • -
    • session - The session logic defining the Deploy's functionality.
    • -
    • approvals - The signer's hexadecimal-encoded public key and signature.
    • -
    -
    -

    For details on custom serializations, check the Serialization Standard. Also, the Types page defines the terms used in the event stream output.

    -

    DeployProcessed

    -

    A DeployProcessed event is emitted when a given Deploy has been executed.

    -
    Expand to view output
    - -
    {
    "DeployProcessed": {
    "deploy_hash": "0f33be8f56ff23d7d503a9804675472e043830a6c17e6141dce717b4f0973c7d",
    "account": "0201cbff12155b6ae1e99d571c01d56e9e1ba0def6719a6f06bc3e4a08f30a887444",
    "timestamp": "2023-01-01T10:07:00.401Z",
    "ttl": "30m",
    "dependencies": [],
    "block_hash": "509b754648168a73e6ab67e64d4a783cf580d6fc0c7c0ec560c6650f717841e0",
    "execution_result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "account-hash-a8261377ef9cf8e7411d6858801c71e28c9322e66355586549c75ab24cdd73f2",
    "transform": "Identity"
    },
    ]
    },
    "transfers": [
    "transfer-3389144d15238240f48f5966f2dc299b6b20eb19c13d834409b4d28fc50fa909"
    ],
    "cost": "100000000"
    }
    }
    }
    }
    -
      -
    • deploy_hash - The cryptographic hash of a Deploy.
    • -
    • account - The hexadecimal-encoded public key of the account submitting the Deploy.
    • -
    • timestamp - A timestamp type representing a concrete moment in time.
    • -
    • dependencies - A list of Deploy hashes.
    • -
    • block_hash - A cryptographic hash identifying a Block.
    • -
    • execution_result - The execution status of the Deploy, which is either Success or Failure.
    • -
    -
    -

    DeployExpired

    -

    A DeployExpired event is emitted when the Deploy is no longer valid for processing or being added to a block due to its time to live (TTL) having expired.

    -
    Expand to view output
    - -
    {
    "DeployExpired": {
    "deploy_hash": "7ecf22fc284526d6db16fbf455f489e0a9cbf782234131c010cf3078fb9be353"
    }
    }
    - -
    -

    Fault

    -

    The Fault event is emitted if there is a validator error.

    -
    Expand the below section to view the Fault event details:
    - -
    {
    "Fault": {
    "era_id": 4591448806312642600,
    "public_key": "013da85eb06279da42e28530e1116be04bfd2aa25ed8d63401ebff4d9153a609a9",
    "timestamp": "2023-01-01T01:26:58.364Z"
    }
    }
    -
      -
    • era_id - A period of time during which the validator set does not change.
    • -
    • public_key - The hexadecimal-encoded public key of the validator that caused the fault.
    • -
    • timestamp - A timestamp representing the moment the validator faulted.
    • -
    -
    -

    FinalitySignature

    -

    This event indicates validators have signed the final approvals and further alterations to the block will not be allowed. Refer to the consensus reached and block finality sections to learn more about finality signatures.

    -
    Expand to view output
    - -
    {
    "FinalitySignature": {
    "block_hash": "eceed827e11f7969a7d3fe91d6fa4ce9749dd79d9f3ea26474fe2014db90e98d",
    "era_id": 8419,
    "signature": "0117087ef4b9a786e5a0ea8f198050e9de93dd94f87469b8124c346aeae5f36ad9adf80f670ee9c5887263267ed32cf932dce9b370353c596d59f91fbd57a1a205",
    "public_key": "01c375b425a36de25dc325c9182861679db2f634abcacd9ae2ee27b84ba62ac1f7"
    }
    }
    -
      -
    • block_hash - A cryptographic hash identifying a Block.
    • -
    • era_id - A period of time during which the validator set does not change.
    • -
    • signature - Serialized bytes representing the validator's signature.
    • -
    • public_key - The hexadecimal-encoded public key of the validator.
    • -
    -
    -

    Step

    -

    The Step event is emitted at the end of every era and contains the execution effects produced by running the auction contract's step function.

    -
    Expand to view output:
    - -
    {
    "Step": {
    "era_id": 1,
    "execution_effect": {
    "operations": [],
    "transforms": [
    {
    "key": "uref-53df18bf01396fbd1ef3a8757c7bdffc684c407d90f2cfeebff166db1d923613-000",
    "transform": "Identity"
    },
    {
    "key": "uref-f268de37fcea55f8fb1abeba8536a1cc041b2aed2691f1cf34aeaaf0ae379aa5-000",
    "transform": "Identity"
    },
    {
    "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",
    "transform": "Identity"
    },
    {
    "key": "bid-278e5af1ca6cddf5d5438999cb072b47f0d65e1484799f692c3c9c40304be30e",
    "transform": {
    "WriteBid": {
    "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",
    "bonding_purse": "uref-136552c255d4d737bf7e43d2be250f9f38691b9fe5d9e34446bff18d6d1cf984-007",
    "staked_amount": "1000000000000005",
    "delegation_rate": 5,
    "vesting_schedule": {
    "initial_release_timestamp_millis": 1664475057182,
    "locked_amounts": null
    },
    "delegators": {
    "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d": {
    "delegator_public_key": "012a241eaa9fa3bd6ccb0e0aaaf4658538f3540e04e2f58973614a168f2f2f813d",
    "staked_amount": "51312014671568117976319379",
    "bonding_purse": "uref-c5ad00f9e6b2f2631ca647ad188187e63799a278a0a46ca25f6b4da64d556662-007",
    "validator_public_key": "0133eaae2821f090ac3ba0eadc0a897742094c0604df72b465c41d4b773298a7b9",
    "vesting_schedule": {
    "initial_release_timestamp_millis": 1664475057182,
    "locked_amounts": null
    }
    }
    },
    "inactive": false
    }
    }
    }
    ]
    }
    }
    }
    -
      -
    • era_id - A period of time during which the validator set does not change.
    • -
    • execution_effect - The journal of execution transforms from a single Deploy.
    • -
    • operations - Operations performed while executing a Deploy.
    • -
    • transform - The actual transformation performed while executing a Deploy.
    • -
    -
    -

    Shutdown

    -

    The Shutdown event is emitted when the node is about to shut down, usually for an upgrade, causing a termination of the event stream.

    -
    Expand the below section to view the Shutdown event details:
    - -
    "Shutdown"
    -
      -
    • Shutdown - The "Shutdown" text notifies the event listener that a shutdown will occur.
    • -
    -
    -

    Reacting to Events

    -

    An application may parse each event needed for its use case and respond accordingly. The dApp may act on some events and not others, or it may act upon them all, depending on its use case. Each event type contains additional data that might help in deciding whether or not to take an action. For example, DeployAccepted events contain the account's public key that submitted the deploy, the contract address, and more. This information can help determine how to proceed or whether or not to react.

    +

    Detecting Contract-Level Events

    +

    The Sidecar streams messages emitted by a contract in a human-readable format. These messages are visible as part of the TransactionProcessed event after the corresponding block is processed and added to the blockchain. For more details, see Verifying a Topic and Verifying a Message.

    +

    Reacting to Events

    +

    An application may parse each event needed for its use case and respond accordingly. Each event type contains additional data that might help decide whether to take action. For example, TransactionAccepted events contain the account's public key that submitted the transaction, the contract address, and more. This information can help determine how to proceed.

    -
    const eventHandler = (event) => {
    if (event.body.DeployAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {
    // Perform an action
    }
    }
    +
    const eventHandler = (event) => {
    if (event.body.TransactionAccepted.header.account == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c") {
    // Perform an action
    }
    }
    -
    def eventHandler(event):
    if event["DeployAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":
    # Perform an action
    +
    def eventHandler(event):
    if event["TransactionAccepted"]["header"]["account"] == "012481699f9231e36ecf002675cd7186b48e6a735d10ec1b30f587ca716937752c":
    # Perform an action
    -

    Unsubscribing from Events

    -

    In many cases, an application may need to unsubscribe after a certain time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the unsubscribe function:

    +

    Unsubscribing from Events

    +

    In many cases, an application may need to unsubscribe after a particular time or may want to unsubscribe from some events but not others. The Casper SDKs provide this ability with the unsubscribe function:

    es.unsubscribe(EventName.EVENT_NAME)
    @@ -164,24 +89,32 @@

    Un
    • EVENT_NAME - One of the different event types emitted by a Casper node.
    -

    Stopping the Event Stream

    +

    Stopping the Event Stream

    A dApp may cease listening to all events using the stop function:

    es.stop()
    -

    Replaying the Event Stream

    -

    This command will replay the event stream from an old event onward. Replace the NODE_ADDRESS, CHANNEL, and ID fields with the values of your scenario.

    +

    Replaying the Sidecar Event Stream

    +

    This command will replay the event stream from an old event onward. Replace the NODE_ADDRESS, PORT, and ID fields with the values of your scenario.

    -
    curl -sN http://NODE_ADDRESS:9999/events/CHANNEL?start_from=ID
    -

    Example:

    -
    curl -sN http://65.21.235.219:9999/events/main?start_from=29267508
    +
    curl -s http://NODE_ADDRESS:PORT/events?start_from=ID
    +

    Example:

    +
    curl -sN http://65.21.235.219:19999/events?start_from=29267508
    +

    Note that certain shells like zsh may require an escape character before the question mark:

    +
    curl -sN http://65.21.235.219:19999/events?start_from=29267508
    -

    Each URL can have a query string added to the form ?start_from=ID, where ID is an integer representing an old event ID. With this query, you can replay the event stream from that old event onward. If you specify an event ID already purged from the cache, the server will replay all the cached events.

    -
    note

    The server keeps only a limited number of events cached to allow replaying the stream to clients using the ?start_from= query string. The cache size can be set differently on each node using the event_stream_buffer_length value in the config.toml. By default, it is only 5000. -The intended use case is to allow a client consuming the event stream that loses its connection to reconnect and catch up with events that were emitted while it was disconnected.

    +

    The server will replay all the cached events if the ID is 0 or if you specify an event ID already purged from the cache.

    +

    The JSON-RPC API

    +

    The Sidecar also offers a JSON-RPC API server for clients to interact with a Casper network. It is a JSON bridge between end users and a Casper node's binary port, forwarding requests to the Casper node's binary port. For more details on how the JSON-RPC API works, see the JSON-RPC README.

    +

    The REST API

    +

    The Sidecar offers a REST API to query stored events. You can discover the specific endpoints of the REST API using OpenAPI and Swagger. The usage instructions in the repository provide more details.

    +

    Sidecar components and architecture diagram 1

    +

    Sidecar components and architecture diagram 2

    +

    Troubleshooting Tips

    +

    For troubleshooting tips, visit Github.

    \ No newline at end of file diff --git a/developers/dapps/nctl-test/index.html b/developers/dapps/nctl-test/index.html index 124181e98..ac92bf140 100644 --- a/developers/dapps/nctl-test/index.html +++ b/developers/dapps/nctl-test/index.html @@ -1,31 +1,31 @@ - + -Local Network Testing | Casper Docs - Redux +Local Network Testing | Casper Docs - Redux - - + +
    Version: 1.5.X

    Testing Smart Contracts with NCTL

    -

    NCTL effectively simulates a live Casper network. The process for sending a Deploy to an NCTL-based network is therefore similar to doing so on a live network.

    -

    Testing Deploys prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.

    + submit an issue on Github
    Version: Next

    Testing Smart Contracts with NCTL

    +

    NCTL effectively simulates a live Casper network. The process for sending a Transaction to an NCTL-based network is therefore similar to doing so on a live network.

    +

    Testing Transactions prior to sending them to a Casper network ensures that they operate as intended. When working in an environment that requires payment for execution, errors and inefficiencies quickly add up. To this end, Casper provides several layers of testing to identify and rectify any errors. After writing your smart contract and testing it using the provided framework, NCTL serves as the next step in the process. While testing is entirely optional, it should be considered a best practice to avoid paying for the execution of faulty code.

    Getting Started with NCTL

    -

    Prior to testing a Deploy through NCTL, you should have the following steps accomplished:

    +

    Prior to testing a Transaction through NCTL, you should have the following steps accomplished:

    1. -

      Completed writing a Deploy

      +

      Completed writing a Transaction

    2. -

      Tested the Deploy using the Casper testing framework

      +

      Tested the Transaction using the Casper testing framework

    3. Setup NCTL on your system

      @@ -34,74 +34,91 @@

      Ge

      NCTL Verification Prior to Testing

      Prior to attempting an NCTL test, you must verify that your local NCTL instance started correctly. Run the following command to view your current node status:

      nctl-status
      -

      You should see five nodes RUNNING and five STOPPED. Further, verify that the node and user information propagated within the casper-node/utils/assets directory. Each node and user should have the associated Keys necessary to interact with the network. Run the following command to view first user details:

      +

      You should see five nodes and instances of sidecar RUNNING and five STOPPED. Further, verify that the node and user information propagated within the casper-node/utils/assets directory. Each node and user should have the associated Keys necessary to interact with the network. Run the following command to view first user details:

      nctl-view-user-account user=1

      Installing the Smart Contract

      This document assumes that you setup your NCTL network using the standard settings in a directory called /casper/.

      -

      You will need the following information to use the put-deploy command:

      +

      You will need the following information to use the put-transaction session command:

      • -

        The chain name, in this case casper-net-1. This will appear in our example put-deploy as --chain-name "casper-net-1"

        +

        The chain name, in this case casper-net-1. This will appear in our example put-transaction as --chain-name "casper-net-1".

      • -

        The secret key of the account sending the Deploy. For this example, we are using node-1 as the sender. The secret key file can be found at casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. In our example put-deploy, this will appear as --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. If your Deploy is more complex and requires multiple accounts, NCTL also establishes multiple users for testing.

        +

        The secret key of the account sending the Transaction. For this example, we are using node-1 as the sender. The secret key file can be found at casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. In our example put-transaction, this will appear as --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem. If your Transaction is more complex and requires multiple accounts, NCTL also establishes multiple users for testing.

      • -

        The payment amount in motes, which should be sufficient to avoid an 'Out of Gas' error. The payment amount will appear in our example put-deploy as --payment-amount 2500000000. NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our note about gas prices.

        +

        The pricing mode for this transaction. In this case, we are using the fixed pricing mode.

      • -

        The path to your Deploy that you wish to send to the NCTL network. This will appear in our example put-deploy as --session-path <PATH> and will require you to define the path to your specific Deploy Wasm.

        +

        The gas price tolerance in CSPR, which is the maximum amount of gas you are willing to pay for execution. This will appear in our example put-transaction as --gas-price-tolerance 10. NCTL tests are not an accurate representation of potential gas costs on a live network. Please see our note about gas prices.

      • -

        The node address for a node on your NCTL network. In this example, we are using the node at http://localhost:11101. On the Casper Mainnet or Testnet, nodes will use port 7777. This will appear in our example put-deploy as --node-address http://<HOST>:7777.

        +

        The path to your Transaction that you wish to send to the NCTL network. This will appear in our example put-transaction as --transaction-path <PATH> and will require you to define the path to your specific Transaction Wasm.

        +
      • +
      • +

        The category of the transaction, based on the size of the Wasm included. install-upgrade being the largest, descending in size through large, medium, and small. This will appear in our example put-transaction as --category 'install-upgrade'.

        +
      • +
      • +

        The session entry point, which at installation time is usually call.

        +
      • +
      • +

        The node address for a node on your NCTL network. In this example, we are using the node at http://localhost:11101. On the Casper Mainnet or Testnet, nodes will use port 7777. This will appear in our example put-transaction as --node-address http://<HOST>:7777.

      -

      The command to send your Deploy should look similar to the following code snippet:

      -
      note

      Use of the $(get_path_to_client) command assumes that you are operating in an activated NCTL envrionment.

      -
      $(get_path_to_client) put-deploy \
      --chain-name "casper-net-1" \
      --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
      --payment-amount 2500000000 \
      --session-path <PATH> \
      --node-address http://localhost:11101
      -

      The response will return something similar to the following information. Note the deploy_hash:

      -
      {
      "id": 4824893960188648146,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.0.0",
      "deploy_hash": "8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13"
      }
      }
      -

      Verifying Deploy Execution

      -

      The previous command sent the Deploy to the NCTL network, but we recommend verifying deploy execution before continuing. The deploy_hash received in the response allows you to query the Deploy's status.

      -

      To query the Deploy's status, you will pass both the deploy_hash and the same node-address from above using the following command. This will return either an error message in the event of failure or the Deploy details if it succeeds.

      -
      $(get_path_to_client) get-deploy 8e6309cc37bc58d8fedc1094ee1bd264a636d39fc0e05b5e1d72d98f7b6faf13 -n http://localhost:11101
      +

      The command to send your Transaction should look similar to the following code snippet:

      +
      note

      Use of the $(get_path_to_client) command assumes that you are operating in an activated NCTL environment.

      +
      $(get_path_to_client) put-transaction session \
      --chain-name "casper-net-1" \
      --secret-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
      --gas-price-tolerance 10 \
      --pricing-mode fixed \
      --transaction-path <PATH> \
      --category 'install-upgrade' \
      --session-entry-point call \
      --node-address http://localhost:11101
      +

      The response will return something similar to the following information. Note the transaction_hash:

      +
      {
      "jsonrpc": "2.0",
      "id": 1294011212530641270,
      "result": {
      "api_version": "2.0.0",
      "transaction_hash": {
      "Version1": "efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e"
      }
      }
      }
      +

      Verifying Transaction Execution

      +

      The previous command sent the Transaction to the NCTL network, but we recommend verifying deploy execution before continuing. The transaction_hash received in the response allows you to query the Transaction's status.

      +

      To query the Transaction's status, you will pass both the transaction_hash and the same node-address from above using the following command. This will return either an error message in the event of failure or the Transaction details if it succeeds.

      +
      $(get_path_to_client) get-transaction efad4a969064b5f8189ea4d6dd2fba2926d01d583a35178c07d7b827de16789e -n http://localhost:11101

      Interacting with the Installed Contract

      -

      Once your NCTL network executes your Deploy, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the ContractHash itself. This hash identifies the contract and allows you to target the included entry points. As we used the pre-established node-1 account to send the Deploy, we can retrieve the ContractHash from the node-1 account information. To do so, we will use the following command with a node address and the PublicKey of the node in question.

      -
      $(get_path_to_client) get-account-info \
      --node-address http://localhost:11101 \
      --public-key /casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/public_key.pem
      -

      This command will return information pertaining to the account, including the NamedKeys. The ContractHash of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a Deploy. In this instance, you will need the following information:

      +

      Once your NCTL network executes your Transaction, you can test the functionality of the installed contract. To do so, you will first need to identify any arguments to pass to the contract, starting with the PackageHash itself. This hash identifies the contract package and allows you to target the included entry points. As we used the pre-established node-1 account to send the Transaction, we can retrieve the PackageHash from the node-1 account information. To do so, we will use the following NCTL command:

      +
      nctl-view-faucet-account
      +

      This will return the NCTL faucet account's PublicKey and AccountHash. We can then query the PublicKey using the following command:

      +
      $(get_path_to_client) query-global-state \
      --node-address http://localhost:11101 \
      --key <PUBLIC KEY> \
      --state-root-hash <STATE ROOT HASH>
      +
      note

      You can retrieve the current state root hash using the command casper client get-state-root-hash.

      +

      This command will return an entity-account- value that you can use as an entity identifier in the following command:

      +
      $(get_path_to_client) get-entity \
      --node-address http://localhost:11101 \
      --entity-identifier <ENTITY IDENTIFIER>
      +

      This command will return information pertaining to the account, including the NamedKeys. The PackageHash of the contract to be tested will appear here. The process of calling the contract is similar to that of installing it, as they are both accomplished through sending a Transaction. In this instance, you will need the following information:

      • -

        The node address, entered in this instance using --node-address http://localhost:11101

        +

        The node address, entered in this instance using --node-address http://localhost:11101.

        +
      • +
      • +

        The chain name, entered in this instance using --chain-name "casper-net-1".

      • -

        The chain name, entered in this instance using --chain-name "casper-net-1"

        +

        The package hash, entered in this instance using --package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4.

      • -

        The payment amount for this Deploy in motes, which may need to be adjusted depending on cost and network chainspec. In this instance, we will use --payment-amount 500000000

        +

        The gas price tolerance in CSPR, which is the maximum amount of gas you are willing to pay for execution.

      • -

        The session path, defining the location of the Wasm bearing file for the Deploy. It appears in our example as --session-path <PATH> but you must define the path to your specific file.

        +

        The entry point on the contract that you wish to invoke.

      • -

        Any session arguments specific to the contract that you are testing. Multiple instances of --session-arg may be used as necessary to provide values to the contract, including the ContractHash you acquired above. In the example below, you will see a demonstration of the ContractHash as a session argument as --session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"

        +

        Any session arguments specific to the contract that you are testing. Multiple instances of --session-arg may be used as necessary to provide values to the contract. In the example below, you will see a demonstration of a session arg of amount as --session-arg "amount:u256='100'".

      -
      $(get_path_to_client) put-deploy \
      --node-address http://localhost:11101 \
      --chain-name "casper-net-1" \
      --payment-amount 500000000 \
      --session-path <PATH> \
      --session-arg "contract_key:key='hash-8c13aaeef50ae7f447ee21276965c31cfa45c4ea3abb03d35d078cdd6a40e4a'"
      +
      $(get_path_to_client) put-transaction package \
      --node-address http://localhost:11101 \
      --chain-name "casper-net-1" \
      --package-address package-47b8b489d54c378144bf85429f4b29c8b47142d542272086f378b9d4e29cada4 \
      --gas-price-tolerance 10 \
      --pricing-mode fixed \
      --session-arg "amount:u256='100'"

      Verifying Correct Contract Behavior

      -

      After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our donation contract from the basic smart contract tutorial, the NCTL process would have the following flow:

      +

      After calling your installed contract, you can verify that the contract behaved as expected by observing the associated change in global state. Depending on how your contract functions, this can have different meanings and results. If we use our counter contract from the basic counter contract tutorial, the NCTL process would have the following flow:

      1. -

        Send a Deploy to install the "Donation" smart contract.

        +

        Send a Transaction to install the "Counter" smart contract.

      2. -

        Verify the execution of the Deploy.

        +

        Verify the execution of the Transaction.

      3. -

        Interact with the installed contract using an additional Deploy that calls one or several of the entry points. For example, calling the donate entry point to donate an amount to the fundraising purse.

        +

        Interact with the installed contract package using an additional Transaction that calls one or several of the entry points. For example, calling the increment entry point to increase the counter by one.

      4. -

        Verify the associated change in global state. Namely, an increase in the balance of the fundraising purse.

        +

        Verify the associated change in global state. Namely, an increase in the counter.

      5. -
    +
    \ No newline at end of file diff --git a/developers/dapps/prerequisites/index.html b/developers/dapps/prerequisites/index.html index a55210ddc..e670ab12c 100644 --- a/developers/dapps/prerequisites/index.html +++ b/developers/dapps/prerequisites/index.html @@ -1,21 +1,21 @@ - + -Prerequisites | Casper Docs - Redux +Prerequisites | Casper Docs - Redux - - + +
    Version: Next

    Prerequisites

    Before trying your hand at dApp development on a Casper network, there are a few things you should do first:

    1. @@ -46,6 +46,6 @@

      D
    2. Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities.
    3. Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively.
    -

    By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network.

    +

    By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network.

    \ No newline at end of file diff --git a/developers/dapps/sdk/client-library-usage/index.html b/developers/dapps/sdk/client-library-usage/index.html index 491041c44..44d93c0b5 100644 --- a/developers/dapps/sdk/client-library-usage/index.html +++ b/developers/dapps/sdk/client-library-usage/index.html @@ -1,21 +1,21 @@ - + -SDK Client Library Usage | Casper Docs - Redux +SDK Client Library Usage | Casper Docs - Redux - - + +
    +

    Once submitted, the above snippet will print the deploy hash in the console.

    \ No newline at end of file diff --git a/developers/dapps/sdk/csharp-sdk/index.html b/developers/dapps/sdk/csharp-sdk/index.html index 497bd2e51..8b235e05d 100644 --- a/developers/dapps/sdk/csharp-sdk/index.html +++ b/developers/dapps/sdk/csharp-sdk/index.html @@ -1,21 +1,21 @@ - + -.NET SDK | Casper Docs - Redux +.NET SDK | Casper Docs - Redux - - + +
    +

    Visit https://make-software.github.io/casper-net-sdk/ to find other examples, tutorials, and complete documentation for this SDK.

    \ No newline at end of file diff --git a/developers/dapps/sdk/go-sdk/index.html b/developers/dapps/sdk/go-sdk/index.html index 0c6365258..7aac4d687 100644 --- a/developers/dapps/sdk/go-sdk/index.html +++ b/developers/dapps/sdk/go-sdk/index.html @@ -1,21 +1,21 @@ - + -Go SDK | Casper Docs - Redux +Go SDK | Casper Docs - Redux - - + +
    Version: Next

    Go SDK

    Usage Examples

    This section includes some examples of how to use Go SDK:

      @@ -26,8 +26,8 @@

      Usage Example

      Get a Deploy from the Network

      package main

      import (
      "context"
      "fmt"
      "net/http"

      "github.com/make-software/casper-go-sdk/casper"
      )

      func main() {
      handler := casper.NewRPCHandler("https://<Node Address and Port>/rpc", http.DefaultClient)
      client := casper.NewRPCClient(handler)
      deployHash := "62972eddc6fdc03b7ec53e52f7da7e24f01add9a74d68e3e21d924051c43f126"
      deploy, err := client.GetDeploy(context.Background(), deployHash)
      if err != nil {
      return
      }
      fmt.Println(deploy.Deploy.Hash)
      }

      Handle the Deploy Processed Event

      -
      package main

      import (
      "context"
      "log"

      "github.com/make-software/casper-go-sdk/sse"
      )

      func main() {
      client := sse.NewClient("https://<Node Address and Port>/events/main")
      defer client.Stop()
      client.RegisterHandler(
      sse.DeployProcessedEventType,
      func(ctx context.Context, rawEvent sse.RawEvent) error {
      deploy, err := rawEvent.ParseAsDeployProcessedEvent()
      if err != nil {
      return err
      }
      log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)
      return nil
      })
      lastEventID := 1234
      client.Start(context.TODO(), lastEventID)
      }
      +
      package main

      import (
      "context"
      "log"

      "github.com/make-software/casper-go-sdk/sse"
      )

      func main() {
      client := sse.NewClient("https://<Node Address and Port>/events")
      defer client.Stop()
      client.RegisterHandler(
      sse.DeployProcessedEventType,
      func(ctx context.Context, rawEvent sse.RawEvent) error {
      deploy, err := rawEvent.ParseAsDeployProcessedEvent()
      if err != nil {
      return err
      }
      log.Printf("Deploy hash: %s", deploy.DeployProcessed.DeployHash)
      return nil
      })
      lastEventID := 1234
      client.Start(context.TODO(), lastEventID)
      }

      Sending a Transfer

      -
      package main

      import (
      "context"
      "encoding/hex"
      "log"
      "math/big"
      "net/http"

      "github.com/make-software/casper-go-sdk/casper"
      "github.com/make-software/casper-go-sdk/types/clvalue"
      )

      func main() {
      accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")
      if err != nil { return }
      amount := big.NewInt(100000000)
      session := casper.ExecutableDeployItem{
      ModuleBytes: &casper.ModuleBytes{
      ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),
      Args: (&casper.Args{}).
      AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).
      AddArgument("amount", *clvalue.NewCLUInt512(amount)),
      },
      }

      payment := casper.StandardPayment(amount)

      deployHeader := casper.DefaultHeader()
      deployHeader.Account = accountPublicKey
      deployHeader.ChainName = "casper-test"

      newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)

      handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)
      client := casper.NewRPCClient(handler)
      result, err := client.PutDeploy(context.Background(), *newDeploy)

      log.Println(result.DeployHash)
      }
    +
    package main

    import (
    "context"
    "encoding/hex"
    "log"
    "math/big"
    "net/http"

    "github.com/make-software/casper-go-sdk/casper"
    "github.com/make-software/casper-go-sdk/types/clvalue"
    )

    func main() {
    accountPublicKey, err := casper.NewPublicKey("012488699f9a31e36ecf002675cd7186b48e6a735d10ec1b308587ca719937752c")
    if err != nil { return }
    amount := big.NewInt(100000000)
    session := casper.ExecutableDeployItem{
    ModuleBytes: &casper.ModuleBytes{
    ModuleBytes: hex.EncodeToString([]byte("<Contract WASM>")),
    Args: (&casper.Args{}).
    AddArgument("target", clvalue.NewCLByteArray(accountPublicKey.AccountHash().Bytes())).
    AddArgument("amount", *clvalue.NewCLUInt512(amount)),
    },
    }

    payment := casper.StandardPayment(amount)

    deployHeader := casper.DefaultHeader()
    deployHeader.Account = accountPublicKey
    deployHeader.ChainName = "casper-test"

    newDeploy, err := casper.MakeDeploy(deployHeader, payment, session)

    handler := casper.NewRPCHandler("https://<Node Address>:7777/rpc", http.DefaultClient)
    client := casper.NewRPCClient(handler)
    result, err := client.PutDeploy(context.Background(), *newDeploy)

    log.Println(result.DeployHash)
    }
    \ No newline at end of file diff --git a/developers/dapps/sdk/python-sdk/index.html b/developers/dapps/sdk/python-sdk/index.html index acdccd0e9..060fd0415 100644 --- a/developers/dapps/sdk/python-sdk/index.html +++ b/developers/dapps/sdk/python-sdk/index.html @@ -1,85 +1,40 @@ - + -Python SDK | Casper Docs - Redux +Python SDK | Casper Docs - Redux - - + +
    Version: Next

    Python SDK

    +

    The Python SDK allows developers to interact with the Casper Node using Python 3.9+. This page covers various examples of using this SDK.

    Installation

    -
    pip3 install pycspr
    -

    How To's

    -

    The following set of How To's cover the full SDK feature set and are designed to be run against a CCTL network.

    -

    Cryptography

    +

    To install the library, run:

    +

    pip3 install pycspr
    +

    Tests

    +

    You can find examples of testing this library with python scripts in the test directory. To run the tests, we recommend the pytest library:

    +
        pytest ./tests
    +

    Usage Examples

    +

    In this section, we outline a couple of essential tasks you can accomplish with the Python SDK:

    -

    Deploys

    - -

    Smart Contracts

    - -

    Node APIs

    -
    +

    For further examples, take a look at the How-tos.

    +

    Sending a transfer

    +

    This example shows you how to define and transfer funds between purses on a Casper network. Replace the path_to_cp2_account_key in the code below with the receiver's account public key.

    +
        import os
    import pathlib
    import random
    import typing

    import pycspr
    from pycspr.client import NodeClient
    from pycspr.client import NodeConnectionInfo
    from pycspr.crypto import KeyAlgorithm
    from pycspr.types import PrivateKey
    from pycspr.types import Deploy
    from pycspr.types import PublicKey

    # path to cp1 secret key - defaults to NCTL user 1.
    path_to_cp1_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"

    # type of cp1 secret key - defaults to ED25519.
    type_of_cp1_secret_key = KeyAlgorithm.ED25519.name,

    # path to cp2 account key - defaults to NCTL user 2.
    path_to_cp2_account_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-2" / "public_key_hex"

    # name of target chain - defaults to NCTL chain.
    chain_name = "casper-net-1"

    # host address of target node - defaults to NCTL node 1.
    node_host = "localhost"

    # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.
    node_port_rpc = 11101

    def _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key, chain_name):
    """Main entry point.
    :param args: Parsed command line arguments.
    """
    # Set node client.
    client = _get_client(node_host, node_port_rpc)

    # Set counter-parties.
    cp1, cp2 = _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key)

    # Set deploy.
    deploy: Deploy = _get_deploy(chain_name, cp1, cp2)

    # Approve deploy.
    deploy.approve(cp1)

    # Dispatch deploy to a node.
    client.deploys.send(deploy)

    #If deploy is successful send the indication
    print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")


    def _get_client(node_host, node_port_rpc) -> NodeClient:
    """Returns a pycspr client instance.
    """
    return NodeClient(NodeConnectionInfo(
    host=node_host,
    port_rpc=node_port_rpc,
    ))


    def _get_counter_parties(path_to_cp1_secret_key, type_of_cp1_secret_key,path_to_cp2_account_key) -> typing.Tuple[PrivateKey, PublicKey]:
    """Returns the 2 counter-parties participating in the transfer.
    """
    cp1 = pycspr.parse_private_key(
    path_to_cp1_secret_key,
    type_of_cp1_secret_key,
    )
    cp2 = pycspr.parse_public_key(
    path_to_cp2_account_key
    )

    return cp1, cp2


    def _get_deploy(chain_name, cp1: PrivateKey, cp2: PublicKey) -> Deploy:
    """Returns transfer deploy to be dispatched to a node.
    """
    # Set standard deploy parameters.
    deploy_params = pycspr.create_deploy_parameters(
    account = cp1,
    chain_name = chain_name
    )

    # Set deploy.
    deploy = pycspr.create_native_transfer(
    params = deploy_params,
    amount = int(2.5e9),
    target = cp2.account_hash,
    correlation_id = random.randint(1, 1e6)
    )

    return deploy


    # Entry point.
    if __name__ == '__main__':
    _main(node_host, node_port_rpc, path_to_cp1_secret_key, type_of_cp1_secret_key, path_to_cp2_account_key, chain_name)
    +

    Staking

    +

    This example shows you how to define and stake funds with a validator.

    +

    import os
    import pathlib

    import pycspr
    from pycspr.client import NodeClient
    from pycspr.client import NodeConnectionInfo
    from pycspr.crypto import KeyAlgorithm
    from pycspr.types import Deploy
    from pycspr.types import PrivateKey

    # path to cp1 secret key - defaults to NCTL user 1.
    path_to_validator_secret_key = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "users" / "user-1" / "secret_key.pem"

    # type of cp1 secret key - defaults to ED25519.
    type_of_validator_secret_key = KeyAlgorithm.ED25519.name

    # path to session code wasm binary - defaults to NCTL bin/eco/add_bid.wasm.
    path_to_wasm = pathlib.Path(os.getenv("NCTL")) / "assets" / "net-1" / "bin" / "auction" / "add_bid.wasm"

    # amount to stake, i.e. bond, into the network.
    amount = int(2.5e9)

    # amount to charge delegators for service provision.
    delegation_rate = 2

    # name of target chain - defaults to NCTL chain.
    chain_name = "casper-net-1"

    # host address of target node - defaults to NCTL node 1.
    node_host = "localhost"

    # Node API JSON-RPC port - defaults to 11101 @ NCTL node 1.
    node_port_rpc = 11101

    def _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm):
    """Main entry point.
    :param args: Parsed command line arguments.
    """
    # Set node client.
    client: NodeClient = _get_client(node_host, node_port_rpc)

    # Set validator key.
    validator: PrivateKey = pycspr.parse_private_key(
    path_to_validator_secret_key,
    type_of_validator_secret_key,
    )

    # Set deploy.
    deploy: Deploy = _get_deploy(validator, chain_name, amount, delegation_rate, path_to_wasm)

    # Approve deploy.
    deploy.approve(validator)

    # Dispatch deploy to a node.
    client.deploys.send(deploy)

    print(f"Deploy dispatched to node [{node_host}]: {deploy.hash.hex()}")


    def _get_client(node_host, node_port_rpc) -> NodeClient:
    """Returns a pycspr client instance.
    """
    return NodeClient(NodeConnectionInfo(
    host = node_host,
    port_rpc = node_port_rpc,
    ))


    def _get_deploy(validator: PrivateKey, chain_name, amount, delegation_rate, path_to_wasm) -> Deploy:
    """Returns delegation deploy to be dispatched to a node.
    """
    # Set standard deploy parameters.
    deploy_params = pycspr.create_deploy_parameters(
    account = validator,
    chain_name = chain_name
    )

    # Set deploy.
    deploy = pycspr.create_validator_auction_bid(
    params = deploy_params,
    amount = amount,
    delegation_rate = delegation_rate,
    public_key = validator.as_public_key(),
    path_to_wasm = path_to_wasm
    )

    return deploy


    # Entry point.
    if __name__ == '__main__':
    _main(node_host, node_port_rpc, path_to_validator_secret_key, type_of_validator_secret_key, chain_name, amount, delegation_rate, path_to_wasm)
    \ No newline at end of file diff --git a/developers/dapps/sdk/script-sdk/index.html b/developers/dapps/sdk/script-sdk/index.html index b58dadec7..f7cc386b5 100644 --- a/developers/dapps/sdk/script-sdk/index.html +++ b/developers/dapps/sdk/script-sdk/index.html @@ -1,21 +1,21 @@ - + -JavaScript/TypeScript SDK | Casper Docs - Redux +JavaScript/TypeScript SDK | Casper Docs - Redux - - + +
    Version: Next

    JavaScript/TypeScript SDK

    This page contains details related to a few JavaScript (JS) clients and the Casper JS SDK.

    Usage of JavaScript Clients

    The Casper team has implemented specific JS clients to support interaction with the Casper contracts.

    @@ -52,6 +52,6 @@

    Sending a

    Here is the code you can use to serialize the deploy:

    const jsonFromDeploy = DeployUtil.deployToJson(signedDeploy);

    Then, you can reconstruct the deploy object using this function:

    -
    const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);

    +
    const deployFromJson = DeployUtil.deployFromJson(jsonFromDeploy);
    \ No newline at end of file diff --git a/developers/dapps/setup-nctl/index.html b/developers/dapps/setup-nctl/index.html index 941e5866b..c61c7b183 100644 --- a/developers/dapps/setup-nctl/index.html +++ b/developers/dapps/setup-nctl/index.html @@ -1,21 +1,21 @@ - + -Local Network Setup | Casper Docs - Redux +Local Network Setup | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting up a Local Network with NCTL

    + submit an issue on Github
    Version: Next

    Setting up a Local Network with NCTL

    NCTL stands for network/node control. NCTL is a CLI application you can use to set up and control multiple local Casper nodes during development. Many developers wish to spin up relatively small test networks to localize their testing before deploying to the blockchain. Adopting a standardized approach in the community is also helpful for troubleshooting and reporting issues.

    Prerequisites

      @@ -23,92 +23,91 @@

      Prerequisites<
    1. Make sure you have Python 3 installed if your operating system does not include Python.
    2. To run NCTL, you will also need the bash shell.
    -

    Video Tutorial

    -

    If you prefer a video walkthrough of this guide, you can check out this video.

    -

    Installing a Virtual Environment

    We will show you how to run NCTL in a virtual environment. If you want to run NCTL at the system level, you can, but we recommend that you only do that if you are sure you know what you are doing.

    First, you will need to install a set of tools required for running NCTL.

    Step 1. The first tool you will need is pip, a package manager for Python. Pip comes with the Python 3 installation from python.org, but if you do not have it already, follow the steps below or the full installation instructions.

    Instructions for MacOS:

    -
    curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    python3 get-pip.py
    +
    $ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    $ python3 get-pip.py

    Instructions for Linux:

    -
    sudo apt install python3-pip
    +
    $ sudo apt install python3-pip

    Step 2. Install pkg-config, a program used to compile and link against one or more libraries.

    Instructions for MacOS:

    -
    brew install pkg-config
    +
    $ brew install pkg-config

    Instructions for Linux:

    -
    sudo apt install pkg-config
    +
    $ sudo apt install pkg-config

    Step 3. Install either libssl-dev (Linux) or openssl (MacOS), which are toolkits for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. They also serve as general-purpose cryptography libraries.

    Instructions for MacOS:

    -
    brew install openssl
    +
    $ brew install openssl

    Instructions for Linux:

    -
    sudo apt install libssl-dev
    +
    $ sudo apt install libssl-dev

    Step 4. You will also need the gcc and g++ compilers, which usually come as part of developer command-line tools (versions 7.5.0 at the time of this writing).

    Instructions for MacOS:

    -
    xcode-select --install
    gcc --version
    g++ --version
    +
    $ xcode-select --install
    $ gcc --version
    $ g++ --version

    Instructions for Linux:

    -
    sudo apt install build-essential
    gcc --version
    g++ --version
    -

    Important Note:

    -

    The following commands need to be executed within the Bash shell. While MacOS and some Linux distributions use Zsh by default, they also include Bash. To ensure proper execution of the subsequent commands, switching to Bash is recommended. If the command does not work, please refer to the Bash documentation on how to install it on your system.

    -

    Step 5. Switching to Bash Shell:

    -

    Type the following command in your terminal:

    +
    $ sudo apt install build-essential
    $ gcc --version
    $ g++ --version
    +

    Step 5. Create and activate a new virtual environment. Commands applicable to the virtual environment will be prefixed with (env). Run the following commands to set it up.

    Instructions for MacOS and Linux:

    -
    bash
    -

    This will launch a new Bash shell session. You can then proceed with the tutorial.

    -

    Step 6. Create and activate a new virtual environment. Commands applicable to the virtual environment will be prefixed with (env). Run the following commands to set it up.

    +
    $ python3 -m venv env
    $ source env/bin/activate
    (env) $
    +

    Step 6. Inside the virtual environment, upgrade pip to the latest version.

    Instructions for MacOS and Linux:

    -
    python3 -m venv env
    source env/bin/activate
    -

    Once you have activated the virtual environment, your terminal prompt will change to indicate you're working within it. It will usually look something like this:

    -
    (env) $  // This line is for visual representation only, not to be copied
    -

    Step 7. Inside the virtual environment, upgrade pip to the latest version.

    +
    (env) $ pip install --upgrade pip
    +

    Step 7. Install jq, a command-line JSON processor.

    Instructions for MacOS and Linux:

    -
    pip install --upgrade pip
    -

    Step 8. Install jq, a command-line JSON processor.

    +
    (env) $ pip install jq
    +

    Step 8. Install supervisor, a cross-platform process manager.

    Instructions for MacOS and Linux:

    -
    pip install jq
    -

    Step 9. Install supervisor, a cross-platform process manager.

    +
    (env) $ pip install supervisor
    +

    Step 9. Install toml, a configuration file parser.

    Instructions for MacOS and Linux:

    -
    pip install supervisor
    -

    Step 10. Install toml, a configuration file parser.

    -

    Instructions for MacOS and Linux:

    -
    pip install toml
    +
    (env) $ pip install toml

    Setting up the Network

    You are now ready to set up and run your local network of Casper nodes.

    -

    Step 11. Clone the casper-node-launcher software in your working directory, which we will call WORKING_DIRECTORY. Very Important!!! Choose a short path for your working directory; otherwise, the NCTL tool will report that the path is too long.

    +
    note

    NCTL will not work properly if the following repositories are downloaded via Github's web GUI. To ensure functionality, use the CLI git clone command.

    +

    Step 10. Clone the casper-nctl software in your working directory, referenced here as WORKING_DIRECTORY. Very Important!!! Choose a short path for your working directory; otherwise, the NCTL tool will report that the path is too long.

    Instructions for MacOS and Linux:

    -
    cd <WORKING_DIRECTORY>
    git clone https://github.com/casper-network/casper-node-launcher
    -
    note

    Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the deploy_delay in your local config.toml before running nctl-assets-setup.

    -

    Step 12. Next, clone the casper-node software, also in your working directory.

    +
    $ cd <WORKING_DIRECTORY>
    $ git clone https://github.com/casper-network/casper-nctl
    +

    Step 11. Clone the casper-node software in your working directory.

    +

    Instructions for MacOS and Linux:

    +
    $ git clone https://github.com/casper-network/casper-node
    +

    Step 12. Clone the casper-client-rs software in your working directory.

    Instructions for MacOS and Linux:

    -
    git clone https://github.com/casper-network/casper-node
    -

    Step 13. Finally, clone the casper-client-rs software in your working directory.

    +
    $ git clone https://github.com/casper-ecosystem/casper-client-rs
    +

    Step 13. Clone the casper-node-launcher software in your working directory.

    +

    Instructions for MacOS and Linux:

    +
    $ git clone https://github.com/casper-network/casper-node-launcher
    +
    note

    Assuming you have set up a small local network, you can speed up the process of creating new blocks with NCTL by reducing the deploy_delay in your local config.toml before running nctl-assets-setup.

    +

    Step 14. Clone the casper-sidecar software in your working directory. As part of Casper's Condor release, the sidecar is now necessary to interact with a Casper network and will handle any API requests.

    Instructions for MacOS and Linux:

    -
    git clone https://github.com/casper-ecosystem/casper-client-rs
    -

    Step 14. Activate the NCTL environment with the following command.

    +
    $ git clone https://github.com/casper-network/casper-sidecar
    +

    Step 15. You may need to extend your .bashrc file to make NCTL commands available from the terminal session. You can do so using the following commands:

    +
    cd YOUR_WORKING_DIRECTORY/casper-nctl

    cat >> $HOME/.bashrc <<- EOM

    # ----------------------------------------------------------------------
    # CASPER - NCTL
    # ----------------------------------------------------------------------

    # Activate NCTL shell.
    . $(pwd)/activate

    EOM
    +

    Followed by refreshing the bash session:

    +
    . $HOME/.bashrc
    +

    Step 16. Activate the NCTL environment with the following command.

    Instructions for MacOS and Linux:

    -
    source casper-node/utils/nctl/activate
    -

    Step 15. Compile the NCTL binary scripts. The following command compiles both the casper-node and the casper-client in release mode.

    +
    $ source casper-node/utils/nctl/activate
    +

    Step 17. Compile the NCTL binary scripts. The following command compiles both the casper-node and the casper-client in release mode.

    Instructions for MacOS and Linux:

    -
    nctl-compile
    +
    $ nctl-compile
    note

    The compilation takes some time, so it might be a perfect moment to get some coffee.

    -

    Step 16. Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes, with 5 active nodes and 5 inactive nodes.

    +

    Step 18. Set up all the assets required to run a local network, including binaries, chainspec, config, faucet, and keys. Also, spin up the network right after. The default network will have 10 nodes and 10 instances of the sidecar, with 5 active nodes and sidecars and 5 inactive nodes and sidecars.

    Instructions for MacOS and Linux:

    -
    nctl-assets-setup && nctl-start
    +
    $ nctl-assets-setup && nctl-start

    Once a network is up and running, you can control each node within the network and add new nodes to the network.

    Several other NCTL commands are available via aliases for execution from within a terminal session. All such commands are prefixed by nctl- and allow you to perform various tasks.

    You should see the new directory utils/nctl/assets, with the following structure.

    -

    +

    Assets Setup

    Here is the command line output you would expect.

    -

    +

    NCTL Output

    Stopping the Network

    -

    Step 17. Although not necessary, you can stop and clean the NCTL setup with the following commands.

    +

    Step 19. Although not necessary, you can stop and clean the NCTL setup with the following commands.

    Instructions for MacOS and Linux:

    -
    nctl-stop
    nctl-clean
    +
    $ nctl-stop
    $ nctl-clean

    Next Steps

    1. Explore the various NCTL commands.
    2. Explore the NCTL usage guide.
    3. -
    +
    \ No newline at end of file diff --git a/developers/dapps/signing-a-deploy/index.html b/developers/dapps/signing-a-deploy/index.html deleted file mode 100644 index 89d27a5e8..000000000 --- a/developers/dapps/signing-a-deploy/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Signing Deploys | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Signing Deploys

    -

    When creating a Deploy to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the deploy using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the Deploy allow the network to verify that it should be executed.

    -

    When a signature is attached to a deploy, it is paired with the public key of the signer, and referred to as an Approval. Every valid deploy has at least one approval.

    -

    The signature creation process begins with the hashing of the payment and session of the deploy to create the BodyHash. The BodyHash becomes a component of the DeployHeader as outlined in the serialization standard. From there, the DeployHeader can be hashed to create the DeployHash. As outlined above, the DeployHash is then combined with the account's key-pair to create the deploy's signature.

    -

    As the DeployHash contains a hash of the deploy's body within, any variation to any aspect of the deploy or sending account's keys would render the DeployHash invalid.

    -

    Public Key Cryptography

    -

    Casper networks are compatible with both Ed25519 and Secp256k1 public key cryptography. When serialized, public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with 1, whereas Secp256k1 are prefixed with 2.

    -

    Casper uses blake2b hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:

    -
      -
    • -

      Ed25519 signs over a SHA-512 digest.

      -
    • -
    • -

      Secp256k1 signs over a SHA-256 digest.

      -
    • -
    - - \ No newline at end of file diff --git a/developers/dapps/signing-a-transaction/index.html b/developers/dapps/signing-a-transaction/index.html new file mode 100644 index 000000000..ea70e8fce --- /dev/null +++ b/developers/dapps/signing-a-transaction/index.html @@ -0,0 +1,35 @@ + + + + + +Signing Transactions | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Signing Transactions

    +

    When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.

    +

    When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an Approval. Every valid transaction has at least one approval.

    +

    The signature creation process begins with the hashing of the payment and session of the transaction to create the BodyHash. The BodyHash becomes a component of the TransactionV1Header as outlined in the serialization standard. From there, the TransactionV1Header can be hashed to create the TransactionV1Hash. As outlined above, the TransactionV1Hash is then combined with the account's key-pair to create the transaction's signature.

    +

    As the TransactionV1Hash contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the TransactionV1Hash invalid.

    +

    Public Key Cryptography

    +

    Casper networks are compatible with both Ed25519 and Secp256k1 public key cryptography. When serialized, public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with 1, whereas Secp256k1 are prefixed with 2.

    +

    Casper uses blake2b hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:

    +
      +
    • +

      Ed25519 signs over a SHA-512 digest.

      +
    • +
    • +

      Secp256k1 signs over a SHA-256 digest.

      +
    • +
    + + \ No newline at end of file diff --git a/developers/dapps/speculative-exec/index.html b/developers/dapps/speculative-exec/index.html index 78215bd70..b8f7205c6 100644 --- a/developers/dapps/speculative-exec/index.html +++ b/developers/dapps/speculative-exec/index.html @@ -1,28 +1,28 @@ - + -Estimating Gas Costs with Speculative Execution | Casper Docs - Redux +Estimating Gas Costs with Speculative Execution | Casper Docs - Redux - - + +
    Version: 1.5.X

    Estimating Gas Costs with Speculative Execution

    + submit an issue on Github
    Version: Next

    Estimating Gas Costs with Speculative Execution

    Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculative_exec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.

    In addition to the Deploy in question, speculative_exec also accepts a [block_identifier] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block.

    Sending a Speculative Execution Deploy using the Rust CLI Casper Client

    -

    The Rust CLI Casper client includes a speculative-exec option that will flag a normal put-deploy for execution but not commitment to global state. The following command shows an example:

    +

    The Rust CLI Casper client includes a speculative-exec option that will flag a normal put-deploy for execution but not commitment to global state. The following command shows an example:


    casper client put-deploy /
    --node-address <HOST:PORT> /
    --chain-name <CHAIN_NAME> /
    --secret-key <PATH> /
    --session-path <PATH> /
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES>
    --speculative-exec <BLOCK HEIGHT OR HASH>

    You should receive execution_results that show a cost.


    {
    "jsonrpc": "2.0",
    "id": -4571113357017152230,
    "result": {
    "api_version": "1.0.0",
    "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",
    "execution_result": {
    "Success": {
    "effect": {
    <Deploy effects removed for conciseness.>
    },
    "transfers": [],
    "cost": "87300473670"
    }
    }
    }
    }

    -
    note

    Cost estimates acquired through speculative_exec may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.

    +
    note

    Cost estimates acquired through speculative_exec may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.

    \ No newline at end of file diff --git a/developers/dapps/technology-stack/index.html b/developers/dapps/technology-stack/index.html index fc160448d..bebf6a1b8 100644 --- a/developers/dapps/technology-stack/index.html +++ b/developers/dapps/technology-stack/index.html @@ -1,38 +1,38 @@ - + -dApp Technology Stack | Casper Docs - Redux +dApp Technology Stack | Casper Docs - Redux - - + +
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; + submit an issue on Github

    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    dApp Technology Stack

    There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.

    Front-End

    The front-end, or client-side of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried.

    -

    You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing Deploys and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill CORS requirements.

    +

    You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill CORS requirements.

    Signing Transactions

    The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:

    1. The Casper Wallet

      -

      Use the Casper Wallet to sign deploys for a Casper network. Deploy objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node.

      +

      Use the Casper Wallet to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node.

      caution

      The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

    2. Third-party signers

      -

      Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed deploy object.

      +

      Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object.

    Querying Global State

    @@ -49,12 +49,12 @@

    Backend
    tip

    -

    There are two main types of blockchain interactions that will originate from the front-end: deploys and queries. In the case of a dApp, both of these will pass through the back-end.

    +

    There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end.

    Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end.

    In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along.

    Blockchain

    -

    The last stop for a deploy or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and deploys originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open transactional, informational, and Proof-of-Stake endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods.

    +

    The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open transactional, informational, and Proof-of-Stake endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods.

    More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as WebAssembly binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in Rust for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust.

    -

    To learn how to write smart contracts for your dApp, read the smart contract documentation.

    +

    To learn how to write smart contracts for your dApp, read the smart contract documentation.

    \ No newline at end of file diff --git a/developers/dapps/template-frontend/index.html b/developers/dapps/template-frontend/index.html index e62e72a7e..297567d02 100644 --- a/developers/dapps/template-frontend/index.html +++ b/developers/dapps/template-frontend/index.html @@ -1,21 +1,21 @@ - + -Front-end in React | Casper Docs - Redux +Front-end in React | Casper Docs - Redux - - + +
    Version: 1.5.X

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    + submit an issue on Github
    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Front-end Template with React

    For building web applications, it is most common to use the Casper JS SDK with React. This is a popular solution among developers, but you may use any front-end library or framework, including none at all, to interact with a Casper network via the Casper JS SDK.

    This guide will walk you through setting up and developing a React application with Vite that communicates with a Casper network. Experience with Vite is not required; however, if you have never built a React app, you should begin by reading the React documentation.

    @@ -90,6 +90,6 @@

    Build f

    When you're ready to release your application, you'll want to compile it to pure JavaScript and serve it from a web server. Do so by running:

    vite build

    Once this is complete, you can preview your production build by running:

    -
    vite preview

    +
    vite preview
    \ No newline at end of file diff --git a/developers/dapps/uref-security/index.html b/developers/dapps/uref-security/index.html index dd847cf47..190066887 100644 --- a/developers/dapps/uref-security/index.html +++ b/developers/dapps/uref-security/index.html @@ -1,24 +1,24 @@ - + -URef Access Rights | Casper Docs - Redux +URef Access Rights | Casper Docs - Redux - - + +
    Version: 1.5.X

    URef Access Rights and Security Considerations

    + submit an issue on Github
    Version: Next

    URef Access Rights and Security Considerations

    Understanding Access Rights

    -

    An Unforgeable Reference or URef is a key type used for storage on a Casper network. They can store any value other than Account and exist as a top-level entity. As such, no individual account may own a URef, they can only hold the necessary AccessRights to interact with a given URef.

    -

    AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

    +

    An Unforgeable Reference or URef is a key type used for storage on a Casper network. They can store any value other than Account and exist as a top-level entity. As such, no individual entity may own a URef, they can only hold the necessary AccessRights to interact with a given URef.

    +

    AccessRights determine how an entity on a Casper network may interact with a URef. They appear as a single byte suffix after the concatenation of te URef's address. As an example, the following is an example of a URef with no associated access rights:

    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-000

    And this is the same URef with READ and ADD access rights.

    uref-974019c976b5f26412ce486158d2431967af35d91387dae8cbcd43c20fce6452-005
    @@ -67,7 +67,7 @@

    Access RightsSerialization
    NONE0
    READ1
    WRITE2
    READ_WRITE3
    ADD4
    READ_ADD5
    ADD_WRITE6
    READ_ADD_WRITE7
    warning

    Any access rights granted alongside a passed URef are irrevocable.

    AccessRights and Purses

    -

    A Purse is a unique type of URef representing a token balance. Each Account will have an associated URef that represents its main purse. Accounts and contracts may have additional purses.

    +

    A Purse is a unique type of URef representing a token balance. Each Addressable Entity will have an associated URef that represents its main purse. Account and contract entities may have additional purses.

    For URefs that represent a purse, access rights determine the ability to read or change the associated balance of tokens. The following table outlines what each operation allows in the context of a purse:

    @@ -95,6 +95,6 @@

    dApp that interacts with tokens in any way, it will be necessary to work with various URef AccessRights for associated purse URefs.

    This tutorial outlines our recommendations when transferring tokens to a contract.

    When passing a URef to another entity in any way, ensure that you are only passing the URef with the appropriate AccessRights. The following example code shows the syntax for creating a URef with any given access rights combination. In this example, only the new_uref should be passed to another entity.

    -
    // This example will create a version of the original URef with access rights stripped entirely.
    let new_uref = uref.with_access_rights(AccessRights::NONE);
    // This example will create a version of the original URef with only READ access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ);
    // This example will create a version of the original URef with only WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::WRITE);
    // This example will create a version of the original URef with both READ and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
    // This example will create a version of the original URef with only ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD);
    // This example will create a version of the original URef with both READ and ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
    // This example will create a version of the original URef with both ADD and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
    // This example will create a version of the original URef with full access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);

    +
    // This example will create a version of the original URef with access rights stripped entirely.
    let new_uref = uref.with_access_rights(AccessRights::NONE);
    // This example will create a version of the original URef with only READ access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ);
    // This example will create a version of the original URef with only WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::WRITE);
    // This example will create a version of the original URef with both READ and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_WRITE);
    // This example will create a version of the original URef with only ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD);
    // This example will create a version of the original URef with both READ and ADD access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD);
    // This example will create a version of the original URef with both ADD and WRITE access rights.
    let new_uref = uref.with_access_rights(AccessRights::ADD_WRITE);
    // This example will create a version of the original URef with full access rights.
    let new_uref = uref.with_access_rights(AccessRights::READ_ADD_WRITE);
    \ No newline at end of file diff --git a/developers/essential-crates/index.html b/developers/essential-crates/index.html index a0215bc21..e9b22d0d9 100644 --- a/developers/essential-crates/index.html +++ b/developers/essential-crates/index.html @@ -1,21 +1,21 @@ - + -Essential Rust Crates | Casper Docs - Redux +Essential Rust Crates | Casper Docs - Redux - - + +
    Version: 1.5.X

    Essential Rust Crates

    + submit an issue on Github
    Version: Next

    Essential Rust Crates

    Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.

    casper-types

    Types shared by many Casper crates:

    @@ -72,6 +72,6 @@

    cargo-cas
  • https://docs.rs/crate/cargo-casper/latest
  • Other Libraries

    -

    The Open-Source Software page provides other community-curated tools and libraries.

    +

    The Open-Source Software page provides other community-curated tools and libraries.

    \ No newline at end of file diff --git a/developers/index.html b/developers/index.html index 9d2d919fc..310619e39 100644 --- a/developers/index.html +++ b/developers/index.html @@ -1,21 +1,21 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Developers Overview

    + submit an issue on Github
    Version: Next

    Developers Overview

    This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.

    @@ -52,6 +52,6 @@
    TopicDescription
    Development PrerequisitesSetup needed for various workflows
    Essential Casper CratesAvailable Casper crates and the corresponding documentation
    Writing On-Chain CodeWriting contracts in Rust and Wasm for a Casper network
    Casper JSON-RPC APIEndpoints for developers wishing to interact directly with a Casper node's JSON-RPC API
    Building dAppsUseful information for dApp developers
    Interacting with the Blockchain Using CLIUsing a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens.

    The Ecosystem Open-Source Software may provide other helpful examples.

    -

    The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together.

    +

    The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together.

    \ No newline at end of file diff --git a/developers/json-rpc/errors/index.html b/developers/json-rpc/errors/index.html index 1305b5ccf..24aa634c1 100644 --- a/developers/json-rpc/errors/index.html +++ b/developers/json-rpc/errors/index.html @@ -1,23 +1,23 @@ - + -Casper JSON-RPC Error Codes | Casper Docs - Redux +Casper JSON-RPC Error Codes | Casper Docs - Redux - - + +
    Version: 1.5.X

    Casper JSON-RPC Error Codes

    + submit an issue on Github
    Version: Next

    Casper JSON-RPC Error Codes

    The following document expands on custom error codes provided by casper-json-rpc crate.

    -

    Error Codes

    +

    Error Codes

    @@ -121,6 +121,6 @@

    Error CodesInvalid Params

    The casper-json-rpc no longer ignores invalid params fields. Params fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent.

    -

    Failing to adhere to this will result in an InvalidParams error.

    +

    Failing to adhere to this will result in an InvalidParams error.

    \ No newline at end of file diff --git a/developers/json-rpc/guidance/index.html b/developers/json-rpc/guidance/index.html index b65c81804..92f6f38bf 100644 --- a/developers/json-rpc/guidance/index.html +++ b/developers/json-rpc/guidance/index.html @@ -1,29 +1,29 @@ - + -Guidance for JSON-RPC SDK Compliance | Casper Docs - Redux +Guidance for JSON-RPC SDK Compliance | Casper Docs - Redux - - + +
    Version: 1.5.X

    Guidance for JSON-RPC SDK Compliance

    + submit an issue on Github
    Version: Next

    Guidance for JSON-RPC SDK Compliance

    A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.

    A Casper JSON-RPC SDK claiming to be complete is expected to implement all endpoints and all types defined in the serialization standard.

    Consistency

    -

    A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and Deploy, not similar terms such as wallet or transaction.

    +

    A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet.

    Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK.

    Advanced Functionality

    SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations.

    However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience.

    -

    For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform.

    +

    For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform.

    \ No newline at end of file diff --git a/developers/json-rpc/index.html b/developers/json-rpc/index.html index 0f66d739a..fdb77e1c7 100644 --- a/developers/json-rpc/index.html +++ b/developers/json-rpc/index.html @@ -1,27 +1,27 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Interacting with the Casper JSON-RPC API

    -

    Casper uses a custom JSON-RPC implementation known as casper-json-rpc that is compliant with the JSON-RPC 2.0 specification. If you are on this page, you are an advanced user wishing to interact directly with a Casper node's JSON-RPC API. You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.

    -

    Casper nodes provide the RPC schema on port 8888, followed by rpc-schema:

    -
    <HOST:8888>/rpc-schema 
    -

    To see an example, navigate to a node's RPC schema using a browser.

    -

    The Casper client subcommand list-rpcs provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:

    + submit an issue on Github
    Version: Next

    Interacting with the Casper JSON-RPC API

    +

    Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.

    +

    The Casper Sidecar service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the JSON-RPC README in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar.

    +

    You can find the latest RPC schema in the Sidecar's GitHub repository.

    +

    The Casper client subcommand list-rpcs also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:

    casper-client list-rpcs --node-address <HOST:PORT>
    +

    You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.

    Table of Contents

    @@ -60,6 +60,6 @@

    Table of C -
    PageDescription
    Guidance for JSON-RPC SDK ComplianceRequirements for a compliant Casper SDK
    Required JSON-RPC Methods for Minimal ComplianceMethods required for a minimally compliant Casper SDK
    Transactional JSON-RPC MethodMethods allowing interaction with a Casper network
    Informational JSON-RPC MethodsMethods returning information about the network from a Casper node
    Proof-of-Stake JSON-RPC MethodsMethods pertaining to Proof-of-Stake functionality on a Casper network
    TypesInformation on types used within JSON-RPC methods
    CL TypesInformation related to CL Types

    +
    PageDescription
    Guidance for JSON-RPC SDK ComplianceRequirements for a compliant Casper SDK
    Required JSON-RPC Methods for Minimal ComplianceMethods required for a minimally compliant Casper SDK
    Transactional JSON-RPC MethodMethods allowing interaction with a Casper network
    Informational JSON-RPC MethodsMethods returning information about the network from a Casper node
    Proof-of-Stake JSON-RPC MethodsMethods pertaining to Proof-of-Stake functionality on a Casper network
    TypesInformation on types used within JSON-RPC methods
    CL TypesInformation related to CL Types
    \ No newline at end of file diff --git a/developers/json-rpc/json-rpc-informational/index.html b/developers/json-rpc/json-rpc-informational/index.html index aacd382a6..9921be755 100644 --- a/developers/json-rpc/json-rpc-informational/index.html +++ b/developers/json-rpc/json-rpc-informational/index.html @@ -1,25 +1,25 @@ - + -Informational JSON-RPC Methods | Casper Docs - Redux +Informational JSON-RPC Methods | Casper Docs - Redux - - + +
    Version: 1.5.X

    Informational JSON-RPC Methods

    + submit an issue on Github
    Version: Next

    Informational JSON-RPC Methods

    The following methods return information from a node on a Casper network. The response should be identical, regardless of the node queried, as the information in question is objective and common to all nodes within a network.


    -

    chain_get_block

    -

    This method returns the JSON representation of a Block from the network.

    +

    chain_get_block

    +

    This method returns the JSON representation of a Block from the network. If you do not specify a block_identifier, you will receive the most recent block.

    @@ -35,10 +35,10 @@

    chain_get_bl -
    ParameterTypeDescription
    block_identifierObjectThe Block hash or the Block height.
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash or the Block height. (Optional)
    Example chain_get_block request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    chain_get_block_result

    The result from chain_get_block depends on block availability from a given node. If chain_get_block returns an error message that the node does not have information on the given block, you may attempt to get the information from a different node.

    @@ -62,13 +62,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.blockObjectThe Block, if found. (Not required) +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    blockObjectThe Block, if found. (Optional)
    Example chain_get_block result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block": {
    "body": {
    "deploy_hashes": [],
    "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "transfer_hashes": [
    "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    ]
    },
    "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "header": {
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",
    "era_end": {
    "era_report": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "rewards": [
    {
    "amount": 1000,
    "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"
    }
    ]
    },
    "next_era_validator_weights": [
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    },
    {
    "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "weight": "123"
    }
    ]
    },
    "era_id": 1,
    "height": 10,
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "protocol_version": "1.0.0",
    "random_bit": true,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "timestamp": "2020-11-17T00:39:24.072Z"
    },
    "proofs": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "016291a7b2689e2edcc6e79030be50edd02f9bd7d809921ae2654012f808c7b9a0f125bc32d6aa610cbd012395a9832ccfaa9262023339f1db71ca073a13bb9707"
    }
    ]
    }
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_block_result",
    "value": {
    "api_version": "2.0.0",
    "block_with_signatures": {
    "block": {
    "Version2": {
    "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "header": {
    "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "body_hash": "48859fb4865d8637d6a35cb224e222cd0e1b1c2dd72928932c1e35ac0550818b",
    "random_bit": true,
    "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
    "era_end": {
    "equivocators": [
    "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
    ],
    "inactive_validators": [
    "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
    ],
    "next_era_validator_weights": [
    {
    "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
    "weight": "123"
    },
    {
    "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
    "weight": "456"
    },
    {
    "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
    "weight": "789"
    }
    ],
    "rewards": {},
    "next_era_gas_price": 1
    },
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "protocol_version": "1.0.0",
    "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "current_gas_price": 1,
    "last_switch_block_hash": "0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a"
    },
    "body": {
    "transactions": {
    "0": [
    {
    "Version1": "1414141414141414141414141414141414141414141414141414141414141414"
    }
    ],
    "1": [
    {
    "Version1": "1515151515151515151515151515151515151515151515151515151515151515"
    }
    ],
    "2": [
    {
    "Version1": "1616161616161616161616161616161616161616161616161616161616161616"
    }
    ],
    "3": [
    {
    "Version1": "1717171717171717171717171717171717171717171717171717171717171717"
    }
    ]
    },
    "rewarded_signatures": []
    }
    }
    },
    "proofs": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "01e18ca03d2ef0238a6a2460a222e0b818406bda99d4c05502c80232013559b926d1c8bca6bf65386f54a847d7850cb76c0c5fd5e633c34c749b8b9958a638d806"
    }
    ]
    }
    }
    }
    }

    -

    chain_get_block_transfers

    -

    This method returns all successful native transfers within a given Block from a network.

    +

    chain_get_block_transfers

    +

    This method returns all successful native transfers within a given Block from a network. If you do not specify a block_identifier, you will receive the transfers from the most recent block.

    @@ -84,10 +84,10 @@

    ch -
    ParameterTypeDescription
    block_identifierObjectThe Block hash.
    +
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_block_transfers request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block_transfers",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_block_transfers",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    chain_get_block_transfers_result

    @@ -115,12 +115,12 @@

    block_hashObjectThe Block hash, if found.transfersArrayThe Block's successful transfers, if found. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    block_hashObjectThe Block hash, if found. (Optional)
    transfersArrayThe Block's successful transfers, if found. (Optional)
    Example chain_get_block_transfers result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "transfers": [
    {
    "amount": "0",
    "deploy_hash": "0000000000000000000000000000000000000000000000000000000000000000",
    "from": "account-hash-0000000000000000000000000000000000000000000000000000000000000000",
    "gas": "0",
    "id": null,
    "source": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",
    "target": "uref-0000000000000000000000000000000000000000000000000000000000000000-000",
    "to": null
    }
    ]
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_block_transfers_result",
    "value": {
    "api_version": "2.0.0",
    "block_hash": "0707070707070707070707070707070707070707070707070707070707070707",
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ]
    }
    }
    }

    -

    chain_get_era_summary

    +

    chain_get_era_summary

    This method returns the era summary at a given Block. If you do not specify a block_identifier, you will receive the era summary at the highest state root hash.

    @@ -140,7 +140,7 @@

    chain_
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_era_summary request
    -

    {
    "id": 1,
    "jsonrpc":"2.0",
    "method":"chain_get_era_summary",
    "params": [
    {
    "Hash":"9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8"
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc":"2.0",
    "method":"chain_get_era_summary",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    chain_get_era_summary_result

    @@ -163,12 +163,12 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.era_summaryObjectThe era summary (if found). +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary, if found. (Optional)
    Example chain_get_era_summary result
    -

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "api_version": "1.0.0",
    "era_summary": {
    "block_hash": "9bfa58709058935882a095ca6adf844b72a2ddf0f49b8575ef1ceda987452fb8",
    "era_id": 1,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff",
    "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",
    "amount": "53472520551166781393617756"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b",
    "amount": "54552773491594393138943367"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "01264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5",
    "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",
    "amount": "51312014670568117976319374"
    }
    },
    {
    "Validator": {
    "validator_public_key": "013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c18726",
    "amount": "56713279372733183026458256"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db",
    "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",
    "amount": "51852141140784624481333262"
    }
    },
    {
    "Validator": {
    "validator_public_key": "0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f12",
    "amount": "56173152902516676521444368"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "0161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b",
    "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",
    "amount": "52392267611001130986347150"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b",
    "amount": "55633026432300170016430480"
    }
    },
    {
    "Delegator": {
    "delegator_public_key": "01b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c60",
    "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",
    "amount": "52932394080952975520954950"
    }
    },
    {
    "Validator": {
    "validator_public_key": "01dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f",
    "amount": "55092899961808199011606173"
    }
    }
    ]
    }
    },
    "state_root_hash": "918abd1973171867e03c1e6e56fd7dd9da35c92461784f9a15c0df23e437d850",
    "merkle_proof": "010000000e0000000000000000000000000000000000000000000000000000000000000000070a0000000101c08939bf1ecd1139448d435989a761c975466d30b96c2dd74e9d23c7b12bc9ff01039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b5c4316483512c2253f3b2c0001039c258651e04597d786142d9749922245cf44b6cc0c93c58bd6c1783ac3be9b0b87d59268bf17d8c6ff1f2d0101264689a5b4c57dac1088cd0aae8074de105f2269f6041e2c120e80df7a95e6b5013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b8e45261378f096e3bd712a00013e193dec433a73a0b41b924243c62311689648a10b4468f9c609c75674c187260b90eee69bba24050981e92e01016f571eaf1d3a442e684ecdb31d00a51448dcbaa06d00b340983311f0ba3e76db0186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b0ef09fedb1f521341ee42a000186d12379939682ae9669b354f7a637ec106369074d567b969cc0e2127c904f120b10446dc1801f7ab820772e010161e7ed5c592f16b507b9dd196662b530f9bde6c5b2cfd957fe8d0700ecfbe20b01d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b8e9a19c8ebfaac847e562b0001d4cbef55ed9968171102aa136c9564286211ee46c5ab65b6fd68fab5b14d4c4b0b9099f3e6461aef67c0042e0101b1339a1d114036d84d7b65c804669166d38456114657abbb0e53e67bf1667c6001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b46fad737700f37d5dec82b0001dbce10c8418c21daf16bc1052a486cdb557ba66b09a84605bc1f4b3df364960f0b9d1ed178841a631760922d01000000000e060000000001fb7043fe388fef916937aa899a0dda9b042168149e600fb068ecb16839d545d60101a0676758b903440b28c8f4a1d46404e9879fcfc0b90dad20962536de493aecc302013584bc9d5c00ac639fe14410b4cfa480b12eddd8f3dce08d7b76ae47977c1c680601664224aca1272e2a5632da4a56399dee6c585318ebbb7bb4040039792d3ad33c07013b48237cd26eb35ec3c864e1ae250ca656d00893de1dfc4c951e0d779adeda1d0a002c722cac61792676eb19d773fd3c41e37a63f54f78bdf7712ca96a5c5e5c4986"
    }
    }
    }

    +

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "chain_get_era_summary_result",
    "value": {
    "api_version": "2.0.0",
    "era_summary": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "era_id": 42,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "1000"
    }
    },
    {
    "Validator": {
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "2000"
    }
    }
    ]
    }
    },
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }
    }

    -

    chain_get_state_root_hash

    +

    chain_get_state_root_hash

    This method returns a state root hash at a given Block. If you do not specify a block_identifier, you will receive the highest state root hash.

    @@ -188,7 +188,7 @@

    ch
    ParameterTypeDescription
    block_identifierObjectThe Block hash. (Optional)
    Example chain_get_state_root_hash request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_state_root_hash",
    "params": [
    {
    "Height": 10
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_state_root_hash",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Height": 10
    }
    }
    ]
    }

    chain_get_state_root_hash_result

    @@ -214,13 +214,13 @@

    state_root_hashStringHex-encoded hash of the state root.
    Example chain_get_state_root_hash result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_state_root_hash_result",
    "value": {
    "api_version": "2.0.0",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808"
    }
    }
    }

    -

    info_get_chainspec

    -

    This method returns raw bytes for chainspec files.

    +

    info_get_chainspec

    +

    This method returns the raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.

    Example info_get_chainspec request
    -

    {
    "jsonrpc": "2.0",
    "method": "info_get_chainspec",
    "id": 5510244237763930243
    }

    +

    {
    "id": 5510244237763930243,
    "jsonrpc": "2.0",
    "method": "info_get_chainspec",
    "params": []
    }

    info_get_chainspec_result

    @@ -247,10 +247,11 @@

    Example info_get_chainspec result

    Please note that adding a --vv flag will return the full chainspec bytes.

    -

    {
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.5.0",
    "chainspec_bytes": {
    "chainspec_bytes": "[22040 hex chars]",
    "maybe_genesis_accounts_bytes": null,
    "maybe_global_state_bytes": null
    }
    },
    "id": 5510244237763930243
    }

    +

    {
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_chainspec_result",
    "value": {
    "api_version": "2.0.0",
    "chainspec_bytes": {
    "chainspec_bytes": "[22040 hex chars]",
    "maybe_genesis_accounts_bytes": null,
    "maybe_global_state_bytes": null
    }
    }
    },
    "id": 5510244237763930243
    }

    -

    info_get_deploy

    -

    This method retrieves a Deploy from a network. It requires a deploy_hash to query the Deploy.

    +

    info_get_deploy

    +
    caution

    DEPRECATED: Use info_get_transaction instead.

    +

    This method retrieves a Deploy from a network. It requires a deploy_hash to query the Deploy.

    @@ -274,11 +275,11 @@

    info_get_dep
    ParameterTypeDescription
    deploy_hashStringThe Deploy hash.
    finalized_approvalsBooleanDetermines whether to return the Deploy with the finalized approvals substituted. (Optional)
    Example info_get_deploy request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_deploy",
    "params": [
    "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    true
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_deploy",
    "params": [
    {
    "name": "deploy_hash",
    "value": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    },
    {
    "name": "finalized_approvals",
    "value": true
    }
    ]
    }

    info_get_deploy_result

    The response contains the Deploy and the results of executing the Deploy.

    -

    If the execution_results field is empty, it means that the network processed the Deploy, but has yet to execute it. If the network executed the Deploy, it will return the results of the execution. The execution results contain the Block hash which contains the Deploy.

    +

    If the execution_info field is empty, it means that the network processed the Deploy, but has yet to execute it. If the network executed the Deploy, it will return the results of the execution. The execution results contain the Block hash which contains the Deploy.

    @@ -304,12 +305,135 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.deployObjectThe Deploy.execution_resultsArrayAn array of execution results with Block hashes. +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    deployObjectThe Deploy.
    execution_infoArrayAn array of execution results with Block hashes, if found. (Optional)
    Example info_get_deploy result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy": {
    "approvals": [
    {
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007",
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    ],
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "chain_name": "casper-example",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "gas_price": 1,
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h"
    },
    "payment": {
    "StoredContractByName": {
    "args": [
    [
    "amount",
    {
    "bytes": "e8030000",
    "cl_type": "I32",
    "parsed": 1000
    }
    ]
    ],
    "entry_point": "example-entry-point",
    "name": "casper-example"
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "bytes": "e8030000",
    "cl_type": "I32",
    "parsed": 1000
    }
    ]
    ]
    }
    }
    },
    "execution_results": [
    {
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "result": {
    "Success": {
    "cost": "123456",
    "effect": {
    "operations": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": "Write"
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Read"
    }
    ],
    "transforms": [
    {
    "key": "uref-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb-007",
    "transform": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "transform": "Identity"
    }
    ]
    },
    "transfers": [
    "transfer-5959595959595959595959595959595959595959595959595959595959595959",
    "transfer-8282828282828282828282828282828282828282828282828282828282828282"
    ]
    }
    }
    }
    ]
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_deploy_result",
    "value": {
    "api_version": "2.0.0",
    "deploy": {
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "gas_price": 1,
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "chain_name": "casper-example"
    },
    "payment": {
    "StoredContractByName": {
    "name": "casper-example",
    "entry_point": "example-entry-point",
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"
    }
    ]
    },
    "execution_info": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "block_height": 10,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "error_message": null,
    "limit": "123456",
    "consumed": "100000",
    "cost": "246912",
    "payment": [
    {
    "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"
    }
    ],
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ],
    "size_estimate": 186,
    "effects": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Identity"
    }
    ]
    }
    }
    }
    }
    }
    }

    +
    +

    info_get_reward

    +

    This method returns the reward for a given era and a validator or delegator.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    validatorStringThe public key of the validator.
    era_identifierObjectThe era identifier. If None, the last finalized era is used. (Optional)
    delegatorStringThe public key of the delegator. If Some, the rewards for the delegator are returned. If None, the rewards for the validator are returned. (Optional)
    +
    Example info_get_reward request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_reward",
    "params": [
    {
    "name": "era_identifier",
    "value": {
    "Era": 1
    }
    },
    {
    "name": "validator",
    "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    {
    "name": "delegator",
    "value": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    ],
    }

    +
    +

    info_get_reward_result

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_idIntegerThe era for which the reward was calculated.
    reward_amountIntegerThe total reward amount in the requested era.
    +
    Example info_get_reward result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_reward_result",
    "value": {
    "api_version": "2.0.0",
    "reward_amount": "42",
    "era_id": 1
    }
    }

    -

    query_balance

    +

    info_get_transaction

    +

    This method retrieves a transaction from a network. It requires a transaction_hash to query the Deploy.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    transaction_hashStringThe transaction hash.
    finalized_approvalsBooleanDetermines whether to return the transaction with the finalized approvals substituted. (Optional)
    +
    Example info_get_transaction request
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_transaction",
    "params": [
    {
    "name": "transaction_hash",
    "value": {
    "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"
    }
    },
    {
    "name": "finalized_approvals",
    "value": true
    }
    ],
    }

    +
    +

    info_get_transaction_result

    +

    The response contains the transaction and the results of executing it on the network.

    +

    If the execution_info field is empty, it means that the network processed the transaction but has yet to execute it. If the network executed the transaction, it will return the execution information, along with the block hash containing the transaction.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    transactionObjectThe transaction.
    execution_infoArrayAn array of execution results with Block hashes, if found. (Optional)
    +
    Example info_get_transaction result
    + +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_transaction_result",
    "value": {
    "api_version": "2.0.0",
    "transaction": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    },
    "execution_info": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "block_height": 10,
    "execution_result": {
    "Version2": {
    "initiator": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "error_message": null,
    "limit": "123456",
    "consumed": "100000",
    "cost": "246912",
    "payment": [
    {
    "source": "uref-0101010101010101010101010101010101010101010101010101010101010101-001"
    }
    ],
    "transfers": [
    {
    "Version2": {
    "transaction_hash": {
    "Version1": "0101010101010101010101010101010101010101010101010101010101010101"
    },
    "from": {
    "AccountHash": "account-hash-0202020202020202020202020202020202020202020202020202020202020202"
    },
    "to": "account-hash-0303030303030303030303030303030303030303030303030303030303030303",
    "source": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007",
    "target": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000",
    "amount": "1000000000000",
    "gas": "2500000000",
    "id": 999
    }
    }
    ],
    "size_estimate": 186,
    "effects": [
    {
    "key": "account-hash-2c4a11c062a8a337bfc97e27fd66291caeb2c65865dcb5d3ef3759c4c97efecb",
    "kind": {
    "AddUInt64": 8
    }
    },
    {
    "key": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
    "kind": "Identity"
    }
    ]
    }
    }
    }
    }
    }
    }

    +
    +

    query_balance

    This method allows you to query for the balance of a purse using a PurseIdentifier and StateIdentifier.

    @@ -331,10 +455,10 @@

    query_balance< -
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used.
    +
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    Example query_balance request
    -
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    +
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    query_balance_result

    @@ -360,9 +484,77 @@

    q
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    balanceObjectThe balance represented in motes.
    Example query_balance result
    -

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "api_version": "1.0.0",
    "balance": "1000000000000000000000000000000000"
    }
    }

    +

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "name": "query_balance_result",
    "value": {
    "api_version": "2.0.0",
    "balance": "123456"
    }
    }
    }

    -

    query_global_state

    +

    query_balance_details

    +

    This method allows you to query for full balance information using a PurseIdentifier and StateIdentifier.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    purse_identifierObjectThe identifier to obtain the purse corresponding to the balance query.
    state_identifierObjectThe state identifier used for the query; if none is passed the tip of the chain will be used. (Optional)
    +
    Example query_balance_details request
    + +
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "query_balance_details",
    "params": [
    {
    "name": "state_identifier",
    "value": {
    "BlockHash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    },
    {
    "name": "purse_identifier",
    "value": {
    "main_purse_under_account_hash": "account-hash-0909090909090909090909090909090909090909090909090909090909090909"
    }
    }
    ]
    }

    +
    +

    query_balance_details_result

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    available_balanceObjectThe available balance in motes (total balance - sum of all active holds).
    holdsArrayThe holds active at the requested point in time.
    total_balanceObjectThe purses total balance, not considering holds.
    `total_balance_proofStringA proof that the given value is present in the Merkle trie.
    +
    Example query_balance_details result
    + +

    {
    "jsonrpc": "2.0",
    "id": -6143675785141640608,
    "result": {
    "name": "query_balance_details_result",
    "value": {
    "api_version": "2.0.0",
    "total_balance": "123456",
    "available_balance": "123456",
    "total_balance_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "holds": [
    {
    "time": 0,
    "amount": "123456",
    "proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    ]
    }
    }
    }

    +
    +

    query_global_state

    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 or state root hash.

    • Note: Querying a purse's balance requires the use of query_balance, rather than any iteration of query_global_state.
    • @@ -392,10 +584,10 @@

      query_glo -
      ParameterTypeDescription
      state_identifierObjectThe identifier used for the query.
      keyStringcasper_types::Key as a formatted string.
      pathArrayThe path components starting from the key as base.
      +
      ParameterTypeDescription
      keyStringThe key as a formatted string, under which data can be stored in global state.
      state_identifierObjectThe identifier used for the query. If not provided, the tip of the chain will be used. (Optional)
      pathArrayThe path components starting from the key as base. (Optional)
      Example query_global_state request
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "query_global_state",
      "params": [
      "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1",
      [],
      {
      "BlockHash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
      }
      ]
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "query_global_state",
      "params": [
      {
      "name": "state_identifier",
      "value": {
      "BlockHash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
      }
      },
      {
      "name": "key",
      "value": "deploy-af684263911154d26fa05be9963171802801a0b6aff8f199b7391eacb8edc9e1"
      },
      {
      "name": "path",
      "value": []
      }
      ]
      }

      query_global_state_result

      @@ -428,13 +620,13 @@

      ParameterTypeDescriptionapi_versionStringThe RPC API version.block_headerObjectThe Block header if a Block hash was provided. (Not required)stored_valueObjectThe stored value.merkle_proofStringThe merkle proof. +
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      block_headerObjectThe Block header if a Block hash was provided. (Optional)
      stored_valueObjectThe stored value.
      merkle_proofStringThe merkle proof.
      Example query_global_state result
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.4.13",
      "block_header": {
      "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
      "body_hash": "cd502c5393a3c8b66d6979ad7857507c9baf5a8ba16ba99c28378d3a970fff42",
      "era_end": {
      "era_report": {
      "equivocators": [
      "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
      ],
      "inactive_validators": [
      "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
      ],
      "rewards": [
      {
      "amount": 1000,
      "validator": "018a88e3dd7409f195fd52db2d3cba5d72ca6709bf1d94121bf3748801b40f6f5c"
      }
      ]
      },
      "next_era_validator_weights": [
      {
      "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
      "weight": "456"
      },
      {
      "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
      "weight": "789"
      },
      {
      "validator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
      "weight": "123"
      }
      ]
      },
      "era_id": 1,
      "height": 10,
      "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
      "protocol_version": "1.0.0",
      "random_bit": true,
      "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
      "timestamp": "2020-11-17T00:39:24.072Z"
      },
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
      "stored_value": {
      "Account": {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "action_thresholds": {
      "deployment": 1,
      "key_management": 1
      },
      "associated_keys": [
      {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "weight": 1
      }
      ],
      "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "named_keys": []
      }
      }
      }
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "2.0.0",
      "block_header": {
      "Version2": {
      "parent_hash": "0707070707070707070707070707070707070707070707070707070707070707",
      "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
      "body_hash": "0505050505050505050505050505050505050505050505050505050505050505",
      "random_bit": true,
      "accumulated_seed": "ac979f51525cfd979b14aa7dc0737c5154eabe0db9280eceaa8dc8d2905b20d5",
      "era_end": {
      "equivocators": [
      "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
      ],
      "inactive_validators": [
      "018139770ea87d175f56a35466c34c7ecccb8d8a91b4ee37a25df60f5b8fc9b394"
      ],
      "next_era_validator_weights": [
      {
      "validator": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
      "weight": "123"
      },
      {
      "validator": "016e7a1cdd29b0b78fd13af4c5598feff4ef2a97166e3ca6f2e4fbfccd80505bf1",
      "weight": "456"
      },
      {
      "validator": "018a875fff1eb38451577acd5afee405456568dd7c89e090863a0557bc7af49f17",
      "weight": "789"
      }
      ],
      "rewards": {},
      "next_era_gas_price": 1
      },
      "timestamp": "2020-11-17T00:39:24.072Z",
      "era_id": 1,
      "height": 10,
      "protocol_version": "1.0.0",
      "proposer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
      "current_gas_price": 1,
      "last_switch_block_hash": "0909090909090909090909090909090909090909090909090909090909090909"
      }
      },
      "stored_value": {
      "Account": {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "named_keys": [
      {
      "name": "main_purse",
      "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
      }
      ],
      "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "associated_keys": [
      {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "weight": 1
      }
      ],
      "action_thresholds": {
      "deployment": 1,
      "key_management": 1
      }
      }
      },
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
      }
      }

      -

      state_get_account_info

      -

      This method returns a JSON representation of an Account from the network. The block_identifier must refer to a Block after the Account's creation, or the method will return an empty response.

      +

      state_get_account_info

      +

      This method returns a JSON representation of an Account from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the account at the highest state root hash. The block_identifier must refer to a Block after the Account's creation, or the method will return an empty response.

      @@ -455,10 +647,10 @@

      state -
      ParameterTypeDescription
      public_keyStringThe public key of the Account.
      block_identifierObjectThe Block identifier.
      +
      ParameterTypeDescription
      account_identifierStringThe public key or account hash of the Account.
      block_identifierObjectThe Block hash. (Optional)
      Example state_get_account_info request
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "state_get_account_info",
      "params": [
      {
      "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
      },
      "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
      ]
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "state_get_account_info",
      "params": [
      {
      "name": "account_identifier",
      "value": "013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
      },
      {
      "name": "block_identifier",
      "value": {
      "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
      }
      }
      ]
      }

      state_get_account_info_result

      @@ -486,12 +678,12 @@

      accountObjectA JSON representation of the Account structure.merkle_proofStringThe merkle proof. +
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      accountObjectA JSON representation of the Account structure.
      merkle_proofStringThe merkle proof.
      Example state_get_account_info result
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "account": {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "action_thresholds": {
      "deployment": 1,
      "key_management": 1
      },
      "associated_keys": [
      {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "weight": 1
      }
      ],
      "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "named_keys": []
      },
      "api_version": "1.4.13",
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
      }
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "name": "state_get_account_info_result",
      "value": {
      "api_version": "2.0.0",
      "account": {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "named_keys": [
      {
      "name": "main_purse",
      "key": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
      }
      ],
      "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "associated_keys": [
      {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "weight": 1
      }
      ],
      "action_thresholds": {
      "deployment": 1,
      "key_management": 1
      }
      },
      "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.

      You may query a stored value directly using the dictionary address.

      @@ -517,7 +709,7 @@

      st
      ParameterTypeDescription
      state_root_hashStringHash of the state root.
      dictionary_identifierObjectThe Dictionary query identifier.
      Example state_get_dictionary_item request
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "state_get_dictionary_item",
      "params": [
      {
      "URef": {
      "dictionary_item_key": "a_unique_entry_identifier",
      "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007"
      }
      },
      "0808080808080808080808080808080808080808080808080808080808080808"
      ]
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "state_get_dictionary_item",
      "params": [
      {
      "name": "state_root_hash",
      "value": "0808080808080808080808080808080808080808080808080808080808080808"
      },
      {
      "name": "dictionary_identifier",
      "value": {
      "URef": {
      "seed_uref": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "dictionary_item_key": "a_unique_entry_identifier"
      }
      }
      }
      ]
      }

      state_get_dictionary_item_result

      @@ -553,17 +745,75 @@

      stored_valueObjectThe stored value.merkle_proofStringThe merkle proof.
      Example state_get_dictionary_item result
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.4.13",
      "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
      "stored_value": {
      "CLValue": {
      "bytes": "0100000000000000",
      "cl_type": "U64",
      "parsed": 1
      }
      }
      }
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "name": "state_get_dictionary_item_result",
      "value": {
      "api_version": "2.0.0",
      "dictionary_key": "dictionary-67518854aa916c97d4e53df8570c8217ccc259da2721b692102d76acd0ee8d1f",
      "stored_value": {
      "CLValue": {
      "cl_type": "U64",
      "bytes": "0100000000000000",
      "parsed": 1
      }
      },
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
      }
      }
      }

      +
      +

      state_get_entity

      +

      This method returns a JSON representation of an AddressableEntity from the network at a given Block. If you do not specify a block_identifier, you will receive the state of the entity at the highest state root hash. The block_identifier must refer to a Block after the entity's creation, or the method will return an empty response.

      + + + + + + + + + + + + + + + + + + + + +
      ParameterTypeDescription
      entity_identifierStringIdentifier of an addressable entity.
      block_identifierObjectThe Block hash. (Optional)
      +
      Example state_get_entity request
      + +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "state_get_entity",
      "params": [
      {
      "name": "entity_identifier",
      "value": {
      "EntityAddr": "entity-account-0000000000000000000000000000000000000000000000000000000000000000"
      }
      },
      {
      "name": "block_identifier",
      "value": {
      "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
      }
      }
      ]
      }

      +
      +

      state_get_entity_result

      + + + + + + + + + + + + + + + + + + + + + + + + + +
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      entityObjectA JSON representation of the AddressableEntity.
      merkle_proofStringThe merkle proof.
      +
      Example state_get_entity result
      + +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "name": "state_get_entity_result",
      "value": {
      "api_version": "2.0.0",
      "entity": {
      "AddressableEntity": {
      "entity": {
      "protocol_version": "2.0.0",
      "entity_kind": {
      "Account": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c"
      },
      "package_hash": "package-0000000000000000000000000000000000000000000000000000000000000000",
      "byte_code_hash": "byte-code-0000000000000000000000000000000000000000000000000000000000000000",
      "main_purse": "uref-09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db-007",
      "associated_keys": [
      {
      "account_hash": "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c",
      "weight": 1
      }
      ],
      "action_thresholds": {
      "deployment": 1,
      "upgrade_management": 1,
      "key_management": 1
      },
      "message_topics": [
      {
      "topic_name": "topic",
      "topic_name_hash": "0000000000000000000000000000000000000000000000000000000000000000"
      }
      ]
      },
      "named_keys": [
      {
      "name": "key",
      "key": "hash-0000000000000000000000000000000000000000000000000000000000000000"
      }
      ],
      "entry_points": [
      {
      "V1CasperVm": {
      "name": "entry_point",
      "args": [],
      "ret": "Unit",
      "access": "Public",
      "entry_point_type": "Caller",
      "entry_point_payment": "Caller"
      }
      }
      ]
      }
      },
      "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
      }
      }
      }


      Node Informational JSON-RPC Methods

      The following methods return information from a node on a Casper network. The responses return information specific to the queried node, and as such, will vary.


      -

      info_get_peers

      +

      info_get_peers

      This method returns a list of peers connected to the node.

      Example info_get_peers request
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "info_get_peers",
      "params": []
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "info_get_peers",
      "params": []
      }

      info_get_peers_result

      @@ -586,16 +836,16 @@

      -
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      peersArrayThe node ID and network address of each connected peer.
      +
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      peersArrayThe node ID and network address of each connected peer.
      Example info_get_peers result
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.4.13",
      "peers": [
      {
      "address": "127.0.0.1:54321",
      "node_id": "tls:0101..0101"
      }
      ]
      }
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "name": "info_get_peers_result",
      "value": {
      "api_version": "2.0.0",
      "peers": [
      {
      "node_id": "tls:0101..0101",
      "address": "127.0.0.1:54321"
      }
      ]
      }
      }
      }

      -

      info_get_status

      +

      info_get_status

      This method returns the current status of a node.

      Example info_get_status request
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "info_get_status",
      "params": []
      }

      +

      {
      "id": 1,
      "jsonrpc": "2.0",
      "method": "info_get_status",
      "params": []
      }

      info_get_status_result

      @@ -678,10 +928,15 @@

      ParameterTypeDescriptionapi_versionStringThe RPC API version.available_block_rangeObjectThe available block range in storage.block_syncObjectThe status of the block synchronizer builders.build_versionStringThe compiled node version.chainspec_nameStringThe chainspec name, used to identify the currently connected network.last_added_block_infoObjectThe minimal info of the last Block from the linear chain.last_progressStringTimestamp of the last recorded progress in the reactor.next_upgradeObjectInformation about the next scheduled upgrade.our_public_signing_keyStringOur public signing key.peersArrayThe node ID and network address of each connected peer.reactor_stateStringThe current state of the node reactor.round_lengthIntegerThe next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block.starting_state_root_hashStringThe state root hash used at the start of the current session.uptimeIntegerTime that passed since the node has started. + + + + + +
      ParameterTypeDescription
      api_versionStringThe RPC API version.
      available_block_rangeObjectThe available block range in storage.
      block_syncObjectThe status of the block synchronizer builders.
      build_versionStringThe compiled node version.
      chainspec_nameStringThe chainspec name, used to identify the currently connected network.
      last_added_block_infoObjectThe minimal info of the last Block from the linear chain. (Optional)
      last_progressStringTimestamp of the last recorded progress in the reactor.
      latest_switch_block_hashObjectThe hash of the latest switch block. (Optional)
      next_upgradeObjectInformation about the next scheduled upgrade. (Optional)
      our_public_signing_keyStringOur public signing key. (Optional)
      peersArrayThe node ID and network address of each connected peer.
      reactor_stateStringThe current state of the node reactor.
      round_lengthIntegerThe next round length if this node is a validator. A round length is the amount of time it takes to reach consensus on proposing a Block. (Optional)
      starting_state_root_hashStringThe state root hash used at the start of the current session.
      uptimeIntegerTime that passed since the node has started.
      Example info_get_status result
      -

      {
      "id": 1,
      "jsonrpc": "2.0",
      "result": {
      "name": "info_get_status_result",
      "value": {
      "peers": [
      {
      "node_id": "tls:0101..0101",
      "address": "127.0.0.1:54321"
      }
      ],
      "api_version": "1.4.8",
      "build_version": "1.0.0-xxxxxxxxx@DEBUG",
      "chainspec_name": "casper-example",
      "starting_state_root_hash": null,
      "last_added_block_info": {
      "hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
      "timestamp": "2020-11-17T00:39:24.072Z",
      "era_id": 1,
      "height": 10,
      "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
      "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
      },
      "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
      "round_length": "1m 5s 536ms",
      "next_upgrade": {
      "activation_point": 42,
      "protocol_version": "2.0.1"
      },
      "uptime": "13s",
      "reactor_state": "Initialize",
      "last_progress": "1970-01-01T00:00:00.000Z",
      "available_block_range": {
      "low": 0,
      "high": 0
      },
      "block_sync": {
      "historical": {
      "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",
      "block_height": 40,
      "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"
      },
      "forward": {
      "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",
      "block_height": 6701,
      "acquisition_state": "have block body(6701) for: block hash 5990..4983"
      }
      }
      }
      }

      -

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_status_result",
    "value": {
    "api_version": "2.0.0",
    "peers": [
    {
    "node_id": "tls:0101..0101",
    "address": "127.0.0.1:54321"
    }
    ],
    "build_version": "1.0.0-xxxxxxxxx@DEBUG",
    "chainspec_name": "casper-example",
    "starting_state_root_hash": "0000000000000000000000000000000000000000000000000000000000000000",
    "last_added_block_info": {
    "hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "era_id": 1,
    "height": 10,
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "creator": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    },
    "our_public_signing_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "round_length": "1m 5s 536ms",
    "next_upgrade": {
    "activation_point": 42,
    "protocol_version": "2.0.1"
    },
    "uptime": "13s",
    "reactor_state": "Initialize",
    "last_progress": "1970-01-01T00:00:00.000Z",
    "available_block_range": {
    "low": 0,
    "high": 0
    },
    "block_sync": {
    "historical": {
    "block_hash": "16ddf28e2b3d2e17f4cef36f8b58827eca917af225d139b0c77df3b4a67dc55e",
    "block_height": 40,
    "acquisition_state": "have strict finality(40) for: block hash 16dd..c55e"
    },
    "forward": {
    "block_hash": "59907b1e32a9158169c4d89d9ce5ac9164fc31240bfcfb0969227ece06d74983",
    "block_height": 6701,
    "acquisition_state": "have block body(6701) for: block hash 5990..4983"
    }
    },
    "latest_switch_block_hash": "0000000000000000000000000000000000000000000000000000000000000000"
    }
    }
    }
    }

    +
    \ No newline at end of file diff --git a/developers/json-rpc/json-rpc-pos/index.html b/developers/json-rpc/json-rpc-pos/index.html index 34d437bf5..f20253957 100644 --- a/developers/json-rpc/json-rpc-pos/index.html +++ b/developers/json-rpc/json-rpc-pos/index.html @@ -1,25 +1,25 @@ - + -Proof-of-Stake JSON-RPC Methods | Casper Docs - Redux +Proof-of-Stake JSON-RPC Methods | Casper Docs - Redux - - + +
    Version: 1.5.X

    Proof-of-Stake JSON-RPC Methods

    + submit an issue on Github
    Version: Next

    Proof-of-Stake JSON-RPC Methods

    The following methods pertain to the Proof-of-Stake functionality of a Casper network. They return information related to auctions, bids and validators. This information is necessary for users involved with node operations and validation.


    -

    state_get_auction_info

    -

    This method returns the bids and validators as of either a specific Block (by height or hash). If you do not provide a block_identifier, state_get_auction_info will return information from the most recent Block.

    +

    state_get_auction_info

    +

    This method returns the bids and validators from a specific Block (by height or hash). If you do not provide a block_identifier, state_get_auction_info will return information from the most recent Block.

    @@ -35,10 +35,10 @@

    state -
    ParameterTypeDescription
    block_identifierObjectThe Block identifier.
    +
    ParameterTypeDescription
    block_identifierObjectThe Block identifier. (Optional)
    Example state_get_auction_info request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_auction_info",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "state_get_auction_info",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0707070707070707070707070707070707070707070707070707070707070707"
    }
    }
    ]
    }

    state_get_auction_info_result

    @@ -64,9 +64,9 @@

    auction_stateObjectThe auction state.
    Example state_get_auction_info result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "auction_state": {
    "bids": [
    {
    "bid": {
    "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",
    "delegation_rate": 0,
    "delegators": [],
    "inactive": false,
    "staked_amount": "10"
    },
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61"
    }
    ],
    "block_height": 10,
    "era_validators": [
    {
    "era_id": 10,
    "validator_weights": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "weight": "10"
    }
    ]
    }
    ],
    "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"
    }
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "state_get_auction_info_result",
    "value": {
    "api_version": "2.0.0",
    "auction_state": {
    "state_root_hash": "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
    "block_height": 10,
    "era_validators": [
    {
    "era_id": 10,
    "validator_weights": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "weight": "10"
    }
    ]
    }
    ],
    "bids": [
    {
    "public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "bid": {
    "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "bonding_purse": "uref-fafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafafa-007",
    "staked_amount": "20",
    "delegation_rate": 0,
    "vesting_schedule": null,
    "delegators": [
    {
    "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",
    "delegator": {
    "delegator_public_key": "014508a07aa941707f3eb2db94c8897a80b2c1197476b6de213ac273df7d86c4ff",
    "staked_amount": "10",
    "bonding_purse": "uref-fbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfbfb-007",
    "validator_public_key": "01197f6b23e16c8532c6abc838facd5ea789be0c76b2920334039bfa8b3d368d61",
    "vesting_schedule": null
    }
    }
    ],
    "inactive": false
    }
    }
    ]
    }
    }
    }
    }

    -

    info_get_validator_changes

    +

    info_get_validator_changes

    This method returns status changes of active validators. Listed changes occurred during the EraId contained within the response itself. A validator may show more than one change in a single era.

    Potential change types:

    @@ -101,7 +101,7 @@

    i
    Change TypeDescription
    AddedThe validator has been added to the set.
    RemovedThe validator has been removed from the set.
    BannedThe validator has been banned in the current era.
    CannotProposeThe validator cannot propose a Block.
    SeenAsFaultyThe validator has performed questionable activity.
    Example info_get_validator_changes request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_validator_changes",
    "params": []
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "info_get_validator_changes",
    "params": []
    }

    info_get_validator_changes_result

    If no changes occurred in the current era, info_get_validator_changes will return empty.

    @@ -128,7 +128,7 @@

    changesObjectThe validators' status changes.
    Example info_get_validator_changes result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "changes": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "status_changes": [
    {
    "era_id": 1,
    "validator_change": "Added"
    }
    ]
    }
    ]
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "info_get_validator_changes_result",
    "value": {
    "api_version": "2.0.0",
    "changes": [
    {
    "public_key": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "status_changes": [
    {
    "era_id": 1,
    "validator_change": "Added"
    }
    ]
    }
    ]
    }
    }
    }

    chain_get_era_info_by_switch_block

    This method returns an EraInfo from the network. Only the last Block in an era, known as a switch block, will contain an era_summary.

    @@ -150,7 +150,7 @@

    block_identifierObjectThe Block identifier. If you do not supply a block_identifier, the returned information will be the most recent Block. (Optional)
    Example chain_get_era_info_by_switch_block request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_era_info_by_switch_block",
    "params": [
    {
    "Hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb"
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "chain_get_era_info_by_switch_block",
    "params": [
    {
    "name": "block_identifier",
    "value": {
    "Hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42"
    }
    }
    ]
    }

    chain_get_era_info_by_switch_block_result

    @@ -173,10 +173,10 @@

    era_summaryObjectThe era summary (If found). +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    era_summaryObjectThe era summary, if found. (Optional)
    Example chain_get_era_info_by_switch_block
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "era_summary": {
    "block_hash": "13c2d7a68ecdd4b74bf4393c88915c836c863fc4bf11d7f2bd930a1bbccacdcb",
    "era_id": 42,
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3",
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "amount": "1000",
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"
    }
    },
    {
    "Validator": {
    "amount": "2000",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876"
    }
    }
    ]
    }
    }
    }
    }
    }

    -

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "chain_get_era_info_by_switch_block_result",
    "value": {
    "api_version": "2.0.0",
    "era_summary": {
    "block_hash": "0744fcb72af43c5cc372039bc5a8bfee48808a9ce414acc0d6338a628c20eb42",
    "era_id": 42,
    "stored_value": {
    "EraInfo": {
    "seigniorage_allocations": [
    {
    "Delegator": {
    "delegator_public_key": "01e1b46a25baa8a5c28beb3c9cfb79b572effa04076f00befa57eb70b016153f18",
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "1000"
    }
    },
    {
    "Validator": {
    "validator_public_key": "012a1732addc639ea43a89e25d3ad912e40232156dcaa4b9edfc709f43d2fb0876",
    "amount": "2000"
    }
    }
    ]
    }
    },
    "state_root_hash": "0808080808080808080808080808080808080808080808080808080808080808",
    "merkle_proof": "01000000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625016ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a72536147614625000000003529cde5c621f857f75f3810611eb4af3f998caaa9d4a3413cf799f99c67db0307010000006ef2e0949ac76e55812421f755abe129b6244fe7168b77f47a7253614761462501010102000000006e06000000000074769d28aac597a36a03a932d4b43e4f10bf0403ee5c41dd035102553f5773631200b9e173e8f05361b681513c14e25e3138639eb03232581db7557c9e8dbbc83ce94500226a9a7fe4f2b7b88d5103a4fc7400f02bf89c860c9ccdd56951a2afe9be0e0267006d820fb5676eb2960e15722f7725f3f8f41030078f8b2e44bf0dc03f71b176d6e800dc5ae9805068c5be6da1a90b2528ee85db0609cc0fb4bd60bbd559f497a98b67f500e1e3e846592f4918234647fca39830b7e1e6ad6f5b7a99b39af823d82ba1873d000003000000010186ff500f287e9b53f823ae1582b1fa429dfede28015125fd233a31ca04d5012002015cc42669a55467a1fdf49750772bfc1aed59b9b085558eb81510e9b015a7c83b0301e3cf4a34b1db6bfa58808b686cb8fe21ebe0c1bcbcee522649d2b135fe510fe3"
    }
    }
    }
    }

    +
    \ No newline at end of file diff --git a/developers/json-rpc/json-rpc-transactional/index.html b/developers/json-rpc/json-rpc-transactional/index.html index c5d7ac707..911dce598 100644 --- a/developers/json-rpc/json-rpc-transactional/index.html +++ b/developers/json-rpc/json-rpc-transactional/index.html @@ -1,24 +1,25 @@ - + -Transactional JSON-RPC Methods | Casper Docs - Redux +Transactional JSON-RPC Methods | Casper Docs - Redux - - + +
    Version: 1.5.X

    Transactional JSON-RPC Methods

    + submit an issue on Github
    Version: Next

    Transactional JSON-RPC Methods


    -

    account_put_deploy

    -

    This is the only means by which users can send their compiled Wasm (as part of a Deploy) to a node on a Casper network. The request takes in the Deploy as a parameter, prior to sending it to a node on a network for execution.

    +

    account_put_deploy

    +
    caution

    DEPRECATED: Use account_put_transaction instead.

    +

    This endpoint allows sending a deploy to be executed by the network.

    @@ -35,15 +36,12 @@

    account_p
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    -
    -

    Note: You can find a list of trusted peers in the network's configuration file, config.toml. Here is an example config.toml. You may send deploys to one of the trusted nodes or use them to query other online nodes.

    -
    Example account_put_deploy request
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": [
    {
    "approvals": [
    {
    "signer": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",
    "signature": "019d6ef5c62c80ad4e50df343fba6f0fced17dea4c65e7976f66335ffcfcde2a7f02e928c8507cef3c76c3151e0e9cc9c3f7838b9f7a99ac4be5522ca092841100"
    }
    ],
    "hash": "00a8677713222df88b6988926e0b14adeda6c663957f5075003395da4e5c6888",
    "header": {
    "account": "01f8b29f39c38600ecb3bbb082951e04ab63a4ad4f7c9048a5057e461a5a8d58a5",
    "body_hash": "145ae09d6da5bc290051db8cb7132a41a30473d5900eaaf409d92b666325ca00",
    "chain_name": "casper-net-1",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "gas_price": 1,
    "timestamp": "2023-09-26T14:07:10.024Z",
    "ttl": "1h"
    },
    "payment": {
    "StoredContractByName": {
    "args": [
    [
    "amount",
    {
    "bytes": "0400f90295",
    "cl_type": "U512"
    }
    ]
    ],
    "entry_point": "example-entry-point",
    "name": "casper-example"
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "09480c3248ef76b603d386f3f4f8a5f87f597d4eaffd475433f861af187ab5db07"
    }
    ]
    ]
    }
    }
    }
    ]
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_deploy",
    "params": [
    {
    "name": "deploy",
    "value": {
    "hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa",
    "header": {
    "account": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "gas_price": 1,
    "body_hash": "d53cf72d17278fd47d399013ca389c50d589352f1a12593c0b8e01872a641b50",
    "dependencies": [
    "0101010101010101010101010101010101010101010101010101010101010101"
    ],
    "chain_name": "casper-example"
    },
    "payment": {
    "StoredContractByName": {
    "name": "casper-example",
    "entry_point": "example-entry-point",
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "I32",
    "bytes": "e8030000",
    "parsed": 1000
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "014c1a89f92e29dd74fc648f741137d9caf4edba97c5f9799ce0c9aa6b0c9b58db368c64098603dbecef645774c05dff057cb1f91f2cf390bbacce78aa6f084007"
    }
    ]
    }
    }
    ]
    }

    account_put_deploy_result

    -

    The result contains the deploy_hash, which is the primary identifier of a Deploy within a Casper network.

    +

    The result contains the RPC API version and a deploy_hash, which is the primary identifier of a Deploy within a Casper network.

    @@ -67,11 +65,17 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.deploy_hashStringA hex-encoded hash of the Deploy as sent.
    Example account_put_deploy result
    -

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.13",
    "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    }
    }

    +

    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "account_put_deploy_result",
    "value": {
    "api_version": "2.0.0",
    "deploy_hash": "5c9b3b099c1378aa8e4a5f07f59ff1fcdc69a83179427c7e67ae0377d94d93fa"
    }
    }
    }

    -

    speculative_exec

    -

    The speculative_exec endpoint provides a method to execute a Deploy without committing its execution effects to global state. By default, speculative_exec is disabled on a node. Sending a request to a node with the endpoint disabled will result in an error message. If enabled, speculative_exec operates on a separate port from the primary JSON-RPC, using 7778.

    -

    speculative_exec executes a Deploy at a specified block. In the case of this endpoint, the execution effects are not committed to global state. As such, it can be used for observing the execution effects of a Deploy without paying for the execution of the Deploy.

    +

    account_put_transaction

    +

    This is the recommended means by which users can send their compiled Wasm (as part of a Transaction) to a node on a Casper network. The request takes in the transaction as a parameter, prior to sending it to a node on a network for execution.

    + + + + + + + @@ -80,6 +84,46 @@

    speculative +
    ParameterTypeDescription
    transactionObjectA transaction consists of an item containing a Deploy and a Transaction along with the requester's signature(s).
    +
    +

    Note: You can find a list of trusted peers in the network's configuration file, config.toml. Here is an example config.toml. You may send transactions to one of the trusted nodes or use them to query other online nodes.

    +
    +
    Example account_put_transaction request
    + +
    {
    "id": 1,
    "jsonrpc": "2.0",
    "method": "account_put_transaction",
    "params": [
    {
    "name": "transaction",
    "value": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    }
    }
    ],
    }

    +
    +

    account_put_transaction_result

    +

    The result contains the RPC API version and the transaction_hash, which is the primary identifier of a transaction within a Casper network.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    transaction_hashStringA hex-encoded hash of the transaction as sent.
    +
    Example account_put_transaction result
    + +
    {
    "id": 1,
    "jsonrpc": "2.0",
    "result": {
    "name": "account_put_transaction_result",
    "value": {
    "api_version": "2.0.0",
    "transaction_hash": {
    "Version1": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468"
    }
    }
    }
    }

    +
    +

    speculative_exec

    +
    caution

    DEPRECATED: Use speculative_exec_txn instead.

    +

    The speculative_exec endpoint allows executing a Deploy without committing its execution effects to global state. By default, speculative_exec is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778.

    + + @@ -92,13 +136,17 @@

    speculative -
    ParameterTypeDescription
    block_identifierObjectThe block hash or height on top of which to execute the deploy. If not supplied,the most recent block will be used.
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    + +
    ParameterTypeDescription
    deployObjectA Deploy consists of an item containing a smart contract along with the requester's signature(s).
    Example speculative_exec request
    -

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec",
    "params": {
    "block_identifier": null,
    "deploy": {
    "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",
    "header": {
    "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "timestamp": "2023-05-23T13:32:45.554Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",
    "dependencies": [],
    "chain_name": "integration-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400e1f505",
    "parsed": "100000000"
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",
    "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010000000000000000",
    "parsed": 0
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"
    }
    ]
    }
    },
    "id": 6889533540839698701
    }

    +

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec",
    "params": {
    "deploy": {
    "hash": "b6aa46333fb858deee7f259a5bca581251c6200a5d902aeb1244c3a7169b5971",
    "header": {
    "account": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "timestamp": "2023-05-23T13:32:45.554Z",
    "ttl": "30m",
    "gas_price": 1,
    "body_hash": "74db109805bb20de43ef89a5b084544a858908b236601519d5827cd9b7fbb925",
    "dependencies": [],
    "chain_name": "integration-test"
    },
    "payment": {
    "ModuleBytes": {
    "module_bytes": "",
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400e1f505",
    "parsed": "100000000"
    }
    ]
    ]
    }
    },
    "session": {
    "Transfer": {
    "args": [
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0400f90295",
    "parsed": "2500000000"
    }
    ],
    [
    "target",
    {
    "cl_type": "PublicKey",
    "bytes": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b",
    "parsed": "01265ea737411b349ad3d0fc724c2c588acd2765c057e5c690cd5e3dade401782b"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "010000000000000000",
    "parsed": 0
    }
    ]
    ]
    }
    },
    "approvals": [
    {
    "signer": "01a2905e4680aa49e0b44100d9dfc861b9605bb35f9956b1e99eb43863363d80aa",
    "signature": "01c94d517d5bbc8d5c74e0e68b8cb308561ff979a1c91907b56d427cc90156c437726c0b736d17f7303f2db66e405c7e5c8175b8b863703938eff1659766dff808"
    }
    ]
    }
    },
    "id": 6889533540839698701
    }

    speculative_exec_result

    -

    The result contains the hash of the targeted block and the results of the execution.

    +

    The result contains the RPC API version and the speculative execution result.

    + + + @@ -116,6 +164,13 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.execution_resultsObjectThe map of Block hash to execution result. +
    Example speculative_exec result
    + +

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "speculative_exec_result",
    "value": {
    "api_version": "2.0.0",
    "execution_result": {
    "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",
    "transfers": [],
    "limit": "100000000000",
    "consumed": "23289743502",
    "effects": [
    {
    "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"
    },
    "name": {
    "cl_type": "String",
    "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",
    "parsed": "test_payment_package_hash"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",
    "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000746573745f7061796d656e745f616363657373",
    "parsed": "test_payment_access"
    }
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": "Identity"
    },
    {
    "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",
    "kind": "Identity"
    },
    {
    "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "pay",
    "args": [
    {
    "name": "amount",
    "cl_type": "U512"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",
    "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "10000000636f6e74726163745f76657273696f6e",
    "parsed": "contract_version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    },
    "name": {
    "cl_type": "String",
    "bytes": "11000000746573745f7061796d656e745f68617368",
    "parsed": "test_payment_hash"
    }
    }
    }
    }
    }
    ],
    "messages": [],
    "error": null
    }
    }
    }
    }

    +
    +

    speculative_exec_txn

    +

    The speculative_exec_txn endpoint allows executing a Transaction without committing its execution effects to global state. By default, speculative_exec_txn is turned off on a node. Sending a request to a node with the endpoint unavailable will result in an error message. Find out if this endpoint is available and which port to access. The port is separate from the node's binary port and the default is 7778.

    @@ -124,10 +179,44 @@

    ParameterTypeDescriptionapi_versionStringThe RPC API version.block_hashObjectThe Block hash on top of which the deploy was executed.execution_resultsObjectThe map of Block hash to execution result. -
    Example speculative_exec result
    + + + + + + + +
    ParameterTypeDescription
    transactionObjectA Transaction is a versioned wrapper for a transaction or deploy.
    +
    Example speculative_exec_txn request
    + +

    {
    "jsonrpc": "2.0",
    "method": "speculative_exec_txn",
    "params": {
    "transaction": {
    "Version1": {
    "hash": "f5582cb81a5abda63ebaa4edb3b05210ecbd63ffb8dd17bfbeb3b867f4014468",
    "header": {
    "chain_name": "casper-example",
    "timestamp": "2020-11-17T00:39:24.072Z",
    "ttl": "1h",
    "body_hash": "aa24833ffbf31d62c8c8c4265349e7c09cd71952fcbce6f7b12daf5e340bf2cc",
    "pricing_mode": {
    "Fixed": {
    "gas_price_tolerance": 5
    }
    },
    "initiator_addr": {
    "PublicKey": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c"
    }
    },
    "body": {
    "args": [
    [
    "source",
    {
    "cl_type": {
    "Option": "URef"
    },
    "bytes": "010a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a07",
    "parsed": "uref-0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a-007"
    }
    ],
    [
    "target",
    {
    "cl_type": "URef",
    "bytes": "1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b00",
    "parsed": "uref-1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b-000"
    }
    ],
    [
    "amount",
    {
    "cl_type": "U512",
    "bytes": "0500ac23fc06",
    "parsed": "30000000000"
    }
    ],
    [
    "id",
    {
    "cl_type": {
    "Option": "U64"
    },
    "bytes": "01e703000000000000",
    "parsed": 999
    }
    ]
    ],
    "target": "Native",
    "entry_point": "Transfer",
    "transaction_category": 0,
    "scheduling": "Standard"
    },
    "approvals": [
    {
    "signer": "01d9bf2148748a85c89da5aad8ee0b0fc2d105fd39d41a4c796536354f0ae2900c",
    "signature": "0137d3f468d8f8a6e63f4110d79be29b8c8428e9cd858a92049660e7851ae16a299640d1fc1c930ab6cb424f1a6eec0b194df74bede14f4af1b5133106f1280d0b"
    }
    ]
    }
    }
    },
    "id": 6889533540839698701
    }

    +
    +

    speculative_exec_txn_result

    +

    The result contains the RPC API version and the speculative execution result.

    + + + + + + + + + + + + + + + + + + + + +
    ParameterTypeDescription
    api_versionStringThe RPC API version.
    execution_resultObjectResult of the speculative execution.
    +
    Example speculative_exec_txn result
    -

    {
    "jsonrpc": "2.0",
    "id": -8801853076373554652,
    "result": {
    "api_version": "1.5.0",
    "block_hash": "ff862326b08702a5089d64e32100537b7ff984cac4c0ba6d1c561f7c47125f76",
    "execution_result": {
    "Success": {
    "effect": {
    "operations": [],
    "transforms": [
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0e630ed87",
    "parsed": "583799990000"
    }
    }
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0e630ed87",
    "parsed": "583799990000"
    }
    }
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "AddUInt512": "100000000"
    }
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": "Identity"
    },
    {
    "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",
    "transform": "Identity"
    },
    {
    "key": "balance-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "05f0ed2d5887",
    "parsed": "581299990000"
    }
    }
    },
    {
    "key": "balance-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd",
    "transform": {
    "AddUInt512": "2500000000"
    }
    },
    {
    "key": "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612",
    "transform": {
    "WriteTransfer": {
    "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",
    "to": "account-hash-f466e7f5f9240fb577d1d4c650c4063752553406dff7aa24b4822ba2b72e5b65",
    "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",
    "target": "uref-92ec6dfbdf151e20b55c89e0a327959cf6e5b091c5f2b39201c1858e2943f3bd-004",
    "amount": "2500000000",
    "gas": "0",
    "id": 0
    }
    }
    },
    {
    "key": "deploy-d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "transform": {
    "WriteDeployInfo": {
    "deploy_hash": "d898910011b1f2f8797a442740e69cd5de41b9f796e658e962a24663e6199e5a",
    "transfers": [
    "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"
    ],
    "from": "account-hash-0a9b33af5108c5a6e1067b0ddec6853ce1745d591375d767ac5db680d21845e7",
    "source": "uref-7c25ef9382fcae902b922866434f7111a1b34534323e93ff5bf22f1a401c2678-007",
    "gas": "100000000"
    }
    }
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-0a300922655180354a9ee92b808c7b45b08e5b01d9da0bac9a9b3415bcebbf8d",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "hash-d2dfc9409965993f9e186db762b585274dcafe439fa1321cfca08017262c8e46",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "hash-59c6451dd58463708fa0b122e97114f07fa5f609229c9d67ac9426935416fbeb",
    "transform": "Identity"
    },
    {
    "key": "hash-f8df015ba26860a7ec8cab4ee99f079325b0bbb9ef0e7810b63d85df39da95fe",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": "Identity"
    },
    {
    "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",
    "transform": "Identity"
    },
    {
    "key": "balance-ea3c9bdcbe57f067a29609d397981b2d0fb39853a0a9f06e444b06404eadcb1a",
    "transform": {
    "WriteCLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    },
    {
    "key": "balance-ecc530e74cf2185936a334aa1e0f07539aa3b33c4b547e71fc4109151755652f",
    "transform": {
    "AddUInt512": "100000000"
    }
    }
    ]
    },
    "transfers": [
    "transfer-97426c848475dae98446f2c2fd00ec7901cd8ddfe250171ff4ed25d78412a612"
    ],
    "cost": "100000000"
    }
    }
    }
    }

    -

    +

    {
    "jsonrpc": "2.0",
    "id": 1,
    "result": {
    "name": "speculative_exec_txn_result",
    "value": {
    "api_version": "2.0.0",
    "execution_result": {
    "block_hash": "b597865a5f96ea23932173601bf6b170a482f562f6dd3598b2d37a86c1f01371",
    "transfers": [],
    "limit": "100000000000",
    "consumed": "23289743502",
    "effects": [
    {
    "key": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-7f292691d790433e131a5ea69c70b85a959a454f5d928de437b11bf4e7c06930",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "10154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "parsed": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b"
    },
    "name": {
    "cl_type": "String",
    "bytes": "19000000746573745f7061796d656e745f7061636b6167655f68617368",
    "parsed": "test_payment_package_hash"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-814d93d21458dd90914dba42395ec9c075bc105cf3ef7ae0215f2107f3b47848",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "0265d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf224907",
    "parsed": "uref-65d264188c3cf9e61862415424c99900ec1c858f168d94d98b332fe738bf2249-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "13000000746573745f7061796d656e745f616363657373",
    "parsed": "test_payment_access"
    }
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": "Identity"
    },
    {
    "key": "entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08",
    "kind": "Identity"
    },
    {
    "key": "package-63227f4db8d0d09e3b4b64416125ac35023e1054e38127780ec241b2b60d8b3d",
    "kind": "Identity"
    },
    {
    "key": "entry-point-v1-entity-system-63448411a9dac7fd2e4a1dc9287ddb95b6f26ebe549b1387e44685d6b56dab08-21bddc7e4379ba445c7118cb51962954e0d1e5aa5cacc0c4ff6095b57eb9fb33",
    "kind": "Identity"
    },
    {
    "key": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "Unit",
    "bytes": "",
    "parsed": null
    }
    }
    }
    },
    {
    "key": "balance-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U512",
    "bytes": "00",
    "parsed": "0"
    }
    }
    }
    },
    {
    "key": "byte-code-v1-wasm-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "kind": {
    "Write": {
    "ByteCode": {
    "kind": "V1CasperWasm",
    "bytes": "0061736d0100000001540c60027f7f017f60017f0060037f7f7f017f60047f7f7f7f017f60077f7f7f7f7f7f7f017f60087f7f7f7f7f7f7f7f017f60037f7f7f0060047f7f7f7f0060017f017f60000060057f7f7f7f7f017f60027f7f000289020a03656e760d6361737065725f726576657274000103656e76196361737065725f6765745f6e616d65645f6172675f73697a65000203656e76146361737065725f6765745f6e616d65645f617267000303656e76156361737065725f6765745f6d61696e5f7075727365000103656e761a6361737065725f6765745f73797374656d5f636f6e7472616374000203656e76146361737065725f63616c6c5f636f6e7472616374000403656e76176361737065725f726561645f686f73745f627566666572000203656e76236361737065725f7472616e736665725f66726f6d5f70757273655f746f5f7075727365000503656e76066d656d6f72790201114003656e760367617300010324230108080809080006060a080b07090b090701070008000802020202080907070008000804050170010808060e027f01418080c0000b7f0141000b070701037061790025090d010041010b071a262a2b2728290afc970123270041d4ab0810082000230141016a2401230141f4034b0440000b100a230141016b24011000000b240041a6960410082000230141046a2401230141f4034b0440000b100c230141046b24010b1b0041d8221008200041187441187541027441c481c0006a2802000bd20501027f41da880410082000410876210141012102024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240200041ff01710e3635000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334350b41a604100841020f0b41a604100841030f0b41a604100841040f0b41a604100841050f0b41a604100841060f0b41a604100841070f0b41a604100841080f0b41a604100841090f0b41a6041008410a0f0b41a6041008410b0f0b41a6041008410c0f0b41a6041008410d0f0b41a6041008410e0f0b41a6041008410f0f0b41a604100841100f0b41a604100841110f0b41a604100841120f0b41a604100841130f0b41a604100841140f0b41a604100841150f0b41a604100841160f0b41a604100841170f0b41a604100841180f0b41a604100841190f0b41a6041008411a0f0b41a6041008411b0f0b41a6041008411c0f0b41a6041008411d0f0b41a6041008411e0f0b41a6041008411f0f0b41a604100841200f0b41a604100841210f0b41a604100841220f0b41a604100841230f0b41a604100841240f0b41a604100841250f0b41a604100841260f0b41a604100841270f0b41a604100841280f0b41f20c1008200141ff01714180f803720f0b41f20c1008200141ff01714180fa03720f0b41f20c1008200141ff01714180fc03720f0b41f20c1008200141ff01714180fe03720f0b41f20c1008200041107641808004720f0b41a604100841290f0b41a6041008412a0f0b41a6041008412b0f0b41a6041008412c0f0b41a6041008412d0f0b41a6041008412e0f0b41a6041008412f0f0b41a604100841300f0b41f4031008413121020b418603100820020bab6309087f017e017f017e017f017e017f017e087f41b8f0111008230041e0026b2200240020004100360290020240024002400240024002400240418080c000410620004190026a1001230141086a2401230141f4034b0440000b100e230141086b2401220141ff017122024136460d0041a69702100820024101470d01419c960410084101230141016a2401230141f4034b0440000b1009230141016b2401000b41f2b3021008024002402000280290022202450d0041a6970210082002417f4c0d0341ccad06100820024101230141096a2401230141f4034b0440000b100f230141096b24012203450d0441d8cf0a100802400240418080c0004106200320021002230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d0041f0ad02100820032d0000220141c0004b0d0141849f0210082002417f6a22042001490d0141e28a12100820004190026a20016a410041c00020016b230141036a2401230141f4034b0440000b1020230141036b24011a20004190026a200341016a2001230141036a2401230141f4034b0440000b1023230141036b24011a20004180016a41376a2205200041c8026a29000037000020004180016a41306a2206200041c1026a29000037030020004180016a41286a2207200041b9026a290000220837030020004180016a41206a2209200041b1026a290000220a37030020004180016a41186a220b200041a9026a290000220c37030020004180016a41106a220d200041a1026a290000220e370300200041c0016a41086a220f20004190026a41096a290000370300200041c0016a41106a2210200e370300200041c0016a41186a2211200c370300200041c0016a41206a2212200a370300200041c0016a41286a22132008370300200041c0016a41306a22142006290300370300200041c0016a41376a2215200529000037000020002000290091023703c001200420016b450d0341d2ab061008200320024101230141086a2401230141f4034b0440000b1010230141086b24010c020b41ceb2081008200320024101230141036a2401230141f4034b0440000b1011230141036b24012001230141016a2401230141f4034b0440000b1009230141016b2401000b419a9a041008200320024101230141086a2401230141f4034b0440000b1010230141086b24010b419c960410084102230141016a2401230141f4034b0440000b1009230141016b2401000b419ef613100820002d0090022116200041c0006a41376a22012015290000370000200041c0006a41306a22042014290300370300200041c0006a41286a22142013290300370300200041c0006a41206a22132012290300370300200041c0006a41186a22122011290300370300200041c0006a41106a22112010290300370300200041c0006a41086a2210200f290300370300200020002903c001370340200320024101230141086a2401230141f4034b0440000b1010230141086b240120004180016a41086a2010290300370300200d2011290300370300200b2012290300370300200920132903003703002007201429030037030020062004290300370300200520012900003700002000200029034037038001200041c48ac000360240200041002802e482403602c001024041094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e482400c060b41848b071008200020002802402201280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c040b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d040b41cccd021008410020002802c0013602e482400c040b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41f4b608100820024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141094101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e4824020020d010b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b2002100302400240024002400240024020022d0020220b41074b0d004188c1121008200041c0016a41106a2205200241116a290000370300200041c0016a41176a2206200241186a29000037000020004190026a41106a2201200529030037030020004190026a41176a2203200629000037000020004190026a41086a2204200241096a2900002208370300200041086a2008370300200041106a2001290300370300200041176a20032900003700002000200229000122083703900220022d0000210d41002802e4824021074100200241786a22033602e482402002200736020020032003280200417e713602002000200837030020004190026a41186a420037030020014200370300200442003703002000420037039002410120004190026a41201004230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0141fa8b0a1008200041c0016a41086a2000419d026a2900003703002005200041a5026a2900003703002006200041ac026a28000036000020002000290095023703c00120002d009102210120002d009002210320002f019202210520002d0094022106200041c48ac000360220200041002802e08240360240024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602e082400c040b41848b071008200020002802202204280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820042000280290023602000c030b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820042000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200420002802900236020020020d030b41cccd021008410020002802403602e082400c040b41bec10c1008200241214101230141036a2401230141f4034b0440000b1011230141036b24014101230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041084101200041c0006a200041206a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602e082402002450d010b41b2d60d1008200220002903c0013700052002410d6a200041c0016a41086a290300370000200241156a200041c0016a41106a2903003700002002411c6a200041c0016a41176a280000360000200220033a000020022005200641107472410874200172360001200041206a41086a200241096a290000370300200041206a41106a200241116a290000370300200041206a41176a200241186a29000037000041002802e082402105200229000121084100200241786a22013602e0824020002008370320200128020021062002200536020020012006417e71360200200041c48ac000360240200020013602c0010240024041084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802c0013602e082400c010b41aac70f10082000200028024022012802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820012000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820012000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200120002802900236020020020d010b41b0c0001008410020002802c0013602e0824000000b20024100360204200220002802c001360208200220024180c0006a410272360200200020023602c00141084101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802c0013602e082402002450d010b419ad609100820022000290320370001200220033a0000200241186a200041376a290000370000200241116a200041306a290300370000200241096a200041286a290300370000200041c48ac000360240200041002802d882403602c0010240024041064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020002802c0013602d882400c010b41aac70f10082000200028024022032802003602900202400240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d0041e4cf02100820032000280290023602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf02100820032000280290023602000c010b41bab7081008200141107422014100360204200120002802900236020820012001418280046a3602002000200136029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012101200320002802900236020020010d010b41b0c0001008410020002802c0013602d8824000000b20014100360204200120002802c001360208200120014180c0006a410272360200200020013602c00141064101200041c0016a200041c0006a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020002802c0013602d882402003450d010b41c08d081008200341113600002003410029008680403700042003410c6a410029008e8040370000200341146a41002d009680403a000041044101230141096a2401230141f4034b0440000b100f230141096b24012206450d0041daa00b1008200641003600000240024002400240024002400240024002400240024020024120200341152006410420004190026a1005230141086a2401230141f4034b0440000b100e230141086b2401220141ff01714136470d004182ad0210082000280290022201450d0441a6970210082001417f4c0d0141ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012205450d0241d2cc0a100820052001200041c0016a1006230141086a2401230141f4034b0440000b100e230141086b2401220441ff01714136470d03419a9b0210084100210420014120490d0541a69702100820014120460d0541e4b10210084101210420052d0020221241074b0d0541dadf05100820052d00002113200041c0016a41176a2207200541016a220441176a290000370000200041c0016a41106a2209200441106a29000037030020004190026a41086a220f200441086a29000037030020004190026a41106a2210200929030037030020004190026a41176a221120072900003700002000200429000037039002024020014121460d0041c6af061008200520014101230141086a2401230141f4034b0440000b1010230141086b2401410221040c0d0b41c0b81b1008200041c0006a41176a22042011290000370000200041c0006a41106a22112010290300370300200041c0006a41086a2210200f2903003703002000200029039002370340200520014101230141086a2401230141f4034b0440000b1010230141086b2401200041c0016a41086a20102903003703002009201129030037030020072004290000370000200020002903403703c001200641044101230141086a2401230141f4034b0440000b1010230141086b2401200341154101230141086a2401230141f4034b0440000b1010230141086b2401200241002802e082403602004100200241786a22023602e0824020022002280200417e7136020020004199026a2202200041086a290300370000200041a1026a2201200041106a290300370000200041a8026a2203200041176a2900003700002000200d3a00900220002000290300370091022000200b3a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220b450d06418eda091008200028024821112000280240210d2002200041c0016a41086a2903003700002001200041c0016a41106a2903003700002003200041d7016a290000370000200020133a009002200020002903c00137009102200020123a00b002200041c0006a20004190026a230141086a2401230141f4034b0440000b1014230141086b24012000280244220f450d0741a2a90710082000280248211220002802402110200041c8026a200041b7016a29000037000020004199026a20004180016a41086a290300370000200041a1026a20004180016a41106a290300370000200041a9026a20004198016a290300370000200041b1026a200041a0016a290300370000200041b9026a200041a8016a290300370000200041c1026a200041b0016a290300370000200020163a009002200020002903800137009102024020002d00cf022202450d004190a0021008200041cf026a2104200221160c090b41bab0021008024020002d00ce022202450d004190a0021008200041ce026a2104200221160c090b41bab0021008024020002d00cd022202450d004190a0021008200041cd026a2104200221160c090b41bab0021008024020002d00cc022202450d004190a0021008200041cc026a2104200221160c090b41bab0021008024020002d00cb022202450d004190a0021008200041cb026a2104200221160c090b41bab0021008024020002d00ca022202450d004190a0021008200041ca026a2104200221160c090b41bab0021008024020002d00c9022202450d004190a0021008200041c9026a2104200221160c090b41bab0021008024020002d00c8022202450d004190a0021008200041c8026a2104200221160c090b41bab0021008024020002d00c7022202450d004190a0021008200041c7026a2104200221160c090b41bab0021008024020002d00c6022202450d004190a0021008200041c6026a2104200221160c090b41bab0021008024020002d00c5022202450d004190a0021008200041c5026a2104200221160c090b41bab0021008024020002d00c4022202450d004190a0021008200041c4026a2104200221160c090b41bab0021008024020002d00c3022202450d004190a0021008200041c3026a2104200221160c090b41bab0021008024020002d00c2022202450d004190a0021008200041c2026a2104200221160c090b41bab0021008024020002d00c1022202450d004190a0021008200041c1026a2104200221160c090b41bab0021008024020002d00c0022202450d004190a0021008200041c0026a2104200221160c090b41bab0021008024020002d00bf022202450d004190a0021008200041bf026a2104200221160c090b41bab0021008024020002d00be022202450d004190a0021008200041be026a2104200221160c090b41bab0021008024020002d00bd022202450d004190a0021008200041bd026a2104200221160c090b41bab0021008024020002d00bc022202450d004190a0021008200041bc026a2104200221160c090b41bab0021008024020002d00bb022202450d004190a0021008200041bb026a2104200221160c090b41bab0021008024020002d00ba022202450d004190a0021008200041ba026a2104200221160c090b41bab0021008024020002d00b9022202450d004190a0021008200041b9026a2104200221160c090b41bab0021008024020002d00b8022202450d004190a0021008200041b8026a2104200221160c090b41bab0021008024020002d00b7022202450d004190a0021008200041b7026a2104200221160c090b41bab0021008024020002d00b6022202450d004190a0021008200041b6026a2104200221160c090b41bab0021008024020002d00b5022202450d004190a0021008200041b5026a2104200221160c090b41bab0021008024020002d00b4022202450d004190a0021008200041b4026a2104200221160c090b41bab0021008024020002d00b3022202450d004190a0021008200041b3026a2104200221160c090b41bab0021008024020002d00b2022202450d004190a0021008200041b2026a2104200221160c090b41bab0021008024020002d00b1022202450d004190a0021008200041b1026a2104200221160c090b41bab0021008024020002d00b0022202450d004190a0021008200041b0026a2104200221160c090b41bab0021008024020002d00af022202450d004190a0021008200041af026a2104200221160c090b41bab0021008024020002d00ae022202450d004190a0021008200041ae026a2104200221160c090b41bab0021008024020002d00ad022202450d004190a0021008200041ad026a2104200221160c090b41bab0021008024020002d00ac022202450d004190a0021008200041ac026a2104200221160c090b41bab0021008024020002d00ab022202450d004190a0021008200041ab026a2104200221160c090b41bab0021008024020002d00aa022202450d004190a0021008200041aa026a2104200221160c090b41bab0021008024020002d00a9022202450d004190a0021008200041a9026a2104200221160c090b41bab0021008024020002d00a8022202450d004190a0021008200041a8026a2104200221160c090b41bab0021008024020002d00a7022202450d004190a0021008200041a7026a2104200221160c090b41bab0021008024020002d00a6022202450d004190a0021008200041a6026a2104200221160c090b41bab0021008024020002d00a5022202450d004190a0021008200041a5026a2104200221160c090b41bab0021008024020002d00a4022202450d004190a0021008200041a4026a2104200221160c090b41bab0021008024020002d00a3022202450d004190a0021008200041a3026a2104200221160c090b41bab0021008024020002d00a2022202450d004190a0021008200041a2026a2104200221160c090b41bab0021008024020002d00a1022202450d004190a0021008200041a1026a2104200221160c090b41bab0021008024020002d00a0022202450d004190a0021008200041a0026a2104200221160c090b41bab0021008024020002d009f022202450d004190a00210082000419f026a2104200221160c090b41bab0021008024020002d009e022202450d004190a00210082000419e026a2104200221160c090b41bab0021008024020002d009d022202450d004190a00210082000419d026a2104200221160c090b41bab0021008024020002d009c022202450d004190a00210082000419c026a2104200221160c090b41bab0021008024020002d009b022202450d004190a00210082000419b026a2104200221160c090b41bab0021008024020002d009a022202450d004190a00210082000419a026a2104200221160c090b41bab0021008024020002d0099022202450d004190a002100820004199026a2104200221160c090b41bab0021008024020002d0098022202450d004190a002100820004198026a2104200221160c090b41bab0021008024020002d0097022202450d004190a002100820004197026a2104200221160c090b41bab0021008024020002d0096022202450d004190a002100820004196026a2104200221160c090b41bab0021008024020002d0095022202450d004190a002100820004195026a2104200221160c090b41bab0021008024020002d0094022202450d004190a002100820004194026a2104200221160c090b41bab0021008024020002d0093022202450d004190a002100820004193026a2104200221160c090b41bab0021008024020002d0092022202450d004190a002100820004192026a2104200221160c090b41bab0021008024020002d0091022202450d004190a002100820004191026a2104200221160c090b41a4a002100820004190026a2104201641ff01710d0841c0ea02100841002102200041003602482000428080808010370340410021010c090b41b4980410082001230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084122230141016a2401230141f4034b0440000b1009230141016b2401000b419c960410084113230141016a2401230141f4034b0440000b1009230141016b2401000b41e4b2051008200020043a009002200020044118763a009302200020044108763b009102200028029002230141016a2401230141f4034b0440000b1009230141016b2401000b41ac95021008410021040c070b41d2ab061008200520014101230141086a2401230141f4034b0440000b1010230141086b24010c060b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b4198bf08100820002d0040230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41e6ef0510080240024002400240024002400240024041002802c882402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c0a0b41fcae07100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e71360200200220022802002203410371200172220536020020034102710d034188ab021008200128020021030c040b4188ab021008200128020022020d000b0b41a2ae021008024041002802c48a402202450d0041b8031008034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210602400240024020022802002205417c7122030d0041c497021008200121050c010b418a9d02100802402005410271450d0041c497021008200121050c010b419afa0210082003200328020441037120017236020420022802042203417c712205450d0141ba3610082002280200417c712103200528020021060b4184cd00100820052006410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41fcae07100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e71360200200220022802002201410371200572220336020020014102710d054188ab021008200528020021030c070b4188ab021008200128020022020d000b0b41ccee10100802404101230141036a2401230141f4034b0440000b1024230141036b24012202417f460d0041d0df00100820024110742202420037020420022002418280046a360200034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4180c000490d0041f6a1021008024020014188106a20054180406a4d0d0041d89702100820014103710d0141aeb4021008200221052001280200417c7121020c080b41b4b207100841002101200541f8bf7f6a220541003602082005420037020020052002280200417c71360200024020022802002206417c712203450d0041d89702100820064102710d0041e2e300100820032003280204410371200572360204200528020441037121010b20052001200272360204200241086a22012001280200417e713602002002200228020022014103712005722203360200024020014102710d004188ab021008200528020021030c080b41a4dc02100820022003417d71360200200528020041027221030c060b4188ab021008200128020022020d000b0b41f0b7021008410041003602c48a400c050b41cef200100820022005417d713602002001200128020041027222033602000b41c497021008200221050c040b41ecca00100820022003417d71360200200528020041027221030b41e82a1008200520033602000b41a8be011008410020023602c48a40200520034101723602002005410c6a4200370200200520054188c0006a410272360208200541086a2102034041f4f40410080240200241086a2d0000410171450d0041b80310080340418af408100820022002280208417e713602082002280204417c712201280200210502400240024020022802002206417c7122030d0041c497021008200121060c010b418a9d02100802402006410271450d0041c497021008200121060c010b419afa0210082003200328020441037120017236020420022802042203417c712206450d0141ba3610082002280200417c712103200628020021050b4184cd00100820062005410371200372360200200228020421030b2002200341037136020420022002280200220341037136020002402003410271450d0041c6c1001008200120012802004102723602000b20012102200141086a2d00004101710d000b0b024020022802002203417c712205200241086a22016b4108490d0041f6a10210080240200141106a200541786a4d0d0041aeb40210082001280200417c712105200221010c040b41b4b207100841002103200541706a220141003602082001420037020020012002280200417c71360200024020022802002206417c712205450d0041d89702100820064102710d0041e2e300100820052005280204410371200172360204200128020441037121030b20012003200272360204200241086a22032003280200417e713602002002200228020022034103712001722205360200024020034102710d004194b102100820012802002103200221050c040b41928a03100820022005417d71360200200120012802004102722203360200200221050c030b4188ab021008200128020022020d000b0b41d42a1008410041003602c8824000000b410020053602c88240200120163a000820012003410172360200200141086a2105024020004190026a2004470d0041a89503100841012102200041013602482000200536024420004108360240410121030c020b41a00b100841082101410121020340418cbc0210082004417f6a22042d00002103024020022001470d0041b69f0210080240200141016a2206450d0041caf9071008200020053602402000200136024420004101360248200041d0026a200141017422162006201620064b1b22064108200641084b1b22062006417f73411f76200041c0006a230141046a2401230141f4034b0440000b1015230141046b2401024020002802d0020d004194b102100820002802d4022105200621010c020b41f0ad02100820002802d8022206418180808078460d0141be9402100820060d050b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b418ad4021008200520026a20033a0000200241016a2102200420004190026a470d000b4182a00310082000200236024820002005360244200020013602402002210320022001470d010b418ccf041008200041c0006a2001230141086a2401230141f4034b0440000b1017230141086b240120002802442105200028024821030b41ccce051008200520036a221620023a00002000200341016a2209360248024020094102490d0041c4be041008410021020240200941017622134101460d004184251008410021014100200941017641feffffff07716b21072005210203404182c004100820022d000021062002201620016a22032d00003a0000200320063a0000200241016a22062d0000210420062003417f6a22032d00003a0000200320043a0000200241026a210220072001417e6a2201470d000b410020016b21020b2009410271450d0041c2a3011008200520026a22012d000021032001200520096a20136b20132002417f736a6a22022d00003a0000200220033a00000b2000280240210102400240024020002802442203450d00419ab907100820002802482105200041c48ac0003602d002200041002802c48240360240024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041cccd021008410020002802403602c482400c030b41848b071008200020002802d0022206280200360290020240418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012202450d0041e4cf02100820062000280290023602000c020b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041e4cf02100820062000280290023602000c010b41bab7081008200241107422024100360204200220002802900236020820022002418280046a3602002000200236029002418010410420004190026a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102200620002802900236020020020d020b41b0c0001008410020002802403602c4824000000b41d4ab0810082001230141026a2401230141f4034b0440000b1013230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b41eeb80810082002410036020420022000280240360208200220024180c0006a4102723602002000200236024041014101200041c0006a200041d0026a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012102410020002802403602c482402002450d010b41feee151008200241003a0000200b2011200f2012200320052002410110072105200241014101230141086a2401230141f4034b0440000b1010230141086b240102402001450d00419a9a041008200320014101230141086a2401230141f4034b0440000b1010230141086b24010b02402010450d00419a9a041008200f20104101230141086a2401230141f4034b0440000b1010230141086b24010b0240200d450d00419a9a041008200b200d4101230141086a2401230141f4034b0440000b1010230141086b24010b02402005230141086a2401230141f4034b0440000b100e230141086b2401220241ff01714136470d0041840c1008200041e0026a24000f0b41b4980410082002230141016a2401230141f4034b0440000b1009230141016b2401000b419c04100800000b41d4ab0810082004230141026a2401230141f4034b0440000b100b230141026b2401230141016a2401230141f4034b0440000b1009230141016b2401000b880801047f41fc8004100841002101413621024100210341002104024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024002400240024020000e323332000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f310b41ac95021008410121040c2f0b41ac95021008410221040c2e0b41ac95021008410321040c2d0b41ac95021008410421040c2c0b41ac95021008410521040c2b0b41ac95021008410621040c2a0b41ac95021008410721040c290b41ac95021008410821040c280b41ac95021008410921040c270b41ac95021008410a21040c260b41ac95021008410b21040c250b41ac95021008410c21040c240b41ac95021008410d21040c230b41ac95021008410e21040c220b41ac95021008410f21040c210b41ac95021008411021040c200b41ac95021008411121040c1f0b41ac95021008411221040c1e0b41ac95021008411321040c1d0b41ac95021008411421040c1c0b41ac95021008411521040c1b0b41ac95021008411621040c1a0b41ac95021008411721040c190b41ac95021008411821040c180b41ac95021008411921040c170b41ac95021008411a21040c160b41ac95021008411b21040c150b41ac95021008411c21040c140b41ac95021008411d21040c130b41ac95021008411e21040c120b41ac95021008411f21040c110b41ac95021008412021040c100b41ac95021008412121040c0f0b41ac95021008412221040c0e0b41ac95021008412321040c0d0b41ac95021008412421040c0c0b41ac95021008412521040c0b0b41ac95021008412621040c0a0b41ac95021008412721040c090b41ac95021008412d21040c080b41ac95021008412e21040c070b41ac95021008412f21040c060b41ac95021008413021040c050b41ac95021008413121040c040b41ac95021008413221040c030b41ac95021008413321040c020b41ac95021008413421040c010b41f4031008413521040b41ac95021008410021030c010b41a0a8021008024002400240024020004180807c7141808004460d0041c69d021008200041807e7122024180fa03460d0241a69702100820024180fc03460d01419aa5021008412b2104410021032000210120024180fe03460d0441f2b30210084128411e20024180f8034622021b2104410021032000410020021b21010c040b41d29e02100820004110742103412c21040c030b41ac95021008412a21040c010b41f4031008412921040b41800a100841002103200021010b41a4171008200420037220014108744180fe03717221020b20020bda0401047f4198db021008230041106b22022400200041036a220341027621000240024002400240417f200141044720014104491b2204417f460d0041d897021008200441ff01710d010b41f29f0210082000417f6a22044180024922050d010b41a4c2091008200241002802c48a4036020c0240200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041c497111008410021042003417c7122032001410374418080016a2205200320054b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012205417f460d0041ccf10510082005411074220441003602042004200228020c3602082004200420034180807c716a4102723602002002200436020c200020012002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b4100200228020c3602c48a400c010b41d0f2071008200241c48ac0003602082002200441027441c482c0006a410020051b220328020036020c0240200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240122040d0041eecd0610082002200241086a20002002230141096a2401230141f4034b0440000b1019230141096b24014100210420022802000d00418aa805100820022802042204200228020c3602082002200436020c200020012002410c6a200241086a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b240121040b2003200228020c3602000b200241106a240020040bbc0401047f41e0a00210080240024002402000450d0041b8960210082001450d0041d0b1021008024002400240417f200241044720024104491b2202417f460d0041d897021008200241ff01710d010b41c6a2021008200141036a410276417f6a2201418002490d010b41ecc603100820004100360200200041786a220120012802002202417e7136020041002802c48a40210302400240200141046a2204280200417c712205450d0041a2ae021008200528020022064101710d0041a6b10510080240024002402002417c7122000d0041c497021008200521020c010b418a9d02100802402002410271450d0041c497021008200521020c010b419afa0210082000200028020441037120057236020420042802002200417c712202450d0141ba3610082001280200417c712100200228020021060b4184cd00100820022006410371200072360200200428020021000b200420004103713602002001200128020022004103713602002000410271450d0141fed2021008200520052802004102723602000c010b41d89c0210082002417c712205450d0341d89702100820024102710d03419cab02100820052d00004101710d03418ef50010082000200541086a2202280200417c71360200200220014101723602000b41c497021008200321010c030b4180b90110082000200141027441c482c0006a2201280200360200200041786a22002000280200417e71360200200120003602000b41b80310080f0b41e82a1008200020033602000b41d0281008410020013602c48a400b280041b29c041008200020012002230141086a2401230141f4034b0440000b1010230141086b24010bd40501077f41bab0021008024020022802002205450d0041f61d10082001417f6a2106410020016b21072000410274210803404186f40410080240200541086a2d0000410171450d0041b8031008034041f29e09100820052005280208417e713602082005280204417c71220128020021090240024002402005280200220a417c71220b0d0041c4970210082001210a0c010b418a9d0210080240200a410271450d0041c4970210082001210a0c010b419afa021008200b200b2802044103712001723602042005280204220b417c71220a450d0141ba3610082005280200417c71210b200a28020021090b4184cd001008200a2009410371200b723602002005280204210b0b2005200b41037136020420052005280200220b4103713602000240200b410271450d0041c6c1001008200120012802004102723602000b2002200136020020012105200141086a2d00004101710d000b0b02402005280200417c71220b200541086a22016b2008490d0041e0e40610080240024020012003200020042802101100004102746a41086a200b20086b200771220b4d0d0041f09902100820062001710d02419af50210082002200541086a280200417c713602002005280200210b200521010c010b41b4b207100841002109200b4100360200200b41786a2201420037020020012005280200417c7136020002402005280200220a417c71220b450d0041d897021008200a4102710d0041e2e3001008200b200b280204410371200172360204200128020441037121090b20012009200572360204200541086a220b200b280200417e7136020020052005280200220b41037120017222093602000240200b4102710d004188ab0210082001280200210b0c010b41cef200100820052009417d7136020020012001280200410272220b3602000b41803710082001200b410172360200200141086a0f0b41f0d502100820022001280200220536020020050d000b0b41ee00100841000b1b0041d82210082000411874411875410274418c82c0006a2802000bed0401037f4184fa0a1008230041106b22022400200241c48ac000360204200241002802e482403602080240024041094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041cccd021008410020022802083602e482400c010b41f49107100820022002280204220428020036020c02400240024041801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012203450d0041e4cf0210082004200228020c3602000c010b4184f2101008024002404101230141036a2401230141f4034b0440000b1024230141036b24012203417f470d0041e4cf0210082004200228020c3602000c010b41bab70810082003411074220341003602042003200228020c36020820032003418280046a3602002002200336020c41801041042002410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121032004200228020c36020020030d010b41cccd021008410020022802083602e482400c010b41f4b60810082003410036020420032002280208360208200320034180c0006a4102723602002002200336020841094101200241086a200241046a419481c0002301410b6a2401230141f4034b0440000b10122301410b6b24012103410020022802083602e4824020030d010b419c04100800000b20004121360208200020033602042000412136020020032001290000370000200320012d00203a0020200341186a200141186a290000370000200341106a200141106a290000370000200341086a200141086a290000370000200241106a24000be10201017f41a89d021008024002402002450d004186a5021008024002400240024020014100480d0041fca90210082003280208450d014182ad02100820032802042204450d01419cc70610082003280200210320014101230141096a2401230141f4034b0440000b100f230141096b24012202450d0341bccb0a1008200220032004230141036a2401230141f4034b0440000b1023230141036b24011a200320044101230141086a2401230141f4034b0440000b1010230141086b24010c020b41c8bc021008200041086a41003602000c040b41ccad06100820014101230141096a2401230141f4034b0440000b100f230141096b24012202450d010b41988401100820002002360204200041086a2001360200200041003602000f0b41808201100820002001360204200041086a4101360200200041013602000f0b41f8d500100820002001360204200041086a41003602000b41d0281008200041013602000b230041ae95041008230141016a2401230141f4034b0440000b1018230141016b2401000baa0201037f418cb7021008230041206b2202240002400240200141016a2201450d0041e8b20910082000280200220341017422042001200420014b1b22014108200141084b1b2201417f73411f762104024002402003450d0041dca503100820024101360218200220033602142002200041046a2802003602100c010b41d0281008200241003602180b200220012004200241106a230141046a2401230141f4034b0440000b1015230141046b2401024020022802000d0041d8800310082002280204210320002001360200200020033602040c020b41b0b0021008200241086a2802002200418180808078460d0141b8960210082000450d00419c04100800000b41ae95041008230141016a2401230141f4034b0440000b1016230141016b2401000b200241206a24000b0900419c04100800000b9d0301047f41d698081008230041106b2204240020042001280200220528020036020c024002400240200241026a220120016c220141801020014180104b1b220241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b24012201450d00418ad90210082005200428020c360200200241027421060c010b41b08d111008024002402002410274220641a08001200641a080014b1b418780046a2207411076230141036a2401230141f4034b0440000b1024230141036b24012201417f470d0041e4cf0210082005200428020c3602000c010b419ec20810082001411074220141003602042001200428020c3602082001200120074180807c716a4102723602002004200136020c200241042004410c6a419481c00041ac81c0002301410b6a2401230141f4034b0440000b10122301410b6b240121012005200428020c36020020010d010b41a09902100841012102410021010c010b419edf001008200142003702042001200120066a410272360200410021020b2000200136020420002002360200200441106a24000b02000b9801004190f011100802400240200241027422022003410374418080016a2203200220034b1b418780046a2203411076230141036a2401230141f4034b0440000b1024230141036b24012202417f470d0041a09902100841012103410021020c010b41d8e80010082002411074220242003702042002200220034180807c716a410272360200410021030b20002002360204200020033602000b0a0041ee0010084180040b090041ee00100841010b0900418603100820010b090041ee00100841000b280041b29c041008200020012002230141066a2401230141f4034b0440000b1022230141066b24010b8c0301087f418cbb041008024002402002410f4b0d0041c497021008200021030c010b41c6850510082000410020006b41037122046a210502402004450d0041d00f10082000210320012106034041fce5021008200320062d00003a0000200641016a2106200341016a22032005490d000b0b2005200220046b2207417c7122086a210302400240200120046a22094103712206450d0041a69702100820084101480d0141fa3d10082009417c71220a41046a21014100200641037422026b4118712104200a280200210603404198f9021008200520062002762001280200220620047472360200200141046a2101200541046a22052003490d0041b8910210080c020b0b41a69702100820084101480d0041c409100820092101034041fce502100820052001280200360200200141046a2101200541046a22052003490d000b0b20074103712102200920086a21010b02402002450d00419c0e1008200320026a2105034041fce5021008200320012d00003a0000200141016a2101200341016a22032005490d000b0b20000be80101037f418cbb041008024002402002410f4b0d0041c497021008200021030c010b419aea0410082000410020006b41037122046a210502402004450d0041c409100820002103034041ecc9021008200320013a0000200341016a22032005490d000b0b2005200220046b2204417c7122026a2103024020024101480d0041bc0f1008200141ff017141818284086c2102034041ecc902100820052002360200200541046a22052003490d000b0b200441037121020b02402002450d00419c0e1008200320026a2105034041ecc9021008200320013a0000200341016a22032005490d000b0b20000b280041b29c0410082000200120022301410c6a2401230141f4034b0440000b10212301410c6b24010b0f00200020004180d30e6c100840000b1c002301411f6a2401230141f4034b0440000b100d2301411f6b24010b24002000200120022003230141096a2401230141f4034b0440000b1019230141096b24010b24002000200120022003230141046a2401230141f4034b0440000b101b230141046b24010b200020002001230141016a2401230141f4034b0440000b101c230141016b24010b1e002000230141016a2401230141f4034b0440000b101d230141016b24010b200020002001230141016a2401230141f4034b0440000b101e230141016b24010b1e002000230141016a2401230141f4034b0440000b101f230141016b24010b0bce020100418080c0000bc402616d6f756e746765745f7061796d656e745f7075727365706179746573745f7061796d656e745f7061636b6167655f68617368746573745f7061796d656e745f616363657373636f6e74726163745f76657273696f6e746573745f7061796d656e745f6861736863616c6c656420604f7074696f6e3a3a756e77726170282960206f6e206120604e6f6e65602076616c7565000001000000040000000400000002000000030000000400000001000000000000000100000005000000060000000700000010000000110000001200000013000000270000002600000027000000260000001000000010000000100000001100000012000000130000002200000022000000420000002a0000001000000011000000120000001300000027000000260000002200000022000000420000002a00000041000000290000002100000021000000"
    }
    }
    }
    },
    {
    "key": "entry-point-v1-entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e-0c5d85bbfb4ae1310aff9ce7b0699549e6d5d5094eba44c5fe2b1e278a673166",
    "kind": {
    "Write": {
    "EntryPoint": {
    "V1CasperVm": {
    "name": "pay",
    "args": [
    {
    "name": "amount",
    "cl_type": "U512"
    }
    ],
    "ret": "Unit",
    "access": "Public",
    "entry_point_type": "Called",
    "entry_point_payment": "Caller"
    }
    }
    }
    }
    },
    {
    "key": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "kind": {
    "Write": {
    "AddressableEntity": {
    "protocol_version": "2.0.0",
    "entity_kind": {
    "SmartContract": "VmCasperV1"
    },
    "package_hash": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "byte_code_hash": "byte-code-9639481569c3940ce272402f0e9bc0ea535435ea9ffc18d8696e4af02c841354",
    "main_purse": "uref-7a9d9c0c33540e9fd4c1245f6ac687c7eacf98ac1072591adc3f83332a909d86-007",
    "associated_keys": [
    {
    "account_hash": "account-hash-58749b769807d041002896ca59f55ec1c87197f66b82d9aee229c91eed7dfc8d",
    "weight": 1
    }
    ],
    "action_thresholds": {
    "deployment": 1,
    "upgrade_management": 1,
    "key_management": 1
    },
    "message_topics": []
    }
    }
    }
    },
    {
    "key": "package-154847e85beee3b5cd1c769b8f01dbc4b93d1cea8370c0b3bc1858d0d248a48b",
    "kind": {
    "Write": {
    "Package": {
    "versions": [
    {
    "entity_version_key": {
    "protocol_version_major": 2,
    "entity_version": 1
    },
    "addressable_entity_hash": "addressable-entity-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    }
    ],
    "disabled_versions": [],
    "groups": [],
    "lock_status": "Unlocked"
    }
    }
    }
    },
    {
    "key": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-000",
    "kind": {
    "Write": {
    "CLValue": {
    "cl_type": "U32",
    "bytes": "01000000",
    "parsed": 1
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-1a77e4ba31d02a3941319349f259d5fb02ef3ed70f92775cd18b8aba359441e2",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "022e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a72607",
    "parsed": "uref-2e024fc493ffb93847290be74a6f921a4226c142b5b196654b5a9c724cb2a726-007"
    },
    "name": {
    "cl_type": "String",
    "bytes": "10000000636f6e74726163745f76657273696f6e",
    "parsed": "contract_version"
    }
    }
    }
    }
    },
    {
    "key": "named-key-entity-account-7ba7c904427d5fe653b99584c07c3c5963b6ea2e75ad87aea69b71a65bf6fcea-9dbabf5ba4a0f30fd2fc8085b3b0baccf6bedc38c362d571b7912387d0bd8f39",
    "kind": {
    "Write": {
    "NamedKey": {
    "named_key": {
    "cl_type": "Key",
    "bytes": "1102eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e",
    "parsed": "entity-contract-eb1c971063155d461059292e91cfe2212d45b79a49294b8d90bdae18cda6e59e"
    },
    "name": {
    "cl_type": "String",
    "bytes": "11000000746573745f7061796d656e745f68617368",
    "parsed": "test_payment_hash"
    }
    }
    }
    }
    }
    ],
    "messages": [],
    "error": null
    }
    }
    }
    }

    +
    \ No newline at end of file diff --git a/developers/json-rpc/minimal-compliance/index.html b/developers/json-rpc/minimal-compliance/index.html index 22232d6f2..6263faac1 100644 --- a/developers/json-rpc/minimal-compliance/index.html +++ b/developers/json-rpc/minimal-compliance/index.html @@ -1,49 +1,49 @@ - + -Required Methods for Minimal Compliance | Casper Docs - Redux +Required Methods for Minimal Compliance | Casper Docs - Redux - - + +
    Version: 1.5.X

    Required Methods for Minimal Compliance

    + submit an issue on Github
    Version: Next

    Required Methods for Minimal Compliance

    The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.

    • -

      chain_get_block - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers.

      +

      chain_get_block - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers.

    • -

      info_get_deploy - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy.

      +

      info_get_deploy - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy.

    • -

      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.

      +

      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 - The state root hash is one of the several global state identifiers used to query the network state after sending deploys.

      +

      chain_get_state_root_hash - The state root hash is one of the several global state identifiers used to query the network state after sending deploys.

    • -

      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_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 - 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 - 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 - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state.

      +

      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 - 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.

      +

      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 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.

    +
    note

    The deprecated methods state_get_balance and state_get_item should not be used.

    +

    In addition to these methods, a minimally compliant Casper SDK must account for the types 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.

    \ No newline at end of file diff --git a/developers/json-rpc/types_chain/index.html b/developers/json-rpc/types_chain/index.html index a8b77202a..815d5b7e5 100644 --- a/developers/json-rpc/types_chain/index.html +++ b/developers/json-rpc/types_chain/index.html @@ -1,21 +1,21 @@ - + -Types | Casper Docs - Redux +Types | Casper Docs - Redux - - + +
    Version: Next

    Types

    The following definitions expand on parameters seen elsewhere within the SDK standard and are provided for clarity and completeness.

    Account

    Structure representing a user's Account, stored in global state.

    @@ -25,7 +25,7 @@

    Accountaccount_hash

  • -

    action_thresholds

    +

    action_thresholds

  • associated_keys

    @@ -37,29 +37,74 @@

    Accountnamed_keys

  • -

    AccountHash

    -

    The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length.

    -

    ActionThresholds

    +

    AccountActionThresholds

    Thresholds that have to be met when executing an action of a certain type.

    Required Parameters:

    +

    AccountAssociatedKeys

    +

    A collection of weighted public keys (represented as account hashes) associated with an account.

    +

    AccountAssociatedKeyWeight

    +

    The weight associated with public keys in an account's associated keys.

    +

    AccountHash

    +

    The AccountHash is a 32-byte hash derived from a supported PublicKey. Its role is to standardize keys that can vary in length.

    +

    AccountIdentifier

    +

    Identifier of an account.

    +

    Contains one of:

    +

    ActivationPoint

    The first era to which the associated protocol version applies.

    +

    Any of:

    +

    AddressableEntity

    + +

    AddressableEntityHash

    +

    The hex-encoded address of the addressable entity.

    Approval

    A struct containing a signature and the public key of the signer.

    Required Parameters:

    @@ -71,6 +116,26 @@

    Approvalsigner

    +

    Array_of_AssociatedKey

    +

    An array of AssociatedKeys.

    +

    Array_of_BlockProof

    +

    An array of BlockProofs.

    +

    Array_of_EntityVersionAndHash

    +

    An array of EntityVersionAndHashes.

    +

    Array_of_EraReward

    +

    An array of EraRewards.

    +

    Array_of_MessageTopic

    +

    An array of MessageTopics.

    +

    Array_of_NamedEntryPoint

    +

    An array of named entry points.

    +

    Array_of_NamedUserGroup

    +

    An array of NamedUserGroups.

    +

    Array_of_PublicKeyAndBid

    +

    An array of bids associated with given public keys.

    +

    Array_of_PublicKeyAndDelegator

    +

    An array consisting of PublicKeyAndDelegators.

    +

    Array_of_ValidatorWeight

    +

    An array of ValidatorWeights.

    AssociatedKey

    A key granted limited permissions to an Account, for purposes such as multisig.

    Required Parameters:

    @@ -79,7 +144,7 @@

    AssociatedKey<

    account_hash

  • -

    weight

    +

    weight

  • AuctionState

    @@ -87,7 +152,7 @@

    AuctionStateRequired Parameters:

    • -

      bids All bids contained within a vector.

      +

      bids All bids contained within a vector.

    • block_height Block height.

      @@ -100,6 +165,8 @@

      AuctionState

    AvailableBlockRange

    +

    An unbroken, inclusive range of blocks.

    +

    Required Parameters:

    • low The inclusive lower bound of the range.

      @@ -108,6 +175,20 @@

      Availabl

      high The inclusive upper bound of the range.

    +

    BalanceHoldWithProof

    +

    Hold amount at a given block time.

    +

    Required Parameters:

    +
      +
    • +

      amount The amount in the hold.

      +
    • +
    • +

      proof A string proof that the given value is present in the Merkle trie.

      +
    • +
    • +

      time The block time at which the hold was created.

      +
    • +

    Bid

    An entry in the validator map.

    Required Parameters:

    @@ -131,12 +212,162 @@

    Bidvalidator_public_key Validator's public key.

    -

    Additional Parameters:

    +

    Optional Parameters:

    • vesting_schedule Vesting schedule for a genesis validator. None if non-genesis validator.
    +

    BidKind

    +

    Auction bid variants.

    +

    One of:

    +
      +
    • +

      Unified A unified record indexed on validator data, with an embedded collection of all delegator bids assigned to that validator. The `Unified`` variant is for legacy retrograde support; new instances will not be created going forward.

      +
    • +
    • +

      Validator A bid record containing only validator data.

      +
    • +
    • +

      Delegator A bid record containing only delegator data.

      +
    • +
    • +

      Bridge A bridge record pointing to a new ValidatorBid after the public key was changed.

      +
    • +
    • +

      Credit Credited amount.

      +
    • +
    +

    Block

    +

    A block after execution.

    +

    One of:

    + +

    BlockBodyV1

    +

    The body portion of a block prior to Casper 2.0.

    +

    Required Parameters:

    +
      +
    • +

      deploy_hashes The deploy hashes of the non-transfer deploys within the block.

      +
    • +
    • +

      proposer The public key of the validator that proposed the block.

      +
    • +
    • +

      transfer_hashes The deploy hashes of the transfers within the block.

      +
    • +
    +

    BlockBodyV2

    +

    The body portion of a block.

    +

    Required Parameters:

    +
      +
    • +

      rewarded_signatures List of identifiers for finality signatures for a particular past block.

      +
    • +
    • +

      transactions Map of transactions mapping categories to a list of transaction hashes.

      +
    • +

    BlockHash

    A cryptographic hash identifying a Block.

    +

    BlockHeader

    +

    The versioned header portion of a block. It encapsulates different variants of the BlockHeader struct.

    +

    One of:

    +
      +
    • +

      Version1 The legacy, initial version of the header portion of a block.

      +
    • +
    • +

      Version2 The version 2 of the header portion of a block.

      +
    • +
    +

    BlockHeaderV1

    +

    The header portion of a block prior to Casper 2.0.

    +

    Required Parameters:

    + +

    Optional Parameters:

    + +

    BlockHeaderV2

    +

    The header portion of a block.

    +

    Required Parameters:

    +
      +
    • +

      accumulated_seed A seed needed for initializing a future era.

      +
    • +
    • +

      body_hash The hash of the block's body.

      +
    • +
    • +

      current_gas_price The gas price of the era.

      +
    • +
    • +

      era_id

      +
    • +
    • +

      height The height of this block.

      +
    • +
    • +

      parent_hash The parent block's hash.

      +
    • +
    • +

      proposer The public key of the validator which proposed the block.

      +
    • +
    • +

      protocol_version The protocol version of the network from when this block was created.

      +
    • +
    • +

      random_bit A random bit needed for initializing a future era.

      +
    • +
    • +

      state_root_hash The root hash of global state after the deploys in this block have been executed.

      +
    • +
    • +

      timestamp The timestamp from when the block was proposed.

      +
    • +
    +

    Optional Parameters:

    +

    BlockIdentifier

    Identifier for possible ways to retrieve a Block.

      @@ -147,59 +378,170 @@

      BlockIdentif

      Height Identify and retrieve the Block with its height.

    +

    BlockProof

    +

    A validator's public key paired with a corresponding signature of a given block hash.

    +

    Required Parameters:

    +

    BlockSynchronizerStatus

    The status of the block synchronizer.

    +

    Optional Parameters:

    • -

      Historical The status of syncing a historical block, if any.

      +

      Historical The status of syncing a historical block, if any.

      +
    • +
    • +

      Forward The status of syncing a forward block, if any.

      +
    • +
    +

    BlockSyncStatus

    +

    The status of syncing an individual block.

    +

    Required Parameters:

    • +

      acquisition_state The state of acquisition of the data associated with the block as a string.

      +
    • +
    • block_hash The block hash.

    • +
    +

    Optional Parameters:

    +
      +
    • block_height The height of the block, if known.
    • +
    +

    BlockTime

    +

    A newtype wrapping a u64, which represents the block time.

    +

    BlockV1

    +

    A block after execution with the resulting global state root hash prior to Casper 2.0. This is the core component of the Casper linear blockchain.

    +

    Required Parameters:

    +
      +
    • +

      body The body portion of the block.

      +
    • -

      block_height The height of the block, if known.

      +

      hash The block hash identifying this block.

    • -

      acquisition_state The state of acquisition of the data associated with the block.

      +

      header The header portion of the block.

    +

    BlockV2

    +

    A block after execution, with the resulting global state root hash. This is the core component of the Casper linear blockchain.

    +

    Required Parameters:

    +
      +
    • +

      body The body portion of the block.

      +
    • +
    • +

      hash The block hash identifying this block.

    • -

      Forward The status of syncing a forward block, if any.

      +

      header The header portion of the block.

      +
    • +
    +

    Bridge

    +

    A bridge record pointing to a new ValidatorBid after the public key was changed.

    +

    Required Parameters:

    +

    Bytes

    +

    Hex-encoded bytes.

    +

    ByteCode

    +

    A container for a contract's Wasm bytes.

    +

    Required Parameters:

    +
    • -

      block_height The height of the block, if known.

      +

      bytes

    • -

      acquisition_state The state of acquisition of the data associated with the block.

      +

      kind

    +

    ByteCodeHash

    +

    The hex-encoded address of a smart contract AddressableEntity.

    +

    ByteCodeKind

    +

    The type of byte code.

    +

    One of:

    +
      +
    • +

      Empty Empty byte code.

      +
    • +
    • +

      V1CasperWasm Byte code to be executed with the version 1 Casper execution engine.

    -

    ChainspecRawBytes

    -

    The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.

    +

    BytesreprError

    +

    Serialization and deserialization errors.

    • -

      chainspec_bytes Hex-encoded raw bytes of the current chainspec.toml file.

      +

      EarlyEndOfStream Early end of stream while deserializing.

      +
    • +
    • +

      Formatting Formatting error while deserializing.

      +
    • +
    • +

      LeftOverBytes Not all input bytes were consumed.

      +
    • +
    • +

      OutOfMemory Out of memory error.

    • -

      maybe_genesis_accounts_bytes Hex-encoded raw bytes of the current genesis accounts.toml file.

      +

      NotRepresentable No serialized representation is available for a value.

    • -

      maybe_global_state_bytes Hex-encoded raw bytes of the current global_state.toml file.

      +

      ExceededRecursionDepth Exceeded a recursion depth limit.

      +
    • +
    +

    ChainspecRawBytes

    +

    The raw bytes of the chainspec.toml, genesis accounts.toml, and global_state.toml files.

    +

    Required Parameters:

    +
      +
    • chainspec_bytes Hex-encoded raw bytes of the current chainspec.toml file.
    • +
    +

    Optional Parameters:

    +

    Contract

    A contract struct that can be serialized as a JSON object.

    Required Parameters:

    +

    ContractHash

    The hash address of the contract.

    ContractPackage

    @@ -210,17 +552,31 @@

    ContractPack

    access_key

  • -

    disabled_versions

    +

    disabled_versions

    +
  • +
  • +

    groups

  • -

    groups

    +

    versions

  • -

    versions

    +

    lock_status

  • ContractPackageHash

    The hash address of the contract package.

    +

    ContractPackageStatus

    +

    An enum to determine the lock status of the contract package.

    +

    One of:

    +
      +
    • +

      Locked The package is locked and cannot be versioned.

      +
    • +
    • +

      Unlocked The package is unlocked and can be versioned.

      +
    • +

    ContractVersion

    The version of the contract.

    Required Parameters:

    @@ -235,6 +591,14 @@

    ContractVers

    protocol_version_major

    +

    ContractVersionKey

    +

    Major element of ProtocolVersion combined with ContractVersion.

    +

    ContractWasm

    +

    A container for a contract's Wasm bytes.

    +

    Required Parameter:

    +

    ContractWasmHash

    The hash address of the contract Wasm.

    Delegator

    @@ -275,7 +639,7 @@

    Deploypayment

  • -

    sessions

    +

    session

  • DeployHash

    @@ -332,46 +696,170 @@

    Diction
  • AccountNamedKey Lookup a dictionary item via an Account's named keys.

    Required Parameters:

    +
      +
    • key The Account key as a formatted string whose named keys contain dictionary_name.

      -

      dictionary_name The named key under which the dictionary seed URef is stored.

      -

      dictionary_item_key The dictionary item key formatted as a string.

    • -

      ContractNamedKey Lookup a dictionary item via a Contract's named keys.

      -

      key The contract key as a formatted string whose named keys contains dictionary_name.

      dictionary_name The named key under which the dictionary seed URef is stored.

      -

      dictionary_item_key The dictionary item key formatted as a string.

    • -

      URef Lookup a dictionary item via its seed URef.

      -

      seed_uref The dictionary's seed URef.

      dictionary_item_key The dictionary item key formatted as a string.

    • -
    • -

      Dictionary Lookup a dictionary item via its unique key.

      -
    -

    Digest

    -

    Hex-encoded hash digest.

    -

    DisabledVersions

    +
  • +
  • +

    ContractNamedKey Lookup a dictionary item via a Contract's named keys.

    Required Parameters:

    • -

      contract_version

      +

      key The contract key as a formatted string whose named keys contains dictionary_name.

    • -

      protocol_version_major

      +

      dictionary_name The named key under which the dictionary seed URef is stored.

      +
    • +
    • +

      dictionary_item_key The dictionary item key formatted as a string.

    -

    EntryPoint

    -

    Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters.

    +
  • +
  • +

    EntityNamedKey

    Required Parameters:

    • -

      access

      +

      key The entity address formatted as a string.

    • -

      args

      +

      dictionary_name The named key under which the dictionary seed URef is stored.

      +
    • +
    • +

      dictionary_item_key The dictionary item key formatted as a string.

      +
    • +
    +
  • +
  • +

    URef Lookup a dictionary item via its seed URef.

    +

    Required Parameters:

    +
      +
    • +

      seed_uref The dictionary's seed URef.

      +
    • +
    • +

      dictionary_item_key The dictionary item key formatted as a string.

      +
    • +
    +
  • +
  • +

    Dictionary Lookup a dictionary item via its unique key.

    +
  • + +

    Digest

    +

    Hex-encoded hash digest.

    +

    Effects

    +

    A log of all transforms produced during execution.

    +

    EntityActionThresholds

    +

    Thresholds that have to be met when executing an action of a certain type.

    +

    Required Parameters:

    + +

    EntityAddr

    +

    The address for an AddressableEntity which contains the 32 bytes and tagging information.

    +

    Any of:

    +
      +
    • +

      The address for a system entity account or contract.

      +
    • +
    • +

      The address of an entity that corresponds to an Account.

      +
    • +
    • +

      The address of an entity that corresponds to a user (non-system) smart contract.

      +
    • +
    +

    EntityAssociatedKeys

    +

    A collection of weighted public keys (represented as account hashes) associated with an account. See Array_of_AssociatedKey.

    +

    EntityAssociatedKeyWeight

    +

    The weight associated with public keys in an entity's associated keys.

    +

    EntityIdentifier

    +

    Identifier of an addressable entity.

    +

    One of:

    + +

    EntityKind

    +

    The type of Package.

    +

    One of:

    +
      +
    • +

      System Package associated with a native contract implementation.

      +
    • +
    • +

      Account Package associated with an Account hash.

      +
    • +
    • +

      SmartContract Packages associated with Wasm stored on chain.

      +
    • +
    +

    EntityOrAccount

    +

    An addressable entity or a legacy account.

    +

    One of:

    + +

    EntityVersionAndHash

    +

    An entity version associated with the given hash.

    +

    Required Parameters:

    + +

    EntityVersionKey

    +

    Major element of ProtocolVersion combined with EntityVersion.

    +

    Required Parameters:

    +
      +
    • +

      entity_version Automatically incremented value for a contract version within a major ProtocolVersion.

      +
    • +
    • +

      protocol_version_major Major element of ProtocolVersion with which a ContractVersion is compatible.

      +
    • +
    +

    EntryPoint

    +

    Metadata describing a callable entry point and its return value, if any. All required parameters should be declared, whereas all non-required parameters should not be declared. Non-required parameters should not be confused with optional parameters.

    +

    Required Parameters:

    + +

    EntryPoint2

    +

    Type signature of a method. Order of arguments matters since they can be referenced by index as well as their name.

    +

    Required Parameters:

    +

    EntryPointAccess

    Enum describing the possible access control options for a contract entry point.

    +

    One of:

    • Public A public entry point is callable by any caller.

      @@ -392,25 +904,135 @@

      EntryPointA
    • Groups Only callers from the authorized, listed groups may call this entry point. Note: If this list is empty then this entry point is not callable from outside the contract.

    • +
    • +

      Template A string type that can't be accessed directly but is kept in the derived Wasm bytes.

      +
    • +

    +

    EntryPointPayment

    +

    An enum specifying who pays for the invocation and execution of the entrypoint.

    +

    One of:

    +
      +
    • +

      Caller The caller must cover the cost.

      +
    • +
    • +

      SelfOnly The current execution will cover the cost to execute self but not the cost of any subsequently invoked contracts.

      +
    • +
    • +

      SelfOnward The current execution will cover the cost to execute self and the cost of any subsequently invoked contracts.

      +

    EntryPointType

    -

    Context of an entry point execution.

    +

    Context of an entry point execution. The most significant bit represents the version. For example, 0b0 represents session and contract entry points up to version 2.0. And, 0b1 is for versions 2.x and later (i.e. installer and utility entry points).

    +

    One of:

    • -

      session Executes in the caller's context.

      +

      Caller Runs using the calling entity's context. In v1.x, this was used for both session code that ran using the originating account's context and stored session code that ran in the caller's context. In v2.x, the renamed Caller variant is exclusively used for Wasm running using the initiating account entity's context. Previously installed 1.x stored session code should continue to work as the binary value matches, but we no longer allow such logic to be upgraded, nor do we allow new stored session code to be installed.

      +
    • +
    • +

      Called Runs within the called entity's context.

    • -

      contract Executes in the callee's context.

      +

      Factory This entry point is intended to extract a subset of bytecode. Runs within the called entity's context.

      +
    • +
    +

    EntryPointValue

    +

    The encaspulated representation of entrypoints.

    +

    One of:

    +
      +
    • +

      V1CasperVm Entrypoints to be executed against the V1 Casper VM.

      +
    • +
    • +

      V2CasperVm Entrypoints to be executed against the V2 Casper VM.

      +
    • +
    +

    EntryPointV2

    +

    The entry point for the V2 Casper VM.

    +

    Required Parameters:

    +
      +
    • +

      flags The flags as a uint32 integer.

      +
    • +
    • +

      function_index The selector as a uint32 integer.

      +
    • +
    +

    EraEndV1

    +

    Information related to the end of an era and validator weights for the following era prior to Casper 2.0.

    +

    Required Parameters:

    + +

    EraEndV2

    +

    Information related to the end of an era and validator weights for the following era.

    +

    Required Parameters:

    +
      +
    • +

      equivocators The set of equivocators.

      +
    • +
    • +

      inactive_validators Validators that haven't produced any units during the era.

      +
    • +
    • +

      next_era_gas_price The gas price for the next era as a uint8 integer. Minimum 0.0 motes.

      +
    • +
    • +

      next_era_validator_weights The validators for the upcoming era and their respective weights.

      +
    • +
    • +

      rewards The rewards distributed to the validators.

    EraID

    Era ID newtype.

    +

    EraIdentifier

    +

    Identifier for an era.

    +

    One of:

    +

    EraInfo

    Auction metadata. Intended to be recorded at each era.

    Required Parameters:

    +

    EraReport_for_PublicKey

    +

    Equivocation, reward and validator inactivity information.

    +

    Required Parameters:

    + +

    EraReward

    +

    A validator's public key paired with a measure of the value of its contribution to consensus, as a fraction of the configured maximum block reward.

    +

    Required Parameters:

    +
      +
    • +

      amount The reward amount.

      +
    • +
    • +

      validator The validator's public key.

      +
    • +

    EraSummary

    The summary of an era.

    Required Parameters:

    @@ -433,595 +1055,967 @@

    EraSummary

    ExecutableDeployItem

    Represents possible variants of an executable Deploy.

    -

    ModuleBytes

    -

    Executable specified as raw bytes that represent Wasm code and an instance of RuntimeArgs.

    +

    ExecutionInfo

    +

    The block hash and height in which a given deploy was executed, along with the execution result if known.

    Required Parameters:

      -
    • module_bytes Hex-encoded raw Wasm bytes. There are some special cases around passing module_bytes for payment code.
    • +
    • +

      block_hash The hash of the block in which the deploy was executed.

      +
    • +
    • +

      block_height The height of the block in which the deploy was executed.

      +
    -

    Additional Parameters:

    +

    Optional Parameters:

    -

    StoredContractByHash

    -

    Stored contract referenced by its ContractHash, entry point and an instance of RuntimeArgs.

    +

    ExecutionEffect

    +

    The journal of execution transforms from a single Deploy.

    Required Parameters:

    +

    ExecutionResult

    +

    The versioned result of executing a single Deploy.

    +

    One of:

    +
      +
    • +

      Version1 Version 1 of execution result type.

      +
    • +
    • +

      Version2 Version 2 of execution result type.

    • +
    +

    ExecutionResultV1

    +

    The result of executing a single deploy prior to Casper 2.0.

    +

    One of:

    +
    • -

      entry_point The name of an entry point.

      +

      Failure The result of a failed execution

      +

      Required Parameters:

      +

      effect

      +

      transfers

      +

      cost

      +

      error_message The error message associated with executing the Deploy.

    • -

      hash A hex-encoded hash.

      +

      Success The result of a successful execution.

      +

      Required Parameters:

      +

      effect

      +

      transfers

      +

      cost

    -

    StoredContractByName

    -

    Stored contract referenced by a named key existing in the signer's Account context, entry point and an instance of RuntimeArgs.

    +

    ExecutionResultV2

    +

    The result of executing a single transaction.

    Required Parameters:

    • -

      args Runtime arguments.

      +

      consumed How much gas was consumed executing this transaction.

      +
    • +
    • +

      cost How much was paid for this transaction.

      +
    • +
    • +

      effects The effects of executing this transaction.

      +
    • +
    • +

      initiator Who initiated this transaction.

      +
    • +
    • +

      limit The maximum allowed gas limit for this transaction.

      +
    • +
    • +

      payment Breakdown of payments made to cover the cost.

      +
    • +
    • +

      size_estimate The size estimate of the transaction

      +
    • +
    • +

      transfers A record of transfers performed while executing this transaction.

      +
    • +
    +

    Optional Parameters:

    +
      +
    • error_message If there is no error message, this execution was processed successfully. If there is an error message, this execution failed to fully process for the stated reason.
    • +
    +

    Gas

    +

    The Gas struct represents a U512 amount of gas.

    +

    GlobalStateIdentifier

    +

    Identifier for possible ways to query global state.

    +
      +
    • +

      BlockHash Query using a block hash.

      +
    • +
    • +

      BlockHeight Query using a block height.

    • -

      entry_point The name of an entry point.

      +

      StateRootHash Query using the state root hash.

      +
    • +
    +

    Group

    +

    A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.

    +

    InitiatorAddr

    +

    The address of the initiator of a transaction

    +

    Contains one of:

    +
      +
    • +

      publickey The public key of the initiator.

    • -

      name A named key.

      +

      accounthash The account hash derived from the public key of the initiator.

    -

    StoredVersionContractByHash

    -

    Stored versioned contract referenced by its ContractPackageHash, entry point and an instance of RuntimeArgs.

    +

    JsonBlockWithSignatures

    +

    A JSON-friendly representation of a block and the signatures for that block.

    Required Parameters:

    • -

      args Runtime arguments.

      +

      block The block.

    • -

      entry_point The name of an entry point.

      +

      proofs The proofs of the block, i.e. a collection of validators' signatures of the block hash.

    • +
    +

    JsonEraValidators

    +

    The validators for the given era.

    +

    Required Parameters:

    + -

    Additional Parameters:

    +

    JsonValidatorChanges

    +

    The changes in a validator's status.

    +

    Required Parameters:

      -
    • version An optional version of the contract to call. It will default to the highest enabled version if no value is specified.
    • +
    • +

      public_key The public key of the validator.

      +
    • +
    • +

      status_changes The set of changes to the validator's status.

      +
    -

    StoredVersionContractByName

    -

    Stored versioned contract referenced by a named key existing in the signer's Account context, entry point and an instance of RuntimeArgs.

    +

    JsonValidatorStatusChange

    +

    A single change to a validator's status in the given era.

    Required Parameters:

    +

    JsonValidatorsWeights

    +

    A validator's weight.

    +

    Required Parameters:

    +
    • -

      entry_point The name of an entry point.

      +

      public_key

    • -

      name A named key.

      +

      weight

    -

    Additional Parameters:

    +

    Key

    +

    The key as a formatted string, under which data can be stored in global state.

    +

    MessageChecksum

    +

    Message checksum as a formatted string.

    +

    MessageTopic

    +

    A topic for contract-level messages.

    +

    Required Parameters:

      -
    • version An optional version of the contract to call. It will default to the highest enabled version if no value is specified.
    • +
    • +

      topic_name A string used to identify the message topic.

      +
    • +
    • +

      topic_name_hash The hash of the name of the message topic.

      +
    -

    Transfer

    -

    A native transfer which does not contain or reference a Wasm code.

    +

    MessageTopicSummary

    +

    Summary of a message topic that will be stored in global state.

    Required Parameters:

      -
    • args
    • +
    • +

      blocktime

      +
    • +
    • +

      message_count The number of messages in this topic.

      +
    -

    ExecutionEffect

    -

    The journal of execution transforms from a single Deploy.

    +

    MinimalBlockInfo

    +

    Minimal info of a Block.

    Required Parameters:

    -

    ExecutionResult

    -

    The result of executing a single Deploy.

    +

    NamedArg

    +

    Named arguments to a contract.

    +

    NamedEntryPoint

    +

    A named entry point.

    +

    Required Parameters:

    • -

      Failure The result of a failed execution`

      +

      entry_point

      +
    • +
    • +

      name A string identifying the entry point.

      +
    • +
    +

    NamedKey

    +

    A named key.

    Required Parameters:

    -

    effect

    -

    transfers

    -

    cost

    -

    error_message The error message associated with executing the Deploy.

    +
      +
    • +

      key The value of the entry: a casper Key type.

    • -

      Success The result of a successful execution.

      +

      name The name of the entry.

      +
    • +
    +

    NamedKeys

    +

    A collection of named keys.

    +

    NamedKeyValue

    +

    A NamedKey value.

    Required Parameters:

    -

    effect

    -

    transfers

    -

    cost

    +
      +
    • +

      name The name of the Key encoded as a CLValue.

      +
    • +
    • +

      named_key The actual Key encoded as a CLValue.

    -

    FinalizedApprovals

    -

    A boolean value that determines whether to return the deploy with the finalized approvals substituted. If false or omitted, returns the deploy with the approvals that were originally received by the node.

    -

    GlobalStateIdentifier

    -

    Identifier for possible ways to query global state.

    +

    NamedUserGroup

    +

    A named group.

    +

    Required Parameters:

    -

    Group

    -

    A (labelled) "user group". Each entry point of a versioned contract may be associated with one or more user groups which are allowed to call it.

    -

    Groups

    +

    NextUpgrade

    +

    Information about the next protocol upgrade.

    +

    Required Parameters:

    + +

    Operation

    +

    An operation performed while executing a Deploy.

    +

    Required Parameters:

    +
      +
    • +

      key The formatted string of the Key.

      +
    • +
    • +

      kind

      +
    • +
    +

    OpKind

    +

    The type of operation performed while executing a Deploy.

    +

    One of:

    +
      +
    • +

      Read A read operation.

      +
    • +
    • +

      Write A write operation.

      +
    • +
    • +

      Add An addition.

      +
    • +
    • +

      NoOp An operation which has no effect.

      +
    • +
    • +

      Prune A prune operation.

      +
    • +
    +

    Package

    +

    Entity definition, metadata and security container.

    +

    Required Parameters:

    +
      +
    • +

      disabled_versions Collection of disabled entity versions. The runtime will not permit disabled entity versions to be executed.

      +
    • +
    • +

      groups Mapping maintaining the set of URefs associated with each user group, used to control access to methods in a particular version of the entity. A method is callable by any context which knows any of the URefs associated with the method's user group.

      +
    • +
    • +

      lock_status A flag that determines whether a entity is locked.

      +
    • +
    • +

      versions All versions (enabled & disabled).

      +
    • +
    +

    Parameter

    +

    Parameter to an entry point.

    +

    Required Parameters:

    + +

    PackageHash

    +

    The hex-encoded address of a package associated with an AddressableEntity.

    +

    PackageStatus

    +

    An enum to determine the lock status of the package.

    +

    One of:

    +
      +
    • +

      Locked The package is locked and cannot be versioned.

      +
    • +
    • +

      Unlocked The package is unlocked and can be versioned.

      +
    • +
    +

    PaymentInfo

    +

    Breakdown of payments made to cover the cost.

    +

    Required Parameters:

    +
      +
    • source Source purse used for payment of the transaction.
    • +
    +

    PeerEntry

    +

    Node peer entry.

    +

    Required Parameters:

    +
      +
    • +

      address Node address.

      +
    • +
    • +

      node_id Node ID.

      +
    • +
    +

    Peers

    +

    Map of peer IDs to network addresses.

    +

    PricingMode

    +

    The pricing mode of a transaction.

    +

    One of:

    +
      +
    • +

      Classic The original payment model, where the creator of the transaction specifies how much they will pay, at what gas price.

      +
    • +
    • +

      Fixed The cost of the transaction is determined by the cost table, per the transaction category.

      +
    • +
    • +

      Reserved The payment for this transaction was previously reserved (Not currently implemented).

      +
    • +
    +

    ProtocolVersion

    +

    Casper Platform protocol version.

    +

    PublicKey

    +

    Hex-encoded cryptographic public key, including the algorithm tag prefix.

    +

    PublicKeyAndBid

    +

    A bid associated with the given public key.

    +

    Required Parameters:

    + +

    PublicKeyAndDelegator

    +

    A delegator associated with the given validator.

    +

    Required Parameters:

    + +

    PurseIdentifier

    +

    The identifier of a purse.

    +

    One of:

    +
      +
    • +

      main_purse_under_public_key The main purse under a provided PublicKey.

      +
    • +
    • +

      main_purse_under_account_hash The main purse under a provided AccountHash.

      +
    • +
    • +

      main_purse_under_entity_addr The main purse of the account identified by this EntityAddr.

      +
    • +
    • +

      purse_uref A specific purse identified by the associated URef.

      +
    • +
    +

    ReservationKind

    +

    Container for bytes recording location, type and data for a gas reservation.

    Required Parameters:

    -

    JsonBid

    -

    An entry in a founding validator map representing a bid.

    +

    RewardedSignatures

    +

    Describes finality signatures that will be rewarded in a block. Consists of a vector of SingleBlockRewardedSignatures, each of which describes signatures for a single ancestor block. The first entry represents the signatures for the parent block, the second for the parent of the parent, and so on.

    +

    RuntimeArgs

    +

    Represents a collection of arguments passed to a smart contract.

    +

    SeigniorageAllocation

    +

    Information about a seigniorage allocation.

    +

    One of:

    +
      +
    • +

      Validator Info about a seigniorage allocation for a validator.

      Required Parameters:

      +

      amount Allocated amount.

      +

      validator_public_key Validator's public key.

      +
    • +
    • +

      Delegator Info about a seigniorage allocation for a delegator.

      +

      Require Parameters:

      +

      amount Allocated amount.

      +

      delegator_public_key Delegator's public key.

      +

      validator_public_key Validator's public key.

      +
    • +
    +

    Signature

    +

    Hex-encoded cryptographic signature, including the algorithm tag prefix.

    +

    SingleBlockRewardedSignatures

    +

    List of identifiers for finality signatures for a particular past block. That past block height is equal to current_height minus signature_rewards_max_delay, the latter being defined in the chainspec.

    +

    StoredValue

    +

    Representation of a value stored in global state.

    • -

      bonding_purse The purse that was used for bonding.

      +

      CLValue A Casper-specific value.

      +
    • +
    • +

      Account An Account.

      +
    • +
    • +

      ContractWasm A contract's Wasm.

      +
    • +
    • +

      Contract Entry points supported by a contract.

      +
    • +
    • +

      ContractPackage A contract definition, metadata, and security container.

      +
    • +
    • +

      LegacyTransfer A version 1 (legacy) transfer.

      +
    • +
    • +

      DeployInfo A record of a Deploy.

      +
    • +
    • +

      EraInfo Information about an era.

      +
    • +
    • +

      Bid A bid.

      +
    • +
    • +

      Withdraw A withdraw.

      +
    • +
    • +

      Unbonding Unbonding information.

      +
    • +
    • +

      AddressableEntity An AddressableEntity.

      +
    • +
    • +

      BidKind A variant that stored BidKind.

    • -

      delegation_rate The delegation rate.

      +

      [Package] A Package.

    • -

      delegators The delegators.

      +

      [ByteCode] A record of byte code.

    • -

      inactive Is this an inactive validator.

      +

      MessageTopic A variant that stores a message topic.

    • -

      staked_amount The amount of tokens staked by a validator (not including delegators).

      +

      Message A variant that stores a message digest.

    • -
    -

    JsonBids

    -

    A Json representation of a single bid.

    -

    Required Parameters:

    - -

    JsonBlock

    -

    A JSON-friendly representation of Block.

    -

    Required Parameters:

    +

    SystemEntityType

    +

    System contract types.

    • -

      body JSON-friendly Block body.

      +

      Mint

    • -

      hash BlockHash.

      +

      HandlePayment

    • -

      header JSON-friendly Block header.

      +

      StandardPayment

    • -

      proofs JSON-friendly list of proofs for this Block.

      +

      Auction

    -

    JsonBlockBody

    -

    A JSON-friendly representation of Body.

    -

    Required Parameters:

    +

    TimeDiff

    +

    Human-readable duration.

    +

    Timestamp

    +

    Timestamp formatted as per RFC 3339.

    +

    TopicNameHash

    +

    The hash of the name of the message topic.

    +

    Transaction

    +

    A versioned wrapper for a transaction or deploy.

    +

    Contains one of:

    + +

    or

    + +

    TransactionEntryPoint

    +

    An entry point of a transaction.

    +

    One of:

    • -

      deploy_hashes

      +

      Call The standard call entry point used in session code.

    • -

      proposer

      +

      Custom A non-native, arbitrary entry point.

    • -

      transfer_hashes

      +

      Transfer The transfer native entry point, used to reference motes from a source purse to a target purse.

    • -
    -

    JsonBlockHeader

    -

    JSON representation of a Block header.

    -
    • -

      accumulated_seed Accumulated seed.

      +

      AddBid The add_bid native entry point, used to create or top off a bid purse.

    • -

      body_hash The body hash.

      +

      WithdrawBid The withdraw_bid native entry point, used to decrease a validator's stake.

    • -

      era_id The Block era id.

      +

      Delegate The delegate native entry point, used to add a new delegator or increase an existing delegator's stake.

    • -

      height The Block height.

      +

      Undelegate The undelegate native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero.

    • -

      parent_hash The parent hash.

      +

      Redelegate The redelegate native entry point, used to reduce a delegator's stake or remove the delegator if the remaining stake is zero. After the unbonding delay, it will automatically delegate to a new validator.

    • -

      protocol_version The protocol version.

      +

      ActivateBid The activate_bid native entry point, used to used to reactivate an inactive bid.

    • -

      random_bit Randomness bit.

      +

      ChangeBidPublicKey The change_bid_public_key native entry point, used to change a bid's public key.

    • +
    +

    TransactionHash

    +

    A versioned wrapper for a transaction hash or deploy hash.

    +

    One of:

    + -

    Additional Parameters:

    - -

    JsonDelegator

    -

    A delegator associated with the given validator.

    -

    Required Parameters:

    +

    TransactionInvocationTarget

    +

    The identifier of a stored transaction target.

    +

    One of:

    • -

      bonding_purse

      +

      ByHash The hex-encoded entity address identifying the invocable entity.

    • -

      delegatee

      +

      ByName The alias identifying the invocable entity.

    • -

      public_key

      +

      ByPackageHash The address and optional version identifying the package.

      +

      Required Parameters:

      +
        +
      • addr The hex-encoded address of the package.
      • +
      +

      Optional parameters:

      +
        +
      • version The package version. If None, the latest enabled version is implied.
      • +
    • -

      staked_amount

      +

      ByPackageName The alias and optional version identifying the package.

      +

      Required Parameters:

      +
        +
      • name The package name.
      • +
      +

      Optional Parameters:

      +
        +
      • version The package version. If None, the latest enabled version is implied.
      • +
    -

    JsonEraEnd

    -

    Required Parameters:

    +

    TransactionRuntime

    +

    Runtime used to execute a transaction.

    +

    Parameters:

    -

    JsonEraReport

    -

    Equivocation and reward information to be included in the terminal Block.

    -

    Required Parameters:

    +

    TransactionScheduling

    +

    The scheduling mode of a transaction.

    +

    One of:

    • -

      equivocators

      +

      Standard No special scheduling applied.

    • -

      inactive_validators

      +

      FutureEra Execution should be scheduled for the specific era.

      +

      Required parameters for FutureEra:

      +
    • -

      rewards

      +

      FutureTimestamp Execution should be scheduled for the specific timestamp or later.

      +

      Required parameters for FutureTimestamp:

      +
    -

    JsonEraValidators

    -

    The validators for the given era.

    -

    Required Parameters:

    +

    TransactionTarget

    +

    The execution target of a Transaction.

    +

    One of:

    -

    JsonExecutionResult

    -

    The execution result of a single Deploy.

    +

    stored The execution target is a stored entity or package.

    +

    Required parameters for a stored target:

    -

    JsonProof

    -

    A JSON-friendly representation of a proof, i.e. a Block's finality signature.

    -

    Required Parameters:

    + +
  • +

    session The execution target is the included module bytes.

    +

    Required parameters for a session target:

    -

    JsonValidatorChanges

    -

    The changes in a validator's status.

    +
  • + +

    TransactionV1

    +

    A unit of work sent by a client to the network, which when executed can cause global state to be altered.

    Required Parameters:

    -

    JsonValidatorStatusChange

    -

    A single change to a validator's status in the given era.

    -

    Required Parameters:

    - -

    JsonValidatorsWeights

    -

    A validator's weight.

    +

    TransactionV1Body

    +

    The body of a TransactionV1.

    Required Parameters:

    -

    Merkle_Proof

    -

    A merkle proof is a construction created using a merkle trie that allows verification of the associated hashes.

    -

    MinimalBlockInfo

    -

    Minimal info of a Block.

    +

    TransactionV1Hash

    +

    A hex-encoded TransactionV1 hash.

    +

    TransactionV1Header

    +

    The header portion of a TransactionV1.

    Required Parameters:

    -

    NamedArg

    -

    Named arguments to a contract.

    -

    NamedKey

    -

    A named key.

    -

    Required Parameters:

    +

    Transfer

    +

    A versioned wrapper for a transfer.

    +

    One of:

    • -

      key The value of the entry: a casper Key type.

      +

      Version1 A version 1 transfer.

    • -

      name The name of the entry.

      +

      Version2 A version 2 transfer.

    -

    NextUpgrade

    -

    Information about the next protocol upgrade.

    +

    TransferAddr

    +

    Hex-encoded version 1 transfer address.

    +

    TransferV1

    +

    Represents a transfer from one purse to another.

    Required Parameters:

    -

    NewValidator

    -

    The public key for the new validator in a redelegation using UnbondingPurse.

    -

    Operation

    -

    An operation performed while executing a Deploy.

    -

    Required Parameters:

    -
    • -

      key The formatted string of the Key.

      +

      from Account from which transfer was executed.

    • -

      kind

      +

      gas

      +
    • +
    • +

      source Source purse.

      +
    • +
    • +

      target Target purse.

    -

    OpKind

    -

    The type of operation performed while executing a Deploy.

    -

    Parameter

    -

    Parameter to an entry point.

    -

    Required Parameters:

    +

    Optional Parameters:

    • -

      cl_type

      +

      id User-defined ID.

    • -

      name

      +

      to Account to which funds are transferred.

    -

    PeerEntry

    +

    TransferV2

    +

    Represents a version 2 transfer from one purse to another.

    Required Parameters:

    • -

      address

      +

      amount Transfer amount.

      +
    • +
    • +

      transaction_hash Transaction that created the transfer.

    • -

      node_id

      +

      from Entity from which transfer was executed.

    • -
    -

    PeersMap

    -

    Map of peer IDs to network addresses.

    -

    ProtocolVersion

    -

    Casper Platform protocol version.

    -

    PublicKey

    -

    Hex-encoded cryptographic public key, including the algorithm tag prefix.

    -

    PurseIdentifier

    -

    The identifier to obtain the purse corresponding to a balance query. Valid identifiers include:

    -
    • -

      main_purse_under_public_key The main purse under a provided PublicKey.

      +

      gas

    • -

      main_purse_under_account_hash The main purse under a provided AccountHash.

      +

      source Source purse.

    • -

      purse_uref A specific purse identified by the associated URef.

      +

      target Target purse.

    -

    ReactorState

    -

    The state of the reactor, which will return one of the following:

    +

    Optional Parameters:

    • -

      Initialize Get all components and reactor state set up on start.

      -
    • -
    • -

      CatchUp Orient to the network and attempt to catch up to tip.

      +

      id User-defined ID.

    • -

      Upgrading Running commit upgrade and creating immediate switch block.

      +

      to Account to which funds are transferred.

    • +
    +

    TransformError

    +

    Error type for applying and combining transforms. A TypeMismatch occurs when a transform cannot be applied because the types are not compatible (e.g. trying to add a number to a string).

    +

    One of:

    +
    • -

      KeepUp Stay caught up with tip.

      +

      serialization

    • -

      Validate Node is currently caught up and is an active validator.

      +

      typemismatch

    • -

      ShutdownForUpgrade Node should be shut down for upgrade.

      +

      deprecated Type no longer supported.

    -

    Reward

    +

    TransformV1

    +

    A transformation performed while executing a Deploy.

    Required Parameters:

    -

    RuntimeArgs

    -

    Represents a collection of arguments passed to a smart contract.

    -

    SeigniorageAllocation

    -

    Information about a seigniorage allocation.

    +

    TransformV2

    +

    A transformation performed while executing a Deploy.

    +

    Required Parameters:

    • -

      Validator Info about a seigniorage allocation for a validator.

      -

      Required Parameters:

      -

      amount Allocated amount.

      -

      validator_public_key Validator's public key.

      +

      key The formatted string of the Key.

    • -

      Delegator Info about a seigniorage allocation for a delegator.

      -

      Require Parameters:

      -

      amount Allocated amount.

      -

      delegator_public_key Delegator's public key.

      -

      validator_public_key Validator's public key.

      +

      kind The transformation.

    -

    Signature

    -

    Hex-encoded cryptographic signature, including the algorithm tag prefix.

    -

    StoredValue

    -

    Representation of a value stored in global state. Account, Contract and ContractPackage have their own json_compatibility representation (see their docs for further info).

    +

    TransformKindV1

    +

    The actual transformation performed while executing a Deploy in version 1.

    +

    One of:

    • -

      CLValue A Casper-specific value.

      -
    • -
    • -

      Account An Account.

      +

      Identity A transform having no effect.

    • -

      ContractWasm A contract's Wasm.

      +

      WriteCLValue Writes the given CLValue to global state.

    • -

      Contract Entry points supported by a contract.

      +

      WriteAccount Writes the given Account to global state.

    • -

      ContractPackage A contract definition, metadata, and security container.

      +

      WriteContractWasm Writes a smart contract as Wasm to global state.

    • -

      Transfer A record of a transfer.

      +

      WriteContract Writes a smart contract to global state.

    • -

      DeployInfo A record of a Deploy.

      +

      WriteContractPackage Writes a smart contract package to global state.

    • -

      EraInfo Auction metadata.

      +

      WriteDeployInfo Writes the given DeployInfo to global state.

    • -

      Bid A bid.

      +

      WriteEraInfo Writes the given EraInfo to global state.

    • -

      Withdraw A withdraw.

      +

      WriteTransfer Writes the given Transfer to global state.

    • -
    -

    TimeDiff

    -

    Human-readable duration.

    -

    Timestamp

    -

    Timestamp formatted as per RFC 3339.

    -

    Transfer

    -

    Represents a transfer from one purse to another.

    -

    Required Parameters:

    -
    • -

      amount Transfer amount.

      +

      WriteBid Writes the given Bid to global state.

    • -

      deploy_hash Deploy that created the transfer.

      +

      WriteWithdraw Writes the given Withdraw to global state.

    • -

      from Account from which transfer was executed.

      +

      WriteUnbonding Writes the given Unbonding to global state.

    • -

      gas

      +

      WriteAddressableEntity Writes the addressable entity to global state.

    • -

      source Source purse.

      +

      WriteBidKind Writes the given BidKind to global state.

    • -

      target Target purse.

      +

      AddInt32 Adds the given i32.

    • -
    -

    Additional Parameters:

    -
    • -

      id User-defined ID.

      +

      AddUInt64 Adds the given u64.

    • -

      to Account to which funds are transferred.

      +

      AddUInt128 Adds the given U128.

    • -
    -

    TransferAddr

    -

    Hex-encoded transfer address.

    -

    Transform

    -

    The actual transformation performed while executing a Deploy.

    -
    • -

      WriteCLValue Write the given CLValue to global state.

      +

      AddUInt256 Adds the given U256.

    • -

      WriteAccount Writes the given Account to global state.

      +

      AddUInt512 Adds the given U512.

    • -

      WriteDeployInfo Writes the given DeployInfo to global state.

      +

      AddKeys Adds the given collection of named keys.

    • -

      WriteEraInfo Writes the given EraInfo to global state.

      +

      Prune Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states.

    • -

      WriteTransfer Writes the given Transfer to global state.

      +

      Failure Represents the case where applying a transform would cause an error.

    • +
    +

    TransformKindV2

    +

    The actual transformation performed while executing a Deploy in version 2.

    +

    One of:

    +
    • -

      WriteBid Writes the given Bid to global state.

      +

      Identity A transform having no effect.

    • -

      WriteWithdraw Writes the given Withdraw to global state.

      +

      Write Writes the new value in global state.

    • AddInt32 Adds the given i32.

      @@ -1042,18 +2036,20 @@

      Transformnamed keys.

    • -

      Failure A failed transformation, containing an error message.

      +

      Prune Removes the pathing to the global state entry of the specified key. The pruned element remains reachable from previously generated global state root hashes, but will not be included in the next generated global state root hash and subsequent states.

      +
    • +
    • +

      Failure Represents the case where applying a transform would cause an error.

    -

    TransformEntry

    -

    A transformation performed while executing a Deploy.

    -

    Required Parameters:

    +

    TypeMismatch

    +

    An error struct representing a type mismatch in StoredValue operations.

    • -

      key The formatted string of the Key.

      +

      expected The name of the expected type.

    • -

      transforms The transformation.

      +

      found The actual type found.

    U128

    @@ -1081,32 +2077,79 @@

    UnbondingPurs
  • validator_public_key The original validator's public key.

  • -
  • -

    new_validator The redelegated validator's public key.

    -
  • + +

    Optional Parameters:

    +

    URef

    Hex-encoded, formatted URef.

    +

    ValidatorBid

    +

    An entry in the validator map.

    +

    Required Parameters:

    +
      +
    • +

      bonding_purse Bonding purse.

      +
    • +
    • +

      delegation_rate The delegation rate.

      +
    • +
    • +

      inactive true if the validator has been "evicted".

      +
    • +
    • +

      maximum_delegation_amount Minimum allowed delegation amount in motes.

      +
    • +
    • +

      minimum_delegation_amount Maximum allowed delegation amount in motes.

      +
    • +
    • +

      staked_amount The amount of tokens staked by a validator.

      +
    • +
    • +

      validator_public_key The validator's public key.

      +
    • +
    +

    Optional Parameters:

    +

    ValidatorChange

    A change to a validator's status between two eras.

    +

    One of:

    • -

      Added

      +

      Added The validator was just added to the validator set.

      +
    • +
    • +

      Removed The validator was removed from the validator set.

      +
    • +
    • +

      Banned The validator was banned from this era.

      +
    • +
    • +

      CannotPropose The validator was excluded from proposing new blocks in this era.

    • -

      Removed

      +

      SeenAsFaulty We saw the validator misbehave in this era.

    • +
    +

    ValidatorCredit

    +

    Validator credit record.

    +

    Required Parameters:

    +

    ValidatorWeight

    +

    A validator's public key paired with its weight, i.e. the total number of motes it staked together with its delegators.

    Required Parameters:

    • @@ -1118,6 +2161,14 @@

      ValidatorWei

    VestingSchedule

    Vesting schedule for a genesis validator.

    +

    Required Parameters:

    +
      +
    • initial_release_timestamp_millies Timestamp of the initial release.
    • +
    +

    Optional Parameters:

    +

    WithdrawPurse

    Withdraw purse, previously known as unbonding purse prior to 1.5. Withdraw purses remain as historical data.

    Required Parameters:

    @@ -1137,6 +2188,6 @@

    WithdrawPurse<
  • validator_public_key The original validator's public key.

  • -

    +
    \ No newline at end of file diff --git a/developers/json-rpc/types_cl/index.html b/developers/json-rpc/types_cl/index.html index 5237e60c7..63f3ddce6 100644 --- a/developers/json-rpc/types_cl/index.html +++ b/developers/json-rpc/types_cl/index.html @@ -1,58 +1,56 @@ - + -CLType | Casper Docs - Redux +CLType | Casper Docs - Redux - - + +
    Version: Next

    CLType

    Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.

    -
        `Bool`
    `I32`
    `I64`
    `U8`
    `U32`
    `U64`
    `U128`
    `U256`
    `U512`
    `Unit`
    `String`
    `Key`
    `URef`
    `PublicKey`
    `Any`
      -
    • -

      Option Option of a CLType.

      -
    • -
    • -

      List Variable-length list of a single CLType (comparable to a Vec).

      -
    • -
    • -

      ByteArray Fixed-length list of a single CLType (comparable to a Rust array).

      -
    • -
    • -

      Result Result with Ok and Err variants of CLType's.

      -
    • -
    • -

      Map Map with keys of a single CLType and values of a single CLType.

      -
    • -
    • -

      Tuple1 1-ary tuple of a CLType.

      -
    • -
    • -

      Tuple2 2-ary tuple of CLTypes.

      -
    • -
    • -

      Tuple3 3-ary tuple of CLTypes.

      -
    • +
    • Bool Primitive
    • +
    • I32 Primitive
    • +
    • I64 Primitive
    • +
    • U8 Primitive
    • +
    • U32 Primitive
    • +
    • U64 Primitive
    • +
    • U128 Large unsigned integer type
    • +
    • U256 Large unsigned integer type
    • +
    • U512 Large unsigned integer type
    • +
    • Unit Primitive
    • +
    • String Primitive
    • +
    • Key System type
    • +
    • URef System type
    • +
    • PublicKey System type
    • +
    • Option Option of a CLType
    • +
    • List Variable-length list of a single CLType (comparable to a Vec)
    • +
    • ByteArray Fixed-length list of a single CLType (comparable to a Rust array)
    • +
    • Result Result with Ok and Err variants of CLType's
    • +
    • Map Map with keys of a single CLType and values of a single CLType
    • +
    • Tuple1 1-ary tuple of a CLType
    • +
    • Tuple2 2-ary tuple of CLTypes
    • +
    • Tuple3 3-ary tuple of CLTypes
    • +
    • Any Unspecified type

    CLValue

    A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized Vec<u8> and also holds the CLType of the underlying data as a separate member. The parsed field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred.

    • -

      bytes A Casper serialized representation of the underlying value. For more information, reference the Serialization Standard.

      +

      bytes A Casper serialized representation of the underlying value. For more information, reference the Serialization Standard.

    • -

      cl_type

      +

      cl_type

    • -
    +
    \ No newline at end of file diff --git a/developers/prerequisites/index.html b/developers/prerequisites/index.html index 85ecddd3a..ff76ac767 100644 --- a/developers/prerequisites/index.html +++ b/developers/prerequisites/index.html @@ -1,25 +1,25 @@ - + -Development Prerequisites | Casper Docs - Redux +Development Prerequisites | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl'; -import Tabs from '@theme/Tabs'; + submit an issue on Github

    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Development Prerequisites

    -

    This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04. Casper does not officially support macOS, but the commands are included for your convenience. If you encounter any problems, reach out to the community on Telegram or Discord. Developing on Windows is not advised.

    +

    This page covers the necessary software for your Casper development environment. To develop comfortably, you should use Linux Ubuntu 20.04 or macOS. Developing on Windows is not advised.

    +
    caution

    Casper does not officially support macOS. If you encounter any problems, reach out to the community on Telegram or Discord.

    Preparing your Development Environment

    @@ -61,7 +61,7 @@

    cargo-casper --version

    note

    Familiarize yourself with the essential Casper crates described here.

    Installing the Casper Client

    -

    The default Casper client is on crates.io. This client can transmit your deploys to a Casper network.

    +

    The default Casper client is on crates.io. This client can transmit your transactions to a Casper network.

    cargo install casper-client

    Verify the installation:

    casper-client --version
    @@ -78,7 +78,7 @@

    You will find the casper-client executable in the target/release directory.

    Installing CMake

    If you plan to compile contracts from the source code, including those provided in the casper-node repository, install CMake with the commands below.

    -

    CMake is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the CMake website. Once installed, check your version as shown below.

    +

    CMake is a popular build tool that we will use, and you may have it installed. If you do, make sure that you have the latest version. If you need to install or upgrade it, follow the steps below or on the CMake website. Once installed, check your version as shown below.

    sudo apt-get -y install cmake
    @@ -120,9 +120,10 @@

    Settin

    Creating an account

    The Casper blockchain uses an on-chain account-based model, uniquely identified by an AccountHash derived from a specific PublicKey.

    -

    By default, a transactional interaction with the blockchain takes the form of a Deploy cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

    -

    Developers must create accounts using the Casper command-line client to access the secret_key.pem file needed during development.

    -

    Some Casper networks, such as the official Testnet and Mainnet, provide wallets that allow account creation as outlined here. However, these wallets do not give developers access to the secret key file.

    +

    By default, a transactional interaction with the blockchain takes the form of a Transaction cryptographically signed by the key-pair corresponding to the PublicKey used to create the account.

    +

    Users can create accounts using the Casper command-line client.

    +

    Alternatively, some Casper networks, such as the official Testnet and Mainnet, provide a browser-based block explorer that allows account creation as outlined here.

    +

    Use either method to generate an account and its corresponding cryptographic key-pair.

    Generating the account hash

    As a developer, you will often use an account hash, which is a 32-byte hash of the public key. This is because responses from the node contain AccountHashes instead of the direct hexadecimal-encoded public key. To view the account hash for a public key, use the account-address option of the Casper CLI client:

    casper-client account-address --public-key <path-to-public_key.pem/public-key-hex>
    @@ -131,21 +132,15 @@

    Funding an

    On Testnet, you can fund an account by requesting test tokens according to this guide. You can request test tokens only once for each account.

    On Mainnet, a pre-existing account must transfer CSPR tokens to the newly created account's main purse to finalize the setup. The source account needs to transfer CSPR tokens to the hexadecimal-encoded public key of the target account. This transfer will automatically create the target account if it does not exist. Currently, this is the only way to create an account on Mainnet.

    Acquiring a Node Address from the Network

    -

    Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, http://<node-address>:7777 by default.

    -

    The node address is the IP address or URL of a peer node.

    -

    Casper Labs provides public Casper node JSON-RPC endpoints for each network:

    - -

    Additionally, both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks.

    +

    Clients can interact with a node on the blockchain via requests sent to that node's JSON-RPC endpoint, http://<node-ip-address>:7777 by default.

    +

    The node address is the IP of a peer node.

    +

    Both the official Testnet and Mainnet provide block explorers that list the IP addresses of nodes on their respective networks.

    You can get the node-ip-address of a node on the network by visiting the following block explorers:

    You will see a list of peers, and you can select the IP of any peer on the list.

    -

    Note: If the selected peer is unresponsive, pick a different peer and try again.

    +

    Note: If the selected peer is unresponsive, pick a different peer and try again.

    \ No newline at end of file diff --git a/developers/writing-onchain-code/assembly-script/index.html b/developers/writing-onchain-code/assembly-script/index.html index 73eb6af66..b8a834e89 100644 --- a/developers/writing-onchain-code/assembly-script/index.html +++ b/developers/writing-onchain-code/assembly-script/index.html @@ -1,21 +1,21 @@ - + -Getting Started with AssemblyScript | Casper Docs - Redux +Getting Started with AssemblyScript | Casper Docs - Redux - - + +
    Version: 1.5.X

    Getting Started with AssemblyScript

    + submit an issue on Github
    Version: Next

    Getting Started with AssemblyScript

    Casper Labs maintains the casper-contract to allow developers to create smart contracts using AssemblyScript. The package source is hosted in the main Casper Network repository.

    Prerequisites

    Installing AssemblyScript

    @@ -27,7 +27,7 @@

    Installing the Casper Package

    The casper-contract package can be installed using the following command:

    npm i casper-contract
    -

    The AssemblyScript contract API documentation can be found at https://www.npmjs.com/package/casper-contract.

    +

    The Assemblyscript contract API documentation can be found at https://www.npmjs.com/package/casper-contract.

    Creating a Project

    For each smart contract, it is necessary to create a project directory and initialize it.

    The npm init process prompts for various details about the project. Answer as you see fit, but you may safely default everything except name, which needs to be specified. In this guide, we will refer to the contract name as your-contract-name.

    @@ -49,6 +49,6 @@

    Sample

    Compile to Wasm

    To compile the contract to Wasm, use npm to run the asbuild script from the project root:

    npm run asbuild
    -

    If the build is successful, there will be a dist folder in the root folder and in it should be your-contract-name.wasm.

    +

    If the build is successful, there will be a dist folder in the root folder and in it should be your-contract-name.wasm.

    \ No newline at end of file diff --git a/developers/writing-onchain-code/best-practices/index.html b/developers/writing-onchain-code/best-practices/index.html index 96cf0d100..4c1a9c70c 100644 --- a/developers/writing-onchain-code/best-practices/index.html +++ b/developers/writing-onchain-code/best-practices/index.html @@ -1,37 +1,37 @@ - + -Best Practices for Casper Smart Contract Authors | Casper Docs - Redux +Best Practices for Casper Smart Contract Authors | Casper Docs - Redux - - + +
    Version: 1.5.X

    Best Practices for Casper Smart Contract Authors

    + submit an issue on Github
    Version: Next

    Best Practices for Casper Smart Contract Authors

    At its core, the Casper platform is software, and best practices for general software development will apply. However, there are specific variables and situations that should be considered when developing for a Casper network. For example, a smart contract installed on global state cannot access file systems or open a connection to external resources.

    Data Efficiency

    -

    When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary Deploys will drastically decrease the overall cost.

    -

    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.

    +

    When developing on Casper, a policy of efficient data usage will ensure the lowest possible cost for on-chain computation. To this end, minimizing the number of necessary transactions will drastically decrease the overall cost.

    +

    When creating smart contracts, including an explicit initialization entry point allows the contract to self-initialize without a subsequent transaction of session code. This entry point creates the internal structure of the contract and cannot be called after the initial transaction. Below is an example of a self-initalizing entry point that can be used within the call function.

    Example Self-initialization Entry Point
    -

    // This entry point initializes the donation system, setting up the fundraising purse
    // and creating a dictionary to track the account hashes and the number of donations
    // made.
    #[no_mangle]
    pub extern "C" fn init() {
    let fundraising_purse = system::create_purse();
    runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());
    // Create a dictionary to track the mapping of account hashes to number of donations made.
    storage::new_dictionary(LEDGER).unwrap_or_revert();
    }

    +

    // This entry point initializes the donation system, setting up the fundraising purse
    // and creating a dictionary to track the account hashes and the number of donations
    // made.
    #[no_mangle]
    pub extern "C" fn init() {
    let fundraising_purse = system::create_purse();
    runtime::put_key(FUNDRAISING_PURSE, fundraising_purse.into());
    // Create a dictionary to track the mapping of account hashes to number of donations made.
    storage::new_dictionary(LEDGER).unwrap_or_revert();
    }

    pub extern "C" fn call() {
    let init_entry_point = EntryPoint::new(
    ENTRY_POINT_INIT,
    vec![],
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    );
    -

    Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial deployment.

    +

    Bear in mind, the host node will not enforce this. The smart contract author must create the entry point and ensure it cannot be called after initial transaction.

    Costs

    -

    Computations occurring on-chain come with associated gas costs. Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a Deploy is critical.

    +

    Computations occurring on-chain come with associated gas costs. Efficient coding can help to minimize gas costs, through the reduction of overall Wasm sent to global state. Beginning with 1.5.0, even invalid Wasm will incur gas costs when sent to global state. As such, proper testing prior to sending a transaction is critical.

    Further, there is a set cost of 2.5 CSPR to create a new purse. If possible, the reuse of purses should be considered to reduce this cost. If reusing purses, proper access management must be maintained to prevent lapses in security. Ultimately, any choices made in regards to security and contract safeguards rely on the smart contract author.

    Tips to reduce WASM size

    -

    Deploys have a maxim size specified in each network chainspec as max_deploy_size. For example, networks running node version 1.5.1, have the following maximum deploy size in bytes:

    -
    max_deploy_size = 1_048_576
    -

    Here are a few tips to reduce the size of Wasm included in a deploy:

    +

    Transactions have a maxim size specified in each network chainspec as max_transaction_size = 1_048_576. For example, networks running node version 2.0, have the following maximum transaction size in bytes:

    +
    max_transaction_size = 1_048_576
    +

    Here are a few tips to reduce the size of Wasm included in a transaction:

    1. Build the smart contract in release mode. You will find an example here

      @@ -55,7 +55,7 @@

      Tip

      Inlining

      As often as practicable, developers should inline functions by including the body of the function within their code rather than making call or call_indirect to the function. In the context of coding for Casper blockchain purposes, this reduces the overhead of executed Wasm and prevents unexpected errors due to exceeding resource tolerances.

      Testing

      -

      Testing all Deploys prior to committing them to Mainnet can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending Deploys to Testnet.

      +

      Testing all transactions prior to committing them to Mainnet can assist authors in detecting bugs and inefficiencies prior to incurring gas fees. Casper provides several methods of testing, including unit testing, testing using NCTL and sending transactions to Testnet.

      Information on these processes can be found at the following locations:

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/calling-contracts/index.html b/developers/writing-onchain-code/calling-contracts/index.html index f74bbcb73..3fe0848cb 100644 --- a/developers/writing-onchain-code/calling-contracts/index.html +++ b/developers/writing-onchain-code/calling-contracts/index.html @@ -1,23 +1,23 @@ - + -Calling Contracts | Casper Docs - Redux +Calling Contracts | Casper Docs - Redux - - + +
    Version: 1.5.X

    Calling Contracts

    -

    Calling a contract on a Casper network requires the use of a deploy. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the deploy for you, using the arguments you provide. This document outlines the various deploy variants through which you can execute Wasm or invoke the execution of on-chain Wasm.

    -

    Using Deploy Variants

    + submit an issue on Github
    Version: Next

    Calling Contracts

    +

    Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.

    +

    Using Legacy Deploy Variants

    ModuleBytes

    ModuleBytes is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm.

    However, you can also use ModuleBytes to deploy session code that calls a contract.

    @@ -29,16 +29,16 @@

    StoredC

    StoredContractByName

    StoredContractByName is similar to StoredContractByHash, with the main difference being the reference used to invoke on-chain Wasm. Where StoredContractByHash requires the contract hash, StoredContractByName uses a string stored as a NamedKey in the caller's account.

    This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's NamedKeys.

    -

    StoredVersionedContractByHash

    +

    StoredVersionedContractByHash

    StoredVersionedContractByHash is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package.

    This makes StoredVersionedContractByHash more stable than StoredContractByHash, as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version.

    DApp developers that use contracts developed by other parties can use StoredVersionedContractByHash to avoid interruptions from contract version changes.

    Further information on the structure of StoredVersionedContractByHash can be found here.

    -

    StoredVersionedContractByName

    +

    StoredVersionedContractByName

    StoredVersionedContractByName combines the functionality of StoredContractByName and StoredVersionedContractByHash. It allows a developer to store a reference string as a NamedKey within their account context that references a contract by its contract package hash.

    Further information on the structure of StoredVersionedContractByName can be found here.

    Transfer

    Native Transfers are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network.

    -

    Further information on the structure of a native Transfer can be found here.

    +

    Further information on the structure of a native Transfer can be found here.

    \ No newline at end of file diff --git a/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html b/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html index 0b7fa6903..9a70bdaa1 100644 --- a/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html +++ b/developers/writing-onchain-code/contract-hash-vs-package-hash/index.html @@ -1,24 +1,23 @@ - + -Contract Hash vs. Package Hash | Casper Docs - Redux +Contract Hash vs. Package Hash | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Using the Contract Hash vs. the Package Hash

    + submit an issue on Github
    Version: Next

    Using the Contract Hash vs. the Package Hash

    This page describes the possibilities of using the contract hash vs. the contract package hash (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, 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

    +

    Package Representation

    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:

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/contract-vs-session/index.html b/developers/writing-onchain-code/contract-vs-session/index.html index af86ee1d6..55d12c261 100644 --- a/developers/writing-onchain-code/contract-vs-session/index.html +++ b/developers/writing-onchain-code/contract-vs-session/index.html @@ -1,21 +1,21 @@ - + -Contracts and Session Code | Casper Docs - Redux +Contracts and Session Code | Casper Docs - Redux - - + +
    Version: Next

    Contracts and Session Code

    What is Session Code?

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the call function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse.

    The best use of session code is when the situation calls for stateless execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary.

    @@ -50,13 +50,13 @@

    Writing Session Code.For more information on writing contracts, see Writing a Basic Smart Contract in Rust. +
    Session CodeContract Code
    Session code always executes in the context of the account that signed the transaction containing the session code.A smart contract, which is stored on-chain logic, executes within its own context.
    Session code has only one entry point, call, which can be used to interact with the session code.A smart contract can have multiple entry points that can be invoked.
    The call entry point initiates any action the session code takes.Any action undertaken by a contract must initiate through an outside call, usually via session code.
    When a put_key call is made within the body of the session code, the key is added to the account's named keys.When a put_key call is made within the smart contract's context, the contract's record is modified to have a new named_key entry.
    For more information on how to write session code, see Writing Session Code.For more information on writing contracts, see Writing a Basic Smart Contract in Rust.

    The following image depicts the comparison presented in the table.

    Comparing Session and Contract Code

    What's Next?

    +
    \ No newline at end of file diff --git a/next/developers/writing-onchain-code/emitting-contract-events/index.html b/developers/writing-onchain-code/emitting-contract-events/index.html similarity index 91% rename from next/developers/writing-onchain-code/emitting-contract-events/index.html rename to developers/writing-onchain-code/emitting-contract-events/index.html index 83ab1573a..5d0c206e8 100644 --- a/next/developers/writing-onchain-code/emitting-contract-events/index.html +++ b/developers/writing-onchain-code/emitting-contract-events/index.html @@ -3,20 +3,20 @@ -Contract-Level Events | Casper Docs - Redux +Contract-Level Events | Casper Docs - Redux - - + +
    Version: Next

    Enabling Contracts to Emit Events

    -

    Smart contracts can be programmed to emit messages while executing. Under certain conditions, an off-chain dApp may listen to these events and react as described in Monitoring and Consuming Events.

    + submit an issue on Github
    +
  • Learn to install a contract and query global state.
  • +
  • Learn to monitor and consume the event stream.
  • +
    \ No newline at end of file diff --git a/next/developers/writing-onchain-code/factory-pattern/index.html b/developers/writing-onchain-code/factory-pattern/index.html similarity index 79% rename from next/developers/writing-onchain-code/factory-pattern/index.html rename to developers/writing-onchain-code/factory-pattern/index.html index 09edc1814..26160eccc 100644 --- a/next/developers/writing-onchain-code/factory-pattern/index.html +++ b/developers/writing-onchain-code/factory-pattern/index.html @@ -3,26 +3,26 @@ -Factory Contracts | Casper Docs - Redux +Factory Contracts | Casper Docs - Redux - - + +
    Version: Next

    Writing Contracts using the Factory Pattern

    This guide presents a factory pattern for simple counter contracts to showcase the Casper APIs that support this pattern. The example contract in this guide is a modified counter contract found here.

    The factory pattern is a widely recognized software design concept used in various programming contexts. DApp developers may use factory implementations to create smart contracts from a given source (or factory), such as a factory method or entry point. A factory pattern ensures that the contracts produced maintain a specified behavior, such as specific entry points and arguments. In general, factories produce other smart contracts according to a template.

    Casper factories are created using the entry point type called EntryPointType::Install, which marks an entry point as a factory method responsible for creating and installing contracts on the chain. An installer entry point will derive new Wasm based on the original session Wasm and create a new contract with different sets of entry points as required. In other words, these installer entry points marked with EntryPointType::Install are the contract factories. When referring to the factory contract on this page, we mean the contract containing the factory entry points.

    The EntryPointAccess::Template marks an entry point that exists in the bytecode but is not callable. Thus, regular entry points can be referenced from within installer entry points marked with EntryPointType::Install. In object-oriented terms, entry points marked with EntryPointAccess::Template act as virtual abstract methods and cannot be called from session code.

    note

    This factory pattern poses a known drawback when using Wasm. All the smart contracts created with the factory pattern share the same Wasm installed on the chain. Thus, developers cannot modify the Wasm once installed and create modified contracts using the factory pattern. Developers must specify all the possible entry points in the parent contract and tag them with the EntryPointAccess::Template marker.

    The Counter Factory Example

    -

    This section dives into a simple counter that uses factory methods to describe how to implement the factory pattern on a Casper network. The Counter on the Testnet Tutorial demonstrates the non-factory version of the counter contract.

    +

    This section dives into a simple counter that uses factory methods to describe how to implement the factory pattern on a Casper network. The Counter on the Testnet Tutorial demonstrates the non-factory version of the counter contract.

    Let's start by exploring the session code, where the contract entry points are defined.

    Two installer entry points are marked with EntryPointType::Install, meaning these entry points will produce new counter contracts once this Wasm is installed in global state. They are also marked with EntryPointAccess::Public so that they can be called from the session code.

    let entry_point: EntryPoint = EntryPoint::new(
    CONTRACT_FACTORY_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Install,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    CONTRACT_FACTORY_DEFAULT_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Install,
    );
    @@ -31,12 +31,12 @@

    On line 68, the contract_factory_default entry point creates a counter contract with a given name and a zero initial value.

    #[no_mangle]
    pub extern "C" fn contract_factory_default() {
    let name: String = runtime::get_named_arg(ARG_NAME);
    installer(name, U512::zero());
    }
    note

    The factory pattern can produce contracts with different entry points. Suppose the session code defines entry points A, B, C, and D as templates. One installer factory entry point could use entry points A and B to create a contract, and the other installer entry point might use entry points C and D. Such support at the API level enables the implementation of more complex use cases.

    -

    The installer function creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's decrement and increment functionality. These entry points are defined just like in any other smart contract, with EntryPointAccess::Public and EntryPointType::Contract, and they are callable for all the counters created. To learn how to call the increment and decrement functions, see the Counter on the Testnet Tutorial, which is the non-factory version of the counter contract.

    +

    The installer function creates a new counter contract by specifying its named keys and entry points. The named keys include the counter's initial value, and the entry points define the counter's decrement and increment functionality. These entry points are defined just like in any other smart contract, with EntryPointAccess::Public and EntryPointType::Contract, and they are callable for all the counters created. To learn how to call the increment and decrement functions, see the Counter on the Testnet Tutorial, which is the non-factory version of the counter contract.

    Sample installer code for a counter factory
    fn installer(name: String, initial_value: U512) {
    let named_keys = {
    let new_uref = storage::new_uref(initial_value);
    let mut named_keys = NamedKeys::new();
    named_keys.insert(CURRENT_VALUE_KEY.to_string(), new_uref.into());
    named_keys
    };

    let entry_points = {
    let mut entry_points = EntryPoints::new();
    let entry_point: EntryPoint = EntryPoint::new(
    INCREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    DECREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);

    entry_points
    };

    let (contract_hash, contract_version) = storage::new_contract(
    entry_points,
    Some(named_keys),
    Some(PACKAGE_HASH_KEY_NAME.to_string()),
    Some(ACCESS_KEY_NAME.to_string()),
    );

    runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());
    runtime::put_key(&name, contract_hash.into());
    }
    -

    It is important to note that the installer logic saves the newly created contract version and contract hash under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the comparison between session and contract context.

    +

    It is important to note that the installer logic saves the newly created contract version and contract hash under the factory contract's named keys. The installer logic runs within the factory contract context, not as part of the session code running within the account context. For more details, see the comparison between session and contract context.

    runtime::put_key(CONTRACT_VERSION, storage::new_uref(contract_version).into());
    runtime::put_key(&name, contract_hash.into());

    For example, if you install the factory counter contract, you will see only one named key for this contract in your account, with the two installer entry points contract_factory and contract_factory_default. See lines 155-163.

    If you call the installer three times to create 3 different counters, you will see 3 named keys for each counter in the factory contract's named keys. The counter contracts produced will have the increment and decrement entry points.

    @@ -44,7 +44,7 @@

    let entry_point: EntryPoint = EntryPoint::new(
    INCREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Template,
    EntryPointType::Contract,
    );
    entry_points.add_entry_point(entry_point);
    let entry_point: EntryPoint = EntryPoint::new(
    DECREASE_ENTRY_POINT.to_string(),
    Parameters::new(),
    CLType::Unit,
    EntryPointAccess::Template,
    EntryPointType::Contract,
    );
    warning

    Suppose developers forget to declare an entry point in the outermost session logic (the call function) and mark it with EntryPointAccess::Template; that Wasm export will be removed when the factory contract is installed in global state. Creating the entry point in the installer logic is not sufficient.

    Unit tests

    -

    Developers can test contracts that follow the factory pattern using the Casper testing framework described under Unit Testing Smart Contracts. The testing process is the same, but this section highlights a particular test called should_install_and_use_factory_pattern found in the unit test suite of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior.

    +

    Developers can test contracts that follow the factory pattern using the Casper testing framework described under Unit Testing Smart Contracts. The testing process is the same, but this section highlights a particular test called should_install_and_use_factory_pattern found in the unit test suite of the counter factory. As the name suggests, the test installs a contract that uses the factory pattern and checks its behavior.

    On line 120, the test starts building a request to call the contract_factory entry point with counter name new-counter-1 and value 1. On line 134, the test calls another factory entry point called contract_factory_default with counter name new-counter-2. The default counter value is 0.

    Once the requests are processed, the test checks the contract hashes of the contracts created:

    +
  • Best Practices for Casper Smart Contract Authors - An outline of best practices when developing smart contracts on a Casper network
  • +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/getting-started/index.html b/developers/writing-onchain-code/getting-started/index.html index 9519cfbfc..044d0b6f1 100644 --- a/developers/writing-onchain-code/getting-started/index.html +++ b/developers/writing-onchain-code/getting-started/index.html @@ -1,28 +1,31 @@ - + -Getting Started with Rust | Casper Docs - Redux +Getting Started with Rust | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Getting Started with Rust Casper Contracts

    + submit an issue on Github
    Version: Next

    Getting Started with Rust Casper Contracts

    This guide covers additional prerequisites for writing your first Casper smart contract. You will also build a sample smart contract and run a few basic tests on it on your local machine.

    Casper's blockchain is built upon the Rust programming language and compiles to WebAssembly. This guide will walk you through the steps to write your first contract, assuming you have already set up your development environment as described here.

    Creating a Project

    You can create a new sample project very easily with the cargo casper crate. For example, let's say that I want to create a project named my-project for this tutorial (you can choose a different name if you wish), then I can simply run the command:

    cargo casper my-project

    If you look inside the newly-created my-project folder, you will find two crates: contract and tests. This is a complete basic smart contract that saves a value, passed as an argument, on the blockchain. The tests crate provides a runtime environment of the Casper virtual machine, and a basic smart contract test.

    +

    Reproducibility

    +

    Currently, cargo does not provide cross-platform reproducibility for binary files, including WebAssembly. The ability to compile a smart contract to the same binary file is important, for example, when verifying that the smart contract binary stored on the blockchain is the same as the provided source code.

    +

    To work around the issue, cargo casper crate provides rustc wrapper, which can be enabled using --wrapper option.

    +
    cargo casper my_project --wrapper

    Using the nightly toolchain

    Navigate to the my-project folder and open the rust-toolchain file. You will notice that the file's contents specify a nightly version of Rust. Here is an example:

    nightly-2022-08-03
    @@ -72,6 +75,6 @@

    Rust Resource
  • https://doc.rust-lang.org/book/foreword.html
  • https://rustwasm.github.io/docs/book/
  • https://doc.rust-lang.org/stable/rust-by-example
  • -

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/simple-contract/index.html b/developers/writing-onchain-code/simple-contract/index.html index 540d83409..6939c664f 100644 --- a/developers/writing-onchain-code/simple-contract/index.html +++ b/developers/writing-onchain-code/simple-contract/index.html @@ -1,28 +1,27 @@ - + -Writing a Basic Smart Contract in Rust | Casper Docs - Redux +Writing a Basic Smart Contract in Rust | Casper Docs - Redux - - + +
    Version: 1.5.X

    Writing a Basic Smart Contract in Rust

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Writing a Basic Smart Contract in Rust

    What is a Smart Contract?

    -

    A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a Deploy. Casper smart contracts are programs that run on a Casper network. They interact with accounts and other contracts through entry points, allowing for various triggers, conditions, and logic.

    +

    A smart contract is a self-contained program installed on a blockchain. In the context of a Casper network, a smart contract consists of contract code installed on-chain using a transaction. Casper smart contracts are programs that run on a Casper network. They interact with entities through entry points, allowing for various triggers, conditions, and logic.

    Smart contracts exist as stored on-chain logic, allowing disparate users to call the included entry points. These contracts can, in turn, call one another to perform interconnected operations and create more complex programs. The decentralized nature of blockchain technology means that these smart contracts do not suffer from any single point of failure. Even if a Casper node leaves the network, other nodes will continue to allow the contract to operate as intended.

    Key Features of Casper Contracts

    -

    On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be sent to a node on a Casper network using a Deploy. Nodes within the network then gossip deploys, include them within a block, and finalize them. After finalizing, the network executes the deploys within the block.

    -

    Further, the Casper platform allows for upgradable contracts. A ContractPackage is created through the new_contract or new_locked_contract methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ContractPackageHash. The new contract is added to this package with a ContractHash key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable.

    +

    On the Casper platform, developers may write smart contracts in any language that compiles to Wasm binaries. This tutorial focuses specifically on writing a smart contract in the Rust language. The Rust compiler compiles the contract code into Wasm. After that, the Wasm binary can be sent to a node on a Casper network using a transaction. Nodes within the network then gossip transactions, include them within a block, and finalize them. After finalizing, the network executes the transactions within the block.

    +

    Further, the Casper platform allows for upgradable contracts. A ContractPackage is created through the new_contract or new_locked_contract methods. Through these methods, the Casper execution engine automatically creates the new contract package and assigns a ContractPackageHash. The new contract is added to this package with a ContractHash key. The execution engine stores the new contract within the contract package alongside any previously installed contract versions, if applicable.

    The new_contract and new_locked_contract methods are a convenience that automatically creates the package associated with a new contract. Developers choosing not to use these methods must first create a contract package to function as a container for their new contract.

    The contract contains required metadata, and it is primarily identified by its ContractHash. While the contract hash identifies a specific ContractVersion, the ContractPackageHash serves as an identifier for the most recent contract version in the contract package.

    Creating the Directory Structure

    @@ -34,7 +33,7 @@

    Auto
    cargo casper my-project

    The cargo casper command will generate an example contract in the contract directory and an example tests crate with logic defined in the integration-tests.rs file. The Makefile includes commands to prepare and build the contract, and the rust-toolchain file specifies the target build version of Rust.

    Semi-automatically using plain cargo

    -
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended and the command creates everything you need to start coding.

    +
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended and the command creates everything you need to start coding.

    1. Create a top-level project directory for the contract code and its corresponding tests.

      @@ -72,7 +71,7 @@

      nightly-2022-08-03

    Manually

    -
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended, and the command creates everything you need to start coding.

    +
    tip

    If you are a beginner, creating the structure automatically with cargo casper is recommended, and the command creates everything you need to start coding.

    1. Create a top-level project directory to store the contract code and corresponding tests.

      @@ -127,9 +126,9 @@

      Defining the global constants

      After importing the necessary dependencies, you should define the constants used within the contract, including entry points and values. The following example outlines the necessary constants for the counter contract.

      // Creating constants for values within the contract package.
      const CONTRACT_PACKAGE_NAME: &str = "counter_package_name";
      const CONTRACT_ACCESS_UREF: &str = "counter_access_uref";

      // Creating constants for the various contract entry points.
      const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";
      const ENTRY_POINT_COUNTER_GET: &str = "counter_get";

      // Creating constants for values within the contract.
      const CONTRACT_VERSION_KEY: &str = "version";
      const CONTRACT_KEY: &str = "counter";
      const COUNT_KEY: &str = "count";
      -

      Defining the contract entry points

      +

      Defining the contract entry points

      Entry points provide access to contract code installed in global state. Either session code or another smart contract may call these entry points. A contract must have at least one entry point and may have more than one entry point. Entry points are defined by their name, and those names should be clear and self-describing. Each entry point is equivalent to a static main entry point in a traditional program.

      -

      Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the Deploy. Note that another smart contract may access any of these entry points.

      +

      Entry points are not functions or methods, and they have no arguments. They are static entry points into the contract's logic. Yet, the contract logic can access parameters by name, passed along with the transaction. Note that another smart contract may access any of these entry points.

      If an entry point has one or more mandatory parameters that will cause the logic to revert if they are not included, declare them within that entry point. Optional and non-critical parameters should be excluded.

      When defining entry points, begin with a #[no_mangle] line to ensure the system does not change critical syntax within the method names. Each entry point should contain the contract code that drives the action you wish it to accomplish. Finally, include any storage or return values needed, as applicable.

      The following entry point is an example from the counter contract. To see all the available entry points, review the contract in GitHub.

      @@ -164,7 +163,7 @@

      D
    2. The String is the name given to identify the data
    3. The Key is the data to be referenced
    4. -

      You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, deploy information, purse balances, etc. The list of possible Key variants can be found here.

      +

      You can create named keys to store any record or value as needed, such as other accounts, smart contracts, URefs, transfers, transaction information, purse balances, etc. The list of possible Key variants can be found here.

      For the counter, we store the integer that we increment into a named key.

          // In the named keys of the counter contract, add a key for the count.
      let mut counter_named_keys = NamedKeys::new();
      let key_name = String::from(COUNT_KEY);
      counter_named_keys.insert(key_name, count_start.into());
        @@ -176,7 +175,7 @@

        D
        1. Create additional named keys.
        -

        Generally, the Contract_Hash and Contract_Version are saved as NamedKeys in the account's context for later use.

        +

        Generally, the Contract_Hash and Contract_Version are saved as NamedKeys for later use.

            // Store the contract version in the context's named keys.
        let version_uref = storage::new_uref(contract_version);
        runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());

        // Create a named key for the contract hash.
        runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());

        The complete call function should look like this:

        #[no_mangle]
        pub extern "C" fn call() {
        // Initialize the count to 0 locally
        let count_start = storage::new_uref(0_i32);
        // Create the entry points for this contract
        let mut counter_entry_points = EntryPoints::new();

        counter_entry_points.add_entry_point(EntryPoint::new(
        ENTRY_POINT_COUNTER_GET,
        Vec::new(),
        CLType::I32,
        EntryPointAccess::Public,
        EntryPointType::Contract,
        ));

        counter_entry_points.add_entry_point(EntryPoint::new(
        ENTRY_POINT_COUNTER_INC,
        Vec::new(),
        CLType::Unit,
        EntryPointAccess::Public,
        EntryPointType::Contract,
        ));

        // In the named keys of the counter contract, add a key for the count.
        let mut counter_named_keys = NamedKeys::new();
        let key_name = String::from(COUNT_KEY);
        counter_named_keys.insert(key_name, count_start.into());

        // Create a new contract package that can be upgraded.
        let (stored_contract_hash, contract_version) = storage::new_contract(
        counter_entry_points,
        Some(counter_named_keys),
        Some(CONTRACT_PACKAGE_NAME.to_string()),
        Some(CONTRACT_ACCESS_UREF.to_string()),
        );

        /* To create a locked contract instead, use new_locked_contract and throw away the contract version returned
        let (stored_contract_hash, _) =
        storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None); */

        // Store the contract version in the context's named keys.
        let version_uref = storage::new_uref(contract_version);
        runtime::put_key(CONTRACT_VERSION_KEY, version_uref.into());

        // Create a named key for the contract hash.
        runtime::put_key(CONTRACT_KEY, stored_contract_hash.into());
        }
        @@ -189,7 +188,7 @@

        Locked Cont
      1. hash_name - Contract hash value. Puts contractHash in the current context's named keys under hash_name.
      2. uref_name - Access URef value. Puts access_uref in the current context's named keys under uref_name.
      3. -

        Note: The current context is the context of the person who initiated the call function, usually an account.

        +

        Note: The current context is the context of the person who initiated the call function, usually an account entity.

        The counter contract in our example would be locked if we created it this way:

        let (stored_contract_hash, _) =
        storage::new_locked_contract(counter_entry_points, Some(counter_named_keys), None, None);

        Compiling Contract Code

        @@ -209,6 +208,6 @@

        What's Next?
      4. Learn to test your contract.
      5. Understand session code and how it triggers a smart contract.
      6. Learn to install a contract and query global state with the Casper command-line client.
      7. -

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/testing-contracts/index.html b/developers/writing-onchain-code/testing-contracts/index.html index ce6948e61..5ec74b33d 100644 --- a/developers/writing-onchain-code/testing-contracts/index.html +++ b/developers/writing-onchain-code/testing-contracts/index.html @@ -1,28 +1,28 @@ - + -Testing Smart Contracts | Casper Docs - Redux +Testing Smart Contracts | Casper Docs - Redux - - + +
    Version: Next

    Testing Smart Contracts

    Introduction

    -

    As part of the Casper development environment, we provide a testing framework to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful deploys and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated.

    +

    As part of the Casper development environment, we provide a testing framework to test new contracts without running a full node. The framework creates an instance of the Casper execution engine, which can confirm successful transactions and monitor changes to global state using assertions. The Casper test crate must be included within the Rust workspace alongside the Wasm-producing crate to be validated.

    note

    The Casper test support crate is one of many options for testing contracts before sending them to a Casper network. If you prefer, you can create your own testing framework.

    Defining Dependencies in Cargo.toml

    This guide uses the project structure, and example contract outlined here for creating tests.

    To begin, outline the required test dependencies in the /tests/Cargo.toml file. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. For the counter tests, we have the following dependencies:

    -
    [dependencies]
    casper-execution-engine = "5.0.0"
    casper-engine-test-support = { version = "5.0.0", features = ["test-support"] }
    casper-types = "3.0.0"
    +
    [dependencies]
    casper-execution-engine = "2.0.1"
    casper-engine-test-support = { version = "2.2.0", features = ["test-support"] }
    casper-types = "1.5.0"
    • casper-execution-engine - This crate imports the execution engine functionality, enabling Wasm execution within the test framework. Each node contains an instance of an execution engine, and the testing framework simulates this behavior.
    • casper-engine-test-support - A helper crate that provides the interface to write tests and interact with an instance of the execution engine.
    • @@ -35,34 +35,33 @@

      Writing th
      #[cfg(test)]
      mod tests {
      // The entire test program resides here
      }

      Importing Builders and Constants

      Import external test support, which includes a variety of default values and helper methods to be used throughout the test. Additionally, you will need to import any CLTypes used within the contract code to be tested.

      -
          // Outlining aspects of the Casper test support crate to include.
      use casper_engine_test_support::{
      ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
      PRODUCTION_RUN_GENESIS_REQUEST,
      };
      // Custom Casper types that will be used within this test.
      use casper_types::{runtime_args, ContractHash, RuntimeArgs};
      +
          // Outlining aspects of the Casper test support crate to include.
      use casper_engine_test_support::{
      ExecuteRequestBuilder, InMemoryWasmTestBuilder, DEFAULT_ACCOUNT_ADDR,
      DEFAULT_RUN_GENESIS_REQUEST,
      };
      // Custom Casper types that will be used within this test.
      use casper_types::{runtime_args, ContractHash, RuntimeArgs};

      Next, you need to define any global variables or constants for the test.

      -
          // Contract Wasm File Paths (Constants)
      const COUNTER_V1_WASM: &str = "counter-v1.wasm";
      const COUNTER_V2_WASM: &str = "counter-v2.wasm";
      const COUNTER_V3_WASM: &str = "counter-v3.wasm";
      const COUNTER_CALL_WASM: &str = "counter-call.wasm";

      // Contract Storage Keys (Constants)
      const CONTRACT_KEY: &str = "counter";
      const COUNT_KEY: &str = "count";
      const LAST_UPDATED_KEY: &str = "last_updated";
      const CONTRACT_VERSION_KEY: &str = "version";

      // Contract Entry Points (Constants)
      const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement";
      const ENTRY_POINT_COUNTER_INC: &str = "counter_inc";
      const ENTRY_POINT_COUNTER_LAST_UPDATED_AT: &str = "counter_last_updated_at";
      +
          const COUNTER_V1_WASM: &str = "counter-v1.wasm"; // The first version of the contract
      const COUNTER_V2_WASM: &str = "counter-v2.wasm"; // The second version of the contract
      const COUNTER_CALL_WASM: &str = "counter-call.wasm"; // Session code that calls the contract

      const CONTRACT_KEY: &str = "counter"; // Named key referencing this contract
      const COUNT_KEY: &str = "count"; // Named key referencing the value to increment/decrement
      const CONTRACT_VERSION_KEY: &str = "version"; // Key maintaining the version of a contract package

      const ENTRY_POINT_COUNTER_DECREMENT: &str = "counter_decrement"; // Entry point to decrement the count value
      const ENTRY_POINT_COUNTER_INC: &str = "counter_inc"; // Entry point to increment the count value

      Creating a Test Function

      Each test function installs the contract and calls entry points to assert that the contract's behavior matches expectations. The test uses the InMemoryWasmTestBuilder to invoke an instance of the execution engine, effectively simulating the process of installing the contract on the chain.

      -

      As part of this process, we use the PRODUCTION_RUN_GENESIS_REQUEST to install the system contracts necessary for the tests, including the Mint, Auction, and HandlePaymentcontracts, as well as establishing a default account and funding the associated purse.

      -
          #[test]
      /// Install version 1 of the counter contract and check its available entry points. ...
      fn install_version1_and_check_entry_points() {
      let mut builder = InMemoryWasmTestBuilder::default();
      builder.run_genesis(&PRODUCTION_RUN_GENESIS_REQUEST).commit();

      // See the repository for the full function.
      }
      +

      As part of this process, we use the DEFAULT_RUN_GENESIS_REQUEST to install the system contracts necessary for the tests, including the Mint, Auction, and HandlePaymentcontracts, as well as establishing a default account and funding the associated purse.

      +
          #[test]
      /// Install version 1 of the counter contract and check its available entry points. ...
      fn install_version1_and_check_entry_points() {
      let mut builder = InMemoryWasmTestBuilder::default();
      builder.run_genesis(&*DEFAULT_RUN_GENESIS_REQUEST).commit();

      // See the repository for the full function.
      }

      Installing the Contract

      -

      Test functions use the ExecuteRequestBuilder to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the DEFAULT_ACCOUNT_ADDR established by our genesis builder as the account sending the Deploy.

      +

      Test functions use the ExecuteRequestBuilder to install a contract to be tested. In the counter tests, we use standard dependencies and the counter contract. Within the execution request, we specify the DEFAULT_ACCOUNT_ADDR established by our genesis builder as the account sending the transaction.

      After building the ExecuteRequestBuilder (in this example, contract_installation_request), we process the request through builder.exec and then add and process other requests as necessary.

          // Install the contract.
      let contract_v1_installation_request = ExecuteRequestBuilder::standard(
      *DEFAULT_ACCOUNT_ADDR,
      COUNTER_V1_WASM,
      runtime_args! {},
      )
      .build();

      builder
      .exec(contract_v1_installation_request)
      .expect_success()
      .commit();

      Calling the Contract by Hash

      -

      To verify the installed contract, we need its contract hash. The test will then call its entry points using the contract_call_by_hash function. The following code retrieves the contract hash from the named keys of the DEFAULT_ACCOUNT_ADDR that sent the installation Deploy.

      +

      To verify the installed contract, we need its contract hash. The test will then call its entry points using the contract_call_by_hash function. The following code retrieves the contract hash from the named keys of the DEFAULT_ACCOUNT_ADDR that sent the installation transaction.

          // Check the contract hash.
      let contract_v1_hash = builder
      .get_expected_account(*DEFAULT_ACCOUNT_ADDR)
      .named_keys()
      .get(CONTRACT_KEY)
      .expect("must have contract hash key as part of contract creation")
      .into_hash()
      .map(ContractHash::new)
      .expect("must get contract hash");

      Next, we test an entry point that should not exist in the first version of the contract.

          // Call the decrement entry point, which should not be in version 1 before the upgrade.
      let contract_decrement_request = ExecuteRequestBuilder::contract_call_by_hash(
      *DEFAULT_ACCOUNT_ADDR,
      contract_v1_hash,
      ENTRY_POINT_COUNTER_DECREMENT,
      runtime_args! {},
      )
      .build();

      // Try executing the decrement entry point and expect an error.
      builder
      .exec(contract_decrement_request)
      .expect_failure()
      .commit();

      Calling the Contract using Session Code

      In the counter example, we use the session code included in the counter-call.wasm file. For more details on what session code is and how it differs from contract code, see the next section.

      -

      The following session code uses the contract hash to identify the contract, the account for sending the deploy (DEFAULT_ACCOUNT_ADDR), the deploy to be sent (COUNTER_CALL_WASM), and the runtime arguments required. Once again, the ExecuteRequestBuilder simulates the execution of session code and calls the counter-inc entry point.

      +

      The following session code uses the contract hash to identify the contract, the account for sending the transaction (DEFAULT_ACCOUNT_ADDR), the transaction to be sent (COUNTER_CALL_WASM), and the runtime arguments required. Once again, the ExecuteRequestBuilder simulates the execution of session code and calls the counter-inc entry point.

          // Use session code to increment the counter.
      let session_code_request = ExecuteRequestBuilder::standard(
      *DEFAULT_ACCOUNT_ADDR,
      COUNTER_CALL_WASM,
      runtime_args! {
      CONTRACT_KEY => contract_v1_hash
      },
      )
      .build();

      builder.exec(session_code_request)
      .expect_success()
      .commit();
      -
      tip

      Testing Time-Sensitive Functions

      Normally, smart contracts operate on a blockchain where time advances in blocks. Testing functions that rely on time can be tricky.

      Simulating Time with with_block_time

      When building a request to call a contract function (using ExecuteRequestBuilder), you can set a custom block time with .with_block_time(desired_time). This pretends the function is called at that specific time.

      Example:

          let session_code_request = ExecuteRequestBuilder::standard(
      *DEFAULT_ACCOUNT_ADDR,
      COUNTER_CALL_WASM,
      runtime_args! {
      CONTRACT_KEY => contract_v1_hash
      },
      .with_block_time(5000)
      .build();

      This lets you test how your contract behaves at different points in time, all within your unit test.

      Evaluating and Comparing Results

      After calling the contract, we should verify the results received to ensure the contract operated as intended. The builder method retrieves the required information and converts it to the value type required. Then, assert_eq!() compares the result against the expected value.

          // Verify the value of count is now 1.
      let incremented_count = builder
      .query(None, count_key, &[])
      .expect("should be stored value.")
      .as_cl_value()
      .expect("should be cl value.")
      .clone()
      .into_t::<i32>()
      .expect("should be i32.");

      assert_eq!(incremented_count, 1);

      For more test examples, visit the casper-node GitHub repository.

      Testing Contracts that Call Contracts

      If the code to be tested involves multiple contracts, they must be installed within the test. The exceptions are system contracts installed as part of the DEFAULT_RUN_GENESIS_REQUEST. The testing framework exists independently of any Casper network, so you will need access to the original contract installation code or the Wasm you wish to include.

      -

      Each contract installation will require an additional Wasm file installed through a Deploy using ExecuteRequestBuilder. Depending on your requirements as a smart contract author, you may need to use return values to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously.

      +

      Each contract installation will require an additional Wasm file installed through a Transaction using ExecuteRequestBuilder. Depending on your requirements as a smart contract author, you may need to use return values to interact with stacks of contracts. Interaction between contracts will require session code to initiate the process, as contracts will not execute actions autonomously.

      The major difference between calling a contract from session code versus contract code is the ability to use non-standard dependencies for the ExecuteRequestBuilder. Where session code must designate a Wasm file within the standard dependencies, contract code can use one of the four available options for calling other contracts, namely:

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/testing-session-code/index.html b/developers/writing-onchain-code/testing-session-code/index.html index d1df088c1..a20034c86 100644 --- a/developers/writing-onchain-code/testing-session-code/index.html +++ b/developers/writing-onchain-code/testing-session-code/index.html @@ -1,21 +1,21 @@ - + -Testing Session Code | Casper Docs - Redux +Testing Session Code | Casper Docs - Redux - - + +
    Version: Next

    Testing Session Code

    This section describes how to test session code using the Casper unit-testing framework. The writing session code section is a prerequisite for this tutorial, which uses the example code described here.

    Specifying Dependencies in Cargo.toml

    The Cargo.toml sample file in the tests directory contains the test framework dependencies. Specify the dependencies for your tests similarly and update the crate versions. Dependencies may vary with each project. These are the basic dependencies the testing framework requires:

    @@ -88,6 +88,6 @@

    Video Walk

    What's Next?

    +
    \ No newline at end of file diff --git a/developers/writing-onchain-code/upgrading-contracts/index.html b/developers/writing-onchain-code/upgrading-contracts/index.html index f14607ed9..547544a12 100644 --- a/developers/writing-onchain-code/upgrading-contracts/index.html +++ b/developers/writing-onchain-code/upgrading-contracts/index.html @@ -1,22 +1,21 @@ - + -Upgrading and Maintaining Smart Contracts | Casper Docs - Redux +Upgrading and Maintaining Smart Contracts | Casper Docs - Redux - - + +
    Version: 1.5.X

    Upgrading and Maintaining Smart Contracts

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Upgrading and Maintaining Smart Contracts

    Our smart contract packaging tools enable you to:

    • Upgrade your contracts and specify how the state of the contract is managed
    • @@ -26,7 +25,7 @@

    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. If you find that you need to use a disabled contract version, you may also re-enable it.

    -

    +

    Package Representation

    The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain.

    Videos and Tutorials

    To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the Writing On-Chain Code documentation.

    @@ -37,6 +36,6 @@

    Videos

    Maintaining a Contract

    The contract maintenance process is generally covered through the contract upgrade process.

    Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance.

    -

    On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process.

    +

    On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process.

    \ No newline at end of file diff --git a/developers/writing-onchain-code/writing-session-code/index.html b/developers/writing-onchain-code/writing-session-code/index.html index eb9b8a973..8f0b31249 100644 --- a/developers/writing-onchain-code/writing-session-code/index.html +++ b/developers/writing-onchain-code/writing-session-code/index.html @@ -1,21 +1,21 @@ - + -Writing Session Code | Casper Docs - Redux +Writing Session Code | Casper Docs - Redux - - + +
    Version: Next

    Writing Session Code

    This section explains how to write session code. To review the definition of session code and the differences between session code and contract code, see Comparing Session Code and Contract Code. Session code can be written in any programming language that compiles to Wasm. However, the examples in this topic use Rust.

    Creating the Directory Structure

    For writing session code, we use the same project structure used for writing contracts, described here.

    @@ -87,6 +87,6 @@

    Video Walk

    What's Next?

    +
    \ No newline at end of file diff --git a/disclaimer/index.html b/disclaimer/index.html index 25b026009..192d5f7b3 100644 --- a/disclaimer/index.html +++ b/disclaimer/index.html @@ -1,21 +1,21 @@ - + -Disclaimer | Casper Docs - Redux +Disclaimer | Casper Docs - Redux - - + +
    Version: 1.5.X

    Disclaimer

    + submit an issue on Github
    Version: Next

    Disclaimer

    By accepting this CasperLabs Tech Spec (this "Whitepaper"), each recipient hereof acknowledges and agrees that is not authorised to, and may not, forward or deliver this Whitepaper, electronically or otherwise, to any other person or reproduce this Whitepaper in any manner whatsoever. Any forwarding, distribution or reproduction of this Whitepaper in whole or in part is unauthorised. Failure to comply with this directive may result in a violation of applicable laws of any affected or involved jurisdiction.

    Nothing in this Whitepaper constitutes an offer to sell, or a solicitation to purchase, the tokens native to the Casper blockchain ("CSPR”). In any event, were this Whitepaper to be deemed to be such an offer or solicitation, no such offer or solicitation is intended or conveyed by this Whitepaper in any jurisdiction where it is unlawful to do so, where such an offer or solicitation would require a license or registration, or where such an offer or solicitation is subject to restrictions. In particular, any CSPR to be issued have not been, and, as of the date of issuance of this Whitepaper, are not intended to be, registered under the securities or similar laws of any jurisdiction, whether or not such jurisdiction considers the CSPR to be a security or similar instrument, and specifically, have not been, and, as of the date of issuance of this Whitepaper are not intended to be, registered under the U.S. Securities Act of 1933, as amended, or the securities laws of any state of the United States of America or any other jurisdiction and may not be offered or sold in any jurisdiction where to do so would constitute a violation of the relevant laws of such jurisdiction.

    This Whitepaper constitutes neither a prospectus according to Art. 652a of the Swiss Code of Obligations (the "CO”) or Art. 1156 CO nor a prospectus or basic information sheet according to the Swiss Financial Services Act (the "FinSA”) nor a listing prospectus nor a simplified prospectus according to Art. 5 of the Swiss Collective Investment Schemes Act (the "CISA”) nor any other prospectus according to CISA nor a prospectus under any other applicable laws.

    @@ -72,6 +72,6 @@

    Risk Factors

    Risks associated with forking: the Recipient understands and accepts that hard and soft forks as well as similar events may, inter alia, lead to the creation of new or competing tokens to the CSPR, adversely affect the functionality, convertibility or transferability or result in a full or partial loss of units or reduction (including reduction to zero) of value of the Recipient’s CSPR (if and when created and/or issued).

    -

    +
    \ No newline at end of file diff --git a/economics/index.html b/economics/index.html index d893f12dc..733980a34 100644 --- a/economics/index.html +++ b/economics/index.html @@ -1,46 +1,51 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Overview of Casper Economics

    -

    Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires that proper incentives be provided to participants operating each of these layers to ensure that they work together to unlock the platform's value.

    -

    We cannot yet provide formal game-theoretic results for our incentive mechanisms, but interested readers can follow our progress with the Economics of the Casper Blockchain paper, which will be periodically updated to summarize ongoing research.

    -

    This section of our online documentation is intended only to familiarize the user with our core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active.

    + submit an issue on Github
    Version: Next

    Overview of Casper Economics

    +

    Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.

    +

    This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active.

    Consensus

    -

    The consensus layer of our platform runs on the Highway flavor of CBC-Casper. The distinguishing characteristics of this protocol are its safety and liveness guarantees. Specifically, under the assumptions made in the Highway protocol paper, blocks in the canonical history cannot be reverted, and new blocks continue to be added to this history indefinitely. The assumptions, however, require that a large portion of validators remain online and honest; this assumed behavior must be incentivized for the platform to remain secure and live.

    -

    When discussing consensus, we default to considering it "one era at a time," unless expressly stated otherwise, in keeping with the Highway paper. Recall that each era is, effectively, a separate instance of the protocol.

    +

    The consensus layer of the Casper Mainnet runs the Zug consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

    +

    When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.

    Agents (consensus layer)

    -

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain's security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.

    +

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain's security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.

    Delegators are users who participate in the platform's security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    Incentives (consensus layer)

    -

    The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.

    -

    Rewards (per era) are issued to validators who perform, at their nominal pace, in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator.

    -

    Evictions deactivate validators who fail to participate in an era, disabling their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract.

    +

    The auction determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.

    +

    Rewards (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator.

    +

    Evictions deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract.

    Runtime

    -

    The runtime layer encompasses the deployment and execution of smart contracts, session code, and other activity that performs computation on the global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to metering computing time, measured as gas. Gas can be conceptualized as relative time use of different Wasm operations and host-side functions. Use of storage is also presently assigned a gas cost. We do not currently have a pricing mechanism for metered gas, although an outstanding Casper Enhancement Proposal (CEP #22) suggests the implementation of a first-price gas auction similar to Ethereum's. The initial Mainnet deploy selection mechanism is based on FIFO.

    -

    We expect to continue work on runtime resource markets, particularly gas futures (CEP #17).

    -

    Agents (consensus layer)

    -

    Validators again play a vital role in this layer since protocol operation includes construction and validation of new blocks, consisting of deploys that change the global state, which the validators also maintain.

    +

    The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to metering computing time, measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost.

    +

    The Mainnet transaction selection mechanism is based on FIFO.

    +

    We expect to continue to work on runtime resource markets.

    +

    Agents (runtime layer)

    +

    Validators again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain.

    Users execute session and contract code using the platform's computational resources

    -

    Incentives (consensus layer)

    -

    Transaction fees, or charges for gas use, ensure that the users compensate validators for performing their computations. Transaction fees are awarded to the block creator. Because we expect to launch with FIFO ordering of deploys, it can be assumed that one unit of gas will be priced at one mote until future changes to deploy orders are implemented.

    +

    Incentives (runtime layer)

    +

    The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a fee elimination model by default, setting the no_fee,no_refund, and fixed pricing configurations in the network's chainspec.

    +

    The no_fee mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.

    +

    The no_refund mode means no refund is handled when fees are eliminated.

    +

    Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes here.

    +

    When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations.

    +

    The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, private networks can set their fee, refund, and pricing strategies.

    Ecosystem

    The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps.

    Macroeconomy

    -

    Casper's macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics are different from those of "digital gold" tokens like Bitcoin, designed to be scarce. Our tokens are minted from a fixed starting basis, which is accounted for by tokens distributed to genesis validators, employees, community members and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate from this basis.

    -

    The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, a behavior we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity on the platform and discourage hoarding tokens in expectation of speculative gain.

    +

    Casper's macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.

    +

    The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain.

    \ No newline at end of file diff --git a/glossary/index.html b/glossary/index.html index ceea95441..d547262b3 100644 --- a/glossary/index.html +++ b/glossary/index.html @@ -1,24 +1,24 @@ - + -Glossary | Casper Docs - Redux +Glossary | Casper Docs - Redux - - + +
    Version: 1.5.X

    Glossary

    + submit an issue on Github
    Version: Next

    Glossary

    These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.


    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    +
    \ No newline at end of file diff --git a/index.html b/index.html index 0f58f953e..67df787be 100644 --- a/index.html +++ b/index.html @@ -1,29 +1,27 @@ - + -What is Casper? | Casper Docs - Redux +Welcome to the official Casper documentation | Casper Docs - Redux - - + +
    Version: 1.5.X

    What is Casper?

    What is Casper?

    -

    Casper is a new Turing-complete smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    -

    The network's consensus protocol is called Highway, and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Highway allows networks to reach higher thresholds of finality, meaning that more blocks are finalized, and validators agree to add them to the blockchain. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the correct-by-construction (CBC) Casper research.

    -

    Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's core features and strengths enable developers and enterprises to reap the benefits of blockchain technology.

    -

    Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises.

    -

    How does Casper work?

    -

    Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network.

    -

    To understand the design further, read this article.

    + submit an issue on Github
    Version: Next

    Welcome to the official Casper documentation

    What is Casper?

    +

    Casper is a smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    +

    How to use this documentation portal

    + + +

    The Nav bar is arranged along the top of your browser window, and may be broken down into left and right. On the left hand side, you will see 5 links, each of which corresponds to a sidebar. There are 5 Sidebars, each of which contains links to content broken down by subject area within the documentation.

    Disclaimer

    -

    Read the Legal Disclaimer regarding this CasperLabs Tech Spec (this "Whitepaper").

    +

    Legal Disclaimer.

    \ No newline at end of file diff --git a/next/concepts/addressable-entity/index.html b/next/concepts/addressable-entity/index.html deleted file mode 100644 index 59c53f660..000000000 --- a/next/concepts/addressable-entity/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Addressable Entities | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Addressable Entities

    -

    What is an Addressable Entity?

    -

    The AddressableEntity data structure encapsulates the behaviour and data associated with several related concepts within the Casper type system. -Casper 2.0 introduces the concept of an AddressableEntity which replaces the existing Account and Contract types.

    -

    The merger of the Account and Contract concepts allows for some new possibilities.

    -

    For any given AddressableEntity, the EntityType will identify if it is an Account, a user-deployed SmartContract, or a System contract such as Mint or HandlePayment.

    -

    This EntityType will dictate what the addressable entity can and cannot do.

    -

    Account

    -

    An addressable entity marked as an Account will behave in much the same way as a traditional legacy account on a Casper network. It will have an associated key pair of a PublicKey and a secret key, and an AccountHash derived from the public key. There is also an associated main purse.

    -

    A legacy account will automatically migrate to an addressable entity when it interacts with the network, with no action necessary on the user side. Their key pair will continue functioning as it did prior to the migration. Further, their main purse will remain the same.

    -

    SmartContract

    -

    An addressable entity marked as a SmartContract will have the same functionality as a legacy contract, but with several new features. The SmartContract now possesses a main purse, and may have associated keys and action thresholds that behave in the same way as an account. More information on multi-signature management, associated keys, and action thresholds can be found here.

    -

    System

    -

    As part of the migration to Casper 2.0, system contracts (Mint, Auction and HandlePayment) will migrate to a special type of addressable entity with the EntityType of System. The StandardPayment system contract will be pruned away.

    -

    Further Reading

    -
    - - \ No newline at end of file diff --git a/next/concepts/callstack/index.html b/next/concepts/callstack/index.html deleted file mode 100644 index 7d5614354..000000000 --- a/next/concepts/callstack/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Call Stacks | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Understanding Call Stacks

    -

    Users wishing to interact with a Casper network must do so through sending a transaction. All transactions consist of session code run in the context of the user account entity that sent the transaction. The session code may install contract code to global state, or interact with previously installed contract code.

    -

    When the session code within a transaction interacts with one or more contracts, this is the beginning of a Call Stack. A call stack is the chronological order in which contracts call other contracts, initiated by an instance of session code.

    -

    The Caller

    -

    In every instance of a call stack, the originating caller is the session code within the account's context that began the interaction. Contract code cannot spontaneously act without session code to activate it. As such, the session code represents the zeroth entity in each call stack. The account that initiated the transaction can be retrieved with the contract_api::runtime::get_caller function.

    -

    The Call Stack

    -

    Developers can access the call stack with the contract_api::runtime::get_call_stack function.

    -

    If session code calls a contract, which in turn calls another contract, then the session code would represent the zeroth entity in the stack, the contract called by the initiating session code would be the first and the contract called by the first contract would be the second.

    -

    In this example, the first contract would be the immediate caller of the second contract, meaning it interacted directly with it. The session code would remain the caller.

    -

    Call Stack

    -

    Limitations

    -

    Casper networks place a limitation on the maximum height of a call stack. This value can be set within the chainspec for the network in question. For the Casper Mainnet, this limit is set at 10 contracts. This does not include the initiating session code, which would still count as the zeroth instance within the stack.

    -

    As such, a call stack may consist of up to ten consecutive called smart contracts, assuming that the Casper network you are working with is set to the default call stack depth. Smart contract developers should consider it best practice to limit the depth of their call stack as much as practicable. If your contract calls a contract not under your direct control, it may call into any other contracts. You can avoid hitting the limitation by being efficient in your contracts and avoiding superfluous contract separation.

    -
    note

    Contract code cannot call session code, only other contract code.

    - - \ No newline at end of file diff --git a/next/concepts/design/consensus/index.html b/next/concepts/design/consensus/index.html deleted file mode 100644 index 4f7162c42..000000000 --- a/next/concepts/design/consensus/index.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - -Consensus in a Casper Network | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Consensus in a Casper Network

    -

    The decentralized nature of a Casper network requires a method for validators to agree on the chain of finalized blocks. Validator nodes must determine the validity of transactions, resolve conflicts, and finalize the blocks in the chain. The network's consensus protocol is a mechanism for the validators to agree on each finalized block.

    -

    Safety, Liveness, and Byzantine Fault Tolerance

    -

    In a Casper network, validator nodes receive different inputs via transactions from connecting clients. Given the consensus mechanism and rules, all honest nodes should output the same value, which is a finalized block in Casper. The Transaction Lifecycle describes what happens after blocks are proposed and finalized. Each finalized block will contain the set of transactions, which the network will eventually execute. The property described here, where all honest nodes agree on a final value, is called safety.

    -

    The consensus protocol ensures that honest validators agree on finalized blocks in a finite time, allowing the network to continue producing blocks indefinitely. This property of the protocol is called liveness.

    -

    Honest validators will agree on finalized blocks even if some nodes are faulty. This property makes the consensus protocol tolerant to a Byzantine fault and thus secure against malicious activity.

    -

    To summarize, the consensus mechanism will determine how a blockchain meets the following requirements:

    -
      -
    • -

      Safety: All honest nodes eventually agree on the final value, which in a Casper network is a finalized block. The consensus mechanism is set up so that no two honest validators will report two different blocks at the same height of the blockchain.

      -
    • -
    • -

      Liveness: The network runs indefinitely and adds new blocks to the chain.

      -
    • -
    • -

      Byzantine Fault Tolerance (BFT): All honest nodes eventually agree on the final value, even if some are faulty.

      -
    • -
    -

    Casper Consensus Protocols

    -

    Each Casper network can choose and configure its consensus protocol using the network's chainspec. The protocols available are Zug and Highway. Highway served as the Casper Mainnet's consensus protocol since launch. The Zug consensus protocol was introduced in version 2.0 to simplify and speed up the consensus process without compromising safety. Zug enables faster block times, less overhead, and a larger validator set in Mainnet. Zug is an implementation of the ideas from the paper From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast, which describes how Zug meets the safety, liveness, and resiliency requirements.

    -

    Consensus in the Casper Mainnet

    -

    The Casper Mainnet is a Proof-of-Stake network in which the on-chain auction contract determines validators participating in consensus. The protocol uses a decentralized network of nodes, which participate in the consensus process by staking CSPR tokens. These active nodes are known as validators. The top 100 bidders are selected through the auction contract every era, to act as validators in the era after the next (current era + 2). Nodes with a greater stake in the network's success have a greater weight in reaching consensus.

    -

    The Mainnet will continue to function as long as the total weight of faulty nodes does not exceed one-third of the total weight of all nodes. Nodes that are not faulty are honest nodes. In most cases, the network can assume that more than two-thirds of all nodes will actively collaborate to achieve consensus. Therefore, stronger-than-average finality guarantees occur during periods when all nodes are acting honestly.

    -
    note

    The Zug or Highway consensus protocols do not necessitate a Proof-of-Stake method of choosing validators and could theoretically be used alongside a private network with a different model.

    -

    Dynamic Round Length

    -

    Within the Zug or Highway protocols, the length of a round is determined dynamically to ensure a suitable time for nodes to send all messages. This ensures that the system maintains liveness by properly communicating all messages and adding blocks to the chain in a timely manner.

    -

    Eras

    -

    The concept of eras (one era consists of multiple rounds) allows consensus to reduce the overall operational storage requirements of participating nodes while also rotating validators. On Mainnet, a new instance of consensus runs every two hours or approximately 440 blocks, depending on current network metrics. This allows for two benefits:

    -
      -
    • -

      Data Reduction - Older "metadata" used in finalizing certain blocks is no longer useful and can be removed without compromising the immutability of the data stored on the blockchain.

      -
    • -
    • -

      Banning Equivocators - Dishonest nodes caught equivocating (signing conflicting consensus messages) in a previous era cannot participate in new eras.

      -
    • -
    -
      -
    • Rotating Validators - Bonded nodes bid on validator spots each era, with the top highest bidders becoming validators for the era after next (current era+ 2).
    • -
    -

    In any given era, node operators will bid to become validators participating in the consensus mechanism for the era after the next (current era + 2). Each time slot within the era will also determine a lead validator. The lead validator proposes a new block to be added to the chain, which is communicated to the other nodes (via broadcasting or gossiping, depending on the consensus protocol). Once this process reaches critical mass, with a sufficient interconnected pattern of messages, the selected block is considered finalized and added to the chain.

    -

    The final block of an era is a switch block and forms the initial state of the next era. A new consensus instance begins with the new era, using information contained within the switch block and a new potential set of validators. More details on the auction process to determine an era's validators can be found within the Consensus Economics page.

    -

    Finality

    -

    Finality occurs when the network can be sure that a block will not be altered, reversed, or canceled after addition to the chain. This occurs via consensus, and as all transactions happen within a block, it allows for confirmation that a transaction cannot be changed. After finality, it would require more than one third of all validators to double-sign to cause a disparity between nodes. In this event, the network would shut down and require a manual restart.

    -

    On a Casper network, a transaction finalizes alongside the finalizing of the block in which it is included. Validators that equivocate risk eviction, in which the network removes them from the validator set. Therefore, honest nodes receive rewards for their participation, while equivocating nodes risk loss of revenue for acting maliciously.

    - -
      -
    • Zug Consensus - An overview of the Zug consensus used in Mainnet and Testnet
    • -
    • Highway Consensus - Brief overview of the Highway consensus available as an alternative to Zug
    • -
    - - \ No newline at end of file diff --git a/next/concepts/design/highway/index.html b/next/concepts/design/highway/index.html deleted file mode 100644 index e815f6f2e..000000000 --- a/next/concepts/design/highway/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - -Highway Consensus | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    The Highway Consensus Protocol

    -

    The Highway consensus protocol was used on the Casper Mainnet until the Zug consensus protocol was introduced in version 2.0 of the Casper node software. Consensus in Casper is described in more detail here. This page describes the Highway consensus protocol at a high level. Private networks can choose between Zug and Highway, depending on their needs.

    -

    Unit Broadcasting

    -

    In Highway, nodes communicate by broadcasting units. A unit is a structure containing the following:

    -
      -
    • Citations of other units (at most one per node), subject to validity conditions
    • -
    • An optional proposed list of transactions to be included in a block. Note that the list can be empty
    • -
    • The unit's creator and its digital signature
    • -
    • Additional metadata, including a timestamp, sequence number, round length, etc.
    • -
    -

    An empty unit still carries an implicit vote. The citations determine which block a unit votes for based on a rule called "the fork choice rule". If there are multiple blocks to vote on and there isn't clarity about which block is the latest, the algorithm calculates the latest block based on the citations. The algorithm counts the weight of units from other validators and what they vote on and chooses the latest block on the branch with the most weight. The proposal unit always votes on itself. The protocol implicitly prefers the proposed block due to the GHOST (Greedy Heaviest Observed Sub-Tree) rule. More details are found in the implementation under the fork choice rule. In summary, if there is a fork, every unit votes on some branch of the chain.

    -

    Over time, the units form a Directed Acyclic Graph (DAG), where units are the vertices and citations are the edges.

    -

    DAG

    -

    Nodes must cite the latest unit received from every node, including their latest unit. If a validator does not follow the process and thus equivocates, their bid gets deactivated. However, the validator is not slashed. When a node equivocates, it can still send units but may not be a validator.

    -

    The Highway protocol proceeds in rounds with a minimum round length. Different nodes can use different round lengths, and ratios of round lengths are always powers of 2. Highway is a partially synchronous protocol because it is not bound to a specific time set in advance, and the network can adjust to delays. Thus, the protocol guarantees partially synchronous liveness. Multiple rounds form an era.

    -

    Block Finalization

    -

    In each round, the assigned leader proposes a list of transactions to be included in a block. A block is finalized if there is a summit among the cited units. A summit is a structure within the graph characterized by a quorum q, a percentage of the participating validator weight, and a level k. Level k represents the depth in the graph. For a given fault tolerance threshold t (FTT), finality is defined as:

    -

    Finality Equation

    -

    If q is close to n, meaning the whole network participates, a block can be finalized with a high fault tolerance threshold (FTT).

    -

    The existence of such a summit means that a weight of more than t would have to equivocate to finalize a conflicting block. In other words, the FTT is the weight of the nodes that would have to collude to finalize a conflicting block and revert the transactions in that block.

    -

    In Mainnet, the FTT was one-third of the validator weight. If over one-third of the validator weight was faulty, those nodes could have prevented block finalization and stalled the network.

    - -
      -
    • Highway Whitepaper - Describes the protocol, and the liveness and safety proofs in detail
    • -
    • Zug Consensus - The protocol currently used in Mainnet and Testnet
    • -
    - - \ No newline at end of file diff --git a/next/concepts/design/p2p/index.html b/next/concepts/design/p2p/index.html deleted file mode 100644 index d12028601..000000000 --- a/next/concepts/design/p2p/index.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - -Network Communication | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Network Communication

    -

    Identity

    -

    Each node has an identity on the network (which is not the same as its identity in the consensus process). The network identity (ID) is based on the fingerprint of the public key of a TLS certificate. A node generates a new private key each time it starts, ensuring a unique ID.

    -

    Each identity is linked with an address, which is an IP and port pair where the node is reachable. This address is also called an endpoint.

    -

    Inter-node connections

    -

    Should a node want to connect to another node with a known endpoint, it opens a TLS connection to the endpoint's address. In the context of common TLS terminology, this makes the connecting node the client and the remote node the server for this connection.

    -

    During connection setup, the client checks the server's certificate, matching the endpoint's expected public identity to ensure we have connected to the right node. Additionally, the TLS parameters of the connection and certificate are required to contain the same ciphers, digests, etc., to protect against downgrade attacks.

    -

    Simultaneously, the connecting node sends its certificate as the client certificate, allowing the server to perform the same check-in reverse and establish the client's ID. At the end of the process, both nodes can be sure to which peer they are connected.

    -

    Once a connection is established, the server will immediately seek to connect back to the client based on its endpoint (see Node Discovery on how the server finds endpoints).

    -

    Connections are used for sending messages one-way only; only the node initiating a connection will send messages on it.

    -

    Network

    -

    As soon as a node has connected to one node in the network, it partakes in Node Discovery. In general, any node will attempt to connect to any other node on the network it finds as described above, leading to a fully connected network.

    -

    Two classes of data transfers happen in the network; broadcasts and gossiping. A broadcast message is sent once, without guarantees, to all the nodes connected to it. The process of gossiping is described further below.

    -

    In general, only consensus messages, which are only sent by active validators, are broadcast. Everything else is gossipped.

    -

    Gossiping

    -

    Multiple types of objects are gossipped, the most prominent ones being blocks, transactions, and endpoints (see Identity). Each of these objects is immutable and can be identified by a unique hash.

    -

    Gossiping is a process of distributing a value across the entire network without directly sending it to each node. This process allows only a subset of nodes to be connected to the original sender and spreading the bandwidth and processing requirements across the network at the cost of latency and overall bandwidth consumed.

    -

    The process can be summarized as follows:

    -

    Given a message M to gossip, the desired saturation S, and an infection limit L:

    -
      -
    1. Pick a subset T of K nodes from all currently connected nodes.
    2. -
    3. Send M to each node in T, noting which nodes were already infected (a node is considered infected if it already had received or known M).
    4. -
    5. For every node shown as already infected, add another random node outside to T and send it M, again noting the response.
    6. -
    7. End when we confirm infection of L new nodes or encountered S already infected nodes.
    8. -
    -

    Through this process, a message will spread to almost all nodes over time.

    -

    Requesting missing data

    -

    While gossiping and broadcasting are sufficient to distribute data across the network in most cases, nodes can also request missing data from peers should they require it. A common example is a missing transaction from a block.

    -

    Validation

    -

    Objects have a concept of dependencies. For example, a block depends on all the transactions whose hashes are listed inside it. A node considers any object valid if all of its dependencies are available on the local node.

    -

    Should a node receive an object from a peer that is not valid yet, it will attempt to complete its validation before processing it further. In the case of gossiping, this means pausing the gossiping of the object until all its dependencies can be retrieved.

    -

    Any node is responsible for only propagating valid objects. Should a node not retrieve all missing dependencies of an object from the peer that sent it, it may punish the peer for doing so.

    -

    Node Discovery

    -

    Node discovery happens by each node periodically gossiping its public address. Upon receiving an address via gossip, each node immediately tries to establish a connection to it and notes the resulting endpoint, if successful.

    - - \ No newline at end of file diff --git a/next/concepts/design/reading-and-writing-to-the-blockchain/index.html b/next/concepts/design/reading-and-writing-to-the-blockchain/index.html deleted file mode 100644 index 08799e863..000000000 --- a/next/concepts/design/reading-and-writing-to-the-blockchain/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - -Reading and Writing Data | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Reading and Writing Data to Global State

    -

    Casper features several means of reading and writing data to global state, depending on user needs and complexity. Reading data from global state can be done by dApps off-chain or by smart contracts on-chain. Writing data requires on-chain interactions due to the nature of the system. Storage in global state can be accomplished using Dictionaries or NamedKeys.

    -
    note

    Casper's Condor release shifts NamedKeys to a top-level key type, making them more viable for larger data sets.

    -

    Using the Casper JSON-RPC

    -

    The query_global_state method available through the JSON-RPC allows users to read data from global state without performing on-chain actions. For more details, see the Querying a Casper Network tutorial.

    -

    Using the Casper Rust API

    -

    The Casper API includes the following functions for reading and writing to global state:

    -
      -
    • put_key - Stores the given Key under the given name in the current context's named keys
    • -
    • get_key - Returns the requested NamedKey from the current context
    • -
    • storage::new_uref - Creates a new URef in the current context
    • -
    • storage::write - Writes a given value under a previously created URef
    • -
    • storage::read - Reads the value from a URef in global state
    • -
    • dictionary_put - Writes the given value under the given dictionary_item_key
    • -
    • dictionary_get - Retrieves the value stored under a dictionary_item_key
    • -
    -

    For more details, see the Reading and Writing to Global State using Rust tutorial.

    - - \ No newline at end of file diff --git a/next/concepts/economics/consensus/index.html b/next/concepts/economics/consensus/index.html deleted file mode 100644 index a4516fee2..000000000 --- a/next/concepts/economics/consensus/index.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - -Consensus | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Consensus Economics

    -

    Casper consensus is a continuous, trustless process where a fixed set of validators engage in scheduled communication to advance the linear chain of finalized blocks, representing the history of changes in the global state of the blockchain. The fixed set of validators may change at each era boundary. The economics of this layer revolve around validator selection and incentivization of participation according to the schedule.

    -

    Validator Selection

    -

    After genesis, the system selects a set of validators using a stake auction process. The auction takes place in the last block of an era, also called a switch block. An auction contract governs the validator selection process, and a chainspec configuration file specifies a few key parameters:

    -
      -
    • The auction_delay specifies the amount of time that needs to pass before the system enables a new set of validators. For example, the auction_delay is 1 for Mainnet. Therefore, after a delay of 1 era, the winning validators become the validating set for the new era.
    • -
    • The validator_slots parameter specifies how many validators can win an auction. The auction selects a fixed number of validators based on their highest bids.
    • -
    -

    Bids

    -

    Each bid is a collection of tokens from a prospective or current validator and its delegators, considered in the auction as a single total. Bids and delegations can increase freely, but withdrawals are subject to an unbonding period governed by the unbonding_delay chainspec parameter. Tokens that are in the unbonding period are not part of the sum total considered in the auction. Consequently, the exact amount of the bid, which translates into protocol weight for winning validators, can vary within an era. The bids are visible in the switch block that determines the winners.

    -

    Each bid contains a delegation rate and activity status. The delegation rate can change at any time. Both of these properties are described further in this document.

    -

    Delegation

    -

    Delegation allows third parties to participate in consensus by adding weight to their preferred validators. Rewards received by validators are distributed in proportion to tokens bid and delegated. The current or prospective validator responsible for the bid receives a portion of the delegator rewards set by the delegation rate.

    -

    Currently, there are delegation limits in the chainspec. Visit the Delegating Tokens page for more details.

    -

    Incentives

    -

    The correct operation of the consensus protocol requires the platform's economics to discourage equivocation (signing conflicting consensus messages) for safety and incentivize participation for liveness. Participation consists of on-time block proposals and timely responses to block proposals.

    -

    Safety may be incentivized through slashing for equivocation. This feature is currently disabled but may be reactivated in the future.

    -

    The network incentivizes participation by issuing rewards to validators for proposing blocks and creating and publishing finality signatures. Delegators also receive rewards by staking with a validator. All rewards are added directly to the corresponding bids and delegations.

    -

    Validator Participation

    -

    The issuance of new tokens and their distribution to validators incentivizes participation even when there is a low transaction load.

    -

    CSPR is issued at a fixed rate and distributed to validators (and, indirectly, delegators) in proportion to their stake. This is analogous to block rewards in Proof-of-Work blockchains, outlining the following:

    -
      -
    • The growth of CSPR supply is exponential
    • -
    • Issuance takes into account slashed CSPR
    • -
    -

    With slashing disabled, we can compute block rewards starting with the formula below, where we have these parameters:

    -
      -
    • i - the era's index as a positive integer [0, 1, 2, ..., n]
    • -
    • initial_supply - the number of CSPR at genesis
    • -
    • issuance_rate - the annual rate at which new CSPR tokens are minted
    • -
    • ticks_per_year - the number of milliseconds in a year equal to 31,536,000,000
    • -
    -
    supply(i) = initial_supply * (1 + issuance_rate)^(tick_at_era_start(i) / ticks_per_year)
    -

    We introduce the round issuance rate (corresponding to the chainspec parameter round_seigniorage_rate) with this formula:

    -
    round_issuance_rate = (1 + issuance_rate)^(2^minimum_round_exponent / ticks_per_year) - 1
    -

    The round issuance rate is the annual issuance rate adjusted to a single round of length determined by the chainspec parameter minimum_round_exponent. For illustration, an exponent of 14 corresponds to a round length of roughly 16 seconds.

    -

    Finally, the base round reward is computed as:

    -
    base_round_reward(i) = round_issuance_rate * supply(i)
    -

    This value gives us the maximum amount of CSPR that the validators can collectively receive from a proposed block.

    -

    Rewards Distribution

    -

    Validators receive rewards for proposing blocks and creating and publishing finality signatures. Each round has a reward pool, mostly allocated toward creating and publishing finality signatures. There is also a small portion of rewards allocated to the block proposals.

    -

    The concept of validator weight is crucial in understanding the distribution scheme:

    -
      -
    • Weight: A validator's bonded stake, which affects rewards distribution since rewards are proportional to a validator's weight on average
    • -
    • Assigned weight of a round: The total weight of validators scheduled to participate in a round
    • -
    • Participated weight of a round: The total weight of validators that participated or sent messages before the end of the round
    • -
    • Relative weight: A validator's weight relative to the total validator weight that participated in a round
    • -
    -

    The rewards allocated for finality signatures are split between creating and publishing the signatures. These rewards are proportional to the weight of the signing validators for both the signers and the finders. A finder's fee determines how the split happens. To summarize:

    -
      -
    • For each finalized block, there is a fraction of rewards due for signature creation and collection
    • -
    • Signature rewards are split between the finder (block proposer) and the signature creators
    • -
    • The signature creators get a part of the signature reward pot due for the block: (1 - finder's fee) * relative weight
    • -
    • The finder gets a small reward as well to incentivize collecting and reporting all the signatures: finder's fee * total relative weight of signatures collected
    • -
    -

    The rewards calculation takes place at the end of an era. In addition to rewarding everything in that era, the algorithm also looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures. Review the Rewards Design page for more details.

    -

    Validator Inactivity

    -

    Validators who send no messages during an entire era are marked as inactive and cease participating in the auction until they send a special transaction that reactivates their bid.

    -

    Founding Validators

    -

    When launching a new Casper network, founding validators are subject to token lock-up, which prevents them from withdrawing any tokens from their bids for 90 days. Then, the network releases their genesis bid tokens in weekly steps, linearly, over an additional 90 days.

    - - \ No newline at end of file diff --git a/next/concepts/economics/fee-elimination/index.html b/next/concepts/economics/fee-elimination/index.html deleted file mode 100644 index 9fd157c66..000000000 --- a/next/concepts/economics/fee-elimination/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Fee Elimination | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Fee Elimination on Mainnet

    -

    Casper networks support configurable fee, refund, and pricing strategies. The Mainnet Condor release has enabled "fee elimination", also known as the "no fee mode", or "no fee transactions" to reduce operational costs for developers. This configurable feature places balance holds on a user's purse rather than taking fees for sending transactions to the network. This behavior benefits parties who send periodic transactions, as their gas costs are locked for some time and then either released all at once or linearly over time, depending on the chainspec settings. Recall that the network chainspec contains all the configuration choices on which every node must agree.

    -

    Instead of paying for gas to execute transactions, the no_fee chainspec configuration instructs the network to place a balance hold on the paying purse without transferring tokens from the purse: fee_handling = { type = 'no_fee'}. The portion of a purse balance that is locked is not available to transfer or spend until it is released; it is marked with a timestamp equal to the block time. In the "no fee" mode, the available balance of a purse equals its actual total balance minus all non-expired balance holds on that purse. The configurable gas_hold_interval determines how long a balance hold remains in effect. The on-chain logic calculates the correct values for total balance and available balance. The query_balance_details RPC endpoint provides details on available balances and hold records.

    -
    note

    A processing hold is not the same as a gas (or balance) hold. The processing hold is a temporary hold that prevents double spend. For example, if you want to do a transfer, you also need to cover the cost of the transfer.

    -

    Chainspec Configurations

    -

    The following chainspec configurations manage this feature:

    -
      -
    • fee_handling - Defines how fees are handled. To enable the "no fee" mode, set it to { type = 'no_fee'}.
    • -
    • refund_handling Defines how refunds of the unused portion of payment amounts are calculated and handled. For this setting to work with the "no fee" mode, set it to { type = 'no_refund'}. If no fees are transferred from the paying purse, no refunds need to be paid out.
    • -
    • pricing_handling - Defines how pricing is handled. For this setting to work with the no_fee mode, set it to { type = 'fixed'}, which means that costs are fixed per the cost table, and senders do not specify how much they pay.
    • -
    • validator_credit_cap - The validator credit cannot exceed this percentage of their total stake.
    • -
    • `gas_hold_balance_handling - Defines how gas holds affect available balance calculations. Valid options are 'accrued' (the sum of the full value of all non-expired holds) and 'amortized' (the sum of each hold is amortized over the time remaining until expiry).
    • -
    • gas_hold_interval - Defines how long gas holds last.
    • -
    -

    Mainnet Condor Configurations

    -

    These are the fee elimination settings for the Condor release on Mainnet:

    -
    # Defines how refunds of the unused portion of payment amounts are calculated and handled.
    #
    # Valid options are:
    # 'refund': a ratio of the unspent token is returned to the spender.
    # 'burn': a ratio of the unspent token is burned.
    # 'no_refund': no refunds are paid out; this is functionally equivalent to refund with 0% ratio.
    # This causes excess payment amounts to be sent to either a
    # pre-defined purse, or back to the sender. The refunded amount is calculated as the given ratio of the payment amount
    # minus the execution costs.
    refund_handling = { type = 'no_refund' }
    # Defines how fees are handled.
    #
    # Valid options are:
    # 'no_fee': fees are eliminated.
    # 'pay_to_proposer': fees are paid to the block proposer
    # 'accumulate': fees are accumulated in a special purse and distributed at the end of each era evenly among all
    # administrator accounts
    # 'burn': fees are burned
    fee_handling = { type = 'no_fee' }
    # If a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.
    validator_credit_cap = [1, 5]
    # Defines how pricing is handled.
    #
    # Valid options are:
    # 'classic': senders of transaction self-specify how much they pay.
    # 'fixed': costs are fixed, per the cost table
    # 'reserved': prepaid transaction (currently not supported)
    pricing_handling = { type = 'fixed' }

    # Defines how gas holds affect available balance calculations.
    #
    # Valid options are:
    # 'accrued': sum of full value of all non-expired holds.
    # 'amortized': sum of each hold is amortized over the time remaining until expiry.
    #
    # For instance, if 12 hours remained on a gas hold with a 24-hour `gas_hold_interval`,
    # with accrued, the full hold amount would be applied
    # with amortized, half the hold amount would be applied
    gas_hold_balance_handling = { type = 'accrued' }
    # Defines how long gas holds last.
    #
    # If fee_handling is set to 'no_fee', the system places a balance hold on the payer
    # equal to the value the fee would have been. Such balance holds expire after a time
    # interval has elapsed. This setting controls how long that interval is. The available
    # balance of a purse equals its total balance minus the held amount(s) of non-expired
    # holds (see gas_hold_balance_handling setting for details of how that is calculated).
    #
    # For instance, if gas_hold_interval is 24 hours and 100 gas is used from a purse,
    # a hold for 100 is placed on that purse and is considered when calculating total balance
    # for 24 hours starting from the block_time when the hold was placed.
    gas_hold_interval = '24 hours'
    -

    Computational and Storage Costs

    -

    Despite the introduction of fee elimination, the network continues to track computational cost based on opcodes as defined in the chainspec, thus retaining the gas pricing mechanism. Opcodes enable Casper nodes to agree on the computational cost of transactions, commonly known as gas. This mechanism is a solution to the halting problem in a distributed network, and it abstracts the computational cost in a way that is deterministically consistent across multiple machines.

    -

    Storage costs are also tracked and calculated using gas. Data written to global state is recorded forever and has a cost; therefore, the network charges for the Wasm that stores data in global state.

    -

    This feature complements the dynamic gas pricing model introduced and configured to scale gas costs based on network utilization.

    - - \ No newline at end of file diff --git a/next/concepts/economics/gas-concepts/index.html b/next/concepts/economics/gas-concepts/index.html deleted file mode 100644 index fc59212c6..000000000 --- a/next/concepts/economics/gas-concepts/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Gas Cost | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Gas and Resources

    -

    What is gas?

    -

    Gas is a conceptual measure of resources used while executing transactions on the blockchain. Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It correlates directly with the amount of computer processing a validator needs to provide to execute a transaction.

    -

    Gas fees are consumed on the network irrespective of whether a transaction was successful or not. Even when a transaction fails, the network measures computational work as gas because it consumes resources and space on the block as the validator attempts to execute it. Depending on how the network was configured, the transaction fee may or may not be refunded, or a hold may placed on the paying purse. See fee elimination for more details.

    -

    How is gas cost determined?

    -

    The amount of gas required for a transaction is determined by how much code is executed on the blockchain and the current average of all block utilization. Currently, gas is priced at a fixed price of 1 mote (1 CSPR is 10^9 motes) per 1 unit of gas. Cost is determined by the network's current_gas_price multiplier, which is dynamic and based on current network usage. A high rate of block utilization will increase the current_gas_price multiplier at the switch block, while low utilization will decrease the multiplier. There is both a minimum and a maximum potential multiplier, and all settings related to dynamic pricing can be configured in a Casper network's chainspec.

    -

    Why do we need to charge a cost?

    -

    Casper is a decentralized network of individual validators supplying their computational resources to keep the network live. As such, computations must be rate-limited and priced for the following reasons:

    -
      -
    • Rate-limiting is used to ensure a secure and live network: -
        -
      • It prevents a specific kind of denial-of-service (DoS) attack. In computer networks, rate-limiting controls the rate of requests sent or received by a network to prevent DoS attacks. Gas behaves similarly, because each block permits only a fixed amount of transactions (gas) to be included in the era.
      • -
      • It explicitly quantifies the system load. The cost helps us evaluate the use of computational resources and measure the amount of computational work that validators need to perform for each transaction. With this knowledge, we can specify minimum system requirements for validators.
      • -
      -
    • -
    • Pricing leads to more meaningful transactions: -
        -
      • Issuers of transactions and smart contract writers will be more aware of the limited network resources because there is a cost associated with each transaction. Pricing prevents users from spamming arbitrary amounts of empty transactions because there is a price to pay for each transaction.
      • -
      -
    • -
    - - \ No newline at end of file diff --git a/next/concepts/economics/staking/index.html b/next/concepts/economics/staking/index.html deleted file mode 100644 index 35253a5ee..000000000 --- a/next/concepts/economics/staking/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Staking | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Staking

    -

    The Casper Mainnet is a Proof-of-Stake blockchain that allows validators to stake the Casper native token CSPR on the network. Validators receive CSPR as an incentive for maintaining and securing the network. CSPR rewards are distributed as blocks are validated into existence and organized into eras.

    -

    Consensus mechanism: The Casper Mainnet and Testnet use a Proof-of-Stake consensus mechanism called Zug. Another Casper network can choose between Zug and Highway using the network's chainspec.

    -

    Number of validators: The Casper Mainnet supports up to 100 validators on the network. This number was chosen to strike a balance between performance and decentralization. This platform parameter can be increased through upgrades as development continues and performance improves. In addition, validators can stake on the Casper Mainnet through permissionless bonding by participating in an auction for the validator slot.

    -

    Permission-less bonding: For validators to begin staking and earning rewards, they must win a staking auction by competing with current and prospective validators to supply one of the forthcoming top stakes for a given era. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for a waiting period to unlock staked tokens.

    -

    Unbonding: To detach from the Casper Mainnet, it takes seven eras for both validators and delegators. Neither validators nor delegators receive rewards for the seven eras required for unbonding, as they are not actively contributing to the network's security during that time. However, during the unbonding period, they may receive rewards for participating in past eras. Read about rewards distribution here. The current unbonding period on the Casper Mainnet is 14 hours, based on the chainspec settings.

    -

    Eras and block times: An era on the Casper Mainnet is roughly 2 hours long. Casper's Zug consensus allows validators to propose blocks as quickly as network conditions allow. We anticipate block times to last between 8 seconds and 1 minute.

    -

    Block rewards: Validators receive rewards proportional to their weight for securing the network and participating in consensus by producing blocks and generating and distributing finality signatures. Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot participate.

    -

    Reward calculations: Reward calculations depend only on the linear structure of the blockchain and published finality signatures rather than block time or consensus mechanism. Reward calculations assume a known constant token supply inflation with nominal platform operation.

    -

    Reward cycle: Rewards are calculated and distributed to validators and delegators at the end of an era for all blocks in that era and several eligible blocks from the previous era. The algorithm looks back into blocks from the previous era to compensate for the delay in creating and distributing finality signatures.

    -

    Token supply and inflation: Mainnet launched with ten billion CSPR at genesis. The target annual supply growth rate is 8%.

    -

    Annual reward percentage: Validators on the Casper Mainnet earned between 10% and 20% of their staked CSPR in the first year of the Mainnet operation, with regular participation under expected network conditions. The growth of individual stakes depends on the total active stake, as only a fixed number of tokens is created per era.

    -

    Slashing: Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated.

    -

    Delegation rate: Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services.

    - - \ No newline at end of file diff --git a/next/concepts/global-state/index.html b/next/concepts/global-state/index.html deleted file mode 100644 index 01c915d5b..000000000 --- a/next/concepts/global-state/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Global State | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Global State

    -

    Introduction

    -

    The storage layer for the Casper blockchain is called global state and has the semantics of a key-value store with additional permissions logic. All accounts, contracts, and any associated data they have are stored in global state. Not all users can access all data, so permissions need to be set accordingly.

    -
    note

    Refer to Keys and Permissions for further information on keys.

    -

    Each finalized block causes changes to the network's global state because of the execution of the transactions it contains. For validators to efficiently judge the correctness of these changes, information about the new state needs to be communicated succinctly. Moreover, the network must communicate portions of global state to users while allowing them to verify the correctness of the parts they receive. For these reasons, the key-value store is implemented as a Merkle trie.

    -

    Merkle Trie Structure

    -

    Global State

    -

    At a high level, a Merkle trie is a key-value store data structure that can be shared piece-wise in a verifiable way (via a construction called a Merkle proof). Each node is labeled by the hash of its data. Leaf nodes are labeled with the hash of their data. Non-leaf nodes are labeled with the hash of the labels of their child nodes.

    -

    Casper's implementation of the trie has radix of 256, meaning each branch node can have up to 256 children. A path through the tree can be an array of bytes, and serialization directly links a key with a path through the tree as its associated value.

    -

    Formally, a trie node is one of the following:

    -
      -
    • a leaf, which includes a key and a value
    • -
    • a branch, which has up to 256 blake2b256 hashes, pointing to up to 256 other nodes in the trie (recall each node is labeled by its hash)
    • -
    • an extension node, which includes a byte array (called the affix) and a blake2b256 hash pointing to another node in the trie
    • -
    -

    The purpose of the extension node is to allow path compression. Consider an example where all keys use the same first four bytes for values in the trie. In this case, it would be inefficient to traverse through four branch nodes where there is only one choice; instead, the root node of the trie could be an extension node with an affix equal to those first four bytes and a pointer to the first non-trivial branch node.

    -

    The Rust implementation of Casper's trie can be found on GitHub:

    - -
    note

    Conceptually, each block has its trie because the state changes based on the transactions it contains. For this reason, Casper's implementation has a notion of a TrieStore, which allows us to look up the root node for each trie.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/A/index.html b/next/concepts/glossary/A/index.html deleted file mode 100644 index 737c6f60c..000000000 --- a/next/concepts/glossary/A/index.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - -A | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    A

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Account

    -

    An Account is a structure that represents a user on a Casper network. Information on creating an account can be found here. Casper's Condor release introduces the concept of an addressable entity, which contains an account entity type that supersedes legacy accounts.

    -

    Account Hash

    -

    The account hash is a 32-byte hash of the public key representing the user account. Information on generating an account hash can be found here.

    -

    Addressable Entity

    -

    An addressable entity is a post-2.0 type that merges the concept of an Account and a Contract, bringing in features from both. More information can be found here.

    -

    AssemblyScript

    -

    AssemblyScript is a TypeScript-based programming language (JavaScript with static types) that is optimized for WebAssembly and compiled to WebAssembly using asc, the reference AssemblyScript compiler. It is developed by the AssemblyScript Project and the AssemblyScript community.

    -

    Auction

    -

    The auction determines the composition of the validator set for each era of the protocol. It is a "first-price" auction (where winning bids become stakes) with a fixed number of spots chosen to balance security with performance. Because rewards are proportional to the stake, it is expected that this competitive mechanism will provide a powerful impetus for staking as many tokens as possible.

    -

    Auction contract

    -

    The auction contract acts as a front-end user interface to the auction by directly accepting bids from validators and delegators. It also contains the logic necessary for carrying out the auction.

    -

    Auction delay

    -

    The number of full eras that pass between the booking block and the era whose validator set it defines. The auction delay is configurable and can be several eras long.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/B/index.html b/next/concepts/glossary/B/index.html deleted file mode 100644 index 658b23cbf..000000000 --- a/next/concepts/glossary/B/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - -B | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    B

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Blake2b

    -

    A function used within the Casper platform to create cryptographic hashes. More information can be found here.

    -

    Block

    -

    Used in two contexts:

    -
      -
    1. A data structure containing a collection of transactions. Blocks form the primary structure of the blockchain.
    2. -
    3. A message that is exchanged between nodes containing the data structure as explained in (1).
    4. -
    -

    Each block has a globally unique ID, achieved by hashing the contents of the block.

    -

    Each block points to its parent. An exception is the first block, which has no parent.

    -

    Block creation

    -

    Block creation means computing the transaction results and collecting the results into a block. We follow a process called execution after consensus.

    -

    The block proposal happens first, and the proposed proto block contains a set of transactions that have not been executed yet.

    -

    Only after consensus on a proto block has been reached, the transactions are executed. The resulting new global state root hash is put into an actual block, together with the executed transactions.

    -

    Note that only validators can create valid blocks.

    -

    Block finality

    -

    A block is "finalized" if validators with more than two-thirds of the total network weight agree on adding it to the blockchain.

    -

    For an observer to see a conflicting block as finalized, several validators whose total weight exceeds one-third of the total network weight would have to collude and show different information in a way that would ultimately be detected and punished (see eviction).

    -

    Block gossiping

    -

    Block gossiping occurs when a message containing a block is sent to one or more nodes on the network. In other words, block gossiping is sending a block validated by the current node but created by another node. The terms block gossiping and block passing are interchangeable.

    -

    Block height

    -

    Block height is an identifier for a given block based on the number of blocks completed prior to that block.

    -

    Block passing

    -

    See block gossiping.

    -

    Block processing

    -

    Block processing consists of running the transactions in a block received from another node to determine updates to the global state. Note that this is an essential part of validating blocks.

    -

    Block proposal

    -

    Sending a (newly) created block to the other nodes on the network for potential inclusion in the blockchain. Note that this term applies to NEW blocks only.

    -

    Block validation

    -

    The process of determining the validity of a block obtained from another node on the network.

    -

    Blockchain

    -

    Blockchain is a P2P network where the collection of nodes (validators) concurrently updates a decentralized, shared database. They do this collectively, building an ever-growing chain of transactions. For performance reasons, transactions are bundled in blocks. According to a particular cooperation protocol (consensus protocol), the collection of nodes connected via a P2P network cooperate to maintain this shared database as a single source of truth. The database's current state is called the global state and has a sizeable map-like collection.

    -

    Block store

    -

    The layer of the node software responsible for storing blocks. This layer is persisted and can be used to allow a node to recover its state after a crash.

    -

    Bond

    -

    The amount of money (in crypto-currency) that is allocated by a node in order to participate in consensus (and to be a validator).

    -

    Bonding

    -

    Depositing money in the auction contract and try to become a staker. The bonding request is a transaction that transfers tokens to the auction contract. In the next booking block, a new set of validators is determined, with weights according to their deposits. This new set becomes active in the era(s) using that booking block.

    -

    Booking block

    -

    The booking block for an era is the block that determines the era's validator set. In it, the auction contract selects the highest bidders to be the future era's validators. There is a configurable delay, the auction_delay, which is the number of eras between the booking block and the era to which it applies. The booking block is always a switch block, so the booking block for era N + auction_delay + 1 is the last block of era N.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/C/index.html b/next/concepts/glossary/C/index.html deleted file mode 100644 index da55073bf..000000000 --- a/next/concepts/glossary/C/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - -C | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    C

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Cargo

    -

    Cargo is Rust's build system and package manager. This tool manages Rust projects, such as building code and downloading dependencies.

    -

    Casper network

    -

    Casper is a Proof-of-Stake blockchain platform with an account-based model that performs execution after consensus. More information on the design of a Casper network can be found here.

    -

    CBC

    -

    Correct-by-construction (CBC) protocols are consensus protocols meeting the following properties:

    -
      -
    • All the nodes share the same proof of asynchronous liveness, which means that the protocol will continue to produce blocks at some interval.
    • -
    • The consensus has mathematically provable safety, which means that once a block is committed, it cannot be reverted.
    • -
    -

    Chainspec

    -

    A collection of configuration settings describing the state of the system at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. Here is an example chainspec, which will change with newer releases.

    -

    Consensus

    -

    Consensus is an algorithm used to mandate agreement on the blockchain among all nodes. The blockchain, although being built in a decentralized way, eventually converges so that all nodes eventually agree on whether a given block is part of the chain or not. The algorithm for securing an agreement is what is known as consensus. The consensus layer contains the algorithm, but the algorithm should not be confused with the consensus layer.

    -

    Contract runtime

    -

    Enables developers to use a seamless workflow for authoring and testing their smart contracts. This environment can also be used for continuous integration, enabling Rust smart contracts to be managed using development best practices.

    -

    Correct by construction

    -

    See CBC.

    -

    Crate

    -

    A compilation unit in Rust. A crate can be compiled into a binary or into a library. By default, rustc, the compiler for the Rust programming language, will produce a binary from a crate.

    -

    CSPR

    -

    CSPR is the Casper token pre-defined on the Casper Mainnet and used to pay for transaction execution and for staking (securing the network).

    - - \ No newline at end of file diff --git a/next/concepts/glossary/D/index.html b/next/concepts/glossary/D/index.html deleted file mode 100644 index 9db6e5427..000000000 --- a/next/concepts/glossary/D/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -D | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    D

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    dApp

    -

    A decentralized application (dApp) employs smart contracts installed on a decentralized peer-to-peer network such as a blockchain.

    -

    Delegation rate

    -

    Node operators (validators) define a delegation rate that they take in exchange for providing staking services. This delegation rate is a percentage of the rewards that the node operator retains for their services.

    -

    Delegator

    -

    Delegators are users who participate in the platform's security by delegating their tokens to validators (which adds to their weight) and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    -

    Deploy

    -

    Deploys are units of work when executed cause global state to be altered. Deploys can contain Wasm to be executed and/or Wasm to be stored on chain. Among many examples, Deploys can transfer tokens from one Account's purse to another, reward node validation, or execute Wasm on the network.

    -

    Casper's Condor release introduces the Transaction. Legacy deploys are a subset of the new transaction architecture and, in most cases, will continue to function as expected.

    -

    All deploys on a Casper network can be broadly categorized as some unit of work that, when executed and committed, affects change to the global state.

    -

    Review the deploy data structure and the deploy implementation for more details.

    -

    Dictionary

    -

    A Dictionary is a storage data structure on a Casper network. Dictionaries represent a more efficient and scalable form of data storage when compared to NamedKeys.

    -

    More information can be found in the Reading and Writing to Dictionaries document.

    -

    Dynamic gas pricing

    -

    Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Find more details here.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/E/index.html b/next/concepts/glossary/E/index.html deleted file mode 100644 index 8c39cda34..000000000 --- a/next/concepts/glossary/E/index.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - -E | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    E

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Ecosystem

    -

    The ecosystem layer in Casper encompasses dApp design and operation.

    -

    Entry point

    -

    See EntryPoint and Defining the Contract Entry Points.

    -

    Equivocation

    -

    A process where dishonest nodes sign conflicting consensus messages. If a node is caught equivocating, other validators will ignore its messages, and the node will become inactive.

    -

    Era

    -

    A period of time during which the validator set does not change.

    -

    In a Casper network, validators cannot join and leave at any point in time, but only at era boundaries. An era's validators are determined using an auction. At the beginning of the era, the validators create a new instance of the consensus protocol and run this instance until they finalize the era's last block (see booking block).

    -

    Eviction

    -

    Validators that fail to participate in era will have their bid deactivated by the protocol, suspending their participation until they signal readiness to resume participation by invoking a method in the auction contract.

    -

    External client

    -

    Any hardware/software connecting to a Node for the purpose of sending transactions or querying the state of the blockchain.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/F/index.html b/next/concepts/glossary/F/index.html deleted file mode 100644 index 41a011b39..000000000 --- a/next/concepts/glossary/F/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -F | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    F

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Finality

    -

    See block finality.

    -

    Fungible

    -

    A fungible item possesses mutual interchangeability and may be replaced seamlessly with another, identical item. A fungible token standard is one in which all tokens are equivalent and interchangeable. In contrast to a non-fungible token, where each token is unique and not interchangeable.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/G/index.html b/next/concepts/glossary/G/index.html deleted file mode 100644 index beaf2337d..000000000 --- a/next/concepts/glossary/G/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - -G | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    G

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Gas

    -

    Gas is a conceptual measure of resources used when executing transactions on the blockchain.

    -

    Gas cost

    -

    Gas cost is the amount of gas consumed during the processing cycles that execute a transaction on the network. It is directly correlated with the amount of computer processing a validator needs to provide to execute a transaction.

    -

    Gas price

    -

    Multiplier applied to gas cost. See dynamic gas pricing.

    -

    Genesis

    -

    The state of the virtual machine at the beginning of the blockchain.

    -

    Groups

    -

    The user groups feature provides access control to the entry points of a contract by creating a new user group for that contract (versioned or not). This feature restricts the use of the constructor entry_point, which sets up the necessary data storage in the runtime context that belongs to the contract. Here is how it works:

    -
      -
    • User groups associate a set of URefs with a label.
    • -
    • The entry points on a contract can accept a list of labels
    • -
    • The runtime checks that a URef from at least one of the allowed groups is present in the caller's context before execution.
    • -
    -

    Global state

    -

    When thinking of a blockchain as a decentralized computer, the global state is its memory state.

    -

    When thinking of a blockchain as a shared database, the global state is the snapshot of the database's data.

    -

    Technically, a global state is a (possibly extensive) collection of key-value pairs, where the keys are references (Refs), and the values are large binary objects (BLOBs).

    -

    For every block B in the blockchain, one can compute the global state achieved by executing all transactions in this block and its ancestors. The root hash identifying this state is stored in every executed block.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/H/index.html b/next/concepts/glossary/H/index.html deleted file mode 100644 index a16b0f3bb..000000000 --- a/next/concepts/glossary/H/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -H | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    H

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Hash

    -

    A hash is the output of a cryptographic function that creates a fixed-length output from an input of any length. Casper networks use the blake2b function.

    -

    Highway

    -

    A consensus protocol that allows clients to use different confidence thresholds to convince themselves that a given block is finalized. The full paper is found in GitHub: https://github.com/casper-network/highway.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/I/index.html b/next/concepts/glossary/I/index.html deleted file mode 100644 index a1c8f4204..000000000 --- a/next/concepts/glossary/I/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -I | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/concepts/glossary/J/index.html b/next/concepts/glossary/J/index.html deleted file mode 100644 index 4c736e57a..000000000 --- a/next/concepts/glossary/J/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -J | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    J

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    JSON

    -

    JSON (JavaScript Object Notation) is a data-interchange format used for several purposes throughout the Casper ecosystem. More information on JSON can be found here.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/K/index.html b/next/concepts/glossary/K/index.html deleted file mode 100644 index 2e410b0aa..000000000 --- a/next/concepts/glossary/K/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -K | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    K

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Key

    -

    Keys are the type under which data (i.e., CLValues, smart contracts, user accounts) are indexed on the network. More information on keys in a Casper network can be found here.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/L/index.html b/next/concepts/glossary/L/index.html deleted file mode 100644 index 7bbd51e11..000000000 --- a/next/concepts/glossary/L/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - -L | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    L

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Liveness

    -

    A necessary property of a consensus protocol: that agreement is always eventually achieved (under certain assumptions).

    -

    If the protocol is not live, the blockchain does not grow anymore, and the network stalls.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/M/index.html b/next/concepts/glossary/M/index.html deleted file mode 100644 index f7273e5a3..000000000 --- a/next/concepts/glossary/M/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -M | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    M

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Mainnet

    -

    The live, decentralized, and public Casper platform, with version 1.0.

    -

    Merkle tree

    -

    A hash tree in which every leaf node is labelled with the cryptographic hash of a data block, and every non-leaf node is labelled with the cryptographic hash of the labels of its child nodes.

    -

    Motes

    -

    A mote is the native accounting unit for a Casper network. All accounting done within a Casper network occurs through motes, with the CSPR token existing as a human-readable convenience wherein a single CSPR consists of 1,000,000,000 motes.

    -

    Multi-Sig

    -

    Short for Multi-Signature. Accounts on a Casper network can associate other accounts to allow or require a multiple signature scheme for transactions. More information on the use of Multi-Sig can be found here.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/N/index.html b/next/concepts/glossary/N/index.html deleted file mode 100644 index d4dbb3d89..000000000 --- a/next/concepts/glossary/N/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - -N | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    N

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    NamedKeys

    -

    NamedKeys -are a collection of String-Key pairs used to easily identify some data on the network.

    -
      -
    • The String is the name given to identify the data
    • -
    • The Key is the data to be referenced
    • -
    -

    Node

    -

    A Casper node is a physical or virtual device that is participating in a Casper network. They store, validate, and preserve the blockchain data.

    -

    You will encounter different types of nodes on the network:

    -
      -
    • Bonded node: a node that has tokens staked as bond and is part of the validator set participating in consensus in that particular era.
    • -
    • Unbonded node: a type of node on the network that receives and processes blocks but does not create blocks and is not a validator. It is otherwise a fully functioning node, following the consensus protocol to know the current status of the blockchain (and therefore also the VM state). Such nodes are useful for querying the status of the blockchain (e.g., to learn information about transaction finalization).
    • -
    -

    Node operator

    -

    See operator.

    -

    Non-Fungible Token (NFT)

    -

    Cryptographic assets on a blockchain with unique identification codes and metadata that distinguish them from each other. They cannot be traded or exchanged at equivalency. This differs from fungible tokens like cryptocurrencies, which are identical to each other and, therefore, can be used as a medium for commercial transactions.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/O/index.html b/next/concepts/glossary/O/index.html deleted file mode 100644 index f767d81d7..000000000 --- a/next/concepts/glossary/O/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -O | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    O

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Operator

    -

    Anyone running a node is an operator.

    -

    An operator that has staked a bid but does not currently have a validator slot is a *staked operator*.

    -

    An operator whose bid has won a validator slot in the auction for a specific era is a validator in that era.

    -

    It is common for a staked operator to win an auction slot for many eras in a row and thus be a validator for a range of eras.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/P/index.html b/next/concepts/glossary/P/index.html deleted file mode 100644 index cac4a054e..000000000 --- a/next/concepts/glossary/P/index.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - -P | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    P

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Partial synchrony

    -

    Partial synchrony is used to define the fault tolerance of a consensus protocol, which is a time-bound mechanism to note suspicions or problems (failure, crashes, etc.). When a protocol is provably live under partial synchrony, it means that the nodes will make a decision within a fixed time period. Once the decision is made and a block is committed, it cannot be reverted. Also, see CBC.

    -

    Participate in consensus

    -

    The process of following the consensus algorithm. The primary participants are validators, bonded with their stake and part of the validator set for that particular era. Delegators participate indirectly by delegating their tokens to one or more of these validators and contributing by increasing the total stake that ensures the security of the network.

    -

    Payment code

    -

    The payment code is the Wasm program that pays the transaction execution fee.

    -

    Peer node

    -

    A node on a peer-to-peer (P2P) network.

    -

    Permissionless

    -

    A permissionless blockchain network has its consensus and transaction validation process open and available for anyone to participate. Being permissionless is an essential characteristic of most public blockchains, enabling decentralization, transparency, and value exchange between participants.

    -

    Primary token

    -

    See CSPR.

    -

    Private key

    -

    See secret key.

    -

    Proof-of-Stake

    -

    Proof-of-Stake (PoS) is a mechanism by which a cryptocurrency blockchain network achieves permissionless-ness. The voting power in consensus is proportional to the number of staked tokens (digital currency specific to this system). The validator vouches with their tokens for the correct operation of their node. A popular choice in such systems is to periodically (once per era, in our case) delegate a fixed size committee of participants, which then is responsible for running the consensus on which blocks to add to the blockchain.

    -

    Proof-of-Work

    -

    A mechanism used in Bitcoin and Etherium for incentivizing participation and securing the system. In these protocols, a participant's voting power is proportional to the amount of computational power possessed.

    -

    Proposer

    -

    The proposer is a selected validator by a Casper network to propose the next block. A validator becomes a proposer by proposing a block to be added to the chain and receiving the appropriate reward. The proposing process assures that new blocks will be added to the blockchain.

    -

    Proto block

    -

    The block proposed by the round leader, which the consensus processes. Only after consensus is complete, the proto block is executed, and the global state is updated.

    -

    A leader is selected from the validator set of that era for each round. The chance of getting selected as a leader is in proportion to the stake one has in that era.

    -

    Purse

    -

    A purse is a unique type of URef representing a token balance. An entity's main purse represents the balance of CSPR tokens (in motes) the entity has access to on a Casper network. An entity may have more than one purse in some instances. More information on purses can be found here.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/Q/index.html b/next/concepts/glossary/Q/index.html deleted file mode 100644 index 92c0fb26f..000000000 --- a/next/concepts/glossary/Q/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -Q | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/concepts/glossary/R/index.html b/next/concepts/glossary/R/index.html deleted file mode 100644 index c3056b3c2..000000000 --- a/next/concepts/glossary/R/index.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - -R | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    R

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Reward

    -

    Validators receive rewards for participating in consensus and finalizing blocks. There is no precise per-block reward. Rewards are split proportionally among stakes within an era. If a validator is offline or cannot vote on many blocks, the rewards earned are also reduced. Delegators can only receive a proportional amount of the validator's rewards minus the validator's delegation rate. Rewards are distributed at the end of each era.

    -

    Root hash

    -

    The root hash, or Merkle Root, is a representation of all the data in a given hash tree. Refer to Merkle tree if you wish to learn more.

    -

    Rust

    -

    A programming language similar to C++, designed for performance and safety, especially safe concurrency.

    -

    Rustdocs

    -

    As part of the Rust development environment, the Rustdocs describe the Casper contracts library, the Casper types library, and the Casper test support library.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/S/index.html b/next/concepts/glossary/S/index.html deleted file mode 100644 index 18f9df853..000000000 --- a/next/concepts/glossary/S/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -S | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    S

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Safe

    -

    When a protocol is provably safe, it means that all the participating nodes will make the same decision and continue to produce blocks at some interval. Also, see CBC.

    -

    Secret key

    -

    A cryptographic and confidential key that signs transactions to ensure their correct execution (carrying out only the user's intended operations).

    -

    Seigniorage

    -

    The reward mechanism by which validators are rewarded for participating in consensus. New tokens are minted and given to validators.

    -

    Session code

    -

    Session code is Wasm executed in the context of an account entity through sending a transaction. The session code contains code the user wishes to execute against the blockchain. When the session code executes, it performs changes to global state.

    -

    Slashing

    -

    In Proof-of-Stake, the deposit acts as collateral. The validator guarantees that it correctly follows the protocol. If the validator node violates the protocol, the deposited amount gets slashed, i.e., a part of it is removed.

    -

    Smart contract

    -

    Smart contracts are self-executing computer programs that perform specific actions based on pre-programmed terms stored on the blockchain. Once the pre-programmed terms are met, the smart contract executes the action and eliminates the need for a centralized third party.

    -

    On a Casper network, a smart contract is a WebAssembly (Wasm) program that the network stores as a value in the global state. The execution of a smart contract causes changes to the global state.

    -

    A smart contract can be invoked by a transaction or by another smart contract. Smart contracts can declare input data as the arguments of a function. When invoking a smart contract, one must provide the input values.

    -

    Smart-contract platform

    -

    A smart contract platform provides the required blockchain environment for the creation, deployment, and execution of smart contracts.

    -

    Staker

    -

    A staker is either a validator or a delegator. Stakers take on the slashing risk in exchange for rewards. Stakers will deposit their tokens by sending a bonding request in the form of a transaction (deployment) to the system. If a validator is slashed, the staker will lose their tokens.

    -

    Staking

    -

    A feature of Proof-of-Stake protocols that allows token holders to actively participate in the protocol, thus securing the network. The Staking Guide highlights the steps required to stake CSPR tokens on the Casper Mainnet.

    -

    State root hash

    -

    The state root hash is an identifier of the network's global state at a moment in time. The state root hash changes with each block executed, containing transactions. Normally, empty blocks do not modify global state. But, if the empty block is the last one in an era, it will also change the state root hash due to changes introduced by the auction contract calculating the validators for future eras.

    -

    Stateful

    -

    Stateful execution depends on a previous state, which makes the output differ each time. Such executions are performed with the context of previous executions and the current execution may be affected by what happened during previous executions.

    -

    Stateless

    -

    Stateless means that the execution doesn't depend on a previous state, so the output of the execution is the same each time. It does not save or reference information about previous executions. Each execution is from scratch as if for the first time.

    -

    Switch Block

    -

    A Switch Block is the final block in an era, which contains the era_summary. See also booking block.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/T/index.html b/next/concepts/glossary/T/index.html deleted file mode 100644 index d80c2fbc3..000000000 --- a/next/concepts/glossary/T/index.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - -T | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    T

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Token

    -

    A type of cryptocurrency that represents an asset. See CSPR.

    -

    Transaction

    -

    Transactions are a unit of work sent by a client to the network, which when executed can cause global state to be altered. They were introduced with Casper's Condor release and supersede the concept of a Deploy. Transactions offer more efficient means of interacting with a Casper network, but legacy deploys will continue to function, in most cases. More information on transactions can be found here.

    -

    Turing-complete blockchain

    -

    Turing completeness refers to the ability of a machine to execute computational problems on its own by deciding or recognizing data manipulation rule sets.

    -

    For a blockchain to be Turing-complete, it means that it can understand and execute any smart contract given enough resources such as a robust code-base (necessary instructions), time, processing power, memory, etc. without human interaction or interference.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/U/index.html b/next/concepts/glossary/U/index.html deleted file mode 100644 index 5590b71b9..000000000 --- a/next/concepts/glossary/U/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -U | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    U

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Unbonding

    -

    Withdrawing money from the auction contract with withdraw bid and possibly ceasing to be a validator. The unbonding request is a transaction that informs the auction contract that the sender wants to decrease their deposit. In the next booking block, only the decreased deposit is considered when determining a future validator set. If it has been decreased to 0, the sender will not be included in the validator set anymore. However, the amount only gets transferred to the sender after the unbonding period. If during that period their node exhibits a fault, the unbonded amount can still be slashed.

    -

    URef

    -

    An Unforgeable Reference, used by a Casper network to store any value other than Account. More information can be found here.

    -

    Users

    -

    Users execute session and contract code using the platform's computational resources.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/V/index.html b/next/concepts/glossary/V/index.html deleted file mode 100644 index 14b8651ea..000000000 --- a/next/concepts/glossary/V/index.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - -V | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    V

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Validator

    -

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks, backing this chain's security with their stakes. Their importance (often referred to as "weight") both to protocol operation and security is, in fact, equal to their stake, which includes both their own and delegated tokens.

    -

    The responsibilities of a validator include:

    - -

    Validators are bonded because they are responsible for progressing the system's state as clients use it (e.g., sending transactions). Validators and stakers can lose their bond (be evicted) for not following the protocol correctly. Validators are also paid for by creating blocks (also by validating blocks -- though this is only indirectly; validators cannot be paid for if they do not validate by design), giving them more incentive to serve the network correctly.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/W/index.html b/next/concepts/glossary/W/index.html deleted file mode 100644 index 0945ea95f..000000000 --- a/next/concepts/glossary/W/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -W | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    W

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    -

    Web3

    -

    An advanced version of the internet based on decentralization and trustless interactions.

    -

    WebAssembly

    -

    WebAssembly (sometimes abbreviated Wasm) is an open standard that defines a portable binary-code format for executable programs and a corresponding textual assembly language and interfaces for facilitating interactions between such programs and their host environment. The main goal of WebAssembly is to enable high-performance applications on web pages. The format is designed to be executed and integrated into other environments, including standalone ones.

    - - \ No newline at end of file diff --git a/next/concepts/glossary/X/index.html b/next/concepts/glossary/X/index.html deleted file mode 100644 index 9f79dd7e0..000000000 --- a/next/concepts/glossary/X/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -X | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/concepts/glossary/Y/index.html b/next/concepts/glossary/Y/index.html deleted file mode 100644 index 182fa3242..000000000 --- a/next/concepts/glossary/Y/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -Y | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/concepts/glossary/Z/index.html b/next/concepts/glossary/Z/index.html deleted file mode 100644 index 067506fda..000000000 --- a/next/concepts/glossary/Z/index.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - -Z | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/concepts/index.html b/next/concepts/index.html deleted file mode 100644 index c6b4d36cb..000000000 --- a/next/concepts/index.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Concepts Overview

    -

    The Casper blockchain is a Turing-complete smart-contracting platform using a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The Casper Mainnet is permissionless, decentralized, and public. Network administrators can also create private or hybrid Casper networks as described here.

    -

    Concepts

    -

    This section of the documentation covers the core concepts underpinning the Casper blockchain. Working with Casper requires an understanding of blockchain technology, as well as some Casper-specific features. We recommend starting with the topics below if you are new to Casper.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Introduction to the Casper BlockchainHigh-level details about the Casper blockchain
    Introduction to dAppsDeveloping distributed applications on the Casper blockchain
    Addressable EntitiesLearn about addressable entities and how they relate to accounts and smart contracts.
    Accounts and Cryptographic KeysThe Casper programming model is account-based. Learn how Casper accounts work and how they are secured
    Key TypesHashes/Keys are used throughout the Casper ecosystem for addresses, packaging data, and more
    Global StateLearn about the storage layer for the Casper blockchain. All accounts, contracts, and data are stored in global state
    Call StacksLearn how Casper manages the calling of a contract
    Transactions and the Transaction LifecycleTransactions are a concept fundamental to the Casper blockchain. Learn about transactions, what they are for, how to create and send them
    Smart ContractsLearn how to develop smart contracts on Casper
    DictionariesLearn about dictionaries, which are a primary construct for storing and retrieving data on the Casper platform
    SerializationLearn about serializing data types and the Casper Serialization Standard
    DesignThe high-level design of a Casper network
    EconomicsLearn about the Casper on-chain economics
    GlossaryA compendium of all the terms used in Casper, in alphabetical order
    -

    Next Steps

    -

    After learning the basic concepts underpinning the Casper protocol, you may wish to look into the following categories.

    -

    Developers

    -

    The Developers area caters to those interested in building dApps and writing smart contracts, including information about specific features or Casper APIs.

    -

    Operators

    -

    The Operators section caters to those who want to run and administrate a Casper node or network.

    -

    Users

    -

    The Users section contains tutorials for those interested in interacting with the Casper blockchain using a block explorer or a Ledger device.

    -

    Resources

    -

    Navigate to Resources to try various tutorials. If you are just getting started and looking to build your first Casper-based dApp, start with the beginner tutorials. Afterward, continue with more advanced tutorials to explore the multi-signature feature, runtime return values, and other essential features.

    - - \ No newline at end of file diff --git a/next/concepts/intro-to-dapps/index.html b/next/concepts/intro-to-dapps/index.html deleted file mode 100644 index 6269c930c..000000000 --- a/next/concepts/intro-to-dapps/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -dApps | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Introduction to dApps

    -

    What is a dApp?

    -

    DApp stands for Decentralized Application. Specifically, it refers to an application built on a blockchain network which combines smart contracts and a user interface.

    -

    A decentralized network consists of a group of interchangeable machines (nodes) that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    -

    A dApp is not just a client-server application where the application can do some work offline, nor is it a web application which can operate in a disconnected mode. A dApp is conceived and built using a distributed architecture where a network of nodes does the processing of smart contracts instead of a single central server.

    -

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized nature of the network means that node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    -

    Interacting with a Casper Decentralized Network

    -

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    -

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. -A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    -

    Updating data in a Casper dApp

    -

    Sending a transaction is the only means by which a dApp can change global state. All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    -

    Post-Consensus Execution in a Casper network

    -

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means that observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    -

    Transaction lifecycle

    -

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    - -
    - - \ No newline at end of file diff --git a/next/concepts/list-auth-keys/index.html b/next/concepts/list-auth-keys/index.html deleted file mode 100644 index 511c44939..000000000 --- a/next/concepts/list-auth-keys/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -Authorization Keys | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Authorization Keys

    -

    This topic explains the usage of authorization keys when signing a transaction and how to access them from a smart contract. Try the Working with Authorization Keys tutorial for an example.

    -

    Associated Keys vs. Authorization Keys

    -

    Let's review the difference between associated keys to an Account and authorization keys for a transaction.

    -
      -
    • Associated keys are public keys that are associated with a given account. To understand associated keys and how they are linked to an account, read about associated keys and weights and try the Two-Party Multi-Signature tutorial.
    • -
    • Authorization keys are public keys used to sign a transaction and are listed in the transaction's approvals. Authorization keys are a subset of the associated keys of the account under which the transaction is executed.
    • -
    • When a node receives a transaction, it checks that the transaction has the required authorization keys under approvals before including it in a block.
    • -
    • Different transactions executing the same smart contract can have different authorization keys.
    • -
    -

    Auth Keys

    -

    Here is a sample JSON representation of an Account's associated keys:

    -
    "associated_keys": [
    {
    "account_hash": "account-hash-1ab…11",
    "weight": 1
    },
    {
    "account_hash": "account-hash-2cd…22",
    "weight": 1
    },
    {
    "account_hash": "account-hash-3de…33",
    "weight": 1
    },
    {
    "account_hash": "account-hash-4fg…44",
    "weight": 1
    }
    ], ...
    -

    Here is a sample JSON representation of a transaction's authorization keys:

    -
    "approvals": [
    {
    "signer": " 2cd...22",
    "signature": "02df8c...f481"
    },
    {
    "signer": "4fg...44",
    "signature": "02ef21...756a"
    }
    ]
    -

    Accessing Authorization Keys from a Smart Contract

    -

    Contract code can retrieve the set of authorization keys for a given transaction by calling the contract_api::runtime::list_authorization_keys function, which returns the set of account hashes representing the keys used to sign the transaction.

    -

    When to Use Authorization Keys

    -

    Authorization keys give developers more fine-grained control within their smart contracts. For example, developers can define a hierarchy within an account's associated keys. Then, they can use this hierarchy and the current execution's authorization keys to limit access for certain operations.

    -

    Try the Working with Authorization Keys tutorial to view an example workflow.

    - - \ No newline at end of file diff --git a/next/concepts/serialization/index.html b/next/concepts/serialization/index.html deleted file mode 100644 index 85820df98..000000000 --- a/next/concepts/serialization/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -Binary Serialization Standard | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Binary Serialization Standard

    -

    We provide a custom implementation to serialize data structures used by the Casper node to their byte representation. This category details custom serialization implementation, allowing developers to build a library that is compatible with the custom serialization.

    -

    The Casper Binary Serialization Standard uses a default u8 byte tag to identify the subsequent data's type and direct further deserialization. Additional serialization rules can be found in the following sub-categories.

    - - - - - - - - - - - - - - - - - - - - - -
    PageDescription
    PrimitivesBase-level types used to create more complex structures.
    StructuresMajor structures used through Casper systems, as well as their included sub-types.
    TypesMinor types not covered Primitives or Structures.
    - - \ No newline at end of file diff --git a/next/concepts/smart-contracts/index.html b/next/concepts/smart-contracts/index.html deleted file mode 100644 index bbbc0db21..000000000 --- a/next/concepts/smart-contracts/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - -Smart Contracts | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Smart Contracts

    -

    Smart Contracts in General

    -

    A smart contract is a self-executing program that automates the actions required in a digital agreement. Once completed, the transactions are trackable and irreversible. Smart contracts permit trusted transactions and agreements among disparate, anonymous parties without the need for a central authority, legal system, or external enforcement mechanism.

    -

    Casper Smart Contracts

    -

    Casper smart contracts can be implemented in any programming language that compiles to Wasm, which can be installed and executed on-chain using transactions. Most documentation examples and the Casper system contracts are written in Rust. You can find a guide to writing a simple, smart contract in Rust here.

    -

    Session Code

    -

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on-chain. Entry points in a contract provide access to the contract code installed in global state. Either session code or another smart contract may call these entry points. Understand when you would use session code over contract code here.

    -

    Factory Pattern

    -

    From node version 2.0, Casper networks provide host-side support for the factory implementations. When the APIs were updated to support this pattern, the focus was on seamless integration with existing Wasm on the Casper blockchain. Contracts already installed in global state will not be affected by these updates. The corresponding Casper Enhancement Proposal provides additional details. Also, you can learn to write a simple contract with factory entry points by following the The Factory Pattern developer guide.

    -

    Further Reading

    -
    - - \ No newline at end of file diff --git a/next/counter-testnet/index.html b/next/counter-testnet/index.html deleted file mode 100644 index 09005575a..000000000 --- a/next/counter-testnet/index.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - - -Introduction | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    A Counter on the Testnet

    -

    This tutorial installs a simple counter contract on the Casper Testnet. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to a local Casper Network, you can follow a similar tutorial and work with NCTL. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    -

    Here is how the tutorial is structured:

    - -

    Prerequisites

    -
      -
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. -
    3. You have installed the Casper client to send transactions to the chain.
    4. -
    5. You were able to set up and fund an account on the Casper Testnet. Make note of two critical pieces of information that you will need to complete this tutorial: -
        -
      • The location of your account’s secret_key.pem file
      • -
      • Your account hash identifier
      • -
      -
    6. -
    7. You selected a node whose RPC port will be receiving the transactions coming from your account.
    8. -
    -

    Video Tutorial

    -

    If you prefer a video walkthrough of this guide, you can check out this video.

    -
    - - \ No newline at end of file diff --git a/next/counter/index.html b/next/counter/index.html deleted file mode 100644 index b7a78d2fa..000000000 --- a/next/counter/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Introduction | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    A Counter on an NCTL Network

    -

    This tutorial installs a simple counter contract on a local Casper network with NCTL. The contract is straightforward and simply maintains a counter variable. If you want to learn to send transactions to the Testnet, you can follow a similar tutorial. Once you are familiar with this process, the next step would be to write more practical smart contracts.

    -

    Here is how the tutorial is structured:

    - -

    Prerequisites

    -
      -
    1. You have completed the Getting Started tutorial to set up your development environment, including tools like cmake (version 3.1.4+), cargo, and Rust.
    2. -
    3. You have completed the NCTL tutorial, which introduces you to the CLI tool to set up and control local Casper networks for development.
    4. -
    5. You have installed the Casper client to send transactions to the chain.
    6. -
    - - \ No newline at end of file diff --git a/next/design/index.html b/next/design/index.html deleted file mode 100644 index 48e97223b..000000000 --- a/next/design/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - -Design Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Design Overview

    TopicDescription
    Network DesignOverview of execution semantics, account permissions, URefs, block structure, tokens, and more
    Network CommunicationPeer-to-peer communication for Casper nodes
    Consensus in CasperIntroduction to Consensus in a Casper network
    Zug ConsensusAn overview of the Zug consensus used in Mainnet and Testnet
    Highway ConsensusBrief overview of the Highway consensus available as an alternative to Zug
    Validator RewardsOverview of how rewards are calculated and distributed
    Reading and Writing Data to Global StateStoring and reading data from the blockchain
    - - \ No newline at end of file diff --git a/next/developers/cli/execution-error-codes/index.html b/next/developers/cli/execution-error-codes/index.html deleted file mode 100644 index a5783c1a3..000000000 --- a/next/developers/cli/execution-error-codes/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -Execution Error Codes | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Execution Error Codes

    -

    This section covers smart contract execution error codes.

    -

    As mentioned in Writing Rust Contracts, smart contracts can exit with an error code defined by an ApiError. Descriptions of each variant are found here and include the following sub-types:

    - -

    An ApiError of one of these sub-types maps to an exit code with an offset defined by the sub-type. For example, an ApiError::User(2) maps to an exit code of 65538 (i.e. 65536 + 2). You can find a mapping from contract exit codes to ApiError variants here.

    - - \ No newline at end of file diff --git a/next/developers/cli/index.html b/next/developers/cli/index.html deleted file mode 100644 index ae40a1518..000000000 --- a/next/developers/cli/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - -Interacting with the Blockchain | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Using the Casper CLI Client

    -

    This section explains how to interact with a Casper network using the Casper command-line client written in Rust.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Transferring TokensTransferring tokens from one account to another using the Casper command-line client
    Delegating tokensDelegating tokens to a validator on a Casper network
    Undelegating Tokens with the Casper ClientUndelegating tokens from a validator on a Casper network
    Sending Deploys to a NetworkSending Deploys to a Casper network using the Rust CLI Client
    Installing Smart ContractsSteps to install a contract on a Casper network
    Verifying contracts using the Casper ClientHow to use Smart Contract Verification Service
    Querying Global StateHow to query global state after contract installation
    Calling Smart Contracts with the Rust ClientVarious ways to call a contract's entry-points
    Execution Error CodesError codes for smart contract execution
    - - \ No newline at end of file diff --git a/next/developers/cli/transfers/index.html b/next/developers/cli/transfers/index.html deleted file mode 100644 index f3741dea0..000000000 --- a/next/developers/cli/transfers/index.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - -Transferring Tokens | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Transferring Tokens with the Casper CLI Client

    -

    The following topics describe using the Casper command-line client to transfer tokens between purses on a Casper network. Depending on the account configuration, a direct transfer or a multiple-signature (multi-sig) transaction transfer can be utilized.

    -

    Transferring tokens using a direct transfer

    -

    Tokens can be transferred directly when the signing key has enough weight to approve the transaction. This is the most common scenario, applicable by default for accounts with a single primary key. To use a direct transfer, see Transferring Tokens Using Direct Transfer.

    -

    Transferring tokens using a multi-sig tranasction

    -

    Multi-sig transaction transfers are typically used when the account initiating the transfer has multiple associated keys that need to sign the transaction. To set up the account's associated keys, see the Two-Party Multi-Signature transactions workflow. To use a multi-sig transaction transfer, see Transferring Tokens Using a Multi-sig Account.

    -

    Verifying a transfer using the command-line client

    -

    To verify the status of a transfer, see Verifying a Transfer.

    - - \ No newline at end of file diff --git a/next/developers/cli/verifying-contracts/index.html b/next/developers/cli/verifying-contracts/index.html deleted file mode 100644 index 790a96d01..000000000 --- a/next/developers/cli/verifying-contracts/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - -Verifying Contracts | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Verifying Smart Contracts

    -

    This document describes actions needed for smart contract verification using the Casper CLI client.

    -

    Prerequisites

    -
      -
    • You have built and installed a contract
    • -
    -

    Verifying contracts using the Casper Client

    -

    You can use the Casper client's verify-contract command to have your contract verified. This command archives your contract's source code and sends it to the verification service. This service performs all the same operations on the provided source that a node does when installing a smart contract on the blockchain. Based on the input transaction hash, the resulting binary is then compared byte-by-byte against the contract fetched from the Casper blockchain. If they match, then the verification is a success.

    -
    casper-client verify-contract --verification-url-basepath <HOST:PORT> <TRANSACTION-HASH> <PATH>
    -
      -
    1. verification-url-basepath - The address of the verification service that will perform the operation; the current two options are https://staging.codeverifier.casper.network for Testnet and https://codeverifier.casper.network for Mainnet.
    2. -
    3. <TRANSACTION-HASH> - Unique transaction hash, which is part of the cryptographic security of blockchain technology. This is the output of the put-txn command if the transaction was a success.
    4. -
    5. <PATH> - Path to the smart contract's source code. If this argument is omitted, the current working directory will be used.
    6. -
    -

    The prerequisites for the source code are the same as when installing it on the blockchain:

    -
      -
    • -

      The source code must be a Rust project as described in The Cargo Book.

      -
    • -
    • -

      There has to be either rust-toolchain or rust-toolchain.toml file and its contents must define a valid Rust toolchain, as described in The rustup book.

      -
    • -
    • -

      The installed contract (WebAssembly binary) must be stripped of debugging symbols before submitting it to the Casper node. This can be achieved by specifying strip = "symbols" in the Rust project configuration or using wasm-strip from the wabt package.

      -
    • -
    -

    If the verification is successful, then users will be able to see that information on various websites integrated with the service, e.g., on https://staging.casperecosystem.io/check-verification-status/ for Testnet transactions and https://casperecosystem.io/check-verification-status/ for Mainnet transactions. This will also allow them to browse through the source code of your smart contract, adding a new layer of transparency and trust.

    - - \ No newline at end of file diff --git a/next/developers/dapps/dapp/index.html b/next/developers/dapps/dapp/index.html deleted file mode 100644 index ef877d634..000000000 --- a/next/developers/dapps/dapp/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -What is a dApp? | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    What is a dApp?

    -

    A decentralized application (dApp) is an application with some data on a blockchain or similar peer-to-peer network.

    -

    The degree that a dApp interacts with the blockchain can vary greatly depending on the needs of the application. Some dApps may use the blockchain simply to store data, with most of the logic taking place off-chain. Others may depend on logic stored on the blockchain, with only the bare minimum user interface stored outside of the blockchain itself.

    -

    How are Decentralized Applications Different?

    -

    A decentralized system consists of a group of interchangeable machines that can perform as a full system or distributed database. Additional machines strengthen the overall system by adding redundancy and computational power.

    -

    Any dApp will need access to a decentralized network, in one form or another. In a Casper network, this means connecting to a node. The decentralized aspect creates a situation where each node is fundamentally interchangeable for this purpose. If the connected node fails, the dApp can switch to a different node and continue operating without losing data or functionality.

    -

    Routine operations in a decentralized network may result in nodes coming on or offline. This node churn can result in downtime for a decentralized application if it relies on a single node. It is necessary to connect to multiple nodes simultaneously to ensure high uptime, especially if you are not operating your own node.

    -

    Interacting with a Decentralized Network

    -

    For a dApp to integrate with a Casper network, it must be able to send transactions via the JSON-RPC. Business logic specific to the dApp can then be executed on chain via the transaction. Sending a Transaction to a node will result in that node gossiping that transaction to other nodes, assuming that the transaction is valid and accepted. The transaction will then be enqueued for execution.

    -

    A transaction contains session code in the form of Wasm to be executed in the context of the sending account entity. Therefore, developers may use any programming language that can compile to Wasm when building a dApp for a Casper network. This session code may consist of Wasm to be executed once, or Wasm which will install contract code to be stored in global state. If the dApp requires periodic execution of the same Wasm, it is more efficient from both a gas and execution perspective to install the Wasm as a contract to be called later.

    -

    Sending a transaction is the only means by which a dApp can change global state. As gas costs operate on a per-byte basis, smart contracts will incur less gas costs over time when compared against executing the same session code repeatedly. A dApp may send a transaction simultaneously to each node it is connected to, but can only do so once per node, per transaction.

    -

    All associated changes to global state occur after successful execution of the transaction. In the case of a failed execution, the stack is unwound and any changes to global state as part of executing the transaction are reverted. However, as there is a penalty payment that must be incurred, there is a change in global state through reducing the balance of the sending account. To send a transaction, an account must hold a minimum balance greater than the network's penalty payment. This penalty payment can vary from network to network. On the public Casper Mainnet, the penalty payment is set to 2.5 CSPR.

    -

    Unlike other blockchain networks, a Casper network performs execution after consensus. This means observing the execution of the transaction is sufficient proof of finality for most cases. For a stronger finality requirement, you can observe the finality signatures for the block that includes the given transaction.

    -

    There is an inherent timing consideration when sending a transaction, from the point where it is sent to when it is executed. The Transaction Lifecycle results in a delay longer than would be expected from a centralized application. The transaction must be sent, accepted, gossiped, included in a finalized block and executed. This process varies from network to network. This delay should be taken into consideration when designing dApps for use with a Casper network, as the number of connected peers and the number of transactions currently being sent may cause it to increase.

    - - \ No newline at end of file diff --git a/next/developers/dapps/index.html b/next/developers/dapps/index.html deleted file mode 100644 index c8001c443..000000000 --- a/next/developers/dapps/index.html +++ /dev/null @@ -1,67 +0,0 @@ - - - - - -Overview of Casper dApps | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Overview of Casper dApps

    -

    The following topics are essential for developers building decentralized applications on a Casper network.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Introducing dAppsIntroducing dApps on a Casper network
    Prerequisites for Building dAppsRecommended setup for building dApps on Casper
    SDK Client LibrariesClient-side libraries providing ways to interact with a Casper network
    dApp Technology StackBuilding the front-end, backend, and on-chain logic of a dApp
    Front-end Template with ReactUse the Casper JS SDK with React to build a dApp frontend
    Signing TransactionsDetails about the signatures required for transactions
    Setting up a Local Network with NCTLLearn to set up a local test network
    Testing Smart Contracts with NCTLTest transactions locally before sending them to a Casper network
    Monitoring and Consuming EventsHow dApps can listen for emitted events using the Casper Sidecar and perform actions based on event data
    - - \ No newline at end of file diff --git a/next/developers/dapps/prerequisites/index.html b/next/developers/dapps/prerequisites/index.html deleted file mode 100644 index 7a55e65e8..000000000 --- a/next/developers/dapps/prerequisites/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Prerequisites | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Prerequisites

    -

    Before trying your hand at dApp development on a Casper network, there are a few things you should do first:

    -
      -
    1. -

      Set up your development environment.

      -
    2. -
    3. -

      Be sure you understand the language(s) you are developing in.

      -

      Before beginning with one or more of the SDKs, ensure that you are familiar with the underlying language itself. There are many guides and tutorials available online to help you.

      -

      The preferred stack for building on Casper is JavaScript using the Casper JS SDK, however there are many more SDKs available for a variety of different programming languages. Read about and examine the other available SDKs in the Introduction to SDKs.

      -
    4. -
    5. -

      Familiarize yourself with the fundamentals of Casper networks.

      -

      Casper networks are Proof-of-Stake smart contract blockchains written in Rust. Their architecture, from how they validates transactions to how they reach consensus, should be well understood before developing dApps that interact with them. Read up on Casper network design principles in the design section.

      -
    6. -
    7. -

      Read the documentation or source code of your chosen SDK.

      -

      Many of the Casper SDKs have documentation available to help you get a full grasp of their functions and methods. In some cases, documentation is written in the source files and rendered using a markup language. Check the repository of your preferred SDK(s) for links to documentation. There are also universal guides to teach you how to perform different functionalities using any of the available SDKs, see Client Library Usage.

      -
    8. -
    -

    Development Considerations

    -

    When developing a public dApp for a Casper network, it is important to keep security in mind and write your smart contract(s) and interface(s) with caution and care, especially if your dApp interacts with tokens of value.

    -

    To ensure the highest level of security, consider the following practices:

    -
      -
    1. Code review and auditing: Have your smart contracts and interfaces thoroughly reviewed and audited by experienced professionals. This will help identify any vulnerabilities, bugs, or potential exploits in your code.
    2. -
    3. Implement best practices: Adhere to industry best practices in smart contract and dApp development. This includes following established design patterns, using secure coding techniques, and staying updated on the latest vulnerabilities and attack vectors.
    4. -
    5. Testing and simulation: Conduct rigorous testing and simulation of your smart contracts and interfaces. This will help uncover any potential issues or weaknesses before deploying them on the mainnet.
    6. -
    7. Plan for upgrades and bug fixes: Design your smart contracts to take advantage of Casper's support for smart contract upgradability. By doing so, you can ensure that your dApp remains secure and adaptable as the Casper ecosystem evolves, enabling seamless integration of future upgrades and bug fixes.
    8. -
    9. Monitor and maintain: Regularly monitor your dApp's performance and security once it is deployed. This will help you quickly identify and address any potential threats or vulnerabilities.
    10. -
    11. Educate users: Provide clear documentation and guidance to your dApp users, helping them understand how to use your application securely and effectively.
    12. -
    -

    By taking these precautions and focusing on security throughout the development process, you can minimize risks and build a more robust and reliable dApp for the Casper Network.

    - - \ No newline at end of file diff --git a/next/developers/dapps/sdk/csharp-sdk/index.html b/next/developers/dapps/sdk/csharp-sdk/index.html deleted file mode 100644 index 252d3fa60..000000000 --- a/next/developers/dapps/sdk/csharp-sdk/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -.NET SDK | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    .NET SDK

    -

    The C# .NET SDK allows developers to interact with a Casper network using C#.

    -

    Documentation

    -

    Visit https://make-software.github.io/casper-net-sdk/ to find the SDK documentation, examples, and tutorials.

    -

    Get started

    -

    This example shows how to retrieve an account's main purse balance from a testnet node. Make sure you have .NET 5 or higher before continuing.

    -

    Open a terminal window and create a new console app:

    -
    dotnet new console -o GetAccountBalance
    cd GetAccountBalance
    -

    The Casper.Network.SDK for .NET is published on nuget.org as a NuGet package.

    -

    To add a reference to the SDK in your project, use the Package Manager in Visual Studio or the dotnet CLI tool.

    -

    Package Manager (Windows)

    -
    Install-Package Casper.Network.SDK
    -

    dotnet CLI Tool (Windows, Mac, and Linux)

    -
    dotnet add package Casper.Network.SDK
    -

    Now, replace the default code in Program.cs with this main program:

    -
    using System;
    using System.Threading.Tasks;
    using Casper.Network.SDK;
    using Casper.Network.SDK.JsonRpc;
    using Casper.Network.SDK.Types;

    namespace Casper.NET.SDK.Examples
    {
    public class GetAccountBalance
    {
    public static async Task Main(string[] args)
    {
    string nodeAddress = "http://testnet-node.make.services:7777";

    var hex = "0203914289b334f57366541099a52156b149436fdb0422b3c48fe4115d0578abf690";
    var publicKey = PublicKey.FromHexString(hex);

    try
    {
    var casperSdk = new NetCasperClient(nodeAddress);

    // Get the balance using the account public key
    //
    var rpcResponse = await casperSdk.GetAccountBalance(publicKey);
    Console.WriteLine("Public Key Balance: " + rpcResponse.Parse().BalanceValue);
    }
    catch (RpcClientException e)
    {
    Console.WriteLine("ERROR:\n" + e.RpcError.Message);
    }
    catch (Exception e)
    {
    Console.WriteLine(e);
    }
    }
    }
    }
    -

    Finally, run the example with:

    -
    dotnet run
    -

    The program will print the account's main purse balance retrieved from the testnet.

    -

    Visit https://make-software.github.io/casper-net-sdk/ to find other examples, tutorials, and complete documentation for this SDK.

    - - \ No newline at end of file diff --git a/next/developers/dapps/signing-a-transaction/index.html b/next/developers/dapps/signing-a-transaction/index.html deleted file mode 100644 index b526fcb65..000000000 --- a/next/developers/dapps/signing-a-transaction/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Signing Transactions | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Signing Transactions

    -

    When creating a Transaction to be executed on a Casper network, the account owner, or more accurately, enough authorized signers must sign the transaction using their account's cryptographic key-pair. This key-pair is a combination of the account's secret and public keys. The signatures attached to the transaction allow the network to verify that it should be executed.

    -

    When a signature is attached to a transaction, it is paired with the public key of the signer, and referred to as an Approval. Every valid transaction has at least one approval.

    -

    The signature creation process begins with the hashing of the payment and session of the transaction to create the BodyHash. The BodyHash becomes a component of the TransactionV1Header as outlined in the serialization standard. From there, the TransactionV1Header can be hashed to create the TransactionV1Hash. As outlined above, the TransactionV1Hash is then combined with the account's key-pair to create the transaction's signature.

    -

    As the TransactionV1Hash contains a hash of the transaction's body within, any variation to any aspect of the transaction or sending account's keys would render the TransactionV1Hash invalid.

    -

    Public Key Cryptography

    -

    Casper networks are compatible with both Ed25519 and Secp256k1 public key cryptography. When serialized, public keys and signatures are prefixed with a single byte, used as a tag to denote the applicable algorithm. Ed25519 public keys and signatures are prefixed with 1, whereas Secp256k1 are prefixed with 2.

    -

    Casper uses blake2b hashing within our serialization. However, these hashed values will be hashed once again when they are signed over. The type of hashing depends on the associated keypair algorithm as follows:

    -
      -
    • -

      Ed25519 signs over a SHA-512 digest.

      -
    • -
    • -

      Secp256k1 signs over a SHA-256 digest.

      -
    • -
    - - \ No newline at end of file diff --git a/next/developers/dapps/speculative-exec/index.html b/next/developers/dapps/speculative-exec/index.html deleted file mode 100644 index 5a1e19cfd..000000000 --- a/next/developers/dapps/speculative-exec/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - -Estimating Gas Costs with Speculative Execution | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Estimating Gas Costs with Speculative Execution

    -

    Version 1.5 of the Casper Node includes a new JSON RPC endpoint called speculative_exec. This endpoint allows developers to send a Deploy to a single node, which will execute the Deploy without committing the results to global state and, therefore, not incurring the associated costs. Observing the execution results of the Deploy gives a rough estimate of the potential cost for sending the Deploy without speculative execution.

    -

    In addition to the Deploy in question, speculative_exec also accepts a [block_identifier] for a specific block height or hash to speculate on. If you do not provide a block identifier, the Deploy will be executed on the most recent block.

    -

    Sending a Speculative Execution Deploy using the Rust CLI Casper Client

    -

    The Rust CLI Casper client includes a speculative-exec option that will flag a normal put-deploy for execution but not commitment to global state. The following command shows an example:

    -

    casper client put-deploy /
    --node-address <HOST:PORT> /
    --chain-name <CHAIN_NAME> /
    --secret-key <PATH> /
    --session-path <PATH> /
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES>
    --speculative-exec <BLOCK HEIGHT OR HASH>

    -

    You should receive execution_results that show a cost.

    -

    {
    "jsonrpc": "2.0",
    "id": -4571113357017152230,
    "result": {
    "api_version": "1.0.0",
    "block_hash": "6ca035b08de092e7f5e8fff771b880c5b4d7463a8f7a9b108888aaad958e5b0f",
    "execution_result": {
    "Success": {
    "effect": {
    <Deploy effects removed for conciseness.>
    },
    "transfers": [],
    "cost": "87300473670"
    }
    }
    }
    }

    -
    note

    Cost estimates acquired through speculative_exec may vary from the cost of sending the same Deploy to a Casper network. Speculative execution is a tool to help narrow down the potential cost of sending a Deploy, but many factors can cause the actual cost to vary.

    - - \ No newline at end of file diff --git a/next/developers/dapps/technology-stack/index.html b/next/developers/dapps/technology-stack/index.html deleted file mode 100644 index 60385dda4..000000000 --- a/next/developers/dapps/technology-stack/index.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - -dApp Technology Stack | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem';

    -

    dApp Technology Stack

    -

    There are 3 layers to building a decentralized application that interacts with a Casper network: Front-end, backend, and on-chain logic. This document outlines lists the requirements for each.

    -

    Front-End

    -

    The front-end, or client-side of a dApp consists of the interface that the user uses to interact with smart contracts on a Casper Network. This interface usually comes in the form of a website/webpage, mobile device application or computer program, but could also include APIs with endpoints that may be called or queried.

    -

    You will need to choose a Casper-compatible SDK for the language you are using to call and query smart contracts on a Casper network. Casper's SDKs have methods available for constructing transactions and gathering global state data. While these interactions can be prepared on the front-end, they must be sent to the backend of your application before being sent off to a network, so as to fulfill CORS requirements.

    -

    Signing Transactions

    -

    The signing of transactions will, in many cases, need to be performed by the user on the front-end, for which you have a couple options:

    -
      -
    1. -

      The Casper Wallet

      -

      Use the Casper Wallet to sign transactions for a Casper network. Transaction objects are first converted to JSON, then sent to the Wallet to be signed, then must be sent to the backend and forwarded to a node.

      -
      caution

      The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

      -
    2. -
    3. -

      Third-party signers

      -

      Third-party signers may be used as well. A JSON representation of the unsigned transaction should be forwarded to the third-party signer and accept a callback containing the signed transaction object.

      -
    4. -
    -

    Querying Global State

    -

    To execute a query of global state, such as retrieving smart contract data or getting current chain information, the preparation may be done on the front-end, but the query to a node must ultimately originate from your application's backend. This preparatory stage comes only in the form of defining a contract hash and the path which you'd like to query data. Alternately, for chain information, you must define the endpoint you'd like to query.

    -

    Backend

    -

    The backend of a dApp consists of the server-side code that connects the blockchain to the front-end interface and deals with data-parsing and application-layer communication. A backend server is necessary for building dApps on Casper as Casper's nodes expect CORS headers from a specified origin on the HTTP requests they receive. Backend servers are helpful for other reasons too, such as queueing requests and analyzing the traffic moving between your dApp and the blockchain.

    -

    As the backend server of a dApp is the software communicating with Casper nodes (the blockchain), it needs to receive information such as which node and endpoint to connect to.

    - - -
    const client = new CasperClient("http://NODE_ADDRESS:7777/rpc");
    -
    - -
    client = NodeClient(NodeConnection(host = "NODE_ADDRESS", port_rpc = 7777))
    -
    -
    -
    tip

    You can find online peers for Mainnet at cspr.live or testnet at testnet.cspr.live

    -

    There are two main types of blockchain interactions that will originate from the front-end: transactions and queries. In the case of a dApp, both of these will pass through the back-end.

    -

    Blockchain interaction for state queries is handled solely on the backend. On the front-end, a user simply chooses the path at which they want to query data. This path is sent to the backend where the server will perform the state query and send the result back to the front-end.

    -

    In the case of a user-signed transaction originating from the dApp's front-end, the backend will need to accept this transaction and forward it to a Casper network. This is often accomplished by opening a POST endpoint that accepts JSON formatted transactions and forwards them along.

    -

    Blockchain

    -

    The last stop for a transaction or query is the blockchain itself. Like the majority of smart contract blockchains, Casper networks maintain a forever-growing, immutable ledger that can be read and written to. When building a dApp for a Casper network, user interactions in the form of queries and transactions originate from the front-end, are forwarded to the backend, and are then sent to a Casper node for interaction with the blockchain. You can communicate with Casper nodes using JSON RPC calls, and have a variety of open transactional, informational, and Proof-of-Stake endpoints. By utilizing an SDK on the backend, you won't need to construct these JSON RPC calls yourself, they'll be done for you within the available methods.

    -

    More than likely, you will want your dApp to perform personalized functions, store custom data, and perhaps even store or transact upon tokens with monetary value. All of these behaviors can be implemented by writing custom smart contracts for your application. Smart contracts on a Casper network can perform any function that a classical computer can. Casper's smart contracts are executed as WebAssembly binaries, and can be written in any language that compiles to WebAssembly. Currently, most developers choose to write their smart contracts in Rust for its reliability and ease-of-use. Additionally, Casper's smart contract documentation is written for Rust.

    -

    To learn how to write smart contracts for your dApp, read the smart contract documentation.

    - - \ No newline at end of file diff --git a/next/developers/essential-crates/index.html b/next/developers/essential-crates/index.html deleted file mode 100644 index 38473922e..000000000 --- a/next/developers/essential-crates/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - -Essential Rust Crates | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Essential Rust Crates

    -

    Several Rust crates are available on crates.io to support smart contract development with Rust. A crate is a compilation unit that can be compiled into a binary or a library. The corresponding documentation is published on docs.rs. The most important crates are listed below.

    -

    casper-types

    -

    Types shared by many Casper crates:

    - -

    casper-contract

    -

    A library for developing Casper smart contracts:

    - -

    casper-engine-test-support

    -

    The Casper test support library:

    - -

    casper-node

    -

    The component for running a node on a Casper network:

    - -

    casper-client

    -

    A client library for interacting with a Casper network:

    - -

    casper-event-standard

    -

    A Rust library that provides a simple and standardized way for Casper contracts to emit events:

    - -

    casper-hashing

    -

    A library providing hashing functionality including Merkle Proof utilities:

    - -

    casper-wasm-utils

    -

    Command-line utilities and corresponding Rust API for producing pwasm-compatible executables:

    - -

    cargo-casper

    -

    A command line tool for creating a Wasm smart contract and tests:

    - -

    Other Libraries

    -

    The Open-Source Software page provides other community-curated tools and libraries.

    - - \ No newline at end of file diff --git a/next/developers/index.html b/next/developers/index.html deleted file mode 100644 index 76d0cdaa8..000000000 --- a/next/developers/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Developers Overview

    -

    This section supports developers getting started with the Casper blockchain by writing dApps or smart contracts in Rust. Developers can install a local development environment with a runtime and a test framework. They can also create and test contracts with the libraries provided or use these libraries to build decentralized applications. Prior knowledge of Unix-based operating systems, like GNU/Linux, and programming knowledge with Rust, AssemblyScript, JavaScript, or Python are highly recommended.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Development PrerequisitesSetup needed for various workflows
    Essential Casper CratesAvailable Casper crates and the corresponding documentation
    Writing On-Chain CodeWriting contracts in Rust and Wasm for a Casper network
    Casper JSON-RPC APIEndpoints for developers wishing to interact directly with a Casper node's JSON-RPC API
    Building dAppsUseful information for dApp developers
    Interacting with the Blockchain Using CLIUsing a Rust command-line client to install and call contracts; transfer, delegate, and undelegate tokens.
    -

    The Ecosystem Open-Source Software may provide other helpful examples.

    -

    The motivation for the Casper Network roadmap is inspired by community feedback and recommendations. We look forward to building a decentralized future together.

    - - \ No newline at end of file diff --git a/next/developers/json-rpc/errors/index.html b/next/developers/json-rpc/errors/index.html deleted file mode 100644 index 7e84775f5..000000000 --- a/next/developers/json-rpc/errors/index.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - -Casper JSON-RPC Error Codes | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Casper JSON-RPC Error Codes

    -

    The following document expands on custom error codes provided by casper-json-rpc crate.

    -

    Error Codes

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    CodeErrorDescription
    -1NoSuchDeployThe requested Deploy was not found.
    -2NoSuchBlockThe requested Block was not found.
    -3FailedToParseQueryKeyParsing the Key from a query failed.
    -4QueryFailedThe query failed to find a result.
    -5QueryFailedToExecuteExecuting the query failed.
    -6FailedToParseGetBalanceURefParsing the URef while getting a balance failed.
    -7FailedToGetBalanceFailed to get the requested balance.
    -8GetBalanceFailedToExecuteExecuting the query to retrieve the balance failed.
    -9InvalidDeployThe given Deploy cannot be executed as it is invalid.
    -10NoSuchAccountThe given account was not found.
    -11FailedToGetDictionaryURefFailed to get the requested dictionary URef.
    -12FailedToGetTrieFailed to get the requested dictionary trie.
    -13NoSuchStateRootThe requested state root hash was not found.
    -32600InvalidRequestThe JSON sent is not a valid Request object.
    -32601MethodNotFoundThe method does not exist or is not available.
    -32602InvalidParamsInvalid method parameter(s)
    -32603InternalErrorInternal JSON-RPC error.
    -32700ParseErrorInvalid JSON was received by the server.
    -

    Invalid Params

    -

    The casper-json-rpc no longer ignores invalid params fields. Params fields to be omitted should be an empty Array '[]', an empty Object '{}' or absent.

    -

    Failing to adhere to this will result in an InvalidParams error.

    - - \ No newline at end of file diff --git a/next/developers/json-rpc/guidance/index.html b/next/developers/json-rpc/guidance/index.html deleted file mode 100644 index 499cdf201..000000000 --- a/next/developers/json-rpc/guidance/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -Guidance for JSON-RPC SDK Compliance | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Guidance for JSON-RPC SDK Compliance

    -

    A compliant Casper JSON-RPC SDK implementation must support all the endpoints and relevant types within the specification. The specification allows everything ranging from a minimal viable implementation to a full implementation, and a given SDK should cite which level of implementation they claim to be compliant with. For example, an SDK claiming to be an informational SDK must have implemented all entry points and relevant types described in the informational JSON-RPC methods page.

    -

    A Casper JSON-RPC SDK claiming to be complete is expected to implement all endpoints and all types defined in the serialization standard.

    -

    Consistency

    -

    A Casper JSON-RPC SDK must be consistent in terminology, language, and functionality relative to the Casper platform's architecture and design. Use actual terms such as Account and AddressableEntity, not similar terms such as wallet.

    -

    Care should be taken to maintain a universal language and not obscure the domain concepts of the Casper platform, which could confuse users of the SDK. The goal is to not make it difficult for users of an SDK to understand the documentation of the Casper platform. Further, they should be able to communicate effectively with technical support personnel who understand the terminology of the Casper platform and not the variant terminology of an SDK.

    -

    Advanced Functionality

    -

    SDK developers are allowed and encouraged to add convenience methods, supporting utilities, domain specific or macro support and extended functionality using the available endpoints and possible combinations.

    -

    However, it is critical that SDK developers avoid misleading or improperly characterizing the purpose and scope of the available endpoints. Custom functionality should improve on the basic building blocks of the Casper Platform, offering added convenience.

    -

    For example, some languages have strong idiomatic opinions and programmers using those languages are comfortable with or even expect SDKs in that language to follow those idioms. This is acceptable, as long as they do not obfuscate underlying terminology or semantics of the Casper platform.

    - - \ No newline at end of file diff --git a/next/developers/json-rpc/index.html b/next/developers/json-rpc/index.html deleted file mode 100644 index a4eaee7cf..000000000 --- a/next/developers/json-rpc/index.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Interacting with the Casper JSON-RPC API

    -

    Casper uses a custom JSON-RPC implementation called casper-json-rpc that complies with the JSON-RPC 2.0 specification.

    -

    The Casper Sidecar service offers a JSON-RPC API server for clients to interact with a Casper node. The Sidecar acts as a JSON bridge between subscribers and a Casper node's binary port, producing faster responses and reducing the load placed on the node. For more details on how the JSON-RPC API works, see the JSON-RPC README in the Sidecar repository. The Sidecar usually runs on the same machine as the node process, and you need to find the port on which to access the Sidecar.

    -

    You can find the latest RPC schema in the Sidecar's GitHub repository.

    -

    The Casper client subcommand list-rpcs also provides all currently supported RPCs. Here is an example of running the Casper client to list RPCs:

    -
    casper-client list-rpcs --node-address <HOST:PORT>
    -

    You may use Postman or write code to interact with the Casper JSON-RPC API, which is fully compatible with the JSON-RPC 2.0 Specification.

    -

    Table of Contents

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PageDescription
    Guidance for JSON-RPC SDK ComplianceRequirements for a compliant Casper SDK
    Required JSON-RPC Methods for Minimal ComplianceMethods required for a minimally compliant Casper SDK
    Transactional JSON-RPC MethodMethods allowing interaction with a Casper network
    Informational JSON-RPC MethodsMethods returning information about the network from a Casper node
    Proof-of-Stake JSON-RPC MethodsMethods pertaining to Proof-of-Stake functionality on a Casper network
    TypesInformation on types used within JSON-RPC methods
    CL TypesInformation related to CL Types
    - - \ No newline at end of file diff --git a/next/developers/json-rpc/minimal-compliance/index.html b/next/developers/json-rpc/minimal-compliance/index.html deleted file mode 100644 index 6ec388f82..000000000 --- a/next/developers/json-rpc/minimal-compliance/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - -Required Methods for Minimal Compliance | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Required Methods for Minimal Compliance

    -

    The methods included in this document represent the most basic, fundamental endpoints for a viable and compliant Casper SDK. They allow the user to retrieve the information necessary to interact with a Casper network, as well as the means to interact.

    -
      -
    • -

      chain_get_block - This method returns the JSON representation of a Block from the network. The ongoing validity of the chain depends on block verification, which includes both a record of deploys and transfers.

      -
    • -
    • -

      info_get_deploy - This method allows retrieval of a Deploy from a Casper network. Without this method, users will be unable to verify any subsequent information relating to a sent Deploy.

      -
    • -
    • -

      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 - The state root hash is one of the several global state identifiers used to query the network state after sending deploys.

      -
    • -
    • -

      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 - 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 - This method returns an item from a Dictionary. Dictionaries represent a more efficient means of tracking large amounts of state.

      -
    • -
    • -

      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 methods state_get_balance and state_get_item should not be used.

    -

    In addition to these methods, a minimally compliant Casper SDK must account for the types 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.

    - - \ No newline at end of file diff --git a/next/developers/json-rpc/types_cl/index.html b/next/developers/json-rpc/types_cl/index.html deleted file mode 100644 index ca1f6a934..000000000 --- a/next/developers/json-rpc/types_cl/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - -CLType | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    CLType

    -

    Casper types, i.e. types which can be stored and manipulated by smart contracts. Provides a description of the underlying data type of a CLValue.

    -
      -
    • Bool Primitive
    • -
    • I32 Primitive
    • -
    • I64 Primitive
    • -
    • U8 Primitive
    • -
    • U32 Primitive
    • -
    • U64 Primitive
    • -
    • U128 Large unsigned integer type
    • -
    • U256 Large unsigned integer type
    • -
    • U512 Large unsigned integer type
    • -
    • Unit Primitive
    • -
    • String Primitive
    • -
    • Key System type
    • -
    • URef System type
    • -
    • PublicKey System type
    • -
    • Option Option of a CLType
    • -
    • List Variable-length list of a single CLType (comparable to a Vec)
    • -
    • ByteArray Fixed-length list of a single CLType (comparable to a Rust array)
    • -
    • Result Result with Ok and Err variants of CLType's
    • -
    • Map Map with keys of a single CLType and values of a single CLType
    • -
    • Tuple1 1-ary tuple of a CLType
    • -
    • Tuple2 2-ary tuple of CLTypes
    • -
    • Tuple3 3-ary tuple of CLTypes
    • -
    • Any Unspecified type
    • -
    -

    CLValue

    -

    A Casper value, i.e. a value which can be stored and manipulated by smart contracts. It holds the underlying data as a type-erased, serialized Vec<u8> and also holds the CLType of the underlying data as a separate member. The parsed field, representing the original value, is a convenience only available when a CLValue is encoded to JSON, and can always be set to null if preferred.

    -
      -
    • -

      bytes A Casper serialized representation of the underlying value. For more information, reference the Serialization Standard.

      -
    • -
    • -

      cl_type

      -
    • -
    - - \ No newline at end of file diff --git a/next/developers/writing-onchain-code/calling-contracts/index.html b/next/developers/writing-onchain-code/calling-contracts/index.html deleted file mode 100644 index 7334bfd19..000000000 --- a/next/developers/writing-onchain-code/calling-contracts/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - -Calling Contracts | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Calling Contracts

    -

    Calling a contract on a Casper network requires the use of a transaction. When using the Casper Rust client, JavaScript SDK, or any other client, the intermediary client crafts the transaction for you, using the arguments you provide. This document outlines the various transaction variants through which you can execute Wasm or invoke the execution of on-chain Wasm.

    -

    Using Legacy Deploy Variants

    -

    ModuleBytes

    -

    ModuleBytes is a deploy variant that allows you to pass opaque Wasm bytes to a network. This variant is used to install a contract on the chain or execute Wasm.

    -

    However, you can also use ModuleBytes to deploy session code that calls a contract.

    -

    Further information on the structure of ModuleBytes can be found in here.

    -

    StoredContractByHash

    -

    StoredContractByHash is a deploy variant that invokes on-chain Wasm by specifying the contract hash and an entry point within the contract. When you don't need to send additional Wasm, you can use this deploy variant to invoke on-chain Wasm. It accepts any runtime arguments necessary for the entry point in question.

    -

    While there is no Wasm associated with this variant, it is still a deploy sent to a node that invokes an installed contract.

    -

    Further information on the structure of StoredContractByHash can be found here.

    -

    StoredContractByName

    -

    StoredContractByName is similar to StoredContractByHash, with the main difference being the reference used to invoke on-chain Wasm. Where StoredContractByHash requires the contract hash, StoredContractByName uses a string stored as a NamedKey in the caller's account.

    -

    This allows the caller to more easily reference a contract stored on-chain for later use but requires pre-planning to store the name within their account's NamedKeys.

    -

    StoredVersionedContractByHash

    -

    StoredVersionedContractByHash is a deploy variant that invokes on-chain Wasm based on the contract package hash rather than the contract hash directly. This variant allows the caller to specify a version within the contract package, but if a specific version is not supplied, it will use the most recent version of the contract within the package.

    -

    This makes StoredVersionedContractByHash more stable than StoredContractByHash, as any caller will be directed to the most recent version of the internal contract without needing to specify the hash of that specific contract. Callers that regularly interact with a contract that they know will be upgraded can use this variant to ensure they are always using the most up-to-date version.

    -

    DApp developers that use contracts developed by other parties can use StoredVersionedContractByHash to avoid interruptions from contract version changes.

    -

    Further information on the structure of StoredVersionedContractByHash can be found here.

    -

    StoredVersionedContractByName

    -

    StoredVersionedContractByName combines the functionality of StoredContractByName and StoredVersionedContractByHash. It allows a developer to store a reference string as a NamedKey within their account context that references a contract by its contract package hash.

    -

    Further information on the structure of StoredVersionedContractByName can be found here.

    -

    Transfer

    -

    Native Transfers are Wasmless transfers on a Casper network. This is how most transfers take place, albeit through a system like the Rust client that crafts the associated deploy and sends it to the network.

    -

    Further information on the structure of a native Transfer can be found here.

    - - \ No newline at end of file diff --git a/next/developers/writing-onchain-code/contract-vs-session/index.html b/next/developers/writing-onchain-code/contract-vs-session/index.html deleted file mode 100644 index 8c9812ecc..000000000 --- a/next/developers/writing-onchain-code/contract-vs-session/index.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - -Contracts and Session Code | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Contracts and Session Code

    -

    What is Session Code?

    -

    Session code is the simplest logic one can execute on a Casper network. It is essential because it is often used to trigger contract logic stored on the chain. Session code requires only one entry point, the call function, and it runs within the context of the account executing the session code. As a result, the session code runs with the account's permissions, such as having access to the account's main purse. For example, the session code could transfer tokens from the account's main purse.

    -

    The best use of session code is when the situation calls for stateless execution, and very little or no internal data needs to be tracked. Session code is required when interacting and accepting values returned across the Wasm boundary.

    -

    Comparing Session and Contract Code

    -

    The following table summarizes the key differences between session code and contract code on a Casper network.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Session CodeContract Code
    Session code always executes in the context of the account that signed the transaction containing the session code.A smart contract, which is stored on-chain logic, executes within its own context.
    Session code has only one entry point, call, which can be used to interact with the session code.A smart contract can have multiple entry points that can be invoked.
    The call entry point initiates any action the session code takes.Any action undertaken by a contract must initiate through an outside call, usually via session code.
    When a put_key call is made within the body of the session code, the key is added to the account's named keys.When a put_key call is made within the smart contract's context, the contract's record is modified to have a new named_key entry.
    For more information on how to write session code, see Writing Session Code.For more information on writing contracts, see Writing a Basic Smart Contract in Rust.
    -

    The following image depicts the comparison presented in the table.

    -

    Comparing Session and Contract Code

    -

    What's Next?

    -
    - - \ No newline at end of file diff --git a/next/developers/writing-onchain-code/upgrading-contracts/index.html b/next/developers/writing-onchain-code/upgrading-contracts/index.html deleted file mode 100644 index d2dd6c54c..000000000 --- a/next/developers/writing-onchain-code/upgrading-contracts/index.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - -Upgrading and Maintaining Smart Contracts | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Upgrading and Maintaining Smart Contracts

    -

    Our smart contract packaging tools enable you to:

    -
      -
    • Upgrade your contracts and specify how the state of the contract is managed
    • -
    • Specify whether a contract is upgradable or immutable
    • -
    • 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. If you find that you need to use a disabled contract version, you may also re-enable it.

    -

    Package Representation

    -

    The contract package is like a container for different contract versions, with functionality that can differ slightly or significantly among versions. The contract package is created when you install the contract on the blockchain.

    -

    Videos and Tutorials

    -

    To learn more about versioning contracts, consult the following video, which builds upon the previous topics and videos in the Writing On-Chain Code documentation.

    -

    - -

    -

    Or, for a different perspective, consult the Smart Contract Upgrade Tutorial.

    -

    Maintaining a Contract

    -

    The contract maintenance process is generally covered through the contract upgrade process.

    -

    Only major version changes in the Casper node software would require specific contract maintenance since a node version has a one-to-one mapping with the contract version. Otherwise, minor contract version changes can be addressed through the contract upgrade process. At the moment, we are not anticipating major contract changes in the Casper Mainnet. Therefore, the contract upgrade process can cater to any minor contract maintenance.

    -

    On instances like new node version releases, type upgrades, and bug fixes, we advise you to adhere to the same contract upgrade process.

    - - \ No newline at end of file diff --git a/next/economics/index.html b/next/economics/index.html deleted file mode 100644 index 186aef443..000000000 --- a/next/economics/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Overview of Casper Economics

    -

    Casper's economic activity can be conceptualized as taking place on four distinct layers: consensus, runtime, ecosystem, and the macroeconomy. Each layer, consensus and up, provides a foundation for the activity taking place on the next layer. A trust-less platform requires proper incentives for participants operating each layer to ensure they work together to unlock the platform's value.

    -

    This online documentation section is intended only to familiarize the user with the Casper core economics features rather than describe their precise implementation and user interface. Some of the features may not be currently active.

    -

    Consensus

    -

    The consensus layer of the Casper Mainnet runs the Zug consensus protocol. The distinguishing characteristics of this protocol are its safety and liveness guarantees, speed, simplicity, and distributed nature. Blocks in the canonical history cannot be reverted (safety), and new blocks continue to be added to this history indefinitely (liveness). The safety and liveness guarantees require that honest validators comprise at least 67% of total validator weight. This required behavior must be incentivized for the platform to remain secure and live. Read the paper for more details: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

    -

    When discussing consensus, we default to considering it "one era at a time" unless expressly stated otherwise. Recall that each era is a separate instance of the protocol.

    -

    Agents (consensus layer)

    -

    Validators are responsible for maintaining platform security by building an ever-growing chain of finalized blocks and backing this chain's security with their stakes. Their importance (often referred to as "weight") to protocol operation and security is, in fact, equal to their stake, including both their own and delegated tokens.

    -

    Delegators are users who participate in the platform's security by delegating their tokens to validators, which adds to their weight and collecting a part of the rewards proportional to their delegations, net of a cut ("delegation rate") that is collected by the validator.

    -

    Incentives (consensus layer)

    -

    The auction determines the composition of the validator set for each protocol era. It is a "first-price" (winning bids become stakes) auction with a fixed number of spots chosen to balance security with performance (generally, the platform will run slower with more validators). Because rewards are proportional to the stake, we expect this competitive mechanism to provide a powerful impetus for staking as many tokens as possible.

    -

    Rewards (per era) are issued to validators who perform at their nominal pace in such a way as to make timely progress on block finalization. These rewards are shared with delegators proportionally to their contributions, net of a cut taken by the validator.

    -

    Evictions deactivate validators who fail to participate in an era, deactivating their bid and suspending their participation until they signal readiness to resume participation by invoking a particular entry point in the auction contract.

    -

    Runtime

    -

    The runtime layer encompasses the installation and execution of smart contracts and other activities that alter the network's global state. This suggests potential markets for finite platform resources, such as markets for computing time and storage. Such markets could ensure that resources are allocated to their highest-value uses. Currently, however, we limit ourselves to metering computing time, measured as gas. Gas can be conceptualized as the relative time use of different Wasm operations and host-side functions. The use of storage is also presently assigned a gas cost.

    -

    The Mainnet transaction selection mechanism is based on FIFO.

    -

    We expect to continue to work on runtime resource markets.

    -

    Agents (runtime layer)

    -

    Validators again play a vital role in this layer since protocol operation includes the construction and validation of new blocks, which consist of transactions that change the global state, which the validators also maintain.

    -

    Users execute session and contract code using the platform's computational resources

    -

    Incentives (runtime layer)

    -

    The Casper node software can be configured to support various fee, refund, and cost-handling strategies. The Condor release on Mainnet has enabled a fee elimination model by default, setting the no_fee,no_refund, and fixed pricing configurations in the network's chainspec.

    -

    The no_fee mode means the token is put on hold instead of being taken from the payer. The hold interval is configured in the chainspec. The hold release mechanism is based on the "accrued" or "amortized" settings in the chainspec. Accrued holds are released after a certain amount of time has passed. Amortized holds are released using a linear schedule over a specified period.

    -

    The no_refund mode means no refund is handled when fees are eliminated.

    -

    Fixed pricing means the gas costs are determined using a cost table, and transactions are put in the appropriate lanes for execution. You can find more details about lanes here.

    -

    When fees are eliminated, the block proposer receives validator credits instead of transaction fees. These credits contribute to the validator's total weight, determining their chances of winning a slot in the next era. Validators get rewards for proposing a block and creating and publishing finality signatures. In essence, gas/balance holds ensure that the network still compensates validators for their computations.

    -

    The fee elimination model is different than the refund model introduced on Mainnet with release 1.5.6 and has replaced the refund behavior. Since all these behaviors are configurable, private networks can set their fee, refund, and pricing strategies.

    -

    Ecosystem

    -

    The ecosystem layer encompasses dApp design and operation. Casper Labs maintains multiple partnerships with prospective dApp developers, and we anticipate devoting significant resources to research the economics of prospective dApps.

    -

    Macroeconomy

    -

    Casper's macroeconomics refers to the activity in the cryptocurrency markets, where CSPR can be treated as one crypto-asset among many rather than a computational platform. Our token economics differ from those of "digital gold" tokens like Bitcoin, which is designed to be scarce. Our tokens are minted on a fixed starting basis, accounted for by tokens distributed to genesis validators, employees, and community members, and held for future distributions. The total supply of tokens grows at a fixed annual percentage rate on this basis.

    -

    The inflationary nature of our macroeconomics has two significant advantages over enforced scarcity. Inflation incentivizes token holders to stake or delegate their tokens, which we explicitly support with our delegation feature. Additionally, because Casper is a general-purpose computing platform, it is essential to supply tokens to support actual economic activity and discourage hoarding tokens in expectation of speculative gain.

    - - \ No newline at end of file diff --git a/next/glossary/index.html b/next/glossary/index.html deleted file mode 100644 index 1304677fb..000000000 --- a/next/glossary/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Glossary | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Glossary

    -

    These definitions are correct in the context of the Casper Labs. They may (and probably will) have slightly different semantics in other contexts, including other blockchain contexts.

    -
    -

    A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

    -
    - - \ No newline at end of file diff --git a/next/index.html b/next/index.html deleted file mode 100644 index ccc19eeeb..000000000 --- a/next/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - -What is Casper? | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    What is Casper?

    What is Casper?

    -

    Casper is a Turing-complete smart-contracting platform, backed by a Proof-of-Stake (PoS) consensus algorithm and WebAssembly (Wasm). The network is a permissionless, decentralized, public blockchain.

    -

    The network's consensus protocol is called Zug, and it has several benefits over classic Byzantine Fault Tolerant (BFT) consensus protocols. First, Zug allows networks to reach higher thresholds of finality, meaning that every block gets finalized within seconds, as fast as the network connections allow. Second, the protocol achieves flexibility by expressing block finality in ways not possible in BFT models. This protocol is built on the following research: From Weakly-terminating Binary Agreement and Reliable Broadcast to Atomic Broadcast.

    -

    Additionally, the Casper Network is optimized for enterprise and developer adoption. While leveraging blockchain technology, the network seeks to accelerate business operations via unique features like predictable network fees, upgradeable contracts, on-chain governance, privacy flexibility, and developer-friendly languages. Casper's core features and strengths enable developers and enterprises to reap the benefits of blockchain technology.

    -

    Casper also solves the scalability trilemma. Notably, the network is optimized for security, decentralization, and high throughput. All this is achieved while evolving to provide leading solutions for open-source projects and enterprises.

    -

    How does Casper work?

    -

    Casper relies on a group of validators to verify transactions and uphold the network. Unlike Proof-of-Work networks, which need to centralize validators for economies of scale, Casper allows for the geographical decentralization of validators. Casper validators verify transactions based on staked tokens and receive CSPR rewards for participating in the PoS consensus mechanism. CSPR is the native token on the Casper Network.

    -

    To understand the design further, read this article.

    -

    Disclaimer

    -

    Read the Legal Disclaimer regarding this CasperLabs Tech Spec (this "Whitepaper").

    - - \ No newline at end of file diff --git a/next/operators/becoming-a-validator/inactive-vs-faulty/index.html b/next/operators/becoming-a-validator/inactive-vs-faulty/index.html deleted file mode 100644 index 7216da8f3..000000000 --- a/next/operators/becoming-a-validator/inactive-vs-faulty/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Inactive and Faulty Nodes | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Inactive vs. Faulty Validator Nodes

    -

    This page describes the differences between a validator node being considered inactive or faulty.

    -

    In the last block of each era N, the consensus algorithm checks whether there are any messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as inactive in that block.

    -

    Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as faulty in that block. Usually, that means:

    -
      -
    • If you got marked as inactive, your node probably crashed or was offline for the duration of one whole era, i.e., at least from when the era began until the era's last block was proposed.
    • -
    • If you got marked as faulty, you were probably running two nodes with the same validator key, or you restarted a node during the era and deleted its unit file.
    • -
    -

    The auction contract is run when the block gets executed, as always at the end of the era. But if you were faulty or inactive, you are now evicted and don't participate in the auction anymore. You also don't receive any rewards for era N. The auction determines the validator set for the era after the next (because auction_delay is set to 1 on mainnet), i.e., for era N + 2. That means you will still be a validator (with a weight proportional to your stake) in the next era, N + 1, but after that, you will not be a validator anymore, and your slot will be given to the next highest bidder.

    -

    And even in the next era, N + 1:

    -
      -
    • If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era N + 1, it will get evicted for being offline in era N.
    • -
    • If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards.
    • -
    -

    In both cases, you remain evicted until you reactivate your bid, as described here.

    - - \ No newline at end of file diff --git a/next/operators/becoming-a-validator/index.html b/next/operators/becoming-a-validator/index.html deleted file mode 100644 index d745df585..000000000 --- a/next/operators/becoming-a-validator/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Becoming a Validator | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Becoming a Validator

    -

    After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Bonding as a ValidatorA guide about the bonding process and submitting a bid
    Unbonding as a ValidatorThe process to withdraw a bid and unbonding
    Recovering from Validator EvictionSteps a validator needs to take if it is evicted from the validator set
    Inactive vs. Faulty NodesThe differences between inactive and faulty nodes
    Change bid public keyThe differences between inactive and faulty nodes
    - - \ No newline at end of file diff --git a/next/operators/index.html b/next/operators/index.html deleted file mode 100644 index 44adeb890..000000000 --- a/next/operators/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Operators Overview

    -

    Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.

    -

    Prior knowledge of Unix-based operating systems and proficiency with systemd and bash scripting are recommended. If you are unfamiliar with systemd, the Arch Linux page on systemd is a good introduction.

    -

    Operators should know the hardware requirements before running a node.

    -

    Also, the network requirements specify how to open ports and modify the network firewall to which the node is connected. This step is necessary to allow incoming connections, enabling communication among nodes.

    -

    Review the node's configuration first. Then, you can follow the node installation instructions.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Node SetupHow to set up a Casper node
    Becoming a ValidatorHow to join a network and become a validator
    Private Network SetupHow to set up a private Casper network
    MaintenanceTopics related to node maintenance
    - - \ No newline at end of file diff --git a/next/operators/maintenance/index.html b/next/operators/maintenance/index.html deleted file mode 100644 index 61e14ad37..000000000 --- a/next/operators/maintenance/index.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - -Node Maintenance | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Node Maintenance

    -

    This section covers maintenance actions such as moving a node to a different location and restoring a database.

    - - - - - - - - - - - - - - - - - -
    TitleDescription
    Archiving and Restoring a DatabaseUsing zstd for the compression and decompression of a Casper node database and streaming from a backup location
    Moving a Validating NodeWays to move a validator node to another machine
    - - \ No newline at end of file diff --git a/next/operators/setup-network/genesis/index.html b/next/operators/setup-network/genesis/index.html deleted file mode 100644 index 42a5326b9..000000000 --- a/next/operators/setup-network/genesis/index.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - -Genesis | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    The Genesis Block

    -

    The Casper node software creates a genesis block from the following input files:

    -
      -
    • chainspec.toml
    • -
    • accounts.toml
    • -
    -

    chainspec.toml

    -

    A version of the chainspec is downloaded by the pull_casper_node_version.sh script installed with the casper-node-launcher debian package. This script pulls the chainspec.toml file from the appropriate path defined in the network config file used (casper.conf for MainNet and casper-test.conf for TestNet).

    -

    The production version of the file from which this is based on can be found at casper-node/resources/production/chainspec.toml in the code base. To create a custom network, this file can be updated as desired. Any changes to this file will result in a different genesis hash. Refer to this page for detailed documentation on each of the variables in the file.

    -

    accounts.toml

    -

    This file contains the genesis validator set information, starting accounts and associated balances and bond amounts.

    -

    If an account is not bonded at genesis, specify a 0 for the bond amount.

    -

    Similar to the chainspec.toml, this is pulled from the appropriate path defined in the network config file used.

    - - \ No newline at end of file diff --git a/next/operators/setup-network/index.html b/next/operators/setup-network/index.html deleted file mode 100644 index 42e29dd5d..000000000 --- a/next/operators/setup-network/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Setting up Private Networks | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Setting up Private Networks

    -

    Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    The Genesis BlockFiles needed to create a genesis block
    The Chain SpecificationConfiguration settings describing the network state
    Setting up a Private Casper NetworkA step-by-step guide to establishing and configuring a private Casper network
    Staging Files for a New NetworkA guide to hosting protocol files for a new Casper network
    - - \ No newline at end of file diff --git a/next/operators/setup/fast-sync/index.html b/next/operators/setup/fast-sync/index.html deleted file mode 100644 index 1c7f93df9..000000000 --- a/next/operators/setup/fast-sync/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - -Fast Sync | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Introducing Fast Sync

    -

    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 transaction 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.

    -

    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 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

    -

    Fast-sync process

    -

    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.

    - - \ No newline at end of file diff --git a/next/operators/setup/hardware/index.html b/next/operators/setup/hardware/index.html deleted file mode 100644 index 3e47a4ff5..000000000 --- a/next/operators/setup/hardware/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Hardware | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Recommended Hardware Specifications

    -

    System Requirements

    -

    The following hardware specifications are recommended for the Casper Mainnet and Testnet:

    -
      -
    • 4 Cores
    • -
    • 32 GB Ram
    • -
    • 2 TB SSD or network SSD backed disk
    • -
    • Linux machine running Ubuntu 20.04
    • -
    -
    Notes
      -
    • -

      SSD is required because HDD cannot perform random writes at the performance needed to keep in sync with the full speed of the network.

      -
    • -
    • -

      For non-archival nodes, disc usage will drop once data recovery is implemented. It is safe to slowly increase the disc space as needed while monitoring on a server capable of this.

      -
    • -
    -

    CPU Requirements

    -

    Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions.

    -

    To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture.

    -
    note

    This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question.

    - - \ No newline at end of file diff --git a/next/operators/setup/index.html b/next/operators/setup/index.html deleted file mode 100644 index 391505b0d..000000000 --- a/next/operators/setup/index.html +++ /dev/null @@ -1,71 +0,0 @@ - - - - - -Setting up a Node | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Setting up a Node

    -

    The prerequisite for becoming a validator is to set up a node and join a network as described here.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Recommended Hardware SpecificationsSystem requirements for the Casper Mainnet and Testnet
    Basic Node ConfigurationProcesses and files involved in setting up a Casper node
    Node EndpointsPorts for communicating with other nodes and dApps
    Installing a NodeStep-by-step instructions to install a Casper node
    Setting the Open Files LimitRequired setting for the Casper node to run correctly
    Upgrading the NodeBefore joining the network, the node needs to be upgraded
    Joining a Running NetworkSteps to join an existing Casper network
    Setting up a Non-Root UserLogging into the node remotely using a key
    Node EventsInformation on a node's events stream
    Sidecar SetupAn application allowing subscribers to monitor a node's event stream, query stored events, and query a node’s JSON-RPC API
    - - \ No newline at end of file diff --git a/next/operators/setup/node-events/index.html b/next/operators/setup/node-events/index.html deleted file mode 100644 index 896a65829..000000000 --- a/next/operators/setup/node-events/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Node Events | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    The Node's Event Stream

    -

    Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the event_stream_server.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.

    -

    Monitoring a Node's Event Stream

    -

    As an operator, you can use cURL to monitor the event stream on a node.

    -
    curl -s http://HOST:PORT/events/
    -
      -
    • HOST - The IP address of a node on the network.
    • -
    • PORT - The port specified as the event_stream_server.address in the node's config.toml.
    • -
    -

    Another helpful tool is the Casper Sidecar, which provides the recommended way to monitor events on a node. Visit the Casper Sidecar Usage Guide for a detailed list of events and REST queries you can use to monitor the node and the state of the network.

    -

    Replaying the Event Stream

    -

    This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the HOST, PORT, and ID fields with the needed values.

    -
    curl -sN http://HOST:PORT/events?start_from=ID
    -

    Example:

    -
    curl -sN http://65.21.235.219:9999/events?start_from=29267508
    -
    note

    The node stores only a limited number of events in its cache, which can be configured using the event_stream_buffer_length in the config.toml. The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected.

    The Casper Sidecar may store additional events depending on how it was configured.

    - - \ No newline at end of file diff --git a/next/operators/setup/non-root-user/index.html b/next/operators/setup/non-root-user/index.html deleted file mode 100644 index 99e94767f..000000000 --- a/next/operators/setup/non-root-user/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - -Non-Root Users | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Setting up a Non-Root User

    -

    Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace <username> in the instructions below with your username.

    -
      -
    1. -

      Use ssh-keygen to generate a new SSH key.

      -
    2. -
    3. -

      Create the user with no password, as the key is your password.

      -
    4. -
    -
    sudo adduser <username> --disabled-password
    -
      -
    1. Create authorized_keys with your key to log in.
    2. -
    -
    sudo su - <username>
    mkdir .ssh
    chmod 700 .ssh
    touch .ssh/authorized_keys
    -
      -
    1. -

      Use the editor of your choice and paste your .ssh public key i the .ssh/authorized_keys file.

      -
    2. -
    3. -

      Exit out of the <username> account and log into the root or previous sudo-er account.

      -
    4. -
    -
    exit
    -
      -
    1. Add your user to sudo-ers under the root account or your previous sudo-er account.
    2. -
    -
    sudo visudo
    -
      -
    1. Type <username> ALL=(ALL:ALL) NOPASSWD:ALL below the row containing root ALL=(ALL:ALL) ALL.
    2. -
    -
    # User privilege specification
    root ALL=(ALL:ALL) ALL
    <username> ALL=(ALL:ALL) NOPASSWD:ALL
    -
      -
    1. You should be able to log in with the key and not use the root user.
    2. -
    -
    ssh -i <your ssh private key> <username>@<server ip>
    -

    Here is an example command:

    -
    ssh -i ~/.ssh/id_rsa casper@10.21.10.200
    - - \ No newline at end of file diff --git a/next/operators/setup/upgrade/index.html b/next/operators/setup/upgrade/index.html deleted file mode 100644 index 62ba5c88c..000000000 --- a/next/operators/setup/upgrade/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Upgrades | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Upgrading the Node

    -

    The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.

    -
    [protocol]
    # This protocol version becomes active at the start of this era.
    activation_point = 100
    -

    At every block finalization, the casper-node looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the chainspec.toml file. This will be the era before where the current casper-node will cleanly shut down.

    -

    The casper-node-launcher will detect a clean exit 0 condition and start the next version of the casper-node.

    -

    Upgrading Protocol Versions

    -

    All Casper Mainnet participants are requested to stage the upgrade of their nodes to a new version of casper-node immediately. Staging an upgrade is a process in which you tell your node to download the upgrade files and prepare them so that they can automatically be applied at the pre-defined activation point.

    -

    Do not restart the node, only run the commands provided. The upgrade will automatically occur at the activation point.

    -

    Upgrade Staging Instructions

    -

    The process to upgrade your node is very straightforward. Log in to your node, and execute the following command on Mainnet:

    -
    sudo -u casper /etc/casper/node_util.py stage_protocols casper.conf
    -

    On Testnet, use casper-test.conf:

    -
    sudo -u casper /etc/casper/node_util.py stage_protocols casper-test.conf
    -

    Note: To only view the list of staged and unstaged protocols, use this command: sudo -u casper /etc/casper/node_util.py check_protocols casper.conf

    -

    Verifying Successful Staging

    -

    After you have successfully executed the staging commands, wait a few minutes for a new block to be issued before checking that your node is correctly staged with the upgrade. After a few minutes, take a look at your status end-point, as follows:

    -
    curl -s http://127.0.0.1:8888/status | jq .next_upgrade
    -

    You should expect this output if properly staged, prior to upgrading:

    -
    $ curl -s localhost:8888/status | jq .next_upgrade
    {
    "activation_point": 4968,
    "protocol_version": "1.4.6"
    }
    -

    If you see null after waiting for a few minutes, then your upgrade staging was not executed successfully.

    -

    Note: The protocol version will change as per the next upgrade available.

    - - \ No newline at end of file diff --git a/next/resources/advanced/multi-sig/index.html b/next/resources/advanced/multi-sig/index.html deleted file mode 100644 index 2ab333683..000000000 --- a/next/resources/advanced/multi-sig/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - -Introduction | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    The Native Multi-Signature Feature

    -

    In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.

    -

    The additional examples present use cases where Casper's multi-signature feature would be helpful.

    - - \ No newline at end of file diff --git a/next/resources/beginner/counter-testnet/overview/index.html b/next/resources/beginner/counter-testnet/overview/index.html deleted file mode 100644 index e58656fd9..000000000 --- a/next/resources/beginner/counter-testnet/overview/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Overview

    -

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    -

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    -

    image

    - - \ No newline at end of file diff --git a/next/resources/beginner/counter/overview/index.html b/next/resources/beginner/counter/overview/index.html deleted file mode 100644 index 7f91d91ab..000000000 --- a/next/resources/beginner/counter/overview/index.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Overview

    -

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    -

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    -

    image

    - - \ No newline at end of file diff --git a/next/resources/build-on-casper/introduction/index.html b/next/resources/build-on-casper/introduction/index.html deleted file mode 100644 index 02d63022e..000000000 --- a/next/resources/build-on-casper/introduction/index.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - - -Build on Casper | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Building on Casper

    -

    This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.

    - -

    Thriving Ecosystem

    -

    The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use.

    -

    Wallets

    - -

    Block Explorers

    - -

    Developer Tools

    - -

    Open Source Software

    - -

    Developer-Friendly Language

    -

    Casper Network's development ecosystem supports WebAssembly by design, rather than requiring proprietary languages like Solidity. Casper contracts function just like regular software. This feature simplifies the development path for enterprises and development teams that want to build on the Casper Mainnet.

    -

    Rust is a beloved programming language for its safety and performance. We offer a Rust experience and a runtime environment for developing smart contracts . The Rust smart contracts are compiled to WebAssembly (Wasm), which is an open standard for performance and portability of modern web applications.

    -
    note

    Wasm can support any language compiled or interpreted on any operating system with the help of appropriate tools. Therefore, we can support more languages for smart contracts as compilation targets for WebAssembly become available.

    -

    Powerful Accounts

    -

    Each Casper network offers powerful accounts that are more than just public keys. Accounts offer weights for separate key management and transaction signing rights, and the ability to run session code (Wasm) in an account's context. By running session code, it's possible to delegate transaction signing to multiple keys, revoke lost keys to recover accounts and store data within the account itself. It is also possible to securely share state between accounts and contracts (without expensive cryptographic checks). Refer to the Casper Permissions Model for more details.

    -

    Contract Upgrades

    -

    Casper smart contracts use a package management model, which allows the direct upgrading of on-chain smart contracts, eliminating the need for complex migration processes and making it easy for developers to add new features or fix bugs by adding a new version of the contract. When installing a contract, it's possible to designate a contract as 'not upgradeable', which is suitable for DeFi contracts.

    -

    Development Tools

    -

    IDE Integration

    -

    The Casper development process strives to be familiar to all developers. You can run and build code locally within an IDE and use assertions and tests to verify the functionality of your application. You can set the contract's starting state and create and run tests on your development machine. Casper contracts function like regular software, so there is little you need to know about the blockchain to get started.

    -

    CI/CD

    -

    Casper also provides the instrumentation and tooling that seamlessly integrates existing Continuous Integration/Continuous Deployment pipelines. Build servers can run the Casper Virtual Machine without the overhead of a full node, tracking the blockchain internal state and running assertions, thus enabling a solid development pipeline.

    -

    Local Network Testing

    -

    We also offer a tool to run a local Casper Network Even though you don't need a stand-alone node for smart contract development, you can configure your local network to test your deployments and estimate gas costs. A local network is helpful when integrating your dApp into a mobile or web interface.

    -

    Public Mainnet and Testnet

    -

    The Casper Mainnet is a public, open-source, community-driven ecosystem. You can also explore the Testnet to test drive your applications and estimate gas costs.

    -

    AWS

    -

    We also offer several tools to run AWS instances of Casper nodes.

    -

    SDK Client Libraries

    -

    In addition to the default command-line Rust client, the Casper community is building other clients in JavaScript, Java, Golang, Python, C#, and other languages.

    -

    No Gas Fees

    -

    Casper seeks to eliminate volatility and improve developer and enterprise experiences by eliminating transaction fees on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows.

    - - \ No newline at end of file diff --git a/next/resources/changelog/index.html b/next/resources/changelog/index.html deleted file mode 100644 index 8551ecbc7..000000000 --- a/next/resources/changelog/index.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - -Documentation Updates by Protocol Release | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Documentation Updates by Protocol Release

    -

    Condor (2.0)

    -

    Concepts

    -

    The following are changes introduced alongside release of the Condor network upgrade.

    -

    Understanding Key Types - Additional Key Types and document restructuring.

    -

    Serialization Standard - Serialization information for new types.

    -

    Smart Contracts - Information on the new factory pattern feature for smart contracts.

    -

    Developers

    -

    Building dApps -> Monitoring and Consuming Events - Information related to contract-level events.

    -

    Casper JSON-RPC API -> Informational JSON-RPC Methods - New RPC methods.

    -

    Casper JSON-RPC API -> Transactional JSON-RPC Methods - New RPC methods.

    -

    Casper JSON-RPC API -> Types - New parameters used by the JSON-RPC API.

    -

    Writing On-Chain Code -> Contract-Level Events - Guide to the new contract-level events feature.

    -

    Writing On-Chain Code -> Factory Contracts - Guide to the new factory pattern for smart contracts.

    -

    Operators

    -

    Private Network -> The Chainspec - Updates to the chainpsec relating to contract-level events.

    - - \ No newline at end of file diff --git a/next/resources/index.html b/next/resources/index.html deleted file mode 100644 index ce9d7ff41..000000000 --- a/next/resources/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - -Resources Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Resources Overview

    -

    Building on Casper

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Wallets and Block ExplorersWallets that support the native Casper token $CSPR
    WebAssemblyLearn why WebAssembly is an advantage in contract development
    AccountsThe Casper account-model allowing for multi-signature deploys
    Developer toolsAvailable development tools
    Ecosystem ProjectsExplore some open-source code available in the Casper ecosystem
    -

    Move to Casper

    - - - - - - - - - - - - - -
    TopicDescription
    Move to CasperLearn how to start working with Casper, having previous knowledge of other blockchains
    -

    Tutorials

    - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    QuickstartInstall Rust and setup a Casper environment
    BeginnerLearn the basics, such as installing and upgrading contracts
    AdvancedLearn about multi-sig, authorization keys, exchange integration, and storage
    - - \ No newline at end of file diff --git a/next/resources/tokens/cep18/quickstart-guide/index.html b/next/resources/tokens/cep18/quickstart-guide/index.html deleted file mode 100644 index c1bde80e8..000000000 --- a/next/resources/tokens/cep18/quickstart-guide/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - -On-chain Installation | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Installing and Interacting with a CEP-18 Contract

    -

    This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.

    -

    The Ethereum Request for Comment (ERC-20) standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded.

    -

    To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions.

    -

    For greater detail into the creation and mechanics of the Casper fungible token contract, see the full Casper Fungible Token Tutorial.

    -

    Prerequisites

    -

    Before using this guide, ensure you meet the following requirements:

    -
      -
    • Set up your machine as per the prerequisites
    • -
    • Use the [Casper command-line client]
    • -
    • Get a valid node-address
    • -
    • Know how to deploy a smart contract to a Casper network
    • -
    • Hold enough CSPR tokens to pay for transactions
    • -
    -

    Setup

    -

    Clone the fungible token (CEP-18) contract repository and run the make build-contract command. This will create the cep18.wasm and the cep18_test_contract.wasm. The token Wasm is the main contract. We will use the cep18_test_contract Wasm to query the balances and allowances of the fungible token balances throughout this workflow.

    -

    Install the Main Fungible Token Contract

    -

    The following command will create a deploy containing the CEP-18 contract instance using your supplied arguments as follows:

    -
      -
    • Name - The name of your CEP-18 token
    • -
    • Symbol - The symbol used to refer to your CEP-18 token
    • -
    • Total_supply - The total supply of the CEP-18 token to be minted
    • -
    • Decimals - The number of spaces after the decimal. (As an example, a total supply of 1000000 with a decimals setting of 3 would be 1,000.000 tokens)
    • -
    -
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18.wasm \
    --session-arg "name:string='CEP18'" \
    --session-arg "symbol:string='gris'" \
    --session-arg "total_supply:u256='100'" \
    --session-arg "decimals:u8='1'" \
    --payment-amount 150000000000
    -

    Install the cep18_test_contract Contract Package

    -

    The following command will install the CEP-18 helper contract that allows you to check balances and access approval features.

    -
    casper-client put-deploy -n http://<NODE IP>:<PORT> \
    --chain-name <CHAIN NAME> \
    --secret-key ~/casper/demo/user_a/secret_key.pem \
    --session-path ~/casper/demo/cep18_test_contract.wasm \
    --payment-amount 50000000000
    -

    At this point, the account that installed both the main contract and the helper contract will look like this.

    -
    {
    "src": {
    "Account": {
    "_accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "namedKeys": [
    {
    "name": "cep18_test_contract",
    "key": "hash-999326ca8408dfd37da023eb6fd82f174151be64f83f9fb837632a0d69fd4c7e"
    },
    {
    "name": "cep18_token_contract",
    "key": "hash-b568f50a64acc8bbe43462ffe243849a88111060b228dacb8f08d42e26985180"
    },
    ],
    "mainPurse": "uref-6c062525debdee18d5cad083ca530fcb65ef8741574fba4c97673f4ed00093f7-007",
    "associatedKeys": [
    {
    "accountHash": "account-hash-303c0f8208220fe9a4de40e1ada1d35fdd6c678877908f01fddb2a56502d67fd",
    "weight": 1
    }
    ],
    "actionThresholds": {
    "deployment": 1,
    "keyManagement": 1
    }
    }
    }
    }
    -

    Note:

    -
    -
      -
    1. cep18_token_contract is the main contract, and is a stored contract, record its hash
    2. -
    3. cep18_test_call is a contract package which contains the utility contract required to read the balances and allowances of users within the fungible token state.
    4. -
    -
    -

    Next Steps

    -

    In the following sections, the sample guide explains the querying of the contract package, token transfers, and approvals.

    -
    - - \ No newline at end of file diff --git a/next/resources/tokens/cep78/reverse-lookup/index.html b/next/resources/tokens/cep78/reverse-lookup/index.html deleted file mode 100644 index 5a5d18cae..000000000 --- a/next/resources/tokens/cep78/reverse-lookup/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -Ownership Lookup | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Owner Reverse Lookup Functionality

    -

    In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.

    -

    In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract.

    -

    This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page.

    -

    The CEP-78 Page System

    -

    Ownership of NFTs within a CEP-78 contract is now tracked with a series of pages, with each page tracking a range of 1,000 tokens each. When installing an instance of the CEP-78 contract, the user determines the total token supply. This, in turn, determines the maximum number of pages, i.e., for a 10,000 token collection, each account could have up to 10 pages numbering from 0-9 tracking ownership of NFTs.

    -

    A page_table tracks which pages within a range have been allocated and set for a certain user. The size of the page table directly correlates to the total token supply, i.e. for a CEP-78 instance tracking 10,000 tokens, the page table would be 10 bits wide. For a total of 20,000 it would be 20 bits wide. The cost of the initial page table allocation depends on the overall total size of a collection, with larger collections possessing correspondingly greater gas costs. To make initial minting costs more stable across contracts, the process of allocating a page table has been shifted to the register_owner entrypoint.

    -

    After registering as an owner, the contract creates an entry within the page_table dictionary for the minting account or contract. This dictionary entry consists of a series of boolean values amounting to the total number of pages in the collection. In our 10,000 token example, this would be 10 bits set to false.

    -

    Upon minting the token, the user will pay for a page allocation. This adds them to the page dictionary, in which each entry corresponds to a specific account or contract that owns tokens within that page. That account or contract's entry in the page dictionary will consist of 1,000 page_address bits set to False upon allocation, and the minting of any given token in that page will set the page_address bit to True.

    -

    In addition, that account or contract's page_table will be updated by marking the corresponding page number's bit as True.

    -

    As an example, consider a new user minting their first NFT with a given CEP-78 contract set to a maximum number of 10,000 tokens. They are minting the 2,350th token within that collection. The following sequence of events would occur:

    -
      -
    1. -

      The contract registers their account as an owner.

      -
    2. -
    3. -

      The contract creates a page_table dictionary for that account, with 10 boolean values. As the numbering system begins with 0, the third boolean value corresponding with page 2 is set to True.

      -
    4. -
    5. -

      The account pays for allocation of page 2, creating an entry in the Page 2 dictionary for that account. Within that entry, there are 1,000 boolean values set to false. Minting the 2,350th token in the collection sets the corresponding page_address boolean for 350 as True.

      -
    6. -
    7. -

      Any further tokens minted by this account prior to the 3,000th token being minted will not have to pay for additional page allocations. If the account mints a token at or beyond 3,000, they must pay for the corresponding page allocation. For example, if they decided to mint the 5,125th token in the collection, they would need to pay for page 5 to be allocated to them. They would then be added to the page 5 dictionary with the page_address boolean for 125 set as True.

      -
    8. -
    -

    This system binds the data writing costs to a maximum size of any given page dictionary.

    -

    Updated Receipts

    -

    If the contract enables OwnerReverseLookupMode, calling the updated_receipts entrypoint will return a list of receipt names alongside the dictionary for the relevant pages.

    -

    Updated receipts come in the format of "{<collection name>}\_m{modulo}\_p{<page number>}". Once again using the 2,350th token as an example, the receipt would read:

    -
    cep78_collection_m_350_p_2
    -

    You can determine the token number by multiplying the page_number by the page_size(1,000) and adding the modulo.

    -

    If the NFTIdentifierMode is set to Ordinal, this number corresponds directly to the token ID.

    -

    If it is set to Hash, you will need to reference the HASH_BY_INDEX dictionary to determine the mapping of token numbers to token hashes.

    - - \ No newline at end of file diff --git a/next/resources/tokens/index.html b/next/resources/tokens/index.html deleted file mode 100644 index 292854b11..000000000 --- a/next/resources/tokens/index.html +++ /dev/null @@ -1,82 +0,0 @@ - - - - - -Casper Token Standards | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Casper Token Standards

    -

    CEP-18 Casper Fungible Token Standard

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    A Casper Fungible Token TutorialA full tutorial for use of the CEP-18 Casper Fungible Token Standard.
    Installing and Interacting with a CEP-18 ContractA quickstart guide for installing a CEP-18 contract with the Rust Casper Client.
    Exploring the CEP-18 ContractsA guide to interacting with installed CEP-18 contracts.
    CEP-18 Token Transfers and AllowancesA guide for transferring Casper Fungible Tokens.
    Testing Framework for CEP-18A CEP-18 testing framework using the Casper engine test support crate.
    -

    CEP-78 Enhanced NFT Standard

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    CEP-78 Enhanced NFT Standard IntroductionAn introduction to the CEP-78 Enhanced NFT Standard.
    CEP-78 ModalitiesInformation on the features available when installing a CEP-78 contract instance.
    Installing and Interacting with a CEP-78 ContractAn introduction to features present in the CEP-78 Enhanced NFT Standard.
    Owner Reverse Lookup FunctionalityInformation on the Onwer Reverse Lookup feature of CEP-78 contracts.
    A CEP-78 JavaScript Client TutorialA tutorial for using the JavaScript CEP-78 client.
    - - \ No newline at end of file diff --git a/next/resources/tutorials/advanced/index.html b/next/resources/tutorials/advanced/index.html deleted file mode 100644 index 07f363e8b..000000000 --- a/next/resources/tutorials/advanced/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Advanced Tutorials | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Advanced Tutorials

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Two-Party Multi-Signature TransactionsA trivial two-party multi-signature scheme for signing and sending transactions
    Multi-Sig ManagementIntegrate key management on Casper accounts and sign transactions with multiple keys
    Interacting with Runtime Return ValuesContract code returning a value to the immediate caller via runtime::ret()
    Safely Transfer Tokens to a ContractTwo methods to handle tokens via a contract
    Reading and Writing to Global State using RustMethods to read and write data to global state on a Casper network using Rust
    Cross Contract CommunicationVariations of cross-contract communication for more complex scenarios
    Working with Authorization KeysRetrieve and use the authorization keys associated with a transaction
    - - \ No newline at end of file diff --git a/next/resources/tutorials/beginner/getting-started-tutorial/index.html b/next/resources/tutorials/beginner/getting-started-tutorial/index.html deleted file mode 100644 index d46d19cc5..000000000 --- a/next/resources/tutorials/beginner/getting-started-tutorial/index.html +++ /dev/null @@ -1,24 +0,0 @@ - - - - - -Getting Started | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Getting Started Video

    -

    This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.

    -

    - -

    - - \ No newline at end of file diff --git a/next/resources/tutorials/beginner/index.html b/next/resources/tutorials/beginner/index.html deleted file mode 100644 index 9eaa9af1b..000000000 --- a/next/resources/tutorials/beginner/index.html +++ /dev/null @@ -1,78 +0,0 @@ - - - - - -Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Overview

    -

    Beginner Tutorials

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on an NCTL NetworkAn example contract that maintains a counter variable on a local Casper Network with NCTL
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Querying a Casper NetworkQueries for users and developers to obtain information stored on the blockchain
    Smart Contract UpgradesLearn how to upgrade smart contracts
    The Casper Fungible Token Standard (CEP-18)Fungible Token Standard (CEP-18) Implementation and Usage
    Launching a Casper Node with AWS MarketplaceLearn how to launch a Casper Node through the AWS Marketplace
    -

    GitHub Tutorials

    - - - - - - - - - - - - - - - - - -
    TitleDescription
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    - - \ No newline at end of file diff --git a/next/runtime/index.html b/next/runtime/index.html deleted file mode 100644 index 05bf2ee20..000000000 --- a/next/runtime/index.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - -Runtime | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Runtime Economics

    -

    The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:

    -
      -
    • A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See Fee Elimination for more details.
    • -
    • A form of dynamic pricing that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era.
    • -
    • Blocks are structured into lanes that can only hold a particular number of transactions of specified types.
    • -
    -

    These economic features are configurable using chainspec parameters.

    -

    Gas Allocation

    -

    Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas.

    -

    We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant CEPs. In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model.

    -

    Consensus before execution & basics of payment

    -

    The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas.

    -

    Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future.

    -

    Costs and limits

    -

    Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex host-side functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the chainspec and may vary according to arguments. Read more about how Casper measures computational work here.

    -

    We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades.

    -

    Lanes and gas costs

    -

    There are several platform parameters that delineate the sets of transactions that may be included in a valid block:

    -
      -
    • Number of lanes and lane types -
        -
      • System interaction lanes for Mint (transfers) and Auction transactions.
      • -
      • WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction.
      • -
      • All lanes can contain some finite number of transactions, set separately for each lane.
      • -
      • For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time.
      • -
      -
    • -
    • Block gas and size limits -
        -
      • The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots.
      • -
      • The block size limit imposes an absolute ceiling on the total byte size of included transactions.
      • -
      • Individual transaction size limits are also enforced.
      • -
      -
    • -
    -

    These are the lane configuration settings for the Condor release on Mainnet:

    -
    [transactions.v1]
    # The configuration settings for the lanes of transactions including both native and Wasm based interactions.
    # Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1
    # respectively
    # The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction
    # within a given lane.
    # The maximum length in bytes of runtime args per V1 transaction.
    # [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)
    # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and
    # the lane must be present and defined.
    # Different casper networks may not impose such a restriction.
    # [1] -> Max transaction size in bytes for a given transaction in a certain lane
    # [2] -> Max args length size in bytes for a given transaction in a certain lane
    # [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane
    # [4] -> The maximum number of transactions the lane can contain
    native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]
    native_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]
    wasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]
    -

    These are the block gas and size limits for the Condor release on Mainnet:

    -
    [transactions]
    ...
    # Maximum block size in bytes including transactions contained by the block. 0 means unlimited.
    max_block_size = 5_242_880
    # The upper limit of total gas of all transactions in a block.
    block_gas_limit = 3_300_000_000_000
    -

    Dynamic Gas Pricing

    -

    A dynamic gas pricing system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack.

    -

    Eliminating Gas Fees

    -

    See Gas and Fee Elimination for more details.

    - - \ No newline at end of file diff --git a/next/sdk/index.html b/next/sdk/index.html deleted file mode 100644 index d275c2867..000000000 --- a/next/sdk/index.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - -SDK Client Libraries | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    SDK Client Libraries

    -

    This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.

    -

    Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories.

    -

    Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories.

    -

    Serialization Standard

    -

    The Casper platform uses a custom serialization format. To this end, we've established a Serialization Standard, which must be followed when building a Casper SDK.

    -

    JSON-RPC API

    -

    Developers can interact directly with the Casper JSON-RPC API instead of using an SDK.

    -

    Table of Contents

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    SDK DocumentationGitHub LocationOrganization
    JavaScript/TypeScriptcasper-js-sdkCasper Ecosystem
    Java SDKcasper-java-sdkCasper Association
    C# SDKcasper-net-sdkMAKE
    Go SDKcasper-go-sdkMAKE
    Python SDKcasper-python-sdkCasper Association
    PHP SDKcasper-php-sdkMAKE
    Scala SDKcasper-scala-sdkM. Abahmane
    - - \ No newline at end of file diff --git a/next/users/block-explorer/index.html b/next/users/block-explorer/index.html deleted file mode 100644 index 02af7382c..000000000 --- a/next/users/block-explorer/index.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - -Block Explorers | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Block Explorers

    -

    The Casper blockchain is available as the Mainnet and Testnet. -The Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR). -The Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet.

    -

    You can use block explorers to explore the Casper blockchain such as :

    - -

    What is a Block Explorer

    -

    A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history.

    -

    Using a Block Explorer

    -

    You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator.

    -

    The following topics link you to detailed instructions on using the cspr.live block explorer to access and work with your CSPR tokens.

    - -
    note

    To perform actions using the cspr.live block explorer, you must sign in to your Casper account using one of the wallets provided.

    - - \ No newline at end of file diff --git a/next/users/csprlive/index.html b/next/users/csprlive/index.html deleted file mode 100644 index 821d9a80d..000000000 --- a/next/users/csprlive/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - -Using CSPR.live | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Using the CSPR.live block explorer

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Funding Testnet AccountsFund a Testnet account for testing
    Transferring TokensTransfer tokens using the CSPR.live block explorer
    Delegating TokensDelegate tokens to a validator
    Undelegating TokensUndelegate tokens from a validator
    - - \ No newline at end of file diff --git a/next/users/delegate-ui/index.html b/next/users/delegate-ui/index.html deleted file mode 100644 index 66de1b2fe..000000000 --- a/next/users/delegate-ui/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - -Delegate Tokens | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Delegating Tokens with a Block Explorer

    -

    Introduction

    -

    This tutorial covers how to delegate Casper tokens to a validator on the network.

    -

    Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called delegation or staking. We will use these terms interchangeably in this guide. See the Staking Key Concepts page for more details about the differences.

    -

    Prerequisites

    -
      -
    1. To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the Casper Wallet by following the Getting Started user guide.
    2. -
    3. You need to fund the account's main purse to delegate tokens.
    4. -
    5. Connect to a block explorer to set up the delegation. This guide uses cspr.live and the Casper Wallet.
    6. -
    7. Review your account before starting the process.
    8. -
    9. Review the current delegation cost and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail.
    10. -
    -

    Reviewing your Account

    -

    Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:

    -
      -
    • The Liquid Account Balance, representing the tokens you have for immediate use
    • -
    • The Delegated Account Balance, representing the delegated tokens already staked with validators on the network
    • -
    • The Delegations tab, listing the validators to whom you have delegated tokens
    • -
    -

    Account and delegations details

    -
      -
    • The Staking Rewards tab, showing the rewards received in each era
    • -
    -

    Account and rewards

    -

    Accessing the Delegation Feature

    -

    You can access the delegation functionality in two ways.

    -

    Option 1: Click Wallet from the top navigation menu and then click Delegate. In the next screen, you will need to specify the validator's public key or search for a validator.

    -

    Delegate from the Wallet

    -

    Option 2: Click Validators from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the Delegate button. The next screen will have the validator's public key pre-populated.

    -

    Delegate from a Validator

    -

    Stepping through the Delegation Process

    -

    The following instructions will take you through the delegation process, starting with the "Delegation details" screen.

    -

    Step 1 - Delegation details

    -
      -
    1. Specify the validator's public key if you have reached this screen using the Wallet drop-down menu. Otherwise, verify the pre-populated key in the Validator field.
    2. -
    3. Enter the amount of CSPR you wish to delegate. Remember to account for the delegation fee.
    4. -
    5. Click Next.
    6. -
    -

    Delegation details

    -

    Step 2 - Confirm the delegation

    -
      -
    1. Review the delegation details.
    2. -
    3. If everything is correct, click Confirm and delegate stake. If you wish to make changes, return to the previous screen.
    4. -
    -

    Confirm delegation details

    -

    Step 3 - Sign the delegation

    -
      -
    1. Sign the delegation by clicking Sign with Casper Wallet.
    2. -
    -

    Sign delegation

    -
      -
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.
    2. -
    -

    Signature Request window

    -
      -
    1. Click Sign in the Signature Request window to finalize the delegation.
    2. -
    -

    Completed delegation

    -

    The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the Deploy Details highlighted above.

    -

    Remember to Monitor your Stake. Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the Rewards tab on your account page on https://cspr.live/.

    -

    If you want to undelegate your tokens, you can do so at any time. See the Undelegation Guide for details.

    -

    Video Tutorial

    -

    This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step.

    -
    - - \ No newline at end of file diff --git a/next/users/funding-from-exchanges/index.html b/next/users/funding-from-exchanges/index.html deleted file mode 100644 index 1659bdee0..000000000 --- a/next/users/funding-from-exchanges/index.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - - -Funding Mainnet Accounts | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Funding Mainnet Accounts from an Exchange

    -

    To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.

    -

    This guide demonstrates a withdrawal from Coinlist to the Casper Mainnet using the cspr.live block explorer. You need to contact the exchange for instructions if you are working with a different exchange.

    -

    Prerequisites

    -

    Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on https://cspr.live/ and the field you need to specify in the withdrawal request from Coinlist.

    -

    Account public key from CSPR.Live

    -

    Transfers from Coinlist to Casper Mainnet

    -

    Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts.

    -
      -
    1. Log into your https://coinlist.co account.
    2. -
    3. Go to the "Wallet" tab.
    4. -
    -

    Coinlist Wallet tab

    -
      -
    1. Click on the "CSPR" section.
    2. -
    -

    CSPR on Coinlist

    -
      -
    1. Click on the "Withdraw" button.
    2. -
    -

    Withdraw on Coinlist

    -
      -
    1. Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.
    2. -
    -

    Withdrawal fields on Coinlist

    -
      -
    1. -

      Enter 0 in the "Transfer ID" field or another value that is meaningful to you. You MUST enter a value, or the transfer will fail!

      -
    2. -
    3. -

      Enter the CSPR amount you wish to transfer.

      -
    4. -
    5. -

      Click "Review".

      -
    6. -
    7. -

      Submit the transfer request. Wait approximately 5 minutes, and then go to the https://cspr.live/ site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.

      -
    8. -
    - - \ No newline at end of file diff --git a/next/users/index.html b/next/users/index.html deleted file mode 100644 index 3b9cf7767..000000000 --- a/next/users/index.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - -Users Overview | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Users Overview

    -

    General Topics

    - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Block ExplorersA guide to understanding block explorers
    Funding Mainnet AccountsFunding Mainnet accounts from an exchange
    Delegating TokensDelegating tokens to a validator (a.k.a. staking with a validator)
    -

    Using CSPR.live

    -

    Interact with the Casper blockchain using the cspr.live block explorer.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TopicDescription
    Funding Testnet AccountsFunding your Testnet account using the Faucet
    Delegating TokensStaking your Casper tokens with cspr.live
    Undelegating TokensUn-staking your Casper tokens
    Transferring TokensTransferring your Casper tokens using cspr.live
    -

    Using Ledger Devices

    -

    Interact with the Casper blockchain using a Ledger device.

    - - - - - - - - - - - - - - - - - -
    TopicDescription
    Ledger SetupA guide to setting up your Ledger device
    Delegating with Ledger DevicesDelegating tokens using your Ledger device
    - - \ No newline at end of file diff --git a/next/users/ledger/index.html b/next/users/ledger/index.html deleted file mode 100644 index 20a695e03..000000000 --- a/next/users/ledger/index.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - - -Casper on Ledger | Casper Docs - Redux - - - - - - - - - -
    - - \ No newline at end of file diff --git a/next/users/testnet-faucet/index.html b/next/users/testnet-faucet/index.html deleted file mode 100644 index a9c69415c..000000000 --- a/next/users/testnet-faucet/index.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - -Testnet Funding | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Funding Testnet Accounts

    -

    The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.

    -

    Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below.

    -

    Requesting Testnet Tokens

    -

    To request test tokens, follow these steps:

    -
      -
    1. Log into the Casper Testnet with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    2. -
    3. Click Tools on the top menu bar and select Faucet from the drop-down menu. Or, navigate to the Faucet using this link: https://testnet.cspr.live/tools/faucet.
    4. -
    5. Click Request tokens on the Faucet page:
    6. -
    -

    Faucet

    -
    caution

    Tokens can be requested only once per account. Otherwise, the deploy will fail with status User error: 1.

    If you have already exhausted your test funds, you can always create a new account.

    -
      -
    1. The Testnet will credit your account with test tokens.
    2. -
    - - \ No newline at end of file diff --git a/next/users/token-transfer/index.html b/next/users/token-transfer/index.html deleted file mode 100644 index 4654fc77d..000000000 --- a/next/users/token-transfer/index.html +++ /dev/null @@ -1,56 +0,0 @@ - - - - - -Transfer Tokens | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Transferring Tokens

    -

    You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.

    -

    Transferring Tokens

    -

    To transfer tokens, follow these steps:

    -
      -
    1. Sign in to your account with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    2. -
    3. Click Wallet on the top menu bar and select Transfer CSPR from the drop-down menu.
    4. -
    5. Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one.
    6. -
    7. Click Next to proceed.
    8. -
    -

    Transfer details

    -
      -
    1. A confirmation window appears to verify the details entered. Click Confirm and transfer to proceed to the next step.
    2. -
    -

    Confirm transfer

    -
      -
    1. Review the following important fields:
    2. -
    -
      -
    • The Deploy hash, which uniquely identifies your transfer
    • -
    • The Recipient public key of the person receiving your transfer
    • -
    • The Recipient account hash used by the system to track the transaction
    • -
    • The Transfer Amount containing the value of the transfer
    • -
    -

    Sign the transaction by selecting the Sign with Casper Wallet button to proceed to the next step.

    -

    Sign the transfer

    -
      -
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click Sign in the Signature Request window to complete the transaction.
    2. -
    -

    Review the transaction

    -
      -
    1. You completed the transaction and successfully transferred tokens.
    2. -
    -

    Transfer completed window

    -
      -
    1. View the updated CSPR balance in the account's main purse next.
    2. -
    - - \ No newline at end of file diff --git a/next/users/undelegate-ui/index.html b/next/users/undelegate-ui/index.html deleted file mode 100644 index 19859790e..000000000 --- a/next/users/undelegate-ui/index.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - -Undelegate Tokens | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Undelegating Tokens

    -

    If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.

    -

    Prerequisites

    -

    This guide assumes that you have previously delegated tokens to a validator using a block explorer or the Casper client.

    -

    Accessing the Undelegation Feature

    -

    You can access the undelegation functionality in three ways.

    -

    Option 1: Click Wallet from the top navigation menu and then click Undelegate Stake.

    -

    Undelegate from Wallet

    -

    Option 2: Click Validators from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the Undelegate Stake button.

    -

    Undelegate from Validator

    -

    Option 3: Open your account details and select the Delegations tab. Click the Undelegate button next to the validator from whom you wish to undelegate.

    -

    Undelegate from Account

    -

    Stepping through the Undelegation Process

    -

    The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.

    -

    Step 1 - Undelegation details

    -
      -
    1. Specify the validator from whom you want to undelegate your tokens if you have reached this screen using the Wallet drop-down menu. The search box will automatically show you the validators with whom you have staked. Otherwise, verify the pre-populated key in the Validator field.
    2. -
    3. Enter the amount of Casper tokens you want to undelegate.
    4. -
    5. Click Next.
    6. -
    -

    Undelegation details

    -

    Step 2 - Confirm the undelegation

    -
      -
    1. Review the undelegation details.
    2. -
    3. If everything looks correct, click Confirm and undelegate stake. If you wish to make changes, return to the previous screen.
    4. -
    -

    Confirm undelegation

    -

    Step 3 - Sign the undelegation

    -
      -
    1. Click Sign with Casper Wallet to sign the undelegation.
    2. -
    -

    Sign the undelegation

    -
      -
    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.
    2. -
    -

    Confirm deploy hash

    -
      -
    1. Click Sign in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:
    2. -
    -

    Undelegation confirmed

    -

    It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.

    -

    Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours.

    - - \ No newline at end of file diff --git a/next/workflow/ledger-setup/index.html b/next/workflow/ledger-setup/index.html deleted file mode 100644 index ad518b016..000000000 --- a/next/workflow/ledger-setup/index.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - -Set up Ledger | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Ledger Setup with Casper

    -

    A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.

    -

    Prerequisites

    -
      -
    1. Configure your Ledger and the Ledger Live application as described in the Getting Started with Ledger Live article.
    2. -
    3. <span style={{color:"#ee5945"}}>CRITICAL: Write down and hide your recovery codes! These are necessary to be able to restore your account if you lose or damage the hardware key.
    4. -
    5. Make sure the Ledger Live application version is at least at 2.73.1, which is the version that includes Casper accounts.
    6. -
    -
    note

    If you need help, contact us on Twitter, Discord, or Telegram.

    -

    Installing the Casper App on a Ledger Device

    -

    Install the Casper app on the Ledger device by following the steps below. You can find similar instructions on the official Ledger support site.

    -
      -
    1. In Ledger Live, open My Ledger at the bottom of the left-hand menu.
    2. -
    -

    Open My Ledger

    -
      -
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    2. -
    -

    Unlock your Ledger device

    -
      -
    1. If asked, allow Ledger manager on your device.
    2. -
    -

    Allow Ledger

    -
      -
    1. Find Casper in the app catalog.
    2. -
    -

    Find the Casper app

    -
    important

    Having trouble finding the Casper app? -Please search "Casper," not "CSPR" when searching for the app in the "My Ledger" tab in Ledger Live.

    -
      -
    1. Click the Install button of the app.
    2. -
    -
      -
    • An installation window appears.
    • -
    • Your device will display "Processing..."
    • -
    • The app installation is confirmed.
    • -
    -

    Casper installation confirmed

    -
      -
    1. Open the Casper App on your Ledger device by clicking both buttons on the device, and keep it open while doing the next steps.
    2. -
    -

    Select Casper on Ledger

    -

    Casper app is ready

    -

    Sending and Receiving Tokens

    -

    To send and receive CSPR tokens using the accounts on your Ledger device, you have two options:

    -
      -
    1. Manage Casper Accounts using Ledger and Ledger Live
    2. -
    3. Manage Casper Accounts using Ledger and CSPR.live
    4. -
    -

    To stake CSPR tokens with a validator on the Casper Mainnet, you need to use the CSPR.live block explorer, as described in Delegating with Ledger Devices.

    -

    Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange.

    - - \ No newline at end of file diff --git a/next/writing-contracts/index.html b/next/writing-contracts/index.html deleted file mode 100644 index 4de680284..000000000 --- a/next/writing-contracts/index.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - -Introduction | Casper Docs - Redux - - - - - - - - - -
    Version: Next

    Writing On-Chain Code

    -

    This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.

    -

    - -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Getting Started with RustAn introduction to using Rust with the Casper Platform
    Getting Started with AssemblyScriptAn introduction to using AssemblyScript with the Casper Platform
    Writing a Basic Smart Contract in RustAn example of a smart contract built in Rust
    Unit Testing Smart ContractsSteps to test contract code using the unit testing framework
    Upgrading and Maintaining Smart ContractsAn introduction to versioning smart contracts
    Calling Contracts
    Smart Contracts and Session CodeUnderstand what session code is and when you would use it over contract code
    Writing Session CodeAn introduction to writing session code
    Unit Testing Session CodeSteps to test session code using the unit testing framework
    Contract-Level EventsEnabling smart contracts to emit messages while executing on the blockchain
    Using Contract Hash vs. Package HashAdvantages and disadvantages of using contract_hash vs. contract_package_hash when calling a contract
    The Factory Pattern for Smart ContractsLearn to implement the contract factory pattern on a Casper network
    Best Practices for Casper Smart Contract AuthorsAn 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 covers installing and calling contracts using the Casper command-line client written in Rust.

    - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Installing Smart Contracts and Querying Global StateA guide on installing smart contracts and querying global state
    Calling Smart Contracts with the Rust ClientSteps to call a smart contract with the Rust command-line client
    Reading and Writing to DictionariesInformation on Dictionaries and how to read and write to them on the Casper Platform.
    Execution Error CodesPossible error codes when writing smart contracts.
    -

    Tutorials

    -

    The following tutorials outline some aspects of writing smart contracts on a Casper network.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Smart Contract UpgradesLearn how to upgrade smart contracts
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    Interacting with Runtime Return ValuesLearning how to return a value using contract code
    Working with Authorization KeysRetrieving and using the authorization keys associated with a transaction
    Safely Transfer Tokens to a ContractHow to handle tokens via a contract
    - - \ No newline at end of file diff --git a/opensearch.xml b/opensearch.xml index 2ed1fefc0..86fdfcbc6 100644 --- a/opensearch.xml +++ b/opensearch.xml @@ -4,8 +4,8 @@ Casper Docs - Redux Search Casper Docs - Redux UTF-8 - https://casper-devrel.github.io/icon/favicon.ico - - - https://casper-devrel.github.io/ + https://casper-network.github.io/icon/favicon.ico + + + https://casper-network.github.io/ \ No newline at end of file diff --git a/operators/becoming-a-validator/bonding/index.html b/operators/becoming-a-validator/bonding/index.html index 4997872ee..ad5abe4dd 100644 --- a/operators/becoming-a-validator/bonding/index.html +++ b/operators/becoming-a-validator/bonding/index.html @@ -1,26 +1,26 @@ - + -Bonding | Casper Docs - Redux +Bonding | Casper Docs - Redux - - + +
    Version: 1.5.X

    Bonding as a Validator

    + submit an issue on Github
    Version: Next

    Bonding as a Validator

    It is recommended that a bonding request be sent once the node has completed the synchronization process. In a Casper network, bonding takes place through the auction contract via the add_bid.wasm contract. The auction runs for a future era, every era. The chainspec.toml specifies the number of slots available, and the auction will take the top N slots and create the validator set for the future era.

    In the Testnet, era durations are approximately two hours. The entire process takes approximately 3 eras. Therefore, the time for bid submission to inclusion in the validator set is a minimum of six hours. Bonding requests (bids) are transactions like any other. Because they are generic transactions, they are more resistant to censorship.

    Method 1: Bonding with the System Auction Contract

    This method submits a bid using the system auction contract. Call the existing add_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    -
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point add_bid \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<BID_AMOUNT>'" \
    --session-arg="delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    +
    sudo -u casper casper-client put-deploy \
    --node-address <HOST:PORT> \
    --secret-key <PATH> \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT_IN_MOTES> \
    --session-hash <SESSION_HASH> \
    --session-entry-point add_bid \
    --session-arg "public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg "amount:u512='<BID_AMOUNT>'" \
    --session-arg "delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    --session-arg "minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'"
    --session-arg "maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'"
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. secret-key - The file name containing the secret key of the account paying for the Deploy
    3. @@ -40,17 +40,19 @@

      Metho
    4. public key: The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid
    5. amount: The bidding amount
    6. delegation_rate: Percentage of the rewards that the node operator retains for their services
    7. +
    8. minimum_delegation_amount (optional): Minimum allowed delegation amount in motes
    9. +
    10. maximum_delegation_amount (optional): Maximum allowed delegation amount in motes

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    note

    Calling the add_bid entry point on the auction contract has a fixed cost of 2.5 CSPR.

    Example:

    This example command uses the Casper Testnet to bid 10,000 CSPR for a validating slot:

    -
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point add_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg="delegation_rate:u8='10'"
    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.75.254:7777 \
    --chain-name casper-test \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --payment-amount 2500000000 \
    --session-hash hash-93d923e336b20a4c4ca14d592b60e5bd3fe330775618290104f9beb326db7ae2 \
    --session-entry-point add_bid \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg "delegation_rate:u8='10'"

    Next, check the status of the auction to see if you have won a validator slot.

    Method 2: Bonding with Compiled Wasm

    Another way to send a bonding transaction to the network is via a deploy containing the compiled add_bid.wasm. For details, refer to Building the Required Contracts.

    The following deploy is a template for sending a bonding request:

    -
    sudo -u casper casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="amount:u512='<BID-AMOUNT>'" \
    --session-arg="delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    +
    sudo -u casper casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --payment-amount <PAYMENT_AMOUNT> \
    --session-path $HOME/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg "public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg "amount:u512='<BID-AMOUNT>'" \
    --session-arg "delegation_rate:u8='<PERCENT_TO_KEEP_FROM_DELEGATORS>'"
    --session-arg "minimum_delegation_amount:u64='<MINIMUM_DELEGATION_AMOUNT>'"
    --session-arg "maximum_delegation_amount:u64='<MAXIMUM_DELEGATION_AMOUNT>'"
    1. node-address - An IP address of a peer on the network. The default port of nodes' JSON-RPC servers on Mainnet and Testnet is 7777
    2. secret-key - The file name containing the secret key of the account paying for the Deploy
    3. @@ -63,12 +65,14 @@

      Method
    4. public_key: The hexadecimal public key of the account's purse submitting the bid. This key must match the secret key that signs the bid
    5. amount: The bidding amount
    6. delegation_rate: Percentage of the rewards that the node operator retains for their services
    7. +
    8. minimum_delegation_amount (optional): Minimum allowed delegation amount in motes
    9. +
    10. maximum_delegation_amount (optional): Maximum allowed delegation amount in motes

    The command will return a deploy hash, which is needed to verify the deploy's processing results.

    note

    This method is more expensive than calling the add_bid entrypoint in the system auction contract, which has a fixed cost of 2.5 CSPR.

    Example:

    Here is an example request to bond using the add_bid.wasm. The payment amount specified is 3 CSPR. You must modify the payment and other values in the deploy based on the network's chainspec.toml.

    -
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.235.219:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 3000000000 \
    --session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg="delegation_rate:u8='10'"
    +
    sudo -u casper casper-client put-deploy \
    --node-address http://65.21.235.219:7777 \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name casper-test \
    --payment-amount 3000000000 \
    --session-path ~/casper-node/target/wasm32-unknown-unknown/release/add_bid.wasm \
    --session-arg "public_key:public_key='01c297d2931fec7e22b2fb1ae3ca5afdfacc2c82ba501e8ed158eecef82b4dcdee'" \
    --session-arg "amount:U512='$[10000 * 1000000000]'" \
    --session-arg "delegation_rate:u8='10'"

    Next, check the bid status to see if you have won a validator slot.

    Checking the Bid Status

    Since the bid was submitted using a deploy like any other, perform get-deploy using the casper-client, to see the execution status.

    @@ -86,6 +90,6 @@

    A Losing BidAvoiding Ejection

    To stay bonded and avoid ejection, each validator must keep their node running and in sync with the rest of the network. To recover from ejection, you will find more details here.

    Withdrawing a Bid

    -

    Follow the steps in Unbonding to withdraw a bid.

    +

    Follow the steps in Unbonding to withdraw a bid.

    \ No newline at end of file diff --git a/next/operators/becoming-a-validator/change-bid-public-key/index.html b/operators/becoming-a-validator/change-bid-public-key/index.html similarity index 70% rename from next/operators/becoming-a-validator/change-bid-public-key/index.html rename to operators/becoming-a-validator/change-bid-public-key/index.html index d836b6775..9417d33b7 100644 --- a/next/operators/becoming-a-validator/change-bid-public-key/index.html +++ b/operators/becoming-a-validator/change-bid-public-key/index.html @@ -3,19 +3,19 @@ -Change bid public key | Casper Docs - Redux +Change bid public key | Casper Docs - Redux - - + +
    Version: Next

    Changing the Public Key Associated with a Validator Bid

    + submit an issue on Github
    Version: Next

    Changing the Public Key Associated with a Validator Bid

    The public key associated with a given validator bid can be changed through the auction contract's change_bid_public_key entry point.

    An example of this functionality would be to transfer ownership of a validator "slot" to a different party or to migrate a node to a backup server. By leveraging the system contract we can perform those operations more securely by making sure that no private key files need to be copied or transmitted between servers.

    When the public key is changed all relevant delegations are also changed to be associated with the updated validator bid.

    @@ -46,7 +46,7 @@

    note

    Calling the change_bid_public_key entry point on the auction contract has a fixed cost of 5 CSPR.

    Method 2: Using compiled WASM

    -

    You may also change the public key associated with a bid via a transaction containing the compiled change_bid_public_key.wasm binary. For details, refer to Building the Required Contracts.

    +

    You may also change the public key associated with a bid via a transaction containing the compiled change_bid_public_key.wasm binary. For details, refer to Building the Required Contracts.

    The following transaction is a template for sending a request:

    sudo -u casper casper-client put-txn session \
    --node-address http://<HOST:PORT> \
    --secret-key /etc/casper/validator_keys/secret_key.pem \
    --chain-name <CHAIN_NAME> \
    --category <INSTALL-UPGRADE|LARGE|MEDIUM|SMALL> \
    --pricing-mode fixed \
    --gas-price-tolerance <GAS_PRICE_TOLERANCE> \
    --transaction-path $HOME/casper-node/target/wasm32-unknown-unknown/release/change_bid_public_key.wasm \
    --session-entry-point call \
    --session-arg="public_key:public_key='<PUBLIC_KEY_HEX>'" \
    --session-arg="new_public_key:public_key='<PUBLIC_KEY_HEX>'"
      diff --git a/operators/becoming-a-validator/inactive-vs-faulty/index.html b/operators/becoming-a-validator/inactive-vs-faulty/index.html index bc73f5a59..75157ed48 100644 --- a/operators/becoming-a-validator/inactive-vs-faulty/index.html +++ b/operators/becoming-a-validator/inactive-vs-faulty/index.html @@ -1,22 +1,21 @@ - + -Inactive and Faulty Nodes | Casper Docs - Redux +Inactive and Faulty Nodes | Casper Docs - Redux - - + +
      Version: 1.5.X

      import useBaseUrl from '@docusaurus/useBaseUrl';

      -

      Inactive vs. Faulty Validator Nodes

      + submit an issue on Github
      Version: Next

      Inactive vs. Faulty Validator Nodes

      This page describes the differences between a validator node being considered inactive or faulty.

      In the last block of each era N, the consensus algorithm checks whether there are any messages from your validator node in that era that have been received by most of the other validators. Only if there is no such message does your node get marked as inactive in that block.

      Similarly, the consensus algorithm checks whether any two messages from your validator node contradict each other. If that is the case, it gets marked as faulty in that block. Usually, that means:

      @@ -30,6 +29,6 @@
    1. If you are inactive, you won't be assigned leader slots or be allowed to propose any blocks. Your node will only vote on other proposers' blocks if it returns online and can still receive rewards. But, even if it comes back online in era N + 1, it will get evicted for being offline in era N.
    2. If you are faulty, all your messages will be ignored. You won't be able to propose blocks or vote for them and won't receive block rewards.
    3. -

      In both cases, you remain evicted until you reactivate your bid, as described here.

      +

      In both cases, you remain evicted until you reactivate your bid, as described here.

    \ No newline at end of file diff --git a/operators/becoming-a-validator/index.html b/operators/becoming-a-validator/index.html index ff3e87fe9..47a677e3d 100644 --- a/operators/becoming-a-validator/index.html +++ b/operators/becoming-a-validator/index.html @@ -1,21 +1,21 @@ - + -Becoming a Validator | Casper Docs - Redux +Becoming a Validator | Casper Docs - Redux - - + +
    Version: 1.5.X

    Becoming a Validator

    + submit an issue on Github
    Version: Next

    Becoming a Validator

    After setting up a node, the operator can submit a bid to win a validating slot and bond to the network. This section also covers unbonding from the network, recovering from eviction, and the differences between inactive and faulty nodes.

    @@ -42,6 +42,10 @@ -
    TitleDescription
    Bonding as a ValidatorA guide about the bonding process and submitting a bid
    Unbonding as a ValidatorThe process to withdraw a bid and unbonding
    Recovering from Validator EvictionSteps a validator needs to take if it is evicted from the validator set
    Inactive vs. Faulty NodesThe differences between inactive and faulty nodes
    + + + + +
    TitleDescription
    Bonding as a ValidatorA guide about the bonding process and submitting a bid
    Unbonding as a ValidatorThe process to withdraw a bid and unbonding
    Recovering from Validator EvictionSteps a validator needs to take if it is evicted from the validator set
    Inactive vs. Faulty NodesThe differences between inactive and faulty nodes
    Change bid public keyThe differences between inactive and faulty nodes
    \ No newline at end of file diff --git a/operators/becoming-a-validator/recovering/index.html b/operators/becoming-a-validator/recovering/index.html index 6a347ca38..111546641 100644 --- a/operators/becoming-a-validator/recovering/index.html +++ b/operators/becoming-a-validator/recovering/index.html @@ -1,22 +1,21 @@ - + -Recovery | Casper Docs - Redux +Recovery | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Recovering from Validator Eviction

    + submit an issue on Github
    Version: Next

    Recovering from Validator Eviction

    This topic discusses the steps a validator needs to take if it is evicted from the validator set:

    1. Detecting the eviction
    2. @@ -33,7 +32,7 @@

      Det

      If you were a previous validator and still exist on the Validators Auction tab but not in Validators, you may have been evicted or outbid.

      Detection using the Casper Client

      All auction information is returned with the casper-client get-auction-info command. It would help if you filtered this down to your public key.

      -

      You can replace the public_key with your public key manually and run this command:

      +

      You can replace the public_key with your public key manually and run this command:

      casper-client get-auction-info | jq '.result.auction_state.bids[] | select( .public_key == "<public_key>")'

      Or, if you set up the node as described in this documentation, you can run another command that will automatically put in your public key:

      casper-client get-auction-info | jq --arg pk "$(cat /etc/casper/validator_keys/public_key_hex)" '.result.auction_state.bids[] | select( (.public_key | ascii_downcase) == ($pk | ascii_downcase) )'
      @@ -96,7 +95,7 @@

      Met
      sudo -u casper casper-client put-deploy \
      --node-address http://65.21.75.254:7777 \
      --secret-key /etc/casper/validator_keys/secret_key.pem \
      --chain-name casper-test \
      --payment-amount 5000000000 \
      --session-path "$HOME/casper-node/target/wasm32-unknown-unknown/release/activate_bid.wasm" \
      --session-arg "validator_public_key:public_key='$(cat /etc/casper/validator_keys/public_key_hex)'"

      Check that the deploy was successful with the casper-client get-deploy <deploy_hash> or by searching for the deploy hash on https://cspr.live/. Also, check the bid activation status as shown below.

      Checking the Bid Activation

      -

      Once your deploy processes, you can check your bid again. You should now see "inactive": false in the output.

      -

      If you wait until the next Era starts, you should also see your public key as a future validator on the Validators tab.

    +

    Once your deploy processes, you can check your bid again. You should now see "inactive": false in the output.

    +

    If you wait until the next Era starts, you should also see your public key as a future validator on the Validators tab.

    \ No newline at end of file diff --git a/operators/becoming-a-validator/unbonding/index.html b/operators/becoming-a-validator/unbonding/index.html index f913d7bd3..6ab251cdb 100644 --- a/operators/becoming-a-validator/unbonding/index.html +++ b/operators/becoming-a-validator/unbonding/index.html @@ -1,21 +1,21 @@ - + -Unbonding | Casper Docs - Redux +Unbonding | Casper Docs - Redux - - + +
    Version: 1.5.X

    Unbonding as a Validator

    + submit an issue on Github
    Version: Next

    Unbonding as a Validator

    Once a bid is placed, it will remain in the state of the auction contract, even if the bid fails to win a slot immediately. New slots may become available if bonded validators leave the network or reduce their bond amounts. Therefore, a bid must be explicitly withdrawn to remove it from the auction.

    Method 1: Unbonding with the System Auction Contract

    This method withdraws a bid using the system auction contract. Call the existing withdraw_bid entry point from the system auction contract. Using this method, you do not need to build any contracts, reducing costs and complexity.

    @@ -70,6 +70,6 @@

    C

    Check the auction contract for updates to the bid amounts.

    casper-client get-auction-info --node-address http://<HOST:PORT>

    Unbonding Wait Period

    -

    To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours.

    +

    To prevent long-range attacks, requests to unbond must go through a mandatory wait period, currently set to 7 eras lasting approximately 14-16 hours.

    \ No newline at end of file diff --git a/operators/index.html b/operators/index.html index cb67bc11a..98e51bc98 100644 --- a/operators/index.html +++ b/operators/index.html @@ -1,21 +1,21 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Operators Overview

    + submit an issue on Github
    Version: Next

    Operators Overview

    Operators who wish to run node infrastructure on a Casper network, either as a standalone private network, or as part of the public network should explore this section.

    Prior knowledge of Unix-based operating systems and proficiency with systemd and bash scripting are recommended. If you are unfamiliar with systemd, the Arch Linux page on systemd is a good introduction.

    Operators should know the hardware requirements before running a node.

    @@ -46,6 +46,6 @@ -
    TopicDescription
    Node SetupHow to set up a Casper node
    Becoming a ValidatorHow to join a network and become a validator
    Private Network SetupHow to set up a private Casper network
    MaintenanceTopics related to node maintenance
    +
    TopicDescription
    Node SetupHow to set up a Casper node
    Becoming a ValidatorHow to join a network and become a validator
    Private Network SetupHow to set up a private Casper network
    MaintenanceTopics related to node maintenance
    \ No newline at end of file diff --git a/operators/maintenance/archiving-and-restoring/index.html b/operators/maintenance/archiving-and-restoring/index.html index 3fc3d1a76..573dbad52 100644 --- a/operators/maintenance/archiving-and-restoring/index.html +++ b/operators/maintenance/archiving-and-restoring/index.html @@ -1,21 +1,21 @@ - + -Archive and Restore a DB | Casper Docs - Redux +Archive and Restore a DB | Casper Docs - Redux - - + +
    Version: 1.5.X

    Archiving and Restoring a Database

    + submit an issue on Github
    Version: Next

    Archiving and Restoring a Database

    This documentation describes processes for the compression and decompression of a Casper node database and streaming from a backup location.

    Zstandard is the best method for compression speed and space for the current LMDB-based database system that the casper-node uses.

    note

    The values presented in this document assume that the trie-compact tool was run on a Mainnet database for compression. Contact the support team if you have questions.

    @@ -97,6 +97,6 @@

    Strea

    Starting a New Node with a Decompressed DB

    If you are starting a node with a decompressed DB, you must tell the node to run at the protocol version of the tip of your DB. You can do this most efficiently with the node_util.py script included in the casper-node-launcher installation.

    For example, if you are using a DB archive from node version 1.4.5, you would run this command:

    -
    sudo /etc/casper/node_util.py force_run_version 1_4_5
    +
    sudo /etc/casper/node_util.py force_run_version 1_4_5
    \ No newline at end of file diff --git a/operators/maintenance/index.html b/operators/maintenance/index.html index 0266d896d..cecc86f77 100644 --- a/operators/maintenance/index.html +++ b/operators/maintenance/index.html @@ -1,21 +1,21 @@ - + -Node Maintenance | Casper Docs - Redux +Node Maintenance | Casper Docs - Redux - - + +
    Version: 1.5.X

    Node Maintenance

    + submit an issue on Github
    Version: Next

    Node Maintenance

    This section covers maintenance actions such as moving a node to a different location and restoring a database.

    @@ -34,6 +34,6 @@ -
    TitleDescription
    Archiving and Restoring a DatabaseUsing zstd for the compression and decompression of a Casper node database and streaming from a backup location
    Moving a Validating NodeWays to move a validator node to another machine
    +
    TitleDescription
    Archiving and Restoring a DatabaseUsing zstd for the compression and decompression of a Casper node database and streaming from a backup location
    Moving a Validating NodeWays to move a validator node to another machine
    \ No newline at end of file diff --git a/operators/maintenance/moving-node/index.html b/operators/maintenance/moving-node/index.html index d4762ea28..b701e3b84 100644 --- a/operators/maintenance/moving-node/index.html +++ b/operators/maintenance/moving-node/index.html @@ -1,21 +1,21 @@ - + -Move a Node | Casper Docs - Redux +Move a Node | Casper Docs - Redux - - + +
    Version: 1.5.X

    Moving a Validating Node

    + submit an issue on Github
    Version: Next

    Moving a Validating 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

    @@ -71,6 +71,6 @@

    After swapping, the new validator node shows no round length until an era transition occurs and will lose all rewards from the point of the switch until the end of that era. The validator is not ejected but will receive rewards starting with the next era.

    tip

    You could time the swap right before the era ends to minimize reward losses.

    Checking file permissions

    -

    After the swap, check and fix file permissions by running the /etc/casper/node_util.py utility.

    +

    After the swap, check and fix file permissions by running the /etc/casper/node_util.py utility.

    \ No newline at end of file diff --git a/operators/setup-network/chain-spec/index.html b/operators/setup-network/chain-spec/index.html index 206d91463..b342aff4d 100644 --- a/operators/setup-network/chain-spec/index.html +++ b/operators/setup-network/chain-spec/index.html @@ -1,22 +1,22 @@ - + -The Chainspec | Casper Docs - Redux +The Chainspec | Casper Docs - Redux - - + +
    Version: 1.5.X

    The Blockchain Specification

    -

    The blockchain specification, or chainspec, is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 1.5.2 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring.

    + submit an issue on Github
    Version: Next

    The Blockchain Specification

    +

    The blockchain specification, or chainspec, is a collection of configuration settings describing the network state at genesis and upgrades to basic system functionality (including system contracts and gas costs) occurring after genesis. This page describes each field in the chainspec, based on version 2.0.0 of the Casper node. The chainspec can and should be customized for private networks. The chainspec attributes are divided into categories based on what they are configuring.

    protocol

    These settings describe the active protocol version.

    @@ -44,7 +44,7 @@

    protocolnetwork

    The following settings configure the networking layer.

    @@ -180,7 +180,93 @@

    coreAttributeDescriptionMainnet Settingera_durationEra duration.'120min'minimum_era_heightMinimum number of blocks per era. An era will take longer than era_duration if that is necessary to reach the minimum height.20minimum_block_timeMinimum difference between a block's and its child's timestamp.'16384ms'validator_slotsNumber of slots available in the validator auction.100finality_threshold_fractionA number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.
    It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.
    Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly.[1, 3]start_protocol_version_with_strict
    _finality_signatures_requiredProtocol version from which nodes are required to hold strict finality signatures.'1.5.0'legacy_required_finalityThe finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'.
    Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures.'Strict'auction_delayNumber of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1.1locked_funds_periodThe period after genesis during which a genesis validator's bid is locked.'90days'vesting_schedule_periodThe period in which the genesis validator's bid is released over time after it is unlocked.'13 weeks'unbonding_delayDefault number of eras that need to pass to be able to withdraw unbonded funds.7round_seigniorage_rateRound seigniorage rate represented as a fraction of the total supply.
    - Annual issuance: 8%.
    - Minimum block time: 2^15 milliseconds.
    - Ticks per year: 31536000000.

    (1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:
    Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)[7, 87535408]max_associated_keysMaximum number of associated keys for a single account.100max_runtime_call_stack_heightMaximum height of the contract runtime call stack.12minimum_delegation_amountMinimum allowed delegation amount in motes.500_000_000_000prune_batch_sizeGlobal state prune batch size for tip pruning in version 1.4.15. Possible values:
    - 0 when the feature is OFF
    - Integer if the feature is ON, representing the number of eras to process per block.0strict_argument_checkingEnables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct CLType.falsesimultaneous_peer_requestsNumber of simultaneous peer requests.5consensus_protocolThe consensus protocol to use. Options are 'Zug' or 'Highway'.'Highway'max_delegators_per_validatorThe maximum amount of delegators per validator. If the value is 0, there is no maximum capacity.1200 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    era_durationEra duration.'120 minutes'
    minimum_era_heightMinimum number of blocks per era. An era will take longer than era_duration if that is necessary to reach the minimum height.20
    minimum_block_timeMinimum difference between a block's and its child's timestamp.'16384 ms'
    validator_slotsNumber of slots available in the validator auction.100
    finality_threshold_fractionA number between 0 and 1 representing the fault tolerance threshold as a fraction used by the internal finalizer.
    It is the fraction of validators that would need to equivocate to make two honest nodes see two conflicting blocks as finalized.
    Let's say this value is F. A higher value F makes it safer to rely on finalized blocks. It also makes it more difficult to finalize blocks, however, and requires strictly more than (F + 1)/2 validators to be working correctly.
    [1, 3]
    start_protocol_version_with_strict
    _finality_signatures_required
    Protocol version from which nodes are required to hold strict finality signatures.'1.5.0'
    legacy_required_finalityThe finality required for legacy blocks. Options are 'Strict', 'Weak', and 'Any'.
    Used to determine finality sufficiency for new joiners syncing blocks created in a protocol version before the start protocol version with strict finality signatures.
    'Strict'
    migrate_legacy_accountsIf true, the protocol upgrade will migrate ALL user accounts to addressable entity. If false, user accounts will be left as they are and will be lazily migrated on a per-account basis if / when that account is used during transaction execution.true
    migrate_legacy_contractsIf true, the protocol upgrade will migrate ALL user contracts to addressable entity. If false, user contracts will be left as they are and will be lazily migrated on a per-contract basis if / when that contract is used during transaction execution.true
    auction_delayNumber of eras before an auction defines the set of validators. If a validator bonds with a sufficient bid in era N, it will be a validator in era N + auction_delay + 1.1
    locked_funds_periodThe period after genesis during which a genesis validator's bid is locked.'0 days'
    vesting_schedule_periodThe period in which the genesis validator's bid is released over time after it is unlocked.'0 weeks'
    unbonding_delayDefault number of eras that need to pass to be able to withdraw unbonded funds.7
    round_seigniorage_rateRound seigniorage rate represented as a fraction of the total supply.
    - Annual issuance: 8%.
    - Minimum block time: 2^15 milliseconds.
    - Ticks per year: 31536000000.

    (1+0.08)^((2^15)/31536000000)-1 is expressed as a fractional number below in Python:
    Fraction((1 + 0.08)**((2**15)/31536000000) - 1).limit_denominator(1000000000)
    [7, 175070816]
    max_associated_keysMaximum number of associated keys for a single account.100
    max_runtime_call_stack_heightMaximum height of the contract runtime call stack.12
    minimum_delegation_amountMinimum allowed delegation amount in motes.500_000_000_000
    maximum_delegation_amountMaximum allowed delegation amount in motes.1_000_000_000_000_000_000
    prune_batch_sizeGlobal state prune batch size for tip pruning. Possible values:
    - 0 when the feature is OFF
    - Integer if the feature is ON, representing the number of eras to process per block.
    0
    strict_argument_checkingEnables strict arguments checking when calling a contract; i.e., all non-optional args are provided and they are of the correct CLType.false
    simultaneous_peer_requestsNumber of simultaneous peer requests.5
    consensus_protocolThe consensus protocol to use. Options are 'Zug' or 'Highway'.'Zug'
    max_delegators_per_validatorThe maximum amount of delegators per validator. If the value is 0, there is no maximum capacity.1200
    finders_feeThe split in finality signature rewards between block producer and participating signers.[1, 5]
    finality_signature_proportionThe proportion of baseline rewards going to reward finality signatures specifically.[1, 2]
    signature_rewards_max_delayLookback interval indicating how many past blocks we are looking at to reward.3
    allow_unrestricted_transfersAllows peer to peer transfers between users. Setting this to false makes sense only for private chains.true
    allow_auction_bidsEnables the auction entry points 'delegate' and 'add_bid'. Setting this to false makes sense only for private chains that don't need to auction new validator slots. These auction entry points will return an error if called, when this option is set to false.true
    compute_rewardsIf set to false, then consensus doesn't compute rewards and always uses 0.true
    refund_handlingDefines how refunds of the unused portion of payment amounts are calculated and handled. Valid options are: refund (a ratio of the unspent token is returned to the spender); burn (a ratio of the unspent token is burned); no_refund (no refunds are paid out){ type = 'no_refund' }
    fee_handlingDefines how fees are handled. Valid options are: no_fee (fees are eliminated); pay_to_proposer (fees are paid to the block proposer); accumulate (fees are accumulated in a special purse and distributed at the end of each era evenly among all administrator accounts); burn (fees are burned){ type = 'no_fee' }
    validator_credit_capIf a validator would recieve a validator credit, it cannot exceed this percentage of their total stake.[1, 5]
    pricing_handlingDefines how pricing is handled. Valid options are: classic (senders of transaction self-specify how much they pay); fixed (costs are fixed, per the cost table); reserved (prepaid transaction, currently not supported){ type = 'fixed' }
    allow_reservationsDoes the network allow pre-payment / reservations for future execution? Currently not supported.false
    gas_hold_balance_handlingDefines how gas holds affect available balance calculations. Valid options are: accrued (sum of full value of all non-expired holds) and amortized (sum of each hold is amortized over the time remaining until expiry).{ type = 'accrued' }
    gas_hold_intervalDefines how long gas holds last.'24 hours'
    administratorsList of public keys of administrator accounts. Setting this option makes only on private chains which require administrator accounts for regulatory reasons.[]
    +

    See the Fee Elimination page for more details regarding refund_handling, fee_handling, validator_credit_cap, pricing_handling, gas_hold_balance_handling, and gas_hold_interval.

    highway

    These settings configure the Highway Consensus protocol.

    @@ -198,14 +284,22 @@

    highwaytransactions

    +

    These settings manage transactions and their lifecycle.

    + + + + + + + + -
    AttributeDescriptionMainnet Setting
    maximum_round_lengthHighway dynamically chooses its round length between minimum_block_time and maximum_round_length.'132seconds'
    reduced_reward_multiplierThe factor by which rewards for a round are multiplied if the greatest summit has ≤50% quorum, i.e., no finality. Expressed as a fraction (1/5 by default on Mainnet).[1, 5]
    -

    deploys

    -

    These settings manage deploys and their lifecycle.

    @@ -233,6 +327,9 @@

    deploystransactions.v1

    +

    These settings manage the transaction lanes including both native and Wasm based interactions. See Lanes and gas costs for details.

    @@ -254,6 +351,8 @@

    deploystransactions.deploy

    @@ -276,7 +375,15 @@

    deployswasm

    The following are Wasm-related settings.

    @@ -317,7 +424,7 @@

    wasm.stora -
    AttributeDescriptionMainnet Setting
    gas_per_byteGas charged per byte stored in global state.630_000
    +
    AttributeDescriptionMainnet Setting
    gas_per_byteGas charged per byte stored in global state.1_117_587

    wasm.opcode_costs

    The following settings manage the cost table for Wasm opcodes.

    @@ -502,11 +609,36 @@

    wasm.messages_limits

    +

    The following chainspec settings manage the cost of contract-level messages.

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    AttributeDescriptionMainnet Setting
    max_topic_name_sizeMaximum size of the topic name.256
    max_topics_per_contractMaximum number of topics that can be added for each contract.128
    max_message_sizeMaximum size in bytes of the serialized message payload.1_024

    wasm.host_function_costs

    The following settings specify costs for low-level bindings for host-side ("external") functions. More documentation and host function declarations are located in smart_contracts/contract/src/ext_ffi.rs.

    -
    - add = { cost = 5_800, arguments = [0, 0, 0, 0] }
    - add_associated_key = { cost = 9_000, arguments = [0, 0, 0] }
    - add_contract_version = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
    - blake2b = { cost = 200, arguments = [0, 0, 0, 0] }
    - call_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 420, 0] }
    - call_versioned_contract = { cost = 4_500, arguments = [0, 0, 0, 0, 0, 0, 0, 420, 0] }
    - create_contract_package_at_hash = { cost = 200, arguments = [0, 0] }
    - create_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }
    - create_purse = { cost = 2_500_000_000, arguments = [0, 0] }
    - disable_contract_version = { cost = 200, arguments = [0, 0, 0, 0] }
    - get_balance = { cost = 3_800, arguments = [0, 0, 0] }
    - get_blocktime = { cost = 330, arguments = [0] }
    - get_caller = { cost = 380, arguments = [0] }
    - get_key = { cost = 2_000, arguments = [0, 440, 0, 0, 0] }
    - get_main_purse = { cost = 1_300, arguments = [0] }
    - get_named_arg = { cost = 200, arguments = [0, 0, 0, 0] }
    - get_named_arg_size = { cost = 200, arguments = [0, 0, 0] }
    - get_phase = { cost = 710, arguments = [0] }
    - get_system_contract = { cost = 1_100, arguments = [0, 0, 0] }
    - has_key = { cost = 1_500, arguments = [0, 840] }
    - is_valid_uref = { cost = 760, arguments = [0, 0] }
    - load_named_keys = { cost = 42_000, arguments = [0, 0] }
    - new_uref = { cost = 17_000, arguments = [0, 0, 590] }
    - random_bytes = { cost = 200, arguments = [0, 0] }
    - print = { cost = 20_000, arguments = [0, 4_600] }
    - provision_contract_user_group_uref = { cost = 200, arguments = [0, 0, 0, 0, 0] }
    - put_key = { cost = 38_000, arguments = [0, 1_100, 0, 0] }
    - read_host_buffer = { cost = 3_500, arguments = [0, 310, 0] }
    - read_value = { cost = 6_000, arguments = [0, 0, 0] }
    - read_value_local = { cost = 5_500, arguments = [0, 590, 0] }
    - remove_associated_key = { cost = 4_200, arguments = [0, 0] }
    - remove_contract_user_group = { cost = 200, arguments = [0, 0, 0, 0] }
    - remove_contract_user_group_urefs = { cost = 200, arguments = [0, 0, 0, 0, 0, 0] }
    - remove_key = { cost = 61_000, arguments = [0, 3_200] }
    - ret = { cost = 23_000, arguments = [0, 420_000] }
    - revert = { cost = 500, arguments = [0] }
    - set_action_threshold = { cost = 74_000, arguments = [0, 0] }
    - transfer_from_purse_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0, 0] }
    - transfer_from_purse_to_purse = { cost = 82_000, arguments = [0, 0, 0, 0, 0, 0, 0, 0] }
    - transfer_to_account = { cost = 2_500_000_000, arguments = [0, 0, 0, 0, 0, 0, 0] }
    - update_associated_key = { cost = 4_200, arguments = [0, 0, 0] }
    - write = { cost = 14_000, arguments = [0, 0, 0, 980] }
    - write_local = { cost = 9_500, arguments = [0, 1_800, 0, 520] }
    -

    system_costs

    -

    The following settings manage protocol operating costs.

    @@ -522,7 +654,239 @@

    system_costsAttributeDescriptionMainnet Settingwasmless_transfer_costDefault gas cost for a wasmless transfer.100_000_000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Host-Side FunctionCostArguments
    add5_800[0, 0, 0, 0]
    add_associated_key1_200_000[0, 0, 0]
    add_contract_version200[0, 0, 0, 0, 120_000, 0, 0, 0, 30_000, 0, 0]
    blake2b1_200_000[0, 120_000, 0, 0]
    call_contract300_000_000[0, 0, 0, 120_000, 0, 120_000, 0]
    call_versioned_contract300_000_000[0, 0, 0, 0, 120_000, 0, 120_000, 0]
    create_contract_package_at_hash200[0, 0]
    create_contract_user_group200[0, 0, 0, 0, 0, 0, 0, 0]
    create_purse2_500_000_000[0, 0]
    disable_contract_version200[0, 0, 0, 0]
    get_balance3_000_000[0, 0, 0]
    get_blocktime330[0]
    get_caller380[0]
    get_key2_000[0, 440, 0, 0, 0]
    get_main_purse1_300[0]
    get_named_arg200[0, 120_000, 0, 120_000]
    get_named_arg_size200[0, 0, 0]
    get_phase710[0]
    get_system_contract1_100[0, 0, 0]
    has_key1_500[0, 840]
    is_valid_uref760[0, 0]
    load_named_keys42_000[0, 0]
    new_uref17_000[0, 0, 590]
    random_bytes200[0, 0]
    print20_000[0, 4_600]
    provision_contract_user_group_uref200[0, 0, 0, 0, 0]
    put_key100_000_000[0, 120_000, 0, 120_000]
    read_host_buffer3_500[0, 310, 0]
    read_value60_000[0, 120_000, 0]
    read_value_local5_500[0, 590, 0]
    remove_associated_key4_200[0, 0]
    remove_contract_user_group200[0, 0, 0, 0]
    remove_contract_user_group_urefs200[0, 0, 0, 0, 0, 120_000]
    remove_key61_000[0, 3_200]
    ret23_000[0, 420_000]
    revert500[0]
    set_action_threshold74_000[0, 0]
    transfer_from_purse_to_account2_500_000_000[0, 0, 0, 0, 0, 0, 0, 0, 0]
    transfer_from_purse_to_purse82_000_000[0, 0, 0, 0, 0, 0, 0, 0]
    transfer_to_account2_500_000_000[0, 0, 0, 0, 0, 0, 0]
    update_associated_key4_200[0, 0, 0]
    write14_000[0, 0, 0, 980]
    dictionary_put9_500[0, 1_800, 0, 520]
    enable_contract_version200[0, 0, 0, 0]
    manage_message_topic200[0, 30_000, 0, 0]
    emit_message200[0, 30_000, 0, 120_000]
    cost_increase_per_message50
    +

    system_costs

    +

    The following settings manage protocol operating costs.

    system_costs.auction_costs

    These settings manage the costs of calling the auction system contract entrypoints.

    @@ -605,7 +969,12 @@

    sy -
    AttributeDescriptionMainnet Setting
    get_era_validatorsCost of calling the get_era_validators entrypoint.10_000
    read_seigniorage_recipientsCost of calling the read_seigniorage_recipients entrypoint.10_000
    add_bidCost of calling the add_bid entrypoint.2_500_000_000
    withdraw_bidCost of calling the withdraw_bid entrypoint.2_500_000_000
    delegateCost of calling the delegate entrypoint.2_500_000_000
    undelegateCost of calling the undelegate entrypoint.2_500_000_000
    run_auctionCost of calling the run_auction entrypoint.10_000
    slashCost of calling the slash entrypoint.10_000
    distributeCost of calling the distribute entrypoint.10_000
    withdraw_delegator_rewardCost of calling the withdraw_delegator_reward entrypoint.10_000
    withdraw_validator_rewardCost of calling the withdraw_validator_reward entrypoint.10_000
    read_era_idCost of calling the read_era_id entrypoint.10_000
    activate_bidCost of calling the activate_bid entrypoint.10_000
    redelegateCost of calling the redelegate entrypoint.2_500_000_000
    + + + + + +
    AttributeDescriptionMainnet Setting
    get_era_validatorsCost of calling the get_era_validators entrypoint.10_000
    read_seigniorage_recipientsCost of calling the read_seigniorage_recipients entrypoint.10_000
    add_bidCost of calling the add_bid entrypoint.2_500_000_000
    withdraw_bidCost of calling the withdraw_bid entrypoint.2_500_000_000
    delegateCost of calling the delegate entrypoint.2_500_000_000
    undelegateCost of calling the undelegate entrypoint.2_500_000_000
    run_auctionCost of calling the run_auction entrypoint.10_000
    slashCost of calling the slash entrypoint.10_000
    distributeCost of calling the distribute entrypoint.10_000
    withdraw_delegator_rewardCost of calling the withdraw_delegator_reward entrypoint.10_000
    withdraw_validator_rewardCost of calling the withdraw_validator_reward entrypoint.10_000
    read_era_idCost of calling the read_era_id entrypoint.10_000
    activate_bidCost of calling the activate_bid entrypoint.10_000
    redelegateCost of calling the redelegate entrypoint.2_500_000_000
    change_bid_public_keyCost of calling the change_bid_public_key entrypoint.5_000_000_000

    system_costs.mint_costs

    These settings manage the costs of calling the mint system contract entrypoints.

    @@ -653,7 +1022,12 @@

    syste -
    AttributeDescriptionMainnet Setting
    mintCost of calling the mint entrypoint.2_500_000_000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10_000
    createCost of calling the create entrypoint.2_500_000_000
    balanceCost of calling the balance entrypoint.10_000
    transferCost of calling the transfer entrypoint.10_000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10_000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2_500_000_000
    + + + + + +
    AttributeDescriptionMainnet Setting
    mintCost of calling the mint entrypoint.2_500_000_000
    reduce_total_supplyCost of calling the reduce_total_supply entrypoint.10_000
    createCost of calling the create entrypoint.2_500_000_000
    balanceCost of calling the balance entrypoint.10_000
    burnCost of calling the burn entrypoint.10_000
    transferCost of calling the transfer entrypoint.10_000
    read_base_round_rewardCost of calling the read_base_round_reward entrypoint.10_000
    mint_into_existing_purseCost of calling the mint_into_existing_purse entrypoint.2_500_000_000

    system_costs.handle_payment_costs

    These settings manage the costs of calling entrypoints on the handle_payment system contract.

    @@ -704,6 +1078,6 @@

    +
    AttributeDescriptionMainnet Setting
    payCost of calling the pay entrypoint and sending an amount to a payment purse.10_000
    \ No newline at end of file diff --git a/operators/setup-network/create-private/index.html b/operators/setup-network/create-private/index.html index 40d75b893..8760533eb 100644 --- a/operators/setup-network/create-private/index.html +++ b/operators/setup-network/create-private/index.html @@ -1,21 +1,21 @@ - + -Private Network Setup | Casper Docs - Redux +Private Network Setup | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting Up a Private Casper Network

    + submit an issue on Github
    Version: Next

    Setting Up a Private Casper Network

    Casper private networks operate in a similar way to the Casper public network. The significant difference in private networks is a closed validator set and having administrator account(s) which can control regular accounts. Hence, there are specific configurations when setting up the genesis block and administrator accounts. Besides the main configuration options that the Casper platform provides, each customer may add other configuration options when setting up a private network.

    Contents

      @@ -77,21 +77,22 @@

      [core]
      allow_unrestricted_transfers = false

    In contrast, users in the public network can freely transfer funds to different accounts.

    -
    note

    A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:

    [core]
    allow_unrestricted_transfers = false
    compute_rewards = false
    allow_auction_bids = false
    refund_handling = { type = "refund", refund_ratio = [1, 1] }
    fee_handling = { type = "accumulate" }
    administrators = ["ADMIN_PUBLIC_KEY"]
    +
    note

    A Casper private network doesn't support the minting process. Only admininstrator accounts can maintain funds. This is enabled by configuring these options:

    [core]
    allow_unrestricted_transfers = false
    compute_rewards = false
    allow_auction_bids = false
    refund_handling = { type = "refund", refund_ratio = [1, 1] }
    fee_handling = { type = "accumulate" }
    administrators = ["ADMIN_PUBLIC_KEY"]

    The Casper Mainnet has different refund and fee handling configurations explained in more detail here.

    [core]
    allow_unrestricted_transfers = true
    compute_rewards = true
    allow_auction_bids = true
    refund_handling = { type = 'no_refund' }
    fee_handling = { type = 'no_fee' }
    administrators = []

    Refund handling configuration

    This option manages the refund behavior at the finalization of a deploy execution. It changes the way the Wasm execution fees are distributed. After each deploy execution, the network calculates the amount of gas spent for the execution and manages to refund any remaining tokens to the user.

    A refund_ratio is specified as a proper fraction (the numerator must be lower or equal to the denominator). In the example below, the refund_ratio is 1:1. If 2.5 CSPR is paid upfront and the gas fee is 1 CSPR, 1.5 CSPR will be given back to the user.

    [core]
    refund_handling = { type = "refund", refund_ratio = [1, 1] }
    -

    After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.

    -

    The default configuration for a public chain, including the Casper Mainet, looks like this:

    -
    [core]
    refund_handling = { type = "refund", refund_ratio = [0, 100] }
    -

    The refund variant with refund_ratio of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return.

    +

    Another example: a refund variant with refund_ratio of [0, 100] means that 0% is given back to the user after deducting gas fees. In other words, if a user paid 2.5 CSPR and the gas fee is 1 CSPR, the user will not get the remaining 1.5 CSPR in return.

    +

    After deducting the gas fee, the distribution of the remaining payment amount is handled based on the fee_handling configuration.

    +

    Starting with the Condor release, a Casper private network can eliminate fees and, thus, not require refunds, similar to the Casper Mainnet:

    +
    refund_handling = { type = 'no_refund' }
    fee_handling = { type = 'no_fee' }

    Fee handling configuration

    This option defines how to distribute the fees after refunds are handled. While refund handling defines the amount we pay back after a transaction, fee handling defines the methods of fee distribution after a refund is performed.

    Set up the configuration as below:

    [core]
    fee_handling = { type = "pay_to_proposer" }
    -

    The fee_handling configuration has three variations:

    +

    The fee_handling configuration has four variations:

      +
    • no_fee: Fees are eliminated. No refunds are necessary.
    • pay_to_proposer: The rest of the payment amount after deducing the gas fee from a refund is paid to the block's proposer.
    • burn: The tokens paid are burned, and the total supply is reduced.
    • accumulate: The funds are transferred to a special accumulation purse. Here, the accumulation purse is owned by a handle payment system contract, and the amount is distributed among all the administrators defined at the end of a switch block. The fees are paid to the purse owned by the handle payment contract, and no tokens are transferred to the proposer when this configuration is enabled.
    • @@ -138,7 +139,7 @@

      Casper node setup GitHub guide to know more details about configuring a new node to operate within a network.

      Additionally, refer to the casper-node-launcher to check whether the installed node binaries match the installed configurations by comparing the version numbers.

      Step 6. Rotating the Validator Accounts

      -

      You need to go through setting up a validator node guide before starting this section.

      +

      You need to go through setting up a validator node guide before starting this section.

      To rotate the validators set, you must perform a network upgrade using a global_state.toml with new entries generated by the global-state-update-gen command.

      When rotating validators manually, you will need to do so after the start of a new era. This allows you to obtain the state root hash from the final block in an era, known as the switch block.

      After acquiring the state root hash from the switch block, you must stop the network. The following command allows you to use the acquired state root hash to generate a new global_state.toml.

      @@ -235,6 +236,6 @@

      Ad
      [core]
      administrators = ["NEW_PUBLIC_KEY"]

      After this step, the private network would be ready for use.

      Setting up a Block Explorer

      -

      Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer here.

    +

    Private and hybrid blockchains can find information on how to set up and operate our free version of a block explorer here.

    \ No newline at end of file diff --git a/operators/setup-network/genesis/index.html b/operators/setup-network/genesis/index.html index 9a4146156..8f03b911a 100644 --- a/operators/setup-network/genesis/index.html +++ b/operators/setup-network/genesis/index.html @@ -1,21 +1,21 @@ - + -Genesis | Casper Docs - Redux +Genesis | Casper Docs - Redux - - + +
    Version: Next

    The Genesis Block

    The Casper node software creates a genesis block from the following input files:

    • chainspec.toml
    • @@ -27,6 +27,6 @@

      chainspec.toml

      accounts.toml

      This file contains the genesis validator set information, starting accounts and associated balances and bond amounts.

      If an account is not bonded at genesis, specify a 0 for the bond amount.

      -

      Similar to the chainspec.toml, this is pulled from the appropriate path defined in the network config file used.

    +

    Similar to the chainspec.toml, this is pulled from the appropriate path defined in the network config file used.

    \ No newline at end of file diff --git a/operators/setup-network/index.html b/operators/setup-network/index.html index e7c3ca2cb..884fd80de 100644 --- a/operators/setup-network/index.html +++ b/operators/setup-network/index.html @@ -1,21 +1,21 @@ - + -Setting up Private Networks | Casper Docs - Redux +Setting up Private Networks | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting up Private Networks

    + submit an issue on Github
    Version: Next

    Setting up Private Networks

    Some projects may require a private Casper network or a hybrid setup involving a private and public Casper network. This section covers the requirements for creating a private network.

    @@ -42,6 +42,6 @@ -
    TitleDescription
    The Genesis BlockFiles needed to create a genesis block
    The Chain SpecificationConfiguration settings describing the network state
    Setting up a Private Casper NetworkA step-by-step guide to establishing and configuring a private Casper network
    Staging Files for a New NetworkA guide to hosting protocol files for a new Casper network
    +
    TitleDescription
    The Genesis BlockFiles needed to create a genesis block
    The Chain SpecificationConfiguration settings describing the network state
    Setting up a Private Casper NetworkA step-by-step guide to establishing and configuring a private Casper network
    Staging Files for a New NetworkA guide to hosting protocol files for a new Casper network
    \ No newline at end of file diff --git a/operators/setup-network/staging-files-for-new-network/index.html b/operators/setup-network/staging-files-for-new-network/index.html index 9bd362367..71d4e7142 100644 --- a/operators/setup-network/staging-files-for-new-network/index.html +++ b/operators/setup-network/staging-files-for-new-network/index.html @@ -1,21 +1,21 @@ - + -Staging Files | Casper Docs - Redux +Staging Files | Casper Docs - Redux - - + +
    Version: 1.5.X

    Staging Files for a New Network

    + submit an issue on Github
    Version: Next

    Staging Files for a New Network

    important

    Staging files is not needed for already established running networks.

    Only use these instructions if you are creating a new Casper network and hosting protocol files for this network.

    Hosting Server

    Files for staging protocol versions are hosted on a typical HTTP(S) server.

    @@ -100,6 +100,6 @@

    S

    We will copy bin.tar.gz and config.tar.gz into 1_1_0. Once this is done, we are safe to update protocol_versions by appending 1_1_0 to the end of the file and uploading it into the root of the network directory.

    Any node that runs the following command will get this new upgrade:

    -
    sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>

    +
    sudo -u casper /etc/casper/node_util.py stage_protocols <network.conf>
    \ No newline at end of file diff --git a/operators/setup/basic-node-configuration/index.html b/operators/setup/basic-node-configuration/index.html index 7b99d3cda..a236785e7 100644 --- a/operators/setup/basic-node-configuration/index.html +++ b/operators/setup/basic-node-configuration/index.html @@ -1,21 +1,21 @@ - + -Configuration | Casper Docs - Redux +Configuration | Casper Docs - Redux - - + +
    Version: 1.5.X

    Basic Node Configuration

    + submit an issue on Github
    Version: Next

    Basic Node Configuration

    This page outlines the processes and files involved in setting up a Casper node. For step-by-step node installation instructions, follow the Node Setup guide.

    The Casper Node Launcher

    A node is usually run by executing the casper-node-launcher, which executes the casper-node as a child process and also handles upgrades to bring the node to the latest version released.

    @@ -93,7 +93,7 @@

    /var/lib/
    • data.lmdb - Persistent global state store of the network
    • data.lmbd-lock - Lockfile for the data.lmdb database
    • -
    • storage.lmdb - Persistent store of all other network data, primarily Blocks and Deploys
    • +
    • storage.lmdb - Persistent store of all other network data, primarily Blocks and transactions
    • storage.lmdb-lock - Lockfile for the storage.lmdb database
    • unit_files/ - Folder containing transient caches of consensus information
    @@ -136,12 +136,12 @@

    Networ

    The node requires a publicly accessible IP address. The config_from_example.sh and node_util.py both allow IP for network address translation (NAT) setup. Specify the public IP address of the node. If you use the config_from_example.sh external services are called to find your IP and this is inserted into the config.toml created.

    The following default values are specified in the file if you want to change them:

      -
    • The port that will be used for status and deploys
    • +
    • The port that will be used for status and transactions
    • The port used for networking
    • Known_addresses - these are the bootstrap nodes (there is no need to change these)

    Enabling Speculative Execution

    -

    The speculative_exec endpoint provides a method to execute a Deploy without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the Deploy in question. By default, speculative_exec is disabled on a node.

    +

    The speculative_exec endpoint provides a method to execute a transaction without committing its execution effects to global state. This can be used by developers to roughly estimate the gas costs of sending the transaction in question. By default, speculative_exec is disabled on a node.

    speculative_exec can be enabled within config.toml by changing enable_server to true under the configuration options for the speculative execution JSON-RPC HTTP server.

    Node operators may also change the incoming request port for speculative execution, which defaults to 7778. Further, you can choose to alter the qps_limit and max_body_bytes, which limit the amount and size of requests to the speculative execution server.

    Example Config.toml configuration with speculative execution enabled

    @@ -155,6 +155,6 @@

    Creating Ke
    sudo -u casper casper-client keygen --help

    More about keys and key generation can also be found in /etc/casper/validator_keys/README.md if the casper-node-launcher was installed from the Debian package.

    note

    Save your keys in a secure location, preferably offline.

    -

    To submit a bonding request, you will need to fund your account as well.

    +

    To submit a bonding request, you will need to fund your account as well.

    \ No newline at end of file diff --git a/next/operators/setup/casper-sidecar/index.html b/operators/setup/casper-sidecar/index.html similarity index 61% rename from next/operators/setup/casper-sidecar/index.html rename to operators/setup/casper-sidecar/index.html index ebd572ffb..e3730ceb0 100644 --- a/next/operators/setup/casper-sidecar/index.html +++ b/operators/setup/casper-sidecar/index.html @@ -3,19 +3,19 @@ -Sidecar Setup | Casper Docs - Redux +Sidecar Setup | Casper Docs - Redux - - + +
    Version: Next

    The Casper Sidecar

    + submit an issue on Github
    Version: Next

    The Casper Sidecar

    The Casper Sidecar is an application running alongside the node process. It allows subscribers to monitor a node's event stream, query stored events, and query the node's JSON-RPC API, thus receiving faster responses and reducing the load placed on the node. The Sidecar usually runs on the same machine as the node process, but it can be configured to run remotely if necessary. The Sidecar supports the following functionalities:

    • A server-sent events (SSE) endpoint with an /events endpoint streaming events from all the connected nodes. The Sidecar also stores these events.
    • @@ -70,6 +70,6 @@

      Using the
    • The RESTful endpoint for performing useful queries about the state of the network

    Troubleshooting Tips

    -

    For troubleshooting tips, visit Github.

    +

    For troubleshooting tips, visit Github.

    \ No newline at end of file diff --git a/operators/setup/fast-sync/index.html b/operators/setup/fast-sync/index.html index 150332f5f..c87ad6063 100644 --- a/operators/setup/fast-sync/index.html +++ b/operators/setup/fast-sync/index.html @@ -1,26 +1,26 @@ - + -Fast Sync | Casper Docs - Redux +Fast Sync | Casper Docs - Redux - - + +
    Version: 1.5.X

    Introducing Fast Sync

    -

    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.

    + submit an issue on Github
    Version: Next

    Introducing Fast Sync

    +

    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 transaction 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.

    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 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

    -

    +

    Fast-sync process

    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.

    +

    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.

    \ No newline at end of file diff --git a/operators/setup/hardware/index.html b/operators/setup/hardware/index.html index 92753b109..892b10f09 100644 --- a/operators/setup/hardware/index.html +++ b/operators/setup/hardware/index.html @@ -1,21 +1,21 @@ - + -Hardware | Casper Docs - Redux +Hardware | Casper Docs - Redux - - + +
    Version: 1.5.X

    Recommended Hardware Specifications

    + submit an issue on Github
    Version: Next

    Recommended Hardware Specifications

    System Requirements

    The following hardware specifications are recommended for the Casper Mainnet and Testnet:

      @@ -35,6 +35,6 @@

      System R

      CPU Requirements

      Attempting to run a Casper node on older hardware can result in unexpected crashes. This is due to the CPU not supporting instructions used by our official binaries, including AVX2 and Intel SHA extensions.

      To avoid these issues, we recommend a CPU running AMD Zen, Intel Ice Lake or newer architecture.

      -
      note

      This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question.

    +
    note

    This only applies to official binaries released by Casper. If you are compiling your node from scratch, you may choose to disable the extensions in question.

    \ No newline at end of file diff --git a/operators/setup/index.html b/operators/setup/index.html index 0ab5720ca..496cb6fd8 100644 --- a/operators/setup/index.html +++ b/operators/setup/index.html @@ -1,21 +1,21 @@ - + -Setting up a Node | Casper Docs - Redux +Setting up a Node | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting up a Node

    + submit an issue on Github
    Version: Next

    Setting up a Node

    The prerequisite for becoming a validator is to set up a node and join a network as described here.

    @@ -58,6 +58,14 @@ -
    TitleDescription
    Recommended Hardware SpecificationsSystem requirements for the Casper Mainnet and Testnet
    Basic Node ConfigurationProcesses and files involved in setting up a Casper node
    Node EndpointsPorts for communicating with other nodes and dApps
    Installing a NodeStep-by-step instructions to install a Casper node
    Setting the Open Files LimitRequired setting for the Casper node to run correctly
    Upgrading the NodeBefore joining the network, the node needs to be upgraded
    Joining a Running NetworkSteps to join an existing Casper network
    Setting up a Non-Root UserLogging into the node remotely using a key
    + + + + + + + + +
    TitleDescription
    Recommended Hardware SpecificationsSystem requirements for the Casper Mainnet and Testnet
    Basic Node ConfigurationProcesses and files involved in setting up a Casper node
    Node EndpointsPorts for communicating with other nodes and dApps
    Installing a NodeStep-by-step instructions to install a Casper node
    Setting the Open Files LimitRequired setting for the Casper node to run correctly
    Upgrading the NodeBefore joining the network, the node needs to be upgraded
    Joining a Running NetworkSteps to join an existing Casper network
    Setting up a Non-Root UserLogging into the node remotely using a key
    Node EventsInformation on a node's events stream
    Sidecar SetupAn application allowing subscribers to monitor a node's event stream, query stored events, and query a node’s JSON-RPC API
    \ No newline at end of file diff --git a/operators/setup/install-node/index.html b/operators/setup/install-node/index.html index 466381018..056fb05d8 100644 --- a/operators/setup/install-node/index.html +++ b/operators/setup/install-node/index.html @@ -1,21 +1,21 @@ - + -Installation | Casper Docs - Redux +Installation | Casper Docs - Redux - - + +
    Version: 1.5.X

    Installing a Node

    + submit an issue on Github
    Version: Next

    Installing a Node

    Ensure the requirements listed in the following sections are met before you start setting up the node on the network, either on Mainnet or Testnet.

    Network Requirements

    The following ports are used by the node:

    @@ -104,6 +104,6 @@

    A Note on Speculative Execution

    The speculative_exec_server defaults to off and can be enabled in your Config.toml file.

    -

    While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You should not use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic.

    +

    While this is a useful tool, understand that it is also an attack vector for a node. The intent is for someone to run on their node as a tool. You should not use this if you are an active validator, as requests into this port can block execution_engine processing for legitimate network traffic.

    \ No newline at end of file diff --git a/operators/setup/joining/index.html b/operators/setup/joining/index.html index 51a4dcad5..c95806146 100644 --- a/operators/setup/joining/index.html +++ b/operators/setup/joining/index.html @@ -1,21 +1,21 @@ - + -Join a Network | Casper Docs - Redux +Join a Network | Casper Docs - Redux - - + +
    Version: 1.5.X

    Joining a Running Network

    + submit an issue on Github
    Version: Next

    Joining a Running Network

    Each Casper network is permissionless, enabling new validators to join the network and provide additional security to the system. This page outlines the sequence of recommended steps to spin up a validating node and join an existing network.

    Step 1: Provisioning Hardware

    Visit the Hardware Specifications section and provision your node hardware.

    @@ -31,7 +31,7 @@

    Step
  • Install these prerequisites, which are also listed here.
    • -
    • Rust
    • +
    • Rust
    • CMake
    • pkg-config - On Ubuntu, use sudo apt-get install pkg-config
    • openssl - On Ubuntu, use sudo apt-get install openssl
    • @@ -42,7 +42,7 @@

      Step

      Install the Rust casper-client and fund the keys you will use for bonding.

    • -

      Use the following commands to build the contracts in release mode. Make sure you have installed Rust.

      +

      Use the following commands to build the contracts in release mode. Make sure you have installed Rust.

    • cd casper-node
      make setup-rs
      make build-client-contracts
      @@ -73,6 +73,6 @@

      Step 8: Sending the Bonding Request

      You can submit a bonding request to change your synchronized node to a validating node.

      -

      The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures.

    +

    The bonding request must be sent after the node has synchronized the protocol state and linear blockchain to avoid being ejected for liveness failures.

    \ No newline at end of file diff --git a/operators/setup/node-endpoints/index.html b/operators/setup/node-endpoints/index.html index 032805d46..255ae0c84 100644 --- a/operators/setup/node-endpoints/index.html +++ b/operators/setup/node-endpoints/index.html @@ -1,21 +1,21 @@ - + -Endpoints | Casper Docs - Redux +Endpoints | Casper Docs - Redux - - + +
    Version: 1.5.X

    Node Endpoints

    + submit an issue on Github
    Version: Next

    Node Endpoints

    As specified in the Network Requirements, a Casper node uses specific ports to communicate with client applications and other nodes on the network. Each node has an identity linked with an IP and port pair where the node is reachable. This address is also called an endpoint. The Network Communication page explains how the nodes connect and communicate securely. Node connections are established using TLS, presenting a client certificate to encrypt peer-to-peer communication.

    This document describes in more detail a Casper node's default endpoints:

    +
    \ No newline at end of file diff --git a/operators/setup/node-events/index.html b/operators/setup/node-events/index.html new file mode 100644 index 000000000..f6bd2ebb7 --- /dev/null +++ b/operators/setup/node-events/index.html @@ -0,0 +1,35 @@ + + + + + +Node Events | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    The Node's Event Stream

    +

    Each Casper node streams events through the SSE (Server Sent Event) server via an /events endpoint and the port specified as the event_stream_server.address in the node's config.toml. This port is by default 9999 for nodes on Testnet and Mainnet.

    +

    Monitoring a Node's Event Stream

    +

    As an operator, you can use cURL to monitor the event stream on a node.

    +
    curl -s http://HOST:PORT/events/
    +
      +
    • HOST - The IP address of a node on the network.
    • +
    • PORT - The port specified as the event_stream_server.address in the node's config.toml.
    • +
    +

    Another helpful tool is the Casper Sidecar, which provides the recommended way to monitor events on a node. Visit the Casper Sidecar Usage Guide for a detailed list of events and REST queries you can use to monitor the node and the state of the network.

    +

    Replaying the Event Stream

    +

    This command will replay the event stream from an old event onward. If the ID is 0 or if you specify an event ID already purged from the cache, the server will replay all the cached events. Replace the HOST, PORT, and ID fields with the needed values.

    +
    curl -sN http://HOST:PORT/events?start_from=ID
    +

    Example:

    +
    curl -sN http://65.21.235.219:9999/events?start_from=29267508
    +
    note

    The node stores only a limited number of events in its cache, which can be configured using the event_stream_buffer_length in the config.toml. The intended use case is to allow the Sidecar consuming the event stream to reconnect (if it loses its connection) and catch up with the events emitted while it was disconnected.

    The Casper Sidecar may store additional events depending on how it was configured.

    + + \ No newline at end of file diff --git a/operators/setup/non-root-user/index.html b/operators/setup/non-root-user/index.html index c1d557bad..6daa3d0f5 100644 --- a/operators/setup/non-root-user/index.html +++ b/operators/setup/non-root-user/index.html @@ -1,21 +1,21 @@ - + -Non-Root Users | Casper Docs - Redux +Non-Root Users | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting up a Non-Root User

    + submit an issue on Github
    Version: Next

    Setting up a Non-Root User

    Operators may log into their servers remotely using a key. The following steps explain how to create a non-root user and log in using a private key instead of the root user. Replace <username> in the instructions below with your username.

    1. @@ -52,6 +52,6 @@
    ssh -i <your ssh private key> <username>@<server ip>

    Here is an example command:

    -
    ssh -i ~/.ssh/id_rsa casper@10.21.10.200
    +
    ssh -i ~/.ssh/id_rsa casper@10.21.10.200
    \ No newline at end of file diff --git a/operators/setup/open-files/index.html b/operators/setup/open-files/index.html index 822822816..539a42230 100644 --- a/operators/setup/open-files/index.html +++ b/operators/setup/open-files/index.html @@ -1,21 +1,21 @@ - + -Open Files Limit | Casper Docs - Redux +Open Files Limit | Casper Docs - Redux - - + +
    Version: 1.5.X

    Setting the Open Files Limit

    + submit an issue on Github
    Version: Next

    Setting the Open Files Limit

    When the casper-node launches, it tries to set the maximum open files limit (nofile) for the process to 64000. With some systems, this limit will be larger than the default hard limit of 4096.

    The node software uses file handles for both files and network connections. Since network connections are unpredictable, running out of file handles can stop critical file writes from occurring. Therefore, the default nofile limit needs to be increased.

    With the casper-node-launcher running, you can see what the system allocated by finding the process ID (PID) for the casper-node with the following command.

    @@ -52,6 +52,6 @@

    Updatin

    It is possible to persist the nofile limit across server reboots, casper-node-launcher restarts, and protocol upgrades, by adding the nofile setting for the casper user in /etc/security/limits.conf.

    Add the following row to the bottom of the /etc/security/limits.conf file:

    casper          hard    nofile          64000
    -

    Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct nofile setting.

    +

    Afterward, log out of any shells to enable this change. Restarting the node should maintain the correct nofile setting.

    \ No newline at end of file diff --git a/operators/setup/upgrade/index.html b/operators/setup/upgrade/index.html index 26e37dcee..32abfe5b0 100644 --- a/operators/setup/upgrade/index.html +++ b/operators/setup/upgrade/index.html @@ -1,21 +1,21 @@ - + -Upgrades | Casper Docs - Redux +Upgrades | Casper Docs - Redux - - + +
    Version: 1.5.X

    Upgrading the Node

    + submit an issue on Github
    Version: Next

    Upgrading the Node

    The chainspec.toml contains a section to indicate from which era the given casper-node version should start running.

    [protocol]
    # This protocol version becomes active at the start of this era.
    activation_point = 100

    At every block finalization, the casper-node looks for newly configured versions. When a new version is configured, the running node will look at future era_id in the chainspec.toml file. This will be the era before where the current casper-node will cleanly shut down.

    @@ -35,6 +35,6 @@

    You should expect this output if properly staged, prior to upgrading:

    $ curl -s localhost:8888/status | jq .next_upgrade
    {
    "activation_point": 4968,
    "protocol_version": "1.4.6"
    }

    If you see null after waiting for a few minutes, then your upgrade staging was not executed successfully.

    -

    Note: The protocol version will change as per the next upgrade available.

    +

    Note: The protocol version will change as per the next upgrade available.

    \ No newline at end of file diff --git a/resources/advanced/list-auth-keys-tutorial/index.html b/resources/advanced/list-auth-keys-tutorial/index.html index af2afd87b..ff4fa5a4e 100644 --- a/resources/advanced/list-auth-keys-tutorial/index.html +++ b/resources/advanced/list-auth-keys-tutorial/index.html @@ -1,37 +1,37 @@ - + -Authorization Keys | Casper Docs - Redux +Authorization Keys | Casper Docs - Redux - - + +
    Version: 1.5.X

    Working with Authorization Keys

    + submit an issue on Github
    Version: Next

    Working with Authorization Keys

    caution

    These examples should not be used in a production environment. They are intended only for teaching and must be tested and adapted for production use.

    This tutorial demonstrates retrieving and using the authorization keys associated with a deploy using the list_authorization_keys function.

    let authorization_keys = runtime::list_authorization_keys();
    -

    Remember that authorization keys are listed under a Deploy's approvals section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:

    +

    Remember that authorization keys are listed under a Deploy's approvals section, which lists the signatures and the public keys of the signers, also called authorizing keys. Here is an example of a deploy's approvals:

    "approvals": [
    {
    "signer": "02021a4da3d6f32ea3ebd2519e1a37a1b811671085bf4f1cf2a36b931344a99b756a",
    "signature": "02df8cdf0bff3bd93e831d24563d5acbefa0ed13814550e910d03208d5fb3c11770dd3d918784ec84342e53666eacf59aeecbf4ce0cdd60e167c4a4b20e4b8f481"
    }
    ]

    The contract code in this example retrieves the set of authorization keys for a given deploy by calling the runtime::list_authorization_keys function. In other words, list_authorization_keys returns the set of account hashes representing the keys used to sign a deploy. Upon installation, the contract code stores the authorization keys for the installer deploy into a NamedKey. The contract also contains an entry point that returns the intersection of the caller deploy's, and installer deploy's authorization keys. The tests in this repository verify different scenarios and check the resulting intersection.

    Prerequisites

    @@ -66,7 +66,7 @@

    cont

    The intersection result is a list stored under a named key of the account calling the contract_call.wasm.

    let key_name: String = runtime::get_named_arg(ARG_KEY_NAME);
    let intersection =
    runtime::call_contract::<Vec<AccountHash>>(contract_hash, ENTRY_POINT, runtime_args! {});
    runtime::put_key(&key_name, storage::new_uref(intersection).into());
    }
    -

    Testing this example

    +

    Testing this example

    This section highlights the tests written for this example, demonstrating the usage of authorization keys. The tests are divided into three parts:

    • Testing the contract installation
    • @@ -233,6 +233,6 @@

      final test in this tutorial checks that when there is no intersection between the caller deploy's authorization keys (account_addr_1, account_addr_2) and the installer deploy's authorization keys (DEFAULT_ACCOUNT_ADDR), the entry point returns an error.

      -
       let session_code = PathBuf::from(CONTRACT_CALL_WASM);

      let session_args = runtime_args! {
      ARG_CONTRACT_HASH => Key::from(contract_hash),
      ARG_KEY_NAME => INTERSECTION_RECEIPT
      };

      // account_addr_2 as an associated key is not among the default account's associated keys
      // The deploy will therefore revert with PermissionDenied
      let entry_point_deploy_item = DeployItemBuilder::new()
      .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
      .with_authorization_keys(&[account_addr_1, account_addr_2])
      .with_address(account_addr_1)
      .with_session_code(session_code, session_args)
      .build();

      let entry_point_request =
      ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

      builder.exec(entry_point_request).commit().expect_failure();

      let error = builder.get_error().expect("must have User error: 0");
      assert_expected_error(
      error,
      0,
      "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",
      );

    +
     let session_code = PathBuf::from(CONTRACT_CALL_WASM);

    let session_args = runtime_args! {
    ARG_CONTRACT_HASH => Key::from(contract_hash),
    ARG_KEY_NAME => INTERSECTION_RECEIPT
    };

    // account_addr_2 as an associated key is not among the default account's associated keys
    // The deploy will therefore revert with PermissionDenied
    let entry_point_deploy_item = DeployItemBuilder::new()
    .with_empty_payment_bytes(runtime_args! {ARG_AMOUNT => *DEFAULT_PAYMENT})
    .with_authorization_keys(&[account_addr_1, account_addr_2])
    .with_address(account_addr_1)
    .with_session_code(session_code, session_args)
    .build();

    let entry_point_request =
    ExecuteRequestBuilder::from_deploy_item(entry_point_deploy_item).build();

    builder.exec(entry_point_request).commit().expect_failure();

    let error = builder.get_error().expect("must have User error: 0");
    assert_expected_error(
    error,
    0,
    "should fail execution since ACCOUNT_USER_2 as associated key is not in installer (DEFAULT_ACCOUNT_ADDR) associated keys",
    );
    \ No newline at end of file diff --git a/resources/advanced/multi-sig/index.html b/resources/advanced/multi-sig/index.html index 1a46d509f..9ec638c8b 100644 --- a/resources/advanced/multi-sig/index.html +++ b/resources/advanced/multi-sig/index.html @@ -1,22 +1,22 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: 1.5.X

    The Native Multi-Signature Feature

    + submit an issue on Github
    Version: Next

    The Native Multi-Signature Feature

    In this tutorial, you will use Casper's permissions model to integrate key management on Casper accounts and sign deploys with multiple keys. The corresponding GitHub respository is here.

    -

    The additional examples present use cases where Casper's multi-signature feature would be helpful.

    +

    The additional examples present use cases where Casper's multi-signature feature would be helpful.

    \ No newline at end of file diff --git a/resources/advanced/multi-sig/multi-sig-workflow/index.html b/resources/advanced/multi-sig/multi-sig-workflow/index.html index ff8fd2e64..605a5ab73 100644 --- a/resources/advanced/multi-sig/multi-sig-workflow/index.html +++ b/resources/advanced/multi-sig/multi-sig-workflow/index.html @@ -1,21 +1,21 @@ - + -Multi-Sig Workflow | Casper Docs - Redux +Multi-Sig Workflow | Casper Docs - Redux - - + +
    Version: 1.5.X

    Multi-Signature Workflow

    + submit an issue on Github
    Version: Next

    Multi-Signature Workflow

    The purpose of this tutorial is to provide an example of how to integrate key management on Casper accounts. This guide assumes previous completion of the Two-Party Multi-Signature Deploys tutorial, among other prerequisites. You will also need the Casper CLI client to use the make-deploy, sign-deploy, and send-deploy Casper CLI client commands.

    warning

    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.

    Prerequisites

    @@ -325,6 +325,6 @@

    R
    Threshold / KeyPrevious weightCurrent weight
    deployment12
    key_management13
    Primary key (1ed5...)13
    Associated key (04a9...)11
    Associated key (e2d0...)11
    Associated key (1fed...)1N/A (Removed)

    Next Steps

    -

    The next section contains additional examples where Casper's multi-signature feature would be helpful.

    +

    The next section contains additional examples where Casper's multi-signature feature would be helpful.

    \ No newline at end of file diff --git a/resources/advanced/multi-sig/other-scenarios/index.html b/resources/advanced/multi-sig/other-scenarios/index.html index be31b2dac..450990466 100644 --- a/resources/advanced/multi-sig/other-scenarios/index.html +++ b/resources/advanced/multi-sig/other-scenarios/index.html @@ -1,21 +1,21 @@ - + -Additional Examples | Casper Docs - Redux +Additional Examples | Casper Docs - Redux - - + +
    Version: 1.5.X

    Additional Examples

    + submit an issue on Github
    Version: Next

    Additional Examples

    This section presents examples of single and multi-signature schemes, where accounts have multiple associated keys and thresholds for signing transactions.

    Example 1: An account with a single (primary) key

    In this example, only one key (account-hash-a1…) can sign transactions in the name of this account. This key is the primary key of the account and has a weight equal to 1. For deployments or key management, the weight required is also 1. Therefore, the key meets the deployment and key management thresholds and can perform both actions.

    @@ -36,6 +36,6 @@

    Example 5: Recovering a lost primary key

    This account has a primary key with a weight of 3, equal to the key management threshold, and three associated keys with a cumulative weight of 3. Two associated keys can combine their weight to sign deploys. All three associated keys can combine their weight to make account updates. If the primary key is lost or compromised, the associated keys can remove it and secure the account.

    Account details in example 5:

    -
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-d4…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    +
    "Account": {
    "account_address": "account-hash-a1…",
    "action_thresholds": {
    "deployment": 2,
    "key_management": 3
    },
    "associated_keys": [
    {
    "account_address": "account-hash-a1…", // primary key
    "weight": 3
    },
    {
    "account_address": "account-hash-b2…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-c3…", // associated key
    "weight": 1
    },
    {
    "account_address": "account-hash-d4…", // associated key
    "weight": 1
    }
    ],
    "main_purse": "uref-1234…",
    "named_keys": []
    }
    \ No newline at end of file diff --git a/resources/beginner/counter-testnet/commands/index.html b/resources/beginner/counter-testnet/commands/index.html index fc018354a..e7af4595e 100644 --- a/resources/beginner/counter-testnet/commands/index.html +++ b/resources/beginner/counter-testnet/commands/index.html @@ -1,21 +1,21 @@ - + -Casper-Client Commands | Casper Docs - Redux +Casper-Client Commands | Casper Docs - Redux - - + +
    Version: Next

    Casper-Client Commands

    State Root Hash

    casper-client get-state-root-hash --node-address [NODE_SERVER_ADDRESS]

    Example:

    @@ -46,6 +46,6 @@

    tutorial walkthrough. However, these will be different when you write your contracts.

    Get Deploys (from the Chain)

    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    -

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    \ No newline at end of file diff --git a/resources/beginner/counter-testnet/overview/index.html b/resources/beginner/counter-testnet/overview/index.html index 3643ce7dd..06620c2d6 100644 --- a/resources/beginner/counter-testnet/overview/index.html +++ b/resources/beginner/counter-testnet/overview/index.html @@ -1,23 +1,23 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: Next

    Overview

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    -

    image

    +

    image

    \ No newline at end of file diff --git a/resources/beginner/counter-testnet/walkthrough/index.html b/resources/beginner/counter-testnet/walkthrough/index.html index 77e448b6c..d3a91e905 100644 --- a/resources/beginner/counter-testnet/walkthrough/index.html +++ b/resources/beginner/counter-testnet/walkthrough/index.html @@ -1,21 +1,21 @@ - + -Tutorial Walkthrough | Casper Docs - Redux +Tutorial Walkthrough | Casper Docs - Redux - - + +
    Version: Next

    Tutorial Walkthrough

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    Clone the Repository

    First, you will need to clone the counter contract repository on our local machine.

    @@ -59,16 +59,6 @@

    View

    Next, get the state-root-hash:

    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777

    You need to use the IP address of one of the connected peers on the Testnet as the node server since the network is running in a decentralized fashion. Make a note of the returned state root hash, but keep in mind that this hash value will need to be updated every time you modify the network state.

    -

    Please be mindful of the node address format when using the casper-client get-state-root-hash command.

    -

    While browsing the connected peers list, you might encounter entries similar to 44.222.236.237:35000. These entries only provide the IP address and port used for peer-to-peer communication within the network.

    -

    For the casper-client get-state-root-hash command, you need to modify the address slightly:

    -
      -
    1. Add the http:// prefix: This indicates that you're communicating with the node using the HTTP protocol.
    2. -
    3. Replace the port: While the peers list might show a different port (e.g., 35000), the Casper node uses port 7777 for state queries.
    4. -
    -

    Following these steps, the correct command format for your example address would be:

    -
    casper-client get-state-root-hash --node-address http://44.222.236.237:7777
    -

    Remember to apply this modification to any node address you use with the get-state-root-hash command.

    Finally, query the actual state:

    casper-client query-global-state \
    --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]

    Substitute the state root hash and account hash values you just retrieved into this command and execute it. Do not be surprised if you see nothing on the network. That is because you have not sent anything to the network yet.

    @@ -114,13 +104,13 @@

    Increment the Counter Again

    If you recall, in the repository there is session code called counter-call. Try to increment the count using that session code instead of the session entry-point used above.

    Keep in mind, this is another put-deploy call just like when you installed the contract. The session-path is once again going to be different for you depending on where you compiled the contract.

    -
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./counter-call/target/wasm32-unknown-unknown/release/counter-call.wasm
    +
    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name casper-test \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path ./counter/target/wasm32-unknown-unknown/release/counter-call.wasm

    View the Final Network State

    To make sure that the session code ran successfully, get the new state root hash and query the network.

    casper-client get-state-root-hash --node-address http://[NODE_IP]:7777

    Get the network state, specifically for the count variable this time:

    casper-client query-global-state --node-address http://[NODE_IP]:7777 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"

    If all went according to plan, your count value should be 2 at this point.

    -

    Congratulations on building, installing, and using a smart contract on the Testnet!

    +

    Congratulations on building, installing, and using a smart contract on the Testnet!

    \ No newline at end of file diff --git a/resources/beginner/counter/commands/index.html b/resources/beginner/counter/commands/index.html index 42dbe7abe..9cdfbd20c 100644 --- a/resources/beginner/counter/commands/index.html +++ b/resources/beginner/counter/commands/index.html @@ -1,21 +1,21 @@ - + -Casper-Client Commands | Casper Docs - Redux +Casper-Client Commands | Casper Docs - Redux - - + +
    Version: Next

    Casper-Client Commands

    Faucet Account Information

    nctl-view-faucet-account

    This command is part of NCTL and provides a view into the faucet account details. The faucet is the default account created on the network. Generally on the Mainnet, your own account is used to fund transactions. However, for the sake of this tutorial, you do not need accounts and will use the faucet to execute deploys. This command supplies two key pieces of information: the account's secret key location and the account hash, which are used to sign deploys and query the network state, respectively.

    @@ -46,6 +46,6 @@

    tutorial walkthrough. However, these will be different when you write your contracts.

    Get Deploys (from the Chain)

    casper-client get-deploy \
    --node-address [NODE_SERVER_ADDRESS] \
    [DEPLOY_HASH]
    -

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    +

    The get-deploy command is complementary to the put-deploy command. It retrieves a deploy from the network and allows you to check the status of the deploy. The DEPLOY_HASH is the identifier to a specific deploy and is returned by the put-deploy command.

    \ No newline at end of file diff --git a/resources/beginner/counter/overview/index.html b/resources/beginner/counter/overview/index.html index 1a2f6173d..dc76e2d5d 100644 --- a/resources/beginner/counter/overview/index.html +++ b/resources/beginner/counter/overview/index.html @@ -1,23 +1,23 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: Next

    Overview

    This flowchart outlines the process you will go through in this tutorial. Since there are quite a few things taking place, you must keep in mind the overall flow as you proceed through the tutorial on your own.

    To summarize the flowchart, this tutorial will walk you through installing a contract on the blockchain and then calling two separate contract entry points to increment a counter variable. Along the way, you will learn how to query the network state to see when the network has successfully incremented the counter.

    -

    image

    +

    image

    \ No newline at end of file diff --git a/resources/beginner/counter/walkthrough/index.html b/resources/beginner/counter/walkthrough/index.html index 6514bd375..88e26fa82 100644 --- a/resources/beginner/counter/walkthrough/index.html +++ b/resources/beginner/counter/walkthrough/index.html @@ -1,67 +1,47 @@ - + -Tutorial Walkthrough | Casper Docs - Redux +Tutorial Walkthrough | Casper Docs - Redux - - + +
    Version: Next

    Tutorial Walkthrough

    Now that you are familiar with the basic commands, you can begin the tutorial walkthrough.

    Clone the Repository

    First, you will need to clone the counter contract repository on our local machine.

    git clone https://github.com/casper-ecosystem/counter
    -

    If you explore the source code, you will see that there are three versions of the counter contract and one file with session code that calls the contract's entry-points:

    +

    If you explore the source code, you will see that there are two versions of the counter contract and one file with session code that calls the contract's entry-points:

    • -

      contract-v1

      +

      contract-v1

      • This is the first version of the counter contract.
      • -
      • It defines two named keys: -
          -
        • counter: References the contract itself.
        • -
        • count: Stores the current counter value.
        • -
        -
      • -
      • It provides functions for: -
          -
        • get_count: Retrieves the current counter value.
        • -
        • counter_inc: Increments the counter value by 1.
        • -
        -
      • +
      • Defines two named keys: counter to reference the contract and an associated variable count to store a value.
      • +
      • Provides a function to get the current count (count_get).
      • +
      • Provides a function to increment the current count (counter_inc).
    • -

      contract-v2 (Not Used in This Tutorial)

      +

      contract-v2

        -
      • An extension of contract-v1. It demonstrates decrementing the counter and contract upgrades.
      • -
      -
    • -
    • -

      **contract-v3 ** (Not Used in This Tutorial)

      -
        -
      • This version showcases how to add new functionalities during smart contract upgrades. It extends contract-v1 and contract-v2 by introducing: -
          -
        • A new named key: last_updated_at - Tracks the timestamp of the last counter update.
        • -
        • A new entry point: get_last_updated_at - Retrieves the last_updated_at timestamp.
        • -
        -
      • -
      • It focuses on the process of adding new fields like last_updated_at to existing contracts.
      • +
      • This is a second version of the counter contract, which will not be used in this tutorial.
      • +
      • This version provides an additional function to decrement the counter and to demonstrate contract upgrades in another tutorial.
    • -

      counter-call

      +

      counter-call

        -
      • Session code that retrieves the specific contract version (e.g., contract-v1), interacts with its functions (e.g., get_count, counter_inc), and verifies the expected behavior.
      • +
      • This is session code that retrieves the contract-v1 contract, gets the current count value, increments it, and ensures the count was incremented by 1.
    @@ -136,6 +116,6 @@

    Get the network state, specifically for the count variable this time:

    casper-client query-global-state --node-address http://localhost:11101 \
    --state-root-hash [STATE_ROOT_HASH]
    --key [ACCOUNT_HASH] -q "counter/count"

    If all went according to plan, your count value should be 2 at this point.

    -

    Congratulations on building, installing, and using a smart contract on your local network!

    +

    Congratulations on building, installing, and using a smart contract on your local network!

    \ No newline at end of file diff --git a/resources/build-on-casper/casper-open-source-software/index.html b/resources/build-on-casper/casper-open-source-software/index.html index 79399fe0e..63f3d50a8 100644 --- a/resources/build-on-casper/casper-open-source-software/index.html +++ b/resources/build-on-casper/casper-open-source-software/index.html @@ -1,21 +1,21 @@ - + -Open-Source Software | Casper Docs - Redux +Open-Source Software | Casper Docs - Redux - - + +
    Version: 1.5.X

    Ecosystem Open-Source Software

    + submit an issue on Github
    Version: Next

    Ecosystem Open-Source Software

    This page lists open-source software available within the Casper ecosystem. Developers and the community may use the listed software as a basis for new projects and solutions.

    @@ -526,6 +526,6 @@ -
    NameDescriptionAuthorLanguageLicenseLast Update DateType
    Basic Yield FarmStaking RewardsRengo LabsRustApache-2.0 license2022-06-24Staking
    Blockcerts on CasperIssues Blockcerts using the Bitcoin, Ethereum, or Casper blockchainamazanzanPythonMIT license2022-07-22Tokens
    BlockMatcher Frontend BackendPrivate Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches.LedgerLeapJavaScript-PHPMIT license2022-01-15Exchange
    Camel CasperApache Camel connector for the Casper BlockchainM.AbahmaneJavaMIT license2022-03-26Tools
    Casper .NET SDKCasper .NET Client SDK to interact with Casper network nodes via RPC.MAKE Software.NETApache-2.0 license2022-04-19Client SDK
    Casper Analytics AppCasper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod Appcaspercommunity.ioPHPMIT license2022-01-20Tools
    Casper C++ SDKC++ library to interact with Casper network nodes via RPCYusuf KetenC++Apache-2.0 license2022-09-13Client SDK
    Casper CalculatorCasper Earnings Calculator and Node MonitorCharles NguyenJavaScriptMIT license2021-09-26Tools
    Casper Contract UpgradeExample contract to demonstrate the general way of upgrading a contract and the necessary stepsCasper LabsRustApache-2.0 license2022-06-21Example Contracts
    Casper Dart SDKCasper Dart SDK is for interacting with the Casper Blockchain using RPC.TemiltasDartApache-2.0 license2022-06-26Client SDK
    Friendly Market's Casper variant of ERC20Implementation of the ERC20 standard for Casper networksFriendly MarketRustApache-2.0 license2022-08-10Tokens
    Casper Go SDKCasper Go SDKMAKE SoftwareGoApache-2.0 license2023-06-01Client SDK
    Casper Hello World ContractThis example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKeyCasper LabsRustNA2022-07-13Example contracts
    Casper JavaScript SDKCasper Client JavaScript SDKCasper LabsTypeScript-JavaScriptApache-2.0 license2022-09-13Client SDK
    Casper Kotlin SDKCasper Kotlin Client SDK to interact with a Casper network.tqhuy2018KotlinMIT license2022-07-21Client SDK
    Casper MetricsCasper Metrics - fast blockchain crawler, API, and analysis toolA3MCTypeScriptMIT license2022-09-09Tools
    Casper NCTL DockerA Docker container that runs Casper NCTL as a serviceMAKE SoftwareShellApache-2.0 license2022-03-17Tools
    Casper Node-REDNodes to communicate with the Casper's Blockchain using node-redcaspercommunity.ioJavaScriptMIT license2022-02-08Tools
    Casper Objective-C SDKCasper Objective-C SDK is for interacting with the Casper Blockchain using RPC.hienbui9999Objective-CMIT license2022-06-18Client SDK
    Casper PHP SDKPHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHPMAKE SoftwarePHPApache-2.0 license2022-06-29Client SDK
    Casper Ruby Client SDKRuby SDK to interact with Casper network nodes via RPC.Sait GulmezRubyApache-2.0 license2022-03-08Client SDK
    Casper Scala SDKCasper Scala client SDK to interact with the Casper Network nodes via RPCM.AbahmaneScalaMIT license2022-03-23Client SDK
    Casper WalletA browser wallet for the Casper NetworkMAKE SoftwareTypeScript-JavaScriptApache-2.0 license2023-04-12Wallet
    Casper SSI Web AppCasper SSI Framework in the form of a demo web application.Credentia NetworkTypeScriptMIT license2022-06-29Tools
    Casper StorageCasper storage - HD walletsCasperDashTypeScriptApache-2.0 license2022-09-14Wallet
    Casper Swift SDKCasper Client SDK. Casper SDK methods implementation in Swift.hienbui9999SwiftMIT license2022-06-08Client SDK
    Casper Two-Party MultiSig ContractThis example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys.Casper LabsRustNA2022-04-26Example contracts
    Casper WorldCasper network status and decentralization map web applicationNodes GuruTypeScriptMIT license2022-01-26Blockchain Explorer
    CasperDash WalletA non-custodial wallet for the Casper blockchainCasperDashJavaScriptMIT license2022-09-14Wallet
    CasperFYRE APIDispensory API interface for Casper MainnetLedgerLeapJavaScript-PHPApache-2.0 license2022-09-06Tools
    CasperHoldersFirst 3rd party UI to interact with Casper BlockchainCasperHoldersJavaScriptApache-2.0 license2022-08-23Blockchain Explorer
    CasperSignThe First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper BlockchainChronoLogic and Digital StrategiesTypeScriptNA2022-08-31dApp
    CEP-78 Enhanced NFT StandardStandard Contract Generator for NFTsCasper LabsRustApache-2.0 license2022-08-23NFT
    CES Rust Event EmitterRust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)MAKE SoftwareRustApache-2.0 license2023-05-11dApp library
    CES JS ParserJS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareJavaScriptApache-2.0 license2023-03-27dApp library
    CES Go ParserGo library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareGoApache-2.0 license2023-06-02dApp library
    Clearest StakeStaking Asset Manager for Node operators and groupsLedgerLeapPHPApache-2.0 license2022-04-02DeFi
    DAO ContractsSmart Contracts for the MVPR On-Chain Governance System on CasperMAKE SoftwareRustApache-2.0 license2022-07-17DAO
    DHF PAYThe crypto currency payment gateway on the CSPR blockchainDHFinanceTypeScriptApache-2.0 license2022-08-28Payments
    DLN DAODLN DAOAlphaFinTypeScriptMIT license2022-09-10DAO
    DotOracleRealtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains.DotOracle NetworkTypeScriptNA2022-09-26Bridge
    Dragon’s Lair Style StakingLair Style StakingRengo LabsRustApache-2.0 license2022-06-24Staking
    Subscription BillingERC-1337 subscription billingRengo LabsRustMIT license2022-04-07Tokens
    Casper Fungible TokenImplementation of Fungible Tokens for Casper networksCasper LabsRustApache-2.0 license2022-09-01Tokens
    Advanced Fungible TokenERC-777 + 1820 Advanced Fungible Token with Callbacks & Self IdentificationRengo LabsRustApache-2.0 license2022-08-16Tokens
    Helper BotHelper bot for improving DevDao VAs productivityA3MCTypeScriptMIT license2022-08-19Tools
    Java SDKCasper Client Java SDKSyntiFiJavaApache-2.0 license2021-04-20Client SDK
    KYC Proxy ContactThis is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)Casper LabsRustNA2022-07-01Example contracts
    LiquidNFTNFT Collateralized LoansRengo LabsJavaScriptGNU General Public License v3.02022-09-15NFT
    Payment Example ContractThis example demonstrates the usage of purses to transfer motes inside a contractCasper LabsRustNA2022-06-22Example contracts
    ServicesDAOThe ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR.Ekon YazilimHTML-CSS-C#MIT license2022-09-13DAO
    Uniswap DemoAppUniswap UI + ContractsRengo LabsJavaScriptGPL-3.0 license2022-09-15DeFi
    Verified Impact NFTAn NFT platform dedicated to impact causes with verification of the beneficiariesAlphaFinJavaScript-RustMIT license2022-07-08NFT
    UseWalletuseWallet is a collection of React Hooks containing everything you need to start working with a Casper networkCasperDashTypescript-ReactMIT license2023-09-19dApp library
    Testnet FaucetA faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for freeCasperDashTypescript-ReactMIT license2023-09-19Tools
    +
    NameDescriptionAuthorLanguageLicenseLast Update DateType
    Basic Yield FarmStaking RewardsRengo LabsRustApache-2.0 license2022-06-24Staking
    Blockcerts on CasperIssues Blockcerts using the Bitcoin, Ethereum, or Casper blockchainamazanzanPythonMIT license2022-07-22Tokens
    BlockMatcher Frontend BackendPrivate Trade (OTC) Platform for Compliant Brokers. This system allows the creation of OTC token deals, matching buyers and sellers together. The admin, or broker, can then clear them in batches.LedgerLeapJavaScript-PHPMIT license2022-01-15Exchange
    Camel CasperApache Camel connector for the Casper BlockchainM.AbahmaneJavaMIT license2022-03-26Tools
    Casper .NET SDKCasper .NET Client SDK to interact with Casper network nodes via RPC.MAKE Software.NETApache-2.0 license2022-04-19Client SDK
    Casper Analytics AppCasper Analytics App. Built with Ionic. Easily exportable as iOS and Andriod Appcaspercommunity.ioPHPMIT license2022-01-20Tools
    Casper C++ SDKC++ library to interact with Casper network nodes via RPCYusuf KetenC++Apache-2.0 license2022-09-13Client SDK
    Casper CalculatorCasper Earnings Calculator and Node MonitorCharles NguyenJavaScriptMIT license2021-09-26Tools
    Casper Contract UpgradeExample contract to demonstrate the general way of upgrading a contract and the necessary stepsCasper LabsRustApache-2.0 license2022-06-21Example Contracts
    Casper Dart SDKCasper Dart SDK is for interacting with the Casper Blockchain using RPC.TemiltasDartApache-2.0 license2022-06-26Client SDK
    Friendly Market's Casper variant of ERC20Implementation of the ERC20 standard for Casper networksFriendly MarketRustApache-2.0 license2022-08-10Tokens
    Casper Go SDKCasper Go SDKMAKE SoftwareGoApache-2.0 license2023-06-01Client SDK
    Casper Hello World ContractThis example demonstrates the session code that accepts a message string and stores it in the calling account under the special_value NamedKeyCasper LabsRustNA2022-07-13Example contracts
    Casper JavaScript SDKCasper Client JavaScript SDKCasper LabsTypeScript-JavaScriptApache-2.0 license2022-09-13Client SDK
    Casper Kotlin SDKCasper Kotlin Client SDK to interact with a Casper network.tqhuy2018KotlinMIT license2022-07-21Client SDK
    Casper MetricsCasper Metrics - fast blockchain crawler, API, and analysis toolA3MCTypeScriptMIT license2022-09-09Tools
    Casper NCTL DockerA Docker container that runs Casper NCTL as a serviceMAKE SoftwareShellApache-2.0 license2022-03-17Tools
    Casper Node-REDNodes to communicate with the Casper's Blockchain using node-redcaspercommunity.ioJavaScriptMIT license2022-02-08Tools
    Casper Objective-C SDKCasper Objective-C SDK is for interacting with the Casper Blockchain using RPC.hienbui9999Objective-CMIT license2022-06-18Client SDK
    Casper PHP SDKPHP SDK to interact with Casper network nodes via RPC. The PHP SDK allows developers to interact with a Casper network using PHPMAKE SoftwarePHPApache-2.0 license2022-06-29Client SDK
    Casper Ruby Client SDKRuby SDK to interact with Casper network nodes via RPC.Sait GulmezRubyApache-2.0 license2022-03-08Client SDK
    Casper Scala SDKCasper Scala client SDK to interact with the Casper Network nodes via RPCM.AbahmaneScalaMIT license2022-03-23Client SDK
    Casper WalletA browser wallet for the Casper NetworkMAKE SoftwareTypeScript-JavaScriptApache-2.0 license2023-04-12Wallet
    Casper SSI Web AppCasper SSI Framework in the form of a demo web application.Credentia NetworkTypeScriptMIT license2022-06-29Tools
    Casper StorageCasper storage - HD walletsCasperDashTypeScriptApache-2.0 license2022-09-14Wallet
    Casper Swift SDKCasper Client SDK. Casper SDK methods implementation in Swift.hienbui9999SwiftMIT license2022-06-08Client SDK
    Casper Two-Party MultiSig ContractThis example demonstrates how to configure an account on a Casper network to require two-party multi-signature deploys.Casper LabsRustNA2022-04-26Example contracts
    Casper WorldCasper network status and decentralization map web applicationNodes GuruTypeScriptMIT license2022-01-26Blockchain Explorer
    CasperDash WalletA non-custodial wallet for the Casper blockchainCasperDashJavaScriptMIT license2022-09-14Wallet
    CasperFYRE APIDispensory API interface for Casper MainnetLedgerLeapJavaScript-PHPApache-2.0 license2022-09-06Tools
    CasperHoldersFirst 3rd party UI to interact with Casper BlockchainCasperHoldersJavaScriptApache-2.0 license2022-08-23Blockchain Explorer
    CasperSignThe First Casper-Native Dapp. CasperSign Allows Users to Sign Contracts Confidentially & Securely on the Casper BlockchainChronoLogic and Digital StrategiesTypeScriptNA2022-08-31dApp
    CEP-78 Enhanced NFT StandardStandard Contract Generator for NFTsCasper LabsRustApache-2.0 license2022-08-23NFT
    CES Rust Event EmitterRust library for smart contracts that emits contract-level events that follow the Casper Event Standard (CES)MAKE SoftwareRustApache-2.0 license2023-05-11dApp library
    CES JS ParserJS library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareJavaScriptApache-2.0 license2023-03-27dApp library
    CES Go ParserGo library for dApp developers that parses contract-level events that follow the Casper Event Standard (CES) from deploy execution resultsMAKE SoftwareGoApache-2.0 license2023-06-02dApp library
    Clearest StakeStaking Asset Manager for Node operators and groupsLedgerLeapPHPApache-2.0 license2022-04-02DeFi
    DAO ContractsSmart Contracts for the MVPR On-Chain Governance System on CasperMAKE SoftwareRustApache-2.0 license2022-07-17DAO
    DHF PAYThe crypto currency payment gateway on the CSPR blockchainDHFinanceTypeScriptApache-2.0 license2022-08-28Payments
    DLN DAODLN DAOAlphaFinTypeScriptMIT license2022-09-10DAO
    DotOracleRealtime decentralized Oracle and Cross-chain liquidity network for EVM, non-EVM Casper, and L2 blockchains.DotOracle NetworkTypeScriptNA2022-09-26Bridge
    Dragon’s Lair Style StakingLair Style StakingRengo LabsRustApache-2.0 license2022-06-24Staking
    Subscription BillingERC-1337 subscription billingRengo LabsRustMIT license2022-04-07Tokens
    Casper Fungible TokenImplementation of Fungible Tokens for Casper networksCasper LabsRustApache-2.0 license2022-09-01Tokens
    Advanced Fungible TokenERC-777 + 1820 Advanced Fungible Token with Callbacks & Self IdentificationRengo LabsRustApache-2.0 license2022-08-16Tokens
    Helper BotHelper bot for improving DevDao VAs productivityA3MCTypeScriptMIT license2022-08-19Tools
    Java SDKCasper Client Java SDKSyntiFiJavaApache-2.0 license2021-04-20Client SDK
    KYC Proxy ContactThis is a proxy contract to check if an account is KYC approved through registered providers (KYC Contracts)Casper LabsRustNA2022-07-01Example contracts
    LiquidNFTNFT Collateralized LoansRengo LabsJavaScriptGNU General Public License v3.02022-09-15NFT
    Payment Example ContractThis example demonstrates the usage of purses to transfer motes inside a contractCasper LabsRustNA2022-06-22Example contracts
    ServicesDAOThe ServicesDAO portal provides a platform for the service DAOs which provide services in a decentralized manner through a modular implementation of MVPR.Ekon YazilimHTML-CSS-C#MIT license2022-09-13DAO
    Uniswap DemoAppUniswap UI + ContractsRengo LabsJavaScriptGPL-3.0 license2022-09-15DeFi
    Verified Impact NFTAn NFT platform dedicated to impact causes with verification of the beneficiariesAlphaFinJavaScript-RustMIT license2022-07-08NFT
    UseWalletuseWallet is a collection of React Hooks containing everything you need to start working with a Casper networkCasperDashTypescript-ReactMIT license2023-09-19dApp library
    Testnet FaucetA faucet is a Casper tool that distributes Testnet tokens to anyone requesting them for freeCasperDashTypescript-ReactMIT license2023-09-19Tools
    \ No newline at end of file diff --git a/resources/build-on-casper/introduction/index.html b/resources/build-on-casper/introduction/index.html index 488d9da81..afea44531 100644 --- a/resources/build-on-casper/introduction/index.html +++ b/resources/build-on-casper/introduction/index.html @@ -1,22 +1,21 @@ - + -Build on Casper | Casper Docs - Redux +Build on Casper | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Building on Casper

    + submit an issue on Github
    Version: Next

    Building on Casper

    This guide intends to briefly show you the current features and advantages of building on the Casper Mainnet.

    Thriving Ecosystem

    The Casper Ecosystem is growing every day through the addition of new dApps and tools. Here is a short list of tools you can use.

    @@ -72,7 +71,7 @@

    AWSWe also offer several tools to run AWS instances of Casper nodes.

    SDK Client Libraries

    In addition to the default command-line Rust client, the Casper community is building other clients in JavaScript, Java, Golang, Python, C#, and other languages.

    -

    Low Gas Fees

    -

    Casper seeks to eliminate volatility and improve developer and enterprise experiences by establishing transparent, consistent, and low gas prices. This feature seeks to promote active and diverse network behaviour and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows.

    +

    No Gas Fees

    +

    Casper seeks to eliminate volatility and improve developer and enterprise experiences by eliminating transaction fees on Mainnet. This feature seeks to promote active and diverse network behavior and we are researching innovative pricing models that will favor dApp developers as the ecosystem grows.

    \ No newline at end of file diff --git a/resources/changelog/index.html b/resources/changelog/index.html new file mode 100644 index 000000000..e2ba366ee --- /dev/null +++ b/resources/changelog/index.html @@ -0,0 +1,35 @@ + + + + + +Documentation Updates by Protocol Release | Casper Docs - Redux + + + + + + + + + +
    Version: Next

    Documentation Updates by Protocol Release

    +

    Condor (2.0)

    +

    Concepts

    +

    The following are changes introduced alongside release of the Condor network upgrade.

    +

    Understanding Key Types - Additional Key Types and document restructuring.

    +

    Serialization Standard - Serialization information for new types.

    +

    Smart Contracts - Information on the new factory pattern feature for smart contracts.

    +

    Developers

    +

    Building dApps -> Monitoring and Consuming Events - Information related to contract-level events.

    +

    Casper JSON-RPC API -> Informational JSON-RPC Methods - New RPC methods.

    +

    Casper JSON-RPC API -> Transactional JSON-RPC Methods - New RPC methods.

    +

    Casper JSON-RPC API -> Types - New parameters used by the JSON-RPC API.

    +

    Writing On-Chain Code -> Contract-Level Events - Guide to the new contract-level events feature.

    +

    Writing On-Chain Code -> Factory Contracts - Guide to the new factory pattern for smart contracts.

    +

    Operators

    +

    Private Network -> The Chainspec - Updates to the chainpsec relating to contract-level events.

    + + \ No newline at end of file diff --git a/resources/index.html b/resources/index.html index 3b0be780e..ecc15fe9f 100644 --- a/resources/index.html +++ b/resources/index.html @@ -1,21 +1,21 @@ - + -Resources Overview | Casper Docs - Redux +Resources Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Resources Overview

    + submit an issue on Github
    Version: Next

    Resources Overview

    Building on Casper

    @@ -84,6 +84,6 @@

    TutorialsQuickstartInstall Rust and setup a Casper environmentBeginnerLearn the basics, such as installing and upgrading contractsAdvancedLearn about multi-sig, authorization keys, exchange integration, and storage

    +
    TopicDescription
    QuickstartInstall Rust and setup a Casper environment
    BeginnerLearn the basics, such as installing and upgrading contracts
    AdvancedLearn about multi-sig, authorization keys, exchange integration, and storage
    \ No newline at end of file diff --git a/resources/moving-to-casper/index.html b/resources/moving-to-casper/index.html index 2f954219a..e02b495e4 100644 --- a/resources/moving-to-casper/index.html +++ b/resources/moving-to-casper/index.html @@ -1,22 +1,21 @@ - + -Move to Casper | Casper Docs - Redux +Move to Casper | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl'; -import Tabs from '@theme/Tabs'; + submit an issue on Github

    Version: Next

    import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem';

    Moving to Casper from another Blockchain

    This page covers various considerations for moving to Casper from another blockchain by comparing Casper to Ethereum, Near, Aptos, and Solana in these aspects:

    @@ -95,7 +94,7 @@

    Contract

    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 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 syntax described in the Interacting with Runtime Return Values tutorial.

    runtime::ret(value);
    -

    Each call to an entry point is treated as a Deploy to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).

    +

    Each call to an entry point is treated as a Deploy to the network, and therefore, each call incurs a cost paid in motes (the network's native accounting unit).

    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.

    @@ -178,6 +177,6 @@

    Ad

    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.

    +

    The Casper ecosystem aims to fulfill all of these aspects, including supporting enterprise-grade projects.

    \ No newline at end of file diff --git a/resources/quick-start/index.html b/resources/quick-start/index.html index d1c5c4b2c..7168bb68d 100644 --- a/resources/quick-start/index.html +++ b/resources/quick-start/index.html @@ -1,27 +1,26 @@ - + -Quickstart | Casper Docs - Redux +Quickstart | Casper Docs - Redux - - + +
    Version: 1.5.X

    Quickstart

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Quickstart

    Here is a list of commands for developers who already meet the prerequisites and want to quickly send a sample contract to the Testnet. Consult the complete documentation for context and additional help.

    Prerequisites

    1. You have installed Rust. Verify the installation with this command: rustup --version. Restart the shell if needed.
    2. -
    3. You have installed cmake. Verify the installation with this command: cmake --version. +
    4. You have installed cmake. Verify the installation with this command: cmake --version.

    If everything went according to plan, the value should be 1. Look at the "parsed" value below.

    {
    "id": 8523290678829319485,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.6",
    "block_header": null,
    "merkle_proof": "[85716 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "01000000",
    "cl_type": "I32",
    "parsed": 1
    }
    }
    }
    }
    -

    You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts.

    +

    You have successfully invoked a contract on the Casper Testnet to increment a value from 0 to 1. Now you have all the infrastructure required to work with more meaningful contracts.

    \ No newline at end of file diff --git a/resources/tokens/cep18/full-tutorial/index.html b/resources/tokens/cep18/full-tutorial/index.html index 1eedb9187..bd4a643f6 100644 --- a/resources/tokens/cep18/full-tutorial/index.html +++ b/resources/tokens/cep18/full-tutorial/index.html @@ -1,24 +1,24 @@ - + -Fungible Token Workflow | Casper Docs - Redux +Fungible Token Workflow | Casper Docs - Redux - - + +
    Version: Next

    Casper Fungible Token Tutorial

    This tutorial introduces an implementation of the CEP-18 standard for the Casper blockchain, known as the Casper Fungible Token. The code for this tutorial is available in GitHub.

    The Ethereum Request for Comment (ERC-20) standard is an integral part of the Ethereum ecosystem. This standard allows for building new tokens based on smart contracts. These ERC-20 tokens are blockchain-based assets that have value and can be transferred or recorded.

    -

    The Casper Fungible Token standard is the Casper Platform's ER-C20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed.

    +

    The Casper Fungible Token standard is the Casper Platform's ERC-20 equivalent. It defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed.

    The following functions implement the rules defined by Casper Fungible Tokens: totalSupply, transfer, transferFrom, approve, balanceOf, and allowance. A portion of this tutorial reviews the contract and the casper_fungible_token library.

    The Writing Rust Contracts on Casper document outlines many aspects of this tutorial and should be read first.

    Preparation

    @@ -76,21 +76,21 @@

    Contract Me
  • transfer_from - Transfers an amount of tokens from the owner to a recipient, if the direct caller has been previously approved to spend the specified amount on behalf of the owner
  • Installing the Contract

    -

    After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the Sending Deploys to a Casper network using the Rust Client section to learn more about install contracts.

    +

    After customizing your instance of the CEP-18 token contract, it's time to install it in global state. Installing the Fungible Token contract is similar to installing other smart contracts, while only the Wasm files and parameters will differ. Refer to the Sending Deploys to a Casper network using the Rust Client section to learn more about install contracts.

    Deploy Prerequisites

    Basic Flow

    Here are the basic steps to install the Casper Fungible Token contract on a Casper Network.

    Cloning the Token Contract

    @@ -127,8 +127,7 @@

    Viewi
    casper-client query-global-state \
    --node-address http://<HOST:PORT> \
    --state-root-hash [STATE_ROOT_HASH] \
    --key [ACCOUNT_HASH]

    Installing the Contract

    Now you can install the contract to the network and check how it behaves.

    -

    If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the note about gas price to understand more about payment amounts and gas price adjustments.

    -

    The Casper platform currently does not refund any tokens as part of sending a deploy. For example, if you spend 10 CSPR for the deployment and it only costs 1 CSPR, you will not receive the remaining 9 CSPR. Refer to the Gas and the Casper Blockchain documentation for further details.

    +

    If you are sending the deploy on Mainnet, try several put deploys on the Testnet to understand the exact gas amount required for that deploy. Refer to the Gas and the Casper Blockchain documentation for further details.

    Use the following command template to deploy the contract:

    casper-client put-deploy \
    --node-address http://<HOST:PORT> \
    --chain-name [NETWORK_NAME]] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [AMOUNT] \
    --session-path [WASM_FILE_PATH]/[File_Name].wasm
    --session-arg <"NAME:TYPE='VALUE'" OR "NAME:TYPE=null">
      @@ -188,6 +187,6 @@

      casper-client query-global-state --node-address http://95.216.24.237:7777 \
      --state-root-hash D00dF8c35B0E9995c2911803F37A212d82c960D9bC5bA3C4F99a661e18D09411 \
      --key account-hash-7f4bf39A311a7538d8C91BB86C71DF774023e16bc4a70ab7e4e8AE77DbF2Ef53 \
      -q "test_contract/name"

    Result:

    You can see that the name is CasperTest in this example.

    -
    {
    "id": -3650676146668320186,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "block_header": null,
    "merkle_proof": "[80252 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    }
    }

    +
    {
    "id": -3650676146668320186,
    "jsonrpc": "2.0",
    "result": {
    "api_version": "1.4.3",
    "block_header": null,
    "merkle_proof": "[80252 hex chars]",
    "stored_value": {
    "CLValue": {
    "bytes": "0A00000043617370657254657374",
    "cl_type": "String",
    "parsed": "CasperTest"
    }
    }
    }
    }

    \ No newline at end of file diff --git a/resources/tokens/cep18/query/index.html b/resources/tokens/cep18/query/index.html index a0d2e4596..2b246a9fe 100644 --- a/resources/tokens/cep18/query/index.html +++ b/resources/tokens/cep18/query/index.html @@ -1,33 +1,33 @@ - + -CEP-18 Contract Details | Casper Docs - Redux +CEP-18 Contract Details | Casper Docs - Redux - - + +
    Version: Next

    Exploring the CEP-18 Contracts

    This document covers the necessary information that you will need to interact with your CEP-18 contract instance. Your setup should include the following two contracts:

    • The Casper fungible token contract

    • -

      The CEP-18 utility contract, which should appear in the NamedKeys of the account that sent the Deploy as cep18_test_contract

      +

      The CEP-18 utility contract, which should appear in the NamedKeys of the account that sent the transaction as cep18_test_contract

    Querying the Contract Package

    We will need the contract package's contract_hash to interact with the recently installed instance of CEP-18. You can find the contract package hash within the installing account's NamedKeys, under the name given during the installation process.

    -
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    // This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing deploy.
    --key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \
    // This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    +
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    // This is the contract package hash, which can be found within the `NamedKeys` of the account that sent the installing transaction.
    --key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \
    // This is the most up to date state root hash, which can found by using the `get-state-root-hash` command in the Casper client.
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    Casper client command without comments
    casper-client query-global-state -n http://<HOST IP>:<PORT> \
    --key hash-82bd86d2675b2dc44c19027fb7717a99db6fda5e0cad8d597f2495a9dbc9df7f \
    --state-root-hash f9f73c3a4da5893b67c4cac94a5695d76cfefff61b050c98a7b19e2b8efd3933
    @@ -54,6 +54,6 @@

    Next Steps

    +
    \ No newline at end of file diff --git a/resources/tokens/cep18/quickstart-guide/index.html b/resources/tokens/cep18/quickstart-guide/index.html index 36d42142f..f07752c6c 100644 --- a/resources/tokens/cep18/quickstart-guide/index.html +++ b/resources/tokens/cep18/quickstart-guide/index.html @@ -1,21 +1,21 @@ - + -On-chain Installation | Casper Docs - Redux +On-chain Installation | Casper Docs - Redux - - + +
    Version: Next

    Installing and Interacting with a CEP-18 Contract

    This quick start guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-18 Casper Fungible Token contract to a Casper network.

    The Ethereum Request for Comment (ERC-20) standard defines a set of rules that dictate the total supply of tokens, how the tokens are transferred, how transactions are approved, and how token data is accessed. These fungible tokens are blockchain-based assets that have value and can be transferred or recorded.

    To execute transactions on a Casper network (involving fungible tokens), you will need some CSPR tokens to pay for the transactions.

    @@ -26,7 +26,7 @@

    Prerequisites<
  • Set up your machine as per the prerequisites
  • Use the [Casper command-line client]
  • Get a valid node-address
  • -
  • Know how to deploy a smart contract to a Casper network
  • +
  • Know how to deploy a smart contract to a Casper network
  • Hold enough CSPR tokens to pay for transactions
  • Setup

    @@ -58,6 +58,6 @@

    Next StepsExploring the CEP18 Contracts
  • CEP-18 Token Transfers and Allowances
  • Testing Framework for CEP-18
  • -

    +
    \ No newline at end of file diff --git a/resources/tokens/cep18/tests/index.html b/resources/tokens/cep18/tests/index.html index 8c2ea39d7..a6ffd0107 100644 --- a/resources/tokens/cep18/tests/index.html +++ b/resources/tokens/cep18/tests/index.html @@ -1,21 +1,21 @@ - + -Testing Guide | Casper Docs - Redux +Testing Guide | Casper Docs - Redux - - + +
    Version: Next

    Testing Framework for CEP-18

    The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.

    The following section reviews the GitHub testing folder, which creates a testing framework for the Casper Fungible Token project. You can find more details about testing Casper contracts here.

    The following is an example of a complete test expecting a failed transfer:

    @@ -31,7 +31,7 @@

    Testing Logic<
    • Step 1 - Specify the starting state of the blockchain.
    • Step 2 - Deploy the compiled contract to the blockchain and query it.
    • -
    • Step 3 - Create additional deploys for calling each of the entrypoints in the contract.
    • +
    • Step 3 - Create additional deploys for calling each of the entrypoints in the contract.

    The test fixture accomplishes these steps by simulating a real-world deploy that stores the contract on the blockchain and then invoking the contract's entrypoints.

    Setting up the Testing Context

    @@ -75,6 +75,6 @@

    Running th
    #[cfg(test)]
    mod allowance;
    #[cfg(test)]
    mod install;
    #[cfg(test)]
    mod mint_and_burn;
    #[cfg(test)]
    mod transfer;
    #[cfg(test)]
    mod utility;

    To run the tests, navigate to the parent cep18 directory and run the command:

    make test
    -

    This example uses bash. If you are using a Rust IDE, you need to configure it to run the tests.

    +

    This example uses bash. If you are using a Rust IDE, you need to configure it to run the tests.

    \ No newline at end of file diff --git a/resources/tokens/cep18/transfer/index.html b/resources/tokens/cep18/transfer/index.html index b91cd7b71..83d4ca623 100644 --- a/resources/tokens/cep18/transfer/index.html +++ b/resources/tokens/cep18/transfer/index.html @@ -1,21 +1,21 @@ - + -CEP-18 Transfers | Casper Docs - Redux +CEP-18 Transfers | Casper Docs - Redux - - + +
    Version: Next

    CEP-18 Token Transfers and Allowances

    This document describes how to transfer CEP-18 tokens on a Casper network using the Casper client. The Exploring the CEP18 Contracts documentation contains more in depth explanations on how to find the various hashes and URefs referenced throughout this document.

    Transferring CEP-18 Tokens to Another Account

    The following command will invoke the transfer entry point on your instance of CEP-18, directing it to transfer 10 of the associated CEP-18 tokens to another account.

    @@ -130,6 +130,6 @@

    Next Steps

    +
    \ No newline at end of file diff --git a/resources/tokens/cep78/introduction/index.html b/resources/tokens/cep78/introduction/index.html index fa01e439a..7704616c1 100644 --- a/resources/tokens/cep78/introduction/index.html +++ b/resources/tokens/cep78/introduction/index.html @@ -1,27 +1,26 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: 1.5.X

    CEP-78 Enhanced NFT Standard Introduction

    + submit an issue on Github
    Version: Next

    CEP-78 Enhanced NFT Standard Introduction

    Usage

    Building the Contract

    The main.rs file within the contract provides the installer for the NFT contract. Users can compile the contract to Wasm using the make build-contract command from the Makefile provided.

    The pre-built Wasm for the contract and all other utility session code can be found as part of the most current release. Users wishing to build the Wasm themselves can pull the code and use the make build-contract command provided in the Makefile. Please note, however, that you must install wasm-strip to build the contract.

    The call method will install the contract with the necessary entrypoints and call the init() entrypoint, which allows the contract to self-initialize and set up the necessary state variables for operation.

    -

    The Full Installation Tutorial provides a step-by-step workflow.

    Required Runtime Arguments

    The following are the required runtime arguments that must be passed to the installer session code to correctly install the NFT contract. For more information on the modalities that these arguments set, please refer to the Modalities documentation.

      @@ -56,7 +55,7 @@

      R

      "burn_mode": The BurnMode modality dictates whether minted NFTs can be burnt. This is an optional parameter and will allow tokens to be burnt by default. This parameter cannot be changed once the contract has been installed.

    • -

      "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.

      +

      "owner_reverse_lookup_mode": The OwnerReverseLookupMode modality dictates whether the lookup for owners to token identifiers is available. This is an optional parameter and will not provide the lookup by default. This parameter cannot be changed once the contract has been installed.

    • "events_mode": The EventsMode modality selects the event schema used to record any changes that occur to tokens issued by the contract instance.

      @@ -69,7 +68,7 @@

      R

    Example deploy

    -

    The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

    +

    The following is an example of installing the NFT contract via a deploy using the Rust CLI Casper client. You can find more examples here.

    casper-client put-deploy -n http://65.108.0.148:7777/rpc --chain-name "casper-test" --payment-amount 500000000000 -k keys/secret_key.pem --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='enhanced-nft-1'" \
    --session-arg "collection_symbol:string='ENFT-1'" \
    --session-arg "total_token_supply:u64='10'" \
    --session-arg "ownership_mode:u8='0'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "allow_minting:bool='true'" \
    --session-arg "owner_reverse_lookup_mode:u8='0'" \
    --session-arg "nft_metadata_kind:u8='2'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='1'"

    Utility Session Code

    Specific entrypoints in use by the current implementation of the NFT contract require session code to accept return values passed by the contract over the Wasm boundary. @@ -107,11 +106,11 @@

    Utility
    Entrypoint nameSession code
    "mint"client/mint_session
    "balance_of"client/balance_of_session
    "get_approvedclient/get_approved_session
    "owner_of"client/owner_of_session
    "transfer"client/transfer_session

    Checking Token Ownership

    -

    Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

    +

    Learn to check token ownership starting with version v1.1.1. The OwnerReverseLookupMode modality must be set to Complete as described here.

    Upgrading to Version 1.1.1

    -

    Upgrade to v1.1.1 using a Standard NamedKey Convention or a Custom NamedKey Convention.

    +

    Upgrade to v1.1.1 using a Standard NamedKey Convention or a Custom NamedKey Convention.

    Installing and Interacting with the Contract using the Rust Casper Client

    -

    You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

    +

    You can find instructions on installing an instance of the CEP-78 contract using the Rust CLI Casper client here.

    Test Suite and Specification

    The expected behavior of the NFT contract implementation is asserted by its test suite found in the tests folder. The test suite and the corresponding unit tests comprise the specification around the contract and outline the expected behaviors @@ -777,6 +776,6 @@

    Error CodesCodeError1InvalidAccount2MissingInstaller3InvalidInstaller4UnexpectedKeyVariant5MissingTokenOwner6InvalidTokenOwner7FailedToGetArgBytes8FailedToCreateDictionary9MissingStorageUref10InvalidStorageUref11MissingOwnerUref12InvalidOwnersUref13FailedToAccessStorageDictionary14FailedToAccessOwnershipDictionary15DuplicateMinted16FailedToConvertCLValue17MissingCollectionName18InvalidCollectionName19FailedToSerializeMetaData20MissingAccount21MissingMintingStatus22InvalidMintingStatus23MissingCollectionSymbol24InvalidCollectionSymbol25MissingTotalTokenSupply26InvalidTotalTokenSupply27MissingTokenID28InvalidTokenIdentifier29MissingTokenOwners30MissingAccountHash31InvalidAccountHash32TokenSupplyDepleted33MissingOwnedTokensDictionary34TokenAlreadyBelongsToMinterFatal35FatalTokenIdDuplication36InvalidMinter37MissingMintingMode38InvalidMintingMode39MissingInstallerKey40FailedToConvertToAccountHash41InvalidBurner42PreviouslyBurntToken43MissingAllowMinting44InvalidAllowMinting45MissingNumberOfMintedTokens46InvalidNumberOfMintedTokens47MissingTokenMetaData48InvalidTokenMetaData49MissingApprovedAccountHash50InvalidApprovedAccountHash51MissingApprovedTokensDictionary52TokenAlreadyApproved53MissingApproveAll54InvalidApproveAll55MissingOperator56InvalidOperator57Phantom58ContractAlreadyInitialized59MintingIsPaused60FailureToParseAccountHash61VacantValueInDictionary62MissingOwnershipMode63InvalidOwnershipMode64InvalidTokenMinter65MissingOwnedTokens66InvalidAccountKeyInDictionary67MissingJsonSchema68InvalidJsonSchema69InvalidKey70InvalidOwnedTokens71MissingTokenURI72InvalidTokenURI73MissingNftKind74InvalidNftKind75MissingHolderMode76InvalidHolderMode77MissingWhitelistMode78InvalidWhitelistMode79MissingContractWhiteList80InvalidContractWhitelist81UnlistedContractHash82InvalidContract83EmptyContractWhitelist84MissingReceiptName85InvalidReceiptName86InvalidJsonMetadata87InvalidJsonFormat88FailedToParseCep78Metadata89FailedToParse721Metadata90FailedToParseCustomMetadata91InvalidCEP78Metadata92FailedToJsonifyCEP78Metadata93InvalidNFT721Metadata94FailedToJsonifyNFT721Metadata95InvalidCustomMetadata96MissingNFTMetadataKind97InvalidNFTMetadataKind98MissingIdentifierMode99InvalidIdentifierMode100FailedToParseTokenId101MissingMetadataMutability102InvalidMetadataMutability103FailedToJsonifyCustomMetadata104ForbiddenMetadataUpdate105MissingBurnMode106InvalidBurnMode107MissingHashByIndex108InvalidHashByIndex109MissingIndexByHash110InvalidIndexByHash111MissingPageTableURef112InvalidPageTableURef113MissingPageLimit114InvalidPageLimit115InvalidPageNumber116InvalidPageIndex117MissingUnmatchedHashCount118InvalidUnmatchedHashCount119MissingPackageHashForUpgrade120MissingPageUref121InvalidPageUref122CannotUpgradeWithZeroSupply123CannotInstallWithZeroSupply124MissingMigrationFlag125InvalidMigrationFlag126ContractAlreadyMigrated127UnregisteredOwnerInMint128UnregisteredOwnerInTransfer129MissingReportingMode130InvalidReportingMode131MissingPage132UnregisteredOwnerFromMigration133ExceededMaxTotalSupply134MissingCep78PackageHash135InvalidCep78InvalidHash136InvalidPackageHashName137InvalidAccessKeyName138InvalidCheckForUpgrade139InvalidNamedKeyConvention140OwnerReverseLookupModeNotTransferable141InvalidAdditionalRequiredMetadata142InvalidOptionalMetadata143MissingOptionalNFTMetadataKind144InvalidOptionalNFTMetadataKind145MissingAdditionalNFTMetadataKind146InvalidAdditionalNFTMetadataKind147InvalidRequirement148MissingEventsMode149InvalidEventsMode150CannotUpgradeToMoreSupply151MissingOperatorDict152MissingApprovedDict153MissingSpenderAccountHash154InvalidSpenderAccountHash155MissingOwnerTokenIdentifierKey156InvalidTransferFilterContract157MissingTransferFilterContract158TransferFilterContractNeedsTransferableMode159TransferFilterContractDenied160MissingACLWhiteList161InvalidACLWhitelist162EmptyACLWhitelist

    +
    CodeError
    1InvalidAccount
    2MissingInstaller
    3InvalidInstaller
    4UnexpectedKeyVariant
    5MissingTokenOwner
    6InvalidTokenOwner
    7FailedToGetArgBytes
    8FailedToCreateDictionary
    9MissingStorageUref
    10InvalidStorageUref
    11MissingOwnerUref
    12InvalidOwnersUref
    13FailedToAccessStorageDictionary
    14FailedToAccessOwnershipDictionary
    15DuplicateMinted
    16FailedToConvertCLValue
    17MissingCollectionName
    18InvalidCollectionName
    19FailedToSerializeMetaData
    20MissingAccount
    21MissingMintingStatus
    22InvalidMintingStatus
    23MissingCollectionSymbol
    24InvalidCollectionSymbol
    25MissingTotalTokenSupply
    26InvalidTotalTokenSupply
    27MissingTokenID
    28InvalidTokenIdentifier
    29MissingTokenOwners
    30MissingAccountHash
    31InvalidAccountHash
    32TokenSupplyDepleted
    33MissingOwnedTokensDictionary
    34TokenAlreadyBelongsToMinterFatal
    35FatalTokenIdDuplication
    36InvalidMinter
    37MissingMintingMode
    38InvalidMintingMode
    39MissingInstallerKey
    40FailedToConvertToAccountHash
    41InvalidBurner
    42PreviouslyBurntToken
    43MissingAllowMinting
    44InvalidAllowMinting
    45MissingNumberOfMintedTokens
    46InvalidNumberOfMintedTokens
    47MissingTokenMetaData
    48InvalidTokenMetaData
    49MissingApprovedAccountHash
    50InvalidApprovedAccountHash
    51MissingApprovedTokensDictionary
    52TokenAlreadyApproved
    53MissingApproveAll
    54InvalidApproveAll
    55MissingOperator
    56InvalidOperator
    57Phantom
    58ContractAlreadyInitialized
    59MintingIsPaused
    60FailureToParseAccountHash
    61VacantValueInDictionary
    62MissingOwnershipMode
    63InvalidOwnershipMode
    64InvalidTokenMinter
    65MissingOwnedTokens
    66InvalidAccountKeyInDictionary
    67MissingJsonSchema
    68InvalidJsonSchema
    69InvalidKey
    70InvalidOwnedTokens
    71MissingTokenURI
    72InvalidTokenURI
    73MissingNftKind
    74InvalidNftKind
    75MissingHolderMode
    76InvalidHolderMode
    77MissingWhitelistMode
    78InvalidWhitelistMode
    79MissingContractWhiteList
    80InvalidContractWhitelist
    81UnlistedContractHash
    82InvalidContract
    83EmptyContractWhitelist
    84MissingReceiptName
    85InvalidReceiptName
    86InvalidJsonMetadata
    87InvalidJsonFormat
    88FailedToParseCep78Metadata
    89FailedToParse721Metadata
    90FailedToParseCustomMetadata
    91InvalidCEP78Metadata
    92FailedToJsonifyCEP78Metadata
    93InvalidNFT721Metadata
    94FailedToJsonifyNFT721Metadata
    95InvalidCustomMetadata
    96MissingNFTMetadataKind
    97InvalidNFTMetadataKind
    98MissingIdentifierMode
    99InvalidIdentifierMode
    100FailedToParseTokenId
    101MissingMetadataMutability
    102InvalidMetadataMutability
    103FailedToJsonifyCustomMetadata
    104ForbiddenMetadataUpdate
    105MissingBurnMode
    106InvalidBurnMode
    107MissingHashByIndex
    108InvalidHashByIndex
    109MissingIndexByHash
    110InvalidIndexByHash
    111MissingPageTableURef
    112InvalidPageTableURef
    113MissingPageLimit
    114InvalidPageLimit
    115InvalidPageNumber
    116InvalidPageIndex
    117MissingUnmatchedHashCount
    118InvalidUnmatchedHashCount
    119MissingPackageHashForUpgrade
    120MissingPageUref
    121InvalidPageUref
    122CannotUpgradeWithZeroSupply
    123CannotInstallWithZeroSupply
    124MissingMigrationFlag
    125InvalidMigrationFlag
    126ContractAlreadyMigrated
    127UnregisteredOwnerInMint
    128UnregisteredOwnerInTransfer
    129MissingReportingMode
    130InvalidReportingMode
    131MissingPage
    132UnregisteredOwnerFromMigration
    133ExceededMaxTotalSupply
    134MissingCep78PackageHash
    135InvalidCep78InvalidHash
    136InvalidPackageHashName
    137InvalidAccessKeyName
    138InvalidCheckForUpgrade
    139InvalidNamedKeyConvention
    140OwnerReverseLookupModeNotTransferable
    141InvalidAdditionalRequiredMetadata
    142InvalidOptionalMetadata
    143MissingOptionalNFTMetadataKind
    144InvalidOptionalNFTMetadataKind
    145MissingAdditionalNFTMetadataKind
    146InvalidAdditionalNFTMetadataKind
    147InvalidRequirement
    148MissingEventsMode
    149InvalidEventsMode
    150CannotUpgradeToMoreSupply
    151MissingOperatorDict
    152MissingApprovedDict
    153MissingSpenderAccountHash
    154InvalidSpenderAccountHash
    155MissingOwnerTokenIdentifierKey
    156InvalidTransferFilterContract
    157MissingTransferFilterContract
    158TransferFilterContractNeedsTransferableMode
    159TransferFilterContractDenied
    160MissingACLWhiteList
    161InvalidACLWhitelist
    162EmptyACLWhitelist
    \ No newline at end of file diff --git a/resources/tokens/cep78/js-tutorial/index.html b/resources/tokens/cep78/js-tutorial/index.html index e7f485c94..55e910e75 100644 --- a/resources/tokens/cep78/js-tutorial/index.html +++ b/resources/tokens/cep78/js-tutorial/index.html @@ -1,21 +1,21 @@ - + -CEP-78 JavaScript Client | Casper Docs - Redux +CEP-78 JavaScript Client | Casper Docs - Redux - - + +
    Version: Next

    CEP-78 JavaScript Client Tutorial

    This tutorial outlines the usage of the JavaScript client available for the CEP-78 Enhanced NFT Standard.

    Further information on the CEP-78 Enhanced NFT Standard can be found here.

    The client is available in npm as casper-cep78-js-client.

    @@ -24,7 +24,7 @@

    Client I

    To install run:

    npm install casper-cep78-js-client

    Installing a CEP-78 Contract using the JavaScript Client

    -

    The install method crafts a Deploy using InstallArgs. +

    The install method crafts a Deploy using InstallArgs. As with every deploy created by the SDK, you can send it using the .send(rpcUrl) method providing the RPC URL that you want to use. It will return deployHash.


    const cc = new CEP78Client(process.env.NODE_URL!, process.env.NETWORK_NAME!);

    const installDeploy = await cc.install(
    {
    collectionName: "my-collection",
    collectionSymbol: "MY-NFTS",
    totalTokenSupply: "1000",
    ownershipMode: NFTOwnershipMode.Transferable,
    nftKind: NFTKind.Physical,
    jsonSchema: {
    properties: {
    color: { name: "color", description: "", required: true },
    size: { name: "size", description: "", required: true },
    material: { name: "material", description: "", required: true },
    condition: { name: "condition", description: "", required: false },
    },
    },
    nftMetadataKind: NFTMetadataKind.CustomValidated,
    identifierMode: NFTIdentifierMode.Ordinal,
    metadataMutability: MetadataMutability.Immutable,
    mintingMode: MintingMode.Installer,
    ownerReverseLookupMode: OwnerReverseLookupMode.Complete
    },
    "250000000000",
    FAUCET_KEYS.publicKey,
    [FAUCET_KEYS]
    );

    const hash = await installDeploy.send(process.env.http://localhost:11101/rpc);

    InstallArgs are specified as follows:

    @@ -138,6 +138,6 @@

    Runn

    Burn - The example will burn the minted NFT.

    -

    The associated code for these deploys may be found in the client-js/examples directory.

    +

    The associated code for these deploys may be found in the client-js/examples directory.

    \ No newline at end of file diff --git a/resources/tokens/cep78/modalities/index.html b/resources/tokens/cep78/modalities/index.html index 9dd8989c3..a514d8b80 100644 --- a/resources/tokens/cep78/modalities/index.html +++ b/resources/tokens/cep78/modalities/index.html @@ -1,21 +1,21 @@ - + -CEP-78 Modalities | Casper Docs - Redux +CEP-78 Modalities | Casper Docs - Redux - - + +
    Version: Next

    CEP-78 Modalities

    The enhanced NFT implementation supports various 'modalities' that dictate the behavior of a specific contract instance. Modalities represent the common expectations around contract usage and behavior.

    Ownership

    This modality specifies the behavior regarding ownership of NFTs and whether the owner of the NFT can change over the contract's lifetime. There are three modes:

    @@ -517,6 +517,6 @@

    Casper
    Event nameIncluded values and type
    Mintrecipient (Key), token_id (String), data (String)
    Transferowner (Key), operator (Option<Key>), recipient (Key), token_id (String)
    Burnowner (Key), token_id (String)
    Approvalowner (Key), spender (Key), token_id (String)
    ApprovalRevokedowner (Key), token_id (String)
    ApprovalForAllowner (Key), operator (Key)
    RevokedForAllowner (Key), operator (Key)
    MetadataUpdatedtoken_id (String), data (String)
    Migration-
    VariablesSet-

    Modality Conflicts

    -

    The MetadataMutability option set to Mutable cannot be used in conjunction with the NFTIdentifierMode modality set to Hash.

    +

    The MetadataMutability option set to Mutable cannot be used in conjunction with the NFTIdentifierMode modality set to Hash.

    \ No newline at end of file diff --git a/resources/tokens/cep78/reverse-lookup/index.html b/resources/tokens/cep78/reverse-lookup/index.html index 74fe80138..e5a087710 100644 --- a/resources/tokens/cep78/reverse-lookup/index.html +++ b/resources/tokens/cep78/reverse-lookup/index.html @@ -1,21 +1,21 @@ - + -Ownership Lookup | Casper Docs - Redux +Ownership Lookup | Casper Docs - Redux - - + +
    Version: Next

    Owner Reverse Lookup Functionality

    In version 1.0 of the CEP-78 Enhanced NFT Standard contract, tracking minted tokens consisted of a single, unbounded list that would grow in size with each additional token. As a result, gas costs would increase over time as the list must be overwritten with each new minting. The related tutorial can be found here.

    In an effort to stabilize the gas costs of larger NFT collections, version 1.1 of CEP-78 includes the use of a pre-allocated page system to track ownership of NFTs within the contract.

    This system stabilizes the cost for interacting with the contract, but not the mint price itself. The size of metadata for a collection, and any differences in that metadata, will still result in some fluctuation in the price for the NFT itself. However, the cost of engaging the system itself will remain stable. Users can expect to pay a higher upfront price for page allocation, but will not need to pay this cost again for any NFTs minted within that given page.

    @@ -47,6 +47,6 @@

    Updated Rec
    cep78_collection_m_350_p_2

    You can determine the token number by multiplying the page_number by the page_size(1,000) and adding the modulo.

    If the NFTIdentifierMode is set to Ordinal, this number corresponds directly to the token ID.

    -

    If it is set to Hash, you will need to reference the HASH_BY_INDEX dictionary to determine the mapping of token numbers to token hashes.

    +

    If it is set to Hash, you will need to reference the HASH_BY_INDEX dictionary to determine the mapping of token numbers to token hashes.

    \ No newline at end of file diff --git a/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html b/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html deleted file mode 100644 index c81fc5553..000000000 --- a/resources/tokens/cep78/using-casper-client/quickstart-guide/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - -Quick Installation | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Casper NFT Quick Installation Guide

    -

    This quick installation guide introduces you to the Casper client commands and Wasm files necessary to deploy a CEP-78 Casper Enhanced NFT contract to the Casper Testnet. For greater detail into the creation and mechanics of the Casper NFT contract, see the complete Casper NFT Tutorial.

    -

    To execute transactions on a Casper network involving NFTs, you will need some CSPR tokens to pay for the transactions. The Testnet provides test tokens using a faucet.

    -

    Prerequisites

    -

    Before using this guide, ensure you meet the following requirements:

    - -

    Setup

    -

    Clone the Casper NFT (CEP-78) contract repository.

    -
    git clone https://github.com/casper-ecosystem/cep-78-enhanced-nft/ && cd cep-78-enhanced-nft
    -

    Run the following commands to build the contract.wasm in the contract/target/wasm32-unknown-unknown/release directory and run the tests.

    -
    make prepare
    make test
    -

    The output of the command would end with the following message:

    -
    test result: ok. 159 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 15.33s
    -

    Installing the NFT Contract

    -

    The following command will install a sample NFT contract on the Testnet:

    -
    casper-client put-deploy --node-address http://localhost:11101/rpc/ \
    --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    --secret-key ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-path contract/target/wasm32-unknown-unknown/release/contract.wasm \
    --session-arg "collection_name:string='CEP-78-collection'" \
    --session-arg "collection_symbol:string='CEP78'" \
    --session-arg "total_token_supply:u64='100'" \
    --session-arg "ownership_mode:u8='2'" \
    --session-arg "nft_kind:u8='1'" \
    --session-arg "nft_metadata_kind:u8='0'" \
    --session-arg "json_schema:string='nft-schema'" \
    --session-arg "identifier_mode:u8='0'" \
    --session-arg "metadata_mutability:u8='0'"
    -

    Next Steps

    -

    Learn to query the contract, perform token transfers, set up approvals, and understand the testing framework.

    -
    - - \ No newline at end of file diff --git a/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html b/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html deleted file mode 100644 index a5985b466..000000000 --- a/resources/tokens/cep78/using-casper-client/testing-NFTs/index.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -Testing NFTs | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Testing NFT Contracts

    -

    Prerequisites

    - -

    Framework Description

    -

    The testing framework in this tutorial uses the Casper engine test support crate for testing the contract implementation against the Casper execution environment.

    -

    The tests source folder contains over 150 tests covering a variety of scenarios, including contract installation, minting and burning tokens, sending transfers, upgrading the contract, and listening to events.

    -

    For more details about the test framework and how each test is set up, visit the Testing Smart Contracts documentation page.

    -

    Running the Tests

    -

    To build and run the tests, issue the following command in the project folder:

    -
    make test
    -

    The project contains a Makefile, which is a custom build script that compiles the contract before running tests in release mode. Then, the script copies the contract.wasm file to the corresponding version folder in a tests/wasm directory. In practice, you only need to run the make test command during development without building the contract separately.

    -

    This example uses bash. If you use a Rust IDE, you must configure it to run the tests.

    - - \ No newline at end of file diff --git a/resources/tokens/index.html b/resources/tokens/index.html index 53e3fdb3c..ae68edd0d 100644 --- a/resources/tokens/index.html +++ b/resources/tokens/index.html @@ -1,21 +1,21 @@ - + -Casper Token Standards | Casper Docs - Redux +Casper Token Standards | Casper Docs - Redux - - + +
    Version: 1.5.X

    Casper Token Standards

    + submit an issue on Github
    Version: Next

    Casper Token Standards

    CEP-18 Casper Fungible Token Standard

    @@ -77,6 +77,6 @@

    TitleDescriptionCEP-78 Enhanced NFT Standard IntroductionAn introduction to the CEP-78 Enhanced NFT Standard.CEP-78 ModalitiesInformation on the features available when installing a CEP-78 contract instance.Installing and Interacting with a CEP-78 ContractAn introduction to features present in the CEP-78 Enhanced NFT Standard.Owner Reverse Lookup FunctionalityInformation on the Onwer Reverse Lookup feature of CEP-78 contracts.A CEP-78 JavaScript Client TutorialA tutorial for using the JavaScript CEP-78 client.

    +
    TitleDescription
    CEP-78 Enhanced NFT Standard IntroductionAn introduction to the CEP-78 Enhanced NFT Standard.
    CEP-78 ModalitiesInformation on the features available when installing a CEP-78 contract instance.
    Installing and Interacting with a CEP-78 ContractAn introduction to features present in the CEP-78 Enhanced NFT Standard.
    Owner Reverse Lookup FunctionalityInformation on the Onwer Reverse Lookup feature of CEP-78 contracts.
    A CEP-78 JavaScript Client TutorialA tutorial for using the JavaScript CEP-78 client.
    \ No newline at end of file diff --git a/next/resources/tokens/using-casper-client/index.html b/resources/tokens/using-casper-client/index.html similarity index 64% rename from next/resources/tokens/using-casper-client/index.html rename to resources/tokens/using-casper-client/index.html index f810d5065..634f5bf8b 100644 --- a/next/resources/tokens/using-casper-client/index.html +++ b/resources/tokens/using-casper-client/index.html @@ -3,23 +3,23 @@ -On-chain Installation | Casper Docs - Redux +On-chain Installation | Casper Docs - Redux - - + +
    Version: Next

    Installing and Interacting with a CEP-78 Contract using the Rust Casper Client

    This documentation will guide you through the process of installing and interacting with an instance of the CEP-78 enhanced NFT standard contract through Casper's Rust CLI client. The contract code installs an instance of CEP-78 as per session arguments provided at the time of installation. It requires a minimum Rust version of 1.63.0.

    -

    Information on the modalities used throughout this installation process can be found in the modalities documentation.

    +

    Information on the modalities used throughout this installation process can be found in the modalities documentation.

    Installing the Contract

    -

    Installing the enhanced NFT contract to global state requires the use of a Deploy. In this case, the session code can be compiled to Wasm by running the make build-contract command provided in the Makefile at the top level. The Wasm will be found in the contract/target/wasm32-unknown-unknown/release directory as contract.wasm.

    +

    Installing the enhanced NFT contract to global state requires the use of a Deploy. In this case, the session code can be compiled to Wasm by running the make build-contract command provided in the Makefile at the top level. The Wasm will be found in the contract/target/wasm32-unknown-unknown/release directory as contract.wasm.

    Below is an example of a casper-client command that provides all required session arguments to install a valid instance of the CEP-78 contract on global state.

    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm
    • @@ -62,7 +62,7 @@

      Inst

      A setting allowing for mutability of metadata. This is only available when using the ordinal identification mode, as the hash mode depends on immutability for identification. In this instance, despite ordinal identification, the 0 represents immutable metadata.

      -

      The session arguments match the available modalities as listed here.

      +

      The session arguments match the available modalities as listed here.

      Casper client command without comments
      casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 500000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/contract/target/wasm32-unknown-unknown/release/contract.wasm \
      --session-arg "collection_name:string='CEP-78-collection'" \
      --session-arg "collection_symbol:string='CEP78'" \
      --session-arg "total_token_supply:u64='100'" \
      --session-arg "ownership_mode:u8='2'" \
      --session-arg "nft_kind:u8='1'" \
      --session-arg "nft_metadata_kind:u8='0'" \
      --session-arg "json_schema:string=''" \
      --session-arg "identifier_mode:u8='0'" \
      --session-arg "metadata_mutability:u8='0'"
      @@ -81,7 +81,7 @@


      casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \ --payment-amount 7500000000 \ -k ~/secret_key.pem \
      --session-hash hash-b3b7a74ae9ef2ea8afc06d6a0830961259605e417e95a53c0cb1ca9737bb0ec7 \
      --session-entry-point "transfer" \
      --session-arg "source_key:key='account-hash-e9ff87766a1d2bab2565bfd5799054946200b51b20c3ca7e54a9269e00fe7cfb'" \
      --session-arg "target_key:key='account-hash-b4782e7c47e4deca5bd90b7adb2d6e884f2d331825d5419d6cbfb59e17642aab'" \
      --session-arg "token_id:u64='0'"

    Minting an NFT

    -

    Below is an example of a casper-client command that uses the mint function of the contract to mint an NFT for the user associated with node-1 in an NCTL environment.

    +

    Below is an example of a casper-client command that uses the mint function of the contract to mint an NFT for the user associated with node-1 in an NCTL environment.

    • casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" --payment-amount 5000000000 -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem --session-path ~/casper/enhanced-nft/client/mint_session/target/wasm32-unknown-unknown/release/mint_call.wasm
    @@ -160,6 +160,6 @@

    Burning an NF
    Casper client command without comments
    casper-client put-deploy -n http://localhost:11101/rpc --chain-name "casper-net-1" \
    --payment-amount 5000000000 \
    -k ~/casper/casper-node/utils/nctl/assets/net-1/nodes/node-1/keys/secret_key.pem \
    --session-hash hash-52e78ae3f6c485d036a74f65ebbb8c75fcc7c33fb42eb667fb32aeba72c63fb5 \
    --session-entry-point "burn" \
    --session-arg "token_id:u64='1'"
    -

    +
    \ No newline at end of file diff --git a/resources/tutorials/advanced/cross-contract/index.html b/resources/tutorials/advanced/cross-contract/index.html index 208b604de..373ed1012 100644 --- a/resources/tutorials/advanced/cross-contract/index.html +++ b/resources/tutorials/advanced/cross-contract/index.html @@ -1,22 +1,21 @@ - + -Cross-Contract Communication | Casper Docs - Redux +Cross-Contract Communication | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Cross-Contract Communication

    + submit an issue on Github
    Version: Next

    Cross-Contract Communication

    This tutorial assumes that you have worked through the following examples. If you have not already done so, then we recommend that you do so now:

    Tutorial Outline

    This tutorial covers some variations of cross-contract communication. Most complex scenarios use cross-contract communication, so it is crucial to understand how this works. It is best explained using the uniswap v2 protocol.

    -

    Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose. The contracts are as follows:

    +

    Uniswap v2 protocol consists of multiple smart contracts which govern a unified blockchain application and each contract serves a different purpose. +The contracts are as follows:

    -

    The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash. The Pair smart contract is used to perform operations like mint or burn on a created pair of tokens.

    +

    The Factory contract is generally used to create a token pair. It throws an event that a pair has been created and allows the user to read the pair created. The most important to notice is that the generation of a token pair actually creates a contract of type Pair under a new address hash. +The Pair smart contract is used to perform operations like mint or burn on a created pair of tokens.

    Having this in mind we will be building two contracts which reference each other in some shape or form. We will look at how the keys are deployed in the contract's context and how we can pass the contract hash into a deployed contract so another contract can be called.

    Creating the Project

    In the appropriate folder, create the project for the contract using the following command:

    cargo casper cross-contract
    -

    This will create the following directory structure within your smart contract folder.

    -
    cross-contract
    ├──contract
    │ ├── Cargo.toml
    │   ├── rust-toolchain
    │   ├── src
    │   │   └── main.rs
    │   └── target
    ├──tests
    │ ├── Cargo.toml
    │ ├── src
    │ │   └── integration_tests.rs
    │ └── target
    └── Makefile
    +

    This will create the following structure under your desired smart contract folder:

    +
    cross-contract/
    └── contract/
    ├── .cargo/
    └── config.toml
    ├── src/
    └── main.rs
    └── Cargo.toml
    └── tests/
    ├── src/
    └── integration-tests.rs
    └── Cargo.toml
    └── .travis.yml
    └── Makefile
    └── rust-toolchain

    After creating the project directory structure, use the following commands to go into the project folder and compile the files:

    cd cross-contract
    make prepare
    make build-contract
    -

    This will produce the .wasm file of our contract. It can be found in contract/target/wasm32-unknown-unknown/release/contract.wasm. Additionally you can check if the tests can be performed using the following command:

    +

    This will also create a target folder under the contract folder where the .wasm of the contract can be found. +Additionally you can check if the tests can be performed using the following command:

    make test

    This should produce the following outcome:

    running 2 tests
    test tests::should_error_on_missing_runtime_arg ... ok
    test tests::should_store_hello_world ... ok

    test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.09s
    -
    tip

    When you try to run the tests, you might encounter errors if the project's dependencies are outdated. If you see an error message similar to the following:

    warning: `tests` (bin "integration-tests" test) generated 2 warnings
    error: could not compile `tests` due to 3 previous errors; 2 warnings emitted
    make: *** [test] Error 101

    This indicates potential issues with outdated dependencies. Use the cargo update command to check for and install any available updates for your project's dependencies or do it manually through Cargo.toml file.

    If you are using cargo extensions in your editor you will see a warning next to the outdated dependencies.

    +
    tip

    If this is not the case and you see the following error:

    warning: `tests` (bin "integration-tests" test) generated 2 warnings
    error: could not compile `tests` due to 3 previous errors; 2 warnings emitted
    make: *** [test] Error 101

    Then it is useful to check if the dependencies in Cargo.toml are still up to date.

    CargoToml

    If you see the red cross, it means the version is not up to date and has to be updated.

    Changing the Standard Contract

    -

    The standard Casper contract from cargo-casper contains some methods that we will reuse. However, we will remove most of the automatically generated code.

    +

    The standard Casper contract from cargo-casper contains some methods that we will reuse. However, we will be getting rid of most auto-generated code.

    We will be changing the main.rs file. Your code should look exactly as below:

    -
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    }
    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    }

    This will serve as a base for introducing the elements needed for cross-contract communication.

    -

    In a contract, you should first define the call entry point. It should be understood as a constructor for the contract. Everything included in the call entry point will be visible as metadata on a Casper network, in the contract's context. You should already be familiar with the call entry point from the Writing a Basic Smart Contract in Rust document. If this is not the case, be sure to familiarize yourself with it now.

    +

    In a contract, you should first define the call entry point. It should be understood as a constructor for the contract. Everything included in the call entry point will be visible as metadata on a Casper network, in the contract's context. +You should already be familiar with the call entry point from the Writing a Basic Smart Contract in Rust document. If this is not the case, be sure to familiarize yourself with it now.

    The contract code, with changes to the call entry point, should look as shown below:

    -
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    // Get the value of the runtime argument named "message"
    let value: String = runtime::get_named_arg("message");

    // The value will be written under a URef
    let value_ref = storage::new_uref(value);

    // Creating the new set of named keys
    // The keys are a Map of String/casper_types::Key
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();

    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key
    // Create a new vector
    let mut params = Vec::new();
    vec.push(Parameter::new("message", CLType::String));

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Describing the metadata for the entry point
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg", // the name of the entry point
    vec, // the arguments which can be passed into the entry point
    CLType::Unit, // return type of the entry point
    EntryPointAccess::Public, // access permissions - public can be accessed always
    EntryPointType::Contract // in most cases it will be contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access the contract hash from the accounts named keys
    runtime::put_key("hello_world_contract", stored_contract_hash.into());

    }
    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };


    #[no_mangle]
    pub extern "C" fn call() {

    // Get the value of the runtime argument named "message"
    let value: String = runtime::get_named_arg("message");

    // The value will be written under a URef
    let value_ref = storage::new_uref(value);

    // Creating the new set of named keys
    // The keys are a Map of String/casper_types::Key
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();

    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the Uref into a casper_types::Key
    // Create a new vector
    let mut params = Vec::new();
    vec.push(Parameter::new("message", CLType::String));

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Describing the metadata for the entry point
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg", // the name of the entry point
    vec, // the arguments which can be passed into the entry point
    CLType::Unit, // return type of the entry point
    EntryPointAccess::Public, // access permissions - public can be accessed always
    EntryPointType::Contract // in most cases it will be contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access the contract hash from the accounts named keys
    runtime::put_key("hello_world_contract", stored_contract_hash.into());

    }
    tip

    runtime and storage appear frequently in our code. If these terms are unfamiliar to you, you should familiarize yourself with the Contract API Modules.

    -

    The metadata for each of the contract's entry points is defined in the call entry point. When installing the contract, the Casper Node will search for the entry point based on the name specified in its metadata. Therefore, each of the entry points defined in the code must share the same name as the String value passed when defining the metadata for the entry point.

    -

    The #[no_mangle] attribute guarantees that the compiler won't alter the entry point's name. It doesn't mandate that the name matches its metadata definition, so developers need to be cautious when specifying entry points.

    +

    The metadata for each of the contract's entry points is defined in the call entry point. When installing the contract, the system will look for the name of the entry point as specified by the metadata for that entry point. Therefore, each of the entry points defined in the code must share the same name as the String value passed when defining the metadata for the entry point.

    +

    The #[no_mangle] flag ensures that the compiler does not modify the name of the entry point. The compiler will not enforce the condition that the name of the entry point is the same value present in its metadata definition, therefore the developer must be careful when defining their entry points.

    In our case, we will define the entry point update_msg in the contract code just before call.

    Your complete contract should match the following:

    -
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };

    #[no_mangle]
    pub extern "C" fn update_msg() {

    let value: String = runtime::get_named_arg("message");
    // Get the uref of the message stored in global state
    let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();
    // Write the message to global state
    storage::write(uref, String::from(value));
    }


    #[no_mangle]
    pub extern "C" fn call() {
    // Get the value of a passed parameter with the key "message"
    let value: String = runtime::get_named_arg("message");
    // The value will be wraped in a URef
    let value_ref = storage::new_uref(value);
    // Creating the new set of named keys
    // The keys are a Map of Key/Value
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();
    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key
    // Create a new vector
    let mut vec = Vec::new();
    vec.push(Parameter::new("message", CLType::String));
    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Define the metadata for the entry point `update_msg`
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points metadata
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("hello_world_contract", stored_contract_hash.into());
    }
    +
    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use alloc::collections::BTreeMap;
    use crate::alloc::string::ToString;


    // Casper crates
    use casper_types::{Key, CLType, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    contract_api::{runtime, storage},
    unwrap_or_revert::UnwrapOrRevert,
    };

    #[no_mangle]
    pub extern "C" fn update_msg() {

    let value: String = runtime::get_named_arg("message");
    // Get the uref of the message stored in global state
    let uref = runtime::get_key("message").unwrap_or_revert().into_uref().unwrap_or_revert();
    // Write the message to global state
    storage::write(uref, String::from(value));
    }


    #[no_mangle]
    pub extern "C" fn call() {
    // Get the value of a passed parameter with the key "message"
    let value: String = runtime::get_named_arg("message");
    // The value will be wraped in a URef
    let value_ref = storage::new_uref(value);
    // Creating the new set of named keys
    // The keys are a Map of Key/Value
    let mut named_keys: BTreeMap<String, Key> = BTreeMap::new();
    // Insert the new value into the named keys
    named_keys.insert(String::from("message"),value_ref.into()); // use into to wrap the value to the key
    // Create a new vector
    let mut vec = Vec::new();
    vec.push(Parameter::new("message", CLType::String));
    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Define the metadata for the entry point `update_msg`
    entry_points.add_entry_point(EntryPoint::new(
    "update_msg",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points metadata
    Some(named_keys), // named keys
    Some("Hello_world_package_name".to_string()), // package name
    Some("Hello_world_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("hello_world_contract", stored_contract_hash.into());
    }
    info

    There is a distinction between storing data in a contract’s NamedKeys and using a dictionary. Dictionaries can be used to store dApp-centric data, but they are not a SQL database and should only be used for data that needs to be stored in global state. Objects referenced in a contract should only be used as links within a bigger application.

    Deploying the Contract

    There are many tools available to send a deploy to a Casper network. The simplest method is to use the Rust CLI with the subcommand put_deploy.

    @@ -94,15 +97,16 @@

    Create Anothe

    This section describes the process of writing an additional contract, which will use an entry point titled call_contract_2 to invoke the update_msg entry point on the previous contract.

    In this tutorial we will be passing the contract hash, as an argument, into the call entry point and use this to perform the calls to the destination contract.

    Prepare the call entry point as described below:

    -

    #[no_mangle]
    pub extern "C" fn call() {

    // Create the list of required runtime arguments for the given entry point.
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let mut named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point metadata definition.
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());
    }

    +

    #[no_mangle]
    pub extern "C" fn call() {

    // Create the list of required runtime arguments for the given entry point.
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let mut named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point metadata definition.
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in the global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());
    }

    This would be the easiest implementation of the call entry point. There is only one entry point which accepts the key contract2 of type String and the key hello_world_contract of the type Key. There aren't any named keys which will be saved in the contract's context. The contract is then stored in global state and placed as an entry within the account's named keys.

    Now that we have defined the metadata for the call_contract_2 entry point, we must now define the entry point itself. This entry point will take the second contract hash as an argument and call the entry point update_msg. It will then pass a message to the second contract as a parameter, which will be stored in that contract’s context.

    -
    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.
    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    // Get the value of the message from the second parameter
    let new_value: String = runtime::get_named_arg("new_message");

    // Call the update_msg entry point on the other contract with the parameter values
    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    "message" => new_value,
    },
    );

    }
    +
    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    // Get the contract hash from the named arguments passed to the `call_contract_2` entry point.
    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    // Get the value of the message from the second parameter
    let new_value: String = runtime::get_named_arg("new_message");

    // Call the update_msg entry point on the other contract with the parameter values
    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    "message" => new_value,
    },
    );

    }

    Your complete contract implementation should look as follows:

    -

    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use crate::alloc::string::ToString;
    use crate::runtime_args::RuntimeArgs;

    // Casper crates
    use casper_types::{
    api_error::ApiError,
    contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    unwrap_or_revert::UnwrapOrRevert,
    contract_api::{runtime, storage},
    };

    // The contract key in the account named keys
    const CONTRACT_HASH: &str = "hello_world_contract";

    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    let new_value: String = runtime::get_named_arg("new_message");

    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    // key => value
    "message" => new_value,
    },
    );

    }

    #[no_mangle]
    pub extern "C" fn call() {

    // Create a new vector - this will be the signature of the entrypoint
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point to the entry points object
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());

    }
    +

    #![no_std]
    #![no_main]

    #[cfg(not(target_arch = "wasm32"))]
    compile_error!("target arch should be wasm32: compile with '--target wasm32-unknown-unknown'");

    // We need to explicitly import the std alloc crate and `alloc::string::String` as we are in a
    // `no_std` environment.
    extern crate alloc;

    // The elementary types
    use alloc::string::String;
    use alloc::vec::Vec;
    use crate::alloc::string::ToString;
    use crate::runtime_args::RuntimeArgs;

    // Casper crates
    use casper_types::{
    api_error::ApiError,
    contracts::NamedKeys, runtime_args, CLType, Key, ContractHash, Parameter, EntryPoint, EntryPoints, EntryPointType, EntryPointAccess};

    use casper_contract::{
    unwrap_or_revert::UnwrapOrRevert,
    contract_api::{runtime, storage},
    };

    // The contract key in the account named keys
    const CONTRACT_HASH: &str = "hello_world_contract";

    #[no_mangle]
    pub extern "C" fn call_contract_2() {

    let contract_hash: ContractHash = runtime::get_named_arg::<Key>(CONTRACT_HASH)
    .into_hash()
    .map(|hash| ContractHash::new(hash))
    .unwrap();

    let new_value: String = runtime::get_named_arg("new_message");

    let _: () = runtime::call_contract(
    contract_hash,
    "update_msg",
    runtime_args! {
    // key => value
    "message" => new_value,
    },
    );

    }

    #[no_mangle]
    pub extern "C" fn call() {

    // Create a new vector - this will be the signature of the entrypoint
    let mut vec = Vec::new();
    vec.push(Parameter::new("new_message", CLType::String));
    vec.push(Parameter::new("hello_world_contract", CLType::Key));

    // In the named keys of the contract, add a key for the count.
    let named_keys = NamedKeys::new();

    // Create an Entry Point Object
    let mut entry_points = EntryPoints::new();

    // Add the entry point to the entry points object
    entry_points.add_entry_point(EntryPoint::new(
    "call_contract_2",
    vec,
    CLType::Unit,
    EntryPointAccess::Public,
    EntryPointType::Contract
    ));

    // The contract is stored in global state
    let (stored_contract_hash, _contract_version) = storage::new_contract(
    entry_points, // entry points
    Some(named_keys), // named keys
    Some("contract2_package_name".to_string()), // package name
    Some("contract2_access_uref".to_string()) // access uref
    );

    // To access from the account - named keys of the account
    runtime::put_key("cross_contract_2", stored_contract_hash.into());

    }

    After you run make build-contract in your second contract's directory, you should obtain the outcome:

    cd contract && cargo build --release --target wasm32-unknown-unknown
    Compiling contract v0.1.0 (/Users/karolmarter/Desktop/Rust_Projects/cross-contract-2/contract)
    Finished release [optimized] target(s) in 0.69s
    wasm-strip contract/target/wasm32-unknown-unknown/release/contract.wasm 2>/dev/null | true
    -

    Create the keys subfolder and copy the keys from the keys subfolder in the first contract into this subfolder. The call from the terminal will look as follows:

    +

    Create the keys subfolder and copy the keys from the keys subfolder in the first contract into this subfolder. +The call from the terminal will look as follows:

    casper-client put-deploy \
    --node-address http://136.243.187.84:7777 \
    --chain-name casper-test \
    --secret-key ./keys/secret_key.pem \
    --payment-amount 20000000000 \
    --session-path ./contract/target/wasm32-unknown-unknown/release/contract.wasm
    tip

    You may have noticed that the contract.wasm is always output to the same filename for each new cargo casper project. You can change this by editing the Makefile in the main directory. You can then observe the result by recompiling your contract with these commands;

    make prepare
    make build-contract

    After the deploy we can check if it was successful and inspect the runtime arguments of the deployed entry points.

    @@ -112,7 +116,7 @@

    Create Anothe

    Observing the deploy, we can see that it succeeded:

    casper-client get-deploy \
    --node-address http://136.243.187.84:7777 af42bc6dbc58f677d138eb968d897f965f1ed118a40980bc16efbcc2a0c71832

    In the execution_results JSON element we should see "Success".

    -

    "execution_results": [
    {
    "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",
    "result": {
    "Success": {
    "cost": "16580565260",
    "effect": { ...

    }
    }
    }
    }
    ]

    +

    "execution_results": [
    {
    "block_hash": "bc3040214e46fe0eaa9d98150a8a67a1033b931619dbc3e5f1a841d3a2d6f869",
    "result": {
    "Success": {
    "cost": "16580565260",
    "effect": { ...

    }
    }
    }
    }
    ]

    Get the state root hash of the current network state:

    casper-client get-state-root-hash --node-address http://136.243.187.84:7777

    The result of invoking theget-state-root-hash command is:

    @@ -155,6 +159,6 @@

    Summary

    +
    \ No newline at end of file diff --git a/resources/tutorials/advanced/index.html b/resources/tutorials/advanced/index.html index 134d5a12e..13db2c4d1 100644 --- a/resources/tutorials/advanced/index.html +++ b/resources/tutorials/advanced/index.html @@ -1,21 +1,21 @@ - + -Advanced Tutorials | Casper Docs - Redux +Advanced Tutorials | Casper Docs - Redux - - + +
    Version: 1.5.X

    Advanced Tutorials

    + submit an issue on Github
    Version: Next

    Advanced Tutorials

    @@ -53,6 +53,6 @@ -
    TitleDescription
    Two-Party Multi-Signature DeploysA trivial two-party multi-signature scheme for signing and sending deploys
    Multi-Sig ManagementIntegrate key management on Casper accounts and sign deploys with multiple keys
    Interacting with Runtime Return ValuesContract code returning a value to the immediate caller via runtime::ret()
    Safely Transfer Tokens to a ContractTwo methods to handle tokens via a contract
    Reading and Writing to Global State using RustMethods to read and write data to global state on a Casper network using Rust
    Cross Contract CommunicationVariations of cross-contract communication for more complex scenarios
    Working with Authorization KeysRetrieve and use the authorization keys associated with a deploy
    +
    TitleDescription
    Two-Party Multi-Signature TransactionsA trivial two-party multi-signature scheme for signing and sending transactions
    Multi-Sig ManagementIntegrate key management on Casper accounts and sign transactions with multiple keys
    Interacting with Runtime Return ValuesContract code returning a value to the immediate caller via runtime::ret()
    Safely Transfer Tokens to a ContractTwo methods to handle tokens via a contract
    Reading and Writing to Global State using RustMethods to read and write data to global state on a Casper network using Rust
    Cross Contract CommunicationVariations of cross-contract communication for more complex scenarios
    Working with Authorization KeysRetrieve and use the authorization keys associated with a transaction
    \ No newline at end of file diff --git a/resources/tutorials/advanced/list-cspr/index.html b/resources/tutorials/advanced/list-cspr/index.html index 61023991b..088f8847a 100644 --- a/resources/tutorials/advanced/list-cspr/index.html +++ b/resources/tutorials/advanced/list-cspr/index.html @@ -1,21 +1,21 @@ - + -Listing CSPR | Casper Docs - Redux +Listing CSPR | Casper Docs - Redux - - + +
    Version: 1.5.X

    Listing CSPR on an Exchange

    + submit an issue on Github
    Version: Next

    Listing CSPR on an Exchange

    This topic describes how to list the Casper token (CSPR) on a cryptocurrency exchange.

    caution

    The Casper Signer has been deprecated and replaced with the Casper Wallet. We are in the process of updating this page. Meanwhile, visit the guide on Building with the Casper Wallet.

    Setting up a Node

    @@ -60,15 +60,15 @@

    The Casp
  • Exchanges can check finality signatures. Validators send finality signatures after the finalized block is executed and global state is updated. The Casper node streams execution effects and finality signatures through an SSE architecture. For more information about various events, see Monitoring and Consuming Events.
  • Staking Integration for Exchanges

    -

    Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the JavaScript SDK to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found here.

    +

    Exchanges seeking to integrate CSPR staking mechanisms will need to understand the processes of delegation, undelegation and redelegation through deploys on a Casper network. The following outlines the use of the JavaScript SDK to perform these actions, as well as parameters relating to staking. Further information about staking on a Casper network can be found here.

    Deploy Structures and Parameters

    Staking operations consists of two parts:

    1. -

      Creating a deploy object

      +

      Creating a deploy object

    2. -

      Signing the deploy

      +

      Signing the deploy

    The staking deploy requires the following information:

    @@ -147,6 +147,6 @@

    Costs and

    The Delegation Cap

    Casper includes a delegator limit rule, which limits the number of delegators that a single validator may have at 953. This is a temporary solution to prevent complications with Casper’s fast sync mechanism - in which high bond counts could break fast sync.

    Validators with a delegator count at or above 953 at the time of the 1.4.5 upgrade were grandfathered in, however new delegators will not be able to delegate to any validator until the delegator count for that validator falls below 953.

    -

    Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their CSPR to that validator. However, no new delegators may join the validator until it drops below the 953 limit.

    +

    Existing delegators may continue to delegate additional CSPR, regardless of the current number of delegators staking their CSPR to that validator. However, no new delegators may join the validator until it drops below the 953 limit.

    \ No newline at end of file diff --git a/resources/tutorials/advanced/return-values-tutorial/index.html b/resources/tutorials/advanced/return-values-tutorial/index.html index 43992c67f..62b3a57c9 100644 --- a/resources/tutorials/advanced/return-values-tutorial/index.html +++ b/resources/tutorials/advanced/return-values-tutorial/index.html @@ -1,21 +1,21 @@ - + -Runtime Return Values | Casper Docs - Redux +Runtime Return Values | Casper Docs - Redux - - + +
    Version: 1.5.X

    Interacting with Runtime Return Values

    + submit an issue on Github
    Version: Next

    Interacting with Runtime Return Values

    Users interacting with a Casper network must keep in mind the differences between session and contract code. Session code executes entirely within the context of the initiating account, while contract code executes within the context of its own state. Any action undertaken by a contract must initiate through an outside call, usually via session code.

    Developers should note the difference between a caller and an immediate caller. The immediate caller represents the session or contract code that directly accessed the entry point. The caller is the original, initiating session code that started the entire process. There are many cases where contract code may call additional contract code. In this case, the immediate caller may be another instance of contract code. Even in this event, the overall caller will be the initiating session code, while there may be several layers of stacked contract code acting as immediate callers.

    Contract code can optionally return a value to their immediate caller via runtime::ret(), whether that immediate caller is another contract code or session code. The returned value may be used within the context of the session or contract code, stored for later use, or discarded if not needed. Use of return values depends entirely on what the developer needs in that instance.

    @@ -30,6 +30,6 @@

    Session

    #[no_mangle]
    pub extern "C" fn call() {
    let fundraiser_contract_hash: ContractHash = runtime::get_named_arg(FUNDRAISER_CONTRACT_HASH);
    let donating_account_key: Key = runtime::get_named_arg(DONATING_ACCOUNT_KEY);
    let donation_amount: U512 = runtime::get_named_arg(DONATION_AMOUNT);

    let donating_purse_uref: URef = runtime::call_contract(
    fundraiser_contract_hash,
    ENTRY_POINT_DONATE,
    runtime_args! {
    DONATING_ACCOUNT_KEY => donating_account_key
    },
    );
    system::transfer_from_purse_to_purse(
    account::get_main_purse(),
    donating_purse_uref,
    donation_amount,
    None
    )
    .unwrap_or_revert()
    }

    This session code calls into a contract's entry point by using runtime::call_contract, supplying the contract_hash to identify the contract to be called, and the name of the entry point to be invoked, in this case donate. It supplies the donating_account_key, which in this case is the account key of the caller. The contract will then provide a return value, in this case donating_purse_uref. To call an entry point, you will need to know the CLType of the return value and identify it within the code.

    You can determine the type of the return value by querying the contract object in global state. To query a contract rather than an account, replace the key parameter with the formatted string representation of the contract hash.

    -

    This example code takes that returned value and transfers a donation_amount from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer.

    +

    This example code takes that returned value and transfers a donation_amount from the calling account's main purse to the established donation purse. It is not necessary for the code to store, or even use, the returned value. Use of the returned value depends on the needs of the developer.

    \ No newline at end of file diff --git a/resources/tutorials/advanced/storage-workflow/index.html b/resources/tutorials/advanced/storage-workflow/index.html index e84b6eebc..a241835a2 100644 --- a/resources/tutorials/advanced/storage-workflow/index.html +++ b/resources/tutorials/advanced/storage-workflow/index.html @@ -1,26 +1,26 @@ - + -Storage Workflow | Casper Docs - Redux +Storage Workflow | Casper Docs - Redux - - + +
    Version: 1.5.X

    Reading and Writing to Global State using Rust

    + submit an issue on Github
    Version: Next

    Reading and Writing to Global State using Rust

    The following examples outline methods to read and write data to global state on a Casper network using the Rust programming language.

    Essentially, there are three means of storage within the Casper ecosystem. These consist of runtime::put_key, storage::write(alongside storage::new_uref as explained below) and storage::dictionary_put. These stored values can be read using runtime::get_key, storage::read and storage::dictionary_get, respectively. Each method stores data in a specific way, and it's important to understand the differences.

    Description of Functions

    runtime::put_key / runtime::get_key

    -

    Both the put_key and get_key functions refer to Casper Key types as outlined in both the Understanding Hash Types and Serialization Standard. These keys are stored within a URef as a Key type.

    +

    Both the put_key and get_key functions refer to Casper Key types as outlined in both the Understanding Hash Types and Serialization Standard. These keys are stored within a URef as a Key type.

    storage::write / storage::read

    storage::write writes a given value to a previously established URef (created using storage::new_uref). Unlike put_key, this value is not one of the Key types listed above, but rather any of the potential CLTypes as outlined. storage::read provides a method to retrieve these values from the associated URef.

    storage:dictionary_put / storage::dictionary_get

    @@ -42,6 +42,6 @@

    list_named_keys - Returns the named keys of the current context
  • has_key - Returns true if the key exists in the current context’s named keys
  • remove_key - Removes the requested NamedKey from the current context
  • -

    +
    \ No newline at end of file diff --git a/resources/tutorials/advanced/transfer-token-to-contract/index.html b/resources/tutorials/advanced/transfer-token-to-contract/index.html index 2771499cd..6d91bbd77 100644 --- a/resources/tutorials/advanced/transfer-token-to-contract/index.html +++ b/resources/tutorials/advanced/transfer-token-to-contract/index.html @@ -1,21 +1,21 @@ - + -Token Transfers | Casper Docs - Redux +Token Transfers | Casper Docs - Redux - - + +
    Version: 1.5.X

    Safely Transfer Tokens to a Contract

    + submit an issue on Github
    Version: Next

    Safely Transfer Tokens to a Contract

    This tutorial covers two methods to handle tokens via a contract. This is not a native process to a Casper network and will require the use of custom code. The following two scenarios provide a framework for developers and the pros and cons of each example. Developers should choose the option that best suits their individual needs.

    For increased security, token transfers from a main purse must be handled via session code (WASM), as shown here. Therefore, transfer-* methods are unavailable in stored WASM for tokens originating from an account's main purse, even when the stored WASM runs in the account context.

    Scenario 1 - Creating a Throw-Away Purse

    @@ -34,6 +34,6 @@

    Scenario 2 - Maint
    // Scenario 2: with this style, the contract being called has some internal accounting
    // to keep track of a reusable purse associated to the calling account; this avoids
    // wasteful creation of one time purses but requires the smart contract being called
    // to have more sophisticated internal logic.
    #[no_mangle]
    pub extern "C" fn call() {
    let amount: U512 = runtime::get_named_arg("amount");

    // This is demonstrating the most direct case, wherein you pass in the contract_hash and
    // the entry_point_names of the target contract as args.
    // With prior setup having been done, this can also be simplified.
    let contract_hash = runtime::get_named_arg("contract_hash");
    // the name of the entry point on the contract that returns a purse uref to receive token at
    // the actual name of the entry point is up to the smart contract authors
    let deposit_point_name = runtime::get_named_arg("deposit_point_name");
    // whatever entry point on the smart contract does the actual work if token has been transferred
    // the actual name of which is up to the smart contract authors.
    let other_entry_point_name = runtime::get_named_arg("other_entry_point_name");

    // The smart contract returns a purse URef of a deposit purse (with ADD access rights only)
    // for the caller to transfer to.
    let deposit_purse: URef = runtime::call_contract(contract_hash, deposit_point_name, runtime_args! {});

    // transfer from the caller's purse to the purse provided by the contract; the transfer is handled
    // safely by the host and the caller's purse is never exposed to the called smart contract.
    system::transfer_from_purse_to_purse(account::get_main_purse(), deposit_purse, amount, None)
    .unwrap_or_revert();

    // The contract being interacted with looks up the associated purse, checks its balance, etc.
    // within its logic. That side of it is entirely up to the smart contract authors to code; the caller
    // merely calls the logic. Also, the entry point might require one or more runtime arguments.
    // In all cases some discovery of the API of the contract you are calling is necessary.
    runtime::call_contract(contract_hash, other_entry_point_name, runtime_args! {});
    }

    Scenario 2 - Advanced Variation

    In Scenario 2, the contract in question maintains a purse for each associated caller. The advanced variation establishes an internal ledger that records the balance of each caller. The contract can record the information for each caller as a dictionary item and respond accordingly. In this fashion, a single purse can store the motes of all callers accessing the contract.

    -

    This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup.

    +

    This design streamlines the internal accounting process of the contract but does require a greater degree of complexity during the initial setup.

    \ No newline at end of file diff --git a/resources/tutorials/advanced/two-party-multi-sig/index.html b/resources/tutorials/advanced/two-party-multi-sig/index.html index 61fa3d2d8..849603901 100644 --- a/resources/tutorials/advanced/two-party-multi-sig/index.html +++ b/resources/tutorials/advanced/two-party-multi-sig/index.html @@ -1,27 +1,27 @@ - + -Two-Party Multi-Sig | Casper Docs - Redux +Two-Party Multi-Sig | Casper Docs - Redux - - + +
    Version: 1.5.X

    Two-Party Multi-Signature Deploys

    -

    Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.

    + submit an issue on Github
    Version: Next

    Two-Party Multi-Signature Deploys

    +

    Accounts on a Casper network can associate other accounts to allow or require a multiple-signature scheme for deploys.

    This workflow describes how a trivial two-party multi-signature scheme for signing and sending deploys can be enforced for an account on a Casper network. This workflow assumes:

    1. You meet the prerequisites, including having the Casper command-line client and a valid node address
    2. You have the main account's PublicKey hex (MA) and another PublicKey hex to associate (AA)
    3. -
    4. You have previously sent deploys to a Casper network
    5. +
    6. You have previously sent deploys to a Casper network

    Configuring the Main Account

    caution

    Incorrect account configurations could render accounts defunct and unusable. We highly recommend executing any changes to an account in a test environment like Testnet before performing them in a live environment like Mainnet.

    @@ -61,7 +61,7 @@

    Confirming Processing and Account Status

    -

    Account configuration on a Casper blockchain is stored in a Merkle Tree and is a snapshot of the blockchain's Global State. The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the state-root-hash and is stored in every executed block.

    +

    Account configuration on a Casper blockchain is stored in a Merkle Tree and is a snapshot of the blockchain's Global State. The representation of global state for a given block can be computed by executing the deploys (including transfers) within the block and its ancestors. The root node of the Merkle Tree identifying a particular state is called the state-root-hash and is stored in every executed block.

    To check that the account was configured correctly, you need the state-root-hash corresponding to the block that contains your deploy. To obtain the state-root-hash, you need to:

    1. Confirm the execution status of the deploy and obtain the hash of the block containing it
    2. @@ -73,6 +73,6 @@

      {
      "id": 1126043166167626077,
      "jsonrpc": "2.0",
      "result": {
      "api_version": "1.0.0",
      "merkle_proof": "2226 chars",
      "stored_value": {
      "Account": {
      "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
      "action_thresholds": {
      "deployment": 2,
      "key_management": 2
      },
      "associated_keys": [
      {
      "account_hash": "account-hash-12dee9fe535bfd8fd335fce1ba1f972f26bb60029a303b310d85419357d18f51",
      "weight": 1
      },
      {
      "account_hash": "account-hash-dc88a1819381c5ebbc3432e5c1d94df18cdcd7253b85259eeebe0ec8661bb84a",
      "weight": 1
      }
      ],
      "main_purse": "uref-74b20e9722d3f087f9dc431e9f0fcc6a803c256e005fa45b64a101512001cb78-007",
      "named_keys": []
      }
      }
      }
      }

    -

    In the example output, you can see the account hashes listed within the associated_keys section. Each key has weight 1; since the action threshold for deployment is 2, neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold.

    +

    In the example output, you can see the account hashes listed within the associated_keys section. Each key has weight 1; since the action threshold for deployment is 2, neither account can sign and send a deploy individually. Thus, the deploy needs to be signed by the secret keys of each account to reach the required threshold.

    \ No newline at end of file diff --git a/resources/tutorials/beginner/aws-node/index.html b/resources/tutorials/beginner/aws-node/index.html index a8c88b1ed..629a1ac04 100644 --- a/resources/tutorials/beginner/aws-node/index.html +++ b/resources/tutorials/beginner/aws-node/index.html @@ -1,21 +1,21 @@ - + -AWS Casper Nodes | Casper Docs - Redux +AWS Casper Nodes | Casper Docs - Redux - - + +
    Version: 1.5.X

    Launching a Casper Node with AWS Marketplace

    + submit an issue on Github
    Version: Next

    Launching a Casper Node with AWS Marketplace

    The following tutorial outlines the process for launching a Casper Node through the Amazon AWS Marketplace.

    Step 1 - Subscribing

    You will first need to subscribe to the Casper node software through the AWS Marketplace. There is no associated cost with this subscription.

    @@ -67,6 +67,6 @@

    EC2 Ke

    Step 12

    Launching Your Node

    If you are satisfied with your configuration choices and all options are correctly filled out, you can hit the orange Launch button to launch your AWS-hosted Casper node.

    -

    Step 13

    +

    Step 13

    \ No newline at end of file diff --git a/resources/tutorials/beginner/cep18/index.html b/resources/tutorials/beginner/cep18/index.html index 488bf221a..a4e33ad47 100644 --- a/resources/tutorials/beginner/cep18/index.html +++ b/resources/tutorials/beginner/cep18/index.html @@ -1,22 +1,21 @@ - + -Fungible Tokens | Casper Docs - Redux +Fungible Tokens | Casper Docs - Redux - - + +
    \ No newline at end of file diff --git a/resources/tutorials/beginner/getting-started-tutorial/index.html b/resources/tutorials/beginner/getting-started-tutorial/index.html index 4b6ac78f3..1c4ed077b 100644 --- a/resources/tutorials/beginner/getting-started-tutorial/index.html +++ b/resources/tutorials/beginner/getting-started-tutorial/index.html @@ -1,24 +1,24 @@ - + -Getting Started | Casper Docs - Redux +Getting Started | Casper Docs - Redux - - + +
    Version: Next

    Getting Started Video

    This video guide is a step-by-step tutorial for setting up your Casper development environment and a sample project. You can follow along and also consult the corresponding Getting Started documentation.

    -

    +

    \ No newline at end of file diff --git a/resources/tutorials/beginner/index.html b/resources/tutorials/beginner/index.html index e8d280b27..448b463e5 100644 --- a/resources/tutorials/beginner/index.html +++ b/resources/tutorials/beginner/index.html @@ -1,21 +1,21 @@ - + -Overview | Casper Docs - Redux +Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    Overview

    + submit an issue on Github
    +
    TitleDescription
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    \ No newline at end of file diff --git a/resources/tutorials/beginner/querying-network/index.html b/resources/tutorials/beginner/querying-network/index.html index abfdc1de0..f1d092175 100644 --- a/resources/tutorials/beginner/querying-network/index.html +++ b/resources/tutorials/beginner/querying-network/index.html @@ -1,21 +1,21 @@ - + -Querying a Node | Casper Docs - Redux +Querying a Node | Casper Docs - Redux - - + +
    Version: Next

    Querying a Casper Node

    The Casper node supports queries for users and developers to obtain information stored on the blockchain.

    This document assumes:

      @@ -115,6 +115,6 @@

      Querying De
    1. id - JSON-RPC identifier, applied to the request and returned in the response. If not provided, a random integer will be assigned
    2. node-address - An IP address of a node on the network
    3. deploy-hash - Hex-encoded hash of the deploy
    4. -

    +
    \ No newline at end of file diff --git a/resources/tutorials/beginner/upgrade-contract/index.html b/resources/tutorials/beginner/upgrade-contract/index.html index 3e6635872..57369c4af 100644 --- a/resources/tutorials/beginner/upgrade-contract/index.html +++ b/resources/tutorials/beginner/upgrade-contract/index.html @@ -1,22 +1,21 @@ - + -Contract Upgrades | Casper Docs - Redux +Contract Upgrades | Casper Docs - Redux - - + +
    Version: 1.5.X

    Upgrading a Contract

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Upgrading a Contract

    This tutorial examines how to upgrade an existing contract, a process similar to upgrading any other software. You can change an unlocked contract package by adding a new contract and updating the default contract version that the contract package should use. You will need to know the contract package hash and use the add_contract_version API. You can also create a locked contract package that cannot be versioned and is therefore not upgradable.

    Video Tutorial

    Here is a video walkthrough of this tutorial.

    @@ -24,7 +23,7 @@

    Video Tutoria

    Prerequisites

    note

    Installing the first version of the contract (contract-v1.wasm) as shown in the counter tutorial is a prerequisite before installing the second version of the contract (contract-v2.wasm).

    @@ -32,7 +31,6 @@

    Prerequisites<
    • contract-v1 is the counter contract you can see in the A Counter on the Testnet tutorial.
    • contract-v2 is the contract with the new counter_decrement entry point.
    • -
    • contract-v3 is the contract with the new get_last_updated_at entry point and last_updated_at named key.

    Contract Versioning Flow

    The following is an example workflow for creating a versioned contract package. Your workflow may differ if you have already created the contract package and have a handle on its hash.

    @@ -57,10 +55,10 @@

    Step 2. Add a new contract to the package

    There are many changes you could make to a Casper contract, like adding new entry points, modifying the behavior of an existing entry point, or completely re-writing the contract.

    To add a new contract version in the package, invoke the add_contract_version function and pass in the ContractPackageHash, EntryPoints, and NamedKeys. In the counter example, you will find the add_contract_version call here.

    -
        let (contract_hash, contract_version) =
    storage::add_contract_version(contract_package_hash,
    entry_points,
    named_keys);
    +
        let (contract_hash, contract_version) = 
    storage::add_contract_version(contract_package_hash,
    entry_points,
    named_keys);

    Explanation of arguments:

      -
    • contract_package_hash - This hash directs you to the contract package. See Hash and Key Explanations.
    • +
    • contract_package_hash - This hash directs you to the contract package. See Hash and Key Explanations.
    • entry_points - Entry points of the contract, which can be modified or newly added.
    • named_keys - Named key pairs of the contract.
    @@ -75,7 +73,7 @@

    make prepare

    make build-contract

    Step 4. Install the contract

    -

    Install the contract on the network via a deploy and verify the deploy status. You can also monitor the event stream to see when your deploy is accepted.

    +

    Install the contract on the network via a deploy and verify the deploy status. You can also monitor the event stream to see when your deploy is accepted.

    To observe the upgrade workflow, you can install the second contract version on the chain. This version contains the counter_decrement entry point.

    note

    Installing the first version of the contract, as shown in the Counter tutorial, is a prerequisite before installing the second version.

    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-path [PATH]/contract-v2/target/wasm32-unknown-unknown/release/counter-v2.wasm
    @@ -110,8 +108,8 @@

    S

    Call the new entry point, counter_decrement, using the package name and check the results.

    casper-client put-deploy \
    --node-address http://[NODE_IP]:7777 \
    --chain-name [CHAIN_NAME] \
    --secret-key [PATH_TO_YOUR_KEY]/secret_key.pem \
    --payment-amount [PAYMENT_AMOUNT_IN_MOTES] \
    --session-package-name "counter_package_name" \
    --session-entry-point "counter_decrement"

    After calling the entry point, the count value should be decremented. You can verify it by querying the network again using the new state root hash.

    Disabling and Enabling Contract Versions

    @@ -121,22 +119,8 @@

    note

    Be aware that calling a contract package will use the most recent contract version. It is not necessary to disable a previous contract version, unless you have a specific need to do so.

    Creating a Locked Contract Package

    You can create a locked contract package with the new_locked_contract function. This contract can never be upgraded.

    -
    let (stored_contract_hash, _) = storage::new_locked_contract(
    contract_entry_points,
    Some(contract_named_keys),
    Some("contract_package_name".to_string()),
    Some("contract_access_uref".to_string()),
    );
    +
    let (stored_contract_hash, _) = storage::new_locked_contract(
    contract_entry_points,
    Some(contract_named_keys),
    Some("contract_package_name".to_string()),
    Some("contract_access_uref".to_string()),
    );

    Apply the contract entry points and named keys when you call the function. You can also specify a hash_name and uref_name that will be put in the context's named keys. You do not need to save the version number returned since the version of this contract package would always be equal to 1.

    -
    note

    Creating a locked contract package is an irreversible decision. To upgrade a contract, use new_contract as Step 1 explains.

    -

    Adding New Fields During Upgrades

    -

    contract-v3 demonstrates adding new data storage to your contract. It introduces a new field for the last update timestamp.

    -

    Key Steps:

    -
      -
    1. -

      Define a Named Key: A key (LAST_UPDATED_KEY) references the new field.

      -
    2. -
    3. -

      Initialize the Field: A URef is created using storage::new_uref to point to the storage location. It's then added to NamedKeys along with the key.

      -
    4. -
    -

    Code Breakdown:

    -
    // Create NamedKeys and initialize the new field (last_updated) with default value (0).
    let mut named_keys = NamedKeys::new();
    let last_updated = storage::new_uref(0_u64);
    named_keys.insert(String::from(LAST_UPDATED_KEY), last_updated.into());
    -

    For a deeper dive into the implementation details, explore the contract-v3 code itself. This hands-on exploration will further solidify your understanding of adding new fields during contract upgrades.

    +
    note

    Creating a locked contract package is an irreversible decision. To upgrade a contract, use new_contract as Step 1 explains.

    \ No newline at end of file diff --git a/runtime/index.html b/runtime/index.html index 4756c590f..b0aea14de 100644 --- a/runtime/index.html +++ b/runtime/index.html @@ -1,39 +1,63 @@ - + -Runtime | Casper Docs - Redux +Runtime | Casper Docs - Redux - - + +
    Version: 1.5.X

    Runtime Economics

    -

    The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. Pending state pruning implementation, disk space use is treated as CPU time usage and charged, irreversibly, per byte written. Currently, gas is allocated according to a first-in, first-out model for deploys, with a fixed price of 1 mote (1/109 part of a CSPR token) per 1 unit of gas.

    -

    Gas allocation

    -

    Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas. We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant CEPs. In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme.

    -

    Consensus before execution & basics of payment

    -

    The Highway protocol in its Mainnet implementation reaches consensus on a block before the block is executed, introducing a subtle difference from platforms like Ethereum. In addition, deploys sent to a Casper network can only be selected based on claimed, rather than used, gas. Consequently, to incentivize user-side optimization and prevent block space exhaustion by poorly optimized deploys, the platform provides no refunds for unused gas.

    -

    Additionally, a minimal amount of CSPR must be present in the user account's main purse to ensure that the payment computation is covered. The community may introduce additional balance checks in the future.

    + submit an issue on Github
    Version: Next

    Runtime Economics

    +

    The economics of the runtime layer should incentivize efficient allocation of computational resources, primarily CPU time, to users. The Condor release has introduced several new economic features:

    +
      +
    • A new mode of paying for computation in Mainnet, where tokens previously assessed as fees are now held for a predetermined period. Held tokens become available to users at the expiry of a predetermined time, or on a linear schedule over a specified period. Note: Increasing the duration of holds reduces the long-run equilibrium average available CSPR balance for an attacker. See Fee Elimination for more details.
    • +
    • A form of dynamic pricing that increments or decrements the gas price in motes for a new era depending on blockchain utilization in the previous era.
    • +
    • Blocks are structured into lanes that can only hold a particular number of transactions of specified types.
    • +
    +

    These economic features are configurable using chainspec parameters.

    +

    Gas Allocation

    +

    Any finite resource on a publicly accessible computer network must be rate-limited, as, otherwise, overuse of this resource is an attack vector -- a minimal requirement for platform security. However, rate-limiting, implemented on our platform as a simple block gas limit with several lanes, leaves the platform with the problem of fairly and efficiently allocating the gas.

    +

    We are researching the optimal structure for spot and futures gas markets, and interested readers should consult the relevant CEPs. In the meantime, this section outlines some basic features of the platform that would underpin any allocation scheme. Currently, gas is allocated according to a first-in, first-out transaction model.

    +

    Consensus before execution & basics of payment

    +

    The Zug and Highway protocols reach consensus on a block before it is executed, introducing a subtle difference from platforms like Ethereum. In addition, transactions sent to a Casper network can only be selected based on claimed rather than used gas.

    +

    Additionally, a minimal amount of CSPR must be present in the user account or contract's main purse to cover the payment computation. The community may introduce additional balance checks in the future.

    Costs and limits

    -

    Gas cost is a measure of relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific more complex host-side functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the chainspec and may vary according to arguments.

    -

    We expect to refine the current gas cost table to reflect time use more closely, with updates introduced in future upgrades. We also anticipate that, with the introduction of state pruning, storage costs will be calculated separately from computing time.

    -

    Lanes

    -

    The block gas limit is split into two lanes, one for native transfers and one for general deploys. The number of transfers, which cost a fixed amount of gas, is governed directly by the block_max_transfer_count chainspec parameter, set to 2500 when Mainnet launched.

    -

    Gas fees

    -

    Currently, the price of gas is fixed at 1 mote per 1 unit of gas.

    -

    Fee allocation

    -

    All fees from a particular block accrue to its proposer, incentivizing non-empty block production and allowing major dApps to execute deploys for free, provided they operate a validator node and are comfortable with the latency introduced by validator scheduling.

    -

    Spot pricing

    -

    Please see CEP #22 for one potential design of a gas spot market.

    -

    Futures pricing

    -

    Please see CEP #17 for our draft proposal of a gas futures market.

    +

    Gas cost is a measure of the relative time used by different primitive operations of the execution engine, which is also assumed to be additive. By additivity, we mean that the time to execute a program is approximately proportional to the sum of gas expended by the opcodes and functions called within the program. Casper assigns gas costs to primitive execution engine opcodes and specific, more complex host-side functions that are callable from within the execution engine context. Gas costs for opcodes and host-side functions are specified in the chainspec and may vary according to arguments. Read more about how Casper measures computational work here.

    +

    We expect to refine the current gas cost table to more closely reflect time use, with updates introduced in future upgrades.

    +

    Lanes and gas costs

    +

    There are several platform parameters that delineate the sets of transactions that may be included in a valid block:

    +
      +
    • Number of lanes and lane types +
        +
      • System interaction lanes for Mint (transfers) and Auction transactions.
      • +
      • WASM lanes serving transactions that carry opaque WASM. These lanes come with different slot sizes. Users need to specify a fixed quantity of gas for a transaction.
      • +
      • All lanes can contain some finite number of transactions, set separately for each lane.
      • +
      • For a call to a smart contract, the gas cost is always the same (given the transaction category), but the amount of CSPR that gets locked depends also on the gas price at the time.
      • +
      +
    • +
    • Block gas and size limits +
        +
      • The block gas limit imposes an absolute ceiling on how much gas can be allocated to the occupied slots.
      • +
      • The block size limit imposes an absolute ceiling on the total byte size of included transactions.
      • +
      • Individual transaction size limits are also enforced.
      • +
      +
    • +
    +

    These are the lane configuration settings for the Condor release on Mainnet:

    +
    [transactions.v1]
    # The configuration settings for the lanes of transactions including both native and Wasm based interactions.
    # Currently the node supports two native interactions the mint and auction and have the reserved identifiers of 0 and 1
    # respectively
    # The remaining wasm based lanes specify the range of configuration settings for a given Wasm based transaction
    # within a given lane.
    # The maximum length in bytes of runtime args per V1 transaction.
    # [0] -> Transaction lane label (apart from the reserved native identifiers these are simply labels)
    # Note: For the given mainnet implementation we specially reserve the label 2 for install and upgrades and
    # the lane must be present and defined.
    # Different casper networks may not impose such a restriction.
    # [1] -> Max transaction size in bytes for a given transaction in a certain lane
    # [2] -> Max args length size in bytes for a given transaction in a certain lane
    # [3] -> Transaction gas limit size in bytes for a given transaction in a certain lane
    # [4] -> The maximum number of transactions the lane can contain
    native_mint_lane = [0, 1024, 1024, 65_000_000_000, 650]
    native_auction_lane = [1, 2048, 2048, 362_500_000_000, 145]
    wasm_lanes = [[2, 1_048_576, 2048, 1_000_000_000_000, 1], [3, 344_064, 1024, 500_000_000_000, 3], [4, 172_032, 1024, 50_000_000_000, 7], [5, 12_288, 512, 1_500_000_000, 15]]
    +

    These are the block gas and size limits for the Condor release on Mainnet:

    +
    [transactions]
    ...
    # Maximum block size in bytes including transactions contained by the block. 0 means unlimited.
    max_block_size = 5_242_880
    # The upper limit of total gas of all transactions in a block.
    block_gas_limit = 3_300_000_000_000
    +

    Dynamic Gas Pricing

    +

    A dynamic gas pricing system assigns the gas price based on block vacancy (or consumption), preventing malicious actors from flooding the network with useless transactions and ensuring network integrity. Dynamic gas pricing acts as a supply and demand-based check on the cost of network usage. If usage is low, the price multiple drifts down over time, incentivizing casual usage. If usage is high, the price multiple climbs up, incentivizing prioritized usage. Dynamic gas pricing also protects against long-range consumption attacks. An attacker attempting to fill blocks to deny usage drives the price up, which requires them to have increasing amounts of tokens available to cover rising gas costs to maintain their attack.

    +

    Eliminating Gas Fees

    +

    See Gas and Fee Elimination for more details.

    \ No newline at end of file diff --git a/sdk/index.html b/sdk/index.html index 8d26b5bd7..70df8fd53 100644 --- a/sdk/index.html +++ b/sdk/index.html @@ -1,26 +1,26 @@ - + -SDK Client Libraries | Casper Docs - Redux +SDK Client Libraries | Casper Docs - Redux - - + +
    Version: 1.5.X

    SDK Client Libraries

    + submit an issue on Github
    Version: Next

    SDK Client Libraries

    This section covers the software development kits (SDKs) published by third parties available for interacting with the Casper blockchain. These SDKs are client-side libraries providing functions or methods (depending on the language) to interact with a Casper network. You can use them as a model to develop your application and accomplish tasks such as generating account keys, sending transfers, or other blockchain transactions.

    Each of these SDKs can be used to build dApps. For browser interaction, you can use the JavaScript SDK; for desktop applications, there are C# and Java SDKs. Click the link on your preferred SDK to learn how to use it in dApp development. To delve into the source code, you may visit the SDKs' Github repositories.

    Each such third party is solely responsible for the SDK it provides, any warranties (to the extent that such warranties have not been disclaimed), and for any claims you may have relating to your access or use thereof. We do not approve or endorse any such SDKs by providing a link thereto, and assume no responsibility for your access or use thereof. The SDKs may be subject to additional licenses and disclaimers as set out in the relevant GitHub repositories.

    Serialization Standard

    -

    The Casper platform uses a custom serialization format. To this end, we've established a Serialization Standard, which must be followed when building a Casper SDK.

    +

    The Casper platform uses a custom serialization format. To this end, we've established a Serialization Standard, which must be followed when building a Casper SDK.

    JSON-RPC API

    Developers can interact directly with the Casper JSON-RPC API instead of using an SDK.

    Table of Contents

    @@ -69,6 +69,6 @@

    Table of C -
    SDK DocumentationGitHub LocationOrganization
    JavaScript/TypeScriptcasper-js-sdkCasper Ecosystem
    Java SDKcasper-java-sdkCasper Association
    C# SDKcasper-net-sdkMAKE
    Go SDKcasper-go-sdkMAKE
    Python SDKcasper-python-sdkCasper Association
    PHP SDKcasper-php-sdkMAKE
    Scala SDKcasper-scala-sdkM. Abahmane

    +
    SDK DocumentationGitHub LocationOrganization
    JavaScript/TypeScriptcasper-js-sdkCasper Ecosystem
    Java SDKcasper-java-sdkCasper Association
    C# SDKcasper-net-sdkMAKE
    Go SDKcasper-go-sdkMAKE
    Python SDKcasper-python-sdkCasper Association
    PHP SDKcasper-php-sdkMAKE
    Scala SDKcasper-scala-sdkM. Abahmane
    \ No newline at end of file diff --git a/search/index.html b/search/index.html index 8470f26fb..77734459e 100644 --- a/search/index.html +++ b/search/index.html @@ -3,18 +3,18 @@ -Search the documentation | Casper Docs - Redux +Search the documentation | Casper Docs - Redux - - + +

    Search the documentation

    + submit an issue on Github

    Search the documentation

    \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml index 4732eea6f..661990857 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -1 +1 @@ -https://casper-devrel.github.io/blog/weekly0.5https://casper-devrel.github.io/blog/addressable-entity/weekly0.5https://casper-devrel.github.io/blog/archive/weekly0.5https://casper-devrel.github.io/blog/authors/weekly0.5https://casper-devrel.github.io/blog/authors/alexanderlimonov/weekly0.5https://casper-devrel.github.io/blog/authors/dylanireland/weekly0.5https://casper-devrel.github.io/blog/authors/melpadden/weekly0.5https://casper-devrel.github.io/blog/authors/sczembor/weekly0.5https://casper-devrel.github.io/blog/condor-fee-elimination/weekly0.5https://casper-devrel.github.io/blog/condor-local-setup/weekly0.5https://casper-devrel.github.io/blog/condor-validator-rewards/weekly0.5https://casper-devrel.github.io/blog/tags/weekly0.5https://casper-devrel.github.io/blog/tags/condor/weekly0.5https://casper-devrel.github.io/blog/tags/docs-redux/weekly0.5https://casper-devrel.github.io/blog/tags/features/weekly0.5https://casper-devrel.github.io/blog/tags/hello/weekly0.5https://casper-devrel.github.io/blog/tags/new-docs/weekly0.5https://casper-devrel.github.io/blog/tags/setup/weekly0.5https://casper-devrel.github.io/blog/tags/tokenomics/weekly0.5https://casper-devrel.github.io/blog/tags/validators/weekly0.5https://casper-devrel.github.io/blog/welcome-docs-redux/weekly0.5https://casper-devrel.github.io/search/weekly0.5https://casper-devrel.github.io/next/weekly0.5https://casper-devrel.github.io/next/concepts/weekly0.5https://casper-devrel.github.io/next/concepts/accounts-and-keys/weekly0.5https://casper-devrel.github.io/next/concepts/addressable-entity/weekly0.5https://casper-devrel.github.io/next/concepts/callstack/weekly0.5https://casper-devrel.github.io/next/concepts/design/casper-design/weekly0.5https://casper-devrel.github.io/next/concepts/design/consensus/weekly0.5https://casper-devrel.github.io/next/concepts/design/highway/weekly0.5https://casper-devrel.github.io/next/concepts/design/networking-protocol/weekly0.5https://casper-devrel.github.io/next/concepts/design/p2p/weekly0.5https://casper-devrel.github.io/next/concepts/design/reading-and-writing-to-the-blockchain/weekly0.5https://casper-devrel.github.io/next/concepts/design/rewards/weekly0.5https://casper-devrel.github.io/next/concepts/design/zug/weekly0.5https://casper-devrel.github.io/next/concepts/dictionaries/weekly0.5https://casper-devrel.github.io/next/concepts/economics/consensus/weekly0.5https://casper-devrel.github.io/next/concepts/economics/dynamic-gas-pricing/weekly0.5https://casper-devrel.github.io/next/concepts/economics/fee-elimination/weekly0.5https://casper-devrel.github.io/next/concepts/economics/gas-concepts/weekly0.5https://casper-devrel.github.io/next/concepts/economics/staking/weekly0.5https://casper-devrel.github.io/next/concepts/global-state/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/A/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/B/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/C/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/D/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/E/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/F/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/G/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/H/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/I/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/J/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/K/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/L/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/M/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/N/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/O/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/P/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/Q/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/R/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/S/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/T/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/U/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/V/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/W/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/X/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/Y/weekly0.5https://casper-devrel.github.io/next/concepts/glossary/Z/weekly0.5https://casper-devrel.github.io/next/concepts/intro-to-dapps/weekly0.5https://casper-devrel.github.io/next/concepts/key-types/weekly0.5https://casper-devrel.github.io/next/concepts/list-auth-keys/weekly0.5https://casper-devrel.github.io/next/concepts/serialization/weekly0.5https://casper-devrel.github.io/next/concepts/serialization/primitives/weekly0.5https://casper-devrel.github.io/next/concepts/serialization/structures/weekly0.5https://casper-devrel.github.io/next/concepts/serialization/types/weekly0.5https://casper-devrel.github.io/next/concepts/smart-contracts/weekly0.5https://casper-devrel.github.io/next/counter-testnet/weekly0.5https://casper-devrel.github.io/next/counter/weekly0.5https://casper-devrel.github.io/next/design/weekly0.5https://casper-devrel.github.io/next/developers/weekly0.5https://casper-devrel.github.io/next/developers/cli/weekly0.5https://casper-devrel.github.io/next/developers/cli/calling-contracts/weekly0.5https://casper-devrel.github.io/next/developers/cli/delegate/weekly0.5https://casper-devrel.github.io/next/developers/cli/execution-error-codes/weekly0.5https://casper-devrel.github.io/next/developers/cli/installing-contracts/weekly0.5https://casper-devrel.github.io/next/developers/cli/opcode-costs/weekly0.5https://casper-devrel.github.io/next/developers/cli/querying-global-state/weekly0.5https://casper-devrel.github.io/next/developers/cli/redelegate/weekly0.5https://casper-devrel.github.io/next/developers/cli/sending-transactions/weekly0.5https://casper-devrel.github.io/next/developers/cli/transfers/weekly0.5https://casper-devrel.github.io/next/developers/cli/transfers/direct-token-transfer/weekly0.5https://casper-devrel.github.io/next/developers/cli/transfers/multisig-deploy-transfer/weekly0.5https://casper-devrel.github.io/next/developers/cli/transfers/verify-transfer/weekly0.5https://casper-devrel.github.io/next/developers/cli/undelegate/weekly0.5https://casper-devrel.github.io/next/developers/cli/verifying-contracts/weekly0.5https://casper-devrel.github.io/next/developers/dapps/weekly0.5https://casper-devrel.github.io/next/developers/dapps/dapp/weekly0.5https://casper-devrel.github.io/next/developers/dapps/monitor-and-consume-events/weekly0.5https://casper-devrel.github.io/next/developers/dapps/nctl-test/weekly0.5https://casper-devrel.github.io/next/developers/dapps/prerequisites/weekly0.5https://casper-devrel.github.io/next/developers/dapps/sdk/client-library-usage/weekly0.5https://casper-devrel.github.io/next/developers/dapps/sdk/csharp-sdk/weekly0.5https://casper-devrel.github.io/next/developers/dapps/sdk/go-sdk/weekly0.5https://casper-devrel.github.io/next/developers/dapps/sdk/python-sdk/weekly0.5https://casper-devrel.github.io/next/developers/dapps/sdk/script-sdk/weekly0.5https://casper-devrel.github.io/next/developers/dapps/setup-nctl/weekly0.5https://casper-devrel.github.io/next/developers/dapps/signing-a-transaction/weekly0.5https://casper-devrel.github.io/next/developers/dapps/speculative-exec/weekly0.5https://casper-devrel.github.io/next/developers/dapps/technology-stack/weekly0.5https://casper-devrel.github.io/next/developers/dapps/template-frontend/weekly0.5https://casper-devrel.github.io/next/developers/dapps/uref-security/weekly0.5https://casper-devrel.github.io/next/developers/essential-crates/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/errors/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/guidance/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/json-rpc-informational/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/json-rpc-pos/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/json-rpc-transactional/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/minimal-compliance/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/types_chain/weekly0.5https://casper-devrel.github.io/next/developers/json-rpc/types_cl/weekly0.5https://casper-devrel.github.io/next/developers/prerequisites/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/assembly-script/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/best-practices/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/calling-contracts/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/contract-hash-vs-package-hash/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/contract-vs-session/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/emitting-contract-events/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/factory-pattern/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/getting-started/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/simple-contract/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/testing-contracts/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/testing-session-code/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/upgrading-contracts/weekly0.5https://casper-devrel.github.io/next/developers/writing-onchain-code/writing-session-code/weekly0.5https://casper-devrel.github.io/next/disclaimer/weekly0.5https://casper-devrel.github.io/next/economics/weekly0.5https://casper-devrel.github.io/next/glossary/weekly0.5https://casper-devrel.github.io/next/operators/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/bonding/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/change-bid-public-key/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/inactive-vs-faulty/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/recovering/weekly0.5https://casper-devrel.github.io/next/operators/becoming-a-validator/unbonding/weekly0.5https://casper-devrel.github.io/next/operators/maintenance/weekly0.5https://casper-devrel.github.io/next/operators/maintenance/archiving-and-restoring/weekly0.5https://casper-devrel.github.io/next/operators/maintenance/moving-node/weekly0.5https://casper-devrel.github.io/next/operators/setup-network/weekly0.5https://casper-devrel.github.io/next/operators/setup-network/chain-spec/weekly0.5https://casper-devrel.github.io/next/operators/setup-network/create-private/weekly0.5https://casper-devrel.github.io/next/operators/setup-network/genesis/weekly0.5https://casper-devrel.github.io/next/operators/setup-network/staging-files-for-new-network/weekly0.5https://casper-devrel.github.io/next/operators/setup/weekly0.5https://casper-devrel.github.io/next/operators/setup/basic-node-configuration/weekly0.5https://casper-devrel.github.io/next/operators/setup/casper-sidecar/weekly0.5https://casper-devrel.github.io/next/operators/setup/fast-sync/weekly0.5https://casper-devrel.github.io/next/operators/setup/hardware/weekly0.5https://casper-devrel.github.io/next/operators/setup/install-node/weekly0.5https://casper-devrel.github.io/next/operators/setup/joining/weekly0.5https://casper-devrel.github.io/next/operators/setup/node-endpoints/weekly0.5https://casper-devrel.github.io/next/operators/setup/node-events/weekly0.5https://casper-devrel.github.io/next/operators/setup/non-root-user/weekly0.5https://casper-devrel.github.io/next/operators/setup/open-files/weekly0.5https://casper-devrel.github.io/next/operators/setup/upgrade/weekly0.5https://casper-devrel.github.io/next/resources/weekly0.5https://casper-devrel.github.io/next/resources/advanced/list-auth-keys-tutorial/weekly0.5https://casper-devrel.github.io/next/resources/advanced/multi-sig/weekly0.5https://casper-devrel.github.io/next/resources/advanced/multi-sig/multi-sig-workflow/weekly0.5https://casper-devrel.github.io/next/resources/advanced/multi-sig/other-scenarios/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter-testnet/commands/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter-testnet/overview/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter-testnet/walkthrough/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter/commands/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter/overview/weekly0.5https://casper-devrel.github.io/next/resources/beginner/counter/walkthrough/weekly0.5https://casper-devrel.github.io/next/resources/build-on-casper/casper-open-source-software/weekly0.5https://casper-devrel.github.io/next/resources/build-on-casper/introduction/weekly0.5https://casper-devrel.github.io/next/resources/changelog/weekly0.5https://casper-devrel.github.io/next/resources/moving-to-casper/weekly0.5https://casper-devrel.github.io/next/resources/quick-start/weekly0.5https://casper-devrel.github.io/next/resources/tokens/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep18/full-tutorial/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep18/query/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep18/quickstart-guide/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep18/tests/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep18/transfer/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep78/introduction/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep78/js-tutorial/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep78/modalities/weekly0.5https://casper-devrel.github.io/next/resources/tokens/cep78/reverse-lookup/weekly0.5https://casper-devrel.github.io/next/resources/tokens/using-casper-client/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/cross-contract/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/list-cspr/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/return-values-tutorial/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/storage-workflow/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/transfer-token-to-contract/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/advanced/two-party-multi-sig/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/aws-node/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/cep18/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/getting-started-tutorial/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/querying-network/weekly0.5https://casper-devrel.github.io/next/resources/tutorials/beginner/upgrade-contract/weekly0.5https://casper-devrel.github.io/next/runtime/weekly0.5https://casper-devrel.github.io/next/sdk/weekly0.5https://casper-devrel.github.io/next/transactions-and-transaction-lifecycle/weekly0.5https://casper-devrel.github.io/next/transactions/weekly0.5https://casper-devrel.github.io/next/users/weekly0.5https://casper-devrel.github.io/next/users/block-explorer/weekly0.5https://casper-devrel.github.io/next/users/csprlive/weekly0.5https://casper-devrel.github.io/next/users/delegate-ui/weekly0.5https://casper-devrel.github.io/next/users/delegating/weekly0.5https://casper-devrel.github.io/next/users/funding-from-exchanges/weekly0.5https://casper-devrel.github.io/next/users/ledger/weekly0.5https://casper-devrel.github.io/next/users/ledger/ledger-cspr-live/weekly0.5https://casper-devrel.github.io/next/users/ledger/ledger-live/weekly0.5https://casper-devrel.github.io/next/users/staking-ledger/weekly0.5https://casper-devrel.github.io/next/users/testnet-faucet/weekly0.5https://casper-devrel.github.io/next/users/token-transfer/weekly0.5https://casper-devrel.github.io/next/users/undelegate-ui/weekly0.5https://casper-devrel.github.io/next/workflow/ledger-setup/weekly0.5https://casper-devrel.github.io/next/writing-contracts/weekly0.5https://casper-devrel.github.io/concepts/weekly0.5https://casper-devrel.github.io/concepts/accounts-and-keys/weekly0.5https://casper-devrel.github.io/concepts/callstack/weekly0.5https://casper-devrel.github.io/concepts/design/casper-design/weekly0.5https://casper-devrel.github.io/concepts/design/highway/weekly0.5https://casper-devrel.github.io/concepts/design/networking-protocol/weekly0.5https://casper-devrel.github.io/concepts/design/p2p/weekly0.5https://casper-devrel.github.io/concepts/design/reading-and-writing-to-the-blockchain/weekly0.5https://casper-devrel.github.io/concepts/dictionaries/weekly0.5https://casper-devrel.github.io/concepts/economics/concepts/weekly0.5https://casper-devrel.github.io/concepts/economics/consensus/weekly0.5https://casper-devrel.github.io/concepts/economics/delegation/weekly0.5https://casper-devrel.github.io/concepts/economics/gas-concepts/weekly0.5https://casper-devrel.github.io/concepts/global-state/weekly0.5https://casper-devrel.github.io/concepts/glossary/A/weekly0.5https://casper-devrel.github.io/concepts/glossary/B/weekly0.5https://casper-devrel.github.io/concepts/glossary/C/weekly0.5https://casper-devrel.github.io/concepts/glossary/D/weekly0.5https://casper-devrel.github.io/concepts/glossary/E/weekly0.5https://casper-devrel.github.io/concepts/glossary/F/weekly0.5https://casper-devrel.github.io/concepts/glossary/G/weekly0.5https://casper-devrel.github.io/concepts/glossary/H/weekly0.5https://casper-devrel.github.io/concepts/glossary/I/weekly0.5https://casper-devrel.github.io/concepts/glossary/J/weekly0.5https://casper-devrel.github.io/concepts/glossary/K/weekly0.5https://casper-devrel.github.io/concepts/glossary/L/weekly0.5https://casper-devrel.github.io/concepts/glossary/M/weekly0.5https://casper-devrel.github.io/concepts/glossary/N/weekly0.5https://casper-devrel.github.io/concepts/glossary/O/weekly0.5https://casper-devrel.github.io/concepts/glossary/P/weekly0.5https://casper-devrel.github.io/concepts/glossary/Q/weekly0.5https://casper-devrel.github.io/concepts/glossary/R/weekly0.5https://casper-devrel.github.io/concepts/glossary/S/weekly0.5https://casper-devrel.github.io/concepts/glossary/T/weekly0.5https://casper-devrel.github.io/concepts/glossary/U/weekly0.5https://casper-devrel.github.io/concepts/glossary/V/weekly0.5https://casper-devrel.github.io/concepts/glossary/W/weekly0.5https://casper-devrel.github.io/concepts/glossary/X/weekly0.5https://casper-devrel.github.io/concepts/glossary/Y/weekly0.5https://casper-devrel.github.io/concepts/glossary/Z/weekly0.5https://casper-devrel.github.io/concepts/hash-types/weekly0.5https://casper-devrel.github.io/concepts/intro-to-dapps/weekly0.5https://casper-devrel.github.io/concepts/list-auth-keys/weekly0.5https://casper-devrel.github.io/concepts/serialization-standard/weekly0.5https://casper-devrel.github.io/concepts/smart-contracts/weekly0.5https://casper-devrel.github.io/counter-testnet/weekly0.5https://casper-devrel.github.io/counter/weekly0.5https://casper-devrel.github.io/deploy-and-deploy-lifecycle/weekly0.5https://casper-devrel.github.io/design/weekly0.5https://casper-devrel.github.io/developers/weekly0.5https://casper-devrel.github.io/developers/cli/weekly0.5https://casper-devrel.github.io/developers/cli/calling-contracts/weekly0.5https://casper-devrel.github.io/developers/cli/delegate/weekly0.5https://casper-devrel.github.io/developers/cli/execution-error-codes/weekly0.5https://casper-devrel.github.io/developers/cli/installing-contracts/weekly0.5https://casper-devrel.github.io/developers/cli/opcode-costs/weekly0.5https://casper-devrel.github.io/developers/cli/querying-global-state/weekly0.5https://casper-devrel.github.io/developers/cli/redelegate/weekly0.5https://casper-devrel.github.io/developers/cli/sending-deploys/weekly0.5https://casper-devrel.github.io/developers/cli/transfers/weekly0.5https://casper-devrel.github.io/developers/cli/transfers/direct-token-transfer/weekly0.5https://casper-devrel.github.io/developers/cli/transfers/multisig-deploy-transfer/weekly0.5https://casper-devrel.github.io/developers/cli/transfers/verify-transfer/weekly0.5https://casper-devrel.github.io/developers/cli/undelegate/weekly0.5https://casper-devrel.github.io/developers/dapps/weekly0.5https://casper-devrel.github.io/developers/dapps/dapp/weekly0.5https://casper-devrel.github.io/developers/dapps/monitor-and-consume-events/weekly0.5https://casper-devrel.github.io/developers/dapps/nctl-test/weekly0.5https://casper-devrel.github.io/developers/dapps/prerequisites/weekly0.5https://casper-devrel.github.io/developers/dapps/sdk/client-library-usage/weekly0.5https://casper-devrel.github.io/developers/dapps/sdk/csharp-sdk/weekly0.5https://casper-devrel.github.io/developers/dapps/sdk/go-sdk/weekly0.5https://casper-devrel.github.io/developers/dapps/sdk/python-sdk/weekly0.5https://casper-devrel.github.io/developers/dapps/sdk/script-sdk/weekly0.5https://casper-devrel.github.io/developers/dapps/setup-nctl/weekly0.5https://casper-devrel.github.io/developers/dapps/signing-a-deploy/weekly0.5https://casper-devrel.github.io/developers/dapps/speculative-exec/weekly0.5https://casper-devrel.github.io/developers/dapps/technology-stack/weekly0.5https://casper-devrel.github.io/developers/dapps/template-frontend/weekly0.5https://casper-devrel.github.io/developers/dapps/uref-security/weekly0.5https://casper-devrel.github.io/developers/essential-crates/weekly0.5https://casper-devrel.github.io/developers/json-rpc/weekly0.5https://casper-devrel.github.io/developers/json-rpc/errors/weekly0.5https://casper-devrel.github.io/developers/json-rpc/guidance/weekly0.5https://casper-devrel.github.io/developers/json-rpc/json-rpc-informational/weekly0.5https://casper-devrel.github.io/developers/json-rpc/json-rpc-pos/weekly0.5https://casper-devrel.github.io/developers/json-rpc/json-rpc-transactional/weekly0.5https://casper-devrel.github.io/developers/json-rpc/minimal-compliance/weekly0.5https://casper-devrel.github.io/developers/json-rpc/types_chain/weekly0.5https://casper-devrel.github.io/developers/json-rpc/types_cl/weekly0.5https://casper-devrel.github.io/developers/prerequisites/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/assembly-script/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/best-practices/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/calling-contracts/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/contract-hash-vs-package-hash/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/contract-vs-session/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/getting-started/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/simple-contract/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/testing-contracts/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/testing-session-code/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/upgrading-contracts/weekly0.5https://casper-devrel.github.io/developers/writing-onchain-code/writing-session-code/weekly0.5https://casper-devrel.github.io/disclaimer/weekly0.5https://casper-devrel.github.io/economics/weekly0.5https://casper-devrel.github.io/glossary/weekly0.5https://casper-devrel.github.io/operators/weekly0.5https://casper-devrel.github.io/operators/becoming-a-validator/weekly0.5https://casper-devrel.github.io/operators/becoming-a-validator/bonding/weekly0.5https://casper-devrel.github.io/operators/becoming-a-validator/inactive-vs-faulty/weekly0.5https://casper-devrel.github.io/operators/becoming-a-validator/recovering/weekly0.5https://casper-devrel.github.io/operators/becoming-a-validator/unbonding/weekly0.5https://casper-devrel.github.io/operators/maintenance/weekly0.5https://casper-devrel.github.io/operators/maintenance/archiving-and-restoring/weekly0.5https://casper-devrel.github.io/operators/maintenance/moving-node/weekly0.5https://casper-devrel.github.io/operators/setup-network/weekly0.5https://casper-devrel.github.io/operators/setup-network/chain-spec/weekly0.5https://casper-devrel.github.io/operators/setup-network/create-private/weekly0.5https://casper-devrel.github.io/operators/setup-network/genesis/weekly0.5https://casper-devrel.github.io/operators/setup-network/staging-files-for-new-network/weekly0.5https://casper-devrel.github.io/operators/setup/weekly0.5https://casper-devrel.github.io/operators/setup/basic-node-configuration/weekly0.5https://casper-devrel.github.io/operators/setup/fast-sync/weekly0.5https://casper-devrel.github.io/operators/setup/hardware/weekly0.5https://casper-devrel.github.io/operators/setup/install-node/weekly0.5https://casper-devrel.github.io/operators/setup/joining/weekly0.5https://casper-devrel.github.io/operators/setup/node-endpoints/weekly0.5https://casper-devrel.github.io/operators/setup/non-root-user/weekly0.5https://casper-devrel.github.io/operators/setup/open-files/weekly0.5https://casper-devrel.github.io/operators/setup/upgrade/weekly0.5https://casper-devrel.github.io/resources/weekly0.5https://casper-devrel.github.io/resources/advanced/list-auth-keys-tutorial/weekly0.5https://casper-devrel.github.io/resources/advanced/multi-sig/weekly0.5https://casper-devrel.github.io/resources/advanced/multi-sig/multi-sig-workflow/weekly0.5https://casper-devrel.github.io/resources/advanced/multi-sig/other-scenarios/weekly0.5https://casper-devrel.github.io/resources/beginner/counter-testnet/commands/weekly0.5https://casper-devrel.github.io/resources/beginner/counter-testnet/overview/weekly0.5https://casper-devrel.github.io/resources/beginner/counter-testnet/walkthrough/weekly0.5https://casper-devrel.github.io/resources/beginner/counter/commands/weekly0.5https://casper-devrel.github.io/resources/beginner/counter/overview/weekly0.5https://casper-devrel.github.io/resources/beginner/counter/walkthrough/weekly0.5https://casper-devrel.github.io/resources/build-on-casper/casper-open-source-software/weekly0.5https://casper-devrel.github.io/resources/build-on-casper/introduction/weekly0.5https://casper-devrel.github.io/resources/condor-for-exchanges/weekly0.5https://casper-devrel.github.io/resources/moving-to-casper/weekly0.5https://casper-devrel.github.io/resources/quick-start/weekly0.5https://casper-devrel.github.io/resources/tokens/weekly0.5https://casper-devrel.github.io/resources/tokens/cep18/full-tutorial/weekly0.5https://casper-devrel.github.io/resources/tokens/cep18/query/weekly0.5https://casper-devrel.github.io/resources/tokens/cep18/quickstart-guide/weekly0.5https://casper-devrel.github.io/resources/tokens/cep18/tests/weekly0.5https://casper-devrel.github.io/resources/tokens/cep18/transfer/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/introduction/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/js-tutorial/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/modalities/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/reverse-lookup/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/using-casper-client/full-installation-tutorial/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/using-casper-client/querying-NFTs/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/using-casper-client/quickstart-guide/weekly0.5https://casper-devrel.github.io/resources/tokens/cep78/using-casper-client/testing-NFTs/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/cross-contract/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/list-cspr/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/return-values-tutorial/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/storage-workflow/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/transfer-token-to-contract/weekly0.5https://casper-devrel.github.io/resources/tutorials/advanced/two-party-multi-sig/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/aws-node/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/cep18/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/getting-started-tutorial/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/querying-network/weekly0.5https://casper-devrel.github.io/resources/tutorials/beginner/upgrade-contract/weekly0.5https://casper-devrel.github.io/runtime/weekly0.5https://casper-devrel.github.io/sdk/weekly0.5https://casper-devrel.github.io/staking/weekly0.5https://casper-devrel.github.io/users/weekly0.5https://casper-devrel.github.io/users/block-explorer/weekly0.5https://casper-devrel.github.io/users/csprlive/weekly0.5https://casper-devrel.github.io/users/delegate-ui/weekly0.5https://casper-devrel.github.io/users/funding-from-exchanges/weekly0.5https://casper-devrel.github.io/users/ledger/weekly0.5https://casper-devrel.github.io/users/ledger/ledger-cspr-live/weekly0.5https://casper-devrel.github.io/users/ledger/ledger-live/weekly0.5https://casper-devrel.github.io/users/staking-ledger/weekly0.5https://casper-devrel.github.io/users/testnet-faucet/weekly0.5https://casper-devrel.github.io/users/token-transfer/weekly0.5https://casper-devrel.github.io/users/undelegate-ui/weekly0.5https://casper-devrel.github.io/workflow/ledger-setup/weekly0.5https://casper-devrel.github.io/writing-contracts/weekly0.5https://casper-devrel.github.io/weekly0.5 \ No newline at end of file +https://casper-network.github.io/blog/weekly0.5https://casper-network.github.io/blog/addressable-entity/weekly0.5https://casper-network.github.io/blog/archive/weekly0.5https://casper-network.github.io/blog/authors/weekly0.5https://casper-network.github.io/blog/authors/alexanderlimonov/weekly0.5https://casper-network.github.io/blog/authors/dylanireland/weekly0.5https://casper-network.github.io/blog/authors/melpadden/weekly0.5https://casper-network.github.io/blog/authors/sczembor/weekly0.5https://casper-network.github.io/blog/condor-fee-elimination/weekly0.5https://casper-network.github.io/blog/condor-local-setup/weekly0.5https://casper-network.github.io/blog/condor-validator-rewards/weekly0.5https://casper-network.github.io/blog/tags/weekly0.5https://casper-network.github.io/blog/tags/condor/weekly0.5https://casper-network.github.io/blog/tags/docs-redux/weekly0.5https://casper-network.github.io/blog/tags/features/weekly0.5https://casper-network.github.io/blog/tags/hello/weekly0.5https://casper-network.github.io/blog/tags/new-docs/weekly0.5https://casper-network.github.io/blog/tags/setup/weekly0.5https://casper-network.github.io/blog/tags/tokenomics/weekly0.5https://casper-network.github.io/blog/tags/validators/weekly0.5https://casper-network.github.io/blog/welcome-docs-redux/weekly0.5https://casper-network.github.io/search/weekly0.5https://casper-network.github.io/1.5.X/weekly0.5https://casper-network.github.io/1.5.X/concepts/weekly0.5https://casper-network.github.io/1.5.X/concepts/accounts-and-keys/weekly0.5https://casper-network.github.io/1.5.X/concepts/callstack/weekly0.5https://casper-network.github.io/1.5.X/concepts/design/casper-design/weekly0.5https://casper-network.github.io/1.5.X/concepts/design/highway/weekly0.5https://casper-network.github.io/1.5.X/concepts/design/networking-protocol/weekly0.5https://casper-network.github.io/1.5.X/concepts/design/p2p/weekly0.5https://casper-network.github.io/1.5.X/concepts/design/reading-and-writing-to-the-blockchain/weekly0.5https://casper-network.github.io/1.5.X/concepts/dictionaries/weekly0.5https://casper-network.github.io/1.5.X/concepts/economics/concepts/weekly0.5https://casper-network.github.io/1.5.X/concepts/economics/consensus/weekly0.5https://casper-network.github.io/1.5.X/concepts/economics/delegation/weekly0.5https://casper-network.github.io/1.5.X/concepts/economics/gas-concepts/weekly0.5https://casper-network.github.io/1.5.X/concepts/global-state/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/A/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/B/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/C/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/D/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/E/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/F/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/G/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/H/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/I/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/J/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/K/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/L/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/M/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/N/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/O/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/P/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/Q/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/R/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/S/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/T/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/U/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/V/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/W/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/X/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/Y/weekly0.5https://casper-network.github.io/1.5.X/concepts/glossary/Z/weekly0.5https://casper-network.github.io/1.5.X/concepts/hash-types/weekly0.5https://casper-network.github.io/1.5.X/concepts/intro-to-dapps/weekly0.5https://casper-network.github.io/1.5.X/concepts/list-auth-keys/weekly0.5https://casper-network.github.io/1.5.X/concepts/serialization-standard/weekly0.5https://casper-network.github.io/1.5.X/concepts/smart-contracts/weekly0.5https://casper-network.github.io/1.5.X/counter-testnet/weekly0.5https://casper-network.github.io/1.5.X/counter/weekly0.5https://casper-network.github.io/1.5.X/deploy-and-deploy-lifecycle/weekly0.5https://casper-network.github.io/1.5.X/design/weekly0.5https://casper-network.github.io/1.5.X/developers/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/calling-contracts/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/delegate/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/execution-error-codes/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/installing-contracts/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/opcode-costs/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/querying-global-state/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/redelegate/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/sending-deploys/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/transfers/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/transfers/direct-token-transfer/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/transfers/multisig-deploy-transfer/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/transfers/verify-transfer/weekly0.5https://casper-network.github.io/1.5.X/developers/cli/undelegate/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/dapp/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/monitor-and-consume-events/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/nctl-test/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/prerequisites/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/sdk/client-library-usage/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/sdk/csharp-sdk/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/sdk/go-sdk/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/sdk/python-sdk/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/sdk/script-sdk/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/setup-nctl/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/signing-a-deploy/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/speculative-exec/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/technology-stack/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/template-frontend/weekly0.5https://casper-network.github.io/1.5.X/developers/dapps/uref-security/weekly0.5https://casper-network.github.io/1.5.X/developers/essential-crates/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/errors/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/guidance/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/json-rpc-informational/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/json-rpc-pos/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/json-rpc-transactional/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/minimal-compliance/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/types_chain/weekly0.5https://casper-network.github.io/1.5.X/developers/json-rpc/types_cl/weekly0.5https://casper-network.github.io/1.5.X/developers/prerequisites/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/assembly-script/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/best-practices/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/calling-contracts/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/contract-hash-vs-package-hash/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/contract-vs-session/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/getting-started/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/simple-contract/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/testing-contracts/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/testing-session-code/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/upgrading-contracts/weekly0.5https://casper-network.github.io/1.5.X/developers/writing-onchain-code/writing-session-code/weekly0.5https://casper-network.github.io/1.5.X/disclaimer/weekly0.5https://casper-network.github.io/1.5.X/economics/weekly0.5https://casper-network.github.io/1.5.X/glossary/weekly0.5https://casper-network.github.io/1.5.X/operators/weekly0.5https://casper-network.github.io/1.5.X/operators/becoming-a-validator/weekly0.5https://casper-network.github.io/1.5.X/operators/becoming-a-validator/bonding/weekly0.5https://casper-network.github.io/1.5.X/operators/becoming-a-validator/inactive-vs-faulty/weekly0.5https://casper-network.github.io/1.5.X/operators/becoming-a-validator/recovering/weekly0.5https://casper-network.github.io/1.5.X/operators/becoming-a-validator/unbonding/weekly0.5https://casper-network.github.io/1.5.X/operators/maintenance/weekly0.5https://casper-network.github.io/1.5.X/operators/maintenance/archiving-and-restoring/weekly0.5https://casper-network.github.io/1.5.X/operators/maintenance/moving-node/weekly0.5https://casper-network.github.io/1.5.X/operators/setup-network/weekly0.5https://casper-network.github.io/1.5.X/operators/setup-network/chain-spec/weekly0.5https://casper-network.github.io/1.5.X/operators/setup-network/create-private/weekly0.5https://casper-network.github.io/1.5.X/operators/setup-network/genesis/weekly0.5https://casper-network.github.io/1.5.X/operators/setup-network/staging-files-for-new-network/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/basic-node-configuration/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/fast-sync/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/hardware/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/install-node/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/joining/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/node-endpoints/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/non-root-user/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/open-files/weekly0.5https://casper-network.github.io/1.5.X/operators/setup/upgrade/weekly0.5https://casper-network.github.io/1.5.X/resources/weekly0.5https://casper-network.github.io/1.5.X/resources/advanced/list-auth-keys-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/advanced/multi-sig/weekly0.5https://casper-network.github.io/1.5.X/resources/advanced/multi-sig/multi-sig-workflow/weekly0.5https://casper-network.github.io/1.5.X/resources/advanced/multi-sig/other-scenarios/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter-testnet/commands/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter-testnet/overview/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter-testnet/walkthrough/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter/commands/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter/overview/weekly0.5https://casper-network.github.io/1.5.X/resources/beginner/counter/walkthrough/weekly0.5https://casper-network.github.io/1.5.X/resources/build-on-casper/casper-open-source-software/weekly0.5https://casper-network.github.io/1.5.X/resources/build-on-casper/introduction/weekly0.5https://casper-network.github.io/1.5.X/resources/condor-for-exchanges/weekly0.5https://casper-network.github.io/1.5.X/resources/moving-to-casper/weekly0.5https://casper-network.github.io/1.5.X/resources/quick-start/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep18/full-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep18/query/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep18/quickstart-guide/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep18/tests/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep18/transfer/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/introduction/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/js-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/modalities/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/reverse-lookup/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/using-casper-client/full-installation-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/using-casper-client/interacting-with-NFTs/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/using-casper-client/querying-NFTs/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/using-casper-client/quickstart-guide/weekly0.5https://casper-network.github.io/1.5.X/resources/tokens/cep78/using-casper-client/testing-NFTs/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/cross-contract/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/list-cspr/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/return-values-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/storage-workflow/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/transfer-token-to-contract/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/advanced/two-party-multi-sig/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/aws-node/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/cep18/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/getting-started-tutorial/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/querying-network/weekly0.5https://casper-network.github.io/1.5.X/resources/tutorials/beginner/upgrade-contract/weekly0.5https://casper-network.github.io/1.5.X/runtime/weekly0.5https://casper-network.github.io/1.5.X/sdk/weekly0.5https://casper-network.github.io/1.5.X/staking/weekly0.5https://casper-network.github.io/1.5.X/users/weekly0.5https://casper-network.github.io/1.5.X/users/block-explorer/weekly0.5https://casper-network.github.io/1.5.X/users/csprlive/weekly0.5https://casper-network.github.io/1.5.X/users/delegate-ui/weekly0.5https://casper-network.github.io/1.5.X/users/funding-from-exchanges/weekly0.5https://casper-network.github.io/1.5.X/users/ledger/weekly0.5https://casper-network.github.io/1.5.X/users/ledger/ledger-cspr-live/weekly0.5https://casper-network.github.io/1.5.X/users/ledger/ledger-live/weekly0.5https://casper-network.github.io/1.5.X/users/staking-ledger/weekly0.5https://casper-network.github.io/1.5.X/users/testnet-faucet/weekly0.5https://casper-network.github.io/1.5.X/users/token-transfer/weekly0.5https://casper-network.github.io/1.5.X/users/undelegate-ui/weekly0.5https://casper-network.github.io/1.5.X/workflow/ledger-setup/weekly0.5https://casper-network.github.io/1.5.X/writing-contracts/weekly0.5https://casper-network.github.io/2.0.0/weekly0.5https://casper-network.github.io/2.0.0/concepts/weekly0.5https://casper-network.github.io/2.0.0/concepts/about/weekly0.5https://casper-network.github.io/2.0.0/concepts/accounts-and-keys/weekly0.5https://casper-network.github.io/2.0.0/concepts/addressable-entity/weekly0.5https://casper-network.github.io/2.0.0/concepts/callstack/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/casper-design/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/consensus/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/highway/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/networking-protocol/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/p2p/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/reading-and-writing-to-the-blockchain/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/rewards/weekly0.5https://casper-network.github.io/2.0.0/concepts/design/zug/weekly0.5https://casper-network.github.io/2.0.0/concepts/dictionaries/weekly0.5https://casper-network.github.io/2.0.0/concepts/economics/consensus/weekly0.5https://casper-network.github.io/2.0.0/concepts/economics/dynamic-gas-pricing/weekly0.5https://casper-network.github.io/2.0.0/concepts/economics/fee-elimination/weekly0.5https://casper-network.github.io/2.0.0/concepts/economics/gas-concepts/weekly0.5https://casper-network.github.io/2.0.0/concepts/economics/staking/weekly0.5https://casper-network.github.io/2.0.0/concepts/global-state/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/A/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/B/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/C/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/D/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/E/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/F/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/G/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/H/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/I/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/J/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/K/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/L/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/M/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/N/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/O/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/P/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/Q/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/R/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/S/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/T/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/U/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/V/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/W/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/X/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/Y/weekly0.5https://casper-network.github.io/2.0.0/concepts/glossary/Z/weekly0.5https://casper-network.github.io/2.0.0/concepts/intro-to-dapps/weekly0.5https://casper-network.github.io/2.0.0/concepts/key-types/weekly0.5https://casper-network.github.io/2.0.0/concepts/list-auth-keys/weekly0.5https://casper-network.github.io/2.0.0/concepts/serialization/weekly0.5https://casper-network.github.io/2.0.0/concepts/serialization/primitives/weekly0.5https://casper-network.github.io/2.0.0/concepts/serialization/structures/weekly0.5https://casper-network.github.io/2.0.0/concepts/serialization/types/weekly0.5https://casper-network.github.io/2.0.0/concepts/smart-contracts/weekly0.5https://casper-network.github.io/2.0.0/counter-testnet/weekly0.5https://casper-network.github.io/2.0.0/counter/weekly0.5https://casper-network.github.io/2.0.0/design/weekly0.5https://casper-network.github.io/2.0.0/developers/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/calling-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/delegate/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/execution-error-codes/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/installing-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/opcode-costs/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/querying-global-state/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/redelegate/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/sending-transactions/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/transfers/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/transfers/direct-token-transfer/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/transfers/multisig-deploy-transfer/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/transfers/verify-transfer/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/undelegate/weekly0.5https://casper-network.github.io/2.0.0/developers/cli/verifying-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/dapp/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/monitor-and-consume-events/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/nctl-test/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/prerequisites/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/sdk/client-library-usage/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/sdk/csharp-sdk/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/sdk/go-sdk/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/sdk/python-sdk/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/sdk/script-sdk/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/setup-nctl/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/signing-a-transaction/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/speculative-exec/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/technology-stack/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/template-frontend/weekly0.5https://casper-network.github.io/2.0.0/developers/dapps/uref-security/weekly0.5https://casper-network.github.io/2.0.0/developers/essential-crates/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/errors/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/guidance/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/json-rpc-informational/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/json-rpc-pos/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/json-rpc-transactional/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/minimal-compliance/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/types_chain/weekly0.5https://casper-network.github.io/2.0.0/developers/json-rpc/types_cl/weekly0.5https://casper-network.github.io/2.0.0/developers/prerequisites/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/assembly-script/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/best-practices/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/calling-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/contract-hash-vs-package-hash/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/contract-vs-session/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/emitting-contract-events/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/factory-pattern/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/getting-started/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/simple-contract/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/testing-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/testing-session-code/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/upgrading-contracts/weekly0.5https://casper-network.github.io/2.0.0/developers/writing-onchain-code/writing-session-code/weekly0.5https://casper-network.github.io/2.0.0/disclaimer/weekly0.5https://casper-network.github.io/2.0.0/economics/weekly0.5https://casper-network.github.io/2.0.0/glossary/weekly0.5https://casper-network.github.io/2.0.0/operators/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/bonding/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/change-bid-public-key/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/inactive-vs-faulty/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/recovering/weekly0.5https://casper-network.github.io/2.0.0/operators/becoming-a-validator/unbonding/weekly0.5https://casper-network.github.io/2.0.0/operators/maintenance/weekly0.5https://casper-network.github.io/2.0.0/operators/maintenance/archiving-and-restoring/weekly0.5https://casper-network.github.io/2.0.0/operators/maintenance/moving-node/weekly0.5https://casper-network.github.io/2.0.0/operators/setup-network/weekly0.5https://casper-network.github.io/2.0.0/operators/setup-network/chain-spec/weekly0.5https://casper-network.github.io/2.0.0/operators/setup-network/create-private/weekly0.5https://casper-network.github.io/2.0.0/operators/setup-network/genesis/weekly0.5https://casper-network.github.io/2.0.0/operators/setup-network/staging-files-for-new-network/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/basic-node-configuration/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/casper-sidecar/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/fast-sync/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/hardware/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/install-node/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/joining/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/node-endpoints/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/node-events/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/non-root-user/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/open-files/weekly0.5https://casper-network.github.io/2.0.0/operators/setup/upgrade/weekly0.5https://casper-network.github.io/2.0.0/resources/weekly0.5https://casper-network.github.io/2.0.0/resources/advanced/list-auth-keys-tutorial/weekly0.5https://casper-network.github.io/2.0.0/resources/advanced/multi-sig/weekly0.5https://casper-network.github.io/2.0.0/resources/advanced/multi-sig/multi-sig-workflow/weekly0.5https://casper-network.github.io/2.0.0/resources/advanced/multi-sig/other-scenarios/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter-testnet/commands/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter-testnet/overview/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter-testnet/walkthrough/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter/commands/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter/overview/weekly0.5https://casper-network.github.io/2.0.0/resources/beginner/counter/walkthrough/weekly0.5https://casper-network.github.io/2.0.0/resources/build-on-casper/casper-open-source-software/weekly0.5https://casper-network.github.io/2.0.0/resources/build-on-casper/introduction/weekly0.5https://casper-network.github.io/2.0.0/resources/changelog/weekly0.5https://casper-network.github.io/2.0.0/resources/moving-to-casper/weekly0.5https://casper-network.github.io/2.0.0/resources/quick-start/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep18/full-tutorial/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep18/query/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep18/quickstart-guide/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep18/tests/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep18/transfer/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep78/introduction/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep78/js-tutorial/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep78/modalities/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/cep78/reverse-lookup/weekly0.5https://casper-network.github.io/2.0.0/resources/tokens/using-casper-client/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/cross-contract/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/list-cspr/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/return-values-tutorial/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/storage-workflow/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/transfer-token-to-contract/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/advanced/two-party-multi-sig/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/aws-node/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/cep18/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/getting-started-tutorial/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/querying-network/weekly0.5https://casper-network.github.io/2.0.0/resources/tutorials/beginner/upgrade-contract/weekly0.5https://casper-network.github.io/2.0.0/runtime/weekly0.5https://casper-network.github.io/2.0.0/sdk/weekly0.5https://casper-network.github.io/2.0.0/transactions-and-transaction-lifecycle/weekly0.5https://casper-network.github.io/2.0.0/transactions/weekly0.5https://casper-network.github.io/2.0.0/users/weekly0.5https://casper-network.github.io/2.0.0/users/block-explorer/weekly0.5https://casper-network.github.io/2.0.0/users/csprlive/weekly0.5https://casper-network.github.io/2.0.0/users/delegate-ui/weekly0.5https://casper-network.github.io/2.0.0/users/delegating/weekly0.5https://casper-network.github.io/2.0.0/users/funding-from-exchanges/weekly0.5https://casper-network.github.io/2.0.0/users/ledger/weekly0.5https://casper-network.github.io/2.0.0/users/ledger/ledger-cspr-live/weekly0.5https://casper-network.github.io/2.0.0/users/ledger/ledger-live/weekly0.5https://casper-network.github.io/2.0.0/users/staking-ledger/weekly0.5https://casper-network.github.io/2.0.0/users/testnet-faucet/weekly0.5https://casper-network.github.io/2.0.0/users/token-transfer/weekly0.5https://casper-network.github.io/2.0.0/users/undelegate-ui/weekly0.5https://casper-network.github.io/2.0.0/workflow/ledger-setup/weekly0.5https://casper-network.github.io/2.0.0/writing-contracts/weekly0.5https://casper-network.github.io/concepts/weekly0.5https://casper-network.github.io/concepts/about/weekly0.5https://casper-network.github.io/concepts/accounts-and-keys/weekly0.5https://casper-network.github.io/concepts/addressable-entity/weekly0.5https://casper-network.github.io/concepts/callstack/weekly0.5https://casper-network.github.io/concepts/design/casper-design/weekly0.5https://casper-network.github.io/concepts/design/consensus/weekly0.5https://casper-network.github.io/concepts/design/highway/weekly0.5https://casper-network.github.io/concepts/design/networking-protocol/weekly0.5https://casper-network.github.io/concepts/design/p2p/weekly0.5https://casper-network.github.io/concepts/design/reading-and-writing-to-the-blockchain/weekly0.5https://casper-network.github.io/concepts/design/rewards/weekly0.5https://casper-network.github.io/concepts/design/zug/weekly0.5https://casper-network.github.io/concepts/dictionaries/weekly0.5https://casper-network.github.io/concepts/economics/consensus/weekly0.5https://casper-network.github.io/concepts/economics/dynamic-gas-pricing/weekly0.5https://casper-network.github.io/concepts/economics/fee-elimination/weekly0.5https://casper-network.github.io/concepts/economics/gas-concepts/weekly0.5https://casper-network.github.io/concepts/economics/staking/weekly0.5https://casper-network.github.io/concepts/global-state/weekly0.5https://casper-network.github.io/concepts/glossary/A/weekly0.5https://casper-network.github.io/concepts/glossary/B/weekly0.5https://casper-network.github.io/concepts/glossary/C/weekly0.5https://casper-network.github.io/concepts/glossary/D/weekly0.5https://casper-network.github.io/concepts/glossary/E/weekly0.5https://casper-network.github.io/concepts/glossary/F/weekly0.5https://casper-network.github.io/concepts/glossary/G/weekly0.5https://casper-network.github.io/concepts/glossary/H/weekly0.5https://casper-network.github.io/concepts/glossary/I/weekly0.5https://casper-network.github.io/concepts/glossary/J/weekly0.5https://casper-network.github.io/concepts/glossary/K/weekly0.5https://casper-network.github.io/concepts/glossary/L/weekly0.5https://casper-network.github.io/concepts/glossary/M/weekly0.5https://casper-network.github.io/concepts/glossary/N/weekly0.5https://casper-network.github.io/concepts/glossary/O/weekly0.5https://casper-network.github.io/concepts/glossary/P/weekly0.5https://casper-network.github.io/concepts/glossary/Q/weekly0.5https://casper-network.github.io/concepts/glossary/R/weekly0.5https://casper-network.github.io/concepts/glossary/S/weekly0.5https://casper-network.github.io/concepts/glossary/T/weekly0.5https://casper-network.github.io/concepts/glossary/U/weekly0.5https://casper-network.github.io/concepts/glossary/V/weekly0.5https://casper-network.github.io/concepts/glossary/W/weekly0.5https://casper-network.github.io/concepts/glossary/X/weekly0.5https://casper-network.github.io/concepts/glossary/Y/weekly0.5https://casper-network.github.io/concepts/glossary/Z/weekly0.5https://casper-network.github.io/concepts/intro-to-dapps/weekly0.5https://casper-network.github.io/concepts/key-types/weekly0.5https://casper-network.github.io/concepts/list-auth-keys/weekly0.5https://casper-network.github.io/concepts/serialization/weekly0.5https://casper-network.github.io/concepts/serialization/primitives/weekly0.5https://casper-network.github.io/concepts/serialization/structures/weekly0.5https://casper-network.github.io/concepts/serialization/types/weekly0.5https://casper-network.github.io/concepts/smart-contracts/weekly0.5https://casper-network.github.io/counter-testnet/weekly0.5https://casper-network.github.io/counter/weekly0.5https://casper-network.github.io/design/weekly0.5https://casper-network.github.io/developers/weekly0.5https://casper-network.github.io/developers/cli/weekly0.5https://casper-network.github.io/developers/cli/calling-contracts/weekly0.5https://casper-network.github.io/developers/cli/delegate/weekly0.5https://casper-network.github.io/developers/cli/execution-error-codes/weekly0.5https://casper-network.github.io/developers/cli/installing-contracts/weekly0.5https://casper-network.github.io/developers/cli/opcode-costs/weekly0.5https://casper-network.github.io/developers/cli/querying-global-state/weekly0.5https://casper-network.github.io/developers/cli/redelegate/weekly0.5https://casper-network.github.io/developers/cli/sending-transactions/weekly0.5https://casper-network.github.io/developers/cli/transfers/weekly0.5https://casper-network.github.io/developers/cli/transfers/direct-token-transfer/weekly0.5https://casper-network.github.io/developers/cli/transfers/multisig-deploy-transfer/weekly0.5https://casper-network.github.io/developers/cli/transfers/verify-transfer/weekly0.5https://casper-network.github.io/developers/cli/undelegate/weekly0.5https://casper-network.github.io/developers/cli/verifying-contracts/weekly0.5https://casper-network.github.io/developers/dapps/weekly0.5https://casper-network.github.io/developers/dapps/dapp/weekly0.5https://casper-network.github.io/developers/dapps/monitor-and-consume-events/weekly0.5https://casper-network.github.io/developers/dapps/nctl-test/weekly0.5https://casper-network.github.io/developers/dapps/prerequisites/weekly0.5https://casper-network.github.io/developers/dapps/sdk/client-library-usage/weekly0.5https://casper-network.github.io/developers/dapps/sdk/csharp-sdk/weekly0.5https://casper-network.github.io/developers/dapps/sdk/go-sdk/weekly0.5https://casper-network.github.io/developers/dapps/sdk/python-sdk/weekly0.5https://casper-network.github.io/developers/dapps/sdk/script-sdk/weekly0.5https://casper-network.github.io/developers/dapps/setup-nctl/weekly0.5https://casper-network.github.io/developers/dapps/signing-a-transaction/weekly0.5https://casper-network.github.io/developers/dapps/speculative-exec/weekly0.5https://casper-network.github.io/developers/dapps/technology-stack/weekly0.5https://casper-network.github.io/developers/dapps/template-frontend/weekly0.5https://casper-network.github.io/developers/dapps/uref-security/weekly0.5https://casper-network.github.io/developers/essential-crates/weekly0.5https://casper-network.github.io/developers/json-rpc/weekly0.5https://casper-network.github.io/developers/json-rpc/errors/weekly0.5https://casper-network.github.io/developers/json-rpc/guidance/weekly0.5https://casper-network.github.io/developers/json-rpc/json-rpc-informational/weekly0.5https://casper-network.github.io/developers/json-rpc/json-rpc-pos/weekly0.5https://casper-network.github.io/developers/json-rpc/json-rpc-transactional/weekly0.5https://casper-network.github.io/developers/json-rpc/minimal-compliance/weekly0.5https://casper-network.github.io/developers/json-rpc/types_chain/weekly0.5https://casper-network.github.io/developers/json-rpc/types_cl/weekly0.5https://casper-network.github.io/developers/prerequisites/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/assembly-script/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/best-practices/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/calling-contracts/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/contract-hash-vs-package-hash/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/contract-vs-session/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/emitting-contract-events/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/factory-pattern/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/getting-started/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/simple-contract/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/testing-contracts/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/testing-session-code/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/upgrading-contracts/weekly0.5https://casper-network.github.io/developers/writing-onchain-code/writing-session-code/weekly0.5https://casper-network.github.io/disclaimer/weekly0.5https://casper-network.github.io/economics/weekly0.5https://casper-network.github.io/glossary/weekly0.5https://casper-network.github.io/operators/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/bonding/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/change-bid-public-key/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/inactive-vs-faulty/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/recovering/weekly0.5https://casper-network.github.io/operators/becoming-a-validator/unbonding/weekly0.5https://casper-network.github.io/operators/maintenance/weekly0.5https://casper-network.github.io/operators/maintenance/archiving-and-restoring/weekly0.5https://casper-network.github.io/operators/maintenance/moving-node/weekly0.5https://casper-network.github.io/operators/setup-network/weekly0.5https://casper-network.github.io/operators/setup-network/chain-spec/weekly0.5https://casper-network.github.io/operators/setup-network/create-private/weekly0.5https://casper-network.github.io/operators/setup-network/genesis/weekly0.5https://casper-network.github.io/operators/setup-network/staging-files-for-new-network/weekly0.5https://casper-network.github.io/operators/setup/weekly0.5https://casper-network.github.io/operators/setup/basic-node-configuration/weekly0.5https://casper-network.github.io/operators/setup/casper-sidecar/weekly0.5https://casper-network.github.io/operators/setup/fast-sync/weekly0.5https://casper-network.github.io/operators/setup/hardware/weekly0.5https://casper-network.github.io/operators/setup/install-node/weekly0.5https://casper-network.github.io/operators/setup/joining/weekly0.5https://casper-network.github.io/operators/setup/node-endpoints/weekly0.5https://casper-network.github.io/operators/setup/node-events/weekly0.5https://casper-network.github.io/operators/setup/non-root-user/weekly0.5https://casper-network.github.io/operators/setup/open-files/weekly0.5https://casper-network.github.io/operators/setup/upgrade/weekly0.5https://casper-network.github.io/resources/weekly0.5https://casper-network.github.io/resources/advanced/list-auth-keys-tutorial/weekly0.5https://casper-network.github.io/resources/advanced/multi-sig/weekly0.5https://casper-network.github.io/resources/advanced/multi-sig/multi-sig-workflow/weekly0.5https://casper-network.github.io/resources/advanced/multi-sig/other-scenarios/weekly0.5https://casper-network.github.io/resources/beginner/counter-testnet/commands/weekly0.5https://casper-network.github.io/resources/beginner/counter-testnet/overview/weekly0.5https://casper-network.github.io/resources/beginner/counter-testnet/walkthrough/weekly0.5https://casper-network.github.io/resources/beginner/counter/commands/weekly0.5https://casper-network.github.io/resources/beginner/counter/overview/weekly0.5https://casper-network.github.io/resources/beginner/counter/walkthrough/weekly0.5https://casper-network.github.io/resources/build-on-casper/casper-open-source-software/weekly0.5https://casper-network.github.io/resources/build-on-casper/introduction/weekly0.5https://casper-network.github.io/resources/changelog/weekly0.5https://casper-network.github.io/resources/moving-to-casper/weekly0.5https://casper-network.github.io/resources/quick-start/weekly0.5https://casper-network.github.io/resources/tokens/weekly0.5https://casper-network.github.io/resources/tokens/cep18/full-tutorial/weekly0.5https://casper-network.github.io/resources/tokens/cep18/query/weekly0.5https://casper-network.github.io/resources/tokens/cep18/quickstart-guide/weekly0.5https://casper-network.github.io/resources/tokens/cep18/tests/weekly0.5https://casper-network.github.io/resources/tokens/cep18/transfer/weekly0.5https://casper-network.github.io/resources/tokens/cep78/introduction/weekly0.5https://casper-network.github.io/resources/tokens/cep78/js-tutorial/weekly0.5https://casper-network.github.io/resources/tokens/cep78/modalities/weekly0.5https://casper-network.github.io/resources/tokens/cep78/reverse-lookup/weekly0.5https://casper-network.github.io/resources/tokens/using-casper-client/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/cross-contract/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/list-cspr/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/return-values-tutorial/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/storage-workflow/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/transfer-token-to-contract/weekly0.5https://casper-network.github.io/resources/tutorials/advanced/two-party-multi-sig/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/aws-node/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/cep18/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/getting-started-tutorial/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/querying-network/weekly0.5https://casper-network.github.io/resources/tutorials/beginner/upgrade-contract/weekly0.5https://casper-network.github.io/runtime/weekly0.5https://casper-network.github.io/sdk/weekly0.5https://casper-network.github.io/transactions-and-transaction-lifecycle/weekly0.5https://casper-network.github.io/transactions/weekly0.5https://casper-network.github.io/users/weekly0.5https://casper-network.github.io/users/block-explorer/weekly0.5https://casper-network.github.io/users/csprlive/weekly0.5https://casper-network.github.io/users/delegate-ui/weekly0.5https://casper-network.github.io/users/delegating/weekly0.5https://casper-network.github.io/users/funding-from-exchanges/weekly0.5https://casper-network.github.io/users/ledger/weekly0.5https://casper-network.github.io/users/ledger/ledger-cspr-live/weekly0.5https://casper-network.github.io/users/ledger/ledger-live/weekly0.5https://casper-network.github.io/users/staking-ledger/weekly0.5https://casper-network.github.io/users/testnet-faucet/weekly0.5https://casper-network.github.io/users/token-transfer/weekly0.5https://casper-network.github.io/users/undelegate-ui/weekly0.5https://casper-network.github.io/workflow/ledger-setup/weekly0.5https://casper-network.github.io/writing-contracts/weekly0.5https://casper-network.github.io/weekly0.5 \ No newline at end of file diff --git a/staking/index.html b/staking/index.html deleted file mode 100644 index f3e21303c..000000000 --- a/staking/index.html +++ /dev/null @@ -1,52 +0,0 @@ - - - - - -Staking vs. Delegating | Casper Docs - Redux - - - - - - - - - -
    Version: 1.5.X

    Staking vs. Delegating

    -

    A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as staking or delegation. They can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.

    -

    Here are a few common topics related to staking, but we also encourage you to do your own research.

    -

    Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network.

    -

    Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate.

    -

    Casper does not treat validator stake differently than delegator stake for security reasons.

    -

    Slashing

    -

    Presently Casper does not slash if a validator equivocates or misbehaves. If a node equivocates, other validators will ignore its messages, and the node will become inactive. The node will terminate once it detects that it has equivocated.

    -

    Delegation Rate

    -

    Validators define a delegation rate that they take in exchange for providing staking services. This rate is a percentage of the rewards that the validator retains for their services.

    -

    Delegation Fees

    -

    It is important to know that the cost of the delegation process is approximately 3 CSPR. Ensure you have extra CSPR in your account's main purse apart from the amount you are delegating; otherwise, the transaction will fail. For example, if you want to delegate 1000 CSPR, you need to have at least 1003 CSPR in your account's main purse.

    -

    Rewards

    -

    Validators receive rewards proportional to their stake for securing the network and participating in consensus (by voting and finalizing blocks). Delegators receive a portion of the validator's rewards, proportional to what they delegated, minus the validator's delegation rate. The rewards earned are reduced if a validator is offline or cannot vote on many blocks.

    -

    There is no precise reward per block. Rewards are split proportionally among stakes within an era and are distributed at the end of each era.

    -

    Selecting a Node for Delegating

    -

    As a prospective delegator, it is essential to select a validating node that you can trust. Block explorers such as cspr.live provide validator performance statistics, including a performance score, total stake, number of delegators, and fees. Please do your due diligence before staking tokens with a validator.

    -

    -

    Monitoring Rewards

    -

    It's recommended that you check in on how your stake is performing from time to time. If the validator you staked with decides to unbond, your stake will also be unbonded and you will not earn rewards. Ensure that the validator you selected performs as per your expectations.

    -

    Validators have to win a staking auction by competing for a validator slot with prospective and current validators. This process is permissionless, meaning validators can join and leave the auction without restrictions, except for the unbonding wait period, which lasts 14 hours.

    -

    Unbonding Period

    -

    For security purposes, whenever tokens are un-delegated, the protocol will continue to keep the token locked for 14 hours.

    -

    Tutorials

    -

    Navigate to these pages for step-by-step tutorials on creating an account and delegating and undelegating tokens.

    -
    - - \ No newline at end of file diff --git a/next/transactions-and-transaction-lifecycle/index.html b/transactions-and-transaction-lifecycle/index.html similarity index 56% rename from next/transactions-and-transaction-lifecycle/index.html rename to transactions-and-transaction-lifecycle/index.html index 60038ddd5..9ca4d2baa 100644 --- a/next/transactions-and-transaction-lifecycle/index.html +++ b/transactions-and-transaction-lifecycle/index.html @@ -3,34 +3,34 @@ -Transaction Lifecycle | Casper Docs - Redux +Transaction Lifecycle | Casper Docs - Redux - - + +
    Version: Next

    Transactions and the Transaction Lifecycle

    + submit an issue on Github
    Version: Next

    Transactions and the Transaction Lifecycle

    Transactions

    -

    A transaction is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions’s structure is as follows:

    +

    A transaction is a data structure containing Wasm and the requester's signature(s). Additionally, the transaction header contains additional metadata about the transaction itself. A transactions’s structure is as follows:

    Transaction Data Structure

    • Body: Containing payment code and session code (more details on these below)
    • Header: containing
        -
      • The Public Key of the account in whose context the transaction will run
      • +
      • The Public Key of the account in whose context the transaction will run
      • The timestamp of the transaction’s creation
      • A time-to-live, after which the transaction expires and cannot be included in a block
      • the blake2b256 hash of the body
    • Transaction hash: the blake2b hash of the Header
    • -
    • Approvals: the set of signatures which have signed the transaction hash; these are used in the account permissions model
    • +
    • Approvals: the set of signatures which have signed the transaction hash; these are used in the account permissions model

    The Transaction Lifecycle

    A transaction goes through the following phases on Casper:

    @@ -56,7 +56,7 @@

    Transac

    A transaction executes in distinct phases to accommodate flexibly paying for computation. The phases of a transaction are payment, session, and finalization. Payment code executes during the payment phase. If it is successful, the session code executes during the session phase. And, independently of session code execution, the finalization phase does some bookkeeping around the payment. Once the transaction is executed, a TransactionProcessed event is emitted by the event stream server.

    In the event of execution failure, the sender will be charged the minimum penalty payment - 2.5 CSPR on the Casper Mainnet. This prevents malicious spamming of faulty transactions.

    Payment code

    -

    Payment code determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's main purse. In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to MAX_PAYMENT_COST may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than MAX_PAYMENT_COST motes (a constant of the system.) +

    Payment code determines the payment amount for the computation requested and how much the sender is willing to pay. Payment code may include arbitrary logic, providing flexibility in paying for a transaction. For example, the simplest payment code could use the account entity's main purse. In contrast, an enterprise application may require a multi-signature scheme that accesses a corporate purse. To ensure the payment code will pay for its own computation, only entities with a balance in their main purse greater than or equal to MAX_PAYMENT_COST may execute transactions. Based on the current conversion rate between gas and motes, we restrict the gas limit of the payment code execution so that the process spends no more than MAX_PAYMENT_COST motes (a constant of the system.) If the payment is absent or not enough, then payment execution is not successful. In this case, the effects of the payment code on global state are reverted, and the system covers the cost of the computation with motes taken from the offending entity's main purse.

    Session code

    Session code provides the main logic for the transaction. It only executes if the payment code is successful. The gas limit for this computation is determined based on the amount of payment given (after subtracting the cost of the payment code itself).

    @@ -64,9 +64,9 @@

    Transac

    The user-defined logic of a transaction can be specified in a number of ways:

    • a Wasm module in binary format representing valid session code, including logic to be executed in the context of an account entity or to store Wasm in the form of a contract to be executed later. (Note that the named keys from the context of the entity the transaction is running in.)
    • -
    • a 32-byte identifier representing the hash where a contract is already stored in the global state
    • +
    • a 32-byte identifier representing the hash where a contract is already stored in the global state
    • a name corresponding to a named key, where a contract is stored under the key
    -

    Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module).

    +

    Payment and session code can be independently specified, so different methods of specifying them may be used (e.g. payment could be specified by a hash key, while the session is explicitly provided as a Wasm module).

    \ No newline at end of file diff --git a/next/transactions/index.html b/transactions/index.html similarity index 80% rename from next/transactions/index.html rename to transactions/index.html index 56d9edcca..cc7e8d091 100644 --- a/next/transactions/index.html +++ b/transactions/index.html @@ -3,20 +3,20 @@ -Transactions | Casper Docs - Redux +Transactions | Casper Docs - Redux - - + +
    Version: Next

    Transactions

    -

    Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.

    + submit an issue on Github
    Version: Next

    Transactions

    +

    Transactions are a new structure that allows users to enact changes in global state on a Casper network. Introduced with the Condor release, Transactions supersede legacy Deploys, allowing for a variety of Wasm-less interactions with the blockchain. These new interactions are more efficient than Deploys and provide a level of convenience that was not previously available.

    The existing Deploy model is deprecated as of Condor, and support will be removed entirely in a future major release. However, Condor will continue to accept valid Deploys and will attempt to execute them. Most existing deploys that function today will continue to do so. However, deploys that depend on a data type or FFI function that has been altered or removed will fail to execute.

    Transaction Types

    The following is a list of Transaction types included within the CLI Casper client put-transaction or put-txn command.

    @@ -51,37 +51,37 @@

    Redelegate

    casper-client put-txn redelegate
    /// The delegator's public key.
    --delegator <STRING>
    /// The old validator's public key.
    --validator <STRING>
    /// The new validator's public key.
    --new-validator <STRING>
    /// The amount in motes to redelegate from the old validator to the new validator.
    --transaction-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Invocable Entity

    -

    invocable-entity allows a user to invoke an entry point on the given AddressableEntity directly using an Entity Address.

    +

    invocable-entity allows a user to invoke an entry point on the given AddressableEntity directly using an Entity Address.

    Casper Client Command

    casper-client put-txn invocable-entity
    /// The [`entity-hash`](../developers/json-rpc/types_chain.md#addressableentityhash) of the entity to invoke.
    --entity-address <FORMATTED STRING or PATH>
    /// The entry point on the invocable entity.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Invocable Entity Alias

    -

    invocable-entity-alias allows a user to invoke an entry point on the given AddressableEntity directly using an alias stored in their named keys.

    +

    invocable-entity-alias allows a user to invoke an entry point on the given AddressableEntity directly using an alias stored in their named keys.

    Casper Client Command

    casper-client put-txn invocable-entity-alias
    /// The entity alias stored in the calling entity's named keys.
    --entity-alias <STRING>
    /// The entry point on the invocable entity.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Package

    -

    package allows a user to invoke an entry point on the given contract package using the associated package-address.

    +

    package allows a user to invoke an entry point on the given contract package using the associated package-address.

    Casper Client Command

    casper-client put-txn package
    /// The address of the contract package.
    --package-address <FORMATTED STRING or PATH>
    /// The entry point to invoke on the package.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Package Name

    -

    package-name allows a user to invoke an entry point on the given contract package using an alias stored in their named keys.

    +

    package-name allows a user to invoke an entry point on the given contract package using an alias stored in their named keys.

    Casper Client Command

    casper-client put-txn package-name
    /// The package alias stored in the calling entity's named keys.
    --package-alias <STRING>
    /// The entry point to invoke on the package.
    --session-entry-point <NAME>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Session

    -

    session allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial Sending Transactions covers this in depth.

    +

    session allows the user to send Wasm in a manner similar to legacy Deploys, but through the new Transaction structure. The tutorial Sending Transactions covers this in depth.

    Casper Client Command

    casper-client put-txn session
    /// The local path pointing to Wasm that will be sent to global state.
    --transaction-path <PATH>
    /// An entry point on a previously installed contract, if applicable.
    --session-entry-point <NAME>
    /// The category of the Transaction, in decreasing size order.
    --category <install-upgrade|large|medium|small>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    Transfer

    -

    transfer allows a user to transfer the designated number of motes to a target address.

    +

    transfer allows a user to transfer the designated number of motes to a target address.

    Casper Client Command

    casper-client put-txn transfer
    /// The recipient of the transfer.
    --target <FORMATTED STRING>
    /// The amount in motes to be transferred.
    --transfer-amount <INTEGER>
    /// The maximum gas price that the user is willing to pay for this transaction.
    --gas-price-tolerance <INTEGER>
    /// The path to the local secret key file, or the [`initiator address`](../developers/json-rpc/types_chain.md#initiatoraddr) sending the transaction.
    <--secret-key <PATH>|--initiator-address <HEX STRING>>

    diff --git a/users/block-explorer/index.html b/users/block-explorer/index.html index 43043c5e2..2de7adac8 100644 --- a/users/block-explorer/index.html +++ b/users/block-explorer/index.html @@ -1,21 +1,21 @@ - + -Block Explorers | Casper Docs - Redux +Block Explorers | Casper Docs - Redux - - + +
    Version: 1.5.X

    Block Explorers

    + submit an issue on Github
    Version: Next

    Block Explorers

    The Casper blockchain is available as the Mainnet and Testnet. The Mainnet is the Casper blockchain that utilizes Casper tokens (CSPR). The Testnet is an alternate Casper blockchain used to test applications without spending CSPR tokens on the Casper Mainnet.

    @@ -28,13 +28,13 @@

    What is a Block Explorer

    A block explorer is a search engine for the blockchain. It allows you to find information such as the transactions executed on the blockchain, the transaction statistics, the validators on the network, and similar blockchain activity. A block explorer gives you information on your account and all the transactions carried out using the account. You can use it to find a specific transaction or view the blockchain's transaction history.

    Using a Block Explorer

    -

    You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of deploys, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator.

    +

    You can use a block explorer to view the blockchain statistics, list of validators, list of blocks executed on the blockchain, list of transactions, and the nodes operating on the blockchain. You can also transfer CSPR tokens, delegate tokens to a validator to earn rewards or undelegate tokens from a validator.

    The following topics link you to detailed instructions on using the cspr.live block explorer to access and work with your CSPR tokens.

    -
    note

    To perform actions using the cspr.live block explorer, you must sign in to your Casper account using one of the wallets provided.

    +
    note

    To perform actions using the cspr.live block explorer, you must sign in to your Casper account using one of the wallets provided.

    \ No newline at end of file diff --git a/users/csprlive/index.html b/users/csprlive/index.html index 56a14636a..03ab204f1 100644 --- a/users/csprlive/index.html +++ b/users/csprlive/index.html @@ -1,21 +1,21 @@ - + -Using CSPR.live | Casper Docs - Redux +Using CSPR.live | Casper Docs - Redux - - + +
    Version: 1.5.X

    Using the CSPR.live block explorer

    + submit an issue on Github
    +
    TopicDescription
    Funding Testnet AccountsFund a Testnet account for testing
    Transferring TokensTransfer tokens using the CSPR.live block explorer
    Delegating TokensDelegate tokens to a validator
    Undelegating TokensUndelegate tokens from a validator
    \ No newline at end of file diff --git a/users/delegate-ui/index.html b/users/delegate-ui/index.html index 27e8192f8..5aa5e765d 100644 --- a/users/delegate-ui/index.html +++ b/users/delegate-ui/index.html @@ -1,31 +1,31 @@ - + -Delegate Tokens | Casper Docs - Redux +Delegate Tokens | Casper Docs - Redux - - + +
    Version: 1.5.X

    Delegating Tokens with a Block Explorer

    + submit an issue on Github
    Version: Next

    Delegating Tokens with a Block Explorer

    Introduction

    This tutorial covers how to delegate Casper tokens to a validator on the network.

    -

    Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called delegation or staking. We will use these terms interchangeably in this guide. See the Staking Key Concepts page for more details about the differences.

    +

    Casper and other Proof-of-Stake protocols allow token holders to earn rewards and participate in the protocol through a mechanism called delegation or staking. We will use these terms interchangeably in this guide. See the Staking Key Concepts page for more details about the differences.

    Prerequisites

    1. To stake tokens with a validator, you must create an account with CSPR tokens in its main purse. One option is to use the Casper Wallet by following the Getting Started user guide.
    2. You need to fund the account's main purse to delegate tokens.
    3. Connect to a block explorer to set up the delegation. This guide uses cspr.live and the Casper Wallet.
    4. Review your account before starting the process.
    5. -
    6. Review the current delegation fees and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail.
    7. +
    8. Review the current delegation cost and ensure you have extra CSPR in your account's main purse apart from the amount you are delegating. Otherwise, the delegation might fail.

    Reviewing your Account

    Once connected to the Casper blockchain, we recommend reviewing the active account you wish to use for delegating tokens, especially these fields:

    @@ -34,17 +34,17 @@

    Reviewing you
  • The Delegated Account Balance, representing the delegated tokens already staked with validators on the network
  • The Delegations tab, listing the validators to whom you have delegated tokens
  • -

    +

    Account and delegations details

    • The Staking Rewards tab, showing the rewards received in each era
    -

    +

    Account and rewards

    Accessing the Delegation Feature

    You can access the delegation functionality in two ways.

    Option 1: Click Wallet from the top navigation menu and then click Delegate. In the next screen, you will need to specify the validator's public key or search for a validator.

    -

    +

    Delegate from the Wallet

    Option 2: Click Validators from the top navigation menu. From the validators table, click on any validator to access their details. Once you find the validator to whom you want to delegate tokens, click the Delegate button. The next screen will have the validator's public key pre-populated.

    -

    +

    Delegate from a Validator

    Stepping through the Delegation Process

    The following instructions will take you through the delegation process, starting with the "Delegation details" screen.

    Step 1 - Delegation details

    @@ -53,31 +53,31 @@

    +

    Delegation details

    Step 2 - Confirm the delegation

    1. Review the delegation details.
    2. If everything is correct, click Confirm and delegate stake. If you wish to make changes, return to the previous screen.
    -

    +

    Confirm delegation details

    Step 3 - Sign the delegation

    1. Sign the delegation by clicking Sign with Casper Wallet.
    -

    +

    Sign delegation

    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign delegation" window before continuing.
    -

    +

    Signature Request window

    1. Click Sign in the Signature Request window to finalize the delegation.
    -

    +

    Completed delegation

    The delegation initiates as soon as the corresponding deploy is signed. You can review the details and status of the deploy by clicking the Deploy Details highlighted above.

    -

    Remember to Monitor your Stake. Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the Rewards tab on your account page on cspr.live.

    +

    Remember to Monitor your Stake. Staking rewards are delivered to your account's main purse after each era, which is currently set to 2 hours. Note that it may take up to 2 eras (4 hours) for the first reward to appear after delegation. The rewards are automatically added to your current stake on the corresponding validator. You may view them under the Rewards tab on your account page on https://cspr.live/.

    If you want to undelegate your tokens, you can do so at any time. See the Undelegation Guide for details.

    Video Tutorial

    This video guide covers the process at a high level, but we recommend following the written tutorial to go through the process step by step.

    -
    +
    \ No newline at end of file diff --git a/next/users/delegating/index.html b/users/delegating/index.html similarity index 54% rename from next/users/delegating/index.html rename to users/delegating/index.html index 97a5552bd..1dcc9ff6d 100644 --- a/next/users/delegating/index.html +++ b/users/delegating/index.html @@ -3,19 +3,19 @@ -Delegating Tokens | Casper Docs - Redux +Delegating Tokens | Casper Docs - Redux - - + +
    Version: Next

    Delegating Tokens

    + submit an issue on Github
    Version: Next

    Delegating Tokens

    A feature of Proof-of-Stake protocols is that token holders can actively participate in the protocol through a mechanism known as delegating or staking with a validator. CSPR holders can stake their tokens with any validator on a Casper network. Alternatively, it is possible to stake tokens via an exchange or custody provider.

    Node operators stake their tokens to earn eligibility to propose and approve blocks on the network. They also run and maintain servers connected to the network. If they win a validator slot, they become validators and help enable the Proof-of-Stake aspect of the network, a process different from mining tokens. Validators thus earn rewards for participating and for securing the network.

    Anyone can participate in the protocol to earn rewards without maintaining a Casper node (a server that stores a copy of the blockchain). One can delegate or allocate CSPR tokens to a chosen validator on the network. Validators retain a percentage of the rewards generated from staked tokens. Participating in the protocol this way, the community can help improve the network's decentralization and security and earn rewards in return. Block explorers connected to the network usually post the base annual reward rate.

    @@ -38,7 +38,7 @@

    First-

    If you perform a delegation for the first time, the system charges some motes to create a purse to hold the delegated tokens. We recommend that you try out delegations on the Casper Testnet before making transactions on the Casper Mainnet. This will help you understand the costs involved in delegating tokens.

    Example: The system can charge 0.5 CSPR in addition to the base delegation fee of 2.5 CSPR, resulting in a delegation cost of 3 CSPR on Mainnet.

    When you set up a delegation transaction, it is essential to have enough funds in your account's main purse. Otherwise, the transaction will fail, and you will lose the delegation cost. For example, if you have 200 CSPR in your purse, delegate at most 197 CSPR and leave at least 3 CSPR for the delegation cost. Another option is to delegate 195 CSPR and leave some additional buffer.

    -

    As a result, when performing a delegation using the command line, we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure.

    +

    As a result, when performing a delegation using the command line, we recommend you specify a little more than the base transaction payment to ensure that the transaction will go through without failure.

    Figure 2 : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR.

    **Figure 2** : On Testnet or Mainnet, the transaction fee for a delegation is a little bit higher than 2.5 CSPR. @@ -50,10 +50,10 @@

    Monitorin

    Tutorials

    Navigate to these pages for step-by-step tutorials on delegating and undelegating tokens.

    +
  • Delegating tokens using a block explorer
  • +
  • Delegating with Ledger devices
  • +
  • Delegating with the Casper client
  • +
  • Undelegating tokens using a block explorer
  • +
    \ No newline at end of file diff --git a/users/funding-from-exchanges/index.html b/users/funding-from-exchanges/index.html index 815397f7f..2d3544173 100644 --- a/users/funding-from-exchanges/index.html +++ b/users/funding-from-exchanges/index.html @@ -1,45 +1,45 @@ - + -Funding Mainnet Accounts | Casper Docs - Redux +Funding Mainnet Accounts | Casper Docs - Redux - - + +
    Version: 1.5.X

    Funding Mainnet Accounts from an Exchange

    + submit an issue on Github
    Version: Next

    Funding Mainnet Accounts from an Exchange

    To send CSPR tokens from an exchange to a Mainnet account, you need the Mainnet account's public key. Then, you can set up a withdrawal request from the exchange using this public key. The transfer will take a few minutes.

    This guide demonstrates a withdrawal from Coinlist to the Casper Mainnet using the cspr.live block explorer. You need to contact the exchange for instructions if you are working with a different exchange.

    Prerequisites

    -

    Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on cspr.live and the field you need to specify in the withdrawal request from Coinlist.

    -

    +

    Before starting, copy the public key where you wish to transfer funds. The screenshot below shows the account page on https://cspr.live/ and the field you need to specify in the withdrawal request from Coinlist.

    +

    Account public key from CSPR.Live

    Transfers from Coinlist to Casper Mainnet

    Try these steps with a small amount of CSPR first. After one successful transfer, you will be more comfortable transferring larger amounts.

      -
    1. Log into your https://coinlist.co/ account.
    2. +
    3. Log into your https://coinlist.co account.
    4. Go to the "Wallet" tab.
    -

    +

    Coinlist Wallet tab

    1. Click on the "CSPR" section.
    -

    +

    CSPR on Coinlist

    1. Click on the "Withdraw" button.
    -

    +

    Withdraw on Coinlist

    1. Enter the public key of the Mainnet account in the "Recipient Address" field of the withdrawal request.
    -

    +

    Withdrawal fields on Coinlist

    1. Enter 0 in the "Transfer ID" field or another value that is meaningful to you. You MUST enter a value, or the transfer will fail!

      @@ -51,8 +51,8 @@

      cspr.live site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.

      +

      Submit the transfer request. Wait approximately 5 minutes, and then go to the https://cspr.live/ site to verify your account details. On the account page, you should see that the "Liquid Account Balance" reflects the amount you have transferred.

    2. -
    +
    \ No newline at end of file diff --git a/users/index.html b/users/index.html index e05d1e6a9..9f6d3e538 100644 --- a/users/index.html +++ b/users/index.html @@ -1,22 +1,21 @@ - + -Users Overview | Casper Docs - Redux +Users Overview | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Users Overview

    + submit an issue on Github
    Version: Next

    Users Overview

    General Topics

    @@ -35,7 +34,11 @@

    General Topic -
    TopicDescription
    Block ExplorersA guide to understanding block explorers
    Funding Mainnet AccountsFunding Mainnet accounts from an exchange
    + + + + +
    TopicDescription
    Block ExplorersA guide to understanding block explorers
    Funding Mainnet AccountsFunding Mainnet accounts from an exchange
    Delegating TokensDelegating tokens to a validator (a.k.a. staking with a validator)

    Using CSPR.live

    Interact with the Casper blockchain using the cspr.live block explorer.

    @@ -83,6 +86,6 @@

    Using L -
    TopicDescription
    Ledger SetupA guide to setting up your Ledger device
    Delegating with Ledger DevicesDelegating tokens using your Ledger device

    +
    TopicDescription
    Ledger SetupA guide to setting up your Ledger device
    Delegating with Ledger DevicesDelegating tokens using your Ledger device
    \ No newline at end of file diff --git a/users/ledger/index.html b/users/ledger/index.html index 700a3c3c3..dd5144e3c 100644 --- a/users/ledger/index.html +++ b/users/ledger/index.html @@ -1,21 +1,21 @@ - + -Casper on Ledger | Casper Docs - Redux +Casper on Ledger | Casper Docs - Redux - - + +
    Version: 1.5.X

    Using Ledger with Casper

    + submit an issue on Github
    +
    TopicDescription
    Ledger Setup with CasperConnect a Ledger device to the Casper application
    Using Ledger and Ledger LiveSend and receive CSPR using Ledger and Ledger Live
    Using Ledger and CSPR.liveSend and receive CSPR using Ledger and CSPR.live
    Delegating with Ledger DevicesDelegate tokens using a Ledger device and CSPR.live
    \ No newline at end of file diff --git a/users/ledger/ledger-cspr-live/index.html b/users/ledger/ledger-cspr-live/index.html index 537df2683..3f0b8abdd 100644 --- a/users/ledger/ledger-cspr-live/index.html +++ b/users/ledger/ledger-cspr-live/index.html @@ -1,22 +1,21 @@ - + -Ledger and CSPR.live | Casper Docs - Redux +Ledger and CSPR.live | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Using Ledger and CSPR.live

    + submit an issue on Github
    Version: Next

    Using Ledger and CSPR.live

    This guide will help you connect your Ledger device to a Casper account using the cspr.live block explorer to send and receive CSPR tokens.

    Prerequisites

      @@ -29,114 +28,114 @@

      Signing Incspr.live/sign-in.

    -

    +

    Sign into cspr.live

    1. Click on the Connect button in the Ledger section.
    -

    +

    Choose to connect with ledger

    1. Click the Connect to Ledger wallet button next.
    -

    +

    Connect to Ledger Wallet in CSPR Live

    1. Select an account you want to use.
    -

    +

    Choose an account to connect

    1. Your Ledger device is now connected to the block explorer, displaying your account details.
    -

    +

    Account connected

    Viewing Account Details

    1. Open cspr.live.
    2. Click on the account in the upper-right corner of the page.
    -

    +

    3-view-account

    1. Click on the View Account button.
    -

    +

    5-view-account-button

    1. You are presented with a page displaying details about your account. Check your account's main purse balance in the Liquid row under Total Balance.
    -

    +

    4-account-details

    Receiving Tokens

    To receive tokens, you need to provide the sender with your account's public key. To find it, follow these steps:

    1. Open the account details page as described here and copy the public key in the Public Key row.
    2. Alternatively, click on the drop-down menu on your account address.
    -

    +

    View account

    1. Click on the Copy Public Key button and share it with the sender.
    -

    +

    Copy public key

    Sending Tokens

    1. Open cspr.live.
    2. Sign in with your Ledger device.
    3. Click on Wallet and then Transfer CSPR.
    -

    +

    5-transfer-wallet

    1. Fill in the details for the transfer.
    -

    +

    1-transfer-details

    1. Click on the Next button.
    2. On the next page, click Confirm and transfer.
    -

    +

    2-transfer-confirm

    1. On the Sign transaction page, click on the Sign with Ledger button.
    -

    +

    3-transfer-sign

    1. Your Ledger hardware wallet will present you with transfer details. Verify the transfer details (txn hash, chain ID, source account, fee, target, and amount). Meanwhile, the block explorer will show this message:
    -

    +

    3-transfer-sign

    Verify the transaction on your Ledger device

    Press the right button on your Ledger Device to review the transaction details (Amount and Address) until you see "Approve".

    1. Verify the Txn hash - ensure it matches the value displayed on cspr.live.
    -

    +

    3-txn-1

    The Txn hash value continues on a second screen.

    -

    +

    4-txn-2

    1. The next page displays transaction Type - for CSPR transfers, that will be Token transfer.
    -

    +

    5-type

    1. Verify the Chain ID, which identifies the network to which you want to send the transaction.
    -

    +

    7-chain

    1. Verify the Account, the account's public key initiating the transaction.
    -

    +

    8-account-1

    The Account value continues on a second screen.

    -

    +

    9-account-2

    1. Verify the Fee. For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR.
    -

    +

    10-fee

    1. Verify the Target, the recipient's public key. Compare this value with the one in the block explorer.
    -

    +

    11-target-1

    The Target value continues on a second screen.

    -

    +

    12-target-2

    1. Verify the Amount you want to transfer.
    -

    +

    13-amount

    1. If you want to approve the transaction, click both buttons on the Ledger device while on the APPROVE screen.
    -

    +

    15-approve

    After approving the transaction with your Ledger hardware wallet, the cspr.live block explorer will display a "Transfer completed" page.

    -

    -

    You can now check your account to see a list of all the completed transfers.

    +

    4-transfer-completed

    +

    You can now check your account to see a list of all the completed transfers.

    \ No newline at end of file diff --git a/users/ledger/ledger-live/index.html b/users/ledger/ledger-live/index.html index 2883b86e5..a0402e863 100644 --- a/users/ledger/ledger-live/index.html +++ b/users/ledger/ledger-live/index.html @@ -1,22 +1,21 @@ - + -Ledger and Ledger Live | Casper Docs - Redux +Ledger and Ledger Live | Casper Docs - Redux - - + +
    Version: 1.5.X

    import useBaseUrl from '@docusaurus/useBaseUrl';

    -

    Using Ledger and Ledger Live

    + submit an issue on Github
    Version: Next

    Using Ledger and Ledger Live

    This guide will help you connect accounts from the Ledger device to the Ledger Live application to send and receive CSPR tokens.

    important

    From Ledger Live version 2.73.1, Casper accounts can be added from the Ledger hardware wallet to Ledger Live.

    Prerequisites

    @@ -29,219 +28,141 @@

    Connectin
    1. Connect the Ledger device to your computer and unlock it by entering your device PIN.
    -

    -Connect the Ledger to your computer -

    +

    Connect the Ledger to your computer

    1. Allow Ledger Manager to connect by clicking the two buttons on the Ledger device.
    -

    -Unlock the Ledger -

    +

    Unlock the ledger

    1. Ledger Live will verify your Ledger device and display the following confirmation:
    -

    -Confirmation that the Ledger is genuine -

    +

    Confirmation that the Ledger is genuine

    1. Click My Ledger in the left-side navigation bar, and search for Casper or CSPR in the App catalog.
    -

    -Confirmation that the Ledger is genuine -

    +

    Confirmation that the Ledger is genuine

    1. To import a Casper account from the Ledger device into the Ledger Live application, click on the Add account link.
    -

    -Click the Add account link -

    +

    Click the Add account link

    1. Open the Casper app on your Ledger device.
    -

    -Open the Casper app -

    +

    Open the Casper app

    1. Ledger Live will import the first account listed on your Ledger device. Choose a name for the account.
    -

    -Name the account -

    +

    Name the account

    1. After synchronizing the account, Ledger Live will confirm that the account was successfully added.
    -

    -Synchronizing the account -

    -

    -Confirmation that the account was added -

    +

    Synchronizing the account

    +

    Confirmation that the account was added

    1. Click on the account summary, to view more details.
    -

    -Account summary -

    -

    -Account details -

    +

    Account summary

    +

    Account details

    1. To add another account, open the Account option in the left-side navigation bar. Then, click on the Add account button.
    -

    -Add a second account -

    +

    Add a second account

    Receiving Tokens

    To receive tokens, you need to provide the sender with your account's public key.

    caution

    Casper accounts only support CSPR tokens. Sending other tokens to a Casper account may result in the permanent loss of funds.

    1. Click on the Receive option in the left-side navigation bar.
    -

    -Click on Receive -

    +

    Click on Receive

    1. Choose an account from the drop-down list.
    -

    -Choose an account -

    +

    Choose an account

    1. Copy the address displayed, or use the corresponding QR code.
    -

    -Choose an account -

    +

    Choose an account 2

    1. Verify that the address displayed in Ledger Live matches the address on your Ledger screen. If it does, click APPROVE.
    -

    -Verify address part 1 -

    -

    -Verify address part 2 -

    -

    -Click APPROVE -

    -

    -Confirmation displayed -

    +

    Verify address part 1

    +

    Verify address part 2

    +

    Click approve

    +

    Confirmation displayed

    Sending Tokens

    Ledger Live supports sending CSPR tokens from one Casper account to another.

    1. Start by clicking on the Send option in the left-side navigation bar. Choose the account to debit:
    -

    -Choose the account to debit -

    +

    Choose the account to debit

    1. Enter the recipient's address and click Continue.
    -

    -Enter recipient -

    +

    Enter reciepient

    1. Enter the amount and an optional transfer ID. Click Continue.
    -

    -Enter amount and transfer ID -

    +

    Enter amount and transfer ID

    1. Review the summary, and if everything is correct, click Continue. Otherwise, click the Back link in the top-left corner.
    -

    -Review the transfer -

    +

    Review the transfer

    1. Your Ledger hardware wallet will present you with the transfer details. Verify the transaction hash, chain ID, source account, fee, target, and amount. Meanwhile, Ledger Live will display this message:
    -

    -Review the transaction in the Ledger -

    +

    Review the transaction in the Ledger

    Verify the transaction on your Ledger device

    Press the right button on your Ledger Device to review the transaction details until you see "APPROVE".

    1. Review the Txn hash.
    -

    -3-txn-1 -

    +

    3-txn-1

    The Txn hash value continues on a second screen.

    -

    -4-txn-2 -

    +

    4-tx-2

    1. The next screen displays the transaction Type, which will be Token transfer.
    -

    -5-type -

    +

    5-type

    1. Verify the chain ID, which for Mainnet should be casper.
    -

    -7-chain -

    +

    7-chain

    1. Verify the Account initiating the token transfer.
    -

    -8-account-1 -

    +

    8-account-1

    The Account value continues on a second screen.

    -

    -9-account-2 -

    +

    9-account-2

    1. Verify the Fee. For CSPR token transfers, that value should be constant and equal to 100,000,000 motes = 0.1 CSPR.
    -

    -10-fee -

    +

    10-fee

    1. Verify the Target, which is the recipient's public key.
    -

    -11-target-1 -

    +

    11-target-1

    The Target value continues on a second screen.

    -

    -12-target-2 -

    +

    12-target-2

    1. Verify the Amount you want to transfer.
    -

    -13-amount -

    +

    13-amount

    1. If you want to approve the transaction, click both buttons on the Ledger device while on the APPROVE screen.
    -

    -15-approve -

    +

    15-approve

    1. After approving the transaction with your Ledger hardware wallet, Ledger Live will display the following windows:
    -

    -Broadcasting transaction -

    -

    -Transaction sent -

    +

    Broadcasting transaction

    +

    Transaction sent

    1. To view the transaction details, click on the View details button. The following screen will appear:
    -

    -Transaction details -

    +

    Transaction details

    1. You can view the transaction in the CSPR.live block explorer by clicking on the View in explorer link.
    -

    -Explorer showing transaction -

    +

    Explorer chowing transaction

    \ No newline at end of file diff --git a/users/staking-ledger/index.html b/users/staking-ledger/index.html index 0caeb680f..371900ff7 100644 --- a/users/staking-ledger/index.html +++ b/users/staking-ledger/index.html @@ -1,21 +1,21 @@ - + -Delegate with Ledger | Casper Docs - Redux +Delegate with Ledger | Casper Docs - Redux - - + +
    Version: 1.5.X

    Delegating with Ledger Devices

    + submit an issue on Github
    Version: Next

    Delegating with Ledger Devices

    Ledger Initialization

    Before getting started, you need to complete two prerequisite steps:

      @@ -30,99 +30,84 @@

      Impo

      Staking with a Validator

      Connect and Login with Ledger

        -
      1. -

        Connect your Ledger to your computer via USB and enter your PIN to unlock it.

        -
      2. -
      3. -

        Open the Casper app on the Ledger (you will see the message "Casper Ready").

        -

        -
      4. -
      5. -

        Sign in to cspr.live with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.

        -

        -
      6. -
      7. -

        Select the public key connected to your Ledger account.

        -

        -
      8. -
      9. -

        View your account by clicking on your public key at the top right corner.

        -

        -
      10. +
      11. Connect your Ledger to your computer via USB and enter your PIN to unlock it.
      12. +
      13. Open the Casper app on the Ledger (you will see the message "Casper Ready").
      14. +
      +

      Casper Ready

      +
        +
      1. Sign in to cspr.live with your Ledger by clicking "Connect" under the Ledger option, as shown in the screenshot below.
      2. +
      +

      Casper Ready 2

      +
        +
      1. Select the public key connected to your Ledger account.
      +

      Casper Ready 3

      +
        +
      1. View your account by clicking on your public key at the top right corner.
      2. +
      +

      Casper Ready 4

      Receive Tokens from an External Source

      -

      This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the documentation.

      +

      This portion will vary slightly depending on where your funds are currently stored. However, the process will require that you send tokens to your public key as described in the documentation.

      Staking Tokens

      Once you have tokens in your account, staking (delegating) with a validator is easy.

        -
      1. -

        Go back to your account, but this time open the "delegate" tab located at: https://cspr.live/delegate-stake (alternatively, click on Wallet ⇒ Delegate Stake to go there).

        -
      2. -
      3. -

        From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you.

        -
      4. -
      5. -

        Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:

        +
      6. Go back to your account, but this time open the "delegate" tab located at: https://cspr.live/delegate-stake (alternatively, click on Wallet ⇒ Delegate Stake to go there).
      7. +
      8. From the validator list, choose any validator you like. You will notice that validators charge different fees and have different amounts staked to them. This may inform your decision to choose the right validator for you.
      9. +
      10. Specify the amount you wish to stake or click "Delegate max" as shown below. Notes:
        1. Remember that the total delegation amount to one validator cannot be less than 500 CSPR.
        2. Both delegation and undelegation have an associated fee, so you need to leave some funds in your account to cover transaction fees. Otherwise, you may need to deposit additional funds to undelegate later.
      11. -
      12. -

        Click "Next" to continue, as shown below.

        -

        -
      13. +
      14. Click "Next" to continue, as shown below.
      15. +
      +

      Casper Ready 5

      +
      1. The page will update with a confirmation page asking you to verify all the details. If everything looks correct, click the "Confirm and delegate stake" button.

      2. You will be presented with a final page asking you to sign the transaction with Ledger. Click the "Sign with Ledger" button at the bottom.

        Note: If you get an error showing a "Transaction rejected" message, make sure your Ledger device is active and connected to your computer. You may also need to re-enter your PIN if it locked itself due to inactivity.

        -

        -
      3. -
      4. -

        On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on cspr.live.

        -

        -
      5. -
      6. -

        Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.

        -

        -

      7. +
      +

      Casper Ready 6

      +
        +
      1. On the Ledger, you will see a message saying, "Please review". Click through the fields and verify everything matches what is being shown to you on cspr.live.
      2. +
      +

      Casper Ready 7

      +
        +
      1. Once you click "Approve", you will see the Delegation Completed screen verifying that your staking successfully was submitted to the blockchain.
      2. +
      +

      Casper Ready 8 +Casper Ready 9

      +
      1. At this point, you can return to your account and wait until the completion of the era when the block gets included in the chain. Once the era completes, you will see that your liquid balance has decreased by your staked amount and is reflected in the "Staked As Delegator" row.

        Note: If you staked your full balance, don't panic if you see a 0 CSPR balance whenever you log in! This is because it shows your liquid assets, not your total balance. You can go to your account details page, as shown below, to see your full balance and asset breakdown between liquid, staked, and undelegated tokens.

        -

      +

      Casper Ready 10

      Unstaking with a Validator

      Initiate the Undelegation

      Now that you have funds delegated, you can liquidate them by undelegating them first. As demonstrated below, on your account's profile page, click "Undelegate" to get started.

      -

      +

      Casper Ready 11

      The next page, "Undelegation details", will ask you how much you wish to undelegate. If you select "Undelegate max", it will attempt to liquidate all of your staked assets (minus the transaction fee). Once you enter a valid amount, the "Next" button will become clickable. Below you can see that I entered 313.02931 CSPR to be able to proceed.

      -

      +

      Casper Ready 12

      You will next be shown a confirmation screen. If everything looks good, then click "Confirm and undelegate stake" to proceed.

      Sign the Undelegation

      You will have to sign the transaction to verify your account is initiating this action.

        -
      1. -

        Connect your Ledger device to your computer.

        -
      2. -
      3. -

        Unlock your Ledger by entering your PIN.

        -
      4. -
      5. -

        Open the "Casper" app and ensure you see "Casper Ready".

        -
      6. -
      7. -

        Then back on cspr.live click the "Sign with Ledger" button shown below.

        -

        -
      8. +
      9. Connect your Ledger device to your computer.
      10. +
      11. Unlock your Ledger by entering your PIN.
      12. +
      13. Open the "Casper" app and ensure you see "Casper Ready".
      14. +
      15. Then back on cspr.live click the "Sign with Ledger" button shown below.
      +

      Casper Ready 13

      On your Ledger, you will see the transaction details. Verify all the information with what is being presented on the screen. If it looks good, then approve the transaction. If all goes according to plan, you will be presented with an "Undelegation completed!" screen.

      -

      +

      Casper Ready 14

      Note: There is a 7 era delay to undelegate. Era duration is approximately 120 minutes. While the funds go through undelegation, the balance will appear in the "Undelegation" row on your account profile page, as you can see below.

      -

      -

      After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish.

    +

    Casper Ready 15

    +

    After the undelegation period completes, your funds will be liquid and available for you to re-stake, withdraw, or use however you wish.

    \ No newline at end of file diff --git a/users/testnet-faucet/index.html b/users/testnet-faucet/index.html index bb8af5717..076b165ca 100644 --- a/users/testnet-faucet/index.html +++ b/users/testnet-faucet/index.html @@ -1,40 +1,34 @@ - + -Testnet Funding | Casper Docs - Redux +Testnet Funding | Casper Docs - Redux - - + +
    Version: 1.5.X

    Funding Testnet Accounts

    + submit an issue on Github
    Version: Next

    Funding Testnet Accounts

    The Casper Testnet is an alternate Casper blockchain that enables testing applications without spending CSPR on the Mainnet. The Testnet is deployed independently from the Mainnet for users to experiment with network features such as transferring, delegating, and undelegating tokens. One way to access the Casper Testnet is to use the cspr.live block explorer.

    Testnet tokens are independent of the Casper token (CSPR). While test tokens do not have any monetary value, they possess the same functionality as the CSPR token within the confines of the Testnet. Users can fund Testnet accounts as outlined below.

    Requesting Testnet Tokens

    To request test tokens, follow these steps:

      -
    1. -

      Log into the Casper Testnet with the Casper Wallet. See the Getting Started user guide for detailed instructions.

      -
    2. -
    3. -

      Click Tools on the top menu bar and select Faucet from the drop-down menu. Or, navigate to the Faucet using this link: https://testnet.cspr.live/tools/faucet.

      -
    4. -
    5. -

      Click Request tokens on the Faucet page:

      -

      -
    6. +
    7. Log into the Casper Testnet with the Casper Wallet. See the Getting Started user guide for detailed instructions.
    8. +
    9. Click Tools on the top menu bar and select Faucet from the drop-down menu. Or, navigate to the Faucet using this link: https://testnet.cspr.live/tools/faucet.
    10. +
    11. Click Request tokens on the Faucet page:
    +

    Faucet

    caution

    Tokens can be requested only once per account. Otherwise, the deploy will fail with status User error: 1.

    If you have already exhausted your test funds, you can always create a new account.

    1. The Testnet will credit your account with test tokens.
    2. -
    +
    \ No newline at end of file diff --git a/users/token-transfer/index.html b/users/token-transfer/index.html index 43c542eb1..05485e560 100644 --- a/users/token-transfer/index.html +++ b/users/token-transfer/index.html @@ -1,22 +1,21 @@ - + -Transfer Tokens | Casper Docs - Redux +Transfer Tokens | Casper Docs - Redux - - + +
    Version: 1.5.X

    Transferring Tokens

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Transferring Tokens

    You can transfer Casper tokens (CSPR) using any block explorer built to explore the Casper blockchain. The Wallet feature on these block explorers enables transfers to another user's purse, delegate stake, or undelegate stake. In this section, we will discuss the steps to transfer CSPR tokens.

    Transferring Tokens

    To transfer tokens, follow these steps:

    @@ -26,11 +25,11 @@

    Transf
  • Enter the recipient's public key, the amount you wish to transfer, and an optional Transfer ID for reference. If you do not provide an ID, the system will auto-generate one.
  • Click Next to proceed.
  • -

    +

    Transfer details

    1. A confirmation window appears to verify the details entered. Click Confirm and transfer to proceed to the next step.
    -

    +

    Confirm transfer

    1. Review the following important fields:
    @@ -41,17 +40,17 @@

    Transf
  • The Transfer Amount containing the value of the transfer
  • Sign the transaction by selecting the Sign with Casper Wallet button to proceed to the next step.

    -

    +

    Sign the transfer

    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign transaction" window before continuing. Click Sign in the Signature Request window to complete the transaction.
    -

    +

    Review the transaction

    1. You completed the transaction and successfully transferred tokens.
    -

    +

    Transfer completed window

    1. View the updated CSPR balance in the account's main purse next.
    2. -

    +
    \ No newline at end of file diff --git a/users/undelegate-ui/index.html b/users/undelegate-ui/index.html index 26f0fa8df..335d91fee 100644 --- a/users/undelegate-ui/index.html +++ b/users/undelegate-ui/index.html @@ -1,32 +1,32 @@ - + -Undelegate Tokens | Casper Docs - Redux +Undelegate Tokens | Casper Docs - Redux - - + +
    Version: 1.5.X

    Undelegating Tokens

    + submit an issue on Github
    Version: Next

    Undelegating Tokens

    If you want to undelegate tokens from a validator, you can do so at any time. Note that undelegation costs approximately 0.5 CSPR.

    Prerequisites

    This guide assumes that you have previously delegated tokens to a validator using a block explorer or the Casper client.

    Accessing the Undelegation Feature

    You can access the undelegation functionality in three ways.

    Option 1: Click Wallet from the top navigation menu and then click Undelegate Stake.

    -

    +

    Undelegate from Wallet

    Option 2: Click Validators from the top navigation menu. Using the validators table, find the validator you wish to undelegate from, and click the Undelegate Stake button.

    -

    +

    Undelegate from Validator

    Option 3: Open your account details and select the Delegations tab. Click the Undelegate button next to the validator from whom you wish to undelegate.

    -

    +

    Undelegate from Account

    Stepping through the Undelegation Process

    The following instructions will take you through the undelegation process, starting with the "Undelegation details" screen.

    Step 1 - Undelegation details

    @@ -35,27 +35,27 @@

    +

    Undelegation details

    Step 2 - Confirm the undelegation

    1. Review the undelegation details.
    2. If everything looks correct, click Confirm and undelegate stake. If you wish to make changes, return to the previous screen.
    -

    +

    Confirm undelegation

    Step 3 - Sign the undelegation

    1. Click Sign with Casper Wallet to sign the undelegation.
    -

    +

    Sign the undelegation

    1. Once the Casper Wallet opens, check the deploy hash. Ensure the deploy hash in the "Signature Request" window matches the deploy hash in the "Sign undelegation" window before continuing.
    -

    +

    Confirm deploy hash

    1. Click Sign in the Signature Request window to finalize the undelegation. The stake undelegation initiates as soon as the corresponding deploy is signed. Here is the expected output:
    -

    +

    Undelegation confirmed

    It may take 1-2 minutes for the undelegation details to become available. Click "Deploy Details" for more information.

    -

    Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours.

    +

    Note that your undelegated tokens will appear in your account automatically after a 7-era delay of approximately 14 hours.

    \ No newline at end of file diff --git a/workflow/ledger-setup/index.html b/workflow/ledger-setup/index.html index dec10bd14..0fff33e73 100644 --- a/workflow/ledger-setup/index.html +++ b/workflow/ledger-setup/index.html @@ -1,22 +1,21 @@ - + -Set up Ledger | Casper Docs - Redux +Set up Ledger | Casper Docs - Redux - - + +
    Version: 1.5.X

    Ledger Setup with Casper

    -

    import useBaseUrl from '@docusaurus/useBaseUrl';

    + submit an issue on Github
    Version: Next

    Ledger Setup with Casper

    A Ledger device is a hardware wallet considered one of the most secure ways to store your digital assets. Ledger uses an offline, or cold storage, method of generating private keys, making it a preferred method for many crypto users.

    Prerequisites

      @@ -30,27 +29,19 @@
    +

    Buying, selling, or swapping CSPR are not currently supported in Ledger Live. For these operations, you need to visit an exchange.

    \ No newline at end of file diff --git a/writing-contracts/index.html b/writing-contracts/index.html index b59dac140..9b61489f9 100644 --- a/writing-contracts/index.html +++ b/writing-contracts/index.html @@ -1,21 +1,21 @@ - + -Introduction | Casper Docs - Redux +Introduction | Casper Docs - Redux - - + +
    Version: 1.5.X

    Writing On-Chain Code

    + submit an issue on Github
    Version: Next

    Writing On-Chain Code

    This section shows you how to write session code and smart contracts in Rust and WebAssembly (Wasm) for a Casper network. When referring to session code, these documents outline logic that executes in the context of an account. In contrast, smart contracts consist of logic installed on-chain, for use by multiple parties. There is a large overlap between the processes of writing session code versus contract code, with some semantic differences outlined in their respective documentation. The Video Series for Writing On-Chain Code accompanies the topics below.

    @@ -73,7 +73,15 @@ -
    TitleDescription
    Getting Started with RustAn introduction to using Rust with the Casper Platform
    Getting Started with AssemblyScriptAn introduction to using AssemblyScript with the Casper Platform
    Writing a Basic Smart Contract in RustAn example of a smart contract built in Rust
    Unit Testing Smart ContractsSteps to test contract code using the unit testing framework
    Upgrading and Maintaining Smart ContractsAn introduction to versioning smart contracts
    Calling Contracts
    Smart Contracts and Session CodeUnderstand what session code is and when you would use it over contract code
    Writing Session CodeAn introduction to writing session code
    Unit Testing Session CodeSteps to test session code using the unit testing framework
    Using Contract Hash vs. Package HashAdvantages and disadvantages of using contract_hash vs. contract_package_hash when calling a contract
    Best Practices for Casper Smart Contract AuthorsAn outline of best practices when developing smart contracts on a Casper network
    + + + + + + + + +
    TitleDescription
    Getting Started with RustAn introduction to using Rust with the Casper Platform
    Getting Started with AssemblyScriptAn introduction to using AssemblyScript with the Casper Platform
    Writing a Basic Smart Contract in RustAn example of a smart contract built in Rust
    Unit Testing Smart ContractsSteps to test contract code using the unit testing framework
    Upgrading and Maintaining Smart ContractsAn introduction to versioning smart contracts
    Calling Contracts
    Smart Contracts and Session CodeUnderstand what session code is and when you would use it over contract code
    Writing Session CodeAn introduction to writing session code
    Unit Testing Session CodeSteps to test session code using the unit testing framework
    Contract-Level EventsEnabling smart contracts to emit messages while executing on the blockchain
    Using Contract Hash vs. Package HashAdvantages and disadvantages of using contract_hash vs. contract_package_hash when calling a contract
    The Factory Pattern for Smart ContractsLearn to implement the contract factory pattern on a Casper network
    Best Practices for Casper Smart Contract AuthorsAn 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 covers installing and calling contracts using the Casper command-line client written in Rust.

    @@ -145,6 +153,6 @@

    TutorialsGetting Started VideoStep-by-step video tutorial for setting up the Casper development environmentA Counter on the TestnetAn example contract that maintains a counter variable on the Casper TestnetSmart Contract UpgradesLearn how to upgrade smart contractsNFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standardFungible Tokens on CasperImplement the Casper Fungible Token standardInteracting with Runtime Return ValuesLearning how to return a value using contract codeWorking with Authorization KeysRetrieving and using the authorization keys associated with a deploySafely Transfer Tokens to a ContractHow to handle tokens via a contract

    +
    TitleDescription
    Getting Started VideoStep-by-step video tutorial for setting up the Casper development environment
    A Counter on the TestnetAn example contract that maintains a counter variable on the Casper Testnet
    Smart Contract UpgradesLearn how to upgrade smart contracts
    NFTs on Casper with the CEP-78 NFT StandardImplementing the Casper CEP-78 NFT standard
    Fungible Tokens on CasperImplement the Casper Fungible Token standard
    Interacting with Runtime Return ValuesLearning how to return a value using contract code
    Working with Authorization KeysRetrieving and using the authorization keys associated with a transaction
    Safely Transfer Tokens to a ContractHow to handle tokens via a contract
    \ No newline at end of file